Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  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
 18static 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
 35static 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
 59static 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
 81static 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
 92static const uint64_t format_modifiers[] = {
 93	DRM_FORMAT_MOD_LINEAR,
 94	DRM_FORMAT_MOD_INVALID,
 95};
 96
 97static 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
134static 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 */
175static 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
261static 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 */
325static 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
465static 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
476static 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
487static 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
499static 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};
512MODULE_DEVICE_TABLE(of, vop2_dt_match);
513
514static 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
521static void vop2_remove(struct platform_device *pdev)
522{
523	component_del(&pdev->dev, &vop2_component_ops);
524}
525
526struct platform_driver vop2_platform_driver = {
527	.probe = vop2_probe,
528	.remove = vop2_remove,
529	.driver = {
530		.name = "rockchip-vop2",
531		.of_match_table = vop2_dt_match,
532	},
533};