• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Wyon Bi <bivvy.bi@rock-chips.com>
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/clk.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/delay.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/reset.h>
18 #include <linux/phy/phy.h>
19 
20 #define HIWORD_UPDATE(x, h, l)		((((x) << (l)) & GENMASK((h), (l))) | \
21 					 (GENMASK((h), (l)) << 16))
22 
23 #define EDP_PHY_GRF_CON0		0x0000
24 #define EDP_PHY_TX_IDLE(x)		HIWORD_UPDATE(x, 11,  8)
25 #define EDP_PHY_TX_PD(x)		HIWORD_UPDATE(x,  7,  4)
26 #define EDP_PHY_IDDQ_EN(x)		HIWORD_UPDATE(x,  1,  1)
27 #define EDP_PHY_PD_PLL(x)		HIWORD_UPDATE(x,  0,  0)
28 #define EDP_PHY_GRF_CON1		0x0004
29 #define EDP_PHY_PLL_DIV(x)		HIWORD_UPDATE(x, 14,  0)
30 #define EDP_PHY_GRF_CON2		0x0008
31 #define EDP_PHY_TX_RTERM(x)		HIWORD_UPDATE(x, 10,  8)
32 #define EDP_PHY_RATE(x)			HIWORD_UPDATE(x,  5,  4)
33 #define EDP_PHY_REF_DIV(x)		HIWORD_UPDATE(x,  3,  0)
34 #define EDP_PHY_GRF_CON3		0x000c
35 #define EDP_PHY_TX_EMP(lane, x)		HIWORD_UPDATE(x, 4 * ((lane) + 1) - 1, \
36 						      4 * (lane))
37 #define EDP_PHY_GRF_CON4		0x0010
38 #define EDP_PHY_TX_AMP(lane, x)		HIWORD_UPDATE(x, 4 * ((lane) + 1) - 2, \
39 						      4 * (lane))
40 #define EDP_PHY_GRF_CON5		0x0014
41 #define EDP_PHY_TX_MODE(x)		HIWORD_UPDATE(x,  9,  8)
42 #define EDP_PHY_TX_AMP_SCALE(lane, x)	HIWORD_UPDATE(x, 2 * ((lane) + 1) - 1, \
43 						      2 * (lane))
44 #define EDP_PHY_GRF_CON6		0x0018
45 #define EDP_PHY_SSC_DEPTH(x)		HIWORD_UPDATE(x, 15, 12)
46 #define EDP_PHY_SSC_EN(x)		HIWORD_UPDATE(x, 11, 11)
47 #define EDP_PHY_SSC_CNT(x)		HIWORD_UPDATE(x,  9,  0)
48 #define EDP_PHY_GRF_CON7		0x001c
49 #define EDP_PHY_GRF_CON8		0x0020
50 #define EDP_PHY_PLL_CTL_H(x)		HIWORD_UPDATE(x, 15,  0)
51 #define EDP_PHY_GRF_CON9		0x0024
52 #define EDP_PHY_TX_CTL(x)		HIWORD_UPDATE(x, 15,  0)
53 #define EDP_PHY_GRF_CON10		0x0028
54 #define EDP_PHY_AUX_RCV_PD_SEL(x)	HIWORD_UPDATE(x,  5,  5)
55 #define EDP_PHY_AUX_DRV_PD_SEL(x)	HIWORD_UPDATE(x,  4,  4)
56 #define EDP_PHY_AUX_IDLE_MASK		BIT(2)
57 #define EDP_PHY_AUX_IDLE(x)		HIWORD_UPDATE(x,  2,  2)
58 #define EDP_PHY_AUX_RCV_PD(x)		HIWORD_UPDATE(x,  1,  1)
59 #define EDP_PHY_AUX_DRV_PD(x)		HIWORD_UPDATE(x,  0,  0)
60 #define EDP_PHY_GRF_CON11		0x002c
61 #define EDP_PHY_AUX_RCV_VCM(x)		HIWORD_UPDATE(x, 14, 12)
62 #define EDP_PHY_AUX_MODE(x)		HIWORD_UPDATE(x, 11, 10)
63 #define EDP_PHY_AUX_AMP_SCALE(x)	HIWORD_UPDATE(x,  9,  8)
64 #define EDP_PHY_AUX_AMP(x)		HIWORD_UPDATE(x,  6,  4)
65 #define EDP_PHY_AUX_RTERM(x)		HIWORD_UPDATE(x,  2,  0)
66 #define EDP_PHY_GRF_STATUS0		0x0030
67 #define PLL_RDY				BIT(0)
68 #define EDP_PHY_GRF_STATUS1		0x0034
69 
70 struct rockchip_edp_phy {
71 	void __iomem *regs;
72 	struct device *dev;
73 	struct clk *pclk;
74 	struct clk *refclk;
75 	struct reset_control *apb_reset;
76 };
77 
78 static struct {
79 	int amp;
80 	int amp_scale;
81 	int emp;
82 } vp[4][4] = {
83 	{ {0x1, 0x1, 0x0}, {0x2, 0x1, 0x4}, {0x3, 0x1, 0x8}, {0x4, 0x1, 0xd} },
84 	{ {0x3, 0x1, 0x0}, {0x5, 0x1, 0x7}, {0x6, 0x1, 0x6}, { -1,  -1,  -1} },
85 	{ {0x5, 0x1, 0x0}, {0x7, 0x1, 0x4}, { -1,  -1,  -1}, { -1,  -1,  -1} },
86 	{ {0x7, 0x1, 0x0}, { -1,  -1,  -1}, { -1,  -1,  -1}, { -1,  -1,  -1} },
87 };
88 
rockchip_edp_phy_set_voltages(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)89 static int rockchip_edp_phy_set_voltages(struct rockchip_edp_phy *edpphy,
90 					 struct phy_configure_opts_dp *dp)
91 {
92 	u8 lane;
93 	u32 val;
94 
95 	for (lane = 0; lane < dp->lanes; lane++) {
96 		val = vp[dp->voltage[lane]][dp->pre[lane]].amp;
97 		writel(EDP_PHY_TX_AMP(lane, val),
98 		       edpphy->regs + EDP_PHY_GRF_CON4);
99 
100 		val = vp[dp->voltage[lane]][dp->pre[lane]].amp_scale;
101 		writel(EDP_PHY_TX_AMP_SCALE(lane, val),
102 		       edpphy->regs + EDP_PHY_GRF_CON5);
103 
104 		val = vp[dp->voltage[lane]][dp->pre[lane]].emp;
105 		writel(EDP_PHY_TX_EMP(lane, val),
106 		       edpphy->regs + EDP_PHY_GRF_CON3);
107 	}
108 
109 	return 0;
110 }
111 
rockchip_edp_phy_set_rate(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)112 static int rockchip_edp_phy_set_rate(struct rockchip_edp_phy *edpphy,
113 				     struct phy_configure_opts_dp *dp)
114 {
115 	u32 value;
116 	int ret;
117 
118 	writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf),
119 	       edpphy->regs + EDP_PHY_GRF_CON0);
120 	usleep_range(100, 101);
121 	writel(EDP_PHY_TX_MODE(0x3), edpphy->regs + EDP_PHY_GRF_CON5);
122 	writel(EDP_PHY_PD_PLL(0x1), edpphy->regs + EDP_PHY_GRF_CON0);
123 
124 	switch (dp->link_rate) {
125 	case 1620:
126 		writel(EDP_PHY_PLL_DIV(0x4380),
127 		       edpphy->regs + EDP_PHY_GRF_CON1);
128 		writel(EDP_PHY_TX_RTERM(0x1) | EDP_PHY_RATE(0x1) |
129 		       EDP_PHY_REF_DIV(0x0), edpphy->regs + EDP_PHY_GRF_CON2);
130 		writel(EDP_PHY_PLL_CTL_H(0x0800),
131 		       edpphy->regs + EDP_PHY_GRF_CON8);
132 		writel(EDP_PHY_TX_CTL(0x0000), edpphy->regs + EDP_PHY_GRF_CON9);
133 		break;
134 	case 2700:
135 		writel(EDP_PHY_PLL_DIV(0x3840),
136 		       edpphy->regs + EDP_PHY_GRF_CON1);
137 		writel(EDP_PHY_TX_RTERM(0x1) | EDP_PHY_RATE(0x0) |
138 		       EDP_PHY_REF_DIV(0x0), edpphy->regs + EDP_PHY_GRF_CON2);
139 		writel(EDP_PHY_PLL_CTL_H(0x0800),
140 		       edpphy->regs + EDP_PHY_GRF_CON8);
141 		writel(EDP_PHY_TX_CTL(0x0000), edpphy->regs + EDP_PHY_GRF_CON9);
142 		break;
143 	}
144 
145 	if (dp->ssc)
146 		writel(EDP_PHY_SSC_DEPTH(0x9) | EDP_PHY_SSC_EN(0x1) |
147 		       EDP_PHY_SSC_CNT(0x17d),
148 		       edpphy->regs + EDP_PHY_GRF_CON6);
149 	else
150 		writel(EDP_PHY_SSC_EN(0x0), edpphy->regs + EDP_PHY_GRF_CON6);
151 
152 	writel(EDP_PHY_PD_PLL(0x0), edpphy->regs + EDP_PHY_GRF_CON0);
153 	writel(EDP_PHY_TX_PD(~GENMASK(dp->lanes - 1, 0)),
154 	       edpphy->regs + EDP_PHY_GRF_CON0);
155 	ret = readl_poll_timeout(edpphy->regs + EDP_PHY_GRF_STATUS0,
156 				 value, value & PLL_RDY, 100, 1000);
157 	if (ret) {
158 		dev_err(edpphy->dev, "pll is not ready: %d\n", ret);
159 		return ret;
160 	}
161 
162 	writel(EDP_PHY_TX_MODE(0x0), edpphy->regs + EDP_PHY_GRF_CON5);
163 	writel(EDP_PHY_TX_IDLE(~GENMASK(dp->lanes - 1, 0)),
164 	       edpphy->regs + EDP_PHY_GRF_CON0);
165 
166 	return 0;
167 }
168 
rockchip_edp_phy_verify_config(struct rockchip_edp_phy * edpphy,struct phy_configure_opts_dp * dp)169 static int rockchip_edp_phy_verify_config(struct rockchip_edp_phy *edpphy,
170 					  struct phy_configure_opts_dp *dp)
171 {
172 	int i;
173 
174 	/* If changing link rate was required, verify it's supported. */
175 	if (dp->set_rate) {
176 		switch (dp->link_rate) {
177 		case 1620:
178 		case 2700:
179 			/* valid bit rate */
180 			break;
181 		default:
182 			return -EINVAL;
183 		}
184 	}
185 
186 	/* Verify lane count. */
187 	switch (dp->lanes) {
188 	case 1:
189 	case 2:
190 	case 4:
191 		/* valid lane count. */
192 		break;
193 	default:
194 		return -EINVAL;
195 	}
196 
197 	/*
198 	 * If changing voltages is required, check swing and pre-emphasis
199 	 * levels, per-lane.
200 	 */
201 	if (dp->set_voltages) {
202 		/* Lane count verified previously. */
203 		for (i = 0; i < dp->lanes; i++) {
204 			if (dp->voltage[i] > 3 || dp->pre[i] > 3)
205 				return -EINVAL;
206 
207 			/*
208 			 * Sum of voltage swing and pre-emphasis levels cannot
209 			 * exceed 3.
210 			 */
211 			if (dp->voltage[i] + dp->pre[i] > 3)
212 				return -EINVAL;
213 		}
214 	}
215 
216 	return 0;
217 }
218 
rockchip_edp_phy_configure(struct phy * phy,union phy_configure_opts * opts)219 static int rockchip_edp_phy_configure(struct phy *phy,
220 				      union phy_configure_opts *opts)
221 {
222 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
223 	int ret;
224 
225 	ret = rockchip_edp_phy_verify_config(edpphy, &opts->dp);
226 	if (ret) {
227 		dev_err(edpphy->dev, "invalid params for phy configure\n");
228 		return ret;
229 	}
230 
231 	if (opts->dp.set_rate) {
232 		ret = rockchip_edp_phy_set_rate(edpphy, &opts->dp);
233 		if (ret) {
234 			dev_err(edpphy->dev,
235 				"rockchip_edp_phy_set_rate failed\n");
236 			return ret;
237 		}
238 	}
239 
240 	if (opts->dp.set_voltages) {
241 		ret = rockchip_edp_phy_set_voltages(edpphy, &opts->dp);
242 		if (ret) {
243 			dev_err(edpphy->dev,
244 				"rockchip_edp_phy_set_voltages failed\n");
245 			return ret;
246 		}
247 	}
248 
249 	return 0;
250 }
251 
rockchip_edp_phy_enabled(struct rockchip_edp_phy * edpphy)252 static bool rockchip_edp_phy_enabled(struct rockchip_edp_phy *edpphy)
253 {
254 	u32 val;
255 
256 	val = readl(edpphy->regs + EDP_PHY_GRF_CON10);
257 
258 	if (val & EDP_PHY_AUX_IDLE_MASK)
259 		return false;
260 
261 	return true;
262 }
263 
rockchip_edp_phy_power_on(struct phy * phy)264 static int rockchip_edp_phy_power_on(struct phy *phy)
265 {
266 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
267 
268 	clk_prepare_enable(edpphy->pclk);
269 	clk_prepare_enable(edpphy->refclk);
270 
271 	if (rockchip_edp_phy_enabled(edpphy))
272 		return 0;
273 
274 	reset_control_assert(edpphy->apb_reset);
275 	usleep_range(100, 101);
276 	reset_control_deassert(edpphy->apb_reset);
277 	usleep_range(100, 101);
278 
279 	writel(EDP_PHY_AUX_RCV_PD(0x1) | EDP_PHY_AUX_DRV_PD(0x1) |
280 	       EDP_PHY_AUX_IDLE(0x1), edpphy->regs + EDP_PHY_GRF_CON10);
281 	writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf) | EDP_PHY_PD_PLL(0x1),
282 	       edpphy->regs + EDP_PHY_GRF_CON0);
283 	usleep_range(100, 101);
284 
285 	writel(EDP_PHY_AUX_RCV_VCM(0x4) | EDP_PHY_AUX_MODE(0x1) |
286 	       EDP_PHY_AUX_AMP_SCALE(0x1) | EDP_PHY_AUX_AMP(0x3) |
287 	       EDP_PHY_AUX_RTERM(0x1), edpphy->regs + EDP_PHY_GRF_CON11);
288 
289 	writel(EDP_PHY_AUX_RCV_PD(0x0) | EDP_PHY_AUX_DRV_PD(0x0),
290 	       edpphy->regs + EDP_PHY_GRF_CON10);
291 	usleep_range(100, 101);
292 
293 	writel(EDP_PHY_AUX_IDLE(0x0), edpphy->regs + EDP_PHY_GRF_CON10);
294 	usleep_range(10000, 11000);
295 
296 	return 0;
297 }
298 
rockchip_edp_phy_power_off(struct phy * phy)299 static int rockchip_edp_phy_power_off(struct phy *phy)
300 {
301 	struct rockchip_edp_phy *edpphy = phy_get_drvdata(phy);
302 
303 	writel(EDP_PHY_TX_IDLE(0xf) | EDP_PHY_TX_PD(0xf),
304 	       edpphy->regs + EDP_PHY_GRF_CON0);
305 	usleep_range(100, 101);
306 	writel(EDP_PHY_TX_MODE(0x3), edpphy->regs + EDP_PHY_GRF_CON5);
307 	writel(EDP_PHY_PD_PLL(0x1), edpphy->regs + EDP_PHY_GRF_CON0);
308 	writel(EDP_PHY_AUX_RCV_PD(0x1) | EDP_PHY_AUX_DRV_PD(0x1) |
309 	       EDP_PHY_AUX_IDLE(0x1), edpphy->regs + EDP_PHY_GRF_CON10);
310 
311 	clk_disable_unprepare(edpphy->refclk);
312 	clk_disable_unprepare(edpphy->pclk);
313 
314 	return 0;
315 }
316 
317 static const struct phy_ops rockchip_edp_phy_ops = {
318 	.power_on = rockchip_edp_phy_power_on,
319 	.power_off = rockchip_edp_phy_power_off,
320 	.configure = rockchip_edp_phy_configure,
321 	.owner = THIS_MODULE,
322 };
323 
rockchip_edp_phy_probe(struct platform_device * pdev)324 static int rockchip_edp_phy_probe(struct platform_device *pdev)
325 {
326 	struct device *dev = &pdev->dev;
327 	struct rockchip_edp_phy *edpphy;
328 	struct phy *phy;
329 	struct phy_provider *phy_provider;
330 	struct resource *res;
331 	int ret;
332 
333 	edpphy = devm_kzalloc(dev, sizeof(*edpphy), GFP_KERNEL);
334 	if (!edpphy)
335 		return -ENOMEM;
336 
337 	edpphy->dev = dev;
338 
339 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
340 	edpphy->regs = devm_ioremap_resource(dev, res);
341 	if (IS_ERR(edpphy->regs))
342 		return PTR_ERR(edpphy->regs);
343 
344 	edpphy->refclk = devm_clk_get(dev, "refclk");
345 	if (IS_ERR(edpphy->refclk)) {
346 		ret = PTR_ERR(edpphy->refclk);
347 		dev_err(dev, "failed to get refclk: %d\n", ret);
348 		return ret;
349 	}
350 
351 	edpphy->pclk = devm_clk_get(dev, "pclk");
352 	if (IS_ERR(edpphy->pclk)) {
353 		ret = PTR_ERR(edpphy->pclk);
354 		dev_err(dev, "failed to get pclk: %d\n", ret);
355 		return ret;
356 	}
357 
358 	edpphy->apb_reset = devm_reset_control_get(dev, "apb");
359 	if (IS_ERR(edpphy->apb_reset)) {
360 		ret = PTR_ERR(edpphy->apb_reset);
361 		dev_err(dev, "failed to get apb reset: %d\n", ret);
362 		return ret;
363 	}
364 
365 	phy = devm_phy_create(dev, NULL, &rockchip_edp_phy_ops);
366 	if (IS_ERR(phy)) {
367 		ret = PTR_ERR(phy);
368 		dev_err(dev, "failed to create PHY: %d\n", ret);
369 		return ret;
370 	}
371 
372 	phy_set_drvdata(phy, edpphy);
373 
374 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
375 	if (IS_ERR(phy_provider)) {
376 		dev_err(dev, "failed to register phy provider\n");
377 		return PTR_ERR(phy_provider);
378 	}
379 
380 	return 0;
381 }
382 
383 static const struct of_device_id rockchip_edp_phy_of_match[] = {
384 	{ .compatible = "rockchip,rk3568-edp-phy", },
385 	{}
386 };
387 MODULE_DEVICE_TABLE(of, rockchip_edp_phy_of_match);
388 
389 static struct platform_driver rockchip_edp_phy_driver = {
390 	.driver = {
391 		.name = "rockchip-edpphy-naneng",
392 		.of_match_table	= of_match_ptr(rockchip_edp_phy_of_match),
393 	},
394 	.probe = rockchip_edp_phy_probe,
395 };
396 module_platform_driver(rockchip_edp_phy_driver);
397 
398 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
399 MODULE_DESCRIPTION("Rockchip Naneng eDP Transmitter PHY driver");
400 MODULE_LICENSE("GPL v2");
401