xref: /linux/drivers/usb/chipidea/usbmisc_imx.c (revision 11992b41008328af0e6a01e13d08b48d6233624e)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Freescale Semiconductor, Inc.
4  */
5 
6 #include <linux/module.h>
7 #include <linux/of.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/delay.h>
11 #include <linux/platform_device.h>
12 #include <linux/usb/otg.h>
13 
14 #include "ci_hdrc_imx.h"
15 
16 #define MX25_USB_PHY_CTRL_OFFSET	0x08
17 #define MX25_BM_EXTERNAL_VBUS_DIVIDER	BIT(23)
18 
19 #define MX25_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
20 #define MX25_EHCI_INTERFACE_DIFF_UNI	(0 << 0)
21 #define MX25_EHCI_INTERFACE_MASK	(0xf)
22 
23 #define MX25_OTG_SIC_SHIFT		29
24 #define MX25_OTG_SIC_MASK		(0x3 << MX25_OTG_SIC_SHIFT)
25 #define MX25_OTG_PM_BIT			BIT(24)
26 #define MX25_OTG_PP_BIT			BIT(11)
27 #define MX25_OTG_OCPOL_BIT		BIT(3)
28 
29 #define MX25_H1_SIC_SHIFT		21
30 #define MX25_H1_SIC_MASK		(0x3 << MX25_H1_SIC_SHIFT)
31 #define MX25_H1_PP_BIT			BIT(18)
32 #define MX25_H1_PM_BIT			BIT(16)
33 #define MX25_H1_IPPUE_UP_BIT		BIT(7)
34 #define MX25_H1_IPPUE_DOWN_BIT		BIT(6)
35 #define MX25_H1_TLL_BIT			BIT(5)
36 #define MX25_H1_USBTE_BIT		BIT(4)
37 #define MX25_H1_OCPOL_BIT		BIT(2)
38 
39 #define MX27_H1_PM_BIT			BIT(8)
40 #define MX27_H2_PM_BIT			BIT(16)
41 #define MX27_OTG_PM_BIT			BIT(24)
42 
43 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET	0x08
44 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET	0x0c
45 #define MX53_USB_CTRL_1_OFFSET	        0x10
46 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2)
47 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2)
48 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6)
49 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6)
50 #define MX53_USB_UH2_CTRL_OFFSET	0x14
51 #define MX53_USB_UH3_CTRL_OFFSET	0x18
52 #define MX53_USB_CLKONOFF_CTRL_OFFSET	0x24
53 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21)
54 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22)
55 #define MX53_BM_OVER_CUR_DIS_H1		BIT(5)
56 #define MX53_BM_OVER_CUR_DIS_OTG	BIT(8)
57 #define MX53_BM_OVER_CUR_DIS_UHx	BIT(30)
58 #define MX53_USB_CTRL_1_UH2_ULPI_EN	BIT(26)
59 #define MX53_USB_CTRL_1_UH3_ULPI_EN	BIT(27)
60 #define MX53_USB_UHx_CTRL_WAKE_UP_EN	BIT(7)
61 #define MX53_USB_UHx_CTRL_ULPI_INT_EN	BIT(8)
62 #define MX53_USB_PHYCTRL1_PLLDIV_MASK	0x3
63 #define MX53_USB_PLL_DIV_24_MHZ		0x01
64 
65 #define MX6_BM_NON_BURST_SETTING	BIT(1)
66 #define MX6_BM_OVER_CUR_DIS		BIT(7)
67 #define MX6_BM_OVER_CUR_POLARITY	BIT(8)
68 #define MX6_BM_PWR_POLARITY		BIT(9)
69 #define MX6_BM_WAKEUP_ENABLE		BIT(10)
70 #define MX6_BM_UTMI_ON_CLOCK		BIT(13)
71 #define MX6_BM_ID_WAKEUP		BIT(16)
72 #define MX6_BM_VBUS_WAKEUP		BIT(17)
73 #define MX6SX_BM_DPDM_WAKEUP_EN		BIT(29)
74 #define MX6_BM_WAKEUP_INTR		BIT(31)
75 
76 #define MX6_USB_HSIC_CTRL_OFFSET	0x10
77 /* Send resume signal without 480Mhz PHY clock */
78 #define MX6SX_BM_HSIC_AUTO_RESUME	BIT(23)
79 /* set before portsc.suspendM = 1 */
80 #define MX6_BM_HSIC_DEV_CONN		BIT(21)
81 /* HSIC enable */
82 #define MX6_BM_HSIC_EN			BIT(12)
83 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */
84 #define MX6_BM_HSIC_CLK_ON		BIT(11)
85 
86 #define MX6_USB_OTG1_PHY_CTRL		0x18
87 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */
88 #define MX6_USB_OTG2_PHY_CTRL		0x1c
89 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v)	(v << 8)
90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS	MX6SX_USB_VBUS_WAKEUP_SOURCE(0)
91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID	MX6SX_USB_VBUS_WAKEUP_SOURCE(1)
92 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID	MX6SX_USB_VBUS_WAKEUP_SOURCE(2)
93 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX6SX_USB_VBUS_WAKEUP_SOURCE(3)
94 
95 #define VF610_OVER_CUR_DIS		BIT(7)
96 
97 #define MX7D_USBNC_USB_CTRL2		0x4
98 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK	0x3
99 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v)		(v << 0)
100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS	MX7D_USB_VBUS_WAKEUP_SOURCE(0)
101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(1)
102 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(2)
103 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX7D_USB_VBUS_WAKEUP_SOURCE(3)
104 #define MX7D_USBNC_AUTO_RESUME				BIT(2)
105 /* The default DM/DP value is pull-down */
106 #define MX7D_USBNC_USB_CTRL2_OPMODE(v)			(v << 6)
107 #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING	MX7D_USBNC_USB_CTRL2_OPMODE(1)
108 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK	(BIT(7) | BIT(6))
109 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN		BIT(8)
110 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL		BIT(12)
111 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN		BIT(13)
112 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL		BIT(14)
113 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN		BIT(15)
114 #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK			(BIT(12) | BIT(13) | \
115 							BIT(14) | BIT(15))
116 
117 #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL	BIT(0)
118 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0	BIT(1)
119 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0	BIT(2)
120 #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB	BIT(3)
121 #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0		BIT(16)
122 
123 #define MX7D_USB_OTG_PHY_CFG2		0x34
124 
125 #define MX7D_USB_OTG_PHY_STATUS		0x3c
126 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0	BIT(0)
127 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1	BIT(1)
128 #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD	BIT(3)
129 #define MX7D_USB_OTG_PHY_STATUS_CHRGDET		BIT(29)
130 
131 #define MX7D_USB_OTG_PHY_CFG1		0x30
132 #define TXPREEMPAMPTUNE0_BIT		28
133 #define TXPREEMPAMPTUNE0_MASK		(3 << 28)
134 #define TXRISETUNE0_BIT			24
135 #define TXRISETUNE0_MASK		(3 << 24)
136 #define TXVREFTUNE0_BIT			20
137 #define TXVREFTUNE0_MASK		(0xf << 20)
138 
139 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
140 				 MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
141 
142 /*
143  * HSIO Block Control Register
144  */
145 
146 #define BLKCTL_USB_WAKEUP_CTRL		0x0
147 #define BLKCTL_OTG_WAKE_ENABLE		BIT(31)
148 #define BLKCTL_OTG_VBUS_SESSVALID	BIT(4)
149 #define BLKCTL_OTG_ID_WAKEUP_EN		BIT(2)
150 #define BLKCTL_OTG_VBUS_WAKEUP_EN	BIT(1)
151 #define BLKCTL_OTG_DPDM_WAKEUP_EN	BIT(0)
152 
153 #define BLKCTL_WAKEUP_SOURCE		(BLKCTL_OTG_WAKE_ENABLE	   | \
154 					 BLKCTL_OTG_ID_WAKEUP_EN   | \
155 					 BLKCTL_OTG_VBUS_WAKEUP_EN | \
156 					 BLKCTL_OTG_DPDM_WAKEUP_EN)
157 
158 struct usbmisc_ops {
159 	/* It's called once when probe a usb device */
160 	int (*init)(struct imx_usbmisc_data *data);
161 	/* It's called once after adding a usb device */
162 	int (*post)(struct imx_usbmisc_data *data);
163 	/* It's called when we need to enable/disable usb wakeup */
164 	int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
165 	/* It's called before setting portsc.suspendM */
166 	int (*hsic_set_connect)(struct imx_usbmisc_data *data);
167 	/* It's called during suspend/resume */
168 	int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
169 	/* usb charger detection */
170 	int (*charger_detection)(struct imx_usbmisc_data *data);
171 	/* It's called when system resume from usb power lost */
172 	int (*power_lost_check)(struct imx_usbmisc_data *data);
173 	/* It's called when device controller changed pullup status */
174 	void (*pullup)(struct imx_usbmisc_data *data, bool on);
175 	/* It's called during suspend/resume to save power */
176 	void (*vbus_comparator_on)(struct imx_usbmisc_data *data, bool on);
177 };
178 
179 struct imx_usbmisc {
180 	void __iomem *base;
181 	void __iomem *blkctl;
182 	spinlock_t lock;
183 	const struct usbmisc_ops *ops;
184 };
185 
186 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data);
187 
188 static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
189 {
190 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
191 	unsigned long flags;
192 	u32 val = 0;
193 
194 	if (data->index > 1)
195 		return -EINVAL;
196 
197 	spin_lock_irqsave(&usbmisc->lock, flags);
198 	switch (data->index) {
199 	case 0:
200 		val = readl(usbmisc->base);
201 		val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT);
202 		val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
203 		val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT);
204 
205 		/*
206 		 * If the polarity is not configured assume active high for
207 		 * historical reasons.
208 		 */
209 		if (data->oc_pol_configured && data->oc_pol_active_low)
210 			val &= ~MX25_OTG_OCPOL_BIT;
211 
212 		writel(val, usbmisc->base);
213 		break;
214 	case 1:
215 		val = readl(usbmisc->base);
216 		val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT |  MX25_H1_IPPUE_UP_BIT);
217 		val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
218 		val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT |
219 			MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT);
220 
221 		/*
222 		 * If the polarity is not configured assume active high for
223 		 * historical reasons.
224 		 */
225 		if (data->oc_pol_configured && data->oc_pol_active_low)
226 			val &= ~MX25_H1_OCPOL_BIT;
227 
228 		writel(val, usbmisc->base);
229 
230 		break;
231 	}
232 	spin_unlock_irqrestore(&usbmisc->lock, flags);
233 
234 	return 0;
235 }
236 
237 static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
238 {
239 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
240 	void __iomem *reg;
241 	unsigned long flags;
242 	u32 val;
243 
244 	if (data->index > 2)
245 		return -EINVAL;
246 
247 	if (data->index)
248 		return 0;
249 
250 	spin_lock_irqsave(&usbmisc->lock, flags);
251 	reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET;
252 	val = readl(reg);
253 
254 	if (data->evdo)
255 		val |= MX25_BM_EXTERNAL_VBUS_DIVIDER;
256 	else
257 		val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER;
258 
259 	writel(val, reg);
260 	spin_unlock_irqrestore(&usbmisc->lock, flags);
261 	usleep_range(5000, 10000); /* needed to stabilize voltage */
262 
263 	return 0;
264 }
265 
266 static int usbmisc_imx27_init(struct imx_usbmisc_data *data)
267 {
268 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
269 	unsigned long flags;
270 	u32 val;
271 
272 	switch (data->index) {
273 	case 0:
274 		val = MX27_OTG_PM_BIT;
275 		break;
276 	case 1:
277 		val = MX27_H1_PM_BIT;
278 		break;
279 	case 2:
280 		val = MX27_H2_PM_BIT;
281 		break;
282 	default:
283 		return -EINVAL;
284 	}
285 
286 	spin_lock_irqsave(&usbmisc->lock, flags);
287 	if (data->disable_oc)
288 		val = readl(usbmisc->base) | val;
289 	else
290 		val = readl(usbmisc->base) & ~val;
291 	writel(val, usbmisc->base);
292 	spin_unlock_irqrestore(&usbmisc->lock, flags);
293 
294 	return 0;
295 }
296 
297 static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
298 {
299 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
300 	void __iomem *reg = NULL;
301 	unsigned long flags;
302 	u32 val = 0;
303 
304 	if (data->index > 3)
305 		return -EINVAL;
306 
307 	/* Select a 24 MHz reference clock for the PHY  */
308 	val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
309 	val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK;
310 	val |= MX53_USB_PLL_DIV_24_MHZ;
311 	writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);
312 
313 	spin_lock_irqsave(&usbmisc->lock, flags);
314 
315 	switch (data->index) {
316 	case 0:
317 		if (data->disable_oc) {
318 			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
319 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
320 			writel(val, reg);
321 		}
322 		break;
323 	case 1:
324 		if (data->disable_oc) {
325 			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
326 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1;
327 			writel(val, reg);
328 		}
329 		break;
330 	case 2:
331 		if (data->ulpi) {
332 			/* set USBH2 into ULPI-mode. */
333 			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
334 			val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN;
335 			/* select ULPI clock */
336 			val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK;
337 			val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI;
338 			writel(val, reg);
339 			/* Set interrupt wake up enable */
340 			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
341 			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
342 				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
343 			writel(val, reg);
344 			if (is_imx53_usbmisc(data)) {
345 				/* Disable internal 60Mhz clock */
346 				reg = usbmisc->base +
347 					MX53_USB_CLKONOFF_CTRL_OFFSET;
348 				val = readl(reg) |
349 					MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF;
350 				writel(val, reg);
351 			}
352 
353 		}
354 		if (data->disable_oc) {
355 			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
356 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
357 			writel(val, reg);
358 		}
359 		break;
360 	case 3:
361 		if (data->ulpi) {
362 			/* set USBH3 into ULPI-mode. */
363 			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
364 			val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN;
365 			/* select ULPI clock */
366 			val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK;
367 			val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI;
368 			writel(val, reg);
369 			/* Set interrupt wake up enable */
370 			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
371 			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
372 				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
373 			writel(val, reg);
374 
375 			if (is_imx53_usbmisc(data)) {
376 				/* Disable internal 60Mhz clock */
377 				reg = usbmisc->base +
378 					MX53_USB_CLKONOFF_CTRL_OFFSET;
379 				val = readl(reg) |
380 					MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF;
381 				writel(val, reg);
382 			}
383 		}
384 		if (data->disable_oc) {
385 			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
386 			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
387 			writel(val, reg);
388 		}
389 		break;
390 	}
391 
392 	spin_unlock_irqrestore(&usbmisc->lock, flags);
393 
394 	return 0;
395 }
396 
397 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data)
398 {
399 	u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS;
400 
401 	if (data->ext_id || data->available_role != USB_DR_MODE_OTG)
402 		wakeup_setting &= ~MX6_BM_ID_WAKEUP;
403 
404 	if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST)
405 		wakeup_setting &= ~MX6_BM_VBUS_WAKEUP;
406 
407 	return wakeup_setting;
408 }
409 
410 static int usbmisc_imx6q_set_wakeup
411 	(struct imx_usbmisc_data *data, bool enabled)
412 {
413 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
414 	unsigned long flags;
415 	u32 val;
416 	int ret = 0;
417 
418 	if (data->index > 3)
419 		return -EINVAL;
420 
421 	spin_lock_irqsave(&usbmisc->lock, flags);
422 	val = readl(usbmisc->base + data->index * 4);
423 	if (enabled) {
424 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
425 		val |= usbmisc_wakeup_setting(data);
426 	} else {
427 		if (val & MX6_BM_WAKEUP_INTR)
428 			pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
429 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
430 	}
431 	writel(val, usbmisc->base + data->index * 4);
432 	spin_unlock_irqrestore(&usbmisc->lock, flags);
433 
434 	return ret;
435 }
436 
437 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
438 {
439 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
440 	unsigned long flags;
441 	u32 reg;
442 
443 	if (data->index > 3)
444 		return -EINVAL;
445 
446 	spin_lock_irqsave(&usbmisc->lock, flags);
447 
448 	reg = readl(usbmisc->base + data->index * 4);
449 	if (data->disable_oc) {
450 		reg |= MX6_BM_OVER_CUR_DIS;
451 	} else {
452 		reg &= ~MX6_BM_OVER_CUR_DIS;
453 
454 		/*
455 		 * If the polarity is not configured keep it as setup by the
456 		 * bootloader.
457 		 */
458 		if (data->oc_pol_configured && data->oc_pol_active_low)
459 			reg |= MX6_BM_OVER_CUR_POLARITY;
460 		else if (data->oc_pol_configured)
461 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
462 	}
463 	/* If the polarity is not set keep it as setup by the bootloader */
464 	if (data->pwr_pol == 1)
465 		reg |= MX6_BM_PWR_POLARITY;
466 	writel(reg, usbmisc->base + data->index * 4);
467 
468 	/* SoC non-burst setting */
469 	reg = readl(usbmisc->base + data->index * 4);
470 	writel(reg | MX6_BM_NON_BURST_SETTING,
471 			usbmisc->base + data->index * 4);
472 
473 	/* For HSIC controller */
474 	if (data->hsic) {
475 		reg = readl(usbmisc->base + data->index * 4);
476 		writel(reg | MX6_BM_UTMI_ON_CLOCK,
477 			usbmisc->base + data->index * 4);
478 		reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
479 			+ (data->index - 2) * 4);
480 		reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
481 		writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
482 			+ (data->index - 2) * 4);
483 	}
484 
485 	spin_unlock_irqrestore(&usbmisc->lock, flags);
486 
487 	usbmisc_imx6q_set_wakeup(data, false);
488 
489 	return 0;
490 }
491 
492 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data)
493 {
494 	int offset, ret = 0;
495 
496 	if (data->index == 2 || data->index == 3) {
497 		offset = (data->index - 2) * 4;
498 	} else if (data->index == 0) {
499 		/*
500 		 * For SoCs like i.MX7D and later, each USB controller has
501 		 * its own non-core register region. For SoCs before i.MX7D,
502 		 * the first two USB controllers are non-HSIC controllers.
503 		 */
504 		offset = 0;
505 	} else {
506 		dev_err(data->dev, "index is error for usbmisc\n");
507 		ret = -EINVAL;
508 	}
509 
510 	return ret ? ret : offset;
511 }
512 
513 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data)
514 {
515 	unsigned long flags;
516 	u32 val;
517 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
518 	int offset;
519 
520 	spin_lock_irqsave(&usbmisc->lock, flags);
521 	offset = usbmisc_imx6_hsic_get_reg_offset(data);
522 	if (offset < 0) {
523 		spin_unlock_irqrestore(&usbmisc->lock, flags);
524 		return offset;
525 	}
526 
527 	val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
528 	if (!(val & MX6_BM_HSIC_DEV_CONN))
529 		writel(val | MX6_BM_HSIC_DEV_CONN,
530 			usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
531 
532 	spin_unlock_irqrestore(&usbmisc->lock, flags);
533 
534 	return 0;
535 }
536 
537 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
538 {
539 	unsigned long flags;
540 	u32 val;
541 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
542 	int offset;
543 
544 	spin_lock_irqsave(&usbmisc->lock, flags);
545 	offset = usbmisc_imx6_hsic_get_reg_offset(data);
546 	if (offset < 0) {
547 		spin_unlock_irqrestore(&usbmisc->lock, flags);
548 		return offset;
549 	}
550 
551 	val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
552 	val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
553 	if (on)
554 		val |= MX6_BM_HSIC_CLK_ON;
555 	else
556 		val &= ~MX6_BM_HSIC_CLK_ON;
557 
558 	writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset);
559 	spin_unlock_irqrestore(&usbmisc->lock, flags);
560 
561 	return 0;
562 }
563 
564 
565 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
566 {
567 	void __iomem *reg = NULL;
568 	unsigned long flags;
569 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
570 	u32 val;
571 
572 	usbmisc_imx6q_init(data);
573 
574 	if (data->index == 0 || data->index == 1) {
575 		reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4;
576 		spin_lock_irqsave(&usbmisc->lock, flags);
577 		/* Set vbus wakeup source as bvalid */
578 		val = readl(reg);
579 		writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg);
580 		/*
581 		 * Disable dp/dm wakeup in device mode when vbus is
582 		 * not there.
583 		 */
584 		val = readl(usbmisc->base + data->index * 4);
585 		writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN,
586 			usbmisc->base + data->index * 4);
587 		spin_unlock_irqrestore(&usbmisc->lock, flags);
588 	}
589 
590 	/* For HSIC controller */
591 	if (data->hsic) {
592 		val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
593 		val |= MX6SX_BM_HSIC_AUTO_RESUME;
594 		writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
595 	}
596 
597 	return 0;
598 }
599 
600 static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
601 {
602 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
603 	u32 reg;
604 
605 	/*
606 	 * Vybrid only has one misc register set, but in two different
607 	 * areas. These is reflected in two instances of this driver.
608 	 */
609 	if (data->index >= 1)
610 		return -EINVAL;
611 
612 	if (data->disable_oc) {
613 		reg = readl(usbmisc->base);
614 		writel(reg | VF610_OVER_CUR_DIS, usbmisc->base);
615 	}
616 
617 	return 0;
618 }
619 
620 static int usbmisc_imx7d_set_wakeup
621 	(struct imx_usbmisc_data *data, bool enabled)
622 {
623 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
624 	unsigned long flags;
625 	u32 val;
626 
627 	spin_lock_irqsave(&usbmisc->lock, flags);
628 	val = readl(usbmisc->base);
629 	if (enabled) {
630 		val &= ~MX6_USB_OTG_WAKEUP_BITS;
631 		val |= usbmisc_wakeup_setting(data);
632 		writel(val, usbmisc->base);
633 	} else {
634 		if (val & MX6_BM_WAKEUP_INTR)
635 			dev_dbg(data->dev, "wakeup int\n");
636 		writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base);
637 	}
638 	spin_unlock_irqrestore(&usbmisc->lock, flags);
639 
640 	return 0;
641 }
642 
643 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
644 {
645 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
646 	unsigned long flags;
647 	u32 reg;
648 
649 	if (data->index >= 1)
650 		return -EINVAL;
651 
652 	spin_lock_irqsave(&usbmisc->lock, flags);
653 	reg = readl(usbmisc->base);
654 	if (data->disable_oc) {
655 		reg |= MX6_BM_OVER_CUR_DIS;
656 	} else {
657 		reg &= ~MX6_BM_OVER_CUR_DIS;
658 
659 		/*
660 		 * If the polarity is not configured keep it as setup by the
661 		 * bootloader.
662 		 */
663 		if (data->oc_pol_configured && data->oc_pol_active_low)
664 			reg |= MX6_BM_OVER_CUR_POLARITY;
665 		else if (data->oc_pol_configured)
666 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
667 	}
668 	/* If the polarity is not set keep it as setup by the bootloader */
669 	if (data->pwr_pol == 1)
670 		reg |= MX6_BM_PWR_POLARITY;
671 	writel(reg, usbmisc->base);
672 
673 	/* SoC non-burst setting */
674 	reg = readl(usbmisc->base);
675 	writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
676 
677 	if (!data->hsic) {
678 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
679 		reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
680 		writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID
681 			| MX7D_USBNC_AUTO_RESUME,
682 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
683 		/* PHY tuning for signal quality */
684 		reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
685 		if (data->emp_curr_control >= 0 &&
686 			data->emp_curr_control <=
687 			(TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) {
688 			reg &= ~TXPREEMPAMPTUNE0_MASK;
689 			reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT);
690 		}
691 
692 		if (data->dc_vol_level_adjust >= 0 &&
693 			data->dc_vol_level_adjust <=
694 			(TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) {
695 			reg &= ~TXVREFTUNE0_MASK;
696 			reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT);
697 		}
698 
699 		if (data->rise_fall_time_adjust >= 0 &&
700 			data->rise_fall_time_adjust <=
701 			(TXRISETUNE0_MASK >> TXRISETUNE0_BIT)) {
702 			reg &= ~TXRISETUNE0_MASK;
703 			reg |= (data->rise_fall_time_adjust << TXRISETUNE0_BIT);
704 		}
705 
706 		writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1);
707 	}
708 
709 	spin_unlock_irqrestore(&usbmisc->lock, flags);
710 
711 	usbmisc_imx7d_set_wakeup(data, false);
712 
713 	return 0;
714 }
715 
716 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data)
717 {
718 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
719 	struct usb_phy *usb_phy = data->usb_phy;
720 	int val;
721 	unsigned long flags;
722 
723 	/* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */
724 	spin_lock_irqsave(&usbmisc->lock, flags);
725 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
726 	val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0;
727 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
728 	spin_unlock_irqrestore(&usbmisc->lock, flags);
729 
730 	/* TVDMSRC_DIS */
731 	msleep(20);
732 
733 	/* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */
734 	spin_lock_irqsave(&usbmisc->lock, flags);
735 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
736 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
737 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 |
738 			MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL,
739 				usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
740 	spin_unlock_irqrestore(&usbmisc->lock, flags);
741 
742 	/* TVDMSRC_ON */
743 	msleep(40);
744 
745 	/*
746 	 * Per BC 1.2, check voltage of D+:
747 	 * DCP: if greater than VDAT_REF;
748 	 * CDP: if less than VDAT_REF.
749 	 */
750 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
751 	if (val & MX7D_USB_OTG_PHY_STATUS_CHRGDET) {
752 		dev_dbg(data->dev, "It is a dedicate charging port\n");
753 		usb_phy->chg_type = DCP_TYPE;
754 	} else {
755 		dev_dbg(data->dev, "It is a charging downstream port\n");
756 		usb_phy->chg_type = CDP_TYPE;
757 	}
758 
759 	return 0;
760 }
761 
762 static void imx7_disable_charger_detector(struct imx_usbmisc_data *data)
763 {
764 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
765 	unsigned long flags;
766 	u32 val;
767 
768 	spin_lock_irqsave(&usbmisc->lock, flags);
769 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
770 	val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB |
771 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
772 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 |
773 			MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL);
774 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
775 
776 	/* Set OPMODE to be 2'b00 and disable its override */
777 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
778 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
779 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
780 
781 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
782 	writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
783 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
784 	spin_unlock_irqrestore(&usbmisc->lock, flags);
785 }
786 
787 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data)
788 {
789 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
790 	unsigned long flags;
791 	u32 val;
792 	int i, data_pin_contact_count = 0;
793 
794 	/* Enable Data Contact Detect (DCD) per the USB BC 1.2 */
795 	spin_lock_irqsave(&usbmisc->lock, flags);
796 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
797 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB,
798 			usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
799 	spin_unlock_irqrestore(&usbmisc->lock, flags);
800 
801 	for (i = 0; i < 100; i = i + 1) {
802 		val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
803 		if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) {
804 			if (data_pin_contact_count++ > 5)
805 				/* Data pin makes contact */
806 				break;
807 			usleep_range(5000, 10000);
808 		} else {
809 			data_pin_contact_count = 0;
810 			usleep_range(5000, 6000);
811 		}
812 	}
813 
814 	/* Disable DCD after finished data contact check */
815 	spin_lock_irqsave(&usbmisc->lock, flags);
816 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
817 	writel(val & ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB,
818 			usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
819 	spin_unlock_irqrestore(&usbmisc->lock, flags);
820 
821 	if (i == 100) {
822 		dev_err(data->dev,
823 			"VBUS is coming from a dedicated power supply.\n");
824 		return -ENXIO;
825 	}
826 
827 	return 0;
828 }
829 
830 static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data)
831 {
832 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
833 	struct usb_phy *usb_phy = data->usb_phy;
834 	unsigned long flags;
835 	u32 val;
836 
837 	/* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */
838 	spin_lock_irqsave(&usbmisc->lock, flags);
839 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
840 	val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL;
841 	writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 |
842 			MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0,
843 				usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
844 	spin_unlock_irqrestore(&usbmisc->lock, flags);
845 
846 	/* TVDPSRC_ON */
847 	msleep(40);
848 
849 	/* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */
850 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
851 	if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) {
852 		dev_dbg(data->dev, "It is a standard downstream port\n");
853 		usb_phy->chg_type = SDP_TYPE;
854 	}
855 
856 	return 0;
857 }
858 
859 /*
860  * Whole charger detection process:
861  * 1. OPMODE override to be non-driving
862  * 2. Data contact check
863  * 3. Primary detection
864  * 4. Secondary detection
865  * 5. Disable charger detection
866  */
867 static int imx7d_charger_detection(struct imx_usbmisc_data *data)
868 {
869 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
870 	struct usb_phy *usb_phy = data->usb_phy;
871 	unsigned long flags;
872 	u32 val;
873 	int ret;
874 
875 	/* Check if vbus is valid */
876 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS);
877 	if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) {
878 		dev_err(data->dev, "vbus is error\n");
879 		return -EINVAL;
880 	}
881 
882 	/*
883 	 * Keep OPMODE to be non-driving mode during the whole
884 	 * charger detection process.
885 	 */
886 	spin_lock_irqsave(&usbmisc->lock, flags);
887 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
888 	val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
889 	val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING;
890 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
891 
892 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
893 	writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN,
894 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
895 	spin_unlock_irqrestore(&usbmisc->lock, flags);
896 
897 	ret = imx7d_charger_data_contact_detect(data);
898 	if (ret)
899 		return ret;
900 
901 	ret = imx7d_charger_primary_detection(data);
902 	if (!ret && usb_phy->chg_type != SDP_TYPE)
903 		ret = imx7d_charger_secondary_detection(data);
904 
905 	imx7_disable_charger_detector(data);
906 
907 	return ret;
908 }
909 
910 static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data *data,
911 					     bool on)
912 {
913 	unsigned long flags;
914 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
915 	u32 val;
916 
917 	if (data->hsic)
918 		return;
919 
920 	spin_lock_irqsave(&usbmisc->lock, flags);
921 	/*
922 	 * Disable VBUS valid comparator when in suspend mode,
923 	 * when OTG is disabled and DRVVBUS0 is asserted case
924 	 * the Bandgap circuitry and VBUS Valid comparator are
925 	 * still powered, even in Suspend or Sleep mode.
926 	 */
927 	val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
928 	if (on)
929 		val |= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0;
930 	else
931 		val &= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0;
932 
933 	writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2);
934 	spin_unlock_irqrestore(&usbmisc->lock, flags);
935 }
936 
937 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data)
938 {
939 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
940 	unsigned long flags;
941 	u32 reg;
942 
943 	if (data->index >= 1)
944 		return -EINVAL;
945 
946 	spin_lock_irqsave(&usbmisc->lock, flags);
947 	reg = readl(usbmisc->base);
948 	if (data->disable_oc) {
949 		reg |= MX6_BM_OVER_CUR_DIS;
950 	} else {
951 		reg &= ~MX6_BM_OVER_CUR_DIS;
952 
953 		/*
954 		 * If the polarity is not configured keep it as setup by the
955 		 * bootloader.
956 		 */
957 		if (data->oc_pol_configured && data->oc_pol_active_low)
958 			reg |= MX6_BM_OVER_CUR_POLARITY;
959 		else if (data->oc_pol_configured)
960 			reg &= ~MX6_BM_OVER_CUR_POLARITY;
961 	}
962 	/* If the polarity is not set keep it as setup by the bootloader */
963 	if (data->pwr_pol == 1)
964 		reg |= MX6_BM_PWR_POLARITY;
965 
966 	writel(reg, usbmisc->base);
967 
968 	/* SoC non-burst setting */
969 	reg = readl(usbmisc->base);
970 	writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base);
971 
972 	if (data->hsic) {
973 		reg = readl(usbmisc->base);
974 		writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base);
975 
976 		reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
977 		reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
978 		writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET);
979 
980 		/*
981 		 * For non-HSIC controller, the autoresume is enabled
982 		 * at MXS PHY driver (usbphy_ctrl bit18).
983 		 */
984 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
985 		writel(reg | MX7D_USBNC_AUTO_RESUME,
986 			usbmisc->base + MX7D_USBNC_USB_CTRL2);
987 	} else {
988 		reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
989 		reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
990 		writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
991 			 usbmisc->base + MX7D_USBNC_USB_CTRL2);
992 	}
993 
994 	spin_unlock_irqrestore(&usbmisc->lock, flags);
995 
996 	usbmisc_imx7d_set_wakeup(data, false);
997 
998 	return 0;
999 }
1000 
1001 static void usbmisc_imx7d_pullup(struct imx_usbmisc_data *data, bool on)
1002 {
1003 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1004 	unsigned long flags;
1005 	u32 val;
1006 
1007 	spin_lock_irqsave(&usbmisc->lock, flags);
1008 	val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
1009 	if (!on) {
1010 		val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK;
1011 		val |= MX7D_USBNC_USB_CTRL2_OPMODE(1);
1012 		val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
1013 	} else {
1014 		val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN;
1015 	}
1016 	writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2);
1017 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1018 }
1019 
1020 static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data)
1021 {
1022 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1023 	unsigned long flags;
1024 	u32 val;
1025 
1026 	spin_lock_irqsave(&usbmisc->lock, flags);
1027 	val = readl(usbmisc->base);
1028 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1029 	/*
1030 	 * Here use a power on reset value to judge
1031 	 * if the controller experienced a power lost
1032 	 */
1033 	if (val == 0x30001000)
1034 		return 1;
1035 	else
1036 		return 0;
1037 }
1038 
1039 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data)
1040 {
1041 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1042 	unsigned long flags;
1043 	u32 val;
1044 
1045 	spin_lock_irqsave(&usbmisc->lock, flags);
1046 	val = readl(usbmisc->base + data->index * 4);
1047 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1048 	/*
1049 	 * Here use a power on reset value to judge
1050 	 * if the controller experienced a power lost
1051 	 */
1052 	if (val == 0x30001000)
1053 		return 1;
1054 	else
1055 		return 0;
1056 }
1057 
1058 static u32 usbmisc_blkctl_wakeup_setting(struct imx_usbmisc_data *data)
1059 {
1060 	u32 wakeup_setting = BLKCTL_WAKEUP_SOURCE;
1061 
1062 	if (data->ext_id || data->available_role != USB_DR_MODE_OTG)
1063 		wakeup_setting &= ~BLKCTL_OTG_ID_WAKEUP_EN;
1064 
1065 	if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST)
1066 		wakeup_setting &= ~BLKCTL_OTG_VBUS_WAKEUP_EN;
1067 
1068 	/* Select session valid as VBUS wakeup source */
1069 	wakeup_setting |= BLKCTL_OTG_VBUS_SESSVALID;
1070 
1071 	return wakeup_setting;
1072 }
1073 
1074 static int usbmisc_imx95_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
1075 {
1076 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1077 	unsigned long flags;
1078 	u32 val;
1079 
1080 	if (!usbmisc->blkctl)
1081 		return 0;
1082 
1083 	spin_lock_irqsave(&usbmisc->lock, flags);
1084 	val = readl(usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL);
1085 	val &= ~BLKCTL_WAKEUP_SOURCE;
1086 
1087 	if (enabled)
1088 		val |= usbmisc_blkctl_wakeup_setting(data);
1089 
1090 	writel(val, usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL);
1091 	spin_unlock_irqrestore(&usbmisc->lock, flags);
1092 
1093 	return 0;
1094 }
1095 
1096 static const struct usbmisc_ops imx25_usbmisc_ops = {
1097 	.init = usbmisc_imx25_init,
1098 	.post = usbmisc_imx25_post,
1099 };
1100 
1101 static const struct usbmisc_ops imx27_usbmisc_ops = {
1102 	.init = usbmisc_imx27_init,
1103 };
1104 
1105 static const struct usbmisc_ops imx51_usbmisc_ops = {
1106 	.init = usbmisc_imx53_init,
1107 };
1108 
1109 static const struct usbmisc_ops imx53_usbmisc_ops = {
1110 	.init = usbmisc_imx53_init,
1111 };
1112 
1113 static const struct usbmisc_ops imx6q_usbmisc_ops = {
1114 	.set_wakeup = usbmisc_imx6q_set_wakeup,
1115 	.init = usbmisc_imx6q_init,
1116 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1117 	.hsic_set_clk   = usbmisc_imx6_hsic_set_clk,
1118 };
1119 
1120 static const struct usbmisc_ops vf610_usbmisc_ops = {
1121 	.init = usbmisc_vf610_init,
1122 };
1123 
1124 static const struct usbmisc_ops imx6sx_usbmisc_ops = {
1125 	.set_wakeup = usbmisc_imx6q_set_wakeup,
1126 	.init = usbmisc_imx6sx_init,
1127 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1128 	.hsic_set_clk = usbmisc_imx6_hsic_set_clk,
1129 	.power_lost_check = usbmisc_imx6sx_power_lost_check,
1130 };
1131 
1132 static const struct usbmisc_ops imx7d_usbmisc_ops = {
1133 	.init = usbmisc_imx7d_init,
1134 	.set_wakeup = usbmisc_imx7d_set_wakeup,
1135 	.charger_detection = imx7d_charger_detection,
1136 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1137 	.pullup = usbmisc_imx7d_pullup,
1138 	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1139 };
1140 
1141 static const struct usbmisc_ops imx7ulp_usbmisc_ops = {
1142 	.init = usbmisc_imx7ulp_init,
1143 	.set_wakeup = usbmisc_imx7d_set_wakeup,
1144 	.hsic_set_connect = usbmisc_imx6_hsic_set_connect,
1145 	.hsic_set_clk = usbmisc_imx6_hsic_set_clk,
1146 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1147 };
1148 
1149 static const struct usbmisc_ops imx95_usbmisc_ops = {
1150 	.init = usbmisc_imx7d_init,
1151 	.set_wakeup = usbmisc_imx95_set_wakeup,
1152 	.charger_detection = imx7d_charger_detection,
1153 	.power_lost_check = usbmisc_imx7d_power_lost_check,
1154 	.pullup = usbmisc_imx7d_pullup,
1155 	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1156 };
1157 
1158 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data)
1159 {
1160 	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1161 
1162 	return usbmisc->ops == &imx53_usbmisc_ops;
1163 }
1164 
1165 int imx_usbmisc_init(struct imx_usbmisc_data *data)
1166 {
1167 	struct imx_usbmisc *usbmisc;
1168 
1169 	if (!data)
1170 		return 0;
1171 
1172 	usbmisc = dev_get_drvdata(data->dev);
1173 	if (!usbmisc->ops->init)
1174 		return 0;
1175 	return usbmisc->ops->init(data);
1176 }
1177 EXPORT_SYMBOL_GPL(imx_usbmisc_init);
1178 
1179 int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
1180 {
1181 	struct imx_usbmisc *usbmisc;
1182 	int ret = 0;
1183 
1184 	if (!data)
1185 		return 0;
1186 
1187 	usbmisc = dev_get_drvdata(data->dev);
1188 	if (usbmisc->ops->post)
1189 		ret = usbmisc->ops->post(data);
1190 	if (ret) {
1191 		dev_err(data->dev, "post init failed, ret=%d\n", ret);
1192 		return ret;
1193 	}
1194 
1195 	if (usbmisc->ops->set_wakeup)
1196 		ret = usbmisc->ops->set_wakeup(data, false);
1197 	if (ret) {
1198 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1199 		return ret;
1200 	}
1201 
1202 	return 0;
1203 }
1204 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
1205 
1206 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
1207 {
1208 	struct imx_usbmisc *usbmisc;
1209 
1210 	if (!data)
1211 		return 0;
1212 
1213 	usbmisc = dev_get_drvdata(data->dev);
1214 	if (!usbmisc->ops->hsic_set_connect || !data->hsic)
1215 		return 0;
1216 	return usbmisc->ops->hsic_set_connect(data);
1217 }
1218 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
1219 
1220 int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect)
1221 {
1222 	struct imx_usbmisc *usbmisc;
1223 	struct usb_phy *usb_phy;
1224 	int ret = 0;
1225 
1226 	if (!data)
1227 		return -EINVAL;
1228 
1229 	usbmisc = dev_get_drvdata(data->dev);
1230 	usb_phy = data->usb_phy;
1231 	if (!usbmisc->ops->charger_detection)
1232 		return -ENOTSUPP;
1233 
1234 	if (connect) {
1235 		ret = usbmisc->ops->charger_detection(data);
1236 		if (ret) {
1237 			dev_err(data->dev,
1238 					"Error occurs during detection: %d\n",
1239 					ret);
1240 			usb_phy->chg_state = USB_CHARGER_ABSENT;
1241 		} else {
1242 			usb_phy->chg_state = USB_CHARGER_PRESENT;
1243 		}
1244 	} else {
1245 		usb_phy->chg_state = USB_CHARGER_ABSENT;
1246 		usb_phy->chg_type = UNKNOWN_TYPE;
1247 	}
1248 	return ret;
1249 }
1250 EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection);
1251 
1252 int imx_usbmisc_pullup(struct imx_usbmisc_data *data, bool on)
1253 {
1254 	struct imx_usbmisc *usbmisc;
1255 
1256 	if (!data)
1257 		return 0;
1258 
1259 	usbmisc = dev_get_drvdata(data->dev);
1260 	if (usbmisc->ops->pullup)
1261 		usbmisc->ops->pullup(data, on);
1262 
1263 	return 0;
1264 }
1265 EXPORT_SYMBOL_GPL(imx_usbmisc_pullup);
1266 
1267 int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup)
1268 {
1269 	struct imx_usbmisc *usbmisc;
1270 	int ret = 0;
1271 
1272 	if (!data)
1273 		return 0;
1274 
1275 	usbmisc = dev_get_drvdata(data->dev);
1276 
1277 	if (usbmisc->ops->vbus_comparator_on)
1278 		usbmisc->ops->vbus_comparator_on(data, false);
1279 
1280 	if (wakeup && usbmisc->ops->set_wakeup)
1281 		ret = usbmisc->ops->set_wakeup(data, true);
1282 	if (ret) {
1283 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1284 		return ret;
1285 	}
1286 
1287 	if (usbmisc->ops->hsic_set_clk && data->hsic)
1288 		ret = usbmisc->ops->hsic_set_clk(data, false);
1289 	if (ret) {
1290 		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1291 		return ret;
1292 	}
1293 
1294 	return ret;
1295 }
1296 EXPORT_SYMBOL_GPL(imx_usbmisc_suspend);
1297 
1298 int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup)
1299 {
1300 	struct imx_usbmisc *usbmisc;
1301 	int ret = 0;
1302 
1303 	if (!data)
1304 		return 0;
1305 
1306 	usbmisc = dev_get_drvdata(data->dev);
1307 
1308 	if (usbmisc->ops->power_lost_check)
1309 		ret = usbmisc->ops->power_lost_check(data);
1310 	if (ret > 0) {
1311 		/* re-init if resume from power lost */
1312 		ret = imx_usbmisc_init(data);
1313 		if (ret) {
1314 			dev_err(data->dev, "re-init failed, ret=%d\n", ret);
1315 			return ret;
1316 		}
1317 	}
1318 
1319 	if (wakeup && usbmisc->ops->set_wakeup)
1320 		ret = usbmisc->ops->set_wakeup(data, false);
1321 	if (ret) {
1322 		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1323 		return ret;
1324 	}
1325 
1326 	if (usbmisc->ops->hsic_set_clk && data->hsic)
1327 		ret = usbmisc->ops->hsic_set_clk(data, true);
1328 	if (ret) {
1329 		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1330 		goto hsic_set_clk_fail;
1331 	}
1332 
1333 	if (usbmisc->ops->vbus_comparator_on)
1334 		usbmisc->ops->vbus_comparator_on(data, true);
1335 
1336 	return 0;
1337 
1338 hsic_set_clk_fail:
1339 	if (wakeup && usbmisc->ops->set_wakeup)
1340 		usbmisc->ops->set_wakeup(data, true);
1341 	return ret;
1342 }
1343 EXPORT_SYMBOL_GPL(imx_usbmisc_resume);
1344 
1345 static const struct of_device_id usbmisc_imx_dt_ids[] = {
1346 	{
1347 		.compatible = "fsl,imx25-usbmisc",
1348 		.data = &imx25_usbmisc_ops,
1349 	},
1350 	{
1351 		.compatible = "fsl,imx35-usbmisc",
1352 		.data = &imx25_usbmisc_ops,
1353 	},
1354 	{
1355 		.compatible = "fsl,imx27-usbmisc",
1356 		.data = &imx27_usbmisc_ops,
1357 	},
1358 	{
1359 		.compatible = "fsl,imx51-usbmisc",
1360 		.data = &imx51_usbmisc_ops,
1361 	},
1362 	{
1363 		.compatible = "fsl,imx53-usbmisc",
1364 		.data = &imx53_usbmisc_ops,
1365 	},
1366 	{
1367 		.compatible = "fsl,imx6q-usbmisc",
1368 		.data = &imx6q_usbmisc_ops,
1369 	},
1370 	{
1371 		.compatible = "fsl,vf610-usbmisc",
1372 		.data = &vf610_usbmisc_ops,
1373 	},
1374 	{
1375 		.compatible = "fsl,imx6sx-usbmisc",
1376 		.data = &imx6sx_usbmisc_ops,
1377 	},
1378 	{
1379 		.compatible = "fsl,imx6ul-usbmisc",
1380 		.data = &imx6sx_usbmisc_ops,
1381 	},
1382 	{
1383 		.compatible = "fsl,imx7d-usbmisc",
1384 		.data = &imx7d_usbmisc_ops,
1385 	},
1386 	{
1387 		.compatible = "fsl,imx7ulp-usbmisc",
1388 		.data = &imx7ulp_usbmisc_ops,
1389 	},
1390 	{
1391 		.compatible = "fsl,imx8ulp-usbmisc",
1392 		.data = &imx7ulp_usbmisc_ops,
1393 	},
1394 	{
1395 		.compatible = "fsl,imx95-usbmisc",
1396 		.data = &imx95_usbmisc_ops,
1397 	},
1398 	{ /* sentinel */ }
1399 };
1400 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
1401 
1402 static int usbmisc_imx_probe(struct platform_device *pdev)
1403 {
1404 	struct imx_usbmisc *data;
1405 	struct resource *res;
1406 
1407 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
1408 	if (!data)
1409 		return -ENOMEM;
1410 
1411 	spin_lock_init(&data->lock);
1412 
1413 	data->base = devm_platform_ioremap_resource(pdev, 0);
1414 	if (IS_ERR(data->base))
1415 		return PTR_ERR(data->base);
1416 
1417 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1418 	if (res) {
1419 		data->blkctl = devm_ioremap_resource(&pdev->dev, res);
1420 		if (IS_ERR(data->blkctl))
1421 			return PTR_ERR(data->blkctl);
1422 	} else if (device_is_compatible(&pdev->dev, "fsl,imx95-usbmisc")) {
1423 		dev_warn(&pdev->dev, "wakeup setting is missing\n");
1424 	}
1425 
1426 	data->ops = of_device_get_match_data(&pdev->dev);
1427 	platform_set_drvdata(pdev, data);
1428 
1429 	return 0;
1430 }
1431 
1432 static struct platform_driver usbmisc_imx_driver = {
1433 	.probe = usbmisc_imx_probe,
1434 	.driver = {
1435 		.name = "usbmisc_imx",
1436 		.of_match_table = usbmisc_imx_dt_ids,
1437 	 },
1438 };
1439 
1440 module_platform_driver(usbmisc_imx_driver);
1441 
1442 MODULE_ALIAS("platform:usbmisc-imx");
1443 MODULE_LICENSE("GPL");
1444 MODULE_DESCRIPTION("driver for imx usb non-core registers");
1445 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
1446