• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_video_port_data rk3588_vop_video_ports[] = {
262 	{
263 		.id = 0,
264 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
265 		.gamma_lut_len = 1024,
266 		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
267 		.max_output = { 4096, 2304 },
268 		/* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */
269 		.pre_scan_max_dly = { 76, 65, 65, 54 },
270 		.offset = 0xc00,
271 	}, {
272 		.id = 1,
273 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
274 		.gamma_lut_len = 1024,
275 		.cubic_lut_len = 729, /* 9x9x9 */
276 		.max_output = { 4096, 2304 },
277 		.pre_scan_max_dly = { 76, 65, 65, 54 },
278 		.offset = 0xd00,
279 	}, {
280 		.id = 2,
281 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
282 		.gamma_lut_len = 1024,
283 		.cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */
284 		.max_output = { 4096, 2304 },
285 		.pre_scan_max_dly = { 52, 52, 52, 52 },
286 		.offset = 0xe00,
287 	}, {
288 		.id = 3,
289 		.gamma_lut_len = 1024,
290 		.max_output = { 2048, 1536 },
291 		.pre_scan_max_dly = { 52, 52, 52, 52 },
292 		.offset = 0xf00,
293 	},
294 };
295 
296 /*
297  * rk3588 vop with 4 cluster, 4 esmart win.
298  * Every cluster can work as 4K win or split into two win.
299  * All win in cluster support AFBCD.
300  *
301  * Every esmart win and smart win support 4 Multi-region.
302  *
303  * Scale filter mode:
304  *
305  * * Cluster:  bicubic for horizontal scale up, others use bilinear
306  * * ESmart:
307  *    * nearest-neighbor/bilinear/bicubic for scale up
308  *    * nearest-neighbor/bilinear/average for scale down
309  *
310  * AXI Read ID assignment:
311  * Two AXI bus:
312  * AXI0 is a read/write bus with a higher performance.
313  * AXI1 is a read only bus.
314  *
315  * Every window on a AXI bus must assigned two unique
316  * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
317  *
318  * AXI0:
319  * Cluster0/1, Esmart0/1, WriteBack
320  *
321  * AXI 1:
322  * Cluster2/3, Esmart2/3
323  *
324  */
325 static const struct vop2_win_data rk3588_vop_win_data[] = {
326 	{
327 		.name = "Cluster0-win0",
328 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
329 		.base = 0x1000,
330 		.formats = formats_cluster,
331 		.nformats = ARRAY_SIZE(formats_cluster),
332 		.format_modifiers = format_modifiers_afbc,
333 		.layer_sel_id = 0,
334 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
335 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
336 		.axi_bus_id = 0,
337 		.axi_yrgb_r_id = 2,
338 		.axi_uv_r_id = 3,
339 		.max_upscale_factor = 4,
340 		.max_downscale_factor = 4,
341 		.dly = { 4, 26, 29 },
342 		.type = DRM_PLANE_TYPE_PRIMARY,
343 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
344 	}, {
345 		.name = "Cluster1-win0",
346 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
347 		.base = 0x1200,
348 		.formats = formats_cluster,
349 		.nformats = ARRAY_SIZE(formats_cluster),
350 		.format_modifiers = format_modifiers_afbc,
351 		.layer_sel_id = 1,
352 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
353 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
354 		.type = DRM_PLANE_TYPE_PRIMARY,
355 		.axi_bus_id = 0,
356 		.axi_yrgb_r_id = 6,
357 		.axi_uv_r_id = 7,
358 		.max_upscale_factor = 4,
359 		.max_downscale_factor = 4,
360 		.dly = { 4, 26, 29 },
361 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
362 	}, {
363 		.name = "Cluster2-win0",
364 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
365 		.base = 0x1400,
366 		.formats = formats_cluster,
367 		.nformats = ARRAY_SIZE(formats_cluster),
368 		.format_modifiers = format_modifiers_afbc,
369 		.layer_sel_id = 4,
370 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
371 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
372 		.type = DRM_PLANE_TYPE_PRIMARY,
373 		.axi_bus_id = 1,
374 		.axi_yrgb_r_id = 2,
375 		.axi_uv_r_id = 3,
376 		.max_upscale_factor = 4,
377 		.max_downscale_factor = 4,
378 		.dly = { 4, 26, 29 },
379 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
380 	}, {
381 		.name = "Cluster3-win0",
382 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
383 		.base = 0x1600,
384 		.formats = formats_cluster,
385 		.nformats = ARRAY_SIZE(formats_cluster),
386 		.format_modifiers = format_modifiers_afbc,
387 		.layer_sel_id = 5,
388 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
389 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
390 		.type = DRM_PLANE_TYPE_PRIMARY,
391 		.axi_bus_id = 1,
392 		.axi_yrgb_r_id = 6,
393 		.axi_uv_r_id = 7,
394 		.max_upscale_factor = 4,
395 		.max_downscale_factor = 4,
396 		.dly = { 4, 26, 29 },
397 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
398 	}, {
399 		.name = "Esmart0-win0",
400 		.phys_id = ROCKCHIP_VOP2_ESMART0,
401 		.formats = formats_esmart,
402 		.nformats = ARRAY_SIZE(formats_esmart),
403 		.format_modifiers = format_modifiers,
404 		.base = 0x1800,
405 		.layer_sel_id = 2,
406 		.supported_rotations = DRM_MODE_REFLECT_Y,
407 		.type = DRM_PLANE_TYPE_OVERLAY,
408 		.axi_bus_id = 0,
409 		.axi_yrgb_r_id = 0x0a,
410 		.axi_uv_r_id = 0x0b,
411 		.max_upscale_factor = 8,
412 		.max_downscale_factor = 8,
413 		.dly = { 23, 45, 48 },
414 	}, {
415 		.name = "Esmart1-win0",
416 		.phys_id = ROCKCHIP_VOP2_ESMART1,
417 		.formats = formats_esmart,
418 		.nformats = ARRAY_SIZE(formats_esmart),
419 		.format_modifiers = format_modifiers,
420 		.base = 0x1a00,
421 		.layer_sel_id = 3,
422 		.supported_rotations = DRM_MODE_REFLECT_Y,
423 		.type = DRM_PLANE_TYPE_OVERLAY,
424 		.axi_bus_id = 0,
425 		.axi_yrgb_r_id = 0x0c,
426 		.axi_uv_r_id = 0x01,
427 		.max_upscale_factor = 8,
428 		.max_downscale_factor = 8,
429 		.dly = { 23, 45, 48 },
430 	}, {
431 		.name = "Esmart2-win0",
432 		.phys_id = ROCKCHIP_VOP2_ESMART2,
433 		.base = 0x1c00,
434 		.formats = formats_esmart,
435 		.nformats = ARRAY_SIZE(formats_esmart),
436 		.format_modifiers = format_modifiers,
437 		.layer_sel_id = 6,
438 		.supported_rotations = DRM_MODE_REFLECT_Y,
439 		.type = DRM_PLANE_TYPE_OVERLAY,
440 		.axi_bus_id = 1,
441 		.axi_yrgb_r_id = 0x0a,
442 		.axi_uv_r_id = 0x0b,
443 		.max_upscale_factor = 8,
444 		.max_downscale_factor = 8,
445 		.dly = { 23, 45, 48 },
446 	}, {
447 		.name = "Esmart3-win0",
448 		.phys_id = ROCKCHIP_VOP2_ESMART3,
449 		.formats = formats_esmart,
450 		.nformats = ARRAY_SIZE(formats_esmart),
451 		.format_modifiers = format_modifiers,
452 		.base = 0x1e00,
453 		.layer_sel_id = 7,
454 		.supported_rotations = DRM_MODE_REFLECT_Y,
455 		.type = DRM_PLANE_TYPE_OVERLAY,
456 		.axi_bus_id = 1,
457 		.axi_yrgb_r_id = 0x0c,
458 		.axi_uv_r_id = 0x0d,
459 		.max_upscale_factor = 8,
460 		.max_downscale_factor = 8,
461 		.dly = { 23, 45, 48 },
462 	},
463 };
464 
465 static const struct vop2_data rk3566_vop = {
466 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
467 	.nr_vps = 3,
468 	.max_input = { 4096, 2304 },
469 	.max_output = { 4096, 2304 },
470 	.vp = rk3568_vop_video_ports,
471 	.win = rk3568_vop_win_data,
472 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
473 	.soc_id = 3566,
474 };
475 
476 static const struct vop2_data rk3568_vop = {
477 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
478 	.nr_vps = 3,
479 	.max_input = { 4096, 2304 },
480 	.max_output = { 4096, 2304 },
481 	.vp = rk3568_vop_video_ports,
482 	.win = rk3568_vop_win_data,
483 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
484 	.soc_id = 3568,
485 };
486 
487 static const struct vop2_data rk3588_vop = {
488 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
489 		   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
490 	.nr_vps = 4,
491 	.max_input = { 4096, 4320 },
492 	.max_output = { 4096, 4320 },
493 	.vp = rk3588_vop_video_ports,
494 	.win = rk3588_vop_win_data,
495 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
496 	.soc_id = 3588,
497 };
498 
499 static const struct of_device_id vop2_dt_match[] = {
500 	{
501 		.compatible = "rockchip,rk3566-vop",
502 		.data = &rk3566_vop,
503 	}, {
504 		.compatible = "rockchip,rk3568-vop",
505 		.data = &rk3568_vop,
506 	}, {
507 		.compatible = "rockchip,rk3588-vop",
508 		.data = &rk3588_vop
509 	}, {
510 	},
511 };
512 MODULE_DEVICE_TABLE(of, vop2_dt_match);
513 
vop2_probe(struct platform_device * pdev)514 static int vop2_probe(struct platform_device *pdev)
515 {
516 	struct device *dev = &pdev->dev;
517 
518 	return component_add(dev, &vop2_component_ops);
519 }
520 
vop2_remove(struct platform_device * pdev)521 static void vop2_remove(struct platform_device *pdev)
522 {
523 	component_del(&pdev->dev, &vop2_component_ops);
524 }
525 
526 struct platform_driver vop2_platform_driver = {
527 	.probe = vop2_probe,
528 	.remove_new = vop2_remove,
529 	.driver = {
530 		.name = "rockchip-vop2",
531 		.of_match_table = vop2_dt_match,
532 	},
533 };
534