Merge tag 'perf-core-2022-06-05' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / rockchip / rockchip_drm_vop2.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4  * Author: Andy Yan <andy.yan@rock-chips.com>
5  */
6 #include <linux/bitfield.h>
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/delay.h>
10 #include <linux/iopoll.h>
11 #include <linux/kernel.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/of_graph.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regmap.h>
20 #include <linux/swab.h>
21
22 #include <drm/drm.h>
23 #include <drm/drm_atomic.h>
24 #include <drm/drm_atomic_uapi.h>
25 #include <drm/drm_crtc.h>
26 #include <drm/drm_crtc_helper.h>
27 #include <drm/drm_debugfs.h>
28 #include <drm/drm_flip_work.h>
29 #include <drm/drm_plane_helper.h>
30 #include <drm/drm_probe_helper.h>
31 #include <drm/drm_vblank.h>
32
33 #include <uapi/linux/videodev2.h>
34 #include <dt-bindings/soc/rockchip,vop2.h>
35
36 #include "rockchip_drm_drv.h"
37 #include "rockchip_drm_gem.h"
38 #include "rockchip_drm_fb.h"
39 #include "rockchip_drm_vop2.h"
40
41 /*
42  * VOP2 architecture
43  *
44  +----------+   +-------------+                                                        +-----------+
45  |  Cluster |   | Sel 1 from 6|                                                        | 1 from 3  |
46  |  window0 |   |    Layer0   |                                                        |    RGB    |
47  +----------+   +-------------+              +---------------+    +-------------+      +-----------+
48  +----------+   +-------------+              |N from 6 layers|    |             |
49  |  Cluster |   | Sel 1 from 6|              |   Overlay0    +--->| Video Port0 |      +-----------+
50  |  window1 |   |    Layer1   |              |               |    |             |      | 1 from 3  |
51  +----------+   +-------------+              +---------------+    +-------------+      |   LVDS    |
52  +----------+   +-------------+                                                        +-----------+
53  |  Esmart  |   | Sel 1 from 6|
54  |  window0 |   |   Layer2    |              +---------------+    +-------------+      +-----------+
55  +----------+   +-------------+              |N from 6 Layers|    |             | +--> | 1 from 3  |
56  +----------+   +-------------+   -------->  |   Overlay1    +--->| Video Port1 |      |   MIPI    |
57  |  Esmart  |   | Sel 1 from 6|   -------->  |               |    |             |      +-----------+
58  |  Window1 |   |   Layer3    |              +---------------+    +-------------+
59  +----------+   +-------------+                                                        +-----------+
60  +----------+   +-------------+                                                        | 1 from 3  |
61  |  Smart   |   | Sel 1 from 6|              +---------------+    +-------------+      |   HDMI    |
62  |  Window0 |   |    Layer4   |              |N from 6 Layers|    |             |      +-----------+
63  +----------+   +-------------+              |   Overlay2    +--->| Video Port2 |
64  +----------+   +-------------+              |               |    |             |      +-----------+
65  |  Smart   |   | Sel 1 from 6|              +---------------+    +-------------+      |  1 from 3 |
66  |  Window1 |   |    Layer5   |                                                        |    eDP    |
67  +----------+   +-------------+                                                        +-----------+
68  *
69  */
70
71 enum vop2_data_format {
72         VOP2_FMT_ARGB8888 = 0,
73         VOP2_FMT_RGB888,
74         VOP2_FMT_RGB565,
75         VOP2_FMT_XRGB101010,
76         VOP2_FMT_YUV420SP,
77         VOP2_FMT_YUV422SP,
78         VOP2_FMT_YUV444SP,
79         VOP2_FMT_YUYV422 = 8,
80         VOP2_FMT_YUYV420,
81         VOP2_FMT_VYUY422,
82         VOP2_FMT_VYUY420,
83         VOP2_FMT_YUV420SP_TILE_8x4 = 0x10,
84         VOP2_FMT_YUV420SP_TILE_16x2,
85         VOP2_FMT_YUV422SP_TILE_8x4,
86         VOP2_FMT_YUV422SP_TILE_16x2,
87         VOP2_FMT_YUV420SP_10,
88         VOP2_FMT_YUV422SP_10,
89         VOP2_FMT_YUV444SP_10,
90 };
91
92 enum vop2_afbc_format {
93         VOP2_AFBC_FMT_RGB565,
94         VOP2_AFBC_FMT_ARGB2101010 = 2,
95         VOP2_AFBC_FMT_YUV420_10BIT,
96         VOP2_AFBC_FMT_RGB888,
97         VOP2_AFBC_FMT_ARGB8888,
98         VOP2_AFBC_FMT_YUV420 = 9,
99         VOP2_AFBC_FMT_YUV422 = 0xb,
100         VOP2_AFBC_FMT_YUV422_10BIT = 0xe,
101         VOP2_AFBC_FMT_INVALID = -1,
102 };
103
104 union vop2_alpha_ctrl {
105         u32 val;
106         struct {
107                 /* [0:1] */
108                 u32 color_mode:1;
109                 u32 alpha_mode:1;
110                 /* [2:3] */
111                 u32 blend_mode:2;
112                 u32 alpha_cal_mode:1;
113                 /* [5:7] */
114                 u32 factor_mode:3;
115                 /* [8:9] */
116                 u32 alpha_en:1;
117                 u32 src_dst_swap:1;
118                 u32 reserved:6;
119                 /* [16:23] */
120                 u32 glb_alpha:8;
121         } bits;
122 };
123
124 struct vop2_alpha {
125         union vop2_alpha_ctrl src_color_ctrl;
126         union vop2_alpha_ctrl dst_color_ctrl;
127         union vop2_alpha_ctrl src_alpha_ctrl;
128         union vop2_alpha_ctrl dst_alpha_ctrl;
129 };
130
131 struct vop2_alpha_config {
132         bool src_premulti_en;
133         bool dst_premulti_en;
134         bool src_pixel_alpha_en;
135         bool dst_pixel_alpha_en;
136         u16 src_glb_alpha_value;
137         u16 dst_glb_alpha_value;
138 };
139
140 struct vop2_win {
141         struct vop2 *vop2;
142         struct drm_plane base;
143         const struct vop2_win_data *data;
144         struct regmap_field *reg[VOP2_WIN_MAX_REG];
145
146         /**
147          * @win_id: graphic window id, a cluster may be split into two
148          * graphics windows.
149          */
150         u8 win_id;
151         u8 delay;
152         u32 offset;
153
154         enum drm_plane_type type;
155 };
156
157 struct vop2_video_port {
158         struct drm_crtc crtc;
159         struct vop2 *vop2;
160         struct clk *dclk;
161         unsigned int id;
162         const struct vop2_video_port_regs *regs;
163         const struct vop2_video_port_data *data;
164
165         struct completion dsp_hold_completion;
166
167         /**
168          * @win_mask: Bitmask of windows attached to the video port;
169          */
170         u32 win_mask;
171
172         struct vop2_win *primary_plane;
173         struct drm_pending_vblank_event *event;
174
175         unsigned int nlayers;
176 };
177
178 struct vop2 {
179         struct device *dev;
180         struct drm_device *drm;
181         struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
182
183         const struct vop2_data *data;
184         /*
185          * Number of windows that are registered as plane, may be less than the
186          * total number of hardware windows.
187          */
188         u32 registered_num_wins;
189
190         void __iomem *regs;
191         struct regmap *map;
192
193         struct regmap *grf;
194
195         /* physical map length of vop2 register */
196         u32 len;
197
198         void __iomem *lut_regs;
199
200         /* protects crtc enable/disable */
201         struct mutex vop2_lock;
202
203         int irq;
204
205         /*
206          * Some global resources are shared between all video ports(crtcs), so
207          * we need a ref counter here.
208          */
209         unsigned int enable_count;
210         struct clk *hclk;
211         struct clk *aclk;
212
213         /* must be put at the end of the struct */
214         struct vop2_win win[];
215 };
216
217 static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
218 {
219         return container_of(crtc, struct vop2_video_port, crtc);
220 }
221
222 static struct vop2_win *to_vop2_win(struct drm_plane *p)
223 {
224         return container_of(p, struct vop2_win, base);
225 }
226
227 static void vop2_lock(struct vop2 *vop2)
228 {
229         mutex_lock(&vop2->vop2_lock);
230 }
231
232 static void vop2_unlock(struct vop2 *vop2)
233 {
234         mutex_unlock(&vop2->vop2_lock);
235 }
236
237 static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
238 {
239         regmap_write(vop2->map, offset, v);
240 }
241
242 static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
243 {
244         regmap_write(vp->vop2->map, vp->data->offset + offset, v);
245 }
246
247 static u32 vop2_readl(struct vop2 *vop2, u32 offset)
248 {
249         u32 val;
250
251         regmap_read(vop2->map, offset, &val);
252
253         return val;
254 }
255
256 static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
257 {
258         regmap_field_write(win->reg[reg], v);
259 }
260
261 static bool vop2_cluster_window(const struct vop2_win *win)
262 {
263         return win->data->feature & WIN_FEATURE_CLUSTER;
264 }
265
266 static void vop2_cfg_done(struct vop2_video_port *vp)
267 {
268         struct vop2 *vop2 = vp->vop2;
269
270         regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE,
271                         BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
272 }
273
274 static void vop2_win_disable(struct vop2_win *win)
275 {
276         vop2_win_write(win, VOP2_WIN_ENABLE, 0);
277
278         if (vop2_cluster_window(win))
279                 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0);
280 }
281
282 static enum vop2_data_format vop2_convert_format(u32 format)
283 {
284         switch (format) {
285         case DRM_FORMAT_XRGB8888:
286         case DRM_FORMAT_ARGB8888:
287         case DRM_FORMAT_XBGR8888:
288         case DRM_FORMAT_ABGR8888:
289                 return VOP2_FMT_ARGB8888;
290         case DRM_FORMAT_RGB888:
291         case DRM_FORMAT_BGR888:
292                 return VOP2_FMT_RGB888;
293         case DRM_FORMAT_RGB565:
294         case DRM_FORMAT_BGR565:
295                 return VOP2_FMT_RGB565;
296         case DRM_FORMAT_NV12:
297                 return VOP2_FMT_YUV420SP;
298         case DRM_FORMAT_NV16:
299                 return VOP2_FMT_YUV422SP;
300         case DRM_FORMAT_NV24:
301                 return VOP2_FMT_YUV444SP;
302         case DRM_FORMAT_YUYV:
303         case DRM_FORMAT_YVYU:
304                 return VOP2_FMT_VYUY422;
305         case DRM_FORMAT_VYUY:
306         case DRM_FORMAT_UYVY:
307                 return VOP2_FMT_YUYV422;
308         default:
309                 DRM_ERROR("unsupported format[%08x]\n", format);
310                 return -EINVAL;
311         }
312 }
313
314 static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
315 {
316         switch (format) {
317         case DRM_FORMAT_XRGB8888:
318         case DRM_FORMAT_ARGB8888:
319         case DRM_FORMAT_XBGR8888:
320         case DRM_FORMAT_ABGR8888:
321                 return VOP2_AFBC_FMT_ARGB8888;
322         case DRM_FORMAT_RGB888:
323         case DRM_FORMAT_BGR888:
324                 return VOP2_AFBC_FMT_RGB888;
325         case DRM_FORMAT_RGB565:
326         case DRM_FORMAT_BGR565:
327                 return VOP2_AFBC_FMT_RGB565;
328         case DRM_FORMAT_NV12:
329                 return VOP2_AFBC_FMT_YUV420;
330         case DRM_FORMAT_NV16:
331                 return VOP2_AFBC_FMT_YUV422;
332         default:
333                 return VOP2_AFBC_FMT_INVALID;
334         }
335
336         return VOP2_AFBC_FMT_INVALID;
337 }
338
339 static bool vop2_win_rb_swap(u32 format)
340 {
341         switch (format) {
342         case DRM_FORMAT_XBGR8888:
343         case DRM_FORMAT_ABGR8888:
344         case DRM_FORMAT_BGR888:
345         case DRM_FORMAT_BGR565:
346                 return true;
347         default:
348                 return false;
349         }
350 }
351
352 static bool vop2_afbc_rb_swap(u32 format)
353 {
354         switch (format) {
355         case DRM_FORMAT_NV24:
356                 return true;
357         default:
358                 return false;
359         }
360 }
361
362 static bool vop2_afbc_uv_swap(u32 format)
363 {
364         switch (format) {
365         case DRM_FORMAT_NV12:
366         case DRM_FORMAT_NV16:
367                 return true;
368         default:
369                 return false;
370         }
371 }
372
373 static bool vop2_win_uv_swap(u32 format)
374 {
375         switch (format) {
376         case DRM_FORMAT_NV12:
377         case DRM_FORMAT_NV16:
378         case DRM_FORMAT_NV24:
379                 return true;
380         default:
381                 return false;
382         }
383 }
384
385 static bool vop2_win_dither_up(u32 format)
386 {
387         switch (format) {
388         case DRM_FORMAT_BGR565:
389         case DRM_FORMAT_RGB565:
390                 return true;
391         default:
392                 return false;
393         }
394 }
395
396 static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
397 {
398         /*
399          * FIXME:
400          *
401          * There is no media type for YUV444 output,
402          * so when out_mode is AAAA or P888, assume output is YUV444 on
403          * yuv format.
404          *
405          * From H/W testing, YUV444 mode need a rb swap.
406          */
407         if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
408             bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
409             bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
410             bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
411             ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
412               bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
413              (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
414               output_mode == ROCKCHIP_OUT_MODE_P888)))
415                 return true;
416         else
417                 return false;
418 }
419
420 static bool is_yuv_output(u32 bus_format)
421 {
422         switch (bus_format) {
423         case MEDIA_BUS_FMT_YUV8_1X24:
424         case MEDIA_BUS_FMT_YUV10_1X30:
425         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
426         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
427         case MEDIA_BUS_FMT_YUYV8_2X8:
428         case MEDIA_BUS_FMT_YVYU8_2X8:
429         case MEDIA_BUS_FMT_UYVY8_2X8:
430         case MEDIA_BUS_FMT_VYUY8_2X8:
431         case MEDIA_BUS_FMT_YUYV8_1X16:
432         case MEDIA_BUS_FMT_YVYU8_1X16:
433         case MEDIA_BUS_FMT_UYVY8_1X16:
434         case MEDIA_BUS_FMT_VYUY8_1X16:
435                 return true;
436         default:
437                 return false;
438         }
439 }
440
441 static bool rockchip_afbc(struct drm_plane *plane, u64 modifier)
442 {
443         int i;
444
445         if (modifier == DRM_FORMAT_MOD_LINEAR)
446                 return false;
447
448         for (i = 0 ; i < plane->modifier_count; i++)
449                 if (plane->modifiers[i] == modifier)
450                         return true;
451
452         return false;
453 }
454
455 static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
456                                         u64 modifier)
457 {
458         struct vop2_win *win = to_vop2_win(plane);
459         struct vop2 *vop2 = win->vop2;
460
461         if (modifier == DRM_FORMAT_MOD_INVALID)
462                 return false;
463
464         if (modifier == DRM_FORMAT_MOD_LINEAR)
465                 return true;
466
467         if (!rockchip_afbc(plane, modifier)) {
468                 drm_err(vop2->drm, "Unsupported format modifier 0x%llx\n",
469                         modifier);
470
471                 return false;
472         }
473
474         return vop2_convert_afbc_format(format) >= 0;
475 }
476
477 static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
478                                       bool afbc_half_block_en)
479 {
480         struct drm_rect *src = &pstate->src;
481         struct drm_framebuffer *fb = pstate->fb;
482         u32 bpp = fb->format->cpp[0] * 8;
483         u32 vir_width = (fb->pitches[0] << 3) / bpp;
484         u32 width = drm_rect_width(src) >> 16;
485         u32 height = drm_rect_height(src) >> 16;
486         u32 act_xoffset = src->x1 >> 16;
487         u32 act_yoffset = src->y1 >> 16;
488         u32 align16_crop = 0;
489         u32 align64_crop = 0;
490         u32 height_tmp;
491         u8 tx, ty;
492         u8 bottom_crop_line_num = 0;
493
494         /* 16 pixel align */
495         if (height & 0xf)
496                 align16_crop = 16 - (height & 0xf);
497
498         height_tmp = height + align16_crop;
499
500         /* 64 pixel align */
501         if (height_tmp & 0x3f)
502                 align64_crop = 64 - (height_tmp & 0x3f);
503
504         bottom_crop_line_num = align16_crop + align64_crop;
505
506         switch (pstate->rotation &
507                 (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y |
508                  DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270)) {
509         case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y:
510                 tx = 16 - ((act_xoffset + width) & 0xf);
511                 ty = bottom_crop_line_num - act_yoffset;
512                 break;
513         case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90:
514                 tx = bottom_crop_line_num - act_yoffset;
515                 ty = vir_width - width - act_xoffset;
516                 break;
517         case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270:
518                 tx = act_yoffset;
519                 ty = act_xoffset;
520                 break;
521         case DRM_MODE_REFLECT_X:
522                 tx = 16 - ((act_xoffset + width) & 0xf);
523                 ty = act_yoffset;
524                 break;
525         case DRM_MODE_REFLECT_Y:
526                 tx = act_xoffset;
527                 ty = bottom_crop_line_num - act_yoffset;
528                 break;
529         case DRM_MODE_ROTATE_90:
530                 tx = bottom_crop_line_num - act_yoffset;
531                 ty = act_xoffset;
532                 break;
533         case DRM_MODE_ROTATE_270:
534                 tx = act_yoffset;
535                 ty = vir_width - width - act_xoffset;
536                 break;
537         case 0:
538                 tx = act_xoffset;
539                 ty = act_yoffset;
540                 break;
541         }
542
543         if (afbc_half_block_en)
544                 ty &= 0x7f;
545
546 #define TRANSFORM_XOFFSET GENMASK(7, 0)
547 #define TRANSFORM_YOFFSET GENMASK(23, 16)
548         return FIELD_PREP(TRANSFORM_XOFFSET, tx) |
549                 FIELD_PREP(TRANSFORM_YOFFSET, ty);
550 }
551
552 /*
553  * A Cluster window has 2048 x 16 line buffer, which can
554  * works at 2048 x 16(Full) or 4096 x 8 (Half) mode.
555  * for Cluster_lb_mode register:
556  * 0: half mode, for plane input width range 2048 ~ 4096
557  * 1: half mode, for cluster work at 2 * 2048 plane mode
558  * 2: half mode, for rotate_90/270 mode
559  *
560  */
561 static int vop2_get_cluster_lb_mode(struct vop2_win *win,
562                                     struct drm_plane_state *pstate)
563 {
564         if ((pstate->rotation & DRM_MODE_ROTATE_270) ||
565             (pstate->rotation & DRM_MODE_ROTATE_90))
566                 return 2;
567         else
568                 return 0;
569 }
570
571 static u16 vop2_scale_factor(u32 src, u32 dst)
572 {
573         u32 fac;
574         int shift;
575
576         if (src == dst)
577                 return 0;
578
579         if (dst < 2)
580                 return U16_MAX;
581
582         if (src < 2)
583                 return 0;
584
585         if (src > dst)
586                 shift = 12;
587         else
588                 shift = 16;
589
590         src--;
591         dst--;
592
593         fac = DIV_ROUND_UP(src << shift, dst) - 1;
594
595         if (fac > U16_MAX)
596                 return U16_MAX;
597
598         return fac;
599 }
600
601 static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
602                              u32 src_w, u32 src_h, u32 dst_w,
603                              u32 dst_h, u32 pixel_format)
604 {
605         const struct drm_format_info *info;
606         u16 hor_scl_mode, ver_scl_mode;
607         u16 hscl_filter_mode, vscl_filter_mode;
608         u8 gt2 = 0;
609         u8 gt4 = 0;
610         u32 val;
611
612         info = drm_format_info(pixel_format);
613
614         if (src_h >= (4 * dst_h)) {
615                 gt4 = 1;
616                 src_h >>= 2;
617         } else if (src_h >= (2 * dst_h)) {
618                 gt2 = 1;
619                 src_h >>= 1;
620         }
621
622         hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
623         ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
624
625         if (hor_scl_mode == SCALE_UP)
626                 hscl_filter_mode = VOP2_SCALE_UP_BIC;
627         else
628                 hscl_filter_mode = VOP2_SCALE_DOWN_BIL;
629
630         if (ver_scl_mode == SCALE_UP)
631                 vscl_filter_mode = VOP2_SCALE_UP_BIL;
632         else
633                 vscl_filter_mode = VOP2_SCALE_DOWN_BIL;
634
635         /*
636          * RK3568 VOP Esmart/Smart dsp_w should be even pixel
637          * at scale down mode
638          */
639         if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
640                 if ((hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) {
641                         drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n",
642                                 win->data->name, dst_w);
643                         dst_w++;
644                 }
645         }
646
647         val = vop2_scale_factor(src_w, dst_w);
648         vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val);
649         val = vop2_scale_factor(src_h, dst_h);
650         vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val);
651
652         vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4);
653         vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2);
654
655         vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, hor_scl_mode);
656         vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, ver_scl_mode);
657
658         if (vop2_cluster_window(win))
659                 return;
660
661         vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode);
662         vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode);
663
664         if (info->is_yuv) {
665                 src_w /= info->hsub;
666                 src_h /= info->vsub;
667
668                 gt4 = 0;
669                 gt2 = 0;
670
671                 if (src_h >= (4 * dst_h)) {
672                         gt4 = 1;
673                         src_h >>= 2;
674                 } else if (src_h >= (2 * dst_h)) {
675                         gt2 = 1;
676                         src_h >>= 1;
677                 }
678
679                 hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
680                 ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
681
682                 val = vop2_scale_factor(src_w, dst_w);
683                 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val);
684
685                 val = vop2_scale_factor(src_h, dst_h);
686                 vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val);
687
688                 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4);
689                 vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2);
690                 vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, hor_scl_mode);
691                 vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, ver_scl_mode);
692                 vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode);
693                 vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode);
694         }
695 }
696
697 static int vop2_convert_csc_mode(int csc_mode)
698 {
699         switch (csc_mode) {
700         case V4L2_COLORSPACE_SMPTE170M:
701         case V4L2_COLORSPACE_470_SYSTEM_M:
702         case V4L2_COLORSPACE_470_SYSTEM_BG:
703                 return CSC_BT601L;
704         case V4L2_COLORSPACE_REC709:
705         case V4L2_COLORSPACE_SMPTE240M:
706         case V4L2_COLORSPACE_DEFAULT:
707                 return CSC_BT709L;
708         case V4L2_COLORSPACE_JPEG:
709                 return CSC_BT601F;
710         case V4L2_COLORSPACE_BT2020:
711                 return CSC_BT2020;
712         default:
713                 return CSC_BT709L;
714         }
715 }
716
717 /*
718  * colorspace path:
719  *      Input        Win csc                     Output
720  * 1. YUV(2020)  --> Y2R->2020To709->R2Y   --> YUV_OUTPUT(601/709)
721  *    RGB        --> R2Y                  __/
722  *
723  * 2. YUV(2020)  --> bypasss               --> YUV_OUTPUT(2020)
724  *    RGB        --> 709To2020->R2Y       __/
725  *
726  * 3. YUV(2020)  --> Y2R->2020To709        --> RGB_OUTPUT(709)
727  *    RGB        --> R2Y                  __/
728  *
729  * 4. YUV(601/709)-> Y2R->709To2020->R2Y   --> YUV_OUTPUT(2020)
730  *    RGB        --> 709To2020->R2Y       __/
731  *
732  * 5. YUV(601/709)-> bypass                --> YUV_OUTPUT(709)
733  *    RGB        --> R2Y                  __/
734  *
735  * 6. YUV(601/709)-> bypass                --> YUV_OUTPUT(601)
736  *    RGB        --> R2Y(601)             __/
737  *
738  * 7. YUV        --> Y2R(709)              --> RGB_OUTPUT(709)
739  *    RGB        --> bypass               __/
740  *
741  * 8. RGB        --> 709To2020->R2Y        --> YUV_OUTPUT(2020)
742  *
743  * 9. RGB        --> R2Y(709)              --> YUV_OUTPUT(709)
744  *
745  * 10. RGB       --> R2Y(601)              --> YUV_OUTPUT(601)
746  *
747  * 11. RGB       --> bypass                --> RGB_OUTPUT(709)
748  */
749
750 static void vop2_setup_csc_mode(struct vop2_video_port *vp,
751                                 struct vop2_win *win,
752                                 struct drm_plane_state *pstate)
753 {
754         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
755         int is_input_yuv = pstate->fb->format->is_yuv;
756         int is_output_yuv = is_yuv_output(vcstate->bus_format);
757         int input_csc = V4L2_COLORSPACE_DEFAULT;
758         int output_csc = vcstate->color_space;
759         bool r2y_en, y2r_en;
760         int csc_mode;
761
762         if (is_input_yuv && !is_output_yuv) {
763                 y2r_en = true;
764                 r2y_en = false;
765                 csc_mode = vop2_convert_csc_mode(input_csc);
766         } else if (!is_input_yuv && is_output_yuv) {
767                 y2r_en = false;
768                 r2y_en = true;
769                 csc_mode = vop2_convert_csc_mode(output_csc);
770         } else {
771                 y2r_en = false;
772                 r2y_en = false;
773                 csc_mode = false;
774         }
775
776         vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
777         vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en);
778         vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode);
779 }
780
781 static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq)
782 {
783         struct vop2 *vop2 = vp->vop2;
784
785         vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq);
786         vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq);
787 }
788
789 static void vop2_crtc_disable_irq(struct vop2_video_port *vp, u32 irq)
790 {
791         struct vop2 *vop2 = vp->vop2;
792
793         vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16);
794 }
795
796 static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
797 {
798         int ret;
799
800         ret = clk_prepare_enable(vop2->hclk);
801         if (ret < 0) {
802                 drm_err(vop2->drm, "failed to enable hclk - %d\n", ret);
803                 return ret;
804         }
805
806         ret = clk_prepare_enable(vop2->aclk);
807         if (ret < 0) {
808                 drm_err(vop2->drm, "failed to enable aclk - %d\n", ret);
809                 goto err;
810         }
811
812         return 0;
813 err:
814         clk_disable_unprepare(vop2->hclk);
815
816         return ret;
817 }
818
819 static void vop2_enable(struct vop2 *vop2)
820 {
821         int ret;
822
823         ret = pm_runtime_get_sync(vop2->dev);
824         if (ret < 0) {
825                 drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
826                 return;
827         }
828
829         ret = vop2_core_clks_prepare_enable(vop2);
830         if (ret) {
831                 pm_runtime_put_sync(vop2->dev);
832                 return;
833         }
834
835         ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
836         if (ret) {
837                 drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
838                 return;
839         }
840
841         if (vop2->data->soc_id == 3566)
842                 vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
843
844         vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
845
846         /*
847          * Disable auto gating, this is a workaround to
848          * avoid display image shift when a window enabled.
849          */
850         regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL,
851                           RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN);
852
853         vop2_writel(vop2, RK3568_SYS0_INT_CLR,
854                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
855         vop2_writel(vop2, RK3568_SYS0_INT_EN,
856                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
857         vop2_writel(vop2, RK3568_SYS1_INT_CLR,
858                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
859         vop2_writel(vop2, RK3568_SYS1_INT_EN,
860                     VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
861 }
862
863 static void vop2_disable(struct vop2 *vop2)
864 {
865         rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
866
867         pm_runtime_put_sync(vop2->dev);
868
869         clk_disable_unprepare(vop2->aclk);
870         clk_disable_unprepare(vop2->hclk);
871 }
872
873 static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
874                                      struct drm_atomic_state *state)
875 {
876         struct vop2_video_port *vp = to_vop2_video_port(crtc);
877         struct vop2 *vop2 = vp->vop2;
878         int ret;
879
880         vop2_lock(vop2);
881
882         drm_crtc_vblank_off(crtc);
883
884         /*
885          * Vop standby will take effect at end of current frame,
886          * if dsp hold valid irq happen, it means standby complete.
887          *
888          * we must wait standby complete when we want to disable aclk,
889          * if not, memory bus maybe dead.
890          */
891         reinit_completion(&vp->dsp_hold_completion);
892
893         vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID);
894
895         vop2_vp_write(vp, RK3568_VP_DSP_CTRL, RK3568_VP_DSP_CTRL__STANDBY);
896
897         ret = wait_for_completion_timeout(&vp->dsp_hold_completion,
898                                           msecs_to_jiffies(50));
899         if (!ret)
900                 drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id);
901
902         vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
903
904         clk_disable_unprepare(vp->dclk);
905
906         vop2->enable_count--;
907
908         if (!vop2->enable_count)
909                 vop2_disable(vop2);
910
911         vop2_unlock(vop2);
912
913         if (crtc->state->event && !crtc->state->active) {
914                 spin_lock_irq(&crtc->dev->event_lock);
915                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
916                 spin_unlock_irq(&crtc->dev->event_lock);
917
918                 crtc->state->event = NULL;
919         }
920 }
921
922 static int vop2_plane_atomic_check(struct drm_plane *plane,
923                                    struct drm_atomic_state *astate)
924 {
925         struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane);
926         struct drm_framebuffer *fb = pstate->fb;
927         struct drm_crtc *crtc = pstate->crtc;
928         struct drm_crtc_state *cstate;
929         struct vop2_video_port *vp;
930         struct vop2 *vop2;
931         const struct vop2_data *vop2_data;
932         struct drm_rect *dest = &pstate->dst;
933         struct drm_rect *src = &pstate->src;
934         int min_scale = FRAC_16_16(1, 8);
935         int max_scale = FRAC_16_16(8, 1);
936         int format;
937         int ret;
938
939         if (!crtc)
940                 return 0;
941
942         vp = to_vop2_video_port(crtc);
943         vop2 = vp->vop2;
944         vop2_data = vop2->data;
945
946         cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc);
947         if (WARN_ON(!cstate))
948                 return -EINVAL;
949
950         ret = drm_atomic_helper_check_plane_state(pstate, cstate,
951                                                   min_scale, max_scale,
952                                                   true, true);
953         if (ret)
954                 return ret;
955
956         if (!pstate->visible)
957                 return 0;
958
959         format = vop2_convert_format(fb->format->format);
960         if (format < 0)
961                 return format;
962
963         if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 ||
964             drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) {
965                 drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n",
966                         drm_rect_width(src) >> 16, drm_rect_height(src) >> 16,
967                         drm_rect_width(dest), drm_rect_height(dest));
968                 pstate->visible = false;
969                 return 0;
970         }
971
972         if (drm_rect_width(src) >> 16 > vop2_data->max_input.width ||
973             drm_rect_height(src) >> 16 > vop2_data->max_input.height) {
974                 drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n",
975                         drm_rect_width(src) >> 16,
976                         drm_rect_height(src) >> 16,
977                         vop2_data->max_input.width,
978                         vop2_data->max_input.height);
979                 return -EINVAL;
980         }
981
982         /*
983          * Src.x1 can be odd when do clip, but yuv plane start point
984          * need align with 2 pixel.
985          */
986         if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) {
987                 drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n");
988                 return -EINVAL;
989         }
990
991         return 0;
992 }
993
994 static void vop2_plane_atomic_disable(struct drm_plane *plane,
995                                       struct drm_atomic_state *state)
996 {
997         struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane);
998         struct vop2_win *win = to_vop2_win(plane);
999         struct vop2 *vop2 = win->vop2;
1000
1001         drm_dbg(vop2->drm, "%s disable\n", win->data->name);
1002
1003         if (!old_pstate->crtc)
1004                 return;
1005
1006         vop2_win_disable(win);
1007         vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
1008 }
1009
1010 /*
1011  * The color key is 10 bit, so all format should
1012  * convert to 10 bit here.
1013  */
1014 static void vop2_plane_setup_color_key(struct drm_plane *plane, u32 color_key)
1015 {
1016         struct drm_plane_state *pstate = plane->state;
1017         struct drm_framebuffer *fb = pstate->fb;
1018         struct vop2_win *win = to_vop2_win(plane);
1019         u32 color_key_en = 0;
1020         u32 r = 0;
1021         u32 g = 0;
1022         u32 b = 0;
1023
1024         if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) {
1025                 vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0);
1026                 return;
1027         }
1028
1029         switch (fb->format->format) {
1030         case DRM_FORMAT_RGB565:
1031         case DRM_FORMAT_BGR565:
1032                 r = (color_key & 0xf800) >> 11;
1033                 g = (color_key & 0x7e0) >> 5;
1034                 b = (color_key & 0x1f);
1035                 r <<= 5;
1036                 g <<= 4;
1037                 b <<= 5;
1038                 color_key_en = 1;
1039                 break;
1040         case DRM_FORMAT_XRGB8888:
1041         case DRM_FORMAT_ARGB8888:
1042         case DRM_FORMAT_XBGR8888:
1043         case DRM_FORMAT_ABGR8888:
1044         case DRM_FORMAT_RGB888:
1045         case DRM_FORMAT_BGR888:
1046                 r = (color_key & 0xff0000) >> 16;
1047                 g = (color_key & 0xff00) >> 8;
1048                 b = (color_key & 0xff);
1049                 r <<= 2;
1050                 g <<= 2;
1051                 b <<= 2;
1052                 color_key_en = 1;
1053                 break;
1054         }
1055
1056         vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en);
1057         vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b);
1058 }
1059
1060 static void vop2_plane_atomic_update(struct drm_plane *plane,
1061                                      struct drm_atomic_state *state)
1062 {
1063         struct drm_plane_state *pstate = plane->state;
1064         struct drm_crtc *crtc = pstate->crtc;
1065         struct vop2_win *win = to_vop2_win(plane);
1066         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1067         struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
1068         struct vop2 *vop2 = win->vop2;
1069         struct drm_framebuffer *fb = pstate->fb;
1070         u32 bpp = fb->format->cpp[0] * 8;
1071         u32 actual_w, actual_h, dsp_w, dsp_h;
1072         u32 act_info, dsp_info;
1073         u32 format;
1074         u32 afbc_format;
1075         u32 rb_swap;
1076         u32 uv_swap;
1077         struct drm_rect *src = &pstate->src;
1078         struct drm_rect *dest = &pstate->dst;
1079         u32 afbc_tile_num;
1080         u32 transform_offset;
1081         bool dither_up;
1082         bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
1083         bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
1084         bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
1085         bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
1086         struct rockchip_gem_object *rk_obj;
1087         unsigned long offset;
1088         bool afbc_en;
1089         dma_addr_t yrgb_mst;
1090         dma_addr_t uv_mst;
1091
1092         /*
1093          * can't update plane when vop2 is disabled.
1094          */
1095         if (WARN_ON(!crtc))
1096                 return;
1097
1098         if (!pstate->visible) {
1099                 vop2_plane_atomic_disable(plane, state);
1100                 return;
1101         }
1102
1103         afbc_en = rockchip_afbc(plane, fb->modifier);
1104
1105         offset = (src->x1 >> 16) * fb->format->cpp[0];
1106
1107         /*
1108          * AFBC HDR_PTR must set to the zero offset of the framebuffer.
1109          */
1110         if (afbc_en)
1111                 offset = 0;
1112         else if (pstate->rotation & DRM_MODE_REFLECT_Y)
1113                 offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
1114         else
1115                 offset += (src->y1 >> 16) * fb->pitches[0];
1116
1117         rk_obj = to_rockchip_obj(fb->obj[0]);
1118
1119         yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
1120         if (fb->format->is_yuv) {
1121                 int hsub = fb->format->hsub;
1122                 int vsub = fb->format->vsub;
1123
1124                 offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
1125                 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
1126
1127                 if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en)
1128                         offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub;
1129
1130                 rk_obj = to_rockchip_obj(fb->obj[0]);
1131                 uv_mst = rk_obj->dma_addr + offset + fb->offsets[1];
1132         }
1133
1134         actual_w = drm_rect_width(src) >> 16;
1135         actual_h = drm_rect_height(src) >> 16;
1136         dsp_w = drm_rect_width(dest);
1137
1138         if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
1139                 drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
1140                         vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay);
1141                 dsp_w = adjusted_mode->hdisplay - dest->x1;
1142                 if (dsp_w < 4)
1143                         dsp_w = 4;
1144                 actual_w = dsp_w * actual_w / drm_rect_width(dest);
1145         }
1146
1147         dsp_h = drm_rect_height(dest);
1148
1149         if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
1150                 drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
1151                         vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay);
1152                 dsp_h = adjusted_mode->vdisplay - dest->y1;
1153                 if (dsp_h < 4)
1154                         dsp_h = 4;
1155                 actual_h = dsp_h * actual_h / drm_rect_height(dest);
1156         }
1157
1158         /*
1159          * This is workaround solution for IC design:
1160          * esmart can't support scale down when actual_w % 16 == 1.
1161          */
1162         if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
1163                 if (actual_w > dsp_w && (actual_w & 0xf) == 1) {
1164                         drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n",
1165                                 vp->id, win->data->name, actual_w);
1166                         actual_w -= 1;
1167                 }
1168         }
1169
1170         if (afbc_en && actual_w % 4) {
1171                 drm_err(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n",
1172                         vp->id, win->data->name, actual_w);
1173                 actual_w = ALIGN_DOWN(actual_w, 4);
1174         }
1175
1176         act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
1177         dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff);
1178
1179         format = vop2_convert_format(fb->format->format);
1180
1181         drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n",
1182                 vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h,
1183                 dest->x1, dest->y1,
1184                 &fb->format->format,
1185                 afbc_en ? "AFBC" : "", &yrgb_mst);
1186
1187         if (afbc_en) {
1188                 u32 stride;
1189
1190                 /* the afbc superblock is 16 x 16 */
1191                 afbc_format = vop2_convert_afbc_format(fb->format->format);
1192
1193                 /* Enable color transform for YTR */
1194                 if (fb->modifier & AFBC_FORMAT_MOD_YTR)
1195                         afbc_format |= (1 << 4);
1196
1197                 afbc_tile_num = ALIGN(actual_w, 16) >> 4;
1198
1199                 /*
1200                  * AFBC pic_vir_width is count by pixel, this is different
1201                  * with WIN_VIR_STRIDE.
1202                  */
1203                 stride = (fb->pitches[0] << 3) / bpp;
1204                 if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270))
1205                         drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligened\n",
1206                                 vp->id, win->data->name, stride);
1207
1208                 rb_swap = vop2_afbc_rb_swap(fb->format->format);
1209                 uv_swap = vop2_afbc_uv_swap(fb->format->format);
1210                 /*
1211                  * This is a workaround for crazy IC design, Cluster
1212                  * and Esmart/Smart use different format configuration map:
1213                  * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart.
1214                  *
1215                  * This is one thing we can make the convert simple:
1216                  * AFBCD decode all the YUV data to YUV444. So we just
1217                  * set all the yuv 10 bit to YUV444_10.
1218                  */
1219                 if (fb->format->is_yuv && bpp == 10)
1220                         format = VOP2_CLUSTER_YUV444_10;
1221
1222                 if (vop2_cluster_window(win))
1223                         vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
1224                 vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
1225                 vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
1226                 vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
1227                 vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
1228                 vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
1229                 if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90)) {
1230                         vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 0);
1231                         transform_offset = vop2_afbc_transform_offset(pstate, false);
1232                 } else {
1233                         vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, 1);
1234                         transform_offset = vop2_afbc_transform_offset(pstate, true);
1235                 }
1236                 vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
1237                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
1238                 vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset);
1239                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1));
1240                 vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16)));
1241                 vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride);
1242                 vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num);
1243                 vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror);
1244                 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270);
1245                 vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90);
1246         } else {
1247                 vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4));
1248         }
1249
1250         vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror);
1251
1252         if (rotate_90 || rotate_270) {
1253                 act_info = swahw32(act_info);
1254                 actual_w = drm_rect_height(src) >> 16;
1255                 actual_h = drm_rect_width(src) >> 16;
1256         }
1257
1258         vop2_win_write(win, VOP2_WIN_FORMAT, format);
1259         vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst);
1260
1261         rb_swap = vop2_win_rb_swap(fb->format->format);
1262         vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
1263         if (!vop2_cluster_window(win)) {
1264                 uv_swap = vop2_win_uv_swap(fb->format->format);
1265                 vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
1266         }
1267
1268         if (fb->format->is_yuv) {
1269                 vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
1270                 vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst);
1271         }
1272
1273         vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format);
1274         if (!vop2_cluster_window(win))
1275                 vop2_plane_setup_color_key(plane, 0);
1276         vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info);
1277         vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info);
1278         vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff));
1279
1280         vop2_setup_csc_mode(vp, win, pstate);
1281
1282         dither_up = vop2_win_dither_up(fb->format->format);
1283         vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up);
1284
1285         vop2_win_write(win, VOP2_WIN_ENABLE, 1);
1286
1287         if (vop2_cluster_window(win)) {
1288                 int lb_mode = vop2_get_cluster_lb_mode(win, pstate);
1289
1290                 vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode);
1291                 vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1);
1292         }
1293 }
1294
1295 static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = {
1296         .atomic_check = vop2_plane_atomic_check,
1297         .atomic_update = vop2_plane_atomic_update,
1298         .atomic_disable = vop2_plane_atomic_disable,
1299 };
1300
1301 static const struct drm_plane_funcs vop2_plane_funcs = {
1302         .update_plane   = drm_atomic_helper_update_plane,
1303         .disable_plane  = drm_atomic_helper_disable_plane,
1304         .destroy = drm_plane_cleanup,
1305         .reset = drm_atomic_helper_plane_reset,
1306         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1307         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
1308         .format_mod_supported = rockchip_vop2_mod_supported,
1309 };
1310
1311 static int vop2_crtc_enable_vblank(struct drm_crtc *crtc)
1312 {
1313         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1314
1315         vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD);
1316
1317         return 0;
1318 }
1319
1320 static void vop2_crtc_disable_vblank(struct drm_crtc *crtc)
1321 {
1322         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1323
1324         vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD);
1325 }
1326
1327 static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
1328                                  const struct drm_display_mode *mode,
1329                                  struct drm_display_mode *adj_mode)
1330 {
1331         drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V |
1332                                         CRTC_STEREO_DOUBLE);
1333
1334         return true;
1335 }
1336
1337 static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
1338 {
1339         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1340
1341         switch (vcstate->bus_format) {
1342         case MEDIA_BUS_FMT_RGB565_1X16:
1343                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
1344                 break;
1345         case MEDIA_BUS_FMT_RGB666_1X18:
1346         case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1347         case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
1348                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
1349                 *dsp_ctrl |= RGB888_TO_RGB666;
1350                 break;
1351         case MEDIA_BUS_FMT_YUV8_1X24:
1352         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1353                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
1354                 break;
1355         default:
1356                 break;
1357         }
1358
1359         if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA)
1360                 *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
1361
1362         *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL,
1363                                 DITHER_DOWN_ALLEGRO);
1364 }
1365
1366 static void vop2_post_config(struct drm_crtc *crtc)
1367 {
1368         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1369         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1370         u16 vtotal = mode->crtc_vtotal;
1371         u16 hdisplay = mode->crtc_hdisplay;
1372         u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1373         u16 vdisplay = mode->crtc_vdisplay;
1374         u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1375         u32 left_margin = 100, right_margin = 100;
1376         u32 top_margin = 100, bottom_margin = 100;
1377         u16 hsize = hdisplay * (left_margin + right_margin) / 200;
1378         u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
1379         u16 hact_end, vact_end;
1380         u32 val;
1381
1382         vsize = rounddown(vsize, 2);
1383         hsize = rounddown(hsize, 2);
1384         hact_st += hdisplay * (100 - left_margin) / 200;
1385         hact_end = hact_st + hsize;
1386         val = hact_st << 16;
1387         val |= hact_end;
1388         vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val);
1389         vact_st += vdisplay * (100 - top_margin) / 200;
1390         vact_end = vact_st + vsize;
1391         val = vact_st << 16;
1392         val |= vact_end;
1393         vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val);
1394         val = scl_cal_scale2(vdisplay, vsize) << 16;
1395         val |= scl_cal_scale2(hdisplay, hsize);
1396         vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val);
1397
1398         val = 0;
1399         if (hdisplay != hsize)
1400                 val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN;
1401         if (vdisplay != vsize)
1402                 val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN;
1403         vop2_vp_write(vp, RK3568_VP_POST_SCL_CTRL, val);
1404
1405         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1406                 u16 vact_st_f1 = vtotal + vact_st + 1;
1407                 u16 vact_end_f1 = vact_st_f1 + vsize;
1408
1409                 val = vact_st_f1 << 16 | vact_end_f1;
1410                 vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
1411         }
1412
1413         vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
1414 }
1415
1416 static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id,
1417                                 u32 polflags)
1418 {
1419         struct vop2 *vop2 = vp->vop2;
1420         u32 die, dip;
1421
1422         die = vop2_readl(vop2, RK3568_DSP_IF_EN);
1423         dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
1424
1425         switch (id) {
1426         case ROCKCHIP_VOP2_EP_RGB0:
1427                 die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
1428                 die |= RK3568_SYS_DSP_INFACE_EN_RGB |
1429                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
1430                 if (polflags & POLFLAG_DCLK_INV)
1431                         regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
1432                 else
1433                         regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
1434                 break;
1435         case ROCKCHIP_VOP2_EP_HDMI0:
1436                 die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
1437                 die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
1438                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
1439                 break;
1440         case ROCKCHIP_VOP2_EP_EDP0:
1441                 die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
1442                 die |= RK3568_SYS_DSP_INFACE_EN_EDP |
1443                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
1444                 break;
1445         case ROCKCHIP_VOP2_EP_MIPI0:
1446                 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
1447                 die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
1448                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
1449                 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1450                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1451                 break;
1452         case ROCKCHIP_VOP2_EP_MIPI1:
1453                 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
1454                 die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
1455                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
1456                 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
1457                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
1458                 break;
1459         case ROCKCHIP_VOP2_EP_LVDS0:
1460                 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
1461                 die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
1462                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
1463                 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1464                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1465                 break;
1466         case ROCKCHIP_VOP2_EP_LVDS1:
1467                 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
1468                 die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
1469                            FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
1470                 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
1471                 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
1472                 break;
1473         default:
1474                 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
1475                 return;
1476         };
1477
1478         dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
1479
1480         vop2_writel(vop2, RK3568_DSP_IF_EN, die);
1481         vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
1482 }
1483
1484 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
1485 {
1486         return us * mode->clock / mode->htotal / 1000;
1487 }
1488
1489 static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
1490                                     struct drm_atomic_state *state)
1491 {
1492         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1493         struct vop2 *vop2 = vp->vop2;
1494         const struct vop2_data *vop2_data = vop2->data;
1495         const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
1496         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1497         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
1498         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
1499         unsigned long clock = mode->crtc_clock * 1000;
1500         u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
1501         u16 hdisplay = mode->crtc_hdisplay;
1502         u16 htotal = mode->crtc_htotal;
1503         u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
1504         u16 hact_end = hact_st + hdisplay;
1505         u16 vdisplay = mode->crtc_vdisplay;
1506         u16 vtotal = mode->crtc_vtotal;
1507         u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
1508         u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
1509         u16 vact_end = vact_st + vdisplay;
1510         u8 out_mode;
1511         u32 dsp_ctrl = 0;
1512         int act_end;
1513         u32 val, polflags;
1514         int ret;
1515         struct drm_encoder *encoder;
1516
1517         drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n",
1518                 hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
1519                 drm_mode_vrefresh(mode), vcstate->output_type, vp->id);
1520
1521         vop2_lock(vop2);
1522
1523         ret = clk_prepare_enable(vp->dclk);
1524         if (ret < 0) {
1525                 drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n",
1526                         vp->id, ret);
1527                 return;
1528         }
1529
1530         if (!vop2->enable_count)
1531                 vop2_enable(vop2);
1532
1533         vop2->enable_count++;
1534
1535         vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY);
1536
1537         polflags = 0;
1538         if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
1539                 polflags |= POLFLAG_DCLK_INV;
1540         if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1541                 polflags |= BIT(HSYNC_POSITIVE);
1542         if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1543                 polflags |= BIT(VSYNC_POSITIVE);
1544
1545         drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
1546                 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
1547
1548                 rk3568_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
1549         }
1550
1551         if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
1552             !(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT))
1553                 out_mode = ROCKCHIP_OUT_MODE_P888;
1554         else
1555                 out_mode = vcstate->output_mode;
1556
1557         dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode);
1558
1559         if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
1560                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP;
1561
1562         if (is_yuv_output(vcstate->bus_format))
1563                 dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y;
1564
1565         vop2_dither_setup(crtc, &dsp_ctrl);
1566
1567         vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len);
1568         val = hact_st << 16;
1569         val |= hact_end;
1570         vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val);
1571
1572         val = vact_st << 16;
1573         val |= vact_end;
1574         vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val);
1575
1576         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1577                 u16 vact_st_f1 = vtotal + vact_st + 1;
1578                 u16 vact_end_f1 = vact_st_f1 + vdisplay;
1579
1580                 val = vact_st_f1 << 16 | vact_end_f1;
1581                 vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val);
1582
1583                 val = vtotal << 16 | (vtotal + vsync_len);
1584                 vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val);
1585                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE;
1586                 dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL;
1587                 dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN;
1588                 vtotal += vtotal + 1;
1589                 act_end = vact_end_f1;
1590         } else {
1591                 act_end = vact_end;
1592         }
1593
1594         vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id),
1595                     (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end);
1596
1597         vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len);
1598
1599         if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1600                 dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV;
1601                 clock *= 2;
1602         }
1603
1604         vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
1605
1606         clk_set_rate(vp->dclk, clock);
1607
1608         vop2_post_config(crtc);
1609
1610         vop2_cfg_done(vp);
1611
1612         vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
1613
1614         drm_crtc_vblank_on(crtc);
1615
1616         vop2_unlock(vop2);
1617 }
1618
1619 static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
1620                                   struct drm_atomic_state *state)
1621 {
1622         struct vop2_video_port *vp = to_vop2_video_port(crtc);
1623         struct drm_plane *plane;
1624         int nplanes = 0;
1625         struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1626
1627         drm_atomic_crtc_state_for_each_plane(plane, crtc_state)
1628                 nplanes++;
1629
1630         if (nplanes > vp->nlayers)
1631                 return -EINVAL;
1632
1633         return 0;
1634 }
1635
1636 static bool is_opaque(u16 alpha)
1637 {
1638         return (alpha >> 8) == 0xff;
1639 }
1640
1641 static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
1642                              struct vop2_alpha *alpha)
1643 {
1644         int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
1645         int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
1646         int src_color_mode = alpha_config->src_premulti_en ?
1647                                 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1648         int dst_color_mode = alpha_config->dst_premulti_en ?
1649                                 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
1650
1651         alpha->src_color_ctrl.val = 0;
1652         alpha->dst_color_ctrl.val = 0;
1653         alpha->src_alpha_ctrl.val = 0;
1654         alpha->dst_alpha_ctrl.val = 0;
1655
1656         if (!alpha_config->src_pixel_alpha_en)
1657                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1658         else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
1659                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1660         else
1661                 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1662
1663         alpha->src_color_ctrl.bits.alpha_en = 1;
1664
1665         if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
1666                 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1667                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1668         } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
1669                 alpha->src_color_ctrl.bits.color_mode = src_color_mode;
1670                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
1671         } else {
1672                 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
1673                 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
1674         }
1675         alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
1676         alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1677         alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1678
1679         alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1680         alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1681         alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
1682         alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
1683         alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
1684         alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1685
1686         alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1687         alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
1688         alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
1689         alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
1690
1691         alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
1692         if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
1693                 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
1694         else
1695                 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
1696         alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
1697         alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
1698 }
1699
1700 static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
1701 {
1702         struct vop2_video_port *vp;
1703         int used_layer = 0;
1704         int i;
1705
1706         for (i = 0; i < port_id; i++) {
1707                 vp = &vop2->vps[i];
1708                 used_layer += hweight32(vp->win_mask);
1709         }
1710
1711         return used_layer;
1712 }
1713
1714 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
1715 {
1716         u32 offset = (main_win->data->phys_id * 0x10);
1717         struct vop2_alpha_config alpha_config;
1718         struct vop2_alpha alpha;
1719         struct drm_plane_state *bottom_win_pstate;
1720         bool src_pixel_alpha_en = false;
1721         u16 src_glb_alpha_val, dst_glb_alpha_val;
1722         bool premulti_en = false;
1723         bool swap = false;
1724
1725         /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
1726         bottom_win_pstate = main_win->base.state;
1727         src_glb_alpha_val = 0;
1728         dst_glb_alpha_val = main_win->base.state->alpha;
1729
1730         if (!bottom_win_pstate->fb)
1731                 return;
1732
1733         alpha_config.src_premulti_en = premulti_en;
1734         alpha_config.dst_premulti_en = false;
1735         alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
1736         alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1737         alpha_config.src_glb_alpha_value = src_glb_alpha_val;
1738         alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
1739         vop2_parse_alpha(&alpha_config, &alpha);
1740
1741         alpha.src_color_ctrl.bits.src_dst_swap = swap;
1742         vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
1743                     alpha.src_color_ctrl.val);
1744         vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
1745                     alpha.dst_color_ctrl.val);
1746         vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
1747                     alpha.src_alpha_ctrl.val);
1748         vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
1749                     alpha.dst_alpha_ctrl.val);
1750 }
1751
1752 static void vop2_setup_alpha(struct vop2_video_port *vp)
1753 {
1754         struct vop2 *vop2 = vp->vop2;
1755         struct drm_framebuffer *fb;
1756         struct vop2_alpha_config alpha_config;
1757         struct vop2_alpha alpha;
1758         struct drm_plane *plane;
1759         int pixel_alpha_en;
1760         int premulti_en, gpremulti_en = 0;
1761         int mixer_id;
1762         u32 offset;
1763         bool bottom_layer_alpha_en = false;
1764         u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
1765
1766         mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
1767         alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
1768
1769         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1770                 struct vop2_win *win = to_vop2_win(plane);
1771
1772                 if (plane->state->normalized_zpos == 0 &&
1773                     !is_opaque(plane->state->alpha) &&
1774                     !vop2_cluster_window(win)) {
1775                         /*
1776                          * If bottom layer have global alpha effect [except cluster layer,
1777                          * because cluster have deal with bottom layer global alpha value
1778                          * at cluster mix], bottom layer mix need deal with global alpha.
1779                          */
1780                         bottom_layer_alpha_en = true;
1781                         dst_global_alpha = plane->state->alpha;
1782                 }
1783         }
1784
1785         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1786                 struct vop2_win *win = to_vop2_win(plane);
1787                 int zpos = plane->state->normalized_zpos;
1788
1789                 if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
1790                         premulti_en = 1;
1791                 else
1792                         premulti_en = 0;
1793
1794                 plane = &win->base;
1795                 fb = plane->state->fb;
1796
1797                 pixel_alpha_en = fb->format->has_alpha;
1798
1799                 alpha_config.src_premulti_en = premulti_en;
1800
1801                 if (bottom_layer_alpha_en && zpos == 1) {
1802                         gpremulti_en = premulti_en;
1803                         /* Cd = Cs + (1 - As) * Cd * Agd */
1804                         alpha_config.dst_premulti_en = false;
1805                         alpha_config.src_pixel_alpha_en = pixel_alpha_en;
1806                         alpha_config.src_glb_alpha_value = plane->state->alpha;
1807                         alpha_config.dst_glb_alpha_value = dst_global_alpha;
1808                 } else if (vop2_cluster_window(win)) {
1809                         /* Mix output data only have pixel alpha */
1810                         alpha_config.dst_premulti_en = true;
1811                         alpha_config.src_pixel_alpha_en = true;
1812                         alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1813                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1814                 } else {
1815                         /* Cd = Cs + (1 - As) * Cd */
1816                         alpha_config.dst_premulti_en = true;
1817                         alpha_config.src_pixel_alpha_en = pixel_alpha_en;
1818                         alpha_config.src_glb_alpha_value = plane->state->alpha;
1819                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1820                 }
1821
1822                 vop2_parse_alpha(&alpha_config, &alpha);
1823
1824                 offset = (mixer_id + zpos - 1) * 0x10;
1825                 vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
1826                             alpha.src_color_ctrl.val);
1827                 vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
1828                             alpha.dst_color_ctrl.val);
1829                 vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
1830                             alpha.src_alpha_ctrl.val);
1831                 vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
1832                             alpha.dst_alpha_ctrl.val);
1833         }
1834
1835         if (vp->id == 0) {
1836                 if (bottom_layer_alpha_en) {
1837                         /* Transfer pixel alpha to hdr mix */
1838                         alpha_config.src_premulti_en = gpremulti_en;
1839                         alpha_config.dst_premulti_en = true;
1840                         alpha_config.src_pixel_alpha_en = true;
1841                         alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1842                         alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
1843                         vop2_parse_alpha(&alpha_config, &alpha);
1844
1845                         vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
1846                                     alpha.src_color_ctrl.val);
1847                         vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
1848                                     alpha.dst_color_ctrl.val);
1849                         vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
1850                                     alpha.src_alpha_ctrl.val);
1851                         vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
1852                                     alpha.dst_alpha_ctrl.val);
1853                 } else {
1854                         vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
1855                 }
1856         }
1857 }
1858
1859 static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
1860 {
1861         struct vop2 *vop2 = vp->vop2;
1862         struct drm_plane *plane;
1863         u32 layer_sel = 0;
1864         u32 port_sel;
1865         unsigned int nlayer, ofs;
1866         struct drm_display_mode *adjusted_mode;
1867         u16 hsync_len;
1868         u16 hdisplay;
1869         u32 bg_dly;
1870         u32 pre_scan_dly;
1871         int i;
1872         struct vop2_video_port *vp0 = &vop2->vps[0];
1873         struct vop2_video_port *vp1 = &vop2->vps[1];
1874         struct vop2_video_port *vp2 = &vop2->vps[2];
1875
1876         adjusted_mode = &vp->crtc.state->adjusted_mode;
1877         hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
1878         hdisplay = adjusted_mode->crtc_hdisplay;
1879
1880         bg_dly = vp->data->pre_scan_max_dly[3];
1881         vop2_writel(vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
1882                     FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
1883
1884         pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
1885         vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
1886
1887         vop2_writel(vop2, RK3568_OVL_CTRL, 0);
1888         port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
1889         port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
1890
1891         if (vp0->nlayers)
1892                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
1893                                      vp0->nlayers - 1);
1894         else
1895                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
1896
1897         if (vp1->nlayers)
1898                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
1899                                      (vp0->nlayers + vp1->nlayers - 1));
1900         else
1901                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
1902
1903         if (vp2->nlayers)
1904                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
1905                         (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
1906         else
1907                 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
1908
1909         layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
1910
1911         ofs = 0;
1912         for (i = 0; i < vp->id; i++)
1913                 ofs += vop2->vps[i].nlayers;
1914
1915         nlayer = 0;
1916         drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
1917                 struct vop2_win *win = to_vop2_win(plane);
1918
1919                 switch (win->data->phys_id) {
1920                 case ROCKCHIP_VOP2_CLUSTER0:
1921                         port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
1922                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
1923                         break;
1924                 case ROCKCHIP_VOP2_CLUSTER1:
1925                         port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
1926                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
1927                         break;
1928                 case ROCKCHIP_VOP2_ESMART0:
1929                         port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
1930                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
1931                         break;
1932                 case ROCKCHIP_VOP2_ESMART1:
1933                         port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
1934                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
1935                         break;
1936                 case ROCKCHIP_VOP2_SMART0:
1937                         port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
1938                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
1939                         break;
1940                 case ROCKCHIP_VOP2_SMART1:
1941                         port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
1942                         port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
1943                         break;
1944                 }
1945
1946                 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
1947                                                           0x7);
1948                 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
1949                                                          win->data->layer_sel_id);
1950                 nlayer++;
1951         }
1952
1953         /* configure unused layers to 0x5 (reserved) */
1954         for (; nlayer < vp->nlayers; nlayer++) {
1955                 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
1956                 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
1957         }
1958
1959         vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
1960         vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
1961         vop2_writel(vop2, RK3568_OVL_CTRL, RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD);
1962 }
1963
1964 static void vop2_setup_dly_for_windows(struct vop2 *vop2)
1965 {
1966         struct vop2_win *win;
1967         int i = 0;
1968         u32 cdly = 0, sdly = 0;
1969
1970         for (i = 0; i < vop2->data->win_size; i++) {
1971                 u32 dly;
1972
1973                 win = &vop2->win[i];
1974                 dly = win->delay;
1975
1976                 switch (win->data->phys_id) {
1977                 case ROCKCHIP_VOP2_CLUSTER0:
1978                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
1979                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
1980                         break;
1981                 case ROCKCHIP_VOP2_CLUSTER1:
1982                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
1983                         cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
1984                         break;
1985                 case ROCKCHIP_VOP2_ESMART0:
1986                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
1987                         break;
1988                 case ROCKCHIP_VOP2_ESMART1:
1989                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
1990                         break;
1991                 case ROCKCHIP_VOP2_SMART0:
1992                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
1993                         break;
1994                 case ROCKCHIP_VOP2_SMART1:
1995                         sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
1996                         break;
1997                 }
1998         }
1999
2000         vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
2001         vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
2002 }
2003
2004 static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
2005                                    struct drm_atomic_state *state)
2006 {
2007         struct vop2_video_port *vp = to_vop2_video_port(crtc);
2008         struct vop2 *vop2 = vp->vop2;
2009         struct drm_plane *plane;
2010
2011         vp->win_mask = 0;
2012
2013         drm_atomic_crtc_for_each_plane(plane, crtc) {
2014                 struct vop2_win *win = to_vop2_win(plane);
2015
2016                 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
2017
2018                 vp->win_mask |= BIT(win->data->phys_id);
2019
2020                 if (vop2_cluster_window(win))
2021                         vop2_setup_cluster_alpha(vop2, win);
2022         }
2023
2024         if (!vp->win_mask)
2025                 return;
2026
2027         vop2_setup_layer_mixer(vp);
2028         vop2_setup_alpha(vp);
2029         vop2_setup_dly_for_windows(vop2);
2030 }
2031
2032 static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
2033                                    struct drm_atomic_state *state)
2034 {
2035         struct vop2_video_port *vp = to_vop2_video_port(crtc);
2036
2037         vop2_post_config(crtc);
2038
2039         vop2_cfg_done(vp);
2040
2041         spin_lock_irq(&crtc->dev->event_lock);
2042
2043         if (crtc->state->event) {
2044                 WARN_ON(drm_crtc_vblank_get(crtc));
2045                 vp->event = crtc->state->event;
2046                 crtc->state->event = NULL;
2047         }
2048
2049         spin_unlock_irq(&crtc->dev->event_lock);
2050 }
2051
2052 static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
2053         .mode_fixup = vop2_crtc_mode_fixup,
2054         .atomic_check = vop2_crtc_atomic_check,
2055         .atomic_begin = vop2_crtc_atomic_begin,
2056         .atomic_flush = vop2_crtc_atomic_flush,
2057         .atomic_enable = vop2_crtc_atomic_enable,
2058         .atomic_disable = vop2_crtc_atomic_disable,
2059 };
2060
2061 static void vop2_crtc_reset(struct drm_crtc *crtc)
2062 {
2063         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
2064
2065         if (crtc->state) {
2066                 __drm_atomic_helper_crtc_destroy_state(crtc->state);
2067                 kfree(vcstate);
2068         }
2069
2070         vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL);
2071         if (!vcstate)
2072                 return;
2073
2074         crtc->state = &vcstate->base;
2075         crtc->state->crtc = crtc;
2076 }
2077
2078 static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
2079 {
2080         struct rockchip_crtc_state *vcstate, *old_vcstate;
2081
2082         old_vcstate = to_rockchip_crtc_state(crtc->state);
2083
2084         vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL);
2085         if (!vcstate)
2086                 return NULL;
2087
2088         __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base);
2089
2090         return &vcstate->base;
2091 }
2092
2093 static void vop2_crtc_destroy_state(struct drm_crtc *crtc,
2094                                     struct drm_crtc_state *state)
2095 {
2096         struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
2097
2098         __drm_atomic_helper_crtc_destroy_state(&vcstate->base);
2099         kfree(vcstate);
2100 }
2101
2102 static const struct drm_crtc_funcs vop2_crtc_funcs = {
2103         .set_config = drm_atomic_helper_set_config,
2104         .page_flip = drm_atomic_helper_page_flip,
2105         .destroy = drm_crtc_cleanup,
2106         .reset = vop2_crtc_reset,
2107         .atomic_duplicate_state = vop2_crtc_duplicate_state,
2108         .atomic_destroy_state = vop2_crtc_destroy_state,
2109         .enable_vblank = vop2_crtc_enable_vblank,
2110         .disable_vblank = vop2_crtc_disable_vblank,
2111 };
2112
2113 static irqreturn_t vop2_isr(int irq, void *data)
2114 {
2115         struct vop2 *vop2 = data;
2116         const struct vop2_data *vop2_data = vop2->data;
2117         u32 axi_irqs[VOP2_SYS_AXI_BUS_NUM];
2118         int ret = IRQ_NONE;
2119         int i;
2120
2121         /*
2122          * The irq is shared with the iommu. If the runtime-pm state of the
2123          * vop2-device is disabled the irq has to be targeted at the iommu.
2124          */
2125         if (!pm_runtime_get_if_in_use(vop2->dev))
2126                 return IRQ_NONE;
2127
2128         for (i = 0; i < vop2_data->nr_vps; i++) {
2129                 struct vop2_video_port *vp = &vop2->vps[i];
2130                 struct drm_crtc *crtc = &vp->crtc;
2131                 u32 irqs;
2132
2133                 irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
2134                 vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
2135
2136                 if (irqs & VP_INT_DSP_HOLD_VALID) {
2137                         complete(&vp->dsp_hold_completion);
2138                         ret = IRQ_HANDLED;
2139                 }
2140
2141                 if (irqs & VP_INT_FS_FIELD) {
2142                         drm_crtc_handle_vblank(crtc);
2143                         spin_lock(&crtc->dev->event_lock);
2144                         if (vp->event) {
2145                                 u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
2146
2147                                 if (!(val & BIT(vp->id))) {
2148                                         drm_crtc_send_vblank_event(crtc, vp->event);
2149                                         vp->event = NULL;
2150                                         drm_crtc_vblank_put(crtc);
2151                                 }
2152                         }
2153                         spin_unlock(&crtc->dev->event_lock);
2154
2155                         ret = IRQ_HANDLED;
2156                 }
2157
2158                 if (irqs & VP_INT_POST_BUF_EMPTY) {
2159                         drm_err_ratelimited(vop2->drm,
2160                                             "POST_BUF_EMPTY irq err at vp%d\n",
2161                                             vp->id);
2162                         ret = IRQ_HANDLED;
2163                 }
2164         }
2165
2166         axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS);
2167         vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]);
2168         axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS);
2169         vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]);
2170
2171         for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) {
2172                 if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) {
2173                         drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n");
2174                         ret = IRQ_HANDLED;
2175                 }
2176         }
2177
2178         pm_runtime_put(vop2->dev);
2179
2180         return ret;
2181 }
2182
2183 static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
2184                            unsigned long possible_crtcs)
2185 {
2186         const struct vop2_win_data *win_data = win->data;
2187         unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2188                                   BIT(DRM_MODE_BLEND_PREMULTI) |
2189                                   BIT(DRM_MODE_BLEND_COVERAGE);
2190         int ret;
2191
2192         ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs,
2193                                        &vop2_plane_funcs, win_data->formats,
2194                                        win_data->nformats,
2195                                        win_data->format_modifiers,
2196                                        win->type, win_data->name);
2197         if (ret) {
2198                 drm_err(vop2->drm, "failed to initialize plane %d\n", ret);
2199                 return ret;
2200         }
2201
2202         drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs);
2203
2204         if (win->data->supported_rotations)
2205                 drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0,
2206                                                    DRM_MODE_ROTATE_0 |
2207                                                    win->data->supported_rotations);
2208         drm_plane_create_alpha_property(&win->base);
2209         drm_plane_create_blend_mode_property(&win->base, blend_caps);
2210         drm_plane_create_zpos_property(&win->base, win->win_id, 0,
2211                                        vop2->registered_num_wins - 1);
2212
2213         return 0;
2214 }
2215
2216 static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
2217 {
2218         int i;
2219
2220         for (i = 0; i < vop2->data->nr_vps; i++) {
2221                 struct vop2_video_port *vp = &vop2->vps[i];
2222
2223                 if (!vp->crtc.port)
2224                         continue;
2225                 if (vp->primary_plane)
2226                         continue;
2227
2228                 return vp;
2229         }
2230
2231         return NULL;
2232 }
2233
2234 #define NR_LAYERS 6
2235
2236 static int vop2_create_crtc(struct vop2 *vop2)
2237 {
2238         const struct vop2_data *vop2_data = vop2->data;
2239         struct drm_device *drm = vop2->drm;
2240         struct device *dev = vop2->dev;
2241         struct drm_plane *plane;
2242         struct device_node *port;
2243         struct vop2_video_port *vp;
2244         int i, nvp, nvps = 0;
2245         int ret;
2246
2247         for (i = 0; i < vop2_data->nr_vps; i++) {
2248                 const struct vop2_video_port_data *vp_data;
2249                 struct device_node *np;
2250                 char dclk_name[9];
2251
2252                 vp_data = &vop2_data->vp[i];
2253                 vp = &vop2->vps[i];
2254                 vp->vop2 = vop2;
2255                 vp->id = vp_data->id;
2256                 vp->regs = vp_data->regs;
2257                 vp->data = vp_data;
2258
2259                 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
2260                 vp->dclk = devm_clk_get(vop2->dev, dclk_name);
2261                 if (IS_ERR(vp->dclk)) {
2262                         drm_err(vop2->drm, "failed to get %s\n", dclk_name);
2263                         return PTR_ERR(vp->dclk);
2264                 }
2265
2266                 np = of_graph_get_remote_node(dev->of_node, i, -1);
2267                 if (!np) {
2268                         drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
2269                         continue;
2270                 }
2271                 of_node_put(np);
2272
2273                 port = of_graph_get_port_by_id(dev->of_node, i);
2274                 if (!port) {
2275                         drm_err(vop2->drm, "no port node found for video_port%d\n", i);
2276                         return -ENOENT;
2277                 }
2278
2279                 vp->crtc.port = port;
2280                 nvps++;
2281         }
2282
2283         nvp = 0;
2284         for (i = 0; i < vop2->registered_num_wins; i++) {
2285                 struct vop2_win *win = &vop2->win[i];
2286                 u32 possible_crtcs;
2287
2288                 if (vop2->data->soc_id == 3566) {
2289                         /*
2290                          * On RK3566 these windows don't have an independent
2291                          * framebuffer. They share the framebuffer with smart0,
2292                          * esmart0 and cluster0 respectively.
2293                          */
2294                         switch (win->data->phys_id) {
2295                         case ROCKCHIP_VOP2_SMART1:
2296                         case ROCKCHIP_VOP2_ESMART1:
2297                         case ROCKCHIP_VOP2_CLUSTER1:
2298                                 continue;
2299                         }
2300                 }
2301
2302                 if (win->type == DRM_PLANE_TYPE_PRIMARY) {
2303                         vp = find_vp_without_primary(vop2);
2304                         if (vp) {
2305                                 possible_crtcs = BIT(nvp);
2306                                 vp->primary_plane = win;
2307                                 nvp++;
2308                         } else {
2309                                 /* change the unused primary window to overlay window */
2310                                 win->type = DRM_PLANE_TYPE_OVERLAY;
2311                         }
2312                 }
2313
2314                 if (win->type == DRM_PLANE_TYPE_OVERLAY)
2315                         possible_crtcs = (1 << nvps) - 1;
2316
2317                 ret = vop2_plane_init(vop2, win, possible_crtcs);
2318                 if (ret) {
2319                         drm_err(vop2->drm, "failed to init plane %s: %d\n",
2320                                 win->data->name, ret);
2321                         return ret;
2322                 }
2323         }
2324
2325         for (i = 0; i < vop2_data->nr_vps; i++) {
2326                 vp = &vop2->vps[i];
2327
2328                 if (!vp->crtc.port)
2329                         continue;
2330
2331                 plane = &vp->primary_plane->base;
2332
2333                 ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL,
2334                                                 &vop2_crtc_funcs,
2335                                                 "video_port%d", vp->id);
2336                 if (ret) {
2337                         drm_err(vop2->drm, "crtc init for video_port%d failed\n", i);
2338                         return ret;
2339                 }
2340
2341                 drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
2342
2343                 init_completion(&vp->dsp_hold_completion);
2344         }
2345
2346         /*
2347          * On the VOP2 it's very hard to change the number of layers on a VP
2348          * during runtime, so we distribute the layers equally over the used
2349          * VPs
2350          */
2351         for (i = 0; i < vop2->data->nr_vps; i++) {
2352                 struct vop2_video_port *vp = &vop2->vps[i];
2353
2354                 if (vp->crtc.port)
2355                         vp->nlayers = NR_LAYERS / nvps;
2356         }
2357
2358         return 0;
2359 }
2360
2361 static void vop2_destroy_crtc(struct drm_crtc *crtc)
2362 {
2363         of_node_put(crtc->port);
2364
2365         /*
2366          * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
2367          * references the CRTC.
2368          */
2369         drm_crtc_cleanup(crtc);
2370 }
2371
2372 static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
2373         [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
2374         [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
2375         [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
2376         [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
2377         [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
2378         [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
2379         [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
2380         [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
2381         [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
2382         [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
2383         [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
2384         [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
2385         [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
2386         [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
2387         [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
2388
2389         /* Scale */
2390         [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
2391         [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
2392         [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
2393         [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
2394         [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
2395         [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
2396         [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
2397
2398         /* cluster regs */
2399         [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
2400         [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
2401         [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
2402
2403         /* afbc regs */
2404         [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
2405         [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
2406         [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
2407         [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
2408         [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
2409         [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
2410         [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
2411         [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
2412         [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
2413         [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
2414         [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
2415         [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
2416         [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
2417         [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
2418         [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
2419         [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
2420         [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
2421         [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
2422         [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
2423         [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
2424         [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
2425         [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
2426         [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
2427         [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
2428         [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
2429         [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
2430         [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
2431         [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
2432         [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
2433         [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
2434 };
2435
2436 static int vop2_cluster_init(struct vop2_win *win)
2437 {
2438         struct vop2 *vop2 = win->vop2;
2439         struct reg_field *cluster_regs;
2440         int ret, i;
2441
2442         cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
2443                                GFP_KERNEL);
2444         if (!cluster_regs)
2445                 return -ENOMEM;
2446
2447         for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
2448                 if (cluster_regs[i].reg != 0xffffffff)
2449                         cluster_regs[i].reg += win->offset;
2450
2451         ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
2452                                            cluster_regs,
2453                                            ARRAY_SIZE(vop2_cluster_regs));
2454
2455         kfree(cluster_regs);
2456
2457         return ret;
2458 };
2459
2460 static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
2461         [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
2462         [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
2463         [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
2464         [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
2465         [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
2466         [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
2467         [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
2468         [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
2469         [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
2470         [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
2471         [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
2472         [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
2473         [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
2474         [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
2475         [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
2476         [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
2477         [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
2478         [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
2479         [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
2480
2481         /* Scale */
2482         [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
2483         [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
2484         [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
2485         [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
2486         [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
2487         [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
2488         [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
2489         [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
2490         [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
2491         [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
2492         [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
2493         [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
2494         [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
2495         [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
2496         [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
2497         [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
2498         [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
2499         [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
2500         [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
2501         [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
2502         [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
2503         [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
2504         [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
2505         [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
2506         [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
2507         [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
2508         [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
2509         [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
2510         [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
2511         [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
2512         [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
2513         [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
2514         [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
2515         [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
2516         [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
2517         [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
2518 };
2519
2520 static int vop2_esmart_init(struct vop2_win *win)
2521 {
2522         struct vop2 *vop2 = win->vop2;
2523         struct reg_field *esmart_regs;
2524         int ret, i;
2525
2526         esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
2527                               GFP_KERNEL);
2528         if (!esmart_regs)
2529                 return -ENOMEM;
2530
2531         for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
2532                 if (esmart_regs[i].reg != 0xffffffff)
2533                         esmart_regs[i].reg += win->offset;
2534
2535         ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
2536                                            esmart_regs,
2537                                            ARRAY_SIZE(vop2_esmart_regs));
2538
2539         kfree(esmart_regs);
2540
2541         return ret;
2542 };
2543
2544 static int vop2_win_init(struct vop2 *vop2)
2545 {
2546         const struct vop2_data *vop2_data = vop2->data;
2547         struct vop2_win *win;
2548         int i, ret;
2549
2550         for (i = 0; i < vop2_data->win_size; i++) {
2551                 const struct vop2_win_data *win_data = &vop2_data->win[i];
2552
2553                 win = &vop2->win[i];
2554                 win->data = win_data;
2555                 win->type = win_data->type;
2556                 win->offset = win_data->base;
2557                 win->win_id = i;
2558                 win->vop2 = vop2;
2559                 if (vop2_cluster_window(win))
2560                         ret = vop2_cluster_init(win);
2561                 else
2562                         ret = vop2_esmart_init(win);
2563                 if (ret)
2564                         return ret;
2565         }
2566
2567         vop2->registered_num_wins = vop2_data->win_size;
2568
2569         return 0;
2570 }
2571
2572 /*
2573  * The window registers are only updated when config done is written.
2574  * Until that they read back the old value. As we read-modify-write
2575  * these registers mark them as non-volatile. This makes sure we read
2576  * the new values from the regmap register cache.
2577  */
2578 static const struct regmap_range vop2_nonvolatile_range[] = {
2579         regmap_reg_range(0x1000, 0x23ff),
2580 };
2581
2582 static const struct regmap_access_table vop2_volatile_table = {
2583         .no_ranges = vop2_nonvolatile_range,
2584         .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range),
2585 };
2586
2587 static const struct regmap_config vop2_regmap_config = {
2588         .reg_bits       = 32,
2589         .val_bits       = 32,
2590         .reg_stride     = 4,
2591         .max_register   = 0x3000,
2592         .name           = "vop2",
2593         .volatile_table = &vop2_volatile_table,
2594         .cache_type     = REGCACHE_RBTREE,
2595 };
2596
2597 static int vop2_bind(struct device *dev, struct device *master, void *data)
2598 {
2599         struct platform_device *pdev = to_platform_device(dev);
2600         const struct vop2_data *vop2_data;
2601         struct drm_device *drm = data;
2602         struct vop2 *vop2;
2603         struct resource *res;
2604         size_t alloc_size;
2605         int ret;
2606
2607         vop2_data = of_device_get_match_data(dev);
2608         if (!vop2_data)
2609                 return -ENODEV;
2610
2611         /* Allocate vop2 struct and its vop2_win array */
2612         alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * vop2_data->win_size;
2613         vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
2614         if (!vop2)
2615                 return -ENOMEM;
2616
2617         vop2->dev = dev;
2618         vop2->data = vop2_data;
2619         vop2->drm = drm;
2620
2621         dev_set_drvdata(dev, vop2);
2622
2623         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vop");
2624         if (!res) {
2625                 drm_err(vop2->drm, "failed to get vop2 register byname\n");
2626                 return -EINVAL;
2627         }
2628
2629         vop2->regs = devm_ioremap_resource(dev, res);
2630         if (IS_ERR(vop2->regs))
2631                 return PTR_ERR(vop2->regs);
2632         vop2->len = resource_size(res);
2633
2634         vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config);
2635
2636         ret = vop2_win_init(vop2);
2637         if (ret)
2638                 return ret;
2639
2640         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut");
2641         if (res) {
2642                 vop2->lut_regs = devm_ioremap_resource(dev, res);
2643                 if (IS_ERR(vop2->lut_regs))
2644                         return PTR_ERR(vop2->lut_regs);
2645         }
2646
2647         vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
2648
2649         vop2->hclk = devm_clk_get(vop2->dev, "hclk");
2650         if (IS_ERR(vop2->hclk)) {
2651                 drm_err(vop2->drm, "failed to get hclk source\n");
2652                 return PTR_ERR(vop2->hclk);
2653         }
2654
2655         vop2->aclk = devm_clk_get(vop2->dev, "aclk");
2656         if (IS_ERR(vop2->aclk)) {
2657                 drm_err(vop2->drm, "failed to get aclk source\n");
2658                 return PTR_ERR(vop2->aclk);
2659         }
2660
2661         vop2->irq = platform_get_irq(pdev, 0);
2662         if (vop2->irq < 0) {
2663                 drm_err(vop2->drm, "cannot find irq for vop2\n");
2664                 return vop2->irq;
2665         }
2666
2667         mutex_init(&vop2->vop2_lock);
2668
2669         ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
2670         if (ret)
2671                 return ret;
2672
2673         ret = vop2_create_crtc(vop2);
2674         if (ret)
2675                 return ret;
2676
2677         rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
2678
2679         pm_runtime_enable(&pdev->dev);
2680
2681         return 0;
2682 }
2683
2684 static void vop2_unbind(struct device *dev, struct device *master, void *data)
2685 {
2686         struct vop2 *vop2 = dev_get_drvdata(dev);
2687         struct drm_device *drm = vop2->drm;
2688         struct list_head *plane_list = &drm->mode_config.plane_list;
2689         struct list_head *crtc_list = &drm->mode_config.crtc_list;
2690         struct drm_crtc *crtc, *tmpc;
2691         struct drm_plane *plane, *tmpp;
2692
2693         pm_runtime_disable(dev);
2694
2695         list_for_each_entry_safe(plane, tmpp, plane_list, head)
2696                 drm_plane_cleanup(plane);
2697
2698         list_for_each_entry_safe(crtc, tmpc, crtc_list, head)
2699                 vop2_destroy_crtc(crtc);
2700 }
2701
2702 const struct component_ops vop2_component_ops = {
2703         .bind = vop2_bind,
2704         .unbind = vop2_unbind,
2705 };
2706 EXPORT_SYMBOL_GPL(vop2_component_ops);