1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Author:
5 * Sandy Huang <hjc@rock-chips.com>
6 */
7
8 #include <linux/component.h>
9 #include <linux/of_device.h>
10 #include <linux/of_graph.h>
11 #include <linux/regmap.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/phy/phy.h>
14 #include <linux/pinctrl/consumer.h>
15 #include <linux/gpio/consumer.h>
16
17 #include <video/of_display_timing.h>
18
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_crtc_helper.h>
21 #include <drm/drm_dp_helper.h>
22 #include <drm/drm_of.h>
23 #include <drm/drm_panel.h>
24 #include <drm/drm_probe_helper.h>
25
26 #include <uapi/linux/videodev2.h>
27
28 #include "rockchip_drm_drv.h"
29 #include "rockchip_drm_vop.h"
30
31 #define HIWORD_UPDATE(v, l, h) (((v) << (l)) | (GENMASK(h, l) << 16))
32
33 #define PX30_GRF_PD_VO_CON1 0x0438
34 #define PX30_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3)
35 #define PX30_RGB_VOP_SEL(v) HIWORD_UPDATE(v, 2, 2)
36
37 #define RK1808_GRF_PD_VO_CON1 0x0444
38 #define RK1808_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3)
39
40 #define RV1106_VENC_GRF_VOP_IO_WRAPPER 0x1000c
41 #define RV1106_IO_BYPASS_SEL(v) HIWORD_UPDATE(v, 0, 1)
42 #define RV1106_VOGRF_VOP_PIPE_BYPASS 0x60034
43 #define RV1106_VOP_PIPE_BYPASS(v) HIWORD_UPDATE(v, 0, 1)
44
45 #define RV1126_GRF_IOFUNC_CON3 0x1026c
46 #define RV1126_LCDC_IO_BYPASS(v) HIWORD_UPDATE(v, 0, 0)
47
48 #define RK3288_GRF_SOC_CON6 0x025c
49 #define RK3288_LVDS_LCDC_SEL(x) HIWORD_UPDATE(x, 3, 3)
50 #define RK3288_GRF_SOC_CON7 0x0260
51 #define RK3288_LVDS_PWRDWN(x) HIWORD_UPDATE(x, 15, 15)
52 #define RK3288_LVDS_CON_ENABLE_2(x) HIWORD_UPDATE(x, 12, 12)
53 #define RK3288_LVDS_CON_ENABLE_1(x) HIWORD_UPDATE(x, 11, 11)
54 #define RK3288_LVDS_CON_CLKINV(x) HIWORD_UPDATE(x, 8, 8)
55 #define RK3288_LVDS_CON_TTL_EN(x) HIWORD_UPDATE(x, 6, 6)
56
57 #define RK3562_GRF_IOC_VO_IO_CON 0x10500
58 #define RK3562_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6)
59
60 #define RK3568_GRF_VO_CON1 0X0364
61 #define RK3568_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6)
62
63 struct rockchip_rgb;
64
65 struct rockchip_rgb_funcs {
66 void (*enable)(struct rockchip_rgb *rgb);
67 void (*disable)(struct rockchip_rgb *rgb);
68 };
69
70 struct rockchip_rgb_data {
71 u32 max_dclk_rate;
72 const struct rockchip_rgb_funcs *funcs;
73 };
74
75 struct mcu_cmd_header {
76 u8 data_type;
77 u8 delay;
78 u8 payload_length;
79 } __packed;
80
81 struct mcu_cmd_desc {
82 struct mcu_cmd_header header;
83 u8 *payload;
84 };
85
86 struct mcu_cmd_seq {
87 struct mcu_cmd_desc *cmds;
88 unsigned int cmd_cnt;
89 };
90
91 struct rockchip_mcu_panel_desc {
92 struct drm_display_mode *mode;
93 struct mcu_cmd_seq *init_seq;
94 struct mcu_cmd_seq *exit_seq;
95
96 struct {
97 unsigned int width;
98 unsigned int height;
99 } size;
100
101 struct {
102 unsigned int prepare;
103 unsigned int enable;
104 unsigned int disable;
105 unsigned int unprepare;
106 unsigned int reset;
107 unsigned int init;
108 } delay;
109
110 unsigned int bpc;
111 u32 bus_format;
112 u32 bus_flags;
113 };
114
115 struct rockchip_mcu_panel {
116 struct drm_panel base;
117 struct drm_device *drm_dev;
118 struct rockchip_mcu_panel_desc *desc;
119
120 struct gpio_desc *enable_gpio;
121 struct gpio_desc *reset_gpio;
122
123 struct device_node *np_crtc;
124
125 bool prepared;
126 bool enabled;
127 };
128
129 struct rockchip_rgb {
130 u8 id;
131 u32 max_dclk_rate;
132 struct device *dev;
133 struct drm_panel *panel;
134 struct drm_bridge *bridge;
135 struct drm_connector connector;
136 struct drm_encoder encoder;
137 struct phy *phy;
138 struct regmap *grf;
139 bool data_sync_bypass;
140 bool is_mcu_panel;
141 bool phy_enabled;
142 const struct rockchip_rgb_funcs *funcs;
143 struct rockchip_drm_sub_dev sub_dev;
144 };
145
connector_to_rgb(struct drm_connector * c)146 static inline struct rockchip_rgb *connector_to_rgb(struct drm_connector *c)
147 {
148 return container_of(c, struct rockchip_rgb, connector);
149 }
150
encoder_to_rgb(struct drm_encoder * e)151 static inline struct rockchip_rgb *encoder_to_rgb(struct drm_encoder *e)
152 {
153 return container_of(e, struct rockchip_rgb, encoder);
154 }
155
to_rockchip_mcu_panel(struct drm_panel * panel)156 static inline struct rockchip_mcu_panel *to_rockchip_mcu_panel(struct drm_panel *panel)
157 {
158 return container_of(panel, struct rockchip_mcu_panel, base);
159 }
160
161 static enum drm_connector_status
rockchip_rgb_connector_detect(struct drm_connector * connector,bool force)162 rockchip_rgb_connector_detect(struct drm_connector *connector, bool force)
163 {
164 return connector_status_connected;
165 }
166
167 static int
rockchip_rgb_atomic_connector_get_property(struct drm_connector * connector,const struct drm_connector_state * state,struct drm_property * property,uint64_t * val)168 rockchip_rgb_atomic_connector_get_property(struct drm_connector *connector,
169 const struct drm_connector_state *state,
170 struct drm_property *property,
171 uint64_t *val)
172 {
173 struct rockchip_rgb *rgb = connector_to_rgb(connector);
174 struct rockchip_drm_private *private = connector->dev->dev_private;
175
176 if (property == private->connector_id_prop) {
177 *val = rgb->id;
178 return 0;
179 }
180
181 DRM_ERROR("failed to get rockchip RGB property\n");
182 return -EINVAL;
183 }
184
185 static const struct drm_connector_funcs rockchip_rgb_connector_funcs = {
186 .detect = rockchip_rgb_connector_detect,
187 .fill_modes = drm_helper_probe_single_connector_modes,
188 .destroy = drm_connector_cleanup,
189 .reset = drm_atomic_helper_connector_reset,
190 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
191 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
192 .atomic_get_property = rockchip_rgb_atomic_connector_get_property,
193 };
194
rockchip_rgb_connector_get_modes(struct drm_connector * connector)195 static int rockchip_rgb_connector_get_modes(struct drm_connector *connector)
196 {
197 struct rockchip_rgb *rgb = connector_to_rgb(connector);
198 struct drm_panel *panel = rgb->panel;
199
200 return drm_panel_get_modes(panel, connector);
201 }
202
203 static struct drm_encoder *
rockchip_rgb_connector_best_encoder(struct drm_connector * connector)204 rockchip_rgb_connector_best_encoder(struct drm_connector *connector)
205 {
206 struct rockchip_rgb *rgb = connector_to_rgb(connector);
207
208 return &rgb->encoder;
209 }
210
211 static const
212 struct drm_connector_helper_funcs rockchip_rgb_connector_helper_funcs = {
213 .get_modes = rockchip_rgb_connector_get_modes,
214 .best_encoder = rockchip_rgb_connector_best_encoder,
215 };
216
rockchip_rgb_encoder_enable(struct drm_encoder * encoder)217 static void rockchip_rgb_encoder_enable(struct drm_encoder *encoder)
218 {
219 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
220
221 pinctrl_pm_select_default_state(rgb->dev);
222
223 if (rgb->funcs && rgb->funcs->enable)
224 rgb->funcs->enable(rgb);
225
226 if (rgb->phy && !rgb->phy_enabled) {
227 phy_power_on(rgb->phy);
228 rgb->phy_enabled = true;
229 }
230
231 if (rgb->panel) {
232 drm_panel_prepare(rgb->panel);
233 drm_panel_enable(rgb->panel);
234 }
235 }
236
rockchip_rgb_encoder_disable(struct drm_encoder * encoder)237 static void rockchip_rgb_encoder_disable(struct drm_encoder *encoder)
238 {
239 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
240
241 if (rgb->panel) {
242 drm_panel_disable(rgb->panel);
243 drm_panel_unprepare(rgb->panel);
244 }
245
246 if (rgb->phy && rgb->phy_enabled) {
247 phy_power_off(rgb->phy);
248 rgb->phy_enabled = false;
249 }
250
251 if (rgb->funcs && rgb->funcs->disable)
252 rgb->funcs->disable(rgb);
253
254 pinctrl_pm_select_sleep_state(rgb->dev);
255 }
256
257 static int
rockchip_rgb_encoder_atomic_check(struct drm_encoder * encoder,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)258 rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder,
259 struct drm_crtc_state *crtc_state,
260 struct drm_connector_state *conn_state)
261 {
262 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
263 struct drm_connector *connector = conn_state->connector;
264 struct drm_display_info *info = &connector->display_info;
265
266 if (info->num_bus_formats)
267 s->bus_format = info->bus_formats[0];
268 else
269 s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
270
271 switch (s->bus_format) {
272 case MEDIA_BUS_FMT_RGB666_1X18:
273 s->output_mode = ROCKCHIP_OUT_MODE_P666;
274 s->output_if = VOP_OUTPUT_IF_RGB;
275 break;
276 case MEDIA_BUS_FMT_RGB565_1X16:
277 s->output_mode = ROCKCHIP_OUT_MODE_P565;
278 s->output_if = VOP_OUTPUT_IF_RGB;
279 break;
280 case MEDIA_BUS_FMT_RGB565_2X8_LE:
281 case MEDIA_BUS_FMT_BGR565_2X8_LE:
282 s->output_mode = ROCKCHIP_OUT_MODE_S565;
283 s->output_if = VOP_OUTPUT_IF_RGB;
284 break;
285 case MEDIA_BUS_FMT_RGB666_3X6:
286 s->output_mode = ROCKCHIP_OUT_MODE_S666;
287 s->output_if = VOP_OUTPUT_IF_RGB;
288 break;
289 case MEDIA_BUS_FMT_RGB888_3X8:
290 case MEDIA_BUS_FMT_BGR888_3X8:
291 s->output_mode = ROCKCHIP_OUT_MODE_S888;
292 s->output_if = VOP_OUTPUT_IF_RGB;
293 break;
294 case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
295 case MEDIA_BUS_FMT_BGR888_DUMMY_4X8:
296 s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
297 s->output_if = VOP_OUTPUT_IF_RGB;
298 break;
299 case MEDIA_BUS_FMT_YUYV8_2X8:
300 case MEDIA_BUS_FMT_YVYU8_2X8:
301 case MEDIA_BUS_FMT_UYVY8_2X8:
302 case MEDIA_BUS_FMT_VYUY8_2X8:
303 s->output_mode = ROCKCHIP_OUT_MODE_BT656;
304 s->output_if = VOP_OUTPUT_IF_BT656;
305 break;
306 case MEDIA_BUS_FMT_YUYV8_1X16:
307 case MEDIA_BUS_FMT_YVYU8_1X16:
308 case MEDIA_BUS_FMT_UYVY8_1X16:
309 case MEDIA_BUS_FMT_VYUY8_1X16:
310 s->output_mode = ROCKCHIP_OUT_MODE_BT1120;
311 s->output_if = VOP_OUTPUT_IF_BT1120;
312 break;
313 case MEDIA_BUS_FMT_RGB888_1X24:
314 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
315 default:
316 s->output_mode = ROCKCHIP_OUT_MODE_P888;
317 s->output_if = VOP_OUTPUT_IF_RGB;
318 break;
319 }
320
321 s->output_type = DRM_MODE_CONNECTOR_DPI;
322 s->bus_flags = info->bus_flags;
323 s->tv_state = &conn_state->tv;
324 s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
325 s->color_space = V4L2_COLORSPACE_DEFAULT;
326
327 return 0;
328 }
329
rockchip_rgb_encoder_loader_protect(struct drm_encoder * encoder,bool on)330 static int rockchip_rgb_encoder_loader_protect(struct drm_encoder *encoder,
331 bool on)
332 {
333 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
334
335 if (rgb->is_mcu_panel) {
336 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
337
338 mcu_panel->prepared = true;
339 mcu_panel->enabled = true;
340
341 return 0;
342 }
343
344 if (rgb->panel)
345 panel_simple_loader_protect(rgb->panel);
346
347 if (on) {
348 phy_init(rgb->phy);
349 if (rgb->phy) {
350 rgb->phy->power_count++;
351 rgb->phy_enabled = true;
352 }
353 } else {
354 phy_exit(rgb->phy);
355 if (rgb->phy) {
356 rgb->phy->power_count--;
357 rgb->phy_enabled = false;
358 }
359 }
360
361 return 0;
362 }
363
364 static enum drm_mode_status
rockchip_rgb_encoder_mode_valid(struct drm_encoder * encoder,const struct drm_display_mode * mode)365 rockchip_rgb_encoder_mode_valid(struct drm_encoder *encoder,
366 const struct drm_display_mode *mode)
367 {
368 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
369 struct device *dev = rgb->dev;
370 u32 request_clock = mode->clock;
371 u32 max_clock = rgb->max_dclk_rate;
372
373 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
374 request_clock *= 2;
375
376 if (max_clock != 0 && request_clock > max_clock) {
377 DRM_DEV_ERROR(dev, "mode [%dx%d] clock %d is higher than max_clock %d\n",
378 mode->hdisplay, mode->vdisplay, request_clock, max_clock);
379 return MODE_CLOCK_HIGH;
380 }
381
382 return MODE_OK;
383 }
384
385 static const
386 struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = {
387 .enable = rockchip_rgb_encoder_enable,
388 .disable = rockchip_rgb_encoder_disable,
389 .atomic_check = rockchip_rgb_encoder_atomic_check,
390 .mode_valid = rockchip_rgb_encoder_mode_valid,
391 };
392
393 static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = {
394 .destroy = drm_encoder_cleanup,
395 };
396
rockchip_mcu_panel_parse_cmd_seq(struct device * dev,const u8 * data,int length,struct mcu_cmd_seq * seq)397 static int rockchip_mcu_panel_parse_cmd_seq(struct device *dev,
398 const u8 *data, int length,
399 struct mcu_cmd_seq *seq)
400 {
401 struct mcu_cmd_header *header;
402 struct mcu_cmd_desc *desc;
403 char *buf, *d;
404 unsigned int i, cnt, len;
405
406 if (!seq)
407 return -EINVAL;
408
409 buf = devm_kmemdup(dev, data, length, GFP_KERNEL);
410 if (!buf)
411 return -ENOMEM;
412
413 d = buf;
414 len = length;
415 cnt = 0;
416 while (len > sizeof(*header)) {
417 header = (struct mcu_cmd_header *)d;
418
419 d += sizeof(*header);
420 len -= sizeof(*header);
421
422 if (header->payload_length > len)
423 return -EINVAL;
424
425 d += header->payload_length;
426 len -= header->payload_length;
427 cnt++;
428 }
429
430 if (len)
431 return -EINVAL;
432
433 seq->cmd_cnt = cnt;
434 seq->cmds = devm_kcalloc(dev, cnt, sizeof(*desc), GFP_KERNEL);
435 if (!seq->cmds)
436 return -ENOMEM;
437
438 d = buf;
439 len = length;
440 for (i = 0; i < cnt; i++) {
441 header = (struct mcu_cmd_header *)d;
442 len -= sizeof(*header);
443 d += sizeof(*header);
444
445 desc = &seq->cmds[i];
446 desc->header = *header;
447 desc->payload = d;
448
449 d += header->payload_length;
450 len -= header->payload_length;
451 }
452
453 return 0;
454 }
455
rockchip_mcu_panel_init(struct rockchip_rgb * rgb,struct device_node * np_mcu_panel)456 static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb, struct device_node *np_mcu_panel)
457 {
458 struct device *dev = rgb->dev;
459 struct device_node *port, *endpoint, *np_crtc, *remote;
460 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
461 struct drm_display_mode *mode;
462 const void *data;
463 int len;
464 int ret;
465 u32 bus_flags;
466
467 mcu_panel->enable_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
468 "enable", 0, GPIOD_ASIS,
469 fwnode_get_name(&np_mcu_panel->fwnode));
470 if (IS_ERR(mcu_panel->enable_gpio)) {
471 DRM_DEV_ERROR(dev, "failed to find mcu panel enable GPIO\n");
472 return PTR_ERR(mcu_panel->enable_gpio);
473 }
474
475 mcu_panel->reset_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
476 "reset", 0, GPIOD_ASIS,
477 fwnode_get_name(&np_mcu_panel->fwnode));
478 if (IS_ERR(mcu_panel->reset_gpio)) {
479 DRM_DEV_ERROR(dev, "failed to find mcu panel reset GPIO\n");
480 return PTR_ERR(mcu_panel->reset_gpio);
481 }
482
483 mcu_panel->desc = devm_kzalloc(dev, sizeof(*mcu_panel->desc), GFP_KERNEL);
484 if (!mcu_panel->desc)
485 return -ENOMEM;
486
487 mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
488 if (!mode)
489 return -ENOMEM;
490
491 if (!of_get_drm_display_mode(np_mcu_panel, mode, &bus_flags,
492 OF_USE_NATIVE_MODE)) {
493 mcu_panel->desc->mode = mode;
494 mcu_panel->desc->bus_flags = bus_flags;
495 } else {
496 DRM_DEV_ERROR(dev, "failed to parse display mode\n");
497 return -EINVAL;
498 }
499
500 of_property_read_u32(np_mcu_panel, "bpc", &mcu_panel->desc->bpc);
501 of_property_read_u32(np_mcu_panel, "bus-format", &mcu_panel->desc->bus_format);
502 of_property_read_u32(np_mcu_panel, "width-mm", &mcu_panel->desc->size.width);
503 of_property_read_u32(np_mcu_panel, "height-mm", &mcu_panel->desc->size.height);
504
505 of_property_read_u32(np_mcu_panel, "prepare-delay-ms", &mcu_panel->desc->delay.prepare);
506 of_property_read_u32(np_mcu_panel, "enable-delay-ms", &mcu_panel->desc->delay.enable);
507 of_property_read_u32(np_mcu_panel, "disable-delay-ms", &mcu_panel->desc->delay.disable);
508 of_property_read_u32(np_mcu_panel, "unprepare-delay-ms",
509 &mcu_panel->desc->delay.unprepare);
510 of_property_read_u32(np_mcu_panel, "reset-delay-ms", &mcu_panel->desc->delay.reset);
511 of_property_read_u32(np_mcu_panel, "init-delay-ms", &mcu_panel->desc->delay.init);
512
513 data = of_get_property(np_mcu_panel, "panel-init-sequence", &len);
514 if (data) {
515 mcu_panel->desc->init_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->init_seq),
516 GFP_KERNEL);
517 if (!mcu_panel->desc->init_seq)
518 return -ENOMEM;
519
520 ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
521 mcu_panel->desc->init_seq);
522 if (ret < 0) {
523 DRM_DEV_ERROR(dev, "failed to parse init sequence\n");
524 return ret;
525 }
526 }
527
528 data = of_get_property(np_mcu_panel, "panel-exit-sequence", &len);
529 if (data) {
530 mcu_panel->desc->exit_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->exit_seq),
531 GFP_KERNEL);
532 if (!mcu_panel->desc->exit_seq)
533 return -ENOMEM;
534
535 ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
536 mcu_panel->desc->exit_seq);
537 if (ret < 0) {
538 DRM_DEV_ERROR(dev, "failed to parse exit sequence\n");
539 return ret;
540 }
541 }
542
543 /*
544 * Support to find crtc device for both vop and vop3:
545 * vopl/vopb -> rgb
546 * vop2/vop3 -> vp -> rgb
547 */
548 port = of_graph_get_port_by_id(dev->of_node, 0);
549 if (port) {
550 for_each_child_of_node(port, endpoint) {
551 if (of_device_is_available(endpoint)) {
552 remote = of_graph_get_remote_endpoint(endpoint);
553 if (remote) {
554 np_crtc = of_get_next_parent(remote);
555 mcu_panel->np_crtc = np_crtc;
556 break;
557 }
558 }
559 }
560
561 if (!mcu_panel->np_crtc) {
562 DRM_DEV_ERROR(dev, "failed to find available crtc for mcu panel\n");
563 return -EINVAL;
564 }
565 }
566
567 return 0;
568 }
569
rockchip_mcu_panel_sleep(unsigned int msec)570 static void rockchip_mcu_panel_sleep(unsigned int msec)
571 {
572 if (msec > 20)
573 msleep(msec);
574 else
575 usleep_range(msec * 1000, (msec + 1) * 1000);
576 }
577
rockchip_mcu_panel_xfer_mcu_cmd_seq(struct rockchip_mcu_panel * mcu_panel,struct mcu_cmd_seq * cmds)578 static int rockchip_mcu_panel_xfer_mcu_cmd_seq(struct rockchip_mcu_panel *mcu_panel,
579 struct mcu_cmd_seq *cmds)
580 {
581 struct drm_device *drm_dev = mcu_panel->drm_dev;
582 struct drm_panel *panel = &mcu_panel->base;
583 struct device_node *np_crtc = mcu_panel->np_crtc;
584 struct drm_crtc *crtc;
585 struct mcu_cmd_desc *cmd;
586 struct rockchip_drm_private *priv;
587 int i;
588 int pipe = 0;
589 u32 value;
590
591 if (!cmds)
592 return -EINVAL;
593
594 drm_for_each_crtc(crtc, drm_dev) {
595 if (crtc->port == np_crtc)
596 break;
597 }
598
599 pipe = drm_crtc_index(crtc);
600 priv = crtc->dev->dev_private;
601 if (!priv->crtc_funcs[pipe]->crtc_send_mcu_cmd) {
602 DRM_DEV_ERROR(panel->dev, "crtc not supported to send mcu cmds\n");
603 return -EINVAL;
604 }
605
606 priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 1);
607 for (i = 0; i < cmds->cmd_cnt; i++) {
608 cmd = &cmds->cmds[i];
609 value = cmd->payload[0];
610 priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, cmd->header.data_type, value);
611 if (cmd->header.delay)
612 rockchip_mcu_panel_sleep(cmd->header.delay);
613 }
614 priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 0);
615
616 return 0;
617 }
618
rockchip_mcu_panel_disable(struct drm_panel * panel)619 static int rockchip_mcu_panel_disable(struct drm_panel *panel)
620 {
621 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
622 int ret = 0;
623
624 if (!mcu_panel->enabled)
625 return 0;
626
627 if (mcu_panel->desc->delay.disable)
628 msleep(mcu_panel->desc->delay.disable);
629
630 ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->exit_seq);
631 if (ret)
632 DRM_DEV_ERROR(panel->dev, "failed to send exit cmds seq\n");
633
634 mcu_panel->enabled = false;
635
636 return 0;
637 }
638
rockchip_mcu_panel_unprepare(struct drm_panel * panel)639 static int rockchip_mcu_panel_unprepare(struct drm_panel *panel)
640 {
641 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
642
643 if (!mcu_panel->prepared)
644 return 0;
645
646 gpiod_direction_output(mcu_panel->reset_gpio, 1);
647 gpiod_direction_output(mcu_panel->enable_gpio, 0);
648
649 if (mcu_panel->desc->delay.unprepare)
650 msleep(mcu_panel->desc->delay.unprepare);
651
652 mcu_panel->prepared = false;
653
654 return 0;
655 }
656
rockchip_mcu_panel_prepare(struct drm_panel * panel)657 static int rockchip_mcu_panel_prepare(struct drm_panel *panel)
658 {
659 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
660 unsigned int delay;
661
662 if (mcu_panel->prepared)
663 return 0;
664
665 gpiod_direction_output(mcu_panel->enable_gpio, 1);
666
667 delay = mcu_panel->desc->delay.prepare;
668 if (delay)
669 msleep(delay);
670
671 gpiod_direction_output(mcu_panel->reset_gpio, 1);
672
673 if (mcu_panel->desc->delay.reset)
674 msleep(mcu_panel->desc->delay.reset);
675
676 gpiod_direction_output(mcu_panel->reset_gpio, 0);
677
678 if (mcu_panel->desc->delay.init)
679 msleep(mcu_panel->desc->delay.init);
680
681 mcu_panel->prepared = true;
682
683 return 0;
684 }
685
rockchip_mcu_panel_enable(struct drm_panel * panel)686 static int rockchip_mcu_panel_enable(struct drm_panel *panel)
687 {
688 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
689 int ret = 0;
690
691 if (mcu_panel->enabled)
692 return 0;
693
694 ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->init_seq);
695 if (ret)
696 DRM_DEV_ERROR(panel->dev, "failed to send init cmds seq\n");
697
698 if (mcu_panel->desc->delay.enable)
699 msleep(mcu_panel->desc->delay.enable);
700
701 mcu_panel->enabled = true;
702
703 return 0;
704 }
705
rockchip_mcu_panel_get_modes(struct drm_panel * panel,struct drm_connector * connector)706 static int rockchip_mcu_panel_get_modes(struct drm_panel *panel,
707 struct drm_connector *connector)
708 {
709 struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
710 struct drm_display_mode *m, *mode;
711
712 if (!mcu_panel->desc)
713 return 0;
714
715 m = mcu_panel->desc->mode;
716 mode = drm_mode_duplicate(connector->dev, m);
717 if (!mode) {
718 DRM_DEV_ERROR(mcu_panel->base.dev, "failed to add mode %ux%u@%u\n",
719 m->hdisplay, m->vdisplay,
720 drm_mode_vrefresh(m));
721 return 0;
722 }
723
724 mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
725
726 drm_mode_set_name(mode);
727
728 drm_mode_probed_add(connector, mode);
729
730 if (mcu_panel->desc->bpc)
731 connector->display_info.bpc = mcu_panel->desc->bpc;
732 if (mcu_panel->desc->size.width)
733 connector->display_info.width_mm = mcu_panel->desc->size.width;
734 if (mcu_panel->desc->size.height)
735 connector->display_info.height_mm = mcu_panel->desc->size.height;
736 if (mcu_panel->desc->bus_format)
737 drm_display_info_set_bus_formats(&connector->display_info,
738 &mcu_panel->desc->bus_format, 1);
739 if (mcu_panel->desc->bus_flags)
740 connector->display_info.bus_flags = mcu_panel->desc->bus_flags;
741
742 return 1;
743 }
744
745 static const struct drm_panel_funcs rockchip_mcu_panel_funcs = {
746 .disable = rockchip_mcu_panel_disable,
747 .unprepare = rockchip_mcu_panel_unprepare,
748 .prepare = rockchip_mcu_panel_prepare,
749 .enable = rockchip_mcu_panel_enable,
750 .get_modes = rockchip_mcu_panel_get_modes,
751 };
752
rockchip_mcu_panel_find_backlight(struct device_node * np_mcu_panel)753 static struct backlight_device *rockchip_mcu_panel_find_backlight(struct device_node *np_mcu_panel)
754 {
755 struct backlight_device *bd = NULL;
756 struct device_node *np = NULL;
757
758 np = of_parse_phandle(np_mcu_panel, "backlight", 0);
759 if (np) {
760 bd = of_find_backlight_by_node(np);
761 if (IS_ERR_OR_NULL(bd))
762 return NULL;
763
764 of_node_put(np);
765
766 if (!bd->props.brightness)
767 bd->props.brightness = bd->props.max_brightness;
768 }
769
770 return bd;
771 }
772
rockchip_rgb_bind(struct device * dev,struct device * master,void * data)773 static int rockchip_rgb_bind(struct device *dev, struct device *master,
774 void *data)
775 {
776 struct rockchip_rgb *rgb = dev_get_drvdata(dev);
777 struct drm_device *drm_dev = data;
778 struct drm_encoder *encoder = &rgb->encoder;
779 struct drm_connector *connector;
780 struct fwnode_handle *fwnode_mcu_panel;
781 int ret;
782
783 fwnode_mcu_panel = device_get_named_child_node(dev, "mcu-panel");
784 if (fwnode_mcu_panel) {
785 struct rockchip_mcu_panel *mcu_panel;
786 struct device_node *np_mcu_panel = to_of_node(fwnode_mcu_panel);
787
788 mcu_panel = devm_kzalloc(dev, sizeof(*mcu_panel), GFP_KERNEL);
789 if (!mcu_panel) {
790 of_node_put(np_mcu_panel);
791 return -ENOMEM;
792 }
793 mcu_panel->drm_dev = drm_dev;
794
795 rgb->panel = &mcu_panel->base;
796
797 ret = rockchip_mcu_panel_init(rgb, np_mcu_panel);
798 if (ret < 0) {
799 DRM_DEV_ERROR(dev, "failed to init mcu panel: %d\n", ret);
800 of_node_put(np_mcu_panel);
801 return ret;
802 }
803
804 rgb->panel->backlight = rockchip_mcu_panel_find_backlight(np_mcu_panel);
805 if (!rgb->panel->backlight) {
806 DRM_DEV_ERROR(dev, "failed to find backlight device");
807 of_node_put(np_mcu_panel);
808 return -EINVAL;
809 }
810
811 of_node_put(np_mcu_panel);
812
813 drm_panel_init(&mcu_panel->base, dev, &rockchip_mcu_panel_funcs,
814 DRM_MODE_CONNECTOR_DPI);
815
816 drm_panel_add(&mcu_panel->base);
817
818 rgb->is_mcu_panel = true;
819 } else {
820 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
821 &rgb->panel, &rgb->bridge);
822 if (ret) {
823 DRM_DEV_ERROR(dev, "failed to find panel or bridge: %d\n", ret);
824 return ret;
825 }
826 }
827
828 encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
829 dev->of_node);
830
831 ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs,
832 DRM_MODE_ENCODER_DPI, NULL);
833 if (ret < 0) {
834 DRM_DEV_ERROR(dev, "failed to initialize encoder: %d\n", ret);
835 return ret;
836 }
837
838 drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs);
839
840 if (rgb->panel) {
841 struct rockchip_drm_private *private = drm_dev->dev_private;
842
843 connector = &rgb->connector;
844 connector->interlace_allowed = true;
845 ret = drm_connector_init(drm_dev, connector,
846 &rockchip_rgb_connector_funcs,
847 DRM_MODE_CONNECTOR_DPI);
848 if (ret < 0) {
849 DRM_DEV_ERROR(dev,
850 "failed to initialize connector: %d\n",
851 ret);
852 goto err_free_encoder;
853 }
854
855 drm_connector_helper_add(connector,
856 &rockchip_rgb_connector_helper_funcs);
857
858 ret = drm_connector_attach_encoder(connector, encoder);
859 if (ret < 0) {
860 DRM_DEV_ERROR(dev,
861 "failed to attach encoder: %d\n", ret);
862 goto err_free_connector;
863 }
864 rgb->sub_dev.connector = &rgb->connector;
865 rgb->sub_dev.of_node = rgb->dev->of_node;
866 rgb->sub_dev.loader_protect = rockchip_rgb_encoder_loader_protect;
867 drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
868 rockchip_drm_register_sub_dev(&rgb->sub_dev);
869 } else {
870 rgb->bridge->encoder = encoder;
871 ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
872 if (ret) {
873 DRM_DEV_ERROR(dev,
874 "failed to attach bridge: %d\n", ret);
875 goto err_free_encoder;
876 }
877 }
878
879 return 0;
880
881 err_free_connector:
882 drm_connector_cleanup(connector);
883 err_free_encoder:
884 drm_encoder_cleanup(encoder);
885 return ret;
886 }
887
rockchip_rgb_unbind(struct device * dev,struct device * master,void * data)888 static void rockchip_rgb_unbind(struct device *dev, struct device *master,
889 void *data)
890 {
891 struct rockchip_rgb *rgb = dev_get_drvdata(dev);
892
893 if (rgb->sub_dev.connector)
894 rockchip_drm_unregister_sub_dev(&rgb->sub_dev);
895 if (rgb->panel)
896 drm_connector_cleanup(&rgb->connector);
897
898 drm_encoder_cleanup(&rgb->encoder);
899 }
900
901 static const struct component_ops rockchip_rgb_component_ops = {
902 .bind = rockchip_rgb_bind,
903 .unbind = rockchip_rgb_unbind,
904 };
905
rockchip_rgb_probe(struct platform_device * pdev)906 static int rockchip_rgb_probe(struct platform_device *pdev)
907 {
908 struct device *dev = &pdev->dev;
909 struct rockchip_rgb *rgb;
910 const struct rockchip_rgb_data *rgb_data;
911 int ret, id;
912
913 rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);
914 if (!rgb)
915 return -ENOMEM;
916
917 id = of_alias_get_id(dev->of_node, "rgb");
918 if (id < 0)
919 id = 0;
920
921 rgb_data = of_device_get_match_data(dev);
922 if (rgb_data) {
923 rgb->max_dclk_rate = rgb_data->max_dclk_rate;
924 rgb->funcs = rgb_data->funcs;
925 }
926 rgb->id = id;
927 rgb->dev = dev;
928 platform_set_drvdata(pdev, rgb);
929
930 rgb->data_sync_bypass =
931 of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass");
932
933 if (dev->parent && dev->parent->of_node) {
934 rgb->grf = syscon_node_to_regmap(dev->parent->of_node);
935 if (IS_ERR(rgb->grf)) {
936 ret = PTR_ERR(rgb->grf);
937 dev_err(dev, "Unable to get grf: %d\n", ret);
938 return ret;
939 }
940 }
941
942 rgb->phy = devm_phy_optional_get(dev, "phy");
943 if (IS_ERR(rgb->phy)) {
944 ret = PTR_ERR(rgb->phy);
945 dev_err(dev, "failed to get phy: %d\n", ret);
946 return ret;
947 }
948
949 return component_add(dev, &rockchip_rgb_component_ops);
950 }
951
rockchip_rgb_remove(struct platform_device * pdev)952 static int rockchip_rgb_remove(struct platform_device *pdev)
953 {
954 component_del(&pdev->dev, &rockchip_rgb_component_ops);
955
956 return 0;
957 }
958
px30_rgb_enable(struct rockchip_rgb * rgb)959 static void px30_rgb_enable(struct rockchip_rgb *rgb)
960 {
961 int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
962 &rgb->encoder);
963
964 regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) |
965 PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
966 }
967
968 static const struct rockchip_rgb_funcs px30_rgb_funcs = {
969 .enable = px30_rgb_enable,
970 };
971
972 static const struct rockchip_rgb_data px30_rgb = {
973 .funcs = &px30_rgb_funcs,
974 };
975
rk1808_rgb_enable(struct rockchip_rgb * rgb)976 static void rk1808_rgb_enable(struct rockchip_rgb *rgb)
977 {
978 regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
979 RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
980 }
981
982 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = {
983 .enable = rk1808_rgb_enable,
984 };
985
986 static const struct rockchip_rgb_data rk1808_rgb = {
987 .funcs = &rk1808_rgb_funcs,
988 };
989
rk3288_rgb_enable(struct rockchip_rgb * rgb)990 static void rk3288_rgb_enable(struct rockchip_rgb *rgb)
991 {
992 int pipe = drm_of_encoder_active_endpoint_id(rgb->dev->of_node,
993 &rgb->encoder);
994
995 regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe));
996 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
997 RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_ENABLE_2(1) |
998 RK3288_LVDS_CON_ENABLE_1(1) | RK3288_LVDS_CON_CLKINV(0) |
999 RK3288_LVDS_CON_TTL_EN(1));
1000 }
1001
rk3288_rgb_disable(struct rockchip_rgb * rgb)1002 static void rk3288_rgb_disable(struct rockchip_rgb *rgb)
1003 {
1004 regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
1005 RK3288_LVDS_PWRDWN(1) | RK3288_LVDS_CON_ENABLE_2(0) |
1006 RK3288_LVDS_CON_ENABLE_1(0) | RK3288_LVDS_CON_TTL_EN(0));
1007 }
1008
1009 static const struct rockchip_rgb_funcs rk3288_rgb_funcs = {
1010 .enable = rk3288_rgb_enable,
1011 .disable = rk3288_rgb_disable,
1012 };
1013
1014 static const struct rockchip_rgb_data rk3288_rgb = {
1015 .funcs = &rk3288_rgb_funcs,
1016 };
1017
rk3562_rgb_enable(struct rockchip_rgb * rgb)1018 static void rk3562_rgb_enable(struct rockchip_rgb *rgb)
1019 {
1020 regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON,
1021 RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass));
1022 }
1023
1024 static const struct rockchip_rgb_funcs rk3562_rgb_funcs = {
1025 .enable = rk3562_rgb_enable,
1026 };
1027
1028 static const struct rockchip_rgb_data rk3562_rgb = {
1029 .funcs = &rk3562_rgb_funcs,
1030 };
1031
rk3568_rgb_enable(struct rockchip_rgb * rgb)1032 static void rk3568_rgb_enable(struct rockchip_rgb *rgb)
1033 {
1034 regmap_write(rgb->grf, RK3568_GRF_VO_CON1,
1035 RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass));
1036 }
1037
1038 static const struct rockchip_rgb_funcs rk3568_rgb_funcs = {
1039 .enable = rk3568_rgb_enable,
1040 };
1041
1042 static const struct rockchip_rgb_data rk3568_rgb = {
1043 .funcs = &rk3568_rgb_funcs,
1044 };
1045
rv1126_rgb_enable(struct rockchip_rgb * rgb)1046 static void rv1126_rgb_enable(struct rockchip_rgb *rgb)
1047 {
1048 regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3,
1049 RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass));
1050 }
1051
1052 static const struct rockchip_rgb_funcs rv1126_rgb_funcs = {
1053 .enable = rv1126_rgb_enable,
1054 };
1055
1056 static const struct rockchip_rgb_data rv1126_rgb = {
1057 .funcs = &rv1126_rgb_funcs,
1058 };
1059
rv1106_rgb_enable(struct rockchip_rgb * rgb)1060 static void rv1106_rgb_enable(struct rockchip_rgb *rgb)
1061 {
1062 regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
1063 RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0));
1064 regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
1065 RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0));
1066 }
1067
1068 static const struct rockchip_rgb_funcs rv1106_rgb_funcs = {
1069 .enable = rv1106_rgb_enable,
1070 };
1071
1072 static const struct rockchip_rgb_data rv1106_rgb = {
1073 .max_dclk_rate = 74250,
1074 .funcs = &rv1106_rgb_funcs,
1075 };
1076
1077 static const struct of_device_id rockchip_rgb_dt_ids[] = {
1078 { .compatible = "rockchip,px30-rgb", .data = &px30_rgb },
1079 { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb },
1080 { .compatible = "rockchip,rk3066-rgb", },
1081 { .compatible = "rockchip,rk3128-rgb", },
1082 { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb },
1083 { .compatible = "rockchip,rk3308-rgb", },
1084 { .compatible = "rockchip,rk3368-rgb", },
1085 { .compatible = "rockchip,rk3562-rgb", .data = &rk3562_rgb },
1086 { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb },
1087 { .compatible = "rockchip,rk3588-rgb", },
1088 { .compatible = "rockchip,rv1106-rgb", .data = &rv1106_rgb},
1089 { .compatible = "rockchip,rv1108-rgb", },
1090 { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb},
1091 {}
1092 };
1093 MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids);
1094
1095 struct platform_driver rockchip_rgb_driver = {
1096 .probe = rockchip_rgb_probe,
1097 .remove = rockchip_rgb_remove,
1098 .driver = {
1099 .name = "rockchip-rgb",
1100 .of_match_table = of_match_ptr(rockchip_rgb_dt_ids),
1101 },
1102 };
1103