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