video: rockchip: vop lite: recover interlace config
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk_vop_lite.c
1 /*
2  * rockchip VOP(Video Output Processer) hardware driver.
3  *
4  * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
5  * Author: WenLong Zhuang <daisen.zhuang@rock-chips.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
22 #include <linux/mm.h>
23 #include <linux/slab.h>
24 #include <linux/device.h>
25 #include <linux/delay.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/rockchip-iovmm.h>
32 #include <asm/div64.h>
33 #include <linux/uaccess.h>
34 #include <linux/rockchip/cpu.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
40 #include "rk_vop_lite.h"
41
42 static int dbg_thresd;
43 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
44
45 #define DBG(level, x...) do {                   \
46         if (unlikely(dbg_thresd >= level))      \
47                 pr_info(x);\
48         } while (0)
49
50 #define to_vop_dev(drv) container_of(drv, struct vop_device, driver)
51
52 static struct rk_lcdc_win vop_win[] = {
53         { .name = "win0", .id = 0},
54         { .name = "win1", .id = 1},
55         { .name = "hwc",  .id = 2}
56 };
57
58 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
59
60 static int vop_clk_enable(struct vop_device *vop_dev)
61 {
62         if (!vop_dev->clk_on) {
63                 pm_runtime_get_sync(vop_dev->dev);
64
65                 clk_enable(vop_dev->hclk);
66                 clk_enable(vop_dev->aclk);
67                 clk_enable(vop_dev->dclk);
68                 spin_lock(&vop_dev->reg_lock);
69                 vop_dev->clk_on = 1;
70                 spin_unlock(&vop_dev->reg_lock);
71         }
72
73         return 0;
74 }
75
76 static int vop_clk_disable(struct vop_device *vop_dev)
77 {
78         if (vop_dev->clk_on) {
79                 spin_lock(&vop_dev->reg_lock);
80                 vop_dev->clk_on = 0;
81                 spin_unlock(&vop_dev->reg_lock);
82                 clk_disable(vop_dev->dclk);
83                 clk_disable(vop_dev->aclk);
84                 clk_disable(vop_dev->hclk);
85
86                 pm_runtime_put(vop_dev->dev);
87         }
88
89         return 0;
90 }
91
92 static int vop_irq_enable(struct vop_device *vop_dev)
93 {
94         u64 val;
95
96         spin_lock(&vop_dev->reg_lock);
97         if (likely(vop_dev->clk_on)) {
98                 vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, INTR_MASK);
99
100                 val = INTR_FS0 | INTR_FS1 | INTR_LINE_FLAG0 | INTR_LINE_FLAG1 |
101                         INTR_BUS_ERROR | INTR_WIN0_EMPTY | INTR_WIN1_EMPTY |
102                         INTR_DSP_HOLD_VALID;
103                 vop_mask_writel(vop_dev, INTR_EN, INTR_MASK, val);
104         }
105         spin_unlock(&vop_dev->reg_lock);
106
107         return 0;
108 }
109
110 static int vop_irq_disable(struct vop_device *vop_dev)
111 {
112         spin_lock(&vop_dev->reg_lock);
113         if (likely(vop_dev->clk_on)) {
114                 vop_writel(vop_dev, INTR_EN, 0xffff0000);
115                 vop_writel(vop_dev, INTR_CLEAR, 0xffffffff);
116                 vop_cfg_done(vop_dev);
117         }
118         spin_unlock(&vop_dev->reg_lock);
119
120         return 0;
121 }
122
123 static int vop_standby_enable(struct vop_device *vop_dev)
124 {
125         u64 val;
126         int ret;
127
128         spin_lock(&vop_dev->reg_lock);
129         if (likely(vop_dev->clk_on)) {
130                 vop_dev->sync.stdbyfin.done = 0;
131
132                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(1));
133                 /*vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);*/
134                 val = V_IMD_VOP_STANDBY_EN(1) | V_IMD_VOP_DMA_STOP(1) |
135                         V_IMD_DSP_OUT_ZERO(1);
136                 vop_msk_reg(vop_dev, SYS_CTRL2, val);
137                 vop_cfg_done(vop_dev);
138                 spin_unlock(&vop_dev->reg_lock);
139
140                 /* wait for standby hold valid */
141                 ret = vop_completion_timeout_ms(&vop_dev->sync.stdbyfin,
142                                                 vop_dev->sync.stdbyfin_to);
143                 if (!ret) {
144                         dev_err(vop_dev->dev,
145                                 "wait standby hold valid timeout %dms\n",
146                                 vop_dev->sync.stdbyfin_to);
147                         return -ETIMEDOUT;
148                 }
149         } else {
150                 spin_unlock(&vop_dev->reg_lock);
151         }
152
153         return 0;
154 }
155
156 static int vop_standby_disable(struct vop_device *vop_dev)
157 {
158         u64 val;
159         int ret;
160
161         spin_lock(&vop_dev->reg_lock);
162         if (likely(vop_dev->clk_on)) {
163                 vop_dev->sync.frmst.done = 0;
164                 val = V_IMD_VOP_STANDBY_EN(0) | V_IMD_VOP_DMA_STOP(0) |
165                         V_IMD_DSP_OUT_ZERO(0);
166                 vop_msk_reg(vop_dev, SYS_CTRL2, val);
167                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(0));
168                 vop_cfg_done(vop_dev);
169                 spin_unlock(&vop_dev->reg_lock);
170
171                 /* win address maybe effect after next frame start,
172                  * but mmu maybe effect right now, so need wait frame start
173                  */
174                 ret = vop_completion_timeout_ms(&vop_dev->sync.frmst,
175                                                 vop_dev->sync.frmst_to);
176                 if (!ret) {
177                         dev_err(vop_dev->dev, "wait frame start timeout %dms\n",
178                                 vop_dev->sync.frmst_to);
179                         return -ETIMEDOUT;
180                 }
181         } else {
182                 spin_unlock(&vop_dev->reg_lock);
183         }
184
185         return 0;
186 }
187
188 static int vop_mmu_enable(struct rk_lcdc_driver *dev_drv)
189 {
190         struct vop_device *vop_dev = to_vop_dev(dev_drv);
191
192         if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
193                 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
194                          __func__);
195                 return -ENODEV;
196         }
197
198         spin_lock(&vop_dev->reg_lock);
199         if (likely(vop_dev->clk_on)) {
200                 if (!vop_dev->iommu_status) {
201                         vop_dev->iommu_status = 1;
202                         rockchip_iovmm_activate(dev_drv->dev);
203                 }
204         }
205         spin_unlock(&vop_dev->reg_lock);
206
207         return 0;
208 }
209
210 static int vop_mmu_disable(struct rk_lcdc_driver *dev_drv)
211 {
212         struct vop_device *vop_dev = to_vop_dev(dev_drv);
213
214         if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
215                 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
216                          __func__);
217                 return -ENODEV;
218         }
219
220         spin_lock(&vop_dev->reg_lock);
221         if (likely(vop_dev->clk_on)) {
222                 if (vop_dev->iommu_status) {
223                         vop_dev->iommu_status = 0;
224                         rockchip_iovmm_deactivate(dev_drv->dev);
225                 }
226         }
227         spin_unlock(&vop_dev->reg_lock);
228
229         return 0;
230 }
231
232 static int vop_reg_dump(struct rk_lcdc_driver *dev_drv)
233 {
234         struct vop_device *vop_dev = to_vop_dev(dev_drv);
235         int *cbase = (int *)vop_dev->regs;
236         int *regsbak = (int *)vop_dev->regsbak;
237         int i, j, val;
238         char dbg_message[30];
239         char buf[10];
240
241         spin_lock(&vop_dev->reg_lock);
242         if (likely(vop_dev->clk_on)) {
243                 pr_info("vop back up reg:\n");
244                 memset(dbg_message, 0, sizeof(dbg_message));
245                 memset(buf, 0, sizeof(buf));
246                 for (i = 0; i <= (0x200 >> 4); i++) {
247                         val = sprintf(dbg_message, "0x%04x: ", i * 16);
248                         for (j = 0; j < 4; j++) {
249                                 val = sprintf(buf, "%08x  ",
250                                               *(regsbak + i * 4 + j));
251                                 strcat(dbg_message, buf);
252                         }
253                         pr_info("%s\n", dbg_message);
254                         memset(dbg_message, 0, sizeof(dbg_message));
255                         memset(buf, 0, sizeof(buf));
256                 }
257
258                 pr_info("vop reg:\n");
259                 for (i = 0; i <= (0x200 >> 4); i++) {
260                         val = sprintf(dbg_message, "0x%04x: ", i * 16);
261                         for (j = 0; j < 4; j++) {
262                                 sprintf(buf, "%08x  ",
263                                         readl_relaxed(cbase + i * 4 + j));
264                                 strcat(dbg_message, buf);
265                         }
266                         pr_info("%s\n", dbg_message);
267                         memset(dbg_message, 0, sizeof(dbg_message));
268                         memset(buf, 0, sizeof(buf));
269                 }
270         }
271         spin_unlock(&vop_dev->reg_lock);
272
273         return 0;
274 }
275
276 #define WIN_EN(id)              \
277 static int win##id##_enable(struct vop_device *vop_dev, int en) \
278 { \
279         spin_lock(&vop_dev->reg_lock);                                  \
280         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \
281         vop_cfg_done(vop_dev);                                          \
282         spin_unlock(&vop_dev->reg_lock);                                \
283         return 0;                                                       \
284 }
285
286 WIN_EN(0);
287 WIN_EN(1);
288
289 /*
290  * enable/disable win directly
291  */
292 static int vop_win_direct_en(struct rk_lcdc_driver *drv,
293                              int win_id, int en)
294 {
295         struct vop_device *vop_dev = to_vop_dev(drv);
296
297         if (win_id == 0)
298                 win0_enable(vop_dev, en);
299         else if (win_id == 1)
300                 win1_enable(vop_dev, en);
301         else
302                 dev_err(vop_dev->dev, "invalid win number:%d\n", win_id);
303         return 0;
304 }
305
306 #define SET_WIN_ADDR(id) \
307 static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \
308 {                                                       \
309         spin_lock(&vop_dev->reg_lock);                  \
310         vop_writel(vop_dev, WIN##id##_YRGB_MST, addr);  \
311         vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1));       \
312         vop_cfg_done(vop_dev);                  \
313         spin_unlock(&vop_dev->reg_lock);                \
314         return 0;                                       \
315 }
316
317 SET_WIN_ADDR(0);
318 SET_WIN_ADDR(1);
319
320 static int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
321                                    int win_id, u32 addr)
322 {
323         struct vop_device *vop_dev = to_vop_dev(dev_drv);
324
325         if (win_id == 0)
326                 set_win0_addr(vop_dev, addr);
327         else
328                 set_win1_addr(vop_dev, addr);
329
330         return 0;
331 }
332
333 static void vop_read_reg_default_cfg(struct vop_device *vop_dev)
334 {
335         int reg = 0;
336         u32 val = 0;
337         struct rk_screen *screen = vop_dev->driver.cur_screen;
338         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
339         u32 V_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
340         u32 st_x, st_y;
341         struct rk_lcdc_win *win0 = vop_dev->driver.win[0];
342
343         spin_lock(&vop_dev->reg_lock);
344         for (reg = 0; reg < vop_dev->len; reg += 4) {
345                 val = vop_readl_backup(vop_dev, reg);
346                 switch (reg) {
347                 case WIN0_ACT_INFO:
348                         win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
349                         win0->area[0].yact =
350                                 ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
351                         break;
352                 case WIN0_DSP_INFO:
353                         win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1;
354                         win0->area[0].ysize =
355                             ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
356                         break;
357                 case WIN0_DSP_ST:
358                         st_x = val & MASK(WIN0_DSP_XST);
359                         st_y = (val & MASK(WIN0_DSP_YST)) >> 16;
360                         win0->area[0].xpos = st_x - h_pw_bp;
361                         win0->area[0].ypos = st_y - V_pw_bp;
362                         break;
363                 case WIN0_CTRL0:
364                         win0->state = val & MASK(WIN0_EN);
365                         win0->area[0].fmt_cfg =
366                                         (val & MASK(WIN0_DATA_FMT)) >> 1;
367                         win0->area[0].format = win0->area[0].fmt_cfg;
368                         break;
369                 case WIN0_VIR:
370                         win0->area[0].y_vir_stride =
371                                         val & MASK(WIN0_YRGB_VIR_STRIDE);
372                         win0->area[0].uv_vir_stride =
373                             (val & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
374                         if (win0->area[0].format == ARGB888)
375                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
376                         else if (win0->area[0].format == RGB888)
377                                 win0->area[0].xvir =
378                                     win0->area[0].y_vir_stride * 4 / 3;
379                         else if ((win0->area[0].format == RGB565) ||
380                                  (win0->area[0].format == BGR565))
381                                 win0->area[0].xvir =
382                                     2 * win0->area[0].y_vir_stride;
383                         else
384                                 win0->area[0].xvir =
385                                     4 * win0->area[0].y_vir_stride;
386                         break;
387                 case WIN0_YRGB_MST:
388                         win0->area[0].smem_start = val;
389                         break;
390                 case WIN0_CBR_MST:
391                         win0->area[0].cbr_start = val;
392                         break;
393                 default:
394                         break;
395                 }
396         }
397         spin_unlock(&vop_dev->reg_lock);
398 }
399
400 static int vop_pre_init(struct rk_lcdc_driver *dev_drv)
401 {
402         struct vop_device *vop_dev = to_vop_dev(dev_drv);
403
404         if (vop_dev->pre_init)
405                 return 0;
406
407         if (dev_drv->iommu_enabled) {
408                 dev_drv->mmu_dev = rk_fb_get_sysmmu_device_by_compatible(
409                                                         dev_drv->mmu_dts_name);
410                 if (dev_drv->mmu_dev)
411                         rk_fb_platform_set_sysmmu(
412                                 dev_drv->mmu_dev, dev_drv->dev);
413                 else
414                         dev_err(dev_drv->dev, "fail get rk iommu device\n");
415         }
416
417         if (!support_uboot_display())
418                 rk_disp_pwr_enable(dev_drv);
419
420         vop_clk_enable(vop_dev);
421
422         /* backup reg config at uboot */
423         vop_read_reg_default_cfg(vop_dev);
424
425         /* vop io voltage select-->0: 3.3v; 1: 1.8v */
426         if (vop_dev->pwr18 == 1)
427                 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
428                                V_VOP_IOVOL_SEL(1));
429         else
430                 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
431                                V_VOP_IOVOL_SEL(0));
432
433         vop_msk_reg(vop_dev, SYS_CTRL1, V_SW_AXI_MAX_OUTSTAND_EN(1) |
434                     V_SW_AXI_MAX_OUTSTAND_NUM(31));
435         vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_AUTO_GATING_EN(0));
436         vop_cfg_done(vop_dev);
437         vop_dev->pre_init = true;
438
439         return 0;
440 }
441
442 static void vop_deinit(struct vop_device *vop_dev)
443 {
444         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
445
446         vop_standby_enable(vop_dev);
447         vop_irq_disable(vop_dev);
448         vop_mmu_disable(dev_drv);
449         vop_clk_disable(vop_dev);
450         clk_unprepare(vop_dev->dclk);
451         clk_unprepare(vop_dev->aclk);
452         clk_unprepare(vop_dev->hclk);
453         pm_runtime_disable(vop_dev->dev);
454 }
455
456 static void __maybe_unused
457 vop_win_csc_mode(struct vop_device *vop_dev, struct rk_lcdc_win *win,
458                  int csc_mode)
459 {
460         u64 val;
461
462         spin_lock(&vop_dev->reg_lock);
463         if (likely(vop_dev->clk_on)) {
464                 if (win->id == 0) {
465                         val = V_WIN0_CSC_MODE(csc_mode);
466                         vop_msk_reg(vop_dev, WIN0_CTRL0, val);
467                 } else if (win->id == 1) {
468                         val = V_WIN1_CSC_MODE(csc_mode);
469                         vop_msk_reg(vop_dev, WIN1_CTRL0, val);
470                 } else {
471                         dev_err(vop_dev->dev, "%s win%d unsupport csc mode",
472                                 __func__, win->id);
473                 }
474         }
475         spin_unlock(&vop_dev->reg_lock);
476 }
477
478 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
479 {
480         struct vop_device *vop_dev = to_vop_dev(dev_drv);
481         struct rk_lcdc_win *win;
482         int i;
483
484         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
485                 win = dev_drv->win[i];
486                 switch (i) {
487                 case 0:
488                         vop_writel(vop_dev, WIN0_COLOR_KEY, win->color_key_val);
489                         break;
490                 case 1:
491                         vop_writel(vop_dev, WIN1_COLOR_KEY, win->color_key_val);
492                         break;
493                 default:
494                         pr_info("%s:un support win num:%d\n",
495                                 __func__, i);
496                         break;
497                 }
498         }
499         return 0;
500 }
501
502 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
503 {
504         struct vop_device *vop_dev = to_vop_dev(dev_drv);
505         struct rk_lcdc_win *win = dev_drv->win[win_id];
506         u64 val;
507         int ppixel_alpha = 0;
508         int alpha_en = win->alpha_en;
509         int i;
510
511         if (!alpha_en) {
512                 if (win_id == 0) {
513                         val = V_WIN0_ALPHA_EN(0);
514                         vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
515                 } else {
516                         val = V_WIN1_ALPHA_EN(0);
517                         vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
518                 }
519                 return 0;
520         }
521
522         ppixel_alpha = ((win->area[0].format == ARGB888) ||
523                         (win->area[0].format == ABGR888)) ? 1 : 0;
524
525         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
526                 if (!dev_drv->win[i]->state)
527                         continue;
528                 if (win->z_order > dev_drv->win[i]->z_order)
529                         break;
530         }
531
532         /*
533          * The bottom layer not support ppixel_alpha mode.
534          */
535         if (i == dev_drv->lcdc_win_num) {
536                 ppixel_alpha = 0;
537                 alpha_en = 0;
538         }
539
540         if (win_id == 0) {
541                 val = V_WIN0_ALPHA_EN(alpha_en) |
542                         V_WIN0_ALPHA_MODE(ppixel_alpha) |
543                         V_WIN0_ALPHA_PRE_MUL(ppixel_alpha) |
544                         V_WIN0_ALPHA_SAT_MODE(0);
545                 vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
546         } else if (win_id == 1) {
547                 val = V_WIN1_ALPHA_EN(alpha_en) |
548                         V_WIN1_ALPHA_MODE(ppixel_alpha) |
549                         V_WIN1_ALPHA_PRE_MUL(ppixel_alpha) |
550                         V_WIN1_ALPHA_SAT_MODE(0);
551                 vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
552         } else {
553                 dev_err(vop_dev->dev, "%s: invalid win id=%d or unsupport\n",
554                         __func__, win_id);
555         }
556
557         return 0;
558 }
559
560 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
561                               struct rk_lcdc_win *win)
562 {
563         u64 val;
564         u16 yrgb_gather_num = 3;
565         u16 cbcr_gather_num = 1;
566
567         switch (win->area[0].format) {
568         case ARGB888:
569         case XBGR888:
570         case ABGR888:
571         case XRGB888:
572                 yrgb_gather_num = 3;
573                 break;
574         case RGB888:
575         case RGB565:
576         case BGR888:
577         case BGR565:
578                 yrgb_gather_num = 2;
579                 break;
580         case YUV444:
581         case YUV422:
582         case YUV420:
583         case YUV420_A:
584         case YUV422_A:
585         case YUV444_A:
586         case YUV420_NV21:
587                 yrgb_gather_num = 1;
588                 cbcr_gather_num = 2;
589                 break;
590         default:
591                 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
592                         __func__, win->area[0].format);
593                 return -EINVAL;
594         }
595
596         if (win->id == 0) {
597                 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
598                         V_WIN0_CBR_AXI_GATHER_EN(1) |
599                         V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
600                         V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
601                 vop_msk_reg(vop_dev, WIN0_CTRL1, val);
602         } else if (win->id == 1) {
603                 val = V_WIN1_AXI_GATHER_EN(1) |
604                         V_WIN1_AXI_GATHER_NUM(yrgb_gather_num);
605                 vop_msk_reg(vop_dev, WIN1_CTRL1, val);
606         }
607         return 0;
608 }
609
610 static int vop_win0_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
611 {
612         struct vop_device *vop_dev = to_vop_dev(dev_drv);
613         struct rk_lcdc_win *win = dev_drv->win[win_id];
614         u64 val;
615
616         if (win->state == 1) {
617                 vop_axi_gather_cfg(vop_dev, win);
618                 val = V_WIN0_EN(win->state) |
619                         V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
620                         V_WIN0_RB_SWAP(win->area[0].swap_rb) |
621                         V_WIN0_UV_SWAP(win->area[0].swap_uv);
622                 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
623                         val |= V_WIN0_INTERLACE_READ(1);
624                 else
625                         val |= V_WIN0_INTERLACE_READ(0);
626                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
627
628                 val = V_WIN0_YRGB_VIR_STRIDE(win->area[0].y_vir_stride) |
629                     V_WIN0_CBR_VIR_STRIDE(win->area[0].uv_vir_stride);
630                 vop_writel(vop_dev, WIN0_VIR, val);
631
632                 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
633                     V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
634                 vop_writel(vop_dev, WIN0_DSP_INFO, val);
635
636                 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
637                     V_WIN0_DSP_YST(win->area[0].dsp_sty);
638                 vop_writel(vop_dev, WIN0_DSP_ST, val);
639
640                 /* only win0 support scale and yuv */
641                 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
642                         V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
643                 vop_writel(vop_dev, WIN0_ACT_INFO, val);
644
645                 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
646                         V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
647                 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB, val);
648
649                 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
650                         V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
651                 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR, val);
652
653                 if (win->area[0].y_addr > 0)
654                         vop_writel(vop_dev, WIN0_YRGB_MST, win->area[0].y_addr);
655                 if (win->area[0].uv_addr > 0)
656                         vop_writel(vop_dev, WIN0_CBR_MST, win->area[0].uv_addr);
657
658                 vop_alpha_cfg(dev_drv, win_id);
659         } else {
660                 val = V_WIN0_EN(win->state);
661                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
662         }
663
664         return 0;
665 }
666
667 static int vop_win1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
668 {
669         struct vop_device *vop_dev = to_vop_dev(dev_drv);
670         struct rk_lcdc_win *win = dev_drv->win[win_id];
671         u64 val;
672
673         if (win->state == 1) {
674                 vop_axi_gather_cfg(vop_dev, win);
675                 val = V_WIN1_EN(win->state) |
676                         V_WIN1_DATA_FMT(win->area[0].fmt_cfg) |
677                         V_WIN1_RB_SWAP(win->area[0].swap_rb);
678                 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
679                         val |= V_WIN1_INTERLACE_READ(1);
680                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
681
682                 val = V_WIN1_VIR_STRIDE(win->area[0].y_vir_stride);
683                 vop_writel(vop_dev, WIN1_VIR, val);
684
685                 val = V_WIN1_DSP_WIDTH(win->area[0].xsize - 1) |
686                     V_WIN1_DSP_HEIGHT(win->area[0].ysize - 1);
687                 vop_writel(vop_dev, WIN1_DSP_INFO, val);
688
689                 val = V_WIN1_DSP_XST(win->area[0].dsp_stx) |
690                     V_WIN1_DSP_YST(win->area[0].dsp_sty);
691                 vop_writel(vop_dev, WIN1_DSP_ST, val);
692
693                 if (win->area[0].y_addr > 0)
694                         vop_writel(vop_dev, WIN1_YRGB_MST, win->area[0].y_addr);
695
696                 vop_alpha_cfg(dev_drv, win_id);
697         } else {
698                 val = V_WIN1_EN(win->state);
699                 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
700         }
701
702         return 0;
703 }
704
705 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
706 {
707         struct vop_device *vop_dev = to_vop_dev(dev_drv);
708         struct rk_lcdc_win *win = dev_drv->win[win_id];
709         unsigned int hwc_size = 0;
710         u64 val;
711
712         if (win->state == 1) {
713                 vop_axi_gather_cfg(vop_dev, win);
714
715                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
716                         hwc_size = 0;
717                 else if ((win->area[0].xsize == 64) &&
718                          (win->area[0].ysize == 64))
719                         hwc_size = 1;
720                 else
721                         dev_err(vop_dev->dev, "unsupported hwc size[%dx%d]!\n",
722                                 win->area[0].xsize, win->area[0].ysize);
723
724                 val = V_HWC_EN(1) | V_HWC_SIZE(hwc_size);
725                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
726
727                 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
728                     V_HWC_DSP_YST(win->area[0].dsp_sty);
729                 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
730
731                 if (win->area[0].y_addr > 0)
732                         vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
733         } else {
734                 val = V_HWC_EN(win->state);
735                 vop_msk_reg(vop_dev, HWC_CTRL0, val);
736         }
737
738         return 0;
739 }
740
741 static int vop_layer_update_regs(struct vop_device *vop_dev,
742                                  struct rk_lcdc_win *win)
743 {
744         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
745
746         vop_msk_reg(vop_dev, SYS_CTRL2,
747                     V_IMD_VOP_STANDBY_EN(vop_dev->standby));
748         if (win->id == 0)
749                 vop_win0_reg_update(dev_drv, win->id);
750         else if (win->id == 1)
751                 vop_win1_reg_update(dev_drv, win->id);
752         else if (win->id == 2)
753                 vop_hwc_reg_update(dev_drv, win->id);
754         vop_cfg_done(vop_dev);
755
756         DBG(2, "%s for vop%d\n", __func__, vop_dev->id);
757         return 0;
758 }
759
760 static int vop_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
761                            int *hwc_lut, int mode)
762 {
763         int i = 0;
764         int __iomem *c;
765         int v;
766         int len = 256 * sizeof(u32);
767         struct vop_device *vop_dev = to_vop_dev(dev_drv);
768
769         if (!dev_drv->hwc_lut)
770                 dev_drv->hwc_lut = devm_kzalloc(vop_dev->dev, len, GFP_KERNEL);
771
772         spin_lock(&vop_dev->reg_lock);
773         if (likely(vop_dev->clk_on)) {
774                 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(0));
775                 vop_cfg_done(vop_dev);
776                 mdelay(25);
777                 for (i = 0; i < 256; i++) {
778                         if (mode == 1)
779                                 dev_drv->hwc_lut[i] = hwc_lut[i];
780
781                         v = dev_drv->hwc_lut[i];
782                         c = vop_dev->hwc_lut_addr_base + i;
783                         writel_relaxed(v, c);
784                 }
785                 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(1));
786                 vop_cfg_done(vop_dev);
787         }
788         spin_unlock(&vop_dev->reg_lock);
789
790         return 0;
791 }
792
793 static int vop_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
794 {
795         int i = 0;
796         int __iomem *c;
797         int v;
798         struct vop_device *vop_dev = to_vop_dev(dev_drv);
799
800         if (!dsp_lut)
801                 return 0;
802
803         spin_lock(&vop_dev->reg_lock);
804         if (likely(vop_dev->clk_on)) {
805                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(0));
806                 vop_cfg_done(vop_dev);
807                 mdelay(25);
808                 for (i = 0; i < 256; i++) {
809                         v = dsp_lut[i];
810                         c = vop_dev->dsp_lut_addr_base + i;
811                         writel_relaxed(v, c);
812                 }
813                 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(1));
814                 vop_cfg_done(vop_dev);
815         }
816         spin_unlock(&vop_dev->reg_lock);
817
818         return 0;
819 }
820
821 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
822 {
823         int ret = 0, fps = 0;
824         struct vop_device *vop_dev = to_vop_dev(dev_drv);
825         struct rk_screen *screen = dev_drv->cur_screen;
826
827         if (reset_rate)
828                 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
829         if (ret)
830                 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
831                         vop_dev->id, screen->mode.pixclock);
832         vop_dev->pixclock =
833             div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
834         vop_dev->driver.pixclock = vop_dev->pixclock;
835
836         fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
837         screen->ft = 1000 / fps;
838         dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
839                  vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
840         return 0;
841 }
842
843 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
844 {
845         struct vop_device *vop_dev = to_vop_dev(dev_drv);
846         struct rk_screen *screen = dev_drv->cur_screen;
847         u16 hsync_len = screen->mode.hsync_len;
848         u16 left_margin = screen->mode.left_margin;
849         u16 right_margin = screen->mode.right_margin;
850         u16 vsync_len = screen->mode.vsync_len;
851         u16 upper_margin = screen->mode.upper_margin;
852         u16 lower_margin = screen->mode.lower_margin;
853         u16 x_res = screen->mode.xres;
854         u16 y_res = screen->mode.yres;
855         u64 val;
856         u16 h_total, v_total;
857         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
858
859         /* config timing reg valid immediately or after frame start */
860         if (screen->mode.vmode & FB_VMODE_INTERLACED) /* after frame start */
861                 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(1));
862         else /* timing reg valid immediately */
863                 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(0));
864
865         h_total = hsync_len + left_margin + x_res + right_margin;
866         v_total = vsync_len + upper_margin + y_res + lower_margin;
867
868         val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
869         vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
870
871         val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
872             V_DSP_HACT_ST(hsync_len + left_margin);
873         vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
874
875         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
876                 /* First Field Timing */
877                 val = V_DSP_VS_END(vsync_len) |
878                     V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
879                                       lower_margin) + y_res + 1);
880                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
881
882                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
883                     V_DSP_VACT_ST(vsync_len + upper_margin);
884                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
885
886                 /* Second Field Timing */
887                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
888                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
889                     lower_margin;
890                 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
891                 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
892
893                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
894                     lower_margin + 1;
895                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
896                     lower_margin + 1;
897                 val = V_DSP_VACT_END_F1(vact_end_f1) |
898                         V_DSP_VACT_ST_F1(vact_st_f1);
899                 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
900
901                 val = V_DSP_LINE_FLAG0_NUM(lower_margin ?
902                                            vact_end_f1 : vact_end_f1 - 1);
903
904                 val |= V_DSP_LINE_FLAG1_NUM(lower_margin ?
905                                             vact_end_f1 : vact_end_f1 - 1);
906                 vop_msk_reg(vop_dev, LINE_FLAG, val);
907         } else {
908                 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
909                 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
910
911                 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
912                     V_DSP_VACT_ST(vsync_len + upper_margin);
913                 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
914
915                 val = V_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
916                         V_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
917                 vop_msk_reg(vop_dev, LINE_FLAG, val);
918         }
919
920         return 0;
921 }
922
923 static int vop_config_source(struct rk_lcdc_driver *dev_drv)
924 {
925         struct vop_device *vop_dev = to_vop_dev(dev_drv);
926         struct rk_screen *screen = dev_drv->cur_screen;
927         u64 val = 0;
928
929         switch (screen->type) {
930         case SCREEN_RGB:
931                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON5,
932                                V_RGB_VOP_SEL(dev_drv->id));
933                 val = V_RGB_DCLK_EN(1) | V_RGB_DCLK_POL(screen->pin_dclk) |
934                         V_RGB_HSYNC_POL(screen->pin_hsync) |
935                         V_RGB_VSYNC_POL(screen->pin_vsync) |
936                         V_RGB_DEN_POL(screen->pin_den);
937                 break;
938         case SCREEN_HDMI:
939                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
940                                V_HDMI_VOP_SEL(dev_drv->id));
941                 val = V_HDMI_DCLK_EN(1) | V_HDMI_DCLK_POL(screen->pin_dclk) |
942                         V_HDMI_HSYNC_POL(screen->pin_hsync) |
943                         V_HDMI_VSYNC_POL(screen->pin_vsync) |
944                         V_HDMI_DEN_POL(screen->pin_den);
945                 break;
946         case SCREEN_LVDS:
947                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
948                                V_LVDS_VOP_SEL(dev_drv->id));
949                 val = V_LVDS_DCLK_EN(1) | V_LVDS_DCLK_POL(screen->pin_dclk) |
950                         V_LVDS_HSYNC_POL(screen->pin_hsync) |
951                         V_LVDS_VSYNC_POL(screen->pin_vsync) |
952                         V_LVDS_DEN_POL(screen->pin_den);
953                 break;
954         case SCREEN_MIPI:
955                 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
956                                V_DSI0_VOP_SEL(dev_drv->id));
957                 val = V_MIPI_DCLK_EN(1) | V_MIPI_DCLK_POL(screen->pin_dclk) |
958                         V_MIPI_HSYNC_POL(screen->pin_hsync) |
959                         V_MIPI_VSYNC_POL(screen->pin_vsync) |
960                         V_MIPI_DEN_POL(screen->pin_den);
961                 break;
962         default:
963                 dev_err(vop_dev->dev, "un supported interface[%d]!\n",
964                         screen->type);
965                 break;
966         }
967
968         val |= V_SW_CORE_CLK_SEL(!!screen->pixelrepeat);
969         if (screen->mode.vmode & FB_VMODE_INTERLACED)
970                 val |= V_SW_HDMI_CLK_I_SEL(1);
971         else
972                 val |= V_SW_HDMI_CLK_I_SEL(0);
973         vop_msk_reg(vop_dev, DSP_CTRL0, val);
974
975         return 0;
976 }
977
978 static int vop_config_interface(struct rk_lcdc_driver *dev_drv)
979 {
980         struct vop_device *vop_dev = to_vop_dev(dev_drv);
981         struct rk_screen *screen = dev_drv->cur_screen;
982         u64 val = 0;
983
984         /* FRC dither down init */
985         if (screen->face != OUT_P888) {
986                 vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821);
987                 vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412);
988                 vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696);
989                 vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969);
990                 vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
991                 vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
992         }
993
994         switch (screen->face) {
995         case OUT_P888:
996                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(0);
997                 break;
998         case OUT_P565:
999                 val = V_DSP_OUT_MODE(OUT_P565) | V_DITHER_DOWN(1) |
1000                         V_DITHER_DOWN_MODE(DITHER_888_565) |
1001                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1002                 break;
1003         case OUT_P666:
1004                 val = V_DSP_OUT_MODE(OUT_P666) | V_DITHER_DOWN(1) |
1005                         V_DITHER_DOWN_MODE(DITHER_888_666) |
1006                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1007                 break;
1008         case OUT_D888_P565:
1009                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1010                         V_DITHER_DOWN_MODE(DITHER_888_565) |
1011                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1012                 break;
1013         case OUT_D888_P666:
1014                 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1015                         V_DITHER_DOWN_MODE(DITHER_888_666) |
1016                         V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1017                 break;
1018         default:
1019                 dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
1020                         screen->face);
1021                 break;
1022         }
1023
1024         if (screen->mode.vmode & FB_VMODE_INTERLACED)
1025                 val |= V_DSP_INTERLACE(1) | V_INTERLACE_FIELD_POL(0);
1026         else
1027                 val |= V_DSP_INTERLACE(0) | V_INTERLACE_FIELD_POL(0);
1028
1029         dev_drv->output_color = screen->color_mode;
1030         if (screen->color_mode == COLOR_RGB)
1031                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1032         else
1033                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1034
1035         val |= V_SW_OVERLAY_MODE(dev_drv->overlay_mode) |
1036                 V_DSP_BG_SWAP(screen->swap_gb) |
1037                 V_DSP_RB_SWAP(screen->swap_rb) |
1038                 V_DSP_RG_SWAP(screen->swap_rg) |
1039                 V_DSP_DELTA_SWAP(screen->swap_delta) |
1040                 V_DSP_DUMMY_SWAP(screen->swap_dumy) |
1041                 V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0);
1042         vop_msk_reg(vop_dev, DSP_CTRL2, val);
1043
1044         return 0;
1045 }
1046
1047 static void vop_config_background(struct rk_lcdc_driver *dev_drv, int rgb)
1048 {
1049         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1050         u64 val;
1051         int b = rgb & 0xff;
1052         int g = (rgb >> 8) & 0xff;
1053         int r = (rgb >> 16) & 0xff;
1054
1055         val = V_DSP_BG_BLUE(b) | V_DSP_BG_GREEN(g) | V_DSP_BG_RED(r);
1056         vop_msk_reg(vop_dev, DSP_BG, val);
1057 }
1058
1059 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1060 {
1061         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1062
1063         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1064                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1065                         vop_msk_reg(vop_dev, BCSH_CTRL,
1066                                     V_SW_BCSH_Y2R_EN(0) | V_SW_BCSH_R2Y_EN(0));
1067                 else            /* YUV2RGB */
1068                         vop_msk_reg(vop_dev, BCSH_CTRL, V_SW_BCSH_Y2R_EN(1) |
1069                                     V_SW_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1070                                     V_SW_BCSH_R2Y_EN(0));
1071         } else {
1072                 /* overlay_mode=VOP_RGB_DOMAIN */
1073                 /* bypass  --need check,if bcsh close? */
1074                 if (dev_drv->output_color == COLOR_RGB) {
1075                         if (dev_drv->bcsh.enable == 1)
1076                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1077                                             V_SW_BCSH_R2Y_EN(1) |
1078                                             V_SW_BCSH_Y2R_EN(1));
1079                         else
1080                                 vop_msk_reg(vop_dev, BCSH_CTRL,
1081                                             V_SW_BCSH_R2Y_EN(0) |
1082                                             V_SW_BCSH_Y2R_EN(0));
1083                 } else {
1084                         /* RGB2YUV */
1085                         vop_msk_reg(vop_dev, BCSH_CTRL,
1086                                     V_SW_BCSH_R2Y_EN(1) |
1087                                     V_SW_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1088                                     V_SW_BCSH_Y2R_EN(0));
1089                 }
1090         }
1091 }
1092
1093 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1094                                u16 *yact, int *format, u32 *dsp_addr,
1095                                int *ymirror)
1096 {
1097         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1098         u32 val;
1099
1100         spin_lock(&vop_dev->reg_lock);
1101         if (likely(vop_dev->clk_on)) {
1102                 val = vop_readl(vop_dev, WIN0_ACT_INFO);
1103                 *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1104                 *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1105
1106                 val = vop_readl(vop_dev, WIN0_CTRL0);
1107                 *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1108                 *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1109         }
1110         spin_unlock(&vop_dev->reg_lock);
1111
1112         return 0;
1113 }
1114
1115 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1116                            int format, u16 xact, u16 yact, u16 xvir,
1117                            int ymirror)
1118 {
1119         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1120         int swap = (format == RGB888) ? 1 : 0;
1121         u64 val;
1122
1123         spin_lock(&vop_dev->reg_lock);
1124         if (likely(vop_dev->clk_on)) {
1125                 val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap);
1126                 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1127
1128                 vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_YRGB_VIR_STRIDE(xvir));
1129                 vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1130                            V_WIN0_ACT_HEIGHT(yact - 1));
1131
1132                 vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1133
1134                 vop_cfg_done(vop_dev);
1135         }
1136         spin_unlock(&vop_dev->reg_lock);
1137
1138         return 0;
1139 }
1140
1141 static void vop_reg_restore(struct rk_lcdc_driver *dev_drv)
1142 {
1143         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1144         int len = FLAG_REG;
1145
1146         spin_lock(&vop_dev->reg_lock);
1147
1148         if (likely(vop_dev->clk_on))
1149                 memcpy(vop_dev->regs, vop_dev->regsbak, len);
1150
1151         spin_unlock(&vop_dev->reg_lock);
1152
1153         /* set screen GAMMA lut */
1154         if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1155                 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1156
1157         /* set hwc lut */
1158         vop_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1159 }
1160
1161 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1162 {
1163         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1164         struct rk_screen *screen = dev_drv->cur_screen;
1165
1166         /*if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))*/
1167         /*      flush_kthread_worker(&dev_drv->update_regs_worker);*/
1168
1169         spin_lock(&vop_dev->reg_lock);
1170         if (likely(vop_dev->clk_on)) {
1171                 vop_config_interface(dev_drv);
1172                 vop_config_source(dev_drv);
1173                 vop_config_timing(dev_drv);
1174                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
1175                         vop_config_background(dev_drv, 0x801080);
1176                 else
1177                         vop_config_background(dev_drv, 0x000000);
1178
1179                 vop_bcsh_path_sel(dev_drv);
1180                 vop_cfg_done(vop_dev);
1181         }
1182         spin_unlock(&vop_dev->reg_lock);
1183
1184         vop_set_dclk(dev_drv, 1);
1185         if (screen->init)
1186                 screen->init();
1187
1188         return 0;
1189 }
1190
1191 /*
1192  * enable or disable layer according to win id
1193  * @open: 1 enable; 0 disable
1194  */
1195 static void vop_layer_enable(struct vop_device *vop_dev,
1196                              unsigned int win_id, bool open)
1197 {
1198         spin_lock(&vop_dev->reg_lock);
1199         if (likely(vop_dev->clk_on) &&
1200             vop_dev->driver.win[win_id]->state != open) {
1201                 if (open) {
1202                         if (!vop_dev->atv_layer_cnt) {
1203                                 dev_info(vop_dev->dev,
1204                                          "wakeup from standby!\n");
1205                                 vop_dev->standby = 0;
1206                         }
1207                         vop_dev->atv_layer_cnt |= (1 << win_id);
1208                 } else {
1209                         if (vop_dev->atv_layer_cnt & (1 << win_id))
1210                                 vop_dev->atv_layer_cnt &= ~(1 << win_id);
1211                 }
1212                 vop_dev->driver.win[win_id]->state = open;
1213                 if (!open) {
1214                         vop_layer_update_regs(vop_dev,
1215                                               vop_dev->driver.win[win_id]);
1216                         vop_cfg_done(vop_dev);
1217                 }
1218                 /* if no layer used,disable lcdc */
1219                 if (!vop_dev->atv_layer_cnt) {
1220                         dev_info(vop_dev->dev,
1221                                  "no layer is used,go to standby!\n");
1222                         vop_dev->standby = 1;
1223                 }
1224         }
1225         spin_unlock(&vop_dev->reg_lock);
1226 }
1227
1228 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
1229                     bool open)
1230 {
1231         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1232
1233         /* enable clk,when first layer open */
1234         if ((open) && (!vop_dev->atv_layer_cnt)) {
1235                 /* rockchip_set_system_status(sys_status); */
1236                 vop_pre_init(dev_drv);
1237                 vop_clk_enable(vop_dev);
1238                 vop_irq_enable(vop_dev);
1239
1240                 if (support_uboot_display() && (vop_dev->prop == PRMRY)) {
1241                         vop_set_dclk(dev_drv, 0);
1242                 } else {
1243                         vop_load_screen(dev_drv, 1);
1244                         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1245                                 dev_drv->trsm_ops->enable();
1246                 }
1247                 if (dev_drv->bcsh.enable)
1248                         vop_set_bcsh(dev_drv, 1);
1249
1250                 /* set screen GAMMA lut */
1251                 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1252                         vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1253         }
1254
1255         if (win_id < ARRAY_SIZE(vop_win))
1256                 vop_layer_enable(vop_dev, win_id, open);
1257         else
1258                 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
1259
1260         dev_drv->first_frame = 0;
1261         return 0;
1262 }
1263
1264 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1265 {
1266         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1267         struct rk_lcdc_win *win = NULL;
1268         struct rk_screen *screen = dev_drv->cur_screen;
1269
1270         if (!screen) {
1271                 dev_err(dev_drv->dev, "screen is null!\n");
1272                 return -ENOENT;
1273         }
1274
1275         if (win_id >= dev_drv->lcdc_win_num) {
1276                 dev_err(dev_drv->dev, "invalid win id:%d!\n", win_id);
1277                 return -EINVAL;
1278         }
1279
1280         win = dev_drv->win[win_id];
1281         win->area[0].y_addr = win->area[0].smem_start + win->area[0].y_offset;
1282         /* only win0 support yuv format */
1283         if (win_id == 0)
1284                 win->area[0].uv_addr =
1285                         win->area[0].cbr_start + win->area[0].c_offset;
1286         else
1287                 win->area[0].uv_addr = 0;
1288
1289         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
1290             vop_dev->id, win->id, win->area[0].y_addr, win->area[0].uv_addr);
1291         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
1292             win->area[0].y_offset, win->area[0].c_offset);
1293         return 0;
1294 }
1295
1296 static int win_0_1_set_par(struct vop_device *vop_dev,
1297                            struct rk_screen *screen, struct rk_lcdc_win *win)
1298 {
1299         char fmt[9] = "NULL";
1300
1301         win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1302                                 screen->mode.hsync_len;
1303         if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1304                 win->area[0].ysize /= 2;
1305                 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1306                         screen->mode.upper_margin + screen->mode.vsync_len;
1307         } else {
1308                 win->area[0].dsp_sty = win->area[0].ypos +
1309                         screen->mode.upper_margin + screen->mode.vsync_len;
1310         }
1311
1312         win->scale_yrgb_x = CALSCALE(win->area[0].xact, win->area[0].xsize);
1313         win->scale_yrgb_y = CALSCALE(win->area[0].yact, win->area[0].ysize);
1314
1315         switch (win->area[0].format) {
1316         case ARGB888:
1317                 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1318                 win->area[0].swap_rb = 0;
1319                 break;
1320         case XBGR888:
1321         case ABGR888:
1322                 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1323                 win->area[0].swap_rb = 1;
1324                 break;
1325         case RGB888:
1326                 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1327                 win->area[0].swap_rb = 0;
1328                 break;
1329         case RGB565:
1330                 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1331                 win->area[0].swap_rb = 0;
1332                 break;
1333         case XRGB888:
1334                 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1335                 win->area[0].swap_rb = 0;
1336                 break;
1337         case BGR888:
1338                 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1339                 win->area[0].swap_rb = 1;
1340                 break;
1341         case BGR565:
1342                 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1343                 win->area[0].swap_rb = 1;
1344                 break;
1345         case YUV422:
1346                 if (win->id == 0) {
1347                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1348                         win->area[0].swap_rb = 0;
1349                         win->area[0].swap_uv = 0;
1350                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1351                                                      win->area[0].xsize);
1352                         win->scale_cbcr_y = CALSCALE(win->area[0].yact,
1353                                                      win->area[0].ysize);
1354                 } else {
1355                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1356                                 __func__, win->id);
1357                 }
1358                 break;
1359         case YUV420:
1360                 if (win->id == 0) {
1361                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1362                         win->area[0].swap_rb = 0;
1363                         win->area[0].swap_uv = 0;
1364                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1365                                                      win->area[0].xsize);
1366                         win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1367                                                      win->area[0].ysize);
1368                 } else {
1369                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1370                                 __func__, win->id);
1371                 }
1372
1373                 break;
1374         case YUV420_NV21:
1375                 if (win->id == 0) {
1376                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1377                         win->area[0].swap_rb = 0;
1378                         win->area[0].swap_uv = 1;
1379                         win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1380                                                      win->area[0].xsize);
1381                         win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1382                                                      win->area[0].ysize);
1383                 } else {
1384                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1385                                 __func__, win->id);
1386                 }
1387                 break;
1388         case YUV444:
1389                 if (win->id == 0) {
1390                         win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1391                         win->area[0].swap_rb = 0;
1392                         win->area[0].swap_uv = 0;
1393                         win->scale_cbcr_x =
1394                                 CALSCALE(win->area[0].xact, win->area[0].xsize);
1395                         win->scale_cbcr_y =
1396                                 CALSCALE(win->area[0].yact, win->area[0].ysize);
1397                 } else {
1398                         dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1399                                 __func__, win->id);
1400                 }
1401                 break;
1402         default:
1403                 dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
1404                         __func__, win->area[0].format);
1405                 break;
1406         }
1407
1408         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
1409             vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
1410             win->area[0].xact, win->area[0].yact, win->area[0].xsize);
1411         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
1412             win->area[0].ysize, win->area[0].xvir, win->area[0].yvir,
1413             win->area[0].xpos, win->area[0].ypos);
1414
1415         return 0;
1416 }
1417
1418 static int hwc_set_par(struct vop_device *vop_dev,
1419                        struct rk_screen *screen, struct rk_lcdc_win *win)
1420 {
1421         win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1422                                 screen->mode.hsync_len;
1423         win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin +
1424                                 screen->mode.vsync_len;
1425
1426         DBG(1, "lcdc[%d]:hwc>>%s\n>>xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d",
1427             vop_dev->id, __func__, win->area[0].xsize, win->area[0].ysize,
1428             win->area[0].xpos, win->area[0].ypos);
1429         return 0;
1430 }
1431
1432 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1433 {
1434         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1435         struct rk_screen *screen = dev_drv->cur_screen;
1436
1437         if (!screen) {
1438                 dev_err(dev_drv->dev, "screen is null!\n");
1439                 return -ENOENT;
1440         }
1441
1442         switch (win_id) {
1443         case 0:
1444                 win_0_1_set_par(vop_dev, screen, dev_drv->win[0]);
1445                 break;
1446         case 1:
1447                 win_0_1_set_par(vop_dev, screen, dev_drv->win[1]);
1448                 break;
1449         case 2:
1450                 hwc_set_par(vop_dev, screen, dev_drv->win[2]);
1451                 break;
1452         default:
1453                 dev_err(dev_drv->dev, "%s: unsupported win id:%d\n",
1454                         __func__, win_id);
1455                 break;
1456         }
1457         return 0;
1458 }
1459
1460 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1461                      unsigned long arg, int win_id)
1462 {
1463         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1464         u32 panel_size[2];
1465         void __user *argp = (void __user *)arg;
1466         struct color_key_cfg clr_key_cfg;
1467
1468         switch (cmd) {
1469         case RK_FBIOGET_PANEL_SIZE:
1470                 panel_size[0] = vop_dev->screen->mode.xres;
1471                 panel_size[1] = vop_dev->screen->mode.yres;
1472                 if (copy_to_user(argp, panel_size, 8))
1473                         return -EFAULT;
1474                 break;
1475         case RK_FBIOPUT_COLOR_KEY_CFG:
1476                 if (copy_from_user(&clr_key_cfg, argp,
1477                                    sizeof(struct color_key_cfg)))
1478                         return -EFAULT;
1479                 vop_clr_key_cfg(dev_drv);
1480                 vop_writel(vop_dev, WIN0_COLOR_KEY,
1481                            clr_key_cfg.win0_color_key_cfg);
1482                 vop_writel(vop_dev, WIN1_COLOR_KEY,
1483                            clr_key_cfg.win1_color_key_cfg);
1484                 break;
1485
1486         default:
1487                 break;
1488         }
1489         return 0;
1490 }
1491
1492 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1493 {
1494         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1495         struct device_node *backlight;
1496         struct property *prop;
1497         u32 *brightness_levels;
1498         u32 length, max, last;
1499
1500         if (vop_dev->backlight)
1501                 return 0;
1502         backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
1503         if (backlight) {
1504                 vop_dev->backlight = of_find_backlight_by_node(backlight);
1505                 if (!vop_dev->backlight)
1506                         dev_info(vop_dev->dev, "No find backlight device\n");
1507         } else {
1508                 dev_info(vop_dev->dev, "No find backlight device node\n");
1509         }
1510         prop = of_find_property(backlight, "brightness-levels", &length);
1511         if (!prop)
1512                 return -EINVAL;
1513         max = length / sizeof(u32);
1514         last = max - 1;
1515         brightness_levels = kmalloc(256, GFP_KERNEL);
1516         if (brightness_levels)
1517                 return -ENOMEM;
1518
1519         if (!of_property_read_u32_array(backlight, "brightness-levels",
1520                                         brightness_levels, max)) {
1521                 if (brightness_levels[0] > brightness_levels[last])
1522                         dev_drv->cabc_pwm_pol = 1;/*negative*/
1523                 else
1524                         dev_drv->cabc_pwm_pol = 0;/*positive*/
1525         } else {
1526                 dev_info(vop_dev->dev,
1527                          "Can not read brightness-levels value\n");
1528         }
1529
1530         kfree(brightness_levels);
1531
1532         return 0;
1533 }
1534
1535 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
1536 {
1537         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1538
1539         if (dev_drv->suspend_flag)
1540                 return 0;
1541
1542         vop_get_backlight_device(dev_drv);
1543
1544         if (enable) {
1545                 /* close the backlight */
1546                 if (vop_dev->backlight) {
1547                         vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
1548                         backlight_update_status(vop_dev->backlight);
1549                 }
1550                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1551                         dev_drv->trsm_ops->disable();
1552         } else {
1553                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1554                         dev_drv->trsm_ops->enable();
1555                 msleep(100);
1556                 /* open the backlight */
1557                 if (vop_dev->backlight) {
1558                         vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
1559                         backlight_update_status(vop_dev->backlight);
1560                 }
1561         }
1562
1563         return 0;
1564 }
1565
1566 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
1567 {
1568         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1569
1570         if (dev_drv->suspend_flag)
1571                 return 0;
1572
1573         dev_drv->suspend_flag = 1;
1574         smp_wmb();
1575         flush_kthread_worker(&dev_drv->update_regs_worker);
1576
1577         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1578                 dev_drv->trsm_ops->disable();
1579
1580         vop_standby_enable(vop_dev);
1581         vop_mmu_disable(dev_drv);
1582         vop_clk_disable(vop_dev);
1583         rk_disp_pwr_disable(dev_drv);
1584
1585         return 0;
1586 }
1587
1588 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
1589 {
1590         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1591
1592         if (!dev_drv->suspend_flag)
1593                 return 0;
1594
1595         rk_disp_pwr_enable(dev_drv);
1596         vop_clk_enable(vop_dev);
1597         vop_reg_restore(dev_drv);
1598         vop_standby_disable(vop_dev);
1599         vop_mmu_enable(dev_drv);
1600         dev_drv->suspend_flag = 0;
1601
1602         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1603                 dev_drv->trsm_ops->enable();
1604
1605         return 0;
1606 }
1607
1608 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
1609 {
1610         switch (blank_mode) {
1611         case FB_BLANK_UNBLANK:
1612                 vop_early_resume(dev_drv);
1613                 break;
1614         case FB_BLANK_NORMAL:
1615                 vop_early_suspend(dev_drv);
1616                 break;
1617         default:
1618                 vop_early_suspend(dev_drv);
1619                 break;
1620         }
1621
1622         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1623
1624         return 0;
1625 }
1626
1627 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
1628                              int win_id, int area_id)
1629 {
1630         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1631         u32 area_status = 0, state = 0;
1632
1633         spin_lock(&vop_dev->reg_lock);
1634         if (likely(vop_dev->clk_on)) {
1635                 switch (win_id) {
1636                 case 0:
1637                         area_status =
1638                                 vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
1639                         break;
1640                 case 1:
1641                         area_status =
1642                                 vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
1643                         break;
1644                 case 2:
1645                         area_status =
1646                                 vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
1647                         break;
1648                 default:
1649                         pr_err("%s: win[%d]area[%d],unsupport!!!\n",
1650                                __func__, win_id, area_id);
1651                         break;
1652                 }
1653         }
1654         spin_unlock(&vop_dev->reg_lock);
1655
1656         state = (area_status > 0) ? 1 : 0;
1657         return state;
1658 }
1659
1660 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
1661                             unsigned int *area_support)
1662 {
1663         area_support[0] = 1;
1664         area_support[1] = 1;
1665
1666         return 0;
1667 }
1668
1669 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
1670 {
1671         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1672         int ovl;
1673
1674         spin_lock(&vop_dev->reg_lock);
1675         if (likely(vop_dev->clk_on)) {
1676                 if (set) {
1677                         vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(swap));
1678                         ovl = swap;
1679                 } else {
1680                         ovl =
1681                             vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1682                 }
1683         } else {
1684                 ovl = -EPERM;
1685         }
1686         spin_unlock(&vop_dev->reg_lock);
1687
1688         return ovl;
1689 }
1690
1691 static char *vop_format_to_string(int format, char *fmt)
1692 {
1693         if (!fmt)
1694                 return NULL;
1695
1696         switch (format) {
1697         case 0:
1698                 strcpy(fmt, "ARGB888");
1699                 break;
1700         case 1:
1701                 strcpy(fmt, "RGB888");
1702                 break;
1703         case 2:
1704                 strcpy(fmt, "RGB565");
1705                 break;
1706         case 4:
1707                 strcpy(fmt, "YCbCr420");
1708                 break;
1709         case 5:
1710                 strcpy(fmt, "YCbCr422");
1711                 break;
1712         case 6:
1713                 strcpy(fmt, "YCbCr444");
1714                 break;
1715         default:
1716                 strcpy(fmt, "invalid\n");
1717                 break;
1718         }
1719         return fmt;
1720 }
1721
1722 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
1723                                  char *buf, int win_id)
1724 {
1725         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1726         struct rk_screen *screen = dev_drv->cur_screen;
1727         u16 hsync_len = screen->mode.hsync_len;
1728         u16 left_margin = screen->mode.left_margin;
1729         u16 vsync_len = screen->mode.vsync_len;
1730         u16 upper_margin = screen->mode.upper_margin;
1731         u32 h_pw_bp = hsync_len + left_margin;
1732         u32 v_pw_bp = vsync_len + upper_margin;
1733         u32 fmt_id;
1734         char format_w0[9] = "NULL";
1735         char format_w1[9] = "NULL";
1736         char dsp_buf[100];
1737         u32 win_ctrl, ovl, vir_info, act_info, dsp_info, dsp_st;
1738         u32 y_factor, uv_factor;
1739         u8 w0_state, w1_state;
1740
1741         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
1742         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
1743         u32 w1_vir_y, w1_dsp_x, w1_dsp_y;
1744         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
1745         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
1746
1747         u32 dclk_freq;
1748         int size = 0;
1749
1750         dclk_freq = screen->mode.pixclock;
1751         /*vop_reg_dump(dev_drv); */
1752
1753         spin_lock(&vop_dev->reg_lock);
1754         if (likely(vop_dev->clk_on)) {
1755                 ovl = vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1756                 /* WIN0 */
1757                 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
1758                 w0_state = win_ctrl & MASK(WIN0_EN);
1759                 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
1760                 vop_format_to_string(fmt_id, format_w0);
1761                 vir_info = vop_readl(vop_dev, WIN0_VIR);
1762                 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
1763                 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
1764                 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
1765                 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
1766                 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
1767                 w0_vir_y = vir_info & MASK(WIN0_YRGB_VIR_STRIDE);
1768                 w0_vir_uv = (vir_info & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
1769                 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
1770                 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1771                 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
1772                 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
1773                 if (w0_state) {
1774                         w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
1775                         w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
1776                 }
1777                 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
1778                 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
1779                 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
1780                 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
1781
1782                 /* WIN1 */
1783                 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
1784                 w1_state = win_ctrl & MASK(WIN1_EN);
1785                 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
1786                 vop_format_to_string(fmt_id, format_w1);
1787                 vir_info = vop_readl(vop_dev, WIN1_VIR);
1788                 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
1789                 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
1790                 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
1791                 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
1792                 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
1793                 if (w1_state) {
1794                         w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
1795                         w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
1796                 }
1797         } else {
1798                 spin_unlock(&vop_dev->reg_lock);
1799                 return -EPERM;
1800         }
1801         spin_unlock(&vop_dev->reg_lock);
1802         /* win0 */
1803         size += snprintf(dsp_buf, 80,
1804                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
1805                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
1806         strcat(buf, dsp_buf);
1807         memset(dsp_buf, 0, sizeof(dsp_buf));
1808
1809         size += snprintf(dsp_buf, 80,
1810                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
1811                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
1812         strcat(buf, dsp_buf);
1813         memset(dsp_buf, 0, sizeof(dsp_buf));
1814
1815         size += snprintf(dsp_buf, 80,
1816                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
1817                  w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
1818         strcat(buf, dsp_buf);
1819         memset(dsp_buf, 0, sizeof(dsp_buf));
1820
1821         size += snprintf(dsp_buf, 80,
1822                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
1823                  w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
1824                  vop_readl(vop_dev, WIN0_CBR_MST));
1825         strcat(buf, dsp_buf);
1826         memset(dsp_buf, 0, sizeof(dsp_buf));
1827
1828         /* win1 */
1829         size += snprintf(dsp_buf, 80,
1830                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d,",
1831                  w1_state, format_w1, w1_vir_y);
1832         strcat(buf, dsp_buf);
1833         memset(dsp_buf, 0, sizeof(dsp_buf));
1834
1835         size += snprintf(dsp_buf, 80,
1836                  " dsp_x   :%5d, dsp_y   :%5d\n",
1837                  w1_dsp_x, w1_dsp_y);
1838         strcat(buf, dsp_buf);
1839         memset(dsp_buf, 0, sizeof(dsp_buf));
1840
1841         size += snprintf(dsp_buf, 80,
1842                  "  x_st :%4d, y_st  :%4d, ",
1843                  w1_st_x - h_pw_bp, w1_st_y - v_pw_bp);
1844         strcat(buf, dsp_buf);
1845         memset(dsp_buf, 0, sizeof(dsp_buf));
1846
1847         size += snprintf(dsp_buf, 80,
1848                  "y_addr:0x%08x\n",
1849                  vop_readl(vop_dev, WIN1_YRGB_MST));
1850         strcat(buf, dsp_buf);
1851         memset(dsp_buf, 0, sizeof(dsp_buf));
1852
1853         /* zorder */
1854         size += snprintf(dsp_buf, 80,
1855                          ovl ? "win0 on the top of win1\n" :
1856                                 "win1 on the top of win0\n");
1857         strcat(buf, dsp_buf);
1858         memset(dsp_buf, 0, sizeof(dsp_buf));
1859
1860         return size;
1861 }
1862
1863 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
1864 {
1865         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1866         struct rk_screen *screen = dev_drv->cur_screen;
1867         u64 ft = 0;
1868         u32 dotclk;
1869         int ret;
1870         u32 pixclock;
1871         u32 x_total, y_total;
1872
1873         if (set) {
1874                 if (fps == 0) {
1875                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
1876                         return 0;
1877                 }
1878                 ft = div_u64(1000000000000llu, fps);
1879                 x_total =
1880                     screen->mode.upper_margin + screen->mode.lower_margin +
1881                     screen->mode.yres + screen->mode.vsync_len;
1882                 y_total =
1883                     screen->mode.left_margin + screen->mode.right_margin +
1884                     screen->mode.xres + screen->mode.hsync_len;
1885                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1886                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1887                 ret = clk_set_rate(vop_dev->dclk, dotclk);
1888         }
1889
1890         pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1891         vop_dev->pixclock = pixclock;
1892         dev_drv->pixclock = vop_dev->pixclock;
1893         fps = rk_fb_calc_fps(screen, pixclock);
1894         screen->ft = 1000 / fps;        /*one frame time in ms */
1895
1896         if (set)
1897                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1898                          clk_get_rate(vop_dev->dclk), fps);
1899
1900         return fps;
1901 }
1902
1903 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1904 {
1905         mutex_lock(&dev_drv->fb_win_id_mutex);
1906         if (order == FB_DEFAULT_ORDER)
1907                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
1908         dev_drv->fb4_win_id = order / 10000;
1909         dev_drv->fb3_win_id = (order / 1000) % 10;
1910         dev_drv->fb2_win_id = (order / 100) % 10;
1911         dev_drv->fb1_win_id = (order / 10) % 10;
1912         dev_drv->fb0_win_id = order % 10;
1913         mutex_unlock(&dev_drv->fb_win_id_mutex);
1914
1915         return 0;
1916 }
1917
1918 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
1919 {
1920         int win_id = 0;
1921
1922         mutex_lock(&dev_drv->fb_win_id_mutex);
1923         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
1924                 win_id = dev_drv->fb0_win_id;
1925         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
1926                 win_id = dev_drv->fb1_win_id;
1927         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
1928                 win_id = dev_drv->fb2_win_id;
1929         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
1930                 win_id = dev_drv->fb3_win_id;
1931         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
1932                 win_id = dev_drv->fb4_win_id;
1933         mutex_unlock(&dev_drv->fb_win_id_mutex);
1934
1935         return win_id;
1936 }
1937
1938 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
1939 {
1940         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1941         int i;
1942         struct rk_lcdc_win *win = NULL;
1943
1944         spin_lock(&vop_dev->reg_lock);
1945         if (likely(vop_dev->clk_on)) {
1946                 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1947                         win = dev_drv->win[i];
1948                         vop_layer_update_regs(vop_dev, win);
1949                 }
1950                 vop_cfg_done(vop_dev);
1951         }
1952         spin_unlock(&vop_dev->reg_lock);
1953
1954         return 0;
1955 }
1956
1957 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1958 {
1959         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1960
1961         spin_lock(&vop_dev->reg_lock);
1962         if (likely(vop_dev->clk_on)) {
1963                 vop_msk_reg(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(open));
1964                 vop_cfg_done(vop_dev);
1965         }
1966         spin_unlock(&vop_dev->reg_lock);
1967
1968         return 0;
1969 }
1970
1971 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1972 {
1973         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1974
1975         spin_lock(&vop_dev->reg_lock);
1976         if (likely(vop_dev->clk_on)) {
1977                 vop_msk_reg(vop_dev, SYS_CTRL0,
1978                             V_DIRECT_PATH_LAYER_SEL(win_id));
1979                 vop_cfg_done(vop_dev);
1980         }
1981         spin_unlock(&vop_dev->reg_lock);
1982         return 0;
1983 }
1984
1985 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
1986 {
1987         struct vop_device *vop_dev = to_vop_dev(dev_drv);
1988         int status;
1989
1990         spin_lock(&vop_dev->reg_lock);
1991
1992         if (likely(vop_dev->clk_on))
1993                 status = vop_read_bit(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(0));
1994
1995         spin_unlock(&vop_dev->reg_lock);
1996
1997         return status;
1998 }
1999
2000 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
2001 {
2002         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2003
2004         if (enable)
2005                 enable_irq(vop_dev->irq);
2006         else
2007                 disable_irq(vop_dev->irq);
2008         return 0;
2009 }
2010
2011 static int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
2012 {
2013         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2014         u32 int_reg;
2015         int ret;
2016
2017         if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
2018                 int_reg = vop_readl(vop_dev, INTR_STATUS);
2019                 if (int_reg & INTR_LINE_FLAG0) {
2020                         vop_dev->driver.frame_time.last_framedone_t =
2021                             vop_dev->driver.frame_time.framedone_t;
2022                         vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
2023                         vop_mask_writel(vop_dev, INTR_CLEAR, INTR_LINE_FLAG0,
2024                                         INTR_LINE_FLAG0);
2025                         ret = RK_LF_STATUS_FC;
2026                 } else {
2027                         ret = RK_LF_STATUS_FR;
2028                 }
2029         } else {
2030                 ret = RK_LF_STATUS_NC;
2031         }
2032
2033         return ret;
2034 }
2035
2036 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2037                             unsigned int dsp_addr[][4])
2038 {
2039         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2040
2041         spin_lock(&vop_dev->reg_lock);
2042         if (likely(vop_dev->clk_on)) {
2043                 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
2044                 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
2045                 dsp_addr[2][0] = vop_readl(vop_dev, HWC_MST);
2046         }
2047         spin_unlock(&vop_dev->reg_lock);
2048         return 0;
2049 }
2050
2051 /*
2052  * a:[-30~0]:
2053  *      sin_hue = sin(a)*256 +0x100;
2054  *      cos_hue = cos(a)*256;
2055  * a:[0~30]
2056  *      sin_hue = sin(a)*256;
2057  *      cos_hue = cos(a)*256;
2058  */
2059 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
2060 {
2061         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2062         u32 val = 0;
2063
2064         spin_lock(&vop_dev->reg_lock);
2065         if (likely(vop_dev->clk_on)) {
2066                 val = vop_readl(vop_dev, BCSH_H);
2067                 switch (mode) {
2068                 case H_SIN:
2069                         val &= MASK(SIN_HUE);
2070                         val <<= 1;
2071                         break;
2072                 case H_COS:
2073                         val &= MASK(COS_HUE);
2074                         val >>= 8;
2075                         val <<= 1;
2076                         break;
2077                 default:
2078                         break;
2079                 }
2080         }
2081         spin_unlock(&vop_dev->reg_lock);
2082
2083         return val;
2084 }
2085
2086 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
2087                             int sin_hue, int cos_hue)
2088 {
2089         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2090         u64 val;
2091
2092         spin_lock(&vop_dev->reg_lock);
2093         if (likely(vop_dev->clk_on)) {
2094                 /*
2095                  * config range is [0, 510), typical value is 256
2096                  * register range is [0, 255], cos_hue typical value is 128
2097                  * sin_hue typical value is 0
2098                  */
2099                 val = V_SIN_HUE(sin_hue >> 1) | V_COS_HUE(cos_hue >> 1);
2100                 vop_msk_reg(vop_dev, BCSH_H, val);
2101                 vop_cfg_done(vop_dev);
2102         }
2103         spin_unlock(&vop_dev->reg_lock);
2104
2105         return 0;
2106 }
2107
2108 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2109                             bcsh_bcs_mode mode, int value)
2110 {
2111         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2112         u64 val = 0;
2113
2114         spin_lock(&vop_dev->reg_lock);
2115         if (likely(vop_dev->clk_on)) {
2116                 switch (mode) {
2117                 case BRIGHTNESS:
2118                         /*
2119                          * user range is [0, 255], typical value is 128
2120                          * register range is [-32, 31], typical value is 0
2121                          */
2122                         value >>= 2; /* 0-->32-->63 for user, typical is 32 */
2123                         if (value < 0x20)
2124                                 value += 0x20;
2125                         else if (value >= 0x20)
2126                                 value = value - 0x20;
2127                         val = V_BRIGHTNESS(value);
2128                         break;
2129                 case CONTRAST:
2130                         /*
2131                          * config range is [0, 510), typical value is 256
2132                          * register range is [0, 255], typical value is 128
2133                          */
2134                         value >>= 1;
2135                         val = V_CONTRAST(value);
2136                         break;
2137                 case SAT_CON:
2138                         /*
2139                          * config range is [0, 1015], typical value is 512
2140                          * register range is [0, 255], typical value is 128
2141                          */
2142                         value >>= 2;
2143                         val = V_SAT_CON(value);
2144                         break;
2145                 default:
2146                         break;
2147                 }
2148                 vop_msk_reg(vop_dev, BCSH_BCS, val);
2149                 vop_cfg_done(vop_dev);
2150         }
2151         spin_unlock(&vop_dev->reg_lock);
2152
2153         return val;
2154 }
2155
2156 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
2157 {
2158         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2159         u64 val = 0;
2160
2161         spin_lock(&vop_dev->reg_lock);
2162         if (likely(vop_dev->clk_on)) {
2163                 val = vop_readl(vop_dev, BCSH_BCS);
2164                 switch (mode) {
2165                 case BRIGHTNESS:
2166                         val &= MASK(BRIGHTNESS);
2167                         if (val >= 0x20)
2168                                 val -= 0x20;
2169                         else
2170                                 val += 0x20;
2171                         val <<= 2;
2172                         break;
2173                 case CONTRAST:
2174                         val &= MASK(CONTRAST);
2175                         val >>= 8;
2176                         val <<= 1;
2177                         break;
2178                 case SAT_CON:
2179                         val &= MASK(SAT_CON);
2180                         val >>= 16;
2181                         val <<= 2;
2182                         break;
2183                 default:
2184                         break;
2185                 }
2186         }
2187         spin_unlock(&vop_dev->reg_lock);
2188         return val;
2189 }
2190
2191 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2192 {
2193         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2194
2195         spin_lock(&vop_dev->reg_lock);
2196         if (likely(vop_dev->clk_on)) {
2197                 if (open) {
2198                         vop_writel(vop_dev, BCSH_BCS,
2199                                    V_BRIGHTNESS(0x00) | V_CONTRAST(0x80) |
2200                                    V_SAT_CON(0x80));
2201                         vop_writel(vop_dev, BCSH_H,
2202                                    V_SIN_HUE(0x00) | V_COS_HUE(0x80));
2203                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(1) |
2204                                     V_VIDEO_MODE(BCSH_MODE_VIDEO));
2205                         dev_drv->bcsh.enable = 1;
2206                 } else {
2207                         vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(0));
2208                         dev_drv->bcsh.enable = 0;
2209                 }
2210                 vop_bcsh_path_sel(dev_drv);
2211                 vop_cfg_done(vop_dev);
2212         }
2213         spin_unlock(&vop_dev->reg_lock);
2214
2215         return 0;
2216 }
2217
2218 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
2219 {
2220         if (!enable || !dev_drv->bcsh.enable) {
2221                 vop_open_bcsh(dev_drv, false);
2222                 return 0;
2223         }
2224
2225         if (dev_drv->bcsh.brightness <= 255 ||
2226             dev_drv->bcsh.contrast < 510 ||
2227             dev_drv->bcsh.sat_con <= 1015 ||
2228             (dev_drv->bcsh.sin_hue < 510 && dev_drv->bcsh.cos_hue < 510)) {
2229                 vop_open_bcsh(dev_drv, true);
2230                 if (dev_drv->bcsh.brightness <= 255)
2231                         vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
2232                                          dev_drv->bcsh.brightness);
2233                 if (dev_drv->bcsh.contrast < 510)
2234                         vop_set_bcsh_bcs(dev_drv, CONTRAST,
2235                                          dev_drv->bcsh.contrast);
2236                 if (dev_drv->bcsh.sat_con <= 1015)
2237                         vop_set_bcsh_bcs(dev_drv, SAT_CON,
2238                                          dev_drv->bcsh.sat_con);
2239                 if (dev_drv->bcsh.sin_hue < 510 &&
2240                     dev_drv->bcsh.cos_hue < 510)
2241                         vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
2242                                          dev_drv->bcsh.cos_hue);
2243         }
2244
2245         return 0;
2246 }
2247
2248 static int __maybe_unused
2249 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2250 {
2251         struct vop_device *vop_dev = to_vop_dev(dev_drv);
2252
2253         if (enable) {
2254                 spin_lock(&vop_dev->reg_lock);
2255                 if (likely(vop_dev->clk_on)) {
2256                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
2257                         vop_cfg_done(vop_dev);
2258                 }
2259                 spin_unlock(&vop_dev->reg_lock);
2260         } else {
2261                 spin_lock(&vop_dev->reg_lock);
2262                 if (likely(vop_dev->clk_on)) {
2263                         vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
2264                         vop_cfg_done(vop_dev);
2265                 }
2266                 spin_unlock(&vop_dev->reg_lock);
2267         }
2268
2269         return 0;
2270 }
2271
2272 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2273         .open = vop_open,
2274         .win_direct_en = vop_win_direct_en,
2275         .load_screen = vop_load_screen,
2276         .get_dspbuf_info = vop_get_dspbuf_info,
2277         .post_dspbuf = vop_post_dspbuf,
2278         .set_par = vop_set_par,
2279         .pan_display = vop_pan_display,
2280         .direct_set_addr = vop_direct_set_win_addr,
2281         .blank = vop_blank,
2282         .ioctl = vop_ioctl,
2283         .suspend = vop_early_suspend,
2284         .resume = vop_early_resume,
2285         .get_win_state = vop_get_win_state,
2286         .area_support_num = vop_get_area_num,
2287         .ovl_mgr = vop_ovl_mgr,
2288         .get_disp_info = vop_get_disp_info,
2289         .fps_mgr = vop_fps_mgr,
2290         .fb_get_win_id = vop_get_win_id,
2291         .fb_win_remap = vop_fb_win_remap,
2292         .poll_vblank = vop_poll_vblank,
2293         .dpi_open = vop_dpi_open,
2294         .dpi_win_sel = vop_dpi_win_sel,
2295         .dpi_status = vop_dpi_status,
2296         .get_dsp_addr = vop_get_dsp_addr,
2297         .set_dsp_bcsh_hue = vop_set_bcsh_hue,
2298         .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
2299         .get_dsp_bcsh_hue = vop_get_bcsh_hue,
2300         .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
2301         .open_bcsh = vop_open_bcsh,
2302         .set_dsp_lut = vop_set_lut,
2303         .set_hwc_lut = vop_set_hwc_lut,
2304         .dump_reg = vop_reg_dump,
2305         .cfg_done = vop_config_done,
2306         .set_irq_to_cpu = vop_set_irq_to_cpu,
2307         /*.dsp_black = vop_dsp_black,*/
2308         .backlight_close = vop_backlight_close,
2309         .mmu_en = vop_mmu_enable,
2310 };
2311
2312 static irqreturn_t vop_isr(int irq, void *dev_id)
2313 {
2314         struct vop_device *vop_dev = (struct vop_device *)dev_id;
2315         ktime_t timestamp = ktime_get();
2316         u32 intr_status;
2317         unsigned long flags;
2318
2319         spin_lock_irqsave(&vop_dev->irq_lock, flags);
2320
2321         intr_status = vop_readl(vop_dev, INTR_STATUS);
2322         vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, intr_status);
2323
2324         spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
2325
2326         intr_status &= 0xffff;  /* ignore raw status at 16~32bit */
2327         /* This is expected for vop iommu irqs, since the irq is shared */
2328         if (!intr_status)
2329                 return IRQ_NONE;
2330
2331         if (intr_status & INTR_FS0) {
2332                 timestamp = ktime_get();
2333                 vop_dev->driver.vsync_info.timestamp = timestamp;
2334                 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
2335                 complete(&vop_dev->sync.frmst);
2336                 intr_status &= ~INTR_FS0;
2337         }
2338
2339         /* fs1 interrupt occur only when the address is different */
2340         if (intr_status & INTR_FS1)
2341                 intr_status &= ~INTR_FS1;
2342
2343         if (intr_status & INTR_ADDR_SAME)
2344                 intr_status &= ~INTR_ADDR_SAME;
2345
2346         if (intr_status & INTR_DSP_HOLD_VALID) {
2347                 complete(&vop_dev->sync.stdbyfin);
2348                 intr_status &= ~INTR_DSP_HOLD_VALID;
2349         }
2350
2351         if (intr_status & INTR_LINE_FLAG0)
2352                 intr_status &= ~INTR_LINE_FLAG0;
2353
2354         if (intr_status & INTR_LINE_FLAG1)
2355                 intr_status &= ~INTR_LINE_FLAG1;
2356
2357         if (intr_status & INTR_BUS_ERROR) {
2358                 intr_status &= ~INTR_BUS_ERROR;
2359                 dev_warn_ratelimited(vop_dev->dev, "bus error!");
2360         }
2361
2362         if (intr_status & INTR_WIN0_EMPTY) {
2363                 intr_status &= ~INTR_WIN0_EMPTY;
2364                 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
2365         }
2366
2367         if (intr_status & INTR_WIN1_EMPTY) {
2368                 intr_status &= ~INTR_WIN1_EMPTY;
2369                 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
2370         }
2371
2372         if (intr_status & INTR_DMA_FINISH)
2373                 intr_status &= ~INTR_DMA_FINISH;
2374
2375         if (intr_status & INTR_MMU_STATUS)
2376                 intr_status &= ~INTR_MMU_STATUS;
2377
2378         if (intr_status)
2379                 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
2380
2381         return IRQ_HANDLED;
2382 }
2383
2384 #if defined(CONFIG_PM)
2385 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
2386 {
2387         return 0;
2388 }
2389
2390 static int vop_resume(struct platform_device *pdev)
2391 {
2392         return 0;
2393 }
2394 #else
2395 #define vop_suspend NULL
2396 #define vop_resume  NULL
2397 #endif
2398
2399 static int vop_parse_dt(struct vop_device *vop_dev)
2400 {
2401         struct device_node *np = vop_dev->dev->of_node;
2402         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2403         int val;
2404
2405         if (of_property_read_u32(np, "rockchip,prop", &val))
2406                 vop_dev->prop = PRMRY;  /*default set it as primary */
2407         else
2408                 vop_dev->prop = val;
2409
2410         if (of_property_read_u32(np, "rockchip,mirror", &val))
2411                 dev_drv->rotate_mode = NO_MIRROR;
2412         else
2413                 dev_drv->rotate_mode = val;
2414
2415         if (of_property_read_u32(np, "rockchip,pwr18", &val))
2416                 /*default set it as 3.xv power supply */
2417                 vop_dev->pwr18 = false;
2418         else
2419                 vop_dev->pwr18 = (val ? true : false);
2420
2421         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2422                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
2423         else
2424                 dev_drv->fb_win_map = val;
2425
2426         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
2427                 dev_drv->bcsh.enable = false;
2428         else
2429                 dev_drv->bcsh.enable = (val ? true : false);
2430
2431         if (of_property_read_u32(np, "rockchip,brightness", &val))
2432                 dev_drv->bcsh.brightness = 0xffff;
2433         else
2434                 dev_drv->bcsh.brightness = val;
2435
2436         if (of_property_read_u32(np, "rockchip,contrast", &val))
2437                 dev_drv->bcsh.contrast = 0xffff;
2438         else
2439                 dev_drv->bcsh.contrast = val;
2440
2441         if (of_property_read_u32(np, "rockchip,sat-con", &val))
2442                 dev_drv->bcsh.sat_con = 0xffff;
2443         else
2444                 dev_drv->bcsh.sat_con = val;
2445
2446         if (of_property_read_u32(np, "rockchip,hue", &val)) {
2447                 dev_drv->bcsh.sin_hue = 0xffff;
2448                 dev_drv->bcsh.cos_hue = 0xffff;
2449         } else {
2450                 dev_drv->bcsh.sin_hue = val & 0xff;
2451                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
2452         }
2453
2454         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2455                 dev_drv->iommu_enabled = 0;
2456         else
2457                 dev_drv->iommu_enabled = val;
2458
2459         return 0;
2460 }
2461
2462 static int vop_probe(struct platform_device *pdev)
2463 {
2464         struct vop_device *vop_dev = NULL;
2465         struct rk_lcdc_driver *dev_drv;
2466         struct device *dev = &pdev->dev;
2467         struct resource *res;
2468         struct device_node *np = pdev->dev.of_node;
2469         int prop;
2470         int ret = 0;
2471
2472         /*
2473          * if the primary lcdc has not registered ,the extend
2474          * lcdc register later
2475          */
2476         of_property_read_u32(np, "rockchip,prop", &prop);
2477         if (prop == EXTEND) {
2478                 if (!is_prmry_rk_lcdc_registered())
2479                         return -EPROBE_DEFER;
2480         }
2481
2482         vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
2483         if (!vop_dev)
2484                 return -ENOMEM;
2485
2486         platform_set_drvdata(pdev, vop_dev);
2487         vop_dev->dev = dev;
2488         vop_parse_dt(vop_dev);
2489
2490         /* enable power domain */
2491         pm_runtime_enable(dev);
2492
2493         vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc");
2494         if (IS_ERR(vop_dev->hclk)) {
2495                 dev_err(vop_dev->dev, "failed to get hclk source\n");
2496                 return PTR_ERR(vop_dev->hclk);
2497         }
2498
2499         vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc");
2500         if (IS_ERR(vop_dev->aclk)) {
2501                 dev_err(vop_dev->dev, "failed to get aclk source\n");
2502                 return PTR_ERR(vop_dev->aclk);
2503         }
2504         vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc");
2505         if (IS_ERR(vop_dev->dclk)) {
2506                 dev_err(vop_dev->dev, "failed to get dclk source\n");
2507                 return PTR_ERR(vop_dev->dclk);
2508         }
2509
2510         clk_prepare(vop_dev->hclk);
2511         clk_prepare(vop_dev->aclk);
2512         clk_prepare(vop_dev->dclk);
2513
2514         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2515         vop_dev->regs = devm_ioremap_resource(dev, res);
2516         if (IS_ERR(vop_dev->regs)) {
2517                 ret = PTR_ERR(vop_dev->regs);
2518                 goto err_exit;
2519         }
2520
2521         vop_dev->reg_phy_base = res->start;
2522         vop_dev->len = resource_size(res);
2523         vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
2524         if (!vop_dev->regsbak) {
2525                 ret = -ENOMEM;
2526                 goto err_exit;
2527         }
2528
2529         vop_dev->hwc_lut_addr_base = (vop_dev->regs + HWC_LUT_ADDR);
2530         vop_dev->dsp_lut_addr_base = (vop_dev->regs + GAMMA_LUT_ADDR);
2531         vop_dev->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
2532         if (IS_ERR(vop_dev->grf_base)) {
2533                 dev_err(vop_dev->dev, "ERROR!! can't find grf reg property\n");
2534                 vop_dev->grf_base = NULL;
2535         }
2536
2537         vop_dev->id = 1;
2538         dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
2539         dev_drv = &vop_dev->driver;
2540         dev_drv->dev = dev;
2541         dev_drv->prop = prop;
2542         dev_drv->id = vop_dev->id;
2543         dev_drv->ops = &lcdc_drv_ops;
2544         dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win);
2545         dev_drv->reserved_fb = 0;
2546         spin_lock_init(&vop_dev->reg_lock);
2547         spin_lock_init(&vop_dev->irq_lock);
2548         init_completion(&vop_dev->sync.stdbyfin);
2549         init_completion(&vop_dev->sync.frmst);
2550         vop_dev->sync.stdbyfin_to = 50; /* timeout 50 ms */
2551         vop_dev->sync.frmst_to = 50;
2552
2553         vop_dev->irq = platform_get_irq(pdev, 0);
2554         if (vop_dev->irq < 0) {
2555                 dev_err(dev, "cannot find IRQ for lcdc%d\n", vop_dev->id);
2556                 ret = vop_dev->irq;
2557                 goto err_exit;
2558         }
2559
2560         ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
2561                                IRQF_SHARED,
2562                                dev_name(dev), vop_dev);
2563         if (ret) {
2564                 dev_err(dev, "cannot requeset irq %d - err %d\n",
2565                         vop_dev->irq, ret);
2566                 goto err_exit;
2567         }
2568
2569         if (dev_drv->iommu_enabled)
2570                 strcpy(dev_drv->mmu_dts_name, VOPL_IOMMU_COMPATIBLE_NAME);
2571
2572         ret = rk_fb_register(dev_drv, vop_win, vop_dev->id);
2573         if (ret < 0) {
2574                 dev_err(dev, "register fb for failed!\n");
2575                 goto err_exit;
2576         }
2577         vop_dev->screen = dev_drv->screen0;
2578         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2579                  vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2580
2581         return 0;
2582
2583 err_exit:
2584         clk_unprepare(vop_dev->dclk);
2585         clk_unprepare(vop_dev->aclk);
2586         clk_unprepare(vop_dev->hclk);
2587         pm_runtime_disable(dev);
2588
2589         return ret;
2590 }
2591
2592 static int vop_remove(struct platform_device *pdev)
2593 {
2594         return 0;
2595 }
2596
2597 static void vop_shutdown(struct platform_device *pdev)
2598 {
2599         struct vop_device *vop_dev = platform_get_drvdata(pdev);
2600         struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2601
2602         dev_drv->suspend_flag = 1;
2603         smp_wmb();
2604         flush_kthread_worker(&dev_drv->update_regs_worker);
2605         kthread_stop(dev_drv->update_regs_thread);
2606
2607         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2608                 dev_drv->trsm_ops->disable();
2609
2610         vop_deinit(vop_dev);
2611         rk_disp_pwr_disable(dev_drv);
2612 }
2613
2614 #if defined(CONFIG_OF)
2615 static const struct of_device_id vop_dt_ids[] = {
2616         {.compatible = "rockchip,rk3366-lcdc-lite",},
2617         {}
2618 };
2619 #endif
2620
2621 static struct platform_driver vop_driver = {
2622         .probe = vop_probe,
2623         .remove = vop_remove,
2624         .driver = {
2625                    .name = "rk-vop-lite",
2626                    .owner = THIS_MODULE,
2627                    .of_match_table = of_match_ptr(vop_dt_ids),
2628                    },
2629         .suspend = vop_suspend,
2630         .resume = vop_resume,
2631         .shutdown = vop_shutdown,
2632 };
2633
2634 static int __init vop_module_init(void)
2635 {
2636         return platform_driver_register(&vop_driver);
2637 }
2638
2639 static void __exit vop_module_exit(void)
2640 {
2641         platform_driver_unregister(&vop_driver);
2642 }
2643
2644 fs_initcall(vop_module_init);
2645 module_exit(vop_module_exit);