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