1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
4 *
5 */
6
7 #include <config.h>
8 #include <common.h>
9 #include <errno.h>
10 #include <malloc.h>
11 #include <fdtdec.h>
12 #include <fdt_support.h>
13 #include <regmap.h>
14 #include <asm/arch/cpu.h>
15 #include <asm/unaligned.h>
16 #include <asm/io.h>
17 #include <linux/list.h>
18 #include <linux/log2.h>
19 #include <linux/media-bus-format.h>
20 #include <asm/arch/clock.h>
21 #include <asm/gpio.h>
22 #include <linux/err.h>
23 #include <linux/ioport.h>
24 #include <dm/device.h>
25 #include <dm/read.h>
26 #include <dm/ofnode.h>
27 #include <fixp-arith.h>
28 #include <syscon.h>
29 #include <linux/iopoll.h>
30 #include <dm/uclass-internal.h>
31 #include <stdlib.h>
32
33 #include "rockchip_display.h"
34 #include "rockchip_crtc.h"
35 #include "rockchip_connector.h"
36 #include "rockchip_phy.h"
37 #include "rockchip_post_csc.h"
38
39 /* System registers definition */
40 #define RK3568_REG_CFG_DONE 0x000
41 #define CFG_DONE_EN BIT(15)
42
43 #define RK3568_VERSION_INFO 0x004
44 #define EN_MASK 1
45
46 #define RK3568_AUTO_GATING_CTRL 0x008
47 #define AUTO_GATING_EN_SHIFT 31
48 #define PORT_DCLK_AUTO_GATING_EN_SHIFT 14
49
50 #define RK3568_SYS_AXI_LUT_CTRL 0x024
51 #define LUT_DMA_EN_SHIFT 0
52 #define DSP_VS_T_SEL_SHIFT 16
53
54 #define RK3568_DSP_IF_EN 0x028
55 #define RGB_EN_SHIFT 0
56 #define RK3588_DP0_EN_SHIFT 0
57 #define RK3588_DP1_EN_SHIFT 1
58 #define RK3588_RGB_EN_SHIFT 8
59 #define HDMI0_EN_SHIFT 1
60 #define EDP0_EN_SHIFT 3
61 #define RK3588_EDP0_EN_SHIFT 2
62 #define RK3588_HDMI0_EN_SHIFT 3
63 #define MIPI0_EN_SHIFT 4
64 #define RK3588_EDP1_EN_SHIFT 4
65 #define RK3588_HDMI1_EN_SHIFT 5
66 #define RK3588_MIPI0_EN_SHIFT 6
67 #define MIPI1_EN_SHIFT 20
68 #define RK3588_MIPI1_EN_SHIFT 7
69 #define LVDS0_EN_SHIFT 5
70 #define LVDS1_EN_SHIFT 24
71 #define BT1120_EN_SHIFT 6
72 #define BT656_EN_SHIFT 7
73 #define IF_MUX_MASK 3
74 #define RGB_MUX_SHIFT 8
75 #define HDMI0_MUX_SHIFT 10
76 #define RK3588_DP0_MUX_SHIFT 12
77 #define RK3588_DP1_MUX_SHIFT 14
78 #define EDP0_MUX_SHIFT 14
79 #define RK3588_HDMI_EDP0_MUX_SHIFT 16
80 #define RK3588_HDMI_EDP1_MUX_SHIFT 18
81 #define MIPI0_MUX_SHIFT 16
82 #define RK3588_MIPI0_MUX_SHIFT 20
83 #define MIPI1_MUX_SHIFT 21
84 #define LVDS0_MUX_SHIFT 18
85 #define LVDS1_MUX_SHIFT 25
86
87 #define RK3568_DSP_IF_CTRL 0x02c
88 #define LVDS_DUAL_EN_SHIFT 0
89 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1
90 #define LVDS_DUAL_SWAP_EN_SHIFT 2
91 #define BT656_UV_SWAP 4
92 #define BT656_YC_SWAP 5
93 #define BT656_DCLK_POL 6
94 #define RK3588_HDMI_DUAL_EN_SHIFT 8
95 #define RK3588_EDP_DUAL_EN_SHIFT 8
96 #define RK3588_DP_DUAL_EN_SHIFT 9
97 #define RK3568_MIPI_DUAL_EN_SHIFT 10
98 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11
99 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12
100
101 #define RK3568_DSP_IF_POL 0x030
102 #define IF_CTRL_REG_DONE_IMD_MASK 1
103 #define IF_CTRL_REG_DONE_IMD_SHIFT 28
104 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19
105 #define IF_CRTL_EDP_DCLK_POL_SHIT 15
106 #define IF_CTRL_EDP_PIN_POL_MASK 0x7
107 #define IF_CTRL_EDP_PIN_POL_SHIFT 12
108 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7
109 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7
110 #define IF_CRTL_HDMI_PIN_POL_SHIT 4
111 #define IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT 3
112 #define IF_CTRL_RGB_LVDS_PIN_POL_MASK 0x7
113 #define IF_CTRL_RGB_LVDS_PIN_POL_SHIFT 0
114
115 #define RK3562_MIPI_DCLK_POL_SHIFT 15
116 #define RK3562_MIPI_PIN_POL_SHIFT 12
117 #define RK3562_IF_PIN_POL_MASK 0x7
118
119 #define RK3588_DP0_PIN_POL_SHIFT 8
120 #define RK3588_DP1_PIN_POL_SHIFT 12
121 #define RK3588_IF_PIN_POL_MASK 0x7
122
123 #define HDMI_EDP0_DCLK_DIV_SHIFT 16
124 #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18
125 #define HDMI_EDP1_DCLK_DIV_SHIFT 20
126 #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22
127 #define MIPI0_PIXCLK_DIV_SHIFT 24
128 #define MIPI1_PIXCLK_DIV_SHIFT 26
129
130 #define RK3568_SYS_OTP_WIN_EN 0x50
131 #define OTP_WIN_EN_SHIFT 0
132 #define RK3568_SYS_LUT_PORT_SEL 0x58
133 #define GAMMA_PORT_SEL_MASK 0x3
134 #define GAMMA_PORT_SEL_SHIFT 0
135 #define GAMMA_AHB_WRITE_SEL_MASK 0x3
136 #define GAMMA_AHB_WRITE_SEL_SHIFT 12
137 #define PORT_MERGE_EN_SHIFT 16
138 #define ESMART_LB_MODE_SEL_MASK 0x3
139 #define ESMART_LB_MODE_SEL_SHIFT 26
140
141 #define RK3568_SYS_PD_CTRL 0x034
142 #define RK3568_VP0_LINE_FLAG 0x70
143 #define RK3568_VP1_LINE_FLAG 0x74
144 #define RK3568_VP2_LINE_FLAG 0x78
145 #define RK3568_SYS0_INT_EN 0x80
146 #define RK3568_SYS0_INT_CLR 0x84
147 #define RK3568_SYS0_INT_STATUS 0x88
148 #define RK3568_SYS1_INT_EN 0x90
149 #define RK3568_SYS1_INT_CLR 0x94
150 #define RK3568_SYS1_INT_STATUS 0x98
151 #define RK3568_VP0_INT_EN 0xA0
152 #define RK3568_VP0_INT_CLR 0xA4
153 #define RK3568_VP0_INT_STATUS 0xA8
154 #define RK3568_VP1_INT_EN 0xB0
155 #define RK3568_VP1_INT_CLR 0xB4
156 #define RK3568_VP1_INT_STATUS 0xB8
157 #define RK3568_VP2_INT_EN 0xC0
158 #define RK3568_VP2_INT_CLR 0xC4
159 #define RK3568_VP2_INT_STATUS 0xC8
160 #define RK3588_CLUSTER0_PD_EN_SHIFT 0
161 #define RK3588_CLUSTER1_PD_EN_SHIFT 1
162 #define RK3588_CLUSTER2_PD_EN_SHIFT 2
163 #define RK3588_CLUSTER3_PD_EN_SHIFT 3
164 #define RK3588_DSC_8K_PD_EN_SHIFT 5
165 #define RK3588_DSC_4K_PD_EN_SHIFT 6
166 #define RK3588_ESMART_PD_EN_SHIFT 7
167
168 #define RK3588_SYS_VAR_FREQ_CTRL 0x038
169 #define RK3588_VP0_LINE_FLAG_OR_EN_SHIFT 20
170 #define RK3588_VP0_DSP_HOLD_OR_EN_SHIFT 24
171 #define RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT 28
172
173 #define RK3568_SYS_STATUS0 0x60
174 #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8
175 #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9
176 #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10
177 #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11
178 #define RK3588_DSC_8K_PD_STATUS_SHIFT 13
179 #define RK3588_DSC_4K_PD_STATUS_SHIFT 14
180 #define RK3588_ESMART_PD_STATUS_SHIFT 15
181
182 #define RK3568_SYS_CTRL_LINE_FLAG0 0x70
183 #define LINE_FLAG_NUM_MASK 0x1fff
184 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0
185 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16
186
187 /* DSC CTRL registers definition */
188 #define RK3588_DSC_8K_SYS_CTRL 0x200
189 #define DSC_PORT_SEL_MASK 0x3
190 #define DSC_PORT_SEL_SHIFT 0
191 #define DSC_MAN_MODE_MASK 0x1
192 #define DSC_MAN_MODE_SHIFT 2
193 #define DSC_INTERFACE_MODE_MASK 0x3
194 #define DSC_INTERFACE_MODE_SHIFT 4
195 #define DSC_PIXEL_NUM_MASK 0x3
196 #define DSC_PIXEL_NUM_SHIFT 6
197 #define DSC_PXL_CLK_DIV_MASK 0x1
198 #define DSC_PXL_CLK_DIV_SHIFT 8
199 #define DSC_CDS_CLK_DIV_MASK 0x3
200 #define DSC_CDS_CLK_DIV_SHIFT 12
201 #define DSC_TXP_CLK_DIV_MASK 0x3
202 #define DSC_TXP_CLK_DIV_SHIFT 14
203 #define DSC_INIT_DLY_MODE_MASK 0x1
204 #define DSC_INIT_DLY_MODE_SHIFT 16
205 #define DSC_SCAN_EN_SHIFT 17
206 #define DSC_HALT_EN_SHIFT 18
207
208 #define RK3588_DSC_8K_RST 0x204
209 #define RST_DEASSERT_MASK 0x1
210 #define RST_DEASSERT_SHIFT 0
211
212 #define RK3588_DSC_8K_CFG_DONE 0x208
213 #define DSC_CFG_DONE_SHIFT 0
214
215 #define RK3588_DSC_8K_INIT_DLY 0x20C
216 #define DSC_INIT_DLY_NUM_MASK 0xffff
217 #define DSC_INIT_DLY_NUM_SHIFT 0
218 #define SCAN_TIMING_PARA_IMD_EN_SHIFT 16
219
220 #define RK3588_DSC_8K_HTOTAL_HS_END 0x210
221 #define DSC_HTOTAL_PW_MASK 0xffffffff
222 #define DSC_HTOTAL_PW_SHIFT 0
223
224 #define RK3588_DSC_8K_HACT_ST_END 0x214
225 #define DSC_HACT_ST_END_MASK 0xffffffff
226 #define DSC_HACT_ST_END_SHIFT 0
227
228 #define RK3588_DSC_8K_VTOTAL_VS_END 0x218
229 #define DSC_VTOTAL_PW_MASK 0xffffffff
230 #define DSC_VTOTAL_PW_SHIFT 0
231
232 #define RK3588_DSC_8K_VACT_ST_END 0x21C
233 #define DSC_VACT_ST_END_MASK 0xffffffff
234 #define DSC_VACT_ST_END_SHIFT 0
235
236 #define RK3588_DSC_8K_STATUS 0x220
237
238 /* Overlay registers definition */
239 #define RK3528_OVL_SYS 0x500
240 #define RK3528_OVL_SYS_PORT_SEL_IMD 0x504
241 #define RK3528_OVL_SYS_GATING_EN_IMD 0x508
242 #define RK3528_OVL_SYS_CLUSTER0_CTRL 0x510
243 #define RK3528_OVL_SYS_ESMART0_CTRL 0x520
244 #define ESMART_DLY_NUM_MASK 0xff
245 #define ESMART_DLY_NUM_SHIFT 0
246 #define RK3528_OVL_SYS_ESMART1_CTRL 0x524
247 #define RK3528_OVL_SYS_ESMART2_CTRL 0x528
248 #define RK3528_OVL_SYS_ESMART3_CTRL 0x52C
249 #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL 0x530
250 #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL 0x534
251 #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x538
252 #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL 0x53c
253
254 #define RK3528_OVL_PORT0_CTRL 0x600
255 #define RK3568_OVL_CTRL 0x600
256 #define OVL_MODE_SEL_MASK 0x1
257 #define OVL_MODE_SEL_SHIFT 0
258 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28
259 #define RK3528_OVL_PORT0_LAYER_SEL 0x604
260 #define RK3568_OVL_LAYER_SEL 0x604
261 #define LAYER_SEL_MASK 0xf
262
263 #define RK3568_OVL_PORT_SEL 0x608
264 #define PORT_MUX_MASK 0xf
265 #define PORT_MUX_SHIFT 0
266 #define LAYER_SEL_PORT_MASK 0x3
267 #define LAYER_SEL_PORT_SHIFT 16
268
269 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610
270 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614
271 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618
272 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C
273 #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL 0x620
274 #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL 0x624
275 #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL 0x628
276 #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL 0x62C
277 #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL 0x630
278 #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL 0x634
279 #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL 0x638
280 #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL 0x63C
281 #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL 0x640
282 #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL 0x644
283 #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL 0x648
284 #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL 0x64C
285 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650
286 #define RK3568_MIX0_DST_COLOR_CTRL 0x654
287 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658
288 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C
289 #define RK3528_HDR_SRC_COLOR_CTRL 0x660
290 #define RK3528_HDR_DST_COLOR_CTRL 0x664
291 #define RK3528_HDR_SRC_ALPHA_CTRL 0x668
292 #define RK3528_HDR_DST_ALPHA_CTRL 0x66C
293 #define RK3528_OVL_PORT0_BG_MIX_CTRL 0x670
294 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0
295 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4
296 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8
297 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC
298 #define RK3568_VP0_BG_MIX_CTRL 0x6E0
299 #define BG_MIX_CTRL_MASK 0xff
300 #define BG_MIX_CTRL_SHIFT 24
301 #define RK3568_VP1_BG_MIX_CTRL 0x6E4
302 #define RK3568_VP2_BG_MIX_CTRL 0x6E8
303 #define RK3568_CLUSTER_DLY_NUM 0x6F0
304 #define RK3568_SMART_DLY_NUM 0x6F8
305
306 #define RK3528_OVL_PORT1_CTRL 0x700
307 #define RK3528_OVL_PORT1_LAYER_SEL 0x704
308 #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL 0x720
309 #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL 0x724
310 #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL 0x728
311 #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL 0x72C
312 #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL 0x730
313 #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL 0x734
314 #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL 0x738
315 #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL 0x73C
316 #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL 0x740
317 #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL 0x744
318 #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL 0x748
319 #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL 0x74C
320 #define RK3528_OVL_PORT1_BG_MIX_CTRL 0x770
321
322 /* Video Port registers definition */
323 #define RK3568_VP0_DSP_CTRL 0xC00
324 #define OUT_MODE_MASK 0xf
325 #define OUT_MODE_SHIFT 0
326 #define DATA_SWAP_MASK 0x1f
327 #define DATA_SWAP_SHIFT 8
328 #define DSP_BG_SWAP 0x1
329 #define DSP_RB_SWAP 0x2
330 #define DSP_RG_SWAP 0x4
331 #define DSP_DELTA_SWAP 0x8
332 #define CORE_DCLK_DIV_EN_SHIFT 4
333 #define P2I_EN_SHIFT 5
334 #define DSP_FILED_POL 6
335 #define INTERLACE_EN_SHIFT 7
336 #define DSP_X_MIR_EN_SHIFT 13
337 #define POST_DSP_OUT_R2Y_SHIFT 15
338 #define PRE_DITHER_DOWN_EN_SHIFT 16
339 #define DITHER_DOWN_EN_SHIFT 17
340 #define DITHER_DOWN_MODE_SHIFT 20
341 #define GAMMA_UPDATE_EN_SHIFT 22
342 #define DSP_LUT_EN_SHIFT 28
343
344 #define STANDBY_EN_SHIFT 31
345
346 #define RK3568_VP0_MIPI_CTRL 0xC04
347 #define DCLK_DIV2_SHIFT 4
348 #define DCLK_DIV2_MASK 0x3
349 #define MIPI_DUAL_EN_SHIFT 20
350 #define MIPI_DUAL_SWAP_EN_SHIFT 21
351 #define EDPI_TE_EN 28
352 #define EDPI_WMS_HOLD_EN 30
353 #define EDPI_WMS_FS 31
354
355
356 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08
357
358 #define RK3568_VP0_DCLK_SEL 0xC0C
359
360 #define RK3568_VP0_3D_LUT_CTRL 0xC10
361 #define VP0_3D_LUT_EN_SHIFT 0
362 #define VP0_3D_LUT_UPDATE_SHIFT 2
363
364 #define RK3588_VP0_CLK_CTRL 0xC0C
365 #define DCLK_CORE_DIV_SHIFT 0
366 #define DCLK_OUT_DIV_SHIFT 2
367
368 #define RK3568_VP0_3D_LUT_MST 0xC20
369
370 #define RK3568_VP0_DSP_BG 0xC2C
371 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30
372 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34
373 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38
374 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C
375 #define RK3568_VP0_POST_SCL_CTRL 0xC40
376 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44
377 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48
378 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C
379 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50
380 #define RK3568_VP0_DSP_VACT_ST_END 0xC54
381 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58
382 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C
383
384 #define RK3568_VP0_BCSH_CTRL 0xC60
385 #define BCSH_CTRL_Y2R_SHIFT 0
386 #define BCSH_CTRL_Y2R_MASK 0x1
387 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2
388 #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3
389 #define BCSH_CTRL_R2Y_SHIFT 4
390 #define BCSH_CTRL_R2Y_MASK 0x1
391 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6
392 #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3
393
394 #define RK3568_VP0_BCSH_BCS 0xC64
395 #define BCSH_BRIGHTNESS_SHIFT 0
396 #define BCSH_BRIGHTNESS_MASK 0xFF
397 #define BCSH_CONTRAST_SHIFT 8
398 #define BCSH_CONTRAST_MASK 0x1FF
399 #define BCSH_SATURATION_SHIFT 20
400 #define BCSH_SATURATION_MASK 0x3FF
401 #define BCSH_OUT_MODE_SHIFT 30
402 #define BCSH_OUT_MODE_MASK 0x3
403
404 #define RK3568_VP0_BCSH_H 0xC68
405 #define BCSH_SIN_HUE_SHIFT 0
406 #define BCSH_SIN_HUE_MASK 0x1FF
407 #define BCSH_COS_HUE_SHIFT 16
408 #define BCSH_COS_HUE_MASK 0x1FF
409
410 #define RK3568_VP0_BCSH_COLOR 0xC6C
411 #define BCSH_EN_SHIFT 31
412 #define BCSH_EN_MASK 1
413
414 #define RK3528_VP0_ACM_CTRL 0xCD0
415 #define POST_CSC_COE00_MASK 0xFFFF
416 #define POST_CSC_COE00_SHIFT 16
417 #define POST_R2Y_MODE_MASK 0x7
418 #define POST_R2Y_MODE_SHIFT 8
419 #define POST_CSC_MODE_MASK 0x7
420 #define POST_CSC_MODE_SHIFT 3
421 #define POST_R2Y_EN_MASK 0x1
422 #define POST_R2Y_EN_SHIFT 2
423 #define POST_CSC_EN_MASK 0x1
424 #define POST_CSC_EN_SHIFT 1
425 #define POST_ACM_BYPASS_EN_MASK 0x1
426 #define POST_ACM_BYPASS_EN_SHIFT 0
427 #define RK3528_VP0_CSC_COE01_02 0xCD4
428 #define RK3528_VP0_CSC_COE10_11 0xCD8
429 #define RK3528_VP0_CSC_COE12_20 0xCDC
430 #define RK3528_VP0_CSC_COE21_22 0xCE0
431 #define RK3528_VP0_CSC_OFFSET0 0xCE4
432 #define RK3528_VP0_CSC_OFFSET1 0xCE8
433 #define RK3528_VP0_CSC_OFFSET2 0xCEC
434
435 #define RK3562_VP0_MCU_CTRL 0xCF8
436 #define MCU_TYPE_SHIFT 31
437 #define MCU_BYPASS_SHIFT 30
438 #define MCU_RS_SHIFT 29
439 #define MCU_FRAME_ST_SHIFT 28
440 #define MCU_HOLD_MODE_SHIFT 27
441 #define MCU_CLK_SEL_SHIFT 26
442 #define MCU_CLK_SEL_MASK 0x1
443 #define MCU_RW_PEND_SHIFT 20
444 #define MCU_RW_PEND_MASK 0x3F
445 #define MCU_RW_PST_SHIFT 16
446 #define MCU_RW_PST_MASK 0xF
447 #define MCU_CS_PEND_SHIFT 10
448 #define MCU_CS_PEND_MASK 0x3F
449 #define MCU_CS_PST_SHIFT 6
450 #define MCU_CS_PST_MASK 0xF
451 #define MCU_PIX_TOTAL_SHIFT 0
452 #define MCU_PIX_TOTAL_MASK 0x3F
453
454 #define RK3562_VP0_MCU_RW_BYPASS_PORT 0xCFC
455 #define MCU_WRITE_DATA_BYPASS_SHIFT 0
456 #define MCU_WRITE_DATA_BYPASS_MASK 0xFFFFFFFF
457
458 #define RK3568_VP1_DSP_CTRL 0xD00
459 #define RK3568_VP1_MIPI_CTRL 0xD04
460 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08
461 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30
462 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34
463 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38
464 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C
465 #define RK3568_VP1_POST_SCL_CTRL 0xD40
466 #define RK3568_VP1_DSP_HACT_INFO 0xD34
467 #define RK3568_VP1_DSP_VACT_INFO 0xD38
468 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44
469 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48
470 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C
471 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50
472 #define RK3568_VP1_DSP_VACT_ST_END 0xD54
473 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58
474 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C
475
476 #define RK3568_VP2_DSP_CTRL 0xE00
477 #define RK3568_VP2_MIPI_CTRL 0xE04
478 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08
479 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30
480 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34
481 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38
482 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C
483 #define RK3568_VP2_POST_SCL_CTRL 0xE40
484 #define RK3568_VP2_DSP_HACT_INFO 0xE34
485 #define RK3568_VP2_DSP_VACT_INFO 0xE38
486 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44
487 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48
488 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C
489 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50
490 #define RK3568_VP2_DSP_VACT_ST_END 0xE54
491 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58
492 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C
493
494 /* Cluster0 register definition */
495 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000
496 #define CLUSTER_YUV2RGB_EN_SHIFT 8
497 #define CLUSTER_RGB2YUV_EN_SHIFT 9
498 #define CLUSTER_CSC_MODE_SHIFT 10
499 #define CLUSTER_DITHER_UP_EN_SHIFT 18
500 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004
501 #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT 12
502 #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT 14
503 #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT 14
504 #define AVG2_MASK 0x1
505 #define CLUSTER_AVG2_SHIFT 18
506 #define AVG4_MASK 0x1
507 #define CLUSTER_AVG4_SHIFT 19
508 #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT 22
509 #define CLUSTER_XGT_EN_SHIFT 24
510 #define XGT_MODE_MASK 0x3
511 #define CLUSTER_XGT_MODE_SHIFT 25
512 #define CLUSTER_XAVG_EN_SHIFT 27
513 #define CLUSTER_YRGB_GT2_SHIFT 28
514 #define CLUSTER_YRGB_GT4_SHIFT 29
515 #define RK3568_CLUSTER0_WIN0_CTRL2 0x1008
516 #define CLUSTER_AXI_YRGB_ID_MASK 0x1f
517 #define CLUSTER_AXI_YRGB_ID_SHIFT 0
518 #define CLUSTER_AXI_UV_ID_MASK 0x1f
519 #define CLUSTER_AXI_UV_ID_SHIFT 5
520
521 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010
522 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014
523 #define RK3568_CLUSTER0_WIN0_VIR 0x1018
524 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020
525 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024
526 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028
527 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030
528 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054
529 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058
530 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C
531 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060
532 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064
533 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068
534 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C
535 #define CLUSTER_AFBCD_HALF_BLOCK_SHIFT 7
536
537 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080
538 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084
539 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090
540 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094
541 #define RK3568_CLUSTER0_WIN1_VIR 0x1098
542 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0
543 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4
544 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8
545 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0
546 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4
547 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8
548 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC
549 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0
550 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4
551 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8
552 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC
553
554 #define RK3568_CLUSTER0_CTRL 0x1100
555 #define CLUSTER_EN_SHIFT 0
556 #define CLUSTER_AXI_ID_MASK 0x1
557 #define CLUSTER_AXI_ID_SHIFT 13
558
559 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200
560 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204
561 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210
562 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214
563 #define RK3568_CLUSTER1_WIN0_VIR 0x1218
564 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220
565 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224
566 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228
567 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230
568 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254
569 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258
570 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C
571 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260
572 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264
573 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268
574 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C
575
576 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280
577 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284
578 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290
579 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294
580 #define RK3568_CLUSTER1_WIN1_VIR 0x1298
581 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0
582 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4
583 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8
584 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0
585 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4
586 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8
587 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC
588 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0
589 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4
590 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8
591 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC
592
593 #define RK3568_CLUSTER1_CTRL 0x1300
594
595 /* Esmart register definition */
596 #define RK3568_ESMART0_CTRL0 0x1800
597 #define RGB2YUV_EN_SHIFT 1
598 #define CSC_MODE_SHIFT 2
599 #define CSC_MODE_MASK 0x3
600 #define ESMART_LB_SELECT_SHIFT 12
601 #define ESMART_LB_SELECT_MASK 0x3
602
603 #define RK3568_ESMART0_CTRL1 0x1804
604 #define ESMART_AXI_YRGB_ID_MASK 0x1f
605 #define ESMART_AXI_YRGB_ID_SHIFT 4
606 #define ESMART_AXI_UV_ID_MASK 0x1f
607 #define ESMART_AXI_UV_ID_SHIFT 12
608 #define YMIRROR_EN_SHIFT 31
609
610 #define RK3568_ESMART0_AXI_CTRL 0x1808
611 #define ESMART_AXI_ID_MASK 0x1
612 #define ESMART_AXI_ID_SHIFT 1
613
614 #define RK3568_ESMART0_REGION0_CTRL 0x1810
615 #define WIN_EN_SHIFT 0
616 #define WIN_FORMAT_MASK 0x1f
617 #define WIN_FORMAT_SHIFT 1
618 #define REGION0_DITHER_UP_EN_SHIFT 12
619 #define REGION0_RB_SWAP_SHIFT 14
620 #define ESMART_XAVG_EN_SHIFT 20
621 #define ESMART_XGT_EN_SHIFT 21
622 #define ESMART_XGT_MODE_SHIFT 22
623
624 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814
625 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818
626 #define RK3568_ESMART0_REGION0_VIR 0x181C
627 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820
628 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824
629 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828
630 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830
631 #define YRGB_XSCL_MODE_MASK 0x3
632 #define YRGB_XSCL_MODE_SHIFT 0
633 #define YRGB_XSCL_FILTER_MODE_MASK 0x3
634 #define YRGB_XSCL_FILTER_MODE_SHIFT 2
635 #define YRGB_YSCL_MODE_MASK 0x3
636 #define YRGB_YSCL_MODE_SHIFT 4
637 #define YRGB_YSCL_FILTER_MODE_MASK 0x3
638 #define YRGB_YSCL_FILTER_MODE_SHIFT 6
639
640 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834
641 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838
642 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C
643 #define RK3568_ESMART0_REGION1_CTRL 0x1840
644 #define YRGB_GT2_MASK 0x1
645 #define YRGB_GT2_SHIFT 8
646 #define YRGB_GT4_MASK 0x1
647 #define YRGB_GT4_SHIFT 9
648
649 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844
650 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848
651 #define RK3568_ESMART0_REGION1_VIR 0x184C
652 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850
653 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854
654 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858
655 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860
656 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864
657 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868
658 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C
659 #define RK3568_ESMART0_REGION2_CTRL 0x1870
660 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874
661 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878
662 #define RK3568_ESMART0_REGION2_VIR 0x187C
663 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880
664 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884
665 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888
666 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890
667 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894
668 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898
669 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C
670 #define RK3568_ESMART0_REGION3_CTRL 0x18A0
671 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4
672 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8
673 #define RK3568_ESMART0_REGION3_VIR 0x18AC
674 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0
675 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4
676 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8
677 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0
678 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4
679 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8
680 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC
681
682 #define RK3568_ESMART1_CTRL0 0x1A00
683 #define RK3568_ESMART1_CTRL1 0x1A04
684 #define RK3568_ESMART1_REGION0_CTRL 0x1A10
685 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14
686 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18
687 #define RK3568_ESMART1_REGION0_VIR 0x1A1C
688 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20
689 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24
690 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28
691 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30
692 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34
693 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38
694 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C
695 #define RK3568_ESMART1_REGION1_CTRL 0x1A40
696 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44
697 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48
698 #define RK3568_ESMART1_REGION1_VIR 0x1A4C
699 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50
700 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54
701 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58
702 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60
703 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64
704 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68
705 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C
706 #define RK3568_ESMART1_REGION2_CTRL 0x1A70
707 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74
708 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78
709 #define RK3568_ESMART1_REGION2_VIR 0x1A7C
710 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80
711 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84
712 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88
713 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90
714 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94
715 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98
716 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C
717 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0
718 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4
719 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8
720 #define RK3568_ESMART1_REGION3_VIR 0x1AAC
721 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0
722 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4
723 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8
724 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0
725 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4
726 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8
727 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC
728
729 #define RK3568_SMART0_CTRL0 0x1C00
730 #define RK3568_SMART0_CTRL1 0x1C04
731 #define RK3568_SMART0_REGION0_CTRL 0x1C10
732 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14
733 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18
734 #define RK3568_SMART0_REGION0_VIR 0x1C1C
735 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20
736 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24
737 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28
738 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30
739 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34
740 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38
741 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C
742 #define RK3568_SMART0_REGION1_CTRL 0x1C40
743 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44
744 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48
745 #define RK3568_SMART0_REGION1_VIR 0x1C4C
746 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50
747 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54
748 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58
749 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60
750 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64
751 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68
752 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C
753 #define RK3568_SMART0_REGION2_CTRL 0x1C70
754 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74
755 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78
756 #define RK3568_SMART0_REGION2_VIR 0x1C7C
757 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80
758 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84
759 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88
760 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90
761 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94
762 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98
763 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C
764 #define RK3568_SMART0_REGION3_CTRL 0x1CA0
765 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4
766 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8
767 #define RK3568_SMART0_REGION3_VIR 0x1CAC
768 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0
769 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4
770 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8
771 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0
772 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4
773 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8
774 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC
775
776 #define RK3568_SMART1_CTRL0 0x1E00
777 #define RK3568_SMART1_CTRL1 0x1E04
778 #define RK3568_SMART1_REGION0_CTRL 0x1E10
779 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14
780 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18
781 #define RK3568_SMART1_REGION0_VIR 0x1E1C
782 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20
783 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24
784 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28
785 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30
786 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34
787 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38
788 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C
789 #define RK3568_SMART1_REGION1_CTRL 0x1E40
790 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44
791 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48
792 #define RK3568_SMART1_REGION1_VIR 0x1E4C
793 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50
794 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54
795 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58
796 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60
797 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64
798 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68
799 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C
800 #define RK3568_SMART1_REGION2_CTRL 0x1E70
801 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74
802 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78
803 #define RK3568_SMART1_REGION2_VIR 0x1E7C
804 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80
805 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84
806 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88
807 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90
808 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94
809 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98
810 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C
811 #define RK3568_SMART1_REGION3_CTRL 0x1EA0
812 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4
813 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8
814 #define RK3568_SMART1_REGION3_VIR 0x1EAC
815 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0
816 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4
817 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8
818 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0
819 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4
820 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8
821 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC
822
823 /* HDR register definition */
824 #define RK3568_HDR_LUT_CTRL 0x2000
825
826 #define RK3588_VP3_DSP_CTRL 0xF00
827 #define RK3588_CLUSTER2_WIN0_CTRL0 0x1400
828 #define RK3588_CLUSTER3_WIN0_CTRL0 0x1600
829
830 /* DSC 8K/4K register definition */
831 #define RK3588_DSC_8K_PPS0_3 0x4000
832 #define RK3588_DSC_8K_CTRL0 0x40A0
833 #define DSC_EN_SHIFT 0
834 #define DSC_RBIT_SHIFT 2
835 #define DSC_RBYT_SHIFT 3
836 #define DSC_FLAL_SHIFT 4
837 #define DSC_MER_SHIFT 5
838 #define DSC_EPB_SHIFT 6
839 #define DSC_EPL_SHIFT 7
840 #define DSC_NSLC_MASK 0x7
841 #define DSC_NSLC_SHIFT 16
842 #define DSC_SBO_SHIFT 28
843 #define DSC_IFEP_SHIFT 29
844 #define DSC_PPS_UPD_SHIFT 31
845 #define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT) | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \
846 (1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT) | (0 << DSC_EPB_SHIFT) | \
847 (1 << DSC_EPL_SHIFT) | (1 << DSC_SBO_SHIFT))
848
849 #define RK3588_DSC_8K_CTRL1 0x40A4
850 #define RK3588_DSC_8K_STS0 0x40A8
851 #define RK3588_DSC_8K_ERS 0x40C4
852
853 #define RK3588_DSC_4K_PPS0_3 0x4100
854 #define RK3588_DSC_4K_CTRL0 0x41A0
855 #define RK3588_DSC_4K_CTRL1 0x41A4
856 #define RK3588_DSC_4K_STS0 0x41A8
857 #define RK3588_DSC_4K_ERS 0x41C4
858
859 /* RK3528 HDR register definition */
860 #define RK3528_HDR_LUT_CTRL 0x2000
861
862 /* RK3528 ACM register definition */
863 #define RK3528_ACM_CTRL 0x6400
864 #define RK3528_ACM_DELTA_RANGE 0x6404
865 #define RK3528_ACM_FETCH_START 0x6408
866 #define RK3528_ACM_FETCH_DONE 0x6420
867 #define RK3528_ACM_YHS_DEL_HY_SEG0 0x6500
868 #define RK3528_ACM_YHS_DEL_HY_SEG152 0x6760
869 #define RK3528_ACM_YHS_DEL_HS_SEG0 0x6764
870 #define RK3528_ACM_YHS_DEL_HS_SEG220 0x6ad4
871 #define RK3528_ACM_YHS_DEL_HGAIN_SEG0 0x6ad8
872 #define RK3528_ACM_YHS_DEL_HGAIN_SEG64 0x6bd8
873
874 #define RK3568_MAX_REG 0x1ED0
875
876 #define RK3562_GRF_IOC_VO_IO_CON 0x10500
877 #define RK3568_GRF_VO_CON1 0x0364
878 #define GRF_BT656_CLK_INV_SHIFT 1
879 #define GRF_BT1120_CLK_INV_SHIFT 2
880 #define GRF_RGB_DCLK_INV_SHIFT 3
881
882 #define RK3588_GRF_VOP_CON2 0x0008
883 #define RK3588_GRF_EDP0_ENABLE_SHIFT 0
884 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1
885 #define RK3588_GRF_EDP1_ENABLE_SHIFT 3
886 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4
887
888 #define RK3588_GRF_VO1_CON0 0x0000
889 #define HDMI_SYNC_POL_MASK 0x3
890 #define HDMI0_SYNC_POL_SHIFT 5
891 #define HDMI1_SYNC_POL_SHIFT 7
892
893 #define RK3588_PMU_BISR_CON3 0x20C
894 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9
895 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10
896 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11
897 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12
898 #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13
899 #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14
900 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15
901
902 #define RK3588_PMU_BISR_STATUS5 0x294
903 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9
904 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10
905 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11
906 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12
907 #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13
908 #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14
909 #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15
910
911 #define VOP2_LAYER_MAX 8
912
913 #define VOP2_MAX_VP_OUTPUT_WIDTH 4096
914
915 #define VOP_FEATURE_OUTPUT_10BIT BIT(0)
916
917 /* KHz */
918 #define VOP2_MAX_DCLK_RATE 600000
919
920 /*
921 * vop2 dsc id
922 */
923 #define ROCKCHIP_VOP2_DSC_8K 0
924 #define ROCKCHIP_VOP2_DSC_4K 1
925
926 /*
927 * vop2 internal power domain id,
928 * should be all none zero, 0 will be
929 * treat as invalid;
930 */
931 #define VOP2_PD_CLUSTER0 BIT(0)
932 #define VOP2_PD_CLUSTER1 BIT(1)
933 #define VOP2_PD_CLUSTER2 BIT(2)
934 #define VOP2_PD_CLUSTER3 BIT(3)
935 #define VOP2_PD_DSC_8K BIT(5)
936 #define VOP2_PD_DSC_4K BIT(6)
937 #define VOP2_PD_ESMART BIT(7)
938
939 #define VOP2_PLANE_NO_SCALING BIT(16)
940
941 #define VOP_FEATURE_OUTPUT_10BIT BIT(0)
942 #define VOP_FEATURE_AFBDC BIT(1)
943 #define VOP_FEATURE_ALPHA_SCALE BIT(2)
944 #define VOP_FEATURE_HDR10 BIT(3)
945 #define VOP_FEATURE_NEXT_HDR BIT(4)
946 /* a feature to splice two windows and two vps to support resolution > 4096 */
947 #define VOP_FEATURE_SPLICE BIT(5)
948 #define VOP_FEATURE_OVERSCAN BIT(6)
949 #define VOP_FEATURE_VIVID_HDR BIT(7)
950 #define VOP_FEATURE_POST_ACM BIT(8)
951 #define VOP_FEATURE_POST_CSC BIT(9)
952
953 #define WIN_FEATURE_HDR2SDR BIT(0)
954 #define WIN_FEATURE_SDR2HDR BIT(1)
955 #define WIN_FEATURE_PRE_OVERLAY BIT(2)
956 #define WIN_FEATURE_AFBDC BIT(3)
957 #define WIN_FEATURE_CLUSTER_MAIN BIT(4)
958 #define WIN_FEATURE_CLUSTER_SUB BIT(5)
959 /* a mirror win can only get fb address
960 * from source win:
961 * Cluster1---->Cluster0
962 * Esmart1 ---->Esmart0
963 * Smart1 ---->Smart0
964 * This is a feather on rk3566
965 */
966 #define WIN_FEATURE_MIRROR BIT(6)
967 #define WIN_FEATURE_MULTI_AREA BIT(7)
968 #define WIN_FEATURE_Y2R_13BIT_DEPTH BIT(8)
969
970 #define V4L2_COLORSPACE_BT709F 0xfe
971 #define V4L2_COLORSPACE_BT2020F 0xff
972
973 enum vop_csc_format {
974 CSC_BT601L,
975 CSC_BT709L,
976 CSC_BT601F,
977 CSC_BT2020,
978 CSC_BT709L_13BIT,
979 CSC_BT709F_13BIT,
980 CSC_BT2020L_13BIT,
981 CSC_BT2020F_13BIT,
982 };
983
984 enum vop_csc_bit_depth {
985 CSC_10BIT_DEPTH,
986 CSC_13BIT_DEPTH,
987 };
988
989 enum vop2_pol {
990 HSYNC_POSITIVE = 0,
991 VSYNC_POSITIVE = 1,
992 DEN_NEGATIVE = 2,
993 DCLK_INVERT = 3
994 };
995
996 enum vop2_bcsh_out_mode {
997 BCSH_OUT_MODE_BLACK,
998 BCSH_OUT_MODE_BLUE,
999 BCSH_OUT_MODE_COLOR_BAR,
1000 BCSH_OUT_MODE_NORMAL_VIDEO,
1001 };
1002
1003 #define _VOP_REG(off, _mask, _shift, _write_mask) \
1004 { \
1005 .offset = off, \
1006 .mask = _mask, \
1007 .shift = _shift, \
1008 .write_mask = _write_mask, \
1009 }
1010
1011 #define VOP_REG(off, _mask, _shift) \
1012 _VOP_REG(off, _mask, _shift, false)
1013 enum dither_down_mode {
1014 RGB888_TO_RGB565 = 0x0,
1015 RGB888_TO_RGB666 = 0x1
1016 };
1017
1018 enum vop2_video_ports_id {
1019 VOP2_VP0,
1020 VOP2_VP1,
1021 VOP2_VP2,
1022 VOP2_VP3,
1023 VOP2_VP_MAX,
1024 };
1025
1026 enum vop2_layer_type {
1027 CLUSTER_LAYER = 0,
1028 ESMART_LAYER = 1,
1029 SMART_LAYER = 2,
1030 };
1031
1032 /* This define must same with kernel win phy id */
1033 enum vop2_layer_phy_id {
1034 ROCKCHIP_VOP2_CLUSTER0 = 0,
1035 ROCKCHIP_VOP2_CLUSTER1,
1036 ROCKCHIP_VOP2_ESMART0,
1037 ROCKCHIP_VOP2_ESMART1,
1038 ROCKCHIP_VOP2_SMART0,
1039 ROCKCHIP_VOP2_SMART1,
1040 ROCKCHIP_VOP2_CLUSTER2,
1041 ROCKCHIP_VOP2_CLUSTER3,
1042 ROCKCHIP_VOP2_ESMART2,
1043 ROCKCHIP_VOP2_ESMART3,
1044 ROCKCHIP_VOP2_LAYER_MAX,
1045 };
1046
1047 enum vop2_scale_up_mode {
1048 VOP2_SCALE_UP_NRST_NBOR,
1049 VOP2_SCALE_UP_BIL,
1050 VOP2_SCALE_UP_BIC,
1051 };
1052
1053 enum vop2_scale_down_mode {
1054 VOP2_SCALE_DOWN_NRST_NBOR,
1055 VOP2_SCALE_DOWN_BIL,
1056 VOP2_SCALE_DOWN_AVG,
1057 };
1058
1059 enum scale_mode {
1060 SCALE_NONE = 0x0,
1061 SCALE_UP = 0x1,
1062 SCALE_DOWN = 0x2
1063 };
1064
1065 enum vop_dsc_interface_mode {
1066 VOP_DSC_IF_DISABLE = 0,
1067 VOP_DSC_IF_HDMI = 1,
1068 VOP_DSC_IF_MIPI_DS_MODE = 2,
1069 VOP_DSC_IF_MIPI_VIDEO_MODE = 3,
1070 };
1071
1072 enum vop3_pre_scale_down_mode {
1073 VOP3_PRE_SCALE_UNSPPORT,
1074 VOP3_PRE_SCALE_DOWN_GT,
1075 VOP3_PRE_SCALE_DOWN_AVG,
1076 };
1077
1078 enum vop3_esmart_lb_mode {
1079 VOP3_ESMART_8K_MODE,
1080 VOP3_ESMART_4K_4K_MODE,
1081 VOP3_ESMART_4K_2K_2K_MODE,
1082 VOP3_ESMART_2K_2K_2K_2K_MODE,
1083 };
1084
1085 struct vop2_layer {
1086 u8 id;
1087 /**
1088 * @win_phys_id: window id of the layer selected.
1089 * Every layer must make sure to select different
1090 * windows of others.
1091 */
1092 u8 win_phys_id;
1093 };
1094
1095 struct vop2_power_domain_data {
1096 u8 id;
1097 u8 parent_id;
1098 /*
1099 * @module_id_mask: module id of which module this power domain is belongs to.
1100 * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3
1101 */
1102 u32 module_id_mask;
1103 };
1104
1105 struct vop2_win_data {
1106 char *name;
1107 u8 phys_id;
1108 enum vop2_layer_type type;
1109 u8 win_sel_port_offset;
1110 u8 layer_sel_win_id[VOP2_VP_MAX];
1111 u8 axi_id;
1112 u8 axi_uv_id;
1113 u8 axi_yrgb_id;
1114 u8 splice_win_id;
1115 u8 pd_id;
1116 u8 hsu_filter_mode;
1117 u8 hsd_filter_mode;
1118 u8 vsu_filter_mode;
1119 u8 vsd_filter_mode;
1120 u8 hsd_pre_filter_mode;
1121 u8 vsd_pre_filter_mode;
1122 u8 scale_engine_num;
1123 u32 reg_offset;
1124 u32 max_upscale_factor;
1125 u32 max_downscale_factor;
1126 bool splice_mode_right;
1127 };
1128
1129 struct vop2_vp_data {
1130 u32 feature;
1131 u8 pre_scan_max_dly;
1132 u8 layer_mix_dly;
1133 u8 hdr_mix_dly;
1134 u8 win_dly;
1135 u8 splice_vp_id;
1136 struct vop_rect max_output;
1137 u32 max_dclk;
1138 };
1139
1140 struct vop2_plane_table {
1141 enum vop2_layer_phy_id plane_id;
1142 enum vop2_layer_type plane_type;
1143 };
1144
1145 struct vop2_vp_plane_mask {
1146 u8 primary_plane_id; /* use this win to show logo */
1147 u8 attached_layers_nr; /* number layers attach to this vp */
1148 u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */
1149 u32 plane_mask;
1150 int cursor_plane_id;
1151 };
1152
1153 struct vop2_dsc_data {
1154 u8 id;
1155 u8 pd_id;
1156 u8 max_slice_num;
1157 u8 max_linebuf_depth; /* used to generate the bitstream */
1158 u8 min_bits_per_pixel; /* bit num after encoder compress */
1159 const char *dsc_txp_clk_src_name;
1160 const char *dsc_txp_clk_name;
1161 const char *dsc_pxl_clk_name;
1162 const char *dsc_cds_clk_name;
1163 };
1164
1165 struct dsc_error_info {
1166 u32 dsc_error_val;
1167 char dsc_error_info[50];
1168 };
1169
1170 struct vop2_dump_regs {
1171 u32 offset;
1172 const char *name;
1173 u32 state_base;
1174 u32 state_mask;
1175 u32 state_shift;
1176 bool enable_state;
1177 };
1178
1179 struct vop2_data {
1180 u32 version;
1181 u32 esmart_lb_mode;
1182 struct vop2_vp_data *vp_data;
1183 struct vop2_win_data *win_data;
1184 struct vop2_vp_plane_mask *plane_mask;
1185 struct vop2_plane_table *plane_table;
1186 struct vop2_power_domain_data *pd;
1187 struct vop2_dsc_data *dsc;
1188 struct dsc_error_info *dsc_error_ecw;
1189 struct dsc_error_info *dsc_error_buffer_flow;
1190 struct vop2_dump_regs *dump_regs;
1191 u8 *vp_primary_plane_order;
1192 u8 nr_vps;
1193 u8 nr_layers;
1194 u8 nr_mixers;
1195 u8 nr_gammas;
1196 u8 nr_pd;
1197 u8 nr_dscs;
1198 u8 nr_dsc_ecw;
1199 u8 nr_dsc_buffer_flow;
1200 u32 reg_len;
1201 u32 dump_regs_size;
1202 };
1203
1204 struct vop2 {
1205 u32 *regsbak;
1206 void *regs;
1207 void *grf;
1208 void *vop_grf;
1209 void *vo1_grf;
1210 void *sys_pmu;
1211 u32 reg_len;
1212 u32 version;
1213 u32 esmart_lb_mode;
1214 bool global_init;
1215 const struct vop2_data *data;
1216 struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX];
1217 };
1218
1219 static struct vop2 *rockchip_vop2;
1220
is_vop3(struct vop2 * vop2)1221 static inline bool is_vop3(struct vop2 *vop2)
1222 {
1223 if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588)
1224 return false;
1225 else
1226 return true;
1227 }
1228
1229 /*
1230 * bli_sd_factor = (src - 1) / (dst - 1) << 12;
1231 * avg_sd_factor:
1232 * bli_su_factor:
1233 * bic_su_factor:
1234 * = (src - 1) / (dst - 1) << 16;
1235 *
1236 * ygt2 enable: dst get one line from two line of the src
1237 * ygt4 enable: dst get one line from four line of the src.
1238 *
1239 */
1240 #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1))
1241 #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1))
1242
1243 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \
1244 (fac * (dst - 1) >> 12 < (src - 1))
1245 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \
1246 (fac * (dst - 1) >> 16 < (src - 1))
1247 #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \
1248 (fac * (dst - 1) >> 16 < (src - 1))
1249
vop2_scale_factor(enum scale_mode mode,int32_t filter_mode,uint32_t src,uint32_t dst)1250 static uint16_t vop2_scale_factor(enum scale_mode mode,
1251 int32_t filter_mode,
1252 uint32_t src, uint32_t dst)
1253 {
1254 uint32_t fac = 0;
1255 int i = 0;
1256
1257 if (mode == SCALE_NONE)
1258 return 0;
1259
1260 /*
1261 * A workaround to avoid zero div.
1262 */
1263 if ((dst == 1) || (src == 1)) {
1264 dst = dst + 1;
1265 src = src + 1;
1266 }
1267
1268 if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
1269 fac = VOP2_BILI_SCL_DN(src, dst);
1270 for (i = 0; i < 100; i++) {
1271 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1272 break;
1273 fac -= 1;
1274 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1275 }
1276 } else {
1277 fac = VOP2_COMMON_SCL(src, dst);
1278 for (i = 0; i < 100; i++) {
1279 if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac))
1280 break;
1281 fac -= 1;
1282 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1283 }
1284 }
1285
1286 return fac;
1287 }
1288
vop3_scale_up_fac_check(uint32_t src,uint32_t dst,uint32_t fac,bool is_hor)1289 static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor)
1290 {
1291 if (is_hor)
1292 return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac);
1293 return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac);
1294 }
1295
vop3_scale_factor(enum scale_mode mode,uint32_t src,uint32_t dst,bool is_hor)1296 static uint16_t vop3_scale_factor(enum scale_mode mode,
1297 uint32_t src, uint32_t dst, bool is_hor)
1298 {
1299 uint32_t fac = 0;
1300 int i = 0;
1301
1302 if (mode == SCALE_NONE)
1303 return 0;
1304
1305 /*
1306 * A workaround to avoid zero div.
1307 */
1308 if ((dst == 1) || (src == 1)) {
1309 dst = dst + 1;
1310 src = src + 1;
1311 }
1312
1313 if (mode == SCALE_DOWN) {
1314 fac = VOP2_BILI_SCL_DN(src, dst);
1315 for (i = 0; i < 100; i++) {
1316 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac))
1317 break;
1318 fac -= 1;
1319 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1320 }
1321 } else {
1322 fac = VOP2_COMMON_SCL(src, dst);
1323 for (i = 0; i < 100; i++) {
1324 if (vop3_scale_up_fac_check(src, dst, fac, is_hor))
1325 break;
1326 fac -= 1;
1327 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
1328 }
1329 }
1330
1331 return fac;
1332 }
1333
scl_get_scl_mode(int src,int dst)1334 static inline enum scale_mode scl_get_scl_mode(int src, int dst)
1335 {
1336 if (src < dst)
1337 return SCALE_UP;
1338 else if (src > dst)
1339 return SCALE_DOWN;
1340
1341 return SCALE_NONE;
1342 }
1343
interpolate(int x1,int y1,int x2,int y2,int x)1344 static inline int interpolate(int x1, int y1, int x2, int y2, int x)
1345 {
1346 return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
1347 }
1348
vop2_get_primary_plane(struct vop2 * vop2,u32 plane_mask)1349 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask)
1350 {
1351 int i = 0;
1352
1353 for (i = 0; i < vop2->data->nr_layers; i++) {
1354 if (plane_mask & BIT(vop2->data->vp_primary_plane_order[i]))
1355 return vop2->data->vp_primary_plane_order[i];
1356 }
1357
1358 return vop2->data->vp_primary_plane_order[0];
1359 }
1360
scl_cal_scale(int src,int dst,int shift)1361 static inline u16 scl_cal_scale(int src, int dst, int shift)
1362 {
1363 return ((src * 2 - 3) << (shift - 1)) / (dst - 1);
1364 }
1365
scl_cal_scale2(int src,int dst)1366 static inline u16 scl_cal_scale2(int src, int dst)
1367 {
1368 return ((src - 1) << 12) / (dst - 1);
1369 }
1370
vop2_writel(struct vop2 * vop2,u32 offset,u32 v)1371 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
1372 {
1373 writel(v, vop2->regs + offset);
1374 vop2->regsbak[offset >> 2] = v;
1375 }
1376
vop2_readl(struct vop2 * vop2,u32 offset)1377 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset)
1378 {
1379 return readl(vop2->regs + offset);
1380 }
1381
vop2_mask_write(struct vop2 * vop2,u32 offset,u32 mask,u32 shift,u32 v,bool write_mask)1382 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset,
1383 u32 mask, u32 shift, u32 v,
1384 bool write_mask)
1385 {
1386 if (!mask)
1387 return;
1388
1389 if (write_mask) {
1390 v = ((v & mask) << shift) | (mask << (shift + 16));
1391 } else {
1392 u32 cached_val = vop2->regsbak[offset >> 2];
1393
1394 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
1395 vop2->regsbak[offset >> 2] = v;
1396 }
1397
1398 writel(v, vop2->regs + offset);
1399 }
1400
vop2_grf_writel(struct vop2 * vop,void * grf_base,u32 offset,u32 mask,u32 shift,u32 v)1401 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset,
1402 u32 mask, u32 shift, u32 v)
1403 {
1404 u32 val = 0;
1405
1406 val = (v << shift) | (mask << (shift + 16));
1407 writel(val, grf_base + offset);
1408 }
1409
vop2_grf_readl(struct vop2 * vop,void * grf_base,u32 offset,u32 mask,u32 shift)1410 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset,
1411 u32 mask, u32 shift)
1412 {
1413 return (readl(grf_base + offset) >> shift) & mask;
1414 }
1415
get_output_if_name(u32 output_if,char * name)1416 static char* get_output_if_name(u32 output_if, char *name)
1417 {
1418 if (output_if & VOP_OUTPUT_IF_RGB)
1419 strcat(name, " RGB");
1420 if (output_if & VOP_OUTPUT_IF_BT1120)
1421 strcat(name, " BT1120");
1422 if (output_if & VOP_OUTPUT_IF_BT656)
1423 strcat(name, " BT656");
1424 if (output_if & VOP_OUTPUT_IF_LVDS0)
1425 strcat(name, " LVDS0");
1426 if (output_if & VOP_OUTPUT_IF_LVDS1)
1427 strcat(name, " LVDS1");
1428 if (output_if & VOP_OUTPUT_IF_MIPI0)
1429 strcat(name, " MIPI0");
1430 if (output_if & VOP_OUTPUT_IF_MIPI1)
1431 strcat(name, " MIPI1");
1432 if (output_if & VOP_OUTPUT_IF_eDP0)
1433 strcat(name, " eDP0");
1434 if (output_if & VOP_OUTPUT_IF_eDP1)
1435 strcat(name, " eDP1");
1436 if (output_if & VOP_OUTPUT_IF_DP0)
1437 strcat(name, " DP0");
1438 if (output_if & VOP_OUTPUT_IF_DP1)
1439 strcat(name, " DP1");
1440 if (output_if & VOP_OUTPUT_IF_HDMI0)
1441 strcat(name, " HDMI0");
1442 if (output_if & VOP_OUTPUT_IF_HDMI1)
1443 strcat(name, " HDMI1");
1444
1445 return name;
1446 }
1447
get_plane_name(int plane_id,char * name)1448 static char *get_plane_name(int plane_id, char *name)
1449 {
1450 switch (plane_id) {
1451 case ROCKCHIP_VOP2_CLUSTER0:
1452 strcat(name, "Cluster0");
1453 break;
1454 case ROCKCHIP_VOP2_CLUSTER1:
1455 strcat(name, "Cluster1");
1456 break;
1457 case ROCKCHIP_VOP2_ESMART0:
1458 strcat(name, "Esmart0");
1459 break;
1460 case ROCKCHIP_VOP2_ESMART1:
1461 strcat(name, "Esmart1");
1462 break;
1463 case ROCKCHIP_VOP2_SMART0:
1464 strcat(name, "Smart0");
1465 break;
1466 case ROCKCHIP_VOP2_SMART1:
1467 strcat(name, "Smart1");
1468 break;
1469 case ROCKCHIP_VOP2_CLUSTER2:
1470 strcat(name, "Cluster2");
1471 break;
1472 case ROCKCHIP_VOP2_CLUSTER3:
1473 strcat(name, "Cluster3");
1474 break;
1475 case ROCKCHIP_VOP2_ESMART2:
1476 strcat(name, "Esmart2");
1477 break;
1478 case ROCKCHIP_VOP2_ESMART3:
1479 strcat(name, "Esmart3");
1480 break;
1481 }
1482
1483 return name;
1484 }
1485
is_yuv_output(u32 bus_format)1486 static bool is_yuv_output(u32 bus_format)
1487 {
1488 switch (bus_format) {
1489 case MEDIA_BUS_FMT_YUV8_1X24:
1490 case MEDIA_BUS_FMT_YUV10_1X30:
1491 case MEDIA_BUS_FMT_YUYV10_1X20:
1492 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1493 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1494 case MEDIA_BUS_FMT_YUYV8_2X8:
1495 case MEDIA_BUS_FMT_YVYU8_2X8:
1496 case MEDIA_BUS_FMT_UYVY8_2X8:
1497 case MEDIA_BUS_FMT_VYUY8_2X8:
1498 case MEDIA_BUS_FMT_YUYV8_1X16:
1499 case MEDIA_BUS_FMT_YVYU8_1X16:
1500 case MEDIA_BUS_FMT_UYVY8_1X16:
1501 case MEDIA_BUS_FMT_VYUY8_1X16:
1502 return true;
1503 default:
1504 return false;
1505 }
1506 }
1507
vop2_convert_csc_mode(int csc_mode,int bit_depth)1508 static int vop2_convert_csc_mode(int csc_mode, int bit_depth)
1509 {
1510 switch (csc_mode) {
1511 case V4L2_COLORSPACE_SMPTE170M:
1512 case V4L2_COLORSPACE_470_SYSTEM_M:
1513 case V4L2_COLORSPACE_470_SYSTEM_BG:
1514 return CSC_BT601L;
1515 case V4L2_COLORSPACE_REC709:
1516 case V4L2_COLORSPACE_SMPTE240M:
1517 case V4L2_COLORSPACE_DEFAULT:
1518 if (bit_depth == CSC_13BIT_DEPTH)
1519 return CSC_BT709L_13BIT;
1520 else
1521 return CSC_BT709L;
1522 case V4L2_COLORSPACE_JPEG:
1523 return CSC_BT601F;
1524 case V4L2_COLORSPACE_BT2020:
1525 if (bit_depth == CSC_13BIT_DEPTH)
1526 return CSC_BT2020L_13BIT;
1527 else
1528 return CSC_BT2020;
1529 case V4L2_COLORSPACE_BT709F:
1530 if (bit_depth == CSC_10BIT_DEPTH) {
1531 printf("WARN: Unsupported bt709f at 10bit csc depth, use bt601f instead\n");
1532 return CSC_BT601F;
1533 } else {
1534 return CSC_BT709F_13BIT;
1535 }
1536 case V4L2_COLORSPACE_BT2020F:
1537 if (bit_depth == CSC_10BIT_DEPTH) {
1538 printf("WARN: Unsupported bt2020f at 10bit csc depth, use bt601f instead\n");
1539 return CSC_BT601F;
1540 } else {
1541 return CSC_BT2020F_13BIT;
1542 }
1543 default:
1544 return CSC_BT709L;
1545 }
1546 }
1547
is_uv_swap(u32 bus_format,u32 output_mode)1548 static bool is_uv_swap(u32 bus_format, u32 output_mode)
1549 {
1550 /*
1551 * FIXME:
1552 *
1553 * There is no media type for YUV444 output,
1554 * so when out_mode is AAAA or P888, assume output is YUV444 on
1555 * yuv format.
1556 *
1557 * From H/W testing, YUV444 mode need a rb swap.
1558 */
1559 if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
1560 bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
1561 bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
1562 bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
1563 ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
1564 bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
1565 (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
1566 output_mode == ROCKCHIP_OUT_MODE_P888)))
1567 return true;
1568 else
1569 return false;
1570 }
1571
is_rb_swap(u32 bus_format,u32 output_mode)1572 static bool is_rb_swap(u32 bus_format, u32 output_mode)
1573 {
1574 /*
1575 * The default component order of serial rgb3x8 formats
1576 * is BGR. So it is needed to enable RB swap.
1577 */
1578 if (bus_format == MEDIA_BUS_FMT_SRGB888_3X8 ||
1579 bus_format == MEDIA_BUS_FMT_SRGB888_DUMMY_4X8)
1580 return true;
1581 else
1582 return false;
1583 }
1584
is_hot_plug_devices(int output_type)1585 static inline bool is_hot_plug_devices(int output_type)
1586 {
1587 switch (output_type) {
1588 case DRM_MODE_CONNECTOR_HDMIA:
1589 case DRM_MODE_CONNECTOR_HDMIB:
1590 case DRM_MODE_CONNECTOR_TV:
1591 case DRM_MODE_CONNECTOR_DisplayPort:
1592 case DRM_MODE_CONNECTOR_VGA:
1593 case DRM_MODE_CONNECTOR_Unknown:
1594 return true;
1595 default:
1596 return false;
1597 }
1598 }
1599
vop2_find_win_by_phys_id(struct vop2 * vop2,int phys_id)1600 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id)
1601 {
1602 int i = 0;
1603
1604 for (i = 0; i < vop2->data->nr_layers; i++) {
1605 if (vop2->data->win_data[i].phys_id == phys_id)
1606 return &vop2->data->win_data[i];
1607 }
1608
1609 return NULL;
1610 }
1611
vop2_find_pd_data_by_id(struct vop2 * vop2,int pd_id)1612 static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id)
1613 {
1614 int i = 0;
1615
1616 for (i = 0; i < vop2->data->nr_pd; i++) {
1617 if (vop2->data->pd[i].id == pd_id)
1618 return &vop2->data->pd[i];
1619 }
1620
1621 return NULL;
1622 }
1623
rk3568_vop2_load_lut(struct vop2 * vop2,int crtc_id,u32 * lut_regs,u32 * lut_val,int lut_len)1624 static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1625 u32 *lut_regs, u32 *lut_val, int lut_len)
1626 {
1627 u32 vp_offset = crtc_id * 0x100;
1628 int i;
1629
1630 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1631 GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT,
1632 crtc_id, false);
1633
1634 for (i = 0; i < lut_len; i++)
1635 writel(lut_val[i], lut_regs + i);
1636
1637 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1638 EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1639 }
1640
rk3588_vop2_load_lut(struct vop2 * vop2,int crtc_id,u32 * lut_regs,u32 * lut_val,int lut_len)1641 static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id,
1642 u32 *lut_regs, u32 *lut_val, int lut_len)
1643 {
1644 u32 vp_offset = crtc_id * 0x100;
1645 int i;
1646
1647 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL,
1648 GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT,
1649 crtc_id, false);
1650
1651 for (i = 0; i < lut_len; i++)
1652 writel(lut_val[i], lut_regs + i);
1653
1654 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1655 EN_MASK, DSP_LUT_EN_SHIFT, 1, false);
1656 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
1657 EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false);
1658 }
1659
rockchip_vop2_gamma_lut_init(struct vop2 * vop2,struct display_state * state)1660 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2,
1661 struct display_state *state)
1662 {
1663 struct connector_state *conn_state = &state->conn_state;
1664 struct crtc_state *cstate = &state->crtc_state;
1665 struct resource gamma_res;
1666 fdt_size_t lut_size;
1667 int i, lut_len, ret = 0;
1668 u32 *lut_regs;
1669 u32 *lut_val;
1670 u32 r, g, b;
1671 struct base2_disp_info *disp_info = conn_state->disp_info;
1672 static int gamma_lut_en_num = 1;
1673
1674 if (gamma_lut_en_num > vop2->data->nr_gammas) {
1675 printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas);
1676 return 0;
1677 }
1678
1679 if (!disp_info)
1680 return 0;
1681
1682 if (!disp_info->gamma_lut_data.size)
1683 return 0;
1684
1685 ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res);
1686 if (ret)
1687 printf("failed to get gamma lut res\n");
1688 lut_regs = (u32 *)gamma_res.start;
1689 lut_size = gamma_res.end - gamma_res.start + 1;
1690 if (lut_regs == (u32 *)FDT_ADDR_T_NONE) {
1691 printf("failed to get gamma lut register\n");
1692 return 0;
1693 }
1694 lut_len = lut_size / 4;
1695 if (lut_len != 256 && lut_len != 1024) {
1696 printf("Warning: unsupport gamma lut table[%d]\n", lut_len);
1697 return 0;
1698 }
1699 lut_val = (u32 *)calloc(1, lut_size);
1700 for (i = 0; i < lut_len; i++) {
1701 r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff;
1702 g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff;
1703 b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff;
1704
1705 lut_val[i] = b * lut_len * lut_len + g * lut_len + r;
1706 }
1707
1708 if (vop2->version == VOP_VERSION_RK3568) {
1709 rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len);
1710 gamma_lut_en_num++;
1711 } else if (vop2->version == VOP_VERSION_RK3588) {
1712 rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len);
1713 if (cstate->splice_mode) {
1714 rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs, lut_val, lut_len);
1715 gamma_lut_en_num++;
1716 }
1717 gamma_lut_en_num++;
1718 }
1719
1720 return 0;
1721 }
1722
rockchip_vop2_cubic_lut_init(struct vop2 * vop2,struct display_state * state)1723 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2,
1724 struct display_state *state)
1725 {
1726 struct connector_state *conn_state = &state->conn_state;
1727 struct crtc_state *cstate = &state->crtc_state;
1728 int i, cubic_lut_len;
1729 u32 vp_offset = cstate->crtc_id * 0x100;
1730 struct base2_disp_info *disp_info = conn_state->disp_info;
1731 struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data;
1732 u32 *cubic_lut_addr;
1733
1734 if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0)
1735 return 0;
1736
1737 if (!disp_info->cubic_lut_data.size)
1738 return 0;
1739
1740 cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id);
1741 cubic_lut_len = disp_info->cubic_lut_data.size;
1742
1743 for (i = 0; i < cubic_lut_len / 2; i++) {
1744 *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) +
1745 ((lut->lgreen[2 * i] & 0xfff) << 12) +
1746 ((lut->lblue[2 * i] & 0xff) << 24);
1747 *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) +
1748 ((lut->lred[2 * i + 1] & 0xfff) << 4) +
1749 ((lut->lgreen[2 * i + 1] & 0xfff) << 16) +
1750 ((lut->lblue[2 * i + 1] & 0xf) << 28);
1751 *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4;
1752 *cubic_lut_addr++ = 0;
1753 }
1754
1755 if (cubic_lut_len % 2) {
1756 *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) +
1757 ((lut->lgreen[2 * i] & 0xfff) << 12) +
1758 ((lut->lblue[2 * i] & 0xff) << 24);
1759 *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8;
1760 *cubic_lut_addr++ = 0;
1761 *cubic_lut_addr = 0;
1762 }
1763
1764 vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset,
1765 get_cubic_lut_buffer(cstate->crtc_id));
1766 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL,
1767 EN_MASK, LUT_DMA_EN_SHIFT, 1, false);
1768 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1769 EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false);
1770 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset,
1771 EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false);
1772
1773 return 0;
1774 }
1775
vop2_bcsh_reg_update(struct display_state * state,struct vop2 * vop2,struct bcsh_state * bcsh_state,int crtc_id)1776 static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2,
1777 struct bcsh_state *bcsh_state, int crtc_id)
1778 {
1779 struct crtc_state *cstate = &state->crtc_state;
1780 u32 vp_offset = crtc_id * 0x100;
1781
1782 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK,
1783 BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false);
1784 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK,
1785 BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false);
1786
1787 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK,
1788 BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
1789 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK,
1790 BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false);
1791
1792 if (!cstate->bcsh_en) {
1793 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1794 BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false);
1795 return;
1796 }
1797
1798 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1799 BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT,
1800 bcsh_state->brightness, false);
1801 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1802 BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false);
1803 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1804 BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT,
1805 bcsh_state->saturation * bcsh_state->contrast / 0x100, false);
1806 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1807 BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false);
1808 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset,
1809 BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false);
1810 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset,
1811 BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT,
1812 BCSH_OUT_MODE_NORMAL_VIDEO, false);
1813 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset,
1814 BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false);
1815 }
1816
vop2_tv_config_update(struct display_state * state,struct vop2 * vop2)1817 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2)
1818 {
1819 struct connector_state *conn_state = &state->conn_state;
1820 struct base_bcsh_info *bcsh_info;
1821 struct crtc_state *cstate = &state->crtc_state;
1822 struct bcsh_state bcsh_state;
1823 int brightness, contrast, saturation, hue, sin_hue, cos_hue;
1824
1825 if (!conn_state->disp_info)
1826 return;
1827 bcsh_info = &conn_state->disp_info->bcsh_info;
1828 if (!bcsh_info)
1829 return;
1830
1831 if (bcsh_info->brightness != 50 ||
1832 bcsh_info->contrast != 50 ||
1833 bcsh_info->saturation != 50 || bcsh_info->hue != 50)
1834 cstate->bcsh_en = true;
1835
1836 if (cstate->bcsh_en) {
1837 if (!cstate->yuv_overlay)
1838 cstate->post_r2y_en = 1;
1839 if (!is_yuv_output(conn_state->bus_format))
1840 cstate->post_y2r_en = 1;
1841 } else {
1842 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
1843 cstate->post_r2y_en = 1;
1844 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
1845 cstate->post_y2r_en = 1;
1846 }
1847
1848 cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
1849
1850 if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT)
1851 brightness = interpolate(0, -128, 100, 127,
1852 bcsh_info->brightness);
1853 else
1854 brightness = interpolate(0, -32, 100, 31,
1855 bcsh_info->brightness);
1856 contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast);
1857 saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation);
1858 hue = interpolate(0, -30, 100, 30, bcsh_info->hue);
1859
1860
1861 /*
1862 * a:[-30~0):
1863 * sin_hue = 0x100 - sin(a)*256;
1864 * cos_hue = cos(a)*256;
1865 * a:[0~30]
1866 * sin_hue = sin(a)*256;
1867 * cos_hue = cos(a)*256;
1868 */
1869 sin_hue = fixp_sin32(hue) >> 23;
1870 cos_hue = fixp_cos32(hue) >> 23;
1871
1872 bcsh_state.brightness = brightness;
1873 bcsh_state.contrast = contrast;
1874 bcsh_state.saturation = saturation;
1875 bcsh_state.sin_hue = sin_hue;
1876 bcsh_state.cos_hue = cos_hue;
1877
1878 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id);
1879 if (cstate->splice_mode)
1880 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id);
1881 }
1882
vop2_setup_dly_for_vp(struct display_state * state,struct vop2 * vop2,int crtc_id)1883 static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id)
1884 {
1885 struct connector_state *conn_state = &state->conn_state;
1886 struct drm_display_mode *mode = &conn_state->mode;
1887 struct crtc_state *cstate = &state->crtc_state;
1888 u32 bg_ovl_dly, bg_dly, pre_scan_dly;
1889 u16 hdisplay = mode->crtc_hdisplay;
1890 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1891
1892 bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly;
1893 bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly;
1894 bg_dly -= bg_ovl_dly;
1895
1896 if (cstate->splice_mode)
1897 pre_scan_dly = bg_dly + (hdisplay >> 2) - 1;
1898 else
1899 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
1900
1901 if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8)
1902 hsync_len = 8;
1903 pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
1904 vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4,
1905 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
1906 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly);
1907 }
1908
vop3_setup_pipe_dly(struct display_state * state,struct vop2 * vop2,int crtc_id)1909 static void vop3_setup_pipe_dly(struct display_state *state, struct vop2 *vop2, int crtc_id)
1910 {
1911 struct connector_state *conn_state = &state->conn_state;
1912 struct drm_display_mode *mode = &conn_state->mode;
1913 struct crtc_state *cstate = &state->crtc_state;
1914 struct vop2_win_data *win_data;
1915 u32 bg_dly, pre_scan_dly;
1916 u16 hdisplay = mode->crtc_hdisplay;
1917 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1918 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
1919 u8 win_id;
1920
1921 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
1922 win_id = atoi(&win_data->name[strlen(win_data->name) - 1]);
1923 vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART0_CTRL + win_id * 4,
1924 ESMART_DLY_NUM_MASK, ESMART_DLY_NUM_SHIFT, 0, false);
1925
1926 bg_dly = vop2->data->vp_data[crtc_id].win_dly +
1927 vop2->data->vp_data[crtc_id].layer_mix_dly +
1928 vop2->data->vp_data[crtc_id].hdr_mix_dly;
1929 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1;
1930 pre_scan_dly = (pre_scan_dly << 16) | hsync_len;
1931 vop2_mask_write(vop2, RK3528_OVL_PORT0_BG_MIX_CTRL + crtc_id * 0x100,
1932 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false);
1933 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly);
1934 }
1935
vop2_post_config(struct display_state * state,struct vop2 * vop2)1936 static void vop2_post_config(struct display_state *state, struct vop2 *vop2)
1937 {
1938 struct connector_state *conn_state = &state->conn_state;
1939 struct drm_display_mode *mode = &conn_state->mode;
1940 struct crtc_state *cstate = &state->crtc_state;
1941 u32 vp_offset = (cstate->crtc_id * 0x100);
1942 u16 vtotal = mode->crtc_vtotal;
1943 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1944 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1945 u16 hdisplay = mode->crtc_hdisplay;
1946 u16 vdisplay = mode->crtc_vdisplay;
1947 u16 hsize =
1948 hdisplay * (conn_state->overscan.left_margin +
1949 conn_state->overscan.right_margin) / 200;
1950 u16 vsize =
1951 vdisplay * (conn_state->overscan.top_margin +
1952 conn_state->overscan.bottom_margin) / 200;
1953 u16 hact_end, vact_end;
1954 u32 val;
1955
1956 hsize = round_down(hsize, 2);
1957 vsize = round_down(vsize, 2);
1958
1959 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200;
1960 hact_end = hact_st + hsize;
1961 val = hact_st << 16;
1962 val |= hact_end;
1963
1964 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val);
1965 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200;
1966 vact_end = vact_st + vsize;
1967 val = vact_st << 16;
1968 val |= vact_end;
1969 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val);
1970 val = scl_cal_scale2(vdisplay, vsize) << 16;
1971 val |= scl_cal_scale2(hdisplay, hsize);
1972 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val);
1973 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0)
1974 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1)
1975 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset,
1976 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) |
1977 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize));
1978 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1979 u16 vact_st_f1 = vtotal + vact_st + 1;
1980 u16 vact_end_f1 = vact_st_f1 + vsize;
1981
1982 val = vact_st_f1 << 16 | vact_end_f1;
1983 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val);
1984 }
1985
1986 if (is_vop3(vop2)) {
1987 vop3_setup_pipe_dly(state, vop2, cstate->crtc_id);
1988 } else {
1989 vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id);
1990 if (cstate->splice_mode)
1991 vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id);
1992 }
1993 }
1994
vop3_post_acm_config(struct display_state * state,struct vop2 * vop2)1995 static void vop3_post_acm_config(struct display_state *state, struct vop2 *vop2)
1996 {
1997 struct connector_state *conn_state = &state->conn_state;
1998 struct crtc_state *cstate = &state->crtc_state;
1999 struct acm_data *acm = &conn_state->disp_info->acm_data;
2000 struct drm_display_mode *mode = &conn_state->mode;
2001 u32 vp_offset = (cstate->crtc_id * 0x100);
2002 s16 *lut_y;
2003 s16 *lut_h;
2004 s16 *lut_s;
2005 u32 value;
2006 int i;
2007
2008 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2009 POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false);
2010 if (!acm->acm_enable) {
2011 writel(0, vop2->regs + RK3528_ACM_CTRL);
2012 return;
2013 }
2014
2015 printf("post acm enable\n");
2016
2017 writel(1, vop2->regs + RK3528_ACM_FETCH_START);
2018
2019 value = (acm->acm_enable & 0x1) + ((mode->hdisplay & 0xfff) << 8) +
2020 ((mode->vdisplay & 0xfff) << 20);
2021 writel(value, vop2->regs + RK3528_ACM_CTRL);
2022
2023 value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) +
2024 ((acm->s_gain << 20) & 0x3ff00000);
2025 writel(value, vop2->regs + RK3528_ACM_DELTA_RANGE);
2026
2027 lut_y = &acm->gain_lut_hy[0];
2028 lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH];
2029 lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2];
2030 for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) {
2031 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
2032 ((lut_s[i] << 16) & 0xff0000);
2033 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2));
2034 }
2035
2036 lut_y = &acm->gain_lut_hs[0];
2037 lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH];
2038 lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2];
2039 for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) {
2040 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) +
2041 ((lut_s[i] << 16) & 0xff0000);
2042 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2));
2043 }
2044
2045 lut_y = &acm->delta_lut_h[0];
2046 lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH];
2047 lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2];
2048 for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) {
2049 value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) +
2050 ((lut_s[i] << 20) & 0x3ff00000);
2051 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2));
2052 }
2053
2054 writel(1, vop2->regs + RK3528_ACM_FETCH_DONE);
2055 }
2056
vop3_post_csc_config(struct display_state * state,struct vop2 * vop2)2057 static void vop3_post_csc_config(struct display_state *state, struct vop2 *vop2)
2058 {
2059 struct connector_state *conn_state = &state->conn_state;
2060 struct crtc_state *cstate = &state->crtc_state;
2061 struct acm_data *acm = &conn_state->disp_info->acm_data;
2062 struct csc_info *csc = &conn_state->disp_info->csc_info;
2063 struct post_csc_coef csc_coef;
2064 bool is_input_yuv = false;
2065 bool is_output_yuv = false;
2066 bool post_r2y_en = false;
2067 bool post_csc_en = false;
2068 u32 vp_offset = (cstate->crtc_id * 0x100);
2069 u32 value;
2070 int range_type;
2071
2072 printf("post csc enable\n");
2073
2074 if (acm->acm_enable) {
2075 if (!cstate->yuv_overlay)
2076 post_r2y_en = true;
2077
2078 /* do y2r in csc module */
2079 if (!is_yuv_output(conn_state->bus_format))
2080 post_csc_en = true;
2081 } else {
2082 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format))
2083 post_r2y_en = true;
2084
2085 /* do y2r in csc module */
2086 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format))
2087 post_csc_en = true;
2088 }
2089
2090 if (csc->csc_enable)
2091 post_csc_en = true;
2092
2093 if (cstate->yuv_overlay || post_r2y_en)
2094 is_input_yuv = true;
2095
2096 if (is_yuv_output(conn_state->bus_format))
2097 is_output_yuv = true;
2098
2099 cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_13BIT_DEPTH);
2100
2101 if (post_csc_en) {
2102 rockchip_calc_post_csc(csc, &csc_coef, cstate->post_csc_mode, is_input_yuv,
2103 is_output_yuv);
2104
2105 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2106 POST_CSC_COE00_MASK, POST_CSC_COE00_SHIFT,
2107 csc_coef.csc_coef00, false);
2108 value = csc_coef.csc_coef01 & 0xffff;
2109 value |= (csc_coef.csc_coef02 << 16) & 0xffff0000;
2110 writel(value, vop2->regs + RK3528_VP0_CSC_COE01_02);
2111 value = csc_coef.csc_coef10 & 0xffff;
2112 value |= (csc_coef.csc_coef11 << 16) & 0xffff0000;
2113 writel(value, vop2->regs + RK3528_VP0_CSC_COE10_11);
2114 value = csc_coef.csc_coef12 & 0xffff;
2115 value |= (csc_coef.csc_coef20 << 16) & 0xffff0000;
2116 writel(value, vop2->regs + RK3528_VP0_CSC_COE12_20);
2117 value = csc_coef.csc_coef21 & 0xffff;
2118 value |= (csc_coef.csc_coef22 << 16) & 0xffff0000;
2119 writel(value, vop2->regs + RK3528_VP0_CSC_COE21_22);
2120 writel(csc_coef.csc_dc0, vop2->regs + RK3528_VP0_CSC_OFFSET0);
2121 writel(csc_coef.csc_dc1, vop2->regs + RK3528_VP0_CSC_OFFSET1);
2122 writel(csc_coef.csc_dc2, vop2->regs + RK3528_VP0_CSC_OFFSET2);
2123
2124 range_type = csc_coef.range_type ? 0 : 1;
2125 range_type <<= is_input_yuv ? 0 : 1;
2126 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2127 POST_CSC_MODE_MASK, POST_CSC_MODE_SHIFT, range_type, false);
2128 }
2129
2130 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2131 POST_R2Y_EN_MASK, POST_R2Y_EN_SHIFT, post_r2y_en ? 1 : 0, false);
2132 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2133 POST_CSC_EN_MASK, POST_CSC_EN_SHIFT, post_csc_en ? 1 : 0, false);
2134 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset,
2135 POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, cstate->post_csc_mode, false);
2136 }
2137
vop3_post_config(struct display_state * state,struct vop2 * vop2)2138 static void vop3_post_config(struct display_state *state, struct vop2 *vop2)
2139 {
2140 struct connector_state *conn_state = &state->conn_state;
2141 struct base2_disp_info *disp_info = conn_state->disp_info;
2142 const char *enable_flag;
2143 if (!disp_info) {
2144 printf("disp_info is empty\n");
2145 return;
2146 }
2147
2148 enable_flag = (const char *)&disp_info->cacm_header;
2149 if (strncasecmp(enable_flag, "CACM", 4)) {
2150 printf("acm and csc is not support\n");
2151 return;
2152 }
2153
2154 vop3_post_acm_config(state, vop2);
2155 vop3_post_csc_config(state, vop2);
2156 }
2157
2158 /*
2159 * Read VOP internal power domain on/off status.
2160 * We should query BISR_STS register in PMU for
2161 * power up/down status when memory repair is enabled.
2162 * Return value: 1 for power on, 0 for power off;
2163 */
vop2_wait_power_domain_on(struct vop2 * vop2,struct vop2_power_domain_data * pd_data)2164 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data)
2165 {
2166 int val = 0;
2167 int shift = 0;
2168 int shift_factor = 0;
2169 bool is_bisr_en = false;
2170
2171 /*
2172 * The order of pd status bits in BISR_STS register
2173 * is different from that in VOP SYS_STS register.
2174 */
2175 if (pd_data->id == VOP2_PD_DSC_8K ||
2176 pd_data->id == VOP2_PD_DSC_4K ||
2177 pd_data->id == VOP2_PD_ESMART)
2178 shift_factor = 1;
2179
2180 shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor;
2181 is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift);
2182 if (is_bisr_en) {
2183 shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor;
2184
2185 return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val,
2186 ((val >> shift) & 0x1), 50 * 1000);
2187 } else {
2188 shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1;
2189
2190 return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val,
2191 !((val >> shift) & 0x1), 50 * 1000);
2192 }
2193 }
2194
vop2_power_domain_on(struct vop2 * vop2,int pd_id)2195 static int vop2_power_domain_on(struct vop2 *vop2, int pd_id)
2196 {
2197 struct vop2_power_domain_data *pd_data;
2198 int ret = 0;
2199
2200 if (!pd_id)
2201 return 0;
2202
2203 pd_data = vop2_find_pd_data_by_id(vop2, pd_id);
2204 if (!pd_data) {
2205 printf("can't find pd_data by id\n");
2206 return -EINVAL;
2207 }
2208
2209 if (pd_data->parent_id) {
2210 ret = vop2_power_domain_on(vop2, pd_data->parent_id);
2211 if (ret) {
2212 printf("can't open parent power domain\n");
2213 return -EINVAL;
2214 }
2215 }
2216
2217 vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK,
2218 RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_id) - 1, 0, false);
2219 ret = vop2_wait_power_domain_on(vop2, pd_data);
2220 if (ret) {
2221 printf("wait vop2 power domain timeout\n");
2222 return ret;
2223 }
2224
2225 return 0;
2226 }
2227
rk3588_vop2_regsbak(struct vop2 * vop2)2228 static void rk3588_vop2_regsbak(struct vop2 *vop2)
2229 {
2230 u32 *base = vop2->regs;
2231 int i = 0;
2232
2233 /*
2234 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU
2235 */
2236 for (i = 0; i < (vop2->reg_len >> 2); i++)
2237 vop2->regsbak[i] = base[i];
2238 }
2239
vop3_overlay_init(struct vop2 * vop2,struct display_state * state)2240 static void vop3_overlay_init(struct vop2 *vop2, struct display_state *state)
2241 {
2242 struct vop2_win_data *win_data;
2243 int layer_phy_id = 0;
2244 int i, j;
2245 u32 ovl_port_offset = 0;
2246 u32 layer_nr = 0;
2247 u8 shift = 0;
2248
2249 /* layer sel win id */
2250 for (i = 0; i < vop2->data->nr_vps; i++) {
2251 shift = 0;
2252 ovl_port_offset = 0x100 * i;
2253 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2254 for (j = 0; j < layer_nr; j++) {
2255 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2256 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2257 vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + ovl_port_offset, LAYER_SEL_MASK,
2258 shift, win_data->layer_sel_win_id[i], false);
2259 shift += 4;
2260 }
2261 }
2262
2263 /* win sel port */
2264 for (i = 0; i < vop2->data->nr_vps; i++) {
2265 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2266 for (j = 0; j < layer_nr; j++) {
2267 if (!vop2->vp_plane_mask[i].attached_layers[j])
2268 continue;
2269 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2270 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2271 shift = win_data->win_sel_port_offset * 2;
2272 vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL_IMD, LAYER_SEL_PORT_MASK,
2273 shift, i, false);
2274 }
2275 }
2276 }
2277
vop2_overlay_init(struct vop2 * vop2,struct display_state * state)2278 static void vop2_overlay_init(struct vop2 *vop2, struct display_state *state)
2279 {
2280 struct crtc_state *cstate = &state->crtc_state;
2281 struct vop2_win_data *win_data;
2282 int layer_phy_id = 0;
2283 int total_used_layer = 0;
2284 int port_mux = 0;
2285 int i, j;
2286 u32 layer_nr = 0;
2287 u8 shift = 0;
2288
2289 /* layer sel win id */
2290 for (i = 0; i < vop2->data->nr_vps; i++) {
2291 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2292 for (j = 0; j < layer_nr; j++) {
2293 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2294 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2295 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK,
2296 shift, win_data->layer_sel_win_id[i], false);
2297 shift += 4;
2298 }
2299 }
2300
2301 /* win sel port */
2302 for (i = 0; i < vop2->data->nr_vps; i++) {
2303 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2304 for (j = 0; j < layer_nr; j++) {
2305 if (!vop2->vp_plane_mask[i].attached_layers[j])
2306 continue;
2307 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2308 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id);
2309 shift = win_data->win_sel_port_offset * 2;
2310 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK,
2311 LAYER_SEL_PORT_SHIFT + shift, i, false);
2312 }
2313 }
2314
2315 /**
2316 * port mux config
2317 */
2318 for (i = 0; i < vop2->data->nr_vps; i++) {
2319 shift = i * 4;
2320 if (vop2->vp_plane_mask[i].attached_layers_nr) {
2321 total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr;
2322 port_mux = total_used_layer - 1;
2323 } else {
2324 port_mux = 8;
2325 }
2326
2327 if (i == vop2->data->nr_vps - 1)
2328 port_mux = vop2->data->nr_mixers;
2329
2330 cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1;
2331 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK,
2332 PORT_MUX_SHIFT + shift, port_mux, false);
2333 }
2334 }
2335
vop3_ignore_plane(struct vop2 * vop2,struct vop2_win_data * win)2336 static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win)
2337 {
2338 if (!is_vop3(vop2))
2339 return false;
2340
2341 if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE &&
2342 win->phys_id != ROCKCHIP_VOP2_ESMART0)
2343 return true;
2344 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE &&
2345 (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3))
2346 return true;
2347 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE &&
2348 win->phys_id == ROCKCHIP_VOP2_ESMART1)
2349 return true;
2350 else
2351 return false;
2352 }
2353
vop3_init_esmart_scale_engine(struct vop2 * vop2)2354 static void vop3_init_esmart_scale_engine(struct vop2 *vop2)
2355 {
2356 struct vop2_win_data *win_data;
2357 int i;
2358 u8 scale_engine_num = 0;
2359
2360 /* store plane mask for vop2_fixup_dts */
2361 for (i = 0; i < vop2->data->nr_layers; i++) {
2362 win_data = &vop2->data->win_data[i];
2363 if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data))
2364 continue;
2365
2366 win_data->scale_engine_num = scale_engine_num++;
2367 }
2368 }
2369
vop2_global_initial(struct vop2 * vop2,struct display_state * state)2370 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state)
2371 {
2372 struct crtc_state *cstate = &state->crtc_state;
2373 struct vop2_vp_plane_mask *plane_mask;
2374 int layer_phy_id = 0;
2375 int i, j;
2376 int ret;
2377 u32 layer_nr = 0;
2378
2379 if (vop2->global_init)
2380 return;
2381
2382 /* OTP must enable at the first time, otherwise mirror layer register is error */
2383 if (soc_is_rk3566())
2384 vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK,
2385 OTP_WIN_EN_SHIFT, 1, false);
2386
2387 if (cstate->crtc->assign_plane) {/* dts assign plane */
2388 u32 plane_mask;
2389 int primary_plane_id;
2390
2391 for (i = 0; i < vop2->data->nr_vps; i++) {
2392 plane_mask = cstate->crtc->vps[i].plane_mask;
2393 vop2->vp_plane_mask[i].plane_mask = plane_mask;
2394 layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */
2395 vop2->vp_plane_mask[i].attached_layers_nr = layer_nr;
2396 primary_plane_id = cstate->crtc->vps[i].primary_plane_id;
2397 if (primary_plane_id >= ROCKCHIP_VOP2_LAYER_MAX)
2398 primary_plane_id = vop2_get_primary_plane(vop2, plane_mask);
2399 vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id;
2400 vop2->vp_plane_mask[i].plane_mask = plane_mask;
2401
2402 /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/
2403 for (j = 0; j < layer_nr; j++) {
2404 vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1;
2405 plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]);
2406 }
2407 }
2408 } else {/* need soft assign plane mask */
2409 /* find the first unplug devices and set it as main display */
2410 int main_vp_index = -1;
2411 int active_vp_num = 0;
2412
2413 for (i = 0; i < vop2->data->nr_vps; i++) {
2414 if (cstate->crtc->vps[i].enable)
2415 active_vp_num++;
2416 }
2417 printf("VOP have %d active VP\n", active_vp_num);
2418
2419 if (soc_is_rk3566() && active_vp_num > 2)
2420 printf("ERROR: rk3566 only support 2 display output!!\n");
2421 plane_mask = vop2->data->plane_mask;
2422 plane_mask += (active_vp_num - 1) * VOP2_VP_MAX;
2423 /*
2424 * For rk3528, one display policy for hdmi store in plane_mask[0], and the other
2425 * for cvbs store in plane_mask[2].
2426 */
2427 if (vop2->version == VOP_VERSION_RK3528 && active_vp_num == 1 &&
2428 cstate->crtc->vps[1].output_type == DRM_MODE_CONNECTOR_TV)
2429 plane_mask += 2 * VOP2_VP_MAX;
2430
2431 if (vop2->version == VOP_VERSION_RK3528) {
2432 /*
2433 * For rk3528, the plane mask of vp is limited, only esmart2 can be selected
2434 * by both vp0 and vp1.
2435 */
2436 j = 0;
2437 } else {
2438 for (i = 0; i < vop2->data->nr_vps; i++) {
2439 if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) {
2440 vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/
2441 main_vp_index = i;
2442 break;
2443 }
2444 }
2445
2446 /* if no find unplug devices, use vp0 as main display */
2447 if (main_vp_index < 0) {
2448 main_vp_index = 0;
2449 vop2->vp_plane_mask[0] = plane_mask[0];
2450 }
2451
2452 j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */
2453 }
2454
2455 /* init other display except main display */
2456 for (i = 0; i < vop2->data->nr_vps; i++) {
2457 if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */
2458 continue;
2459 vop2->vp_plane_mask[i] = plane_mask[j++];
2460 }
2461
2462 /* store plane mask for vop2_fixup_dts */
2463 for (i = 0; i < vop2->data->nr_vps; i++) {
2464 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr;
2465 for (j = 0; j < layer_nr; j++) {
2466 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j];
2467 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id);
2468 }
2469 }
2470 }
2471
2472 if (vop2->version == VOP_VERSION_RK3588)
2473 rk3588_vop2_regsbak(vop2);
2474 else
2475 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len);
2476
2477 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK,
2478 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false);
2479 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
2480 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false);
2481
2482 for (i = 0; i < vop2->data->nr_vps; i++) {
2483 printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr);
2484 for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++)
2485 printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]);
2486 printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id);
2487 }
2488
2489 if (is_vop3(vop2))
2490 vop3_overlay_init(vop2, state);
2491 else
2492 vop2_overlay_init(vop2, state);
2493
2494 if (is_vop3(vop2)) {
2495 /*
2496 * you can rewrite at dts vop node:
2497 *
2498 * VOP3_ESMART_8K_MODE = 0,
2499 * VOP3_ESMART_4K_4K_MODE = 1,
2500 * VOP3_ESMART_4K_2K_2K_MODE = 2,
2501 * VOP3_ESMART_2K_2K_2K_2K_MODE = 3,
2502 *
2503 * &vop {
2504 * esmart_lb_mode = /bits/ 8 <2>;
2505 * };
2506 */
2507 ret = ofnode_read_u32(cstate->node, "esmart_lb_mode", &vop2->esmart_lb_mode);
2508 if (ret < 0)
2509 vop2->esmart_lb_mode = vop2->data->esmart_lb_mode;
2510 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, ESMART_LB_MODE_SEL_MASK,
2511 ESMART_LB_MODE_SEL_SHIFT, vop2->esmart_lb_mode, false);
2512
2513 vop3_init_esmart_scale_engine(vop2);
2514
2515 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, EN_MASK,
2516 DSP_VS_T_SEL_SHIFT, 0, false);
2517 }
2518
2519 if (vop2->version == VOP_VERSION_RK3568)
2520 vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0);
2521
2522 vop2->global_init = true;
2523 }
2524
vop2_initial(struct vop2 * vop2,struct display_state * state)2525 static int vop2_initial(struct vop2 *vop2, struct display_state *state)
2526 {
2527 rockchip_vop2_gamma_lut_init(vop2, state);
2528 rockchip_vop2_cubic_lut_init(vop2, state);
2529
2530 return 0;
2531 }
2532
2533 /*
2534 * VOP2 have multi video ports.
2535 * video port ------- crtc
2536 */
rockchip_vop2_preinit(struct display_state * state)2537 static int rockchip_vop2_preinit(struct display_state *state)
2538 {
2539 struct crtc_state *cstate = &state->crtc_state;
2540 const struct vop2_data *vop2_data = cstate->crtc->data;
2541
2542 if (!rockchip_vop2) {
2543 rockchip_vop2 = calloc(1, sizeof(struct vop2));
2544 if (!rockchip_vop2)
2545 return -ENOMEM;
2546 memset(rockchip_vop2, 0, sizeof(struct vop2));
2547 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG);
2548 rockchip_vop2->reg_len = RK3568_MAX_REG;
2549 #ifdef CONFIG_SPL_BUILD
2550 rockchip_vop2->regs = (void *)RK3528_VOP_BASE;
2551 #else
2552 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev);
2553 rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
2554 if (rockchip_vop2->grf <= 0)
2555 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf);
2556 #endif
2557 rockchip_vop2->version = vop2_data->version;
2558 rockchip_vop2->data = vop2_data;
2559 if (rockchip_vop2->version == VOP_VERSION_RK3588) {
2560 struct regmap *map;
2561
2562 rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF);
2563 if (rockchip_vop2->vop_grf <= 0)
2564 printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf);
2565 map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf");
2566 rockchip_vop2->vo1_grf = regmap_get_range(map, 0);
2567 if (rockchip_vop2->vo1_grf <= 0)
2568 printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf);
2569 rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
2570 if (rockchip_vop2->sys_pmu <= 0)
2571 printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu);
2572 }
2573 }
2574
2575 cstate->private = rockchip_vop2;
2576 cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output;
2577 cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature;
2578
2579 vop2_global_initial(rockchip_vop2, state);
2580
2581 return 0;
2582 }
2583
2584 /*
2585 * calc the dclk on rk3588
2586 * the available div of dclk is 1, 2, 4
2587 *
2588 */
vop2_calc_dclk(unsigned long child_clk,unsigned long max_dclk)2589 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
2590 {
2591 if (child_clk * 4 <= max_dclk)
2592 return child_clk * 4;
2593 else if (child_clk * 2 <= max_dclk)
2594 return child_clk * 2;
2595 else if (child_clk <= max_dclk)
2596 return child_clk;
2597 else
2598 return 0;
2599 }
2600
2601 /*
2602 * 4 pixclk/cycle on rk3588
2603 * RGB/eDP/HDMI: if_pixclk >= dclk_core
2604 * DP: dp_pixclk = dclk_out <= dclk_core
2605 * DSI: mipi_pixclk <= dclk_out <= dclk_core
2606 */
vop2_calc_cru_cfg(struct display_state * state,int * dclk_core_div,int * dclk_out_div,int * if_pixclk_div,int * if_dclk_div)2607 static unsigned long vop2_calc_cru_cfg(struct display_state *state,
2608 int *dclk_core_div, int *dclk_out_div,
2609 int *if_pixclk_div, int *if_dclk_div)
2610 {
2611 struct crtc_state *cstate = &state->crtc_state;
2612 struct connector_state *conn_state = &state->conn_state;
2613 struct drm_display_mode *mode = &conn_state->mode;
2614 struct vop2 *vop2 = cstate->private;
2615 unsigned long v_pixclk = mode->crtc_clock;
2616 unsigned long dclk_core_rate = v_pixclk >> 2;
2617 unsigned long dclk_rate = v_pixclk;
2618 unsigned long dclk_out_rate;
2619 u64 if_dclk_rate;
2620 u64 if_pixclk_rate;
2621 int output_type = conn_state->type;
2622 int output_mode = conn_state->output_mode;
2623 int K = 1;
2624
2625 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE &&
2626 output_mode == ROCKCHIP_OUT_MODE_YUV420) {
2627 printf("Dual channel and YUV420 can't work together\n");
2628 return -EINVAL;
2629 }
2630
2631 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
2632 output_mode == ROCKCHIP_OUT_MODE_YUV420)
2633 K = 2;
2634
2635 if (output_type == DRM_MODE_CONNECTOR_HDMIA) {
2636 /*
2637 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
2638 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
2639 */
2640 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE ||
2641 output_mode == ROCKCHIP_OUT_MODE_YUV420) {
2642 dclk_rate = dclk_rate >> 1;
2643 K = 2;
2644 }
2645 if (cstate->dsc_enable) {
2646 if_pixclk_rate = cstate->dsc_cds_clk_rate << 1;
2647 if_dclk_rate = cstate->dsc_cds_clk_rate;
2648 } else {
2649 if_pixclk_rate = (dclk_core_rate << 1) / K;
2650 if_dclk_rate = dclk_core_rate / K;
2651 }
2652
2653 if (v_pixclk > VOP2_MAX_DCLK_RATE)
2654 dclk_rate = vop2_calc_dclk(dclk_core_rate,
2655 vop2->data->vp_data[cstate->crtc_id].max_dclk);
2656
2657 if (!dclk_rate) {
2658 printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n",
2659 vop2->data->vp_data[cstate->crtc_id].max_dclk, if_pixclk_rate);
2660 return -EINVAL;
2661 }
2662 *if_pixclk_div = dclk_rate / if_pixclk_rate;
2663 *if_dclk_div = dclk_rate / if_dclk_rate;
2664 *dclk_core_div = dclk_rate / dclk_core_rate;
2665 printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n",
2666 dclk_rate, *if_pixclk_div, *if_dclk_div);
2667 } else if (output_type == DRM_MODE_CONNECTOR_eDP) {
2668 /* edp_pixclk = edp_dclk > dclk_core */
2669 if_pixclk_rate = v_pixclk / K;
2670 if_dclk_rate = v_pixclk / K;
2671 dclk_rate = if_pixclk_rate * K;
2672 *dclk_core_div = dclk_rate / dclk_core_rate;
2673 *if_pixclk_div = dclk_rate / if_pixclk_rate;
2674 *if_dclk_div = *if_pixclk_div;
2675 } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) {
2676 dclk_out_rate = v_pixclk >> 2;
2677 dclk_out_rate = dclk_out_rate / K;
2678
2679 dclk_rate = vop2_calc_dclk(dclk_out_rate,
2680 vop2->data->vp_data[cstate->crtc_id].max_dclk);
2681 if (!dclk_rate) {
2682 printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n",
2683 vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_core_rate);
2684 return -EINVAL;
2685 }
2686 *dclk_out_div = dclk_rate / dclk_out_rate;
2687 *dclk_core_div = dclk_rate / dclk_core_rate;
2688 } else if (output_type == DRM_MODE_CONNECTOR_DSI) {
2689 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2690 K = 2;
2691 if (cstate->dsc_enable)
2692 /* dsc output is 96bit, dsi input is 192 bit */
2693 if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1;
2694 else
2695 if_pixclk_rate = dclk_core_rate / K;
2696 /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */
2697 dclk_out_rate = dclk_core_rate / K;
2698 /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */
2699 dclk_rate = vop2_calc_dclk(dclk_out_rate,
2700 vop2->data->vp_data[cstate->crtc_id].max_dclk);
2701 if (!dclk_rate) {
2702 printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n",
2703 vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_rate);
2704 return -EINVAL;
2705 }
2706
2707 if (cstate->dsc_enable)
2708 dclk_rate /= cstate->dsc_slice_num;
2709
2710 *dclk_out_div = dclk_rate / dclk_out_rate;
2711 *dclk_core_div = dclk_rate / dclk_core_rate;
2712 *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/
2713 if (cstate->dsc_enable)
2714 *if_pixclk_div = dclk_out_rate * 1000LL / if_pixclk_rate;
2715
2716 } else if (output_type == DRM_MODE_CONNECTOR_DPI) {
2717 dclk_rate = v_pixclk;
2718 *dclk_core_div = dclk_rate / dclk_core_rate;
2719 }
2720
2721 *if_pixclk_div = ilog2(*if_pixclk_div);
2722 *if_dclk_div = ilog2(*if_dclk_div);
2723 *dclk_core_div = ilog2(*dclk_core_div);
2724 *dclk_out_div = ilog2(*dclk_out_div);
2725
2726 return dclk_rate;
2727 }
2728
vop2_calc_dsc_clk(struct display_state * state)2729 static int vop2_calc_dsc_clk(struct display_state *state)
2730 {
2731 struct connector_state *conn_state = &state->conn_state;
2732 struct drm_display_mode *mode = &conn_state->mode;
2733 struct crtc_state *cstate = &state->crtc_state;
2734 u64 v_pixclk = mode->crtc_clock * 1000LL; /* video timing pixclk */
2735 u8 k = 1;
2736
2737 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2738 k = 2;
2739
2740 cstate->dsc_txp_clk_rate = v_pixclk;
2741 do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k));
2742
2743 cstate->dsc_pxl_clk_rate = v_pixclk;
2744 do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k));
2745
2746 /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
2747 * cds_dat_width = 96;
2748 * bits_per_pixel = [8-12];
2749 * As cds clk is div from txp clk and only support 1/2/4 div,
2750 * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4,
2751 * otherwise dsc_cds = crtc_clock / 8;
2752 */
2753 cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8);
2754
2755 return 0;
2756 }
2757
rk3588_vop2_if_cfg(struct display_state * state)2758 static unsigned long rk3588_vop2_if_cfg(struct display_state *state)
2759 {
2760 struct crtc_state *cstate = &state->crtc_state;
2761 struct connector_state *conn_state = &state->conn_state;
2762 struct drm_display_mode *mode = &conn_state->mode;
2763 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
2764 struct vop2 *vop2 = cstate->private;
2765 u32 vp_offset = (cstate->crtc_id * 0x100);
2766 u16 hdisplay = mode->crtc_hdisplay;
2767 int output_if = conn_state->output_if;
2768 int if_pixclk_div = 0;
2769 int if_dclk_div = 0;
2770 unsigned long dclk_rate;
2771 u32 val;
2772
2773 if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
2774 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
2775 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
2776 } else {
2777 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
2778 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
2779 }
2780
2781 if (cstate->dsc_enable) {
2782 int k = 1;
2783
2784 if (!vop2->data->nr_dscs) {
2785 printf("Unsupported DSC\n");
2786 return 0;
2787 }
2788
2789 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
2790 k = 2;
2791
2792 cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
2793 cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k;
2794 cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num;
2795
2796 vop2_calc_dsc_clk(state);
2797 printf("Enable DSC%d slice:%dx%d, slice num:%d\n",
2798 cstate->dsc_id, dsc_sink_cap->slice_width,
2799 dsc_sink_cap->slice_height, cstate->dsc_slice_num);
2800 }
2801
2802 dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div);
2803
2804 if (output_if & VOP_OUTPUT_IF_RGB) {
2805 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2806 4, false);
2807 }
2808
2809 if (output_if & VOP_OUTPUT_IF_BT1120) {
2810 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2811 3, false);
2812 }
2813
2814 if (output_if & VOP_OUTPUT_IF_BT656) {
2815 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT,
2816 2, false);
2817 }
2818
2819 if (output_if & VOP_OUTPUT_IF_MIPI0) {
2820 if (cstate->crtc_id == 2)
2821 val = 0;
2822 else
2823 val = 1;
2824
2825 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
2826 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2827 RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false);
2828
2829 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT,
2830 1, false);
2831 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false);
2832 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT,
2833 if_pixclk_div, false);
2834
2835 if (conn_state->hold_mode) {
2836 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2837 EN_MASK, EDPI_TE_EN, !cstate->soft_te, false);
2838 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2839 EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
2840 }
2841 }
2842
2843 if (output_if & VOP_OUTPUT_IF_MIPI1) {
2844 if (cstate->crtc_id == 2)
2845 val = 0;
2846 else if (cstate->crtc_id == 3)
2847 val = 1;
2848 else
2849 val = 3; /*VP1*/
2850 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
2851 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2852 RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false);
2853
2854 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT,
2855 1, false);
2856 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT,
2857 val, false);
2858 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT,
2859 if_pixclk_div, false);
2860
2861 if (conn_state->hold_mode) {
2862 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2863 EN_MASK, EDPI_TE_EN, !cstate->soft_te, false);
2864 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2865 EN_MASK, EDPI_WMS_HOLD_EN, 1, false);
2866 }
2867 }
2868
2869 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
2870 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
2871 MIPI_DUAL_EN_SHIFT, 1, false);
2872 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
2873 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
2874 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
2875 false);
2876 switch (conn_state->type) {
2877 case DRM_MODE_CONNECTOR_DisplayPort:
2878 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2879 RK3588_DP_DUAL_EN_SHIFT, 1, false);
2880 break;
2881 case DRM_MODE_CONNECTOR_eDP:
2882 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2883 RK3588_EDP_DUAL_EN_SHIFT, 1, false);
2884 break;
2885 case DRM_MODE_CONNECTOR_HDMIA:
2886 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2887 RK3588_HDMI_DUAL_EN_SHIFT, 1, false);
2888 break;
2889 case DRM_MODE_CONNECTOR_DSI:
2890 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
2891 RK3568_MIPI_DUAL_EN_SHIFT, 1, false);
2892 break;
2893 default:
2894 break;
2895 }
2896 }
2897
2898 if (output_if & VOP_OUTPUT_IF_eDP0) {
2899 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT,
2900 1, false);
2901 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
2902 cstate->crtc_id, false);
2903 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
2904 if_dclk_div, false);
2905
2906 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
2907 if_pixclk_div, false);
2908
2909 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2910 RK3588_GRF_EDP0_ENABLE_SHIFT, 1);
2911 }
2912
2913 if (output_if & VOP_OUTPUT_IF_eDP1) {
2914 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT,
2915 1, false);
2916 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2917 cstate->crtc_id, false);
2918 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2919 if_dclk_div, false);
2920
2921 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2922 if_pixclk_div, false);
2923
2924 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2925 RK3588_GRF_EDP1_ENABLE_SHIFT, 1);
2926 }
2927
2928 if (output_if & VOP_OUTPUT_IF_HDMI0) {
2929 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT,
2930 1, false);
2931 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT,
2932 cstate->crtc_id, false);
2933 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT,
2934 if_dclk_div, false);
2935
2936 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT,
2937 if_pixclk_div, false);
2938
2939 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2940 RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1);
2941 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2942 HDMI_SYNC_POL_MASK,
2943 HDMI0_SYNC_POL_SHIFT, val);
2944 }
2945
2946 if (output_if & VOP_OUTPUT_IF_HDMI1) {
2947 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT,
2948 1, false);
2949 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT,
2950 cstate->crtc_id, false);
2951 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT,
2952 if_dclk_div, false);
2953
2954 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT,
2955 if_pixclk_div, false);
2956
2957 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK,
2958 RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1);
2959 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0,
2960 HDMI_SYNC_POL_MASK,
2961 HDMI1_SYNC_POL_SHIFT, val);
2962 }
2963
2964 if (output_if & VOP_OUTPUT_IF_DP0) {
2965 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT,
2966 1, false);
2967 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT,
2968 cstate->crtc_id, false);
2969 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2970 RK3588_DP0_PIN_POL_SHIFT, val, false);
2971 }
2972
2973 if (output_if & VOP_OUTPUT_IF_DP1) {
2974 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT,
2975 1, false);
2976 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT,
2977 cstate->crtc_id, false);
2978 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK,
2979 RK3588_DP1_PIN_POL_SHIFT, val, false);
2980 }
2981
2982 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2983 DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false);
2984 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3,
2985 DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false);
2986
2987 return dclk_rate;
2988 }
2989
rk3568_vop2_if_cfg(struct display_state * state)2990 static unsigned long rk3568_vop2_if_cfg(struct display_state *state)
2991 {
2992 struct crtc_state *cstate = &state->crtc_state;
2993 struct connector_state *conn_state = &state->conn_state;
2994 struct drm_display_mode *mode = &conn_state->mode;
2995 struct vop2 *vop2 = cstate->private;
2996 u32 vp_offset = (cstate->crtc_id * 0x100);
2997 bool dclk_inv;
2998 u32 val;
2999
3000 dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
3001 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3002 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3003
3004 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
3005 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
3006 1, false);
3007 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3008 RGB_MUX_SHIFT, cstate->crtc_id, false);
3009 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
3010 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
3011 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
3012 GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
3013 }
3014
3015 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) {
3016 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
3017 1, false);
3018 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK,
3019 BT1120_EN_SHIFT, 1, false);
3020 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3021 RGB_MUX_SHIFT, cstate->crtc_id, false);
3022 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
3023 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv);
3024 }
3025
3026 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
3027 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
3028 1, false);
3029 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3030 RGB_MUX_SHIFT, cstate->crtc_id, false);
3031 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK,
3032 GRF_BT656_CLK_INV_SHIFT, !dclk_inv);
3033 }
3034
3035 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
3036 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
3037 1, false);
3038 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3039 LVDS0_MUX_SHIFT, cstate->crtc_id, false);
3040 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
3041 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
3042 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3043 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
3044 }
3045
3046 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) {
3047 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT,
3048 1, false);
3049 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3050 LVDS1_MUX_SHIFT, cstate->crtc_id, false);
3051 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK,
3052 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
3053 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3054 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
3055 }
3056
3057 if (conn_state->output_flags &
3058 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE |
3059 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) {
3060 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3061 LVDS_DUAL_EN_SHIFT, 1, false);
3062 if (conn_state->output_flags &
3063 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3064 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3065 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1,
3066 false);
3067 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
3068 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK,
3069 LVDS_DUAL_SWAP_EN_SHIFT, 1, false);
3070 }
3071
3072 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
3073 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
3074 1, false);
3075 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3076 MIPI0_MUX_SHIFT, cstate->crtc_id, false);
3077 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3078 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
3079 }
3080
3081 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) {
3082 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT,
3083 1, false);
3084 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3085 MIPI1_MUX_SHIFT, cstate->crtc_id, false);
3086 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3087 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false);
3088 }
3089
3090 if (conn_state->output_flags &
3091 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
3092 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK,
3093 MIPI_DUAL_EN_SHIFT, 1, false);
3094 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP)
3095 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3096 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1,
3097 false);
3098 }
3099
3100 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) {
3101 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT,
3102 1, false);
3103 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3104 EDP0_MUX_SHIFT, cstate->crtc_id, false);
3105 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3106 IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false);
3107 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_EDP_PIN_POL_MASK,
3108 IF_CTRL_EDP_PIN_POL_SHIFT, val, false);
3109 }
3110
3111 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
3112 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
3113 1, false);
3114 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3115 HDMI0_MUX_SHIFT, cstate->crtc_id, false);
3116 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3117 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
3118 vop2_mask_write(vop2, RK3568_DSP_IF_POL,
3119 IF_CRTL_HDMI_PIN_POL_MASK,
3120 IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
3121 }
3122
3123 return mode->clock;
3124 }
3125
rk3528_vop2_if_cfg(struct display_state * state)3126 static unsigned long rk3528_vop2_if_cfg(struct display_state *state)
3127 {
3128 struct crtc_state *cstate = &state->crtc_state;
3129 struct connector_state *conn_state = &state->conn_state;
3130 struct drm_display_mode *mode = &conn_state->mode;
3131 struct vop2 *vop2 = cstate->private;
3132 u32 val;
3133
3134 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3135 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3136
3137 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) {
3138 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT,
3139 1, false);
3140 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3141 RGB_MUX_SHIFT, cstate->crtc_id, false);
3142 }
3143
3144 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) {
3145 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT,
3146 1, false);
3147 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3148 HDMI0_MUX_SHIFT, cstate->crtc_id, false);
3149 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3150 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false);
3151 vop2_mask_write(vop2, RK3568_DSP_IF_POL,
3152 IF_CRTL_HDMI_PIN_POL_MASK,
3153 IF_CRTL_HDMI_PIN_POL_SHIT, val, false);
3154 }
3155
3156 return mode->crtc_clock;
3157 }
3158
rk3562_vop2_if_cfg(struct display_state * state)3159 static unsigned long rk3562_vop2_if_cfg(struct display_state *state)
3160 {
3161 struct crtc_state *cstate = &state->crtc_state;
3162 struct connector_state *conn_state = &state->conn_state;
3163 struct drm_display_mode *mode = &conn_state->mode;
3164 struct vop2 *vop2 = cstate->private;
3165 bool dclk_inv;
3166 u32 val;
3167
3168 dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
3169 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE);
3170 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
3171
3172 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) {
3173 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT,
3174 1, false);
3175 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3176 RGB_MUX_SHIFT, cstate->crtc_id, false);
3177 vop2_grf_writel(vop2, vop2->grf, RK3562_GRF_IOC_VO_IO_CON, EN_MASK,
3178 GRF_RGB_DCLK_INV_SHIFT, dclk_inv);
3179 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
3180 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
3181 }
3182
3183 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) {
3184 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT,
3185 1, false);
3186 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3187 LVDS0_MUX_SHIFT, cstate->crtc_id, false);
3188 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3189 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false);
3190 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
3191 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false);
3192 }
3193
3194 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) {
3195 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT,
3196 1, false);
3197 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK,
3198 MIPI0_MUX_SHIFT, cstate->crtc_id, false);
3199 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK,
3200 RK3562_MIPI_DCLK_POL_SHIFT, dclk_inv, false);
3201 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK,
3202 RK3562_MIPI_PIN_POL_SHIFT, val, false);
3203 }
3204
3205 return mode->crtc_clock;
3206 }
3207
vop2_post_color_swap(struct display_state * state)3208 static void vop2_post_color_swap(struct display_state *state)
3209 {
3210 struct crtc_state *cstate = &state->crtc_state;
3211 struct connector_state *conn_state = &state->conn_state;
3212 struct vop2 *vop2 = cstate->private;
3213 u32 vp_offset = (cstate->crtc_id * 0x100);
3214 u32 output_type = conn_state->type;
3215 u32 data_swap = 0;
3216
3217 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode) ||
3218 is_rb_swap(conn_state->bus_format, conn_state->output_mode))
3219 data_swap = DSP_RB_SWAP;
3220
3221 if (vop2->version == VOP_VERSION_RK3588 &&
3222 (output_type == DRM_MODE_CONNECTOR_HDMIA ||
3223 output_type == DRM_MODE_CONNECTOR_eDP) &&
3224 (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
3225 conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30))
3226 data_swap |= DSP_RG_SWAP;
3227
3228 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset,
3229 DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false);
3230 }
3231
vop2_clk_set_parent(struct clk * clk,struct clk * parent)3232 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent)
3233 {
3234 int ret = 0;
3235
3236 if (parent->dev)
3237 ret = clk_set_parent(clk, parent);
3238 if (ret < 0)
3239 debug("failed to set %s as parent for %s\n",
3240 parent->dev->name, clk->dev->name);
3241 }
3242
vop2_clk_set_rate(struct clk * clk,ulong rate)3243 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate)
3244 {
3245 int ret = 0;
3246
3247 if (clk->dev)
3248 ret = clk_set_rate(clk, rate);
3249 if (ret < 0)
3250 debug("failed to set %s rate %lu \n", clk->dev->name, rate);
3251
3252 return ret;
3253 }
3254
vop2_calc_dsc_cru_cfg(struct display_state * state,int * dsc_txp_clk_div,int * dsc_pxl_clk_div,int * dsc_cds_clk_div,u64 dclk_rate)3255 static void vop2_calc_dsc_cru_cfg(struct display_state *state,
3256 int *dsc_txp_clk_div, int *dsc_pxl_clk_div,
3257 int *dsc_cds_clk_div, u64 dclk_rate)
3258 {
3259 struct crtc_state *cstate = &state->crtc_state;
3260
3261 *dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate;
3262 *dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate;
3263 *dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate;
3264
3265 *dsc_txp_clk_div = ilog2(*dsc_txp_clk_div);
3266 *dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div);
3267 *dsc_cds_clk_div = ilog2(*dsc_cds_clk_div);
3268 }
3269
vop2_load_pps(struct display_state * state,struct vop2 * vop2,u8 dsc_id)3270 static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id)
3271 {
3272 struct crtc_state *cstate = &state->crtc_state;
3273 struct drm_dsc_picture_parameter_set *pps = &cstate->pps;
3274 struct drm_dsc_picture_parameter_set config_pps;
3275 const struct vop2_data *vop2_data = vop2->data;
3276 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
3277 u32 *pps_val = (u32 *)&config_pps;
3278 u32 decoder_regs_offset = (dsc_id * 0x100);
3279 int i = 0;
3280
3281 memcpy(&config_pps, pps, sizeof(config_pps));
3282
3283 if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) {
3284 config_pps.pps_3 &= 0xf0;
3285 config_pps.pps_3 |= dsc_data->max_linebuf_depth;
3286 printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n",
3287 dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf);
3288 }
3289
3290 for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
3291 config_pps.rc_range_parameters[i] =
3292 (pps->rc_range_parameters[i] >> 3 & 0x1f) |
3293 ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) |
3294 ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) |
3295 ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10);
3296 }
3297
3298 for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++)
3299 vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++);
3300 }
3301
vop2_dsc_enable(struct display_state * state,struct vop2 * vop2,u8 dsc_id,u64 dclk_rate)3302 static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate)
3303 {
3304 struct connector_state *conn_state = &state->conn_state;
3305 struct drm_display_mode *mode = &conn_state->mode;
3306 struct crtc_state *cstate = &state->crtc_state;
3307 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap;
3308 const struct vop2_data *vop2_data = vop2->data;
3309 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id];
3310 bool mipi_ds_mode = false;
3311 u8 dsc_interface_mode = 0;
3312 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
3313 u16 hdisplay = mode->crtc_hdisplay;
3314 u16 htotal = mode->crtc_htotal;
3315 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
3316 u16 vdisplay = mode->crtc_vdisplay;
3317 u16 vtotal = mode->crtc_vtotal;
3318 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
3319 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
3320 u16 vact_end = vact_st + vdisplay;
3321 u32 ctrl_regs_offset = (dsc_id * 0x30);
3322 u32 decoder_regs_offset = (dsc_id * 0x100);
3323 int dsc_txp_clk_div = 0;
3324 int dsc_pxl_clk_div = 0;
3325 int dsc_cds_clk_div = 0;
3326 int val = 0;
3327
3328 if (!vop2->data->nr_dscs) {
3329 printf("Unsupported DSC\n");
3330 return;
3331 }
3332
3333 if (cstate->dsc_slice_num > dsc_data->max_slice_num)
3334 printf("DSC%d supported max slice is: %d, current is: %d\n",
3335 dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num);
3336
3337 if (dsc_data->pd_id) {
3338 if (vop2_power_domain_on(vop2, dsc_data->pd_id))
3339 printf("open dsc%d pd fail\n", dsc_id);
3340 }
3341
3342 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK,
3343 SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false);
3344 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK,
3345 DSC_PORT_SEL_SHIFT, cstate->crtc_id, false);
3346 if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
3347 dsc_interface_mode = VOP_DSC_IF_HDMI;
3348 } else {
3349 mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE);
3350 if (mipi_ds_mode)
3351 dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE;
3352 else
3353 dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE;
3354 }
3355
3356 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3357 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
3358 DSC_MAN_MODE_SHIFT, 0, false);
3359 else
3360 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
3361 DSC_MAN_MODE_SHIFT, 1, false);
3362
3363 vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate);
3364
3365 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK,
3366 DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false);
3367 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK,
3368 DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false);
3369 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK,
3370 DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false);
3371 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK,
3372 DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false);
3373 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
3374 DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false);
3375 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK,
3376 DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false);
3377 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
3378 DSC_HALT_EN_SHIFT, mipi_ds_mode, false);
3379
3380 if (!mipi_ds_mode) {
3381 u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end;
3382 u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16;
3383 u64 dsc_cds_rate = cstate->dsc_cds_clk_rate;
3384 u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */
3385 u32 dly_num, dsc_cds_rate_mhz, val = 0;
3386 int k = 1;
3387
3388 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
3389 k = 2;
3390
3391 if (target_bpp >> 4 < dsc_data->min_bits_per_pixel)
3392 printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel);
3393
3394 /*
3395 * dly_num = delay_line_num * T(one-line) / T (dsc_cds)
3396 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz
3397 * T (dsc_cds) = 1 / dsc_cds_rate_mhz
3398 *
3399 * HDMI:
3400 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay
3401 * delay_line_num = 4 - BPP / 8
3402 * = (64 - target_bpp / 8) / 16
3403 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
3404 *
3405 * MIPI DSI[4320 and 9216 is buffer size for DSC]:
3406 * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size;
3407 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3408 * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size;
3409 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3410 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num
3411 */
3412 do_div(dsc_cds_rate, 1000000); /* hz to Mhz */
3413 dsc_cds_rate_mhz = dsc_cds_rate;
3414 dsc_hsync = hsync_len / 2;
3415 if (dsc_interface_mode == VOP_DSC_IF_HDMI) {
3416 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
3417 } else {
3418 int dsc_buf_size = dsc_id == 0 ? 4320 * 8 : 9216 * 2;
3419 int delay_line_num = dsc_buf_size / cstate->dsc_slice_num /
3420 be16_to_cpu(cstate->pps.chunk_size);
3421
3422 delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
3423 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num;
3424
3425 /* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */
3426 if (dsc_hsync < 8)
3427 dsc_hsync = 8;
3428 }
3429 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK,
3430 DSC_INIT_DLY_MODE_SHIFT, 0, false);
3431 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK,
3432 DSC_INIT_DLY_NUM_SHIFT, dly_num, false);
3433
3434 /*
3435 * htotal / dclk_core = dsc_htotal /cds_clk
3436 *
3437 * dclk_core = DCLK / (1 << dclk_core->div_val)
3438 * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val)
3439 * txp_clk = DCLK / (1 << dsc_txp_clk->div_val)
3440 *
3441 * dsc_htotal = htotal * (1 << dclk_core->div_val) /
3442 * ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val))
3443 */
3444 dsc_htotal = htotal * (1 << cstate->dclk_core_div) /
3445 ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div));
3446 val = dsc_htotal << 16 | dsc_hsync;
3447 vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK,
3448 DSC_HTOTAL_PW_SHIFT, val, false);
3449
3450 dsc_hact_st = hact_st / 2;
3451 dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st;
3452 val = dsc_hact_end << 16 | dsc_hact_st;
3453 vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK,
3454 DSC_HACT_ST_END_SHIFT, val, false);
3455
3456 vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK,
3457 DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false);
3458 vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK,
3459 DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false);
3460 }
3461
3462 vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK,
3463 RST_DEASSERT_SHIFT, 1, false);
3464 udelay(10);
3465
3466 val |= DSC_CTRL0_DEF_CON | (ilog2(cstate->dsc_slice_num) << DSC_NSLC_SHIFT) |
3467 ((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT);
3468 vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
3469
3470 vop2_load_pps(state, vop2, dsc_id);
3471
3472 val |= (1 << DSC_PPS_UPD_SHIFT);
3473 vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
3474
3475 printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n",
3476 dsc_id,
3477 cstate->dsc_txp_clk_rate, dsc_txp_clk_div,
3478 cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div,
3479 cstate->dsc_cds_clk_rate, dsc_cds_clk_div);
3480 }
3481
is_extend_pll(struct display_state * state,struct udevice ** clk_dev)3482 static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev)
3483 {
3484 struct crtc_state *cstate = &state->crtc_state;
3485 struct vop2 *vop2 = cstate->private;
3486 struct udevice *vp_dev, *dev;
3487 struct ofnode_phandle_args args;
3488 char vp_name[10];
3489 int ret;
3490
3491 if (vop2->version != VOP_VERSION_RK3588)
3492 return false;
3493
3494 sprintf(vp_name, "port@%d", cstate->crtc_id);
3495 if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) {
3496 debug("warn: can't get vp device\n");
3497 return false;
3498 }
3499
3500 ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0,
3501 0, &args);
3502 if (ret) {
3503 debug("assigned-clock-parents's node not define\n");
3504 return false;
3505 }
3506
3507 if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) {
3508 debug("warn: can't get clk device\n");
3509 return false;
3510 }
3511
3512 if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) {
3513 printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name);
3514 if (clk_dev)
3515 *clk_dev = dev;
3516 return true;
3517 }
3518
3519 return false;
3520 }
3521
vop3_mcu_mode_setup(struct display_state * state)3522 static void vop3_mcu_mode_setup(struct display_state *state)
3523 {
3524 struct crtc_state *cstate = &state->crtc_state;
3525 struct vop2 *vop2 = cstate->private;
3526 u32 vp_offset = (cstate->crtc_id * 0x100);
3527
3528 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3529 MCU_TYPE_SHIFT, 1, false);
3530 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3531 MCU_HOLD_MODE_SHIFT, 1, false);
3532 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK,
3533 MCU_PIX_TOTAL_SHIFT, cstate->mcu_timing.mcu_pix_total, false);
3534 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK,
3535 MCU_CS_PST_SHIFT, cstate->mcu_timing.mcu_cs_pst, false);
3536 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK,
3537 MCU_CS_PEND_SHIFT, cstate->mcu_timing.mcu_cs_pend, false);
3538 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK,
3539 MCU_RW_PST_SHIFT, cstate->mcu_timing.mcu_rw_pst, false);
3540 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK,
3541 MCU_RW_PEND_SHIFT, cstate->mcu_timing.mcu_rw_pend, false);
3542 }
3543
vop3_mcu_bypass_mode_setup(struct display_state * state)3544 static void vop3_mcu_bypass_mode_setup(struct display_state *state)
3545 {
3546 struct crtc_state *cstate = &state->crtc_state;
3547 struct vop2 *vop2 = cstate->private;
3548 u32 vp_offset = (cstate->crtc_id * 0x100);
3549
3550 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3551 MCU_TYPE_SHIFT, 1, false);
3552 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3553 MCU_HOLD_MODE_SHIFT, 1, false);
3554 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK,
3555 MCU_PIX_TOTAL_SHIFT, 53, false);
3556 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK,
3557 MCU_CS_PST_SHIFT, 6, false);
3558 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK,
3559 MCU_CS_PEND_SHIFT, 48, false);
3560 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK,
3561 MCU_RW_PST_SHIFT, 12, false);
3562 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK,
3563 MCU_RW_PEND_SHIFT, 30, false);
3564 }
3565
rockchip_vop2_send_mcu_cmd(struct display_state * state,u32 type,u32 value)3566 static int rockchip_vop2_send_mcu_cmd(struct display_state *state, u32 type, u32 value)
3567 {
3568 struct crtc_state *cstate = &state->crtc_state;
3569 struct connector_state *conn_state = &state->conn_state;
3570 struct drm_display_mode *mode = &conn_state->mode;
3571 struct vop2 *vop2 = cstate->private;
3572 u32 vp_offset = (cstate->crtc_id * 0x100);
3573 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
3574
3575 /*
3576 * 1.disable port dclk auto gating.
3577 * 2.set mcu bypass mode timing to adapt to the mode of sending cmds.
3578 * 3.make setting of output mode take effect.
3579 * 4.set dclk rate to 150M, in order to sync with hclk in sending cmds.
3580 */
3581 if (type == MCU_SETBYPASS && value) {
3582 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK,
3583 AUTO_GATING_EN_SHIFT, 0, false);
3584 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK,
3585 PORT_DCLK_AUTO_GATING_EN_SHIFT, 0, false);
3586 vop3_mcu_bypass_mode_setup(state);
3587 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3588 STANDBY_EN_SHIFT, 0, false);
3589 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
3590 vop2_clk_set_rate(&cstate->dclk, 150000000);
3591 }
3592
3593 switch (type) {
3594 case MCU_WRCMD:
3595 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3596 MCU_RS_SHIFT, 0, false);
3597 vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset,
3598 MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT,
3599 value, false);
3600 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3601 MCU_RS_SHIFT, 1, false);
3602 break;
3603 case MCU_WRDATA:
3604 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3605 MCU_RS_SHIFT, 1, false);
3606 vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset,
3607 MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT,
3608 value, false);
3609 break;
3610 case MCU_SETBYPASS:
3611 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
3612 MCU_BYPASS_SHIFT, value ? 1 : 0, false);
3613 break;
3614 default:
3615 break;
3616 }
3617
3618 /*
3619 * 1.restore port dclk auto gating.
3620 * 2.restore mcu data mode timing.
3621 * 3.restore dclk rate to crtc_clock.
3622 */
3623 if (type == MCU_SETBYPASS && !value) {
3624 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK,
3625 AUTO_GATING_EN_SHIFT, 1, false);
3626 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK,
3627 PORT_DCLK_AUTO_GATING_EN_SHIFT, 1, false);
3628 vop3_mcu_mode_setup(state);
3629 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3630 STANDBY_EN_SHIFT, 1, false);
3631 vop2_clk_set_rate(&cstate->dclk, mode->crtc_clock * 1000);
3632 }
3633
3634 return 0;
3635 }
3636
vop2_get_vrefresh(struct display_state * state)3637 static int vop2_get_vrefresh(struct display_state *state)
3638 {
3639 struct crtc_state *cstate = &state->crtc_state;
3640 struct connector_state *conn_state = &state->conn_state;
3641 struct drm_display_mode *mode = &conn_state->mode;
3642
3643 if (cstate->mcu_timing.mcu_pix_total)
3644 return mode->vrefresh / cstate->mcu_timing.mcu_pix_total;
3645 else
3646 return mode->vrefresh;
3647 }
3648
rockchip_vop2_init(struct display_state * state)3649 static int rockchip_vop2_init(struct display_state *state)
3650 {
3651 struct crtc_state *cstate = &state->crtc_state;
3652 struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id];
3653 struct connector_state *conn_state = &state->conn_state;
3654 struct drm_display_mode *mode = &conn_state->mode;
3655 struct vop2 *vop2 = cstate->private;
3656 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
3657 u16 hdisplay = mode->crtc_hdisplay;
3658 u16 htotal = mode->crtc_htotal;
3659 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
3660 u16 hact_end = hact_st + hdisplay;
3661 u16 vdisplay = mode->crtc_vdisplay;
3662 u16 vtotal = mode->crtc_vtotal;
3663 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
3664 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
3665 u16 vact_end = vact_st + vdisplay;
3666 bool yuv_overlay = false;
3667 u32 vp_offset = (cstate->crtc_id * 0x100);
3668 u32 line_flag_offset = (cstate->crtc_id * 4);
3669 u32 val, act_end;
3670 u8 dither_down_en = 0;
3671 u8 dither_down_mode = 0;
3672 u8 pre_dither_down_en = 0;
3673 u8 dclk_div_factor = 0;
3674 char output_type_name[30] = {0};
3675 #ifndef CONFIG_SPL_BUILD
3676 char dclk_name[9];
3677 #endif
3678 struct clk hdmi0_phy_pll;
3679 struct clk hdmi1_phy_pll;
3680 struct clk hdmi_phy_pll;
3681 struct udevice *disp_dev;
3682 unsigned long dclk_rate = 0;
3683 int ret;
3684
3685 printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n",
3686 mode->crtc_hdisplay, mode->vdisplay,
3687 mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
3688 vop2_get_vrefresh(state),
3689 get_output_if_name(conn_state->output_if, output_type_name),
3690 cstate->crtc_id);
3691
3692 if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
3693 cstate->splice_mode = true;
3694 cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id;
3695 if (!cstate->splice_crtc_id) {
3696 printf("%s: Splice mode is unsupported by vp%d\n",
3697 __func__, cstate->crtc_id);
3698 return -EINVAL;
3699 }
3700
3701 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK,
3702 PORT_MERGE_EN_SHIFT, 1, false);
3703 }
3704
3705 vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
3706 RK3588_VP0_LINE_FLAG_OR_EN_SHIFT + cstate->crtc_id, 1, false);
3707 vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK,
3708 RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT + cstate->crtc_id, 1, false);
3709
3710 vop2_initial(vop2, state);
3711 if (vop2->version == VOP_VERSION_RK3588)
3712 dclk_rate = rk3588_vop2_if_cfg(state);
3713 else if (vop2->version == VOP_VERSION_RK3568)
3714 dclk_rate = rk3568_vop2_if_cfg(state);
3715 else if (vop2->version == VOP_VERSION_RK3528)
3716 dclk_rate = rk3528_vop2_if_cfg(state);
3717 else if (vop2->version == VOP_VERSION_RK3562)
3718 dclk_rate = rk3562_vop2_if_cfg(state);
3719
3720 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
3721 !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT))
3722 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
3723
3724 vop2_post_color_swap(state);
3725
3726 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK,
3727 OUT_MODE_SHIFT, conn_state->output_mode, false);
3728
3729 switch (conn_state->bus_format) {
3730 case MEDIA_BUS_FMT_RGB565_1X16:
3731 dither_down_en = 1;
3732 dither_down_mode = RGB888_TO_RGB565;
3733 pre_dither_down_en = 1;
3734 break;
3735 case MEDIA_BUS_FMT_RGB666_1X18:
3736 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
3737 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
3738 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA:
3739 dither_down_en = 1;
3740 dither_down_mode = RGB888_TO_RGB666;
3741 pre_dither_down_en = 1;
3742 break;
3743 case MEDIA_BUS_FMT_YUV8_1X24:
3744 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
3745 dither_down_en = 0;
3746 pre_dither_down_en = 1;
3747 break;
3748 case MEDIA_BUS_FMT_YUV10_1X30:
3749 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
3750 dither_down_en = 0;
3751 pre_dither_down_en = 0;
3752 break;
3753 case MEDIA_BUS_FMT_YUYV10_1X20:
3754 case MEDIA_BUS_FMT_RGB888_1X24:
3755 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
3756 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
3757 case MEDIA_BUS_FMT_RGB101010_1X30:
3758 default:
3759 dither_down_en = 0;
3760 pre_dither_down_en = 1;
3761 break;
3762 }
3763
3764 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3765 DITHER_DOWN_EN_SHIFT, dither_down_en, false);
3766 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3767 DITHER_DOWN_MODE_SHIFT, dither_down_mode, false);
3768 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3769 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false);
3770 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3771 DITHER_DOWN_MODE_SHIFT, dither_down_mode, false);
3772
3773 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0;
3774 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id,
3775 yuv_overlay, false);
3776
3777 cstate->yuv_overlay = yuv_overlay;
3778
3779 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset,
3780 (htotal << 16) | hsync_len);
3781 val = hact_st << 16;
3782 val |= hact_end;
3783 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val);
3784 val = vact_st << 16;
3785 val |= vact_end;
3786 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val);
3787 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
3788 u16 vact_st_f1 = vtotal + vact_st + 1;
3789 u16 vact_end_f1 = vact_st_f1 + vdisplay;
3790
3791 val = vact_st_f1 << 16 | vact_end_f1;
3792 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset,
3793 val);
3794
3795 val = vtotal << 16 | (vtotal + vsync_len);
3796 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val);
3797 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3798 INTERLACE_EN_SHIFT, 1, false);
3799 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3800 DSP_FILED_POL, 1, false);
3801 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3802 P2I_EN_SHIFT, 1, false);
3803 vtotal += vtotal + 1;
3804 act_end = vact_end_f1;
3805 } else {
3806 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3807 INTERLACE_EN_SHIFT, 0, false);
3808 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3809 P2I_EN_SHIFT, 0, false);
3810 act_end = vact_end;
3811 }
3812 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset,
3813 (vtotal << 16) | vsync_len);
3814
3815 if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
3816 conn_state->output_if & VOP_OUTPUT_IF_BT656)
3817 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3818 CORE_DCLK_DIV_EN_SHIFT, 1, false);
3819 else
3820 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3821 CORE_DCLK_DIV_EN_SHIFT, 0, false);
3822
3823 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420)
3824 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3825 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false);
3826 else
3827 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
3828 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false);
3829
3830 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
3831 OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false);
3832
3833 if (yuv_overlay)
3834 val = 0x20010200;
3835 else
3836 val = 0;
3837 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val);
3838 if (cstate->splice_mode) {
3839 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK,
3840 OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id,
3841 yuv_overlay, false);
3842 vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val);
3843 }
3844
3845 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3846 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false);
3847
3848 if (vp->xmirror_en)
3849 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
3850 DSP_X_MIR_EN_SHIFT, 1, false);
3851
3852 vop2_tv_config_update(state, vop2);
3853 vop2_post_config(state, vop2);
3854 if (cstate->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC))
3855 vop3_post_config(state, vop2);
3856
3857 if (cstate->dsc_enable) {
3858 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
3859 vop2_dsc_enable(state, vop2, 0, dclk_rate * 1000LL);
3860 vop2_dsc_enable(state, vop2, 1, dclk_rate * 1000LL);
3861 } else {
3862 vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate * 1000LL);
3863 }
3864 }
3865
3866 #ifndef CONFIG_SPL_BUILD
3867 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id);
3868 ret = clk_get_by_name(cstate->dev, dclk_name, &cstate->dclk);
3869 if (ret) {
3870 printf("%s: Failed to get dclk ret=%d\n", __func__, ret);
3871 return ret;
3872 }
3873 #endif
3874
3875 ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev);
3876 if (!ret) {
3877 ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll);
3878 if (ret)
3879 debug("%s: hdmi0_phy_pll may not define\n", __func__);
3880 ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll);
3881 if (ret)
3882 debug("%s: hdmi1_phy_pll may not define\n", __func__);
3883 } else {
3884 hdmi0_phy_pll.dev = NULL;
3885 hdmi1_phy_pll.dev = NULL;
3886 debug("%s: Faile to find display-subsystem node\n", __func__);
3887 }
3888
3889 if (vop2->version == VOP_VERSION_RK3528) {
3890 struct ofnode_phandle_args args;
3891
3892 ret = dev_read_phandle_with_args(cstate->dev, "assigned-clock-parents",
3893 "#clock-cells", 0, 0, &args);
3894 if (!ret) {
3895 ret = uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &hdmi0_phy_pll.dev);
3896 if (ret) {
3897 debug("warn: can't get clk device\n");
3898 return ret;
3899 }
3900 } else {
3901 debug("assigned-clock-parents's node not define\n");
3902 }
3903 }
3904
3905 if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) {
3906 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0)
3907 vop2_clk_set_parent(&cstate->dclk, &hdmi0_phy_pll);
3908 else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1)
3909 vop2_clk_set_parent(&cstate->dclk, &hdmi1_phy_pll);
3910
3911 /*
3912 * uboot clk driver won't set dclk parent's rate when use
3913 * hdmi phypll as dclk source.
3914 * So set dclk rate is meaningless. Set hdmi phypll rate
3915 * directly.
3916 */
3917 if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) {
3918 ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000);
3919 } else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) {
3920 ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000);
3921 } else {
3922 if (is_extend_pll(state, &hdmi_phy_pll.dev)) {
3923 ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000);
3924 } else {
3925 #ifndef CONFIG_SPL_BUILD
3926 ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate * 1000);
3927 #else
3928 if (vop2->version == VOP_VERSION_RK3528) {
3929 void *cru_base = (void *)RK3528_CRU_BASE;
3930
3931 /* dclk src switch to hdmiphy pll */
3932 writel((BIT(0) << 16) | BIT(0), cru_base + 0x450);
3933 rockchip_phy_set_pll(conn_state->connector->phy, dclk_rate * 1000);
3934 ret = dclk_rate * 1000;
3935 }
3936 #endif
3937 }
3938 }
3939 } else {
3940 if (is_extend_pll(state, &hdmi_phy_pll.dev))
3941 ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000);
3942 else
3943 ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate * 1000);
3944 }
3945
3946 if (IS_ERR_VALUE(ret)) {
3947 printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n",
3948 __func__, cstate->crtc_id, dclk_rate, ret);
3949 return ret;
3950 } else {
3951 dclk_div_factor = mode->clock / dclk_rate;
3952 if (vop2->version == VOP_VERSION_RK3528 &&
3953 conn_state->output_if & VOP_OUTPUT_IF_BT656)
3954 mode->crtc_clock = ret / 4 / 1000;
3955 else
3956 mode->crtc_clock = ret * dclk_div_factor / 1000;
3957 printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock);
3958 }
3959
3960 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
3961 RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false);
3962 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK,
3963 RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false);
3964
3965 if (cstate->mcu_timing.mcu_pix_total)
3966 vop3_mcu_mode_setup(state);
3967
3968 return 0;
3969 }
3970
vop2_setup_scale(struct vop2 * vop2,struct vop2_win_data * win,uint32_t src_w,uint32_t src_h,uint32_t dst_w,uint32_t dst_h)3971 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win,
3972 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
3973 uint32_t dst_h)
3974 {
3975 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
3976 uint16_t hscl_filter_mode, vscl_filter_mode;
3977 uint8_t xgt2 = 0, xgt4 = 0;
3978 uint8_t ygt2 = 0, ygt4 = 0;
3979 uint32_t xfac = 0, yfac = 0;
3980 u32 win_offset = win->reg_offset;
3981 bool xgt_en = false;
3982 bool xavg_en = false;
3983
3984 if (is_vop3(vop2)) {
3985 if (src_w >= (4 * dst_w)) {
3986 xgt4 = 1;
3987 src_w >>= 2;
3988 } else if (src_w >= (2 * dst_w)) {
3989 xgt2 = 1;
3990 src_w >>= 1;
3991 }
3992 }
3993
3994 if (src_h >= (4 * dst_h)) {
3995 ygt4 = 1;
3996 src_h >>= 2;
3997 } else if (src_h >= (2 * dst_h)) {
3998 ygt2 = 1;
3999 src_h >>= 1;
4000 }
4001
4002 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
4003 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
4004
4005 if (yrgb_hor_scl_mode == SCALE_UP)
4006 hscl_filter_mode = win->hsu_filter_mode;
4007 else
4008 hscl_filter_mode = win->hsd_filter_mode;
4009
4010 if (yrgb_ver_scl_mode == SCALE_UP)
4011 vscl_filter_mode = win->vsu_filter_mode;
4012 else
4013 vscl_filter_mode = win->vsd_filter_mode;
4014
4015 /*
4016 * RK3568 VOP Esmart/Smart dsp_w should be even pixel
4017 * at scale down mode
4018 */
4019 if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) {
4020 printf("win dst_w[%d] should align as 2 pixel\n", dst_w);
4021 dst_w += 1;
4022 }
4023
4024 if (is_vop3(vop2)) {
4025 xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true);
4026 yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false);
4027
4028 if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG)
4029 xavg_en = xgt2 || xgt4;
4030 else
4031 xgt_en = xgt2 || xgt4;
4032 } else {
4033 xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w);
4034 yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h);
4035 }
4036
4037 if (win->type == CLUSTER_LAYER) {
4038 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset,
4039 yfac << 16 | xfac);
4040
4041 if (is_vop3(vop2)) {
4042 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4043 EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false);
4044 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4045 EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false);
4046 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4047 XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
4048
4049 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4050 YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT,
4051 yrgb_hor_scl_mode, false);
4052 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4053 YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT,
4054 yrgb_ver_scl_mode, false);
4055 } else {
4056 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4057 YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT,
4058 yrgb_hor_scl_mode, false);
4059 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4060 YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT,
4061 yrgb_ver_scl_mode, false);
4062 }
4063
4064 if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) {
4065 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4066 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false);
4067 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4068 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false);
4069 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4070 AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false);
4071 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4072 AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false);
4073 } else {
4074 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4075 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false);
4076 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4077 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false);
4078 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4079 AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false);
4080 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset,
4081 AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false);
4082 }
4083 } else {
4084 vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset,
4085 yfac << 16 | xfac);
4086
4087 if (is_vop3(vop2)) {
4088 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4089 EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false);
4090 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4091 EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false);
4092 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4093 XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false);
4094 }
4095
4096 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4097 YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false);
4098 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4099 YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false);
4100
4101 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
4102 YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false);
4103 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
4104 YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false);
4105
4106 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
4107 YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT,
4108 hscl_filter_mode, false);
4109 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset,
4110 YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT,
4111 vscl_filter_mode, false);
4112 }
4113 }
4114
vop2_axi_config(struct vop2 * vop2,struct vop2_win_data * win)4115 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win)
4116 {
4117 u32 win_offset = win->reg_offset;
4118
4119 if (win->type == CLUSTER_LAYER) {
4120 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK,
4121 CLUSTER_AXI_ID_SHIFT, win->axi_id, false);
4122 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK,
4123 CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
4124 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK,
4125 CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
4126 } else {
4127 vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK,
4128 ESMART_AXI_ID_SHIFT, win->axi_id, false);
4129 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK,
4130 ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false);
4131 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK,
4132 ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false);
4133 }
4134 }
4135
vop2_win_dither_up(uint32_t format)4136 static bool vop2_win_dither_up(uint32_t format)
4137 {
4138 switch (format) {
4139 case ROCKCHIP_FMT_RGB565:
4140 return true;
4141 default:
4142 return false;
4143 }
4144 }
4145
vop2_set_cluster_win(struct display_state * state,struct vop2_win_data * win)4146 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win)
4147 {
4148 struct crtc_state *cstate = &state->crtc_state;
4149 struct connector_state *conn_state = &state->conn_state;
4150 struct drm_display_mode *mode = &conn_state->mode;
4151 struct vop2 *vop2 = cstate->private;
4152 int src_w = cstate->src_rect.w;
4153 int src_h = cstate->src_rect.h;
4154 int crtc_x = cstate->crtc_rect.x;
4155 int crtc_y = cstate->crtc_rect.y;
4156 int crtc_w = cstate->crtc_rect.w;
4157 int crtc_h = cstate->crtc_rect.h;
4158 int xvir = cstate->xvir;
4159 int y_mirror = 0;
4160 int csc_mode;
4161 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
4162 /* offset of the right window in splice mode */
4163 u32 splice_pixel_offset = 0;
4164 u32 splice_yrgb_offset = 0;
4165 u32 win_offset = win->reg_offset;
4166 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4167 bool dither_up;
4168
4169 if (win->splice_mode_right) {
4170 src_w = cstate->right_src_rect.w;
4171 src_h = cstate->right_src_rect.h;
4172 crtc_x = cstate->right_crtc_rect.x;
4173 crtc_y = cstate->right_crtc_rect.y;
4174 crtc_w = cstate->right_crtc_rect.w;
4175 crtc_h = cstate->right_crtc_rect.h;
4176 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
4177 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
4178 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4179 }
4180
4181 act_info = (src_h - 1) << 16;
4182 act_info |= (src_w - 1) & 0xffff;
4183
4184 dsp_info = (crtc_h - 1) << 16;
4185 dsp_info |= (crtc_w - 1) & 0xffff;
4186
4187 dsp_stx = crtc_x;
4188 dsp_sty = crtc_y;
4189 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
4190
4191 if (mode->flags & DRM_MODE_FLAG_YMIRROR)
4192 y_mirror = 1;
4193 else
4194 y_mirror = 0;
4195
4196 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
4197
4198 if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528 ||
4199 vop2->version == VOP_VERSION_RK3562)
4200 vop2_axi_config(vop2, win);
4201
4202 if (y_mirror)
4203 printf("WARN: y mirror is unsupported by cluster window\n");
4204
4205 /* rk3588 should set half_blocK_en to 1 in line and tile mode */
4206 if (vop2->version == VOP_VERSION_RK3588)
4207 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_AFBCD_CTRL + win_offset,
4208 EN_MASK, CLUSTER_AFBCD_HALF_BLOCK_SHIFT, 1, false);
4209
4210 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset,
4211 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
4212 false);
4213 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir);
4214 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset,
4215 cstate->dma_addr + splice_yrgb_offset);
4216
4217 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info);
4218 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info);
4219 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st);
4220
4221 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false);
4222
4223 csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
4224 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
4225 CLUSTER_RGB2YUV_EN_SHIFT,
4226 is_yuv_output(conn_state->bus_format), false);
4227 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK,
4228 CLUSTER_CSC_MODE_SHIFT, csc_mode, false);
4229
4230 dither_up = vop2_win_dither_up(cstate->format);
4231 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK,
4232 CLUSTER_DITHER_UP_EN_SHIFT, dither_up, false);
4233
4234 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false);
4235
4236 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4237 }
4238
vop2_set_smart_win(struct display_state * state,struct vop2_win_data * win)4239 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win)
4240 {
4241 struct crtc_state *cstate = &state->crtc_state;
4242 struct connector_state *conn_state = &state->conn_state;
4243 struct drm_display_mode *mode = &conn_state->mode;
4244 struct vop2 *vop2 = cstate->private;
4245 int src_w = cstate->src_rect.w;
4246 int src_h = cstate->src_rect.h;
4247 int crtc_x = cstate->crtc_rect.x;
4248 int crtc_y = cstate->crtc_rect.y;
4249 int crtc_w = cstate->crtc_rect.w;
4250 int crtc_h = cstate->crtc_rect.h;
4251 int xvir = cstate->xvir;
4252 int y_mirror = 0;
4253 int csc_mode;
4254 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty;
4255 /* offset of the right window in splice mode */
4256 u32 splice_pixel_offset = 0;
4257 u32 splice_yrgb_offset = 0;
4258 u32 win_offset = win->reg_offset;
4259 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4260 bool dither_up;
4261
4262 if (win->splice_mode_right) {
4263 src_w = cstate->right_src_rect.w;
4264 src_h = cstate->right_src_rect.h;
4265 crtc_x = cstate->right_crtc_rect.x;
4266 crtc_y = cstate->right_crtc_rect.y;
4267 crtc_w = cstate->right_crtc_rect.w;
4268 crtc_h = cstate->right_crtc_rect.h;
4269 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x;
4270 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3);
4271 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4272 }
4273
4274 /*
4275 * This is workaround solution for IC design:
4276 * esmart can't support scale down when actual_w % 16 == 1.
4277 */
4278 if (src_w > crtc_w && (src_w & 0xf) == 1) {
4279 printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w);
4280 src_w -= 1;
4281 }
4282
4283 act_info = (src_h - 1) << 16;
4284 act_info |= (src_w - 1) & 0xffff;
4285
4286 dsp_info = (crtc_h - 1) << 16;
4287 dsp_info |= (crtc_w - 1) & 0xffff;
4288
4289 dsp_stx = crtc_x;
4290 dsp_sty = crtc_y;
4291 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
4292
4293 if (mode->flags & DRM_MODE_FLAG_YMIRROR)
4294 y_mirror = 1;
4295 else
4296 y_mirror = 0;
4297
4298 if (is_vop3(vop2))
4299 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, ESMART_LB_SELECT_MASK,
4300 ESMART_LB_SELECT_SHIFT, win->scale_engine_num, false);
4301
4302 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h);
4303
4304 if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528 ||
4305 vop2->version == VOP_VERSION_RK3562)
4306 vop2_axi_config(vop2, win);
4307
4308 if (y_mirror)
4309 cstate->dma_addr += (src_h - 1) * xvir * 4;
4310 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK,
4311 YMIRROR_EN_SHIFT, y_mirror, false);
4312
4313 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset,
4314 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format,
4315 false);
4316 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir);
4317 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset,
4318 cstate->dma_addr + splice_yrgb_offset);
4319
4320 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset,
4321 act_info);
4322 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset,
4323 dsp_info);
4324 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st);
4325
4326 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
4327 WIN_EN_SHIFT, 1, false);
4328
4329 csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH);
4330 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK,
4331 RGB2YUV_EN_SHIFT,
4332 is_yuv_output(conn_state->bus_format), false);
4333 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK,
4334 CSC_MODE_SHIFT, csc_mode, false);
4335
4336 dither_up = vop2_win_dither_up(cstate->format);
4337 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK,
4338 REGION0_DITHER_UP_EN_SHIFT, dither_up, false);
4339
4340 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4341 }
4342
vop2_calc_display_rect_for_splice(struct display_state * state)4343 static void vop2_calc_display_rect_for_splice(struct display_state *state)
4344 {
4345 struct crtc_state *cstate = &state->crtc_state;
4346 struct connector_state *conn_state = &state->conn_state;
4347 struct drm_display_mode *mode = &conn_state->mode;
4348 struct display_rect *src_rect = &cstate->src_rect;
4349 struct display_rect *dst_rect = &cstate->crtc_rect;
4350 struct display_rect left_src, left_dst, right_src, right_dst;
4351 u16 half_hdisplay = mode->crtc_hdisplay >> 1;
4352 int left_src_w, left_dst_w, right_dst_w;
4353
4354 left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x;
4355 if (left_dst_w < 0)
4356 left_dst_w = 0;
4357 right_dst_w = dst_rect->w - left_dst_w;
4358
4359 if (!right_dst_w)
4360 left_src_w = src_rect->w;
4361 else
4362 left_src_w = src_rect->x + src_rect->w - src_rect->w / 2;
4363
4364 left_src.x = src_rect->x;
4365 left_src.w = left_src_w;
4366 left_dst.x = dst_rect->x;
4367 left_dst.w = left_dst_w;
4368 right_src.x = left_src.x + left_src.w;
4369 right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w;
4370 right_dst.x = dst_rect->x + left_dst_w - half_hdisplay;
4371 right_dst.w = right_dst_w;
4372
4373 left_src.y = src_rect->y;
4374 left_src.h = src_rect->h;
4375 left_dst.y = dst_rect->y;
4376 left_dst.h = dst_rect->h;
4377 right_src.y = src_rect->y;
4378 right_src.h = src_rect->h;
4379 right_dst.y = dst_rect->y;
4380 right_dst.h = dst_rect->h;
4381
4382 memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect));
4383 memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect));
4384 memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect));
4385 memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect));
4386 }
4387
rockchip_vop2_set_plane(struct display_state * state)4388 static int rockchip_vop2_set_plane(struct display_state *state)
4389 {
4390 struct crtc_state *cstate = &state->crtc_state;
4391 struct vop2 *vop2 = cstate->private;
4392 struct vop2_win_data *win_data;
4393 struct vop2_win_data *splice_win_data;
4394 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
4395 char plane_name[10] = {0};
4396
4397 if (cstate->crtc_rect.w > cstate->max_output.width) {
4398 printf("ERROR: output w[%d] exceeded max width[%d]\n",
4399 cstate->crtc_rect.w, cstate->max_output.width);
4400 return -EINVAL;
4401 }
4402
4403 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
4404 if (!win_data) {
4405 printf("invalid win id %d\n", primary_plane_id);
4406 return -ENODEV;
4407 }
4408
4409 /* ignore some plane register according vop3 esmart lb mode */
4410 if (vop3_ignore_plane(vop2, win_data))
4411 return -EACCES;
4412
4413 if (vop2->version == VOP_VERSION_RK3588) {
4414 if (vop2_power_domain_on(vop2, win_data->pd_id))
4415 printf("open vp%d plane pd fail\n", cstate->crtc_id);
4416 }
4417
4418 if (cstate->splice_mode) {
4419 if (win_data->splice_win_id) {
4420 splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id);
4421 splice_win_data->splice_mode_right = true;
4422
4423 if (vop2_power_domain_on(vop2, splice_win_data->pd_id))
4424 printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id);
4425
4426 vop2_calc_display_rect_for_splice(state);
4427 if (win_data->type == CLUSTER_LAYER)
4428 vop2_set_cluster_win(state, splice_win_data);
4429 else
4430 vop2_set_smart_win(state, splice_win_data);
4431 } else {
4432 printf("ERROR: splice mode is unsupported by plane %s\n",
4433 get_plane_name(primary_plane_id, plane_name));
4434 return -EINVAL;
4435 }
4436 }
4437
4438 if (win_data->type == CLUSTER_LAYER)
4439 vop2_set_cluster_win(state, win_data);
4440 else
4441 vop2_set_smart_win(state, win_data);
4442
4443 printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n",
4444 cstate->crtc_id, get_plane_name(primary_plane_id, plane_name),
4445 cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h,
4446 cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format,
4447 cstate->dma_addr);
4448
4449 return 0;
4450 }
4451
rockchip_vop2_prepare(struct display_state * state)4452 static int rockchip_vop2_prepare(struct display_state *state)
4453 {
4454 return 0;
4455 }
4456
vop2_dsc_cfg_done(struct display_state * state)4457 static void vop2_dsc_cfg_done(struct display_state *state)
4458 {
4459 struct connector_state *conn_state = &state->conn_state;
4460 struct crtc_state *cstate = &state->crtc_state;
4461 struct vop2 *vop2 = cstate->private;
4462 u8 dsc_id = cstate->dsc_id;
4463 u32 ctrl_regs_offset = (dsc_id * 0x30);
4464
4465 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
4466 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK,
4467 DSC_CFG_DONE_SHIFT, 1, false);
4468 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK,
4469 DSC_CFG_DONE_SHIFT, 1, false);
4470 } else {
4471 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK,
4472 DSC_CFG_DONE_SHIFT, 1, false);
4473 }
4474 }
4475
rockchip_vop2_enable(struct display_state * state)4476 static int rockchip_vop2_enable(struct display_state *state)
4477 {
4478 struct crtc_state *cstate = &state->crtc_state;
4479 struct vop2 *vop2 = cstate->private;
4480 u32 vp_offset = (cstate->crtc_id * 0x100);
4481 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4482
4483 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4484 STANDBY_EN_SHIFT, 0, false);
4485
4486 if (cstate->splice_mode)
4487 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4488
4489 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4490
4491 if (cstate->dsc_enable)
4492 vop2_dsc_cfg_done(state);
4493
4494 if (cstate->mcu_timing.mcu_pix_total)
4495 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK,
4496 MCU_HOLD_MODE_SHIFT, 0, false);
4497
4498 return 0;
4499 }
4500
rockchip_vop2_disable(struct display_state * state)4501 static int rockchip_vop2_disable(struct display_state *state)
4502 {
4503 struct crtc_state *cstate = &state->crtc_state;
4504 struct vop2 *vop2 = cstate->private;
4505 u32 vp_offset = (cstate->crtc_id * 0x100);
4506 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16);
4507
4508 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK,
4509 STANDBY_EN_SHIFT, 1, false);
4510
4511 if (cstate->splice_mode)
4512 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16);
4513
4514 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done);
4515
4516 return 0;
4517 }
4518
rockchip_vop2_get_cursor_plane(struct display_state * state,u32 plane_mask,int cursor_plane)4519 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane)
4520 {
4521 struct crtc_state *cstate = &state->crtc_state;
4522 struct vop2 *vop2 = cstate->private;
4523 int i = 0;
4524 int correct_cursor_plane = -1;
4525 int plane_type = -1;
4526
4527 if (cursor_plane < 0)
4528 return -1;
4529
4530 if (plane_mask & (1 << cursor_plane))
4531 return cursor_plane;
4532
4533 /* Get current cursor plane type */
4534 for (i = 0; i < vop2->data->nr_layers; i++) {
4535 if (vop2->data->plane_table[i].plane_id == cursor_plane) {
4536 plane_type = vop2->data->plane_table[i].plane_type;
4537 break;
4538 }
4539 }
4540
4541 /* Get the other same plane type plane id */
4542 for (i = 0; i < vop2->data->nr_layers; i++) {
4543 if (vop2->data->plane_table[i].plane_type == plane_type &&
4544 vop2->data->plane_table[i].plane_id != cursor_plane) {
4545 correct_cursor_plane = vop2->data->plane_table[i].plane_id;
4546 break;
4547 }
4548 }
4549
4550 /* To check whether the new correct_cursor_plane is attach to current vp */
4551 if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) {
4552 printf("error: faild to find correct plane as cursor plane\n");
4553 return -1;
4554 }
4555
4556 printf("vp%d adjust cursor plane from %d to %d\n",
4557 cstate->crtc_id, cursor_plane, correct_cursor_plane);
4558
4559 return correct_cursor_plane;
4560 }
4561
rockchip_vop2_fixup_dts(struct display_state * state,void * blob)4562 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob)
4563 {
4564 struct crtc_state *cstate = &state->crtc_state;
4565 struct vop2 *vop2 = cstate->private;
4566 ofnode vp_node;
4567 struct device_node *port_parent_node = cstate->ports_node;
4568 static bool vop_fix_dts;
4569 const char *path;
4570 u32 plane_mask = 0;
4571 int vp_id = 0;
4572 int cursor_plane_id = -1;
4573
4574 if (vop_fix_dts || vop2->version == VOP_VERSION_RK3528)
4575 return 0;
4576
4577 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) {
4578 path = vp_node.np->full_name;
4579 plane_mask = vop2->vp_plane_mask[vp_id].plane_mask;
4580
4581 if (cstate->crtc->assign_plane)
4582 continue;
4583 cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask,
4584 cstate->crtc->vps[vp_id].cursor_plane);
4585 printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n",
4586 vp_id, plane_mask,
4587 vop2->vp_plane_mask[vp_id].primary_plane_id,
4588 cursor_plane_id);
4589
4590 do_fixup_by_path_u32(blob, path, "rockchip,plane-mask",
4591 plane_mask, 1);
4592 do_fixup_by_path_u32(blob, path, "rockchip,primary-plane",
4593 vop2->vp_plane_mask[vp_id].primary_plane_id, 1);
4594 if (cursor_plane_id >= 0)
4595 do_fixup_by_path_u32(blob, path, "cursor-win-id",
4596 cursor_plane_id, 1);
4597 vp_id++;
4598 }
4599
4600 vop_fix_dts = true;
4601
4602 return 0;
4603 }
4604
rockchip_vop2_check(struct display_state * state)4605 static int rockchip_vop2_check(struct display_state *state)
4606 {
4607 struct crtc_state *cstate = &state->crtc_state;
4608 struct rockchip_crtc *crtc = cstate->crtc;
4609
4610 if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) {
4611 printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id);
4612 return -ENOTSUPP;
4613 }
4614
4615 if (cstate->splice_mode) {
4616 crtc->splice_mode = true;
4617 crtc->splice_crtc_id = cstate->splice_crtc_id;
4618 }
4619
4620 return 0;
4621 }
4622
rockchip_vop2_mode_valid(struct display_state * state)4623 static int rockchip_vop2_mode_valid(struct display_state *state)
4624 {
4625 struct connector_state *conn_state = &state->conn_state;
4626 struct crtc_state *cstate = &state->crtc_state;
4627 struct drm_display_mode *mode = &conn_state->mode;
4628 struct videomode vm;
4629
4630 drm_display_mode_to_videomode(mode, &vm);
4631
4632 if (vm.hactive < 32 || vm.vactive < 32 ||
4633 (vm.hfront_porch * vm.hsync_len * vm.hback_porch *
4634 vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) {
4635 printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id);
4636 return -EINVAL;
4637 }
4638
4639 return 0;
4640 }
4641
rockchip_vop2_mode_fixup(struct display_state * state)4642 static int rockchip_vop2_mode_fixup(struct display_state *state)
4643 {
4644 struct connector_state *conn_state = &state->conn_state;
4645 struct drm_display_mode *mode = &conn_state->mode;
4646 struct crtc_state *cstate = &state->crtc_state;
4647 struct vop2 *vop2 = cstate->private;
4648
4649 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE);
4650
4651 if (mode->flags & DRM_MODE_FLAG_DBLCLK || conn_state->output_if & VOP_OUTPUT_IF_BT656)
4652 mode->crtc_clock *= 2;
4653
4654 /*
4655 * For RK3528, the path of CVBS output is like:
4656 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC
4657 * The vop2 dclk should be four times crtc_clock for CVBS sampling
4658 * clock needs.
4659 */
4660 if (vop2->version == VOP_VERSION_RK3528 && conn_state->output_if & VOP_OUTPUT_IF_BT656)
4661 mode->crtc_clock *= 4;
4662
4663 if (cstate->mcu_timing.mcu_pix_total) {
4664 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_S888)
4665 /*
4666 * For serial output_mode rgb3x8, one pixel need 3 cycles.
4667 * So dclk should be three times mode clock.
4668 */
4669 mode->crtc_clock *= 3;
4670 else if (conn_state->output_mode == ROCKCHIP_OUT_MODE_S888_DUMMY)
4671 /*
4672 * For serial output_mode argb4x8, one pixel need 4 cycles.
4673 * So dclk should be four times mode clock.
4674 */
4675 mode->crtc_clock *= 4;
4676 }
4677
4678 if (conn_state->secondary) {
4679 mode->crtc_clock *= 2;
4680 mode->crtc_hdisplay *= 2;
4681 mode->crtc_hsync_start *= 2;
4682 mode->crtc_hsync_end *= 2;
4683 mode->crtc_htotal *= 2;
4684 }
4685
4686 return 0;
4687 }
4688
4689 #define FRAC_16_16(mult, div) (((mult) << 16) / (div))
4690
rockchip_vop2_plane_check(struct display_state * state)4691 static int rockchip_vop2_plane_check(struct display_state *state)
4692 {
4693 struct crtc_state *cstate = &state->crtc_state;
4694 struct vop2 *vop2 = cstate->private;
4695 struct display_rect *src = &cstate->src_rect;
4696 struct display_rect *dst = &cstate->crtc_rect;
4697 struct vop2_win_data *win_data;
4698 int min_scale, max_scale;
4699 int hscale, vscale;
4700 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id;
4701
4702 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id);
4703 if (!win_data) {
4704 printf("ERROR: invalid win id %d\n", primary_plane_id);
4705 return -ENODEV;
4706 }
4707
4708 min_scale = FRAC_16_16(1, win_data->max_downscale_factor);
4709 max_scale = FRAC_16_16(win_data->max_upscale_factor, 1);
4710
4711 hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale);
4712 vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale);
4713 if (hscale < 0 || vscale < 0) {
4714 printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name);
4715 return -ERANGE;
4716 }
4717
4718 return 0;
4719 }
4720
rockchip_vop2_apply_soft_te(struct display_state * state)4721 static int rockchip_vop2_apply_soft_te(struct display_state *state)
4722 {
4723 __maybe_unused struct connector_state *conn_state = &state->conn_state;
4724 struct crtc_state *cstate = &state->crtc_state;
4725 struct vop2 *vop2 = cstate->private;
4726 u32 vp_offset = (cstate->crtc_id * 0x100);
4727 int val = 0;
4728 int ret = 0;
4729
4730 ret = readl_poll_timeout(vop2->regs + RK3568_VP0_MIPI_CTRL + vp_offset, val,
4731 (val >> EDPI_WMS_FS) & 0x1, 50 * 1000);
4732 if (!ret) {
4733 #ifndef CONFIG_SPL_BUILD
4734 ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val,
4735 !val, 50 * 1000);
4736 if (!ret) {
4737 ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val,
4738 val, 50 * 1000);
4739 if (!ret) {
4740 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset,
4741 EN_MASK, EDPI_WMS_FS, 1, false);
4742 } else {
4743 printf("ERROR: vp%d wait for active TE signal timeout\n",
4744 cstate->crtc_id);
4745 return ret;
4746 }
4747 } else {
4748 printf("ERROR: vp%d TE signal maybe always high\n", cstate->crtc_id);
4749 return ret;
4750 }
4751 #endif
4752 } else {
4753 printf("ERROR: vp%d wait vop2 frame start timeout in hold mode\n", cstate->crtc_id);
4754 return ret;
4755 }
4756
4757 return 0;
4758 }
4759
rockchip_vop2_regs_dump(struct display_state * state)4760 static int rockchip_vop2_regs_dump(struct display_state *state)
4761 {
4762 struct crtc_state *cstate = &state->crtc_state;
4763 struct vop2 *vop2 = cstate->private;
4764 const struct vop2_data *vop2_data = vop2->data;
4765 const struct vop2_dump_regs *regs = vop2_data->dump_regs;
4766 u32 n, i, j;
4767 u32 base;
4768
4769 if (!cstate->crtc->active)
4770 return -EINVAL;
4771
4772 n = vop2_data->dump_regs_size;
4773 for (i = 0; i < n; i++) {
4774 base = regs[i].offset;
4775 printf("\n%s:\n", regs[i].name);
4776 for (j = 0; j < 68;) {
4777 printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4,
4778 vop2_readl(vop2, base + (4 * j)),
4779 vop2_readl(vop2, base + (4 * (j + 1))),
4780 vop2_readl(vop2, base + (4 * (j + 2))),
4781 vop2_readl(vop2, base + (4 * (j + 3))));
4782 j += 4;
4783 }
4784 }
4785
4786 return 0;
4787 }
4788
rockchip_vop2_active_regs_dump(struct display_state * state)4789 static int rockchip_vop2_active_regs_dump(struct display_state *state)
4790 {
4791 struct crtc_state *cstate = &state->crtc_state;
4792 struct vop2 *vop2 = cstate->private;
4793 const struct vop2_data *vop2_data = vop2->data;
4794 const struct vop2_dump_regs *regs = vop2_data->dump_regs;
4795 u32 n, i, j;
4796 u32 base;
4797 bool enable_state;
4798
4799 if (!cstate->crtc->active)
4800 return -EINVAL;
4801
4802 n = vop2_data->dump_regs_size;
4803 for (i = 0; i < n; i++) {
4804 if (regs[i].state_mask) {
4805 enable_state = (vop2_readl(vop2, regs[i].state_base) >> regs[i].state_shift) &
4806 regs[i].state_mask;
4807 if (enable_state != regs[i].enable_state)
4808 continue;
4809 }
4810
4811 base = regs[i].offset;
4812 printf("\n%s:\n", regs[i].name);
4813 for (j = 0; j < 68;) {
4814 printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4,
4815 vop2_readl(vop2, base + (4 * j)),
4816 vop2_readl(vop2, base + (4 * (j + 1))),
4817 vop2_readl(vop2, base + (4 * (j + 2))),
4818 vop2_readl(vop2, base + (4 * (j + 3))));
4819 j += 4;
4820 }
4821 }
4822
4823 return 0;
4824 }
4825
4826 static struct vop2_dump_regs rk3528_dump_regs[] = {
4827 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
4828 { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 },
4829 { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
4830 { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
4831 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
4832 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
4833 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
4834 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
4835 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
4836 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 },
4837 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 },
4838 { RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
4839 { RK3528_ACM_CTRL, "ACM", RK3528_ACM_CTRL, 0x1, 0, 1},
4840 };
4841
4842 static u8 rk3528_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
4843 ROCKCHIP_VOP2_ESMART0,
4844 ROCKCHIP_VOP2_ESMART1,
4845 ROCKCHIP_VOP2_ESMART2,
4846 ROCKCHIP_VOP2_ESMART3,
4847 };
4848
4849 static struct vop2_plane_table rk3528_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
4850 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
4851 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
4852 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
4853 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
4854 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
4855 };
4856
4857 static struct vop2_vp_plane_mask rk3528_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
4858 { /* one display policy for hdmi */
4859 {/* main display */
4860 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
4861 .attached_layers_nr = 4,
4862 .attached_layers = {
4863 ROCKCHIP_VOP2_CLUSTER0,
4864 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART2
4865 },
4866 },
4867 {/* second display */},
4868 {/* third display */},
4869 {/* fourth display */},
4870 },
4871
4872 { /* two display policy */
4873 {/* main display */
4874 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
4875 .attached_layers_nr = 3,
4876 .attached_layers = {
4877 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1
4878 },
4879 },
4880
4881 {/* second display */
4882 .primary_plane_id = ROCKCHIP_VOP2_ESMART3,
4883 .attached_layers_nr = 2,
4884 .attached_layers = {
4885 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
4886 },
4887 },
4888 {/* third display */},
4889 {/* fourth display */},
4890 },
4891
4892 { /* one display policy for cvbs */
4893 {/* main display */
4894 .primary_plane_id = ROCKCHIP_VOP2_ESMART3,
4895 .attached_layers_nr = 2,
4896 .attached_layers = {
4897 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
4898 },
4899 },
4900 {/* second display */},
4901 {/* third display */},
4902 {/* fourth display */},
4903 },
4904
4905 {/* reserved */},
4906 };
4907
4908 static struct vop2_win_data rk3528_win_data[5] = {
4909 {
4910 .name = "Esmart0",
4911 .phys_id = ROCKCHIP_VOP2_ESMART0,
4912 .type = ESMART_LAYER,
4913 .win_sel_port_offset = 8,
4914 .layer_sel_win_id = { 1, 0xff, 0xff, 0xff },
4915 .reg_offset = 0,
4916 .axi_id = 0,
4917 .axi_yrgb_id = 0x06,
4918 .axi_uv_id = 0x07,
4919 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
4920 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4921 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
4922 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4923 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
4924 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */
4925 .max_upscale_factor = 8,
4926 .max_downscale_factor = 8,
4927 },
4928
4929 {
4930 .name = "Esmart1",
4931 .phys_id = ROCKCHIP_VOP2_ESMART1,
4932 .type = ESMART_LAYER,
4933 .win_sel_port_offset = 10,
4934 .layer_sel_win_id = { 2, 0xff, 0xff, 0xff },
4935 .reg_offset = 0x200,
4936 .axi_id = 0,
4937 .axi_yrgb_id = 0x08,
4938 .axi_uv_id = 0x09,
4939 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
4940 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4941 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
4942 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4943 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
4944 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */
4945 .max_upscale_factor = 8,
4946 .max_downscale_factor = 8,
4947 },
4948
4949 {
4950 .name = "Esmart2",
4951 .phys_id = ROCKCHIP_VOP2_ESMART2,
4952 .type = ESMART_LAYER,
4953 .win_sel_port_offset = 12,
4954 .layer_sel_win_id = { 3, 0, 0xff, 0xff },
4955 .reg_offset = 0x400,
4956 .axi_id = 0,
4957 .axi_yrgb_id = 0x0a,
4958 .axi_uv_id = 0x0b,
4959 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
4960 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4961 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
4962 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4963 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
4964 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */
4965 .max_upscale_factor = 8,
4966 .max_downscale_factor = 8,
4967 },
4968
4969 {
4970 .name = "Esmart3",
4971 .phys_id = ROCKCHIP_VOP2_ESMART3,
4972 .type = ESMART_LAYER,
4973 .win_sel_port_offset = 14,
4974 .layer_sel_win_id = { 0xff, 1, 0xff, 0xff },
4975 .reg_offset = 0x600,
4976 .axi_id = 0,
4977 .axi_yrgb_id = 0x0c,
4978 .axi_uv_id = 0x0d,
4979 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
4980 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4981 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
4982 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
4983 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
4984 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */
4985 .max_upscale_factor = 8,
4986 .max_downscale_factor = 8,
4987 },
4988
4989 {
4990 .name = "Cluster0",
4991 .phys_id = ROCKCHIP_VOP2_CLUSTER0,
4992 .type = CLUSTER_LAYER,
4993 .win_sel_port_offset = 0,
4994 .layer_sel_win_id = { 0, 0xff, 0xff, 0xff },
4995 .reg_offset = 0,
4996 .axi_id = 0,
4997 .axi_yrgb_id = 0x02,
4998 .axi_uv_id = 0x03,
4999 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5000 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5001 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5002 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5003 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
5004 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */
5005 .max_upscale_factor = 8,
5006 .max_downscale_factor = 8,
5007 },
5008 };
5009
5010 static struct vop2_vp_data rk3528_vp_data[2] = {
5011 {
5012 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_POST_ACM |
5013 VOP_FEATURE_POST_CSC,
5014 .max_output = {4096, 4096},
5015 .layer_mix_dly = 6,
5016 .hdr_mix_dly = 2,
5017 .win_dly = 8,
5018 },
5019 {
5020 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
5021 .max_output = {1920, 1080},
5022 .layer_mix_dly = 2,
5023 .hdr_mix_dly = 0,
5024 .win_dly = 8,
5025 },
5026 };
5027
5028 const struct vop2_data rk3528_vop = {
5029 .version = VOP_VERSION_RK3528,
5030 .nr_vps = 2,
5031 .vp_data = rk3528_vp_data,
5032 .win_data = rk3528_win_data,
5033 .plane_mask = rk3528_vp_plane_mask[0],
5034 .plane_table = rk3528_plane_table,
5035 .vp_primary_plane_order = rk3528_vp_primary_plane_order,
5036 .nr_layers = 5,
5037 .nr_mixers = 3,
5038 .nr_gammas = 2,
5039 .esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE,
5040 .dump_regs = rk3528_dump_regs,
5041 .dump_regs_size = ARRAY_SIZE(rk3528_dump_regs),
5042 };
5043
5044 static struct vop2_dump_regs rk3562_dump_regs[] = {
5045 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
5046 { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 },
5047 { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
5048 { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
5049 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
5050 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
5051 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
5052 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
5053 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 },
5054 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 },
5055 };
5056
5057 static u8 rk3562_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
5058 ROCKCHIP_VOP2_ESMART0,
5059 ROCKCHIP_VOP2_ESMART1,
5060 ROCKCHIP_VOP2_ESMART2,
5061 ROCKCHIP_VOP2_ESMART3,
5062 };
5063
5064 static struct vop2_plane_table rk3562_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
5065 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
5066 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
5067 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
5068 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
5069 };
5070
5071 static struct vop2_vp_plane_mask rk3562_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
5072 { /* one display policy for hdmi */
5073 {/* main display */
5074 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5075 .attached_layers_nr = 4,
5076 .attached_layers = {
5077 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1,
5078 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
5079 },
5080 },
5081 {/* second display */},
5082 {/* third display */},
5083 {/* fourth display */},
5084 },
5085
5086 { /* two display policy */
5087 {/* main display */
5088 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5089 .attached_layers_nr = 2,
5090 .attached_layers = {
5091 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1
5092 },
5093 },
5094
5095 {/* second display */
5096 .primary_plane_id = ROCKCHIP_VOP2_ESMART2,
5097 .attached_layers_nr = 2,
5098 .attached_layers = {
5099 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3
5100 },
5101 },
5102 {/* third display */},
5103 {/* fourth display */},
5104 },
5105
5106 {/* reserved */},
5107 };
5108
5109 static struct vop2_win_data rk3562_win_data[4] = {
5110 {
5111 .name = "Esmart0",
5112 .phys_id = ROCKCHIP_VOP2_ESMART0,
5113 .type = ESMART_LAYER,
5114 .win_sel_port_offset = 8,
5115 .layer_sel_win_id = { 0, 0, 0xff, 0xff },
5116 .reg_offset = 0,
5117 .axi_id = 0,
5118 .axi_yrgb_id = 0x02,
5119 .axi_uv_id = 0x03,
5120 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5121 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5122 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5123 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5124 .max_upscale_factor = 8,
5125 .max_downscale_factor = 8,
5126 },
5127
5128 {
5129 .name = "Esmart1",
5130 .phys_id = ROCKCHIP_VOP2_ESMART1,
5131 .type = ESMART_LAYER,
5132 .win_sel_port_offset = 10,
5133 .layer_sel_win_id = { 1, 1, 0xff, 0xff },
5134 .reg_offset = 0x200,
5135 .axi_id = 0,
5136 .axi_yrgb_id = 0x04,
5137 .axi_uv_id = 0x05,
5138 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5139 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5140 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5141 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5142 .max_upscale_factor = 8,
5143 .max_downscale_factor = 8,
5144 },
5145
5146 {
5147 .name = "Esmart2",
5148 .phys_id = ROCKCHIP_VOP2_ESMART2,
5149 .type = ESMART_LAYER,
5150 .win_sel_port_offset = 12,
5151 .layer_sel_win_id = { 2, 2, 0xff, 0xff },
5152 .reg_offset = 0x400,
5153 .axi_id = 0,
5154 .axi_yrgb_id = 0x06,
5155 .axi_uv_id = 0x07,
5156 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5157 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5158 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5159 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5160 .max_upscale_factor = 8,
5161 .max_downscale_factor = 8,
5162 },
5163
5164 {
5165 .name = "Esmart3",
5166 .phys_id = ROCKCHIP_VOP2_ESMART3,
5167 .type = ESMART_LAYER,
5168 .win_sel_port_offset = 14,
5169 .layer_sel_win_id = { 3, 3, 0xff, 0xff },
5170 .reg_offset = 0x600,
5171 .axi_id = 0,
5172 .axi_yrgb_id = 0x08,
5173 .axi_uv_id = 0x0d,
5174 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5175 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5176 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5177 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5178 .max_upscale_factor = 8,
5179 .max_downscale_factor = 8,
5180 },
5181 };
5182
5183 static struct vop2_vp_data rk3562_vp_data[2] = {
5184 {
5185 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
5186 .max_output = {2048, 4096},
5187 .win_dly = 8,
5188 .layer_mix_dly = 8,
5189 },
5190 {
5191 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN,
5192 .max_output = {2048, 1080},
5193 .win_dly = 8,
5194 .layer_mix_dly = 8,
5195 },
5196 };
5197
5198 const struct vop2_data rk3562_vop = {
5199 .version = VOP_VERSION_RK3562,
5200 .nr_vps = 2,
5201 .vp_data = rk3562_vp_data,
5202 .win_data = rk3562_win_data,
5203 .plane_mask = rk3562_vp_plane_mask[0],
5204 .plane_table = rk3562_plane_table,
5205 .vp_primary_plane_order = rk3562_vp_primary_plane_order,
5206 .nr_layers = 4,
5207 .nr_mixers = 3,
5208 .nr_gammas = 2,
5209 .esmart_lb_mode = VOP3_ESMART_2K_2K_2K_2K_MODE,
5210 .dump_regs = rk3562_dump_regs,
5211 .dump_regs_size = ARRAY_SIZE(rk3562_dump_regs),
5212 };
5213
5214 static struct vop2_dump_regs rk3568_dump_regs[] = {
5215 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
5216 { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 },
5217 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
5218 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
5219 { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 },
5220 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
5221 { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 },
5222 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
5223 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
5224 { RK3568_SMART0_CTRL0, "Smart0", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 },
5225 { RK3568_SMART1_CTRL0, "Smart1", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 },
5226 { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
5227 };
5228
5229 static u8 rk3568_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
5230 ROCKCHIP_VOP2_SMART0,
5231 ROCKCHIP_VOP2_SMART1,
5232 ROCKCHIP_VOP2_ESMART0,
5233 ROCKCHIP_VOP2_ESMART1,
5234 };
5235
5236 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
5237 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
5238 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
5239 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
5240 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
5241 {ROCKCHIP_VOP2_SMART0, SMART_LAYER},
5242 {ROCKCHIP_VOP2_SMART0, SMART_LAYER},
5243 };
5244
5245 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
5246 { /* one display policy */
5247 {/* main display */
5248 .primary_plane_id = ROCKCHIP_VOP2_SMART0,
5249 .attached_layers_nr = 6,
5250 .attached_layers = {
5251 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0,
5252 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
5253 },
5254 },
5255 {/* second display */},
5256 {/* third display */},
5257 {/* fourth display */},
5258 },
5259
5260 { /* two display policy */
5261 {/* main display */
5262 .primary_plane_id = ROCKCHIP_VOP2_SMART0,
5263 .attached_layers_nr = 3,
5264 .attached_layers = {
5265 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
5266 },
5267 },
5268
5269 {/* second display */
5270 .primary_plane_id = ROCKCHIP_VOP2_SMART1,
5271 .attached_layers_nr = 3,
5272 .attached_layers = {
5273 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1
5274 },
5275 },
5276 {/* third display */},
5277 {/* fourth display */},
5278 },
5279
5280 { /* three display policy */
5281 {/* main display */
5282 .primary_plane_id = ROCKCHIP_VOP2_SMART0,
5283 .attached_layers_nr = 3,
5284 .attached_layers = {
5285 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0
5286 },
5287 },
5288
5289 {/* second display */
5290 .primary_plane_id = ROCKCHIP_VOP2_SMART1,
5291 .attached_layers_nr = 2,
5292 .attached_layers = {
5293 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1
5294 },
5295 },
5296
5297 {/* third display */
5298 .primary_plane_id = ROCKCHIP_VOP2_ESMART1,
5299 .attached_layers_nr = 1,
5300 .attached_layers = { ROCKCHIP_VOP2_ESMART1 },
5301 },
5302
5303 {/* fourth display */},
5304 },
5305
5306 {/* reserved for four display policy */},
5307 };
5308
5309 static struct vop2_win_data rk3568_win_data[6] = {
5310 {
5311 .name = "Cluster0",
5312 .phys_id = ROCKCHIP_VOP2_CLUSTER0,
5313 .type = CLUSTER_LAYER,
5314 .win_sel_port_offset = 0,
5315 .layer_sel_win_id = { 0, 0, 0, 0xff },
5316 .reg_offset = 0,
5317 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5318 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5319 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5320 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5321 .max_upscale_factor = 4,
5322 .max_downscale_factor = 4,
5323 },
5324
5325 {
5326 .name = "Cluster1",
5327 .phys_id = ROCKCHIP_VOP2_CLUSTER1,
5328 .type = CLUSTER_LAYER,
5329 .win_sel_port_offset = 1,
5330 .layer_sel_win_id = { 1, 1, 1, 0xff },
5331 .reg_offset = 0x200,
5332 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5333 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5334 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5335 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5336 .max_upscale_factor = 4,
5337 .max_downscale_factor = 4,
5338 },
5339
5340 {
5341 .name = "Esmart0",
5342 .phys_id = ROCKCHIP_VOP2_ESMART0,
5343 .type = ESMART_LAYER,
5344 .win_sel_port_offset = 4,
5345 .layer_sel_win_id = { 2, 2, 2, 0xff },
5346 .reg_offset = 0,
5347 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5348 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5349 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5350 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5351 .max_upscale_factor = 8,
5352 .max_downscale_factor = 8,
5353 },
5354
5355 {
5356 .name = "Esmart1",
5357 .phys_id = ROCKCHIP_VOP2_ESMART1,
5358 .type = ESMART_LAYER,
5359 .win_sel_port_offset = 5,
5360 .layer_sel_win_id = { 6, 6, 6, 0xff },
5361 .reg_offset = 0x200,
5362 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5363 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5364 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5365 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5366 .max_upscale_factor = 8,
5367 .max_downscale_factor = 8,
5368 },
5369
5370 {
5371 .name = "Smart0",
5372 .phys_id = ROCKCHIP_VOP2_SMART0,
5373 .type = SMART_LAYER,
5374 .win_sel_port_offset = 6,
5375 .layer_sel_win_id = { 3, 3, 3, 0xff },
5376 .reg_offset = 0x400,
5377 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5378 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5379 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5380 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5381 .max_upscale_factor = 8,
5382 .max_downscale_factor = 8,
5383 },
5384
5385 {
5386 .name = "Smart1",
5387 .phys_id = ROCKCHIP_VOP2_SMART1,
5388 .type = SMART_LAYER,
5389 .win_sel_port_offset = 7,
5390 .layer_sel_win_id = { 7, 7, 7, 0xff },
5391 .reg_offset = 0x600,
5392 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5393 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5394 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5395 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5396 .max_upscale_factor = 8,
5397 .max_downscale_factor = 8,
5398 },
5399 };
5400
5401 static struct vop2_vp_data rk3568_vp_data[3] = {
5402 {
5403 .feature = VOP_FEATURE_OUTPUT_10BIT,
5404 .pre_scan_max_dly = 42,
5405 .max_output = {4096, 2304},
5406 },
5407 {
5408 .feature = 0,
5409 .pre_scan_max_dly = 40,
5410 .max_output = {2048, 1536},
5411 },
5412 {
5413 .feature = 0,
5414 .pre_scan_max_dly = 40,
5415 .max_output = {1920, 1080},
5416 },
5417 };
5418
5419 const struct vop2_data rk3568_vop = {
5420 .version = VOP_VERSION_RK3568,
5421 .nr_vps = 3,
5422 .vp_data = rk3568_vp_data,
5423 .win_data = rk3568_win_data,
5424 .plane_mask = rk356x_vp_plane_mask[0],
5425 .plane_table = rk356x_plane_table,
5426 .vp_primary_plane_order = rk3568_vp_primary_plane_order,
5427 .nr_layers = 6,
5428 .nr_mixers = 5,
5429 .nr_gammas = 1,
5430 .dump_regs = rk3568_dump_regs,
5431 .dump_regs_size = ARRAY_SIZE(rk3568_dump_regs),
5432 };
5433
5434 static u8 rk3588_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = {
5435 ROCKCHIP_VOP2_ESMART0,
5436 ROCKCHIP_VOP2_ESMART1,
5437 ROCKCHIP_VOP2_ESMART2,
5438 ROCKCHIP_VOP2_ESMART3,
5439 ROCKCHIP_VOP2_CLUSTER0,
5440 ROCKCHIP_VOP2_CLUSTER1,
5441 ROCKCHIP_VOP2_CLUSTER2,
5442 ROCKCHIP_VOP2_CLUSTER3,
5443 };
5444
5445 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = {
5446 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER},
5447 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER},
5448 {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER},
5449 {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER},
5450 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER},
5451 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER},
5452 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER},
5453 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER},
5454 };
5455
5456 static struct vop2_dump_regs rk3588_dump_regs[] = {
5457 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 },
5458 { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 },
5459 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 },
5460 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 },
5461 { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 },
5462 { RK3588_VP3_DSP_CTRL, "VP3", RK3588_VP3_DSP_CTRL, 0x1, 31, 0 },
5463 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 },
5464 { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 },
5465 { RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2", RK3588_CLUSTER2_WIN0_CTRL0, 0x1, 0, 1 },
5466 { RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3", RK3588_CLUSTER3_WIN0_CTRL0, 0x1, 0, 1 },
5467 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 },
5468 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 },
5469 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 },
5470 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 },
5471 { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 },
5472 };
5473
5474 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = {
5475 { /* one display policy */
5476 {/* main display */
5477 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5478 .attached_layers_nr = 8,
5479 .attached_layers = {
5480 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2,
5481 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3,
5482 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3
5483 },
5484 },
5485 {/* second display */},
5486 {/* third display */},
5487 {/* fourth display */},
5488 },
5489
5490 { /* two display policy */
5491 {/* main display */
5492 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5493 .attached_layers_nr = 4,
5494 .attached_layers = {
5495 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0,
5496 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1
5497 },
5498 },
5499
5500 {/* second display */
5501 .primary_plane_id = ROCKCHIP_VOP2_ESMART2,
5502 .attached_layers_nr = 4,
5503 .attached_layers = {
5504 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2,
5505 ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3
5506 },
5507 },
5508 {/* third display */},
5509 {/* fourth display */},
5510 },
5511
5512 { /* three display policy */
5513 {/* main display */
5514 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5515 .attached_layers_nr = 3,
5516 .attached_layers = {
5517 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0
5518 },
5519 },
5520
5521 {/* second display */
5522 .primary_plane_id = ROCKCHIP_VOP2_ESMART1,
5523 .attached_layers_nr = 3,
5524 .attached_layers = {
5525 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1
5526 },
5527 },
5528
5529 {/* third display */
5530 .primary_plane_id = ROCKCHIP_VOP2_ESMART2,
5531 .attached_layers_nr = 2,
5532 .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 },
5533 },
5534
5535 {/* fourth display */},
5536 },
5537
5538 { /* four display policy */
5539 {/* main display */
5540 .primary_plane_id = ROCKCHIP_VOP2_ESMART0,
5541 .attached_layers_nr = 2,
5542 .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 },
5543 },
5544
5545 {/* second display */
5546 .primary_plane_id = ROCKCHIP_VOP2_ESMART1,
5547 .attached_layers_nr = 2,
5548 .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 },
5549 },
5550
5551 {/* third display */
5552 .primary_plane_id = ROCKCHIP_VOP2_ESMART2,
5553 .attached_layers_nr = 2,
5554 .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 },
5555 },
5556
5557 {/* fourth display */
5558 .primary_plane_id = ROCKCHIP_VOP2_ESMART3,
5559 .attached_layers_nr = 2,
5560 .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 },
5561 },
5562 },
5563
5564 };
5565
5566 static struct vop2_win_data rk3588_win_data[8] = {
5567 {
5568 .name = "Cluster0",
5569 .phys_id = ROCKCHIP_VOP2_CLUSTER0,
5570 .splice_win_id = ROCKCHIP_VOP2_CLUSTER1,
5571 .type = CLUSTER_LAYER,
5572 .win_sel_port_offset = 0,
5573 .layer_sel_win_id = { 0, 0, 0, 0 },
5574 .reg_offset = 0,
5575 .axi_id = 0,
5576 .axi_yrgb_id = 2,
5577 .axi_uv_id = 3,
5578 .pd_id = VOP2_PD_CLUSTER0,
5579 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5580 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5581 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5582 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5583 .max_upscale_factor = 4,
5584 .max_downscale_factor = 4,
5585 },
5586
5587 {
5588 .name = "Cluster1",
5589 .phys_id = ROCKCHIP_VOP2_CLUSTER1,
5590 .type = CLUSTER_LAYER,
5591 .win_sel_port_offset = 1,
5592 .layer_sel_win_id = { 1, 1, 1, 1 },
5593 .reg_offset = 0x200,
5594 .axi_id = 0,
5595 .axi_yrgb_id = 6,
5596 .axi_uv_id = 7,
5597 .pd_id = VOP2_PD_CLUSTER1,
5598 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5599 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5600 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5601 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5602 .max_upscale_factor = 4,
5603 .max_downscale_factor = 4,
5604 },
5605
5606 {
5607 .name = "Cluster2",
5608 .phys_id = ROCKCHIP_VOP2_CLUSTER2,
5609 .splice_win_id = ROCKCHIP_VOP2_CLUSTER3,
5610 .type = CLUSTER_LAYER,
5611 .win_sel_port_offset = 2,
5612 .layer_sel_win_id = { 4, 4, 4, 4 },
5613 .reg_offset = 0x400,
5614 .axi_id = 1,
5615 .axi_yrgb_id = 2,
5616 .axi_uv_id = 3,
5617 .pd_id = VOP2_PD_CLUSTER2,
5618 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5619 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5620 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5621 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5622 .max_upscale_factor = 4,
5623 .max_downscale_factor = 4,
5624 },
5625
5626 {
5627 .name = "Cluster3",
5628 .phys_id = ROCKCHIP_VOP2_CLUSTER3,
5629 .type = CLUSTER_LAYER,
5630 .win_sel_port_offset = 3,
5631 .layer_sel_win_id = { 5, 5, 5, 5 },
5632 .reg_offset = 0x600,
5633 .axi_id = 1,
5634 .axi_yrgb_id = 6,
5635 .axi_uv_id = 7,
5636 .pd_id = VOP2_PD_CLUSTER3,
5637 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5638 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5639 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5640 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5641 .max_upscale_factor = 4,
5642 .max_downscale_factor = 4,
5643 },
5644
5645 {
5646 .name = "Esmart0",
5647 .phys_id = ROCKCHIP_VOP2_ESMART0,
5648 .splice_win_id = ROCKCHIP_VOP2_ESMART1,
5649 .type = ESMART_LAYER,
5650 .win_sel_port_offset = 4,
5651 .layer_sel_win_id = { 2, 2, 2, 2 },
5652 .reg_offset = 0,
5653 .axi_id = 0,
5654 .axi_yrgb_id = 0x0a,
5655 .axi_uv_id = 0x0b,
5656 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5657 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5658 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5659 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5660 .max_upscale_factor = 8,
5661 .max_downscale_factor = 8,
5662 },
5663
5664 {
5665 .name = "Esmart1",
5666 .phys_id = ROCKCHIP_VOP2_ESMART1,
5667 .type = ESMART_LAYER,
5668 .win_sel_port_offset = 5,
5669 .layer_sel_win_id = { 3, 3, 3, 3 },
5670 .reg_offset = 0x200,
5671 .axi_id = 0,
5672 .axi_yrgb_id = 0x0c,
5673 .axi_uv_id = 0x0d,
5674 .pd_id = VOP2_PD_ESMART,
5675 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5676 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5677 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5678 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5679 .max_upscale_factor = 8,
5680 .max_downscale_factor = 8,
5681 },
5682
5683 {
5684 .name = "Esmart2",
5685 .phys_id = ROCKCHIP_VOP2_ESMART2,
5686 .splice_win_id = ROCKCHIP_VOP2_ESMART3,
5687 .type = ESMART_LAYER,
5688 .win_sel_port_offset = 6,
5689 .layer_sel_win_id = { 6, 6, 6, 6 },
5690 .reg_offset = 0x400,
5691 .axi_id = 1,
5692 .axi_yrgb_id = 0x0a,
5693 .axi_uv_id = 0x0b,
5694 .pd_id = VOP2_PD_ESMART,
5695 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5696 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5697 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5698 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5699 .max_upscale_factor = 8,
5700 .max_downscale_factor = 8,
5701 },
5702
5703 {
5704 .name = "Esmart3",
5705 .phys_id = ROCKCHIP_VOP2_ESMART3,
5706 .type = ESMART_LAYER,
5707 .win_sel_port_offset = 7,
5708 .layer_sel_win_id = { 7, 7, 7, 7 },
5709 .reg_offset = 0x600,
5710 .axi_id = 1,
5711 .axi_yrgb_id = 0x0c,
5712 .axi_uv_id = 0x0d,
5713 .pd_id = VOP2_PD_ESMART,
5714 .hsu_filter_mode = VOP2_SCALE_UP_BIC,
5715 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5716 .vsu_filter_mode = VOP2_SCALE_UP_BIL,
5717 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL,
5718 .max_upscale_factor = 8,
5719 .max_downscale_factor = 8,
5720 },
5721 };
5722
5723 static struct dsc_error_info dsc_ecw[] = {
5724 {0x00000000, "no error detected by DSC encoder"},
5725 {0x0030ffff, "bits per component error"},
5726 {0x0040ffff, "multiple mode error"},
5727 {0x0050ffff, "line buffer depth error"},
5728 {0x0060ffff, "minor version error"},
5729 {0x0070ffff, "picture height error"},
5730 {0x0080ffff, "picture width error"},
5731 {0x0090ffff, "number of slices error"},
5732 {0x00c0ffff, "slice height Error "},
5733 {0x00d0ffff, "slice width error"},
5734 {0x00e0ffff, "second line BPG offset error"},
5735 {0x00f0ffff, "non second line BPG offset error"},
5736 {0x0100ffff, "PPS ID error"},
5737 {0x0110ffff, "bits per pixel (BPP) Error"},
5738 {0x0120ffff, "buffer flow error"}, /* dsc_buffer_flow */
5739
5740 {0x01510001, "slice 0 RC buffer model overflow error"},
5741 {0x01510002, "slice 1 RC buffer model overflow error"},
5742 {0x01510004, "slice 2 RC buffer model overflow error"},
5743 {0x01510008, "slice 3 RC buffer model overflow error"},
5744 {0x01510010, "slice 4 RC buffer model overflow error"},
5745 {0x01510020, "slice 5 RC buffer model overflow error"},
5746 {0x01510040, "slice 6 RC buffer model overflow error"},
5747 {0x01510080, "slice 7 RC buffer model overflow error"},
5748
5749 {0x01610001, "slice 0 RC buffer model underflow error"},
5750 {0x01610002, "slice 1 RC buffer model underflow error"},
5751 {0x01610004, "slice 2 RC buffer model underflow error"},
5752 {0x01610008, "slice 3 RC buffer model underflow error"},
5753 {0x01610010, "slice 4 RC buffer model underflow error"},
5754 {0x01610020, "slice 5 RC buffer model underflow error"},
5755 {0x01610040, "slice 6 RC buffer model underflow error"},
5756 {0x01610080, "slice 7 RC buffer model underflow error"},
5757
5758 {0xffffffff, "unsuccessful RESET cycle status"},
5759 {0x00a0ffff, "ICH full error precision settings error"},
5760 {0x0020ffff, "native mode"},
5761 };
5762
5763 static struct dsc_error_info dsc_buffer_flow[] = {
5764 {0x00000000, "rate buffer status"},
5765 {0x00000001, "line buffer status"},
5766 {0x00000002, "decoder model status"},
5767 {0x00000003, "pixel buffer status"},
5768 {0x00000004, "balance fifo buffer status"},
5769 {0x00000005, "syntax element fifo status"},
5770 };
5771
5772 static struct vop2_dsc_data rk3588_dsc_data[] = {
5773 {
5774 .id = ROCKCHIP_VOP2_DSC_8K,
5775 .pd_id = VOP2_PD_DSC_8K,
5776 .max_slice_num = 8,
5777 .max_linebuf_depth = 11,
5778 .min_bits_per_pixel = 8,
5779 .dsc_txp_clk_src_name = "dsc_8k_txp_clk_src",
5780 .dsc_txp_clk_name = "dsc_8k_txp_clk",
5781 .dsc_pxl_clk_name = "dsc_8k_pxl_clk",
5782 .dsc_cds_clk_name = "dsc_8k_cds_clk",
5783 },
5784
5785 {
5786 .id = ROCKCHIP_VOP2_DSC_4K,
5787 .pd_id = VOP2_PD_DSC_4K,
5788 .max_slice_num = 2,
5789 .max_linebuf_depth = 11,
5790 .min_bits_per_pixel = 8,
5791 .dsc_txp_clk_src_name = "dsc_4k_txp_clk_src",
5792 .dsc_txp_clk_name = "dsc_4k_txp_clk",
5793 .dsc_pxl_clk_name = "dsc_4k_pxl_clk",
5794 .dsc_cds_clk_name = "dsc_4k_cds_clk",
5795 },
5796 };
5797
5798 static struct vop2_vp_data rk3588_vp_data[4] = {
5799 {
5800 .splice_vp_id = 1,
5801 .feature = VOP_FEATURE_OUTPUT_10BIT,
5802 .pre_scan_max_dly = 54,
5803 .max_dclk = 600000,
5804 .max_output = {7680, 4320},
5805 },
5806 {
5807 .feature = VOP_FEATURE_OUTPUT_10BIT,
5808 .pre_scan_max_dly = 54,
5809 .max_dclk = 600000,
5810 .max_output = {4096, 2304},
5811 },
5812 {
5813 .feature = VOP_FEATURE_OUTPUT_10BIT,
5814 .pre_scan_max_dly = 52,
5815 .max_dclk = 600000,
5816 .max_output = {4096, 2304},
5817 },
5818 {
5819 .feature = 0,
5820 .pre_scan_max_dly = 52,
5821 .max_dclk = 200000,
5822 .max_output = {1920, 1080},
5823 },
5824 };
5825
5826 static struct vop2_power_domain_data rk3588_vop_pd_data[] = {
5827 {
5828 .id = VOP2_PD_CLUSTER0,
5829 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0),
5830 },
5831 {
5832 .id = VOP2_PD_CLUSTER1,
5833 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1),
5834 .parent_id = VOP2_PD_CLUSTER0,
5835 },
5836 {
5837 .id = VOP2_PD_CLUSTER2,
5838 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2),
5839 .parent_id = VOP2_PD_CLUSTER0,
5840 },
5841 {
5842 .id = VOP2_PD_CLUSTER3,
5843 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3),
5844 .parent_id = VOP2_PD_CLUSTER0,
5845 },
5846 {
5847 .id = VOP2_PD_ESMART,
5848 .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) |
5849 BIT(ROCKCHIP_VOP2_ESMART2) |
5850 BIT(ROCKCHIP_VOP2_ESMART3),
5851 },
5852 {
5853 .id = VOP2_PD_DSC_8K,
5854 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K),
5855 },
5856 {
5857 .id = VOP2_PD_DSC_4K,
5858 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K),
5859 },
5860 };
5861
5862 const struct vop2_data rk3588_vop = {
5863 .version = VOP_VERSION_RK3588,
5864 .nr_vps = 4,
5865 .vp_data = rk3588_vp_data,
5866 .win_data = rk3588_win_data,
5867 .plane_mask = rk3588_vp_plane_mask[0],
5868 .plane_table = rk3588_plane_table,
5869 .pd = rk3588_vop_pd_data,
5870 .dsc = rk3588_dsc_data,
5871 .dsc_error_ecw = dsc_ecw,
5872 .dsc_error_buffer_flow = dsc_buffer_flow,
5873 .vp_primary_plane_order = rk3588_vp_primary_plane_order,
5874 .nr_layers = 8,
5875 .nr_mixers = 7,
5876 .nr_gammas = 4,
5877 .nr_pd = ARRAY_SIZE(rk3588_vop_pd_data),
5878 .nr_dscs = 2,
5879 .nr_dsc_ecw = ARRAY_SIZE(dsc_ecw),
5880 .nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow),
5881 .dump_regs = rk3588_dump_regs,
5882 .dump_regs_size = ARRAY_SIZE(rk3588_dump_regs),
5883 };
5884
5885 const struct rockchip_crtc_funcs rockchip_vop2_funcs = {
5886 .preinit = rockchip_vop2_preinit,
5887 .prepare = rockchip_vop2_prepare,
5888 .init = rockchip_vop2_init,
5889 .set_plane = rockchip_vop2_set_plane,
5890 .enable = rockchip_vop2_enable,
5891 .disable = rockchip_vop2_disable,
5892 .fixup_dts = rockchip_vop2_fixup_dts,
5893 .send_mcu_cmd = rockchip_vop2_send_mcu_cmd,
5894 .check = rockchip_vop2_check,
5895 .mode_valid = rockchip_vop2_mode_valid,
5896 .mode_fixup = rockchip_vop2_mode_fixup,
5897 .plane_check = rockchip_vop2_plane_check,
5898 .regs_dump = rockchip_vop2_regs_dump,
5899 .active_regs_dump = rockchip_vop2_active_regs_dump,
5900 .apply_soft_te = rockchip_vop2_apply_soft_te,
5901 };
5902