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