1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip PCIE3.0 phy driver
5 * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
9 #include <linux/delay.h>
11 #include <linux/iopoll.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
16 #include <linux/phy/pcie.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 #include <linux/reset.h>
22 /* Register for RK3568 */
23 #define GRF_PCIE30PHY_CON1 0x4
24 #define GRF_PCIE30PHY_CON6 0x18
25 #define GRF_PCIE30PHY_CON9 0x24
26 #define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31))
27 #define GRF_PCIE30PHY_STATUS0 0x80
28 #define GRF_PCIE30PHY_WR_EN (0xf << 16)
29 #define SRAM_INIT_DONE(reg) (reg & BIT(14))
31 #define RK3568_BIFURCATION_LANE_0_1 BIT(0)
33 /* Register for RK3588 */
34 #define PHP_GRF_PCIESEL_CON 0x100
35 #define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0
36 #define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904
37 #define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04
38 #define RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1 0x1004
39 #define RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1 0x1104
40 #define RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1 0x2004
41 #define RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1 0x2104
42 #define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
44 #define RK3588_BIFURCATION_LANE_0_1 BIT(0)
45 #define RK3588_BIFURCATION_LANE_2_3 BIT(1)
46 #define RK3588_LANE_AGGREGATION BIT(2)
47 #define RK3588_RX_CMN_REFCLK_MODE_EN ((BIT(7) << 16) | BIT(7))
48 #define RK3588_RX_CMN_REFCLK_MODE_DIS (BIT(7) << 16)
49 #define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16)
50 #define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16)
52 struct rockchip_p3phy_ops
;
54 struct rockchip_p3phy_priv
{
55 const struct rockchip_p3phy_ops
*ops
;
59 /* pcie30_phymode: Aggregation, Bifurcation */
61 struct regmap
*phy_grf
;
62 struct regmap
*pipe_grf
;
63 struct reset_control
*p30phy
;
65 struct clk_bulk_data
*clks
;
69 u32 rx_cmn_refclk_mode
[4];
72 struct rockchip_p3phy_ops
{
73 int (*phy_init
)(struct rockchip_p3phy_priv
*priv
);
76 static int rockchip_p3phy_set_mode(struct phy
*phy
, enum phy_mode mode
, int submode
)
78 struct rockchip_p3phy_priv
*priv
= phy_get_drvdata(phy
);
80 /* Actually We don't care EP/RC mode, but just record it */
82 case PHY_MODE_PCIE_RC
:
83 priv
->mode
= PHY_MODE_PCIE_RC
;
85 case PHY_MODE_PCIE_EP
:
86 priv
->mode
= PHY_MODE_PCIE_EP
;
89 dev_err(&phy
->dev
, "%s, invalid mode\n", __func__
);
96 static int rockchip_p3phy_rk3568_init(struct rockchip_p3phy_priv
*priv
)
98 struct phy
*phy
= priv
->phy
;
99 bool bifurcation
= false;
103 /* Deassert PCIe PMA output clamp mode */
104 regmap_write(priv
->phy_grf
, GRF_PCIE30PHY_CON9
, GRF_PCIE30PHY_DA_OCM
);
106 for (int i
= 0; i
< priv
->num_lanes
; i
++) {
107 dev_info(&phy
->dev
, "lane number %d, val %d\n", i
, priv
->lanes
[i
]);
108 if (priv
->lanes
[i
] > 1)
112 /* Set bifurcation if needed, and it doesn't care RC/EP */
114 dev_info(&phy
->dev
, "bifurcation enabled\n");
115 regmap_write(priv
->phy_grf
, GRF_PCIE30PHY_CON6
,
116 GRF_PCIE30PHY_WR_EN
| RK3568_BIFURCATION_LANE_0_1
);
117 regmap_write(priv
->phy_grf
, GRF_PCIE30PHY_CON1
,
118 GRF_PCIE30PHY_DA_OCM
);
120 dev_dbg(&phy
->dev
, "bifurcation disabled\n");
121 regmap_write(priv
->phy_grf
, GRF_PCIE30PHY_CON6
,
122 GRF_PCIE30PHY_WR_EN
& ~RK3568_BIFURCATION_LANE_0_1
);
125 reset_control_deassert(priv
->p30phy
);
127 ret
= regmap_read_poll_timeout(priv
->phy_grf
,
128 GRF_PCIE30PHY_STATUS0
,
129 reg
, SRAM_INIT_DONE(reg
),
132 dev_err(&priv
->phy
->dev
, "%s: lock failed 0x%x, check input refclk and power supply\n",
137 static const struct rockchip_p3phy_ops rk3568_ops
= {
138 .phy_init
= rockchip_p3phy_rk3568_init
,
141 static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv
*priv
)
144 u8 mode
= RK3588_LANE_AGGREGATION
; /* default */
147 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1
,
148 priv
->rx_cmn_refclk_mode
[0] ? RK3588_RX_CMN_REFCLK_MODE_EN
:
149 RK3588_RX_CMN_REFCLK_MODE_DIS
);
150 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1
,
151 priv
->rx_cmn_refclk_mode
[1] ? RK3588_RX_CMN_REFCLK_MODE_EN
:
152 RK3588_RX_CMN_REFCLK_MODE_DIS
);
153 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1
,
154 priv
->rx_cmn_refclk_mode
[2] ? RK3588_RX_CMN_REFCLK_MODE_EN
:
155 RK3588_RX_CMN_REFCLK_MODE_DIS
);
156 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1
,
157 priv
->rx_cmn_refclk_mode
[3] ? RK3588_RX_CMN_REFCLK_MODE_EN
:
158 RK3588_RX_CMN_REFCLK_MODE_DIS
);
160 /* Deassert PCIe PMA output clamp mode */
161 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_CMN_CON0
, BIT(8) | BIT(24));
163 /* Set bifurcation if needed */
164 for (int i
= 0; i
< priv
->num_lanes
; i
++) {
165 if (priv
->lanes
[i
] > 1)
166 mode
&= ~RK3588_LANE_AGGREGATION
;
167 if (priv
->lanes
[i
] == 3)
168 mode
|= RK3588_BIFURCATION_LANE_0_1
;
169 if (priv
->lanes
[i
] == 4)
170 mode
|= RK3588_BIFURCATION_LANE_2_3
;
174 regmap_write(priv
->phy_grf
, RK3588_PCIE3PHY_GRF_CMN_CON0
,
175 RK3588_PCIE30_PHY_MODE_EN
| reg
);
177 /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */
178 if (!IS_ERR(priv
->pipe_grf
)) {
179 reg
= mode
& (RK3588_BIFURCATION_LANE_0_1
| RK3588_BIFURCATION_LANE_2_3
);
181 regmap_write(priv
->pipe_grf
, PHP_GRF_PCIESEL_CON
,
182 RK3588_PCIE1LN_SEL_EN
| reg
);
185 reset_control_deassert(priv
->p30phy
);
187 ret
= regmap_read_poll_timeout(priv
->phy_grf
,
188 RK3588_PCIE3PHY_GRF_PHY0_STATUS1
,
189 reg
, RK3588_SRAM_INIT_DONE(reg
),
191 ret
|= regmap_read_poll_timeout(priv
->phy_grf
,
192 RK3588_PCIE3PHY_GRF_PHY1_STATUS1
,
193 reg
, RK3588_SRAM_INIT_DONE(reg
),
196 dev_err(&priv
->phy
->dev
, "lock failed 0x%x, check input refclk and power supply\n",
201 static const struct rockchip_p3phy_ops rk3588_ops
= {
202 .phy_init
= rockchip_p3phy_rk3588_init
,
205 static int rockchip_p3phy_init(struct phy
*phy
)
207 struct rockchip_p3phy_priv
*priv
= phy_get_drvdata(phy
);
210 ret
= clk_bulk_prepare_enable(priv
->num_clks
, priv
->clks
);
212 dev_err(&priv
->phy
->dev
, "failed to enable PCIe bulk clks %d\n", ret
);
216 reset_control_assert(priv
->p30phy
);
219 if (priv
->ops
->phy_init
) {
220 ret
= priv
->ops
->phy_init(priv
);
222 clk_bulk_disable_unprepare(priv
->num_clks
, priv
->clks
);
228 static int rockchip_p3phy_exit(struct phy
*phy
)
230 struct rockchip_p3phy_priv
*priv
= phy_get_drvdata(phy
);
232 clk_bulk_disable_unprepare(priv
->num_clks
, priv
->clks
);
233 reset_control_assert(priv
->p30phy
);
237 static const struct phy_ops rockchip_p3phy_ops
= {
238 .init
= rockchip_p3phy_init
,
239 .exit
= rockchip_p3phy_exit
,
240 .set_mode
= rockchip_p3phy_set_mode
,
241 .owner
= THIS_MODULE
,
244 static int rockchip_p3phy_probe(struct platform_device
*pdev
)
246 struct phy_provider
*phy_provider
;
247 struct device
*dev
= &pdev
->dev
;
248 struct rockchip_p3phy_priv
*priv
;
249 struct device_node
*np
= dev
->of_node
;
252 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
256 priv
->mmio
= devm_platform_get_and_ioremap_resource(pdev
, 0, NULL
);
257 if (IS_ERR(priv
->mmio
)) {
258 ret
= PTR_ERR(priv
->mmio
);
262 priv
->ops
= of_device_get_match_data(&pdev
->dev
);
264 dev_err(dev
, "no of match data provided\n");
268 priv
->phy_grf
= syscon_regmap_lookup_by_phandle(np
, "rockchip,phy-grf");
269 if (IS_ERR(priv
->phy_grf
)) {
270 dev_err(dev
, "failed to find rockchip,phy_grf regmap\n");
271 return PTR_ERR(priv
->phy_grf
);
274 if (of_device_is_compatible(np
, "rockchip,rk3588-pcie3-phy")) {
276 syscon_regmap_lookup_by_phandle(dev
->of_node
,
277 "rockchip,pipe-grf");
278 if (IS_ERR(priv
->pipe_grf
))
279 dev_info(dev
, "failed to find rockchip,pipe_grf regmap\n");
281 priv
->pipe_grf
= NULL
;
284 priv
->num_lanes
= of_property_read_variable_u32_array(dev
->of_node
, "data-lanes",
286 ARRAY_SIZE(priv
->lanes
));
288 /* if no data-lanes assume aggregation */
289 if (priv
->num_lanes
== -EINVAL
) {
290 dev_dbg(dev
, "no data-lanes property found\n");
293 } else if (priv
->num_lanes
< 0) {
294 dev_err(dev
, "failed to read data-lanes property %d\n", priv
->num_lanes
);
295 return priv
->num_lanes
;
298 ret
= of_property_read_variable_u32_array(dev
->of_node
,
299 "rockchip,rx-common-refclk-mode",
300 priv
->rx_cmn_refclk_mode
, 1,
301 ARRAY_SIZE(priv
->rx_cmn_refclk_mode
));
303 * if no rockchip,rx-common-refclk-mode, assume enabled for all lanes in
304 * order to be DT backwards compatible. (Since HW reset val is enabled.)
306 if (ret
== -EINVAL
) {
307 for (int i
= 0; i
< ARRAY_SIZE(priv
->rx_cmn_refclk_mode
); i
++)
308 priv
->rx_cmn_refclk_mode
[i
] = 1;
309 } else if (ret
< 0) {
310 dev_err(dev
, "failed to read rockchip,rx-common-refclk-mode property %d\n",
315 priv
->phy
= devm_phy_create(dev
, NULL
, &rockchip_p3phy_ops
);
316 if (IS_ERR(priv
->phy
)) {
317 dev_err(dev
, "failed to create combphy\n");
318 return PTR_ERR(priv
->phy
);
321 priv
->p30phy
= devm_reset_control_get_optional_exclusive(dev
, "phy");
322 if (IS_ERR(priv
->p30phy
)) {
323 return dev_err_probe(dev
, PTR_ERR(priv
->p30phy
),
324 "failed to get phy reset control\n");
327 dev_info(dev
, "no phy reset control specified\n");
329 priv
->num_clks
= devm_clk_bulk_get_all(dev
, &priv
->clks
);
330 if (priv
->num_clks
< 1)
333 dev_set_drvdata(dev
, priv
);
334 phy_set_drvdata(priv
->phy
, priv
);
335 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
336 return PTR_ERR_OR_ZERO(phy_provider
);
339 static const struct of_device_id rockchip_p3phy_of_match
[] = {
340 { .compatible
= "rockchip,rk3568-pcie3-phy", .data
= &rk3568_ops
},
341 { .compatible
= "rockchip,rk3588-pcie3-phy", .data
= &rk3588_ops
},
344 MODULE_DEVICE_TABLE(of
, rockchip_p3phy_of_match
);
346 static struct platform_driver rockchip_p3phy_driver
= {
347 .probe
= rockchip_p3phy_probe
,
349 .name
= "rockchip-snps-pcie3-phy",
350 .of_match_table
= rockchip_p3phy_of_match
,
353 module_platform_driver(rockchip_p3phy_driver
);
354 MODULE_DESCRIPTION("Rockchip Synopsys PCIe 3.0 PHY driver");
355 MODULE_LICENSE("GPL");