hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
....@@ -1,62 +1,48 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
34 * Author:Mark Yao <mark.yao@rock-chips.com>
45 *
56 * based on exynos_drm_drv.c
6
- *
7
- * This software is licensed under the terms of the GNU General Public
8
- * License version 2, as published by the Free Software Foundation, and
9
- * may be copied, distributed, and modified under those terms.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
17
-#include <drm/drmP.h>
18
-#include <drm/drm_atomic.h>
19
-#include <drm/drm_crtc_helper.h>
20
-#include <drm/drm_fb_helper.h>
21
-#include <drm/drm_gem_cma_helper.h>
22
-#include <drm/drm_of.h>
23
-#include <linux/devfreq.h>
24
-#include <linux/dma-buf.h>
9
+#include <linux/dma-buf-cache.h>
2510 #include <linux/dma-mapping.h>
2611 #include <linux/dma-iommu.h>
2712 #include <linux/genalloc.h>
2813 #include <linux/pm_runtime.h>
29
-#include <linux/memblock.h>
3014 #include <linux/module.h>
3115 #include <linux/of_address.h>
3216 #include <linux/of_graph.h>
17
+#include <linux/of_platform.h>
3318 #include <linux/clk.h>
34
-#include <linux/clk-provider.h>
3519 #include <linux/component.h>
3620 #include <linux/console.h>
3721 #include <linux/iommu.h>
3822 #include <linux/of_reserved_mem.h>
3923
24
+#include <drm/drm_debugfs.h>
25
+#include <drm/drm_drv.h>
26
+#include <drm/drm_displayid.h>
27
+#include <drm/drm_fb_helper.h>
28
+#include <drm/drm_gem_cma_helper.h>
29
+#include <drm/drm_of.h>
30
+#include <drm/drm_probe_helper.h>
31
+#include <drm/drm_vblank.h>
32
+
4033 #include "rockchip_drm_drv.h"
4134 #include "rockchip_drm_fb.h"
4235 #include "rockchip_drm_fbdev.h"
4336 #include "rockchip_drm_gem.h"
37
+#include "rockchip_drm_logo.h"
4438
45
-#include "../drm_internal.h"
39
+#include "../drm_crtc_internal.h"
4640
4741 #define DRIVER_NAME "rockchip"
4842 #define DRIVER_DESC "RockChip Soc DRM"
4943 #define DRIVER_DATE "20140818"
50
-#define DRIVER_MAJOR 2
44
+#define DRIVER_MAJOR 3
5145 #define DRIVER_MINOR 0
52
-#define DRIVER_PATCH 0
53
-
54
-/***********************************************************************
55
- * Rockchip DRM driver version
56
- *
57
- * v2.0.0 : add basic version for linux 4.19 rockchip drm driver(hjc)
58
- *
59
- **********************************************************************/
6046
6147 #if IS_ENABLED(CONFIG_DRM_ROCKCHIP_VVOP)
6248 static bool is_support_iommu = false;
....@@ -64,40 +50,234 @@
6450 static bool is_support_iommu = true;
6551 #endif
6652 static bool iommu_reserve_map;
53
+
6754 static struct drm_driver rockchip_drm_driver;
6855
69
-struct rockchip_drm_mode_set {
70
- struct list_head head;
71
- struct drm_framebuffer *fb;
72
- struct drm_connector *connector;
73
- struct drm_crtc *crtc;
74
- struct drm_display_mode *mode;
75
- int clock;
76
- int hdisplay;
77
- int vdisplay;
78
- int vrefresh;
79
- int flags;
80
- int picture_aspect_ratio;
81
- int crtc_hsync_end;
82
- int crtc_vsync_end;
56
+static unsigned int drm_debug;
57
+module_param_named(debug, drm_debug, int, 0600);
8358
84
- int left_margin;
85
- int right_margin;
86
- int top_margin;
87
- int bottom_margin;
59
+static inline bool rockchip_drm_debug_enabled(enum rockchip_drm_debug_category category)
60
+{
61
+ return unlikely(drm_debug & category);
62
+}
8863
89
- unsigned int brightness;
90
- unsigned int contrast;
91
- unsigned int saturation;
92
- unsigned int hue;
64
+__printf(3, 4)
65
+void rockchip_drm_dbg(const struct device *dev, enum rockchip_drm_debug_category category,
66
+ const char *format, ...)
67
+{
68
+ struct va_format vaf;
69
+ va_list args;
9370
94
- bool mode_changed;
95
- bool force_output;
96
- int ratio;
97
-};
71
+ if (!rockchip_drm_debug_enabled(category))
72
+ return;
73
+
74
+ va_start(args, format);
75
+ vaf.fmt = format;
76
+ vaf.va = &args;
77
+
78
+ if (dev)
79
+ dev_printk(KERN_DEBUG, dev, "%pV", &vaf);
80
+ else
81
+ printk(KERN_DEBUG "%pV", &vaf);
82
+
83
+ va_end(args);
84
+}
85
+
86
+/**
87
+ * rockchip_drm_wait_vact_end
88
+ * @crtc: CRTC to enable line flag
89
+ * @mstimeout: millisecond for timeout
90
+ *
91
+ * Wait for vact_end line flag irq or timeout.
92
+ *
93
+ * Returns:
94
+ * Zero on success, negative errno on failure.
95
+ */
96
+int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
97
+{
98
+ struct rockchip_drm_private *priv;
99
+ int pipe, ret = 0;
100
+
101
+ if (!crtc)
102
+ return -ENODEV;
103
+
104
+ if (mstimeout <= 0)
105
+ return -EINVAL;
106
+
107
+ priv = crtc->dev->dev_private;
108
+ pipe = drm_crtc_index(crtc);
109
+
110
+ if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->wait_vact_end)
111
+ ret = priv->crtc_funcs[pipe]->wait_vact_end(crtc, mstimeout);
112
+
113
+ return ret;
114
+}
115
+EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
116
+
117
+void drm_mode_convert_to_split_mode(struct drm_display_mode *mode)
118
+{
119
+ u16 hactive, hfp, hsync, hbp;
120
+
121
+ hactive = mode->hdisplay;
122
+ hfp = mode->hsync_start - mode->hdisplay;
123
+ hsync = mode->hsync_end - mode->hsync_start;
124
+ hbp = mode->htotal - mode->hsync_end;
125
+
126
+ mode->clock *= 2;
127
+ mode->crtc_clock *= 2;
128
+ mode->hdisplay = hactive * 2;
129
+ mode->hsync_start = mode->hdisplay + hfp * 2;
130
+ mode->hsync_end = mode->hsync_start + hsync * 2;
131
+ mode->htotal = mode->hsync_end + hbp * 2;
132
+ drm_mode_set_name(mode);
133
+}
134
+EXPORT_SYMBOL(drm_mode_convert_to_split_mode);
135
+
136
+void drm_mode_convert_to_origin_mode(struct drm_display_mode *mode)
137
+{
138
+ u16 hactive, hfp, hsync, hbp;
139
+
140
+ hactive = mode->hdisplay;
141
+ hfp = mode->hsync_start - mode->hdisplay;
142
+ hsync = mode->hsync_end - mode->hsync_start;
143
+ hbp = mode->htotal - mode->hsync_end;
144
+
145
+ mode->clock /= 2;
146
+ mode->crtc_clock /= 2;
147
+ mode->hdisplay = hactive / 2;
148
+ mode->hsync_start = mode->hdisplay + hfp / 2;
149
+ mode->hsync_end = mode->hsync_start + hsync / 2;
150
+ mode->htotal = mode->hsync_end + hbp / 2;
151
+}
152
+EXPORT_SYMBOL(drm_mode_convert_to_origin_mode);
153
+
154
+/**
155
+ * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
156
+ * @connector: connector to report the event on
157
+ *
158
+ * On some hardware a hotplug event notification may come from outside the display
159
+ * driver / device. An example of this is some USB Type-C setups where the hardware
160
+ * muxes the DisplayPort data and aux-lines but does not pass the altmode HPD
161
+ * status bit to the GPU's DP HPD pin.
162
+ *
163
+ * This function can be used to report these out-of-band events after obtaining
164
+ * a drm_connector reference through calling drm_connector_find_by_fwnode().
165
+ */
166
+void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode)
167
+{
168
+ struct rockchip_drm_sub_dev *sub_dev;
169
+
170
+ if (!connector_fwnode || !connector_fwnode->dev)
171
+ return;
172
+
173
+ sub_dev = rockchip_drm_get_sub_dev(dev_of_node(connector_fwnode->dev));
174
+
175
+ if (sub_dev && sub_dev->connector && sub_dev->oob_hotplug_event)
176
+ sub_dev->oob_hotplug_event(sub_dev->connector);
177
+}
178
+EXPORT_SYMBOL(drm_connector_oob_hotplug_event);
179
+
180
+uint32_t rockchip_drm_get_bpp(const struct drm_format_info *info)
181
+{
182
+ /* use whatever a driver has set */
183
+ if (info->cpp[0])
184
+ return info->cpp[0] * 8;
185
+
186
+ switch (info->format) {
187
+ case DRM_FORMAT_YUV420_8BIT:
188
+ return 12;
189
+ case DRM_FORMAT_YUV420_10BIT:
190
+ return 15;
191
+ case DRM_FORMAT_VUY101010:
192
+ return 30;
193
+ default:
194
+ break;
195
+ }
196
+
197
+ /* all attempts failed */
198
+ return 0;
199
+}
200
+EXPORT_SYMBOL(rockchip_drm_get_bpp);
201
+
202
+uint32_t rockchip_drm_get_cycles_per_pixel(uint32_t bus_format)
203
+{
204
+ switch (bus_format) {
205
+ case MEDIA_BUS_FMT_RGB565_1X16:
206
+ case MEDIA_BUS_FMT_RGB666_1X18:
207
+ case MEDIA_BUS_FMT_RGB888_1X24:
208
+ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
209
+ return 1;
210
+ case MEDIA_BUS_FMT_RGB565_2X8_LE:
211
+ case MEDIA_BUS_FMT_BGR565_2X8_LE:
212
+ return 2;
213
+ case MEDIA_BUS_FMT_RGB666_3X6:
214
+ case MEDIA_BUS_FMT_RGB888_3X8:
215
+ case MEDIA_BUS_FMT_BGR888_3X8:
216
+ return 3;
217
+ case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
218
+ case MEDIA_BUS_FMT_BGR888_DUMMY_4X8:
219
+ return 4;
220
+ default:
221
+ return 1;
222
+ }
223
+}
224
+EXPORT_SYMBOL(rockchip_drm_get_cycles_per_pixel);
225
+
226
+/**
227
+ * rockchip_drm_of_find_possible_crtcs - find the possible CRTCs for an active
228
+ * encoder port
229
+ * @dev: DRM device
230
+ * @port: encoder port to scan for endpoints
231
+ *
232
+ * Scan all active endpoints attached to a port, locate their attached CRTCs,
233
+ * and generate the DRM mask of CRTCs which may be attached to this
234
+ * encoder.
235
+ *
236
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
237
+ */
238
+uint32_t rockchip_drm_of_find_possible_crtcs(struct drm_device *dev,
239
+ struct device_node *port)
240
+{
241
+ struct device_node *remote_port, *ep;
242
+ uint32_t possible_crtcs = 0;
243
+
244
+ for_each_endpoint_of_node(port, ep) {
245
+ if (!of_device_is_available(ep))
246
+ continue;
247
+
248
+ remote_port = of_graph_get_remote_port(ep);
249
+ if (!remote_port) {
250
+ of_node_put(ep);
251
+ continue;
252
+ }
253
+
254
+ possible_crtcs |= drm_of_crtc_port_mask(dev, remote_port);
255
+
256
+ of_node_put(remote_port);
257
+ }
258
+
259
+ return possible_crtcs;
260
+}
261
+EXPORT_SYMBOL(rockchip_drm_of_find_possible_crtcs);
98262
99263 static DEFINE_MUTEX(rockchip_drm_sub_dev_lock);
100264 static LIST_HEAD(rockchip_drm_sub_dev_list);
265
+
266
+void rockchip_connector_update_vfp_for_vrr(struct drm_crtc *crtc, struct drm_display_mode *mode,
267
+ int vfp)
268
+{
269
+ struct rockchip_drm_sub_dev *sub_dev;
270
+
271
+ mutex_lock(&rockchip_drm_sub_dev_lock);
272
+ list_for_each_entry(sub_dev, &rockchip_drm_sub_dev_list, list) {
273
+ if (sub_dev->connector->state->crtc == crtc) {
274
+ if (sub_dev->update_vfp_for_vrr)
275
+ sub_dev->update_vfp_for_vrr(sub_dev->connector, mode, vfp);
276
+ }
277
+ }
278
+ mutex_unlock(&rockchip_drm_sub_dev_lock);
279
+}
280
+EXPORT_SYMBOL(rockchip_connector_update_vfp_for_vrr);
101281
102282 void rockchip_drm_register_sub_dev(struct rockchip_drm_sub_dev *sub_dev)
103283 {
....@@ -151,6 +331,26 @@
151331 }
152332 EXPORT_SYMBOL(rockchip_drm_get_sub_dev_type);
153333
334
+u32 rockchip_drm_get_scan_line_time_ns(void)
335
+{
336
+ struct rockchip_drm_sub_dev *sub_dev = NULL;
337
+ struct drm_display_mode *mode;
338
+ int linedur_ns = 0;
339
+
340
+ mutex_lock(&rockchip_drm_sub_dev_lock);
341
+ list_for_each_entry(sub_dev, &rockchip_drm_sub_dev_list, list) {
342
+ if (sub_dev->connector->encoder && sub_dev->connector->state->crtc) {
343
+ mode = &sub_dev->connector->state->crtc->state->adjusted_mode;
344
+ linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, mode->crtc_clock);
345
+ break;
346
+ }
347
+ }
348
+ mutex_unlock(&rockchip_drm_sub_dev_lock);
349
+
350
+ return linedur_ns;
351
+}
352
+EXPORT_SYMBOL(rockchip_drm_get_scan_line_time_ns);
353
+
154354 void rockchip_drm_te_handle(struct drm_crtc *crtc)
155355 {
156356 struct rockchip_drm_private *priv = crtc->dev->dev_private;
....@@ -166,22 +366,22 @@
166366 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
167367 1430, 1650, 0, 720, 725, 730, 750, 0,
168368 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
169
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
369
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
170370 /* 16 - 1920x1080@60Hz 16:9 */
171371 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
172372 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
173373 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
174
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
374
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
175375 /* 31 - 1920x1080@50Hz 16:9 */
176376 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
177377 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
178378 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
179
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
379
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
180380 /* 19 - 1280x720@50Hz 16:9 */
181381 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
182382 1760, 1980, 0, 720, 725, 730, 750, 0,
183383 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
184
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
384
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
185385 /* 0x10 - 1024x768@60Hz */
186386 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
187387 1184, 1344, 0, 768, 771, 777, 806, 0,
....@@ -190,12 +390,12 @@
190390 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
191391 796, 864, 0, 576, 581, 586, 625, 0,
192392 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
193
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
393
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
194394 /* 2 - 720x480@60Hz 4:3 */
195395 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
196396 798, 858, 0, 480, 489, 495, 525, 0,
197397 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
198
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
398
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
199399 };
200400
201401 int rockchip_drm_add_modes_noedid(struct drm_connector *connector)
....@@ -224,1013 +424,638 @@
224424 }
225425 EXPORT_SYMBOL(rockchip_drm_add_modes_noedid);
226426
227
-#ifdef CONFIG_ARCH_ROCKCHIP
228
-struct drm_prime_callback_data {
229
- struct drm_gem_object *obj;
230
- struct sg_table *sgt;
427
+static const struct rockchip_drm_width_dclk {
428
+ int width;
429
+ u32 dclk_khz;
430
+} rockchip_drm_dclk[] = {
431
+ {1920, 148500},
432
+ {2048, 200000},
433
+ {2560, 280000},
434
+ {3840, 594000},
435
+ {4096, 594000},
436
+ {7680, 2376000},
231437 };
232
-#endif
233438
234
-#ifndef MODULE
235
-static struct drm_crtc *find_crtc_by_node(struct drm_device *drm_dev, struct device_node *node)
439
+u32 rockchip_drm_get_dclk_by_width(int width)
236440 {
237
- struct device_node *np_crtc;
238
- struct drm_crtc *crtc;
441
+ int i = 0;
442
+ u32 dclk_khz;
239443
240
- np_crtc = of_get_parent(node);
241
- if (!np_crtc || !of_device_is_available(np_crtc))
444
+ for (i = 0; i < ARRAY_SIZE(rockchip_drm_dclk); i++) {
445
+ if (width == rockchip_drm_dclk[i].width) {
446
+ dclk_khz = rockchip_drm_dclk[i].dclk_khz;
447
+ break;
448
+ }
449
+ }
450
+
451
+ if (i == ARRAY_SIZE(rockchip_drm_dclk)) {
452
+ DRM_ERROR("Can't not find %d width solution and use 148500 khz as max dclk\n", width);
453
+
454
+ dclk_khz = 148500;
455
+ }
456
+
457
+ return dclk_khz;
458
+}
459
+EXPORT_SYMBOL(rockchip_drm_get_dclk_by_width);
460
+
461
+static int
462
+cea_db_tag(const u8 *db)
463
+{
464
+ return db[0] >> 5;
465
+}
466
+
467
+static int
468
+cea_db_payload_len(const u8 *db)
469
+{
470
+ return db[0] & 0x1f;
471
+}
472
+
473
+#define for_each_cea_db(cea, i, start, end) \
474
+ for ((i) = (start); \
475
+ (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); \
476
+ (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
477
+
478
+#define HDMI_NEXT_HDR_VSDB_OUI 0xd04601
479
+
480
+static bool cea_db_is_hdmi_next_hdr_block(const u8 *db)
481
+{
482
+ unsigned int oui;
483
+
484
+ if (cea_db_tag(db) != 0x07)
485
+ return false;
486
+
487
+ if (cea_db_payload_len(db) < 11)
488
+ return false;
489
+
490
+ oui = db[3] << 16 | db[2] << 8 | db[1];
491
+
492
+ return oui == HDMI_NEXT_HDR_VSDB_OUI;
493
+}
494
+
495
+static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
496
+{
497
+ unsigned int oui;
498
+
499
+ if (cea_db_tag(db) != 0x03)
500
+ return false;
501
+
502
+ if (cea_db_payload_len(db) < 7)
503
+ return false;
504
+
505
+ oui = db[3] << 16 | db[2] << 8 | db[1];
506
+
507
+ return oui == HDMI_FORUM_IEEE_OUI;
508
+}
509
+
510
+static int
511
+cea_db_offsets(const u8 *cea, int *start, int *end)
512
+{
513
+ /* DisplayID CTA extension blocks and top-level CEA EDID
514
+ * block header definitions differ in the following bytes:
515
+ * 1) Byte 2 of the header specifies length differently,
516
+ * 2) Byte 3 is only present in the CEA top level block.
517
+ *
518
+ * The different definitions for byte 2 follow.
519
+ *
520
+ * DisplayID CTA extension block defines byte 2 as:
521
+ * Number of payload bytes
522
+ *
523
+ * CEA EDID block defines byte 2 as:
524
+ * Byte number (decimal) within this block where the 18-byte
525
+ * DTDs begin. If no non-DTD data is present in this extension
526
+ * block, the value should be set to 04h (the byte after next).
527
+ * If set to 00h, there are no DTDs present in this block and
528
+ * no non-DTD data.
529
+ */
530
+ if (cea[0] == 0x81) {
531
+ /*
532
+ * for_each_displayid_db() has already verified
533
+ * that these stay within expected bounds.
534
+ */
535
+ *start = 3;
536
+ *end = *start + cea[2];
537
+ } else if (cea[0] == 0x02) {
538
+ /* Data block offset in CEA extension block */
539
+ *start = 4;
540
+ *end = cea[2];
541
+ if (*end == 0)
542
+ *end = 127;
543
+ if (*end < 4 || *end > 127)
544
+ return -ERANGE;
545
+ } else {
546
+ return -EOPNOTSUPP;
547
+ }
548
+
549
+ return 0;
550
+}
551
+
552
+static u8 *find_edid_extension(const struct edid *edid,
553
+ int ext_id, int *ext_index)
554
+{
555
+ u8 *edid_ext = NULL;
556
+ int i;
557
+
558
+ /* No EDID or EDID extensions */
559
+ if (edid == NULL || edid->extensions == 0)
242560 return NULL;
243561
244
- drm_for_each_crtc(crtc, drm_dev) {
245
- if (crtc->port == np_crtc)
246
- return crtc;
562
+ /* Find CEA extension */
563
+ for (i = *ext_index; i < edid->extensions; i++) {
564
+ edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
565
+ if (edid_ext[0] == ext_id)
566
+ break;
567
+ }
568
+
569
+ if (i >= edid->extensions)
570
+ return NULL;
571
+
572
+ *ext_index = i + 1;
573
+
574
+ return edid_ext;
575
+}
576
+
577
+static int validate_displayid(u8 *displayid, int length, int idx)
578
+{
579
+ int i, dispid_length;
580
+ u8 csum = 0;
581
+ struct displayid_hdr *base;
582
+
583
+ base = (struct displayid_hdr *)&displayid[idx];
584
+
585
+ DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
586
+ base->rev, base->bytes, base->prod_id, base->ext_count);
587
+
588
+ /* +1 for DispID checksum */
589
+ dispid_length = sizeof(*base) + base->bytes + 1;
590
+ if (dispid_length > length - idx)
591
+ return -EINVAL;
592
+
593
+ for (i = 0; i < dispid_length; i++)
594
+ csum += displayid[idx + i];
595
+ if (csum) {
596
+ DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
597
+ return -EINVAL;
598
+ }
599
+
600
+ return 0;
601
+}
602
+
603
+static u8 *find_displayid_extension(const struct edid *edid,
604
+ int *length, int *idx,
605
+ int *ext_index)
606
+{
607
+ u8 *displayid = find_edid_extension(edid, 0x70, ext_index);
608
+ struct displayid_hdr *base;
609
+ int ret;
610
+
611
+ if (!displayid)
612
+ return NULL;
613
+
614
+ /* EDID extensions block checksum isn't for us */
615
+ *length = EDID_LENGTH - 1;
616
+ *idx = 1;
617
+
618
+ ret = validate_displayid(displayid, *length, *idx);
619
+ if (ret)
620
+ return NULL;
621
+
622
+ base = (struct displayid_hdr *)&displayid[*idx];
623
+ *length = *idx + sizeof(*base) + base->bytes;
624
+
625
+ return displayid;
626
+}
627
+
628
+static u8 *find_cea_extension(const struct edid *edid)
629
+{
630
+ int length, idx;
631
+ struct displayid_block *block;
632
+ u8 *cea;
633
+ u8 *displayid;
634
+ int ext_index;
635
+
636
+ /* Look for a top level CEA extension block */
637
+ /* FIXME: make callers iterate through multiple CEA ext blocks? */
638
+ ext_index = 0;
639
+ cea = find_edid_extension(edid, 0x02, &ext_index);
640
+ if (cea)
641
+ return cea;
642
+
643
+ /* CEA blocks can also be found embedded in a DisplayID block */
644
+ ext_index = 0;
645
+ for (;;) {
646
+ displayid = find_displayid_extension(edid, &length, &idx,
647
+ &ext_index);
648
+ if (!displayid)
649
+ return NULL;
650
+
651
+ idx += sizeof(struct displayid_hdr);
652
+ for_each_displayid_db(displayid, block, idx, length) {
653
+ if (block->tag == 0x81)
654
+ return (u8 *)block;
655
+ }
247656 }
248657
249658 return NULL;
250659 }
251660
252
-static struct drm_connector *find_connector_by_node(struct drm_device *drm_dev,
253
- struct device_node *node)
661
+#define EDID_CEA_YCRCB422 (1 << 4)
662
+
663
+int rockchip_drm_get_yuv422_format(struct drm_connector *connector,
664
+ struct edid *edid)
254665 {
255
- struct device_node *np_connector;
256
- struct rockchip_drm_sub_dev *sub_dev;
666
+ struct drm_display_info *info;
667
+ const u8 *edid_ext;
257668
258
- np_connector = of_graph_get_remote_port_parent(node);
259
- if (!np_connector || !of_device_is_available(np_connector))
260
- return NULL;
669
+ if (!connector || !edid)
670
+ return -EINVAL;
261671
262
- sub_dev = rockchip_drm_get_sub_dev(np_connector);
263
- if (!sub_dev)
264
- return NULL;
672
+ info = &connector->display_info;
265673
266
- return sub_dev->connector;
267
-}
674
+ edid_ext = find_cea_extension(edid);
675
+ if (!edid_ext)
676
+ return -EINVAL;
268677
269
-static struct drm_connector *find_connector_by_bridge(struct drm_device *drm_dev,
270
- struct device_node *node)
271
-{
272
- struct device_node *np_encoder, *np_connector = NULL;
273
- struct drm_connector *connector = NULL;
274
- struct device_node *port, *endpoint;
275
- struct rockchip_drm_sub_dev *sub_dev;
276
-
277
- np_encoder = of_graph_get_remote_port_parent(node);
278
- if (!np_encoder || !of_device_is_available(np_encoder))
279
- goto err_put_encoder;
280
-
281
- port = of_graph_get_port_by_id(np_encoder, 1);
282
- if (!port) {
283
- dev_err(drm_dev->dev, "can't found port point!\n");
284
- goto err_put_encoder;
285
- }
286
-
287
- for_each_child_of_node(port, endpoint) {
288
- np_connector = of_graph_get_remote_port_parent(endpoint);
289
- if (!np_connector) {
290
- dev_err(drm_dev->dev,
291
- "can't found connector node, please init!\n");
292
- goto err_put_port;
293
- }
294
- if (!of_device_is_available(np_connector)) {
295
- of_node_put(np_connector);
296
- np_connector = NULL;
297
- continue;
298
- } else {
299
- break;
300
- }
301
- }
302
- if (!np_connector) {
303
- dev_err(drm_dev->dev, "can't found available connector node!\n");
304
- goto err_put_port;
305
- }
306
-
307
- sub_dev = rockchip_drm_get_sub_dev(np_connector);
308
- if (!sub_dev)
309
- goto err_put_port;
310
- connector = sub_dev->connector;
311
-
312
- of_node_put(np_connector);
313
-err_put_port:
314
- of_node_put(port);
315
-err_put_encoder:
316
- of_node_put(np_encoder);
317
-
318
- return connector;
319
-}
320
-
321
-void rockchip_free_loader_memory(struct drm_device *drm)
322
-{
323
- struct rockchip_drm_private *private = drm->dev_private;
324
- struct rockchip_logo *logo;
325
- void *start, *end;
326
-
327
- if (!private || !private->logo || --private->logo->count)
328
- return;
329
-
330
- logo = private->logo;
331
- start = phys_to_virt(logo->dma_addr);
332
- end = phys_to_virt(logo->dma_addr + logo->size);
333
-
334
- if (private->domain) {
335
- u32 pg_size = 1UL << __ffs(private->domain->pgsize_bitmap);
336
-
337
- iommu_unmap(private->domain, logo->dma_addr, ALIGN(logo->size, pg_size));
338
- }
339
-
340
- memblock_free(logo->start, logo->size);
341
- free_reserved_area(start, end, -1, "drm_logo");
342
- kfree(logo);
343
- private->logo = NULL;
344
- private->loader_protect = false;
345
-}
346
-
347
-static int init_loader_memory(struct drm_device *drm_dev)
348
-{
349
- struct rockchip_drm_private *private = drm_dev->dev_private;
350
- struct rockchip_logo *logo;
351
- struct device_node *np = drm_dev->dev->of_node;
352
- struct device_node *node;
353
- phys_addr_t start, size;
354
- u32 pg_size = PAGE_SIZE;
355
- struct resource res;
356
- int ret, idx;
357
-
358
- idx = of_property_match_string(np, "memory-region-names", "drm-logo");
359
- if (idx >= 0)
360
- node = of_parse_phandle(np, "memory-region", idx);
361
- else
362
- node = of_parse_phandle(np, "logo-memory-region", 0);
363
- if (!node)
364
- return -ENOMEM;
365
-
366
- ret = of_address_to_resource(node, 0, &res);
367
- if (ret)
368
- return ret;
369
- if (private->domain)
370
- pg_size = 1UL << __ffs(private->domain->pgsize_bitmap);
371
- start = ALIGN_DOWN(res.start, pg_size);
372
- size = resource_size(&res);
373
- if (!size)
374
- return -ENOMEM;
375
-
376
- logo = kmalloc(sizeof(*logo), GFP_KERNEL);
377
- if (!logo)
378
- return -ENOMEM;
379
-
380
- logo->kvaddr = phys_to_virt(start);
381
-
382
- if (private->domain) {
383
- ret = iommu_map(private->domain, start, start, ALIGN(size, pg_size),
384
- IOMMU_WRITE | IOMMU_READ);
385
- if (ret) {
386
- dev_err(drm_dev->dev, "failed to create 1v1 mapping\n");
387
- goto err_free_logo;
388
- }
389
- }
390
-
391
- logo->dma_addr = start;
392
- logo->size = size;
393
- logo->count = 1;
394
- private->logo = logo;
395
-
396
- idx = of_property_match_string(np, "memory-region-names", "drm-cubic-lut");
397
- if (idx < 0)
398
- return 0;
399
-
400
- node = of_parse_phandle(np, "memory-region", idx);
401
- if (!node)
402
- return -ENOMEM;
403
-
404
- ret = of_address_to_resource(node, 0, &res);
405
- if (ret)
406
- return ret;
407
- start = ALIGN_DOWN(res.start, pg_size);
408
- size = resource_size(&res);
409
- if (!size)
410
- return 0;
411
-
412
- private->cubic_lut_kvaddr = phys_to_virt(start);
413
- if (private->domain) {
414
- ret = iommu_map(private->domain, start, start, ALIGN(size, pg_size),
415
- IOMMU_WRITE | IOMMU_READ);
416
- if (ret) {
417
- dev_err(drm_dev->dev, "failed to create 1v1 mapping for cubic lut\n");
418
- goto err_free_logo;
419
- }
420
- }
421
- private->cubic_lut_dma_addr = start;
678
+ if (edid_ext[3] & EDID_CEA_YCRCB422)
679
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
422680
423681 return 0;
424
-
425
-err_free_logo:
426
- kfree(logo);
427
-
428
- return ret;
429682 }
683
+EXPORT_SYMBOL(rockchip_drm_get_yuv422_format);
430684
431
-static struct drm_framebuffer *
432
-get_framebuffer_by_node(struct drm_device *drm_dev, struct device_node *node)
685
+static
686
+void get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 *max_rate_per_lane)
433687 {
434
- struct rockchip_drm_private *private = drm_dev->dev_private;
435
- struct drm_mode_fb_cmd2 mode_cmd = { 0 };
436
- u32 val;
437
- int bpp;
438
-
439
- if (WARN_ON(!private->logo))
440
- return NULL;
441
-
442
- if (of_property_read_u32(node, "logo,offset", &val)) {
443
- pr_err("%s: failed to get logo,offset\n", __func__);
444
- return NULL;
445
- }
446
- mode_cmd.offsets[0] = val;
447
-
448
- if (of_property_read_u32(node, "logo,width", &val)) {
449
- pr_err("%s: failed to get logo,width\n", __func__);
450
- return NULL;
451
- }
452
- mode_cmd.width = val;
453
-
454
- if (of_property_read_u32(node, "logo,height", &val)) {
455
- pr_err("%s: failed to get logo,height\n", __func__);
456
- return NULL;
457
- }
458
- mode_cmd.height = val;
459
-
460
- if (of_property_read_u32(node, "logo,bpp", &val)) {
461
- pr_err("%s: failed to get logo,bpp\n", __func__);
462
- return NULL;
463
- }
464
- bpp = val;
465
-
466
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width * bpp, 32) / 8;
467
-
468
- switch (bpp) {
469
- case 16:
470
- mode_cmd.pixel_format = DRM_FORMAT_RGB565;
688
+ switch (max_frl_rate) {
689
+ case 1:
690
+ *max_lanes = 3;
691
+ *max_rate_per_lane = 3;
471692 break;
472
- case 24:
473
- mode_cmd.pixel_format = DRM_FORMAT_RGB888;
693
+ case 2:
694
+ *max_lanes = 3;
695
+ *max_rate_per_lane = 6;
474696 break;
475
- case 32:
476
- mode_cmd.pixel_format = DRM_FORMAT_XRGB8888;
697
+ case 3:
698
+ *max_lanes = 4;
699
+ *max_rate_per_lane = 6;
477700 break;
701
+ case 4:
702
+ *max_lanes = 4;
703
+ *max_rate_per_lane = 8;
704
+ break;
705
+ case 5:
706
+ *max_lanes = 4;
707
+ *max_rate_per_lane = 10;
708
+ break;
709
+ case 6:
710
+ *max_lanes = 4;
711
+ *max_rate_per_lane = 12;
712
+ break;
713
+ case 0:
478714 default:
479
- pr_err("%s: unsupported to logo bpp %d\n", __func__, bpp);
480
- return NULL;
715
+ *max_lanes = 0;
716
+ *max_rate_per_lane = 0;
481717 }
482
-
483
- return rockchip_fb_alloc(drm_dev, &mode_cmd, NULL, private->logo, 1);
484718 }
485719
486
-static struct rockchip_drm_mode_set *
487
-of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route)
720
+#define EDID_DSC_10BPC (1 << 0)
721
+#define EDID_DSC_12BPC (1 << 1)
722
+#define EDID_DSC_16BPC (1 << 2)
723
+#define EDID_DSC_ALL_BPP (1 << 3)
724
+#define EDID_DSC_NATIVE_420 (1 << 6)
725
+#define EDID_DSC_1P2 (1 << 7)
726
+#define EDID_DSC_MAX_FRL_RATE_MASK 0xf0
727
+#define EDID_DSC_MAX_SLICES 0xf
728
+#define EDID_DSC_TOTAL_CHUNK_KBYTES 0x3f
729
+#define EDID_MAX_FRL_RATE_MASK 0xf0
730
+
731
+static
732
+void parse_edid_forum_vsdb(struct rockchip_drm_dsc_cap *dsc_cap,
733
+ u8 *max_frl_rate_per_lane, u8 *max_lanes, u8 *add_func,
734
+ const u8 *hf_vsdb)
488735 {
489
- struct rockchip_drm_private *private = drm_dev->dev_private;
490
- struct rockchip_drm_mode_set *set;
491
- struct device_node *connect;
492
- struct drm_framebuffer *fb;
493
- struct drm_connector *connector;
494
- struct drm_crtc *crtc;
495
- const char *string;
496
- u32 val;
736
+ u8 max_frl_rate;
737
+ u8 dsc_max_frl_rate;
738
+ u8 dsc_max_slices;
497739
498
- connect = of_parse_phandle(route, "connect", 0);
499
- if (!connect)
500
- return NULL;
501
-
502
- fb = get_framebuffer_by_node(drm_dev, route);
503
- if (IS_ERR_OR_NULL(fb))
504
- return NULL;
505
-
506
- crtc = find_crtc_by_node(drm_dev, connect);
507
- connector = find_connector_by_node(drm_dev, connect);
508
- if (!connector)
509
- connector = find_connector_by_bridge(drm_dev, connect);
510
- if (!crtc || !connector) {
511
- dev_warn(drm_dev->dev,
512
- "No available crtc or connector for display");
513
- drm_framebuffer_put(fb);
514
- return NULL;
515
- }
516
-
517
- set = kzalloc(sizeof(*set), GFP_KERNEL);
518
- if (!set)
519
- return NULL;
520
-
521
- if (!of_property_read_u32(route, "video,clock", &val))
522
- set->clock = val;
523
-
524
- if (!of_property_read_u32(route, "video,hdisplay", &val))
525
- set->hdisplay = val;
526
-
527
- if (!of_property_read_u32(route, "video,vdisplay", &val))
528
- set->vdisplay = val;
529
-
530
- if (!of_property_read_u32(route, "video,crtc_hsync_end", &val))
531
- set->crtc_hsync_end = val;
532
-
533
- if (!of_property_read_u32(route, "video,crtc_vsync_end", &val))
534
- set->crtc_vsync_end = val;
535
-
536
- if (!of_property_read_u32(route, "video,vrefresh", &val))
537
- set->vrefresh = val;
538
-
539
- if (!of_property_read_u32(route, "video,flags", &val))
540
- set->flags = val;
541
-
542
- if (!of_property_read_u32(route, "video,aspect_ratio", &val))
543
- set->picture_aspect_ratio = val;
544
-
545
- if (!of_property_read_u32(route, "overscan,left_margin", &val))
546
- set->left_margin = val;
547
-
548
- if (!of_property_read_u32(route, "overscan,right_margin", &val))
549
- set->right_margin = val;
550
-
551
- if (!of_property_read_u32(route, "overscan,top_margin", &val))
552
- set->top_margin = val;
553
-
554
- if (!of_property_read_u32(route, "overscan,bottom_margin", &val))
555
- set->bottom_margin = val;
556
-
557
- if (!of_property_read_u32(route, "bcsh,brightness", &val))
558
- set->brightness = val;
559
- else
560
- set->brightness = 50;
561
-
562
- if (!of_property_read_u32(route, "bcsh,contrast", &val))
563
- set->contrast = val;
564
- else
565
- set->contrast = 50;
566
-
567
- if (!of_property_read_u32(route, "bcsh,saturation", &val))
568
- set->saturation = val;
569
- else
570
- set->saturation = 50;
571
-
572
- if (!of_property_read_u32(route, "bcsh,hue", &val))
573
- set->hue = val;
574
- else
575
- set->hue = 50;
576
-
577
- set->force_output = of_property_read_bool(route, "force-output");
578
-
579
- if (!of_property_read_u32(route, "cubic_lut,offset", &val)) {
580
- private->cubic_lut[crtc->index].enable = true;
581
- private->cubic_lut[crtc->index].offset = val;
582
- }
583
-
584
- set->ratio = 1;
585
- if (!of_property_read_string(route, "logo,mode", &string) &&
586
- !strcmp(string, "fullscreen"))
587
- set->ratio = 0;
588
-
589
- set->fb = fb;
590
- set->crtc = crtc;
591
- set->connector = connector;
592
-
593
- return set;
594
-}
595
-
596
-static int rockchip_drm_fill_connector_modes(struct drm_connector *connector,
597
- uint32_t maxX, uint32_t maxY,
598
- bool force_output)
599
-{
600
- struct drm_device *dev = connector->dev;
601
- struct drm_display_mode *mode;
602
- const struct drm_connector_helper_funcs *connector_funcs =
603
- connector->helper_private;
604
- int count = 0;
605
- bool verbose_prune = true;
606
- enum drm_connector_status old_status;
607
-
608
- WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
609
-
610
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
611
- connector->name);
612
- /* set all modes to the unverified state */
613
- list_for_each_entry(mode, &connector->modes, head)
614
- mode->status = MODE_STALE;
615
-
616
- if (force_output)
617
- connector->force = DRM_FORCE_ON;
618
- if (connector->force) {
619
- if (connector->force == DRM_FORCE_ON ||
620
- connector->force == DRM_FORCE_ON_DIGITAL)
621
- connector->status = connector_status_connected;
622
- else
623
- connector->status = connector_status_disconnected;
624
- if (connector->funcs->force)
625
- connector->funcs->force(connector);
626
- } else {
627
- old_status = connector->status;
628
-
629
- if (connector->funcs->detect)
630
- connector->status = connector->funcs->detect(connector, true);
631
- else
632
- connector->status = connector_status_connected;
633
- /*
634
- * Normally either the driver's hpd code or the poll loop should
635
- * pick up any changes and fire the hotplug event. But if
636
- * userspace sneaks in a probe, we might miss a change. Hence
637
- * check here, and if anything changed start the hotplug code.
638
- */
639
- if (old_status != connector->status) {
640
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
641
- connector->base.id,
642
- connector->name,
643
- old_status, connector->status);
644
-
645
- /*
646
- * The hotplug event code might call into the fb
647
- * helpers, and so expects that we do not hold any
648
- * locks. Fire up the poll struct instead, it will
649
- * disable itself again.
650
- */
651
- dev->mode_config.delayed_event = true;
652
- if (dev->mode_config.poll_enabled)
653
- schedule_delayed_work(&dev->mode_config.output_poll_work,
654
- 0);
655
- }
656
- }
657
-
658
- /* Re-enable polling in case the global poll config changed. */
659
- if (!dev->mode_config.poll_running)
660
- drm_kms_helper_poll_enable(dev);
661
-
662
- dev->mode_config.poll_running = true;
663
-
664
- if (connector->status == connector_status_disconnected) {
665
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
666
- connector->base.id, connector->name);
667
- drm_connector_update_edid_property(connector, NULL);
668
- verbose_prune = false;
669
- goto prune;
670
- }
671
-
672
- count = (*connector_funcs->get_modes)(connector);
673
-
674
- if (count == 0 && connector->status == connector_status_connected)
675
- count = drm_add_modes_noedid(connector, 1024, 768);
676
- if (force_output)
677
- count += rockchip_drm_add_modes_noedid(connector);
678
- if (count == 0)
679
- goto prune;
680
-
681
- drm_connector_list_update(connector);
682
-
683
- list_for_each_entry(mode, &connector->modes, head) {
684
- if (mode->status == MODE_OK)
685
- mode->status = drm_mode_validate_driver(dev, mode);
686
-
687
- if (mode->status == MODE_OK)
688
- mode->status = drm_mode_validate_size(mode, maxX, maxY);
689
-
690
- /**
691
- * if (mode->status == MODE_OK)
692
- * mode->status = drm_mode_validate_flag(mode, mode_flags);
693
- */
694
- if (mode->status == MODE_OK && connector_funcs->mode_valid)
695
- mode->status = connector_funcs->mode_valid(connector,
696
- mode);
697
- if (mode->status == MODE_OK)
698
- mode->status = drm_mode_validate_ycbcr420(mode,
699
- connector);
700
- }
701
-
702
-prune:
703
- drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
704
-
705
- if (list_empty(&connector->modes))
706
- return 0;
707
-
708
- list_for_each_entry(mode, &connector->modes, head)
709
- mode->vrefresh = drm_mode_vrefresh(mode);
710
-
711
- drm_mode_sort(&connector->modes);
712
-
713
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
714
- connector->name);
715
- list_for_each_entry(mode, &connector->modes, head) {
716
- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
717
- drm_mode_debug_printmodeline(mode);
718
- }
719
-
720
- return count;
721
-}
722
-
723
-static int setup_initial_state(struct drm_device *drm_dev,
724
- struct drm_atomic_state *state,
725
- struct rockchip_drm_mode_set *set)
726
-{
727
- struct rockchip_drm_private *priv = drm_dev->dev_private;
728
- struct drm_connector *connector = set->connector;
729
- struct drm_crtc *crtc = set->crtc;
730
- struct drm_crtc_state *crtc_state;
731
- struct drm_connector_state *conn_state;
732
- struct drm_plane_state *primary_state;
733
- struct drm_display_mode *mode = NULL;
734
- const struct drm_connector_helper_funcs *funcs;
735
- const struct drm_encoder_helper_funcs *encoder_funcs;
736
- int pipe = drm_crtc_index(crtc);
737
- bool is_crtc_enabled = true;
738
- int hdisplay, vdisplay;
739
- int fb_width, fb_height;
740
- int found = 0, match = 0;
741
- int num_modes;
742
- int ret = 0;
743
- struct rockchip_crtc_state *s = NULL;
744
-
745
- if (!set->hdisplay || !set->vdisplay || !set->vrefresh)
746
- is_crtc_enabled = false;
747
-
748
- conn_state = drm_atomic_get_connector_state(state, connector);
749
- if (IS_ERR(conn_state))
750
- return PTR_ERR(conn_state);
751
-
752
- funcs = connector->helper_private;
753
-
754
- if (funcs->best_encoder)
755
- conn_state->best_encoder = funcs->best_encoder(connector);
756
- else
757
- conn_state->best_encoder = drm_atomic_helper_best_encoder(connector);
758
-
759
- if (funcs->loader_protect)
760
- funcs->loader_protect(connector, true);
761
- connector->loader_protect = true;
762
- encoder_funcs = conn_state->best_encoder->helper_private;
763
- if (encoder_funcs->loader_protect)
764
- encoder_funcs->loader_protect(conn_state->best_encoder, true);
765
- conn_state->best_encoder->loader_protect = true;
766
- num_modes = rockchip_drm_fill_connector_modes(connector, 4096, 4096, set->force_output);
767
- if (!num_modes) {
768
- dev_err(drm_dev->dev, "connector[%s] can't found any modes\n",
769
- connector->name);
770
- ret = -EINVAL;
771
- goto error_conn;
772
- }
773
-
774
- list_for_each_entry(mode, &connector->modes, head) {
775
- if (mode->clock == set->clock &&
776
- mode->hdisplay == set->hdisplay &&
777
- mode->vdisplay == set->vdisplay &&
778
- mode->crtc_hsync_end == set->crtc_hsync_end &&
779
- mode->crtc_vsync_end == set->crtc_vsync_end &&
780
- drm_mode_vrefresh(mode) == set->vrefresh &&
781
- /* we just need to focus on DRM_MODE_FLAG_ALL flag, so here
782
- * we compare mode->flags with set->flags & DRM_MODE_FLAG_ALL.
783
- */
784
- mode->flags == (set->flags & DRM_MODE_FLAG_ALL) &&
785
- mode->picture_aspect_ratio == set->picture_aspect_ratio) {
786
- found = 1;
787
- match = 1;
788
- break;
789
- }
790
- }
791
-
792
- if (!found) {
793
- ret = -EINVAL;
794
- connector->status = connector_status_disconnected;
795
- goto error_conn;
796
- }
797
-
798
- conn_state->tv.brightness = set->brightness;
799
- conn_state->tv.contrast = set->contrast;
800
- conn_state->tv.saturation = set->saturation;
801
- conn_state->tv.hue = set->hue;
802
- set->mode = mode;
803
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
804
- if (IS_ERR(crtc_state)) {
805
- ret = PTR_ERR(crtc_state);
806
- goto error_conn;
807
- }
808
-
809
- drm_mode_copy(&crtc_state->adjusted_mode, mode);
810
- if (!match || !is_crtc_enabled) {
811
- set->mode_changed = true;
812
- } else {
813
- ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
814
- if (ret)
815
- goto error_conn;
816
-
817
- mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
818
- ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
819
- if (ret)
820
- goto error_conn;
821
-
822
- crtc_state->active = true;
823
-
824
- if (priv->crtc_funcs[pipe] &&
825
- priv->crtc_funcs[pipe]->loader_protect)
826
- priv->crtc_funcs[pipe]->loader_protect(crtc, true);
827
- }
828
-
829
- if (!set->fb) {
830
- ret = 0;
831
- goto error_crtc;
832
- }
833
- primary_state = drm_atomic_get_plane_state(state, crtc->primary);
834
- if (IS_ERR(primary_state)) {
835
- ret = PTR_ERR(primary_state);
836
- goto error_crtc;
837
- }
838
-
839
- hdisplay = mode->hdisplay;
840
- vdisplay = mode->vdisplay;
841
- fb_width = set->fb->width;
842
- fb_height = set->fb->height;
843
-
844
- primary_state->crtc = crtc;
845
- primary_state->src_x = 0;
846
- primary_state->src_y = 0;
847
- primary_state->src_w = fb_width << 16;
848
- primary_state->src_h = fb_height << 16;
849
- if (set->ratio) {
850
- if (set->fb->width >= hdisplay) {
851
- primary_state->crtc_x = 0;
852
- primary_state->crtc_w = hdisplay;
853
- } else {
854
- primary_state->crtc_x = (hdisplay - fb_width) / 2;
855
- primary_state->crtc_w = set->fb->width;
856
- }
857
-
858
- if (set->fb->height >= vdisplay) {
859
- primary_state->crtc_y = 0;
860
- primary_state->crtc_h = vdisplay;
861
- } else {
862
- primary_state->crtc_y = (vdisplay - fb_height) / 2;
863
- primary_state->crtc_h = fb_height;
864
- }
865
- } else {
866
- primary_state->crtc_x = 0;
867
- primary_state->crtc_y = 0;
868
- primary_state->crtc_w = hdisplay;
869
- primary_state->crtc_h = vdisplay;
870
- }
871
- s = to_rockchip_crtc_state(crtc->state);
872
- s->output_type = connector->connector_type;
873
-
874
- return 0;
875
-
876
-error_crtc:
877
- if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect)
878
- priv->crtc_funcs[pipe]->loader_protect(crtc, false);
879
-error_conn:
880
- if (funcs->loader_protect)
881
- funcs->loader_protect(connector, false);
882
- connector->loader_protect = false;
883
- if (encoder_funcs->loader_protect)
884
- encoder_funcs->loader_protect(conn_state->best_encoder, false);
885
- conn_state->best_encoder->loader_protect = false;
886
-
887
- return ret;
888
-}
889
-
890
-static int update_state(struct drm_device *drm_dev,
891
- struct drm_atomic_state *state,
892
- struct rockchip_drm_mode_set *set,
893
- unsigned int *plane_mask)
894
-{
895
- struct drm_crtc *crtc = set->crtc;
896
- struct drm_connector *connector = set->connector;
897
- struct drm_display_mode *mode = set->mode;
898
- struct drm_plane_state *primary_state;
899
- struct drm_crtc_state *crtc_state;
900
- struct drm_connector_state *conn_state;
901
- int ret;
902
- struct rockchip_crtc_state *s;
903
-
904
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
905
- if (IS_ERR(crtc_state))
906
- return PTR_ERR(crtc_state);
907
- conn_state = drm_atomic_get_connector_state(state, connector);
908
- if (IS_ERR(conn_state))
909
- return PTR_ERR(conn_state);
910
- s = to_rockchip_crtc_state(crtc_state);
911
- s->left_margin = set->left_margin;
912
- s->right_margin = set->right_margin;
913
- s->top_margin = set->top_margin;
914
- s->bottom_margin = set->bottom_margin;
915
-
916
- if (set->mode_changed) {
917
- ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
918
- if (ret)
919
- return ret;
920
-
921
- ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
922
- if (ret)
923
- return ret;
924
-
925
- crtc_state->active = true;
926
- } else {
927
- const struct drm_encoder_helper_funcs *encoder_helper_funcs;
928
- const struct drm_connector_helper_funcs *connector_helper_funcs;
929
- struct drm_encoder *encoder;
930
-
931
- connector_helper_funcs = connector->helper_private;
932
- if (!connector_helper_funcs)
933
- return -ENXIO;
934
- if (connector_helper_funcs->best_encoder)
935
- encoder = connector_helper_funcs->best_encoder(connector);
936
- else
937
- encoder = drm_atomic_helper_best_encoder(connector);
938
- if (!encoder)
939
- return -ENXIO;
940
- encoder_helper_funcs = encoder->helper_private;
941
- if (!encoder_helper_funcs->atomic_check)
942
- return -ENXIO;
943
- ret = encoder_helper_funcs->atomic_check(encoder, crtc->state,
944
- conn_state);
945
- if (ret)
946
- return ret;
947
-
948
- if (encoder_helper_funcs->atomic_mode_set)
949
- encoder_helper_funcs->atomic_mode_set(encoder,
950
- crtc_state,
951
- conn_state);
952
- else if (encoder_helper_funcs->mode_set)
953
- encoder_helper_funcs->mode_set(encoder, mode, mode);
954
- }
955
-
956
- primary_state = drm_atomic_get_plane_state(state, crtc->primary);
957
- if (IS_ERR(primary_state))
958
- return PTR_ERR(primary_state);
959
-
960
- crtc_state->plane_mask = 1 << drm_plane_index(crtc->primary);
961
- *plane_mask |= crtc_state->plane_mask;
962
-
963
- drm_atomic_set_fb_for_plane(primary_state, set->fb);
964
- drm_framebuffer_put(set->fb);
965
- ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
966
-
967
- return ret;
968
-}
969
-
970
-static void show_loader_logo(struct drm_device *drm_dev)
971
-{
972
- struct drm_atomic_state *state, *old_state;
973
- struct device_node *np = drm_dev->dev->of_node;
974
- struct drm_mode_config *mode_config = &drm_dev->mode_config;
975
- struct rockchip_drm_private *private = drm_dev->dev_private;
976
- struct device_node *root, *route;
977
- struct rockchip_drm_mode_set *set, *tmp, *unset;
978
- struct list_head mode_set_list;
979
- struct list_head mode_unset_list;
980
- unsigned int plane_mask = 0;
981
- int ret, i;
982
-
983
- root = of_get_child_by_name(np, "route");
984
- if (!root) {
985
- dev_warn(drm_dev->dev, "failed to parse display resources\n");
740
+ if (!hf_vsdb[7])
986741 return;
987
- }
988742
989
- if (init_loader_memory(drm_dev)) {
990
- dev_warn(drm_dev->dev, "failed to parse loader memory\n");
743
+ DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
744
+ max_frl_rate = (hf_vsdb[7] & EDID_MAX_FRL_RATE_MASK) >> 4;
745
+ get_max_frl_rate(max_frl_rate, max_lanes,
746
+ max_frl_rate_per_lane);
747
+
748
+ *add_func = hf_vsdb[8];
749
+
750
+ if (cea_db_payload_len(hf_vsdb) < 13)
991751 return;
752
+
753
+ dsc_cap->v_1p2 = hf_vsdb[11] & EDID_DSC_1P2;
754
+
755
+ if (!dsc_cap->v_1p2)
756
+ return;
757
+
758
+ dsc_cap->native_420 = hf_vsdb[11] & EDID_DSC_NATIVE_420;
759
+ dsc_cap->all_bpp = hf_vsdb[11] & EDID_DSC_ALL_BPP;
760
+
761
+ if (hf_vsdb[11] & EDID_DSC_16BPC)
762
+ dsc_cap->bpc_supported = 16;
763
+ else if (hf_vsdb[11] & EDID_DSC_12BPC)
764
+ dsc_cap->bpc_supported = 12;
765
+ else if (hf_vsdb[11] & EDID_DSC_10BPC)
766
+ dsc_cap->bpc_supported = 10;
767
+ else
768
+ dsc_cap->bpc_supported = 0;
769
+
770
+ dsc_max_frl_rate = (hf_vsdb[12] & EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
771
+ get_max_frl_rate(dsc_max_frl_rate, &dsc_cap->max_lanes,
772
+ &dsc_cap->max_frl_rate_per_lane);
773
+ dsc_cap->total_chunk_kbytes = hf_vsdb[13] & EDID_DSC_TOTAL_CHUNK_KBYTES;
774
+
775
+ dsc_max_slices = hf_vsdb[12] & EDID_DSC_MAX_SLICES;
776
+ switch (dsc_max_slices) {
777
+ case 1:
778
+ dsc_cap->max_slices = 1;
779
+ dsc_cap->clk_per_slice = 340;
780
+ break;
781
+ case 2:
782
+ dsc_cap->max_slices = 2;
783
+ dsc_cap->clk_per_slice = 340;
784
+ break;
785
+ case 3:
786
+ dsc_cap->max_slices = 4;
787
+ dsc_cap->clk_per_slice = 340;
788
+ break;
789
+ case 4:
790
+ dsc_cap->max_slices = 8;
791
+ dsc_cap->clk_per_slice = 340;
792
+ break;
793
+ case 5:
794
+ dsc_cap->max_slices = 8;
795
+ dsc_cap->clk_per_slice = 400;
796
+ break;
797
+ case 6:
798
+ dsc_cap->max_slices = 12;
799
+ dsc_cap->clk_per_slice = 400;
800
+ break;
801
+ case 7:
802
+ dsc_cap->max_slices = 16;
803
+ dsc_cap->clk_per_slice = 400;
804
+ break;
805
+ case 0:
806
+ default:
807
+ dsc_cap->max_slices = 0;
808
+ dsc_cap->clk_per_slice = 0;
992809 }
993
-
994
- INIT_LIST_HEAD(&mode_set_list);
995
- INIT_LIST_HEAD(&mode_unset_list);
996
- drm_modeset_lock_all(drm_dev);
997
- state = drm_atomic_state_alloc(drm_dev);
998
- if (!state) {
999
- dev_err(drm_dev->dev, "failed to alloc atomic state\n");
1000
- ret = -ENOMEM;
1001
- goto err_unlock;
1002
- }
1003
-
1004
- state->acquire_ctx = mode_config->acquire_ctx;
1005
-
1006
- for_each_child_of_node(root, route) {
1007
- if (!of_device_is_available(route))
1008
- continue;
1009
-
1010
- set = of_parse_display_resource(drm_dev, route);
1011
- if (!set)
1012
- continue;
1013
-
1014
- if (setup_initial_state(drm_dev, state, set)) {
1015
- drm_framebuffer_put(set->fb);
1016
- INIT_LIST_HEAD(&set->head);
1017
- list_add_tail(&set->head, &mode_unset_list);
1018
- continue;
1019
- }
1020
- INIT_LIST_HEAD(&set->head);
1021
- list_add_tail(&set->head, &mode_set_list);
1022
- }
1023
-
1024
- /*
1025
- * the mode_unset_list store the unconnected route, if route's crtc
1026
- * isn't used, we should close it.
1027
- */
1028
- list_for_each_entry_safe(unset, tmp, &mode_unset_list, head) {
1029
- struct rockchip_drm_mode_set *tmp_set;
1030
- int find_used_crtc = 0;
1031
-
1032
- list_for_each_entry_safe(set, tmp_set, &mode_set_list, head) {
1033
- if (set->crtc == unset->crtc) {
1034
- find_used_crtc = 1;
1035
- continue;
1036
- }
1037
- }
1038
-
1039
- if (!find_used_crtc) {
1040
- struct drm_crtc *crtc = unset->crtc;
1041
- int pipe = drm_crtc_index(crtc);
1042
- struct rockchip_drm_private *priv =
1043
- drm_dev->dev_private;
1044
-
1045
- if (unset->hdisplay && unset->vdisplay) {
1046
- if (priv->crtc_funcs[pipe] &&
1047
- priv->crtc_funcs[pipe]->loader_protect)
1048
- priv->crtc_funcs[pipe]->loader_protect(crtc, true);
1049
- priv->crtc_funcs[pipe]->crtc_close(crtc);
1050
- if (priv->crtc_funcs[pipe] &&
1051
- priv->crtc_funcs[pipe]->loader_protect)
1052
- priv->crtc_funcs[pipe]->loader_protect(crtc, false);
1053
- }
1054
- }
1055
-
1056
- list_del(&unset->head);
1057
- kfree(unset);
1058
- }
1059
-
1060
- if (list_empty(&mode_set_list)) {
1061
- dev_warn(drm_dev->dev, "can't not find any loader display\n");
1062
- ret = -ENXIO;
1063
- goto err_free_state;
1064
- }
1065
-
1066
- /*
1067
- * The state save initial devices status, swap the state into
1068
- * drm devices as old state, so if new state come, can compare
1069
- * with this state to judge which status need to update.
1070
- */
1071
- WARN_ON(drm_atomic_helper_swap_state(state, false));
1072
- drm_atomic_state_put(state);
1073
- old_state = drm_atomic_helper_duplicate_state(drm_dev,
1074
- mode_config->acquire_ctx);
1075
- if (IS_ERR(old_state)) {
1076
- dev_err(drm_dev->dev, "failed to duplicate atomic state\n");
1077
- ret = PTR_ERR_OR_ZERO(old_state);
1078
- goto err_free_state;
1079
- }
1080
-
1081
- state = drm_atomic_helper_duplicate_state(drm_dev,
1082
- mode_config->acquire_ctx);
1083
- if (IS_ERR(state)) {
1084
- dev_err(drm_dev->dev, "failed to duplicate atomic state\n");
1085
- ret = PTR_ERR_OR_ZERO(state);
1086
- goto err_free_old_state;
1087
- }
1088
- state->acquire_ctx = mode_config->acquire_ctx;
1089
- list_for_each_entry(set, &mode_set_list, head)
1090
- /*
1091
- * We don't want to see any fail on update_state.
1092
- */
1093
- WARN_ON(update_state(drm_dev, state, set, &plane_mask));
1094
-
1095
- for (i = 0; i < state->num_connector; i++) {
1096
- if (state->connectors[i].new_state->connector->status !=
1097
- connector_status_connected)
1098
- state->connectors[i].new_state->best_encoder = NULL;
1099
- }
1100
-
1101
- ret = drm_atomic_commit(state);
1102
- /**
1103
- * todo
1104
- * drm_atomic_clean_old_fb(drm_dev, plane_mask, ret);
1105
- */
1106
-
1107
- list_for_each_entry_safe(set, tmp, &mode_set_list, head) {
1108
- if (set->force_output)
1109
- set->connector->force = DRM_FORCE_UNSPECIFIED;
1110
- list_del(&set->head);
1111
- kfree(set);
1112
- }
1113
-
1114
- /*
1115
- * Is possible get deadlock here?
1116
- */
1117
- WARN_ON(ret == -EDEADLK);
1118
-
1119
- if (ret) {
1120
- /*
1121
- * restore display status if atomic commit failed.
1122
- */
1123
- WARN_ON(drm_atomic_helper_swap_state(old_state, false));
1124
- goto err_free_state;
1125
- }
1126
-
1127
- rockchip_free_loader_memory(drm_dev);
1128
- drm_atomic_state_put(old_state);
1129
- drm_atomic_state_put(state);
1130
-
1131
- private->loader_protect = true;
1132
- drm_modeset_unlock_all(drm_dev);
1133
- return;
1134
-err_free_old_state:
1135
- drm_atomic_state_put(old_state);
1136
-err_free_state:
1137
- drm_atomic_state_put(state);
1138
-err_unlock:
1139
- drm_modeset_unlock_all(drm_dev);
1140
- if (ret)
1141
- dev_err(drm_dev->dev, "failed to show loader logo\n");
1142810 }
1143811
1144
-static const char *const loader_protect_clocks[] __initconst = {
1145
- "hclk_vio",
1146
- "hclk_vop",
1147
- "hclk_vopb",
1148
- "hclk_vopl",
1149
- "aclk_vio",
1150
- "aclk_vio0",
1151
- "aclk_vio1",
1152
- "aclk_vop",
1153
- "aclk_vopb",
1154
- "aclk_vopl",
1155
- "aclk_vo_pre",
1156
- "aclk_vio_pre",
1157
- "dclk_vop",
1158
- "dclk_vop0",
1159
- "dclk_vop1",
1160
- "dclk_vopb",
1161
- "dclk_vopl",
812
+enum {
813
+ VER_26_BYTE_V0,
814
+ VER_15_BYTE_V1,
815
+ VER_12_BYTE_V1,
816
+ VER_12_BYTE_V2,
1162817 };
1163818
1164
-static struct clk **loader_clocks __initdata;
1165
-static int __init rockchip_clocks_loader_protect(void)
819
+static int check_next_hdr_version(const u8 *next_hdr_db)
1166820 {
1167
- int nclocks = ARRAY_SIZE(loader_protect_clocks);
1168
- struct clk *clk;
1169
- int i;
821
+ u16 ver;
1170822
1171
- loader_clocks = kcalloc(nclocks, sizeof(void *), GFP_KERNEL);
1172
- if (!loader_clocks)
1173
- return -ENOMEM;
823
+ ver = (next_hdr_db[5] & 0xf0) << 8 | next_hdr_db[0];
1174824
1175
- for (i = 0; i < nclocks; i++) {
1176
- clk = __clk_lookup(loader_protect_clocks[i]);
1177
-
1178
- if (clk) {
1179
- loader_clocks[i] = clk;
1180
- clk_prepare_enable(clk);
1181
- }
825
+ switch (ver) {
826
+ case 0x00f9:
827
+ return VER_26_BYTE_V0;
828
+ case 0x20ee:
829
+ return VER_15_BYTE_V1;
830
+ case 0x20eb:
831
+ return VER_12_BYTE_V1;
832
+ case 0x40eb:
833
+ return VER_12_BYTE_V2;
834
+ default:
835
+ return -ENOENT;
1182836 }
1183
-
1184
- return 0;
1185837 }
1186
-arch_initcall_sync(rockchip_clocks_loader_protect);
1187838
1188
-static int __init rockchip_clocks_loader_unprotect(void)
839
+static void parse_ver_26_v0_data(struct ver_26_v0 *hdr, const u8 *data)
1189840 {
1190
- int i;
841
+ hdr->yuv422_12bit = data[5] & BIT(0);
842
+ hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
843
+ hdr->global_dimming = (data[5] & BIT(2)) >> 2;
1191844
1192
- if (!loader_clocks)
1193
- return -ENODEV;
845
+ hdr->dm_major_ver = (data[21] & 0xf0) >> 4;
846
+ hdr->dm_minor_ver = data[21] & 0xf;
1194847
1195
- for (i = 0; i < ARRAY_SIZE(loader_protect_clocks); i++) {
1196
- struct clk *clk = loader_clocks[i];
848
+ hdr->t_min_pq = (data[19] << 4) | ((data[18] & 0xf0) >> 4);
849
+ hdr->t_max_pq = (data[20] << 4) | (data[18] & 0xf);
1197850
1198
- if (clk)
1199
- clk_disable_unprepare(clk);
851
+ hdr->rx = (data[7] << 4) | ((data[6] & 0xf0) >> 4);
852
+ hdr->ry = (data[8] << 4) | (data[6] & 0xf);
853
+ hdr->gx = (data[10] << 4) | ((data[9] & 0xf0) >> 4);
854
+ hdr->gy = (data[11] << 4) | (data[9] & 0xf);
855
+ hdr->bx = (data[13] << 4) | ((data[12] & 0xf0) >> 4);
856
+ hdr->by = (data[14] << 4) | (data[12] & 0xf);
857
+ hdr->wx = (data[16] << 4) | ((data[15] & 0xf0) >> 4);
858
+ hdr->wy = (data[17] << 4) | (data[15] & 0xf);
859
+}
860
+
861
+static void parse_ver_15_v1_data(struct ver_15_v1 *hdr, const u8 *data)
862
+{
863
+ hdr->yuv422_12bit = data[5] & BIT(0);
864
+ hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
865
+ hdr->global_dimming = data[6] & BIT(0);
866
+
867
+ hdr->dm_version = (data[5] & 0x1c) >> 2;
868
+
869
+ hdr->colorimetry = data[7] & BIT(0);
870
+
871
+ hdr->t_max_lum = (data[6] & 0xfe) >> 1;
872
+ hdr->t_min_lum = (data[7] & 0xfe) >> 1;
873
+
874
+ hdr->rx = data[9];
875
+ hdr->ry = data[10];
876
+ hdr->gx = data[11];
877
+ hdr->gy = data[12];
878
+ hdr->bx = data[13];
879
+ hdr->by = data[14];
880
+}
881
+
882
+static void parse_ver_12_v1_data(struct ver_12_v1 *hdr, const u8 *data)
883
+{
884
+ hdr->yuv422_12bit = data[5] & BIT(0);
885
+ hdr->support_2160p_60 = (data[5] & BIT(1)) >> 1;
886
+ hdr->global_dimming = data[6] & BIT(0);
887
+
888
+ hdr->dm_version = (data[5] & 0x1c) >> 2;
889
+
890
+ hdr->colorimetry = data[7] & BIT(0);
891
+
892
+ hdr->t_max_lum = (data[6] & 0xfe) >> 1;
893
+ hdr->t_min_lum = (data[7] & 0xfe) >> 1;
894
+
895
+ hdr->low_latency = data[8] & 0x3;
896
+
897
+ hdr->unique_rx = (data[11] & 0xf8) >> 3;
898
+ hdr->unique_ry = (data[11] & 0x7) << 2 | (data[10] & BIT(0)) << 1 |
899
+ (data[9] & BIT(0));
900
+ hdr->unique_gx = (data[9] & 0xfe) >> 1;
901
+ hdr->unique_gy = (data[10] & 0xfe) >> 1;
902
+ hdr->unique_bx = (data[8] & 0xe0) >> 5;
903
+ hdr->unique_by = (data[8] & 0x1c) >> 2;
904
+}
905
+
906
+static void parse_ver_12_v2_data(struct ver_12_v2 *hdr, const u8 *data)
907
+{
908
+ hdr->yuv422_12bit = data[5] & BIT(0);
909
+ hdr->backlt_ctrl = (data[5] & BIT(1)) >> 1;
910
+ hdr->global_dimming = (data[6] & BIT(2)) >> 2;
911
+
912
+ hdr->dm_version = (data[5] & 0x1c) >> 2;
913
+ hdr->backlt_min_luma = data[6] & 0x3;
914
+ hdr->interface = data[7] & 0x3;
915
+ hdr->yuv444_10b_12b = (data[8] & BIT(0)) << 1 | (data[9] & BIT(0));
916
+
917
+ hdr->t_min_pq_v2 = (data[6] & 0xf8) >> 3;
918
+ hdr->t_max_pq_v2 = (data[7] & 0xf8) >> 3;
919
+
920
+ hdr->unique_rx = (data[10] & 0xf8) >> 3;
921
+ hdr->unique_ry = (data[11] & 0xf8) >> 3;
922
+ hdr->unique_gx = (data[8] & 0xfe) >> 1;
923
+ hdr->unique_gy = (data[9] & 0xfe) >> 1;
924
+ hdr->unique_bx = data[10] & 0x7;
925
+ hdr->unique_by = data[11] & 0x7;
926
+}
927
+
928
+static
929
+void parse_next_hdr_block(struct next_hdr_sink_data *sink_data,
930
+ const u8 *next_hdr_db)
931
+{
932
+ int version;
933
+
934
+ version = check_next_hdr_version(next_hdr_db);
935
+ if (version < 0)
936
+ return;
937
+
938
+ sink_data->version = version;
939
+
940
+ switch (version) {
941
+ case VER_26_BYTE_V0:
942
+ parse_ver_26_v0_data(&sink_data->ver_26_v0, next_hdr_db);
943
+ break;
944
+ case VER_15_BYTE_V1:
945
+ parse_ver_15_v1_data(&sink_data->ver_15_v1, next_hdr_db);
946
+ break;
947
+ case VER_12_BYTE_V1:
948
+ parse_ver_12_v1_data(&sink_data->ver_12_v1, next_hdr_db);
949
+ break;
950
+ case VER_12_BYTE_V2:
951
+ parse_ver_12_v2_data(&sink_data->ver_12_v2, next_hdr_db);
952
+ break;
953
+ default:
954
+ break;
1200955 }
1201
- kfree(loader_clocks);
1202
-
1203
- return 0;
1204956 }
1205
-late_initcall_sync(rockchip_clocks_loader_unprotect);
1206
-#endif
1207957
1208
-int rockchip_drm_crtc_send_mcu_cmd(struct drm_device *drm_dev,
1209
- struct device_node *np_crtc,
1210
- u32 type, u32 value)
958
+int rockchip_drm_parse_cea_ext(struct rockchip_drm_dsc_cap *dsc_cap,
959
+ u8 *max_frl_rate_per_lane, u8 *max_lanes, u8 *add_func,
960
+ const struct edid *edid)
1211961 {
1212
- struct drm_crtc *crtc;
1213
- int pipe = 0;
1214
- struct rockchip_drm_private *priv;
962
+ const u8 *edid_ext;
963
+ int i, start, end;
1215964
1216
- if (!np_crtc || !of_device_is_available(np_crtc))
965
+ if (!dsc_cap || !max_frl_rate_per_lane || !max_lanes || !edid || !add_func)
1217966 return -EINVAL;
1218967
1219
- drm_for_each_crtc(crtc, drm_dev) {
1220
- if (of_get_parent(crtc->port) == np_crtc)
1221
- break;
1222
- }
1223
-
1224
- pipe = drm_crtc_index(crtc);
1225
- if (pipe >= ROCKCHIP_MAX_CRTC)
968
+ edid_ext = find_cea_extension(edid);
969
+ if (!edid_ext)
1226970 return -EINVAL;
1227
- priv = crtc->dev->dev_private;
1228
- if (priv->crtc_funcs[pipe]->crtc_send_mcu_cmd)
1229
- priv->crtc_funcs[pipe]->crtc_send_mcu_cmd(crtc, type, value);
971
+
972
+ if (cea_db_offsets(edid_ext, &start, &end))
973
+ return -EINVAL;
974
+
975
+ for_each_cea_db(edid_ext, i, start, end) {
976
+ const u8 *db = &edid_ext[i];
977
+
978
+ if (cea_db_is_hdmi_forum_vsdb(db))
979
+ parse_edid_forum_vsdb(dsc_cap, max_frl_rate_per_lane,
980
+ max_lanes, add_func, db);
981
+ }
1230982
1231983 return 0;
1232984 }
1233
-EXPORT_SYMBOL(rockchip_drm_crtc_send_mcu_cmd);
985
+EXPORT_SYMBOL(rockchip_drm_parse_cea_ext);
986
+
987
+int rockchip_drm_parse_next_hdr(struct next_hdr_sink_data *sink_data,
988
+ const struct edid *edid)
989
+{
990
+ const u8 *edid_ext;
991
+ int i, start, end;
992
+
993
+ if (!sink_data || !edid)
994
+ return -EINVAL;
995
+
996
+ memset(sink_data, 0, sizeof(struct next_hdr_sink_data));
997
+
998
+ edid_ext = find_cea_extension(edid);
999
+ if (!edid_ext)
1000
+ return -EINVAL;
1001
+
1002
+ if (cea_db_offsets(edid_ext, &start, &end))
1003
+ return -EINVAL;
1004
+
1005
+ for_each_cea_db(edid_ext, i, start, end) {
1006
+ const u8 *db = &edid_ext[i];
1007
+
1008
+ if (cea_db_is_hdmi_next_hdr_block(db))
1009
+ parse_next_hdr_block(sink_data, db);
1010
+ }
1011
+
1012
+ return 0;
1013
+}
1014
+EXPORT_SYMBOL(rockchip_drm_parse_next_hdr);
1015
+
1016
+#define COLORIMETRY_DATA_BLOCK 0x5
1017
+#define USE_EXTENDED_TAG 0x07
1018
+
1019
+static bool cea_db_is_hdmi_colorimetry_data_block(const u8 *db)
1020
+{
1021
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
1022
+ return false;
1023
+
1024
+ if (db[1] != COLORIMETRY_DATA_BLOCK)
1025
+ return false;
1026
+
1027
+ return true;
1028
+}
1029
+
1030
+int
1031
+rockchip_drm_parse_colorimetry_data_block(u8 *colorimetry, const struct edid *edid)
1032
+{
1033
+ const u8 *edid_ext;
1034
+ int i, start, end;
1035
+
1036
+ if (!colorimetry || !edid)
1037
+ return -EINVAL;
1038
+
1039
+ *colorimetry = 0;
1040
+
1041
+ edid_ext = find_cea_extension(edid);
1042
+ if (!edid_ext)
1043
+ return -EINVAL;
1044
+
1045
+ if (cea_db_offsets(edid_ext, &start, &end))
1046
+ return -EINVAL;
1047
+
1048
+ for_each_cea_db(edid_ext, i, start, end) {
1049
+ const u8 *db = &edid_ext[i];
1050
+
1051
+ if (cea_db_is_hdmi_colorimetry_data_block(db))
1052
+ /* As per CEA 861-G spec */
1053
+ *colorimetry = ((db[3] & (0x1 << 7)) << 1) | db[2];
1054
+ }
1055
+
1056
+ return 0;
1057
+}
1058
+EXPORT_SYMBOL(rockchip_drm_parse_colorimetry_data_block);
12341059
12351060 /*
12361061 * Attach a (component) device to the shared drm dma mapping from master drm
....@@ -1265,6 +1090,17 @@
12651090 return;
12661091
12671092 iommu_detach_device(domain, dev);
1093
+}
1094
+
1095
+void rockchip_drm_crtc_standby(struct drm_crtc *crtc, bool standby)
1096
+{
1097
+ struct rockchip_drm_private *priv = crtc->dev->dev_private;
1098
+ int pipe = drm_crtc_index(crtc);
1099
+
1100
+ if (pipe < ROCKCHIP_MAX_CRTC &&
1101
+ priv->crtc_funcs[pipe] &&
1102
+ priv->crtc_funcs[pipe]->crtc_standby)
1103
+ priv->crtc_funcs[pipe]->crtc_standby(crtc, standby);
12681104 }
12691105
12701106 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
....@@ -1383,16 +1219,12 @@
13831219 struct drm_minor *minor = node->minor;
13841220 struct drm_device *drm_dev = minor->dev;
13851221 struct rockchip_drm_private *priv = drm_dev->dev_private;
1386
-
13871222 struct drm_printer p = drm_seq_file_printer(s);
13881223
13891224 if (!priv->domain)
13901225 return 0;
1391
-
13921226 mutex_lock(&priv->mm_lock);
1393
-
13941227 drm_mm_print(&priv->mm, &p);
1395
-
13961228 mutex_unlock(&priv->mm_lock);
13971229
13981230 return 0;
....@@ -1462,21 +1294,15 @@
14621294 { "mm_dump", rockchip_drm_mm_dump, 0, NULL },
14631295 };
14641296
1465
-static int rockchip_drm_debugfs_init(struct drm_minor *minor)
1297
+static void rockchip_drm_debugfs_init(struct drm_minor *minor)
14661298 {
14671299 struct drm_device *dev = minor->dev;
14681300 struct rockchip_drm_private *priv = dev->dev_private;
14691301 struct drm_crtc *crtc;
1470
- int ret;
14711302
1472
- ret = drm_debugfs_create_files(rockchip_debugfs_files,
1473
- ARRAY_SIZE(rockchip_debugfs_files),
1474
- minor->debugfs_root,
1475
- minor);
1476
- if (ret) {
1477
- dev_err(dev->dev, "could not install rockchip_debugfs_list\n");
1478
- return ret;
1479
- }
1303
+ drm_debugfs_create_files(rockchip_debugfs_files,
1304
+ ARRAY_SIZE(rockchip_debugfs_files),
1305
+ minor->debugfs_root, minor);
14801306
14811307 drm_for_each_crtc(crtc, dev) {
14821308 int pipe = drm_crtc_index(crtc);
....@@ -1485,10 +1311,14 @@
14851311 priv->crtc_funcs[pipe]->debugfs_init)
14861312 priv->crtc_funcs[pipe]->debugfs_init(minor, crtc);
14871313 }
1488
-
1489
- return 0;
14901314 }
14911315 #endif
1316
+
1317
+static const struct drm_prop_enum_list split_area[] = {
1318
+ { ROCKCHIP_DRM_SPLIT_UNSET, "UNSET" },
1319
+ { ROCKCHIP_DRM_SPLIT_LEFT_SIDE, "LEFT" },
1320
+ { ROCKCHIP_DRM_SPLIT_RIGHT_SIDE, "RIGHT" },
1321
+};
14921322
14931323 static int rockchip_drm_create_properties(struct drm_device *dev)
14941324 {
....@@ -1508,24 +1338,6 @@
15081338 private->color_space_prop = prop;
15091339
15101340 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1511
- "GLOBAL_ALPHA", 0, 255);
1512
- if (!prop)
1513
- return -ENOMEM;
1514
- private->global_alpha_prop = prop;
1515
-
1516
- prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1517
- "BLEND_MODE", 0, 1);
1518
- if (!prop)
1519
- return -ENOMEM;
1520
- private->blend_mode_prop = prop;
1521
-
1522
- prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1523
- "ALPHA_SCALE", 0, 1);
1524
- if (!prop)
1525
- return -ENOMEM;
1526
- private->alpha_scale_prop = prop;
1527
-
1528
- prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
15291341 "ASYNC_COMMIT", 0, 1);
15301342 if (!prop)
15311343 return -ENOMEM;
....@@ -1537,53 +1349,35 @@
15371349 return -ENOMEM;
15381350 private->share_id_prop = prop;
15391351
1540
- prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1352
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_IMMUTABLE,
15411353 "CONNECTOR_ID", 0, 0xf);
15421354 if (!prop)
15431355 return -ENOMEM;
15441356 private->connector_id_prop = prop;
15451357
1358
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "SPLIT_AREA",
1359
+ split_area,
1360
+ ARRAY_SIZE(split_area));
1361
+ private->split_area_prop = prop;
1362
+
1363
+ prop = drm_property_create_object(dev,
1364
+ DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_IMMUTABLE,
1365
+ "SOC_ID", DRM_MODE_OBJECT_CRTC);
1366
+ private->soc_id_prop = prop;
1367
+
1368
+ prop = drm_property_create_object(dev,
1369
+ DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_IMMUTABLE,
1370
+ "PORT_ID", DRM_MODE_OBJECT_CRTC);
1371
+ private->port_id_prop = prop;
1372
+
1373
+ private->aclk_prop = drm_property_create_range(dev, 0, "ACLK", 0, UINT_MAX);
1374
+ private->bg_prop = drm_property_create_range(dev, 0, "BACKGROUND", 0, UINT_MAX);
1375
+ private->line_flag_prop = drm_property_create_range(dev, 0, "LINE_FLAG1", 0, UINT_MAX);
1376
+ private->cubic_lut_prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "CUBIC_LUT", 0);
1377
+ private->cubic_lut_size_prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE,
1378
+ "CUBIC_LUT_SIZE", 0, UINT_MAX);
1379
+
15461380 return drm_mode_create_tv_properties(dev, 0, NULL);
1547
-}
1548
-
1549
-static int rockchip_gem_pool_init(struct drm_device *drm)
1550
-{
1551
- struct rockchip_drm_private *private = drm->dev_private;
1552
- struct device_node *np = drm->dev->of_node;
1553
- struct device_node *node;
1554
- phys_addr_t start, size;
1555
- struct resource res;
1556
- int ret;
1557
-
1558
- node = of_parse_phandle(np, "secure-memory-region", 0);
1559
- if (!node)
1560
- return -ENXIO;
1561
-
1562
- ret = of_address_to_resource(node, 0, &res);
1563
- if (ret)
1564
- return ret;
1565
- start = res.start;
1566
- size = resource_size(&res);
1567
- if (!size)
1568
- return -ENOMEM;
1569
-
1570
- private->secure_buffer_pool = gen_pool_create(PAGE_SHIFT, -1);
1571
- if (!private->secure_buffer_pool)
1572
- return -ENOMEM;
1573
-
1574
- gen_pool_add(private->secure_buffer_pool, start, size, -1);
1575
-
1576
- return 0;
1577
-}
1578
-
1579
-static void rockchip_gem_pool_destroy(struct drm_device *drm)
1580
-{
1581
- struct rockchip_drm_private *private = drm->dev_private;
1582
-
1583
- if (!private->secure_buffer_pool)
1584
- return;
1585
-
1586
- gen_pool_destroy(private->secure_buffer_pool);
15871381 }
15881382
15891383 static void rockchip_attach_connector_property(struct drm_device *drm)
....@@ -1655,20 +1449,44 @@
16551449 drm_modeset_unlock_all(drm);
16561450 }
16571451
1658
-static bool is_support_hotplug(uint32_t output_type)
1452
+static int rockchip_gem_pool_init(struct drm_device *drm)
16591453 {
1660
- switch (output_type) {
1661
- case DRM_MODE_CONNECTOR_DVII:
1662
- case DRM_MODE_CONNECTOR_DVID:
1663
- case DRM_MODE_CONNECTOR_DVIA:
1664
- case DRM_MODE_CONNECTOR_DisplayPort:
1665
- case DRM_MODE_CONNECTOR_HDMIA:
1666
- case DRM_MODE_CONNECTOR_HDMIB:
1667
- case DRM_MODE_CONNECTOR_TV:
1668
- return true;
1669
- default:
1670
- return false;
1671
- }
1454
+ struct rockchip_drm_private *private = drm->dev_private;
1455
+ struct device_node *np = drm->dev->of_node;
1456
+ struct device_node *node;
1457
+ phys_addr_t start, size;
1458
+ struct resource res;
1459
+ int ret;
1460
+
1461
+ node = of_parse_phandle(np, "secure-memory-region", 0);
1462
+ if (!node)
1463
+ return -ENXIO;
1464
+
1465
+ ret = of_address_to_resource(node, 0, &res);
1466
+ if (ret)
1467
+ return ret;
1468
+ start = res.start;
1469
+ size = resource_size(&res);
1470
+ if (!size)
1471
+ return -ENOMEM;
1472
+
1473
+ private->secure_buffer_pool = gen_pool_create(PAGE_SHIFT, -1);
1474
+ if (!private->secure_buffer_pool)
1475
+ return -ENOMEM;
1476
+
1477
+ gen_pool_add(private->secure_buffer_pool, start, size, -1);
1478
+
1479
+ return 0;
1480
+}
1481
+
1482
+static void rockchip_gem_pool_destroy(struct drm_device *drm)
1483
+{
1484
+ struct rockchip_drm_private *private = drm->dev_private;
1485
+
1486
+ if (!private->secure_buffer_pool)
1487
+ return;
1488
+
1489
+ gen_pool_destroy(private->secure_buffer_pool);
16721490 }
16731491
16741492 static int rockchip_drm_bind(struct device *dev)
....@@ -1676,9 +1494,6 @@
16761494 struct drm_device *drm_dev;
16771495 struct rockchip_drm_private *private;
16781496 int ret;
1679
- struct device_node *np = dev->of_node;
1680
- struct device_node *parent_np;
1681
- struct drm_crtc *crtc;
16821497
16831498 drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
16841499 if (IS_ERR(drm_dev))
....@@ -1692,35 +1507,16 @@
16921507 goto err_free;
16931508 }
16941509
1695
- mutex_init(&private->commit_lock);
16961510 mutex_init(&private->ovl_lock);
1697
- INIT_WORK(&private->commit_work, rockchip_drm_atomic_work);
1511
+
16981512 drm_dev->dev_private = private;
16991513
1700
- private->dmc_support = false;
1701
- private->devfreq = devfreq_get_devfreq_by_phandle(dev, 0);
1702
- if (IS_ERR(private->devfreq)) {
1703
- if (PTR_ERR(private->devfreq) == -EPROBE_DEFER) {
1704
- parent_np = of_parse_phandle(np, "devfreq", 0);
1705
- if (parent_np &&
1706
- of_device_is_available(parent_np)) {
1707
- private->dmc_support = true;
1708
- dev_warn(dev, "defer getting devfreq\n");
1709
- } else {
1710
- dev_info(dev, "dmc is disabled\n");
1711
- }
1712
- } else {
1713
- dev_info(dev, "devfreq is not set\n");
1714
- }
1715
- private->devfreq = NULL;
1716
- } else {
1717
- private->dmc_support = true;
1718
- dev_info(dev, "devfreq is ready\n");
1719
- }
1720
- private->hdmi_pll.pll = devm_clk_get(dev, "hdmi-tmds-pll");
1721
- if (PTR_ERR(private->hdmi_pll.pll) == -ENOENT) {
1722
- private->hdmi_pll.pll = NULL;
1723
- } else if (PTR_ERR(private->hdmi_pll.pll) == -EPROBE_DEFER) {
1514
+ INIT_LIST_HEAD(&private->psr_list);
1515
+ mutex_init(&private->psr_list_lock);
1516
+ mutex_init(&private->commit_lock);
1517
+
1518
+ private->hdmi_pll.pll = devm_clk_get_optional(dev, "hdmi-tmds-pll");
1519
+ if (PTR_ERR(private->hdmi_pll.pll) == -EPROBE_DEFER) {
17241520 ret = -EPROBE_DEFER;
17251521 goto err_free;
17261522 } else if (IS_ERR(private->hdmi_pll.pll)) {
....@@ -1728,10 +1524,8 @@
17281524 ret = PTR_ERR(private->hdmi_pll.pll);
17291525 goto err_free;
17301526 }
1731
- private->default_pll.pll = devm_clk_get(dev, "default-vop-pll");
1732
- if (PTR_ERR(private->default_pll.pll) == -ENOENT) {
1733
- private->default_pll.pll = NULL;
1734
- } else if (PTR_ERR(private->default_pll.pll) == -EPROBE_DEFER) {
1527
+ private->default_pll.pll = devm_clk_get_optional(dev, "default-vop-pll");
1528
+ if (PTR_ERR(private->default_pll.pll) == -EPROBE_DEFER) {
17351529 ret = -EPROBE_DEFER;
17361530 goto err_free;
17371531 } else if (IS_ERR(private->default_pll.pll)) {
....@@ -1740,14 +1534,9 @@
17401534 goto err_free;
17411535 }
17421536
1743
- INIT_LIST_HEAD(&private->psr_list);
1744
- mutex_init(&private->psr_list_lock);
1745
-
1746
- ret = rockchip_drm_init_iommu(drm_dev);
1537
+ ret = drmm_mode_config_init(drm_dev);
17471538 if (ret)
17481539 goto err_free;
1749
-
1750
- drm_mode_config_init(drm_dev);
17511540
17521541 rockchip_drm_mode_config_init(drm_dev);
17531542 rockchip_drm_create_properties(drm_dev);
....@@ -1773,48 +1562,38 @@
17731562 /* init kms poll for handling hpd */
17741563 drm_kms_helper_poll_init(drm_dev);
17751564
1776
- private->page_pools = dmabuf_page_pool_create(GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP, 0);
1565
+ ret = rockchip_drm_init_iommu(drm_dev);
1566
+ if (ret)
1567
+ goto err_unbind_all;
17771568
17781569 rockchip_gem_pool_init(drm_dev);
1779
-#ifndef MODULE
1780
- show_loader_logo(drm_dev);
1781
-#endif
17821570 ret = of_reserved_mem_device_init(drm_dev->dev);
17831571 if (ret)
17841572 DRM_DEBUG_KMS("No reserved memory region assign to drm\n");
17851573
1574
+ rockchip_drm_show_logo(drm_dev);
1575
+
17861576 ret = rockchip_drm_fbdev_init(drm_dev);
17871577 if (ret)
1788
- goto err_kms_helper_poll_fini;
1789
-
1790
- if (private->fbdev_helper && private->fbdev_helper->fb) {
1791
- drm_for_each_crtc(crtc, drm_dev) {
1792
- struct rockchip_crtc_state *s = NULL;
1793
-
1794
- s = to_rockchip_crtc_state(crtc->state);
1795
- if (is_support_hotplug(s->output_type))
1796
- drm_framebuffer_get(private->fbdev_helper->fb);
1797
- }
1798
- }
1578
+ goto err_iommu_cleanup;
17991579
18001580 drm_dev->mode_config.allow_fb_modifiers = true;
18011581
18021582 ret = drm_dev_register(drm_dev, 0);
18031583 if (ret)
1804
- goto err_fbdev_fini;
1584
+ goto err_kms_helper_poll_fini;
18051585
18061586 return 0;
1807
-err_fbdev_fini:
1808
- rockchip_drm_fbdev_fini(drm_dev);
18091587 err_kms_helper_poll_fini:
18101588 rockchip_gem_pool_destroy(drm_dev);
18111589 drm_kms_helper_poll_fini(drm_dev);
1590
+ rockchip_drm_fbdev_fini(drm_dev);
1591
+err_iommu_cleanup:
1592
+ rockchip_iommu_cleanup(drm_dev);
18121593 err_unbind_all:
1813
- dmabuf_page_pool_destroy(private->page_pools);
18141594 component_unbind_all(dev, drm_dev);
18151595 err_mode_config_cleanup:
18161596 drm_mode_config_cleanup(drm_dev);
1817
- rockchip_iommu_cleanup(drm_dev);
18181597 err_free:
18191598 drm_dev->dev_private = NULL;
18201599 dev_set_drvdata(dev, NULL);
....@@ -1971,61 +1750,20 @@
19711750 return rockchip_gem_prime_end_cpu_access(obj, dir);
19721751 }
19731752
1974
-static int rockchip_drm_gem_begin_cpu_access_partial(
1975
- struct dma_buf *dma_buf,
1976
- enum dma_data_direction dir,
1977
- unsigned int offset, unsigned int len)
1978
-{
1979
- struct drm_gem_object *obj = dma_buf->priv;
1980
-
1981
- return rockchip_gem_prime_begin_cpu_access_partial(obj, dir, offset, len);
1982
-}
1983
-
1984
-static int rockchip_drm_gem_end_cpu_access_partial(
1985
- struct dma_buf *dma_buf,
1986
- enum dma_data_direction dir,
1987
- unsigned int offset, unsigned int len)
1988
-{
1989
- struct drm_gem_object *obj = dma_buf->priv;
1990
-
1991
- return rockchip_gem_prime_end_cpu_access_partial(obj, dir, offset, len);
1992
-}
1993
-
19941753 static const struct dma_buf_ops rockchip_drm_gem_prime_dmabuf_ops = {
1754
+ .cache_sgt_mapping = true,
19951755 .attach = drm_gem_map_attach,
19961756 .detach = drm_gem_map_detach,
19971757 .map_dma_buf = drm_gem_map_dma_buf,
19981758 .unmap_dma_buf = drm_gem_unmap_dma_buf,
19991759 .release = drm_gem_dmabuf_release,
2000
- .map = drm_gem_dmabuf_kmap,
2001
- .unmap = drm_gem_dmabuf_kunmap,
20021760 .mmap = drm_gem_dmabuf_mmap,
20031761 .vmap = drm_gem_dmabuf_vmap,
20041762 .vunmap = drm_gem_dmabuf_vunmap,
1763
+ .get_uuid = drm_gem_dmabuf_get_uuid,
20051764 .begin_cpu_access = rockchip_drm_gem_dmabuf_begin_cpu_access,
20061765 .end_cpu_access = rockchip_drm_gem_dmabuf_end_cpu_access,
2007
- .begin_cpu_access_partial = rockchip_drm_gem_begin_cpu_access_partial,
2008
- .end_cpu_access_partial = rockchip_drm_gem_end_cpu_access_partial,
20091766 };
2010
-
2011
-#ifdef CONFIG_ARCH_ROCKCHIP
2012
-static void drm_gem_prime_dmabuf_release_callback(void *data)
2013
-{
2014
- struct drm_prime_callback_data *cb_data = data;
2015
-
2016
- if (cb_data && cb_data->obj && cb_data->obj->import_attach) {
2017
- struct dma_buf_attachment *attach = cb_data->obj->import_attach;
2018
- struct sg_table *sgt = cb_data->sgt;
2019
-
2020
- if (sgt)
2021
- dma_buf_unmap_attachment(attach, sgt,
2022
- DMA_BIDIRECTIONAL);
2023
- dma_buf_detach(attach->dmabuf, attach);
2024
- drm_gem_object_put_unlocked(cb_data->obj);
2025
- kfree(cb_data);
2026
- }
2027
-}
2028
-#endif
20291767
20301768 static struct drm_gem_object *rockchip_drm_gem_prime_import_dev(struct drm_device *dev,
20311769 struct dma_buf *dma_buf,
....@@ -2034,9 +1772,6 @@
20341772 struct dma_buf_attachment *attach;
20351773 struct sg_table *sgt;
20361774 struct drm_gem_object *obj;
2037
-#ifdef CONFIG_ARCH_ROCKCHIP
2038
- struct drm_prime_callback_data *cb_data = NULL;
2039
-#endif
20401775 int ret;
20411776
20421777 if (dma_buf->ops == &rockchip_drm_gem_prime_dmabuf_ops) {
....@@ -2051,15 +1786,6 @@
20511786 }
20521787 }
20531788
2054
-#ifdef CONFIG_ARCH_ROCKCHIP
2055
- cb_data = dma_buf_get_release_callback_data(dma_buf,
2056
- drm_gem_prime_dmabuf_release_callback);
2057
- if (cb_data && cb_data->obj && cb_data->obj->dev == dev) {
2058
- drm_gem_object_get(cb_data->obj);
2059
- return cb_data->obj;
2060
- }
2061
-#endif
2062
-
20631789 if (!dev->driver->gem_prime_import_sg_table)
20641790 return ERR_PTR(-EINVAL);
20651791
....@@ -2068,14 +1794,6 @@
20681794 return ERR_CAST(attach);
20691795
20701796 get_dma_buf(dma_buf);
2071
-
2072
-#ifdef CONFIG_ARCH_ROCKCHIP
2073
- cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
2074
- if (!cb_data) {
2075
- ret = -ENOMEM;
2076
- goto fail_detach;
2077
- }
2078
-#endif
20791797
20801798 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
20811799 if (IS_ERR(sgt)) {
....@@ -2090,24 +1808,13 @@
20901808 }
20911809
20921810 obj->import_attach = attach;
2093
-
2094
-#ifdef CONFIG_ARCH_ROCKCHIP
2095
- cb_data->obj = obj;
2096
- cb_data->sgt = sgt;
2097
- dma_buf_set_release_callback(dma_buf,
2098
- drm_gem_prime_dmabuf_release_callback, cb_data);
2099
- dma_buf_put(dma_buf);
2100
- drm_gem_object_get(obj);
2101
-#endif
1811
+ obj->resv = dma_buf->resv;
21021812
21031813 return obj;
21041814
21051815 fail_unmap:
21061816 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
21071817 fail_detach:
2108
-#ifdef CONFIG_ARCH_ROCKCHIP
2109
- kfree(cb_data);
2110
-#endif
21111818 dma_buf_detach(dma_buf, attach);
21121819 dma_buf_put(dma_buf);
21131820
....@@ -2120,10 +1827,10 @@
21201827 return rockchip_drm_gem_prime_import_dev(dev, dma_buf, dev->dev);
21211828 }
21221829
2123
-static struct dma_buf *rockchip_drm_gem_prime_export(struct drm_device *dev,
2124
- struct drm_gem_object *obj,
1830
+static struct dma_buf *rockchip_drm_gem_prime_export(struct drm_gem_object *obj,
21251831 int flags)
21261832 {
1833
+ struct drm_device *dev = obj->dev;
21271834 struct dma_buf_export_info exp_info = {
21281835 .exp_name = KBUILD_MODNAME, /* white lie for debug */
21291836 .owner = dev->driver->fops->owner,
....@@ -2131,26 +1838,20 @@
21311838 .size = obj->size,
21321839 .flags = flags,
21331840 .priv = obj,
1841
+ .resv = obj->resv,
21341842 };
2135
-
2136
- if (dev->driver->gem_prime_res_obj)
2137
- exp_info.resv = dev->driver->gem_prime_res_obj(obj);
21381843
21391844 return drm_gem_dmabuf_export(dev, &exp_info);
21401845 }
21411846
21421847 static struct drm_driver rockchip_drm_driver = {
2143
- .driver_features = DRIVER_MODESET | DRIVER_GEM |
2144
- DRIVER_PRIME | DRIVER_ATOMIC |
2145
- DRIVER_RENDER,
1848
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC | DRIVER_RENDER,
21461849 .postclose = rockchip_drm_postclose,
21471850 .lastclose = rockchip_drm_lastclose,
21481851 .open = rockchip_drm_open,
21491852 .gem_vm_ops = &drm_gem_cma_vm_ops,
21501853 .gem_free_object_unlocked = rockchip_gem_free_object,
21511854 .dumb_create = rockchip_gem_dumb_create,
2152
- .dumb_map_offset = rockchip_gem_dumb_map_offset,
2153
- .dumb_destroy = drm_gem_dumb_destroy,
21541855 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
21551856 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
21561857 .gem_prime_import = rockchip_drm_gem_prime_import,
....@@ -2171,64 +1872,21 @@
21711872 .date = DRIVER_DATE,
21721873 .major = DRIVER_MAJOR,
21731874 .minor = DRIVER_MINOR,
2174
- .patchlevel = DRIVER_PATCH,
21751875 };
21761876
21771877 #ifdef CONFIG_PM_SLEEP
2178
-static void rockchip_drm_fb_suspend(struct drm_device *drm)
2179
-{
2180
- struct rockchip_drm_private *priv = drm->dev_private;
2181
-
2182
- console_lock();
2183
- drm_fb_helper_set_suspend(priv->fbdev_helper, 1);
2184
- console_unlock();
2185
-}
2186
-
2187
-static void rockchip_drm_fb_resume(struct drm_device *drm)
2188
-{
2189
- struct rockchip_drm_private *priv = drm->dev_private;
2190
-
2191
- console_lock();
2192
- drm_fb_helper_set_suspend(priv->fbdev_helper, 0);
2193
- console_unlock();
2194
-}
2195
-
21961878 static int rockchip_drm_sys_suspend(struct device *dev)
21971879 {
21981880 struct drm_device *drm = dev_get_drvdata(dev);
2199
- struct rockchip_drm_private *priv;
22001881
2201
- if (!drm)
2202
- return 0;
2203
-
2204
- drm_kms_helper_poll_disable(drm);
2205
- rockchip_drm_fb_suspend(drm);
2206
-
2207
- priv = drm->dev_private;
2208
- priv->state = drm_atomic_helper_suspend(drm);
2209
- if (IS_ERR(priv->state)) {
2210
- rockchip_drm_fb_resume(drm);
2211
- drm_kms_helper_poll_enable(drm);
2212
- return PTR_ERR(priv->state);
2213
- }
2214
-
2215
- return 0;
1882
+ return drm_mode_config_helper_suspend(drm);
22161883 }
22171884
22181885 static int rockchip_drm_sys_resume(struct device *dev)
22191886 {
22201887 struct drm_device *drm = dev_get_drvdata(dev);
2221
- struct rockchip_drm_private *priv;
22221888
2223
- if (!drm)
2224
- return 0;
2225
-
2226
- priv = drm->dev_private;
2227
- drm_atomic_helper_resume(drm, priv->state);
2228
- rockchip_drm_fb_resume(drm);
2229
- drm_kms_helper_poll_enable(drm);
2230
-
2231
- return 0;
1889
+ return drm_mode_config_helper_resume(drm);
22321890 }
22331891 #endif
22341892
....@@ -2240,6 +1898,53 @@
22401898 #define MAX_ROCKCHIP_SUB_DRIVERS 16
22411899 static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS];
22421900 static int num_rockchip_sub_drivers;
1901
+
1902
+/*
1903
+ * Check if a vop endpoint is leading to a rockchip subdriver or bridge.
1904
+ * Should be called from the component bind stage of the drivers
1905
+ * to ensure that all subdrivers are probed.
1906
+ *
1907
+ * @ep: endpoint of a rockchip vop
1908
+ *
1909
+ * returns true if subdriver, false if external bridge and -ENODEV
1910
+ * if remote port does not contain a device.
1911
+ */
1912
+int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
1913
+{
1914
+ struct device_node *node = of_graph_get_remote_port_parent(ep);
1915
+ struct platform_device *pdev;
1916
+ struct device_driver *drv;
1917
+ int i;
1918
+
1919
+ if (!node)
1920
+ return -ENODEV;
1921
+
1922
+ /* status disabled will prevent creation of platform-devices */
1923
+ pdev = of_find_device_by_node(node);
1924
+ of_node_put(node);
1925
+ if (!pdev)
1926
+ return -ENODEV;
1927
+
1928
+ /*
1929
+ * All rockchip subdrivers have probed at this point, so
1930
+ * any device not having a driver now is an external bridge.
1931
+ */
1932
+ drv = pdev->dev.driver;
1933
+ if (!drv) {
1934
+ platform_device_put(pdev);
1935
+ return false;
1936
+ }
1937
+
1938
+ for (i = 0; i < num_rockchip_sub_drivers; i++) {
1939
+ if (rockchip_sub_drivers[i] == to_platform_driver(drv)) {
1940
+ platform_device_put(pdev);
1941
+ return true;
1942
+ }
1943
+ }
1944
+
1945
+ platform_device_put(pdev);
1946
+ return false;
1947
+}
22431948
22441949 static int compare_dev(struct device *dev, void *data)
22451950 {
....@@ -2264,8 +1969,7 @@
22641969 struct device *p = NULL, *d;
22651970
22661971 do {
2267
- d = bus_find_device(&platform_bus_type, p, &drv->driver,
2268
- (void *)platform_bus_type.match);
1972
+ d = platform_find_device_by_driver(p, &drv->driver);
22691973 put_device(p);
22701974 p = d;
22711975
....@@ -2311,7 +2015,7 @@
23112015 }
23122016
23132017 iommu = of_parse_phandle(port->parent, "iommus", 0);
2314
- if (!iommu || !of_device_is_available(iommu->parent)) {
2018
+ if (!iommu || !of_device_is_available(iommu)) {
23152019 DRM_DEV_DEBUG(dev,
23162020 "no iommu attached for %pOF, using non-iommu buffers\n",
23172021 port->parent);
....@@ -2323,8 +2027,8 @@
23232027 }
23242028
23252029 found = true;
2326
- iommu_reserve_map |= of_property_read_bool(iommu, "rockchip,reserve-map");
23272030
2031
+ iommu_reserve_map |= of_property_read_bool(iommu, "rockchip,reserve-map");
23282032 of_node_put(iommu);
23292033 of_node_put(port);
23302034 }
....@@ -2359,14 +2063,19 @@
23592063 if (IS_ERR(match))
23602064 return PTR_ERR(match);
23612065
2066
+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
2067
+ if (ret)
2068
+ goto err;
2069
+
23622070 ret = component_master_add_with_match(dev, &rockchip_drm_ops, match);
2363
- if (ret < 0) {
2364
- rockchip_drm_match_remove(dev);
2365
- return ret;
2366
- }
2367
- dev->coherent_dma_mask = DMA_BIT_MASK(64);
2071
+ if (ret < 0)
2072
+ goto err;
23682073
23692074 return 0;
2075
+err:
2076
+ rockchip_drm_match_remove(dev);
2077
+
2078
+ return ret;
23702079 }
23712080
23722081 static int rockchip_drm_platform_remove(struct platform_device *pdev)
....@@ -2382,10 +2091,8 @@
23822091 {
23832092 struct drm_device *drm = platform_get_drvdata(pdev);
23842093
2385
- if (drm) {
2386
- drm_kms_helper_poll_fini(drm);
2094
+ if (drm)
23872095 drm_atomic_helper_shutdown(drm);
2388
- }
23892096 }
23902097
23912098 static const struct of_device_id rockchip_drm_dt_ids[] = {
....@@ -2421,6 +2128,7 @@
24212128 #else
24222129 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP);
24232130 ADD_ROCKCHIP_SUB_DRIVER(vop2_platform_driver, CONFIG_ROCKCHIP_VOP2);
2131
+ ADD_ROCKCHIP_SUB_DRIVER(vconn_platform_driver, CONFIG_ROCKCHIP_VCONN);
24242132 ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver,
24252133 CONFIG_ROCKCHIP_LVDS);
24262134 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
....@@ -2428,12 +2136,17 @@
24282136 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
24292137 ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver,
24302138 CONFIG_ROCKCHIP_DW_HDMI);
2431
- ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_driver,
2139
+ ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
2140
+ CONFIG_ROCKCHIP_DW_MIPI_DSI);
2141
+ ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi2_rockchip_driver,
24322142 CONFIG_ROCKCHIP_DW_MIPI_DSI);
24332143 ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
2434
- ADD_ROCKCHIP_SUB_DRIVER(rockchip_tve_driver,
2435
- CONFIG_ROCKCHIP_DRM_TVE);
2144
+ ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
2145
+ CONFIG_ROCKCHIP_RK3066_HDMI);
24362146 ADD_ROCKCHIP_SUB_DRIVER(rockchip_rgb_driver, CONFIG_ROCKCHIP_RGB);
2147
+ ADD_ROCKCHIP_SUB_DRIVER(rockchip_tve_driver, CONFIG_ROCKCHIP_DRM_TVE);
2148
+ ADD_ROCKCHIP_SUB_DRIVER(dw_dp_driver, CONFIG_ROCKCHIP_DW_DP);
2149
+
24372150 #endif
24382151 ret = platform_register_drivers(rockchip_sub_drivers,
24392152 num_rockchip_sub_drivers);
....@@ -2443,6 +2156,8 @@
24432156 ret = platform_driver_register(&rockchip_drm_platform_driver);
24442157 if (ret)
24452158 goto err_unreg_drivers;
2159
+
2160
+ rockchip_gem_get_ddr_info();
24462161
24472162 return 0;
24482163
....@@ -2460,7 +2175,11 @@
24602175 num_rockchip_sub_drivers);
24612176 }
24622177
2178
+#ifdef CONFIG_VIDEO_REVERSE_IMAGE
2179
+fs_initcall(rockchip_drm_init);
2180
+#else
24632181 module_init(rockchip_drm_init);
2182
+#endif
24642183 module_exit(rockchip_drm_fini);
24652184
24662185 MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>");