mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-05 01:42:49 +08:00
Import am335x usb driver file from FreeBSD.
This commit is contained in:
parent
83574df474
commit
bd3c01a126
421
freebsd/sys/arm/ti/am335x/am335x_musb.c
Normal file
421
freebsd/sys/arm/ti/am335x/am335x_musb.c
Normal file
@ -0,0 +1,421 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@freebsd.org>
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/stddef.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sx.h>
|
||||
#include <rtems/bsd/sys/unistd.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_process.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#define USB_DEBUG_VAR usbssdebug
|
||||
|
||||
#include <dev/usb/usb_controller.h>
|
||||
#include <dev/usb/usb_bus.h>
|
||||
#include <dev/usb/controller/musb_otg.h>
|
||||
#include <dev/usb/usb_debug.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_scm.h>
|
||||
#include <arm/ti/am335x/am335x_scm.h>
|
||||
|
||||
#define USBCTRL_REV 0x00
|
||||
#define USBCTRL_CTRL 0x14
|
||||
#define USBCTRL_STAT 0x18
|
||||
#define USBCTRL_IRQ_STAT0 0x30
|
||||
#define IRQ_STAT0_RXSHIFT 16
|
||||
#define IRQ_STAT0_TXSHIFT 0
|
||||
#define USBCTRL_IRQ_STAT1 0x34
|
||||
#define IRQ_STAT1_DRVVBUS (1 << 8)
|
||||
#define USBCTRL_INTEN_SET0 0x38
|
||||
#define USBCTRL_INTEN_SET1 0x3C
|
||||
#define USBCTRL_INTEN_USB_ALL 0x1ff
|
||||
#define USBCTRL_INTEN_USB_SOF (1 << 3)
|
||||
#define USBCTRL_INTEN_CLR0 0x40
|
||||
#define USBCTRL_INTEN_CLR1 0x44
|
||||
#define USBCTRL_UTMI 0xE0
|
||||
#define USBCTRL_UTMI_FSDATAEXT (1 << 1)
|
||||
#define USBCTRL_MODE 0xE8
|
||||
#define USBCTRL_MODE_IDDIG (1 << 8)
|
||||
#define USBCTRL_MODE_IDDIGMUX (1 << 7)
|
||||
|
||||
/* USBSS resource + 2 MUSB ports */
|
||||
|
||||
#define RES_USBCORE 0
|
||||
#define RES_USBCTRL 1
|
||||
|
||||
#define USB_WRITE4(sc, idx, reg, val) do { \
|
||||
bus_write_4((sc)->sc_mem_res[idx], (reg), (val)); \
|
||||
} while (0)
|
||||
|
||||
#define USB_READ4(sc, idx, reg) bus_read_4((sc)->sc_mem_res[idx], (reg))
|
||||
|
||||
#define USBCTRL_WRITE4(sc, reg, val) \
|
||||
USB_WRITE4((sc), RES_USBCTRL, (reg), (val))
|
||||
#define USBCTRL_READ4(sc, reg) \
|
||||
USB_READ4((sc), RES_USBCTRL, (reg))
|
||||
|
||||
static struct resource_spec am335x_musbotg_mem_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_MEMORY, 1, RF_ACTIVE },
|
||||
{ -1, 0, 0 }
|
||||
};
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
static int usbssdebug = 0;
|
||||
|
||||
static SYSCTL_NODE(_hw_usb, OID_AUTO, am335x_usbss, CTLFLAG_RW, 0, "AM335x USBSS");
|
||||
SYSCTL_INT(_hw_usb_am335x_usbss, OID_AUTO, debug, CTLFLAG_RW,
|
||||
&usbssdebug, 0, "Debug level");
|
||||
#endif
|
||||
|
||||
static device_probe_t musbotg_probe;
|
||||
static device_attach_t musbotg_attach;
|
||||
static device_detach_t musbotg_detach;
|
||||
|
||||
struct musbotg_super_softc {
|
||||
struct musbotg_softc sc_otg;
|
||||
struct resource *sc_mem_res[2];
|
||||
int sc_irq_rid;
|
||||
};
|
||||
|
||||
static void
|
||||
musbotg_vbus_poll(struct musbotg_super_softc *sc)
|
||||
{
|
||||
uint32_t stat;
|
||||
|
||||
if (sc->sc_otg.sc_mode == MUSB2_DEVICE_MODE)
|
||||
musbotg_vbus_interrupt(&sc->sc_otg, 1);
|
||||
else {
|
||||
stat = USBCTRL_READ4(sc, USBCTRL_STAT);
|
||||
musbotg_vbus_interrupt(&sc->sc_otg, stat & 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Arg to musbotg_clocks_on and musbot_clocks_off is
|
||||
* a uint32_t * pointing to the SCM register offset.
|
||||
*/
|
||||
static uint32_t USB_CTRL[] = {SCM_USB_CTRL0, SCM_USB_CTRL1};
|
||||
|
||||
static void
|
||||
musbotg_clocks_on(void *arg)
|
||||
{
|
||||
struct musbotg_softc *sc;
|
||||
uint32_t c, reg;
|
||||
|
||||
sc = arg;
|
||||
reg = USB_CTRL[sc->sc_id];
|
||||
|
||||
ti_scm_reg_read_4(reg, &c);
|
||||
c &= ~3; /* Enable power */
|
||||
c |= 1 << 19; /* VBUS detect enable */
|
||||
c |= 1 << 20; /* Session end enable */
|
||||
ti_scm_reg_write_4(reg, c);
|
||||
}
|
||||
|
||||
static void
|
||||
musbotg_clocks_off(void *arg)
|
||||
{
|
||||
struct musbotg_softc *sc;
|
||||
uint32_t c, reg;
|
||||
|
||||
sc = arg;
|
||||
reg = USB_CTRL[sc->sc_id];
|
||||
|
||||
/* Disable power to PHY */
|
||||
ti_scm_reg_read_4(reg, &c);
|
||||
ti_scm_reg_write_4(reg, c | 3);
|
||||
}
|
||||
|
||||
static void
|
||||
musbotg_ep_int_set(struct musbotg_softc *sc, int ep, int on)
|
||||
{
|
||||
struct musbotg_super_softc *ssc = sc->sc_platform_data;
|
||||
uint32_t epmask;
|
||||
|
||||
epmask = ((1 << ep) << IRQ_STAT0_RXSHIFT);
|
||||
epmask |= ((1 << ep) << IRQ_STAT0_TXSHIFT);
|
||||
if (on)
|
||||
USBCTRL_WRITE4(ssc, USBCTRL_INTEN_SET0, epmask);
|
||||
else
|
||||
USBCTRL_WRITE4(ssc, USBCTRL_INTEN_CLR0, epmask);
|
||||
}
|
||||
|
||||
static void
|
||||
musbotg_wrapper_interrupt(void *arg)
|
||||
{
|
||||
struct musbotg_softc *sc = arg;
|
||||
struct musbotg_super_softc *ssc = sc->sc_platform_data;
|
||||
uint32_t stat, stat0, stat1;
|
||||
|
||||
stat = USBCTRL_READ4(ssc, USBCTRL_STAT);
|
||||
stat0 = USBCTRL_READ4(ssc, USBCTRL_IRQ_STAT0);
|
||||
stat1 = USBCTRL_READ4(ssc, USBCTRL_IRQ_STAT1);
|
||||
if (stat0)
|
||||
USBCTRL_WRITE4(ssc, USBCTRL_IRQ_STAT0, stat0);
|
||||
if (stat1)
|
||||
USBCTRL_WRITE4(ssc, USBCTRL_IRQ_STAT1, stat1);
|
||||
|
||||
DPRINTFN(4, "port%d: stat0=%08x stat1=%08x, stat=%08x\n",
|
||||
sc->sc_id, stat0, stat1, stat);
|
||||
|
||||
if (stat1 & IRQ_STAT1_DRVVBUS)
|
||||
musbotg_vbus_interrupt(sc, stat & 1);
|
||||
|
||||
musbotg_interrupt(arg, ((stat0 >> 16) & 0xffff),
|
||||
stat0 & 0xffff, stat1 & 0xff);
|
||||
}
|
||||
|
||||
static int
|
||||
musbotg_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "ti,musb-am33xx"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "TI AM33xx integrated USB OTG controller");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
musbotg_attach(device_t dev)
|
||||
{
|
||||
struct musbotg_super_softc *sc = device_get_softc(dev);
|
||||
char mode[16];
|
||||
int err;
|
||||
uint32_t reg;
|
||||
|
||||
sc->sc_otg.sc_id = device_get_unit(dev);
|
||||
|
||||
/* Request the memory resources */
|
||||
err = bus_alloc_resources(dev, am335x_musbotg_mem_spec,
|
||||
sc->sc_mem_res);
|
||||
if (err) {
|
||||
device_printf(dev,
|
||||
"Error: could not allocate mem resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Request the IRQ resources */
|
||||
sc->sc_otg.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
|
||||
&sc->sc_irq_rid, RF_ACTIVE);
|
||||
if (sc->sc_otg.sc_irq_res == NULL) {
|
||||
device_printf(dev,
|
||||
"Error: could not allocate irq resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* setup MUSB OTG USB controller interface softc */
|
||||
sc->sc_otg.sc_clocks_on = &musbotg_clocks_on;
|
||||
sc->sc_otg.sc_clocks_off = &musbotg_clocks_off;
|
||||
sc->sc_otg.sc_clocks_arg = &sc->sc_otg;
|
||||
|
||||
sc->sc_otg.sc_ep_int_set = musbotg_ep_int_set;
|
||||
|
||||
/* initialise some bus fields */
|
||||
sc->sc_otg.sc_bus.parent = dev;
|
||||
sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
|
||||
sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES;
|
||||
sc->sc_otg.sc_bus.dma_bits = 32;
|
||||
|
||||
/* get all DMA memory */
|
||||
if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
|
||||
USB_GET_DMA_TAG(dev), NULL)) {
|
||||
device_printf(dev,
|
||||
"Failed allocate bus mem for musb\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
sc->sc_otg.sc_io_res = sc->sc_mem_res[RES_USBCORE];
|
||||
sc->sc_otg.sc_io_tag =
|
||||
rman_get_bustag(sc->sc_otg.sc_io_res);
|
||||
sc->sc_otg.sc_io_hdl =
|
||||
rman_get_bushandle(sc->sc_otg.sc_io_res);
|
||||
sc->sc_otg.sc_io_size =
|
||||
rman_get_size(sc->sc_otg.sc_io_res);
|
||||
|
||||
sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
|
||||
if (!(sc->sc_otg.sc_bus.bdev)) {
|
||||
device_printf(dev, "No busdev for musb\n");
|
||||
goto error;
|
||||
}
|
||||
device_set_ivars(sc->sc_otg.sc_bus.bdev,
|
||||
&sc->sc_otg.sc_bus);
|
||||
|
||||
err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res,
|
||||
INTR_TYPE_BIO | INTR_MPSAFE,
|
||||
NULL, (driver_intr_t *)musbotg_wrapper_interrupt,
|
||||
&sc->sc_otg, &sc->sc_otg.sc_intr_hdl);
|
||||
if (err) {
|
||||
sc->sc_otg.sc_intr_hdl = NULL;
|
||||
device_printf(dev,
|
||||
"Failed to setup interrupt for musb\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
sc->sc_otg.sc_platform_data = sc;
|
||||
if (OF_getprop(ofw_bus_get_node(dev), "dr_mode", mode,
|
||||
sizeof(mode)) > 0) {
|
||||
if (strcasecmp(mode, "host") == 0)
|
||||
sc->sc_otg.sc_mode = MUSB2_HOST_MODE;
|
||||
else
|
||||
sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE;
|
||||
} else {
|
||||
/* Beaglebone defaults: USB0 device, USB1 HOST. */
|
||||
if (sc->sc_otg.sc_id == 0)
|
||||
sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE;
|
||||
else
|
||||
sc->sc_otg.sc_mode = MUSB2_HOST_MODE;
|
||||
}
|
||||
|
||||
/*
|
||||
* software-controlled function
|
||||
*/
|
||||
|
||||
if (sc->sc_otg.sc_mode == MUSB2_HOST_MODE) {
|
||||
reg = USBCTRL_READ4(sc, USBCTRL_MODE);
|
||||
reg |= USBCTRL_MODE_IDDIGMUX;
|
||||
reg &= ~USBCTRL_MODE_IDDIG;
|
||||
USBCTRL_WRITE4(sc, USBCTRL_MODE, reg);
|
||||
USBCTRL_WRITE4(sc, USBCTRL_UTMI,
|
||||
USBCTRL_UTMI_FSDATAEXT);
|
||||
} else {
|
||||
reg = USBCTRL_READ4(sc, USBCTRL_MODE);
|
||||
reg |= USBCTRL_MODE_IDDIGMUX;
|
||||
reg |= USBCTRL_MODE_IDDIG;
|
||||
USBCTRL_WRITE4(sc, USBCTRL_MODE, reg);
|
||||
}
|
||||
|
||||
reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF;
|
||||
USBCTRL_WRITE4(sc, USBCTRL_INTEN_SET1, reg);
|
||||
USBCTRL_WRITE4(sc, USBCTRL_INTEN_CLR0, 0xffffffff);
|
||||
|
||||
err = musbotg_init(&sc->sc_otg);
|
||||
if (!err)
|
||||
err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
|
||||
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
/* poll VBUS one time */
|
||||
musbotg_vbus_poll(sc);
|
||||
|
||||
return (0);
|
||||
|
||||
error:
|
||||
musbotg_detach(dev);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
musbotg_detach(device_t dev)
|
||||
{
|
||||
struct musbotg_super_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
/* during module unload there are lots of children leftover */
|
||||
device_delete_children(dev);
|
||||
|
||||
if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) {
|
||||
/*
|
||||
* only call musbotg_uninit() after musbotg_init()
|
||||
*/
|
||||
musbotg_uninit(&sc->sc_otg);
|
||||
|
||||
err = bus_teardown_intr(dev, sc->sc_otg.sc_irq_res,
|
||||
sc->sc_otg.sc_intr_hdl);
|
||||
sc->sc_otg.sc_intr_hdl = NULL;
|
||||
}
|
||||
|
||||
usb_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL);
|
||||
|
||||
/* Free resources if any */
|
||||
if (sc->sc_mem_res[0])
|
||||
bus_release_resources(dev, am335x_musbotg_mem_spec,
|
||||
sc->sc_mem_res);
|
||||
|
||||
if (sc->sc_otg.sc_irq_res)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
|
||||
sc->sc_otg.sc_irq_res);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t musbotg_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, musbotg_probe),
|
||||
DEVMETHOD(device_attach, musbotg_attach),
|
||||
DEVMETHOD(device_detach, musbotg_detach),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t musbotg_driver = {
|
||||
.name = "musbotg",
|
||||
.methods = musbotg_methods,
|
||||
.size = sizeof(struct musbotg_super_softc),
|
||||
};
|
||||
|
||||
static devclass_t musbotg_devclass;
|
||||
|
||||
DRIVER_MODULE(musbotg, usbss, musbotg_driver, musbotg_devclass, 0, 0);
|
||||
MODULE_DEPEND(musbotg, usbss, 1, 1, 1);
|
857
freebsd/sys/arm/ti/am335x/am335x_prcm.c
Normal file
857
freebsd/sys/arm/ti/am335x/am335x_prcm.c
Normal file
@ -0,0 +1,857 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/timeet.h>
|
||||
#include <sys/timetc.h>
|
||||
#include <sys/watchdog.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <arm/ti/tivar.h>
|
||||
#include <arm/ti/ti_scm.h>
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include "am335x_scm.h"
|
||||
|
||||
#define CM_PER 0
|
||||
#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x000)
|
||||
#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x004)
|
||||
#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x00C)
|
||||
#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x014)
|
||||
#define CM_PER_LCDC_CLKCTRL (CM_PER + 0x018)
|
||||
#define CM_PER_USB0_CLKCTRL (CM_PER + 0x01C)
|
||||
#define CM_PER_TPTC0_CLKCTRL (CM_PER + 0x024)
|
||||
#define CM_PER_UART5_CLKCTRL (CM_PER + 0x038)
|
||||
#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x03C)
|
||||
#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x044)
|
||||
#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x048)
|
||||
#define CM_PER_SPI0_CLKCTRL (CM_PER + 0x04C)
|
||||
#define CM_PER_SPI1_CLKCTRL (CM_PER + 0x050)
|
||||
#define CM_PER_UART1_CLKCTRL (CM_PER + 0x06C)
|
||||
#define CM_PER_UART2_CLKCTRL (CM_PER + 0x070)
|
||||
#define CM_PER_UART3_CLKCTRL (CM_PER + 0x074)
|
||||
#define CM_PER_UART4_CLKCTRL (CM_PER + 0x078)
|
||||
#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x07C)
|
||||
#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x080)
|
||||
#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x084)
|
||||
#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x088)
|
||||
#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0x0AC)
|
||||
#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0x0B0)
|
||||
#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0x0B4)
|
||||
#define CM_PER_TPCC_CLKCTRL (CM_PER + 0x0BC)
|
||||
#define CM_PER_EPWMSS1_CLKCTRL (CM_PER + 0x0CC)
|
||||
#define CM_PER_EPWMSS0_CLKCTRL (CM_PER + 0x0D4)
|
||||
#define CM_PER_EPWMSS2_CLKCTRL (CM_PER + 0x0D8)
|
||||
#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0x0DC)
|
||||
#define CM_PER_L3_CLKCTRL (CM_PER + 0x0E0)
|
||||
#define CM_PER_PRUSS_CLKCTRL (CM_PER + 0x0E8)
|
||||
#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0x0EC)
|
||||
#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0x0F0)
|
||||
#define CM_PER_MMC1_CLKCTRL (CM_PER + 0x0F4)
|
||||
#define CM_PER_MMC2_CLKCTRL (CM_PER + 0x0F8)
|
||||
#define CM_PER_TPTC1_CLKCTRL (CM_PER + 0x0FC)
|
||||
#define CM_PER_TPTC2_CLKCTRL (CM_PER + 0x100)
|
||||
#define CM_PER_SPINLOCK0_CLKCTRL (CM_PER + 0x10C)
|
||||
#define CM_PER_MAILBOX0_CLKCTRL (CM_PER + 0x110)
|
||||
#define CM_PER_OCPWP_L3_CLKSTCTRL (CM_PER + 0x12C)
|
||||
#define CM_PER_OCPWP_CLKCTRL (CM_PER + 0x130)
|
||||
#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144)
|
||||
#define CM_PER_PRUSS_CLKSTCTRL (CM_PER + 0x140)
|
||||
|
||||
#define CM_WKUP 0x400
|
||||
#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0x000)
|
||||
#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x004)
|
||||
#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x008)
|
||||
#define CM_WKUP_CM_L3_AON_CLKSTCTRL (CM_WKUP + 0x01C)
|
||||
#define CM_WKUP_CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x02C)
|
||||
#define CM_WKUP_CM_IDLEST_DPLL_DISP (CM_WKUP + 0x048)
|
||||
#define CM_WKUP_CM_CLKSEL_DPLL_DISP (CM_WKUP + 0x054)
|
||||
#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER (CM_WKUP + 0x07C)
|
||||
#define CM_WKUP_CM_CLKMODE_DPLL_DISP (CM_WKUP + 0x098)
|
||||
#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0x0B8)
|
||||
#define CM_WKUP_ADC_TSC_CLKCTRL (CM_WKUP + 0x0BC)
|
||||
|
||||
#define CM_DPLL 0x500
|
||||
#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x004)
|
||||
#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x008)
|
||||
#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x00C)
|
||||
#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x010)
|
||||
#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x018)
|
||||
#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x01C)
|
||||
#define CLKSEL_PRUSS_OCP_CLK (CM_DPLL + 0x030)
|
||||
|
||||
#define CM_RTC 0x800
|
||||
#define CM_RTC_RTC_CLKCTRL (CM_RTC + 0x000)
|
||||
#define CM_RTC_CLKSTCTRL (CM_RTC + 0x004)
|
||||
|
||||
#define PRM_PER 0xC00
|
||||
#define PRM_PER_RSTCTRL (PRM_PER + 0x00)
|
||||
|
||||
#define PRM_DEVICE_OFFSET 0xF00
|
||||
#define PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00)
|
||||
|
||||
struct am335x_prcm_softc {
|
||||
struct resource * res[2];
|
||||
bus_space_tag_t bst;
|
||||
bus_space_handle_t bsh;
|
||||
};
|
||||
|
||||
static struct resource_spec am335x_prcm_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
|
||||
|
||||
static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
|
||||
static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
|
||||
static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
|
||||
static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
|
||||
static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
|
||||
static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
|
||||
static int am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq);
|
||||
static void am335x_prcm_reset(void);
|
||||
static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev);
|
||||
static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
|
||||
|
||||
#define AM335X_NOOP_CLOCK_DEV(i) \
|
||||
{ .id = (i), \
|
||||
.clk_activate = am335x_clk_noop_activate, \
|
||||
.clk_deactivate = am335x_clk_noop_deactivate, \
|
||||
.clk_set_source = am335x_clk_noop_set_source, \
|
||||
.clk_accessible = NULL, \
|
||||
.clk_get_source_freq = NULL, \
|
||||
.clk_set_source_freq = NULL \
|
||||
}
|
||||
|
||||
#define AM335X_GENERIC_CLOCK_DEV(i) \
|
||||
{ .id = (i), \
|
||||
.clk_activate = am335x_clk_generic_activate, \
|
||||
.clk_deactivate = am335x_clk_generic_deactivate, \
|
||||
.clk_set_source = am335x_clk_generic_set_source, \
|
||||
.clk_accessible = NULL, \
|
||||
.clk_get_source_freq = NULL, \
|
||||
.clk_set_source_freq = NULL \
|
||||
}
|
||||
|
||||
#define AM335X_GPIO_CLOCK_DEV(i) \
|
||||
{ .id = (i), \
|
||||
.clk_activate = am335x_clk_gpio_activate, \
|
||||
.clk_deactivate = am335x_clk_generic_deactivate, \
|
||||
.clk_set_source = am335x_clk_generic_set_source, \
|
||||
.clk_accessible = NULL, \
|
||||
.clk_get_source_freq = NULL, \
|
||||
.clk_set_source_freq = NULL \
|
||||
}
|
||||
|
||||
#define AM335X_MMCHS_CLOCK_DEV(i) \
|
||||
{ .id = (i), \
|
||||
.clk_activate = am335x_clk_generic_activate, \
|
||||
.clk_deactivate = am335x_clk_generic_deactivate, \
|
||||
.clk_set_source = am335x_clk_generic_set_source, \
|
||||
.clk_accessible = NULL, \
|
||||
.clk_get_source_freq = am335x_clk_hsmmc_get_source_freq, \
|
||||
.clk_set_source_freq = NULL \
|
||||
}
|
||||
|
||||
struct ti_clock_dev ti_am335x_clk_devmap[] = {
|
||||
/* System clocks */
|
||||
{ .id = SYS_CLK,
|
||||
.clk_activate = NULL,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = am335x_clk_get_sysclk_freq,
|
||||
.clk_set_source_freq = NULL,
|
||||
},
|
||||
/* MPU (ARM) core clocks */
|
||||
{ .id = MPU_CLK,
|
||||
.clk_activate = NULL,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
|
||||
.clk_set_source_freq = NULL,
|
||||
},
|
||||
/* CPSW Ethernet Switch core clocks */
|
||||
{ .id = CPSW_CLK,
|
||||
.clk_activate = am335x_clk_cpsw_activate,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = NULL,
|
||||
.clk_set_source_freq = NULL,
|
||||
},
|
||||
|
||||
/* Mentor USB HS controller core clocks */
|
||||
{ .id = MUSB0_CLK,
|
||||
.clk_activate = am335x_clk_musb0_activate,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = NULL,
|
||||
.clk_set_source_freq = NULL,
|
||||
},
|
||||
|
||||
/* LCD controller clocks */
|
||||
{ .id = LCDC_CLK,
|
||||
.clk_activate = am335x_clk_lcdc_activate,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = am335x_clk_get_arm_disp_freq,
|
||||
.clk_set_source_freq = am335x_clk_set_arm_disp_freq,
|
||||
},
|
||||
|
||||
/* UART */
|
||||
AM335X_NOOP_CLOCK_DEV(UART1_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(UART2_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(UART3_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(UART4_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(UART5_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(UART6_CLK),
|
||||
|
||||
/* DMTimer */
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER2_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER3_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER4_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER5_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER6_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(TIMER7_CLK),
|
||||
|
||||
/* GPIO, we use hwmods as reference, not units in spec */
|
||||
AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
|
||||
AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
|
||||
AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
|
||||
AM335X_GPIO_CLOCK_DEV(GPIO4_CLK),
|
||||
|
||||
/* I2C we use hwmods as reference, not units in spec */
|
||||
AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(I2C3_CLK),
|
||||
|
||||
/* McSPI we use hwmods as reference, not units in spec */
|
||||
AM335X_GENERIC_CLOCK_DEV(SPI0_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(SPI1_CLK),
|
||||
|
||||
/* TSC_ADC */
|
||||
AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK),
|
||||
|
||||
/* EDMA */
|
||||
AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
|
||||
|
||||
/* MMCHS */
|
||||
AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
|
||||
AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
|
||||
AM335X_MMCHS_CLOCK_DEV(MMC3_CLK),
|
||||
|
||||
/* PWMSS */
|
||||
AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK),
|
||||
AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK),
|
||||
|
||||
/* System Mailbox clock */
|
||||
AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK),
|
||||
|
||||
/* SPINLOCK */
|
||||
AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK),
|
||||
|
||||
/* PRU-ICSS */
|
||||
{ .id = PRUSS_CLK,
|
||||
.clk_activate = am335x_clk_pruss_activate,
|
||||
.clk_deactivate = NULL,
|
||||
.clk_set_source = NULL,
|
||||
.clk_accessible = NULL,
|
||||
.clk_get_source_freq = NULL,
|
||||
.clk_set_source_freq = NULL,
|
||||
},
|
||||
|
||||
/* RTC */
|
||||
AM335X_GENERIC_CLOCK_DEV(RTC_CLK),
|
||||
|
||||
{ INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
struct am335x_clk_details {
|
||||
clk_ident_t id;
|
||||
uint32_t clkctrl_reg;
|
||||
uint32_t clksel_reg;
|
||||
};
|
||||
|
||||
#define _CLK_DETAIL(i, c, s) \
|
||||
{ .id = (i), \
|
||||
.clkctrl_reg = (c), \
|
||||
.clksel_reg = (s), \
|
||||
}
|
||||
|
||||
static struct am335x_clk_details g_am335x_clk_details[] = {
|
||||
|
||||
/* UART. UART0 clock not controllable. */
|
||||
_CLK_DETAIL(UART1_CLK, 0, 0),
|
||||
_CLK_DETAIL(UART2_CLK, CM_PER_UART1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(UART3_CLK, CM_PER_UART2_CLKCTRL, 0),
|
||||
_CLK_DETAIL(UART4_CLK, CM_PER_UART3_CLKCTRL, 0),
|
||||
_CLK_DETAIL(UART5_CLK, CM_PER_UART4_CLKCTRL, 0),
|
||||
_CLK_DETAIL(UART6_CLK, CM_PER_UART5_CLKCTRL, 0),
|
||||
|
||||
/* DMTimer modules */
|
||||
_CLK_DETAIL(TIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
|
||||
_CLK_DETAIL(TIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
|
||||
_CLK_DETAIL(TIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
|
||||
_CLK_DETAIL(TIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
|
||||
_CLK_DETAIL(TIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
|
||||
_CLK_DETAIL(TIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
|
||||
|
||||
/* GPIO modules, hwmods start with gpio1 */
|
||||
_CLK_DETAIL(GPIO1_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO2_CLKCTRL, 0),
|
||||
_CLK_DETAIL(GPIO4_CLK, CM_PER_GPIO3_CLKCTRL, 0),
|
||||
|
||||
/* I2C modules, hwmods start with i2c1 */
|
||||
_CLK_DETAIL(I2C1_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(I2C2_CLK, CM_PER_I2C1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(I2C3_CLK, CM_PER_I2C2_CLKCTRL, 0),
|
||||
|
||||
/* McSPI modules, hwmods start with spi0 */
|
||||
_CLK_DETAIL(SPI0_CLK, CM_PER_SPI0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(SPI1_CLK, CM_PER_SPI1_CLKCTRL, 0),
|
||||
|
||||
/* TSC_ADC module */
|
||||
_CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0),
|
||||
|
||||
/* EDMA modules */
|
||||
_CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
|
||||
_CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
|
||||
|
||||
/* MMCHS modules, hwmods start with mmc1*/
|
||||
_CLK_DETAIL(MMC1_CLK, CM_PER_MMC0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(MMC3_CLK, CM_PER_MMC1_CLKCTRL, 0),
|
||||
|
||||
/* PWMSS modules */
|
||||
_CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0),
|
||||
_CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0),
|
||||
|
||||
_CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0),
|
||||
_CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0),
|
||||
|
||||
/* RTC module */
|
||||
_CLK_DETAIL(RTC_CLK, CM_RTC_RTC_CLKCTRL, 0),
|
||||
|
||||
{ INVALID_CLK_IDENT, 0},
|
||||
};
|
||||
|
||||
/* Read/Write macros */
|
||||
#define prcm_read_4(reg) \
|
||||
bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
|
||||
#define prcm_write_4(reg, val) \
|
||||
bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
|
||||
|
||||
void am335x_prcm_setup_dmtimer(int);
|
||||
|
||||
static int
|
||||
am335x_prcm_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (ofw_bus_is_compatible(dev, "ti,am3-prcm")) {
|
||||
device_set_desc(dev, "AM335x Power and Clock Management");
|
||||
return(BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_prcm_attach(device_t dev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = device_get_softc(dev);
|
||||
unsigned int sysclk, fclk;
|
||||
|
||||
if (am335x_prcm_sc)
|
||||
return (ENXIO);
|
||||
|
||||
if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
sc->bst = rman_get_bustag(sc->res[0]);
|
||||
sc->bsh = rman_get_bushandle(sc->res[0]);
|
||||
|
||||
am335x_prcm_sc = sc;
|
||||
ti_cpu_reset = am335x_prcm_reset;
|
||||
|
||||
if (am335x_clk_get_sysclk_freq(NULL, &sysclk) != 0)
|
||||
sysclk = 0;
|
||||
if (am335x_clk_get_arm_fclk_freq(NULL, &fclk) != 0)
|
||||
fclk = 0;
|
||||
if (sysclk && fclk)
|
||||
device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
|
||||
sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
|
||||
else
|
||||
device_printf(dev, "can't read frequencies yet (SCM device not ready?)\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t am335x_prcm_methods[] = {
|
||||
DEVMETHOD(device_probe, am335x_prcm_probe),
|
||||
DEVMETHOD(device_attach, am335x_prcm_attach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t am335x_prcm_driver = {
|
||||
"am335x_prcm",
|
||||
am335x_prcm_methods,
|
||||
sizeof(struct am335x_prcm_softc),
|
||||
};
|
||||
|
||||
static devclass_t am335x_prcm_devclass;
|
||||
|
||||
DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
|
||||
am335x_prcm_devclass, 0, 0);
|
||||
MODULE_VERSION(am335x_prcm, 1);
|
||||
MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
|
||||
|
||||
static struct am335x_clk_details*
|
||||
am335x_clk_details(clk_ident_t id)
|
||||
{
|
||||
struct am335x_clk_details *walker;
|
||||
|
||||
for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
|
||||
if (id == walker->id)
|
||||
return (walker);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_noop_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
struct am335x_clk_details* clk_details;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
clk_details = am335x_clk_details(clkdev->id);
|
||||
|
||||
if (clk_details == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
|
||||
prcm_write_4(clk_details->clkctrl_reg, 2);
|
||||
while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
struct am335x_clk_details* clk_details;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
clk_details = am335x_clk_details(clkdev->id);
|
||||
|
||||
if (clk_details == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
|
||||
/* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
|
||||
prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
|
||||
while ((prcm_read_4(clk_details->clkctrl_reg) &
|
||||
(3 | (1 << 18) )) != (2 | (1 << 18)))
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
struct am335x_clk_details* clk_details;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
clk_details = am335x_clk_details(clkdev->id);
|
||||
|
||||
if (clk_details == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
|
||||
prcm_write_4(clk_details->clkctrl_reg, 0);
|
||||
while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
struct am335x_clk_details* clk_details;
|
||||
uint32_t reg;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
clk_details = am335x_clk_details(clkdev->id);
|
||||
|
||||
if (clk_details == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
switch (clksrc) {
|
||||
case EXT_CLK:
|
||||
reg = 0; /* SEL2: TCLKIN clock */
|
||||
break;
|
||||
case SYSCLK_CLK:
|
||||
reg = 1; /* SEL1: CLK_M_OSC clock */
|
||||
break;
|
||||
case F32KHZ_CLK:
|
||||
reg = 2; /* SEL3: CLK_32KHZ clock */
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
prcm_write_4(clk_details->clksel_reg, reg);
|
||||
while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
|
||||
{
|
||||
*freq = 96000000;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
|
||||
{
|
||||
uint32_t ctrl_status;
|
||||
|
||||
/* Read the input clock freq from the control module. */
|
||||
if (ti_scm_reg_read_4(SCM_CTRL_STATUS, &ctrl_status))
|
||||
return (ENXIO);
|
||||
|
||||
switch ((ctrl_status>>22) & 0x3) {
|
||||
case 0x0:
|
||||
/* 19.2Mhz */
|
||||
*freq = 19200000;
|
||||
break;
|
||||
case 0x1:
|
||||
/* 24Mhz */
|
||||
*freq = 24000000;
|
||||
break;
|
||||
case 0x2:
|
||||
/* 25Mhz */
|
||||
*freq = 25000000;
|
||||
break;
|
||||
case 0x3:
|
||||
/* 26Mhz */
|
||||
*freq = 26000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define DPLL_BYP_CLKSEL(reg) ((reg>>23) & 1)
|
||||
#define DPLL_DIV(reg) ((reg & 0x7f)+1)
|
||||
#define DPLL_MULT(reg) ((reg>>8) & 0x7FF)
|
||||
#define DPLL_MAX_MUL 0x800
|
||||
#define DPLL_MAX_DIV 0x80
|
||||
|
||||
static int
|
||||
am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t sysclk;
|
||||
|
||||
reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
|
||||
|
||||
/*Check if we are running in bypass */
|
||||
if (DPLL_BYP_CLKSEL(reg))
|
||||
return ENXIO;
|
||||
|
||||
am335x_clk_get_sysclk_freq(NULL, &sysclk);
|
||||
*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t sysclk;
|
||||
|
||||
reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_DISP);
|
||||
|
||||
/*Check if we are running in bypass */
|
||||
if (DPLL_BYP_CLKSEL(reg))
|
||||
return ENXIO;
|
||||
|
||||
am335x_clk_get_sysclk_freq(NULL, &sysclk);
|
||||
*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq)
|
||||
{
|
||||
uint32_t sysclk;
|
||||
uint32_t mul, div;
|
||||
uint32_t i, j;
|
||||
unsigned int delta, min_delta;
|
||||
|
||||
am335x_clk_get_sysclk_freq(NULL, &sysclk);
|
||||
|
||||
/* Bypass mode */
|
||||
prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
|
||||
|
||||
/* Make sure it's in bypass mode */
|
||||
while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
|
||||
& (1 << 8)))
|
||||
DELAY(10);
|
||||
|
||||
/* Dumb and non-optimal implementation */
|
||||
min_delta = freq;
|
||||
for (i = 1; i < DPLL_MAX_MUL; i++) {
|
||||
for (j = 1; j < DPLL_MAX_DIV; j++) {
|
||||
delta = abs(freq - i*(sysclk/j));
|
||||
if (delta < min_delta) {
|
||||
mul = i;
|
||||
div = j;
|
||||
min_delta = delta;
|
||||
}
|
||||
if (min_delta == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (mul << 8) | (div - 1));
|
||||
|
||||
/* Locked mode */
|
||||
prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
|
||||
|
||||
int timeout = 10000;
|
||||
while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
|
||||
& (1 << 0))) && timeout--)
|
||||
DELAY(10);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
am335x_prcm_reset(void)
|
||||
{
|
||||
prcm_write_4(PRM_RSTCTRL, (1<<1));
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* set MODULENAME to ENABLE */
|
||||
prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
|
||||
|
||||
/* wait for IDLEST to become Func(0) */
|
||||
while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
|
||||
|
||||
/*set CLKTRCTRL to SW_WKUP(2) */
|
||||
prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
|
||||
|
||||
/* wait for 125 MHz OCP clock to become active */
|
||||
while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
|
||||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
|
||||
/* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
|
||||
prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
|
||||
|
||||
/*set MODULEMODE to ENABLE(2) */
|
||||
prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
|
||||
|
||||
/* wait for MODULEMODE to become ENABLE(2) */
|
||||
while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
|
||||
DELAY(10);
|
||||
|
||||
/* wait for IDLEST to become Func(0) */
|
||||
while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
|
||||
DELAY(10);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* For now set frequency to 2*VGA_PIXEL_CLOCK
|
||||
*/
|
||||
am335x_clk_set_arm_disp_freq(clkdev, 25175000*2);
|
||||
|
||||
/*set MODULEMODE to ENABLE(2) */
|
||||
prcm_write_4(CM_PER_LCDC_CLKCTRL, 2);
|
||||
|
||||
/* wait for MODULEMODE to become ENABLE(2) */
|
||||
while ((prcm_read_4(CM_PER_LCDC_CLKCTRL) & 0x3) != 2)
|
||||
DELAY(10);
|
||||
|
||||
/* wait for IDLEST to become Func(0) */
|
||||
while(prcm_read_4(CM_PER_LCDC_CLKCTRL) & (3<<16))
|
||||
DELAY(10);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_clk_pruss_activate(struct ti_clock_dev *clkdev)
|
||||
{
|
||||
struct am335x_prcm_softc *sc = am335x_prcm_sc;
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* Set MODULEMODE to ENABLE(2) */
|
||||
prcm_write_4(CM_PER_PRUSS_CLKCTRL, 2);
|
||||
|
||||
/* Wait for MODULEMODE to become ENABLE(2) */
|
||||
while ((prcm_read_4(CM_PER_PRUSS_CLKCTRL) & 0x3) != 2)
|
||||
DELAY(10);
|
||||
|
||||
/* Set CLKTRCTRL to SW_WKUP(2) */
|
||||
prcm_write_4(CM_PER_PRUSS_CLKSTCTRL, 2);
|
||||
|
||||
/* Wait for the 200 MHz OCP clock to become active */
|
||||
while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<4)) == 0)
|
||||
DELAY(10);
|
||||
|
||||
/* Wait for the 200 MHz IEP clock to become active */
|
||||
while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<5)) == 0)
|
||||
DELAY(10);
|
||||
|
||||
/* Wait for the 192 MHz UART clock to become active */
|
||||
while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0)
|
||||
DELAY(10);
|
||||
|
||||
/* Select L3F as OCP clock */
|
||||
prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 0);
|
||||
while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 0)
|
||||
DELAY(10);
|
||||
|
||||
/* Clear the RESET bit */
|
||||
prcm_write_4(PRM_PER_RSTCTRL, prcm_read_4(PRM_PER_RSTCTRL) & ~2);
|
||||
|
||||
return (0);
|
||||
}
|
49
freebsd/sys/arm/ti/am335x/am335x_scm.h
Normal file
49
freebsd/sys/arm/ti/am335x/am335x_scm.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 __AM335X_SCM_H__
|
||||
#define __AM335X_SCM_H__
|
||||
|
||||
/* AM335x-specific registers for control module (scm) */
|
||||
#define SCM_CTRL_STATUS 0x40
|
||||
#define SCM_BGAP_CTRL 0x448
|
||||
#define SCM_BGAP_TEMP_MASK 0xff
|
||||
#define SCM_BGAP_TEMP_SHIFT 8
|
||||
#define SCM_BGAP_BGOFF (1 << 6)
|
||||
#define SCM_BGAP_SOC (1 << 4)
|
||||
#define SCM_BGAP_CLRZ (1 << 3)
|
||||
#define SCM_BGAP_CONTCONV (1 << 2)
|
||||
#define SCM_BGAP_EOCZ (1 << 1)
|
||||
#define SCM_USB_CTRL0 0x620
|
||||
#define SCM_USB_STS0 0x624
|
||||
#define SCM_USB_CTRL1 0x628
|
||||
#define SCM_USB_STS1 0x62C
|
||||
#define SCM_MAC_ID0_LO 0x630
|
||||
#define SCM_MAC_ID0_HI 0x634
|
||||
#define SCM_PWMSS_CTRL 0x664
|
||||
|
||||
#endif /* __AM335X_SCM_H__ */
|
226
freebsd/sys/arm/ti/am335x/am335x_usbss.c
Normal file
226
freebsd/sys/arm/ti/am335x/am335x_usbss.c
Normal file
@ -0,0 +1,226 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@freebsd.org>
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/stddef.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sx.h>
|
||||
#include <rtems/bsd/sys/unistd.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
|
||||
#include <dev/fdt/simplebus.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
|
||||
#include <dev/usb/usb_core.h>
|
||||
#include <dev/usb/usb_busdma.h>
|
||||
#include <dev/usb/usb_process.h>
|
||||
#include <dev/usb/usb_util.h>
|
||||
|
||||
#include <dev/usb/usb_controller.h>
|
||||
#include <dev/usb/usb_bus.h>
|
||||
#include <dev/usb/controller/musb_otg.h>
|
||||
#include <dev/usb/usb_debug.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_scm.h>
|
||||
#include <arm/ti/am335x/am335x_scm.h>
|
||||
|
||||
#define AM335X_USB_PORTS 2
|
||||
|
||||
#define USBSS_REVREG 0x00
|
||||
#define USBSS_SYSCONFIG 0x10
|
||||
#define USBSS_SYSCONFIG_SRESET 1
|
||||
|
||||
#define USBCTRL_REV 0x00
|
||||
#define USBCTRL_CTRL 0x14
|
||||
#define USBCTRL_STAT 0x18
|
||||
#define USBCTRL_IRQ_STAT0 0x30
|
||||
#define IRQ_STAT0_RXSHIFT 16
|
||||
#define IRQ_STAT0_TXSHIFT 0
|
||||
#define USBCTRL_IRQ_STAT1 0x34
|
||||
#define IRQ_STAT1_DRVVBUS (1 << 8)
|
||||
#define USBCTRL_INTEN_SET0 0x38
|
||||
#define USBCTRL_INTEN_SET1 0x3C
|
||||
#define USBCTRL_INTEN_USB_ALL 0x1ff
|
||||
#define USBCTRL_INTEN_USB_SOF (1 << 3)
|
||||
#define USBCTRL_INTEN_CLR0 0x40
|
||||
#define USBCTRL_INTEN_CLR1 0x44
|
||||
#define USBCTRL_UTMI 0xE0
|
||||
#define USBCTRL_UTMI_FSDATAEXT (1 << 1)
|
||||
#define USBCTRL_MODE 0xE8
|
||||
#define USBCTRL_MODE_IDDIG (1 << 8)
|
||||
#define USBCTRL_MODE_IDDIGMUX (1 << 7)
|
||||
|
||||
#define USBSS_WRITE4(sc, reg, val) \
|
||||
bus_write_4((sc)->sc_mem_res, (reg), (val))
|
||||
#define USBSS_READ4(sc, reg) \
|
||||
bus_read_4((sc)->sc_mem_res, (reg))
|
||||
|
||||
static device_probe_t usbss_probe;
|
||||
static device_attach_t usbss_attach;
|
||||
static device_detach_t usbss_detach;
|
||||
|
||||
struct usbss_softc {
|
||||
struct simplebus_softc simplebus_sc;
|
||||
struct resource *sc_mem_res;
|
||||
int sc_mem_rid;
|
||||
};
|
||||
|
||||
static int
|
||||
usbss_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "ti,am33xx-usb"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "TI AM33xx integrated USB OTG controller");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
usbss_attach(device_t dev)
|
||||
{
|
||||
struct usbss_softc *sc = device_get_softc(dev);
|
||||
int i;
|
||||
uint32_t rev;
|
||||
phandle_t node;
|
||||
|
||||
/* Request the memory resources */
|
||||
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->sc_mem_rid, RF_ACTIVE);
|
||||
if (sc->sc_mem_res == NULL) {
|
||||
device_printf(dev,
|
||||
"Error: could not allocate mem resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Enable device clocks. */
|
||||
ti_prcm_clk_enable(MUSB0_CLK);
|
||||
|
||||
/*
|
||||
* Reset USBSS, USB0 and USB1.
|
||||
* The registers of USB subsystem must not be accessed while the
|
||||
* reset pulse is active (200ns).
|
||||
*/
|
||||
USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET);
|
||||
DELAY(100);
|
||||
i = 10;
|
||||
while (USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) {
|
||||
DELAY(100);
|
||||
if (i-- == 0) {
|
||||
device_printf(dev, "reset timeout.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the module revision. */
|
||||
rev = USBSS_READ4(sc, USBSS_REVREG);
|
||||
device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n",
|
||||
(rev >> 8) & 7, (rev >> 6) & 3, rev & 63);
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
|
||||
if (node == -1) {
|
||||
usbss_detach(dev);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
simplebus_init(dev, node);
|
||||
|
||||
/*
|
||||
* Allow devices to identify.
|
||||
*/
|
||||
bus_generic_probe(dev);
|
||||
|
||||
/*
|
||||
* Now walk the OFW tree and attach top-level devices.
|
||||
*/
|
||||
for (node = OF_child(node); node > 0; node = OF_peer(node))
|
||||
simplebus_add_device(dev, node, 0, NULL, -1, NULL);
|
||||
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
static int
|
||||
usbss_detach(device_t dev)
|
||||
{
|
||||
struct usbss_softc *sc = device_get_softc(dev);
|
||||
|
||||
/* Free resources if any */
|
||||
if (sc->sc_mem_res)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
|
||||
sc->sc_mem_res);
|
||||
|
||||
/* during module unload there are lots of children leftover */
|
||||
device_delete_children(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t usbss_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, usbss_probe),
|
||||
DEVMETHOD(device_attach, usbss_attach),
|
||||
DEVMETHOD(device_detach, usbss_detach),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(usbss, usbss_driver, usbss_methods,
|
||||
sizeof(struct usbss_softc), simplebus_driver);
|
||||
static devclass_t usbss_devclass;
|
||||
DRIVER_MODULE(usbss, simplebus, usbss_driver, usbss_devclass, 0, 0);
|
||||
MODULE_DEPEND(usbss, usb, 1, 1, 1);
|
83
freebsd/sys/arm/ti/ti_cpuid.h
Normal file
83
freebsd/sys/arm/ti/ti_cpuid.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* Copyright (c) 2011
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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_CPUID_H_
|
||||
#define _TI_CPUID_H_
|
||||
|
||||
#define OMAP_MAKEREV(d, a, b, c) \
|
||||
(uint32_t)(((d) << 16) | (((a) & 0xf) << 8) | (((b) & 0xf) << 4) | ((c) & 0xf))
|
||||
|
||||
#define OMAP_REV_DEVICE(x) (((x) >> 16) & 0xffff)
|
||||
#define OMAP_REV_MAJOR(x) (((x) >> 8) & 0xf)
|
||||
#define OMAP_REV_MINOR(x) (((x) >> 4) & 0xf)
|
||||
#define OMAP_REV_MINOR_MINOR(x) (((x) >> 0) & 0xf)
|
||||
|
||||
#define OMAP3350_DEV 0x3530
|
||||
#define OMAP3350_REV_ES1_0 OMAP_MAKEREV(OMAP3350_DEV, 1, 0, 0)
|
||||
#define OMAP3530_REV_ES2_0 OMAP_MAKEREV(OMAP3350_DEV, 2, 0, 0)
|
||||
#define OMAP3530_REV_ES2_1 OMAP_MAKEREV(OMAP3350_DEV, 2, 1, 0)
|
||||
#define OMAP3530_REV_ES3_0 OMAP_MAKEREV(OMAP3350_DEV, 3, 0, 0)
|
||||
#define OMAP3530_REV_ES3_1 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 0)
|
||||
#define OMAP3530_REV_ES3_1_2 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 2)
|
||||
|
||||
#define OMAP4430_DEV 0x4430
|
||||
#define OMAP4430_REV_ES1_0 OMAP_MAKEREV(OMAP4430_DEV, 1, 0, 0)
|
||||
#define OMAP4430_REV_ES2_0 OMAP_MAKEREV(OMAP4430_DEV, 2, 0, 0)
|
||||
#define OMAP4430_REV_ES2_1 OMAP_MAKEREV(OMAP4430_DEV, 2, 1, 0)
|
||||
#define OMAP4430_REV_ES2_2 OMAP_MAKEREV(OMAP4430_DEV, 2, 2, 0)
|
||||
#define OMAP4430_REV_ES2_3 OMAP_MAKEREV(OMAP4430_DEV, 2, 3, 0)
|
||||
#define OMAP4430_REV_UNKNOWN OMAP_MAKEREV(OMAP4430_DEV, 9, 9, 9)
|
||||
|
||||
#define OMAP4460_DEV 0x4460
|
||||
#define OMAP4460_REV_ES1_0 OMAP_MAKEREV(OMAP4460_DEV, 1, 0, 0)
|
||||
#define OMAP4460_REV_ES1_1 OMAP_MAKEREV(OMAP4460_DEV, 1, 1, 0)
|
||||
#define OMAP4460_REV_UNKNOWN OMAP_MAKEREV(OMAP4460_DEV, 9, 9, 9)
|
||||
|
||||
#define OMAP4470_DEV 0x4470
|
||||
#define OMAP4470_REV_ES1_0 OMAP_MAKEREV(OMAP4470_DEV, 1, 0, 0)
|
||||
#define OMAP4470_REV_UNKNOWN OMAP_MAKEREV(OMAP4470_DEV, 9, 9, 9)
|
||||
|
||||
#define OMAP_UNKNOWN_DEV OMAP_MAKEREV(0x9999, 9, 9, 9)
|
||||
|
||||
#define AM335X_DEVREV(x) ((x) >> 28)
|
||||
|
||||
#define CHIP_OMAP_4 0
|
||||
#define CHIP_AM335X 1
|
||||
|
||||
extern int _ti_chip;
|
||||
|
||||
static __inline int ti_chip(void)
|
||||
{
|
||||
KASSERT(_ti_chip != -1, ("Can't determine TI Chip"));
|
||||
return _ti_chip;
|
||||
}
|
||||
|
||||
uint32_t ti_revision(void);
|
||||
|
||||
#endif /* _TI_CPUID_H_ */
|
357
freebsd/sys/arm/ti/ti_prcm.c
Normal file
357
freebsd/sys/arm/ti/ti_prcm.c
Normal file
@ -0,0 +1,357 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Ben Gray.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Power, Reset and Clock Management Module
|
||||
*
|
||||
* This is a very simple driver wrapper around the PRCM set of registers in
|
||||
* the OMAP3 chip. It allows you to turn on and off things like the functional
|
||||
* and interface clocks to the various on-chip modules.
|
||||
*
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <rtems/bsd/sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <arm/ti/ti_cpuid.h>
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
/**
|
||||
* ti_*_clk_devmap - Array of clock devices, should be defined one per SoC
|
||||
*
|
||||
* This array is typically defined in one of the targeted *_prcm_clk.c
|
||||
* files and is specific to the given SoC platform. Each entry in the array
|
||||
* corresponds to an individual clock device.
|
||||
*/
|
||||
extern struct ti_clock_dev ti_omap4_clk_devmap[];
|
||||
extern struct ti_clock_dev ti_am335x_clk_devmap[];
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_dev - returns a pointer to the clock device with given id
|
||||
* @clk: the ID of the clock device to get
|
||||
*
|
||||
* Simply iterates through the clk_devmap global array and returns a pointer
|
||||
* to the clock device if found.
|
||||
*
|
||||
* LOCKING:
|
||||
* None
|
||||
*
|
||||
* RETURNS:
|
||||
* The pointer to the clock device on success, on failure NULL is returned.
|
||||
*/
|
||||
static struct ti_clock_dev *
|
||||
ti_prcm_clk_dev(clk_ident_t clk)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
|
||||
/* Find the clock within the devmap - it's a bit inefficent having a for
|
||||
* loop for this, but this function should only called when a driver is
|
||||
* being activated so IMHO not a big issue.
|
||||
*/
|
||||
clk_dev = NULL;
|
||||
switch(ti_chip()) {
|
||||
#ifdef SOC_OMAP4
|
||||
case CHIP_OMAP_4:
|
||||
clk_dev = &(ti_omap4_clk_devmap[0]);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SOC_TI_AM335X
|
||||
case CHIP_AM335X:
|
||||
clk_dev = &(ti_am335x_clk_devmap[0]);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (clk_dev == NULL)
|
||||
panic("No clock devmap found");
|
||||
while (clk_dev->id != INVALID_CLK_IDENT) {
|
||||
if (clk_dev->id == clk) {
|
||||
return (clk_dev);
|
||||
}
|
||||
clk_dev++;
|
||||
}
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
printf("ti_prcm: Failed to find clock device (%d)\n", clk);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_valid - enables a clock for a particular module
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
|
||||
*
|
||||
* This function can enable either a functional or interface clock.
|
||||
*
|
||||
* The real work done to enable the clock is really done in the callback
|
||||
* function associated with the clock, this function is simply a wrapper
|
||||
* around that.
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_valid(clk_ident_t clk)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ti_prcm_clk_dev(clk) == NULL)
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_enable - enables a clock for a particular module
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
|
||||
*
|
||||
* This function can enable either a functional or interface clock.
|
||||
*
|
||||
* The real work done to enable the clock is really done in the callback
|
||||
* function associated with the clock, this function is simply a wrapper
|
||||
* around that.
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_enable(clk_ident_t clk)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
int ret;
|
||||
|
||||
/* Find the clock within the devmap - it's a bit inefficent having a for
|
||||
* loop for this, but this function should only called when a driver is
|
||||
* being activated so IMHO not a big issue.
|
||||
*/
|
||||
clk_dev = ti_prcm_clk_dev(clk);
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
if (clk_dev == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Activate the clock */
|
||||
if (clk_dev->clk_activate)
|
||||
ret = clk_dev->clk_activate(clk_dev);
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_disable - disables a clock for a particular module
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
|
||||
*
|
||||
* This function can enable either a functional or interface clock.
|
||||
*
|
||||
* The real work done to enable the clock is really done in the callback
|
||||
* function associated with the clock, this function is simply a wrapper
|
||||
* around that.
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_disable(clk_ident_t clk)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
int ret;
|
||||
|
||||
/* Find the clock within the devmap - it's a bit inefficent having a for
|
||||
* loop for this, but this function should only called when a driver is
|
||||
* being activated so IMHO not a big issue.
|
||||
*/
|
||||
clk_dev = ti_prcm_clk_dev(clk);
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
if (clk_dev == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Activate the clock */
|
||||
if (clk_dev->clk_deactivate)
|
||||
ret = clk_dev->clk_deactivate(clk_dev);
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_set_source - sets the source
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
|
||||
*
|
||||
* This function can enable either a functional or interface clock.
|
||||
*
|
||||
* The real work done to enable the clock is really done in the callback
|
||||
* function associated with the clock, this function is simply a wrapper
|
||||
* around that.
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
int ret;
|
||||
|
||||
/* Find the clock within the devmap - it's a bit inefficent having a for
|
||||
* loop for this, but this function should only called when a driver is
|
||||
* being activated so IMHO not a big issue.
|
||||
*/
|
||||
clk_dev = ti_prcm_clk_dev(clk);
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
if (clk_dev == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Activate the clock */
|
||||
if (clk_dev->clk_set_source)
|
||||
ret = clk_dev->clk_set_source(clk_dev, clksrc);
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_get_source_freq - gets the source clock frequency
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* @freq: pointer to an integer that upon return will contain the src freq
|
||||
*
|
||||
* This function returns the frequency of the source clock.
|
||||
*
|
||||
* The real work done to enable the clock is really done in the callback
|
||||
* function associated with the clock, this function is simply a wrapper
|
||||
* around that.
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
int ret;
|
||||
|
||||
/* Find the clock within the devmap - it's a bit inefficent having a for
|
||||
* loop for this, but this function should only called when a driver is
|
||||
* being activated so IMHO not a big issue.
|
||||
*/
|
||||
clk_dev = ti_prcm_clk_dev(clk);
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
if (clk_dev == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Get the source frequency of the clock */
|
||||
if (clk_dev->clk_get_source_freq)
|
||||
ret = clk_dev->clk_get_source_freq(clk_dev, freq);
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_prcm_clk_set_source_freq - sets the source clock frequency as close to freq as possible
|
||||
* @clk: identifier for the module to enable, see ti_prcm.h for a list
|
||||
* of possible modules.
|
||||
* @freq: requested freq
|
||||
*
|
||||
* LOCKING:
|
||||
* Internally locks the driver context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns 0 on success or positive error code on failure.
|
||||
*/
|
||||
int
|
||||
ti_prcm_clk_set_source_freq(clk_ident_t clk, unsigned int freq)
|
||||
{
|
||||
struct ti_clock_dev *clk_dev;
|
||||
int ret;
|
||||
|
||||
clk_dev = ti_prcm_clk_dev(clk);
|
||||
|
||||
/* Sanity check we managed to find the clock */
|
||||
if (clk_dev == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
/* Get the source frequency of the clock */
|
||||
if (clk_dev->clk_set_source_freq)
|
||||
ret = clk_dev->clk_set_source_freq(clk_dev, freq);
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
return (ret);
|
||||
}
|
207
freebsd/sys/arm/ti/ti_prcm.h
Normal file
207
freebsd/sys/arm/ti/ti_prcm.h
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2010
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Ben Gray.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Texas Instruments - OMAP3xxx series processors
|
||||
*
|
||||
* Reference:
|
||||
* OMAP35x Applications Processor
|
||||
* Technical Reference Manual
|
||||
* (omap35xx_techref.pdf)
|
||||
*/
|
||||
#ifndef _TI_PRCM_H_
|
||||
#define _TI_PRCM_H_
|
||||
|
||||
typedef enum {
|
||||
|
||||
INVALID_CLK_IDENT = 0,
|
||||
|
||||
/* System clocks, typically you can only call ti_prcm_clk_get_source_freq()
|
||||
* on these clocks as they are enabled by default.
|
||||
*/
|
||||
SYS_CLK = 1,
|
||||
|
||||
/* The MPU (ARM) core clock */
|
||||
MPU_CLK = 20,
|
||||
|
||||
/* MMC modules */
|
||||
MMC1_CLK = 100,
|
||||
MMC2_CLK,
|
||||
MMC3_CLK,
|
||||
MMC4_CLK,
|
||||
MMC5_CLK,
|
||||
MMC6_CLK,
|
||||
|
||||
/* I2C modules */
|
||||
I2C1_CLK = 200,
|
||||
I2C2_CLK,
|
||||
I2C3_CLK,
|
||||
I2C4_CLK,
|
||||
I2C5_CLK,
|
||||
|
||||
/* USB module(s) */
|
||||
USBTLL_CLK = 300,
|
||||
USBHSHOST_CLK,
|
||||
USBFSHOST_CLK,
|
||||
USBP1_PHY_CLK,
|
||||
USBP2_PHY_CLK,
|
||||
USBP1_UTMI_CLK,
|
||||
USBP2_UTMI_CLK,
|
||||
USBP1_HSIC_CLK,
|
||||
USBP2_HSIC_CLK,
|
||||
|
||||
/* UART modules */
|
||||
UART1_CLK = 400,
|
||||
UART2_CLK,
|
||||
UART3_CLK,
|
||||
UART4_CLK,
|
||||
UART5_CLK,
|
||||
UART6_CLK,
|
||||
UART7_CLK,
|
||||
UART8_CLK,
|
||||
UART9_CLK,
|
||||
|
||||
/* General purpose timer modules */
|
||||
TIMER1_CLK = 500,
|
||||
TIMER2_CLK,
|
||||
TIMER3_CLK,
|
||||
TIMER4_CLK,
|
||||
TIMER5_CLK,
|
||||
TIMER6_CLK,
|
||||
TIMER7_CLK,
|
||||
TIMER8_CLK,
|
||||
TIMER9_CLK,
|
||||
TIMER10_CLK,
|
||||
TIMER11_CLK,
|
||||
TIMER12_CLK,
|
||||
|
||||
/* McBSP module(s) */
|
||||
MCBSP1_CLK = 600,
|
||||
MCBSP2_CLK,
|
||||
MCBSP3_CLK,
|
||||
MCBSP4_CLK,
|
||||
MCBSP5_CLK,
|
||||
|
||||
/* General purpose I/O modules */
|
||||
GPIO1_CLK = 700,
|
||||
GPIO2_CLK,
|
||||
GPIO3_CLK,
|
||||
GPIO4_CLK,
|
||||
GPIO5_CLK,
|
||||
GPIO6_CLK,
|
||||
GPIO7_CLK,
|
||||
|
||||
/* sDMA module */
|
||||
SDMA_CLK = 800,
|
||||
|
||||
/* CPSW modules */
|
||||
CPSW_CLK = 1000,
|
||||
|
||||
/* Mentor USB modules */
|
||||
MUSB0_CLK = 1100,
|
||||
|
||||
/* EDMA module */
|
||||
EDMA_TPCC_CLK = 1200,
|
||||
EDMA_TPTC0_CLK,
|
||||
EDMA_TPTC1_CLK,
|
||||
EDMA_TPTC2_CLK,
|
||||
|
||||
/* LCD controller module */
|
||||
LCDC_CLK = 1300,
|
||||
|
||||
/* PWM modules */
|
||||
PWMSS0_CLK = 1400,
|
||||
PWMSS1_CLK,
|
||||
PWMSS2_CLK,
|
||||
|
||||
/* Mailbox modules */
|
||||
MAILBOX0_CLK = 1500,
|
||||
|
||||
/* Spinlock modules */
|
||||
SPINLOCK0_CLK = 1600,
|
||||
|
||||
PRUSS_CLK = 1700,
|
||||
|
||||
TSC_ADC_CLK = 1800,
|
||||
|
||||
/* RTC module */
|
||||
RTC_CLK = 1900,
|
||||
|
||||
/* McSPI */
|
||||
SPI0_CLK = 2000,
|
||||
SPI1_CLK,
|
||||
} clk_ident_t;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
SYSCLK_CLK, /* System clock */
|
||||
EXT_CLK,
|
||||
|
||||
F32KHZ_CLK, /* 32KHz clock */
|
||||
F48MHZ_CLK, /* 48MHz clock */
|
||||
F64MHZ_CLK, /* 64MHz clock */
|
||||
F96MHZ_CLK, /* 96MHz clock */
|
||||
|
||||
} clk_src_t;
|
||||
|
||||
struct ti_clock_dev {
|
||||
/* The profile of the timer */
|
||||
clk_ident_t id;
|
||||
|
||||
/* A bunch of callbacks associated with the clock device */
|
||||
int (*clk_activate)(struct ti_clock_dev *clkdev);
|
||||
int (*clk_deactivate)(struct ti_clock_dev *clkdev);
|
||||
int (*clk_set_source)(struct ti_clock_dev *clkdev,
|
||||
clk_src_t clksrc);
|
||||
int (*clk_accessible)(struct ti_clock_dev *clkdev);
|
||||
int (*clk_set_source_freq)(struct ti_clock_dev *clkdev,
|
||||
unsigned int freq);
|
||||
int (*clk_get_source_freq)(struct ti_clock_dev *clkdev,
|
||||
unsigned int *freq);
|
||||
};
|
||||
|
||||
int ti_prcm_clk_valid(clk_ident_t clk);
|
||||
int ti_prcm_clk_enable(clk_ident_t clk);
|
||||
int ti_prcm_clk_disable(clk_ident_t clk);
|
||||
int ti_prcm_clk_accessible(clk_ident_t clk);
|
||||
int ti_prcm_clk_disable_autoidle(clk_ident_t clk);
|
||||
int ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc);
|
||||
int ti_prcm_clk_set_source_freq(clk_ident_t clk, unsigned int freq);
|
||||
int ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq);
|
||||
void ti_prcm_reset(void);
|
||||
|
||||
#endif /* _TI_PRCM_H_ */
|
176
freebsd/sys/arm/ti/ti_scm.c
Normal file
176
freebsd/sys/arm/ti/ti_scm.c
Normal file
@ -0,0 +1,176 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Ben Gray.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SCM - System Control Module
|
||||
*
|
||||
* Hopefully in the end this module will contain a bunch of utility functions
|
||||
* for configuring and querying the general system control registers, but for
|
||||
* now it only does pin(pad) multiplexing.
|
||||
*
|
||||
* This is different from the GPIO module in that it is used to configure the
|
||||
* pins between modules not just GPIO input/output.
|
||||
*
|
||||
* This file contains the generic top level driver, however it relies on chip
|
||||
* specific settings and therefore expects an array of ti_scm_padconf structs
|
||||
* call ti_padconf_devmap to be located somewhere in the kernel.
|
||||
*
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <rtems/bsd/sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/fdt/fdt_pinctrl.h>
|
||||
|
||||
#include "ti_scm.h"
|
||||
|
||||
static struct resource_spec ti_scm_res_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
static struct ti_scm_softc *ti_scm_sc;
|
||||
|
||||
#define ti_scm_read_4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define ti_scm_write_4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
/*
|
||||
* Device part of OMAP SCM driver
|
||||
*/
|
||||
static int
|
||||
ti_scm_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "syscon"))
|
||||
return (ENXIO);
|
||||
|
||||
if (ti_scm_sc) {
|
||||
return (EEXIST);
|
||||
}
|
||||
|
||||
device_set_desc(dev, "TI Control Module");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_scm_attach - attaches the timer to the simplebus
|
||||
* @dev: new device
|
||||
*
|
||||
* Reserves memory and interrupt resources, stores the softc structure
|
||||
* globally and registers both the timecount and eventtimer objects.
|
||||
*
|
||||
* RETURNS
|
||||
* Zero on success or ENXIO if an error occuried.
|
||||
*/
|
||||
static int
|
||||
ti_scm_attach(device_t dev)
|
||||
{
|
||||
struct ti_scm_softc *sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_dev = dev;
|
||||
|
||||
if (bus_alloc_resources(dev, ti_scm_res_spec, sc->sc_res)) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Global timer interface */
|
||||
sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
|
||||
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
|
||||
|
||||
ti_scm_sc = sc;
|
||||
|
||||
/* Attach platform extensions, if any. */
|
||||
bus_generic_probe(dev);
|
||||
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
int
|
||||
ti_scm_reg_read_4(uint32_t reg, uint32_t *val)
|
||||
{
|
||||
if (!ti_scm_sc)
|
||||
return (ENXIO);
|
||||
|
||||
*val = ti_scm_read_4(ti_scm_sc, reg);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ti_scm_reg_write_4(uint32_t reg, uint32_t val)
|
||||
{
|
||||
if (!ti_scm_sc)
|
||||
return (ENXIO);
|
||||
|
||||
ti_scm_write_4(ti_scm_sc, reg, val);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static device_method_t ti_scm_methods[] = {
|
||||
DEVMETHOD(device_probe, ti_scm_probe),
|
||||
DEVMETHOD(device_attach, ti_scm_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t ti_scm_driver = {
|
||||
"ti_scm",
|
||||
ti_scm_methods,
|
||||
sizeof(struct ti_scm_softc),
|
||||
};
|
||||
|
||||
static devclass_t ti_scm_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(ti_scm, simplebus, ti_scm_driver, ti_scm_devclass, 0, 0,
|
||||
BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
|
56
freebsd/sys/arm/ti/ti_scm.h
Normal file
56
freebsd/sys/arm/ti/ti_scm.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2010
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Ben Gray.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Functions to configure the PIN multiplexing on the chip.
|
||||
*
|
||||
* This is different from the GPIO module in that it is used to configure the
|
||||
* pins between modules not just GPIO input output.
|
||||
*
|
||||
*/
|
||||
#ifndef _TI_SCM_H_
|
||||
#define _TI_SCM_H_
|
||||
|
||||
struct ti_scm_softc {
|
||||
device_t sc_dev;
|
||||
struct resource * sc_res[4];
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
};
|
||||
|
||||
int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
|
||||
int ti_scm_reg_write_4(uint32_t reg, uint32_t val);
|
||||
|
||||
#endif /* _TI_SCM_H_ */
|
41
freebsd/sys/arm/ti/tivar.h
Normal file
41
freebsd/sys/arm/ti/tivar.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2010
|
||||
* Ben Gray <ben.r.gray@gmail.com>.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Ben Gray.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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 _TIVAR_H_
|
||||
#define _TIVAR_H_
|
||||
|
||||
/* board-dependent reset function implementation */
|
||||
extern void (*ti_cpu_reset)(void);
|
||||
|
||||
#endif /* _TIVAR_H_ */
|
58
freebsd/sys/dev/fdt/fdt_pinctrl.h
Normal file
58
freebsd/sys/dev/fdt/fdt_pinctrl.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
|
||||
* 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 DEV_FDT_PINCTRL_H
|
||||
#define DEV_FDT_PINCTRL_H
|
||||
|
||||
#include <rtems/bsd/local/fdt_pinctrl_if.h>
|
||||
|
||||
/*
|
||||
* Configure pins by name or index. This looks up the pinctrl-N property in
|
||||
* client's fdt data by index or name, and passes each handle in it to the
|
||||
* pinctrl driver for configuration.
|
||||
*/
|
||||
int fdt_pinctrl_configure(device_t client, u_int index);
|
||||
int fdt_pinctrl_configure_by_name(device_t client, const char * name);
|
||||
|
||||
/*
|
||||
* Register a pinctrl driver so that it can be used by other devices which call
|
||||
* fdt_pinctrl_configure(). The pinprop argument is the name of a property that
|
||||
* identifies each descendent of the pinctrl node which is a pin configuration
|
||||
* node whose xref phandle can be passed to FDT_PINCTRL_CONFIGURE(). If this is
|
||||
* NULL, every descendant node is registered.
|
||||
*/
|
||||
int fdt_pinctrl_register(device_t pinctrl, const char *pinprop);
|
||||
|
||||
/*
|
||||
* Walk the device tree and configure pins for each enabled device whose
|
||||
* pinctrl-0 property contains references to nodes which are children of the
|
||||
* given pinctrl device. This helper routine is for use by pinctrl drivers.
|
||||
*/
|
||||
int fdt_pinctrl_configure_tree(device_t pinctrl);
|
||||
|
||||
#endif /* DEV_FDT_PINCTRL_H */
|
||||
|
4257
freebsd/sys/dev/usb/controller/musb_otg.c
Normal file
4257
freebsd/sys/dev/usb/controller/musb_otg.c
Normal file
File diff suppressed because it is too large
Load Diff
435
freebsd/sys/dev/usb/controller/musb_otg.h
Normal file
435
freebsd/sys/dev/usb/controller/musb_otg.h
Normal file
@ -0,0 +1,435 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2008 Hans Petter Selasky. 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file defines the registers of the Mentor Graphics USB OnTheGo
|
||||
* Inventra chip.
|
||||
*/
|
||||
|
||||
#ifndef _MUSB2_OTG_H_
|
||||
#define _MUSB2_OTG_H_
|
||||
|
||||
#define MUSB2_MAX_DEVICES USB_MAX_DEVICES
|
||||
|
||||
/* Common registers */
|
||||
|
||||
#define MUSB2_REG_FADDR 0x0000 /* function address register */
|
||||
#define MUSB2_MASK_FADDR 0x7F
|
||||
|
||||
#define MUSB2_REG_POWER 0x0001 /* power register */
|
||||
#define MUSB2_MASK_SUSPM_ENA 0x01
|
||||
#define MUSB2_MASK_SUSPMODE 0x02
|
||||
#define MUSB2_MASK_RESUME 0x04
|
||||
#define MUSB2_MASK_RESET 0x08
|
||||
#define MUSB2_MASK_HSMODE 0x10
|
||||
#define MUSB2_MASK_HSENAB 0x20
|
||||
#define MUSB2_MASK_SOFTC 0x40
|
||||
#define MUSB2_MASK_ISOUPD 0x80
|
||||
|
||||
/* Endpoint interrupt handling */
|
||||
|
||||
#define MUSB2_REG_INTTX 0x0002 /* transmit interrupt register */
|
||||
#define MUSB2_REG_INTRX 0x0004 /* receive interrupt register */
|
||||
#define MUSB2_REG_INTTXE 0x0006 /* transmit interrupt enable register */
|
||||
#define MUSB2_REG_INTRXE 0x0008 /* receive interrupt enable register */
|
||||
#define MUSB2_MASK_EPINT(epn) (1 << (epn)) /* epn = [0..15] */
|
||||
|
||||
/* Common interrupt handling */
|
||||
|
||||
#define MUSB2_REG_INTUSB 0x000A /* USB interrupt register */
|
||||
#define MUSB2_MASK_ISUSP 0x01
|
||||
#define MUSB2_MASK_IRESUME 0x02
|
||||
#define MUSB2_MASK_IRESET 0x04
|
||||
#define MUSB2_MASK_IBABBLE 0x04
|
||||
#define MUSB2_MASK_ISOF 0x08
|
||||
#define MUSB2_MASK_ICONN 0x10
|
||||
#define MUSB2_MASK_IDISC 0x20
|
||||
#define MUSB2_MASK_ISESSRQ 0x40
|
||||
#define MUSB2_MASK_IVBUSERR 0x80
|
||||
|
||||
#define MUSB2_REG_INTUSBE 0x000B /* USB interrupt enable register */
|
||||
#define MUSB2_REG_FRAME 0x000C /* USB frame register */
|
||||
#define MUSB2_MASK_FRAME 0x3FF /* 0..1023 */
|
||||
|
||||
#define MUSB2_REG_EPINDEX 0x000E /* endpoint index register */
|
||||
#define MUSB2_MASK_EPINDEX 0x0F
|
||||
|
||||
#define MUSB2_REG_TESTMODE 0x000F /* test mode register */
|
||||
#define MUSB2_MASK_TSE0_NAK 0x01
|
||||
#define MUSB2_MASK_TJ 0x02
|
||||
#define MUSB2_MASK_TK 0x04
|
||||
#define MUSB2_MASK_TPACKET 0x08
|
||||
#define MUSB2_MASK_TFORCE_HS 0x10
|
||||
#define MUSB2_MASK_TFORCE_LS 0x20
|
||||
#define MUSB2_MASK_TFIFO_ACC 0x40
|
||||
#define MUSB2_MASK_TFORCE_HC 0x80
|
||||
|
||||
#define MUSB2_REG_INDEXED_CSR 0x0010 /* EP control status register offset */
|
||||
|
||||
#define MUSB2_REG_TXMAXP (0x0000 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_REG_RXMAXP (0x0004 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_PKTSIZE 0x03FF /* in bytes, should be even */
|
||||
#define MUSB2_MASK_PKTMULT 0xFC00 /* HS packet multiplier: 0..2 */
|
||||
|
||||
#define MUSB2_REG_TXCSRL (0x0002 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_CSRL_TXPKTRDY 0x01
|
||||
#define MUSB2_MASK_CSRL_TXFIFONEMPTY 0x02
|
||||
#define MUSB2_MASK_CSRL_TXUNDERRUN 0x04 /* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_TXERROR 0x04 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_TXFFLUSH 0x08
|
||||
#define MUSB2_MASK_CSRL_TXSENDSTALL 0x10/* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_TXSETUPPKT 0x10 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_TXSENTSTALL 0x20/* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_TXSTALLED 0x20 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_TXDT_CLR 0x40
|
||||
#define MUSB2_MASK_CSRL_TXINCOMP 0x80 /* Device mode */
|
||||
#define MUSB2_MASK_CSRL_TXNAKTO 0x80 /* Host mode */
|
||||
|
||||
/* Device Side Mode */
|
||||
#define MUSB2_MASK_CSR0L_RXPKTRDY 0x01
|
||||
#define MUSB2_MASK_CSR0L_TXPKTRDY 0x02
|
||||
#define MUSB2_MASK_CSR0L_SENTSTALL 0x04
|
||||
#define MUSB2_MASK_CSR0L_DATAEND 0x08
|
||||
#define MUSB2_MASK_CSR0L_SETUPEND 0x10
|
||||
#define MUSB2_MASK_CSR0L_SENDSTALL 0x20
|
||||
#define MUSB2_MASK_CSR0L_RXPKTRDY_CLR 0x40
|
||||
#define MUSB2_MASK_CSR0L_SETUPEND_CLR 0x80
|
||||
|
||||
/* Host Side Mode */
|
||||
#define MUSB2_MASK_CSR0L_TXFIFONEMPTY 0x02
|
||||
#define MUSB2_MASK_CSR0L_RXSTALL 0x04
|
||||
#define MUSB2_MASK_CSR0L_SETUPPKT 0x08
|
||||
#define MUSB2_MASK_CSR0L_ERROR 0x10
|
||||
#define MUSB2_MASK_CSR0L_REQPKT 0x20
|
||||
#define MUSB2_MASK_CSR0L_STATUSPKT 0x40
|
||||
#define MUSB2_MASK_CSR0L_NAKTIMO 0x80
|
||||
|
||||
#define MUSB2_REG_TXCSRH (0x0003 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_CSRH_TXDT_VAL 0x01 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRH_TXDT_WREN 0x02 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRH_TXDMAREQMODE 0x04
|
||||
#define MUSB2_MASK_CSRH_TXDT_SWITCH 0x08
|
||||
#define MUSB2_MASK_CSRH_TXDMAREQENA 0x10
|
||||
#define MUSB2_MASK_CSRH_RXMODE 0x00
|
||||
#define MUSB2_MASK_CSRH_TXMODE 0x20
|
||||
#define MUSB2_MASK_CSRH_TXISO 0x40 /* Device Mode */
|
||||
#define MUSB2_MASK_CSRH_TXAUTOSET 0x80
|
||||
|
||||
#define MUSB2_MASK_CSR0H_FFLUSH 0x01 /* Device Side flush FIFO */
|
||||
#define MUSB2_MASK_CSR0H_DT 0x02 /* Host Side data toggle */
|
||||
#define MUSB2_MASK_CSR0H_DT_WREN 0x04 /* Host Side */
|
||||
#define MUSB2_MASK_CSR0H_PING_DIS 0x08 /* Host Side */
|
||||
|
||||
#define MUSB2_REG_RXCSRL (0x0006 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_CSRL_RXPKTRDY 0x01
|
||||
#define MUSB2_MASK_CSRL_RXFIFOFULL 0x02
|
||||
#define MUSB2_MASK_CSRL_RXOVERRUN 0x04 /* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_RXERROR 0x04 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_RXDATAERR 0x08 /* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_RXNAKTO 0x08 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_RXFFLUSH 0x10
|
||||
#define MUSB2_MASK_CSRL_RXSENDSTALL 0x20/* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_RXREQPKT 0x20 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_RXSENTSTALL 0x40/* Device Mode */
|
||||
#define MUSB2_MASK_CSRL_RXSTALL 0x40 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRL_RXDT_CLR 0x80
|
||||
|
||||
#define MUSB2_REG_RXCSRH (0x0007 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_CSRH_RXINCOMP 0x01
|
||||
#define MUSB2_MASK_CSRH_RXDT_VAL 0x02 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRH_RXDT_WREN 0x04 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRH_RXDMAREQMODE 0x08
|
||||
#define MUSB2_MASK_CSRH_RXNYET 0x10
|
||||
#define MUSB2_MASK_CSRH_RXDMAREQENA 0x20
|
||||
#define MUSB2_MASK_CSRH_RXISO 0x40 /* Device Mode */
|
||||
#define MUSB2_MASK_CSRH_RXAUTOREQ 0x40 /* Host Mode */
|
||||
#define MUSB2_MASK_CSRH_RXAUTOCLEAR 0x80
|
||||
|
||||
#define MUSB2_REG_RXCOUNT (0x0008 + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_RXCOUNT 0xFFFF
|
||||
|
||||
#define MUSB2_REG_TXTI (0x000A + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_REG_RXTI (0x000C + MUSB2_REG_INDEXED_CSR)
|
||||
|
||||
/* Host Mode */
|
||||
#define MUSB2_MASK_TI_SPEED 0xC0
|
||||
#define MUSB2_MASK_TI_SPEED_LO 0xC0
|
||||
#define MUSB2_MASK_TI_SPEED_FS 0x80
|
||||
#define MUSB2_MASK_TI_SPEED_HS 0x40
|
||||
#define MUSB2_MASK_TI_PROTO_CTRL 0x00
|
||||
#define MUSB2_MASK_TI_PROTO_ISOC 0x10
|
||||
#define MUSB2_MASK_TI_PROTO_BULK 0x20
|
||||
#define MUSB2_MASK_TI_PROTO_INTR 0x30
|
||||
#define MUSB2_MASK_TI_EP_NUM 0x0F
|
||||
|
||||
#define MUSB2_REG_TXNAKLIMIT (0x000B /* EPN=0 */ + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_REG_RXNAKLIMIT (0x000D /* EPN=0 */ + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_NAKLIMIT 0xFF
|
||||
|
||||
#define MUSB2_REG_FSIZE (0x000F + MUSB2_REG_INDEXED_CSR)
|
||||
#define MUSB2_MASK_RX_FSIZE 0xF0 /* 3..13, 2**n bytes */
|
||||
#define MUSB2_MASK_TX_FSIZE 0x0F /* 3..13, 2**n bytes */
|
||||
|
||||
#define MUSB2_REG_EPFIFO(n) (0x0020 + (4*(n)))
|
||||
|
||||
#define MUSB2_REG_CONFDATA (0x000F + MUSB2_REG_INDEXED_CSR) /* EPN=0 */
|
||||
#define MUSB2_MASK_CD_UTMI_DW 0x01
|
||||
#define MUSB2_MASK_CD_SOFTCONE 0x02
|
||||
#define MUSB2_MASK_CD_DYNFIFOSZ 0x04
|
||||
#define MUSB2_MASK_CD_HBTXE 0x08
|
||||
#define MUSB2_MASK_CD_HBRXE 0x10
|
||||
#define MUSB2_MASK_CD_BIGEND 0x20
|
||||
#define MUSB2_MASK_CD_MPTXE 0x40
|
||||
#define MUSB2_MASK_CD_MPRXE 0x80
|
||||
|
||||
/* Various registers */
|
||||
|
||||
#define MUSB2_REG_DEVCTL 0x0060
|
||||
#define MUSB2_MASK_SESS 0x01
|
||||
#define MUSB2_MASK_HOSTREQ 0x02
|
||||
#define MUSB2_MASK_HOSTMD 0x04
|
||||
#define MUSB2_MASK_VBUS0 0x08
|
||||
#define MUSB2_MASK_VBUS1 0x10
|
||||
#define MUSB2_MASK_LSDEV 0x20
|
||||
#define MUSB2_MASK_FSDEV 0x40
|
||||
#define MUSB2_MASK_BDEV 0x80
|
||||
|
||||
#define MUSB2_REG_MISC 0x0061
|
||||
#define MUSB2_MASK_RXEDMA 0x01
|
||||
#define MUSB2_MASK_TXEDMA 0x02
|
||||
|
||||
#define MUSB2_REG_TXFIFOSZ 0x0062
|
||||
#define MUSB2_REG_RXFIFOSZ 0x0063
|
||||
#define MUSB2_MASK_FIFODB 0x10 /* set if double buffering, r/w */
|
||||
#define MUSB2_MASK_FIFOSZ 0x0F
|
||||
#define MUSB2_VAL_FIFOSZ_8 0
|
||||
#define MUSB2_VAL_FIFOSZ_16 1
|
||||
#define MUSB2_VAL_FIFOSZ_32 2
|
||||
#define MUSB2_VAL_FIFOSZ_64 3
|
||||
#define MUSB2_VAL_FIFOSZ_128 4
|
||||
#define MUSB2_VAL_FIFOSZ_256 5
|
||||
#define MUSB2_VAL_FIFOSZ_512 6
|
||||
#define MUSB2_VAL_FIFOSZ_1024 7
|
||||
#define MUSB2_VAL_FIFOSZ_2048 8
|
||||
#define MUSB2_VAL_FIFOSZ_4096 9
|
||||
|
||||
#define MUSB2_REG_TXFIFOADD 0x0064
|
||||
#define MUSB2_REG_RXFIFOADD 0x0066
|
||||
#define MUSB2_MASK_FIFOADD 0xFFF /* unit is 8-bytes */
|
||||
|
||||
#define MUSB2_REG_VSTATUS 0x0068
|
||||
#define MUSB2_REG_VCONTROL 0x0068
|
||||
#define MUSB2_REG_HWVERS 0x006C
|
||||
#define MUSB2_REG_ULPI_BASE 0x0070
|
||||
|
||||
#define MUSB2_REG_EPINFO 0x0078
|
||||
#define MUSB2_MASK_NRXEP 0xF0
|
||||
#define MUSB2_MASK_NTXEP 0x0F
|
||||
|
||||
#define MUSB2_REG_RAMINFO 0x0079
|
||||
#define MUSB2_REG_LINKINFO 0x007A
|
||||
|
||||
#define MUSB2_REG_VPLEN 0x007B
|
||||
#define MUSB2_MASK_VPLEN 0xFF
|
||||
|
||||
#define MUSB2_REG_HS_EOF1 0x007C
|
||||
#define MUSB2_REG_FS_EOF1 0x007D
|
||||
#define MUSB2_REG_LS_EOF1 0x007E
|
||||
#define MUSB2_REG_SOFT_RST 0x007F
|
||||
#define MUSB2_MASK_SRST 0x01
|
||||
#define MUSB2_MASK_SRSTX 0x02
|
||||
|
||||
#define MUSB2_REG_RQPKTCOUNT(n) (0x0300 + (4*(n))
|
||||
#define MUSB2_REG_RXDBDIS 0x0340
|
||||
#define MUSB2_REG_TXDBDIS 0x0342
|
||||
#define MUSB2_MASK_DB(n) (1 << (n)) /* disable double buffer, n = [0..15] */
|
||||
|
||||
#define MUSB2_REG_CHIRPTO 0x0344
|
||||
#define MUSB2_REG_HSRESUM 0x0346
|
||||
|
||||
/* Host Mode only registers */
|
||||
|
||||
#define MUSB2_REG_TXFADDR(n) (0x0080 + (8*(n)))
|
||||
#define MUSB2_REG_TXHADDR(n) (0x0082 + (8*(n)))
|
||||
#define MUSB2_REG_TXHUBPORT(n) (0x0083 + (8*(n)))
|
||||
#define MUSB2_REG_RXFADDR(n) (0x0084 + (8*(n)))
|
||||
#define MUSB2_REG_RXHADDR(n) (0x0086 + (8*(n)))
|
||||
#define MUSB2_REG_RXHUBPORT(n) (0x0087 + (8*(n)))
|
||||
|
||||
#define MUSB2_EP_MAX 16 /* maximum number of endpoints */
|
||||
|
||||
#define MUSB2_DEVICE_MODE 0
|
||||
#define MUSB2_HOST_MODE 1
|
||||
|
||||
#define MUSB2_READ_2(sc, reg) \
|
||||
bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
|
||||
|
||||
#define MUSB2_WRITE_2(sc, reg, data) \
|
||||
bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
|
||||
|
||||
#define MUSB2_READ_1(sc, reg) \
|
||||
bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
|
||||
|
||||
#define MUSB2_WRITE_1(sc, reg, data) \
|
||||
bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
|
||||
|
||||
struct musbotg_td;
|
||||
struct musbotg_softc;
|
||||
|
||||
typedef uint8_t (musbotg_cmd_t)(struct musbotg_td *td);
|
||||
|
||||
struct musbotg_dma {
|
||||
struct musbotg_softc *sc;
|
||||
uint32_t dma_chan;
|
||||
uint8_t busy:1;
|
||||
uint8_t complete:1;
|
||||
uint8_t error:1;
|
||||
};
|
||||
|
||||
struct musbotg_td {
|
||||
struct musbotg_td *obj_next;
|
||||
musbotg_cmd_t *func;
|
||||
struct usb_page_cache *pc;
|
||||
uint32_t offset;
|
||||
uint32_t remainder;
|
||||
uint16_t max_frame_size; /* packet_size * mult */
|
||||
uint16_t reg_max_packet;
|
||||
uint8_t ep_no;
|
||||
uint8_t transfer_type;
|
||||
uint8_t error:1;
|
||||
uint8_t alt_next:1;
|
||||
uint8_t short_pkt:1;
|
||||
uint8_t support_multi_buffer:1;
|
||||
uint8_t did_stall:1;
|
||||
uint8_t dma_enabled:1;
|
||||
uint8_t transaction_started:1;
|
||||
uint8_t dev_addr;
|
||||
uint8_t toggle;
|
||||
int8_t channel;
|
||||
uint8_t haddr;
|
||||
uint8_t hport;
|
||||
};
|
||||
|
||||
struct musbotg_std_temp {
|
||||
musbotg_cmd_t *func;
|
||||
struct usb_page_cache *pc;
|
||||
struct musbotg_td *td;
|
||||
struct musbotg_td *td_next;
|
||||
uint32_t len;
|
||||
uint32_t offset;
|
||||
uint16_t max_frame_size;
|
||||
uint8_t short_pkt;
|
||||
/*
|
||||
* short_pkt = 0: transfer should be short terminated
|
||||
* short_pkt = 1: transfer should not be short terminated
|
||||
*/
|
||||
uint8_t setup_alt_next;
|
||||
uint8_t did_stall;
|
||||
uint8_t dev_addr;
|
||||
int8_t channel;
|
||||
uint8_t haddr;
|
||||
uint8_t hport;
|
||||
uint8_t transfer_type;
|
||||
};
|
||||
|
||||
struct musbotg_config_desc {
|
||||
struct usb_config_descriptor confd;
|
||||
struct usb_interface_descriptor ifcd;
|
||||
struct usb_endpoint_descriptor endpd;
|
||||
} __packed;
|
||||
|
||||
union musbotg_hub_temp {
|
||||
uWord wValue;
|
||||
struct usb_port_status ps;
|
||||
};
|
||||
|
||||
struct musbotg_flags {
|
||||
uint8_t change_connect:1;
|
||||
uint8_t change_suspend:1;
|
||||
uint8_t change_reset:1;
|
||||
uint8_t change_over_current:1;
|
||||
uint8_t change_enabled:1;
|
||||
uint8_t status_suspend:1; /* set if suspended */
|
||||
uint8_t status_vbus:1; /* set if present */
|
||||
uint8_t status_bus_reset:1; /* set if reset complete */
|
||||
uint8_t status_high_speed:1; /* set if High Speed is selected */
|
||||
uint8_t remote_wakeup:1;
|
||||
uint8_t self_powered:1;
|
||||
uint8_t clocks_off:1;
|
||||
uint8_t port_powered:1;
|
||||
uint8_t port_enabled:1;
|
||||
uint8_t port_over_current:1;
|
||||
uint8_t d_pulled_up:1;
|
||||
};
|
||||
|
||||
struct musbotg_softc {
|
||||
struct usb_bus sc_bus;
|
||||
union musbotg_hub_temp sc_hub_temp;
|
||||
struct usb_hw_ep_profile sc_hw_ep_profile[MUSB2_EP_MAX];
|
||||
|
||||
struct usb_device *sc_devices[MUSB2_MAX_DEVICES];
|
||||
struct resource *sc_io_res;
|
||||
struct resource *sc_irq_res;
|
||||
void *sc_intr_hdl;
|
||||
bus_size_t sc_io_size;
|
||||
bus_space_tag_t sc_io_tag;
|
||||
bus_space_handle_t sc_io_hdl;
|
||||
|
||||
void (*sc_clocks_on) (void *arg);
|
||||
void (*sc_clocks_off) (void *arg);
|
||||
void (*sc_ep_int_set) (struct musbotg_softc *sc, int ep, int on);
|
||||
void *sc_clocks_arg;
|
||||
|
||||
uint32_t sc_bounce_buf[(1024 * 3) / 4]; /* bounce buffer */
|
||||
|
||||
uint8_t sc_ep_max; /* maximum number of RX and TX
|
||||
* endpoints supported */
|
||||
uint8_t sc_rt_addr; /* root HUB address */
|
||||
uint8_t sc_dv_addr; /* device address */
|
||||
uint8_t sc_conf; /* root HUB config */
|
||||
uint8_t sc_ep0_busy; /* set if ep0 is busy */
|
||||
uint8_t sc_ep0_cmd; /* pending commands */
|
||||
uint8_t sc_conf_data; /* copy of hardware register */
|
||||
|
||||
uint8_t sc_hub_idata[1];
|
||||
uint16_t sc_channel_mask; /* 16 endpoints */
|
||||
|
||||
struct musbotg_flags sc_flags;
|
||||
uint8_t sc_id;
|
||||
uint8_t sc_mode;
|
||||
void *sc_platform_data;
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
|
||||
usb_error_t musbotg_init(struct musbotg_softc *sc);
|
||||
void musbotg_uninit(struct musbotg_softc *sc);
|
||||
void musbotg_interrupt(struct musbotg_softc *sc,
|
||||
uint16_t rxstat, uint16_t txstat, uint8_t stat);
|
||||
void musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on);
|
||||
void musbotg_connect_interrupt(struct musbotg_softc *sc);
|
||||
|
||||
#endif /* _MUSB2_OTG_H_ */
|
106
freebsd/sys/sys/timeet.h
Normal file
106
freebsd/sys/sys/timeet.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*-
|
||||
* Copyright (c) 2010-2013 Alexander Motin <mav@FreeBSD.org>
|
||||
* 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,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 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 _SYS_TIMEEC_H_
|
||||
#define _SYS_TIMEEC_H_
|
||||
|
||||
#ifndef _KERNEL
|
||||
#error "no user-serviceable parts inside"
|
||||
#endif
|
||||
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* `struct eventtimer' is the interface between the hardware which implements
|
||||
* a event timer and the MI code which uses this to receive time events.
|
||||
*/
|
||||
|
||||
struct eventtimer;
|
||||
typedef int et_start_t(struct eventtimer *et,
|
||||
sbintime_t first, sbintime_t period);
|
||||
typedef int et_stop_t(struct eventtimer *et);
|
||||
typedef void et_event_cb_t(struct eventtimer *et, void *arg);
|
||||
typedef int et_deregister_cb_t(struct eventtimer *et, void *arg);
|
||||
|
||||
struct eventtimer {
|
||||
SLIST_ENTRY(eventtimer) et_all;
|
||||
/* Pointer to the next event timer. */
|
||||
const char *et_name;
|
||||
/* Name of the event timer. */
|
||||
int et_flags;
|
||||
/* Set of capabilities flags: */
|
||||
#define ET_FLAGS_PERIODIC 1
|
||||
#define ET_FLAGS_ONESHOT 2
|
||||
#define ET_FLAGS_PERCPU 4
|
||||
#define ET_FLAGS_C3STOP 8
|
||||
#define ET_FLAGS_POW2DIV 16
|
||||
int et_quality;
|
||||
/*
|
||||
* Used to determine if this timecounter is better than
|
||||
* another timecounter. Higher means better.
|
||||
*/
|
||||
int et_active;
|
||||
u_int64_t et_frequency;
|
||||
/* Base frequency in Hz. */
|
||||
sbintime_t et_min_period;
|
||||
sbintime_t et_max_period;
|
||||
et_start_t *et_start;
|
||||
et_stop_t *et_stop;
|
||||
et_event_cb_t *et_event_cb;
|
||||
et_deregister_cb_t *et_deregister_cb;
|
||||
void *et_arg;
|
||||
void *et_priv;
|
||||
struct sysctl_oid *et_sysctl;
|
||||
/* Pointer to the event timer's private parts. */
|
||||
};
|
||||
|
||||
extern struct mtx et_eventtimers_mtx;
|
||||
#define ET_LOCK() mtx_lock(&et_eventtimers_mtx)
|
||||
#define ET_UNLOCK() mtx_unlock(&et_eventtimers_mtx)
|
||||
|
||||
/* Driver API */
|
||||
int et_register(struct eventtimer *et);
|
||||
int et_deregister(struct eventtimer *et);
|
||||
void et_change_frequency(struct eventtimer *et, uint64_t newfreq);
|
||||
/* Consumer API */
|
||||
struct eventtimer *et_find(const char *name, int check, int want);
|
||||
int et_init(struct eventtimer *et, et_event_cb_t *event,
|
||||
et_deregister_cb_t *deregister, void *arg);
|
||||
int et_start(struct eventtimer *et, sbintime_t first, sbintime_t period);
|
||||
int et_stop(struct eventtimer *et);
|
||||
int et_ban(struct eventtimer *et);
|
||||
int et_free(struct eventtimer *et);
|
||||
|
||||
#ifdef SYSCTL_DECL
|
||||
SYSCTL_DECL(_kern_eventtimer);
|
||||
#endif
|
||||
#endif /* !_SYS_TIMETC_H_ */
|
||||
|
115
freebsd/sys/sys/watchdog.h
Normal file
115
freebsd/sys/sys/watchdog.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Poul-Henning Kamp
|
||||
* Copyright (c) 2013 iXsystems.com,
|
||||
* author: Alfred Perlstein <alfred@freebsd.org>
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _SYS_WATCHDOG_H
|
||||
#define _SYS_WATCHDOG_H
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#define _PATH_WATCHDOG "fido"
|
||||
|
||||
#define WDIOCPATPAT _IOW('W', 42, u_int) /* pat the watchdog */
|
||||
#define WDIOC_SETTIMEOUT _IOW('W', 43, int) /* set/reset the timer */
|
||||
#define WDIOC_GETTIMEOUT _IOR('W', 44, int) /* get total timeout */
|
||||
#define WDIOC_GETTIMELEFT _IOR('W', 45, int) /* get time left */
|
||||
#define WDIOC_GETPRETIMEOUT _IOR('W', 46, int) /* get the pre-timeout */
|
||||
#define WDIOC_SETPRETIMEOUT _IOW('W', 47, int) /* set the pre-timeout */
|
||||
/* set the action when a pre-timeout occurs see: WD_SOFT_* */
|
||||
#define WDIOC_SETPRETIMEOUTACT _IOW('W', 48, int)
|
||||
|
||||
/* use software watchdog instead of hardware */
|
||||
#define WDIOC_SETSOFT _IOW('W', 49, int)
|
||||
#define WDIOC_SETSOFTTIMEOUTACT _IOW('W', 50, int)
|
||||
|
||||
#define WD_ACTIVE 0x8000000
|
||||
/*
|
||||
* Watchdog reset, timeout set to value in WD_INTERVAL field.
|
||||
* The kernel will arm the watchdog and unless the userland
|
||||
* program calls WDIOCPATPAT again before the timer expires
|
||||
* the system will reinitialize.
|
||||
*/
|
||||
|
||||
#define WD_PASSIVE 0x0400000
|
||||
/*
|
||||
* Set the watchdog in passive mode.
|
||||
* The kernel will chose an appropriate timeout duration and
|
||||
* periodically reset the timer provided everything looks all
|
||||
* right to the kernel.
|
||||
*/
|
||||
|
||||
#define WD_LASTVAL 0x0200000
|
||||
/*
|
||||
* Use the already last used timeout value.
|
||||
* The kernel will use as timeout the last valid timeout provided.
|
||||
*/
|
||||
|
||||
#define WD_INTERVAL 0x00000ff
|
||||
/*
|
||||
* Mask for duration bits.
|
||||
* The watchdog will have a nominal patience of 2^N * nanoseconds.
|
||||
* Example: N == 30 gives a patience of 2^30 nanoseconds ~= 1 second.
|
||||
* NB: Expect variance in the +/- 10-20% range.
|
||||
*/
|
||||
|
||||
/* Handy macros for humans not used to power of two nanoseconds */
|
||||
#define WD_TO_NEVER 0
|
||||
#define WD_TO_1MS 20
|
||||
#define WD_TO_125MS 27
|
||||
#define WD_TO_250MS 28
|
||||
#define WD_TO_500MS 29
|
||||
#define WD_TO_1SEC 30
|
||||
#define WD_TO_2SEC 31
|
||||
#define WD_TO_4SEC 32
|
||||
#define WD_TO_8SEC 33
|
||||
#define WD_TO_16SEC 34
|
||||
#define WD_TO_32SEC 35
|
||||
#define WD_TO_64SEC 36
|
||||
#define WD_TO_128SEC 37
|
||||
|
||||
/* action on pre-timeout trigger */
|
||||
#define WD_SOFT_PANIC 0x01 /* panic */
|
||||
#define WD_SOFT_DDB 0x02 /* enter debugger */
|
||||
#define WD_SOFT_LOG 0x04 /* log(9) */
|
||||
#define WD_SOFT_PRINTF 0x08 /* printf(9) */
|
||||
#define WD_SOFT_MASK 0x0f /* all of the above */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/eventhandler.h>
|
||||
|
||||
typedef void (*watchdog_fn)(void *, u_int, int *);
|
||||
|
||||
EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn);
|
||||
|
||||
u_int wdog_kern_last_timeout(void);
|
||||
int wdog_kern_pat(u_int utim);
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_WATCHDOG_H */
|
Loading…
x
Reference in New Issue
Block a user