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