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