aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/usb-musb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 22:28:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 22:28:15 -0400
commit0df0914d414a504b975f3cc66ace0c16ef55b7f3 (patch)
treec97ffa357943a8b226cdec1b9632c4cede813205 /arch/arm/mach-omap2/usb-musb.c
parent6899608533410557e6698cb9d4ff6df553916e98 (diff)
parent05f689400ea5fa3d71af82f910c8b140f87ad1f3 (diff)
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (258 commits) omap: zoom: host should not pull up wl1271's irq line arm: plat-omap: iommu: fix request_mem_region() error path OMAP2+: Common CPU DIE ID reading code reads wrong registers for OMAP4430 omap4: mux: Remove duplicate mux modes omap: iovmm: don't check 'da' to set IOVMF_DA_FIXED flag omap: iovmm: disallow mapping NULL address when IOVMF_DA_ANON is set omap2+: mux: Fix compile when CONFIG_OMAP_MUX is not selected omap4: board-omap4panda: Initialise the serial pads omap3: board-3430sdp: Initialise the serial pads omap4: board-4430sdp: Initialise the serial pads omap2+: mux: Add macro for configuring static with omap_hwmod_mux_init omap2+: mux: Remove the use of IDLE flag omap2+: Add separate list for dynamic pads to mux perf: add OMAP support for the new power events OMAP4: Add IVA OPP enteries. OMAP4: Update Voltage Rail Values for MPU, IVA and CORE OMAP4: Enable 800 MHz and 1 GHz MPU-OPP OMAP3+: OPP: Replace voltage values with Macros OMAP3: wdtimer: Fix CORE idle transition Watchdog: omap_wdt: add fine grain runtime-pm ... Fix up various conflicts in - arch/arm/mach-omap2/board-omap3evm.c - arch/arm/mach-omap2/clock3xxx_data.c - arch/arm/mach-omap2/usb-musb.c - arch/arm/plat-omap/include/plat/usb.h - drivers/usb/musb/musb_core.h
Diffstat (limited to 'arch/arm/mach-omap2/usb-musb.c')
-rw-r--r--arch/arm/mach-omap2/usb-musb.c220
1 files changed, 83 insertions, 137 deletions
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 241fc94b411..35559f77e2d 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -30,118 +30,11 @@
30#include <mach/irqs.h> 30#include <mach/irqs.h>
31#include <mach/am35xx.h> 31#include <mach/am35xx.h>
32#include <plat/usb.h> 32#include <plat/usb.h>
33#include "control.h" 33#include <plat/omap_device.h>
34#include "mux.h"
34 35
35#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X) 36#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X)
36 37
37static void am35x_musb_reset(void)
38{
39 u32 regval;
40
41 /* Reset the musb interface */
42 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
43
44 regval |= AM35XX_USBOTGSS_SW_RST;
45 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
46
47 regval &= ~AM35XX_USBOTGSS_SW_RST;
48 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
49
50 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
51}
52
53static void am35x_musb_phy_power(u8 on)
54{
55 unsigned long timeout = jiffies + msecs_to_jiffies(100);
56 u32 devconf2;
57
58 if (on) {
59 /*
60 * Start the on-chip PHY and its PLL.
61 */
62 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
63
64 devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
65 devconf2 |= CONF2_PHY_PLLON;
66
67 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
68
69 pr_info(KERN_INFO "Waiting for PHY clock good...\n");
70 while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
71 & CONF2_PHYCLKGD)) {
72 cpu_relax();
73
74 if (time_after(jiffies, timeout)) {
75 pr_err(KERN_ERR "musb PHY clock good timed out\n");
76 break;
77 }
78 }
79 } else {
80 /*
81 * Power down the on-chip PHY.
82 */
83 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
84
85 devconf2 &= ~CONF2_PHY_PLLON;
86 devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
87 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
88 }
89}
90
91static void am35x_musb_clear_irq(void)
92{
93 u32 regval;
94
95 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
96 regval |= AM35XX_USBOTGSS_INT_CLR;
97 omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
98 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
99}
100
101static void am35x_musb_set_mode(u8 musb_mode)
102{
103 u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
104
105 devconf2 &= ~CONF2_OTGMODE;
106 switch (musb_mode) {
107#ifdef CONFIG_USB_MUSB_HDRC_HCD
108 case MUSB_HOST: /* Force VBUS valid, ID = 0 */
109 devconf2 |= CONF2_FORCE_HOST;
110 break;
111#endif
112#ifdef CONFIG_USB_GADGET_MUSB_HDRC
113 case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
114 devconf2 |= CONF2_FORCE_DEVICE;
115 break;
116#endif
117#ifdef CONFIG_USB_MUSB_OTG
118 case MUSB_OTG: /* Don't override the VBUS/ID comparators */
119 devconf2 |= CONF2_NO_OVERRIDE;
120 break;
121#endif
122 default:
123 pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
124 }
125
126 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
127}
128
129static struct resource musb_resources[] = {
130 [0] = { /* start and end set dynamically */
131 .flags = IORESOURCE_MEM,
132 },
133 [1] = { /* general IRQ */
134 .start = INT_243X_HS_USB_MC,
135 .flags = IORESOURCE_IRQ,
136 .name = "mc",
137 },
138 [2] = { /* DMA IRQ */
139 .start = INT_243X_HS_USB_DMA,
140 .flags = IORESOURCE_IRQ,
141 .name = "dma",
142 },
143};
144
145static struct musb_hdrc_config musb_config = { 38static struct musb_hdrc_config musb_config = {
146 .multipoint = 1, 39 .multipoint = 1,
147 .dyn_fifo = 1, 40 .dyn_fifo = 1,
@@ -169,38 +62,65 @@ static struct musb_hdrc_platform_data musb_plat = {
169 62
170static u64 musb_dmamask = DMA_BIT_MASK(32); 63static u64 musb_dmamask = DMA_BIT_MASK(32);
171 64
172static struct platform_device musb_device = { 65static struct omap_device_pm_latency omap_musb_latency[] = {
173 .name = "musb-omap2430", 66 {
174 .id = -1, 67 .deactivate_func = omap_device_idle_hwmods,
175 .dev = { 68 .activate_func = omap_device_enable_hwmods,
176 .dma_mask = &musb_dmamask, 69 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
177 .coherent_dma_mask = DMA_BIT_MASK(32),
178 .platform_data = &musb_plat,
179 }, 70 },
180 .num_resources = ARRAY_SIZE(musb_resources),
181 .resource = musb_resources,
182}; 71};
183 72
73static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
74{
75 switch (board_data->interface_type) {
76 case MUSB_INTERFACE_UTMI:
77 omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT);
78 omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT);
79 break;
80 case MUSB_INTERFACE_ULPI:
81 omap_mux_init_signal("usba0_ulpiphy_clk",
82 OMAP_PIN_INPUT_PULLDOWN);
83 omap_mux_init_signal("usba0_ulpiphy_stp",
84 OMAP_PIN_INPUT_PULLDOWN);
85 omap_mux_init_signal("usba0_ulpiphy_dir",
86 OMAP_PIN_INPUT_PULLDOWN);
87 omap_mux_init_signal("usba0_ulpiphy_nxt",
88 OMAP_PIN_INPUT_PULLDOWN);
89 omap_mux_init_signal("usba0_ulpiphy_dat0",
90 OMAP_PIN_INPUT_PULLDOWN);
91 omap_mux_init_signal("usba0_ulpiphy_dat1",
92 OMAP_PIN_INPUT_PULLDOWN);
93 omap_mux_init_signal("usba0_ulpiphy_dat2",
94 OMAP_PIN_INPUT_PULLDOWN);
95 omap_mux_init_signal("usba0_ulpiphy_dat3",
96 OMAP_PIN_INPUT_PULLDOWN);
97 omap_mux_init_signal("usba0_ulpiphy_dat4",
98 OMAP_PIN_INPUT_PULLDOWN);
99 omap_mux_init_signal("usba0_ulpiphy_dat5",
100 OMAP_PIN_INPUT_PULLDOWN);
101 omap_mux_init_signal("usba0_ulpiphy_dat6",
102 OMAP_PIN_INPUT_PULLDOWN);
103 omap_mux_init_signal("usba0_ulpiphy_dat7",
104 OMAP_PIN_INPUT_PULLDOWN);
105 break;
106 default:
107 break;
108 }
109}
110
184void __init usb_musb_init(struct omap_musb_board_data *board_data) 111void __init usb_musb_init(struct omap_musb_board_data *board_data)
185{ 112{
186 if (cpu_is_omap243x()) { 113 struct omap_hwmod *oh;
187 musb_resources[0].start = OMAP243X_HS_BASE; 114 struct omap_device *od;
188 } else if (cpu_is_omap3517() || cpu_is_omap3505()) { 115 struct platform_device *pdev;
189 musb_device.name = "musb-am35x"; 116 struct device *dev;
190 musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE; 117 int bus_id = -1;
191 musb_resources[1].start = INT_35XX_USBOTG_IRQ; 118 const char *oh_name, *name;
192 board_data->set_phy_power = am35x_musb_phy_power; 119
193 board_data->clear_irq = am35x_musb_clear_irq; 120 if (cpu_is_omap3517() || cpu_is_omap3505()) {
194 board_data->set_mode = am35x_musb_set_mode;
195 board_data->reset = am35x_musb_reset;
196 } else if (cpu_is_omap34xx()) {
197 musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
198 } else if (cpu_is_omap44xx()) { 121 } else if (cpu_is_omap44xx()) {
199 musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE; 122 usb_musb_mux_init(board_data);
200 musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N;
201 musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N;
202 } 123 }
203 musb_resources[0].end = musb_resources[0].start + SZ_4K - 1;
204 124
205 /* 125 /*
206 * REVISIT: This line can be removed once all the platforms using 126 * REVISIT: This line can be removed once all the platforms using
@@ -212,12 +132,38 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
212 musb_plat.mode = board_data->mode; 132 musb_plat.mode = board_data->mode;
213 musb_plat.extvbus = board_data->extvbus; 133 musb_plat.extvbus = board_data->extvbus;
214 134
215 if (platform_device_register(&musb_device) < 0)
216 printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
217
218 if (cpu_is_omap44xx()) 135 if (cpu_is_omap44xx())
219 omap4430_phy_init(dev); 136 omap4430_phy_init(dev);
220 137
138 if (cpu_is_omap3517() || cpu_is_omap3505()) {
139 oh_name = "am35x_otg_hs";
140 name = "musb-am35x";
141 } else {
142 oh_name = "usb_otg_hs";
143 name = "musb-omap2430";
144 }
145
146 oh = omap_hwmod_lookup(oh_name);
147 if (!oh) {
148 pr_err("Could not look up %s\n", oh_name);
149 return;
150 }
151
152 od = omap_device_build(name, bus_id, oh, &musb_plat,
153 sizeof(musb_plat), omap_musb_latency,
154 ARRAY_SIZE(omap_musb_latency), false);
155 if (IS_ERR(od)) {
156 pr_err("Could not build omap_device for %s %s\n",
157 name, oh_name);
158 return;
159 }
160
161 pdev = &od->pdev;
162 dev = &pdev->dev;
163 get_device(dev);
164 dev->dma_mask = &musb_dmamask;
165 dev->coherent_dma_mask = musb_dmamask;
166 put_device(dev);
221} 167}
222 168
223#else 169#else