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