Commit | Line | Data |
---|---|---|
9c92ab61 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2048e328 MY |
2 | /* |
3 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | |
4 | * Author:Mark Yao <mark.yao@rock-chips.com> | |
2048e328 MY |
5 | */ |
6 | ||
7 | #ifndef _ROCKCHIP_DRM_VOP_H | |
8 | #define _ROCKCHIP_DRM_VOP_H | |
9 | ||
eb5cb6aa M |
10 | /* |
11 | * major: IP major version, used for IP structure | |
12 | * minor: big feature change under same structure | |
13 | */ | |
14 | #define VOP_VERSION(major, minor) ((major) << 8 | (minor)) | |
15 | #define VOP_MAJOR(version) ((version) >> 8) | |
16 | #define VOP_MINOR(version) ((version) & 0xff) | |
17 | ||
1c21aa8f DC |
18 | #define NUM_YUV2YUV_COEFFICIENTS 12 |
19 | ||
5f94e357 AR |
20 | /* AFBC supports a number of configurable modes. Relevant to us is block size |
21 | * (16x16 or 32x8), storage modifiers (SPARSE, SPLIT), and the YUV-like | |
22 | * colourspace transform (YTR). 16x16 SPARSE mode is always used. SPLIT mode | |
23 | * could be enabled via the hreg_block_split register, but is not currently | |
24 | * handled. The colourspace transform is implicitly always assumed by the | |
25 | * decoder, so consumers must use this transform as well. | |
26 | * | |
27 | * Failure to match modifiers will cause errors displaying AFBC buffers | |
28 | * produced by conformant AFBC producers, including Mesa. | |
29 | */ | |
7707f722 AP |
30 | #define ROCKCHIP_AFBC_MOD \ |
31 | DRM_FORMAT_MOD_ARM_AFBC( \ | |
32 | AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \ | |
5f94e357 | 33 | | AFBC_FORMAT_MOD_YTR \ |
7707f722 AP |
34 | ) |
35 | ||
a67719d1 MY |
36 | enum vop_data_format { |
37 | VOP_FMT_ARGB8888 = 0, | |
38 | VOP_FMT_RGB888, | |
39 | VOP_FMT_RGB565, | |
40 | VOP_FMT_YUV420SP = 4, | |
41 | VOP_FMT_YUV422SP, | |
42 | VOP_FMT_YUV444SP, | |
43 | }; | |
44 | ||
a67719d1 | 45 | struct vop_reg { |
a67719d1 | 46 | uint32_t mask; |
9a61c54b M |
47 | uint16_t offset; |
48 | uint8_t shift; | |
d49463ec | 49 | bool write_mask; |
9548e1b4 | 50 | bool relaxed; |
a67719d1 MY |
51 | }; |
52 | ||
7707f722 AP |
53 | struct vop_afbc { |
54 | struct vop_reg enable; | |
55 | struct vop_reg win_sel; | |
56 | struct vop_reg format; | |
604be855 AY |
57 | struct vop_reg rb_swap; |
58 | struct vop_reg uv_swap; | |
59 | struct vop_reg auto_gating_en; | |
60 | struct vop_reg block_split_en; | |
61 | struct vop_reg pic_vir_width; | |
62 | struct vop_reg tile_num; | |
7707f722 | 63 | struct vop_reg hreg_block_split; |
604be855 | 64 | struct vop_reg pic_offset; |
7707f722 | 65 | struct vop_reg pic_size; |
604be855 AY |
66 | struct vop_reg dsp_offset; |
67 | struct vop_reg transform_offset; | |
7707f722 | 68 | struct vop_reg hdr_ptr; |
604be855 AY |
69 | struct vop_reg half_block_en; |
70 | struct vop_reg xmirror; | |
71 | struct vop_reg ymirror; | |
72 | struct vop_reg rotate_270; | |
73 | struct vop_reg rotate_90; | |
7707f722 AP |
74 | struct vop_reg rstn; |
75 | }; | |
76 | ||
9a61c54b M |
77 | struct vop_modeset { |
78 | struct vop_reg htotal_pw; | |
79 | struct vop_reg hact_st_end; | |
80 | struct vop_reg hpost_st_end; | |
81 | struct vop_reg vtotal_pw; | |
82 | struct vop_reg vact_st_end; | |
83 | struct vop_reg vpost_st_end; | |
84 | }; | |
85 | ||
86 | struct vop_output { | |
87 | struct vop_reg pin_pol; | |
88 | struct vop_reg dp_pin_pol; | |
1f6c62ca | 89 | struct vop_reg dp_dclk_pol; |
9a61c54b | 90 | struct vop_reg edp_pin_pol; |
1f6c62ca | 91 | struct vop_reg edp_dclk_pol; |
9a61c54b | 92 | struct vop_reg hdmi_pin_pol; |
1f6c62ca | 93 | struct vop_reg hdmi_dclk_pol; |
9a61c54b | 94 | struct vop_reg mipi_pin_pol; |
1f6c62ca | 95 | struct vop_reg mipi_dclk_pol; |
9a61c54b | 96 | struct vop_reg rgb_pin_pol; |
1f6c62ca | 97 | struct vop_reg rgb_dclk_pol; |
9a61c54b | 98 | struct vop_reg dp_en; |
a67719d1 MY |
99 | struct vop_reg edp_en; |
100 | struct vop_reg hdmi_en; | |
101 | struct vop_reg mipi_en; | |
cf6d100d | 102 | struct vop_reg mipi_dual_channel_en; |
9a61c54b M |
103 | struct vop_reg rgb_en; |
104 | }; | |
105 | ||
106 | struct vop_common { | |
107 | struct vop_reg cfg_done; | |
60b7ae7f | 108 | struct vop_reg dsp_blank; |
9a61c54b | 109 | struct vop_reg data_blank; |
6bda8112 | 110 | struct vop_reg pre_dither_down; |
a5c0fa44 UR |
111 | struct vop_reg dither_down_sel; |
112 | struct vop_reg dither_down_mode; | |
113 | struct vop_reg dither_down_en; | |
a67719d1 | 114 | struct vop_reg dither_up; |
b23ab6ac | 115 | struct vop_reg dsp_lut_en; |
9a61c54b M |
116 | struct vop_reg gate_en; |
117 | struct vop_reg mmu_en; | |
118 | struct vop_reg out_mode; | |
119 | struct vop_reg standby; | |
120 | }; | |
a67719d1 | 121 | |
9a61c54b | 122 | struct vop_misc { |
60b7ae7f | 123 | struct vop_reg global_regdone_en; |
a67719d1 MY |
124 | }; |
125 | ||
126 | struct vop_intr { | |
127 | const int *intrs; | |
128 | uint32_t nintrs; | |
ac6560df M |
129 | |
130 | struct vop_reg line_flag_num[2]; | |
a67719d1 MY |
131 | struct vop_reg enable; |
132 | struct vop_reg clear; | |
133 | struct vop_reg status; | |
134 | }; | |
1194fffb MY |
135 | |
136 | struct vop_scl_extension { | |
a67719d1 MY |
137 | struct vop_reg cbcr_vsd_mode; |
138 | struct vop_reg cbcr_vsu_mode; | |
139 | struct vop_reg cbcr_hsd_mode; | |
140 | struct vop_reg cbcr_ver_scl_mode; | |
141 | struct vop_reg cbcr_hor_scl_mode; | |
142 | struct vop_reg yrgb_vsd_mode; | |
143 | struct vop_reg yrgb_vsu_mode; | |
144 | struct vop_reg yrgb_hsd_mode; | |
145 | struct vop_reg yrgb_ver_scl_mode; | |
146 | struct vop_reg yrgb_hor_scl_mode; | |
147 | struct vop_reg line_load_mode; | |
148 | struct vop_reg cbcr_axi_gather_num; | |
149 | struct vop_reg yrgb_axi_gather_num; | |
150 | struct vop_reg vsd_cbcr_gt2; | |
151 | struct vop_reg vsd_cbcr_gt4; | |
152 | struct vop_reg vsd_yrgb_gt2; | |
153 | struct vop_reg vsd_yrgb_gt4; | |
154 | struct vop_reg bic_coe_sel; | |
155 | struct vop_reg cbcr_axi_gather_en; | |
156 | struct vop_reg yrgb_axi_gather_en; | |
a67719d1 | 157 | struct vop_reg lb_mode; |
1194fffb MY |
158 | }; |
159 | ||
160 | struct vop_scl_regs { | |
161 | const struct vop_scl_extension *ext; | |
162 | ||
a67719d1 MY |
163 | struct vop_reg scale_yrgb_x; |
164 | struct vop_reg scale_yrgb_y; | |
165 | struct vop_reg scale_cbcr_x; | |
166 | struct vop_reg scale_cbcr_y; | |
167 | }; | |
168 | ||
1c21aa8f DC |
169 | struct vop_yuv2yuv_phy { |
170 | struct vop_reg y2r_coefficients[NUM_YUV2YUV_COEFFICIENTS]; | |
171 | }; | |
172 | ||
a67719d1 MY |
173 | struct vop_win_phy { |
174 | const struct vop_scl_regs *scl; | |
175 | const uint32_t *data_formats; | |
176 | uint32_t nformats; | |
7707f722 | 177 | const uint64_t *format_modifiers; |
a67719d1 MY |
178 | |
179 | struct vop_reg enable; | |
60b7ae7f | 180 | struct vop_reg gate; |
a67719d1 MY |
181 | struct vop_reg format; |
182 | struct vop_reg rb_swap; | |
3fa50896 | 183 | struct vop_reg uv_swap; |
a67719d1 MY |
184 | struct vop_reg act_info; |
185 | struct vop_reg dsp_info; | |
186 | struct vop_reg dsp_st; | |
187 | struct vop_reg yrgb_mst; | |
188 | struct vop_reg uv_mst; | |
189 | struct vop_reg yrgb_vir; | |
190 | struct vop_reg uv_vir; | |
677e8bbc DC |
191 | struct vop_reg y_mir_en; |
192 | struct vop_reg x_mir_en; | |
a67719d1 MY |
193 | |
194 | struct vop_reg dst_alpha_ctl; | |
195 | struct vop_reg src_alpha_ctl; | |
2aae8ed1 PK |
196 | struct vop_reg alpha_pre_mul; |
197 | struct vop_reg alpha_mode; | |
198 | struct vop_reg alpha_en; | |
9dd2aca4 | 199 | struct vop_reg channel; |
a67719d1 MY |
200 | }; |
201 | ||
1c21aa8f DC |
202 | struct vop_win_yuv2yuv_data { |
203 | uint32_t base; | |
204 | const struct vop_yuv2yuv_phy *phy; | |
205 | struct vop_reg y2r_en; | |
206 | }; | |
207 | ||
a67719d1 MY |
208 | struct vop_win_data { |
209 | uint32_t base; | |
210 | const struct vop_win_phy *phy; | |
211 | enum drm_plane_type type; | |
212 | }; | |
213 | ||
214 | struct vop_data { | |
eb5cb6aa | 215 | uint32_t version; |
a67719d1 | 216 | const struct vop_intr *intr; |
9a61c54b M |
217 | const struct vop_common *common; |
218 | const struct vop_misc *misc; | |
219 | const struct vop_modeset *modeset; | |
220 | const struct vop_output *output; | |
7707f722 | 221 | const struct vop_afbc *afbc; |
1c21aa8f | 222 | const struct vop_win_yuv2yuv_data *win_yuv2yuv; |
a67719d1 MY |
223 | const struct vop_win_data *win; |
224 | unsigned int win_size; | |
b23ab6ac | 225 | unsigned int lut_size; |
efd11cc8 M |
226 | |
227 | #define VOP_FEATURE_OUTPUT_RGB10 BIT(0) | |
1f0f0151 | 228 | #define VOP_FEATURE_INTERNAL_RGB BIT(1) |
efd11cc8 | 229 | u64 feature; |
a67719d1 | 230 | }; |
2048e328 MY |
231 | |
232 | /* interrupt define */ | |
233 | #define DSP_HOLD_VALID_INTR (1 << 0) | |
234 | #define FS_INTR (1 << 1) | |
235 | #define LINE_FLAG_INTR (1 << 2) | |
236 | #define BUS_ERROR_INTR (1 << 3) | |
237 | ||
238 | #define INTR_MASK (DSP_HOLD_VALID_INTR | FS_INTR | \ | |
239 | LINE_FLAG_INTR | BUS_ERROR_INTR) | |
240 | ||
241 | #define DSP_HOLD_VALID_INTR_EN(x) ((x) << 4) | |
242 | #define FS_INTR_EN(x) ((x) << 5) | |
243 | #define LINE_FLAG_INTR_EN(x) ((x) << 6) | |
244 | #define BUS_ERROR_INTR_EN(x) ((x) << 7) | |
245 | #define DSP_HOLD_VALID_INTR_MASK (1 << 4) | |
246 | #define FS_INTR_MASK (1 << 5) | |
247 | #define LINE_FLAG_INTR_MASK (1 << 6) | |
248 | #define BUS_ERROR_INTR_MASK (1 << 7) | |
249 | ||
250 | #define INTR_CLR_SHIFT 8 | |
251 | #define DSP_HOLD_VALID_INTR_CLR (1 << (INTR_CLR_SHIFT + 0)) | |
252 | #define FS_INTR_CLR (1 << (INTR_CLR_SHIFT + 1)) | |
253 | #define LINE_FLAG_INTR_CLR (1 << (INTR_CLR_SHIFT + 2)) | |
254 | #define BUS_ERROR_INTR_CLR (1 << (INTR_CLR_SHIFT + 3)) | |
255 | ||
256 | #define DSP_LINE_NUM(x) (((x) & 0x1fff) << 12) | |
257 | #define DSP_LINE_NUM_MASK (0x1fff << 12) | |
258 | ||
259 | /* src alpha ctrl define */ | |
260 | #define SRC_FADING_VALUE(x) (((x) & 0xff) << 24) | |
261 | #define SRC_GLOBAL_ALPHA(x) (((x) & 0xff) << 16) | |
262 | #define SRC_FACTOR_M0(x) (((x) & 0x7) << 6) | |
263 | #define SRC_ALPHA_CAL_M0(x) (((x) & 0x1) << 5) | |
264 | #define SRC_BLEND_M0(x) (((x) & 0x3) << 3) | |
265 | #define SRC_ALPHA_M0(x) (((x) & 0x1) << 2) | |
266 | #define SRC_COLOR_M0(x) (((x) & 0x1) << 1) | |
267 | #define SRC_ALPHA_EN(x) (((x) & 0x1) << 0) | |
268 | /* dst alpha ctrl define */ | |
269 | #define DST_FACTOR_M0(x) (((x) & 0x7) << 6) | |
270 | ||
271 | /* | |
272 | * display output interface supported by rockchip lcdc | |
273 | */ | |
274 | #define ROCKCHIP_OUT_MODE_P888 0 | |
275 | #define ROCKCHIP_OUT_MODE_P666 1 | |
276 | #define ROCKCHIP_OUT_MODE_P565 2 | |
277 | /* for use special outface */ | |
278 | #define ROCKCHIP_OUT_MODE_AAAA 15 | |
279 | ||
cf6d100d HS |
280 | /* output flags */ |
281 | #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) | |
282 | ||
2048e328 MY |
283 | enum alpha_mode { |
284 | ALPHA_STRAIGHT, | |
285 | ALPHA_INVERSE, | |
286 | }; | |
287 | ||
288 | enum global_blend_mode { | |
289 | ALPHA_GLOBAL, | |
290 | ALPHA_PER_PIX, | |
291 | ALPHA_PER_PIX_GLOBAL, | |
292 | }; | |
293 | ||
294 | enum alpha_cal_mode { | |
295 | ALPHA_SATURATION, | |
296 | ALPHA_NO_SATURATION, | |
297 | }; | |
298 | ||
299 | enum color_mode { | |
300 | ALPHA_SRC_PRE_MUL, | |
301 | ALPHA_SRC_NO_PRE_MUL, | |
302 | }; | |
303 | ||
304 | enum factor_mode { | |
305 | ALPHA_ZERO, | |
306 | ALPHA_ONE, | |
307 | ALPHA_SRC, | |
308 | ALPHA_SRC_INVERSE, | |
309 | ALPHA_SRC_GLOBAL, | |
310 | }; | |
311 | ||
4c156c21 MY |
312 | enum scale_mode { |
313 | SCALE_NONE = 0x0, | |
314 | SCALE_UP = 0x1, | |
315 | SCALE_DOWN = 0x2 | |
316 | }; | |
317 | ||
318 | enum lb_mode { | |
319 | LB_YUV_3840X5 = 0x0, | |
320 | LB_YUV_2560X8 = 0x1, | |
321 | LB_RGB_3840X2 = 0x2, | |
322 | LB_RGB_2560X4 = 0x3, | |
323 | LB_RGB_1920X5 = 0x4, | |
324 | LB_RGB_1280X8 = 0x5 | |
325 | }; | |
326 | ||
327 | enum sacle_up_mode { | |
328 | SCALE_UP_BIL = 0x0, | |
329 | SCALE_UP_BIC = 0x1 | |
330 | }; | |
331 | ||
332 | enum scale_down_mode { | |
333 | SCALE_DOWN_BIL = 0x0, | |
334 | SCALE_DOWN_AVG = 0x1 | |
335 | }; | |
336 | ||
a5c0fa44 UR |
337 | enum dither_down_mode { |
338 | RGB888_TO_RGB565 = 0x0, | |
339 | RGB888_TO_RGB666 = 0x1 | |
340 | }; | |
341 | ||
342 | enum dither_down_mode_sel { | |
343 | DITHER_DOWN_ALLEGRO = 0x0, | |
344 | DITHER_DOWN_FRC = 0x1 | |
345 | }; | |
346 | ||
1a0f7ed3 CZ |
347 | enum vop_pol { |
348 | HSYNC_POSITIVE = 0, | |
349 | VSYNC_POSITIVE = 1, | |
1f6c62ca | 350 | DEN_NEGATIVE = 2 |
1a0f7ed3 CZ |
351 | }; |
352 | ||
4c156c21 MY |
353 | #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) |
354 | #define SCL_FT_DEFAULT_FIXPOINT_SHIFT 12 | |
355 | #define SCL_MAX_VSKIPLINES 4 | |
356 | #define MIN_SCL_FT_AFTER_VSKIP 1 | |
357 | ||
358 | static inline uint16_t scl_cal_scale(int src, int dst, int shift) | |
359 | { | |
360 | return ((src * 2 - 3) << (shift - 1)) / (dst - 1); | |
361 | } | |
362 | ||
1194fffb MY |
363 | static inline uint16_t scl_cal_scale2(int src, int dst) |
364 | { | |
365 | return ((src - 1) << 12) / (dst - 1); | |
366 | } | |
367 | ||
4c156c21 MY |
368 | #define GET_SCL_FT_BILI_DN(src, dst) scl_cal_scale(src, dst, 12) |
369 | #define GET_SCL_FT_BILI_UP(src, dst) scl_cal_scale(src, dst, 16) | |
370 | #define GET_SCL_FT_BIC(src, dst) scl_cal_scale(src, dst, 16) | |
371 | ||
372 | static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h, | |
373 | int vskiplines) | |
374 | { | |
375 | int act_height; | |
376 | ||
53c902b9 | 377 | act_height = DIV_ROUND_UP(src_h, vskiplines); |
4c156c21 | 378 | |
0b12e9c0 M |
379 | if (act_height == dst_h) |
380 | return GET_SCL_FT_BILI_DN(src_h, dst_h) / vskiplines; | |
381 | ||
4c156c21 MY |
382 | return GET_SCL_FT_BILI_DN(act_height, dst_h); |
383 | } | |
384 | ||
385 | static inline enum scale_mode scl_get_scl_mode(int src, int dst) | |
386 | { | |
387 | if (src < dst) | |
388 | return SCALE_UP; | |
389 | else if (src > dst) | |
390 | return SCALE_DOWN; | |
391 | ||
392 | return SCALE_NONE; | |
393 | } | |
394 | ||
395 | static inline int scl_get_vskiplines(uint32_t srch, uint32_t dsth) | |
396 | { | |
397 | uint32_t vskiplines; | |
398 | ||
399 | for (vskiplines = SCL_MAX_VSKIPLINES; vskiplines > 1; vskiplines /= 2) | |
400 | if (srch >= vskiplines * dsth * MIN_SCL_FT_AFTER_VSKIP) | |
401 | break; | |
402 | ||
403 | return vskiplines; | |
404 | } | |
405 | ||
406 | static inline int scl_vop_cal_lb_mode(int width, bool is_yuv) | |
407 | { | |
408 | int lb_mode; | |
409 | ||
10635917 SH |
410 | if (is_yuv) { |
411 | if (width > 1280) | |
412 | lb_mode = LB_YUV_3840X5; | |
413 | else | |
414 | lb_mode = LB_YUV_2560X8; | |
415 | } else { | |
416 | if (width > 2560) | |
417 | lb_mode = LB_RGB_3840X2; | |
418 | else if (width > 1920) | |
419 | lb_mode = LB_RGB_2560X4; | |
420 | else | |
421 | lb_mode = LB_RGB_1920X5; | |
422 | } | |
4c156c21 MY |
423 | |
424 | return lb_mode; | |
425 | } | |
426 | ||
a67719d1 | 427 | extern const struct component_ops vop_component_ops; |
2048e328 | 428 | #endif /* _ROCKCHIP_DRM_VOP_H */ |