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