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