forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/rockchip/rockchip_rgb.c
....@@ -1,24 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
34 * Author:
45 * Sandy Huang <hjc@rock-chips.com>
5
- *
6
- * This software is licensed under the terms of the GNU General Public
7
- * License version 2, as published by the Free Software Foundation, and
8
- * may be copied, distributed, and modified under those terms.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 */
15
-
16
-#include <drm/drmP.h>
17
-#include <drm/drm_atomic_helper.h>
18
-#include <drm/drm_crtc_helper.h>
19
-#include <drm/drm_dp_helper.h>
20
-#include <drm/drm_panel.h>
21
-#include <drm/drm_of.h>
227
238 #include <linux/component.h>
249 #include <linux/of_device.h>
....@@ -27,6 +12,17 @@
2712 #include <linux/mfd/syscon.h>
2813 #include <linux/phy/phy.h>
2914 #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
+
3026 #include <uapi/linux/videodev2.h>
3127
3228 #include "rockchip_drm_drv.h"
....@@ -41,6 +37,11 @@
4137 #define RK1808_GRF_PD_VO_CON1 0x0444
4238 #define RK1808_RGB_DATA_SYNC_BYPASS(v) HIWORD_UPDATE(v, 3, 3)
4339
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
+
4445 #define RV1126_GRF_IOFUNC_CON3 0x1026c
4546 #define RV1126_LCDC_IO_BYPASS(v) HIWORD_UPDATE(v, 0, 0)
4647
....@@ -53,6 +54,9 @@
5354 #define RK3288_LVDS_CON_CLKINV(x) HIWORD_UPDATE(x, 8, 8)
5455 #define RK3288_LVDS_CON_TTL_EN(x) HIWORD_UPDATE(x, 6, 6)
5556
57
+#define RK3562_GRF_IOC_VO_IO_CON 0x10500
58
+#define RK3562_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6)
59
+
5660 #define RK3568_GRF_VO_CON1 0X0364
5761 #define RK3568_RGB_DATA_BYPASS(v) HIWORD_UPDATE(v, 6, 6)
5862
....@@ -63,9 +67,72 @@
6367 void (*disable)(struct rockchip_rgb *rgb);
6468 };
6569
70
+struct rockchip_rgb_data {
71
+ u32 rgb_max_dclk_rate;
72
+ u32 mcu_max_dclk_rate;
73
+ const struct rockchip_rgb_funcs *funcs;
74
+};
75
+
76
+struct mcu_cmd_header {
77
+ u8 data_type;
78
+ u8 delay;
79
+ u8 payload_length;
80
+} __packed;
81
+
82
+struct mcu_cmd_desc {
83
+ struct mcu_cmd_header header;
84
+ u8 *payload;
85
+};
86
+
87
+struct mcu_cmd_seq {
88
+ struct mcu_cmd_desc *cmds;
89
+ unsigned int cmd_cnt;
90
+};
91
+
92
+struct rockchip_mcu_panel_desc {
93
+ struct drm_display_mode *mode;
94
+ struct mcu_cmd_seq *init_seq;
95
+ struct mcu_cmd_seq *exit_seq;
96
+
97
+ struct {
98
+ unsigned int width;
99
+ unsigned int height;
100
+ } size;
101
+
102
+ struct {
103
+ unsigned int prepare;
104
+ unsigned int enable;
105
+ unsigned int disable;
106
+ unsigned int unprepare;
107
+ unsigned int reset;
108
+ unsigned int init;
109
+ } delay;
110
+
111
+ unsigned int bpc;
112
+ u32 bus_format;
113
+ u32 bus_flags;
114
+};
115
+
116
+struct rockchip_mcu_panel {
117
+ struct drm_panel base;
118
+ struct drm_device *drm_dev;
119
+ struct rockchip_mcu_panel_desc *desc;
120
+
121
+ struct gpio_desc *enable_gpio;
122
+ struct gpio_desc *reset_gpio;
123
+
124
+ struct device_node *np_crtc;
125
+
126
+ bool prepared;
127
+ bool enabled;
128
+};
129
+
66130 struct rockchip_rgb {
67131 u8 id;
132
+ u32 max_dclk_rate;
133
+ u32 mcu_pix_total;
68134 struct device *dev;
135
+ struct device_node *np_mcu_panel;
69136 struct drm_panel *panel;
70137 struct drm_bridge *bridge;
71138 struct drm_connector connector;
....@@ -73,6 +140,7 @@
73140 struct phy *phy;
74141 struct regmap *grf;
75142 bool data_sync_bypass;
143
+ bool phy_enabled;
76144 const struct rockchip_rgb_funcs *funcs;
77145 struct rockchip_drm_sub_dev sub_dev;
78146 };
....@@ -85,6 +153,11 @@
85153 static inline struct rockchip_rgb *encoder_to_rgb(struct drm_encoder *e)
86154 {
87155 return container_of(e, struct rockchip_rgb, encoder);
156
+}
157
+
158
+static inline struct rockchip_mcu_panel *to_rockchip_mcu_panel(struct drm_panel *panel)
159
+{
160
+ return container_of(panel, struct rockchip_mcu_panel, base);
88161 }
89162
90163 static enum drm_connector_status
....@@ -112,7 +185,6 @@
112185 }
113186
114187 static const struct drm_connector_funcs rockchip_rgb_connector_funcs = {
115
- .dpms = drm_helper_connector_dpms,
116188 .detect = rockchip_rgb_connector_detect,
117189 .fill_modes = drm_helper_probe_single_connector_modes,
118190 .destroy = drm_connector_cleanup,
....@@ -127,7 +199,7 @@
127199 struct rockchip_rgb *rgb = connector_to_rgb(connector);
128200 struct drm_panel *panel = rgb->panel;
129201
130
- return drm_panel_get_modes(panel);
202
+ return drm_panel_get_modes(panel, connector);
131203 }
132204
133205 static struct drm_encoder *
....@@ -147,21 +219,15 @@
147219 static void rockchip_rgb_encoder_enable(struct drm_encoder *encoder)
148220 {
149221 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
150
- int ret;
151222
152223 pinctrl_pm_select_default_state(rgb->dev);
153224
154225 if (rgb->funcs && rgb->funcs->enable)
155226 rgb->funcs->enable(rgb);
156227
157
- if (rgb->phy) {
158
- ret = phy_set_mode(rgb->phy, PHY_MODE_VIDEO_TTL);
159
- if (ret) {
160
- dev_err(rgb->dev, "failed to set phy mode: %d\n", ret);
161
- return;
162
- }
163
-
228
+ if (rgb->phy && !rgb->phy_enabled) {
164229 phy_power_on(rgb->phy);
230
+ rgb->phy_enabled = true;
165231 }
166232
167233 if (rgb->panel) {
....@@ -179,8 +245,10 @@
179245 drm_panel_unprepare(rgb->panel);
180246 }
181247
182
- if (rgb->phy)
248
+ if (rgb->phy && rgb->phy_enabled) {
183249 phy_power_off(rgb->phy);
250
+ rgb->phy_enabled = false;
251
+ }
184252
185253 if (rgb->funcs && rgb->funcs->disable)
186254 rgb->funcs->disable(rgb);
....@@ -211,11 +279,22 @@
211279 s->output_mode = ROCKCHIP_OUT_MODE_P565;
212280 s->output_if = VOP_OUTPUT_IF_RGB;
213281 break;
214
- case MEDIA_BUS_FMT_SRGB888_3X8:
282
+ case MEDIA_BUS_FMT_RGB565_2X8_LE:
283
+ case MEDIA_BUS_FMT_BGR565_2X8_LE:
284
+ s->output_mode = ROCKCHIP_OUT_MODE_S565;
285
+ s->output_if = VOP_OUTPUT_IF_RGB;
286
+ break;
287
+ case MEDIA_BUS_FMT_RGB666_3X6:
288
+ s->output_mode = ROCKCHIP_OUT_MODE_S666;
289
+ s->output_if = VOP_OUTPUT_IF_RGB;
290
+ break;
291
+ case MEDIA_BUS_FMT_RGB888_3X8:
292
+ case MEDIA_BUS_FMT_BGR888_3X8:
215293 s->output_mode = ROCKCHIP_OUT_MODE_S888;
216294 s->output_if = VOP_OUTPUT_IF_RGB;
217295 break;
218
- case MEDIA_BUS_FMT_SRGB888_DUMMY_4X8:
296
+ case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
297
+ case MEDIA_BUS_FMT_BGR888_DUMMY_4X8:
219298 s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
220299 s->output_if = VOP_OUTPUT_IF_RGB;
221300 break;
....@@ -244,7 +323,7 @@
244323 s->output_type = DRM_MODE_CONNECTOR_DPI;
245324 s->bus_flags = info->bus_flags;
246325 s->tv_state = &conn_state->tv;
247
- s->eotf = TRADITIONAL_GAMMA_SDR;
326
+ s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
248327 s->color_space = V4L2_COLORSPACE_DEFAULT;
249328
250329 return 0;
....@@ -255,10 +334,65 @@
255334 {
256335 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
257336
337
+ if (rgb->np_mcu_panel) {
338
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
339
+
340
+ mcu_panel->prepared = true;
341
+ mcu_panel->enabled = true;
342
+
343
+ return 0;
344
+ }
345
+
258346 if (rgb->panel)
259
- drm_panel_loader_protect(rgb->panel, on);
347
+ panel_simple_loader_protect(rgb->panel);
348
+
349
+ if (on) {
350
+ phy_init(rgb->phy);
351
+ if (rgb->phy) {
352
+ rgb->phy->power_count++;
353
+ rgb->phy_enabled = true;
354
+ }
355
+ } else {
356
+ phy_exit(rgb->phy);
357
+ if (rgb->phy) {
358
+ rgb->phy->power_count--;
359
+ rgb->phy_enabled = false;
360
+ }
361
+ }
260362
261363 return 0;
364
+}
365
+
366
+static enum drm_mode_status
367
+rockchip_rgb_encoder_mode_valid(struct drm_encoder *encoder,
368
+ const struct drm_display_mode *mode)
369
+{
370
+ struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
371
+ struct device *dev = rgb->dev;
372
+ struct drm_display_info *info = &rgb->connector.display_info;
373
+ u32 request_clock = mode->clock;
374
+ u32 max_clock = rgb->max_dclk_rate;
375
+ u32 bus_format;
376
+
377
+ if (info->num_bus_formats)
378
+ bus_format = info->bus_formats[0];
379
+ else
380
+ bus_format = MEDIA_BUS_FMT_RGB888_1X24;
381
+
382
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
383
+ request_clock *= 2;
384
+
385
+ if (rgb->np_mcu_panel)
386
+ request_clock *= rockchip_drm_get_cycles_per_pixel(bus_format) *
387
+ (rgb->mcu_pix_total + 1);
388
+
389
+ if (max_clock != 0 && request_clock > max_clock) {
390
+ DRM_DEV_ERROR(dev, "mode [%dx%d] clock %d is higher than max_clock %d\n",
391
+ mode->hdisplay, mode->vdisplay, request_clock, max_clock);
392
+ return MODE_CLOCK_HIGH;
393
+ }
394
+
395
+ return MODE_OK;
262396 }
263397
264398 static const
....@@ -266,12 +400,418 @@
266400 .enable = rockchip_rgb_encoder_enable,
267401 .disable = rockchip_rgb_encoder_disable,
268402 .atomic_check = rockchip_rgb_encoder_atomic_check,
269
- .loader_protect = rockchip_rgb_encoder_loader_protect,
403
+ .mode_valid = rockchip_rgb_encoder_mode_valid,
270404 };
271405
272406 static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = {
273407 .destroy = drm_encoder_cleanup,
274408 };
409
+
410
+static int rockchip_mcu_panel_parse_cmd_seq(struct device *dev,
411
+ const u8 *data, int length,
412
+ struct mcu_cmd_seq *seq)
413
+{
414
+ struct mcu_cmd_header *header;
415
+ struct mcu_cmd_desc *desc;
416
+ char *buf, *d;
417
+ unsigned int i, cnt, len;
418
+
419
+ if (!seq)
420
+ return -EINVAL;
421
+
422
+ buf = devm_kmemdup(dev, data, length, GFP_KERNEL);
423
+ if (!buf)
424
+ return -ENOMEM;
425
+
426
+ d = buf;
427
+ len = length;
428
+ cnt = 0;
429
+ while (len > sizeof(*header)) {
430
+ header = (struct mcu_cmd_header *)d;
431
+
432
+ d += sizeof(*header);
433
+ len -= sizeof(*header);
434
+
435
+ if (header->payload_length > len)
436
+ return -EINVAL;
437
+
438
+ d += header->payload_length;
439
+ len -= header->payload_length;
440
+ cnt++;
441
+ }
442
+
443
+ if (len)
444
+ return -EINVAL;
445
+
446
+ seq->cmd_cnt = cnt;
447
+ seq->cmds = devm_kcalloc(dev, cnt, sizeof(*desc), GFP_KERNEL);
448
+ if (!seq->cmds)
449
+ return -ENOMEM;
450
+
451
+ d = buf;
452
+ len = length;
453
+ for (i = 0; i < cnt; i++) {
454
+ header = (struct mcu_cmd_header *)d;
455
+ len -= sizeof(*header);
456
+ d += sizeof(*header);
457
+
458
+ desc = &seq->cmds[i];
459
+ desc->header = *header;
460
+ desc->payload = d;
461
+
462
+ d += header->payload_length;
463
+ len -= header->payload_length;
464
+ }
465
+
466
+ return 0;
467
+}
468
+
469
+static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb)
470
+{
471
+ struct device *dev = rgb->dev;
472
+ struct device_node *np_mcu_panel = rgb->np_mcu_panel;
473
+ struct device_node *port, *endpoint, *np_crtc, *remote, *np_mcu_timing;
474
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
475
+ struct drm_display_mode *mode;
476
+ const void *data;
477
+ int len;
478
+ int ret;
479
+ u32 bus_flags;
480
+ u32 val;
481
+
482
+ mcu_panel->enable_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
483
+ "enable", 0, GPIOD_ASIS,
484
+ fwnode_get_name(&np_mcu_panel->fwnode));
485
+ if (IS_ERR(mcu_panel->enable_gpio)) {
486
+ DRM_DEV_ERROR(dev, "failed to find mcu panel enable GPIO\n");
487
+ return PTR_ERR(mcu_panel->enable_gpio);
488
+ }
489
+
490
+ mcu_panel->reset_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
491
+ "reset", 0, GPIOD_ASIS,
492
+ fwnode_get_name(&np_mcu_panel->fwnode));
493
+ if (IS_ERR(mcu_panel->reset_gpio)) {
494
+ DRM_DEV_ERROR(dev, "failed to find mcu panel reset GPIO\n");
495
+ return PTR_ERR(mcu_panel->reset_gpio);
496
+ }
497
+
498
+ mcu_panel->desc = devm_kzalloc(dev, sizeof(*mcu_panel->desc), GFP_KERNEL);
499
+ if (!mcu_panel->desc)
500
+ return -ENOMEM;
501
+
502
+ mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
503
+ if (!mode)
504
+ return -ENOMEM;
505
+
506
+ if (!of_get_drm_display_mode(np_mcu_panel, mode, &bus_flags,
507
+ OF_USE_NATIVE_MODE)) {
508
+ mcu_panel->desc->mode = mode;
509
+ mcu_panel->desc->bus_flags = bus_flags;
510
+ } else {
511
+ DRM_DEV_ERROR(dev, "failed to parse display mode\n");
512
+ return -EINVAL;
513
+ }
514
+
515
+ of_property_read_u32(np_mcu_panel, "bpc", &mcu_panel->desc->bpc);
516
+ of_property_read_u32(np_mcu_panel, "bus-format", &mcu_panel->desc->bus_format);
517
+ of_property_read_u32(np_mcu_panel, "width-mm", &mcu_panel->desc->size.width);
518
+ of_property_read_u32(np_mcu_panel, "height-mm", &mcu_panel->desc->size.height);
519
+
520
+ of_property_read_u32(np_mcu_panel, "prepare-delay-ms", &mcu_panel->desc->delay.prepare);
521
+ of_property_read_u32(np_mcu_panel, "enable-delay-ms", &mcu_panel->desc->delay.enable);
522
+ of_property_read_u32(np_mcu_panel, "disable-delay-ms", &mcu_panel->desc->delay.disable);
523
+ of_property_read_u32(np_mcu_panel, "unprepare-delay-ms",
524
+ &mcu_panel->desc->delay.unprepare);
525
+ of_property_read_u32(np_mcu_panel, "reset-delay-ms", &mcu_panel->desc->delay.reset);
526
+ of_property_read_u32(np_mcu_panel, "init-delay-ms", &mcu_panel->desc->delay.init);
527
+
528
+ data = of_get_property(np_mcu_panel, "panel-init-sequence", &len);
529
+ if (data) {
530
+ mcu_panel->desc->init_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->init_seq),
531
+ GFP_KERNEL);
532
+ if (!mcu_panel->desc->init_seq)
533
+ return -ENOMEM;
534
+
535
+ ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
536
+ mcu_panel->desc->init_seq);
537
+ if (ret < 0) {
538
+ DRM_DEV_ERROR(dev, "failed to parse init sequence\n");
539
+ return ret;
540
+ }
541
+ }
542
+
543
+ data = of_get_property(np_mcu_panel, "panel-exit-sequence", &len);
544
+ if (data) {
545
+ mcu_panel->desc->exit_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->exit_seq),
546
+ GFP_KERNEL);
547
+ if (!mcu_panel->desc->exit_seq)
548
+ return -ENOMEM;
549
+
550
+ ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
551
+ mcu_panel->desc->exit_seq);
552
+ if (ret < 0) {
553
+ DRM_DEV_ERROR(dev, "failed to parse exit sequence\n");
554
+ return ret;
555
+ }
556
+ }
557
+
558
+ /*
559
+ * Support to find crtc device for both vop and vop3:
560
+ * vopl/vopb -> rgb
561
+ * vop2/vop3 -> vp -> rgb
562
+ */
563
+ port = of_graph_get_port_by_id(dev->of_node, 0);
564
+ if (port) {
565
+ for_each_child_of_node(port, endpoint) {
566
+ if (of_device_is_available(endpoint)) {
567
+ remote = of_graph_get_remote_endpoint(endpoint);
568
+ if (remote) {
569
+ np_crtc = of_get_next_parent(remote);
570
+ mcu_panel->np_crtc = np_crtc;
571
+
572
+ of_node_put(np_crtc);
573
+ break;
574
+ }
575
+ }
576
+ }
577
+
578
+ if (!mcu_panel->np_crtc) {
579
+ DRM_DEV_ERROR(dev, "failed to find available crtc for mcu panel\n");
580
+ return -EINVAL;
581
+ }
582
+
583
+ np_mcu_timing = of_get_child_by_name(mcu_panel->np_crtc, "mcu-timing");
584
+ if (!np_mcu_timing) {
585
+ np_crtc = of_get_parent(mcu_panel->np_crtc);
586
+ if (np_crtc)
587
+ np_mcu_timing = of_get_child_by_name(np_crtc, "mcu-timing");
588
+
589
+ if (!np_mcu_timing) {
590
+ DRM_DEV_ERROR(dev, "failed to find timing config for mcu panel\n");
591
+ of_node_put(np_crtc);
592
+ return -EINVAL;
593
+ }
594
+
595
+ of_node_put(np_crtc);
596
+ }
597
+
598
+ ret = of_property_read_u32(np_mcu_timing, "mcu-pix-total", &val);
599
+ if (ret || val == 0) {
600
+ DRM_DEV_ERROR(dev, "failed to parse mcu_pix_total config\n");
601
+ of_node_put(np_mcu_timing);
602
+ return -EINVAL;
603
+ }
604
+ rgb->mcu_pix_total = val;
605
+
606
+ of_node_put(np_mcu_timing);
607
+ }
608
+
609
+ return 0;
610
+}
611
+
612
+static void rockchip_mcu_panel_sleep(unsigned int msec)
613
+{
614
+ if (msec > 20)
615
+ msleep(msec);
616
+ else
617
+ usleep_range(msec * 1000, (msec + 1) * 1000);
618
+}
619
+
620
+static int rockchip_mcu_panel_xfer_mcu_cmd_seq(struct rockchip_mcu_panel *mcu_panel,
621
+ struct mcu_cmd_seq *cmds)
622
+{
623
+ struct drm_device *drm_dev = mcu_panel->drm_dev;
624
+ struct drm_panel *panel = &mcu_panel->base;
625
+ struct device_node *np_crtc = mcu_panel->np_crtc;
626
+ struct drm_crtc *crtc;
627
+ struct mcu_cmd_desc *cmd;
628
+ struct rockchip_drm_private *priv;
629
+ int i;
630
+ int pipe = 0;
631
+ u32 value;
632
+
633
+ if (!cmds)
634
+ return -EINVAL;
635
+
636
+ drm_for_each_crtc(crtc, drm_dev) {
637
+ if (crtc->port == np_crtc)
638
+ break;
639
+ }
640
+
641
+ pipe = drm_crtc_index(crtc);
642
+ priv = crtc->dev->dev_private;
643
+ if (!priv->crtc_funcs[pipe]->crtc_send_mcu_cmd) {
644
+ DRM_DEV_ERROR(panel->dev, "crtc not supported to send mcu cmds\n");
645
+ return -EINVAL;
646
+ }
647
+
648
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 1);
649
+ for (i = 0; i < cmds->cmd_cnt; i++) {
650
+ cmd = &cmds->cmds[i];
651
+ value = cmd->payload[0];
652
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, cmd->header.data_type, value);
653
+ if (cmd->header.delay)
654
+ rockchip_mcu_panel_sleep(cmd->header.delay);
655
+ }
656
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 0);
657
+
658
+ return 0;
659
+}
660
+
661
+static int rockchip_mcu_panel_disable(struct drm_panel *panel)
662
+{
663
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
664
+ int ret = 0;
665
+
666
+ if (!mcu_panel->enabled)
667
+ return 0;
668
+
669
+ if (mcu_panel->desc->delay.disable)
670
+ msleep(mcu_panel->desc->delay.disable);
671
+
672
+ ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->exit_seq);
673
+ if (ret)
674
+ DRM_DEV_ERROR(panel->dev, "failed to send exit cmds seq\n");
675
+
676
+ mcu_panel->enabled = false;
677
+
678
+ return 0;
679
+}
680
+
681
+static int rockchip_mcu_panel_unprepare(struct drm_panel *panel)
682
+{
683
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
684
+
685
+ if (!mcu_panel->prepared)
686
+ return 0;
687
+
688
+ gpiod_direction_output(mcu_panel->reset_gpio, 1);
689
+ gpiod_direction_output(mcu_panel->enable_gpio, 0);
690
+
691
+ if (mcu_panel->desc->delay.unprepare)
692
+ msleep(mcu_panel->desc->delay.unprepare);
693
+
694
+ mcu_panel->prepared = false;
695
+
696
+ return 0;
697
+}
698
+
699
+static int rockchip_mcu_panel_prepare(struct drm_panel *panel)
700
+{
701
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
702
+ unsigned int delay;
703
+
704
+ if (mcu_panel->prepared)
705
+ return 0;
706
+
707
+ gpiod_direction_output(mcu_panel->enable_gpio, 1);
708
+
709
+ delay = mcu_panel->desc->delay.prepare;
710
+ if (delay)
711
+ msleep(delay);
712
+
713
+ gpiod_direction_output(mcu_panel->reset_gpio, 1);
714
+
715
+ if (mcu_panel->desc->delay.reset)
716
+ msleep(mcu_panel->desc->delay.reset);
717
+
718
+ gpiod_direction_output(mcu_panel->reset_gpio, 0);
719
+
720
+ if (mcu_panel->desc->delay.init)
721
+ msleep(mcu_panel->desc->delay.init);
722
+
723
+ mcu_panel->prepared = true;
724
+
725
+ return 0;
726
+}
727
+
728
+static int rockchip_mcu_panel_enable(struct drm_panel *panel)
729
+{
730
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
731
+ int ret = 0;
732
+
733
+ if (mcu_panel->enabled)
734
+ return 0;
735
+
736
+ ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->init_seq);
737
+ if (ret)
738
+ DRM_DEV_ERROR(panel->dev, "failed to send init cmds seq\n");
739
+
740
+ if (mcu_panel->desc->delay.enable)
741
+ msleep(mcu_panel->desc->delay.enable);
742
+
743
+ mcu_panel->enabled = true;
744
+
745
+ return 0;
746
+}
747
+
748
+static int rockchip_mcu_panel_get_modes(struct drm_panel *panel,
749
+ struct drm_connector *connector)
750
+{
751
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
752
+ struct drm_display_mode *m, *mode;
753
+
754
+ if (!mcu_panel->desc)
755
+ return 0;
756
+
757
+ m = mcu_panel->desc->mode;
758
+ mode = drm_mode_duplicate(connector->dev, m);
759
+ if (!mode) {
760
+ DRM_DEV_ERROR(mcu_panel->base.dev, "failed to add mode %ux%u@%u\n",
761
+ m->hdisplay, m->vdisplay,
762
+ drm_mode_vrefresh(m));
763
+ return 0;
764
+ }
765
+
766
+ mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
767
+
768
+ drm_mode_set_name(mode);
769
+
770
+ drm_mode_probed_add(connector, mode);
771
+
772
+ if (mcu_panel->desc->bpc)
773
+ connector->display_info.bpc = mcu_panel->desc->bpc;
774
+ if (mcu_panel->desc->size.width)
775
+ connector->display_info.width_mm = mcu_panel->desc->size.width;
776
+ if (mcu_panel->desc->size.height)
777
+ connector->display_info.height_mm = mcu_panel->desc->size.height;
778
+ if (mcu_panel->desc->bus_format)
779
+ drm_display_info_set_bus_formats(&connector->display_info,
780
+ &mcu_panel->desc->bus_format, 1);
781
+ if (mcu_panel->desc->bus_flags)
782
+ connector->display_info.bus_flags = mcu_panel->desc->bus_flags;
783
+
784
+ return 1;
785
+}
786
+
787
+static const struct drm_panel_funcs rockchip_mcu_panel_funcs = {
788
+ .disable = rockchip_mcu_panel_disable,
789
+ .unprepare = rockchip_mcu_panel_unprepare,
790
+ .prepare = rockchip_mcu_panel_prepare,
791
+ .enable = rockchip_mcu_panel_enable,
792
+ .get_modes = rockchip_mcu_panel_get_modes,
793
+};
794
+
795
+static struct backlight_device *rockchip_mcu_panel_find_backlight(struct rockchip_rgb *rgb)
796
+{
797
+ struct backlight_device *bd = NULL;
798
+ struct device_node *np_mcu_panel = rgb->np_mcu_panel;
799
+ struct device_node *np = NULL;
800
+
801
+ np = of_parse_phandle(np_mcu_panel, "backlight", 0);
802
+ if (np) {
803
+ bd = of_find_backlight_by_node(np);
804
+ if (IS_ERR_OR_NULL(bd))
805
+ return NULL;
806
+
807
+ of_node_put(np);
808
+
809
+ if (!bd->props.brightness)
810
+ bd->props.brightness = bd->props.max_brightness;
811
+ }
812
+
813
+ return bd;
814
+}
275815
276816 static int rockchip_rgb_bind(struct device *dev, struct device *master,
277817 void *data)
....@@ -282,15 +822,44 @@
282822 struct drm_connector *connector;
283823 int ret;
284824
285
- ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
286
- &rgb->panel, &rgb->bridge);
287
- if (ret) {
288
- DRM_DEV_ERROR(dev, "failed to find panel or bridge: %d\n", ret);
289
- return ret;
825
+ if (rgb->np_mcu_panel) {
826
+ struct rockchip_mcu_panel *mcu_panel;
827
+
828
+ mcu_panel = devm_kzalloc(dev, sizeof(*mcu_panel), GFP_KERNEL);
829
+ if (!mcu_panel) {
830
+ return -ENOMEM;
831
+ }
832
+ mcu_panel->drm_dev = drm_dev;
833
+
834
+ rgb->panel = &mcu_panel->base;
835
+
836
+ ret = rockchip_mcu_panel_init(rgb);
837
+ if (ret < 0) {
838
+ DRM_DEV_ERROR(dev, "failed to init mcu panel: %d\n", ret);
839
+ return ret;
840
+ }
841
+
842
+ rgb->panel->backlight = rockchip_mcu_panel_find_backlight(rgb);
843
+ if (!rgb->panel->backlight) {
844
+ DRM_DEV_ERROR(dev, "failed to find backlight device");
845
+ return -EINVAL;
846
+ }
847
+
848
+ drm_panel_init(&mcu_panel->base, dev, &rockchip_mcu_panel_funcs,
849
+ DRM_MODE_CONNECTOR_DPI);
850
+
851
+ drm_panel_add(&mcu_panel->base);
852
+ } else {
853
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
854
+ &rgb->panel, &rgb->bridge);
855
+ if (ret) {
856
+ DRM_DEV_ERROR(dev, "failed to find panel or bridge: %d\n", ret);
857
+ return ret;
858
+ }
290859 }
291860
292
- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
293
- dev->of_node);
861
+ encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
862
+ dev->of_node);
294863
295864 ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs,
296865 DRM_MODE_ENCODER_DPI, NULL);
....@@ -325,25 +894,19 @@
325894 "failed to attach encoder: %d\n", ret);
326895 goto err_free_connector;
327896 }
328
-
329
- ret = drm_panel_attach(rgb->panel, connector);
330
- if (ret < 0) {
331
- DRM_DEV_ERROR(dev, "failed to attach panel: %d\n", ret);
332
- goto err_free_connector;
333
- }
334897 rgb->sub_dev.connector = &rgb->connector;
335898 rgb->sub_dev.of_node = rgb->dev->of_node;
899
+ rgb->sub_dev.loader_protect = rockchip_rgb_encoder_loader_protect;
336900 drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
337901 rockchip_drm_register_sub_dev(&rgb->sub_dev);
338902 } else {
339903 rgb->bridge->encoder = encoder;
340
- ret = drm_bridge_attach(encoder, rgb->bridge, NULL);
904
+ ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
341905 if (ret) {
342906 DRM_DEV_ERROR(dev,
343907 "failed to attach bridge: %d\n", ret);
344908 goto err_free_encoder;
345909 }
346
- encoder->bridge = rgb->bridge;
347910 }
348911
349912 return 0;
....@@ -362,10 +925,8 @@
362925
363926 if (rgb->sub_dev.connector)
364927 rockchip_drm_unregister_sub_dev(&rgb->sub_dev);
365
- if (rgb->panel) {
366
- drm_panel_detach(rgb->panel);
928
+ if (rgb->panel)
367929 drm_connector_cleanup(&rgb->connector);
368
- }
369930
370931 drm_encoder_cleanup(&rgb->encoder);
371932 }
....@@ -379,6 +940,8 @@
379940 {
380941 struct device *dev = &pdev->dev;
381942 struct rockchip_rgb *rgb;
943
+ const struct rockchip_rgb_data *rgb_data;
944
+ struct fwnode_handle *fwnode_mcu_panel;
382945 int ret, id;
383946
384947 rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);
....@@ -389,13 +952,23 @@
389952 if (id < 0)
390953 id = 0;
391954
955
+ rgb->data_sync_bypass = of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass");
956
+
957
+ fwnode_mcu_panel = device_get_named_child_node(dev, "mcu-panel");
958
+ if (fwnode_mcu_panel)
959
+ rgb->np_mcu_panel = to_of_node(fwnode_mcu_panel);
960
+
961
+ rgb_data = of_device_get_match_data(dev);
962
+ if (rgb_data) {
963
+ rgb->funcs = rgb_data->funcs;
964
+ if (rgb->np_mcu_panel)
965
+ rgb->max_dclk_rate = rgb_data->mcu_max_dclk_rate;
966
+ else
967
+ rgb->max_dclk_rate = rgb_data->rgb_max_dclk_rate;
968
+ }
392969 rgb->id = id;
393970 rgb->dev = dev;
394
- rgb->funcs = of_device_get_match_data(dev);
395971 platform_set_drvdata(pdev, rgb);
396
-
397
- rgb->data_sync_bypass =
398
- of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass");
399972
400973 if (dev->parent && dev->parent->of_node) {
401974 rgb->grf = syscon_node_to_regmap(dev->parent->of_node);
....@@ -436,6 +1009,10 @@
4361009 .enable = px30_rgb_enable,
4371010 };
4381011
1012
+static const struct rockchip_rgb_data px30_rgb = {
1013
+ .funcs = &px30_rgb_funcs,
1014
+};
1015
+
4391016 static void rk1808_rgb_enable(struct rockchip_rgb *rgb)
4401017 {
4411018 regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
....@@ -444,6 +1021,10 @@
4441021
4451022 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = {
4461023 .enable = rk1808_rgb_enable,
1024
+};
1025
+
1026
+static const struct rockchip_rgb_data rk1808_rgb = {
1027
+ .funcs = &rk1808_rgb_funcs,
4471028 };
4481029
4491030 static void rk3288_rgb_enable(struct rockchip_rgb *rgb)
....@@ -470,6 +1051,24 @@
4701051 .disable = rk3288_rgb_disable,
4711052 };
4721053
1054
+static const struct rockchip_rgb_data rk3288_rgb = {
1055
+ .funcs = &rk3288_rgb_funcs,
1056
+};
1057
+
1058
+static void rk3562_rgb_enable(struct rockchip_rgb *rgb)
1059
+{
1060
+ regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON,
1061
+ RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass));
1062
+}
1063
+
1064
+static const struct rockchip_rgb_funcs rk3562_rgb_funcs = {
1065
+ .enable = rk3562_rgb_enable,
1066
+};
1067
+
1068
+static const struct rockchip_rgb_data rk3562_rgb = {
1069
+ .funcs = &rk3562_rgb_funcs,
1070
+};
1071
+
4731072 static void rk3568_rgb_enable(struct rockchip_rgb *rgb)
4741073 {
4751074 regmap_write(rgb->grf, RK3568_GRF_VO_CON1,
....@@ -478,6 +1077,10 @@
4781077
4791078 static const struct rockchip_rgb_funcs rk3568_rgb_funcs = {
4801079 .enable = rk3568_rgb_enable,
1080
+};
1081
+
1082
+static const struct rockchip_rgb_data rk3568_rgb = {
1083
+ .funcs = &rk3568_rgb_funcs,
4811084 };
4821085
4831086 static void rv1126_rgb_enable(struct rockchip_rgb *rgb)
....@@ -490,17 +1093,42 @@
4901093 .enable = rv1126_rgb_enable,
4911094 };
4921095
1096
+static const struct rockchip_rgb_data rv1126_rgb = {
1097
+ .funcs = &rv1126_rgb_funcs,
1098
+};
1099
+
1100
+static void rv1106_rgb_enable(struct rockchip_rgb *rgb)
1101
+{
1102
+ regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
1103
+ RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0));
1104
+ regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
1105
+ RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0));
1106
+}
1107
+
1108
+static const struct rockchip_rgb_funcs rv1106_rgb_funcs = {
1109
+ .enable = rv1106_rgb_enable,
1110
+};
1111
+
1112
+static const struct rockchip_rgb_data rv1106_rgb = {
1113
+ .rgb_max_dclk_rate = 74250,
1114
+ .mcu_max_dclk_rate = 150000,
1115
+ .funcs = &rv1106_rgb_funcs,
1116
+};
1117
+
4931118 static const struct of_device_id rockchip_rgb_dt_ids[] = {
494
- { .compatible = "rockchip,px30-rgb", .data = &px30_rgb_funcs },
495
- { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb_funcs },
1119
+ { .compatible = "rockchip,px30-rgb", .data = &px30_rgb },
1120
+ { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb },
4961121 { .compatible = "rockchip,rk3066-rgb", },
4971122 { .compatible = "rockchip,rk3128-rgb", },
498
- { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb_funcs },
1123
+ { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb },
4991124 { .compatible = "rockchip,rk3308-rgb", },
5001125 { .compatible = "rockchip,rk3368-rgb", },
501
- { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb_funcs },
1126
+ { .compatible = "rockchip,rk3562-rgb", .data = &rk3562_rgb },
1127
+ { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb },
1128
+ { .compatible = "rockchip,rk3588-rgb", },
1129
+ { .compatible = "rockchip,rv1106-rgb", .data = &rv1106_rgb},
5021130 { .compatible = "rockchip,rv1108-rgb", },
503
- { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb_funcs},
1131
+ { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb},
5041132 {}
5051133 };
5061134 MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids);