xref: /rk3399_rockchip-uboot/drivers/phy/phy-rockchip-naneng-combphy.c (revision c0c8f176f3afaa90ae63c3b6cda813d484ad6fc2)
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 rk3568_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 	case PHY_TYPE_SATA:
439 		writel(0x41, priv->mmio + 0x38);
440 		writel(0x8F, priv->mmio + 0x18);
441 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
442 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
443 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
444 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
445 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
446 		break;
447 	case PHY_TYPE_SGMII:
448 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
449 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
450 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
451 		param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
452 		break;
453 	case PHY_TYPE_QSGMII:
454 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
455 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
456 		param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
457 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
458 		param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
459 		break;
460 	default:
461 		pr_err("%s, phy-type %d\n", __func__, priv->mode);
462 		return -EINVAL;
463 	}
464 
465 	/* The default ref clock is 25Mhz */
466 	param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
467 
468 	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
469 		val = readl(priv->mmio + (0x7 << 2));
470 		val |= BIT(4);
471 		writel(val, priv->mmio + (0x7 << 2));
472 	}
473 
474 	return 0;
475 }
476 
477 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
478 	/* pipe-phy-grf */
479 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
480 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
481 	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
482 	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
483 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
484 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
485 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
486 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
487 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
488 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
489 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
490 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
491 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
492 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
493 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
494 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
495 	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
496 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
497 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
498 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
499 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
500 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
501 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
502 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
503 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
504 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
505 	/* pipe-grf */
506 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
507 	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
508 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
509 	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
510 	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
511 };
512 
513 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
514 	.grfcfg		= &rk3568_combphy_grfcfgs,
515 	.combphy_cfg	= rk3568_combphy_cfg,
516 };
517 
518 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
519 {
520 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
521 	u32 val;
522 
523 	switch (priv->mode) {
524 	case PHY_TYPE_PCIE:
525 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
526 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
527 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
528 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
529 		break;
530 	case PHY_TYPE_USB3:
531 		/* Set SSC downward spread spectrum */
532 		val = readl(priv->mmio + (0x1f << 2));
533 		val &= ~GENMASK(5, 4);
534 		val |= 0x01 << 4;
535 		writel(val, priv->mmio + 0x7c);
536 
537 		/* Enable adaptive CTLE for USB3.0 Rx */
538 		val = readl(priv->mmio + (0x0e << 2));
539 		val &= ~GENMASK(0, 0);
540 		val |= 0x01;
541 		writel(val, priv->mmio + (0x0e << 2));
542 
543 		/* Set PLL KVCO fine tuning signals */
544 		val = readl(priv->mmio + (0x20 << 2));
545 		val &= ~(0x7 << 2);
546 		val |= 0x2 << 2;
547 		writel(val, priv->mmio + (0x20 << 2));
548 
549 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
550 		writel(0x4, priv->mmio + (0xb << 2));
551 
552 		/* Set PLL input clock divider 1/2 */
553 		val = readl(priv->mmio + (0x5 << 2));
554 		val &= ~(0x3 << 6);
555 		val |= 0x1 << 6;
556 		writel(val, priv->mmio + (0x5 << 2));
557 
558 		/* Set PLL loop divider */
559 		writel(0x32, priv->mmio + (0x11 << 2));
560 
561 		/* Set PLL KVCO to min and set PLL charge pump current to max */
562 		writel(0xf0, priv->mmio + (0xa << 2));
563 
564 		/* Set Rx squelch input filler bandwidth */
565 		writel(0x0d, priv->mmio + (0x14 << 2));
566 
567 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
568 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
569 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
570 		break;
571 	case PHY_TYPE_SATA:
572 		/* Enable adaptive CTLE for SATA Rx */
573 		val = readl(priv->mmio + (0x0e << 2));
574 		val &= ~GENMASK(0, 0);
575 		val |= 0x01;
576 		writel(val, priv->mmio + (0x0e << 2));
577 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
578 		writel(0x8F, priv->mmio + (0x06 << 2));
579 
580 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
581 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
582 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
583 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
584 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
585 		param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
586 		break;
587 	case PHY_TYPE_SGMII:
588 	case PHY_TYPE_QSGMII:
589 	default:
590 		dev_err(priv->dev, "incompatible PHY type\n");
591 		return -EINVAL;
592 	}
593 
594 	/* 100MHz refclock signal is good */
595 	clk_set_rate(&priv->ref_clk, 100000000);
596 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
597 	if (priv->mode == PHY_TYPE_PCIE) {
598 		/* PLL KVCO tuning fine */
599 		val = readl(priv->mmio + (0x20 << 2));
600 		val &= ~GENMASK(4, 2);
601 		val |= 0x4 << 2;
602 		writel(val, priv->mmio + (0x20 << 2));
603 
604 		/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
605 		val = 0x4c;
606 		writel(val, priv->mmio + (0x1b << 2));
607 
608 		/* Set up su_trim: T3 */
609 		val = 0xb0;
610 		writel(val, priv->mmio + (0xa << 2));
611 		val = 0x47;
612 		writel(val, priv->mmio + (0xb << 2));
613 		val = 0x57;
614 		writel(val, priv->mmio + (0xd << 2));
615 	}
616 
617 	return 0;
618 }
619 
620 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
621 	/* pipe-phy-grf */
622 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
623 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
624 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
625 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
626 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
627 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
628 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
629 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
630 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
631 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
632 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
633 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
634 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
635 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
636 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
637 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
638 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
639 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
640 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
641 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
642 	/* pipe-grf */
643 	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
644 	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
645 };
646 
647 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
648 	.grfcfg		= &rk3588_combphy_grfcfgs,
649 	.combphy_cfg	= rk3588_combphy_cfg,
650 };
651 
652 static const struct udevice_id rockchip_combphy_ids[] = {
653 	{
654 		.compatible = "rockchip,rk3528-naneng-combphy",
655 		.data = (ulong)&rk3528_combphy_cfgs
656 	},
657 	{
658 		.compatible = "rockchip,rk3568-naneng-combphy",
659 		.data = (ulong)&rk3568_combphy_cfgs
660 	},
661 	{
662 		.compatible = "rockchip,rk3588-naneng-combphy",
663 		.data = (ulong)&rk3588_combphy_cfgs
664 	},
665 	{ }
666 };
667 
668 U_BOOT_DRIVER(rockchip_naneng_combphy) = {
669 	.name		= "naneng-combphy",
670 	.id		= UCLASS_PHY,
671 	.of_match	= rockchip_combphy_ids,
672 	.ops		= &rochchip_combphy_ops,
673 	.probe		= rockchip_combphy_probe,
674 	.priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv),
675 };
676