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 <linux/uaccess.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37 #include <linux/rockchip-iovmm.h>
38 #include "rk312x_lcdc.h"
39 #include <linux/rockchip/dvfs.h>
41 static int dbg_thresd;
42 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
44 #define DBG(level, x...) do { \
45 if (unlikely(dbg_thresd >= level)) \
46 pr_info(KERN_INFO x); \
49 #define grf_writel(offset, v) do { \
50 writel_relaxed(v, RK_GRF_VIRT + offset); \
54 static struct rk_lcdc_win lcdc_win[] = {
72 static irqreturn_t rk312x_lcdc_isr(int irq, void *dev_id)
74 struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
75 ktime_t timestamp = ktime_get();
76 u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
78 if (int_reg & m_FS_INT_STA) {
79 timestamp = ktime_get();
80 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
82 /*if (lcdc_dev->driver.wait_fs) {*/
84 spin_lock(&(lcdc_dev->driver.cpl_lock));
85 complete(&(lcdc_dev->driver.frame_done));
86 spin_unlock(&(lcdc_dev->driver.cpl_lock));
88 lcdc_dev->driver.vsync_info.timestamp = timestamp;
89 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
91 } else if (int_reg & m_LF_INT_STA) {
92 lcdc_dev->driver.frame_time.last_framedone_t =
93 lcdc_dev->driver.frame_time.framedone_t;
94 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
95 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
99 #ifdef LCDC_IRQ_EMPTY_DEBUG
100 if (int_reg & m_WIN0_EMPTY_INT_STA) {
101 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN0_EMPTY_INT_CLEAR,
102 v_WIN0_EMPTY_INT_CLEAR(1));
103 dev_info(lcdc_dev->dev, "win0 empty irq\n");
104 } else if (int_reg & m_WIN1_EMPTY_INT_STA) {
105 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN1_EMPTY_INT_CLEAR,
106 v_WIN1_EMPTY_INT_CLEAR(1));
107 dev_info(lcdc_dev->dev, "win1 empty irq\n");
114 static int rk312x_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
116 #ifdef CONFIG_RK_FPGA
117 lcdc_dev->clk_on = 1;
120 if (!lcdc_dev->clk_on) {
121 clk_prepare_enable(lcdc_dev->hclk);
122 clk_prepare_enable(lcdc_dev->dclk);
123 clk_prepare_enable(lcdc_dev->aclk);
124 clk_prepare_enable(lcdc_dev->pd);
125 spin_lock(&lcdc_dev->reg_lock);
126 lcdc_dev->clk_on = 1;
127 spin_unlock(&lcdc_dev->reg_lock);
133 static int rk312x_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
135 #ifdef CONFIG_RK_FPGA
136 lcdc_dev->clk_on = 0;
139 if (lcdc_dev->clk_on) {
140 spin_lock(&lcdc_dev->reg_lock);
141 lcdc_dev->clk_on = 0;
142 spin_unlock(&lcdc_dev->reg_lock);
144 clk_disable_unprepare(lcdc_dev->dclk);
145 clk_disable_unprepare(lcdc_dev->hclk);
146 clk_disable_unprepare(lcdc_dev->aclk);
147 clk_disable_unprepare(lcdc_dev->pd);
153 static int rk312x_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
156 struct lcdc_device *lcdc_dev = container_of(dev_drv,
157 struct lcdc_device, driver);
158 /*struct rk_screen *screen = dev_drv->cur_screen;*/
160 spin_lock(&lcdc_dev->reg_lock);
161 if (likely(lcdc_dev->clk_on)) {
162 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
163 m_LF_INT_CLEAR | m_LF_INT_EN |
164 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
165 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) |
166 v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
167 v_BUS_ERR_INT_CLEAR(1) | v_BUS_ERR_INT_EN(0);
169 mask |= m_LF_INT_NUM;
170 val |= v_LF_INT_NUM(screen->mode.vsync_len +
171 screen->mode.upper_margin +
174 #ifdef LCDC_IRQ_EMPTY_DEBUG
175 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
176 val |= v_WIN0_EMPTY_INT_EN(1) | v_WIN1_EMPTY_INT_EN(1);
179 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
180 spin_unlock(&lcdc_dev->reg_lock);
182 spin_unlock(&lcdc_dev->reg_lock);
188 static int rk312x_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
192 spin_lock(&lcdc_dev->reg_lock);
193 if (likely(lcdc_dev->clk_on)) {
194 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
195 m_LF_INT_CLEAR | m_LF_INT_EN |
196 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
197 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
198 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
199 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
200 #ifdef LCDC_IRQ_EMPTY_DEBUG
201 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
202 val |= v_WIN0_EMPTY_INT_EN(0) | v_WIN1_EMPTY_INT_EN(0);
205 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
206 spin_unlock(&lcdc_dev->reg_lock);
208 spin_unlock(&lcdc_dev->reg_lock);
215 static int win0_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
217 spin_lock(&lcdc_dev->reg_lock);
218 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, addr);
219 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(1));
220 lcdc_cfg_done(lcdc_dev);
221 spin_unlock(&lcdc_dev->reg_lock);
226 static int win1_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
228 spin_lock(&lcdc_dev->reg_lock);
229 if (lcdc_dev->soc_type == VOP_RK3036)
230 lcdc_writel(lcdc_dev, WIN1_MST, addr);
232 lcdc_writel(lcdc_dev, WIN1_MST_RK312X, addr);
233 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(1));
234 lcdc_cfg_done(lcdc_dev);
235 spin_unlock(&lcdc_dev->reg_lock);
239 int rk312x_lcdc_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
240 int win_id, u32 addr)
242 struct lcdc_device *lcdc_dev = container_of(dev_drv,
243 struct lcdc_device, driver);
245 win0_set_addr(lcdc_dev, addr);
247 win1_set_addr(lcdc_dev, addr);
252 static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
256 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
257 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
259 spin_lock(&lcdc_dev->reg_lock);
260 for (reg = 0; reg < 0xe0; reg += 4) {
261 val = lcdc_readl(lcdc_dev, reg);
262 if (reg == WIN0_ACT_INFO) {
263 win0->area[0].xact = (val & m_ACT_WIDTH)+1;
264 win0->area[0].yact = ((val & m_ACT_HEIGHT)>>16)+1;
267 if (lcdc_dev->soc_type == VOP_RK312X) {
268 if (reg == WIN1_DSP_INFO_RK312X) {
269 win1->area[0].xact = (val & m_DSP_WIDTH) + 1;
271 ((val & m_DSP_HEIGHT) >> 16) + 1;
274 if (reg == WIN1_ACT_INFO) {
275 win1->area[0].xact = (val & m_ACT_WIDTH) + 1;
277 ((val & m_ACT_HEIGHT) >> 16) + 1;
281 spin_unlock(&lcdc_dev->reg_lock);
284 static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
288 enum data_format win0_format = lcdc_dev->driver.win[0]->format;
289 enum data_format win1_format = lcdc_dev->driver.win[1]->format;
291 int win0_alpha_en = ((win0_format == ARGB888) ||
292 (win0_format == ABGR888)) ? 1 : 0;
293 int win1_alpha_en = ((win1_format == ARGB888) ||
294 (win1_format == ABGR888)) ? 1 : 0;
295 int atv_layer_cnt = lcdc_dev->driver.win[0]->state +
296 lcdc_dev->driver.win[1]->state;
297 u32 *_pv = (u32 *)lcdc_dev->regsbak;
299 _pv += (DSP_CTRL0 >> 2);
300 win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
301 if (win0_top && (atv_layer_cnt >= 2) && (win0_alpha_en)) {
302 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
303 val = v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0);
304 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
306 mask = m_WIN0_ALPHA_MODE |
307 m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
308 val = v_WIN0_ALPHA_MODE(1) |
309 v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
310 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
311 /*this vop bg layer not support yuv domain overlay,so bg val
312 have to set 0x800a80 equeal to 0x000000 at rgb domian,after
313 android start we recover to 0x00000*/
315 val = v_BG_COLOR(0x000000);
316 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
317 } else if ((!win0_top) && (atv_layer_cnt >= 2) &&
319 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
320 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
321 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
323 mask = m_WIN1_ALPHA_MODE |
324 m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
325 val = v_WIN1_ALPHA_MODE(1) |
326 v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
327 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
328 /*this vop bg layer not support yuv domain overlay,so bg val
329 have to set 0x800a80 equeal to 0x000000 at rgb domian,after
330 android start we recover to 0x00000*/
332 val = v_BG_COLOR(0x000000);
333 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
335 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
336 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
337 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
340 if (lcdc_dev->driver.win[2]->state == 1) {
341 mask = m_HWC_ALPAH_EN;
342 val = v_HWC_ALPAH_EN(1);
343 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
345 mask = m_HWC_ALPHA_MODE;
346 val = v_HWC_ALPHA_MODE(1);
347 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
349 mask = m_HWC_ALPAH_EN;
350 val = v_HWC_ALPAH_EN(0);
351 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
357 static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
358 struct rk_lcdc_win *win)
360 struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
361 struct rk_screen *screen = dev_drv->cur_screen;
363 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
364 switch (win->fmt_cfg) {
365 case VOP_FORMAT_ARGB888:
366 case VOP_FORMAT_RGB888:
367 case VOP_FORMAT_RGB565:
368 if ((screen->mode.xres < 1280) &&
369 (screen->mode.yres < 720)) {
370 win->csc_mode = VOP_R2Y_CSC_BT601;
372 win->csc_mode = VOP_R2Y_CSC_BT709;
379 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
380 v_WIN0_CSC_MODE(win->csc_mode));
381 } else if (win->id == 1) {
382 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
383 v_WIN1_CSC_MODE(win->csc_mode));
385 } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
386 switch (win->fmt_cfg) {
387 case VOP_FORMAT_YCBCR420:
389 win->csc_mode = VOP_Y2R_CSC_MPEG;
390 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
392 v_WIN0_CSC_MODE(win->csc_mode));
402 static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
403 struct rk_lcdc_win *win)
408 if (win->state == 1) {
409 if (lcdc_dev->soc_type == VOP_RK312X)
410 lcdc_layer_csc_mode(lcdc_dev, win);
413 mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
414 val = v_WIN0_EN(win->state) |
415 v_WIN0_FORMAT(win->fmt_cfg) |
416 v_WIN0_RB_SWAP(win->swap_rb);
417 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
418 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
419 v_X_SCL_FACTOR(win->scale_yrgb_x) |
420 v_Y_SCL_FACTOR(win->scale_yrgb_y));
421 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
422 v_X_SCL_FACTOR(win->scale_cbcr_x) |
423 v_Y_SCL_FACTOR(win->scale_cbcr_y));
425 lcdc_msk_reg(lcdc_dev, WIN0_VIR,
426 m_YRGB_VIR | m_CBBR_VIR,
427 v_YRGB_VIR(win->area[0].y_vir_stride) |
428 v_CBCR_VIR(win->area[0].uv_vir_stride));
429 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
430 v_ACT_WIDTH(win->area[0].xact) |
431 v_ACT_HEIGHT(win->area[0].yact));
432 lcdc_writel(lcdc_dev, WIN0_DSP_ST,
433 v_DSP_STX(win->area[0].dsp_stx) |
434 v_DSP_STY(win->area[0].dsp_sty));
435 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
436 v_DSP_WIDTH(win->area[0].xsize) |
437 v_DSP_HEIGHT(win->area[0].ysize));
439 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
440 win->area[0].y_addr);
441 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
442 win->area[0].uv_addr);
443 } else if (win->id == 1) {
444 mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
445 val = v_WIN1_EN(win->state) |
446 v_WIN1_FORMAT(win->fmt_cfg) |
447 v_WIN1_RB_SWAP(win->swap_rb);
448 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
449 /* rk312x unsupport win1 scale */
450 if (lcdc_dev->soc_type == VOP_RK3036) {
451 lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
452 v_X_SCL_FACTOR(win->scale_yrgb_x) |
453 v_Y_SCL_FACTOR(win->scale_yrgb_y));
454 lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
455 v_ACT_WIDTH(win->area[0].xact) |
456 v_ACT_HEIGHT(win->area[0].yact));
457 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
458 v_DSP_WIDTH(win->area[0].xsize) |
459 v_DSP_HEIGHT(win->area[0].ysize));
460 lcdc_writel(lcdc_dev, WIN1_DSP_ST,
461 v_DSP_STX(win->area[0].dsp_stx) |
462 v_DSP_STY(win->area[0].dsp_sty));
463 lcdc_writel(lcdc_dev,
464 WIN1_MST, win->area[0].y_addr);
466 lcdc_writel(lcdc_dev, WIN1_DSP_INFO_RK312X,
467 v_DSP_WIDTH(win->area[0].xsize) |
468 v_DSP_HEIGHT(win->area[0].ysize));
469 lcdc_writel(lcdc_dev, WIN1_DSP_ST_RK312X,
470 v_DSP_STX(win->area[0].dsp_stx) |
471 v_DSP_STY(win->area[0].dsp_sty));
473 lcdc_writel(lcdc_dev,
475 win->area[0].y_addr);
478 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
479 v_YRGB_VIR(win->area[0].y_vir_stride));
482 } else if (win->id == 2) {
483 mask = m_HWC_EN | m_HWC_LODAD_EN;
484 val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
485 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
486 if ((win->area[0].xsize == 32) &&
487 (win->area[0].ysize == 32))
489 else if ((win->area[0].xsize == 64) &&
490 (win->area[0].ysize == 64))
493 dev_err(lcdc_dev->dev, "unsupport hwc size:x=%d,y=%d\n",
494 win->area[0].xsize, win->area[0].ysize);
495 lcdc_writel(lcdc_dev, HWC_DSP_ST,
496 v_DSP_STX(win->area[0].dsp_stx) |
497 v_DSP_STY(win->area[0].dsp_sty));
499 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
502 win->area[0].y_addr = 0;
503 win->area[0].uv_addr = 0;
505 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
507 else if (win->id == 1)
508 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
510 else if (win->id == 2)
511 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
513 rk312x_lcdc_alpha_cfg(lcdc_dev);
516 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
519 spin_lock(&lcdc_dev->reg_lock);
520 if (likely(lcdc_dev->clk_on) &&
521 lcdc_dev->driver.win[win_id]->state != open) {
523 if (!lcdc_dev->atv_layer_cnt) {
524 dev_info(lcdc_dev->dev,
525 "wakeup from standby!\n");
526 lcdc_dev->standby = 0;
528 lcdc_dev->atv_layer_cnt++;
529 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
530 lcdc_dev->atv_layer_cnt--;
532 lcdc_dev->driver.win[win_id]->state = open;
534 lcdc_layer_update_regs(lcdc_dev,
535 lcdc_dev->driver.win[win_id]);
536 lcdc_cfg_done(lcdc_dev);
538 /*if no layer used,disable lcdc */
539 if (!lcdc_dev->atv_layer_cnt) {
540 dev_info(lcdc_dev->dev,
541 "no layer is used,go to standby!\n");
542 lcdc_dev->standby = 1;
545 spin_unlock(&lcdc_dev->reg_lock);
548 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
550 struct lcdc_device *lcdc_dev =
551 container_of(dev_drv, struct lcdc_device, driver);
552 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
553 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
556 spin_lock(&lcdc_dev->reg_lock);
557 if (likely(lcdc_dev->clk_on)) {
558 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
559 v_LCDC_STANDBY(lcdc_dev->standby));
560 lcdc_layer_update_regs(lcdc_dev, win0);
561 lcdc_layer_update_regs(lcdc_dev, win1);
562 rk312x_lcdc_alpha_cfg(lcdc_dev);
563 lcdc_cfg_done(lcdc_dev);
566 spin_unlock(&lcdc_dev->reg_lock);
567 //if (dev_drv->wait_fs) {
569 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
570 init_completion(&dev_drv->frame_done);
571 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
572 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
574 (dev_drv->cur_screen->ft +
576 if (!timeout && (!dev_drv->frame_done.done)) {
577 dev_warn(lcdc_dev->dev,
578 "wait for new frame start time out!\n");
582 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
587 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
589 memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
592 static void rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
595 struct lcdc_device *lcdc_dev =
596 container_of(dev_drv, struct lcdc_device, driver);
598 /*spin_lock(&lcdc_dev->reg_lock);*/
599 if (likely(lcdc_dev->clk_on)) {
600 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
601 m_AXI_OUTSTANDING_MAX_NUM;
602 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
603 v_AXI_MAX_OUTSTANDING_EN(1);
604 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
606 /*spin_unlock(&lcdc_dev->reg_lock);*/
608 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
609 int *hwc_lut, int mode)
615 struct lcdc_device *lcdc_dev =
616 container_of(dev_drv, struct lcdc_device, driver);
617 if (dev_drv->hwc_lut == NULL)
618 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
620 spin_lock(&lcdc_dev->reg_lock);
621 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
622 lcdc_cfg_done(lcdc_dev);
624 for (i = 0; i < 256; i++) {
626 dev_drv->hwc_lut[i] = hwc_lut[i];
627 v = dev_drv->hwc_lut[i];
628 c = lcdc_dev->hwc_lut_addr_base + i;
629 writel_relaxed(v, c);
631 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
632 lcdc_cfg_done(lcdc_dev);
633 spin_unlock(&lcdc_dev->reg_lock);
637 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
642 struct lcdc_device *lcdc_dev =
643 container_of(dev_drv, struct lcdc_device, driver);
645 spin_lock(&lcdc_dev->reg_lock);
646 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
647 lcdc_cfg_done(lcdc_dev);
649 for (i = 0; i < 256; i++) {
650 v = dev_drv->cur_screen->dsp_lut[i];
651 c = lcdc_dev->dsp_lut_addr_base + (i<<2);
652 writel_relaxed(v, c);
654 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
655 lcdc_cfg_done(lcdc_dev);
656 spin_unlock(&lcdc_dev->reg_lock);
660 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
663 #ifdef CONFIG_RK_FPGA
667 struct lcdc_device *lcdc_dev =
668 container_of(dev_drv, struct lcdc_device, driver);
669 struct rk_screen *screen = dev_drv->cur_screen;
672 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
674 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
676 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
677 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
679 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
680 screen->ft = 1000 / fps;
681 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
682 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
686 /********do basic init*********/
687 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
689 struct lcdc_device *lcdc_dev = container_of(dev_drv,
690 struct lcdc_device, driver);
691 if (lcdc_dev->pre_init)
694 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
695 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
696 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
697 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
698 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
699 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
701 if (/*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
702 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
703 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
707 rk_disp_pwr_enable(dev_drv);
708 rk312x_lcdc_clk_enable(lcdc_dev);
710 /* backup reg config at uboot */
711 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
713 /* config for the FRC mode of dither down */
714 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
715 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
716 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
717 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
718 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
719 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
721 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
722 lcdc_cfg_done(lcdc_dev);
723 /*if (dev_drv->iommu_enabled)
724 {// disable all wins to workaround iommu pagefault
725 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
726 v_WIN0_EN(0) | v_WIN1_EN(0));
727 lcdc_cfg_done(lcdc_dev);
728 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
730 if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
731 if(support_uboot_display())
732 dev_drv->bcsh_init_status = 1;
734 dev_drv->ops->open_bcsh(dev_drv, 1);
736 lcdc_dev->pre_init = true;
741 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
745 spin_lock(&lcdc_dev->reg_lock);
746 if (likely(lcdc_dev->clk_on)) {
747 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
748 m_LF_INT_CLEAR | m_LF_INT_EN |
749 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
750 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
751 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
752 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
753 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
754 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
755 lcdc_cfg_done(lcdc_dev);
756 spin_unlock(&lcdc_dev->reg_lock);
758 spin_unlock(&lcdc_dev->reg_lock);
763 static u32 calc_sclk_freq(struct rk_screen *src_screen,
764 struct rk_screen *dst_screen)
772 if (!src_screen || !dst_screen)
775 dsp_vtotal = dst_screen->mode.yres;
776 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
777 dst_screen->mode.xres + dst_screen->mode.right_margin;
778 dsp_in_vtotal = src_screen->mode.yres;
779 dsp_in_htotal = src_screen->mode.left_margin +
780 src_screen->mode.hsync_len +
781 src_screen->mode.xres + src_screen->mode.right_margin;
782 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
783 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
785 return (u32)sclk_freq;
788 #define SCLK_PLL_LIMIT 594000000
789 #define GPU_FREQ_MAX_LIMIT 297000000
790 #define GPU_FREQ_NEED 400000000
792 static u32 calc_sclk_pll_freq(u32 sclk_freq)
796 if (sclk_freq < (SCLK_PLL_LIMIT / 10)) {
797 return (sclk_freq * 10);
799 multi_num = GPU_FREQ_NEED / sclk_freq;
800 return (sclk_freq * multi_num);
804 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
805 struct rk_screen *dst, u32 sclk_freq)
810 u64 T_BP_in, T_BP_out, T_Delta, Tin;
811 u32 src_pixclock, dst_pixclock;
813 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
815 if (unlikely(!src) || unlikely(!dst))
818 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
819 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
820 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
821 dst->mode.xres + dst->mode.right_margin;
822 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
823 dst->mode.yres + dst->mode.lower_margin;
824 src_htotal = src->mode.left_margin + src->mode.hsync_len +
825 src->mode.xres + src->mode.right_margin;
826 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
827 src->mode.yres + src->mode.lower_margin;
828 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
829 src->mode.hsync_len + src->mode.left_margin;
830 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
831 dst->mode.hsync_len + dst->mode.left_margin;
833 T_BP_in = BP_in * src_pixclock;
834 T_BP_out = BP_out * dst_pixclock;
835 Tin = src_vtotal * src_htotal * src_pixclock;
837 v_scale_ratio = src->mode.yres / dst->mode.yres;
838 if (v_scale_ratio <= 2)
839 T_Delta = 5 * src_htotal * src_pixclock;
841 T_Delta = 12 * src_htotal * src_pixclock;
843 if (T_BP_in + T_Delta > T_BP_out)
844 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
846 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
848 /* (T_frm_st = scl_vst * src_htotal * src_pixclock +
849 scl_hst * src_pixclock) */
850 temp = do_div(T_frm_st, src_pixclock);
851 temp = do_div(T_frm_st, src_htotal);
852 dst->scl_hst = temp - 1;
853 dst->scl_vst = T_frm_st;
858 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
859 struct rk_screen *dst_screen, bool enable)
861 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
862 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
863 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
864 u32 scl_v_factor, scl_h_factor;
865 u32 dst_frame_hst, dst_frame_vst;
866 u32 src_w, src_h, dst_w, dst_h;
872 struct rk_screen *src;
873 struct rk_screen *dst;
874 struct lcdc_device *lcdc_dev = container_of(dev_drv,
875 struct lcdc_device, driver);
876 struct dvfs_node *gpu_clk = clk_get_dvfs_node("clk_gpu");
878 if (unlikely(!lcdc_dev->clk_on))
882 spin_lock(&lcdc_dev->reg_lock);
883 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
884 m_SCALER_EN | m_SCALER_OUT_ZERO |
886 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(1) |
888 lcdc_cfg_done(lcdc_dev);
889 spin_unlock(&lcdc_dev->reg_lock);
890 if (lcdc_dev->sclk_on) {
891 clk_disable_unprepare(lcdc_dev->sclk);
892 lcdc_dev->sclk_on = false;
895 /* switch pll freq as default when sclk is no used */
896 if (clk_get_rate(lcdc_dev->pll_sclk) != GPU_FREQ_NEED) {
897 dvfs_clk_enable_limit(gpu_clk, GPU_FREQ_MAX_LIMIT,
899 clk_set_rate(lcdc_dev->pll_sclk, GPU_FREQ_NEED);
900 dvfs_clk_enable_limit(gpu_clk, 0, -1);
902 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
907 * rk312x used one lcdc to apply dual disp
908 * hdmi screen is used for scaler src
909 * prmry screen is used for scaler dst
912 src = dev_drv->cur_screen;
914 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
918 if (!lcdc_dev->sclk_on) {
919 clk_prepare_enable(lcdc_dev->sclk);
920 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
921 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
924 dvfs_clk_enable_limit(gpu_clk,
928 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
929 /* cancel limit gpu freq */
930 dvfs_clk_enable_limit(gpu_clk, 0, -1);
932 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
933 lcdc_dev->sclk_on = true;
934 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
935 lcdc_dev->s_pixclock);
938 /* config scale timing */
939 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
940 dst_frame_vst = dst->scl_vst;
941 dst_frame_hst = dst->scl_hst;
943 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
944 dst->mode.xres + dst->mode.right_margin;
945 dsp_hs_end = dst->mode.hsync_len;
947 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
948 dst->mode.yres + dst->mode.lower_margin;
949 dsp_vs_end = dst->mode.vsync_len;
951 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
953 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
954 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
956 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
958 dsp_hact_st = dsp_hbor_st + bor_left;
959 dsp_hact_end = dsp_hbor_end - bor_right;
960 dsp_vact_st = dsp_vbor_st + bor_up;
961 dsp_vact_end = dsp_vbor_end - bor_down;
963 src_w = src->mode.xres;
964 src_h = src->mode.yres;
965 dst_w = dsp_hact_end - dsp_hact_st;
966 dst_h = dsp_vact_end - dsp_vact_st;
968 /* calc scale factor */
969 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
970 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
972 spin_lock(&lcdc_dev->reg_lock);
973 if (dst->color_mode != src->color_mode) {
974 /*dev_drv->output_color = dst->color_mode;
975 if (dev_drv->output_color == COLOR_YCBCR)
976 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
978 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
979 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
980 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
983 lcdc_writel(lcdc_dev, SCALER_FACTOR,
984 v_SCALER_H_FACTOR(scl_h_factor) |
985 v_SCALER_V_FACTOR(scl_v_factor));
987 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
988 v_SCALER_FRAME_HST(dst_frame_hst) |
989 v_SCALER_FRAME_VST(dst_frame_vst));
990 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
991 v_SCALER_HS_END(dsp_hs_end) |
992 v_SCALER_HTOTAL(dsp_htotal));
993 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
994 v_SCALER_HAEP(dsp_hact_end) |
995 v_SCALER_HASP(dsp_hact_st));
996 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
997 v_SCALER_VS_END(dsp_vs_end) |
998 v_SCALER_VTOTAL(dsp_vtotal));
999 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
1000 v_SCALER_VAEP(dsp_vact_end) |
1001 v_SCALER_VASP(dsp_vact_st));
1002 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
1003 v_SCALER_HBOR_END(dsp_hbor_end) |
1004 v_SCALER_HBOR_ST(dsp_hbor_st));
1005 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
1006 v_SCALER_VBOR_END(dsp_vbor_end) |
1007 v_SCALER_VBOR_ST(dsp_vbor_st));
1008 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1009 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
1010 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
1011 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1012 m_SCALER_EN | m_SCALER_OUT_ZERO |
1014 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) |
1015 v_SCALER_OUT_EN(1));
1017 lcdc_cfg_done(lcdc_dev);
1018 spin_unlock(&lcdc_dev->reg_lock);
1023 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
1024 struct lcdc_device *lcdc_dev)
1026 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1027 if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
1028 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1029 m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1030 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1032 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1033 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1036 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1038 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1039 if (dev_drv->output_color == COLOR_RGB) /* bypass */
1040 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1041 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1042 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1044 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1046 m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1048 v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1053 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1056 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1057 struct lcdc_device, driver);
1058 struct rk_screen *screen = dev_drv->cur_screen;
1059 u16 right_margin = screen->mode.right_margin;
1060 u16 left_margin = screen->mode.left_margin;
1061 u16 lower_margin = screen->mode.lower_margin;
1062 u16 upper_margin = screen->mode.upper_margin;
1063 u16 x_res = screen->mode.xres;
1064 u16 y_res = screen->mode.yres;
1067 spin_lock(&lcdc_dev->reg_lock);
1068 if (likely(lcdc_dev->clk_on)) {
1069 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1070 m_LCDC_STANDBY, v_LCDC_STANDBY(1));
1071 lcdc_cfg_done(lcdc_dev);
1073 /* Select output color domain */
1074 /*dev_drv->output_color = screen->color_mode;
1075 if (lcdc_dev->soc_type == VOP_RK312X) {
1076 if (dev_drv->output_color == COLOR_YCBCR)
1077 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1079 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1081 dev_drv->output_color = COLOR_RGB;
1082 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1084 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1085 /*something wrong at yuv domain*/
1087 switch (screen->type) {
1089 if (lcdc_dev->soc_type == VOP_RK312X) {
1090 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1091 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1092 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1096 if (lcdc_dev->soc_type == VOP_RK312X) {
1097 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1098 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1099 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1103 if (lcdc_dev->soc_type == VOP_RK312X) {
1104 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1105 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1106 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1110 mask = m_HDMI_DCLK_EN;
1111 val = v_HDMI_DCLK_EN(1);
1112 if (screen->pixelrepeat) {
1113 mask |= m_CORE_CLK_DIV_EN;
1114 val |= v_CORE_CLK_DIV_EN(1);
1116 mask |= m_CORE_CLK_DIV_EN;
1117 val |= v_CORE_CLK_DIV_EN(0);
1119 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1120 if (lcdc_dev->soc_type == VOP_RK312X) {
1121 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1123 v_SW_UV_OFFSET_EN(0));
1124 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1126 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1127 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1128 v_HDMI_DEN_POL(screen->pin_den);
1129 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1131 mask = (1 << 4) | (1 << 5) | (1 << 6);
1132 val = (screen->pin_hsync << 4) |
1133 (screen->pin_vsync << 5) |
1134 (screen->pin_den << 6);
1135 grf_writel(RK3036_GRF_SOC_CON2,
1136 (mask << 16) | val);
1138 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1141 case SCREEN_TVOUT_TEST:
1142 mask = m_TVE_DAC_DCLK_EN;
1143 val = v_TVE_DAC_DCLK_EN(1);
1144 if (screen->pixelrepeat) {
1145 mask |= m_CORE_CLK_DIV_EN;
1146 val |= v_CORE_CLK_DIV_EN(1);
1148 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1149 if (x_res == 720 && y_res == 576)
1150 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1151 v_TVE_MODE(TV_PAL));
1152 else if (x_res == 720 && y_res == 480)
1153 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1154 v_TVE_MODE(TV_NTSC));
1156 dev_err(lcdc_dev->dev,
1157 "unsupported video timing!\n");
1160 if (lcdc_dev->soc_type == VOP_RK312X) {
1161 if (screen->type == SCREEN_TVOUT_TEST)
1162 /*for TVE index test,vop must ovarlay at yuv domain*/
1163 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1164 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1166 v_SW_UV_OFFSET_EN(1));
1168 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1172 dev_err(lcdc_dev->dev, "un supported interface!\n");
1175 if (lcdc_dev->soc_type == VOP_RK312X) {
1176 switch (screen->face) {
1179 mask = m_DITHER_DOWN_EN |
1180 m_DITHER_DOWN_MODE |
1182 val = v_DITHER_DOWN_EN(1) |
1183 v_DITHER_DOWN_MODE(0) |
1184 v_DITHER_DOWN_SEL(1);
1185 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1189 mask = m_DITHER_DOWN_EN |
1190 m_DITHER_DOWN_MODE |
1192 val = v_DITHER_DOWN_EN(1) |
1193 v_DITHER_DOWN_MODE(1) |
1194 v_DITHER_DOWN_SEL(1);
1195 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1199 mask = m_DITHER_DOWN_EN |
1200 m_DITHER_DOWN_MODE |
1202 val = v_DITHER_DOWN_EN(1) |
1203 v_DITHER_DOWN_MODE(0) |
1204 v_DITHER_DOWN_SEL(1);
1205 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1209 mask = m_DITHER_DOWN_EN |
1210 m_DITHER_DOWN_MODE |
1212 val = v_DITHER_DOWN_EN(1) |
1213 v_DITHER_DOWN_MODE(1) |
1214 v_DITHER_DOWN_SEL(1);
1215 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1219 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1220 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1221 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1224 dev_err(lcdc_dev->dev, "un supported interface!\n");
1227 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1228 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1231 mask = m_HSYNC_POL | m_VSYNC_POL |
1232 m_DEN_POL | m_DCLK_POL;
1233 val = v_HSYNC_POL(screen->pin_hsync) |
1234 v_VSYNC_POL(screen->pin_vsync) |
1235 v_DEN_POL(screen->pin_den) |
1236 v_DCLK_POL(screen->pin_dclk);
1238 if (screen->type != SCREEN_HDMI) {
1239 mask |= m_DSP_OUT_FORMAT;
1240 val |= v_DSP_OUT_FORMAT(face);
1243 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1245 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1246 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1247 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1249 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1250 v_DSP_RB_SWAP(screen->swap_rb) |
1251 v_DSP_RG_SWAP(screen->swap_rg) |
1252 v_DSP_DELTA_SWAP(screen->swap_delta) |
1253 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1254 v_BLANK_EN(0) | v_BLACK_EN(0);
1255 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1258 val = v_HSYNC(screen->mode.hsync_len) |
1259 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1261 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1262 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1263 v_HASP(screen->mode.hsync_len + left_margin);
1264 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1266 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1267 /* First Field Timing */
1268 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1269 v_VSYNC(screen->mode.vsync_len) |
1270 v_VERPRD(2 * (screen->mode.vsync_len +
1272 lower_margin) + y_res + 1));
1273 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1274 v_VAEP(screen->mode.vsync_len +
1275 upper_margin + y_res / 2) |
1276 v_VASP(screen->mode.vsync_len +
1278 /* Second Field Timing */
1279 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1280 v_VSYNC_ST_F1(screen->mode.vsync_len +
1281 upper_margin + y_res / 2 +
1283 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1284 upper_margin + y_res / 2 +
1286 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1287 v_VAEP(2 * (screen->mode.vsync_len +
1289 y_res + lower_margin + 1) |
1290 v_VASP(2 * (screen->mode.vsync_len +
1292 y_res / 2 + lower_margin + 1));
1294 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1295 m_INTERLACE_DSP_EN |
1296 m_WIN0_YRGB_DEFLICK_EN |
1297 m_WIN0_CBR_DEFLICK_EN |
1298 m_INTERLACE_FIELD_POL |
1299 m_WIN0_INTERLACE_EN |
1300 m_WIN1_INTERLACE_EN,
1301 v_INTERLACE_DSP_EN(1) |
1302 v_WIN0_YRGB_DEFLICK_EN(1) |
1303 v_WIN0_CBR_DEFLICK_EN(1) |
1304 v_INTERLACE_FIELD_POL(0) |
1305 v_WIN0_INTERLACE_EN(1) |
1306 v_WIN1_INTERLACE_EN(1));
1307 mask = m_LF_INT_NUM;
1308 val = v_LF_INT_NUM(screen->mode.vsync_len +
1309 screen->mode.upper_margin +
1310 screen->mode.yres/2);
1311 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1313 val = v_VSYNC(screen->mode.vsync_len) |
1314 v_VERPRD(screen->mode.vsync_len + upper_margin +
1315 y_res + lower_margin);
1316 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1318 val = v_VAEP(screen->mode.vsync_len +
1319 upper_margin + y_res) |
1320 v_VASP(screen->mode.vsync_len + upper_margin);
1321 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1323 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1324 m_INTERLACE_DSP_EN |
1325 m_WIN0_YRGB_DEFLICK_EN |
1326 m_WIN0_CBR_DEFLICK_EN |
1327 m_INTERLACE_FIELD_POL |
1328 m_WIN0_INTERLACE_EN |
1329 m_WIN1_INTERLACE_EN,
1330 v_INTERLACE_DSP_EN(0) |
1331 v_WIN0_YRGB_DEFLICK_EN(0) |
1332 v_WIN0_CBR_DEFLICK_EN(0) |
1333 v_INTERLACE_FIELD_POL(0) |
1334 v_WIN0_INTERLACE_EN(0) |
1335 v_WIN1_INTERLACE_EN(0));
1336 mask = m_LF_INT_NUM;
1337 val = v_LF_INT_NUM(screen->mode.vsync_len +
1338 screen->mode.upper_margin +
1340 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1343 spin_unlock(&lcdc_dev->reg_lock);
1344 rk312x_lcdc_set_dclk(dev_drv, 1);
1345 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY, v_LCDC_STANDBY(0));
1346 lcdc_cfg_done(lcdc_dev);
1347 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1348 dev_drv->trsm_ops->enable();
1355 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1358 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1359 struct lcdc_device, driver);
1361 /* enable clk,when first layer open */
1362 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1363 rockchip_set_system_status(SYS_STATUS_LCDC0);
1364 rk312x_lcdc_pre_init(dev_drv);
1365 rk312x_lcdc_clk_enable(lcdc_dev);
1366 #if defined(CONFIG_ROCKCHIP_IOMMU)
1367 if (dev_drv->iommu_enabled) {
1368 if (!dev_drv->mmu_dev) {
1370 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1371 if (dev_drv->mmu_dev) {
1372 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1375 dev_err(dev_drv->dev,
1376 "failed to get rockchip iommu device\n");
1380 /*if (dev_drv->mmu_dev)
1381 rockchip_iovmm_activate(dev_drv->dev);*/
1384 rk312x_lcdc_reg_restore(lcdc_dev);
1385 /*if (dev_drv->iommu_enabled)
1386 rk312x_lcdc_mmu_en(dev_drv);*/
1387 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1388 rk312x_lcdc_set_dclk(dev_drv, 0);
1389 rk312x_lcdc_enable_irq(dev_drv);
1391 rk312x_load_screen(dev_drv, 1);
1394 /* set screen lut */
1395 if (dev_drv->cur_screen->dsp_lut)
1396 rk312x_lcdc_set_lut(dev_drv);
1399 if (win_id < ARRAY_SIZE(lcdc_win))
1400 lcdc_layer_enable(lcdc_dev, win_id, open);
1402 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1404 /* when all layer closed,disable clk */
1405 /* if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1406 rk312x_lcdc_disable_irq(lcdc_dev);
1407 rk312x_lcdc_reg_update(dev_drv);
1408 #if defined(CONFIG_ROCKCHIP_IOMMU)
1409 if (dev_drv->iommu_enabled) {
1410 if (dev_drv->mmu_dev)
1411 rockchip_iovmm_deactivate(dev_drv->dev);
1414 rk312x_lcdc_clk_disable(lcdc_dev);
1415 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1420 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1422 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1423 struct lcdc_device, driver);
1424 struct rk_screen *screen = dev_drv->cur_screen;
1425 struct rk_lcdc_win *win = NULL;
1426 char fmt[9] = "NULL";
1429 dev_err(dev_drv->dev, "screen is null!\n");
1434 win = dev_drv->win[0];
1435 } else if (win_id == 1) {
1436 win = dev_drv->win[1];
1437 } else if (win_id == 2) {
1438 win = dev_drv->win[2];
1440 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1444 spin_lock(&lcdc_dev->reg_lock);
1445 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1446 screen->mode.hsync_len;
1447 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1448 win->area[0].ysize /= 2;
1449 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1450 screen->mode.upper_margin +
1451 screen->mode.vsync_len;
1453 win->area[0].dsp_sty = win->area[0].ypos +
1454 screen->mode.upper_margin +
1455 screen->mode.vsync_len;
1457 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1458 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1460 switch (win->format) {
1462 win->fmt_cfg = VOP_FORMAT_ARGB888;
1466 win->fmt_cfg = VOP_FORMAT_ARGB888;
1470 win->fmt_cfg = VOP_FORMAT_ARGB888;
1474 win->fmt_cfg = VOP_FORMAT_RGB888;
1478 win->fmt_cfg = VOP_FORMAT_RGB565;
1483 win->fmt_cfg = VOP_FORMAT_YCBCR444;
1485 CalScale(win->area[0].xact, win->area[0].xsize);
1487 CalScale(win->area[0].yact, win->area[0].ysize);
1490 dev_err(lcdc_dev->driver.dev,
1491 "%s:un supported format!\n", __func__);
1496 win->fmt_cfg = VOP_FORMAT_YCBCR422;
1497 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1498 win->area[0].xsize);
1500 CalScale(win->area[0].yact, win->area[0].ysize);
1503 dev_err(lcdc_dev->driver.dev,
1504 "%s:un supported format!\n", __func__);
1509 win->fmt_cfg = VOP_FORMAT_YCBCR420;
1511 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1513 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1516 dev_err(lcdc_dev->driver.dev,
1517 "%s:un supported format!\n", __func__);
1521 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1525 spin_unlock(&lcdc_dev->reg_lock);
1528 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1529 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1530 get_format_string(win->format, fmt), win->area[0].xact,
1531 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1532 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1537 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1539 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1540 struct lcdc_device, driver);
1541 struct rk_lcdc_win *win = NULL;
1542 struct rk_screen *screen = dev_drv->cur_screen;
1545 dev_err(dev_drv->dev, "screen is null!\n");
1550 win = dev_drv->win[0];
1551 } else if (win_id == 1) {
1552 win = dev_drv->win[1];
1553 } else if (win_id == 2) {
1554 win = dev_drv->win[2];
1556 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1560 spin_lock(&lcdc_dev->reg_lock);
1561 if (likely(lcdc_dev->clk_on)) {
1562 win->area[0].y_addr =
1563 win->area[0].smem_start + win->area[0].y_offset;
1564 win->area[0].uv_addr =
1565 win->area[0].cbr_start + win->area[0].c_offset;
1566 if (win->area[0].y_addr)
1567 lcdc_layer_update_regs(lcdc_dev, win);
1568 /* lcdc_cfg_done(lcdc_dev); */
1570 spin_unlock(&lcdc_dev->reg_lock);
1572 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1573 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1574 win->area[0].y_offset);
1575 /* this is the first frame of the system,enable frame start interrupt */
1576 if ((dev_drv->first_frame)) {
1577 dev_drv->first_frame = 0;
1578 rk312x_lcdc_enable_irq(dev_drv);
1584 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1585 unsigned long arg, int win_id)
1587 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1588 struct lcdc_device, driver);
1590 void __user *argp = (void __user *)arg;
1591 struct color_key_cfg clr_key_cfg;
1594 case RK_FBIOGET_PANEL_SIZE:
1595 panel_size[0] = lcdc_dev->screen->mode.xres;
1596 panel_size[1] = lcdc_dev->screen->mode.yres;
1597 if (copy_to_user(argp, panel_size, 8))
1600 case RK_FBIOPUT_COLOR_KEY_CFG:
1601 if (copy_from_user(&clr_key_cfg, argp,
1602 sizeof(struct color_key_cfg)))
1604 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1605 clr_key_cfg.win0_color_key_cfg);
1606 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1607 clr_key_cfg.win1_color_key_cfg);
1616 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1621 mutex_lock(&dev_drv->fb_win_id_mutex);
1622 if (!strcmp(id, "fb0"))
1623 win_id = dev_drv->fb0_win_id;
1624 else if (!strcmp(id, "fb1"))
1625 win_id = dev_drv->fb1_win_id;
1626 else if (!strcmp(id, "fb2"))
1627 win_id = dev_drv->fb2_win_id;
1628 mutex_unlock(&dev_drv->fb_win_id_mutex);
1633 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1638 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1641 struct lcdc_device *lcdc_dev =
1642 container_of(dev_drv, struct lcdc_device, driver);
1645 spin_lock(&lcdc_dev->reg_lock);
1646 if (lcdc_dev->clk_on) {
1648 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1652 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1657 spin_unlock(&lcdc_dev->reg_lock);
1662 static int rk312x_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1664 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1665 struct lcdc_device, driver);
1666 struct device_node *backlight;
1668 if (lcdc_dev->backlight)
1671 backlight = of_parse_phandle(lcdc_dev->dev->of_node,
1674 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
1675 if (!lcdc_dev->backlight)
1676 dev_info(lcdc_dev->dev, "No find backlight device\n");
1678 dev_info(lcdc_dev->dev, "No find backlight device node\n");
1684 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1686 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1687 struct lcdc_device, driver);
1688 if (dev_drv->suspend_flag)
1691 /* close the backlight */
1692 rk312x_lcdc_get_backlight_device(dev_drv);
1693 if (lcdc_dev->backlight) {
1694 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
1695 backlight_update_status(lcdc_dev->backlight);
1698 dev_drv->suspend_flag = 1;
1699 flush_kthread_worker(&dev_drv->update_regs_worker);
1701 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1702 dev_drv->trsm_ops->disable();
1703 spin_lock(&lcdc_dev->reg_lock);
1704 if (likely(lcdc_dev->clk_on)) {
1705 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1706 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1707 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1708 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1709 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1711 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1713 lcdc_cfg_done(lcdc_dev);
1715 if (dev_drv->iommu_enabled) {
1716 if (dev_drv->mmu_dev)
1717 rockchip_iovmm_deactivate(dev_drv->dev);
1720 spin_unlock(&lcdc_dev->reg_lock);
1722 spin_unlock(&lcdc_dev->reg_lock);
1725 rk312x_lcdc_clk_disable(lcdc_dev);
1726 rk_disp_pwr_disable(dev_drv);
1730 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1732 struct lcdc_device *lcdc_dev =
1733 container_of(dev_drv, struct lcdc_device, driver);
1735 if (!dev_drv->suspend_flag)
1737 rk_disp_pwr_enable(dev_drv);
1738 dev_drv->suspend_flag = 0;
1740 if (lcdc_dev->atv_layer_cnt) {
1741 rk312x_lcdc_clk_enable(lcdc_dev);
1742 rk312x_lcdc_reg_restore(lcdc_dev);
1744 /* config for the FRC mode of dither down */
1745 if (dev_drv->cur_screen &&
1746 dev_drv->cur_screen->face != OUT_P888) {
1747 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1748 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1749 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1750 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1751 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1752 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1755 /* set screen lut */
1756 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1757 rk312x_lcdc_set_lut(dev_drv);
1759 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1761 spin_lock(&lcdc_dev->reg_lock);
1763 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1765 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1767 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1768 lcdc_cfg_done(lcdc_dev);
1770 if (dev_drv->iommu_enabled) {
1771 if (dev_drv->mmu_dev)
1772 rockchip_iovmm_activate(dev_drv->dev);
1775 spin_unlock(&lcdc_dev->reg_lock);
1778 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1779 dev_drv->trsm_ops->enable();
1784 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1785 int win_id, int blank_mode)
1787 switch (blank_mode) {
1788 case FB_BLANK_UNBLANK:
1789 rk312x_lcdc_early_resume(dev_drv);
1791 case FB_BLANK_NORMAL:
1792 rk312x_lcdc_early_suspend(dev_drv);
1795 rk312x_lcdc_early_suspend(dev_drv);
1799 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1804 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1806 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1807 struct lcdc_device, driver);
1809 unsigned int mask, val;
1810 struct rk_lcdc_win *win = NULL;
1812 spin_lock(&lcdc_dev->reg_lock);
1813 if (lcdc_dev->clk_on) {
1814 #if defined(CONFIG_ROCKCHIP_IOMMU)
1815 if (dev_drv->iommu_enabled) {
1816 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
1817 lcdc_dev->iommu_status = 1;
1818 /*if ((support_uboot_display() &&
1819 (lcdc_dev->prop == PRMRY))) {
1820 lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
1823 lcdc_msk_reg(lcdc_dev,
1824 WIN0_CTRL0, mask,val);
1826 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1827 v_LCDC_STANDBY(1));*/
1828 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1829 m_WIN0_EN, v_WIN0_EN(0));
1830 lcdc_cfg_done(lcdc_dev);
1832 rockchip_iovmm_activate(dev_drv->dev);
1833 rk312x_lcdc_mmu_en(dev_drv);
1834 lcdc_msk_reg(lcdc_dev,
1835 SYS_CTRL, m_WIN0_EN, v_WIN0_EN(1));
1839 for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
1840 win = dev_drv->win[i];
1841 if ((win->state == 0) && (win->last_state == 1)) {
1846 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1852 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1858 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1865 win->last_state = win->state;
1867 lcdc_cfg_done(lcdc_dev);
1869 spin_unlock(&lcdc_dev->reg_lock);
1875 sin_hue = sin(a)*256 +0x100;
1876 cos_hue = cos(a)*256;
1878 sin_hue = sin(a)*256;
1879 cos_hue = cos(a)*256;
1881 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1884 struct lcdc_device *lcdc_dev =
1885 container_of(dev_drv, struct lcdc_device, driver);
1888 spin_lock(&lcdc_dev->reg_lock);
1889 if (lcdc_dev->clk_on) {
1890 val = lcdc_readl(lcdc_dev, BCSH_H);
1893 val &= m_BCSH_SIN_HUE;
1896 val &= m_BCSH_COS_HUE;
1903 spin_unlock(&lcdc_dev->reg_lock);
1908 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
1911 struct lcdc_device *lcdc_dev =
1912 container_of(dev_drv, struct lcdc_device, driver);
1915 spin_lock(&lcdc_dev->reg_lock);
1916 if (lcdc_dev->clk_on) {
1917 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1918 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1919 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1920 lcdc_cfg_done(lcdc_dev);
1922 spin_unlock(&lcdc_dev->reg_lock);
1927 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1928 bcsh_bcs_mode mode, int value)
1930 struct lcdc_device *lcdc_dev =
1931 container_of(dev_drv, struct lcdc_device, driver);
1934 spin_lock(&lcdc_dev->reg_lock);
1935 if (lcdc_dev->clk_on) {
1938 /* from 0 to 255,typical is 128 */
1941 else if (value >= 0x80)
1942 value = value - 0x80;
1943 mask = m_BCSH_BRIGHTNESS;
1944 val = v_BCSH_BRIGHTNESS(value);
1947 /* from 0 to 510,typical is 256 */
1948 mask = m_BCSH_CONTRAST;
1949 val = v_BCSH_CONTRAST(value);
1952 /* from 0 to 1015,typical is 256 */
1953 mask = m_BCSH_SAT_CON;
1954 val = v_BCSH_SAT_CON(value);
1959 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
1960 lcdc_cfg_done(lcdc_dev);
1962 spin_unlock(&lcdc_dev->reg_lock);
1966 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1969 struct lcdc_device *lcdc_dev =
1970 container_of(dev_drv, struct lcdc_device, driver);
1973 spin_lock(&lcdc_dev->reg_lock);
1974 if (lcdc_dev->clk_on) {
1975 val = lcdc_readl(lcdc_dev, BCSH_BCS);
1978 val &= m_BCSH_BRIGHTNESS;
1985 val &= m_BCSH_CONTRAST;
1989 val &= m_BCSH_SAT_CON;
1996 spin_unlock(&lcdc_dev->reg_lock);
2000 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2002 struct lcdc_device *lcdc_dev =
2003 container_of(dev_drv, struct lcdc_device, driver);
2005 if(dev_drv->bcsh_init_status && open) {
2006 dev_drv->bcsh_init_status = 0;
2009 spin_lock(&lcdc_dev->reg_lock);
2010 if (lcdc_dev->clk_on) {
2011 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
2013 lcdc_msk_reg(lcdc_dev,
2014 BCSH_CTRL, m_BCSH_EN | m_BCSH_OUT_MODE,
2015 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
2016 lcdc_writel(lcdc_dev, BCSH_BCS,
2017 v_BCSH_BRIGHTNESS(0x00) |
2018 v_BCSH_CONTRAST(0x80) |
2019 v_BCSH_SAT_CON(0x80));
2020 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
2024 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
2026 lcdc_cfg_done(lcdc_dev);
2029 spin_unlock(&lcdc_dev->reg_lock);
2033 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2035 struct rk_lcdc_win_area area;
2036 int fb2_win_id, fb1_win_id, fb0_win_id;
2038 mutex_lock(&dev_drv->fb_win_id_mutex);
2039 if (order == FB_DEFAULT_ORDER)
2040 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
2042 fb2_win_id = order / 100;
2043 fb1_win_id = (order / 10) % 10;
2044 fb0_win_id = order % 10;
2046 if (fb0_win_id != dev_drv->fb0_win_id) {
2047 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
2048 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
2049 dev_drv->win[fb0_win_id]->area[0];
2050 dev_drv->win[fb0_win_id]->area[0] = area;
2051 dev_drv->fb0_win_id = fb0_win_id;
2053 dev_drv->fb1_win_id = fb1_win_id;
2054 dev_drv->fb2_win_id = fb2_win_id;
2056 mutex_unlock(&dev_drv->fb_win_id_mutex);
2061 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2064 struct lcdc_device *lcdc_dev =
2065 container_of(dev_drv, struct lcdc_device, driver);
2066 struct rk_screen *screen = dev_drv->cur_screen;
2071 u32 x_total, y_total;
2074 ft = div_u64(1000000000000llu, fps);
2076 screen->mode.upper_margin + screen->mode.lower_margin +
2077 screen->mode.yres + screen->mode.vsync_len;
2079 screen->mode.left_margin + screen->mode.right_margin +
2080 screen->mode.xres + screen->mode.hsync_len;
2081 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2082 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2083 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2086 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2087 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2088 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2089 screen->ft = 1000 / fps; /*one frame time in ms */
2092 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2093 clk_get_rate(lcdc_dev->dclk), fps);
2098 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
2101 struct lcdc_device *lcdc_dev =
2102 container_of(dev_drv,
2103 struct lcdc_device, driver);
2105 enable_irq(lcdc_dev->irq);
2107 disable_irq(lcdc_dev->irq);
2111 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2113 struct lcdc_device *lcdc_dev =
2114 container_of(dev_drv, struct lcdc_device, driver);
2118 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
2119 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
2120 if (int_reg & m_LF_INT_STA) {
2121 dev_drv->frame_time.last_framedone_t =
2122 dev_drv->frame_time.framedone_t;
2123 dev_drv->frame_time.framedone_t = cpu_clock(0);
2124 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
2126 ret = RK_LF_STATUS_FC;
2128 ret = RK_LF_STATUS_FR;
2131 ret = RK_LF_STATUS_NC;
2137 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2138 unsigned int *dsp_addr)
2140 struct lcdc_device *lcdc_dev =
2141 container_of(dev_drv, struct lcdc_device, driver);
2143 if (lcdc_dev->clk_on) {
2144 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2145 if (lcdc_dev->soc_type == VOP_RK3036)
2146 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
2147 else if (lcdc_dev->soc_type == VOP_RK312X)
2148 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2153 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2154 char *buf, int win_id)
2156 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
2158 char format_w0[9] = "NULL";
2159 char format_w1[9] = "NULL";
2160 char status_w0[9] = "NULL";
2161 char status_w1[9] = "NULL";
2162 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
2163 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
2164 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
2165 u16 x_factor, y_factor, x_scale, y_scale;
2167 u32 win1_dsp_yaddr = 0;
2169 spin_lock(&lcdc_dev->reg_lock);
2170 if (lcdc_dev->clk_on) {
2172 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2173 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2174 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2177 if (fmt_id & m_WIN0_EN)
2178 strcpy(status_w0, "enabled");
2180 strcpy(status_w0, "disabled");
2182 if ((fmt_id & m_WIN1_EN) >> 1)
2183 strcpy(status_w1, "enabled");
2185 strcpy(status_w1, "disabled");
2188 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2191 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2192 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2195 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2196 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2197 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2199 if (lcdc_dev->soc_type == VOP_RK3036) {
2200 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2201 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2202 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2203 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2204 /* rk312x unsupport win1 scaler,so have no act info */
2210 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2211 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2212 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2214 if (lcdc_dev->soc_type == VOP_RK3036)
2215 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2216 else if (lcdc_dev->soc_type == VOP_RK312X)
2217 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2218 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2219 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2222 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2223 x_st_w0 = dsp_st & m_DSP_STX;
2224 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2226 if (lcdc_dev->soc_type == VOP_RK3036)
2227 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2228 else if (lcdc_dev->soc_type == VOP_RK312X)
2229 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2231 x_st_w1 = dsp_st & m_DSP_STX;
2232 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2235 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2236 x_factor = factor & m_X_SCL_FACTOR;
2237 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2238 x_scale = 4096 * 100 / x_factor;
2239 y_scale = 4096 * 100 / y_factor;
2242 if (lcdc_dev->soc_type == VOP_RK3036)
2243 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2244 else if (lcdc_dev->soc_type == VOP_RK312X)
2245 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2247 spin_unlock(&lcdc_dev->reg_lock);
2250 spin_unlock(&lcdc_dev->reg_lock);
2251 return snprintf(buf, PAGE_SIZE,
2263 "YRGB buffer addr:0x%08x\n"
2264 "CBR buffer addr:0x%08x\n\n"
2274 "YRGB buffer addr:0x%08x\n"
2289 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2290 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2301 ovl ? "win0 on the top of win1\n" :
2302 "win1 on the top of win0\n");
2305 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2307 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2310 int *cbase = (int *)lcdc_dev->regs;
2311 int *regsbak = (int *)lcdc_dev->regsbak;
2314 pr_info("back up reg:\n");
2315 for (i = 0; i <= (0xDC >> 4); i++) {
2316 for (j = 0; j < 4; j++)
2317 pr_info("%08x ", *(regsbak + i * 4 + j));
2321 pr_info("lcdc reg:\n");
2322 for (i = 0; i <= (0xDC >> 4); i++) {
2323 for (j = 0; j < 4; j++)
2324 pr_info("%08x ", readl_relaxed(cbase + i * 4 + j));
2330 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2332 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2333 struct lcdc_device, driver);
2334 if (lcdc_dev->soc_type == VOP_RK312X) {
2335 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2336 v_DIRECT_PATH_EN(open));
2337 lcdc_cfg_done(lcdc_dev);
2342 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2344 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2345 struct lcdc_device, driver);
2347 if (lcdc_dev->soc_type == VOP_RK312X) {
2348 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2349 v_DIRECT_PATH_LAYER(win_id));
2350 lcdc_cfg_done(lcdc_dev);
2355 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2357 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2358 struct lcdc_device, driver);
2361 if (lcdc_dev->soc_type == VOP_RK312X)
2362 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2367 static int rk312x_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2369 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2370 struct lcdc_device, driver);
2372 rk312x_lcdc_get_backlight_device(dev_drv);
2375 /* close the backlight */
2376 if (lcdc_dev->backlight) {
2377 lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
2378 backlight_update_status(lcdc_dev->backlight);
2381 spin_lock(&lcdc_dev->reg_lock);
2382 if (likely(lcdc_dev->clk_on)) {
2383 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2385 lcdc_cfg_done(lcdc_dev);
2387 spin_unlock(&lcdc_dev->reg_lock);
2389 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2390 dev_drv->trsm_ops->disable();
2392 spin_lock(&lcdc_dev->reg_lock);
2393 if (likely(lcdc_dev->clk_on)) {
2394 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2396 lcdc_cfg_done(lcdc_dev);
2398 spin_unlock(&lcdc_dev->reg_lock);
2399 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2400 dev_drv->trsm_ops->enable();
2402 /* open the backlight */
2403 if (lcdc_dev->backlight) {
2404 lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
2405 backlight_update_status(lcdc_dev->backlight);
2413 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2414 .open = rk312x_lcdc_open,
2415 .load_screen = rk312x_load_screen,
2416 .set_par = rk312x_lcdc_set_par,
2417 .pan_display = rk312x_lcdc_pan_display,
2418 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2419 .blank = rk312x_lcdc_blank,
2420 .ioctl = rk312x_lcdc_ioctl,
2421 .get_win_state = rk312x_lcdc_get_win_state,
2422 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2423 .get_disp_info = rk312x_lcdc_get_disp_info,
2424 .fps_mgr = rk312x_lcdc_fps_mgr,
2425 .fb_get_win_id = rk312x_lcdc_get_win_id,
2426 .fb_win_remap = rk312x_fb_win_remap,
2427 .poll_vblank = rk312x_lcdc_poll_vblank,
2428 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2429 .cfg_done = rk312x_lcdc_cfg_done,
2430 .dump_reg = rk312x_lcdc_reg_dump,
2431 .dpi_open = rk312x_lcdc_dpi_open,
2432 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2433 .dpi_status = rk312x_lcdc_dpi_status,
2434 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2435 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2436 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2437 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2438 .open_bcsh = rk312x_lcdc_open_bcsh,
2439 .set_screen_scaler = rk312x_lcdc_set_scaler,
2440 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2441 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2442 .dsp_black = rk312x_lcdc_dsp_black,
2445 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2446 .soc_type = VOP_RK3036,
2449 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2450 .soc_type = VOP_RK312X,
2453 #if defined(CONFIG_OF)
2454 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2457 .compatible = "rockchip,rk3036-lcdc",
2458 .data = (void *)&rk3036_lcdc_drvdata,
2462 .compatible = "rockchip,rk312x-lcdc",
2463 .data = (void *)&rk312x_lcdc_drvdata,
2468 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2470 struct device_node *np = lcdc_dev->dev->of_node;
2471 const struct of_device_id *match;
2472 const struct rk_lcdc_drvdata *lcdc_drvdata;
2475 #if defined(CONFIG_ROCKCHIP_IOMMU)
2476 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2477 lcdc_dev->driver.iommu_enabled = 0;
2479 lcdc_dev->driver.iommu_enabled = val;
2481 lcdc_dev->driver.iommu_enabled = 0;
2484 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2485 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2487 lcdc_dev->driver.fb_win_map = val;
2489 match = of_match_node(rk312x_lcdc_dt_ids, np);
2491 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2492 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2494 return PTR_ERR(match);
2500 static int rk312x_lcdc_probe(struct platform_device *pdev)
2502 struct lcdc_device *lcdc_dev = NULL;
2503 struct rk_lcdc_driver *dev_drv;
2504 struct device *dev = &pdev->dev;
2505 struct resource *res;
2508 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2510 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2513 platform_set_drvdata(pdev, lcdc_dev);
2514 lcdc_dev->dev = dev;
2515 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2516 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2520 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2521 lcdc_dev->reg_phy_base = res->start;
2522 lcdc_dev->len = resource_size(res);
2523 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2524 if (IS_ERR(lcdc_dev->regs)) {
2525 ret = PTR_ERR(lcdc_dev->regs);
2529 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2530 if (IS_ERR(lcdc_dev->regsbak)) {
2531 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2532 ret = PTR_ERR(lcdc_dev->regsbak);
2535 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2536 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2537 lcdc_dev->prop = PRMRY;
2538 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2539 dev_drv = &lcdc_dev->driver;
2541 dev_drv->prop = lcdc_dev->prop;
2542 dev_drv->id = lcdc_dev->id;
2543 dev_drv->ops = &lcdc_drv_ops;
2544 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2545 spin_lock_init(&lcdc_dev->reg_lock);
2547 lcdc_dev->irq = platform_get_irq(pdev, 0);
2548 if (lcdc_dev->irq < 0) {
2549 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2552 goto err_request_irq;
2555 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2556 IRQF_DISABLED | IRQF_SHARED,
2557 dev_name(dev), lcdc_dev);
2559 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2560 lcdc_dev->irq, ret);
2561 goto err_request_irq;
2564 if (dev_drv->iommu_enabled)
2565 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2567 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2569 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2570 goto err_register_fb;
2572 lcdc_dev->screen = dev_drv->screen0;
2574 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2575 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2580 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2583 devm_kfree(&pdev->dev, lcdc_dev);
2587 #if defined(CONFIG_PM)
2588 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2593 static int rk312x_lcdc_resume(struct platform_device *pdev)
2598 #define rk312x_lcdc_suspend NULL
2599 #define rk312x_lcdc_resume NULL
2602 static int rk312x_lcdc_remove(struct platform_device *pdev)
2607 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2609 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2611 rk312x_lcdc_deinit(lcdc_dev);
2612 rk312x_lcdc_clk_disable(lcdc_dev);
2613 rk_disp_pwr_disable(&lcdc_dev->driver);
2615 if (lcdc_dev->backlight)
2616 put_device(&lcdc_dev->backlight->dev);
2619 static struct platform_driver rk312x_lcdc_driver = {
2620 .probe = rk312x_lcdc_probe,
2621 .remove = rk312x_lcdc_remove,
2623 .name = "rk312x-lcdc",
2624 .owner = THIS_MODULE,
2625 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2627 .suspend = rk312x_lcdc_suspend,
2628 .resume = rk312x_lcdc_resume,
2629 .shutdown = rk312x_lcdc_shutdown,
2632 static int __init rk312x_lcdc_module_init(void)
2634 return platform_driver_register(&rk312x_lcdc_driver);
2637 static void __exit rk312x_lcdc_module_exit(void)
2639 platform_driver_unregister(&rk312x_lcdc_driver);
2642 fs_initcall(rk312x_lcdc_module_init);
2643 module_exit(rk312x_lcdc_module_exit);