2 * Copyright 2012-2015 Freescale Semiconductor, Inc.
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
12 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/err.h>
16 #include <linux/delay.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
20 #include "ci_hdrc_imx.h"
22 #define MX25_USB_PHY_CTRL_OFFSET 0x08
23 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23)
25 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
26 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0)
27 #define MX25_EHCI_INTERFACE_MASK (0xf)
29 #define MX25_OTG_SIC_SHIFT 29
30 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
31 #define MX25_OTG_PM_BIT BIT(24)
32 #define MX25_OTG_PP_BIT BIT(11)
33 #define MX25_OTG_OCPOL_BIT BIT(3)
35 #define MX25_H1_SIC_SHIFT 21
36 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
37 #define MX25_H1_PP_BIT BIT(18)
38 #define MX25_H1_PM_BIT BIT(16)
39 #define MX25_H1_IPPUE_UP_BIT BIT(7)
40 #define MX25_H1_IPPUE_DOWN_BIT BIT(6)
41 #define MX25_H1_TLL_BIT BIT(5)
42 #define MX25_H1_USBTE_BIT BIT(4)
43 #define MX25_H1_OCPOL_BIT BIT(2)
45 #define MX27_H1_PM_BIT BIT(8)
46 #define MX27_H2_PM_BIT BIT(16)
47 #define MX27_OTG_PM_BIT BIT(24)
49 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08
50 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c
51 #define MX53_USB_UH2_CTRL_OFFSET 0x14
52 #define MX53_USB_UH3_CTRL_OFFSET 0x18
53 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5)
54 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8)
55 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
56 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3
57 #define MX53_USB_PLL_DIV_24_MHZ 0x01
59 #define MX6_BM_UNBURST_SETTING BIT(1)
60 #define MX6_BM_OVER_CUR_DIS BIT(7)
61 #define MX6_BM_WAKEUP_ENABLE BIT(10)
62 #define MX6_BM_UTMI_ON_CLOCK BIT(13)
63 #define MX6_BM_ID_WAKEUP BIT(16)
64 #define MX6_BM_VBUS_WAKEUP BIT(17)
65 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29)
66 #define MX6_BM_WAKEUP_INTR BIT(31)
68 #define MX6_USB_HSIC_CTRL_OFFSET 0x10
69 /* Send resume signal without 480Mhz PHY clock */
70 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23)
71 /* set before portsc.suspendM = 1 */
72 #define MX6_BM_HSIC_DEV_CONN BIT(21)
74 #define MX6_BM_HSIC_EN BIT(12)
75 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */
76 #define MX6_BM_HSIC_CLK_ON BIT(11)
78 #define MX6_USB_OTG1_PHY_CTRL 0x18
79 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */
80 #define MX6_USB_OTG2_PHY_CTRL 0x1c
81 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8)
82 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0)
83 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1)
84 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2)
85 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3)
87 #define VF610_OVER_CUR_DIS BIT(7)
89 #define ANADIG_ANA_MISC0 0x150
90 #define ANADIG_ANA_MISC0_SET 0x154
91 #define ANADIG_ANA_MISC0_CLK_DELAY(x) ((x >> 26) & 0x7)
94 /* It's called once when probe a usb device */
95 int (*init)(struct imx_usbmisc_data *data);
96 /* It's called once after adding a usb device */
97 int (*post)(struct imx_usbmisc_data *data);
98 /* It's called when we need to enable/disable usb wakeup */
99 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
100 /* It's called when system resume from usb power lost */
101 int (*power_lost_check)(struct imx_usbmisc_data *data);
102 /* It's called before setting portsc.suspendM */
103 int (*hsic_set_connect)(struct imx_usbmisc_data *data);
104 /* It's called during suspend/resume */
105 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
111 const struct usbmisc_ops *ops;
114 static struct regulator *vbus_wakeup_reg;
116 static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
118 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
125 spin_lock_irqsave(&usbmisc->lock, flags);
126 switch (data->index) {
128 val = readl(usbmisc->base);
129 val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT);
130 val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
131 val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT);
132 writel(val, usbmisc->base);
135 val = readl(usbmisc->base);
136 val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT);
137 val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
138 val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT |
139 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT);
141 writel(val, usbmisc->base);
145 spin_unlock_irqrestore(&usbmisc->lock, flags);
150 static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
152 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
161 spin_lock_irqsave(&usbmisc->lock, flags);
162 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET;
164 writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg);
165 spin_unlock_irqrestore(&usbmisc->lock, flags);
166 usleep_range(5000, 10000); /* needed to stabilize voltage */
172 static int usbmisc_imx27_init(struct imx_usbmisc_data *data)
174 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
178 switch (data->index) {
180 val = MX27_OTG_PM_BIT;
183 val = MX27_H1_PM_BIT;
186 val = MX27_H2_PM_BIT;
192 spin_lock_irqsave(&usbmisc->lock, flags);
193 if (data->disable_oc)
194 val = readl(usbmisc->base) | val;
196 val = readl(usbmisc->base) & ~val;
197 writel(val, usbmisc->base);
198 spin_unlock_irqrestore(&usbmisc->lock, flags);
203 static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
205 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
206 void __iomem *reg = NULL;
213 /* Select a 24 MHz reference clock for the PHY */
214 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
215 val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK;
216 val |= MX53_USB_PLL_DIV_24_MHZ;
217 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
219 if (data->disable_oc) {
220 spin_lock_irqsave(&usbmisc->lock, flags);
221 switch (data->index) {
223 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
224 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
227 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
228 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1;
231 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
232 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
235 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
236 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
241 spin_unlock_irqrestore(&usbmisc->lock, flags);
247 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data)
251 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
253 spin_lock_irqsave(&usbmisc->lock, flags);
254 if (data->index == 2 || data->index == 3) {
255 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
256 + (data->index - 2) * 4);
257 if (!(val & MX6_BM_HSIC_DEV_CONN))
258 writel(val | MX6_BM_HSIC_DEV_CONN,
259 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
260 + (data->index - 2) * 4);
262 spin_unlock_irqrestore(&usbmisc->lock, flags);
267 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
271 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
273 spin_lock_irqsave(&usbmisc->lock, flags);
274 if (data->index == 2 || data->index == 3) {
275 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
276 + (data->index - 2) * 4);
277 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
279 val |= MX6_BM_HSIC_CLK_ON;
281 val &= ~MX6_BM_HSIC_CLK_ON;
282 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
283 + (data->index - 2) * 4);
285 spin_unlock_irqrestore(&usbmisc->lock, flags);
290 static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
292 if (data->available_role == USB_DR_MODE_PERIPHERAL)
293 return MX6_BM_VBUS_WAKEUP;
294 else if (data->available_role == USB_DR_MODE_OTG)
295 return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
300 static int usbmisc_imx6q_set_wakeup
301 (struct imx_usbmisc_data *data, bool enabled)
303 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
306 u32 wakeup_setting = MX6_BM_WAKEUP_ENABLE;
312 spin_lock_irqsave(&usbmisc->lock, flags);
313 val = readl(usbmisc->base + data->index * 4);
315 wakeup_setting |= imx6q_finalize_wakeup_setting(data);
316 writel(val | wakeup_setting, usbmisc->base + data->index * 4);
317 spin_unlock_irqrestore(&usbmisc->lock, flags);
319 ret = regulator_enable(vbus_wakeup_reg);
321 if (val & MX6_BM_WAKEUP_INTR)
322 pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
323 wakeup_setting |= MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
324 writel(val & ~wakeup_setting, usbmisc->base + data->index * 4);
325 spin_unlock_irqrestore(&usbmisc->lock, flags);
326 if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
327 regulator_disable(vbus_wakeup_reg);
333 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
335 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
342 spin_lock_irqsave(&usbmisc->lock, flags);
344 if (data->disable_oc) {
345 reg = readl(usbmisc->base + data->index * 4);
346 writel(reg | MX6_BM_OVER_CUR_DIS,
347 usbmisc->base + data->index * 4);
350 /* SoC unburst setting */
351 reg = readl(usbmisc->base + data->index * 4);
352 writel(reg | MX6_BM_UNBURST_SETTING,
353 usbmisc->base + data->index * 4);
355 spin_unlock_irqrestore(&usbmisc->lock, flags);
357 usbmisc_imx6q_set_wakeup(data, false);
362 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
364 void __iomem *reg = NULL;
366 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
370 usbmisc_imx6q_init(data);
372 if (data->index == 0 || data->index == 1) {
373 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4;
374 spin_lock_irqsave(&usbmisc->lock, flags);
375 /* Set vbus wakeup source as bvalid */
377 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg);
379 * Disable dp/dm wakeup in device mode when vbus is
382 val = readl(usbmisc->base + data->index * 4);
383 writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN,
384 usbmisc->base + data->index * 4);
385 spin_unlock_irqrestore(&usbmisc->lock, flags);
388 /* For HSIC controller */
389 if (data->index == 2) {
390 spin_lock_irqsave(&usbmisc->lock, flags);
391 val = readl(usbmisc->base + data->index * 4);
392 writel(val | MX6_BM_UTMI_ON_CLOCK,
393 usbmisc->base + data->index * 4);
394 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
395 + (data->index - 2) * 4);
396 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON |
397 MX6SX_BM_HSIC_AUTO_RESUME;
398 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
399 + (data->index - 2) * 4);
400 spin_unlock_irqrestore(&usbmisc->lock, flags);
403 * Need to add delay to wait 24M OSC to be stable,
404 * it's board specific.
406 regmap_read(data->anatop, ANADIG_ANA_MISC0, &val);
407 /* 0 <= data->osc_clkgate_delay <= 7 */
408 if (data->osc_clkgate_delay > ANADIG_ANA_MISC0_CLK_DELAY(val))
409 regmap_write(data->anatop, ANADIG_ANA_MISC0_SET,
410 (data->osc_clkgate_delay) << 26);
416 static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
418 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
422 * Vybrid only has one misc register set, but in two different
423 * areas. These is reflected in two instances of this driver.
425 if (data->index >= 1)
428 if (data->disable_oc) {
429 reg = readl(usbmisc->base);
430 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base);
436 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data)
438 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
442 spin_lock_irqsave(&usbmisc->lock, flags);
443 val = readl(usbmisc->base + data->index * 4);
444 spin_unlock_irqrestore(&usbmisc->lock, flags);
446 * Here use a power on reset value to judge
447 * if the controller experienced a power lost
449 if (val == 0x30001000)
455 static const struct usbmisc_ops imx25_usbmisc_ops = {
456 .init = usbmisc_imx25_init,
457 .post = usbmisc_imx25_post,
460 static const struct usbmisc_ops imx27_usbmisc_ops = {
461 .init = usbmisc_imx27_init,
464 static const struct usbmisc_ops imx53_usbmisc_ops = {
465 .init = usbmisc_imx53_init,
468 static const struct usbmisc_ops imx6q_usbmisc_ops = {
469 .set_wakeup = usbmisc_imx6q_set_wakeup,
470 .init = usbmisc_imx6q_init,
471 .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
472 .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
475 static const struct usbmisc_ops vf610_usbmisc_ops = {
476 .init = usbmisc_vf610_init,
479 static const struct usbmisc_ops imx6sx_usbmisc_ops = {
480 .set_wakeup = usbmisc_imx6q_set_wakeup,
481 .init = usbmisc_imx6sx_init,
482 .power_lost_check = usbmisc_imx6sx_power_lost_check,
483 .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
484 .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
487 int imx_usbmisc_init(struct imx_usbmisc_data *data)
489 struct imx_usbmisc *usbmisc;
494 usbmisc = dev_get_drvdata(data->dev);
495 if (!usbmisc->ops->init)
497 return usbmisc->ops->init(data);
499 EXPORT_SYMBOL_GPL(imx_usbmisc_init);
501 int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
503 struct imx_usbmisc *usbmisc;
508 usbmisc = dev_get_drvdata(data->dev);
509 if (!usbmisc->ops->post)
511 return usbmisc->ops->post(data);
513 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
515 int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
517 struct imx_usbmisc *usbmisc;
522 usbmisc = dev_get_drvdata(data->dev);
523 if (!usbmisc->ops->set_wakeup)
525 return usbmisc->ops->set_wakeup(data, enabled);
527 EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
529 int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *data)
531 struct imx_usbmisc *usbmisc;
536 usbmisc = dev_get_drvdata(data->dev);
537 if (!usbmisc->ops->power_lost_check)
539 return usbmisc->ops->power_lost_check(data);
541 EXPORT_SYMBOL_GPL(imx_usbmisc_power_lost_check);
543 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
545 struct imx_usbmisc *usbmisc;
550 usbmisc = dev_get_drvdata(data->dev);
551 if (!usbmisc->ops->hsic_set_connect)
553 return usbmisc->ops->hsic_set_connect(data);
555 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
557 int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
559 struct imx_usbmisc *usbmisc;
564 usbmisc = dev_get_drvdata(data->dev);
565 if (!usbmisc->ops->hsic_set_clk)
567 return usbmisc->ops->hsic_set_clk(data, on);
569 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk);
571 static const struct of_device_id usbmisc_imx_dt_ids[] = {
573 .compatible = "fsl,imx25-usbmisc",
574 .data = &imx25_usbmisc_ops,
577 .compatible = "fsl,imx35-usbmisc",
578 .data = &imx25_usbmisc_ops,
581 .compatible = "fsl,imx27-usbmisc",
582 .data = &imx27_usbmisc_ops,
585 .compatible = "fsl,imx51-usbmisc",
586 .data = &imx53_usbmisc_ops,
589 .compatible = "fsl,imx53-usbmisc",
590 .data = &imx53_usbmisc_ops,
593 .compatible = "fsl,imx6q-usbmisc",
594 .data = &imx6q_usbmisc_ops,
597 .compatible = "fsl,vf610-usbmisc",
598 .data = &vf610_usbmisc_ops,
601 .compatible = "fsl,imx6sx-usbmisc",
602 .data = &imx6sx_usbmisc_ops,
606 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
608 static int usbmisc_imx_probe(struct platform_device *pdev)
610 struct resource *res;
611 struct imx_usbmisc *data;
612 struct of_device_id *tmp_dev;
614 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
618 spin_lock_init(&data->lock);
620 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
621 data->base = devm_ioremap_resource(&pdev->dev, res);
622 if (IS_ERR(data->base))
623 return PTR_ERR(data->base);
625 tmp_dev = (struct of_device_id *)
626 of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
627 data->ops = (const struct usbmisc_ops *)tmp_dev->data;
628 platform_set_drvdata(pdev, data);
630 vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
631 if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
632 return -EPROBE_DEFER;
633 else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
634 /* no vbus regualator is needed */
635 vbus_wakeup_reg = NULL;
636 else if (IS_ERR(vbus_wakeup_reg)) {
637 dev_err(&pdev->dev, "Getting regulator error: %ld\n",
638 PTR_ERR(vbus_wakeup_reg));
639 return PTR_ERR(vbus_wakeup_reg);
645 static int usbmisc_imx_remove(struct platform_device *pdev)
650 static struct platform_driver usbmisc_imx_driver = {
651 .probe = usbmisc_imx_probe,
652 .remove = usbmisc_imx_remove,
654 .name = "usbmisc_imx",
655 .owner = THIS_MODULE,
656 .of_match_table = usbmisc_imx_dt_ids,
660 module_platform_driver(usbmisc_imx_driver);
662 MODULE_ALIAS("platform:usbmisc-imx");
663 MODULE_LICENSE("GPL v2");
664 MODULE_DESCRIPTION("driver for imx usb non-core registers");
665 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");