1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver
5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
8 #include <dt-bindings/phy/phy.h>
10 #include <linux/mfd/syscon.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>
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)
25 #define PHYREG6_PLL_DIV_MASK GENMASK(7, 6)
26 #define PHYREG6_PLL_DIV_SHIFT 6
27 #define PHYREG6_PLL_DIV_2 1
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
38 #define PHYREG8_SSC_EN BIT(4)
41 #define PHYREG11_SU_TRIM_0_7 0xF0
44 #define PHYREG12_PLL_LPF_ADJ_VALUE 4
47 #define PHYREG13_RESISTER_MASK GENMASK(5, 4)
48 #define PHYREG13_RESISTER_SHIFT 0x4
49 #define PHYREG13_RESISTER_HIGH_Z 3
50 #define PHYREG13_CKRCV_AMP0 BIT(7)
53 #define PHYREG14_CKRCV_AMP1 BIT(0)
56 #define PHYREG15_CTLE_EN BIT(0)
57 #define PHYREG15_SSC_CNT_MASK GENMASK(7, 6)
58 #define PHYREG15_SSC_CNT_SHIFT 6
59 #define PHYREG15_SSC_CNT_VALUE 1
62 #define PHYREG16_SSC_CNT_VALUE 0x5f
65 #define PHYREG18_PLL_LOOP 0x32
68 #define PHYREG27_RX_TRIM_RK3588 0x4C
71 #define PHYREG32_SSC_MASK GENMASK(7, 4)
72 #define PHYREG32_SSC_DIR_SHIFT 4
73 #define PHYREG32_SSC_UPWARD 0
74 #define PHYREG32_SSC_DOWNWARD 1
75 #define PHYREG32_SSC_OFFSET_SHIFT 6
76 #define PHYREG32_SSC_OFFSET_500PPM 1
79 #define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2)
80 #define PHYREG33_PLL_KVCO_SHIFT 2
81 #define PHYREG33_PLL_KVCO_VALUE 2
83 struct rockchip_combphy_priv
;
93 struct rockchip_combphy_grfcfg
{
94 struct combphy_reg pcie_mode_set
;
95 struct combphy_reg usb_mode_set
;
96 struct combphy_reg sgmii_mode_set
;
97 struct combphy_reg qsgmii_mode_set
;
98 struct combphy_reg pipe_rxterm_set
;
99 struct combphy_reg pipe_txelec_set
;
100 struct combphy_reg pipe_txcomp_set
;
101 struct combphy_reg pipe_clk_25m
;
102 struct combphy_reg pipe_clk_100m
;
103 struct combphy_reg pipe_phymode_sel
;
104 struct combphy_reg pipe_rate_sel
;
105 struct combphy_reg pipe_rxterm_sel
;
106 struct combphy_reg pipe_txelec_sel
;
107 struct combphy_reg pipe_txcomp_sel
;
108 struct combphy_reg pipe_clk_ext
;
109 struct combphy_reg pipe_sel_usb
;
110 struct combphy_reg pipe_sel_qsgmii
;
111 struct combphy_reg pipe_phy_status
;
112 struct combphy_reg con0_for_pcie
;
113 struct combphy_reg con1_for_pcie
;
114 struct combphy_reg con2_for_pcie
;
115 struct combphy_reg con3_for_pcie
;
116 struct combphy_reg con0_for_sata
;
117 struct combphy_reg con1_for_sata
;
118 struct combphy_reg con2_for_sata
;
119 struct combphy_reg con3_for_sata
;
120 struct combphy_reg pipe_con0_for_sata
;
121 struct combphy_reg pipe_con1_for_sata
;
122 struct combphy_reg pipe_xpcs_phy_ready
;
123 struct combphy_reg pipe_pcie1l0_sel
;
124 struct combphy_reg pipe_pcie1l1_sel
;
127 struct rockchip_combphy_cfg
{
128 unsigned int num_phys
;
129 unsigned int phy_ids
[3];
130 const struct rockchip_combphy_grfcfg
*grfcfg
;
131 int (*combphy_cfg
)(struct rockchip_combphy_priv
*priv
);
134 struct rockchip_combphy_priv
{
139 struct clk_bulk_data
*clks
;
141 struct regmap
*pipe_grf
;
142 struct regmap
*phy_grf
;
144 struct reset_control
*phy_rst
;
145 const struct rockchip_combphy_cfg
*cfg
;
151 static void rockchip_combphy_updatel(struct rockchip_combphy_priv
*priv
,
152 int mask
, int val
, int reg
)
156 temp
= readl(priv
->mmio
+ reg
);
157 temp
= (temp
& ~(mask
)) | val
;
158 writel(temp
, priv
->mmio
+ reg
);
161 static int rockchip_combphy_param_write(struct regmap
*base
,
162 const struct combphy_reg
*reg
, bool en
)
166 tmp
= en
? reg
->enable
: reg
->disable
;
167 mask
= GENMASK(reg
->bitend
, reg
->bitstart
);
168 val
= (tmp
<< reg
->bitstart
) | (mask
<< BIT_WRITEABLE_SHIFT
);
170 return regmap_write(base
, reg
->offset
, val
);
173 static u32
rockchip_combphy_is_ready(struct rockchip_combphy_priv
*priv
)
175 const struct rockchip_combphy_grfcfg
*cfg
= priv
->cfg
->grfcfg
;
178 mask
= GENMASK(cfg
->pipe_phy_status
.bitend
,
179 cfg
->pipe_phy_status
.bitstart
);
181 regmap_read(priv
->phy_grf
, cfg
->pipe_phy_status
.offset
, &val
);
182 val
= (val
& mask
) >> cfg
->pipe_phy_status
.bitstart
;
187 static int rockchip_combphy_init(struct phy
*phy
)
189 struct rockchip_combphy_priv
*priv
= phy_get_drvdata(phy
);
190 const struct rockchip_combphy_grfcfg
*cfg
= priv
->cfg
->grfcfg
;
194 ret
= clk_bulk_prepare_enable(priv
->num_clks
, priv
->clks
);
196 dev_err(priv
->dev
, "failed to enable clks\n");
200 switch (priv
->type
) {
205 case PHY_TYPE_QSGMII
:
206 if (priv
->cfg
->combphy_cfg
)
207 ret
= priv
->cfg
->combphy_cfg(priv
);
210 dev_err(priv
->dev
, "incompatible PHY type\n");
216 dev_err(priv
->dev
, "failed to init phy for phy type %x\n", priv
->type
);
220 ret
= reset_control_deassert(priv
->phy_rst
);
224 if (priv
->type
== PHY_TYPE_USB3
) {
225 ret
= readx_poll_timeout_atomic(rockchip_combphy_is_ready
,
227 val
== cfg
->pipe_phy_status
.enable
,
230 dev_warn(priv
->dev
, "wait phy status ready timeout\n");
236 clk_bulk_disable_unprepare(priv
->num_clks
, priv
->clks
);
241 static int rockchip_combphy_exit(struct phy
*phy
)
243 struct rockchip_combphy_priv
*priv
= phy_get_drvdata(phy
);
245 clk_bulk_disable_unprepare(priv
->num_clks
, priv
->clks
);
246 reset_control_assert(priv
->phy_rst
);
251 static const struct phy_ops rockchip_combphy_ops
= {
252 .init
= rockchip_combphy_init
,
253 .exit
= rockchip_combphy_exit
,
254 .owner
= THIS_MODULE
,
257 static struct phy
*rockchip_combphy_xlate(struct device
*dev
, const struct of_phandle_args
*args
)
259 struct rockchip_combphy_priv
*priv
= dev_get_drvdata(dev
);
261 if (args
->args_count
!= 1) {
262 dev_err(dev
, "invalid number of arguments\n");
263 return ERR_PTR(-EINVAL
);
266 if (priv
->type
!= PHY_NONE
&& priv
->type
!= args
->args
[0])
267 dev_warn(dev
, "phy type select %d overwriting type %d\n",
268 args
->args
[0], priv
->type
);
270 priv
->type
= args
->args
[0];
275 static int rockchip_combphy_parse_dt(struct device
*dev
, struct rockchip_combphy_priv
*priv
)
279 priv
->num_clks
= devm_clk_bulk_get_all(dev
, &priv
->clks
);
280 if (priv
->num_clks
< 1)
284 for (i
= 0; i
< priv
->num_clks
; i
++) {
285 if (!strncmp(priv
->clks
[i
].id
, "ref", 3)) {
286 priv
->refclk
= priv
->clks
[i
].clk
;
292 dev_err(dev
, "no refclk found\n");
296 priv
->pipe_grf
= syscon_regmap_lookup_by_phandle(dev
->of_node
, "rockchip,pipe-grf");
297 if (IS_ERR(priv
->pipe_grf
)) {
298 dev_err(dev
, "failed to find peri_ctrl pipe-grf regmap\n");
299 return PTR_ERR(priv
->pipe_grf
);
302 priv
->phy_grf
= syscon_regmap_lookup_by_phandle(dev
->of_node
, "rockchip,pipe-phy-grf");
303 if (IS_ERR(priv
->phy_grf
)) {
304 dev_err(dev
, "failed to find peri_ctrl pipe-phy-grf regmap\n");
305 return PTR_ERR(priv
->phy_grf
);
308 priv
->enable_ssc
= device_property_present(dev
, "rockchip,enable-ssc");
310 priv
->ext_refclk
= device_property_present(dev
, "rockchip,ext-refclk");
312 priv
->phy_rst
= devm_reset_control_array_get_exclusive(dev
);
313 if (IS_ERR(priv
->phy_rst
))
314 return dev_err_probe(dev
, PTR_ERR(priv
->phy_rst
), "failed to get phy reset\n");
319 static int rockchip_combphy_probe(struct platform_device
*pdev
)
321 struct phy_provider
*phy_provider
;
322 struct device
*dev
= &pdev
->dev
;
323 struct rockchip_combphy_priv
*priv
;
324 const struct rockchip_combphy_cfg
*phy_cfg
;
325 struct resource
*res
;
328 phy_cfg
= of_device_get_match_data(dev
);
330 dev_err(dev
, "no OF match data provided\n");
334 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
338 priv
->mmio
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
339 if (IS_ERR(priv
->mmio
)) {
340 ret
= PTR_ERR(priv
->mmio
);
344 /* find the phy-id from the io address */
346 for (id
= 0; id
< phy_cfg
->num_phys
; id
++) {
347 if (res
->start
== phy_cfg
->phy_ids
[id
]) {
354 priv
->type
= PHY_NONE
;
357 ret
= rockchip_combphy_parse_dt(dev
, priv
);
361 ret
= reset_control_assert(priv
->phy_rst
);
363 dev_err(dev
, "failed to reset phy\n");
367 priv
->phy
= devm_phy_create(dev
, NULL
, &rockchip_combphy_ops
);
368 if (IS_ERR(priv
->phy
)) {
369 dev_err(dev
, "failed to create combphy\n");
370 return PTR_ERR(priv
->phy
);
373 dev_set_drvdata(dev
, priv
);
374 phy_set_drvdata(priv
->phy
, priv
);
376 phy_provider
= devm_of_phy_provider_register(dev
, rockchip_combphy_xlate
);
378 return PTR_ERR_OR_ZERO(phy_provider
);
381 static int rk3568_combphy_cfg(struct rockchip_combphy_priv
*priv
)
383 const struct rockchip_combphy_grfcfg
*cfg
= priv
->cfg
->grfcfg
;
387 switch (priv
->type
) {
389 /* Set SSC downward spread spectrum. */
390 rockchip_combphy_updatel(priv
, PHYREG32_SSC_MASK
,
391 PHYREG32_SSC_DOWNWARD
<< PHYREG32_SSC_DIR_SHIFT
,
394 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con0_for_pcie
, true);
395 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con1_for_pcie
, true);
396 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con2_for_pcie
, true);
397 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con3_for_pcie
, true);
401 /* Set SSC downward spread spectrum. */
402 rockchip_combphy_updatel(priv
, PHYREG32_SSC_MASK
,
403 PHYREG32_SSC_DOWNWARD
<< PHYREG32_SSC_DIR_SHIFT
,
406 /* Enable adaptive CTLE for USB3.0 Rx. */
407 val
= readl(priv
->mmio
+ PHYREG15
);
408 val
|= PHYREG15_CTLE_EN
;
409 writel(val
, priv
->mmio
+ PHYREG15
);
411 /* Set PLL KVCO fine tuning signals. */
412 rockchip_combphy_updatel(priv
, PHYREG33_PLL_KVCO_MASK
,
413 PHYREG33_PLL_KVCO_VALUE
<< PHYREG33_PLL_KVCO_SHIFT
,
416 /* Enable controlling random jitter. */
417 writel(PHYREG12_PLL_LPF_ADJ_VALUE
, priv
->mmio
+ PHYREG12
);
419 /* Set PLL input clock divider 1/2. */
420 rockchip_combphy_updatel(priv
, PHYREG6_PLL_DIV_MASK
,
421 PHYREG6_PLL_DIV_2
<< PHYREG6_PLL_DIV_SHIFT
,
424 writel(PHYREG18_PLL_LOOP
, priv
->mmio
+ PHYREG18
);
425 writel(PHYREG11_SU_TRIM_0_7
, priv
->mmio
+ PHYREG11
);
427 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_sel_usb
, true);
428 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_txcomp_sel
, false);
429 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_txelec_sel
, false);
430 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->usb_mode_set
, true);
434 /* Enable adaptive CTLE for SATA Rx. */
435 val
= readl(priv
->mmio
+ PHYREG15
);
436 val
|= PHYREG15_CTLE_EN
;
437 writel(val
, priv
->mmio
+ PHYREG15
);
439 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
440 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
442 val
= PHYREG7_TX_RTERM_50OHM
<< PHYREG7_TX_RTERM_SHIFT
;
443 val
|= PHYREG7_RX_RTERM_44OHM
<< PHYREG7_RX_RTERM_SHIFT
;
444 writel(val
, priv
->mmio
+ PHYREG7
);
446 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con0_for_sata
, true);
447 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con1_for_sata
, true);
448 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con2_for_sata
, true);
449 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con3_for_sata
, true);
450 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_con0_for_sata
, true);
454 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_xpcs_phy_ready
, true);
455 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_phymode_sel
, true);
456 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_sel_qsgmii
, true);
457 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->sgmii_mode_set
, true);
460 case PHY_TYPE_QSGMII
:
461 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_xpcs_phy_ready
, true);
462 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_phymode_sel
, true);
463 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_rate_sel
, true);
464 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_sel_qsgmii
, true);
465 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->qsgmii_mode_set
, true);
469 dev_err(priv
->dev
, "incompatible PHY type\n");
473 rate
= clk_get_rate(priv
->refclk
);
476 case REF_CLOCK_24MHz
:
477 if (priv
->type
== PHY_TYPE_USB3
|| priv
->type
== PHY_TYPE_SATA
) {
478 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
479 val
= PHYREG15_SSC_CNT_VALUE
<< PHYREG15_SSC_CNT_SHIFT
;
480 rockchip_combphy_updatel(priv
, PHYREG15_SSC_CNT_MASK
,
483 writel(PHYREG16_SSC_CNT_VALUE
, priv
->mmio
+ PHYREG16
);
487 case REF_CLOCK_25MHz
:
488 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_25m
, true);
491 case REF_CLOCK_100MHz
:
492 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_100m
, true);
493 if (priv
->type
== PHY_TYPE_PCIE
) {
494 /* PLL KVCO fine tuning. */
495 val
= PHYREG33_PLL_KVCO_VALUE
<< PHYREG33_PLL_KVCO_SHIFT
;
496 rockchip_combphy_updatel(priv
, PHYREG33_PLL_KVCO_MASK
,
499 /* Enable controlling random jitter. */
500 writel(PHYREG12_PLL_LPF_ADJ_VALUE
, priv
->mmio
+ PHYREG12
);
502 val
= PHYREG6_PLL_DIV_2
<< PHYREG6_PLL_DIV_SHIFT
;
503 rockchip_combphy_updatel(priv
, PHYREG6_PLL_DIV_MASK
,
506 writel(PHYREG18_PLL_LOOP
, priv
->mmio
+ PHYREG18
);
507 writel(PHYREG11_SU_TRIM_0_7
, priv
->mmio
+ PHYREG11
);
508 } else if (priv
->type
== PHY_TYPE_SATA
) {
509 /* downward spread spectrum +500ppm */
510 val
= PHYREG32_SSC_DOWNWARD
<< PHYREG32_SSC_DIR_SHIFT
;
511 val
|= PHYREG32_SSC_OFFSET_500PPM
<< PHYREG32_SSC_OFFSET_SHIFT
;
512 rockchip_combphy_updatel(priv
, PHYREG32_SSC_MASK
, val
, PHYREG32
);
517 dev_err(priv
->dev
, "unsupported rate: %lu\n", rate
);
521 if (priv
->ext_refclk
) {
522 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_ext
, true);
523 if (priv
->type
== PHY_TYPE_PCIE
&& rate
== REF_CLOCK_100MHz
) {
524 val
= PHYREG13_RESISTER_HIGH_Z
<< PHYREG13_RESISTER_SHIFT
;
525 val
|= PHYREG13_CKRCV_AMP0
;
526 rockchip_combphy_updatel(priv
, PHYREG13_RESISTER_MASK
, val
, PHYREG13
);
528 val
= readl(priv
->mmio
+ PHYREG14
);
529 val
|= PHYREG14_CKRCV_AMP1
;
530 writel(val
, priv
->mmio
+ PHYREG14
);
534 if (priv
->enable_ssc
) {
535 val
= readl(priv
->mmio
+ PHYREG8
);
536 val
|= PHYREG8_SSC_EN
;
537 writel(val
, priv
->mmio
+ PHYREG8
);
543 static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs
= {
545 .pcie_mode_set
= { 0x0000, 5, 0, 0x00, 0x11 },
546 .usb_mode_set
= { 0x0000, 5, 0, 0x00, 0x04 },
547 .sgmii_mode_set
= { 0x0000, 5, 0, 0x00, 0x01 },
548 .qsgmii_mode_set
= { 0x0000, 5, 0, 0x00, 0x21 },
549 .pipe_rxterm_set
= { 0x0000, 12, 12, 0x00, 0x01 },
550 .pipe_txelec_set
= { 0x0004, 1, 1, 0x00, 0x01 },
551 .pipe_txcomp_set
= { 0x0004, 4, 4, 0x00, 0x01 },
552 .pipe_clk_25m
= { 0x0004, 14, 13, 0x00, 0x01 },
553 .pipe_clk_100m
= { 0x0004, 14, 13, 0x00, 0x02 },
554 .pipe_phymode_sel
= { 0x0008, 1, 1, 0x00, 0x01 },
555 .pipe_rate_sel
= { 0x0008, 2, 2, 0x00, 0x01 },
556 .pipe_rxterm_sel
= { 0x0008, 8, 8, 0x00, 0x01 },
557 .pipe_txelec_sel
= { 0x0008, 12, 12, 0x00, 0x01 },
558 .pipe_txcomp_sel
= { 0x0008, 15, 15, 0x00, 0x01 },
559 .pipe_clk_ext
= { 0x000c, 9, 8, 0x02, 0x01 },
560 .pipe_sel_usb
= { 0x000c, 14, 13, 0x00, 0x01 },
561 .pipe_sel_qsgmii
= { 0x000c, 15, 13, 0x00, 0x07 },
562 .pipe_phy_status
= { 0x0034, 6, 6, 0x01, 0x00 },
563 .con0_for_pcie
= { 0x0000, 15, 0, 0x00, 0x1000 },
564 .con1_for_pcie
= { 0x0004, 15, 0, 0x00, 0x0000 },
565 .con2_for_pcie
= { 0x0008, 15, 0, 0x00, 0x0101 },
566 .con3_for_pcie
= { 0x000c, 15, 0, 0x00, 0x0200 },
567 .con0_for_sata
= { 0x0000, 15, 0, 0x00, 0x0119 },
568 .con1_for_sata
= { 0x0004, 15, 0, 0x00, 0x0040 },
569 .con2_for_sata
= { 0x0008, 15, 0, 0x00, 0x80c3 },
570 .con3_for_sata
= { 0x000c, 15, 0, 0x00, 0x4407 },
572 .pipe_con0_for_sata
= { 0x0000, 15, 0, 0x00, 0x2220 },
573 .pipe_xpcs_phy_ready
= { 0x0040, 2, 2, 0x00, 0x01 },
576 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs
= {
583 .grfcfg
= &rk3568_combphy_grfcfgs
,
584 .combphy_cfg
= rk3568_combphy_cfg
,
587 static int rk3588_combphy_cfg(struct rockchip_combphy_priv
*priv
)
589 const struct rockchip_combphy_grfcfg
*cfg
= priv
->cfg
->grfcfg
;
593 switch (priv
->type
) {
595 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con0_for_pcie
, true);
596 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con1_for_pcie
, true);
597 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con2_for_pcie
, true);
598 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con3_for_pcie
, true);
601 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_pcie1l0_sel
, true);
604 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_pcie1l1_sel
, true);
609 /* Set SSC downward spread spectrum */
610 rockchip_combphy_updatel(priv
, PHYREG32_SSC_MASK
,
611 PHYREG32_SSC_DOWNWARD
<< PHYREG32_SSC_DIR_SHIFT
,
614 /* Enable adaptive CTLE for USB3.0 Rx. */
615 val
= readl(priv
->mmio
+ PHYREG15
);
616 val
|= PHYREG15_CTLE_EN
;
617 writel(val
, priv
->mmio
+ PHYREG15
);
619 /* Set PLL KVCO fine tuning signals. */
620 rockchip_combphy_updatel(priv
, PHYREG33_PLL_KVCO_MASK
,
621 PHYREG33_PLL_KVCO_VALUE
<< PHYREG33_PLL_KVCO_SHIFT
,
624 /* Enable controlling random jitter. */
625 writel(PHYREG12_PLL_LPF_ADJ_VALUE
, priv
->mmio
+ PHYREG12
);
627 /* Set PLL input clock divider 1/2. */
628 rockchip_combphy_updatel(priv
, PHYREG6_PLL_DIV_MASK
,
629 PHYREG6_PLL_DIV_2
<< PHYREG6_PLL_DIV_SHIFT
,
632 writel(PHYREG18_PLL_LOOP
, priv
->mmio
+ PHYREG18
);
633 writel(PHYREG11_SU_TRIM_0_7
, priv
->mmio
+ PHYREG11
);
635 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_txcomp_sel
, false);
636 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_txelec_sel
, false);
637 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->usb_mode_set
, true);
640 /* Enable adaptive CTLE for SATA Rx. */
641 val
= readl(priv
->mmio
+ PHYREG15
);
642 val
|= PHYREG15_CTLE_EN
;
643 writel(val
, priv
->mmio
+ PHYREG15
);
645 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
646 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
648 val
= PHYREG7_TX_RTERM_50OHM
<< PHYREG7_TX_RTERM_SHIFT
;
649 val
|= PHYREG7_RX_RTERM_44OHM
<< PHYREG7_RX_RTERM_SHIFT
;
650 writel(val
, priv
->mmio
+ PHYREG7
);
652 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con0_for_sata
, true);
653 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con1_for_sata
, true);
654 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con2_for_sata
, true);
655 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->con3_for_sata
, true);
656 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_con0_for_sata
, true);
657 rockchip_combphy_param_write(priv
->pipe_grf
, &cfg
->pipe_con1_for_sata
, true);
660 case PHY_TYPE_QSGMII
:
662 dev_err(priv
->dev
, "incompatible PHY type\n");
666 rate
= clk_get_rate(priv
->refclk
);
669 case REF_CLOCK_24MHz
:
670 if (priv
->type
== PHY_TYPE_USB3
|| priv
->type
== PHY_TYPE_SATA
) {
671 /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
672 val
= PHYREG15_SSC_CNT_VALUE
<< PHYREG15_SSC_CNT_SHIFT
;
673 rockchip_combphy_updatel(priv
, PHYREG15_SSC_CNT_MASK
,
676 writel(PHYREG16_SSC_CNT_VALUE
, priv
->mmio
+ PHYREG16
);
680 case REF_CLOCK_25MHz
:
681 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_25m
, true);
683 case REF_CLOCK_100MHz
:
684 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_100m
, true);
685 if (priv
->type
== PHY_TYPE_PCIE
) {
686 /* PLL KVCO fine tuning. */
687 val
= 4 << PHYREG33_PLL_KVCO_SHIFT
;
688 rockchip_combphy_updatel(priv
, PHYREG33_PLL_KVCO_MASK
,
691 /* Enable controlling random jitter. */
692 writel(PHYREG12_PLL_LPF_ADJ_VALUE
, priv
->mmio
+ PHYREG12
);
694 /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
695 writel(PHYREG27_RX_TRIM_RK3588
, priv
->mmio
+ PHYREG27
);
697 /* Set up su_trim: */
698 writel(PHYREG11_SU_TRIM_0_7
, priv
->mmio
+ PHYREG11
);
699 } else if (priv
->type
== PHY_TYPE_SATA
) {
700 /* downward spread spectrum +500ppm */
701 val
= PHYREG32_SSC_DOWNWARD
<< PHYREG32_SSC_DIR_SHIFT
;
702 val
|= PHYREG32_SSC_OFFSET_500PPM
<< PHYREG32_SSC_OFFSET_SHIFT
;
703 rockchip_combphy_updatel(priv
, PHYREG32_SSC_MASK
, val
, PHYREG32
);
707 dev_err(priv
->dev
, "Unsupported rate: %lu\n", rate
);
711 if (priv
->ext_refclk
) {
712 rockchip_combphy_param_write(priv
->phy_grf
, &cfg
->pipe_clk_ext
, true);
713 if (priv
->type
== PHY_TYPE_PCIE
&& rate
== REF_CLOCK_100MHz
) {
714 val
= PHYREG13_RESISTER_HIGH_Z
<< PHYREG13_RESISTER_SHIFT
;
715 val
|= PHYREG13_CKRCV_AMP0
;
716 rockchip_combphy_updatel(priv
, PHYREG13_RESISTER_MASK
, val
, PHYREG13
);
718 val
= readl(priv
->mmio
+ PHYREG14
);
719 val
|= PHYREG14_CKRCV_AMP1
;
720 writel(val
, priv
->mmio
+ PHYREG14
);
724 if (priv
->enable_ssc
) {
725 val
= readl(priv
->mmio
+ PHYREG8
);
726 val
|= PHYREG8_SSC_EN
;
727 writel(val
, priv
->mmio
+ PHYREG8
);
733 static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs
= {
735 .pcie_mode_set
= { 0x0000, 5, 0, 0x00, 0x11 },
736 .usb_mode_set
= { 0x0000, 5, 0, 0x00, 0x04 },
737 .pipe_rxterm_set
= { 0x0000, 12, 12, 0x00, 0x01 },
738 .pipe_txelec_set
= { 0x0004, 1, 1, 0x00, 0x01 },
739 .pipe_txcomp_set
= { 0x0004, 4, 4, 0x00, 0x01 },
740 .pipe_clk_25m
= { 0x0004, 14, 13, 0x00, 0x01 },
741 .pipe_clk_100m
= { 0x0004, 14, 13, 0x00, 0x02 },
742 .pipe_rxterm_sel
= { 0x0008, 8, 8, 0x00, 0x01 },
743 .pipe_txelec_sel
= { 0x0008, 12, 12, 0x00, 0x01 },
744 .pipe_txcomp_sel
= { 0x0008, 15, 15, 0x00, 0x01 },
745 .pipe_clk_ext
= { 0x000c, 9, 8, 0x02, 0x01 },
746 .pipe_phy_status
= { 0x0034, 6, 6, 0x01, 0x00 },
747 .con0_for_pcie
= { 0x0000, 15, 0, 0x00, 0x1000 },
748 .con1_for_pcie
= { 0x0004, 15, 0, 0x00, 0x0000 },
749 .con2_for_pcie
= { 0x0008, 15, 0, 0x00, 0x0101 },
750 .con3_for_pcie
= { 0x000c, 15, 0, 0x00, 0x0200 },
751 .con0_for_sata
= { 0x0000, 15, 0, 0x00, 0x0129 },
752 .con1_for_sata
= { 0x0004, 15, 0, 0x00, 0x0000 },
753 .con2_for_sata
= { 0x0008, 15, 0, 0x00, 0x80c1 },
754 .con3_for_sata
= { 0x000c, 15, 0, 0x00, 0x0407 },
756 .pipe_con0_for_sata
= { 0x0000, 11, 5, 0x00, 0x22 },
757 .pipe_con1_for_sata
= { 0x0000, 2, 0, 0x00, 0x2 },
758 .pipe_pcie1l0_sel
= { 0x0100, 0, 0, 0x01, 0x0 },
759 .pipe_pcie1l1_sel
= { 0x0100, 1, 1, 0x01, 0x0 },
762 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs
= {
769 .grfcfg
= &rk3588_combphy_grfcfgs
,
770 .combphy_cfg
= rk3588_combphy_cfg
,
773 static const struct of_device_id rockchip_combphy_of_match
[] = {
775 .compatible
= "rockchip,rk3568-naneng-combphy",
776 .data
= &rk3568_combphy_cfgs
,
779 .compatible
= "rockchip,rk3588-naneng-combphy",
780 .data
= &rk3588_combphy_cfgs
,
784 MODULE_DEVICE_TABLE(of
, rockchip_combphy_of_match
);
786 static struct platform_driver rockchip_combphy_driver
= {
787 .probe
= rockchip_combphy_probe
,
789 .name
= "rockchip-naneng-combphy",
790 .of_match_table
= rockchip_combphy_of_match
,
793 module_platform_driver(rockchip_combphy_driver
);
795 MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
796 MODULE_LICENSE("GPL v2");