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