xref: /rk3399_rockchip-uboot/drivers/phy/phy-rockchip-naneng-combphy.c (revision 885c5d5d1bf208344fe0437cf6cdabe30da130cf)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip USB3.0/PCIe Gen2/SATA/SGMII combphy driver
4  *
5  * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
6  */
7 
8 #include <common.h>
9 #include <clk.h>
10 #include <dm.h>
11 #include <dm/lists.h>
12 #include <dt-bindings/phy/phy.h>
13 #include <generic-phy.h>
14 #include <syscon.h>
15 #include <asm/io.h>
16 #include <asm/arch/clock.h>
17 #include <regmap.h>
18 #include <reset-uclass.h>
19 
20 #define BIT_WRITEABLE_SHIFT		16
21 
22 struct rockchip_combphy_priv;
23 
24 struct combphy_reg {
25 	u32 offset;
26 	u16 bitend;
27 	u16 bitstart;
28 	u16 disable;
29 	u16 enable;
30 };
31 
32 struct rockchip_combphy_grfcfg {
33 	struct combphy_reg pcie_mode_set;
34 	struct combphy_reg usb_mode_set;
35 	struct combphy_reg sgmii_mode_set;
36 	struct combphy_reg qsgmii_mode_set;
37 	struct combphy_reg pipe_rxterm_set;
38 	struct combphy_reg pipe_txelec_set;
39 	struct combphy_reg pipe_txcomp_set;
40 	struct combphy_reg pipe_clk_24m;
41 	struct combphy_reg pipe_clk_25m;
42 	struct combphy_reg pipe_clk_100m;
43 	struct combphy_reg pipe_phymode_sel;
44 	struct combphy_reg pipe_rate_sel;
45 	struct combphy_reg pipe_rxterm_sel;
46 	struct combphy_reg pipe_txelec_sel;
47 	struct combphy_reg pipe_txcomp_sel;
48 	struct combphy_reg pipe_clk_ext;
49 	struct combphy_reg pipe_sel_usb;
50 	struct combphy_reg pipe_sel_qsgmii;
51 	struct combphy_reg pipe_phy_status;
52 	struct combphy_reg con0_for_pcie;
53 	struct combphy_reg con1_for_pcie;
54 	struct combphy_reg con2_for_pcie;
55 	struct combphy_reg con3_for_pcie;
56 	struct combphy_reg con0_for_sata;
57 	struct combphy_reg con1_for_sata;
58 	struct combphy_reg con2_for_sata;
59 	struct combphy_reg con3_for_sata;
60 	struct combphy_reg pipe_con0_for_sata;
61 	struct combphy_reg pipe_con1_for_sata;
62 	struct combphy_reg pipe_sgmii_mac_sel;
63 	struct combphy_reg pipe_xpcs_phy_ready;
64 	struct combphy_reg u3otg0_port_en;
65 	struct combphy_reg u3otg1_port_en;
66 };
67 
68 struct rockchip_combphy_cfg {
69 	const struct rockchip_combphy_grfcfg *grfcfg;
70 	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
71 };
72 
73 struct rockchip_combphy_priv {
74 	u32 mode;
75 	void __iomem *mmio;
76 	struct udevice *dev;
77 	struct regmap *pipe_grf;
78 	struct regmap *phy_grf;
79 	struct phy *phy;
80 	struct reset_ctl phy_rst;
81 	struct clk ref_clk;
82 	const struct rockchip_combphy_cfg *cfg;
83 };
84 
85 static int param_write(struct regmap *base,
86 		       const struct combphy_reg *reg, bool en)
87 {
88 	u32 val, mask, tmp;
89 
90 	tmp = en ? reg->enable : reg->disable;
91 	mask = GENMASK(reg->bitend, reg->bitstart);
92 	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
93 
94 	return regmap_write(base, reg->offset, val);
95 }
96 
97 static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv)
98 {
99 	int ret = 0;
100 
101 	if (priv->cfg->combphy_cfg) {
102 		ret = priv->cfg->combphy_cfg(priv);
103 		if (ret) {
104 			dev_err(priv->dev, "failed to init phy for pcie\n");
105 			return ret;
106 		}
107 	}
108 
109 	return ret;
110 }
111 
112 static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv)
113 {
114 	int ret = 0;
115 
116 	if (priv->cfg->combphy_cfg) {
117 		ret = priv->cfg->combphy_cfg(priv);
118 		if (ret) {
119 			dev_err(priv->dev, "failed to init phy for usb3\n");
120 			return ret;
121 		}
122 	}
123 
124 	return ret;
125 }
126 
127 static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv)
128 {
129 	int ret = 0;
130 
131 	if (priv->cfg->combphy_cfg) {
132 		ret = priv->cfg->combphy_cfg(priv);
133 		if (ret) {
134 			dev_err(priv->dev, "failed to init phy for sata\n");
135 			return ret;
136 		}
137 	}
138 
139 	return ret;
140 }
141 
142 static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv)
143 {
144 	int ret = 0;
145 
146 	if (priv->cfg->combphy_cfg) {
147 		ret = priv->cfg->combphy_cfg(priv);
148 		if (ret) {
149 			dev_err(priv->dev, "failed to init phy for sgmii\n");
150 			return ret;
151 		}
152 	}
153 
154 	return ret;
155 }
156 
157 static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
158 {
159 	switch (priv->mode) {
160 	case PHY_TYPE_PCIE:
161 		rockchip_combphy_pcie_init(priv);
162 		break;
163 	case PHY_TYPE_USB3:
164 		rockchip_combphy_usb3_init(priv);
165 		break;
166 	case PHY_TYPE_SATA:
167 		rockchip_combphy_sata_init(priv);
168 		break;
169 	case PHY_TYPE_SGMII:
170 	case PHY_TYPE_QSGMII:
171 		return rockchip_combphy_sgmii_init(priv);
172 	default:
173 		dev_err(priv->dev, "incompatible PHY type\n");
174 		return -EINVAL;
175 	}
176 
177 	return 0;
178 }
179 
180 static int rockchip_combphy_init(struct phy *phy)
181 {
182 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
183 	int ret;
184 
185 	ret = clk_enable(&priv->ref_clk);
186 	if (ret < 0 && ret != -ENOSYS)
187 		return ret;
188 
189 	ret = rockchip_combphy_set_mode(priv);
190 	if (ret)
191 		goto err_clk;
192 
193 	reset_deassert(&priv->phy_rst);
194 
195 	return 0;
196 
197 err_clk:
198 	clk_disable(&priv->ref_clk);
199 
200 	return ret;
201 }
202 
203 static int rockchip_combphy_exit(struct phy *phy)
204 {
205 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
206 
207 	clk_disable(&priv->ref_clk);
208 	reset_assert(&priv->phy_rst);
209 
210 	return 0;
211 }
212 
213 static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *args)
214 {
215 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
216 
217 	if (args->args_count != 1) {
218 		pr_err("invalid number of arguments\n");
219 		return -EINVAL;
220 	}
221 
222 	priv->mode = args->args[0];
223 
224 	return 0;
225 }
226 
227 static const struct phy_ops rochchip_combphy_ops = {
228 	.init = rockchip_combphy_init,
229 	.exit = rockchip_combphy_exit,
230 	.of_xlate = rockchip_combphy_xlate,
231 };
232 
233 static int rockchip_combphy_parse_dt(struct udevice *dev,
234 				     struct rockchip_combphy_priv *priv)
235 {
236 	struct udevice *syscon;
237 	int ret;
238 	u32 vals[4];
239 
240 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon);
241 	if (ret) {
242 		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap ret= %d\n", ret);
243 		return ret;
244 	}
245 	priv->pipe_grf = syscon_get_regmap(syscon);
246 
247 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon);
248 	if (ret) {
249 		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
250 		return ret;
251 	}
252 	priv->phy_grf = syscon_get_regmap(syscon);
253 
254 	ret = clk_get_by_index(dev, 0, &priv->ref_clk);
255 	if (ret) {
256 		dev_err(dev, "failed to find ref clock\n");
257 		return PTR_ERR(&priv->ref_clk);
258 	}
259 
260 	ret = reset_get_by_name(dev, "combphy", &priv->phy_rst);
261 	if (ret) {
262 		dev_err(dev, "no phy reset control specified\n");
263 		return ret;
264 	}
265 
266 	if (!dev_read_u32_array(dev, "rockchip,pcie1ln-sel-bits",
267 				vals, ARRAY_SIZE(vals)))
268 		regmap_write(priv->pipe_grf, vals[0],
269 			     (GENMASK(vals[2], vals[1]) << 16) | vals[3]);
270 
271 	return 0;
272 }
273 
274 static int rockchip_combphy_probe(struct udevice *udev)
275 {
276 	struct rockchip_combphy_priv *priv = dev_get_priv(udev);
277 	const struct rockchip_combphy_cfg *phy_cfg;
278 
279 	priv->mmio = (void __iomem *)dev_read_addr(udev);
280 	if (IS_ERR(priv->mmio))
281 		return PTR_ERR(priv->mmio);
282 
283 	phy_cfg = (const struct rockchip_combphy_cfg *)dev_get_driver_data(udev);
284 	if (!phy_cfg) {
285 		dev_err(udev, "No OF match data provided\n");
286 		return -EINVAL;
287 	}
288 
289 	priv->dev = udev;
290 	priv->mode = PHY_TYPE_SATA;
291 	priv->cfg = phy_cfg;
292 
293 	return rockchip_combphy_parse_dt(udev, priv);
294 }
295 
296 static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
297 {
298 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
299 	u32 val;
300 
301 	switch (priv->mode) {
302 	case PHY_TYPE_PCIE:
303 		/* Set SSC downward spread spectrum */
304 		val = readl(priv->mmio + 0x18);
305 		val &= ~GENMASK(5, 4);
306 		val |= 0x01 << 4;
307 		writel(val, priv->mmio + 0x18);
308 
309 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
310 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
311 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
312 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
313 		break;
314 	case PHY_TYPE_USB3:
315 		/* Set SSC downward spread spectrum */
316 		val = readl(priv->mmio + 0x18);
317 		val &= ~GENMASK(5, 4);
318 		val |= 0x01 << 4;
319 		writel(val, priv->mmio + 0x18);
320 
321 		/* Enable adaptive CTLE for USB3.0 Rx */
322 		val = readl(priv->mmio + 0x200);
323 		val &= ~GENMASK(17, 17);
324 		val |= 0x01;
325 		writel(val, priv->mmio + 0x200);
326 
327 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
328 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
329 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
330 		break;
331 	default:
332 		dev_err(priv->dev, "incompatible PHY type\n");
333 		return -EINVAL;
334 	}
335 
336 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
337 	if (priv->mode == PHY_TYPE_PCIE) {
338 		/* PLL KVCO tuning fine */
339 		val = readl(priv->mmio + 0x18);
340 		val &= ~(0x7 << 10);
341 		val |= 0x2 << 10;
342 		writel(val, priv->mmio + 0x18);
343 
344 		/* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */
345 		val = readl(priv->mmio + 0x108);
346 		val &= ~(0x7f7);
347 		val |= 0x4f0;
348 		writel(val, priv->mmio + 0x108);
349 	}
350 
351 	return 0;
352 }
353 
354 static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = {
355 	/* pipe-phy-grf */
356 	.pcie_mode_set		= { 0x48000, 5, 0, 0x00, 0x11 },
357 	.usb_mode_set		= { 0x48000, 5, 0, 0x00, 0x04 },
358 	.pipe_rxterm_set	= { 0x48000, 12, 12, 0x00, 0x01 },
359 	.pipe_txelec_set	= { 0x48004, 1, 1, 0x00, 0x01 },
360 	.pipe_txcomp_set	= { 0x48004, 4, 4, 0x00, 0x01 },
361 	.pipe_clk_24m		= { 0x48004, 14, 13, 0x00, 0x00 },
362 	.pipe_clk_100m		= { 0x48004, 14, 13, 0x00, 0x02 },
363 	.pipe_rxterm_sel	= { 0x48008, 8, 8, 0x00, 0x01 },
364 	.pipe_txelec_sel	= { 0x48008, 12, 12, 0x00, 0x01 },
365 	.pipe_txcomp_sel	= { 0x48008, 15, 15, 0x00, 0x01 },
366 	.pipe_clk_ext		= { 0x4800c, 9, 8, 0x02, 0x01 },
367 	.pipe_phy_status	= { 0x48034, 6, 6, 0x01, 0x00 },
368 	.con0_for_pcie		= { 0x48000, 15, 0, 0x00, 0x110 },
369 	.con1_for_pcie		= { 0x48004, 15, 0, 0x00, 0x00 },
370 	.con2_for_pcie		= { 0x48008, 15, 0, 0x00, 0x101 },
371 	.con3_for_pcie		= { 0x4800c, 15, 0, 0x00, 0x0200 },
372 	/* pipe-grf */
373 	.u3otg0_port_en		= { 0x40044, 15, 0, 0x0181, 0x1100 },
374 };
375 
376 static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = {
377 	.grfcfg		= &rk3528_combphy_grfcfgs,
378 	.combphy_cfg	= rk3528_combphy_cfg,
379 };
380 
381 static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
382 {
383 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
384 	u32 val;
385 
386 	switch (priv->mode) {
387 	case PHY_TYPE_PCIE:
388 		/* Set SSC downward spread spectrum */
389 		val = readl(priv->mmio + (0x1f << 2));
390 		val &= ~GENMASK(5, 4);
391 		val |= 0x01 << 4;
392 		writel(val, priv->mmio + 0x7c);
393 
394 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
395 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
396 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
397 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
398 		break;
399 	case PHY_TYPE_USB3:
400 		/* Set SSC downward spread spectrum */
401 		val = readl(priv->mmio + (0x1f << 2));
402 		val &= ~GENMASK(5, 4);
403 		val |= 0x01 << 4;
404 		writel(val, priv->mmio + 0x7c);
405 
406 		/* Enable adaptive CTLE for USB3.0 Rx */
407 		val = readl(priv->mmio + (0x0e << 2));
408 		val &= ~GENMASK(0, 0);
409 		val |= 0x01;
410 		writel(val, priv->mmio + (0x0e << 2));
411 
412 		/* Set PLL KVCO fine tuning signals */
413 		val = readl(priv->mmio + (0x20 << 2));
414 		val &= ~(0x7 << 2);
415 		val |= 0x2 << 2;
416 		writel(val, priv->mmio + (0x20 << 2));
417 
418 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
419 		writel(0x4, priv->mmio + (0xb << 2));
420 
421 		/* Set PLL input clock divider 1/2 */
422 		val = readl(priv->mmio + (0x5 << 2));
423 		val &= ~(0x3 << 6);
424 		val |= 0x1 << 6;
425 		writel(val, priv->mmio + (0x5 << 2));
426 
427 		/* Set PLL loop divider */
428 		writel(0x32, priv->mmio + (0x11 << 2));
429 
430 		/* Set PLL KVCO to min and set PLL charge pump current to max */
431 		writel(0xf0, priv->mmio + (0xa << 2));
432 
433 		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
434 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
435 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
436 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
437 		break;
438 	default:
439 		pr_err("%s, phy-type %d\n", __func__, priv->mode);
440 		return -EINVAL;
441 	}
442 
443 	clk_set_rate(&priv->ref_clk, 100000000);
444 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
445 
446 	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
447 		val = readl(priv->mmio + (0x7 << 2));
448 		val |= BIT(4);
449 		writel(val, priv->mmio + (0x7 << 2));
450 	}
451 
452 	return 0;
453 }
454 
455 static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = {
456 	/* pipe-phy-grf */
457 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
458 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
459 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
460 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
461 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
462 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
463 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
464 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
465 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
466 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
467 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
468 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
469 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
470 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
471 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
472 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
473 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
474 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
475 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
476 	/* pipe-grf */
477 	.u3otg0_port_en		= { 0x0094, 15, 0, 0x0181, 0x1100 },
478 };
479 
480 static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = {
481 	.grfcfg		= &rk3562_combphy_grfcfgs,
482 	.combphy_cfg	= rk3562_combphy_cfg,
483 };
484 
485 static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
486 {
487 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
488 	u32 val;
489 
490 	switch (priv->mode) {
491 	case PHY_TYPE_PCIE:
492 		/* Set SSC downward spread spectrum */
493 		val = readl(priv->mmio + (0x1f << 2));
494 		val &= ~GENMASK(5, 4);
495 		val |= 0x01 << 4;
496 		writel(val, priv->mmio + 0x7c);
497 
498 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
499 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
500 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
501 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
502 		break;
503 	case PHY_TYPE_USB3:
504 		/* Set SSC downward spread spectrum */
505 		val = readl(priv->mmio + (0x1f << 2));
506 		val &= ~GENMASK(5, 4);
507 		val |= 0x01 << 4;
508 		writel(val, priv->mmio + 0x7c);
509 
510 		/* Enable adaptive CTLE for USB3.0 Rx */
511 		val = readl(priv->mmio + (0x0e << 2));
512 		val &= ~GENMASK(0, 0);
513 		val |= 0x01;
514 		writel(val, priv->mmio + (0x0e << 2));
515 
516 		/* Set PLL KVCO fine tuning signals */
517 		val = readl(priv->mmio + (0x20 << 2));
518 		val &= ~(0x7 << 2);
519 		val |= 0x2 << 2;
520 		writel(val, priv->mmio + (0x20 << 2));
521 
522 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
523 		writel(0x4, priv->mmio + (0xb << 2));
524 
525 		/* Set PLL input clock divider 1/2 */
526 		val = readl(priv->mmio + (0x5 << 2));
527 		val &= ~(0x3 << 6);
528 		val |= 0x1 << 6;
529 		writel(val, priv->mmio + (0x5 << 2));
530 
531 		/* Set PLL loop divider */
532 		writel(0x32, priv->mmio + (0x11 << 2));
533 
534 		/* Set PLL KVCO to min and set PLL charge pump current to max */
535 		writel(0xf0, priv->mmio + (0xa << 2));
536 
537 		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
538 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
539 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
540 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
541 		break;
542 	case PHY_TYPE_SATA:
543 		writel(0x41, priv->mmio + 0x38);
544 		writel(0x8F, priv->mmio + 0x18);
545 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
546 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
547 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
548 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
549 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
550 		break;
551 	case PHY_TYPE_SGMII:
552 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
553 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
554 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
555 		param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
556 		break;
557 	case PHY_TYPE_QSGMII:
558 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
559 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
560 		param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
561 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
562 		param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
563 		break;
564 	default:
565 		pr_err("%s, phy-type %d\n", __func__, priv->mode);
566 		return -EINVAL;
567 	}
568 
569 	/* The default ref clock is 25Mhz */
570 	param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
571 
572 	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
573 		val = readl(priv->mmio + (0x7 << 2));
574 		val |= BIT(4);
575 		writel(val, priv->mmio + (0x7 << 2));
576 	}
577 
578 	return 0;
579 }
580 
581 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
582 	/* pipe-phy-grf */
583 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
584 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
585 	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
586 	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
587 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
588 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
589 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
590 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
591 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
592 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
593 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
594 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
595 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
596 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
597 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
598 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
599 	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
600 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
601 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
602 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
603 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
604 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
605 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
606 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
607 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
608 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
609 	/* pipe-grf */
610 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
611 	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
612 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
613 	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
614 	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
615 };
616 
617 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
618 	.grfcfg		= &rk3568_combphy_grfcfgs,
619 	.combphy_cfg	= rk3568_combphy_cfg,
620 };
621 
622 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
623 {
624 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
625 	u32 val;
626 
627 	switch (priv->mode) {
628 	case PHY_TYPE_PCIE:
629 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
630 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
631 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
632 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
633 		break;
634 	case PHY_TYPE_USB3:
635 		/* Set SSC downward spread spectrum */
636 		val = readl(priv->mmio + (0x1f << 2));
637 		val &= ~GENMASK(5, 4);
638 		val |= 0x01 << 4;
639 		writel(val, priv->mmio + 0x7c);
640 
641 		/* Enable adaptive CTLE for USB3.0 Rx */
642 		val = readl(priv->mmio + (0x0e << 2));
643 		val &= ~GENMASK(0, 0);
644 		val |= 0x01;
645 		writel(val, priv->mmio + (0x0e << 2));
646 
647 		/* Set PLL KVCO fine tuning signals */
648 		val = readl(priv->mmio + (0x20 << 2));
649 		val &= ~(0x7 << 2);
650 		val |= 0x2 << 2;
651 		writel(val, priv->mmio + (0x20 << 2));
652 
653 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
654 		writel(0x4, priv->mmio + (0xb << 2));
655 
656 		/* Set PLL input clock divider 1/2 */
657 		val = readl(priv->mmio + (0x5 << 2));
658 		val &= ~(0x3 << 6);
659 		val |= 0x1 << 6;
660 		writel(val, priv->mmio + (0x5 << 2));
661 
662 		/* Set PLL loop divider */
663 		writel(0x32, priv->mmio + (0x11 << 2));
664 
665 		/* Set PLL KVCO to min and set PLL charge pump current to max */
666 		writel(0xf0, priv->mmio + (0xa << 2));
667 
668 		/* Set Rx squelch input filler bandwidth */
669 		writel(0x0d, priv->mmio + (0x14 << 2));
670 
671 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
672 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
673 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
674 		break;
675 	case PHY_TYPE_SATA:
676 		/* Enable adaptive CTLE for SATA Rx */
677 		val = readl(priv->mmio + (0x0e << 2));
678 		val &= ~GENMASK(0, 0);
679 		val |= 0x01;
680 		writel(val, priv->mmio + (0x0e << 2));
681 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
682 		writel(0x8F, priv->mmio + (0x06 << 2));
683 
684 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
685 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
686 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
687 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
688 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
689 		param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
690 		break;
691 	case PHY_TYPE_SGMII:
692 	case PHY_TYPE_QSGMII:
693 	default:
694 		dev_err(priv->dev, "incompatible PHY type\n");
695 		return -EINVAL;
696 	}
697 
698 	/* 100MHz refclock signal is good */
699 	clk_set_rate(&priv->ref_clk, 100000000);
700 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
701 	if (priv->mode == PHY_TYPE_PCIE) {
702 		/* PLL KVCO tuning fine */
703 		val = readl(priv->mmio + (0x20 << 2));
704 		val &= ~GENMASK(4, 2);
705 		val |= 0x4 << 2;
706 		writel(val, priv->mmio + (0x20 << 2));
707 
708 		/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
709 		val = 0x4c;
710 		writel(val, priv->mmio + (0x1b << 2));
711 
712 		/* Set up su_trim: T3 */
713 		val = 0xb0;
714 		writel(val, priv->mmio + (0xa << 2));
715 		val = 0x47;
716 		writel(val, priv->mmio + (0xb << 2));
717 		val = 0x57;
718 		writel(val, priv->mmio + (0xd << 2));
719 	}
720 
721 	return 0;
722 }
723 
724 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
725 	/* pipe-phy-grf */
726 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
727 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
728 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
729 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
730 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
731 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
732 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
733 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
734 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
735 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
736 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
737 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
738 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
739 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
740 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
741 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
742 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
743 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
744 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
745 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
746 	/* pipe-grf */
747 	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
748 	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
749 };
750 
751 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
752 	.grfcfg		= &rk3588_combphy_grfcfgs,
753 	.combphy_cfg	= rk3588_combphy_cfg,
754 };
755 
756 static const struct udevice_id rockchip_combphy_ids[] = {
757 	{
758 		.compatible = "rockchip,rk3528-naneng-combphy",
759 		.data = (ulong)&rk3528_combphy_cfgs
760 	},
761 	{
762 		.compatible = "rockchip,rk3562-naneng-combphy",
763 		.data = (ulong)&rk3562_combphy_cfgs
764 	},
765 	{
766 		.compatible = "rockchip,rk3568-naneng-combphy",
767 		.data = (ulong)&rk3568_combphy_cfgs
768 	},
769 	{
770 		.compatible = "rockchip,rk3588-naneng-combphy",
771 		.data = (ulong)&rk3588_combphy_cfgs
772 	},
773 	{ }
774 };
775 
776 U_BOOT_DRIVER(rockchip_naneng_combphy) = {
777 	.name		= "naneng-combphy",
778 	.id		= UCLASS_PHY,
779 	.of_match	= rockchip_combphy_ids,
780 	.ops		= &rochchip_combphy_ops,
781 	.probe		= rockchip_combphy_probe,
782 	.priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv),
783 };
784