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