Commit | Line | Data |
---|---|---|
9c92ab61 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
a67719d1 MY |
2 | /* |
3 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | |
4 | * Author:Mark Yao <mark.yao@rock-chips.com> | |
a67719d1 MY |
5 | */ |
6 | ||
a67719d1 | 7 | #include <linux/component.h> |
c2156ccd SR |
8 | #include <linux/mod_devicetable.h> |
9 | #include <linux/module.h> | |
10 | #include <linux/of.h> | |
11 | #include <linux/platform_device.h> | |
12 | ||
13 | #include <drm/drm_fourcc.h> | |
14 | #include <drm/drm_plane.h> | |
15 | #include <drm/drm_print.h> | |
a67719d1 MY |
16 | |
17 | #include "rockchip_drm_vop.h" | |
18 | #include "rockchip_vop_reg.h" | |
b02516b6 | 19 | #include "rockchip_drm_drv.h" |
a67719d1 | 20 | |
9548e1b4 M |
21 | #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \ |
22 | { \ | |
23 | .offset = off, \ | |
a67719d1 | 24 | .mask = _mask, \ |
9548e1b4 M |
25 | .shift = _shift, \ |
26 | .write_mask = _write_mask, \ | |
27 | .relaxed = _relaxed, \ | |
28 | } | |
d49463ec | 29 | |
9548e1b4 M |
30 | #define VOP_REG(off, _mask, _shift) \ |
31 | _VOP_REG(off, _mask, _shift, false, true) | |
32 | ||
33 | #define VOP_REG_SYNC(off, _mask, _shift) \ | |
34 | _VOP_REG(off, _mask, _shift, false, false) | |
35 | ||
36 | #define VOP_REG_MASK_SYNC(off, _mask, _shift) \ | |
37 | _VOP_REG(off, _mask, _shift, true, false) | |
a67719d1 | 38 | |
f7673453 | 39 | static const uint32_t formats_win_full[] = { |
a67719d1 MY |
40 | DRM_FORMAT_XRGB8888, |
41 | DRM_FORMAT_ARGB8888, | |
42 | DRM_FORMAT_XBGR8888, | |
43 | DRM_FORMAT_ABGR8888, | |
44 | DRM_FORMAT_RGB888, | |
45 | DRM_FORMAT_BGR888, | |
46 | DRM_FORMAT_RGB565, | |
47 | DRM_FORMAT_BGR565, | |
48 | DRM_FORMAT_NV12, | |
3fa50896 | 49 | DRM_FORMAT_NV21, |
a67719d1 | 50 | DRM_FORMAT_NV16, |
3fa50896 | 51 | DRM_FORMAT_NV61, |
a67719d1 | 52 | DRM_FORMAT_NV24, |
3fa50896 | 53 | DRM_FORMAT_NV42, |
a67719d1 MY |
54 | }; |
55 | ||
7707f722 AP |
56 | static const uint64_t format_modifiers_win_full[] = { |
57 | DRM_FORMAT_MOD_LINEAR, | |
58 | DRM_FORMAT_MOD_INVALID, | |
59 | }; | |
60 | ||
61 | static const uint64_t format_modifiers_win_full_afbc[] = { | |
62 | ROCKCHIP_AFBC_MOD, | |
63 | DRM_FORMAT_MOD_LINEAR, | |
64 | DRM_FORMAT_MOD_INVALID, | |
65 | }; | |
66 | ||
f7673453 | 67 | static const uint32_t formats_win_lite[] = { |
a67719d1 MY |
68 | DRM_FORMAT_XRGB8888, |
69 | DRM_FORMAT_ARGB8888, | |
70 | DRM_FORMAT_XBGR8888, | |
71 | DRM_FORMAT_ABGR8888, | |
72 | DRM_FORMAT_RGB888, | |
73 | DRM_FORMAT_BGR888, | |
74 | DRM_FORMAT_RGB565, | |
75 | DRM_FORMAT_BGR565, | |
76 | }; | |
77 | ||
7707f722 AP |
78 | static const uint64_t format_modifiers_win_lite[] = { |
79 | DRM_FORMAT_MOD_LINEAR, | |
80 | DRM_FORMAT_MOD_INVALID, | |
81 | }; | |
82 | ||
53c2710c | 83 | static const struct vop_scl_regs rk3036_win0_scl = { |
b51502ad MY |
84 | .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), |
85 | .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
86 | .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
87 | .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
88 | }; | |
89 | ||
53c2710c AB |
90 | static const struct vop_scl_regs rk3036_win1_scl = { |
91 | .scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
92 | .scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16), | |
93 | }; | |
94 | ||
b51502ad | 95 | static const struct vop_win_phy rk3036_win0_data = { |
53c2710c | 96 | .scl = &rk3036_win0_scl, |
b51502ad MY |
97 | .data_formats = formats_win_full, |
98 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 99 | .format_modifiers = format_modifiers_win_full, |
b51502ad MY |
100 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0), |
101 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3), | |
102 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15), | |
103 | .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
104 | .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
105 | .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0), | |
106 | .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0), | |
107 | .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0), | |
108 | .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0), | |
109 | .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16), | |
d099fa67 AB |
110 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18), |
111 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0), | |
112 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
b51502ad MY |
113 | }; |
114 | ||
115 | static const struct vop_win_phy rk3036_win1_data = { | |
53c2710c | 116 | .scl = &rk3036_win1_scl, |
b51502ad MY |
117 | .data_formats = formats_win_lite, |
118 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 119 | .format_modifiers = format_modifiers_win_lite, |
b51502ad MY |
120 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), |
121 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), | |
122 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), | |
123 | .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0), | |
124 | .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
125 | .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0), | |
126 | .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0), | |
127 | .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), | |
d099fa67 AB |
128 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19), |
129 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1), | |
130 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
b51502ad MY |
131 | }; |
132 | ||
133 | static const struct vop_win_data rk3036_vop_win_data[] = { | |
134 | { .base = 0x00, .phy = &rk3036_win0_data, | |
135 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
136 | { .base = 0x00, .phy = &rk3036_win1_data, | |
137 | .type = DRM_PLANE_TYPE_CURSOR }, | |
138 | }; | |
139 | ||
140 | static const int rk3036_vop_intrs[] = { | |
141 | DSP_HOLD_VALID_INTR, | |
142 | FS_INTR, | |
143 | LINE_FLAG_INTR, | |
144 | BUS_ERROR_INTR, | |
145 | }; | |
146 | ||
147 | static const struct vop_intr rk3036_intr = { | |
148 | .intrs = rk3036_vop_intrs, | |
149 | .nintrs = ARRAY_SIZE(rk3036_vop_intrs), | |
ac6560df | 150 | .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12), |
9a61c54b M |
151 | .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0), |
152 | .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4), | |
153 | .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8), | |
b51502ad MY |
154 | }; |
155 | ||
9a61c54b | 156 | static const struct vop_modeset rk3036_modeset = { |
b51502ad MY |
157 | .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), |
158 | .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
159 | .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
160 | .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
9a61c54b M |
161 | }; |
162 | ||
163 | static const struct vop_output rk3036_output = { | |
164 | .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4), | |
165 | }; | |
166 | ||
167 | static const struct vop_common rk3036_common = { | |
168 | .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30), | |
169 | .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), | |
170 | .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24), | |
a5c0fa44 UR |
171 | .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27), |
172 | .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11), | |
173 | .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10), | |
9548e1b4 | 174 | .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), |
b51502ad MY |
175 | }; |
176 | ||
b51502ad | 177 | static const struct vop_data rk3036_vop = { |
b51502ad | 178 | .intr = &rk3036_intr, |
9a61c54b M |
179 | .common = &rk3036_common, |
180 | .modeset = &rk3036_modeset, | |
181 | .output = &rk3036_output, | |
b51502ad MY |
182 | .win = rk3036_vop_win_data, |
183 | .win_size = ARRAY_SIZE(rk3036_vop_win_data), | |
8e140cb6 | 184 | .max_output = { 1920, 1080 }, |
b51502ad MY |
185 | }; |
186 | ||
460c3b00 SH |
187 | static const struct vop_win_phy rk3126_win1_data = { |
188 | .data_formats = formats_win_lite, | |
189 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 190 | .format_modifiers = format_modifiers_win_lite, |
460c3b00 SH |
191 | .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), |
192 | .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), | |
193 | .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), | |
194 | .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
195 | .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), | |
196 | .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0), | |
197 | .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0), | |
d099fa67 AB |
198 | .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19), |
199 | .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1), | |
200 | .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29), | |
460c3b00 SH |
201 | }; |
202 | ||
203 | static const struct vop_win_data rk3126_vop_win_data[] = { | |
204 | { .base = 0x00, .phy = &rk3036_win0_data, | |
205 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
206 | { .base = 0x00, .phy = &rk3126_win1_data, | |
207 | .type = DRM_PLANE_TYPE_CURSOR }, | |
208 | }; | |
209 | ||
210 | static const struct vop_data rk3126_vop = { | |
211 | .intr = &rk3036_intr, | |
212 | .common = &rk3036_common, | |
213 | .modeset = &rk3036_modeset, | |
214 | .output = &rk3036_output, | |
215 | .win = rk3126_vop_win_data, | |
216 | .win_size = ARRAY_SIZE(rk3126_vop_win_data), | |
8e140cb6 | 217 | .max_output = { 1920, 1080 }, |
460c3b00 SH |
218 | }; |
219 | ||
570913e0 SH |
220 | static const int px30_vop_intrs[] = { |
221 | FS_INTR, | |
222 | 0, 0, | |
223 | LINE_FLAG_INTR, | |
224 | 0, | |
225 | BUS_ERROR_INTR, | |
226 | 0, 0, | |
227 | DSP_HOLD_VALID_INTR, | |
228 | }; | |
229 | ||
230 | static const struct vop_intr px30_intr = { | |
231 | .intrs = px30_vop_intrs, | |
232 | .nintrs = ARRAY_SIZE(px30_vop_intrs), | |
a6edf839 SH |
233 | .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0), |
234 | .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0), | |
235 | .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0), | |
236 | .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0), | |
570913e0 SH |
237 | }; |
238 | ||
239 | static const struct vop_common px30_common = { | |
240 | .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), | |
241 | .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), | |
242 | .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14), | |
a5c0fa44 UR |
243 | .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8), |
244 | .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7), | |
245 | .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6), | |
570913e0 SH |
246 | .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0), |
247 | }; | |
248 | ||
249 | static const struct vop_modeset px30_modeset = { | |
250 | .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), | |
251 | .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0), | |
252 | .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), | |
253 | .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0), | |
254 | }; | |
255 | ||
256 | static const struct vop_output px30_output = { | |
1f6c62ca NY |
257 | .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1), |
258 | .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2), | |
570913e0 | 259 | .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0), |
1f6c62ca NY |
260 | .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25), |
261 | .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26), | |
570913e0 SH |
262 | .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24), |
263 | }; | |
264 | ||
265 | static const struct vop_scl_regs px30_win_scl = { | |
266 | .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
267 | .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
268 | .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
269 | .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
270 | }; | |
271 | ||
272 | static const struct vop_win_phy px30_win0_data = { | |
273 | .scl = &px30_win_scl, | |
274 | .data_formats = formats_win_full, | |
275 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 276 | .format_modifiers = format_modifiers_win_full, |
570913e0 SH |
277 | .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0), |
278 | .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1), | |
279 | .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12), | |
3fa50896 | 280 | .uv_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 15), |
570913e0 SH |
281 | .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0), |
282 | .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0), | |
283 | .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0), | |
284 | .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0), | |
285 | .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0), | |
286 | .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0), | |
287 | .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16), | |
2aae8ed1 PK |
288 | .alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2), |
289 | .alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1), | |
290 | .alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
291 | }; |
292 | ||
293 | static const struct vop_win_phy px30_win1_data = { | |
294 | .data_formats = formats_win_lite, | |
295 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 296 | .format_modifiers = format_modifiers_win_lite, |
570913e0 SH |
297 | .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0), |
298 | .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4), | |
299 | .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12), | |
3fa50896 | 300 | .uv_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 15), |
570913e0 SH |
301 | .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0), |
302 | .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0), | |
303 | .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0), | |
304 | .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0), | |
2aae8ed1 PK |
305 | .alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2), |
306 | .alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1), | |
307 | .alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
308 | }; |
309 | ||
310 | static const struct vop_win_phy px30_win2_data = { | |
311 | .data_formats = formats_win_lite, | |
312 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 313 | .format_modifiers = format_modifiers_win_lite, |
a6edf839 SH |
314 | .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4), |
315 | .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0), | |
570913e0 SH |
316 | .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5), |
317 | .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20), | |
318 | .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0), | |
319 | .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
320 | .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0), | |
321 | .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0), | |
2aae8ed1 PK |
322 | .alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2), |
323 | .alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1), | |
324 | .alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0), | |
570913e0 SH |
325 | }; |
326 | ||
327 | static const struct vop_win_data px30_vop_big_win_data[] = { | |
328 | { .base = 0x00, .phy = &px30_win0_data, | |
329 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
330 | { .base = 0x00, .phy = &px30_win1_data, | |
331 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
332 | { .base = 0x00, .phy = &px30_win2_data, | |
333 | .type = DRM_PLANE_TYPE_CURSOR }, | |
334 | }; | |
335 | ||
336 | static const struct vop_data px30_vop_big = { | |
872b68e9 | 337 | .version = VOP_VERSION(2, 6), |
570913e0 | 338 | .intr = &px30_intr, |
8d544233 | 339 | .feature = VOP_FEATURE_INTERNAL_RGB, |
570913e0 SH |
340 | .common = &px30_common, |
341 | .modeset = &px30_modeset, | |
342 | .output = &px30_output, | |
343 | .win = px30_vop_big_win_data, | |
344 | .win_size = ARRAY_SIZE(px30_vop_big_win_data), | |
8e140cb6 | 345 | .max_output = { 1920, 1080 }, |
570913e0 SH |
346 | }; |
347 | ||
348 | static const struct vop_win_data px30_vop_lit_win_data[] = { | |
349 | { .base = 0x00, .phy = &px30_win1_data, | |
350 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
351 | }; | |
352 | ||
353 | static const struct vop_data px30_vop_lit = { | |
872b68e9 | 354 | .version = VOP_VERSION(2, 5), |
570913e0 | 355 | .intr = &px30_intr, |
8d544233 | 356 | .feature = VOP_FEATURE_INTERNAL_RGB, |
570913e0 SH |
357 | .common = &px30_common, |
358 | .modeset = &px30_modeset, | |
359 | .output = &px30_output, | |
360 | .win = px30_vop_lit_win_data, | |
361 | .win_size = ARRAY_SIZE(px30_vop_lit_win_data), | |
8e140cb6 | 362 | .max_output = { 1920, 1080 }, |
570913e0 SH |
363 | }; |
364 | ||
f4a6de85 MY |
365 | static const struct vop_scl_regs rk3066_win_scl = { |
366 | .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
367 | .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
368 | .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
369 | .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
370 | }; | |
371 | ||
372 | static const struct vop_win_phy rk3066_win0_data = { | |
373 | .scl = &rk3066_win_scl, | |
374 | .data_formats = formats_win_full, | |
375 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 376 | .format_modifiers = format_modifiers_win_full, |
f4a6de85 | 377 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0), |
742203cd AB |
378 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4), |
379 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19), | |
3fa50896 | 380 | .uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 22), |
f4a6de85 MY |
381 | .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0), |
382 | .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
383 | .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0), | |
384 | .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0), | |
385 | .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0), | |
386 | .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0), | |
387 | .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16), | |
d099fa67 AB |
388 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21), |
389 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0), | |
f4a6de85 MY |
390 | }; |
391 | ||
392 | static const struct vop_win_phy rk3066_win1_data = { | |
f4a6de85 MY |
393 | .data_formats = formats_win_full, |
394 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 395 | .format_modifiers = format_modifiers_win_full, |
f4a6de85 | 396 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1), |
742203cd AB |
397 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7), |
398 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23), | |
3fa50896 | 399 | .uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 26), |
f4a6de85 MY |
400 | .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0), |
401 | .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0), | |
402 | .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0), | |
403 | .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0), | |
404 | .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0), | |
405 | .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0), | |
406 | .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16), | |
d099fa67 AB |
407 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22), |
408 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1), | |
f4a6de85 MY |
409 | }; |
410 | ||
411 | static const struct vop_win_phy rk3066_win2_data = { | |
412 | .data_formats = formats_win_lite, | |
413 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 414 | .format_modifiers = format_modifiers_win_lite, |
f4a6de85 | 415 | .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2), |
742203cd AB |
416 | .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10), |
417 | .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27), | |
f4a6de85 MY |
418 | .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0), |
419 | .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), | |
420 | .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), | |
421 | .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0), | |
d099fa67 AB |
422 | .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23), |
423 | .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2), | |
f4a6de85 MY |
424 | }; |
425 | ||
426 | static const struct vop_modeset rk3066_modeset = { | |
427 | .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
428 | .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
429 | .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
430 | .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
431 | }; | |
432 | ||
433 | static const struct vop_output rk3066_output = { | |
434 | .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4), | |
435 | }; | |
436 | ||
437 | static const struct vop_common rk3066_common = { | |
438 | .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1), | |
439 | .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0), | |
440 | .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0), | |
a5c0fa44 UR |
441 | .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11), |
442 | .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10), | |
f4a6de85 | 443 | .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), |
742203cd AB |
444 | .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9), |
445 | .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31), | |
446 | .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25), | |
f4a6de85 MY |
447 | }; |
448 | ||
449 | static const struct vop_win_data rk3066_vop_win_data[] = { | |
450 | { .base = 0x00, .phy = &rk3066_win0_data, | |
451 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
452 | { .base = 0x00, .phy = &rk3066_win1_data, | |
453 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
454 | { .base = 0x00, .phy = &rk3066_win2_data, | |
455 | .type = DRM_PLANE_TYPE_CURSOR }, | |
456 | }; | |
457 | ||
458 | static const int rk3066_vop_intrs[] = { | |
459 | /* | |
460 | * hs_start interrupt fires at frame-start, so serves | |
461 | * the same purpose as dsp_hold in the driver. | |
462 | */ | |
463 | DSP_HOLD_VALID_INTR, | |
464 | FS_INTR, | |
465 | LINE_FLAG_INTR, | |
466 | BUS_ERROR_INTR, | |
467 | }; | |
468 | ||
469 | static const struct vop_intr rk3066_intr = { | |
470 | .intrs = rk3066_vop_intrs, | |
471 | .nintrs = ARRAY_SIZE(rk3066_vop_intrs), | |
472 | .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12), | |
473 | .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0), | |
474 | .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4), | |
475 | .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8), | |
476 | }; | |
477 | ||
478 | static const struct vop_data rk3066_vop = { | |
479 | .version = VOP_VERSION(2, 1), | |
480 | .intr = &rk3066_intr, | |
481 | .common = &rk3066_common, | |
482 | .modeset = &rk3066_modeset, | |
483 | .output = &rk3066_output, | |
484 | .win = rk3066_vop_win_data, | |
485 | .win_size = ARRAY_SIZE(rk3066_vop_win_data), | |
8e140cb6 | 486 | .max_output = { 1920, 1080 }, |
f4a6de85 MY |
487 | }; |
488 | ||
428e15cc HS |
489 | static const struct vop_scl_regs rk3188_win_scl = { |
490 | .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
491 | .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
492 | .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
493 | .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
494 | }; | |
495 | ||
496 | static const struct vop_win_phy rk3188_win0_data = { | |
497 | .scl = &rk3188_win_scl, | |
498 | .data_formats = formats_win_full, | |
499 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 500 | .format_modifiers = format_modifiers_win_full, |
428e15cc HS |
501 | .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0), |
502 | .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3), | |
503 | .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15), | |
3fa50896 | 504 | .uv_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 18), |
428e15cc HS |
505 | .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0), |
506 | .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
507 | .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0), | |
508 | .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0), | |
509 | .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0), | |
510 | .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0), | |
d099fa67 AB |
511 | .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 18), |
512 | .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 0), | |
513 | .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29), | |
428e15cc HS |
514 | }; |
515 | ||
516 | static const struct vop_win_phy rk3188_win1_data = { | |
517 | .data_formats = formats_win_lite, | |
518 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 519 | .format_modifiers = format_modifiers_win_lite, |
428e15cc HS |
520 | .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1), |
521 | .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6), | |
522 | .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19), | |
523 | /* no act_info on window1 */ | |
524 | .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0), | |
525 | .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0), | |
526 | .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0), | |
527 | .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16), | |
d099fa67 AB |
528 | .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 19), |
529 | .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 1), | |
530 | .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29), | |
428e15cc HS |
531 | }; |
532 | ||
533 | static const struct vop_modeset rk3188_modeset = { | |
534 | .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0), | |
535 | .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0), | |
536 | .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0), | |
537 | .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0), | |
538 | }; | |
539 | ||
540 | static const struct vop_output rk3188_output = { | |
541 | .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4), | |
542 | }; | |
543 | ||
544 | static const struct vop_common rk3188_common = { | |
545 | .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31), | |
546 | .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30), | |
547 | .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0), | |
548 | .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0), | |
a5c0fa44 UR |
549 | .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27), |
550 | .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11), | |
551 | .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10), | |
ab64b448 AB |
552 | .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24), |
553 | .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9), | |
554 | .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28), | |
555 | .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25), | |
428e15cc HS |
556 | }; |
557 | ||
558 | static const struct vop_win_data rk3188_vop_win_data[] = { | |
559 | { .base = 0x00, .phy = &rk3188_win0_data, | |
560 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
561 | { .base = 0x00, .phy = &rk3188_win1_data, | |
562 | .type = DRM_PLANE_TYPE_CURSOR }, | |
563 | }; | |
564 | ||
565 | static const int rk3188_vop_intrs[] = { | |
4f297df8 HS |
566 | /* |
567 | * hs_start interrupt fires at frame-start, so serves | |
568 | * the same purpose as dsp_hold in the driver. | |
569 | */ | |
570 | DSP_HOLD_VALID_INTR, | |
428e15cc HS |
571 | FS_INTR, |
572 | LINE_FLAG_INTR, | |
573 | BUS_ERROR_INTR, | |
574 | }; | |
575 | ||
576 | static const struct vop_intr rk3188_vop_intr = { | |
577 | .intrs = rk3188_vop_intrs, | |
578 | .nintrs = ARRAY_SIZE(rk3188_vop_intrs), | |
579 | .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12), | |
580 | .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0), | |
581 | .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4), | |
582 | .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8), | |
583 | }; | |
584 | ||
585 | static const struct vop_data rk3188_vop = { | |
586 | .intr = &rk3188_vop_intr, | |
587 | .common = &rk3188_common, | |
588 | .modeset = &rk3188_modeset, | |
589 | .output = &rk3188_output, | |
590 | .win = rk3188_vop_win_data, | |
591 | .win_size = ARRAY_SIZE(rk3188_vop_win_data), | |
592 | .feature = VOP_FEATURE_INTERNAL_RGB, | |
8e140cb6 | 593 | .max_output = { 2048, 1536 }, |
428e15cc HS |
594 | }; |
595 | ||
f7673453 MY |
596 | static const struct vop_scl_extension rk3288_win_full_scl_ext = { |
597 | .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), | |
598 | .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), | |
599 | .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28), | |
600 | .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26), | |
601 | .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24), | |
602 | .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23), | |
603 | .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22), | |
604 | .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20), | |
605 | .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18), | |
606 | .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16), | |
607 | .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15), | |
608 | .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12), | |
609 | .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8), | |
610 | .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7), | |
611 | .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6), | |
612 | .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5), | |
613 | .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4), | |
614 | .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2), | |
615 | .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1), | |
616 | .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0), | |
617 | .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5), | |
618 | }; | |
619 | ||
620 | static const struct vop_scl_regs rk3288_win_full_scl = { | |
621 | .ext = &rk3288_win_full_scl_ext, | |
622 | .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), | |
623 | .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), | |
624 | .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0), | |
625 | .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16), | |
626 | }; | |
627 | ||
628 | static const struct vop_win_phy rk3288_win01_data = { | |
629 | .scl = &rk3288_win_full_scl, | |
630 | .data_formats = formats_win_full, | |
631 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 632 | .format_modifiers = format_modifiers_win_full, |
f7673453 MY |
633 | .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), |
634 | .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), | |
635 | .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), | |
3fa50896 | 636 | .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), |
f7673453 MY |
637 | .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), |
638 | .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
639 | .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), | |
640 | .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), | |
641 | .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), | |
642 | .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), | |
643 | .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), | |
644 | .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
645 | .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
9dd2aca4 | 646 | .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), |
f7673453 MY |
647 | }; |
648 | ||
649 | static const struct vop_win_phy rk3288_win23_data = { | |
650 | .data_formats = formats_win_lite, | |
651 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 652 | .format_modifiers = format_modifiers_win_lite, |
60b7ae7f M |
653 | .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4), |
654 | .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), | |
f7673453 MY |
655 | .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1), |
656 | .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12), | |
657 | .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0), | |
658 | .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
659 | .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0), | |
660 | .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0), | |
661 | .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0), | |
662 | .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0), | |
663 | }; | |
664 | ||
9a61c54b M |
665 | static const struct vop_modeset rk3288_modeset = { |
666 | .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
667 | .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
668 | .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
669 | .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
670 | .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), | |
671 | .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), | |
672 | }; | |
673 | ||
674 | static const struct vop_output rk3288_output = { | |
675 | .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4), | |
f7673453 MY |
676 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), |
677 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
678 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
679 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
9a61c54b M |
680 | }; |
681 | ||
682 | static const struct vop_common rk3288_common = { | |
683 | .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22), | |
684 | .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23), | |
685 | .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20), | |
a5c0fa44 UR |
686 | .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4), |
687 | .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3), | |
688 | .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2), | |
6bda8112 | 689 | .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1), |
f7673453 | 690 | .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6), |
b23ab6ac | 691 | .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0), |
f7673453 | 692 | .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19), |
60b7ae7f | 693 | .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), |
f7673453 | 694 | .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), |
9548e1b4 | 695 | .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), |
f7673453 MY |
696 | }; |
697 | ||
a67719d1 MY |
698 | /* |
699 | * Note: rk3288 has a dedicated 'cursor' window, however, that window requires | |
700 | * special support to get alpha blending working. For now, just use overlay | |
701 | * window 3 for the drm cursor. | |
702 | * | |
703 | */ | |
704 | static const struct vop_win_data rk3288_vop_win_data[] = { | |
f7673453 MY |
705 | { .base = 0x00, .phy = &rk3288_win01_data, |
706 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
707 | { .base = 0x40, .phy = &rk3288_win01_data, | |
708 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
709 | { .base = 0x00, .phy = &rk3288_win23_data, | |
710 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
711 | { .base = 0x50, .phy = &rk3288_win23_data, | |
712 | .type = DRM_PLANE_TYPE_CURSOR }, | |
a67719d1 MY |
713 | }; |
714 | ||
715 | static const int rk3288_vop_intrs[] = { | |
716 | DSP_HOLD_VALID_INTR, | |
717 | FS_INTR, | |
718 | LINE_FLAG_INTR, | |
719 | BUS_ERROR_INTR, | |
720 | }; | |
721 | ||
722 | static const struct vop_intr rk3288_vop_intr = { | |
723 | .intrs = rk3288_vop_intrs, | |
724 | .nintrs = ARRAY_SIZE(rk3288_vop_intrs), | |
ac6560df | 725 | .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12), |
f7673453 MY |
726 | .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0), |
727 | .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4), | |
728 | .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), | |
a67719d1 MY |
729 | }; |
730 | ||
731 | static const struct vop_data rk3288_vop = { | |
eb5cb6aa | 732 | .version = VOP_VERSION(3, 1), |
efd11cc8 | 733 | .feature = VOP_FEATURE_OUTPUT_RGB10, |
a67719d1 | 734 | .intr = &rk3288_vop_intr, |
9a61c54b M |
735 | .common = &rk3288_common, |
736 | .modeset = &rk3288_modeset, | |
737 | .output = &rk3288_output, | |
a67719d1 MY |
738 | .win = rk3288_vop_win_data, |
739 | .win_size = ARRAY_SIZE(rk3288_vop_win_data), | |
b23ab6ac | 740 | .lut_size = 1024, |
8e140cb6 SH |
741 | /* |
742 | * This is the maximum resolution for the VOPB, the VOPL can only do | |
743 | * 2560x1600, but we can't distinguish them as they have the same | |
744 | * compatible. | |
745 | */ | |
746 | .max_output = { 3840, 2160 }, | |
a67719d1 MY |
747 | }; |
748 | ||
eb5cb6aa | 749 | static const int rk3368_vop_intrs[] = { |
f7673453 | 750 | FS_INTR, |
0a63bfd0 | 751 | 0, 0, |
f7673453 | 752 | LINE_FLAG_INTR, |
0a63bfd0 | 753 | 0, |
f7673453 | 754 | BUS_ERROR_INTR, |
0a63bfd0 MY |
755 | 0, 0, 0, 0, 0, 0, 0, |
756 | DSP_HOLD_VALID_INTR, | |
f7673453 MY |
757 | }; |
758 | ||
eb5cb6aa M |
759 | static const struct vop_intr rk3368_vop_intr = { |
760 | .intrs = rk3368_vop_intrs, | |
761 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
762 | .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0), | |
763 | .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16), | |
764 | .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0), | |
765 | .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0), | |
766 | .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0), | |
767 | }; | |
768 | ||
fbb1c738 EG |
769 | static const struct vop_win_phy rk3368_win01_data = { |
770 | .scl = &rk3288_win_full_scl, | |
771 | .data_formats = formats_win_full, | |
772 | .nformats = ARRAY_SIZE(formats_win_full), | |
7707f722 | 773 | .format_modifiers = format_modifiers_win_full, |
fbb1c738 EG |
774 | .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), |
775 | .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), | |
776 | .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12), | |
3fa50896 | 777 | .uv_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 15), |
677e8bbc DC |
778 | .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21), |
779 | .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22), | |
fbb1c738 EG |
780 | .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0), |
781 | .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
782 | .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0), | |
783 | .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0), | |
784 | .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0), | |
785 | .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0), | |
786 | .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16), | |
787 | .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
788 | .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
789 | .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0), | |
790 | }; | |
791 | ||
eb5cb6aa M |
792 | static const struct vop_win_phy rk3368_win23_data = { |
793 | .data_formats = formats_win_lite, | |
794 | .nformats = ARRAY_SIZE(formats_win_lite), | |
7707f722 | 795 | .format_modifiers = format_modifiers_win_lite, |
eb5cb6aa M |
796 | .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0), |
797 | .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4), | |
798 | .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), | |
799 | .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), | |
677e8bbc | 800 | .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15), |
eb5cb6aa M |
801 | .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), |
802 | .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), | |
803 | .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), | |
804 | .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0), | |
805 | .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0), | |
806 | .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0), | |
807 | }; | |
808 | ||
809 | static const struct vop_win_data rk3368_vop_win_data[] = { | |
fbb1c738 | 810 | { .base = 0x00, .phy = &rk3368_win01_data, |
eb5cb6aa | 811 | .type = DRM_PLANE_TYPE_PRIMARY }, |
fbb1c738 | 812 | { .base = 0x40, .phy = &rk3368_win01_data, |
eb5cb6aa M |
813 | .type = DRM_PLANE_TYPE_OVERLAY }, |
814 | { .base = 0x00, .phy = &rk3368_win23_data, | |
815 | .type = DRM_PLANE_TYPE_OVERLAY }, | |
816 | { .base = 0x50, .phy = &rk3368_win23_data, | |
817 | .type = DRM_PLANE_TYPE_CURSOR }, | |
818 | }; | |
819 | ||
820 | static const struct vop_output rk3368_output = { | |
1f6c62ca NY |
821 | .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19), |
822 | .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23), | |
823 | .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27), | |
824 | .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31), | |
825 | .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16), | |
826 | .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20), | |
827 | .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24), | |
828 | .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28), | |
eb5cb6aa M |
829 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), |
830 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
831 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
832 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
833 | }; | |
834 | ||
835 | static const struct vop_misc rk3368_misc = { | |
836 | .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11), | |
837 | }; | |
838 | ||
839 | static const struct vop_data rk3368_vop = { | |
840 | .version = VOP_VERSION(3, 2), | |
841 | .intr = &rk3368_vop_intr, | |
842 | .common = &rk3288_common, | |
843 | .modeset = &rk3288_modeset, | |
844 | .output = &rk3368_output, | |
845 | .misc = &rk3368_misc, | |
846 | .win = rk3368_vop_win_data, | |
847 | .win_size = ARRAY_SIZE(rk3368_vop_win_data), | |
8e140cb6 | 848 | .max_output = { 4096, 2160 }, |
eb5cb6aa M |
849 | }; |
850 | ||
851 | static const struct vop_intr rk3366_vop_intr = { | |
852 | .intrs = rk3368_vop_intrs, | |
853 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
854 | .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0), | |
855 | .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16), | |
856 | .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0), | |
857 | .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0), | |
858 | .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0), | |
859 | }; | |
860 | ||
861 | static const struct vop_data rk3366_vop = { | |
862 | .version = VOP_VERSION(3, 4), | |
863 | .intr = &rk3366_vop_intr, | |
864 | .common = &rk3288_common, | |
865 | .modeset = &rk3288_modeset, | |
866 | .output = &rk3368_output, | |
867 | .misc = &rk3368_misc, | |
868 | .win = rk3368_vop_win_data, | |
869 | .win_size = ARRAY_SIZE(rk3368_vop_win_data), | |
8e140cb6 | 870 | .max_output = { 4096, 2160 }, |
f7673453 MY |
871 | }; |
872 | ||
9a61c54b | 873 | static const struct vop_output rk3399_output = { |
1f6c62ca NY |
874 | .dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19), |
875 | .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19), | |
876 | .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23), | |
877 | .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27), | |
878 | .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31), | |
879 | .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16), | |
880 | .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16), | |
881 | .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20), | |
882 | .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24), | |
883 | .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28), | |
9a61c54b M |
884 | .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11), |
885 | .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12), | |
886 | .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13), | |
887 | .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14), | |
888 | .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15), | |
cf6d100d | 889 | .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3), |
9a61c54b M |
890 | }; |
891 | ||
3ba000d6 HCB |
892 | static const struct vop_common rk3399_common = { |
893 | .standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22), | |
894 | .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23), | |
895 | .mmu_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 20), | |
896 | .dither_down_sel = VOP_REG(RK3399_DSP_CTRL1, 0x1, 4), | |
897 | .dither_down_mode = VOP_REG(RK3399_DSP_CTRL1, 0x1, 3), | |
898 | .dither_down_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 2), | |
899 | .pre_dither_down = VOP_REG(RK3399_DSP_CTRL1, 0x1, 1), | |
900 | .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6), | |
901 | .dsp_lut_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 0), | |
902 | .update_gamma_lut = VOP_REG(RK3399_DSP_CTRL1, 0x1, 7), | |
903 | .lut_buffer_index = VOP_REG(RK3399_DBG_POST_REG1, 0x1, 1), | |
904 | .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19), | |
905 | .dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18), | |
906 | .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0), | |
907 | .cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0), | |
908 | }; | |
909 | ||
1c21aa8f DC |
910 | static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = { |
911 | .y2r_coefficients = { | |
912 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0), | |
913 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16), | |
914 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0), | |
915 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16), | |
916 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0), | |
917 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16), | |
918 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0), | |
919 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16), | |
920 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0), | |
921 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0), | |
922 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0), | |
923 | VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0), | |
924 | }, | |
925 | }; | |
926 | ||
927 | static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { }; | |
928 | ||
929 | static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = { | |
930 | { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, | |
931 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) }, | |
932 | { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data, | |
933 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) }, | |
934 | { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data }, | |
935 | { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data }, | |
7707f722 AP |
936 | |
937 | }; | |
938 | ||
939 | static const struct vop_win_phy rk3399_win01_data = { | |
940 | .scl = &rk3288_win_full_scl, | |
941 | .data_formats = formats_win_full, | |
942 | .nformats = ARRAY_SIZE(formats_win_full), | |
943 | .format_modifiers = format_modifiers_win_full_afbc, | |
944 | .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), | |
945 | .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), | |
946 | .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), | |
3fa50896 | 947 | .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15), |
9da1e9ab | 948 | .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21), |
7707f722 AP |
949 | .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), |
950 | .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), | |
951 | .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), | |
952 | .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0), | |
953 | .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0), | |
954 | .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0), | |
955 | .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0), | |
956 | .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), | |
957 | .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), | |
958 | .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), | |
9da1e9ab | 959 | .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0), |
7707f722 AP |
960 | }; |
961 | ||
962 | /* | |
963 | * rk3399 vop big windows register layout is same as rk3288, but we | |
964 | * have a separate rk3399 win data array here so that we can advertise | |
965 | * AFBC on the primary plane. | |
966 | */ | |
967 | static const struct vop_win_data rk3399_vop_win_data[] = { | |
968 | { .base = 0x00, .phy = &rk3399_win01_data, | |
969 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
9da1e9ab | 970 | { .base = 0x40, .phy = &rk3368_win01_data, |
7707f722 | 971 | .type = DRM_PLANE_TYPE_OVERLAY }, |
9da1e9ab | 972 | { .base = 0x00, .phy = &rk3368_win23_data, |
7707f722 | 973 | .type = DRM_PLANE_TYPE_OVERLAY }, |
9da1e9ab | 974 | { .base = 0x50, .phy = &rk3368_win23_data, |
7707f722 AP |
975 | .type = DRM_PLANE_TYPE_CURSOR }, |
976 | }; | |
977 | ||
978 | static const struct vop_afbc rk3399_vop_afbc = { | |
979 | .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3), | |
980 | .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0), | |
981 | .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1), | |
982 | .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16), | |
983 | .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21), | |
984 | .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0), | |
985 | .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0), | |
1c21aa8f DC |
986 | }; |
987 | ||
0a63bfd0 | 988 | static const struct vop_data rk3399_vop_big = { |
eb5cb6aa | 989 | .version = VOP_VERSION(3, 5), |
efd11cc8 | 990 | .feature = VOP_FEATURE_OUTPUT_RGB10, |
eb5cb6aa | 991 | .intr = &rk3366_vop_intr, |
3ba000d6 | 992 | .common = &rk3399_common, |
9a61c54b M |
993 | .modeset = &rk3288_modeset, |
994 | .output = &rk3399_output, | |
7707f722 | 995 | .afbc = &rk3399_vop_afbc, |
eb5cb6aa | 996 | .misc = &rk3368_misc, |
7707f722 AP |
997 | .win = rk3399_vop_win_data, |
998 | .win_size = ARRAY_SIZE(rk3399_vop_win_data), | |
1c21aa8f | 999 | .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data, |
3ba000d6 | 1000 | .lut_size = 1024, |
8e140cb6 | 1001 | .max_output = { 4096, 2160 }, |
f7673453 MY |
1002 | }; |
1003 | ||
0a63bfd0 | 1004 | static const struct vop_win_data rk3399_vop_lit_win_data[] = { |
fbb1c738 | 1005 | { .base = 0x00, .phy = &rk3368_win01_data, |
0a63bfd0 | 1006 | .type = DRM_PLANE_TYPE_PRIMARY }, |
eb5cb6aa | 1007 | { .base = 0x00, .phy = &rk3368_win23_data, |
0a63bfd0 MY |
1008 | .type = DRM_PLANE_TYPE_CURSOR}, |
1009 | }; | |
1010 | ||
1c21aa8f DC |
1011 | static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = { |
1012 | { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data, | |
1013 | .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)}, | |
1014 | { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data }, | |
1015 | }; | |
1016 | ||
0a63bfd0 | 1017 | static const struct vop_data rk3399_vop_lit = { |
eb5cb6aa M |
1018 | .version = VOP_VERSION(3, 6), |
1019 | .intr = &rk3366_vop_intr, | |
3ba000d6 | 1020 | .common = &rk3399_common, |
9a61c54b M |
1021 | .modeset = &rk3288_modeset, |
1022 | .output = &rk3399_output, | |
eb5cb6aa | 1023 | .misc = &rk3368_misc, |
0a63bfd0 MY |
1024 | .win = rk3399_vop_lit_win_data, |
1025 | .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), | |
1c21aa8f | 1026 | .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data, |
3ba000d6 | 1027 | .lut_size = 256, |
8e140cb6 | 1028 | .max_output = { 2560, 1600 }, |
f7673453 MY |
1029 | }; |
1030 | ||
eb5cb6aa M |
1031 | static const struct vop_win_data rk3228_vop_win_data[] = { |
1032 | { .base = 0x00, .phy = &rk3288_win01_data, | |
1033 | .type = DRM_PLANE_TYPE_PRIMARY }, | |
1034 | { .base = 0x40, .phy = &rk3288_win01_data, | |
1035 | .type = DRM_PLANE_TYPE_CURSOR }, | |
1036 | }; | |
1037 | ||
1038 | static const struct vop_data rk3228_vop = { | |
1039 | .version = VOP_VERSION(3, 7), | |
1040 | .feature = VOP_FEATURE_OUTPUT_RGB10, | |
1041 | .intr = &rk3366_vop_intr, | |
1042 | .common = &rk3288_common, | |
1043 | .modeset = &rk3288_modeset, | |
1044 | .output = &rk3399_output, | |
1045 | .misc = &rk3368_misc, | |
1046 | .win = rk3228_vop_win_data, | |
1047 | .win_size = ARRAY_SIZE(rk3228_vop_win_data), | |
8e140cb6 | 1048 | .max_output = { 4096, 2160 }, |
eb5cb6aa M |
1049 | }; |
1050 | ||
1051 | static const struct vop_modeset rk3328_modeset = { | |
1052 | .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), | |
1053 | .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0), | |
1054 | .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), | |
1055 | .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0), | |
1056 | .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0), | |
1057 | .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0), | |
1058 | }; | |
1059 | ||
1060 | static const struct vop_output rk3328_output = { | |
1f6c62ca NY |
1061 | .rgb_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 19), |
1062 | .hdmi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 23), | |
1063 | .edp_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 27), | |
1064 | .mipi_dclk_pol = VOP_REG(RK3328_DSP_CTRL1, 0x1, 31), | |
eb5cb6aa M |
1065 | .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12), |
1066 | .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13), | |
1067 | .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14), | |
1068 | .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15), | |
1f6c62ca NY |
1069 | .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 16), |
1070 | .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 20), | |
1071 | .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 24), | |
1072 | .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0x7, 28), | |
eb5cb6aa M |
1073 | }; |
1074 | ||
1075 | static const struct vop_misc rk3328_misc = { | |
1076 | .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11), | |
1077 | }; | |
1078 | ||
1079 | static const struct vop_common rk3328_common = { | |
1080 | .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22), | |
a5c0fa44 UR |
1081 | .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4), |
1082 | .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3), | |
1083 | .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2), | |
1084 | .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1), | |
eb5cb6aa M |
1085 | .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6), |
1086 | .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), | |
1087 | .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), | |
1088 | .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), | |
1089 | }; | |
1090 | ||
1091 | static const struct vop_intr rk3328_vop_intr = { | |
1092 | .intrs = rk3368_vop_intrs, | |
1093 | .nintrs = ARRAY_SIZE(rk3368_vop_intrs), | |
1094 | .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0), | |
1095 | .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16), | |
1096 | .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0), | |
1097 | .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0), | |
1098 | .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0), | |
1099 | }; | |
1100 | ||
1101 | static const struct vop_win_data rk3328_vop_win_data[] = { | |
fbb1c738 | 1102 | { .base = 0xd0, .phy = &rk3368_win01_data, |
eb5cb6aa | 1103 | .type = DRM_PLANE_TYPE_PRIMARY }, |
fbb1c738 | 1104 | { .base = 0x1d0, .phy = &rk3368_win01_data, |
eb5cb6aa | 1105 | .type = DRM_PLANE_TYPE_OVERLAY }, |
fbb1c738 | 1106 | { .base = 0x2d0, .phy = &rk3368_win01_data, |
eb5cb6aa M |
1107 | .type = DRM_PLANE_TYPE_CURSOR }, |
1108 | }; | |
1109 | ||
1110 | static const struct vop_data rk3328_vop = { | |
1111 | .version = VOP_VERSION(3, 8), | |
1112 | .feature = VOP_FEATURE_OUTPUT_RGB10, | |
1113 | .intr = &rk3328_vop_intr, | |
1114 | .common = &rk3328_common, | |
1115 | .modeset = &rk3328_modeset, | |
1116 | .output = &rk3328_output, | |
1117 | .misc = &rk3328_misc, | |
1118 | .win = rk3328_vop_win_data, | |
1119 | .win_size = ARRAY_SIZE(rk3328_vop_win_data), | |
8e140cb6 | 1120 | .max_output = { 4096, 2160 }, |
eb5cb6aa M |
1121 | }; |
1122 | ||
a67719d1 | 1123 | static const struct of_device_id vop_driver_dt_match[] = { |
f7673453 MY |
1124 | { .compatible = "rockchip,rk3036-vop", |
1125 | .data = &rk3036_vop }, | |
460c3b00 SH |
1126 | { .compatible = "rockchip,rk3126-vop", |
1127 | .data = &rk3126_vop }, | |
570913e0 SH |
1128 | { .compatible = "rockchip,px30-vop-big", |
1129 | .data = &px30_vop_big }, | |
1130 | { .compatible = "rockchip,px30-vop-lit", | |
1131 | .data = &px30_vop_lit }, | |
f4a6de85 MY |
1132 | { .compatible = "rockchip,rk3066-vop", |
1133 | .data = &rk3066_vop }, | |
428e15cc HS |
1134 | { .compatible = "rockchip,rk3188-vop", |
1135 | .data = &rk3188_vop }, | |
b51502ad MY |
1136 | { .compatible = "rockchip,rk3288-vop", |
1137 | .data = &rk3288_vop }, | |
eb5cb6aa M |
1138 | { .compatible = "rockchip,rk3368-vop", |
1139 | .data = &rk3368_vop }, | |
1140 | { .compatible = "rockchip,rk3366-vop", | |
1141 | .data = &rk3366_vop }, | |
0a63bfd0 MY |
1142 | { .compatible = "rockchip,rk3399-vop-big", |
1143 | .data = &rk3399_vop_big }, | |
1144 | { .compatible = "rockchip,rk3399-vop-lit", | |
1145 | .data = &rk3399_vop_lit }, | |
eb5cb6aa M |
1146 | { .compatible = "rockchip,rk3228-vop", |
1147 | .data = &rk3228_vop }, | |
1148 | { .compatible = "rockchip,rk3328-vop", | |
1149 | .data = &rk3328_vop }, | |
a67719d1 MY |
1150 | {}, |
1151 | }; | |
1152 | MODULE_DEVICE_TABLE(of, vop_driver_dt_match); | |
1153 | ||
1154 | static int vop_probe(struct platform_device *pdev) | |
1155 | { | |
1156 | struct device *dev = &pdev->dev; | |
1157 | ||
1158 | if (!dev->of_node) { | |
d8dd6804 | 1159 | DRM_DEV_ERROR(dev, "can't find vop devices\n"); |
a67719d1 MY |
1160 | return -ENODEV; |
1161 | } | |
1162 | ||
1163 | return component_add(dev, &vop_component_ops); | |
1164 | } | |
1165 | ||
3c855610 | 1166 | static void vop_remove(struct platform_device *pdev) |
a67719d1 MY |
1167 | { |
1168 | component_del(&pdev->dev, &vop_component_ops); | |
a67719d1 MY |
1169 | } |
1170 | ||
8820b68b | 1171 | struct platform_driver vop_platform_driver = { |
a67719d1 | 1172 | .probe = vop_probe, |
3c855610 | 1173 | .remove_new = vop_remove, |
a67719d1 MY |
1174 | .driver = { |
1175 | .name = "rockchip-vop", | |
87185cc8 | 1176 | .of_match_table = vop_driver_dt_match, |
a67719d1 MY |
1177 | }, |
1178 | }; |