• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip PIPE USB3.0 PCIE SATA combphy driver
4  *
5  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/delay.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/phy/phy.h>
17 #include <linux/regmap.h>
18 #include <linux/reset.h>
19 #include <dt-bindings/phy/phy.h>
20 
21 #define BIT_WRITEABLE_SHIFT		16
22 
23 struct rockchip_combphy_priv;
24 
25 struct combphy_reg {
26 	u16 offset;
27 	u16 bitend;
28 	u16 bitstart;
29 	u16 disable;
30 	u16 enable;
31 };
32 
33 struct rockchip_combphy_grfcfg {
34 	struct combphy_reg pcie_mode_set;
35 	struct combphy_reg usb_mode_set;
36 	struct combphy_reg sgmii_mode_set;
37 	struct combphy_reg qsgmii_mode_set;
38 	struct combphy_reg pipe_rxterm_set;
39 	struct combphy_reg pipe_txelec_set;
40 	struct combphy_reg pipe_txcomp_set;
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 int num_clks;
70 	const struct clk_bulk_data *clks;
71 	const struct rockchip_combphy_grfcfg *grfcfg;
72 	bool force_det_out; /* Tx detect Rx errata */
73 	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
74 };
75 
76 struct rockchip_combphy_priv {
77 	u8 mode;
78 	void __iomem *mmio;
79 	int num_clks;
80 	struct clk_bulk_data *clks;
81 	struct device *dev;
82 	struct regmap *pipe_grf;
83 	struct regmap *phy_grf;
84 	struct phy *phy;
85 	struct reset_control *apb_rst;
86 	struct reset_control *phy_rst;
87 	const struct rockchip_combphy_cfg *cfg;
88 };
89 
param_read(struct regmap * base,const struct combphy_reg * reg,u32 val)90 static inline bool param_read(struct regmap *base,
91 			      const struct combphy_reg *reg, u32 val)
92 {
93 	int ret;
94 	u32 mask, orig, tmp;
95 
96 	ret = regmap_read(base, reg->offset, &orig);
97 	if (ret)
98 		return false;
99 
100 	mask = GENMASK(reg->bitend, reg->bitstart);
101 	tmp = (orig & mask) >> reg->bitstart;
102 
103 	return tmp == val;
104 }
105 
param_write(struct regmap * base,const struct combphy_reg * reg,bool en)106 static int param_write(struct regmap *base,
107 		       const struct combphy_reg *reg, bool en)
108 {
109 	u32 val, mask, tmp;
110 
111 	tmp = en ? reg->enable : reg->disable;
112 	mask = GENMASK(reg->bitend, reg->bitstart);
113 	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
114 
115 	return regmap_write(base, reg->offset, val);
116 }
117 
rockchip_combphy_is_ready(struct rockchip_combphy_priv * priv)118 static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
119 {
120 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
121 	u32 mask, val;
122 
123 	mask = GENMASK(cfg->pipe_phy_status.bitend,
124 		       cfg->pipe_phy_status.bitstart);
125 
126 	regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
127 	val = (val & mask) >> cfg->pipe_phy_status.bitstart;
128 
129 	return val;
130 }
131 
rockchip_combphy_pcie_init(struct rockchip_combphy_priv * priv)132 static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv)
133 {
134 	int ret = 0;
135 	u32 val;
136 
137 	if (priv->cfg->combphy_cfg) {
138 		ret = priv->cfg->combphy_cfg(priv);
139 		if (ret) {
140 			dev_err(priv->dev, "failed to init phy for pcie\n");
141 			return ret;
142 		}
143 	}
144 
145 	if (priv->cfg->force_det_out) {
146 		val = readl(priv->mmio + (0x19 << 2));
147 		val |= BIT(5);
148 		writel(val, priv->mmio + (0x19 << 2));
149 	}
150 
151 	return ret;
152 }
153 
rockchip_combphy_usb3_init(struct rockchip_combphy_priv * priv)154 static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv)
155 {
156 	int ret = 0;
157 
158 	if (priv->cfg->combphy_cfg) {
159 		ret = priv->cfg->combphy_cfg(priv);
160 		if (ret) {
161 			dev_err(priv->dev, "failed to init phy for usb3\n");
162 			return ret;
163 		}
164 	}
165 
166 	return ret;
167 }
168 
rockchip_combphy_sata_init(struct rockchip_combphy_priv * priv)169 static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv)
170 {
171 	int ret = 0;
172 
173 	if (priv->cfg->combphy_cfg) {
174 		ret = priv->cfg->combphy_cfg(priv);
175 		if (ret) {
176 			dev_err(priv->dev, "failed to init phy for sata\n");
177 			return ret;
178 		}
179 	}
180 
181 	return ret;
182 }
183 
rockchip_combphy_sgmii_init(struct rockchip_combphy_priv * priv)184 static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv)
185 {
186 	int ret = 0;
187 
188 	if (priv->cfg->combphy_cfg) {
189 		ret = priv->cfg->combphy_cfg(priv);
190 		if (ret) {
191 			dev_err(priv->dev, "failed to init phy for sgmii\n");
192 			return ret;
193 		}
194 	}
195 
196 	return ret;
197 }
198 
rockchip_combphy_set_mode(struct rockchip_combphy_priv * priv)199 static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
200 {
201 	switch (priv->mode) {
202 	case PHY_TYPE_PCIE:
203 		rockchip_combphy_pcie_init(priv);
204 		break;
205 	case PHY_TYPE_USB3:
206 		rockchip_combphy_usb3_init(priv);
207 		break;
208 	case PHY_TYPE_SATA:
209 		rockchip_combphy_sata_init(priv);
210 		break;
211 	case PHY_TYPE_SGMII:
212 	case PHY_TYPE_QSGMII:
213 		return rockchip_combphy_sgmii_init(priv);
214 	default:
215 		dev_err(priv->dev, "incompatible PHY type\n");
216 		return -EINVAL;
217 	}
218 
219 	return 0;
220 }
221 
rockchip_combphy_init(struct phy * phy)222 static int rockchip_combphy_init(struct phy *phy)
223 {
224 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
225 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
226 	u32 val;
227 	int ret;
228 
229 	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
230 	if (ret) {
231 		dev_err(priv->dev, "failed to enable clks\n");
232 		return ret;
233 	}
234 
235 	ret = rockchip_combphy_set_mode(priv);
236 	if (ret)
237 		goto err_clk;
238 
239 	ret = reset_control_deassert(priv->phy_rst);
240 	if (ret)
241 		goto err_clk;
242 
243 	if (priv->mode == PHY_TYPE_USB3) {
244 		ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready,
245 						priv, val,
246 						val == cfg->pipe_phy_status.enable,
247 						10, 1000);
248 		if (ret)
249 			dev_warn(priv->dev, "wait phy status ready timeout\n");
250 	}
251 
252 	return 0;
253 
254 err_clk:
255 	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
256 
257 	return ret;
258 }
259 
rockchip_combphy_exit(struct phy * phy)260 static int rockchip_combphy_exit(struct phy *phy)
261 {
262 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
263 
264 	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
265 	reset_control_assert(priv->phy_rst);
266 
267 	return 0;
268 }
269 
270 static const struct phy_ops rochchip_combphy_ops = {
271 	.init = rockchip_combphy_init,
272 	.exit = rockchip_combphy_exit,
273 	.owner = THIS_MODULE,
274 };
275 
rockchip_combphy_xlate(struct device * dev,struct of_phandle_args * args)276 static struct phy *rockchip_combphy_xlate(struct device *dev,
277 					  struct of_phandle_args *args)
278 {
279 	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
280 
281 	if (args->args_count != 1) {
282 		dev_err(dev, "invalid number of arguments\n");
283 		return ERR_PTR(-EINVAL);
284 	}
285 
286 	if (priv->mode != PHY_NONE && priv->mode != args->args[0])
287 		dev_warn(dev, "phy type select %d overwriting type %d\n",
288 			 args->args[0], priv->mode);
289 
290 	priv->mode = args->args[0];
291 
292 	return priv->phy;
293 }
294 
rockchip_combphy_parse_dt(struct device * dev,struct rockchip_combphy_priv * priv)295 static int rockchip_combphy_parse_dt(struct device *dev,
296 				     struct rockchip_combphy_priv *priv)
297 {
298 	const struct rockchip_combphy_cfg *phy_cfg = priv->cfg;
299 	int ret, mac_id;
300 	u32 vals[4];
301 
302 	ret = devm_clk_bulk_get(dev, priv->num_clks, priv->clks);
303 	if (ret == -EPROBE_DEFER)
304 		return -EPROBE_DEFER;
305 	if (ret)
306 		priv->num_clks = 0;
307 
308 	priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
309 							 "rockchip,pipe-grf");
310 	if (IS_ERR(priv->pipe_grf)) {
311 		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
312 		return PTR_ERR(priv->pipe_grf);
313 	}
314 
315 	priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
316 							"rockchip,pipe-phy-grf");
317 	if (IS_ERR(priv->phy_grf)) {
318 		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
319 		return PTR_ERR(priv->phy_grf);
320 	}
321 
322 	if (device_property_present(dev, "rockchip,dis-u3otg0-port"))
323 		param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg0_port_en,
324 			    false);
325 	else if (device_property_present(dev, "rockchip,dis-u3otg1-port"))
326 		param_write(priv->pipe_grf, &phy_cfg->grfcfg->u3otg1_port_en,
327 			    false);
328 
329 	if (!device_property_read_u32(dev, "rockchip,sgmii-mac-sel", &mac_id) &&
330 	    (mac_id > 0))
331 		param_write(priv->pipe_grf, &phy_cfg->grfcfg->pipe_sgmii_mac_sel,
332 			    true);
333 
334 	if (!device_property_read_u32_array(dev, "rockchip,pcie1ln-sel-bits",
335 					    vals, ARRAY_SIZE(vals)))
336 		regmap_write(priv->pipe_grf, vals[0],
337 			     (GENMASK(vals[2], vals[1]) << 16) | (vals[3] << vals[1]));
338 
339 	priv->apb_rst = devm_reset_control_get_optional(dev, "combphy-apb");
340 	if (IS_ERR(priv->apb_rst)) {
341 		ret = PTR_ERR(priv->apb_rst);
342 
343 		if (ret != -EPROBE_DEFER)
344 			dev_warn(dev, "failed to get apb reset\n");
345 
346 		return ret;
347 	}
348 
349 	priv->phy_rst = devm_reset_control_get_optional(dev, "combphy");
350 	if (IS_ERR(priv->phy_rst)) {
351 		ret = PTR_ERR(priv->phy_rst);
352 
353 		if (ret != -EPROBE_DEFER)
354 			dev_warn(dev, "failed to get phy reset\n");
355 
356 		return ret;
357 	}
358 
359 	return reset_control_assert(priv->phy_rst);
360 }
361 
rockchip_combphy_probe(struct platform_device * pdev)362 static int rockchip_combphy_probe(struct platform_device *pdev)
363 {
364 	struct phy_provider *phy_provider;
365 	struct device *dev = &pdev->dev;
366 	struct rockchip_combphy_priv *priv;
367 	const struct rockchip_combphy_cfg *phy_cfg;
368 	struct resource *res;
369 	int ret;
370 
371 	phy_cfg = of_device_get_match_data(dev);
372 	if (!phy_cfg) {
373 		dev_err(dev, "No OF match data provided\n");
374 		return -EINVAL;
375 	}
376 
377 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
378 	if (!priv)
379 		return -ENOMEM;
380 
381 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
382 	priv->mmio = devm_ioremap_resource(dev, res);
383 	if (IS_ERR(priv->mmio)) {
384 		ret = PTR_ERR(priv->mmio);
385 		return ret;
386 	}
387 
388 	priv->num_clks = phy_cfg->num_clks;
389 
390 	priv->clks = devm_kmemdup(dev, phy_cfg->clks,
391 				  phy_cfg->num_clks * sizeof(struct clk_bulk_data),
392 				  GFP_KERNEL);
393 
394 	if (!priv->clks)
395 		return -ENOMEM;
396 
397 	priv->dev = dev;
398 	priv->mode = PHY_NONE;
399 	priv->cfg = phy_cfg;
400 
401 	ret = rockchip_combphy_parse_dt(dev, priv);
402 	if (ret)
403 		return ret;
404 
405 	priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops);
406 	if (IS_ERR(priv->phy)) {
407 		dev_err(dev, "failed to create combphy\n");
408 		return PTR_ERR(priv->phy);
409 	}
410 
411 	dev_set_drvdata(dev, priv);
412 	phy_set_drvdata(priv->phy, priv);
413 
414 	phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate);
415 
416 	return PTR_ERR_OR_ZERO(phy_provider);
417 }
418 
rk3568_combphy_cfg(struct rockchip_combphy_priv * priv)419 static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
420 {
421 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
422 	struct clk *refclk = NULL;
423 	unsigned long rate;
424 	int i;
425 	u32 val;
426 
427 	/* Configure PHY reference clock frequency */
428 	for (i = 0; i < priv->num_clks; i++) {
429 		if (!strncmp(priv->clks[i].id, "refclk", 6)) {
430 			refclk = priv->clks[i].clk;
431 			break;
432 		}
433 	}
434 
435 	if (!refclk) {
436 		dev_err(priv->dev, "No refclk found\n");
437 		return -EINVAL;
438 	}
439 
440 	switch (priv->mode) {
441 	case PHY_TYPE_PCIE:
442 		/* Set SSC downward spread spectrum */
443 		val = readl(priv->mmio + (0x1f << 2));
444 		val &= ~GENMASK(5, 4);
445 		val |= 0x01 << 4;
446 		writel(val, priv->mmio + 0x7c);
447 
448 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
449 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
450 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
451 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
452 		break;
453 	case PHY_TYPE_USB3:
454 		/* Set SSC downward spread spectrum */
455 		val = readl(priv->mmio + (0x1f << 2));
456 		val &= ~GENMASK(5, 4);
457 		val |= 0x01 << 4;
458 		writel(val, priv->mmio + 0x7c);
459 
460 		/* Enable adaptive CTLE for USB3.0 Rx */
461 		val = readl(priv->mmio + (0x0e << 2));
462 		val &= ~GENMASK(0, 0);
463 		val |= 0x01;
464 		writel(val, priv->mmio + (0x0e << 2));
465 
466 		/* Set PLL KVCO fine tuning signals */
467 		val = readl(priv->mmio + (0x20 << 2));
468 		val &= ~(0x7 << 2);
469 		val |= 0x2 << 2;
470 		writel(val, priv->mmio + (0x20 << 2));
471 
472 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
473 		writel(0x4, priv->mmio + (0xb << 2));
474 
475 		/* Set PLL input clock divider 1/2 */
476 		val = readl(priv->mmio + (0x5 << 2));
477 		val &= ~(0x3 << 6);
478 		val |= 0x1 << 6;
479 		writel(val, priv->mmio + (0x5 << 2));
480 
481 		/* Set PLL loop divider */
482 		writel(0x32, priv->mmio + (0x11 << 2));
483 
484 		/* Set PLL KVCO to min and set PLL charge pump current to max */
485 		writel(0xf0, priv->mmio + (0xa << 2));
486 
487 		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
488 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
489 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
490 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
491 		break;
492 	case PHY_TYPE_SATA:
493 		writel(0x41, priv->mmio + 0x38);
494 		writel(0x8F, priv->mmio + 0x18);
495 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
496 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
497 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
498 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
499 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
500 		break;
501 	case PHY_TYPE_SGMII:
502 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
503 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
504 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
505 		param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
506 		break;
507 	case PHY_TYPE_QSGMII:
508 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
509 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
510 		param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
511 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
512 		param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
513 		break;
514 	default:
515 		dev_err(priv->dev, "incompatible PHY type\n");
516 		return -EINVAL;
517 	}
518 
519 	rate = clk_get_rate(refclk);
520 
521 	switch (rate) {
522 	case 24000000:
523 		if (priv->mode == PHY_TYPE_USB3 || priv->mode == PHY_TYPE_SATA) {
524 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
525 			val = readl(priv->mmio + (0x0e << 2));
526 			val &= ~GENMASK(7, 6);
527 			val |= 0x01 << 6;
528 			writel(val, priv->mmio + (0x0e << 2));
529 
530 			val = readl(priv->mmio + (0x0f << 2));
531 			val &= ~GENMASK(7, 0);
532 			val |= 0x5f;
533 			writel(val, priv->mmio + (0x0f << 2));
534 		}
535 		break;
536 	case 25000000:
537 		param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
538 		break;
539 	case 100000000:
540 		param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
541 		if (priv->mode == PHY_TYPE_PCIE) {
542 			/* PLL KVCO tuning fine */
543 			val = readl(priv->mmio + (0x20 << 2));
544 			val &= ~(0x7 << 2);
545 			val |= 0x2 << 2;
546 			writel(val, priv->mmio + (0x20 << 2));
547 
548 			/* Enable controlling random jitter, aka RMJ */
549 			writel(0x4, priv->mmio + (0xb << 2));
550 
551 			val = readl(priv->mmio + (0x5 << 2));
552 			val &= ~(0x3 << 6);
553 			val |= 0x1 << 6;
554 			writel(val, priv->mmio + (0x5 << 2));
555 
556 			writel(0x32, priv->mmio + (0x11 << 2));
557 			writel(0xf0, priv->mmio + (0xa << 2));
558 		} else if (priv->mode == PHY_TYPE_SATA) {
559 			/* downward spread spectrum +500ppm */
560 			val = readl(priv->mmio + (0x1f << 2));
561 			val &= ~GENMASK(7, 4);
562 			val |= 0x50;
563 			writel(val, priv->mmio + (0x1f << 2));
564 		}
565 		break;
566 	default:
567 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
568 		return -EINVAL;
569 	}
570 
571 	if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) {
572 		param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
573 		if (priv->mode == PHY_TYPE_PCIE && rate == 100000000) {
574 			val = readl(priv->mmio + (0xc << 2));
575 			val |= 0x3 << 4 | 0x1 << 7;
576 			writel(val, priv->mmio + (0xc << 2));
577 
578 			val = readl(priv->mmio + (0xd << 2));
579 			val |= 0x1;
580 			writel(val, priv->mmio + (0xd << 2));
581 		}
582 	}
583 
584 	if (device_property_read_bool(priv->dev, "rockchip,enable-ssc")) {
585 		val = readl(priv->mmio + (0x7 << 2));
586 		val |= BIT(4);
587 		writel(val, priv->mmio + (0x7 << 2));
588 	}
589 
590 	return 0;
591 }
592 
593 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
594 	/* pipe-phy-grf */
595 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
596 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
597 	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
598 	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
599 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
600 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
601 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
602 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
603 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
604 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
605 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
606 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
607 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
608 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
609 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
610 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
611 	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
612 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
613 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
614 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
615 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
616 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
617 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
618 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
619 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
620 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
621 	/* pipe-grf */
622 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
623 	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
624 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
625 	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
626 	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
627 };
628 
629 static const struct clk_bulk_data rk3568_clks[] = {
630 	{ .id = "refclk" },
631 	{ .id = "apbclk" },
632 	{ .id = "pipe_clk" },
633 };
634 
635 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
636 	.num_clks	= ARRAY_SIZE(rk3568_clks),
637 	.clks		= rk3568_clks,
638 	.grfcfg		= &rk3568_combphy_grfcfgs,
639 	.combphy_cfg	= rk3568_combphy_cfg,
640 	.force_det_out	= true,
641 };
642 
rk3588_combphy_cfg(struct rockchip_combphy_priv * priv)643 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
644 {
645 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
646 	struct clk *refclk = NULL;
647 	unsigned long rate;
648 	int i;
649 	u32 val;
650 
651 	/* Configure PHY reference clock frequency */
652 	for (i = 0; i < priv->num_clks; i++) {
653 		if (!strncmp(priv->clks[i].id, "refclk", 6)) {
654 			refclk = priv->clks[i].clk;
655 			break;
656 		}
657 	}
658 
659 	if (!refclk) {
660 		dev_err(priv->dev, "No refclk found\n");
661 		return -EINVAL;
662 	}
663 
664 	switch (priv->mode) {
665 	case PHY_TYPE_PCIE:
666 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
667 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
668 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
669 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
670 		break;
671 	case PHY_TYPE_USB3:
672 		/* Set SSC downward spread spectrum */
673 		val = readl(priv->mmio + (0x1f << 2));
674 		val &= ~GENMASK(5, 4);
675 		val |= 0x01 << 4;
676 		writel(val, priv->mmio + 0x7c);
677 
678 		/* Enable adaptive CTLE for USB3.0 Rx */
679 		val = readl(priv->mmio + (0x0e << 2));
680 		val &= ~GENMASK(0, 0);
681 		val |= 0x01;
682 		writel(val, priv->mmio + (0x0e << 2));
683 
684 		/* Set PLL KVCO fine tuning signals */
685 		val = readl(priv->mmio + (0x20 << 2));
686 		val &= ~(0x7 << 2);
687 		val |= 0x2 << 2;
688 		writel(val, priv->mmio + (0x20 << 2));
689 
690 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
691 		writel(0x4, priv->mmio + (0xb << 2));
692 
693 		/* Set PLL input clock divider 1/2 */
694 		val = readl(priv->mmio + (0x5 << 2));
695 		val &= ~(0x3 << 6);
696 		val |= 0x1 << 6;
697 		writel(val, priv->mmio + (0x5 << 2));
698 
699 		/* Set PLL loop divider */
700 		writel(0x32, priv->mmio + (0x11 << 2));
701 
702 		/* Set PLL KVCO to min and set PLL charge pump current to max */
703 		writel(0xf0, priv->mmio + (0xa << 2));
704 
705 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
706 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
707 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
708 		break;
709 	case PHY_TYPE_SATA:
710 		/* Enable adaptive CTLE for SATA Rx */
711 		val = readl(priv->mmio + (0x0e << 2));
712 		val &= ~GENMASK(0, 0);
713 		val |= 0x01;
714 		writel(val, priv->mmio + (0x0e << 2));
715 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
716 		writel(0x8F, priv->mmio + (0x06 << 2));
717 
718 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
719 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
720 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
721 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
722 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
723 		param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
724 		break;
725 	case PHY_TYPE_SGMII:
726 	case PHY_TYPE_QSGMII:
727 	default:
728 		dev_err(priv->dev, "incompatible PHY type\n");
729 		return -EINVAL;
730 	}
731 
732 	rate = clk_get_rate(refclk);
733 
734 	switch (rate) {
735 	case 24000000:
736 		if (priv->mode == PHY_TYPE_USB3 || priv->mode == PHY_TYPE_SATA) {
737 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
738 			val = readl(priv->mmio + (0x0e << 2));
739 			val &= ~GENMASK(7, 6);
740 			val |= 0x01 << 6;
741 			writel(val, priv->mmio + (0x0e << 2));
742 
743 			val = readl(priv->mmio + (0x0f << 2));
744 			val &= ~GENMASK(7, 0);
745 			val |= 0x5f;
746 			writel(val, priv->mmio + (0x0f << 2));
747 		}
748 		break;
749 	case 25000000:
750 		param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
751 		break;
752 	case 100000000:
753 		param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
754 		if (priv->mode == PHY_TYPE_PCIE) {
755 			/* PLL KVCO tuning fine */
756 			val = readl(priv->mmio + (0x20 << 2));
757 			val &= ~GENMASK(4, 2);
758 			val |= 0x4 << 2;
759 			writel(val, priv->mmio + (0x20 << 2));
760 
761 			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
762 			val = 0x4c;
763 			writel(val, priv->mmio + (0x1b << 2));
764 
765 			/* Set up su_trim:  */
766 			val = 0xf0;
767 			writel(val, priv->mmio + (0xa << 2));
768 			val = 0x4;
769 			writel(val, priv->mmio + (0xb << 2));
770 		} else if (priv->mode == PHY_TYPE_SATA) {
771 			/* downward spread spectrum +500ppm */
772 			val = readl(priv->mmio + (0x1f << 2));
773 			val &= ~GENMASK(7, 4);
774 			val |= 0x50;
775 			writel(val, priv->mmio + (0x1f << 2));
776 		}
777 		break;
778 	default:
779 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
780 		return -EINVAL;
781 	}
782 
783 	return 0;
784 }
785 
786 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
787 	/* pipe-phy-grf */
788 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
789 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
790 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
791 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
792 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
793 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
794 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
795 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
796 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
797 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
798 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
799 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
800 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
801 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
802 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
803 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
804 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
805 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
806 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
807 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
808 	/* pipe-grf */
809 	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
810 	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
811 };
812 
813 static const struct clk_bulk_data rk3588_clks[] = {
814 	{ .id = "refclk" },
815 	{ .id = "apbclk" },
816 	{ .id = "phpclk" },
817 };
818 
819 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
820 	.num_clks	= ARRAY_SIZE(rk3588_clks),
821 	.clks		= rk3588_clks,
822 	.grfcfg		= &rk3588_combphy_grfcfgs,
823 	.combphy_cfg	= rk3588_combphy_cfg,
824 	.force_det_out	= true,
825 };
826 
827 static const struct of_device_id rockchip_combphy_of_match[] = {
828 	{
829 		.compatible = "rockchip,rk3568-naneng-combphy",
830 		.data = &rk3568_combphy_cfgs,
831 	},
832 	{
833 		.compatible = "rockchip,rk3588-naneng-combphy",
834 		.data = &rk3588_combphy_cfgs,
835 	},
836 	{ },
837 };
838 MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
839 
840 static struct platform_driver rockchip_combphy_driver = {
841 	.probe	= rockchip_combphy_probe,
842 	.driver = {
843 		.name = "naneng-combphy",
844 		.of_match_table = rockchip_combphy_of_match,
845 	},
846 };
847 module_platform_driver(rockchip_combphy_driver);
848 
849 MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
850 MODULE_LICENSE("GPL v2");
851