forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
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,8 +67,68 @@
6367 void (*disable)(struct rockchip_rgb *rgb);
6468 };
6569
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
+
66129 struct rockchip_rgb {
67130 u8 id;
131
+ u32 max_dclk_rate;
68132 struct device *dev;
69133 struct drm_panel *panel;
70134 struct drm_bridge *bridge;
....@@ -73,6 +137,8 @@
73137 struct phy *phy;
74138 struct regmap *grf;
75139 bool data_sync_bypass;
140
+ bool is_mcu_panel;
141
+ bool phy_enabled;
76142 const struct rockchip_rgb_funcs *funcs;
77143 struct rockchip_drm_sub_dev sub_dev;
78144 };
....@@ -85,6 +151,11 @@
85151 static inline struct rockchip_rgb *encoder_to_rgb(struct drm_encoder *e)
86152 {
87153 return container_of(e, struct rockchip_rgb, encoder);
154
+}
155
+
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);
88159 }
89160
90161 static enum drm_connector_status
....@@ -112,7 +183,6 @@
112183 }
113184
114185 static const struct drm_connector_funcs rockchip_rgb_connector_funcs = {
115
- .dpms = drm_helper_connector_dpms,
116186 .detect = rockchip_rgb_connector_detect,
117187 .fill_modes = drm_helper_probe_single_connector_modes,
118188 .destroy = drm_connector_cleanup,
....@@ -127,7 +197,7 @@
127197 struct rockchip_rgb *rgb = connector_to_rgb(connector);
128198 struct drm_panel *panel = rgb->panel;
129199
130
- return drm_panel_get_modes(panel);
200
+ return drm_panel_get_modes(panel, connector);
131201 }
132202
133203 static struct drm_encoder *
....@@ -147,21 +217,15 @@
147217 static void rockchip_rgb_encoder_enable(struct drm_encoder *encoder)
148218 {
149219 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
150
- int ret;
151220
152221 pinctrl_pm_select_default_state(rgb->dev);
153222
154223 if (rgb->funcs && rgb->funcs->enable)
155224 rgb->funcs->enable(rgb);
156225
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
-
226
+ if (rgb->phy && !rgb->phy_enabled) {
164227 phy_power_on(rgb->phy);
228
+ rgb->phy_enabled = true;
165229 }
166230
167231 if (rgb->panel) {
....@@ -173,28 +237,21 @@
173237 static void rockchip_rgb_encoder_disable(struct drm_encoder *encoder)
174238 {
175239 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
176
- struct drm_crtc *crtc = encoder->crtc;
177
- struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
178240
179241 if (rgb->panel) {
180242 drm_panel_disable(rgb->panel);
181243 drm_panel_unprepare(rgb->panel);
182244 }
183245
184
- if (rgb->phy)
246
+ if (rgb->phy && rgb->phy_enabled) {
185247 phy_power_off(rgb->phy);
248
+ rgb->phy_enabled = false;
249
+ }
186250
187251 if (rgb->funcs && rgb->funcs->disable)
188252 rgb->funcs->disable(rgb);
189253
190254 pinctrl_pm_select_sleep_state(rgb->dev);
191
-
192
- if (s->output_if & VOP_OUTPUT_IF_RGB)
193
- s->output_if &= ~VOP_OUTPUT_IF_RGB;
194
- else if (s->output_if & VOP_OUTPUT_IF_BT656)
195
- s->output_if &= ~VOP_OUTPUT_IF_BT656;
196
- else if (s->output_if & VOP_OUTPUT_IF_BT1120)
197
- s->output_if &= ~VOP_OUTPUT_IF_BT1120;
198255 }
199256
200257 static int
....@@ -214,46 +271,48 @@
214271 switch (s->bus_format) {
215272 case MEDIA_BUS_FMT_RGB666_1X18:
216273 s->output_mode = ROCKCHIP_OUT_MODE_P666;
217
- s->output_if |= VOP_OUTPUT_IF_RGB;
274
+ s->output_if = VOP_OUTPUT_IF_RGB;
218275 break;
219276 case MEDIA_BUS_FMT_RGB565_1X16:
220277 s->output_mode = ROCKCHIP_OUT_MODE_P565;
221
- s->output_if |= VOP_OUTPUT_IF_RGB;
278
+ s->output_if = VOP_OUTPUT_IF_RGB;
222279 break;
223
- case MEDIA_BUS_FMT_SRGB888_3X8:
280
+ case MEDIA_BUS_FMT_RGB888_3X8:
281
+ case MEDIA_BUS_FMT_BGR888_3X8:
224282 s->output_mode = ROCKCHIP_OUT_MODE_S888;
225
- s->output_if |= VOP_OUTPUT_IF_RGB;
283
+ s->output_if = VOP_OUTPUT_IF_RGB;
226284 break;
227
- case MEDIA_BUS_FMT_SRGB888_DUMMY_4X8:
285
+ case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
286
+ case MEDIA_BUS_FMT_BGR888_DUMMY_4X8:
228287 s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
229
- s->output_if |= VOP_OUTPUT_IF_RGB;
288
+ s->output_if = VOP_OUTPUT_IF_RGB;
230289 break;
231290 case MEDIA_BUS_FMT_YUYV8_2X8:
232291 case MEDIA_BUS_FMT_YVYU8_2X8:
233292 case MEDIA_BUS_FMT_UYVY8_2X8:
234293 case MEDIA_BUS_FMT_VYUY8_2X8:
235294 s->output_mode = ROCKCHIP_OUT_MODE_BT656;
236
- s->output_if |= VOP_OUTPUT_IF_BT656;
295
+ s->output_if = VOP_OUTPUT_IF_BT656;
237296 break;
238297 case MEDIA_BUS_FMT_YUYV8_1X16:
239298 case MEDIA_BUS_FMT_YVYU8_1X16:
240299 case MEDIA_BUS_FMT_UYVY8_1X16:
241300 case MEDIA_BUS_FMT_VYUY8_1X16:
242301 s->output_mode = ROCKCHIP_OUT_MODE_BT1120;
243
- s->output_if |= VOP_OUTPUT_IF_BT1120;
302
+ s->output_if = VOP_OUTPUT_IF_BT1120;
244303 break;
245304 case MEDIA_BUS_FMT_RGB888_1X24:
246305 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
247306 default:
248307 s->output_mode = ROCKCHIP_OUT_MODE_P888;
249
- s->output_if |= VOP_OUTPUT_IF_RGB;
308
+ s->output_if = VOP_OUTPUT_IF_RGB;
250309 break;
251310 }
252311
253312 s->output_type = DRM_MODE_CONNECTOR_DPI;
254313 s->bus_flags = info->bus_flags;
255314 s->tv_state = &conn_state->tv;
256
- s->eotf = TRADITIONAL_GAMMA_SDR;
315
+ s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
257316 s->color_space = V4L2_COLORSPACE_DEFAULT;
258317
259318 return 0;
....@@ -264,10 +323,54 @@
264323 {
265324 struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
266325
326
+ if (rgb->is_mcu_panel) {
327
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
328
+
329
+ mcu_panel->prepared = true;
330
+ mcu_panel->enabled = true;
331
+
332
+ return 0;
333
+ }
334
+
267335 if (rgb->panel)
268
- drm_panel_loader_protect(rgb->panel, on);
336
+ panel_simple_loader_protect(rgb->panel);
337
+
338
+ if (on) {
339
+ phy_init(rgb->phy);
340
+ if (rgb->phy) {
341
+ rgb->phy->power_count++;
342
+ rgb->phy_enabled = true;
343
+ }
344
+ } else {
345
+ phy_exit(rgb->phy);
346
+ if (rgb->phy) {
347
+ rgb->phy->power_count--;
348
+ rgb->phy_enabled = false;
349
+ }
350
+ }
269351
270352 return 0;
353
+}
354
+
355
+static enum drm_mode_status
356
+rockchip_rgb_encoder_mode_valid(struct drm_encoder *encoder,
357
+ const struct drm_display_mode *mode)
358
+{
359
+ struct rockchip_rgb *rgb = encoder_to_rgb(encoder);
360
+ struct device *dev = rgb->dev;
361
+ u32 request_clock = mode->clock;
362
+ u32 max_clock = rgb->max_dclk_rate;
363
+
364
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
365
+ request_clock *= 2;
366
+
367
+ if (max_clock != 0 && request_clock > max_clock) {
368
+ DRM_DEV_ERROR(dev, "mode [%dx%d] clock %d is higher than max_clock %d\n",
369
+ mode->hdisplay, mode->vdisplay, request_clock, max_clock);
370
+ return MODE_CLOCK_HIGH;
371
+ }
372
+
373
+ return MODE_OK;
271374 }
272375
273376 static const
....@@ -275,12 +378,388 @@
275378 .enable = rockchip_rgb_encoder_enable,
276379 .disable = rockchip_rgb_encoder_disable,
277380 .atomic_check = rockchip_rgb_encoder_atomic_check,
278
- .loader_protect = rockchip_rgb_encoder_loader_protect,
381
+ .mode_valid = rockchip_rgb_encoder_mode_valid,
279382 };
280383
281384 static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = {
282385 .destroy = drm_encoder_cleanup,
283386 };
387
+
388
+static int rockchip_mcu_panel_parse_cmd_seq(struct device *dev,
389
+ const u8 *data, int length,
390
+ struct mcu_cmd_seq *seq)
391
+{
392
+ struct mcu_cmd_header *header;
393
+ struct mcu_cmd_desc *desc;
394
+ char *buf, *d;
395
+ unsigned int i, cnt, len;
396
+
397
+ if (!seq)
398
+ return -EINVAL;
399
+
400
+ buf = devm_kmemdup(dev, data, length, GFP_KERNEL);
401
+ if (!buf)
402
+ return -ENOMEM;
403
+
404
+ d = buf;
405
+ len = length;
406
+ cnt = 0;
407
+ while (len > sizeof(*header)) {
408
+ header = (struct mcu_cmd_header *)d;
409
+
410
+ d += sizeof(*header);
411
+ len -= sizeof(*header);
412
+
413
+ if (header->payload_length > len)
414
+ return -EINVAL;
415
+
416
+ d += header->payload_length;
417
+ len -= header->payload_length;
418
+ cnt++;
419
+ }
420
+
421
+ if (len)
422
+ return -EINVAL;
423
+
424
+ seq->cmd_cnt = cnt;
425
+ seq->cmds = devm_kcalloc(dev, cnt, sizeof(*desc), GFP_KERNEL);
426
+ if (!seq->cmds)
427
+ return -ENOMEM;
428
+
429
+ d = buf;
430
+ len = length;
431
+ for (i = 0; i < cnt; i++) {
432
+ header = (struct mcu_cmd_header *)d;
433
+ len -= sizeof(*header);
434
+ d += sizeof(*header);
435
+
436
+ desc = &seq->cmds[i];
437
+ desc->header = *header;
438
+ desc->payload = d;
439
+
440
+ d += header->payload_length;
441
+ len -= header->payload_length;
442
+ }
443
+
444
+ return 0;
445
+}
446
+
447
+static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb, struct device_node *np_mcu_panel)
448
+{
449
+ struct device *dev = rgb->dev;
450
+ struct device_node *port, *endpoint, *np_crtc, *remote;
451
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel);
452
+ struct drm_display_mode *mode;
453
+ const void *data;
454
+ int len;
455
+ int ret;
456
+ u32 bus_flags;
457
+
458
+ mcu_panel->enable_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
459
+ "enable", 0, GPIOD_ASIS,
460
+ fwnode_get_name(&np_mcu_panel->fwnode));
461
+ if (IS_ERR(mcu_panel->enable_gpio)) {
462
+ DRM_DEV_ERROR(dev, "failed to find mcu panel enable GPIO\n");
463
+ return PTR_ERR(mcu_panel->enable_gpio);
464
+ }
465
+
466
+ mcu_panel->reset_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode,
467
+ "reset", 0, GPIOD_ASIS,
468
+ fwnode_get_name(&np_mcu_panel->fwnode));
469
+ if (IS_ERR(mcu_panel->reset_gpio)) {
470
+ DRM_DEV_ERROR(dev, "failed to find mcu panel reset GPIO\n");
471
+ return PTR_ERR(mcu_panel->reset_gpio);
472
+ }
473
+
474
+ mcu_panel->desc = devm_kzalloc(dev, sizeof(*mcu_panel->desc), GFP_KERNEL);
475
+ if (!mcu_panel->desc)
476
+ return -ENOMEM;
477
+
478
+ mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
479
+ if (!mode)
480
+ return -ENOMEM;
481
+
482
+ if (!of_get_drm_display_mode(np_mcu_panel, mode, &bus_flags,
483
+ OF_USE_NATIVE_MODE)) {
484
+ mcu_panel->desc->mode = mode;
485
+ mcu_panel->desc->bus_flags = bus_flags;
486
+ } else {
487
+ DRM_DEV_ERROR(dev, "failed to parse display mode\n");
488
+ return -EINVAL;
489
+ }
490
+
491
+ of_property_read_u32(np_mcu_panel, "bpc", &mcu_panel->desc->bpc);
492
+ of_property_read_u32(np_mcu_panel, "bus-format", &mcu_panel->desc->bus_format);
493
+ of_property_read_u32(np_mcu_panel, "width-mm", &mcu_panel->desc->size.width);
494
+ of_property_read_u32(np_mcu_panel, "height-mm", &mcu_panel->desc->size.height);
495
+
496
+ of_property_read_u32(np_mcu_panel, "prepare-delay-ms", &mcu_panel->desc->delay.prepare);
497
+ of_property_read_u32(np_mcu_panel, "enable-delay-ms", &mcu_panel->desc->delay.enable);
498
+ of_property_read_u32(np_mcu_panel, "disable-delay-ms", &mcu_panel->desc->delay.disable);
499
+ of_property_read_u32(np_mcu_panel, "unprepare-delay-ms",
500
+ &mcu_panel->desc->delay.unprepare);
501
+ of_property_read_u32(np_mcu_panel, "reset-delay-ms", &mcu_panel->desc->delay.reset);
502
+ of_property_read_u32(np_mcu_panel, "init-delay-ms", &mcu_panel->desc->delay.init);
503
+
504
+ data = of_get_property(np_mcu_panel, "panel-init-sequence", &len);
505
+ if (data) {
506
+ mcu_panel->desc->init_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->init_seq),
507
+ GFP_KERNEL);
508
+ if (!mcu_panel->desc->init_seq)
509
+ return -ENOMEM;
510
+
511
+ ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
512
+ mcu_panel->desc->init_seq);
513
+ if (ret < 0) {
514
+ DRM_DEV_ERROR(dev, "failed to parse init sequence\n");
515
+ return ret;
516
+ }
517
+ }
518
+
519
+ data = of_get_property(np_mcu_panel, "panel-exit-sequence", &len);
520
+ if (data) {
521
+ mcu_panel->desc->exit_seq = devm_kzalloc(dev, sizeof(*mcu_panel->desc->exit_seq),
522
+ GFP_KERNEL);
523
+ if (!mcu_panel->desc->exit_seq)
524
+ return -ENOMEM;
525
+
526
+ ret = rockchip_mcu_panel_parse_cmd_seq(dev, data, len,
527
+ mcu_panel->desc->exit_seq);
528
+ if (ret < 0) {
529
+ DRM_DEV_ERROR(dev, "failed to parse exit sequence\n");
530
+ return ret;
531
+ }
532
+ }
533
+
534
+ /*
535
+ * Support to find crtc device for both vop and vop3:
536
+ * vopl/vopb -> rgb
537
+ * vop2/vop3 -> vp -> rgb
538
+ */
539
+ port = of_graph_get_port_by_id(dev->of_node, 0);
540
+ if (port) {
541
+ for_each_child_of_node(port, endpoint) {
542
+ if (of_device_is_available(endpoint)) {
543
+ remote = of_graph_get_remote_endpoint(endpoint);
544
+ if (remote) {
545
+ np_crtc = of_get_next_parent(remote);
546
+ mcu_panel->np_crtc = np_crtc;
547
+ break;
548
+ }
549
+ }
550
+ }
551
+
552
+ if (!mcu_panel->np_crtc) {
553
+ DRM_DEV_ERROR(dev, "failed to find available crtc for mcu panel\n");
554
+ return -EINVAL;
555
+ }
556
+ }
557
+
558
+ return 0;
559
+}
560
+
561
+static void rockchip_mcu_panel_sleep(unsigned int msec)
562
+{
563
+ if (msec > 20)
564
+ msleep(msec);
565
+ else
566
+ usleep_range(msec * 1000, (msec + 1) * 1000);
567
+}
568
+
569
+static int rockchip_mcu_panel_xfer_mcu_cmd_seq(struct rockchip_mcu_panel *mcu_panel,
570
+ struct mcu_cmd_seq *cmds)
571
+{
572
+ struct drm_device *drm_dev = mcu_panel->drm_dev;
573
+ struct drm_panel *panel = &mcu_panel->base;
574
+ struct device_node *np_crtc = mcu_panel->np_crtc;
575
+ struct drm_crtc *crtc;
576
+ struct mcu_cmd_desc *cmd;
577
+ struct rockchip_drm_private *priv;
578
+ int i;
579
+ int pipe = 0;
580
+ u32 value;
581
+
582
+ if (!cmds)
583
+ return -EINVAL;
584
+
585
+ drm_for_each_crtc(crtc, drm_dev) {
586
+ if (crtc->port == np_crtc)
587
+ break;
588
+ }
589
+
590
+ pipe = drm_crtc_index(crtc);
591
+ priv = crtc->dev->dev_private;
592
+ if (!priv->crtc_funcs[pipe]->crtc_send_mcu_cmd) {
593
+ DRM_DEV_ERROR(panel->dev, "crtc not supported to send mcu cmds\n");
594
+ return -EINVAL;
595
+ }
596
+
597
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 1);
598
+ for (i = 0; i < cmds->cmd_cnt; i++) {
599
+ cmd = &cmds->cmds[i];
600
+ value = cmd->payload[0];
601
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, cmd->header.data_type, value);
602
+ if (cmd->header.delay)
603
+ rockchip_mcu_panel_sleep(cmd->header.delay);
604
+ }
605
+ priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, MCU_SETBYPASS, 0);
606
+
607
+ return 0;
608
+}
609
+
610
+static int rockchip_mcu_panel_disable(struct drm_panel *panel)
611
+{
612
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
613
+ int ret = 0;
614
+
615
+ if (!mcu_panel->enabled)
616
+ return 0;
617
+
618
+ if (mcu_panel->desc->delay.disable)
619
+ msleep(mcu_panel->desc->delay.disable);
620
+
621
+ ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->exit_seq);
622
+ if (ret)
623
+ DRM_DEV_ERROR(panel->dev, "failed to send exit cmds seq\n");
624
+
625
+ mcu_panel->enabled = false;
626
+
627
+ return 0;
628
+}
629
+
630
+static int rockchip_mcu_panel_unprepare(struct drm_panel *panel)
631
+{
632
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
633
+
634
+ if (!mcu_panel->prepared)
635
+ return 0;
636
+
637
+ gpiod_direction_output(mcu_panel->reset_gpio, 1);
638
+ gpiod_direction_output(mcu_panel->enable_gpio, 0);
639
+
640
+ if (mcu_panel->desc->delay.unprepare)
641
+ msleep(mcu_panel->desc->delay.unprepare);
642
+
643
+ mcu_panel->prepared = false;
644
+
645
+ return 0;
646
+}
647
+
648
+static int rockchip_mcu_panel_prepare(struct drm_panel *panel)
649
+{
650
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
651
+ unsigned int delay;
652
+
653
+ if (mcu_panel->prepared)
654
+ return 0;
655
+
656
+ gpiod_direction_output(mcu_panel->enable_gpio, 1);
657
+
658
+ delay = mcu_panel->desc->delay.prepare;
659
+ if (delay)
660
+ msleep(delay);
661
+
662
+ gpiod_direction_output(mcu_panel->reset_gpio, 1);
663
+
664
+ if (mcu_panel->desc->delay.reset)
665
+ msleep(mcu_panel->desc->delay.reset);
666
+
667
+ gpiod_direction_output(mcu_panel->reset_gpio, 0);
668
+
669
+ if (mcu_panel->desc->delay.init)
670
+ msleep(mcu_panel->desc->delay.init);
671
+
672
+ mcu_panel->prepared = true;
673
+
674
+ return 0;
675
+}
676
+
677
+static int rockchip_mcu_panel_enable(struct drm_panel *panel)
678
+{
679
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
680
+ int ret = 0;
681
+
682
+ if (mcu_panel->enabled)
683
+ return 0;
684
+
685
+ ret = rockchip_mcu_panel_xfer_mcu_cmd_seq(mcu_panel, mcu_panel->desc->init_seq);
686
+ if (ret)
687
+ DRM_DEV_ERROR(panel->dev, "failed to send init cmds seq\n");
688
+
689
+ if (mcu_panel->desc->delay.enable)
690
+ msleep(mcu_panel->desc->delay.enable);
691
+
692
+ mcu_panel->enabled = true;
693
+
694
+ return 0;
695
+}
696
+
697
+static int rockchip_mcu_panel_get_modes(struct drm_panel *panel,
698
+ struct drm_connector *connector)
699
+{
700
+ struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
701
+ struct drm_display_mode *m, *mode;
702
+
703
+ if (!mcu_panel->desc)
704
+ return 0;
705
+
706
+ m = mcu_panel->desc->mode;
707
+ mode = drm_mode_duplicate(connector->dev, m);
708
+ if (!mode) {
709
+ DRM_DEV_ERROR(mcu_panel->base.dev, "failed to add mode %ux%u@%u\n",
710
+ m->hdisplay, m->vdisplay,
711
+ drm_mode_vrefresh(m));
712
+ return 0;
713
+ }
714
+
715
+ mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
716
+
717
+ drm_mode_set_name(mode);
718
+
719
+ drm_mode_probed_add(connector, mode);
720
+
721
+ if (mcu_panel->desc->bpc)
722
+ connector->display_info.bpc = mcu_panel->desc->bpc;
723
+ if (mcu_panel->desc->size.width)
724
+ connector->display_info.width_mm = mcu_panel->desc->size.width;
725
+ if (mcu_panel->desc->size.height)
726
+ connector->display_info.height_mm = mcu_panel->desc->size.height;
727
+ if (mcu_panel->desc->bus_format)
728
+ drm_display_info_set_bus_formats(&connector->display_info,
729
+ &mcu_panel->desc->bus_format, 1);
730
+ if (mcu_panel->desc->bus_flags)
731
+ connector->display_info.bus_flags = mcu_panel->desc->bus_flags;
732
+
733
+ return 1;
734
+}
735
+
736
+static const struct drm_panel_funcs rockchip_mcu_panel_funcs = {
737
+ .disable = rockchip_mcu_panel_disable,
738
+ .unprepare = rockchip_mcu_panel_unprepare,
739
+ .prepare = rockchip_mcu_panel_prepare,
740
+ .enable = rockchip_mcu_panel_enable,
741
+ .get_modes = rockchip_mcu_panel_get_modes,
742
+};
743
+
744
+static struct backlight_device *rockchip_mcu_panel_find_backlight(struct device_node *np_mcu_panel)
745
+{
746
+ struct backlight_device *bd = NULL;
747
+ struct device_node *np = NULL;
748
+
749
+ np = of_parse_phandle(np_mcu_panel, "backlight", 0);
750
+ if (np) {
751
+ bd = of_find_backlight_by_node(np);
752
+ if (IS_ERR_OR_NULL(bd))
753
+ return NULL;
754
+
755
+ of_node_put(np);
756
+
757
+ if (!bd->props.brightness)
758
+ bd->props.brightness = bd->props.max_brightness;
759
+ }
760
+
761
+ return bd;
762
+}
284763
285764 static int rockchip_rgb_bind(struct device *dev, struct device *master,
286765 void *data)
....@@ -289,17 +768,56 @@
289768 struct drm_device *drm_dev = data;
290769 struct drm_encoder *encoder = &rgb->encoder;
291770 struct drm_connector *connector;
771
+ struct fwnode_handle *fwnode_mcu_panel;
292772 int ret;
293773
294
- ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
295
- &rgb->panel, &rgb->bridge);
296
- if (ret) {
297
- DRM_DEV_ERROR(dev, "failed to find panel or bridge: %d\n", ret);
298
- return ret;
774
+ fwnode_mcu_panel = device_get_named_child_node(dev, "mcu-panel");
775
+ if (fwnode_mcu_panel) {
776
+ struct rockchip_mcu_panel *mcu_panel;
777
+ struct device_node *np_mcu_panel = to_of_node(fwnode_mcu_panel);
778
+
779
+ mcu_panel = devm_kzalloc(dev, sizeof(*mcu_panel), GFP_KERNEL);
780
+ if (!mcu_panel) {
781
+ of_node_put(np_mcu_panel);
782
+ return -ENOMEM;
783
+ }
784
+ mcu_panel->drm_dev = drm_dev;
785
+
786
+ rgb->panel = &mcu_panel->base;
787
+
788
+ ret = rockchip_mcu_panel_init(rgb, np_mcu_panel);
789
+ if (ret < 0) {
790
+ DRM_DEV_ERROR(dev, "failed to init mcu panel: %d\n", ret);
791
+ of_node_put(np_mcu_panel);
792
+ return ret;
793
+ }
794
+
795
+ rgb->panel->backlight = rockchip_mcu_panel_find_backlight(np_mcu_panel);
796
+ if (!rgb->panel->backlight) {
797
+ DRM_DEV_ERROR(dev, "failed to find backlight device");
798
+ of_node_put(np_mcu_panel);
799
+ return -EINVAL;
800
+ }
801
+
802
+ of_node_put(np_mcu_panel);
803
+
804
+ drm_panel_init(&mcu_panel->base, dev, &rockchip_mcu_panel_funcs,
805
+ DRM_MODE_CONNECTOR_DPI);
806
+
807
+ drm_panel_add(&mcu_panel->base);
808
+
809
+ rgb->is_mcu_panel = true;
810
+ } else {
811
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
812
+ &rgb->panel, &rgb->bridge);
813
+ if (ret) {
814
+ DRM_DEV_ERROR(dev, "failed to find panel or bridge: %d\n", ret);
815
+ return ret;
816
+ }
299817 }
300818
301
- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
302
- dev->of_node);
819
+ encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
820
+ dev->of_node);
303821
304822 ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs,
305823 DRM_MODE_ENCODER_DPI, NULL);
....@@ -334,25 +852,19 @@
334852 "failed to attach encoder: %d\n", ret);
335853 goto err_free_connector;
336854 }
337
-
338
- ret = drm_panel_attach(rgb->panel, connector);
339
- if (ret < 0) {
340
- DRM_DEV_ERROR(dev, "failed to attach panel: %d\n", ret);
341
- goto err_free_connector;
342
- }
343855 rgb->sub_dev.connector = &rgb->connector;
344856 rgb->sub_dev.of_node = rgb->dev->of_node;
857
+ rgb->sub_dev.loader_protect = rockchip_rgb_encoder_loader_protect;
345858 drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
346859 rockchip_drm_register_sub_dev(&rgb->sub_dev);
347860 } else {
348861 rgb->bridge->encoder = encoder;
349
- ret = drm_bridge_attach(encoder, rgb->bridge, NULL);
862
+ ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0);
350863 if (ret) {
351864 DRM_DEV_ERROR(dev,
352865 "failed to attach bridge: %d\n", ret);
353866 goto err_free_encoder;
354867 }
355
- encoder->bridge = rgb->bridge;
356868 }
357869
358870 return 0;
....@@ -371,10 +883,8 @@
371883
372884 if (rgb->sub_dev.connector)
373885 rockchip_drm_unregister_sub_dev(&rgb->sub_dev);
374
- if (rgb->panel) {
375
- drm_panel_detach(rgb->panel);
886
+ if (rgb->panel)
376887 drm_connector_cleanup(&rgb->connector);
377
- }
378888
379889 drm_encoder_cleanup(&rgb->encoder);
380890 }
....@@ -388,6 +898,7 @@
388898 {
389899 struct device *dev = &pdev->dev;
390900 struct rockchip_rgb *rgb;
901
+ const struct rockchip_rgb_data *rgb_data;
391902 int ret, id;
392903
393904 rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL);
....@@ -398,9 +909,13 @@
398909 if (id < 0)
399910 id = 0;
400911
912
+ rgb_data = of_device_get_match_data(dev);
913
+ if (rgb_data) {
914
+ rgb->max_dclk_rate = rgb_data->max_dclk_rate;
915
+ rgb->funcs = rgb_data->funcs;
916
+ }
401917 rgb->id = id;
402918 rgb->dev = dev;
403
- rgb->funcs = of_device_get_match_data(dev);
404919 platform_set_drvdata(pdev, rgb);
405920
406921 rgb->data_sync_bypass =
....@@ -445,6 +960,10 @@
445960 .enable = px30_rgb_enable,
446961 };
447962
963
+static const struct rockchip_rgb_data px30_rgb = {
964
+ .funcs = &px30_rgb_funcs,
965
+};
966
+
448967 static void rk1808_rgb_enable(struct rockchip_rgb *rgb)
449968 {
450969 regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
....@@ -453,6 +972,10 @@
453972
454973 static const struct rockchip_rgb_funcs rk1808_rgb_funcs = {
455974 .enable = rk1808_rgb_enable,
975
+};
976
+
977
+static const struct rockchip_rgb_data rk1808_rgb = {
978
+ .funcs = &rk1808_rgb_funcs,
456979 };
457980
458981 static void rk3288_rgb_enable(struct rockchip_rgb *rgb)
....@@ -479,6 +1002,24 @@
4791002 .disable = rk3288_rgb_disable,
4801003 };
4811004
1005
+static const struct rockchip_rgb_data rk3288_rgb = {
1006
+ .funcs = &rk3288_rgb_funcs,
1007
+};
1008
+
1009
+static void rk3562_rgb_enable(struct rockchip_rgb *rgb)
1010
+{
1011
+ regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON,
1012
+ RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass));
1013
+}
1014
+
1015
+static const struct rockchip_rgb_funcs rk3562_rgb_funcs = {
1016
+ .enable = rk3562_rgb_enable,
1017
+};
1018
+
1019
+static const struct rockchip_rgb_data rk3562_rgb = {
1020
+ .funcs = &rk3562_rgb_funcs,
1021
+};
1022
+
4821023 static void rk3568_rgb_enable(struct rockchip_rgb *rgb)
4831024 {
4841025 regmap_write(rgb->grf, RK3568_GRF_VO_CON1,
....@@ -487,6 +1028,10 @@
4871028
4881029 static const struct rockchip_rgb_funcs rk3568_rgb_funcs = {
4891030 .enable = rk3568_rgb_enable,
1031
+};
1032
+
1033
+static const struct rockchip_rgb_data rk3568_rgb = {
1034
+ .funcs = &rk3568_rgb_funcs,
4901035 };
4911036
4921037 static void rv1126_rgb_enable(struct rockchip_rgb *rgb)
....@@ -499,17 +1044,41 @@
4991044 .enable = rv1126_rgb_enable,
5001045 };
5011046
1047
+static const struct rockchip_rgb_data rv1126_rgb = {
1048
+ .funcs = &rv1126_rgb_funcs,
1049
+};
1050
+
1051
+static void rv1106_rgb_enable(struct rockchip_rgb *rgb)
1052
+{
1053
+ regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
1054
+ RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0));
1055
+ regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
1056
+ RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0));
1057
+}
1058
+
1059
+static const struct rockchip_rgb_funcs rv1106_rgb_funcs = {
1060
+ .enable = rv1106_rgb_enable,
1061
+};
1062
+
1063
+static const struct rockchip_rgb_data rv1106_rgb = {
1064
+ .max_dclk_rate = 74250,
1065
+ .funcs = &rv1106_rgb_funcs,
1066
+};
1067
+
5021068 static const struct of_device_id rockchip_rgb_dt_ids[] = {
503
- { .compatible = "rockchip,px30-rgb", .data = &px30_rgb_funcs },
504
- { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb_funcs },
1069
+ { .compatible = "rockchip,px30-rgb", .data = &px30_rgb },
1070
+ { .compatible = "rockchip,rk1808-rgb", .data = &rk1808_rgb },
5051071 { .compatible = "rockchip,rk3066-rgb", },
5061072 { .compatible = "rockchip,rk3128-rgb", },
507
- { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb_funcs },
1073
+ { .compatible = "rockchip,rk3288-rgb", .data = &rk3288_rgb },
5081074 { .compatible = "rockchip,rk3308-rgb", },
5091075 { .compatible = "rockchip,rk3368-rgb", },
510
- { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb_funcs },
1076
+ { .compatible = "rockchip,rk3562-rgb", .data = &rk3562_rgb },
1077
+ { .compatible = "rockchip,rk3568-rgb", .data = &rk3568_rgb },
1078
+ { .compatible = "rockchip,rk3588-rgb", },
1079
+ { .compatible = "rockchip,rv1106-rgb", .data = &rv1106_rgb},
5111080 { .compatible = "rockchip,rv1108-rgb", },
512
- { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb_funcs},
1081
+ { .compatible = "rockchip,rv1126-rgb", .data = &rv1126_rgb},
5131082 {}
5141083 };
5151084 MODULE_DEVICE_TABLE(of, rockchip_rgb_dt_ids);