summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/db_trace.c4
-rw-r--r--sys/arm/arm/elf_trampoline.c23
-rw-r--r--sys/arm/arm/generic_timer.c56
-rw-r--r--sys/arm/arm/pmap-v6.c2
-rw-r--r--sys/arm/arm/trap.c12
-rw-r--r--sys/arm/arm/vfp.c39
-rw-r--r--sys/arm/arm/vm_machdep.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_fb.c11
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.c102
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.h3
-rw-r--r--sys/arm/broadcom/bcm2835/files.bcm28352
-rw-r--r--sys/arm/broadcom/bcm2835/std.bcm28357
-rw-r--r--sys/arm/broadcom/bcm2835/std.rpi12
-rw-r--r--sys/arm/conf/BEAGLEBONE4
-rw-r--r--sys/arm/conf/RPI-B13
-rw-r--r--sys/arm/ti/am335x/am335x_pmic.c8
-rw-r--r--sys/arm/ti/am335x/am335x_usbss.c481
-rw-r--r--sys/arm/ti/am335x/files.am335x1
-rw-r--r--sys/arm/ti/ti_mmchs.c17
-rw-r--r--sys/arm/ti/ti_mmchs.h6
20 files changed, 674 insertions, 131 deletions
diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c
index 6b72cde..99c27fc 100644
--- a/sys/arm/arm/db_trace.c
+++ b/sys/arm/arm/db_trace.c
@@ -515,11 +515,11 @@ db_stack_trace_cmd(db_expr_t addr, db_expr_t count, boolean_t kernel_only)
db_printsym(scp, DB_STGY_PROC);
db_printf("\n");
#ifdef __PROG26
- db_printf("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
+ db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC);
db_printf(")\n");
#else
- db_printf("scp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
+ db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
db_printsym(frame[FR_RLV], DB_STGY_PROC);
db_printf(")\n");
#endif
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index fe03adf..87be924 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -49,42 +49,59 @@ void _start(void);
void __start(void);
void __startC(void);
+extern unsigned int cpufunc_id(void);
+extern void armv6_idcache_wbinv_all(void);
+extern void armv7_idcache_wbinv_all(void);
+extern void do_call(void *, void *, void *, int);
+
#define GZ_HEAD 0xa
#ifdef CPU_ARM7TDMI
#define cpu_idcache_wbinv_all arm7tdmi_cache_flushID
+extern void arm7tdmi_cache_flushID(void);
#elif defined(CPU_ARM8)
#define cpu_idcache_wbinv_all arm8_cache_purgeID
+extern void arm8_cache_purgeID(void);
#elif defined(CPU_ARM9)
#define cpu_idcache_wbinv_all arm9_idcache_wbinv_all
+extern void arm9_idcache_wbinv_all(void);
#elif defined(CPU_FA526) || defined(CPU_FA626TE)
#define cpu_idcache_wbinv_all fa526_idcache_wbinv_all
+extern void fa526_idcache_wbinv_all(void);
#elif defined(CPU_ARM9E)
#define cpu_idcache_wbinv_all armv5_ec_idcache_wbinv_all
+extern void armv5_ec_idcache_wbinv_all(void);
#elif defined(CPU_ARM10)
#define cpu_idcache_wbinv_all arm10_idcache_wbinv_all
+extern void arm10_idcache_wbinv_all(void);
#elif defined(CPU_ARM1136) || defined(CPU_ARM1176)
#define cpu_idcache_wbinv_all armv6_idcache_wbinv_all
#elif defined(CPU_SA110) || defined(CPU_SA1110) || defined(CPU_SA1100) || \
defined(CPU_IXP12X0)
#define cpu_idcache_wbinv_all sa1_cache_purgeID
+extern void sa1_cache_purgeID(void);
#elif defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
defined(CPU_XSCALE_80219)
#define cpu_idcache_wbinv_all xscale_cache_purgeID
+extern void xscale_cache_purgeID(void);
#elif defined(CPU_XSCALE_81342)
#define cpu_idcache_wbinv_all xscalec3_cache_purgeID
+extern void xscalec3_cache_purgeID(void);
#elif defined(CPU_MV_PJ4B)
#if !defined(SOC_MV_ARMADAXP)
#define cpu_idcache_wbinv_all armv6_idcache_wbinv_all
+extern void armv6_idcache_wbinv_all(void);
#else
#define cpu_idcache_wbinv_all() armadaxp_idcache_wbinv_all
#endif
#endif /* CPU_MV_PJ4B */
#ifdef CPU_XSCALE_81342
#define cpu_l2cache_wbinv_all xscalec3_l2cache_purge
+extern void xscalec3_l2cache_purge(void);
#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
#define cpu_l2cache_wbinv_all sheeva_l2cache_wbinv_all
+extern void sheeva_l2cache_wbinv_all(void);
#elif defined(CPU_CORTEXA)
#define cpu_idcache_wbinv_all armv7_idcache_wbinv_all
#define cpu_l2cache_wbinv_all()
@@ -434,11 +451,11 @@ static void *
inflate_kernel(void *kernel, void *startaddr)
{
struct inflate infl;
- char slide[GZ_WSIZE];
+ unsigned char slide[GZ_WSIZE];
orig_input = kernel;
memcnt = memtot = 0;
- i_input = (char *)kernel + GZ_HEAD;
+ i_input = (unsigned char *)kernel + GZ_HEAD;
if (((char *)kernel)[3] & 0x18) {
while (*i_input)
i_input++;
@@ -590,6 +607,8 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
__asm __volatile(".globl func_end\n"
"func_end:");
+ /* NOTREACHED */
+ return NULL;
}
extern char func_end[];
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 48d92ae..7517b24 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -60,28 +60,21 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/fdt.h>
-#define GENERIC_TIMER_CTRL_ENABLE (1 << 0)
-#define GENERIC_TIMER_CTRL_INT_MASK (1 << 1)
-#define GENERIC_TIMER_CTRL_INT_STAT (1 << 2)
-#define GENERIC_TIMER_REG_CTRL 0
-#define GENERIC_TIMER_REG_TVAL 1
-
-#define GENERIC_TIMER_CNTKCTL_PL0PTEN (1 << 9) /* Physical timer registers
- access from PL0 */
-#define GENERIC_TIMER_CNTKCTL_PL0VTEN (1 << 8) /* Virtual timer registers
- access from PL0 */
-#define GENERIC_TIMER_CNTKCTL_EVNTI (1 << 4) /* Virtual counter
- event bits */
-#define GENERIC_TIMER_CNTKCTL_EVNTDIR (1 << 3) /* Virtual counter
- event transition */
-#define GENERIC_TIMER_CNTKCTL_EVNTEN (1 << 2) /* Enables events from
- the virtual counter */
-#define GENERIC_TIMER_CNTKCTL_PL0VCTEN (1 << 1) /* CNTVCT and CNTFRQ
- access from PL0 */
-#define GENERIC_TIMER_CNTKCTL_PL0PCTEN (1 << 0) /* CNTPCT and CNTFRQ
- access from PL0 */
-
-#define GENERIC_TIMER_CNTPSIRQ 29
+#define GT_CTRL_ENABLE (1 << 0)
+#define GT_CTRL_INT_MASK (1 << 1)
+#define GT_CTRL_INT_STAT (1 << 2)
+#define GT_REG_CTRL 0
+#define GT_REG_TVAL 1
+
+#define GT_CNTKCTL_PL0PTEN (1 << 9) /* PL0 Physical timer reg access */
+#define GT_CNTKCTL_PL0VTEN (1 << 8) /* PL0 Virtual timer reg access */
+#define GT_CNTKCTL_EVNTI (1 << 4) /* Virtual counter event bits */
+#define GT_CNTKCTL_EVNTDIR (1 << 3) /* Virtual counter event transition */
+#define GT_CNTKCTL_EVNTEN (1 << 2) /* Enables virtual counter events */
+#define GT_CNTKCTL_PL0VCTEN (1 << 1) /* PL0 CNTVCT and CNTFRQ access */
+#define GT_CNTKCTL_PL0PCTEN (1 << 0) /* PL0 CNTPCT and CNTFRQ access */
+
+#define GT_CNTPSIRQ 29
struct arm_tmr_softc {
struct resource *irq_res;
@@ -182,11 +175,8 @@ disable_user_access(void)
uint32_t cntkctl;
__asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
- cntkctl &= ~(GENERIC_TIMER_CNTKCTL_PL0PTEN |
- GENERIC_TIMER_CNTKCTL_PL0VTEN |
- GENERIC_TIMER_CNTKCTL_EVNTEN |
- GENERIC_TIMER_CNTKCTL_PL0VCTEN |
- GENERIC_TIMER_CNTKCTL_PL0PCTEN);
+ cntkctl &= ~(GT_CNTKCTL_PL0PTEN | GT_CNTKCTL_PL0VTEN |
+ GT_CNTKCTL_EVNTEN | GT_CNTKCTL_PL0VCTEN | GT_CNTKCTL_PL0PCTEN);
__asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
isb();
}
@@ -209,8 +199,8 @@ arm_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
if (first != 0) {
counts = ((uint32_t)et->et_frequency * first) >> 32;
ctrl = get_ctrl();
- ctrl &= ~GENERIC_TIMER_CTRL_INT_MASK;
- ctrl |= GENERIC_TIMER_CTRL_ENABLE;
+ ctrl &= ~GT_CTRL_INT_MASK;
+ ctrl |= GT_CTRL_ENABLE;
set_tval(counts);
set_ctrl(ctrl);
return (0);
@@ -226,7 +216,7 @@ arm_tmr_stop(struct eventtimer *et)
int ctrl;
ctrl = get_ctrl();
- ctrl &= GENERIC_TIMER_CTRL_ENABLE;
+ ctrl &= GT_CTRL_ENABLE;
set_ctrl(ctrl);
return (0);
@@ -240,8 +230,8 @@ arm_tmr_intr(void *arg)
sc = (struct arm_tmr_softc *)arg;
ctrl = get_ctrl();
- if (ctrl & GENERIC_TIMER_CTRL_INT_STAT) {
- ctrl |= GENERIC_TIMER_CTRL_INT_MASK;
+ if (ctrl & GT_CTRL_INT_STAT) {
+ ctrl |= GT_CTRL_INT_MASK;
set_ctrl(ctrl);
}
@@ -289,7 +279,7 @@ arm_tmr_attach(device_t dev)
rid = 0;
sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
- GENERIC_TIMER_CNTPSIRQ, GENERIC_TIMER_CNTPSIRQ,
+ GT_CNTPSIRQ, GT_CNTPSIRQ,
1, RF_SHAREABLE | RF_ACTIVE);
arm_tmr_sc = sc;
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index c0f4c2c..73b899c 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -3336,7 +3336,7 @@ pmap_pv_reclaim(pmap_t locked_pmap)
m = PHYS_TO_VM_PAGE(l2pte_pa(*ptep));
KASSERT((vm_offset_t)m >= KERNBASE,
("Trying to access non-existent page "
- "va %x pte %x in %s", va, *ptep));
+ "va %x pte %x", va, *ptep));
*ptep = 0;
PTE_SYNC(ptep);
pmap_nuke_pv(m, pmap, pv);
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index 08b4396..761169c 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -238,7 +238,7 @@ data_abort_handler(trapframe_t *tf)
int error = 0;
struct ksig ksig;
struct proc *p;
-
+
/* Grab FAR/FSR before enabling interrupts */
far = cpu_faultaddress();
@@ -262,10 +262,10 @@ data_abort_handler(trapframe_t *tf)
if (user) {
td->td_pticks = 0;
- td->td_frame = tf;
+ td->td_frame = tf;
if (td->td_ucred != td->td_proc->p_ucred)
cred_update_thread(td);
-
+
}
/* Grab the current pcb */
pcb = td->td_pcb;
@@ -276,7 +276,7 @@ data_abort_handler(trapframe_t *tf)
if (__predict_true(tf->tf_spsr & F32_bit) == 0)
enable_interrupts(F32_bit);
}
-
+
/* Invoke the appropriate handler, if necessary */
if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
@@ -720,7 +720,7 @@ prefetch_abort_handler(trapframe_t *tf)
printf("prefetch abort handler: %p %p\n", (void*)tf->tf_pc,
(void*)tf->tf_usr_lr);
#endif
-
+
td = curthread;
p = td->td_proc;
PCPU_INC(cnt.v_trap);
@@ -937,7 +937,7 @@ swi_handler(trapframe_t *frame)
struct thread *td = curthread;
td->td_frame = frame;
-
+
td->td_pticks = 0;
/*
* Make sure the program counter is correctly aligned so we
diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c
index d341176..b9dce13 100644
--- a/sys/arm/arm/vfp.c
+++ b/sys/arm/arm/vfp.c
@@ -195,15 +195,27 @@ vfp_restore(struct vfp_state *vfpsave)
{
u_int vfpscr = 0;
+ /*
+ * Work around an issue with GCC where the asm it generates is
+ * not unified syntax and fails to assemble because it expects
+ * the ldcleq instruction in the form ldc<c>l, not in the UAL
+ * form ldcl<c>, and similar for stcleq.
+ */
+#ifdef __clang__
+#define ldclne "ldclne"
+#define stclne "stclne"
+#else
+#define ldclne "ldcnel"
+#define stclne "stcnel"
+#endif
if (vfpsave) {
- __asm __volatile("ldc p10, c0, [%0], #128\n" /* d0-d15 */
- "cmp %0, 0\n" /* -D16 or -D32? */
- "ldcleq p11, c0, [%0], #128\n" /* d16-d31 */
- "addne %0, %0, #128\n" /* skip missing regs */
- "ldr %1, [%0]\n" /* set old vfpscr */
- "mcr p10, 7, %1, cr1, c0, 0\n"
- :: "r" (vfpsave), "r" (vfpscr), "r" (is_d32)
- : "cc");
+ __asm __volatile("ldc p10, c0, [%1], #128\n" /* d0-d15 */
+ "cmp %2, #0\n" /* -D16 or -D32? */
+ ldclne" p11, c0, [%1], #128\n" /* d16-d31 */
+ "addeq %1, %1, #128\n" /* skip missing regs */
+ "ldr %0, [%1]\n" /* set old vfpscr */
+ "mcr p10, 7, %0, cr1, c0, 0\n"
+ : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
PCPU_SET(vfpcthread, PCPU_GET(curthread));
}
}
@@ -225,13 +237,16 @@ vfp_store(struct vfp_state *vfpsave)
tmp = fmrx(VFPEXC); /* Is the vfp enabled? */
if (vfpsave && tmp & VFPEXC_EN) {
__asm __volatile("stc p11, c0, [%1], #128\n" /* d0-d15 */
- "cmp %0, 0\n" /* -D16 or -D32? */
- "stcleq p11, c0, [%1], #128\n" /* d16-d31 */
- "addne %1, %1, #128\n" /* skip missing regs */
+ "cmp %2, #0\n" /* -D16 or -D32? */
+ stclne" p11, c0, [%1], #128\n" /* d16-d31 */
+ "addeq %1, %1, #128\n" /* skip missing regs */
"mrc p10, 7, %0, cr1, c0, 0\n" /* fmxr(VFPSCR) */
"str %0, [%1]\n" /* save vfpscr */
- : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
+ : "=&r" (vfpscr) : "r" (vfpsave), "r" (is_d32) : "cc");
}
+#undef ldcleq
+#undef stcleq
+
#ifndef SMP
/* eventually we will use this information for UP also */
PCPU_SET(vfpcthread, 0);
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 29a213f..3bb76e2 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -251,7 +251,7 @@ sf_buf_alloc(struct vm_page *m, int flags)
if (flags & SFB_NOWAIT)
goto done;
sf_buf_alloc_want++;
- mbstat.sf_allocwait++;
+ SFSTAT_INC(sf_allocwait);
error = msleep(&sf_buf_freelist, &sf_buf_lock,
(flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
sf_buf_alloc_want--;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fb.c b/sys/arm/broadcom/bcm2835/bcm2835_fb.c
index 0f1e81c..879f278 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_fb.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_fb.c
@@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$");
#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+#include "mbox_if.h"
+
#define BCMFB_FONT_HEIGHT 16
struct argb {
@@ -173,6 +175,7 @@ bcm_fb_init(void *arg)
volatile struct bcm_fb_config* fb_config = sc->fb_config;
phandle_t node;
pcell_t cell;
+ device_t mbox;
node = ofw_bus_get_node(sc->dev);
@@ -205,8 +208,12 @@ bcm_fb_init(void *arg)
bus_dmamap_sync(sc->dma_tag, sc->dma_map,
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- bcm_mbox_write(BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
- bcm_mbox_read(BCM2835_MBOX_CHAN_FB, &err);
+
+ mbox = devclass_get_device(devclass_find("mbox"), 0);
+ if (mbox) {
+ MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
+ MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err);
+ }
bus_dmamap_sync(sc->dma_tag, sc->dma_map,
BUS_DMASYNC_POSTREAD);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
index f18102b..4278742 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -49,8 +49,11 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/fdt.h>
+
#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
+#include "mbox_if.h"
+
#define REG_READ 0x00
#define REG_POL 0x10
#define REG_SENDER 0x14
@@ -65,12 +68,12 @@ __FBSDID("$FreeBSD$");
#define MBOX_CHAN(msg) ((msg) & 0xf)
#define MBOX_DATA(msg) ((msg) & ~0xf)
-#define MBOX_LOCK do { \
- mtx_lock(&bcm_mbox_sc->lock); \
+#define MBOX_LOCK(sc) do { \
+ mtx_lock(&(sc)->lock); \
} while(0)
-#define MBOX_UNLOCK do { \
- mtx_unlock(&bcm_mbox_sc->lock); \
+#define MBOX_UNLOCK(sc) do { \
+ mtx_unlock(&(sc)->lock); \
} while(0)
#ifdef DEBUG
@@ -90,12 +93,10 @@ struct bcm_mbox_softc {
int msg[BCM2835_MBOX_CHANS];
};
-static struct bcm_mbox_softc *bcm_mbox_sc = NULL;
-
-#define mbox_read_4(reg) \
- bus_space_read_4(bcm_mbox_sc->bst, bcm_mbox_sc->bsh, reg)
-#define mbox_write_4(reg, val) \
- bus_space_write_4(bcm_mbox_sc->bst, bcm_mbox_sc->bsh, reg, val)
+#define mbox_read_4(sc, reg) \
+ bus_space_read_4((sc)->bst, (sc)->bsh, reg)
+#define mbox_write_4(sc, reg, val) \
+ bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
static void
bcm_mbox_intr(void *arg)
@@ -105,9 +106,9 @@ bcm_mbox_intr(void *arg)
uint32_t data;
uint32_t msg;
- MBOX_LOCK;
- while (!(mbox_read_4(REG_STATUS) & STATUS_EMPTY)) {
- msg = mbox_read_4(REG_READ);
+ MBOX_LOCK(sc);
+ while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) {
+ msg = mbox_read_4(sc, REG_READ);
dprintf("bcm_mbox_intr: raw data %08x\n", msg);
chan = MBOX_CHAN(msg);
data = MBOX_DATA(msg);
@@ -121,7 +122,7 @@ bcm_mbox_intr(void *arg)
wakeup(&sc->msg[chan]);
}
- MBOX_UNLOCK;
+ MBOX_UNLOCK(sc);
}
static int
@@ -143,9 +144,6 @@ bcm_mbox_attach(device_t dev)
int i;
int rid = 0;
- if (bcm_mbox_sc != NULL)
- return (EINVAL);
-
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "could not allocate memory resource\n");
@@ -176,72 +174,76 @@ bcm_mbox_attach(device_t dev)
sc->msg[0] = 0;
}
- bcm_mbox_sc = sc;
/* Read all pending messages */
bcm_mbox_intr(sc);
- /* Should be called after bcm_mbox_sc initialization */
- mbox_write_4(REG_CONFIG, CONFIG_DATA_IRQ);
+ mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ);
return (0);
}
-static device_method_t bcm_mbox_methods[] = {
- DEVMETHOD(device_probe, bcm_mbox_probe),
- DEVMETHOD(device_attach, bcm_mbox_attach),
- { 0, 0 }
-};
-
-static driver_t bcm_mbox_driver = {
- "mbox",
- bcm_mbox_methods,
- sizeof(struct bcm_mbox_softc),
-};
-
-static devclass_t bcm_mbox_devclass;
-
-DRIVER_MODULE(mbox, simplebus, bcm_mbox_driver, bcm_mbox_devclass, 0, 0);
-
/*
* Mailbox API
*/
-int
-bcm_mbox_write(int chan, uint32_t data)
+static int
+bcm_mbox_write(device_t dev, int chan, uint32_t data)
{
int limit = 20000;
+ struct bcm_mbox_softc *sc = device_get_softc(dev);
dprintf("bcm_mbox_write: chan %d, data %08x\n", chan, data);
- MBOX_LOCK;
+ MBOX_LOCK(sc);
- while ((mbox_read_4(REG_STATUS) & STATUS_FULL) && limit--) {
+ while ((mbox_read_4(sc, REG_STATUS) & STATUS_FULL) && limit--) {
DELAY(2);
}
if (limit == 0) {
printf("bcm_mbox_write: STATUS_FULL stuck");
- MBOX_UNLOCK;
+ MBOX_UNLOCK(sc);
return (EAGAIN);
}
- mbox_write_4(REG_WRITE, MBOX_MSG(chan, data));
+ mbox_write_4(sc, REG_WRITE, MBOX_MSG(chan, data));
- MBOX_UNLOCK;
+ MBOX_UNLOCK(sc);
return (0);
}
-int
-bcm_mbox_read(int chan, uint32_t *data)
+static int
+bcm_mbox_read(device_t dev, int chan, uint32_t *data)
{
- struct bcm_mbox_softc *sc = bcm_mbox_sc;
+ struct bcm_mbox_softc *sc = device_get_softc(dev);
dprintf("bcm_mbox_read: chan %d\n", chan);
- MBOX_LOCK;
+ MBOX_LOCK(sc);
while (!sc->valid[chan])
msleep(&sc->msg[chan], &sc->lock, PZERO, "vcio mbox read", 0);
- *data = bcm_mbox_sc->msg[chan];
- bcm_mbox_sc->valid[chan] = 0;
- MBOX_UNLOCK;
+ *data = sc->msg[chan];
+ sc->valid[chan] = 0;
+ MBOX_UNLOCK(sc);
dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
return (0);
}
+
+static device_method_t bcm_mbox_methods[] = {
+ DEVMETHOD(device_probe, bcm_mbox_probe),
+ DEVMETHOD(device_attach, bcm_mbox_attach),
+
+ DEVMETHOD(mbox_read, bcm_mbox_read),
+ DEVMETHOD(mbox_write, bcm_mbox_write),
+
+ DEVMETHOD_END
+};
+
+static driver_t bcm_mbox_driver = {
+ "mbox",
+ bcm_mbox_methods,
+ sizeof(struct bcm_mbox_softc),
+};
+
+static devclass_t bcm_mbox_devclass;
+
+DRIVER_MODULE(mbox, simplebus, bcm_mbox_driver, bcm_mbox_devclass, 0, 0);
+
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
index edb9d5b..52f48e4 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
@@ -38,7 +38,4 @@
#define BCM2835_MBOX_CHAN_TS 6
#define BCM2835_MBOX_CHANS 7
-int bcm_mbox_write(int chan, uint32_t data);
-int bcm_mbox_read(int chan, uint32_t *data);
-
#endif /* _BCM2835_MBOX_H_ */
diff --git a/sys/arm/broadcom/bcm2835/files.bcm2835 b/sys/arm/broadcom/bcm2835/files.bcm2835
index aa1af40..9c0ff05 100644
--- a/sys/arm/broadcom/bcm2835/files.bcm2835
+++ b/sys/arm/broadcom/bcm2835/files.bcm2835
@@ -22,3 +22,5 @@ arm/arm/cpufunc_asm_armv6.S standard
arm/arm/irq_dispatch.S standard
kern/kern_clocksource.c standard
+
+dev/mbox/mbox_if.m standard
diff --git a/sys/arm/broadcom/bcm2835/std.bcm2835 b/sys/arm/broadcom/bcm2835/std.bcm2835
new file mode 100644
index 0000000..ebc1fb0
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/std.bcm2835
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+machine arm armv6
+cpu CPU_ARM1176
+
+files "../broadcom/bcm2835/files.bcm2835"
+
diff --git a/sys/arm/broadcom/bcm2835/std.rpi b/sys/arm/broadcom/bcm2835/std.rpi
new file mode 100644
index 0000000..8bb62c8
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/std.rpi
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+include "../broadcom/bcm2835/std.bcm2835"
+
+options KERNVIRTADDR=0xc0100000
+makeoptions KERNVIRTADDR=0xc0100000
+options KERNPHYSADDR=0x00100000
+makeoptions KERNPHYSADDR=0x00100000
+options PHYSADDR=0x00000000
+options STARTUP_PAGETABLE_ADDR=0x01000000
+options FREEBSD_BOOT_LOADER
+options LINUX_BOOT_ABI
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 1304868..f6fe35e 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -123,6 +123,10 @@ device bpf
device miibus
device axe # ASIX Electronics USB Ethernet
+# Device mode support and USFS template
+device usb_template # Control of the gadget
+device usfs
+
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index 38db5dd..474f6a9 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -18,21 +18,10 @@
# $FreeBSD$
ident RPI-B
-machine arm armv6
-cpu CPU_ARM1176
-files "../broadcom/bcm2835/files.bcm2835"
+include "../broadcom/bcm2835/std.rpi"
makeoptions MODULES_OVERRIDE=""
-options KERNVIRTADDR=0xc0100000
-makeoptions KERNVIRTADDR=0xc0100000
-options KERNPHYSADDR=0x00100000
-makeoptions KERNPHYSADDR=0x00100000
-options PHYSADDR=0x00000000
-options STARTUP_PAGETABLE_ADDR=0x01000000
-options FREEBSD_BOOT_LOADER
-options LINUX_BOOT_ABI
-
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options HZ=100
diff --git a/sys/arm/ti/am335x/am335x_pmic.c b/sys/arm/ti/am335x/am335x_pmic.c
index eab400a..462a2b8 100644
--- a/sys/arm/ti/am335x/am335x_pmic.c
+++ b/sys/arm/ti/am335x/am335x_pmic.c
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
#define TPS65217A 0x7
#define TPS65217B 0xF
+#define TPS65217C 0xE
+#define TPS65217D 0x6
/* TPS65217 Reisters */
#define TPS65217_CHIPID_REG 0x00
@@ -131,6 +133,12 @@ am335x_pmic_start(void *xdev)
case TPS65217B:
sprintf(name, "TPS65217B ver 1.%u", reg & 0xF);
break;
+ case TPS65217C:
+ sprintf(name, "TPS65217C ver 1.%u", reg & 0xF);
+ break;
+ case TPS65217D:
+ sprintf(name, "TPS65217D ver 1.%u", reg & 0xF);
+ break;
default:
sprintf(name, "Unknown PMIC");
}
diff --git a/sys/arm/ti/am335x/am335x_usbss.c b/sys/arm/ti/am335x/am335x_usbss.c
new file mode 100644
index 0000000..75b92ba
--- /dev/null
+++ b/sys/arm/ti/am335x/am335x_usbss.c
@@ -0,0 +1,481 @@
+/*-
+ * 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 AM335X_USB_PORTS 2
+
+#define USBSS_REVREG 0x00
+#define USBSS_SYSCONFIG 0x10
+#define USBSS_SYSCONFIG_SRESET 1
+
+#define USBCTRL_REV 0x00
+#define USBCTRL_CTRL 0x14
+#define USBCTRL_STAT 0x18
+#define USBCTRL_IRQ_STAT0 0x30
+#define IRQ_STAT0_RXSHIFT 16
+#define IRQ_STAT0_TXSHIFT 0
+#define USBCTRL_IRQ_STAT1 0x34
+#define IRQ_STAT1_DRVVBUS (1 << 8)
+#define USBCTRL_INTEN_SET0 0x38
+#define USBCTRL_INTEN_SET1 0x3C
+#define USBCTRL_INTEN_USB_ALL 0x1ff
+#define USBCTRL_INTEN_USB_SOF (1 << 3)
+#define USBCTRL_INTEN_CLR0 0x40
+#define USBCTRL_INTEN_CLR1 0x44
+#define USBCTRL_UTMI 0xE0
+#define USBCTRL_UTMI_FSDATAEXT (1 << 1)
+#define USBCTRL_MODE 0xE8
+#define USBCTRL_MODE_IDDIG (1 << 8)
+#define USBCTRL_MODE_IDDIGMUX (1 << 7)
+
+/* 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))
+#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;
+
+static SYSCTL_NODE(_hw_usb, OID_AUTO, am335x_usbss, CTLFLAG_RW, 0, "AM335x USBSS");
+SYSCTL_INT(_hw_usb_am335x_usbss, OID_AUTO, debug, CTLFLAG_RW,
+ &usbssdebug, 0, "Debug level");
+#endif
+
+static device_probe_t musbotg_probe;
+static device_attach_t musbotg_attach;
+static device_detach_t musbotg_detach;
+
+struct musbotg_super_softc {
+ struct musbotg_softc sc_otg[AM335X_USB_PORTS];
+ struct resource *sc_mem_res[AM335X_USB_PORTS*3+1];
+ struct resource *sc_irq_res[AM335X_USB_PORTS+1];
+ void *sc_intr_hdl;
+};
+
+static void
+musbotg_vbus_poll(struct musbotg_super_softc *sc, int port)
+{
+ uint32_t stat;
+
+ if (sc->sc_otg[port].sc_mode == MUSB2_DEVICE_MODE)
+ musbotg_vbus_interrupt(&sc->sc_otg[port], 1);
+ else {
+ stat = USBCTRL_READ4(sc, port, USBCTRL_STAT);
+ musbotg_vbus_interrupt(&sc->sc_otg[port], stat & 1);
+ }
+}
+
+/*
+ * Arg to musbotg_clocks_on and musbot_clocks_off is
+ * a uint32_t * pointing to the SCM register offset.
+ */
+static uint32_t USB_CTRL[] = {SCM_USB_CTRL0, SCM_USB_CTRL1};
+
+static void
+musbotg_clocks_on(void *arg)
+{
+ uint32_t c, reg = *(uint32_t *)arg;
+
+ ti_scm_reg_read_4(reg, &c);
+ c &= ~3; /* Enable power */
+ c |= 1 << 19; /* VBUS detect enable */
+ c |= 1 << 20; /* Session end enable */
+ ti_scm_reg_write_4(reg, c);
+}
+
+static void
+musbotg_clocks_off(void *arg)
+{
+ uint32_t c, reg = *(uint32_t *)arg;
+
+ /* Disable power to PHY */
+ ti_scm_reg_read_4(reg, &c);
+ ti_scm_reg_write_4(reg, c | 3);
+}
+
+static void
+musbotg_ep_int_set(struct musbotg_softc *sc, int ep, int on)
+{
+ struct musbotg_super_softc *ssc = sc->sc_platform_data;
+ uint32_t epmask;
+
+ epmask = ((1 << ep) << IRQ_STAT0_RXSHIFT);
+ epmask |= ((1 << ep) << IRQ_STAT0_TXSHIFT);
+ if (on)
+ USBCTRL_WRITE4(ssc, sc->sc_id,
+ USBCTRL_INTEN_SET0, epmask);
+ else
+ USBCTRL_WRITE4(ssc, sc->sc_id,
+ USBCTRL_INTEN_CLR0, epmask);
+}
+
+static void
+musbotg_usbss_interrupt(void *arg)
+{
+ panic("USBSS real interrupt");
+}
+
+static void
+musbotg_wrapper_interrupt(void *arg)
+{
+ struct musbotg_softc *sc = arg;
+ struct musbotg_super_softc *ssc = sc->sc_platform_data;
+ uint32_t stat, stat0, stat1;
+ stat = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_STAT);
+ stat0 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0);
+ stat1 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT1);
+ if (stat0)
+ USBCTRL_WRITE4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0, stat0);
+ if (stat1)
+ USBCTRL_WRITE4(ssc, sc->sc_id, USBCTRL_IRQ_STAT1, stat1);
+
+ DPRINTFN(4, "port%d: stat0=%08x stat1=%08x, stat=%08x\n",
+ sc->sc_id, stat0, stat1, stat);
+
+ if (stat1 & IRQ_STAT1_DRVVBUS)
+ musbotg_vbus_interrupt(sc, stat & 1);
+
+ musbotg_interrupt(arg, ((stat0 >> 16) & 0xffff),
+ stat0 & 0xffff, stat1 & 0xff);
+}
+
+static int
+musbotg_probe(device_t dev)
+{
+ 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;
+ int i;
+ uint32_t rev, reg;
+
+ /* 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 */
+ 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);
+ }
+
+ /*
+ * Reset USBSS, USB0 and USB1
+ */
+ rev = USBSS_READ4(sc, USBSS_REVREG);
+ device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n",
+ (rev >> 8) & 7, (rev >> 6) & 3, rev & 63);
+
+ ti_prcm_clk_enable(MUSB0_CLK);
+
+ USBSS_WRITE4(sc, USBSS_SYSCONFIG,
+ USBSS_SYSCONFIG_SRESET);
+ while (USBSS_READ4(sc, USBSS_SYSCONFIG) &
+ USBSS_SYSCONFIG_SRESET)
+ ;
+
+ 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;
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_otg[i].sc_bus,
+ USB_GET_DMA_TAG(dev), NULL)) {
+ device_printf(dev,
+ "Failed allocate bus mem for musb%d\n", i);
+ return (ENOMEM);
+ }
+ sc->sc_otg[i].sc_io_res = sc->sc_mem_res[RES_USBCORE(i)];
+ sc->sc_otg[i].sc_io_tag =
+ rman_get_bustag(sc->sc_otg[i].sc_io_res);
+ sc->sc_otg[i].sc_io_hdl =
+ rman_get_bushandle(sc->sc_otg[i].sc_io_res);
+ sc->sc_otg[i].sc_io_size =
+ rman_get_size(sc->sc_otg[i].sc_io_res);
+
+ sc->sc_otg[i].sc_irq_res = sc->sc_irq_res[i+1];
+
+ sc->sc_otg[i].sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (!(sc->sc_otg[i].sc_bus.bdev)) {
+ device_printf(dev, "No busdev for musb%d\n", i);
+ goto error;
+ }
+ device_set_ivars(sc->sc_otg[i].sc_bus.bdev,
+ &sc->sc_otg[i].sc_bus);
+
+ err = bus_setup_intr(dev, sc->sc_otg[i].sc_irq_res,
+ INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, (driver_intr_t *)musbotg_wrapper_interrupt,
+ &sc->sc_otg[i], &sc->sc_otg[i].sc_intr_hdl);
+ if (err) {
+ sc->sc_otg[i].sc_intr_hdl = NULL;
+ device_printf(dev,
+ "Failed to setup interrupt for musb%d\n", i);
+ goto error;
+ }
+
+ sc->sc_otg[i].sc_id = i;
+ sc->sc_otg[i].sc_platform_data = sc;
+ if (i == 0)
+ sc->sc_otg[i].sc_mode = MUSB2_DEVICE_MODE;
+ else
+ sc->sc_otg[i].sc_mode = MUSB2_HOST_MODE;
+
+ /*
+ * software-controlled function
+ */
+
+ if (sc->sc_otg[i].sc_mode == MUSB2_HOST_MODE) {
+ reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
+ reg |= USBCTRL_MODE_IDDIGMUX;
+ reg &= ~USBCTRL_MODE_IDDIG;
+ USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
+ USBCTRL_WRITE4(sc, i, USBCTRL_UTMI,
+ USBCTRL_UTMI_FSDATAEXT);
+ } else {
+ reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
+ reg |= USBCTRL_MODE_IDDIGMUX;
+ reg |= USBCTRL_MODE_IDDIG;
+ USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
+ }
+
+ reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF;
+ USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_SET1, reg);
+ USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_CLR0, 0xffffffff);
+
+ err = musbotg_init(&sc->sc_otg[i]);
+ if (!err)
+ err = device_probe_and_attach(sc->sc_otg[i].sc_bus.bdev);
+
+ if (err)
+ goto error;
+
+ /* poll VBUS one time */
+ musbotg_vbus_poll(sc, i);
+ }
+
+ return (0);
+
+error:
+ musbotg_detach(dev);
+ return (ENXIO);
+}
+
+static int
+musbotg_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;
+ }
+
+
+ /* 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_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[] = {
+ /* 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, simplebus, musbotg_driver, musbotg_devclass, 0, 0);
+MODULE_DEPEND(musbotg, usb, 1, 1, 1);
diff --git a/sys/arm/ti/am335x/files.am335x b/sys/arm/ti/am335x/files.am335x
index a275341..70e0e26 100644
--- a/sys/arm/ti/am335x/files.am335x
+++ b/sys/arm/ti/am335x/files.am335x
@@ -7,6 +7,7 @@ arm/ti/am335x/am335x_scm_padconf.c standard
arm/ti/am335x/am335x_lcd.c optional sc
arm/ti/am335x/am335x_lcd_syscons.c optional sc
arm/ti/am335x/am335x_pwm.c standard
+arm/ti/am335x/am335x_usbss.c optional musb fdt
arm/ti/ti_edma3.c standard
arm/ti/ti_mmchs.c optional mmc
arm/ti/cpsw/if_cpsw.c optional cpsw
diff --git a/sys/arm/ti/ti_mmchs.c b/sys/arm/ti/ti_mmchs.c
index 76ecc58..25c7d06 100644
--- a/sys/arm/ti/ti_mmchs.c
+++ b/sys/arm/ti/ti_mmchs.c
@@ -212,11 +212,12 @@ ti_mmchs_reset_controller(struct ti_mmchs_softc *sc, uint32_t bit)
sysctl = ti_mmchs_read_4(sc, MMCHS_SYSCTL);
ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl | bit);
-
- if ((ti_chip() == CHIP_OMAP_4) && (ti_revision() > OMAP4430_REV_ES1_0)) {
- /* OMAP4 ES2 and greater has an updated reset logic.
- * Monitor a 0->1 transition first
- */
+ /*
+ * AM335x and OMAP4 >= ES2 have an updated reset logic.
+ * Monitor a 0->1 transition first.
+ */
+ if ((ti_chip() == CHIP_AM335X) ||
+ ((ti_chip() == CHIP_OMAP_4) && (ti_revision() > OMAP4430_REV_ES1_0))) {
attempts = 10000;
while (!(ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0))
continue;
@@ -1327,7 +1328,7 @@ ti_mmchs_hw_init(device_t dev)
unsigned long timeout;
uint32_t sysctl;
uint32_t capa;
- uint32_t con;
+ uint32_t con, sysconfig;
/* 1: Enable the controller and interface/functional clocks */
clk = MMC0_CLK + sc->device_id;
@@ -1344,7 +1345,9 @@ ti_mmchs_hw_init(device_t dev)
}
/* 2: Issue a softreset to the controller */
- ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, 0x0002);
+ sysconfig = ti_mmchs_read_4(sc, MMCHS_SYSCONFIG);
+ sysconfig |= MMCHS_SYSCONFIG_SRST;
+ ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, sysconfig);
timeout = 100;
while ((ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) & 0x01) == 0x0) {
DELAY(1000);
diff --git a/sys/arm/ti/ti_mmchs.h b/sys/arm/ti/ti_mmchs.h
index 5a7f3f4..175c0c6 100644
--- a/sys/arm/ti/ti_mmchs.h
+++ b/sys/arm/ti/ti_mmchs.h
@@ -67,6 +67,12 @@
#define AM335X_MMCHS_REG_OFFSET 0x100
/* Register bit settings */
+#define MMCHS_SYSCONFIG_CLK_FUN (2 << 8)
+#define MMCHS_SYSCONFIG_CLK_IFC (1 << 8)
+#define MMCHS_SYSCONFIG_SIDL (2 << 3)
+#define MMCHS_SYSCONFIG_ENW (1 << 2)
+#define MMCHS_SYSCONFIG_SRST (1 << 1)
+#define MMCHS_SYSCONFIG_AIDL (1 << 0)
#define MMCHS_STAT_BADA (1UL << 29)
#define MMCHS_STAT_CERR (1UL << 28)
#define MMCHS_STAT_ACE (1UL << 24)
OpenPOWER on IntegriCloud