xref: /openbmc/linux/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1604be855SAndy Yan // SPDX-License-Identifier: GPL-2.0-only
2604be855SAndy Yan /*
3604be855SAndy Yan  * Copyright (C) Rockchip Electronics Co.Ltd
4604be855SAndy Yan  * Author: Andy Yan <andy.yan@rock-chips.com>
5604be855SAndy Yan  */
6604be855SAndy Yan 
7604be855SAndy Yan #include <linux/kernel.h>
8604be855SAndy Yan #include <linux/component.h>
9604be855SAndy Yan #include <linux/mod_devicetable.h>
10604be855SAndy Yan #include <linux/platform_device.h>
11604be855SAndy Yan #include <linux/of.h>
12604be855SAndy Yan #include <drm/drm_fourcc.h>
13604be855SAndy Yan #include <drm/drm_plane.h>
14604be855SAndy Yan #include <drm/drm_print.h>
15604be855SAndy Yan 
16604be855SAndy Yan #include "rockchip_drm_vop2.h"
17604be855SAndy Yan 
18604be855SAndy Yan static const uint32_t formats_win_full_10bit[] = {
19604be855SAndy Yan 	DRM_FORMAT_XRGB8888,
20604be855SAndy Yan 	DRM_FORMAT_ARGB8888,
21604be855SAndy Yan 	DRM_FORMAT_XBGR8888,
22604be855SAndy Yan 	DRM_FORMAT_ABGR8888,
23604be855SAndy Yan 	DRM_FORMAT_RGB888,
24604be855SAndy Yan 	DRM_FORMAT_BGR888,
25604be855SAndy Yan 	DRM_FORMAT_RGB565,
26604be855SAndy Yan 	DRM_FORMAT_BGR565,
27604be855SAndy Yan 	DRM_FORMAT_NV12,
28604be855SAndy Yan 	DRM_FORMAT_NV16,
29604be855SAndy Yan 	DRM_FORMAT_NV24,
30604be855SAndy Yan };
31604be855SAndy Yan 
32604be855SAndy Yan static const uint32_t formats_win_full_10bit_yuyv[] = {
33604be855SAndy Yan 	DRM_FORMAT_XRGB8888,
34604be855SAndy Yan 	DRM_FORMAT_ARGB8888,
35604be855SAndy Yan 	DRM_FORMAT_XBGR8888,
36604be855SAndy Yan 	DRM_FORMAT_ABGR8888,
37604be855SAndy Yan 	DRM_FORMAT_RGB888,
38604be855SAndy Yan 	DRM_FORMAT_BGR888,
39604be855SAndy Yan 	DRM_FORMAT_RGB565,
40604be855SAndy Yan 	DRM_FORMAT_BGR565,
41604be855SAndy Yan 	DRM_FORMAT_NV12,
42604be855SAndy Yan 	DRM_FORMAT_NV16,
43604be855SAndy Yan 	DRM_FORMAT_NV24,
44604be855SAndy Yan 	DRM_FORMAT_YVYU,
45604be855SAndy Yan 	DRM_FORMAT_VYUY,
46604be855SAndy Yan };
47604be855SAndy Yan 
48604be855SAndy Yan static const uint32_t formats_win_lite[] = {
49604be855SAndy Yan 	DRM_FORMAT_XRGB8888,
50604be855SAndy Yan 	DRM_FORMAT_ARGB8888,
51604be855SAndy Yan 	DRM_FORMAT_XBGR8888,
52604be855SAndy Yan 	DRM_FORMAT_ABGR8888,
53604be855SAndy Yan 	DRM_FORMAT_RGB888,
54604be855SAndy Yan 	DRM_FORMAT_BGR888,
55604be855SAndy Yan 	DRM_FORMAT_RGB565,
56604be855SAndy Yan 	DRM_FORMAT_BGR565,
57604be855SAndy Yan };
58604be855SAndy Yan 
59604be855SAndy Yan static const uint64_t format_modifiers[] = {
60604be855SAndy Yan 	DRM_FORMAT_MOD_LINEAR,
61604be855SAndy Yan 	DRM_FORMAT_MOD_INVALID,
62604be855SAndy Yan };
63604be855SAndy Yan 
64604be855SAndy Yan static const uint64_t format_modifiers_afbc[] = {
65604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16),
66604be855SAndy Yan 
67604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
68604be855SAndy Yan 				AFBC_FORMAT_MOD_SPARSE),
69604be855SAndy Yan 
70604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
71604be855SAndy Yan 				AFBC_FORMAT_MOD_YTR),
72604be855SAndy Yan 
73604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
74604be855SAndy Yan 				AFBC_FORMAT_MOD_CBR),
75604be855SAndy Yan 
76604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
77604be855SAndy Yan 				AFBC_FORMAT_MOD_YTR |
78604be855SAndy Yan 				AFBC_FORMAT_MOD_SPARSE),
79604be855SAndy Yan 
80604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
81604be855SAndy Yan 				AFBC_FORMAT_MOD_CBR |
82604be855SAndy Yan 				AFBC_FORMAT_MOD_SPARSE),
83604be855SAndy Yan 
84604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
85604be855SAndy Yan 				AFBC_FORMAT_MOD_YTR |
86604be855SAndy Yan 				AFBC_FORMAT_MOD_CBR),
87604be855SAndy Yan 
88604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
89604be855SAndy Yan 				AFBC_FORMAT_MOD_YTR |
90604be855SAndy Yan 				AFBC_FORMAT_MOD_CBR |
91604be855SAndy Yan 				AFBC_FORMAT_MOD_SPARSE),
92604be855SAndy Yan 
93604be855SAndy Yan 	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
94604be855SAndy Yan 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
95604be855SAndy Yan 				AFBC_FORMAT_MOD_YTR |
96604be855SAndy Yan 				AFBC_FORMAT_MOD_SPARSE |
97604be855SAndy Yan 				AFBC_FORMAT_MOD_SPLIT),
98604be855SAndy Yan 	DRM_FORMAT_MOD_INVALID,
99604be855SAndy Yan };
100604be855SAndy Yan 
101604be855SAndy Yan static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
102604be855SAndy Yan 	{
103604be855SAndy Yan 		.id = 0,
104604be855SAndy Yan 		.feature = VOP_FEATURE_OUTPUT_10BIT,
105604be855SAndy Yan 		.gamma_lut_len = 1024,
106604be855SAndy Yan 		.cubic_lut_len = 9 * 9 * 9,
107604be855SAndy Yan 		.max_output = { 4096, 2304 },
108604be855SAndy Yan 		.pre_scan_max_dly = { 69, 53, 53, 42 },
109604be855SAndy Yan 		.offset = 0xc00,
110604be855SAndy Yan 	}, {
111604be855SAndy Yan 		.id = 1,
112604be855SAndy Yan 		.gamma_lut_len = 1024,
113604be855SAndy Yan 		.max_output = { 2048, 1536 },
114604be855SAndy Yan 		.pre_scan_max_dly = { 40, 40, 40, 40 },
115604be855SAndy Yan 		.offset = 0xd00,
116604be855SAndy Yan 	}, {
117604be855SAndy Yan 		.id = 2,
118604be855SAndy Yan 		.gamma_lut_len = 1024,
119604be855SAndy Yan 		.max_output = { 1920, 1080 },
120604be855SAndy Yan 		.pre_scan_max_dly = { 40, 40, 40, 40 },
121604be855SAndy Yan 		.offset = 0xe00,
122604be855SAndy Yan 	},
123604be855SAndy Yan };
124604be855SAndy Yan 
125604be855SAndy Yan /*
126604be855SAndy Yan  * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win.
127604be855SAndy Yan  * Every cluster can work as 4K win or split into two win.
128604be855SAndy Yan  * All win in cluster support AFBCD.
129604be855SAndy Yan  *
130604be855SAndy Yan  * Every esmart win and smart win support 4 Multi-region.
131604be855SAndy Yan  *
132604be855SAndy Yan  * Scale filter mode:
133604be855SAndy Yan  *
134604be855SAndy Yan  * * Cluster:  bicubic for horizontal scale up, others use bilinear
135604be855SAndy Yan  * * ESmart:
136604be855SAndy Yan  *    * nearest-neighbor/bilinear/bicubic for scale up
137604be855SAndy Yan  *    * nearest-neighbor/bilinear/average for scale down
138604be855SAndy Yan  *
139604be855SAndy Yan  *
140604be855SAndy Yan  * @TODO describe the wind like cpu-map dt nodes;
141604be855SAndy Yan  */
142604be855SAndy Yan static const struct vop2_win_data rk3568_vop_win_data[] = {
143604be855SAndy Yan 	{
144604be855SAndy Yan 		.name = "Smart0-win0",
145604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_SMART0,
146604be855SAndy Yan 		.base = 0x1c00,
147604be855SAndy Yan 		.formats = formats_win_lite,
148604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_lite),
149604be855SAndy Yan 		.format_modifiers = format_modifiers,
150604be855SAndy Yan 		.layer_sel_id = 3,
151604be855SAndy Yan 		.supported_rotations = DRM_MODE_REFLECT_Y,
152604be855SAndy Yan 		.type = DRM_PLANE_TYPE_PRIMARY,
153604be855SAndy Yan 		.max_upscale_factor = 8,
154604be855SAndy Yan 		.max_downscale_factor = 8,
155604be855SAndy Yan 		.dly = { 20, 47, 41 },
156604be855SAndy Yan 	}, {
157604be855SAndy Yan 		.name = "Smart1-win0",
158604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_SMART1,
159604be855SAndy Yan 		.formats = formats_win_lite,
160604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_lite),
161604be855SAndy Yan 		.format_modifiers = format_modifiers,
162604be855SAndy Yan 		.base = 0x1e00,
163604be855SAndy Yan 		.layer_sel_id = 7,
164604be855SAndy Yan 		.supported_rotations = DRM_MODE_REFLECT_Y,
165604be855SAndy Yan 		.type = DRM_PLANE_TYPE_PRIMARY,
166604be855SAndy Yan 		.max_upscale_factor = 8,
167604be855SAndy Yan 		.max_downscale_factor = 8,
168604be855SAndy Yan 		.dly = { 20, 47, 41 },
169604be855SAndy Yan 	}, {
170604be855SAndy Yan 		.name = "Esmart1-win0",
171604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_ESMART1,
172604be855SAndy Yan 		.formats = formats_win_full_10bit_yuyv,
173604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
174604be855SAndy Yan 		.format_modifiers = format_modifiers,
175604be855SAndy Yan 		.base = 0x1a00,
176604be855SAndy Yan 		.layer_sel_id = 6,
177604be855SAndy Yan 		.supported_rotations = DRM_MODE_REFLECT_Y,
178604be855SAndy Yan 		.type = DRM_PLANE_TYPE_PRIMARY,
179604be855SAndy Yan 		.max_upscale_factor = 8,
180604be855SAndy Yan 		.max_downscale_factor = 8,
181604be855SAndy Yan 		.dly = { 20, 47, 41 },
182604be855SAndy Yan 	}, {
183604be855SAndy Yan 		.name = "Esmart0-win0",
184604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_ESMART0,
185604be855SAndy Yan 		.formats = formats_win_full_10bit_yuyv,
186604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
187604be855SAndy Yan 		.format_modifiers = format_modifiers,
188604be855SAndy Yan 		.base = 0x1800,
189604be855SAndy Yan 		.layer_sel_id = 2,
190604be855SAndy Yan 		.supported_rotations = DRM_MODE_REFLECT_Y,
191de4a4c8fSSascha Hauer 		.type = DRM_PLANE_TYPE_PRIMARY,
192604be855SAndy Yan 		.max_upscale_factor = 8,
193604be855SAndy Yan 		.max_downscale_factor = 8,
194604be855SAndy Yan 		.dly = { 20, 47, 41 },
195604be855SAndy Yan 	}, {
196604be855SAndy Yan 		.name = "Cluster0-win0",
197604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
198604be855SAndy Yan 		.base = 0x1000,
199604be855SAndy Yan 		.formats = formats_win_full_10bit,
200604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_full_10bit),
201604be855SAndy Yan 		.format_modifiers = format_modifiers_afbc,
202604be855SAndy Yan 		.layer_sel_id = 0,
203604be855SAndy Yan 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
204604be855SAndy Yan 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
205604be855SAndy Yan 		.max_upscale_factor = 4,
206604be855SAndy Yan 		.max_downscale_factor = 4,
207604be855SAndy Yan 		.dly = { 0, 27, 21 },
208604be855SAndy Yan 		.type = DRM_PLANE_TYPE_OVERLAY,
209604be855SAndy Yan 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
210604be855SAndy Yan 	}, {
211604be855SAndy Yan 		.name = "Cluster1-win0",
212604be855SAndy Yan 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
213604be855SAndy Yan 		.base = 0x1200,
214604be855SAndy Yan 		.formats = formats_win_full_10bit,
215604be855SAndy Yan 		.nformats = ARRAY_SIZE(formats_win_full_10bit),
216604be855SAndy Yan 		.format_modifiers = format_modifiers_afbc,
217604be855SAndy Yan 		.layer_sel_id = 1,
218604be855SAndy Yan 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
219604be855SAndy Yan 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
220604be855SAndy Yan 		.type = DRM_PLANE_TYPE_OVERLAY,
221604be855SAndy Yan 		.max_upscale_factor = 4,
222604be855SAndy Yan 		.max_downscale_factor = 4,
223604be855SAndy Yan 		.dly = { 0, 27, 21 },
224604be855SAndy Yan 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
225604be855SAndy Yan 	},
226604be855SAndy Yan };
227604be855SAndy Yan 
228604be855SAndy Yan static const struct vop2_data rk3566_vop = {
229604be855SAndy Yan 	.nr_vps = 3,
230604be855SAndy Yan 	.max_input = { 4096, 2304 },
231604be855SAndy Yan 	.max_output = { 4096, 2304 },
232604be855SAndy Yan 	.vp = rk3568_vop_video_ports,
233604be855SAndy Yan 	.win = rk3568_vop_win_data,
234604be855SAndy Yan 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
235604be855SAndy Yan 	.soc_id = 3566,
236604be855SAndy Yan };
237604be855SAndy Yan 
238604be855SAndy Yan static const struct vop2_data rk3568_vop = {
239604be855SAndy Yan 	.nr_vps = 3,
240604be855SAndy Yan 	.max_input = { 4096, 2304 },
241604be855SAndy Yan 	.max_output = { 4096, 2304 },
242604be855SAndy Yan 	.vp = rk3568_vop_video_ports,
243604be855SAndy Yan 	.win = rk3568_vop_win_data,
244604be855SAndy Yan 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
245604be855SAndy Yan 	.soc_id = 3568,
246604be855SAndy Yan };
247604be855SAndy Yan 
248604be855SAndy Yan static const struct of_device_id vop2_dt_match[] = {
249604be855SAndy Yan 	{
250604be855SAndy Yan 		.compatible = "rockchip,rk3566-vop",
251604be855SAndy Yan 		.data = &rk3566_vop,
252604be855SAndy Yan 	}, {
253604be855SAndy Yan 		.compatible = "rockchip,rk3568-vop",
254604be855SAndy Yan 		.data = &rk3568_vop,
255604be855SAndy Yan 	}, {
256604be855SAndy Yan 	},
257604be855SAndy Yan };
258604be855SAndy Yan MODULE_DEVICE_TABLE(of, vop2_dt_match);
259604be855SAndy Yan 
vop2_probe(struct platform_device * pdev)260604be855SAndy Yan static int vop2_probe(struct platform_device *pdev)
261604be855SAndy Yan {
262604be855SAndy Yan 	struct device *dev = &pdev->dev;
263604be855SAndy Yan 
264604be855SAndy Yan 	return component_add(dev, &vop2_component_ops);
265604be855SAndy Yan }
266604be855SAndy Yan 
vop2_remove(struct platform_device * pdev)267*3c855610SUwe Kleine-König static void vop2_remove(struct platform_device *pdev)
268604be855SAndy Yan {
269604be855SAndy Yan 	component_del(&pdev->dev, &vop2_component_ops);
270604be855SAndy Yan }
271604be855SAndy Yan 
272604be855SAndy Yan struct platform_driver vop2_platform_driver = {
273604be855SAndy Yan 	.probe = vop2_probe,
274*3c855610SUwe Kleine-König 	.remove_new = vop2_remove,
275604be855SAndy Yan 	.driver = {
276604be855SAndy Yan 		.name = "rockchip-vop2",
277604be855SAndy Yan 		.of_match_table = of_match_ptr(vop2_dt_match),
278604be855SAndy Yan 	},
279604be855SAndy Yan };
280