diff options
| author | David Brownell <dbrownell@users.sourceforge.net> | 2009-02-24 18:31:54 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:20:36 -0400 |
| commit | a227fd7db74fa05d866790a4b29ba049bb5035cc (patch) | |
| tree | d3f852d767e1c31394acd2c9bec811c0619df5dd | |
| parent | 743821717c611913a5a3f95010b141f0b4cb5463 (diff) | |
USB: musb: partial DaVinci dm355 support
Partial support for DaVinci DM355, on the EVM board; peripheral
mode should work, once mainline merges DM355 support. Missing:
(a) renumbering the GPIO for DRVVBUS on the DM6446 EVM,
when DAVINCI_N_GPIO increases;
(b) disabling DM355_DEEPSLEEP.DRVVBUS_OVERRIDE so VBUS is
driven according to the ID signal, if cpu_is_..._dm355()
The new PHY control bits are ignored on DM6446.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/musb/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/usb/musb/davinci.c | 63 | ||||
| -rw-r--r-- | drivers/usb/musb/davinci.h | 23 |
3 files changed, 62 insertions, 30 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9985db08e7db..b66e8544d8b9 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
| @@ -20,8 +20,8 @@ config USB_MUSB_HDRC | |||
| 20 | it's being used with, including the USB peripheral role, | 20 | it's being used with, including the USB peripheral role, |
| 21 | or the USB host role, or both. | 21 | or the USB host role, or both. |
| 22 | 22 | ||
| 23 | Texas Instruments parts using this IP include DaVinci 644x, | 23 | Texas Instruments familiies using this IP include DaVinci |
| 24 | OMAP 243x, OMAP 343x, and TUSB 6010. | 24 | (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010. |
| 25 | 25 | ||
| 26 | Analog Devices parts using this IP include Blackfin BF54x, | 26 | Analog Devices parts using this IP include Blackfin BF54x, |
| 27 | BF525 and BF527. | 27 | BF525 and BF527. |
| @@ -40,7 +40,7 @@ config USB_MUSB_SOC | |||
| 40 | default y if (BF54x && !BF544) | 40 | default y if (BF54x && !BF544) |
| 41 | default y if (BF52x && !BF522 && !BF523) | 41 | default y if (BF52x && !BF522 && !BF523) |
| 42 | 42 | ||
| 43 | comment "DaVinci 644x USB support" | 43 | comment "DaVinci 35x and 644x USB support" |
| 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
| 45 | 45 | ||
| 46 | comment "OMAP 243x high speed USB support" | 46 | comment "OMAP 243x high speed USB support" |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 2dc7606f319c..10d11ab113ab 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -48,6 +48,9 @@ | |||
| 48 | #include "cppi_dma.h" | 48 | #include "cppi_dma.h" |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) | ||
| 52 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) | ||
| 53 | |||
| 51 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most | 54 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most |
| 52 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 | 55 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 |
| 53 | * and, when in host mode, autosuspending idle root ports... PHYPLLON | 56 | * and, when in host mode, autosuspending idle root ports... PHYPLLON |
| @@ -56,20 +59,26 @@ | |||
| 56 | 59 | ||
| 57 | static inline void phy_on(void) | 60 | static inline void phy_on(void) |
| 58 | { | 61 | { |
| 59 | /* start the on-chip PHY and its PLL */ | 62 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
| 60 | __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON, | 63 | |
| 61 | (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR)); | 64 | /* power everything up; start the on-chip PHY and its PLL */ |
| 62 | while ((__raw_readl((void __force __iomem *) | 65 | phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); |
| 63 | IO_ADDRESS(USBPHY_CTL_PADDR)) | 66 | phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; |
| 64 | & USBPHY_PHYCLKGD) == 0) | 67 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
| 68 | |||
| 69 | /* wait for PLL to lock before proceeding */ | ||
| 70 | while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0) | ||
| 65 | cpu_relax(); | 71 | cpu_relax(); |
| 66 | } | 72 | } |
| 67 | 73 | ||
| 68 | static inline void phy_off(void) | 74 | static inline void phy_off(void) |
| 69 | { | 75 | { |
| 70 | /* powerdown the on-chip PHY and its oscillator */ | 76 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
| 71 | __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *) | 77 | |
| 72 | IO_ADDRESS(USBPHY_CTL_PADDR)); | 78 | /* powerdown the on-chip PHY, its PLL, and the OTG block */ |
| 79 | phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON); | ||
| 80 | phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN; | ||
| 81 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
| 73 | } | 82 | } |
| 74 | 83 | ||
| 75 | static int dma_off = 1; | 84 | static int dma_off = 1; |
| @@ -126,10 +135,6 @@ void musb_platform_disable(struct musb *musb) | |||
| 126 | } | 135 | } |
| 127 | 136 | ||
| 128 | 137 | ||
| 129 | /* REVISIT it's not clear whether DaVinci can support full OTG. */ | ||
| 130 | |||
| 131 | static int vbus_state = -1; | ||
| 132 | |||
| 133 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 138 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
| 134 | #define portstate(stmt) stmt | 139 | #define portstate(stmt) stmt |
| 135 | #else | 140 | #else |
| @@ -137,10 +142,19 @@ static int vbus_state = -1; | |||
| 137 | #endif | 142 | #endif |
| 138 | 143 | ||
| 139 | 144 | ||
| 140 | /* VBUS SWITCHING IS BOARD-SPECIFIC */ | 145 | /* |
| 146 | * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM, | ||
| 147 | * which doesn't wire DRVVBUS to the FET that switches it. Unclear | ||
| 148 | * if that's a problem with the DM6446 chip or just with that board. | ||
| 149 | * | ||
| 150 | * In either case, the DM355 EVM automates DRVVBUS the normal way, | ||
| 151 | * when J10 is out, and TI documents it as handling OTG. | ||
| 152 | */ | ||
| 141 | 153 | ||
| 142 | #ifdef CONFIG_MACH_DAVINCI_EVM | 154 | #ifdef CONFIG_MACH_DAVINCI_EVM |
| 143 | 155 | ||
| 156 | static int vbus_state = -1; | ||
| 157 | |||
| 144 | /* I2C operations are always synchronous, and require a task context. | 158 | /* I2C operations are always synchronous, and require a task context. |
| 145 | * With unloaded systems, using the shared workqueue seems to suffice | 159 | * With unloaded systems, using the shared workqueue seems to suffice |
| 146 | * to satisfy the 100msec A_WAIT_VRISE timeout... | 160 | * to satisfy the 100msec A_WAIT_VRISE timeout... |
| @@ -150,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored) | |||
| 150 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 164 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
| 151 | vbus_state = !vbus_state; | 165 | vbus_state = !vbus_state; |
| 152 | } | 166 | } |
| 153 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
| 154 | 167 | ||
| 155 | #endif /* EVM */ | 168 | #endif /* EVM */ |
| 156 | 169 | ||
| 157 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) | 170 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) |
| 158 | { | 171 | { |
| 172 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
| 159 | if (is_on) | 173 | if (is_on) |
| 160 | is_on = 1; | 174 | is_on = 1; |
| 161 | 175 | ||
| @@ -163,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) | |||
| 163 | return; | 177 | return; |
| 164 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ | 178 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ |
| 165 | 179 | ||
| 166 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
| 167 | if (machine_is_davinci_evm()) { | 180 | if (machine_is_davinci_evm()) { |
| 181 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
| 182 | |||
| 168 | if (immediate) | 183 | if (immediate) |
| 169 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 184 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
| 170 | else | 185 | else |
| 171 | schedule_work(&evm_vbus_work); | 186 | schedule_work(&evm_vbus_work); |
| 172 | } | 187 | } |
| 173 | #endif | ||
| 174 | if (immediate) | 188 | if (immediate) |
| 175 | vbus_state = is_on; | 189 | vbus_state = is_on; |
| 190 | #endif | ||
| 176 | } | 191 | } |
| 177 | 192 | ||
| 178 | static void davinci_set_vbus(struct musb *musb, int is_on) | 193 | static void davinci_set_vbus(struct musb *musb, int is_on) |
| @@ -391,6 +406,17 @@ int __init musb_platform_init(struct musb *musb) | |||
| 391 | musb->board_set_vbus = davinci_set_vbus; | 406 | musb->board_set_vbus = davinci_set_vbus; |
| 392 | davinci_source_power(musb, 0, 1); | 407 | davinci_source_power(musb, 0, 1); |
| 393 | 408 | ||
| 409 | /* dm355 EVM swaps D+/D- for signal integrity, and | ||
| 410 | * is clocked from the main 24 MHz crystal. | ||
| 411 | */ | ||
| 412 | if (machine_is_davinci_dm355_evm()) { | ||
| 413 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); | ||
| 414 | |||
| 415 | phy_ctrl &= ~(3 << 9); | ||
| 416 | phy_ctrl |= USBPHY_DATAPOL; | ||
| 417 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
| 418 | } | ||
| 419 | |||
| 394 | /* reset the controller */ | 420 | /* reset the controller */ |
| 395 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 421 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
| 396 | 422 | ||
| @@ -401,8 +427,7 @@ int __init musb_platform_init(struct musb *musb) | |||
| 401 | 427 | ||
| 402 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ | 428 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ |
| 403 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", | 429 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", |
| 404 | revision, __raw_readl((void __force __iomem *) | 430 | revision, __raw_readl(USB_PHY_CTRL), |
| 405 | IO_ADDRESS(USBPHY_CTL_PADDR)), | ||
| 406 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); | 431 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); |
| 407 | 432 | ||
| 408 | musb->isr = davinci_interrupt; | 433 | musb->isr = davinci_interrupt; |
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 7fb6238e270f..046c84433cad 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h | |||
| @@ -15,14 +15,21 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | /* Integrated highspeed/otg PHY */ | 17 | /* Integrated highspeed/otg PHY */ |
| 18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) | 18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) |
| 19 | #define USBPHY_PHYCLKGD (1 << 8) | 19 | #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ |
| 20 | #define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */ | 20 | #define USBPHY_PHYCLKGD BIT(8) |
| 21 | #define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */ | 21 | #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ |
| 22 | #define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */ | 22 | #define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */ |
| 23 | #define USBPHY_CLKO1SEL (1 << 3) | 23 | #define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */ |
| 24 | #define USBPHY_OSCPDWN (1 << 2) | 24 | #define USBPHY_PHYPLLON BIT(4) /* override pll suspend */ |
| 25 | #define USBPHY_PHYPDWN (1 << 0) | 25 | #define USBPHY_CLKO1SEL BIT(3) |
| 26 | #define USBPHY_OSCPDWN BIT(2) | ||
| 27 | #define USBPHY_OTGPDWN BIT(1) | ||
| 28 | #define USBPHY_PHYPDWN BIT(0) | ||
| 29 | |||
| 30 | #define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) | ||
| 31 | #define DRVVBUS_FORCE BIT(2) | ||
| 32 | #define DRVVBUS_OVERRIDE BIT(1) | ||
| 26 | 33 | ||
| 27 | /* For now include usb OTG module registers here */ | 34 | /* For now include usb OTG module registers here */ |
| 28 | #define DAVINCI_USB_VERSION_REG 0x00 | 35 | #define DAVINCI_USB_VERSION_REG 0x00 |
