From owner-svn-src-all@FreeBSD.ORG Sat Nov 16 08:20:50 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id EA0C4CC8; Sat, 16 Nov 2013 08:20:50 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id D8ED0239B; Sat, 16 Nov 2013 08:20:50 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rAG8KoUk012091; Sat, 16 Nov 2013 08:20:50 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rAG8KoHH012089; Sat, 16 Nov 2013 08:20:50 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <201311160820.rAG8KoHH012089@svn.freebsd.org> From: Rui Paulo Date: Sat, 16 Nov 2013 08:20:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258209 - head/sys/arm/ti X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Nov 2013 08:20:51 -0000 Author: rpaulo Date: Sat Nov 16 08:20:50 2013 New Revision: 258209 URL: http://svnweb.freebsd.org/changeset/base/258209 Log: Add a driver for the Texas Instruments Mailbox hardware. Added: head/sys/arm/ti/ti_mbox.c (contents, props changed) head/sys/arm/ti/ti_mbox.h (contents, props changed) Added: head/sys/arm/ti/ti_mbox.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/ti/ti_mbox.c Sat Nov 16 08:20:50 2013 (r258209) @@ -0,0 +1,262 @@ +/*- + * Copyright (c) 2013 Rui Paulo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "mbox_if.h" + +#define DEBUG +#ifdef DEBUG +#define DPRINTF(fmt, ...) do { \ + printf("%s: ", __func__); \ + printf(fmt, __VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +static device_probe_t ti_mbox_probe; +static device_attach_t ti_mbox_attach; +static device_detach_t ti_mbox_detach; +static void ti_mbox_intr(void *); +static int ti_mbox_read(device_t, int, uint32_t *); +static int ti_mbox_write(device_t, int, uint32_t); + +struct ti_mbox_softc { + struct mtx sc_mtx; + struct resource *sc_mem_res; + struct resource *sc_irq_res; + void *sc_intr; + bus_space_tag_t sc_bt; + bus_space_handle_t sc_bh; +}; + +#define TI_MBOX_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define TI_MBOX_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) + +static device_method_t ti_mbox_methods[] = { + DEVMETHOD(device_probe, ti_mbox_probe), + DEVMETHOD(device_attach, ti_mbox_attach), + DEVMETHOD(device_detach, ti_mbox_detach), + + DEVMETHOD(mbox_read, ti_mbox_read), + DEVMETHOD(mbox_write, ti_mbox_write), + + DEVMETHOD_END +}; + +static driver_t ti_mbox_driver = { + "ti_mbox", + ti_mbox_methods, + sizeof(struct ti_mbox_softc) +}; + +static devclass_t ti_mbox_devclass; + +DRIVER_MODULE(ti_mbox, simplebus, ti_mbox_driver, ti_mbox_devclass, 0, 0); + +static __inline uint32_t +ti_mbox_reg_read(struct ti_mbox_softc *sc, uint16_t reg) +{ + return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg)); +} + +static __inline void +ti_mbox_reg_write(struct ti_mbox_softc *sc, uint16_t reg, uint32_t val) +{ + bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val); +} + +static int +ti_mbox_probe(device_t dev) +{ + if (ofw_bus_is_compatible(dev, "ti,system-mbox")) { + device_set_desc(dev, "TI System Mailbox"); + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +ti_mbox_attach(device_t dev) +{ + struct ti_mbox_softc *sc; + int rid, delay, chan; + uint32_t rev, sysconfig; + + if (ti_prcm_clk_enable(MAILBOX0_CLK) != 0) { + device_printf(dev, "could not enable MBOX clock\n"); + return (ENXIO); + } + sc = device_get_softc(dev); + rid = 0; + mtx_init(&sc->sc_mtx, "TI mbox", MTX_DEF, 0); + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->sc_mem_res == NULL) { + device_printf(dev, "could not allocate memory resource\n"); + return (ENXIO); + } + sc->sc_bt = rman_get_bustag(sc->sc_mem_res); + sc->sc_bh = rman_get_bushandle(sc->sc_mem_res); + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->sc_irq_res == NULL) { + device_printf(dev, "could not allocate interrupt resource\n"); + ti_mbox_detach(dev); + return (ENXIO); + } + if (bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE | INTR_TYPE_MISC, + NULL, ti_mbox_intr, sc, &sc->sc_intr) != 0) { + device_printf(dev, "unable to setup the interrupt handler\n"); + ti_mbox_detach(dev); + return (ENXIO); + } + /* + * Reset the controller. + */ + sysconfig = ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG); + DPRINTF("initial sysconfig %d\n", sysconfig); + sysconfig |= TI_MBOX_SYSCONFIG_SOFTRST; + delay = 100; + while (ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG) & + TI_MBOX_SYSCONFIG_SOFTRST) { + delay--; + DELAY(10); + } + if (delay == 0) { + device_printf(dev, "controller reset failed\n"); + ti_mbox_detach(dev); + return (ENXIO); + } + /* + * Enable smart idle mode. + */ + ti_mbox_reg_write(sc, TI_MBOX_SYSCONFIG, + ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG) | TI_MBOX_SYSCONFIG_SMARTIDLE); + rev = ti_mbox_reg_read(sc, TI_MBOX_REVISION); + DPRINTF("rev %d\n", rev); + device_printf(dev, "revision %d.%d\n", (rev >> 8) & 0x4, rev & 0x40); + /* + * Enable message interrupts. + */ + for (chan = 0; chan < 8; chan++) + ti_mbox_reg_write(sc, TI_MBOX_IRQENABLE_SET(chan), 1); + + return (0); +} + +static int +ti_mbox_detach(device_t dev) +{ + struct ti_mbox_softc *sc; + + sc = device_get_softc(dev); + if (sc->sc_intr) + bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr); + if (sc->sc_irq_res) + bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res), + sc->sc_irq_res); + if (sc->sc_mem_res) + bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res), + sc->sc_mem_res); + + return (0); +} + +static void +ti_mbox_intr(void *arg) +{ + struct ti_mbox_softc *sc; + + sc = arg; + DPRINTF("interrupt %p", sc); +} + +static int +ti_mbox_read(device_t dev, int chan, uint32_t *data) +{ + struct ti_mbox_softc *sc; + + if (chan < 0 || chan > 7) + return (EINVAL); + sc = device_get_softc(dev); + + return (ti_mbox_reg_read(sc, TI_MBOX_MESSAGE(chan))); +} + +static int +ti_mbox_write(device_t dev, int chan, uint32_t data) +{ + int limit = 500; + struct ti_mbox_softc *sc; + + if (chan < 0 || chan > 7) + return (EINVAL); + sc = device_get_softc(dev); + TI_MBOX_LOCK(sc); + /* XXX implement interrupt method */ + while (ti_mbox_reg_read(sc, TI_MBOX_FIFOSTATUS(chan)) == 1 && + limit--) { + DELAY(10); + } + if (limit == 0) { + device_printf(dev, "FIFOSTAUS%d stuck\n", chan); + TI_MBOX_UNLOCK(sc); + return (EAGAIN); + } + ti_mbox_reg_write(sc, TI_MBOX_MESSAGE(chan), data); + + return (0); +} Added: head/sys/arm/ti/ti_mbox.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/ti/ti_mbox.h Sat Nov 16 08:20:50 2013 (r258209) @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2013 Rui Paulo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _TI_MBOX_H_ +#define _TI_MBOX_H_ + +#define TI_MBOX_REVISION 0x00 +#define TI_MBOX_SYSCONFIG 0x10 +#define TI_MBOX_SYSCONFIG_SOFTRST 0x01 +#define TI_MBOX_SYSCONFIG_SMARTIDLE (0x02 << 2) +#define TI_MBOX_MESSAGE(n) (0x40 + (n) * 0x4) +#define TI_MBOX_FIFOSTATUS(n) (0x80 + (n) * 0x4) +#define TI_MBOX_MSGSTATUS(n) (0xc0 + (n) * 0x4) +#define TI_MBOX_IRQSTATUS_RAW(n) (0x100 + (n) * 0x10) +#define TI_MBOX_IRQSTATUS_CLR(n) (0x104 + (n) * 0x10) +#define TI_MBOX_IRQENABLE_SET(n) (0x108 + (n) * 0x10) +#define TI_MBOX_IRQENABLE_CLR(n) (0x10c + (n) * 0x10) + +#endif /* _TI_MBOX_H_ */