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