2 * Copyright (c) 2015 Sanchayan Maity <sanchayan.maity@toradex.com>
3 * Copyright (C) 2015 Toradex AG
5 * Based on ehci-mx6 driver
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <linux/compiler.h>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/imx-regs.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/imx-common/iomux-v3.h>
19 #include <asm/imx-common/regs-usbphy.h>
20 #include <usb/ehci-fsl.h>
24 #define USB_NC_REG_OFFSET 0x00000800
26 #define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6)
28 #define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
29 #define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
32 #define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
33 #define UCMD_RESET (1 << 1) /* controller reset */
35 static const unsigned phy_bases
[] = {
40 static const unsigned nc_reg_bases
[] = {
45 static void usb_internal_phy_clock_gate(int index
)
47 void __iomem
*phy_reg
;
49 phy_reg
= (void __iomem
*)phy_bases
[index
];
50 clrbits_le32(phy_reg
+ USBPHY_CTRL
, USBPHY_CTRL_CLKGATE
);
53 static void usb_power_config(int index
)
55 struct anadig_reg __iomem
*anadig
=
56 (struct anadig_reg __iomem
*)ANADIG_BASE_ADDR
;
57 void __iomem
*pll_ctrl
;
61 pll_ctrl
= &anadig
->pll3_ctrl
;
62 clrbits_le32(pll_ctrl
, ANADIG_PLL3_CTRL_BYPASS
);
63 setbits_le32(pll_ctrl
, ANADIG_PLL3_CTRL_ENABLE
64 | ANADIG_PLL3_CTRL_POWERDOWN
65 | ANADIG_PLL_CTRL_EN_USB_CLKS
);
68 pll_ctrl
= &anadig
->pll7_ctrl
;
69 clrbits_le32(pll_ctrl
, ANADIG_PLL7_CTRL_BYPASS
);
70 setbits_le32(pll_ctrl
, ANADIG_PLL7_CTRL_ENABLE
71 | ANADIG_PLL7_CTRL_POWERDOWN
72 | ANADIG_PLL_CTRL_EN_USB_CLKS
);
79 static void usb_phy_enable(int index
, struct usb_ehci
*ehci
)
81 void __iomem
*phy_reg
;
82 void __iomem
*phy_ctrl
;
83 void __iomem
*usb_cmd
;
85 phy_reg
= (void __iomem
*)phy_bases
[index
];
86 phy_ctrl
= (void __iomem
*)(phy_reg
+ USBPHY_CTRL
);
87 usb_cmd
= (void __iomem
*)&ehci
->usbcmd
;
90 clrbits_le32(usb_cmd
, UCMD_RUN_STOP
);
91 while (readl(usb_cmd
) & UCMD_RUN_STOP
)
94 setbits_le32(usb_cmd
, UCMD_RESET
);
95 while (readl(usb_cmd
) & UCMD_RESET
)
98 /* Reset USBPHY module */
99 setbits_le32(phy_ctrl
, USBPHY_CTRL_SFTRST
);
102 /* Remove CLKGATE and SFTRST */
103 clrbits_le32(phy_ctrl
, USBPHY_CTRL_CLKGATE
| USBPHY_CTRL_SFTRST
);
106 /* Power up the PHY */
107 writel(0, phy_reg
+ USBPHY_PWD
);
109 /* Enable FS/LS device */
110 setbits_le32(phy_ctrl
, USBPHY_CTRL_ENUTMILEVEL2
|
111 USBPHY_CTRL_ENUTMILEVEL3
);
114 static void usb_oc_config(int index
)
118 ctrl
= (void __iomem
*)(nc_reg_bases
[index
] + USB_NC_REG_OFFSET
);
120 setbits_le32(ctrl
, UCTRL_OVER_CUR_POL
);
121 setbits_le32(ctrl
, UCTRL_OVER_CUR_DIS
);
124 int __weak
board_usb_phy_mode(int port
)
129 int __weak
board_ehci_hcd_init(int port
)
134 int ehci_hcd_init(int index
, enum usb_init_type init
,
135 struct ehci_hccr
**hccr
, struct ehci_hcor
**hcor
)
137 struct usb_ehci
*ehci
;
138 enum usb_init_type type
;
140 if (index
>= ARRAY_SIZE(nc_reg_bases
))
143 ehci
= (struct usb_ehci
*)nc_reg_bases
[index
];
145 /* Do board specific initialisation */
146 board_ehci_hcd_init(index
);
148 usb_power_config(index
);
149 usb_oc_config(index
);
150 usb_internal_phy_clock_gate(index
);
151 usb_phy_enable(index
, ehci
);
153 *hccr
= (struct ehci_hccr
*)((uint32_t)&ehci
->caplength
);
154 *hcor
= (struct ehci_hcor
*)((uint32_t)*hccr
+
155 HC_LENGTH(ehci_readl(&(*hccr
)->cr_capbase
)));
157 type
= board_usb_phy_mode(index
);
161 if (init
== USB_INIT_DEVICE
) {
162 setbits_le32(&ehci
->usbmode
, CM_DEVICE
);
163 writel((PORT_PTS_UTMI
| PORT_PTS_PTW
), &ehci
->portsc
);
164 setbits_le32(&ehci
->portsc
, USB_EN
);
165 } else if (init
== USB_INIT_HOST
) {
166 setbits_le32(&ehci
->usbmode
, CM_HOST
);
167 writel((PORT_PTS_UTMI
| PORT_PTS_PTW
), &ehci
->portsc
);
168 setbits_le32(&ehci
->portsc
, USB_EN
);
174 int ehci_hcd_stop(int index
)