|
@@ -37,9 +37,27 @@
|
|
|
#include <asm/arch/usb.h>
|
|
|
#include <asm/arch/board.h>
|
|
|
|
|
|
+#ifdef CONFIG_ARCH_OMAP1
|
|
|
+
|
|
|
+#define INT_USB_IRQ_GEN IH2_BASE + 20
|
|
|
+#define INT_USB_IRQ_NISO IH2_BASE + 30
|
|
|
+#define INT_USB_IRQ_ISO IH2_BASE + 29
|
|
|
+#define INT_USB_IRQ_HGEN INT_USB_HHC_1
|
|
|
+#define INT_USB_IRQ_OTG IH2_BASE + 8
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
+#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
|
|
|
+#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
|
|
|
+#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
|
|
|
+#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
|
|
|
+#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
/* These routines should handle the standard chip-specific modes
|
|
|
* for usb0/1/2 ports, covering basic mux and transceiver setup.
|
|
|
- * Call omap_usb_init() once, from INIT_MACHINE().
|
|
|
*
|
|
|
* Some board-*.c files will need to set up additional mux options,
|
|
|
* like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
|
|
@@ -96,19 +114,26 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
|
|
|
{
|
|
|
u32 syscon1 = 0;
|
|
|
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG &= ~USBT0WRMODEI(USB_BIDIR_TLL);
|
|
|
+
|
|
|
if (nwires == 0) {
|
|
|
- if (!cpu_is_omap15xx()) {
|
|
|
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
|
|
|
/* pulldown D+/D- */
|
|
|
USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (is_device)
|
|
|
- omap_cfg_reg(W4_USB_PUEN);
|
|
|
+ if (is_device) {
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ omap_cfg_reg(J20_24XX_USB0_PUEN);
|
|
|
+ else
|
|
|
+ omap_cfg_reg(W4_USB_PUEN);
|
|
|
+ }
|
|
|
|
|
|
- /* internal transceiver */
|
|
|
- if (nwires == 2) {
|
|
|
+ /* internal transceiver (unavailable on 17xx, 24xx) */
|
|
|
+ if (!cpu_class_is_omap2() && nwires == 2) {
|
|
|
// omap_cfg_reg(P9_USB_DP);
|
|
|
// omap_cfg_reg(R8_USB_DM);
|
|
|
|
|
@@ -136,29 +161,50 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- omap_cfg_reg(V6_USB0_TXD);
|
|
|
- omap_cfg_reg(W9_USB0_TXEN);
|
|
|
- omap_cfg_reg(W5_USB0_SE0);
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ omap_cfg_reg(K18_24XX_USB0_DAT);
|
|
|
+ omap_cfg_reg(K19_24XX_USB0_TXEN);
|
|
|
+ omap_cfg_reg(J14_24XX_USB0_SE0);
|
|
|
+ if (nwires != 3)
|
|
|
+ omap_cfg_reg(J18_24XX_USB0_RCV);
|
|
|
+ } else {
|
|
|
+ omap_cfg_reg(V6_USB0_TXD);
|
|
|
+ omap_cfg_reg(W9_USB0_TXEN);
|
|
|
+ omap_cfg_reg(W5_USB0_SE0);
|
|
|
+ if (nwires != 3)
|
|
|
+ omap_cfg_reg(Y5_USB0_RCV);
|
|
|
+ }
|
|
|
|
|
|
- /* NOTE: SPEED and SUSP aren't configured here */
|
|
|
+ /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
|
|
|
+ * may be able to use I2C requests to set those bits along
|
|
|
+ * with VBUS switching and overcurrent detction.
|
|
|
+ */
|
|
|
|
|
|
- if (nwires != 3)
|
|
|
- omap_cfg_reg(Y5_USB0_RCV);
|
|
|
- if (nwires != 6)
|
|
|
+ if (cpu_class_is_omap1() && nwires != 6)
|
|
|
USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
|
|
|
|
|
|
switch (nwires) {
|
|
|
case 3:
|
|
|
syscon1 = 2;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
|
|
|
break;
|
|
|
case 4:
|
|
|
syscon1 = 1;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
|
|
|
break;
|
|
|
case 6:
|
|
|
syscon1 = 3;
|
|
|
- omap_cfg_reg(AA9_USB0_VP);
|
|
|
- omap_cfg_reg(R9_USB0_VM);
|
|
|
- USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ omap_cfg_reg(J19_24XX_USB0_VP);
|
|
|
+ omap_cfg_reg(K20_24XX_USB0_VM);
|
|
|
+ CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_UNIDIR);
|
|
|
+ } else {
|
|
|
+ omap_cfg_reg(AA9_USB0_VP);
|
|
|
+ omap_cfg_reg(R9_USB0_VM);
|
|
|
+ USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
|
|
|
+ }
|
|
|
break;
|
|
|
default:
|
|
|
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
|
|
@@ -171,14 +217,22 @@ static u32 __init omap_usb1_init(unsigned nwires)
|
|
|
{
|
|
|
u32 syscon1 = 0;
|
|
|
|
|
|
- if (nwires != 6 && !cpu_is_omap15xx())
|
|
|
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
|
|
|
USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG &= ~USBT1WRMODEI(USB_BIDIR_TLL);
|
|
|
+
|
|
|
if (nwires == 0)
|
|
|
return 0;
|
|
|
|
|
|
/* external transceiver */
|
|
|
- omap_cfg_reg(USB1_TXD);
|
|
|
- omap_cfg_reg(USB1_TXEN);
|
|
|
+ if (cpu_class_is_omap1()) {
|
|
|
+ omap_cfg_reg(USB1_TXD);
|
|
|
+ omap_cfg_reg(USB1_TXEN);
|
|
|
+ if (nwires != 3)
|
|
|
+ omap_cfg_reg(USB1_RCV);
|
|
|
+ }
|
|
|
+
|
|
|
if (cpu_is_omap15xx()) {
|
|
|
omap_cfg_reg(USB1_SEO);
|
|
|
omap_cfg_reg(USB1_SPEED);
|
|
@@ -190,20 +244,38 @@ static u32 __init omap_usb1_init(unsigned nwires)
|
|
|
} else if (cpu_is_omap1710()) {
|
|
|
omap_cfg_reg(R13_1710_USB1_SE0);
|
|
|
// SUSP
|
|
|
+ } else if (cpu_is_omap24xx()) {
|
|
|
+ /* NOTE: board-specific code must set up pin muxing for usb1,
|
|
|
+ * since each signal could come out on either of two balls.
|
|
|
+ */
|
|
|
} else {
|
|
|
- pr_debug("usb unrecognized\n");
|
|
|
+ pr_debug("usb%d cpu unrecognized\n", 1);
|
|
|
+ return 0;
|
|
|
}
|
|
|
- if (nwires != 3)
|
|
|
- omap_cfg_reg(USB1_RCV);
|
|
|
|
|
|
switch (nwires) {
|
|
|
+ case 2:
|
|
|
+ if (!cpu_is_omap24xx())
|
|
|
+ goto bad;
|
|
|
+ /* NOTE: board-specific code must override this setting if
|
|
|
+ * this TLL link is not using DP/DM
|
|
|
+ */
|
|
|
+ syscon1 = 1;
|
|
|
+ CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR_TLL);
|
|
|
+ break;
|
|
|
case 3:
|
|
|
syscon1 = 2;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
|
|
|
break;
|
|
|
case 4:
|
|
|
syscon1 = 1;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
|
|
|
break;
|
|
|
case 6:
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ goto bad;
|
|
|
syscon1 = 3;
|
|
|
omap_cfg_reg(USB1_VP);
|
|
|
omap_cfg_reg(USB1_VM);
|
|
@@ -211,6 +283,7 @@ static u32 __init omap_usb1_init(unsigned nwires)
|
|
|
USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
|
|
|
break;
|
|
|
default:
|
|
|
+bad:
|
|
|
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
|
|
|
1, nwires);
|
|
|
}
|
|
@@ -221,10 +294,17 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
|
|
|
{
|
|
|
u32 syscon1 = 0;
|
|
|
|
|
|
- /* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ CONTROL_DEVCONF_REG &= ~(USBT2WRMODEI(USB_BIDIR_TLL)
|
|
|
+ | USBT2TLL5PI);
|
|
|
+ alt_pingroup = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
|
|
|
if (alt_pingroup || nwires == 0)
|
|
|
return 0;
|
|
|
- if (nwires != 6 && !cpu_is_omap15xx())
|
|
|
+
|
|
|
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
|
|
|
USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
|
|
|
|
|
|
/* external transceiver */
|
|
@@ -242,19 +322,54 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
|
|
|
if (nwires != 3)
|
|
|
omap_cfg_reg(Y5_USB2_RCV);
|
|
|
// FIXME omap_cfg_reg(USB2_SPEED);
|
|
|
+ } else if (cpu_is_omap24xx()) {
|
|
|
+ omap_cfg_reg(Y11_24XX_USB2_DAT);
|
|
|
+ omap_cfg_reg(AA10_24XX_USB2_SE0);
|
|
|
+ if (nwires > 2)
|
|
|
+ omap_cfg_reg(AA12_24XX_USB2_TXEN);
|
|
|
+ if (nwires > 3)
|
|
|
+ omap_cfg_reg(AA6_24XX_USB2_RCV);
|
|
|
} else {
|
|
|
- pr_debug("usb unrecognized\n");
|
|
|
+ pr_debug("usb%d cpu unrecognized\n", 1);
|
|
|
+ return 0;
|
|
|
}
|
|
|
- // omap_cfg_reg(USB2_SUSP);
|
|
|
+ // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP);
|
|
|
|
|
|
switch (nwires) {
|
|
|
+ case 2:
|
|
|
+ if (!cpu_is_omap24xx())
|
|
|
+ goto bad;
|
|
|
+ /* NOTE: board-specific code must override this setting if
|
|
|
+ * this TLL link is not using DP/DM
|
|
|
+ */
|
|
|
+ syscon1 = 1;
|
|
|
+ CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR_TLL);
|
|
|
+ break;
|
|
|
case 3:
|
|
|
syscon1 = 2;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
|
|
|
break;
|
|
|
case 4:
|
|
|
syscon1 = 1;
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ if (!cpu_is_omap24xx())
|
|
|
+ goto bad;
|
|
|
+ omap_cfg_reg(AA4_24XX_USB2_TLLSE0);
|
|
|
+ /* NOTE: board-specific code must override this setting if
|
|
|
+ * this TLL link is not using DP/DM. Something must also
|
|
|
+ * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
|
|
|
+ */
|
|
|
+ syscon1 = 3;
|
|
|
+ CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_UNIDIR_TLL)
|
|
|
+ | USBT2TLL5PI;
|
|
|
break;
|
|
|
case 6:
|
|
|
+ if (cpu_is_omap24xx())
|
|
|
+ goto bad;
|
|
|
syscon1 = 3;
|
|
|
if (cpu_is_omap15xx()) {
|
|
|
omap_cfg_reg(USB2_VP);
|
|
@@ -266,6 +381,7 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
+bad:
|
|
|
printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
|
|
|
2, nwires);
|
|
|
}
|
|
@@ -294,13 +410,13 @@ static struct resource udc_resources[] = {
|
|
|
.end = UDC_BASE + 0xff,
|
|
|
.flags = IORESOURCE_MEM,
|
|
|
}, { /* general IRQ */
|
|
|
- .start = IH2_BASE + 20,
|
|
|
+ .start = INT_USB_IRQ_GEN,
|
|
|
.flags = IORESOURCE_IRQ,
|
|
|
}, { /* PIO IRQ */
|
|
|
- .start = IH2_BASE + 30,
|
|
|
+ .start = INT_USB_IRQ_NISO,
|
|
|
.flags = IORESOURCE_IRQ,
|
|
|
}, { /* SOF IRQ */
|
|
|
- .start = IH2_BASE + 29,
|
|
|
+ .start = INT_USB_IRQ_ISO,
|
|
|
.flags = IORESOURCE_IRQ,
|
|
|
},
|
|
|
};
|
|
@@ -329,11 +445,11 @@ static u64 ohci_dmamask = ~(u32)0;
|
|
|
static struct resource ohci_resources[] = {
|
|
|
{
|
|
|
.start = OMAP_OHCI_BASE,
|
|
|
- .end = OMAP_OHCI_BASE + 4096 - 1,
|
|
|
+ .end = OMAP_OHCI_BASE + 0xff,
|
|
|
.flags = IORESOURCE_MEM,
|
|
|
},
|
|
|
{
|
|
|
- .start = INT_USB_HHC_1,
|
|
|
+ .start = INT_USB_IRQ_HGEN,
|
|
|
.flags = IORESOURCE_IRQ,
|
|
|
},
|
|
|
};
|
|
@@ -361,7 +477,7 @@ static struct resource otg_resources[] = {
|
|
|
.end = OTG_BASE + 0xff,
|
|
|
.flags = IORESOURCE_MEM,
|
|
|
}, {
|
|
|
- .start = IH2_BASE + 8,
|
|
|
+ .start = INT_USB_IRQ_OTG,
|
|
|
.flags = IORESOURCE_IRQ,
|
|
|
},
|
|
|
};
|
|
@@ -385,7 +501,7 @@ static struct platform_device otg_device = {
|
|
|
|
|
|
|
|
|
// FIXME correct answer depends on hmc_mode,
|
|
|
-// as does any nonzero value for config->otg port number
|
|
|
+// as does (on omap1) any nonzero value for config->otg port number
|
|
|
#ifdef CONFIG_USB_GADGET_OMAP
|
|
|
#define is_usb0_device(config) 1
|
|
|
#else
|
|
@@ -426,12 +542,13 @@ omap_otg_init(struct omap_usb_config *config)
|
|
|
if (config->otg)
|
|
|
syscon |= OTG_EN;
|
|
|
#endif
|
|
|
- pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
|
|
|
+ if (cpu_class_is_omap1())
|
|
|
+ pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
|
|
|
pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
|
|
|
OTG_SYSCON_2_REG = syscon;
|
|
|
|
|
|
printk("USB: hmc %d", config->hmc_mode);
|
|
|
- if (alt_pingroup)
|
|
|
+ if (!alt_pingroup)
|
|
|
printk(", usb2 alt %d wires", config->pins[2]);
|
|
|
else if (config->pins[0])
|
|
|
printk(", usb0 %d wires%s", config->pins[0],
|
|
@@ -444,10 +561,12 @@ omap_otg_init(struct omap_usb_config *config)
|
|
|
printk(", Mini-AB on usb%d", config->otg - 1);
|
|
|
printk("\n");
|
|
|
|
|
|
- /* leave USB clocks/controllers off until needed */
|
|
|
- ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
|
|
|
- ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
|
|
|
- ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
|
|
|
+ if (cpu_class_is_omap1()) {
|
|
|
+ /* leave USB clocks/controllers off until needed */
|
|
|
+ ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
|
|
|
+ ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
|
|
|
+ ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
|
|
|
+ }
|
|
|
syscon = OTG_SYSCON_1_REG;
|
|
|
syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
|
|
|
|
|
@@ -585,7 +704,7 @@ omap_usb_init(void)
|
|
|
}
|
|
|
platform_data = *config;
|
|
|
|
|
|
- if (cpu_is_omap730() || cpu_is_omap16xx())
|
|
|
+ if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
|
|
|
omap_otg_init(&platform_data);
|
|
|
else if (cpu_is_omap15xx())
|
|
|
omap_1510_usb_init(&platform_data);
|