2 * drivers/video/rockchip/lcdc/rk312x_lcdc.c
4 * Copyright (C) 2014 ROCKCHIP, Inc.
5 * Author: zhuangwenlong<zwl@rock-chips.com>
6 * zhengyang<zhengyang@rock-chips.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
23 #include <linux/slab.h>
24 #include <linux/device.h>
25 #include <linux/delay.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <asm/div64.h>
31 #include <asm/uaccess.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37 #include <linux/rockchip-iovmm.h>
38 #include "rk312x_lcdc.h"
40 static int dbg_thresd;
41 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
43 #define DBG(level, x...) do { \
44 if (unlikely(dbg_thresd >= level)) \
45 printk(KERN_INFO x); } while (0)
47 #define grf_writel(offset, v) do { \
48 writel_relaxed(v, RK_GRF_VIRT + offset); \
52 static struct rk_lcdc_win lcdc_win[] = {
70 static irqreturn_t rk312x_lcdc_isr(int irq, void *dev_id)
72 struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
73 ktime_t timestamp = ktime_get();
74 u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
76 if (int_reg & m_FS_INT_STA) {
77 timestamp = ktime_get();
78 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
80 //if (lcdc_dev->driver.wait_fs) {
82 spin_lock(&(lcdc_dev->driver.cpl_lock));
83 complete(&(lcdc_dev->driver.frame_done));
84 spin_unlock(&(lcdc_dev->driver.cpl_lock));
86 lcdc_dev->driver.vsync_info.timestamp = timestamp;
87 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
89 } else if (int_reg & m_LF_INT_STA) {
90 lcdc_dev->driver.frame_time.last_framedone_t =
91 lcdc_dev->driver.frame_time.framedone_t;
92 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
93 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
97 #ifdef LCDC_IRQ_EMPTY_DEBUG
98 if (int_reg & m_WIN0_EMPTY_INT_STA) {
99 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN0_EMPTY_INT_CLEAR,
100 v_WIN0_EMPTY_INT_CLEAR(1));
101 dev_info(lcdc_dev->dev, "win0 empty irq\n");
102 } else if (int_reg & m_WIN1_EMPTY_INT_STA) {
103 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN1_EMPTY_INT_CLEAR,
104 v_WIN1_EMPTY_INT_CLEAR(1));
105 dev_info(lcdc_dev->dev, "win1 empty irq\n");
112 static int rk312x_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
114 #ifdef CONFIG_RK_FPGA
115 lcdc_dev->clk_on = 1;
118 if (!lcdc_dev->clk_on) {
119 clk_prepare_enable(lcdc_dev->hclk);
120 clk_prepare_enable(lcdc_dev->dclk);
121 clk_prepare_enable(lcdc_dev->aclk);
122 clk_prepare_enable(lcdc_dev->pd);
123 spin_lock(&lcdc_dev->reg_lock);
124 lcdc_dev->clk_on = 1;
125 spin_unlock(&lcdc_dev->reg_lock);
131 static int rk312x_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
133 #ifdef CONFIG_RK_FPGA
134 lcdc_dev->clk_on = 0;
137 if (lcdc_dev->clk_on) {
138 spin_lock(&lcdc_dev->reg_lock);
139 lcdc_dev->clk_on = 0;
140 spin_unlock(&lcdc_dev->reg_lock);
142 clk_disable_unprepare(lcdc_dev->dclk);
143 clk_disable_unprepare(lcdc_dev->hclk);
144 clk_disable_unprepare(lcdc_dev->aclk);
145 clk_disable_unprepare(lcdc_dev->pd);
151 static int rk312x_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
154 struct lcdc_device *lcdc_dev = container_of(dev_drv,
155 struct lcdc_device, driver);
156 struct rk_screen *screen = dev_drv->cur_screen;
158 spin_lock(&lcdc_dev->reg_lock);
159 if (likely(lcdc_dev->clk_on)) {
160 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
161 m_LF_INT_CLEAR | m_LF_INT_EN | m_LF_INT_NUM |
162 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
163 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) |
164 v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
165 v_BUS_ERR_INT_CLEAR(1) | v_BUS_ERR_INT_EN(0) |
166 v_LF_INT_NUM(screen->mode.vsync_len +
167 screen->mode.upper_margin +
169 #ifdef LCDC_IRQ_EMPTY_DEBUG
170 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
171 val |= v_WIN0_EMPTY_INT_EN(1) | v_WIN1_EMPTY_INT_EN(1);
174 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
175 spin_unlock(&lcdc_dev->reg_lock);
177 spin_unlock(&lcdc_dev->reg_lock);
183 static int rk312x_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
187 spin_lock(&lcdc_dev->reg_lock);
188 if (likely(lcdc_dev->clk_on)) {
189 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
190 m_LF_INT_CLEAR | m_LF_INT_EN |
191 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
192 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
193 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
194 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
195 #ifdef LCDC_IRQ_EMPTY_DEBUG
196 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
197 val |= v_WIN0_EMPTY_INT_EN(0) | v_WIN1_EMPTY_INT_EN(0);
200 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
201 spin_unlock(&lcdc_dev->reg_lock);
203 spin_unlock(&lcdc_dev->reg_lock);
210 static int win0_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
212 spin_lock(&lcdc_dev->reg_lock);
213 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, addr);
214 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(1));
215 lcdc_cfg_done(lcdc_dev);
216 spin_unlock(&lcdc_dev->reg_lock);
221 static int win1_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
223 spin_lock(&lcdc_dev->reg_lock);
224 if (lcdc_dev->soc_type == VOP_RK3036)
225 lcdc_writel(lcdc_dev, WIN1_MST, addr);
227 lcdc_writel(lcdc_dev, WIN1_MST_RK312X, addr);
228 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(1));
229 lcdc_cfg_done(lcdc_dev);
230 spin_unlock(&lcdc_dev->reg_lock);
234 int rk312x_lcdc_direct_set_win_addr
235 (struct rk_lcdc_driver *dev_drv, int win_id, u32 addr)
237 struct lcdc_device *lcdc_dev = container_of(dev_drv,
238 struct lcdc_device, driver);
240 win0_set_addr(lcdc_dev, addr);
242 win1_set_addr(lcdc_dev, addr);
247 static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
251 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
252 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
253 spin_lock(&lcdc_dev->reg_lock);
254 for (reg = 0; reg < 0xe0; reg += 4) {
255 val = lcdc_readl(lcdc_dev, reg);
256 if (reg == WIN0_ACT_INFO) {
257 win0->area[0].xact = (val & m_ACT_WIDTH)+1;
258 win0->area[0].yact = ((val & m_ACT_HEIGHT)>>16)+1;
261 if (lcdc_dev->soc_type == VOP_RK312X) {
262 if (reg == WIN1_DSP_INFO_RK312X) {
263 win1->area[0].xact = (val & m_DSP_WIDTH) + 1;
264 win1->area[0].yact = ((val & m_DSP_HEIGHT) >> 16) + 1;
267 if (reg == WIN1_ACT_INFO) {
268 win1->area[0].xact = (val & m_ACT_WIDTH) + 1;
269 win1->area[0].yact = ((val & m_ACT_HEIGHT) >> 16) + 1;
274 spin_unlock(&lcdc_dev->reg_lock);
277 static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
281 enum data_format win0_format = lcdc_dev->driver.win[0]->format;
282 enum data_format win1_format = lcdc_dev->driver.win[1]->format;
284 int win0_alpha_en = ((win0_format == ARGB888)
285 || (win0_format == ABGR888)) ? 1 : 0;
286 int win1_alpha_en = ((win1_format == ARGB888)
287 || (win1_format == ABGR888)) ? 1 : 0;
288 u32 *_pv = (u32 *) lcdc_dev->regsbak;
290 _pv += (DSP_CTRL0 >> 2);
291 win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
292 if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
293 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
294 val = v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0);
295 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
297 mask = m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
298 val = v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
299 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
300 } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2)
301 && (win1_alpha_en)) {
302 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
303 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
304 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
306 mask = m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
307 val = v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
308 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
310 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
311 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
312 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
315 if(lcdc_dev->driver.win[2]->state == 1) {
316 mask = m_HWC_ALPAH_EN;
317 val = v_HWC_ALPAH_EN(1);
318 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
320 mask = m_HWC_ALPHA_MODE;
321 val = v_HWC_ALPHA_MODE(1);
322 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
324 mask = m_HWC_ALPAH_EN;
325 val = v_HWC_ALPAH_EN(0);
326 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
332 static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
333 struct rk_lcdc_win *win)
335 struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
336 struct rk_screen *screen = dev_drv->cur_screen;
338 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
339 switch (win->fmt_cfg) {
340 case VOP_FORMAT_ARGB888:
341 case VOP_FORMAT_RGB888:
342 case VOP_FORMAT_RGB565:
343 if ((screen->mode.xres < 1280 ) &&
344 (screen->mode.yres < 720)) {
345 win->csc_mode = VOP_R2Y_CSC_BT601;
347 win->csc_mode = VOP_R2Y_CSC_BT709;
354 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
355 v_WIN0_CSC_MODE(win->csc_mode));
356 } else if (win->id == 1) {
357 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
358 v_WIN1_CSC_MODE(win->csc_mode));
360 } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
361 switch (win->fmt_cfg) {
362 case VOP_FORMAT_YCBCR420:
364 win->csc_mode = VOP_Y2R_CSC_MPEG;
365 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
366 v_WIN0_CSC_MODE(win->csc_mode));
377 static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
378 struct rk_lcdc_win *win)
383 if (win->state == 1) {
384 if (lcdc_dev->soc_type == VOP_RK312X)
385 lcdc_layer_csc_mode(lcdc_dev, win);
388 mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
389 val = v_WIN0_EN(win->state) |
390 v_WIN0_FORMAT(win->fmt_cfg) |
391 v_WIN0_RB_SWAP(win->swap_rb);
392 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
393 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
394 v_X_SCL_FACTOR(win->scale_yrgb_x) |
395 v_Y_SCL_FACTOR(win->scale_yrgb_y));
396 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
397 v_X_SCL_FACTOR(win->scale_cbcr_x) |
398 v_Y_SCL_FACTOR(win->scale_cbcr_y));
400 lcdc_msk_reg(lcdc_dev, WIN0_VIR,
401 m_YRGB_VIR | m_CBBR_VIR,
402 v_YRGB_VIR(win->area[0].y_vir_stride) |
403 v_CBCR_VIR(win->area[0].uv_vir_stride));
404 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
405 v_ACT_WIDTH(win->area[0].xact) |
406 v_ACT_HEIGHT(win->area[0].yact));
407 lcdc_writel(lcdc_dev, WIN0_DSP_ST,
408 v_DSP_STX(win->area[0].dsp_stx) |
409 v_DSP_STY(win->area[0].dsp_sty));
410 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
411 v_DSP_WIDTH(win->area[0].xsize) |
412 v_DSP_HEIGHT(win->area[0].ysize));
414 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
415 win->area[0].y_addr);
416 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
417 win->area[0].uv_addr);
418 } else if (win->id == 1) {
419 mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
420 val = v_WIN1_EN(win->state) |
421 v_WIN1_FORMAT(win->fmt_cfg) |
422 v_WIN1_RB_SWAP(win->swap_rb);
423 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
424 /* rk312x unsupport win1 scale */
425 if (lcdc_dev->soc_type == VOP_RK3036) {
426 lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
427 v_X_SCL_FACTOR(win->scale_yrgb_x) |
428 v_Y_SCL_FACTOR(win->scale_yrgb_y));
429 lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
430 v_ACT_WIDTH(win->area[0].xact) |
431 v_ACT_HEIGHT(win->area[0].yact));
432 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
433 v_DSP_WIDTH(win->area[0].xsize) |
434 v_DSP_HEIGHT(win->area[0].ysize));
435 lcdc_writel(lcdc_dev, WIN1_DSP_ST,
436 v_DSP_STX(win->area[0].dsp_stx) |
437 v_DSP_STY(win->area[0].dsp_sty));
438 lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
440 lcdc_writel(lcdc_dev, WIN1_DSP_INFO_RK312X,
441 v_DSP_WIDTH(win->area[0].xsize) |
442 v_DSP_HEIGHT(win->area[0].ysize));
443 lcdc_writel(lcdc_dev, WIN1_DSP_ST_RK312X,
444 v_DSP_STX(win->area[0].dsp_stx) |
445 v_DSP_STY(win->area[0].dsp_sty));
447 lcdc_writel(lcdc_dev, WIN1_MST_RK312X, win->area[0].y_addr);
450 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
451 v_YRGB_VIR(win->area[0].y_vir_stride));
454 } else if (win->id == 2) {
455 mask = m_HWC_EN | m_HWC_LODAD_EN;
456 val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
457 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
458 if((win->area[0].xsize == 32) &&(win->area[0].ysize == 32))
460 else if((win->area[0].xsize == 64) &&(win->area[0].ysize == 64))
463 dev_err(lcdc_dev->dev,"unsupport hwc size:x=%d,y=%d\n",
464 win->area[0].xsize,win->area[0].ysize);
465 lcdc_writel(lcdc_dev, HWC_DSP_ST,
466 v_DSP_STX(win->area[0].dsp_stx) |
467 v_DSP_STY(win->area[0].dsp_sty));
469 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
473 win->area[0].y_addr = 0;
474 win->area[0].uv_addr = 0;
476 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
478 else if (win->id == 1)
479 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
481 else if (win->id == 2)
482 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
484 rk312x_lcdc_alpha_cfg(lcdc_dev);
487 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
490 spin_lock(&lcdc_dev->reg_lock);
491 if (likely(lcdc_dev->clk_on)
492 && lcdc_dev->driver.win[win_id]->state != open) {
494 if (!lcdc_dev->atv_layer_cnt) {
495 dev_info(lcdc_dev->dev,
496 "wakeup from standby!\n");
497 lcdc_dev->standby = 0;
499 lcdc_dev->atv_layer_cnt++;
500 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
501 lcdc_dev->atv_layer_cnt--;
503 lcdc_dev->driver.win[win_id]->state = open;
505 lcdc_layer_update_regs(lcdc_dev,
506 lcdc_dev->driver.win[win_id]);
507 lcdc_cfg_done(lcdc_dev);
509 /*if no layer used,disable lcdc */
510 if (!lcdc_dev->atv_layer_cnt) {
511 dev_info(lcdc_dev->dev,
512 "no layer is used,go to standby!\n");
513 lcdc_dev->standby = 1;
516 spin_unlock(&lcdc_dev->reg_lock);
519 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
521 struct lcdc_device *lcdc_dev =
522 container_of(dev_drv, struct lcdc_device, driver);
523 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
524 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
527 spin_lock(&lcdc_dev->reg_lock);
528 if (likely(lcdc_dev->clk_on)) {
529 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
530 v_LCDC_STANDBY(lcdc_dev->standby));
531 lcdc_layer_update_regs(lcdc_dev, win0);
532 lcdc_layer_update_regs(lcdc_dev, win1);
533 rk312x_lcdc_alpha_cfg(lcdc_dev);
534 lcdc_cfg_done(lcdc_dev);
537 spin_unlock(&lcdc_dev->reg_lock);
538 //if (dev_drv->wait_fs) {
540 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
541 init_completion(&dev_drv->frame_done);
542 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
543 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
545 (dev_drv->cur_screen->ft +
547 if (!timeout && (!dev_drv->frame_done.done)) {
548 dev_warn(lcdc_dev->dev,
549 "wait for new frame start time out!\n");
553 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
558 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
560 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0xe0);
563 static void rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
566 struct lcdc_device *lcdc_dev =
567 container_of(dev_drv, struct lcdc_device, driver);
569 spin_lock(&lcdc_dev->reg_lock);
570 if (likely(lcdc_dev->clk_on)) {
571 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
572 m_AXI_OUTSTANDING_MAX_NUM;
573 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
574 v_AXI_MAX_OUTSTANDING_EN(1);
575 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
577 spin_unlock(&lcdc_dev->reg_lock);
579 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv, int *hwc_lut,int mode)
585 struct lcdc_device *lcdc_dev =
586 container_of(dev_drv, struct lcdc_device, driver);
587 if(dev_drv->hwc_lut == NULL) {
588 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
590 spin_lock(&lcdc_dev->reg_lock);
591 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
592 lcdc_cfg_done(lcdc_dev);
594 for (i = 0; i < 256; i++) {
596 dev_drv->hwc_lut[i] = hwc_lut[i];
597 v = dev_drv->hwc_lut[i];
598 c = lcdc_dev->hwc_lut_addr_base + i;
599 writel_relaxed(v, c);
601 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
602 lcdc_cfg_done(lcdc_dev);
603 spin_unlock(&lcdc_dev->reg_lock);
608 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
613 struct lcdc_device *lcdc_dev =
614 container_of(dev_drv, struct lcdc_device, driver);
616 spin_lock(&lcdc_dev->reg_lock);
617 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
618 lcdc_cfg_done(lcdc_dev);
620 for (i = 0; i < 256; i++) {
621 v = dev_drv->cur_screen->dsp_lut[i];
622 c = lcdc_dev->dsp_lut_addr_base + (i<<2);
623 writel_relaxed(v, c);
625 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
626 lcdc_cfg_done(lcdc_dev);
627 spin_unlock(&lcdc_dev->reg_lock);
631 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
633 #ifdef CONFIG_RK_FPGA
637 struct lcdc_device *lcdc_dev =
638 container_of(dev_drv, struct lcdc_device, driver);
639 struct rk_screen *screen = dev_drv->cur_screen;
641 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
643 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
645 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
646 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
648 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
649 screen->ft = 1000 / fps;
650 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
651 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
656 /********do basic init*********/
657 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
659 struct lcdc_device *lcdc_dev = container_of(dev_drv,
660 struct lcdc_device, driver);
661 if (lcdc_dev->pre_init)
664 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
665 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
666 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
667 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
668 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
669 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
671 if ( /*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
672 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
673 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
677 rk_disp_pwr_enable(dev_drv);
678 rk312x_lcdc_clk_enable(lcdc_dev);
680 /* backup reg config at uboot */
681 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
683 /* config for the FRC mode of dither down */
684 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
685 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
686 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
687 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
688 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
689 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
691 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
692 lcdc_cfg_done(lcdc_dev);
693 if (dev_drv->iommu_enabled) {/* disable all wins to workaround iommu pagefault */
694 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
695 v_WIN0_EN(0) | v_WIN1_EN(0));
696 lcdc_cfg_done(lcdc_dev);
697 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
699 if ((dev_drv->ops->open_bcsh)&&(dev_drv->output_color == COLOR_YCBCR))
700 dev_drv->ops->open_bcsh(dev_drv,1);
701 lcdc_dev->pre_init = true;
706 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
710 spin_lock(&lcdc_dev->reg_lock);
711 if (likely(lcdc_dev->clk_on)) {
712 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
713 m_LF_INT_CLEAR | m_LF_INT_EN |
714 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
715 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
716 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
717 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
718 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
719 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
720 lcdc_cfg_done(lcdc_dev);
721 spin_unlock(&lcdc_dev->reg_lock);
723 spin_unlock(&lcdc_dev->reg_lock);
729 static u32 calc_sclk_freq(struct rk_screen *src_screen, struct rk_screen *dst_screen)
737 if (!src_screen || !dst_screen)
740 dsp_vtotal = dst_screen->mode.yres;
741 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
742 dst_screen->mode.xres + dst_screen->mode.right_margin;
743 dsp_in_vtotal = src_screen->mode.yres;
744 dsp_in_htotal = src_screen->mode.left_margin +
745 src_screen->mode.hsync_len +
746 src_screen->mode.xres + src_screen->mode.right_margin;
747 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
748 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
750 return (u32)sclk_freq;
753 #define SCLK_PLL_LIMIT 594000000
754 static u32 calc_sclk_pll_freq(u32 sclk_freq)
756 #define ACCURACY_LEV 100
759 u16 max_multi_num = 0, multi_num = 0, remainder_num = 0;
760 u32 less_delta = 0, greater_delta = 0;
765 max_multi_num = SCLK_PLL_LIMIT / sclk_freq;
766 decimal_num = (sclk_freq / (1000000 / ACCURACY_LEV)) % ACCURACY_LEV;
767 multi_num = ACCURACY_LEV / decimal_num;
769 if (multi_num > max_multi_num) {
770 multi_num = max_multi_num;
771 } else if (decimal_num != 0) {
772 remainder_num = ACCURACY_LEV % decimal_num;
773 if (remainder_num != 0) {
774 less_delta = ACCURACY_LEV - (decimal_num * multi_num);
775 greater_delta = decimal_num * (multi_num + 1) - ACCURACY_LEV;
776 multi_num = (less_delta < greater_delta) ? multi_num : (multi_num + 1);
780 pll_freq = sclk_freq * multi_num;
784 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
785 struct rk_screen *dst, u32 sclk_freq)
790 u64 T_BP_in, T_BP_out, T_Delta, Tin;
791 u32 src_pixclock, dst_pixclock;
793 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
795 if (unlikely(!src) || unlikely(!dst))
798 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
799 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
800 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
801 dst->mode.xres + dst->mode.right_margin;
802 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
803 dst->mode.yres + dst->mode.lower_margin;
804 src_htotal = src->mode.left_margin + src->mode.hsync_len +
805 src->mode.xres + src->mode.right_margin;
806 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
807 src->mode.yres + src->mode.lower_margin;
808 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
809 src->mode.hsync_len + src->mode.left_margin;
810 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
811 dst->mode.hsync_len + dst->mode.left_margin;
813 T_BP_in = BP_in * src_pixclock;
814 T_BP_out = BP_out * dst_pixclock;
815 Tin = src_vtotal * src_htotal * src_pixclock;
817 v_scale_ratio = src->mode.yres / dst->mode.yres;
818 if (v_scale_ratio <= 2)
819 T_Delta = 5 * src_htotal * src_pixclock;
821 T_Delta = 12 * src_htotal * src_pixclock;
823 if (T_BP_in + T_Delta > T_BP_out)
824 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
826 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
827 printk("T_in=%lld,T_BP_in=%lld,T_Delta=%lld,T_BP_out=%lld\n",Tin,T_BP_in,T_Delta,T_BP_out);
828 printk("T_frm_st=%lld\n",T_frm_st);
829 printk("src_pixclock=%d\n,dst_pixclock=%d\n",src_pixclock,dst_pixclock);
831 /* (T_frm_st = scl_vst * src_htotal * src_pixclock + scl_hst * src_pixclock) */
832 temp = do_div(T_frm_st, src_htotal * src_pixclock);
833 dst->scl_vst = T_frm_st;
834 do_div(temp, src_pixclock);
836 printk("dst_frame_hst=%d,dst_frame_vst=%d\n",dst->scl_hst,dst->scl_vst);
840 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
841 struct rk_screen *dst_screen, bool enable)
843 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
844 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
845 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
846 u32 scl_v_factor, scl_h_factor;
847 u32 dst_frame_hst, dst_frame_vst;
848 u32 src_w, src_h, dst_w, dst_h;
854 struct rk_screen *src;
855 struct rk_screen *dst;
856 struct lcdc_device *lcdc_dev = container_of(dev_drv,
857 struct lcdc_device, driver);
859 if (unlikely(!lcdc_dev->clk_on))
863 spin_lock(&lcdc_dev->reg_lock);
864 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
865 m_SCALER_EN | m_SCALER_OUT_ZERO | m_SCALER_OUT_EN,
866 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(0) | v_SCALER_OUT_EN(0));
867 spin_unlock(&lcdc_dev->reg_lock);
868 if (lcdc_dev->sclk_on) {
869 clk_disable_unprepare(lcdc_dev->sclk);
870 lcdc_dev->sclk_on = false;
872 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
877 * rk312x used one lcdc to apply dual disp
878 * hdmi screen is used for scaler src
879 * prmry screen is used for scaler dst
882 src = dev_drv->cur_screen;
884 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
888 if (!lcdc_dev->sclk_on) {
889 clk_prepare_enable(lcdc_dev->sclk);
890 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
891 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
892 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
893 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
894 lcdc_dev->sclk_on = true;
895 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
896 lcdc_dev->s_pixclock);
899 /* config scale timing */
900 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
901 dst_frame_vst = dst->scl_vst;
902 dst_frame_hst = dst->scl_hst;
904 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
905 dst->mode.xres + dst->mode.right_margin;
906 dsp_hs_end = dst->mode.hsync_len;
908 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
909 dst->mode.yres + dst->mode.lower_margin;
910 dsp_vs_end = dst->mode.vsync_len;
912 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
914 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
915 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
917 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
919 dsp_hact_st = dsp_hbor_st + bor_left;
920 dsp_hact_end = dsp_hbor_end - bor_right;
921 dsp_vact_st = dsp_vbor_st + bor_up;
922 dsp_vact_end = dsp_vbor_end - bor_down;
924 src_w = src->mode.xres;
925 src_h = src->mode.yres;
926 dst_w = dsp_hact_end - dsp_hact_st;
927 dst_h = dsp_vact_end - dsp_vact_st;
929 /* calc scale factor */
930 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
931 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
933 spin_lock(&lcdc_dev->reg_lock);
934 if (dst->color_mode != src->color_mode) {
935 /*dev_drv->output_color = dst->color_mode;
936 if (dev_drv->output_color == COLOR_YCBCR)
937 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
939 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
940 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
941 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
944 lcdc_writel(lcdc_dev, SCALER_FACTOR,
945 v_SCALER_H_FACTOR(scl_h_factor) |
946 v_SCALER_V_FACTOR(scl_v_factor));
948 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
949 v_SCALER_FRAME_HST(dst_frame_hst) |
950 v_SCALER_FRAME_VST(dst_frame_vst));
951 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
952 v_SCALER_HS_END(dsp_hs_end) |
953 v_SCALER_HTOTAL(dsp_htotal));
954 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
955 v_SCALER_HAEP(dsp_hact_end) |
956 v_SCALER_HASP(dsp_hact_st));
957 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
958 v_SCALER_VS_END(dsp_vs_end) |
959 v_SCALER_VTOTAL(dsp_vtotal));
960 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
961 v_SCALER_VAEP(dsp_vact_end) |
962 v_SCALER_VASP(dsp_vact_st));
963 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
964 v_SCALER_HBOR_END(dsp_hbor_end) |
965 v_SCALER_HBOR_ST(dsp_hbor_st));
966 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
967 v_SCALER_VBOR_END(dsp_vbor_end) |
968 v_SCALER_VBOR_ST(dsp_vbor_st));
969 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
970 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
971 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
972 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
973 m_SCALER_EN | m_SCALER_OUT_ZERO | m_SCALER_OUT_EN,
974 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) | v_SCALER_OUT_EN(1));
976 lcdc_cfg_done(lcdc_dev);
977 spin_unlock(&lcdc_dev->reg_lock);
982 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
985 struct lcdc_device *lcdc_dev = container_of(dev_drv,
986 struct lcdc_device, driver);
987 struct rk_screen *screen = dev_drv->cur_screen;
988 u16 right_margin = screen->mode.right_margin;
989 u16 left_margin = screen->mode.left_margin;
990 u16 lower_margin = screen->mode.lower_margin;
991 u16 upper_margin = screen->mode.upper_margin;
992 u16 x_res = screen->mode.xres;
993 u16 y_res = screen->mode.yres;
996 spin_lock(&lcdc_dev->reg_lock);
997 if (likely(lcdc_dev->clk_on)) {
998 /* Select output color domain */
999 /*dev_drv->output_color = screen->color_mode;
1000 if (lcdc_dev->soc_type == VOP_RK312X) {
1001 if (dev_drv->output_color == COLOR_YCBCR)
1002 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1004 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1006 dev_drv->output_color = COLOR_RGB;
1007 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1009 dev_drv->overlay_mode = VOP_RGB_DOMAIN;/*something wrong at yuv domain*/
1011 switch (screen->type) {
1013 if (lcdc_dev->soc_type == VOP_RK312X) {
1014 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1015 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1016 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1020 if (lcdc_dev->soc_type == VOP_RK312X) {
1021 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1022 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1023 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1027 if (lcdc_dev->soc_type == VOP_RK312X) {
1028 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1029 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1030 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1034 mask = m_HDMI_DCLK_EN;
1035 val = v_HDMI_DCLK_EN(1);
1036 if (screen->pixelrepeat) {
1037 mask |= m_CORE_CLK_DIV_EN;
1038 val |= v_CORE_CLK_DIV_EN(1);
1040 mask |= m_CORE_CLK_DIV_EN;
1041 val |= v_CORE_CLK_DIV_EN(0);
1043 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1044 if (lcdc_dev->soc_type == VOP_RK312X) {
1045 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1047 v_SW_UV_OFFSET_EN(0));
1048 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1050 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1051 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1052 v_HDMI_DEN_POL(screen->pin_den);
1053 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1055 mask = (1 << 4) | (1 << 5) | (1 << 6);
1056 val = (screen->pin_hsync << 4) |
1057 (screen->pin_vsync << 5) |
1058 (screen->pin_den << 6);
1059 grf_writel(RK3036_GRF_SOC_CON2, (mask << 16) | val);
1063 case SCREEN_TVOUT_TEST:
1064 mask = m_TVE_DAC_DCLK_EN;
1065 val = v_TVE_DAC_DCLK_EN(1);
1066 if (screen->pixelrepeat) {
1067 mask |= m_CORE_CLK_DIV_EN;
1068 val |= v_CORE_CLK_DIV_EN(1);
1070 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1071 if (x_res == 720 && y_res == 576)
1072 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1073 v_TVE_MODE(TV_PAL));
1074 else if (x_res == 720 && y_res == 480)
1075 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1076 v_TVE_MODE(TV_NTSC));
1078 dev_err(lcdc_dev->dev,
1079 "unsupported video timing!\n");
1082 if (lcdc_dev->soc_type == VOP_RK312X) {
1083 if (screen->type == SCREEN_TVOUT_TEST)/*for TVE index test,vop must ovarlay at yuv domain*/
1084 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1085 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1087 v_SW_UV_OFFSET_EN(1));
1091 dev_err(lcdc_dev->dev, "un supported interface!\n");
1094 if (lcdc_dev->soc_type == VOP_RK312X) {
1095 switch (screen->face) {
1098 mask = m_DITHER_DOWN_EN |
1099 m_DITHER_DOWN_MODE |
1101 val = v_DITHER_DOWN_EN(1) |
1102 v_DITHER_DOWN_MODE(0) |
1103 v_DITHER_DOWN_SEL(1);
1104 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1108 mask = m_DITHER_DOWN_EN |
1109 m_DITHER_DOWN_MODE |
1111 val = v_DITHER_DOWN_EN(1) |
1112 v_DITHER_DOWN_MODE(1) |
1113 v_DITHER_DOWN_SEL(1);
1114 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1118 mask = m_DITHER_DOWN_EN |
1119 m_DITHER_DOWN_MODE |
1121 val = v_DITHER_DOWN_EN(1) |
1122 v_DITHER_DOWN_MODE(0) |
1123 v_DITHER_DOWN_SEL(1);
1124 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1128 mask = m_DITHER_DOWN_EN |
1129 m_DITHER_DOWN_MODE |
1131 val = v_DITHER_DOWN_EN(1) |
1132 v_DITHER_DOWN_MODE(1) |
1133 v_DITHER_DOWN_SEL(1);
1134 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1138 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1139 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1140 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1143 dev_err(lcdc_dev->dev, "un supported interface!\n");
1146 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1147 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1150 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
1151 m_DEN_POL | m_DCLK_POL;
1152 val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
1153 v_VSYNC_POL(screen->pin_vsync) |
1154 v_DEN_POL(screen->pin_den) |
1155 v_DCLK_POL(screen->pin_dclk);
1156 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1158 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1159 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1160 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1162 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1163 v_DSP_RB_SWAP(screen->swap_rb) |
1164 v_DSP_RG_SWAP(screen->swap_rg) |
1165 v_DSP_DELTA_SWAP(screen->swap_delta) |
1166 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1167 v_BLANK_EN(0) | v_BLACK_EN(0);
1168 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1171 val = v_HSYNC(screen->mode.hsync_len) |
1172 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1174 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1175 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1176 v_HASP(screen->mode.hsync_len + left_margin);
1177 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1179 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1180 /* First Field Timing */
1181 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1182 v_VSYNC(screen->mode.vsync_len) |
1183 v_VERPRD(2 * (screen->mode.vsync_len + upper_margin + lower_margin) +
1185 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1186 v_VAEP(screen->mode.vsync_len +
1187 upper_margin + y_res / 2) |
1188 v_VASP(screen->mode.vsync_len +
1190 /* Second Field Timing */
1191 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1192 v_VSYNC_ST_F1(screen->mode.vsync_len +
1193 upper_margin + y_res / 2 +
1195 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1196 upper_margin + y_res / 2 +
1198 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1199 v_VAEP(2 * (screen->mode.vsync_len + upper_margin) +
1200 y_res + lower_margin + 1) |
1201 v_VASP(2 * (screen->mode.vsync_len + upper_margin) +
1202 y_res / 2 + lower_margin + 1));
1204 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1205 m_INTERLACE_DSP_EN |
1206 m_WIN0_YRGB_DEFLICK_EN |
1207 m_WIN0_CBR_DEFLICK_EN |
1208 m_INTERLACE_FIELD_POL |
1209 m_WIN0_INTERLACE_EN |
1210 m_WIN1_INTERLACE_EN,
1211 v_INTERLACE_DSP_EN(1) |
1212 v_WIN0_YRGB_DEFLICK_EN(1) |
1213 v_WIN0_CBR_DEFLICK_EN(1) |
1214 v_INTERLACE_FIELD_POL(0) |
1215 v_WIN0_INTERLACE_EN(1) |
1216 v_WIN1_INTERLACE_EN(1));
1217 mask = m_LF_INT_NUM;
1218 val = v_LF_INT_NUM(screen->mode.vsync_len +
1219 screen->mode.upper_margin +
1220 screen->mode.yres/2);
1221 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1223 val = v_VSYNC(screen->mode.vsync_len) |
1224 v_VERPRD(screen->mode.vsync_len + upper_margin +
1225 y_res + lower_margin);
1226 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1228 val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
1229 v_VASP(screen->mode.vsync_len + upper_margin);
1230 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1232 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1233 m_INTERLACE_DSP_EN |
1234 m_WIN0_YRGB_DEFLICK_EN |
1235 m_WIN0_CBR_DEFLICK_EN |
1236 m_INTERLACE_FIELD_POL |
1237 m_WIN0_INTERLACE_EN |
1238 m_WIN1_INTERLACE_EN,
1239 v_INTERLACE_DSP_EN(0) |
1240 v_WIN0_YRGB_DEFLICK_EN(0) |
1241 v_WIN0_CBR_DEFLICK_EN(0) |
1242 v_INTERLACE_FIELD_POL(0) |
1243 v_WIN0_INTERLACE_EN(0) |
1244 v_WIN1_INTERLACE_EN(0));
1245 mask = m_LF_INT_NUM;
1246 val = v_LF_INT_NUM(screen->mode.vsync_len +
1247 screen->mode.upper_margin +
1249 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1253 spin_unlock(&lcdc_dev->reg_lock);
1254 rk312x_lcdc_set_dclk(dev_drv);
1255 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1256 dev_drv->trsm_ops->enable();
1263 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1266 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1267 struct lcdc_device, driver);
1269 /* enable clk,when first layer open */
1270 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1271 rockchip_set_system_status(SYS_STATUS_LCDC0);
1272 rk312x_lcdc_pre_init(dev_drv);
1273 rk312x_lcdc_clk_enable(lcdc_dev);
1274 #if defined(CONFIG_ROCKCHIP_IOMMU)
1275 if (dev_drv->iommu_enabled) {
1276 if (!dev_drv->mmu_dev) {
1278 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1279 if (dev_drv->mmu_dev) {
1280 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1283 dev_err(dev_drv->dev,
1284 "failed to get rockchip iommu device\n");
1288 if (dev_drv->mmu_dev)
1289 rockchip_iovmm_activate(dev_drv->dev);
1292 rk312x_lcdc_reg_restore(lcdc_dev);
1293 if (dev_drv->iommu_enabled)
1294 rk312x_lcdc_mmu_en(dev_drv);
1295 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1296 rk312x_lcdc_set_dclk(dev_drv);
1297 rk312x_lcdc_enable_irq(dev_drv);
1299 rk312x_load_screen(dev_drv, 1);
1302 /* set screen lut */
1303 if (dev_drv->cur_screen->dsp_lut)
1304 rk312x_lcdc_set_lut(dev_drv);
1307 if (win_id < ARRAY_SIZE(lcdc_win))
1308 lcdc_layer_enable(lcdc_dev, win_id, open);
1310 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1312 /* when all layer closed,disable clk */
1313 if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1314 rk312x_lcdc_disable_irq(lcdc_dev);
1315 rk312x_lcdc_reg_update(dev_drv);
1316 #if defined(CONFIG_ROCKCHIP_IOMMU)
1317 if (dev_drv->iommu_enabled) {
1318 if (dev_drv->mmu_dev)
1319 rockchip_iovmm_deactivate(dev_drv->dev);
1322 rk312x_lcdc_clk_disable(lcdc_dev);
1323 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1328 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1330 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1331 struct lcdc_device, driver);
1332 struct rk_screen *screen = dev_drv->cur_screen;
1333 struct rk_lcdc_win *win = NULL;
1334 char fmt[9] = "NULL";
1337 dev_err(dev_drv->dev, "screen is null!\n");
1342 win = dev_drv->win[0];
1343 } else if (win_id == 1) {
1344 win = dev_drv->win[1];
1345 } else if (win_id == 2) {
1346 win = dev_drv->win[2];
1348 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1352 spin_lock(&lcdc_dev->reg_lock);
1353 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1354 screen->mode.hsync_len;
1355 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1356 win->area[0].ysize /= 2;
1357 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1358 screen->mode.upper_margin +
1359 screen->mode.vsync_len;
1361 win->area[0].dsp_sty = win->area[0].ypos +
1362 screen->mode.upper_margin +
1363 screen->mode.vsync_len;
1365 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1366 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1368 switch (win->format) {
1370 win->fmt_cfg = VOP_FORMAT_ARGB888;
1374 win->fmt_cfg = VOP_FORMAT_ARGB888;
1378 win->fmt_cfg = VOP_FORMAT_ARGB888;
1382 win->fmt_cfg = VOP_FORMAT_RGB888;
1386 win->fmt_cfg = VOP_FORMAT_RGB565;
1391 win->fmt_cfg = VOP_FORMAT_YCBCR444;
1393 CalScale(win->area[0].xact, win->area[0].xsize);
1395 CalScale(win->area[0].yact, win->area[0].ysize);
1398 dev_err(lcdc_dev->driver.dev,
1399 "%s:un supported format!\n", __func__);
1404 win->fmt_cfg = VOP_FORMAT_YCBCR422;
1405 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1406 win->area[0].xsize);
1408 CalScale(win->area[0].yact, win->area[0].ysize);
1411 dev_err(lcdc_dev->driver.dev,
1412 "%s:un supported format!\n", __func__);
1417 win->fmt_cfg = VOP_FORMAT_YCBCR420;
1419 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1421 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1424 dev_err(lcdc_dev->driver.dev,
1425 "%s:un supported format!\n", __func__);
1429 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1433 spin_unlock(&lcdc_dev->reg_lock);
1436 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1437 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1438 get_format_string(win->format, fmt), win->area[0].xact,
1439 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1440 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1445 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1447 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1448 struct lcdc_device, driver);
1449 struct rk_lcdc_win *win = NULL;
1450 struct rk_screen *screen = dev_drv->cur_screen;
1453 dev_err(dev_drv->dev, "screen is null!\n");
1458 win = dev_drv->win[0];
1459 } else if (win_id == 1) {
1460 win = dev_drv->win[1];
1461 } else if (win_id == 2) {
1462 win = dev_drv->win[2];
1464 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1468 spin_lock(&lcdc_dev->reg_lock);
1469 if (likely(lcdc_dev->clk_on)) {
1470 win->area[0].y_addr =
1471 win->area[0].smem_start + win->area[0].y_offset;
1472 win->area[0].uv_addr =
1473 win->area[0].cbr_start + win->area[0].c_offset;
1474 if (win->area[0].y_addr)
1475 lcdc_layer_update_regs(lcdc_dev, win);
1476 /* lcdc_cfg_done(lcdc_dev); */
1478 spin_unlock(&lcdc_dev->reg_lock);
1480 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1481 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1482 win->area[0].y_offset);
1483 /* this is the first frame of the system,enable frame start interrupt */
1484 if ((dev_drv->first_frame)) {
1485 dev_drv->first_frame = 0;
1486 rk312x_lcdc_enable_irq(dev_drv);
1493 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1494 unsigned long arg, int win_id)
1496 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1497 struct lcdc_device, driver);
1499 void __user *argp = (void __user *)arg;
1500 struct color_key_cfg clr_key_cfg;
1503 case RK_FBIOGET_PANEL_SIZE:
1504 panel_size[0] = lcdc_dev->screen->mode.xres;
1505 panel_size[1] = lcdc_dev->screen->mode.yres;
1506 if (copy_to_user(argp, panel_size, 8))
1509 case RK_FBIOPUT_COLOR_KEY_CFG:
1510 if (copy_from_user(&clr_key_cfg, argp,
1511 sizeof(struct color_key_cfg)))
1513 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1514 clr_key_cfg.win0_color_key_cfg);
1515 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1516 clr_key_cfg.win1_color_key_cfg);
1525 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1529 mutex_lock(&dev_drv->fb_win_id_mutex);
1530 if (!strcmp(id, "fb0"))
1531 win_id = dev_drv->fb0_win_id;
1532 else if (!strcmp(id, "fb1"))
1533 win_id = dev_drv->fb1_win_id;
1534 else if (!strcmp(id, "fb2"))
1535 win_id = dev_drv->fb2_win_id;
1536 mutex_unlock(&dev_drv->fb_win_id_mutex);
1541 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1546 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1549 struct lcdc_device *lcdc_dev =
1550 container_of(dev_drv, struct lcdc_device, driver);
1552 spin_lock(&lcdc_dev->reg_lock);
1553 if (lcdc_dev->clk_on) {
1555 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1559 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1564 spin_unlock(&lcdc_dev->reg_lock);
1569 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1572 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1573 struct lcdc_device, driver);
1574 if (dev_drv->suspend_flag)
1576 dev_drv->suspend_flag = 1;
1577 flush_kthread_worker(&dev_drv->update_regs_worker);
1579 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1580 dev_drv->trsm_ops->disable();
1581 spin_lock(&lcdc_dev->reg_lock);
1582 if (likely(lcdc_dev->clk_on)) {
1583 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1584 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1585 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1586 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1587 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1589 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1591 lcdc_cfg_done(lcdc_dev);
1593 if (dev_drv->iommu_enabled) {
1594 if (dev_drv->mmu_dev)
1595 rockchip_iovmm_deactivate(dev_drv->dev);
1598 spin_unlock(&lcdc_dev->reg_lock);
1600 spin_unlock(&lcdc_dev->reg_lock);
1603 rk312x_lcdc_clk_disable(lcdc_dev);
1604 rk_disp_pwr_disable(dev_drv);
1608 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1610 struct lcdc_device *lcdc_dev =
1611 container_of(dev_drv, struct lcdc_device, driver);
1613 if (!dev_drv->suspend_flag)
1615 rk_disp_pwr_enable(dev_drv);
1616 dev_drv->suspend_flag = 0;
1618 if (lcdc_dev->atv_layer_cnt) {
1619 rk312x_lcdc_clk_enable(lcdc_dev);
1620 rk312x_lcdc_reg_restore(lcdc_dev);
1622 /* config for the FRC mode of dither down */
1623 if (dev_drv->cur_screen &&
1624 dev_drv->cur_screen->face != OUT_P888) {
1625 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1626 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1627 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1628 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1629 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1630 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1633 /* set screen lut */
1634 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1635 rk312x_lcdc_set_lut(dev_drv);
1637 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1639 spin_lock(&lcdc_dev->reg_lock);
1641 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1643 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1645 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1646 lcdc_cfg_done(lcdc_dev);
1648 if (dev_drv->iommu_enabled) {
1649 if (dev_drv->mmu_dev)
1650 rockchip_iovmm_activate(dev_drv->dev);
1653 spin_unlock(&lcdc_dev->reg_lock);
1656 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1657 dev_drv->trsm_ops->enable();
1661 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1662 int win_id, int blank_mode)
1664 switch (blank_mode) {
1665 case FB_BLANK_UNBLANK:
1666 rk312x_lcdc_early_resume(dev_drv);
1668 case FB_BLANK_NORMAL:
1669 rk312x_lcdc_early_suspend(dev_drv);
1672 rk312x_lcdc_early_suspend(dev_drv);
1676 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1681 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1683 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1684 struct lcdc_device, driver);
1685 spin_lock(&lcdc_dev->reg_lock);
1686 if (lcdc_dev->clk_on)
1687 lcdc_cfg_done(lcdc_dev);
1688 spin_unlock(&lcdc_dev->reg_lock);
1694 sin_hue = sin(a)*256 +0x100;
1695 cos_hue = cos(a)*256;
1697 sin_hue = sin(a)*256;
1698 cos_hue = cos(a)*256;
1700 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1704 struct lcdc_device *lcdc_dev =
1705 container_of(dev_drv, struct lcdc_device, driver);
1708 spin_lock(&lcdc_dev->reg_lock);
1709 if (lcdc_dev->clk_on) {
1710 val = lcdc_readl(lcdc_dev, BCSH_H);
1713 val &= m_BCSH_SIN_HUE;
1716 val &= m_BCSH_COS_HUE;
1723 spin_unlock(&lcdc_dev->reg_lock);
1728 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
1732 struct lcdc_device *lcdc_dev =
1733 container_of(dev_drv, struct lcdc_device, driver);
1736 spin_lock(&lcdc_dev->reg_lock);
1737 if (lcdc_dev->clk_on) {
1738 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1739 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1740 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1741 lcdc_cfg_done(lcdc_dev);
1743 spin_unlock(&lcdc_dev->reg_lock);
1748 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1749 bcsh_bcs_mode mode, int value)
1751 struct lcdc_device *lcdc_dev =
1752 container_of(dev_drv, struct lcdc_device, driver);
1755 spin_lock(&lcdc_dev->reg_lock);
1756 if (lcdc_dev->clk_on) {
1759 /* from 0 to 255,typical is 128 */
1762 else if (value >= 0x80)
1763 value = value - 0x80;
1764 mask = m_BCSH_BRIGHTNESS;
1765 val = v_BCSH_BRIGHTNESS(value);
1768 /* from 0 to 510,typical is 256 */
1769 mask = m_BCSH_CONTRAST;
1770 val = v_BCSH_CONTRAST(value);
1773 /* from 0 to 1015,typical is 256 */
1774 mask = m_BCSH_SAT_CON;
1775 val = v_BCSH_SAT_CON(value);
1780 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
1781 lcdc_cfg_done(lcdc_dev);
1783 spin_unlock(&lcdc_dev->reg_lock);
1787 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1790 struct lcdc_device *lcdc_dev =
1791 container_of(dev_drv, struct lcdc_device, driver);
1794 spin_lock(&lcdc_dev->reg_lock);
1795 if (lcdc_dev->clk_on) {
1796 val = lcdc_readl(lcdc_dev, BCSH_BCS);
1799 val &= m_BCSH_BRIGHTNESS;
1806 val &= m_BCSH_CONTRAST;
1810 val &= m_BCSH_SAT_CON;
1817 spin_unlock(&lcdc_dev->reg_lock);
1821 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
1823 struct lcdc_device *lcdc_dev =
1824 container_of(dev_drv, struct lcdc_device, driver);
1827 spin_lock(&lcdc_dev->reg_lock);
1828 if (lcdc_dev->clk_on) {
1829 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1830 if (dev_drv->output_color == COLOR_YCBCR) /* bypass */
1831 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1832 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1834 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1835 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE | m_BCSH_R2Y_EN,
1837 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1839 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1840 if (dev_drv->output_color == COLOR_RGB) /* bypass */
1841 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1842 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1844 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1845 m_BCSH_R2Y_EN | m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1846 v_BCSH_R2Y_EN(1) | v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1850 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,m_BCSH_EN | m_BCSH_OUT_MODE,
1851 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
1852 lcdc_writel(lcdc_dev, BCSH_BCS,
1853 v_BCSH_BRIGHTNESS(0x00) |
1854 v_BCSH_CONTRAST(0x80) |
1855 v_BCSH_SAT_CON(0x80));
1856 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
1860 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
1862 lcdc_cfg_done(lcdc_dev);
1866 spin_unlock(&lcdc_dev->reg_lock);
1870 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1872 struct rk_lcdc_win_area area;
1873 int fb2_win_id, fb1_win_id, fb0_win_id;
1875 mutex_lock(&dev_drv->fb_win_id_mutex);
1876 if (order == FB_DEFAULT_ORDER)
1877 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1879 fb2_win_id = order / 100;
1880 fb1_win_id = (order / 10) % 10;
1881 fb0_win_id = order % 10;
1883 if (fb0_win_id != dev_drv->fb0_win_id) {
1884 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
1885 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
1886 dev_drv->win[fb0_win_id]->area[0];
1887 dev_drv->win[fb0_win_id]->area[0] = area;
1888 dev_drv->fb0_win_id = fb0_win_id;
1890 dev_drv->fb1_win_id = fb1_win_id;
1891 dev_drv->fb2_win_id = fb2_win_id;
1893 mutex_unlock(&dev_drv->fb_win_id_mutex);
1898 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
1901 struct lcdc_device *lcdc_dev =
1902 container_of(dev_drv, struct lcdc_device, driver);
1903 struct rk_screen *screen = dev_drv->cur_screen;
1908 u32 x_total, y_total;
1910 ft = div_u64(1000000000000llu, fps);
1912 screen->mode.upper_margin + screen->mode.lower_margin +
1913 screen->mode.yres + screen->mode.vsync_len;
1915 screen->mode.left_margin + screen->mode.right_margin +
1916 screen->mode.xres + screen->mode.hsync_len;
1917 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1918 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1919 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1922 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1923 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1924 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1925 screen->ft = 1000 / fps; /*one frame time in ms */
1928 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1929 clk_get_rate(lcdc_dev->dclk), fps);
1934 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
1937 struct lcdc_device *lcdc_dev =
1938 container_of(dev_drv,struct lcdc_device,driver);
1940 enable_irq(lcdc_dev->irq);
1942 disable_irq(lcdc_dev->irq);
1946 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1948 struct lcdc_device *lcdc_dev =
1949 container_of(dev_drv, struct lcdc_device, driver);
1953 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
1954 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1955 if (int_reg & m_LF_INT_STA) {
1956 dev_drv->frame_time.last_framedone_t =
1957 dev_drv->frame_time.framedone_t;
1958 dev_drv->frame_time.framedone_t = cpu_clock(0);
1959 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1961 ret = RK_LF_STATUS_FC;
1963 ret = RK_LF_STATUS_FR;
1965 ret = RK_LF_STATUS_NC;
1971 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
1972 unsigned int *dsp_addr)
1974 struct lcdc_device *lcdc_dev =
1975 container_of(dev_drv, struct lcdc_device, driver);
1977 if (lcdc_dev->clk_on) {
1978 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1979 if (lcdc_dev->soc_type == VOP_RK3036)
1980 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
1981 else if (lcdc_dev->soc_type == VOP_RK312X)
1982 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
1987 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1988 char *buf, int win_id)
1990 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
1992 char format_w0[9] = "NULL";
1993 char format_w1[9] = "NULL";
1994 char status_w0[9] = "NULL";
1995 char status_w1[9] = "NULL";
1996 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
1997 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
1998 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
1999 u16 x_factor, y_factor, x_scale, y_scale;
2001 u32 win1_dsp_yaddr = 0;
2003 spin_lock(&lcdc_dev->reg_lock);
2004 if (lcdc_dev->clk_on) {
2006 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2007 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2008 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2011 if (fmt_id & m_WIN0_EN)
2012 strcpy(status_w0, "enabled");
2014 strcpy(status_w0, "disabled");
2016 if ((fmt_id & m_WIN1_EN) >> 1)
2017 strcpy(status_w1, "enabled");
2019 strcpy(status_w1, "disabled");
2022 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2025 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2026 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2029 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2030 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2031 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2033 if (lcdc_dev->soc_type == VOP_RK3036) {
2034 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2035 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2036 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2037 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2038 /* rk312x unsupport win1 scaler,so have no act info */
2044 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2045 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2046 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2048 if (lcdc_dev->soc_type == VOP_RK3036)
2049 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2050 else if (lcdc_dev->soc_type == VOP_RK312X)
2051 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2052 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2053 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2056 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2057 x_st_w0 = dsp_st & m_DSP_STX;
2058 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2060 if (lcdc_dev->soc_type == VOP_RK3036)
2061 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2062 else if (lcdc_dev->soc_type == VOP_RK312X)
2063 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2065 x_st_w1 = dsp_st & m_DSP_STX;
2066 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2069 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2070 x_factor = factor & m_X_SCL_FACTOR;
2071 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2072 x_scale = 4096 * 100 / x_factor;
2073 y_scale = 4096 * 100 / y_factor;
2076 if (lcdc_dev->soc_type == VOP_RK3036)
2077 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2078 else if (lcdc_dev->soc_type == VOP_RK312X)
2079 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2081 spin_unlock(&lcdc_dev->reg_lock);
2084 spin_unlock(&lcdc_dev->reg_lock);
2085 return snprintf(buf, PAGE_SIZE,
2097 "YRGB buffer addr:0x%08x\n"
2098 "CBR buffer addr:0x%08x\n\n"
2108 "YRGB buffer addr:0x%08x\n"
2123 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2124 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2135 ovl ? "win0 on the top of win1\n" :
2136 "win1 on the top of win0\n");
2139 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2141 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2144 int *cbase = (int *)lcdc_dev->regs;
2145 int *regsbak = (int *)lcdc_dev->regsbak;
2148 printk("back up reg:\n");
2149 for (i = 0; i <= (0xDC >> 4); i++) {
2150 for (j = 0; j < 4; j++)
2151 printk("%08x ", *(regsbak + i * 4 + j));
2155 printk("lcdc reg:\n");
2156 for (i = 0; i <= (0xDC >> 4); i++) {
2157 for (j = 0; j < 4; j++)
2158 printk("%08x ", readl_relaxed(cbase + i * 4 + j));
2164 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2166 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2167 struct lcdc_device, driver);
2168 if (lcdc_dev->soc_type == VOP_RK312X) {
2169 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2170 v_DIRECT_PATH_EN(open));
2171 lcdc_cfg_done(lcdc_dev);
2176 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2178 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2179 struct lcdc_device, driver);
2181 if (lcdc_dev->soc_type == VOP_RK312X) {
2182 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2183 v_DIRECT_PATH_LAYER(win_id));
2184 lcdc_cfg_done(lcdc_dev);
2190 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2192 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2193 struct lcdc_device, driver);
2196 if (lcdc_dev->soc_type == VOP_RK312X)
2197 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2202 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2203 .open = rk312x_lcdc_open,
2204 .load_screen = rk312x_load_screen,
2205 .set_par = rk312x_lcdc_set_par,
2206 .pan_display = rk312x_lcdc_pan_display,
2207 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2208 .blank = rk312x_lcdc_blank,
2209 .ioctl = rk312x_lcdc_ioctl,
2210 .get_win_state = rk312x_lcdc_get_win_state,
2211 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2212 .get_disp_info = rk312x_lcdc_get_disp_info,
2213 .fps_mgr = rk312x_lcdc_fps_mgr,
2214 .fb_get_win_id = rk312x_lcdc_get_win_id,
2215 .fb_win_remap = rk312x_fb_win_remap,
2216 .poll_vblank = rk312x_lcdc_poll_vblank,
2217 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2218 .cfg_done = rk312x_lcdc_cfg_done,
2219 .dump_reg = rk312x_lcdc_reg_dump,
2220 .dpi_open = rk312x_lcdc_dpi_open,
2221 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2222 .dpi_status = rk312x_lcdc_dpi_status,
2223 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2224 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2225 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2226 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2227 .open_bcsh = rk312x_lcdc_open_bcsh,
2228 .set_screen_scaler = rk312x_lcdc_set_scaler,
2229 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2230 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2233 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2234 .soc_type = VOP_RK3036,
2237 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2238 .soc_type = VOP_RK312X,
2241 #if defined(CONFIG_OF)
2242 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2245 .compatible = "rockchip,rk3036-lcdc",
2246 .data = (void *)&rk3036_lcdc_drvdata,
2250 .compatible = "rockchip,rk312x-lcdc",
2251 .data = (void *)&rk312x_lcdc_drvdata,
2256 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2258 struct device_node *np = lcdc_dev->dev->of_node;
2259 const struct of_device_id *match;
2260 const struct rk_lcdc_drvdata *lcdc_drvdata;
2263 #if defined(CONFIG_ROCKCHIP_IOMMU)
2264 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2265 lcdc_dev->driver.iommu_enabled = 0;
2267 lcdc_dev->driver.iommu_enabled = val;
2269 lcdc_dev->driver.iommu_enabled = 0;
2272 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2273 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2275 lcdc_dev->driver.fb_win_map = val;
2277 match = of_match_node(rk312x_lcdc_dt_ids, np);
2279 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2280 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2282 return PTR_ERR(match);
2288 static int rk312x_lcdc_probe(struct platform_device *pdev)
2290 struct lcdc_device *lcdc_dev = NULL;
2291 struct rk_lcdc_driver *dev_drv;
2292 struct device *dev = &pdev->dev;
2293 struct resource *res;
2296 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2298 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2301 platform_set_drvdata(pdev, lcdc_dev);
2302 lcdc_dev->dev = dev;
2303 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2304 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2308 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2309 lcdc_dev->reg_phy_base = res->start;
2310 lcdc_dev->len = resource_size(res);
2311 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2312 if (IS_ERR(lcdc_dev->regs)) {
2313 ret = PTR_ERR(lcdc_dev->regs);
2317 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2318 if (IS_ERR(lcdc_dev->regsbak)) {
2319 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2320 ret = PTR_ERR(lcdc_dev->regsbak);
2323 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2324 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2325 lcdc_dev->prop = PRMRY;
2326 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2327 dev_drv = &lcdc_dev->driver;
2329 dev_drv->prop = lcdc_dev->prop;
2330 dev_drv->id = lcdc_dev->id;
2331 dev_drv->ops = &lcdc_drv_ops;
2332 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2333 spin_lock_init(&lcdc_dev->reg_lock);
2335 lcdc_dev->irq = platform_get_irq(pdev, 0);
2336 if (lcdc_dev->irq < 0) {
2337 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2340 goto err_request_irq;
2343 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2344 IRQF_DISABLED | IRQF_SHARED, dev_name(dev), lcdc_dev);
2346 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2347 lcdc_dev->irq, ret);
2348 goto err_request_irq;
2351 if (dev_drv->iommu_enabled)
2352 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2354 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2356 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2357 goto err_register_fb;
2359 lcdc_dev->screen = dev_drv->screen0;
2361 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2362 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2367 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2370 devm_kfree(&pdev->dev, lcdc_dev);
2374 #if defined(CONFIG_PM)
2375 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2380 static int rk312x_lcdc_resume(struct platform_device *pdev)
2385 #define rk312x_lcdc_suspend NULL
2386 #define rk312x_lcdc_resume NULL
2389 static int rk312x_lcdc_remove(struct platform_device *pdev)
2394 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2396 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2398 rk312x_lcdc_deinit(lcdc_dev);
2399 rk312x_lcdc_clk_disable(lcdc_dev);
2400 rk_disp_pwr_disable(&lcdc_dev->driver);
2403 static struct platform_driver rk312x_lcdc_driver = {
2404 .probe = rk312x_lcdc_probe,
2405 .remove = rk312x_lcdc_remove,
2407 .name = "rk312x-lcdc",
2408 .owner = THIS_MODULE,
2409 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2411 .suspend = rk312x_lcdc_suspend,
2412 .resume = rk312x_lcdc_resume,
2413 .shutdown = rk312x_lcdc_shutdown,
2416 static int __init rk312x_lcdc_module_init(void)
2418 return platform_driver_register(&rk312x_lcdc_driver);
2421 static void __exit rk312x_lcdc_module_exit(void)
2423 platform_driver_unregister(&rk312x_lcdc_driver);
2426 fs_initcall(rk312x_lcdc_module_init);
2427 module_exit(rk312x_lcdc_module_exit);