Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159335787
D2146.id4427.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
197 KB
Referenced Files
None
Subscribers
None
D2146.id4427.diff
View Options
Index: sys/arm/conf/BEAGLEBONE
===================================================================
--- sys/arm/conf/BEAGLEBONE
+++ sys/arm/conf/BEAGLEBONE
@@ -163,7 +163,9 @@
device usb_template # Control of the gadget
device usfs
+device fdt_pinctrl
+
# Flattened Device Tree
options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=beaglebone.dts
+makeoptions FDT_DTS_FILE=am335x-boneblack.dts
Index: sys/arm/ti/aintc.c
===================================================================
--- sys/arm/ti/aintc.c
+++ sys/arm/ti/aintc.c
@@ -84,9 +84,9 @@
if (!ofw_bus_status_okay(dev))
return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "ti,aintc"))
+ if (!ofw_bus_is_compatible(dev, "ti,am33xx-intc"))
return (ENXIO);
+
device_set_desc(dev, "TI AINTC Interrupt Controller");
return (BUS_PROBE_DEFAULT);
}
Index: sys/arm/ti/am335x/am335x_dmtimer.c
===================================================================
--- sys/arm/ti/am335x/am335x_dmtimer.c
+++ sys/arm/ti/am335x/am335x_dmtimer.c
@@ -54,6 +54,7 @@
#include <machine/bus.h>
#include <machine/fdt.h>
+#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_scm.h>
@@ -110,78 +111,31 @@
#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;
-};
-static struct am335x_dmtimer_softc *am335x_dmtimer_sc;
-
-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 }
+ union {
+ struct timecounter tc;
+ struct eventtimer et;
+ } func;
};
-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);
-}
+static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
+static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
/*
* PPS driver routines, included when the kernel is built with option PPS_SYNC.
@@ -198,6 +152,7 @@
* latched value from the timer. The remaining work (done by pps_event()) is
* scheduled to be done later in a non-interrupt context.
*/
+#if 0
#ifdef PPS_SYNC
#define PPS_CDEV_NAME "pps"
@@ -216,19 +171,19 @@
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
@@ -245,10 +200,10 @@
* 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);
}
}
@@ -399,7 +354,7 @@
* 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. */
@@ -428,6 +383,7 @@
}
#endif /* PPS_SYNC */
+#endif /* 0 */
/*
* End of PPS driver code.
*/
@@ -439,7 +395,7 @@
sc = tc->tc_priv;
- return (am335x_dmtimer_tc_read_4(sc, DMT_TCRR));
+ return (DMTIMER_READ4(sc, DMT_TCRR));
}
static int
@@ -463,13 +419,13 @@
* 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;
}
@@ -483,13 +439,13 @@
* 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);
}
@@ -502,10 +458,10 @@
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);
}
@@ -517,13 +473,90 @@
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);
+ if (OF_hasprop(node, "ti,timer-pwm"))
+ return (0);
+
+ return (1);
+}
+
+static int
+am335x_dmtimer_init_et(struct am335x_dmtimer_softc *sc)
+{
+ if (am335x_dmtimer_et_sc != NULL)
+ return (EEXIST);
+
+ /* 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)
{
@@ -531,7 +564,8 @@
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);
}
@@ -543,8 +577,9 @@
am335x_dmtimer_attach(device_t dev)
{
struct am335x_dmtimer_softc *sc;
- void *ihl;
int err;
+ int timer_id;
+ int enable;
/*
* Note that if this routine returns an error status rather than running
@@ -553,9 +588,7 @@
*/
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);
@@ -565,81 +598,46 @@
}
/* 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) {
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);
-
- 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_unit(dev, "timer");
+ if (timer_id < 0) {
+ device_printf(dev, "failed to get device id using ti,hwmods\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;
+ err = ti_prcm_clk_set_source(DMTIMER0_CLK + timer_id, SYSCLK_CLK);
+ err |= ti_prcm_clk_enable(DMTIMER0_CLK + timer_id);
- 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;
+ if (err) {
+ device_printf(dev, "Error: could not enable timer clock\n");
+ return (ENXIO);
+ }
+ }
return (0);
}
@@ -668,7 +666,7 @@
int32_t counts;
uint32_t first, last;
- sc = am335x_dmtimer_sc;
+ sc = am335x_dmtimer_tc_sc;
if (sc == NULL) {
for (; usec > 0; usec--)
@@ -681,10 +679,10 @@
/* 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 {
Index: sys/arm/ti/am335x/am335x_ecap.c
===================================================================
--- /dev/null
+++ sys/arm/ti/am335x/am335x_ecap.c
@@ -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);
Index: sys/arm/ti/am335x/am335x_ehrpwm.c
===================================================================
--- /dev/null
+++ sys/arm/ti/am335x/am335x_ehrpwm.c
@@ -0,0 +1,448 @@
+/*-
+ * 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"
+
+/* In ticks */
+#define DEFAULT_PWM_PERIOD 1000
+#define PWM_CLOCK 100000000UL
+
+#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_ehrpwm softc", MTX_DEF)
+#define PWM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
+
+#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, reg, value);
+
+#define EPWM_TBCTL 0x00
+#define TBCTL_FREERUN (2 << 14)
+#define TBCTL_PHDIR_UP (1 << 13)
+#define TBCTL_PHDIR_DOWN (0 << 13)
+#define TBCTL_CLKDIV(x) ((x) << 10)
+#define TBCTL_CLKDIV_MASK (3 << 10)
+#define TBCTL_HSPCLKDIV(x) ((x) << 7)
+#define TBCTL_HSPCLKDIV_MASK (3 << 7)
+#define TBCTL_SYNCOSEL_DISABLED (3 << 4)
+#define TBCTL_PRDLD_SHADOW (0 << 3)
+#define TBCTL_PRDLD_IMMEDIATE (0 << 3)
+#define TBCTL_PHSEN_ENABLED (1 << 2)
+#define TBCTL_PHSEN_DISABLED (0 << 2)
+#define TBCTL_CTRMODE_MASK (3)
+#define TBCTL_CTRMODE_UP (0 << 0)
+#define TBCTL_CTRMODE_DOWN (1 << 0)
+#define TBCTL_CTRMODE_UPDOWN (2 << 0)
+#define TBCTL_CTRMODE_FREEZE (3 << 0)
+
+#define EPWM_TBSTS 0x02
+#define EPWM_TBPHSHR 0x04
+#define EPWM_TBPHS 0x06
+#define EPWM_TBCNT 0x08
+#define EPWM_TBPRD 0x0a
+/* Counter-compare */
+#define EPWM_CMPCTL 0x0e
+#define CMPCTL_SHDWBMODE_SHADOW (1 << 6)
+#define CMPCTL_SHDWBMODE_IMMEDIATE (0 << 6)
+#define CMPCTL_SHDWAMODE_SHADOW (1 << 4)
+#define CMPCTL_SHDWAMODE_IMMEDIATE (0 << 4)
+#define CMPCTL_LOADBMODE_ZERO (0 << 2)
+#define CMPCTL_LOADBMODE_PRD (1 << 2)
+#define CMPCTL_LOADBMODE_EITHER (2 << 2)
+#define CMPCTL_LOADBMODE_FREEZE (3 << 2)
+#define CMPCTL_LOADAMODE_ZERO (0 << 0)
+#define CMPCTL_LOADAMODE_PRD (1 << 0)
+#define CMPCTL_LOADAMODE_EITHER (2 << 0)
+#define CMPCTL_LOADAMODE_FREEZE (3 << 0)
+#define EPWM_CMPAHR 0x10
+#define EPWM_CMPA 0x12
+#define EPWM_CMPB 0x14
+/* CMPCTL_LOADAMODE_ZERO */
+#define EPWM_AQCTLA 0x16
+#define EPWM_AQCTLB 0x18
+#define AQCTL_CBU_NONE (0 << 8)
+#define AQCTL_CBU_CLEAR (1 << 8)
+#define AQCTL_CBU_SET (2 << 8)
+#define AQCTL_CBU_TOGGLE (3 << 8)
+#define AQCTL_CAU_NONE (0 << 4)
+#define AQCTL_CAU_CLEAR (1 << 4)
+#define AQCTL_CAU_SET (2 << 4)
+#define AQCTL_CAU_TOGGLE (3 << 4)
+#define AQCTL_ZRO_NONE (0 << 0)
+#define AQCTL_ZRO_CLEAR (1 << 0)
+#define AQCTL_ZRO_SET (2 << 0)
+#define AQCTL_ZRO_TOGGLE (3 << 0)
+#define EPWM_AQSFRC 0x1a
+#define EPWM_AQCSFRC 0x1c
+
+/* Trip-Zone module */
+#define EPWM_TZCTL 0x28
+#define EPWM_TZFLG 0x2C
+/* High-Resolution PWM */
+#define EPWM_HRCTL 0x40
+#define HRCTL_DELMODE_BOTH 3
+#define HRCTL_DELMODE_FALL 2
+#define HRCTL_DELMODE_RISE 1
+
+static device_probe_t am335x_ehrpwm_probe;
+static device_attach_t am335x_ehrpwm_attach;
+static device_detach_t am335x_ehrpwm_detach;
+
+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;
+ int sc_mem_rid;
+ /* sysctl for configuration */
+ int sc_pwm_clkdiv;
+ int sc_pwm_freq;
+ struct sysctl_oid *sc_clkdiv_oid;
+ struct sysctl_oid *sc_freq_oid;
+ struct sysctl_oid *sc_period_oid;
+ struct sysctl_oid *sc_chanA_oid;
+ struct sysctl_oid *sc_chanB_oid;
+ uint32_t sc_pwm_period;
+ uint32_t sc_pwm_dutyA;
+ uint32_t sc_pwm_dutyB;
+};
+
+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_ehrpwm_driver = {
+ "am335x_ehrpwm",
+ am335x_ehrpwm_methods,
+ sizeof(struct am335x_ehrpwm_softc),
+};
+
+static devclass_t am335x_ehrpwm_devclass;
+
+static void
+am335x_ehrpwm_freq(struct am335x_ehrpwm_softc *sc)
+{
+ int clkdiv;
+
+ clkdiv = am335x_ehrpwm_clkdiv[sc->sc_pwm_clkdiv];
+ sc->sc_pwm_freq = PWM_CLOCK / (1 * clkdiv) / sc->sc_pwm_period;
+}
+
+static int
+am335x_ehrpwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
+{
+ int clkdiv, error, freq, i, period;
+ struct am335x_ehrpwm_softc *sc;
+ uint32_t reg;
+
+ sc = (struct am335x_ehrpwm_softc *)arg1;
+
+ PWM_LOCK(sc);
+ freq = sc->sc_pwm_freq;
+ PWM_UNLOCK(sc);
+
+ error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ if (freq > PWM_CLOCK)
+ freq = PWM_CLOCK;
+
+ PWM_LOCK(sc);
+ if (freq != sc->sc_pwm_freq) {
+ 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;
+ sc->sc_pwm_clkdiv = i;
+ sc->sc_pwm_period = period;
+ }
+ /* Reset the duty cycle settings. */
+ sc->sc_pwm_dutyA = 0;
+ sc->sc_pwm_dutyB = 0;
+ EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+ EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+ /* Update the clkdiv settings. */
+ reg = EPWM_READ2(sc, EPWM_TBCTL);
+ reg &= ~TBCTL_CLKDIV_MASK;
+ reg |= TBCTL_CLKDIV(sc->sc_pwm_clkdiv);
+ EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+ /* Update the period settings. */
+ EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
+ am335x_ehrpwm_freq(sc);
+ }
+ PWM_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+am335x_ehrpwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
+{
+ int error, i, clkdiv;
+ struct am335x_ehrpwm_softc *sc;
+ uint32_t reg;
+
+ sc = (struct am335x_ehrpwm_softc *)arg1;
+
+ PWM_LOCK(sc);
+ clkdiv = am335x_ehrpwm_clkdiv[sc->sc_pwm_clkdiv];
+ PWM_UNLOCK(sc);
+
+ error = sysctl_handle_int(oidp, &clkdiv, sizeof(clkdiv), req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ PWM_LOCK(sc);
+ 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_ehrpwm_freq(sc);
+ }
+ PWM_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+am335x_ehrpwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
+{
+ 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
+ duty = sc->sc_pwm_dutyB;
+ error = sysctl_handle_int(oidp, &duty, 0, req);
+
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ if (duty > sc->sc_pwm_period) {
+ device_printf(sc->sc_dev, "Duty cycle can't be greater then period\n");
+ return (EINVAL);
+ }
+
+ PWM_LOCK(sc);
+ if (oidp == sc->sc_chanA_oid) {
+ sc->sc_pwm_dutyA = duty;
+ EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+ }
+ else {
+ sc->sc_pwm_dutyB = duty;
+ EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+ }
+ PWM_UNLOCK(sc);
+
+ return (error);
+}
+
+static int
+am335x_ehrpwm_sysctl_period(SYSCTL_HANDLER_ARGS)
+{
+ 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);
+
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ if (period < 1)
+ return (EINVAL);
+
+ if (period > USHRT_MAX)
+ period = USHRT_MAX;
+
+ PWM_LOCK(sc);
+ /* Reset the duty cycle settings. */
+ sc->sc_pwm_dutyA = 0;
+ sc->sc_pwm_dutyB = 0;
+ EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+ EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+ /* Update the period settings. */
+ sc->sc_pwm_period = period;
+ EPWM_WRITE2(sc, EPWM_TBPRD, period - 1);
+ am335x_ehrpwm_freq(sc);
+ PWM_UNLOCK(sc);
+
+ return (error);
+}
+
+static int
+am335x_ehrpwm_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(dev, "ti,am33xx-ehrpwm"))
+ return (ENXIO);
+
+ device_set_desc(dev, "AM335x EHRPWM");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_ehrpwm_attach(device_t dev)
+{
+ struct am335x_ehrpwm_softc *sc;
+ uint32_t reg;
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid *tree;
+
+ 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;
+ }
+
+ /* 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_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_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_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_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_ehrpwm_sysctl_duty, "I", "Channel B duty cycles");
+
+ /* CONFIGURE EPWM1 */
+ reg = EPWM_READ2(sc, EPWM_TBCTL);
+ reg &= ~(TBCTL_CLKDIV_MASK | TBCTL_HSPCLKDIV_MASK);
+ EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+
+ sc->sc_pwm_period = DEFAULT_PWM_PERIOD;
+ sc->sc_pwm_dutyA = 0;
+ sc->sc_pwm_dutyB = 0;
+ am335x_ehrpwm_freq(sc);
+
+ EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
+ EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+ EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+
+ EPWM_WRITE2(sc, EPWM_AQCTLA, (AQCTL_ZRO_SET | AQCTL_CAU_CLEAR));
+ EPWM_WRITE2(sc, EPWM_AQCTLB, (AQCTL_ZRO_SET | AQCTL_CBU_CLEAR));
+
+ /* START EPWM */
+ reg &= ~TBCTL_CTRMODE_MASK;
+ reg |= TBCTL_CTRMODE_UP | TBCTL_FREERUN;
+ EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+
+ EPWM_WRITE2(sc, EPWM_TZCTL, 0xf);
+ reg = EPWM_READ2(sc, EPWM_TZFLG);
+
+ return (0);
+fail:
+ PWM_LOCK_DESTROY(sc);
+ 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_ehrpwm_detach(device_t dev)
+{
+ struct am335x_ehrpwm_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_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);
Index: sys/arm/ti/am335x/am335x_gpio.c
===================================================================
--- sys/arm/ti/am335x/am335x_gpio.c
+++ sys/arm/ti/am335x/am335x_gpio.c
@@ -51,7 +51,7 @@
#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 @@
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 @@
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 {
Index: sys/arm/ti/am335x/am335x_lcd.c
===================================================================
--- sys/arm/ti/am335x/am335x_lcd.c
+++ sys/arm/ti/am335x/am335x_lcd.c
@@ -242,7 +242,7 @@
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;
@@ -676,7 +676,7 @@
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;
Index: sys/arm/ti/am335x/am335x_musb.c
===================================================================
--- /dev/null
+++ sys/arm/ti/am335x/am335x_musb.c
@@ -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);
Index: sys/arm/ti/am335x/am335x_pmic.c
===================================================================
--- sys/arm/ti/am335x/am335x_pmic.c
+++ sys/arm/ti/am335x/am335x_pmic.c
@@ -110,12 +110,12 @@
{
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);
+ sc->sc_addr = iicbus_get_addr(dev) * 2;
device_set_desc(dev, "TI TPS65217 Power Management IC");
Index: sys/arm/ti/am335x/am335x_prcm.c
===================================================================
--- sys/arm/ti/am335x/am335x_prcm.c
+++ sys/arm/ti/am335x/am335x_prcm.c
@@ -389,7 +389,7 @@
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);
}
@@ -417,10 +417,15 @@
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);
}
Index: sys/arm/ti/am335x/am335x_pwm.h
===================================================================
--- sys/arm/ti/am335x/am335x_pwm.h
+++ sys/arm/ti/am335x/am335x_pwm.h
@@ -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__ */
Index: sys/arm/ti/am335x/am335x_pwm.c
===================================================================
--- sys/arm/ti/am335x/am335x_pwm.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*-
- * 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 <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
-#define PWM_CLOCK 100000000UL
-
-#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)
-#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_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)
-
-#define EPWM_TBCTL 0x00
-#define TBCTL_FREERUN (2 << 14)
-#define TBCTL_PHDIR_UP (1 << 13)
-#define TBCTL_PHDIR_DOWN (0 << 13)
-#define TBCTL_CLKDIV(x) ((x) << 10)
-#define TBCTL_CLKDIV_MASK (3 << 10)
-#define TBCTL_HSPCLKDIV(x) ((x) << 7)
-#define TBCTL_HSPCLKDIV_MASK (3 << 7)
-#define TBCTL_SYNCOSEL_DISABLED (3 << 4)
-#define TBCTL_PRDLD_SHADOW (0 << 3)
-#define TBCTL_PRDLD_IMMEDIATE (0 << 3)
-#define TBCTL_PHSEN_ENABLED (1 << 2)
-#define TBCTL_PHSEN_DISABLED (0 << 2)
-#define TBCTL_CTRMODE_MASK (3)
-#define TBCTL_CTRMODE_UP (0 << 0)
-#define TBCTL_CTRMODE_DOWN (1 << 0)
-#define TBCTL_CTRMODE_UPDOWN (2 << 0)
-#define TBCTL_CTRMODE_FREEZE (3 << 0)
-
-#define EPWM_TBSTS 0x02
-#define EPWM_TBPHSHR 0x04
-#define EPWM_TBPHS 0x06
-#define EPWM_TBCNT 0x08
-#define EPWM_TBPRD 0x0a
-/* Counter-compare */
-#define EPWM_CMPCTL 0x0e
-#define CMPCTL_SHDWBMODE_SHADOW (1 << 6)
-#define CMPCTL_SHDWBMODE_IMMEDIATE (0 << 6)
-#define CMPCTL_SHDWAMODE_SHADOW (1 << 4)
-#define CMPCTL_SHDWAMODE_IMMEDIATE (0 << 4)
-#define CMPCTL_LOADBMODE_ZERO (0 << 2)
-#define CMPCTL_LOADBMODE_PRD (1 << 2)
-#define CMPCTL_LOADBMODE_EITHER (2 << 2)
-#define CMPCTL_LOADBMODE_FREEZE (3 << 2)
-#define CMPCTL_LOADAMODE_ZERO (0 << 0)
-#define CMPCTL_LOADAMODE_PRD (1 << 0)
-#define CMPCTL_LOADAMODE_EITHER (2 << 0)
-#define CMPCTL_LOADAMODE_FREEZE (3 << 0)
-#define EPWM_CMPAHR 0x10
-#define EPWM_CMPA 0x12
-#define EPWM_CMPB 0x14
-/* CMPCTL_LOADAMODE_ZERO */
-#define EPWM_AQCTLA 0x16
-#define EPWM_AQCTLB 0x18
-#define AQCTL_CBU_NONE (0 << 8)
-#define AQCTL_CBU_CLEAR (1 << 8)
-#define AQCTL_CBU_SET (2 << 8)
-#define AQCTL_CBU_TOGGLE (3 << 8)
-#define AQCTL_CAU_NONE (0 << 4)
-#define AQCTL_CAU_CLEAR (1 << 4)
-#define AQCTL_CAU_SET (2 << 4)
-#define AQCTL_CAU_TOGGLE (3 << 4)
-#define AQCTL_ZRO_NONE (0 << 0)
-#define AQCTL_ZRO_CLEAR (1 << 0)
-#define AQCTL_ZRO_SET (2 << 0)
-#define AQCTL_ZRO_TOGGLE (3 << 0)
-#define EPWM_AQSFRC 0x1a
-#define EPWM_AQCSFRC 0x1c
-
-/* Trip-Zone module */
-#define EPWM_TZCTL 0x28
-#define EPWM_TZFLG 0x2C
-/* High-Resolution PWM */
-#define EPWM_HRCTL 0x40
-#define HRCTL_DELMODE_BOTH 3
-#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 };
-
-struct am335x_pwm_softc {
- device_t sc_dev;
- struct mtx sc_mtx;
- struct resource *sc_mem_res[4];
- int sc_id;
- /* sysctl for configuration */
- int sc_pwm_clkdiv;
- int sc_pwm_freq;
- struct sysctl_oid *sc_clkdiv_oid;
- struct sysctl_oid *sc_freq_oid;
- struct sysctl_oid *sc_period_oid;
- struct sysctl_oid *sc_chanA_oid;
- struct sysctl_oid *sc_chanB_oid;
- uint32_t sc_pwm_period;
- uint32_t sc_pwm_dutyA;
- 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),
-
- DEVMETHOD_END
-};
-
-static driver_t am335x_pwm_driver = {
- "am335x_pwm",
- am335x_pwm_methods,
- sizeof(struct am335x_pwm_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 void
-am335x_pwm_freq(struct am335x_pwm_softc *sc)
-{
- int clkdiv;
-
- clkdiv = am335x_pwm_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)
-{
- int clkdiv, error, freq, i, period;
- struct am335x_pwm_softc *sc;
- uint32_t reg;
-
- sc = (struct am335x_pwm_softc *)arg1;
-
- PWM_LOCK(sc);
- freq = sc->sc_pwm_freq;
- PWM_UNLOCK(sc);
-
- error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
- if (error != 0 || req->newptr == NULL)
- return (error);
-
- if (freq > PWM_CLOCK)
- freq = PWM_CLOCK;
-
- PWM_LOCK(sc);
- if (freq != sc->sc_pwm_freq) {
- for (i = nitems(am335x_pwm_clkdiv) - 1; i >= 0; i--) {
- clkdiv = am335x_pwm_clkdiv[i];
- period = PWM_CLOCK / clkdiv / freq;
- if (period > USHRT_MAX)
- break;
- sc->sc_pwm_clkdiv = i;
- sc->sc_pwm_period = period;
- }
- /* Reset the duty cycle settings. */
- sc->sc_pwm_dutyA = 0;
- sc->sc_pwm_dutyB = 0;
- EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
- EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
- /* Update the clkdiv settings. */
- reg = EPWM_READ2(sc, EPWM_TBCTL);
- reg &= ~TBCTL_CLKDIV_MASK;
- reg |= TBCTL_CLKDIV(sc->sc_pwm_clkdiv);
- EPWM_WRITE2(sc, EPWM_TBCTL, reg);
- /* Update the period settings. */
- EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
- am335x_pwm_freq(sc);
- }
- PWM_UNLOCK(sc);
-
- return (0);
-}
-
-static int
-am335x_pwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
-{
- int error, i, clkdiv;
- struct am335x_pwm_softc *sc;
- uint32_t reg;
-
- sc = (struct am335x_pwm_softc *)arg1;
-
- PWM_LOCK(sc);
- clkdiv = am335x_pwm_clkdiv[sc->sc_pwm_clkdiv];
- PWM_UNLOCK(sc);
-
- error = sysctl_handle_int(oidp, &clkdiv, sizeof(clkdiv), req);
- if (error != 0 || req->newptr == NULL)
- 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])
- 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);
- }
- PWM_UNLOCK(sc);
-
- return (0);
-}
-
-static int
-am335x_pwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
-{
- struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
- int error;
- uint32_t duty;
-
- if (oidp == sc->sc_chanA_oid)
- duty = sc->sc_pwm_dutyA;
- else
- duty = sc->sc_pwm_dutyB;
- error = sysctl_handle_int(oidp, &duty, 0, req);
-
- if (error != 0 || req->newptr == NULL)
- return (error);
-
- if (duty > sc->sc_pwm_period) {
- device_printf(sc->sc_dev, "Duty cycle can't be greater then period\n");
- return (EINVAL);
- }
-
- PWM_LOCK(sc);
- if (oidp == sc->sc_chanA_oid) {
- sc->sc_pwm_dutyA = duty;
- EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
- }
- else {
- sc->sc_pwm_dutyB = duty;
- EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
- }
- PWM_UNLOCK(sc);
-
- return (error);
-}
-
-static int
-am335x_pwm_sysctl_period(SYSCTL_HANDLER_ARGS)
-{
- struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
- int error;
- uint32_t period;
-
- period = sc->sc_pwm_period;
- error = sysctl_handle_int(oidp, &period, 0, req);
-
- if (error != 0 || req->newptr == NULL)
- return (error);
-
- if (period < 1)
- return (EINVAL);
-
- if (period > USHRT_MAX)
- period = USHRT_MAX;
-
- PWM_LOCK(sc);
- /* Reset the duty cycle settings. */
- sc->sc_pwm_dutyA = 0;
- sc->sc_pwm_dutyB = 0;
- EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
- EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
- /* Update the period settings. */
- sc->sc_pwm_period = period;
- EPWM_WRITE2(sc, EPWM_TBPRD, period - 1);
- am335x_pwm_freq(sc);
- PWM_UNLOCK(sc);
-
- return (error);
-}
-
-static int
-am335x_pwm_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "ti,am335x-pwm"))
- return (ENXIO);
-
- device_set_desc(dev, "AM335x PWM");
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-am335x_pwm_attach(device_t dev)
-{
- struct am335x_pwm_softc *sc;
- int err;
- 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) {
- 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 |= (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");
-
- 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");
-
- 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");
-
- 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");
-
- 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");
-
- /* CONFIGURE EPWM1 */
- reg = EPWM_READ2(sc, EPWM_TBCTL);
- reg &= ~(TBCTL_CLKDIV_MASK | TBCTL_HSPCLKDIV_MASK);
- EPWM_WRITE2(sc, EPWM_TBCTL, reg);
-
- sc->sc_pwm_period = DEFAULT_PWM_PERIOD;
- sc->sc_pwm_dutyA = 0;
- sc->sc_pwm_dutyB = 0;
- am335x_pwm_freq(sc);
-
- EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
- EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
- EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
-
- EPWM_WRITE2(sc, EPWM_AQCTLA, (AQCTL_ZRO_SET | AQCTL_CAU_CLEAR));
- EPWM_WRITE2(sc, EPWM_AQCTLB, (AQCTL_ZRO_SET | AQCTL_CBU_CLEAR));
-
- /* START EPWM */
- reg &= ~TBCTL_CTRMODE_MASK;
- reg |= TBCTL_CTRMODE_UP | TBCTL_FREERUN;
- EPWM_WRITE2(sc, EPWM_TBCTL, reg);
-
- EPWM_WRITE2(sc, EPWM_TZCTL, 0xf);
- reg = EPWM_READ2(sc, EPWM_TZFLG);
-
- 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);
-
- return(ENXIO);
-}
-
-static int
-am335x_pwm_detach(device_t dev)
-{
- struct am335x_pwm_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);
- PWM_UNLOCK(sc);
-
- PWM_LOCK_DESTROY(sc);
-
- 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);
Index: sys/arm/ti/am335x/am335x_pwmss.c
===================================================================
--- /dev/null
+++ sys/arm/ti/am335x/am335x_pwmss.c
@@ -0,0 +1,154 @@
+/*-
+ * 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_hwmods.h>
+#include <arm/ti/ti_prcm.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;
+ int sc_id;
+};
+
+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),
+
+ /* Bus interface */
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource,bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_get_resource_list, bus_generic_get_resource_list),
+
+ /* OFW bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, ofw_bus_gen_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
+ DEVMETHOD_END
+};
+
+static driver_t am335x_pwmss_driver = {
+ "am335x_pwmss",
+ am335x_pwmss_methods,
+ sizeof(struct am335x_pwmss_softc),
+};
+
+static devclass_t am335x_pwmss_devclass;
+
+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;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ sc->sc_id = ti_hwmods_get_unit(dev, "pwmss");
+ if (sc->sc_id < 0) {
+ device_printf(dev, "failed to get device id based on ti,hwmods\n");
+ return (EINVAL);
+ }
+
+ ti_prcm_clk_enable(PWMSS0_CLK + sc->sc_id);
+ ti_scm_reg_read_4(SCM_PWMSS_CTRL, ®);
+ reg |= (1 << sc->sc_id);
+ ti_scm_reg_write_4(SCM_PWMSS_CTRL, reg);
+
+ simplebus_attach_children(dev);
+
+ return (0);
+}
+
+static int
+am335x_pwmss_detach(device_t dev)
+{
+
+ return (0);
+}
+
+DRIVER_MODULE(am335x_pwmss, simplebus, am335x_pwmss_driver, am335x_pwmss_devclass, 0, 0);
+MODULE_VERSION(am335x_pwmss, 1);
+MODULE_DEPEND(am335x_pwmss, simplebus, 1, 1, 1);
Index: sys/arm/ti/am335x/am335x_scm_padconf.c
===================================================================
--- sys/arm/ti/am335x/am335x_scm_padconf.c
+++ sys/arm/ti/am335x/am335x_scm_padconf.c
@@ -45,7 +45,7 @@
#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 @@
.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 @@
{ .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,
Index: sys/arm/ti/am335x/am335x_usbss.c
===================================================================
--- sys/arm/ti/am335x/am335x_usbss.c
+++ sys/arm/ti/am335x/am335x_usbss.c
@@ -46,6 +46,7 @@
#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 @@
#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,28 @@
#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))
-
-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 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;
+ bus_read_4((sc)->sc_mem_res, (reg))
-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 usbss_probe;
+static device_attach_t usbss_attach;
+static device_detach_t usbss_detach;
-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;
+struct usbss_softc {
+ struct resource *sc_mem_res;
+ int sc_mem_rid;
};
-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 +126,21 @@
}
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;
/* 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,184 +165,63 @@
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;
- }
-
- 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];
-
- sc->sc_otg[i].sc_ep_int_set = musbotg_ep_int_set;
-
- /* 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;
-
- /* 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);
- }
+ simplebus_attach_children(dev);
return (0);
-
-error:
- musbotg_detach(dev);
- return (ENXIO);
}
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),
+ /* Bus interface */
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource,bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_get_resource_list, bus_generic_get_resource_list),
+
+ /* OFW bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, ofw_bus_gen_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
DEVMETHOD_END
};
-static driver_t musbotg_driver = {
- .name = "musbotg",
- .methods = musbotg_methods,
- .size = sizeof(struct musbotg_super_softc),
+static driver_t usbss_driver = {
+ .name = "usbss",
+ .methods = usbss_methods,
+ .size = sizeof(struct usbss_softc),
};
-static devclass_t musbotg_devclass;
+static devclass_t usbss_devclass;
-DRIVER_MODULE(musbotg, simplebus, musbotg_driver, musbotg_devclass, 0, 0);
-MODULE_DEPEND(musbotg, usb, 1, 1, 1);
+DRIVER_MODULE(usbss, simplebus, usbss_driver, usbss_devclass, 0, 0);
+MODULE_DEPEND(usbss, usb, 1, 1, 1);
Index: sys/arm/ti/am335x/files.am335x
===================================================================
--- sys/arm/ti/am335x/files.am335x
+++ sys/arm/ti/am335x/files.am335x
@@ -8,10 +8,13 @@
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
Index: sys/arm/ti/cpsw/if_cpsw.c
===================================================================
--- sys/arm/ti/cpsw/if_cpsw.c
+++ sys/arm/ti/cpsw/if_cpsw.c
@@ -195,8 +195,7 @@
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 @@
/*
* 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 @@
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 @@
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 = fdt32_to_cpu(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 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_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 @@
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);
Index: sys/arm/ti/cpsw/if_cpswreg.h
===================================================================
--- sys/arm/ti/cpsw/if_cpswreg.h
+++ sys/arm/ti/cpsw/if_cpswreg.h
@@ -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)
Index: sys/arm/ti/cpsw/if_cpswvar.h
===================================================================
--- sys/arm/ti/cpsw/if_cpswvar.h
+++ sys/arm/ti/cpsw/if_cpswvar.h
@@ -78,7 +78,9 @@
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. */
Index: sys/arm/ti/files.ti
===================================================================
--- sys/arm/ti/files.ti
+++ sys/arm/ti/files.ti
@@ -13,9 +13,11 @@
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
Index: sys/arm/ti/ti_adc.c
===================================================================
--- sys/arm/ti/ti_adc.c
+++ sys/arm/ti/ti_adc.c
@@ -467,7 +467,7 @@
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");
Index: sys/arm/ti/ti_common.c
===================================================================
--- sys/arm/ti/ti_common.c
+++ sys/arm/ti/ti_common.c
@@ -74,7 +74,8 @@
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]);
Index: sys/arm/ti/ti_edma3.c
===================================================================
--- sys/arm/ti/ti_edma3.c
+++ sys/arm/ti/ti_edma3.c
@@ -99,7 +99,11 @@
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 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 @@
/* 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);
Index: sys/arm/ti/ti_gpio.h
===================================================================
--- sys/arm/ti/ti_gpio.h
+++ sys/arm/ti/ti_gpio.h
@@ -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 @@
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 */
Index: sys/arm/ti/ti_gpio.c
===================================================================
--- sys/arm/ti/ti_gpio.c
+++ sys/arm/ti/ti_gpio.c
@@ -49,6 +49,7 @@
#include <machine/resource.h>
#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
@@ -101,54 +102,18 @@
#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)
{
switch(ti_chip()) {
@@ -181,47 +146,6 @@
}
/**
- * 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
*/
#define TI_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
@@ -244,9 +168,9 @@
* 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 @@
* 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 @@
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 @@
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 @@
}
/* 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 @@
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 @@
* 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 @@
/* 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,10 @@
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,7 +564,7 @@
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);
@@ -655,87 +573,87 @@
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);
- }
+ if (sc->sc_irq_res == NULL)
+ return (-1);
+
+ /*
+ * 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");
+ return (-1);
}
return (0);
}
-static int
+static void
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_res == NULL)
+ return;
- if (sc->sc_irq_hdl[i]) {
- bus_teardown_intr(dev, sc->sc_irq_res[i],
- sc->sc_irq_hdl[i]);
- }
+ if (sc->sc_irq_hdl) {
+ bus_teardown_intr(dev, sc->sc_irq_res,
+ sc->sc_irq_hdl);
}
-
- 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;
+ int hwmod;
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);
+ hwmod = ti_hwmods_get_unit(dev, "gpio") - 1;
+ if (hwmod <= 0) {
+ device_printf(dev, "failed to get device id based on ti,hwmods\n");
+ return (EINVAL);
+ }
+
+ sc->sc_bank = ti_first_gpio_bank() + hwmod;
+ ti_prcm_clk_enable(GPIO0_CLK + sc->sc_bank);
/*
* 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,27 +678,25 @@
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);
@@ -811,21 +727,23 @@
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 +770,27 @@
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);
+ 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 +819,57 @@
}
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(void *source)
+ti_gpio_unmask_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);
- reg = ti_gpio_intr_reg(ti_gpio_sc, irq);
+ TI_GPIO_LOCK(sc);
+ 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_intr_set(ti_gpio_sc, TI_GPIO_BANK(irq),
- TI_GPIO_MASK(irq));
+ ti_gpio_write_4(sc, reg, val);
+ ti_gpio_intr_set(sc, TI_GPIO_MASK(irq));
}
- TI_GPIO_UNLOCK(ti_gpio_sc);
+ 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)
+{
+ struct ti_gpio_mask_arg *arg = source;
+
+ ti_gpio_unmask_irq_internal(arg->softc, arg->pin);
}
static int
@@ -1000,15 +930,15 @@
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 +961,9 @@
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)
Index: sys/arm/ti/ti_hwmods.h
===================================================================
--- /dev/null
+++ sys/arm/ti/ti_hwmods.h
@@ -0,0 +1,33 @@
+/*-
+ * 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_
+
+int ti_hwmods_get_unit(device_t dev, const char *hwname);
+
+#endif /* _TI_HWMODS_H_ */
Index: sys/arm/ti/ti_hwmods.c
===================================================================
--- /dev/null
+++ sys/arm/ti/ti_hwmods.c
@@ -0,0 +1,83 @@
+/*-
+ * 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_hwmods.h>
+
+int
+ti_hwmods_get_unit(device_t dev, const char *hwname)
+{
+ phandle_t node;
+ int len, hwlen, l;
+ char *name;
+ int unit;
+
+ unit = -1;
+ hwlen = strlen(hwname);
+
+ if ((node = ofw_bus_get_node(dev)) == 0)
+ return (-1);
+
+ if ((len = OF_getproplen(node, "ti,hwmods")) <= 0)
+ return (-1);
+
+ name = malloc(len + 1, M_DEVBUF, M_NOWAIT);
+ if (OF_getprop(node, "ti,hwmods", (void*)name, len) <= 0) {
+ free(name, M_DEVBUF);
+ return (-1);
+ }
+
+ while (len > 0) {
+ if (strncmp(hwname, name, hwlen) == 0) {
+ unit = (int)strtol(name + hwlen, NULL, 10);
+ break;
+ }
+ /* Slide to the next sub-string. */
+ l = strlen(name) + 1;
+ name += l;
+ len -= l;
+ }
+
+ free(name, M_DEVBUF);
+ return (unit);
+}
Index: sys/arm/ti/ti_i2c.c
===================================================================
--- sys/arm/ti/ti_i2c.c
+++ sys/arm/ti/ti_i2c.c
@@ -66,6 +66,7 @@
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_i2c.h>
@@ -81,7 +82,7 @@
struct ti_i2c_softc
{
device_t sc_dev;
- uint32_t device_id;
+ int device_id;
struct resource* sc_irq_res;
struct resource* sc_mem_res;
device_t sc_iicbus;
@@ -815,7 +816,7 @@
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 +838,10 @@
/* 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->device_id = ti_hwmods_get_unit(dev, "i2c") - 1;
+ if (sc->device_id < 0) {
+ device_printf(dev, "failed to get device id using ti,hwmod\n");
return (ENXIO);
}
Index: sys/arm/ti/ti_pinmux.h
===================================================================
--- /dev/null
+++ sys/arm/ti/ti_pinmux.h
@@ -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_ */
Index: sys/arm/ti/ti_pinmux.c
===================================================================
--- /dev/null
+++ sys/arm/ti/ti_pinmux.c
@@ -0,0 +1,529 @@
+/*
+ * Copyright (c) 2010
+ * Ben Gray <ben.r.gray@gmail.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * SCM - System Control Module
+ *
+ * Hopefully in the end this module will contain a bunch of utility functions
+ * for configuring and querying the general system control registers, but for
+ * now it only does pin(pad) multiplexing.
+ *
+ * This is different from the GPIO module in that it is used to configure the
+ * pins between modules not just GPIO input/output.
+ *
+ * This file contains the generic top level driver, however it relies on chip
+ * specific settings and therefore expects an array of ti_pinmux_padconf structs
+ * call ti_padconf_devmap to be located somewhere in the kernel.
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <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);
+}
+
+/**
+ * ti_pinmux_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_pinmux_padconf_init_from_fdt(struct ti_pinmux_softc *sc)
+{
+ const struct ti_pinmux_padconf *padconf;
+ const struct ti_pinmux_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_pinmux_dev.padconf;
+
+ while (padconf->ballname != NULL) {
+ if (strcmp(padconf->ballname, padname) == 0) {
+ padstates = ti_pinmux_dev.padstate;
+ err = 1;
+ while (padstates->state != NULL) {
+ if (strcmp(padstates->state, padstate) == 0) {
+ err = ti_pinmux_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);
+}
+
+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);
+
+ device_set_desc(dev, "TI Control Module");
+ return (BUS_PROBE_DEFAULT);
+}
+
+/**
+ * ti_pinmux_attach - attaches the timer to the simplebus
+ * @dev: new device
+ *
+ * Reserves memory and interrupt resources, stores the softc structure
+ * globally and registers both the timecount and eventtimer objects.
+ *
+ * RETURNS
+ * Zero on 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 (ti_pinmux_sc)
+ return (ENXIO);
+
+ 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);
+ }
+
+ /* Global timer interface */
+ sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
+ sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
+
+ ti_pinmux_sc = sc;
+
+ ti_pinmux_padconf_init_from_fdt(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, ofwbus, ti_pinmux_driver, ti_pinmux_devclass, 0, 0);
Index: sys/arm/ti/ti_scm.h
===================================================================
--- sys/arm/ti/ti_scm.h
+++ sys/arm/ti/ti_scm.h
@@ -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 @@
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);
Index: sys/arm/ti/ti_scm.c
===================================================================
--- sys/arm/ti/ti_scm.c
+++ sys/arm/ti/ti_scm.c
@@ -64,6 +64,7 @@
#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,352 +78,21 @@
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);
device_set_desc(dev, "TI Control Module");
@@ -460,8 +130,6 @@
ti_scm_sc = sc;
- ti_scm_padconf_init_from_fdt(sc);
-
return (0);
}
@@ -489,6 +157,7 @@
static device_method_t ti_scm_methods[] = {
DEVMETHOD(device_probe, ti_scm_probe),
DEVMETHOD(device_attach, ti_scm_attach),
+
{ 0, 0 }
};
@@ -500,4 +169,4 @@
static devclass_t ti_scm_devclass;
-DRIVER_MODULE(ti_scm, simplebus, ti_scm_driver, ti_scm_devclass, 0, 0);
+DRIVER_MODULE(ti_scm, ofwbus, ti_scm_driver, ti_scm_devclass, 0, 0);
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -1395,7 +1395,7 @@
dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl
dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand
dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \
- dependency "$S/boot/fdt/dts/${MACHINE}/${FDT_DTS_FILE}"
+ dependency "fdt_static_dtb.h"
dev/fdt/simplebus.c optional fdt
dev/fe/if_fe.c optional fe
dev/fe/if_fe_pccard.c optional fe pccard
Index: sys/dev/fdt/simplebus.h
===================================================================
--- sys/dev/fdt/simplebus.h
+++ sys/dev/fdt/simplebus.h
@@ -53,4 +53,6 @@
struct ofw_bus_devinfo obdinfo;
struct resource_list rl;
};
+
+int simplebus_attach_children(device_t);
#endif /* _FDT_SIMPLEBUS_PRIVATE_H */
Index: sys/dev/fdt/simplebus.c
===================================================================
--- sys/dev/fdt/simplebus.c
+++ sys/dev/fdt/simplebus.c
@@ -63,7 +63,7 @@
static int simplebus_fill_ranges(phandle_t node,
struct simplebus_softc *sc);
static struct simplebus_devinfo *simplebus_setup_dinfo(device_t dev,
- phandle_t node);
+ phandle_t node, pcell_t acells, pcell_t scells);
/*
* Driver methods.
@@ -161,7 +161,7 @@
*/
for (node = OF_child(node); node > 0; node = OF_peer(node)) {
- if ((di = simplebus_setup_dinfo(dev, node)) == NULL)
+ if ((di = simplebus_setup_dinfo(dev, node, sc->acells, sc->scells)) == NULL)
continue;
cdev = device_add_child(dev, NULL, -1);
if (cdev == NULL) {
@@ -228,13 +228,10 @@
}
static struct simplebus_devinfo *
-simplebus_setup_dinfo(device_t dev, phandle_t node)
+simplebus_setup_dinfo(device_t dev, phandle_t node, pcell_t acells, pcell_t scells)
{
- struct simplebus_softc *sc;
struct simplebus_devinfo *ndi;
- sc = device_get_softc(dev);
-
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) {
free(ndi, M_DEVBUF);
@@ -242,7 +239,7 @@
}
resource_list_init(&ndi->rl);
- ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells, &ndi->rl);
+ ofw_bus_reg_to_rl(dev, node, acells, scells, &ndi->rl);
ofw_bus_intr_to_rl(dev, node, &ndi->rl);
return (ndi);
@@ -362,3 +359,39 @@
rv += bus_print_child_footer(bus, child);
return (rv);
}
+
+int
+simplebus_attach_children(device_t dev)
+{
+ struct simplebus_devinfo *di;
+ phandle_t node;
+ device_t cdev;
+ pcell_t acells, scells;
+
+ node = ofw_bus_get_node(dev);
+
+ /*
+ * Some important numbers
+ */
+ acells = 2;
+ OF_getencprop(node, "#address-cells", &acells, sizeof(acells));
+ scells = 1;
+ OF_getencprop(node, "#size-cells", &scells, sizeof(scells));
+
+ for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+ if ((di = simplebus_setup_dinfo(dev, node, acells, scells)) == NULL)
+ continue;
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev == NULL) {
+ device_printf(dev, "<%s>: device_add_child failed\n",
+ di->obdinfo.obd_name);
+ resource_list_free(&di->rl);
+ ofw_bus_gen_destroy_devinfo(&di->obdinfo);
+ free(di, M_DEVBUF);
+ continue;
+ }
+ device_set_ivars(cdev, di);
+ }
+
+ return (bus_generic_attach(dev));
+}
Index: sys/dev/ofw/ofw_bus_subr.h
===================================================================
--- sys/dev/ofw/ofw_bus_subr.h
+++ sys/dev/ofw/ofw_bus_subr.h
@@ -55,6 +55,7 @@
/* Generic implementation of ofw_bus_if.m methods and helper routines */
int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t);
void ofw_bus_gen_destroy_devinfo(struct ofw_bus_devinfo *);
+const struct ofw_bus_devinfo * ofw_bus_gen_get_devinfo(device_t bus, device_t dev);
ofw_bus_get_compat_t ofw_bus_gen_get_compat;
ofw_bus_get_model_t ofw_bus_gen_get_model;
Index: sys/dev/ofw/ofw_bus_subr.c
===================================================================
--- sys/dev/ofw/ofw_bus_subr.c
+++ sys/dev/ofw/ofw_bus_subr.c
@@ -97,6 +97,13 @@
return (0);
};
+const struct ofw_bus_devinfo *
+ofw_bus_gen_get_devinfo(device_t bus, device_t dev)
+{
+
+ return OFW_BUS_GET_DEVINFO(device_get_parent(bus), dev);
+}
+
const char *
ofw_bus_gen_get_compat(device_t bus, device_t dev)
{
Index: sys/dev/uart/uart_bus.h
===================================================================
--- sys/dev/uart/uart_bus.h
+++ sys/dev/uart/uart_bus.h
@@ -70,6 +70,7 @@
struct uart_ops *uc_ops; /* Low-level console operations. */
u_int uc_range; /* Bus space address range. */
u_int uc_rclk; /* Default rclk for this device. */
+ u_int uc_regshft; /* Default regshift for this device. */
};
struct uart_softc {
Index: sys/dev/uart/uart_bus_fdt.c
===================================================================
--- sys/dev/uart/uart_bus_fdt.c
+++ sys/dev/uart/uart_bus_fdt.c
@@ -86,6 +86,7 @@
{"lpc,uart", (uintptr_t)&uart_lpc_class},
{"qcom,msm-uartdm", (uintptr_t)&uart_msm_class},
{"ti,ns16550", (uintptr_t)&uart_ti8250_class},
+ {"ti,omap3-uart", (uintptr_t)&uart_ti8250_class},
{"ns16550", (uintptr_t)&uart_ns8250_class},
{NULL, (uintptr_t)NULL},
};
@@ -122,7 +123,7 @@
pcell_t shift;
if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0)
- shift = 0;
+ return (-1);
*cell = fdt32_to_cpu(shift);
return (0);
}
@@ -151,7 +152,8 @@
if ((err = uart_fdt_get_clock(node, &clock)) != 0)
return (err);
- uart_fdt_get_shift(node, &shift);
+ if (uart_fdt_get_shift(node, &shift) < 0)
+ shift = sc->sc_class->uc_regshft;
return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
}
Index: sys/dev/uart/uart_cpu_fdt.c
===================================================================
--- sys/dev/uart/uart_cpu_fdt.c
+++ sys/dev/uart/uart_cpu_fdt.c
@@ -83,10 +83,12 @@
{
pcell_t shift;
- if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0)
- shift = 0;
- *cell = fdt32_to_cpu(shift);
- return (0);
+ if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) > 0) {
+ *cell = fdt32_to_cpu(shift);
+ return (0);
+ }
+
+ return (-1);
}
int
@@ -159,7 +161,6 @@
/*
* Retrieve serial attributes.
*/
- uart_fdt_get_shift(node, &shift);
if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
br = 0;
@@ -178,6 +179,9 @@
return (ENXIO);
class = (struct uart_class *)cd->ocd_data;
+ if (uart_fdt_get_shift(node, &shift) < 0)
+ shift = class->uc_regshft;
+
di->bas.chan = 0;
di->bas.regshft = (u_int)shift;
di->baudrate = br;
Index: sys/dev/uart/uart_dev_ti8250.c
===================================================================
--- sys/dev/uart/uart_dev_ti8250.c
+++ sys/dev/uart/uart_dev_ti8250.c
@@ -136,6 +136,7 @@
sizeof(struct ti8250_softc),
.uc_ops = &uart_ns8250_ops,
.uc_range = 0x88,
- .uc_rclk = 48000000
+ .uc_rclk = 48000000,
+ .uc_regshft = 2
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jun 13, 11:56 PM (17 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33936608
Default Alt Text
D2146.id4427.diff (197 KB)
Attached To
Mode
D2146: Rewrite TI platforms support to use vendor DTS files
Attached
Detach File
Event Timeline
Log In to Comment