aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAjay Kumar Gupta <ajay.gupta@ti.com>2010-12-07 08:27:45 -0500
committerFelipe Balbi <balbi@ti.com>2010-12-10 03:21:35 -0500
commita9c037832e9624e240c5019d0e01e9352e8f638d (patch)
tree5d90651ae6180954029a66f074cdec01b5b95d5c
parent46960847ef3e3a5d395121635fffa5dfa279fe90 (diff)
musb: am35x: fix compile error due to control apis
commit 4814ced5116e3b73dc4f63eec84999739fc8ed11 (OMAP: control: move plat-omap/control.h to mach-omap2/control.h) moved <plat/control.h> to another location, preventing drivers from accessing it, so we need to pass function pointers from arch code to be able to talk to internal PHY on AM35x. Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--arch/arm/mach-omap2/usb-musb.c97
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h4
-rw-r--r--drivers/usb/musb/am35x.c130
3 files changed, 146 insertions, 85 deletions
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 9107883287f6..5298949d4b11 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -30,9 +30,102 @@
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 34
34#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X) 35#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X)
35 36
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
36static struct resource musb_resources[] = { 129static struct resource musb_resources[] = {
37 [0] = { /* start and end set dynamically */ 130 [0] = { /* start and end set dynamically */
38 .flags = IORESOURCE_MEM, 131 .flags = IORESOURCE_MEM,
@@ -96,6 +189,10 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
96 musb_device.name = "musb-am35x"; 189 musb_device.name = "musb-am35x";
97 musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE; 190 musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE;
98 musb_resources[1].start = INT_35XX_USBOTG_IRQ; 191 musb_resources[1].start = INT_35XX_USBOTG_IRQ;
192 board_data->set_phy_power = am35x_musb_phy_power;
193 board_data->clear_irq = am35x_musb_clear_irq;
194 board_data->set_mode = am35x_musb_set_mode;
195 board_data->reset = am35x_musb_reset;
99 } else if (cpu_is_omap34xx()) { 196 } else if (cpu_is_omap34xx()) {
100 musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE; 197 musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
101 } else if (cpu_is_omap44xx()) { 198 } else if (cpu_is_omap44xx()) {
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 9b1893f31fc8..5c02416049b2 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -70,6 +70,10 @@ struct omap_musb_board_data {
70 u8 mode; 70 u8 mode;
71 u16 power; 71 u16 power;
72 unsigned extvbus:1; 72 unsigned extvbus:1;
73 void (*set_phy_power)(u8 on);
74 void (*clear_irq)(void);
75 void (*set_mode)(u8 mode);
76 void (*reset)(void);
73}; 77};
74 78
75enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI}; 79enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 62e65f0a7284..d5a3da37c90c 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -32,7 +32,6 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/dma-mapping.h> 33#include <linux/dma-mapping.h>
34 34
35#include <plat/control.h>
36#include <plat/usb.h> 35#include <plat/usb.h>
37 36
38#include "musb_core.h" 37#include "musb_core.h"
@@ -90,47 +89,6 @@ struct am35x_glue {
90}; 89};
91#define glue_to_musb(g) platform_get_drvdata(g->musb) 90#define glue_to_musb(g) platform_get_drvdata(g->musb)
92 91
93static inline void phy_on(void)
94{
95 unsigned long timeout = jiffies + msecs_to_jiffies(100);
96 u32 devconf2;
97
98 /*
99 * Start the on-chip PHY and its PLL.
100 */
101 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
102
103 devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
104 devconf2 |= CONF2_PHY_PLLON;
105
106 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
107
108 DBG(1, "Waiting for PHY clock good...\n");
109 while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
110 & CONF2_PHYCLKGD)) {
111 cpu_relax();
112
113 if (time_after(jiffies, timeout)) {
114 DBG(1, "musb PHY clock good timed out\n");
115 break;
116 }
117 }
118}
119
120static inline void phy_off(void)
121{
122 u32 devconf2;
123
124 /*
125 * Power down the on-chip PHY.
126 */
127 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
128
129 devconf2 &= ~CONF2_PHY_PLLON;
130 devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
131 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
132}
133
134/* 92/*
135 * am35x_musb_enable - enable interrupts 93 * am35x_musb_enable - enable interrupts
136 */ 94 */
@@ -265,9 +223,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
265{ 223{
266 struct musb *musb = hci; 224 struct musb *musb = hci;
267 void __iomem *reg_base = musb->ctrl_base; 225 void __iomem *reg_base = musb->ctrl_base;
226 struct device *dev = musb->controller;
227 struct musb_hdrc_platform_data *plat = dev->platform_data;
228 struct omap_musb_board_data *data = plat->board_data;
268 unsigned long flags; 229 unsigned long flags;
269 irqreturn_t ret = IRQ_NONE; 230 irqreturn_t ret = IRQ_NONE;
270 u32 epintr, usbintr, lvl_intr; 231 u32 epintr, usbintr;
271 232
272 spin_lock_irqsave(&musb->lock, flags); 233 spin_lock_irqsave(&musb->lock, flags);
273 234
@@ -356,9 +317,8 @@ eoi:
356 /* EOI needs to be written for the IRQ to be re-asserted. */ 317 /* EOI needs to be written for the IRQ to be re-asserted. */
357 if (ret == IRQ_HANDLED || epintr || usbintr) { 318 if (ret == IRQ_HANDLED || epintr || usbintr) {
358 /* clear level interrupt */ 319 /* clear level interrupt */
359 lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 320 if (data->clear_irq)
360 lvl_intr |= AM35XX_USBOTGSS_INT_CLR; 321 data->clear_irq();
361 omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR);
362 /* write EOI */ 322 /* write EOI */
363 musb_writel(reg_base, USB_END_OF_INTR_REG, 0); 323 musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
364 } 324 }
@@ -374,37 +334,26 @@ eoi:
374 334
375static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode) 335static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
376{ 336{
377 u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); 337 struct device *dev = musb->controller;
338 struct musb_hdrc_platform_data *plat = dev->platform_data;
339 struct omap_musb_board_data *data = plat->board_data;
340 int retval = 0;
378 341
379 devconf2 &= ~CONF2_OTGMODE; 342 if (data->set_mode)
380 switch (musb_mode) { 343 data->set_mode(musb_mode);
381#ifdef CONFIG_USB_MUSB_HDRC_HCD 344 else
382 case MUSB_HOST: /* Force VBUS valid, ID = 0 */ 345 retval = -EIO;
383 devconf2 |= CONF2_FORCE_HOST;
384 break;
385#endif
386#ifdef CONFIG_USB_GADGET_MUSB_HDRC
387 case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
388 devconf2 |= CONF2_FORCE_DEVICE;
389 break;
390#endif
391#ifdef CONFIG_USB_MUSB_OTG
392 case MUSB_OTG: /* Don't override the VBUS/ID comparators */
393 devconf2 |= CONF2_NO_OVERRIDE;
394 break;
395#endif
396 default:
397 DBG(2, "Trying to set unsupported mode %u\n", musb_mode);
398 }
399 346
400 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); 347 return retval;
401 return 0;
402} 348}
403 349
404static int am35x_musb_init(struct musb *musb) 350static int am35x_musb_init(struct musb *musb)
405{ 351{
352 struct device *dev = musb->controller;
353 struct musb_hdrc_platform_data *plat = dev->platform_data;
354 struct omap_musb_board_data *data = plat->board_data;
406 void __iomem *reg_base = musb->ctrl_base; 355 void __iomem *reg_base = musb->ctrl_base;
407 u32 rev, lvl_intr, sw_reset; 356 u32 rev;
408 357
409 musb->mregs += USB_MENTOR_CORE_OFFSET; 358 musb->mregs += USB_MENTOR_CORE_OFFSET;
410 359
@@ -421,39 +370,40 @@ static int am35x_musb_init(struct musb *musb)
421 if (is_host_enabled(musb)) 370 if (is_host_enabled(musb))
422 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); 371 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
423 372
424 /* Global reset */ 373 /* Reset the musb */
425 sw_reset = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); 374 if (data->reset)
426 375 data->reset();
427 sw_reset |= AM35XX_USBOTGSS_SW_RST;
428 omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET);
429
430 sw_reset &= ~AM35XX_USBOTGSS_SW_RST;
431 omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET);
432 376
433 /* Reset the controller */ 377 /* Reset the controller */
434 musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); 378 musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
435 379
436 /* Start the on-chip PHY and its PLL. */ 380 /* Start the on-chip PHY and its PLL. */
437 phy_on(); 381 if (data->set_phy_power)
382 data->set_phy_power(1);
438 383
439 msleep(5); 384 msleep(5);
440 385
441 musb->isr = am35x_musb_interrupt; 386 musb->isr = am35x_musb_interrupt;
442 387
443 /* clear level interrupt */ 388 /* clear level interrupt */
444 lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 389 if (data->clear_irq)
445 lvl_intr |= AM35XX_USBOTGSS_INT_CLR; 390 data->clear_irq();
446 omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR);
447 391
448 return 0; 392 return 0;
449} 393}
450 394
451static int am35x_musb_exit(struct musb *musb) 395static int am35x_musb_exit(struct musb *musb)
452{ 396{
397 struct device *dev = musb->controller;
398 struct musb_hdrc_platform_data *plat = dev->platform_data;
399 struct omap_musb_board_data *data = plat->board_data;
400
453 if (is_host_enabled(musb)) 401 if (is_host_enabled(musb))
454 del_timer_sync(&otg_workaround); 402 del_timer_sync(&otg_workaround);
455 403
456 phy_off(); 404 /* Shutdown the on-chip PHY and its PLL. */
405 if (data->set_phy_power)
406 data->set_phy_power(0);
457 407
458 otg_put_transceiver(musb->xceiv); 408 otg_put_transceiver(musb->xceiv);
459 usb_nop_xceiv_unregister(); 409 usb_nop_xceiv_unregister();
@@ -630,8 +580,13 @@ static int __exit am35x_remove(struct platform_device *pdev)
630static int am35x_suspend(struct device *dev) 580static int am35x_suspend(struct device *dev)
631{ 581{
632 struct am35x_glue *glue = dev_get_drvdata(dev); 582 struct am35x_glue *glue = dev_get_drvdata(dev);
583 struct musb_hdrc_platform_data *plat = dev->platform_data;
584 struct omap_musb_board_data *data = plat->board_data;
585
586 /* Shutdown the on-chip PHY and its PLL. */
587 if (data->set_phy_power)
588 data->set_phy_power(0);
633 589
634 phy_off();
635 clk_disable(glue->phy_clk); 590 clk_disable(glue->phy_clk);
636 clk_disable(glue->clk); 591 clk_disable(glue->clk);
637 592
@@ -641,9 +596,14 @@ static int am35x_suspend(struct device *dev)
641static int am35x_resume(struct device *dev) 596static int am35x_resume(struct device *dev)
642{ 597{
643 struct am35x_glue *glue = dev_get_drvdata(dev); 598 struct am35x_glue *glue = dev_get_drvdata(dev);
599 struct musb_hdrc_platform_data *plat = dev->platform_data;
600 struct omap_musb_board_data *data = plat->board_data;
644 int ret; 601 int ret;
645 602
646 phy_on(); 603 /* Start the on-chip PHY and its PLL. */
604 if (data->set_phy_power)
605 data->set_phy_power(1);
606
647 ret = clk_enable(glue->phy_clk); 607 ret = clk_enable(glue->phy_clk);
648 if (ret) { 608 if (ret) {
649 dev_err(dev, "failed to enable PHY clock\n"); 609 dev_err(dev, "failed to enable PHY clock\n");