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