video: rockchip: vop: 3399: update for cabc
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk322x_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk322x_lcdc.c
3  *
4  * Copyright (C) 2015 ROCKCHIP, Inc.
5  * Author: Mark Yao <mark.yao@rock-chips.com>
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/of_device.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <linux/devfreq.h>
31 #include <linux/devfreq-event.h>
32 #include <linux/rockchip-iovmm.h>
33 #include <asm/div64.h>
34 #include <linux/uaccess.h>
35 #include <linux/rockchip/iomap.h>
36 #include <linux/rockchip/grf.h>
37 #include <linux/rockchip/common.h>
38 #include <dt-bindings/clock/rk_system_status.h>
39 #include <soc/rockchip/rkfb_dmc.h>
40
41 #include "rk322x_lcdc.h"
42
43 /*#define CONFIG_RK_FPGA 1*/
44 #define VOP_CHIP(dev)   (dev->data->chip_type)
45
46 static int dbg_thresd;
47 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
48
49 #define DBG(level, x...) do {                   \
50         if (unlikely(dbg_thresd >= level))      \
51                 pr_info(x);\
52         } while (0)
53
54 static struct rk_lcdc_win rk322x_vop_win[] = {
55         { .name = "win0",
56           .id = VOP_WIN0,
57           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
58                                 SUPPORT_SCALE | SUPPORT_YUV |
59                                 SUPPORT_YUV10BIT,
60           .property.max_input_x = 4096,
61           .property.max_input_y = 2304},
62         { .name = "win1",
63           .id = VOP_WIN1,
64           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
65                                 SUPPORT_SCALE | SUPPORT_YUV |
66                                 SUPPORT_YUV10BIT,
67           .property.max_input_x = 4096,
68           .property.max_input_y = 2304},
69         {
70           .name = "hwc",
71           .id = VOP_HWC,
72           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
73                                 SUPPORT_HWC_LAYER,
74           .property.max_input_x = 128,
75           .property.max_input_y = 128
76         }
77 };
78
79 static struct rk_lcdc_win rk3399_vop_win[] = {
80         { .name = "win0",
81           .id = VOP_WIN0,
82           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
83                                 SUPPORT_SCALE | SUPPORT_YUV |
84                                 SUPPORT_YUV10BIT,
85           .property.max_input_x = 4096,
86           .property.max_input_y = 2304},
87         { .name = "win1",
88           .id = VOP_WIN1,
89           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
90                                 SUPPORT_SCALE | SUPPORT_YUV |
91                                 SUPPORT_YUV10BIT,
92           .property.max_input_x = 4096,
93           .property.max_input_y = 2304},
94         { .name = "win2",
95           .id = VOP_WIN2,
96           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
97                                 SUPPORT_MULTI_AREA,
98           .property.max_input_x = 4096,
99           .property.max_input_y = 2304},
100         { .name = "win3",
101           .id = VOP_WIN3,
102           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
103                                 SUPPORT_MULTI_AREA,
104           .property.max_input_x = 4096,
105           .property.max_input_y = 2304},
106         {
107           .name = "hwc",
108           .id = VOP_HWC,
109           .property.feature = SUPPORT_WIN_IDENTIFY | SUPPORT_HW_EXIST |
110                                 SUPPORT_HWC_LAYER,
111           .property.max_input_x = 128,
112           .property.max_input_y = 128
113         }
114 };
115
116 static const struct vop_data rk322x_data = {
117         .chip_type = VOP_RK322X,
118         .win = rk322x_vop_win,
119         .n_wins = ARRAY_SIZE(rk322x_vop_win),
120 };
121
122 static const struct vop_data rk3399_data = {
123         .chip_type = VOP_RK3399,
124         .win = rk3399_vop_win,
125         .n_wins = ARRAY_SIZE(rk3399_vop_win),
126 };
127
128 #if defined(CONFIG_OF)
129 static const struct of_device_id vop_dt_ids[] = {
130         {.compatible = "rockchip,rk322x-lcdc",
131          .data = &rk322x_data, },
132         {.compatible = "rockchip,rk3399-lcdc",
133          .data = &rk3399_data, },
134         {}
135 };
136 #endif
137
138 static const u32 csc_y2r_bt601_limit[12] = {
139         0x04a8,      0,  0x0662, 0xfffc8654,
140         0x04a8, 0xfe6f,  0xfcbf, 0x00022056,
141         0x04a8, 0x0812,       0, 0xfffbaeac,
142 };
143
144 static const u32 csc_y2r_bt709_full[12] = {
145         0x04a8,      0,  0x072c, 0xfffc219e,
146         0x04a8, 0xff26,  0xfdde, 0x0001357b,
147         0x04a8, 0x0873,       0, 0xfffb7dee,
148 };
149
150 static const u32 csc_y2r_bt601_full[12] = {
151         0x0400,      0,  0x059c, 0xfffd342d,
152         0x0400, 0xfea0,  0xfd25, 0x00021fcc,
153         0x0400, 0x0717,       0, 0xfffc76bc,
154 };
155
156 static const u32 csc_y2r_bt601_limit_10[12] = {
157         0x04a8,      0,  0x0662, 0xfff2134e,
158         0x04a8, 0xfe6f,  0xfcbf, 0x00087b58,
159         0x04a8, 0x0812,       0, 0xffeeb4b0,
160 };
161
162 static const u32 csc_y2r_bt709_full_10[12] = {
163         0x04a8,      0,  0x072c, 0xfff08077,
164         0x04a8, 0xff26,  0xfdde, 0x0004cfed,
165         0x04a8, 0x0873,       0, 0xffedf1b8,
166 };
167
168 static const u32 csc_y2r_bt601_full_10[12] = {
169         0x0400,      0,  0x059c, 0xfff4cab4,
170         0x0400, 0xfea0,  0xfd25, 0x00087932,
171         0x0400, 0x0717,       0, 0xfff1d4f2,
172 };
173
174 static const u32 csc_y2r_bt2020[12] = {
175         0x04a8,      0, 0x06b6, 0xfff16bfc,
176         0x04a8, 0xff40, 0xfd66, 0x58ae9,
177         0x04a8, 0x0890,      0, 0xffedb828,
178 };
179
180 static const u32 csc_r2y_bt601_limit[12] = {
181         0x0107, 0x0204, 0x0064, 0x04200,
182         0xff68, 0xfed6, 0x01c2, 0x20200,
183         0x01c2, 0xfe87, 0xffb7, 0x20200,
184 };
185
186 static const u32 csc_r2y_bt709_full[12] = {
187         0x00bb, 0x0275, 0x003f, 0x04200,
188         0xff99, 0xfea5, 0x01c2, 0x20200,
189         0x01c2, 0xfe68, 0xffd7, 0x20200,
190 };
191
192 static const u32 csc_r2y_bt601_full[12] = {
193         0x0132, 0x0259, 0x0075, 0x200,
194         0xff53, 0xfead, 0x0200, 0x20200,
195         0x0200, 0xfe53, 0xffad, 0x20200,
196 };
197
198 static const u32 csc_r2y_bt601_limit_10[12] = {
199         0x0107, 0x0204, 0x0064, 0x10200,
200         0xff68, 0xfed6, 0x01c2, 0x80200,
201         0x01c2, 0xfe87, 0xffb7, 0x80200,
202 };
203
204 static const u32 csc_r2y_bt709_full_10[12] = {
205         0x00bb, 0x0275, 0x003f, 0x10200,
206         0xff99, 0xfea5, 0x01c2, 0x80200,
207         0x01c2, 0xfe68, 0xffd7, 0x80200,
208 };
209
210 static const u32 csc_r2y_bt601_full_10[12] = {
211         0x0132, 0x0259, 0x0075, 0x200,
212         0xff53, 0xfead, 0x0200, 0x80200,
213         0x0200, 0xfe53, 0xffad, 0x80200,
214 };
215
216 static const u32 csc_r2y_bt2020[12] = {
217         0x00e6, 0x0253, 0x0034, 0x10200,
218         0xff83, 0xfebd, 0x01c1, 0x80200,
219         0x01c1, 0xfe64, 0xffdc, 0x80200,
220 };
221
222 static const u32 csc_r2r_bt2020to709[12] = {
223         0x06a4, 0xfda6, 0xffb5, 0x200,
224         0xff80, 0x0488, 0xfff8, 0x200,
225         0xffed, 0xff99, 0x047a, 0x200,
226 };
227
228 static const u32 csc_r2r_bt709to2020[12] = {
229         0x282, 0x151, 0x02c, 0x200,
230         0x047, 0x3ae, 0x00c, 0x200,
231         0x011, 0x05a, 0x395, 0x200,
232 };
233
234 static int vop_get_id(struct vop_device *vop_dev, u32 phy_base)
235 {
236         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
237                 if (phy_base == 0xff900000) /* vop big */
238                         return 0;
239                 else if (phy_base == 0xff8f0000) /* vop lit */
240                         return 1;
241                 else
242                         return -EINVAL;
243         } else {
244                 return 0;
245         }
246 }
247
248 static void vop_load_csc_table(struct vop_device *vop_dev, u32 offset,
249                                const u32 *table)
250 {
251         u32 csc_val;
252
253         csc_val = table[1] << 16 | table[0];
254         vop_writel(vop_dev, offset, csc_val);
255         csc_val = table[4] << 16 | table[2];
256         vop_writel(vop_dev, offset + 4, csc_val);
257         csc_val = table[6] << 16 | table[5];
258         vop_writel(vop_dev, offset + 8, csc_val);
259         csc_val = table[9] << 16 | table[8];
260         vop_writel(vop_dev, offset + 0xc, csc_val);
261         csc_val = table[10];
262         vop_writel(vop_dev, offset + 0x10, csc_val);
263         csc_val = table[3];
264         vop_writel(vop_dev, offset + 0x14, csc_val);
265         csc_val = table[7];
266         vop_writel(vop_dev, offset + 0x18, csc_val);
267         csc_val = table[11];
268         vop_writel(vop_dev, offset + 0x1c, csc_val);
269 }
270
271 #define LOAD_CSC(dev, mode, table, win_id) \
272                 vop_load_csc_table(dev, \
273                                    WIN0_YUV2YUV_##mode + 0x60 * win_id, \
274                                    table)
275
276 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
277
278 static int vop_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
279 {
280         struct vop_device *vop_dev =
281                         container_of(dev_drv, struct vop_device, driver);
282         int i, j;
283
284         if (!vop_dev->dsp_lut_addr_base) {
285                 dev_warn(vop_dev->dev, "not support dsp lut config\n");
286                 return 0;
287         }
288
289         if (!dsp_lut) {
290                 dev_err(vop_dev->dev, "dsp lut table is null\n");
291                 return -EINVAL;
292         }
293
294         spin_lock(&vop_dev->reg_lock);
295         for (i = 0; i < 256; i++) {
296                 u32 v, r, g, b;
297                 int __iomem *c;
298
299                 v = dsp_lut[i];
300                 c = vop_dev->dsp_lut_addr_base + (i << 2);
301                 b = (v & 0xff) << 2;
302                 g = (v & 0xff00) << 4;
303                 r = (v & 0xff0000) << 6;
304                 v = r + g + b;
305                 for (j = 0; j < 4; j++) {
306                         writel_relaxed(v, c);
307                         v += (1 + (1 << 10) + (1 << 20));
308                         c++;
309                 }
310         }
311         vop_msk_reg(vop_dev, DSP_CTRL1, V_DSP_LUT_EN(1));
312         /*
313          * update_gamma value auto clean to 0 by HW, should not
314          * bakeup it.
315          */
316         vop_msk_reg_nobak(vop_dev, DSP_CTRL1, V_UPDATE_GAMMA_LUT(1));
317
318         vop_cfg_done(vop_dev);
319         spin_unlock(&vop_dev->reg_lock);
320
321         return 0;
322 }
323
324 static int vop_set_cabc(struct rk_lcdc_driver *dev_drv, int *cabc_lut)
325 {
326         struct vop_device *vop_dev =
327                         container_of(dev_drv, struct vop_device, driver);
328         int i;
329
330         if (!vop_dev->cabc_lut_addr_base) {
331                 dev_warn(vop_dev->dev, "not support cabc config\n");
332                 return 0;
333         }
334
335         if (!cabc_lut) {
336                 dev_err(vop_dev->dev, "cabc lut table is null\n");
337                 return -EINVAL;
338         }
339         spin_lock(&vop_dev->reg_lock);
340         vop_msk_reg(vop_dev, CABC_CTRL1, V_CABC_LUT_EN(0));
341         vop_cfg_done(vop_dev);
342         spin_unlock(&vop_dev->reg_lock);
343
344         mdelay(25);
345
346         spin_lock(&vop_dev->reg_lock);
347         for (i = 0; i < 128; i++) {
348                 u32 v;
349
350                 v = cabc_lut[i];
351
352                 writel_relaxed(v, vop_dev->cabc_lut_addr_base + i);
353         }
354         vop_msk_reg(vop_dev, CABC_CTRL1, V_CABC_LUT_EN(1));
355         spin_unlock(&vop_dev->reg_lock);
356
357         return 0;
358 }
359
360 static int vop_clk_enable(struct vop_device *vop_dev)
361 {
362         if (!vop_dev->clk_on) {
363                 clk_prepare_enable(vop_dev->hclk);
364                 clk_prepare_enable(vop_dev->dclk);
365                 clk_prepare_enable(vop_dev->aclk);
366                 if (vop_dev->hclk_noc)
367                         clk_prepare_enable(vop_dev->hclk_noc);
368                 if (vop_dev->aclk_noc)
369                         clk_prepare_enable(vop_dev->aclk_noc);
370 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
371                 pm_runtime_get_sync(vop_dev->dev);
372 #endif
373                 spin_lock(&vop_dev->reg_lock);
374                 vop_dev->clk_on = 1;
375                 spin_unlock(&vop_dev->reg_lock);
376         }
377
378         return 0;
379 }
380
381 static int vop_clk_disable(struct vop_device *vop_dev)
382 {
383         if (vop_dev->clk_on) {
384                 spin_lock(&vop_dev->reg_lock);
385                 vop_dev->clk_on = 0;
386                 spin_unlock(&vop_dev->reg_lock);
387                 mdelay(25);
388 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
389                 pm_runtime_put_sync(vop_dev->dev);
390 #endif
391                 clk_disable_unprepare(vop_dev->dclk);
392                 clk_disable_unprepare(vop_dev->hclk);
393                 clk_disable_unprepare(vop_dev->aclk);
394                 if (vop_dev->hclk_noc)
395                         clk_disable_unprepare(vop_dev->hclk_noc);
396                 if (vop_dev->aclk_noc)
397                         clk_disable_unprepare(vop_dev->aclk_noc);
398         }
399
400         return 0;
401 }
402
403 static int __maybe_unused vop_disable_irq(struct vop_device *vop_dev)
404 {
405         if (likely(vop_dev->clk_on)) {
406                 spin_lock(&vop_dev->reg_lock);
407                 vop_writel(vop_dev, INTR_EN0, 0xffff0000);
408                 vop_writel(vop_dev, INTR_EN1, 0xffff0000);
409                 vop_writel(vop_dev, INTR_CLEAR0, 0xffffffff);
410                 vop_writel(vop_dev, INTR_CLEAR1, 0xffffffff);
411                 vop_cfg_done(vop_dev);
412                 spin_unlock(&vop_dev->reg_lock);
413         };
414
415         return 0;
416 }
417
418 static int vop_reg_dump(struct rk_lcdc_driver *dev_drv)
419 {
420         struct vop_device *vop_dev =
421             container_of(dev_drv, struct vop_device, driver);
422         int *cbase = (int *)vop_dev->regs;
423         int *regsbak = (int *)vop_dev->regsbak;
424         int i, j, val;
425         char dbg_message[30];
426         char buf[10];
427
428         pr_info("lcd back up reg:\n");
429         memset(dbg_message, 0, sizeof(dbg_message));
430         memset(buf, 0, sizeof(buf));
431         for (i = 0; i <= (0x200 >> 4); i++) {
432                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
433                 for (j = 0; j < 4; j++) {
434                         val = sprintf(buf, "%08x  ", *(regsbak + i * 4 + j));
435                         strcat(dbg_message, buf);
436                 }
437                 pr_info("%s\n", dbg_message);
438                 memset(dbg_message, 0, sizeof(dbg_message));
439                 memset(buf, 0, sizeof(buf));
440         }
441
442         pr_info("lcdc reg:\n");
443         for (i = 0; i <= (0x200 >> 4); i++) {
444                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
445                 for (j = 0; j < 4; j++) {
446                         sprintf(buf, "%08x  ",
447                                 readl_relaxed(cbase + i * 4 + j));
448                         strcat(dbg_message, buf);
449                 }
450                 pr_info("%s\n", dbg_message);
451                 memset(dbg_message, 0, sizeof(dbg_message));
452                 memset(buf, 0, sizeof(buf));
453         }
454
455         return 0;
456 }
457
458 #define WIN_EN(id)              \
459 static int win##id##_enable(struct vop_device *vop_dev, int en) \
460 { \
461         spin_lock(&vop_dev->reg_lock);                                  \
462         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \
463         vop_cfg_done(vop_dev);                                          \
464         spin_unlock(&vop_dev->reg_lock);                                \
465         return 0;                                                       \
466 }
467
468 WIN_EN(0);
469 WIN_EN(1);
470 WIN_EN(2);
471 WIN_EN(3);
472
473 /*enable/disable win directly*/
474 static int vop_win_direct_en(struct rk_lcdc_driver *drv,
475                              int win_id, int en)
476 {
477         struct vop_device *vop_dev =
478             container_of(drv, struct vop_device, driver);
479
480         drv->win[win_id]->state = en;
481         if (win_id == 0)
482                 win0_enable(vop_dev, en);
483         else if (win_id == 1)
484                 win1_enable(vop_dev, en);
485         else if (win_id == 2)
486                 win2_enable(vop_dev, en);
487         else if (win_id == 3)
488                 win3_enable(vop_dev, en);
489         else
490                 dev_err(vop_dev->dev, "invalid win number:%d\n", win_id);
491         return 0;
492 }
493
494 #define SET_WIN_ADDR(id) \
495 static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \
496 {                                                       \
497         spin_lock(&vop_dev->reg_lock);                  \
498         vop_writel(vop_dev, WIN##id##_YRGB_MST, addr);  \
499         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1));       \
500         vop_cfg_done(vop_dev);                  \
501         spin_unlock(&vop_dev->reg_lock);                \
502         return 0;                                       \
503 }
504
505 SET_WIN_ADDR(0);
506 SET_WIN_ADDR(1);
507 int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
508                             int win_id, u32 addr)
509 {
510         struct vop_device *vop_dev =
511             container_of(dev_drv, struct vop_device, driver);
512         if (win_id == 0)
513                 set_win0_addr(vop_dev, addr);
514         else
515                 set_win1_addr(vop_dev, addr);
516
517         return 0;
518 }
519
520 static void lcdc_read_reg_defalut_cfg(struct vop_device *vop_dev)
521 {
522         int reg = 0;
523         u32 val = 0;
524         struct rk_screen *screen = vop_dev->driver.cur_screen;
525         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
526         u32 V_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
527         u32 st_x, st_y;
528         struct rk_lcdc_win *win0 = vop_dev->driver.win[0];
529
530         spin_lock(&vop_dev->reg_lock);
531         for (reg = 0; reg < vop_dev->len; reg += 4) {
532                 val = vop_readl_backup(vop_dev, reg);
533                 switch (reg) {
534                 case WIN0_ACT_INFO:
535                         win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
536                         win0->area[0].yact =
537                                 ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
538                         break;
539                 case WIN0_DSP_INFO:
540                         win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1;
541                         win0->area[0].ysize =
542                             ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
543                         break;
544                 case WIN0_DSP_ST:
545                         st_x = val & MASK(WIN0_DSP_XST);
546                         st_y = (val & MASK(WIN0_DSP_YST)) >> 16;
547                         win0->area[0].xpos = st_x - h_pw_bp;
548                         win0->area[0].ypos = st_y - V_pw_bp;
549                         break;
550                 case WIN0_CTRL0:
551                         win0->state = val & MASK(WIN0_EN);
552                         win0->area[0].fmt_cfg =
553                                         (val & MASK(WIN0_DATA_FMT)) >> 1;
554                         win0->fmt_10 = (val & MASK(WIN0_FMT_10)) >> 4;
555                         win0->area[0].format = win0->area[0].fmt_cfg;
556                         break;
557                 case WIN0_VIR:
558                         win0->area[0].y_vir_stride =
559                                         val & MASK(WIN0_VIR_STRIDE);
560                         win0->area[0].uv_vir_stride =
561                             (val & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
562                         if (win0->area[0].format == ARGB888)
563                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
564                         else if (win0->area[0].format == RGB888)
565                                 win0->area[0].xvir =
566                                     win0->area[0].y_vir_stride * 4 / 3;
567                         else if (win0->area[0].format == RGB565)
568                                 win0->area[0].xvir =
569                                     2 * win0->area[0].y_vir_stride;
570                         else
571                                 win0->area[0].xvir =
572                                     4 * win0->area[0].y_vir_stride;
573                         break;
574                 case WIN0_YRGB_MST:
575                         win0->area[0].smem_start = val;
576                         break;
577                 case WIN0_CBR_MST:
578                         win0->area[0].cbr_start = val;
579                         break;
580                 default:
581                         break;
582                 }
583         }
584         spin_unlock(&vop_dev->reg_lock);
585 }
586
587 /********do basic init*********/
588 static int vop_pre_init(struct rk_lcdc_driver *dev_drv)
589 {
590         struct vop_device *vop_dev =
591             container_of(dev_drv, struct vop_device, driver);
592         if (vop_dev->pre_init)
593                 return 0;
594         vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc");
595         vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc");
596         vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc");
597         if (IS_ERR(vop_dev->aclk) || IS_ERR(vop_dev->dclk) ||
598             IS_ERR(vop_dev->hclk))
599                 dev_err(vop_dev->dev, "failed to get clk source\n");
600         vop_dev->hclk_noc = devm_clk_get(vop_dev->dev, "hclk_vop_noc");
601         if (IS_ERR(vop_dev->hclk_noc)) {
602                 vop_dev->hclk_noc = NULL;
603                 dev_err(vop_dev->dev, "failed to get clk source\n");
604         }
605         vop_dev->aclk_noc = devm_clk_get(vop_dev->dev, "aclk_vop_noc");
606         if (IS_ERR(vop_dev->aclk_noc)) {
607                 vop_dev->aclk_noc = NULL;
608                 dev_err(vop_dev->dev, "failed to get clk source\n");
609         }
610         if (!support_uboot_display())
611                 rk_disp_pwr_enable(dev_drv);
612         vop_clk_enable(vop_dev);
613
614         memcpy(vop_dev->regsbak, vop_dev->regs, vop_dev->len);
615         /*backup reg config at uboot */
616         lcdc_read_reg_defalut_cfg(vop_dev);
617         #ifndef CONFIG_RK_FPGA
618         /*
619          * Todo, not verified
620          *
621         if (vop_dev->pwr18 == 1) {
622                 v = 0x00200020;
623                 vop_grf_writel(vop_dev->pmugrf_base,
624                                 PMUGRF_SOC_CON0_VOP, v);
625         } else {
626                 v = 0x00200000;
627                 vop_grf_writel(vop_dev->pmugrf_base,
628                                 PMUGRF_SOC_CON0_VOP, v);
629         }
630         */
631         #endif
632         vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821);
633         vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412);
634         vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696);
635         vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969);
636         vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
637         vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
638
639         if (!dev_drv->cabc_mode)
640                 vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(0));
641         vop_msk_reg(vop_dev, DSP_CTRL1, V_DITHER_UP_EN(1));
642         vop_cfg_done(vop_dev);
643         vop_dev->pre_init = true;
644
645         return 0;
646 }
647
648 static void vop_deint(struct vop_device *vop_dev)
649 {
650         if (vop_dev->clk_on) {
651                 u64 val;
652
653                 vop_disable_irq(vop_dev);
654                 spin_lock(&vop_dev->reg_lock);
655                 vop_msk_reg(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
656                 vop_msk_reg(vop_dev, WIN1_CTRL0, V_WIN0_EN(0));
657
658                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) | V_WIN2_MST1_EN(0) |
659                         V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
660                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
661                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
662                 vop_cfg_done(vop_dev);
663                 spin_unlock(&vop_dev->reg_lock);
664                 mdelay(50);
665         }
666 }
667
668 static void vop_win_csc_mode(struct vop_device *vop_dev,
669                              struct rk_lcdc_win *win,
670                              int csc_mode)
671 {
672         u64 val;
673
674         if (win->id == VOP_WIN0) {
675                 val = V_WIN0_CSC_MODE(csc_mode);
676                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
677         } else if (win->id == VOP_WIN1) {
678                 val = V_WIN1_CSC_MODE(csc_mode);
679                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
680         } else {
681                 val = V_HWC_CSC_MODE(csc_mode);
682                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
683         }
684 }
685
686 static int rk3399_vop_win_csc_cfg(struct rk_lcdc_driver *dev_drv)
687 {
688         struct vop_device *vop_dev =
689             container_of(dev_drv, struct vop_device, driver);
690         int output_color = dev_drv->output_color;
691         int i;
692
693         for (i = 0; i < dev_drv->lcdc_win_num && i <= 4; i++) {
694                 struct rk_lcdc_win *win = dev_drv->win[i];
695                 int shift = i * 8;
696                 u64 val = V_WIN0_YUV2YUV_EN(0) | V_WIN0_YUV2YUV_R2Y_EN(0) |
697                                 V_WIN0_YUV2YUV_Y2R_EN(0);
698
699                 if (!win->state)
700                         continue;
701                 if (output_color == COLOR_RGB &&
702                     !(IS_YUV(win->area[0].fmt_cfg) || win->area[0].yuyv_fmt))
703                         goto post;
704
705                 if (output_color == COLOR_RGB) {
706                         val |= V_WIN0_YUV2YUV_Y2R_EN(1);
707                         if (win->colorspace == CSC_BT601) {
708                                 /*
709                                  * Win Y2Y moudle always use 10bit mode.
710                                  */
711                                 LOAD_CSC(vop_dev, Y2R,
712                                          csc_y2r_bt601_full_10, i);
713                         } else if (win->colorspace == CSC_BT709) {
714                                 LOAD_CSC(vop_dev, Y2R,
715                                          csc_y2r_bt709_full_10, i);
716                         } else if (win->colorspace == CSC_BT2020) {
717                                 val |= V_WIN0_YUV2YUV_EN(1);
718                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt2020, i);
719                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt2020to709, i);
720                         }
721                 } else if (output_color == COLOR_YCBCR ||
722                                 output_color == COLOR_YCBCR_BT709) {
723                         if (!(IS_YUV(win->area[0].fmt_cfg) ||
724                               win->area[0].yuyv_fmt)) {
725                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1);
726                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full_10, i);
727                         } else if (win->colorspace == CSC_BT2020) {
728                                 val |= V_WIN0_YUV2YUV_EN(1) |
729                                         V_WIN0_YUV2YUV_Y2R_EN(1) |
730                                         V_WIN0_YUV2YUV_R2Y_EN(1);
731                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt2020, i);
732                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt2020to709, i);
733                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt709_full_10, i);
734                         }
735                 } else if (output_color == COLOR_YCBCR_BT2020) {
736                         if (!(IS_YUV(win->area[0].fmt_cfg) ||
737                               win->area[0].yuyv_fmt)) {
738                                 val |= V_WIN0_YUV2YUV_R2Y_EN(1) |
739                                         V_WIN0_YUV2YUV_EN(1);
740                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt709to2020, i);
741                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
742                         } else if (win->colorspace == CSC_BT601 ||
743                                         win->colorspace == CSC_BT709) {
744                                 val |= V_WIN0_YUV2YUV_Y2R_EN(1) |
745                                         V_WIN0_YUV2YUV_R2Y_EN(1) |
746                                         V_WIN0_YUV2YUV_EN(1);
747                                 LOAD_CSC(vop_dev, Y2R, csc_y2r_bt709_full_10, i);
748                                 LOAD_CSC(vop_dev, R2R, csc_r2r_bt709to2020, i);
749                                 LOAD_CSC(vop_dev, R2Y, csc_r2y_bt2020, i);
750                         }
751                 }
752 post:
753                 vop_msk_reg(vop_dev, YUV2YUV_WIN, val << shift);
754         }
755
756         return output_color;
757 }
758
759 /*
760  * colorspace path:
761  *      Input        Win csc            Post csc              Output
762  * 1. YUV(2020)  --> bypass   ---+ Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
763  *    RGB        --> R2Y(709) __/
764  *
765  * 2. YUV(2020)  --> bypass   ---+       bypass        --> YUV_OUTPUT(2020)
766  *    RGB        --> R2Y(709) __/
767  *
768  * 3. YUV(2020)  --> bypass   ---+    Y2R->2020To709   --> RGB_OUTPUT(709)
769  *    RGB        --> R2Y(709) __/
770  *
771  * 4. YUV(601/709)-> bypass   ---+ Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
772  *    RGB        --> R2Y(709) __/
773  *
774  * 5. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(709)
775  *    RGB        --> R2Y(709) __/
776  *
777  * 6. YUV(601/709)-> bypass   ---+       bypass        --> YUV_OUTPUT(601)
778  *    RGB        --> R2Y(601) __/
779  *
780  * 7. YUV(601)   --> Y2R(601/mpeg)-+     bypass        --> RGB_OUTPUT(709)
781  *    RGB        --> bypass   ____/
782  *
783  * 8. YUV(709)   --> Y2R(709/hd) --+     bypass        --> RGB_OUTPUT(709)
784  *    RGB        --> bypass   ____/
785  *
786  * 9. RGB        --> bypass   --->    709To2020->R2Y   --> YUV_OUTPUT(2020)
787  *
788  * 10. RGB       --> R2Y(709) --->      bypass        --> YUV_OUTPUT(709)
789  *
790  * 11. RGB       --> R2Y(601) --->       bypass        --> YUV_OUTPUT(601)
791  *
792  * 12. RGB       --> bypass   --->       bypass        --> RGB_OUTPUT(709)
793  */
794 static int rk3228_vop_win_csc_cfg(struct rk_lcdc_driver *dev_drv)
795 {
796         struct vop_device *vop_dev =
797             container_of(dev_drv, struct vop_device, driver);
798         struct rk_lcdc_win *win;
799         int output_color = dev_drv->output_color;
800         int win_csc = COLOR_RGB;
801         int r2y_mode = VOP_R2Y_CSC_BT709;
802         int i;
803
804         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
805                 win = dev_drv->win[i];
806                 if (!win->state)
807                         continue;
808
809                 if (IS_YUV(win->area[0].fmt_cfg)) {
810                         if (win->colorspace == CSC_BT2020 &&
811                             win_csc < COLOR_YCBCR_BT2020) {
812                                 r2y_mode = VOP_R2Y_CSC_BT709;
813                                 win_csc = COLOR_YCBCR_BT2020;
814                         }
815
816                         if (win->colorspace == CSC_BT709 &&
817                             win_csc < COLOR_YCBCR_BT709) {
818                                 r2y_mode = VOP_R2Y_CSC_BT709;
819                                 win_csc = COLOR_YCBCR_BT709;
820                         }
821
822                         if (win->colorspace == CSC_BT601 &&
823                             win_csc < COLOR_YCBCR) {
824                                 r2y_mode = VOP_R2Y_CSC_BT709;
825                                 win_csc = COLOR_YCBCR;
826                         }
827                 }
828         }
829
830         if (win_csc == COLOR_RGB) {
831                 if (output_color == COLOR_YCBCR_BT709) {
832                         r2y_mode = VOP_R2Y_CSC_BT709;
833                         win_csc = COLOR_YCBCR_BT709;
834                 } else if (output_color == COLOR_YCBCR) {
835                         r2y_mode = VOP_R2Y_CSC_BT601;
836                         win_csc = COLOR_YCBCR;
837                 }
838         }
839
840         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
841                 win = dev_drv->win[i];
842                 if (!win->state)
843                         continue;
844
845                 if (win_csc != COLOR_RGB && !IS_YUV(win->area[0].fmt_cfg))
846                         vop_win_csc_mode(vop_dev, win, r2y_mode);
847
848                 if (IS_YUV(win->area[0].fmt_cfg)) {
849                         if (win_csc == COLOR_YCBCR)
850                                 vop_win_csc_mode(vop_dev, win,
851                                                  VOP_Y2R_CSC_MPEG);
852                         else if (win_csc == COLOR_YCBCR_BT709)
853                                 vop_win_csc_mode(vop_dev, win, VOP_Y2R_CSC_HD);
854                 }
855         }
856
857         return win_csc;
858 }
859
860 static int vop_post_csc_cfg(struct rk_lcdc_driver *dev_drv)
861 {
862         struct vop_device *vop_dev =
863             container_of(dev_drv, struct vop_device, driver);
864         int output_color = dev_drv->output_color;
865         int win_csc = 0, overlay_mode = 0;
866         u64 val;
867
868         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
869                 win_csc = rk3228_vop_win_csc_cfg(dev_drv);
870         } else if (VOP_CHIP(vop_dev) == VOP_RK3399) {
871                 win_csc = rk3399_vop_win_csc_cfg(dev_drv);
872
873                 /*
874                  * RK3399 not support post csc config.
875                  */
876                 goto done;
877         }
878
879         val = V_YUV2YUV_POST_Y2R_EN(0) | V_YUV2YUV_POST_EN(0) |
880                 V_YUV2YUV_POST_R2Y_EN(0);
881         /* Y2R */
882         if (win_csc == COLOR_YCBCR && output_color == COLOR_YCBCR_BT2020) {
883                 val |= V_YUV2YUV_POST_Y2R_EN(1);
884                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
885                                    csc_y2r_bt709_full);
886         }
887         if (win_csc == COLOR_YCBCR_BT2020 &&
888             output_color != COLOR_YCBCR_BT2020) {
889                 val |= V_YUV2YUV_POST_Y2R_EN(1);
890                 vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE,
891                                    csc_y2r_bt2020);
892         }
893
894         /* R2R */
895         if ((win_csc == COLOR_YCBCR ||
896              win_csc == COLOR_YCBCR_BT709 ||
897              win_csc == COLOR_RGB) && output_color == COLOR_YCBCR_BT2020) {
898                 val |= V_YUV2YUV_POST_EN(1);
899                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
900                                    csc_r2r_bt709to2020);
901         }
902         if (win_csc == COLOR_YCBCR_BT2020 &&
903             (output_color == COLOR_YCBCR ||
904              output_color == COLOR_YCBCR_BT709 ||
905              output_color == COLOR_RGB)) {
906                 val |= V_YUV2YUV_POST_EN(1);
907                 vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE,
908                                    csc_r2r_bt2020to709);
909         }
910
911         /* Y2R */
912         if (output_color != COLOR_RGB) {
913                 val |= V_YUV2YUV_POST_R2Y_EN(1);
914
915                 if (output_color == COLOR_YCBCR_BT2020)
916                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
917                                            csc_r2y_bt2020);
918                 else
919                         vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE,
920                                            csc_r2y_bt709_full);
921         }
922
923         DBG(1, "win_csc=%d output_color=%d val=%llx\n",
924             win_csc, output_color, val);
925         vop_msk_reg(vop_dev, YUV2YUV_POST, val);
926 done:
927         overlay_mode = (win_csc != COLOR_RGB) ? VOP_YUV_DOMAIN : VOP_RGB_DOMAIN;
928         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(overlay_mode));
929
930         return 0;
931 }
932
933 static int vop_post_cfg(struct rk_lcdc_driver *dev_drv)
934 {
935         struct vop_device *vop_dev =
936             container_of(dev_drv, struct vop_device, driver);
937         struct rk_screen *screen = dev_drv->cur_screen;
938         u16 x_res = screen->mode.xres;
939         u16 y_res = screen->mode.yres;
940         u64 val;
941         u16 h_total, v_total;
942         u16 post_hsd_en, post_vsd_en;
943         u16 post_dsp_hact_st, post_dsp_hact_end;
944         u16 post_dsp_vact_st, post_dsp_vact_end;
945         u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
946         u16 post_h_fac, post_v_fac;
947
948         screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200;
949         screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200;
950         screen->post_xsize = x_res *
951             (dev_drv->overscan.left + dev_drv->overscan.right) / 200;
952         screen->post_ysize = y_res *
953             (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200;
954
955         h_total = screen->mode.hsync_len + screen->mode.left_margin +
956             x_res + screen->mode.right_margin;
957         v_total = screen->mode.vsync_len + screen->mode.upper_margin +
958             y_res + screen->mode.lower_margin;
959
960         if (screen->post_dsp_stx + screen->post_xsize > x_res) {
961                 dev_warn(vop_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
962                          screen->post_dsp_stx, screen->post_xsize, x_res);
963                 screen->post_dsp_stx = x_res - screen->post_xsize;
964         }
965         if (screen->x_mirror == 0) {
966                 post_dsp_hact_st = screen->post_dsp_stx +
967                     screen->mode.hsync_len + screen->mode.left_margin;
968                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
969         } else {
970                 post_dsp_hact_end = h_total - screen->mode.right_margin -
971                     screen->post_dsp_stx;
972                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
973         }
974         if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
975                 post_hsd_en = 1;
976                 post_h_fac =
977                     GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
978         } else {
979                 post_hsd_en = 0;
980                 post_h_fac = 0x1000;
981         }
982
983         if (screen->post_dsp_sty + screen->post_ysize > y_res) {
984                 dev_warn(vop_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
985                          screen->post_dsp_sty, screen->post_ysize, y_res);
986                 screen->post_dsp_sty = y_res - screen->post_ysize;
987         }
988
989         if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
990                 post_vsd_en = 1;
991                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
992                                                       screen->post_ysize);
993         } else {
994                 post_vsd_en = 0;
995                 post_v_fac = 0x1000;
996         }
997
998         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
999                 post_dsp_vact_st = screen->post_dsp_sty / 2 +
1000                                         screen->mode.vsync_len +
1001                                         screen->mode.upper_margin;
1002                 post_dsp_vact_end = post_dsp_vact_st +
1003                                         screen->post_ysize / 2;
1004
1005                 post_dsp_vact_st_f1 = screen->mode.vsync_len +
1006                                         screen->mode.upper_margin +
1007                                         y_res / 2 +
1008                                         screen->mode.lower_margin +
1009                                         screen->mode.vsync_len +
1010                                         screen->mode.upper_margin +
1011                                         screen->post_dsp_sty / 2 +
1012                                         1;
1013                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 +
1014                                         screen->post_ysize / 2;
1015         } else {
1016                 if (screen->y_mirror == 0) {
1017                         post_dsp_vact_st = screen->post_dsp_sty +
1018                             screen->mode.vsync_len +
1019                             screen->mode.upper_margin;
1020                         post_dsp_vact_end = post_dsp_vact_st +
1021                                 screen->post_ysize;
1022                 } else {
1023                         post_dsp_vact_end = v_total -
1024                                 screen->mode.lower_margin -
1025                             screen->post_dsp_sty;
1026                         post_dsp_vact_st = post_dsp_vact_end -
1027                                 screen->post_ysize;
1028                 }
1029                 post_dsp_vact_st_f1 = 0;
1030                 post_dsp_vact_end_f1 = 0;
1031         }
1032         DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
1033             screen->post_xsize, screen->post_ysize, screen->xpos);
1034         DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
1035             screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
1036         val = V_DSP_HACT_END_POST(post_dsp_hact_end) |
1037             V_DSP_HACT_ST_POST(post_dsp_hact_st);
1038         vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val);
1039
1040         val = V_DSP_VACT_END_POST(post_dsp_vact_end) |
1041             V_DSP_VACT_ST_POST(post_dsp_vact_st);
1042         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO, val);
1043
1044         val = V_POST_HS_FACTOR_YRGB(post_h_fac) |
1045             V_POST_VS_FACTOR_YRGB(post_v_fac);
1046         vop_msk_reg(vop_dev, POST_SCL_FACTOR_YRGB, val);
1047         val = V_DSP_VACT_END_POST(post_dsp_vact_end_f1) |
1048             V_DSP_VACT_ST_POST(post_dsp_vact_st_f1);
1049         vop_msk_reg(vop_dev, POST_DSP_VACT_INFO_F1, val);
1050         val = V_POST_HOR_SD_EN(post_hsd_en) | V_POST_VER_SD_EN(post_vsd_en);
1051         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
1052
1053         vop_post_csc_cfg(dev_drv);
1054
1055         return 0;
1056 }
1057
1058 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
1059 {
1060         struct vop_device *vop_dev =
1061             container_of(dev_drv, struct vop_device, driver);
1062         struct rk_lcdc_win *win;
1063         u32 colorkey_r, colorkey_g, colorkey_b;
1064         int i, key_val;
1065
1066         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1067                 win = dev_drv->win[i];
1068                 key_val = win->color_key_val;
1069                 colorkey_r = (key_val & 0xff) << 2;
1070                 colorkey_g = ((key_val >> 8) & 0xff) << 12;
1071                 colorkey_b = ((key_val >> 16) & 0xff) << 22;
1072                 /* color key dither 565/888->aaa */
1073                 key_val = colorkey_r | colorkey_g | colorkey_b;
1074                 switch (i) {
1075                 case 0:
1076                         vop_writel(vop_dev, WIN0_COLOR_KEY, key_val);
1077                         break;
1078                 case 1:
1079                         vop_writel(vop_dev, WIN1_COLOR_KEY, key_val);
1080                         break;
1081                 case 2:
1082                         vop_writel(vop_dev, WIN2_COLOR_KEY, key_val);
1083                         break;
1084                 case 3:
1085                         vop_writel(vop_dev, WIN3_COLOR_KEY, key_val);
1086                         break;
1087                 default:
1088                         pr_info("%s:un support win num:%d\n",
1089                                 __func__, i);
1090                         break;
1091                 }
1092         }
1093         return 0;
1094 }
1095
1096 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
1097 {
1098         struct vop_device *vop_dev =
1099             container_of(dev_drv, struct vop_device, driver);
1100         struct rk_lcdc_win *win = dev_drv->win[win_id];
1101         struct alpha_config alpha_config;
1102         u64 val;
1103         int ppixel_alpha = 0, global_alpha = 0, i;
1104         u32 src_alpha_ctl = 0, dst_alpha_ctl = 0;
1105         int alpha_en = 1;
1106
1107         memset(&alpha_config, 0, sizeof(struct alpha_config));
1108         for (i = 0; i < win->area_num; i++) {
1109                 ppixel_alpha |= ((win->area[i].format == ARGB888) ||
1110                                  (win->area[i].format == FBDC_ARGB_888) ||
1111                                  (win->area[i].format == FBDC_ABGR_888) ||
1112                                  (win->area[i].format == ABGR888)) ? 1 : 0;
1113         }
1114
1115         global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
1116
1117         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1118                 if (!dev_drv->win[i]->state)
1119                         continue;
1120                 if (win->z_order > dev_drv->win[i]->z_order)
1121                         break;
1122         }
1123
1124         /*
1125          * The bottom layer not support ppixel_alpha mode.
1126          */
1127         if (i == dev_drv->lcdc_win_num)
1128                 ppixel_alpha = 0;
1129         alpha_config.src_global_alpha_val = win->g_alpha_val;
1130         win->alpha_mode = AB_SRC_OVER;
1131
1132         switch (win->alpha_mode) {
1133         case AB_USER_DEFINE:
1134                 break;
1135         case AB_CLEAR:
1136                 alpha_config.src_factor_mode = AA_ZERO;
1137                 alpha_config.dst_factor_mode = AA_ZERO;
1138                 break;
1139         case AB_SRC:
1140                 alpha_config.src_factor_mode = AA_ONE;
1141                 alpha_config.dst_factor_mode = AA_ZERO;
1142                 break;
1143         case AB_DST:
1144                 alpha_config.src_factor_mode = AA_ZERO;
1145                 alpha_config.dst_factor_mode = AA_ONE;
1146                 break;
1147         case AB_SRC_OVER:
1148                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1149                 if (global_alpha)
1150                         alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1151                 else
1152                         alpha_config.src_factor_mode = AA_ONE;
1153                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1154                 break;
1155         case AB_DST_OVER:
1156                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1157                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1158                 alpha_config.dst_factor_mode = AA_ONE;
1159                 break;
1160         case AB_SRC_IN:
1161                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1162                 alpha_config.src_factor_mode = AA_SRC;
1163                 alpha_config.dst_factor_mode = AA_ZERO;
1164                 break;
1165         case AB_DST_IN:
1166                 alpha_config.src_factor_mode = AA_ZERO;
1167                 alpha_config.dst_factor_mode = AA_SRC;
1168                 break;
1169         case AB_SRC_OUT:
1170                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1171                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1172                 alpha_config.dst_factor_mode = AA_ZERO;
1173                 break;
1174         case AB_DST_OUT:
1175                 alpha_config.src_factor_mode = AA_ZERO;
1176                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1177                 break;
1178         case AB_SRC_ATOP:
1179                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1180                 alpha_config.src_factor_mode = AA_SRC;
1181                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1182                 break;
1183         case AB_DST_ATOP:
1184                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1185                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1186                 alpha_config.dst_factor_mode = AA_SRC;
1187                 break;
1188         case XOR:
1189                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
1190                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
1191                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1192                 break;
1193         case AB_SRC_OVER_GLOBAL:
1194                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1195                 alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
1196                 alpha_config.src_factor_mode = AA_SRC_GLOBAL;
1197                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
1198                 break;
1199         default:
1200                 pr_err("alpha mode error\n");
1201                 break;
1202         }
1203         if ((ppixel_alpha == 1) && (global_alpha == 1))
1204                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
1205         else if (ppixel_alpha == 1)
1206                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
1207         else if (global_alpha == 1)
1208                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
1209         else
1210                 alpha_en = 0;
1211         alpha_config.src_alpha_mode = AA_STRAIGHT;
1212         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
1213
1214         switch (win_id) {
1215         case 0:
1216                 src_alpha_ctl = 0x60;
1217                 dst_alpha_ctl = 0x64;
1218                 break;
1219         case 1:
1220                 src_alpha_ctl = 0xa0;
1221                 dst_alpha_ctl = 0xa4;
1222                 break;
1223         case 2:
1224                 src_alpha_ctl = 0xdc;
1225                 dst_alpha_ctl = 0xec;
1226                 break;
1227         case 3:
1228                 src_alpha_ctl = 0x12c;
1229                 dst_alpha_ctl = 0x13c;
1230                 break;
1231         case 4:
1232                 src_alpha_ctl = 0x160;
1233                 dst_alpha_ctl = 0x164;
1234                 break;
1235         }
1236         val = V_WIN0_DST_FACTOR_MODE(alpha_config.dst_factor_mode);
1237         vop_msk_reg(vop_dev, dst_alpha_ctl, val);
1238         val = V_WIN0_SRC_ALPHA_EN(alpha_en) |
1239             V_WIN0_SRC_COLOR_MODE(alpha_config.src_color_mode) |
1240             V_WIN0_SRC_ALPHA_MODE(alpha_config.src_alpha_mode) |
1241             V_WIN0_SRC_BLEND_MODE(alpha_config.src_global_alpha_mode) |
1242             V_WIN0_SRC_ALPHA_CAL_MODE(alpha_config.src_alpha_cal_m0) |
1243             V_WIN0_SRC_FACTOR_MODE(alpha_config.src_factor_mode) |
1244             V_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
1245
1246         vop_msk_reg(vop_dev, src_alpha_ctl, val);
1247
1248         return 0;
1249 }
1250
1251 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
1252                               struct rk_lcdc_win *win)
1253 {
1254         u64 val;
1255         u16 yrgb_gather_num = 3;
1256         u16 cbcr_gather_num = 1;
1257
1258         switch (win->area[0].format) {
1259         case ARGB888:
1260         case XBGR888:
1261         case ABGR888:
1262         case FBDC_ARGB_888:
1263         case FBDC_RGBX_888:
1264         case FBDC_ABGR_888:
1265                 yrgb_gather_num = 3;
1266                 break;
1267         case RGB888:
1268         case RGB565:
1269         case FBDC_RGB_565:
1270                 yrgb_gather_num = 2;
1271                 break;
1272         case YUV444:
1273         case YUV422:
1274         case YUV420:
1275         case YUV420_A:
1276         case YUV422_A:
1277         case YUV444_A:
1278         case YUV420_NV21:
1279         case YUYV420:
1280         case UYVY420:
1281                 yrgb_gather_num = 1;
1282                 cbcr_gather_num = 2;
1283                 break;
1284         case YUYV422:
1285         case UYVY422:
1286                 yrgb_gather_num = 2;
1287                 cbcr_gather_num = 2;
1288                 break;
1289         default:
1290                 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
1291                         __func__, win->area[0].format);
1292                 return -EINVAL;
1293         }
1294
1295         if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1)) {
1296                 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
1297                         V_WIN0_CBR_AXI_GATHER_EN(1) |
1298                         V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
1299                         V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
1300                 vop_msk_reg(vop_dev, WIN0_CTRL1 + (win->id * 0x40), val);
1301         } else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3)) {
1302                 val = V_WIN2_AXI_GATHER_EN(1) |
1303                         V_WIN2_AXI_GATHER_NUM(yrgb_gather_num);
1304                 vop_msk_reg(vop_dev, WIN2_CTRL1 + ((win->id - 2) * 0x50), val);
1305         } else if (win->id == VOP_HWC) {
1306                 val = V_HWC_AXI_GATHER_EN(1) |
1307                         V_HWC_AXI_GATHER_NUM(yrgb_gather_num);
1308                 vop_msk_reg(vop_dev, HWC_CTRL1, val);
1309         }
1310         return 0;
1311 }
1312
1313 static int vop_fbdc_reg_update(struct vop_device *vop_dev, int win_id)
1314 {
1315         struct rk_lcdc_win *win = vop_dev->driver.win[win_id];
1316         u64 val;
1317
1318         val = V_VOP_FBDC_WIN_SEL(win_id) |
1319                 V_AFBCD_HREG_PIXEL_PACKING_FMT(win->area[0].fbdc_fmt_cfg) |
1320                 V_AFBCD_HREG_BLOCK_SPLIT(win->area[0].fbdc_cor_en);
1321         vop_msk_reg(vop_dev, AFBCD0_CTRL, val);
1322
1323         val = V_AFBCD_HREG_PIC_WIDTH(win->area[0].fbdc_mb_width - 1) |
1324                 V_AFBCD_HREG_PIC_HEIGHT(win->area[0].fbdc_mb_height - 1);
1325         vop_msk_reg(vop_dev, AFBCD0_PIC_SIZE, val);
1326
1327         return 0;
1328 }
1329
1330 static int vop_init_fbdc_config(struct vop_device *vop_dev, int win_id)
1331 {
1332         struct rk_lcdc_driver *vop_drv = &vop_dev->driver;
1333         struct rk_lcdc_win *win = vop_drv->win[win_id];
1334         struct rk_screen *screen = vop_drv->cur_screen;
1335
1336         if (screen->mode.flag & FB_VMODE_INTERLACED) {
1337                 dev_err(vop_dev->dev, "unsupport fbdc+interlace!\n");
1338                 return 0;
1339         }
1340
1341         if (VOP_CHIP(vop_dev) != VOP_RK3399) {
1342                 pr_err("soc: 0x%08x not support FBDC\n", VOP_CHIP(vop_dev));
1343                 return 0;
1344         }
1345
1346         win->area[0].fbdc_mb_width = win->area[0].xvir;
1347         win->area[0].fbdc_mb_height = win->area[0].yact;
1348         win->area[0].fbdc_cor_en = 0; /* hreg_block_split */
1349         win->area[0].fbdc_fmt_cfg |= AFBDC_YUV_COLOR_TRANSFORM << 4;
1350
1351         return 0;
1352 }
1353
1354 static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1355 {
1356         struct vop_device *vop_dev =
1357             container_of(dev_drv, struct vop_device, driver);
1358         struct rk_lcdc_win *win = dev_drv->win[win_id];
1359         u64 val;
1360         u32 off;
1361         int format;
1362         struct rk_win_property *win_property =
1363                                 &dev_drv->win[win_id]->property;
1364
1365         off = win_id * 0x40;
1366
1367         if (win->state == 1) {
1368                 if (!(win_property->feature & SUPPORT_HW_EXIST)) {
1369                         pr_err("vop[%d] win[%d] hardware unsupport\n",
1370                                vop_dev->id, win_id);
1371                         return 0;
1372                 }
1373                 vop_axi_gather_cfg(vop_dev, win);
1374                 if (win->area[0].fbdc_en)
1375                         vop_fbdc_reg_update(vop_dev, win_id);
1376                 /*
1377                  * rk322x have a bug on windows 0 and 1:
1378                  *
1379                  * When switch win format from RGB to YUV, would flash
1380                  * some green lines on the top of the windows.
1381                  *
1382                  * Use bg_en show one blank frame to skip the error frame.
1383                  */
1384                 if (IS_YUV(win->area[0].fmt_cfg)) {
1385                         val = vop_readl(vop_dev, WIN0_CTRL0);
1386                         format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1387
1388                         if (!IS_YUV(format)) {
1389                                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1390                                         val = V_WIN0_DSP_BG_RED(0x200) |
1391                                                 V_WIN0_DSP_BG_GREEN(0x40) |
1392                                                 V_WIN0_DSP_BG_BLUE(0x200) |
1393                                                 V_WIN0_BG_EN(1);
1394                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1395                                                     val);
1396                                 } else {
1397                                         val = V_WIN0_DSP_BG_RED(0) |
1398                                                 V_WIN0_DSP_BG_GREEN(0) |
1399                                                 V_WIN0_DSP_BG_BLUE(0) |
1400                                                 V_WIN0_BG_EN(1);
1401                                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off,
1402                                                     val);
1403                                 }
1404                         } else {
1405                                 val = V_WIN0_BG_EN(0);
1406                                 vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1407                         }
1408                 } else {
1409                         val = V_WIN0_BG_EN(0);
1410                         vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val);
1411                 }
1412
1413                 val = V_WIN0_EN(win->state) |
1414                         V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
1415                         V_WIN0_FMT_10(win->fmt_10) |
1416                         V_WIN0_LB_MODE(win->win_lb_mode) |
1417                         V_WIN0_RB_SWAP(win->area[0].swap_rb) |
1418                         V_WIN0_X_MIR_EN(win->xmirror) |
1419                         V_WIN0_Y_MIR_EN(win->ymirror) |
1420                         V_WIN0_UV_SWAP(win->area[0].swap_uv);
1421                 if (VOP_CHIP(vop_dev) == VOP_RK3399)
1422                         val |= V_WIN0_YUYV(win->area[0].yuyv_fmt);
1423                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1424                 val = V_WIN0_BIC_COE_SEL(win->bic_coe_el) |
1425                     V_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
1426                     V_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
1427                     V_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
1428                     V_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
1429                     V_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
1430                     V_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
1431                     V_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
1432                     V_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
1433                     V_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
1434                     V_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
1435                     V_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
1436                     V_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
1437                     V_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
1438                     V_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
1439                 vop_msk_reg(vop_dev, WIN0_CTRL1 + off, val);
1440                 val = V_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
1441                     V_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
1442                 vop_writel(vop_dev, WIN0_VIR + off, val);
1443                 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
1444                     V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
1445                 vop_writel(vop_dev, WIN0_ACT_INFO + off, val);
1446
1447                 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
1448                     V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
1449                 vop_writel(vop_dev, WIN0_DSP_INFO + off, val);
1450
1451                 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
1452                     V_WIN0_DSP_YST(win->area[0].dsp_sty);
1453                 vop_writel(vop_dev, WIN0_DSP_ST + off, val);
1454
1455                 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
1456                     V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
1457                 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB + off, val);
1458
1459                 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
1460                     V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
1461                 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val);
1462         } else {
1463                 val = V_WIN0_EN(win->state);
1464                 vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
1465         }
1466
1467         return 0;
1468 }
1469
1470 static int area_xst(struct rk_lcdc_win *win, int area_num)
1471 {
1472         struct rk_lcdc_win_area area_temp;
1473         int i, j;
1474
1475         for (i = 0; i < area_num; i++) {
1476                 for (j = i + 1; j < area_num; j++) {
1477                         if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
1478                                 memcpy(&area_temp, &win->area[i],
1479                                        sizeof(struct rk_lcdc_win_area));
1480                                 memcpy(&win->area[i], &win->area[j],
1481                                        sizeof(struct rk_lcdc_win_area));
1482                                 memcpy(&win->area[j], &area_temp,
1483                                        sizeof(struct rk_lcdc_win_area));
1484                         }
1485                 }
1486         }
1487
1488         return 0;
1489 }
1490
1491 static int vop_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1492 {
1493         struct vop_device *vop_dev =
1494                         container_of(dev_drv, struct vop_device, driver);
1495         struct rk_lcdc_win *win = dev_drv->win[win_id];
1496         unsigned int off;
1497         u64 val;
1498         struct rk_win_property *win_property =
1499                                 &dev_drv->win[win_id]->property;
1500
1501         off = (win_id - 2) * 0x50;
1502         area_xst(win, win->area_num);
1503
1504         if (win->state == 1) {
1505                 if (!(win_property->feature & SUPPORT_HW_EXIST)) {
1506                         pr_err("vop[%d] win[%d] hardware unsupport\n",
1507                                vop_dev->id, win_id);
1508                         return 0;
1509                 }
1510                 vop_axi_gather_cfg(vop_dev, win);
1511                 if (win->area[0].fbdc_en)
1512                         vop_fbdc_reg_update(vop_dev, win_id);
1513                 val = V_WIN2_EN(1) | V_WIN1_CSC_MODE(win->csc_mode);
1514                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1515                 /* area 0 */
1516                 if (win->area[0].state == 1) {
1517                         val = V_WIN2_MST0_EN(win->area[0].state) |
1518                             V_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1519                             V_WIN2_RB_SWAP0(win->area[0].swap_rb);
1520                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1521
1522                         val = V_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1523                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1524
1525                         val = V_WIN2_DSP_WIDTH0(win->area[0].xsize - 1) |
1526                             V_WIN2_DSP_HEIGHT0(win->area[0].ysize - 1);
1527                         vop_writel(vop_dev, WIN2_DSP_INFO0 + off, val);
1528                         val = V_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1529                             V_WIN2_DSP_YST0(win->area[0].dsp_sty);
1530                         vop_writel(vop_dev, WIN2_DSP_ST0 + off, val);
1531                 } else {
1532                         val = V_WIN2_MST0_EN(0);
1533                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1534                 }
1535                 /* area 1 */
1536                 if (win->area[1].state == 1) {
1537                         val = V_WIN2_MST1_EN(win->area[1].state) |
1538                             V_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1539                             V_WIN2_RB_SWAP1(win->area[1].swap_rb);
1540                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1541
1542                         val = V_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1543                         vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
1544
1545                         val = V_WIN2_DSP_WIDTH1(win->area[1].xsize - 1) |
1546                             V_WIN2_DSP_HEIGHT1(win->area[1].ysize - 1);
1547                         vop_writel(vop_dev, WIN2_DSP_INFO1 + off, val);
1548                         val = V_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1549                             V_WIN2_DSP_YST1(win->area[1].dsp_sty);
1550                         vop_writel(vop_dev, WIN2_DSP_ST1 + off, val);
1551                 } else {
1552                         val = V_WIN2_MST1_EN(0);
1553                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1554                 }
1555                 /* area 2 */
1556                 if (win->area[2].state == 1) {
1557                         val = V_WIN2_MST2_EN(win->area[2].state) |
1558                             V_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1559                             V_WIN2_RB_SWAP2(win->area[2].swap_rb);
1560                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1561
1562                         val = V_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1563                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1564
1565                         val = V_WIN2_DSP_WIDTH2(win->area[2].xsize - 1) |
1566                             V_WIN2_DSP_HEIGHT2(win->area[2].ysize - 1);
1567                         vop_writel(vop_dev, WIN2_DSP_INFO2 + off, val);
1568                         val = V_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1569                             V_WIN2_DSP_YST2(win->area[2].dsp_sty);
1570                         vop_writel(vop_dev, WIN2_DSP_ST2 + off, val);
1571                 } else {
1572                         val = V_WIN2_MST2_EN(0);
1573                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1574                 }
1575                 /* area 3 */
1576                 if (win->area[3].state == 1) {
1577                         val = V_WIN2_MST3_EN(win->area[3].state) |
1578                             V_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1579                             V_WIN2_RB_SWAP3(win->area[3].swap_rb);
1580                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1581
1582                         val = V_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1583                         vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
1584
1585                         val = V_WIN2_DSP_WIDTH3(win->area[3].xsize - 1) |
1586                             V_WIN2_DSP_HEIGHT3(win->area[3].ysize - 1);
1587                         vop_writel(vop_dev, WIN2_DSP_INFO3 + off, val);
1588                         val = V_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1589                             V_WIN2_DSP_YST3(win->area[3].dsp_sty);
1590                         vop_writel(vop_dev, WIN2_DSP_ST3 + off, val);
1591                 } else {
1592                         val = V_WIN2_MST3_EN(0);
1593                         vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1594                 }
1595         } else {
1596                 val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
1597                     V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
1598                 vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
1599         }
1600
1601         return 0;
1602 }
1603
1604 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1605 {
1606         struct vop_device *vop_dev =
1607             container_of(dev_drv, struct vop_device, driver);
1608         struct rk_lcdc_win *win = dev_drv->win[win_id];
1609         unsigned int hwc_size = 0;
1610         u64 val;
1611
1612         if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32)) {
1613                 hwc_size = 0;
1614         } else if ((win->area[0].xsize == 64) && (win->area[0].ysize == 64)) {
1615                 hwc_size = 1;
1616         } else if ((win->area[0].xsize == 96) && (win->area[0].ysize == 96)) {
1617                 hwc_size = 2;
1618         } else if ((win->area[0].xsize == 128) &&
1619                    (win->area[0].ysize == 128)) {
1620                 hwc_size = 3;
1621         } else {
1622                 dev_err(vop_dev->dev, "un supported hwc size[%dx%d]!\n",
1623                                 win->area[0].xsize, win->area[0].ysize);
1624                 return -EINVAL;
1625         }
1626
1627         if (win->state == 1) {
1628                 vop_axi_gather_cfg(vop_dev, win);
1629                 val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1630                     V_HWC_RB_SWAP(win->area[0].swap_rb);
1631                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1632
1633                 val = V_HWC_SIZE(hwc_size);
1634                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1635
1636                 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
1637                     V_HWC_DSP_YST(win->area[0].dsp_sty);
1638                 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
1639         } else {
1640                 val = V_HWC_EN(win->state);
1641                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
1642         }
1643
1644         return 0;
1645 }
1646
1647 static int vop_layer_update_regs(struct vop_device *vop_dev,
1648                                  struct rk_lcdc_win *win)
1649 {
1650         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
1651
1652         if (likely(vop_dev->clk_on)) {
1653                 vop_msk_reg(vop_dev, SYS_CTRL,
1654                             V_VOP_STANDBY_EN(vop_dev->standby));
1655                 if ((win->id == VOP_WIN0) || (win->id == VOP_WIN1))
1656                         vop_win_0_1_reg_update(dev_drv, win->id);
1657                 else if ((win->id == VOP_WIN2) || (win->id == VOP_WIN3))
1658                         vop_win_2_3_reg_update(dev_drv, win->id);
1659                 else if (win->id == VOP_HWC)
1660                         vop_hwc_reg_update(dev_drv, win->id);
1661                 vop_cfg_done(vop_dev);
1662         }
1663
1664         DBG(2, "%s for lcdc%d\n", __func__, vop_dev->id);
1665         return 0;
1666 }
1667
1668 static int __maybe_unused vop_mmu_en(struct rk_lcdc_driver *dev_drv)
1669 {
1670         u64 val;
1671         struct vop_device *vop_dev =
1672             container_of(dev_drv, struct vop_device, driver);
1673
1674         if (unlikely(!vop_dev->clk_on)) {
1675                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1676                 return 0;
1677         }
1678         if (dev_drv->iommu_enabled) {
1679                 if (!vop_dev->iommu_status && dev_drv->mmu_dev) {
1680                         if (likely(vop_dev->clk_on)) {
1681                                 val = V_VOP_MMU_EN(1);
1682                                 vop_msk_reg(vop_dev, SYS_CTRL, val);
1683                                 val = V_AXI_OUTSTANDING_MAX_NUM(31) |
1684                                         V_AXI_MAX_OUTSTANDING_EN(1);
1685                                 vop_msk_reg(vop_dev, SYS_CTRL1, val);
1686                         }
1687                         vop_dev->iommu_status = 1;
1688                         rockchip_iovmm_activate(dev_drv->dev);
1689                 }
1690         }
1691         return 0;
1692 }
1693
1694 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1695 {
1696         int ret = 0, fps = 0;
1697         struct vop_device *vop_dev =
1698             container_of(dev_drv, struct vop_device, driver);
1699         struct rk_screen *screen = dev_drv->cur_screen;
1700 #ifdef CONFIG_RK_FPGA
1701         return 0;
1702 #endif
1703         if (reset_rate)
1704                 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
1705         if (ret)
1706                 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
1707                         vop_dev->id, screen->mode.pixclock);
1708         vop_dev->pixclock =
1709             div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1710         vop_dev->driver.pixclock = vop_dev->pixclock;
1711
1712         fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
1713         screen->ft = 1000 / fps;
1714         dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
1715                  vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
1716         return 0;
1717 }
1718
1719 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
1720 {
1721         struct vop_device *vop_dev =
1722             container_of(dev_drv, struct vop_device, driver);
1723         struct rk_screen *screen = dev_drv->cur_screen;
1724         u16 hsync_len = screen->mode.hsync_len;
1725         u16 left_margin = screen->mode.left_margin;
1726         u16 right_margin = screen->mode.right_margin;
1727         u16 vsync_len = screen->mode.vsync_len;
1728         u16 upper_margin = screen->mode.upper_margin;
1729         u16 lower_margin = screen->mode.lower_margin;
1730         u16 x_res = screen->mode.xres;
1731         u16 y_res = screen->mode.yres;
1732         u64 val;
1733         u16 h_total, v_total;
1734         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1735
1736         h_total = hsync_len + left_margin + x_res + right_margin;
1737         v_total = vsync_len + upper_margin + y_res + lower_margin;
1738
1739         val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
1740         vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
1741
1742         val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
1743             V_DSP_HACT_ST(hsync_len + left_margin);
1744         vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
1745
1746         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1747                 /* First Field Timing */
1748                 val = V_DSP_VS_END(vsync_len) |
1749                     V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1750                                       lower_margin) + y_res + 1);
1751                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1752
1753                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1754                     V_DSP_VACT_ST(vsync_len + upper_margin);
1755                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1756
1757                 /* Second Field Timing */
1758                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1759                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1760                     lower_margin;
1761                 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
1762                 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
1763
1764                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1765                     lower_margin + 1;
1766                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1767                     lower_margin + 1;
1768                 val = V_DSP_VACT_END_F1(vact_end_f1) |
1769                         V_DSP_VACT_ST_F1(vact_st_f1);
1770                 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
1771                 vop_msk_reg(vop_dev, DSP_CTRL0,
1772                             V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0));
1773
1774                 val = V_DSP_LINE_FLAG_NUM_0(lower_margin ?
1775                                             vact_end_f1 : vact_end_f1 - 1);
1776
1777                 val |= V_DSP_LINE_FLAG_NUM_1(lower_margin ?
1778                                              vact_end_f1 : vact_end_f1 - 1);
1779                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1780         } else {
1781                 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
1782                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
1783
1784                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1785                     V_DSP_VACT_ST(vsync_len + upper_margin);
1786                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
1787
1788                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) |
1789                             V_DSP_FIELD_POL(0));
1790
1791                 val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) |
1792                         V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res);
1793                 vop_msk_reg(vop_dev, LINE_FLAG, val);
1794         }
1795         vop_post_cfg(dev_drv);
1796         if ((x_res <= VOP_INPUT_MAX_WIDTH / 2) && (vop_dev->id == 0))
1797                 vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(1));
1798         else
1799                 vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(0));
1800
1801         return 0;
1802 }
1803
1804 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1805 {
1806         struct vop_device *vop_dev =
1807             container_of(dev_drv, struct vop_device, driver);
1808         u32 bcsh_ctrl;
1809
1810         vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(dev_drv->overlay_mode));
1811         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1812                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1813                         vop_msk_reg(vop_dev, BCSH_CTRL,
1814                                     V_BCSH_Y2R_EN(0) | V_BCSH_R2Y_EN(0));
1815                 else            /* YUV2RGB */
1816                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_Y2R_EN(1) |
1817                                     V_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1818                                     V_BCSH_R2Y_EN(0));
1819         } else {
1820                 /* overlay_mode=VOP_RGB_DOMAIN */
1821                 /* bypass  --need check,if bcsh close? */
1822                 if (dev_drv->output_color == COLOR_RGB) {
1823                         bcsh_ctrl = vop_readl(vop_dev, BCSH_CTRL);
1824                         if (((bcsh_ctrl & MASK(BCSH_EN)) == 1) ||
1825                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1826                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1827                                             V_BCSH_R2Y_EN(1) |
1828                                             V_BCSH_Y2R_EN(1));
1829                         else
1830                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1831                                             V_BCSH_R2Y_EN(0) |
1832                                             V_BCSH_Y2R_EN(0));
1833                 } else {
1834                         /* RGB2YUV */
1835                         vop_msk_reg(vop_dev, BCSH_CTRL,
1836                                     V_BCSH_R2Y_EN(1) |
1837                                     V_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1838                                     V_BCSH_Y2R_EN(0));
1839                 }
1840         }
1841 }
1842
1843 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1844                                u16 *yact, int *format, u32 *dsp_addr,
1845                                int *ymirror)
1846 {
1847         struct vop_device *vop_dev =
1848                         container_of(dev_drv, struct vop_device, driver);
1849         u32 val;
1850
1851         spin_lock(&vop_dev->reg_lock);
1852
1853         val = vop_readl(vop_dev, WIN0_ACT_INFO);
1854         *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1855         *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1856
1857         val = vop_readl(vop_dev, WIN0_CTRL0);
1858         *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1859         *ymirror = (val & MASK(WIN0_Y_MIR_EN)) >> 22;
1860         *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1861
1862         spin_unlock(&vop_dev->reg_lock);
1863
1864         return 0;
1865 }
1866
1867 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1868                            int format, u16 xact, u16 yact, u16 xvir,
1869                            int ymirror)
1870 {
1871         struct vop_device *vop_dev =
1872                         container_of(dev_drv, struct vop_device, driver);
1873         int swap = (format == RGB888) ? 1 : 0;
1874         struct rk_lcdc_win *win = dev_drv->win[0];
1875         u64 val;
1876
1877         val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap) |
1878                 V_WIN0_Y_MIR_EN(ymirror);
1879         vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1880
1881         vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir));
1882         vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1883                    V_WIN0_ACT_HEIGHT(yact - 1));
1884
1885         vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1886
1887         vop_cfg_done(vop_dev);
1888
1889         if (format == RGB888)
1890                 win->area[0].format = BGR888;
1891         else
1892                 win->area[0].format = format;
1893
1894         win->ymirror = ymirror;
1895         win->state = 1;
1896         win->last_state = 1;
1897
1898         return 0;
1899 }
1900
1901 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1902 {
1903         u16 face = 0;
1904         u16 dclk_ddr = 0;
1905         struct vop_device *vop_dev =
1906             container_of(dev_drv, struct vop_device, driver);
1907         struct rk_screen *screen = dev_drv->cur_screen;
1908         u64 val = 0;
1909
1910         if (unlikely(!vop_dev->clk_on)) {
1911                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
1912                 return 0;
1913         }
1914
1915         if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))
1916                 flush_kthread_worker(&dev_drv->update_regs_worker);
1917
1918         spin_lock(&vop_dev->reg_lock);
1919         if (likely(vop_dev->clk_on)) {
1920                 switch (screen->face) {
1921                 case OUT_P565:
1922                         face = OUT_P565;
1923                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1924                                 V_PRE_DITHER_DOWN_EN(1) |
1925                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1926                         break;
1927                 case OUT_P666:
1928                         face = OUT_P666;
1929                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1930                                 V_PRE_DITHER_DOWN_EN(1) |
1931                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1932                         break;
1933                 case OUT_D888_P565:
1934                         face = OUT_P888;
1935                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1936                                 V_PRE_DITHER_DOWN_EN(1) |
1937                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(0);
1938                         break;
1939                 case OUT_D888_P666:
1940                         face = OUT_P888;
1941                         val = V_DITHER_DOWN_EN(1) | V_DITHER_UP_EN(1) |
1942                                 V_PRE_DITHER_DOWN_EN(1) |
1943                                 V_DITHER_DOWN_SEL(1) | V_DITHER_DOWN_MODE(1);
1944                         break;
1945                 case OUT_P888:
1946                         face = OUT_P888;
1947                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1)
1948                                 | V_PRE_DITHER_DOWN_EN(1) |
1949                                 V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0);
1950                         break;
1951                 case OUT_S888x:
1952                         face = OUT_S888x;
1953                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1)
1954                                 | V_PRE_DITHER_DOWN_EN(1) |
1955                                 V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0);
1956                         break;
1957                 case OUT_S888:
1958                         face = OUT_S888;
1959                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1)
1960                                 | V_PRE_DITHER_DOWN_EN(1) |
1961                                 V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0);
1962                         break;
1963                 case OUT_YUV_420:
1964                         face = OUT_YUV_420;
1965                         dclk_ddr = 1;
1966                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1967                                 V_PRE_DITHER_DOWN_EN(1) |
1968                                 V_DITHER_DOWN_SEL(0) |
1969                                 V_DITHER_DOWN_MODE(0);
1970                         break;
1971                 case OUT_YUV_420_10BIT:
1972                         face = OUT_YUV_420;
1973                         dclk_ddr = 1;
1974                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1975                                 V_PRE_DITHER_DOWN_EN(0) |
1976                                 V_DITHER_DOWN_SEL(0) |
1977                                 V_DITHER_DOWN_MODE(0);
1978                         break;
1979                 case OUT_YUV_422:
1980                         face = OUT_YUV_422;
1981                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1982                                 V_PRE_DITHER_DOWN_EN(1) |
1983                                 V_DITHER_DOWN_SEL(0) |
1984                                 V_DITHER_DOWN_MODE(0);
1985                         break;
1986                 case OUT_YUV_422_10BIT:
1987                         face = OUT_YUV_422;
1988                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1989                                 V_PRE_DITHER_DOWN_EN(0) |
1990                                 V_DITHER_DOWN_SEL(0) |
1991                                 V_DITHER_DOWN_MODE(0);
1992                         break;
1993                 case OUT_P101010:
1994                         face = OUT_P101010;
1995                         val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
1996                                 V_PRE_DITHER_DOWN_EN(0) |
1997                                 V_DITHER_DOWN_SEL(0) |
1998                                 V_DITHER_DOWN_MODE(0);
1999                         break;
2000                 default:
2001                         dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
2002                                 screen->face);
2003                         break;
2004                 }
2005
2006                 vop_msk_reg(vop_dev, DSP_CTRL1, val);
2007                 switch (screen->type) {
2008                 case SCREEN_TVOUT:
2009                         val = V_SW_UV_OFFSET_EN(1) | V_SW_IMD_TVE_DCLK_EN(1) |
2010                                 V_SW_IMD_TVE_DCLK_EN(1) |
2011                                 V_SW_IMD_TVE_DCLK_POL(1) |
2012                                 V_SW_GENLOCK(1) | V_SW_DAC_SEL(1);
2013                         if (screen->mode.xres == 720 &&
2014                             screen->mode.yres == 576)
2015                                 val |= V_SW_TVE_MODE(1);
2016                         else
2017                                 val |= V_SW_TVE_MODE(0);
2018                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2019                         break;
2020                 case SCREEN_HDMI:
2021                         if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
2022                             ((screen->face == OUT_P888) ||
2023                              (screen->face == OUT_P101010))) {
2024                                 if (vop_dev->id == 0)
2025                                         face = OUT_P101010; /*RGB 10bit output*/
2026                                 else
2027                                         face = OUT_P888;
2028                         }
2029                         val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
2030                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2031                         val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
2032                                 V_HDMI_VSYNC_POL(screen->pin_vsync) |
2033                                 V_HDMI_DEN_POL(screen->pin_den) |
2034                                 V_HDMI_DCLK_POL(screen->pin_dclk);
2035                         /*hsync vsync den dclk polo,dither */
2036                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
2037                         break;
2038                 case SCREEN_RGB:
2039                 case SCREEN_LVDS:
2040                         val = V_RGB_OUT_EN(1);
2041                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2042                         break;
2043                 case SCREEN_MIPI:
2044                         val = V_MIPI_OUT_EN(1);
2045                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2046                         val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
2047                                 V_MIPI_VSYNC_POL(screen->pin_vsync) |
2048                                 V_MIPI_DEN_POL(screen->pin_den) |
2049                                 V_MIPI_DCLK_POL(screen->pin_dclk);
2050                         /*hsync vsync den dclk polo,dither */
2051                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
2052                         break;
2053                 case SCREEN_DUAL_MIPI:
2054                         val = V_MIPI_OUT_EN(1) | V_MIPI_DUAL_CHANNEL_EN(1);
2055                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2056                         val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
2057                                 V_MIPI_VSYNC_POL(screen->pin_vsync) |
2058                                 V_MIPI_DEN_POL(screen->pin_den) |
2059                                 V_MIPI_DCLK_POL(screen->pin_dclk);
2060                         /*hsync vsync den dclk polo,dither */
2061                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
2062                         break;
2063                 case SCREEN_EDP:
2064                         if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
2065                             (vop_dev->id == 0))
2066                                 face = OUT_P101010;
2067                         val = V_EDP_OUT_EN(1);
2068                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2069                         val = V_EDP_HSYNC_POL(screen->pin_hsync) |
2070                                 V_EDP_VSYNC_POL(screen->pin_vsync) |
2071                                 V_EDP_DEN_POL(screen->pin_den) |
2072                                 V_EDP_DCLK_POL(screen->pin_dclk);
2073                         /*hsync vsync den dclk polo,dither */
2074                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
2075                         break;
2076                 case SCREEN_DP:
2077                         dclk_ddr = 0;
2078                         if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
2079                             ((screen->face == OUT_P888) ||
2080                              (screen->face == OUT_P101010))) {
2081                                 if (vop_dev->id == 0)
2082                                         face = OUT_P101010;
2083                                 else
2084                                         face = OUT_P888;
2085                         }
2086                         val = V_DP_OUT_EN(1);
2087                         vop_msk_reg(vop_dev, SYS_CTRL, val);
2088                         val = V_DP_HSYNC_POL(screen->pin_hsync) |
2089                                 V_DP_VSYNC_POL(screen->pin_vsync) |
2090                                 V_DP_DEN_POL(screen->pin_den) |
2091                                 V_DP_DCLK_POL(screen->pin_dclk);
2092                         /*hsync vsync den dclk polo,dither */
2093                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
2094                         break;
2095                 default:
2096                         dev_err(vop_dev->dev, "un supported interface[%d]!\n",
2097                                 screen->type);
2098                         break;
2099                 }
2100
2101                 if (screen->color_mode == COLOR_RGB)
2102                         dev_drv->overlay_mode = VOP_RGB_DOMAIN;
2103                 else
2104                         dev_drv->overlay_mode = VOP_YUV_DOMAIN;
2105
2106 #ifndef CONFIG_RK_FPGA
2107                 /*
2108                  * Todo:
2109                  * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7);
2110                  *  move to  lvds driver
2111                  */
2112                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
2113 #endif
2114                 val = V_DSP_OUT_MODE(face) | V_DSP_DCLK_DDR(dclk_ddr) |
2115                     V_DSP_BG_SWAP(screen->swap_gb) |
2116                     V_DSP_RB_SWAP(screen->swap_rb) |
2117                     V_DSP_RG_SWAP(screen->swap_rg) |
2118                     V_DSP_DELTA_SWAP(screen->swap_delta) |
2119                     V_DSP_DUMMY_SWAP(screen->swap_dumy) | V_DSP_OUT_ZERO(0) |
2120                     V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0) |
2121                     V_DSP_X_MIR_EN(screen->x_mirror) |
2122                     V_DSP_Y_MIR_EN(screen->y_mirror);
2123                 val |= V_SW_CORE_DCLK_SEL(!!screen->pixelrepeat);
2124                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
2125                         val |= V_SW_HDMI_CLK_I_SEL(1);
2126                 else
2127                         val |= V_SW_HDMI_CLK_I_SEL(0);
2128                 vop_msk_reg(vop_dev, DSP_CTRL0, val);
2129
2130                 if (screen->mode.vmode & FB_VMODE_INTERLACED)
2131                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(1));
2132                 else
2133                         vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(0));
2134                 /* BG color */
2135                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
2136                         val = V_DSP_OUT_RGB_YUV(1);
2137                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2138                         val = V_DSP_BG_BLUE(0x200) | V_DSP_BG_GREEN(0x40) |
2139                                 V_DSP_BG_RED(0x200);
2140                         vop_msk_reg(vop_dev, DSP_BG, val);
2141                 } else {
2142                         val = V_DSP_OUT_RGB_YUV(0);
2143                         vop_msk_reg(vop_dev, POST_SCL_CTRL, val);
2144                         val = V_DSP_BG_BLUE(0x55) | V_DSP_BG_GREEN(0x55) |
2145                                 V_DSP_BG_RED(0x55);
2146                         vop_msk_reg(vop_dev, DSP_BG, val);
2147                 }
2148                 dev_drv->output_color = screen->color_mode;
2149                 vop_bcsh_path_sel(dev_drv);
2150                 vop_config_timing(dev_drv);
2151                 vop_cfg_done(vop_dev);
2152         }
2153         spin_unlock(&vop_dev->reg_lock);
2154         vop_set_dclk(dev_drv, 1);
2155         if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT &&
2156             dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2157                 dev_drv->trsm_ops->enable();
2158         if (screen->init)
2159                 screen->init();
2160
2161         return 0;
2162 }
2163
2164 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv);
2165 static int vop_early_resume(struct rk_lcdc_driver *dev_drv);
2166 /*enable layer,open:1,enable;0 disable*/
2167 static void vop_layer_enable(struct vop_device *vop_dev,
2168                              unsigned int win_id, bool open)
2169 {
2170         spin_lock(&vop_dev->reg_lock);
2171         if (likely(vop_dev->clk_on) &&
2172             vop_dev->driver.win[win_id]->state != open) {
2173                 if (open) {
2174                         if (!vop_dev->atv_layer_cnt) {
2175                                 dev_info(vop_dev->dev,
2176                                          "wakeup from standby!\n");
2177                                 vop_dev->standby = 0;
2178                         }
2179                         vop_dev->atv_layer_cnt |= (1 << win_id);
2180                 } else {
2181                         if (vop_dev->atv_layer_cnt & (1 << win_id))
2182                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
2183                 }
2184                 vop_dev->driver.win[win_id]->state = open;
2185                 if (!open) {
2186                         vop_layer_update_regs(vop_dev,
2187                                               vop_dev->driver.win[win_id]);
2188                         vop_cfg_done(vop_dev);
2189                 }
2190         }
2191         spin_unlock(&vop_dev->reg_lock);
2192         /* if no layer used,disable lcdc */
2193         if (vop_dev->prop == EXTEND) {
2194                 if (!vop_dev->atv_layer_cnt && !open) {
2195                         if (!wait_event_timeout(vop_dev->wait_dmc_queue,
2196                                                 !vop_dev->dmc_in_process, HZ / 5))
2197                                 dev_warn(vop_dev->dev,
2198                                          "Timeout waiting for dmc when vop disable\n");
2199
2200                         vop_dev->vop_switch_status = 1;
2201                         vop_early_suspend(&vop_dev->driver);
2202                         dev_info(vop_dev->dev,
2203                                  "no layer is used,go to standby!\n");
2204                         vop_dev->standby = 1;
2205
2206                         vop_dev->vop_switch_status = 0;
2207                         wake_up(&vop_dev->wait_vop_switch_queue);
2208                         /*
2209                          * if clsoe enxtend vop need to enable dmc again.
2210                          */
2211                         if (vop_dev->devfreq) {
2212                                 if (vop_dev->devfreq_event_dev)
2213                                         devfreq_event_enable_edev(vop_dev->devfreq_event_dev);
2214                                 devfreq_resume_device(vop_dev->devfreq);
2215                         }
2216                 } else if (open) {
2217                         vop_early_resume(&vop_dev->driver);
2218                         vop_dev->vop_switch_status = 0;
2219                         wake_up(&vop_dev->wait_vop_switch_queue);
2220                         /* if enable two vop, need to disable dmc */
2221                         if (vop_dev->devfreq) {
2222                                 if (vop_dev->devfreq_event_dev)
2223                                         devfreq_event_disable_edev(vop_dev->devfreq_event_dev);
2224                                 devfreq_suspend_device(vop_dev->devfreq);
2225                         }
2226                         dev_info(vop_dev->dev, "wake up from standby!\n");
2227                 }
2228         } else if (vop_dev->prop == PRMRY) {
2229                 if ((open) && (!vop_dev->atv_layer_cnt)) {
2230                         vop_dev->vop_switch_status = 0;
2231                         wake_up(&vop_dev->wait_vop_switch_queue);
2232                 }
2233         }
2234 }
2235
2236 static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
2237 {
2238         struct vop_device *vop_dev = container_of(dev_drv,
2239                                                     struct vop_device, driver);
2240         u64 val;
2241         /* struct rk_screen *screen = dev_drv->cur_screen; */
2242
2243         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
2244
2245         val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 |
2246                 INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY |
2247                 INTR_POST_BUF_EMPTY;
2248         val |= val << 16;
2249
2250         vop_msk_reg(vop_dev, INTR_EN0, val);
2251
2252         return 0;
2253 }
2254
2255 static int dmc_notify(struct notifier_block *nb, unsigned long event,
2256                       void *data)
2257 {
2258         struct vop_device *vop = container_of(nb, struct vop_device, dmc_nb);
2259
2260         if (event == DEVFREQ_PRECHANGE) {
2261
2262                 /*
2263                  * check if vop in enable or disable process,
2264                  * if yes, wait until it finish, use 200ms as
2265                  * timeout.
2266                  */
2267                 if (!wait_event_timeout(vop->wait_vop_switch_queue,
2268                                         !vop->vop_switch_status, HZ / 5))
2269                         dev_warn(vop->dev,
2270                                  "Timeout waiting for vop swtich status\n");
2271                 vop->dmc_in_process = 1;
2272         } else if (event == DEVFREQ_POSTCHANGE) {
2273                 vop->dmc_in_process = 0;
2274                 wake_up(&vop->wait_dmc_queue);
2275         }
2276
2277         return NOTIFY_OK;
2278 }
2279
2280 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
2281                     bool open)
2282 {
2283         struct vop_device *vop_dev =
2284             container_of(dev_drv, struct vop_device, driver);
2285
2286         /* enable clk,when first layer open */
2287         if ((open) && (!vop_dev->atv_layer_cnt)) {
2288                 /* rockchip_set_system_status(sys_status); */
2289                 if (!wait_event_timeout(vop_dev->wait_dmc_queue,
2290                                 !vop_dev->dmc_in_process, HZ / 5))
2291                         dev_warn(vop_dev->dev,
2292                                  "Timeout waiting for dmc when vop enable\n");
2293                 vop_dev->vop_switch_status = 1;
2294                 vop_pre_init(dev_drv);
2295                 vop_clk_enable(vop_dev);
2296                 vop_enable_irq(dev_drv);
2297                 if (dev_drv->iommu_enabled) {
2298                         if (!dev_drv->mmu_dev) {
2299                                 dev_drv->mmu_dev =
2300                                     rk_fb_get_sysmmu_device_by_compatible
2301                                     (dev_drv->mmu_dts_name);
2302                                 if (dev_drv->mmu_dev) {
2303                                         rk_fb_platform_set_sysmmu
2304                                             (dev_drv->mmu_dev, dev_drv->dev);
2305                                 } else {
2306                                         dev_err(dev_drv->dev,
2307                                                 "fail get rk iommu device\n");
2308                                         return -1;
2309                                 }
2310                         }
2311                 }
2312                 if ((support_uboot_display() && (vop_dev->prop == PRMRY)))
2313                         vop_set_dclk(dev_drv, 0);
2314                 else
2315                         vop_load_screen(dev_drv, 1);
2316                 if (dev_drv->bcsh.enable)
2317                         vop_set_bcsh(dev_drv, 1);
2318                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
2319                 vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
2320         }
2321
2322         if (win_id < dev_drv->lcdc_win_num)
2323                 vop_layer_enable(vop_dev, win_id, open);
2324         else
2325                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
2326
2327         dev_drv->first_frame = 0;
2328         return 0;
2329 }
2330
2331 static int win_0_1_display(struct vop_device *vop_dev,
2332                            struct rk_lcdc_win *win)
2333 {
2334         u32 y_addr;
2335         u32 uv_addr;
2336         unsigned int off;
2337
2338         off = win->id * 0x40;
2339         /*win->smem_start + win->y_offset; */
2340         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2341         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2342         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2343             vop_dev->id, win->id, y_addr, uv_addr);
2344         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2345             win->area[0].y_offset, win->area[0].c_offset);
2346         spin_lock(&vop_dev->reg_lock);
2347         if (likely(vop_dev->clk_on)) {
2348                 win->area[0].y_addr = y_addr;
2349                 win->area[0].uv_addr = uv_addr;
2350                 vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2351                 vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2352                 if (win->area[0].fbdc_en == 1)
2353                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2354                                    win->area[0].y_addr);
2355         }
2356         spin_unlock(&vop_dev->reg_lock);
2357
2358         return 0;
2359 }
2360
2361 static int win_2_3_display(struct vop_device *vop_dev,
2362                            struct rk_lcdc_win *win)
2363 {
2364         u32 i, y_addr;
2365         unsigned int off;
2366
2367         off = (win->id - 2) * 0x50;
2368         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2369         DBG(2, "lcdc[%d]:win[%d]:", vop_dev->id, win->id);
2370
2371         if (likely(vop_dev->clk_on)) {
2372                 for (i = 0; i < win->area_num; i++) {
2373                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2374                             i, win->area[i].y_addr, win->area[i].y_offset);
2375                         win->area[i].y_addr =
2376                             win->area[i].smem_start + win->area[i].y_offset;
2377                         }
2378                 spin_lock(&vop_dev->reg_lock);
2379                 vop_writel(vop_dev, WIN2_MST0 + off, win->area[0].y_addr);
2380                 vop_writel(vop_dev, WIN2_MST1 + off, win->area[1].y_addr);
2381                 vop_writel(vop_dev, WIN2_MST2 + off, win->area[2].y_addr);
2382                 vop_writel(vop_dev, WIN2_MST3 + off, win->area[3].y_addr);
2383                 if (win->area[0].fbdc_en == 1)
2384                         vop_writel(vop_dev, AFBCD0_HDR_PTR,
2385                                    win->area[0].y_addr);
2386                 spin_unlock(&vop_dev->reg_lock);
2387         }
2388         return 0;
2389 }
2390
2391 static int hwc_display(struct vop_device *vop_dev, struct rk_lcdc_win *win)
2392 {
2393         u32 y_addr;
2394
2395         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2396         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2397             vop_dev->id, __func__, y_addr);
2398         spin_lock(&vop_dev->reg_lock);
2399         if (likely(vop_dev->clk_on)) {
2400                 win->area[0].y_addr = y_addr;
2401                 vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
2402         }
2403         spin_unlock(&vop_dev->reg_lock);
2404
2405         return 0;
2406 }
2407
2408 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2409 {
2410         struct vop_device *vop_dev =
2411             container_of(dev_drv, struct vop_device, driver);
2412         struct rk_lcdc_win *win = NULL;
2413         struct rk_screen *screen = dev_drv->cur_screen;
2414
2415         win = dev_drv->win[win_id];
2416         if (!screen) {
2417                 dev_err(dev_drv->dev, "screen is null!\n");
2418                 return -ENOENT;
2419         }
2420         if (unlikely(!vop_dev->clk_on)) {
2421                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
2422                 return 0;
2423         }
2424         if (win_id == 0) {
2425                 win_0_1_display(vop_dev, win);
2426         } else if (win_id == 1) {
2427                 win_0_1_display(vop_dev, win);
2428         } else if (win_id == 2) {
2429                 win_2_3_display(vop_dev, win);
2430         } else if (win_id == 3) {
2431                 win_2_3_display(vop_dev, win);
2432         } else if (win_id == 4) {
2433                 hwc_display(vop_dev, win);
2434         } else {
2435                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2436                 return -EINVAL;
2437         }
2438
2439         return 0;
2440 }
2441
2442 static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
2443 {
2444         u16 srcW = 0;
2445         u16 srcH = 0;
2446         u16 dstW = 0;
2447         u16 dstH = 0;
2448         u16 yrgb_srcW = 0;
2449         u16 yrgb_srcH = 0;
2450         u16 yrgb_dstW = 0;
2451         u16 yrgb_dstH = 0;
2452         u32 yrgb_vscalednmult = 0;
2453         u32 yrgb_xscl_factor = 0;
2454         u32 yrgb_yscl_factor = 0;
2455         u8 yrgb_vsd_bil_gt2 = 0;
2456         u8 yrgb_vsd_bil_gt4 = 0;
2457
2458         u16 cbcr_srcW = 0;
2459         u16 cbcr_srcH = 0;
2460         u16 cbcr_dstW = 0;
2461         u16 cbcr_dstH = 0;
2462         u32 cbcr_vscalednmult = 0;
2463         u32 cbcr_xscl_factor = 0;
2464         u32 cbcr_yscl_factor = 0;
2465         u8 cbcr_vsd_bil_gt2 = 0;
2466         u8 cbcr_vsd_bil_gt4 = 0;
2467         u8 yuv_fmt = 0;
2468
2469         srcW = win->area[0].xact;
2470         if ((screen->mode.vmode & FB_VMODE_INTERLACED) &&
2471             (win->area[0].yact == 2 * win->area[0].ysize)) {
2472                 srcH = win->area[0].yact / 2;
2473                 yrgb_vsd_bil_gt2 = 1;
2474                 cbcr_vsd_bil_gt2 = 1;
2475         } else {
2476                 srcH = win->area[0].yact;
2477         }
2478         dstW = win->area[0].xsize;
2479         dstH = win->area[0].ysize;
2480
2481         /*yrgb scl mode */
2482         yrgb_srcW = srcW;
2483         yrgb_srcH = srcH;
2484         yrgb_dstW = dstW;
2485         yrgb_dstH = dstH;
2486         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2487                 pr_err("ERROR: yrgb scale exceed 8,");
2488                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2489                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2490         }
2491         if (yrgb_srcW < yrgb_dstW)
2492                 win->yrgb_hor_scl_mode = SCALE_UP;
2493         else if (yrgb_srcW > yrgb_dstW)
2494                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2495         else
2496                 win->yrgb_hor_scl_mode = SCALE_NONE;
2497
2498         if (yrgb_srcH < yrgb_dstH)
2499                 win->yrgb_ver_scl_mode = SCALE_UP;
2500         else if (yrgb_srcH > yrgb_dstH)
2501                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2502         else
2503                 win->yrgb_ver_scl_mode = SCALE_NONE;
2504
2505         /*cbcr scl mode */
2506         switch (win->area[0].format) {
2507         case YUV422:
2508         case YUYV422:
2509         case UYVY422:
2510         case YUV422_A:
2511                 cbcr_srcW = srcW / 2;
2512                 cbcr_dstW = dstW;
2513                 cbcr_srcH = srcH;
2514                 cbcr_dstH = dstH;
2515                 yuv_fmt = 1;
2516                 break;
2517         case YUV420:
2518         case YUYV420:
2519         case UYVY420:
2520         case YUV420_A:
2521         case YUV420_NV21:
2522                 cbcr_srcW = srcW / 2;
2523                 cbcr_dstW = dstW;
2524                 cbcr_srcH = srcH / 2;
2525                 cbcr_dstH = dstH;
2526                 yuv_fmt = 1;
2527                 break;
2528         case YUV444:
2529         case YUV444_A:
2530                 cbcr_srcW = srcW;
2531                 cbcr_dstW = dstW;
2532                 cbcr_srcH = srcH;
2533                 cbcr_dstH = dstH;
2534                 yuv_fmt = 1;
2535                 break;
2536         default:
2537                 cbcr_srcW = 0;
2538                 cbcr_dstW = 0;
2539                 cbcr_srcH = 0;
2540                 cbcr_dstH = 0;
2541                 yuv_fmt = 0;
2542                 break;
2543         }
2544         if (yuv_fmt) {
2545                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2546                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2547                         pr_err("ERROR: cbcr scale exceed 8,");
2548                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2549                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2550                 }
2551         }
2552
2553         if (cbcr_srcW < cbcr_dstW)
2554                 win->cbr_hor_scl_mode = SCALE_UP;
2555         else if (cbcr_srcW > cbcr_dstW)
2556                 win->cbr_hor_scl_mode = SCALE_DOWN;
2557         else
2558                 win->cbr_hor_scl_mode = SCALE_NONE;
2559
2560         if (cbcr_srcH < cbcr_dstH)
2561                 win->cbr_ver_scl_mode = SCALE_UP;
2562         else if (cbcr_srcH > cbcr_dstH)
2563                 win->cbr_ver_scl_mode = SCALE_DOWN;
2564         else
2565                 win->cbr_ver_scl_mode = SCALE_NONE;
2566
2567         /* line buffer mode */
2568         if ((win->area[0].format == YUV422) ||
2569             (win->area[0].format == YUV420) ||
2570             (win->area[0].format == YUYV422) ||
2571             (win->area[0].format == YUYV420) ||
2572             (win->area[0].format == UYVY422) ||
2573             (win->area[0].format == UYVY420) ||
2574             (win->area[0].format == YUV420_NV21) ||
2575             (win->area[0].format == YUV422_A) ||
2576             (win->area[0].format == YUV420_A)) {
2577                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2578                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2579                             (cbcr_dstW == 0))
2580                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2581                                        cbcr_dstW);
2582                         else if (cbcr_dstW > 1280)
2583                                 win->win_lb_mode = LB_YUV_3840X5;
2584                         else
2585                                 win->win_lb_mode = LB_YUV_2560X8;
2586                 } else {        /* SCALE_UP or SCALE_NONE */
2587                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2588                             (cbcr_srcW == 0))
2589                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2590                                        cbcr_srcW);
2591                         else if (cbcr_srcW > 1280)
2592                                 win->win_lb_mode = LB_YUV_3840X5;
2593                         else
2594                                 win->win_lb_mode = LB_YUV_2560X8;
2595                 }
2596         } else {
2597                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2598                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2599                             (yrgb_dstW == 0))
2600                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2601                         else if (yrgb_dstW > 2560)
2602                                 win->win_lb_mode = LB_RGB_3840X2;
2603                         else if (yrgb_dstW > 1920)
2604                                 win->win_lb_mode = LB_RGB_2560X4;
2605                         else if (yrgb_dstW > 1280)
2606                                 win->win_lb_mode = LB_RGB_1920X5;
2607                         else
2608                                 win->win_lb_mode = LB_RGB_1280X8;
2609                 } else {        /* SCALE_UP or SCALE_NONE */
2610                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2611                             (yrgb_srcW == 0))
2612                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2613                         else if (yrgb_srcW > 2560)
2614                                 win->win_lb_mode = LB_RGB_3840X2;
2615                         else if (yrgb_srcW > 1920)
2616                                 win->win_lb_mode = LB_RGB_2560X4;
2617                         else if (yrgb_srcW > 1280)
2618                                 win->win_lb_mode = LB_RGB_1920X5;
2619                         else
2620                                 win->win_lb_mode = LB_RGB_1280X8;
2621                 }
2622         }
2623         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2624
2625         /* vsd/vsu scale ALGORITHM */
2626         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2627         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2628         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2629         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2630
2631         /* if (VOP_CHIP(vop_dev) == VOP_RK3399) { */
2632         if ((win->area[0].format == YUYV422) ||
2633             (win->area[0].format == YUYV420) ||
2634             (win->area[0].format == UYVY422) ||
2635             (win->area[0].format == UYVY420)) {
2636                 yrgb_vscalednmult =
2637                         vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2638                 if (yrgb_vscalednmult == 4) {
2639                         yrgb_vsd_bil_gt4 = 1;
2640                         yrgb_vsd_bil_gt2 = 0;
2641                 } else if (yrgb_vscalednmult == 2) {
2642                         yrgb_vsd_bil_gt4 = 0;
2643                         yrgb_vsd_bil_gt2 = 1;
2644                 } else {
2645                         yrgb_vsd_bil_gt4 = 0;
2646                         yrgb_vsd_bil_gt2 = 0;
2647                 }
2648                 if ((win->area[0].format == YUYV420) ||
2649                     (win->area[0].format == UYVY420)) {
2650                         if ((yrgb_vsd_bil_gt4 == 1) || (yrgb_vsd_bil_gt2 == 1))
2651                                 win->yrgb_vsd_mode = SCALE_DOWN_AVG;
2652                 }
2653
2654                 cbcr_vscalednmult =
2655                         vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2656                 if (cbcr_vscalednmult == 4) {
2657                         cbcr_vsd_bil_gt4 = 1;
2658                         cbcr_vsd_bil_gt2 = 0;
2659                 } else if (cbcr_vscalednmult == 2) {
2660                         cbcr_vsd_bil_gt4 = 0;
2661                         cbcr_vsd_bil_gt2 = 1;
2662                 } else {
2663                         cbcr_vsd_bil_gt4 = 0;
2664                         cbcr_vsd_bil_gt2 = 0;
2665                 }
2666                 if ((win->area[0].format == YUYV420) ||
2667                     (win->area[0].format == UYVY420)) {
2668                         if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1))
2669                                 win->cbr_vsd_mode = SCALE_DOWN_AVG;
2670                 }
2671                 /* CBCR vsd_mode must same to YRGB for YUYV when gt2 or gt4 */
2672                 if ((cbcr_vsd_bil_gt4 == 1) || (cbcr_vsd_bil_gt2 == 1)) {
2673                         if (win->yrgb_vsd_mode != win->cbr_vsd_mode)
2674                                 win->cbr_vsd_mode = win->yrgb_vsd_mode;
2675                 }
2676         }
2677         /* 3399 yuyv support*/
2678         if (win->ymirror == 1) {
2679                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2680                         pr_info("y_mirror enable, y-vsd AVG mode unsupprot\n");
2681                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2682         }
2683         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
2684                 if (win->yrgb_vsd_mode == SCALE_DOWN_AVG)
2685                         pr_info("interlace mode, y-vsd AVG mode unsupprot\n");
2686                 /* interlace mode must bill */
2687                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2688                 win->cbr_vsd_mode = SCALE_DOWN_BIL;
2689         }
2690         switch (win->win_lb_mode) {
2691         case LB_YUV_3840X5:
2692         case LB_YUV_2560X8:
2693         case LB_RGB_1920X5:
2694         case LB_RGB_1280X8:
2695                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2696                 win->cbr_vsu_mode = SCALE_UP_BIC;
2697                 break;
2698         case LB_RGB_3840X2:
2699                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2700                         pr_err("ERROR : not allow yrgb ver scale\n");
2701                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2702                         pr_err("ERROR : not allow cbcr ver scale\n");
2703                 break;
2704         case LB_RGB_2560X4:
2705                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2706                 win->cbr_vsu_mode = SCALE_UP_BIL;
2707                 break;
2708         default:
2709                 pr_info("%s:un supported win_lb_mode:%d\n",
2710                         __func__, win->win_lb_mode);
2711                 break;
2712         }
2713
2714         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2715             (win->area[0].fbdc_en == 1)) {
2716                 /* in this pattern,use bil mode,not support souble scd,
2717                  * use avg mode, support double scd, but aclk should be
2718                  * bigger than dclk.
2719                  */
2720                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2721                         pr_err("ERROR : fbdc mode,not support y scale down:");
2722                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2723                                yrgb_srcH, yrgb_dstH);
2724                 }
2725         }
2726         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2727             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2728             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2729
2730         /* SCALE FACTOR */
2731
2732         /* (1.1)YRGB HOR SCALE FACTOR */
2733         switch (win->yrgb_hor_scl_mode) {
2734         case SCALE_NONE:
2735                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2736                 break;
2737         case SCALE_UP:
2738                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2739                 break;
2740         case SCALE_DOWN:
2741                 switch (win->yrgb_hsd_mode) {
2742                 case SCALE_DOWN_BIL:
2743                         yrgb_xscl_factor =
2744                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2745                         break;
2746                 case SCALE_DOWN_AVG:
2747                         yrgb_xscl_factor =
2748                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2749                         break;
2750                 default:
2751                         pr_info("%s:un supported yrgb_hsd_mode:%d\n", __func__,
2752                                 win->yrgb_hsd_mode);
2753                         break;
2754                 }
2755                 break;
2756         default:
2757                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2758                         __func__, win->yrgb_hor_scl_mode);
2759                 break;
2760         }
2761
2762         /* (1.2)YRGB VER SCALE FACTOR */
2763         switch (win->yrgb_ver_scl_mode) {
2764         case SCALE_NONE:
2765                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2766                 break;
2767         case SCALE_UP:
2768                 switch (win->yrgb_vsu_mode) {
2769                 case SCALE_UP_BIL:
2770                         yrgb_yscl_factor =
2771                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2772                         break;
2773                 case SCALE_UP_BIC:
2774                         if (yrgb_srcH < 3) {
2775                                 pr_err("yrgb_srcH should be");
2776                                 pr_err(" greater than 3 !!!\n");
2777                         }
2778                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2779                                                                 yrgb_dstH);
2780                         break;
2781                 default:
2782                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2783                                 __func__, win->yrgb_vsu_mode);
2784                         break;
2785                 }
2786                 break;
2787         case SCALE_DOWN:
2788                 switch (win->yrgb_vsd_mode) {
2789                 case SCALE_DOWN_BIL:
2790                         yrgb_vscalednmult =
2791                             vop_get_hard_ware_vskiplines(yrgb_srcH, yrgb_dstH);
2792                         yrgb_yscl_factor =
2793                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2794                                                            yrgb_vscalednmult);
2795                         if (yrgb_yscl_factor >= 0x2000) {
2796                                 pr_err("yrgb_yscl_factor should less 0x2000");
2797                                 pr_err("yrgb_yscl_factor=%4x;\n",
2798                                        yrgb_yscl_factor);
2799                         }
2800                         if (yrgb_vscalednmult == 4) {
2801                                 yrgb_vsd_bil_gt4 = 1;
2802                                 yrgb_vsd_bil_gt2 = 0;
2803                         } else if (yrgb_vscalednmult == 2) {
2804                                 yrgb_vsd_bil_gt4 = 0;
2805                                 yrgb_vsd_bil_gt2 = 1;
2806                         } else {
2807                                 yrgb_vsd_bil_gt4 = 0;
2808                                 yrgb_vsd_bil_gt2 = 0;
2809                         }
2810                         break;
2811                 case SCALE_DOWN_AVG:
2812                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2813                                                                  yrgb_dstH);
2814                         break;
2815                 default:
2816                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2817                                 __func__, win->yrgb_vsd_mode);
2818                         break;
2819                 }               /*win->yrgb_vsd_mode */
2820                 break;
2821         default:
2822                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2823                         __func__, win->yrgb_ver_scl_mode);
2824                 break;
2825         }
2826         win->scale_yrgb_x = yrgb_xscl_factor;
2827         win->scale_yrgb_y = yrgb_yscl_factor;
2828         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2829         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2830         DBG(1, "yrgb:h_fac=%d, V_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2831             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2832
2833         /*(2.1)CBCR HOR SCALE FACTOR */
2834         switch (win->cbr_hor_scl_mode) {
2835         case SCALE_NONE:
2836                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2837                 break;
2838         case SCALE_UP:
2839                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2840                 break;
2841         case SCALE_DOWN:
2842                 switch (win->cbr_hsd_mode) {
2843                 case SCALE_DOWN_BIL:
2844                         cbcr_xscl_factor =
2845                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2846                         break;
2847                 case SCALE_DOWN_AVG:
2848                         cbcr_xscl_factor =
2849                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2850                         break;
2851                 default:
2852                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2853                                 __func__, win->cbr_hsd_mode);
2854                         break;
2855                 }
2856                 break;
2857         default:
2858                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2859                         __func__, win->cbr_hor_scl_mode);
2860                 break;
2861         }                       /*win->cbr_hor_scl_mode */
2862
2863         /* (2.2)CBCR VER SCALE FACTOR */
2864         switch (win->cbr_ver_scl_mode) {
2865         case SCALE_NONE:
2866                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2867                 break;
2868         case SCALE_UP:
2869                 switch (win->cbr_vsu_mode) {
2870                 case SCALE_UP_BIL:
2871                         cbcr_yscl_factor =
2872                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2873                         break;
2874                 case SCALE_UP_BIC:
2875                         if (cbcr_srcH < 3) {
2876                                 pr_err("cbcr_srcH should be ");
2877                                 pr_err("greater than 3 !!!\n");
2878                         }
2879                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2880                                                                 cbcr_dstH);
2881                         break;
2882                 default:
2883                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2884                                 __func__, win->cbr_vsu_mode);
2885                         break;
2886                 }
2887                 break;
2888         case SCALE_DOWN:
2889                 switch (win->cbr_vsd_mode) {
2890                 case SCALE_DOWN_BIL:
2891                         cbcr_vscalednmult =
2892                             vop_get_hard_ware_vskiplines(cbcr_srcH, cbcr_dstH);
2893                         cbcr_yscl_factor =
2894                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2895                                                            cbcr_vscalednmult);
2896                         if (cbcr_yscl_factor >= 0x2000) {
2897                                 pr_err("cbcr_yscl_factor should be less ");
2898                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2899                                        cbcr_yscl_factor);
2900                         }
2901
2902                         if (cbcr_vscalednmult == 4) {
2903                                 cbcr_vsd_bil_gt4 = 1;
2904                                 cbcr_vsd_bil_gt2 = 0;
2905                         } else if (cbcr_vscalednmult == 2) {
2906                                 cbcr_vsd_bil_gt4 = 0;
2907                                 cbcr_vsd_bil_gt2 = 1;
2908                         } else {
2909                                 cbcr_vsd_bil_gt4 = 0;
2910                                 cbcr_vsd_bil_gt2 = 0;
2911                         }
2912                         break;
2913                 case SCALE_DOWN_AVG:
2914                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2915                                                                  cbcr_dstH);
2916                         break;
2917                 default:
2918                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2919                                 __func__, win->cbr_vsd_mode);
2920                         break;
2921                 }
2922                 break;
2923         default:
2924                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2925                         __func__, win->cbr_ver_scl_mode);
2926                 break;
2927         }
2928         win->scale_cbcr_x = cbcr_xscl_factor;
2929         win->scale_cbcr_y = cbcr_yscl_factor;
2930         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2931         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2932
2933         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2934             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2935         return 0;
2936 }
2937
2938 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2939                      struct rk_lcdc_win_area *area)
2940 {
2941         int pos;
2942
2943         if (screen->x_mirror && mirror_en)
2944                 pr_err("not support both win and global mirror\n");
2945
2946         if ((!mirror_en) && (!screen->x_mirror))
2947                 pos = area->xpos + screen->mode.left_margin +
2948                         screen->mode.hsync_len;
2949         else
2950                 pos = screen->mode.xres - area->xpos -
2951                         area->xsize + screen->mode.left_margin +
2952                         screen->mode.hsync_len;
2953
2954         return pos;
2955 }
2956
2957 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2958                      struct rk_lcdc_win_area *area)
2959 {
2960         int pos;
2961
2962         if (screen->y_mirror && mirror_en)
2963                 pr_err("not support both win and global mirror\n");
2964
2965         if ((!mirror_en) && (!screen->y_mirror))
2966                 pos = area->ypos + screen->mode.upper_margin +
2967                         screen->mode.vsync_len;
2968         else
2969                 pos = screen->mode.yres - area->ypos -
2970                         area->ysize + screen->mode.upper_margin +
2971                         screen->mode.vsync_len;
2972
2973         return pos;
2974 }
2975
2976 static int win_0_1_set_par(struct vop_device *vop_dev,
2977                            struct rk_screen *screen, struct rk_lcdc_win *win)
2978 {
2979         u32 xact = 0, yact = 0, xvir = 0, yvir = 0, xpos = 0, ypos = 0;
2980         u8 fmt_cfg = 0, swap_rb = 0, swap_uv = 0;
2981         char fmt[9] = "NULL";
2982
2983         xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]);
2984         ypos = dsp_y_pos(win->ymirror, screen, &win->area[0]);
2985
2986         spin_lock(&vop_dev->reg_lock);
2987         if (likely(vop_dev->clk_on)) {
2988                 vop_cal_scl_fac(win, screen);
2989                 switch (win->area[0].format) {
2990                 case FBDC_RGB_565:
2991                         fmt_cfg = 2;
2992                         swap_rb = 0;
2993                         win->fmt_10 = 0;
2994                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_RGB565;
2995                         break;
2996                 case FBDC_ARGB_888:
2997                         fmt_cfg = 0;
2998                         swap_rb = 1;
2999                         win->fmt_10 = 0;
3000                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3001                         break;
3002                 case FBDC_ABGR_888:
3003                         fmt_cfg = 0;
3004                         swap_rb = 0;
3005                         win->fmt_10 = 0;
3006                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3007                         break;
3008                 case FBDC_RGBX_888:
3009                         fmt_cfg = 0;
3010                         swap_rb = 0;
3011                         win->fmt_10 = 0;
3012                         win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3013                         break;
3014                 case ARGB888:
3015                         fmt_cfg = 0;
3016                         swap_rb = 0;
3017                         win->fmt_10 = 0;
3018                         break;
3019                 case XBGR888:
3020                 case ABGR888:
3021                         fmt_cfg = 0;
3022                         swap_rb = 1;
3023                         win->fmt_10 = 0;
3024                         break;
3025                 case BGR888:
3026                         fmt_cfg = 1;
3027                         swap_rb = 1;
3028                         win->fmt_10 = 0;
3029                         break;
3030                 case RGB888:
3031                         fmt_cfg = 1;
3032                         swap_rb = 0;
3033                         win->fmt_10 = 0;
3034                         break;
3035                 case RGB565:
3036                         fmt_cfg = 2;
3037                         swap_rb = 0;
3038                         win->fmt_10 = 0;
3039                         break;
3040                 case YUV422:
3041                         fmt_cfg = 5;
3042                         swap_rb = 0;
3043                         win->fmt_10 = 0;
3044                         break;
3045                 case YUV420:
3046                         fmt_cfg = 4;
3047                         swap_rb = 0;
3048                         win->fmt_10 = 0;
3049                         break;
3050                 case YUV420_NV21:
3051                         fmt_cfg = 4;
3052                         swap_rb = 0;
3053                         swap_uv = 1;
3054                         win->fmt_10 = 0;
3055                         break;
3056                 case YUV444:
3057                         fmt_cfg = 6;
3058                         swap_rb = 0;
3059                         win->fmt_10 = 0;
3060                         break;
3061                 case YUV422_A:
3062                         fmt_cfg = 5;
3063                         swap_rb = 0;
3064                         win->fmt_10 = 1;
3065                         break;
3066                 case YUV420_A:
3067                         fmt_cfg = 4;
3068                         swap_rb = 0;
3069                         win->fmt_10 = 1;
3070                         break;
3071                 case YUV444_A:
3072                         fmt_cfg = 6;
3073                         swap_rb = 0;
3074                         win->fmt_10 = 1;
3075                         break;
3076                 case YUYV422:
3077                         fmt_cfg = 0;
3078                         swap_rb = 0;
3079                         win->fmt_10 = 0;
3080                         win->area[0].yuyv_fmt = 1;
3081                         break;
3082                 case YUYV420:
3083                         fmt_cfg = 1;
3084                         swap_rb = 0;
3085                         win->fmt_10 = 0;
3086                         win->area[0].yuyv_fmt = 1;
3087                         break;
3088                 case UYVY422:
3089                         fmt_cfg = 2;
3090                         swap_rb = 0;
3091                         win->fmt_10 = 0;
3092                         win->area[0].yuyv_fmt = 1;
3093                         break;
3094                 case UYVY420:
3095                         fmt_cfg = 3;
3096                         swap_rb = 0;
3097                         win->fmt_10 = 0;
3098                         win->area[0].yuyv_fmt = 1;
3099                         break;
3100                 default:
3101                         dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
3102                                 __func__, win->area[0].format);
3103                         break;
3104                 }
3105                 win->area[0].fmt_cfg = fmt_cfg;
3106                 win->area[0].swap_rb = swap_rb;
3107                 win->area[0].swap_uv = swap_uv;
3108                 win->area[0].dsp_stx = xpos;
3109                 win->area[0].dsp_sty = ypos;
3110                 xact = win->area[0].xact;
3111                 yact = win->area[0].yact;
3112                 xvir = win->area[0].xvir;
3113                 yvir = win->area[0].yvir;
3114         }
3115         if (win->area[0].fbdc_en)
3116                 vop_init_fbdc_config(vop_dev, win->id);
3117         vop_win_0_1_reg_update(&vop_dev->driver, win->id);
3118         spin_unlock(&vop_dev->reg_lock);
3119
3120         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3121             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
3122             xact, yact, win->area[0].xsize);
3123         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3124             win->area[0].ysize, xvir, yvir, xpos, ypos);
3125
3126         return 0;
3127 }
3128
3129 static int win_2_3_set_par(struct vop_device *vop_dev,
3130                            struct rk_screen *screen, struct rk_lcdc_win *win)
3131 {
3132         int i;
3133         u8 fmt_cfg = 0, swap_rb = 0;
3134         char fmt[9] = "NULL";
3135
3136         if (VOP_CHIP(vop_dev) == VOP_RK322X) {
3137                 pr_err("rk3228 not support win2/3 set par\n");
3138                 return -EINVAL;
3139         }
3140         if (win->ymirror) {
3141                 pr_err("win[%d] not support y mirror\n", win->id);
3142                 return -EINVAL;
3143         }
3144         spin_lock(&vop_dev->reg_lock);
3145         if (likely(vop_dev->clk_on)) {
3146                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", vop_dev->id, win->id);
3147                 for (i = 0; i < win->area_num; i++) {
3148                         switch (win->area[i].format) {
3149                         case FBDC_RGB_565:
3150                                 fmt_cfg = 2;
3151                                 swap_rb = 0;
3152                                 win->fmt_10 = 0;
3153                                 win->area[0].fbdc_fmt_cfg = AFBDC_FMT_RGB565;
3154                                 break;
3155                         case FBDC_ARGB_888:
3156                                 fmt_cfg = 0;
3157                                 swap_rb = 1;
3158                                 win->fmt_10 = 0;
3159                                 win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3160                                 break;
3161                         case FBDC_ABGR_888:
3162                                 fmt_cfg = 0;
3163                                 swap_rb = 0;
3164                                 win->fmt_10 = 0;
3165                                 win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3166                                 break;
3167                         case FBDC_RGBX_888:
3168                                 fmt_cfg = 0;
3169                                 swap_rb = 0;
3170                                 win->fmt_10 = 0;
3171                                 win->area[0].fbdc_fmt_cfg = AFBDC_FMT_U8U8U8U8;
3172                                 break;
3173                         case ARGB888:
3174                                 fmt_cfg = 0;
3175                                 swap_rb = 0;
3176                                 break;
3177                         case XBGR888:
3178                         case ABGR888:
3179                                 fmt_cfg = 0;
3180                                 swap_rb = 1;
3181                                 break;
3182                         case RGB888:
3183                                 fmt_cfg = 1;
3184                                 swap_rb = 0;
3185                                 break;
3186                         case RGB565:
3187                                 fmt_cfg = 2;
3188                                 swap_rb = 0;
3189                                 break;
3190                         default:
3191                                 dev_err(vop_dev->driver.dev,
3192                                         "%s:un supported format!\n", __func__);
3193                                 spin_unlock(&vop_dev->reg_lock);
3194                                 return -EINVAL;
3195                         }
3196                         win->area[i].fmt_cfg = fmt_cfg;
3197                         win->area[i].swap_rb = swap_rb;
3198                         win->area[i].dsp_stx = dsp_x_pos(win->xmirror, screen,
3199                                                          &win->area[i]);
3200                         win->area[i].dsp_sty = dsp_y_pos(win->ymirror, screen,
3201                                                          &win->area[i]);
3202                         if (((win->area[i].xact != win->area[i].xsize) ||
3203                              (win->area[i].yact != win->area[i].ysize)) &&
3204                             (screen->mode.vmode == FB_VMODE_NONINTERLACED)) {
3205                                 pr_err("win[%d]->area[%d],not support scale\n",
3206                                        win->id, i);
3207                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
3208                                        win->area[i].xact, win->area[i].yact,
3209                                        win->area[i].xsize, win->area[i].ysize);
3210                                 win->area[i].xsize = win->area[i].xact;
3211                                 win->area[i].ysize = win->area[i].yact;
3212                         }
3213                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
3214                             get_format_string(win->area[i].format, fmt),
3215                             win->area[i].xsize, win->area[i].ysize,
3216                             win->area[i].xpos, win->area[i].ypos);
3217                 }
3218         }
3219         if (win->area[0].fbdc_en)
3220                 vop_init_fbdc_config(vop_dev, win->id);
3221         vop_win_2_3_reg_update(&vop_dev->driver, win->id);
3222         spin_unlock(&vop_dev->reg_lock);
3223         return 0;
3224 }
3225
3226 static int hwc_set_par(struct vop_device *vop_dev,
3227                        struct rk_screen *screen, struct rk_lcdc_win *win)
3228 {
3229         u32 xact = 0, yact = 0, xvir = 0, yvir = 0, xpos = 0, ypos = 0;
3230         u8 fmt_cfg = 0, swap_rb = 0;
3231         char fmt[9] = "NULL";
3232
3233         xpos = win->area[0].xpos + screen->mode.left_margin +
3234             screen->mode.hsync_len;
3235         ypos = win->area[0].ypos + screen->mode.upper_margin +
3236             screen->mode.vsync_len;
3237
3238         spin_lock(&vop_dev->reg_lock);
3239         if (likely(vop_dev->clk_on)) {
3240                 switch (win->area[0].format) {
3241                 case ARGB888:
3242                         fmt_cfg = 0;
3243                         swap_rb = 0;
3244                         break;
3245                 case XBGR888:
3246                 case ABGR888:
3247                         fmt_cfg = 0;
3248                         swap_rb = 1;
3249                         break;
3250                 case RGB888:
3251                         fmt_cfg = 1;
3252                         swap_rb = 0;
3253                         break;
3254                 case RGB565:
3255                         fmt_cfg = 2;
3256                         swap_rb = 0;
3257                         break;
3258                 default:
3259                         dev_err(vop_dev->dev, "%s:un supported format[%d]!\n",
3260                                 __func__, win->area[0].format);
3261                         break;
3262                 }
3263                 win->area[0].fmt_cfg = fmt_cfg;
3264                 win->area[0].swap_rb = swap_rb;
3265                 win->area[0].dsp_stx = xpos;
3266                 win->area[0].dsp_sty = ypos;
3267                 xact = win->area[0].xact;
3268                 yact = win->area[0].yact;
3269                 xvir = win->area[0].xvir;
3270                 yvir = win->area[0].yvir;
3271         }
3272         vop_hwc_reg_update(&vop_dev->driver, 4);
3273         spin_unlock(&vop_dev->reg_lock);
3274
3275         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3276             vop_dev->id, __func__, get_format_string(win->area[0].format, fmt),
3277             xact, yact, win->area[0].xsize);
3278         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3279             win->area[0].ysize, xvir, yvir, xpos, ypos);
3280         return 0;
3281 }
3282
3283 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
3284 {
3285         struct vop_device *vop_dev =
3286             container_of(dev_drv, struct vop_device, driver);
3287         struct rk_lcdc_win *win = NULL;
3288         struct rk_screen *screen = dev_drv->cur_screen;
3289
3290         if (unlikely(!vop_dev->clk_on)) {
3291                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3292                 return 0;
3293         }
3294         win = dev_drv->win[win_id];
3295         if (win)
3296         switch (win_id) {
3297         case 0:
3298                 win_0_1_set_par(vop_dev, screen, win);
3299                 break;
3300         case 1:
3301                 win_0_1_set_par(vop_dev, screen, win);
3302                 break;
3303         case 2:
3304                 win_2_3_set_par(vop_dev, screen, win);
3305                 break;
3306         case 3:
3307                 win_2_3_set_par(vop_dev, screen, win);
3308                 break;
3309         case 4:
3310                 hwc_set_par(vop_dev, screen, win);
3311                 break;
3312         default:
3313                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
3314                 break;
3315         }
3316         return 0;
3317 }
3318
3319 static int vop_set_writeback(struct rk_lcdc_driver *dev_drv)
3320 {
3321         struct vop_device *vop_dev =
3322             container_of(dev_drv, struct vop_device, driver);
3323         int output_color = dev_drv->output_color;
3324         struct rk_screen *screen = dev_drv->cur_screen;
3325         struct rk_fb_reg_wb_data *wb_data;
3326         int xact = screen->mode.xres;
3327         int yact = screen->mode.yres;
3328         u32 fmt_cfg;
3329         int xsize, ysize;
3330         u64 v;
3331
3332         if (unlikely(!vop_dev->clk_on)) {
3333                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
3334                 return 0;
3335         }
3336         wb_data = &dev_drv->wb_data;
3337         if ((wb_data->xsize == 0) || (wb_data->ysize == 0))
3338                 return 0;
3339
3340         xsize = wb_data->xsize;
3341         ysize = wb_data->ysize;
3342
3343         /*
3344          * RGB overlay mode support ARGB888, RGB888, RGB565, NV12,
3345          * but YUV overlay mode only support NV12, it's hard to judge RGB
3346          * or YUV overlay mode by userspace, so here force only support
3347          * NV12 mode.
3348          */
3349         if (wb_data->data_format != YUV420 && output_color != COLOR_RGB) {
3350                 pr_err("writeback only support NV12 when overlay is not RGB\n");
3351                 return -EINVAL;
3352         }
3353
3354         if (ysize != yact && ysize != (yact / 2)) {
3355                 pr_err("WriteBack only support yact=%d, ysize=%d\n",
3356                        yact, ysize);
3357                 return -EINVAL;
3358         }
3359
3360         switch (wb_data->data_format) {
3361         case ARGB888:
3362         case ABGR888:
3363         case XRGB888:
3364         case XBGR888:
3365                 fmt_cfg = 0;
3366                 break;
3367         case RGB888:
3368         case BGR888:
3369                 fmt_cfg = 1;
3370                 break;
3371         case RGB565:
3372         case BGR565:
3373                 fmt_cfg = 2;
3374                 break;
3375         case YUV420:
3376                 fmt_cfg = 8;
3377                 break;
3378         default:
3379                 pr_info("unsupport fmt: %d\n", wb_data->data_format);
3380                 return -EINVAL;
3381         }
3382
3383         v = V_WB_EN(wb_data->state) | V_WB_FMT(fmt_cfg) | V_WB_RGB2YUV_MODE(1) |
3384                 V_WB_XPSD_BIL_EN(xact != xsize) |
3385                 V_WB_YTHROW_EN(ysize == (yact / 2)) |
3386                 V_WB_YTHROW_MODE(0);
3387
3388         v |= V_WB_RGB2YUV_EN((output_color == COLOR_RGB) &&
3389                              (wb_data->data_format == YUV420));
3390
3391         vop_msk_reg(vop_dev, WB_CTRL0, v);
3392
3393         v = V_WB_WIDTH(xsize) | V_WB_XPSD_BIL_FACTOR((xact << 12) / xsize);
3394
3395         vop_msk_reg(vop_dev, WB_CTRL1, v);
3396
3397         vop_writel(vop_dev, WB_YRGB_MST, wb_data->smem_start);
3398         if (wb_data->data_format == YUV420)
3399                 vop_writel(vop_dev, WB_CBR_MST, wb_data->smem_start);
3400
3401         return 0;
3402 }
3403
3404 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3405                      unsigned long arg, int win_id)
3406 {
3407         struct vop_device *vop_dev =
3408                         container_of(dev_drv, struct vop_device, driver);
3409         u32 panel_size[2];
3410         void __user *argp = (void __user *)arg;
3411         struct color_key_cfg clr_key_cfg;
3412
3413         switch (cmd) {
3414         case RK_FBIOGET_PANEL_SIZE:
3415                 panel_size[0] = vop_dev->screen->mode.xres;
3416                 panel_size[1] = vop_dev->screen->mode.yres;
3417                 if (copy_to_user(argp, panel_size, 8))
3418                         return -EFAULT;
3419                 break;
3420         case RK_FBIOPUT_COLOR_KEY_CFG:
3421                 if (copy_from_user(&clr_key_cfg, argp, sizeof(clr_key_cfg)))
3422                         return -EFAULT;
3423                 vop_clr_key_cfg(dev_drv);
3424                 vop_writel(vop_dev, WIN0_COLOR_KEY,
3425                            clr_key_cfg.win0_color_key_cfg);
3426                 vop_writel(vop_dev, WIN1_COLOR_KEY,
3427                            clr_key_cfg.win1_color_key_cfg);
3428                 break;
3429
3430         default:
3431                 break;
3432         }
3433         return 0;
3434 }
3435
3436 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3437 {
3438         struct vop_device *vop_dev = container_of(dev_drv,
3439                                                     struct vop_device, driver);
3440         struct device_node *backlight;
3441         struct property *prop;
3442         u32 *brightness_levels;
3443         u32 length, max, last;
3444
3445         if (vop_dev->backlight)
3446                 return 0;
3447         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
3448         if (backlight) {
3449                 vop_dev->backlight = of_find_backlight_by_node(backlight);
3450                 if (!vop_dev->backlight)
3451                         dev_info(vop_dev->dev, "No find backlight device\n");
3452         } else {
3453                 dev_info(vop_dev->dev, "No find backlight device node\n");
3454         }
3455         prop = of_find_property(backlight, "brightness-levels", &length);
3456         if (!prop)
3457                 return -EINVAL;
3458         max = length / sizeof(u32);
3459         last = max - 1;
3460         brightness_levels = kmalloc(256, GFP_KERNEL);
3461         if (brightness_levels)
3462                 return -ENOMEM;
3463
3464         if (!of_property_read_u32_array(backlight, "brightness-levels",
3465                                         brightness_levels, max)) {
3466                 if (brightness_levels[0] > brightness_levels[last])
3467                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3468                 else
3469                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3470         } else {
3471                 dev_info(vop_dev->dev,
3472                          "Can not read brightness-levels value\n");
3473         }
3474
3475         kfree(brightness_levels);
3476
3477         return 0;
3478 }
3479
3480 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
3481 {
3482         struct vop_device *vop_dev =
3483             container_of(dev_drv, struct vop_device, driver);
3484
3485         if (dev_drv->suspend_flag)
3486                 return 0;
3487
3488         dev_drv->suspend_flag = 1;
3489         /* ensure suspend_flag take effect on multi process */
3490         smp_wmb();
3491         flush_kthread_worker(&dev_drv->update_regs_worker);
3492
3493         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3494                 dev_drv->trsm_ops->disable();
3495
3496         if (likely(vop_dev->clk_on)) {
3497                 spin_lock(&vop_dev->reg_lock);
3498                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1));
3499                 vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);
3500                 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1));
3501                 vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1));
3502                 if (VOP_CHIP(vop_dev) == VOP_RK3399) {
3503                         vop_msk_reg(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
3504                         vop_msk_reg(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
3505                         vop_msk_reg(vop_dev, WIN2_CTRL0, V_WIN2_EN(0));
3506                         vop_msk_reg(vop_dev, WIN3_CTRL0, V_WIN3_EN(0));
3507                         vop_msk_reg(vop_dev, AFBCD0_CTRL, V_VOP_FBDC_EN(0));
3508                 }
3509                 vop_cfg_done(vop_dev);
3510
3511                 if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3512                         mdelay(50);
3513                         rockchip_iovmm_deactivate(dev_drv->dev);
3514                 }
3515
3516                 spin_unlock(&vop_dev->reg_lock);
3517         }
3518
3519         vop_clk_disable(vop_dev);
3520         rk_disp_pwr_disable(dev_drv);
3521
3522         return 0;
3523 }
3524
3525 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
3526 {
3527         struct vop_device *vop_dev =
3528             container_of(dev_drv, struct vop_device, driver);
3529
3530         if (!dev_drv->suspend_flag)
3531                 return 0;
3532         rk_disp_pwr_enable(dev_drv);
3533
3534         vop_clk_enable(vop_dev);
3535         spin_lock(&vop_dev->reg_lock);
3536         memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len);
3537         spin_unlock(&vop_dev->reg_lock);
3538
3539         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
3540         vop_set_cabc(dev_drv, dev_drv->cur_screen->cabc_lut);
3541         spin_lock(&vop_dev->reg_lock);
3542
3543         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0));
3544         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0));
3545         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0));
3546         vop_cfg_done(vop_dev);
3547         spin_unlock(&vop_dev->reg_lock);
3548
3549         if (dev_drv->iommu_enabled && dev_drv->mmu_dev) {
3550                 /* win address maybe effect after next frame start,
3551                  * but mmu maybe effect right now, so we delay 50ms
3552                  */
3553                 mdelay(50);
3554                 rockchip_iovmm_activate(dev_drv->dev);
3555         }
3556
3557         dev_drv->suspend_flag = 0;
3558
3559         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3560                 dev_drv->trsm_ops->enable();
3561
3562         return 0;
3563 }
3564
3565 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
3566 {
3567         switch (blank_mode) {
3568         case FB_BLANK_UNBLANK:
3569                 vop_early_resume(dev_drv);
3570                 break;
3571         case FB_BLANK_NORMAL:
3572                 vop_early_suspend(dev_drv);
3573                 break;
3574         default:
3575                 vop_early_suspend(dev_drv);
3576                 break;
3577         }
3578
3579         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3580
3581         return 0;
3582 }
3583
3584 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
3585                              int win_id, int area_id)
3586 {
3587         struct vop_device *vop_dev =
3588                         container_of(dev_drv, struct vop_device, driver);
3589         u32 area_status = 0, state = 0;
3590
3591         switch (win_id) {
3592         case 0:
3593                 area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
3594                 break;
3595         case 1:
3596                 area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
3597                 break;
3598         case 2:
3599                 if (area_id == 0)
3600                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3601                                                    V_WIN2_MST0_EN(0));
3602                 if (area_id == 1)
3603                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3604                                                    V_WIN2_MST1_EN(0));
3605                 if (area_id == 2)
3606                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3607                                                    V_WIN2_MST2_EN(0));
3608                 if (area_id == 3)
3609                         area_status = vop_read_bit(vop_dev, WIN2_CTRL0,
3610                                                    V_WIN2_MST3_EN(0));
3611                 break;
3612         case 3:
3613                 if (area_id == 0)
3614                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3615                                                    V_WIN3_MST0_EN(0));
3616                 if (area_id == 1)
3617                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3618                                                    V_WIN3_MST1_EN(0));
3619                 if (area_id == 2)
3620                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3621                                                    V_WIN3_MST2_EN(0));
3622                 if (area_id == 3)
3623                         area_status = vop_read_bit(vop_dev, WIN3_CTRL0,
3624                                                    V_WIN3_MST3_EN(0));
3625                 break;
3626         case 4:
3627                 area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
3628                 break;
3629         default:
3630                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",
3631                        __func__, win_id, area_id);
3632                 break;
3633         }
3634
3635         state = (area_status > 0) ? 1 : 0;
3636         return state;
3637 }
3638
3639 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
3640                             unsigned int *area_support)
3641 {
3642         struct vop_device *vop_dev =
3643             container_of(dev_drv, struct vop_device, driver);
3644
3645         area_support[0] = 1;
3646         area_support[1] = 1;
3647
3648         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
3649                 area_support[2] = 4;
3650                 area_support[3] = 4;
3651         }
3652
3653         return 0;
3654 }
3655
3656 /*overlay will be do at regupdate*/
3657 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
3658 {
3659         struct vop_device *vop_dev =
3660             container_of(dev_drv, struct vop_device, driver);
3661         struct rk_lcdc_win *win = NULL;
3662         int i, ovl = 0;
3663         u64 val;
3664         int z_order_num = 0;
3665         int layer0_sel = 0, layer1_sel = 1, layer2_sel = 2, layer3_sel = 3;
3666
3667         if (swap == 0) {
3668                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3669                         win = dev_drv->win[i];
3670                         if (win->state == 1)
3671                                 z_order_num++;
3672                 }
3673                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
3674                         win = dev_drv->win[i];
3675                         if (win->state == 0)
3676                                 win->z_order = z_order_num++;
3677                         switch (win->z_order) {
3678                         case 0:
3679                                 layer0_sel = win->id;
3680                                 break;
3681                         case 1:
3682                                 layer1_sel = win->id;
3683                                 break;
3684                         case 2:
3685                                 layer2_sel = win->id;
3686                                 break;
3687                         case 3:
3688                                 layer3_sel = win->id;
3689                                 break;
3690                         default:
3691                                 break;
3692                         }
3693                 }
3694         } else {
3695                 layer0_sel = swap % 10;
3696                 layer1_sel = swap / 10 % 10;
3697                 layer2_sel = swap / 100 % 10;
3698                 layer3_sel = swap / 1000;
3699         }
3700
3701         spin_lock(&vop_dev->reg_lock);
3702         if (vop_dev->clk_on) {
3703                 if (set) {
3704                         val = V_DSP_LAYER0_SEL(layer0_sel) |
3705                             V_DSP_LAYER1_SEL(layer1_sel) |
3706                             V_DSP_LAYER2_SEL(layer2_sel) |
3707                             V_DSP_LAYER3_SEL(layer3_sel);
3708                         vop_msk_reg(vop_dev, DSP_CTRL1, val);
3709                 } else {
3710                         layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3711                                                   V_DSP_LAYER0_SEL(0));
3712                         layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3713                                                   V_DSP_LAYER1_SEL(0));
3714                         layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3715                                                   V_DSP_LAYER2_SEL(0));
3716                         layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1,
3717                                                   V_DSP_LAYER3_SEL(0));
3718                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3719                             layer1_sel * 10 + layer0_sel;
3720                 }
3721         } else {
3722                 ovl = -EPERM;
3723         }
3724         spin_unlock(&vop_dev->reg_lock);
3725
3726         return ovl;
3727 }
3728
3729 static char *vop_format_to_string(int format, char *fmt)
3730 {
3731         if (!fmt)
3732                 return NULL;
3733
3734         switch (format) {
3735         case 0:
3736                 strcpy(fmt, "ARGB888");
3737                 break;
3738         case 1:
3739                 strcpy(fmt, "RGB888");
3740                 break;
3741         case 2:
3742                 strcpy(fmt, "RGB565");
3743                 break;
3744         case 4:
3745                 strcpy(fmt, "YCbCr420");
3746                 break;
3747         case 5:
3748                 strcpy(fmt, "YCbCr422");
3749                 break;
3750         case 6:
3751                 strcpy(fmt, "YCbCr444");
3752         case 8:
3753                 strcpy(fmt, "YUYV422");
3754                 break;
3755         case 9:
3756                 strcpy(fmt, "YUYV420");
3757                 break;
3758         case 10:
3759                 strcpy(fmt, "UYVY422");
3760                 break;
3761         case 11:
3762                 strcpy(fmt, "UYVY420");
3763                 break;
3764         default:
3765                 strcpy(fmt, "invalid\n");
3766                 break;
3767         }
3768         return fmt;
3769 }
3770
3771 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
3772                                  char *buf, int win_id)
3773 {
3774         struct vop_device *vop_dev =
3775             container_of(dev_drv, struct vop_device, driver);
3776         struct rk_screen *screen = dev_drv->cur_screen;
3777         u16 hsync_len = screen->mode.hsync_len;
3778         u16 left_margin = screen->mode.left_margin;
3779         u16 vsync_len = screen->mode.vsync_len;
3780         u16 upper_margin = screen->mode.upper_margin;
3781         u32 h_pw_bp = hsync_len + left_margin;
3782         u32 v_pw_bp = vsync_len + upper_margin;
3783         u32 fmt_id;
3784         char format_w0[9] = "NULL";
3785         char format_w1[9] = "NULL";
3786         char format_w2_0[9] = "NULL";
3787         char format_w2_1[9] = "NULL";
3788         char format_w2_2[9] = "NULL";
3789         char format_w2_3[9] = "NULL";
3790         char format_w3_0[9] = "NULL";
3791         char format_w3_1[9] = "NULL";
3792         char format_w3_2[9] = "NULL";
3793         char format_w3_3[9] = "NULL";
3794         char dsp_buf[100];
3795         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3796         u32 y_factor, uv_factor;
3797         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3798         u8 w0_state, w1_state, w2_state, w3_state;
3799         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3800         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3801
3802         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3803         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3804         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3805         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3806         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3807         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3808
3809         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3810         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3811         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3812         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3813         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3814         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3815         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3816
3817         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3818         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3819         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3820         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3821         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3822         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3823         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3824         u32 dclk_freq;
3825         int size = 0;
3826
3827         dclk_freq = screen->mode.pixclock;
3828         /*vop_reg_dump(dev_drv); */
3829
3830         spin_lock(&vop_dev->reg_lock);
3831         if (vop_dev->clk_on) {
3832                 zorder = vop_readl(vop_dev, DSP_CTRL1);
3833                 layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8;
3834                 layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10;
3835                 layer2_sel = (zorder & MASK(DSP_LAYER2_SEL)) >> 12;
3836                 layer3_sel = (zorder & MASK(DSP_LAYER3_SEL)) >> 14;
3837                 /* WIN0 */
3838                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
3839                 w0_state = win_ctrl & MASK(WIN0_EN);
3840                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
3841                 fmt_id |= (win_ctrl & MASK(WIN0_YUYV)) >> 14; /* yuyv*/
3842                 vop_format_to_string(fmt_id, format_w0);
3843                 vir_info = vop_readl(vop_dev, WIN0_VIR);
3844                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
3845                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
3846                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
3847                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
3848                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
3849                 w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE);
3850                 w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16;
3851                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
3852                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
3853                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
3854                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
3855                 if (w0_state) {
3856                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
3857                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
3858                 }
3859                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
3860                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
3861                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
3862                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
3863
3864                 /* WIN1 */
3865                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
3866                 w1_state = win_ctrl & MASK(WIN1_EN);
3867                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
3868                 fmt_id |= (win_ctrl & MASK(WIN1_YUYV)) >> 14; /* yuyv*/
3869                 vop_format_to_string(fmt_id, format_w1);
3870                 vir_info = vop_readl(vop_dev, WIN1_VIR);
3871                 act_info = vop_readl(vop_dev, WIN1_ACT_INFO);
3872                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
3873                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
3874                 y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB);
3875                 uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR);
3876                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
3877                 w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16;
3878                 w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1;
3879                 w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1;
3880                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
3881                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
3882                 if (w1_state) {
3883                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
3884                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
3885                 }
3886                 w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB);
3887                 w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16;
3888                 w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR);
3889                 w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16;
3890
3891                 /*WIN2 */
3892                 win_ctrl = vop_readl(vop_dev, WIN2_CTRL0);
3893                 w2_state = win_ctrl & MASK(WIN2_EN);
3894                 w2_0_state = (win_ctrl & 0x10) >> 4;
3895                 w2_1_state = (win_ctrl & 0x100) >> 8;
3896                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3897                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3898                 vir_info = vop_readl(vop_dev, WIN2_VIR0_1);
3899                 w2_0_vir_y = vir_info & MASK(WIN2_VIR_STRIDE0);
3900                 w2_1_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE1)) >> 16;
3901                 vir_info = vop_readl(vop_dev, WIN2_VIR2_3);
3902                 w2_2_vir_y = vir_info & MASK(WIN2_VIR_STRIDE2);
3903                 w2_3_vir_y = (vir_info & MASK(WIN2_VIR_STRIDE3)) >> 16;
3904
3905                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT0)) >> 5;
3906                 vop_format_to_string(fmt_id, format_w2_0);
3907                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT1)) >> 9;
3908                 vop_format_to_string(fmt_id, format_w2_1);
3909                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT2)) >> 13;
3910                 vop_format_to_string(fmt_id, format_w2_2);
3911                 fmt_id = (win_ctrl & MASK(WIN2_DATA_FMT3)) >> 17;
3912                 vop_format_to_string(fmt_id, format_w2_3);
3913
3914                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO0);
3915                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST0);
3916                 w2_0_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH0)) + 1;
3917                 w2_0_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT0)) >> 16) + 1;
3918                 if (w2_0_state) {
3919                         w2_0_st_x = dsp_st & MASK(WIN2_DSP_XST0);
3920                         w2_0_st_y = (dsp_st & MASK(WIN2_DSP_YST0)) >> 16;
3921                 }
3922                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO1);
3923                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST1);
3924                 w2_1_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH1)) + 1;
3925                 w2_1_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT1)) >> 16) + 1;
3926                 if (w2_1_state) {
3927                         w2_1_st_x = dsp_st & MASK(WIN2_DSP_XST1);
3928                         w2_1_st_y = (dsp_st & MASK(WIN2_DSP_YST1)) >> 16;
3929                 }
3930                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO2);
3931                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST2);
3932                 w2_2_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH2)) + 1;
3933                 w2_2_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT2)) >> 16) + 1;
3934                 if (w2_2_state) {
3935                         w2_2_st_x = dsp_st & MASK(WIN2_DSP_XST2);
3936                         w2_2_st_y = (dsp_st & MASK(WIN2_DSP_YST2)) >> 16;
3937                 }
3938                 dsp_info = vop_readl(vop_dev, WIN2_DSP_INFO3);
3939                 dsp_st = vop_readl(vop_dev, WIN2_DSP_ST3);
3940                 w2_3_dsp_x = (dsp_info & MASK(WIN2_DSP_WIDTH3)) + 1;
3941                 w2_3_dsp_y = ((dsp_info & MASK(WIN2_DSP_HEIGHT3)) >> 16) + 1;
3942                 if (w2_3_state) {
3943                         w2_3_st_x = dsp_st & MASK(WIN2_DSP_XST3);
3944                         w2_3_st_y = (dsp_st & MASK(WIN2_DSP_YST3)) >> 16;
3945                 }
3946
3947                 /*WIN3 */
3948                 win_ctrl = vop_readl(vop_dev, WIN3_CTRL0);
3949                 w3_state = win_ctrl & MASK(WIN3_EN);
3950                 w3_0_state = (win_ctrl & 0x10) >> 4;
3951                 w3_1_state = (win_ctrl & 0x100) >> 8;
3952                 w3_2_state = (win_ctrl & 0x1000) >> 12;
3953                 w3_3_state = (win_ctrl & 0x10000) >> 16;
3954                 vir_info = vop_readl(vop_dev, WIN3_VIR0_1);
3955                 w3_0_vir_y = vir_info & MASK(WIN3_VIR_STRIDE0);
3956                 w3_1_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE1)) >> 16;
3957                 vir_info = vop_readl(vop_dev, WIN3_VIR2_3);
3958                 w3_2_vir_y = vir_info & MASK(WIN3_VIR_STRIDE2);
3959                 w3_3_vir_y = (vir_info & MASK(WIN3_VIR_STRIDE3)) >> 16;
3960
3961                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT0)) >> 5;
3962                 vop_format_to_string(fmt_id, format_w3_0);
3963                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT1)) >> 9;
3964                 vop_format_to_string(fmt_id, format_w3_1);
3965                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT2)) >> 13;
3966                 vop_format_to_string(fmt_id, format_w3_2);
3967                 fmt_id = (win_ctrl & MASK(WIN3_DATA_FMT3)) >> 17;
3968                 vop_format_to_string(fmt_id, format_w3_3);
3969
3970                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO0);
3971                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST0);
3972                 w3_0_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH0)) + 1;
3973                 w3_0_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT0)) >> 16) + 1;
3974                 if (w3_0_state) {
3975                         w3_0_st_x = dsp_st & MASK(WIN3_DSP_XST0);
3976                         w3_0_st_y = (dsp_st & MASK(WIN3_DSP_YST0)) >> 16;
3977                 }
3978                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO1);
3979                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST1);
3980                 w3_1_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH1)) + 1;
3981                 w3_1_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT1)) >> 16) + 1;
3982                 if (w3_1_state) {
3983                         w3_1_st_x = dsp_st & MASK(WIN3_DSP_XST1);
3984                         w3_1_st_y = (dsp_st & MASK(WIN3_DSP_YST1)) >> 16;
3985                 }
3986                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO2);
3987                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST2);
3988                 w3_2_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH2)) + 1;
3989                 w3_2_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT2)) >> 16) + 1;
3990                 if (w3_2_state) {
3991                         w3_2_st_x = dsp_st & MASK(WIN3_DSP_XST2);
3992                         w3_2_st_y = (dsp_st & MASK(WIN3_DSP_YST2)) >> 16;
3993                 }
3994                 dsp_info = vop_readl(vop_dev, WIN3_DSP_INFO3);
3995                 dsp_st = vop_readl(vop_dev, WIN3_DSP_ST3);
3996                 w3_3_dsp_x = (dsp_info & MASK(WIN3_DSP_WIDTH3)) + 1;
3997                 w3_3_dsp_y = ((dsp_info & MASK(WIN3_DSP_HEIGHT3)) >> 16) + 1;
3998                 if (w3_3_state) {
3999                         w3_3_st_x = dsp_st & MASK(WIN3_DSP_XST3);
4000                         w3_3_st_y = (dsp_st & MASK(WIN3_DSP_YST3)) >> 16;
4001                 }
4002         } else {
4003                 spin_unlock(&vop_dev->reg_lock);
4004                 return -EPERM;
4005         }
4006         spin_unlock(&vop_dev->reg_lock);
4007         size += snprintf(dsp_buf, 80,
4008                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
4009                 layer3_sel, layer2_sel, layer1_sel, layer0_sel);
4010         strcat(buf, dsp_buf);
4011         memset(dsp_buf, 0, sizeof(dsp_buf));
4012         /* win0 */
4013         size += snprintf(dsp_buf, 80,
4014                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
4015                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
4016         strcat(buf, dsp_buf);
4017         memset(dsp_buf, 0, sizeof(dsp_buf));
4018
4019         size += snprintf(dsp_buf, 80,
4020                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
4021                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
4022         strcat(buf, dsp_buf);
4023         memset(dsp_buf, 0, sizeof(dsp_buf));
4024
4025         size += snprintf(dsp_buf, 80,
4026                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
4027                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
4028         strcat(buf, dsp_buf);
4029         memset(dsp_buf, 0, sizeof(dsp_buf));
4030
4031         size += snprintf(dsp_buf, 80,
4032                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
4033                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
4034                  vop_readl(vop_dev, WIN0_CBR_MST));
4035         strcat(buf, dsp_buf);
4036         memset(dsp_buf, 0, sizeof(dsp_buf));
4037
4038         /* win1 */
4039         size += snprintf(dsp_buf, 80,
4040                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
4041                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
4042         strcat(buf, dsp_buf);
4043         memset(dsp_buf, 0, sizeof(dsp_buf));
4044
4045         size += snprintf(dsp_buf, 80,
4046                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
4047                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
4048         strcat(buf, dsp_buf);
4049         memset(dsp_buf, 0, sizeof(dsp_buf));
4050
4051         size += snprintf(dsp_buf, 80,
4052                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
4053                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp, w1_y_h_fac, w1_y_v_fac);
4054         strcat(buf, dsp_buf);
4055         memset(dsp_buf, 0, sizeof(dsp_buf));
4056
4057         size += snprintf(dsp_buf, 80,
4058                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
4059                  w1_uv_h_fac, w1_uv_v_fac, vop_readl(vop_dev, WIN1_YRGB_MST),
4060                  vop_readl(vop_dev, WIN1_CBR_MST));
4061         strcat(buf, dsp_buf);
4062         memset(dsp_buf, 0, sizeof(dsp_buf));
4063
4064         /*win2*/
4065         size += snprintf(dsp_buf, 80,
4066                  "win2:\n  state:%d\n",
4067                  w2_state);
4068         strcat(buf, dsp_buf);
4069         memset(dsp_buf, 0, sizeof(dsp_buf));
4070         /*area 0*/
4071         size += snprintf(dsp_buf, 80,
4072                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4073                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
4074         strcat(buf, dsp_buf);
4075         memset(dsp_buf, 0, sizeof(dsp_buf));
4076         size += snprintf(dsp_buf, 80,
4077                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4078                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
4079                  vop_readl(vop_dev, WIN2_MST0));
4080         strcat(buf, dsp_buf);
4081         memset(dsp_buf, 0, sizeof(dsp_buf));
4082
4083         /*area 1*/
4084         size += snprintf(dsp_buf, 80,
4085                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4086                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
4087         strcat(buf, dsp_buf);
4088         memset(dsp_buf, 0, sizeof(dsp_buf));
4089         size += snprintf(dsp_buf, 80,
4090                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4091                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
4092                  vop_readl(vop_dev, WIN2_MST1));
4093         strcat(buf, dsp_buf);
4094         memset(dsp_buf, 0, sizeof(dsp_buf));
4095
4096         /*area 2*/
4097         size += snprintf(dsp_buf, 80,
4098                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4099                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
4100         strcat(buf, dsp_buf);
4101         memset(dsp_buf, 0, sizeof(dsp_buf));
4102         size += snprintf(dsp_buf, 80,
4103                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4104                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
4105                  vop_readl(vop_dev, WIN2_MST2));
4106         strcat(buf, dsp_buf);
4107         memset(dsp_buf, 0, sizeof(dsp_buf));
4108
4109         /*area 3*/
4110         size += snprintf(dsp_buf, 80,
4111                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4112                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
4113         strcat(buf, dsp_buf);
4114         memset(dsp_buf, 0, sizeof(dsp_buf));
4115         size += snprintf(dsp_buf, 80,
4116                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4117                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
4118                  vop_readl(vop_dev, WIN2_MST3));
4119         strcat(buf, dsp_buf);
4120         memset(dsp_buf, 0, sizeof(dsp_buf));
4121
4122         /*win3*/
4123         size += snprintf(dsp_buf, 80,
4124                  "win3:\n  state:%d\n",
4125                  w3_state);
4126         strcat(buf, dsp_buf);
4127         memset(dsp_buf, 0, sizeof(dsp_buf));
4128         /*area 0*/
4129         size += snprintf(dsp_buf, 80,
4130                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4131                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
4132         strcat(buf, dsp_buf);
4133         memset(dsp_buf, 0, sizeof(dsp_buf));
4134         size += snprintf(dsp_buf, 80,
4135                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4136                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
4137                  vop_readl(vop_dev, WIN3_MST0));
4138         strcat(buf, dsp_buf);
4139         memset(dsp_buf, 0, sizeof(dsp_buf));
4140
4141         /*area 1*/
4142         size += snprintf(dsp_buf, 80,
4143                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4144                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
4145         strcat(buf, dsp_buf);
4146         memset(dsp_buf, 0, sizeof(dsp_buf));
4147         size += snprintf(dsp_buf, 80,
4148                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4149                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
4150                  vop_readl(vop_dev, WIN3_MST1));
4151         strcat(buf, dsp_buf);
4152         memset(dsp_buf, 0, sizeof(dsp_buf));
4153
4154         /*area 2*/
4155         size += snprintf(dsp_buf, 80,
4156                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4157                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
4158         strcat(buf, dsp_buf);
4159         memset(dsp_buf, 0, sizeof(dsp_buf));
4160         size += snprintf(dsp_buf, 80,
4161                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4162                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
4163                  vop_readl(vop_dev, WIN3_MST2));
4164         strcat(buf, dsp_buf);
4165         memset(dsp_buf, 0, sizeof(dsp_buf));
4166
4167         /*area 3*/
4168         size += snprintf(dsp_buf, 80,
4169                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
4170                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
4171         strcat(buf, dsp_buf);
4172         memset(dsp_buf, 0, sizeof(dsp_buf));
4173         size += snprintf(dsp_buf, 80,
4174                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
4175                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
4176                  vop_readl(vop_dev, WIN3_MST3));
4177         strcat(buf, dsp_buf);
4178         memset(dsp_buf, 0, sizeof(dsp_buf));
4179
4180         return size;
4181 }
4182
4183 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
4184 {
4185         struct vop_device *vop_dev =
4186             container_of(dev_drv, struct vop_device, driver);
4187         struct rk_screen *screen = dev_drv->cur_screen;
4188         u64 ft = 0;
4189         u32 dotclk;
4190         int ret;
4191         u32 pixclock;
4192         u32 x_total, y_total;
4193
4194         if (set) {
4195                 if (fps == 0) {
4196                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
4197                         return 0;
4198                 }
4199                 ft = div_u64(1000000000000llu, fps);
4200                 x_total =
4201                     screen->mode.upper_margin + screen->mode.lower_margin +
4202                     screen->mode.yres + screen->mode.vsync_len;
4203                 y_total =
4204                     screen->mode.left_margin + screen->mode.right_margin +
4205                     screen->mode.xres + screen->mode.hsync_len;
4206                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
4207                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
4208                 ret = clk_set_rate(vop_dev->dclk, dotclk);
4209         }
4210
4211         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
4212         vop_dev->pixclock = pixclock;
4213         dev_drv->pixclock = vop_dev->pixclock;
4214         fps = rk_fb_calc_fps(screen, pixclock);
4215         screen->ft = 1000 / fps;        /*one frame time in ms */
4216
4217         if (set)
4218                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
4219                          clk_get_rate(vop_dev->dclk), fps);
4220
4221         return fps;
4222 }
4223
4224 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
4225 {
4226         mutex_lock(&dev_drv->fb_win_id_mutex);
4227         if (order == FB_DEFAULT_ORDER)
4228                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
4229         dev_drv->fb4_win_id = order / 10000;
4230         dev_drv->fb3_win_id = (order / 1000) % 10;
4231         dev_drv->fb2_win_id = (order / 100) % 10;
4232         dev_drv->fb1_win_id = (order / 10) % 10;
4233         dev_drv->fb0_win_id = order % 10;
4234         mutex_unlock(&dev_drv->fb_win_id_mutex);
4235
4236         return 0;
4237 }
4238
4239 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
4240 {
4241         int win_id = 0;
4242
4243         mutex_lock(&dev_drv->fb_win_id_mutex);
4244         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
4245                 win_id = dev_drv->fb0_win_id;
4246         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
4247                 win_id = dev_drv->fb1_win_id;
4248         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
4249                 win_id = dev_drv->fb2_win_id;
4250         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
4251                 win_id = dev_drv->fb3_win_id;
4252         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
4253                 win_id = dev_drv->fb4_win_id;
4254         mutex_unlock(&dev_drv->fb_win_id_mutex);
4255
4256         return win_id;
4257 }
4258
4259 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
4260 {
4261         struct vop_device *vop_dev =
4262             container_of(dev_drv, struct vop_device, driver);
4263         int i, fbdc_en = 0;
4264         u64 val;
4265         struct rk_lcdc_win *win = NULL;
4266
4267         spin_lock(&vop_dev->reg_lock);
4268         vop_post_cfg(dev_drv);
4269         vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
4270         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
4271                 win = dev_drv->win[i];
4272                 vop_alpha_cfg(dev_drv, i);
4273                 fbdc_en |= win->area[0].fbdc_en;
4274                 vop_dev->atv_layer_cnt &= ~(1 << win->id);
4275                 vop_dev->atv_layer_cnt |= (win->state << win->id);
4276                 if ((win->state == 0) && (win->last_state == 1)) {
4277                         switch (win->id) {
4278                         case 0:
4279                                 val = V_WIN0_EN(0);
4280                                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
4281                                 break;
4282                         case 1:
4283                                 val = V_WIN1_EN(0);
4284                                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
4285                                 break;
4286                         case 2:
4287                                 val = V_WIN2_EN(0) | V_WIN2_MST0_EN(0) |
4288                                     V_WIN2_MST1_EN(0) |
4289                                     V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
4290                                 vop_msk_reg(vop_dev, WIN2_CTRL0, val);
4291                                 break;
4292                         case 3:
4293                                 val = V_WIN3_EN(0) | V_WIN3_MST0_EN(0) |
4294                                     V_WIN3_MST1_EN(0) |
4295                                     V_WIN3_MST2_EN(0) | V_WIN3_MST3_EN(0);
4296                                 vop_msk_reg(vop_dev, WIN3_CTRL0, val);
4297                                 break;
4298                         case 4:
4299                                 val = V_HWC_EN(0);
4300                                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
4301                                 break;
4302                         default:
4303                                 break;
4304                         }
4305                 }
4306                 win->last_state = win->state;
4307         }
4308         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4309                 val = V_VOP_FBDC_EN(fbdc_en);
4310                 vop_msk_reg(vop_dev, AFBCD0_CTRL, val);
4311         }
4312         vop_cfg_done(vop_dev);
4313         spin_unlock(&vop_dev->reg_lock);
4314         return 0;
4315 }
4316
4317 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
4318 {
4319         struct vop_device *vop_dev =
4320             container_of(dev_drv, struct vop_device, driver);
4321         spin_lock(&vop_dev->reg_lock);
4322         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open));
4323         vop_cfg_done(vop_dev);
4324         spin_unlock(&vop_dev->reg_lock);
4325         return 0;
4326 }
4327
4328 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
4329 {
4330         struct vop_device *vop_dev = container_of(dev_drv,
4331                                                     struct vop_device, driver);
4332         spin_lock(&vop_dev->reg_lock);
4333         vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id));
4334         vop_cfg_done(vop_dev);
4335         spin_unlock(&vop_dev->reg_lock);
4336         return 0;
4337 }
4338
4339 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
4340 {
4341         struct vop_device *vop_dev =
4342             container_of(dev_drv, struct vop_device, driver);
4343         int ovl;
4344
4345         spin_lock(&vop_dev->reg_lock);
4346         ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0));
4347         spin_unlock(&vop_dev->reg_lock);
4348         return ovl;
4349 }
4350
4351 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
4352 {
4353         struct vop_device *vop_dev =
4354                         container_of(dev_drv, struct vop_device, driver);
4355         if (enable)
4356                 enable_irq(vop_dev->irq);
4357         else
4358                 disable_irq_nosync(vop_dev->irq);
4359         return 0;
4360 }
4361
4362 int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
4363 {
4364         struct vop_device *vop_dev =
4365             container_of(dev_drv, struct vop_device, driver);
4366         u32 int_reg;
4367         int ret;
4368
4369         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
4370                 int_reg = vop_readl(vop_dev, INTR_STATUS0);
4371                 if (int_reg & INTR_LINE_FLAG0) {
4372                         vop_dev->driver.frame_time.last_framedone_t =
4373                             vop_dev->driver.frame_time.framedone_t;
4374                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
4375                         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0,
4376                                         INTR_LINE_FLAG0);
4377                         ret = RK_LF_STATUS_FC;
4378                 } else {
4379                         ret = RK_LF_STATUS_FR;
4380                 }
4381         } else {
4382                 ret = RK_LF_STATUS_NC;
4383         }
4384
4385         return ret;
4386 }
4387
4388 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
4389                             unsigned int dsp_addr[][4])
4390 {
4391         struct vop_device *vop_dev =
4392             container_of(dev_drv, struct vop_device, driver);
4393         spin_lock(&vop_dev->reg_lock);
4394         if (vop_dev->clk_on) {
4395                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
4396                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
4397                 dsp_addr[2][0] = vop_readl(vop_dev, WIN2_MST0);
4398                 dsp_addr[2][1] = vop_readl(vop_dev, WIN2_MST1);
4399                 dsp_addr[2][2] = vop_readl(vop_dev, WIN2_MST2);
4400                 dsp_addr[2][3] = vop_readl(vop_dev, WIN2_MST3);
4401                 dsp_addr[3][0] = vop_readl(vop_dev, WIN3_MST0);
4402                 dsp_addr[3][1] = vop_readl(vop_dev, WIN3_MST1);
4403                 dsp_addr[3][2] = vop_readl(vop_dev, WIN3_MST2);
4404                 dsp_addr[3][3] = vop_readl(vop_dev, WIN3_MST3);
4405                 dsp_addr[4][0] = vop_readl(vop_dev, HWC_MST);
4406         }
4407         spin_unlock(&vop_dev->reg_lock);
4408         return 0;
4409 }
4410
4411
4412 int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty)
4413 {
4414         /*
4415          * TODO:
4416          * pwm_period_hpr = bl_pwm_period;
4417          * pwm_duty_lpr = bl_pwm_duty;
4418          * pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
4419          * bl_pwm_period, bl_pwm_duty);
4420          */
4421
4422         return 0;
4423 }
4424
4425 /*
4426  *  a:[-30~0]:
4427  *    sin_hue = sin(a)*256 +0x100;
4428  *    cos_hue = cos(a)*256;
4429  *  a:[0~30]
4430  *    sin_hue = sin(a)*256;
4431  *    cos_hue = cos(a)*256;
4432  */
4433 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
4434 {
4435         struct vop_device *vop_dev =
4436             container_of(dev_drv, struct vop_device, driver);
4437         u32 val = 0;
4438
4439         spin_lock(&vop_dev->reg_lock);
4440         if (vop_dev->clk_on) {
4441                 val = vop_readl(vop_dev, BCSH_H);
4442                 switch (mode) {
4443                 case H_SIN:
4444                         val &= MASK(SIN_HUE);
4445                         break;
4446                 case H_COS:
4447                         val &= MASK(COS_HUE);
4448                         val >>= 16;
4449                         break;
4450                 default:
4451                         break;
4452                 }
4453         }
4454         spin_unlock(&vop_dev->reg_lock);
4455
4456         return val;
4457 }
4458
4459 static int vop_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode,
4460                             int calc, int up, int down, int global)
4461 {
4462         struct vop_device *vop_dev =
4463                         container_of(dev_drv, struct vop_device, driver);
4464         struct rk_screen *screen = dev_drv->cur_screen;
4465         u32 total_pixel, calc_pixel, stage_up, stage_down;
4466         u32 pixel_num, global_dn;
4467         u64 val = 0;
4468         ktime_t timestamp;
4469         int ret = 0;
4470
4471         if (!vop_dev->cabc_lut_addr_base) {
4472                 pr_err("vop chip[%d] not supoort cabc\n", VOP_CHIP(vop_dev));
4473                 return 0;
4474         }
4475
4476         if (!screen->cabc_lut) {
4477                 pr_err("screen cabc lut not config, so not open cabc\n");
4478                 return 0;
4479         }
4480
4481         if (!mode) {
4482                 if (VOP_CHIP(vop_dev) == VOP_RK3399) {
4483                         calc = 0;
4484                         up = 256;
4485                         down = 255;
4486                         global = 0;
4487                 } else {
4488                         spin_lock(&vop_dev->reg_lock);
4489                         if (vop_dev->clk_on) {
4490                                 vop_msk_reg(vop_dev, CABC_CTRL0,
4491                                             V_CABC_EN(0) | V_CABC_HANDLE_EN(0));
4492                                 vop_cfg_done(vop_dev);
4493                         }
4494                         pr_info("mode = 0, close cabc\n");
4495                         spin_unlock(&vop_dev->reg_lock);
4496                         return 0;
4497                 }
4498         }
4499
4500         total_pixel = screen->mode.xres * screen->mode.yres;
4501         pixel_num = 1000 - calc;
4502         calc_pixel = (total_pixel * pixel_num) / 1000;
4503         stage_up = up;
4504         stage_down = down;
4505         global_dn = global;
4506         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
4507                 mode, calc, stage_up, stage_down, global_dn);
4508
4509         spin_lock(&vop_dev->reg_lock);
4510         if (vop_dev->clk_on) {
4511                 val = V_PWM_CONFIG_MODE(STAGE_BY_STAGE) |
4512                         V_CABC_CALC_PIXEL_NUM(calc_pixel);
4513                 vop_msk_reg(vop_dev, CABC_CTRL0, val);
4514
4515                 val = V_CABC_LUT_EN(1) | V_CABC_TOTAL_NUM(total_pixel);
4516                 vop_msk_reg(vop_dev, CABC_CTRL1, val);
4517
4518                 val = V_CABC_STAGE_DOWN(stage_down) |
4519                         V_CABC_STAGE_UP(stage_up) |
4520                         V_CABC_STAGE_UP_MODE(0) | V_MAX_SCALE_CFG_VALUE(1) |
4521                         V_MAX_SCALE_CFG_ENABLE(0);
4522                 vop_msk_reg(vop_dev, CABC_CTRL2, val);
4523
4524                 val = V_CABC_GLOBAL_DN(global_dn) |
4525                         V_CABC_GLOBAL_DN_LIMIT_EN(1);
4526                 vop_msk_reg(vop_dev, CABC_CTRL3, val);
4527                 vop_cfg_done(vop_dev);
4528         }
4529         spin_unlock(&vop_dev->reg_lock);
4530
4531         timestamp = dev_drv->vsync_info.timestamp;
4532         ret = wait_event_interruptible_timeout(dev_drv->vsync_info.wait,
4533                         !ktime_equal(timestamp, dev_drv->vsync_info.timestamp),
4534                         msecs_to_jiffies(50));
4535         if (ret < 0)
4536                 return ret;
4537         else if (ret == 0)
4538                 pr_err("%s wait vsync time out\n", __func__);
4539
4540         spin_lock(&vop_dev->reg_lock);
4541         val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1);
4542         vop_msk_reg(vop_dev, CABC_CTRL0, val);
4543         vop_cfg_done(vop_dev);
4544         spin_unlock(&vop_dev->reg_lock);
4545
4546         return 0;
4547 }
4548
4549 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4550                             int sin_hue, int cos_hue)
4551 {
4552         struct vop_device *vop_dev =
4553             container_of(dev_drv, struct vop_device, driver);
4554         u64 val;
4555
4556         spin_lock(&vop_dev->reg_lock);
4557         if (vop_dev->clk_on) {
4558                 val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue);
4559                 vop_msk_reg(vop_dev, BCSH_H, val);
4560                 vop_cfg_done(vop_dev);
4561         }
4562         spin_unlock(&vop_dev->reg_lock);
4563
4564         return 0;
4565 }
4566
4567 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4568                             bcsh_bcs_mode mode, int value)
4569 {
4570         struct vop_device *vop_dev =
4571             container_of(dev_drv, struct vop_device, driver);
4572         u64 val = 0;
4573
4574         spin_lock(&vop_dev->reg_lock);
4575         if (vop_dev->clk_on) {
4576                 switch (mode) {
4577                 case BRIGHTNESS:
4578                         /*from 0 to 255,typical is 128 */
4579                         if (value < 0x80)
4580                                 value += 0x80;
4581                         else if (value >= 0x80)
4582                                 value = value - 0x80;
4583                         val = V_BRIGHTNESS(value);
4584                         break;
4585                 case CONTRAST:
4586                         /*from 0 to 510,typical is 256 */
4587                         val = V_CONTRAST(value);
4588                         break;
4589                 case SAT_CON:
4590                         /*from 0 to 1015,typical is 256 */
4591                         val = V_SAT_CON(value);
4592                         break;
4593                 default:
4594                         break;
4595                 }
4596                 vop_msk_reg(vop_dev, BCSH_BCS, val);
4597                 vop_cfg_done(vop_dev);
4598         }
4599         spin_unlock(&vop_dev->reg_lock);
4600
4601         return val;
4602 }
4603
4604 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
4605 {
4606         struct vop_device *vop_dev =
4607             container_of(dev_drv, struct vop_device, driver);
4608         u64 val = 0;
4609
4610         spin_lock(&vop_dev->reg_lock);
4611         if (vop_dev->clk_on) {
4612                 val = vop_readl(vop_dev, BCSH_BCS);
4613                 switch (mode) {
4614                 case BRIGHTNESS:
4615                         val &= MASK(BRIGHTNESS);
4616                         if (val > 0x80)
4617                                 val -= 0x80;
4618                         else
4619                                 val += 0x80;
4620                         break;
4621                 case CONTRAST:
4622                         val &= MASK(CONTRAST);
4623                         val >>= 8;
4624                         break;
4625                 case SAT_CON:
4626                         val &= MASK(SAT_CON);
4627                         val >>= 20;
4628                         break;
4629                 default:
4630                         break;
4631                 }
4632         }
4633         spin_unlock(&vop_dev->reg_lock);
4634         return val;
4635 }
4636
4637 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4638 {
4639         struct vop_device *vop_dev =
4640             container_of(dev_drv, struct vop_device, driver);
4641
4642         spin_lock(&vop_dev->reg_lock);
4643         if (vop_dev->clk_on) {
4644                 if (open) {
4645                         vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1);
4646                         vop_writel(vop_dev, BCSH_BCS, 0xd0010000);
4647                         vop_writel(vop_dev, BCSH_H, 0x01000000);
4648                         dev_drv->bcsh.enable = 1;
4649                 } else {
4650                         vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0));
4651                         dev_drv->bcsh.enable = 0;
4652                 }
4653                 vop_bcsh_path_sel(dev_drv);
4654                 vop_cfg_done(vop_dev);
4655         }
4656         spin_unlock(&vop_dev->reg_lock);
4657
4658         return 0;
4659 }
4660
4661 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4662 {
4663         if (!enable || !dev_drv->bcsh.enable) {
4664                 vop_open_bcsh(dev_drv, false);
4665                 return 0;
4666         }
4667
4668         if (dev_drv->bcsh.brightness <= 255 ||
4669             dev_drv->bcsh.contrast <= 510 ||
4670             dev_drv->bcsh.sat_con <= 1015 ||
4671             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4672                 vop_open_bcsh(dev_drv, true);
4673                 if (dev_drv->bcsh.brightness <= 255)
4674                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4675                                          dev_drv->bcsh.brightness);
4676                 if (dev_drv->bcsh.contrast <= 510)
4677                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
4678                                          dev_drv->bcsh.contrast);
4679                 if (dev_drv->bcsh.sat_con <= 1015)
4680                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
4681                                          dev_drv->bcsh.sat_con);
4682                 if (dev_drv->bcsh.sin_hue <= 511 &&
4683                     dev_drv->bcsh.cos_hue <= 511)
4684                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
4685                                          dev_drv->bcsh.cos_hue);
4686         }
4687
4688         return 0;
4689 }
4690
4691 static int __maybe_unused
4692 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4693 {
4694         struct vop_device *vop_dev =
4695             container_of(dev_drv, struct vop_device, driver);
4696
4697         if (enable) {
4698                 spin_lock(&vop_dev->reg_lock);
4699                 if (likely(vop_dev->clk_on)) {
4700                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
4701                         vop_cfg_done(vop_dev);
4702                 }
4703                 spin_unlock(&vop_dev->reg_lock);
4704         } else {
4705                 spin_lock(&vop_dev->reg_lock);
4706                 if (likely(vop_dev->clk_on)) {
4707                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
4708
4709                         vop_cfg_done(vop_dev);
4710                 }
4711                 spin_unlock(&vop_dev->reg_lock);
4712         }
4713
4714         return 0;
4715 }
4716
4717 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
4718 {
4719         struct vop_device *vop_dev =
4720             container_of(dev_drv, struct vop_device, driver);
4721
4722         if (unlikely(!vop_dev->clk_on)) {
4723                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4724                 return 0;
4725         }
4726         vop_get_backlight_device(dev_drv);
4727
4728         if (enable) {
4729                 /* close the backlight */
4730                 if (vop_dev->backlight) {
4731                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4732                         backlight_update_status(vop_dev->backlight);
4733                 }
4734                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4735                         dev_drv->trsm_ops->disable();
4736         } else {
4737                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4738                         dev_drv->trsm_ops->enable();
4739                 msleep(100);
4740                 /* open the backlight */
4741                 if (vop_dev->backlight) {
4742                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
4743                         backlight_update_status(vop_dev->backlight);
4744                 }
4745         }
4746
4747         return 0;
4748 }
4749
4750 static int vop_set_overscan(struct rk_lcdc_driver *dev_drv,
4751                             struct overscan *overscan)
4752 {
4753         struct vop_device *vop_dev =
4754             container_of(dev_drv, struct vop_device, driver);
4755
4756         if (unlikely(!vop_dev->clk_on)) {
4757                 pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
4758                 return 0;
4759         }
4760         /*vop_post_cfg(dev_drv);*/
4761
4762         return 0;
4763 }
4764
4765 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4766         .open = vop_open,
4767         .win_direct_en = vop_win_direct_en,
4768         .load_screen = vop_load_screen,
4769         .get_dspbuf_info = vop_get_dspbuf_info,
4770         .post_dspbuf = vop_post_dspbuf,
4771         .set_par = vop_set_par,
4772         .pan_display = vop_pan_display,
4773         .set_wb = vop_set_writeback,
4774         .direct_set_addr = vop_direct_set_win_addr,
4775         /*.lcdc_reg_update = vop_reg_update,*/
4776         .blank = vop_blank,
4777         .ioctl = vop_ioctl,
4778         .suspend = vop_early_suspend,
4779         .resume = vop_early_resume,
4780         .get_win_state = vop_get_win_state,
4781         .area_support_num = vop_get_area_num,
4782         .ovl_mgr = vop_ovl_mgr,
4783         .get_disp_info = vop_get_disp_info,
4784         .fps_mgr = vop_fps_mgr,
4785         .fb_get_win_id = vop_get_win_id,
4786         .fb_win_remap = vop_fb_win_remap,
4787         .poll_vblank = vop_poll_vblank,
4788         .dpi_open = vop_dpi_open,
4789         .dpi_win_sel = vop_dpi_win_sel,
4790         .dpi_status = vop_dpi_status,
4791         .get_dsp_addr = vop_get_dsp_addr,
4792         .set_dsp_lut = vop_set_lut,
4793         .set_cabc_lut = vop_set_cabc,
4794         .set_dsp_cabc = vop_set_dsp_cabc,
4795         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
4796         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
4797         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
4798         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
4799         .open_bcsh = vop_open_bcsh,
4800         .dump_reg = vop_reg_dump,
4801         .cfg_done = vop_config_done,
4802         .set_irq_to_cpu = vop_set_irq_to_cpu,
4803         /*.dsp_black = vop_dsp_black,*/
4804         .backlight_close = vop_backlight_close,
4805         .mmu_en    = vop_mmu_en,
4806         .set_overscan   = vop_set_overscan,
4807 };
4808
4809 static irqreturn_t vop_isr(int irq, void *dev_id)
4810 {
4811         struct vop_device *vop_dev = (struct vop_device *)dev_id;
4812         ktime_t timestamp = ktime_get();
4813         u32 intr_status;
4814         unsigned long flags;
4815
4816         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4817
4818         intr_status = vop_readl(vop_dev, INTR_STATUS0);
4819         vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status);
4820
4821         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4822         /* This is expected for vop iommu irqs, since the irq is shared */
4823         if (!intr_status)
4824                 return IRQ_NONE;
4825
4826         if (intr_status & INTR_FS) {
4827                 timestamp = ktime_get();
4828                 if (vop_dev->driver.wb_data.state) {
4829                         u32 wb_status;
4830
4831                         spin_lock_irqsave(&vop_dev->irq_lock, flags);
4832                         wb_status = vop_read_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4833
4834                         if (wb_status)
4835                                 vop_clr_bit(vop_dev, WB_CTRL0, V_WB_EN(0));
4836
4837                         vop_cfg_done(vop_dev);
4838                         vop_dev->driver.wb_data.state = 0;
4839                         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
4840                 }
4841                 vop_dev->driver.vsync_info.timestamp = timestamp;
4842                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
4843                 intr_status &= ~INTR_FS;
4844         }
4845
4846         if (intr_status & INTR_LINE_FLAG0)
4847                 intr_status &= ~INTR_LINE_FLAG0;
4848
4849         if (intr_status & INTR_LINE_FLAG1)
4850                 intr_status &= ~INTR_LINE_FLAG1;
4851
4852         if (intr_status & INTR_FS_NEW)
4853                 intr_status &= ~INTR_FS_NEW;
4854
4855         if (intr_status & INTR_BUS_ERROR) {
4856                 intr_status &= ~INTR_BUS_ERROR;
4857                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
4858         }
4859
4860         if (intr_status & INTR_WIN0_EMPTY) {
4861                 intr_status &= ~INTR_WIN0_EMPTY;
4862                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
4863         }
4864
4865         if (intr_status & INTR_WIN1_EMPTY) {
4866                 intr_status &= ~INTR_WIN1_EMPTY;
4867                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
4868         }
4869
4870         if (intr_status & INTR_HWC_EMPTY) {
4871                 intr_status &= ~INTR_HWC_EMPTY;
4872                 dev_warn_ratelimited(vop_dev->dev, "intr hwc empty!");
4873         }
4874
4875         if (intr_status & INTR_POST_BUF_EMPTY) {
4876                 intr_status &= ~INTR_POST_BUF_EMPTY;
4877                 dev_warn_ratelimited(vop_dev->dev, "intr post buf empty!");
4878         }
4879
4880         if (intr_status)
4881                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
4882
4883         return IRQ_HANDLED;
4884 }
4885
4886 #if defined(CONFIG_PM)
4887 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
4888 {
4889         return 0;
4890 }
4891
4892 static int vop_resume(struct platform_device *pdev)
4893 {
4894         return 0;
4895 }
4896 #else
4897 #define vop_suspend NULL
4898 #define vop_resume  NULL
4899 #endif
4900
4901 static int vop_parse_dt(struct vop_device *vop_dev)
4902 {
4903         struct device_node *np = vop_dev->dev->of_node;
4904         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
4905         int val;
4906
4907         if (of_property_read_u32(np, "rockchip,prop", &val))
4908                 vop_dev->prop = PRMRY;  /*default set it as primary */
4909         else
4910                 vop_dev->prop = val;
4911
4912         if (of_property_read_u32(np, "rockchip,mirror", &val))
4913                 dev_drv->rotate_mode = NO_MIRROR;
4914         else
4915                 dev_drv->rotate_mode = val;
4916
4917         if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
4918                 dev_drv->cabc_mode = 0; /* default set close cabc */
4919         else
4920                 dev_drv->cabc_mode = val;
4921
4922         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4923                 /*default set it as 3.xv power supply */
4924                 vop_dev->pwr18 = false;
4925         else
4926                 vop_dev->pwr18 = (val ? true : false);
4927
4928         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4929                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4930         else
4931                 dev_drv->fb_win_map = val;
4932
4933         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4934                 dev_drv->bcsh.enable = false;
4935         else
4936                 dev_drv->bcsh.enable = (val ? true : false);
4937
4938         if (of_property_read_u32(np, "rockchip,brightness", &val))
4939                 dev_drv->bcsh.brightness = 0xffff;
4940         else
4941                 dev_drv->bcsh.brightness = val;
4942
4943         if (of_property_read_u32(np, "rockchip,contrast", &val))
4944                 dev_drv->bcsh.contrast = 0xffff;
4945         else
4946                 dev_drv->bcsh.contrast = val;
4947
4948         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4949                 dev_drv->bcsh.sat_con = 0xffff;
4950         else
4951                 dev_drv->bcsh.sat_con = val;
4952
4953         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4954                 dev_drv->bcsh.sin_hue = 0xffff;
4955                 dev_drv->bcsh.cos_hue = 0xffff;
4956         } else {
4957                 dev_drv->bcsh.sin_hue = val & 0xff;
4958                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4959         }
4960
4961         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4962                 dev_drv->iommu_enabled = 0;
4963         else
4964                 dev_drv->iommu_enabled = val;
4965
4966         if (of_property_read_u32(np, "rockchip,dsp_mode", &val))
4967                 dev_drv->dsp_mode = DEFAULT_MODE;
4968         else
4969                 dev_drv->dsp_mode = val;
4970
4971         return 0;
4972 }
4973
4974 static struct platform_device *rk322x_pdev;
4975
4976 int vop_register_dmc(void)
4977 {
4978         struct platform_device *pdev = rk322x_pdev;
4979         struct vop_device *vop_dev;
4980         struct device *dev = &pdev->dev;
4981         struct devfreq *devfreq;
4982         struct devfreq_event_dev *event_dev;
4983
4984         if (!pdev)
4985                 return -ENODEV;
4986
4987         vop_dev = platform_get_drvdata(pdev);;
4988         if (!vop_dev)
4989                 return -ENODEV;
4990
4991         dev = &pdev->dev;
4992         devfreq = devfreq_get_devfreq_by_phandle(dev, 0);
4993         if (IS_ERR(devfreq)) {
4994                 dev_err(vop_dev->dev, "fail to get devfreq for dmc\n");
4995                 return -ENODEV;
4996         }
4997
4998         vop_dev->devfreq = devfreq;
4999         vop_dev->dmc_nb.notifier_call = dmc_notify;
5000         devfreq_register_notifier(vop_dev->devfreq, &vop_dev->dmc_nb,
5001                                   DEVFREQ_TRANSITION_NOTIFIER);
5002
5003         event_dev = devfreq_event_get_edev_by_phandle(vop_dev->devfreq->dev.parent,
5004                                                       0);
5005         if (IS_ERR(event_dev)) {
5006                 dev_err(vop_dev->dev, "fail to get edev for dmc\n");
5007                 return -ENODEV;
5008         }
5009
5010         vop_dev->devfreq_event_dev = event_dev;
5011         return 0;
5012 }
5013
5014 static int vop_probe(struct platform_device *pdev)
5015 {
5016         struct vop_device *vop_dev = NULL;
5017         struct rk_lcdc_driver *dev_drv;
5018         const struct of_device_id *of_id;
5019         struct device *dev = &pdev->dev;
5020         struct resource *res;
5021         struct device_node *np = pdev->dev.of_node;
5022         int prop;
5023         int ret = 0;
5024
5025         /* if the primary lcdc has not registered ,the extend
5026          * lcdc register later
5027          */
5028         of_property_read_u32(np, "rockchip,prop", &prop);
5029         if (prop == EXTEND) {
5030                 if (!is_prmry_rk_lcdc_registered())
5031                         return -EPROBE_DEFER;
5032         }
5033         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
5034         if (!vop_dev)
5035                 return -ENOMEM;
5036         of_id = of_match_device(vop_dt_ids, dev);
5037         vop_dev->data = of_id->data;
5038         if (VOP_CHIP(vop_dev) != VOP_RK322X && VOP_CHIP(vop_dev) != VOP_RK3399)
5039                 return -ENODEV;
5040         platform_set_drvdata(pdev, vop_dev);
5041         vop_dev->dev = dev;
5042         vop_parse_dt(vop_dev);
5043 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
5044         /* enable power domain */
5045         pm_runtime_enable(dev);
5046 #endif
5047         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
5048         vop_dev->reg_phy_base = res->start;
5049         vop_dev->len = resource_size(res);
5050         vop_dev->regs = devm_ioremap(&pdev->dev, res->start,
5051                                      resource_size(res));
5052         if (IS_ERR(vop_dev->regs))
5053                 return PTR_ERR(vop_dev->regs);
5054
5055         dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs);
5056
5057         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
5058         if (IS_ERR(vop_dev->regsbak))
5059                 return PTR_ERR(vop_dev->regsbak);
5060         if (VOP_CHIP(vop_dev) == VOP_RK3399) {
5061                 vop_dev->dsp_lut_addr_base = vop_dev->regs + GAMMA_LUT_ADDR;
5062                 vop_dev->cabc_lut_addr_base = vop_dev->regs +
5063                                                 CABC_GAMMA_LUT_ADDR;
5064         }
5065         vop_dev->grf_base =
5066                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
5067         if (IS_ERR(vop_dev->grf_base)) {
5068                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
5069                 vop_dev->grf_base = NULL;
5070         }
5071
5072         vop_dev->id = vop_get_id(vop_dev, vop_dev->reg_phy_base);
5073         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
5074         dev_drv = &vop_dev->driver;
5075         dev_drv->dev = dev;
5076         dev_drv->prop = prop;
5077         dev_drv->id = vop_dev->id;
5078         dev_drv->ops = &lcdc_drv_ops;
5079         dev_drv->lcdc_win_num = vop_dev->data->n_wins;
5080         dev_drv->reserved_fb = 0;
5081         spin_lock_init(&vop_dev->reg_lock);
5082         spin_lock_init(&vop_dev->irq_lock);
5083         vop_dev->irq = platform_get_irq(pdev, 0);
5084         if (vop_dev->irq < 0) {
5085                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
5086                         vop_dev->id);
5087                 return -ENXIO;
5088         }
5089
5090         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
5091                                IRQF_SHARED, dev_name(dev), vop_dev);
5092         if (ret) {
5093                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
5094                         vop_dev->irq, ret);
5095                 return ret;
5096         }
5097         if (dev_drv->iommu_enabled) {
5098                 if (VOP_CHIP(vop_dev) == VOP_RK322X) {
5099                         strcpy(dev_drv->mmu_dts_name,
5100                                VOP_IOMMU_COMPATIBLE_NAME);
5101                 } else {
5102                         if (vop_dev->id == 0)
5103                                 strcpy(dev_drv->mmu_dts_name,
5104                                        VOPB_IOMMU_COMPATIBLE_NAME);
5105                         else
5106                                 strcpy(dev_drv->mmu_dts_name,
5107                                        VOPL_IOMMU_COMPATIBLE_NAME);
5108                 }
5109         }
5110         if (VOP_CHIP(vop_dev) == VOP_RK3399)
5111                 dev_drv->property.feature |= SUPPORT_WRITE_BACK | SUPPORT_AFBDC;
5112         dev_drv->property.feature |= SUPPORT_VOP_IDENTIFY |
5113                                         SUPPORT_YUV420_OUTPUT;
5114         dev_drv->property.max_output_x = 4096;
5115         dev_drv->property.max_output_y = 2160;
5116
5117         if ((VOP_CHIP(vop_dev) == VOP_RK3399) && (vop_dev->id == 1)) {
5118                 vop_dev->data->win[1].property.feature &= ~SUPPORT_HW_EXIST;
5119                 vop_dev->data->win[3].property.feature &= ~SUPPORT_HW_EXIST;
5120         }
5121
5122         init_waitqueue_head(&vop_dev->wait_vop_switch_queue);
5123         vop_dev->vop_switch_status = 0;
5124         init_waitqueue_head(&vop_dev->wait_dmc_queue);
5125         vop_dev->dmc_in_process = 0;
5126
5127         ret = rk_fb_register(dev_drv, vop_dev->data->win, vop_dev->id);
5128         if (ret < 0) {
5129                 dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id);
5130                 return ret;
5131         }
5132         vop_dev->screen = dev_drv->screen0;
5133         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
5134                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
5135
5136         rk322x_pdev = pdev;
5137
5138         return 0;
5139 }
5140
5141 static int vop_remove(struct platform_device *pdev)
5142 {
5143         return 0;
5144 }
5145
5146 static void vop_shutdown(struct platform_device *pdev)
5147 {
5148         struct vop_device *vop_dev = platform_get_drvdata(pdev);
5149         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
5150
5151         dev_drv->suspend_flag = 1;
5152         /* ensure suspend_flag take effect on multi process */
5153         smp_wmb();
5154         flush_kthread_worker(&dev_drv->update_regs_worker);
5155         kthread_stop(dev_drv->update_regs_thread);
5156         vop_deint(vop_dev);
5157
5158         vop_clk_disable(vop_dev);
5159 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
5160         pm_runtime_disable(vop_dev->dev);
5161 #endif
5162         rk_disp_pwr_disable(dev_drv);
5163 }
5164
5165 static struct platform_driver vop_driver = {
5166         .probe = vop_probe,
5167         .remove = vop_remove,
5168         .driver = {
5169                    .name = "rk322x-lcdc",
5170                    .owner = THIS_MODULE,
5171                    .of_match_table = of_match_ptr(vop_dt_ids),
5172                    },
5173         .suspend = vop_suspend,
5174         .resume = vop_resume,
5175         .shutdown = vop_shutdown,
5176 };
5177
5178 static int __init vop_module_init(void)
5179 {
5180         return platform_driver_register(&vop_driver);
5181 }
5182
5183 static void __exit vop_module_exit(void)
5184 {
5185         platform_driver_unregister(&vop_driver);
5186 }
5187
5188 fs_initcall(vop_module_init);
5189 module_exit(vop_module_exit);