xref: /linux/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c (revision 3f1c07fc21c68bd3bd2df9d2c9441f6485e934d9)
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/bitfield.h>
8 #include <linux/kernel.h>
9 #include <linux/component.h>
10 #include <linux/hw_bitfield.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/platform_device.h>
13 #include <linux/of.h>
14 #include <drm/drm_blend.h>
15 #include <drm/drm_fourcc.h>
16 #include <drm/drm_framebuffer.h>
17 #include <drm/drm_plane.h>
18 #include <drm/drm_print.h>
19 
20 #include "rockchip_drm_vop2.h"
21 
22 union vop2_alpha_ctrl {
23 	u32 val;
24 	struct {
25 		/* [0:1] */
26 		u32 color_mode:1;
27 		u32 alpha_mode:1;
28 		/* [2:3] */
29 		u32 blend_mode:2;
30 		u32 alpha_cal_mode:1;
31 		/* [5:7] */
32 		u32 factor_mode:3;
33 		/* [8:9] */
34 		u32 alpha_en:1;
35 		u32 src_dst_swap:1;
36 		u32 reserved:6;
37 		/* [16:23] */
38 		u32 glb_alpha:8;
39 	} bits;
40 };
41 
42 struct vop2_alpha {
43 	union vop2_alpha_ctrl src_color_ctrl;
44 	union vop2_alpha_ctrl dst_color_ctrl;
45 	union vop2_alpha_ctrl src_alpha_ctrl;
46 	union vop2_alpha_ctrl dst_alpha_ctrl;
47 };
48 
49 struct vop2_alpha_config {
50 	bool src_premulti_en;
51 	bool dst_premulti_en;
52 	bool src_pixel_alpha_en;
53 	bool dst_pixel_alpha_en;
54 	u16 src_glb_alpha_value;
55 	u16 dst_glb_alpha_value;
56 };
57 
58 static const uint32_t formats_cluster[] = {
59 	DRM_FORMAT_XRGB2101010,
60 	DRM_FORMAT_XBGR2101010,
61 	DRM_FORMAT_XRGB8888,
62 	DRM_FORMAT_ARGB8888,
63 	DRM_FORMAT_XBGR8888,
64 	DRM_FORMAT_ABGR8888,
65 	DRM_FORMAT_RGB888,
66 	DRM_FORMAT_BGR888,
67 	DRM_FORMAT_RGB565,
68 	DRM_FORMAT_BGR565,
69 	DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */
70 	DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */
71 	DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/
72 	DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
73 };
74 
75 /*
76  * The cluster windows on rk3576 support:
77  * RGB: linear mode and afbc
78  * YUV: linear mode and rfbc
79  * rfbc is a rockchip defined non-linear mode, produced by
80  * Video decoder
81  */
82 static const uint32_t formats_rk3576_cluster[] = {
83 	DRM_FORMAT_XRGB2101010,
84 	DRM_FORMAT_XBGR2101010,
85 	DRM_FORMAT_ARGB2101010,
86 	DRM_FORMAT_ABGR2101010,
87 	DRM_FORMAT_XRGB8888,
88 	DRM_FORMAT_ARGB8888,
89 	DRM_FORMAT_XBGR8888,
90 	DRM_FORMAT_ABGR8888,
91 	DRM_FORMAT_RGB888,
92 	DRM_FORMAT_BGR888,
93 	DRM_FORMAT_RGB565,
94 	DRM_FORMAT_BGR565,
95 	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
96 	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
97 	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
98 	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
99 	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
100 	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
101 	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
102 	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
103 	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
104 };
105 
106 static const uint32_t formats_esmart[] = {
107 	DRM_FORMAT_XRGB8888,
108 	DRM_FORMAT_ARGB8888,
109 	DRM_FORMAT_XBGR8888,
110 	DRM_FORMAT_ABGR8888,
111 	DRM_FORMAT_RGB888,
112 	DRM_FORMAT_BGR888,
113 	DRM_FORMAT_RGB565,
114 	DRM_FORMAT_BGR565,
115 	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
116 	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
117 	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
118 	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
119 	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
120 	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
121 	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
122 	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
123 	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
124 	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
125 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
126 	DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
127 	DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
128 };
129 
130 static const uint32_t formats_rk356x_esmart[] = {
131 	DRM_FORMAT_XRGB8888,
132 	DRM_FORMAT_ARGB8888,
133 	DRM_FORMAT_XBGR8888,
134 	DRM_FORMAT_ABGR8888,
135 	DRM_FORMAT_RGB888,
136 	DRM_FORMAT_BGR888,
137 	DRM_FORMAT_RGB565,
138 	DRM_FORMAT_BGR565,
139 	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
140 	DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */
141 	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
142 	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
143 	DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */
144 	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
145 	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
146 	DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */
147 	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
148 	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
149 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
150 };
151 
152 /*
153  * Add XRGB2101010/ARGB2101010ARGB1555/XRGB1555
154  */
155 static const uint32_t formats_rk3576_esmart[] = {
156 	DRM_FORMAT_XRGB2101010,
157 	DRM_FORMAT_XBGR2101010,
158 	DRM_FORMAT_ARGB2101010,
159 	DRM_FORMAT_ABGR2101010,
160 	DRM_FORMAT_XRGB8888,
161 	DRM_FORMAT_ARGB8888,
162 	DRM_FORMAT_XBGR8888,
163 	DRM_FORMAT_ABGR8888,
164 	DRM_FORMAT_RGB888,
165 	DRM_FORMAT_BGR888,
166 	DRM_FORMAT_RGB565,
167 	DRM_FORMAT_BGR565,
168 	DRM_FORMAT_ARGB1555,
169 	DRM_FORMAT_ABGR1555,
170 	DRM_FORMAT_XRGB1555,
171 	DRM_FORMAT_XBGR1555,
172 	DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
173 	DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */
174 	DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
175 	DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */
176 	DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */
177 	DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
178 	DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */
179 	DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */
180 	DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
181 	DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
182 	DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
183 	DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */
184 	DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */
185 };
186 
187 static const uint32_t formats_smart[] = {
188 	DRM_FORMAT_XRGB8888,
189 	DRM_FORMAT_ARGB8888,
190 	DRM_FORMAT_XBGR8888,
191 	DRM_FORMAT_ABGR8888,
192 	DRM_FORMAT_RGB888,
193 	DRM_FORMAT_BGR888,
194 	DRM_FORMAT_RGB565,
195 	DRM_FORMAT_BGR565,
196 };
197 
198 static const uint64_t format_modifiers[] = {
199 	DRM_FORMAT_MOD_LINEAR,
200 	DRM_FORMAT_MOD_INVALID,
201 };
202 
203 static const uint64_t format_modifiers_afbc[] = {
204 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16),
205 
206 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
207 				AFBC_FORMAT_MOD_SPARSE),
208 
209 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
210 				AFBC_FORMAT_MOD_YTR),
211 
212 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
213 				AFBC_FORMAT_MOD_CBR),
214 
215 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
216 				AFBC_FORMAT_MOD_YTR |
217 				AFBC_FORMAT_MOD_SPARSE),
218 
219 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
220 				AFBC_FORMAT_MOD_CBR |
221 				AFBC_FORMAT_MOD_SPARSE),
222 
223 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
224 				AFBC_FORMAT_MOD_YTR |
225 				AFBC_FORMAT_MOD_CBR),
226 
227 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
228 				AFBC_FORMAT_MOD_YTR |
229 				AFBC_FORMAT_MOD_CBR |
230 				AFBC_FORMAT_MOD_SPARSE),
231 
232 	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
233 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
234 				AFBC_FORMAT_MOD_YTR |
235 				AFBC_FORMAT_MOD_SPARSE |
236 				AFBC_FORMAT_MOD_SPLIT),
237 	DRM_FORMAT_MOD_INVALID,
238 };
239 
240 /* used from rk3576, afbc 32*8 half mode */
241 static const uint64_t format_modifiers_rk3576_afbc[] = {
242 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
243 				AFBC_FORMAT_MOD_SPLIT),
244 
245 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
246 				AFBC_FORMAT_MOD_SPARSE |
247 				AFBC_FORMAT_MOD_SPLIT),
248 
249 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
250 				AFBC_FORMAT_MOD_YTR |
251 				AFBC_FORMAT_MOD_SPLIT),
252 
253 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
254 				AFBC_FORMAT_MOD_CBR |
255 				AFBC_FORMAT_MOD_SPLIT),
256 
257 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
258 				AFBC_FORMAT_MOD_CBR |
259 				AFBC_FORMAT_MOD_SPARSE |
260 				AFBC_FORMAT_MOD_SPLIT),
261 
262 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
263 				AFBC_FORMAT_MOD_YTR |
264 				AFBC_FORMAT_MOD_CBR |
265 				AFBC_FORMAT_MOD_SPLIT),
266 
267 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
268 				AFBC_FORMAT_MOD_YTR |
269 				AFBC_FORMAT_MOD_CBR |
270 				AFBC_FORMAT_MOD_SPARSE |
271 				AFBC_FORMAT_MOD_SPLIT),
272 
273 	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
274 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
275 				AFBC_FORMAT_MOD_YTR |
276 				AFBC_FORMAT_MOD_SPARSE |
277 				AFBC_FORMAT_MOD_SPLIT),
278 	DRM_FORMAT_MOD_LINEAR,
279 	DRM_FORMAT_MOD_INVALID,
280 };
281 
282 static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
283 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
284 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
285 	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
286 	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
287 	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
288 	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
289 	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
290 	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
291 	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
292 	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
293 	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
294 	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
295 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
296 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
297 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
298 	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
299 	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
300 	/* RK3588 only, reserved bit on rk3568*/
301 	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
302 
303 	/* Scale */
304 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
305 	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
306 	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
307 	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
308 	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
309 	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
310 	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
311 
312 	/* cluster regs */
313 	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
314 	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
315 	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
316 
317 	/* afbc regs */
318 	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
319 	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
320 	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
321 	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
322 	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
323 	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
324 	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
325 	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
326 	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
327 	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
328 	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
329 	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
330 	[VOP2_WIN_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_TRANSFORM_OFFSET, 0, 31),
331 	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
332 	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
333 	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
334 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
335 	[VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
336 	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
337 	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
338 	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
339 	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
340 	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
341 	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
342 	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
343 	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
344 	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
345 	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
346 	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
347 	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
348 };
349 
350 static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = {
351 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
352 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
353 	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
354 	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
355 	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
356 	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
357 	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
358 	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
359 	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
360 	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
361 	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
362 	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
363 	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
364 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
365 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
366 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
367 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
368 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
369 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
370 	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
371 	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
372 	/* RK3588 only, reserved register on rk3568 */
373 	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
374 
375 	/* Scale */
376 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
377 	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
378 	[VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
379 	[VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
380 	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
381 	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
382 	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
383 	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
384 	[VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
385 	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
386 	[VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
387 	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
388 	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
389 	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
390 	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
391 	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
392 	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
393 	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
394 	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
395 	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
396 	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
397 	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
398 	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
399 	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
400 	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
401 	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
402 	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
403 	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
404 	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
405 	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
406 	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
407 	[VOP2_WIN_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
408 	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
409 	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
410 	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
411 	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
412 };
413 
414 static const struct reg_field rk3576_vop_cluster_regs[VOP2_WIN_MAX_REG] = {
415 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
416 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
417 	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
418 	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 17, 17),
419 	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
420 	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
421 	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
422 	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
423 	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
424 	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
425 	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
426 	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
427 	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
428 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
429 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
430 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
431 	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 4),
432 	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 9),
433 	/* Read only bit on rk3576, writing on this bit have no effect.*/
434 	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
435 
436 	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_CLUSTER_PORT_SEL_IMD, 0, 1),
437 	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_CLUSTER_DLY_NUM, 0, 7),
438 
439 	/* Scale */
440 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
441 	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
442 	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
443 	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
444 	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 22, 23),
445 	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
446 	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
447 
448 	/* cluster regs */
449 	[VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
450 	[VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
451 	[VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
452 
453 	/* afbc regs */
454 	[VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
455 	[VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
456 	[VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
457 	[VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
458 	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
459 	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
460 	[VOP2_WIN_AFBC_PLD_OFFSET_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 16, 16),
461 	[VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
462 	[VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
463 	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
464 	[VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
465 	[VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
466 	[VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
467 	[VOP2_WIN_AFBC_PLD_OFFSET] = REG_FIELD(RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET, 0, 31),
468 	[VOP2_WIN_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_TRANSFORM_OFFSET, 0, 31),
469 	[VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
470 	[VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
471 	[VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
472 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
473 	[VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
474 	[VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
475 	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
476 	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
477 	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
478 	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
479 	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
480 	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
481 	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
482 	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
483 	[VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
484 	[VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
485 };
486 
487 static const struct reg_field rk3576_vop_smart_regs[VOP2_WIN_MAX_REG] = {
488 	[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
489 	[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
490 	[VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
491 	[VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
492 	[VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
493 	[VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
494 	[VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
495 	[VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
496 	[VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
497 	[VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
498 	[VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
499 	[VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
500 	[VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
501 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
502 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
503 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
504 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
505 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
506 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
507 	[VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_SMART_PORT_SEL_IMD, 0, 1),
508 	[VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_SMART_DLY_NUM, 0, 7),
509 	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
510 	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
511 	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
512 
513 	/* Scale */
514 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
515 	[VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
516 	[VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
517 	[VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
518 	[VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
519 	[VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
520 	[VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
521 	[VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
522 	[VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
523 	[VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
524 	[VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
525 	[VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
526 
527 	/* CBCR share the same scale factor as YRGB */
528 	[VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
529 	[VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
530 	[VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
531 	[VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff},
532 	[VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff},
533 	[VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff},
534 
535 	[VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
536 	[VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
537 	[VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
538 	[VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
539 	[VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
540 	[VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
541 	[VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
542 	[VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
543 	[VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
544 	[VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
545 	[VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
546 	[VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
547 	[VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
548 	[VOP2_WIN_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
549 	[VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
550 	[VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
551 	[VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
552 	[VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
553 };
554 
555 static const struct vop2_video_port_data rk3568_vop_video_ports[] = {
556 	{
557 		.id = 0,
558 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
559 		.gamma_lut_len = 1024,
560 		.cubic_lut_len = 9 * 9 * 9,
561 		.max_output = { 4096, 2304 },
562 		.pre_scan_max_dly = { 69, 53, 53, 42 },
563 		.offset = 0xc00,
564 	}, {
565 		.id = 1,
566 		.gamma_lut_len = 1024,
567 		.max_output = { 2048, 1536 },
568 		.pre_scan_max_dly = { 40, 40, 40, 40 },
569 		.offset = 0xd00,
570 	}, {
571 		.id = 2,
572 		.gamma_lut_len = 1024,
573 		.max_output = { 1920, 1080 },
574 		.pre_scan_max_dly = { 40, 40, 40, 40 },
575 		.offset = 0xe00,
576 	},
577 };
578 
579 /*
580  * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win.
581  * Every cluster can work as 4K win or split into two win.
582  * All win in cluster support AFBCD.
583  *
584  * Every esmart win and smart win support 4 Multi-region.
585  *
586  * Scale filter mode:
587  *
588  * * Cluster:  bicubic for horizontal scale up, others use bilinear
589  * * ESmart:
590  *    * nearest-neighbor/bilinear/bicubic for scale up
591  *    * nearest-neighbor/bilinear/average for scale down
592  *
593  *
594  * @TODO describe the wind like cpu-map dt nodes;
595  */
596 static const struct vop2_win_data rk3568_vop_win_data[] = {
597 	{
598 		.name = "Smart0-win0",
599 		.phys_id = ROCKCHIP_VOP2_SMART0,
600 		.base = 0x1c00,
601 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
602 		.formats = formats_smart,
603 		.nformats = ARRAY_SIZE(formats_smart),
604 		.format_modifiers = format_modifiers,
605 		/* 0xf means this layer can't attached to this VP */
606 		.layer_sel_id = { 3, 3, 3, 0xf },
607 		.supported_rotations = DRM_MODE_REFLECT_Y,
608 		.type = DRM_PLANE_TYPE_PRIMARY,
609 		.max_upscale_factor = 8,
610 		.max_downscale_factor = 8,
611 		.dly = { 20, 47, 41 },
612 	}, {
613 		.name = "Smart1-win0",
614 		.phys_id = ROCKCHIP_VOP2_SMART1,
615 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
616 		.formats = formats_smart,
617 		.nformats = ARRAY_SIZE(formats_smart),
618 		.format_modifiers = format_modifiers,
619 		.base = 0x1e00,
620 		.layer_sel_id = { 7, 7, 7, 0xf },
621 		.supported_rotations = DRM_MODE_REFLECT_Y,
622 		.type = DRM_PLANE_TYPE_PRIMARY,
623 		.max_upscale_factor = 8,
624 		.max_downscale_factor = 8,
625 		.dly = { 20, 47, 41 },
626 	}, {
627 		.name = "Esmart1-win0",
628 		.phys_id = ROCKCHIP_VOP2_ESMART1,
629 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
630 		.formats = formats_rk356x_esmart,
631 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
632 		.format_modifiers = format_modifiers,
633 		.base = 0x1a00,
634 		.layer_sel_id = { 6, 6, 6, 0xf },
635 		.supported_rotations = DRM_MODE_REFLECT_Y,
636 		.type = DRM_PLANE_TYPE_PRIMARY,
637 		.max_upscale_factor = 8,
638 		.max_downscale_factor = 8,
639 		.dly = { 20, 47, 41 },
640 	}, {
641 		.name = "Esmart0-win0",
642 		.phys_id = ROCKCHIP_VOP2_ESMART0,
643 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
644 		.formats = formats_rk356x_esmart,
645 		.nformats = ARRAY_SIZE(formats_rk356x_esmart),
646 		.format_modifiers = format_modifiers,
647 		.base = 0x1800,
648 		.layer_sel_id = { 2, 2, 2, 0xf },
649 		.supported_rotations = DRM_MODE_REFLECT_Y,
650 		.type = DRM_PLANE_TYPE_PRIMARY,
651 		.max_upscale_factor = 8,
652 		.max_downscale_factor = 8,
653 		.dly = { 20, 47, 41 },
654 	}, {
655 		.name = "Cluster0-win0",
656 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
657 		.base = 0x1000,
658 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
659 		.formats = formats_cluster,
660 		.nformats = ARRAY_SIZE(formats_cluster),
661 		.format_modifiers = format_modifiers_afbc,
662 		.layer_sel_id = { 0, 0, 0, 0xf },
663 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
664 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
665 		.max_upscale_factor = 4,
666 		.max_downscale_factor = 4,
667 		.dly = { 0, 27, 21 },
668 		.type = DRM_PLANE_TYPE_OVERLAY,
669 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
670 	}, {
671 		.name = "Cluster1-win0",
672 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
673 		.base = 0x1200,
674 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2),
675 		.formats = formats_cluster,
676 		.nformats = ARRAY_SIZE(formats_cluster),
677 		.format_modifiers = format_modifiers_afbc,
678 		.layer_sel_id = { 1, 1, 1, 0xf },
679 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
680 					DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
681 		.type = DRM_PLANE_TYPE_OVERLAY,
682 		.max_upscale_factor = 4,
683 		.max_downscale_factor = 4,
684 		.dly = { 0, 27, 21 },
685 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
686 	},
687 };
688 
689 static const struct vop2_regs_dump rk3568_regs_dump[] = {
690 	{
691 		.name = "SYS",
692 		.base = RK3568_REG_CFG_DONE,
693 		.size = 0x100,
694 		.en_reg  = 0,
695 		.en_val = 0,
696 		.en_mask = 0
697 	}, {
698 		.name = "OVL",
699 		.base = RK3568_OVL_CTRL,
700 		.size = 0x100,
701 		.en_reg = 0,
702 		.en_val = 0,
703 		.en_mask = 0,
704 	}, {
705 		.name = "VP0",
706 		.base = RK3568_VP0_CTRL_BASE,
707 		.size = 0x100,
708 		.en_reg = RK3568_VP_DSP_CTRL,
709 		.en_val = 0,
710 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
711 	}, {
712 		.name = "VP1",
713 		.base = RK3568_VP1_CTRL_BASE,
714 		.size = 0x100,
715 		.en_reg = RK3568_VP_DSP_CTRL,
716 		.en_val = 0,
717 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
718 	}, {
719 		.name = "VP2",
720 		.base = RK3568_VP2_CTRL_BASE,
721 		.size = 0x100,
722 		.en_reg = RK3568_VP_DSP_CTRL,
723 		.en_val = 0,
724 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
725 
726 	}, {
727 		.name = "Cluster0",
728 		.base = RK3568_CLUSTER0_CTRL_BASE,
729 		.size = 0x110,
730 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
731 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
732 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
733 	}, {
734 		.name = "Cluster1",
735 		.base = RK3568_CLUSTER1_CTRL_BASE,
736 		.size = 0x110,
737 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
738 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
739 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
740 	}, {
741 		.name = "Esmart0",
742 		.base = RK3568_ESMART0_CTRL_BASE,
743 		.size = 0xf0,
744 		.en_reg = RK3568_SMART_REGION0_CTRL,
745 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
746 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
747 	}, {
748 		.name = "Esmart1",
749 		.base = RK3568_ESMART1_CTRL_BASE,
750 		.size = 0xf0,
751 		.en_reg = RK3568_SMART_REGION0_CTRL,
752 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
753 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
754 	}, {
755 		.name = "Smart0",
756 		.base = RK3568_SMART0_CTRL_BASE,
757 		.size = 0xf0,
758 		.en_reg = RK3568_SMART_REGION0_CTRL,
759 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
760 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
761 	}, {
762 		.name = "Smart1",
763 		.base = RK3568_SMART1_CTRL_BASE,
764 		.size = 0xf0,
765 		.en_reg = RK3568_SMART_REGION0_CTRL,
766 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
767 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
768 	},
769 };
770 
771 static const struct vop2_video_port_data rk3576_vop_video_ports[] = {
772 	{
773 		.id = 0,
774 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
775 		.gamma_lut_len = 1024,
776 		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
777 		.max_output = { 4096, 2304 },
778 		/* win layer_mix hdr  */
779 		.pre_scan_max_dly = { 10, 8, 2, 0 },
780 		.offset = 0xc00,
781 		.pixel_rate = 2,
782 	}, {
783 		.id = 1,
784 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
785 		.gamma_lut_len = 1024,
786 		.cubic_lut_len = 729, /* 9x9x9 */
787 		.max_output = { 2560, 1600 },
788 		/* win layer_mix hdr  */
789 		.pre_scan_max_dly = { 10, 6, 0, 0 },
790 		.offset = 0xd00,
791 		.pixel_rate = 1,
792 	}, {
793 		.id = 2,
794 		.gamma_lut_len = 1024,
795 		.max_output = { 1920, 1080 },
796 		/* win layer_mix hdr  */
797 		.pre_scan_max_dly = { 10, 6, 0, 0 },
798 		.offset = 0xe00,
799 		.pixel_rate = 1,
800 	},
801 };
802 
803 /*
804  * rk3576 vop with 2 cluster, 4 esmart win.
805  * Every cluster can work as 4K win or split into two 2K win.
806  * All win in cluster support AFBCD.
807  *
808  * Every esmart win support 4 Multi-region.
809  *
810  * VP0 can use Cluster0/1 and Esmart0/2
811  * VP1 can use Cluster0/1 and Esmart1/3
812  * VP2 can use Esmart0/1/2/3
813  *
814  * Scale filter mode:
815  *
816  * * Cluster:
817  * * Support prescale down:
818  * * H/V: gt2/avg2 or gt4/avg4
819  * * After prescale down:
820  *	* nearest-neighbor/bilinear/multi-phase filter for scale up
821  *	* nearest-neighbor/bilinear/multi-phase filter for scale down
822  *
823  * * Esmart:
824  * * Support prescale down:
825  * * H: gt2/avg2 or gt4/avg4
826  * * V: gt2 or gt4
827  * * After prescale down:
828  *	* nearest-neighbor/bilinear/bicubic for scale up
829  *	* nearest-neighbor/bilinear for scale down
830  *
831  * AXI config::
832  *
833  * * Cluster0 win0: 0xa,  0xb       [AXI0]
834  * * Cluster0 win1: 0xc,  0xd       [AXI0]
835  * * Cluster1 win0: 0x6,  0x7       [AXI0]
836  * * Cluster1 win1: 0x8,  0x9       [AXI0]
837  * * Esmart0:       0x10, 0x11      [AXI0]
838  * * Esmart1:       0x12, 0x13      [AXI0]
839  * * Esmart2:       0xa,  0xb       [AXI1]
840  * * Esmart3:       0xc,  0xd       [AXI1]
841  * * Lut dma rid:   0x1,  0x2,  0x3 [AXI0]
842  * * DCI dma rid:   0x4             [AXI0]
843  * * Metadata rid:  0x5             [AXI0]
844  *
845  * * Limit:
846  * * (1) Cluster0/1 are fixed on AXI0 by IC design
847  * * (2) 0x0 and 0xf can't be used;
848  * * (3) 5 Bits ID for eache axi bus
849  * * (3) cluster and lut/dci/metadata rid must smaller than 0xf,
850  * *     if Cluster rid is bigger than 0xf, VOP will dead at the
851  * *     system bandwidth very terrible scene.
852  */
853 static const struct vop2_win_data rk3576_vop_win_data[] = {
854 	{
855 		.name = "Cluster0-win0",
856 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
857 		.base = 0x1000,
858 		.possible_vp_mask = BIT(0) | BIT(1),
859 		.formats = formats_rk3576_cluster,
860 		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
861 		.format_modifiers = format_modifiers_rk3576_afbc,
862 		.layer_sel_id = { 0, 0, 0xf, 0xf },
863 		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
864 		.type = DRM_PLANE_TYPE_PRIMARY,
865 		.axi_bus_id = 0,
866 		.axi_yrgb_r_id = 0xa,
867 		.axi_uv_r_id = 0xb,
868 		.max_upscale_factor = 4,
869 		.max_downscale_factor = 4,
870 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
871 	}, {
872 		.name = "Cluster1-win0",
873 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
874 		.base = 0x1200,
875 		.possible_vp_mask = BIT(0) | BIT(1),
876 		.formats = formats_rk3576_cluster,
877 		.nformats = ARRAY_SIZE(formats_rk3576_cluster),
878 		.format_modifiers = format_modifiers_rk3576_afbc,
879 		.layer_sel_id = { 1, 1, 0xf, 0xf },
880 		.supported_rotations =  DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
881 		.type = DRM_PLANE_TYPE_PRIMARY,
882 		.axi_bus_id = 0,
883 		.axi_yrgb_r_id = 6,
884 		.axi_uv_r_id = 7,
885 		.max_upscale_factor = 4,
886 		.max_downscale_factor = 4,
887 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
888 	}, {
889 		.name = "Esmart0-win0",
890 		.phys_id = ROCKCHIP_VOP2_ESMART0,
891 		.base = 0x1800,
892 		.possible_vp_mask = BIT(0) | BIT(2),
893 		.formats = formats_rk3576_esmart,
894 		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
895 		.format_modifiers = format_modifiers,
896 		.layer_sel_id = { 2, 0xf, 0, 0xf },
897 		.supported_rotations = DRM_MODE_REFLECT_Y,
898 		.type = DRM_PLANE_TYPE_OVERLAY,
899 		.axi_bus_id = 0,
900 		.axi_yrgb_r_id = 0x10,
901 		.axi_uv_r_id = 0x11,
902 		.max_upscale_factor = 8,
903 		.max_downscale_factor = 8,
904 	}, {
905 		.name = "Esmart1-win0",
906 		.phys_id = ROCKCHIP_VOP2_ESMART1,
907 		.base = 0x1a00,
908 		.possible_vp_mask = BIT(1) | BIT(2),
909 		.formats = formats_rk3576_esmart,
910 		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
911 		.format_modifiers = format_modifiers,
912 		.layer_sel_id = { 0xf, 2, 1, 0xf },
913 		.supported_rotations = DRM_MODE_REFLECT_Y,
914 		.type = DRM_PLANE_TYPE_OVERLAY,
915 		.axi_bus_id = 0,
916 		.axi_yrgb_r_id = 0x12,
917 		.axi_uv_r_id = 0x13,
918 		.max_upscale_factor = 8,
919 		.max_downscale_factor = 8,
920 	}, {
921 		.name = "Esmart2-win0",
922 		.phys_id = ROCKCHIP_VOP2_ESMART2,
923 		.base = 0x1c00,
924 		.possible_vp_mask = BIT(0) | BIT(2),
925 		.formats = formats_rk3576_esmart,
926 		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
927 		.format_modifiers = format_modifiers,
928 		.layer_sel_id = { 3, 0xf, 2, 0xf },
929 		.supported_rotations = DRM_MODE_REFLECT_Y,
930 		.type = DRM_PLANE_TYPE_OVERLAY,
931 		.axi_bus_id = 1,
932 		.axi_yrgb_r_id = 0x0a,
933 		.axi_uv_r_id = 0x0b,
934 		.max_upscale_factor = 8,
935 		.max_downscale_factor = 8,
936 	}, {
937 		.name = "Esmart3-win0",
938 		.phys_id = ROCKCHIP_VOP2_ESMART3,
939 		.base = 0x1e00,
940 		.possible_vp_mask = BIT(1) | BIT(2),
941 		.formats = formats_rk3576_esmart,
942 		.nformats = ARRAY_SIZE(formats_rk3576_esmart),
943 		.format_modifiers = format_modifiers,
944 		.layer_sel_id = { 0xf, 3, 3, 0xf },
945 		.supported_rotations = DRM_MODE_REFLECT_Y,
946 		.type = DRM_PLANE_TYPE_OVERLAY,
947 		.axi_bus_id = 1,
948 		.axi_yrgb_r_id = 0x0c,
949 		.axi_uv_r_id = 0x0d,
950 		.max_upscale_factor = 8,
951 		.max_downscale_factor = 8,
952 	},
953 };
954 
955 static const struct vop2_regs_dump rk3576_regs_dump[] = {
956 	{
957 		.name = "SYS",
958 		.base = RK3568_REG_CFG_DONE,
959 		.size = 0x200,
960 		.en_reg  = 0,
961 		.en_val = 0,
962 		.en_mask = 0
963 	}, {
964 		.name = "OVL_SYS",
965 		.base = RK3576_SYS_EXTRA_ALPHA_CTRL,
966 		.size = 0x50,
967 		.en_reg = 0,
968 		.en_val = 0,
969 		.en_mask = 0,
970 	}, {
971 		.name = "OVL_VP0",
972 		.base = RK3576_OVL_CTRL(0),
973 		.size = 0x80,
974 		.en_reg = 0,
975 		.en_val = 0,
976 		.en_mask = 0,
977 	}, {
978 		.name = "OVL_VP1",
979 		.base = RK3576_OVL_CTRL(1),
980 		.size = 0x80,
981 		.en_reg = 0,
982 		.en_val = 0,
983 		.en_mask = 0,
984 	}, {
985 		.name = "OVL_VP2",
986 		.base = RK3576_OVL_CTRL(2),
987 		.size = 0x80,
988 		.en_reg = 0,
989 		.en_val = 0,
990 		.en_mask = 0,
991 	}, {
992 		.name = "VP0",
993 		.base = RK3568_VP0_CTRL_BASE,
994 		.size = 0x100,
995 		.en_reg = RK3568_VP_DSP_CTRL,
996 		.en_val = 0,
997 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
998 	}, {
999 		.name = "VP1",
1000 		.base = RK3568_VP1_CTRL_BASE,
1001 		.size = 0x100,
1002 		.en_reg = RK3568_VP_DSP_CTRL,
1003 		.en_val = 0,
1004 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1005 	}, {
1006 		.name = "VP2",
1007 		.base = RK3568_VP2_CTRL_BASE,
1008 		.size = 0x100,
1009 		.en_reg = RK3568_VP_DSP_CTRL,
1010 		.en_val = 0,
1011 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1012 	}, {
1013 		.name = "Cluster0",
1014 		.base = RK3568_CLUSTER0_CTRL_BASE,
1015 		.size = 0x200,
1016 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1017 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1018 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1019 	}, {
1020 		.name = "Cluster1",
1021 		.base = RK3568_CLUSTER1_CTRL_BASE,
1022 		.size = 0x200,
1023 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1024 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1025 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1026 	}, {
1027 		.name = "Esmart0",
1028 		.base = RK3568_ESMART0_CTRL_BASE,
1029 		.size = 0xf0,
1030 		.en_reg = RK3568_SMART_REGION0_CTRL,
1031 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1032 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1033 	}, {
1034 		.name = "Esmart1",
1035 		.base = RK3568_ESMART1_CTRL_BASE,
1036 		.size = 0xf0,
1037 		.en_reg = RK3568_SMART_REGION0_CTRL,
1038 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1039 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1040 	}, {
1041 		.name = "Esmart2",
1042 		.base = RK3588_ESMART2_CTRL_BASE,
1043 		.size = 0xf0,
1044 		.en_reg = RK3568_SMART_REGION0_CTRL,
1045 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1046 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1047 	}, {
1048 		.name = "Esmart3",
1049 		.base = RK3588_ESMART3_CTRL_BASE,
1050 		.size = 0xf0,
1051 		.en_reg = RK3568_SMART_REGION0_CTRL,
1052 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1053 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1054 	},
1055 };
1056 
1057 static const struct vop2_video_port_data rk3588_vop_video_ports[] = {
1058 	{
1059 		.id = 0,
1060 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
1061 		.gamma_lut_len = 1024,
1062 		.cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
1063 		.max_output = { 4096, 2304 },
1064 		/* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */
1065 		.pre_scan_max_dly = { 76, 65, 65, 54 },
1066 		.offset = 0xc00,
1067 	}, {
1068 		.id = 1,
1069 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
1070 		.gamma_lut_len = 1024,
1071 		.cubic_lut_len = 729, /* 9x9x9 */
1072 		.max_output = { 4096, 2304 },
1073 		.pre_scan_max_dly = { 76, 65, 65, 54 },
1074 		.offset = 0xd00,
1075 	}, {
1076 		.id = 2,
1077 		.feature = VOP2_VP_FEATURE_OUTPUT_10BIT,
1078 		.gamma_lut_len = 1024,
1079 		.cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */
1080 		.max_output = { 4096, 2304 },
1081 		.pre_scan_max_dly = { 52, 52, 52, 52 },
1082 		.offset = 0xe00,
1083 	}, {
1084 		.id = 3,
1085 		.gamma_lut_len = 1024,
1086 		.max_output = { 2048, 1536 },
1087 		.pre_scan_max_dly = { 52, 52, 52, 52 },
1088 		.offset = 0xf00,
1089 	},
1090 };
1091 
1092 /*
1093  * rk3588 vop with 4 cluster, 4 esmart win.
1094  * Every cluster can work as 4K win or split into two win.
1095  * All win in cluster support AFBCD.
1096  *
1097  * Every esmart win and smart win support 4 Multi-region.
1098  *
1099  * Scale filter mode:
1100  *
1101  * * Cluster:  bicubic for horizontal scale up, others use bilinear
1102  * * ESmart:
1103  *    * nearest-neighbor/bilinear/bicubic for scale up
1104  *    * nearest-neighbor/bilinear/average for scale down
1105  *
1106  * AXI Read ID assignment:
1107  * Two AXI bus:
1108  * AXI0 is a read/write bus with a higher performance.
1109  * AXI1 is a read only bus.
1110  *
1111  * Every window on a AXI bus must assigned two unique
1112  * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
1113  *
1114  * AXI0:
1115  * Cluster0/1, Esmart0/1, WriteBack
1116  *
1117  * AXI 1:
1118  * Cluster2/3, Esmart2/3
1119  *
1120  */
1121 static const struct vop2_win_data rk3588_vop_win_data[] = {
1122 	{
1123 		.name = "Cluster0-win0",
1124 		.phys_id = ROCKCHIP_VOP2_CLUSTER0,
1125 		.base = 0x1000,
1126 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1127 		.formats = formats_cluster,
1128 		.nformats = ARRAY_SIZE(formats_cluster),
1129 		.format_modifiers = format_modifiers_afbc,
1130 		.layer_sel_id = { 0, 0, 0, 0 },
1131 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
1132 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
1133 		.axi_bus_id = 0,
1134 		.axi_yrgb_r_id = 2,
1135 		.axi_uv_r_id = 3,
1136 		.max_upscale_factor = 4,
1137 		.max_downscale_factor = 4,
1138 		.dly = { 4, 26, 29 },
1139 		.type = DRM_PLANE_TYPE_PRIMARY,
1140 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
1141 	}, {
1142 		.name = "Cluster1-win0",
1143 		.phys_id = ROCKCHIP_VOP2_CLUSTER1,
1144 		.base = 0x1200,
1145 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1146 		.formats = formats_cluster,
1147 		.nformats = ARRAY_SIZE(formats_cluster),
1148 		.format_modifiers = format_modifiers_afbc,
1149 		.layer_sel_id = { 1, 1, 1, 1 },
1150 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
1151 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
1152 		.type = DRM_PLANE_TYPE_PRIMARY,
1153 		.axi_bus_id = 0,
1154 		.axi_yrgb_r_id = 6,
1155 		.axi_uv_r_id = 7,
1156 		.max_upscale_factor = 4,
1157 		.max_downscale_factor = 4,
1158 		.dly = { 4, 26, 29 },
1159 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
1160 	}, {
1161 		.name = "Cluster2-win0",
1162 		.phys_id = ROCKCHIP_VOP2_CLUSTER2,
1163 		.base = 0x1400,
1164 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1165 		.formats = formats_cluster,
1166 		.nformats = ARRAY_SIZE(formats_cluster),
1167 		.format_modifiers = format_modifiers_afbc,
1168 		.layer_sel_id = { 4, 4, 4, 4 },
1169 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
1170 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
1171 		.type = DRM_PLANE_TYPE_PRIMARY,
1172 		.axi_bus_id = 1,
1173 		.axi_yrgb_r_id = 2,
1174 		.axi_uv_r_id = 3,
1175 		.max_upscale_factor = 4,
1176 		.max_downscale_factor = 4,
1177 		.dly = { 4, 26, 29 },
1178 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
1179 	}, {
1180 		.name = "Cluster3-win0",
1181 		.phys_id = ROCKCHIP_VOP2_CLUSTER3,
1182 		.base = 0x1600,
1183 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1184 		.formats = formats_cluster,
1185 		.nformats = ARRAY_SIZE(formats_cluster),
1186 		.format_modifiers = format_modifiers_afbc,
1187 		.layer_sel_id =  { 5, 5, 5, 5 },
1188 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
1189 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
1190 		.type = DRM_PLANE_TYPE_PRIMARY,
1191 		.axi_bus_id = 1,
1192 		.axi_yrgb_r_id = 6,
1193 		.axi_uv_r_id = 7,
1194 		.max_upscale_factor = 4,
1195 		.max_downscale_factor = 4,
1196 		.dly = { 4, 26, 29 },
1197 		.feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER,
1198 	}, {
1199 		.name = "Esmart0-win0",
1200 		.phys_id = ROCKCHIP_VOP2_ESMART0,
1201 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1202 		.formats = formats_esmart,
1203 		.nformats = ARRAY_SIZE(formats_esmart),
1204 		.format_modifiers = format_modifiers,
1205 		.base = 0x1800,
1206 		.layer_sel_id = { 2, 2, 2, 2 },
1207 		.supported_rotations = DRM_MODE_REFLECT_Y,
1208 		.type = DRM_PLANE_TYPE_OVERLAY,
1209 		.axi_bus_id = 0,
1210 		.axi_yrgb_r_id = 0x0a,
1211 		.axi_uv_r_id = 0x0b,
1212 		.max_upscale_factor = 8,
1213 		.max_downscale_factor = 8,
1214 		.dly = { 23, 45, 48 },
1215 	}, {
1216 		.name = "Esmart1-win0",
1217 		.phys_id = ROCKCHIP_VOP2_ESMART1,
1218 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1219 		.formats = formats_esmart,
1220 		.nformats = ARRAY_SIZE(formats_esmart),
1221 		.format_modifiers = format_modifiers,
1222 		.base = 0x1a00,
1223 		.layer_sel_id = { 3, 3, 3, 3 },
1224 		.supported_rotations = DRM_MODE_REFLECT_Y,
1225 		.type = DRM_PLANE_TYPE_OVERLAY,
1226 		.axi_bus_id = 0,
1227 		.axi_yrgb_r_id = 0x0c,
1228 		.axi_uv_r_id = 0x01,
1229 		.max_upscale_factor = 8,
1230 		.max_downscale_factor = 8,
1231 		.dly = { 23, 45, 48 },
1232 	}, {
1233 		.name = "Esmart2-win0",
1234 		.phys_id = ROCKCHIP_VOP2_ESMART2,
1235 		.base = 0x1c00,
1236 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1237 		.formats = formats_esmart,
1238 		.nformats = ARRAY_SIZE(formats_esmart),
1239 		.format_modifiers = format_modifiers,
1240 		.layer_sel_id =  { 6, 6, 6, 6 },
1241 		.supported_rotations = DRM_MODE_REFLECT_Y,
1242 		.type = DRM_PLANE_TYPE_OVERLAY,
1243 		.axi_bus_id = 1,
1244 		.axi_yrgb_r_id = 0x0a,
1245 		.axi_uv_r_id = 0x0b,
1246 		.max_upscale_factor = 8,
1247 		.max_downscale_factor = 8,
1248 		.dly = { 23, 45, 48 },
1249 	}, {
1250 		.name = "Esmart3-win0",
1251 		.phys_id = ROCKCHIP_VOP2_ESMART3,
1252 		.possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
1253 		.formats = formats_esmart,
1254 		.nformats = ARRAY_SIZE(formats_esmart),
1255 		.format_modifiers = format_modifiers,
1256 		.base = 0x1e00,
1257 		.layer_sel_id =  { 7, 7, 7, 7 },
1258 		.supported_rotations = DRM_MODE_REFLECT_Y,
1259 		.type = DRM_PLANE_TYPE_OVERLAY,
1260 		.axi_bus_id = 1,
1261 		.axi_yrgb_r_id = 0x0c,
1262 		.axi_uv_r_id = 0x0d,
1263 		.max_upscale_factor = 8,
1264 		.max_downscale_factor = 8,
1265 		.dly = { 23, 45, 48 },
1266 	},
1267 };
1268 
1269 static const struct vop2_regs_dump rk3588_regs_dump[] = {
1270 	{
1271 		.name = "SYS",
1272 		.base = RK3568_REG_CFG_DONE,
1273 		.size = 0x100,
1274 		.en_reg  = 0,
1275 		.en_val = 0,
1276 		.en_mask = 0
1277 	}, {
1278 		.name = "OVL",
1279 		.base = RK3568_OVL_CTRL,
1280 		.size = 0x100,
1281 		.en_reg = 0,
1282 		.en_val = 0,
1283 		.en_mask = 0,
1284 	}, {
1285 		.name = "VP0",
1286 		.base = RK3568_VP0_CTRL_BASE,
1287 		.size = 0x100,
1288 		.en_reg = RK3568_VP_DSP_CTRL,
1289 		.en_val = 0,
1290 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1291 	}, {
1292 		.name = "VP1",
1293 		.base = RK3568_VP1_CTRL_BASE,
1294 		.size = 0x100,
1295 		.en_reg = RK3568_VP_DSP_CTRL,
1296 		.en_val = 0,
1297 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1298 	}, {
1299 		.name = "VP2",
1300 		.base = RK3568_VP2_CTRL_BASE,
1301 		.size = 0x100,
1302 		.en_reg = RK3568_VP_DSP_CTRL,
1303 		.en_val = 0,
1304 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1305 
1306 	}, {
1307 		.name = "VP3",
1308 		.base = RK3588_VP3_CTRL_BASE,
1309 		.size = 0x100,
1310 		.en_reg = RK3568_VP_DSP_CTRL,
1311 		.en_val = 0,
1312 		.en_mask = RK3568_VP_DSP_CTRL__STANDBY,
1313 	}, {
1314 		.name = "Cluster0",
1315 		.base = RK3568_CLUSTER0_CTRL_BASE,
1316 		.size = 0x110,
1317 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1318 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1319 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1320 	}, {
1321 		.name = "Cluster1",
1322 		.base = RK3568_CLUSTER1_CTRL_BASE,
1323 		.size = 0x110,
1324 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1325 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1326 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1327 	}, {
1328 		.name = "Cluster2",
1329 		.base = RK3588_CLUSTER2_CTRL_BASE,
1330 		.size = 0x110,
1331 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1332 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1333 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1334 	}, {
1335 		.name = "Cluster3",
1336 		.base = RK3588_CLUSTER3_CTRL_BASE,
1337 		.size = 0x110,
1338 		.en_reg = RK3568_CLUSTER_WIN_CTRL0,
1339 		.en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1340 		.en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN,
1341 	}, {
1342 		.name = "Esmart0",
1343 		.base = RK3568_ESMART0_CTRL_BASE,
1344 		.size = 0xf0,
1345 		.en_reg = RK3568_SMART_REGION0_CTRL,
1346 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1347 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1348 	}, {
1349 		.name = "Esmart1",
1350 		.base = RK3568_ESMART1_CTRL_BASE,
1351 		.size = 0xf0,
1352 		.en_reg = RK3568_SMART_REGION0_CTRL,
1353 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1354 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1355 	}, {
1356 		.name = "Esmart2",
1357 		.base = RK3588_ESMART2_CTRL_BASE,
1358 		.size = 0xf0,
1359 		.en_reg = RK3568_SMART_REGION0_CTRL,
1360 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1361 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1362 	}, {
1363 		.name = "Esmart3",
1364 		.base = RK3588_ESMART3_CTRL_BASE,
1365 		.size = 0xf0,
1366 		.en_reg = RK3568_SMART_REGION0_CTRL,
1367 		.en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1368 		.en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN,
1369 	},
1370 };
1371 
1372 /*
1373  * phys_id is used to identify a main window(Cluster Win/Smart Win, not
1374  * include the sub win of a cluster or the multi area) that can do overlay
1375  * in main overlay stage.
1376  */
vop2_find_win_by_phys_id(struct vop2 * vop2,uint8_t phys_id)1377 static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
1378 {
1379 	struct vop2_win *win;
1380 	int i;
1381 
1382 	for (i = 0; i < vop2->data->win_size; i++) {
1383 		win = &vop2->win[i];
1384 		if (win->data->phys_id == phys_id)
1385 			return win;
1386 	}
1387 
1388 	return NULL;
1389 }
1390 
rk3568_set_intf_mux(struct vop2_video_port * vp,int id,u32 polflags)1391 static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
1392 {
1393 	struct vop2 *vop2 = vp->vop2;
1394 	struct drm_crtc *crtc = &vp->crtc;
1395 	u32 die, dip;
1396 
1397 	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
1398 	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
1399 
1400 	switch (id) {
1401 	case ROCKCHIP_VOP2_EP_RGB0:
1402 		die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
1403 		die |= RK3568_SYS_DSP_INFACE_EN_RGB |
1404 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
1405 		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1406 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1407 		if (polflags & POLFLAG_DCLK_INV)
1408 			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
1409 		else
1410 			regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
1411 		break;
1412 	case ROCKCHIP_VOP2_EP_HDMI0:
1413 		die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
1414 		die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
1415 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
1416 		dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
1417 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
1418 		break;
1419 	case ROCKCHIP_VOP2_EP_EDP0:
1420 		die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
1421 		die |= RK3568_SYS_DSP_INFACE_EN_EDP |
1422 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
1423 		dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
1424 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
1425 		break;
1426 	case ROCKCHIP_VOP2_EP_MIPI0:
1427 		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
1428 		die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
1429 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
1430 		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1431 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1432 		break;
1433 	case ROCKCHIP_VOP2_EP_MIPI1:
1434 		die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
1435 		die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
1436 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
1437 		dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1438 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1439 		break;
1440 	case ROCKCHIP_VOP2_EP_LVDS0:
1441 		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
1442 		die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
1443 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
1444 		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1445 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1446 		break;
1447 	case ROCKCHIP_VOP2_EP_LVDS1:
1448 		die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
1449 		die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
1450 			   FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
1451 		dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1452 		dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1453 		break;
1454 	default:
1455 		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
1456 		return 0;
1457 	}
1458 
1459 	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
1460 
1461 	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
1462 	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
1463 
1464 	return crtc->state->adjusted_mode.crtc_clock  * 1000LL;
1465 }
1466 
rk3576_set_intf_mux(struct vop2_video_port * vp,int id,u32 polflags)1467 static unsigned long rk3576_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
1468 {
1469 	struct vop2 *vop2 = vp->vop2;
1470 	struct drm_crtc *crtc = &vp->crtc;
1471 	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1472 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1473 	u8 port_pix_rate = vp->data->pixel_rate;
1474 	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_sel;
1475 	u32 ctrl, vp_clk_div, reg, dclk_div;
1476 	unsigned long dclk_in_rate, dclk_core_rate;
1477 
1478 	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 || adjusted_mode->crtc_clock > 600000)
1479 		dclk_div = 2;
1480 	else
1481 		dclk_div = 1;
1482 
1483 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
1484 		dclk_core_rate = adjusted_mode->crtc_clock / 2;
1485 	else
1486 		dclk_core_rate = adjusted_mode->crtc_clock / port_pix_rate;
1487 
1488 	dclk_in_rate = adjusted_mode->crtc_clock / dclk_div;
1489 
1490 	dclk_core_div = dclk_in_rate > dclk_core_rate ? 1 : 0;
1491 
1492 	if (vop2_output_if_is_edp(id))
1493 		if_pixclk_div = port_pix_rate == 2 ? RK3576_DSP_IF_PCLK_DIV : 0;
1494 	else
1495 		if_pixclk_div = port_pix_rate == 1 ? RK3576_DSP_IF_PCLK_DIV : 0;
1496 
1497 	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) {
1498 		if_dclk_sel = RK3576_DSP_IF_DCLK_SEL_OUT;
1499 		dclk_out_div = 1;
1500 	} else {
1501 		if_dclk_sel = 0;
1502 		dclk_out_div = 0;
1503 	}
1504 
1505 	switch (id) {
1506 	case ROCKCHIP_VOP2_EP_HDMI0:
1507 		reg = RK3576_HDMI0_IF_CTRL;
1508 		break;
1509 	case ROCKCHIP_VOP2_EP_EDP0:
1510 		reg = RK3576_EDP0_IF_CTRL;
1511 		break;
1512 	case ROCKCHIP_VOP2_EP_MIPI0:
1513 		reg = RK3576_MIPI0_IF_CTRL;
1514 		break;
1515 	case ROCKCHIP_VOP2_EP_DP0:
1516 		reg = RK3576_DP0_IF_CTRL;
1517 		break;
1518 	case ROCKCHIP_VOP2_EP_DP1:
1519 		reg = RK3576_DP1_IF_CTRL;
1520 		break;
1521 	default:
1522 		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
1523 		return 0;
1524 	}
1525 
1526 	ctrl = vop2_readl(vop2, reg);
1527 	ctrl &= ~RK3576_DSP_IF_DCLK_SEL_OUT;
1528 	ctrl &= ~RK3576_DSP_IF_PCLK_DIV;
1529 	ctrl &= ~RK3576_DSP_IF_MUX;
1530 	ctrl |= RK3576_DSP_IF_CFG_DONE_IMD;
1531 	ctrl |= if_dclk_sel | if_pixclk_div;
1532 	ctrl |= RK3576_DSP_IF_CLK_OUT_EN | RK3576_DSP_IF_EN;
1533 	ctrl |= FIELD_PREP(RK3576_DSP_IF_MUX, vp->id);
1534 	ctrl |= FIELD_PREP(RK3576_DSP_IF_PIN_POL, polflags);
1535 	vop2_writel(vop2, reg, ctrl);
1536 
1537 	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
1538 	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
1539 
1540 	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
1541 
1542 	return dclk_in_rate * 1000LL;
1543 }
1544 
1545 /*
1546  * calc the dclk on rk3588
1547  * the available div of dclk is 1, 2, 4
1548  */
rk3588_calc_dclk(unsigned long child_clk,unsigned long max_dclk)1549 static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
1550 {
1551 	if (child_clk * 4 <= max_dclk)
1552 		return child_clk * 4;
1553 	else if (child_clk * 2 <= max_dclk)
1554 		return child_clk * 2;
1555 	else if (child_clk <= max_dclk)
1556 		return child_clk;
1557 	else
1558 		return 0;
1559 }
1560 
1561 /*
1562  * 4 pixclk/cycle on rk3588
1563  * RGB/eDP/HDMI: if_pixclk >= dclk_core
1564  * DP: dp_pixclk = dclk_out <= dclk_core
1565  * DSI: mipi_pixclk <= dclk_out <= dclk_core
1566  */
rk3588_calc_cru_cfg(struct vop2_video_port * vp,int id,int * dclk_core_div,int * dclk_out_div,int * if_pixclk_div,int * if_dclk_div)1567 static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
1568 					 int *dclk_core_div, int *dclk_out_div,
1569 					 int *if_pixclk_div, int *if_dclk_div)
1570 {
1571 	struct vop2 *vop2 = vp->vop2;
1572 	struct drm_crtc *crtc = &vp->crtc;
1573 	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1574 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1575 	int output_mode = vcstate->output_mode;
1576 	unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
1577 	unsigned long dclk_core_rate = v_pixclk >> 2;
1578 	unsigned long dclk_rate = v_pixclk;
1579 	unsigned long dclk_out_rate;
1580 	unsigned long if_pixclk_rate;
1581 	int K = 1;
1582 
1583 	if (vop2_output_if_is_hdmi(id)) {
1584 		/*
1585 		 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
1586 		 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
1587 		 */
1588 		if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
1589 			dclk_rate = dclk_rate >> 1;
1590 			K = 2;
1591 		}
1592 
1593 		/*
1594 		 * if_pixclk_rate = (dclk_core_rate << 1) / K;
1595 		 * if_dclk_rate = dclk_core_rate / K;
1596 		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
1597 		 * *if_dclk_div = dclk_rate / if_dclk_rate;
1598 		 */
1599 		*if_pixclk_div = 2;
1600 		*if_dclk_div = 4;
1601 	} else if (vop2_output_if_is_edp(id)) {
1602 		/*
1603 		 * edp_pixclk = edp_dclk > dclk_core
1604 		 */
1605 		if_pixclk_rate = v_pixclk / K;
1606 		dclk_rate = if_pixclk_rate * K;
1607 		/*
1608 		 * *if_pixclk_div = dclk_rate / if_pixclk_rate;
1609 		 * *if_dclk_div = *if_pixclk_div;
1610 		 */
1611 		*if_pixclk_div = K;
1612 		*if_dclk_div = K;
1613 	} else if (vop2_output_if_is_dp(id)) {
1614 		if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
1615 			dclk_out_rate = v_pixclk >> 3;
1616 		else
1617 			dclk_out_rate = v_pixclk >> 2;
1618 
1619 		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
1620 		if (!dclk_rate) {
1621 			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
1622 				dclk_out_rate);
1623 			return 0;
1624 		}
1625 		*dclk_out_div = dclk_rate / dclk_out_rate;
1626 	} else if (vop2_output_if_is_mipi(id)) {
1627 		if_pixclk_rate = dclk_core_rate / K;
1628 		/*
1629 		 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
1630 		 */
1631 		dclk_out_rate = if_pixclk_rate;
1632 		/*
1633 		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
1634 		 * we get a little factor here
1635 		 */
1636 		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
1637 		if (!dclk_rate) {
1638 			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
1639 				dclk_out_rate);
1640 			return 0;
1641 		}
1642 		*dclk_out_div = dclk_rate / dclk_out_rate;
1643 		/*
1644 		 * mipi pixclk == dclk_out
1645 		 */
1646 		*if_pixclk_div = 1;
1647 	} else if (vop2_output_if_is_dpi(id)) {
1648 		dclk_rate = v_pixclk;
1649 	}
1650 
1651 	*dclk_core_div = dclk_rate / dclk_core_rate;
1652 	*if_pixclk_div = ilog2(*if_pixclk_div);
1653 	*if_dclk_div = ilog2(*if_dclk_div);
1654 	*dclk_core_div = ilog2(*dclk_core_div);
1655 	*dclk_out_div = ilog2(*dclk_out_div);
1656 
1657 	drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
1658 		dclk_rate, *if_pixclk_div, *if_dclk_div);
1659 
1660 	return dclk_rate;
1661 }
1662 
1663 /*
1664  * MIPI port mux on rk3588:
1665  * 0: Video Port2
1666  * 1: Video Port3
1667  * 3: Video Port 1(MIPI1 only)
1668  */
rk3588_get_mipi_port_mux(int vp_id)1669 static u32 rk3588_get_mipi_port_mux(int vp_id)
1670 {
1671 	if (vp_id == 1)
1672 		return 3;
1673 	else if (vp_id == 3)
1674 		return 1;
1675 	else
1676 		return 0;
1677 }
1678 
rk3588_get_hdmi_pol(u32 flags)1679 static u32 rk3588_get_hdmi_pol(u32 flags)
1680 {
1681 	u32 val;
1682 
1683 	val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
1684 	val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
1685 
1686 	return val;
1687 }
1688 
rk3588_set_intf_mux(struct vop2_video_port * vp,int id,u32 polflags)1689 static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
1690 {
1691 	struct vop2 *vop2 = vp->vop2;
1692 	int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
1693 	unsigned long clock;
1694 	u32 die, dip, div, vp_clk_div, val;
1695 
1696 	clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
1697 				    &if_pixclk_div, &if_dclk_div);
1698 	if (!clock)
1699 		return 0;
1700 
1701 	vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
1702 	vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
1703 
1704 	die = vop2_readl(vop2, RK3568_DSP_IF_EN);
1705 	dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
1706 	div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
1707 
1708 	switch (id) {
1709 	case ROCKCHIP_VOP2_EP_HDMI0:
1710 		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
1711 		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
1712 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
1713 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
1714 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
1715 		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
1716 			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
1717 		val = rk3588_get_hdmi_pol(polflags);
1718 		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(1), 1));
1719 		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0,
1720 			     FIELD_PREP_WM16(GENMASK(6, 5), val));
1721 		break;
1722 	case ROCKCHIP_VOP2_EP_HDMI1:
1723 		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
1724 		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
1725 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
1726 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
1727 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
1728 		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
1729 			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
1730 		val = rk3588_get_hdmi_pol(polflags);
1731 		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(4), 1));
1732 		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0,
1733 			     FIELD_PREP_WM16(GENMASK(8, 7), val));
1734 		break;
1735 	case ROCKCHIP_VOP2_EP_EDP0:
1736 		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
1737 		div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
1738 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
1739 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
1740 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
1741 		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
1742 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
1743 		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(0), 1));
1744 		break;
1745 	case ROCKCHIP_VOP2_EP_EDP1:
1746 		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
1747 		div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
1748 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
1749 		div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
1750 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
1751 		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
1752 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
1753 		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(3), 1));
1754 		break;
1755 	case ROCKCHIP_VOP2_EP_MIPI0:
1756 		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
1757 		div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
1758 		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
1759 		val = rk3588_get_mipi_port_mux(vp->id);
1760 		die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
1761 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
1762 		break;
1763 	case ROCKCHIP_VOP2_EP_MIPI1:
1764 		div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
1765 		div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
1766 		die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
1767 		val = rk3588_get_mipi_port_mux(vp->id);
1768 		die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
1769 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
1770 		break;
1771 	case ROCKCHIP_VOP2_EP_DP0:
1772 		die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
1773 		die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
1774 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
1775 		dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
1776 		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
1777 		break;
1778 	case ROCKCHIP_VOP2_EP_DP1:
1779 		die &= ~RK3588_SYS_DSP_INFACE_EN_DP1_MUX;
1780 		die |= RK3588_SYS_DSP_INFACE_EN_DP1 |
1781 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP1_MUX, vp->id);
1782 		dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
1783 		dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
1784 		break;
1785 	default:
1786 		drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
1787 		return 0;
1788 	}
1789 
1790 	dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
1791 
1792 	vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
1793 	vop2_writel(vop2, RK3568_DSP_IF_EN, die);
1794 	vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
1795 	vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
1796 
1797 	return clock;
1798 }
1799 
is_opaque(u16 alpha)1800 static bool is_opaque(u16 alpha)
1801 {
1802 	return (alpha >> 8) == 0xff;
1803 }
1804 
vop2_parse_alpha(struct vop2_alpha_config * alpha_config,struct vop2_alpha * alpha)1805 static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
1806 			     struct vop2_alpha *alpha)
1807 {
1808 	int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
1809 	int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
1810 	int src_color_mode = alpha_config->src_premulti_en ?
1811 				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1812 	int dst_color_mode = alpha_config->dst_premulti_en ?
1813 				ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1814 
1815 	alpha->src_color_ctrl.val = 0;
1816 	alpha->dst_color_ctrl.val = 0;
1817 	alpha->src_alpha_ctrl.val = 0;
1818 	alpha->dst_alpha_ctrl.val = 0;
1819 
1820 	if (!alpha_config->src_pixel_alpha_en)
1821 		alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1822 	else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
1823 		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1824 	else
1825 		alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1826 
1827 	alpha->src_color_ctrl.bits.alpha_en = 1;
1828 
1829 	if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
1830 		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1831 		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1832 	} else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
1833 		alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1834 		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
1835 	} else {
1836 		alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
1837 		alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1838 	}
1839 	alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
1840 	alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1841 	alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1842 
1843 	alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1844 	alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1845 	alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1846 	alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
1847 	alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
1848 	alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1849 
1850 	alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1851 	alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
1852 	alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1853 	alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
1854 
1855 	alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1856 	if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
1857 		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1858 	else
1859 		alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1860 	alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
1861 	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1862 }
1863 
vop2_find_start_mixer_id_for_vp(struct vop2_video_port * vp)1864 static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp)
1865 {
1866 	struct vop2 *vop2 = vp->vop2;
1867 	struct vop2_win *win;
1868 	u32 layer_sel = vop2->old_layer_sel;
1869 	u32 used_layer = 0;
1870 	unsigned long win_mask = vp->win_mask;
1871 	unsigned long phys_id;
1872 	bool match;
1873 	int i;
1874 
1875 	for (i = 0; i < 31; i += 4) {
1876 		match = false;
1877 		for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) {
1878 			win = vop2_find_win_by_phys_id(vop2, phys_id);
1879 			if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) {
1880 				match = true;
1881 				break;
1882 			}
1883 		}
1884 
1885 		if (!match)
1886 			used_layer += 1;
1887 		else
1888 			break;
1889 	}
1890 
1891 	return used_layer;
1892 }
1893 
vop2_setup_cluster_alpha(struct vop2 * vop2,struct vop2_win * main_win)1894 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
1895 {
1896 	struct vop2_alpha_config alpha_config;
1897 	struct vop2_alpha alpha;
1898 	struct drm_plane_state *bottom_win_pstate;
1899 	bool src_pixel_alpha_en = false;
1900 	u16 src_glb_alpha_val, dst_glb_alpha_val;
1901 	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
1902 	u32 offset = 0;
1903 	bool premulti_en = false;
1904 	bool swap = false;
1905 
1906 	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
1907 	bottom_win_pstate = main_win->base.state;
1908 	src_glb_alpha_val = 0;
1909 	dst_glb_alpha_val = main_win->base.state->alpha;
1910 
1911 	if (!bottom_win_pstate->fb)
1912 		return;
1913 
1914 	alpha_config.src_premulti_en = premulti_en;
1915 	alpha_config.dst_premulti_en = false;
1916 	alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
1917 	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1918 	alpha_config.src_glb_alpha_value = src_glb_alpha_val;
1919 	alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
1920 	vop2_parse_alpha(&alpha_config, &alpha);
1921 
1922 	alpha.src_color_ctrl.bits.src_dst_swap = swap;
1923 
1924 	switch (main_win->data->phys_id) {
1925 	case ROCKCHIP_VOP2_CLUSTER0:
1926 		offset = 0x0;
1927 		break;
1928 	case ROCKCHIP_VOP2_CLUSTER1:
1929 		offset = 0x10;
1930 		break;
1931 	case ROCKCHIP_VOP2_CLUSTER2:
1932 		offset = 0x20;
1933 		break;
1934 	case ROCKCHIP_VOP2_CLUSTER3:
1935 		offset = 0x30;
1936 		break;
1937 	}
1938 
1939 	if (vop2->version <= VOP_VERSION_RK3588) {
1940 		src_color_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL;
1941 		dst_color_ctrl_reg = RK3568_CLUSTER0_MIX_DST_COLOR_CTRL;
1942 		src_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL;
1943 		dst_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL;
1944 	} else {
1945 		src_color_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL;
1946 		dst_color_ctrl_reg = RK3576_CLUSTER0_MIX_DST_COLOR_CTRL;
1947 		src_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL;
1948 		dst_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL;
1949 	}
1950 
1951 	vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
1952 	vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
1953 	vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
1954 	vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
1955 }
1956 
vop2_setup_alpha(struct vop2_video_port * vp)1957 static void vop2_setup_alpha(struct vop2_video_port *vp)
1958 {
1959 	struct vop2 *vop2 = vp->vop2;
1960 	struct drm_framebuffer *fb;
1961 	struct vop2_alpha_config alpha_config;
1962 	struct vop2_alpha alpha;
1963 	struct drm_plane *plane;
1964 	int pixel_alpha_en;
1965 	int premulti_en, gpremulti_en = 0;
1966 	int mixer_id;
1967 	u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg;
1968 	u32 offset;
1969 	bool bottom_layer_alpha_en = false;
1970 	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
1971 
1972 	if (vop2->version <= VOP_VERSION_RK3588)
1973 		mixer_id = vop2_find_start_mixer_id_for_vp(vp);
1974 	else
1975 		mixer_id = 0;
1976 
1977 	alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1978 
1979 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1980 		struct vop2_win *win = to_vop2_win(plane);
1981 
1982 		if (plane->state->normalized_zpos == 0 &&
1983 		    !is_opaque(plane->state->alpha) &&
1984 		    !vop2_cluster_window(win)) {
1985 			/*
1986 			 * If bottom layer have global alpha effect [except cluster layer,
1987 			 * because cluster have deal with bottom layer global alpha value
1988 			 * at cluster mix], bottom layer mix need deal with global alpha.
1989 			 */
1990 			bottom_layer_alpha_en = true;
1991 			dst_global_alpha = plane->state->alpha;
1992 		}
1993 	}
1994 
1995 	if (vop2->version <= VOP_VERSION_RK3588) {
1996 		src_color_ctrl_reg = RK3568_MIX0_SRC_COLOR_CTRL;
1997 		dst_color_ctrl_reg = RK3568_MIX0_DST_COLOR_CTRL;
1998 		src_alpha_ctrl_reg = RK3568_MIX0_SRC_ALPHA_CTRL;
1999 		dst_alpha_ctrl_reg = RK3568_MIX0_DST_ALPHA_CTRL;
2000 	} else {
2001 		src_color_ctrl_reg = RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp->id);
2002 		dst_color_ctrl_reg = RK3576_OVL_MIX0_DST_COLOR_CTRL(vp->id);
2003 		src_alpha_ctrl_reg = RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp->id);
2004 		dst_alpha_ctrl_reg = RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp->id);
2005 	}
2006 
2007 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
2008 		struct vop2_win *win = to_vop2_win(plane);
2009 		int zpos = plane->state->normalized_zpos;
2010 
2011 		/*
2012 		 * Need to configure alpha from second layer.
2013 		 */
2014 		if (zpos == 0)
2015 			continue;
2016 
2017 		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
2018 			premulti_en = 1;
2019 		else
2020 			premulti_en = 0;
2021 
2022 		plane = &win->base;
2023 		fb = plane->state->fb;
2024 
2025 		pixel_alpha_en = fb->format->has_alpha;
2026 
2027 		alpha_config.src_premulti_en = premulti_en;
2028 
2029 		if (bottom_layer_alpha_en && zpos == 1) {
2030 			gpremulti_en = premulti_en;
2031 			/* Cd = Cs + (1 - As) * Cd * Agd */
2032 			alpha_config.dst_premulti_en = false;
2033 			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
2034 			alpha_config.src_glb_alpha_value = plane->state->alpha;
2035 			alpha_config.dst_glb_alpha_value = dst_global_alpha;
2036 		} else if (vop2_cluster_window(win)) {
2037 			/* Mix output data only have pixel alpha */
2038 			alpha_config.dst_premulti_en = true;
2039 			alpha_config.src_pixel_alpha_en = true;
2040 			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
2041 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
2042 		} else {
2043 			/* Cd = Cs + (1 - As) * Cd */
2044 			alpha_config.dst_premulti_en = true;
2045 			alpha_config.src_pixel_alpha_en = pixel_alpha_en;
2046 			alpha_config.src_glb_alpha_value = plane->state->alpha;
2047 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
2048 		}
2049 
2050 		vop2_parse_alpha(&alpha_config, &alpha);
2051 
2052 		offset = (mixer_id + zpos - 1) * 0x10;
2053 
2054 		vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val);
2055 		vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val);
2056 		vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val);
2057 		vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val);
2058 	}
2059 
2060 	if (vp->id == 0) {
2061 		if (vop2->version <= VOP_VERSION_RK3588) {
2062 			src_color_ctrl_reg = RK3568_HDR0_SRC_COLOR_CTRL;
2063 			dst_color_ctrl_reg = RK3568_HDR0_DST_COLOR_CTRL;
2064 			src_alpha_ctrl_reg = RK3568_HDR0_SRC_ALPHA_CTRL;
2065 			dst_alpha_ctrl_reg = RK3568_HDR0_DST_ALPHA_CTRL;
2066 		} else {
2067 			src_color_ctrl_reg = RK3576_OVL_HDR_SRC_COLOR_CTRL(vp->id);
2068 			dst_color_ctrl_reg = RK3576_OVL_HDR_DST_COLOR_CTRL(vp->id);
2069 			src_alpha_ctrl_reg = RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp->id);
2070 			dst_alpha_ctrl_reg = RK3576_OVL_HDR_DST_ALPHA_CTRL(vp->id);
2071 		}
2072 
2073 		if (bottom_layer_alpha_en) {
2074 			/* Transfer pixel alpha to hdr mix */
2075 			alpha_config.src_premulti_en = gpremulti_en;
2076 			alpha_config.dst_premulti_en = true;
2077 			alpha_config.src_pixel_alpha_en = true;
2078 			alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
2079 			alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
2080 
2081 			vop2_parse_alpha(&alpha_config, &alpha);
2082 
2083 			vop2_writel(vop2, src_color_ctrl_reg, alpha.src_color_ctrl.val);
2084 			vop2_writel(vop2, dst_color_ctrl_reg, alpha.dst_color_ctrl.val);
2085 			vop2_writel(vop2, src_alpha_ctrl_reg, alpha.src_alpha_ctrl.val);
2086 			vop2_writel(vop2, dst_alpha_ctrl_reg, alpha.dst_alpha_ctrl.val);
2087 		} else {
2088 			vop2_writel(vop2, src_color_ctrl_reg, 0);
2089 		}
2090 	}
2091 }
2092 
rk3568_vop2_read_port_mux(struct vop2 * vop2)2093 static u32 rk3568_vop2_read_port_mux(struct vop2 *vop2)
2094 {
2095 	return vop2_readl(vop2, RK3568_OVL_PORT_SEL);
2096 }
2097 
rk3568_vop2_wait_for_port_mux_done(struct vop2 * vop2)2098 static void rk3568_vop2_wait_for_port_mux_done(struct vop2 *vop2)
2099 {
2100 	u32 port_mux_sel;
2101 	int ret;
2102 
2103 	/*
2104 	 * Spin until the previous port_mux figuration is done.
2105 	 */
2106 	ret = readx_poll_timeout_atomic(rk3568_vop2_read_port_mux, vop2, port_mux_sel,
2107 					port_mux_sel == vop2->old_port_sel, 0, 50 * 1000);
2108 	if (ret)
2109 		DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n",
2110 			      port_mux_sel, vop2->old_port_sel);
2111 }
2112 
rk3568_vop2_read_layer_cfg(struct vop2 * vop2)2113 static u32 rk3568_vop2_read_layer_cfg(struct vop2 *vop2)
2114 {
2115 	return vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
2116 }
2117 
rk3568_vop2_wait_for_layer_cfg_done(struct vop2 * vop2,u32 cfg)2118 static void rk3568_vop2_wait_for_layer_cfg_done(struct vop2 *vop2, u32 cfg)
2119 {
2120 	u32 atv_layer_cfg;
2121 	int ret;
2122 
2123 	/*
2124 	 * Spin until the previous layer configuration is done.
2125 	 */
2126 	ret = readx_poll_timeout_atomic(rk3568_vop2_read_layer_cfg, vop2, atv_layer_cfg,
2127 					atv_layer_cfg == cfg, 0, 50 * 1000);
2128 	if (ret)
2129 		DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n",
2130 			      atv_layer_cfg, cfg);
2131 }
2132 
rk3568_vop2_setup_layer_mixer(struct vop2_video_port * vp)2133 static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp)
2134 {
2135 	struct vop2 *vop2 = vp->vop2;
2136 	struct drm_plane *plane;
2137 	u32 layer_sel = 0;
2138 	u32 port_sel;
2139 	u32 old_layer_sel = 0;
2140 	u32 atv_layer_sel = 0;
2141 	u32 old_port_sel = 0;
2142 	u8 layer_id;
2143 	u8 old_layer_id;
2144 	u8 layer_sel_id;
2145 	unsigned int ofs;
2146 	u32 ovl_ctrl;
2147 	int i;
2148 	struct vop2_video_port *vp0 = &vop2->vps[0];
2149 	struct vop2_video_port *vp1 = &vop2->vps[1];
2150 	struct vop2_video_port *vp2 = &vop2->vps[2];
2151 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
2152 
2153 	mutex_lock(&vop2->ovl_lock);
2154 	ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
2155 	ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
2156 	ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL;
2157 
2158 	if (vcstate->yuv_overlay)
2159 		ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
2160 	else
2161 		ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
2162 
2163 	old_port_sel = vop2->old_port_sel;
2164 	port_sel = old_port_sel;
2165 	port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
2166 
2167 	if (vp0->nlayers)
2168 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
2169 				     vp0->nlayers - 1);
2170 	else
2171 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
2172 
2173 	if (vp1->nlayers)
2174 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
2175 				     (vp0->nlayers + vp1->nlayers - 1));
2176 	else
2177 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
2178 
2179 	if (vp2->nlayers)
2180 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
2181 			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
2182 	else
2183 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
2184 
2185 	/* Fixed value for rk3588 */
2186 	if (vop2->version == VOP_VERSION_RK3588)
2187 		port_sel |= FIELD_PREP(RK3588_OVL_PORT_SET__PORT3_MUX, 7);
2188 
2189 	atv_layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
2190 	old_layer_sel = vop2->old_layer_sel;
2191 	layer_sel = old_layer_sel;
2192 
2193 	ofs = 0;
2194 	for (i = 0; i < vp->id; i++)
2195 		ofs += vop2->vps[i].nlayers;
2196 
2197 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
2198 		struct vop2_win *win = to_vop2_win(plane);
2199 		struct vop2_win *old_win;
2200 
2201 		layer_id = (u8)(plane->state->normalized_zpos + ofs);
2202 		/*
2203 		 * Find the layer this win bind in old state.
2204 		 */
2205 		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
2206 			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
2207 			if (layer_sel_id == win->data->layer_sel_id[vp->id])
2208 				break;
2209 		}
2210 
2211 		/*
2212 		 * Find the win bind to this layer in old state
2213 		 */
2214 		for (i = 0; i < vop2->data->win_size; i++) {
2215 			old_win = &vop2->win[i];
2216 			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
2217 			if (layer_sel_id == old_win->data->layer_sel_id[vp->id])
2218 				break;
2219 		}
2220 
2221 		switch (win->data->phys_id) {
2222 		case ROCKCHIP_VOP2_CLUSTER0:
2223 			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
2224 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
2225 			break;
2226 		case ROCKCHIP_VOP2_CLUSTER1:
2227 			port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
2228 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
2229 			break;
2230 		case ROCKCHIP_VOP2_CLUSTER2:
2231 			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
2232 			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
2233 			break;
2234 		case ROCKCHIP_VOP2_CLUSTER3:
2235 			port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
2236 			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
2237 			break;
2238 		case ROCKCHIP_VOP2_ESMART0:
2239 			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
2240 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
2241 			break;
2242 		case ROCKCHIP_VOP2_ESMART1:
2243 			port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
2244 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
2245 			break;
2246 		case ROCKCHIP_VOP2_ESMART2:
2247 			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
2248 			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
2249 			break;
2250 		case ROCKCHIP_VOP2_ESMART3:
2251 			port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
2252 			port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
2253 			break;
2254 		case ROCKCHIP_VOP2_SMART0:
2255 			port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
2256 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
2257 			break;
2258 		case ROCKCHIP_VOP2_SMART1:
2259 			port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
2260 			port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
2261 			break;
2262 		}
2263 
2264 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
2265 		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id[vp->id]);
2266 		/*
2267 		 * When we bind a window from layerM to layerN, we also need to move the old
2268 		 * window on layerN to layerM to avoid one window selected by two or more layers.
2269 		 */
2270 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
2271 		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id,
2272 			     old_win->data->layer_sel_id[vp->id]);
2273 	}
2274 
2275 	vop2->old_layer_sel = layer_sel;
2276 	vop2->old_port_sel = port_sel;
2277 	/*
2278 	 * As the RK3568_OVL_LAYER_SEL and RK3568_OVL_PORT_SEL are shared by all Video Ports,
2279 	 * and the configuration take effect by one Video Port's vsync.
2280 	 * When performing layer migration or change the zpos of layers, there are two things
2281 	 * to be observed and followed:
2282 	 * 1. When a layer is migrated from one VP to another, the configuration of the layer
2283 	 *    can only take effect after the Port mux configuration is enabled.
2284 	 *
2285 	 * 2. When we change the zpos of layers, we must ensure that the change for the previous
2286 	 *    VP takes effect before we proceed to change the next VP. Otherwise, the new
2287 	 *    configuration might overwrite the previous one for the previous VP, or it could
2288 	 *    lead to the configuration of the previous VP being take effect along with the VSYNC
2289 	 *    of the new VP.
2290 	 */
2291 	if (layer_sel != old_layer_sel || port_sel != old_port_sel)
2292 		ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id);
2293 	vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
2294 
2295 	if (port_sel != old_port_sel) {
2296 		vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
2297 		vop2_cfg_done(vp);
2298 		rk3568_vop2_wait_for_port_mux_done(vop2);
2299 	}
2300 
2301 	if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel)
2302 		rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel);
2303 
2304 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
2305 	mutex_unlock(&vop2->ovl_lock);
2306 }
2307 
rk3568_vop2_setup_dly_for_windows(struct vop2_video_port * vp)2308 static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
2309 {
2310 	struct vop2 *vop2 = vp->vop2;
2311 	struct vop2_win *win;
2312 	int i = 0;
2313 	u32 cdly = 0, sdly = 0;
2314 
2315 	for (i = 0; i < vop2->data->win_size; i++) {
2316 		u32 dly;
2317 
2318 		win = &vop2->win[i];
2319 		dly = win->delay;
2320 
2321 		switch (win->data->phys_id) {
2322 		case ROCKCHIP_VOP2_CLUSTER0:
2323 			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
2324 			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
2325 			break;
2326 		case ROCKCHIP_VOP2_CLUSTER1:
2327 			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
2328 			cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
2329 			break;
2330 		case ROCKCHIP_VOP2_ESMART0:
2331 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
2332 			break;
2333 		case ROCKCHIP_VOP2_ESMART1:
2334 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
2335 			break;
2336 		case ROCKCHIP_VOP2_SMART0:
2337 		case ROCKCHIP_VOP2_ESMART2:
2338 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
2339 			break;
2340 		case ROCKCHIP_VOP2_SMART1:
2341 		case ROCKCHIP_VOP2_ESMART3:
2342 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
2343 			break;
2344 		}
2345 	}
2346 
2347 	vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
2348 	vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
2349 }
2350 
rk3568_vop2_setup_overlay(struct vop2_video_port * vp)2351 static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp)
2352 {
2353 	struct vop2 *vop2 = vp->vop2;
2354 	struct drm_crtc *crtc = &vp->crtc;
2355 	struct drm_plane *plane;
2356 
2357 	vp->win_mask = 0;
2358 
2359 	drm_atomic_crtc_for_each_plane(plane, crtc) {
2360 		struct vop2_win *win = to_vop2_win(plane);
2361 
2362 		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
2363 
2364 		vp->win_mask |= BIT(win->data->phys_id);
2365 
2366 		if (vop2_cluster_window(win))
2367 			vop2_setup_cluster_alpha(vop2, win);
2368 	}
2369 
2370 	if (!vp->win_mask)
2371 		return;
2372 
2373 	rk3568_vop2_setup_layer_mixer(vp);
2374 	vop2_setup_alpha(vp);
2375 	rk3568_vop2_setup_dly_for_windows(vp);
2376 }
2377 
rk3576_vop2_setup_layer_mixer(struct vop2_video_port * vp)2378 static void rk3576_vop2_setup_layer_mixer(struct vop2_video_port *vp)
2379 {
2380 	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
2381 	struct vop2 *vop2 = vp->vop2;
2382 	struct drm_plane *plane;
2383 	u32 layer_sel = 0xffff; /* 0xf means this layer is disabled */
2384 	u32 ovl_ctrl;
2385 
2386 	ovl_ctrl = vop2_readl(vop2, RK3576_OVL_CTRL(vp->id));
2387 	if (vcstate->yuv_overlay)
2388 		ovl_ctrl |= RK3576_OVL_CTRL__YUV_MODE;
2389 	else
2390 		ovl_ctrl &= ~RK3576_OVL_CTRL__YUV_MODE;
2391 
2392 	vop2_writel(vop2, RK3576_OVL_CTRL(vp->id), ovl_ctrl);
2393 
2394 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
2395 		struct vop2_win *win = to_vop2_win(plane);
2396 
2397 		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
2398 							  0xf);
2399 		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos,
2400 							 win->data->layer_sel_id[vp->id]);
2401 	}
2402 
2403 	vop2_writel(vop2, RK3576_OVL_LAYER_SEL(vp->id), layer_sel);
2404 }
2405 
rk3576_vop2_setup_dly_for_windows(struct vop2_video_port * vp)2406 static void rk3576_vop2_setup_dly_for_windows(struct vop2_video_port *vp)
2407 {
2408 	struct drm_plane *plane;
2409 	struct vop2_win *win;
2410 
2411 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
2412 		win = to_vop2_win(plane);
2413 		vop2_win_write(win, VOP2_WIN_DLY_NUM, 0);
2414 	}
2415 }
2416 
rk3576_vop2_setup_overlay(struct vop2_video_port * vp)2417 static void rk3576_vop2_setup_overlay(struct vop2_video_port *vp)
2418 {
2419 	struct vop2 *vop2 = vp->vop2;
2420 	struct drm_crtc *crtc = &vp->crtc;
2421 	struct drm_plane *plane;
2422 
2423 	vp->win_mask = 0;
2424 
2425 	drm_atomic_crtc_for_each_plane(plane, crtc) {
2426 		struct vop2_win *win = to_vop2_win(plane);
2427 
2428 		win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
2429 		vp->win_mask |= BIT(win->data->phys_id);
2430 
2431 		if (vop2_cluster_window(win))
2432 			vop2_setup_cluster_alpha(vop2, win);
2433 	}
2434 
2435 	if (!vp->win_mask)
2436 		return;
2437 
2438 	rk3576_vop2_setup_layer_mixer(vp);
2439 	vop2_setup_alpha(vp);
2440 	rk3576_vop2_setup_dly_for_windows(vp);
2441 }
2442 
rk3568_vop2_setup_bg_dly(struct vop2_video_port * vp)2443 static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp)
2444 {
2445 	struct drm_crtc *crtc = &vp->crtc;
2446 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
2447 	u16 hdisplay = mode->crtc_hdisplay;
2448 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
2449 	u32 bg_dly;
2450 	u32 pre_scan_dly;
2451 
2452 	bg_dly = vp->data->pre_scan_max_dly[3];
2453 	vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
2454 		    FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
2455 
2456 	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
2457 	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
2458 }
2459 
rk3576_vop2_setup_bg_dly(struct vop2_video_port * vp)2460 static void rk3576_vop2_setup_bg_dly(struct vop2_video_port *vp)
2461 {
2462 	struct drm_crtc *crtc = &vp->crtc;
2463 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
2464 	u16 hdisplay = mode->crtc_hdisplay;
2465 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
2466 	u32 bg_dly;
2467 	u32 pre_scan_dly;
2468 
2469 	bg_dly = vp->data->pre_scan_max_dly[VOP2_DLY_WIN] +
2470 		 vp->data->pre_scan_max_dly[VOP2_DLY_LAYER_MIX] +
2471 		 vp->data->pre_scan_max_dly[VOP2_DLY_HDR_MIX];
2472 
2473 	vop2_writel(vp->vop2, RK3576_OVL_BG_MIX_CTRL(vp->id),
2474 		    FIELD_PREP(RK3576_OVL_BG_MIX_CTRL__BG_DLY, bg_dly));
2475 
2476 	pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
2477 	vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
2478 }
2479 
2480 static const struct vop2_ops rk3568_vop_ops = {
2481 	.setup_intf_mux = rk3568_set_intf_mux,
2482 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
2483 	.setup_overlay = rk3568_vop2_setup_overlay,
2484 };
2485 
2486 static const struct vop2_ops rk3576_vop_ops = {
2487 	.setup_intf_mux = rk3576_set_intf_mux,
2488 	.setup_bg_dly = rk3576_vop2_setup_bg_dly,
2489 	.setup_overlay = rk3576_vop2_setup_overlay,
2490 };
2491 
2492 static const struct vop2_ops rk3588_vop_ops = {
2493 	.setup_intf_mux = rk3588_set_intf_mux,
2494 	.setup_bg_dly = rk3568_vop2_setup_bg_dly,
2495 	.setup_overlay = rk3568_vop2_setup_overlay,
2496 };
2497 
2498 static const struct vop2_data rk3566_vop = {
2499 	.version = VOP_VERSION_RK3568,
2500 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
2501 	.nr_vps = 3,
2502 	.max_input = { 4096, 2304 },
2503 	.max_output = { 4096, 2304 },
2504 	.vp = rk3568_vop_video_ports,
2505 	.win = rk3568_vop_win_data,
2506 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
2507 	.cluster_reg = rk3568_vop_cluster_regs,
2508 	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
2509 	.smart_reg = rk3568_vop_smart_regs,
2510 	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
2511 	.regs_dump = rk3568_regs_dump,
2512 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
2513 	.ops = &rk3568_vop_ops,
2514 	.soc_id = 3566,
2515 };
2516 
2517 static const struct vop2_data rk3568_vop = {
2518 	.version = VOP_VERSION_RK3568,
2519 	.feature = VOP2_FEATURE_HAS_SYS_GRF,
2520 	.nr_vps = 3,
2521 	.max_input = { 4096, 2304 },
2522 	.max_output = { 4096, 2304 },
2523 	.vp = rk3568_vop_video_ports,
2524 	.win = rk3568_vop_win_data,
2525 	.win_size = ARRAY_SIZE(rk3568_vop_win_data),
2526 	.cluster_reg = rk3568_vop_cluster_regs,
2527 	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
2528 	.smart_reg = rk3568_vop_smart_regs,
2529 	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
2530 	.regs_dump = rk3568_regs_dump,
2531 	.regs_dump_size = ARRAY_SIZE(rk3568_regs_dump),
2532 	.ops = &rk3568_vop_ops,
2533 	.soc_id = 3568,
2534 };
2535 
2536 static const struct vop2_data rk3576_vop = {
2537 	.version = VOP_VERSION_RK3576,
2538 	.feature = VOP2_FEATURE_HAS_SYS_PMU,
2539 	.nr_vps = 3,
2540 	.max_input = { 4096, 4320 },
2541 	.max_output = { 4096, 4320 },
2542 	.vp = rk3576_vop_video_ports,
2543 	.win = rk3576_vop_win_data,
2544 	.win_size = ARRAY_SIZE(rk3576_vop_win_data),
2545 	.cluster_reg = rk3576_vop_cluster_regs,
2546 	.nr_cluster_regs = ARRAY_SIZE(rk3576_vop_cluster_regs),
2547 	.smart_reg = rk3576_vop_smart_regs,
2548 	.nr_smart_regs = ARRAY_SIZE(rk3576_vop_smart_regs),
2549 	.regs_dump = rk3576_regs_dump,
2550 	.regs_dump_size = ARRAY_SIZE(rk3576_regs_dump),
2551 	.ops = &rk3576_vop_ops,
2552 	.soc_id = 3576,
2553 };
2554 
2555 static const struct vop2_data rk3588_vop = {
2556 	.version = VOP_VERSION_RK3588,
2557 	.feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF |
2558 		   VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU,
2559 	.nr_vps = 4,
2560 	.max_input = { 4096, 4320 },
2561 	.max_output = { 4096, 4320 },
2562 	.vp = rk3588_vop_video_ports,
2563 	.win = rk3588_vop_win_data,
2564 	.win_size = ARRAY_SIZE(rk3588_vop_win_data),
2565 	.cluster_reg = rk3568_vop_cluster_regs,
2566 	.nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs),
2567 	.smart_reg = rk3568_vop_smart_regs,
2568 	.nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs),
2569 	.regs_dump = rk3588_regs_dump,
2570 	.regs_dump_size = ARRAY_SIZE(rk3588_regs_dump),
2571 	.ops = &rk3588_vop_ops,
2572 	.soc_id = 3588,
2573 };
2574 
2575 static const struct of_device_id vop2_dt_match[] = {
2576 	{
2577 		.compatible = "rockchip,rk3566-vop",
2578 		.data = &rk3566_vop,
2579 	}, {
2580 		.compatible = "rockchip,rk3568-vop",
2581 		.data = &rk3568_vop,
2582 	}, {
2583 		.compatible = "rockchip,rk3576-vop",
2584 		.data = &rk3576_vop,
2585 	}, {
2586 		.compatible = "rockchip,rk3588-vop",
2587 		.data = &rk3588_vop
2588 	}, {
2589 	},
2590 };
2591 MODULE_DEVICE_TABLE(of, vop2_dt_match);
2592 
vop2_probe(struct platform_device * pdev)2593 static int vop2_probe(struct platform_device *pdev)
2594 {
2595 	struct device *dev = &pdev->dev;
2596 
2597 	return component_add(dev, &vop2_component_ops);
2598 }
2599 
vop2_remove(struct platform_device * pdev)2600 static void vop2_remove(struct platform_device *pdev)
2601 {
2602 	component_del(&pdev->dev, &vop2_component_ops);
2603 }
2604 
2605 struct platform_driver vop2_platform_driver = {
2606 	.probe = vop2_probe,
2607 	.remove = vop2_remove,
2608 	.driver = {
2609 		.name = "rockchip-vop2",
2610 		.of_match_table = vop2_dt_match,
2611 	},
2612 };
2613