1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) Rockchip Electronics Co., Ltd.
4 * Author: Andy Yan <andy.yan@rock-chips.com>
5 */
6
7 #include <linux/kernel.h>
8 #include <linux/component.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/platform_device.h>
11 #include <linux/of.h>
12 #include <drm/drm_fourcc.h>
13 #include <drm/drm_plane.h>
14 #include <drm/drm_print.h>
15
16 #include "rockchip_drm_vop2.h"
17
18 static const uint32_t formats_cluster[] = {
19 DRM_FORMAT_XRGB2101010,
20 DRM_FORMAT_XBGR2101010,
21 DRM_FORMAT_XRGB8888,
22 DRM_FORMAT_ARGB8888,
23 DRM_FORMAT_XBGR8888,
24 DRM_FORMAT_ABGR8888,
25 DRM_FORMAT_RGB888,
26 DRM_FORMAT_BGR888,
27 DRM_FORMAT_RGB565,
28 DRM_FORMAT_BGR565,
29 DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */
30 DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */
31 DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/
32 DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
33 };
34
35 static const uint32_t formats_esmart[] = {
36 DRM_FORMAT_XRGB8888,
37 DRM_FORMAT_ARGB8888,
38 DRM_FORMAT_XBGR8888,
39 DRM_FORMAT_ABGR8888,
40 DRM_FORMAT_RGB888,
41 DRM_FORMAT_BGR888,
42 DRM_FORMAT_RGB565,
43 DRM_FORMAT_BGR565,
44 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
45 DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
46 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
47 DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
48 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
49 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
50 DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
51 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
52 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
53 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
54 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
55 DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
56 DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
57 };
58
59 static const uint32_t formats_rk356x_esmart[] = {
60 DRM_FORMAT_XRGB8888,
61 DRM_FORMAT_ARGB8888,
62 DRM_FORMAT_XBGR8888,
63 DRM_FORMAT_ABGR8888,
64 DRM_FORMAT_RGB888,
65 DRM_FORMAT_BGR888,
66 DRM_FORMAT_RGB565,
67 DRM_FORMAT_BGR565,
68 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
69 DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */
70 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
71 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
72 DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */
73 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
74 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
75 DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */
76 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
77 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
78 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
79 };
80
81 static const uint32_t formats_smart[] = {
82 DRM_FORMAT_XRGB8888,
83 DRM_FORMAT_ARGB8888,
84 DRM_FORMAT_XBGR8888,
85 DRM_FORMAT_ABGR8888,
86 DRM_FORMAT_RGB888,
87 DRM_FORMAT_BGR888,
88 DRM_FORMAT_RGB565,
89 DRM_FORMAT_BGR565,
90 };
91
92 static const uint64_t format_modifiers[] = {
93 DRM_FORMAT_MOD_LINEAR,
94 DRM_FORMAT_MOD_INVALID,
95 };
96
97 static const uint64_t format_modifiers_afbc[] = {
98 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16),
99
100 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
101 AFBC_FORMAT_MOD_SPARSE),
102
103 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
104 AFBC_FORMAT_MOD_YTR),
105
106 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
107 AFBC_FORMAT_MOD_CBR),
108
109 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
110 AFBC_FORMAT_MOD_YTR |
111 AFBC_FORMAT_MOD_SPARSE),
112
113 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
114 AFBC_FORMAT_MOD_CBR |
115 AFBC_FORMAT_MOD_SPARSE),
116
117 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
118 AFBC_FORMAT_MOD_YTR |
119 AFBC_FORMAT_MOD_CBR),
120
121 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
122 AFBC_FORMAT_MOD_YTR |
123 AFBC_FORMAT_MOD_CBR |
124 AFBC_FORMAT_MOD_SPARSE),
125
126 /* SPLIT mandates SPARSE, RGB modes mandates YTR */
127 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
128 AFBC_FORMAT_MOD_YTR |
129 AFBC_FORMAT_MOD_SPARSE |
130 AFBC_FORMAT_MOD_SPLIT),
131 DRM_FORMAT_MOD_INVALID,
132 };
133
134 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
135 {
136 .id = 0,
137 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
138 .gamma_lut_len = 1024,
139 .cubic_lut_len = 9 * 9 * 9,
140 .max_output = { 4096, 2304 },
141 .pre_scan_max_dly = { 69, 53, 53, 42 },
142 .offset = 0xc00,
143 }, {
144 .id = 1,
145 .gamma_lut_len = 1024,
146 .max_output = { 2048, 1536 },
147 .pre_scan_max_dly = { 40, 40, 40, 40 },
148 .offset = 0xd00,
149 }, {
150 .id = 2,
151 .gamma_lut_len = 1024,
152 .max_output = { 1920, 1080 },
153 .pre_scan_max_dly = { 40, 40, 40, 40 },
154 .offset = 0xe00,
155 },
156 };
157
158 /*
159 * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win.
160 * Every cluster can work as 4K win or split into two win.
161 * All win in cluster support AFBCD.
162 *
163 * Every esmart win and smart win support 4 Multi-region.
164 *
165 * Scale filter mode:
166 *
167 * * Cluster: bicubic for horizontal scale up, others use bilinear
168 * * ESmart:
169 * * nearest-neighbor/bilinear/bicubic for scale up
170 * * nearest-neighbor/bilinear/average for scale down
171 *
172 *
173 * @TODO describe the wind like cpu-map dt nodes;
174 */
175 static const struct vop2_win_data rk3568_vop_win_data[] = {
176 {
177 .name = "Smart0-win0",
178 .phys_id = ROCKCHIP_VOP2_SMART0,
179 .base = 0x1c00,
180 .formats = formats_smart,
181 .nformats = ARRAY_SIZE(formats_smart),
182 .format_modifiers = format_modifiers,
183 .layer_sel_id = 3,
184 .supported_rotations = DRM_MODE_REFLECT_Y,
185 .type = DRM_PLANE_TYPE_PRIMARY,
186 .max_upscale_factor = 8,
187 .max_downscale_factor = 8,
188 .dly = { 20, 47, 41 },
189 }, {
190 .name = "Smart1-win0",
191 .phys_id = ROCKCHIP_VOP2_SMART1,
192 .formats = formats_smart,
193 .nformats = ARRAY_SIZE(formats_smart),
194 .format_modifiers = format_modifiers,
195 .base = 0x1e00,
196 .layer_sel_id = 7,
197 .supported_rotations = DRM_MODE_REFLECT_Y,
198 .type = DRM_PLANE_TYPE_PRIMARY,
199 .max_upscale_factor = 8,
200 .max_downscale_factor = 8,
201 .dly = { 20, 47, 41 },
202 }, {
203 .name = "Esmart1-win0",
204 .phys_id = ROCKCHIP_VOP2_ESMART1,
205 .formats = formats_rk356x_esmart,
206 .nformats = ARRAY_SIZE(formats_rk356x_esmart),
207 .format_modifiers = format_modifiers,
208 .base = 0x1a00,
209 .layer_sel_id = 6,
210 .supported_rotations = DRM_MODE_REFLECT_Y,
211 .type = DRM_PLANE_TYPE_PRIMARY,
212 .max_upscale_factor = 8,
213 .max_downscale_factor = 8,
214 .dly = { 20, 47, 41 },
215 }, {
216 .name = "Esmart0-win0",
217 .phys_id = ROCKCHIP_VOP2_ESMART0,
218 .formats = formats_rk356x_esmart,
219 .nformats = ARRAY_SIZE(formats_rk356x_esmart),
220 .format_modifiers = format_modifiers,
221 .base = 0x1800,
222 .layer_sel_id = 2,
223 .supported_rotations = DRM_MODE_REFLECT_Y,
224 .type = DRM_PLANE_TYPE_PRIMARY,
225 .max_upscale_factor = 8,
226 .max_downscale_factor = 8,
227 .dly = { 20, 47, 41 },
228 }, {
229 .name = "Cluster0-win0",
230 .phys_id = ROCKCHIP_VOP2_CLUSTER0,
231 .base = 0x1000,
232 .formats = formats_cluster,
233 .nformats = ARRAY_SIZE(formats_cluster),
234 .format_modifiers = format_modifiers_afbc,
235 .layer_sel_id = 0,
236 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
237 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
238 .max_upscale_factor = 4,
239 .max_downscale_factor = 4,
240 .dly = { 0, 27, 21 },
241 .type = DRM_PLANE_TYPE_OVERLAY,
242 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
243 }, {
244 .name = "Cluster1-win0",
245 .phys_id = ROCKCHIP_VOP2_CLUSTER1,
246 .base = 0x1200,
247 .formats = formats_cluster,
248 .nformats = ARRAY_SIZE(formats_cluster),
249 .format_modifiers = format_modifiers_afbc,
250 .layer_sel_id = 1,
251 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
252 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
253 .type = DRM_PLANE_TYPE_OVERLAY,
254 .max_upscale_factor = 4,
255 .max_downscale_factor = 4,
256 .dly = { 0, 27, 21 },
257 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
258 },
259 };
260
261 static const struct vop2_regs_dump rk3568_regs_dump[] = {
262 {
263 .name = "SYS",
264 .base = RK3568_REG_CFG_DONE,
265 .size = 0x100,
266 .en_reg = 0,
267 .en_val = 0,
268 .en_mask = 0
269 }, {
270 .name = "OVL",
271 .base = RK3568_OVL_CTRL,
272 .size = 0x100,
273 .en_reg = 0,
274 .en_val = 0,
275 .en_mask = 0,
276 }, {
277 .name = "VP0",
278 .base = RK3568_VP0_CTRL_BASE,
279 .size = 0x100,
280 .en_reg = RK3568_VP_DSP_CTRL,
281 .en_val = 0,
282 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
283 }, {
284 .name = "VP1",
285 .base = RK3568_VP1_CTRL_BASE,
286 .size = 0x100,
287 .en_reg = RK3568_VP_DSP_CTRL,
288 .en_val = 0,
289 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
290 }, {
291 .name = "VP2",
292 .base = RK3568_VP2_CTRL_BASE,
293 .size = 0x100,
294 .en_reg = RK3568_VP_DSP_CTRL,
295 .en_val = 0,
296 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
297
298 }, {
299 .name = "Cluster0",
300 .base = RK3568_CLUSTER0_CTRL_BASE,
301 .size = 0x110,
302 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
303 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
304 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
305 }, {
306 .name = "Cluster1",
307 .base = RK3568_CLUSTER1_CTRL_BASE,
308 .size = 0x110,
309 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
310 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
311 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
312 }, {
313 .name = "Esmart0",
314 .base = RK3568_ESMART0_CTRL_BASE,
315 .size = 0xf0,
316 .en_reg = RK3568_SMART_REGION0_CTRL,
317 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
318 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
319 }, {
320 .name = "Esmart1",
321 .base = RK3568_ESMART1_CTRL_BASE,
322 .size = 0xf0,
323 .en_reg = RK3568_SMART_REGION0_CTRL,
324 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
325 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
326 }, {
327 .name = "Smart0",
328 .base = RK3568_SMART0_CTRL_BASE,
329 .size = 0xf0,
330 .en_reg = RK3568_SMART_REGION0_CTRL,
331 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
332 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
333 }, {
334 .name = "Smart1",
335 .base = RK3568_SMART1_CTRL_BASE,
336 .size = 0xf0,
337 .en_reg = RK3568_SMART_REGION0_CTRL,
338 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
339 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
340 },
341 };
342
343 static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
344 {
345 .id = 0,
346 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
347 .gamma_lut_len = 1024,
348 .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
349 .max_output = { 4096, 2304 },
350 /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */
351 .pre_scan_max_dly = { 76, 65, 65, 54 },
352 .offset = 0xc00,
353 }, {
354 .id = 1,
355 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
356 .gamma_lut_len = 1024,
357 .cubic_lut_len = 729, /* 9x9x9 */
358 .max_output = { 4096, 2304 },
359 .pre_scan_max_dly = { 76, 65, 65, 54 },
360 .offset = 0xd00,
361 }, {
362 .id = 2,
363 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
364 .gamma_lut_len = 1024,
365 .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */
366 .max_output = { 4096, 2304 },
367 .pre_scan_max_dly = { 52, 52, 52, 52 },
368 .offset = 0xe00,
369 }, {
370 .id = 3,
371 .gamma_lut_len = 1024,
372 .max_output = { 2048, 1536 },
373 .pre_scan_max_dly = { 52, 52, 52, 52 },
374 .offset = 0xf00,
375 },
376 };
377
378 /*
379 * rk3588 vop with 4 cluster, 4 esmart win.
380 * Every cluster can work as 4K win or split into two win.
381 * All win in cluster support AFBCD.
382 *
383 * Every esmart win and smart win support 4 Multi-region.
384 *
385 * Scale filter mode:
386 *
387 * * Cluster: bicubic for horizontal scale up, others use bilinear
388 * * ESmart:
389 * * nearest-neighbor/bilinear/bicubic for scale up
390 * * nearest-neighbor/bilinear/average for scale down
391 *
392 * AXI Read ID assignment:
393 * Two AXI bus:
394 * AXI0 is a read/write bus with a higher performance.
395 * AXI1 is a read only bus.
396 *
397 * Every window on a AXI bus must assigned two unique
398 * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
399 *
400 * AXI0:
401 * Cluster0/1, Esmart0/1, WriteBack
402 *
403 * AXI 1:
404 * Cluster2/3, Esmart2/3
405 *
406 */
407 static const struct vop2_win_data rk3588_vop_win_data[] = {
408 {
409 .name = "Cluster0-win0",
410 .phys_id = ROCKCHIP_VOP2_CLUSTER0,
411 .base = 0x1000,
412 .formats = formats_cluster,
413 .nformats = ARRAY_SIZE(formats_cluster),
414 .format_modifiers = format_modifiers_afbc,
415 .layer_sel_id = 0,
416 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
417 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
418 .axi_bus_id = 0,
419 .axi_yrgb_r_id = 2,
420 .axi_uv_r_id = 3,
421 .max_upscale_factor = 4,
422 .max_downscale_factor = 4,
423 .dly = { 4, 26, 29 },
424 .type = DRM_PLANE_TYPE_PRIMARY,
425 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
426 }, {
427 .name = "Cluster1-win0",
428 .phys_id = ROCKCHIP_VOP2_CLUSTER1,
429 .base = 0x1200,
430 .formats = formats_cluster,
431 .nformats = ARRAY_SIZE(formats_cluster),
432 .format_modifiers = format_modifiers_afbc,
433 .layer_sel_id = 1,
434 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
435 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
436 .type = DRM_PLANE_TYPE_PRIMARY,
437 .axi_bus_id = 0,
438 .axi_yrgb_r_id = 6,
439 .axi_uv_r_id = 7,
440 .max_upscale_factor = 4,
441 .max_downscale_factor = 4,
442 .dly = { 4, 26, 29 },
443 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
444 }, {
445 .name = "Cluster2-win0",
446 .phys_id = ROCKCHIP_VOP2_CLUSTER2,
447 .base = 0x1400,
448 .formats = formats_cluster,
449 .nformats = ARRAY_SIZE(formats_cluster),
450 .format_modifiers = format_modifiers_afbc,
451 .layer_sel_id = 4,
452 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
453 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
454 .type = DRM_PLANE_TYPE_PRIMARY,
455 .axi_bus_id = 1,
456 .axi_yrgb_r_id = 2,
457 .axi_uv_r_id = 3,
458 .max_upscale_factor = 4,
459 .max_downscale_factor = 4,
460 .dly = { 4, 26, 29 },
461 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
462 }, {
463 .name = "Cluster3-win0",
464 .phys_id = ROCKCHIP_VOP2_CLUSTER3,
465 .base = 0x1600,
466 .formats = formats_cluster,
467 .nformats = ARRAY_SIZE(formats_cluster),
468 .format_modifiers = format_modifiers_afbc,
469 .layer_sel_id = 5,
470 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
471 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
472 .type = DRM_PLANE_TYPE_PRIMARY,
473 .axi_bus_id = 1,
474 .axi_yrgb_r_id = 6,
475 .axi_uv_r_id = 7,
476 .max_upscale_factor = 4,
477 .max_downscale_factor = 4,
478 .dly = { 4, 26, 29 },
479 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
480 }, {
481 .name = "Esmart0-win0",
482 .phys_id = ROCKCHIP_VOP2_ESMART0,
483 .formats = formats_esmart,
484 .nformats = ARRAY_SIZE(formats_esmart),
485 .format_modifiers = format_modifiers,
486 .base = 0x1800,
487 .layer_sel_id = 2,
488 .supported_rotations = DRM_MODE_REFLECT_Y,
489 .type = DRM_PLANE_TYPE_OVERLAY,
490 .axi_bus_id = 0,
491 .axi_yrgb_r_id = 0x0a,
492 .axi_uv_r_id = 0x0b,
493 .max_upscale_factor = 8,
494 .max_downscale_factor = 8,
495 .dly = { 23, 45, 48 },
496 }, {
497 .name = "Esmart1-win0",
498 .phys_id = ROCKCHIP_VOP2_ESMART1,
499 .formats = formats_esmart,
500 .nformats = ARRAY_SIZE(formats_esmart),
501 .format_modifiers = format_modifiers,
502 .base = 0x1a00,
503 .layer_sel_id = 3,
504 .supported_rotations = DRM_MODE_REFLECT_Y,
505 .type = DRM_PLANE_TYPE_OVERLAY,
506 .axi_bus_id = 0,
507 .axi_yrgb_r_id = 0x0c,
508 .axi_uv_r_id = 0x01,
509 .max_upscale_factor = 8,
510 .max_downscale_factor = 8,
511 .dly = { 23, 45, 48 },
512 }, {
513 .name = "Esmart2-win0",
514 .phys_id = ROCKCHIP_VOP2_ESMART2,
515 .base = 0x1c00,
516 .formats = formats_esmart,
517 .nformats = ARRAY_SIZE(formats_esmart),
518 .format_modifiers = format_modifiers,
519 .layer_sel_id = 6,
520 .supported_rotations = DRM_MODE_REFLECT_Y,
521 .type = DRM_PLANE_TYPE_OVERLAY,
522 .axi_bus_id = 1,
523 .axi_yrgb_r_id = 0x0a,
524 .axi_uv_r_id = 0x0b,
525 .max_upscale_factor = 8,
526 .max_downscale_factor = 8,
527 .dly = { 23, 45, 48 },
528 }, {
529 .name = "Esmart3-win0",
530 .phys_id = ROCKCHIP_VOP2_ESMART3,
531 .formats = formats_esmart,
532 .nformats = ARRAY_SIZE(formats_esmart),
533 .format_modifiers = format_modifiers,
534 .base = 0x1e00,
535 .layer_sel_id = 7,
536 .supported_rotations = DRM_MODE_REFLECT_Y,
537 .type = DRM_PLANE_TYPE_OVERLAY,
538 .axi_bus_id = 1,
539 .axi_yrgb_r_id = 0x0c,
540 .axi_uv_r_id = 0x0d,
541 .max_upscale_factor = 8,
542 .max_downscale_factor = 8,
543 .dly = { 23, 45, 48 },
544 },
545 };
546
547 static const struct vop2_regs_dump rk3588_regs_dump[] = {
548 {
549 .name = "SYS",
550 .base = RK3568_REG_CFG_DONE,
551 .size = 0x100,
552 .en_reg = 0,
553 .en_val = 0,
554 .en_mask = 0
555 }, {
556 .name = "OVL",
557 .base = RK3568_OVL_CTRL,
558 .size = 0x100,
559 .en_reg = 0,
560 .en_val = 0,
561 .en_mask = 0,
562 }, {
563 .name = "VP0",
564 .base = RK3568_VP0_CTRL_BASE,
565 .size = 0x100,
566 .en_reg = RK3568_VP_DSP_CTRL,
567 .en_val = 0,
568 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
569 }, {
570 .name = "VP1",
571 .base = RK3568_VP1_CTRL_BASE,
572 .size = 0x100,
573 .en_reg = RK3568_VP_DSP_CTRL,
574 .en_val = 0,
575 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
576 }, {
577 .name = "VP2",
578 .base = RK3568_VP2_CTRL_BASE,
579 .size = 0x100,
580 .en_reg = RK3568_VP_DSP_CTRL,
581 .en_val = 0,
582 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
583
584 }, {
585 .name = "VP3",
586 .base = RK3588_VP3_CTRL_BASE,
587 .size = 0x100,
588 .en_reg = RK3568_VP_DSP_CTRL,
589 .en_val = 0,
590 .en_mask = RK3568_VP_DSP_CTRL__STANDBY,
591 }, {
592 .name = "Cluster0",
593 .base = RK3568_CLUSTER0_CTRL_BASE,
594 .size = 0x110,
595 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
596 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
597 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
598 }, {
599 .name = "Cluster1",
600 .base = RK3568_CLUSTER1_CTRL_BASE,
601 .size = 0x110,
602 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
603 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
604 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
605 }, {
606 .name = "Cluster2",
607 .base = RK3588_CLUSTER2_CTRL_BASE,
608 .size = 0x110,
609 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
610 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
611 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
612 }, {
613 .name = "Cluster3",
614 .base = RK3588_CLUSTER3_CTRL_BASE,
615 .size = 0x110,
616 .en_reg = RK3568_CLUSTER_WIN_CTRL0,
617 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
618 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
619 }, {
620 .name = "Esmart0",
621 .base = RK3568_ESMART0_CTRL_BASE,
622 .size = 0xf0,
623 .en_reg = RK3568_SMART_REGION0_CTRL,
624 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
625 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
626 }, {
627 .name = "Esmart1",
628 .base = RK3568_ESMART1_CTRL_BASE,
629 .size = 0xf0,
630 .en_reg = RK3568_SMART_REGION0_CTRL,
631 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
632 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
633 }, {
634 .name = "Esmart2",
635 .base = RK3588_ESMART2_CTRL_BASE,
636 .size = 0xf0,
637 .en_reg = RK3568_SMART_REGION0_CTRL,
638 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
639 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
640 }, {
641 .name = "Esmart3",
642 .base = RK3588_ESMART3_CTRL_BASE,
643 .size = 0xf0,
644 .en_reg = RK3568_SMART_REGION0_CTRL,
645 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
646 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
647 },
648 };
649
650 static const struct vop2_data rk3566_vop = {
651 .feature = VOP2_FEATURE_HAS_SYS_GRF,
652 .nr_vps = 3,
653 .max_input = { 4096, 2304 },
654 .max_output = { 4096, 2304 },
655 .vp = rk3568_vop_video_ports,
656 .win = rk3568_vop_win_data,
657 .win_size = ARRAY_SIZE(rk3568_vop_win_data),
658 .regs_dump = rk3568_regs_dump,
659 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
660 .soc_id = 3566,
661 };
662
663 static const struct vop2_data rk3568_vop = {
664 .feature = VOP2_FEATURE_HAS_SYS_GRF,
665 .nr_vps = 3,
666 .max_input = { 4096, 2304 },
667 .max_output = { 4096, 2304 },
668 .vp = rk3568_vop_video_ports,
669 .win = rk3568_vop_win_data,
670 .win_size = ARRAY_SIZE(rk3568_vop_win_data),
671 .regs_dump = rk3568_regs_dump,
672 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
673 .soc_id = 3568,
674 };
675
676 static const struct vop2_data rk3588_vop = {
677 .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
678 VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
679 .nr_vps = 4,
680 .max_input = { 4096, 4320 },
681 .max_output = { 4096, 4320 },
682 .vp = rk3588_vop_video_ports,
683 .win = rk3588_vop_win_data,
684 .win_size = ARRAY_SIZE(rk3588_vop_win_data),
685 .regs_dump = rk3588_regs_dump,
686 .regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
687 .soc_id = 3588,
688 };
689
690 static const struct of_device_id vop2_dt_match[] = {
691 {
692 .compatible = "rockchip,rk3566-vop",
693 .data = &rk3566_vop,
694 }, {
695 .compatible = "rockchip,rk3568-vop",
696 .data = &rk3568_vop,
697 }, {
698 .compatible = "rockchip,rk3588-vop",
699 .data = &rk3588_vop
700 }, {
701 },
702 };
703 MODULE_DEVICE_TABLE(of, vop2_dt_match);
704
vop2_probe(struct platform_device * pdev)705 static int vop2_probe(struct platform_device *pdev)
706 {
707 struct device *dev = &pdev->dev;
708
709 return component_add(dev, &vop2_component_ops);
710 }
711
vop2_remove(struct platform_device * pdev)712 static void vop2_remove(struct platform_device *pdev)
713 {
714 component_del(&pdev->dev, &vop2_component_ops);
715 }
716
717 struct platform_driver vop2_platform_driver = {
718 .probe = vop2_probe,
719 .remove = vop2_remove,
720 .driver = {
721 .name = "rockchip-vop2",
722 .of_match_table = vop2_dt_match,
723 },
724 };
725