xref: /linux/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c (revision df02351331671abb26788bc13f6d276e26ae068f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver
4  *
5  * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
6  */
7 
8 #include <dt-bindings/phy/phy.h>
9 #include <linux/clk.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/of.h>
12 #include <linux/phy/phy.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 #include <linux/reset.h>
16 #include <linux/units.h>
17 
18 #define BIT_WRITEABLE_SHIFT		16
19 #define REF_CLOCK_24MHz			(24 * HZ_PER_MHZ)
20 #define REF_CLOCK_25MHz			(25 * HZ_PER_MHZ)
21 #define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
22 
23 /* COMBO PHY REG */
24 #define PHYREG6				0x14
25 #define PHYREG6_PLL_DIV_MASK		GENMASK(7, 6)
26 #define PHYREG6_PLL_DIV_SHIFT		6
27 #define PHYREG6_PLL_DIV_2		1
28 
29 #define PHYREG7				0x18
30 #define PHYREG7_TX_RTERM_MASK		GENMASK(7, 4)
31 #define PHYREG7_TX_RTERM_SHIFT		4
32 #define PHYREG7_TX_RTERM_50OHM		8
33 #define PHYREG7_RX_RTERM_MASK		GENMASK(3, 0)
34 #define PHYREG7_RX_RTERM_SHIFT		0
35 #define PHYREG7_RX_RTERM_44OHM		15
36 
37 #define PHYREG8				0x1C
38 #define PHYREG8_SSC_EN			BIT(4)
39 
40 #define PHYREG10			0x24
41 #define PHYREG10_SSC_PCM_MASK		GENMASK(3, 0)
42 #define PHYREG10_SSC_PCM_3500PPM	7
43 
44 #define PHYREG11			0x28
45 #define PHYREG11_SU_TRIM_0_7		0xF0
46 
47 #define PHYREG12			0x2C
48 #define PHYREG12_PLL_LPF_ADJ_VALUE	4
49 
50 #define PHYREG13			0x30
51 #define PHYREG13_RESISTER_MASK		GENMASK(5, 4)
52 #define PHYREG13_RESISTER_SHIFT		0x4
53 #define PHYREG13_RESISTER_HIGH_Z	3
54 #define PHYREG13_CKRCV_AMP0		BIT(7)
55 
56 #define PHYREG14			0x34
57 #define PHYREG14_CKRCV_AMP1		BIT(0)
58 
59 #define PHYREG15			0x38
60 #define PHYREG15_CTLE_EN		BIT(0)
61 #define PHYREG15_SSC_CNT_MASK		GENMASK(7, 6)
62 #define PHYREG15_SSC_CNT_SHIFT		6
63 #define PHYREG15_SSC_CNT_VALUE		1
64 
65 #define PHYREG16			0x3C
66 #define PHYREG16_SSC_CNT_VALUE		0x5f
67 
68 #define PHYREG17			0x40
69 
70 #define PHYREG18			0x44
71 #define PHYREG18_PLL_LOOP		0x32
72 
73 #define PHYREG21			0x50
74 #define PHYREG21_RX_SQUELCH_VAL		0x0D
75 
76 #define PHYREG27			0x6C
77 #define PHYREG27_RX_TRIM_RK3588		0x4C
78 
79 #define PHYREG30			0x74
80 
81 #define PHYREG32			0x7C
82 #define PHYREG32_SSC_MASK		GENMASK(7, 4)
83 #define PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
84 #define PHYREG32_SSC_DIR_SHIFT		4
85 #define PHYREG32_SSC_UPWARD		0
86 #define PHYREG32_SSC_DOWNWARD		1
87 #define PHYREG32_SSC_OFFSET_MASK	GENMASK(7, 6)
88 #define PHYREG32_SSC_OFFSET_SHIFT	6
89 #define PHYREG32_SSC_OFFSET_500PPM	1
90 
91 #define PHYREG33			0x80
92 #define PHYREG33_PLL_KVCO_MASK		GENMASK(4, 2)
93 #define PHYREG33_PLL_KVCO_SHIFT		2
94 #define PHYREG33_PLL_KVCO_VALUE		2
95 #define PHYREG33_PLL_KVCO_VALUE_RK3576	4
96 
97 struct rockchip_combphy_priv;
98 
99 struct combphy_reg {
100 	u16 offset;
101 	u16 bitend;
102 	u16 bitstart;
103 	u16 disable;
104 	u16 enable;
105 };
106 
107 struct rockchip_combphy_grfcfg {
108 	struct combphy_reg pcie_mode_set;
109 	struct combphy_reg usb_mode_set;
110 	struct combphy_reg sgmii_mode_set;
111 	struct combphy_reg qsgmii_mode_set;
112 	struct combphy_reg pipe_rxterm_set;
113 	struct combphy_reg pipe_txelec_set;
114 	struct combphy_reg pipe_txcomp_set;
115 	struct combphy_reg pipe_clk_24m;
116 	struct combphy_reg pipe_clk_25m;
117 	struct combphy_reg pipe_clk_100m;
118 	struct combphy_reg pipe_phymode_sel;
119 	struct combphy_reg pipe_rate_sel;
120 	struct combphy_reg pipe_rxterm_sel;
121 	struct combphy_reg pipe_txelec_sel;
122 	struct combphy_reg pipe_txcomp_sel;
123 	struct combphy_reg pipe_clk_ext;
124 	struct combphy_reg pipe_sel_usb;
125 	struct combphy_reg pipe_sel_qsgmii;
126 	struct combphy_reg pipe_phy_status;
127 	struct combphy_reg con0_for_pcie;
128 	struct combphy_reg con1_for_pcie;
129 	struct combphy_reg con2_for_pcie;
130 	struct combphy_reg con3_for_pcie;
131 	struct combphy_reg con0_for_sata;
132 	struct combphy_reg con1_for_sata;
133 	struct combphy_reg con2_for_sata;
134 	struct combphy_reg con3_for_sata;
135 	struct combphy_reg pipe_con0_for_sata;
136 	struct combphy_reg pipe_con1_for_sata;
137 	struct combphy_reg pipe_xpcs_phy_ready;
138 	struct combphy_reg pipe_pcie1l0_sel;
139 	struct combphy_reg pipe_pcie1l1_sel;
140 };
141 
142 struct rockchip_combphy_cfg {
143 	unsigned int num_phys;
144 	unsigned int phy_ids[3];
145 	const struct rockchip_combphy_grfcfg *grfcfg;
146 	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
147 };
148 
149 struct rockchip_combphy_priv {
150 	u8 type;
151 	int id;
152 	void __iomem *mmio;
153 	int num_clks;
154 	struct clk_bulk_data *clks;
155 	struct device *dev;
156 	struct regmap *pipe_grf;
157 	struct regmap *phy_grf;
158 	struct phy *phy;
159 	struct reset_control *phy_rst;
160 	const struct rockchip_combphy_cfg *cfg;
161 	bool enable_ssc;
162 	bool ext_refclk;
163 	struct clk *refclk;
164 };
165 
rockchip_combphy_updatel(struct rockchip_combphy_priv * priv,int mask,int val,int reg)166 static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,
167 				     int mask, int val, int reg)
168 {
169 	unsigned int temp;
170 
171 	temp = readl(priv->mmio + reg);
172 	temp = (temp & ~(mask)) | val;
173 	writel(temp, priv->mmio + reg);
174 }
175 
rockchip_combphy_param_write(struct regmap * base,const struct combphy_reg * reg,bool en)176 static int rockchip_combphy_param_write(struct regmap *base,
177 					const struct combphy_reg *reg, bool en)
178 {
179 	u32 val, mask, tmp;
180 
181 	tmp = en ? reg->enable : reg->disable;
182 	mask = GENMASK(reg->bitend, reg->bitstart);
183 	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
184 
185 	return regmap_write(base, reg->offset, val);
186 }
187 
rockchip_combphy_is_ready(struct rockchip_combphy_priv * priv)188 static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
189 {
190 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
191 	u32 mask, val;
192 
193 	mask = GENMASK(cfg->pipe_phy_status.bitend,
194 		       cfg->pipe_phy_status.bitstart);
195 
196 	regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
197 	val = (val & mask) >> cfg->pipe_phy_status.bitstart;
198 
199 	return val;
200 }
201 
rockchip_combphy_init(struct phy * phy)202 static int rockchip_combphy_init(struct phy *phy)
203 {
204 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
205 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
206 	u32 val;
207 	int ret;
208 
209 	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
210 	if (ret) {
211 		dev_err(priv->dev, "failed to enable clks\n");
212 		return ret;
213 	}
214 
215 	switch (priv->type) {
216 	case PHY_TYPE_PCIE:
217 	case PHY_TYPE_USB3:
218 	case PHY_TYPE_SATA:
219 	case PHY_TYPE_SGMII:
220 	case PHY_TYPE_QSGMII:
221 		if (priv->cfg->combphy_cfg)
222 			ret = priv->cfg->combphy_cfg(priv);
223 		break;
224 	default:
225 		dev_err(priv->dev, "incompatible PHY type\n");
226 		ret = -EINVAL;
227 		break;
228 	}
229 
230 	if (ret) {
231 		dev_err(priv->dev, "failed to init phy for phy type %x\n", priv->type);
232 		goto err_clk;
233 	}
234 
235 	ret = reset_control_deassert(priv->phy_rst);
236 	if (ret)
237 		goto err_clk;
238 
239 	if (priv->type == PHY_TYPE_USB3) {
240 		ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready,
241 						priv, val,
242 						val == cfg->pipe_phy_status.enable,
243 						10, 1000);
244 		if (ret)
245 			dev_warn(priv->dev, "wait phy status ready timeout\n");
246 	}
247 
248 	return 0;
249 
250 err_clk:
251 	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
252 
253 	return ret;
254 }
255 
rockchip_combphy_exit(struct phy * phy)256 static int rockchip_combphy_exit(struct phy *phy)
257 {
258 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
259 
260 	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
261 	reset_control_assert(priv->phy_rst);
262 
263 	return 0;
264 }
265 
266 static const struct phy_ops rockchip_combphy_ops = {
267 	.init = rockchip_combphy_init,
268 	.exit = rockchip_combphy_exit,
269 	.owner = THIS_MODULE,
270 };
271 
rockchip_combphy_xlate(struct device * dev,const struct of_phandle_args * args)272 static struct phy *rockchip_combphy_xlate(struct device *dev, const struct of_phandle_args *args)
273 {
274 	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
275 
276 	if (args->args_count != 1) {
277 		dev_err(dev, "invalid number of arguments\n");
278 		return ERR_PTR(-EINVAL);
279 	}
280 
281 	if (priv->type != PHY_NONE && priv->type != args->args[0])
282 		dev_warn(dev, "phy type select %d overwriting type %d\n",
283 			 args->args[0], priv->type);
284 
285 	priv->type = args->args[0];
286 
287 	return priv->phy;
288 }
289 
rockchip_combphy_parse_dt(struct device * dev,struct rockchip_combphy_priv * priv)290 static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv)
291 {
292 	int i;
293 
294 	priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
295 	if (priv->num_clks < 1)
296 		return -EINVAL;
297 
298 	priv->refclk = NULL;
299 	for (i = 0; i < priv->num_clks; i++) {
300 		if (!strncmp(priv->clks[i].id, "ref", 3)) {
301 			priv->refclk = priv->clks[i].clk;
302 			break;
303 		}
304 	}
305 
306 	if (!priv->refclk) {
307 		dev_err(dev, "no refclk found\n");
308 		return -EINVAL;
309 	}
310 
311 	priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf");
312 	if (IS_ERR(priv->pipe_grf)) {
313 		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
314 		return PTR_ERR(priv->pipe_grf);
315 	}
316 
317 	priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf");
318 	if (IS_ERR(priv->phy_grf)) {
319 		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
320 		return PTR_ERR(priv->phy_grf);
321 	}
322 
323 	priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc");
324 
325 	priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
326 
327 	priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy");
328 	/* fallback to old behaviour */
329 	if (PTR_ERR(priv->phy_rst) == -ENOENT)
330 		priv->phy_rst = devm_reset_control_array_get_exclusive(dev);
331 	if (IS_ERR(priv->phy_rst))
332 		return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n");
333 
334 	return 0;
335 }
336 
rockchip_combphy_probe(struct platform_device * pdev)337 static int rockchip_combphy_probe(struct platform_device *pdev)
338 {
339 	struct phy_provider *phy_provider;
340 	struct device *dev = &pdev->dev;
341 	struct rockchip_combphy_priv *priv;
342 	const struct rockchip_combphy_cfg *phy_cfg;
343 	struct resource *res;
344 	int ret, id;
345 
346 	phy_cfg = of_device_get_match_data(dev);
347 	if (!phy_cfg) {
348 		dev_err(dev, "no OF match data provided\n");
349 		return -EINVAL;
350 	}
351 
352 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
353 	if (!priv)
354 		return -ENOMEM;
355 
356 	priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
357 	if (IS_ERR(priv->mmio)) {
358 		ret = PTR_ERR(priv->mmio);
359 		return ret;
360 	}
361 
362 	/* find the phy-id from the io address */
363 	priv->id = -ENODEV;
364 	for (id = 0; id < phy_cfg->num_phys; id++) {
365 		if (res->start == phy_cfg->phy_ids[id]) {
366 			priv->id = id;
367 			break;
368 		}
369 	}
370 
371 	priv->dev = dev;
372 	priv->type = PHY_NONE;
373 	priv->cfg = phy_cfg;
374 
375 	ret = rockchip_combphy_parse_dt(dev, priv);
376 	if (ret)
377 		return ret;
378 
379 	ret = reset_control_assert(priv->phy_rst);
380 	if (ret) {
381 		dev_err(dev, "failed to reset phy\n");
382 		return ret;
383 	}
384 
385 	priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
386 	if (IS_ERR(priv->phy)) {
387 		dev_err(dev, "failed to create combphy\n");
388 		return PTR_ERR(priv->phy);
389 	}
390 
391 	dev_set_drvdata(dev, priv);
392 	phy_set_drvdata(priv->phy, priv);
393 
394 	phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate);
395 
396 	return PTR_ERR_OR_ZERO(phy_provider);
397 }
398 
rk3562_combphy_cfg(struct rockchip_combphy_priv * priv)399 static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
400 {
401 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
402 	unsigned long rate;
403 	u32 val;
404 
405 	switch (priv->type) {
406 	case PHY_TYPE_PCIE:
407 		/* Set SSC downward spread spectrum */
408 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
409 					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
410 					 PHYREG32);
411 
412 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
413 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
414 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
415 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
416 		break;
417 	case PHY_TYPE_USB3:
418 		/* Set SSC downward spread spectrum */
419 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
420 					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
421 					 PHYREG32);
422 
423 		/* Enable adaptive CTLE for USB3.0 Rx */
424 		rockchip_combphy_updatel(priv, PHYREG15_CTLE_EN,
425 					 PHYREG15_CTLE_EN, PHYREG15);
426 
427 		/* Set PLL KVCO fine tuning signals */
428 		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
429 
430 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
431 		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
432 
433 		/* Set PLL input clock divider 1/2 */
434 		val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
435 		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
436 
437 		/* Set PLL loop divider */
438 		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
439 
440 		/* Set PLL KVCO to min and set PLL charge pump current to max */
441 		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
442 
443 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
444 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
445 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
446 		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
447 		break;
448 	default:
449 		dev_err(priv->dev, "incompatible PHY type\n");
450 		return -EINVAL;
451 	}
452 
453 	rate = clk_get_rate(priv->refclk);
454 
455 	switch (rate) {
456 	case REF_CLOCK_24MHz:
457 		if (priv->type == PHY_TYPE_USB3) {
458 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
459 			val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
460 			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
461 						 val, PHYREG15);
462 
463 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
464 		}
465 		break;
466 	case REF_CLOCK_25MHz:
467 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
468 		break;
469 	case REF_CLOCK_100MHz:
470 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
471 		if (priv->type == PHY_TYPE_PCIE) {
472 			/* PLL KVCO tuning fine */
473 			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE);
474 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
475 						 val, PHYREG33);
476 
477 			/* Enable controlling random jitter, aka RMJ */
478 			writel(0x4, priv->mmio + PHYREG12);
479 
480 			val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT;
481 			rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
482 						 val, PHYREG6);
483 
484 			writel(0x32, priv->mmio + PHYREG18);
485 			writel(0xf0, priv->mmio + PHYREG11);
486 		}
487 		break;
488 	default:
489 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
490 		return -EINVAL;
491 	}
492 
493 	if (priv->ext_refclk) {
494 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
495 		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
496 			val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
497 			val |= PHYREG13_CKRCV_AMP0;
498 			rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
499 
500 			val = readl(priv->mmio + PHYREG14);
501 			val |= PHYREG14_CKRCV_AMP1;
502 			writel(val, priv->mmio + PHYREG14);
503 		}
504 	}
505 
506 	if (priv->enable_ssc) {
507 		val = readl(priv->mmio + PHYREG8);
508 		val |= PHYREG8_SSC_EN;
509 		writel(val, priv->mmio + PHYREG8);
510 	}
511 
512 	return 0;
513 }
514 
515 static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = {
516 	/* pipe-phy-grf */
517 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
518 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
519 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
520 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
521 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
522 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
523 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
524 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
525 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
526 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
527 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
528 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
529 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
530 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
531 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
532 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
533 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
534 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
535 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
536 };
537 
538 static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = {
539 	.num_phys = 1,
540 	.phy_ids = {
541 		0xff750000
542 	},
543 	.grfcfg		= &rk3562_combphy_grfcfgs,
544 	.combphy_cfg	= rk3562_combphy_cfg,
545 };
546 
rk3568_combphy_cfg(struct rockchip_combphy_priv * priv)547 static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
548 {
549 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
550 	unsigned long rate;
551 	u32 val;
552 
553 	switch (priv->type) {
554 	case PHY_TYPE_PCIE:
555 		/* Set SSC downward spread spectrum. */
556 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
557 					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
558 					 PHYREG32);
559 
560 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
561 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
562 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
563 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
564 		break;
565 
566 	case PHY_TYPE_USB3:
567 		/* Set SSC downward spread spectrum. */
568 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
569 					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
570 					 PHYREG32);
571 
572 		/* Enable adaptive CTLE for USB3.0 Rx. */
573 		val = readl(priv->mmio + PHYREG15);
574 		val |= PHYREG15_CTLE_EN;
575 		writel(val, priv->mmio + PHYREG15);
576 
577 		/* Set PLL KVCO fine tuning signals. */
578 		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
579 					 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
580 					 PHYREG33);
581 
582 		/* Enable controlling random jitter. */
583 		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
584 
585 		/* Set PLL input clock divider 1/2. */
586 		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
587 					 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
588 					 PHYREG6);
589 
590 		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
591 		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
592 
593 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
594 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
595 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
596 		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
597 		break;
598 
599 	case PHY_TYPE_SATA:
600 		/* Enable adaptive CTLE for SATA Rx. */
601 		val = readl(priv->mmio + PHYREG15);
602 		val |= PHYREG15_CTLE_EN;
603 		writel(val, priv->mmio + PHYREG15);
604 		/*
605 		 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
606 		 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
607 		 */
608 		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
609 		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
610 		writel(val, priv->mmio + PHYREG7);
611 
612 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
613 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
614 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
615 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
616 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
617 		break;
618 
619 	case PHY_TYPE_SGMII:
620 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
621 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
622 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
623 		rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
624 		break;
625 
626 	case PHY_TYPE_QSGMII:
627 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
628 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
629 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
630 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
631 		rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
632 		break;
633 
634 	default:
635 		dev_err(priv->dev, "incompatible PHY type\n");
636 		return -EINVAL;
637 	}
638 
639 	rate = clk_get_rate(priv->refclk);
640 
641 	switch (rate) {
642 	case REF_CLOCK_24MHz:
643 		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
644 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
645 			val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
646 			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
647 						 val, PHYREG15);
648 
649 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
650 		}
651 		break;
652 
653 	case REF_CLOCK_25MHz:
654 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
655 		break;
656 
657 	case REF_CLOCK_100MHz:
658 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
659 		if (priv->type == PHY_TYPE_PCIE) {
660 			/* PLL KVCO  fine tuning. */
661 			val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT;
662 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
663 						 val, PHYREG33);
664 
665 			/* Enable controlling random jitter. */
666 			writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
667 
668 			val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT;
669 			rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
670 						 val, PHYREG6);
671 
672 			writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
673 			writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
674 		} else if (priv->type == PHY_TYPE_SATA) {
675 			/* downward spread spectrum +500ppm */
676 			val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
677 			val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
678 			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
679 		}
680 		break;
681 
682 	default:
683 		dev_err(priv->dev, "unsupported rate: %lu\n", rate);
684 		return -EINVAL;
685 	}
686 
687 	if (priv->ext_refclk) {
688 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
689 		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
690 			val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
691 			val |= PHYREG13_CKRCV_AMP0;
692 			rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
693 
694 			val = readl(priv->mmio + PHYREG14);
695 			val |= PHYREG14_CKRCV_AMP1;
696 			writel(val, priv->mmio + PHYREG14);
697 		}
698 	}
699 
700 	if (priv->enable_ssc) {
701 		val = readl(priv->mmio + PHYREG8);
702 		val |= PHYREG8_SSC_EN;
703 		writel(val, priv->mmio + PHYREG8);
704 	}
705 
706 	return 0;
707 }
708 
709 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
710 	/* pipe-phy-grf */
711 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
712 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
713 	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
714 	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
715 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
716 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
717 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
718 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
719 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
720 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
721 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
722 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
723 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
724 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
725 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
726 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
727 	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
728 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
729 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
730 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
731 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
732 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
733 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
734 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
735 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
736 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
737 	/* pipe-grf */
738 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
739 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
740 };
741 
742 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
743 	.num_phys = 3,
744 	.phy_ids = {
745 		0xfe820000,
746 		0xfe830000,
747 		0xfe840000,
748 	},
749 	.grfcfg		= &rk3568_combphy_grfcfgs,
750 	.combphy_cfg	= rk3568_combphy_cfg,
751 };
752 
rk3576_combphy_cfg(struct rockchip_combphy_priv * priv)753 static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
754 {
755 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
756 	unsigned long rate;
757 	u32 val;
758 
759 	switch (priv->type) {
760 	case PHY_TYPE_PCIE:
761 		/* Set SSC downward spread spectrum */
762 		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
763 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
764 
765 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
766 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
767 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
768 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
769 		break;
770 
771 	case PHY_TYPE_USB3:
772 		/* Set SSC downward spread spectrum */
773 		val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
774 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
775 
776 		/* Enable adaptive CTLE for USB3.0 Rx */
777 		val = readl(priv->mmio + PHYREG15);
778 		val |= PHYREG15_CTLE_EN;
779 		writel(val, priv->mmio + PHYREG15);
780 
781 		/* Set PLL KVCO fine tuning signals */
782 		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
783 
784 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
785 		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
786 
787 		/* Set PLL input clock divider 1/2 */
788 		val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
789 		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
790 
791 		/* Set PLL loop divider */
792 		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
793 
794 		/* Set PLL KVCO to min and set PLL charge pump current to max */
795 		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
796 
797 		/* Set Rx squelch input filler bandwidth */
798 		writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21);
799 
800 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
801 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
802 		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
803 		break;
804 
805 	case PHY_TYPE_SATA:
806 		/* Enable adaptive CTLE for SATA Rx */
807 		val = readl(priv->mmio + PHYREG15);
808 		val |= PHYREG15_CTLE_EN;
809 		writel(val, priv->mmio + PHYREG15);
810 
811 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
812 		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
813 		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
814 		writel(val, priv->mmio + PHYREG7);
815 
816 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
817 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
818 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
819 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
820 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
821 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
822 		break;
823 
824 	default:
825 		dev_err(priv->dev, "incompatible PHY type\n");
826 		return -EINVAL;
827 	}
828 
829 	rate = clk_get_rate(priv->refclk);
830 
831 	switch (rate) {
832 	case REF_CLOCK_24MHz:
833 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
834 		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
835 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
836 			val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
837 			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
838 						 val, PHYREG15);
839 
840 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
841 		} else if (priv->type == PHY_TYPE_PCIE) {
842 			/* PLL KVCO tuning fine */
843 			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
844 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
845 						 val, PHYREG33);
846 
847 			/* Set up rx_pck invert and rx msb to disable */
848 			writel(0x00, priv->mmio + PHYREG27);
849 
850 			/*
851 			 * Set up SU adjust signal:
852 			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
853 			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b011
854 			 * su_trim[31:24], CKDRV adjust
855 			 */
856 			writel(0x90, priv->mmio + PHYREG11);
857 			writel(0x02, priv->mmio + PHYREG12);
858 			writel(0x57, priv->mmio + PHYREG14);
859 
860 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
861 		}
862 		break;
863 
864 	case REF_CLOCK_25MHz:
865 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
866 		break;
867 
868 	case REF_CLOCK_100MHz:
869 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
870 		if (priv->type == PHY_TYPE_PCIE) {
871 			/* gate_tx_pck_sel length select work for L1SS */
872 			writel(0xc0, priv->mmio + PHYREG30);
873 
874 			/* PLL KVCO tuning fine */
875 			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
876 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
877 						 val, PHYREG33);
878 
879 			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
880 			writel(0x4c, priv->mmio + PHYREG27);
881 
882 			/*
883 			 * Set up SU adjust signal:
884 			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
885 			 * su_trim[15:8],  bypass PLL loop divider code, and
886 			 *                 PLL LPF R1 adujst bits[9:7]=3'b101
887 			 * su_trim[23:16], CKRCV adjust
888 			 * su_trim[31:24], CKDRV adjust
889 			 */
890 			writel(0x90, priv->mmio + PHYREG11);
891 			writel(0x43, priv->mmio + PHYREG12);
892 			writel(0x88, priv->mmio + PHYREG13);
893 			writel(0x56, priv->mmio + PHYREG14);
894 		} else if (priv->type == PHY_TYPE_SATA) {
895 			/* downward spread spectrum +500ppm */
896 			val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD);
897 			val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM);
898 			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
899 
900 			/* ssc ppm adjust to 3500ppm */
901 			rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK,
902 						 PHYREG10_SSC_PCM_3500PPM,
903 						 PHYREG10);
904 		}
905 		break;
906 
907 	default:
908 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
909 		return -EINVAL;
910 	}
911 
912 	if (priv->ext_refclk) {
913 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
914 		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
915 			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
916 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
917 						 val, PHYREG33);
918 
919 			/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
920 			writel(0x0c, priv->mmio + PHYREG27);
921 
922 			/*
923 			 * Set up SU adjust signal:
924 			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
925 			 * su_trim[15:8],  bypass PLL loop divider code, and
926 			 *                 PLL LPF R1 adujst bits[9:7]=3'b101.
927 			 * su_trim[23:16], CKRCV adjust
928 			 * su_trim[31:24], CKDRV adjust
929 			 */
930 			writel(0x90, priv->mmio + PHYREG11);
931 			writel(0x43, priv->mmio + PHYREG12);
932 			writel(0x88, priv->mmio + PHYREG13);
933 			writel(0x56, priv->mmio + PHYREG14);
934 		}
935 	}
936 
937 	if (priv->enable_ssc) {
938 		val = readl(priv->mmio + PHYREG8);
939 		val |= PHYREG8_SSC_EN;
940 		writel(val, priv->mmio + PHYREG8);
941 
942 		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
943 			/* Set PLL loop divider */
944 			writel(0x00, priv->mmio + PHYREG17);
945 			writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
946 
947 			/* Set up rx_pck invert and rx msb to disable */
948 			writel(0x00, priv->mmio + PHYREG27);
949 
950 			/*
951 			 * Set up SU adjust signal:
952 			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
953 			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b101
954 			 * su_trim[23:16], CKRCV adjust
955 			 * su_trim[31:24], CKDRV adjust
956 			 */
957 			writel(0x90, priv->mmio + PHYREG11);
958 			writel(0x02, priv->mmio + PHYREG12);
959 			writel(0x08, priv->mmio + PHYREG13);
960 			writel(0x57, priv->mmio + PHYREG14);
961 			writel(0x40, priv->mmio + PHYREG15);
962 
963 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
964 
965 			val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
966 			writel(val, priv->mmio + PHYREG33);
967 		}
968 	}
969 
970 	return 0;
971 }
972 
973 static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
974 	/* pipe-phy-grf */
975 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
976 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
977 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
978 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
979 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
980 	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
981 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
982 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
983 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
984 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
985 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
986 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
987 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
988 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
989 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
990 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
991 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
992 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
993 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
994 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
995 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
996 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
997 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
998 	/* php-grf */
999 	.pipe_con0_for_sata	= { 0x001C, 2, 0, 0x00, 0x2 },
1000 	.pipe_con1_for_sata	= { 0x0020, 2, 0, 0x00, 0x2 },
1001 };
1002 
1003 static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
1004 	.num_phys = 2,
1005 	.phy_ids = {
1006 		0x2b050000,
1007 		0x2b060000
1008 	},
1009 	.grfcfg		= &rk3576_combphy_grfcfgs,
1010 	.combphy_cfg	= rk3576_combphy_cfg,
1011 };
1012 
rk3588_combphy_cfg(struct rockchip_combphy_priv * priv)1013 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
1014 {
1015 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
1016 	unsigned long rate;
1017 	u32 val;
1018 
1019 	switch (priv->type) {
1020 	case PHY_TYPE_PCIE:
1021 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
1022 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
1023 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
1024 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
1025 		switch (priv->id) {
1026 		case 1:
1027 			rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
1028 			break;
1029 		case 2:
1030 			rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);
1031 			break;
1032 		}
1033 		break;
1034 	case PHY_TYPE_USB3:
1035 		/* Set SSC downward spread spectrum */
1036 		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
1037 					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
1038 					 PHYREG32);
1039 
1040 		/* Enable adaptive CTLE for USB3.0 Rx. */
1041 		val = readl(priv->mmio + PHYREG15);
1042 		val |= PHYREG15_CTLE_EN;
1043 		writel(val, priv->mmio + PHYREG15);
1044 
1045 		/* Set PLL KVCO fine tuning signals. */
1046 		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
1047 					 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
1048 					 PHYREG33);
1049 
1050 		/* Enable controlling random jitter. */
1051 		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
1052 
1053 		/* Set PLL input clock divider 1/2. */
1054 		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
1055 					 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
1056 					 PHYREG6);
1057 
1058 		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
1059 		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
1060 
1061 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
1062 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
1063 		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
1064 		break;
1065 	case PHY_TYPE_SATA:
1066 		/* Enable adaptive CTLE for SATA Rx. */
1067 		val = readl(priv->mmio + PHYREG15);
1068 		val |= PHYREG15_CTLE_EN;
1069 		writel(val, priv->mmio + PHYREG15);
1070 		/*
1071 		 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
1072 		 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
1073 		 */
1074 		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
1075 		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
1076 		writel(val, priv->mmio + PHYREG7);
1077 
1078 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
1079 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
1080 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
1081 		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
1082 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
1083 		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
1084 		break;
1085 	case PHY_TYPE_SGMII:
1086 	case PHY_TYPE_QSGMII:
1087 	default:
1088 		dev_err(priv->dev, "incompatible PHY type\n");
1089 		return -EINVAL;
1090 	}
1091 
1092 	rate = clk_get_rate(priv->refclk);
1093 
1094 	switch (rate) {
1095 	case REF_CLOCK_24MHz:
1096 		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
1097 			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
1098 			val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
1099 			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
1100 						 val, PHYREG15);
1101 
1102 			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
1103 		}
1104 		break;
1105 
1106 	case REF_CLOCK_25MHz:
1107 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
1108 		break;
1109 	case REF_CLOCK_100MHz:
1110 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
1111 		if (priv->type == PHY_TYPE_PCIE) {
1112 			/* PLL KVCO fine tuning. */
1113 			val = 4 << PHYREG33_PLL_KVCO_SHIFT;
1114 			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
1115 						 val, PHYREG33);
1116 
1117 			/* Enable controlling random jitter. */
1118 			writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
1119 
1120 			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
1121 			writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27);
1122 
1123 			/* Set up su_trim:  */
1124 			writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
1125 		} else if (priv->type == PHY_TYPE_SATA) {
1126 			/* downward spread spectrum +500ppm */
1127 			val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
1128 			val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
1129 			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
1130 		}
1131 		break;
1132 	default:
1133 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
1134 		return -EINVAL;
1135 	}
1136 
1137 	if (priv->ext_refclk) {
1138 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
1139 		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
1140 			val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
1141 			val |= PHYREG13_CKRCV_AMP0;
1142 			rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
1143 
1144 			val = readl(priv->mmio + PHYREG14);
1145 			val |= PHYREG14_CKRCV_AMP1;
1146 			writel(val, priv->mmio + PHYREG14);
1147 		}
1148 	}
1149 
1150 	if (priv->enable_ssc) {
1151 		val = readl(priv->mmio + PHYREG8);
1152 		val |= PHYREG8_SSC_EN;
1153 		writel(val, priv->mmio + PHYREG8);
1154 	}
1155 
1156 	return 0;
1157 }
1158 
1159 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
1160 	/* pipe-phy-grf */
1161 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
1162 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
1163 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
1164 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
1165 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
1166 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
1167 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
1168 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
1169 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
1170 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
1171 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
1172 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
1173 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
1174 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
1175 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
1176 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
1177 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
1178 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
1179 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
1180 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
1181 	/* pipe-grf */
1182 	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
1183 	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
1184 	.pipe_pcie1l0_sel	= { 0x0100, 0, 0, 0x01, 0x0 },
1185 	.pipe_pcie1l1_sel	= { 0x0100, 1, 1, 0x01, 0x0 },
1186 };
1187 
1188 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
1189 	.num_phys = 3,
1190 	.phy_ids = {
1191 		0xfee00000,
1192 		0xfee10000,
1193 		0xfee20000,
1194 	},
1195 	.grfcfg		= &rk3588_combphy_grfcfgs,
1196 	.combphy_cfg	= rk3588_combphy_cfg,
1197 };
1198 
1199 static const struct of_device_id rockchip_combphy_of_match[] = {
1200 	{
1201 		.compatible = "rockchip,rk3562-naneng-combphy",
1202 		.data = &rk3562_combphy_cfgs,
1203 	},
1204 	{
1205 		.compatible = "rockchip,rk3568-naneng-combphy",
1206 		.data = &rk3568_combphy_cfgs,
1207 	},
1208 	{
1209 		.compatible = "rockchip,rk3576-naneng-combphy",
1210 		.data = &rk3576_combphy_cfgs,
1211 	},
1212 	{
1213 		.compatible = "rockchip,rk3588-naneng-combphy",
1214 		.data = &rk3588_combphy_cfgs,
1215 	},
1216 	{ },
1217 };
1218 MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
1219 
1220 static struct platform_driver rockchip_combphy_driver = {
1221 	.probe	= rockchip_combphy_probe,
1222 	.driver = {
1223 		.name = "rockchip-naneng-combphy",
1224 		.of_match_table = rockchip_combphy_of_match,
1225 	},
1226 };
1227 module_platform_driver(rockchip_combphy_driver);
1228 
1229 MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
1230 MODULE_LICENSE("GPL v2");
1231