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