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