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
rk3568_combphy_cfg(struct rockchip_combphy_priv * priv)399 static int rk3568_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
418 case PHY_TYPE_USB3:
419 /* Set SSC downward spread spectrum. */
420 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
421 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
422 PHYREG32);
423
424 /* Enable adaptive CTLE for USB3.0 Rx. */
425 val = readl(priv->mmio + PHYREG15);
426 val |= PHYREG15_CTLE_EN;
427 writel(val, priv->mmio + PHYREG15);
428
429 /* Set PLL KVCO fine tuning signals. */
430 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
431 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
432 PHYREG33);
433
434 /* Enable controlling random jitter. */
435 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
436
437 /* Set PLL input clock divider 1/2. */
438 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
439 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
440 PHYREG6);
441
442 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
443 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
444
445 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
446 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
447 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
448 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
449 break;
450
451 case PHY_TYPE_SATA:
452 /* Enable adaptive CTLE for SATA Rx. */
453 val = readl(priv->mmio + PHYREG15);
454 val |= PHYREG15_CTLE_EN;
455 writel(val, priv->mmio + PHYREG15);
456 /*
457 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
458 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
459 */
460 val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
461 val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
462 writel(val, priv->mmio + PHYREG7);
463
464 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
465 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
466 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
467 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
468 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
469 break;
470
471 case PHY_TYPE_SGMII:
472 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
473 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
474 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
475 rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
476 break;
477
478 case PHY_TYPE_QSGMII:
479 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
480 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
481 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
482 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
483 rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
484 break;
485
486 default:
487 dev_err(priv->dev, "incompatible PHY type\n");
488 return -EINVAL;
489 }
490
491 rate = clk_get_rate(priv->refclk);
492
493 switch (rate) {
494 case REF_CLOCK_24MHz:
495 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
496 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
497 val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
498 rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
499 val, PHYREG15);
500
501 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
502 }
503 break;
504
505 case REF_CLOCK_25MHz:
506 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
507 break;
508
509 case REF_CLOCK_100MHz:
510 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
511 if (priv->type == PHY_TYPE_PCIE) {
512 /* PLL KVCO fine tuning. */
513 val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT;
514 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
515 val, PHYREG33);
516
517 /* Enable controlling random jitter. */
518 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
519
520 val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT;
521 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
522 val, PHYREG6);
523
524 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
525 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
526 } else if (priv->type == PHY_TYPE_SATA) {
527 /* downward spread spectrum +500ppm */
528 val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
529 val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
530 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
531 }
532 break;
533
534 default:
535 dev_err(priv->dev, "unsupported rate: %lu\n", rate);
536 return -EINVAL;
537 }
538
539 if (priv->ext_refclk) {
540 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
541 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
542 val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
543 val |= PHYREG13_CKRCV_AMP0;
544 rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
545
546 val = readl(priv->mmio + PHYREG14);
547 val |= PHYREG14_CKRCV_AMP1;
548 writel(val, priv->mmio + PHYREG14);
549 }
550 }
551
552 if (priv->enable_ssc) {
553 val = readl(priv->mmio + PHYREG8);
554 val |= PHYREG8_SSC_EN;
555 writel(val, priv->mmio + PHYREG8);
556 }
557
558 return 0;
559 }
560
561 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
562 /* pipe-phy-grf */
563 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
564 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
565 .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 },
566 .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 },
567 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
568 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
569 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
570 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
571 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
572 .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 },
573 .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 },
574 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
575 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
576 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
577 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
578 .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 },
579 .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 },
580 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
581 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
582 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
583 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
584 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
585 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 },
586 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 },
587 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 },
588 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 },
589 /* pipe-grf */
590 .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 },
591 .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 },
592 };
593
594 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
595 .num_phys = 3,
596 .phy_ids = {
597 0xfe820000,
598 0xfe830000,
599 0xfe840000,
600 },
601 .grfcfg = &rk3568_combphy_grfcfgs,
602 .combphy_cfg = rk3568_combphy_cfg,
603 };
604
rk3576_combphy_cfg(struct rockchip_combphy_priv * priv)605 static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
606 {
607 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
608 unsigned long rate;
609 u32 val;
610
611 switch (priv->type) {
612 case PHY_TYPE_PCIE:
613 /* Set SSC downward spread spectrum */
614 val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
615 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
616
617 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
618 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
619 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
620 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
621 break;
622
623 case PHY_TYPE_USB3:
624 /* Set SSC downward spread spectrum */
625 val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
626 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
627
628 /* Enable adaptive CTLE for USB3.0 Rx */
629 val = readl(priv->mmio + PHYREG15);
630 val |= PHYREG15_CTLE_EN;
631 writel(val, priv->mmio + PHYREG15);
632
633 /* Set PLL KVCO fine tuning signals */
634 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
635
636 /* Set PLL LPF R1 to su_trim[10:7]=1001 */
637 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
638
639 /* Set PLL input clock divider 1/2 */
640 val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
641 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
642
643 /* Set PLL loop divider */
644 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
645
646 /* Set PLL KVCO to min and set PLL charge pump current to max */
647 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
648
649 /* Set Rx squelch input filler bandwidth */
650 writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21);
651
652 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
653 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
654 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
655 break;
656
657 case PHY_TYPE_SATA:
658 /* Enable adaptive CTLE for SATA Rx */
659 val = readl(priv->mmio + PHYREG15);
660 val |= PHYREG15_CTLE_EN;
661 writel(val, priv->mmio + PHYREG15);
662
663 /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
664 val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
665 val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
666 writel(val, priv->mmio + PHYREG7);
667
668 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
669 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
670 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
671 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
672 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
673 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
674 break;
675
676 default:
677 dev_err(priv->dev, "incompatible PHY type\n");
678 return -EINVAL;
679 }
680
681 rate = clk_get_rate(priv->refclk);
682
683 switch (rate) {
684 case REF_CLOCK_24MHz:
685 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
686 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
687 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
688 val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
689 rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
690 val, PHYREG15);
691
692 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
693 } else if (priv->type == PHY_TYPE_PCIE) {
694 /* PLL KVCO tuning fine */
695 val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
696 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
697 val, PHYREG33);
698
699 /* Set up rx_pck invert and rx msb to disable */
700 writel(0x00, priv->mmio + PHYREG27);
701
702 /*
703 * Set up SU adjust signal:
704 * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
705 * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011
706 * su_trim[31:24], CKDRV adjust
707 */
708 writel(0x90, priv->mmio + PHYREG11);
709 writel(0x02, priv->mmio + PHYREG12);
710 writel(0x57, priv->mmio + PHYREG14);
711
712 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
713 }
714 break;
715
716 case REF_CLOCK_25MHz:
717 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
718 break;
719
720 case REF_CLOCK_100MHz:
721 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
722 if (priv->type == PHY_TYPE_PCIE) {
723 /* gate_tx_pck_sel length select work for L1SS */
724 writel(0xc0, priv->mmio + PHYREG30);
725
726 /* PLL KVCO tuning fine */
727 val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
728 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
729 val, PHYREG33);
730
731 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
732 writel(0x4c, priv->mmio + PHYREG27);
733
734 /*
735 * Set up SU adjust signal:
736 * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
737 * su_trim[15:8], bypass PLL loop divider code, and
738 * PLL LPF R1 adujst bits[9:7]=3'b101
739 * su_trim[23:16], CKRCV adjust
740 * su_trim[31:24], CKDRV adjust
741 */
742 writel(0x90, priv->mmio + PHYREG11);
743 writel(0x43, priv->mmio + PHYREG12);
744 writel(0x88, priv->mmio + PHYREG13);
745 writel(0x56, priv->mmio + PHYREG14);
746 } else if (priv->type == PHY_TYPE_SATA) {
747 /* downward spread spectrum +500ppm */
748 val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD);
749 val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM);
750 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
751
752 /* ssc ppm adjust to 3500ppm */
753 rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK,
754 PHYREG10_SSC_PCM_3500PPM,
755 PHYREG10);
756 }
757 break;
758
759 default:
760 dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
761 return -EINVAL;
762 }
763
764 if (priv->ext_refclk) {
765 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
766 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
767 val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
768 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
769 val, PHYREG33);
770
771 /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
772 writel(0x0c, priv->mmio + PHYREG27);
773
774 /*
775 * Set up SU adjust signal:
776 * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
777 * su_trim[15:8], bypass PLL loop divider code, and
778 * PLL LPF R1 adujst bits[9:7]=3'b101.
779 * su_trim[23:16], CKRCV adjust
780 * su_trim[31:24], CKDRV adjust
781 */
782 writel(0x90, priv->mmio + PHYREG11);
783 writel(0x43, priv->mmio + PHYREG12);
784 writel(0x88, priv->mmio + PHYREG13);
785 writel(0x56, priv->mmio + PHYREG14);
786 }
787 }
788
789 if (priv->enable_ssc) {
790 val = readl(priv->mmio + PHYREG8);
791 val |= PHYREG8_SSC_EN;
792 writel(val, priv->mmio + PHYREG8);
793
794 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
795 /* Set PLL loop divider */
796 writel(0x00, priv->mmio + PHYREG17);
797 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
798
799 /* Set up rx_pck invert and rx msb to disable */
800 writel(0x00, priv->mmio + PHYREG27);
801
802 /*
803 * Set up SU adjust signal:
804 * su_trim[7:0], PLL KVCO adjust bits[2:0] to min
805 * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b101
806 * su_trim[23:16], CKRCV adjust
807 * su_trim[31:24], CKDRV adjust
808 */
809 writel(0x90, priv->mmio + PHYREG11);
810 writel(0x02, priv->mmio + PHYREG12);
811 writel(0x08, priv->mmio + PHYREG13);
812 writel(0x57, priv->mmio + PHYREG14);
813 writel(0x40, priv->mmio + PHYREG15);
814
815 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
816
817 val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
818 writel(val, priv->mmio + PHYREG33);
819 }
820 }
821
822 return 0;
823 }
824
825 static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
826 /* pipe-phy-grf */
827 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
828 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
829 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
830 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
831 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
832 .pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x00 },
833 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
834 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
835 .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 },
836 .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 },
837 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
838 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
839 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
840 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
841 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
842 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
843 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
844 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
845 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
846 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 },
847 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 },
848 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 },
849 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 },
850 /* php-grf */
851 .pipe_con0_for_sata = { 0x001C, 2, 0, 0x00, 0x2 },
852 .pipe_con1_for_sata = { 0x0020, 2, 0, 0x00, 0x2 },
853 };
854
855 static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
856 .num_phys = 2,
857 .phy_ids = {
858 0x2b050000,
859 0x2b060000
860 },
861 .grfcfg = &rk3576_combphy_grfcfgs,
862 .combphy_cfg = rk3576_combphy_cfg,
863 };
864
rk3588_combphy_cfg(struct rockchip_combphy_priv * priv)865 static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
866 {
867 const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
868 unsigned long rate;
869 u32 val;
870
871 switch (priv->type) {
872 case PHY_TYPE_PCIE:
873 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
874 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
875 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
876 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
877 switch (priv->id) {
878 case 1:
879 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
880 break;
881 case 2:
882 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);
883 break;
884 }
885 break;
886 case PHY_TYPE_USB3:
887 /* Set SSC downward spread spectrum */
888 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
889 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
890 PHYREG32);
891
892 /* Enable adaptive CTLE for USB3.0 Rx. */
893 val = readl(priv->mmio + PHYREG15);
894 val |= PHYREG15_CTLE_EN;
895 writel(val, priv->mmio + PHYREG15);
896
897 /* Set PLL KVCO fine tuning signals. */
898 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
899 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
900 PHYREG33);
901
902 /* Enable controlling random jitter. */
903 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
904
905 /* Set PLL input clock divider 1/2. */
906 rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
907 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
908 PHYREG6);
909
910 writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
911 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
912
913 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
914 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
915 rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
916 break;
917 case PHY_TYPE_SATA:
918 /* Enable adaptive CTLE for SATA Rx. */
919 val = readl(priv->mmio + PHYREG15);
920 val |= PHYREG15_CTLE_EN;
921 writel(val, priv->mmio + PHYREG15);
922 /*
923 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
924 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
925 */
926 val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
927 val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
928 writel(val, priv->mmio + PHYREG7);
929
930 rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
931 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
932 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
933 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
934 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
935 rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
936 break;
937 case PHY_TYPE_SGMII:
938 case PHY_TYPE_QSGMII:
939 default:
940 dev_err(priv->dev, "incompatible PHY type\n");
941 return -EINVAL;
942 }
943
944 rate = clk_get_rate(priv->refclk);
945
946 switch (rate) {
947 case REF_CLOCK_24MHz:
948 if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
949 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
950 val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
951 rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
952 val, PHYREG15);
953
954 writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
955 }
956 break;
957
958 case REF_CLOCK_25MHz:
959 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
960 break;
961 case REF_CLOCK_100MHz:
962 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
963 if (priv->type == PHY_TYPE_PCIE) {
964 /* PLL KVCO fine tuning. */
965 val = 4 << PHYREG33_PLL_KVCO_SHIFT;
966 rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
967 val, PHYREG33);
968
969 /* Enable controlling random jitter. */
970 writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
971
972 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
973 writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27);
974
975 /* Set up su_trim: */
976 writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
977 } else if (priv->type == PHY_TYPE_SATA) {
978 /* downward spread spectrum +500ppm */
979 val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
980 val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
981 rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
982 }
983 break;
984 default:
985 dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
986 return -EINVAL;
987 }
988
989 if (priv->ext_refclk) {
990 rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
991 if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
992 val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
993 val |= PHYREG13_CKRCV_AMP0;
994 rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
995
996 val = readl(priv->mmio + PHYREG14);
997 val |= PHYREG14_CKRCV_AMP1;
998 writel(val, priv->mmio + PHYREG14);
999 }
1000 }
1001
1002 if (priv->enable_ssc) {
1003 val = readl(priv->mmio + PHYREG8);
1004 val |= PHYREG8_SSC_EN;
1005 writel(val, priv->mmio + PHYREG8);
1006 }
1007
1008 return 0;
1009 }
1010
1011 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
1012 /* pipe-phy-grf */
1013 .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
1014 .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
1015 .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
1016 .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
1017 .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
1018 .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
1019 .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
1020 .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
1021 .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
1022 .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
1023 .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
1024 .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
1025 .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
1026 .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
1027 .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
1028 .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
1029 .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 },
1030 .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 },
1031 .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 },
1032 .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 },
1033 /* pipe-grf */
1034 .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 },
1035 .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 },
1036 .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 },
1037 .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 },
1038 };
1039
1040 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
1041 .num_phys = 3,
1042 .phy_ids = {
1043 0xfee00000,
1044 0xfee10000,
1045 0xfee20000,
1046 },
1047 .grfcfg = &rk3588_combphy_grfcfgs,
1048 .combphy_cfg = rk3588_combphy_cfg,
1049 };
1050
1051 static const struct of_device_id rockchip_combphy_of_match[] = {
1052 {
1053 .compatible = "rockchip,rk3568-naneng-combphy",
1054 .data = &rk3568_combphy_cfgs,
1055 },
1056 {
1057 .compatible = "rockchip,rk3576-naneng-combphy",
1058 .data = &rk3576_combphy_cfgs,
1059 },
1060 {
1061 .compatible = "rockchip,rk3588-naneng-combphy",
1062 .data = &rk3588_combphy_cfgs,
1063 },
1064 { },
1065 };
1066 MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
1067
1068 static struct platform_driver rockchip_combphy_driver = {
1069 .probe = rockchip_combphy_probe,
1070 .driver = {
1071 .name = "rockchip-naneng-combphy",
1072 .of_match_table = rockchip_combphy_of_match,
1073 },
1074 };
1075 module_platform_driver(rockchip_combphy_driver);
1076
1077 MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
1078 MODULE_LICENSE("GPL v2");
1079