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