xref: /linux/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
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