summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-at91/at91_pmc.h14
-rw-r--r--board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c13
-rw-r--r--board/ti/evm/evm.c43
-rw-r--r--board/ti/evm/evm.h14
-rw-r--r--drivers/usb/host/ohci-at91.c14
-rw-r--r--drivers/usb/host/ohci-hcd.c150
-rw-r--r--drivers/usb/host/ohci.h15
-rw-r--r--drivers/usb/musb/da8xx.c6
-rw-r--r--drivers/usb/musb/davinci.c6
-rw-r--r--drivers/usb/musb/musb_core.c7
-rw-r--r--drivers/usb/musb/musb_core.h30
-rw-r--r--drivers/usb/musb/omap3.c9
-rw-r--r--drivers/usb/musb/omap3.h4
13 files changed, 233 insertions, 92 deletions
diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h
index 5b1a85d..2f9ad96 100644
--- a/arch/arm/include/asm/arch-at91/at91_pmc.h
+++ b/arch/arm/include/asm/arch-at91/at91_pmc.h
@@ -35,13 +35,15 @@ typedef struct at91_pmc {
u32 pcer; /* 0x10 Peripheral Clock Enable Register */
u32 pcdr; /* 0x14 Peripheral Clock Disable Register */
u32 pcsr; /* 0x18 Peripheral Clock Status Register */
- u32 reserved1;
+ u32 uckr; /* 0x1C UTMI Clock Register */
u32 mor; /* 0x20 Main Oscilator Register */
u32 mcfr; /* 0x24 Main Clock Frequency Register */
u32 pllar; /* 0x28 PLL A Register */
u32 pllbr; /* 0x2C PLL B Register */
u32 mckr; /* 0x30 Master Clock Register */
- u32 reserved2[3];
+ u32 reserved1;
+ u32 usb; /* 0x38 USB Clock Register */
+ u32 reserved2;
u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */
u32 reserved3[4];
u32 ier; /* 0x60 Interrupt Enable Register */
@@ -199,6 +201,14 @@ typedef struct at91_pmc {
#define AT91_PMC_PDIV_2 (1 << 12)
#ifdef CONFIG_AT91_LEGACY
+#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register */
+#endif
+#define AT91_PMC_USBS_USB_PLLA (0x0) /* USB Clock Input is PLLA */
+#define AT91_PMC_USBS_USB_UPLL (0x1) /* USB Clock Input is UPLL */
+#define AT91_PMC_USBDIV_8 (0x7 << 8) /* USB Clock divided by 8 */
+#define AT91_PMC_USBDIV_10 (0x9 << 8) /* USB Clock divided by 10 */
+
+#ifdef CONFIG_AT91_LEGACY
#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-3 Registers */
#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */
diff --git a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
index edfb627..8fa0449 100644
--- a/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
+++ b/board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c
@@ -87,6 +87,16 @@ static void at91sam9m10g45ek_nand_hw_init(void)
}
#endif
+#ifdef CONFIG_CMD_USB
+static void at91sam9m10g45ek_usb_hw_init(void)
+{
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9G45_ID_PIODE);
+
+ at91_set_gpio_output(AT91_PIN_PD1, 0);
+ at91_set_gpio_output(AT91_PIN_PD3, 0);
+}
+#endif
+
#ifdef CONFIG_MACB
static void at91sam9m10g45ek_macb_hw_init(void)
{
@@ -251,6 +261,9 @@ int board_init(void)
#ifdef CONFIG_CMD_NAND
at91sam9m10g45ek_nand_hw_init();
#endif
+#ifdef CONFIG_CMD_USB
+ at91sam9m10g45ek_usb_hw_init();
+#endif
#ifdef CONFIG_HAS_DATAFLASH
at91_spi0_hw_init(1 << 0);
#endif
diff --git a/board/ti/evm/evm.c b/board/ti/evm/evm.c
index 0718a08..9948b9c 100644
--- a/board/ti/evm/evm.c
+++ b/board/ti/evm/evm.c
@@ -37,6 +37,46 @@
#include <asm/mach-types.h>
#include "evm.h"
+static u8 omap3_evm_version;
+
+u8 get_omap3_evm_rev(void)
+{
+ return omap3_evm_version;
+}
+
+static void omap3_evm_get_revision(void)
+{
+ unsigned int smsc_id;
+
+ /* Ethernet PHY ID is stored at ID_REV register */
+ smsc_id = readl(CONFIG_SMC911X_BASE + 0x50) & 0xFFFF0000;
+ printf("Read back SMSC id 0x%x\n", smsc_id);
+
+ switch (smsc_id) {
+ /* SMSC9115 chipset */
+ case 0x01150000:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
+ break;
+ /* SMSC 9220 chipset */
+ case 0x92200000:
+ default:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
+ }
+}
+
+/*
+ * MUSB port on OMAP3EVM Rev >= E requires extvbus programming.
+ */
+u8 omap3_evm_need_extvbus(void)
+{
+ u8 retval = 0;
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+ retval = 1;
+
+ return retval;
+}
+
/*
* Routine: board_init
* Description: Early hardware init.
@@ -121,6 +161,9 @@ static void setup_net_chip(void)
writel(GPIO0, &gpio3_base->cleardataout);
udelay(1);
writel(GPIO0, &gpio3_base->setdataout);
+
+ /* determine omap3evm revision */
+ omap3_evm_get_revision();
}
int board_eth_init(bd_t *bis)
diff --git a/board/ti/evm/evm.h b/board/ti/evm/evm.h
index 37da29d..e2581f6 100644
--- a/board/ti/evm/evm.h
+++ b/board/ti/evm/evm.h
@@ -33,6 +33,20 @@ const omap3_sysinfo sysinfo = {
#endif
};
+/*
+ * OMAP35x EVM revision
+ * Run time detection of EVM revision is done by reading Ethernet
+ * PHY ID -
+ * GEN_1 = 0x01150000
+ * GEN_2 = 0x92200000
+ */
+enum {
+ OMAP3EVM_BOARD_GEN_1 = 0, /* EVM Rev between A - D */
+ OMAP3EVM_BOARD_GEN_2, /* EVM Rev >= Rev E */
+};
+
+u8 get_omap3_evm_rev(void);
+
static void setup_net_chip(void);
/*
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index b2e03bc..64fde68 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -41,6 +41,15 @@ int usb_cpu_init(void)
writel(get_pllb_init(), &pmc->pllbr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB)
;
+#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
+ /* Enable UPLL */
+ writel(readl(&pmc->uckr) | AT91_PMC_UPLLEN | AT91_PMC_BIASEN,
+ &pmc->uckr);
+ while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU)
+ ;
+
+ /* Select PLLA as input clock of OHCI */
+ writel(AT91_PMC_USBS_USB_UPLL | AT91_PMC_USBDIV_10, &pmc->usb);
#endif
/* Enable USB host clock. */
@@ -72,6 +81,11 @@ int usb_cpu_stop(void)
writel(0, &pmc->pllbr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0)
;
+#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
+ /* Disable UPLL */
+ writel(readl(&pmc->uckr) & (~AT91_PMC_UPLLEN), &pmc->uckr);
+ while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU)
+ ;
#endif
return 0;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b03a600..3f76c4e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -83,17 +83,6 @@
#define OHCI_CONTROL_INIT \
(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-/*
- * e.g. PCI controllers need this
- */
-#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS
-# define readl(a) __swap_32(*((volatile u32 *)(a)))
-# define writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a))
-#else
-# define readl(a) (*((volatile u32 *)(a)))
-# define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
-#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
-
#define min_t(type, x, y) \
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
@@ -147,13 +136,13 @@ struct ohci_device ohci_dev;
struct usb_device *devgone;
static inline u32 roothub_a(struct ohci *hc)
- { return readl(&hc->regs->roothub.a); }
+ { return ohci_readl(&hc->regs->roothub.a); }
static inline u32 roothub_b(struct ohci *hc)
- { return readl(&hc->regs->roothub.b); }
+ { return ohci_readl(&hc->regs->roothub.b); }
static inline u32 roothub_status(struct ohci *hc)
- { return readl(&hc->regs->roothub.status); }
+ { return ohci_readl(&hc->regs->roothub.status); }
static inline u32 roothub_portstatus(struct ohci *hc, int i)
- { return readl(&hc->regs->roothub.portstatus[i]); }
+ { return ohci_readl(&hc->regs->roothub.portstatus[i]); }
/* forward declaration */
static int hc_interrupt(void);
@@ -302,11 +291,11 @@ static void ohci_dump_status(ohci_t *controller)
struct ohci_regs *regs = controller->regs;
__u32 temp;
- temp = readl(&regs->revision) & 0xff;
+ temp = ohci_readl(&regs->revision) & 0xff;
if (temp != 0x10)
dbg("spec %d.%d", (temp >> 4), (temp & 0x0f));
- temp = readl(&regs->control);
+ temp = ohci_readl(&regs->control);
dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
(temp & OHCI_CTRL_RWE) ? " RWE" : "",
(temp & OHCI_CTRL_RWC) ? " RWC" : "",
@@ -319,7 +308,7 @@ static void ohci_dump_status(ohci_t *controller)
temp & OHCI_CTRL_CBSR
);
- temp = readl(&regs->cmdstatus);
+ temp = ohci_readl(&regs->cmdstatus);
dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
(temp & OHCI_SOC) >> 16,
(temp & OHCI_OCR) ? " OCR" : "",
@@ -328,18 +317,20 @@ static void ohci_dump_status(ohci_t *controller)
(temp & OHCI_HCR) ? " HCR" : ""
);
- ohci_dump_intr_mask("intrstatus", readl(&regs->intrstatus));
- ohci_dump_intr_mask("intrenable", readl(&regs->intrenable));
+ ohci_dump_intr_mask("intrstatus", ohci_readl(&regs->intrstatus));
+ ohci_dump_intr_mask("intrenable", ohci_readl(&regs->intrenable));
- maybe_print_eds("ed_periodcurrent", readl(&regs->ed_periodcurrent));
+ maybe_print_eds("ed_periodcurrent",
+ ohci_readl(&regs->ed_periodcurrent));
- maybe_print_eds("ed_controlhead", readl(&regs->ed_controlhead));
- maybe_print_eds("ed_controlcurrent", readl(&regs->ed_controlcurrent));
+ maybe_print_eds("ed_controlhead", ohci_readl(&regs->ed_controlhead));
+ maybe_print_eds("ed_controlcurrent",
+ ohci_readl(&regs->ed_controlcurrent));
- maybe_print_eds("ed_bulkhead", readl(&regs->ed_bulkhead));
- maybe_print_eds("ed_bulkcurrent", readl(&regs->ed_bulkcurrent));
+ maybe_print_eds("ed_bulkhead", ohci_readl(&regs->ed_bulkhead));
+ maybe_print_eds("ed_bulkcurrent", ohci_readl(&regs->ed_bulkcurrent));
- maybe_print_eds("donehead", readl(&regs->donehead));
+ maybe_print_eds("donehead", ohci_readl(&regs->donehead));
}
static void ohci_dump_roothub(ohci_t *controller, int verbose)
@@ -518,11 +509,11 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
/* implicitly requeued */
if (urb->dev->irq_handle &&
(urb->dev->irq_act_len = urb->actual_length)) {
- writel(OHCI_INTR_WDH, &regs->intrenable);
- readl(&regs->intrenable); /* PCI posting flush */
+ ohci_writel(OHCI_INTR_WDH, &regs->intrenable);
+ ohci_readl(&regs->intrenable); /* PCI posting flush */
urb->dev->irq_handle(urb->dev);
- writel(OHCI_INTR_WDH, &regs->intrdisable);
- readl(&regs->intrdisable); /* PCI posting flush */
+ ohci_writel(OHCI_INTR_WDH, &regs->intrdisable);
+ ohci_readl(&regs->intrdisable); /* PCI posting flush */
}
urb->actual_length = 0;
td_submit_job(
@@ -631,7 +622,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
case PIPE_CONTROL:
ed->hwNextED = 0;
if (ohci->ed_controltail == NULL)
- writel(ed, &ohci->regs->ed_controlhead);
+ ohci_writel(ed, &ohci->regs->ed_controlhead);
else
ohci->ed_controltail->hwNextED =
m32_swap((unsigned long)ed);
@@ -640,7 +631,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
!ohci->ed_rm_list[1] && !ohci->sleeping) {
ohci->hc_control |= OHCI_CTRL_CLE;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control, &ohci->regs->control);
}
ohci->ed_controltail = edi;
break;
@@ -648,7 +639,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
case PIPE_BULK:
ed->hwNextED = 0;
if (ohci->ed_bulktail == NULL)
- writel(ed, &ohci->regs->ed_bulkhead);
+ ohci_writel(ed, &ohci->regs->ed_bulkhead);
else
ohci->ed_bulktail->hwNextED =
m32_swap((unsigned long)ed);
@@ -657,7 +648,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
!ohci->ed_rm_list[1] && !ohci->sleeping) {
ohci->hc_control |= OHCI_CTRL_BLE;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control, &ohci->regs->control);
}
ohci->ed_bulktail = edi;
break;
@@ -725,9 +716,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)
if (ed->ed_prev == NULL) {
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_CLE;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control,
+ &ohci->regs->control);
}
- writel(m32_swap(*((__u32 *)&ed->hwNextED)),
+ ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)),
&ohci->regs->ed_controlhead);
} else {
ed->ed_prev->hwNextED = ed->hwNextED;
@@ -744,9 +736,10 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)
if (ed->ed_prev == NULL) {
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_BLE;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control,
+ &ohci->regs->control);
}
- writel(m32_swap(*((__u32 *)&ed->hwNextED)),
+ ohci_writel(m32_swap(*((__u32 *)&ed->hwNextED)),
&ohci->regs->ed_bulkhead);
} else {
ed->ed_prev->hwNextED = ed->hwNextED;
@@ -923,7 +916,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe,
if (!ohci->sleeping) {
/* start bulk list */
- writel(OHCI_BLF, &ohci->regs->cmdstatus);
+ ohci_writel(OHCI_BLF, &ohci->regs->cmdstatus);
}
break;
@@ -949,7 +942,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe,
if (!ohci->sleeping) {
/* start Control list */
- writel(OHCI_CLF, &ohci->regs->cmdstatus);
+ ohci_writel(OHCI_CLF, &ohci->regs->cmdstatus);
}
break;
@@ -1224,13 +1217,13 @@ static unsigned char root_hub_str_index1[] =
#define OK(x) len = (x); break
#ifdef DEBUG
-#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); writel((x), \
+#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); ohci_writel((x), \
&gohci.regs->roothub.status); }
#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, \
- (x)); writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); }
+ (x)); ohci_writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); }
#else
-#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
-#define WR_RH_PORTSTAT(x) writel((x), \
+#define WR_RH_STAT(x) ohci_writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x) ohci_writel((x), \
&gohci.regs->roothub.portstatus[wIndex-1])
#endif
#define RD_RH_STAT roothub_status(&gohci)
@@ -1661,10 +1654,10 @@ static int hc_reset(ohci_t *ohci)
int timeout = 1000;
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
- writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET,
- base + EHCI_USBCMD_OFF);
+ base += EHCI_USBCMD_OFF;
+ ohci_writel(ohci_readl(base) | EHCI_USBCMD_HCRESET, base);
- while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) {
+ while (ohci_readl(base) & EHCI_USBCMD_HCRESET) {
if (timeout-- <= 0) {
printf("USB RootHub reset timed out!");
break;
@@ -1674,11 +1667,11 @@ static int hc_reset(ohci_t *ohci)
} else
printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO);
#endif
- if (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- /* SMM owns the HC */
- writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */
+ if (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) {
+ /* SMM owns the HC, request ownership */
+ ohci_writel(OHCI_OCR, &ohci->regs->cmdstatus);
info("USB HC TakeOver from SMM");
- while (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
+ while (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) {
wait_ms(10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
@@ -1688,19 +1681,19 @@ static int hc_reset(ohci_t *ohci)
}
/* Disable HC interrupts */
- writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ ohci_writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);
dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",
ohci->slot_name,
- readl(&ohci->regs->control));
+ ohci_readl(&ohci->regs->control));
/* Reset USB (needed by some controllers) */
ohci->hc_control = 0;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control, &ohci->regs->control);
/* HC Reset requires max 10 us delay */
- writel(OHCI_HCR, &ohci->regs->cmdstatus);
- while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ ohci_writel(OHCI_HCR, &ohci->regs->cmdstatus);
+ while ((ohci_readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
if (--timeout == 0) {
err("USB HC reset timed out!");
return -1;
@@ -1726,39 +1719,40 @@ static int hc_start(ohci_t *ohci)
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
- writel(0, &ohci->regs->ed_controlhead);
- writel(0, &ohci->regs->ed_bulkhead);
+ ohci_writel(0, &ohci->regs->ed_controlhead);
+ ohci_writel(0, &ohci->regs->ed_bulkhead);
- writel((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */
+ ohci_writel((__u32)ohci->hcca,
+ &ohci->regs->hcca); /* reset clears this */
fminterval = 0x2edf;
- writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
+ ohci_writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
- writel(fminterval, &ohci->regs->fminterval);
- writel(0x628, &ohci->regs->lsthresh);
+ ohci_writel(fminterval, &ohci->regs->fminterval);
+ ohci_writel(0x628, &ohci->regs->lsthresh);
/* start controller operations */
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
- writel(ohci->hc_control, &ohci->regs->control);
+ ohci_writel(ohci->hc_control, &ohci->regs->control);
/* disable all interrupts */
mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
OHCI_INTR_OC | OHCI_INTR_MIE);
- writel(mask, &ohci->regs->intrdisable);
+ ohci_writel(mask, &ohci->regs->intrdisable);
/* clear all interrupts */
mask &= ~OHCI_INTR_MIE;
- writel(mask, &ohci->regs->intrstatus);
+ ohci_writel(mask, &ohci->regs->intrstatus);
/* Choose the interrupts we care about now - but w/o MIE */
mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
- writel(mask, &ohci->regs->intrenable);
+ ohci_writel(mask, &ohci->regs->intrenable);
#ifdef OHCI_USE_NPS
/* required for AMD-756 and some Mac platforms */
- writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,
+ ohci_writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,
&ohci->regs->roothub.a);
- writel(RH_HS_LPSC, &ohci->regs->roothub.status);
+ ohci_writel(RH_HS_LPSC, &ohci->regs->roothub.status);
#endif /* OHCI_USE_NPS */
#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })
@@ -1792,13 +1786,13 @@ static int hc_interrupt(void)
!(m32_swap(ohci->hcca->done_head) & 0x01)) {
ints = OHCI_INTR_WDH;
} else {
- ints = readl(&regs->intrstatus);
+ ints = ohci_readl(&regs->intrstatus);
if (ints == ~(u32)0) {
ohci->disabled++;
err("%s device removed!", ohci->slot_name);
return -1;
} else {
- ints &= readl(&regs->intrenable);
+ ints &= ohci_readl(&regs->intrenable);
if (ints == 0) {
dbg("hc_interrupt: returning..\n");
return 0xff;
@@ -1833,16 +1827,16 @@ static int hc_interrupt(void)
if (ints & OHCI_INTR_WDH) {
wait_ms(1);
- writel(OHCI_INTR_WDH, &regs->intrdisable);
- (void)readl(&regs->intrdisable); /* flush */
+ ohci_writel(OHCI_INTR_WDH, &regs->intrdisable);
+ (void)ohci_readl(&regs->intrdisable); /* flush */
stat = dl_done_list(&gohci);
- writel(OHCI_INTR_WDH, &regs->intrenable);
- (void)readl(&regs->intrdisable); /* flush */
+ ohci_writel(OHCI_INTR_WDH, &regs->intrenable);
+ (void)ohci_readl(&regs->intrdisable); /* flush */
}
if (ints & OHCI_INTR_SO) {
dbg("USB Schedule overrun\n");
- writel(OHCI_INTR_SO, &regs->intrenable);
+ ohci_writel(OHCI_INTR_SO, &regs->intrenable);
stat = -1;
}
@@ -1850,13 +1844,13 @@ static int hc_interrupt(void)
if (ints & OHCI_INTR_SF) {
unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;
wait_ms(1);
- writel(OHCI_INTR_SF, &regs->intrdisable);
+ ohci_writel(OHCI_INTR_SF, &regs->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
- writel(OHCI_INTR_SF, &regs->intrenable);
+ ohci_writel(OHCI_INTR_SF, &regs->intrenable);
stat = 0xff;
}
- writel(ints, &regs->intrstatus);
+ ohci_writel(ints, &regs->intrstatus);
return stat;
}
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 79aa79d..d977e8f 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -7,6 +7,17 @@
* usb-ohci.h
*/
+/*
+ * e.g. PCI controllers need this
+ */
+#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS
+# define ohci_readl(a) __swap_32(*((volatile u32 *)(a)))
+# define ohci_writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a))
+#else
+# define ohci_readl(a) (*((volatile u32 *)(a)))
+# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
+#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
+
/* functions for doing board or CPU specific setup/cleanup */
extern int usb_board_init(void);
extern int usb_board_stop(void);
@@ -196,8 +207,8 @@ struct ohci_hcca {
/*
* This is the structure of the OHCI controller's memory mapped I/O
- * region. This is Memory Mapped I/O. You must use the readl() and
- * writel() macros defined in asm/io.h to access these!!
+ * region. This is Memory Mapped I/O. You must use the ohci_readl() and
+ * ohci_writel() macros defined in this file to access these!!
*/
struct ohci_regs {
/* control and status registers */
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 40bfe44..617d88e 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -27,9 +27,9 @@
/* MUSB platform configuration */
struct musb_config musb_cfg = {
- (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE,
- DA8XX_USB_OTG_TIMEOUT,
- 0
+ .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE,
+ .timeout = DA8XX_USB_OTG_TIMEOUT,
+ .musb_speed = 0,
};
/*
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 8fbadc9..f56f2df 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -28,9 +28,9 @@
/* MUSB platform configuration */
struct musb_config musb_cfg = {
- (struct musb_regs *)MENTOR_USB0_BASE,
- DAVINCI_USB_TIMEOUT,
- 0
+ .regs = (struct musb_regs *)MENTOR_USB0_BASE,
+ .timeout = DAVINCI_USB_TIMEOUT,
+ .musb_speed = 0,
};
/* MUSB module register overlay */
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 7766069..dc740cf 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -34,6 +34,7 @@ void musb_start(void)
{
#if defined(CONFIG_MUSB_HCD)
u8 devctl;
+ u8 busctl;
#endif
/* disable all interrupts */
@@ -45,6 +46,12 @@ void musb_start(void)
/* put into basic highspeed mode and start session */
writeb(MUSB_POWER_HSENAB, &musbr->power);
#if defined(CONFIG_MUSB_HCD)
+ /* Program PHY to use EXT VBUS if required */
+ if (musb_cfg.extvbus == 1) {
+ busctl = musb_read_ulpi_buscontrol(musbr);
+ musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS);
+ }
+
devctl = readb(&musbr->devctl);
writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
#endif
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 9a1fb4f..4771876 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -112,7 +112,10 @@ struct musb_regs {
u16 rxfifoadd;
u32 vcontrol;
u16 hwvers;
- u16 reserved2[5];
+ u16 reserved2a[1];
+ u8 ulpi_busctl;
+ u8 reserved2b[1];
+ u16 reserved2[3];
u8 epinfo;
u8 raminfo;
u8 linkinfo;
@@ -181,6 +184,10 @@ struct musb_regs {
#define MUSB_DEVCTL_HR 0x02
#define MUSB_DEVCTL_SESSION 0x01
+/* ULPI VBUSCONTROL */
+#define ULPI_USE_EXTVBUS 0x01
+#define ULPI_USE_EXTVBUSIND 0x02
+
/* TESTMODE */
#define MUSB_TEST_FORCE_HOST 0x80
#define MUSB_TEST_FIFO_ACCESS 0x40
@@ -341,6 +348,7 @@ struct musb_config {
struct musb_regs *regs;
u32 timeout;
u8 musb_speed;
+ u8 extvbus;
};
/* externally defined data */
@@ -361,6 +369,26 @@ extern void read_fifo(u8 ep, u32 length, void *fifo_data);
# define readb(addr) (u8)bfin_read16(addr)
# undef writeb
# define writeb(b, addr) bfin_write16(addr, b)
+/*
+ * The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY.
+ * However, it has no ULPI support - so there are no registers at all.
+ * That means accesses to ULPI_BUSCONTROL have to be abstracted away.
+ */
+static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr)
+{
+ return 0;
+}
+static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val)
+{}
+#else
+static inline u8 musb_read_ulpi_buscontrol(struct musb_regs *musbr)
+{
+ return readb(&musbr->ulpi_busctl);
+}
+static inline void musb_write_ulpi_buscontrol(struct musb_regs *musbr, u8 val)
+{
+ writeb(val, &musbr->ulpi_busctl);
+}
#endif
#endif /* __MUSB_HDRC_DEFS_H__ */
diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c
index 3bfd0a0..a983552 100644
--- a/drivers/usb/musb/omap3.c
+++ b/drivers/usb/musb/omap3.c
@@ -36,9 +36,9 @@
static int platform_needs_initialization = 1;
struct musb_config musb_cfg = {
- (struct musb_regs *)MENTOR_USB0_BASE,
- OMAP3_USB_TIMEOUT,
- 0
+ .regs = (struct musb_regs *)MENTOR_USB0_BASE,
+ .timeout = OMAP3_USB_TIMEOUT,
+ .musb_speed = 0,
};
/*
@@ -119,6 +119,9 @@ int musb_platform_init(void)
stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY;
writel(stdby, &otg->forcestdby);
+#ifdef CONFIG_OMAP3_EVM
+ musb_cfg.extvbus = omap3_evm_need_extvbus();
+#endif
platform_needs_initialization = 0;
}
diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h
index b591862..c934e0c 100644
--- a/drivers/usb/musb/omap3.h
+++ b/drivers/usb/musb/omap3.h
@@ -44,4 +44,8 @@
int musb_platform_init(void);
+#ifdef CONFIG_OMAP3_EVM
+extern u8 omap3_evm_use_extvbus(void);
+#endif
+
#endif /* _MUSB_OMAP3_H */