rk3036 lcdc: fix uboot display logo kernel open iommu splash
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3036_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3036_lcdc.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  * Author:zhengyang<zhengyang@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 <asm/div64.h>
30 #include <linux/uaccess.h>
31 #include <linux/rockchip/cpu.h>
32 #include <linux/rockchip/iomap.h>
33 #include <linux/rockchip/grf.h>
34 #include <linux/rockchip/common.h>
35 #include <dt-bindings/clock/rk_system_status.h>
36 #if defined(CONFIG_ION_ROCKCHIP)
37 #include <linux/rockchip-iovmm.h>
38 #endif
39 #include "rk3036_lcdc.h"
40
41 static int dbg_thresd;
42 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
43
44 #define DBG(level, x...) do {                   \
45         if (unlikely(dbg_thresd >= level))      \
46                 dev_info(dev_drv->dev, x);              \
47         } while (0)
48
49 #define grf_writel(offset, v)   do { \
50         writel_relaxed(v, RK_GRF_VIRT + offset); \
51         dsb(); \
52         } while (0)
53
54 static struct rk_lcdc_win lcdc_win[] = {
55         [0] = {
56                .name = "win0",
57                .id = 0,
58                .support_3d = false,
59                },
60         [1] = {
61                .name = "win1",
62                .id = 1,
63                .support_3d = false,
64                },
65         [2] = {
66                .name = "hwc",
67                .id = 2,
68                .support_3d = false,
69                },
70 };
71
72 static irqreturn_t rk3036_lcdc_isr(int irq, void *dev_id)
73 {
74         struct lcdc_device *lcdc_dev =
75             (struct lcdc_device *)dev_id;
76         ktime_t timestamp = ktime_get();
77         u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
78
79         if (int_reg & m_FS_INT_STA) {
80                 timestamp = ktime_get();
81                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
82                              v_FS_INT_CLEAR(1));
83                 /*if (lcdc_dev->driver.wait_fs) {*/
84                 if (0) {
85                         spin_lock(&(lcdc_dev->driver.cpl_lock));
86                         complete(&(lcdc_dev->driver.frame_done));
87                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
88                 }
89                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
90                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
91
92         } else if (int_reg & m_LF_INT_STA) {
93                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
94                              v_LF_INT_CLEAR(1));
95         }
96         return IRQ_HANDLED;
97 }
98
99 static int rk3036_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
100 {
101 #ifdef CONFIG_RK_FPGA
102         lcdc_dev->clk_on = 1;
103         return 0;
104 #endif
105         if (!lcdc_dev->clk_on) {
106                 clk_prepare_enable(lcdc_dev->hclk);
107                 clk_prepare_enable(lcdc_dev->dclk);
108                 clk_prepare_enable(lcdc_dev->aclk);
109 /*              clk_prepare_enable(lcdc_dev->pd);*/
110                 spin_lock(&lcdc_dev->reg_lock);
111                 lcdc_dev->clk_on = 1;
112                 spin_unlock(&lcdc_dev->reg_lock);
113         }
114
115         return 0;
116 }
117
118 static int rk3036_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
119 {
120 #ifdef CONFIG_RK_FPGA
121         lcdc_dev->clk_on = 0;
122         return 0;
123 #endif
124         if (lcdc_dev->clk_on) {
125                 spin_lock(&lcdc_dev->reg_lock);
126                 lcdc_dev->clk_on = 0;
127                 spin_unlock(&lcdc_dev->reg_lock);
128                 mdelay(25);
129                 clk_disable_unprepare(lcdc_dev->dclk);
130                 clk_disable_unprepare(lcdc_dev->hclk);
131                 clk_disable_unprepare(lcdc_dev->aclk);
132 /*              clk_disable_unprepare(lcdc_dev->pd);*/
133         }
134
135         return 0;
136 }
137
138 static int rk3036_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
139 {
140         u32 mask, val;
141         struct lcdc_device *lcdc_dev = container_of(dev_drv,
142                                         struct lcdc_device, driver);
143         mask = m_FS_INT_CLEAR | m_FS_INT_EN;
144         val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1);
145         lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
146         return 0;
147 }
148
149 static int rk3036_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
150 {
151         u32 mask, val;
152
153         spin_lock(&lcdc_dev->reg_lock);
154         if (likely(lcdc_dev->clk_on)) {
155                 mask = m_FS_INT_CLEAR | m_FS_INT_EN;
156                 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0);
157                 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
158                 spin_unlock(&lcdc_dev->reg_lock);
159         } else {
160                 spin_unlock(&lcdc_dev->reg_lock);
161         }
162         mdelay(1);
163         return 0;
164 }
165
166 static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device
167                                              *lcdc_dev)
168 {
169         int reg = 0;
170         u32 value = 0;
171
172         spin_lock(&lcdc_dev->reg_lock);
173         for (reg = 0; reg < 0xe0; reg += 4)
174                 value = lcdc_readl(lcdc_dev, reg);
175
176         spin_unlock(&lcdc_dev->reg_lock);
177 }
178
179 static int rk3036_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
180 {
181         int win0_top = 0;
182         u32 mask, val;
183         enum data_format win0_format = lcdc_dev->driver.win[0]->format;
184         enum data_format win1_format = lcdc_dev->driver.win[1]->format;
185
186         int win0_alpha_en = ((win0_format == ARGB888) ||
187                                 (win0_format == ABGR888)) ? 1 : 0;
188         int win1_alpha_en = ((win1_format == ARGB888) ||
189                                 (win1_format == ABGR888)) ? 1 : 0;
190         u32 *_pv = (u32 *)lcdc_dev->regsbak;
191
192         _pv += (DSP_CTRL0 >> 2);
193         win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
194         if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
195                 mask =  m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN |
196                         m_WIN1_PREMUL_SCALE;
197                 val = v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0) |
198                         v_WIN1_PREMUL_SCALE(0);
199                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
200
201                 mask = m_WIN0_ALPHA_MODE | m_PREMUL_ALPHA_ENABLE |
202                         m_ALPHA_MODE_SEL1;
203                 val = v_WIN0_ALPHA_MODE(1) | v_PREMUL_ALPHA_ENABLE(1) |
204                         v_ALPHA_MODE_SEL1(0);
205                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
206         } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2) &&
207                    (win1_alpha_en)) {
208                 mask =  m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN |
209                         m_WIN1_PREMUL_SCALE;
210                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1) |
211                         v_WIN1_PREMUL_SCALE(0);
212                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
213
214                 mask = m_WIN1_ALPHA_MODE | m_PREMUL_ALPHA_ENABLE |
215                         m_ALPHA_MODE_SEL1;
216                 val = v_WIN1_ALPHA_MODE(1) | v_PREMUL_ALPHA_ENABLE(1) |
217                         v_ALPHA_MODE_SEL1(0);
218                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
219         } else {
220                 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
221                 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
222                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
223         }
224
225         if (lcdc_dev->driver.win[2]->state == 1) {
226                 mask =  m_HWC_ALPAH_EN;
227                 val = v_HWC_ALPAH_EN(1);
228                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
229
230                 mask =  m_HWC_ALPHA_MODE;
231                 val = v_HWC_ALPHA_MODE(1);
232                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
233         } else {
234                 mask =  m_HWC_ALPAH_EN;
235                 val = v_HWC_ALPAH_EN(0);
236                 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
237         }
238
239         return 0;
240 }
241
242 static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
243                                    struct rk_lcdc_win *win)
244 {
245         u32 mask, val;
246         int hwc_size;
247
248         if (win->state == 1) {
249                 if (win->id == 0) {
250                         mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
251                         val = v_WIN0_EN(win->state) |
252                               v_WIN0_FORMAT(win->fmt_cfg) |
253                               v_WIN0_RB_SWAP(win->swap_rb);
254                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
255                         lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
256                                     v_X_SCL_FACTOR(win->scale_yrgb_x) |
257                                     v_Y_SCL_FACTOR(win->scale_yrgb_y));
258                         lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
259                                     v_X_SCL_FACTOR(win->scale_cbcr_x) |
260                                     v_Y_SCL_FACTOR(win->scale_cbcr_y));
261                         lcdc_msk_reg(lcdc_dev, WIN0_VIR,
262                                      m_YRGB_VIR | m_CBBR_VIR,
263                                      v_YRGB_VIR(win->area[0].y_vir_stride) |
264                                      v_CBBR_VIR(win->area[0].uv_vir_stride));
265                         lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
266                                     v_ACT_WIDTH(win->area[0].xact) |
267                                     v_ACT_HEIGHT(win->area[0].yact));
268                         lcdc_writel(lcdc_dev, WIN0_DSP_ST,
269                                     v_DSP_STX(win->area[0].dsp_stx) |
270                                     v_DSP_STY(win->area[0].dsp_sty));
271                         lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
272                                     v_DSP_WIDTH(win->post_cfg.xsize) |
273                                     v_DSP_HEIGHT(win->post_cfg.ysize));
274
275                         lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
276                                     win->area[0].y_addr);
277                         lcdc_writel(lcdc_dev, WIN0_CBR_MST,
278                                     win->area[0].uv_addr);
279                 } else if (win->id == 1) {
280                         mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
281                         val = v_WIN1_EN(win->state) |
282                               v_WIN1_FORMAT(win->fmt_cfg) |
283                               v_WIN1_RB_SWAP(win->swap_rb);
284                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
285                         lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
286                                     v_X_SCL_FACTOR(win->scale_yrgb_x) |
287                                     v_Y_SCL_FACTOR(win->scale_yrgb_y));
288
289                         lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
290                                      v_YRGB_VIR(win->area[0].y_vir_stride));
291                         lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
292                                     v_ACT_WIDTH(win->area[0].xact) |
293                                     v_ACT_HEIGHT(win->area[0].yact));
294                         lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
295                                     v_DSP_WIDTH(win->post_cfg.xsize) |
296                                     v_DSP_HEIGHT(win->post_cfg.ysize));
297                         lcdc_writel(lcdc_dev, WIN1_DSP_ST,
298                                     v_DSP_STX(win->area[0].dsp_stx) |
299                                     v_DSP_STY(win->area[0].dsp_sty));
300                         lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
301                 } else if (win->id == 2) {
302                         mask = m_HWC_EN | m_HWC_LODAD_EN;
303                         val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
304                         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
305                         if ((win->area[0].xsize == 32) &&
306                             (win->area[0].ysize == 32))
307                                 hwc_size = 0;
308                         else if ((win->area[0].xsize == 64) &&
309                                  (win->area[0].ysize == 64))
310                                 hwc_size = 1;
311                         else
312                                 dev_err(lcdc_dev->dev,
313                                         "unsupport hwc size:x=%d,y=%d\n",
314                                         win->area[0].xsize,
315                                         win->area[0].ysize);
316                         lcdc_writel(lcdc_dev, HWC_DSP_ST,
317                                     v_DSP_STX(win->area[0].dsp_stx) |
318                                     v_DSP_STY(win->area[0].dsp_sty));
319                         lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
320                 }
321         } else {
322                 win->area[0].y_addr = 0;
323                 win->area[0].uv_addr = 0;
324                 if (win->id == 0)
325                         lcdc_msk_reg(lcdc_dev,
326                                      SYS_CTRL, m_WIN0_EN, v_WIN0_EN(0));
327                 else if (win->id == 1)
328                         lcdc_msk_reg(lcdc_dev,
329                                      SYS_CTRL, m_WIN1_EN, v_WIN1_EN(0));
330                 else if (win->id == 2)
331                         lcdc_msk_reg(lcdc_dev,
332                                      SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
333         }
334         rk3036_lcdc_alpha_cfg(lcdc_dev);
335 }
336
337 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev,
338                               unsigned int win_id, bool open)
339 {
340         spin_lock(&lcdc_dev->reg_lock);
341         if (likely(lcdc_dev->clk_on) &&
342             lcdc_dev->driver.win[win_id]->state != open) {
343                 if (open) {
344                         if (!lcdc_dev->atv_layer_cnt) {
345                                 dev_info(lcdc_dev->dev,
346                                          "wakeup from standby!\n");
347                                 lcdc_dev->standby = 0;
348                         }
349                         lcdc_dev->atv_layer_cnt++;
350                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
351                         lcdc_dev->atv_layer_cnt--;
352                 }
353                 lcdc_dev->driver.win[win_id]->state = open;
354                 if (!open) {
355                         lcdc_layer_update_regs(lcdc_dev,
356                                                lcdc_dev->driver.win[win_id]);
357                         lcdc_cfg_done(lcdc_dev);
358                 }
359                 /*if no layer used,disable lcdc*/
360                 if (!lcdc_dev->atv_layer_cnt) {
361                         dev_info(lcdc_dev->dev,
362                                  "no layer is used, go to standby!\n");
363                         lcdc_dev->standby = 1;
364                 }
365         }
366         spin_unlock(&lcdc_dev->reg_lock);
367 }
368
369 static int rk3036_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
370 {
371         struct lcdc_device *lcdc_dev =
372             container_of(dev_drv, struct lcdc_device, driver);
373         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
374         struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
375         int timeout;
376         unsigned long flags;
377
378         spin_lock(&lcdc_dev->reg_lock);
379         if (likely(lcdc_dev->clk_on)) {
380                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
381                              v_LCDC_STANDBY(lcdc_dev->standby));
382                 lcdc_layer_update_regs(lcdc_dev, win0);
383                 lcdc_layer_update_regs(lcdc_dev, win1);
384                 rk3036_lcdc_alpha_cfg(lcdc_dev);
385                 lcdc_cfg_done(lcdc_dev);
386         }
387         spin_unlock(&lcdc_dev->reg_lock);
388         /* if (dev_drv->wait_fs) { */
389         if (0) {
390                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
391                 init_completion(&dev_drv->frame_done);
392                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
393                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
394                                                       msecs_to_jiffies
395                                                       (dev_drv->cur_screen->ft
396                                                        + 5));
397                 if (!timeout && (!dev_drv->frame_done.done)) {
398                         dev_warn(lcdc_dev->dev,
399                                  "wait for new frame start time out!\n");
400                         return -ETIMEDOUT;
401                 }
402         }
403         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
404         return 0;
405 }
406
407 static void rk3036_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
408 {
409         memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
410 }
411
412 static void rk3036_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
413 {
414         u32 mask, val;
415         struct lcdc_device *lcdc_dev =
416             container_of(dev_drv, struct lcdc_device, driver);
417
418         /*spin_lock(&lcdc_dev->reg_lock);*/
419         if (likely(lcdc_dev->clk_on)) {
420                 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
421                         m_AXI_OUTSTANDING_MAX_NUM;
422                 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
423                         v_AXI_MAX_OUTSTANDING_EN(1);
424                 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
425         }
426         /*spin_unlock(&lcdc_dev->reg_lock);*/
427 }
428
429 static int rk3036_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
430                         int *hwc_lut, int mode)
431 {
432         int i = 0;
433         int __iomem *c;
434         int v;
435         int len = 256*4;
436
437         struct lcdc_device *lcdc_dev =
438                         container_of(dev_drv, struct lcdc_device, driver);
439         if (dev_drv->hwc_lut == NULL)
440                 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
441
442         spin_lock(&lcdc_dev->reg_lock);
443         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
444         lcdc_cfg_done(lcdc_dev);
445         mdelay(25);
446         for (i = 0; i < 256; i++) {
447                 if (mode == 1)
448                         dev_drv->hwc_lut[i] = hwc_lut[i];
449                 v = dev_drv->hwc_lut[i];
450                 c = lcdc_dev->hwc_lut_addr_base + i;
451                 writel_relaxed(v, c);
452         }
453         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
454         lcdc_cfg_done(lcdc_dev);
455         spin_unlock(&lcdc_dev->reg_lock);
456         return 0;
457 }
458
459 #if 0
460 static int rk3036_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
461 {
462 #ifdef CONFIG_RK_FPGA
463         return 0;
464 #endif
465         int ret, fps;
466         struct lcdc_device *lcdc_dev =
467             container_of(dev_drv, struct lcdc_device, driver);
468         struct rk_screen *screen = dev_drv->cur_screen;
469
470         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
471         if (ret)
472                 dev_err(dev_drv->dev,
473                         "set lcdc%d dclk failed\n", lcdc_dev->id);
474         lcdc_dev->pixclock =
475                  div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
476         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
477
478         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
479         screen->ft = 1000 / fps;
480         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
481                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
482         return 0;
483 }
484 #endif
485 /********do basic init*********/
486 static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
487 {
488         struct lcdc_device *lcdc_dev = container_of(dev_drv,
489                                 struct lcdc_device, driver);
490
491         if (lcdc_dev->pre_init)
492                 return 0;
493         lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
494         lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
495         lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
496 /*      lcdc_dev->pd   = devm_clk_get(lcdc_dev->dev, "pd_lcdc"); */
497
498         if (/*IS_ERR(lcdc_dev->pd) ||*/ (IS_ERR(lcdc_dev->aclk)) ||
499             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
500                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
501                         lcdc_dev->id);
502         }
503
504         rk_disp_pwr_enable(dev_drv);
505         rk3036_lcdc_clk_enable(lcdc_dev);
506
507         /*backup reg config at uboot*/
508         rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
509         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN,
510                      v_AUTO_GATING_EN(0));
511         lcdc_cfg_done(lcdc_dev);
512         if (dev_drv->iommu_enabled)
513                 /*disable win0 to workaround iommu pagefault*/
514                 lcdc_layer_enable(lcdc_dev, 0, 0);
515         lcdc_dev->pre_init = true;
516
517         return 0;
518 }
519
520 static int rk3036_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
521 {
522         int ret = -EINVAL;
523         int fps;
524         u16 face = 0;
525         struct lcdc_device *lcdc_dev = container_of(dev_drv,
526                                                 struct lcdc_device, driver);
527         struct rk_screen *screen = dev_drv->cur_screen;
528         u16 right_margin = screen->mode.right_margin;
529         u16 left_margin = screen->mode.left_margin;
530         u16 lower_margin = screen->mode.lower_margin;
531         u16 upper_margin = screen->mode.upper_margin;
532         u16 x_res = screen->mode.xres;
533         u16 y_res = screen->mode.yres;
534         u32 mask, val;
535
536         spin_lock(&lcdc_dev->reg_lock);
537         if (likely(lcdc_dev->clk_on)) {
538                 switch (screen->type) {
539                 case SCREEN_HDMI:
540                         mask = m_HDMI_DCLK_EN;
541                         val = v_HDMI_DCLK_EN(1);
542                         if (screen->pixelrepeat) {
543                                 mask |= m_CORE_CLK_DIV_EN;
544                                 val |= v_CORE_CLK_DIV_EN(1);
545                         } else {
546                                 mask |= m_CORE_CLK_DIV_EN;
547                                 val |= v_CORE_CLK_DIV_EN(0);
548                         }
549                         lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
550                         mask = (1 << 4) | (1 << 5) | (1 << 6);
551                         val = (screen->pin_hsync << 4) |
552                                 (screen->pin_vsync << 5) |
553                                 (screen->pin_den << 6);
554                         grf_writel(RK3036_GRF_SOC_CON2, (mask << 16) | val);
555                         break;
556                 case SCREEN_TVOUT:
557                         mask = m_TVE_DAC_DCLK_EN;
558                         val = v_TVE_DAC_DCLK_EN(1);
559                         if (screen->pixelrepeat) {
560                                 mask |= m_CORE_CLK_DIV_EN;
561                                 val |= v_CORE_CLK_DIV_EN(1);
562                         } else {
563                                 mask |= m_CORE_CLK_DIV_EN;
564                                 val |= v_CORE_CLK_DIV_EN(0);
565                         }
566                         lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
567                         if ((x_res == 720) && (y_res == 576)) {
568                                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
569                                              m_TVE_MODE, v_TVE_MODE(TV_PAL));
570                         } else if ((x_res == 720) && (y_res == 480)) {
571                                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
572                                              m_TVE_MODE, v_TVE_MODE(TV_NTSC));
573                         } else {
574                                 dev_err(lcdc_dev->dev,
575                                         "unsupported video timing!\n");
576                                 return -1;
577                         }
578                         break;
579                 default:
580                         dev_err(lcdc_dev->dev, "un supported interface!\n");
581                         break;
582                 }
583
584                 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
585                     m_DEN_POL | m_DCLK_POL;
586                 val = v_DSP_OUT_FORMAT(face) |
587                         v_HSYNC_POL(screen->pin_hsync) |
588                         v_VSYNC_POL(screen->pin_vsync) |
589                         v_DEN_POL(screen->pin_den) |
590                         v_DCLK_POL(screen->pin_dclk);
591                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
592
593                 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
594                     m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
595                     m_DSP_DUMMY_SWAP | m_BLANK_EN;
596
597                 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
598                     v_DSP_RB_SWAP(screen->swap_rb) |
599                     v_DSP_RG_SWAP(screen->swap_rg) |
600                     v_DSP_DELTA_SWAP(screen->swap_delta) |
601                                      v_DSP_DUMMY_SWAP(screen->swap_dumy) |
602                                                       v_BLANK_EN(0) |
603                                      v_BLACK_EN(0);
604                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
605                 val =
606                     v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
607                                                                hsync_len +
608                                                                left_margin +
609                                                                x_res +
610                                                                right_margin);
611                 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
612                 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
613                     v_HASP(screen->mode.hsync_len + left_margin);
614                 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
615
616                 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
617                         /*First Field Timing*/
618                         lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
619                                     v_VSYNC(screen->mode.vsync_len) |
620                                     v_VERPRD(2 * (screen->mode.vsync_len +
621                                                   upper_margin + lower_margin)
622                                              + y_res + 1));
623                         lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
624                                     v_VAEP(screen->mode.vsync_len +
625                                         upper_margin + y_res/2) |
626                                     v_VASP(screen->mode.vsync_len +
627                                         upper_margin));
628                         /*Second Field Timing*/
629                         lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
630                                     v_VSYNC_ST_F1(screen->mode.vsync_len +
631                                                   upper_margin + y_res/2 +
632                                                   lower_margin) |
633                                     v_VSYNC_END_F1(2 * screen->mode.vsync_len
634                                                    + upper_margin + y_res/2 +
635                                                    lower_margin));
636                         lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
637                                     v_VAEP(2 * (screen->mode.vsync_len +
638                                                 upper_margin) + y_res +
639                                                 lower_margin + 1) |
640                                     v_VASP(2 * (screen->mode.vsync_len +
641                                                 upper_margin) + y_res/2 +
642                                                 lower_margin + 1));
643
644                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
645                                      m_INTERLACE_DSP_EN |
646                                      m_INTERLACE_DSP_POL |
647                                      m_WIN1_DIFF_DCLK_EN |
648                                      m_WIN0_YRGB_DEFLICK_EN |
649                                      m_WIN0_CBR_DEFLICK_EN |
650                                      m_WIN0_INTERLACE_EN |
651                                      m_WIN1_INTERLACE_EN,
652                                      v_INTERLACE_DSP_EN(1) |
653                                      v_INTERLACE_DSP_POL(0) |
654                                      v_WIN1_DIFF_DCLK_EN(1) |
655                                      v_WIN0_YRGB_DEFLICK_EN(1) |
656                                      v_WIN0_CBR_DEFLICK_EN(1) |
657                                      v_WIN0_INTERLACE_EN(1) |
658                                      v_WIN1_INTERLACE_EN(1));
659                 } else {
660                         val = v_VSYNC(screen->mode.vsync_len) |
661                               v_VERPRD(screen->mode.vsync_len + upper_margin +
662                                         y_res + lower_margin);
663                         lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
664
665                         val = v_VAEP(screen->mode.vsync_len +
666                                      upper_margin + y_res) |
667                             v_VASP(screen->mode.vsync_len +
668                                    screen->mode.upper_margin);
669                         lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
670
671                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
672                                      m_INTERLACE_DSP_EN |
673                                      m_WIN1_DIFF_DCLK_EN |
674                                      m_WIN0_YRGB_DEFLICK_EN |
675                                      m_WIN0_CBR_DEFLICK_EN |
676                                      m_WIN0_INTERLACE_EN |
677                                      m_WIN1_INTERLACE_EN,
678                                      v_INTERLACE_DSP_EN(0) |
679                                      v_WIN1_DIFF_DCLK_EN(0) |
680                                      v_WIN0_YRGB_DEFLICK_EN(0) |
681                                      v_WIN0_CBR_DEFLICK_EN(0) |
682                                      v_WIN0_INTERLACE_EN(1) |
683                                      v_WIN1_INTERLACE_EN(1));
684                 }
685         }
686         spin_unlock(&lcdc_dev->reg_lock);
687
688         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
689         if (ret)
690                 dev_err(dev_drv->dev,
691                         "set lcdc%d dclk failed\n", lcdc_dev->id);
692         lcdc_dev->pixclock =
693             div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
694         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
695
696         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
697         screen->ft = 1000 / fps;
698         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
699                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
700         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
701                 dev_drv->trsm_ops->enable();
702         if (screen->init)
703                 screen->init();
704
705         return 0;
706 }
707
708 static int rk3036_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
709                             bool open)
710 {
711         struct lcdc_device *lcdc_dev = container_of(dev_drv,
712                                         struct lcdc_device, driver);
713
714         /*enable clk,when first layer open */
715         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
716                 rk3036_lcdc_pre_init(dev_drv);
717                 rk3036_lcdc_clk_enable(lcdc_dev);
718         #if defined(CONFIG_ROCKCHIP_IOMMU)
719                 if (dev_drv->iommu_enabled) {
720                         if (!dev_drv->mmu_dev) {
721                                 dev_drv->mmu_dev =
722                                 rk_fb_get_sysmmu_device_by_compatible(
723                                         dev_drv->mmu_dts_name);
724                                 if (dev_drv->mmu_dev) {
725                                         rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
726                                                                   dev_drv->dev);
727                                 } else {
728                                         dev_err(dev_drv->dev,
729                                                 "failed to get iommu device\n"
730                                                 );
731                                         return -1;
732                                 }
733                         }
734                 }
735         #endif
736                 rk3036_lcdc_reg_restore(lcdc_dev);
737                 /*if (dev_drv->iommu_enabled)
738                         rk3036_lcdc_mmu_en(dev_drv);*/
739                 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
740                         /*rk3036_lcdc_set_dclk(dev_drv);*/
741                         rk3036_lcdc_enable_irq(dev_drv);
742                 } else {
743                         rk3036_load_screen(dev_drv, 1);
744                 }
745         }
746
747         if (win_id < ARRAY_SIZE(lcdc_win))
748                 lcdc_layer_enable(lcdc_dev, win_id, open);
749         else
750                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
751
752         /*when all layer closed,disable clk */
753         if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
754                 rk3036_lcdc_disable_irq(lcdc_dev);
755                 rk3036_lcdc_reg_update(dev_drv);
756                 #if defined(CONFIG_ROCKCHIP_IOMMU)
757                 if (dev_drv->iommu_enabled) {
758                         if (dev_drv->mmu_dev)
759                                 rockchip_iovmm_deactivate(dev_drv->dev);
760                 }
761                 #endif
762                 rk3036_lcdc_clk_disable(lcdc_dev);
763         }
764
765         return 0;
766 }
767
768 static int rk3036_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
769 {
770         struct lcdc_device *lcdc_dev =
771                         container_of(dev_drv, struct lcdc_device, driver);
772         struct rk_screen *screen = dev_drv->cur_screen;
773         struct rk_lcdc_win *win = NULL;
774         char fmt[9] = "NULL";
775
776         if (!screen) {
777                 dev_err(dev_drv->dev, "screen is null!\n");
778                 return -ENOENT;
779         }
780
781         if (win_id == 0) {
782                 win = dev_drv->win[0];
783         } else if (win_id == 1) {
784                 win = dev_drv->win[1];
785         } else if (win_id == 2) {
786                 win = dev_drv->win[2];
787         } else {
788                 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
789                 return -EINVAL;
790         }
791
792         spin_lock(&lcdc_dev->reg_lock);
793         win->post_cfg.xpos = win->area[0].xpos * (dev_drv->overscan.left +
794                 dev_drv->overscan.right)/200 + screen->mode.xres *
795                         (100 - dev_drv->overscan.left) / 200;
796
797         win->post_cfg.ypos = win->area[0].ypos * (dev_drv->overscan.top +
798                 dev_drv->overscan.bottom)/200 +
799                 screen->mode.yres *
800                         (100 - dev_drv->overscan.top) / 200;
801         win->post_cfg.xsize = win->area[0].xsize *
802                                 (dev_drv->overscan.left +
803                                 dev_drv->overscan.right)/200;
804         win->post_cfg.ysize = win->area[0].ysize *
805                                 (dev_drv->overscan.top +
806                                 dev_drv->overscan.bottom)/200;
807
808         win->area[0].dsp_stx = win->post_cfg.xpos + screen->mode.left_margin +
809                                 screen->mode.hsync_len;
810         if (screen->mode.vmode == FB_VMODE_INTERLACED) {
811                 win->post_cfg.ysize /= 2;
812                 win->area[0].dsp_sty = win->post_cfg.ypos/2 +
813                                         screen->mode.upper_margin +
814                                         screen->mode.vsync_len;
815         } else {
816                 win->area[0].dsp_sty = win->post_cfg.ypos +
817                                         screen->mode.upper_margin +
818                                         screen->mode.vsync_len;
819         }
820         win->scale_yrgb_x = calscale(win->area[0].xact, win->post_cfg.xsize);
821         win->scale_yrgb_y = calscale(win->area[0].yact, win->post_cfg.ysize);
822
823         switch (win->format) {
824         case ARGB888:
825                 win->fmt_cfg = VOP_FORMAT_ARGB888;
826                 win->swap_rb = 0;
827                 break;
828         case XBGR888:
829                 win->fmt_cfg = VOP_FORMAT_ARGB888;
830                 win->swap_rb = 1;
831                 break;
832         case ABGR888:
833                 win->fmt_cfg = VOP_FORMAT_ARGB888;
834                 win->swap_rb = 1;
835                 break;
836         case RGB888:
837                 win->fmt_cfg = VOP_FORMAT_RGB888;
838                 win->swap_rb = 0;
839                 break;
840         case RGB565:
841                 win->fmt_cfg = VOP_FORMAT_RGB565;
842                 win->swap_rb = 0;
843                 break;
844         case YUV444:
845                 if (win_id == 0) {
846                         win->fmt_cfg = VOP_FORMAT_YCBCR444;
847                         win->scale_cbcr_x = calscale(win->area[0].xact,
848                                                      win->post_cfg.xsize);
849                         win->scale_cbcr_y = calscale(win->area[0].yact,
850                                                      win->post_cfg.ysize);
851                         win->swap_rb = 0;
852                 } else {
853                         dev_err(lcdc_dev->driver.dev,
854                                 "%s:un supported format!\n",
855                                 __func__);
856                 }
857                 break;
858         case YUV422:
859                 if (win_id == 0) {
860                         win->fmt_cfg = VOP_FORMAT_YCBCR422;
861                         win->scale_cbcr_x = calscale((win->area[0].xact / 2),
862                                                      win->post_cfg.xsize);
863                         win->scale_cbcr_y = calscale(win->area[0].yact,
864                                                      win->post_cfg.ysize);
865                         win->swap_rb = 0;
866                 } else {
867                         dev_err(lcdc_dev->driver.dev,
868                                 "%s:un supported format!\n",
869                                 __func__);
870                 }
871                 break;
872         case YUV420:
873                 if (win_id == 0) {
874                         win->fmt_cfg = VOP_FORMAT_YCBCR420;
875                         win->scale_cbcr_x = calscale(win->area[0].xact / 2,
876                                                      win->post_cfg.xsize);
877                         win->scale_cbcr_y = calscale(win->area[0].yact / 2,
878                                                      win->post_cfg.ysize);
879                         win->swap_rb = 0;
880                 } else {
881                         dev_err(lcdc_dev->driver.dev,
882                                 "%s:un supported format!\n",
883                                 __func__);
884                 }
885                 break;
886         default:
887                 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
888                         __func__);
889                 break;
890         }
891         spin_unlock(&lcdc_dev->reg_lock);
892
893         DBG(2, "lcdc%d>>%s\n"
894                 ">>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
895                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
896                 __func__, get_format_string(win->format, fmt),
897                 win->area[0].xact, win->area[0].yact, win->post_cfg.xsize,
898                 win->post_cfg.ysize, win->area[0].xvir, win->area[0].yvir,
899                 win->post_cfg.xpos, win->post_cfg.ypos);
900         return 0;
901 }
902
903 static int rk3036_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
904 {
905         struct lcdc_device *lcdc_dev = container_of(dev_drv,
906                                                 struct lcdc_device, driver);
907         struct rk_lcdc_win *win = NULL;
908         struct rk_screen *screen = dev_drv->cur_screen;
909
910         if (!screen) {
911                 dev_err(dev_drv->dev, "screen is null!\n");
912                 return -ENOENT;
913         }
914
915         if (win_id == 0) {
916                 win = dev_drv->win[0];
917         } else if (win_id == 1) {
918                 win = dev_drv->win[1];
919         } else if (win_id == 2) {
920                 win = dev_drv->win[2];
921         } else {
922                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
923                 return -EINVAL;
924         }
925
926         spin_lock(&lcdc_dev->reg_lock);
927         if (likely(lcdc_dev->clk_on)) {
928                 win->area[0].y_addr = win->area[0].smem_start +
929                                         win->area[0].y_offset;
930                 win->area[0].uv_addr = win->area[0].cbr_start +
931                                         win->area[0].c_offset;
932                 if (win->area[0].y_addr)
933                         lcdc_layer_update_regs(lcdc_dev, win);
934                 /*lcdc_cfg_done(lcdc_dev);*/
935         }
936         spin_unlock(&lcdc_dev->reg_lock);
937
938         DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
939             lcdc_dev->id, __func__, win->area[0].y_addr,
940             win->area[0].uv_addr, win->area[0].y_offset);
941          /* this is the first frame of the system,
942                 enable frame start interrupt*/
943         if ((dev_drv->first_frame))  {
944                 dev_drv->first_frame = 0;
945                 rk3036_lcdc_enable_irq(dev_drv);
946         }
947         return 0;
948 }
949
950 static int rk3036_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
951                              unsigned long arg, int win_id)
952 {
953         struct lcdc_device *lcdc_dev = container_of(dev_drv,
954                                         struct lcdc_device, driver);
955         u32 panel_size[2];
956         void __user *argp = (void __user *)arg;
957         struct color_key_cfg clr_key_cfg;
958
959         switch (cmd) {
960         case RK_FBIOGET_PANEL_SIZE:
961                 panel_size[0] = lcdc_dev->screen->mode.xres;
962                 panel_size[1] = lcdc_dev->screen->mode.yres;
963                 if (copy_to_user(argp, panel_size, 8))
964                         return -EFAULT;
965                 break;
966         case RK_FBIOPUT_COLOR_KEY_CFG:
967                 if (copy_from_user(&clr_key_cfg, argp,
968                                    sizeof(struct color_key_cfg)))
969                         return -EFAULT;
970                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
971                             clr_key_cfg.win0_color_key_cfg);
972                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
973                             clr_key_cfg.win1_color_key_cfg);
974                 break;
975
976         default:
977                 break;
978         }
979         return 0;
980 }
981
982 static int rk3036_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
983                                   const char *id)
984 {
985         int win_id = 0;
986
987         mutex_lock(&dev_drv->fb_win_id_mutex);
988         if (!strcmp(id, "fb0"))
989                 win_id = dev_drv->fb0_win_id;
990         else if (!strcmp(id, "fb1"))
991                 win_id = dev_drv->fb1_win_id;
992         else if (!strcmp(id, "fb2"))
993                 win_id = dev_drv->fb2_win_id;
994         mutex_unlock(&dev_drv->fb_win_id_mutex);
995
996         return win_id;
997 }
998
999 static int rk3036_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
1000                                      int win_id)
1001 {
1002         return dev_drv->win[win_id]->state;
1003 }
1004
1005 static int rk3036_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1006                                bool set)
1007 {
1008         struct lcdc_device *lcdc_dev =
1009             container_of(dev_drv, struct lcdc_device, driver);
1010         int ovl;
1011
1012         spin_lock(&lcdc_dev->reg_lock);
1013         if (lcdc_dev->clk_on) {
1014                 if (set) {
1015                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1016                                      v_WIN0_TOP(swap));
1017                         ovl = swap;
1018                 } else {
1019                         ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1020                 }
1021         } else {
1022                 ovl = -EPERM;
1023         }
1024         spin_unlock(&lcdc_dev->reg_lock);
1025
1026         return ovl;
1027 }
1028
1029 static int rk3036_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1030 {
1031         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1032                                         struct lcdc_device, driver);
1033         if (dev_drv->suspend_flag)
1034                 return 0;
1035         dev_drv->suspend_flag = 1;
1036         flush_kthread_worker(&dev_drv->update_regs_worker);
1037
1038         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1039                 dev_drv->trsm_ops->disable();
1040         spin_lock(&lcdc_dev->reg_lock);
1041         if (likely(lcdc_dev->clk_on)) {
1042                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
1043                              v_BLANK_EN(1));
1044                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1045                              v_FS_INT_CLEAR(1));
1046                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1047                              v_DSP_OUT_ZERO(1));
1048                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1049                              v_LCDC_STANDBY(1));
1050                 lcdc_cfg_done(lcdc_dev);
1051                 if (dev_drv->iommu_enabled) {
1052                         if (dev_drv->mmu_dev)
1053                                 rockchip_iovmm_deactivate(dev_drv->dev);
1054                 }
1055                 spin_unlock(&lcdc_dev->reg_lock);
1056         } else {
1057                 spin_unlock(&lcdc_dev->reg_lock);
1058                 return 0;
1059         }
1060         rk3036_lcdc_clk_disable(lcdc_dev);
1061         rk_disp_pwr_disable(dev_drv);
1062         return 0;
1063 }
1064
1065 static int rk3036_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1066 {
1067         struct lcdc_device *lcdc_dev =
1068             container_of(dev_drv, struct lcdc_device, driver);
1069
1070         if (!dev_drv->suspend_flag)
1071                 return 0;
1072         rk_disp_pwr_enable(dev_drv);
1073         dev_drv->suspend_flag = 0;
1074
1075         if (lcdc_dev->atv_layer_cnt) {
1076                 rk3036_lcdc_clk_enable(lcdc_dev);
1077                 rk3036_lcdc_reg_restore(lcdc_dev);
1078                 /*set hwc lut*/
1079                 rk3036_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1080
1081                 spin_lock(&lcdc_dev->reg_lock);
1082
1083                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1084                              v_DSP_OUT_ZERO(0));
1085                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1086                              v_LCDC_STANDBY(0));
1087                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
1088                              v_BLANK_EN(0));
1089                 lcdc_cfg_done(lcdc_dev);
1090                 if (dev_drv->iommu_enabled) {
1091                         if (dev_drv->mmu_dev)
1092                                 rockchip_iovmm_activate(dev_drv->dev);
1093                 }
1094                 spin_unlock(&lcdc_dev->reg_lock);
1095         }
1096
1097         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1098                 dev_drv->trsm_ops->enable();
1099         return 0;
1100 }
1101
1102
1103 static int rk3036_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1104                              int win_id, int blank_mode)
1105 {
1106         switch (blank_mode) {
1107         case FB_BLANK_UNBLANK:
1108                 rk3036_lcdc_early_resume(dev_drv);
1109                 break;
1110         case FB_BLANK_NORMAL:
1111                 rk3036_lcdc_early_suspend(dev_drv);
1112                 break;
1113         default:
1114                 rk3036_lcdc_early_suspend(dev_drv);
1115                 break;
1116         }
1117
1118         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1119
1120         return 0;
1121 }
1122
1123 static int rk3036_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1124 {
1125         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1126                                         struct lcdc_device, driver);
1127
1128         spin_lock(&lcdc_dev->reg_lock);
1129         if (lcdc_dev->clk_on) {
1130                 #if defined(CONFIG_ROCKCHIP_IOMMU)
1131                 if (dev_drv->iommu_enabled) {
1132                         if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
1133                                 lcdc_dev->iommu_status = 1;
1134                                 if (support_uboot_display() &&
1135                                     lcdc_dev->prop == PRMRY) {
1136                                         lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1137                                                      m_WIN0_EN,
1138                                                      v_WIN0_EN(0));
1139                                 }
1140                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1141                                              v_LCDC_STANDBY(1));
1142                                 lcdc_cfg_done(lcdc_dev);
1143                                 mdelay(50);
1144                                 rockchip_iovmm_activate(dev_drv->dev);
1145                                 rk3036_lcdc_mmu_en(dev_drv);
1146                         }
1147                 }
1148                 #endif
1149
1150                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1151                              v_LCDC_STANDBY(lcdc_dev->standby));
1152                 lcdc_cfg_done(lcdc_dev);
1153         }
1154         spin_unlock(&lcdc_dev->reg_lock);
1155         return 0;
1156 }
1157
1158 /*
1159         a:[-30~0]:
1160             sin_hue = sin(a)*256 +0x100;
1161             cos_hue = cos(a)*256;
1162         a:[0~30]
1163             sin_hue = sin(a)*256;
1164             cos_hue = cos(a)*256;
1165 */
1166 static int rk3036_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1167                                     bcsh_hue_mode mode)
1168 {
1169         struct lcdc_device *lcdc_dev =
1170             container_of(dev_drv, struct lcdc_device, driver);
1171         u32 val;
1172
1173         spin_lock(&lcdc_dev->reg_lock);
1174         if (lcdc_dev->clk_on) {
1175                 val = lcdc_readl(lcdc_dev, BCSH_H);
1176                 switch (mode) {
1177                 case H_SIN:
1178                         val &= m_BCSH_SIN_HUE;
1179                         break;
1180                 case H_COS:
1181                         val &= m_BCSH_COS_HUE;
1182                         val >>= 8;
1183                         break;
1184                 default:
1185                         break;
1186                 }
1187         }
1188         spin_unlock(&lcdc_dev->reg_lock);
1189
1190         return val;
1191 }
1192
1193
1194 static int rk3036_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1195                                     int sin_hue, int cos_hue)
1196 {
1197         struct lcdc_device *lcdc_dev =
1198             container_of(dev_drv, struct lcdc_device, driver);
1199         u32 mask, val;
1200
1201         spin_lock(&lcdc_dev->reg_lock);
1202         if (lcdc_dev->clk_on) {
1203                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1204                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1205                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1206                 lcdc_cfg_done(lcdc_dev);
1207         }
1208         spin_unlock(&lcdc_dev->reg_lock);
1209
1210         return 0;
1211 }
1212
1213 static int rk3036_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1214                                     bcsh_bcs_mode mode, int value)
1215 {
1216         struct lcdc_device *lcdc_dev =
1217             container_of(dev_drv, struct lcdc_device, driver);
1218         u32 mask, val;
1219
1220         spin_lock(&lcdc_dev->reg_lock);
1221         if (lcdc_dev->clk_on) {
1222                 switch (mode) {
1223                 case BRIGHTNESS:
1224                 /*from 0 to 255,typical is 128*/
1225                         if (value < 0x20)
1226                                 value += 0x20;
1227                         else if (value >= 0x20)
1228                                 value = value - 0x20;
1229                         mask =  m_BCSH_BRIGHTNESS;
1230                         val = v_BCSH_BRIGHTNESS(value);
1231                         break;
1232                 case CONTRAST:
1233                 /*from 0 to 510,typical is 256*/
1234                         mask =  m_BCSH_CONTRAST;
1235                         val =  v_BCSH_CONTRAST(value);
1236                         break;
1237                 case SAT_CON:
1238                 /*from 0 to 1015,typical is 256*/
1239                         mask = m_BCSH_SAT_CON;
1240                         val = v_BCSH_SAT_CON(value);
1241                         break;
1242                 default:
1243                         break;
1244                 }
1245                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
1246                 lcdc_cfg_done(lcdc_dev);
1247         }
1248         spin_unlock(&lcdc_dev->reg_lock);
1249         return val;
1250 }
1251
1252 static int rk3036_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1253                                     bcsh_bcs_mode mode)
1254 {
1255         struct lcdc_device *lcdc_dev =
1256             container_of(dev_drv, struct lcdc_device, driver);
1257         u32 val;
1258
1259         spin_lock(&lcdc_dev->reg_lock);
1260         if (lcdc_dev->clk_on) {
1261                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
1262                 switch (mode) {
1263                 case BRIGHTNESS:
1264                         val &= m_BCSH_BRIGHTNESS;
1265                         if (val > 0x20)
1266                                 val -= 0x20;
1267                         else if (val == 0x20)
1268                                 val = -32;
1269                         break;
1270                 case CONTRAST:
1271                         val &= m_BCSH_CONTRAST;
1272                         val >>= 8;
1273                         break;
1274                 case SAT_CON:
1275                         val &= m_BCSH_SAT_CON;
1276                         val >>= 16;
1277                         break;
1278                 default:
1279                         break;
1280                 }
1281         }
1282         spin_unlock(&lcdc_dev->reg_lock);
1283         return val;
1284 }
1285
1286
1287 static int rk3036_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
1288 {
1289         struct lcdc_device *lcdc_dev =
1290             container_of(dev_drv, struct lcdc_device, driver);
1291         u32 mask, val;
1292
1293         spin_lock(&lcdc_dev->reg_lock);
1294         if (lcdc_dev->clk_on) {
1295                 if (open) {
1296                         lcdc_writel(lcdc_dev, BCSH_CTRL,
1297                                     v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
1298                         lcdc_writel(lcdc_dev, BCSH_BCS,
1299                                     v_BCSH_BRIGHTNESS(0x00) |
1300                                     v_BCSH_CONTRAST(0x80) |
1301                                     v_BCSH_SAT_CON(0x80));
1302                         lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
1303                 } else {
1304                         mask = m_BCSH_EN;
1305                         val = v_BCSH_EN(0);
1306                         lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
1307                 }
1308                 lcdc_cfg_done(lcdc_dev);
1309         }
1310         spin_unlock(&lcdc_dev->reg_lock);
1311         return 0;
1312 }
1313
1314 static int rk3036_lcdc_set_overscan(struct rk_lcdc_driver *dev_drv,
1315                                     struct overscan *overscan)
1316 {
1317         int i;
1318
1319         dev_drv->overscan = *overscan;
1320         for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1321                 if (dev_drv->win[i] && dev_drv->win[i]->state) {
1322                         rk3036_lcdc_set_par(dev_drv, i);
1323                         rk3036_lcdc_pan_display(dev_drv, i);
1324                 }
1325         }
1326         rk3036_lcdc_cfg_done(dev_drv);
1327         return 0;
1328 }
1329
1330 static int rk3036_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1331 {
1332         mutex_lock(&dev_drv->fb_win_id_mutex);
1333         if (order == FB_DEFAULT_ORDER)
1334                 order = FB0_WIN1_FB1_WIN0_FB2_WIN2;
1335         dev_drv->fb2_win_id = order / 100;
1336         dev_drv->fb1_win_id = (order / 10) % 10;
1337         dev_drv->fb0_win_id = order % 10;
1338         mutex_unlock(&dev_drv->fb_win_id_mutex);
1339
1340         return 0;
1341 }
1342
1343 static int rk3036_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
1344                                bool set)
1345 {
1346         struct lcdc_device *lcdc_dev =
1347             container_of(dev_drv, struct lcdc_device, driver);
1348         struct rk_screen *screen = dev_drv->cur_screen;
1349         u64 ft = 0;
1350         u32 dotclk;
1351         int ret;
1352         u32 pixclock;
1353         u32 x_total, y_total;
1354
1355         if (set) {
1356                 ft = div_u64(1000000000000llu, fps);
1357                 x_total =
1358                     screen->mode.upper_margin + screen->mode.lower_margin +
1359                     screen->mode.yres + screen->mode.vsync_len;
1360                 y_total =
1361                     screen->mode.left_margin + screen->mode.right_margin +
1362                     screen->mode.xres + screen->mode.hsync_len;
1363                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1364                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1365                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1366         }
1367
1368         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1369         lcdc_dev->pixclock = pixclock;
1370         dev_drv->pixclock = pixclock;
1371         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1372         screen->ft = 1000 / fps;        /*one frame time in ms */
1373
1374         if (set)
1375                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1376                          clk_get_rate(lcdc_dev->dclk), fps);
1377
1378         return fps;
1379 }
1380
1381 static int rk3036_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1382 {
1383         struct lcdc_device *lcdc_dev =
1384             container_of(dev_drv, struct lcdc_device, driver);
1385         u32 int_reg;
1386         int ret;
1387
1388         if (lcdc_dev->clk_on) {
1389                 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1390                 if (int_reg & m_LF_INT_STA) {
1391                         lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1392                                      v_LF_INT_CLEAR(1));
1393                         ret = RK_LF_STATUS_FC;
1394                 } else {
1395                         ret = RK_LF_STATUS_FR;
1396                 }
1397         } else {
1398                 ret = RK_LF_STATUS_NC;
1399         }
1400
1401         return ret;
1402 }
1403
1404 static int rk3036_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
1405                                     unsigned int *dsp_addr)
1406 {
1407         struct lcdc_device *lcdc_dev =
1408             container_of(dev_drv, struct lcdc_device, driver);
1409
1410         if (lcdc_dev->clk_on) {
1411                 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1412                 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
1413         }
1414         return 0;
1415 }
1416
1417 static ssize_t rk3036_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1418                                          char *buf, int win_id)
1419 {
1420         struct rk_lcdc_win *win = NULL;
1421         char fmt[9] = "NULL";
1422         u32     size;
1423
1424         if (win_id < ARRAY_SIZE(lcdc_win)) {
1425                 win = dev_drv->win[win_id];
1426         } else {
1427                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1428                 return 0;
1429         }
1430
1431         size = snprintf(buf, PAGE_SIZE, "win%d: %s\n", win_id,
1432                         get_format_string(win->format, fmt));
1433         size += snprintf(buf + size, PAGE_SIZE - size,
1434                          "      xact %d yact %d xvir %d yvir %d\n",
1435                 win->area[0].xact, win->area[0].yact,
1436                 win->area[0].xvir, win->area[0].yvir);
1437         size += snprintf(buf + size, PAGE_SIZE - size,
1438                          "      xpos %d ypos %d xsize %d ysize %d\n",
1439                 win->area[0].xpos, win->area[0].ypos,
1440                 win->area[0].xsize, win->area[0].ysize);
1441         size += snprintf(buf + size, PAGE_SIZE - size,
1442                          "      yaddr 0x%x uvaddr 0x%x\n",
1443                 win->area[0].y_addr, win->area[0].uv_addr);
1444         return size;
1445 }
1446
1447 static int rk3036_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
1448 {
1449         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1450                                                 struct lcdc_device,
1451                                                 driver);
1452         int *cbase = (int *)lcdc_dev->regs;
1453         int *regsbak = (int *)lcdc_dev->regsbak;
1454         int i, j;
1455
1456         dev_info(dev_drv->dev, "back up reg:\n");
1457         for (i = 0; i <= (0xDC >> 4); i++) {
1458                 for (j = 0; j < 4; j++)
1459                         dev_info(dev_drv->dev, "%08x  ",
1460                                  *(regsbak + i * 4 + j));
1461                 dev_info(dev_drv->dev, "\n");
1462         }
1463
1464         dev_info(dev_drv->dev, "lcdc reg:\n");
1465         for (i = 0; i <= (0xDC >> 4); i++) {
1466                 for (j = 0; j < 4; j++)
1467                         dev_info(dev_drv->dev, "%08x  ",
1468                                  readl_relaxed(cbase + i * 4 + j));
1469                 dev_info(dev_drv->dev, "\n");
1470         }
1471         return 0;
1472 }
1473
1474 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
1475         .open                   = rk3036_lcdc_open,
1476         .load_screen            = rk3036_load_screen,
1477         .set_par                = rk3036_lcdc_set_par,
1478         .pan_display            = rk3036_lcdc_pan_display,
1479         .blank                  = rk3036_lcdc_blank,
1480         .ioctl                  = rk3036_lcdc_ioctl,
1481         .get_win_state          = rk3036_lcdc_get_win_state,
1482         .ovl_mgr                = rk3036_lcdc_ovl_mgr,
1483         .get_disp_info          = rk3036_lcdc_get_disp_info,
1484         .fps_mgr                = rk3036_lcdc_fps_mgr,
1485         .fb_get_win_id          = rk3036_lcdc_get_win_id,
1486         .fb_win_remap           = rk3036_fb_win_remap,
1487         .poll_vblank            = rk3036_lcdc_poll_vblank,
1488         .get_dsp_addr           = rk3036_lcdc_get_dsp_addr,
1489         .cfg_done               = rk3036_lcdc_cfg_done,
1490         .dump_reg               = rk3036_lcdc_reg_dump,
1491         .set_dsp_bcsh_hue       = rk3036_lcdc_set_bcsh_hue,
1492         .set_dsp_bcsh_bcs       = rk3036_lcdc_set_bcsh_bcs,
1493         .get_dsp_bcsh_hue       = rk3036_lcdc_get_bcsh_hue,
1494         .get_dsp_bcsh_bcs       = rk3036_lcdc_get_bcsh_bcs,
1495         .open_bcsh              = rk3036_lcdc_open_bcsh,
1496         .set_overscan           = rk3036_lcdc_set_overscan,
1497         .set_hwc_lut            = rk3036_lcdc_set_hwc_lut,
1498 };
1499
1500 static int rk3036_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
1501 {
1502         struct device_node *np = lcdc_dev->dev->of_node;
1503         int val;
1504
1505 #if defined(CONFIG_ROCKCHIP_IOMMU)
1506         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
1507                 lcdc_dev->driver.iommu_enabled = 0;
1508         else
1509                 lcdc_dev->driver.iommu_enabled = val;
1510 #else
1511         lcdc_dev->driver.iommu_enabled = 0;
1512 #endif
1513         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
1514                 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
1515         else
1516                 lcdc_dev->driver.fb_win_map = val;
1517
1518         return 0;
1519 }
1520
1521 static int rk3036_lcdc_probe(struct platform_device *pdev)
1522 {
1523         struct lcdc_device *lcdc_dev = NULL;
1524         struct rk_lcdc_driver *dev_drv;
1525         struct device *dev = &pdev->dev;
1526         struct resource *res;
1527         int ret;
1528
1529         lcdc_dev = devm_kzalloc(dev,
1530                                 sizeof(struct lcdc_device), GFP_KERNEL);
1531         if (!lcdc_dev) {
1532                 dev_err(&pdev->dev, "rk3036 lcdc device kmalloc fail!");
1533                 return -ENOMEM;
1534         }
1535         platform_set_drvdata(pdev, lcdc_dev);
1536         lcdc_dev->dev = dev;
1537         rk3036_lcdc_parse_dt(lcdc_dev);
1538
1539         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1540         lcdc_dev->reg_phy_base = res->start;
1541         lcdc_dev->len = resource_size(res);
1542         lcdc_dev->regs = devm_ioremap_resource(dev, res);
1543         if (IS_ERR(lcdc_dev->regs))
1544                 return PTR_ERR(lcdc_dev->regs);
1545
1546         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
1547         if (IS_ERR(lcdc_dev->regsbak))
1548                 return PTR_ERR(lcdc_dev->regsbak);
1549
1550         lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
1551         lcdc_dev->prop = PRMRY;
1552         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
1553         dev_drv = &lcdc_dev->driver;
1554         dev_drv->dev = dev;
1555         dev_drv->prop = PRMRY;
1556         dev_drv->id = lcdc_dev->id;
1557         dev_drv->ops = &lcdc_drv_ops;
1558         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
1559         spin_lock_init(&lcdc_dev->reg_lock);
1560
1561         lcdc_dev->irq = platform_get_irq(pdev, 0);
1562         if (lcdc_dev->irq < 0) {
1563                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
1564                         lcdc_dev->id);
1565                 return -ENXIO;
1566         }
1567
1568         ret = devm_request_irq(dev, lcdc_dev->irq, rk3036_lcdc_isr,
1569                                IRQF_DISABLED | IRQF_SHARED,
1570                                dev_name(dev), lcdc_dev);
1571         if (ret) {
1572                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
1573                         lcdc_dev->irq, ret);
1574                 return ret;
1575         }
1576
1577         if (dev_drv->iommu_enabled)
1578                 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
1579
1580         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
1581         if (ret < 0) {
1582                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
1583                 return ret;
1584         }
1585         lcdc_dev->screen = dev_drv->screen0;
1586
1587         dev_info(dev, "lcdc probe ok, iommu %s\n",
1588                  dev_drv->iommu_enabled ? "enabled" : "disabled");
1589
1590         return 0;
1591 }
1592
1593 #if defined(CONFIG_PM)
1594 static int rk3036_lcdc_suspend(struct platform_device *pdev,
1595                                pm_message_t state)
1596 {
1597         return 0;
1598 }
1599
1600 static int rk3036_lcdc_resume(struct platform_device *pdev)
1601 {
1602         return 0;
1603 }
1604 #else
1605 #define rk3036_lcdc_suspend NULL
1606 #define rk3036_lcdc_resume  NULL
1607 #endif
1608
1609 static int rk3036_lcdc_remove(struct platform_device *pdev)
1610 {
1611         return 0;
1612 }
1613
1614 static void rk3036_lcdc_shutdown(struct platform_device *pdev)
1615 {
1616 }
1617
1618 #if defined(CONFIG_OF)
1619 static const struct of_device_id rk3036_lcdc_dt_ids[] = {
1620         {.compatible = "rockchip,rk3036-lcdc",},
1621         {}
1622 };
1623 #endif
1624
1625 static struct platform_driver rk3036_lcdc_driver = {
1626         .probe = rk3036_lcdc_probe,
1627         .remove = rk3036_lcdc_remove,
1628         .driver = {
1629                 .name = "rk3036-lcdc",
1630                 .owner = THIS_MODULE,
1631                 .of_match_table = of_match_ptr(rk3036_lcdc_dt_ids),
1632         },
1633         .suspend = rk3036_lcdc_suspend,
1634         .resume = rk3036_lcdc_resume,
1635         .shutdown = rk3036_lcdc_shutdown,
1636 };
1637
1638 static int __init rk3036_lcdc_module_init(void)
1639 {
1640         return platform_driver_register(&rk3036_lcdc_driver);
1641 }
1642
1643 static void __exit rk3036_lcdc_module_exit(void)
1644 {
1645         platform_driver_unregister(&rk3036_lcdc_driver);
1646 }
1647
1648 fs_initcall(rk3036_lcdc_module_init);
1649 module_exit(rk3036_lcdc_module_exit);