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