a86ef24df06be5541196459003aa102bdc2b55bd
[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
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 = 8;
1072         u16 cbcr_gather_num = 2;
1073
1074         switch (win->area[0].format) {
1075         case ARGB888:
1076         case XBGR888:
1077         case ABGR888:
1078                 yrgb_gather_num = 8;
1079                 break;
1080         case RGB888:
1081         case RGB565:
1082                 yrgb_gather_num = 4;
1083                 break;
1084         case YUV444:
1085         case YUV422:
1086         case YUV420:
1087         case YUV420_NV21:
1088                 yrgb_gather_num = 2;
1089                 cbcr_gather_num = 4;
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_WIN0_YRGB_AXI_GATHER_EN | m_WIN0_YRGB_AXI_GATHER_NUM;
1106                 val = v_WIN0_YRGB_AXI_GATHER_EN(1) |
1107                         v_WIN0_YRGB_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         } else {
1246                 mask = m_WIN0_EN;
1247                 val = v_WIN0_EN(win->state);
1248                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
1249         }
1250         return 0;
1251 }
1252
1253 static int rk3368_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1254 {
1255         struct lcdc_device *lcdc_dev =
1256             container_of(dev_drv, struct lcdc_device, driver);
1257         struct rk_lcdc_win *win = dev_drv->win[win_id];
1258         unsigned int mask, val, off;
1259
1260         off = (win_id - 2) * 0x50;
1261         rk3368_lcdc_area_xst(win, win->area_num);
1262
1263         if (win->state == 1) {
1264                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1265                 rk3368_lcdc_axi_gather_cfg(lcdc_dev, win);
1266                 if (win->area[0].fbdc_en) {
1267                         rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
1268                 } else {
1269                         mask = m_IFBDC_CTRL_FBDC_EN;
1270                         val = v_IFBDC_CTRL_FBDC_EN(0);
1271                         lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
1272                 }
1273
1274                 mask = m_WIN2_EN | m_WIN2_CSC_MODE;
1275                 val = v_WIN2_EN(1) | v_WIN1_CSC_MODE(win->csc_mode);
1276                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1277                 /*area 0 */
1278                 if (win->area[0].state == 1) {
1279                         mask = m_WIN2_MST0_EN | m_WIN2_DATA_FMT0 |
1280                             m_WIN2_RB_SWAP0;
1281                         val = v_WIN2_MST0_EN(win->area[0].state) |
1282                             v_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
1283                             v_WIN2_RB_SWAP0(win->area[0].swap_rb);
1284                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1285
1286                         mask = m_WIN2_VIR_STRIDE0;
1287                         val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
1288                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1289
1290                         /*lcdc_writel(lcdc_dev,WIN2_MST0+off,
1291                            win->area[0].y_addr); */
1292                         val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
1293                             v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
1294                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO0 + off, val);
1295                         val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
1296                             v_WIN2_DSP_YST0(win->area[0].dsp_sty);
1297                         lcdc_writel(lcdc_dev, WIN2_DSP_ST0 + off, val);
1298                 } else {
1299                         mask = m_WIN2_MST0_EN;
1300                         val = v_WIN2_MST0_EN(0);
1301                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1302                 }
1303                 /*area 1 */
1304                 if (win->area[1].state == 1) {
1305                         /*rk3368_win_area_check_var(win_id, 1,
1306                                                   &win->area[0], &win->area[1]);
1307                         */
1308
1309                         mask = m_WIN2_MST1_EN | m_WIN2_DATA_FMT1 |
1310                             m_WIN2_RB_SWAP1;
1311                         val = v_WIN2_MST1_EN(win->area[1].state) |
1312                             v_WIN2_DATA_FMT1(win->area[1].fmt_cfg) |
1313                             v_WIN2_RB_SWAP1(win->area[1].swap_rb);
1314                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1315
1316                         mask = m_WIN2_VIR_STRIDE1;
1317                         val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
1318                         lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
1319
1320                         /*lcdc_writel(lcdc_dev,WIN2_MST1+off,
1321                            win->area[1].y_addr); */
1322                         val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
1323                             v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
1324                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO1 + off, val);
1325                         val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
1326                             v_WIN2_DSP_YST1(win->area[1].dsp_sty);
1327                         lcdc_writel(lcdc_dev, WIN2_DSP_ST1 + off, val);
1328                 } else {
1329                         mask = m_WIN2_MST1_EN;
1330                         val = v_WIN2_MST1_EN(0);
1331                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1332                 }
1333                 /*area 2 */
1334                 if (win->area[2].state == 1) {
1335                         /*rk3368_win_area_check_var(win_id, 2,
1336                                                   &win->area[1], &win->area[2]);
1337                         */
1338
1339                         mask = m_WIN2_MST2_EN | m_WIN2_DATA_FMT2 |
1340                             m_WIN2_RB_SWAP2;
1341                         val = v_WIN2_MST2_EN(win->area[2].state) |
1342                             v_WIN2_DATA_FMT2(win->area[2].fmt_cfg) |
1343                             v_WIN2_RB_SWAP2(win->area[2].swap_rb);
1344                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1345
1346                         mask = m_WIN2_VIR_STRIDE2;
1347                         val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
1348                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1349
1350                         /*lcdc_writel(lcdc_dev,WIN2_MST2+off,
1351                            win->area[2].y_addr); */
1352                         val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
1353                             v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
1354                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO2 + off, val);
1355                         val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
1356                             v_WIN2_DSP_YST2(win->area[2].dsp_sty);
1357                         lcdc_writel(lcdc_dev, WIN2_DSP_ST2 + off, val);
1358                 } else {
1359                         mask = m_WIN2_MST2_EN;
1360                         val = v_WIN2_MST2_EN(0);
1361                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1362                 }
1363                 /*area 3 */
1364                 if (win->area[3].state == 1) {
1365                         /*rk3368_win_area_check_var(win_id, 3,
1366                                                   &win->area[2], &win->area[3]);
1367                         */
1368
1369                         mask = m_WIN2_MST3_EN | m_WIN2_DATA_FMT3 |
1370                             m_WIN2_RB_SWAP3;
1371                         val = v_WIN2_MST3_EN(win->area[3].state) |
1372                             v_WIN2_DATA_FMT3(win->area[3].fmt_cfg) |
1373                             v_WIN2_RB_SWAP3(win->area[3].swap_rb);
1374                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1375
1376                         mask = m_WIN2_VIR_STRIDE3;
1377                         val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
1378                         lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
1379
1380                         /*lcdc_writel(lcdc_dev,WIN2_MST3+off,
1381                            win->area[3].y_addr); */
1382                         val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
1383                             v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
1384                         lcdc_writel(lcdc_dev, WIN2_DSP_INFO3 + off, val);
1385                         val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
1386                             v_WIN2_DSP_YST3(win->area[3].dsp_sty);
1387                         lcdc_writel(lcdc_dev, WIN2_DSP_ST3 + off, val);
1388                 } else {
1389                         mask = m_WIN2_MST3_EN;
1390                         val = v_WIN2_MST3_EN(0);
1391                         lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1392                 }
1393
1394                 if (win->alpha_en == 1) {
1395                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1396                 } else {
1397                         mask = m_WIN2_SRC_ALPHA_EN;
1398                         val = v_WIN2_SRC_ALPHA_EN(0);
1399                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL + off,
1400                                      mask, val);
1401                 }
1402         } else {
1403                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
1404                     m_WIN2_MST0_EN | m_WIN2_MST2_EN | m_WIN2_MST3_EN;
1405                 val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
1406                     v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
1407                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
1408         }
1409         return 0;
1410 }
1411
1412 static int rk3368_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
1413 {
1414         struct lcdc_device *lcdc_dev =
1415             container_of(dev_drv, struct lcdc_device, driver);
1416         struct rk_lcdc_win *win = dev_drv->win[win_id];
1417         unsigned int mask, val, hwc_size = 0;
1418
1419         if (win->state == 1) {
1420                 rk3368_lcdc_csc_mode(lcdc_dev, win);
1421                 rk3368_lcdc_axi_gather_cfg(lcdc_dev, win);
1422                 mask = m_HWC_EN | m_HWC_DATA_FMT |
1423                     m_HWC_RB_SWAP | m_WIN0_CSC_MODE;
1424                 val = v_HWC_EN(1) | v_HWC_DATA_FMT(win->area[0].fmt_cfg) |
1425                     v_HWC_RB_SWAP(win->area[0].swap_rb) |
1426                     v_WIN0_CSC_MODE(win->csc_mode);
1427                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1428
1429                 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
1430                         hwc_size = 0;
1431                 else if ((win->area[0].xsize == 64) &&
1432                          (win->area[0].ysize == 64))
1433                         hwc_size = 1;
1434                 else if ((win->area[0].xsize == 96) &&
1435                          (win->area[0].ysize == 96))
1436                         hwc_size = 2;
1437                 else if ((win->area[0].xsize == 128) &&
1438                          (win->area[0].ysize == 128))
1439                         hwc_size = 3;
1440                 else
1441                         dev_err(lcdc_dev->dev, "un supported hwc size!\n");
1442
1443                 mask = m_HWC_SIZE;
1444                 val = v_HWC_SIZE(hwc_size);
1445                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1446
1447                 mask = m_HWC_DSP_XST | m_HWC_DSP_YST;
1448                 val = v_HWC_DSP_XST(win->area[0].dsp_stx) |
1449                     v_HWC_DSP_YST(win->area[0].dsp_sty);
1450                 lcdc_msk_reg(lcdc_dev, HWC_DSP_ST, mask, val);
1451
1452                 if (win->alpha_en == 1) {
1453                         rk3368_lcdc_alpha_cfg(dev_drv, win_id);
1454                 } else {
1455                         mask = m_WIN2_SRC_ALPHA_EN;
1456                         val = v_WIN2_SRC_ALPHA_EN(0);
1457                         lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL, mask, val);
1458                 }
1459         } else {
1460                 mask = m_HWC_EN;
1461                 val = v_HWC_EN(win->state);
1462                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1463         }
1464         return 0;
1465 }
1466
1467 static int rk3368_lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
1468                                          struct rk_lcdc_win *win)
1469 {
1470         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
1471         int timeout;
1472         unsigned long flags;
1473
1474         if (likely(lcdc_dev->clk_on)) {
1475                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1476                              v_STANDBY_EN(lcdc_dev->standby));
1477                 if ((win->id == 0) || (win->id == 1))
1478                         rk3368_win_0_1_reg_update(dev_drv, win->id);
1479                 else if ((win->id == 2) || (win->id == 3))
1480                         rk3368_win_2_3_reg_update(dev_drv, win->id);
1481                 else if (win->id == 4)
1482                         rk3368_hwc_reg_update(dev_drv, win->id);
1483                 /*rk3368_lcdc_post_cfg(dev_drv); */
1484                 lcdc_cfg_done(lcdc_dev);
1485         }
1486
1487         /*if (dev_drv->wait_fs) { */
1488         if (0) {
1489                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1490                 init_completion(&dev_drv->frame_done);
1491                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1492                 timeout =
1493                     wait_for_completion_timeout(&dev_drv->frame_done,
1494                                                 msecs_to_jiffies
1495                                                 (dev_drv->cur_screen->ft + 5));
1496                 if (!timeout && (!dev_drv->frame_done.done)) {
1497                         dev_warn(lcdc_dev->dev,
1498                                  "wait for new frame start time out!\n");
1499                         return -ETIMEDOUT;
1500                 }
1501         }
1502         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
1503         return 0;
1504 }
1505
1506 static int rk3368_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
1507 {
1508         memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0x270);
1509         return 0;
1510 }
1511
1512 static int __maybe_unused rk3368_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
1513 {
1514         u32 mask, val;
1515         struct lcdc_device *lcdc_dev =
1516             container_of(dev_drv, struct lcdc_device, driver);
1517
1518 #if defined(CONFIG_ROCKCHIP_IOMMU)
1519         if (dev_drv->iommu_enabled) {
1520                 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
1521                         if (likely(lcdc_dev->clk_on)) {
1522                                 mask = m_MMU_EN;
1523                                 val = v_MMU_EN(1);
1524                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1525                                 mask = m_AXI_MAX_OUTSTANDING_EN |
1526                                         m_AXI_OUTSTANDING_MAX_NUM;
1527                                 val = v_AXI_OUTSTANDING_MAX_NUM(31) |
1528                                         v_AXI_MAX_OUTSTANDING_EN(1);
1529                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
1530                         }
1531                         lcdc_dev->iommu_status = 1;
1532                         rockchip_iovmm_activate(dev_drv->dev);
1533                 }
1534         }
1535 #endif
1536         return 0;
1537 }
1538
1539 static int rk3368_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
1540 {
1541         int ret = 0, fps = 0;
1542         struct lcdc_device *lcdc_dev =
1543             container_of(dev_drv, struct lcdc_device, driver);
1544         struct rk_screen *screen = dev_drv->cur_screen;
1545 #ifdef CONFIG_RK_FPGA
1546         return 0;
1547 #endif
1548         if (reset_rate)
1549                 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);/*set pll */
1550         if (ret)
1551                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
1552         lcdc_dev->pixclock =
1553             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1554         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
1555
1556         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
1557         screen->ft = 1000 / fps;
1558         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
1559                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
1560         return 0;
1561 }
1562
1563 static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv)
1564 {
1565         struct lcdc_device *lcdc_dev =
1566             container_of(dev_drv, struct lcdc_device, driver);
1567         struct rk_screen *screen = dev_drv->cur_screen;
1568         u16 hsync_len = screen->mode.hsync_len;
1569         u16 left_margin = screen->mode.left_margin;
1570         u16 right_margin = screen->mode.right_margin;
1571         u16 vsync_len = screen->mode.vsync_len;
1572         u16 upper_margin = screen->mode.upper_margin;
1573         u16 lower_margin = screen->mode.lower_margin;
1574         u16 x_res = screen->mode.xres;
1575         u16 y_res = screen->mode.yres;
1576         u32 mask, val;
1577         u16 h_total, v_total;
1578         u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
1579
1580         h_total = hsync_len + left_margin + x_res + right_margin;
1581         v_total = vsync_len + upper_margin + y_res + lower_margin;
1582
1583         mask = m_DSP_HS_PW | m_DSP_HTOTAL;
1584         val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
1585         lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
1586
1587         mask = m_DSP_HACT_END | m_DSP_HACT_ST;
1588         val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
1589             v_DSP_HACT_ST(hsync_len + left_margin);
1590         lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
1591
1592         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1593                 /* First Field Timing */
1594                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1595                 val = v_DSP_VS_PW(vsync_len) |
1596                     v_DSP_VTOTAL(2 * (vsync_len + upper_margin +
1597                                       lower_margin) + y_res + 1);
1598                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1599
1600                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1601                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
1602                     v_DSP_VACT_ST(vsync_len + upper_margin);
1603                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1604
1605                 /* Second Field Timing */
1606                 mask = m_DSP_VS_ST_F1 | m_DSP_VS_END_F1;
1607                 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
1608                 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
1609                     lower_margin;
1610                 val = v_DSP_VS_ST_F1(vs_st_f1) | v_DSP_VS_END_F1(vs_end_f1);
1611                 lcdc_msk_reg(lcdc_dev, DSP_VS_ST_END_F1, mask, val);
1612
1613                 mask = m_DSP_VACT_END_F1 | m_DSP_VAC_ST_F1;
1614                 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
1615                     lower_margin + 1;
1616                 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
1617                     lower_margin + 1;
1618                 val =
1619                     v_DSP_VACT_END_F1(vact_end_f1) |
1620                     v_DSP_VAC_ST_F1(vact_st_f1);
1621                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END_F1, mask, val);
1622
1623                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1624                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1625                              v_DSP_INTERLACE(1) | v_DSP_FIELD_POL(0));
1626                 mask =
1627                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1628                     m_WIN0_CBR_DEFLICK;
1629                 val =
1630                     v_WIN0_INTERLACE_READ(1) | v_WIN0_YRGB_DEFLICK(1) |
1631                     v_WIN0_CBR_DEFLICK(1);
1632                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1633
1634                 mask =
1635                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1636                     m_WIN1_CBR_DEFLICK;
1637                 val =
1638                     v_WIN1_INTERLACE_READ(1) | v_WIN1_YRGB_DEFLICK(1) |
1639                     v_WIN1_CBR_DEFLICK(1);
1640                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1641
1642                 mask = m_WIN2_INTERLACE_READ;
1643                 val = v_WIN2_INTERLACE_READ(1);
1644                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1645
1646                 mask = m_WIN3_INTERLACE_READ;
1647                 val = v_WIN3_INTERLACE_READ(1);
1648                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1649
1650                 mask = m_HWC_INTERLACE_READ;
1651                 val = v_HWC_INTERLACE_READ(1);
1652                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1653
1654                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1655                 val =
1656                     v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res / 2) |
1657                     v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res / 2);
1658                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1659         } else {
1660                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1661                 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
1662                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1663
1664                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1665                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1666                     v_DSP_VACT_ST(vsync_len + upper_margin);
1667                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1668
1669                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1670                              m_DSP_INTERLACE | m_DSP_FIELD_POL,
1671                              v_DSP_INTERLACE(0) | v_DSP_FIELD_POL(0));
1672
1673                 mask =
1674                     m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
1675                     m_WIN0_CBR_DEFLICK;
1676                 val =
1677                     v_WIN0_INTERLACE_READ(0) | v_WIN0_YRGB_DEFLICK(0) |
1678                     v_WIN0_CBR_DEFLICK(0);
1679                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1680
1681                 mask =
1682                     m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
1683                     m_WIN1_CBR_DEFLICK;
1684                 val =
1685                     v_WIN1_INTERLACE_READ(0) | v_WIN1_YRGB_DEFLICK(0) |
1686                     v_WIN1_CBR_DEFLICK(0);
1687                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1688
1689                 mask = m_WIN2_INTERLACE_READ;
1690                 val = v_WIN2_INTERLACE_READ(0);
1691                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1692
1693                 mask = m_WIN3_INTERLACE_READ;
1694                 val = v_WIN3_INTERLACE_READ(0);
1695                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1696
1697                 mask = m_HWC_INTERLACE_READ;
1698                 val = v_HWC_INTERLACE_READ(0);
1699                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
1700
1701                 mask = m_DSP_LINE_FLAG0_NUM | m_DSP_LINE_FLAG1_NUM;
1702                 val = v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
1703                         v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
1704                 lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
1705         }
1706         rk3368_lcdc_post_cfg(dev_drv);
1707         return 0;
1708 }
1709
1710 static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1711 {
1712         struct lcdc_device *lcdc_dev =
1713             container_of(dev_drv, struct lcdc_device, driver);
1714         u32 bcsh_ctrl;
1715
1716         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_OVERLAY_MODE,
1717                      v_OVERLAY_MODE(dev_drv->overlay_mode));
1718         if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1719                 if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
1720                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1721                                      m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1722                                      v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1723                 else            /* YUV2RGB */
1724                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1725                                      m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1726                                      m_BCSH_R2Y_EN,
1727                                      v_BCSH_Y2R_EN(1) |
1728                                      v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1729                                      v_BCSH_R2Y_EN(0));
1730         } else {                /* overlay_mode=VOP_RGB_DOMAIN */
1731                 /* bypass  --need check,if bcsh close? */
1732                 if (dev_drv->output_color == COLOR_RGB) {
1733                         bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1734                         if (((bcsh_ctrl & m_BCSH_EN) == 1) ||
1735                             (dev_drv->bcsh.enable == 1))/*bcsh enabled */
1736                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1737                                              m_BCSH_R2Y_EN |
1738                                              m_BCSH_Y2R_EN,
1739                                              v_BCSH_R2Y_EN(1) |
1740                                              v_BCSH_Y2R_EN(1));
1741                         else
1742                                 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1743                                              m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1744                                              v_BCSH_R2Y_EN(0) |
1745                                              v_BCSH_Y2R_EN(0));
1746                 } else          /* RGB2YUV */
1747                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1748                                      m_BCSH_R2Y_EN |
1749                                      m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1750                                      v_BCSH_R2Y_EN(1) |
1751                                      v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1752                                      v_BCSH_Y2R_EN(0));
1753         }
1754 }
1755
1756 static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1757                                   u16 *yact, int *format, u32 *dsp_addr)
1758 {
1759         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1760                                                     struct lcdc_device, driver);
1761         u32 val;
1762
1763         spin_lock(&lcdc_dev->reg_lock);
1764
1765         val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1766         *xact = (val & m_WIN0_ACT_WIDTH) + 1;
1767         *yact = ((val & m_WIN0_ACT_HEIGHT)>>16) + 1;
1768
1769         val = lcdc_readl(lcdc_dev, WIN0_CTRL0);
1770         *format = (val & m_WIN0_DATA_FMT) >> 1;
1771         *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1772
1773         spin_unlock(&lcdc_dev->reg_lock);
1774
1775         return 0;
1776 }
1777
1778 static int rk3368_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1779                               int format, u16 xact, u16 yact, u16 xvir)
1780 {
1781         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1782                                                     struct lcdc_device, driver);
1783         u32 val, mask;
1784         int swap = (format == RGB888) ? 1 : 0;
1785
1786         mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP;
1787         val = v_WIN0_DATA_FMT(format) | v_WIN0_RB_SWAP(swap);
1788         lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1789
1790         lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_WIN0_VIR_STRIDE,
1791                         v_WIN0_VIR_STRIDE(xvir));
1792         lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_WIN0_ACT_WIDTH(xact) |
1793                     v_WIN0_ACT_HEIGHT(yact));
1794
1795         lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1796
1797         lcdc_cfg_done(lcdc_dev);
1798
1799         return 0;
1800 }
1801
1802 static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen)
1803 {
1804         struct lcdc_device *lcdc_dev =
1805             container_of(dev_drv, struct lcdc_device, driver);
1806         u32 mask, val;
1807         u32 __maybe_unused v;
1808         /*printk("0407:standby=%d,initscreen=%d,dev_drv->first_frame=%d\n",
1809                 lcdc_dev->standby,initscreen,dev_drv->first_frame);*/
1810         if (!lcdc_dev->standby && initscreen && (dev_drv->first_frame != 1)) {
1811                 mdelay(150);
1812                 mask = m_WIN0_EN;
1813                 val = v_WIN0_EN(0);
1814                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
1815                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
1816
1817                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
1818                         m_WIN2_MST1_EN |
1819                         m_WIN2_MST2_EN | m_WIN2_MST3_EN;
1820                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
1821                         v_WIN2_MST1_EN(0) |
1822                         v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
1823                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
1824                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
1825                 mask = m_HDMI_OUT_EN;
1826                 val = v_HDMI_OUT_EN(0);
1827                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1828                 lcdc_cfg_done(lcdc_dev);
1829                 mdelay(50);
1830                 writel_relaxed(0, lcdc_dev->regs + REG_CFG_DONE);
1831 #if 0
1832                 if (dev_drv->iommu_enabled) {
1833                         if (dev_drv->mmu_dev)
1834                                 rockchip_iovmm_deactivate(dev_drv->dev);
1835                 }
1836                 lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
1837                                 (1 << 4)  | (1 << 5)  | (1 << 6) |
1838                                 (1 << 20) | (1 << 21) | (1 << 22));
1839                 udelay(100);
1840                 v = lcdc_cru_readl(lcdc_dev->cru_base, 0x0318);
1841                 pr_info("cru read = 0x%x\n", v);
1842                 lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
1843                                 (0 << 4)  | (0 << 5)  | (0 << 6) |
1844                                 (1 << 20) | (1 << 21) | (1 << 22));
1845                 mdelay(100);
1846                 if (dev_drv->iommu_enabled) {
1847                         if (dev_drv->mmu_dev)
1848                                 rockchip_iovmm_activate(dev_drv->dev);
1849                 }
1850                 mdelay(50);
1851                 rk3368_lcdc_reg_restore(lcdc_dev);
1852                 mdelay(50);
1853 #endif
1854         }
1855         return 0;
1856 }
1857
1858 static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1859 {
1860         u16 face = 0;
1861         u16 dclk_ddr = 0;
1862         u32 v = 0;
1863         struct lcdc_device *lcdc_dev =
1864             container_of(dev_drv, struct lcdc_device, driver);
1865         struct rk_screen *screen = dev_drv->cur_screen;
1866         u32 mask, val;
1867         if (!lcdc_dev->standby && initscreen && (dev_drv->first_frame != 1))
1868                 flush_kthread_worker(&dev_drv->update_regs_worker);
1869
1870         spin_lock(&lcdc_dev->reg_lock);
1871         if (likely(lcdc_dev->clk_on)) {
1872                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1873 #if 0
1874                 if (!lcdc_dev->standby && !initscreen) {
1875                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
1876                                      v_STANDBY_EN(1));
1877                         lcdc_cfg_done(lcdc_dev);
1878                         mdelay(50);
1879                 }
1880 #else
1881         lcdc_reset(dev_drv, initscreen);
1882 #endif
1883                 switch (screen->face) {
1884                 case OUT_P565:
1885                         face = OUT_P565;
1886                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1887                             m_DITHER_DOWN_SEL;
1888                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1889                             v_DITHER_DOWN_SEL(1);
1890                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1891                         break;
1892                 case OUT_P666:
1893                         face = OUT_P666;
1894                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1895                             m_DITHER_DOWN_SEL;
1896                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1897                             v_DITHER_DOWN_SEL(1);
1898                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1899                         break;
1900                 case OUT_D888_P565:
1901                         face = OUT_P888;
1902                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1903                             m_DITHER_DOWN_SEL;
1904                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1905                             v_DITHER_DOWN_SEL(1);
1906                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1907                         break;
1908                 case OUT_D888_P666:
1909                         face = OUT_P888;
1910                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1911                             m_DITHER_DOWN_SEL;
1912                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1913                             v_DITHER_DOWN_SEL(1);
1914                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1915                         break;
1916                 case OUT_P888:
1917                         face = OUT_P888;
1918                         mask = m_DITHER_DOWN_EN;
1919                         val = v_DITHER_DOWN_EN(0);
1920                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1921                         break;
1922                 case OUT_YUV_420:
1923                         /*yuv420 output prefer yuv domain overlay */
1924                         face = OUT_YUV_420;
1925                         dclk_ddr = 1;
1926                         mask = m_DITHER_DOWN_EN;
1927                         val = v_DITHER_DOWN_EN(0);
1928                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1929                         break;
1930                 case OUT_S888:
1931                         face = OUT_S888;
1932                         mask = m_DITHER_DOWN_EN;
1933                         val = v_DITHER_DOWN_EN(0);
1934                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1935                         break;
1936                 case OUT_S888DUMY:
1937                         face = OUT_S888DUMY;
1938                         mask = m_DITHER_DOWN_EN;
1939                         val = v_DITHER_DOWN_EN(0);
1940                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1941                         break;
1942                 default:
1943                         dev_err(lcdc_dev->dev, "un supported interface!\n");
1944                         break;
1945                 }
1946                 switch (screen->type) {
1947                 case SCREEN_RGB:
1948                         mask = m_RGB_OUT_EN;
1949                         val = v_RGB_OUT_EN(1);
1950                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1951                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1952                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1953                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1954                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1955                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
1956                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
1957                         v = 1 << 15 | (1 << (15 + 16));
1958
1959                         break;
1960                 case SCREEN_LVDS:
1961                         mask = m_RGB_OUT_EN;
1962                         val = v_RGB_OUT_EN(1);
1963                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1964                         mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
1965                             m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
1966                         val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
1967                             v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
1968                             v_RGB_LVDS_DEN_POL(screen->pin_den) |
1969                             v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
1970                         v = 0 << 15 | (1 << (15 + 16));
1971                         break;
1972                 case SCREEN_HDMI:
1973                         /*face = OUT_RGB_AAA;*/
1974                         if (screen->color_mode == COLOR_RGB)
1975                                 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1976                         else
1977                                 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1978                         mask = m_HDMI_OUT_EN  | m_RGB_OUT_EN;
1979                         val = v_HDMI_OUT_EN(1) | v_RGB_OUT_EN(0);
1980                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1981                         mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1982                             m_HDMI_DEN_POL | m_HDMI_DCLK_POL;
1983                         val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1984                             v_HDMI_VSYNC_POL(screen->pin_vsync) |
1985                             v_HDMI_DEN_POL(screen->pin_den) |
1986                             v_HDMI_DCLK_POL(screen->pin_dclk);
1987                         break;
1988                 case SCREEN_MIPI:
1989                         mask = m_MIPI_OUT_EN  | m_RGB_OUT_EN;
1990                         val = v_MIPI_OUT_EN(1) | v_RGB_OUT_EN(0);
1991                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1992                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
1993                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
1994                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
1995                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
1996                             v_MIPI_DEN_POL(screen->pin_den) |
1997                             v_MIPI_DCLK_POL(screen->pin_dclk);
1998                         break;
1999                 case SCREEN_DUAL_MIPI:
2000                         mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN  |
2001                                 m_RGB_OUT_EN;
2002                         val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1) |
2003                                 v_RGB_OUT_EN(0);
2004                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2005                         mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
2006                             m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
2007                         val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
2008                             v_MIPI_VSYNC_POL(screen->pin_vsync) |
2009                             v_MIPI_DEN_POL(screen->pin_den) |
2010                             v_MIPI_DCLK_POL(screen->pin_dclk);
2011                         break;
2012                 case SCREEN_EDP:
2013                         face = OUT_P888;        /*RGB 888 output */
2014
2015                         mask = m_EDP_OUT_EN | m_RGB_OUT_EN;
2016                         val = v_EDP_OUT_EN(1) | v_RGB_OUT_EN(0);
2017                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
2018                         /*because edp have to sent aaa fmt */
2019                         mask = m_DITHER_DOWN_EN;
2020                         val = v_DITHER_DOWN_EN(0);
2021
2022                         mask |= m_EDP_HSYNC_POL | m_EDP_VSYNC_POL |
2023                             m_EDP_DEN_POL | m_EDP_DCLK_POL;
2024                         val |= v_EDP_HSYNC_POL(screen->pin_hsync) |
2025                             v_EDP_VSYNC_POL(screen->pin_vsync) |
2026                             v_EDP_DEN_POL(screen->pin_den) |
2027                             v_EDP_DCLK_POL(screen->pin_dclk);
2028                         break;
2029                 }
2030                 /*hsync vsync den dclk polo,dither */
2031                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
2032 #ifndef CONFIG_RK_FPGA
2033                 /*writel_relaxed(v, RK_GRF_VIRT + rk3368_GRF_SOC_CON7);
2034                 move to  lvds driver*/
2035                 /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
2036 #endif
2037                 mask = m_DSP_OUT_MODE | m_DSP_DCLK_DDR | m_DSP_BG_SWAP |
2038                     m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
2039                     m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
2040                     m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
2041                 val = v_DSP_OUT_MODE(face) | v_DSP_DCLK_DDR(dclk_ddr) |
2042                     v_DSP_BG_SWAP(screen->swap_gb) |
2043                     v_DSP_RB_SWAP(screen->swap_rb) |
2044                     v_DSP_RG_SWAP(screen->swap_rg) |
2045                     v_DSP_DELTA_SWAP(screen->swap_delta) |
2046                     v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
2047                     v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
2048                     v_DSP_X_MIR_EN(screen->x_mirror) |
2049                     v_DSP_Y_MIR_EN(screen->y_mirror);
2050                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
2051                 /*BG color */
2052                 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
2053                 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
2054                         val = v_DSP_BG_BLUE(0x80) | v_DSP_BG_GREEN(0x10) |
2055                                 v_DSP_BG_RED(0x80);
2056                 else
2057                         val = v_DSP_BG_BLUE(0) | v_DSP_BG_GREEN(0) |
2058                                 v_DSP_BG_RED(0);
2059                 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
2060                 dev_drv->output_color = screen->color_mode;
2061                 if (screen->dsp_lut == NULL)
2062                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2063                                      v_DSP_LUT_EN(0));
2064                 else
2065                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2066                                      v_DSP_LUT_EN(1));
2067                 rk3368_lcdc_bcsh_path_sel(dev_drv);
2068                 rk3368_config_timing(dev_drv);
2069         }
2070         spin_unlock(&lcdc_dev->reg_lock);
2071         rk3368_lcdc_set_dclk(dev_drv, 1);
2072         if (screen->type != SCREEN_HDMI &&
2073             screen->type != SCREEN_TVOUT &&
2074             dev_drv->trsm_ops &&
2075             dev_drv->trsm_ops->enable)
2076                 dev_drv->trsm_ops->enable();
2077         if (screen->init)
2078                 screen->init();
2079         if (!lcdc_dev->standby)
2080                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
2081         return 0;
2082 }
2083
2084
2085 /*enable layer,open:1,enable;0 disable*/
2086 static void rk3368_lcdc_layer_enable(struct lcdc_device *lcdc_dev,
2087                                      unsigned int win_id, bool open)
2088 {
2089         spin_lock(&lcdc_dev->reg_lock);
2090         if (likely(lcdc_dev->clk_on) &&
2091             lcdc_dev->driver.win[win_id]->state != open) {
2092                 if (open) {
2093                         if (!lcdc_dev->atv_layer_cnt) {
2094                                 dev_info(lcdc_dev->dev,
2095                                          "wakeup from standby!\n");
2096                                 lcdc_dev->standby = 0;
2097                         }
2098                         lcdc_dev->atv_layer_cnt |= (1 << win_id);
2099                 } else {
2100                         if (lcdc_dev->atv_layer_cnt & (1 << win_id))
2101                                 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
2102                 }
2103                 lcdc_dev->driver.win[win_id]->state = open;
2104                 if (!open) {
2105                         /*rk3368_lcdc_reg_update(dev_drv);*/
2106                         rk3368_lcdc_layer_update_regs
2107                         (lcdc_dev, lcdc_dev->driver.win[win_id]);
2108                         lcdc_cfg_done(lcdc_dev);
2109                 }
2110                 /*if no layer used,disable lcdc */
2111                 if (!lcdc_dev->atv_layer_cnt) {
2112                         dev_info(lcdc_dev->dev,
2113                                  "no layer is used,go to standby!\n");
2114                         lcdc_dev->standby = 1;
2115                 }
2116         }
2117         spin_unlock(&lcdc_dev->reg_lock);
2118 }
2119
2120 static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
2121 {
2122         struct lcdc_device *lcdc_dev = container_of(dev_drv,
2123                                                     struct lcdc_device, driver);
2124         u32 mask, val;
2125         /*struct rk_screen *screen = dev_drv->cur_screen; */
2126
2127         mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
2128             m_LINE_FLAG1_INTR_CLR;
2129         val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
2130             v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1);
2131         lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
2132
2133         mask = m_FS_INTR_EN | m_LINE_FLAG0_INTR_EN |
2134                 m_BUS_ERROR_INTR_EN | m_LINE_FLAG1_INTR_EN;
2135         val = v_FS_INTR_EN(1) | v_LINE_FLAG0_INTR_EN(1) |
2136             v_BUS_ERROR_INTR_EN(1) | v_LINE_FLAG1_INTR_EN(0);
2137         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
2138
2139 #ifdef LCDC_IRQ_EMPTY_DEBUG
2140         mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
2141             m_WIN2_EMPTY_INTR_EN |
2142             m_WIN3_EMPTY_INTR_EN | m_HWC_EMPTY_INTR_EN |
2143             m_POST_BUF_EMPTY_INTR_EN | m_PWM_GEN_INTR_EN;
2144         val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) |
2145             v_WIN2_EMPTY_INTR_EN(1) |
2146             v_WIN3_EMPTY_INTR_EN(1) | v_HWC_EMPTY_INTR_EN(1) |
2147             v_POST_BUF_EMPTY_INTR_EN(1) | v_PWM_GEN_INTR_EN(1);
2148         lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
2149 #endif
2150         return 0;
2151 }
2152
2153 static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
2154                             bool open)
2155 {
2156         struct lcdc_device *lcdc_dev =
2157             container_of(dev_drv, struct lcdc_device, driver);
2158 #if 0/*ndef CONFIG_RK_FPGA*/
2159         int sys_status =
2160             (dev_drv->id == 0) ? SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1;
2161 #endif
2162         /*enable clk,when first layer open */
2163         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
2164                 /*rockchip_set_system_status(sys_status);*/
2165                 rk3368_lcdc_pre_init(dev_drv);
2166                 rk3368_lcdc_clk_enable(lcdc_dev);
2167                 rk3368_lcdc_enable_irq(dev_drv);
2168 #if defined(CONFIG_ROCKCHIP_IOMMU)
2169                 if (dev_drv->iommu_enabled) {
2170                         if (!dev_drv->mmu_dev) {
2171                                 dev_drv->mmu_dev =
2172                                     rk_fb_get_sysmmu_device_by_compatible
2173                                     (dev_drv->mmu_dts_name);
2174                                 if (dev_drv->mmu_dev) {
2175                                         rk_fb_platform_set_sysmmu
2176                                             (dev_drv->mmu_dev, dev_drv->dev);
2177                                 } else {
2178                                         dev_err(dev_drv->dev,
2179                                                 "fail get rk iommu device\n");
2180                                         return -1;
2181                                 }
2182                         }
2183                         /*if (dev_drv->mmu_dev)
2184                            rockchip_iovmm_activate(dev_drv->dev); */
2185                 }
2186 #endif
2187                 rk3368_lcdc_reg_restore(lcdc_dev);
2188                 /*if (dev_drv->iommu_enabled)
2189                    rk3368_lcdc_mmu_en(dev_drv); */
2190                 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
2191                         rk3368_lcdc_set_dclk(dev_drv, 0);
2192                         /*rk3368_lcdc_enable_irq(dev_drv);*/
2193                 } else {
2194                         rk3368_load_screen(dev_drv, 1);
2195                 }
2196                 if (dev_drv->bcsh.enable)
2197                         rk3368_lcdc_set_bcsh(dev_drv, 1);
2198                 spin_lock(&lcdc_dev->reg_lock);
2199                 if (dev_drv->cur_screen->dsp_lut)
2200                         rk3368_lcdc_set_lut(dev_drv,
2201                                             dev_drv->cur_screen->dsp_lut);
2202                 if (dev_drv->cur_screen->cabc_lut)
2203                         rk3368_set_cabc_lut(dev_drv,
2204                                             dev_drv->cur_screen->cabc_lut);
2205                 spin_unlock(&lcdc_dev->reg_lock);
2206         }
2207
2208         if (win_id < ARRAY_SIZE(lcdc_win))
2209                 rk3368_lcdc_layer_enable(lcdc_dev, win_id, open);
2210         else
2211                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
2212
2213
2214         /* when all layer closed,disable clk */
2215         /*if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
2216            rk3368_lcdc_disable_irq(lcdc_dev);
2217            rk3368_lcdc_reg_update(dev_drv);
2218            #if defined(CONFIG_ROCKCHIP_IOMMU)
2219            if (dev_drv->iommu_enabled) {
2220            if (dev_drv->mmu_dev)
2221            rockchip_iovmm_deactivate(dev_drv->dev);
2222            }
2223            #endif
2224            rk3368_lcdc_clk_disable(lcdc_dev);
2225            #ifndef CONFIG_RK_FPGA
2226            rockchip_clear_system_status(sys_status);
2227            #endif
2228            } */
2229         dev_drv->first_frame = 0;
2230         return 0;
2231 }
2232
2233 static int win_0_1_display(struct lcdc_device *lcdc_dev,
2234                            struct rk_lcdc_win *win)
2235 {
2236         u32 y_addr;
2237         u32 uv_addr;
2238         unsigned int off;
2239
2240         off = win->id * 0x40;
2241         /*win->smem_start + win->y_offset; */
2242         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2243         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
2244         DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
2245             lcdc_dev->id, win->id, y_addr, uv_addr);
2246         DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
2247             win->area[0].y_offset, win->area[0].c_offset);
2248         spin_lock(&lcdc_dev->reg_lock);
2249         if (likely(lcdc_dev->clk_on)) {
2250                 win->area[0].y_addr = y_addr;
2251                 win->area[0].uv_addr = uv_addr;
2252                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
2253                 lcdc_writel(lcdc_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
2254                 if (win->area[0].fbdc_en == 1)
2255                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2256                                         win->area[0].y_addr);
2257         }
2258         spin_unlock(&lcdc_dev->reg_lock);
2259
2260         return 0;
2261 }
2262
2263 static int win_2_3_display(struct lcdc_device *lcdc_dev,
2264                            struct rk_lcdc_win *win)
2265 {
2266         u32 i, y_addr;
2267         unsigned int off;
2268
2269         off = (win->id - 2) * 0x50;
2270         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2271         DBG(2, "lcdc[%d]:win[%d]:", lcdc_dev->id, win->id);
2272
2273         spin_lock(&lcdc_dev->reg_lock);
2274         if (likely(lcdc_dev->clk_on)) {
2275                 for (i = 0; i < win->area_num; i++) {
2276                         DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
2277                             i, win->area[i].y_addr, win->area[i].y_offset);
2278                         win->area[i].y_addr =
2279                             win->area[i].smem_start + win->area[i].y_offset;
2280                         }
2281                 lcdc_writel(lcdc_dev, WIN2_MST0 + off, win->area[0].y_addr);
2282                 lcdc_writel(lcdc_dev, WIN2_MST1 + off, win->area[1].y_addr);
2283                 lcdc_writel(lcdc_dev, WIN2_MST2 + off, win->area[2].y_addr);
2284                 lcdc_writel(lcdc_dev, WIN2_MST3 + off, win->area[3].y_addr);
2285                 if (win->area[0].fbdc_en == 1)
2286                         lcdc_writel(lcdc_dev, IFBDC_BASE_ADDR,
2287                                         win->area[0].y_addr);
2288         }
2289         spin_unlock(&lcdc_dev->reg_lock);
2290         return 0;
2291 }
2292
2293 static int hwc_display(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win)
2294 {
2295         u32 y_addr;
2296
2297         y_addr = win->area[0].smem_start + win->area[0].y_offset;
2298         DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
2299             lcdc_dev->id, __func__, y_addr);
2300         spin_lock(&lcdc_dev->reg_lock);
2301         if (likely(lcdc_dev->clk_on)) {
2302                 win->area[0].y_addr = y_addr;
2303                 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
2304         }
2305         spin_unlock(&lcdc_dev->reg_lock);
2306
2307         return 0;
2308 }
2309
2310 static int rk3368_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
2311 {
2312         struct lcdc_device *lcdc_dev =
2313             container_of(dev_drv, struct lcdc_device, driver);
2314         struct rk_lcdc_win *win = NULL;
2315         struct rk_screen *screen = dev_drv->cur_screen;
2316
2317 #if defined(WAIT_FOR_SYNC)
2318         int timeout;
2319         unsigned long flags;
2320 #endif
2321         win = dev_drv->win[win_id];
2322         if (!screen) {
2323                 dev_err(dev_drv->dev, "screen is null!\n");
2324                 return -ENOENT;
2325         }
2326         if (win_id == 0) {
2327                 win_0_1_display(lcdc_dev, win);
2328         } else if (win_id == 1) {
2329                 win_0_1_display(lcdc_dev, win);
2330         } else if (win_id == 2) {
2331                 win_2_3_display(lcdc_dev, win);
2332         } else if (win_id == 3) {
2333                 win_2_3_display(lcdc_dev, win);
2334         } else if (win_id == 4) {
2335                 hwc_display(lcdc_dev, win);
2336         } else {
2337                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
2338                 return -EINVAL;
2339         }
2340
2341 #if defined(WAIT_FOR_SYNC)
2342         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
2343         init_completion(&dev_drv->frame_done);
2344         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
2345         timeout =
2346             wait_for_completion_timeout(&dev_drv->frame_done,
2347                                         msecs_to_jiffies(dev_drv->
2348                                                          cur_screen->ft + 5));
2349         if (!timeout && (!dev_drv->frame_done.done)) {
2350                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
2351                 return -ETIMEDOUT;
2352         }
2353 #endif
2354         return 0;
2355 }
2356
2357 static int rk3368_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
2358 {
2359         u16 srcW;
2360         u16 srcH;
2361         u16 dstW;
2362         u16 dstH;
2363         u16 yrgb_srcW;
2364         u16 yrgb_srcH;
2365         u16 yrgb_dstW;
2366         u16 yrgb_dstH;
2367         u32 yrgb_vscalednmult;
2368         u32 yrgb_xscl_factor;
2369         u32 yrgb_yscl_factor;
2370         u8 yrgb_vsd_bil_gt2 = 0;
2371         u8 yrgb_vsd_bil_gt4 = 0;
2372
2373         u16 cbcr_srcW;
2374         u16 cbcr_srcH;
2375         u16 cbcr_dstW;
2376         u16 cbcr_dstH;
2377         u32 cbcr_vscalednmult;
2378         u32 cbcr_xscl_factor;
2379         u32 cbcr_yscl_factor;
2380         u8 cbcr_vsd_bil_gt2 = 0;
2381         u8 cbcr_vsd_bil_gt4 = 0;
2382         u8 yuv_fmt = 0;
2383
2384         srcW = win->area[0].xact;
2385         srcH = win->area[0].yact;
2386         dstW = win->area[0].xsize;
2387         dstH = win->area[0].ysize;
2388
2389         /*yrgb scl mode */
2390         yrgb_srcW = srcW;
2391         yrgb_srcH = srcH;
2392         yrgb_dstW = dstW;
2393         yrgb_dstH = dstH;
2394         if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
2395                 pr_err("ERROR: yrgb scale exceed 8,");
2396                 pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
2397                        yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
2398         }
2399         if (yrgb_srcW < yrgb_dstW)
2400                 win->yrgb_hor_scl_mode = SCALE_UP;
2401         else if (yrgb_srcW > yrgb_dstW)
2402                 win->yrgb_hor_scl_mode = SCALE_DOWN;
2403         else
2404                 win->yrgb_hor_scl_mode = SCALE_NONE;
2405
2406         if (yrgb_srcH < yrgb_dstH)
2407                 win->yrgb_ver_scl_mode = SCALE_UP;
2408         else if (yrgb_srcH > yrgb_dstH)
2409                 win->yrgb_ver_scl_mode = SCALE_DOWN;
2410         else
2411                 win->yrgb_ver_scl_mode = SCALE_NONE;
2412
2413         /*cbcr scl mode */
2414         switch (win->area[0].format) {
2415         case YUV422:
2416         case YUV422_A:
2417                 cbcr_srcW = srcW / 2;
2418                 cbcr_dstW = dstW;
2419                 cbcr_srcH = srcH;
2420                 cbcr_dstH = dstH;
2421                 yuv_fmt = 1;
2422                 break;
2423         case YUV420:
2424         case YUV420_A:
2425         case YUV420_NV21:
2426                 cbcr_srcW = srcW / 2;
2427                 cbcr_dstW = dstW;
2428                 cbcr_srcH = srcH / 2;
2429                 cbcr_dstH = dstH;
2430                 yuv_fmt = 1;
2431                 break;
2432         case YUV444:
2433         case YUV444_A:
2434                 cbcr_srcW = srcW;
2435                 cbcr_dstW = dstW;
2436                 cbcr_srcH = srcH;
2437                 cbcr_dstH = dstH;
2438                 yuv_fmt = 1;
2439                 break;
2440         default:
2441                 cbcr_srcW = 0;
2442                 cbcr_dstW = 0;
2443                 cbcr_srcH = 0;
2444                 cbcr_dstH = 0;
2445                 yuv_fmt = 0;
2446                 break;
2447         }
2448         if (yuv_fmt) {
2449                 if ((cbcr_dstW * 8 <= cbcr_srcW) ||
2450                     (cbcr_dstH * 8 <= cbcr_srcH)) {
2451                         pr_err("ERROR: cbcr scale exceed 8,");
2452                         pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
2453                                cbcr_srcH, cbcr_dstW, cbcr_dstH);
2454                 }
2455         }
2456
2457         if (cbcr_srcW < cbcr_dstW)
2458                 win->cbr_hor_scl_mode = SCALE_UP;
2459         else if (cbcr_srcW > cbcr_dstW)
2460                 win->cbr_hor_scl_mode = SCALE_DOWN;
2461         else
2462                 win->cbr_hor_scl_mode = SCALE_NONE;
2463
2464         if (cbcr_srcH < cbcr_dstH)
2465                 win->cbr_ver_scl_mode = SCALE_UP;
2466         else if (cbcr_srcH > cbcr_dstH)
2467                 win->cbr_ver_scl_mode = SCALE_DOWN;
2468         else
2469                 win->cbr_ver_scl_mode = SCALE_NONE;
2470
2471         /*DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
2472             "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
2473             "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n", srcW,
2474             srcH, dstW, dstH, yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH,
2475             win->yrgb_hor_scl_mode, win->yrgb_ver_scl_mode, cbcr_srcW,
2476             cbcr_srcH, cbcr_dstW, cbcr_dstH, win->cbr_hor_scl_mode,
2477             win->cbr_ver_scl_mode);*/
2478
2479         /*line buffer mode */
2480         if ((win->area[0].format == YUV422) ||
2481             (win->area[0].format == YUV420) ||
2482             (win->area[0].format == YUV420_NV21) ||
2483             (win->area[0].format == YUV422_A) ||
2484             (win->area[0].format == YUV420_A)) {
2485                 if (win->cbr_hor_scl_mode == SCALE_DOWN) {
2486                         if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
2487                             (cbcr_dstW == 0))
2488                                 pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
2489                                        cbcr_dstW);
2490                         else if (cbcr_dstW > 1280)
2491                                 win->win_lb_mode = LB_YUV_3840X5;
2492                         else
2493                                 win->win_lb_mode = LB_YUV_2560X8;
2494                 } else {        /*SCALE_UP or SCALE_NONE */
2495                         if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
2496                             (cbcr_srcW == 0))
2497                                 pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
2498                                        cbcr_srcW);
2499                         else if (cbcr_srcW > 1280)
2500                                 win->win_lb_mode = LB_YUV_3840X5;
2501                         else
2502                                 win->win_lb_mode = LB_YUV_2560X8;
2503                 }
2504         } else {
2505                 if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
2506                         if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
2507                             (yrgb_dstW == 0))
2508                                 pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
2509                         else if (yrgb_dstW > 2560)
2510                                 win->win_lb_mode = LB_RGB_3840X2;
2511                         else if (yrgb_dstW > 1920)
2512                                 win->win_lb_mode = LB_RGB_2560X4;
2513                         else if (yrgb_dstW > 1280)
2514                                 win->win_lb_mode = LB_RGB_1920X5;
2515                         else
2516                                 win->win_lb_mode = LB_RGB_1280X8;
2517                 } else {        /*SCALE_UP or SCALE_NONE */
2518                         if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
2519                             (yrgb_srcW == 0))
2520                                 pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
2521                         else if (yrgb_srcW > 2560)
2522                                 win->win_lb_mode = LB_RGB_3840X2;
2523                         else if (yrgb_srcW > 1920)
2524                                 win->win_lb_mode = LB_RGB_2560X4;
2525                         else if (yrgb_srcW > 1280)
2526                                 win->win_lb_mode = LB_RGB_1920X5;
2527                         else
2528                                 win->win_lb_mode = LB_RGB_1280X8;
2529                 }
2530         }
2531         DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
2532
2533         /*vsd/vsu scale ALGORITHM */
2534         win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2535         win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2536         win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
2537         win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
2538         switch (win->win_lb_mode) {
2539         case LB_YUV_3840X5:
2540         case LB_YUV_2560X8:
2541         case LB_RGB_1920X5:
2542         case LB_RGB_1280X8:
2543                 win->yrgb_vsu_mode = SCALE_UP_BIC;
2544                 win->cbr_vsu_mode = SCALE_UP_BIC;
2545                 break;
2546         case LB_RGB_3840X2:
2547                 if (win->yrgb_ver_scl_mode != SCALE_NONE)
2548                         pr_err("ERROR : not allow yrgb ver scale\n");
2549                 if (win->cbr_ver_scl_mode != SCALE_NONE)
2550                         pr_err("ERROR : not allow cbcr ver scale\n");
2551                 break;
2552         case LB_RGB_2560X4:
2553                 win->yrgb_vsu_mode = SCALE_UP_BIL;
2554                 win->cbr_vsu_mode = SCALE_UP_BIL;
2555                 break;
2556         default:
2557                 pr_info("%s:un supported win_lb_mode:%d\n",
2558                         __func__, win->win_lb_mode);
2559                 break;
2560         }
2561         if (win->mirror_en == 1) {      /*interlace mode must bill */
2562                 win->yrgb_vsd_mode = SCALE_DOWN_BIL;
2563         }
2564
2565         if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
2566             (win->area[0].fbdc_en == 1)) {
2567                 /*in this pattern,use bil mode,not support souble scd,
2568                 use avg mode, support double scd, but aclk should be
2569                 bigger than dclk,aclk>>dclk */
2570                 if (yrgb_srcH >= 2 * yrgb_dstH) {
2571                         pr_err("ERROR : fbdc mode,not support y scale down:");
2572                         pr_err("srcH[%d] > 2 *dstH[%d]\n",
2573                                yrgb_srcH, yrgb_dstH);
2574                 }
2575         }
2576         DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
2577             win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
2578             win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
2579
2580         /*SCALE FACTOR */
2581
2582         /*(1.1)YRGB HOR SCALE FACTOR */
2583         switch (win->yrgb_hor_scl_mode) {
2584         case SCALE_NONE:
2585                 yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2586                 break;
2587         case SCALE_UP:
2588                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
2589                 break;
2590         case SCALE_DOWN:
2591                 switch (win->yrgb_hsd_mode) {
2592                 case SCALE_DOWN_BIL:
2593                         yrgb_xscl_factor =
2594                             GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
2595                         break;
2596                 case SCALE_DOWN_AVG:
2597                         yrgb_xscl_factor =
2598                             GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
2599                         break;
2600                 default:
2601                         pr_info(
2602                                 "%s:un supported yrgb_hsd_mode:%d\n", __func__,
2603                                win->yrgb_hsd_mode);
2604                         break;
2605                 }
2606                 break;
2607         default:
2608                 pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
2609                         __func__, win->yrgb_hor_scl_mode);
2610                 break;
2611         }                       /*win->yrgb_hor_scl_mode */
2612
2613         /*(1.2)YRGB VER SCALE FACTOR */
2614         switch (win->yrgb_ver_scl_mode) {
2615         case SCALE_NONE:
2616                 yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2617                 break;
2618         case SCALE_UP:
2619                 switch (win->yrgb_vsu_mode) {
2620                 case SCALE_UP_BIL:
2621                         yrgb_yscl_factor =
2622                             GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
2623                         break;
2624                 case SCALE_UP_BIC:
2625                         if (yrgb_srcH < 3) {
2626                                 pr_err("yrgb_srcH should be");
2627                                 pr_err(" greater than 3 !!!\n");
2628                         }
2629                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
2630                                                                 yrgb_dstH);
2631                         break;
2632                 default:
2633                         pr_info("%s:un support yrgb_vsu_mode:%d\n",
2634                                 __func__, win->yrgb_vsu_mode);
2635                         break;
2636                 }
2637                 break;
2638         case SCALE_DOWN:
2639                 switch (win->yrgb_vsd_mode) {
2640                 case SCALE_DOWN_BIL:
2641                         yrgb_vscalednmult =
2642                             rk3368_get_hard_ware_vskiplines(yrgb_srcH,
2643                                                             yrgb_dstH);
2644                         yrgb_yscl_factor =
2645                             GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
2646                                                            yrgb_vscalednmult);
2647                         if (yrgb_yscl_factor >= 0x2000) {
2648                                 pr_err("yrgb_yscl_factor should be ");
2649                                 pr_err("less than 0x2000,yrgb_yscl_factor=%4x;\n",
2650                                        yrgb_yscl_factor);
2651                         }
2652                         if (yrgb_vscalednmult == 4) {
2653                                 yrgb_vsd_bil_gt4 = 1;
2654                                 yrgb_vsd_bil_gt2 = 0;
2655                         } else if (yrgb_vscalednmult == 2) {
2656                                 yrgb_vsd_bil_gt4 = 0;
2657                                 yrgb_vsd_bil_gt2 = 1;
2658                         } else {
2659                                 yrgb_vsd_bil_gt4 = 0;
2660                                 yrgb_vsd_bil_gt2 = 0;
2661                         }
2662                         break;
2663                 case SCALE_DOWN_AVG:
2664                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
2665                                                                  yrgb_dstH);
2666                         break;
2667                 default:
2668                         pr_info("%s:un support yrgb_vsd_mode:%d\n",
2669                                 __func__, win->yrgb_vsd_mode);
2670                         break;
2671                 }               /*win->yrgb_vsd_mode */
2672                 break;
2673         default:
2674                 pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
2675                         __func__, win->yrgb_ver_scl_mode);
2676                 break;
2677         }
2678         win->scale_yrgb_x = yrgb_xscl_factor;
2679         win->scale_yrgb_y = yrgb_yscl_factor;
2680         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
2681         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
2682         DBG(1, "yrgb:h_fac=%d, v_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
2683             yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
2684
2685         /*(2.1)CBCR HOR SCALE FACTOR */
2686         switch (win->cbr_hor_scl_mode) {
2687         case SCALE_NONE:
2688                 cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2689                 break;
2690         case SCALE_UP:
2691                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
2692                 break;
2693         case SCALE_DOWN:
2694                 switch (win->cbr_hsd_mode) {
2695                 case SCALE_DOWN_BIL:
2696                         cbcr_xscl_factor =
2697                             GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
2698                         break;
2699                 case SCALE_DOWN_AVG:
2700                         cbcr_xscl_factor =
2701                             GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
2702                         break;
2703                 default:
2704                         pr_info("%s:un support cbr_hsd_mode:%d\n",
2705                                 __func__, win->cbr_hsd_mode);
2706                         break;
2707                 }
2708                 break;
2709         default:
2710                 pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
2711                         __func__, win->cbr_hor_scl_mode);
2712                 break;
2713         }                       /*win->cbr_hor_scl_mode */
2714
2715         /*(2.2)CBCR VER SCALE FACTOR */
2716         switch (win->cbr_ver_scl_mode) {
2717         case SCALE_NONE:
2718                 cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
2719                 break;
2720         case SCALE_UP:
2721                 switch (win->cbr_vsu_mode) {
2722                 case SCALE_UP_BIL:
2723                         cbcr_yscl_factor =
2724                             GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
2725                         break;
2726                 case SCALE_UP_BIC:
2727                         if (cbcr_srcH < 3) {
2728                                 pr_err("cbcr_srcH should be ");
2729                                 pr_err("greater than 3 !!!\n");
2730                         }
2731                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
2732                                                                 cbcr_dstH);
2733                         break;
2734                 default:
2735                         pr_info("%s:un support cbr_vsu_mode:%d\n",
2736                                 __func__, win->cbr_vsu_mode);
2737                         break;
2738                 }
2739                 break;
2740         case SCALE_DOWN:
2741                 switch (win->cbr_vsd_mode) {
2742                 case SCALE_DOWN_BIL:
2743                         cbcr_vscalednmult =
2744                             rk3368_get_hard_ware_vskiplines(cbcr_srcH,
2745                                                             cbcr_dstH);
2746                         cbcr_yscl_factor =
2747                             GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
2748                                                            cbcr_vscalednmult);
2749                         if (cbcr_yscl_factor >= 0x2000) {
2750                                 pr_err("cbcr_yscl_factor should be less ");
2751                                 pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
2752                                        cbcr_yscl_factor);
2753                         }
2754
2755                         if (cbcr_vscalednmult == 4) {
2756                                 cbcr_vsd_bil_gt4 = 1;
2757                                 cbcr_vsd_bil_gt2 = 0;
2758                         } else if (cbcr_vscalednmult == 2) {
2759                                 cbcr_vsd_bil_gt4 = 0;
2760                                 cbcr_vsd_bil_gt2 = 1;
2761                         } else {
2762                                 cbcr_vsd_bil_gt4 = 0;
2763                                 cbcr_vsd_bil_gt2 = 0;
2764                         }
2765                         break;
2766                 case SCALE_DOWN_AVG:
2767                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
2768                                                                  cbcr_dstH);
2769                         break;
2770                 default:
2771                         pr_info("%s:un support cbr_vsd_mode:%d\n",
2772                                 __func__, win->cbr_vsd_mode);
2773                         break;
2774                 }
2775                 break;
2776         default:
2777                 pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
2778                         __func__, win->cbr_ver_scl_mode);
2779                 break;
2780         }
2781         win->scale_cbcr_x = cbcr_xscl_factor;
2782         win->scale_cbcr_y = cbcr_yscl_factor;
2783         win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
2784         win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
2785
2786         DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
2787             cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
2788         return 0;
2789 }
2790
2791 static int dsp_x_pos(int mirror_en, struct rk_screen *screen,
2792                      struct rk_lcdc_win_area *area)
2793 {
2794         int pos;
2795
2796         if (screen->x_mirror && mirror_en)
2797                 pr_err("not support both win and global mirror\n");
2798
2799         if ((!mirror_en) && (!screen->x_mirror))
2800                 pos = area->xpos + screen->mode.left_margin +
2801                         screen->mode.hsync_len;
2802         else
2803                 pos = screen->mode.xres - area->xpos -
2804                         area->xsize + screen->mode.left_margin +
2805                         screen->mode.hsync_len;
2806
2807         return pos;
2808 }
2809
2810 static int dsp_y_pos(int mirror_en, struct rk_screen *screen,
2811                      struct rk_lcdc_win_area *area)
2812 {
2813         int pos;
2814
2815         if (screen->y_mirror && mirror_en)
2816                 pr_err("not support both win and global mirror\n");
2817         if (screen->mode.vmode == FB_VMODE_NONINTERLACED) {
2818                 if ((!mirror_en) && (!screen->y_mirror))
2819                         pos = area->ypos + screen->mode.upper_margin +
2820                                 screen->mode.vsync_len;
2821                 else
2822                         pos = screen->mode.yres - area->ypos -
2823                                 area->ysize + screen->mode.upper_margin +
2824                                 screen->mode.vsync_len;
2825         } else if (screen->mode.vmode == FB_VMODE_INTERLACED) {
2826                 pos = area->ypos / 2 + screen->mode.upper_margin +
2827                         screen->mode.vsync_len;
2828                 area->ysize /= 2;
2829         }
2830
2831         return pos;
2832 }
2833
2834 static int win_0_1_set_par(struct lcdc_device *lcdc_dev,
2835                            struct rk_screen *screen, struct rk_lcdc_win *win)
2836 {
2837         u32 xact, yact, xvir, yvir, xpos, ypos;
2838         u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
2839         char fmt[9] = "NULL";
2840
2841         xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]);
2842         ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]);
2843
2844         spin_lock(&lcdc_dev->reg_lock);
2845         if (likely(lcdc_dev->clk_on)) {
2846                 rk3368_lcdc_cal_scl_fac(win);   /*fac,lb,gt2,gt4 */
2847                 switch (win->area[0].format) {
2848                 case FBDC_RGB_565:
2849                         fmt_cfg = 2;
2850                         swap_rb = 0;
2851                         win->fmt_10 = 0;
2852                         win->area[0].fbdc_fmt_cfg = 0x05;
2853                         break;
2854                 case FBDC_ARGB_888:
2855                         fmt_cfg = 0;
2856                         swap_rb = 0;
2857                         win->fmt_10 = 0;
2858                         win->area[0].fbdc_fmt_cfg = 0x0c;
2859                         break;
2860                 case FBDC_ABGR_888:
2861                         fmt_cfg = 0;
2862                         swap_rb = 1;
2863                         win->fmt_10 = 0;
2864                         win->area[0].fbdc_fmt_cfg = 0x0c;
2865                         break;
2866                 case FBDC_RGBX_888:
2867                         fmt_cfg = 0;
2868                         swap_rb = 0;
2869                         win->fmt_10 = 0;
2870                         win->area[0].fbdc_fmt_cfg = 0x3a;
2871                         break;
2872                 case ARGB888:
2873                         fmt_cfg = 0;
2874                         swap_rb = 0;
2875                         win->fmt_10 = 0;
2876                         break;
2877                 case XBGR888:
2878                 case ABGR888:
2879                         fmt_cfg = 0;
2880                         swap_rb = 1;
2881                         win->fmt_10 = 0;
2882                         break;
2883                 case RGB888:
2884                         fmt_cfg = 1;
2885                         swap_rb = 0;
2886                         win->fmt_10 = 0;
2887                         break;
2888                 case RGB565:
2889                         fmt_cfg = 2;
2890                         swap_rb = 0;
2891                         win->fmt_10 = 0;
2892                         break;
2893                 case YUV422:
2894                         fmt_cfg = 5;
2895                         swap_rb = 0;
2896                         win->fmt_10 = 0;
2897                         break;
2898                 case YUV420:
2899                         fmt_cfg = 4;
2900                         swap_rb = 0;
2901                         win->fmt_10 = 0;
2902                         break;
2903                 case YUV420_NV21:
2904                         fmt_cfg = 4;
2905                         swap_rb = 0;
2906                         swap_uv = 1;
2907                         win->fmt_10 = 0;
2908                         break;
2909                 case YUV444:
2910                         fmt_cfg = 6;
2911                         swap_rb = 0;
2912                         win->fmt_10 = 0;
2913                         break;
2914                 case YUV422_A:
2915                         fmt_cfg = 5;
2916                         swap_rb = 0;
2917                         win->fmt_10 = 1;
2918                         break;
2919                 case YUV420_A:
2920                         fmt_cfg = 4;
2921                         swap_rb = 0;
2922                         win->fmt_10 = 1;
2923                         break;
2924                 case YUV444_A:
2925                         fmt_cfg = 6;
2926                         swap_rb = 0;
2927                         win->fmt_10 = 1;
2928                         break;
2929                 default:
2930                         dev_err(lcdc_dev->driver.dev, "%s:unsupport format!\n",
2931                                 __func__);
2932                         break;
2933                 }
2934                 win->area[0].fmt_cfg = fmt_cfg;
2935                 win->area[0].swap_rb = swap_rb;
2936                 win->area[0].swap_uv = swap_uv;
2937                 win->area[0].dsp_stx = xpos;
2938                 win->area[0].dsp_sty = ypos;
2939                 xact = win->area[0].xact;
2940                 yact = win->area[0].yact;
2941                 xvir = win->area[0].xvir;
2942                 yvir = win->area[0].yvir;
2943         }
2944         if (win->area[0].fbdc_en)
2945                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
2946         rk3368_win_0_1_reg_update(&lcdc_dev->driver, win->id);
2947         spin_unlock(&lcdc_dev->reg_lock);
2948
2949         DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
2950             lcdc_dev->id, win->id, get_format_string(win->area[0].format, fmt),
2951             xact, yact, win->area[0].xsize);
2952         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
2953             win->area[0].ysize, xvir, yvir, xpos, ypos);
2954
2955         return 0;
2956 }
2957
2958
2959 static int win_2_3_set_par(struct lcdc_device *lcdc_dev,
2960                            struct rk_screen *screen, struct rk_lcdc_win *win)
2961 {
2962         int i;
2963         u8 fmt_cfg, swap_rb;
2964         char fmt[9] = "NULL";
2965
2966         if (win->mirror_en)
2967                 pr_err("win[%d] not support y mirror\n", win->id);
2968         spin_lock(&lcdc_dev->reg_lock);
2969         if (likely(lcdc_dev->clk_on)) {
2970                 DBG(2, "lcdc[%d]:win[%d]>>\n>\n", lcdc_dev->id, win->id);
2971                 for (i = 0; i < win->area_num; i++) {
2972                         switch (win->area[i].format) {
2973                         case FBDC_RGB_565:
2974                                 fmt_cfg = 2;
2975                                 swap_rb = 0;
2976                                 win->fmt_10 = 0;
2977                                 win->area[0].fbdc_fmt_cfg = 0x05;
2978                                 break;
2979                         case FBDC_ARGB_888:
2980                                 fmt_cfg = 0;
2981                                 swap_rb = 0;
2982                                 win->fmt_10 = 0;
2983                                 win->area[0].fbdc_fmt_cfg = 0x0c;
2984                                 break;
2985                         case FBDC_RGBX_888:
2986                                 fmt_cfg = 0;
2987                                 swap_rb = 0;
2988                                 win->fmt_10 = 0;
2989                                 win->area[0].fbdc_fmt_cfg = 0x3a;
2990                                 break;
2991                         case ARGB888:
2992                                 fmt_cfg = 0;
2993                                 swap_rb = 0;
2994                                 break;
2995                         case XBGR888:
2996                         case ABGR888:
2997                                 fmt_cfg = 0;
2998                                 swap_rb = 1;
2999                                 break;
3000                         case RGB888:
3001                                 fmt_cfg = 1;
3002                                 swap_rb = 0;
3003                                 break;
3004                         case RGB565:
3005                                 fmt_cfg = 2;
3006                                 swap_rb = 0;
3007                                 break;
3008                         default:
3009                                 dev_err(lcdc_dev->driver.dev,
3010                                         "%s:un supported format!\n", __func__);
3011                                 break;
3012                         }
3013                         win->area[i].fmt_cfg = fmt_cfg;
3014                         win->area[i].swap_rb = swap_rb;
3015                         win->area[i].dsp_stx =
3016                                         dsp_x_pos(win->mirror_en, screen,
3017                                                   &win->area[i]);
3018                         win->area[i].dsp_sty =
3019                                         dsp_y_pos(win->mirror_en, screen,
3020                                                   &win->area[i]);
3021                         if ((win->area[i].xact != win->area[i].xsize) ||
3022                             (win->area[i].yact != win->area[i].ysize)) {
3023                                 pr_err("win[%d]->area[%d],not support scale\n",
3024                                         win->id, i);
3025                                 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
3026                                         win->area[i].xact,win->area[i].yact,
3027                                         win->area[i].xsize,win->area[i].ysize);
3028                                 win->area[i].xsize = win->area[i].xact;
3029                                 win->area[i].ysize = win->area[i].yact;
3030                         }
3031                         DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
3032                             get_format_string(win->area[i].format, fmt),
3033                             win->area[i].xsize, win->area[i].ysize,
3034                             win->area[i].xpos, win->area[i].ypos);
3035                 }
3036         }
3037         if (win->area[0].fbdc_en)
3038                 rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
3039         rk3368_win_2_3_reg_update(&lcdc_dev->driver, win->id);
3040         spin_unlock(&lcdc_dev->reg_lock);
3041         return 0;
3042 }
3043
3044 static int hwc_set_par(struct lcdc_device *lcdc_dev,
3045                        struct rk_screen *screen, struct rk_lcdc_win *win)
3046 {
3047         u32 xact, yact, xvir, yvir, xpos, ypos;
3048         u8 fmt_cfg = 0, swap_rb;
3049         char fmt[9] = "NULL";
3050
3051         xpos = win->area[0].xpos + screen->mode.left_margin +
3052             screen->mode.hsync_len;
3053         ypos = win->area[0].ypos + screen->mode.upper_margin +
3054             screen->mode.vsync_len;
3055
3056         spin_lock(&lcdc_dev->reg_lock);
3057         if (likely(lcdc_dev->clk_on)) {
3058                 /*rk3368_lcdc_cal_scl_fac(win); *//*fac,lb,gt2,gt4 */
3059                 switch (win->area[0].format) {
3060                 case ARGB888:
3061                         fmt_cfg = 0;
3062                         swap_rb = 0;
3063                         break;
3064                 case XBGR888:
3065                 case ABGR888:
3066                         fmt_cfg = 0;
3067                         swap_rb = 1;
3068                         break;
3069                 case RGB888:
3070                         fmt_cfg = 1;
3071                         swap_rb = 0;
3072                         break;
3073                 case RGB565:
3074                         fmt_cfg = 2;
3075                         swap_rb = 0;
3076                         break;
3077                 default:
3078                         dev_err(lcdc_dev->driver.dev,
3079                                 "%s:un supported format!\n", __func__);
3080                         break;
3081                 }
3082                 win->area[0].fmt_cfg = fmt_cfg;
3083                 win->area[0].swap_rb = swap_rb;
3084                 win->area[0].dsp_stx = xpos;
3085                 win->area[0].dsp_sty = ypos;
3086                 xact = win->area[0].xact;
3087                 yact = win->area[0].yact;
3088                 xvir = win->area[0].xvir;
3089                 yvir = win->area[0].yvir;
3090         }
3091         rk3368_hwc_reg_update(&lcdc_dev->driver, 4);
3092         spin_unlock(&lcdc_dev->reg_lock);
3093
3094         DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
3095             lcdc_dev->id, __func__, get_format_string(win->area[0].format, fmt),
3096             xact, yact, win->area[0].xsize);
3097         DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
3098             win->area[0].ysize, xvir, yvir, xpos, ypos);
3099         return 0;
3100 }
3101
3102 static int rk3368_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
3103 {
3104         struct lcdc_device *lcdc_dev =
3105             container_of(dev_drv, struct lcdc_device, driver);
3106         struct rk_lcdc_win *win = NULL;
3107         struct rk_screen *screen = dev_drv->cur_screen;
3108
3109         win = dev_drv->win[win_id];
3110         switch (win_id) {
3111         case 0:
3112                 win_0_1_set_par(lcdc_dev, screen, win);
3113                 break;
3114         case 1:
3115                 win_0_1_set_par(lcdc_dev, screen, win);
3116                 break;
3117         case 2:
3118                 win_2_3_set_par(lcdc_dev, screen, win);
3119                 break;
3120         case 3:
3121                 win_2_3_set_par(lcdc_dev, screen, win);
3122                 break;
3123         case 4:
3124                 hwc_set_par(lcdc_dev, screen, win);
3125                 break;
3126         default:
3127                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
3128                 break;
3129         }
3130         return 0;
3131 }
3132
3133 static int rk3368_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
3134                              unsigned long arg, int win_id)
3135 {
3136         struct lcdc_device *lcdc_dev =
3137             container_of(dev_drv, struct lcdc_device, driver);
3138         u32 panel_size[2];
3139         void __user *argp = (void __user *)arg;
3140         struct color_key_cfg clr_key_cfg;
3141
3142         switch (cmd) {
3143         case RK_FBIOGET_PANEL_SIZE:
3144                 panel_size[0] = lcdc_dev->screen->mode.xres;
3145                 panel_size[1] = lcdc_dev->screen->mode.yres;
3146                 if (copy_to_user(argp, panel_size, 8))
3147                         return -EFAULT;
3148                 break;
3149         case RK_FBIOPUT_COLOR_KEY_CFG:
3150                 if (copy_from_user(&clr_key_cfg, argp,
3151                                    sizeof(struct color_key_cfg)))
3152                         return -EFAULT;
3153                 rk3368_lcdc_clr_key_cfg(dev_drv);
3154                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
3155                             clr_key_cfg.win0_color_key_cfg);
3156                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
3157                             clr_key_cfg.win1_color_key_cfg);
3158                 break;
3159
3160         default:
3161                 break;
3162         }
3163         return 0;
3164 }
3165
3166 static int rk3368_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
3167 {
3168         struct lcdc_device *lcdc_dev = container_of(dev_drv,
3169                                                     struct lcdc_device, driver);
3170         struct device_node *backlight;
3171         struct property *prop;
3172         u32 brightness_levels[256];
3173         u32 length, max, last;
3174
3175         if (lcdc_dev->backlight)
3176                 return 0;
3177         backlight = of_parse_phandle(lcdc_dev->dev->of_node, "backlight", 0);
3178         if (backlight) {
3179                 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
3180                 if (!lcdc_dev->backlight)
3181                         dev_info(lcdc_dev->dev, "No find backlight device\n");
3182         } else {
3183                 dev_info(lcdc_dev->dev, "No find backlight device node\n");
3184         }
3185         prop = of_find_property(backlight, "brightness-levels", &length);
3186         if (!prop)
3187                 return -EINVAL;
3188         max = length / sizeof(u32);
3189         last = max - 1;
3190         if (!of_property_read_u32_array(backlight, "brightness-levels", brightness_levels, max)) {
3191                 if (brightness_levels[0] > brightness_levels[last])
3192                         dev_drv->cabc_pwm_pol = 1;/*negative*/
3193                 else
3194                         dev_drv->cabc_pwm_pol = 0;/*positive*/
3195         } else {
3196                 dev_info(lcdc_dev->dev, "Can not read brightness-levels value\n");
3197         }
3198         return 0;
3199 }
3200
3201 static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
3202 {
3203         struct lcdc_device *lcdc_dev =
3204             container_of(dev_drv, struct lcdc_device, driver);
3205         if (dev_drv->suspend_flag)
3206                 return 0;
3207         /* close the backlight */
3208         /*rk3368_lcdc_get_backlight_device(dev_drv);
3209         if (lcdc_dev->backlight) {
3210                 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
3211                 backlight_update_status(lcdc_dev->backlight);
3212         }*/
3213
3214         dev_drv->suspend_flag = 1;
3215         flush_kthread_worker(&dev_drv->update_regs_worker);
3216
3217         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
3218                 dev_drv->trsm_ops->disable();
3219
3220         spin_lock(&lcdc_dev->reg_lock);
3221         if (likely(lcdc_dev->clk_on)) {
3222                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3223                              v_DSP_BLANK_EN(1));
3224                 lcdc_msk_reg(lcdc_dev,
3225                              INTR_CLEAR, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR,
3226                              v_FS_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1));
3227                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3228                              v_DSP_OUT_ZERO(1));
3229                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(1));
3230                 lcdc_cfg_done(lcdc_dev);
3231
3232                 if (dev_drv->iommu_enabled) {
3233                         if (dev_drv->mmu_dev)
3234                                 rockchip_iovmm_deactivate(dev_drv->dev);
3235                 }
3236
3237                 spin_unlock(&lcdc_dev->reg_lock);
3238         } else {
3239                 spin_unlock(&lcdc_dev->reg_lock);
3240                 return 0;
3241         }
3242         rk3368_lcdc_clk_disable(lcdc_dev);
3243         rk_disp_pwr_disable(dev_drv);
3244         return 0;
3245 }
3246
3247 static int rk3368_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
3248 {
3249         struct lcdc_device *lcdc_dev =
3250             container_of(dev_drv, struct lcdc_device, driver);
3251
3252         if (!dev_drv->suspend_flag)
3253                 return 0;
3254         rk_disp_pwr_enable(dev_drv);
3255
3256         if (1/*lcdc_dev->atv_layer_cnt*/) {
3257                 rk3368_lcdc_clk_enable(lcdc_dev);
3258                 rk3368_lcdc_reg_restore(lcdc_dev);
3259
3260                 spin_lock(&lcdc_dev->reg_lock);
3261                 if (dev_drv->cur_screen->dsp_lut)
3262                         rk3368_lcdc_set_lut(dev_drv,
3263                                             dev_drv->cur_screen->dsp_lut);
3264                 if (dev_drv->cur_screen->cabc_lut)
3265                         rk3368_set_cabc_lut(dev_drv,
3266                                             dev_drv->cur_screen->cabc_lut);
3267
3268                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
3269                              v_DSP_OUT_ZERO(0));
3270                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
3271                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
3272                              v_DSP_BLANK_EN(0));
3273                 lcdc_cfg_done(lcdc_dev);
3274
3275                 if (dev_drv->iommu_enabled) {
3276                         if (dev_drv->mmu_dev)
3277                                 rockchip_iovmm_activate(dev_drv->dev);
3278                 }
3279
3280                 spin_unlock(&lcdc_dev->reg_lock);
3281         }
3282         dev_drv->suspend_flag = 0;
3283
3284         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
3285                 dev_drv->trsm_ops->enable();
3286         mdelay(100);
3287         return 0;
3288 }
3289
3290 static int rk3368_lcdc_blank(struct rk_lcdc_driver *dev_drv,
3291                              int win_id, int blank_mode)
3292 {
3293         switch (blank_mode) {
3294         case FB_BLANK_UNBLANK:
3295                 rk3368_lcdc_early_resume(dev_drv);
3296                 break;
3297         case FB_BLANK_NORMAL:
3298                 rk3368_lcdc_early_suspend(dev_drv);
3299                 break;
3300         default:
3301                 rk3368_lcdc_early_suspend(dev_drv);
3302                 break;
3303         }
3304
3305         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
3306
3307         return 0;
3308 }
3309
3310 static int rk3368_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
3311                                            int win_id, int area_id)
3312 {
3313         struct lcdc_device *lcdc_dev =
3314             container_of(dev_drv, struct lcdc_device, driver);
3315         u32 win_ctrl = 0;
3316         u32 area_status = 0, state = 0;
3317
3318         switch (win_id) {
3319         case 0:
3320                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
3321                 area_status = win_ctrl & m_WIN0_EN;
3322                 break;
3323         case 1:
3324                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
3325                 area_status = win_ctrl & m_WIN1_EN;
3326                 break;
3327         case 2:
3328                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
3329                 if (area_id == 0)
3330                         area_status = win_ctrl & (m_WIN2_MST0_EN | m_WIN2_EN);
3331                 if (area_id == 1)
3332                         area_status = win_ctrl & m_WIN2_MST1_EN;
3333                 if (area_id == 2)
3334                         area_status = win_ctrl & m_WIN2_MST2_EN;
3335                 if (area_id == 3)
3336                         area_status = win_ctrl & m_WIN2_MST3_EN;
3337                 break;
3338         case 3:
3339                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
3340                 if (area_id == 0)
3341                         area_status = win_ctrl & (m_WIN3_MST0_EN | m_WIN3_EN);
3342                 if (area_id == 1)
3343                         area_status = win_ctrl & m_WIN3_MST1_EN;
3344                 if (area_id == 2)
3345                         area_status = win_ctrl & m_WIN3_MST2_EN;
3346                 if (area_id == 3)
3347                         area_status = win_ctrl & m_WIN3_MST3_EN;
3348                 break;
3349         case 4:
3350                 win_ctrl = lcdc_readl(lcdc_dev, HWC_CTRL0);
3351                 area_status = win_ctrl & m_HWC_EN;
3352                 break;
3353         default:
3354                 pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",__func__,win_id,area_id);
3355                 break;
3356         }
3357
3358         state = (area_status > 0) ? 1 : 0;
3359         return state;
3360 }
3361
3362 static int rk3368_lcdc_get_area_num(struct rk_lcdc_driver *dev_drv,
3363                                            unsigned int *area_support)
3364 {
3365         area_support[0] = 1;
3366         area_support[1] = 1;
3367         area_support[2] = 4;
3368         area_support[3] = 4;
3369
3370         return 0;
3371 }
3372
3373 /*overlay will be do at regupdate*/
3374 static int rk3368_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
3375                                bool set)
3376 {
3377         struct lcdc_device *lcdc_dev =
3378             container_of(dev_drv, struct lcdc_device, driver);
3379         struct rk_lcdc_win *win = NULL;
3380         int i, ovl;
3381         unsigned int mask, val;
3382         int z_order_num = 0;
3383         int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3384
3385         if (swap == 0) {
3386                 for (i = 0; i < 4; i++) {
3387                         win = dev_drv->win[i];
3388                         if (win->state == 1)
3389                                 z_order_num++;
3390                 }
3391                 for (i = 0; i < 4; i++) {
3392                         win = dev_drv->win[i];
3393                         if (win->state == 0)
3394                                 win->z_order = z_order_num++;
3395                         switch (win->z_order) {
3396                         case 0:
3397                                 layer0_sel = win->id;
3398                                 break;
3399                         case 1:
3400                                 layer1_sel = win->id;
3401                                 break;
3402                         case 2:
3403                                 layer2_sel = win->id;
3404                                 break;
3405                         case 3:
3406                                 layer3_sel = win->id;
3407                                 break;
3408                         default:
3409                                 break;
3410                         }
3411                 }
3412         } else {
3413                 layer0_sel = swap % 10;
3414                 layer1_sel = swap / 10 % 10;
3415                 layer2_sel = swap / 100 % 10;
3416                 layer3_sel = swap / 1000;
3417         }
3418
3419         spin_lock(&lcdc_dev->reg_lock);
3420         if (lcdc_dev->clk_on) {
3421                 if (set) {
3422                         mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
3423                             m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
3424                         val = v_DSP_LAYER0_SEL(layer0_sel) |
3425                             v_DSP_LAYER1_SEL(layer1_sel) |
3426                             v_DSP_LAYER2_SEL(layer2_sel) |
3427                             v_DSP_LAYER3_SEL(layer3_sel);
3428                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
3429                 } else {
3430                         layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3431                                                    m_DSP_LAYER0_SEL);
3432                         layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3433                                                    m_DSP_LAYER1_SEL);
3434                         layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3435                                                    m_DSP_LAYER2_SEL);
3436                         layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
3437                                                    m_DSP_LAYER3_SEL);
3438                         ovl = layer3_sel * 1000 + layer2_sel * 100 +
3439                             layer1_sel * 10 + layer0_sel;
3440                 }
3441         } else {
3442                 ovl = -EPERM;
3443         }
3444         spin_unlock(&lcdc_dev->reg_lock);
3445
3446         return ovl;
3447 }
3448
3449 static char *rk3368_lcdc_format_to_string(int format, char *fmt)
3450 {
3451         if (!fmt)
3452                 return NULL;
3453
3454         switch (format) {
3455         case 0:
3456                 strcpy(fmt, "ARGB888");
3457                 break;
3458         case 1:
3459                 strcpy(fmt, "RGB888");
3460                 break;
3461         case 2:
3462                 strcpy(fmt, "RGB565");
3463                 break;
3464         case 4:
3465                 strcpy(fmt, "YCbCr420");
3466                 break;
3467         case 5:
3468                 strcpy(fmt, "YCbCr422");
3469                 break;
3470         case 6:
3471                 strcpy(fmt, "YCbCr444");
3472                 break;
3473         default:
3474                 strcpy(fmt, "invalid\n");
3475                 break;
3476         }
3477         return fmt;
3478 }
3479 static ssize_t rk3368_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
3480                                          char *buf, int win_id)
3481 {
3482         struct lcdc_device *lcdc_dev =
3483             container_of(dev_drv, struct lcdc_device, driver);
3484         struct rk_screen *screen = dev_drv->cur_screen;
3485         u16 hsync_len = screen->mode.hsync_len;
3486         u16 left_margin = screen->mode.left_margin;
3487         u16 vsync_len = screen->mode.vsync_len;
3488         u16 upper_margin = screen->mode.upper_margin;
3489         u32 h_pw_bp = hsync_len + left_margin;
3490         u32 v_pw_bp = vsync_len + upper_margin;
3491         u32 fmt_id;
3492         char format_w0[9] = "NULL";
3493         char format_w1[9] = "NULL";
3494         char format_w2_0[9] = "NULL";
3495         char format_w2_1[9] = "NULL";
3496         char format_w2_2[9] = "NULL";
3497         char format_w2_3[9] = "NULL";
3498         char format_w3_0[9] = "NULL";
3499         char format_w3_1[9] = "NULL";
3500         char format_w3_2[9] = "NULL";
3501         char format_w3_3[9] = "NULL";
3502         char dsp_buf[100];
3503         u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
3504         u32 y_factor, uv_factor;
3505         u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
3506         u8 w0_state, w1_state, w2_state, w3_state;
3507         u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
3508         u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
3509
3510         u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
3511         u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
3512         u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
3513         u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
3514         u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
3515         u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
3516
3517         u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
3518         u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
3519         u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
3520         u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
3521         u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
3522         u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
3523         u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
3524
3525         u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
3526         u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
3527         u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
3528         u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
3529         u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
3530         u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
3531         u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
3532         u32 dclk_freq;
3533         int size = 0;
3534
3535         dclk_freq = screen->mode.pixclock;
3536         /*rk3368_lcdc_reg_dump(dev_drv); */
3537
3538         spin_lock(&lcdc_dev->reg_lock);
3539         if (lcdc_dev->clk_on) {
3540                 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
3541                 layer0_sel = (zorder & m_DSP_LAYER0_SEL) >> 8;
3542                 layer1_sel = (zorder & m_DSP_LAYER1_SEL) >> 10;
3543                 layer2_sel = (zorder & m_DSP_LAYER2_SEL) >> 12;
3544                 layer3_sel = (zorder & m_DSP_LAYER3_SEL) >> 14;
3545                 /*WIN0 */
3546                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
3547                 w0_state = win_ctrl & m_WIN0_EN;
3548                 fmt_id = (win_ctrl & m_WIN0_DATA_FMT) >> 1;
3549                 rk3368_lcdc_format_to_string(fmt_id, format_w0);
3550                 vir_info = lcdc_readl(lcdc_dev, WIN0_VIR);
3551                 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
3552                 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
3553                 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
3554                 y_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
3555                 uv_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_CBR);
3556                 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
3557                 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV) >> 16;
3558                 w0_act_x = (act_info & m_WIN0_ACT_WIDTH) + 1;
3559                 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT) >> 16) + 1;
3560                 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH) + 1;
3561                 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT) >> 16) + 1;
3562                 if (w0_state) {
3563                         w0_st_x = dsp_st & m_WIN0_DSP_XST;
3564                         w0_st_y = (dsp_st & m_WIN0_DSP_YST) >> 16;
3565                 }
3566                 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
3567                 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB) >> 16;
3568                 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
3569                 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR) >> 16;
3570
3571                 /*WIN1 */
3572                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
3573                 w1_state = win_ctrl & m_WIN1_EN;
3574                 fmt_id = (win_ctrl & m_WIN1_DATA_FMT) >> 1;
3575                 rk3368_lcdc_format_to_string(fmt_id, format_w1);
3576                 vir_info = lcdc_readl(lcdc_dev, WIN1_VIR);
3577                 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
3578                 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
3579                 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
3580                 y_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_YRGB);
3581                 uv_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_CBR);
3582                 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
3583                 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV) >> 16;
3584                 w1_act_x = (act_info & m_WIN1_ACT_WIDTH) + 1;
3585                 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT) >> 16) + 1;
3586                 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH) + 1;
3587                 w1_dsp_y = ((dsp_info & m_WIN1_DSP_HEIGHT) >> 16) + 1;
3588                 if (w1_state) {
3589                         w1_st_x = dsp_st & m_WIN1_DSP_XST;
3590                         w1_st_y = (dsp_st & m_WIN1_DSP_YST) >> 16;
3591                 }
3592                 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
3593                 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB) >> 16;
3594                 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
3595                 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR) >> 16;
3596                 /*WIN2 */
3597                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
3598                 w2_state = win_ctrl & m_WIN2_EN;
3599                 w2_0_state = (win_ctrl & 0x10) >> 4;
3600                 w2_1_state = (win_ctrl & 0x100) >> 8;
3601                 w2_2_state = (win_ctrl & 0x1000) >> 12;
3602                 w2_3_state = (win_ctrl & 0x10000) >> 16;
3603                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR0_1);
3604                 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
3605                 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1) >> 16;
3606                 vir_info = lcdc_readl(lcdc_dev, WIN2_VIR2_3);
3607                 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
3608                 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3) >> 16;
3609
3610                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT0) >> 1;
3611                 rk3368_lcdc_format_to_string(fmt_id, format_w2_0);
3612                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT1) >> 1;
3613                 rk3368_lcdc_format_to_string(fmt_id, format_w2_1);
3614                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT2) >> 1;
3615                 rk3368_lcdc_format_to_string(fmt_id, format_w2_2);
3616                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT3) >> 1;
3617                 rk3368_lcdc_format_to_string(fmt_id, format_w2_3);
3618
3619                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO0);
3620                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST0);
3621                 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0) + 1;
3622                 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0) >> 16) + 1;
3623                 if (w2_0_state) {
3624                         w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
3625                         w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0) >> 16;
3626                 }
3627                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO1);
3628                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST1);
3629                 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1) + 1;
3630                 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1) >> 16) + 1;
3631                 if (w2_1_state) {
3632                         w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
3633                         w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1) >> 16;
3634                 }
3635                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO2);
3636                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST2);
3637                 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2) + 1;
3638                 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2) >> 16) + 1;
3639                 if (w2_2_state) {
3640                         w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
3641                         w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2) >> 16;
3642                 }
3643                 dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO3);
3644                 dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST3);
3645                 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3) + 1;
3646                 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3) >> 16) + 1;
3647                 if (w2_3_state) {
3648                         w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
3649                         w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3) >> 16;
3650                 }
3651
3652                 /*WIN3 */
3653                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
3654                 w3_state = win_ctrl & m_WIN3_EN;
3655                 w3_0_state = (win_ctrl & m_WIN3_MST0_EN) >> 4;
3656                 w3_1_state = (win_ctrl & m_WIN3_MST1_EN) >> 8;
3657                 w3_2_state = (win_ctrl & m_WIN3_MST2_EN) >> 12;
3658                 w3_3_state = (win_ctrl & m_WIN3_MST3_EN) >> 16;
3659                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR0_1);
3660                 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
3661                 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1) >> 16;
3662                 vir_info = lcdc_readl(lcdc_dev, WIN3_VIR2_3);
3663                 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
3664                 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3) >> 16;
3665                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT0) >> 1;
3666                 rk3368_lcdc_format_to_string(fmt_id, format_w3_0);
3667                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT1) >> 1;
3668                 rk3368_lcdc_format_to_string(fmt_id, format_w3_1);
3669                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT2) >> 1;
3670                 rk3368_lcdc_format_to_string(fmt_id, format_w3_2);
3671                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT3) >> 1;
3672                 rk3368_lcdc_format_to_string(fmt_id, format_w3_3);
3673                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO0);
3674                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST0);
3675                 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0) + 1;
3676                 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0) >> 16) + 1;
3677                 if (w3_0_state) {
3678                         w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
3679                         w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0) >> 16;
3680                 }
3681
3682                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO1);
3683                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST1);
3684                 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1) + 1;
3685                 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1) >> 16) + 1;
3686                 if (w3_1_state) {
3687                         w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
3688                         w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1) >> 16;
3689                 }
3690
3691                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO2);
3692                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST2);
3693                 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2) + 1;
3694                 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2) >> 16) + 1;
3695                 if (w3_2_state) {
3696                         w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
3697                         w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2) >> 16;
3698                 }
3699
3700                 dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO3);
3701                 dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST3);
3702                 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3) + 1;
3703                 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3) >> 16) + 1;
3704                 if (w3_3_state) {
3705                         w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
3706                         w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3) >> 16;
3707                 }
3708
3709         } else {
3710                 spin_unlock(&lcdc_dev->reg_lock);
3711                 return -EPERM;
3712         }
3713         spin_unlock(&lcdc_dev->reg_lock);
3714         size += snprintf(dsp_buf, 80,
3715                 "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
3716                 layer3_sel, layer2_sel, layer1_sel, layer0_sel);
3717         strcat(buf, dsp_buf);
3718         memset(dsp_buf, 0, sizeof(dsp_buf));
3719         /*win0*/
3720         size += snprintf(dsp_buf, 80,
3721                  "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3722                  w0_state, format_w0, w0_vir_y, w0_vir_uv);
3723         strcat(buf, dsp_buf);
3724         memset(dsp_buf, 0, sizeof(dsp_buf));
3725
3726         size += snprintf(dsp_buf, 80,
3727                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3728                  w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
3729         strcat(buf, dsp_buf);
3730         memset(dsp_buf, 0, sizeof(dsp_buf));
3731
3732         size += snprintf(dsp_buf, 80,
3733                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3734                  w0_st_x-h_pw_bp, w0_st_y-v_pw_bp, w0_y_h_fac, w0_y_v_fac);
3735         strcat(buf, dsp_buf);
3736         memset(dsp_buf, 0, sizeof(dsp_buf));
3737
3738         size += snprintf(dsp_buf, 80,
3739                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3740                  w0_uv_h_fac, w0_uv_v_fac, lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
3741                  lcdc_readl(lcdc_dev, WIN0_CBR_MST));
3742         strcat(buf, dsp_buf);
3743         memset(dsp_buf, 0, sizeof(dsp_buf));
3744
3745         /*win1*/
3746         size += snprintf(dsp_buf, 80,
3747                  "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
3748                  w1_state, format_w1, w1_vir_y, w1_vir_uv);
3749         strcat(buf, dsp_buf);
3750         memset(dsp_buf, 0, sizeof(dsp_buf));
3751
3752         size += snprintf(dsp_buf, 80,
3753                  " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
3754                  w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
3755         strcat(buf, dsp_buf);
3756         memset(dsp_buf, 0, sizeof(dsp_buf));
3757
3758         size += snprintf(dsp_buf, 80,
3759                  "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
3760                  w1_st_x-h_pw_bp, w1_st_y-v_pw_bp, w1_y_h_fac, w1_y_v_fac);
3761         strcat(buf, dsp_buf);
3762         memset(dsp_buf, 0, sizeof(dsp_buf));
3763
3764         size += snprintf(dsp_buf, 80,
3765                  "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
3766                  w1_uv_h_fac, w1_uv_v_fac, lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
3767                  lcdc_readl(lcdc_dev, WIN1_CBR_MST));
3768         strcat(buf, dsp_buf);
3769         memset(dsp_buf, 0, sizeof(dsp_buf));
3770
3771         /*win2*/
3772         size += snprintf(dsp_buf, 80,
3773                  "win2:\n  state:%d\n",
3774                  w2_state);
3775         strcat(buf, dsp_buf);
3776         memset(dsp_buf, 0, sizeof(dsp_buf));
3777         /*area 0*/
3778         size += snprintf(dsp_buf, 80,
3779                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3780                  w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
3781         strcat(buf, dsp_buf);
3782         memset(dsp_buf, 0, sizeof(dsp_buf));
3783         size += snprintf(dsp_buf, 80,
3784                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3785                  w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
3786                  lcdc_readl(lcdc_dev, WIN2_MST0));
3787         strcat(buf, dsp_buf);
3788         memset(dsp_buf, 0, sizeof(dsp_buf));
3789
3790         /*area 1*/
3791         size += snprintf(dsp_buf, 80,
3792                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3793                  w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
3794         strcat(buf, dsp_buf);
3795         memset(dsp_buf, 0, sizeof(dsp_buf));
3796         size += snprintf(dsp_buf, 80,
3797                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3798                  w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
3799                  lcdc_readl(lcdc_dev, WIN2_MST1));
3800         strcat(buf, dsp_buf);
3801         memset(dsp_buf, 0, sizeof(dsp_buf));
3802
3803         /*area 2*/
3804         size += snprintf(dsp_buf, 80,
3805                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3806                  w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
3807         strcat(buf, dsp_buf);
3808         memset(dsp_buf, 0, sizeof(dsp_buf));
3809         size += snprintf(dsp_buf, 80,
3810                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3811                  w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
3812                  lcdc_readl(lcdc_dev, WIN2_MST2));
3813         strcat(buf, dsp_buf);
3814         memset(dsp_buf, 0, sizeof(dsp_buf));
3815
3816         /*area 3*/
3817         size += snprintf(dsp_buf, 80,
3818                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3819                  w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
3820         strcat(buf, dsp_buf);
3821         memset(dsp_buf, 0, sizeof(dsp_buf));
3822         size += snprintf(dsp_buf, 80,
3823                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3824                  w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
3825                  lcdc_readl(lcdc_dev, WIN2_MST3));
3826         strcat(buf, dsp_buf);
3827         memset(dsp_buf, 0, sizeof(dsp_buf));
3828
3829         /*win3*/
3830         size += snprintf(dsp_buf, 80,
3831                  "win3:\n  state:%d\n",
3832                  w3_state);
3833         strcat(buf, dsp_buf);
3834         memset(dsp_buf, 0, sizeof(dsp_buf));
3835         /*area 0*/
3836         size += snprintf(dsp_buf, 80,
3837                  "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3838                  w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
3839         strcat(buf, dsp_buf);
3840         memset(dsp_buf, 0, sizeof(dsp_buf));
3841         size += snprintf(dsp_buf, 80,
3842                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3843                  w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
3844                  lcdc_readl(lcdc_dev, WIN3_MST0));
3845         strcat(buf, dsp_buf);
3846         memset(dsp_buf, 0, sizeof(dsp_buf));
3847
3848         /*area 1*/
3849         size += snprintf(dsp_buf, 80,
3850                  "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3851                  w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
3852         strcat(buf, dsp_buf);
3853         memset(dsp_buf, 0, sizeof(dsp_buf));
3854         size += snprintf(dsp_buf, 80,
3855                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3856                  w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
3857                  lcdc_readl(lcdc_dev, WIN3_MST1));
3858         strcat(buf, dsp_buf);
3859         memset(dsp_buf, 0, sizeof(dsp_buf));
3860
3861         /*area 2*/
3862         size += snprintf(dsp_buf, 80,
3863                  "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3864                  w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
3865         strcat(buf, dsp_buf);
3866         memset(dsp_buf, 0, sizeof(dsp_buf));
3867         size += snprintf(dsp_buf, 80,
3868                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3869                  w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
3870                  lcdc_readl(lcdc_dev, WIN3_MST2));
3871         strcat(buf, dsp_buf);
3872         memset(dsp_buf, 0, sizeof(dsp_buf));
3873
3874         /*area 3*/
3875         size += snprintf(dsp_buf, 80,
3876                  "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
3877                  w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
3878         strcat(buf, dsp_buf);
3879         memset(dsp_buf, 0, sizeof(dsp_buf));
3880         size += snprintf(dsp_buf, 80,
3881                  " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
3882                  w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
3883                  lcdc_readl(lcdc_dev, WIN3_MST3));
3884         strcat(buf, dsp_buf);
3885         memset(dsp_buf, 0, sizeof(dsp_buf));
3886
3887         return size;
3888 }
3889
3890 static int rk3368_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
3891                                bool set)
3892 {
3893         struct lcdc_device *lcdc_dev =
3894             container_of(dev_drv, struct lcdc_device, driver);
3895         struct rk_screen *screen = dev_drv->cur_screen;
3896         u64 ft = 0;
3897         u32 dotclk;
3898         int ret;
3899         u32 pixclock;
3900         u32 x_total, y_total;
3901
3902         if (set) {
3903                 if (fps == 0) {
3904                         dev_info(dev_drv->dev, "unsupport set fps=0\n");
3905                         return 0;
3906                 }
3907                 ft = div_u64(1000000000000llu, fps);
3908                 x_total =
3909                     screen->mode.upper_margin + screen->mode.lower_margin +
3910                     screen->mode.yres + screen->mode.vsync_len;
3911                 y_total =
3912                     screen->mode.left_margin + screen->mode.right_margin +
3913                     screen->mode.xres + screen->mode.hsync_len;
3914                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
3915                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
3916                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
3917         }
3918
3919         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
3920         lcdc_dev->pixclock = pixclock;
3921         dev_drv->pixclock = lcdc_dev->pixclock;
3922         fps = rk_fb_calc_fps(screen, pixclock);
3923         screen->ft = 1000 / fps;        /*one frame time in ms */
3924
3925         if (set)
3926                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
3927                          clk_get_rate(lcdc_dev->dclk), fps);
3928
3929         return fps;
3930 }
3931
3932 static int rk3368_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
3933 {
3934         mutex_lock(&dev_drv->fb_win_id_mutex);
3935         if (order == FB_DEFAULT_ORDER)
3936                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
3937         dev_drv->fb4_win_id = order / 10000;
3938         dev_drv->fb3_win_id = (order / 1000) % 10;
3939         dev_drv->fb2_win_id = (order / 100) % 10;
3940         dev_drv->fb1_win_id = (order / 10) % 10;
3941         dev_drv->fb0_win_id = order % 10;
3942         mutex_unlock(&dev_drv->fb_win_id_mutex);
3943
3944         return 0;
3945 }
3946
3947 static int rk3368_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
3948                                   const char *id)
3949 {
3950         int win_id = 0;
3951
3952         mutex_lock(&dev_drv->fb_win_id_mutex);
3953         if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
3954                 win_id = dev_drv->fb0_win_id;
3955         else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
3956                 win_id = dev_drv->fb1_win_id;
3957         else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
3958                 win_id = dev_drv->fb2_win_id;
3959         else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
3960                 win_id = dev_drv->fb3_win_id;
3961         else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
3962                 win_id = dev_drv->fb4_win_id;
3963         mutex_unlock(&dev_drv->fb_win_id_mutex);
3964
3965         return win_id;
3966 }
3967
3968 static int rk3368_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
3969 {
3970         struct lcdc_device *lcdc_dev =
3971             container_of(dev_drv, struct lcdc_device, driver);
3972         int i;
3973         unsigned int mask, val;
3974         struct rk_lcdc_win *win = NULL;
3975
3976         spin_lock(&lcdc_dev->reg_lock);
3977         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
3978                      v_STANDBY_EN(lcdc_dev->standby));
3979         for (i = 0; i < 4; i++) {
3980                 win = dev_drv->win[i];
3981                 if ((win->state == 0) && (win->last_state == 1)) {
3982                         switch (win->id) {
3983                         case 0:
3984                                 /*lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
3985                                    for rk3288 to fix hw bug? */
3986                                 mask = m_WIN0_EN;
3987                                 val = v_WIN0_EN(0);
3988                                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
3989                                 break;
3990                         case 1:
3991                                 /*lcdc_writel(lcdc_dev,WIN1_CTRL1,0x0);
3992                                    for rk3288 to fix hw bug? */
3993                                 mask = m_WIN1_EN;
3994                                 val = v_WIN1_EN(0);
3995                                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
3996                                 break;
3997                         case 2:
3998                                 mask = m_WIN2_EN | m_WIN2_MST0_EN |
3999                                     m_WIN2_MST1_EN |
4000                                     m_WIN2_MST2_EN | m_WIN2_MST3_EN;
4001                                 val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
4002                                     v_WIN2_MST1_EN(0) |
4003                                     v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
4004                                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
4005                                 break;
4006                         case 3:
4007                                 mask = m_WIN3_EN | m_WIN3_MST0_EN |
4008                                     m_WIN3_MST1_EN |
4009                                     m_WIN3_MST2_EN | m_WIN3_MST3_EN;
4010                                 val = v_WIN3_EN(0) | v_WIN3_MST0_EN(0) |
4011                                     v_WIN3_MST1_EN(0) |
4012                                     v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
4013                                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
4014                                 break;
4015                         case 4:
4016                                 mask = m_HWC_EN;
4017                                 val = v_HWC_EN(0);
4018                                 lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
4019                                 break;
4020                         default:
4021                                 break;
4022                         }
4023                 }
4024                 win->last_state = win->state;
4025         }
4026         lcdc_cfg_done(lcdc_dev);
4027         spin_unlock(&lcdc_dev->reg_lock);
4028         return 0;
4029 }
4030
4031 static int rk3368_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
4032 {
4033         struct lcdc_device *lcdc_dev =
4034             container_of(dev_drv, struct lcdc_device, driver);
4035         spin_lock(&lcdc_dev->reg_lock);
4036         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
4037                      v_DIRECT_PATH_EN(open));
4038         lcdc_cfg_done(lcdc_dev);
4039         spin_unlock(&lcdc_dev->reg_lock);
4040         return 0;
4041 }
4042
4043 static int rk3368_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
4044 {
4045         struct lcdc_device *lcdc_dev = container_of(dev_drv,
4046                                                     struct lcdc_device, driver);
4047         spin_lock(&lcdc_dev->reg_lock);
4048         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
4049                      v_DIRECT_PATCH_SEL(win_id));
4050         lcdc_cfg_done(lcdc_dev);
4051         spin_unlock(&lcdc_dev->reg_lock);
4052         return 0;
4053 }
4054
4055 static int rk3368_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
4056 {
4057         struct lcdc_device *lcdc_dev =
4058             container_of(dev_drv, struct lcdc_device, driver);
4059         int ovl;
4060
4061         spin_lock(&lcdc_dev->reg_lock);
4062         ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
4063         spin_unlock(&lcdc_dev->reg_lock);
4064         return ovl;
4065 }
4066
4067 static int rk3368_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
4068                                       int enable)
4069 {
4070         struct lcdc_device *lcdc_dev =
4071             container_of(dev_drv, struct lcdc_device, driver);
4072         if (enable)
4073                 enable_irq(lcdc_dev->irq);
4074         else
4075                 disable_irq(lcdc_dev->irq);
4076         return 0;
4077 }
4078
4079 int rk3368_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
4080 {
4081         struct lcdc_device *lcdc_dev =
4082             container_of(dev_drv, struct lcdc_device, driver);
4083         u32 int_reg;
4084         int ret;
4085
4086         if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
4087                 int_reg = lcdc_readl(lcdc_dev, INTR_STATUS);
4088                 if (int_reg & m_LINE_FLAG0_INTR_STS) {
4089                         lcdc_dev->driver.frame_time.last_framedone_t =
4090                             lcdc_dev->driver.frame_time.framedone_t;
4091                         lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
4092                         lcdc_msk_reg(lcdc_dev, INTR_CLEAR,
4093                                      m_LINE_FLAG0_INTR_CLR,
4094                                      v_LINE_FLAG0_INTR_CLR(1));
4095                         ret = RK_LF_STATUS_FC;
4096                 } else {
4097                         ret = RK_LF_STATUS_FR;
4098                 }
4099         } else {
4100                 ret = RK_LF_STATUS_NC;
4101         }
4102
4103         return ret;
4104 }
4105
4106 static int rk3368_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
4107                                     unsigned int dsp_addr[][4])
4108 {
4109         struct lcdc_device *lcdc_dev =
4110             container_of(dev_drv, struct lcdc_device, driver);
4111         spin_lock(&lcdc_dev->reg_lock);
4112         if (lcdc_dev->clk_on) {
4113                 dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
4114                 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
4115                 dsp_addr[2][0] = lcdc_readl(lcdc_dev, WIN2_MST0);
4116                 dsp_addr[2][1] = lcdc_readl(lcdc_dev, WIN2_MST1);
4117                 dsp_addr[2][2] = lcdc_readl(lcdc_dev, WIN2_MST2);
4118                 dsp_addr[2][3] = lcdc_readl(lcdc_dev, WIN2_MST3);
4119                 dsp_addr[3][0] = lcdc_readl(lcdc_dev, WIN3_MST0);
4120                 dsp_addr[3][1] = lcdc_readl(lcdc_dev, WIN3_MST1);
4121                 dsp_addr[3][2] = lcdc_readl(lcdc_dev, WIN3_MST2);
4122                 dsp_addr[3][3] = lcdc_readl(lcdc_dev, WIN3_MST3);
4123         }
4124         spin_unlock(&lcdc_dev->reg_lock);
4125         return 0;
4126 }
4127 static u32 pwm_period_hpr, pwm_duty_lpr;
4128 static u32 cabc_status = 0;
4129
4130 int rk3368_lcdc_update_pwm(int bl_pwm_period, int bl_pwm_duty)
4131 {
4132         pwm_period_hpr = bl_pwm_period;
4133         pwm_duty_lpr = bl_pwm_duty;
4134         /*pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n",
4135         bl_pwm_period, bl_pwm_duty);*/
4136         return 0;
4137 }
4138
4139 int rk3368_lcdc_cabc_status(void)
4140 {
4141         return cabc_status;
4142 }
4143
4144 static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,
4145                                     int mode, int calc, int up,
4146                                     int down, int global)
4147 {
4148         struct lcdc_device *lcdc_dev =
4149             container_of(dev_drv, struct lcdc_device, driver);
4150         struct rk_screen *screen = dev_drv->cur_screen;
4151         u32 total_pixel, calc_pixel, stage_up, stage_down;
4152         u32 pixel_num, global_su;
4153         u32 stage_up_rec, stage_down_rec, global_su_rec, gamma_global_su_rec;
4154         u32 mask = 0, val = 0, cabc_en = 0;
4155         int *cabc_lut = NULL;
4156
4157         if (!screen->cabc_lut) {
4158                 pr_err("screen cabc lut not config, so not open cabc\n");
4159                 return 0;
4160         } else {
4161                 cabc_lut = screen->cabc_lut;
4162         }
4163
4164         if (!screen->cabc_gamma_base) {
4165                 pr_err("screen cabc_gamma_base no config, so not open cabc\n");
4166                 return 0;
4167         }
4168         dev_drv->cabc_mode = mode;
4169         cabc_en = (mode > 0) ? 1 : 0;
4170         rk3368_lcdc_get_backlight_device(dev_drv);
4171         if (cabc_en == 0) {
4172                 spin_lock(&lcdc_dev->reg_lock);
4173                 if (lcdc_dev->clk_on) {
4174                         lcdc_msk_reg(lcdc_dev, CABC_CTRL0,
4175                                      m_CABC_EN, v_CABC_EN(0));
4176                         lcdc_cfg_done(lcdc_dev);
4177                 }
4178                 pr_info("mode = 0, close cabc\n");
4179                 rk_pwm_set(pwm_period_hpr, pwm_duty_lpr);
4180                 cabc_status = 0;
4181                 spin_unlock(&lcdc_dev->reg_lock);
4182                 return 0;
4183         }
4184         if (cabc_status == 0) { /*get from pwm*/
4185                 rk_pwm_get(&pwm_period_hpr, &pwm_duty_lpr);
4186                 pr_info("pwm_period_hpr=0x%x, pwm_duty_lpr=0x%x\n",
4187                         pwm_period_hpr, pwm_duty_lpr);
4188         }
4189
4190         total_pixel = screen->mode.xres * screen->mode.yres;
4191         pixel_num = 1000 - calc;
4192         calc_pixel = (total_pixel * pixel_num) / 1000;
4193         stage_up = up;
4194         stage_down = down;
4195         global_su = global;
4196         pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n",
4197                 mode, calc, stage_up, stage_down, global_su);
4198
4199         stage_up_rec = 256 * 256 / stage_up;
4200         stage_down_rec = 256 * 256 / stage_down;
4201         global_su_rec = (256 * 256 / global_su);
4202         gamma_global_su_rec = cabc_lut[global_su_rec];
4203
4204         spin_lock(&lcdc_dev->reg_lock);
4205         if (lcdc_dev->clk_on) {
4206                 mask = m_CABC_CALC_PIXEL_NUM | m_CABC_EN;
4207                 val = v_CABC_CALC_PIXEL_NUM(calc_pixel) |
4208                         v_CABC_EN(cabc_en);
4209                 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
4210
4211                 mask = m_CABC_TOTAL_PIXEL_NUM | m_CABC_LUT_EN;
4212                 val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(1);
4213                 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
4214
4215                 mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC |
4216                     m_CABC_GLOBAL_SU_LIMIT_EN | m_CABC_GLOBAL_SU_REC;
4217                 val = v_CABC_STAGE_UP(stage_up) |
4218                     v_CABC_STAGE_UP_REC(stage_up_rec) |
4219                     v_CABC_GLOBAL_SU_LIMIT_EN(1) |
4220                     v_CABC_GLOBAL_SU_REC(gamma_global_su_rec);
4221                 lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val);
4222
4223                 mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC |
4224                     m_CABC_GLOBAL_SU;
4225                 val = v_CABC_STAGE_DOWN(stage_down) |
4226                     v_CABC_STAGE_DOWN_REC(stage_down_rec) |
4227                     v_CABC_GLOBAL_SU(global_su);
4228                 lcdc_msk_reg(lcdc_dev, CABC_CTRL3, mask, val);
4229                 lcdc_cfg_done(lcdc_dev);
4230         }
4231         cabc_status = 1;
4232         spin_unlock(&lcdc_dev->reg_lock);
4233
4234         return 0;
4235 }
4236
4237 /*
4238         a:[-30~0]:
4239             sin_hue = sin(a)*256 +0x100;
4240             cos_hue = cos(a)*256;
4241         a:[0~30]
4242             sin_hue = sin(a)*256;
4243             cos_hue = cos(a)*256;
4244 */
4245 static int rk3368_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4246                                     bcsh_hue_mode mode)
4247 {
4248         struct lcdc_device *lcdc_dev =
4249             container_of(dev_drv, struct lcdc_device, driver);
4250         u32 val;
4251
4252         spin_lock(&lcdc_dev->reg_lock);
4253         if (lcdc_dev->clk_on) {
4254                 val = lcdc_readl(lcdc_dev, BCSH_H);
4255                 switch (mode) {
4256                 case H_SIN:
4257                         val &= m_BCSH_SIN_HUE;
4258                         break;
4259                 case H_COS:
4260                         val &= m_BCSH_COS_HUE;
4261                         val >>= 16;
4262                         break;
4263                 default:
4264                         break;
4265                 }
4266         }
4267         spin_unlock(&lcdc_dev->reg_lock);
4268
4269         return val;
4270 }
4271
4272 static int rk3368_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
4273                                     int sin_hue, int cos_hue)
4274 {
4275         struct lcdc_device *lcdc_dev =
4276             container_of(dev_drv, struct lcdc_device, driver);
4277         u32 mask, val;
4278
4279         spin_lock(&lcdc_dev->reg_lock);
4280         if (lcdc_dev->clk_on) {
4281                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
4282                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
4283                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
4284                 lcdc_cfg_done(lcdc_dev);
4285         }
4286         spin_unlock(&lcdc_dev->reg_lock);
4287
4288         return 0;
4289 }
4290
4291 static int rk3368_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4292                                     bcsh_bcs_mode mode, int value)
4293 {
4294         struct lcdc_device *lcdc_dev =
4295             container_of(dev_drv, struct lcdc_device, driver);
4296         u32 mask, val;
4297
4298         spin_lock(&lcdc_dev->reg_lock);
4299         if (lcdc_dev->clk_on) {
4300                 switch (mode) {
4301                 case BRIGHTNESS:
4302                         /*from 0 to 255,typical is 128 */
4303                         if (value < 0x80)
4304                                 value += 0x80;
4305                         else if (value >= 0x80)
4306                                 value = value - 0x80;
4307                         mask = m_BCSH_BRIGHTNESS;
4308                         val = v_BCSH_BRIGHTNESS(value);
4309                         break;
4310                 case CONTRAST:
4311                         /*from 0 to 510,typical is 256 */
4312                         mask = m_BCSH_CONTRAST;
4313                         val = v_BCSH_CONTRAST(value);
4314                         break;
4315                 case SAT_CON:
4316                         /*from 0 to 1015,typical is 256 */
4317                         mask = m_BCSH_SAT_CON;
4318                         val = v_BCSH_SAT_CON(value);
4319                         break;
4320                 default:
4321                         break;
4322                 }
4323                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
4324                 lcdc_cfg_done(lcdc_dev);
4325         }
4326         spin_unlock(&lcdc_dev->reg_lock);
4327         return val;
4328 }
4329
4330 static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
4331                                     bcsh_bcs_mode mode)
4332 {
4333         struct lcdc_device *lcdc_dev =
4334             container_of(dev_drv, struct lcdc_device, driver);
4335         u32 val;
4336
4337         spin_lock(&lcdc_dev->reg_lock);
4338         if (lcdc_dev->clk_on) {
4339                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
4340                 switch (mode) {
4341                 case BRIGHTNESS:
4342                         val &= m_BCSH_BRIGHTNESS;
4343                         if (val > 0x80)
4344                                 val -= 0x80;
4345                         else
4346                                 val += 0x80;
4347                         break;
4348                 case CONTRAST:
4349                         val &= m_BCSH_CONTRAST;
4350                         val >>= 8;
4351                         break;
4352                 case SAT_CON:
4353                         val &= m_BCSH_SAT_CON;
4354                         val >>= 20;
4355                         break;
4356                 default:
4357                         break;
4358                 }
4359         }
4360         spin_unlock(&lcdc_dev->reg_lock);
4361         return val;
4362 }
4363
4364 static int rk3368_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
4365 {
4366         struct lcdc_device *lcdc_dev =
4367             container_of(dev_drv, struct lcdc_device, driver);
4368         u32 mask, val;
4369
4370         spin_lock(&lcdc_dev->reg_lock);
4371         if (lcdc_dev->clk_on) {
4372                 if (open) {
4373                         lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 0x1);
4374                         lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
4375                         lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
4376                         dev_drv->bcsh.enable = 1;
4377                 } else {
4378                         mask = m_BCSH_EN;
4379                         val = v_BCSH_EN(0);
4380                         lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
4381                         dev_drv->bcsh.enable = 0;
4382                 }
4383                 rk3368_lcdc_bcsh_path_sel(dev_drv);
4384                 lcdc_cfg_done(lcdc_dev);
4385         }
4386         spin_unlock(&lcdc_dev->reg_lock);
4387         return 0;
4388 }
4389
4390 static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
4391 {
4392         if (!enable || !dev_drv->bcsh.enable) {
4393                 rk3368_lcdc_open_bcsh(dev_drv, false);
4394                 return 0;
4395         }
4396
4397         if (dev_drv->bcsh.brightness <= 255 ||
4398             dev_drv->bcsh.contrast <= 510 ||
4399             dev_drv->bcsh.sat_con <= 1015 ||
4400             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
4401                 rk3368_lcdc_open_bcsh(dev_drv, true);
4402                 if (dev_drv->bcsh.brightness <= 255)
4403                         rk3368_lcdc_set_bcsh_bcs(dev_drv, BRIGHTNESS,
4404                                                  dev_drv->bcsh.brightness);
4405                 if (dev_drv->bcsh.contrast <= 510)
4406                         rk3368_lcdc_set_bcsh_bcs(dev_drv, CONTRAST,
4407                                                  dev_drv->bcsh.contrast);
4408                 if (dev_drv->bcsh.sat_con <= 1015)
4409                         rk3368_lcdc_set_bcsh_bcs(dev_drv, SAT_CON,
4410                                                  dev_drv->bcsh.sat_con);
4411                 if (dev_drv->bcsh.sin_hue <= 511 &&
4412                     dev_drv->bcsh.cos_hue <= 511)
4413                         rk3368_lcdc_set_bcsh_hue(dev_drv,
4414                                                  dev_drv->bcsh.sin_hue,
4415                                                  dev_drv->bcsh.cos_hue);
4416         }
4417         return 0;
4418 }
4419
4420 static int __maybe_unused
4421 rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
4422 {
4423         struct lcdc_device *lcdc_dev =
4424             container_of(dev_drv, struct lcdc_device, driver);
4425
4426         if (enable) {
4427                 spin_lock(&lcdc_dev->reg_lock);
4428                 if (likely(lcdc_dev->clk_on)) {
4429                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4430                                      v_DSP_BLACK_EN(1));
4431                         lcdc_cfg_done(lcdc_dev);
4432                 }
4433                 spin_unlock(&lcdc_dev->reg_lock);
4434         } else {
4435                 spin_lock(&lcdc_dev->reg_lock);
4436                 if (likely(lcdc_dev->clk_on)) {
4437                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
4438                                      v_DSP_BLACK_EN(0));
4439
4440                         lcdc_cfg_done(lcdc_dev);
4441                 }
4442                 spin_unlock(&lcdc_dev->reg_lock);
4443         }
4444
4445         return 0;
4446 }
4447
4448
4449 static int rk3368_lcdc_backlight_close(struct rk_lcdc_driver *dev_drv,
4450                                        int enable)
4451 {
4452         struct lcdc_device *lcdc_dev =
4453             container_of(dev_drv, struct lcdc_device, driver);
4454
4455         rk3368_lcdc_get_backlight_device(dev_drv);
4456
4457         if (enable) {
4458                 /* close the backlight */
4459                 if (lcdc_dev->backlight) {
4460                         lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
4461                         backlight_update_status(lcdc_dev->backlight);
4462                 }
4463                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4464                         dev_drv->trsm_ops->disable();
4465         } else {
4466                 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
4467                         dev_drv->trsm_ops->enable();
4468                 msleep(100);
4469                 /* open the backlight */
4470                 if (lcdc_dev->backlight) {
4471                         lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
4472                         backlight_update_status(lcdc_dev->backlight);
4473                 }
4474         }
4475
4476         return 0;
4477 }
4478
4479 static int rk3368_lcdc_set_overscan(struct rk_lcdc_driver *dev_drv,
4480                                     struct overscan *overscan)
4481 {
4482         rk3368_lcdc_post_cfg(dev_drv);
4483
4484         return 0;
4485 }
4486
4487 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
4488         .open = rk3368_lcdc_open,
4489         .win_direct_en = rk3368_lcdc_win_direct_en,
4490         .load_screen = rk3368_load_screen,
4491         .get_dspbuf_info = rk3368_get_dspbuf_info,
4492         .post_dspbuf = rk3368_post_dspbuf,
4493         .set_par = rk3368_lcdc_set_par,
4494         .pan_display = rk3368_lcdc_pan_display,
4495         .direct_set_addr = rk3368_lcdc_direct_set_win_addr,
4496         /*.lcdc_reg_update = rk3368_lcdc_reg_update,*/
4497         .blank = rk3368_lcdc_blank,
4498         .ioctl = rk3368_lcdc_ioctl,
4499         .suspend = rk3368_lcdc_early_suspend,
4500         .resume = rk3368_lcdc_early_resume,
4501         .get_win_state = rk3368_lcdc_get_win_state,
4502         .area_support_num = rk3368_lcdc_get_area_num,
4503         .ovl_mgr = rk3368_lcdc_ovl_mgr,
4504         .get_disp_info = rk3368_lcdc_get_disp_info,
4505         .fps_mgr = rk3368_lcdc_fps_mgr,
4506         .fb_get_win_id = rk3368_lcdc_get_win_id,
4507         .fb_win_remap = rk3368_fb_win_remap,
4508         .set_dsp_lut = rk3368_lcdc_set_lut,
4509         .set_cabc_lut = rk3368_set_cabc_lut,
4510         .poll_vblank = rk3368_lcdc_poll_vblank,
4511         .dpi_open = rk3368_lcdc_dpi_open,
4512         .dpi_win_sel = rk3368_lcdc_dpi_win_sel,
4513         .dpi_status = rk3368_lcdc_dpi_status,
4514         .get_dsp_addr = rk3368_lcdc_get_dsp_addr,
4515         .set_dsp_cabc = rk3368_lcdc_set_dsp_cabc,
4516         .set_dsp_bcsh_hue = rk3368_lcdc_set_bcsh_hue,
4517         .set_dsp_bcsh_bcs = rk3368_lcdc_set_bcsh_bcs,
4518         .get_dsp_bcsh_hue = rk3368_lcdc_get_bcsh_hue,
4519         .get_dsp_bcsh_bcs = rk3368_lcdc_get_bcsh_bcs,
4520         .open_bcsh = rk3368_lcdc_open_bcsh,
4521         .dump_reg = rk3368_lcdc_reg_dump,
4522         .cfg_done = rk3368_lcdc_config_done,
4523         .set_irq_to_cpu = rk3368_lcdc_set_irq_to_cpu,
4524         /*.dsp_black = rk3368_lcdc_dsp_black,*/
4525         .backlight_close = rk3368_lcdc_backlight_close,
4526         .mmu_en    = rk3368_lcdc_mmu_en,
4527         .set_overscan   = rk3368_lcdc_set_overscan,
4528 };
4529
4530 #ifdef LCDC_IRQ_EMPTY_DEBUG
4531 static int rk3368_lcdc_parse_irq(struct lcdc_device *lcdc_dev,
4532                                  unsigned int intr_status)
4533 {
4534         if (intr_status & m_WIN0_EMPTY_INTR_STS) {
4535                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN0_EMPTY_INTR_CLR,
4536                              v_WIN0_EMPTY_INTR_CLR(1));
4537                 dev_warn(lcdc_dev->dev, "win0 empty irq!");
4538         } else if (intr_status & m_WIN1_EMPTY_INTR_STS) {
4539                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN1_EMPTY_INTR_CLR,
4540                              v_WIN1_EMPTY_INTR_CLR(1));
4541                 dev_warn(lcdc_dev->dev, "win1 empty irq!");
4542         } else if (intr_status & m_WIN2_EMPTY_INTR_STS) {
4543                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN2_EMPTY_INTR_CLR,
4544                              v_WIN2_EMPTY_INTR_CLR(1));
4545                 dev_warn(lcdc_dev->dev, "win2 empty irq!");
4546         } else if (intr_status & m_WIN3_EMPTY_INTR_STS) {
4547                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN3_EMPTY_INTR_CLR,
4548                              v_WIN3_EMPTY_INTR_CLR(1));
4549                 dev_warn(lcdc_dev->dev, "win3 empty irq!");
4550         } else if (intr_status & m_HWC_EMPTY_INTR_STS) {
4551                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_HWC_EMPTY_INTR_CLR,
4552                              v_HWC_EMPTY_INTR_CLR(1));
4553                 dev_warn(lcdc_dev->dev, "HWC empty irq!");
4554         } else if (intr_status & m_POST_BUF_EMPTY_INTR_STS) {
4555                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_POST_BUF_EMPTY_INTR_CLR,
4556                              v_POST_BUF_EMPTY_INTR_CLR(1));
4557                 dev_warn(lcdc_dev->dev, "post buf empty irq!");
4558         } else if (intr_status & m_PWM_GEN_INTR_STS) {
4559                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_PWM_GEN_INTR_CLR,
4560                              v_PWM_GEN_INTR_CLR(1));
4561                 dev_warn(lcdc_dev->dev, "PWM gen irq!");
4562         }
4563         return 0;
4564 }
4565 #endif
4566
4567 static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id)
4568 {
4569         struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
4570         ktime_t timestamp = ktime_get();
4571         u32 intr_status;
4572         u32 scale_global_limit, scale_global_limit_reg;
4573         u32 cabc_pwm_lut_value;
4574         int pwm_plus;
4575         int *cabc_gamma_base = NULL;
4576         intr_status = lcdc_readl(lcdc_dev, INTR_STATUS);
4577
4578         if (intr_status & m_FS_INTR_STS) {
4579                 timestamp = ktime_get();
4580                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_INTR_CLR,
4581                              v_FS_INTR_CLR(1));
4582                 /*if(lcdc_dev->driver.wait_fs){ */
4583                 if (0) {
4584                         spin_lock(&(lcdc_dev->driver.cpl_lock));
4585                         complete(&(lcdc_dev->driver.frame_done));
4586                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
4587                 }
4588 #ifdef CONFIG_DRM_ROCKCHIP
4589                 lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
4590 #endif
4591                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
4592                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
4593         } else if (intr_status & m_LINE_FLAG0_INTR_STS) {
4594                 lcdc_dev->driver.frame_time.last_framedone_t =
4595                         lcdc_dev->driver.frame_time.framedone_t;
4596                 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
4597                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG0_INTR_CLR,
4598                              v_LINE_FLAG0_INTR_CLR(1));
4599
4600                 if (cabc_status == 1) {
4601                         cabc_gamma_base =
4602                                 lcdc_dev->driver.cur_screen->cabc_gamma_base;
4603                         scale_global_limit  = lcdc_readl(lcdc_dev, CABC_DEBUG2);
4604                         scale_global_limit_reg = scale_global_limit;
4605                         scale_global_limit >>= 16;
4606                         scale_global_limit &= 0xff;
4607
4608                         if (lcdc_dev->driver.cabc_pwm_pol == 1) {/*negative*/
4609                                 pwm_plus = pwm_period_hpr - pwm_duty_lpr;
4610                                 cabc_pwm_lut_value =
4611                                         pwm_period_hpr -
4612                                         ((cabc_gamma_base[scale_global_limit] * pwm_plus) >> 16);
4613                         } else {/*positive*/
4614                                 pwm_plus = pwm_duty_lpr;
4615                                 cabc_pwm_lut_value =
4616                                         cabc_gamma_base[scale_global_limit] *
4617                                         pwm_plus >> 16;
4618                         }
4619                         rk_pwm_set(pwm_period_hpr, cabc_pwm_lut_value);
4620                 }
4621         } else if (intr_status & m_LINE_FLAG1_INTR_STS) {
4622                 /*line flag1 */
4623                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG1_INTR_CLR,
4624                              v_LINE_FLAG1_INTR_CLR(1));
4625         } else if (intr_status & m_FS_NEW_INTR_STS) {
4626                 /*new frame start */
4627                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_NEW_INTR_CLR,
4628                              v_FS_NEW_INTR_CLR(1));
4629         } else if (intr_status & m_BUS_ERROR_INTR_STS) {
4630                 lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_BUS_ERROR_INTR_CLR,
4631                              v_BUS_ERROR_INTR_CLR(1));
4632                 dev_warn(lcdc_dev->dev, "bus error!");
4633         }
4634
4635         /* for win empty debug */
4636 #ifdef LCDC_IRQ_EMPTY_DEBUG
4637         rk3368_lcdc_parse_irq(lcdc_dev, intr_status);
4638 #endif
4639         return IRQ_HANDLED;
4640 }
4641
4642 #if defined(CONFIG_PM)
4643 static int rk3368_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
4644 {
4645         return 0;
4646 }
4647
4648 static int rk3368_lcdc_resume(struct platform_device *pdev)
4649 {
4650         return 0;
4651 }
4652 #else
4653 #define rk3368_lcdc_suspend NULL
4654 #define rk3368_lcdc_resume  NULL
4655 #endif
4656
4657 static int rk3368_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
4658 {
4659         struct device_node *np = lcdc_dev->dev->of_node;
4660         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
4661         int val;
4662
4663         if (of_property_read_u32(np, "rockchip,prop", &val))
4664                 lcdc_dev->prop = PRMRY; /*default set it as primary */
4665         else
4666                 lcdc_dev->prop = val;
4667
4668         if (of_property_read_u32(np, "rockchip,mirror", &val))
4669                 dev_drv->rotate_mode = NO_MIRROR;
4670         else
4671                 dev_drv->rotate_mode = val;
4672
4673         if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
4674                 dev_drv->cabc_mode = 0; /* default set close cabc */
4675         else
4676                 dev_drv->cabc_mode = val;
4677
4678         if (of_property_read_u32(np, "rockchip,pwr18", &val))
4679                 /*default set it as 3.xv power supply */
4680                 lcdc_dev->pwr18 = false;
4681         else
4682                 lcdc_dev->pwr18 = (val ? true : false);
4683
4684         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
4685                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
4686         else
4687                 dev_drv->fb_win_map = val;
4688
4689         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
4690                 dev_drv->bcsh.enable = false;
4691         else
4692                 dev_drv->bcsh.enable = (val ? true : false);
4693
4694         if (of_property_read_u32(np, "rockchip,brightness", &val))
4695                 dev_drv->bcsh.brightness = 0xffff;
4696         else
4697                 dev_drv->bcsh.brightness = val;
4698
4699         if (of_property_read_u32(np, "rockchip,contrast", &val))
4700                 dev_drv->bcsh.contrast = 0xffff;
4701         else
4702                 dev_drv->bcsh.contrast = val;
4703
4704         if (of_property_read_u32(np, "rockchip,sat-con", &val))
4705                 dev_drv->bcsh.sat_con = 0xffff;
4706         else
4707                 dev_drv->bcsh.sat_con = val;
4708
4709         if (of_property_read_u32(np, "rockchip,hue", &val)) {
4710                 dev_drv->bcsh.sin_hue = 0xffff;
4711                 dev_drv->bcsh.cos_hue = 0xffff;
4712         } else {
4713                 dev_drv->bcsh.sin_hue = val & 0xff;
4714                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
4715         }
4716
4717 #if defined(CONFIG_ROCKCHIP_IOMMU)
4718         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
4719                 dev_drv->iommu_enabled = 0;
4720         else
4721                 dev_drv->iommu_enabled = val;
4722 #else
4723         dev_drv->iommu_enabled = 0;
4724 #endif
4725         return 0;
4726 }
4727
4728 static int rk3368_lcdc_probe(struct platform_device *pdev)
4729 {
4730         struct lcdc_device *lcdc_dev = NULL;
4731         struct rk_lcdc_driver *dev_drv;
4732         struct device *dev = &pdev->dev;
4733         struct resource *res;
4734         struct device_node *np = pdev->dev.of_node;
4735         int prop;
4736         int ret = 0;
4737
4738         /*if the primary lcdc has not registered ,the extend
4739            lcdc register later */
4740         of_property_read_u32(np, "rockchip,prop", &prop);
4741         if (prop == EXTEND) {
4742                 if (!is_prmry_rk_lcdc_registered())
4743                         return -EPROBE_DEFER;
4744         }
4745         lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
4746         if (!lcdc_dev) {
4747                 dev_err(&pdev->dev, "rk3368 lcdc device kmalloc fail!");
4748                 return -ENOMEM;
4749         }
4750         platform_set_drvdata(pdev, lcdc_dev);
4751         lcdc_dev->dev = dev;
4752         rk3368_lcdc_parse_dt(lcdc_dev);
4753         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4754         lcdc_dev->reg_phy_base = res->start;
4755         lcdc_dev->len = resource_size(res);
4756         lcdc_dev->regs = devm_ioremap_resource(dev, res);
4757         if (IS_ERR(lcdc_dev->regs))
4758                 return PTR_ERR(lcdc_dev->regs);
4759         else
4760                 dev_info(dev, "lcdc_dev->regs=0x%lx\n", (long)lcdc_dev->regs);
4761
4762         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
4763         if (IS_ERR(lcdc_dev->regsbak))
4764                 return PTR_ERR(lcdc_dev->regsbak);
4765         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
4766         lcdc_dev->cabc_lut_addr_base = (lcdc_dev->regs + CABC_GAMMA_LUT_ADDR);
4767         lcdc_dev->grf_base =
4768                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
4769         if (IS_ERR(lcdc_dev->grf_base)) {
4770                 dev_err(&pdev->dev, "can't find lcdc grf property\n");
4771                 return PTR_ERR(lcdc_dev->grf_base);
4772         }
4773         lcdc_dev->pmugrf_base =
4774                 syscon_regmap_lookup_by_phandle(np, "rockchip,pmugrf");
4775         if (IS_ERR(lcdc_dev->pmugrf_base)) {
4776                 dev_err(&pdev->dev, "can't find lcdc pmu grf property\n");
4777                 return PTR_ERR(lcdc_dev->pmugrf_base);
4778         }
4779
4780         lcdc_dev->cru_base =
4781                 syscon_regmap_lookup_by_phandle(np, "rockchip,cru");
4782         if (IS_ERR(lcdc_dev->cru_base)) {
4783                 dev_err(&pdev->dev, "can't find lcdc cru_base property\n");
4784                 return PTR_ERR(lcdc_dev->cru_base);
4785         }
4786
4787         lcdc_dev->id = 0;
4788         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
4789         dev_drv = &lcdc_dev->driver;
4790         dev_drv->dev = dev;
4791         dev_drv->prop = prop;
4792         dev_drv->id = lcdc_dev->id;
4793         dev_drv->ops = &lcdc_drv_ops;
4794         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
4795         dev_drv->reserved_fb = 1;/*only need reserved 1 buffer*/
4796         spin_lock_init(&lcdc_dev->reg_lock);
4797
4798         lcdc_dev->irq = platform_get_irq(pdev, 0);
4799         if (lcdc_dev->irq < 0) {
4800                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
4801                         lcdc_dev->id);
4802                 return -ENXIO;
4803         }
4804
4805         ret = devm_request_irq(dev, lcdc_dev->irq, rk3368_lcdc_isr,
4806                                IRQF_DISABLED | IRQF_SHARED,
4807                                dev_name(dev), lcdc_dev);
4808         if (ret) {
4809                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
4810                         lcdc_dev->irq, ret);
4811                 return ret;
4812         }
4813
4814         if (dev_drv->iommu_enabled) {
4815                 if (lcdc_dev->id == 0) {
4816                         strcpy(dev_drv->mmu_dts_name,
4817                                VOPB_IOMMU_COMPATIBLE_NAME);
4818                 } else {
4819                         strcpy(dev_drv->mmu_dts_name,
4820                                VOPL_IOMMU_COMPATIBLE_NAME);
4821                 }
4822         }
4823
4824         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
4825         if (ret < 0) {
4826                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
4827                 return ret;
4828         }
4829         lcdc_dev->screen = dev_drv->screen0;
4830         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
4831                  lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
4832
4833         return 0;
4834 }
4835
4836 static int rk3368_lcdc_remove(struct platform_device *pdev)
4837 {
4838         return 0;
4839 }
4840
4841 static void rk3368_lcdc_shutdown(struct platform_device *pdev)
4842 {
4843         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
4844         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
4845 #if 1
4846         dev_drv->suspend_flag = 1;
4847         mdelay(100);
4848         flush_kthread_worker(&dev_drv->update_regs_worker);
4849         kthread_stop(dev_drv->update_regs_thread);
4850         rk3368_lcdc_deint(lcdc_dev);
4851         /*if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
4852                 dev_drv->trsm_ops->disable();*/
4853
4854         rk3368_lcdc_clk_disable(lcdc_dev);
4855         rk_disp_pwr_disable(dev_drv);
4856 #else
4857         rk3368_lcdc_early_suspend(&lcdc_dev->driver);
4858         rk3368_lcdc_deint(lcdc_dev);
4859 #endif
4860
4861 }
4862
4863 #if defined(CONFIG_OF)
4864 static const struct of_device_id rk3368_lcdc_dt_ids[] = {
4865         {.compatible = "rockchip,rk3368-lcdc",},
4866         {}
4867 };
4868 #endif
4869
4870 static struct platform_driver rk3368_lcdc_driver = {
4871         .probe = rk3368_lcdc_probe,
4872         .remove = rk3368_lcdc_remove,
4873         .driver = {
4874                    .name = "rk3368-lcdc",
4875                    .owner = THIS_MODULE,
4876                    .of_match_table = of_match_ptr(rk3368_lcdc_dt_ids),
4877                    },
4878         .suspend = rk3368_lcdc_suspend,
4879         .resume = rk3368_lcdc_resume,
4880         .shutdown = rk3368_lcdc_shutdown,
4881 };
4882
4883 static int __init rk3368_lcdc_module_init(void)
4884 {
4885         return platform_driver_register(&rk3368_lcdc_driver);
4886 }
4887
4888 static void __exit rk3368_lcdc_module_exit(void)
4889 {
4890         platform_driver_unregister(&rk3368_lcdc_driver);
4891 }
4892
4893 fs_initcall(rk3368_lcdc_module_init);
4894 module_exit(rk3368_lcdc_module_exit);