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