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