rk3368 vop: cabc lut update only when cabc enable
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3368_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3368_lcdc.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *Author:hjc<hjc@rock-chips.com>
6  *This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <linux/rockchip-iovmm.h>
30 #include <asm/div64.h>
31 #include <linux/uaccess.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37
38 #include "rk3368_lcdc.h"
39
40 #if defined(CONFIG_HAS_EARLYSUSPEND)
41 #include <linux/earlysuspend.h>
42 #endif
43 /*#define CONFIG_RK_FPGA 1*/
44
45 static int dbg_thresd;
46 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
47
48 #define DBG(level, x...) do {                   \
49         if (unlikely(dbg_thresd >= level))      \
50                 pr_info(x);\
51         } while (0)
52
53 static struct rk_lcdc_win lcdc_win[] = {
54         [0] = {
55                .name = "win0",
56                .id = 0,
57                .support_3d = false,
58                },
59         [1] = {
60                .name = "win1",
61                .id = 1,
62                .support_3d = false,
63                },
64         [2] = {
65                .name = "win2",
66                .id = 2,
67                .support_3d = false,
68                },
69         [3] = {
70                .name = "win3",
71                .id = 3,
72                .support_3d = false,
73                },
74         [4] = {
75                .name = "hwc",
76                .id = 4,
77                .support_3d = false,
78                }
79 };
80
81 static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
82
83 /*#define WAIT_FOR_SYNC 1*/
84 u32 rk3368_get_hard_ware_vskiplines(u32 srch, u32 dsth)
85 {
86         u32 vscalednmult;
87
88         if (srch >= (u32) (4 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
89                 vscalednmult = 4;
90         else if (srch >= (u32) (2 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
91                 vscalednmult = 2;
92         else
93                 vscalednmult = 1;
94
95         return vscalednmult;
96 }
97
98
99 static int rk3368_set_cabc_lut(struct rk_lcdc_driver *dev_drv, int *cabc_lut)
100 {
101         int i;
102         int __iomem *c;
103         u32 v;
104         struct lcdc_device *lcdc_dev =
105             container_of(dev_drv, struct lcdc_device, driver);
106
107         lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
108                      v_CABC_LUT_EN(0));
109         lcdc_cfg_done(lcdc_dev);
110         mdelay(25);
111         for (i = 0; i < 256; i++) {
112                 v = cabc_lut[i];
113                 c = lcdc_dev->cabc_lut_addr_base + i;
114                 writel_relaxed(v, c);
115         }
116         lcdc_msk_reg(lcdc_dev, CABC_CTRL1, m_CABC_LUT_EN,
117                      v_CABC_LUT_EN(1));
118         return 0;
119 }
120
121
122 static int rk3368_lcdc_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
123 {
124         int i;
125         int __iomem *c;
126         u32 v;
127         struct lcdc_device *lcdc_dev =
128             container_of(dev_drv, struct lcdc_device, driver);
129
130         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
131                      v_DSP_LUT_EN(0));
132         lcdc_cfg_done(lcdc_dev);
133         mdelay(25);
134         for (i = 0; i < 256; i++) {
135                 v = dsp_lut[i];
136                 c = lcdc_dev->dsp_lut_addr_base + i;
137                 writel_relaxed(v, c);
138         }
139         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
140                      v_DSP_LUT_EN(1));
141
142         return 0;
143 }
144
145 static int rk3368_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
146 {
147 #ifdef CONFIG_RK_FPGA
148         lcdc_dev->clk_on = 1;
149         return 0;
150 #endif
151         if (!lcdc_dev->clk_on) {
152                 clk_prepare_enable(lcdc_dev->hclk);
153                 clk_prepare_enable(lcdc_dev->dclk);
154                 clk_prepare_enable(lcdc_dev->aclk);
155                 clk_prepare_enable(lcdc_dev->pd);
156                 spin_lock(&lcdc_dev->reg_lock);
157                 lcdc_dev->clk_on = 1;
158                 spin_unlock(&lcdc_dev->reg_lock);
159         }
160
161         return 0;
162 }
163
164 static int rk3368_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
165 {
166 #ifdef CONFIG_RK_FPGA
167         lcdc_dev->clk_on = 0;
168         return 0;
169 #endif
170         if (lcdc_dev->clk_on) {
171                 spin_lock(&lcdc_dev->reg_lock);
172                 lcdc_dev->clk_on = 0;
173                 spin_unlock(&lcdc_dev->reg_lock);
174                 mdelay(25);
175                 clk_disable_unprepare(lcdc_dev->dclk);
176                 clk_disable_unprepare(lcdc_dev->hclk);
177                 clk_disable_unprepare(lcdc_dev->aclk);
178                 clk_disable_unprepare(lcdc_dev->pd);
179         }
180
181         return 0;
182 }
183
184 static int __maybe_unused
185         rk3368_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
186 {
187         u32 mask, val;
188
189         spin_lock(&lcdc_dev->reg_lock);
190         if (likely(lcdc_dev->clk_on)) {
191                 mask = m_FS_INTR_EN | m_FS_NEW_INTR_EN |
192                     m_ADDR_SAME_INTR_EN | m_LINE_FLAG0_INTR_EN |
193                     m_LINE_FLAG1_INTR_EN | m_BUS_ERROR_INTR_EN |
194                     m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
195                     m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
196                     m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
197                     m_PWM_GEN_INTR_EN | m_DSP_HOLD_VALID_INTR_EN;
198                 val = v_FS_INTR_EN(0) | v_FS_NEW_INTR_EN(0) |
199                     v_ADDR_SAME_INTR_EN(0) |
200                     v_LINE_FLAG0_INTR_EN(0) | v_LINE_FLAG1_INTR_EN(0) |
201                     v_BUS_ERROR_INTR_EN(0) | v_WIN0_EMPTY_INTR_EN(0) |
202                     v_WIN1_EMPTY_INTR_EN(0) | v_WIN2_EMPTY_INTR_EN(0) |
203                     v_WIN3_EMPTY_INTR_EN(0) | v_HWC_EMPTY_INTR_EN(0) |
204                     v_POST_BUF_EMPTY_INTR_EN(0) |
205                     v_PWM_GEN_INTR_EN(0) | v_DSP_HOLD_VALID_INTR_EN(0);
206                 lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
207
208                 mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR |
209                     m_ADDR_SAME_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
210                     m_LINE_FLAG1_INTR_CLR | m_BUS_ERROR_INTR_CLR |
211                     m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
212                     m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
213                     m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
214                     m_PWM_GEN_INTR_CLR | m_DSP_HOLD_VALID_INTR_CLR;
215                 val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
216                     v_ADDR_SAME_INTR_CLR(1) |
217                     v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1) |
218                     v_BUS_ERROR_INTR_CLR(1) | v_WIN0_EMPTY_INTR_CLR(1) |
219                     v_WIN1_EMPTY_INTR_CLR(1) | v_WIN2_EMPTY_INTR_CLR(1) |
220                     v_WIN3_EMPTY_INTR_CLR(1) | v_HWC_EMPTY_INTR_CLR(1) |
221                     v_POST_BUF_EMPTY_INTR_CLR(1) |
222                     v_PWM_GEN_INTR_CLR(1) | v_DSP_HOLD_VALID_INTR_CLR(1);
223                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
224                 lcdc_cfg_done(lcdc_dev);
225                 spin_unlock(&lcdc_dev->reg_lock);
226         } else {
227                 spin_unlock(&lcdc_dev->reg_lock);
228         }
229         mdelay(1);
230         return 0;
231 }
232
233 static int rk3368_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
234 {
235         struct lcdc_device *lcdc_dev =
236             container_of(dev_drv, struct lcdc_device, driver);
237         int *cbase = (int *)lcdc_dev->regs;
238         int *regsbak = (int *)lcdc_dev->regsbak;
239         int i, j, val;
240         char dbg_message[30];
241         char buf[10];
242
243         pr_info("lcd 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  ", *(regsbak + i * 4 + j));
250                         strcat(dbg_message, buf);
251                 }
252                 pr_info("%s\n", dbg_message);
253                 memset(dbg_message, 0, sizeof(dbg_message));
254                 memset(buf, 0, sizeof(buf));
255         }
256
257         pr_info("lcdc reg:\n");
258         for (i = 0; i <= (0x200 >> 4); i++) {
259                 val = sprintf(dbg_message, "0x%04x: ", i * 16);
260                 for (j = 0; j < 4; j++) {
261                         sprintf(buf, "%08x  ",
262                                 readl_relaxed(cbase + i * 4 + j));
263                         strcat(dbg_message, buf);
264                 }
265                 pr_info("%s\n", dbg_message);
266                 memset(dbg_message, 0, sizeof(dbg_message));
267                 memset(buf, 0, sizeof(buf));
268         }
269
270         return 0;
271 }
272
273 #define WIN_EN(id)              \
274 static int win##id##_enable(struct lcdc_device *lcdc_dev, int en)       \
275 { \
276         u32 msk, val;                                                   \
277         spin_lock(&lcdc_dev->reg_lock);                                 \
278         msk =  m_WIN##id##_EN;                                          \
279         val  =  v_WIN##id##_EN(en);                                     \
280         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);              \
281         lcdc_cfg_done(lcdc_dev);                                        \
282         val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);            \
283         while (val !=  (!!en))  {                                       \
284                 val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);    \
285         }                                                               \
286         spin_unlock(&lcdc_dev->reg_lock);                               \
287         return 0;                                                       \
288 }
289
290 WIN_EN(0);
291 WIN_EN(1);
292 WIN_EN(2);
293 WIN_EN(3);
294 /*enable/disable win directly*/
295 static int rk3368_lcdc_win_direct_en(struct rk_lcdc_driver *drv,
296                                      int win_id, int en)
297 {
298         struct lcdc_device *lcdc_dev =
299             container_of(drv, struct lcdc_device, driver);
300         if (win_id == 0)
301                 win0_enable(lcdc_dev, en);
302         else if (win_id == 1)
303                 win1_enable(lcdc_dev, en);
304         else if (win_id == 2)
305                 win2_enable(lcdc_dev, en);
306         else if (win_id == 3)
307                 win3_enable(lcdc_dev, en);
308         else
309                 dev_err(lcdc_dev->dev, "invalid win number:%d\n", win_id);
310         return 0;
311 }
312
313 #define SET_WIN_ADDR(id) \
314 static int set_win##id##_addr(struct lcdc_device *lcdc_dev, u32 addr) \
315 {                                                       \
316         u32 msk, val;                                   \
317         spin_lock(&lcdc_dev->reg_lock);                 \
318         lcdc_writel(lcdc_dev, WIN##id##_YRGB_MST, addr);        \
319         msk =  m_WIN##id##_EN;                          \
320         val  =  v_WIN0_EN(1);                           \
321         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);      \
322         lcdc_cfg_done(lcdc_dev);                        \
323         spin_unlock(&lcdc_dev->reg_lock);               \
324         return 0;                                       \
325 }
326
327 SET_WIN_ADDR(0);
328 SET_WIN_ADDR(1);
329 int rk3368_lcdc_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
330                                     int win_id, u32 addr)
331 {
332         struct lcdc_device *lcdc_dev =
333             container_of(dev_drv, struct lcdc_device, driver);
334         if (win_id == 0)
335                 set_win0_addr(lcdc_dev, addr);
336         else
337                 set_win1_addr(lcdc_dev, addr);
338
339         return 0;
340 }
341
342 static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
343 {
344         int reg = 0;
345         u32 val = 0;
346         struct rk_screen *screen = lcdc_dev->driver.cur_screen;
347         u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
348         u32 v_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
349         u32 st_x, st_y;
350         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
351
352         spin_lock(&lcdc_dev->reg_lock);
353         for (reg = 0; reg < SCAN_LINE_NUM; reg += 4) {
354                 val = lcdc_readl_backup(lcdc_dev, reg);
355                 switch (reg) {
356                 case WIN0_ACT_INFO:
357                         win0->area[0].xact = (val & m_WIN0_ACT_WIDTH) + 1;
358                         win0->area[0].yact =
359                             ((val & m_WIN0_ACT_HEIGHT) >> 16) + 1;
360                         break;
361                 case WIN0_DSP_INFO:
362                         win0->area[0].xsize = (val & m_WIN0_DSP_WIDTH) + 1;
363                         win0->area[0].ysize =
364                             ((val & m_WIN0_DSP_HEIGHT) >> 16) + 1;
365                         break;
366                 case WIN0_DSP_ST:
367                         st_x = val & m_WIN0_DSP_XST;
368                         st_y = (val & m_WIN0_DSP_YST) >> 16;
369                         win0->area[0].xpos = st_x - h_pw_bp;
370                         win0->area[0].ypos = st_y - v_pw_bp;
371                         break;
372                 case WIN0_CTRL0:
373                         win0->state = val & m_WIN0_EN;
374                         win0->area[0].fmt_cfg = (val & m_WIN0_DATA_FMT) >> 1;
375                         win0->fmt_10 = (val & m_WIN0_FMT_10) >> 4;
376                         win0->area[0].format = win0->area[0].fmt_cfg;
377                         break;
378                 case WIN0_VIR:
379                         win0->area[0].y_vir_stride = val & m_WIN0_VIR_STRIDE;
380                         win0->area[0].uv_vir_stride =
381                             (val & m_WIN0_VIR_STRIDE_UV) >> 16;
382                         if (win0->area[0].format == ARGB888)
383                                 win0->area[0].xvir = win0->area[0].y_vir_stride;
384                         else if (win0->area[0].format == RGB888)
385                                 win0->area[0].xvir =
386                                     win0->area[0].y_vir_stride * 4 / 3;
387                         else if (win0->area[0].format == RGB565)
388                                 win0->area[0].xvir =
389                                     2 * win0->area[0].y_vir_stride;
390                         else    /* YUV */
391                                 win0->area[0].xvir =
392                                     4 * win0->area[0].y_vir_stride;
393                         break;
394                 case WIN0_YRGB_MST:
395                         win0->area[0].smem_start = val;
396                         break;
397                 case WIN0_CBR_MST:
398                         win0->area[0].cbr_start = val;
399                         break;
400                 default:
401                         break;
402                 }
403         }
404         spin_unlock(&lcdc_dev->reg_lock);
405 }
406
407 /********do basic init*********/
408 static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
409 {
410         u32 mask, val, v;
411         struct lcdc_device *lcdc_dev =
412             container_of(dev_drv, struct lcdc_device, driver);
413         if (lcdc_dev->pre_init)
414                 return 0;
415
416         lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
417         lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
418         lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
419         lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
420
421         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
422             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
423                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
424                         lcdc_dev->id);
425         }
426         if (!support_uboot_display())
427                 rk_disp_pwr_enable(dev_drv);
428         rk3368_lcdc_clk_enable(lcdc_dev);
429
430         /*backup reg config at uboot */
431         lcdc_read_reg_defalut_cfg(lcdc_dev);
432         if (lcdc_dev->pwr18 == 1) {
433                 v = 0x00200020; /*bit5: 1,1.8v;0,3.3v*/
434                 lcdc_grf_writel(lcdc_dev->pmugrf_base,
435                                 PMUGRF_SOC_CON0_VOP, v);
436         } else {
437                 v = 0x00200000; /*bit5: 1,1.8v;0,3.3v*/
438                 lcdc_grf_writel(lcdc_dev->pmugrf_base,
439                                 PMUGRF_SOC_CON0_VOP, v);
440         }
441 #if 0
442         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x15110903);
443         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x00030911);
444         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x1a150b04);
445         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x00040b15);
446         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x15110903);
447         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x00030911);
448 #else
449         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x40000000);
450         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x0);
451         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x80000000);
452         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x0);
453         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x40000000);
454         lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x0);
455 #endif
456         lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
457         lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
458         lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0xa55a9696);
459         lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x5aa56969);
460         lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
461         lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
462
463         mask = m_AUTO_GATING_EN;
464         val = v_AUTO_GATING_EN(0);
465         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
466         mask = m_DITHER_UP_EN;
467         val = v_DITHER_UP_EN(1);
468         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
469         lcdc_cfg_done(lcdc_dev);
470         /*disable win0 to workaround iommu pagefault */
471         /*if (dev_drv->iommu_enabled) */
472         /*      win0_enable(lcdc_dev, 0); */
473         lcdc_dev->pre_init = true;
474
475         return 0;
476 }
477
478 static void rk3368_lcdc_deint(struct lcdc_device *lcdc_dev)
479 {
480         u32 mask, val;
481
482         if (lcdc_dev->clk_on) {
483                 rk3368_lcdc_disable_irq(lcdc_dev);
484                 spin_lock(&lcdc_dev->reg_lock);
485                 mask = m_WIN0_EN;
486                 val = v_WIN0_EN(0);
487                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
488                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
489
490                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
491                         m_WIN2_MST1_EN |
492                         m_WIN2_MST2_EN | m_WIN2_MST3_EN;
493                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
494                         v_WIN2_MST1_EN(0) |
495                         v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
496                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
497                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
498                 lcdc_cfg_done(lcdc_dev);
499                 spin_unlock(&lcdc_dev->reg_lock);
500                 mdelay(50);
501         }
502 }
503
504 static int rk3368_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
505 {
506         struct lcdc_device *lcdc_dev =
507             container_of(dev_drv, struct lcdc_device, driver);
508         struct rk_screen *screen = dev_drv->cur_screen;
509         u16 x_res = screen->mode.xres;
510         u16 y_res = screen->mode.yres;
511         u32 mask, val;
512         u16 h_total, v_total;
513         u16 post_hsd_en, post_vsd_en;
514         u16 post_dsp_hact_st, post_dsp_hact_end;
515         u16 post_dsp_vact_st, post_dsp_vact_end;
516         u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
517         u16 post_h_fac, post_v_fac;
518
519         screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200;
520         screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200;
521         screen->post_xsize = x_res *
522             (dev_drv->overscan.left + dev_drv->overscan.right) / 200;
523         screen->post_ysize = y_res *
524             (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200;
525
526         h_total = screen->mode.hsync_len + screen->mode.left_margin +
527             x_res + screen->mode.right_margin;
528         v_total = screen->mode.vsync_len + screen->mode.upper_margin +
529             y_res + screen->mode.lower_margin;
530
531         if (screen->post_dsp_stx + screen->post_xsize > x_res) {
532                 dev_warn(lcdc_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
533                          screen->post_dsp_stx, screen->post_xsize, x_res);
534                 screen->post_dsp_stx = x_res - screen->post_xsize;
535         }
536         if (screen->x_mirror == 0) {
537                 post_dsp_hact_st = screen->post_dsp_stx +
538                     screen->mode.hsync_len + screen->mode.left_margin;
539                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
540         } else {
541                 post_dsp_hact_end = h_total - screen->mode.right_margin -
542                     screen->post_dsp_stx;
543                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
544         }
545         if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
546                 post_hsd_en = 1;
547                 post_h_fac =
548                     GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
549         } else {
550                 post_hsd_en = 0;
551                 post_h_fac = 0x1000;
552         }
553
554         if (screen->post_dsp_sty + screen->post_ysize > y_res) {
555                 dev_warn(lcdc_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
556                          screen->post_dsp_sty, screen->post_ysize, y_res);
557                 screen->post_dsp_sty = y_res - screen->post_ysize;
558         }
559
560         if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
561                 post_vsd_en = 1;
562                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
563                                                       screen->post_ysize);
564         } else {
565                 post_vsd_en = 0;
566                 post_v_fac = 0x1000;
567         }
568
569         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
570                 post_dsp_vact_st = screen->post_dsp_sty / 2 +
571                                         screen->mode.vsync_len +
572                                         screen->mode.upper_margin;
573                 post_dsp_vact_end = post_dsp_vact_st +
574                                         screen->post_ysize / 2;
575
576                 post_dsp_vact_st_f1 = screen->mode.vsync_len +
577                                       screen->mode.upper_margin +
578                                       y_res/2 +
579                                       screen->mode.lower_margin +
580                                       screen->mode.vsync_len +
581                                       screen->mode.upper_margin +
582                                       screen->post_dsp_sty / 2 +
583                                       1;
584                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 +
585                                         screen->post_ysize/2;
586         } else {
587                 if (screen->y_mirror == 0) {
588                         post_dsp_vact_st = screen->post_dsp_sty +
589                             screen->mode.vsync_len +
590                             screen->mode.upper_margin;
591                         post_dsp_vact_end = post_dsp_vact_st +
592                                 screen->post_ysize;
593                 } else {
594                         post_dsp_vact_end = v_total -
595                                 screen->mode.lower_margin -
596                             screen->post_dsp_sty;
597                         post_dsp_vact_st = post_dsp_vact_end -
598                                 screen->post_ysize;
599                 }
600                 post_dsp_vact_st_f1 = 0;
601                 post_dsp_vact_end_f1 = 0;
602         }
603         DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
604             screen->post_xsize, screen->post_ysize, screen->xpos);
605         DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
606             screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
607         mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
608         val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
609             v_DSP_HACT_ST_POST(post_dsp_hact_st);
610         lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
611
612         mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
613         val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
614             v_DSP_VACT_ST_POST(post_dsp_vact_st);
615         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
616
617         mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
618         val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
619             v_POST_VS_FACTOR_YRGB(post_v_fac);
620         lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
621
622         mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
623         val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
624             v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
625         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
626
627         mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
628         val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
629         lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
630         return 0;
631 }
632
633 static int rk3368_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
634 {
635         struct lcdc_device *lcdc_dev =
636             container_of(dev_drv, struct lcdc_device, driver);
637         struct rk_lcdc_win *win;
638         u32 colorkey_r, colorkey_g, colorkey_b;
639         int i, key_val;
640
641         for (i = 0; i < 4; i++) {
642                 win = dev_drv->win[i];
643                 key_val = win->color_key_val;
644                 colorkey_r = (key_val & 0xff) << 2;
645                 colorkey_g = ((key_val >> 8) & 0xff) << 12;
646                 colorkey_b = ((key_val >> 16) & 0xff) << 22;
647                 /*color key dither 565/888->aaa */
648                 key_val = colorkey_r | colorkey_g | colorkey_b;
649                 switch (i) {
650                 case 0:
651                         lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
652                         break;
653                 case 1:
654                         lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
655                         break;
656                 case 2:
657                         lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
658                         break;
659                 case 3:
660                         lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
661                         break;
662                 default:
663                         pr_info("%s:un support win num:%d\n",
664                                 __func__, i);
665                         break;
666                 }
667         }
668         return 0;
669 }
670
671 static int rk3368_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
672 {
673         struct lcdc_device *lcdc_dev =
674             container_of(dev_drv, struct lcdc_device, driver);
675         struct rk_lcdc_win *win = dev_drv->win[win_id];
676         struct alpha_config alpha_config;
677         u32 mask, val;
678         int ppixel_alpha = 0, global_alpha = 0, i;
679         u32 src_alpha_ctl, dst_alpha_ctl;
680
681         for (i = 0; i < win->area_num; i++) {
682                 ppixel_alpha |= ((win->area[i].format == ARGB888) ||
683                                  (win->area[i].format == FBDC_ARGB_888) ||
684                                  (win->area[i].format == FBDC_ABGR_888) ||
685                                  (win->area[i].format == ABGR888)) ? 1 : 0;
686         }
687         global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
688         alpha_config.src_global_alpha_val = win->g_alpha_val;
689         win->alpha_mode = AB_SRC_OVER;
690         /*printk("%s,alpha_mode=%d,alpha_en=%d,ppixel_a=%d,gla_a=%d\n",
691            __func__,win->alpha_mode,win->alpha_en,ppixel_alpha,
692            global_alpha); */
693         switch (win->alpha_mode) {
694         case AB_USER_DEFINE:
695                 break;
696         case AB_CLEAR:
697                 alpha_config.src_factor_mode = AA_ZERO;
698                 alpha_config.dst_factor_mode = AA_ZERO;
699                 break;
700         case AB_SRC:
701                 alpha_config.src_factor_mode = AA_ONE;
702                 alpha_config.dst_factor_mode = AA_ZERO;
703                 break;
704         case AB_DST:
705                 alpha_config.src_factor_mode = AA_ZERO;
706                 alpha_config.dst_factor_mode = AA_ONE;
707                 break;
708         case AB_SRC_OVER:
709                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
710                 if (global_alpha)
711                         alpha_config.src_factor_mode = AA_SRC_GLOBAL;
712                 else
713                         alpha_config.src_factor_mode = AA_ONE;
714                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
715                 break;
716         case AB_DST_OVER:
717                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
718                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
719                 alpha_config.dst_factor_mode = AA_ONE;
720                 break;
721         case AB_SRC_IN:
722                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
723                 alpha_config.src_factor_mode = AA_SRC;
724                 alpha_config.dst_factor_mode = AA_ZERO;
725                 break;
726         case AB_DST_IN:
727                 alpha_config.src_factor_mode = AA_ZERO;
728                 alpha_config.dst_factor_mode = AA_SRC;
729                 break;
730         case AB_SRC_OUT:
731                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
732                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
733                 alpha_config.dst_factor_mode = AA_ZERO;
734                 break;
735         case AB_DST_OUT:
736                 alpha_config.src_factor_mode = AA_ZERO;
737                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
738                 break;
739         case AB_SRC_ATOP:
740                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
741                 alpha_config.src_factor_mode = AA_SRC;
742                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
743                 break;
744         case AB_DST_ATOP:
745                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
746                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
747                 alpha_config.dst_factor_mode = AA_SRC;
748                 break;
749         case XOR:
750                 alpha_config.src_color_mode = AA_SRC_PRE_MUL;
751                 alpha_config.src_factor_mode = AA_SRC_INVERSE;
752                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
753                 break;
754         case AB_SRC_OVER_GLOBAL:
755                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
756                 alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
757                 alpha_config.src_factor_mode = AA_SRC_GLOBAL;
758                 alpha_config.dst_factor_mode = AA_SRC_INVERSE;
759                 break;
760         default:
761                 pr_err("alpha mode error\n");
762                 break;
763         }
764         if ((ppixel_alpha == 1) && (global_alpha == 1))
765                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
766         else if (ppixel_alpha == 1)
767                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
768         else if (global_alpha == 1)
769                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
770         else
771                 dev_warn(lcdc_dev->dev, "alpha_en should be 0\n");
772         alpha_config.src_alpha_mode = AA_STRAIGHT;
773         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
774
775         switch (win_id) {
776         case 0:
777                 src_alpha_ctl = 0x60;
778                 dst_alpha_ctl = 0x64;
779                 break;
780         case 1:
781                 src_alpha_ctl = 0xa0;
782                 dst_alpha_ctl = 0xa4;
783                 break;
784         case 2:
785                 src_alpha_ctl = 0xdc;
786                 dst_alpha_ctl = 0xec;
787                 break;
788         case 3:
789                 src_alpha_ctl = 0x12c;
790                 dst_alpha_ctl = 0x13c;
791                 break;
792         case 4:
793                 src_alpha_ctl = 0x160;
794                 dst_alpha_ctl = 0x164;
795                 break;
796         }
797         mask = m_WIN0_DST_FACTOR_M0;
798         val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
799         lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
800         mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
801             m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
802             m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0 |
803             m_WIN0_SRC_GLOBAL_ALPHA;
804         val = v_WIN0_SRC_ALPHA_EN(1) |
805             v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
806             v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
807             v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
808             v_WIN0_SRC_ALPHA_CAL_M0(alpha_config.src_alpha_cal_m0) |
809             v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
810             v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
811         lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
812
813         return 0;
814 }
815
816 static int rk3368_lcdc_area_xst(struct rk_lcdc_win *win, int area_num)
817 {
818         struct rk_lcdc_win_area area_temp;
819         int i, j;
820
821         for (i = 0; i < area_num; i++) {
822                 for (j = i + 1; j < area_num; j++) {
823                         if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
824                                 memcpy(&area_temp, &win->area[i],
825                                        sizeof(struct rk_lcdc_win_area));
826                                 memcpy(&win->area[i], &win->area[j],
827                                        sizeof(struct rk_lcdc_win_area));
828                                 memcpy(&win->area[j], &area_temp,
829                                        sizeof(struct rk_lcdc_win_area));
830                         }
831                 }
832         }
833
834         return 0;
835 }
836
837 static int __maybe_unused
838         rk3368_lcdc_area_swap(struct rk_lcdc_win *win, int area_num)
839 {
840         struct rk_lcdc_win_area area_temp;
841
842         switch (area_num) {
843         case 2:
844                 area_temp = win->area[0];
845                 win->area[0] = win->area[1];
846                 win->area[1] = area_temp;
847                 break;
848         case 3:
849                 area_temp = win->area[0];
850                 win->area[0] = win->area[2];
851                 win->area[2] = area_temp;
852                 break;
853         case 4:
854                 area_temp = win->area[0];
855                 win->area[0] = win->area[3];
856                 win->area[3] = area_temp;
857
858                 area_temp = win->area[1];
859                 win->area[1] = win->area[2];
860                 win->area[2] = area_temp;
861                 break;
862         default:
863                 pr_info("un supported area num!\n");
864                 break;
865         }
866         return 0;
867 }
868
869 static int __maybe_unused
870 rk3368_win_area_check_var(int win_id, int area_num,
871                           struct rk_lcdc_win_area *area_pre,
872                           struct rk_lcdc_win_area *area_now)
873 {
874         if ((area_pre->xpos > area_now->xpos) ||
875             ((area_pre->xpos + area_pre->xsize > area_now->xpos) &&
876              (area_pre->ypos + area_pre->ysize > area_now->ypos))) {
877                 area_now->state = 0;
878                 pr_err("win[%d]:\n"
879                        "area_pre[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n"
880                        "area_now[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n",
881                        win_id,
882                        area_num - 1, area_pre->xpos, area_pre->xsize,
883                        area_pre->ypos, area_pre->ysize,
884                        area_num, area_now->xpos, area_now->xsize,
885                        area_now->ypos, area_now->ysize);
886                 return -EINVAL;
887         }
888         return 0;
889 }
890
891 static int __maybe_unused rk3368_get_fbdc_idle(struct rk_lcdc_driver *dev_drv)
892 {
893         struct lcdc_device *lcdc_dev =
894             container_of(dev_drv, struct lcdc_device, driver);
895         u32 val, i;
896
897         for (i = 0; i < 100; i++) {
898                 val = lcdc_readl(lcdc_dev, IFBDC_DEBUG0);
899                 val &= m_DBG_IFBDC_IDLE;
900                 if (val)
901                         continue;
902                 else
903                         mdelay(10);
904         };
905         return val;
906 }
907
908 static int rk3368_fbdc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
909 {
910         struct lcdc_device *lcdc_dev =
911             container_of(dev_drv, struct lcdc_device, driver);
912         struct rk_lcdc_win *win = dev_drv->win[win_id];
913         u32 mask, val;
914
915         mask = m_IFBDC_CTRL_FBDC_EN | m_IFBDC_CTRL_FBDC_COR_EN |
916             m_IFBDC_CTRL_FBDC_WIN_SEL | m_IFBDC_CTRL_FBDC_ROTATION_MODE |
917             m_IFBDC_CTRL_FBDC_FMT | m_IFBDC_CTRL_WIDTH_RATIO;
918         val = v_IFBDC_CTRL_FBDC_EN(win->area[0].fbdc_en) |
919             v_IFBDC_CTRL_FBDC_COR_EN(win->area[0].fbdc_cor_en) |
920             v_IFBDC_CTRL_FBDC_WIN_SEL(win->id) |
921             v_IFBDC_CTRL_FBDC_ROTATION_MODE(win->mirror_en << 1) |
922             v_IFBDC_CTRL_FBDC_FMT(win->area[0].fbdc_fmt_cfg) |
923             v_IFBDC_CTRL_WIDTH_RATIO(win->area[0].fbdc_dsp_width_ratio);
924         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
925
926         mask = m_IFBDC_TILES_NUM;
927         val = v_IFBDC_TILES_NUM(win->area[0].fbdc_num_tiles);
928         lcdc_msk_reg(lcdc_dev, IFBDC_TILES_NUM, mask, val);
929
930         mask = m_IFBDC_MB_SIZE_WIDTH | m_IFBDC_MB_SIZE_HEIGHT;
931         val = v_IFBDC_MB_SIZE_WIDTH(win->area[0].fbdc_mb_width) |
932             v_IFBDC_MB_SIZE_HEIGHT(win->area[0].fbdc_mb_height);
933         lcdc_msk_reg(lcdc_dev, IFBDC_MB_SIZE, mask, val);
934
935         mask = m_IFBDC_CMP_INDEX_INIT;
936         val = v_IFBDC_CMP_INDEX_INIT(win->area[0].fbdc_cmp_index_init);
937         lcdc_msk_reg(lcdc_dev, IFBDC_CMP_INDEX_INIT, mask, val);
938
939         mask = m_IFBDC_MB_VIR_WIDTH;
940         val = v_IFBDC_MB_VIR_WIDTH(win->area[0].fbdc_mb_vir_width);
941         lcdc_msk_reg(lcdc_dev, IFBDC_MB_VIR_WIDTH, mask, val);
942
943         return 0;
944 }
945
946 static int rk3368_init_fbdc_config(struct rk_lcdc_driver *dev_drv, int win_id)
947 {
948         struct lcdc_device *lcdc_dev =
949             container_of(dev_drv, struct lcdc_device, driver);
950         struct rk_lcdc_win *win = dev_drv->win[win_id];
951         u8 fbdc_dsp_width_ratio;
952         u16 fbdc_mb_vir_width, fbdc_mb_vir_height;
953         u16 fbdc_mb_width, fbdc_mb_height;
954         u16 fbdc_mb_xst, fbdc_mb_yst, fbdc_num_tiles;
955         u16 fbdc_cmp_index_init;
956         u8 mb_w_size, mb_h_size;
957         struct rk_screen *screen = dev_drv->cur_screen;
958
959         if (screen->mode.flag == FB_VMODE_INTERLACED) {
960                 dev_err(lcdc_dev->dev, "unsupport fbdc+interlace!\n");
961                 return 0;
962         }
963
964         switch (win->area[0].fmt_cfg) {
965         case VOP_FORMAT_ARGB888:
966                 fbdc_dsp_width_ratio = 0;
967                 mb_w_size = 16;
968                 break;
969         case VOP_FORMAT_RGB888:
970                 fbdc_dsp_width_ratio = 0;
971                 mb_w_size = 16;
972                 break;
973         case VOP_FORMAT_RGB565:
974                 fbdc_dsp_width_ratio = 1;
975                 mb_w_size = 32;
976                 break;
977         default:
978                 dev_err(lcdc_dev->dev,
979                         "in fbdc mode,unsupport fmt:%d!\n",
980                         win->area[0].fmt_cfg);
981                 break;
982         }
983         mb_h_size = 4;
984
985         /*macro block xvir and yvir */
986         if ((win->area[0].xvir % mb_w_size == 0) &&
987             (win->area[0].yvir % mb_h_size == 0)) {
988                 fbdc_mb_vir_width = win->area[0].xvir / mb_w_size;
989                 fbdc_mb_vir_height = win->area[0].yvir / mb_h_size;
990         } else {
991                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
992                 pr_err("xvir[%d]/yvir[%d] should %d/%d pix align!\n",
993                        win->area[0].xvir, win->area[0].yvir,
994                        mb_w_size, mb_h_size);
995         }
996         /*macro block xact and yact */
997         if ((win->area[0].xact % mb_w_size == 0) &&
998             (win->area[0].yact % mb_h_size == 0)) {
999                 fbdc_mb_width = win->area[0].xact / mb_w_size;
1000                 fbdc_mb_height = win->area[0].yact / mb_h_size;
1001         } else {
1002                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
1003                 pr_err("xact[%d]/yact[%d] should %d/%d pix align!\n",
1004                        win->area[0].xact, win->area[0].yact,
1005                        mb_w_size, mb_h_size);
1006         }
1007         /*macro block xoff and yoff */
1008         if ((win->area[0].xoff % mb_w_size == 0) &&
1009             (win->area[0].yoff % mb_h_size == 0)) {
1010                 fbdc_mb_xst = win->area[0].xoff / mb_w_size;
1011                 fbdc_mb_yst = win->area[0].yoff / mb_h_size;
1012         } else {
1013                 pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
1014                 pr_err("xoff[%d]/yoff[%d] should %d/%d pix align!\n",
1015                        win->area[0].xoff, win->area[0].yoff,
1016                        mb_w_size, mb_h_size);
1017         }
1018
1019         /*FBDC tiles */
1020         fbdc_num_tiles = fbdc_mb_vir_width * fbdc_mb_vir_height;
1021
1022         /*
1023            switch (fbdc_rotation_mode)  {
1024            case FBDC_ROT_NONE:
1025            fbdc_cmp_index_init =
1026            (fbdc_mb_yst*fbdc_mb_vir_width) +  fbdc_mb_xst;
1027            break;
1028            case FBDC_X_MIRROR:
1029            fbdc_cmp_index_init =
1030            (fbdc_mb_yst*fbdc_mb_vir_width) + (fbdc_mb_xst+
1031            (fbdc_mb_width-1));
1032            break;
1033            case FBDC_Y_MIRROR:
1034            fbdc_cmp_index_init =
1035            ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width)  +
1036            fbdc_mb_xst;
1037            break;
1038            case FBDC_ROT_180:
1039            fbdc_cmp_index_init =
1040            ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width) +
1041            (fbdc_mb_xst+(fbdc_mb_width-1));
1042            break;
1043            }
1044          */
1045         if ((win->mirror_en) && ((win_id == 2) || (win_id == 3))) {
1046                 fbdc_cmp_index_init =
1047                     ((fbdc_mb_yst + (fbdc_mb_height - 1)) * fbdc_mb_vir_width) +
1048                     (fbdc_mb_xst + (fbdc_mb_width - 1));
1049         } else {
1050                 fbdc_cmp_index_init =
1051                     (fbdc_mb_yst * fbdc_mb_vir_width) + fbdc_mb_xst;
1052         }
1053         /*fbdc fmt maybe need to change*/
1054         win->area[0].fbdc_dsp_width_ratio = fbdc_dsp_width_ratio;
1055         win->area[0].fbdc_mb_vir_width = fbdc_mb_vir_width;
1056         win->area[0].fbdc_mb_vir_height = fbdc_mb_vir_height;
1057         win->area[0].fbdc_mb_width = fbdc_mb_width;
1058         win->area[0].fbdc_mb_height = fbdc_mb_height;
1059         win->area[0].fbdc_mb_xst = fbdc_mb_xst;
1060         win->area[0].fbdc_mb_yst = fbdc_mb_yst;
1061         win->area[0].fbdc_num_tiles = fbdc_num_tiles;
1062         win->area[0].fbdc_cmp_index_init = fbdc_cmp_index_init;
1063
1064         return 0;
1065 }
1066
1067 static int rk3368_lcdc_axi_gather_cfg(struct lcdc_device *lcdc_dev,
1068                                             struct rk_lcdc_win *win)
1069 {
1070         u32 mask, val;
1071         u16 yrgb_gather_num = 3;
1072         u16 cbcr_gather_num = 1;
1073
1074         switch (win->area[0].format) {
1075         case ARGB888:
1076         case XBGR888:
1077         case ABGR888:
1078                 yrgb_gather_num = 3;
1079                 break;
1080         case RGB888:
1081         case RGB565:
1082                 yrgb_gather_num = 2;
1083                 break;
1084         case YUV444:
1085         case YUV422:
1086         case YUV420:
1087         case YUV420_NV21:
1088                 yrgb_gather_num = 1;
1089                 cbcr_gather_num = 2;
1090                 break;
1091         default:
1092                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1093                         __func__);
1094                 return -EINVAL;
1095         }
1096
1097         if ((win->id == 0) || (win->id == 1)) {
1098                 mask = m_WIN0_YRGB_AXI_GATHER_EN | m_WIN0_CBR_AXI_GATHER_EN |
1099                         m_WIN0_YRGB_AXI_GATHER_NUM | m_WIN0_CBR_AXI_GATHER_NUM;
1100                 val = v_WIN0_YRGB_AXI_GATHER_EN(1) | v_WIN0_CBR_AXI_GATHER_EN(1) |
1101                         v_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
1102                         v_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
1103                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1 + (win->id * 0x40), mask, val);
1104         } else if ((win->id == 2) || (win->id == 3)) {
1105                 mask = m_WIN2_AXI_GATHER_EN | m_WIN2_AXI_GATHER_NUM;
1106                 val = v_WIN2_AXI_GATHER_EN(1) |
1107                         v_WIN2_AXI_GATHER_NUM(yrgb_gather_num);
1108                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL1 + ((win->id - 2) * 0x50), mask, val);
1109         } else if (win->id == 4) {
1110                 mask = m_HWC_AXI_GATHER_EN | m_HWC_AXI_GATHER_NUM;
1111                 val = v_HWC_AXI_GATHER_EN(1) |
1112                         v_HWC_AXI_GATHER_NUM(yrgb_gather_num);
1113                 lcdc_msk_reg(lcdc_dev, HWC_CTRL1, mask, val);
1114         }
1115         return 0;
1116 }
1117
1118 static void rk3368_lcdc_csc_mode(struct lcdc_device *lcdc_dev,
1119                                  struct rk_lcdc_win *win)
1120 {
1121         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
1122         struct rk_screen *screen = dev_drv->cur_screen;
1123
1124         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1125                 switch (win->area[0].fmt_cfg) {
1126                 case VOP_FORMAT_ARGB888:
1127                 case VOP_FORMAT_RGB888:
1128                 case VOP_FORMAT_RGB565:
1129                         if ((screen->mode.xres < 1280) &&
1130                             (screen->mode.yres < 720)) {
1131                                 win->csc_mode = VOP_R2Y_CSC_BT601;
1132                         } else {
1133                                 win->csc_mode = VOP_R2Y_CSC_BT709;
1134                         }
1135                         break;
1136                 default:
1137                         break;
1138                 }
1139         } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
1140                 switch (win->area[0].fmt_cfg) {
1141                 case VOP_FORMAT_YCBCR420:
1142                         if ((win->id == 0) || (win->id == 1))
1143                                 win->csc_mode = VOP_Y2R_CSC_MPEG;
1144                         break;
1145                 default:
1146                         break;
1147                 }
1148         }
1149 }
1150
1151 static int rk3368_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1152 {
1153         struct lcdc_device *lcdc_dev =
1154             container_of(dev_drv, struct lcdc_device, driver);
1155         struct rk_lcdc_win *win = dev_drv->win[win_id];
1156         unsigned int mask, val, off;
1157
1158         off = win_id * 0x40;
1159         /*if(win->win_lb_mode == 5)
1160            win->win_lb_mode = 4;
1161            for rk3288 to fix hw bug? */
1162
1163         if (win->state == 1) {
1164                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1165                 rk3368_lcdc_axi_gather_cfg(lcdc_dev, win);
1166                 if (win->area[0].fbdc_en) {
1167                         rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
1168                 } else {
1169                         mask = m_IFBDC_CTRL_FBDC_EN;
1170                         val = v_IFBDC_CTRL_FBDC_EN(0);
1171                         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
1172                 }
1173                 mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
1174                     m_WIN0_LB_MODE | m_WIN0_RB_SWAP | m_WIN0_X_MIRROR |
1175                     m_WIN0_Y_MIRROR | m_WIN0_CSC_MODE |m_WIN0_UV_SWAP;
1176                 val = v_WIN0_EN(win->state) |
1177                     v_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
1178                     v_WIN0_FMT_10(win->fmt_10) |
1179                     v_WIN0_LB_MODE(win->win_lb_mode) |
1180                     v_WIN0_RB_SWAP(win->area[0].swap_rb) |
1181                     v_WIN0_X_MIRROR(win->mirror_en) |
1182                     v_WIN0_Y_MIRROR(win->mirror_en) |
1183                     v_WIN0_CSC_MODE(win->csc_mode) |
1184                     v_WIN0_UV_SWAP(win->area[0].swap_uv);
1185                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
1186
1187                 mask = m_WIN0_BIC_COE_SEL |
1188                     m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
1189                     m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT2 |
1190                     m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
1191                     m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
1192                     m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
1193                     m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
1194                     m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
1195                 val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
1196                     v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
1197                     v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
1198                     v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
1199                     v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
1200                     v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
1201                     v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
1202                     v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
1203                     v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
1204                     v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
1205                     v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
1206                     v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
1207                     v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
1208                     v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
1209                     v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
1210                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1 + off, mask, val);
1211                 val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
1212                     v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
1213                 lcdc_writel(lcdc_dev, WIN0_VIR + off, val);
1214                 /*lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off,
1215                                 win->area[0].y_addr);
1216                    lcdc_writel(lcdc_dev, WIN0_CBR_MST+off,
1217                                 win->area[0].uv_addr); */
1218                 val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
1219                     v_WIN0_ACT_HEIGHT(win->area[0].yact);
1220                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO + off, val);
1221
1222                 val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
1223                     v_WIN0_DSP_HEIGHT(win->area[0].ysize);
1224                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO + off, val);
1225
1226                 val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
1227                     v_WIN0_DSP_YST(win->area[0].dsp_sty);
1228                 lcdc_writel(lcdc_dev, WIN0_DSP_ST + off, val);
1229
1230                 val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
1231                     v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
1232                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB + off, val);
1233
1234                 val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
1235                     v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
1236                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR + off, val);
1237                 if (win->alpha_en == 1) {
1238                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1239                 } else {
1240                         mask = m_WIN0_SRC_ALPHA_EN;
1241                         val = v_WIN0_SRC_ALPHA_EN(0);
1242                         lcdc_msk_reg(lcdc_dev, WIN0_SRC_ALPHA_CTRL + off,
1243                                      mask, val);
1244                 }
1245
1246                 if (dev_drv->cur_screen->mode.vmode == FB_VMODE_INTERLACED) {
1247                         mask = m_WIN0_YRGB_DEFLICK | m_WIN0_CBR_DEFLICK;
1248                         if (win->area[0].yact == 2 * win->area[0].ysize)
1249                                 val =v_WIN0_YRGB_DEFLICK(0) | v_WIN0_CBR_DEFLICK(0);
1250                         else
1251                                 val =v_WIN0_YRGB_DEFLICK(1) | v_WIN0_CBR_DEFLICK(1);
1252                         lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1253                 }
1254         } else {
1255                 mask = m_WIN0_EN;
1256                 val = v_WIN0_EN(win->state);
1257                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
1258         }
1259         return 0;
1260 }
1261
1262 static int rk3368_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1263 {
1264         struct lcdc_device *lcdc_dev =
1265             container_of(dev_drv, struct lcdc_device, driver);
1266         struct rk_lcdc_win *win = dev_drv->win[win_id];
1267         unsigned int mask, val, off;
1268
1269         off = (win_id - 2) * 0x50;
1270         rk3368_lcdc_area_xst(win, win->area_num);
1271
1272         if (win->state == 1) {
1273                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1274                 rk3368_lcdc_axi_gather_cfg(lcdc_dev, win);
1275                 if (win->area[0].fbdc_en) {
1276                         rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
1277                 } else {
1278                         mask = m_IFBDC_CTRL_FBDC_EN;
1279                         val = v_IFBDC_CTRL_FBDC_EN(0);
1280                         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
1281                 }
1282
1283                 mask = m_WIN2_EN | m_WIN2_CSC_MODE;
1284                 val = v_WIN2_EN(1) | v_WIN1_CSC_MODE(win->csc_mode);
1285                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1286                 /*area 0 */
1287                 if (win->area[0].state == 1) {
1288                         mask = m_WIN2_MST0_EN | m_WIN2_DATA_FMT0 |
1289                             m_WIN2_RB_SWAP0;
1290                         val = v_WIN2_MST0_EN(win->area[0].state) |
1291                             v_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1292                             v_WIN2_RB_SWAP0(win->area[0].swap_rb);
1293                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1294
1295                         mask = m_WIN2_VIR_STRIDE0;
1296                         val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1297                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1298
1299                         /*lcdc_writel(lcdc_dev,WIN2_MST0+off,
1300                            win->area[0].y_addr); */
1301                         val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
1302                             v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
1303                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO0 + off, val);
1304                         val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1305                             v_WIN2_DSP_YST0(win->area[0].dsp_sty);
1306                         lcdc_writel(lcdc_dev, WIN2_DSP_ST0 + off, val);
1307                 } else {
1308                         mask = m_WIN2_MST0_EN;
1309                         val = v_WIN2_MST0_EN(0);
1310                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1311                 }
1312                 /*area 1 */
1313                 if (win->area[1].state == 1) {
1314                         /*rk3368_win_area_check_var(win_id, 1,
1315                                                   &win->area[0], &win->area[1]);
1316                         */
1317
1318                         mask = m_WIN2_MST1_EN | m_WIN2_DATA_FMT1 |
1319                             m_WIN2_RB_SWAP1;
1320                         val = v_WIN2_MST1_EN(win->area[1].state) |
1321                             v_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1322                             v_WIN2_RB_SWAP1(win->area[1].swap_rb);
1323                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1324
1325                         mask = m_WIN2_VIR_STRIDE1;
1326                         val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1327                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1328
1329                         /*lcdc_writel(lcdc_dev,WIN2_MST1+off,
1330                            win->area[1].y_addr); */
1331                         val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
1332                             v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
1333                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO1 + off, val);
1334                         val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1335                             v_WIN2_DSP_YST1(win->area[1].dsp_sty);
1336                         lcdc_writel(lcdc_dev, WIN2_DSP_ST1 + off, val);
1337                 } else {
1338                         mask = m_WIN2_MST1_EN;
1339                         val = v_WIN2_MST1_EN(0);
1340                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1341                 }
1342                 /*area 2 */
1343                 if (win->area[2].state == 1) {
1344                         /*rk3368_win_area_check_var(win_id, 2,
1345                                                   &win->area[1], &win->area[2]);
1346                         */
1347
1348                         mask = m_WIN2_MST2_EN | m_WIN2_DATA_FMT2 |
1349                             m_WIN2_RB_SWAP2;
1350                         val = v_WIN2_MST2_EN(win->area[2].state) |
1351                             v_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1352                             v_WIN2_RB_SWAP2(win->area[2].swap_rb);
1353                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1354
1355                         mask = m_WIN2_VIR_STRIDE2;
1356                         val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1357                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1358
1359                         /*lcdc_writel(lcdc_dev,WIN2_MST2+off,
1360                            win->area[2].y_addr); */
1361                         val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
1362                             v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
1363                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO2 + off, val);
1364                         val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1365                             v_WIN2_DSP_YST2(win->area[2].dsp_sty);
1366                         lcdc_writel(lcdc_dev, WIN2_DSP_ST2 + off, val);
1367                 } else {
1368                         mask = m_WIN2_MST2_EN;
1369                         val = v_WIN2_MST2_EN(0);
1370                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1371                 }
1372                 /*area 3 */
1373                 if (win->area[3].state == 1) {
1374                         /*rk3368_win_area_check_var(win_id, 3,
1375                                                   &win->area[2], &win->area[3]);
1376                         */
1377
1378                         mask = m_WIN2_MST3_EN | m_WIN2_DATA_FMT3 |
1379                             m_WIN2_RB_SWAP3;
1380                         val = v_WIN2_MST3_EN(win->area[3].state) |
1381                             v_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1382                             v_WIN2_RB_SWAP3(win->area[3].swap_rb);
1383                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1384
1385                         mask = m_WIN2_VIR_STRIDE3;
1386                         val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1387                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1388
1389                         /*lcdc_writel(lcdc_dev,WIN2_MST3+off,
1390                            win->area[3].y_addr); */
1391                         val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
1392                             v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
1393                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO3 + off, val);
1394                         val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1395                             v_WIN2_DSP_YST3(win->area[3].dsp_sty);
1396                         lcdc_writel(lcdc_dev, WIN2_DSP_ST3 + off, val);
1397                 } else {
1398                         mask = m_WIN2_MST3_EN;
1399                         val = v_WIN2_MST3_EN(0);
1400                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1401                 }
1402
1403                 if (win->alpha_en == 1) {
1404                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1405                 } else {
1406                         mask = m_WIN2_SRC_ALPHA_EN;
1407                         val = v_WIN2_SRC_ALPHA_EN(0);
1408                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL + off,
1409                                      mask, val);
1410                 }
1411         } else {
1412                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
1413                     m_WIN2_MST0_EN | m_WIN2_MST2_EN | m_WIN2_MST3_EN;
1414                 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
1415                     v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
1416                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1417         }
1418         return 0;
1419 }
1420
1421 static int rk3368_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1422 {
1423         struct lcdc_device *lcdc_dev =
1424             container_of(dev_drv, struct lcdc_device, driver);
1425         struct rk_lcdc_win *win = dev_drv->win[win_id];
1426         unsigned int mask, val, hwc_size = 0;
1427
1428         if (win->state == 1) {
1429                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1430                 rk3368_lcdc_axi_gather_cfg(lcdc_dev, win);
1431                 mask = m_HWC_EN | m_HWC_DATA_FMT |
1432                     m_HWC_RB_SWAP | m_WIN0_CSC_MODE;
1433                 val = v_HWC_EN(1) | v_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1434                     v_HWC_RB_SWAP(win->area[0].swap_rb) |
1435                     v_WIN0_CSC_MODE(win->csc_mode);
1436                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1437
1438                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
1439                         hwc_size = 0;
1440                 else if ((win->area[0].xsize == 64) &&
1441                          (win->area[0].ysize == 64))
1442                         hwc_size = 1;
1443                 else if ((win->area[0].xsize == 96) &&
1444                          (win->area[0].ysize == 96))
1445                         hwc_size = 2;
1446                 else if ((win->area[0].xsize == 128) &&
1447                          (win->area[0].ysize == 128))
1448                         hwc_size = 3;
1449                 else
1450                         dev_err(lcdc_dev->dev, "un supported hwc size!\n");
1451
1452                 mask = m_HWC_SIZE;
1453                 val = v_HWC_SIZE(hwc_size);
1454                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1455
1456                 mask = m_HWC_DSP_XST | m_HWC_DSP_YST;
1457                 val = v_HWC_DSP_XST(win->area[0].dsp_stx) |
1458                     v_HWC_DSP_YST(win->area[0].dsp_sty);
1459                 lcdc_msk_reg(lcdc_dev, HWC_DSP_ST, mask, val);
1460
1461                 if (win->alpha_en == 1) {
1462                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1463                 } else {
1464                         mask = m_WIN2_SRC_ALPHA_EN;
1465                         val = v_WIN2_SRC_ALPHA_EN(0);
1466                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL, mask, val);
1467                 }
1468         } else {
1469                 mask = m_HWC_EN;
1470                 val = v_HWC_EN(win->state);
1471                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1472         }
1473         return 0;
1474 }
1475
1476 static int rk3368_lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
1477                                          struct rk_lcdc_win *win)
1478 {
1479         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
1480         int timeout;
1481         unsigned long flags;
1482
1483         if (likely(lcdc_dev->clk_on)) {
1484                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1485                              v_STANDBY_EN(lcdc_dev->standby));
1486                 if ((win->id == 0) || (win->id == 1))
1487                         rk3368_win_0_1_reg_update(dev_drv, win->id);
1488                 else if ((win->id == 2) || (win->id == 3))
1489                         rk3368_win_2_3_reg_update(dev_drv, win->id);
1490                 else if (win->id == 4)
1491                         rk3368_hwc_reg_update(dev_drv, win->id);
1492                 /*rk3368_lcdc_post_cfg(dev_drv); */
1493                 lcdc_cfg_done(lcdc_dev);
1494         }
1495
1496         /*if (dev_drv->wait_fs) { */
1497         if (0) {
1498                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1499                 init_completion(&dev_drv->frame_done);
1500                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1501                 timeout =
1502                     wait_for_completion_timeout(&dev_drv->frame_done,
1503                                                 msecs_to_jiffies
1504                                                 (dev_drv->cur_screen->ft + 5));
1505                 if (!timeout && (!dev_drv->frame_done.done)) {
1506                         dev_warn(lcdc_dev->dev,
1507                                  "wait for new frame start time out!\n");
1508                         return -ETIMEDOUT;
1509                 }
1510         }
1511         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
1512         return 0;
1513 }
1514
1515 static int rk3368_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
1516 {
1517         memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0x270);
1518         return 0;
1519 }
1520
1521 static int __maybe_unused rk3368_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
1522 {
1523         u32 mask, val;
1524         struct lcdc_device *lcdc_dev =
1525             container_of(dev_drv, struct lcdc_device, driver);
1526
1527         if (unlikely(!lcdc_dev->clk_on)) {
1528                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
1529                 return 0;
1530         }
1531 #if defined(CONFIG_ROCKCHIP_IOMMU)
1532         if (dev_drv->iommu_enabled) {
1533                 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
1534                         if (likely(lcdc_dev->clk_on)) {
1535                                 mask = m_MMU_EN;
1536                                 val = v_MMU_EN(1);
1537                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1538                                 mask = m_AXI_MAX_OUTSTANDING_EN |
1539                                         m_AXI_OUTSTANDING_MAX_NUM;
1540                                 val = v_AXI_OUTSTANDING_MAX_NUM(31) |
1541                                         v_AXI_MAX_OUTSTANDING_EN(1);
1542                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
1543                         }
1544                         lcdc_dev->iommu_status = 1;
1545                         rockchip_iovmm_activate(dev_drv->dev);
1546                 }
1547         }
1548 #endif
1549         return 0;
1550 }
1551
1552 static int rk3368_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1553 {
1554         int ret = 0, fps = 0;
1555         struct lcdc_device *lcdc_dev =
1556             container_of(dev_drv, struct lcdc_device, driver);
1557         struct rk_screen *screen = dev_drv->cur_screen;
1558 #ifdef CONFIG_RK_FPGA
1559         return 0;
1560 #endif
1561         if (reset_rate)
1562                 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);/*set pll */
1563         if (ret)
1564                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
1565         lcdc_dev->pixclock =
1566             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1567         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
1568
1569         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
1570         screen->ft = 1000 / fps;
1571         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
1572                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
1573         return 0;
1574 }
1575
1576 static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv)
1577 {
1578         struct lcdc_device *lcdc_dev =
1579             container_of(dev_drv, struct lcdc_device, driver);
1580         struct rk_screen *screen = dev_drv->cur_screen;
1581         u16 hsync_len = screen->mode.hsync_len;
1582         u16 left_margin = screen->mode.left_margin;
1583         u16 right_margin = screen->mode.right_margin;
1584         u16 vsync_len = screen->mode.vsync_len;
1585         u16 upper_margin = screen->mode.upper_margin;
1586         u16 lower_margin = screen->mode.lower_margin;
1587         u16 x_res = screen->mode.xres;
1588         u16 y_res = screen->mode.yres;
1589         u32 mask, val;
1590         u16 h_total, v_total;
1591         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1592
1593         h_total = hsync_len + left_margin + x_res + right_margin;
1594         v_total = vsync_len + upper_margin + y_res + lower_margin;
1595
1596         mask = m_DSP_HS_PW | m_DSP_HTOTAL;
1597         val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
1598         lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
1599
1600         mask = m_DSP_HACT_END | m_DSP_HACT_ST;
1601         val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
1602             v_DSP_HACT_ST(hsync_len + left_margin);
1603         lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
1604
1605         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1606                 /* First Field Timing */
1607                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1608                 val = v_DSP_VS_PW(vsync_len) |
1609                     v_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1610                                       lower_margin) + y_res + 1);
1611                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1612
1613                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1614                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1615                     v_DSP_VACT_ST(vsync_len + upper_margin);
1616                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1617
1618                 /* Second Field Timing */
1619                 mask = m_DSP_VS_ST_F1 | m_DSP_VS_END_F1;
1620                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1621                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1622                     lower_margin;
1623                 val = v_DSP_VS_ST_F1(vs_st_f1) | v_DSP_VS_END_F1(vs_end_f1);
1624                 lcdc_msk_reg(lcdc_dev, DSP_VS_ST_END_F1, mask, val);
1625
1626                 mask = m_DSP_VACT_END_F1 | m_DSP_VAC_ST_F1;
1627                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1628                     lower_margin + 1;
1629                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1630                     lower_margin + 1;
1631                 val =
1632                     v_DSP_VACT_END_F1(vact_end_f1) |
1633                     v_DSP_VAC_ST_F1(vact_st_f1);
1634                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END_F1, mask, val);
1635
1636                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1637                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1638                              v_DSP_INTERLACE(1) | v_DSP_FIELD_POL(0));
1639                 mask =
1640                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1641                     m_WIN0_CBR_DEFLICK;
1642                 val =
1643                     v_WIN0_INTERLACE_READ(1) | v_WIN0_YRGB_DEFLICK(0) |
1644                     v_WIN0_CBR_DEFLICK(0);
1645                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1646
1647                 mask =
1648                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1649                     m_WIN1_CBR_DEFLICK;
1650                 val =
1651                     v_WIN1_INTERLACE_READ(1) | v_WIN1_YRGB_DEFLICK(0) |
1652                     v_WIN1_CBR_DEFLICK(0);
1653                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1654
1655                 mask = m_WIN2_INTERLACE_READ;
1656                 val = v_WIN2_INTERLACE_READ(1);
1657                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1658
1659                 mask = m_WIN3_INTERLACE_READ;
1660                 val = v_WIN3_INTERLACE_READ(1);
1661                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1662
1663                 mask = m_HWC_INTERLACE_READ;
1664                 val = v_HWC_INTERLACE_READ(1);
1665                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1666
1667                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1668                 val =
1669                     v_DSP_LINE_FLAG0_NUM(vact_end_f1) |
1670                     v_DSP_LINE_FLAG1_NUM(vact_end_f1);
1671                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1672         } else {
1673                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1674                 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
1675                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1676
1677                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1678                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1679                     v_DSP_VACT_ST(vsync_len + upper_margin);
1680                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1681
1682                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1683                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1684                              v_DSP_INTERLACE(0) | v_DSP_FIELD_POL(0));
1685
1686                 mask =
1687                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1688                     m_WIN0_CBR_DEFLICK;
1689                 val =
1690                     v_WIN0_INTERLACE_READ(0) | v_WIN0_YRGB_DEFLICK(0) |
1691                     v_WIN0_CBR_DEFLICK(0);
1692                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1693
1694                 mask =
1695                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1696                     m_WIN1_CBR_DEFLICK;
1697                 val =
1698                     v_WIN1_INTERLACE_READ(0) | v_WIN1_YRGB_DEFLICK(0) |
1699                     v_WIN1_CBR_DEFLICK(0);
1700                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1701
1702                 mask = m_WIN2_INTERLACE_READ;
1703                 val = v_WIN2_INTERLACE_READ(0);
1704                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1705
1706                 mask = m_WIN3_INTERLACE_READ;
1707                 val = v_WIN3_INTERLACE_READ(0);
1708                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1709
1710                 mask = m_HWC_INTERLACE_READ;
1711                 val = v_HWC_INTERLACE_READ(0);
1712                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1713
1714                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1715                 val = v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
1716                         v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
1717                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1718         }
1719         rk3368_lcdc_post_cfg(dev_drv);
1720         return 0;
1721 }
1722
1723 static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1724 {
1725         struct lcdc_device *lcdc_dev =
1726             container_of(dev_drv, struct lcdc_device, driver);
1727         u32 bcsh_ctrl;
1728
1729         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_OVERLAY_MODE,
1730                      v_OVERLAY_MODE(dev_drv->overlay_mode));
1731         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1732                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1733                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1734                                      m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1735                                      v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1736                 else            /* YUV2RGB */
1737                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1738                                      m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1739                                      m_BCSH_R2Y_EN,
1740                                      v_BCSH_Y2R_EN(1) |
1741                                      v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1742                                      v_BCSH_R2Y_EN(0));
1743         } else {                /* overlay_mode=VOP_RGB_DOMAIN */
1744                 /* bypass  --need check,if bcsh close? */
1745                 if (dev_drv->output_color == COLOR_RGB) {
1746                         bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1747                         if (((bcsh_ctrl & m_BCSH_EN) == 1) ||
1748                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1749                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1750                                              m_BCSH_R2Y_EN |
1751                                              m_BCSH_Y2R_EN,
1752                                              v_BCSH_R2Y_EN(1) |
1753                                              v_BCSH_Y2R_EN(1));
1754                         else
1755                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1756                                              m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1757                                              v_BCSH_R2Y_EN(0) |
1758                                              v_BCSH_Y2R_EN(0));
1759                 } else          /* RGB2YUV */
1760                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1761                                      m_BCSH_R2Y_EN |
1762                                      m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1763                                      v_BCSH_R2Y_EN(1) |
1764                                      v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1765                                      v_BCSH_Y2R_EN(0));
1766         }
1767 }
1768
1769 static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1770                                   u16 *yact, int *format, u32 *dsp_addr)
1771 {
1772         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1773                                                     struct lcdc_device, driver);
1774         u32 val;
1775
1776         spin_lock(&lcdc_dev->reg_lock);
1777
1778         val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1779         *xact = (val & m_WIN0_ACT_WIDTH) + 1;
1780         *yact = ((val & m_WIN0_ACT_HEIGHT)>>16) + 1;
1781
1782         val = lcdc_readl(lcdc_dev, WIN0_CTRL0);
1783         *format = (val & m_WIN0_DATA_FMT) >> 1;
1784         *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1785
1786         spin_unlock(&lcdc_dev->reg_lock);
1787
1788         return 0;
1789 }
1790
1791 static int rk3368_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1792                               int format, u16 xact, u16 yact, u16 xvir)
1793 {
1794         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1795                                                     struct lcdc_device, driver);
1796         u32 val, mask;
1797         int swap = (format == RGB888) ? 1 : 0;
1798
1799         mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP;
1800         val = v_WIN0_DATA_FMT(format) | v_WIN0_RB_SWAP(swap);
1801         lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1802
1803         lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_WIN0_VIR_STRIDE,
1804                         v_WIN0_VIR_STRIDE(xvir));
1805         lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_WIN0_ACT_WIDTH(xact) |
1806                     v_WIN0_ACT_HEIGHT(yact));
1807
1808         lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1809
1810         lcdc_cfg_done(lcdc_dev);
1811
1812         return 0;
1813 }
1814
1815 static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen)
1816 {
1817         struct lcdc_device *lcdc_dev =
1818             container_of(dev_drv, struct lcdc_device, driver);
1819         u32 mask, val;
1820         u32 __maybe_unused v;
1821         /*printk("0407:standby=%d,initscreen=%d,dev_drv->first_frame=%d\n",
1822                 lcdc_dev->standby,initscreen,dev_drv->first_frame);*/
1823         if (!lcdc_dev->standby && initscreen && (dev_drv->first_frame != 1)) {
1824                 mdelay(150);
1825                 mask = m_WIN0_EN;
1826                 val = v_WIN0_EN(0);
1827                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1828                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1829
1830                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
1831                         m_WIN2_MST1_EN |
1832                         m_WIN2_MST2_EN | m_WIN2_MST3_EN;
1833                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
1834                         v_WIN2_MST1_EN(0) |
1835                         v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
1836                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1837                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1838                 mask = m_HDMI_OUT_EN;
1839                 val = v_HDMI_OUT_EN(0);
1840                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1841                 lcdc_cfg_done(lcdc_dev);
1842                 mdelay(50);
1843                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(1));
1844                 writel_relaxed(0, lcdc_dev->regs + REG_CFG_DONE);
1845                 mdelay(50);
1846 #if 0
1847                 if (dev_drv->iommu_enabled) {
1848                         if (dev_drv->mmu_dev)
1849                                 rockchip_iovmm_deactivate(dev_drv->dev);
1850                 }
1851                 lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
1852                                 (1 << 4)  | (1 << 5)  | (1 << 6) |
1853                                 (1 << 20) | (1 << 21) | (1 << 22));
1854                 udelay(100);
1855                 v = lcdc_cru_readl(lcdc_dev->cru_base, 0x0318);
1856                 pr_info("cru read = 0x%x\n", v);
1857                 lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
1858                                 (0 << 4)  | (0 << 5)  | (0 << 6) |
1859                                 (1 << 20) | (1 << 21) | (1 << 22));
1860                 mdelay(100);
1861                 if (dev_drv->iommu_enabled) {
1862                         if (dev_drv->mmu_dev)
1863                                 rockchip_iovmm_activate(dev_drv->dev);
1864                 }
1865                 mdelay(50);
1866                 rk3368_lcdc_reg_restore(lcdc_dev);
1867                 mdelay(50);
1868 #endif
1869         }
1870         return 0;
1871 }
1872
1873 static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1874 {
1875         u16 face = 0;
1876         u16 dclk_ddr = 0;
1877         u32 v = 0;
1878         struct lcdc_device *lcdc_dev =
1879             container_of(dev_drv, struct lcdc_device, driver);
1880         struct rk_screen *screen = dev_drv->cur_screen;
1881         u32 mask, val;
1882
1883         if (unlikely(!lcdc_dev->clk_on)) {
1884                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
1885                 return 0;
1886         }
1887
1888         if (!lcdc_dev->standby && initscreen && (dev_drv->first_frame != 1))
1889                 flush_kthread_worker(&dev_drv->update_regs_worker);
1890
1891         spin_lock(&lcdc_dev->reg_lock);
1892         if (likely(lcdc_dev->clk_on)) {
1893                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1894 #if 0
1895                 if (!lcdc_dev->standby && !initscreen) {
1896                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1897                                      v_STANDBY_EN(1));
1898                         lcdc_cfg_done(lcdc_dev);
1899                         mdelay(50);
1900                 }
1901 #else
1902         lcdc_reset(dev_drv, initscreen);
1903 #endif
1904                 switch (screen->face) {
1905                 case OUT_P565:
1906                         face = OUT_P565;
1907                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1908                             m_DITHER_DOWN_SEL;
1909                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1910                             v_DITHER_DOWN_SEL(1);
1911                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1912                         break;
1913                 case OUT_P666:
1914                         face = OUT_P666;
1915                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1916                             m_DITHER_DOWN_SEL;
1917                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1918                             v_DITHER_DOWN_SEL(1);
1919                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1920                         break;
1921                 case OUT_D888_P565:
1922                         face = OUT_P888;
1923                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1924                             m_DITHER_DOWN_SEL;
1925                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1926                             v_DITHER_DOWN_SEL(1);
1927                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1928                         break;
1929                 case OUT_D888_P666:
1930                         face = OUT_P888;
1931                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1932                             m_DITHER_DOWN_SEL;
1933                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1934                             v_DITHER_DOWN_SEL(1);
1935                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1936                         break;
1937                 case OUT_P888:
1938                         face = OUT_P888;
1939                         mask = m_DITHER_DOWN_EN;
1940                         val = v_DITHER_DOWN_EN(0);
1941                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1942                         break;
1943                 case OUT_YUV_420:
1944                         /*yuv420 output prefer yuv domain overlay */
1945                         face = OUT_YUV_420;
1946                         dclk_ddr = 1;
1947                         mask = m_DITHER_DOWN_EN;
1948                         val = v_DITHER_DOWN_EN(0);
1949                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1950                         break;
1951                 case OUT_S888:
1952                         face = OUT_S888;
1953                         mask = m_DITHER_DOWN_EN;
1954                         val = v_DITHER_DOWN_EN(0);
1955                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1956                         break;
1957                 case OUT_S888DUMY:
1958                         face = OUT_S888DUMY;
1959                         mask = m_DITHER_DOWN_EN;
1960                         val = v_DITHER_DOWN_EN(0);
1961                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1962                         break;
1963                 case OUT_CCIR656:
1964                         if (screen->color_mode == COLOR_RGB)
1965                                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1966                         else
1967                                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1968                         face = OUT_CCIR656_MODE_0;
1969                         mask = m_DITHER_DOWN_EN;
1970                         val = v_DITHER_DOWN_EN(0);
1971                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1972                         break;
1973                 default:
1974                         dev_err(lcdc_dev->dev, "un supported interface!\n");
1975                         break;
1976                 }
1977                 switch (screen->type) {
1978                 case SCREEN_RGB:
1979                         mask = m_RGB_OUT_EN;
1980                         val = v_RGB_OUT_EN(1);
1981                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1982                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1983                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1984                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1985                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1986                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
1987                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
1988                         v = 1 << 15 | (1 << (15 + 16));
1989
1990                         break;
1991                 case SCREEN_LVDS:
1992                         mask = m_RGB_OUT_EN;
1993                         val = v_RGB_OUT_EN(1);
1994                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1995                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1996                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1997                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1998                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1999                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
2000                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
2001                         v = 0 << 15 | (1 << (15 + 16));
2002                         break;
2003                 case SCREEN_HDMI:
2004                         /*face = OUT_RGB_AAA;*/
2005                         if (screen->color_mode == COLOR_RGB)
2006                                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
2007                         else
2008                                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
2009                         mask = m_HDMI_OUT_EN  | m_RGB_OUT_EN;
2010                         val = v_HDMI_OUT_EN(1) | v_RGB_OUT_EN(0);
2011                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2012                         mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
2013                             m_HDMI_DEN_POL | m_HDMI_DCLK_POL;
2014                         val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
2015                             v_HDMI_VSYNC_POL(screen->pin_vsync) |
2016                             v_HDMI_DEN_POL(screen->pin_den) |
2017                             v_HDMI_DCLK_POL(screen->pin_dclk);
2018                         break;
2019                 case SCREEN_MIPI:
2020                         mask = m_MIPI_OUT_EN  | m_RGB_OUT_EN;
2021                         val = v_MIPI_OUT_EN(1) | v_RGB_OUT_EN(0);
2022                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2023                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
2024                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
2025                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
2026                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
2027                             v_MIPI_DEN_POL(screen->pin_den) |
2028                             v_MIPI_DCLK_POL(screen->pin_dclk);
2029                         break;
2030                 case SCREEN_DUAL_MIPI:
2031                         mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN  |
2032                                 m_RGB_OUT_EN;
2033                         val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1) |
2034                                 v_RGB_OUT_EN(0);
2035                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2036                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
2037                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
2038                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
2039                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
2040                             v_MIPI_DEN_POL(screen->pin_den) |
2041                             v_MIPI_DCLK_POL(screen->pin_dclk);
2042                         break;
2043                 case SCREEN_EDP:
2044                         face = OUT_P888;        /*RGB 888 output */
2045
2046                         mask = m_EDP_OUT_EN | m_RGB_OUT_EN;
2047                         val = v_EDP_OUT_EN(1) | v_RGB_OUT_EN(0);
2048                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2049                         /*because edp have to sent aaa fmt */
2050                         mask = m_DITHER_DOWN_EN;
2051                         val = v_DITHER_DOWN_EN(0);
2052
2053                         mask |= m_EDP_HSYNC_POL | m_EDP_VSYNC_POL |
2054                             m_EDP_DEN_POL | m_EDP_DCLK_POL;
2055                         val |= v_EDP_HSYNC_POL(screen->pin_hsync) |
2056                             v_EDP_VSYNC_POL(screen->pin_vsync) |
2057                             v_EDP_DEN_POL(screen->pin_den) |
2058                             v_EDP_DCLK_POL(screen->pin_dclk);
2059                         break;
2060                 }
2061                 /*hsync vsync den dclk polo,dither */
2062                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
2063 #ifndef CONFIG_RK_FPGA
2064                 /*writel_relaxed(v, RK_GRF_VIRT + rk3368_GRF_SOC_CON7);
2065                 move to  lvds driver*/
2066                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
2067 #endif
2068                 mask = m_DSP_OUT_MODE | m_DSP_DCLK_DDR | m_DSP_BG_SWAP |
2069                     m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
2070                     m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
2071                     m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
2072                 val = v_DSP_OUT_MODE(face) | v_DSP_DCLK_DDR(dclk_ddr) |
2073                     v_DSP_BG_SWAP(screen->swap_gb) |
2074                     v_DSP_RB_SWAP(screen->swap_rb) |
2075                     v_DSP_RG_SWAP(screen->swap_rg) |
2076                     v_DSP_DELTA_SWAP(screen->swap_delta) |
2077                     v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
2078                     v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
2079                     v_DSP_X_MIR_EN(screen->x_mirror) |
2080                     v_DSP_Y_MIR_EN(screen->y_mirror);
2081                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
2082                 /*BG color */
2083                 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
2084                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
2085                         val = v_DSP_BG_BLUE(0x80) | v_DSP_BG_GREEN(0x10) |
2086                                 v_DSP_BG_RED(0x80);
2087                 else
2088                         val = v_DSP_BG_BLUE(0) | v_DSP_BG_GREEN(0) |
2089                                 v_DSP_BG_RED(0);
2090                 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
2091                 dev_drv->output_color = screen->color_mode;
2092                 if (screen->dsp_lut == NULL)
2093                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2094                                      v_DSP_LUT_EN(0));
2095                 else
2096                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2097                                      v_DSP_LUT_EN(1));
2098                 rk3368_lcdc_bcsh_path_sel(dev_drv);
2099                 rk3368_config_timing(dev_drv);
2100         }
2101         spin_unlock(&lcdc_dev->reg_lock);
2102         rk3368_lcdc_set_dclk(dev_drv, 1);
2103         if (screen->type != SCREEN_HDMI &&
2104             screen->type != SCREEN_TVOUT &&
2105             dev_drv->trsm_ops &&
2106             dev_drv->trsm_ops->enable)
2107                 dev_drv->trsm_ops->enable();    
2108                 if (screen->init)
2109                         screen->init();
2110         /*if (!lcdc_dev->standby)
2111                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
2112                         m_STANDBY_EN, v_STANDBY_EN(0));*/
2113         return 0;
2114 }
2115
2116
2117 /*enable layer,open:1,enable;0 disable*/
2118 static void rk3368_lcdc_layer_enable(struct lcdc_device *lcdc_dev,
2119                                      unsigned int win_id, bool open)
2120 {
2121         spin_lock(&lcdc_dev->reg_lock);
2122         if (likely(lcdc_dev->clk_on) &&
2123             lcdc_dev->driver.win[win_id]->state != open) {
2124                 if (open) {
2125                         if (!lcdc_dev->atv_layer_cnt) {
2126                                 dev_info(lcdc_dev->dev,
2127                                          "wakeup from standby!\n");
2128                                 lcdc_dev->standby = 0;
2129                         }
2130                         lcdc_dev->atv_layer_cnt |= (1 << win_id);
2131                 } else {
2132                         if (lcdc_dev->atv_layer_cnt & (1 << win_id))
2133                                 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
2134                 }
2135                 lcdc_dev->driver.win[win_id]->state = open;
2136                 if (!open) {
2137                         /*rk3368_lcdc_reg_update(dev_drv);*/
2138                         rk3368_lcdc_layer_update_regs
2139                         (lcdc_dev, lcdc_dev->driver.win[win_id]);
2140                         lcdc_cfg_done(lcdc_dev);
2141                 }
2142                 /*if no layer used,disable lcdc */
2143                 if (!lcdc_dev->atv_layer_cnt) {
2144                         dev_info(lcdc_dev->dev,
2145                                  "no layer is used,go to standby!\n");
2146                         lcdc_dev->standby = 1;
2147                 }
2148         }
2149         spin_unlock(&lcdc_dev->reg_lock);
2150 }
2151
2152 static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
2153 {
2154         struct lcdc_device *lcdc_dev = container_of(dev_drv,
2155                                                     struct lcdc_device, driver);
2156         u32 mask, val;
2157         /*struct rk_screen *screen = dev_drv->cur_screen; */
2158
2159         mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
2160             m_LINE_FLAG1_INTR_CLR;
2161         val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
2162             v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1);
2163         lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
2164
2165         mask = m_FS_INTR_EN | m_LINE_FLAG0_INTR_EN |
2166                 m_BUS_ERROR_INTR_EN | m_LINE_FLAG1_INTR_EN;
2167         val = v_FS_INTR_EN(1) | v_LINE_FLAG0_INTR_EN(1) |
2168             v_BUS_ERROR_INTR_EN(1) | v_LINE_FLAG1_INTR_EN(0);
2169         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
2170
2171 #ifdef LCDC_IRQ_EMPTY_DEBUG
2172         mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
2173             m_WIN2_EMPTY_INTR_EN |
2174             m_WIN3_EMPTY_INTR_EN | m_HWC_EMPTY_INTR_EN |
2175             m_POST_BUF_EMPTY_INTR_EN | m_PWM_GEN_INTR_EN;
2176         val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) |
2177             v_WIN2_EMPTY_INTR_EN(1) |
2178             v_WIN3_EMPTY_INTR_EN(1) | v_HWC_EMPTY_INTR_EN(1) |
2179             v_POST_BUF_EMPTY_INTR_EN(1) | v_PWM_GEN_INTR_EN(1);
2180         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
2181 #endif
2182         return 0;
2183 }
2184
2185 static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
2186                             bool open)
2187 {
2188         struct lcdc_device *lcdc_dev =
2189             container_of(dev_drv, struct lcdc_device, driver);
2190 #if 0/*ndef CONFIG_RK_FPGA*/
2191         int sys_status =
2192             (dev_drv->id == 0) ? SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1;
2193 #endif
2194         /*enable clk,when first layer open */
2195         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
2196                 /*rockchip_set_system_status(sys_status);*/
2197                 rk3368_lcdc_pre_init(dev_drv);
2198                 rk3368_lcdc_clk_enable(lcdc_dev);
2199                 rk3368_lcdc_enable_irq(dev_drv);
2200 #if defined(CONFIG_ROCKCHIP_IOMMU)
2201                 if (dev_drv->iommu_enabled) {
2202                         if (!dev_drv->mmu_dev) {
2203                                 dev_drv->mmu_dev =
2204                                     rk_fb_get_sysmmu_device_by_compatible
2205                                     (dev_drv->mmu_dts_name);
2206                                 if (dev_drv->mmu_dev) {
2207                                         rk_fb_platform_set_sysmmu
2208                                             (dev_drv->mmu_dev, dev_drv->dev);
2209                                 } else {
2210                                         dev_err(dev_drv->dev,
2211                                                 "fail get rk iommu device\n");
2212                                         return -1;
2213                                 }
2214                         }
2215                         /*if (dev_drv->mmu_dev)
2216                            rockchip_iovmm_activate(dev_drv->dev); */
2217                 }
2218 #endif
2219                 rk3368_lcdc_reg_restore(lcdc_dev);
2220                 /*if (dev_drv->iommu_enabled)
2221                    rk3368_lcdc_mmu_en(dev_drv); */
2222                 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
2223                         rk3368_lcdc_set_dclk(dev_drv, 0);
2224                         /*rk3368_lcdc_enable_irq(dev_drv);*/
2225                 } else {
2226                         rk3368_load_screen(dev_drv, 1);
2227                 }
2228                 if (dev_drv->bcsh.enable)
2229                         rk3368_lcdc_set_bcsh(dev_drv, 1);
2230                 spin_lock(&lcdc_dev->reg_lock);
2231                 if (dev_drv->cur_screen->dsp_lut)
2232                         rk3368_lcdc_set_lut(dev_drv,
2233                                             dev_drv->cur_screen->dsp_lut);
2234                 if ((dev_drv->cur_screen->cabc_lut) && dev_drv->cabc_mode)
2235                         rk3368_set_cabc_lut(dev_drv,
2236                                             dev_drv->cur_screen->cabc_lut);
2237                 spin_unlock(&lcdc_dev->reg_lock);
2238         }
2239
2240         if (win_id < ARRAY_SIZE(lcdc_win))
2241                 rk3368_lcdc_layer_enable(lcdc_dev, win_id, open);
2242         else
2243                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
2244
2245
2246         /* when all layer closed,disable clk */
2247         /*if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
2248            rk3368_lcdc_disable_irq(lcdc_dev);
2249            rk3368_lcdc_reg_update(dev_drv);
2250            #if defined(CONFIG_ROCKCHIP_IOMMU)
2251            if (dev_drv->iommu_enabled) {
2252            if (dev_drv->mmu_dev)
2253            rockchip_iovmm_deactivate(dev_drv->dev);
2254            }
2255            #endif
2256            rk3368_lcdc_clk_disable(lcdc_dev);
2257            #ifndef CONFIG_RK_FPGA
2258            rockchip_clear_system_status(sys_status);
2259            #endif
2260            } */
2261         dev_drv->first_frame = 0;
2262         return 0;
2263 }
2264
2265 static int win_0_1_display(struct lcdc_device *lcdc_dev,
2266                            struct rk_lcdc_win *win)
2267 {
2268         u32 y_addr;
2269         u32 uv_addr;
2270         unsigned int off;
2271
2272         off = win->id * 0x40;
2273         /*win->smem_start + win->y_offset; */
2274         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2275         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2276         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2277             lcdc_dev->id, win->id, y_addr, uv_addr);
2278         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2279             win->area[0].y_offset, win->area[0].c_offset);
2280         spin_lock(&lcdc_dev->reg_lock);
2281         if (likely(lcdc_dev->clk_on)) {
2282                 win->area[0].y_addr = y_addr;
2283                 win->area[0].uv_addr = uv_addr;
2284                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2285                 lcdc_writel(lcdc_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2286                 if (win->area[0].fbdc_en == 1)
2287                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2288                                         win->area[0].y_addr);
2289         }
2290         spin_unlock(&lcdc_dev->reg_lock);
2291
2292         return 0;
2293 }
2294
2295 static int win_2_3_display(struct lcdc_device *lcdc_dev,
2296                            struct rk_lcdc_win *win)
2297 {
2298         u32 i, y_addr;
2299         unsigned int off;
2300
2301         off = (win->id - 2) * 0x50;
2302         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2303         DBG(2, "lcdc[%d]:win[%d]:", lcdc_dev->id, win->id);
2304
2305         spin_lock(&lcdc_dev->reg_lock);
2306         if (likely(lcdc_dev->clk_on)) {
2307                 for (i = 0; i < win->area_num; i++) {
2308                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2309                             i, win->area[i].y_addr, win->area[i].y_offset);
2310                         win->area[i].y_addr =
2311                             win->area[i].smem_start + win->area[i].y_offset;
2312                         }
2313                 lcdc_writel(lcdc_dev, WIN2_MST0 + off, win->area[0].y_addr);
2314                 lcdc_writel(lcdc_dev, WIN2_MST1 + off, win->area[1].y_addr);
2315                 lcdc_writel(lcdc_dev, WIN2_MST2 + off, win->area[2].y_addr);
2316                 lcdc_writel(lcdc_dev, WIN2_MST3 + off, win->area[3].y_addr);
2317                 if (win->area[0].fbdc_en == 1)
2318                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2319                                         win->area[0].y_addr);
2320         }
2321         spin_unlock(&lcdc_dev->reg_lock);
2322         return 0;
2323 }
2324
2325 static int hwc_display(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win)
2326 {
2327         u32 y_addr;
2328
2329         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2330         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2331             lcdc_dev->id, __func__, y_addr);
2332         spin_lock(&lcdc_dev->reg_lock);
2333         if (likely(lcdc_dev->clk_on)) {
2334                 win->area[0].y_addr = y_addr;
2335                 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
2336         }
2337         spin_unlock(&lcdc_dev->reg_lock);
2338
2339         return 0;
2340 }
2341
2342 static int rk3368_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2343 {
2344         struct lcdc_device *lcdc_dev =
2345             container_of(dev_drv, struct lcdc_device, driver);
2346         struct rk_lcdc_win *win = NULL;
2347         struct rk_screen *screen = dev_drv->cur_screen;
2348
2349 #if defined(WAIT_FOR_SYNC)
2350         int timeout;
2351         unsigned long flags;
2352 #endif
2353         win = dev_drv->win[win_id];
2354         if (!screen) {
2355                 dev_err(dev_drv->dev, "screen is null!\n");
2356                 return -ENOENT;
2357         }
2358         if (unlikely(!lcdc_dev->clk_on)) {
2359                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
2360                 return 0;
2361         }
2362         if (win_id == 0) {
2363                 win_0_1_display(lcdc_dev, win);
2364         } else if (win_id == 1) {
2365                 win_0_1_display(lcdc_dev, win);
2366         } else if (win_id == 2) {
2367                 win_2_3_display(lcdc_dev, win);
2368         } else if (win_id == 3) {
2369                 win_2_3_display(lcdc_dev, win);
2370         } else if (win_id == 4) {
2371                 hwc_display(lcdc_dev, win);
2372         } else {
2373                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2374                 return -EINVAL;
2375         }
2376
2377 #if defined(WAIT_FOR_SYNC)
2378         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
2379         init_completion(&dev_drv->frame_done);
2380         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
2381         timeout =
2382             wait_for_completion_timeout(&dev_drv->frame_done,
2383                                         msecs_to_jiffies(dev_drv->
2384                                                          cur_screen->ft + 5));
2385         if (!timeout && (!dev_drv->frame_done.done)) {
2386                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
2387                 return -ETIMEDOUT;
2388         }
2389 #endif
2390         return 0;
2391 }
2392
2393 static int rk3368_lcdc_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
2394 {
2395         u16 srcW;
2396         u16 srcH;
2397         u16 dstW;
2398         u16 dstH;
2399         u16 yrgb_srcW;
2400         u16 yrgb_srcH;
2401         u16 yrgb_dstW;
2402         u16 yrgb_dstH;
2403         u32 yrgb_vscalednmult;
2404         u32 yrgb_xscl_factor;
2405         u32 yrgb_yscl_factor;
2406         u8 yrgb_vsd_bil_gt2 = 0;
2407         u8 yrgb_vsd_bil_gt4 = 0;
2408
2409         u16 cbcr_srcW;
2410         u16 cbcr_srcH;
2411         u16 cbcr_dstW;
2412         u16 cbcr_dstH;
2413         u32 cbcr_vscalednmult;
2414         u32 cbcr_xscl_factor;
2415         u32 cbcr_yscl_factor;
2416         u8 cbcr_vsd_bil_gt2 = 0;
2417         u8 cbcr_vsd_bil_gt4 = 0;
2418         u8 yuv_fmt = 0;
2419
2420         srcW = win->area[0].xact;
2421         if ((screen->mode.vmode == FB_VMODE_INTERLACED) &&
2422             (win->area[0].yact == 2 * win->area[0].ysize)) {
2423                 srcH = win->area[0].yact / 2;
2424                 yrgb_vsd_bil_gt2 = 1;
2425                 cbcr_vsd_bil_gt2 = 1;
2426         } else {
2427                 srcH = win->area[0].yact;
2428         }
2429         dstW = win->area[0].xsize;
2430         dstH = win->area[0].ysize;
2431
2432         /*yrgb scl mode */
2433         yrgb_srcW = srcW;
2434         yrgb_srcH = srcH;
2435         yrgb_dstW = dstW;
2436         yrgb_dstH = dstH;
2437         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2438                 pr_err("ERROR: yrgb scale exceed 8,");
2439                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2440                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2441         }
2442         if (yrgb_srcW < yrgb_dstW)
2443                 win->yrgb_hor_scl_mode = SCALE_UP;
2444         else if (yrgb_srcW > yrgb_dstW)
2445                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2446         else
2447                 win->yrgb_hor_scl_mode = SCALE_NONE;
2448
2449         if (yrgb_srcH < yrgb_dstH)
2450                 win->yrgb_ver_scl_mode = SCALE_UP;
2451         else if (yrgb_srcH > yrgb_dstH)
2452                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2453         else
2454                 win->yrgb_ver_scl_mode = SCALE_NONE;
2455
2456         /*cbcr scl mode */
2457         switch (win->area[0].format) {
2458         case YUV422:
2459         case YUV422_A:
2460                 cbcr_srcW = srcW / 2;
2461                 cbcr_dstW = dstW;
2462                 cbcr_srcH = srcH;
2463                 cbcr_dstH = dstH;
2464                 yuv_fmt = 1;
2465                 break;
2466         case YUV420:
2467         case YUV420_A:
2468         case YUV420_NV21:
2469                 cbcr_srcW = srcW / 2;
2470                 cbcr_dstW = dstW;
2471                 cbcr_srcH = srcH / 2;
2472                 cbcr_dstH = dstH;
2473                 yuv_fmt = 1;
2474                 break;
2475         case YUV444:
2476         case YUV444_A:
2477                 cbcr_srcW = srcW;
2478                 cbcr_dstW = dstW;
2479                 cbcr_srcH = srcH;
2480                 cbcr_dstH = dstH;
2481                 yuv_fmt = 1;
2482                 break;
2483         default:
2484                 cbcr_srcW = 0;
2485                 cbcr_dstW = 0;
2486                 cbcr_srcH = 0;
2487                 cbcr_dstH = 0;
2488                 yuv_fmt = 0;
2489                 break;
2490         }
2491         if (yuv_fmt) {
2492                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2493                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2494                         pr_err("ERROR: cbcr scale exceed 8,");
2495                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2496                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2497                 }
2498         }
2499
2500         if (cbcr_srcW < cbcr_dstW)
2501                 win->cbr_hor_scl_mode = SCALE_UP;
2502         else if (cbcr_srcW > cbcr_dstW)
2503                 win->cbr_hor_scl_mode = SCALE_DOWN;
2504         else
2505                 win->cbr_hor_scl_mode = SCALE_NONE;
2506
2507         if (cbcr_srcH < cbcr_dstH)
2508                 win->cbr_ver_scl_mode = SCALE_UP;
2509         else if (cbcr_srcH > cbcr_dstH)
2510                 win->cbr_ver_scl_mode = SCALE_DOWN;
2511         else
2512                 win->cbr_ver_scl_mode = SCALE_NONE;
2513
2514         /*DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
2515             "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
2516             "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n", srcW,
2517             srcH, dstW, dstH, yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH,
2518             win->yrgb_hor_scl_mode, win->yrgb_ver_scl_mode, cbcr_srcW,
2519             cbcr_srcH, cbcr_dstW, cbcr_dstH, win->cbr_hor_scl_mode,
2520             win->cbr_ver_scl_mode);*/
2521
2522         /*line buffer mode */
2523         if ((win->area[0].format == YUV422) ||
2524             (win->area[0].format == YUV420) ||
2525             (win->area[0].format == YUV420_NV21) ||
2526             (win->area[0].format == YUV422_A) ||
2527             (win->area[0].format == YUV420_A)) {
2528                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2529                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2530                             (cbcr_dstW == 0))
2531                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2532                                        cbcr_dstW);
2533                         else if (cbcr_dstW > 1280)
2534                                 win->win_lb_mode = LB_YUV_3840X5;
2535                         else
2536                                 win->win_lb_mode = LB_YUV_2560X8;
2537                 } else {        /*SCALE_UP or SCALE_NONE */
2538                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2539                             (cbcr_srcW == 0))
2540                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2541                                        cbcr_srcW);
2542                         else if (cbcr_srcW > 1280)
2543                                 win->win_lb_mode = LB_YUV_3840X5;
2544                         else
2545                                 win->win_lb_mode = LB_YUV_2560X8;
2546                 }
2547         } else {
2548                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2549                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2550                             (yrgb_dstW == 0))
2551                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2552                         else if (yrgb_dstW > 2560)
2553                                 win->win_lb_mode = LB_RGB_3840X2;
2554                         else if (yrgb_dstW > 1920)
2555                                 win->win_lb_mode = LB_RGB_2560X4;
2556                         else if (yrgb_dstW > 1280)
2557                                 win->win_lb_mode = LB_RGB_1920X5;
2558                         else
2559                                 win->win_lb_mode = LB_RGB_1280X8;
2560                 } else {        /*SCALE_UP or SCALE_NONE */
2561                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2562                             (yrgb_srcW == 0))
2563                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2564                         else if (yrgb_srcW > 2560)
2565                                 win->win_lb_mode = LB_RGB_3840X2;
2566                         else if (yrgb_srcW > 1920)
2567                                 win->win_lb_mode = LB_RGB_2560X4;
2568                         else if (yrgb_srcW > 1280)
2569                                 win->win_lb_mode = LB_RGB_1920X5;
2570                         else
2571                                 win->win_lb_mode = LB_RGB_1280X8;
2572                 }
2573         }
2574         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2575
2576         /*vsd/vsu scale ALGORITHM */
2577         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2578         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2579         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2580         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2581         switch (win->win_lb_mode) {
2582         case LB_YUV_3840X5:
2583         case LB_YUV_2560X8:
2584         case LB_RGB_1920X5:
2585         case LB_RGB_1280X8:
2586                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2587                 win->cbr_vsu_mode = SCALE_UP_BIC;
2588                 break;
2589         case LB_RGB_3840X2:
2590                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2591                         pr_err("ERROR : not allow yrgb ver scale\n");
2592                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2593                         pr_err("ERROR : not allow cbcr ver scale\n");
2594                 break;
2595         case LB_RGB_2560X4:
2596                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2597                 win->cbr_vsu_mode = SCALE_UP_BIL;
2598                 break;
2599         default:
2600                 pr_info("%s:un supported win_lb_mode:%d\n",
2601                         __func__, win->win_lb_mode);
2602                 break;
2603         }
2604         if (win->mirror_en == 1) {
2605                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2606         }
2607         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
2608                 /*interlace mode must bill */
2609                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2610                 win->cbr_vsd_mode = SCALE_DOWN_BIL;
2611         }
2612         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2613             (win->area[0].fbdc_en == 1)) {
2614                 /*in this pattern,use bil mode,not support souble scd,
2615                 use avg mode, support double scd, but aclk should be
2616                 bigger than dclk,aclk>>dclk */
2617                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2618                         pr_err("ERROR : fbdc mode,not support y scale down:");
2619                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2620                                yrgb_srcH, yrgb_dstH);
2621                 }
2622         }
2623         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2624             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2625             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2626
2627         /*SCALE FACTOR */
2628
2629         /*(1.1)YRGB HOR SCALE FACTOR */
2630         switch (win->yrgb_hor_scl_mode) {
2631         case SCALE_NONE:
2632                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2633                 break;
2634         case SCALE_UP:
2635                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2636                 break;
2637         case SCALE_DOWN:
2638                 switch (win->yrgb_hsd_mode) {
2639                 case SCALE_DOWN_BIL:
2640                         yrgb_xscl_factor =
2641                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2642                         break;
2643                 case SCALE_DOWN_AVG:
2644                         yrgb_xscl_factor =
2645                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2646                         break;
2647                 default:
2648                         pr_info(
2649                                 "%s:un supported yrgb_hsd_mode:%d\n", __func__,
2650                                win->yrgb_hsd_mode);
2651                         break;
2652                 }
2653                 break;
2654         default:
2655                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2656                         __func__, win->yrgb_hor_scl_mode);
2657                 break;
2658         }                       /*win->yrgb_hor_scl_mode */
2659
2660         /*(1.2)YRGB VER SCALE FACTOR */
2661         switch (win->yrgb_ver_scl_mode) {
2662         case SCALE_NONE:
2663                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2664                 break;
2665         case SCALE_UP:
2666                 switch (win->yrgb_vsu_mode) {
2667                 case SCALE_UP_BIL:
2668                         yrgb_yscl_factor =
2669                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2670                         break;
2671                 case SCALE_UP_BIC:
2672                         if (yrgb_srcH < 3) {
2673                                 pr_err("yrgb_srcH should be");
2674                                 pr_err(" greater than 3 !!!\n");
2675                         }
2676                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2677                                                                 yrgb_dstH);
2678                         break;
2679                 default:
2680                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2681                                 __func__, win->yrgb_vsu_mode);
2682                         break;
2683                 }
2684                 break;
2685         case SCALE_DOWN:
2686                 switch (win->yrgb_vsd_mode) {
2687                 case SCALE_DOWN_BIL:
2688                         yrgb_vscalednmult =
2689                             rk3368_get_hard_ware_vskiplines(yrgb_srcH,
2690                                                             yrgb_dstH);
2691                         yrgb_yscl_factor =
2692                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2693                                                            yrgb_vscalednmult);
2694                         if (yrgb_yscl_factor >= 0x2000) {
2695                                 pr_err("yrgb_yscl_factor should be ");
2696                                 pr_err("less than 0x2000,yrgb_yscl_factor=%4x;\n",
2697                                        yrgb_yscl_factor);
2698                         }
2699                         if (yrgb_vscalednmult == 4) {
2700                                 yrgb_vsd_bil_gt4 = 1;
2701                                 yrgb_vsd_bil_gt2 = 0;
2702                         } else if (yrgb_vscalednmult == 2) {
2703                                 yrgb_vsd_bil_gt4 = 0;
2704                                 yrgb_vsd_bil_gt2 = 1;
2705                         } else {
2706                                 yrgb_vsd_bil_gt4 = 0;
2707                                 yrgb_vsd_bil_gt2 = 0;
2708                         }
2709                         break;
2710                 case SCALE_DOWN_AVG:
2711                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2712                                                                  yrgb_dstH);
2713                         break;
2714                 default:
2715                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2716                                 __func__, win->yrgb_vsd_mode);
2717                         break;
2718                 }               /*win->yrgb_vsd_mode */
2719                 break;
2720         default:
2721                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2722                         __func__, win->yrgb_ver_scl_mode);
2723                 break;
2724         }
2725         win->scale_yrgb_x = yrgb_xscl_factor;
2726         win->scale_yrgb_y = yrgb_yscl_factor;
2727         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2728         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2729         DBG(1, "yrgb:h_fac=%d, v_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2730             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2731
2732         /*(2.1)CBCR HOR SCALE FACTOR */
2733         switch (win->cbr_hor_scl_mode) {
2734         case SCALE_NONE:
2735                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2736                 break;
2737         case SCALE_UP:
2738                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2739                 break;
2740         case SCALE_DOWN:
2741                 switch (win->cbr_hsd_mode) {
2742                 case SCALE_DOWN_BIL:
2743                         cbcr_xscl_factor =
2744                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2745                         break;
2746                 case SCALE_DOWN_AVG:
2747                         cbcr_xscl_factor =
2748                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2749                         break;
2750                 default:
2751                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2752                                 __func__, win->cbr_hsd_mode);
2753                         break;
2754                 }
2755                 break;
2756         default:
2757                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2758                         __func__, win->cbr_hor_scl_mode);
2759                 break;
2760         }                       /*win->cbr_hor_scl_mode */
2761
2762         /*(2.2)CBCR VER SCALE FACTOR */
2763         switch (win->cbr_ver_scl_mode) {
2764         case SCALE_NONE:
2765                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2766                 break;
2767         case SCALE_UP:
2768                 switch (win->cbr_vsu_mode) {
2769                 case SCALE_UP_BIL:
2770                         cbcr_yscl_factor =
2771                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2772                         break;
2773                 case SCALE_UP_BIC:
2774                         if (cbcr_srcH < 3) {
2775                                 pr_err("cbcr_srcH should be ");
2776                                 pr_err("greater than 3 !!!\n");
2777                         }
2778                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2779                                                                 cbcr_dstH);
2780                         break;
2781                 default:
2782                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2783                                 __func__, win->cbr_vsu_mode);
2784                         break;
2785                 }
2786                 break;
2787         case SCALE_DOWN:
2788                 switch (win->cbr_vsd_mode) {
2789                 case SCALE_DOWN_BIL:
2790                         cbcr_vscalednmult =
2791                             rk3368_get_hard_ware_vskiplines(cbcr_srcH,
2792                                                             cbcr_dstH);
2793                         cbcr_yscl_factor =
2794                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2795                                                            cbcr_vscalednmult);
2796                         if (cbcr_yscl_factor >= 0x2000) {
2797                                 pr_err("cbcr_yscl_factor should be less ");
2798                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2799                                        cbcr_yscl_factor);
2800                         }
2801
2802                         if (cbcr_vscalednmult == 4) {
2803                                 cbcr_vsd_bil_gt4 = 1;
2804                                 cbcr_vsd_bil_gt2 = 0;
2805                         } else if (cbcr_vscalednmult == 2) {
2806                                 cbcr_vsd_bil_gt4 = 0;
2807                                 cbcr_vsd_bil_gt2 = 1;
2808                         } else {
2809                                 cbcr_vsd_bil_gt4 = 0;
2810                                 cbcr_vsd_bil_gt2 = 0;
2811                         }
2812                         break;
2813                 case SCALE_DOWN_AVG:
2814                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2815                                                                  cbcr_dstH);
2816                         break;
2817                 default:
2818                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2819                                 __func__, win->cbr_vsd_mode);
2820                         break;
2821                 }
2822                 break;
2823         default:
2824                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2825                         __func__, win->cbr_ver_scl_mode);
2826                 break;
2827         }
2828         win->scale_cbcr_x = cbcr_xscl_factor;
2829         win->scale_cbcr_y = cbcr_yscl_factor;
2830         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2831         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2832
2833         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2834             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2835         return 0;
2836 }
2837
2838 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2839                      struct rk_lcdc_win_area *area)
2840 {
2841         int pos;
2842
2843         if (screen->x_mirror && mirror_en)
2844                 pr_err("not support both win and global mirror\n");
2845
2846         if ((!mirror_en) && (!screen->x_mirror))
2847                 pos = area->xpos + screen->mode.left_margin +
2848                         screen->mode.hsync_len;
2849         else
2850                 pos = screen->mode.xres - area->xpos -
2851                         area->xsize + screen->mode.left_margin +
2852                         screen->mode.hsync_len;
2853
2854         return pos;
2855 }
2856
2857 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2858                      struct rk_lcdc_win_area *area)
2859 {
2860         int pos;
2861
2862         if (screen->y_mirror && mirror_en)
2863                 pr_err("not support both win and global mirror\n");
2864         if (screen->mode.vmode == FB_VMODE_NONINTERLACED) {
2865                 if ((!mirror_en) && (!screen->y_mirror))
2866                         pos = area->ypos + screen->mode.upper_margin +
2867                                 screen->mode.vsync_len;
2868                 else
2869                         pos = screen->mode.yres - area->ypos -
2870                                 area->ysize + screen->mode.upper_margin +
2871                                 screen->mode.vsync_len;
2872         } else if (screen->mode.vmode == FB_VMODE_INTERLACED) {
2873                 pos = area->ypos / 2 + screen->mode.upper_margin +
2874                         screen->mode.vsync_len;
2875                 area->ysize /= 2;
2876         }
2877
2878         return pos;
2879 }
2880
2881 static int win_0_1_set_par(struct lcdc_device *lcdc_dev,
2882                            struct rk_screen *screen, struct rk_lcdc_win *win)
2883 {
2884         u32 xact, yact, xvir, yvir, xpos, ypos;
2885         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2886         char fmt[9] = "NULL";
2887
2888         xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]);
2889         ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]);
2890
2891         spin_lock(&lcdc_dev->reg_lock);
2892         if (likely(lcdc_dev->clk_on)) {
2893                 rk3368_lcdc_cal_scl_fac(win, screen);   /*fac,lb,gt2,gt4 */
2894                 switch (win->area[0].format) {
2895                 case FBDC_RGB_565:
2896                         fmt_cfg = 2;
2897                         swap_rb = 0;
2898                         win->fmt_10 = 0;
2899                         win->area[0].fbdc_fmt_cfg = 0x05;
2900                         break;
2901                 case FBDC_ARGB_888:
2902                         fmt_cfg = 0;
2903                         swap_rb = 0;
2904                         win->fmt_10 = 0;
2905                         win->area[0].fbdc_fmt_cfg = 0x0c;
2906                         break;
2907                 case FBDC_ABGR_888:
2908                         fmt_cfg = 0;
2909                         swap_rb = 1;
2910                         win->fmt_10 = 0;
2911                         win->area[0].fbdc_fmt_cfg = 0x0c;
2912                         break;
2913                 case FBDC_RGBX_888:
2914                         fmt_cfg = 0;
2915                         swap_rb = 0;
2916                         win->fmt_10 = 0;
2917                         win->area[0].fbdc_fmt_cfg = 0x3a;
2918                         break;
2919                 case ARGB888:
2920                         fmt_cfg = 0;
2921                         swap_rb = 0;
2922                         win->fmt_10 = 0;
2923                         break;
2924                 case XBGR888:
2925                 case ABGR888:
2926                         fmt_cfg = 0;
2927                         swap_rb = 1;
2928                         win->fmt_10 = 0;
2929                         break;
2930                 case RGB888:
2931                         fmt_cfg = 1;
2932                         swap_rb = 0;
2933                         win->fmt_10 = 0;
2934                         break;
2935                 case RGB565:
2936                         fmt_cfg = 2;
2937                         swap_rb = 0;
2938                         win->fmt_10 = 0;
2939                         break;
2940                 case YUV422:
2941                         fmt_cfg = 5;
2942                         swap_rb = 0;
2943                         win->fmt_10 = 0;
2944                         break;
2945                 case YUV420:
2946                         fmt_cfg = 4;
2947                         swap_rb = 0;
2948                         win->fmt_10 = 0;
2949                         break;
2950                 case YUV420_NV21:
2951                         fmt_cfg = 4;
2952                         swap_rb = 0;
2953                         swap_uv = 1;
2954                         win->fmt_10 = 0;
2955                         break;
2956                 case YUV444:
2957                         fmt_cfg = 6;
2958                         swap_rb = 0;
2959                         win->fmt_10 = 0;
2960                         break;
2961                 case YUV422_A:
2962                         fmt_cfg = 5;
2963                         swap_rb = 0;
2964                         win->fmt_10 = 1;
2965                         break;
2966                 case YUV420_A:
2967                         fmt_cfg = 4;
2968                         swap_rb = 0;
2969                         win->fmt_10 = 1;
2970                         break;
2971                 case YUV444_A:
2972                         fmt_cfg = 6;
2973                         swap_rb = 0;
2974                         win->fmt_10 = 1;
2975                         break;
2976                 default:
2977                         dev_err(lcdc_dev->driver.dev, "%s:unsupport format!\n",
2978                                 __func__);
2979                         break;
2980                 }
2981                 win->area[0].fmt_cfg = fmt_cfg;
2982                 win->area[0].swap_rb = swap_rb;
2983                 win->area[0].swap_uv = swap_uv;
2984                 win->area[0].dsp_stx = xpos;
2985                 win->area[0].dsp_sty = ypos;
2986                 xact = win->area[0].xact;
2987                 yact = win->area[0].yact;
2988                 xvir = win->area[0].xvir;
2989                 yvir = win->area[0].yvir;
2990         }
2991         if (win->area[0].fbdc_en)
2992                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
2993         rk3368_win_0_1_reg_update(&lcdc_dev->driver, win->id);
2994         spin_unlock(&lcdc_dev->reg_lock);
2995
2996         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2997             lcdc_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2998             xact, yact, win->area[0].xsize);
2999         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3000             win->area[0].ysize, xvir, yvir, xpos, ypos);
3001
3002         return 0;
3003 }
3004
3005
3006 static int win_2_3_set_par(struct lcdc_device *lcdc_dev,
3007                            struct rk_screen *screen, struct rk_lcdc_win *win)
3008 {
3009         int i;
3010         u8 fmt_cfg, swap_rb;
3011         char fmt[9] = "NULL";
3012
3013         if (win->mirror_en)
3014                 pr_err("win[%d] not support y mirror\n", win->id);
3015         spin_lock(&lcdc_dev->reg_lock);
3016         if (likely(lcdc_dev->clk_on)) {
3017                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", lcdc_dev->id, win->id);
3018                 for (i = 0; i < win->area_num; i++) {
3019                         switch (win->area[i].format) {
3020                         case FBDC_RGB_565:
3021                                 fmt_cfg = 2;
3022                                 swap_rb = 0;
3023                                 win->fmt_10 = 0;
3024                                 win->area[0].fbdc_fmt_cfg = 0x05;
3025                                 break;
3026                         case FBDC_ARGB_888:
3027                                 fmt_cfg = 0;
3028                                 swap_rb = 0;
3029                                 win->fmt_10 = 0;
3030                                 win->area[0].fbdc_fmt_cfg = 0x0c;
3031                                 break;
3032                         case FBDC_RGBX_888:
3033                                 fmt_cfg = 0;
3034                                 swap_rb = 0;
3035                                 win->fmt_10 = 0;
3036                                 win->area[0].fbdc_fmt_cfg = 0x3a;
3037                                 break;
3038                         case ARGB888:
3039                                 fmt_cfg = 0;
3040                                 swap_rb = 0;
3041                                 break;
3042                         case XBGR888:
3043                         case ABGR888:
3044                                 fmt_cfg = 0;
3045                                 swap_rb = 1;
3046                                 break;
3047                         case RGB888:
3048                                 fmt_cfg = 1;
3049                                 swap_rb = 0;
3050                                 break;
3051                         case RGB565:
3052                                 fmt_cfg = 2;
3053                                 swap_rb = 0;
3054                                 break;
3055                         default:
3056                                 dev_err(lcdc_dev->driver.dev,
3057                                         "%s:un supported format!\n", __func__);
3058                                 break;
3059                         }
3060                         win->area[i].fmt_cfg = fmt_cfg;
3061                         win->area[i].swap_rb = swap_rb;
3062                         win->area[i].dsp_stx =
3063                                         dsp_x_pos(win->mirror_en, screen,
3064                                                   &win->area[i]);
3065                         win->area[i].dsp_sty =
3066                                         dsp_y_pos(win->mirror_en, screen,
3067                                                   &win->area[i]);
3068                         if (((win->area[i].xact != win->area[i].xsize) ||
3069                             (win->area[i].yact != win->area[i].ysize)) &&
3070                             (screen->mode.vmode == FB_VMODE_NONINTERLACED)) {
3071                                 pr_err("win[%d]->area[%d],not support scale\n",
3072                                         win->id, i);
3073                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
3074                                         win->area[i].xact,win->area[i].yact,
3075                                         win->area[i].xsize,win->area[i].ysize);
3076                                 win->area[i].xsize = win->area[i].xact;
3077                                 win->area[i].ysize = win->area[i].yact;
3078                         }
3079                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
3080                             get_format_string(win->area[i].format, fmt),
3081                             win->area[i].xsize, win->area[i].ysize,
3082                             win->area[i].xpos, win->area[i].ypos);
3083                 }
3084         }
3085         if (win->area[0].fbdc_en)
3086                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
3087         rk3368_win_2_3_reg_update(&lcdc_dev->driver, win->id);
3088         spin_unlock(&lcdc_dev->reg_lock);
3089         return 0;
3090 }
3091
3092 static int hwc_set_par(struct lcdc_device *lcdc_dev,
3093                        struct rk_screen *screen, struct rk_lcdc_win *win)
3094 {
3095         u32 xact, yact, xvir, yvir, xpos, ypos;
3096         u8 fmt_cfg = 0, swap_rb;
3097         char fmt[9] = "NULL";
3098
3099         xpos = win->area[0].xpos + screen->mode.left_margin +
3100             screen->mode.hsync_len;
3101         ypos = win->area[0].ypos + screen->mode.upper_margin +
3102             screen->mode.vsync_len;
3103
3104         spin_lock(&lcdc_dev->reg_lock);
3105         if (likely(lcdc_dev->clk_on)) {
3106                 /*rk3368_lcdc_cal_scl_fac(win); *//*fac,lb,gt2,gt4 */
3107                 switch (win->area[0].format) {
3108                 case ARGB888:
3109                         fmt_cfg = 0;
3110                         swap_rb = 0;
3111                         break;
3112                 case XBGR888:
3113                 case ABGR888:
3114                         fmt_cfg = 0;
3115                         swap_rb = 1;
3116                         break;
3117                 case RGB888:
3118                         fmt_cfg = 1;
3119                         swap_rb = 0;
3120                         break;
3121                 case RGB565:
3122                         fmt_cfg = 2;
3123                         swap_rb = 0;
3124                         break;
3125                 default:
3126                         dev_err(lcdc_dev->driver.dev,
3127                                 "%s:un supported format!\n", __func__);
3128                         break;
3129                 }
3130                 win->area[0].fmt_cfg = fmt_cfg;
3131                 win->area[0].swap_rb = swap_rb;
3132                 win->area[0].dsp_stx = xpos;
3133                 win->area[0].dsp_sty = ypos;
3134                 xact = win->area[0].xact;
3135                 yact = win->area[0].yact;
3136                 xvir = win->area[0].xvir;
3137                 yvir = win->area[0].yvir;
3138         }
3139         rk3368_hwc_reg_update(&lcdc_dev->driver, 4);
3140         spin_unlock(&lcdc_dev->reg_lock);
3141
3142         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3143             lcdc_dev->id, __func__, get_format_string(win->area[0].format, fmt),
3144             xact, yact, win->area[0].xsize);
3145         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3146             win->area[0].ysize, xvir, yvir, xpos, ypos);
3147         return 0;
3148 }
3149
3150 static int rk3368_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
3151 {
3152         struct lcdc_device *lcdc_dev =
3153             container_of(dev_drv, struct lcdc_device, driver);
3154         struct rk_lcdc_win *win = NULL;
3155         struct rk_screen *screen = dev_drv->cur_screen;
3156
3157         if (unlikely(!lcdc_dev->clk_on)) {
3158                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
3159                 return 0;
3160         }
3161         win = dev_drv->win[win_id];
3162         switch (win_id) {
3163         case 0:
3164                 win_0_1_set_par(lcdc_dev, screen, win);
3165                 break;
3166         case 1:
3167                 win_0_1_set_par(lcdc_dev, screen, win);
3168                 break;
3169         case 2:
3170                 win_2_3_set_par(lcdc_dev, screen, win);
3171                 break;
3172         case 3:
3173                 win_2_3_set_par(lcdc_dev, screen, win);
3174                 break;
3175         case 4:
3176                 hwc_set_par(lcdc_dev, screen, win);
3177                 break;
3178         default:
3179                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
3180                 break;
3181         }
3182         return 0;
3183 }
3184
3185 static int rk3368_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3186                              unsigned long arg, int win_id)
3187 {
3188         struct lcdc_device *lcdc_dev =
3189             container_of(dev_drv, struct lcdc_device, driver);
3190         u32 panel_size[2];
3191         void __user *argp = (void __user *)arg;
3192         struct color_key_cfg clr_key_cfg;
3193
3194         switch (cmd) {
3195         case RK_FBIOGET_PANEL_SIZE:
3196                 panel_size[0] = lcdc_dev->screen->mode.xres;
3197                 panel_size[1] = lcdc_dev->screen->mode.yres;
3198                 if (copy_to_user(argp, panel_size, 8))
3199                         return -EFAULT;
3200                 break;
3201         case RK_FBIOPUT_COLOR_KEY_CFG:
3202                 if (copy_from_user(&clr_key_cfg, argp,
3203                                    sizeof(struct color_key_cfg)))
3204                         return -EFAULT;
3205                 rk3368_lcdc_clr_key_cfg(dev_drv);
3206                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
3207                             clr_key_cfg.win0_color_key_cfg);
3208                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
3209                             clr_key_cfg.win1_color_key_cfg);
3210                 break;
3211
3212         default:
3213                 break;
3214         }
3215         return 0;
3216 }
3217
3218 static int rk3368_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3219 {
3220         struct lcdc_device *lcdc_dev = container_of(dev_drv,
3221                                                     struct lcdc_device, driver);
3222         struct device_node *backlight;
3223         struct property *prop;
3224         u32 brightness_levels[256];
3225         u32 length, max, last;
3226
3227         if (lcdc_dev->backlight)
3228                 return 0;
3229         backlight = of_parse_phandle(lcdc_dev->dev->of_node, "backlight", 0);
3230         if (backlight) {
3231                 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
3232                 if (!lcdc_dev->backlight)
3233                         dev_info(lcdc_dev->dev, "No find backlight device\n");
3234         } else {
3235                 dev_info(lcdc_dev->dev, "No find backlight device node\n");
3236         }
3237         prop = of_find_property(backlight, "brightness-levels", &length);
3238         if (!prop)
3239                 return -EINVAL;
3240         max = length / sizeof(u32);
3241         last = max - 1;
3242         if (!of_property_read_u32_array(backlight, "brightness-levels", brightness_levels, max)) {
3243                 if (brightness_levels[0] > brightness_levels[last])
3244                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3245                 else
3246                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3247         } else {
3248                 dev_info(lcdc_dev->dev, "Can not read brightness-levels value\n");
3249         }
3250         return 0;
3251 }
3252
3253 static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
3254 {
3255         struct lcdc_device *lcdc_dev =
3256             container_of(dev_drv, struct lcdc_device, driver);
3257         if (dev_drv->suspend_flag)
3258                 return 0;
3259         /* close the backlight */
3260         /*rk3368_lcdc_get_backlight_device(dev_drv);
3261         if (lcdc_dev->backlight) {
3262                 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
3263                 backlight_update_status(lcdc_dev->backlight);
3264         }*/
3265
3266         dev_drv->suspend_flag = 1;
3267         flush_kthread_worker(&dev_drv->update_regs_worker);
3268
3269         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3270                 dev_drv->trsm_ops->disable();
3271
3272         spin_lock(&lcdc_dev->reg_lock);
3273         if (likely(lcdc_dev->clk_on)) {
3274                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3275                              v_DSP_BLANK_EN(1));
3276                 lcdc_msk_reg(lcdc_dev,
3277                              INTR_CLEAR, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR,
3278                              v_FS_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1));
3279                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3280                              v_DSP_OUT_ZERO(1));
3281                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(1));
3282                 lcdc_cfg_done(lcdc_dev);
3283
3284                 if (dev_drv->iommu_enabled) {
3285                         if (dev_drv->mmu_dev)
3286                                 rockchip_iovmm_deactivate(dev_drv->dev);
3287                 }
3288
3289                 spin_unlock(&lcdc_dev->reg_lock);
3290         } else {
3291                 spin_unlock(&lcdc_dev->reg_lock);
3292                 return 0;
3293         }
3294         rk3368_lcdc_clk_disable(lcdc_dev);
3295         rk_disp_pwr_disable(dev_drv);
3296         return 0;
3297 }
3298
3299 static int rk3368_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
3300 {
3301         struct lcdc_device *lcdc_dev =
3302             container_of(dev_drv, struct lcdc_device, driver);
3303
3304         if (!dev_drv->suspend_flag)
3305                 return 0;
3306         rk_disp_pwr_enable(dev_drv);
3307
3308         if (1/*lcdc_dev->atv_layer_cnt*/) {
3309                 rk3368_lcdc_clk_enable(lcdc_dev);
3310                 rk3368_lcdc_reg_restore(lcdc_dev);
3311
3312                 spin_lock(&lcdc_dev->reg_lock);
3313                 if (dev_drv->cur_screen->dsp_lut)
3314                         rk3368_lcdc_set_lut(dev_drv,
3315                                             dev_drv->cur_screen->dsp_lut);
3316                 if (dev_drv->cur_screen->cabc_lut && dev_drv->cabc_mode)
3317                         rk3368_set_cabc_lut(dev_drv,
3318                                             dev_drv->cur_screen->cabc_lut);
3319
3320                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3321                              v_DSP_OUT_ZERO(0));
3322                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
3323                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3324                              v_DSP_BLANK_EN(0));
3325                 lcdc_cfg_done(lcdc_dev);
3326
3327                 if (dev_drv->iommu_enabled) {
3328                         /* win address maybe effect after next frame start,
3329                          * but mmu maybe effect right now, so we delay 50ms
3330                          */
3331                         mdelay(50);
3332                         if (dev_drv->mmu_dev)
3333                                 rockchip_iovmm_activate(dev_drv->dev);
3334                 }
3335
3336                 spin_unlock(&lcdc_dev->reg_lock);
3337         }
3338         dev_drv->suspend_flag = 0;
3339
3340         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3341                 dev_drv->trsm_ops->enable();
3342         mdelay(100);
3343         return 0;
3344 }
3345
3346 static int rk3368_lcdc_blank(struct rk_lcdc_driver *dev_drv,
3347                              int win_id, int blank_mode)
3348 {
3349         switch (blank_mode) {
3350         case FB_BLANK_UNBLANK:
3351                 rk3368_lcdc_early_resume(dev_drv);
3352                 break;
3353         case FB_BLANK_NORMAL:
3354                 rk3368_lcdc_early_suspend(dev_drv);
3355                 break;
3356         default:
3357                 rk3368_lcdc_early_suspend(dev_drv);
3358                 break;
3359         }
3360
3361         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3362
3363         return 0;
3364 }
3365
3366 static int rk3368_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
3367                                            int win_id, int area_id)
3368 {
3369         struct lcdc_device *lcdc_dev =
3370             container_of(dev_drv, struct lcdc_device, driver);
3371         u32 win_ctrl = 0;
3372         u32 area_status = 0, state = 0;
3373
3374         switch (win_id) {
3375         case 0:
3376                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
3377                 area_status = win_ctrl & m_WIN0_EN;
3378                 break;
3379         case 1:
3380                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
3381                 area_status = win_ctrl & m_WIN1_EN;
3382                 break;
3383         case 2:
3384                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
3385                 if (area_id == 0)
3386                         area_status = win_ctrl & (m_WIN2_MST0_EN | m_WIN2_EN);
3387                 if (area_id == 1)
3388                         area_status = win_ctrl & m_WIN2_MST1_EN;
3389                 if (area_id == 2)
3390                         area_status = win_ctrl & m_WIN2_MST2_EN;
3391                 if (area_id == 3)
3392                         area_status = win_ctrl & m_WIN2_MST3_EN;
3393                 break;
3394         case 3:
3395                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
3396                 if (area_id == 0)
3397                         area_status = win_ctrl & (m_WIN3_MST0_EN | m_WIN3_EN);
3398                 if (area_id == 1)
3399                         area_status = win_ctrl & m_WIN3_MST1_EN;
3400                 if (area_id == 2)
3401                         area_status = win_ctrl & m_WIN3_MST2_EN;
3402                 if (area_id == 3)
3403                         area_status = win_ctrl & m_WIN3_MST3_EN;
3404                 break;
3405         case 4:
3406                 win_ctrl = lcdc_readl(lcdc_dev, HWC_CTRL0);
3407                 area_status = win_ctrl & m_HWC_EN;
3408                 break;
3409         default:
3410                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",__func__,win_id,area_id);
3411                 break;
3412         }
3413
3414         state = (area_status > 0) ? 1 : 0;
3415         return state;
3416 }
3417
3418 static int rk3368_lcdc_get_area_num(struct rk_lcdc_driver *dev_drv,
3419                                            unsigned int *area_support)
3420 {
3421         area_support[0] = 1;
3422         area_support[1] = 1;
3423         area_support[2] = 4;
3424         area_support[3] = 4;
3425
3426         return 0;
3427 }
3428
3429 /*overlay will be do at regupdate*/
3430 static int rk3368_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
3431                                bool set)
3432 {
3433         struct lcdc_device *lcdc_dev =
3434             container_of(dev_drv, struct lcdc_device, driver);
3435         struct rk_lcdc_win *win = NULL;
3436         int i, ovl;
3437         unsigned int mask, val;
3438         int z_order_num = 0;
3439         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3440
3441         if (swap == 0) {
3442                 for (i = 0; i < 4; i++) {
3443                         win = dev_drv->win[i];
3444                         if (win->state == 1)
3445                                 z_order_num++;
3446                 }
3447                 for (i = 0; i < 4; i++) {
3448                         win = dev_drv->win[i];
3449                         if (win->state == 0)
3450                                 win->z_order = z_order_num++;
3451                         switch (win->z_order) {
3452                         case 0:
3453                                 layer0_sel = win->id;
3454                                 break;
3455                         case 1:
3456                                 layer1_sel = win->id;
3457                                 break;
3458                         case 2:
3459                                 layer2_sel = win->id;
3460                                 break;
3461                         case 3:
3462                                 layer3_sel = win->id;
3463                                 break;
3464                         default:
3465                                 break;
3466                         }
3467                 }
3468         } else {
3469                 layer0_sel = swap % 10;
3470                 layer1_sel = swap / 10 % 10;
3471                 layer2_sel = swap / 100 % 10;
3472                 layer3_sel = swap / 1000;
3473         }
3474
3475         spin_lock(&lcdc_dev->reg_lock);
3476         if (lcdc_dev->clk_on) {
3477                 if (set) {
3478                         mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
3479                             m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
3480                         val = v_DSP_LAYER0_SEL(layer0_sel) |
3481                             v_DSP_LAYER1_SEL(layer1_sel) |
3482                             v_DSP_LAYER2_SEL(layer2_sel) |
3483                             v_DSP_LAYER3_SEL(layer3_sel);
3484                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
3485                 } else {
3486                         layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3487                                                    m_DSP_LAYER0_SEL);
3488                         layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3489                                                    m_DSP_LAYER1_SEL);
3490                         layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3491                                                    m_DSP_LAYER2_SEL);
3492                         layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3493                                                    m_DSP_LAYER3_SEL);
3494                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3495                             layer1_sel * 10 + layer0_sel;
3496                 }
3497         } else {
3498                 ovl = -EPERM;
3499         }
3500         spin_unlock(&lcdc_dev->reg_lock);
3501
3502         return ovl;
3503 }
3504
3505 static char *rk3368_lcdc_format_to_string(int format, char *fmt)
3506 {
3507         if (!fmt)
3508                 return NULL;
3509
3510         switch (format) {
3511         case 0:
3512                 strcpy(fmt, "ARGB888");
3513                 break;
3514         case 1:
3515                 strcpy(fmt, "RGB888");
3516                 break;
3517         case 2:
3518                 strcpy(fmt, "RGB565");
3519                 break;
3520         case 4:
3521                 strcpy(fmt, "YCbCr420");
3522                 break;
3523         case 5:
3524                 strcpy(fmt, "YCbCr422");
3525                 break;
3526         case 6:
3527                 strcpy(fmt, "YCbCr444");
3528                 break;
3529         default:
3530                 strcpy(fmt, "invalid\n");
3531                 break;
3532         }
3533         return fmt;
3534 }
3535 static ssize_t rk3368_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
3536                                          char *buf, int win_id)
3537 {
3538         struct lcdc_device *lcdc_dev =
3539             container_of(dev_drv, struct lcdc_device, driver);
3540         struct rk_screen *screen = dev_drv->cur_screen;
3541         u16 hsync_len = screen->mode.hsync_len;
3542         u16 left_margin = screen->mode.left_margin;
3543         u16 vsync_len = screen->mode.vsync_len;
3544         u16 upper_margin = screen->mode.upper_margin;
3545         u32 h_pw_bp = hsync_len + left_margin;
3546         u32 v_pw_bp = vsync_len + upper_margin;
3547         u32 fmt_id;
3548         char format_w0[9] = "NULL";
3549         char format_w1[9] = "NULL";
3550         char format_w2_0[9] = "NULL";
3551         char format_w2_1[9] = "NULL";
3552         char format_w2_2[9] = "NULL";
3553         char format_w2_3[9] = "NULL";
3554         char format_w3_0[9] = "NULL";
3555         char format_w3_1[9] = "NULL";
3556         char format_w3_2[9] = "NULL";
3557         char format_w3_3[9] = "NULL";
3558         char dsp_buf[100];
3559         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3560         u32 y_factor, uv_factor;
3561         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3562         u8 w0_state, w1_state, w2_state, w3_state;
3563         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3564         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3565
3566         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3567         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3568         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3569         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3570         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3571         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3572
3573         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3574         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3575         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3576         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3577         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3578         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3579         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3580
3581         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3582         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3583         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3584         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3585         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3586         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3587         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3588         u32 dclk_freq;
3589         int size = 0;
3590
3591         dclk_freq = screen->mode.pixclock;
3592         /*rk3368_lcdc_reg_dump(dev_drv); */
3593
3594         spin_lock(&lcdc_dev->reg_lock);
3595         if (lcdc_dev->clk_on) {
3596                 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
3597                 layer0_sel = (zorder & m_DSP_LAYER0_SEL) >> 8;
3598                 layer1_sel = (zorder & m_DSP_LAYER1_SEL) >> 10;
3599                 layer2_sel = (zorder & m_DSP_LAYER2_SEL) >> 12;
3600                 layer3_sel = (zorder & m_DSP_LAYER3_SEL) >> 14;
3601                 /*WIN0 */
3602                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
3603                 w0_state = win_ctrl & m_WIN0_EN;
3604                 fmt_id = (win_ctrl & m_WIN0_DATA_FMT) >> 1;
3605                 rk3368_lcdc_format_to_string(fmt_id, format_w0);
3606                 vir_info = lcdc_readl(lcdc_dev, WIN0_VIR);
3607                 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
3608                 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
3609                 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
3610                 y_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
3611                 uv_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_CBR);
3612                 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
3613                 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV) >> 16;
3614                 w0_act_x = (act_info & m_WIN0_ACT_WIDTH) + 1;
3615                 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT) >> 16) + 1;
3616                 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH) + 1;
3617                 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT) >> 16) + 1;
3618                 if (w0_state) {
3619                         w0_st_x = dsp_st & m_WIN0_DSP_XST;
3620                         w0_st_y = (dsp_st & m_WIN0_DSP_YST) >> 16;
3621                 }
3622                 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
3623                 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB) >> 16;
3624                 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
3625                 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR) >> 16;
3626
3627                 /*WIN1 */
3628                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
3629                 w1_state = win_ctrl & m_WIN1_EN;
3630                 fmt_id = (win_ctrl & m_WIN1_DATA_FMT) >> 1;
3631                 rk3368_lcdc_format_to_string(fmt_id, format_w1);
3632                 vir_info = lcdc_readl(lcdc_dev, WIN1_VIR);
3633                 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
3634                 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
3635                 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
3636                 y_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_YRGB);
3637                 uv_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_CBR);
3638                 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
3639                 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV) >> 16;
3640                 w1_act_x = (act_info & m_WIN1_ACT_WIDTH) + 1;
3641                 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT) >> 16) + 1;
3642                 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH) + 1;
3643                 w1_dsp_y = ((dsp_info & m_WIN1_DSP_HEIGHT) >> 16) + 1;
3644                 if (w1_state) {
3645                         w1_st_x = dsp_st & m_WIN1_DSP_XST;
3646                         w1_st_y = (dsp_st & m_WIN1_DSP_YST) >> 16;
3647                 }
3648                 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
3649                 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB) >> 16;
3650                 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
3651                 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR) >> 16;
3652                 /*WIN2 */
3653                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
3654                 w2_state = win_ctrl & m_WIN2_EN;
3655                 w2_0_state = (win_ctrl & 0x10) >> 4;
3656                 w2_1_state = (win_ctrl & 0x100) >> 8;
3657                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3658                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3659                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR0_1);
3660                 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
3661                 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1) >> 16;
3662                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR2_3);
3663                 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
3664                 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3) >> 16;
3665
3666                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT0) >> 1;
3667                 rk3368_lcdc_format_to_string(fmt_id, format_w2_0);
3668                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT1) >> 1;
3669                 rk3368_lcdc_format_to_string(fmt_id, format_w2_1);
3670                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT2) >> 1;
3671                 rk3368_lcdc_format_to_string(fmt_id, format_w2_2);
3672                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT3) >> 1;
3673                 rk3368_lcdc_format_to_string(fmt_id, format_w2_3);
3674
3675                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO0);
3676                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST0);
3677                 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0) + 1;
3678                 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0) >> 16) + 1;
3679                 if (w2_0_state) {
3680                         w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
3681                         w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0) >> 16;
3682                 }
3683                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO1);
3684                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST1);
3685                 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1) + 1;
3686                 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1) >> 16) + 1;
3687                 if (w2_1_state) {
3688                         w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
3689                         w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1) >> 16;
3690                 }
3691                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO2);
3692                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST2);
3693                 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2) + 1;
3694                 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2) >> 16) + 1;
3695                 if (w2_2_state) {
3696                         w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
3697                         w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2) >> 16;
3698                 }
3699                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO3);
3700                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST3);
3701                 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3) + 1;
3702                 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3) >> 16) + 1;
3703                 if (w2_3_state) {
3704                         w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
3705                         w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3) >> 16;
3706                 }
3707
3708                 /*WIN3 */
3709                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
3710                 w3_state = win_ctrl & m_WIN3_EN;
3711                 w3_0_state = (win_ctrl & m_WIN3_MST0_EN) >> 4;
3712                 w3_1_state = (win_ctrl & m_WIN3_MST1_EN) >> 8;
3713                 w3_2_state = (win_ctrl & m_WIN3_MST2_EN) >> 12;
3714                 w3_3_state = (win_ctrl & m_WIN3_MST3_EN) >> 16;
3715                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR0_1);
3716                 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
3717                 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1) >> 16;
3718                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR2_3);
3719                 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
3720                 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3) >> 16;
3721                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT0) >> 1;
3722                 rk3368_lcdc_format_to_string(fmt_id, format_w3_0);
3723                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT1) >> 1;
3724                 rk3368_lcdc_format_to_string(fmt_id, format_w3_1);
3725                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT2) >> 1;
3726                 rk3368_lcdc_format_to_string(fmt_id, format_w3_2);
3727                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT3) >> 1;
3728                 rk3368_lcdc_format_to_string(fmt_id, format_w3_3);
3729                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO0);
3730                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST0);
3731                 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0) + 1;
3732                 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0) >> 16) + 1;
3733                 if (w3_0_state) {
3734                         w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
3735                         w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0) >> 16;
3736                 }
3737
3738                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO1);
3739                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST1);
3740                 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1) + 1;
3741                 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1) >> 16) + 1;
3742                 if (w3_1_state) {
3743                         w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
3744                         w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1) >> 16;
3745                 }
3746
3747                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO2);
3748                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST2);
3749                 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2) + 1;
3750                 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2) >> 16) + 1;
3751                 if (w3_2_state) {
3752                         w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
3753                         w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2) >> 16;
3754                 }
3755
3756                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO3);
3757                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST3);
3758                 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3) + 1;
3759                 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3) >> 16) + 1;
3760                 if (w3_3_state) {
3761                         w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
3762                         w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3) >> 16;
3763                 }
3764
3765         } else {
3766                 spin_unlock(&lcdc_dev->reg_lock);
3767                 return -EPERM;
3768         }
3769         spin_unlock(&lcdc_dev->reg_lock);
3770         size += snprintf(dsp_buf, 80,
3771                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
3772                 layer3_sel, layer2_sel, layer1_sel, layer0_sel);
3773         strcat(buf, dsp_buf);
3774         memset(dsp_buf, 0, sizeof(dsp_buf));
3775         /*win0*/
3776         size += snprintf(dsp_buf, 80,
3777                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3778                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3779         strcat(buf, dsp_buf);
3780         memset(dsp_buf, 0, sizeof(dsp_buf));
3781
3782         size += snprintf(dsp_buf, 80,
3783                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3784                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3785         strcat(buf, dsp_buf);
3786         memset(dsp_buf, 0, sizeof(dsp_buf));
3787
3788         size += snprintf(dsp_buf, 80,
3789                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3790                  w0_st_x-h_pw_bp, w0_st_y-v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3791         strcat(buf, dsp_buf);
3792         memset(dsp_buf, 0, sizeof(dsp_buf));
3793
3794         size += snprintf(dsp_buf, 80,
3795                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3796                  w0_uv_h_fac, w0_uv_v_fac, lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
3797                  lcdc_readl(lcdc_dev, WIN0_CBR_MST));
3798         strcat(buf, dsp_buf);
3799         memset(dsp_buf, 0, sizeof(dsp_buf));
3800
3801         /*win1*/
3802         size += snprintf(dsp_buf, 80,
3803                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3804                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3805         strcat(buf, dsp_buf);
3806         memset(dsp_buf, 0, sizeof(dsp_buf));
3807
3808         size += snprintf(dsp_buf, 80,
3809                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3810                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3811         strcat(buf, dsp_buf);
3812         memset(dsp_buf, 0, sizeof(dsp_buf));
3813
3814         size += snprintf(dsp_buf, 80,
3815                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3816                  w1_st_x-h_pw_bp, w1_st_y-v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3817         strcat(buf, dsp_buf);
3818         memset(dsp_buf, 0, sizeof(dsp_buf));
3819
3820         size += snprintf(dsp_buf, 80,
3821                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3822                  w1_uv_h_fac, w1_uv_v_fac, lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
3823                  lcdc_readl(lcdc_dev, WIN1_CBR_MST));
3824         strcat(buf, dsp_buf);
3825         memset(dsp_buf, 0, sizeof(dsp_buf));
3826
3827         /*win2*/
3828         size += snprintf(dsp_buf, 80,
3829                  "win2:\n  state:%d\n",
3830                  w2_state);
3831         strcat(buf, dsp_buf);
3832         memset(dsp_buf, 0, sizeof(dsp_buf));
3833         /*area 0*/
3834         size += snprintf(dsp_buf, 80,
3835                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3836                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
3837         strcat(buf, dsp_buf);
3838         memset(dsp_buf, 0, sizeof(dsp_buf));
3839         size += snprintf(dsp_buf, 80,
3840                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3841                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
3842                  lcdc_readl(lcdc_dev, WIN2_MST0));
3843         strcat(buf, dsp_buf);
3844         memset(dsp_buf, 0, sizeof(dsp_buf));
3845
3846         /*area 1*/
3847         size += snprintf(dsp_buf, 80,
3848                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3849                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
3850         strcat(buf, dsp_buf);
3851         memset(dsp_buf, 0, sizeof(dsp_buf));
3852         size += snprintf(dsp_buf, 80,
3853                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3854                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
3855                  lcdc_readl(lcdc_dev, WIN2_MST1));
3856         strcat(buf, dsp_buf);
3857         memset(dsp_buf, 0, sizeof(dsp_buf));
3858
3859         /*area 2*/
3860         size += snprintf(dsp_buf, 80,
3861                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3862                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
3863         strcat(buf, dsp_buf);
3864         memset(dsp_buf, 0, sizeof(dsp_buf));
3865         size += snprintf(dsp_buf, 80,
3866                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3867                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
3868                  lcdc_readl(lcdc_dev, WIN2_MST2));
3869         strcat(buf, dsp_buf);
3870         memset(dsp_buf, 0, sizeof(dsp_buf));
3871
3872         /*area 3*/
3873         size += snprintf(dsp_buf, 80,
3874                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3875                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
3876         strcat(buf, dsp_buf);
3877         memset(dsp_buf, 0, sizeof(dsp_buf));
3878         size += snprintf(dsp_buf, 80,
3879                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3880                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
3881                  lcdc_readl(lcdc_dev, WIN2_MST3));
3882         strcat(buf, dsp_buf);
3883         memset(dsp_buf, 0, sizeof(dsp_buf));
3884
3885         /*win3*/
3886         size += snprintf(dsp_buf, 80,
3887                  "win3:\n  state:%d\n",
3888                  w3_state);
3889         strcat(buf, dsp_buf);
3890         memset(dsp_buf, 0, sizeof(dsp_buf));
3891         /*area 0*/
3892         size += snprintf(dsp_buf, 80,
3893                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3894                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
3895         strcat(buf, dsp_buf);
3896         memset(dsp_buf, 0, sizeof(dsp_buf));
3897         size += snprintf(dsp_buf, 80,
3898                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3899                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
3900                  lcdc_readl(lcdc_dev, WIN3_MST0));
3901         strcat(buf, dsp_buf);
3902         memset(dsp_buf, 0, sizeof(dsp_buf));
3903
3904         /*area 1*/
3905         size += snprintf(dsp_buf, 80,
3906                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3907                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
3908         strcat(buf, dsp_buf);
3909         memset(dsp_buf, 0, sizeof(dsp_buf));
3910         size += snprintf(dsp_buf, 80,
3911                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3912                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
3913                  lcdc_readl(lcdc_dev, WIN3_MST1));
3914         strcat(buf, dsp_buf);
3915         memset(dsp_buf, 0, sizeof(dsp_buf));
3916
3917         /*area 2*/
3918         size += snprintf(dsp_buf, 80,
3919                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3920                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
3921         strcat(buf, dsp_buf);
3922         memset(dsp_buf, 0, sizeof(dsp_buf));
3923         size += snprintf(dsp_buf, 80,
3924                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3925                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
3926                  lcdc_readl(lcdc_dev, WIN3_MST2));
3927         strcat(buf, dsp_buf);
3928         memset(dsp_buf, 0, sizeof(dsp_buf));
3929
3930         /*area 3*/
3931         size += snprintf(dsp_buf, 80,
3932                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3933                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
3934         strcat(buf, dsp_buf);
3935         memset(dsp_buf, 0, sizeof(dsp_buf));
3936         size += snprintf(dsp_buf, 80,
3937                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3938                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
3939                  lcdc_readl(lcdc_dev, WIN3_MST3));
3940         strcat(buf, dsp_buf);
3941         memset(dsp_buf, 0, sizeof(dsp_buf));
3942
3943         return size;
3944 }
3945
3946 static int rk3368_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
3947                                bool set)
3948 {
3949         struct lcdc_device *lcdc_dev =
3950             container_of(dev_drv, struct lcdc_device, driver);
3951         struct rk_screen *screen = dev_drv->cur_screen;
3952         u64 ft = 0;
3953         u32 dotclk;
3954         int ret;
3955         u32 pixclock;
3956         u32 x_total, y_total;
3957
3958         if (set) {
3959                 if (fps == 0) {
3960                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3961                         return 0;
3962                 }
3963                 ft = div_u64(1000000000000llu, fps);
3964                 x_total =
3965                     screen->mode.upper_margin + screen->mode.lower_margin +
3966                     screen->mode.yres + screen->mode.vsync_len;
3967                 y_total =
3968                     screen->mode.left_margin + screen->mode.right_margin +
3969                     screen->mode.xres + screen->mode.hsync_len;
3970                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3971                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3972                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
3973         }
3974
3975         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
3976         lcdc_dev->pixclock = pixclock;
3977         dev_drv->pixclock = lcdc_dev->pixclock;
3978         fps = rk_fb_calc_fps(screen, pixclock);
3979         screen->ft = 1000 / fps;        /*one frame time in ms */
3980
3981         if (set)
3982                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
3983                          clk_get_rate(lcdc_dev->dclk), fps);
3984
3985         return fps;
3986 }
3987
3988 static int rk3368_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
3989 {
3990         mutex_lock(&dev_drv->fb_win_id_mutex);
3991         if (order == FB_DEFAULT_ORDER)
3992                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
3993         dev_drv->fb4_win_id = order / 10000;
3994         dev_drv->fb3_win_id = (order / 1000) % 10;
3995         dev_drv->fb2_win_id = (order / 100) % 10;
3996         dev_drv->fb1_win_id = (order / 10) % 10;
3997         dev_drv->fb0_win_id = order % 10;
3998         mutex_unlock(&dev_drv->fb_win_id_mutex);
3999
4000         return 0;
4001 }
4002
4003 static int rk3368_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
4004                                   const char *id)
4005 {
4006         int win_id = 0;
4007
4008         mutex_lock(&dev_drv->fb_win_id_mutex);
4009         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
4010                 win_id = dev_drv->fb0_win_id;
4011         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
4012                 win_id = dev_drv->fb1_win_id;
4013         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
4014                 win_id = dev_drv->fb2_win_id;
4015         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
4016                 win_id = dev_drv->fb3_win_id;
4017         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
4018                 win_id = dev_drv->fb4_win_id;
4019         mutex_unlock(&dev_drv->fb_win_id_mutex);
4020
4021         return win_id;
4022 }
4023
4024 static int rk3368_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
4025 {
4026         struct lcdc_device *lcdc_dev =
4027             container_of(dev_drv, struct lcdc_device, driver);
4028         int i;
4029         unsigned int mask, val;
4030         struct rk_lcdc_win *win = NULL;
4031         u32 line_scane_num, dsp_vs_st_f1;
4032
4033         if (lcdc_dev->driver.cur_screen->mode.vmode == FB_VMODE_INTERLACED) {
4034                 dsp_vs_st_f1 = lcdc_readl(lcdc_dev, DSP_VS_ST_END_F1) >> 16;
4035                 for (i = 0; i < 1000; i++) {
4036                         line_scane_num =
4037                                 lcdc_readl(lcdc_dev, SCAN_LINE_NUM) & 0x1fff;
4038                         if (line_scane_num > dsp_vs_st_f1 + 1)
4039                                 udelay(50);
4040                         else
4041                                 break;
4042                 }
4043         }
4044
4045         spin_lock(&lcdc_dev->reg_lock);
4046         rk3368_lcdc_post_cfg(dev_drv);
4047         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
4048                      v_STANDBY_EN(lcdc_dev->standby));
4049         for (i = 0; i < 4; i++) {
4050                 win = dev_drv->win[i];
4051                 if ((win->state == 0) && (win->last_state == 1)) {
4052                         switch (win->id) {
4053                         case 0:
4054                                 /*lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
4055                                    for rk3288 to fix hw bug? */
4056                                 mask = m_WIN0_EN;
4057                                 val = v_WIN0_EN(0);
4058                                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
4059                                 break;
4060                         case 1:
4061                                 /*lcdc_writel(lcdc_dev,WIN1_CTRL1,0x0);
4062                                    for rk3288 to fix hw bug? */
4063                                 mask = m_WIN1_EN;
4064                                 val = v_WIN1_EN(0);
4065                                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
4066                                 break;
4067                         case 2:
4068                                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
4069                                     m_WIN2_MST1_EN |
4070                                     m_WIN2_MST2_EN | m_WIN2_MST3_EN;
4071                                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
4072                                     v_WIN2_MST1_EN(0) |
4073                                     v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
4074                                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
4075                                 break;
4076                         case 3:
4077                                 mask = m_WIN3_EN | m_WIN3_MST0_EN |
4078                                     m_WIN3_MST1_EN |
4079                                     m_WIN3_MST2_EN | m_WIN3_MST3_EN;
4080                                 val = v_WIN3_EN(0) | v_WIN3_MST0_EN(0) |
4081                                     v_WIN3_MST1_EN(0) |
4082                                     v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
4083                                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
4084                                 break;
4085                         case 4:
4086                                 mask = m_HWC_EN;
4087                                 val = v_HWC_EN(0);
4088                                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
4089                                 break;
4090                         default:
4091                                 break;
4092                         }
4093                 }
4094                 win->last_state = win->state;
4095         }
4096         lcdc_cfg_done(lcdc_dev);
4097         spin_unlock(&lcdc_dev->reg_lock);
4098         return 0;
4099 }
4100
4101 static int rk3368_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
4102 {
4103         struct lcdc_device *lcdc_dev =
4104             container_of(dev_drv, struct lcdc_device, driver);
4105         spin_lock(&lcdc_dev->reg_lock);
4106         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
4107                      v_DIRECT_PATH_EN(open));
4108         lcdc_cfg_done(lcdc_dev);
4109         spin_unlock(&lcdc_dev->reg_lock);
4110         return 0;
4111 }
4112
4113 static int rk3368_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
4114 {
4115         struct lcdc_device *lcdc_dev = container_of(dev_drv,
4116                                                     struct lcdc_device, driver);
4117         spin_lock(&lcdc_dev->reg_lock);
4118         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
4119                      v_DIRECT_PATCH_SEL(win_id));
4120         lcdc_cfg_done(lcdc_dev);
4121         spin_unlock(&lcdc_dev->reg_lock);
4122         return 0;
4123 }
4124
4125 static int rk3368_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
4126 {
4127         struct lcdc_device *lcdc_dev =
4128             container_of(dev_drv, struct lcdc_device, driver);
4129         int ovl;
4130
4131         spin_lock(&lcdc_dev->reg_lock);
4132         ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
4133         spin_unlock(&lcdc_dev->reg_lock);
4134         return ovl;
4135 }
4136
4137 static int rk3368_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
4138                                       int enable)
4139 {
4140         struct lcdc_device *lcdc_dev =
4141             container_of(dev_drv, struct lcdc_device, driver);
4142         if (enable)
4143                 enable_irq(lcdc_dev->irq);
4144         else
4145                 disable_irq(lcdc_dev->irq);
4146         return 0;
4147 }
4148
4149 int rk3368_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
4150 {
4151         struct lcdc_device *lcdc_dev =
4152             container_of(dev_drv, struct lcdc_device, driver);
4153         u32 int_reg;
4154         int ret;
4155
4156         if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
4157                 int_reg = lcdc_readl(lcdc_dev, INTR_STATUS);
4158                 if (int_reg & m_LINE_FLAG0_INTR_STS) {
4159                         lcdc_dev->driver.frame_time.last_framedone_t =
4160                             lcdc_dev->driver.frame_time.framedone_t;
4161                         lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
4162                         lcdc_msk_reg(lcdc_dev, INTR_CLEAR,
4163                                      m_LINE_FLAG0_INTR_CLR,
4164                                      v_LINE_FLAG0_INTR_CLR(1));
4165                         ret = RK_LF_STATUS_FC;
4166                 } else {
4167                         ret = RK_LF_STATUS_FR;
4168                 }
4169         } else {
4170                 ret = RK_LF_STATUS_NC;
4171         }
4172
4173         return ret;
4174 }
4175
4176 static int rk3368_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
4177                                     unsigned int dsp_addr[][4])
4178 {
4179         struct lcdc_device *lcdc_dev =
4180             container_of(dev_drv, struct lcdc_device, driver);
4181         spin_lock(&lcdc_dev->reg_lock);
4182         if (lcdc_dev->clk_on) {
4183                 dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
4184                 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
4185                 dsp_addr[2][0] = lcdc_readl(lcdc_dev, WIN2_MST0);
4186                 dsp_addr[2][1] = lcdc_readl(lcdc_dev, WIN2_MST1);
4187                 dsp_addr[2][2] = lcdc_readl(lcdc_dev, WIN2_MST2);
4188                 dsp_addr[2][3] = lcdc_readl(lcdc_dev, WIN2_MST3);
4189                 dsp_addr[3][0] = lcdc_readl(lcdc_dev, WIN3_MST0);
4190                 dsp_addr[3][1] = lcdc_readl(lcdc_dev, WIN3_MST1);
4191                 dsp_addr[3][2] = lcdc_readl(lcdc_dev, WIN3_MST2);
4192                 dsp_addr[3][3] = lcdc_readl(lcdc_dev, WIN3_MST3);
4193         }
4194         spin_unlock(&lcdc_dev->reg_lock);
4195         return 0;
4196 }
4197 static u32 pwm_period_hpr, pwm_duty_lpr;
4198 static u32 cabc_status = 0;
4199
4200 int rk3368_lcdc_update_pwm(int bl_pwm_period, int bl_pwm_duty)
4201 {
4202         pwm_period_hpr = bl_pwm_period;
4203         pwm_duty_lpr = bl_pwm_duty;
4204         /*pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
4205         bl_pwm_period, bl_pwm_duty);*/
4206         return 0;
4207 }
4208
4209 int rk3368_lcdc_cabc_status(void)
4210 {
4211         return cabc_status;
4212 }
4213
4214 static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,
4215                                     int mode, int calc, int up,
4216                                     int down, int global)
4217 {
4218         struct lcdc_device *lcdc_dev =
4219             container_of(dev_drv, struct lcdc_device, driver);
4220         struct rk_screen *screen = dev_drv->cur_screen;
4221         u32 total_pixel, calc_pixel, stage_up, stage_down;
4222         u32 pixel_num, global_su;
4223         u32 stage_up_rec, stage_down_rec, global_su_rec, gamma_global_su_rec;
4224         u32 mask = 0, val = 0, cabc_en = 0;
4225         int *cabc_lut = NULL;
4226
4227         if (!screen->cabc_lut) {
4228                 pr_err("screen cabc lut not config, so not open cabc\n");
4229                 return 0;
4230         } else {
4231                 cabc_lut = screen->cabc_lut;
4232         }
4233
4234         if (!screen->cabc_gamma_base) {
4235                 pr_err("screen cabc_gamma_base no config, so not open cabc\n");
4236                 return 0;
4237         }
4238         dev_drv->cabc_mode = mode;
4239         cabc_en = (mode > 0) ? 1 : 0;
4240         rk3368_lcdc_get_backlight_device(dev_drv);
4241         if (cabc_en == 0) {
4242                 spin_lock(&lcdc_dev->reg_lock);
4243                 if (lcdc_dev->clk_on) {
4244                         lcdc_msk_reg(lcdc_dev, CABC_CTRL0,
4245                                      m_CABC_EN, v_CABC_EN(0));
4246                         lcdc_cfg_done(lcdc_dev);
4247                 }
4248                 pr_info("mode = 0, close cabc\n");
4249                 rk_pwm_set(pwm_period_hpr, pwm_duty_lpr);
4250                 cabc_status = 0;
4251                 spin_unlock(&lcdc_dev->reg_lock);
4252                 return 0;
4253         }
4254         if (cabc_status == 0) { /*get from pwm*/
4255                 rk3368_set_cabc_lut(dev_drv, dev_drv->cur_screen->cabc_lut);
4256                 rk_pwm_get(&pwm_period_hpr, &pwm_duty_lpr);
4257                 pr_info("pwm_period_hpr=0x%x, pwm_duty_lpr=0x%x\n",
4258                         pwm_period_hpr, pwm_duty_lpr);
4259         }
4260
4261         total_pixel = screen->mode.xres * screen->mode.yres;
4262         pixel_num = 1000 - calc;
4263         calc_pixel = (total_pixel * pixel_num) / 1000;
4264         stage_up = up;
4265         stage_down = down;
4266         global_su = global;
4267         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
4268                 mode, calc, stage_up, stage_down, global_su);
4269
4270         stage_up_rec = 256 * 256 / stage_up;
4271         stage_down_rec = 256 * 256 / stage_down;
4272         global_su_rec = (256 * 256 / global_su);
4273         gamma_global_su_rec = cabc_lut[global_su_rec];
4274
4275         spin_lock(&lcdc_dev->reg_lock);
4276         if (lcdc_dev->clk_on) {
4277                 mask = m_CABC_CALC_PIXEL_NUM | m_CABC_EN;
4278                 val = v_CABC_CALC_PIXEL_NUM(calc_pixel) |
4279                         v_CABC_EN(cabc_en);
4280                 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
4281
4282                 mask = m_CABC_TOTAL_PIXEL_NUM | m_CABC_LUT_EN;
4283                 val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(1);
4284                 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
4285
4286                 mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC |
4287                     m_CABC_GLOBAL_SU_LIMIT_EN | m_CABC_GLOBAL_SU_REC;
4288                 val = v_CABC_STAGE_UP(stage_up) |
4289                     v_CABC_STAGE_UP_REC(stage_up_rec) |
4290                     v_CABC_GLOBAL_SU_LIMIT_EN(1) |
4291                     v_CABC_GLOBAL_SU_REC(gamma_global_su_rec);
4292                 lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val);
4293
4294                 mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC |
4295                     m_CABC_GLOBAL_SU;
4296                 val = v_CABC_STAGE_DOWN(stage_down) |
4297                     v_CABC_STAGE_DOWN_REC(stage_down_rec) |
4298                     v_CABC_GLOBAL_SU(global_su);
4299                 lcdc_msk_reg(lcdc_dev, CABC_CTRL3, mask, val);
4300                 lcdc_cfg_done(lcdc_dev);
4301         }
4302         cabc_status = 1;
4303         spin_unlock(&lcdc_dev->reg_lock);
4304
4305         return 0;
4306 }
4307
4308 /*
4309         a:[-30~0]:
4310             sin_hue = sin(a)*256 +0x100;
4311             cos_hue = cos(a)*256;
4312         a:[0~30]
4313             sin_hue = sin(a)*256;
4314             cos_hue = cos(a)*256;
4315 */
4316 static int rk3368_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4317                                     bcsh_hue_mode mode)
4318 {
4319         struct lcdc_device *lcdc_dev =
4320             container_of(dev_drv, struct lcdc_device, driver);
4321         u32 val;
4322
4323         spin_lock(&lcdc_dev->reg_lock);
4324         if (lcdc_dev->clk_on) {
4325                 val = lcdc_readl(lcdc_dev, BCSH_H);
4326                 switch (mode) {
4327                 case H_SIN:
4328                         val &= m_BCSH_SIN_HUE;
4329                         break;
4330                 case H_COS:
4331                         val &= m_BCSH_COS_HUE;
4332                         val >>= 16;
4333                         break;
4334                 default:
4335                         break;
4336                 }
4337         }
4338         spin_unlock(&lcdc_dev->reg_lock);
4339
4340         return val;
4341 }
4342
4343 static int rk3368_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4344                                     int sin_hue, int cos_hue)
4345 {
4346         struct lcdc_device *lcdc_dev =
4347             container_of(dev_drv, struct lcdc_device, driver);
4348         u32 mask, val;
4349
4350         spin_lock(&lcdc_dev->reg_lock);
4351         if (lcdc_dev->clk_on) {
4352                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
4353                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
4354                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
4355                 lcdc_cfg_done(lcdc_dev);
4356         }
4357         spin_unlock(&lcdc_dev->reg_lock);
4358
4359         return 0;
4360 }
4361
4362 static int rk3368_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4363                                     bcsh_bcs_mode mode, int value)
4364 {
4365         struct lcdc_device *lcdc_dev =
4366             container_of(dev_drv, struct lcdc_device, driver);
4367         u32 mask, val;
4368
4369         spin_lock(&lcdc_dev->reg_lock);
4370         if (lcdc_dev->clk_on) {
4371                 switch (mode) {
4372                 case BRIGHTNESS:
4373                         /*from 0 to 255,typical is 128 */
4374                         if (value < 0x80)
4375                                 value += 0x80;
4376                         else if (value >= 0x80)
4377                                 value = value - 0x80;
4378                         mask = m_BCSH_BRIGHTNESS;
4379                         val = v_BCSH_BRIGHTNESS(value);
4380                         break;
4381                 case CONTRAST:
4382                         /*from 0 to 510,typical is 256 */
4383                         mask = m_BCSH_CONTRAST;
4384                         val = v_BCSH_CONTRAST(value);
4385                         break;
4386                 case SAT_CON:
4387                         /*from 0 to 1015,typical is 256 */
4388                         mask = m_BCSH_SAT_CON;
4389                         val = v_BCSH_SAT_CON(value);
4390                         break;
4391                 default:
4392                         break;
4393                 }
4394                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
4395                 lcdc_cfg_done(lcdc_dev);
4396         }
4397         spin_unlock(&lcdc_dev->reg_lock);
4398         return val;
4399 }
4400
4401 static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4402                                     bcsh_bcs_mode mode)
4403 {
4404         struct lcdc_device *lcdc_dev =
4405             container_of(dev_drv, struct lcdc_device, driver);
4406         u32 val;
4407
4408         spin_lock(&lcdc_dev->reg_lock);
4409         if (lcdc_dev->clk_on) {
4410                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
4411                 switch (mode) {
4412                 case BRIGHTNESS:
4413                         val &= m_BCSH_BRIGHTNESS;
4414                         if (val > 0x80)
4415                                 val -= 0x80;
4416                         else
4417                                 val += 0x80;
4418                         break;
4419                 case CONTRAST:
4420                         val &= m_BCSH_CONTRAST;
4421                         val >>= 8;
4422                         break;
4423                 case SAT_CON:
4424                         val &= m_BCSH_SAT_CON;
4425                         val >>= 20;
4426                         break;
4427                 default:
4428                         break;
4429                 }
4430         }
4431         spin_unlock(&lcdc_dev->reg_lock);
4432         return val;
4433 }
4434
4435 static int rk3368_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4436 {
4437         struct lcdc_device *lcdc_dev =
4438             container_of(dev_drv, struct lcdc_device, driver);
4439         u32 mask, val;
4440
4441         spin_lock(&lcdc_dev->reg_lock);
4442         if (lcdc_dev->clk_on) {
4443                 if (open) {
4444                         lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 0x1);
4445                         lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
4446                         lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
4447                         dev_drv->bcsh.enable = 1;
4448                 } else {
4449                         mask = m_BCSH_EN;
4450                         val = v_BCSH_EN(0);
4451                         lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
4452                         dev_drv->bcsh.enable = 0;
4453                 }
4454                 rk3368_lcdc_bcsh_path_sel(dev_drv);
4455                 lcdc_cfg_done(lcdc_dev);
4456         }
4457         spin_unlock(&lcdc_dev->reg_lock);
4458         return 0;
4459 }
4460
4461 static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4462 {
4463         if (!enable || !dev_drv->bcsh.enable) {
4464                 rk3368_lcdc_open_bcsh(dev_drv, false);
4465                 return 0;
4466         }
4467
4468         if (dev_drv->bcsh.brightness <= 255 ||
4469             dev_drv->bcsh.contrast <= 510 ||
4470             dev_drv->bcsh.sat_con <= 1015 ||
4471             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4472                 rk3368_lcdc_open_bcsh(dev_drv, true);
4473                 if (dev_drv->bcsh.brightness <= 255)
4474                         rk3368_lcdc_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4475                                                  dev_drv->bcsh.brightness);
4476                 if (dev_drv->bcsh.contrast <= 510)
4477                         rk3368_lcdc_set_bcsh_bcs(dev_drv, CONTRAST,
4478                                                  dev_drv->bcsh.contrast);
4479                 if (dev_drv->bcsh.sat_con <= 1015)
4480                         rk3368_lcdc_set_bcsh_bcs(dev_drv, SAT_CON,
4481                                                  dev_drv->bcsh.sat_con);
4482                 if (dev_drv->bcsh.sin_hue <= 511 &&
4483                     dev_drv->bcsh.cos_hue <= 511)
4484                         rk3368_lcdc_set_bcsh_hue(dev_drv,
4485                                                  dev_drv->bcsh.sin_hue,
4486                                                  dev_drv->bcsh.cos_hue);
4487         }
4488         return 0;
4489 }
4490
4491 static int __maybe_unused
4492 rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4493 {
4494         struct lcdc_device *lcdc_dev =
4495             container_of(dev_drv, struct lcdc_device, driver);
4496
4497         if (enable) {
4498                 spin_lock(&lcdc_dev->reg_lock);
4499                 if (likely(lcdc_dev->clk_on)) {
4500                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4501                                      v_DSP_BLACK_EN(1));
4502                         lcdc_cfg_done(lcdc_dev);
4503                 }
4504                 spin_unlock(&lcdc_dev->reg_lock);
4505         } else {
4506                 spin_lock(&lcdc_dev->reg_lock);
4507                 if (likely(lcdc_dev->clk_on)) {
4508                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4509                                      v_DSP_BLACK_EN(0));
4510
4511                         lcdc_cfg_done(lcdc_dev);
4512                 }
4513                 spin_unlock(&lcdc_dev->reg_lock);
4514         }
4515
4516         return 0;
4517 }
4518
4519
4520 static int rk3368_lcdc_wait_frame_start(struct rk_lcdc_driver *dev_drv,
4521                                          int enable)
4522 {
4523         u32 line_scane_num, vsync_end, vact_end;
4524         u32 interlace_mode;
4525
4526         struct lcdc_device *lcdc_dev =
4527             container_of(dev_drv, struct lcdc_device, driver);
4528
4529         if (unlikely(!lcdc_dev->clk_on)) {
4530                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
4531                 return 0;
4532         }
4533         if (0 == enable) {
4534                 interlace_mode = lcdc_read_bit(lcdc_dev, DSP_CTRL0,
4535                                                m_DSP_INTERLACE);
4536                 if (interlace_mode) {
4537                         vsync_end = lcdc_readl(lcdc_dev, DSP_VS_ST_END_F1) &
4538                                         m_DSP_VS_END_F1;
4539                         vact_end = lcdc_readl(lcdc_dev, DSP_VACT_ST_END_F1) &
4540                                         m_DSP_VACT_END_F1;
4541                 } else {
4542                         vsync_end = lcdc_readl(lcdc_dev, DSP_VTOTAL_VS_END) &
4543                                         m_DSP_VS_PW;
4544                         vact_end = lcdc_readl(lcdc_dev, DSP_VACT_ST_END) &
4545                                         m_DSP_VACT_END;
4546                 }
4547                 while (1) {
4548                         line_scane_num = lcdc_readl(lcdc_dev, SCAN_LINE_NUM) &
4549                                         0x1fff;
4550                         if ((line_scane_num > vsync_end) &&
4551                             (line_scane_num <= vact_end - 100))
4552                                 break;
4553                 }
4554                 return 0;
4555         } else if (1 == enable) {
4556                 line_scane_num = lcdc_readl(lcdc_dev, SCAN_LINE_NUM) & 0x1fff;
4557                 return line_scane_num;
4558         }
4559
4560         return 0;
4561 }
4562
4563 static int rk3368_lcdc_backlight_close(struct rk_lcdc_driver *dev_drv,
4564                                        int enable)
4565 {
4566         struct lcdc_device *lcdc_dev =
4567             container_of(dev_drv, struct lcdc_device, driver);
4568
4569         if (unlikely(!lcdc_dev->clk_on)) {
4570                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
4571                 return 0;
4572         }
4573         rk3368_lcdc_get_backlight_device(dev_drv);
4574
4575         if (enable) {
4576                 /* close the backlight */
4577                 if (lcdc_dev->backlight) {
4578                         lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4579                         backlight_update_status(lcdc_dev->backlight);
4580                 }
4581                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4582                         dev_drv->trsm_ops->disable();
4583         } else {
4584                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4585                         dev_drv->trsm_ops->enable();
4586                 msleep(100);
4587                 /* open the backlight */
4588                 if (lcdc_dev->backlight) {
4589                         lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
4590                         backlight_update_status(lcdc_dev->backlight);
4591                 }
4592         }
4593
4594         return 0;
4595 }
4596
4597 static int rk3368_lcdc_set_overscan(struct rk_lcdc_driver *dev_drv,
4598                                     struct overscan *overscan)
4599 {
4600         struct lcdc_device *lcdc_dev =
4601             container_of(dev_drv, struct lcdc_device, driver);
4602
4603         if (unlikely(!lcdc_dev->clk_on)) {
4604                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
4605                 return 0;
4606         }
4607         /*rk3368_lcdc_post_cfg(dev_drv);*/
4608
4609         return 0;
4610 }
4611
4612 static int rk3368_lcdc_extern_func(struct rk_lcdc_driver *dev_drv,
4613                                         int cmd)
4614 {
4615         struct lcdc_device *lcdc_dev =
4616             container_of(dev_drv, struct lcdc_device, driver);
4617         u32 val;
4618
4619         if (unlikely(!lcdc_dev->clk_on)) {
4620                 pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
4621                 return 0;
4622         }
4623
4624         switch (cmd) {
4625         case GET_PAGE_FAULT:
4626                 val = lcdc_readl(lcdc_dev, MMU_INT_RAWSTAT);
4627                 if ((val & 0x1) == 1) {
4628                         if ((val & 0x2) == 1)
4629                                 pr_info("val = 0x%x, vop iommu bus error\n", val);
4630                         else
4631                                 return 1;
4632                 }
4633                 break;
4634         case CLR_PAGE_FAULT:
4635                 lcdc_writel(lcdc_dev, MMU_INT_CLEAR, 0x3);
4636                 break;
4637         case UNMASK_PAGE_FAULT:
4638                 lcdc_writel(lcdc_dev, MMU_INT_MASK, 0x2);
4639                 break;
4640         default:
4641                 break;
4642         }
4643
4644         return 0;
4645 }
4646
4647 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4648         .open = rk3368_lcdc_open,
4649         .win_direct_en = rk3368_lcdc_win_direct_en,
4650         .load_screen = rk3368_load_screen,
4651         .get_dspbuf_info = rk3368_get_dspbuf_info,
4652         .post_dspbuf = rk3368_post_dspbuf,
4653         .set_par = rk3368_lcdc_set_par,
4654         .pan_display = rk3368_lcdc_pan_display,
4655         .direct_set_addr = rk3368_lcdc_direct_set_win_addr,
4656         /*.lcdc_reg_update = rk3368_lcdc_reg_update,*/
4657         .blank = rk3368_lcdc_blank,
4658         .ioctl = rk3368_lcdc_ioctl,
4659         .suspend = rk3368_lcdc_early_suspend,
4660         .resume = rk3368_lcdc_early_resume,
4661         .get_win_state = rk3368_lcdc_get_win_state,
4662         .area_support_num = rk3368_lcdc_get_area_num,
4663         .ovl_mgr = rk3368_lcdc_ovl_mgr,
4664         .get_disp_info = rk3368_lcdc_get_disp_info,
4665         .fps_mgr = rk3368_lcdc_fps_mgr,
4666         .fb_get_win_id = rk3368_lcdc_get_win_id,
4667         .fb_win_remap = rk3368_fb_win_remap,
4668         .set_dsp_lut = rk3368_lcdc_set_lut,
4669         .set_cabc_lut = rk3368_set_cabc_lut,
4670         .poll_vblank = rk3368_lcdc_poll_vblank,
4671         .dpi_open = rk3368_lcdc_dpi_open,
4672         .dpi_win_sel = rk3368_lcdc_dpi_win_sel,
4673         .dpi_status = rk3368_lcdc_dpi_status,
4674         .get_dsp_addr = rk3368_lcdc_get_dsp_addr,
4675         .set_dsp_cabc = rk3368_lcdc_set_dsp_cabc,
4676         .set_dsp_bcsh_hue = rk3368_lcdc_set_bcsh_hue,
4677         .set_dsp_bcsh_bcs = rk3368_lcdc_set_bcsh_bcs,
4678         .get_dsp_bcsh_hue = rk3368_lcdc_get_bcsh_hue,
4679         .get_dsp_bcsh_bcs = rk3368_lcdc_get_bcsh_bcs,
4680         .open_bcsh = rk3368_lcdc_open_bcsh,
4681         .dump_reg = rk3368_lcdc_reg_dump,
4682         .cfg_done = rk3368_lcdc_config_done,
4683         .set_irq_to_cpu = rk3368_lcdc_set_irq_to_cpu,
4684         /*.dsp_black = rk3368_lcdc_dsp_black,*/
4685         .backlight_close = rk3368_lcdc_backlight_close,
4686         .mmu_en    = rk3368_lcdc_mmu_en,
4687         .set_overscan   = rk3368_lcdc_set_overscan,
4688         .extern_func    = rk3368_lcdc_extern_func,
4689         .wait_frame_start = rk3368_lcdc_wait_frame_start,
4690 };
4691
4692 #ifdef LCDC_IRQ_EMPTY_DEBUG
4693 static int rk3368_lcdc_parse_irq(struct lcdc_device *lcdc_dev,
4694                                  unsigned int intr_status)
4695 {
4696         if (intr_status & m_WIN0_EMPTY_INTR_STS) {
4697                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN0_EMPTY_INTR_CLR,
4698                              v_WIN0_EMPTY_INTR_CLR(1));
4699                 dev_warn(lcdc_dev->dev, "win0 empty irq!");
4700         } else if (intr_status & m_WIN1_EMPTY_INTR_STS) {
4701                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN1_EMPTY_INTR_CLR,
4702                              v_WIN1_EMPTY_INTR_CLR(1));
4703                 dev_warn(lcdc_dev->dev, "win1 empty irq!");
4704         } else if (intr_status & m_WIN2_EMPTY_INTR_STS) {
4705                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN2_EMPTY_INTR_CLR,
4706                              v_WIN2_EMPTY_INTR_CLR(1));
4707                 dev_warn(lcdc_dev->dev, "win2 empty irq!");
4708         } else if (intr_status & m_WIN3_EMPTY_INTR_STS) {
4709                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN3_EMPTY_INTR_CLR,
4710                              v_WIN3_EMPTY_INTR_CLR(1));
4711                 dev_warn(lcdc_dev->dev, "win3 empty irq!");
4712         } else if (intr_status & m_HWC_EMPTY_INTR_STS) {
4713                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_HWC_EMPTY_INTR_CLR,
4714                              v_HWC_EMPTY_INTR_CLR(1));
4715                 dev_warn(lcdc_dev->dev, "HWC empty irq!");
4716         } else if (intr_status & m_POST_BUF_EMPTY_INTR_STS) {
4717                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_POST_BUF_EMPTY_INTR_CLR,
4718                              v_POST_BUF_EMPTY_INTR_CLR(1));
4719                 dev_warn(lcdc_dev->dev, "post buf empty irq!");
4720         } else if (intr_status & m_PWM_GEN_INTR_STS) {
4721                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_PWM_GEN_INTR_CLR,
4722                              v_PWM_GEN_INTR_CLR(1));
4723                 dev_warn(lcdc_dev->dev, "PWM gen irq!");
4724         }
4725         return 0;
4726 }
4727 #endif
4728
4729 static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id)
4730 {
4731         struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
4732         ktime_t timestamp = ktime_get();
4733         u32 intr_status;
4734         u32 scale_global_limit, scale_global_limit_reg;
4735         u32 cabc_pwm_lut_value;
4736         int pwm_plus;
4737         int *cabc_gamma_base = NULL;
4738         u32 line_scane_num, dsp_vs_st_f1;
4739         struct rk_screen *screen = lcdc_dev->driver.cur_screen;
4740
4741         intr_status = lcdc_readl(lcdc_dev, INTR_STATUS);
4742
4743         if (intr_status & m_FS_INTR_STS) {
4744                 timestamp = ktime_get();
4745                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_INTR_CLR,
4746                              v_FS_INTR_CLR(1));
4747                 line_scane_num = lcdc_readl(lcdc_dev, SCAN_LINE_NUM) & 0x1fff;
4748                 dsp_vs_st_f1 = lcdc_readl(lcdc_dev, DSP_VS_ST_END_F1) >> 16;
4749                 /*if(lcdc_dev->driver.wait_fs){ */
4750                 if (0) {
4751                         spin_lock(&(lcdc_dev->driver.cpl_lock));
4752                         complete(&(lcdc_dev->driver.frame_done));
4753                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
4754                 }
4755 #ifdef CONFIG_DRM_ROCKCHIP
4756                 lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
4757 #endif
4758                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
4759                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
4760                 if ((screen->mode.vmode == FB_VMODE_NONINTERLACED) ||
4761                     (line_scane_num >= dsp_vs_st_f1)) {
4762                         lcdc_dev->driver.vsync_info.timestamp = timestamp;
4763                         wake_up_interruptible_all(
4764                                 &lcdc_dev->driver.vsync_info.wait);
4765                 }
4766         } else if (intr_status & m_LINE_FLAG0_INTR_STS) {
4767                 lcdc_dev->driver.frame_time.last_framedone_t =
4768                         lcdc_dev->driver.frame_time.framedone_t;
4769                 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
4770                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG0_INTR_CLR,
4771                              v_LINE_FLAG0_INTR_CLR(1));
4772
4773                 if (cabc_status == 1) {
4774                         cabc_gamma_base =
4775                                 lcdc_dev->driver.cur_screen->cabc_gamma_base;
4776                         scale_global_limit  = lcdc_readl(lcdc_dev, CABC_DEBUG2);
4777                         scale_global_limit_reg = scale_global_limit;
4778                         scale_global_limit >>= 16;
4779                         scale_global_limit &= 0xff;
4780
4781                         if (lcdc_dev->driver.cabc_pwm_pol == 1) {/*negative*/
4782                                 pwm_plus = pwm_period_hpr - pwm_duty_lpr;
4783                                 cabc_pwm_lut_value =
4784                                         pwm_period_hpr -
4785                                         ((cabc_gamma_base[scale_global_limit] * pwm_plus) >> 16);
4786                         } else {/*positive*/
4787                                 pwm_plus = pwm_duty_lpr;
4788                                 cabc_pwm_lut_value =
4789                                         cabc_gamma_base[scale_global_limit] *
4790                                         pwm_plus >> 16;
4791                         }
4792                         rk_pwm_set(pwm_period_hpr, cabc_pwm_lut_value);
4793                 }
4794         } else if (intr_status & m_LINE_FLAG1_INTR_STS) {
4795                 /*line flag1 */
4796                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG1_INTR_CLR,
4797                              v_LINE_FLAG1_INTR_CLR(1));
4798         } else if (intr_status & m_FS_NEW_INTR_STS) {
4799                 /*new frame start */
4800                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_NEW_INTR_CLR,
4801                              v_FS_NEW_INTR_CLR(1));
4802         } else if (intr_status & m_BUS_ERROR_INTR_STS) {
4803                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_BUS_ERROR_INTR_CLR,
4804                              v_BUS_ERROR_INTR_CLR(1));
4805                 dev_warn(lcdc_dev->dev, "bus error!");
4806         }
4807
4808         /* for win empty debug */
4809 #ifdef LCDC_IRQ_EMPTY_DEBUG
4810         rk3368_lcdc_parse_irq(lcdc_dev, intr_status);
4811 #endif
4812         return IRQ_HANDLED;
4813 }
4814
4815 #if defined(CONFIG_PM)
4816 static int rk3368_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
4817 {
4818         return 0;
4819 }
4820
4821 static int rk3368_lcdc_resume(struct platform_device *pdev)
4822 {
4823         return 0;
4824 }
4825 #else
4826 #define rk3368_lcdc_suspend NULL
4827 #define rk3368_lcdc_resume  NULL
4828 #endif
4829
4830 static int rk3368_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
4831 {
4832         struct device_node *np = lcdc_dev->dev->of_node;
4833         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
4834         int val;
4835
4836         if (of_property_read_u32(np, "rockchip,prop", &val))
4837                 lcdc_dev->prop = PRMRY; /*default set it as primary */
4838         else
4839                 lcdc_dev->prop = val;
4840
4841         if (of_property_read_u32(np, "rockchip,mirror", &val))
4842                 dev_drv->rotate_mode = NO_MIRROR;
4843         else
4844                 dev_drv->rotate_mode = val;
4845
4846         if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
4847                 dev_drv->cabc_mode = 0; /* default set close cabc */
4848         else
4849                 dev_drv->cabc_mode = val;
4850
4851         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4852                 /*default set it as 3.xv power supply */
4853                 lcdc_dev->pwr18 = false;
4854         else
4855                 lcdc_dev->pwr18 = (val ? true : false);
4856
4857         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4858                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4859         else
4860                 dev_drv->fb_win_map = val;
4861
4862         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4863                 dev_drv->bcsh.enable = false;
4864         else
4865                 dev_drv->bcsh.enable = (val ? true : false);
4866
4867         if (of_property_read_u32(np, "rockchip,brightness", &val))
4868                 dev_drv->bcsh.brightness = 0xffff;
4869         else
4870                 dev_drv->bcsh.brightness = val;
4871
4872         if (of_property_read_u32(np, "rockchip,contrast", &val))
4873                 dev_drv->bcsh.contrast = 0xffff;
4874         else
4875                 dev_drv->bcsh.contrast = val;
4876
4877         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4878                 dev_drv->bcsh.sat_con = 0xffff;
4879         else
4880                 dev_drv->bcsh.sat_con = val;
4881
4882         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4883                 dev_drv->bcsh.sin_hue = 0xffff;
4884                 dev_drv->bcsh.cos_hue = 0xffff;
4885         } else {
4886                 dev_drv->bcsh.sin_hue = val & 0xff;
4887                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4888         }
4889
4890 #if defined(CONFIG_ROCKCHIP_IOMMU)
4891         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4892                 dev_drv->iommu_enabled = 0;
4893         else
4894                 dev_drv->iommu_enabled = val;
4895 #else
4896         dev_drv->iommu_enabled = 0;
4897 #endif
4898         return 0;
4899 }
4900
4901 static int rk3368_lcdc_probe(struct platform_device *pdev)
4902 {
4903         struct lcdc_device *lcdc_dev = NULL;
4904         struct rk_lcdc_driver *dev_drv;
4905         struct device *dev = &pdev->dev;
4906         struct resource *res;
4907         struct device_node *np = pdev->dev.of_node;
4908         int prop;
4909         int ret = 0;
4910
4911         /*if the primary lcdc has not registered ,the extend
4912            lcdc register later */
4913         of_property_read_u32(np, "rockchip,prop", &prop);
4914         if (prop == EXTEND) {
4915                 if (!is_prmry_rk_lcdc_registered())
4916                         return -EPROBE_DEFER;
4917         }
4918         lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
4919         if (!lcdc_dev) {
4920                 dev_err(&pdev->dev, "rk3368 lcdc device kmalloc fail!");
4921                 return -ENOMEM;
4922         }
4923         platform_set_drvdata(pdev, lcdc_dev);
4924         lcdc_dev->dev = dev;
4925         rk3368_lcdc_parse_dt(lcdc_dev);
4926         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4927         lcdc_dev->reg_phy_base = res->start;
4928         lcdc_dev->len = resource_size(res);
4929         lcdc_dev->regs = devm_ioremap_resource(dev, res);
4930         if (IS_ERR(lcdc_dev->regs))
4931                 return PTR_ERR(lcdc_dev->regs);
4932         else
4933                 dev_info(dev, "lcdc_dev->regs=0x%lx\n", (long)lcdc_dev->regs);
4934
4935         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
4936         if (IS_ERR(lcdc_dev->regsbak))
4937                 return PTR_ERR(lcdc_dev->regsbak);
4938         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
4939         lcdc_dev->cabc_lut_addr_base = (lcdc_dev->regs + CABC_GAMMA_LUT_ADDR);
4940         lcdc_dev->grf_base =
4941                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4942         if (IS_ERR(lcdc_dev->grf_base)) {
4943                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4944                 return PTR_ERR(lcdc_dev->grf_base);
4945         }
4946         lcdc_dev->pmugrf_base =
4947                 syscon_regmap_lookup_by_phandle(np, "rockchip,pmugrf");
4948         if (IS_ERR(lcdc_dev->pmugrf_base)) {
4949                 dev_err(&pdev->dev, "can't find lcdc pmu grf property\n");
4950                 return PTR_ERR(lcdc_dev->pmugrf_base);
4951         }
4952
4953         lcdc_dev->cru_base =
4954                 syscon_regmap_lookup_by_phandle(np, "rockchip,cru");
4955         if (IS_ERR(lcdc_dev->cru_base)) {
4956                 dev_err(&pdev->dev, "can't find lcdc cru_base property\n");
4957                 return PTR_ERR(lcdc_dev->cru_base);
4958         }
4959
4960         lcdc_dev->id = 0;
4961         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
4962         dev_drv = &lcdc_dev->driver;
4963         dev_drv->dev = dev;
4964         dev_drv->prop = prop;
4965         dev_drv->id = lcdc_dev->id;
4966         dev_drv->ops = &lcdc_drv_ops;
4967         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
4968         dev_drv->reserved_fb = 1;/*only need reserved 1 buffer*/
4969         spin_lock_init(&lcdc_dev->reg_lock);
4970
4971         lcdc_dev->irq = platform_get_irq(pdev, 0);
4972         if (lcdc_dev->irq < 0) {
4973                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4974                         lcdc_dev->id);
4975                 return -ENXIO;
4976         }
4977
4978         ret = devm_request_irq(dev, lcdc_dev->irq, rk3368_lcdc_isr,
4979                                IRQF_DISABLED | IRQF_SHARED,
4980                                dev_name(dev), lcdc_dev);
4981         if (ret) {
4982                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4983                         lcdc_dev->irq, ret);
4984                 return ret;
4985         }
4986
4987         if (dev_drv->iommu_enabled) {
4988                 if (lcdc_dev->id == 0) {
4989                         strcpy(dev_drv->mmu_dts_name,
4990                                VOPB_IOMMU_COMPATIBLE_NAME);
4991                 } else {
4992                         strcpy(dev_drv->mmu_dts_name,
4993                                VOPL_IOMMU_COMPATIBLE_NAME);
4994                 }
4995         }
4996
4997         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
4998         if (ret < 0) {
4999                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
5000                 return ret;
5001         }
5002         lcdc_dev->screen = dev_drv->screen0;
5003         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
5004                  lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
5005
5006         return 0;
5007 }
5008
5009 static int rk3368_lcdc_remove(struct platform_device *pdev)
5010 {
5011         return 0;
5012 }
5013
5014 static void rk3368_lcdc_shutdown(struct platform_device *pdev)
5015 {
5016         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
5017         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
5018 #if 1
5019         dev_drv->suspend_flag = 1;
5020         mdelay(100);
5021         flush_kthread_worker(&dev_drv->update_regs_worker);
5022         kthread_stop(dev_drv->update_regs_thread);
5023         rk3368_lcdc_deint(lcdc_dev);
5024         /*if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
5025                 dev_drv->trsm_ops->disable();*/
5026
5027         rk3368_lcdc_clk_disable(lcdc_dev);
5028         rk_disp_pwr_disable(dev_drv);
5029 #else
5030         rk3368_lcdc_early_suspend(&lcdc_dev->driver);
5031         rk3368_lcdc_deint(lcdc_dev);
5032 #endif
5033
5034 }
5035
5036 #if defined(CONFIG_OF)
5037 static const struct of_device_id rk3368_lcdc_dt_ids[] = {
5038         {.compatible = "rockchip,rk3368-lcdc",},
5039         {}
5040 };
5041 #endif
5042
5043 static struct platform_driver rk3368_lcdc_driver = {
5044         .probe = rk3368_lcdc_probe,
5045         .remove = rk3368_lcdc_remove,
5046         .driver = {
5047                    .name = "rk3368-lcdc",
5048                    .owner = THIS_MODULE,
5049                    .of_match_table = of_match_ptr(rk3368_lcdc_dt_ids),
5050                    },
5051         .suspend = rk3368_lcdc_suspend,
5052         .resume = rk3368_lcdc_resume,
5053         .shutdown = rk3368_lcdc_shutdown,
5054 };
5055
5056 static int __init rk3368_lcdc_module_init(void)
5057 {
5058         return platform_driver_register(&rk3368_lcdc_driver);
5059 }
5060
5061 static void __exit rk3368_lcdc_module_exit(void)
5062 {
5063         platform_driver_unregister(&rk3368_lcdc_driver);
5064 }
5065
5066 fs_initcall(rk3368_lcdc_module_init);
5067 module_exit(rk3368_lcdc_module_exit);