]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/arm/mach-mx6/usb_h1.c
ENGR00258491-2 msl-mx6: usb: put PHY to be out of low power explicitly
[karo-tx-linux.git] / arch / arm / mach-mx6 / usb_h1.c
1 /*
2  * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/types.h>
21 #include <linux/delay.h>
22 #include <linux/clk.h>
23 #include <linux/platform_device.h>
24 #include <linux/fsl_devices.h>
25 #include <linux/gpio.h>
26 #include <linux/io.h>
27 #include <linux/delay.h>
28 #include <mach/arc_otg.h>
29 #include <mach/hardware.h>
30 #include "devices-imx6q.h"
31 #include "regs-anadig.h"
32 #include "usb.h"
33
34 static struct clk *usb_oh3_clk;
35 extern int clk_get_usecount(struct clk *clk);
36 static struct fsl_usb2_platform_data usbh1_config;
37
38 static void fsl_platform_h1_set_usb_phy_dis(
39                 struct fsl_usb2_platform_data *pdata, bool enable)
40 {
41         u32 usb_phy_ctrl_dcdt = 0;
42         void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
43         usb_phy_ctrl_dcdt = __raw_readl(
44                         MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
45                         BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
46         if (enable) {
47                 if (usb_phy_ctrl_dcdt == 0) {
48                         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
49                                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
50
51                         __raw_writel(BM_USBPHY_PWD_RXPWDENV,
52                                         MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET);
53
54                         udelay(300);
55
56                         __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
57                                 MX6_IO_ADDRESS(pdata->phy_regs)
58                                 + HW_USBPHY_CTRL_SET);
59
60                         UH1_USBSTS |= (1 << 7);
61
62                         while ((UH1_USBSTS & (1 << 7)) == 0)
63                                 ;
64
65                         udelay(2);
66
67                         __raw_writel(BM_USBPHY_PWD_RXPWDENV,
68                                         MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR);
69
70                         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
71                                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
72
73                 }
74         } else {
75                 if (usb_phy_ctrl_dcdt
76                                 == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
77                         __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
78                                 MX6_IO_ADDRESS(pdata->phy_regs)
79                                 + HW_USBPHY_CTRL_CLR);
80         }
81 }
82
83 static void usbh1_internal_phy_clock_gate(bool on)
84 {
85         void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
86         if (on) {
87                 __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_CLR);
88         } else {
89                 __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_SET);
90         }
91 }
92
93 static void usbh1_platform_phy_power_on(void)
94 {
95         void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
96         __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
97                                 anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
98 }
99
100 static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
101 {
102         u32 tmp;
103         void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
104         void __iomem *phy_ctrl;
105
106         /* Stop then Reset */
107         UH1_USBCMD &= ~UCMD_RUN_STOP;
108         while (UH1_USBCMD & UCMD_RUN_STOP)
109                 ;
110
111         UH1_USBCMD |= UCMD_RESET;
112         while ((UH1_USBCMD) & (UCMD_RESET))
113                 ;
114
115         /*
116          * If the controller reset does not put the PHY be out of
117          * low power mode, do it manually.
118          */
119         if (UH1_PORTSC1 & PORTSC_PHCD) {
120                 UH1_PORTSC1 &= ~PORTSC_PHCD;
121                 mdelay(1);
122         }
123
124         /* Reset USBPHY module */
125         phy_ctrl = phy_reg + HW_USBPHY_CTRL;
126         tmp = __raw_readl(phy_ctrl);
127         tmp |= BM_USBPHY_CTRL_SFTRST;
128         __raw_writel(tmp, phy_ctrl);
129         udelay(10);
130
131         /* Remove CLKGATE and SFTRST */
132         tmp = __raw_readl(phy_ctrl);
133         tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
134         __raw_writel(tmp, phy_ctrl);
135         udelay(10);
136
137         /* Power up the PHY */
138         __raw_writel(0, phy_reg + HW_USBPHY_PWD);
139         /* enable FS/LS device */
140         tmp = __raw_readl(phy_reg + HW_USBPHY_CTRL);
141         tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
142         __raw_writel(tmp, phy_reg + HW_USBPHY_CTRL);
143
144         if (!usb_icbug_swfix_need())
145                 __raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
146         if (cpu_is_mx6sl())
147                 __raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
148         return 0;
149 }
150 static int fsl_usb_host_init_ext(struct platform_device *pdev)
151 {
152         int ret;
153         struct clk *usb_clk;
154         usb_clk = clk_get(NULL, "usboh3_clk");
155         clk_enable(usb_clk);
156         usb_oh3_clk = usb_clk;
157
158         ret = fsl_usb_host_init(pdev);
159         if (ret) {
160                 printk(KERN_ERR "host1 init fails......\n");
161                 clk_disable(usb_oh3_clk);
162                 clk_put(usb_oh3_clk);
163                 return ret;
164         }
165         usbh1_internal_phy_clock_gate(true);
166         usb_phy_enable(pdev->dev.platform_data);
167
168         return 0;
169 }
170
171 static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
172 {
173         struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
174
175         fsl_usb_host_uninit(pdata);
176
177         clk_disable(usb_oh3_clk);
178         clk_put(usb_oh3_clk);
179
180 }
181
182 static void usbh1_clock_gate(bool on)
183 {
184         pr_debug("%s: on is %d\n", __func__, on);
185         if (on) {
186                 clk_enable(usb_oh3_clk);
187         } else {
188                 clk_disable(usb_oh3_clk);
189         }
190 }
191
192 static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
193 {
194         void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
195
196         pr_debug("host1, %s, enable is %d\n", __func__, enable);
197         if (enable) {
198                 __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
199                                 | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
200                                 | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
201                                 | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
202                                 | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
203                                 | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
204                                 | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_SET);
205                 USB_H1_CTRL |= (UCTRL_OWIE);
206         } else {
207                 __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
208                                 | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
209                                 | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
210                                 | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
211                                 | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
212                                 | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
213                                 | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_CLR);
214                 USB_H1_CTRL &= ~(UCTRL_OWIE);
215                 /* The interrupt must be disabled for at least 3
216                 * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
217                 udelay(100);
218         }
219 }
220
221 static void usbh1_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata)
222 {
223         void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
224         u32 tmp;
225         u32 index = 0;
226
227         /* before we set and then clear PWD bit,
228          * we must wait LS to be J */
229         if ((UH1_PORTSC1 & (3 << 26)) != (1 << 26)) {
230                 while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_J_STATE) &&
231                                 (index < 1000)) {
232                         index++;
233                         udelay(4);
234                 }
235         } else {
236                 while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_K_STATE) &&
237                                 (index < 1000)) {
238                         index++;
239                         udelay(4);
240                 }
241         }
242
243         if (index >= 1000)
244                 printk(KERN_INFO "%s big error\n", __func__);
245
246         tmp = (BM_USBPHY_PWD_TXPWDFS
247                 | BM_USBPHY_PWD_TXPWDIBIAS
248                 | BM_USBPHY_PWD_TXPWDV2I
249                 | BM_USBPHY_PWD_RXPWDENV
250                 | BM_USBPHY_PWD_RXPWD1PT1
251                 | BM_USBPHY_PWD_RXPWDDIFF
252                 | BM_USBPHY_PWD_RXPWDRX);
253         __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
254
255         __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
256
257         fsl_platform_h1_set_usb_phy_dis(pdata, 0);
258 }
259
260 static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
261 {
262         u32 index = 0;
263
264         if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
265                 return ;
266         while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
267                         && (index < 1000)) {
268                 udelay(500);
269                 index++;
270         }
271         if (index >= 1000)
272                 printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
273                 __func__, __LINE__);
274         /* We should add some delay to wait for the device switch to
275           * High-Speed 45ohm termination resistors mode. */
276         udelay(500);
277         fsl_platform_h1_set_usb_phy_dis(pdata, 1);
278 }
279
280 static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
281 {
282         /*for mx6sl ,we do not need any sw fix*/
283         if (cpu_is_mx6sl())
284                 return ;
285         __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
286                 MX6_IO_ADDRESS(pdata->phy_regs)
287                 + HW_USBPHY_CTRL_CLR);
288 }
289
290 static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
291 {
292         u32 index = 0;
293
294         /*for mx6sl ,we do not need any sw fix*/
295         if (cpu_is_mx6sl())
296                 return ;
297         if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
298                 return ;
299         while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
300                         && (index < 1000)) {
301                 udelay(500);
302                 index++;
303         }
304         if (index >= 1000)
305                 printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
306                 __func__, __LINE__);
307         /* We should add some delay to wait for the device switch to
308           * High-Speed 45ohm termination resistors mode. */
309         udelay(500);
310         __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
311                 MX6_IO_ADDRESS(pdata->phy_regs)
312                 + HW_USBPHY_CTRL_SET);
313 }
314
315 static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
316 {
317         u32 tmp;
318         void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
319         pr_debug("host1, %s, enable is %d\n", __func__, enable);
320         if (enable) {
321                 UH1_PORTSC1 |= PORTSC_PHCD;
322
323                 pr_debug("%s, Poweroff UTMI \n", __func__);
324
325                 tmp = (BM_USBPHY_PWD_TXPWDFS
326                         | BM_USBPHY_PWD_TXPWDIBIAS
327                         | BM_USBPHY_PWD_TXPWDV2I
328                         | BM_USBPHY_PWD_RXPWDENV
329                         | BM_USBPHY_PWD_RXPWD1PT1
330                         | BM_USBPHY_PWD_RXPWDDIFF
331                         | BM_USBPHY_PWD_RXPWDRX);
332                 __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
333
334                 usbh1_internal_phy_clock_gate(false);
335         } else {
336                 if (UH1_PORTSC1 & PORTSC_PHCD) {
337                         UH1_PORTSC1 &= ~PORTSC_PHCD;
338                         mdelay(1);
339                 }
340                 usbh1_internal_phy_clock_gate(true);
341                 tmp = (BM_USBPHY_PWD_TXPWDFS
342                         | BM_USBPHY_PWD_TXPWDIBIAS
343                         | BM_USBPHY_PWD_TXPWDV2I
344                         | BM_USBPHY_PWD_RXPWDENV
345                         | BM_USBPHY_PWD_RXPWD1PT1
346                         | BM_USBPHY_PWD_RXPWDDIFF
347                         | BM_USBPHY_PWD_RXPWDRX);
348                 __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
349                 /*
350                  * The PHY works at 32Khz clock when it is at low power mode,
351                  * it needs 10 clocks from 32Khz to normal work state, so
352                  * 500us is the safe value for PHY enters stable status
353                  * according to IC engineer.
354                  */
355                 udelay(500);
356
357         }
358 }
359
360 static enum usb_wakeup_event _is_usbh1_wakeup(struct fsl_usb2_platform_data *pdata)
361 {
362         u32 wakeup_req = USB_H1_CTRL & UCTRL_OWIR;
363
364         if (wakeup_req)
365                 return WAKEUP_EVENT_DPDM;
366         pr_err("host1, %s, invalid wake up\n", __func__);
367         return WAKEUP_EVENT_INVALID;
368 }
369
370 static void h1_wakeup_handler(struct fsl_usb2_platform_data *pdata)
371 {
372         _wake_up_enable(pdata, false);
373         _phy_lowpower_suspend(pdata, false);
374 }
375
376 static void usbh1_wakeup_event_clear(void)
377 {
378         int wakeup_req = USB_H1_CTRL & UCTRL_OWIR;
379
380         if (wakeup_req != 0) {
381                 printk(KERN_INFO "Unknown wakeup.(H1 OTGSC 0x%x)\n", UH1_PORTSC1);
382                 /* Disable OWIE to clear OWIR, wait 3 clock
383                  * cycles of standly clock(32KHz)
384                  */
385                 USB_H1_CTRL &= ~UCTRL_OWIE;
386                 udelay(100);
387                 USB_H1_CTRL |= UCTRL_OWIE;
388         }
389 }
390
391 static struct fsl_usb2_platform_data usbh1_config = {
392         .name           = "Host 1",
393         .init           = fsl_usb_host_init_ext,
394         .exit           = fsl_usb_host_uninit_ext,
395         .operating_mode = FSL_USB2_MPH_HOST,
396         .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
397         .power_budget = 500,    /* 500 mA max power */
398         .wake_up_enable = _wake_up_enable,
399         .usb_clock_for_pm  = usbh1_clock_gate,
400         .platform_set_disconnect_det = fsl_platform_h1_set_usb_phy_dis,
401         .phy_lowpower_suspend = _phy_lowpower_suspend,
402         .is_wakeup_event = _is_usbh1_wakeup,
403         .wakeup_handler = h1_wakeup_handler,
404         .platform_phy_power_on = usbh1_platform_phy_power_on,
405         .transceiver = "utmi",
406         .phy_regs = USB_PHY1_BASE_ADDR,
407 };
408 static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = {
409                 .name = "USBH1 wakeup",
410                 .usb_clock_for_pm  = usbh1_clock_gate,
411                 .usb_pdata = {&usbh1_config, NULL, NULL},
412                 .usb_wakeup_exhandle = usbh1_wakeup_event_clear,
413 };
414
415 static struct platform_device *pdev, *pdev_wakeup;
416 static driver_vbus_func  mx6_set_usb_host1_vbus;
417
418 static int  __init mx6_usb_h1_init(void)
419 {
420         static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
421         struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = {
422                 imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)};
423         struct imx_fsl_usb2_wakeup_data  imx6sl_fsl_hs_wakeup_data[] = {
424                 imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)};
425         struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = {
426                 imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)};
427         struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = {
428                 imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)};
429
430         mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus);
431         usbh1_config.platform_driver_vbus = mx6_set_usb_host1_vbus;
432
433         /* Some phy and power's special controls for host1
434          * 1. The external charger detector needs to be disabled
435          * or the signal at DP will be poor
436          * 2. The PLL's power and output to usb for host 1
437          * is totally controlled by IC, so the Software only needs
438          * to enable them at initializtion.
439          */
440         __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B  \
441                         | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
442                         anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
443         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
444                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
445         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE  \
446                         | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
447                         | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
448                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
449
450         usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
451         if (usb_icbug_swfix_need()) {
452                 usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend_swfix;
453                 usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume_swfix;
454         } else {
455                 usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend;
456                 usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume;
457         }
458         if (cpu_is_mx6sl())
459                 pdev = imx6sl_add_fsl_ehci_hs(1, &usbh1_config);
460         else
461                 pdev = imx6q_add_fsl_ehci_hs(1, &usbh1_config);
462         usbh1_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
463         if (cpu_is_mx6sl())
464                 pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
465         else
466                 pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
467         platform_device_add(pdev);
468         ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
469                 (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
470         return 0;
471 }
472 module_init(mx6_usb_h1_init);
473
474 static void __exit mx6_usb_h1_exit(void)
475 {
476         static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
477
478         platform_device_unregister(pdev);
479         platform_device_unregister(pdev_wakeup);
480         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
481                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
482         __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE  \
483                         | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
484                         | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
485                         anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
486
487         return ;
488 }
489 module_exit(mx6_usb_h1_exit);
490
491 MODULE_AUTHOR("Freescale Semiconductor");
492 MODULE_LICENSE("GPL");