Switch TI platform support code from using FreeBSD's custom-baked DTS

files to vendor-provided ones. It should make easier to adopt platform
code to new revisions of hardware and to use DTS overlays for various
Beaglebone extensions (shields/capes).

Original dts filenames were not changed, they're now wrappers over dts
files provided by TI. So make sure you update .dtb files on your
devices as part of kernel update

GPIO addressing was changed: instead of one global /dev/gpioc0 there
are per-bank instances of /dev/gpiocX. Each bank has 32 pins so for
instance pin 121 on /dev/gpioc0 in old addressing scheme is now pin 25
on /dev/gpioc3

On Pandaboard serial console devices was changed from /dev/ttyu0 to
/dev/ttyu2 so you'll have to update /etc/ttys to get login prompt
on serial port in multiuser mode. Single user mode serial console
should work as-is

Differential Revision:	https://reviews.freebsd.org/D2146
Reviewed by:	rpaulo, ian, Michal Meloun, Svatopluk Kraus
This commit is contained in:
Oleksandr Tymoshenko 2015-05-22 03:16:18 +00:00
parent 2569f51471
commit 5b03aba6c8
55 changed files with 3992 additions and 3859 deletions

View File

@ -31,6 +31,19 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20150521:
TI platform code switched to using vendor DTS files and this update
may break existing systems running on Beaglebone, Beaglebone Black,
and Pandaboard:
- dtb files should be regenerated/reinstalled. Filenames are the
same but content is different now
- GPIO addressing was changed, now each GPIO bank (32 pins per bank)
has its own /dev/gpiocX device, e.g. pin 121 on /dev/gpioc0 in old
addressing scheme is now pin 25 on /dev/gpioc3.
- Pandaboard: /etc/ttys should be updated, serial console device is
now /dev/ttyu2, not /dev/ttyu0
20150501:
soelim(1) from gnu/usr.bin/groff has been replaced by usr.bin/soelim.
If you need the GNU extension from groff soelim(1), install groff

View File

@ -133,5 +133,8 @@ device axe # ASIX Electronics USB Ethernet
device usb_template # Control of the gadget
device usfs
# Pinmux
device fdt_pinctrl
# Flattened Device Tree
options FDT # Configure using FDT/DTB data

View File

@ -57,6 +57,7 @@ options DDB # Enable the kernel debugger
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
device fdt_pinctrl
# Interrupt controller
device gic
@ -81,6 +82,7 @@ device pl310 # PL310 L2 cache controller
# GPIO
device gpio
device gpioled
# The following enables MFS as root, this seems similar to an initramfs or initrd
# as used in Linux.

View File

@ -69,7 +69,6 @@ static struct resource_spec ti_aintc_spec[] = {
{ -1, 0 }
};
static struct ti_aintc_softc *ti_aintc_sc = NULL;
#define aintc_read_4(_sc, reg) \
@ -77,6 +76,12 @@ static struct ti_aintc_softc *ti_aintc_sc = NULL;
#define aintc_write_4(_sc, reg, val) \
bus_space_write_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg), (val))
/* List of compatible strings for FDT tree */
static struct ofw_compat_data compat_data[] = {
{"ti,am33xx-intc", 1},
{"ti,omap2-intc", 1},
{NULL, 0},
};
static void
aintc_post_filter(void *arg)
@ -92,9 +97,9 @@ ti_aintc_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,aintc"))
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "TI AINTC Interrupt Controller");
return (BUS_PROBE_DEFAULT);
}

View File

@ -54,7 +54,8 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_pinmux.h>
#define AM335X_NUM_TIMERS 8
@ -109,78 +110,38 @@ __FBSDID("$FreeBSD$");
#define DEFAULT_ET_TIMER 2
#define DEFAULT_TC_TIMER 3
#define DMTIMER_READ4(sc, reg) (bus_read_4((sc)->tmr_mem_res, (reg)))
#define DMTIMER_WRITE4(sc, reg, val) (bus_write_4((sc)->tmr_mem_res, (reg), (val)))
struct am335x_dmtimer_softc {
struct resource * tmr_mem_res[AM335X_NUM_TIMERS];
struct resource * tmr_irq_res[AM335X_NUM_TIMERS];
device_t dev;
int tmr_mem_rid;
struct resource * tmr_mem_res;
int tmr_irq_rid;
struct resource * tmr_irq_res;
void *tmr_irq_handler;
uint32_t sysclk_freq;
uint32_t tc_num; /* Which timer number is tc. */
uint32_t tc_tclr; /* Cached tc TCLR register. */
struct resource * tc_memres; /* Resources for tc timer. */
uint32_t et_num; /* Which timer number is et. */
uint32_t et_tclr; /* Cached et TCLR register. */
struct resource * et_memres; /* Resources for et timer. */
uint32_t tclr; /* Cached TCLR register. */
int pps_curmode; /* Edge mode now set in hw. */
struct task pps_task; /* For pps_event handling. */
struct cdev * pps_cdev;
struct pps_state pps;
struct timecounter tc;
struct eventtimer et;
union {
struct timecounter tc;
struct eventtimer et;
} func;
};
static struct am335x_dmtimer_softc *am335x_dmtimer_sc;
static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
static struct resource_spec am335x_dmtimer_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE },
{ SYS_RES_MEMORY, 2, RF_ACTIVE },
{ SYS_RES_MEMORY, 3, RF_ACTIVE },
{ SYS_RES_MEMORY, 4, RF_ACTIVE },
{ SYS_RES_MEMORY, 5, RF_ACTIVE },
{ SYS_RES_MEMORY, 6, RF_ACTIVE },
{ SYS_RES_MEMORY, 7, RF_ACTIVE },
{ -1, 0, 0 }
};
static struct resource_spec am335x_dmtimer_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ SYS_RES_IRQ, 3, RF_ACTIVE },
{ SYS_RES_IRQ, 4, RF_ACTIVE },
{ SYS_RES_IRQ, 5, RF_ACTIVE },
{ SYS_RES_IRQ, 6, RF_ACTIVE },
{ SYS_RES_IRQ, 7, RF_ACTIVE },
{ -1, 0, 0 }
};
static inline uint32_t
am335x_dmtimer_tc_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
{
return (bus_read_4(sc->tc_memres, reg));
}
static inline void
am335x_dmtimer_tc_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
uint32_t val)
{
bus_write_4(sc->tc_memres, reg, val);
}
static inline uint32_t
am335x_dmtimer_et_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
{
return (bus_read_4(sc->et_memres, reg));
}
static inline void
am335x_dmtimer_et_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
uint32_t val)
{
bus_write_4(sc->et_memres, reg, val);
}
#ifdef PPS_SYNC
/* -1 - not detected, 0 - not found, > 0 - timerX module */
static int am335x_dmtimer_pps_module = -1;
static const char *am335x_dmtimer_pps_hwmod = NULL;
#endif
/*
* PPS driver routines, included when the kernel is built with option PPS_SYNC.
@ -215,19 +176,19 @@ am335x_dmtimer_set_capture_mode(struct am335x_dmtimer_softc *sc, bool force_off)
return;
sc->pps_curmode = newmode;
sc->tc_tclr &= ~DMT_TCLR_CAPTRAN_MASK;
sc->tclr &= ~DMT_TCLR_CAPTRAN_MASK;
switch (newmode) {
case PPS_CAPTUREASSERT:
sc->tc_tclr |= DMT_TCLR_CAPTRAN_LOHI;
sc->tclr |= DMT_TCLR_CAPTRAN_LOHI;
break;
case PPS_CAPTURECLEAR:
sc->tc_tclr |= DMT_TCLR_CAPTRAN_HILO;
sc->tclr |= DMT_TCLR_CAPTRAN_HILO;
break;
default:
/* It can't be BOTH, so it's disabled. */
break;
}
am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
}
static void
@ -244,10 +205,10 @@ am335x_dmtimer_tc_poll_pps(struct timecounter *tc)
* TCAR status to re-arm the capture for the next second, we have to
* write to the IRQ status register, not the RAW register. Quirky.
*/
if (am335x_dmtimer_tc_read_4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
if (DMTIMER_READ4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
pps_capture(&sc->pps);
sc->pps.capcount = am335x_dmtimer_tc_read_4(sc, DMT_TCAR1);
am335x_dmtimer_tc_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
sc->pps.capcount = DMTIMER_READ4(sc, DMT_TCAR1);
DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
taskqueue_enqueue_fast(taskqueue_fast, &sc->pps_task);
}
}
@ -339,21 +300,15 @@ static struct cdevsw am335x_dmtimer_pps_cdevsw = {
.d_name = PPS_CDEV_NAME,
};
/*
* Set up the PPS cdev and the the kernel timepps stuff.
*
* Note that this routine cannot touch the hardware, because bus space resources
* are not fully set up yet when this is called.
*/
static int
am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
static void
am335x_dmtimer_pps_find()
{
int i, timer_num, unit;
int i;
unsigned int padstate;
const char * padmux;
struct padinfo {
char * ballname;
char * muxname;
const char * muxname;
int timer_num;
} padinfo[] = {
{"GPMC_ADVn_ALE", "timer4", 4},
@ -370,21 +325,47 @@ am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
* is configured for input. The right symbolic values aren't exported
* yet from ti_scm.h.
*/
timer_num = 0;
for (i = 0; i < nitems(padinfo) && timer_num == 0; ++i) {
if (ti_scm_padconf_get(padinfo[i].ballname, &padmux,
am335x_dmtimer_pps_module = 0;
for (i = 0; i < nitems(padinfo) && am335x_dmtimer_pps_module == 0; ++i) {
if (ti_pinmux_padconf_get(padinfo[i].ballname, &padmux,
&padstate) == 0) {
if (strcasecmp(padinfo[i].muxname, padmux) == 0 &&
(padstate & (0x01 << 5)))
timer_num = padinfo[i].timer_num;
(padstate & (0x01 << 5))) {
am335x_dmtimer_pps_module = padinfo[i].timer_num;
am335x_dmtimer_pps_hwmod = padinfo[i].muxname;
}
}
}
if (timer_num == 0) {
device_printf(dev, "No DMTimer found with capture pin "
if (am335x_dmtimer_pps_module == 0) {
printf("am335x_dmtimer: No DMTimer found with capture pin "
"configured as input; PPS driver disabled.\n");
return (DEFAULT_TC_TIMER);
}
}
/*
* Set up the PPS cdev and the the kernel timepps stuff.
*
* Note that this routine cannot touch the hardware, because bus space resources
* are not fully set up yet when this is called.
*/
static void
am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
{
int unit;
if (am335x_dmtimer_pps_module == -1)
am335x_dmtimer_pps_find();
/* No PPS input */
if (am335x_dmtimer_pps_module == 0)
return;
/* Not PPS-enabled input */
if ((am335x_dmtimer_pps_module > 0) &&
(!ti_hwmods_contains(dev, am335x_dmtimer_pps_hwmod)))
return;
/*
* Indicate our capabilities (pretty much just capture of either edge).
@ -398,35 +379,21 @@ am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
* Set up to capture the PPS via timecounter polling, and init the task
* that does deferred pps_event() processing after capture.
*/
sc->tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
sc->func.tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc);
/* Create the PPS cdev. */
unit = device_get_unit(dev);
sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit,
UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME "%d", unit);
UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME);
sc->pps_cdev->si_drv1 = sc;
unit = device_get_unit(sc->pps_cdev);
device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n",
timer_num, PPS_CDEV_NAME, unit);
return (timer_num);
am335x_dmtimer_pps_module, PPS_CDEV_NAME, unit);
}
#else /* PPS_SYNC */
#endif
static int
am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
{
/*
* When PPS support is not compiled in, there's no need to use a timer
* that has an associated capture-input pin, so use the default.
*/
return (DEFAULT_TC_TIMER);
}
#endif /* PPS_SYNC */
/*
* End of PPS driver code.
*/
@ -438,7 +405,7 @@ am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
sc = tc->tc_priv;
return (am335x_dmtimer_tc_read_4(sc, DMT_TCRR));
return (DMTIMER_READ4(sc, DMT_TCRR));
}
static int
@ -462,13 +429,13 @@ am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
* from the et_event_cb() routine dispatched from our own handler, but
* it's not clear to me that that's the only case possible.
*/
sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
if (period != 0) {
reload_count = ((uint32_t)et->et_frequency * period) >> 32;
sc->et_tclr |= DMT_TCLR_AUTOLOAD;
sc->tclr |= DMT_TCLR_AUTOLOAD;
} else {
reload_count = 0;
}
@ -482,13 +449,13 @@ am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
* Set auto-reload and current-count values. This timer hardware counts
* up from the initial/reload value and interrupts on the zero rollover.
*/
am335x_dmtimer_et_write_4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
am335x_dmtimer_et_write_4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
DMTIMER_WRITE4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
DMTIMER_WRITE4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
/* Enable overflow interrupt, and start the timer. */
am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
sc->et_tclr |= DMT_TCLR_START;
am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
DMTIMER_WRITE4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
sc->tclr |= DMT_TCLR_START;
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
return (0);
}
@ -501,10 +468,10 @@ am335x_dmtimer_stop(struct eventtimer *et)
sc = et->et_priv;
/* Stop timer, disable and clear interrupt. */
sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
DMTIMER_WRITE4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
return (0);
}
@ -516,13 +483,96 @@ am335x_dmtimer_intr(void *arg)
sc = arg;
/* Ack the interrupt, and invoke the callback if it's still enabled. */
am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
if (sc->et.et_active)
sc->et.et_event_cb(&sc->et, sc->et.et_arg);
DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
if (sc->func.et.et_active)
sc->func.et.et_event_cb(&sc->func.et, sc->func.et.et_arg);
return (FILTER_HANDLED);
}
/*
* Checks if timer is suitable to be system timer
*/
static int
am335x_dmtimer_system_compatible(device_t dev)
{
phandle_t node;
node = ofw_bus_get_node(dev);
if (OF_hasprop(node, "ti,timer-alwon"))
return (0);
return (1);
}
static int
am335x_dmtimer_init_et(struct am335x_dmtimer_softc *sc)
{
if (am335x_dmtimer_et_sc != NULL)
return (EEXIST);
#ifdef PPS_SYNC
if ((am335x_dmtimer_pps_module > 0) &&
(!ti_hwmods_contains(sc->dev, am335x_dmtimer_pps_hwmod))) {
device_printf(sc->dev, "not PPS enabled\n");
return (ENXIO);
}
#endif
/* Setup eventtimer interrupt handler. */
if (bus_setup_intr(sc->dev, sc->tmr_irq_res, INTR_TYPE_CLK,
am335x_dmtimer_intr, NULL, sc, &sc->tmr_irq_handler) != 0) {
device_printf(sc->dev, "Unable to setup the clock irq handler.\n");
return (ENXIO);
}
sc->func.et.et_name = "AM335x Eventtimer";
sc->func.et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->func.et.et_quality = 1000;
sc->func.et.et_frequency = sc->sysclk_freq;
sc->func.et.et_min_period =
((0x00000005LLU << 32) / sc->func.et.et_frequency);
sc->func.et.et_max_period =
(0xfffffffeLLU << 32) / sc->func.et.et_frequency;
sc->func.et.et_start = am335x_dmtimer_start;
sc->func.et.et_stop = am335x_dmtimer_stop;
sc->func.et.et_priv = sc;
et_register(&sc->func.et);
am335x_dmtimer_et_sc = sc;
return (0);
}
static int
am335x_dmtimer_init_tc(struct am335x_dmtimer_softc *sc)
{
if (am335x_dmtimer_tc_sc != NULL)
return (EEXIST);
/* Set up timecounter, start it, register it. */
DMTIMER_WRITE4(sc, DMT_TSICR, DMT_TSICR_RESET);
while (DMTIMER_READ4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
continue;
sc->tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
DMTIMER_WRITE4(sc, DMT_TLDR, 0);
DMTIMER_WRITE4(sc, DMT_TCRR, 0);
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
sc->func.tc.tc_name = "AM335x Timecounter";
sc->func.tc.tc_get_timecount = am335x_dmtimer_tc_get_timecount;
sc->func.tc.tc_counter_mask = ~0u;
sc->func.tc.tc_frequency = sc->sysclk_freq;
sc->func.tc.tc_quality = 1000;
sc->func.tc.tc_priv = sc;
tc_init(&sc->func.tc);
am335x_dmtimer_tc_sc = sc;
return (0);
}
static int
am335x_dmtimer_probe(device_t dev)
{
@ -530,7 +580,8 @@ am335x_dmtimer_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "ti,am335x-dmtimer")) {
if (ofw_bus_is_compatible(dev, "ti,am335x-timer-1ms") ||
ofw_bus_is_compatible(dev, "ti,am335x-timer")) {
device_set_desc(dev, "AM335x DMTimer");
return(BUS_PROBE_DEFAULT);
}
@ -542,8 +593,9 @@ static int
am335x_dmtimer_attach(device_t dev)
{
struct am335x_dmtimer_softc *sc;
void *ihl;
int err;
clk_ident_t timer_id;
int enable;
/*
* Note that if this routine returns an error status rather than running
@ -552,9 +604,7 @@ am335x_dmtimer_attach(device_t dev)
*/
sc = device_get_softc(dev);
if (am335x_dmtimer_sc != NULL)
return (EINVAL);
sc->dev = dev;
/* Get the base clock frequency. */
err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq);
@ -564,82 +614,61 @@ am335x_dmtimer_attach(device_t dev)
}
/* Request the memory resources. */
err = bus_alloc_resources(dev, am335x_dmtimer_mem_spec,
sc->tmr_mem_res);
if (err) {
sc->tmr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->tmr_mem_rid, RF_ACTIVE);
if (sc->tmr_mem_res == NULL) {
device_printf(dev, "Error: could not allocate mem resources\n");
return (ENXIO);
}
/* Request the IRQ resources. */
err = bus_alloc_resources(dev, am335x_dmtimer_irq_spec,
sc->tmr_irq_res);
sc->tmr_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->tmr_irq_rid, RF_ACTIVE);
if (err) {
bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
sc->tmr_mem_res);
device_printf(dev, "Error: could not allocate irq resources\n");
return (ENXIO);
}
/*
* Use the default eventtimer. Let the PPS init routine decide which
* timer to use for the timecounter.
*/
sc->et_num = DEFAULT_ET_TIMER;
sc->tc_num = am335x_dmtimer_pps_init(dev, sc);
#ifdef PPS_SYNC
am335x_dmtimer_pps_init(dev, sc);
#endif
sc->et_memres = sc->tmr_mem_res[sc->et_num];
sc->tc_memres = sc->tmr_mem_res[sc->tc_num];
/* Enable clocks and power on the chosen devices. */
err = ti_prcm_clk_set_source(DMTIMER0_CLK + sc->et_num, SYSCLK_CLK);
err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->et_num);
err |= ti_prcm_clk_set_source(DMTIMER0_CLK + sc->tc_num, SYSCLK_CLK);
err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->tc_num);
if (err) {
device_printf(dev, "Error: could not enable timer clock\n");
return (ENXIO);
enable = 0;
/* Try to use as a timecounter or event timer */
if (am335x_dmtimer_system_compatible(dev)) {
if (am335x_dmtimer_init_tc(sc) == 0)
enable = 1;
else if (am335x_dmtimer_init_et(sc) == 0)
enable = 1;
}
/* Setup eventtimer interrupt handler. */
if (bus_setup_intr(dev, sc->tmr_irq_res[sc->et_num], INTR_TYPE_CLK,
am335x_dmtimer_intr, NULL, sc, &ihl) != 0) {
device_printf(dev, "Unable to setup the clock irq handler.\n");
return (ENXIO);
if (enable) {
/* Enable clocks and power on the chosen devices. */
timer_id = ti_hwmods_get_clock(dev);
if (timer_id == INVALID_CLK_IDENT) {
bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
sc->tmr_mem_res);
bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
sc->tmr_irq_res);
device_printf(dev, "failed to get device id using ti,hwmods\n");
return (ENXIO);
}
err = ti_prcm_clk_set_source(timer_id, SYSCLK_CLK);
err |= ti_prcm_clk_enable(timer_id);
if (err) {
bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
sc->tmr_mem_res);
bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
sc->tmr_irq_res);
device_printf(dev, "Error: could not enable timer clock\n");
return (ENXIO);
}
}
/* Set up timecounter, start it, register it. */
am335x_dmtimer_tc_write_4(sc, DMT_TSICR, DMT_TSICR_RESET);
while (am335x_dmtimer_tc_read_4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
continue;
sc->tc_tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
am335x_dmtimer_tc_write_4(sc, DMT_TLDR, 0);
am335x_dmtimer_tc_write_4(sc, DMT_TCRR, 0);
am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
sc->tc.tc_name = "AM335x Timecounter";
sc->tc.tc_get_timecount = am335x_dmtimer_tc_get_timecount;
sc->tc.tc_counter_mask = ~0u;
sc->tc.tc_frequency = sc->sysclk_freq;
sc->tc.tc_quality = 1000;
sc->tc.tc_priv = sc;
tc_init(&sc->tc);
sc->et.et_name = "AM335x Eventtimer";
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->sysclk_freq;
sc->et.et_min_period =
((0x00000005LLU << 32) / sc->et.et_frequency);
sc->et.et_max_period =
(0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = am335x_dmtimer_start;
sc->et.et_stop = am335x_dmtimer_stop;
sc->et.et_priv = sc;
et_register(&sc->et);
/* Store a pointer to the softc for use in DELAY(). */
am335x_dmtimer_sc = sc;
return (0);
}
@ -667,7 +696,7 @@ DELAY(int usec)
int32_t counts;
uint32_t first, last;
sc = am335x_dmtimer_sc;
sc = am335x_dmtimer_tc_sc;
if (sc == NULL) {
for (; usec > 0; usec--)
@ -680,10 +709,10 @@ DELAY(int usec)
/* Get the number of times to count */
counts = (usec + 1) * (sc->sysclk_freq / 1000000);
first = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
first = DMTIMER_READ4(sc, DMT_TCRR);
while (counts > 0) {
last = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
last = DMTIMER_READ4(sc, DMT_TCRR);
if (last > first) {
counts -= (int32_t)(last - first);
} else {

View File

@ -0,0 +1,201 @@
/*-
* Copyright (c) 2013 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "am335x_pwm.h"
#define ECAP_TSCTR 0x00
#define ECAP_CAP1 0x08
#define ECAP_CAP2 0x0C
#define ECAP_CAP3 0x10
#define ECAP_CAP4 0x14
#define ECAP_ECCTL2 0x2A
#define ECCTL2_MODE_APWM (1 << 9)
#define ECCTL2_SYNCO_SEL (3 << 6)
#define ECCTL2_TSCTRSTOP_FREERUN (1 << 4)
#define ECAP_READ2(_sc, reg) bus_read_2((_sc)->sc_mem_res, reg);
#define ECAP_WRITE2(_sc, reg, value) \
bus_write_2((_sc)->sc_mem_res, reg, value);
#define ECAP_READ4(_sc, reg) bus_read_4((_sc)->sc_mem_res, reg);
#define ECAP_WRITE4(_sc, reg, value) \
bus_write_4((_sc)->sc_mem_res, reg, value);
#define PWM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define PWM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define PWM_LOCK_INIT(_sc) mtx_init(&(_sc)->sc_mtx, \
device_get_nameunit(_sc->sc_dev), "am335x_ecap softc", MTX_DEF)
#define PWM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
static device_probe_t am335x_ecap_probe;
static device_attach_t am335x_ecap_attach;
static device_detach_t am335x_ecap_detach;
struct am335x_ecap_softc {
device_t sc_dev;
struct mtx sc_mtx;
struct resource *sc_mem_res;
int sc_mem_rid;
};
static device_method_t am335x_ecap_methods[] = {
DEVMETHOD(device_probe, am335x_ecap_probe),
DEVMETHOD(device_attach, am335x_ecap_attach),
DEVMETHOD(device_detach, am335x_ecap_detach),
DEVMETHOD_END
};
static driver_t am335x_ecap_driver = {
"am335x_ecap",
am335x_ecap_methods,
sizeof(struct am335x_ecap_softc),
};
static devclass_t am335x_ecap_devclass;
/*
* API function to set period/duty cycles for ECAPx
*/
int
am335x_pwm_config_ecap(int unit, int period, int duty)
{
device_t dev;
struct am335x_ecap_softc *sc;
uint16_t reg;
dev = devclass_get_device(am335x_ecap_devclass, unit);
if (dev == NULL)
return (ENXIO);
if (duty > period)
return (EINVAL);
if (period == 0)
return (EINVAL);
sc = device_get_softc(dev);
PWM_LOCK(sc);
reg = ECAP_READ2(sc, ECAP_ECCTL2);
reg |= ECCTL2_MODE_APWM | ECCTL2_TSCTRSTOP_FREERUN | ECCTL2_SYNCO_SEL;
ECAP_WRITE2(sc, ECAP_ECCTL2, reg);
/* CAP3 in APWM mode is APRD shadow register */
ECAP_WRITE4(sc, ECAP_CAP3, period - 1);
/* CAP4 in APWM mode is ACMP shadow register */
ECAP_WRITE4(sc, ECAP_CAP4, duty);
/* Restart counter */
ECAP_WRITE4(sc, ECAP_TSCTR, 0);
PWM_UNLOCK(sc);
return (0);
}
static int
am335x_ecap_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,am33xx-ecap"))
return (ENXIO);
device_set_desc(dev, "AM335x eCAP");
return (BUS_PROBE_DEFAULT);
}
static int
am335x_ecap_attach(device_t dev)
{
struct am335x_ecap_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
PWM_LOCK_INIT(sc);
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, "cannot allocate memory resources\n");
goto fail;
}
return (0);
fail:
PWM_LOCK_DESTROY(sc);
return (ENXIO);
}
static int
am335x_ecap_detach(device_t dev)
{
struct am335x_ecap_softc *sc;
sc = device_get_softc(dev);
PWM_LOCK(sc);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
PWM_UNLOCK(sc);
PWM_LOCK_DESTROY(sc);
return (0);
}
DRIVER_MODULE(am335x_ecap, am335x_pwmss, am335x_ecap_driver, am335x_ecap_devclass, 0, 0);
MODULE_VERSION(am335x_ecap, 1);
MODULE_DEPEND(am335x_ecap, am335x_pwmss, 1, 1, 1);

View File

@ -46,11 +46,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_scm.h>
#include "am335x_pwm.h"
#include "am335x_scm.h"
/* In ticks */
#define DEFAULT_PWM_PERIOD 1000
@ -59,47 +55,12 @@ __FBSDID("$FreeBSD$");
#define PWM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define PWM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define PWM_LOCK_INIT(_sc) mtx_init(&(_sc)->sc_mtx, \
device_get_nameunit(_sc->sc_dev), "am335x_pwm softc", MTX_DEF)
device_get_nameunit(_sc->sc_dev), "am335x_ehrpwm softc", MTX_DEF)
#define PWM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
static struct resource_spec am335x_pwm_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* PWMSS */
{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* eCAP */
{ SYS_RES_MEMORY, 2, RF_ACTIVE }, /* eQEP */
{ SYS_RES_MEMORY, 3, RF_ACTIVE }, /*ePWM */
{ -1, 0, 0 }
};
#define PWMSS_READ4(_sc, reg) bus_read_4((_sc)->sc_mem_res[0], reg);
#define PWMSS_WRITE4(_sc, reg, value) \
bus_write_4((_sc)->sc_mem_res[0], reg, value);
#define ECAP_READ2(_sc, reg) bus_read_2((_sc)->sc_mem_res[1], reg);
#define ECAP_WRITE2(_sc, reg, value) \
bus_write_2((_sc)->sc_mem_res[1], reg, value);
#define ECAP_READ4(_sc, reg) bus_read_4((_sc)->sc_mem_res[1], reg);
#define ECAP_WRITE4(_sc, reg, value) \
bus_write_4((_sc)->sc_mem_res[1], reg, value);
#define EPWM_READ2(_sc, reg) bus_read_2((_sc)->sc_mem_res[3], reg);
#define EPWM_READ2(_sc, reg) bus_read_2((_sc)->sc_mem_res, reg);
#define EPWM_WRITE2(_sc, reg, value) \
bus_write_2((_sc)->sc_mem_res[3], reg, value);
#define PWMSS_IDVER 0x00
#define PWMSS_SYSCONFIG 0x04
#define PWMSS_CLKCONFIG 0x08
#define CLKCONFIG_EPWMCLK_EN (1 << 8)
#define PWMSS_CLKSTATUS 0x0C
#define ECAP_TSCTR 0x00
#define ECAP_CAP1 0x08
#define ECAP_CAP2 0x0C
#define ECAP_CAP3 0x10
#define ECAP_CAP4 0x14
#define ECAP_ECCTL2 0x2A
#define ECCTL2_MODE_APWM (1 << 9)
#define ECCTL2_SYNCO_SEL (3 << 6)
#define ECCTL2_TSCTRSTOP_FREERUN (1 << 4)
bus_write_2((_sc)->sc_mem_res, reg, value);
#define EPWM_TBCTL 0x00
#define TBCTL_FREERUN (2 << 14)
@ -169,17 +130,17 @@ static struct resource_spec am335x_pwm_mem_spec[] = {
#define HRCTL_DELMODE_FALL 2
#define HRCTL_DELMODE_RISE 1
static device_probe_t am335x_pwm_probe;
static device_attach_t am335x_pwm_attach;
static device_detach_t am335x_pwm_detach;
static int am335x_pwm_clkdiv[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
static device_probe_t am335x_ehrpwm_probe;
static device_attach_t am335x_ehrpwm_attach;
static device_detach_t am335x_ehrpwm_detach;
struct am335x_pwm_softc {
static int am335x_ehrpwm_clkdiv[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
struct am335x_ehrpwm_softc {
device_t sc_dev;
struct mtx sc_mtx;
struct resource *sc_mem_res[4];
int sc_id;
struct resource *sc_mem_res;
int sc_mem_rid;
/* sysctl for configuration */
int sc_pwm_clkdiv;
int sc_pwm_freq;
@ -193,79 +154,39 @@ struct am335x_pwm_softc {
uint32_t sc_pwm_dutyB;
};
static device_method_t am335x_pwm_methods[] = {
DEVMETHOD(device_probe, am335x_pwm_probe),
DEVMETHOD(device_attach, am335x_pwm_attach),
DEVMETHOD(device_detach, am335x_pwm_detach),
static device_method_t am335x_ehrpwm_methods[] = {
DEVMETHOD(device_probe, am335x_ehrpwm_probe),
DEVMETHOD(device_attach, am335x_ehrpwm_attach),
DEVMETHOD(device_detach, am335x_ehrpwm_detach),
DEVMETHOD_END
};
static driver_t am335x_pwm_driver = {
"am335x_pwm",
am335x_pwm_methods,
sizeof(struct am335x_pwm_softc),
static driver_t am335x_ehrpwm_driver = {
"am335x_ehrpwm",
am335x_ehrpwm_methods,
sizeof(struct am335x_ehrpwm_softc),
};
static devclass_t am335x_pwm_devclass;
/*
* API function to set period/duty cycles for ECASx
*/
int
am335x_pwm_config_ecas(int unit, int period, int duty)
{
device_t dev;
struct am335x_pwm_softc *sc;
uint16_t reg;
dev = devclass_get_device(am335x_pwm_devclass, unit);
if (dev == NULL)
return (ENXIO);
if (duty > period)
return (EINVAL);
if (period == 0)
return (EINVAL);
sc = device_get_softc(dev);
PWM_LOCK(sc);
reg = ECAP_READ2(sc, ECAP_ECCTL2);
reg |= ECCTL2_MODE_APWM | ECCTL2_TSCTRSTOP_FREERUN | ECCTL2_SYNCO_SEL;
ECAP_WRITE2(sc, ECAP_ECCTL2, reg);
/* CAP3 in APWM mode is APRD shadow register */
ECAP_WRITE4(sc, ECAP_CAP3, period - 1);
/* CAP4 in APWM mode is ACMP shadow register */
ECAP_WRITE4(sc, ECAP_CAP4, duty);
/* Restart counter */
ECAP_WRITE4(sc, ECAP_TSCTR, 0);
PWM_UNLOCK(sc);
return (0);
}
static devclass_t am335x_ehrpwm_devclass;
static void
am335x_pwm_freq(struct am335x_pwm_softc *sc)
am335x_ehrpwm_freq(struct am335x_ehrpwm_softc *sc)
{
int clkdiv;
clkdiv = am335x_pwm_clkdiv[sc->sc_pwm_clkdiv];
clkdiv = am335x_ehrpwm_clkdiv[sc->sc_pwm_clkdiv];
sc->sc_pwm_freq = PWM_CLOCK / (1 * clkdiv) / sc->sc_pwm_period;
}
static int
am335x_pwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
am335x_ehrpwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
{
int clkdiv, error, freq, i, period;
struct am335x_pwm_softc *sc;
struct am335x_ehrpwm_softc *sc;
uint32_t reg;
sc = (struct am335x_pwm_softc *)arg1;
sc = (struct am335x_ehrpwm_softc *)arg1;
PWM_LOCK(sc);
freq = sc->sc_pwm_freq;
@ -280,8 +201,8 @@ am335x_pwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
PWM_LOCK(sc);
if (freq != sc->sc_pwm_freq) {
for (i = nitems(am335x_pwm_clkdiv) - 1; i >= 0; i--) {
clkdiv = am335x_pwm_clkdiv[i];
for (i = nitems(am335x_ehrpwm_clkdiv) - 1; i >= 0; i--) {
clkdiv = am335x_ehrpwm_clkdiv[i];
period = PWM_CLOCK / clkdiv / freq;
if (period > USHRT_MAX)
break;
@ -300,7 +221,7 @@ am335x_pwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
EPWM_WRITE2(sc, EPWM_TBCTL, reg);
/* Update the period settings. */
EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
am335x_pwm_freq(sc);
am335x_ehrpwm_freq(sc);
}
PWM_UNLOCK(sc);
@ -308,16 +229,16 @@ am335x_pwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
}
static int
am335x_pwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
am335x_ehrpwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
{
int error, i, clkdiv;
struct am335x_pwm_softc *sc;
struct am335x_ehrpwm_softc *sc;
uint32_t reg;
sc = (struct am335x_pwm_softc *)arg1;
sc = (struct am335x_ehrpwm_softc *)arg1;
PWM_LOCK(sc);
clkdiv = am335x_pwm_clkdiv[sc->sc_pwm_clkdiv];
clkdiv = am335x_ehrpwm_clkdiv[sc->sc_pwm_clkdiv];
PWM_UNLOCK(sc);
error = sysctl_handle_int(oidp, &clkdiv, sizeof(clkdiv), req);
@ -325,16 +246,16 @@ am335x_pwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
return (error);
PWM_LOCK(sc);
if (clkdiv != am335x_pwm_clkdiv[sc->sc_pwm_clkdiv]) {
for (i = 0; i < nitems(am335x_pwm_clkdiv); i++)
if (clkdiv >= am335x_pwm_clkdiv[i])
if (clkdiv != am335x_ehrpwm_clkdiv[sc->sc_pwm_clkdiv]) {
for (i = 0; i < nitems(am335x_ehrpwm_clkdiv); i++)
if (clkdiv >= am335x_ehrpwm_clkdiv[i])
sc->sc_pwm_clkdiv = i;
reg = EPWM_READ2(sc, EPWM_TBCTL);
reg &= ~TBCTL_CLKDIV_MASK;
reg |= TBCTL_CLKDIV(sc->sc_pwm_clkdiv);
EPWM_WRITE2(sc, EPWM_TBCTL, reg);
am335x_pwm_freq(sc);
am335x_ehrpwm_freq(sc);
}
PWM_UNLOCK(sc);
@ -342,12 +263,12 @@ am335x_pwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
}
static int
am335x_pwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
am335x_ehrpwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
{
struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
struct am335x_ehrpwm_softc *sc = (struct am335x_ehrpwm_softc*)arg1;
int error;
uint32_t duty;
if (oidp == sc->sc_chanA_oid)
duty = sc->sc_pwm_dutyA;
else
@ -377,12 +298,12 @@ am335x_pwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
}
static int
am335x_pwm_sysctl_period(SYSCTL_HANDLER_ARGS)
am335x_ehrpwm_sysctl_period(SYSCTL_HANDLER_ARGS)
{
struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
struct am335x_ehrpwm_softc *sc = (struct am335x_ehrpwm_softc*)arg1;
int error;
uint32_t period;
period = sc->sc_pwm_period;
error = sysctl_handle_int(oidp, &period, 0, req);
@ -404,85 +325,70 @@ am335x_pwm_sysctl_period(SYSCTL_HANDLER_ARGS)
/* Update the period settings. */
sc->sc_pwm_period = period;
EPWM_WRITE2(sc, EPWM_TBPRD, period - 1);
am335x_pwm_freq(sc);
am335x_ehrpwm_freq(sc);
PWM_UNLOCK(sc);
return (error);
}
static int
am335x_pwm_probe(device_t dev)
am335x_ehrpwm_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,am335x-pwm"))
if (!ofw_bus_is_compatible(dev, "ti,am33xx-ehrpwm"))
return (ENXIO);
device_set_desc(dev, "AM335x PWM");
device_set_desc(dev, "AM335x EHRPWM");
return (BUS_PROBE_DEFAULT);
}
static int
am335x_pwm_attach(device_t dev)
am335x_ehrpwm_attach(device_t dev)
{
struct am335x_pwm_softc *sc;
int err;
struct am335x_ehrpwm_softc *sc;
uint32_t reg;
phandle_t node;
pcell_t did;
struct sysctl_ctx_list *ctx;
struct sysctl_oid *tree;
sc = device_get_softc(dev);
sc->sc_dev = dev;
/* Get the PWM module id */
node = ofw_bus_get_node(dev);
if ((OF_getprop(node, "pwm-device-id", &did, sizeof(did))) <= 0) {
device_printf(dev, "missing pwm-device-id attribute in FDT\n");
return (ENXIO);
}
sc->sc_id = fdt32_to_cpu(did);
PWM_LOCK_INIT(sc);
err = bus_alloc_resources(dev, am335x_pwm_mem_spec,
sc->sc_mem_res);
if (err) {
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, "cannot allocate memory resources\n");
goto fail;
}
ti_prcm_clk_enable(PWMSS0_CLK + sc->sc_id);
ti_scm_reg_read_4(SCM_PWMSS_CTRL, &reg);
reg |= (1 << sc->sc_id);
ti_scm_reg_write_4(SCM_PWMSS_CTRL, reg);
/* Init backlight interface */
ctx = device_get_sysctl_ctx(sc->sc_dev);
tree = device_get_sysctl_tree(sc->sc_dev);
sc->sc_clkdiv_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"clkdiv", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
am335x_pwm_sysctl_clkdiv, "I", "PWM clock prescaler");
am335x_ehrpwm_sysctl_clkdiv, "I", "PWM clock prescaler");
sc->sc_freq_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
am335x_pwm_sysctl_freq, "I", "PWM frequency");
am335x_ehrpwm_sysctl_freq, "I", "PWM frequency");
sc->sc_period_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"period", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
am335x_pwm_sysctl_period, "I", "PWM period");
am335x_ehrpwm_sysctl_period, "I", "PWM period");
sc->sc_chanA_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"dutyA", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
am335x_pwm_sysctl_duty, "I", "Channel A duty cycles");
am335x_ehrpwm_sysctl_duty, "I", "Channel A duty cycles");
sc->sc_chanB_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"dutyB", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
am335x_pwm_sysctl_duty, "I", "Channel B duty cycles");
am335x_ehrpwm_sysctl_duty, "I", "Channel B duty cycles");
/* CONFIGURE EPWM1 */
reg = EPWM_READ2(sc, EPWM_TBCTL);
@ -492,7 +398,7 @@ am335x_pwm_attach(device_t dev)
sc->sc_pwm_period = DEFAULT_PWM_PERIOD;
sc->sc_pwm_dutyA = 0;
sc->sc_pwm_dutyB = 0;
am335x_pwm_freq(sc);
am335x_ehrpwm_freq(sc);
EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
@ -512,24 +418,24 @@ am335x_pwm_attach(device_t dev)
return (0);
fail:
PWM_LOCK_DESTROY(sc);
if (sc->sc_mem_res[0])
bus_release_resources(dev, am335x_pwm_mem_spec,
sc->sc_mem_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
return(ENXIO);
}
static int
am335x_pwm_detach(device_t dev)
am335x_ehrpwm_detach(device_t dev)
{
struct am335x_pwm_softc *sc;
struct am335x_ehrpwm_softc *sc;
sc = device_get_softc(dev);
PWM_LOCK(sc);
if (sc->sc_mem_res[0])
bus_release_resources(dev, am335x_pwm_mem_spec,
sc->sc_mem_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
PWM_UNLOCK(sc);
PWM_LOCK_DESTROY(sc);
@ -537,6 +443,6 @@ am335x_pwm_detach(device_t dev)
return (0);
}
DRIVER_MODULE(am335x_pwm, simplebus, am335x_pwm_driver, am335x_pwm_devclass, 0, 0);
MODULE_VERSION(am335x_pwm, 1);
MODULE_DEPEND(am335x_pwm, simplebus, 1, 1, 1);
DRIVER_MODULE(am335x_ehrpwm, am335x_pwmss, am335x_ehrpwm_driver, am335x_ehrpwm_devclass, 0, 0);
MODULE_VERSION(am335x_ehrpwm, 1);
MODULE_DEPEND(am335x_ehrpwm, am335x_pwmss, 1, 1, 1);

View File

@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_pinmux.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
@ -86,6 +86,8 @@ static int
am335x_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
struct ti_gpio_softc *sc = device_get_softc(dev);
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
@ -99,15 +101,16 @@ am335x_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
return ti_pinmux_padconf_set_gpiomode(sc->sc_bank*32 + gpio, state);
}
static int
am335x_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
struct ti_gpio_softc *sc = device_get_softc(dev);
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
if (ti_pinmux_padconf_get_gpiomode(sc->sc_bank*32 + gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {

View File

@ -242,7 +242,7 @@ am335x_lcd_sysctl_backlight(SYSCTL_HANDLER_ARGS)
backlight = 100;
LCD_LOCK(sc);
error = am335x_pwm_config_ecas(PWM_UNIT, PWM_PERIOD,
error = am335x_pwm_config_ecap(PWM_UNIT, PWM_PERIOD,
backlight*PWM_PERIOD/100);
if (error == 0)
sc->sc_backlight = backlight;
@ -252,12 +252,10 @@ am335x_lcd_sysctl_backlight(SYSCTL_HANDLER_ARGS)
}
static int
am335x_read_panel_property(device_t dev, const char *name, uint32_t *val)
am335x_read_property(device_t dev, phandle_t node, const char *name, uint32_t *val)
{
phandle_t node;
pcell_t cell;
node = ofw_bus_get_node(dev);
if ((OF_getprop(node, name, &cell, sizeof(cell))) <= 0) {
device_printf(dev, "missing '%s' attribute in LCD panel info\n",
name);
@ -270,85 +268,116 @@ am335x_read_panel_property(device_t dev, const char *name, uint32_t *val)
}
static int
am335x_read_panel_info(device_t dev, struct panel_info *panel)
am335x_read_timing(device_t dev, phandle_t node, struct panel_info *panel)
{
int error;
phandle_t timings_node, timing_node, native;
timings_node = fdt_find_child(node, "display-timings");
if (timings_node == 0) {
device_printf(dev, "no \"display-timings\" node\n");
return (-1);
}
if (OF_searchencprop(timings_node, "native-mode", &native,
sizeof(native)) == -1) {
device_printf(dev, "no \"native-mode\" reference in \"timings\" node\n");
return (-1);
}
timing_node = OF_node_from_xref(native);
error = 0;
if ((error = am335x_read_panel_property(dev,
"panel_width", &panel->panel_width)))
if ((error = am335x_read_property(dev, timing_node,
"hactive", &panel->panel_width)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_height", &panel->panel_height)))
if ((error = am335x_read_property(dev, timing_node,
"vactive", &panel->panel_height)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_hfp", &panel->panel_hfp)))
if ((error = am335x_read_property(dev, timing_node,
"hfront-porch", &panel->panel_hfp)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_hbp", &panel->panel_hbp)))
if ((error = am335x_read_property(dev, timing_node,
"hback-porch", &panel->panel_hbp)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_hsw", &panel->panel_hsw)))
if ((error = am335x_read_property(dev, timing_node,
"hsync-len", &panel->panel_hsw)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_vfp", &panel->panel_vfp)))
if ((error = am335x_read_property(dev, timing_node,
"vfront-porch", &panel->panel_vfp)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_vbp", &panel->panel_vbp)))
if ((error = am335x_read_property(dev, timing_node,
"vback-porch", &panel->panel_vbp)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_vsw", &panel->panel_vsw)))
if ((error = am335x_read_property(dev, timing_node,
"vsync-len", &panel->panel_vsw)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_pxl_clk", &panel->panel_pxl_clk)))
if ((error = am335x_read_property(dev, timing_node,
"clock-frequency", &panel->panel_pxl_clk)))
goto out;
if ((error = am335x_read_panel_property(dev,
"panel_invert_pxl_clk", &panel->panel_invert_pxl_clk)))
if ((error = am335x_read_property(dev, timing_node,
"pixelclk-active", &panel->pixelclk_active)))
goto out;
if ((error = am335x_read_panel_property(dev,
"ac_bias", &panel->ac_bias)))
if ((error = am335x_read_property(dev, timing_node,
"hsync-active", &panel->hsync_active)))
goto out;
if ((error = am335x_read_panel_property(dev,
"ac_bias_intrpt", &panel->ac_bias_intrpt)))
if ((error = am335x_read_property(dev, timing_node,
"vsync-active", &panel->vsync_active)))
goto out;
if ((error = am335x_read_panel_property(dev,
"dma_burst_sz", &panel->dma_burst_sz)))
out:
return (error);
}
static int
am335x_read_panel_info(device_t dev, phandle_t node, struct panel_info *panel)
{
int error;
phandle_t panel_info_node;
panel_info_node = fdt_find_child(node, "panel-info");
if (panel_info_node == 0)
return (-1);
error = 0;
if ((error = am335x_read_property(dev, panel_info_node,
"ac-bias", &panel->ac_bias)))
goto out;
if ((error = am335x_read_panel_property(dev,
if ((error = am335x_read_property(dev, panel_info_node,
"ac-bias-intrpt", &panel->ac_bias_intrpt)))
goto out;
if ((error = am335x_read_property(dev, panel_info_node,
"dma-burst-sz", &panel->dma_burst_sz)))
goto out;
if ((error = am335x_read_property(dev, panel_info_node,
"bpp", &panel->bpp)))
goto out;
if ((error = am335x_read_panel_property(dev,
if ((error = am335x_read_property(dev, panel_info_node,
"fdd", &panel->fdd)))
goto out;
if ((error = am335x_read_panel_property(dev,
"invert_line_clock", &panel->invert_line_clock)))
if ((error = am335x_read_property(dev, panel_info_node,
"sync-edge", &panel->sync_edge)))
goto out;
if ((error = am335x_read_panel_property(dev,
"invert_frm_clock", &panel->invert_frm_clock)))
goto out;
if ((error = am335x_read_panel_property(dev,
"sync_edge", &panel->sync_edge)))
goto out;
error = am335x_read_panel_property(dev,
"sync_ctrl", &panel->sync_ctrl);
error = am335x_read_property(dev, panel_info_node,
"sync-ctrl", &panel->sync_ctrl);
out:
return (error);
@ -423,7 +452,7 @@ am335x_lcd_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,am335x-lcd"))
if (!ofw_bus_is_compatible(dev, "ti,am33xx-tilcdc"))
return (ENXIO);
device_set_desc(dev, "AM335x LCD controller");
@ -454,12 +483,32 @@ am335x_lcd_attach(device_t dev)
uint32_t hbp, hfp, hsw;
uint32_t vbp, vfp, vsw;
uint32_t width, height;
phandle_t root, panel_node;
sc = device_get_softc(dev);
sc->sc_dev = dev;
if (am335x_read_panel_info(dev, &panel))
root = OF_finddevice("/");
if (root == 0) {
device_printf(dev, "failed to get FDT root node\n");
return (ENXIO);
}
panel_node = fdt_find_compatible(root, "ti,tilcdc,panel", 1);
if (panel_node == 0) {
device_printf(dev, "failed to find compatible panel in FDT blob\n");
return (ENXIO);
}
if (am335x_read_panel_info(dev, panel_node, &panel)) {
device_printf(dev, "failed to read panel info\n");
return (ENXIO);
}
if (am335x_read_timing(dev, panel_node, &panel)) {
device_printf(dev, "failed to read timings\n");
return (ENXIO);
}
int ref_freq = 0;
ti_prcm_clk_enable(LCDC_CLK);
@ -593,11 +642,11 @@ am335x_lcd_attach(device_t dev)
timing2 |= RASTER_TIMING_2_PHSVS_RISE;
else
timing2 |= RASTER_TIMING_2_PHSVS_FALL;
if (panel.invert_line_clock)
if (panel.hsync_active == 0)
timing2 |= RASTER_TIMING_2_IHS;
if (panel.invert_frm_clock)
if (panel.vsync_active == 0)
timing2 |= RASTER_TIMING_2_IVS;
if (panel.panel_invert_pxl_clk)
if (panel.pixelclk_active == 0)
timing2 |= RASTER_TIMING_2_IPC;
/* AC bias */
@ -676,7 +725,7 @@ am335x_lcd_attach(device_t dev)
am335x_lcd_sysctl_backlight, "I", "LCD backlight");
sc->sc_backlight = 0;
/* Check if eCAS interface is available at this point */
if (am335x_pwm_config_ecas(PWM_UNIT,
if (am335x_pwm_config_ecap(PWM_UNIT,
PWM_PERIOD, PWM_PERIOD) == 0)
sc->sc_backlight = 100;

View File

@ -42,12 +42,12 @@ struct panel_info {
uint32_t dma_burst_sz;
uint32_t bpp;
uint32_t fdd;
uint32_t invert_line_clock;
uint32_t invert_frm_clock;
uint32_t hsync_active;
uint32_t vsync_active;
uint32_t sync_edge;
uint32_t sync_ctrl;
uint32_t panel_pxl_clk;
uint32_t panel_invert_pxl_clk;
uint32_t pixelclk_active;
};
int am335x_lcd_syscons_setup(vm_offset_t vaddr, vm_paddr_t paddr,

View File

@ -0,0 +1,417 @@
/*-
* 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 <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <dev/fdt/fdt_common.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);
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 (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);
device_t bdev;
int err;
if (sc->sc_otg.sc_bus.bdev) {
bdev = sc->sc_otg.sc_bus.bdev;
device_detach(bdev);
device_delete_child(dev, bdev);
}
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);
/* during module unload there are lots of children leftover */
device_delete_children(dev);
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);

View File

@ -153,12 +153,13 @@ am335x_pmic_probe(device_t dev)
{
struct am335x_pmic_softc *sc;
if (!ofw_bus_is_compatible(dev, "ti,am335x-pmic"))
if (!ofw_bus_is_compatible(dev, "ti,tps65217"))
return (ENXIO);
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
/* Convert to 8-bit addressing */
sc->sc_addr = iicbus_get_addr(dev) << 1;
device_set_desc(dev, "TI TPS65217 Power Management IC");

View File

@ -237,32 +237,32 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
.clk_get_source_freq = am335x_clk_get_arm_disp_freq,
},
/* UART. Uart0 clock cannot be controlled. */
AM335X_NOOP_CLOCK_DEV(UART0_CLK),
AM335X_GENERIC_CLOCK_DEV(UART1_CLK),
/* 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(DMTIMER2_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
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 */
AM335X_GPIO_CLOCK_DEV(GPIO0_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 */
AM335X_GENERIC_CLOCK_DEV(I2C0_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),
/* TSC_ADC */
AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK),
@ -274,9 +274,9 @@ struct ti_clock_dev ti_am335x_clk_devmap[] = {
AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
/* MMCHS */
AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
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),
@ -319,31 +319,31 @@ struct am335x_clk_details {
static struct am335x_clk_details g_am335x_clk_details[] = {
/* UART. UART0 clock not controllable. */
_CLK_DETAIL(UART0_CLK, 0, 0),
_CLK_DETAIL(UART1_CLK, CM_PER_UART1_CLKCTRL, 0),
_CLK_DETAIL(UART2_CLK, CM_PER_UART2_CLKCTRL, 0),
_CLK_DETAIL(UART3_CLK, CM_PER_UART3_CLKCTRL, 0),
_CLK_DETAIL(UART4_CLK, CM_PER_UART4_CLKCTRL, 0),
_CLK_DETAIL(UART5_CLK, CM_PER_UART5_CLKCTRL, 0),
_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(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
_CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
_CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
_CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
_CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
_CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
_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 */
_CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
_CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
_CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
_CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
/* 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 */
_CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
_CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
_CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_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),
/* TSC_ADC module */
_CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0),
@ -354,10 +354,10 @@ static struct am335x_clk_details g_am335x_clk_details[] = {
_CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
_CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
/* MMCHS modules*/
_CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
_CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_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),
@ -388,7 +388,7 @@ am335x_prcm_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "am335x,prcm")) {
if (ofw_bus_is_compatible(dev, "ti,am3-prcm")) {
device_set_desc(dev, "AM335x Power and Clock Management");
return(BUS_PROBE_DEFAULT);
}
@ -416,10 +416,15 @@ am335x_prcm_attach(device_t dev)
am335x_prcm_sc = sc;
ti_cpu_reset = am335x_prcm_reset;
am335x_clk_get_sysclk_freq(NULL, &sysclk);
am335x_clk_get_arm_fclk_freq(NULL, &fclk);
device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
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);
}

View File

@ -28,6 +28,6 @@
#ifndef __AM335X_PWM_H__
#define __AM335X_PWM_H__
int am335x_pwm_config_ecas(int unit, int period, int duty);
int am335x_pwm_config_ecap(int unit, int period, int duty);
#endif /* __AM335X_PWM_H__ */

View File

@ -0,0 +1,163 @@
/*-
* Copyright (c) 2013 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <dev/fdt/fdt_common.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 <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_scm.h>
#include "am335x_pwm.h"
#include "am335x_scm.h"
#define PWMSS_IDVER 0x00
#define PWMSS_SYSCONFIG 0x04
#define PWMSS_CLKCONFIG 0x08
#define CLKCONFIG_EPWMCLK_EN (1 << 8)
#define PWMSS_CLKSTATUS 0x0C
static device_probe_t am335x_pwmss_probe;
static device_attach_t am335x_pwmss_attach;
static device_detach_t am335x_pwmss_detach;
struct am335x_pwmss_softc {
device_t sc_dev;
clk_ident_t sc_clk;
};
static device_method_t am335x_pwmss_methods[] = {
DEVMETHOD(device_probe, am335x_pwmss_probe),
DEVMETHOD(device_attach, am335x_pwmss_attach),
DEVMETHOD(device_detach, am335x_pwmss_detach),
DEVMETHOD_END
};
static int
am335x_pwmss_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,am33xx-pwmss"))
return (ENXIO);
device_set_desc(dev, "AM335x PWM");
return (BUS_PROBE_DEFAULT);
}
static int
am335x_pwmss_attach(device_t dev)
{
struct am335x_pwmss_softc *sc;
uint32_t reg, id;
phandle_t node;
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_clk = ti_hwmods_get_clock(dev);
if (sc->sc_clk == INVALID_CLK_IDENT) {
device_printf(dev, "failed to get device id based on ti,hwmods\n");
return (EINVAL);
}
ti_prcm_clk_enable(sc->sc_clk);
ti_scm_reg_read_4(SCM_PWMSS_CTRL, &reg);
switch (sc->sc_clk) {
case PWMSS0_CLK:
id = 0;
break;
case PWMSS1_CLK:
id = 1;
break;
case PWMSS2_CLK:
id = 2;
break;
default:
device_printf(dev, "unknown pwmss clock id: %d\n", sc->sc_clk);
return (EINVAL);
}
reg |= (1 << id);
ti_scm_reg_write_4(SCM_PWMSS_CTRL, reg);
node = ofw_bus_get_node(dev);
if (node == -1)
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
am335x_pwmss_detach(device_t dev)
{
return (0);
}
DEFINE_CLASS_1(am335x_pwmss, am335x_pwmss_driver, am335x_pwmss_methods,
sizeof(struct am335x_pwmss_softc), simplebus_driver);
static devclass_t am335x_pwmss_devclass;
DRIVER_MODULE(am335x_pwmss, simplebus, am335x_pwmss_driver, am335x_pwmss_devclass, 0, 0);
MODULE_VERSION(am335x_pwmss, 1);

View File

@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_pinmux.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
.muxmodes[7] = m7, \
}
const static struct ti_scm_padstate ti_padstate_devmap[] = {
const static struct ti_pinmux_padstate ti_padstate_devmap[] = {
{"output", PADCONF_OUTPUT },
{"output_pullup", PADCONF_OUTPUT_PULLUP },
{"input", PADCONF_INPUT },
@ -74,228 +74,228 @@ const static struct ti_scm_padstate ti_padstate_devmap[] = {
{ .state = NULL }
};
const static struct ti_scm_padconf ti_padconf_devmap[] = {
_PIN(0x800, "GPMC_AD0", 32, 7,"gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0"),
_PIN(0x804, "GPMC_AD1", 33, 7,"gpmc_ad1", "mmc1_dat1", NULL, NULL, NULL, NULL, NULL, "gpio1_1"),
_PIN(0x808, "GPMC_AD2", 34, 7,"gpmc_ad2", "mmc1_dat2", NULL, NULL, NULL, NULL, NULL, "gpio1_2"),
_PIN(0x80C, "GPMC_AD3", 35, 7,"gpmc_ad3", "mmc1_dat3", NULL, NULL, NULL, NULL, NULL, "gpio1_3"),
_PIN(0x810, "GPMC_AD4", 36, 7,"gpmc_ad4", "mmc1_dat4", NULL, NULL, NULL, NULL, NULL, "gpio1_4"),
_PIN(0x814, "GPMC_AD5", 37, 7,"gpmc_ad5", "mmc1_dat5", NULL, NULL, NULL, NULL, NULL, "gpio1_5"),
_PIN(0x818, "GPMC_AD6", 38, 7,"gpmc_ad6", "mmc1_dat6", NULL, NULL, NULL, NULL, NULL, "gpio1_6"),
_PIN(0x81C, "GPMC_AD7", 39, 7,"gpmc_ad7", "mmc1_dat7", NULL, NULL, NULL, NULL, NULL, "gpio1_7"),
_PIN(0x820, "GPMC_AD8", 22, 7, "gpmc_ad8", "lcd_data23", "mmc1_dat0", "mmc2_dat4", "ehrpwm2A", NULL, NULL, "gpio0_22"),
_PIN(0x824, "GPMC_AD9", 23, 7, "gpmc_ad9", "lcd_data22", "mmc1_dat1", "mmc2_dat5", "ehrpwm2B", NULL, NULL, "gpio0_23"),
_PIN(0x828, "GPMC_AD10", 26, 7, "gpmc_ad10", "lcd_data21", "mmc1_dat2", "mmc2_dat6", "ehrpwm2_tripzone_in", NULL, NULL, "gpio0_26"),
_PIN(0x82C, "GPMC_AD11", 27, 7, "gpmc_ad11", "lcd_data20", "mmc1_dat3", "mmc2_dat7", "ehrpwm0_synco", NULL, NULL, "gpio0_27"),
_PIN(0x830, "GPMC_AD12", 44, 7, "gpmc_ad12", "lcd_data19", "mmc1_dat4", "mmc2_dat0", "eQEP2A_in", "pr1_mii0_txd2", "pr1_pru0_pru_r30_14", "gpio1_12"),
_PIN(0x834, "GPMC_AD13", 45, 7, "gpmc_ad13", "lcd_data18", "mmc1_dat5", "mmc2_dat1", "eQEP2B_in", "pr1_mii0_txd1", "pr1_pru0_pru_r30_15", "gpio1_13"),
_PIN(0x838, "GPMC_AD14", 46, 7, "gpmc_ad14", "lcd_data17", "mmc1_dat6", "mmc2_dat2", "eQEP2_index", "pr1_mii0_txd0", "pr1_pru0_pru_r31_14", "gpio1_14"),
_PIN(0x83C, "GPMC_AD15", 47, 7, "gpmc_ad15", "lcd_data16", "mmc1_dat7", "mmc2_dat3", "eQEP2_strobe", "pr1_ecap0_ecap_capin_apwm_o", "pr1_pru0_pru_r31_15", "gpio1_15"),
_PIN(0x840, "GPMC_A0", 48, 7, "gpmc_a0", "gmii2_txen", "rgmii2_tctl", "rmii2_txen", "gpmc_a16", "pr1_mii_mt1_clk", "ehrpwm1_tripzone_input", "gpio1_16"),
_PIN(0x844, "GPMC_A1", 49, 7, "gpmc_a1", "gmii2_rxdv", "rgmii2_rctl", "mmc2_dat0", "gpmc_a17", "pr1_mii1_txd3", "ehrpwm0_synco", "gpio1_17"),
_PIN(0x848, "GPMC_A2", 50, 7, "gpmc_a2", "gmii2_txd3", "rgmii2_td3", "mmc2_dat1", "gpmc_a18", "pr1_mii1_txd2", "ehrpwm1A", "gpio1_18"),
_PIN(0x84C, "GPMC_A3", 51, 7, "gpmc_a3", "gmii2_txd2", "rgmii2_td2", "mmc2_dat2", "gpmc_a19", "pr1_mii1_txd1", "ehrpwm1B", "gpio1_19"),
_PIN(0x850, "GPMC_A4", 52, 7, "gpmc_a4", "gmii2_txd1", "rgmii2_td1", "rmii2_tdx1", "gpmc_a20", "pr1_mii1_txd0", "eQEP1A_in", "gpio1_20"),
_PIN(0x854, "GPMC_A5", 53, 7, "gpmc_a5", "gmii2_txd0", "rgmii2_td0", "rmii2_txd0", "gpmc_a21", "pr1_mii1_rxd3", "eQEP1B_in", "gpio1_21"),
_PIN(0x858, "GPMC_A6", 54, 7, "gpmc_a6", "gmii2_txclk", "rgmii2_tclk", "mmc2_dat4", "gpmc_a22", "pr1_mii1_rxd2", "eQEP1_index", "gpio1_22"),
_PIN(0x85C, "GPMC_A7", 55, 7, "gpmc_a7", "gmii2_rxclk", "rgmii2_rclk", "mmc2_dat5", "gpmc_a23", "pr1_mii1_rxd1", "eQEP1_strobe", "gpio1_23"),
_PIN(0x860, "GPMC_A8", 56, 7, "gpmc_a8", "gmii2_rxd3", "rgmii2_rd3", "mmc2_dat6", "gpmc_a24", "pr1_mii1_rxd0", "mcasp0_aclkx", "gpio1_24"),
_PIN(0x864, "GPMC_A9", 57, 7, "gmpc_a9", "gmii2_rxd2", "rgmii2_rd2", "mmc2_dat7 / rmii2_crs_dv", "gpmc_a25", "pr1_mii_mr1_clk", "mcasp0_fsx", "gpio1_25"),
_PIN(0x868, "GPMC_A10", 58, 7, "gmpc_a10", "gmii2_rxd1", "rgmii2_rd1", "rmii2_rxd1", "gpmc_a26", "pr1_mii1_rxdv", "mcasp0_arx0", "gpio1_26"),
_PIN(0x86C, "GPMC_A11", 59, 7, "gmpc_a11", "gmii2_rxd0", "rgmii2_rd0", "rmii2_rxd0", "gpmc_a27", "pr1_mii1_rxer", "mcasp0_axr1", "gpio1_27"),
_PIN(0x870, "GPMC_WAIT0", 30, 7, "gpmc_wait0", "gmii2_crs", "gpmc_csn4", "rmii2_crs_dv", "mmc1_sdcd", "pr1_mii1_col", "uart4_rxd", "gpio0_30"),
_PIN(0x874, "GPMC_WPn", 31, 7, "gpmc_wpn", "gmii2_rxerr", "gpmc_csn5", "rmii2_rxerr", "mmc2_sdcd", "pr1_mii1_txen", "uart4_txd", "gpio0_31"),
_PIN(0x878, "GPMC_BEn1", 60, 7, "gpmc_be1n", "gmii2_col", "gmpc_csn6","mmc2_dat3", "gpmc_dir", "pr1_mii1_rxlink", "mcasp0_aclkr", "gpio1_28"),
_PIN(0x87c, "GPMC_CSn0", 61, 7, "gpmc_csn0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio1_29"),
_PIN(0x880, "GPMC_CSn1", 62, 7, "gpmc_csn1", "gpmc_clk", "mmc1_clk", "pr1_edio_data_in6", "pr1_edio_data_out6", "pr1_pru1_pru_r30_12", "pr1_pru1_pru_r31_12", "gpio1_30"),
_PIN(0x884, "GPMC_CSn2", 63, 7, "gpmc_csn2", "gpmc_be1n", "mmc1_cmd", "pr1_edio_data_in7", "pr1_edio_data_out7", "pr1_pru1_pru_r30_13", "pr1_pru1_pru_r31_13", "gpio1_31"),
_PIN(0x888, "GPMC_CSn3", 64, 7, "gpmc_csn3", "gpmc_a3", "rmii2_crs_dv", "mmc2_cmd", "pr1_mii0_crs", "pr1_mdio_data", "EMU4", "gpio2_0"),
_PIN(0x88c, "GPMC_CLK", 65, 7, "gpmc_clk", "lcd_memory_clk", "gpmc_wait1", "mmc2_clk", "pr1_mii1_crs", "pr1_mdio_mdclk", "mcasp0_fsr", "gpio2_1"),
_PIN(0x890, "GPMC_ADVn_ALE", 66, 7, "gpmc_advn_ale", NULL, "timer4", NULL, NULL, NULL, NULL, "gpio2_2"),
_PIN(0x894, "GPMC_OEn_REn", 67, 7, "gpmc_oen_ren", NULL, "timer7", NULL, NULL, NULL, NULL, "gpio2_3"),
_PIN(0x898, "GPMC_WEn", 68, 7, "gpmc_wen", NULL, "timer6", NULL, NULL, NULL, NULL, "gpio2_4"),
_PIN(0x89c, "GPMC_BEn0_CLE", 67, 7, "gpmc_ben0_cle", NULL, "timer5", NULL, NULL, NULL, NULL, "gpio2_5"),
_PIN(0x8a0, "LCD_DATA0", 68, 7, "lcd_data0", "gpmc_a0", "pr1_mii_mt0_clk", "ehrpwm2A", NULL, "pr1_pru1_pru_r30_0", "pr1_pru1_pru_r31_0", "gpio2_6"),
_PIN(0x8a4, "LCD_DATA1", 69, 7, "lcd_data1", "gpmc_a1", "pr1_mii0_txen", "ehrpwm2B", NULL, "pr1_pru1_pru_r30_1", "pr1_pru1_pru_r31_1", "gpio2_7"),
_PIN(0x8a8, "LCD_DATA2", 70, 7, "lcd_data2", "gpmc_a2", "pr1_mii0_txd3", "ehrpwm2_tripzone_input", NULL, "pr1_pru1_pru_r30_2", "pr1_pru1_pru_r31_2", "gpio2_8"),
_PIN(0x8ac, "LCD_DATA3", 71, 7, "lcd_data3", "gpmc_a3", "pr1_mii0_txd2", "ehrpwm0_synco", NULL, "pr1_pru1_pru_r30_3", "pr1_pru1_pru_r31_3", "gpio2_9"),
_PIN(0x8b0, "LCD_DATA4", 72, 7, "lcd_data4", "gpmc_a4", "pr1_mii0_txd1", "eQEP2A_in", NULL, "pr1_pru1_pru_r30_4", "pr1_pru1_pru_r31_4", "gpio2_10"),
_PIN(0x8b4, "LCD_DATA5", 73, 7, "lcd_data5", "gpmc_a5", "pr1_mii0_txd0", "eQEP2B_in", NULL, "pr1_pru1_pru_r30_5", "pr1_pru1_pru_r31_5", "gpio2_11"),
_PIN(0x8b8, "LCD_DATA6", 74, 7, "lcd_data6", "gpmc_a6", "pr1_edio_data_in6", "eQEP2_index", "pr1_edio_data_out6", "pr1_pru1_pru_r30_6", "pr1_pru1_pru_r31_6", "gpio2_12"),
_PIN(0x8bc, "LCD_DATA7", 75, 7, "lcd_data7", "gpmc_a7", "pr1_edio_data_in7", "eQEP2_strobe", "pr1_edio_data_out7", "pr1_pru1_pru_r30_7", "pr1_pru1_pru_r31_7", "gpio2_13"),
_PIN(0x8c0, "LCD_DATA8", 76, 7, "lcd_data8", "gpmc_a12", "ehrpwm1_tripzone_input", "mcasp0_aclkx", "uart5_txd", "pr1_mii0_rxd3", "uart2_ctsn", "gpio2_14"),
_PIN(0x8c4, "LCD_DATA9", 76, 7, "lcd_data9", "gpmc_a13", "ehrpwm0_synco", "mcasp0_fsx", "uart5_rxd", "pr1_mii0_rxd2", "uart2_rtsn", "gpio2_15"),
_PIN(0x8c8, "LCD_DATA10", 77, 7, "lcd_data10", "gpmc_a14", "ehrpwm1A", "mcasp0_axr0", NULL, "pr1_mii0_rxd1", "uart3_ctsn", "gpio2_16"),
_PIN(0x8cc, "LCD_DATA11", 78, 7, "lcd_data11", "gpmc_a15", "ehrpwm1B", "mcasp0_ahclkr", "mcasp0_axr2", "pr1_mii0_rxd0", "uart3_rtsn", "gpio2_17"),
_PIN(0x8d0, "LCD_DATA12", 8, 7, "lcd_data12", "gpmc_a16", "eQEP1A_in", "mcasp0_aclkr", "mcasp0_axr2", "pr1_mii0_rxlink", "uart4_ctsn", "gpio0_8"),
_PIN(0x8d4, "LCD_DATA13", 9, 7, "lcd_data13", "gpmc_a17", "eQEP1B_in", "mcasp0_fsr", "mcasp0_axr3", "pr1_mii0_rxer", "uart4_rtsn", "gpio0_9"),
_PIN(0x8d8, "LCD_DATA14", 10, 7, "lcd_data14", "gpmc_a18", "eQEP1_index", "mcasp0_axr1", "uart5_rxd", "pr1_mii_mr0_clk", "uart5_ctsn", "gpio0_10"),
_PIN(0x8dc, "LCD_DATA15", 11, 7, "lcd_data15", "gpmc_a19", "eQEP1_strobe", "mcasp0_ahclkx", "mcasp0_axr3", "pr1_mii0_rxdv", "uart5_rtsn", "gpio0_11"),
_PIN(0x8e0, "LCD_VSYNC", 86, 7, "lcd_vsync", "gpmc_a8", "gpmc_a1", "pr1_edio_data_in2", "pr1_edio_data_out2", "pr1_pru1_pru_r30_8", "pr1_pru1_pru_r31_8", "gpio2_22"),
_PIN(0x8e4, "LCD_HSYNC", 87, 7, "lcd_hsync", "gmpc_a9", "gpmc_a2", "pr1_edio_data_in3", "pr1_edio_data_out3", "pr1_pru1_pru_r30_9", "pr1_pru1_pru_r31_9", "gpio2_23"),
_PIN(0x8e8, "LCD_PCLK", 88, 7, "lcd_pclk", "gpmc_a10", "pr1_mii0_crs", "pr1_edio_data_in4", "pr1_edio_data_out4", "pr1_pru1_pru_r30_10", "pr1_pru1_pru_r31_10", "gpio2_24"),
_PIN(0x8ec, "LCD_AC_BIAS_EN", 89, 7, "lcd_ac_bias_en", "gpmc_a11", "pr1_mii1_crs", "pr1_edio_data_in5", "pr1_edio_data_out5", "pr1_pru1_pru_r30_11", "pr1_pru1_pru_r31_11", "gpio2_25"),
_PIN(0x8f0, "MMC0_DAT3", 90, 7, "mmc0_dat3", "gpmc_a20", "uart4_ctsn", "timer5", "uart1_dcdn", "pr1_pru0_pru_r30_8", "pr1_pru0_pru_r31_8", "gpio2_26"),
_PIN(0x8f4, "MMC0_DAT2", 91, 7, "mmc0_dat2", "gpmc_a21", "uart4_rtsn", "timer6", "uart1_dsrn", "pr1_pru0_pru_r30_9", "pr1_pru0_pru_r31_9", "gpio2_27"),
_PIN(0x8f8, "MMC0_DAT1", 92, 7, "mmc0_dat1", "gpmc_a22", "uart5_ctsn", "uart3_rxd", "uart1_dtrn", "pr1_pru0_pru_r30_10", "pr1_pru0_pru_r31_10", "gpio2_28"),
_PIN(0x8fc, "MMC0_DAT0", 93, 7, "mmc0_dat0", "gpmc_a23", "uart5_rtsn", "uart3_txd", "uart1_rin", "pr1_pru0_pru_r30_11", "pr1_pru0_pru_r31_11", "gpio2_29"),
_PIN(0x900, "MMC0_CLK", 94, 7, "mmc0_clk", "gpmc_a24", "uart3_ctsn", "uart2_rxd", "dcan1_tx", "pr1_pru0_pru_r30_12", "pr1_pru0_pru_r31_12", "gpio2_30"),
_PIN(0x904, "MMC0_CMD", 95, 7, "mmc0_cmd", "gpmc_a25", "uart3_rtsn", "uart2_txd", "dcan1_rx", "pr1_pru0_pru_r30_13", "pr1_pru0_pru_r31_13", "gpio2_31"),
_PIN(0x908, "MII1_COL", 96, 7, "gmii1_col", "rmii2_refclk", "spi1_sclk", "uart5_rxd", "mcasp1_axr2", "mmc2_dat3", "mcasp0_axr2", "gpio3_0"),
_PIN(0x90c, "MII1_CRS", 97, 7, "gmii1_crs", "rmii1_crs_dv", "spi1_d0", "I2C1_SDA", "mcasp1_aclkx", "uart5_ctsn", "uart2_rxd", "gpio3_1"),
_PIN(0x910, "MII1_RX_ER", 98, 7, "gmii1_rxerr", "rmii1_rxerr", "spi1_d1", "I2C1_SCL", "mcasp1_fsx", "uart5_rtsn", "uart2_txd", "gpio3_2"),
_PIN(0x914, "MII1_TX_EN", 99, 7, "gmii1_txen", "rmii1_txen", "rgmii1_tctl", "timer4", "mcasp1_axr0", "eQEP0_index", "mmc2_cmd", "gpio3_3"),
_PIN(0x918, "MII1_RX_DV", 100, 7, "gmii1_rxdv", "cd_memory_clk", "rgmii1_rctl", "uart5_txd", "mcasp1_aclkx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),
_PIN(0x91c, "MII1_TXD3", 16, 7, "gmii1_txd3", "dcan0_tx", "rgmii1_td3", "uart4_rxd", "mcasp1_fsx", "mmc2_dat1", "mcasp0_fsr", "gpio0_16"),
_PIN(0x920, "MII1_TXD2", 17, 7, "gmii1_txd2", "dcan0_rx", "rgmii1_td2", "uart4_txd", "mcasp1_axr0", "mmc2_dat2", "mcasp0_ahclkx", "gpio0_17"),
_PIN(0x924, "MII1_TXD1", 21, 7, "gmii1_txd1", "rmii1_txd1", "rgmii1_td1", "mcasp1_fsr", "mcasp1_axr1", "eQEP0A_in", "mmc1_cmd", "gpio0_21"),
_PIN(0x928, "MII1_TXD0", 28, 7, "gmii1_txd0", "rmii1_txd0", "rgmii1_td0", "mcasp1_axr2", "mcasp1_aclkr", "eQEP0B_in", "mmc1_clk", "gpio0_28"),
_PIN(0x92c, "MII1_TX_CLK", 105, 7, "gmii1_txclk", "uart2_rxd", "rgmii1_tclk", "mmc0_dat7", "mmc1_dat0", "uart1_dcdn", "mcasp0_aclkx", "gpio3_9"),
_PIN(0x930, "MII1_RX_CLK", 106, 7, "gmii1_rxclk", "uart2_txd", "rgmii1_rclk", "mmc0_dat6", "mmc1_dat1", "uart1_dsrn", "mcasp0_fsx", "gpio3_10"),
_PIN(0x934, "MII1_RXD3", 82, 7, "gmii1_rxd3", "uart3_rxd", "rgmii1_rd3", "mmc0_dat5", "mmc1_dat2", "uart1_dtrn", "mcasp0_axr0", "gpio2_18"),
_PIN(0x938, "MII1_RXD2", 83, 7, "gmii1_rxd2", "uart3_txd", "rgmii1_rd2", "mmc0_dat4", "mmc1_dat3", "uart1_rin", "mcasp0_axr1", "gpio2_19"),
_PIN(0x93c, "MII1_RXD1", 84, 7, "gmii1_rxd1", "rmii1_rxd1", "rgmii1_rd1", "mcasp1_axr3", "mcasp1_fsr", "eQEP0_strobe", "mmc2_clk", "gpio2_20"),
_PIN(0x940, "MII1_RXD0", 85, 7, "gmii1_rxd0", "rmii1_rxd0", "rgmii1_rd0", "mcasp1_ahclkx", "mcasp1_ahclkr", "mcasp1_aclkr", "mcasp0_axr3", "gpio2_21"),
_PIN(0x944, "RMII1_REF_CLK", 29, 7, "rmii1_refclk", "xdma_event_intr2", "spi1_cs0", "uart5_txd", "mcasp1_axr3", "mmc0_pow", "mcasp1_ahclkx", "gpio0_29"),
_PIN(0x948, "MDIO", 0, 7, "mdio_data", "timer6", "uart5_rxd", "uart3_ctsn", "mmc0_sdcd","mmc1_cmd", "mmc2_cmd","gpio0_0"),
_PIN(0x94c, "MDC", 1, 7, "mdio_clk", "timer5", "uart5_txd", "uart3_rtsn", "mmc0_sdwp", "mmc1_clk", "mmc2_clk", "gpio0_1"),
_PIN(0x950, "SPI0_SCLK", 2, 7, "spi0_sclk", "uart2_rxd", "I2C2_SDA", "ehrpwm0A", "pr1_uart0_cts_n", "pr1_edio_sof", "EMU2", "gpio0_2"),
_PIN(0x954, "SPI0_D0", 3, 7, "spi0_d0", "uart2_txd", "I2C2_SCL", "ehrpwm0B", "pr1_uart0_rts_n", "pr1_edio_latch_in", "EMU3", "gpio0_3"),
_PIN(0x958, "SPI0_D1", 4, 7, "spi0_d1", "mmc1_sdwp", "I2C1_SDA", "ehrpwm0_tripzone_input", "pr1_uart0_rxd", "pr1_edio_data_in0", "pr1_edio_data_out0", "gpio0_4"),
_PIN(0x95c, "SPI0_CS0", 5, 7, "spi0_cs0", "mmc2_sdwp", "I2C1_SCL", "ehrpwm0_synci", "pr1_uart0_txd", "pr1_edio_data_in1", "pr1_edio_data_out1", "gpio0_5"),
_PIN(0x960, "SPI0_CS1", 6, 7, "spi0_cs1", "uart3_rxd", "eCAP1_in_PWM1_out", "mcc0_pow", "xdm_event_intr2", "mmc0_sdcd", "EMU4", "gpio0_6"),
_PIN(0x964, "ECAP0_IN_PWM0_OUT",7, 7, "eCAP0_in_PWM0_out", "uart3_txd", "spi1_cs1", "pr1_ecap0_ecap_capin_apwm_o", "spi1_sclk", "mmc0_sdwp", "xdma_event_intr2", "gpio0_7"),
_PIN(0x968, "UART0_CTSn", 40, 7, "uart0_ctsn", "uart4_rxd", "dcan1_tx", "I2C1_SDA", "spi1_d0", "timer7", "pr1_edc_sync0_out", "gpio1_8"),
_PIN(0x96c, "UART0_RTSn", 41, 7, "uart0_rtsn", "uart4_txd", "dcan1_rx", "I2C1_SCL", "spi1_d1", "spi1_cs0", "pr1_edc_sync1_out", "gpio1_9"),
_PIN(0x970, "UART0_rxd", 42, 7, "uart0_rxd", "spi1_cs0", "dcan0_tx", "I2C2_SDA", "eCAP2_in_PWM2_out", "pr1_pru1_pru_r30_14", "pr1_pru1_pru_r31_14", "gpio1_10"),
_PIN(0x974, "UART0_txd", 43, 7, "uart0_txd", "spi1_cs1", "dcan0_rx", "I2C2_SCL", "eCAP1_in_PWM1_out", "pr1_pru1_pru_r30_15", "pr1_pru1_pru_r31_15", "gpio1_11"),
_PIN(0x978, "UART1_CTSn", 12, 7, "uart1_ctsn", "timer6_mux1", "dcan0_tx", "I2C2_SDA", "spi1_cs0", "pr1_uart0_cts_n", "pr1_edc_latch0_in", "gpio0_12"),
_PIN(0x97c, "UART1_RTSn", 13, 7, "uart1_rtsn", "timer5_mux1", "dcan0_rx", "I2C2_SCL", "spi1_cs1", "pr1_uart0_rts_n", "pr1_edc_latch1_in", "gpio0_13"),
_PIN(0x980, "UART1_RXD", 14, 7, "uart1_rxd", "mmc1_sdwp", "dcan1_tx", "I2C1_SDA", NULL, "pr1_uart0_rxd", "pr1_pru1_pru_r31_16", "gpio0_14"),
_PIN(0x984, "UART1_TXD", 15, 7, "uart1_txd", "mmc2_sdwp", "dcan1_rx", "I2C1_SCL", NULL, "pr1_uart0_txd", "pr1_pru0_pru_r31_16", "gpio0_15"),
_PIN(0x988, "I2C0_SDA", 101, 7, "I2C0_SDA", "timer4", "uart2_ctsn", "eCAP2_in_PWM2_out", NULL, NULL, NULL, "gpio3_5"),
_PIN(0x98c, "I2C0_SCL", 102, 7, "I2C0_SCL", "timer7", "uart2_rtsn", "eCAP1_in_PWM1_out", NULL, NULL, NULL, "gpio3_6"),
_PIN(0x990, "MCASP0_ACLKX", 110, 7, "mcasp0_aclkx", "ehrpwm0A", NULL, "spi1_sclk", "mmc0_sdcd", "pr1_pru0_pru_r30_0", "pr1_pru0_pru_r31_0", "gpio3_14"),
_PIN(0x994, "MCASP0_FSX", 111, 7, "mcasp0_fsx", "ehrpwm0B", NULL, "spi1_d0", "mmc1_sdcd", "pr1_pru0_pru_r30_1", "pr1_pru0_pru_r31_1", "gpio3_15"),
_PIN(0x998, "MCASP0_AXR0", 112, 7, "mcasp0_axr0", "ehrpwm0_tripzone_input", NULL, "spi1_d1", "mmc2_sdcd", "pr1_pru0_pru_r30_2", "pr1_pru0_pru_r31_2", "gpio3_16"),
_PIN(0x99c, "MCASP0_AHCLKR", 113, 7, "mcasp0_ahclkr", "ehrpwm0_synci", "mcasp0_axr2", "spi1_cs0", "eCAP2_in_PWM2_out", "pr1_pru0_pru_r30_3", "pr1_pru0_pru_r31_3", "gpio3_17"),
_PIN(0x9a0, "MCASP0_ACLKR", 114, 7, "mcasp0_aclkr", "eQEP0A_in", "mcasp0_axr2", "mcasp1_aclkx", "mmc0_sdwp", "pr1_pru0_pru_r30_4", "pr1_pru0_pru_r31_4", "gpio3_18"),
_PIN(0x9a4, "MCASP0_FSR", 115, 7, "mcasp0_fsr", "eQEP0B_in", "mcasp0_axr3", "mcasp1_fsx", "EMU2", "pr1_pru0_pru_r30_5", "pr1_pru0_pru_r31_5", "gpio3_19"),
_PIN(0x9a8, "MCASP0_AXR1", 116, 7, "mcasp0_axr1", "eQEP0_index", NULL, "mcasp1_axr0", "EMU3", "pr1_pru0_pru_r30_6", "pr1_pru0_pru_r31_6", "gpio3_20"),
_PIN(0x9ac, "MCASP0_AHCLKX", 117, 7, "mcasp0_ahclkx", "eQEP0_strobe", "mcasp0_axr3", "mcasp1_axr1", "EMU4", "pr1_pru0_pru_r30_7", "pr1_pru0_pru_r31_7", "gpio3_21"),
_PIN(0x9b0, "XDMA_EVENT_INTR0", 19, 7, "xdma_event_intr0", NULL, "timer4", "clkout1", "spi1_cs1", "pr1_pru1_pru_r31_16", "EMU2", "gpio0_19"),
_PIN(0x9b4, "XDMA_EVENT_INTR1", 20, 7, "xdma_event_intr1", NULL, "tclkin", "clkout2", "timer7", "pr1_pru0_pru_r31_16", "EMU3", "gpio0_20"),
const static struct ti_pinmux_padconf ti_padconf_devmap[] = {
_PIN(0x000, "GPMC_AD0", 32, 7,"gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0"),
_PIN(0x004, "GPMC_AD1", 33, 7,"gpmc_ad1", "mmc1_dat1", NULL, NULL, NULL, NULL, NULL, "gpio1_1"),
_PIN(0x008, "GPMC_AD2", 34, 7,"gpmc_ad2", "mmc1_dat2", NULL, NULL, NULL, NULL, NULL, "gpio1_2"),
_PIN(0x00C, "GPMC_AD3", 35, 7,"gpmc_ad3", "mmc1_dat3", NULL, NULL, NULL, NULL, NULL, "gpio1_3"),
_PIN(0x010, "GPMC_AD4", 36, 7,"gpmc_ad4", "mmc1_dat4", NULL, NULL, NULL, NULL, NULL, "gpio1_4"),
_PIN(0x014, "GPMC_AD5", 37, 7,"gpmc_ad5", "mmc1_dat5", NULL, NULL, NULL, NULL, NULL, "gpio1_5"),
_PIN(0x018, "GPMC_AD6", 38, 7,"gpmc_ad6", "mmc1_dat6", NULL, NULL, NULL, NULL, NULL, "gpio1_6"),
_PIN(0x01C, "GPMC_AD7", 39, 7,"gpmc_ad7", "mmc1_dat7", NULL, NULL, NULL, NULL, NULL, "gpio1_7"),
_PIN(0x020, "GPMC_AD8", 22, 7, "gpmc_ad8", "lcd_data23", "mmc1_dat0", "mmc2_dat4", "ehrpwm2A", NULL, NULL, "gpio0_22"),
_PIN(0x024, "GPMC_AD9", 23, 7, "gpmc_ad9", "lcd_data22", "mmc1_dat1", "mmc2_dat5", "ehrpwm2B", NULL, NULL, "gpio0_23"),
_PIN(0x028, "GPMC_AD10", 26, 7, "gpmc_ad10", "lcd_data21", "mmc1_dat2", "mmc2_dat6", "ehrpwm2_tripzone_in", NULL, NULL, "gpio0_26"),
_PIN(0x02C, "GPMC_AD11", 27, 7, "gpmc_ad11", "lcd_data20", "mmc1_dat3", "mmc2_dat7", "ehrpwm0_synco", NULL, NULL, "gpio0_27"),
_PIN(0x030, "GPMC_AD12", 44, 7, "gpmc_ad12", "lcd_data19", "mmc1_dat4", "mmc2_dat0", "eQEP2A_in", "pr1_mii0_txd2", "pr1_pru0_pru_r30_14", "gpio1_12"),
_PIN(0x034, "GPMC_AD13", 45, 7, "gpmc_ad13", "lcd_data18", "mmc1_dat5", "mmc2_dat1", "eQEP2B_in", "pr1_mii0_txd1", "pr1_pru0_pru_r30_15", "gpio1_13"),
_PIN(0x038, "GPMC_AD14", 46, 7, "gpmc_ad14", "lcd_data17", "mmc1_dat6", "mmc2_dat2", "eQEP2_index", "pr1_mii0_txd0", "pr1_pru0_pru_r31_14", "gpio1_14"),
_PIN(0x03C, "GPMC_AD15", 47, 7, "gpmc_ad15", "lcd_data16", "mmc1_dat7", "mmc2_dat3", "eQEP2_strobe", "pr1_ecap0_ecap_capin_apwm_o", "pr1_pru0_pru_r31_15", "gpio1_15"),
_PIN(0x040, "GPMC_A0", 48, 7, "gpmc_a0", "gmii2_txen", "rgmii2_tctl", "rmii2_txen", "gpmc_a16", "pr1_mii_mt1_clk", "ehrpwm1_tripzone_input", "gpio1_16"),
_PIN(0x044, "GPMC_A1", 49, 7, "gpmc_a1", "gmii2_rxdv", "rgmii2_rctl", "mmc2_dat0", "gpmc_a17", "pr1_mii1_txd3", "ehrpwm0_synco", "gpio1_17"),
_PIN(0x048, "GPMC_A2", 50, 7, "gpmc_a2", "gmii2_txd3", "rgmii2_td3", "mmc2_dat1", "gpmc_a18", "pr1_mii1_txd2", "ehrpwm1A", "gpio1_18"),
_PIN(0x04C, "GPMC_A3", 51, 7, "gpmc_a3", "gmii2_txd2", "rgmii2_td2", "mmc2_dat2", "gpmc_a19", "pr1_mii1_txd1", "ehrpwm1B", "gpio1_19"),
_PIN(0x050, "GPMC_A4", 52, 7, "gpmc_a4", "gmii2_txd1", "rgmii2_td1", "rmii2_tdx1", "gpmc_a20", "pr1_mii1_txd0", "eQEP1A_in", "gpio1_20"),
_PIN(0x054, "GPMC_A5", 53, 7, "gpmc_a5", "gmii2_txd0", "rgmii2_td0", "rmii2_txd0", "gpmc_a21", "pr1_mii1_rxd3", "eQEP1B_in", "gpio1_21"),
_PIN(0x058, "GPMC_A6", 54, 7, "gpmc_a6", "gmii2_txclk", "rgmii2_tclk", "mmc2_dat4", "gpmc_a22", "pr1_mii1_rxd2", "eQEP1_index", "gpio1_22"),
_PIN(0x05C, "GPMC_A7", 55, 7, "gpmc_a7", "gmii2_rxclk", "rgmii2_rclk", "mmc2_dat5", "gpmc_a23", "pr1_mii1_rxd1", "eQEP1_strobe", "gpio1_23"),
_PIN(0x060, "GPMC_A8", 56, 7, "gpmc_a8", "gmii2_rxd3", "rgmii2_rd3", "mmc2_dat6", "gpmc_a24", "pr1_mii1_rxd0", "mcasp0_aclkx", "gpio1_24"),
_PIN(0x064, "GPMC_A9", 57, 7, "gmpc_a9", "gmii2_rxd2", "rgmii2_rd2", "mmc2_dat7 / rmii2_crs_dv", "gpmc_a25", "pr1_mii_mr1_clk", "mcasp0_fsx", "gpio1_25"),
_PIN(0x068, "GPMC_A10", 58, 7, "gmpc_a10", "gmii2_rxd1", "rgmii2_rd1", "rmii2_rxd1", "gpmc_a26", "pr1_mii1_rxdv", "mcasp0_arx0", "gpio1_26"),
_PIN(0x06C, "GPMC_A11", 59, 7, "gmpc_a11", "gmii2_rxd0", "rgmii2_rd0", "rmii2_rxd0", "gpmc_a27", "pr1_mii1_rxer", "mcasp0_axr1", "gpio1_27"),
_PIN(0x070, "GPMC_WAIT0", 30, 7, "gpmc_wait0", "gmii2_crs", "gpmc_csn4", "rmii2_crs_dv", "mmc1_sdcd", "pr1_mii1_col", "uart4_rxd", "gpio0_30"),
_PIN(0x074, "GPMC_WPn", 31, 7, "gpmc_wpn", "gmii2_rxerr", "gpmc_csn5", "rmii2_rxerr", "mmc2_sdcd", "pr1_mii1_txen", "uart4_txd", "gpio0_31"),
_PIN(0x078, "GPMC_BEn1", 60, 7, "gpmc_be1n", "gmii2_col", "gmpc_csn6","mmc2_dat3", "gpmc_dir", "pr1_mii1_rxlink", "mcasp0_aclkr", "gpio1_28"),
_PIN(0x07c, "GPMC_CSn0", 61, 7, "gpmc_csn0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio1_29"),
_PIN(0x080, "GPMC_CSn1", 62, 7, "gpmc_csn1", "gpmc_clk", "mmc1_clk", "pr1_edio_data_in6", "pr1_edio_data_out6", "pr1_pru1_pru_r30_12", "pr1_pru1_pru_r31_12", "gpio1_30"),
_PIN(0x084, "GPMC_CSn2", 63, 7, "gpmc_csn2", "gpmc_be1n", "mmc1_cmd", "pr1_edio_data_in7", "pr1_edio_data_out7", "pr1_pru1_pru_r30_13", "pr1_pru1_pru_r31_13", "gpio1_31"),
_PIN(0x088, "GPMC_CSn3", 64, 7, "gpmc_csn3", "gpmc_a3", "rmii2_crs_dv", "mmc2_cmd", "pr1_mii0_crs", "pr1_mdio_data", "EMU4", "gpio2_0"),
_PIN(0x08c, "GPMC_CLK", 65, 7, "gpmc_clk", "lcd_memory_clk", "gpmc_wait1", "mmc2_clk", "pr1_mii1_crs", "pr1_mdio_mdclk", "mcasp0_fsr", "gpio2_1"),
_PIN(0x090, "GPMC_ADVn_ALE", 66, 7, "gpmc_advn_ale", NULL, "timer4", NULL, NULL, NULL, NULL, "gpio2_2"),
_PIN(0x094, "GPMC_OEn_REn", 67, 7, "gpmc_oen_ren", NULL, "timer7", NULL, NULL, NULL, NULL, "gpio2_3"),
_PIN(0x098, "GPMC_WEn", 68, 7, "gpmc_wen", NULL, "timer6", NULL, NULL, NULL, NULL, "gpio2_4"),
_PIN(0x09c, "GPMC_BEn0_CLE", 67, 7, "gpmc_ben0_cle", NULL, "timer5", NULL, NULL, NULL, NULL, "gpio2_5"),
_PIN(0x0a0, "LCD_DATA0", 68, 7, "lcd_data0", "gpmc_a0", "pr1_mii_mt0_clk", "ehrpwm2A", NULL, "pr1_pru1_pru_r30_0", "pr1_pru1_pru_r31_0", "gpio2_6"),
_PIN(0x0a4, "LCD_DATA1", 69, 7, "lcd_data1", "gpmc_a1", "pr1_mii0_txen", "ehrpwm2B", NULL, "pr1_pru1_pru_r30_1", "pr1_pru1_pru_r31_1", "gpio2_7"),
_PIN(0x0a8, "LCD_DATA2", 70, 7, "lcd_data2", "gpmc_a2", "pr1_mii0_txd3", "ehrpwm2_tripzone_input", NULL, "pr1_pru1_pru_r30_2", "pr1_pru1_pru_r31_2", "gpio2_8"),
_PIN(0x0ac, "LCD_DATA3", 71, 7, "lcd_data3", "gpmc_a3", "pr1_mii0_txd2", "ehrpwm0_synco", NULL, "pr1_pru1_pru_r30_3", "pr1_pru1_pru_r31_3", "gpio2_9"),
_PIN(0x0b0, "LCD_DATA4", 72, 7, "lcd_data4", "gpmc_a4", "pr1_mii0_txd1", "eQEP2A_in", NULL, "pr1_pru1_pru_r30_4", "pr1_pru1_pru_r31_4", "gpio2_10"),
_PIN(0x0b4, "LCD_DATA5", 73, 7, "lcd_data5", "gpmc_a5", "pr1_mii0_txd0", "eQEP2B_in", NULL, "pr1_pru1_pru_r30_5", "pr1_pru1_pru_r31_5", "gpio2_11"),
_PIN(0x0b8, "LCD_DATA6", 74, 7, "lcd_data6", "gpmc_a6", "pr1_edio_data_in6", "eQEP2_index", "pr1_edio_data_out6", "pr1_pru1_pru_r30_6", "pr1_pru1_pru_r31_6", "gpio2_12"),
_PIN(0x0bc, "LCD_DATA7", 75, 7, "lcd_data7", "gpmc_a7", "pr1_edio_data_in7", "eQEP2_strobe", "pr1_edio_data_out7", "pr1_pru1_pru_r30_7", "pr1_pru1_pru_r31_7", "gpio2_13"),
_PIN(0x0c0, "LCD_DATA8", 76, 7, "lcd_data8", "gpmc_a12", "ehrpwm1_tripzone_input", "mcasp0_aclkx", "uart5_txd", "pr1_mii0_rxd3", "uart2_ctsn", "gpio2_14"),
_PIN(0x0c4, "LCD_DATA9", 76, 7, "lcd_data9", "gpmc_a13", "ehrpwm0_synco", "mcasp0_fsx", "uart5_rxd", "pr1_mii0_rxd2", "uart2_rtsn", "gpio2_15"),
_PIN(0x0c8, "LCD_DATA10", 77, 7, "lcd_data10", "gpmc_a14", "ehrpwm1A", "mcasp0_axr0", NULL, "pr1_mii0_rxd1", "uart3_ctsn", "gpio2_16"),
_PIN(0x0cc, "LCD_DATA11", 78, 7, "lcd_data11", "gpmc_a15", "ehrpwm1B", "mcasp0_ahclkr", "mcasp0_axr2", "pr1_mii0_rxd0", "uart3_rtsn", "gpio2_17"),
_PIN(0x0d0, "LCD_DATA12", 8, 7, "lcd_data12", "gpmc_a16", "eQEP1A_in", "mcasp0_aclkr", "mcasp0_axr2", "pr1_mii0_rxlink", "uart4_ctsn", "gpio0_8"),
_PIN(0x0d4, "LCD_DATA13", 9, 7, "lcd_data13", "gpmc_a17", "eQEP1B_in", "mcasp0_fsr", "mcasp0_axr3", "pr1_mii0_rxer", "uart4_rtsn", "gpio0_9"),
_PIN(0x0d8, "LCD_DATA14", 10, 7, "lcd_data14", "gpmc_a18", "eQEP1_index", "mcasp0_axr1", "uart5_rxd", "pr1_mii_mr0_clk", "uart5_ctsn", "gpio0_10"),
_PIN(0x0dc, "LCD_DATA15", 11, 7, "lcd_data15", "gpmc_a19", "eQEP1_strobe", "mcasp0_ahclkx", "mcasp0_axr3", "pr1_mii0_rxdv", "uart5_rtsn", "gpio0_11"),
_PIN(0x0e0, "LCD_VSYNC", 86, 7, "lcd_vsync", "gpmc_a8", "gpmc_a1", "pr1_edio_data_in2", "pr1_edio_data_out2", "pr1_pru1_pru_r30_8", "pr1_pru1_pru_r31_8", "gpio2_22"),
_PIN(0x0e4, "LCD_HSYNC", 87, 7, "lcd_hsync", "gmpc_a9", "gpmc_a2", "pr1_edio_data_in3", "pr1_edio_data_out3", "pr1_pru1_pru_r30_9", "pr1_pru1_pru_r31_9", "gpio2_23"),
_PIN(0x0e8, "LCD_PCLK", 88, 7, "lcd_pclk", "gpmc_a10", "pr1_mii0_crs", "pr1_edio_data_in4", "pr1_edio_data_out4", "pr1_pru1_pru_r30_10", "pr1_pru1_pru_r31_10", "gpio2_24"),
_PIN(0x0ec, "LCD_AC_BIAS_EN", 89, 7, "lcd_ac_bias_en", "gpmc_a11", "pr1_mii1_crs", "pr1_edio_data_in5", "pr1_edio_data_out5", "pr1_pru1_pru_r30_11", "pr1_pru1_pru_r31_11", "gpio2_25"),
_PIN(0x0f0, "MMC0_DAT3", 90, 7, "mmc0_dat3", "gpmc_a20", "uart4_ctsn", "timer5", "uart1_dcdn", "pr1_pru0_pru_r30_8", "pr1_pru0_pru_r31_8", "gpio2_26"),
_PIN(0x0f4, "MMC0_DAT2", 91, 7, "mmc0_dat2", "gpmc_a21", "uart4_rtsn", "timer6", "uart1_dsrn", "pr1_pru0_pru_r30_9", "pr1_pru0_pru_r31_9", "gpio2_27"),
_PIN(0x0f8, "MMC0_DAT1", 92, 7, "mmc0_dat1", "gpmc_a22", "uart5_ctsn", "uart3_rxd", "uart1_dtrn", "pr1_pru0_pru_r30_10", "pr1_pru0_pru_r31_10", "gpio2_28"),
_PIN(0x0fc, "MMC0_DAT0", 93, 7, "mmc0_dat0", "gpmc_a23", "uart5_rtsn", "uart3_txd", "uart1_rin", "pr1_pru0_pru_r30_11", "pr1_pru0_pru_r31_11", "gpio2_29"),
_PIN(0x100, "MMC0_CLK", 94, 7, "mmc0_clk", "gpmc_a24", "uart3_ctsn", "uart2_rxd", "dcan1_tx", "pr1_pru0_pru_r30_12", "pr1_pru0_pru_r31_12", "gpio2_30"),
_PIN(0x104, "MMC0_CMD", 95, 7, "mmc0_cmd", "gpmc_a25", "uart3_rtsn", "uart2_txd", "dcan1_rx", "pr1_pru0_pru_r30_13", "pr1_pru0_pru_r31_13", "gpio2_31"),
_PIN(0x108, "MII1_COL", 96, 7, "gmii1_col", "rmii2_refclk", "spi1_sclk", "uart5_rxd", "mcasp1_axr2", "mmc2_dat3", "mcasp0_axr2", "gpio3_0"),
_PIN(0x10c, "MII1_CRS", 97, 7, "gmii1_crs", "rmii1_crs_dv", "spi1_d0", "I2C1_SDA", "mcasp1_aclkx", "uart5_ctsn", "uart2_rxd", "gpio3_1"),
_PIN(0x110, "MII1_RX_ER", 98, 7, "gmii1_rxerr", "rmii1_rxerr", "spi1_d1", "I2C1_SCL", "mcasp1_fsx", "uart5_rtsn", "uart2_txd", "gpio3_2"),
_PIN(0x114, "MII1_TX_EN", 99, 7, "gmii1_txen", "rmii1_txen", "rgmii1_tctl", "timer4", "mcasp1_axr0", "eQEP0_index", "mmc2_cmd", "gpio3_3"),
_PIN(0x118, "MII1_RX_DV", 100, 7, "gmii1_rxdv", "cd_memory_clk", "rgmii1_rctl", "uart5_txd", "mcasp1_aclkx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),
_PIN(0x11c, "MII1_TXD3", 16, 7, "gmii1_txd3", "dcan0_tx", "rgmii1_td3", "uart4_rxd", "mcasp1_fsx", "mmc2_dat1", "mcasp0_fsr", "gpio0_16"),
_PIN(0x120, "MII1_TXD2", 17, 7, "gmii1_txd2", "dcan0_rx", "rgmii1_td2", "uart4_txd", "mcasp1_axr0", "mmc2_dat2", "mcasp0_ahclkx", "gpio0_17"),
_PIN(0x124, "MII1_TXD1", 21, 7, "gmii1_txd1", "rmii1_txd1", "rgmii1_td1", "mcasp1_fsr", "mcasp1_axr1", "eQEP0A_in", "mmc1_cmd", "gpio0_21"),
_PIN(0x128, "MII1_TXD0", 28, 7, "gmii1_txd0", "rmii1_txd0", "rgmii1_td0", "mcasp1_axr2", "mcasp1_aclkr", "eQEP0B_in", "mmc1_clk", "gpio0_28"),
_PIN(0x12c, "MII1_TX_CLK", 105, 7, "gmii1_txclk", "uart2_rxd", "rgmii1_tclk", "mmc0_dat7", "mmc1_dat0", "uart1_dcdn", "mcasp0_aclkx", "gpio3_9"),
_PIN(0x130, "MII1_RX_CLK", 106, 7, "gmii1_rxclk", "uart2_txd", "rgmii1_rclk", "mmc0_dat6", "mmc1_dat1", "uart1_dsrn", "mcasp0_fsx", "gpio3_10"),
_PIN(0x134, "MII1_RXD3", 82, 7, "gmii1_rxd3", "uart3_rxd", "rgmii1_rd3", "mmc0_dat5", "mmc1_dat2", "uart1_dtrn", "mcasp0_axr0", "gpio2_18"),
_PIN(0x138, "MII1_RXD2", 83, 7, "gmii1_rxd2", "uart3_txd", "rgmii1_rd2", "mmc0_dat4", "mmc1_dat3", "uart1_rin", "mcasp0_axr1", "gpio2_19"),
_PIN(0x13c, "MII1_RXD1", 84, 7, "gmii1_rxd1", "rmii1_rxd1", "rgmii1_rd1", "mcasp1_axr3", "mcasp1_fsr", "eQEP0_strobe", "mmc2_clk", "gpio2_20"),
_PIN(0x140, "MII1_RXD0", 85, 7, "gmii1_rxd0", "rmii1_rxd0", "rgmii1_rd0", "mcasp1_ahclkx", "mcasp1_ahclkr", "mcasp1_aclkr", "mcasp0_axr3", "gpio2_21"),
_PIN(0x144, "RMII1_REF_CLK", 29, 7, "rmii1_refclk", "xdma_event_intr2", "spi1_cs0", "uart5_txd", "mcasp1_axr3", "mmc0_pow", "mcasp1_ahclkx", "gpio0_29"),
_PIN(0x148, "MDIO", 0, 7, "mdio_data", "timer6", "uart5_rxd", "uart3_ctsn", "mmc0_sdcd","mmc1_cmd", "mmc2_cmd","gpio0_0"),
_PIN(0x14c, "MDC", 1, 7, "mdio_clk", "timer5", "uart5_txd", "uart3_rtsn", "mmc0_sdwp", "mmc1_clk", "mmc2_clk", "gpio0_1"),
_PIN(0x150, "SPI0_SCLK", 2, 7, "spi0_sclk", "uart2_rxd", "I2C2_SDA", "ehrpwm0A", "pr1_uart0_cts_n", "pr1_edio_sof", "EMU2", "gpio0_2"),
_PIN(0x154, "SPI0_D0", 3, 7, "spi0_d0", "uart2_txd", "I2C2_SCL", "ehrpwm0B", "pr1_uart0_rts_n", "pr1_edio_latch_in", "EMU3", "gpio0_3"),
_PIN(0x158, "SPI0_D1", 4, 7, "spi0_d1", "mmc1_sdwp", "I2C1_SDA", "ehrpwm0_tripzone_input", "pr1_uart0_rxd", "pr1_edio_data_in0", "pr1_edio_data_out0", "gpio0_4"),
_PIN(0x15c, "SPI0_CS0", 5, 7, "spi0_cs0", "mmc2_sdwp", "I2C1_SCL", "ehrpwm0_synci", "pr1_uart0_txd", "pr1_edio_data_in1", "pr1_edio_data_out1", "gpio0_5"),
_PIN(0x160, "SPI0_CS1", 6, 7, "spi0_cs1", "uart3_rxd", "eCAP1_in_PWM1_out", "mcc0_pow", "xdm_event_intr2", "mmc0_sdcd", "EMU4", "gpio0_6"),
_PIN(0x164, "ECAP0_IN_PWM0_OUT",7, 7, "eCAP0_in_PWM0_out", "uart3_txd", "spi1_cs1", "pr1_ecap0_ecap_capin_apwm_o", "spi1_sclk", "mmc0_sdwp", "xdma_event_intr2", "gpio0_7"),
_PIN(0x168, "UART0_CTSn", 40, 7, "uart0_ctsn", "uart4_rxd", "dcan1_tx", "I2C1_SDA", "spi1_d0", "timer7", "pr1_edc_sync0_out", "gpio1_8"),
_PIN(0x16c, "UART0_RTSn", 41, 7, "uart0_rtsn", "uart4_txd", "dcan1_rx", "I2C1_SCL", "spi1_d1", "spi1_cs0", "pr1_edc_sync1_out", "gpio1_9"),
_PIN(0x170, "UART0_rxd", 42, 7, "uart0_rxd", "spi1_cs0", "dcan0_tx", "I2C2_SDA", "eCAP2_in_PWM2_out", "pr1_pru1_pru_r30_14", "pr1_pru1_pru_r31_14", "gpio1_10"),
_PIN(0x174, "UART0_txd", 43, 7, "uart0_txd", "spi1_cs1", "dcan0_rx", "I2C2_SCL", "eCAP1_in_PWM1_out", "pr1_pru1_pru_r30_15", "pr1_pru1_pru_r31_15", "gpio1_11"),
_PIN(0x178, "UART1_CTSn", 12, 7, "uart1_ctsn", "timer6_mux1", "dcan0_tx", "I2C2_SDA", "spi1_cs0", "pr1_uart0_cts_n", "pr1_edc_latch0_in", "gpio0_12"),
_PIN(0x17c, "UART1_RTSn", 13, 7, "uart1_rtsn", "timer5_mux1", "dcan0_rx", "I2C2_SCL", "spi1_cs1", "pr1_uart0_rts_n", "pr1_edc_latch1_in", "gpio0_13"),
_PIN(0x180, "UART1_RXD", 14, 7, "uart1_rxd", "mmc1_sdwp", "dcan1_tx", "I2C1_SDA", NULL, "pr1_uart0_rxd", "pr1_pru1_pru_r31_16", "gpio0_14"),
_PIN(0x184, "UART1_TXD", 15, 7, "uart1_txd", "mmc2_sdwp", "dcan1_rx", "I2C1_SCL", NULL, "pr1_uart0_txd", "pr1_pru0_pru_r31_16", "gpio0_15"),
_PIN(0x188, "I2C0_SDA", 101, 7, "I2C0_SDA", "timer4", "uart2_ctsn", "eCAP2_in_PWM2_out", NULL, NULL, NULL, "gpio3_5"),
_PIN(0x18c, "I2C0_SCL", 102, 7, "I2C0_SCL", "timer7", "uart2_rtsn", "eCAP1_in_PWM1_out", NULL, NULL, NULL, "gpio3_6"),
_PIN(0x190, "MCASP0_ACLKX", 110, 7, "mcasp0_aclkx", "ehrpwm0A", NULL, "spi1_sclk", "mmc0_sdcd", "pr1_pru0_pru_r30_0", "pr1_pru0_pru_r31_0", "gpio3_14"),
_PIN(0x194, "MCASP0_FSX", 111, 7, "mcasp0_fsx", "ehrpwm0B", NULL, "spi1_d0", "mmc1_sdcd", "pr1_pru0_pru_r30_1", "pr1_pru0_pru_r31_1", "gpio3_15"),
_PIN(0x198, "MCASP0_AXR0", 112, 7, "mcasp0_axr0", "ehrpwm0_tripzone_input", NULL, "spi1_d1", "mmc2_sdcd", "pr1_pru0_pru_r30_2", "pr1_pru0_pru_r31_2", "gpio3_16"),
_PIN(0x19c, "MCASP0_AHCLKR", 113, 7, "mcasp0_ahclkr", "ehrpwm0_synci", "mcasp0_axr2", "spi1_cs0", "eCAP2_in_PWM2_out", "pr1_pru0_pru_r30_3", "pr1_pru0_pru_r31_3", "gpio3_17"),
_PIN(0x1a0, "MCASP0_ACLKR", 114, 7, "mcasp0_aclkr", "eQEP0A_in", "mcasp0_axr2", "mcasp1_aclkx", "mmc0_sdwp", "pr1_pru0_pru_r30_4", "pr1_pru0_pru_r31_4", "gpio3_18"),
_PIN(0x1a4, "MCASP0_FSR", 115, 7, "mcasp0_fsr", "eQEP0B_in", "mcasp0_axr3", "mcasp1_fsx", "EMU2", "pr1_pru0_pru_r30_5", "pr1_pru0_pru_r31_5", "gpio3_19"),
_PIN(0x1a8, "MCASP0_AXR1", 116, 7, "mcasp0_axr1", "eQEP0_index", NULL, "mcasp1_axr0", "EMU3", "pr1_pru0_pru_r30_6", "pr1_pru0_pru_r31_6", "gpio3_20"),
_PIN(0x1ac, "MCASP0_AHCLKX", 117, 7, "mcasp0_ahclkx", "eQEP0_strobe", "mcasp0_axr3", "mcasp1_axr1", "EMU4", "pr1_pru0_pru_r30_7", "pr1_pru0_pru_r31_7", "gpio3_21"),
_PIN(0x1b0, "XDMA_EVENT_INTR0", 19, 7, "xdma_event_intr0", NULL, "timer4", "clkout1", "spi1_cs1", "pr1_pru1_pru_r31_16", "EMU2", "gpio0_19"),
_PIN(0x1b4, "XDMA_EVENT_INTR1", 20, 7, "xdma_event_intr1", NULL, "tclkin", "clkout2", "timer7", "pr1_pru0_pru_r31_16", "EMU3", "gpio0_20"),
#if 0
_PIN(0x9b8, "nresetin_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9bc, "porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c0, "nnmi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c4, "osc0_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9c8, "osc0_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9cc, "osc0_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d0, "tms", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d4, "tdi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9d8, "tdo", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9dc, "tck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9e0, "ntrst", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1b8, "nresetin_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1bc, "porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1c0, "nnmi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1c4, "osc0_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1c8, "osc0_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1cc, "osc0_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1d0, "tms", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1d4, "tdi", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1d8, "tdo", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1dc, "tck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1e0, "ntrst", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0x9e4, "EMU0", 103, 7, "EMU0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_7"),
_PIN(0x9e8, "EMU1", 104, 0, "EMU1", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_8"),
_PIN(0x1e4, "EMU0", 103, 7, "EMU0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_7"),
_PIN(0x1e8, "EMU1", 104, 0, "EMU1", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_8"),
#if 0
_PIN(0x9ec, "osc1_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f0, "osc1_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f4, "osc1_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9f8, "rtc_porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x9fc, "pmic_power_en", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa00, "ext_wakeup", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa04, "enz_kaldo_1p8v", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1ec, "osc1_in", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1f0, "osc1_out", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1f4, "osc1_vss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1f8, "rtc_porz", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x1fc, "pmic_power_en", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x200, "ext_wakeup", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x204, "enz_kaldo_1p8v", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
_PIN(0xa08, "USB0_DM", 0, 0, "USB0_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa0c, "USB0_DP", 0, 0, "USB0_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa10, "USB0_CE", 0, 0, "USB0_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa14, "USB0_ID", 0, 0, "USB0_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa18, "USB0_VBUS", 0, 0, "USB0_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa1c, "USB0_DRVVBUS", 18, 7, "USB0_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio0_18"),
_PIN(0xa20, "USB1_DM", 0, 0, "USB1_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa24, "USB1_DP", 0, 0, "USB1_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa28, "USB1_CE", 0, 0, "USB1_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa2c, "USB1_ID", 0, 0, "USB1_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa30, "USB1_VBUS", 0, 0, "USB1_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa34, "USB1_DRVVBUS", 109, 7, "USB1_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_13"),
_PIN(0x208, "USB0_DM", 0, 0, "USB0_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x20c, "USB0_DP", 0, 0, "USB0_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x210, "USB0_CE", 0, 0, "USB0_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x214, "USB0_ID", 0, 0, "USB0_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x218, "USB0_VBUS", 0, 0, "USB0_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x21c, "USB0_DRVVBUS", 18, 7, "USB0_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio0_18"),
_PIN(0x220, "USB1_DM", 0, 0, "USB1_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x224, "USB1_DP", 0, 0, "USB1_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x228, "USB1_CE", 0, 0, "USB1_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x22c, "USB1_ID", 0, 0, "USB1_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x230, "USB1_VBUS", 0, 0, "USB1_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x234, "USB1_DRVVBUS", 109, 7, "USB1_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_13"),
#if 0
_PIN(0xa38, "ddr_resetn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa3c, "ddr_csn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa40, "ddr_cke", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa44, "ddr_ck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa48, "ddr_nck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa4c, "ddr_casn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa50, "ddr_rasn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa54, "ddr_wen", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa58, "ddr_ba0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa5c, "ddr_ba1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa60, "ddr_ba2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa64, "ddr_a0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa68, "ddr_a1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa6c, "ddr_a2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa70, "ddr_a3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa74, "ddr_a4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa78, "ddr_a5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa7c, "ddr_a6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa80, "ddr_a7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa84, "ddr_a8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa88, "ddr_a9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa8c, "ddr_a10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa90, "ddr_a11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa94, "ddr_a12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa98, "ddr_a13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xa9c, "ddr_a14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa0, "ddr_a15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa4, "ddr_odt", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaa8, "ddr_d0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaac, "ddr_d1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab0, "ddr_d2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab4, "ddr_d3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xab8, "ddr_d4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xabc, "ddr_d5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac0, "ddr_d6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac4, "ddr_d7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xac8, "ddr_d8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xacc, "ddr_d9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad0, "ddr_d10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad4, "ddr_d11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xad8, "ddr_d12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xadc, "ddr_d13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae0, "ddr_d14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae4, "ddr_d15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xae8, "ddr_dqm0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaec, "ddr_dqm1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf0, "ddr_dqs0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf4, "ddr_dqsn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xaf8, "ddr_dqs1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xafc, "ddr_dqsn1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb00, "ddr_vref", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb04, "ddr_vtp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb08, "ddr_strben0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb0c, "ddr_strben1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb2c, "ain0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb28, "ain1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb24, "ain2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb20, "ain3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb1c, "ain4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb18, "ain5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb14, "ain6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb10, "ain7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb30, "vrefp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb34, "vrefn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb38, "avdd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb3c, "avss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb40, "iforce", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb44, "vsense", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0xb48, "testout", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x238, "ddr_resetn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x23c, "ddr_csn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x240, "ddr_cke", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x244, "ddr_ck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x248, "ddr_nck", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x24c, "ddr_casn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x250, "ddr_rasn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x254, "ddr_wen", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x258, "ddr_ba0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x25c, "ddr_ba1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x260, "ddr_ba2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x264, "ddr_a0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x268, "ddr_a1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x26c, "ddr_a2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x270, "ddr_a3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x274, "ddr_a4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x278, "ddr_a5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x27c, "ddr_a6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x280, "ddr_a7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x284, "ddr_a8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x288, "ddr_a9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x28c, "ddr_a10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x290, "ddr_a11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x294, "ddr_a12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x298, "ddr_a13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x29c, "ddr_a14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2a0, "ddr_a15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2a4, "ddr_odt", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2a8, "ddr_d0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2ac, "ddr_d1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2b0, "ddr_d2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2b4, "ddr_d3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2b8, "ddr_d4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2bc, "ddr_d5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2c0, "ddr_d6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2c4, "ddr_d7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2c8, "ddr_d8", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2cc, "ddr_d9", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2d0, "ddr_d10", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2d4, "ddr_d11", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2d8, "ddr_d12", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2dc, "ddr_d13", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2e0, "ddr_d14", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2e4, "ddr_d15", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2e8, "ddr_dqm0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2ec, "ddr_dqm1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2f0, "ddr_dqs0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2f4, "ddr_dqsn0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2f8, "ddr_dqs1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x2fc, "ddr_dqsn1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x300, "ddr_vref", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x304, "ddr_vtp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x308, "ddr_strben0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x30c, "ddr_strben1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x32c, "ain0", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x328, "ain1", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x324, "ain2", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x320, "ain3", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x31c, "ain4", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x318, "ain5", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x314, "ain6", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x310, "ain7", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x330, "vrefp", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x334, "vrefn", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x338, "avdd", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x33c, "avss", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x340, "iforce", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x344, "vsense", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PIN(0x348, "testout", 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
#endif
{ .ballname = NULL },
};
const struct ti_scm_device ti_scm_dev = {
const struct ti_pinmux_device ti_pinmux_dev = {
.padconf_muxmode_mask = 0x7,
.padconf_sate_mask = 0x78,
.padstate = ti_padstate_devmap,

View File

@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/priv.h>
#include <dev/fdt/fdt_common.h>
#include <dev/fdt/simplebus.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@ -58,8 +59,6 @@ __FBSDID("$FreeBSD$");
#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>
@ -97,164 +96,29 @@ __FBSDID("$FreeBSD$");
#define USBCTRL_MODE_IDDIG (1 << 8)
#define USBCTRL_MODE_IDDIGMUX (1 << 7)
/* USBSS resource + 2 MUSB ports */
#define RES_USBSS 0
#define RES_USBCTRL(i) (3*i+1)
#define RES_USBPHY(i) (3*i+2)
#define RES_USBCORE(i) (3*i+3)
#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 USBSS_WRITE4(sc, reg, val) \
USB_WRITE4((sc), RES_USBSS, (reg), (val))
bus_write_4((sc)->sc_mem_res, (reg), (val))
#define USBSS_READ4(sc, reg) \
USB_READ4((sc), RES_USBSS, (reg))
#define USBCTRL_WRITE4(sc, unit, reg, val) \
USB_WRITE4((sc), RES_USBCTRL(unit), (reg), (val))
#define USBCTRL_READ4(sc, unit, reg) \
USB_READ4((sc), RES_USBCTRL(unit), (reg))
#define USBPHY_WRITE4(sc, unit, reg, val) \
USB_WRITE4((sc), RES_USBPHY(unit), (reg), (val))
#define USBPHY_READ4(sc, unit, reg) \
USB_READ4((sc), RES_USBPHY(unit), (reg))
bus_read_4((sc)->sc_mem_res, (reg))
static struct resource_spec am335x_musbotg_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE },
{ SYS_RES_MEMORY, 2, RF_ACTIVE },
{ SYS_RES_MEMORY, 3, RF_ACTIVE },
{ SYS_RES_MEMORY, 4, RF_ACTIVE },
{ SYS_RES_MEMORY, 5, RF_ACTIVE },
{ SYS_RES_MEMORY, 6, RF_ACTIVE },
{ -1, 0, 0 }
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 struct resource_spec am335x_musbotg_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, 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[AM335X_USB_PORTS];
struct resource *sc_mem_res[AM335X_USB_PORTS*3+1];
struct resource *sc_irq_res[AM335X_USB_PORTS+1];
void *sc_intr_hdl;
};
static void
musbotg_vbus_poll(struct musbotg_super_softc *sc, int port)
{
uint32_t stat;
if (sc->sc_otg[port].sc_mode == MUSB2_DEVICE_MODE)
musbotg_vbus_interrupt(&sc->sc_otg[port], 1);
else {
stat = USBCTRL_READ4(sc, port, USBCTRL_STAT);
musbotg_vbus_interrupt(&sc->sc_otg[port], 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)
{
uint32_t c, reg = *(uint32_t *)arg;
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)
{
uint32_t c, reg = *(uint32_t *)arg;
/* 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, sc->sc_id,
USBCTRL_INTEN_SET0, epmask);
else
USBCTRL_WRITE4(ssc, sc->sc_id,
USBCTRL_INTEN_CLR0, epmask);
}
static void
musbotg_usbss_interrupt(void *arg)
{
panic("USBSS real interrupt");
}
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, sc->sc_id, USBCTRL_STAT);
stat0 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0);
stat1 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT1);
if (stat0)
USBCTRL_WRITE4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0, stat0);
if (stat1)
USBCTRL_WRITE4(ssc, sc->sc_id, 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)
usbss_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,musb-am33xx"))
if (!ofw_bus_is_compatible(dev, "ti,am33xx-usb"))
return (ENXIO);
device_set_desc(dev, "TI AM33xx integrated USB OTG controller");
@ -263,31 +127,22 @@ musbotg_probe(device_t dev)
}
static int
musbotg_attach(device_t dev)
usbss_attach(device_t dev)
{
struct musbotg_super_softc *sc = device_get_softc(dev);
int err;
struct usbss_softc *sc = device_get_softc(dev);
int i;
uint32_t rev, reg;
uint32_t rev;
phandle_t node;
/* Request the memory resources */
err = bus_alloc_resources(dev, am335x_musbotg_mem_spec,
sc->sc_mem_res);
if (err) {
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);
}
/* Request the IRQ resources */
err = bus_alloc_resources(dev, am335x_musbotg_irq_spec,
sc->sc_irq_res);
if (err) {
device_printf(dev,
"Error: could not allocate irq resources\n");
return (ENXIO);
}
/* Enable device clocks. */
ti_prcm_clk_enable(MUSB0_CLK);
@ -312,170 +167,50 @@ musbotg_attach(device_t dev)
device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n",
(rev >> 8) & 7, (rev >> 6) & 3, rev & 63);
err = bus_setup_intr(dev, sc->sc_irq_res[0],
INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)musbotg_usbss_interrupt, sc,
&sc->sc_intr_hdl);
if (err) {
sc->sc_intr_hdl = NULL;
device_printf(dev, "Failed to setup USBSS interrupt\n");
goto error;
node = ofw_bus_get_node(dev);
if (node == -1) {
usbss_detach(dev);
return (ENXIO);
}
for (i = 0; i < AM335X_USB_PORTS; i++) {
/* setup MUSB OTG USB controller interface softc */
sc->sc_otg[i].sc_clocks_on = &musbotg_clocks_on;
sc->sc_otg[i].sc_clocks_off = &musbotg_clocks_off;
sc->sc_otg[i].sc_clocks_arg = &USB_CTRL[i];
simplebus_init(dev, node);
sc->sc_otg[i].sc_ep_int_set = musbotg_ep_int_set;
/*
* Allow devices to identify.
*/
bus_generic_probe(dev);
/* initialise some bus fields */
sc->sc_otg[i].sc_bus.parent = dev;
sc->sc_otg[i].sc_bus.devices = sc->sc_otg[i].sc_devices;
sc->sc_otg[i].sc_bus.devices_max = MUSB2_MAX_DEVICES;
sc->sc_otg[i].sc_bus.dma_bits = 32;
/*
* 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);
/* get all DMA memory */
if (usb_bus_mem_alloc_all(&sc->sc_otg[i].sc_bus,
USB_GET_DMA_TAG(dev), NULL)) {
device_printf(dev,
"Failed allocate bus mem for musb%d\n", i);
return (ENOMEM);
}
sc->sc_otg[i].sc_io_res = sc->sc_mem_res[RES_USBCORE(i)];
sc->sc_otg[i].sc_io_tag =
rman_get_bustag(sc->sc_otg[i].sc_io_res);
sc->sc_otg[i].sc_io_hdl =
rman_get_bushandle(sc->sc_otg[i].sc_io_res);
sc->sc_otg[i].sc_io_size =
rman_get_size(sc->sc_otg[i].sc_io_res);
sc->sc_otg[i].sc_irq_res = sc->sc_irq_res[i+1];
sc->sc_otg[i].sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_otg[i].sc_bus.bdev)) {
device_printf(dev, "No busdev for musb%d\n", i);
goto error;
}
device_set_ivars(sc->sc_otg[i].sc_bus.bdev,
&sc->sc_otg[i].sc_bus);
err = bus_setup_intr(dev, sc->sc_otg[i].sc_irq_res,
INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)musbotg_wrapper_interrupt,
&sc->sc_otg[i], &sc->sc_otg[i].sc_intr_hdl);
if (err) {
sc->sc_otg[i].sc_intr_hdl = NULL;
device_printf(dev,
"Failed to setup interrupt for musb%d\n", i);
goto error;
}
sc->sc_otg[i].sc_id = i;
sc->sc_otg[i].sc_platform_data = sc;
if (i == 0)
sc->sc_otg[i].sc_mode = MUSB2_DEVICE_MODE;
else
sc->sc_otg[i].sc_mode = MUSB2_HOST_MODE;
/*
* software-controlled function
*/
if (sc->sc_otg[i].sc_mode == MUSB2_HOST_MODE) {
reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
reg |= USBCTRL_MODE_IDDIGMUX;
reg &= ~USBCTRL_MODE_IDDIG;
USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
USBCTRL_WRITE4(sc, i, USBCTRL_UTMI,
USBCTRL_UTMI_FSDATAEXT);
} else {
reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
reg |= USBCTRL_MODE_IDDIGMUX;
reg |= USBCTRL_MODE_IDDIG;
USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
}
reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF;
USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_SET1, reg);
USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_CLR0, 0xffffffff);
err = musbotg_init(&sc->sc_otg[i]);
if (!err)
err = device_probe_and_attach(sc->sc_otg[i].sc_bus.bdev);
if (err)
goto error;
/* poll VBUS one time */
musbotg_vbus_poll(sc, i);
}
return (0);
error:
musbotg_detach(dev);
return (ENXIO);
return (bus_generic_attach(dev));
}
static int
musbotg_detach(device_t dev)
usbss_detach(device_t dev)
{
struct musbotg_super_softc *sc = device_get_softc(dev);
device_t bdev;
int err;
int i;
for (i = 0; i < AM335X_USB_PORTS; i++) {
if (sc->sc_otg[i].sc_bus.bdev) {
bdev = sc->sc_otg[i].sc_bus.bdev;
device_detach(bdev);
device_delete_child(dev, bdev);
}
if (sc->sc_otg[i].sc_irq_res && sc->sc_otg[i].sc_intr_hdl) {
/*
* only call musbotg_uninit() after musbotg_init()
*/
musbotg_uninit(&sc->sc_otg[i]);
err = bus_teardown_intr(dev, sc->sc_otg[i].sc_irq_res,
sc->sc_otg[i].sc_intr_hdl);
sc->sc_otg[i].sc_intr_hdl = NULL;
}
usb_bus_mem_free_all(&sc->sc_otg[i].sc_bus, NULL);
}
if (sc->sc_intr_hdl) {
bus_teardown_intr(dev, sc->sc_irq_res[0],
sc->sc_intr_hdl);
sc->sc_intr_hdl = NULL;
}
struct usbss_softc *sc = device_get_softc(dev);
/* Free resources if any */
if (sc->sc_mem_res[0])
bus_release_resources(dev, am335x_musbotg_mem_spec,
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
sc->sc_mem_res);
if (sc->sc_irq_res[0])
bus_release_resources(dev, am335x_musbotg_irq_spec,
sc->sc_irq_res);
/* during module unload there are lots of children leftover */
device_delete_children(dev);
return (0);
}
static device_method_t musbotg_methods[] = {
static device_method_t usbss_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, musbotg_probe),
DEVMETHOD(device_attach, musbotg_attach),
DEVMETHOD(device_detach, musbotg_detach),
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),
@ -483,13 +218,8 @@ static device_method_t musbotg_methods[] = {
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, simplebus, musbotg_driver, musbotg_devclass, 0, 0);
MODULE_DEPEND(musbotg, usb, 1, 1, 1);
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);

View File

@ -8,10 +8,13 @@ arm/ti/am335x/am335x_lcd.c optional sc | vt
arm/ti/am335x/am335x_lcd_syscons.c optional sc
arm/ti/am335x/am335x_pmic.c optional am335x_pmic
arm/ti/am335x/am335x_prcm.c standard
arm/ti/am335x/am335x_pwm.c standard
arm/ti/am335x/am335x_pwmss.c standard
arm/ti/am335x/am335x_ehrpwm.c standard
arm/ti/am335x/am335x_ecap.c standard
arm/ti/am335x/am335x_rtc.c optional am335x_rtc
arm/ti/am335x/am335x_scm_padconf.c standard
arm/ti/am335x/am335x_usbss.c optional musb fdt
arm/ti/am335x/am335x_musb.c optional musb fdt
arm/ti/ti_edma3.c standard
arm/ti/cpsw/if_cpsw.c optional cpsw

View File

@ -195,8 +195,7 @@ DRIVER_MODULE(miibus, cpsw, miibus_driver, miibus_devclass, 0, 0);
MODULE_DEPEND(cpsw, ether, 1, 1, 1);
MODULE_DEPEND(cpsw, miibus, 1, 1, 1);
static struct resource_spec res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
static struct resource_spec irq_res_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
{ SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE },
{ SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE },
@ -322,21 +321,21 @@ cpsw_debugf(const char *fmt, ...)
/*
* Read/Write macros
*/
#define cpsw_read_4(sc, reg) bus_read_4(sc->res[0], reg)
#define cpsw_write_4(sc, reg, val) bus_write_4(sc->res[0], reg, val)
#define cpsw_read_4(sc, reg) bus_read_4(sc->mem_res, reg)
#define cpsw_write_4(sc, reg, val) bus_write_4(sc->mem_res, reg, val)
#define cpsw_cpdma_bd_offset(i) (CPSW_CPPI_RAM_OFFSET + ((i)*16))
#define cpsw_cpdma_bd_paddr(sc, slot) \
BUS_SPACE_PHYSADDR(sc->res[0], slot->bd_offset)
BUS_SPACE_PHYSADDR(sc->mem_res, slot->bd_offset)
#define cpsw_cpdma_read_bd(sc, slot, val) \
bus_read_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4)
bus_read_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
#define cpsw_cpdma_write_bd(sc, slot, val) \
bus_write_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4)
bus_write_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
#define cpsw_cpdma_write_bd_next(sc, slot, next_slot) \
cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot))
#define cpsw_cpdma_read_bd_flags(sc, slot) \
bus_read_2(sc->res[0], slot->bd_offset + 14)
bus_read_2(sc->mem_res, slot->bd_offset + 14)
#define cpsw_write_hdp_slot(sc, queue, slot) \
cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot))
#define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0))
@ -549,9 +548,12 @@ cpsw_attach(device_t dev)
struct cpsw_softc *sc = device_get_softc(dev);
struct mii_softc *miisc;
struct ifnet *ifp;
void *phy_sc;
int error, phy, nsegs;
int phy, nsegs, error;
uint32_t reg;
pcell_t phy_id[3];
u_long mem_base, mem_size;
phandle_t child;
int len;
CPSW_DEBUGF((""));
@ -559,21 +561,58 @@ cpsw_attach(device_t dev)
sc->dev = dev;
sc->node = ofw_bus_get_node(dev);
/* Get phy address from fdt */
if (fdt_get_phyaddr(sc->node, sc->dev, &phy, &phy_sc) != 0) {
/* TODO: handle multiple slaves */
phy = -1;
/* Find any slave with phy_id */
for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) {
len = OF_getproplen(child, "phy_id");
if (len <= 0)
continue;
/* Get phy address from fdt */
if (OF_getencprop(child, "phy_id", phy_id, len) <= 0)
continue;
phy = phy_id[1];
/* TODO: get memory window for MDIO */
break;
}
if (phy == -1) {
device_printf(dev, "failed to get PHY address from FDT\n");
return (ENXIO);
}
mem_base = 0;
mem_size = 0;
if (fdt_regsize(sc->node, &mem_base, &mem_size) != 0) {
device_printf(sc->dev, "no regs property in cpsw node\n");
return (ENXIO);
}
/* Initialize mutexes */
mtx_init(&sc->tx.lock, device_get_nameunit(dev),
"cpsw TX lock", MTX_DEF);
mtx_init(&sc->rx.lock, device_get_nameunit(dev),
"cpsw RX lock", MTX_DEF);
/* Allocate IO and IRQ resources */
error = bus_alloc_resources(dev, res_spec, sc->res);
/* Allocate IRQ resources */
error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res);
if (error) {
device_printf(dev, "could not allocate resources\n");
device_printf(dev, "could not allocate IRQ resources\n");
cpsw_detach(dev);
return (ENXIO);
}
sc->mem_rid = 0;
sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&sc->mem_rid, mem_base, mem_base + CPSW_MEMWINDOW_SIZE -1,
CPSW_MEMWINDOW_SIZE, RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(sc->dev, "failed to allocate memory resource\n");
cpsw_detach(dev);
return (ENXIO);
}
@ -690,11 +729,11 @@ cpsw_attach(device_t dev)
cpsw_write_4(sc, MDIOUSERPHYSEL0, 1 << 6 | (miisc->mii_phy & 0x1F));
/* Note: We don't use sc->res[3] (TX interrupt) */
if (cpsw_attach_interrupt(sc, sc->res[1],
if (cpsw_attach_interrupt(sc, sc->irq_res[0],
cpsw_intr_rx_thresh, "CPSW RX threshold interrupt") ||
cpsw_attach_interrupt(sc, sc->res[2],
cpsw_attach_interrupt(sc, sc->irq_res[1],
cpsw_intr_rx, "CPSW RX interrupt") ||
cpsw_attach_interrupt(sc, sc->res[4],
cpsw_attach_interrupt(sc, sc->irq_res[3],
cpsw_intr_misc, "CPSW misc interrupt")) {
cpsw_detach(dev);
return (ENXIO);
@ -761,7 +800,8 @@ cpsw_detach(device_t dev)
KASSERT(error == 0, ("Unable to destroy DMA tag"));
/* Free IO memory handler */
bus_release_resources(dev, res_spec, sc->res);
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res);
bus_release_resources(dev, irq_res_spec, sc->irq_res);
if (sc->ifp != NULL)
if_free(sc->ifp);

View File

@ -118,6 +118,8 @@
#define CPSW_CPPI_RAM_OFFSET 0x2000
#define CPSW_CPPI_RAM_SIZE 0x2000
#define CPSW_MEMWINDOW_SIZE 0x4000
#define CPDMA_BD_SOP (1<<15)
#define CPDMA_BD_EOP (1<<14)
#define CPDMA_BD_OWNER (1<<13)

View File

@ -78,7 +78,9 @@ struct cpsw_softc {
device_t miibus;
struct mii_data *mii;
/* We expect 1 memory resource and 4 interrupts from the device tree. */
struct resource *res[1 + CPSW_INTR_COUNT];
struct resource *mem_res;
int mem_rid;
struct resource *irq_res[CPSW_INTR_COUNT];
/* Interrupts get recorded here as we initialize them. */
/* Interrupt teardown just walks this list. */

View File

@ -9,9 +9,11 @@ arm/arm/pmu.c optional hwpmc
arm/ti/ti_common.c standard
arm/ti/ti_cpuid.c standard
arm/ti/ti_hwmods.c standard
arm/ti/ti_machdep.c standard
arm/ti/ti_prcm.c standard
arm/ti/ti_scm.c standard
arm/ti/ti_pinmux.c standard
dev/mbox/mbox_if.m optional ti_mbox
arm/ti/ti_mbox.c optional ti_mbox
arm/ti/ti_pruss.c optional ti_pruss

View File

@ -4,6 +4,8 @@ arm/arm/mpcore_timer.c standard
arm/ti/ti_smc.S standard
arm/ti/usb/omap_ehci.c optional usb ehci
arm/ti/usb/omap_host.c optional usb
arm/ti/usb/omap_tll.c optional usb
arm/ti/ti_sdma.c optional ti_sdma
arm/ti/omap4/omap4_gpio.c optional gpio

View File

@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_pinmux.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
@ -77,6 +77,9 @@ static int
omap4_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
struct ti_gpio_softc *sc;
sc = device_get_softc(dev);
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
@ -88,16 +91,19 @@ omap4_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
return ti_pinmux_padconf_set_gpiomode((sc->sc_bank-1)*32 + gpio, state);
}
static int
omap4_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
struct ti_gpio_softc *sc;
sc = device_get_softc(dev);
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
if (ti_pinmux_padconf_get_gpiomode((sc->sc_bank-1)*32 + gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {

View File

@ -93,17 +93,9 @@ __FBSDID("$FreeBSD$");
#define FREQ_48MHZ 48000000
#define FREQ_32KHZ 32000
/**
* We need three memory regions to cover all the clock configuration registers.
*
* PRM Instance - 0x4A30 6000 : 0x4A30 8000
* CM1 Instance - 0x4A00 4000 : 0x4A00 5000
* CM2 Instance - 0x4A00 8000 : 0x4A00 A000
*
*/
#define PRM_INSTANCE_MEM_REGION 0
#define CM1_INSTANCE_MEM_REGION 1
#define CM2_INSTANCE_MEM_REGION 2
#define PRM_INSTANCE 1
#define CM1_INSTANCE 2
#define CM2_INSTANCE 3
/**
* Address offsets from the PRM memory region to the top level clock control
@ -174,19 +166,19 @@ __FBSDID("$FreeBSD$");
#define CLKCTRL_IDLEST_IDLE 0x00020000UL
#define CLKCTRL_IDLEST_DISABLED 0x00030000UL
static struct resource_spec omap4_scm_res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */
{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* Control memory window */
{ SYS_RES_MEMORY, 2, RF_ACTIVE }, /* Control memory window */
{ -1, 0 }
static struct ofw_compat_data compat_data[] = {
{"ti,omap4-cm1", (uintptr_t)CM1_INSTANCE},
{"ti,omap4-cm2", (uintptr_t)CM2_INSTANCE},
{"ti,omap4-prm", (uintptr_t)PRM_INSTANCE},
{NULL, (uintptr_t)0},
};
struct omap4_prcm_softc {
struct resource *sc_res[3];
struct resource *sc_res;
int sc_rid;
int sc_instance;
};
static struct omap4_prcm_softc *omap4_prcm_sc;
static int omap4_clk_generic_activate(struct ti_clock_dev *clkdev);
static int omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev);
static int omap4_clk_generic_accessible(struct ti_clock_dev *clkdev);
@ -283,17 +275,17 @@ struct ti_clock_dev ti_omap4_clk_devmap[] = {
OMAP4_GENERIC_CLOCK_DEV(UART4_CLK),
/* Timer device source clocks */
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER1_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER2_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER3_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER4_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER5_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER6_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER7_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER8_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER9_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER10_CLK),
OMAP4_GPTIMER_CLOCK_DEV(GPTIMER11_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER1_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER2_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER3_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER4_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER5_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER6_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER7_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER8_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER9_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER10_CLK),
OMAP4_GPTIMER_CLOCK_DEV(TIMER11_CLK),
/* MMC device clocks (MMC1 and MMC2 can have different input clocks) */
OMAP4_HSMMC_CLOCK_DEV(MMC1_CLK),
@ -344,7 +336,7 @@ struct ti_clock_dev ti_omap4_clk_devmap[] = {
struct omap4_clk_details {
clk_ident_t id;
uint32_t mem_region;
uint32_t instance;
uint32_t clksel_reg;
int32_t src_freq;
@ -352,9 +344,9 @@ struct omap4_clk_details {
uint32_t enable_mode;
};
#define OMAP4_GENERIC_CLOCK_DETAILS(i, f, m, r, e) \
#define OMAP4_GENERIC_CLOCK_DETAILS(i, f, di, r, e) \
{ .id = (i), \
.mem_region = (m), \
.instance = (di), \
.clksel_reg = (r), \
.src_freq = (f), \
.enable_mode = (e), \
@ -363,77 +355,77 @@ struct omap4_clk_details {
static struct omap4_clk_details g_omap4_clk_details[] = {
/* UART */
OMAP4_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(UART4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(UART4_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
/* General purpose timers */
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER1_CLK, -1, PRM_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER1_CLK, -1, PRM_INSTANCE,
(WKUP_CM_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER2_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER2_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x038), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER3_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER3_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER4_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER4_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x048), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER5_CLK, -1, CM1_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER5_CLK, -1, CM1_INSTANCE,
(ABE_CM1_OFFSET + 0x068), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER6_CLK, -1, CM1_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER6_CLK, -1, CM1_INSTANCE,
(ABE_CM1_OFFSET + 0x070), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER7_CLK, -1, CM1_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER7_CLK, -1, CM1_INSTANCE,
(ABE_CM1_OFFSET + 0x078), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER8_CLK, -1, CM1_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER8_CLK, -1, CM1_INSTANCE,
(ABE_CM1_OFFSET + 0x080), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER9_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER9_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x050), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER10_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER10_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x028), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER11_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(TIMER11_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x030), CLKCTRL_MODULEMODE_ENABLE),
/* HSMMC (MMC1 and MMC2 can have different input clocks) */
OMAP4_GENERIC_CLOCK_DETAILS(MMC1_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(MMC1_CLK, -1, CM2_INSTANCE,
(L3INIT_CM2_OFFSET + 0x028), /*CLKCTRL_MODULEMODE_ENABLE*/2),
OMAP4_GENERIC_CLOCK_DETAILS(MMC2_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(MMC2_CLK, -1, CM2_INSTANCE,
(L3INIT_CM2_OFFSET + 0x030), /*CLKCTRL_MODULEMODE_ENABLE*/2),
OMAP4_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x120), /*CLKCTRL_MODULEMODE_ENABLE*/2),
OMAP4_GENERIC_CLOCK_DETAILS(MMC4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(MMC4_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x128), /*CLKCTRL_MODULEMODE_ENABLE*/2),
OMAP4_GENERIC_CLOCK_DETAILS(MMC5_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(MMC5_CLK, FREQ_48MHZ, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x160), /*CLKCTRL_MODULEMODE_ENABLE*/1),
/* GPIO modules */
OMAP4_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, PRM_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, PRM_INSTANCE,
(WKUP_CM_OFFSET + 0x038), CLKCTRL_MODULEMODE_AUTO),
OMAP4_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x060), CLKCTRL_MODULEMODE_AUTO),
OMAP4_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x068), CLKCTRL_MODULEMODE_AUTO),
OMAP4_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x070), CLKCTRL_MODULEMODE_AUTO),
OMAP4_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x078), CLKCTRL_MODULEMODE_AUTO),
OMAP4_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x080), CLKCTRL_MODULEMODE_AUTO),
/* sDMA block */
OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE,
(CORE_CM2_OFFSET + 0x300), CLKCTRL_MODULEMODE_AUTO),
/* I2C modules */
OMAP4_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0A0), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0A8), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0B0), CLKCTRL_MODULEMODE_ENABLE),
OMAP4_GENERIC_CLOCK_DETAILS(I2C4_CLK, -1, CM2_INSTANCE_MEM_REGION,
OMAP4_GENERIC_CLOCK_DETAILS(I2C4_CLK, -1, CM2_INSTANCE,
(L4PER_CM2_OFFSET + 0x0B8), CLKCTRL_MODULEMODE_ENABLE),
{ INVALID_CLK_IDENT, 0, 0, 0, 0 },
@ -474,6 +466,27 @@ omap4_clk_details(clk_ident_t id)
return NULL;
}
static struct omap4_prcm_softc *
omap4_prcm_get_instance_softc(int module_instance)
{
int i, maxunit;
devclass_t prcm_devclass;
device_t dev;
struct omap4_prcm_softc *sc;
prcm_devclass = devclass_find("omap4_prcm");
maxunit = devclass_get_maxunit(prcm_devclass);
for (i = 0; i < maxunit; i++) {
dev = devclass_get_device(prcm_devclass, i);
sc = device_get_softc(dev);
if (sc->sc_instance == module_instance)
return (sc);
}
return (NULL);
}
/**
* omap4_clk_generic_activate - checks if a module is accessible
@ -492,21 +505,21 @@ omap4_clk_details(clk_ident_t id)
static int
omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
unsigned int i;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -558,20 +571,21 @@ omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
static int
omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -626,20 +640,21 @@ omap4_clk_generic_set_source(struct ti_clock_dev *clkdev,
static int
omap4_clk_generic_accessible(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -703,19 +718,20 @@ static int
omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev,
clk_src_t clksrc)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -744,21 +760,22 @@ omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev,
unsigned int *freq
)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
unsigned int src_freq;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -793,20 +810,22 @@ static int
omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev,
clk_src_t clksrc)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -852,21 +871,22 @@ omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,
unsigned int *freq
)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct omap4_clk_details* clk_details;
struct resource* clk_mem_res;
uint32_t clksel;
unsigned int src_freq;
if (sc == NULL)
return ENXIO;
clk_details = omap4_clk_details(clkdev->id);
if (clk_details == NULL)
return (ENXIO);
clk_mem_res = sc->sc_res[clk_details->mem_region];
sc = omap4_prcm_get_instance_softc(clk_details->instance);
if (sc == NULL)
return ENXIO;
clk_mem_res = sc->sc_res;
if (clk_mem_res == NULL)
return (EINVAL);
@ -913,13 +933,14 @@ omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev,
{
uint32_t clksel;
uint32_t sysclk;
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
sc = omap4_prcm_get_instance_softc(PRM_INSTANCE);
if (sc == NULL)
return ENXIO;
/* Read the input clock freq from the configuration register (CM_SYS_CLKSEL) */
clksel = bus_read_4(sc->sc_res[PRM_INSTANCE_MEM_REGION], CM_SYS_CLKSEL_OFFSET);
clksel = bus_read_4(sc->sc_res, CM_SYS_CLKSEL_OFFSET);
switch (clksel & 0x7) {
case 0x1:
/* 12Mhz */
@ -971,15 +992,16 @@ omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev,
uint32_t clksel;
uint32_t pll_mult, pll_div;
uint32_t mpuclk, sysclk;
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
sc = omap4_prcm_get_instance_softc(CM1_INSTANCE);
if (sc == NULL)
return ENXIO;
/* Read the clksel register which contains the DPLL multiple and divide
* values. These are applied to the sysclk.
*/
clksel = bus_read_4(sc->sc_res[CM1_INSTANCE_MEM_REGION], CM_CLKSEL_DPLL_MPU);
clksel = bus_read_4(sc->sc_res, CM_CLKSEL_DPLL_MPU);
pll_mult = ((clksel >> 8) & 0x7ff);
pll_div = (clksel & 0x7f) + 1;
@ -1050,12 +1072,13 @@ struct dpll_param usb_dpll_param[7] = {
static int
omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct resource* clk_mem_res;
uint32_t clksel_reg_off;
uint32_t clksel;
unsigned int i;
sc = omap4_prcm_get_instance_softc(CM2_INSTANCE);
if (sc == NULL)
return ENXIO;
@ -1068,7 +1091,7 @@ omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
*/
/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
/* Enable the module and also enable the optional func clocks for
@ -1103,7 +1126,7 @@ omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
*/
/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
clksel = bus_read_4(clk_mem_res, clksel_reg_off);
/* Enable the module and also enable the optional func clocks */
@ -1165,18 +1188,19 @@ omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
static int
omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct resource* clk_mem_res;
uint32_t clksel_reg_off;
uint32_t clksel;
sc = omap4_prcm_get_instance_softc(CM2_INSTANCE);
if (sc == NULL)
return ENXIO;
switch (clkdev->id) {
case USBTLL_CLK:
/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
clksel = bus_read_4(clk_mem_res, clksel_reg_off);
@ -1205,7 +1229,7 @@ omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
*/
/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
clksel = bus_read_4(clk_mem_res, clksel_reg_off);
@ -1255,22 +1279,23 @@ omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
static int
omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct resource* clk_mem_res;
uint32_t clksel_reg_off;
uint32_t clksel;
sc = omap4_prcm_get_instance_softc(CM2_INSTANCE);
if (sc == NULL)
return ENXIO;
if (clkdev->id == USBTLL_CLK) {
/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
}
else if (clkdev->id == USBHSHOST_CLK) {
/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
}
else {
@ -1304,12 +1329,13 @@ static int
omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
clk_src_t clksrc)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
struct omap4_prcm_softc *sc;
struct resource* clk_mem_res;
uint32_t clksel_reg_off;
uint32_t clksel;
unsigned int bit;
sc = omap4_prcm_get_instance_softc(CM2_INSTANCE);
if (sc == NULL)
return ENXIO;
@ -1321,7 +1347,7 @@ omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
return (EINVAL);
/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
clk_mem_res = sc->sc_res;
clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
clksel = bus_read_4(clk_mem_res, clksel_reg_off);
@ -1342,10 +1368,15 @@ omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
static void
omap4_prcm_reset(void)
{
struct omap4_prcm_softc *sc = omap4_prcm_sc;
bus_write_4(sc->sc_res[0], PRM_RSTCTRL,
bus_read_4(sc->sc_res[0], PRM_RSTCTRL) | PRM_RSTCTRL_RESET);
bus_read_4(sc->sc_res[0], PRM_RSTCTRL);
struct omap4_prcm_softc *sc;
sc = omap4_prcm_get_instance_softc(PRM_INSTANCE);
if (sc == NULL)
return;
bus_write_4(sc->sc_res, PRM_RSTCTRL,
bus_read_4(sc->sc_res, PRM_RSTCTRL) | PRM_RSTCTRL_RESET);
bus_read_4(sc->sc_res, PRM_RSTCTRL);
}
/**
@ -1363,15 +1394,31 @@ omap4_prcm_reset(void)
static int
omap4_prcm_probe(device_t dev)
{
const struct ofw_compat_data *ocd;
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,omap4_prcm"))
ocd = ofw_bus_search_compatible(dev, compat_data);
if ((int)ocd->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "TI OMAP Power, Reset and Clock Management");
return (0);
switch ((int)ocd->ocd_data) {
case PRM_INSTANCE:
device_set_desc(dev, "TI OMAP Power, Reset and Clock Management (PRM)");
break;
case CM1_INSTANCE:
device_set_desc(dev, "TI OMAP Power, Reset and Clock Management (C1)");
break;
case CM2_INSTANCE:
device_set_desc(dev, "TI OMAP Power, Reset and Clock Management (C2)");
break;
default:
device_printf(dev, "unknown instance type: %d\n", (int)ocd->ocd_data);
return (ENXIO);
}
return (BUS_PROBE_DEFAULT);
}
/**
@ -1393,18 +1440,33 @@ extern uint32_t platform_arm_tmr_freq;
static int
omap4_prcm_attach(device_t dev)
{
struct omap4_prcm_softc *sc = device_get_softc(dev);
struct omap4_prcm_softc *sc;
unsigned int freq;
const struct ofw_compat_data *ocd;
if (bus_alloc_resources(dev, omap4_scm_res_spec, sc->sc_res)) {
sc = device_get_softc(dev);
ocd = ofw_bus_search_compatible(dev, compat_data);
sc->sc_instance = (int)ocd->ocd_data;
sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
RF_ACTIVE);
if (sc->sc_res == NULL) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
omap4_prcm_sc = sc;
ti_cpu_reset = omap4_prcm_reset;
omap4_clk_get_arm_fclk_freq(NULL, &freq);
arm_tmr_change_frequency(freq / 2);
/*
* In order to determine ARM frequency we need both RPM and CM1
* instances up and running. So wait until all CRM devices are
* initialized. Should be replaced with proper clock framework
*/
if (device_get_unit(dev) == 2) {
omap4_clk_get_arm_fclk_freq(NULL, &freq);
arm_tmr_change_frequency(freq / 2);
}
return (0);
}

View File

@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_pinmux.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
.muxmodes[7] = m7, \
}
const static struct ti_scm_padstate ti_padstate_devmap[] = {
const static struct ti_pinmux_padstate ti_padstate_devmap[] = {
{"output", PADCONF_PIN_OUTPUT},
{"input", PADCONF_PIN_INPUT},
{"input_pullup", PADCONF_PIN_INPUT_PULLUP},
@ -88,214 +88,214 @@ const static struct ti_scm_padstate ti_padstate_devmap[] = {
/*
* Table 18-10, p. 3470
*/
const static struct ti_scm_padconf ti_padconf_devmap[] = {
_PINDEF(0x0040, "c12", 0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0042, "d12", 0, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0044, "c13", 0, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0046, "d13", 0, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0048, "c15", 0, 0, "gpmc_ad4", "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004a, "d15", 0, 0, "gpmc_ad5", "sdmmc2_dat5", "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004c, "a16", 0, 0, "gpmc_ad6", "sdmmc2_dat6", "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x004e, "b16", 0, 0, "gpmc_ad7", "sdmmc2_dat7", "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0050, "c16", 32, 3, "gpmc_ad8", "kpd_row0", "c2c_data15", "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
_PINDEF(0x0052, "d16", 33, 3, "gpmc_ad9", "kpd_row1", "c2c_data14", "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
_PINDEF(0x0054, "c17", 34, 3, "gpmc_ad10", "kpd_row2", "c2c_data13", "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
_PINDEF(0x0056, "d17", 35, 3, "gpmc_ad11", "kpd_row3", "c2c_data12", "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
_PINDEF(0x0058, "c18", 36, 3, "gpmc_ad12", "kpd_col0", "c2c_data11", "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
_PINDEF(0x005a, "d18", 37, 3, "gpmc_ad13", "kpd_col1", "c2c_data10", "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
_PINDEF(0x005c, "c19", 38, 3, "gpmc_ad14", "kpd_col2", "c2c_data9", "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
_PINDEF(0x005e, "d19", 39, 3, "gpmc_ad15", "kpd_col3", "c2c_data8", "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
_PINDEF(0x0060, "b17", 40, 3, "gpmc_a16", "kpd_row4", "c2c_datain0", "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
_PINDEF(0x0062, "a18", 41, 3, "gpmc_a17", "kpd_row5", "c2c_datain1", "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
_PINDEF(0x0064, "b18", 42, 3, "gpmc_a18", "kpd_row6", "c2c_datain2", "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
_PINDEF(0x0066, "a19", 43, 3, "gpmc_a19", "kpd_row7", "c2c_datain3", "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
_PINDEF(0x0068, "b19", 44, 3, "gpmc_a20", "kpd_col4", "c2c_datain4", "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
_PINDEF(0x006a, "b20", 45, 3, "gpmc_a21", "kpd_col5", "c2c_datain5", "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
_PINDEF(0x006c, "a21", 46, 3, "gpmc_a22", "kpd_col6", "c2c_datain6", "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
_PINDEF(0x006e, "b21", 47, 3, "gpmc_a23", "kpd_col7", "c2c_datain7", "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
_PINDEF(0x0070, "c20", 48, 3, "gpmc_a24", "kpd_col8", "c2c_clkout0", "gpio_48", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0072, "d20", 49, 3, "gpmc_a25", NULL, "c2c_clkout1", "gpio_49", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0074, "b25", 50, 3, "gpmc_ncs0", NULL, NULL, "gpio_50", "sys_ndmareq0", NULL, NULL, NULL),
_PINDEF(0x0076, "c21", 51, 3, "gpmc_ncs1", NULL, "c2c_dataout6", "gpio_51", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0078, "d21", 52, 3, "gpmc_ncs2", "kpd_row8", "c2c_dataout7", "gpio_52", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007a, "c22", 53, 3, "gpmc_ncs3", "gpmc_dir", "c2c_dataout4", "gpio_53", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007c, "c25", 54, 3, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54", "sys_ndmareq1", NULL, NULL, NULL),
_PINDEF(0x007e, "b22", 55, 3, "gpmc_clk", NULL, NULL, "gpio_55", "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
_PINDEF(0x0080, "d25", 56, 3, "gpmc_nadv_ale", "dsi1_te1", NULL, "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
_PINDEF(0x0082, "b11", 0, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0084, "b12", 0, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0086, "c23", 59, 3, "gpmc_nbe0_cle", "dsi2_te0", NULL, "gpio_59", NULL, NULL, NULL, NULL),
_PINDEF(0x0088, "d22", 60, 3, "gpmc_nbe1", NULL, "c2c_dataout5", "gpio_60", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x008a, "b26", 61, 3, "gpmc_wait0", "dsi2_te1", NULL, "gpio_61", NULL, NULL, NULL, NULL),
_PINDEF(0x008c, "b23", 62, 3, "gpmc_wait1", NULL, "c2c_dataout2", "gpio_62", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x008e, "d23", 100, 3, "gpmc_wait2", "usbc1_icusb_txen", "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL, NULL, "safe_mode"),
_PINDEF(0x0090, "a24", 101, 3, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
_PINDEF(0x0092, "b24", 102, 3, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
_PINDEF(0x0094, "c24", 103, 3, "gpmc_ncs6", "dsi2_te0", "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL, NULL, "safe_mode"),
_PINDEF(0x0096, "d24", 104, 3, "gpmc_ncs7", "dsi2_te1", "c2c_dataout1", "gpio_104", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0098, "b9", 63, 3, "hdmi_hpd", NULL, NULL, "gpio_63", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009a, "b10", 64, 3, "hdmi_cec", NULL, NULL, "gpio_64", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009c, "a8", 65, 3, "hdmi_ddc_scl", NULL, NULL, "gpio_65", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009e, "b8", 66, 3, "hdmi_ddc_sda", NULL, NULL, "gpio_66", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a0, "r26", 0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a2, "r25", 0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a4, "t26", 0, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a6, "t25", 0, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a8, "u26", 0, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00aa, "u25", 0, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ac, "v26", 0, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ae, "v25", 0, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b0, "w26", 0, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b2, "w25", 0, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b4, "m26", 0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b6, "m25", 0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b8, "n26", 0, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ba, "n25", 0, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00bc, "t27", 81, 3, "cam_shutter", NULL, NULL, "gpio_81", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00be, "u27", 82, 3, "cam_strobe", NULL, NULL, "gpio_82", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c0, "v27", 83, 3, "cam_globalreset", NULL, NULL, "gpio_83", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c2, "ae18", 84, 3, "usbb1_ulpitll_clk", "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk", NULL, "hw_dbg20", "safe_mode"),
_PINDEF(0x00c4, "ag19", 85, 3, "usbb1_ulpitll_stp", "hsi1_cadata", "mcbsp4_clkr", "gpio_85", "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21", "safe_mode"),
_PINDEF(0x00c6, "af19", 86, 3, "usbb1_ulpitll_dir", "hsi1_caflag", "mcbsp4_fsr", "gpio_86", "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
_PINDEF(0x00c8, "ae19", 87, 3, "usbb1_ulpitll_nxt", "hsi1_acready", "mcbsp4_fsx", "gpio_87", "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23", "safe_mode"),
_PINDEF(0x00ca, "af18", 88, 3, "usbb1_ulpitll_dat0", "hsi1_acwake", "mcbsp4_clkx", "gpio_88", "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24", "safe_mode"),
_PINDEF(0x00cc, "ag18", 89, 3, "usbb1_ulpitll_dat1", "hsi1_acdata", "mcbsp4_dx", "gpio_89", "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25", "safe_mode"),
_PINDEF(0x00ce, "ae17", 90, 3, "usbb1_ulpitll_dat2", "hsi1_acflag", "mcbsp4_dr", "gpio_90", "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26", "safe_mode"),
_PINDEF(0x00d0, "af17", 91, 3, "usbb1_ulpitll_dat3", "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3", "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
_PINDEF(0x00d2, "ah17", 92, 3, "usbb1_ulpitll_dat4", "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92", "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
_PINDEF(0x00d4, "ae16", 93, 3, "usbb1_ulpitll_dat5", "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93", "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
_PINDEF(0x00d6, "af16", 94, 3, "usbb1_ulpitll_dat6", "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94", "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30", "safe_mode"),
_PINDEF(0x00d8, "ag16", 95, 3, "usbb1_ulpitll_dat7", "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95", "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31", "safe_mode"),
_PINDEF(0x00da, "af14", 96, 3, "usbb1_hsic_data", NULL, NULL, "gpio_96", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00dc, "ae14", 97, 3, "usbb1_hsic_strobe", NULL, NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00de, "h2", 98, 3, "usbc1_icusb_dp", NULL, NULL, "gpio_98", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e0, "h3", 99, 3, "usbc1_icusb_dm", NULL, NULL, "gpio_99", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e2, "d2", 100, 3, "sdmmc1_clk", NULL, "dpm_emu19", "gpio_100", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e4, "e3", 101, 3, "sdmmc1_cmd", NULL, "uart1_rx", "gpio_101", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e6, "e4", 102, 3, "sdmmc1_dat0", NULL, "dpm_emu18", "gpio_102", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e8, "e2", 103, 3, "sdmmc1_dat1", NULL, "dpm_emu17", "gpio_103", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ea, "e1", 104, 3, "sdmmc1_dat2", NULL, "dpm_emu16", "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
_PINDEF(0x00ec, "f4", 105, 3, "sdmmc1_dat3", NULL, "dpm_emu15", "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
_PINDEF(0x00ee, "f3", 106, 3, "sdmmc1_dat4", NULL, NULL, "gpio_106", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f0, "f1", 107, 3, "sdmmc1_dat5", NULL, NULL, "gpio_107", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f2, "g4", 108, 3, "sdmmc1_dat6", NULL, NULL, "gpio_108", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f4, "g3", 109, 3, "sdmmc1_dat7", NULL, NULL, "gpio_109", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f6, "ad27", 110, 3, "abe_mcbsp2_clkx", "mcspi2_clk", "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm", NULL, NULL, "safe_mode"),
_PINDEF(0x00f8, "ad26", 111, 3, "abe_mcbsp2_dr", "mcspi2_somi", "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL, NULL, "safe_mode"),
_PINDEF(0x00fa, "ad25", 112, 3, "abe_mcbsp2_dx", "mcspi2_simo", "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL, NULL, "safe_mode"),
_PINDEF(0x00fc, "ac28", 113, 3, "abe_mcbsp2_fsx", "mcspi2_cs0", "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL, NULL, "safe_mode"),
_PINDEF(0x00fe, "ac26", 114, 3, "abe_mcbsp1_clkx", "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0100, "ac25", 115, 3, "abe_mcbsp1_dr", "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0102, "ab25", 116, 3, "abe_mcbsp1_dx", "sdmmc3_dat2", "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0104, "ac27", 117, 3, "abe_mcbsp1_fsx", "sdmmc3_dat3", "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0106, "ag25", 0, 0, "abe_pdm_ul_data", "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0108, "af25", 0, 0, "abe_pdm_dl_data", "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010a, "ae25", 0, 0, "abe_pdm_frame", "abe_mcbsp3_clkx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010c, "af26", 0, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x010e, "ah26", 118, 3, "abe_clks", NULL, NULL, "gpio_118", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0110, "ae24", 119, 3, "abe_dmic_clk1", NULL, NULL, "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL, "safe_mode"),
_PINDEF(0x0112, "af24", 120, 3, "abe_dmic_din1", NULL, NULL, "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL, "safe_mode"),
_PINDEF(0x0114, "ag24", 121, 3, "abe_dmic_din2", "slimbus2_clock", "abe_mcasp_axr", "gpio_121", NULL, "dmtimer11_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x0116, "ah24", 122, 3, "abe_dmic_din3", "slimbus2_data", "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x0118, "ab26", 123, 3, "uart2_cts", "sdmmc3_clk", NULL, "gpio_123", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011a, "ab27", 124, 3, "uart2_rts", "sdmmc3_cmd", NULL, "gpio_124", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011c, "aa25", 125, 3, "uart2_rx", "sdmmc3_dat0", NULL, "gpio_125", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011e, "aa26", 126, 3, "uart2_tx", "sdmmc3_dat1", NULL, "gpio_126", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0120, "aa27", 127, 3, "hdq_sio", "i2c3_sccb", "i2c2_sccb", "gpio_127", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0122, "ae28", 0, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0124, "ae26", 0, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0126, "c26", 128, 3, "i2c2_scl", "uart1_rx", NULL, "gpio_128", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0128, "d26", 129, 3, "i2c2_sda", "uart1_tx", NULL, "gpio_129", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012a, "w27", 130, 3, "i2c3_scl", NULL, NULL, "gpio_130", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012c, "y27", 131, 3, "i2c3_sda", NULL, NULL, "gpio_131", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x012e, "ag21", 132, 3, "i2c4_scl", NULL, NULL, "gpio_132", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0130, "ah22", 133, 3, "i2c4_sda", NULL, NULL, "gpio_133", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0132, "af22", 134, 3, "mcspi1_clk", NULL, NULL, "gpio_134", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0134, "ae22", 135, 3, "mcspi1_somi", NULL, NULL, "gpio_135", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0136, "ag22", 136, 3, "mcspi1_simo", NULL, NULL, "gpio_136", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0138, "ae23", 137, 3, "mcspi1_cs0", NULL, NULL, "gpio_137", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013a, "af23", 138, 3, "mcspi1_cs1", "uart1_rx", NULL, "gpio_138", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013c, "ag23", 139, 3, "mcspi1_cs2", "uart1_cts", "slimbus2_clock", "gpio_139", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013e, "ah23", 140, 3, "mcspi1_cs3", "uart1_rts", "slimbus2_data", "gpio_140", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0140, "f27", 141, 3, "uart3_cts_rctx", "uart1_tx", NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0142, "f28", 142, 3, "uart3_rts_sd", NULL, NULL, "gpio_142", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0144, "g27", 143, 3, "uart3_rx_irrx", "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0146, "g28", 144, 3, "uart3_tx_irtx", "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0148, "ae5", 145, 3, "sdmmc5_clk", "mcspi2_clk", "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk", NULL, "safe_mode"),
_PINDEF(0x014a, "af5", 146, 3, "sdmmc5_cmd", "mcspi2_simo", "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd", NULL, "safe_mode"),
_PINDEF(0x014c, "ae4", 147, 3, "sdmmc5_dat0", "mcspi2_somi", "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0", NULL, "safe_mode"),
_PINDEF(0x014e, "af4", 148, 3, "sdmmc5_dat1", NULL, "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1", NULL, "safe_mode"),
_PINDEF(0x0150, "ag3", 149, 3, "sdmmc5_dat2", "mcspi2_cs1", NULL, "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
_PINDEF(0x0152, "af3", 150, 3, "sdmmc5_dat3", "mcspi2_cs0", NULL, "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
_PINDEF(0x0154, "ae21", 151, 3, "mcspi4_clk", "sdmmc4_clk", "kpd_col6", "gpio_151", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0156, "af20", 152, 3, "mcspi4_simo", "sdmmc4_cmd", "kpd_col7", "gpio_152", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0158, "af21", 153, 3, "mcspi4_somi", "sdmmc4_dat0", "kpd_row6", "gpio_153", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015a, "ae20", 154, 3, "mcspi4_cs0", "sdmmc4_dat3", "kpd_row7", "gpio_154", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015c, "ag20", 155, 3, "uart4_rx", "sdmmc4_dat2", "kpd_row8", "gpio_155", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015e, "ah19", 156, 3, "uart4_tx", "sdmmc4_dat1", "kpd_col8", "gpio_156", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0160, "ag12", 157, 3, "usbb2_ulpitll_clk", "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157", "hsi2_cawake", NULL, NULL, "safe_mode"),
_PINDEF(0x0162, "af12", 158, 3, "usbb2_ulpitll_stp", "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158", "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
_PINDEF(0x0164, "ae12", 159, 3, "usbb2_ulpitll_dir", "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159", "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
_PINDEF(0x0166, "ag13", 160, 3, "usbb2_ulpitll_nxt", "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160", "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
_PINDEF(0x0168, "ae11", 161, 3, "usbb2_ulpitll_dat0", "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161", "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen", "safe_mode"),
_PINDEF(0x016a, "af11", 162, 3, "usbb2_ulpitll_dat1", "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162", "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat", "safe_mode"),
_PINDEF(0x016c, "ag11", 163, 3, "usbb2_ulpitll_dat2", "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163", "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0", "safe_mode"),
_PINDEF(0x016e, "ah11", 164, 3, "usbb2_ulpitll_dat3", "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164", "hsi2_caready", "dispc2_data15", "rfbi_data15", "safe_mode"),
_PINDEF(0x0170, "ae10", 165, 3, "usbb2_ulpitll_dat4", "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165", "mcspi3_somi", "dispc2_data14", "rfbi_data14", "safe_mode"),
_PINDEF(0x0172, "af10", 166, 3, "usbb2_ulpitll_dat5", "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166", "mcspi3_cs0", "dispc2_data13", "rfbi_data13", "safe_mode"),
_PINDEF(0x0174, "ag10", 167, 3, "usbb2_ulpitll_dat6", "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167", "mcspi3_simo", "dispc2_data12", "rfbi_data12", "safe_mode"),
_PINDEF(0x0176, "ae9", 168, 3, "usbb2_ulpitll_dat7", "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168", "mcspi3_clk", "dispc2_data11", "rfbi_data11", "safe_mode"),
_PINDEF(0x0178, "af13", 169, 3, "usbb2_hsic_data", NULL, NULL, "gpio_169", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017a, "ae13", 170, 3, "usbb2_hsic_strobe", NULL, NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017c, "g26", 171, 3, "kpd_col3", "kpd_col0", NULL, "gpio_171", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x017e, "g25", 172, 3, "kpd_col4", "kpd_col1", NULL, "gpio_172", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0180, "h26", 173, 3, "kpd_col5", "kpd_col2", NULL, "gpio_173", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0182, "h25", 174, 3, "kpd_col0", "kpd_col3", NULL, "gpio_174", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0184, "j27", 0, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0186, "h27", 1, 3, "kpd_col2", "kpd_col5", NULL, "gpio_1", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0188, "j26", 175, 3, "kpd_row3", "kpd_row0", NULL, "gpio_175", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018a, "j25", 176, 3, "kpd_row4", "kpd_row1", NULL, "gpio_176", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018c, "k26", 177, 3, "kpd_row5", "kpd_row2", NULL, "gpio_177", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x018e, "k25", 178, 3, "kpd_row0", "kpd_row3", NULL, "gpio_178", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0190, "l27", 2, 3, "kpd_row1", "kpd_row4", NULL, "gpio_2", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0192, "k27", 3, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0194, "c3", 0, 0, "usba0_otg_ce", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0196, "b5", 0, 0, "usba0_otg_dp", "uart3_rx_irrx", "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0198, "b4", 0, 0, "usba0_otg_dm", "uart3_tx_irtx", "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019a, "aa28", 181, 3, "fref_clk1_out", NULL, NULL, "gpio_181", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019c, "y28", 182, 3, "fref_clk2_out", NULL, NULL, "gpio_182", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x019e, "ae6", 0, 0, "sys_nirq1", NULL, NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a0, "af6", 183, 3, "sys_nirq2", NULL, NULL, "gpio_183", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a2, "f26", 184, 3, "sys_boot0", NULL, NULL, "gpio_184", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a4, "e27", 185, 3, "sys_boot1", NULL, NULL, "gpio_185", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a6, "e26", 186, 3, "sys_boot2", NULL, NULL, "gpio_186", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01a8, "e25", 187, 3, "sys_boot3", NULL, NULL, "gpio_187", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01aa, "d28", 188, 3, "sys_boot4", NULL, NULL, "gpio_188", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01ac, "d27", 189, 3, "sys_boot5", NULL, NULL, "gpio_189", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x01ae, "m2", 11, 3, "dpm_emu0", NULL, NULL, "gpio_11", NULL, NULL, "hw_dbg0", "safe_mode"),
_PINDEF(0x01b0, "n2", 12, 3, "dpm_emu1", NULL, NULL, "gpio_12", NULL, NULL, "hw_dbg1", "safe_mode"),
_PINDEF(0x01b2, "p2", 13, 3, "dpm_emu2", "usba0_ulpiphy_clk", NULL, "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "safe_mode"),
_PINDEF(0x01b4, "v1", 14, 3, "dpm_emu3", "usba0_ulpiphy_stp", NULL, "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3", "safe_mode"),
_PINDEF(0x01b6, "v2", 15, 3, "dpm_emu4", "usba0_ulpiphy_dir", NULL, "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4", "safe_mode"),
_PINDEF(0x01b8, "w1", 16, 3, "dpm_emu5", "usba0_ulpiphy_nxt", NULL, "gpio_16", "rfbi_te_vsync0", "dispc2_data16", "hw_dbg5", "safe_mode"),
_PINDEF(0x01ba, "w2", 17, 3, "dpm_emu6", "usba0_ulpiphy_dat0", "uart3_tx_irtx", "gpio_17", "rfbi_hsync0", "dispc2_data17", "hw_dbg6", "safe_mode"),
_PINDEF(0x01bc, "w3", 18, 3, "dpm_emu7", "usba0_ulpiphy_dat1", "uart3_rx_irrx", "gpio_18", "rfbi_cs0", "dispc2_hsync", "hw_dbg7", "safe_mode"),
_PINDEF(0x01be, "w4", 19, 3, "dpm_emu8", "usba0_ulpiphy_dat2", "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk", "hw_dbg8", "safe_mode"),
_PINDEF(0x01c0, "y2", 20, 3, "dpm_emu9", "usba0_ulpiphy_dat3", "uart3_cts_rctx", "gpio_20", "rfbi_we", "dispc2_vsync", "hw_dbg9", "safe_mode"),
_PINDEF(0x01c2, "y3", 21, 3, "dpm_emu10", "usba0_ulpiphy_dat4", NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10", "safe_mode"),
_PINDEF(0x01c4, "y4", 22, 3, "dpm_emu11", "usba0_ulpiphy_dat5", NULL, "gpio_22", "rfbi_data8", "dispc2_data8", "hw_dbg11", "safe_mode"),
_PINDEF(0x01c6, "aa1", 23, 3, "dpm_emu12", "usba0_ulpiphy_dat6", NULL, "gpio_23", "rfbi_data7", "dispc2_data7", "hw_dbg12", "safe_mode"),
_PINDEF(0x01c8, "aa2", 24, 3, "dpm_emu13", "usba0_ulpiphy_dat7", NULL, "gpio_24", "rfbi_data6", "dispc2_data6", "hw_dbg13", "safe_mode"),
_PINDEF(0x01ca, "aa3", 25, 3, "dpm_emu14", "sys_drm_msecure", "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5", "hw_dbg14", "safe_mode"),
_PINDEF(0x01cc, "aa4", 26, 3, "dpm_emu15", "sys_secure_indicator", NULL, "gpio_26", "rfbi_data4", "dispc2_data4", "hw_dbg15", "safe_mode"),
_PINDEF(0x01ce, "ab2", 27, 3, "dpm_emu16", "dmtimer8_pwm_evt", "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3", "hw_dbg16", "safe_mode"),
_PINDEF(0x01d0, "ab3", 28, 3, "dpm_emu17", "dmtimer9_pwm_evt", "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2", "hw_dbg17", "safe_mode"),
_PINDEF(0x01d2, "ab4", 190, 3, "dpm_emu18", "dmtimer10_pwm_evt", "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1", "hw_dbg18", "safe_mode"),
_PINDEF(0x01d4, "ac4", 191, 3, "dpm_emu19", "dmtimer11_pwm_evt", "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0", "hw_dbg19", "safe_mode"),
const static struct ti_pinmux_padconf ti_padconf_devmap[] = {
_PINDEF(0x0000, "c12", 0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0002, "d12", 0, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0004, "c13", 0, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0006, "d13", 0, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0008, "c15", 0, 0, "gpmc_ad4", "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x000a, "d15", 0, 0, "gpmc_ad5", "sdmmc2_dat5", "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x000c, "a16", 0, 0, "gpmc_ad6", "sdmmc2_dat6", "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x000e, "b16", 0, 0, "gpmc_ad7", "sdmmc2_dat7", "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0010, "c16", 32, 3, "gpmc_ad8", "kpd_row0", "c2c_data15", "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
_PINDEF(0x0012, "d16", 33, 3, "gpmc_ad9", "kpd_row1", "c2c_data14", "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
_PINDEF(0x0014, "c17", 34, 3, "gpmc_ad10", "kpd_row2", "c2c_data13", "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
_PINDEF(0x0016, "d17", 35, 3, "gpmc_ad11", "kpd_row3", "c2c_data12", "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
_PINDEF(0x0018, "c18", 36, 3, "gpmc_ad12", "kpd_col0", "c2c_data11", "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
_PINDEF(0x001a, "d18", 37, 3, "gpmc_ad13", "kpd_col1", "c2c_data10", "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
_PINDEF(0x001c, "c19", 38, 3, "gpmc_ad14", "kpd_col2", "c2c_data9", "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
_PINDEF(0x001e, "d19", 39, 3, "gpmc_ad15", "kpd_col3", "c2c_data8", "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
_PINDEF(0x0020, "b17", 40, 3, "gpmc_a16", "kpd_row4", "c2c_datain0", "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
_PINDEF(0x0022, "a18", 41, 3, "gpmc_a17", "kpd_row5", "c2c_datain1", "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
_PINDEF(0x0024, "b18", 42, 3, "gpmc_a18", "kpd_row6", "c2c_datain2", "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
_PINDEF(0x0026, "a19", 43, 3, "gpmc_a19", "kpd_row7", "c2c_datain3", "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
_PINDEF(0x0028, "b19", 44, 3, "gpmc_a20", "kpd_col4", "c2c_datain4", "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
_PINDEF(0x002a, "b20", 45, 3, "gpmc_a21", "kpd_col5", "c2c_datain5", "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
_PINDEF(0x002c, "a21", 46, 3, "gpmc_a22", "kpd_col6", "c2c_datain6", "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
_PINDEF(0x002e, "b21", 47, 3, "gpmc_a23", "kpd_col7", "c2c_datain7", "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
_PINDEF(0x0030, "c20", 48, 3, "gpmc_a24", "kpd_col8", "c2c_clkout0", "gpio_48", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0032, "d20", 49, 3, "gpmc_a25", NULL, "c2c_clkout1", "gpio_49", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0034, "b25", 50, 3, "gpmc_ncs0", NULL, NULL, "gpio_50", "sys_ndmareq0", NULL, NULL, NULL),
_PINDEF(0x0036, "c21", 51, 3, "gpmc_ncs1", NULL, "c2c_dataout6", "gpio_51", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0038, "d21", 52, 3, "gpmc_ncs2", "kpd_row8", "c2c_dataout7", "gpio_52", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x003a, "c22", 53, 3, "gpmc_ncs3", "gpmc_dir", "c2c_dataout4", "gpio_53", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x003c, "c25", 54, 3, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54", "sys_ndmareq1", NULL, NULL, NULL),
_PINDEF(0x003e, "b22", 55, 3, "gpmc_clk", NULL, NULL, "gpio_55", "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
_PINDEF(0x0040, "d25", 56, 3, "gpmc_nadv_ale", "dsi1_te1", NULL, "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
_PINDEF(0x0042, "b11", 0, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0044, "b12", 0, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0046, "c23", 59, 3, "gpmc_nbe0_cle", "dsi2_te0", NULL, "gpio_59", NULL, NULL, NULL, NULL),
_PINDEF(0x0048, "d22", 60, 3, "gpmc_nbe1", NULL, "c2c_dataout5", "gpio_60", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x004a, "b26", 61, 3, "gpmc_wait0", "dsi2_te1", NULL, "gpio_61", NULL, NULL, NULL, NULL),
_PINDEF(0x004c, "b23", 62, 3, "gpmc_wait1", NULL, "c2c_dataout2", "gpio_62", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x004e, "d23", 100, 3, "gpmc_wait2", "usbc1_icusb_txen", "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL, NULL, "safe_mode"),
_PINDEF(0x0050, "a24", 101, 3, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
_PINDEF(0x0052, "b24", 102, 3, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
_PINDEF(0x0054, "c24", 103, 3, "gpmc_ncs6", "dsi2_te0", "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL, NULL, "safe_mode"),
_PINDEF(0x0056, "d24", 104, 3, "gpmc_ncs7", "dsi2_te1", "c2c_dataout1", "gpio_104", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0058, "b9", 63, 3, "hdmi_hpd", NULL, NULL, "gpio_63", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x005a, "b10", 64, 3, "hdmi_cec", NULL, NULL, "gpio_64", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x005c, "a8", 65, 3, "hdmi_ddc_scl", NULL, NULL, "gpio_65", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x005e, "b8", 66, 3, "hdmi_ddc_sda", NULL, NULL, "gpio_66", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0060, "r26", 0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0062, "r25", 0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0064, "t26", 0, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0066, "t25", 0, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0068, "u26", 0, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x006a, "u25", 0, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x006c, "v26", 0, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x006e, "v25", 0, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0070, "w26", 0, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0072, "w25", 0, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0074, "m26", 0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0076, "m25", 0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0078, "n26", 0, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007a, "n25", 0, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007c, "t27", 81, 3, "cam_shutter", NULL, NULL, "gpio_81", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x007e, "u27", 82, 3, "cam_strobe", NULL, NULL, "gpio_82", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0080, "v27", 83, 3, "cam_globalreset", NULL, NULL, "gpio_83", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0082, "ae18", 84, 3, "usbb1_ulpitll_clk", "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk", NULL, "hw_dbg20", "safe_mode"),
_PINDEF(0x0084, "ag19", 85, 3, "usbb1_ulpitll_stp", "hsi1_cadata", "mcbsp4_clkr", "gpio_85", "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21", "safe_mode"),
_PINDEF(0x0086, "af19", 86, 3, "usbb1_ulpitll_dir", "hsi1_caflag", "mcbsp4_fsr", "gpio_86", "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
_PINDEF(0x0088, "ae19", 87, 3, "usbb1_ulpitll_nxt", "hsi1_acready", "mcbsp4_fsx", "gpio_87", "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23", "safe_mode"),
_PINDEF(0x008a, "af18", 88, 3, "usbb1_ulpitll_dat0", "hsi1_acwake", "mcbsp4_clkx", "gpio_88", "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24", "safe_mode"),
_PINDEF(0x008c, "ag18", 89, 3, "usbb1_ulpitll_dat1", "hsi1_acdata", "mcbsp4_dx", "gpio_89", "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25", "safe_mode"),
_PINDEF(0x008e, "ae17", 90, 3, "usbb1_ulpitll_dat2", "hsi1_acflag", "mcbsp4_dr", "gpio_90", "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26", "safe_mode"),
_PINDEF(0x0090, "af17", 91, 3, "usbb1_ulpitll_dat3", "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3", "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
_PINDEF(0x0092, "ah17", 92, 3, "usbb1_ulpitll_dat4", "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92", "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
_PINDEF(0x0094, "ae16", 93, 3, "usbb1_ulpitll_dat5", "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93", "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
_PINDEF(0x0096, "af16", 94, 3, "usbb1_ulpitll_dat6", "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94", "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30", "safe_mode"),
_PINDEF(0x0098, "ag16", 95, 3, "usbb1_ulpitll_dat7", "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95", "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31", "safe_mode"),
_PINDEF(0x009a, "af14", 96, 3, "usbb1_hsic_data", NULL, NULL, "gpio_96", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009c, "ae14", 97, 3, "usbb1_hsic_strobe", NULL, NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x009e, "h2", 98, 3, "usbc1_icusb_dp", NULL, NULL, "gpio_98", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a0, "h3", 99, 3, "usbc1_icusb_dm", NULL, NULL, "gpio_99", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a2, "d2", 100, 3, "sdmmc1_clk", NULL, "dpm_emu19", "gpio_100", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a4, "e3", 101, 3, "sdmmc1_cmd", NULL, "uart1_rx", "gpio_101", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a6, "e4", 102, 3, "sdmmc1_dat0", NULL, "dpm_emu18", "gpio_102", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00a8, "e2", 103, 3, "sdmmc1_dat1", NULL, "dpm_emu17", "gpio_103", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00aa, "e1", 104, 3, "sdmmc1_dat2", NULL, "dpm_emu16", "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
_PINDEF(0x00ac, "f4", 105, 3, "sdmmc1_dat3", NULL, "dpm_emu15", "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
_PINDEF(0x00ae, "f3", 106, 3, "sdmmc1_dat4", NULL, NULL, "gpio_106", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b0, "f1", 107, 3, "sdmmc1_dat5", NULL, NULL, "gpio_107", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b2, "g4", 108, 3, "sdmmc1_dat6", NULL, NULL, "gpio_108", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b4, "g3", 109, 3, "sdmmc1_dat7", NULL, NULL, "gpio_109", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00b6, "ad27", 110, 3, "abe_mcbsp2_clkx", "mcspi2_clk", "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm", NULL, NULL, "safe_mode"),
_PINDEF(0x00b8, "ad26", 111, 3, "abe_mcbsp2_dr", "mcspi2_somi", "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL, NULL, "safe_mode"),
_PINDEF(0x00ba, "ad25", 112, 3, "abe_mcbsp2_dx", "mcspi2_simo", "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL, NULL, "safe_mode"),
_PINDEF(0x00bc, "ac28", 113, 3, "abe_mcbsp2_fsx", "mcspi2_cs0", "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL, NULL, "safe_mode"),
_PINDEF(0x00be, "ac26", 114, 3, "abe_mcbsp1_clkx", "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c0, "ac25", 115, 3, "abe_mcbsp1_dr", "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c2, "ab25", 116, 3, "abe_mcbsp1_dx", "sdmmc3_dat2", "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c4, "ac27", 117, 3, "abe_mcbsp1_fsx", "sdmmc3_dat3", "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c6, "ag25", 0, 0, "abe_pdm_ul_data", "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00c8, "af25", 0, 0, "abe_pdm_dl_data", "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ca, "ae25", 0, 0, "abe_pdm_frame", "abe_mcbsp3_clkx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00cc, "af26", 0, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ce, "ah26", 118, 3, "abe_clks", NULL, NULL, "gpio_118", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00d0, "ae24", 119, 3, "abe_dmic_clk1", NULL, NULL, "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL, "safe_mode"),
_PINDEF(0x00d2, "af24", 120, 3, "abe_dmic_din1", NULL, NULL, "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL, "safe_mode"),
_PINDEF(0x00d4, "ag24", 121, 3, "abe_dmic_din2", "slimbus2_clock", "abe_mcasp_axr", "gpio_121", NULL, "dmtimer11_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x00d6, "ah24", 122, 3, "abe_dmic_din3", "slimbus2_data", "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt", NULL, "safe_mode"),
_PINDEF(0x00d8, "ab26", 123, 3, "uart2_cts", "sdmmc3_clk", NULL, "gpio_123", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00da, "ab27", 124, 3, "uart2_rts", "sdmmc3_cmd", NULL, "gpio_124", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00dc, "aa25", 125, 3, "uart2_rx", "sdmmc3_dat0", NULL, "gpio_125", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00de, "aa26", 126, 3, "uart2_tx", "sdmmc3_dat1", NULL, "gpio_126", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e0, "aa27", 127, 3, "hdq_sio", "i2c3_sccb", "i2c2_sccb", "gpio_127", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e2, "ae28", 0, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x00e4, "ae26", 0, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x00e6, "c26", 128, 3, "i2c2_scl", "uart1_rx", NULL, "gpio_128", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00e8, "d26", 129, 3, "i2c2_sda", "uart1_tx", NULL, "gpio_129", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ea, "w27", 130, 3, "i2c3_scl", NULL, NULL, "gpio_130", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ec, "y27", 131, 3, "i2c3_sda", NULL, NULL, "gpio_131", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00ee, "ag21", 132, 3, "i2c4_scl", NULL, NULL, "gpio_132", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f0, "ah22", 133, 3, "i2c4_sda", NULL, NULL, "gpio_133", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f2, "af22", 134, 3, "mcspi1_clk", NULL, NULL, "gpio_134", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f4, "ae22", 135, 3, "mcspi1_somi", NULL, NULL, "gpio_135", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f6, "ag22", 136, 3, "mcspi1_simo", NULL, NULL, "gpio_136", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00f8, "ae23", 137, 3, "mcspi1_cs0", NULL, NULL, "gpio_137", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00fa, "af23", 138, 3, "mcspi1_cs1", "uart1_rx", NULL, "gpio_138", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00fc, "ag23", 139, 3, "mcspi1_cs2", "uart1_cts", "slimbus2_clock", "gpio_139", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x00fe, "ah23", 140, 3, "mcspi1_cs3", "uart1_rts", "slimbus2_data", "gpio_140", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0100, "f27", 141, 3, "uart3_cts_rctx", "uart1_tx", NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0102, "f28", 142, 3, "uart3_rts_sd", NULL, NULL, "gpio_142", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0104, "g27", 143, 3, "uart3_rx_irrx", "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0106, "g28", 144, 3, "uart3_tx_irtx", "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0108, "ae5", 145, 3, "sdmmc5_clk", "mcspi2_clk", "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk", NULL, "safe_mode"),
_PINDEF(0x010a, "af5", 146, 3, "sdmmc5_cmd", "mcspi2_simo", "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd", NULL, "safe_mode"),
_PINDEF(0x010c, "ae4", 147, 3, "sdmmc5_dat0", "mcspi2_somi", "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0", NULL, "safe_mode"),
_PINDEF(0x010e, "af4", 148, 3, "sdmmc5_dat1", NULL, "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1", NULL, "safe_mode"),
_PINDEF(0x0110, "ag3", 149, 3, "sdmmc5_dat2", "mcspi2_cs1", NULL, "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
_PINDEF(0x0112, "af3", 150, 3, "sdmmc5_dat3", "mcspi2_cs0", NULL, "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
_PINDEF(0x0114, "ae21", 151, 3, "mcspi4_clk", "sdmmc4_clk", "kpd_col6", "gpio_151", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0116, "af20", 152, 3, "mcspi4_simo", "sdmmc4_cmd", "kpd_col7", "gpio_152", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0118, "af21", 153, 3, "mcspi4_somi", "sdmmc4_dat0", "kpd_row6", "gpio_153", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011a, "ae20", 154, 3, "mcspi4_cs0", "sdmmc4_dat3", "kpd_row7", "gpio_154", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011c, "ag20", 155, 3, "uart4_rx", "sdmmc4_dat2", "kpd_row8", "gpio_155", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x011e, "ah19", 156, 3, "uart4_tx", "sdmmc4_dat1", "kpd_col8", "gpio_156", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0120, "ag12", 157, 3, "usbb2_ulpitll_clk", "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157", "hsi2_cawake", NULL, NULL, "safe_mode"),
_PINDEF(0x0122, "af12", 158, 3, "usbb2_ulpitll_stp", "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158", "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
_PINDEF(0x0124, "ae12", 159, 3, "usbb2_ulpitll_dir", "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159", "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
_PINDEF(0x0126, "ag13", 160, 3, "usbb2_ulpitll_nxt", "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160", "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
_PINDEF(0x0128, "ae11", 161, 3, "usbb2_ulpitll_dat0", "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161", "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen", "safe_mode"),
_PINDEF(0x012a, "af11", 162, 3, "usbb2_ulpitll_dat1", "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162", "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat", "safe_mode"),
_PINDEF(0x012c, "ag11", 163, 3, "usbb2_ulpitll_dat2", "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163", "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0", "safe_mode"),
_PINDEF(0x012e, "ah11", 164, 3, "usbb2_ulpitll_dat3", "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164", "hsi2_caready", "dispc2_data15", "rfbi_data15", "safe_mode"),
_PINDEF(0x0130, "ae10", 165, 3, "usbb2_ulpitll_dat4", "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165", "mcspi3_somi", "dispc2_data14", "rfbi_data14", "safe_mode"),
_PINDEF(0x0132, "af10", 166, 3, "usbb2_ulpitll_dat5", "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166", "mcspi3_cs0", "dispc2_data13", "rfbi_data13", "safe_mode"),
_PINDEF(0x0134, "ag10", 167, 3, "usbb2_ulpitll_dat6", "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167", "mcspi3_simo", "dispc2_data12", "rfbi_data12", "safe_mode"),
_PINDEF(0x0136, "ae9", 168, 3, "usbb2_ulpitll_dat7", "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168", "mcspi3_clk", "dispc2_data11", "rfbi_data11", "safe_mode"),
_PINDEF(0x0138, "af13", 169, 3, "usbb2_hsic_data", NULL, NULL, "gpio_169", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013a, "ae13", 170, 3, "usbb2_hsic_strobe", NULL, NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013c, "g26", 171, 3, "kpd_col3", "kpd_col0", NULL, "gpio_171", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x013e, "g25", 172, 3, "kpd_col4", "kpd_col1", NULL, "gpio_172", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0140, "h26", 173, 3, "kpd_col5", "kpd_col2", NULL, "gpio_173", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0142, "h25", 174, 3, "kpd_col0", "kpd_col3", NULL, "gpio_174", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0144, "j27", 0, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0146, "h27", 1, 3, "kpd_col2", "kpd_col5", NULL, "gpio_1", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0148, "j26", 175, 3, "kpd_row3", "kpd_row0", NULL, "gpio_175", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x014a, "j25", 176, 3, "kpd_row4", "kpd_row1", NULL, "gpio_176", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x014c, "k26", 177, 3, "kpd_row5", "kpd_row2", NULL, "gpio_177", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x014e, "k25", 178, 3, "kpd_row0", "kpd_row3", NULL, "gpio_178", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0150, "l27", 2, 3, "kpd_row1", "kpd_row4", NULL, "gpio_2", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0152, "k27", 3, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0154, "c3", 0, 0, "usba0_otg_ce", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
_PINDEF(0x0156, "b5", 0, 0, "usba0_otg_dp", "uart3_rx_irrx", "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0158, "b4", 0, 0, "usba0_otg_dm", "uart3_tx_irtx", "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015a, "aa28", 181, 3, "fref_clk1_out", NULL, NULL, "gpio_181", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015c, "y28", 182, 3, "fref_clk2_out", NULL, NULL, "gpio_182", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x015e, "ae6", 0, 0, "sys_nirq1", NULL, NULL, NULL, NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0160, "af6", 183, 3, "sys_nirq2", NULL, NULL, "gpio_183", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0162, "f26", 184, 3, "sys_boot0", NULL, NULL, "gpio_184", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0164, "e27", 185, 3, "sys_boot1", NULL, NULL, "gpio_185", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0166, "e26", 186, 3, "sys_boot2", NULL, NULL, "gpio_186", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x0168, "e25", 187, 3, "sys_boot3", NULL, NULL, "gpio_187", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x016a, "d28", 188, 3, "sys_boot4", NULL, NULL, "gpio_188", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x016c, "d27", 189, 3, "sys_boot5", NULL, NULL, "gpio_189", NULL, NULL, NULL, "safe_mode"),
_PINDEF(0x016e, "m2", 11, 3, "dpm_emu0", NULL, NULL, "gpio_11", NULL, NULL, "hw_dbg0", "safe_mode"),
_PINDEF(0x0170, "n2", 12, 3, "dpm_emu1", NULL, NULL, "gpio_12", NULL, NULL, "hw_dbg1", "safe_mode"),
_PINDEF(0x0172, "p2", 13, 3, "dpm_emu2", "usba0_ulpiphy_clk", NULL, "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "safe_mode"),
_PINDEF(0x0174, "v1", 14, 3, "dpm_emu3", "usba0_ulpiphy_stp", NULL, "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3", "safe_mode"),
_PINDEF(0x0176, "v2", 15, 3, "dpm_emu4", "usba0_ulpiphy_dir", NULL, "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4", "safe_mode"),
_PINDEF(0x0178, "w1", 16, 3, "dpm_emu5", "usba0_ulpiphy_nxt", NULL, "gpio_16", "rfbi_te_vsync0", "dispc2_data16", "hw_dbg5", "safe_mode"),
_PINDEF(0x017a, "w2", 17, 3, "dpm_emu6", "usba0_ulpiphy_dat0", "uart3_tx_irtx", "gpio_17", "rfbi_hsync0", "dispc2_data17", "hw_dbg6", "safe_mode"),
_PINDEF(0x017c, "w3", 18, 3, "dpm_emu7", "usba0_ulpiphy_dat1", "uart3_rx_irrx", "gpio_18", "rfbi_cs0", "dispc2_hsync", "hw_dbg7", "safe_mode"),
_PINDEF(0x017e, "w4", 19, 3, "dpm_emu8", "usba0_ulpiphy_dat2", "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk", "hw_dbg8", "safe_mode"),
_PINDEF(0x0180, "y2", 20, 3, "dpm_emu9", "usba0_ulpiphy_dat3", "uart3_cts_rctx", "gpio_20", "rfbi_we", "dispc2_vsync", "hw_dbg9", "safe_mode"),
_PINDEF(0x0182, "y3", 21, 3, "dpm_emu10", "usba0_ulpiphy_dat4", NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10", "safe_mode"),
_PINDEF(0x0184, "y4", 22, 3, "dpm_emu11", "usba0_ulpiphy_dat5", NULL, "gpio_22", "rfbi_data8", "dispc2_data8", "hw_dbg11", "safe_mode"),
_PINDEF(0x0186, "aa1", 23, 3, "dpm_emu12", "usba0_ulpiphy_dat6", NULL, "gpio_23", "rfbi_data7", "dispc2_data7", "hw_dbg12", "safe_mode"),
_PINDEF(0x0188, "aa2", 24, 3, "dpm_emu13", "usba0_ulpiphy_dat7", NULL, "gpio_24", "rfbi_data6", "dispc2_data6", "hw_dbg13", "safe_mode"),
_PINDEF(0x018a, "aa3", 25, 3, "dpm_emu14", "sys_drm_msecure", "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5", "hw_dbg14", "safe_mode"),
_PINDEF(0x018c, "aa4", 26, 3, "dpm_emu15", "sys_secure_indicator", NULL, "gpio_26", "rfbi_data4", "dispc2_data4", "hw_dbg15", "safe_mode"),
_PINDEF(0x018e, "ab2", 27, 3, "dpm_emu16", "dmtimer8_pwm_evt", "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3", "hw_dbg16", "safe_mode"),
_PINDEF(0x0190, "ab3", 28, 3, "dpm_emu17", "dmtimer9_pwm_evt", "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2", "hw_dbg17", "safe_mode"),
_PINDEF(0x0192, "ab4", 190, 3, "dpm_emu18", "dmtimer10_pwm_evt", "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1", "hw_dbg18", "safe_mode"),
_PINDEF(0x0194, "ac4", 191, 3, "dpm_emu19", "dmtimer11_pwm_evt", "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0", "hw_dbg19", "safe_mode"),
{ .ballname = NULL },
};
const struct ti_scm_device ti_scm_dev = {
const struct ti_pinmux_device ti_pinmux_dev = {
.padconf_muxmode_mask = CONTROL_PADCONF_MUXMODE_MASK,
.padconf_sate_mask = CONTROL_PADCONF_SATE_MASK,
.padstate = ti_padstate_devmap,

View File

@ -467,7 +467,7 @@ static int
ti_adc_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "ti,adc"))
if (!ofw_bus_is_compatible(dev, "ti,am3359-tscadc"))
return (ENXIO);
device_set_desc(dev, "TI ADC controller");

View File

@ -44,36 +44,21 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/vmparam.h>
struct fdt_fixup_entry fdt_fixup_table[] = {
{ NULL, NULL }
};
#ifdef SOC_OMAP4
static int
fdt_gic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
if (!fdt_is_compatible(node, "arm,gic"))
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]);
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
return (0);
}
#endif
#ifdef SOC_TI_AM335X
static int
fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
int *pol)
{
if (!fdt_is_compatible(node, "ti,aintc"))
if (!fdt_is_compatible(node, "ti,aintc") &&
!fdt_is_compatible(node, "ti,am33xx-intc"))
return (ENXIO);
*interrupt = fdt32_to_cpu(intr[0]);
@ -86,7 +71,7 @@ fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
fdt_pic_decode_t fdt_pic_table[] = {
#ifdef SOC_OMAP4
&fdt_gic_decode_ic,
&gic_decode_fdt,
#endif
#ifdef SOC_TI_AM335X
&fdt_aintc_decode_ic,

View File

@ -99,7 +99,11 @@ __FBSDID("$FreeBSD$");
struct ti_edma3_softc {
device_t sc_dev;
struct resource * mem_res[TI_EDMA3_NUM_TCS+1];
/*
* We use one-element array in case if we need to add
* mem resources for transfer control windows
*/
struct resource * mem_res[1];
struct resource * irq_res[TI_EDMA3_NUM_IRQS];
void *ih_cookie[TI_EDMA3_NUM_IRQS];
};
@ -108,9 +112,6 @@ static struct ti_edma3_softc *ti_edma3_sc = NULL;
static struct resource_spec ti_edma3_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE },
{ SYS_RES_MEMORY, 2, RF_ACTIVE },
{ SYS_RES_MEMORY, 3, RF_ACTIVE },
{ -1, 0, 0 }
};
static struct resource_spec ti_edma3_irq_spec[] = {
@ -123,8 +124,6 @@ static struct resource_spec ti_edma3_irq_spec[] = {
/* Read/Write macros */
#define ti_edma3_cc_rd_4(reg) bus_read_4(ti_edma3_sc->mem_res[0], reg)
#define ti_edma3_cc_wr_4(reg, val) bus_write_4(ti_edma3_sc->mem_res[0], reg, val)
#define ti_edma3_tc_rd_4(c, reg) bus_read_4(ti_edma3_sc->mem_res[c+1], reg)
#define ti_edma3_tc_wr_4(c, reg, val) bus_write_4(ti_edma3_sc->mem_res[c+1], reg, val)
static void ti_edma3_intr_comp(void *arg);
static void ti_edma3_intr_mperr(void *arg);

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
@ -101,53 +102,17 @@ __FBSDID("$FreeBSD$");
#define TI_GPIO_SETDATAOUT 0x0194
/* Other SoC Specific definitions */
#define OMAP4_MAX_GPIO_BANKS 6
#define OMAP4_FIRST_GPIO_BANK 1
#define OMAP4_INTR_PER_BANK 1
#define OMAP4_GPIO_REV 0x50600801
#define AM335X_MAX_GPIO_BANKS 4
#define AM335X_FIRST_GPIO_BANK 0
#define AM335X_INTR_PER_BANK 2
#define AM335X_GPIO_REV 0x50600801
#define PINS_PER_BANK 32
#define TI_GPIO_BANK(p) ((p) / PINS_PER_BANK)
#define TI_GPIO_MASK(p) (1U << ((p) % PINS_PER_BANK))
static struct ti_gpio_softc *ti_gpio_sc = NULL;
static int ti_gpio_detach(device_t);
static u_int
ti_max_gpio_banks(void)
{
switch(ti_chip()) {
#ifdef SOC_OMAP4
case CHIP_OMAP_4:
return (OMAP4_MAX_GPIO_BANKS);
#endif
#ifdef SOC_TI_AM335X
case CHIP_AM335X:
return (AM335X_MAX_GPIO_BANKS);
#endif
}
return (0);
}
static u_int
ti_max_gpio_intrs(void)
{
switch(ti_chip()) {
#ifdef SOC_OMAP4
case CHIP_OMAP_4:
return (OMAP4_MAX_GPIO_BANKS * OMAP4_INTR_PER_BANK);
#endif
#ifdef SOC_TI_AM335X
case CHIP_AM335X:
return (AM335X_MAX_GPIO_BANKS * AM335X_INTR_PER_BANK);
#endif
}
return (0);
}
static u_int
ti_first_gpio_bank(void)
{
@ -180,47 +145,6 @@ ti_gpio_rev(void)
return (0);
}
/**
* ti_gpio_mem_spec - Resource specification used when allocating resources
* ti_gpio_irq_spec - Resource specification used when allocating resources
*
* This driver module can have up to six independent memory regions, each
* region typically controls 32 GPIO pins.
*
* On OMAP3 and OMAP4 there is only one physical interrupt line per bank,
* but there are two set of registers which control the interrupt delivery
* to internal subsystems. The first set of registers control the
* interrupts delivery to the MPU and the second set control the
* interrupts delivery to the DSP.
*
* On AM335x there are two physical interrupt lines for each GPIO module.
* Each interrupt line is controlled by a set of registers.
*/
static struct resource_spec ti_gpio_mem_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_MEMORY, 1, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 3, RF_ACTIVE | RF_OPTIONAL },
#if !defined(SOC_TI_AM335X)
{ SYS_RES_MEMORY, 4, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_MEMORY, 5, RF_ACTIVE | RF_OPTIONAL },
#endif
{ -1, 0, 0 }
};
static struct resource_spec ti_gpio_irq_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 5, RF_ACTIVE | RF_OPTIONAL },
#if defined(SOC_TI_AM335X)
{ SYS_RES_IRQ, 6, RF_ACTIVE | RF_OPTIONAL },
{ SYS_RES_IRQ, 7, RF_ACTIVE | RF_OPTIONAL },
#endif
{ -1, 0, 0 }
};
/**
* Macros for driver mutex locking
*/
@ -244,9 +168,9 @@ static struct resource_spec ti_gpio_irq_spec[] = {
* 32-bit value read from the register.
*/
static inline uint32_t
ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off)
ti_gpio_read_4(struct ti_gpio_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->sc_mem_res[bank], off));
return (bus_read_4(sc->sc_mem_res, off));
}
/**
@ -260,52 +184,52 @@ ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off)
* nothing
*/
static inline void
ti_gpio_write_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off,
ti_gpio_write_4(struct ti_gpio_softc *sc, bus_size_t off,
uint32_t val)
{
bus_write_4(sc->sc_mem_res[bank], off, val);
bus_write_4(sc->sc_mem_res, off, val);
}
static inline void
ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
ti_gpio_intr_clr(struct ti_gpio_softc *sc, uint32_t mask)
{
/* We clear both set of registers. */
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_0, mask);
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_1, mask);
ti_gpio_write_4(sc, TI_GPIO_IRQSTATUS_CLR_0, mask);
ti_gpio_write_4(sc, TI_GPIO_IRQSTATUS_CLR_1, mask);
}
static inline void
ti_gpio_intr_set(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
ti_gpio_intr_set(struct ti_gpio_softc *sc, uint32_t mask)
{
/*
* On OMAP4 we unmask only the MPU interrupt and on AM335x we
* also activate only the first interrupt.
*/
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_SET_0, mask);
ti_gpio_write_4(sc, TI_GPIO_IRQSTATUS_SET_0, mask);
}
static inline void
ti_gpio_intr_ack(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
ti_gpio_intr_ack(struct ti_gpio_softc *sc, uint32_t mask)
{
/*
* Acknowledge the interrupt on both registers even if we use only
* the first one.
*/
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_0, mask);
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_1, mask);
ti_gpio_write_4(sc, TI_GPIO_IRQSTATUS_0, mask);
ti_gpio_write_4(sc, TI_GPIO_IRQSTATUS_1, mask);
}
static inline uint32_t
ti_gpio_intr_status(struct ti_gpio_softc *sc, unsigned int bank)
ti_gpio_intr_status(struct ti_gpio_softc *sc)
{
uint32_t reg;
/* Get the status from both registers. */
reg = ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_0);
reg |= ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_1);
reg = ti_gpio_read_4(sc, TI_GPIO_IRQSTATUS_0);
reg |= ti_gpio_read_4(sc, TI_GPIO_IRQSTATUS_1);
return (reg);
}
@ -337,7 +261,7 @@ static int
ti_gpio_pin_max(device_t dev, int *maxpin)
{
*maxpin = ti_max_gpio_banks() * PINS_PER_BANK - 1;
*maxpin = PINS_PER_BANK - 1;
return (0);
}
@ -346,11 +270,8 @@ static int
ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
{
if (pin >= sc->sc_maxpin ||
TI_GPIO_BANK(pin) >= ti_max_gpio_banks() ||
sc->sc_mem_res[TI_GPIO_BANK(pin)] == NULL) {
if (pin >= sc->sc_maxpin || sc->sc_mem_res == NULL)
return (EINVAL);
}
return (0);
}
@ -489,12 +410,12 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
}
/* If configuring as an output set the "output enable" bit */
oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE);
oe = ti_gpio_read_4(sc, TI_GPIO_OE);
if (flags & GPIO_PIN_INPUT)
oe |= TI_GPIO_MASK(pin);
else
oe &= ~TI_GPIO_MASK(pin);
ti_gpio_write_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE, oe);
ti_gpio_write_4(sc, TI_GPIO_OE, oe);
TI_GPIO_UNLOCK(sc);
return (0);
@ -529,7 +450,7 @@ ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
reg = TI_GPIO_CLEARDATAOUT;
else
reg = TI_GPIO_SETDATAOUT;
ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin));
ti_gpio_write_4(sc, reg, TI_GPIO_MASK(pin));
TI_GPIO_UNLOCK(sc);
return (0);
@ -565,12 +486,12 @@ ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
* input register otherwise.
*/
TI_GPIO_LOCK(sc);
oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE);
oe = ti_gpio_read_4(sc, TI_GPIO_OE);
if (oe & TI_GPIO_MASK(pin))
reg = TI_GPIO_DATAIN;
else
reg = TI_GPIO_DATAOUT;
val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), reg);
val = ti_gpio_read_4(sc, reg);
*value = (val & TI_GPIO_MASK(pin)) ? 1 : 0;
TI_GPIO_UNLOCK(sc);
@ -601,12 +522,12 @@ ti_gpio_pin_toggle(device_t dev, uint32_t pin)
/* Toggle the pin */
TI_GPIO_LOCK(sc);
val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_DATAOUT);
val = ti_gpio_read_4(sc, TI_GPIO_DATAOUT);
if (val & TI_GPIO_MASK(pin))
reg = TI_GPIO_CLEARDATAOUT;
else
reg = TI_GPIO_SETDATAOUT;
ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin));
ti_gpio_write_4(sc, reg, TI_GPIO_MASK(pin));
TI_GPIO_UNLOCK(sc);
return (0);
@ -631,13 +552,8 @@ ti_gpio_intr(void *arg)
sc = (struct ti_gpio_softc *)arg;
bank_last = -1;
reg = 0; /* squelch bogus gcc warning */
reg = ti_gpio_intr_status(sc);
for (irq = 0; irq < sc->sc_maxpin; irq++) {
/* Read interrupt status only once for each bank. */
if (TI_GPIO_BANK(irq) != bank_last) {
reg = ti_gpio_intr_status(sc, TI_GPIO_BANK(irq));
bank_last = TI_GPIO_BANK(irq);
}
if ((reg & TI_GPIO_MASK(irq)) == 0)
continue;
event = sc->sc_events[irq];
@ -646,96 +562,57 @@ ti_gpio_intr(void *arg)
else
device_printf(sc->sc_dev, "Stray IRQ %d\n", irq);
/* Ack the IRQ Status bit. */
ti_gpio_intr_ack(sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq));
ti_gpio_intr_ack(sc, TI_GPIO_MASK(irq));
}
return (FILTER_HANDLED);
}
static int
ti_gpio_attach_intr(device_t dev)
{
int i;
struct ti_gpio_softc *sc;
sc = device_get_softc(dev);
for (i = 0; i < ti_max_gpio_intrs(); i++) {
if (sc->sc_irq_res[i] == NULL)
break;
/*
* Register our interrupt filter for each of the IRQ resources.
*/
if (bus_setup_intr(dev, sc->sc_irq_res[i],
INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc,
&sc->sc_irq_hdl[i]) != 0) {
device_printf(dev,
"WARNING: unable to register interrupt filter\n");
return (-1);
}
}
return (0);
}
static int
ti_gpio_detach_intr(device_t dev)
{
int i;
struct ti_gpio_softc *sc;
/* Teardown our interrupt filters. */
sc = device_get_softc(dev);
for (i = 0; i < ti_max_gpio_intrs(); i++) {
if (sc->sc_irq_res[i] == NULL)
break;
if (sc->sc_irq_hdl[i]) {
bus_teardown_intr(dev, sc->sc_irq_res[i],
sc->sc_irq_hdl[i]);
}
}
return (0);
}
static int
ti_gpio_bank_init(device_t dev, int bank)
ti_gpio_bank_init(device_t dev)
{
int pin;
struct ti_gpio_softc *sc;
uint32_t flags, reg_oe, rev;
clk_ident_t clk;
sc = device_get_softc(dev);
/* Enable the interface and functional clocks for the module. */
ti_prcm_clk_enable(GPIO0_CLK + ti_first_gpio_bank() + bank);
clk = ti_hwmods_get_clock(dev);
if (clk == INVALID_CLK_IDENT) {
device_printf(dev, "failed to get device id based on ti,hwmods\n");
return (EINVAL);
}
sc->sc_bank = clk - GPIO1_CLK + ti_first_gpio_bank();
ti_prcm_clk_enable(clk);
/*
* Read the revision number of the module. TI don't publish the
* actual revision numbers, so instead the values have been
* determined by experimentation.
*/
rev = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION);
rev = ti_gpio_read_4(sc, TI_GPIO_REVISION);
/* Check the revision. */
if (rev != ti_gpio_rev()) {
device_printf(dev, "Warning: could not determine the revision "
"of GPIO module %d (revision:0x%08x)\n", bank, rev);
"of GPIO module (revision:0x%08x)\n", rev);
return (EINVAL);
}
/* Disable interrupts for all pins. */
ti_gpio_intr_clr(sc, bank, 0xffffffff);
ti_gpio_intr_clr(sc, 0xffffffff);
/* Init OE register based on pads configuration. */
reg_oe = 0xffffffff;
for (pin = 0; pin < PINS_PER_BANK; pin++) {
TI_GPIO_GET_FLAGS(dev, PINS_PER_BANK * bank + pin, &flags);
TI_GPIO_GET_FLAGS(dev, pin, &flags);
if (flags & GPIO_PIN_OUTPUT)
reg_oe &= ~(1UL << pin);
}
ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_oe);
ti_gpio_write_4(sc, TI_GPIO_OE, reg_oe);
return (0);
}
@ -760,35 +637,38 @@ ti_gpio_attach(device_t dev)
unsigned int i;
int err;
if (ti_gpio_sc != NULL)
return (ENXIO);
ti_gpio_sc = sc = device_get_softc(dev);
sc = device_get_softc(dev);
sc->sc_dev = dev;
TI_GPIO_LOCK_INIT(sc);
ti_gpio_pin_max(dev, &sc->sc_maxpin);
sc->sc_maxpin++;
/* There are up to 6 different GPIO register sets located in different
* memory areas on the chip. The memory range should have been set for
* the driver when it was added as a child.
*/
if (bus_alloc_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res) != 0) {
sc->sc_mem_rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->sc_mem_rid, RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "Error: could not allocate mem resources\n");
ti_gpio_detach(dev);
return (ENXIO);
}
/* Request the IRQ resources */
if (bus_alloc_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res) != 0) {
sc->sc_irq_rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->sc_irq_rid, RF_ACTIVE);
if (!sc->sc_irq_res) {
device_printf(dev, "Error: could not allocate irq resources\n");
ti_gpio_detach(dev);
return (ENXIO);
}
/* Setup the IRQ resources */
if (ti_gpio_attach_intr(dev) != 0) {
device_printf(dev, "Error: could not setup irq handlers\n");
/*
* Register our interrupt filter for each of the IRQ resources.
*/
if (bus_setup_intr(dev, sc->sc_irq_res,
INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc,
&sc->sc_irq_hdl) != 0) {
device_printf(dev,
"WARNING: unable to register interrupt filter\n");
ti_gpio_detach(dev);
return (ENXIO);
}
@ -811,21 +691,23 @@ ti_gpio_attach(device_t dev)
sc->sc_events = malloc(sizeof(struct intr_event *) * sc->sc_maxpin,
M_DEVBUF, M_WAITOK | M_ZERO);
sc->sc_mask_args = malloc(sizeof(struct ti_gpio_mask_arg) * sc->sc_maxpin,
M_DEVBUF, M_WAITOK | M_ZERO);
/* We need to go through each block and ensure the clocks are running and
* the module is enabled. It might be better to do this only when the
* pins are configured which would result in less power used if the GPIO
* pins weren't used ...
*/
for (i = 0; i < ti_max_gpio_banks(); i++) {
if (sc->sc_mem_res[i] != NULL) {
/* Initialize the GPIO module. */
err = ti_gpio_bank_init(dev, i);
if (err != 0) {
ti_gpio_detach(dev);
return (err);
}
if (sc->sc_mem_res != NULL) {
/* Initialize the GPIO module. */
err = ti_gpio_bank_init(dev);
if (err != 0) {
ti_gpio_detach(dev);
return (err);
}
}
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
ti_gpio_detach(dev);
@ -852,26 +734,30 @@ static int
ti_gpio_detach(device_t dev)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
unsigned int i;
KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
/* Disable all interrupts */
for (i = 0; i < ti_max_gpio_banks(); i++) {
if (sc->sc_mem_res[i] != NULL)
ti_gpio_intr_clr(sc, i, 0xffffffff);
}
if (sc->sc_mem_res != NULL)
ti_gpio_intr_clr(sc, 0xffffffff);
gpiobus_detach_bus(dev);
if (sc->sc_events)
free(sc->sc_events, M_DEVBUF);
if (sc->sc_mask_args)
free(sc->sc_mask_args, M_DEVBUF);
if (sc->sc_irq_polarity)
free(sc->sc_irq_polarity, M_DEVBUF);
if (sc->sc_irq_trigger)
free(sc->sc_irq_trigger, M_DEVBUF);
/* Release the memory and IRQ resources. */
ti_gpio_detach_intr(dev);
bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
if (sc->sc_irq_hdl) {
bus_teardown_intr(dev, sc->sc_irq_res,
sc->sc_irq_hdl);
}
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
sc->sc_irq_res);
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
sc->sc_mem_res);
TI_GPIO_LOCK_DESTROY(sc);
return (0);
@ -900,46 +786,57 @@ ti_gpio_intr_reg(struct ti_gpio_softc *sc, int irq)
}
static void
ti_gpio_mask_irq(void *source)
ti_gpio_mask_irq_internal(struct ti_gpio_softc *sc, int irq)
{
int irq;
uint32_t reg, val;
irq = (int)source;
if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0)
if (ti_gpio_valid_pin(sc, irq) != 0)
return;
TI_GPIO_LOCK(ti_gpio_sc);
ti_gpio_intr_clr(ti_gpio_sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq));
reg = ti_gpio_intr_reg(ti_gpio_sc, irq);
TI_GPIO_LOCK(sc);
ti_gpio_intr_clr(sc, TI_GPIO_MASK(irq));
reg = ti_gpio_intr_reg(sc, irq);
if (reg != 0) {
val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg);
val = ti_gpio_read_4(sc, reg);
val &= ~TI_GPIO_MASK(irq);
ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val);
ti_gpio_write_4(sc, reg, val);
}
TI_GPIO_UNLOCK(ti_gpio_sc);
TI_GPIO_UNLOCK(sc);
}
static void
ti_gpio_unmask_irq_internal(struct ti_gpio_softc *sc, int irq)
{
uint32_t reg, val;
if (ti_gpio_valid_pin(sc, irq) != 0)
return;
TI_GPIO_LOCK(sc);
reg = ti_gpio_intr_reg(sc, irq);
if (reg != 0) {
val = ti_gpio_read_4(sc, reg);
val |= TI_GPIO_MASK(irq);
ti_gpio_write_4(sc, reg, val);
ti_gpio_intr_set(sc, TI_GPIO_MASK(irq));
}
TI_GPIO_UNLOCK(sc);
}
static void
ti_gpio_mask_irq(void *source)
{
struct ti_gpio_mask_arg *arg = source;
ti_gpio_mask_irq_internal(arg->softc, arg->pin);
}
static void
ti_gpio_unmask_irq(void *source)
{
int irq;
uint32_t reg, val;
struct ti_gpio_mask_arg *arg = source;
irq = (int)source;
if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0)
return;
TI_GPIO_LOCK(ti_gpio_sc);
reg = ti_gpio_intr_reg(ti_gpio_sc, irq);
if (reg != 0) {
val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg);
val |= TI_GPIO_MASK(irq);
ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val);
ti_gpio_intr_set(ti_gpio_sc, TI_GPIO_BANK(irq),
TI_GPIO_MASK(irq));
}
TI_GPIO_UNLOCK(ti_gpio_sc);
ti_gpio_unmask_irq_internal(arg->softc, arg->pin);
}
static int
@ -1000,15 +897,15 @@ ti_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig,
reg = ti_gpio_intr_reg(sc, irq);
if (reg != 0) {
/* Apply the new settings. */
val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), reg);
val = ti_gpio_read_4(sc, reg);
val |= TI_GPIO_MASK(irq);
ti_gpio_write_4(sc, TI_GPIO_BANK(irq), reg, val);
ti_gpio_write_4(sc, reg, val);
}
if (reg != oldreg && oldreg != 0) {
/* Remove the old settings. */
val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), oldreg);
val = ti_gpio_read_4(sc, oldreg);
val &= ~TI_GPIO_MASK(irq);
ti_gpio_write_4(sc, TI_GPIO_BANK(irq), oldreg, val);
ti_gpio_write_4(sc, oldreg, val);
}
TI_GPIO_UNLOCK(sc);
@ -1031,7 +928,9 @@ ti_gpio_setup_intr(device_t dev, device_t child, struct resource *ires,
event = sc->sc_events[pin];
if (event == NULL) {
error = intr_event_create(&event, (void *)(uintptr_t)pin, 0,
sc->sc_mask_args[pin].softc = sc;
sc->sc_mask_args[pin].pin = pin;
error = intr_event_create(&event, (void *)&sc->sc_mask_args[pin], 0,
pin, ti_gpio_mask_irq, ti_gpio_unmask_irq, NULL, NULL,
"gpio%d pin%d:", device_get_unit(dev), pin);
if (error != 0)

View File

@ -39,6 +39,11 @@
*/
#define MAX_GPIO_INTRS 8
struct ti_gpio_mask_arg {
void *softc;
int pin;
};
/**
* Structure that stores the driver context.
*
@ -52,22 +57,21 @@ struct ti_gpio_softc {
enum intr_trigger *sc_irq_trigger;
enum intr_polarity *sc_irq_polarity;
int sc_bank;
int sc_maxpin;
struct mtx sc_mtx;
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
* the SoC type.
*/
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
int sc_mem_rid;
struct resource *sc_mem_res;
int sc_irq_rid;
struct resource *sc_irq_res;
/* Interrupt events. */
struct intr_event **sc_events;
struct ti_gpio_mask_arg *sc_mask_args;
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
void *sc_irq_hdl;
};
#endif /* TI_GPIO_H */

170
sys/arm/ti/ti_hwmods.c Normal file
View File

@ -0,0 +1,170 @@
/*-
* Copyright (c) 2015 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 ``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$
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
struct hwmod {
const char *name;
int clock_id;
};
struct hwmod ti_hwmods[] = {
{"i2c1", I2C1_CLK},
{"i2c2", I2C2_CLK},
{"i2c3", I2C3_CLK},
{"i2c4", I2C4_CLK},
{"i2c5", I2C5_CLK},
{"gpio1", GPIO1_CLK},
{"gpio2", GPIO2_CLK},
{"gpio3", GPIO3_CLK},
{"gpio4", GPIO4_CLK},
{"gpio5", GPIO5_CLK},
{"gpio6", GPIO6_CLK},
{"gpio7", GPIO7_CLK},
{"mmc1", MMC1_CLK},
{"mmc2", MMC2_CLK},
{"mmc3", MMC3_CLK},
{"mmc4", MMC4_CLK},
{"mmc5", MMC5_CLK},
{"mmc6", MMC6_CLK},
{"epwmss0", PWMSS0_CLK},
{"epwmss1", PWMSS1_CLK},
{"epwmss2", PWMSS2_CLK},
{"timer1", TIMER1_CLK},
{"timer2", TIMER2_CLK},
{"timer3", TIMER3_CLK},
{"timer4", TIMER4_CLK},
{"timer5", TIMER5_CLK},
{"timer6", TIMER6_CLK},
{"timer7", TIMER7_CLK},
{"uart1", UART1_CLK},
{"uart2", UART2_CLK},
{"uart3", UART3_CLK},
{"uart4", UART4_CLK},
{"uart5", UART5_CLK},
{"uart6", UART6_CLK},
{"uart7", UART7_CLK},
{NULL, 0}
};
clk_ident_t
ti_hwmods_get_clock(device_t dev)
{
phandle_t node;
int len, l;
char *name;
char *buf;
int clk;
struct hwmod *hw;
if ((node = ofw_bus_get_node(dev)) == 0)
return (INVALID_CLK_IDENT);
if ((len = OF_getprop_alloc(node, "ti,hwmods", 1, (void**)&name)) <= 0)
return (INVALID_CLK_IDENT);
buf = name;
clk = INVALID_CLK_IDENT;
while ((len > 0) && (clk == INVALID_CLK_IDENT)) {
for (hw = ti_hwmods; hw->name != NULL; ++hw) {
if (strcmp(hw->name, name) == 0) {
clk = hw->clock_id;
break;
}
}
/* Slide to the next sub-string. */
l = strlen(name) + 1;
name += l;
len -= l;
}
if (len > 0)
device_printf(dev, "WARNING: more then one ti,hwmod \n");
free(buf, M_OFWPROP);
return (clk);
}
int ti_hwmods_contains(device_t dev, const char *hwmod)
{
phandle_t node;
int len, l;
char *name;
char *buf;
int result;
if ((node = ofw_bus_get_node(dev)) == 0)
return (0);
if ((len = OF_getprop_alloc(node, "ti,hwmods", 1, (void**)&name)) <= 0)
return (0);
buf = name;
result = 0;
while (len > 0) {
if (strcmp(name, hwmod) == 0) {
result = 1;
break;
}
/* Slide to the next sub-string. */
l = strlen(name) + 1;
name += l;
len -= l;
}
free(buf, M_OFWPROP);
return (result);
}

34
sys/arm/ti/ti_hwmods.h Normal file
View File

@ -0,0 +1,34 @@
/*-
* Copyright (c) 2015 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _TI_HWMODS_H_
#define _TI_HWMODS_H_
clk_ident_t ti_hwmods_get_clock(device_t dev);
int ti_hwmods_contains(device_t dev, const char *hwmod);
#endif /* _TI_HWMODS_H_ */

View File

@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_i2c.h>
#include <dev/iicbus/iiconf.h>
@ -81,7 +82,7 @@ __FBSDID("$FreeBSD$");
struct ti_i2c_softc
{
device_t sc_dev;
uint32_t device_id;
clk_ident_t clk_id;
struct resource* sc_irq_res;
struct resource* sc_mem_res;
device_t sc_iicbus;
@ -693,7 +694,6 @@ ti_i2c_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
static int
ti_i2c_activate(device_t dev)
{
clk_ident_t clk;
int err;
struct ti_i2c_softc *sc;
@ -703,8 +703,7 @@ ti_i2c_activate(device_t dev)
* 1. Enable the functional and interface clocks (see Section
* 23.1.5.1.1.1.1).
*/
clk = I2C0_CLK + sc->device_id;
err = ti_prcm_clk_enable(clk);
err = ti_prcm_clk_enable(sc->clk_id);
if (err)
return (err);
@ -727,7 +726,6 @@ static void
ti_i2c_deactivate(device_t dev)
{
struct ti_i2c_softc *sc = device_get_softc(dev);
clk_ident_t clk;
/* Disable the controller - cancel all transactions. */
ti_i2c_write_2(sc, I2C_REG_IRQENABLE_CLR, 0xffff);
@ -755,8 +753,7 @@ ti_i2c_deactivate(device_t dev)
}
/* Finally disable the functional and interface clocks. */
clk = I2C0_CLK + sc->device_id;
ti_prcm_clk_disable(clk);
ti_prcm_clk_disable(sc->clk_id);
}
static int
@ -815,7 +812,7 @@ ti_i2c_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,i2c"))
if (!ofw_bus_is_compatible(dev, "ti,omap4-i2c"))
return (ENXIO);
device_set_desc(dev, "TI I2C Controller");
@ -837,9 +834,10 @@ ti_i2c_attach(device_t dev)
/* Get the i2c device id from FDT. */
node = ofw_bus_get_node(dev);
if ((OF_getencprop(node, "i2c-device-id", &sc->device_id,
sizeof(sc->device_id))) <= 0) {
device_printf(dev, "missing i2c-device-id attribute in FDT\n");
/* i2c ti,hwmods bindings is special: it start with index 1 */
sc->clk_id = ti_hwmods_get_clock(dev);
if (sc->clk_id == INVALID_CLK_IDENT) {
device_printf(dev, "failed to get device id using ti,hwmod\n");
return (ENXIO);
}

View File

@ -121,7 +121,7 @@ ti_mbox_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "ti,system-mbox")) {
if (ofw_bus_is_compatible(dev, "ti,omap4-mailbox")) {
device_set_desc(dev, "TI System Mailbox");
return (BUS_PROBE_DEFAULT);
}

445
sys/arm/ti/ti_pinmux.c Normal file
View File

@ -0,0 +1,445 @@
/*
* 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.
*/
/**
* Exposes pinmux module to pinctrl-compatible interface
*/
#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 <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <dev/fdt/fdt_common.h>
#include <dev/fdt/fdt_pinctrl.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "ti_pinmux.h"
struct pincfg {
uint32_t reg;
uint32_t conf;
};
static struct resource_spec ti_pinmux_res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */
{ -1, 0 }
};
static struct ti_pinmux_softc *ti_pinmux_sc;
#define ti_pinmux_read_2(sc, reg) \
bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define ti_pinmux_write_2(sc, reg, val) \
bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#define ti_pinmux_read_4(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define ti_pinmux_write_4(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
/**
* ti_padconf_devmap - Array of pins, should be defined one per SoC
*
* This array is typically defined in one of the targeted *_scm_pinumx.c
* files and is specific to the given SoC platform. Each entry in the array
* corresponds to an individual pin.
*/
extern const struct ti_pinmux_device ti_pinmux_dev;
/**
* ti_pinmux_padconf_from_name - searches the list of pads and returns entry
* with matching ball name.
* @ballname: the name of the ball
*
* RETURNS:
* A pointer to the matching padconf or NULL if the ball wasn't found.
*/
static const struct ti_pinmux_padconf*
ti_pinmux_padconf_from_name(const char *ballname)
{
const struct ti_pinmux_padconf *padconf;
padconf = ti_pinmux_dev.padconf;
while (padconf->ballname != NULL) {
if (strcmp(ballname, padconf->ballname) == 0)
return(padconf);
padconf++;
}
return (NULL);
}
/**
* ti_pinmux_padconf_set_internal - sets the muxmode and state for a pad/pin
* @padconf: pointer to the pad structure
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
static int
ti_pinmux_padconf_set_internal(struct ti_pinmux_softc *sc,
const struct ti_pinmux_padconf *padconf,
const char *muxmode, unsigned int state)
{
unsigned int mode;
uint16_t reg_val;
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_pinmux_dev.padconf_sate_mask);
/* find the new mode requested */
for (mode = 0; mode < 8; mode++) {
if ((padconf->muxmodes[mode] != NULL) &&
(strcmp(padconf->muxmodes[mode], muxmode) == 0)) {
break;
}
}
/* couldn't find the mux mode */
if (mode >= 8) {
printf("Invalid mode \"%s\"\n", muxmode);
return (EINVAL);
}
/* set the mux mode */
reg_val |= (uint16_t)(mode & ti_pinmux_dev.padconf_muxmode_mask);
if (bootverbose)
device_printf(sc->sc_dev, "setting internal %x for %s\n",
reg_val, muxmode);
/* write the register value (16-bit writes) */
ti_pinmux_write_2(sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_pinmux_padconf_set - sets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_pinmux_padconf_set(const char *padname, const char *muxmode, unsigned int state)
{
const struct ti_pinmux_padconf *padconf;
if (!ti_pinmux_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_pinmux_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
return (ti_pinmux_padconf_set_internal(ti_pinmux_sc, padconf, muxmode, state));
}
/**
* ti_pinmux_padconf_get - gets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: upon return will contain the name of the muxmode of the pin
* @state: upon return will contain the state of the pad/pin
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_pinmux_padconf_get(const char *padname, const char **muxmode,
unsigned int *state)
{
const struct ti_pinmux_padconf *padconf;
uint16_t reg_val;
if (!ti_pinmux_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_pinmux_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
/* read the register value (16-bit reads) */
reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off);
/* save the state */
if (state)
*state = (reg_val & ti_pinmux_dev.padconf_sate_mask);
/* save the mode */
if (muxmode)
*muxmode = padconf->muxmodes[(reg_val & ti_pinmux_dev.padconf_muxmode_mask)];
return (0);
}
/**
* ti_pinmux_padconf_set_gpiomode - converts a pad to GPIO mode.
* @gpio: the GPIO pin number (0-195)
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_pinmux_padconf_set_gpiomode(uint32_t gpio, unsigned int state)
{
const struct ti_pinmux_padconf *padconf;
uint16_t reg_val;
if (!ti_pinmux_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_pinmux_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_pinmux_dev.padconf_sate_mask);
/* set the mux mode */
reg_val |= (uint16_t)(padconf->gpio_mode & ti_pinmux_dev.padconf_muxmode_mask);
/* write the register value (16-bit writes) */
ti_pinmux_write_2(ti_pinmux_sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_pinmux_padconf_get_gpiomode - gets the current GPIO mode of the pin
* @gpio: the GPIO pin number (0-195)
* @state: upon return will contain the state
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or not configured as GPIO.
*/
int
ti_pinmux_padconf_get_gpiomode(uint32_t gpio, unsigned int *state)
{
const struct ti_pinmux_padconf *padconf;
uint16_t reg_val;
if (!ti_pinmux_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_pinmux_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* read the current register settings */
reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off);
/* check to make sure the pins is configured as GPIO in the first state */
if ((reg_val & ti_pinmux_dev.padconf_muxmode_mask) != padconf->gpio_mode)
return (EINVAL);
/* read and store the reset of the state, i.e. pull-up, pull-down, etc */
if (state)
*state = (reg_val & ti_pinmux_dev.padconf_sate_mask);
return (0);
}
static int
ti_pinmux_configure_pins(device_t dev, phandle_t cfgxref)
{
struct pincfg *cfgtuples, *cfg;
phandle_t cfgnode;
int i, ntuples;
static struct ti_pinmux_softc *sc;
sc = device_get_softc(dev);
cfgnode = OF_node_from_xref(cfgxref);
ntuples = OF_getencprop_alloc(cfgnode, "pinctrl-single,pins", sizeof(*cfgtuples),
(void **)&cfgtuples);
if (ntuples < 0)
return (ENOENT);
if (ntuples == 0)
return (0); /* Empty property is not an error. */
for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) {
if (bootverbose) {
char name[32];
OF_getprop(cfgnode, "name", &name, sizeof(name));
printf("%16s: muxreg 0x%04x muxval 0x%02x\n",
name, cfg->reg, cfg->conf);
}
/* write the register value (16-bit writes) */
ti_pinmux_write_2(sc, cfg->reg, cfg->conf);
}
free(cfgtuples, M_OFWPROP);
return (0);
}
/*
* Device part of OMAP SCM driver
*/
static int
ti_pinmux_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "pinctrl-single"))
return (ENXIO);
if (ti_pinmux_sc) {
printf("%s: multiple pinctrl modules in device tree data, ignoring\n",
__func__);
return (EEXIST);
}
device_set_desc(dev, "TI Pinmux Module");
return (BUS_PROBE_DEFAULT);
}
/**
* ti_pinmux_attach - attaches the pinmux to the simplebus
* @dev: new device
*
* RETURNS
* Zero on sucess or ENXIO if an error occuried.
*/
static int
ti_pinmux_attach(device_t dev)
{
struct ti_pinmux_softc *sc = device_get_softc(dev);
#if 0
if (ti_pinmux_sc)
return (ENXIO);
#endif
sc->sc_dev = dev;
if (bus_alloc_resources(dev, ti_pinmux_res_spec, sc->sc_res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
if (ti_pinmux_sc == NULL)
ti_pinmux_sc = sc;
fdt_pinctrl_register(dev, "pinctrl-single,pins");
fdt_pinctrl_configure_tree(dev);
return (0);
}
static device_method_t ti_pinmux_methods[] = {
DEVMETHOD(device_probe, ti_pinmux_probe),
DEVMETHOD(device_attach, ti_pinmux_attach),
/* fdt_pinctrl interface */
DEVMETHOD(fdt_pinctrl_configure, ti_pinmux_configure_pins),
{ 0, 0 }
};
static driver_t ti_pinmux_driver = {
"ti_pinmux",
ti_pinmux_methods,
sizeof(struct ti_pinmux_softc),
};
static devclass_t ti_pinmux_devclass;
DRIVER_MODULE(ti_pinmux, simplebus, ti_pinmux_driver, ti_pinmux_devclass, 0, 0);

80
sys/arm/ti/ti_pinmux.h Normal file
View File

@ -0,0 +1,80 @@
/*
* 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_PINMUX_H_
#define _TI_PINMUX_H_
struct ti_pinmux_padconf {
uint16_t reg_off;
uint16_t gpio_pin;
uint16_t gpio_mode;
const char *ballname;
const char *muxmodes[8];
};
struct ti_pinmux_padstate {
const char *state;
uint16_t reg;
};
struct ti_pinmux_device {
uint16_t padconf_muxmode_mask;
uint16_t padconf_sate_mask;
const struct ti_pinmux_padstate *padstate;
const struct ti_pinmux_padconf *padconf;
};
struct ti_pinmux_softc {
device_t sc_dev;
struct resource * sc_res[4];
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
};
int ti_pinmux_padconf_set(const char *padname, const char *muxmode,
unsigned int state);
int ti_pinmux_padconf_get(const char *padname, const char **muxmode,
unsigned int *state);
int ti_pinmux_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
int ti_pinmux_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
#endif /* _TI_SCM_H_ */

View File

@ -46,6 +46,8 @@
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.
*/
@ -55,19 +57,19 @@ typedef enum {
MPU_CLK = 20,
/* MMC modules */
MMC0_CLK = 100,
MMC1_CLK,
MMC1_CLK = 100,
MMC2_CLK,
MMC3_CLK,
MMC4_CLK,
MMC5_CLK,
MMC6_CLK,
/* I2C modules */
I2C0_CLK = 200,
I2C1_CLK,
I2C1_CLK = 200,
I2C2_CLK,
I2C3_CLK,
I2C4_CLK,
I2C5_CLK,
/* USB module(s) */
USBTLL_CLK = 300,
@ -81,8 +83,7 @@ typedef enum {
USBP2_HSIC_CLK,
/* UART modules */
UART0_CLK = 400,
UART1_CLK,
UART1_CLK = 400,
UART2_CLK,
UART3_CLK,
UART4_CLK,
@ -90,20 +91,21 @@ typedef enum {
UART6_CLK,
UART7_CLK,
UART8_CLK,
UART9_CLK,
/* General purpose timer modules */
GPTIMER1_CLK = 500,
GPTIMER2_CLK,
GPTIMER3_CLK,
GPTIMER4_CLK,
GPTIMER5_CLK,
GPTIMER6_CLK,
GPTIMER7_CLK,
GPTIMER8_CLK,
GPTIMER9_CLK,
GPTIMER10_CLK,
GPTIMER11_CLK,
GPTIMER12_CLK,
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,
@ -113,27 +115,17 @@ typedef enum {
MCBSP5_CLK,
/* General purpose I/O modules */
GPIO0_CLK = 700,
GPIO1_CLK,
GPIO1_CLK = 700,
GPIO2_CLK,
GPIO3_CLK,
GPIO4_CLK,
GPIO5_CLK,
GPIO6_CLK,
GPIO7_CLK,
/* sDMA module */
SDMA_CLK = 800,
/* DMTimer modules */
DMTIMER0_CLK = 900,
DMTIMER1_CLK,
DMTIMER2_CLK,
DMTIMER3_CLK,
DMTIMER4_CLK,
DMTIMER5_CLK,
DMTIMER6_CLK,
DMTIMER7_CLK,
/* CPSW modules */
CPSW_CLK = 1000,
@ -166,9 +158,6 @@ typedef enum {
/* RTC module */
RTC_CLK = 1900,
INVALID_CLK_IDENT
} clk_ident_t;
/*

View File

@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <dev/fdt/fdt_common.h>
#include <dev/fdt/fdt_pinctrl.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@ -77,354 +78,29 @@ static struct resource_spec ti_scm_res_spec[] = {
static struct ti_scm_softc *ti_scm_sc;
#define ti_scm_read_2(sc, reg) \
bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define ti_scm_write_2(sc, reg, val) \
bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#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))
/**
* ti_padconf_devmap - Array of pins, should be defined one per SoC
*
* This array is typically defined in one of the targeted *_scm_pinumx.c
* files and is specific to the given SoC platform. Each entry in the array
* corresponds to an individual pin.
*/
extern const struct ti_scm_device ti_scm_dev;
/**
* ti_scm_padconf_from_name - searches the list of pads and returns entry
* with matching ball name.
* @ballname: the name of the ball
*
* RETURNS:
* A pointer to the matching padconf or NULL if the ball wasn't found.
*/
static const struct ti_scm_padconf*
ti_scm_padconf_from_name(const char *ballname)
{
const struct ti_scm_padconf *padconf;
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (strcmp(ballname, padconf->ballname) == 0)
return(padconf);
padconf++;
}
return (NULL);
}
/**
* ti_scm_padconf_set_internal - sets the muxmode and state for a pad/pin
* @padconf: pointer to the pad structure
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
static int
ti_scm_padconf_set_internal(struct ti_scm_softc *sc,
const struct ti_scm_padconf *padconf,
const char *muxmode, unsigned int state)
{
unsigned int mode;
uint16_t reg_val;
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
/* find the new mode requested */
for (mode = 0; mode < 8; mode++) {
if ((padconf->muxmodes[mode] != NULL) &&
(strcmp(padconf->muxmodes[mode], muxmode) == 0)) {
break;
}
}
/* couldn't find the mux mode */
if (mode >= 8) {
printf("Invalid mode \"%s\"\n", muxmode);
return (EINVAL);
}
/* set the mux mode */
reg_val |= (uint16_t)(mode & ti_scm_dev.padconf_muxmode_mask);
if (bootverbose)
device_printf(sc->sc_dev, "setting internal %x for %s\n",
reg_val, muxmode);
/* write the register value (16-bit writes) */
ti_scm_write_2(sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_scm_padconf_set - sets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_set(const char *padname, const char *muxmode, unsigned int state)
{
const struct ti_scm_padconf *padconf;
if (!ti_scm_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_scm_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
return (ti_scm_padconf_set_internal(ti_scm_sc, padconf, muxmode, state));
}
/**
* ti_scm_padconf_get - gets the muxmode and state for a pad/pin
* @padname: the name of the pad, i.e. "c12"
* @muxmode: upon return will contain the name of the muxmode of the pin
* @state: upon return will contain the state of the pad/pin
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the pin in the devmap */
padconf = ti_scm_padconf_from_name(padname);
if (padconf == NULL)
return (EINVAL);
/* read the register value (16-bit reads) */
reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
/* save the state */
if (state)
*state = (reg_val & ti_scm_dev.padconf_sate_mask);
/* save the mode */
if (muxmode)
*muxmode = padconf->muxmodes[(reg_val & ti_scm_dev.padconf_muxmode_mask)];
return (0);
}
/**
* ti_scm_padconf_set_gpiomode - converts a pad to GPIO mode.
* @gpio: the GPIO pin number (0-195)
* @state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
int
ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* populate the new value for the PADCONF register */
reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
/* set the mux mode */
reg_val |= (uint16_t)(padconf->gpio_mode & ti_scm_dev.padconf_muxmode_mask);
/* write the register value (16-bit writes) */
ti_scm_write_2(ti_scm_sc, padconf->reg_off, reg_val);
return (0);
}
/**
* ti_scm_padconf_get_gpiomode - gets the current GPIO mode of the pin
* @gpio: the GPIO pin number (0-195)
* @state: upon return will contain the state
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or not configured as GPIO.
*/
int
ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state)
{
const struct ti_scm_padconf *padconf;
uint16_t reg_val;
if (!ti_scm_sc)
return (ENXIO);
/* find the gpio pin in the padconf array */
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (padconf->gpio_pin == gpio)
break;
padconf++;
}
if (padconf->ballname == NULL)
return (EINVAL);
/* read the current register settings */
reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
/* check to make sure the pins is configured as GPIO in the first state */
if ((reg_val & ti_scm_dev.padconf_muxmode_mask) != padconf->gpio_mode)
return (EINVAL);
/* read and store the reset of the state, i.e. pull-up, pull-down, etc */
if (state)
*state = (reg_val & ti_scm_dev.padconf_sate_mask);
return (0);
}
/**
* ti_scm_padconf_init_from_hints - processes the hints for padconf
* @sc: the driver soft context
*
*
*
* LOCKING:
* Internally locks it's own context.
*
* RETURNS:
* 0 on success.
* EINVAL if pin requested is outside valid range or already in use.
*/
static int
ti_scm_padconf_init_from_fdt(struct ti_scm_softc *sc)
{
const struct ti_scm_padconf *padconf;
const struct ti_scm_padstate *padstates;
int err;
phandle_t node;
int len;
char *fdt_pad_config;
int i;
char *padname, *muxname, *padstate;
node = ofw_bus_get_node(sc->sc_dev);
len = OF_getproplen(node, "scm-pad-config");
OF_getprop_alloc(node, "scm-pad-config", 1, (void **)&fdt_pad_config);
i = len;
while (i > 0) {
padname = fdt_pad_config;
fdt_pad_config += strlen(padname) + 1;
i -= strlen(padname) + 1;
if (i <= 0)
break;
muxname = fdt_pad_config;
fdt_pad_config += strlen(muxname) + 1;
i -= strlen(muxname) + 1;
if (i <= 0)
break;
padstate = fdt_pad_config;
fdt_pad_config += strlen(padstate) + 1;
i -= strlen(padstate) + 1;
if (i < 0)
break;
padconf = ti_scm_dev.padconf;
while (padconf->ballname != NULL) {
if (strcmp(padconf->ballname, padname) == 0) {
padstates = ti_scm_dev.padstate;
err = 1;
while (padstates->state != NULL) {
if (strcmp(padstates->state, padstate) == 0) {
err = ti_scm_padconf_set_internal(sc,
padconf, muxname, padstates->reg);
}
padstates++;
}
if (err)
device_printf(sc->sc_dev,
"err: failed to configure "
"pin \"%s\" as \"%s\"\n",
padconf->ballname,
muxname);
}
padconf++;
}
}
return (0);
}
/*
* 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, "ti,scm"))
if (!ofw_bus_is_compatible(dev, "syscon"))
return (ENXIO);
if (ti_scm_sc) {
printf("%s: multiple SCM modules in device tree data, ignoring\n",
__func__);
return (EEXIST);
}
device_set_desc(dev, "TI Control Module");
return (BUS_PROBE_DEFAULT);
}
@ -444,9 +120,6 @@ ti_scm_attach(device_t dev)
{
struct ti_scm_softc *sc = device_get_softc(dev);
if (ti_scm_sc)
return (ENXIO);
sc->sc_dev = dev;
if (bus_alloc_resources(dev, ti_scm_res_spec, sc->sc_res)) {
@ -460,8 +133,6 @@ ti_scm_attach(device_t dev)
ti_scm_sc = sc;
ti_scm_padconf_init_from_fdt(sc);
return (0);
}
@ -489,6 +160,7 @@ ti_scm_reg_write_4(uint32_t reg, uint32_t val)
static device_method_t ti_scm_methods[] = {
DEVMETHOD(device_probe, ti_scm_probe),
DEVMETHOD(device_attach, ti_scm_attach),
{ 0, 0 }
};

View File

@ -43,26 +43,6 @@
#ifndef _TI_SCM_H_
#define _TI_SCM_H_
struct ti_scm_padconf {
uint16_t reg_off;
uint16_t gpio_pin;
uint16_t gpio_mode;
const char *ballname;
const char *muxmodes[8];
};
struct ti_scm_padstate {
const char *state;
uint16_t reg;
};
struct ti_scm_device {
uint16_t padconf_muxmode_mask;
uint16_t padconf_sate_mask;
const struct ti_scm_padstate *padstate;
const struct ti_scm_padconf *padconf;
};
struct ti_scm_softc {
device_t sc_dev;
struct resource * sc_res[4];
@ -70,12 +50,6 @@ struct ti_scm_softc {
bus_space_handle_t sc_bsh;
};
int ti_scm_padconf_set(const char *padname, const char *muxmode,
unsigned int state);
int ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state);
int ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
int ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
int ti_scm_reg_write_4(uint32_t reg, uint32_t val);

View File

@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include "gpio_if.h"
struct ti_sdhci_softc {
@ -66,7 +67,7 @@ struct ti_sdhci_softc {
struct resource * irq_res;
void * intr_cookie;
struct sdhci_slot slot;
uint32_t mmchs_device_id;
clk_ident_t mmchs_clk_id;
uint32_t mmchs_reg_off;
uint32_t sdhci_reg_off;
uint32_t baseclk_hz;
@ -383,19 +384,18 @@ static void
ti_sdhci_hw_init(device_t dev)
{
struct ti_sdhci_softc *sc = device_get_softc(dev);
clk_ident_t clk;
uint32_t regval;
unsigned long timeout;
/* Enable the controller and interface/functional clocks */
clk = MMC0_CLK + sc->mmchs_device_id;
if (ti_prcm_clk_enable(clk) != 0) {
if (ti_prcm_clk_enable(sc->mmchs_clk_id) != 0) {
device_printf(dev, "Error: failed to enable MMC clock\n");
return;
}
/* Get the frequency of the source clock */
if (ti_prcm_clk_get_source_freq(clk, &sc->baseclk_hz) != 0) {
if (ti_prcm_clk_get_source_freq(sc->mmchs_clk_id,
&sc->baseclk_hz) != 0) {
device_printf(dev, "Error: failed to get source clock freq\n");
return;
}
@ -484,12 +484,10 @@ ti_sdhci_attach(device_t dev)
* up and added in freebsd, it doesn't exist in the published bindings.
*/
node = ofw_bus_get_node(dev);
if ((OF_getprop(node, "mmchs-device-id", &prop, sizeof(prop))) <= 0) {
sc->mmchs_device_id = device_get_unit(dev);
device_printf(dev, "missing mmchs-device-id attribute in FDT, "
"using unit number (%d)", sc->mmchs_device_id);
} else
sc->mmchs_device_id = fdt32_to_cpu(prop);
sc->mmchs_clk_id = ti_hwmods_get_clock(dev);
if (sc->mmchs_clk_id == INVALID_CLK_IDENT) {
device_printf(dev, "failed to get clock based on hwmods property\n");
}
/*
* The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first
@ -500,7 +498,7 @@ ti_sdhci_attach(device_t dev)
* be done once and never reset.
*/
sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
if (sc->mmchs_device_id == 0 || OF_hasprop(node, "ti,dual-volt")) {
if (sc->mmchs_clk_id == MMC1_CLK || OF_hasprop(node, "ti,dual-volt")) {
sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310;
}

View File

@ -1131,7 +1131,7 @@ ti_sdma_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,sdma"))
if (!ofw_bus_is_compatible(dev, "ti,omap4430-sdma"))
return (ENXIO);
device_set_desc(dev, "TI sDMA Controller");

View File

@ -24,65 +24,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* Driver for the High Speed USB EHCI module on the TI OMAP3530 SoC.
*
* WARNING: I've only tried this driver on a limited number of USB peripherals,
* it is still very raw and bound to have numerous bugs in it.
*
* This driver is based on the FreeBSD IXP4xx EHCI driver with a lot of the
* setup sequence coming from the Linux community and their EHCI driver for
* OMAP. Without these as a base I don't think I would have been able to get
* this driver working.
*
* The driver only contains the EHCI parts, the module also supports OHCI and
* USB on-the-go (OTG), currently neither are supported.
*
* CAUTION: This driver was written to run on the beaglebaord dev board, so I
* have made some assumptions about the type of PHY used and some of the other
* settings. Bare that in mind if you intend to use this driver on another
* platform.
*
* NOTE: This module uses a few different clocks, one being a 60Mhz clock for
* the TTL part of the module. This clock is derived from DPPL5 which must be
* configured prior to loading this driver - it is not configured by the
* bootloader. It took me a long time to figure this out, and caused much
* frustration. This PLL is now setup in the timer/clocks part of the BSP,
* check out the omap_prcm_setup_dpll5() function in omap_prcm.c for more info.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bus.h"
#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/conf.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/linker_set.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/condvar.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/unistd.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/gpio.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/fdt/simplebus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/usb/usb.h>
@ -98,80 +53,83 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/controller/ehci.h>
#include <dev/usb/controller/ehcireg.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_scm.h>
#include <machine/bus.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/usb/omap_usb.h>
#include "gpio_if.h"
/* EHCI */
#define OMAP_USBHOST_HCCAPBASE 0x0000
#define OMAP_USBHOST_HCSPARAMS 0x0004
#define OMAP_USBHOST_HCCPARAMS 0x0008
#define OMAP_USBHOST_USBCMD 0x0010
#define OMAP_USBHOST_USBSTS 0x0014
#define OMAP_USBHOST_USBINTR 0x0018
#define OMAP_USBHOST_FRINDEX 0x001C
#define OMAP_USBHOST_CTRLDSSEGMENT 0x0020
#define OMAP_USBHOST_PERIODICLISTBASE 0x0024
#define OMAP_USBHOST_ASYNCLISTADDR 0x0028
#define OMAP_USBHOST_CONFIGFLAG 0x0050
#define OMAP_USBHOST_PORTSC(i) (0x0054 + (0x04 * (i)))
#define OMAP_USBHOST_INSNREG00 0x0090
#define OMAP_USBHOST_INSNREG01 0x0094
#define OMAP_USBHOST_INSNREG02 0x0098
#define OMAP_USBHOST_INSNREG03 0x009C
#define OMAP_USBHOST_INSNREG04 0x00A0
#define OMAP_USBHOST_INSNREG05_UTMI 0x00A4
#define OMAP_USBHOST_INSNREG05_ULPI 0x00A4
#define OMAP_USBHOST_INSNREG06 0x00A8
#define OMAP_USBHOST_INSNREG07 0x00AC
#define OMAP_USBHOST_INSNREG08 0x00B0
#define OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
#define OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT 31
#define OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT 24
#define OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT 22
#define OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT 16
#define OMAP_USBHOST_INSNREG05_ULPI_EXTREGADD_SHIFT 8
#define OMAP_USBHOST_INSNREG05_ULPI_WRDATA_SHIFT 0
#define ULPI_FUNC_CTRL_RESET (1 << 5)
/*-------------------------------------------------------------------------*/
/*
* Macros for Set and Clear
* See ULPI 1.1 specification to find the registers with Set and Clear offsets
*/
#define ULPI_SET(a) (a + 1)
#define ULPI_CLR(a) (a + 2)
/*-------------------------------------------------------------------------*/
/*
* Register Map
*/
#define ULPI_VENDOR_ID_LOW 0x00
#define ULPI_VENDOR_ID_HIGH 0x01
#define ULPI_PRODUCT_ID_LOW 0x02
#define ULPI_PRODUCT_ID_HIGH 0x03
#define ULPI_FUNC_CTRL 0x04
#define ULPI_IFC_CTRL 0x07
#define ULPI_OTG_CTRL 0x0a
#define ULPI_USB_INT_EN_RISE 0x0d
#define ULPI_USB_INT_EN_FALL 0x10
#define ULPI_USB_INT_STS 0x13
#define ULPI_USB_INT_LATCH 0x14
#define ULPI_DEBUG 0x15
#define ULPI_SCRATCH 0x16
#define OMAP_EHCI_HC_DEVSTR "TI OMAP USB 2.0 controller"
struct omap_ehci_softc {
ehci_softc_t base; /* storage for EHCI code */
device_t sc_dev;
device_t sc_gpio_dev;
/* TLL register set */
struct resource* tll_mem_res;
/* UHH register set */
struct resource* uhh_mem_res;
/* The revision of the HS USB HOST read from UHH_REVISION */
uint32_t ehci_rev;
/* The following details are provided by conf hints */
int port_mode[3];
int phy_reset[3];
int reset_gpio_pin[3];
};
static device_attach_t omap_ehci_attach;
static device_detach_t omap_ehci_detach;
static device_shutdown_t omap_ehci_shutdown;
static device_suspend_t omap_ehci_suspend;
static device_resume_t omap_ehci_resume;
/**
* omap_tll_read_4 - read a 32-bit value from the USBTLL registers
* omap_tll_write_4 - write a 32-bit value from the USBTLL registers
* omap_tll_readb - read an 8-bit value from the USBTLL registers
* omap_tll_writeb - write an 8-bit value from the USBTLL registers
* @sc: omap ehci device context
* @off: byte offset within the register set to read from
* @val: the value to write into the register
*
*
* LOCKING:
* None
*
* RETURNS:
* nothing in case of write function, if read function returns the value read.
*/
static inline uint32_t
omap_tll_read_4(struct omap_ehci_softc *sc, bus_size_t off)
{
return bus_read_4(sc->tll_mem_res, off);
}
static inline void
omap_tll_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->tll_mem_res, off, val);
}
static inline uint8_t
omap_tll_readb(struct omap_ehci_softc *sc, bus_size_t off)
{
return bus_read_1(sc->tll_mem_res, off);
}
static inline void
omap_tll_writeb(struct omap_ehci_softc *sc, bus_size_t off, uint8_t val)
{
bus_write_1(sc->tll_mem_res, off, val);
}
/**
* omap_ehci_read_4 - read a 32-bit value from the EHCI registers
@ -192,92 +150,13 @@ omap_ehci_read_4(struct omap_ehci_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->base.sc_io_res, off));
}
static inline void
omap_ehci_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->base.sc_io_res, off, val);
}
/**
* omap_uhh_read_4 - read a 32-bit value from the UHH registers
* omap_uhh_write_4 - write a 32-bit value from the UHH registers
* @sc: omap ehci device context
* @off: byte offset within the register set to read from
* @val: the value to write into the register
*
*
* LOCKING:
* None
*
* RETURNS:
* nothing in case of write function, if read function returns the value read.
*/
static inline uint32_t
omap_uhh_read_4(struct omap_ehci_softc *sc, bus_size_t off)
{
return bus_read_4(sc->uhh_mem_res, off);
}
static inline void
omap_uhh_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->uhh_mem_res, off, val);
}
/**
* omap_ehci_utmi_init - initialises the UTMI part of the controller
* @isc: omap ehci device context
*
*
*
* LOCKING:
* none
*
* RETURNS:
* nothing
*/
static void
omap_ehci_utmi_init(struct omap_ehci_softc *isc, unsigned int en_mask)
{
unsigned int i;
uint32_t reg;
/* There are 3 TLL channels, one per USB controller so set them all up the
* same, SDR mode, bit stuffing and no autoidle.
*/
for (i=0; i<3; i++) {
reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
| TLL_CHANNEL_CONF_ULPINOBITSTUFF
| TLL_CHANNEL_CONF_ULPIDDRMODE);
omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
}
/* Program the common TLL register */
reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_SHARED_CONF);
reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
| TLL_SHARED_CONF_USB_DIVRATIO_MASK);
reg |= ( TLL_SHARED_CONF_FCLK_IS_ON
| TLL_SHARED_CONF_USB_DIVRATIO_2
| TLL_SHARED_CONF_USB_180D_SDR_EN);
omap_tll_write_4(isc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
/* Enable channels now */
for (i = 0; i < 3; i++) {
reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
/* Enable only the reg that is needed */
if ((en_mask & (1 << i)) == 0)
continue;
reg |= TLL_CHANNEL_CONF_CHANEN;
omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
}
}
/**
* omap_ehci_soft_phy_reset - resets the phy using the reset command
* @isc: omap ehci device context
@ -321,7 +200,6 @@ omap_ehci_soft_phy_reset(struct omap_ehci_softc *isc, unsigned int port)
}
}
}
/**
* omap_ehci_init - initialises the USB host EHCI controller
@ -340,216 +218,12 @@ omap_ehci_soft_phy_reset(struct omap_ehci_softc *isc, unsigned int port)
static int
omap_ehci_init(struct omap_ehci_softc *isc)
{
unsigned long timeout;
int ret = 0;
uint8_t tll_ch_mask = 0;
uint32_t reg = 0;
int reset_performed = 0;
int i;
device_t uhh_dev;
uhh_dev = device_get_parent(isc->sc_dev);
device_printf(isc->sc_dev, "Starting TI EHCI USB Controller\n");
/* Enable Clocks for high speed USBHOST */
ti_prcm_clk_enable(USBHSHOST_CLK);
/* Hold the PHY in reset while configuring */
for (int i = 0; i < 3; i++) {
if (isc->phy_reset[i]) {
/* Configure the GPIO to drive low (hold in reset) */
if ((isc->reset_gpio_pin[i] != -1) && (isc->sc_gpio_dev != NULL)) {
GPIO_PIN_SETFLAGS(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
GPIO_PIN_OUTPUT);
GPIO_PIN_SET(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
GPIO_PIN_LOW);
reset_performed = 1;
}
}
}
/* Hold the PHY in RESET for enough time till DIR is high */
if (reset_performed)
DELAY(10);
/* Read the UHH revision */
isc->ehci_rev = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_REVISION);
device_printf(isc->sc_dev, "UHH revision 0x%08x\n", isc->ehci_rev);
/* Initilise the low level interface module(s) */
if (isc->ehci_rev == OMAP_EHCI_REV1) {
/* Enable the USB TLL */
ti_prcm_clk_enable(USBTLL_CLK);
/* Perform TLL soft reset, and wait until reset is complete */
omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
/* Set the timeout to 100ms*/
timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
/* Wait for TLL reset to complete */
while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) &
TLL_SYSSTATUS_RESETDONE) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(isc->sc_dev, "TLL reset operation timed out\n");
ret = EINVAL;
goto err_sys_status;
}
}
device_printf(isc->sc_dev, "TLL RESET DONE\n");
/* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
* SIDLEMODE = 2 : Smart-idle mode. Sidleack asserted after Idlereq
* assertion when no more activity on the USB.
* ENAWAKEUP = 1 : Wakeup generation enabled
*/
omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
TLL_SYSCONFIG_AUTOIDLE |
TLL_SYSCONFIG_SIDLE_SMART_IDLE |
TLL_SYSCONFIG_CACTIVITY);
} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
/* For OMAP44xx devices you have to enable the per-port clocks:
* PHY_MODE - External ULPI clock
* TTL_MODE - Internal UTMI clock
* HSIC_MODE - Internal 480Mhz and 60Mhz clocks
*/
if (isc->ehci_rev == OMAP_EHCI_REV2) {
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) {
ti_prcm_clk_set_source(USBP1_PHY_CLK, EXT_CLK);
ti_prcm_clk_enable(USBP1_PHY_CLK);
} else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
ti_prcm_clk_enable(USBP1_UTMI_CLK);
else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
ti_prcm_clk_enable(USBP1_HSIC_CLK);
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) {
ti_prcm_clk_set_source(USBP2_PHY_CLK, EXT_CLK);
ti_prcm_clk_enable(USBP2_PHY_CLK);
} else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
ti_prcm_clk_enable(USBP2_UTMI_CLK);
else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
ti_prcm_clk_enable(USBP2_HSIC_CLK);
}
}
/* Put UHH in SmartIdle/SmartStandby mode */
reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSCONFIG);
if (isc->ehci_rev == OMAP_EHCI_REV1) {
reg &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK |
UHH_SYSCONFIG_MIDLEMODE_MASK);
reg |= (UHH_SYSCONFIG_ENAWAKEUP |
UHH_SYSCONFIG_AUTOIDLE |
UHH_SYSCONFIG_CLOCKACTIVITY |
UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE |
UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY);
} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
reg &= ~UHH_SYSCONFIG_IDLEMODE_MASK;
reg |= UHH_SYSCONFIG_IDLEMODE_NOIDLE;
reg &= ~UHH_SYSCONFIG_STANDBYMODE_MASK;
reg |= UHH_SYSCONFIG_STANDBYMODE_NOSTDBY;
}
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, reg);
device_printf(isc->sc_dev, "OMAP_UHH_SYSCONFIG: 0x%08x\n", reg);
reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG);
/* Setup ULPI bypass and burst configurations */
reg |= (UHH_HOSTCONFIG_ENA_INCR4 |
UHH_HOSTCONFIG_ENA_INCR8 |
UHH_HOSTCONFIG_ENA_INCR16);
reg &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
if (isc->ehci_rev == OMAP_EHCI_REV1) {
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS;
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS;
if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS;
/* Bypass the TLL module for PHY mode operation */
if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
(isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
(isc->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
reg &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS;
else
reg |= UHH_HOSTCONFIG_P1_ULPI_BYPASS;
} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
reg |= UHH_HOSTCONFIG_APP_START_CLK;
/* Clear port mode fields for PHY mode*/
reg &= ~UHH_HOSTCONFIG_P1_MODE_MASK;
reg &= ~UHH_HOSTCONFIG_P2_MODE_MASK;
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
reg |= UHH_HOSTCONFIG_P1_MODE_UTMI_PHY;
else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
reg |= UHH_HOSTCONFIG_P1_MODE_HSIC;
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
reg |= UHH_HOSTCONFIG_P2_MODE_UTMI_PHY;
else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
reg |= UHH_HOSTCONFIG_P2_MODE_HSIC;
}
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG, reg);
device_printf(isc->sc_dev, "UHH setup done, uhh_hostconfig=0x%08x\n", reg);
/* I found the code and comments in the Linux EHCI driver - thanks guys :)
*
* "An undocumented "feature" in the OMAP3 EHCI controller, causes suspended
* ports to be taken out of suspend when the USBCMD.Run/Stop bit is cleared
* (for example when we do ehci_bus_suspend). This breaks suspend-resume if
* the root-hub is allowed to suspend. Writing 1 to this undocumented
* register bit disables this feature and restores normal behavior."
*/
#if 0
omap_ehci_write_4(isc, OMAP_USBHOST_INSNREG04,
OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND);
#endif
/* If any of the ports are configured in TLL mode, enable them */
if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ||
(isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ||
(isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) {
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
tll_ch_mask |= 0x1;
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
tll_ch_mask |= 0x2;
if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
tll_ch_mask |= 0x4;
/* Enable UTMI mode for required TLL channels */
omap_ehci_utmi_init(isc, tll_ch_mask);
}
/* Release the PHY reset signal now we have configured everything */
if (reset_performed) {
/* Delay for 10ms */
DELAY(10000);
for (i = 0; i < 3; i++) {
/* Release reset */
if (isc->phy_reset[i] && (isc->reset_gpio_pin[i] != -1)
&& (isc->sc_gpio_dev != NULL)) {
GPIO_PIN_SET(isc->sc_gpio_dev,
isc->reset_gpio_pin[i], GPIO_PIN_HIGH);
}
}
}
/* Set the interrupt threshold control, it controls the maximum rate at
* which the host controller issues interrupts. We set it to 1 microframe
@ -561,166 +235,15 @@ omap_ehci_init(struct omap_ehci_softc *isc)
omap_ehci_write_4(isc, OMAP_USBHOST_USBCMD, reg);
/* Soft reset the PHY using PHY reset command over ULPI */
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
omap_ehci_soft_phy_reset(isc, 0);
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
omap_ehci_soft_phy_reset(isc, 1);
for (i = 0; i < OMAP_HS_USB_PORTS; i++) {
if (omap_usb_port_mode(uhh_dev, i) == EHCI_HCD_OMAP_MODE_PHY)
omap_ehci_soft_phy_reset(isc, i);
}
return(0);
err_sys_status:
/* Disable the TLL clocks */
ti_prcm_clk_disable(USBTLL_CLK);
/* Disable Clocks for USBHOST */
ti_prcm_clk_disable(USBHSHOST_CLK);
return(ret);
}
/**
* omap_ehci_fini - shutdown the EHCI controller
* @isc: omap ehci device context
*
*
*
* LOCKING:
* none
*
* RETURNS:
* 0 on success, a negative error code on failure.
*/
static void
omap_ehci_fini(struct omap_ehci_softc *isc)
{
unsigned long timeout;
device_printf(isc->sc_dev, "Stopping TI EHCI USB Controller\n");
/* Set the timeout */
if (hz < 10)
timeout = 1;
else
timeout = (100 * hz) / 1000;
/* Reset the UHH, OHCI and EHCI modules */
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, 0x0002);
while ((omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSSTATUS) & 0x07) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(isc->sc_dev, "operation timed out\n");
break;
}
}
/* Set the timeout */
if (hz < 10)
timeout = 1;
else
timeout = (100 * hz) / 1000;
/* Reset the TLL module */
omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, 0x0002);
while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(isc->sc_dev, "operation timed out\n");
break;
}
}
/* Disable functional and interface clocks for the TLL and HOST modules */
ti_prcm_clk_disable(USBTLL_CLK);
ti_prcm_clk_disable(USBHSHOST_CLK);
device_printf(isc->sc_dev, "Clock to USB host has been disabled\n");
}
/**
* omap_ehci_suspend - suspends the bus
* @dev: omap ehci device
*
* Effectively boilerplate EHCI suspend code.
*
* TODO: There is a lot more we could do here - i.e. force the controller into
* idle mode and disable all the clocks for start.
*
* LOCKING:
* none
*
* RETURNS:
* 0 on success or a positive error code
*/
static int
omap_ehci_suspend(device_t dev)
{
int err;
err = bus_generic_suspend(dev);
if (err)
return (err);
return (0);
}
/**
* omap_ehci_resume - resumes a suspended bus
* @dev: omap ehci device
*
* Effectively boilerplate EHCI resume code.
*
* LOCKING:
* none
*
* RETURNS:
* 0 on success or a positive error code on failure
*/
static int
omap_ehci_resume(device_t dev)
{
bus_generic_resume(dev);
return (0);
}
/**
* omap_ehci_shutdown - starts the given command
* @dev:
*
* Effectively boilerplate EHCI shutdown code.
*
* LOCKING:
* none.
*
* RETURNS:
* 0 on success or a positive error code on failure
*/
static int
omap_ehci_shutdown(device_t dev)
{
int err;
err = bus_generic_shutdown(dev);
if (err)
return (err);
return (0);
}
/**
* omap_ehci_probe - starts the given command
* @dev:
@ -740,7 +263,7 @@ omap_ehci_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,usb-ehci"))
if (!ofw_bus_is_compatible(dev, "ti,ehci-omap"))
return (ENXIO);
device_set_desc(dev, OMAP_EHCI_HC_DEVSTR);
@ -766,15 +289,9 @@ static int
omap_ehci_attach(device_t dev)
{
struct omap_ehci_softc *isc = device_get_softc(dev);
phandle_t node;
/* 3 ports with 3 cells per port */
pcell_t phyconf[3 * 3];
pcell_t *phyconf_ptr;
ehci_softc_t *sc = &isc->base;
int err;
int rid;
int len, tuple_size;
int i;
/* initialise some bus fields */
sc->sc_bus.parent = dev;
@ -782,6 +299,8 @@ omap_ehci_attach(device_t dev)
sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
sc->sc_bus.dma_bits = 32;
sprintf(sc->sc_vendor, "Texas Instruments");
/* save the device */
isc->sc_dev = dev;
@ -791,16 +310,6 @@ omap_ehci_attach(device_t dev)
return (ENOMEM);
}
/* When the EHCI driver is added to the tree it is expected that 3
* memory resources and 1 interrupt resource is assigned. The memory
* resources should be:
* 0 => EHCI register range
* 1 => UHH register range
* 2 => TLL register range
*
* The interrupt resource is just the single interupt for the controller.
*/
/* Allocate resource for the EHCI register set */
rid = 0;
sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
@ -816,21 +325,6 @@ omap_ehci_attach(device_t dev)
goto error;
}
/* Allocate resource for the UHH register set */
rid = 1;
isc->uhh_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!isc->uhh_mem_res) {
device_printf(dev, "Error: Could not map UHH memory\n");
goto error;
}
/* Allocate resource for the TLL register set */
rid = 2;
isc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!isc->tll_mem_res) {
device_printf(dev, "Error: Could not map TLL memory\n");
goto error;
}
/* Add this device as a child of the USBus device */
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!sc->sc_bus.bdev) {
@ -841,44 +335,6 @@ omap_ehci_attach(device_t dev)
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
device_set_desc(sc->sc_bus.bdev, OMAP_EHCI_HC_DEVSTR);
/* Set the vendor name */
sprintf(sc->sc_vendor, "Texas Instruments");
/* Get the GPIO device, we may need this if the driver needs to toggle
* some pins for external PHY resets.
*/
isc->sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
if (isc->sc_gpio_dev == NULL) {
device_printf(dev, "Error: failed to get the GPIO device\n");
goto error;
}
/* Set the defaults for the hints */
for (i = 0; i < 3; i++) {
isc->phy_reset[i] = 0;
isc->port_mode[i] = EHCI_HCD_OMAP_MODE_UNKNOWN;
isc->reset_gpio_pin[i] = -1;
}
tuple_size = sizeof(pcell_t) * 3;
node = ofw_bus_get_node(dev);
len = OF_getprop(node, "phy-config", phyconf, sizeof(phyconf));
if (len > 0) {
if (len % tuple_size)
goto error;
if ((len / tuple_size) != 3)
goto error;
phyconf_ptr = phyconf;
for (i = 0; i < 3; i++) {
isc->port_mode[i] = fdt32_to_cpu(*phyconf_ptr);
isc->phy_reset[i] = fdt32_to_cpu(*(phyconf_ptr + 1));
isc->reset_gpio_pin[i] = fdt32_to_cpu(*(phyconf_ptr + 2));
phyconf_ptr += 3;
}
}
/* Initialise the ECHI registers */
err = omap_ehci_init(isc);
if (err) {
@ -886,13 +342,11 @@ omap_ehci_attach(device_t dev)
goto error;
}
/* Set the tag and size of the register set in the EHCI context */
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
/* Setup the interrupt */
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
@ -902,7 +356,6 @@ omap_ehci_attach(device_t dev)
goto error;
}
/* Finally we are ready to kick off the ECHI host controller */
err = ehci_init(sc);
if (err == 0) {
@ -980,20 +433,6 @@ omap_ehci_detach(device_t dev)
sc->sc_io_res = NULL;
}
/* Release the other register set memory maps */
if (isc->tll_mem_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->tll_mem_res);
isc->tll_mem_res = NULL;
}
if (isc->uhh_mem_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->uhh_mem_res);
isc->uhh_mem_res = NULL;
}
usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
omap_ehci_fini(isc);
return (0);
}
@ -1002,9 +441,10 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, omap_ehci_probe),
DEVMETHOD(device_attach, omap_ehci_attach),
DEVMETHOD(device_detach, omap_ehci_detach),
DEVMETHOD(device_suspend, omap_ehci_suspend),
DEVMETHOD(device_resume, omap_ehci_resume),
DEVMETHOD(device_shutdown, omap_ehci_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
@ -1020,4 +460,4 @@ static driver_t ehci_driver = {
static devclass_t ehci_devclass;
DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
DRIVER_MODULE(ehci, omap_uhh, ehci_driver, ehci_devclass, 0, 0);

466
sys/arm/ti/usb/omap_host.c Normal file
View File

@ -0,0 +1,466 @@
/*-
* Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/rman.h>
#include <sys/module.h>
#include <dev/fdt/fdt_common.h>
#include <dev/fdt/simplebus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/usb/omap_usb.h>
/*
* USB Host Module
*/
/* UHH */
#define OMAP_USBHOST_UHH_REVISION 0x0000
#define OMAP_USBHOST_UHH_SYSCONFIG 0x0010
#define OMAP_USBHOST_UHH_SYSSTATUS 0x0014
#define OMAP_USBHOST_UHH_HOSTCONFIG 0x0040
#define OMAP_USBHOST_UHH_DEBUG_CSR 0x0044
/* UHH Register Set */
#define UHH_SYSCONFIG_MIDLEMODE_MASK (3UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY (2UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_NOSTANDBY (1UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_FORCESTANDBY (0UL << 12)
#define UHH_SYSCONFIG_CLOCKACTIVITY (1UL << 8)
#define UHH_SYSCONFIG_SIDLEMODE_MASK (3UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE (2UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_NOIDLE (1UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_FORCEIDLE (0UL << 3)
#define UHH_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define UHH_SYSCONFIG_SOFTRESET (1UL << 1)
#define UHH_SYSCONFIG_AUTOIDLE (1UL << 0)
#define UHH_HOSTCONFIG_APP_START_CLK (1UL << 31)
#define UHH_HOSTCONFIG_P3_CONNECT_STATUS (1UL << 10)
#define UHH_HOSTCONFIG_P2_CONNECT_STATUS (1UL << 9)
#define UHH_HOSTCONFIG_P1_CONNECT_STATUS (1UL << 8)
#define UHH_HOSTCONFIG_ENA_INCR_ALIGN (1UL << 5)
#define UHH_HOSTCONFIG_ENA_INCR16 (1UL << 4)
#define UHH_HOSTCONFIG_ENA_INCR8 (1UL << 3)
#define UHH_HOSTCONFIG_ENA_INCR4 (1UL << 2)
#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN (1UL << 1)
#define UHH_HOSTCONFIG_P1_ULPI_BYPASS (1UL << 0)
/* The following are on rev2 (OMAP44xx) of the EHCI only */
#define UHH_SYSCONFIG_IDLEMODE_MASK (3UL << 2)
#define UHH_SYSCONFIG_IDLEMODE_NOIDLE (1UL << 2)
#define UHH_SYSCONFIG_STANDBYMODE_MASK (3UL << 4)
#define UHH_SYSCONFIG_STANDBYMODE_NOSTDBY (1UL << 4)
#define UHH_HOSTCONFIG_P1_MODE_MASK (3UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_ULPI_PHY (0UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_UTMI_PHY (1UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_HSIC (3UL << 16)
#define UHH_HOSTCONFIG_P2_MODE_MASK (3UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_ULPI_PHY (0UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_UTMI_PHY (1UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_HSIC (3UL << 18)
/*
* Values of UHH_REVISION - Note: these are not given in the TRM but taken
* from the linux OMAP EHCI driver (thanks guys). It has been verified on
* a Panda and Beagle board.
*/
#define OMAP_UHH_REV1 0x00000010 /* OMAP3 */
#define OMAP_UHH_REV2 0x50700100 /* OMAP4 */
struct omap_uhh_softc {
struct simplebus_softc simplebus_sc;
device_t sc_dev;
/* UHH register set */
struct resource* uhh_mem_res;
/* The revision of the HS USB HOST read from UHH_REVISION */
uint32_t uhh_rev;
/* The following details are provided by conf hints */
int port_mode[3];
};
static device_attach_t omap_uhh_attach;
static device_detach_t omap_uhh_detach;
static inline uint32_t
omap_uhh_read_4(struct omap_uhh_softc *sc, bus_size_t off)
{
return bus_read_4(sc->uhh_mem_res, off);
}
static inline void
omap_uhh_write_4(struct omap_uhh_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->uhh_mem_res, off, val);
}
static int
omap_uhh_init(struct omap_uhh_softc *isc)
{
uint8_t tll_ch_mask;
uint32_t reg;
int i;
/* Enable Clocks for high speed USBHOST */
ti_prcm_clk_enable(USBHSHOST_CLK);
/* Read the UHH revision */
isc->uhh_rev = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_REVISION);
device_printf(isc->sc_dev, "UHH revision 0x%08x\n", isc->uhh_rev);
if (isc->uhh_rev == OMAP_UHH_REV2) {
/* For OMAP44xx devices you have to enable the per-port clocks:
* PHY_MODE - External ULPI clock
* TTL_MODE - Internal UTMI clock
* HSIC_MODE - Internal 480Mhz and 60Mhz clocks
*/
switch(isc->port_mode[0]) {
case EHCI_HCD_OMAP_MODE_UNKNOWN:
break;
case EHCI_HCD_OMAP_MODE_PHY:
if (ti_prcm_clk_set_source(USBP1_PHY_CLK, EXT_CLK))
device_printf(isc->sc_dev,
"failed to set clock source for port 0\n");
if (ti_prcm_clk_enable(USBP1_PHY_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP1_PHY_CLK source for port 0\n");
break;
case EHCI_HCD_OMAP_MODE_TLL:
if (ti_prcm_clk_enable(USBP1_UTMI_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP1_PHY_CLK source for port 0\n");
break;
case EHCI_HCD_OMAP_MODE_HSIC:
if (ti_prcm_clk_enable(USBP1_HSIC_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP1_PHY_CLK source for port 0\n");
break;
default:
device_printf(isc->sc_dev, "unknown port mode %d for port 0\n", isc->port_mode[0]);
}
switch(isc->port_mode[1]) {
case EHCI_HCD_OMAP_MODE_UNKNOWN:
break;
case EHCI_HCD_OMAP_MODE_PHY:
if (ti_prcm_clk_set_source(USBP2_PHY_CLK, EXT_CLK))
device_printf(isc->sc_dev,
"failed to set clock source for port 0\n");
if (ti_prcm_clk_enable(USBP2_PHY_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP2_PHY_CLK source for port 1\n");
break;
case EHCI_HCD_OMAP_MODE_TLL:
if (ti_prcm_clk_enable(USBP2_UTMI_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP2_UTMI_CLK source for port 1\n");
break;
case EHCI_HCD_OMAP_MODE_HSIC:
if (ti_prcm_clk_enable(USBP2_HSIC_CLK))
device_printf(isc->sc_dev,
"failed to set clock USBP2_HSIC_CLK source for port 1\n");
break;
default:
device_printf(isc->sc_dev, "unknown port mode %d for port 1\n", isc->port_mode[1]);
}
}
/* Put UHH in SmartIdle/SmartStandby mode */
reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSCONFIG);
if (isc->uhh_rev == OMAP_UHH_REV1) {
reg &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK |
UHH_SYSCONFIG_MIDLEMODE_MASK);
reg |= (UHH_SYSCONFIG_ENAWAKEUP |
UHH_SYSCONFIG_AUTOIDLE |
UHH_SYSCONFIG_CLOCKACTIVITY |
UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE |
UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY);
} else if (isc->uhh_rev == OMAP_UHH_REV2) {
reg &= ~UHH_SYSCONFIG_IDLEMODE_MASK;
reg |= UHH_SYSCONFIG_IDLEMODE_NOIDLE;
reg &= ~UHH_SYSCONFIG_STANDBYMODE_MASK;
reg |= UHH_SYSCONFIG_STANDBYMODE_NOSTDBY;
}
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, reg);
device_printf(isc->sc_dev, "OMAP_UHH_SYSCONFIG: 0x%08x\n", reg);
reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG);
/* Setup ULPI bypass and burst configurations */
reg |= (UHH_HOSTCONFIG_ENA_INCR4 |
UHH_HOSTCONFIG_ENA_INCR8 |
UHH_HOSTCONFIG_ENA_INCR16);
reg &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
if (isc->uhh_rev == OMAP_UHH_REV1) {
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS;
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS;
if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
reg &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS;
/* Bypass the TLL module for PHY mode operation */
if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
(isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
(isc->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
reg &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS;
else
reg |= UHH_HOSTCONFIG_P1_ULPI_BYPASS;
} else if (isc->uhh_rev == OMAP_UHH_REV2) {
reg |= UHH_HOSTCONFIG_APP_START_CLK;
/* Clear port mode fields for PHY mode*/
reg &= ~UHH_HOSTCONFIG_P1_MODE_MASK;
reg &= ~UHH_HOSTCONFIG_P2_MODE_MASK;
if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
reg |= UHH_HOSTCONFIG_P1_MODE_UTMI_PHY;
else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
reg |= UHH_HOSTCONFIG_P1_MODE_HSIC;
if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
reg |= UHH_HOSTCONFIG_P2_MODE_UTMI_PHY;
else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
reg |= UHH_HOSTCONFIG_P2_MODE_HSIC;
}
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG, reg);
device_printf(isc->sc_dev, "UHH setup done, uhh_hostconfig=0x%08x\n", reg);
/* I found the code and comments in the Linux EHCI driver - thanks guys :)
*
* "An undocumented "feature" in the OMAP3 EHCI controller, causes suspended
* ports to be taken out of suspend when the USBCMD.Run/Stop bit is cleared
* (for example when we do omap_uhh_bus_suspend). This breaks suspend-resume if
* the root-hub is allowed to suspend. Writing 1 to this undocumented
* register bit disables this feature and restores normal behavior."
*/
#if 0
omap_uhh_write_4(isc, OMAP_USBHOST_INSNREG04,
OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND);
#endif
tll_ch_mask = 0;
for (i = 0; i < OMAP_HS_USB_PORTS; i++) {
if (isc->port_mode[i] == EHCI_HCD_OMAP_MODE_TLL)
tll_ch_mask |= (1 << i);
}
if (tll_ch_mask)
omap_tll_utmi_enable(tll_ch_mask);
return(0);
}
/**
* omap_uhh_fini - shutdown the EHCI controller
* @isc: omap ehci device context
*
*
*
* LOCKING:
* none
*
* RETURNS:
* 0 on success, a negative error code on failure.
*/
static void
omap_uhh_fini(struct omap_uhh_softc *isc)
{
unsigned long timeout;
device_printf(isc->sc_dev, "Stopping TI EHCI USB Controller\n");
/* Set the timeout */
if (hz < 10)
timeout = 1;
else
timeout = (100 * hz) / 1000;
/* Reset the UHH, OHCI and EHCI modules */
omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, 0x0002);
while ((omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSSTATUS) & 0x07) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(isc->sc_dev, "operation timed out\n");
break;
}
}
/* Disable functional and interface clocks for the TLL and HOST modules */
ti_prcm_clk_disable(USBHSHOST_CLK);
device_printf(isc->sc_dev, "Clock to USB host has been disabled\n");
}
int
omap_usb_port_mode(device_t dev, int port)
{
struct omap_uhh_softc *isc;
isc = device_get_softc(dev);
if ((port < 0) || (port >= OMAP_HS_USB_PORTS))
return (-1);
return isc->port_mode[port];
}
static int
omap_uhh_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,usbhs-host"))
return (ENXIO);
device_set_desc(dev, "TI OMAP USB 2.0 Host module");
return (BUS_PROBE_DEFAULT);
}
static int
omap_uhh_attach(device_t dev)
{
struct omap_uhh_softc *isc = device_get_softc(dev);
int err;
int rid;
int i;
phandle_t node;
char propname[16];
char *mode;
/* save the device */
isc->sc_dev = dev;
/* Allocate resource for the UHH register set */
rid = 0;
isc->uhh_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!isc->uhh_mem_res) {
device_printf(dev, "Error: Could not map UHH memory\n");
goto error;
}
node = ofw_bus_get_node(dev);
if (node == -1)
goto error;
/* Get port modes from FDT */
for (i = 0; i < OMAP_HS_USB_PORTS; i++) {
isc->port_mode[i] = EHCI_HCD_OMAP_MODE_UNKNOWN;
snprintf(propname, sizeof(propname),
"port%d-mode", i+1);
if (OF_getprop_alloc(node, propname, 1, (void**)&mode) <= 0)
continue;
if (strcmp(mode, "ehci-phy") == 0)
isc->port_mode[i] = EHCI_HCD_OMAP_MODE_PHY;
else if (strcmp(mode, "ehci-tll") == 0)
isc->port_mode[i] = EHCI_HCD_OMAP_MODE_TLL;
else if (strcmp(mode, "ehci-hsic") == 0)
isc->port_mode[i] = EHCI_HCD_OMAP_MODE_HSIC;
}
/* Initialise the ECHI registers */
err = omap_uhh_init(isc);
if (err) {
device_printf(dev, "Error: could not setup OMAP EHCI, %d\n", err);
goto error;
}
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));
error:
omap_uhh_detach(dev);
return (ENXIO);
}
static int
omap_uhh_detach(device_t dev)
{
struct omap_uhh_softc *isc = device_get_softc(dev);
/* during module unload there are lots of children leftover */
device_delete_children(dev);
if (isc->uhh_mem_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->uhh_mem_res);
isc->uhh_mem_res = NULL;
}
omap_uhh_fini(isc);
return (0);
}
static device_method_t omap_uhh_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, omap_uhh_probe),
DEVMETHOD(device_attach, omap_uhh_attach),
DEVMETHOD(device_detach, omap_uhh_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
DEFINE_CLASS_1(omap_uhh, omap_uhh_driver, omap_uhh_methods,
sizeof(struct omap_uhh_softc), simplebus_driver);
static devclass_t omap_uhh_devclass;
DRIVER_MODULE(omap_uhh, simplebus, omap_uhh_driver, omap_uhh_devclass, 0, 0);

364
sys/arm/ti/usb/omap_tll.c Normal file
View File

@ -0,0 +1,364 @@
/*-
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/rman.h>
#include <sys/module.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/usb/omap_usb.h>
/*
* USB TLL Module
*/
#define OMAP_USBTLL_REVISION 0x0000
#define OMAP_USBTLL_SYSCONFIG 0x0010
#define OMAP_USBTLL_SYSSTATUS 0x0014
#define OMAP_USBTLL_IRQSTATUS 0x0018
#define OMAP_USBTLL_IRQENABLE 0x001C
#define OMAP_USBTLL_TLL_SHARED_CONF 0x0030
#define OMAP_USBTLL_TLL_CHANNEL_CONF(i) (0x0040 + (0x04 * (i)))
#define OMAP_USBTLL_SAR_CNTX(i) (0x0400 + (0x04 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_LO(i) (0x0800 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_HI(i) (0x0801 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i) (0x0802 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i) (0x0803 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL(i) (0x0804 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i) (0x0805 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i) (0x0806 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL(i) (0x0807 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i) (0x0808 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i) (0x0809 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL(i) (0x080A + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_SET(i) (0x080B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i) (0x080C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i) (0x080D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i) (0x080E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i) (0x080F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i) (0x0810 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i) (0x0811 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i) (0x0812 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_STATUS(i) (0x0813 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH(i) (0x0814 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_DEBUG(i) (0x0815 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i) (0x0816 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i) (0x0817 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i) (0x0818 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i) (0x082F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i) (0x0830 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i) (0x0831 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i) (0x0832 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i) (0x0833 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i) (0x0834 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS(i) (0x0835 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i) (0x0836 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i) (0x0837 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i) (0x0838 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN(i) (0x083B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i) (0x083C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i) (0x083D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i) (0x083E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i) (0x083F + (0x100 * (i)))
/* TLL Register Set */
#define TLL_SYSCONFIG_CACTIVITY (1UL << 8)
#define TLL_SYSCONFIG_SIDLE_SMART_IDLE (2UL << 3)
#define TLL_SYSCONFIG_SIDLE_NO_IDLE (1UL << 3)
#define TLL_SYSCONFIG_SIDLE_FORCED_IDLE (0UL << 3)
#define TLL_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define TLL_SYSCONFIG_SOFTRESET (1UL << 1)
#define TLL_SYSCONFIG_AUTOIDLE (1UL << 0)
#define TLL_SYSSTATUS_RESETDONE (1UL << 0)
#define TLL_SHARED_CONF_USB_90D_DDR_EN (1UL << 6)
#define TLL_SHARED_CONF_USB_180D_SDR_EN (1UL << 5)
#define TLL_SHARED_CONF_USB_DIVRATIO_MASK (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_128 (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_64 (6UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_32 (5UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_16 (4UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_8 (3UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_4 (2UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_2 (1UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_1 (0UL << 2)
#define TLL_SHARED_CONF_FCLK_REQ (1UL << 1)
#define TLL_SHARED_CONF_FCLK_IS_ON (1UL << 0)
#define TLL_CHANNEL_CONF_DRVVBUS (1UL << 16)
#define TLL_CHANNEL_CONF_CHRGVBUS (1UL << 15)
#define TLL_CHANNEL_CONF_ULPINOBITSTUFF (1UL << 11)
#define TLL_CHANNEL_CONF_ULPIAUTOIDLE (1UL << 10)
#define TLL_CHANNEL_CONF_UTMIAUTOIDLE (1UL << 9)
#define TLL_CHANNEL_CONF_ULPIDDRMODE (1UL << 8)
#define TLL_CHANNEL_CONF_ULPIOUTCLKMODE (1UL << 7)
#define TLL_CHANNEL_CONF_TLLFULLSPEED (1UL << 6)
#define TLL_CHANNEL_CONF_TLLCONNECT (1UL << 5)
#define TLL_CHANNEL_CONF_TLLATTACH (1UL << 4)
#define TLL_CHANNEL_CONF_UTMIISADEV (1UL << 3)
#define TLL_CHANNEL_CONF_CHANEN (1UL << 0)
struct omap_tll_softc {
device_t sc_dev;
/* TLL register set */
struct resource* tll_mem_res;
int tll_mem_rid;
};
static struct omap_tll_softc *omap_tll_sc;
static int omap_tll_attach(device_t dev);
static int omap_tll_detach(device_t dev);
static inline uint32_t
omap_tll_read_4(struct omap_tll_softc *sc, bus_size_t off)
{
return bus_read_4(sc->tll_mem_res, off);
}
static inline void
omap_tll_write_4(struct omap_tll_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->tll_mem_res, off, val);
}
void
omap_tll_utmi_enable(unsigned int en_mask)
{
struct omap_tll_softc *sc;
unsigned int i;
uint32_t reg;
sc = omap_tll_sc;
if (sc == NULL)
return;
/* There are 3 TLL channels, one per USB controller so set them all up the
* same, SDR mode, bit stuffing and no autoidle.
*/
for (i=0; i<3; i++) {
reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
| TLL_CHANNEL_CONF_ULPINOBITSTUFF
| TLL_CHANNEL_CONF_ULPIDDRMODE);
omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
}
/* Program the common TLL register */
reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_SHARED_CONF);
reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
| TLL_SHARED_CONF_USB_DIVRATIO_MASK);
reg |= ( TLL_SHARED_CONF_FCLK_IS_ON
| TLL_SHARED_CONF_USB_DIVRATIO_2
| TLL_SHARED_CONF_USB_180D_SDR_EN);
omap_tll_write_4(sc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
/* Enable channels now */
for (i = 0; i < 3; i++) {
reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
/* Enable only the reg that is needed */
if ((en_mask & (1 << i)) == 0)
continue;
reg |= TLL_CHANNEL_CONF_CHANEN;
omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
}
}
static int
omap_tll_init(struct omap_tll_softc *sc)
{
unsigned long timeout;
int ret = 0;
/* Enable the USB TLL */
ti_prcm_clk_enable(USBTLL_CLK);
/* Perform TLL soft reset, and wait until reset is complete */
omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
/* Set the timeout to 100ms*/
timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
/* Wait for TLL reset to complete */
while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) &
TLL_SYSSTATUS_RESETDONE) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(sc->sc_dev, "TLL reset operation timed out\n");
ret = EINVAL;
goto err_sys_status;
}
}
/* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
* SIDLEMODE = 2 : Smart-idle mode. Sidleack asserted after Idlereq
* assertion when no more activity on the USB.
* ENAWAKEUP = 1 : Wakeup generation enabled
*/
omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
TLL_SYSCONFIG_AUTOIDLE |
TLL_SYSCONFIG_SIDLE_SMART_IDLE |
TLL_SYSCONFIG_CACTIVITY);
return(0);
err_sys_status:
/* Disable the TLL clocks */
ti_prcm_clk_disable(USBTLL_CLK);
return(ret);
}
static void
omap_tll_disable(struct omap_tll_softc *sc)
{
unsigned long timeout;
timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
/* Reset the TLL module */
omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, 0x0002);
while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
/* Sleep for a tick */
pause("USBRESET", 1);
if (timeout-- == 0) {
device_printf(sc->sc_dev, "operation timed out\n");
break;
}
}
/* Disable functional and interface clocks for the TLL and HOST modules */
ti_prcm_clk_disable(USBTLL_CLK);
}
static int
omap_tll_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,usbhs-tll"))
return (ENXIO);
device_set_desc(dev, "TI OMAP USB 2.0 TLL module");
return (BUS_PROBE_DEFAULT);
}
static int
omap_tll_attach(device_t dev)
{
struct omap_tll_softc *sc;
sc = device_get_softc(dev);
/* save the device */
sc->sc_dev = dev;
/* Allocate resource for the TLL register set */
sc->tll_mem_rid = 0;
sc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->tll_mem_rid, RF_ACTIVE);
if (!sc->tll_mem_res) {
device_printf(dev, "Error: Could not map TLL memory\n");
goto error;
}
omap_tll_init(sc);
omap_tll_sc = sc;
return (0);
error:
omap_tll_detach(dev);
return (ENXIO);
}
static int
omap_tll_detach(device_t dev)
{
struct omap_tll_softc *sc;
sc = device_get_softc(dev);
omap_tll_disable(sc);
/* Release the other register set memory maps */
if (sc->tll_mem_res) {
bus_release_resource(dev, SYS_RES_MEMORY,
sc->tll_mem_rid, sc->tll_mem_res);
sc->tll_mem_res = NULL;
}
omap_tll_sc = NULL;
return (0);
}
static device_method_t omap_tll_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, omap_tll_probe),
DEVMETHOD(device_attach, omap_tll_attach),
DEVMETHOD(device_detach, omap_tll_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{0, 0}
};
static driver_t omap_tll_driver = {
"omap_tll",
omap_tll_methods,
sizeof(struct omap_tll_softc),
};
static devclass_t omap_tll_devclass;
DRIVER_MODULE(omap_tll, simplebus, omap_tll_driver, omap_tll_devclass, 0, 0);

View File

@ -35,230 +35,14 @@
#ifndef _OMAP_USB_H_
#define _OMAP_USB_H_
/*
* USB TTL Module
*/
#define OMAP_USBTLL_REVISION 0x0000
#define OMAP_USBTLL_SYSCONFIG 0x0010
#define OMAP_USBTLL_SYSSTATUS 0x0014
#define OMAP_USBTLL_IRQSTATUS 0x0018
#define OMAP_USBTLL_IRQENABLE 0x001C
#define OMAP_USBTLL_TLL_SHARED_CONF 0x0030
#define OMAP_USBTLL_TLL_CHANNEL_CONF(i) (0x0040 + (0x04 * (i)))
#define OMAP_USBTLL_SAR_CNTX(i) (0x0400 + (0x04 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_LO(i) (0x0800 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_ID_HI(i) (0x0801 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i) (0x0802 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i) (0x0803 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL(i) (0x0804 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i) (0x0805 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i) (0x0806 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL(i) (0x0807 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i) (0x0808 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i) (0x0809 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL(i) (0x080A + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_SET(i) (0x080B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i) (0x080C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i) (0x080D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i) (0x080E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i) (0x080F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i) (0x0810 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i) (0x0811 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i) (0x0812 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_STATUS(i) (0x0813 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH(i) (0x0814 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_DEBUG(i) (0x0815 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i) (0x0816 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i) (0x0817 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i) (0x0818 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i) (0x082F + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i) (0x0830 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i) (0x0831 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i) (0x0832 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i) (0x0833 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i) (0x0834 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS(i) (0x0835 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i) (0x0836 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i) (0x0837 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i) (0x0838 + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN(i) (0x083B + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i) (0x083C + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i) (0x083D + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i) (0x083E + (0x100 * (i)))
#define OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i) (0x083F + (0x100 * (i)))
/*
* USB Host Module
*/
/* UHH */
#define OMAP_USBHOST_UHH_REVISION 0x0000
#define OMAP_USBHOST_UHH_SYSCONFIG 0x0010
#define OMAP_USBHOST_UHH_SYSSTATUS 0x0014
#define OMAP_USBHOST_UHH_HOSTCONFIG 0x0040
#define OMAP_USBHOST_UHH_DEBUG_CSR 0x0044
/* EHCI */
#define OMAP_USBHOST_HCCAPBASE 0x0000
#define OMAP_USBHOST_HCSPARAMS 0x0004
#define OMAP_USBHOST_HCCPARAMS 0x0008
#define OMAP_USBHOST_USBCMD 0x0010
#define OMAP_USBHOST_USBSTS 0x0014
#define OMAP_USBHOST_USBINTR 0x0018
#define OMAP_USBHOST_FRINDEX 0x001C
#define OMAP_USBHOST_CTRLDSSEGMENT 0x0020
#define OMAP_USBHOST_PERIODICLISTBASE 0x0024
#define OMAP_USBHOST_ASYNCLISTADDR 0x0028
#define OMAP_USBHOST_CONFIGFLAG 0x0050
#define OMAP_USBHOST_PORTSC(i) (0x0054 + (0x04 * (i)))
#define OMAP_USBHOST_INSNREG00 0x0090
#define OMAP_USBHOST_INSNREG01 0x0094
#define OMAP_USBHOST_INSNREG02 0x0098
#define OMAP_USBHOST_INSNREG03 0x009C
#define OMAP_USBHOST_INSNREG04 0x00A0
#define OMAP_USBHOST_INSNREG05_UTMI 0x00A4
#define OMAP_USBHOST_INSNREG05_ULPI 0x00A4
#define OMAP_USBHOST_INSNREG06 0x00A8
#define OMAP_USBHOST_INSNREG07 0x00AC
#define OMAP_USBHOST_INSNREG08 0x00B0
#define OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
#define OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT 31
#define OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT 24
#define OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT 22
#define OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT 16
#define OMAP_USBHOST_INSNREG05_ULPI_EXTREGADD_SHIFT 8
#define OMAP_USBHOST_INSNREG05_ULPI_WRDATA_SHIFT 0
/* TLL Register Set */
#define TLL_SYSCONFIG_CACTIVITY (1UL << 8)
#define TLL_SYSCONFIG_SIDLE_SMART_IDLE (2UL << 3)
#define TLL_SYSCONFIG_SIDLE_NO_IDLE (1UL << 3)
#define TLL_SYSCONFIG_SIDLE_FORCED_IDLE (0UL << 3)
#define TLL_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define TLL_SYSCONFIG_SOFTRESET (1UL << 1)
#define TLL_SYSCONFIG_AUTOIDLE (1UL << 0)
#define TLL_SYSSTATUS_RESETDONE (1UL << 0)
#define TLL_SHARED_CONF_USB_90D_DDR_EN (1UL << 6)
#define TLL_SHARED_CONF_USB_180D_SDR_EN (1UL << 5)
#define TLL_SHARED_CONF_USB_DIVRATIO_MASK (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_128 (7UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_64 (6UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_32 (5UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_16 (4UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_8 (3UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_4 (2UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_2 (1UL << 2)
#define TLL_SHARED_CONF_USB_DIVRATIO_1 (0UL << 2)
#define TLL_SHARED_CONF_FCLK_REQ (1UL << 1)
#define TLL_SHARED_CONF_FCLK_IS_ON (1UL << 0)
#define TLL_CHANNEL_CONF_DRVVBUS (1UL << 16)
#define TLL_CHANNEL_CONF_CHRGVBUS (1UL << 15)
#define TLL_CHANNEL_CONF_ULPINOBITSTUFF (1UL << 11)
#define TLL_CHANNEL_CONF_ULPIAUTOIDLE (1UL << 10)
#define TLL_CHANNEL_CONF_UTMIAUTOIDLE (1UL << 9)
#define TLL_CHANNEL_CONF_ULPIDDRMODE (1UL << 8)
#define TLL_CHANNEL_CONF_ULPIOUTCLKMODE (1UL << 7)
#define TLL_CHANNEL_CONF_TLLFULLSPEED (1UL << 6)
#define TLL_CHANNEL_CONF_TLLCONNECT (1UL << 5)
#define TLL_CHANNEL_CONF_TLLATTACH (1UL << 4)
#define TLL_CHANNEL_CONF_UTMIISADEV (1UL << 3)
#define TLL_CHANNEL_CONF_CHANEN (1UL << 0)
/* UHH Register Set */
#define UHH_SYSCONFIG_MIDLEMODE_MASK (3UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY (2UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_NOSTANDBY (1UL << 12)
#define UHH_SYSCONFIG_MIDLEMODE_FORCESTANDBY (0UL << 12)
#define UHH_SYSCONFIG_CLOCKACTIVITY (1UL << 8)
#define UHH_SYSCONFIG_SIDLEMODE_MASK (3UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE (2UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_NOIDLE (1UL << 3)
#define UHH_SYSCONFIG_SIDLEMODE_FORCEIDLE (0UL << 3)
#define UHH_SYSCONFIG_ENAWAKEUP (1UL << 2)
#define UHH_SYSCONFIG_SOFTRESET (1UL << 1)
#define UHH_SYSCONFIG_AUTOIDLE (1UL << 0)
#define UHH_HOSTCONFIG_APP_START_CLK (1UL << 31)
#define UHH_HOSTCONFIG_P3_CONNECT_STATUS (1UL << 10)
#define UHH_HOSTCONFIG_P2_CONNECT_STATUS (1UL << 9)
#define UHH_HOSTCONFIG_P1_CONNECT_STATUS (1UL << 8)
#define UHH_HOSTCONFIG_ENA_INCR_ALIGN (1UL << 5)
#define UHH_HOSTCONFIG_ENA_INCR16 (1UL << 4)
#define UHH_HOSTCONFIG_ENA_INCR8 (1UL << 3)
#define UHH_HOSTCONFIG_ENA_INCR4 (1UL << 2)
#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN (1UL << 1)
#define UHH_HOSTCONFIG_P1_ULPI_BYPASS (1UL << 0)
/* The following are on rev2 (OMAP44xx) of the EHCI only */
#define UHH_SYSCONFIG_IDLEMODE_MASK (3UL << 2)
#define UHH_SYSCONFIG_IDLEMODE_NOIDLE (1UL << 2)
#define UHH_SYSCONFIG_STANDBYMODE_MASK (3UL << 4)
#define UHH_SYSCONFIG_STANDBYMODE_NOSTDBY (1UL << 4)
#define UHH_HOSTCONFIG_P1_MODE_MASK (3UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_ULPI_PHY (0UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_UTMI_PHY (1UL << 16)
#define UHH_HOSTCONFIG_P1_MODE_HSIC (3UL << 16)
#define UHH_HOSTCONFIG_P2_MODE_MASK (3UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_ULPI_PHY (0UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_UTMI_PHY (1UL << 18)
#define UHH_HOSTCONFIG_P2_MODE_HSIC (3UL << 18)
#define ULPI_FUNC_CTRL_RESET (1 << 5)
/*-------------------------------------------------------------------------*/
/*
* Macros for Set and Clear
* See ULPI 1.1 specification to find the registers with Set and Clear offsets
*/
#define ULPI_SET(a) (a + 1)
#define ULPI_CLR(a) (a + 2)
/*-------------------------------------------------------------------------*/
/*
* Register Map
*/
#define ULPI_VENDOR_ID_LOW 0x00
#define ULPI_VENDOR_ID_HIGH 0x01
#define ULPI_PRODUCT_ID_LOW 0x02
#define ULPI_PRODUCT_ID_HIGH 0x03
#define ULPI_FUNC_CTRL 0x04
#define ULPI_IFC_CTRL 0x07
#define ULPI_OTG_CTRL 0x0a
#define ULPI_USB_INT_EN_RISE 0x0d
#define ULPI_USB_INT_EN_FALL 0x10
#define ULPI_USB_INT_STS 0x13
#define ULPI_USB_INT_LATCH 0x14
#define ULPI_DEBUG 0x15
#define ULPI_SCRATCH 0x16
/*
* Values of UHH_REVISION - Note: these are not given in the TRM but taken
* from the linux OMAP EHCI driver (thanks guys). It has been verified on
* a Panda and Beagle board.
*/
#define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */
#define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */
#define EHCI_VENDORID_OMAP3 0x42fa05
#define OMAP_EHCI_HC_DEVSTR "TI OMAP USB 2.0 controller"
#define OMAP_HS_USB_PORTS 3
#define EHCI_HCD_OMAP_MODE_UNKNOWN 0
#define EHCI_HCD_OMAP_MODE_PHY 1
#define EHCI_HCD_OMAP_MODE_TLL 2
#define EHCI_HCD_OMAP_MODE_HSIC 3
void omap_tll_utmi_enable(unsigned int en_mask);
int omap_usb_port_mode(device_t dev, int port);
#endif /* _OMAP_USB_H_ */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
* Copyright (c) 2015 Oleksandr Tymoshenko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,158 +26,4 @@
* $FreeBSD$
*/
/dts-v1/;
/include/ "am335x.dtsi"
/ {
model = "TMDXEVM3358";
compatible = "ti,am335x";
aliases {
soc = &SOC;
uart0 = &uart0;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
};
am335x {
scm@44e10000 {
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
/* I2C0 */
"I2C0_SDA", "I2C0_SDA","i2c",
"I2C0_SCL", "I2C0_SCL","i2c",
/* Ethernet */
"MII1_RX_ER", "gmii1_rxerr", "input_pulldown",
"MII1_TX_EN", "gmii1_txen", "output",
"MII1_RX_DV", "gmii1_rxdv", "input_pulldown",
"MII1_TXD3", "gmii1_txd3", "output",
"MII1_TXD2", "gmii1_txd2", "output",
"MII1_TXD1", "gmii1_txd1", "output",
"MII1_TXD0", "gmii1_txd0", "output",
"MII1_TX_CLK", "gmii1_txclk", "input_pulldown",
"MII1_RX_CLK", "gmii1_rxclk", "input_pulldown",
"MII1_RXD3", "gmii1_rxd3", "input_pulldown",
"MII1_RXD2", "gmii1_rxd2", "input_pulldown",
"MII1_RXD1", "gmii1_rxd1", "input_pulldown",
"MII1_RXD0", "gmii1_rxd0", "input_pulldown",
"MDIO", "mdio_data", "input_pullup",
"MDC", "mdio_clk", "output_pullup",
/* MMCSD0 */
"MMC0_CMD", "mmc0_cmd", "input_pullup",
"MMC0_CLK", "mmc0_clk", "input_pullup",
"MMC0_DAT0", "mmc0_dat0", "input_pullup",
"MMC0_DAT1", "mmc0_dat1", "input_pullup",
"MMC0_DAT2", "mmc0_dat2", "input_pullup",
"MMC0_DAT3", "mmc0_dat3", "input_pullup",
/* GPIO */
"GPMC_AD10", "gpio0_26", "input_pulldown",
"GPMC_AD11", "gpio0_27", "input_pulldown",
"GPMC_AD0", "gpio1_0", "input_pulldown",
"GPMC_AD1", "gpio1_1", "input_pulldown",
"GPMC_AD2", "gpio1_2", "input_pulldown",
"GPMC_AD3", "gpio1_3", "input_pulldown",
"GPMC_AD4", "gpio1_4", "input_pulldown",
"GPMC_AD5", "gpio1_5", "input_pulldown",
"GPMC_AD6", "gpio1_6", "input_pulldown",
"GPMC_AD7", "gpio1_7", "input_pulldown",
"GPMC_AD12", "gpio1_12", "input_pulldown",
"GPMC_AD13", "gpio1_13", "input_pulldown",
"GPMC_AD14", "gpio1_14", "input_pulldown",
"GPMC_AD15", "gpio1_15", "input_pulldown",
"GPMC_A0", "gpio1_16", "input_pulldown",
"GPMC_A1", "gpio1_17", "input_pulldown",
"GPMC_A5", "gpio1_21", "output", /* User LED 1 */
"GPMC_A6", "gpio1_22", "output", /* User LED 2 */
"GPMC_A7", "gpio1_23", "output", /* User LED 3 */
"GPMC_A8", "gpio1_24", "output", /* User LED 4 */
"GPMC_BEn1", "gpio1_28", "input_pulldown",
"GPMC_CSn0", "gpio1_29", "input_pulldown",
"GPMC_CSn1", "gpio1_30", "input_pulldown",
"GPMC_CSn2", "gpio1_31", "input_pulldown",
"MCASP0_FSR", "gpio3_19", "input_pulldown",
"MCASP0_AHCLKX", "gpio3_21", "input_pulldown",
/* TIMERs */
"GPMC_ADVn_ALE", "timer4", "output",
"GPMC_BEn0_CLE", "timer5", "output",
"GPMC_WEn", "timer6", "output",
"GPMC_OEn_REn", "timer7", "output",
/* USB0 and USB1 */
"USB0_DRVVBUS", "USB0_DRVVBUS", "output",
"USB1_DRVVBUS", "USB1_DRVVBUS", "output",
/* LCD */
"GPMC_AD8", "lcd_data23", "output",
"GPMC_AD9", "lcd_data22", "output",
"GPMC_AD10", "lcd_data21", "output",
"GPMC_AD11", "lcd_data20", "output",
"GPMC_AD12", "lcd_data19", "output",
"GPMC_AD13", "lcd_data18", "output",
"GPMC_AD14", "lcd_data17", "output",
"GPMC_AD15", "lcd_data16", "output",
"GPMC_CLK", "lcd_memory_clk", "output",
"LCD_DATA0", "lcd_data0", "output",
"LCD_DATA1", "lcd_data1", "output",
"LCD_DATA2", "lcd_data2", "output",
"LCD_DATA3", "lcd_data3", "output",
"LCD_DATA4", "lcd_data4", "output",
"LCD_DATA5", "lcd_data5", "output",
"LCD_DATA6", "lcd_data6", "output",
"LCD_DATA7", "lcd_data7", "output",
"LCD_DATA8", "lcd_data8", "output",
"LCD_DATA9", "lcd_data9", "output",
"LCD_DATA10", "lcd_data10", "output",
"LCD_DATA11", "lcd_data11", "output",
"LCD_DATA12", "lcd_data12", "output",
"LCD_DATA13", "lcd_data13", "output",
"LCD_DATA14", "lcd_data14", "output",
"LCD_DATA15", "lcd_data15", "output",
"LCD_VSYNC", "lcd_vsync", "output",
"LCD_HSYNC", "lcd_hsync", "output",
"LCD_PCLK", "lcd_pclk", "output",
"LCD_AC_BIAS_EN", "lcd_ac_bias_en", "output",
"ECAP0_IN_PWM0_OUT", "eCAP0_in_PWM0_out", "output";
};
lcd@4830e000 {
panel_name = "TFC_S9700RTWV35TR_01B";
panel_width = <800>;
panel_height = <480>;
panel_hfp = <39>;
panel_hbp = <39>;
panel_hsw = <47>;
panel_vfp = <13>;
panel_vbp = <29>;
panel_vsw = <2>;
panel_pxl_clk = <30000000>;
panel_invert_pxl_clk = <0>;
panel_type = <1>; /* Active or passive, compatibility */
panel_max_bpp = <32>; /* compatibility */
panel_min_bpp = <32>; /* compatibility */
panel_shade = <1>; /* compatibility */
ac_bias = <255>;
ac_bias_intrpt = <0>;
dma_burst_sz = <16>;
bpp = <32>;
fdd = <128>;
tft_alt_mode = <0>; /* compatiblity */
stn_565_mode = <0>; /* compatibility */
mono_8bit_mode = <0>; /* compatibilty */
invert_line_clock = <1>;
invert_frm_clock = <1>;
sync_edge = <0>;
sync_ctrl = <1>;
raster_order = <0>; /* compatibity */
};
};
chosen {
stdin = "uart0";
stdout = "uart0";
};
};
#include "am335x-evm.dts"

View File

@ -1,349 +0,0 @@
/*-
* 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.
*
* $FreeBSD$
*/
/ {
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&AINTC>;
SOC: am335x {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
bus-frequency = <0>;
AINTC: interrupt-controller@48200000 {
compatible = "ti,aintc";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = < 0x48200000 0x1000 >;
};
pmu {
compatible = "arm,cortex-a8-pmu";
interrupts = <3>;
};
scm@44e10000 {
compatible = "ti,scm";
reg = < 0x44e10000 0x2000 >;
};
prcm@44E00000 {
compatible = "am335x,prcm";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x44E00000 0x1300 >;
};
dmtimers@44E05000 {
compatible = "ti,am335x-dmtimer";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x44E05000 0x1000
0x44E31000 0x1000
0x48040000 0x1000
0x48042000 0x1000
0x48044000 0x1000
0x48046000 0x1000
0x48048000 0x1000
0x4804A000 0x1000 >;
interrupts = < 66 67 68 69 92 93 94 95 >;
interrupt-parent = <&AINTC>;
};
rtc: rtc@44E3E000 {
compatible = "ti,da830-rtc";
reg = <0x44E3E000 0x1000>;
interrupts = < 75 76 >;
interrupt-parent = <&AINTC>;
};
adc0: adc@44E0D000 {
compatible = "ti,adc";
reg = <0x44E0D000 0x2000>;
interrupts = < 16 >;
interrupt-parent = <&AINTC>;
};
wdt1@44E35000 {
compatible = "ti,omap3-wdt";
reg = <0x44E35000 0x1000>;
interrupts = <91>;
interrupt-parent = <&AINTC>;
};
GPIO: gpio {
#gpio-cells = <3>;
compatible = "ti,gpio";
gpio-controller;
reg =< 0x44E07000 0x1000
0x4804C000 0x1000
0x481AC000 0x1000
0x481AE000 0x1000 >;
interrupts = < 96 97 98 99 32 33 62 63 >;
interrupt-parent = <&AINTC>;
interrupt-controller;
#interrupt-cells = <1>;
};
uart0: serial@44E09000 {
compatible = "ti,ns16550";
reg = <0x44E09000 0x1000>;
reg-shift = <2>;
interrupts = < 72 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 0 >;
};
uart1: serial@48022000 {
compatible = "ti,ns16550";
reg = <0x48022000 0x1000>;
reg-shift = <2>;
interrupts = < 73 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 1 >;
status = "disabled";
};
uart2: serial@48024000 {
compatible = "ti,ns16550";
reg = <0x48024000 0x1000>;
reg-shift = <2>;
interrupts = < 74 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 2 >;
status = "disabled";
};
uart3: serial@481a6000 {
compatible = "ti,ns16550";
reg = <0x481A6000 0x1000>;
reg-shift = <2>;
interrupts = < 44 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 3 >;
status = "disabled";
};
uart4: serial@481a8000 {
compatible = "ti,ns16550";
reg = <0x481A8000 0x1000>;
reg-shift = <2>;
interrupts = < 45 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 4 >;
status = "disabled";
};
uart5: serial@481aa000 {
compatible = "ti,ns16550";
reg = <0x481AA000 0x1000>;
reg-shift = <2>;
interrupts = < 46 >;
interrupt-parent = <&AINTC>;
clock-frequency = < 48000000 >;
uart-device-id = < 5 >;
status = "disabled";
};
edma3@49000000 {
compatible = "ti,edma3";
reg =< 0x49000000 0x100000 /* Channel Controller Regs */
0x49800000 0x100000 /* Transfer Controller 0 Regs */
0x49900000 0x100000 /* Transfer Controller 1 Regs */
0x49a00000 0x100000 >; /* Transfer Controller 2 Regs */
interrupts = <12 13 14>;
interrupt-parent = <&AINTC>;
};
mmchs0@48060000 {
compatible = "ti,omap3-hsmmc", "ti,mmchs";
reg =<0x48060000 0x1000 >;
interrupts = <64>;
interrupt-parent = <&AINTC>;
mmchs-device-id = <0>;
mmchs-wp-gpio-pin = <0xffffffff>;
ti,dual-volt;
};
mmchs1@481D8000 {
compatible = "ti,omap3-hsmmc", "ti,mmchs";
reg =<0x481D8000 0x1000 >;
interrupts = <28>;
interrupt-parent = <&AINTC>;
mmchs-device-id = <1>;
mmchs-wp-gpio-pin = <0xffffffff>;
status = "disabled";
};
enet0: ethernet@4A100000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ti,cpsw";
reg = <0x4A100000 0x4000>;
interrupts = <40 41 42 43>;
interrupt-parent = <&AINTC>;
phy-handle = <&phy0>;
mdio@0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,cpsw-mdio";
phy0: ethernet-phy@0 {
reg = <0x0>;
};
};
};
i2c0: i2c@44e0b000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,i2c";
reg =< 0x44e0b000 0x1000 >;
interrupts = <70>;
interrupt-parent = <&AINTC>;
i2c-device-id = <0>;
};
i2c1: i2c@4802a000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,i2c";
reg =< 0x4802a000 0x1000 >;
interrupts = <71>;
interrupt-parent = <&AINTC>;
i2c-device-id = <1>;
};
i2c2: i2c@4819c000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,i2c";
reg =< 0x4819c000 0x1000 >;
interrupts = <30>;
interrupt-parent = <&AINTC>;
i2c-device-id = <2>;
};
pwm@48300000 {
compatible = "ti,am335x-pwm";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x48300000 0x100 /* PWMSS0 */
0x48300100 0x80 /* eCAP0 */
0x48300180 0x80 /* eQEP0 */
0x48300200 0x60 /* ePWM0 */
>;
interrupts = <86 58>; /* ePWM0INT, ePWM0_TZINT */
interrupt-parent = <&AINTC>;
pwm-device-id = <0>;
};
pwm@48302000 {
compatible = "ti,am335x-pwm";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x48302000 0x100 /* PWMSS1 */
0x48302100 0x80 /* eCAP1 */
0x48302180 0x80 /* eQEP1 */
0x48302200 0x60 /* ePWM1 */
>;
interrupts = <87 59>; /* ePWM1INT, ePWM1_TZINT */
interrupt-parent = <&AINTC>;
pwm-device-id = <1>;
};
pwm@48304000 {
compatible = "ti,am335x-pwm";
#address-cells = <1>;
#size-cells = <1>;
reg = < 0x48304000 0x100 /* PWMSS2 */
0x48304100 0x80 /* eCAP2 */
0x48304180 0x80 /* eQEP2 */
0x48304200 0x60 /* ePWM2 */
>;
interrupts = <88 60>; /* ePWM2INT, ePWM2_TZINT */
interrupt-parent = <&AINTC>;
pwm-device-id = <2>;
};
lcd: lcd@4830e000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,am335x-lcd";
reg =< 0x4830e000 0x1000 >;
interrupts = <36>;
interrupt-parent = <&AINTC>;
};
usb@47400000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,musb-am33xx";
reg =< 0x47400000 0x1000 /* USBSS */
0x47401000 0x300 /* USB0 */
0x47401300 0x100 /* USB0_PHY */
0x47401400 0x400 /* USB0_CORE */
0x47401800 0x300 /* USB1 */
0x47401B00 0x100 /* USB1_PHY */
0x47401C00 0x400 /* USB1_CORE */
>;
interrupts = <17 18 19>;
interrupt-parent = <&AINTC>;
/* 1 - Host Mode, 0 - Device Mode */
modemask = <2>;
};
mbox0@480C8000 {
compatible = "am335x,system-mbox";
reg = < 0x480C8000 0x1000 >;
interrupts = <77>;
interrupt-parent = <&AINTC>;
};
spinlock0@480CA000 {
compatible = "am335x,spinlock";
reg = < 0x480CA000 0x1000 >;
};
pruss@4A300000 {
compatible = "ti,pruss-v2";
reg = <0x4A300000 0x80000>;
interrupt-parent = <&AINTC>;
interrupts = <20 21 22 23 24 25 26 27>;
};
};
};

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
* Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,161 +26,6 @@
* $FreeBSD$
*/
/dts-v1/;
/include/ "am335x.dtsi"
/ {
model = "beaglebone-black";
compatible = "beaglebone-black", "beaglebone", "ti,am335x";
aliases {
soc = &SOC;
uart0 = &uart0;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x20000000 >; /* 512MB RAM */
};
am335x {
scm@44e10000 {
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
/* I2C0 */
"I2C0_SDA", "I2C0_SDA","i2c",
"I2C0_SCL", "I2C0_SCL","i2c",
/* I2C1 */
"SPI0_D1", "I2C1_SDA", "i2c",
"SPI0_CS0", "I2C1_SCL", "i2c",
/* I2C2 */
"UART1_CTSn", "I2C2_SDA", "i2c",
"UART1_RTSn", "I2C2_SCL", "i2c",
/* Ethernet */
"MII1_RX_ER", "gmii1_rxerr", "input_pulldown",
"MII1_TX_EN", "gmii1_txen", "output",
"MII1_RX_DV", "gmii1_rxdv", "input_pulldown",
"MII1_TXD3", "gmii1_txd3", "output",
"MII1_TXD2", "gmii1_txd2", "output",
"MII1_TXD1", "gmii1_txd1", "output",
"MII1_TXD0", "gmii1_txd0", "output",
"MII1_TX_CLK", "gmii1_txclk", "input_pulldown",
"MII1_RX_CLK", "gmii1_rxclk", "input_pulldown",
"MII1_RXD3", "gmii1_rxd3", "input_pulldown",
"MII1_RXD2", "gmii1_rxd2", "input_pulldown",
"MII1_RXD1", "gmii1_rxd1", "input_pulldown",
"MII1_RXD0", "gmii1_rxd0", "input_pulldown",
"MDIO", "mdio_data", "input_pullup",
"MDC", "mdio_clk", "output_pullup",
/* MMCSD0 */
"MMC0_CMD", "mmc0_cmd", "input_pullup",
"MMC0_CLK", "mmc0_clk", "input_pullup",
"MMC0_DAT0", "mmc0_dat0", "input_pullup",
"MMC0_DAT1", "mmc0_dat1", "input_pullup",
"MMC0_DAT2", "mmc0_dat2", "input_pullup",
"MMC0_DAT3", "mmc0_dat3", "input_pullup",
/* MMC1 */
"GPMC_CSn1", "mmc1_clk", "input_pullup",
"GPMC_CSn2", "mmc1_cmd", "input_pullup",
"GPMC_CSn3", "gpio2_0", "output_pullup", /* Reset */
"GPMC_AD0", "mmc1_dat0", "input_pullup",
"GPMC_AD1", "mmc1_dat1", "input_pullup",
"GPMC_AD2", "mmc1_dat2", "input_pullup",
"GPMC_AD3", "mmc1_dat3", "input_pullup",
"GPMC_AD4", "mmc1_dat4", "input_pullup",
"GPMC_AD5", "mmc1_dat5", "input_pullup",
"GPMC_AD6", "mmc1_dat6", "input_pullup",
"GPMC_AD7", "mmc1_dat7", "input_pullup",
/* GPIO */
"ECAP0_IN_PWM0_OUT", "gpio0_7", "input_pulldown",
"GPMC_AD10", "gpio0_26", "input_pulldown",
"GPMC_AD11", "gpio0_27", "input_pulldown",
"GPMC_AD12", "gpio1_12", "input_pulldown",
"GPMC_AD13", "gpio1_13", "input_pulldown",
"GPMC_AD14", "gpio1_14", "input_pulldown",
"GPMC_AD15", "gpio1_15", "input_pulldown",
"GPMC_A0", "gpio1_16", "input_pulldown",
"GPMC_A1", "gpio1_17", "input_pulldown",
"GPMC_A5", "gpio1_21", "output", /* User LED 1 */
"GPMC_A6", "gpio1_22", "output", /* User LED 2 */
"GPMC_A7", "gpio1_23", "output", /* User LED 3 */
"GPMC_A8", "gpio1_24", "output", /* User LED 4 */
"GPMC_BEn1", "gpio1_28", "input_pulldown",
"GPMC_CSn0", "gpio1_29", "input_pulldown",
"GPMC_CLK", "gpio2_1", "input_pulldown",
"LCD_DATA0", "gpio2_6", "input_pulldown",
"LCD_DATA1", "gpio2_7", "input_pulldown",
"LCD_DATA2", "gpio2_8", "input_pulldown",
"LCD_DATA3", "gpio2_9", "input_pulldown",
"LCD_DATA4", "gpio2_10", "input_pulldown",
"LCD_DATA5", "gpio2_11", "input_pulldown",
"LCD_DATA6", "gpio2_12", "input_pulldown",
"LCD_DATA7", "gpio2_13", "input_pulldown",
"LCD_VSYNC", "gpio2_22", "input_pulldown",
"LCD_HSYNC", "gpio2_23", "input_pulldown",
"LCD_PCLK", "gpio2_24", "input_pulldown",
"LCD_AC_BIAS_EN", "gpio2_25", "input_pulldown",
"MCASP0_FSR", "gpio3_19", "input_pulldown",
"MCASP0_AHCLKX", "gpio3_21", "input_pulldown",
/* TIMERs */
"GPMC_ADVn_ALE", "timer4", "output",
"GPMC_BEn0_CLE", "timer5", "output",
"GPMC_WEn", "timer6", "output",
"GPMC_OEn_REn", "timer7", "output",
/* USB0 and USB1 */
"USB0_DRVVBUS", "USB0_DRVVBUS", "output",
"USB1_DRVVBUS", "USB1_DRVVBUS", "output",
/* PWM */
"GPMC_A2", "ehrpwm1A", "output",
"GPMC_A3", "ehrpwm1B", "output",
"GPMC_AD8", "ehrpwm2A", "output",
"GPMC_AD9", "ehrpwm2B", "output";
};
mmchs1@481D8000 {
bus-width = <8>;
status = "okay";
non-removable;
};
i2c@44e0b000 {
pmic@48 {
compatible = "ti,am335x-pmic";
reg = <0x48>;
interrupts = <7>; /* nNMI */
interrupt-parent = <&AINTC>;
};
};
};
leds {
compatible = "gpio-leds";
led1 {
gpios = <&GPIO 53 2 0>;
name = "led1";
};
led2 {
gpios = <&GPIO 54 2 0>;
name = "led2";
};
led3 {
gpios = <&GPIO 55 2 0>;
name = "led3";
};
led4 {
gpios = <&GPIO 56 2 0>;
name = "led4";
};
};
chosen {
stdin = "uart0";
stdout = "uart0";
};
};
#include "am335x-boneblack.dts"
#include "beaglebone-common.dtsi"

View File

@ -0,0 +1,45 @@
/*-
* Copyright (c) 2015 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$
*/
/ {
ocp {
pruss@4A300000 {
compatible = "ti,pruss-v2";
reg = <0x4A300000 0x80000>;
interrupt-parent = <&intc>;
interrupts = <20 21 22 23 24 25 26 27>;
};
};
};
&tps {
interrupt-parent = <&intc>;
interrupts = <7>;
};

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
* Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,120 +26,5 @@
* $FreeBSD$
*/
/dts-v1/;
/include/ "am335x.dtsi"
/ {
model = "beaglebone";
compatible = "beaglebone", "ti,am335x";
aliases {
soc = &SOC;
uart0 = &uart0;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
};
am335x {
scm@44e10000 {
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
/* I2C0 */
"I2C0_SDA", "I2C0_SDA","i2c",
"I2C0_SCL", "I2C0_SCL","i2c",
/* Ethernet */
"MII1_RX_ER", "gmii1_rxerr", "input_pulldown",
"MII1_TX_EN", "gmii1_txen", "output",
"MII1_RX_DV", "gmii1_rxdv", "input_pulldown",
"MII1_TXD3", "gmii1_txd3", "output",
"MII1_TXD2", "gmii1_txd2", "output",
"MII1_TXD1", "gmii1_txd1", "output",
"MII1_TXD0", "gmii1_txd0", "output",
"MII1_TX_CLK", "gmii1_txclk", "input_pulldown",
"MII1_RX_CLK", "gmii1_rxclk", "input_pulldown",
"MII1_RXD3", "gmii1_rxd3", "input_pulldown",
"MII1_RXD2", "gmii1_rxd2", "input_pulldown",
"MII1_RXD1", "gmii1_rxd1", "input_pulldown",
"MII1_RXD0", "gmii1_rxd0", "input_pulldown",
"MDIO", "mdio_data", "input_pullup",
"MDC", "mdio_clk", "output_pullup",
/* MMCSD0 */
"MMC0_CMD", "mmc0_cmd", "input_pullup",
"MMC0_CLK", "mmc0_clk", "input_pullup",
"MMC0_DAT0", "mmc0_dat0", "input_pullup",
"MMC0_DAT1", "mmc0_dat1", "input_pullup",
"MMC0_DAT2", "mmc0_dat2", "input_pullup",
"MMC0_DAT3", "mmc0_dat3", "input_pullup",
/* USB0 and USB1 */
"USB0_DRVVBUS", "USB0_DRVVBUS", "output",
"USB1_DRVVBUS", "USB1_DRVVBUS", "output",
/* GPIO */
"ECAP0_IN_PWM0_OUT", "gpio0_7", "input_pulldown",
"GPMC_AD10", "gpio0_26", "input_pulldown",
"GPMC_AD11", "gpio0_27", "input_pulldown",
"GPMC_AD0", "gpio1_0", "input_pulldown",
"GPMC_AD1", "gpio1_1", "input_pulldown",
"GPMC_AD2", "gpio1_2", "input_pulldown",
"GPMC_AD3", "gpio1_3", "input_pulldown",
"GPMC_AD4", "gpio1_4", "input_pulldown",
"GPMC_AD5", "gpio1_5", "input_pulldown",
"GPMC_AD6", "gpio1_6", "input_pulldown",
"GPMC_AD7", "gpio1_7", "input_pulldown",
"GPMC_AD12", "gpio1_12", "input_pulldown",
"GPMC_AD13", "gpio1_13", "input_pulldown",
"GPMC_AD14", "gpio1_14", "input_pulldown",
"GPMC_AD15", "gpio1_15", "input_pulldown",
"GPMC_A0", "gpio1_16", "input_pulldown",
"GPMC_A1", "gpio1_17", "input_pulldown",
"GPMC_A5", "gpio1_21", "output", /* User LED 1 */
"GPMC_A6", "gpio1_22", "output", /* User LED 2 */
"GPMC_A7", "gpio1_23", "output", /* User LED 3 */
"GPMC_A8", "gpio1_24", "output", /* User LED 4 */
"GPMC_BEn1", "gpio1_28", "input_pulldown",
"GPMC_CSn0", "gpio1_29", "input_pulldown",
"GPMC_CSn1", "gpio1_30", "input_pulldown",
"GPMC_CSn2", "gpio1_31", "input_pulldown",
"GPMC_CLK", "gpio2_1", "input_pulldown",
"LCD_DATA0", "gpio2_6", "input_pulldown",
"LCD_DATA1", "gpio2_7", "input_pulldown",
"LCD_DATA2", "gpio2_8", "input_pulldown",
"LCD_DATA3", "gpio2_9", "input_pulldown",
"LCD_DATA4", "gpio2_10", "input_pulldown",
"LCD_DATA5", "gpio2_11", "input_pulldown",
"LCD_DATA6", "gpio2_12", "input_pulldown",
"LCD_DATA7", "gpio2_13", "input_pulldown",
"LCD_VSYNC", "gpio2_22", "input_pulldown",
"LCD_HSYNC", "gpio2_23", "input_pulldown",
"LCD_PCLK", "gpio2_24", "input_pulldown",
"LCD_AC_BIAS_EN", "gpio2_25", "input_pulldown",
"MCASP0_FSR", "gpio3_19", "input_pulldown",
"MCASP0_AHCLKX", "gpio3_21", "input_pulldown",
/* TIMERs */
"GPMC_ADVn_ALE", "timer4", "output",
"GPMC_BEn0_CLE", "timer5", "output",
"GPMC_WEn", "timer6", "output",
"GPMC_OEn_REn", "timer7", "output",
/* PWM */
"GPMC_A2", "ehrpwm1A", "output",
"GPMC_A3", "ehrpwm1B", "output",
"GPMC_AD8", "ehrpwm2A", "output",
"GPMC_AD9", "ehrpwm2B", "output";
};
i2c@44e0b000 {
pmic@24 {
compatible = "ti,am335x-pmic";
reg = <0x48>;
};
};
};
chosen {
stdin = "uart0";
stdout = "uart0";
};
};
#include "am335x-bone.dts"
#include "beaglebone-common.dtsi"

View File

@ -0,0 +1,49 @@
/*-
* Copyright (c) 2015 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$
*/
&mmc1 {
non-removable; /* XXX need real solution */
};
&mmc5 {
status = "disabled";
};
/ {
ocp {
global-timer@48240600 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x48240200 0x20>;
interrupts = <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
};
};
chosen {
stdin = "serial2";
stdout = "serial2";
};
};

View File

@ -0,0 +1,31 @@
/*-
* Copyright (c) 2015 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$
*/
#include "omap4-panda-es.dts"
#include "pandaboard-common.dtsi"

View File

@ -1,9 +1,7 @@
/*-
* Copyright (c) 2011 The FreeBSD Foundation
* Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
* All rights reserved.
*
* Developed by Damjan Marion <damjan.marion@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -28,159 +26,6 @@
* $FreeBSD$
*/
/dts-v1/;
/ {
model = "pandaboard";
compatible = "pandaboard", "ti,omap4430";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&GIC>;
aliases {
soc = &SOC;
uart3 = &uart3;
};
memory {
device_type = "memory";
reg = < 0x80000000 0x40000000 >; /* 1GB RAM at 0x0 */
};
SOC: omap4430 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
bus-frequency = <0>;
GIC: interrupt-controller@48241000 {
compatible = "arm,gic";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = < 0x48241000 0x1000 >, /* Distributor Registers */
< 0x48240100 0x0100 >; /* CPU Interface Registers */
};
omap4_prcm@4a306000 {
compatible = "ti,omap4_prcm";
reg =< 0x4a306000 0x2000
0x4a004000 0x1000
0x4a008000 0x8000>;
};
pl310@48242000 {
compatible = "arm,pl310";
reg = < 0x48242000 0x1000 >;
interrupts = < 32 >;
interrupt-parent = < &GIC >;
};
mp_tmr@48240200 {
compatible = "arm,mpcore-timers";
#address-cells = <1>;
#size-cells = <0>;
reg = < 0x48240200 0x100 >, /* Global Timer Registers */
< 0x48240600 0x100 >; /* Private Timer Registers */
interrupts = < 27 29 >;
interrupt-parent = < &GIC >;
};
uart3: serial@48020000 {
compatible = "ns16550";
reg = <0x48020000 0x1000>;
reg-shift = <2>;
interrupts = < 106 >;
interrupt-parent = <&GIC>;
clock-frequency = < 48000000 >; /* 48Mhz clock for all uarts */
/* (techref 17.3.1.1) */
};
scm@4a100000 {
compatible = "ti,scm";
reg = < 0x4a100000 0x1000 >;
/* Set of triplets < padname, muxname, padstate> */
scm-pad-config =
"ag19", "usbb1_ulpiphy_stp", "output",
"ae18", "usbb1_ulpiphy_clk", "input_pulldown",
"af19", "usbb1_ulpiphy_dir", "input_pulldown",
"ae19", "usbb1_ulpiphy_nxt", "input_pulldown",
"af18", "usbb1_ulpiphy_dat0", "input_pulldown",
"ag18", "usbb1_ulpiphy_dat1", "input_pulldown",
"ae17", "usbb1_ulpiphy_dat2", "input_pulldown",
"af17", "usbb1_ulpiphy_dat3", "input_pulldown",
"ah17", "usbb1_ulpiphy_dat4", "input_pulldown",
"ae16", "usbb1_ulpiphy_dat5", "input_pulldown",
"af16", "usbb1_ulpiphy_dat6", "input_pulldown",
"ag16", "usbb1_ulpiphy_dat7", "input_pulldown";
};
GPIO: gpio {
#gpio-cells = <3>;
compatible = "ti,gpio";
gpio-controller;
reg =< 0x4a310000 0x1000
0x48055000 0x1000
0x48057000 0x1000
0x48059000 0x1000
0x4805b000 0x1000
0x4805d000 0x1000>;
interrupts = <61 62 63 64 65 66>;
interrupt-parent = <&GIC>;
};
ehci {
compatible = "ti,usb-ehci", "usb-ehci";
/*
* USB port PHY configuration is a tuple: <mode, reset, gpio_pin>
* mode is one of the following values:
* 0 - unknown
* 1 - PHY
* 2 - TLL
* 3 - HSIC
*
* reset indicates (if non-zero) if port reset is required
* gpio_pin - GPIO pin that is used to perform reset
*/
phy-config = < 1 0 0
0 0 0
0 0 0>;
reg = < 0x4a064c00 0x100 /* EHCI regs */
0x4a064000 0x700 /* UHH regs */
0x4a062000 0x1000>; /* TLL regs */
interrupts = <109>;
interrupt-parent = <&GIC>;
};
I2C1: i2c@x48070000 {
compatible = "ti,i2c";
reg =< 0x48070000 0x100 >;
interrupts = <88>;
interrupt-parent = <&GIC>;
i2c-device-id = <1>;
};
sdma@x48070000 {
compatible = "ti,sdma";
reg =< 0x4A056000 0x1000 >;
interrupts = <44 45 46 47>;
interrupt-parent = <&GIC>;
};
mmc@x4809C000 {
compatible = "ti,mmchs";
reg =<0x4809C000 0x1000 >;
interrupts = <115>;
interrupt-parent = <&GIC>;
mmchs-device-id = <1>;
non-removable; /* XXX need real solution */
};
};
chosen {
stdin = "uart3";
stdout = "uart3";
};
};
#include "omap4-panda.dts"
#include "pandaboard-common.dtsi"

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
@ -71,29 +72,15 @@ static int
ti8250_bus_probe(struct uart_softc *sc)
{
int status;
int devid;
clk_ident_t clkid;
pcell_t prop;
phandle_t node;
/*
* Get the device id from FDT. If it's not there we can't turn on the
* right clocks, so bail, unless we're doing unit 0. We assume that's
* the serial console, whose clock isn't controllable anyway, and we
* sure don't want to break the console because of a config error.
*/
node = ofw_bus_get_node(sc->sc_dev);
if ((OF_getprop(node, "uart-device-id", &prop, sizeof(prop))) <= 0) {
device_printf(sc->sc_dev,
"missing uart-device-id attribute in FDT\n");
if (device_get_unit(sc->sc_dev) != 0)
return (ENXIO);
devid = 0;
} else
devid = fdt32_to_cpu(prop);
/* Enable clocks for this device. We can't continue if that fails. */
clkid = UART0_CLK + devid;
clkid = ti_hwmods_get_clock(sc->sc_dev);
if (clkid == INVALID_CLK_IDENT) {
device_printf(sc->sc_dev,
"failed to get clock based on hwmods\n");
clkid = UART1_CLK + device_get_unit(sc->sc_dev);
}
if ((status = ti_prcm_clk_enable(clkid)) != 0)
return (status);
@ -138,10 +125,12 @@ static struct uart_class uart_ti8250_class = {
.uc_ops = &uart_ns8250_ops,
.uc_range = 0x88,
.uc_rclk = 48000000,
.uc_rshift = 0
.uc_rshift = 2
};
static struct ofw_compat_data compat_data[] = {
{"ti,ns16550", (uintptr_t)&uart_ti8250_class},
{"ti,omap3-uart", (uintptr_t)&uart_ti8250_class},
{"ti,omap4-uart", (uintptr_t)&uart_ti8250_class},
{NULL, (uintptr_t)NULL},
};
UART_FDT_CLASS_AND_DEVICE(compat_data);