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