1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Rockchip SoC DP (Display Port) interface driver.
4 *
5 * Copyright (C) Rockchip Electronics Co., Ltd.
6 * Author: Andy Yan <andy.yan@rock-chips.com>
7 * Yakir Yang <ykk@rock-chips.com>
8 * Jeff Chen <jeff.chen@rock-chips.com>
9 */
10
11#include <linux/component.h>
12#include <linux/mfd/syscon.h>
13#include <linux/of.h>
14#include <linux/of_graph.h>
15#include <linux/platform_device.h>
16#include <linux/pm_runtime.h>
17#include <linux/regmap.h>
18#include <linux/reset.h>
19#include <linux/clk.h>
20
21#include <video/of_videomode.h>
22#include <video/videomode.h>
23
24#include <drm/display/drm_dp_aux_bus.h>
25#include <drm/display/drm_dp_helper.h>
26#include <drm/drm_atomic.h>
27#include <drm/drm_atomic_helper.h>
28#include <drm/bridge/analogix_dp.h>
29#include <drm/drm_of.h>
30#include <drm/drm_panel.h>
31#include <drm/drm_probe_helper.h>
32#include <drm/drm_simple_kms_helper.h>
33
34#include "rockchip_drm_drv.h"
35
36#define PSR_WAIT_LINE_FLAG_TIMEOUT_MS 100
37
38#define GRF_REG_FIELD(_reg, _lsb, _msb) { \
39 .reg = _reg, \
40 .lsb = _lsb, \
41 .msb = _msb, \
42 .valid = true, \
43 }
44
45struct rockchip_grf_reg_field {
46 u32 reg;
47 u32 lsb;
48 u32 msb;
49 bool valid;
50};
51
52/**
53 * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
54 * @lcdc_sel: grf register field of lcdc_sel
55 * @edp_mode: grf register field of edp_mode
56 * @chip_type: specific chip type
57 * @reg: register base address
58 */
59struct rockchip_dp_chip_data {
60 const struct rockchip_grf_reg_field lcdc_sel;
61 const struct rockchip_grf_reg_field edp_mode;
62 u32 chip_type;
63 u32 reg;
64};
65
66struct rockchip_dp_device {
67 struct drm_device *drm_dev;
68 struct device *dev;
69 struct rockchip_encoder encoder;
70 struct drm_display_mode mode;
71
72 struct clk *pclk;
73 struct clk *grfclk;
74 struct regmap *grf;
75 struct reset_control *rst;
76 struct reset_control *apbrst;
77
78 const struct rockchip_dp_chip_data *data;
79
80 struct analogix_dp_device *adp;
81 struct analogix_dp_plat_data plat_data;
82};
83
84static struct rockchip_dp_device *encoder_to_dp(struct drm_encoder *encoder)
85{
86 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
87
88 return container_of(rkencoder, struct rockchip_dp_device, encoder);
89}
90
91static struct rockchip_dp_device *pdata_encoder_to_dp(struct analogix_dp_plat_data *plat_data)
92{
93 return container_of(plat_data, struct rockchip_dp_device, plat_data);
94}
95
96static int rockchip_grf_write(struct regmap *grf, u32 reg, u32 mask, u32 val)
97{
98 return regmap_write(map: grf, reg, val: (mask << 16) | (val & mask));
99}
100
101static int rockchip_grf_field_write(struct regmap *grf,
102 const struct rockchip_grf_reg_field *field,
103 u32 val)
104{
105 u32 mask;
106
107 if (!field->valid)
108 return 0;
109
110 mask = GENMASK(field->msb, field->lsb);
111 val <<= field->lsb;
112
113 return rockchip_grf_write(grf, reg: field->reg, mask, val);
114}
115
116static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
117{
118 reset_control_assert(rstc: dp->rst);
119 usleep_range(min: 10, max: 20);
120 reset_control_deassert(rstc: dp->rst);
121
122 reset_control_assert(rstc: dp->apbrst);
123 usleep_range(min: 10, max: 20);
124 reset_control_deassert(rstc: dp->apbrst);
125
126 return 0;
127}
128
129static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
130{
131 struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
132 int ret;
133
134 ret = clk_prepare_enable(clk: dp->pclk);
135 if (ret < 0) {
136 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
137 return ret;
138 }
139
140 ret = rockchip_dp_pre_init(dp);
141 if (ret < 0) {
142 DRM_DEV_ERROR(dp->dev, "failed to dp pre init %d\n", ret);
143 clk_disable_unprepare(clk: dp->pclk);
144 return ret;
145 }
146
147 ret = rockchip_grf_field_write(grf: dp->grf, field: &dp->data->edp_mode, val: 1);
148 if (ret != 0)
149 DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
150
151 return ret;
152}
153
154static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
155{
156 struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
157 int ret;
158
159 ret = rockchip_grf_field_write(grf: dp->grf, field: &dp->data->edp_mode, val: 0);
160 if (ret != 0)
161 DRM_DEV_ERROR(dp->dev, "failed to set edp mode %d\n", ret);
162
163 clk_disable_unprepare(clk: dp->pclk);
164
165 return 0;
166}
167
168static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
169 struct drm_connector *connector)
170{
171 struct drm_display_info *di = &connector->display_info;
172 /* VOP couldn't output YUV video format for eDP rightly */
173 u32 mask = DRM_COLOR_FORMAT_YCBCR444 | DRM_COLOR_FORMAT_YCBCR422;
174
175 if ((di->color_formats & mask)) {
176 DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
177 di->color_formats &= ~mask;
178 di->color_formats |= DRM_COLOR_FORMAT_RGB444;
179 di->bpc = 8;
180 }
181
182 return 0;
183}
184
185static bool
186rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
187 const struct drm_display_mode *mode,
188 struct drm_display_mode *adjusted_mode)
189{
190 /* do nothing */
191 return true;
192}
193
194static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
195 struct drm_display_mode *mode,
196 struct drm_display_mode *adjusted)
197{
198 /* do nothing */
199}
200
201static
202struct drm_crtc *rockchip_dp_drm_get_new_crtc(struct drm_encoder *encoder,
203 struct drm_atomic_state *state)
204{
205 struct drm_connector *connector;
206 struct drm_connector_state *conn_state;
207
208 connector = drm_atomic_get_new_connector_for_encoder(state, encoder);
209 if (!connector)
210 return NULL;
211
212 conn_state = drm_atomic_get_new_connector_state(state, connector);
213 if (!conn_state)
214 return NULL;
215
216 return conn_state->crtc;
217}
218
219static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
220 struct drm_atomic_state *state)
221{
222 struct rockchip_dp_device *dp = encoder_to_dp(encoder);
223 struct drm_crtc *crtc;
224 struct drm_crtc_state *old_crtc_state;
225 struct of_endpoint endpoint;
226 struct device_node *remote_port, *remote_port_parent;
227 char name[32];
228 u32 port_id;
229 int ret;
230
231 crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
232 if (!crtc)
233 return;
234
235 old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
236 /* Coming back from self refresh, nothing to do */
237 if (old_crtc_state && old_crtc_state->self_refresh_active)
238 return;
239
240 ret = clk_prepare_enable(clk: dp->grfclk);
241 if (ret < 0) {
242 DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
243 return;
244 }
245
246 ret = drm_of_encoder_active_endpoint(node: dp->dev->of_node, encoder, endpoint: &endpoint);
247 if (ret < 0)
248 return;
249
250 remote_port_parent = of_graph_get_remote_port_parent(node: endpoint.local_node);
251 if (remote_port_parent) {
252 if (of_get_child_by_name(node: remote_port_parent, name: "ports")) {
253 remote_port = of_graph_get_remote_port(node: endpoint.local_node);
254 of_property_read_u32(np: remote_port, propname: "reg", out_value: &port_id);
255 of_node_put(node: remote_port);
256 sprintf(buf: name, fmt: "%s vp%d", remote_port_parent->full_name, port_id);
257 } else {
258 sprintf(buf: name, fmt: "%s %s",
259 remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
260 }
261 of_node_put(node: remote_port_parent);
262
263 DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
264 }
265
266 ret = rockchip_grf_field_write(grf: dp->grf, field: &dp->data->lcdc_sel, val: endpoint.id);
267 if (ret != 0)
268 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
269
270 clk_disable_unprepare(clk: dp->grfclk);
271}
272
273static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder,
274 struct drm_atomic_state *state)
275{
276 struct rockchip_dp_device *dp = encoder_to_dp(encoder);
277 struct drm_crtc *crtc;
278 struct drm_crtc_state *new_crtc_state = NULL;
279 int ret;
280
281 crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
282 /* No crtc means we're doing a full shutdown */
283 if (!crtc)
284 return;
285
286 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
287 /* If we're not entering self-refresh, no need to wait for vact */
288 if (!new_crtc_state || !new_crtc_state->self_refresh_active)
289 return;
290
291 ret = rockchip_drm_wait_vact_end(crtc, PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
292 if (ret)
293 DRM_DEV_ERROR(dp->dev, "line flag irq timed out\n");
294}
295
296static int
297rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
298 struct drm_crtc_state *crtc_state,
299 struct drm_connector_state *conn_state)
300{
301 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
302 struct drm_display_info *di = &conn_state->connector->display_info;
303
304 /*
305 * The hardware IC designed that VOP must output the RGB10 video
306 * format to eDP controller, and if eDP panel only support RGB8,
307 * then eDP controller should cut down the video data, not via VOP
308 * controller, that's why we need to hardcode the VOP output mode
309 * to RGA10 here.
310 */
311
312 s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
313 s->output_type = DRM_MODE_CONNECTOR_eDP;
314 s->output_bpc = di->bpc;
315
316 return 0;
317}
318
319static const struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
320 .mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
321 .mode_set = rockchip_dp_drm_encoder_mode_set,
322 .atomic_enable = rockchip_dp_drm_encoder_enable,
323 .atomic_disable = rockchip_dp_drm_encoder_disable,
324 .atomic_check = rockchip_dp_drm_encoder_atomic_check,
325};
326
327static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
328{
329 struct device *dev = dp->dev;
330 struct device_node *np = dev->of_node;
331
332 dp->grf = syscon_regmap_lookup_by_phandle(np, property: "rockchip,grf");
333 if (IS_ERR(ptr: dp->grf)) {
334 DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n");
335 return PTR_ERR(ptr: dp->grf);
336 }
337
338 dp->grfclk = devm_clk_get(dev, id: "grf");
339 if (PTR_ERR(ptr: dp->grfclk) == -ENOENT) {
340 dp->grfclk = NULL;
341 } else if (PTR_ERR(ptr: dp->grfclk) == -EPROBE_DEFER) {
342 return -EPROBE_DEFER;
343 } else if (IS_ERR(ptr: dp->grfclk)) {
344 DRM_DEV_ERROR(dev, "failed to get grf clock\n");
345 return PTR_ERR(ptr: dp->grfclk);
346 }
347
348 dp->pclk = devm_clk_get(dev, id: "pclk");
349 if (IS_ERR(ptr: dp->pclk)) {
350 DRM_DEV_ERROR(dev, "failed to get pclk property\n");
351 return PTR_ERR(ptr: dp->pclk);
352 }
353
354 dp->rst = devm_reset_control_get(dev, id: "dp");
355 if (IS_ERR(ptr: dp->rst)) {
356 DRM_DEV_ERROR(dev, "failed to get dp reset control\n");
357 return PTR_ERR(ptr: dp->rst);
358 }
359
360 dp->apbrst = devm_reset_control_get_optional(dev, id: "apb");
361 if (IS_ERR(ptr: dp->apbrst)) {
362 DRM_DEV_ERROR(dev, "failed to get apb reset control\n");
363 return PTR_ERR(ptr: dp->apbrst);
364 }
365
366 return 0;
367}
368
369static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
370{
371 struct drm_encoder *encoder = &dp->encoder.encoder;
372 struct drm_device *drm_dev = dp->drm_dev;
373 struct device *dev = dp->dev;
374 int ret;
375
376 encoder->possible_crtcs = drm_of_find_possible_crtcs(dev: drm_dev,
377 port: dev->of_node);
378 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
379
380 ret = drm_simple_encoder_init(dev: drm_dev, encoder,
381 DRM_MODE_ENCODER_TMDS);
382 if (ret) {
383 DRM_ERROR("failed to initialize encoder with drm\n");
384 return ret;
385 }
386
387 drm_encoder_helper_add(encoder, funcs: &rockchip_dp_encoder_helper_funcs);
388
389 return 0;
390}
391
392static int rockchip_dp_bind(struct device *dev, struct device *master,
393 void *data)
394{
395 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
396 struct drm_device *drm_dev = data;
397 int ret;
398
399 dp->drm_dev = drm_dev;
400
401 ret = rockchip_dp_drm_create_encoder(dp);
402 if (ret) {
403 DRM_ERROR("failed to create drm encoder\n");
404 return ret;
405 }
406
407 rockchip_drm_encoder_set_crtc_endpoint_id(rencoder: &dp->encoder,
408 np: dev->of_node, port: 0, reg: 0);
409
410 dp->plat_data.encoder = &dp->encoder.encoder;
411
412 ret = analogix_dp_bind(dp: dp->adp, drm_dev);
413 if (ret)
414 goto err_cleanup_encoder;
415
416 return 0;
417err_cleanup_encoder:
418 dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder);
419 return ret;
420}
421
422static void rockchip_dp_unbind(struct device *dev, struct device *master,
423 void *data)
424{
425 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
426
427 analogix_dp_unbind(dp: dp->adp);
428 dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder);
429}
430
431static const struct component_ops rockchip_dp_component_ops = {
432 .bind = rockchip_dp_bind,
433 .unbind = rockchip_dp_unbind,
434};
435
436static int rockchip_dp_link_panel(struct drm_dp_aux *aux)
437{
438 struct analogix_dp_plat_data *plat_data = analogix_dp_aux_to_plat_data(aux);
439 struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
440 int ret;
441
442 /*
443 * If drm_of_find_panel_or_bridge() returns -ENODEV, there may be no valid panel
444 * or bridge nodes. The driver should go on for the driver-free bridge or the DP
445 * mode applications.
446 */
447 ret = drm_of_find_panel_or_bridge(np: dp->dev->of_node, port: 1, endpoint: 0, panel: &plat_data->panel, NULL);
448 if (ret && ret != -ENODEV)
449 return ret;
450
451 return component_add(dp->dev, &rockchip_dp_component_ops);
452}
453
454static int rockchip_dp_probe(struct platform_device *pdev)
455{
456 struct device *dev = &pdev->dev;
457 const struct rockchip_dp_chip_data *dp_data;
458 struct rockchip_dp_device *dp;
459 struct resource *res;
460 int i;
461 int ret;
462
463 dp_data = of_device_get_match_data(dev);
464 if (!dp_data)
465 return -ENODEV;
466
467 dp = devm_kzalloc(dev, size: sizeof(*dp), GFP_KERNEL);
468 if (!dp)
469 return -ENOMEM;
470
471 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
472
473 i = 0;
474 while (dp_data[i].reg) {
475 if (dp_data[i].reg == res->start) {
476 dp->data = &dp_data[i];
477 break;
478 }
479
480 i++;
481 }
482
483 if (!dp->data)
484 return dev_err_probe(dev, err: -EINVAL, fmt: "no chip-data for %s node\n",
485 dev->of_node->name);
486
487 dp->dev = dev;
488 dp->adp = ERR_PTR(error: -ENODEV);
489 dp->plat_data.dev_type = dp->data->chip_type;
490 dp->plat_data.power_on = rockchip_dp_poweron;
491 dp->plat_data.power_off = rockchip_dp_powerdown;
492 dp->plat_data.get_modes = rockchip_dp_get_modes;
493
494 ret = rockchip_dp_of_probe(dp);
495 if (ret < 0)
496 return ret;
497
498 platform_set_drvdata(pdev, data: dp);
499
500 dp->adp = analogix_dp_probe(dev, plat_data: &dp->plat_data);
501 if (IS_ERR(ptr: dp->adp))
502 return PTR_ERR(ptr: dp->adp);
503
504 ret = devm_of_dp_aux_populate_bus(aux: analogix_dp_get_aux(dp: dp->adp), done_probing: rockchip_dp_link_panel);
505 if (ret) {
506 /*
507 * If devm_of_dp_aux_populate_bus() returns -ENODEV, the done_probing() will not
508 * be called because there are no EP devices. Then the rockchip_dp_link_panel()
509 * will be called directly in order to support the other valid DT configurations.
510 *
511 * NOTE: The devm_of_dp_aux_populate_bus() is allowed to return -EPROBE_DEFER.
512 */
513 if (ret != -ENODEV)
514 return dev_err_probe(dev: dp->dev, err: ret, fmt: "failed to populate aux bus\n");
515
516 return rockchip_dp_link_panel(aux: analogix_dp_get_aux(dp: dp->adp));
517 }
518
519 return 0;
520}
521
522static void rockchip_dp_remove(struct platform_device *pdev)
523{
524 component_del(&pdev->dev, &rockchip_dp_component_ops);
525}
526
527static int rockchip_dp_suspend(struct device *dev)
528{
529 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
530
531 if (IS_ERR(ptr: dp->adp))
532 return 0;
533
534 return analogix_dp_suspend(dp: dp->adp);
535}
536
537static int rockchip_dp_resume(struct device *dev)
538{
539 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
540
541 if (IS_ERR(ptr: dp->adp))
542 return 0;
543
544 return analogix_dp_resume(dp: dp->adp);
545}
546
547static DEFINE_RUNTIME_DEV_PM_OPS(rockchip_dp_pm_ops, rockchip_dp_suspend,
548 rockchip_dp_resume, NULL);
549
550static const struct rockchip_dp_chip_data rk3399_edp[] = {
551 {
552 .lcdc_sel = GRF_REG_FIELD(0x6250, 5, 5),
553 .chip_type = RK3399_EDP,
554 .reg = 0xff970000,
555 },
556 { /* sentinel */ }
557};
558
559static const struct rockchip_dp_chip_data rk3288_dp[] = {
560 {
561 .lcdc_sel = GRF_REG_FIELD(0x025c, 5, 5),
562 .chip_type = RK3288_DP,
563 .reg = 0xff970000,
564 },
565 { /* sentinel */ }
566};
567
568static const struct rockchip_dp_chip_data rk3588_edp[] = {
569 {
570 .edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
571 .chip_type = RK3588_EDP,
572 .reg = 0xfdec0000,
573 },
574 {
575 .edp_mode = GRF_REG_FIELD(0x0004, 0, 0),
576 .chip_type = RK3588_EDP,
577 .reg = 0xfded0000,
578 },
579 { /* sentinel */ }
580};
581
582static const struct of_device_id rockchip_dp_dt_ids[] = {
583 {.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
584 {.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
585 {.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
586 {}
587};
588MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
589
590struct platform_driver rockchip_dp_driver = {
591 .probe = rockchip_dp_probe,
592 .remove = rockchip_dp_remove,
593 .driver = {
594 .name = "rockchip-dp",
595 .pm = pm_ptr(&rockchip_dp_pm_ops),
596 .of_match_table = rockchip_dp_dt_ids,
597 },
598};
599

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c