• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Amlogic G12A DWC3 Glue layer
4  *
5  * Copyright (C) 2019 BayLibre, SAS
6  * Author: Neil Armstrong <narmstrong@baylibre.com>
7  */
8 
9 #include <common.h>
10 #include <asm-generic/io.h>
11 #include <dm.h>
12 #include <dm/device-internal.h>
13 #include <dm/lists.h>
14 #include <dwc3-uboot.h>
15 #include <generic-phy.h>
16 #include <linux/usb/ch9.h>
17 #include <linux/usb/gadget.h>
18 #include <malloc.h>
19 #include <regmap.h>
20 #include <usb.h>
21 #include "core.h"
22 #include "gadget.h"
23 #include <reset.h>
24 #include <clk.h>
25 #include <power/regulator.h>
26 #include <linux/bitfield.h>
27 #include <linux/bitops.h>
28 #include <linux/compat.h>
29 
30 /* USB2 Ports Control Registers */
31 
32 #define U2P_REG_SIZE						0x20
33 
34 #define U2P_R0							0x0
35 	#define U2P_R0_HOST_DEVICE				BIT(0)
36 	#define U2P_R0_POWER_OK					BIT(1)
37 	#define U2P_R0_HAST_MODE				BIT(2)
38 	#define U2P_R0_POWER_ON_RESET				BIT(3)
39 	#define U2P_R0_ID_PULLUP				BIT(4)
40 	#define U2P_R0_DRV_VBUS					BIT(5)
41 
42 #define U2P_R1							0x4
43 	#define U2P_R1_PHY_READY				BIT(0)
44 	#define U2P_R1_ID_DIG					BIT(1)
45 	#define U2P_R1_OTG_SESSION_VALID			BIT(2)
46 	#define U2P_R1_VBUS_VALID				BIT(3)
47 
48 /* USB Glue Control Registers */
49 
50 #define USB_R0							0x80
51 	#define USB_R0_P30_LANE0_TX2RX_LOOPBACK			BIT(17)
52 	#define USB_R0_P30_LANE0_EXT_PCLK_REQ			BIT(18)
53 	#define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK		GENMASK(28, 19)
54 	#define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK		GENMASK(30, 29)
55 	#define USB_R0_U2D_ACT					BIT(31)
56 
57 #define USB_R1							0x84
58 	#define USB_R1_U3H_BIGENDIAN_GS				BIT(0)
59 	#define USB_R1_U3H_PME_ENABLE				BIT(1)
60 	#define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK		GENMASK(4, 2)
61 	#define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK		GENMASK(9, 7)
62 	#define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK		GENMASK(13, 12)
63 	#define USB_R1_U3H_HOST_U3_PORT_DISABLE			BIT(16)
64 	#define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT	BIT(17)
65 	#define USB_R1_U3H_HOST_MSI_ENABLE			BIT(18)
66 	#define USB_R1_U3H_FLADJ_30MHZ_REG_MASK			GENMASK(24, 19)
67 	#define USB_R1_P30_PCS_TX_SWING_FULL_MASK		GENMASK(31, 25)
68 
69 #define USB_R2							0x88
70 	#define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK		GENMASK(25, 20)
71 	#define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK		GENMASK(31, 26)
72 
73 #define USB_R3							0x8c
74 	#define USB_R3_P30_SSC_ENABLE				BIT(0)
75 	#define USB_R3_P30_SSC_RANGE_MASK			GENMASK(3, 1)
76 	#define USB_R3_P30_SSC_REF_CLK_SEL_MASK			GENMASK(12, 4)
77 	#define USB_R3_P30_REF_SSP_EN				BIT(13)
78 
79 #define USB_R4							0x90
80 	#define USB_R4_P21_PORT_RESET_0				BIT(0)
81 	#define USB_R4_P21_SLEEP_M0				BIT(1)
82 	#define USB_R4_MEM_PD_MASK				GENMASK(3, 2)
83 	#define USB_R4_P21_ONLY					BIT(4)
84 
85 #define USB_R5							0x94
86 	#define USB_R5_ID_DIG_SYNC				BIT(0)
87 	#define USB_R5_ID_DIG_REG				BIT(1)
88 	#define USB_R5_ID_DIG_CFG_MASK				GENMASK(3, 2)
89 	#define USB_R5_ID_DIG_EN_0				BIT(4)
90 	#define USB_R5_ID_DIG_EN_1				BIT(5)
91 	#define USB_R5_ID_DIG_CURR				BIT(6)
92 	#define USB_R5_ID_DIG_IRQ				BIT(7)
93 	#define USB_R5_ID_DIG_TH_MASK				GENMASK(15, 8)
94 	#define USB_R5_ID_DIG_CNT_MASK				GENMASK(23, 16)
95 
96 enum {
97 	USB2_HOST_PHY = 0,
98 	USB2_OTG_PHY,
99 	USB3_HOST_PHY,
100 	PHY_COUNT,
101 };
102 
103 static const char *phy_names[PHY_COUNT] = {
104 	"usb2-phy0", "usb2-phy1", "usb3-phy0",
105 };
106 
107 struct dwc3_meson_g12a {
108 	struct udevice		*dev;
109 	struct regmap           *regmap;
110 	struct clk		clk;
111 	struct reset_ctl	reset;
112 	struct phy		phys[PHY_COUNT];
113 	enum usb_dr_mode	otg_mode;
114 	enum usb_dr_mode	otg_phy_mode;
115 	unsigned int		usb2_ports;
116 	unsigned int		usb3_ports;
117 #if CONFIG_IS_ENABLED(DM_REGULATOR)
118 	struct udevice		*vbus_supply;
119 #endif
120 };
121 
122 #define U2P_REG_SIZE						0x20
123 #define USB_REG_OFFSET						0x80
124 
dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a * priv,int i,enum usb_dr_mode mode)125 static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
126 					  int i, enum usb_dr_mode mode)
127 {
128 	switch (mode) {
129 	case USB_DR_MODE_HOST:
130 	case USB_DR_MODE_OTG:
131 	case USB_DR_MODE_UNKNOWN:
132 		regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
133 				U2P_R0_HOST_DEVICE,
134 				U2P_R0_HOST_DEVICE);
135 		break;
136 
137 	case USB_DR_MODE_PERIPHERAL:
138 		regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
139 				U2P_R0_HOST_DEVICE, 0);
140 		break;
141 	}
142 }
143 
dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a * priv)144 static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
145 {
146 	int i;
147 
148 	if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
149 		priv->otg_phy_mode = USB_DR_MODE_PERIPHERAL;
150 	else
151 		priv->otg_phy_mode = USB_DR_MODE_HOST;
152 
153 	for (i = 0 ; i < USB3_HOST_PHY ; ++i) {
154 		if (!priv->phys[i].dev)
155 			continue;
156 
157 		regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
158 				   U2P_R0_POWER_ON_RESET,
159 				   U2P_R0_POWER_ON_RESET);
160 
161 		if (i == USB2_OTG_PHY) {
162 			regmap_update_bits(priv->regmap,
163 					   U2P_R0 + (U2P_REG_SIZE * i),
164 					   U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
165 					   U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
166 
167 			dwc3_meson_g12a_usb2_set_mode(priv, i,
168 						      priv->otg_phy_mode);
169 		} else
170 			dwc3_meson_g12a_usb2_set_mode(priv, i,
171 						      USB_DR_MODE_HOST);
172 
173 		regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
174 				   U2P_R0_POWER_ON_RESET, 0);
175 	}
176 
177 	return 0;
178 }
179 
dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a * priv)180 static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
181 {
182 	regmap_update_bits(priv->regmap, USB_R3,
183 			USB_R3_P30_SSC_RANGE_MASK |
184 			USB_R3_P30_REF_SSP_EN,
185 			USB_R3_P30_SSC_ENABLE |
186 			FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
187 			USB_R3_P30_REF_SSP_EN);
188 	udelay(2);
189 
190 	regmap_update_bits(priv->regmap, USB_R2,
191 			USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
192 			FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
193 
194 	regmap_update_bits(priv->regmap, USB_R2,
195 			USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
196 			FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
197 
198 	udelay(2);
199 
200 	regmap_update_bits(priv->regmap, USB_R1,
201 			USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
202 			USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
203 
204 	regmap_update_bits(priv->regmap, USB_R1,
205 			USB_R1_P30_PCS_TX_SWING_FULL_MASK,
206 			FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
207 }
208 
dwc3_meson_g12a_usb_init_mode(struct dwc3_meson_g12a * priv)209 static void dwc3_meson_g12a_usb_init_mode(struct dwc3_meson_g12a *priv)
210 {
211 	if (priv->otg_phy_mode == USB_DR_MODE_PERIPHERAL) {
212 		regmap_update_bits(priv->regmap, USB_R0,
213 				USB_R0_U2D_ACT, USB_R0_U2D_ACT);
214 		regmap_update_bits(priv->regmap, USB_R0,
215 				USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
216 		regmap_update_bits(priv->regmap, USB_R4,
217 				USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
218 	} else {
219 		regmap_update_bits(priv->regmap, USB_R0,
220 				USB_R0_U2D_ACT, 0);
221 		regmap_update_bits(priv->regmap, USB_R4,
222 				USB_R4_P21_SLEEP_M0, 0);
223 	}
224 }
225 
dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a * priv)226 static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
227 {
228 	int ret;
229 
230 	ret = dwc3_meson_g12a_usb2_init(priv);
231 	if (ret)
232 		return ret;
233 
234 	regmap_update_bits(priv->regmap, USB_R1,
235 			USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
236 			FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
237 
238 	regmap_update_bits(priv->regmap, USB_R5,
239 			USB_R5_ID_DIG_EN_0,
240 			USB_R5_ID_DIG_EN_0);
241 	regmap_update_bits(priv->regmap, USB_R5,
242 			USB_R5_ID_DIG_EN_1,
243 			USB_R5_ID_DIG_EN_1);
244 	regmap_update_bits(priv->regmap, USB_R5,
245 			USB_R5_ID_DIG_TH_MASK,
246 			FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
247 
248 	/* If we have an actual SuperSpeed port, initialize it */
249 	if (priv->usb3_ports)
250 		dwc3_meson_g12a_usb3_init(priv);
251 
252 	dwc3_meson_g12a_usb_init_mode(priv);
253 
254 	return 0;
255 }
256 
dwc3_meson_g12a_force_mode(struct udevice * dev,enum usb_dr_mode mode)257 int dwc3_meson_g12a_force_mode(struct udevice *dev, enum usb_dr_mode mode)
258 {
259 	struct dwc3_meson_g12a *priv = dev_get_platdata(dev);
260 
261 	if (!priv)
262 		return -EINVAL;
263 
264 	if (mode != USB_DR_MODE_HOST && mode != USB_DR_MODE_PERIPHERAL)
265 		return -EINVAL;
266 
267 	if (!priv->phys[USB2_OTG_PHY].dev)
268 		return -EINVAL;
269 
270 	if (mode == priv->otg_mode)
271 		return 0;
272 
273 	if (mode == USB_DR_MODE_HOST)
274 		debug("%s: switching to Host Mode\n", __func__);
275 	else
276 		debug("%s: switching to Device Mode\n", __func__);
277 
278 #if CONFIG_IS_ENABLED(DM_REGULATOR)
279 	if (priv->vbus_supply) {
280 		int ret = regulator_set_enable(priv->vbus_supply,
281 					(mode == USB_DR_MODE_PERIPHERAL));
282 		if (ret)
283 			return ret;
284 	}
285 #endif
286 	priv->otg_phy_mode = mode;
287 
288 	dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode);
289 
290 	dwc3_meson_g12a_usb_init_mode(priv);
291 
292 	return 0;
293 }
294 
dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a * priv)295 static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
296 {
297 	int i, ret;
298 
299 	for (i = 0 ; i < PHY_COUNT ; ++i) {
300 		ret = generic_phy_get_by_name(priv->dev, phy_names[i],
301 					      &priv->phys[i]);
302 		if (ret == -ENOENT)
303 			continue;
304 
305 		if (ret)
306 			return ret;
307 
308 		if (i == USB3_HOST_PHY)
309 			priv->usb3_ports++;
310 		else
311 			priv->usb2_ports++;
312 	}
313 
314 	debug("%s: usb2 ports: %d\n", __func__, priv->usb2_ports);
315 	debug("%s: usb3 ports: %d\n", __func__, priv->usb3_ports);
316 
317 	return 0;
318 }
319 
dwc3_meson_g12a_reset_init(struct dwc3_meson_g12a * priv)320 static int dwc3_meson_g12a_reset_init(struct dwc3_meson_g12a *priv)
321 {
322 	int ret;
323 
324 	ret = reset_get_by_index(priv->dev, 0, &priv->reset);
325 	if (ret)
326 		return ret;
327 
328 	ret = reset_assert(&priv->reset);
329 	udelay(1);
330 	ret |= reset_deassert(&priv->reset);
331 	if (ret) {
332 		reset_free(&priv->reset);
333 		return ret;
334 	}
335 
336 	return 0;
337 }
338 
dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a * priv)339 static int dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a *priv)
340 {
341 	int ret;
342 
343 	ret = clk_get_by_index(priv->dev, 0, &priv->clk);
344 	if (ret)
345 		return ret;
346 
347 #if CONFIG_IS_ENABLED(CLK)
348 	ret = clk_enable(&priv->clk);
349 	if (ret) {
350 		clk_free(&priv->clk);
351 		return ret;
352 	}
353 #endif
354 
355 	return 0;
356 }
357 
dwc3_meson_g12a_probe(struct udevice * dev)358 static int dwc3_meson_g12a_probe(struct udevice *dev)
359 {
360 	struct dwc3_meson_g12a *priv = dev_get_platdata(dev);
361 	int ret, i;
362 
363 	priv->dev = dev;
364 
365 	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
366 	if (ret)
367 		return ret;
368 
369 	ret = dwc3_meson_g12a_clk_init(priv);
370 	if (ret)
371 		return ret;
372 
373 	ret = dwc3_meson_g12a_reset_init(priv);
374 	if (ret)
375 		return ret;
376 
377 	ret = dwc3_meson_g12a_get_phys(priv);
378 	if (ret)
379 		return ret;
380 
381 #if CONFIG_IS_ENABLED(DM_REGULATOR)
382 	ret = device_get_supply_regulator(dev, "vbus-supply",
383 					  &priv->vbus_supply);
384 	if (ret && ret != -ENOENT) {
385 		pr_err("Failed to get PHY regulator\n");
386 		return ret;
387 	}
388 
389 	if (priv->vbus_supply) {
390 		ret = regulator_set_enable(priv->vbus_supply, true);
391 		if (ret)
392 			return ret;
393 	}
394 #endif
395 
396 	priv->otg_mode = usb_get_dr_mode(dev_of_offset(dev));
397 
398 	ret = dwc3_meson_g12a_usb_init(priv);
399 	if (ret)
400 		return ret;
401 
402 	for (i = 0 ; i < PHY_COUNT ; ++i) {
403 		if (!priv->phys[i].dev)
404 			continue;
405 
406 		ret = generic_phy_init(&priv->phys[i]);
407 		if (ret)
408 			goto err_phy_init;
409 	}
410 
411 	return 0;
412 
413 err_phy_init:
414 	for (i = 0 ; i < PHY_COUNT ; ++i) {
415 		if (!priv->phys[i].dev)
416 			continue;
417 
418 		 generic_phy_exit(&priv->phys[i]);
419 	}
420 
421 	return ret;
422 }
423 
dwc3_meson_g12a_remove(struct udevice * dev)424 static int dwc3_meson_g12a_remove(struct udevice *dev)
425 {
426 	struct dwc3_meson_g12a *priv = dev_get_platdata(dev);
427 	int i;
428 
429 	reset_release_all(&priv->reset, 1);
430 
431 	clk_release_all(&priv->clk, 1);
432 
433 	for (i = 0 ; i < PHY_COUNT ; ++i) {
434 		if (!priv->phys[i].dev)
435 			continue;
436 
437 		 generic_phy_exit(&priv->phys[i]);
438 	}
439 
440 	return dm_scan_fdt_dev(dev);
441 }
442 
443 static const struct udevice_id dwc3_meson_g12a_ids[] = {
444 	{ .compatible = "amlogic,meson-g12a-usb-ctrl" },
445 	{ }
446 };
447 
448 U_BOOT_DRIVER(dwc3_generic_wrapper) = {
449 	.name	= "dwc3-meson-g12a",
450 	.id	= UCLASS_SIMPLE_BUS,
451 	.of_match = dwc3_meson_g12a_ids,
452 	.probe = dwc3_meson_g12a_probe,
453 	.remove = dwc3_meson_g12a_remove,
454 	.platdata_auto_alloc_size = sizeof(struct dwc3_meson_g12a),
455 
456 };
457