xref: /rk3399_rockchip-uboot/drivers/phy/phy-rockchip-naneng-combphy.c (revision ac8e4a892e8eb0463d8d9db49f3c456cfef191c4)
1925c5749SYifeng Zhao // SPDX-License-Identifier: GPL-2.0
2925c5749SYifeng Zhao /*
3925c5749SYifeng Zhao  * Rockchip USB3.0/PCIe Gen2/SATA/SGMII combphy driver
4925c5749SYifeng Zhao  *
5925c5749SYifeng Zhao  * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
6925c5749SYifeng Zhao  */
7925c5749SYifeng Zhao 
8925c5749SYifeng Zhao #include <common.h>
9925c5749SYifeng Zhao #include <clk.h>
10925c5749SYifeng Zhao #include <dm.h>
11925c5749SYifeng Zhao #include <dm/lists.h>
12925c5749SYifeng Zhao #include <dt-bindings/phy/phy.h>
13925c5749SYifeng Zhao #include <generic-phy.h>
14925c5749SYifeng Zhao #include <syscon.h>
15925c5749SYifeng Zhao #include <asm/io.h>
16925c5749SYifeng Zhao #include <asm/arch/clock.h>
17925c5749SYifeng Zhao #include <regmap.h>
18925c5749SYifeng Zhao #include <reset-uclass.h>
1914d5da7dSwilliam.wu #include <linux/iopoll.h>
20925c5749SYifeng Zhao 
21925c5749SYifeng Zhao #define BIT_WRITEABLE_SHIFT		16
22925c5749SYifeng Zhao 
23925c5749SYifeng Zhao struct rockchip_combphy_priv;
24925c5749SYifeng Zhao 
25925c5749SYifeng Zhao struct combphy_reg {
263452d642SJianwei Zheng 	u32 offset;
27925c5749SYifeng Zhao 	u16 bitend;
28925c5749SYifeng Zhao 	u16 bitstart;
29925c5749SYifeng Zhao 	u16 disable;
30925c5749SYifeng Zhao 	u16 enable;
31925c5749SYifeng Zhao };
32925c5749SYifeng Zhao 
33925c5749SYifeng Zhao struct rockchip_combphy_grfcfg {
34925c5749SYifeng Zhao 	struct combphy_reg pcie_mode_set;
35925c5749SYifeng Zhao 	struct combphy_reg usb_mode_set;
36925c5749SYifeng Zhao 	struct combphy_reg sgmii_mode_set;
37925c5749SYifeng Zhao 	struct combphy_reg qsgmii_mode_set;
38925c5749SYifeng Zhao 	struct combphy_reg pipe_rxterm_set;
39925c5749SYifeng Zhao 	struct combphy_reg pipe_txelec_set;
40925c5749SYifeng Zhao 	struct combphy_reg pipe_txcomp_set;
413452d642SJianwei Zheng 	struct combphy_reg pipe_clk_24m;
42925c5749SYifeng Zhao 	struct combphy_reg pipe_clk_25m;
43925c5749SYifeng Zhao 	struct combphy_reg pipe_clk_100m;
44925c5749SYifeng Zhao 	struct combphy_reg pipe_phymode_sel;
45925c5749SYifeng Zhao 	struct combphy_reg pipe_rate_sel;
46925c5749SYifeng Zhao 	struct combphy_reg pipe_rxterm_sel;
47925c5749SYifeng Zhao 	struct combphy_reg pipe_txelec_sel;
48925c5749SYifeng Zhao 	struct combphy_reg pipe_txcomp_sel;
49925c5749SYifeng Zhao 	struct combphy_reg pipe_clk_ext;
50925c5749SYifeng Zhao 	struct combphy_reg pipe_sel_usb;
51925c5749SYifeng Zhao 	struct combphy_reg pipe_sel_qsgmii;
52925c5749SYifeng Zhao 	struct combphy_reg pipe_phy_status;
53925c5749SYifeng Zhao 	struct combphy_reg con0_for_pcie;
54925c5749SYifeng Zhao 	struct combphy_reg con1_for_pcie;
55925c5749SYifeng Zhao 	struct combphy_reg con2_for_pcie;
56925c5749SYifeng Zhao 	struct combphy_reg con3_for_pcie;
57925c5749SYifeng Zhao 	struct combphy_reg con0_for_sata;
58925c5749SYifeng Zhao 	struct combphy_reg con1_for_sata;
59925c5749SYifeng Zhao 	struct combphy_reg con2_for_sata;
60925c5749SYifeng Zhao 	struct combphy_reg con3_for_sata;
61925c5749SYifeng Zhao 	struct combphy_reg pipe_con0_for_sata;
62cf3c44cbSJon Lin 	struct combphy_reg pipe_con1_for_sata;
63925c5749SYifeng Zhao 	struct combphy_reg pipe_sgmii_mac_sel;
64925c5749SYifeng Zhao 	struct combphy_reg pipe_xpcs_phy_ready;
65925c5749SYifeng Zhao 	struct combphy_reg u3otg0_port_en;
66925c5749SYifeng Zhao 	struct combphy_reg u3otg1_port_en;
6714d5da7dSwilliam.wu 	struct combphy_reg u3otg0_pipe_clk_sel;
6886b316b4SFrank Wang 	struct combphy_reg pipe_phy_grf_reset;
69925c5749SYifeng Zhao };
70925c5749SYifeng Zhao 
71925c5749SYifeng Zhao struct rockchip_combphy_cfg {
72925c5749SYifeng Zhao 	const struct rockchip_combphy_grfcfg *grfcfg;
73925c5749SYifeng Zhao 	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
74925c5749SYifeng Zhao };
75925c5749SYifeng Zhao 
76925c5749SYifeng Zhao struct rockchip_combphy_priv {
77925c5749SYifeng Zhao 	u32 mode;
78925c5749SYifeng Zhao 	void __iomem *mmio;
79925c5749SYifeng Zhao 	struct udevice *dev;
80925c5749SYifeng Zhao 	struct regmap *pipe_grf;
81925c5749SYifeng Zhao 	struct regmap *phy_grf;
82925c5749SYifeng Zhao 	struct phy *phy;
83925c5749SYifeng Zhao 	struct reset_ctl phy_rst;
84925c5749SYifeng Zhao 	struct clk ref_clk;
85925c5749SYifeng Zhao 	const struct rockchip_combphy_cfg *cfg;
86925c5749SYifeng Zhao };
87925c5749SYifeng Zhao 
88925c5749SYifeng Zhao static int param_write(struct regmap *base,
89925c5749SYifeng Zhao 		       const struct combphy_reg *reg, bool en)
90925c5749SYifeng Zhao {
91925c5749SYifeng Zhao 	u32 val, mask, tmp;
92925c5749SYifeng Zhao 
93925c5749SYifeng Zhao 	tmp = en ? reg->enable : reg->disable;
94925c5749SYifeng Zhao 	mask = GENMASK(reg->bitend, reg->bitstart);
95925c5749SYifeng Zhao 	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
96925c5749SYifeng Zhao 
97925c5749SYifeng Zhao 	return regmap_write(base, reg->offset, val);
98925c5749SYifeng Zhao }
99925c5749SYifeng Zhao 
10014d5da7dSwilliam.wu static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
10114d5da7dSwilliam.wu {
10214d5da7dSwilliam.wu 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
10314d5da7dSwilliam.wu 	u32 mask, val;
10414d5da7dSwilliam.wu 
10514d5da7dSwilliam.wu 	mask = GENMASK(cfg->pipe_phy_status.bitend,
10614d5da7dSwilliam.wu 		       cfg->pipe_phy_status.bitstart);
10714d5da7dSwilliam.wu 
10814d5da7dSwilliam.wu 	regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
10914d5da7dSwilliam.wu 	val = (val & mask) >> cfg->pipe_phy_status.bitstart;
11014d5da7dSwilliam.wu 
11114d5da7dSwilliam.wu 	return val;
11214d5da7dSwilliam.wu }
11314d5da7dSwilliam.wu 
114925c5749SYifeng Zhao static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv)
115925c5749SYifeng Zhao {
116925c5749SYifeng Zhao 	int ret = 0;
117925c5749SYifeng Zhao 
118925c5749SYifeng Zhao 	if (priv->cfg->combphy_cfg) {
119925c5749SYifeng Zhao 		ret = priv->cfg->combphy_cfg(priv);
120925c5749SYifeng Zhao 		if (ret) {
121925c5749SYifeng Zhao 			dev_err(priv->dev, "failed to init phy for pcie\n");
122925c5749SYifeng Zhao 			return ret;
123925c5749SYifeng Zhao 		}
124925c5749SYifeng Zhao 	}
125925c5749SYifeng Zhao 
126925c5749SYifeng Zhao 	return ret;
127925c5749SYifeng Zhao }
128925c5749SYifeng Zhao 
129925c5749SYifeng Zhao static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv)
130925c5749SYifeng Zhao {
131*ac8e4a89SWilliam Wu 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
132925c5749SYifeng Zhao 	int ret = 0;
133925c5749SYifeng Zhao 
134*ac8e4a89SWilliam Wu 	if (dev_read_bool(priv->dev, "rockchip,dis-u3otg0-port")) {
135*ac8e4a89SWilliam Wu 		ret = param_write(priv->pipe_grf, &cfg->u3otg0_port_en, false);
136*ac8e4a89SWilliam Wu 		return ret;
137*ac8e4a89SWilliam Wu 	} else if (dev_read_bool(priv->dev, "rockchip,dis-u3otg1-port")) {
138*ac8e4a89SWilliam Wu 		param_write(priv->pipe_grf, &cfg->u3otg1_port_en, false);
139*ac8e4a89SWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3576
140*ac8e4a89SWilliam Wu 		param_write(priv->phy_grf,  &cfg->usb_mode_set, true);
141*ac8e4a89SWilliam Wu #endif
142*ac8e4a89SWilliam Wu 		return ret;
143*ac8e4a89SWilliam Wu 	}
144*ac8e4a89SWilliam Wu 
145925c5749SYifeng Zhao 	if (priv->cfg->combphy_cfg) {
146925c5749SYifeng Zhao 		ret = priv->cfg->combphy_cfg(priv);
147925c5749SYifeng Zhao 		if (ret) {
148925c5749SYifeng Zhao 			dev_err(priv->dev, "failed to init phy for usb3\n");
149925c5749SYifeng Zhao 			return ret;
150925c5749SYifeng Zhao 		}
151925c5749SYifeng Zhao 	}
152925c5749SYifeng Zhao 
153925c5749SYifeng Zhao 	return ret;
154925c5749SYifeng Zhao }
155925c5749SYifeng Zhao 
156925c5749SYifeng Zhao static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv)
157925c5749SYifeng Zhao {
158925c5749SYifeng Zhao 	int ret = 0;
159925c5749SYifeng Zhao 
160925c5749SYifeng Zhao 	if (priv->cfg->combphy_cfg) {
161925c5749SYifeng Zhao 		ret = priv->cfg->combphy_cfg(priv);
162925c5749SYifeng Zhao 		if (ret) {
163925c5749SYifeng Zhao 			dev_err(priv->dev, "failed to init phy for sata\n");
164925c5749SYifeng Zhao 			return ret;
165925c5749SYifeng Zhao 		}
166925c5749SYifeng Zhao 	}
167925c5749SYifeng Zhao 
168925c5749SYifeng Zhao 	return ret;
169925c5749SYifeng Zhao }
170925c5749SYifeng Zhao 
171925c5749SYifeng Zhao static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv)
172925c5749SYifeng Zhao {
173925c5749SYifeng Zhao 	int ret = 0;
174925c5749SYifeng Zhao 
175925c5749SYifeng Zhao 	if (priv->cfg->combphy_cfg) {
176925c5749SYifeng Zhao 		ret = priv->cfg->combphy_cfg(priv);
177925c5749SYifeng Zhao 		if (ret) {
178925c5749SYifeng Zhao 			dev_err(priv->dev, "failed to init phy for sgmii\n");
179925c5749SYifeng Zhao 			return ret;
180925c5749SYifeng Zhao 		}
181925c5749SYifeng Zhao 	}
182925c5749SYifeng Zhao 
183925c5749SYifeng Zhao 	return ret;
184925c5749SYifeng Zhao }
185925c5749SYifeng Zhao 
18614d5da7dSwilliam.wu int rockchip_combphy_usb3_uboot_init(void)
18714d5da7dSwilliam.wu {
18814d5da7dSwilliam.wu 	struct udevice *udev;
18914d5da7dSwilliam.wu 	struct rockchip_combphy_priv *priv;
19014d5da7dSwilliam.wu 	const struct rockchip_combphy_grfcfg *cfg;
19114d5da7dSwilliam.wu 	u32 val;
19214d5da7dSwilliam.wu 	int ret;
19314d5da7dSwilliam.wu 
19414d5da7dSwilliam.wu 	ret = uclass_get_device_by_driver(UCLASS_PHY,
19514d5da7dSwilliam.wu 					  DM_GET_DRIVER(rockchip_naneng_combphy),
19614d5da7dSwilliam.wu 					  &udev);
19714d5da7dSwilliam.wu 	if (ret) {
19814d5da7dSwilliam.wu 		pr_err("%s: get usb3-phy node failed: %d\n", __func__, ret);
19914d5da7dSwilliam.wu 		return ret;
20014d5da7dSwilliam.wu 	}
20114d5da7dSwilliam.wu 
20214d5da7dSwilliam.wu 	priv = dev_get_priv(udev);
20314d5da7dSwilliam.wu 	priv->mode = PHY_TYPE_USB3;
20414d5da7dSwilliam.wu 	cfg = priv->cfg->grfcfg;
20514d5da7dSwilliam.wu 
20614d5da7dSwilliam.wu 	rockchip_combphy_usb3_init(priv);
20714d5da7dSwilliam.wu 	reset_deassert(&priv->phy_rst);
20814d5da7dSwilliam.wu 
20914d5da7dSwilliam.wu 	if (cfg->pipe_phy_grf_reset.enable)
21014d5da7dSwilliam.wu 		param_write(priv->phy_grf, &cfg->pipe_phy_grf_reset, false);
21114d5da7dSwilliam.wu 
21214d5da7dSwilliam.wu 	if (priv->mode == PHY_TYPE_USB3) {
21314d5da7dSwilliam.wu 		ret = readx_poll_timeout(rockchip_combphy_is_ready,
21414d5da7dSwilliam.wu 					 priv, val,
21514d5da7dSwilliam.wu 					 val == cfg->pipe_phy_status.enable,
21614d5da7dSwilliam.wu 					 1000);
21714d5da7dSwilliam.wu 		if (ret) {
21814d5da7dSwilliam.wu 			dev_err(priv->dev, "wait phy status ready timeout\n");
21914d5da7dSwilliam.wu 			param_write(priv->phy_grf, &cfg->usb_mode_set, false);
22014d5da7dSwilliam.wu 			if (cfg->u3otg0_pipe_clk_sel.disable)
22114d5da7dSwilliam.wu 				param_write(priv->phy_grf, &cfg->u3otg0_pipe_clk_sel, false);
22214d5da7dSwilliam.wu 			return ret;
22314d5da7dSwilliam.wu 		}
22414d5da7dSwilliam.wu 	}
22514d5da7dSwilliam.wu 
22614d5da7dSwilliam.wu 	/* Select clk_usb3otg0_pipe for source clk */
22714d5da7dSwilliam.wu 	if (cfg->u3otg0_pipe_clk_sel.disable)
22814d5da7dSwilliam.wu 		param_write(priv->phy_grf, &cfg->u3otg0_pipe_clk_sel, true);
22914d5da7dSwilliam.wu 
23014d5da7dSwilliam.wu 	return ret;
23114d5da7dSwilliam.wu }
23214d5da7dSwilliam.wu 
233925c5749SYifeng Zhao static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
234925c5749SYifeng Zhao {
235925c5749SYifeng Zhao 	switch (priv->mode) {
236925c5749SYifeng Zhao 	case PHY_TYPE_PCIE:
237925c5749SYifeng Zhao 		rockchip_combphy_pcie_init(priv);
238925c5749SYifeng Zhao 		break;
239925c5749SYifeng Zhao 	case PHY_TYPE_USB3:
240925c5749SYifeng Zhao 		rockchip_combphy_usb3_init(priv);
241925c5749SYifeng Zhao 		break;
242925c5749SYifeng Zhao 	case PHY_TYPE_SATA:
243925c5749SYifeng Zhao 		rockchip_combphy_sata_init(priv);
244925c5749SYifeng Zhao 		break;
245925c5749SYifeng Zhao 	case PHY_TYPE_SGMII:
246925c5749SYifeng Zhao 	case PHY_TYPE_QSGMII:
247925c5749SYifeng Zhao 		return rockchip_combphy_sgmii_init(priv);
248925c5749SYifeng Zhao 	default:
249925c5749SYifeng Zhao 		dev_err(priv->dev, "incompatible PHY type\n");
250925c5749SYifeng Zhao 		return -EINVAL;
251925c5749SYifeng Zhao 	}
252925c5749SYifeng Zhao 
253925c5749SYifeng Zhao 	return 0;
254925c5749SYifeng Zhao }
255925c5749SYifeng Zhao 
256925c5749SYifeng Zhao static int rockchip_combphy_init(struct phy *phy)
257925c5749SYifeng Zhao {
258925c5749SYifeng Zhao 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
25986b316b4SFrank Wang 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
260925c5749SYifeng Zhao 	int ret;
261925c5749SYifeng Zhao 
262925c5749SYifeng Zhao 	ret = clk_enable(&priv->ref_clk);
263925c5749SYifeng Zhao 	if (ret < 0 && ret != -ENOSYS)
264925c5749SYifeng Zhao 		return ret;
265925c5749SYifeng Zhao 
266925c5749SYifeng Zhao 	ret = rockchip_combphy_set_mode(priv);
267925c5749SYifeng Zhao 	if (ret)
268925c5749SYifeng Zhao 		goto err_clk;
269925c5749SYifeng Zhao 
270925c5749SYifeng Zhao 	reset_deassert(&priv->phy_rst);
271925c5749SYifeng Zhao 
27286b316b4SFrank Wang 	if (cfg->pipe_phy_grf_reset.enable)
27386b316b4SFrank Wang 		param_write(priv->phy_grf, &cfg->pipe_phy_grf_reset, false);
27486b316b4SFrank Wang 
275925c5749SYifeng Zhao 	return 0;
276925c5749SYifeng Zhao 
277925c5749SYifeng Zhao err_clk:
278925c5749SYifeng Zhao 	clk_disable(&priv->ref_clk);
279925c5749SYifeng Zhao 
280925c5749SYifeng Zhao 	return ret;
281925c5749SYifeng Zhao }
282925c5749SYifeng Zhao 
283925c5749SYifeng Zhao static int rockchip_combphy_exit(struct phy *phy)
284925c5749SYifeng Zhao {
285925c5749SYifeng Zhao 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
28686b316b4SFrank Wang 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
287925c5749SYifeng Zhao 
28886b316b4SFrank Wang 	if (cfg->pipe_phy_grf_reset.enable)
28986b316b4SFrank Wang 		param_write(priv->phy_grf, &cfg->pipe_phy_grf_reset, true);
29086b316b4SFrank Wang 
291925c5749SYifeng Zhao 	reset_assert(&priv->phy_rst);
29286b316b4SFrank Wang 	clk_disable(&priv->ref_clk);
293925c5749SYifeng Zhao 
294925c5749SYifeng Zhao 	return 0;
295925c5749SYifeng Zhao }
296925c5749SYifeng Zhao 
297925c5749SYifeng Zhao static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *args)
298925c5749SYifeng Zhao {
299925c5749SYifeng Zhao 	struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
300925c5749SYifeng Zhao 
301925c5749SYifeng Zhao 	if (args->args_count != 1) {
302925c5749SYifeng Zhao 		pr_err("invalid number of arguments\n");
303925c5749SYifeng Zhao 		return -EINVAL;
304925c5749SYifeng Zhao 	}
305925c5749SYifeng Zhao 
306925c5749SYifeng Zhao 	priv->mode = args->args[0];
307925c5749SYifeng Zhao 
308925c5749SYifeng Zhao 	return 0;
309925c5749SYifeng Zhao }
310925c5749SYifeng Zhao 
311925c5749SYifeng Zhao static const struct phy_ops rochchip_combphy_ops = {
312925c5749SYifeng Zhao 	.init = rockchip_combphy_init,
313925c5749SYifeng Zhao 	.exit = rockchip_combphy_exit,
314925c5749SYifeng Zhao 	.of_xlate = rockchip_combphy_xlate,
315925c5749SYifeng Zhao };
316925c5749SYifeng Zhao 
317925c5749SYifeng Zhao static int rockchip_combphy_parse_dt(struct udevice *dev,
318925c5749SYifeng Zhao 				     struct rockchip_combphy_priv *priv)
319925c5749SYifeng Zhao {
320925c5749SYifeng Zhao 	struct udevice *syscon;
321925c5749SYifeng Zhao 	int ret;
3227cc44222SJon Lin 	u32 vals[4];
323925c5749SYifeng Zhao 
324925c5749SYifeng Zhao 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon);
325925c5749SYifeng Zhao 	if (ret) {
326cf3c44cbSJon Lin 		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap ret= %d\n", ret);
327925c5749SYifeng Zhao 		return ret;
328925c5749SYifeng Zhao 	}
329925c5749SYifeng Zhao 	priv->pipe_grf = syscon_get_regmap(syscon);
330925c5749SYifeng Zhao 
331925c5749SYifeng Zhao 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon);
332925c5749SYifeng Zhao 	if (ret) {
333925c5749SYifeng Zhao 		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
334925c5749SYifeng Zhao 		return ret;
335925c5749SYifeng Zhao 	}
336925c5749SYifeng Zhao 	priv->phy_grf = syscon_get_regmap(syscon);
337925c5749SYifeng Zhao 
338925c5749SYifeng Zhao 	ret = clk_get_by_index(dev, 0, &priv->ref_clk);
339925c5749SYifeng Zhao 	if (ret) {
340925c5749SYifeng Zhao 		dev_err(dev, "failed to find ref clock\n");
341925c5749SYifeng Zhao 		return PTR_ERR(&priv->ref_clk);
342925c5749SYifeng Zhao 	}
343925c5749SYifeng Zhao 
344dbf89912SRen Jianing 	ret = reset_get_by_name(dev, "combphy", &priv->phy_rst);
345925c5749SYifeng Zhao 	if (ret) {
346925c5749SYifeng Zhao 		dev_err(dev, "no phy reset control specified\n");
347925c5749SYifeng Zhao 		return ret;
348925c5749SYifeng Zhao 	}
349925c5749SYifeng Zhao 
3507cc44222SJon Lin 	if (!dev_read_u32_array(dev, "rockchip,pcie1ln-sel-bits",
3517cc44222SJon Lin 				vals, ARRAY_SIZE(vals)))
3527cc44222SJon Lin 		regmap_write(priv->pipe_grf, vals[0],
3537cc44222SJon Lin 			     (GENMASK(vals[2], vals[1]) << 16) | vals[3]);
3547cc44222SJon Lin 
355925c5749SYifeng Zhao 	return 0;
356925c5749SYifeng Zhao }
357925c5749SYifeng Zhao 
358925c5749SYifeng Zhao static int rockchip_combphy_probe(struct udevice *udev)
359925c5749SYifeng Zhao {
360925c5749SYifeng Zhao 	struct rockchip_combphy_priv *priv = dev_get_priv(udev);
361925c5749SYifeng Zhao 	const struct rockchip_combphy_cfg *phy_cfg;
362925c5749SYifeng Zhao 
363925c5749SYifeng Zhao 	priv->mmio = (void __iomem *)dev_read_addr(udev);
364925c5749SYifeng Zhao 	if (IS_ERR(priv->mmio))
365925c5749SYifeng Zhao 		return PTR_ERR(priv->mmio);
366925c5749SYifeng Zhao 
367925c5749SYifeng Zhao 	phy_cfg = (const struct rockchip_combphy_cfg *)dev_get_driver_data(udev);
368925c5749SYifeng Zhao 	if (!phy_cfg) {
369925c5749SYifeng Zhao 		dev_err(udev, "No OF match data provided\n");
370925c5749SYifeng Zhao 		return -EINVAL;
371925c5749SYifeng Zhao 	}
372925c5749SYifeng Zhao 
373925c5749SYifeng Zhao 	priv->dev = udev;
374925c5749SYifeng Zhao 	priv->mode = PHY_TYPE_SATA;
375925c5749SYifeng Zhao 	priv->cfg = phy_cfg;
376925c5749SYifeng Zhao 
3775eec6d12SJon Lin 	return rockchip_combphy_parse_dt(udev, priv);
378925c5749SYifeng Zhao }
379925c5749SYifeng Zhao 
380fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3528
3813452d642SJianwei Zheng static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
3823452d642SJianwei Zheng {
3833452d642SJianwei Zheng 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
3843452d642SJianwei Zheng 	u32 val;
3853452d642SJianwei Zheng 
3863452d642SJianwei Zheng 	switch (priv->mode) {
3873452d642SJianwei Zheng 	case PHY_TYPE_PCIE:
3883452d642SJianwei Zheng 		/* Set SSC downward spread spectrum */
3893452d642SJianwei Zheng 		val = readl(priv->mmio + 0x18);
3903452d642SJianwei Zheng 		val &= ~GENMASK(5, 4);
3913452d642SJianwei Zheng 		val |= 0x01 << 4;
3923452d642SJianwei Zheng 		writel(val, priv->mmio + 0x18);
3933452d642SJianwei Zheng 
3943452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
3953452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
3963452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
3973452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
3983452d642SJianwei Zheng 		break;
3993452d642SJianwei Zheng 	case PHY_TYPE_USB3:
4003452d642SJianwei Zheng 		/* Set SSC downward spread spectrum */
4013452d642SJianwei Zheng 		val = readl(priv->mmio + 0x18);
4023452d642SJianwei Zheng 		val &= ~GENMASK(5, 4);
4033452d642SJianwei Zheng 		val |= 0x01 << 4;
4043452d642SJianwei Zheng 		writel(val, priv->mmio + 0x18);
4053452d642SJianwei Zheng 
4063452d642SJianwei Zheng 		/* Enable adaptive CTLE for USB3.0 Rx */
4073452d642SJianwei Zheng 		val = readl(priv->mmio + 0x200);
4083452d642SJianwei Zheng 		val &= ~GENMASK(17, 17);
4093452d642SJianwei Zheng 		val |= 0x01;
4103452d642SJianwei Zheng 		writel(val, priv->mmio + 0x200);
4113452d642SJianwei Zheng 
412fc3847fcSWilliam Wu 		/* Set Rx squelch input filler bandwidth */
413fc3847fcSWilliam Wu 		val = readl(priv->mmio + 0x20c);
414fc3847fcSWilliam Wu 		val &= ~GENMASK(2, 0);
415fc3847fcSWilliam Wu 		val |= 0x06;
416fc3847fcSWilliam Wu 		writel(val, priv->mmio + 0x20c);
417fc3847fcSWilliam Wu 
4183452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
4193452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
4203452d642SJianwei Zheng 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
4213452d642SJianwei Zheng 		break;
4223452d642SJianwei Zheng 	default:
4233452d642SJianwei Zheng 		dev_err(priv->dev, "incompatible PHY type\n");
4243452d642SJianwei Zheng 		return -EINVAL;
4253452d642SJianwei Zheng 	}
4263452d642SJianwei Zheng 
4273452d642SJianwei Zheng 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
4283452d642SJianwei Zheng 	if (priv->mode == PHY_TYPE_PCIE) {
4293452d642SJianwei Zheng 		/* PLL KVCO tuning fine */
4303452d642SJianwei Zheng 		val = readl(priv->mmio + 0x18);
4313452d642SJianwei Zheng 		val &= ~(0x7 << 10);
4323452d642SJianwei Zheng 		val |= 0x2 << 10;
4333452d642SJianwei Zheng 		writel(val, priv->mmio + 0x18);
4343452d642SJianwei Zheng 
4353452d642SJianwei Zheng 		/* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */
4363452d642SJianwei Zheng 		val = readl(priv->mmio + 0x108);
4373452d642SJianwei Zheng 		val &= ~(0x7f7);
4383452d642SJianwei Zheng 		val |= 0x4f0;
4393452d642SJianwei Zheng 		writel(val, priv->mmio + 0x108);
4403452d642SJianwei Zheng 	}
4413452d642SJianwei Zheng 
4423452d642SJianwei Zheng 	return 0;
4433452d642SJianwei Zheng }
4443452d642SJianwei Zheng 
4453452d642SJianwei Zheng static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = {
4463452d642SJianwei Zheng 	/* pipe-phy-grf */
4473452d642SJianwei Zheng 	.pcie_mode_set		= { 0x48000, 5, 0, 0x00, 0x11 },
4483452d642SJianwei Zheng 	.usb_mode_set		= { 0x48000, 5, 0, 0x00, 0x04 },
4493452d642SJianwei Zheng 	.pipe_rxterm_set	= { 0x48000, 12, 12, 0x00, 0x01 },
4503452d642SJianwei Zheng 	.pipe_txelec_set	= { 0x48004, 1, 1, 0x00, 0x01 },
4513452d642SJianwei Zheng 	.pipe_txcomp_set	= { 0x48004, 4, 4, 0x00, 0x01 },
4523452d642SJianwei Zheng 	.pipe_clk_24m		= { 0x48004, 14, 13, 0x00, 0x00 },
4533452d642SJianwei Zheng 	.pipe_clk_100m		= { 0x48004, 14, 13, 0x00, 0x02 },
4543452d642SJianwei Zheng 	.pipe_rxterm_sel	= { 0x48008, 8, 8, 0x00, 0x01 },
4553452d642SJianwei Zheng 	.pipe_txelec_sel	= { 0x48008, 12, 12, 0x00, 0x01 },
4563452d642SJianwei Zheng 	.pipe_txcomp_sel	= { 0x48008, 15, 15, 0x00, 0x01 },
4573452d642SJianwei Zheng 	.pipe_clk_ext		= { 0x4800c, 9, 8, 0x02, 0x01 },
4583452d642SJianwei Zheng 	.pipe_phy_status	= { 0x48034, 6, 6, 0x01, 0x00 },
4593452d642SJianwei Zheng 	.con0_for_pcie		= { 0x48000, 15, 0, 0x00, 0x110 },
4603452d642SJianwei Zheng 	.con1_for_pcie		= { 0x48004, 15, 0, 0x00, 0x00 },
4613452d642SJianwei Zheng 	.con2_for_pcie		= { 0x48008, 15, 0, 0x00, 0x101 },
4623452d642SJianwei Zheng 	.con3_for_pcie		= { 0x4800c, 15, 0, 0x00, 0x0200 },
4633452d642SJianwei Zheng 	/* pipe-grf */
46414d5da7dSwilliam.wu 	.u3otg0_pipe_clk_sel	= { 0x40044, 7, 7, 0x01, 0x00 },
4653452d642SJianwei Zheng 	.u3otg0_port_en		= { 0x40044, 15, 0, 0x0181, 0x1100 },
4663452d642SJianwei Zheng };
4673452d642SJianwei Zheng 
4683452d642SJianwei Zheng static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = {
4693452d642SJianwei Zheng 	.grfcfg		= &rk3528_combphy_grfcfgs,
4703452d642SJianwei Zheng 	.combphy_cfg	= rk3528_combphy_cfg,
4713452d642SJianwei Zheng };
472fc22f2adSWilliam Wu #endif
4733452d642SJianwei Zheng 
474fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3562
475885c5d5dSFrank Wang static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
476885c5d5dSFrank Wang {
477885c5d5dSFrank Wang 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
478885c5d5dSFrank Wang 	u32 val;
479885c5d5dSFrank Wang 
480885c5d5dSFrank Wang 	switch (priv->mode) {
481885c5d5dSFrank Wang 	case PHY_TYPE_PCIE:
482885c5d5dSFrank Wang 		/* Set SSC downward spread spectrum */
483885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x1f << 2));
484885c5d5dSFrank Wang 		val &= ~GENMASK(5, 4);
485885c5d5dSFrank Wang 		val |= 0x01 << 4;
486885c5d5dSFrank Wang 		writel(val, priv->mmio + 0x7c);
487885c5d5dSFrank Wang 
488885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
489885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
490885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
491885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
492885c5d5dSFrank Wang 		break;
493885c5d5dSFrank Wang 	case PHY_TYPE_USB3:
494885c5d5dSFrank Wang 		/* Set SSC downward spread spectrum */
495885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x1f << 2));
496885c5d5dSFrank Wang 		val &= ~GENMASK(5, 4);
497885c5d5dSFrank Wang 		val |= 0x01 << 4;
498885c5d5dSFrank Wang 		writel(val, priv->mmio + 0x7c);
499885c5d5dSFrank Wang 
500885c5d5dSFrank Wang 		/* Enable adaptive CTLE for USB3.0 Rx */
501885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x0e << 2));
502885c5d5dSFrank Wang 		val &= ~GENMASK(0, 0);
503885c5d5dSFrank Wang 		val |= 0x01;
504885c5d5dSFrank Wang 		writel(val, priv->mmio + (0x0e << 2));
505885c5d5dSFrank Wang 
506885c5d5dSFrank Wang 		/* Set PLL KVCO fine tuning signals */
507885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x20 << 2));
508885c5d5dSFrank Wang 		val &= ~(0x7 << 2);
509885c5d5dSFrank Wang 		val |= 0x2 << 2;
510885c5d5dSFrank Wang 		writel(val, priv->mmio + (0x20 << 2));
511885c5d5dSFrank Wang 
512885c5d5dSFrank Wang 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
513885c5d5dSFrank Wang 		writel(0x4, priv->mmio + (0xb << 2));
514885c5d5dSFrank Wang 
515885c5d5dSFrank Wang 		/* Set PLL input clock divider 1/2 */
516885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x5 << 2));
517885c5d5dSFrank Wang 		val &= ~(0x3 << 6);
518885c5d5dSFrank Wang 		val |= 0x1 << 6;
519885c5d5dSFrank Wang 		writel(val, priv->mmio + (0x5 << 2));
520885c5d5dSFrank Wang 
521885c5d5dSFrank Wang 		/* Set PLL loop divider */
522885c5d5dSFrank Wang 		writel(0x32, priv->mmio + (0x11 << 2));
523885c5d5dSFrank Wang 
524885c5d5dSFrank Wang 		/* Set PLL KVCO to min and set PLL charge pump current to max */
525885c5d5dSFrank Wang 		writel(0xf0, priv->mmio + (0xa << 2));
526885c5d5dSFrank Wang 
527fc3847fcSWilliam Wu 		/* Set Rx squelch input filler bandwidth */
528fc3847fcSWilliam Wu 		writel(0x0e, priv->mmio + (0x14 << 2));
529fc3847fcSWilliam Wu 
530885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
531885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
532885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
533885c5d5dSFrank Wang 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
534885c5d5dSFrank Wang 		break;
535885c5d5dSFrank Wang 	default:
536885c5d5dSFrank Wang 		pr_err("%s, phy-type %d\n", __func__, priv->mode);
537885c5d5dSFrank Wang 		return -EINVAL;
538885c5d5dSFrank Wang 	}
539885c5d5dSFrank Wang 
540885c5d5dSFrank Wang 	clk_set_rate(&priv->ref_clk, 100000000);
541885c5d5dSFrank Wang 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
542885c5d5dSFrank Wang 
543cc9876f4SJon Lin 	if (priv->mode == PHY_TYPE_PCIE) {
544cc9876f4SJon Lin 		/* PLL KVCO tuning fine */
545cc9876f4SJon Lin 		val = readl(priv->mmio + (0x20 << 2));
546cc9876f4SJon Lin 		val &= ~(0x7 << 2);
547cc9876f4SJon Lin 		val |= 0x2 << 2;
548cc9876f4SJon Lin 		writel(val, priv->mmio + (0x20 << 2));
549cc9876f4SJon Lin 
550cc9876f4SJon Lin 		/* Enable controlling random jitter, aka RMJ */
551cc9876f4SJon Lin 		writel(0x4, priv->mmio + (0xb << 2));
552cc9876f4SJon Lin 
553cc9876f4SJon Lin 		val = readl(priv->mmio + (0x5 << 2));
554cc9876f4SJon Lin 		val &= ~(0x3 << 6);
555cc9876f4SJon Lin 		val |= 0x1 << 6;
556cc9876f4SJon Lin 		writel(val, priv->mmio + (0x5 << 2));
557cc9876f4SJon Lin 
558cc9876f4SJon Lin 		writel(0x32, priv->mmio + (0x11 << 2));
559cc9876f4SJon Lin 		writel(0xf0, priv->mmio + (0xa << 2));
560cc9876f4SJon Lin 	}
561cc9876f4SJon Lin 
562885c5d5dSFrank Wang 	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
563885c5d5dSFrank Wang 		val = readl(priv->mmio + (0x7 << 2));
564885c5d5dSFrank Wang 		val |= BIT(4);
565885c5d5dSFrank Wang 		writel(val, priv->mmio + (0x7 << 2));
566885c5d5dSFrank Wang 	}
567885c5d5dSFrank Wang 
568885c5d5dSFrank Wang 	return 0;
569885c5d5dSFrank Wang }
570885c5d5dSFrank Wang 
571885c5d5dSFrank Wang static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = {
572885c5d5dSFrank Wang 	/* pipe-phy-grf */
573885c5d5dSFrank Wang 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
574885c5d5dSFrank Wang 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
575885c5d5dSFrank Wang 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
576885c5d5dSFrank Wang 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
577885c5d5dSFrank Wang 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
578885c5d5dSFrank Wang 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
579885c5d5dSFrank Wang 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
580885c5d5dSFrank Wang 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
581885c5d5dSFrank Wang 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
582885c5d5dSFrank Wang 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
583885c5d5dSFrank Wang 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
584885c5d5dSFrank Wang 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
585885c5d5dSFrank Wang 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
586885c5d5dSFrank Wang 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
587885c5d5dSFrank Wang 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
588885c5d5dSFrank Wang 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
589885c5d5dSFrank Wang 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
590885c5d5dSFrank Wang 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
591885c5d5dSFrank Wang 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
59286b316b4SFrank Wang 	.pipe_phy_grf_reset	= { 0x0014, 1, 0, 0x3, 0x1 },
593885c5d5dSFrank Wang 	/* pipe-grf */
594885c5d5dSFrank Wang 	.u3otg0_port_en		= { 0x0094, 15, 0, 0x0181, 0x1100 },
595885c5d5dSFrank Wang };
596885c5d5dSFrank Wang 
597885c5d5dSFrank Wang static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = {
598885c5d5dSFrank Wang 	.grfcfg		= &rk3562_combphy_grfcfgs,
599885c5d5dSFrank Wang 	.combphy_cfg	= rk3562_combphy_cfg,
600885c5d5dSFrank Wang };
601fc22f2adSWilliam Wu #endif
602885c5d5dSFrank Wang 
603fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3568
604925c5749SYifeng Zhao static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
605925c5749SYifeng Zhao {
606925c5749SYifeng Zhao 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
607925c5749SYifeng Zhao 	u32 val;
608925c5749SYifeng Zhao 
609925c5749SYifeng Zhao 	switch (priv->mode) {
610925c5749SYifeng Zhao 	case PHY_TYPE_PCIE:
611925c5749SYifeng Zhao 		/* Set SSC downward spread spectrum */
612925c5749SYifeng Zhao 		val = readl(priv->mmio + (0x1f << 2));
613925c5749SYifeng Zhao 		val &= ~GENMASK(5, 4);
614925c5749SYifeng Zhao 		val |= 0x01 << 4;
615925c5749SYifeng Zhao 		writel(val, priv->mmio + 0x7c);
616925c5749SYifeng Zhao 
617925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
618925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
619925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
620925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
621925c5749SYifeng Zhao 		break;
622925c5749SYifeng Zhao 	case PHY_TYPE_USB3:
623925c5749SYifeng Zhao 		/* Set SSC downward spread spectrum */
624925c5749SYifeng Zhao 		val = readl(priv->mmio + (0x1f << 2));
625925c5749SYifeng Zhao 		val &= ~GENMASK(5, 4);
626925c5749SYifeng Zhao 		val |= 0x01 << 4;
627925c5749SYifeng Zhao 		writel(val, priv->mmio + 0x7c);
628925c5749SYifeng Zhao 
629925c5749SYifeng Zhao 		/* Enable adaptive CTLE for USB3.0 Rx */
630925c5749SYifeng Zhao 		val = readl(priv->mmio + (0x0e << 2));
631925c5749SYifeng Zhao 		val &= ~GENMASK(0, 0);
632925c5749SYifeng Zhao 		val |= 0x01;
633925c5749SYifeng Zhao 		writel(val, priv->mmio + (0x0e << 2));
634925c5749SYifeng Zhao 
635a0d03578SWilliam Wu 		/* Set PLL KVCO fine tuning signals */
636a0d03578SWilliam Wu 		val = readl(priv->mmio + (0x20 << 2));
637a0d03578SWilliam Wu 		val &= ~(0x7 << 2);
638a0d03578SWilliam Wu 		val |= 0x2 << 2;
639a0d03578SWilliam Wu 		writel(val, priv->mmio + (0x20 << 2));
640a0d03578SWilliam Wu 
641a0d03578SWilliam Wu 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
642a0d03578SWilliam Wu 		writel(0x4, priv->mmio + (0xb << 2));
643a0d03578SWilliam Wu 
644a0d03578SWilliam Wu 		/* Set PLL input clock divider 1/2 */
645a0d03578SWilliam Wu 		val = readl(priv->mmio + (0x5 << 2));
646a0d03578SWilliam Wu 		val &= ~(0x3 << 6);
647a0d03578SWilliam Wu 		val |= 0x1 << 6;
648a0d03578SWilliam Wu 		writel(val, priv->mmio + (0x5 << 2));
649a0d03578SWilliam Wu 
650a0d03578SWilliam Wu 		/* Set PLL loop divider */
651a0d03578SWilliam Wu 		writel(0x32, priv->mmio + (0x11 << 2));
652a0d03578SWilliam Wu 
653a0d03578SWilliam Wu 		/* Set PLL KVCO to min and set PLL charge pump current to max */
654a0d03578SWilliam Wu 		writel(0xf0, priv->mmio + (0xa << 2));
655a0d03578SWilliam Wu 
656fc3847fcSWilliam Wu 		/* Set Rx squelch input filler bandwidth */
657fc3847fcSWilliam Wu 		writel(0x0e, priv->mmio + (0x14 << 2));
658fc3847fcSWilliam Wu 
659925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
660925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
661925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
662925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
663925c5749SYifeng Zhao 		break;
664925c5749SYifeng Zhao 	case PHY_TYPE_SATA:
665925c5749SYifeng Zhao 		writel(0x41, priv->mmio + 0x38);
666925c5749SYifeng Zhao 		writel(0x8F, priv->mmio + 0x18);
667925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
668925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
669925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
670925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
671925c5749SYifeng Zhao 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
672925c5749SYifeng Zhao 		break;
673925c5749SYifeng Zhao 	case PHY_TYPE_SGMII:
674925c5749SYifeng Zhao 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
675925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
676925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
677925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
678925c5749SYifeng Zhao 		break;
679925c5749SYifeng Zhao 	case PHY_TYPE_QSGMII:
680925c5749SYifeng Zhao 		param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
681925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
682925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
683925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
684925c5749SYifeng Zhao 		param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
685925c5749SYifeng Zhao 		break;
686925c5749SYifeng Zhao 	default:
687925c5749SYifeng Zhao 		pr_err("%s, phy-type %d\n", __func__, priv->mode);
688925c5749SYifeng Zhao 		return -EINVAL;
689925c5749SYifeng Zhao 	}
690925c5749SYifeng Zhao 
691dbf89912SRen Jianing 	/* The default ref clock is 25Mhz */
692dbf89912SRen Jianing 	param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
693925c5749SYifeng Zhao 
694925c5749SYifeng Zhao 	if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) {
695925c5749SYifeng Zhao 		val = readl(priv->mmio + (0x7 << 2));
696925c5749SYifeng Zhao 		val |= BIT(4);
697925c5749SYifeng Zhao 		writel(val, priv->mmio + (0x7 << 2));
698925c5749SYifeng Zhao 	}
699925c5749SYifeng Zhao 
700925c5749SYifeng Zhao 	return 0;
701925c5749SYifeng Zhao }
702925c5749SYifeng Zhao 
703925c5749SYifeng Zhao static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
704925c5749SYifeng Zhao 	/* pipe-phy-grf */
705925c5749SYifeng Zhao 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
706925c5749SYifeng Zhao 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
707925c5749SYifeng Zhao 	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
708925c5749SYifeng Zhao 	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
709925c5749SYifeng Zhao 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
710925c5749SYifeng Zhao 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
711925c5749SYifeng Zhao 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
712925c5749SYifeng Zhao 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
713925c5749SYifeng Zhao 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
714925c5749SYifeng Zhao 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
715925c5749SYifeng Zhao 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
716925c5749SYifeng Zhao 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
717925c5749SYifeng Zhao 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
718925c5749SYifeng Zhao 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
719925c5749SYifeng Zhao 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
720925c5749SYifeng Zhao 	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
721925c5749SYifeng Zhao 	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
722925c5749SYifeng Zhao 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
723925c5749SYifeng Zhao 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
724925c5749SYifeng Zhao 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
725925c5749SYifeng Zhao 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
726925c5749SYifeng Zhao 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
727925c5749SYifeng Zhao 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
728925c5749SYifeng Zhao 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
729925c5749SYifeng Zhao 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
730925c5749SYifeng Zhao 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
731925c5749SYifeng Zhao 	/* pipe-grf */
732925c5749SYifeng Zhao 	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
733925c5749SYifeng Zhao 	.pipe_sgmii_mac_sel	= { 0x0040, 1, 1, 0x00, 0x01 },
734925c5749SYifeng Zhao 	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
735925c5749SYifeng Zhao 	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
736925c5749SYifeng Zhao 	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
737925c5749SYifeng Zhao };
738925c5749SYifeng Zhao 
739925c5749SYifeng Zhao static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
740925c5749SYifeng Zhao 	.grfcfg		= &rk3568_combphy_grfcfgs,
741925c5749SYifeng Zhao 	.combphy_cfg	= rk3568_combphy_cfg,
742925c5749SYifeng Zhao };
743fc22f2adSWilliam Wu #endif
744925c5749SYifeng Zhao 
745fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3588
746cf3c44cbSJon Lin static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
747cf3c44cbSJon Lin {
748cf3c44cbSJon Lin 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
749d8968f57SWilliam Wu 	u32 val;
750cf3c44cbSJon Lin 
751cf3c44cbSJon Lin 	switch (priv->mode) {
752cf3c44cbSJon Lin 	case PHY_TYPE_PCIE:
753cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
754cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
755cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
756cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
757cf3c44cbSJon Lin 		break;
758cf3c44cbSJon Lin 	case PHY_TYPE_USB3:
759d8968f57SWilliam Wu 		/* Set SSC downward spread spectrum */
760d8968f57SWilliam Wu 		val = readl(priv->mmio + (0x1f << 2));
761d8968f57SWilliam Wu 		val &= ~GENMASK(5, 4);
762d8968f57SWilliam Wu 		val |= 0x01 << 4;
763d8968f57SWilliam Wu 		writel(val, priv->mmio + 0x7c);
764d8968f57SWilliam Wu 
765d8968f57SWilliam Wu 		/* Enable adaptive CTLE for USB3.0 Rx */
766d8968f57SWilliam Wu 		val = readl(priv->mmio + (0x0e << 2));
767d8968f57SWilliam Wu 		val &= ~GENMASK(0, 0);
768d8968f57SWilliam Wu 		val |= 0x01;
769d8968f57SWilliam Wu 		writel(val, priv->mmio + (0x0e << 2));
770d8968f57SWilliam Wu 
771d8968f57SWilliam Wu 		/* Set PLL KVCO fine tuning signals */
772d8968f57SWilliam Wu 		val = readl(priv->mmio + (0x20 << 2));
773d8968f57SWilliam Wu 		val &= ~(0x7 << 2);
774d8968f57SWilliam Wu 		val |= 0x2 << 2;
775d8968f57SWilliam Wu 		writel(val, priv->mmio + (0x20 << 2));
776d8968f57SWilliam Wu 
777d8968f57SWilliam Wu 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
778d8968f57SWilliam Wu 		writel(0x4, priv->mmio + (0xb << 2));
779d8968f57SWilliam Wu 
780d8968f57SWilliam Wu 		/* Set PLL input clock divider 1/2 */
781d8968f57SWilliam Wu 		val = readl(priv->mmio + (0x5 << 2));
782d8968f57SWilliam Wu 		val &= ~(0x3 << 6);
783d8968f57SWilliam Wu 		val |= 0x1 << 6;
784d8968f57SWilliam Wu 		writel(val, priv->mmio + (0x5 << 2));
785d8968f57SWilliam Wu 
786d8968f57SWilliam Wu 		/* Set PLL loop divider */
787d8968f57SWilliam Wu 		writel(0x32, priv->mmio + (0x11 << 2));
788d8968f57SWilliam Wu 
789d8968f57SWilliam Wu 		/* Set PLL KVCO to min and set PLL charge pump current to max */
790d8968f57SWilliam Wu 		writel(0xf0, priv->mmio + (0xa << 2));
791d8968f57SWilliam Wu 
79287bfcd06SWilliam Wu 		/* Set Rx squelch input filler bandwidth */
79387bfcd06SWilliam Wu 		writel(0x0d, priv->mmio + (0x14 << 2));
79487bfcd06SWilliam Wu 
795cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
796cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
797cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
798cf3c44cbSJon Lin 		break;
799cf3c44cbSJon Lin 	case PHY_TYPE_SATA:
800418dd88dSYifeng Zhao 		/* Enable adaptive CTLE for SATA Rx */
801418dd88dSYifeng Zhao 		val = readl(priv->mmio + (0x0e << 2));
802418dd88dSYifeng Zhao 		val &= ~GENMASK(0, 0);
803418dd88dSYifeng Zhao 		val |= 0x01;
804418dd88dSYifeng Zhao 		writel(val, priv->mmio + (0x0e << 2));
805418dd88dSYifeng Zhao 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
806418dd88dSYifeng Zhao 		writel(0x8F, priv->mmio + (0x06 << 2));
807418dd88dSYifeng Zhao 
808cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
809cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
810cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
811cf3c44cbSJon Lin 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
812cf3c44cbSJon Lin 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
813cf3c44cbSJon Lin 		param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
814cf3c44cbSJon Lin 		break;
815cf3c44cbSJon Lin 	case PHY_TYPE_SGMII:
816cf3c44cbSJon Lin 	case PHY_TYPE_QSGMII:
817cf3c44cbSJon Lin 	default:
818cf3c44cbSJon Lin 		dev_err(priv->dev, "incompatible PHY type\n");
819cf3c44cbSJon Lin 		return -EINVAL;
820cf3c44cbSJon Lin 	}
821cf3c44cbSJon Lin 
822c72d402cSJon Lin 	/* 100MHz refclock signal is good */
823c72d402cSJon Lin 	clk_set_rate(&priv->ref_clk, 100000000);
824cf3c44cbSJon Lin 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
825e278c201SKever Yang 	if (priv->mode == PHY_TYPE_PCIE) {
826e278c201SKever Yang 		/* PLL KVCO tuning fine */
827e278c201SKever Yang 		val = readl(priv->mmio + (0x20 << 2));
828e278c201SKever Yang 		val &= ~GENMASK(4, 2);
829e278c201SKever Yang 		val |= 0x4 << 2;
830e278c201SKever Yang 		writel(val, priv->mmio + (0x20 << 2));
831e278c201SKever Yang 
832e278c201SKever Yang 		/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
833e278c201SKever Yang 		val = 0x4c;
834e278c201SKever Yang 		writel(val, priv->mmio + (0x1b << 2));
835e278c201SKever Yang 
836e278c201SKever Yang 		/* Set up su_trim: T3 */
837e278c201SKever Yang 		val = 0xb0;
838e278c201SKever Yang 		writel(val, priv->mmio + (0xa << 2));
839e278c201SKever Yang 		val = 0x47;
840e278c201SKever Yang 		writel(val, priv->mmio + (0xb << 2));
841e278c201SKever Yang 		val = 0x57;
842e278c201SKever Yang 		writel(val, priv->mmio + (0xd << 2));
843e278c201SKever Yang 	}
844cf3c44cbSJon Lin 
845cf3c44cbSJon Lin 	return 0;
846cf3c44cbSJon Lin }
847cf3c44cbSJon Lin 
848cf3c44cbSJon Lin static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
849cf3c44cbSJon Lin 	/* pipe-phy-grf */
850cf3c44cbSJon Lin 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
851cf3c44cbSJon Lin 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
852cf3c44cbSJon Lin 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
853cf3c44cbSJon Lin 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
854cf3c44cbSJon Lin 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
855cf3c44cbSJon Lin 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
856cf3c44cbSJon Lin 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
857cf3c44cbSJon Lin 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
858cf3c44cbSJon Lin 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
859cf3c44cbSJon Lin 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
860cf3c44cbSJon Lin 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
861cf3c44cbSJon Lin 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
862cf3c44cbSJon Lin 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
863cf3c44cbSJon Lin 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
864cf3c44cbSJon Lin 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
865cf3c44cbSJon Lin 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
866cf3c44cbSJon Lin 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
867418dd88dSYifeng Zhao 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
868cf3c44cbSJon Lin 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
869cf3c44cbSJon Lin 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
870cf3c44cbSJon Lin 	/* pipe-grf */
871cf3c44cbSJon Lin 	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
872cf3c44cbSJon Lin 	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
873cf3c44cbSJon Lin };
874cf3c44cbSJon Lin 
875cf3c44cbSJon Lin static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
876cf3c44cbSJon Lin 	.grfcfg		= &rk3588_combphy_grfcfgs,
877cf3c44cbSJon Lin 	.combphy_cfg	= rk3588_combphy_cfg,
878cf3c44cbSJon Lin };
879fc22f2adSWilliam Wu #endif
880cf3c44cbSJon Lin 
8813f21b61aSJon Lin 
8823f21b61aSJon Lin #ifdef CONFIG_ROCKCHIP_RK3576
8833f21b61aSJon Lin static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
8843f21b61aSJon Lin {
8853f21b61aSJon Lin 	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
8863f21b61aSJon Lin 	u32 val;
8873f21b61aSJon Lin 
8883f21b61aSJon Lin 	switch (priv->mode) {
8893f21b61aSJon Lin 	case PHY_TYPE_PCIE:
8903f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
8913f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
8923f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
8933f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
8943f21b61aSJon Lin 		break;
8953f21b61aSJon Lin 	case PHY_TYPE_USB3:
8963f21b61aSJon Lin 		/* Set SSC downward spread spectrum */
8973f21b61aSJon Lin 		val = readl(priv->mmio + (0x1f << 2));
8983f21b61aSJon Lin 		val &= ~GENMASK(5, 4);
8993f21b61aSJon Lin 		val |= 0x01 << 4;
9003f21b61aSJon Lin 		writel(val, priv->mmio + 0x7c);
9013f21b61aSJon Lin 
9023f21b61aSJon Lin 		/* Enable adaptive CTLE for USB3.0 Rx */
9033f21b61aSJon Lin 		val = readl(priv->mmio + (0x0e << 2));
9043f21b61aSJon Lin 		val &= ~GENMASK(0, 0);
9053f21b61aSJon Lin 		val |= 0x01;
9063f21b61aSJon Lin 		writel(val, priv->mmio + (0x0e << 2));
9073f21b61aSJon Lin 
9083f21b61aSJon Lin 		/* Set PLL KVCO fine tuning signals */
9093f21b61aSJon Lin 		val = readl(priv->mmio + (0x20 << 2));
9103f21b61aSJon Lin 		val &= ~(0x7 << 2);
9113f21b61aSJon Lin 		val |= 0x2 << 2;
9123f21b61aSJon Lin 		writel(val, priv->mmio + (0x20 << 2));
9133f21b61aSJon Lin 
9143f21b61aSJon Lin 		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
9153f21b61aSJon Lin 		writel(0x4, priv->mmio + (0xb << 2));
9163f21b61aSJon Lin 
9173f21b61aSJon Lin 		/* Set PLL input clock divider 1/2 */
9183f21b61aSJon Lin 		val = readl(priv->mmio + (0x5 << 2));
9193f21b61aSJon Lin 		val &= ~(0x3 << 6);
9203f21b61aSJon Lin 		val |= 0x1 << 6;
9213f21b61aSJon Lin 		writel(val, priv->mmio + (0x5 << 2));
9223f21b61aSJon Lin 
9233f21b61aSJon Lin 		/* Set PLL loop divider */
9243f21b61aSJon Lin 		writel(0x32, priv->mmio + (0x11 << 2));
9253f21b61aSJon Lin 
9263f21b61aSJon Lin 		/* Set PLL KVCO to min and set PLL charge pump current to max */
9273f21b61aSJon Lin 		writel(0xf0, priv->mmio + (0xa << 2));
9283f21b61aSJon Lin 
9293f21b61aSJon Lin 		/* Set Rx squelch input filler bandwidth */
9303f21b61aSJon Lin 		writel(0x0d, priv->mmio + (0x14 << 2));
9313f21b61aSJon Lin 
9323f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
9333f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
9343f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->usb_mode_set, true);
9353f21b61aSJon Lin 		break;
9363f21b61aSJon Lin 	case PHY_TYPE_SATA:
9373f21b61aSJon Lin 		/* Enable adaptive CTLE for SATA Rx */
9383f21b61aSJon Lin 		val = readl(priv->mmio + (0x0e << 2));
9393f21b61aSJon Lin 		val &= ~GENMASK(0, 0);
9403f21b61aSJon Lin 		val |= 0x01;
9413f21b61aSJon Lin 		writel(val, priv->mmio + (0x0e << 2));
9423f21b61aSJon Lin 		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
9433f21b61aSJon Lin 		writel(0x8F, priv->mmio + (0x06 << 2));
9443f21b61aSJon Lin 
9453f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con0_for_sata, true);
9463f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con1_for_sata, true);
9473f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con2_for_sata, true);
9483f21b61aSJon Lin 		param_write(priv->phy_grf, &cfg->con3_for_sata, true);
9493f21b61aSJon Lin 		param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
9503f21b61aSJon Lin 		param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
9513f21b61aSJon Lin 		break;
9523f21b61aSJon Lin 	case PHY_TYPE_SGMII:
9533f21b61aSJon Lin 	case PHY_TYPE_QSGMII:
9543f21b61aSJon Lin 	default:
9553f21b61aSJon Lin 		dev_err(priv->dev, "incompatible PHY type\n");
9563f21b61aSJon Lin 		return -EINVAL;
9573f21b61aSJon Lin 	}
9583f21b61aSJon Lin 
9593f21b61aSJon Lin 	/* 100MHz refclock signal is good */
9603f21b61aSJon Lin 	clk_set_rate(&priv->ref_clk, 100000000);
9613f21b61aSJon Lin 	param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
9623f21b61aSJon Lin 	if (priv->mode == PHY_TYPE_PCIE) {
9633f21b61aSJon Lin 		/* gate_tx_pck_sel length select work for L1SS */
9643f21b61aSJon Lin 		writel(0xc0, priv->mmio + 0x74);
9653f21b61aSJon Lin 
9663f21b61aSJon Lin 		/* PLL KVCO tuning fine */
9673f21b61aSJon Lin 		val = readl(priv->mmio + (0x20 << 2));
9683f21b61aSJon Lin 		val &= ~(0x7 << 2);
9693f21b61aSJon Lin 		val |= 0x2 << 2;
9703f21b61aSJon Lin 		writel(val, priv->mmio + (0x20 << 2));
9713f21b61aSJon Lin 
9723f21b61aSJon Lin 		/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
9733f21b61aSJon Lin 		writel(0x4c, priv->mmio + (0x1b << 2));
9743f21b61aSJon Lin 
9753f21b61aSJon Lin 		/* Set up su_trim: T3_P1 650mv */
9763f21b61aSJon Lin 		writel(0x90, priv->mmio + (0xa << 2));
9773f21b61aSJon Lin 		writel(0x43, priv->mmio + (0xb << 2));
9783f21b61aSJon Lin 		writel(0x88, priv->mmio + (0xc << 2));
9793f21b61aSJon Lin 		writel(0x56, priv->mmio + (0xd << 2));
9803f21b61aSJon Lin 	}
9813f21b61aSJon Lin 
9823f21b61aSJon Lin 	return 0;
9833f21b61aSJon Lin }
9843f21b61aSJon Lin 
9853f21b61aSJon Lin static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
9863f21b61aSJon Lin 	/* pipe-phy-grf */
9873f21b61aSJon Lin 	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
9883f21b61aSJon Lin 	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
9893f21b61aSJon Lin 	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
9903f21b61aSJon Lin 	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
9913f21b61aSJon Lin 	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
9923f21b61aSJon Lin 	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
9933f21b61aSJon Lin 	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
9943f21b61aSJon Lin 	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
9953f21b61aSJon Lin 	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
9963f21b61aSJon Lin 	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
9973f21b61aSJon Lin 	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
9983f21b61aSJon Lin 	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
9993f21b61aSJon Lin 	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
10003f21b61aSJon Lin 	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
10013f21b61aSJon Lin 	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
10023f21b61aSJon Lin 	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
10033f21b61aSJon Lin 	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
10043f21b61aSJon Lin 	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
10053f21b61aSJon Lin 	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
10063f21b61aSJon Lin 	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
10073f21b61aSJon Lin 	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
10083f21b61aSJon Lin 	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
10093f21b61aSJon Lin 	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
10103f21b61aSJon Lin 	.pipe_phy_grf_reset	= { 0x0014, 1, 0, 0x3, 0x1 },
10113f21b61aSJon Lin 	/* php-grf */
10123f21b61aSJon Lin 	.pipe_con0_for_sata	= { 0x001C, 2, 0, 0x00, 0x2 },
10133f21b61aSJon Lin 	.pipe_con1_for_sata	= { 0x0020, 2, 0, 0x00, 0x2 },
10143f21b61aSJon Lin 	.u3otg1_port_en		= { 0x0038, 15, 0, 0x0181, 0x1100 },
10153f21b61aSJon Lin };
10163f21b61aSJon Lin 
10173f21b61aSJon Lin static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
10183f21b61aSJon Lin 	.grfcfg		= &rk3576_combphy_grfcfgs,
10193f21b61aSJon Lin 	.combphy_cfg	= rk3576_combphy_cfg,
10203f21b61aSJon Lin };
10213f21b61aSJon Lin #endif
10223f21b61aSJon Lin 
1023925c5749SYifeng Zhao static const struct udevice_id rockchip_combphy_ids[] = {
1024fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3528
1025925c5749SYifeng Zhao 	{
10263452d642SJianwei Zheng 		.compatible = "rockchip,rk3528-naneng-combphy",
10273452d642SJianwei Zheng 		.data = (ulong)&rk3528_combphy_cfgs
10283452d642SJianwei Zheng 	},
1029fc22f2adSWilliam Wu #endif
1030fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3562
10313452d642SJianwei Zheng 	{
1032885c5d5dSFrank Wang 		.compatible = "rockchip,rk3562-naneng-combphy",
1033885c5d5dSFrank Wang 		.data = (ulong)&rk3562_combphy_cfgs
1034885c5d5dSFrank Wang 	},
1035fc22f2adSWilliam Wu #endif
1036fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3568
1037885c5d5dSFrank Wang 	{
1038925c5749SYifeng Zhao 		.compatible = "rockchip,rk3568-naneng-combphy",
1039925c5749SYifeng Zhao 		.data = (ulong)&rk3568_combphy_cfgs
1040925c5749SYifeng Zhao 	},
1041fc22f2adSWilliam Wu #endif
1042fc22f2adSWilliam Wu #ifdef CONFIG_ROCKCHIP_RK3588
1043cf3c44cbSJon Lin 	{
1044cf3c44cbSJon Lin 		.compatible = "rockchip,rk3588-naneng-combphy",
1045cf3c44cbSJon Lin 		.data = (ulong)&rk3588_combphy_cfgs
1046cf3c44cbSJon Lin 	},
1047fc22f2adSWilliam Wu #endif
10483f21b61aSJon Lin #ifdef CONFIG_ROCKCHIP_RK3576
10493f21b61aSJon Lin 	{
10503f21b61aSJon Lin 		.compatible = "rockchip,rk3576-naneng-combphy",
10513f21b61aSJon Lin 		.data = (ulong)&rk3576_combphy_cfgs
10523f21b61aSJon Lin 	},
10533f21b61aSJon Lin #endif
1054925c5749SYifeng Zhao 	{ }
1055925c5749SYifeng Zhao };
1056925c5749SYifeng Zhao 
1057925c5749SYifeng Zhao U_BOOT_DRIVER(rockchip_naneng_combphy) = {
1058925c5749SYifeng Zhao 	.name		= "naneng-combphy",
1059925c5749SYifeng Zhao 	.id		= UCLASS_PHY,
1060925c5749SYifeng Zhao 	.of_match	= rockchip_combphy_ids,
1061925c5749SYifeng Zhao 	.ops		= &rochchip_combphy_ops,
1062925c5749SYifeng Zhao 	.probe		= rockchip_combphy_probe,
1063925c5749SYifeng Zhao 	.priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv),
1064925c5749SYifeng Zhao };
1065