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_backup(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]->area[0].format;
289 enum data_format win1_format = lcdc_dev->driver.win[1]->area[0].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 if (lcdc_dev->driver.overlay_mode == VOP_YUV_DOMAIN)
326 val = v_WIN0_ALPHA_MODE(1) |
327 v_ALPHA_MODE_SEL0(0) |
328 v_ALPHA_MODE_SEL1(0);
330 val = v_WIN1_ALPHA_MODE(1) |
331 v_ALPHA_MODE_SEL0(1) |
332 v_ALPHA_MODE_SEL1(0);
333 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
334 /*this vop bg layer not support yuv domain overlay,so bg val
335 have to set 0x800a80 equeal to 0x000000 at rgb domian,after
336 android start we recover to 0x00000*/
338 val = v_BG_COLOR(0x000000);
339 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
341 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
342 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
343 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
346 if (lcdc_dev->driver.win[2]->state == 1) {
347 mask = m_HWC_ALPAH_EN;
348 val = v_HWC_ALPAH_EN(1);
349 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
351 mask = m_HWC_ALPHA_MODE;
352 val = v_HWC_ALPHA_MODE(1);
353 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
355 mask = m_HWC_ALPAH_EN;
356 val = v_HWC_ALPAH_EN(0);
357 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
363 static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
364 struct rk_lcdc_win *win)
366 struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
367 struct rk_screen *screen = dev_drv->cur_screen;
369 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
370 switch (win->area[0].fmt_cfg) {
371 case VOP_FORMAT_ARGB888:
372 case VOP_FORMAT_RGB888:
373 case VOP_FORMAT_RGB565:
374 if ((screen->mode.xres < 1280) &&
375 (screen->mode.yres < 720)) {
376 win->csc_mode = VOP_R2Y_CSC_BT601;
378 win->csc_mode = VOP_R2Y_CSC_BT709;
385 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
386 v_WIN0_CSC_MODE(win->csc_mode));
387 } else if (win->id == 1) {
388 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
389 v_WIN1_CSC_MODE(win->csc_mode));
391 } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
392 switch (win->area[0].fmt_cfg) {
393 case VOP_FORMAT_YCBCR420:
395 win->csc_mode = VOP_Y2R_CSC_MPEG;
396 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
398 v_WIN0_CSC_MODE(win->csc_mode));
408 static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
409 struct rk_lcdc_win *win)
414 if (win->state == 1) {
415 if (lcdc_dev->soc_type == VOP_RK312X)
416 lcdc_layer_csc_mode(lcdc_dev, win);
419 mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
420 val = v_WIN0_EN(win->state) |
421 v_WIN0_FORMAT(win->area[0].fmt_cfg) |
422 v_WIN0_RB_SWAP(win->area[0].swap_rb);
423 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
424 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
425 v_X_SCL_FACTOR(win->scale_yrgb_x) |
426 v_Y_SCL_FACTOR(win->scale_yrgb_y));
427 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
428 v_X_SCL_FACTOR(win->scale_cbcr_x) |
429 v_Y_SCL_FACTOR(win->scale_cbcr_y));
431 lcdc_msk_reg(lcdc_dev, WIN0_VIR,
432 m_YRGB_VIR | m_CBBR_VIR,
433 v_YRGB_VIR(win->area[0].y_vir_stride) |
434 v_CBCR_VIR(win->area[0].uv_vir_stride));
435 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
436 v_ACT_WIDTH(win->area[0].xact) |
437 v_ACT_HEIGHT(win->area[0].yact));
438 lcdc_writel(lcdc_dev, WIN0_DSP_ST,
439 v_DSP_STX(win->area[0].dsp_stx) |
440 v_DSP_STY(win->area[0].dsp_sty));
441 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
442 v_DSP_WIDTH(win->area[0].xsize) |
443 v_DSP_HEIGHT(win->area[0].ysize));
445 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
446 win->area[0].y_addr);
447 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
448 win->area[0].uv_addr);
449 } else if (win->id == 1) {
450 mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
451 val = v_WIN1_EN(win->state) |
452 v_WIN1_FORMAT(win->area[0].fmt_cfg) |
453 v_WIN1_RB_SWAP(win->area[0].swap_rb);
454 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
455 /* rk312x unsupport win1 scale */
456 if (lcdc_dev->soc_type == VOP_RK3036) {
457 lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
458 v_X_SCL_FACTOR(win->scale_yrgb_x) |
459 v_Y_SCL_FACTOR(win->scale_yrgb_y));
460 lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
461 v_ACT_WIDTH(win->area[0].xact) |
462 v_ACT_HEIGHT(win->area[0].yact));
463 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
464 v_DSP_WIDTH(win->area[0].xsize) |
465 v_DSP_HEIGHT(win->area[0].ysize));
466 lcdc_writel(lcdc_dev, WIN1_DSP_ST,
467 v_DSP_STX(win->area[0].dsp_stx) |
468 v_DSP_STY(win->area[0].dsp_sty));
469 lcdc_writel(lcdc_dev,
470 WIN1_MST, win->area[0].y_addr);
472 lcdc_writel(lcdc_dev, WIN1_DSP_INFO_RK312X,
473 v_DSP_WIDTH(win->area[0].xsize) |
474 v_DSP_HEIGHT(win->area[0].ysize));
475 lcdc_writel(lcdc_dev, WIN1_DSP_ST_RK312X,
476 v_DSP_STX(win->area[0].dsp_stx) |
477 v_DSP_STY(win->area[0].dsp_sty));
479 lcdc_writel(lcdc_dev,
481 win->area[0].y_addr);
484 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
485 v_YRGB_VIR(win->area[0].y_vir_stride));
488 } else if (win->id == 2) {
489 mask = m_HWC_EN | m_HWC_LODAD_EN;
490 val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
491 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
492 if ((win->area[0].xsize == 32) &&
493 (win->area[0].ysize == 32))
495 else if ((win->area[0].xsize == 64) &&
496 (win->area[0].ysize == 64))
499 dev_err(lcdc_dev->dev, "unsupport hwc size:x=%d,y=%d\n",
500 win->area[0].xsize, win->area[0].ysize);
501 lcdc_writel(lcdc_dev, HWC_DSP_ST,
502 v_DSP_STX(win->area[0].dsp_stx) |
503 v_DSP_STY(win->area[0].dsp_sty));
505 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
508 win->area[0].y_addr = 0;
509 win->area[0].uv_addr = 0;
511 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
513 else if (win->id == 1)
514 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
516 else if (win->id == 2)
517 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
519 rk312x_lcdc_alpha_cfg(lcdc_dev);
522 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
525 spin_lock(&lcdc_dev->reg_lock);
526 if (likely(lcdc_dev->clk_on) &&
527 lcdc_dev->driver.win[win_id]->state != open) {
529 if (!lcdc_dev->atv_layer_cnt) {
530 dev_info(lcdc_dev->dev,
531 "wakeup from standby!\n");
532 lcdc_dev->standby = 0;
534 lcdc_dev->atv_layer_cnt |= (1 << win_id);
535 } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
536 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
538 lcdc_dev->driver.win[win_id]->state = open;
540 lcdc_layer_update_regs(lcdc_dev,
541 lcdc_dev->driver.win[win_id]);
542 lcdc_cfg_done(lcdc_dev);
544 /*if no layer used,disable lcdc */
545 if (!lcdc_dev->atv_layer_cnt) {
546 dev_info(lcdc_dev->dev,
547 "no layer is used,go to standby!\n");
548 lcdc_dev->standby = 1;
551 spin_unlock(&lcdc_dev->reg_lock);
554 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
556 struct lcdc_device *lcdc_dev =
557 container_of(dev_drv, struct lcdc_device, driver);
558 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
559 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
562 spin_lock(&lcdc_dev->reg_lock);
563 if (likely(lcdc_dev->clk_on)) {
564 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
565 v_LCDC_STANDBY(lcdc_dev->standby));
566 lcdc_layer_update_regs(lcdc_dev, win0);
567 lcdc_layer_update_regs(lcdc_dev, win1);
568 rk312x_lcdc_alpha_cfg(lcdc_dev);
569 lcdc_cfg_done(lcdc_dev);
572 spin_unlock(&lcdc_dev->reg_lock);
573 //if (dev_drv->wait_fs) {
575 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
576 init_completion(&dev_drv->frame_done);
577 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
578 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
580 (dev_drv->cur_screen->ft +
582 if (!timeout && (!dev_drv->frame_done.done)) {
583 dev_warn(lcdc_dev->dev,
584 "wait for new frame start time out!\n");
588 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
593 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
595 memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
598 static int rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
601 struct lcdc_device *lcdc_dev =
602 container_of(dev_drv, struct lcdc_device, driver);
604 /*spin_lock(&lcdc_dev->reg_lock);*/
605 if (likely(lcdc_dev->clk_on)) {
606 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
607 m_AXI_OUTSTANDING_MAX_NUM;
608 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
609 v_AXI_MAX_OUTSTANDING_EN(1);
610 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
612 /*spin_unlock(&lcdc_dev->reg_lock);*/
613 #if defined(CONFIG_ROCKCHIP_IOMMU)
614 if (dev_drv->iommu_enabled) {
615 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
616 lcdc_dev->iommu_status = 1;
617 rockchip_iovmm_activate(dev_drv->dev);
618 rk312x_lcdc_mmu_en(dev_drv);
625 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
626 int *hwc_lut, int mode)
632 struct lcdc_device *lcdc_dev =
633 container_of(dev_drv, struct lcdc_device, driver);
634 if (dev_drv->hwc_lut == NULL)
635 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
637 spin_lock(&lcdc_dev->reg_lock);
638 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
639 lcdc_cfg_done(lcdc_dev);
641 for (i = 0; i < 256; i++) {
643 dev_drv->hwc_lut[i] = hwc_lut[i];
644 v = dev_drv->hwc_lut[i];
645 c = lcdc_dev->hwc_lut_addr_base + i;
646 writel_relaxed(v, c);
648 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
649 lcdc_cfg_done(lcdc_dev);
650 spin_unlock(&lcdc_dev->reg_lock);
654 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
659 struct lcdc_device *lcdc_dev =
660 container_of(dev_drv, struct lcdc_device, driver);
662 spin_lock(&lcdc_dev->reg_lock);
663 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
664 lcdc_cfg_done(lcdc_dev);
666 for (i = 0; i < 256; i++) {
667 v = dev_drv->cur_screen->dsp_lut[i];
668 c = lcdc_dev->dsp_lut_addr_base + (i<<2);
669 writel_relaxed(v, c);
671 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
672 lcdc_cfg_done(lcdc_dev);
673 spin_unlock(&lcdc_dev->reg_lock);
677 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
680 #ifdef CONFIG_RK_FPGA
684 struct lcdc_device *lcdc_dev =
685 container_of(dev_drv, struct lcdc_device, driver);
686 struct rk_screen *screen = dev_drv->cur_screen;
689 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
691 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
693 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
694 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
696 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
697 screen->ft = 1000 / fps;
698 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
699 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
703 /********do basic init*********/
704 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
706 struct lcdc_device *lcdc_dev = container_of(dev_drv,
707 struct lcdc_device, driver);
708 if (lcdc_dev->pre_init)
711 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
712 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
713 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
714 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
715 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
716 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
718 if (/*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
719 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
720 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
724 rk_disp_pwr_enable(dev_drv);
725 rk312x_lcdc_clk_enable(lcdc_dev);
727 /* backup reg config at uboot */
728 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
730 /* config for the FRC mode of dither down */
731 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
732 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
733 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
734 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
735 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
736 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
738 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
739 lcdc_cfg_done(lcdc_dev);
740 /*if (dev_drv->iommu_enabled)
741 {// disable all wins to workaround iommu pagefault
742 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
743 v_WIN0_EN(0) | v_WIN1_EN(0));
744 lcdc_cfg_done(lcdc_dev);
745 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
747 if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
748 if (support_uboot_display())
749 dev_drv->bcsh_init_status = 1;
751 dev_drv->ops->open_bcsh(dev_drv, 1);
753 lcdc_dev->pre_init = true;
758 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
762 spin_lock(&lcdc_dev->reg_lock);
763 if (likely(lcdc_dev->clk_on)) {
764 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
765 m_LF_INT_CLEAR | m_LF_INT_EN |
766 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
767 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
768 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
769 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
770 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
771 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
772 lcdc_cfg_done(lcdc_dev);
773 spin_unlock(&lcdc_dev->reg_lock);
775 spin_unlock(&lcdc_dev->reg_lock);
780 static u32 calc_sclk_freq(struct rk_screen *src_screen,
781 struct rk_screen *dst_screen)
789 if (!src_screen || !dst_screen)
792 dsp_vtotal = dst_screen->mode.yres;
793 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
794 dst_screen->mode.xres + dst_screen->mode.right_margin;
795 dsp_in_vtotal = src_screen->mode.yres;
796 dsp_in_htotal = src_screen->mode.left_margin +
797 src_screen->mode.hsync_len +
798 src_screen->mode.xres + src_screen->mode.right_margin;
799 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
800 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
802 return (u32)sclk_freq;
805 #define SCLK_PLL_LIMIT 594000000
806 #define GPU_FREQ_MAX_LIMIT 297000000
807 #define GPU_FREQ_NEED 400000000
809 static u32 calc_sclk_pll_freq(u32 sclk_freq)
813 if (sclk_freq < (SCLK_PLL_LIMIT / 10)) {
814 return (sclk_freq * 10);
816 multi_num = GPU_FREQ_NEED / sclk_freq;
817 return (sclk_freq * multi_num);
821 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
822 struct rk_screen *dst, u32 sclk_freq)
827 u64 T_BP_in, T_BP_out, T_Delta, Tin;
828 u32 src_pixclock, dst_pixclock;
830 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
832 if (unlikely(!src) || unlikely(!dst))
835 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
836 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
837 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
838 dst->mode.xres + dst->mode.right_margin;
839 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
840 dst->mode.yres + dst->mode.lower_margin;
841 src_htotal = src->mode.left_margin + src->mode.hsync_len +
842 src->mode.xres + src->mode.right_margin;
843 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
844 src->mode.yres + src->mode.lower_margin;
845 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
846 src->mode.hsync_len + src->mode.left_margin;
847 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
848 dst->mode.hsync_len + dst->mode.left_margin;
850 T_BP_in = BP_in * src_pixclock;
851 T_BP_out = BP_out * dst_pixclock;
852 Tin = src_vtotal * src_htotal * src_pixclock;
854 v_scale_ratio = src->mode.yres / dst->mode.yres;
855 if (v_scale_ratio <= 2)
856 T_Delta = 5 * src_htotal * src_pixclock;
858 T_Delta = 12 * src_htotal * src_pixclock;
860 if (T_BP_in + T_Delta > T_BP_out)
861 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
863 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
865 /* (T_frm_st = scl_vst * src_htotal * src_pixclock +
866 scl_hst * src_pixclock) */
867 temp = do_div(T_frm_st, src_pixclock);
868 temp = do_div(T_frm_st, src_htotal);
869 dst->scl_hst = temp - 1;
870 dst->scl_vst = T_frm_st;
875 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
876 struct rk_screen *dst_screen, bool enable)
878 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
879 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
880 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
881 u32 scl_v_factor, scl_h_factor;
882 u32 dst_frame_hst, dst_frame_vst;
883 u32 src_w, src_h, dst_w, dst_h;
889 struct rk_screen *src;
890 struct rk_screen *dst;
891 struct lcdc_device *lcdc_dev = container_of(dev_drv,
892 struct lcdc_device, driver);
893 struct dvfs_node *gpu_clk = clk_get_dvfs_node("clk_gpu");
895 if (unlikely(!lcdc_dev->clk_on))
899 spin_lock(&lcdc_dev->reg_lock);
900 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
901 m_SCALER_EN | m_SCALER_OUT_ZERO |
903 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(1) |
905 lcdc_cfg_done(lcdc_dev);
906 spin_unlock(&lcdc_dev->reg_lock);
907 if (lcdc_dev->sclk_on) {
908 clk_disable_unprepare(lcdc_dev->sclk);
909 lcdc_dev->sclk_on = false;
912 /* switch pll freq as default when sclk is no used */
913 if (clk_get_rate(lcdc_dev->pll_sclk) != GPU_FREQ_NEED) {
914 dvfs_clk_enable_limit(gpu_clk, GPU_FREQ_MAX_LIMIT,
916 clk_set_rate(lcdc_dev->pll_sclk, GPU_FREQ_NEED);
917 dvfs_clk_enable_limit(gpu_clk, 0, -1);
919 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
924 * rk312x used one lcdc to apply dual disp
925 * hdmi screen is used for scaler src
926 * prmry screen is used for scaler dst
929 src = dev_drv->cur_screen;
931 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
935 if (!lcdc_dev->sclk_on) {
936 clk_prepare_enable(lcdc_dev->sclk);
937 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
938 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
941 dvfs_clk_enable_limit(gpu_clk,
945 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
946 /* cancel limit gpu freq */
947 dvfs_clk_enable_limit(gpu_clk, 0, -1);
949 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
950 lcdc_dev->sclk_on = true;
951 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
952 lcdc_dev->s_pixclock);
955 /* config scale timing */
956 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
957 dst_frame_vst = dst->scl_vst;
958 dst_frame_hst = dst->scl_hst;
960 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
961 dst->mode.xres + dst->mode.right_margin;
962 dsp_hs_end = dst->mode.hsync_len;
964 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
965 dst->mode.yres + dst->mode.lower_margin;
966 dsp_vs_end = dst->mode.vsync_len;
968 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
970 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
971 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
973 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
975 dsp_hact_st = dsp_hbor_st + bor_left;
976 dsp_hact_end = dsp_hbor_end - bor_right;
977 dsp_vact_st = dsp_vbor_st + bor_up;
978 dsp_vact_end = dsp_vbor_end - bor_down;
980 src_w = src->mode.xres;
981 src_h = src->mode.yres;
982 dst_w = dsp_hact_end - dsp_hact_st;
983 dst_h = dsp_vact_end - dsp_vact_st;
985 /* calc scale factor */
986 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
987 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
989 spin_lock(&lcdc_dev->reg_lock);
990 if (dst->color_mode != src->color_mode) {
991 /*dev_drv->output_color = dst->color_mode;
992 if (dev_drv->output_color == COLOR_YCBCR)
993 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
995 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
996 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
997 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
1000 lcdc_writel(lcdc_dev, SCALER_FACTOR,
1001 v_SCALER_H_FACTOR(scl_h_factor) |
1002 v_SCALER_V_FACTOR(scl_v_factor));
1004 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
1005 v_SCALER_FRAME_HST(dst_frame_hst) |
1006 v_SCALER_FRAME_VST(dst_frame_vst));
1007 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
1008 v_SCALER_HS_END(dsp_hs_end) |
1009 v_SCALER_HTOTAL(dsp_htotal));
1010 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
1011 v_SCALER_HAEP(dsp_hact_end) |
1012 v_SCALER_HASP(dsp_hact_st));
1013 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
1014 v_SCALER_VS_END(dsp_vs_end) |
1015 v_SCALER_VTOTAL(dsp_vtotal));
1016 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
1017 v_SCALER_VAEP(dsp_vact_end) |
1018 v_SCALER_VASP(dsp_vact_st));
1019 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
1020 v_SCALER_HBOR_END(dsp_hbor_end) |
1021 v_SCALER_HBOR_ST(dsp_hbor_st));
1022 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
1023 v_SCALER_VBOR_END(dsp_vbor_end) |
1024 v_SCALER_VBOR_ST(dsp_vbor_st));
1025 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1026 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
1027 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
1028 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1029 m_SCALER_EN | m_SCALER_OUT_ZERO |
1031 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) |
1032 v_SCALER_OUT_EN(1));
1034 lcdc_cfg_done(lcdc_dev);
1035 spin_unlock(&lcdc_dev->reg_lock);
1040 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
1041 struct lcdc_device *lcdc_dev)
1044 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1045 if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
1046 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1047 m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1048 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1050 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1051 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1054 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1056 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1057 if (dev_drv->output_color == COLOR_RGB) {
1059 bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1060 if (((bcsh_ctrl&m_BCSH_EN) == 1) ||
1061 (dev_drv->bcsh.enable == 1))/*bcsh enabled*/
1062 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1063 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1064 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1065 else/*bcsh disabled*/
1066 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1067 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1068 v_BCSH_R2Y_EN(0) | v_BCSH_Y2R_EN(0));
1069 } else /* RGB2YUV */
1070 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1072 m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1074 v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1079 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1082 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1083 struct lcdc_device, driver);
1084 struct rk_screen *screen = dev_drv->cur_screen;
1085 u16 right_margin = screen->mode.right_margin;
1086 u16 left_margin = screen->mode.left_margin;
1087 u16 lower_margin = screen->mode.lower_margin;
1088 u16 upper_margin = screen->mode.upper_margin;
1089 u16 x_res = screen->mode.xres;
1090 u16 y_res = screen->mode.yres;
1093 spin_lock(&lcdc_dev->reg_lock);
1094 if (likely(lcdc_dev->clk_on)) {
1095 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1096 m_LCDC_STANDBY, v_LCDC_STANDBY(1));
1097 lcdc_cfg_done(lcdc_dev);
1099 /* Select output color domain */
1100 /*dev_drv->output_color = screen->color_mode;
1101 if (lcdc_dev->soc_type == VOP_RK312X) {
1102 if (dev_drv->output_color == COLOR_YCBCR)
1103 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1105 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1107 dev_drv->output_color = COLOR_RGB;
1108 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1110 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1111 /*something wrong at yuv domain*/
1113 switch (screen->type) {
1115 if (lcdc_dev->soc_type == VOP_RK312X) {
1116 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1117 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1118 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1122 if (lcdc_dev->soc_type == VOP_RK312X) {
1123 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1124 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1125 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1129 if (lcdc_dev->soc_type == VOP_RK312X) {
1130 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1131 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1132 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1136 mask = m_HDMI_DCLK_EN;
1137 val = v_HDMI_DCLK_EN(1);
1138 if (screen->pixelrepeat) {
1139 mask |= m_CORE_CLK_DIV_EN;
1140 val |= v_CORE_CLK_DIV_EN(1);
1142 mask |= m_CORE_CLK_DIV_EN;
1143 val |= v_CORE_CLK_DIV_EN(0);
1145 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1146 if (lcdc_dev->soc_type == VOP_RK312X) {
1147 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1149 v_SW_UV_OFFSET_EN(0));
1150 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1152 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1153 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1154 v_HDMI_DEN_POL(screen->pin_den);
1155 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1157 mask = (1 << 4) | (1 << 5) | (1 << 6);
1158 val = (screen->pin_hsync << 4) |
1159 (screen->pin_vsync << 5) |
1160 (screen->pin_den << 6);
1161 grf_writel(RK3036_GRF_SOC_CON2,
1162 (mask << 16) | val);
1164 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1167 case SCREEN_TVOUT_TEST:
1168 mask = m_TVE_DAC_DCLK_EN;
1169 val = v_TVE_DAC_DCLK_EN(1);
1170 if (screen->pixelrepeat) {
1171 mask |= m_CORE_CLK_DIV_EN;
1172 val |= v_CORE_CLK_DIV_EN(1);
1174 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1175 if (x_res == 720 && y_res == 576)
1176 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1177 v_TVE_MODE(TV_PAL));
1178 else if (x_res == 720 && y_res == 480)
1179 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1180 v_TVE_MODE(TV_NTSC));
1182 dev_err(lcdc_dev->dev,
1183 "unsupported video timing!\n");
1186 if (lcdc_dev->soc_type == VOP_RK312X) {
1187 if (screen->type == SCREEN_TVOUT_TEST)
1188 /*for TVE index test,vop must ovarlay at yuv domain*/
1189 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1190 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1192 v_SW_UV_OFFSET_EN(1));
1194 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1198 dev_err(lcdc_dev->dev, "un supported interface!\n");
1201 if (lcdc_dev->soc_type == VOP_RK312X) {
1202 switch (dev_drv->screen0->face) {
1205 mask = m_DITHER_DOWN_EN |
1206 m_DITHER_DOWN_MODE |
1208 val = v_DITHER_DOWN_EN(1) |
1209 v_DITHER_DOWN_MODE(0) |
1210 v_DITHER_DOWN_SEL(1);
1211 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1215 mask = m_DITHER_DOWN_EN |
1216 m_DITHER_DOWN_MODE |
1218 val = v_DITHER_DOWN_EN(1) |
1219 v_DITHER_DOWN_MODE(1) |
1220 v_DITHER_DOWN_SEL(1);
1221 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1225 mask = m_DITHER_DOWN_EN |
1226 m_DITHER_DOWN_MODE |
1228 val = v_DITHER_DOWN_EN(1) |
1229 v_DITHER_DOWN_MODE(0) |
1230 v_DITHER_DOWN_SEL(1);
1231 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1235 mask = m_DITHER_DOWN_EN |
1236 m_DITHER_DOWN_MODE |
1238 val = v_DITHER_DOWN_EN(1) |
1239 v_DITHER_DOWN_MODE(1) |
1240 v_DITHER_DOWN_SEL(1);
1241 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1245 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1246 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1247 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1250 dev_err(lcdc_dev->dev, "un supported interface!\n");
1253 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1254 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1257 mask = m_HSYNC_POL | m_VSYNC_POL |
1258 m_DEN_POL | m_DCLK_POL;
1259 val = v_HSYNC_POL(screen->pin_hsync) |
1260 v_VSYNC_POL(screen->pin_vsync) |
1261 v_DEN_POL(screen->pin_den) |
1262 v_DCLK_POL(screen->pin_dclk);
1264 if (screen->type != SCREEN_HDMI) {
1265 mask |= m_DSP_OUT_FORMAT;
1266 val |= v_DSP_OUT_FORMAT(face);
1269 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1271 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1272 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1273 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1275 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1276 v_DSP_RB_SWAP(screen->swap_rb) |
1277 v_DSP_RG_SWAP(screen->swap_rg) |
1278 v_DSP_DELTA_SWAP(screen->swap_delta) |
1279 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1280 v_BLANK_EN(0) | v_BLACK_EN(0);
1281 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1284 val = v_HSYNC(screen->mode.hsync_len) |
1285 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1287 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1288 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1289 v_HASP(screen->mode.hsync_len + left_margin);
1290 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1292 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1293 /* First Field Timing */
1294 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1295 v_VSYNC(screen->mode.vsync_len) |
1296 v_VERPRD(2 * (screen->mode.vsync_len +
1298 lower_margin) + y_res + 1));
1299 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1300 v_VAEP(screen->mode.vsync_len +
1301 upper_margin + y_res / 2) |
1302 v_VASP(screen->mode.vsync_len +
1304 /* Second Field Timing */
1305 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1306 v_VSYNC_ST_F1(screen->mode.vsync_len +
1307 upper_margin + y_res / 2 +
1309 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1310 upper_margin + y_res / 2 +
1312 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1313 v_VAEP(2 * (screen->mode.vsync_len +
1315 y_res + lower_margin + 1) |
1316 v_VASP(2 * (screen->mode.vsync_len +
1318 y_res / 2 + lower_margin + 1));
1320 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1321 m_INTERLACE_DSP_EN |
1322 m_WIN0_YRGB_DEFLICK_EN |
1323 m_WIN0_CBR_DEFLICK_EN |
1324 m_INTERLACE_FIELD_POL |
1325 m_WIN0_INTERLACE_EN |
1326 m_WIN1_INTERLACE_EN,
1327 v_INTERLACE_DSP_EN(1) |
1328 v_WIN0_YRGB_DEFLICK_EN(1) |
1329 v_WIN0_CBR_DEFLICK_EN(1) |
1330 v_INTERLACE_FIELD_POL(0) |
1331 v_WIN0_INTERLACE_EN(1) |
1332 v_WIN1_INTERLACE_EN(1));
1333 mask = m_LF_INT_NUM;
1334 val = v_LF_INT_NUM(screen->mode.vsync_len +
1335 screen->mode.upper_margin +
1336 screen->mode.yres/2);
1337 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1339 val = v_VSYNC(screen->mode.vsync_len) |
1340 v_VERPRD(screen->mode.vsync_len + upper_margin +
1341 y_res + lower_margin);
1342 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1344 val = v_VAEP(screen->mode.vsync_len +
1345 upper_margin + y_res) |
1346 v_VASP(screen->mode.vsync_len + upper_margin);
1347 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1349 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1350 m_INTERLACE_DSP_EN |
1351 m_WIN0_YRGB_DEFLICK_EN |
1352 m_WIN0_CBR_DEFLICK_EN |
1353 m_INTERLACE_FIELD_POL |
1354 m_WIN0_INTERLACE_EN |
1355 m_WIN1_INTERLACE_EN,
1356 v_INTERLACE_DSP_EN(0) |
1357 v_WIN0_YRGB_DEFLICK_EN(0) |
1358 v_WIN0_CBR_DEFLICK_EN(0) |
1359 v_INTERLACE_FIELD_POL(0) |
1360 v_WIN0_INTERLACE_EN(0) |
1361 v_WIN1_INTERLACE_EN(0));
1362 mask = m_LF_INT_NUM;
1363 val = v_LF_INT_NUM(screen->mode.vsync_len +
1364 screen->mode.upper_margin +
1366 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1369 spin_unlock(&lcdc_dev->reg_lock);
1370 rk312x_lcdc_set_dclk(dev_drv, 1);
1371 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY, v_LCDC_STANDBY(0));
1372 lcdc_cfg_done(lcdc_dev);
1373 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1374 dev_drv->trsm_ops->enable();
1381 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1384 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1385 struct lcdc_device, driver);
1387 /* enable clk,when first layer open */
1388 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1389 rockchip_set_system_status(SYS_STATUS_LCDC0);
1390 rk312x_lcdc_pre_init(dev_drv);
1391 rk312x_lcdc_clk_enable(lcdc_dev);
1392 #if defined(CONFIG_ROCKCHIP_IOMMU)
1393 if (dev_drv->iommu_enabled) {
1394 if (!dev_drv->mmu_dev) {
1396 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1397 if (dev_drv->mmu_dev) {
1398 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1401 dev_err(dev_drv->dev,
1402 "failed to get rockchip iommu device\n");
1406 /*if (dev_drv->mmu_dev)
1407 rockchip_iovmm_activate(dev_drv->dev);*/
1410 rk312x_lcdc_reg_restore(lcdc_dev);
1411 /*if (dev_drv->iommu_enabled)
1412 rk312x_lcdc_mmu_en(dev_drv);*/
1413 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1414 rk312x_lcdc_set_dclk(dev_drv, 0);
1415 rk312x_lcdc_enable_irq(dev_drv);
1417 rk312x_load_screen(dev_drv, 1);
1420 /* set screen lut */
1421 if (dev_drv->cur_screen->dsp_lut)
1422 rk312x_lcdc_set_lut(dev_drv);
1425 if (win_id < ARRAY_SIZE(lcdc_win))
1426 lcdc_layer_enable(lcdc_dev, win_id, open);
1428 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1430 /* when all layer closed,disable clk */
1431 /* if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1432 rk312x_lcdc_disable_irq(lcdc_dev);
1433 rk312x_lcdc_reg_update(dev_drv);
1434 #if defined(CONFIG_ROCKCHIP_IOMMU)
1435 if (dev_drv->iommu_enabled) {
1436 if (dev_drv->mmu_dev)
1437 rockchip_iovmm_deactivate(dev_drv->dev);
1440 rk312x_lcdc_clk_disable(lcdc_dev);
1441 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1446 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1448 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1449 struct lcdc_device, driver);
1450 struct rk_screen *screen = dev_drv->cur_screen;
1451 struct rk_lcdc_win *win = NULL;
1452 char fmt[9] = "NULL";
1455 dev_err(dev_drv->dev, "screen is null!\n");
1460 win = dev_drv->win[0];
1461 } else if (win_id == 1) {
1462 win = dev_drv->win[1];
1463 } else if (win_id == 2) {
1464 win = dev_drv->win[2];
1466 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1470 spin_lock(&lcdc_dev->reg_lock);
1471 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1472 screen->mode.hsync_len;
1473 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1474 win->area[0].ysize /= 2;
1475 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1476 screen->mode.upper_margin +
1477 screen->mode.vsync_len;
1479 win->area[0].dsp_sty = win->area[0].ypos +
1480 screen->mode.upper_margin +
1481 screen->mode.vsync_len;
1483 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1484 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1486 switch (win->area[0].format) {
1488 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1489 win->area[0].swap_rb = 0;
1492 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1493 win->area[0].swap_rb = 1;
1496 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1497 win->area[0].swap_rb = 1;
1500 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1501 win->area[0].swap_rb = 0;
1504 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1505 win->area[0].swap_rb = 0;
1509 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1511 CalScale(win->area[0].xact, win->area[0].xsize);
1513 CalScale(win->area[0].yact, win->area[0].ysize);
1514 win->area[0].swap_rb = 0;
1516 dev_err(lcdc_dev->driver.dev,
1517 "%s:un supported format!\n", __func__);
1522 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1523 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1524 win->area[0].xsize);
1526 CalScale(win->area[0].yact, win->area[0].ysize);
1527 win->area[0].swap_rb = 0;
1529 dev_err(lcdc_dev->driver.dev,
1530 "%s:un supported format!\n", __func__);
1535 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1537 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1539 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1540 win->area[0].swap_rb = 0;
1542 dev_err(lcdc_dev->driver.dev,
1543 "%s:un supported format!\n", __func__);
1547 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1551 spin_unlock(&lcdc_dev->reg_lock);
1554 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1555 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1556 get_format_string(win->area[0].format, fmt), win->area[0].xact,
1557 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1558 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1563 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1565 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1566 struct lcdc_device, driver);
1567 struct rk_lcdc_win *win = NULL;
1568 struct rk_screen *screen = dev_drv->cur_screen;
1571 dev_err(dev_drv->dev, "screen is null!\n");
1576 win = dev_drv->win[0];
1577 } else if (win_id == 1) {
1578 win = dev_drv->win[1];
1579 } else if (win_id == 2) {
1580 win = dev_drv->win[2];
1582 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1586 spin_lock(&lcdc_dev->reg_lock);
1587 if (likely(lcdc_dev->clk_on)) {
1588 win->area[0].y_addr =
1589 win->area[0].smem_start + win->area[0].y_offset;
1590 win->area[0].uv_addr =
1591 win->area[0].cbr_start + win->area[0].c_offset;
1592 if (win->area[0].y_addr)
1593 lcdc_layer_update_regs(lcdc_dev, win);
1594 /* lcdc_cfg_done(lcdc_dev); */
1596 spin_unlock(&lcdc_dev->reg_lock);
1598 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1599 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1600 win->area[0].y_offset);
1601 /* this is the first frame of the system,enable frame start interrupt */
1602 if ((dev_drv->first_frame)) {
1603 dev_drv->first_frame = 0;
1604 rk312x_lcdc_enable_irq(dev_drv);
1610 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1611 unsigned long arg, int win_id)
1613 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1614 struct lcdc_device, driver);
1616 void __user *argp = (void __user *)arg;
1617 struct color_key_cfg clr_key_cfg;
1620 case RK_FBIOGET_PANEL_SIZE:
1621 panel_size[0] = lcdc_dev->screen->mode.xres;
1622 panel_size[1] = lcdc_dev->screen->mode.yres;
1623 if (copy_to_user(argp, panel_size, 8))
1626 case RK_FBIOPUT_COLOR_KEY_CFG:
1627 if (copy_from_user(&clr_key_cfg, argp,
1628 sizeof(struct color_key_cfg)))
1630 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1631 clr_key_cfg.win0_color_key_cfg);
1632 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1633 clr_key_cfg.win1_color_key_cfg);
1642 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1647 mutex_lock(&dev_drv->fb_win_id_mutex);
1648 if (!strcmp(id, "fb0"))
1649 win_id = dev_drv->fb0_win_id;
1650 else if (!strcmp(id, "fb1"))
1651 win_id = dev_drv->fb1_win_id;
1652 else if (!strcmp(id, "fb2"))
1653 win_id = dev_drv->fb2_win_id;
1654 mutex_unlock(&dev_drv->fb_win_id_mutex);
1659 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1664 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1667 struct lcdc_device *lcdc_dev =
1668 container_of(dev_drv, struct lcdc_device, driver);
1671 spin_lock(&lcdc_dev->reg_lock);
1672 if (lcdc_dev->clk_on) {
1674 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1678 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1683 spin_unlock(&lcdc_dev->reg_lock);
1688 static int rk312x_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1690 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1691 struct lcdc_device, driver);
1692 struct device_node *backlight;
1694 if (lcdc_dev->backlight)
1697 backlight = of_parse_phandle(lcdc_dev->dev->of_node,
1700 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
1701 if (!lcdc_dev->backlight)
1702 dev_info(lcdc_dev->dev, "No find backlight device\n");
1704 dev_info(lcdc_dev->dev, "No find backlight device node\n");
1710 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1712 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1713 struct lcdc_device, driver);
1714 if (dev_drv->suspend_flag)
1717 /* close the backlight */
1718 rk312x_lcdc_get_backlight_device(dev_drv);
1719 if (lcdc_dev->backlight) {
1720 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
1721 backlight_update_status(lcdc_dev->backlight);
1724 dev_drv->suspend_flag = 1;
1725 flush_kthread_worker(&dev_drv->update_regs_worker);
1727 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1728 dev_drv->trsm_ops->disable();
1729 spin_lock(&lcdc_dev->reg_lock);
1730 if (likely(lcdc_dev->clk_on)) {
1731 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1732 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1733 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1734 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1735 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1737 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1739 lcdc_cfg_done(lcdc_dev);
1741 if (dev_drv->iommu_enabled) {
1742 if (dev_drv->mmu_dev)
1743 rockchip_iovmm_deactivate(dev_drv->dev);
1746 spin_unlock(&lcdc_dev->reg_lock);
1748 spin_unlock(&lcdc_dev->reg_lock);
1751 rk312x_lcdc_clk_disable(lcdc_dev);
1752 rk_disp_pwr_disable(dev_drv);
1756 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1758 struct lcdc_device *lcdc_dev =
1759 container_of(dev_drv, struct lcdc_device, driver);
1761 if (!dev_drv->suspend_flag)
1763 rk_disp_pwr_enable(dev_drv);
1764 dev_drv->suspend_flag = 0;
1766 rk312x_lcdc_clk_enable(lcdc_dev);
1767 rk312x_lcdc_reg_restore(lcdc_dev);
1769 /* config for the FRC mode of dither down */
1770 if (dev_drv->cur_screen &&
1771 dev_drv->cur_screen->face != OUT_P888) {
1772 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1773 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1774 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1775 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1776 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1777 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1780 /* set screen lut */
1781 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1782 rk312x_lcdc_set_lut(dev_drv);
1784 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1786 spin_lock(&lcdc_dev->reg_lock);
1788 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1790 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1792 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1793 lcdc_cfg_done(lcdc_dev);
1795 if (dev_drv->iommu_enabled) {
1796 if (dev_drv->mmu_dev)
1797 rockchip_iovmm_activate(dev_drv->dev);
1800 spin_unlock(&lcdc_dev->reg_lock);
1802 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1803 dev_drv->trsm_ops->enable();
1808 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1809 int win_id, int blank_mode)
1811 switch (blank_mode) {
1812 case FB_BLANK_UNBLANK:
1813 rk312x_lcdc_early_resume(dev_drv);
1815 case FB_BLANK_NORMAL:
1816 rk312x_lcdc_early_suspend(dev_drv);
1819 rk312x_lcdc_early_suspend(dev_drv);
1823 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1828 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1830 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1831 struct lcdc_device, driver);
1833 unsigned int mask, val;
1834 struct rk_lcdc_win *win = NULL;
1836 spin_lock(&lcdc_dev->reg_lock);
1837 if (lcdc_dev->clk_on) {
1838 for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
1839 win = dev_drv->win[i];
1840 if ((win->state == 0) && (win->last_state == 1)) {
1845 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1851 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1857 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1864 win->last_state = win->state;
1866 lcdc_cfg_done(lcdc_dev);
1868 spin_unlock(&lcdc_dev->reg_lock);
1874 sin_hue = sin(a)*256 +0x100;
1875 cos_hue = cos(a)*256;
1877 sin_hue = sin(a)*256;
1878 cos_hue = cos(a)*256;
1880 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1883 struct lcdc_device *lcdc_dev =
1884 container_of(dev_drv, struct lcdc_device, driver);
1887 spin_lock(&lcdc_dev->reg_lock);
1888 if (lcdc_dev->clk_on) {
1889 val = lcdc_readl(lcdc_dev, BCSH_H);
1892 val &= m_BCSH_SIN_HUE;
1895 val &= m_BCSH_COS_HUE;
1902 spin_unlock(&lcdc_dev->reg_lock);
1907 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
1910 struct lcdc_device *lcdc_dev =
1911 container_of(dev_drv, struct lcdc_device, driver);
1914 spin_lock(&lcdc_dev->reg_lock);
1915 if (lcdc_dev->clk_on) {
1916 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1917 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1918 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1919 lcdc_cfg_done(lcdc_dev);
1921 spin_unlock(&lcdc_dev->reg_lock);
1926 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1927 bcsh_bcs_mode mode, int value)
1929 struct lcdc_device *lcdc_dev =
1930 container_of(dev_drv, struct lcdc_device, driver);
1933 spin_lock(&lcdc_dev->reg_lock);
1934 if (lcdc_dev->clk_on) {
1937 /* from 0 to 255,typical is 128 */
1940 else if (value >= 0x80)
1941 value = value - 0x80;
1942 mask = m_BCSH_BRIGHTNESS;
1943 val = v_BCSH_BRIGHTNESS(value);
1946 /* from 0 to 510,typical is 256 */
1947 mask = m_BCSH_CONTRAST;
1948 val = v_BCSH_CONTRAST(value);
1951 /* from 0 to 1015,typical is 256 */
1952 mask = m_BCSH_SAT_CON;
1953 val = v_BCSH_SAT_CON(value);
1958 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
1959 lcdc_cfg_done(lcdc_dev);
1961 spin_unlock(&lcdc_dev->reg_lock);
1965 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1968 struct lcdc_device *lcdc_dev =
1969 container_of(dev_drv, struct lcdc_device, driver);
1972 spin_lock(&lcdc_dev->reg_lock);
1973 if (lcdc_dev->clk_on) {
1974 val = lcdc_readl(lcdc_dev, BCSH_BCS);
1977 val &= m_BCSH_BRIGHTNESS;
1984 val &= m_BCSH_CONTRAST;
1988 val &= m_BCSH_SAT_CON;
1995 spin_unlock(&lcdc_dev->reg_lock);
1999 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2001 struct lcdc_device *lcdc_dev =
2002 container_of(dev_drv, struct lcdc_device, driver);
2004 if (dev_drv->bcsh_init_status && open) {
2005 dev_drv->bcsh_init_status = 0;
2008 spin_lock(&lcdc_dev->reg_lock);
2009 if (lcdc_dev->clk_on) {
2011 lcdc_msk_reg(lcdc_dev,
2012 BCSH_CTRL, m_BCSH_EN | m_BCSH_OUT_MODE,
2013 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
2014 lcdc_writel(lcdc_dev, BCSH_BCS,
2015 v_BCSH_BRIGHTNESS(0x00) |
2016 v_BCSH_CONTRAST(0x80) |
2017 v_BCSH_SAT_CON(0x80));
2018 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
2019 dev_drv->bcsh.enable = 1;
2023 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
2024 dev_drv->bcsh.enable = 0;
2026 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
2027 lcdc_cfg_done(lcdc_dev);
2030 spin_unlock(&lcdc_dev->reg_lock);
2034 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2036 struct rk_lcdc_win_area area;
2037 int fb2_win_id, fb1_win_id, fb0_win_id;
2039 mutex_lock(&dev_drv->fb_win_id_mutex);
2040 if (order == FB_DEFAULT_ORDER)
2041 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
2043 fb2_win_id = order / 100;
2044 fb1_win_id = (order / 10) % 10;
2045 fb0_win_id = order % 10;
2047 if (fb0_win_id != dev_drv->fb0_win_id) {
2048 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
2049 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
2050 dev_drv->win[fb0_win_id]->area[0];
2051 dev_drv->win[fb0_win_id]->area[0] = area;
2052 dev_drv->fb0_win_id = fb0_win_id;
2054 dev_drv->fb1_win_id = fb1_win_id;
2055 dev_drv->fb2_win_id = fb2_win_id;
2057 mutex_unlock(&dev_drv->fb_win_id_mutex);
2062 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2065 struct lcdc_device *lcdc_dev =
2066 container_of(dev_drv, struct lcdc_device, driver);
2067 struct rk_screen *screen = dev_drv->cur_screen;
2072 u32 x_total, y_total;
2075 ft = div_u64(1000000000000llu, fps);
2077 screen->mode.upper_margin + screen->mode.lower_margin +
2078 screen->mode.yres + screen->mode.vsync_len;
2080 screen->mode.left_margin + screen->mode.right_margin +
2081 screen->mode.xres + screen->mode.hsync_len;
2082 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2083 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2084 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2087 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2088 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2089 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2090 screen->ft = 1000 / fps; /*one frame time in ms */
2093 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2094 clk_get_rate(lcdc_dev->dclk), fps);
2099 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
2102 struct lcdc_device *lcdc_dev =
2103 container_of(dev_drv,
2104 struct lcdc_device, driver);
2106 enable_irq(lcdc_dev->irq);
2108 disable_irq(lcdc_dev->irq);
2112 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2114 struct lcdc_device *lcdc_dev =
2115 container_of(dev_drv, struct lcdc_device, driver);
2119 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
2120 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
2121 if (int_reg & m_LF_INT_STA) {
2122 dev_drv->frame_time.last_framedone_t =
2123 dev_drv->frame_time.framedone_t;
2124 dev_drv->frame_time.framedone_t = cpu_clock(0);
2125 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
2127 ret = RK_LF_STATUS_FC;
2129 ret = RK_LF_STATUS_FR;
2132 ret = RK_LF_STATUS_NC;
2138 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2139 unsigned int *dsp_addr)
2141 struct lcdc_device *lcdc_dev =
2142 container_of(dev_drv, struct lcdc_device, driver);
2144 if (lcdc_dev->clk_on) {
2145 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2146 if (lcdc_dev->soc_type == VOP_RK3036)
2147 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
2148 else if (lcdc_dev->soc_type == VOP_RK312X)
2149 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2154 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2155 char *buf, int win_id)
2157 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
2159 char format_w0[9] = "NULL";
2160 char format_w1[9] = "NULL";
2161 char status_w0[9] = "NULL";
2162 char status_w1[9] = "NULL";
2163 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
2164 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
2165 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
2166 u16 x_factor, y_factor, x_scale, y_scale;
2168 u32 win1_dsp_yaddr = 0;
2170 spin_lock(&lcdc_dev->reg_lock);
2171 if (lcdc_dev->clk_on) {
2173 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2174 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2175 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2178 if (fmt_id & m_WIN0_EN)
2179 strcpy(status_w0, "enabled");
2181 strcpy(status_w0, "disabled");
2183 if ((fmt_id & m_WIN1_EN) >> 1)
2184 strcpy(status_w1, "enabled");
2186 strcpy(status_w1, "disabled");
2189 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2192 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2193 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2196 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2197 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2198 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2200 if (lcdc_dev->soc_type == VOP_RK3036) {
2201 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2202 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2203 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2204 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2205 /* rk312x unsupport win1 scaler,so have no act info */
2211 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2212 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2213 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2215 if (lcdc_dev->soc_type == VOP_RK3036)
2216 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2217 else if (lcdc_dev->soc_type == VOP_RK312X)
2218 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2219 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2220 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2223 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2224 x_st_w0 = dsp_st & m_DSP_STX;
2225 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2227 if (lcdc_dev->soc_type == VOP_RK3036)
2228 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2229 else if (lcdc_dev->soc_type == VOP_RK312X)
2230 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2232 x_st_w1 = dsp_st & m_DSP_STX;
2233 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2236 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2237 x_factor = factor & m_X_SCL_FACTOR;
2238 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2239 x_scale = 4096 * 100 / x_factor;
2240 y_scale = 4096 * 100 / y_factor;
2243 if (lcdc_dev->soc_type == VOP_RK3036)
2244 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2245 else if (lcdc_dev->soc_type == VOP_RK312X)
2246 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2248 spin_unlock(&lcdc_dev->reg_lock);
2251 spin_unlock(&lcdc_dev->reg_lock);
2252 return snprintf(buf, PAGE_SIZE,
2264 "YRGB buffer addr:0x%08x\n"
2265 "CBR buffer addr:0x%08x\n\n"
2275 "YRGB buffer addr:0x%08x\n"
2290 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2291 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2302 ovl ? "win0 on the top of win1\n" :
2303 "win1 on the top of win0\n");
2306 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2308 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2311 int *cbase = (int *)lcdc_dev->regs;
2312 int *regsbak = (int *)lcdc_dev->regsbak;
2315 pr_info("back up reg:\n");
2316 for (i = 0; i <= (0xDC >> 4); i++) {
2317 for (j = 0; j < 4; j++)
2318 pr_info("%08x ", *(regsbak + i * 4 + j));
2322 pr_info("lcdc reg:\n");
2323 for (i = 0; i <= (0xDC >> 4); i++) {
2324 for (j = 0; j < 4; j++)
2325 pr_info("%08x ", readl_relaxed(cbase + i * 4 + j));
2331 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2333 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2334 struct lcdc_device, driver);
2335 if (lcdc_dev->soc_type == VOP_RK312X) {
2336 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2337 v_DIRECT_PATH_EN(open));
2338 lcdc_cfg_done(lcdc_dev);
2343 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2345 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2346 struct lcdc_device, driver);
2348 if (lcdc_dev->soc_type == VOP_RK312X) {
2349 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2350 v_DIRECT_PATH_LAYER(win_id));
2351 lcdc_cfg_done(lcdc_dev);
2356 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2358 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2359 struct lcdc_device, driver);
2362 if (lcdc_dev->soc_type == VOP_RK312X)
2363 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2368 static int rk312x_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2370 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2371 struct lcdc_device, driver);
2373 rk312x_lcdc_get_backlight_device(dev_drv);
2376 /* close the backlight */
2377 if (lcdc_dev->backlight) {
2378 lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
2379 backlight_update_status(lcdc_dev->backlight);
2382 spin_lock(&lcdc_dev->reg_lock);
2383 if (likely(lcdc_dev->clk_on)) {
2384 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2386 lcdc_cfg_done(lcdc_dev);
2388 spin_unlock(&lcdc_dev->reg_lock);
2390 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2391 dev_drv->trsm_ops->disable();
2393 spin_lock(&lcdc_dev->reg_lock);
2394 if (likely(lcdc_dev->clk_on)) {
2395 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2397 lcdc_cfg_done(lcdc_dev);
2399 spin_unlock(&lcdc_dev->reg_lock);
2400 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2401 dev_drv->trsm_ops->enable();
2403 /* open the backlight */
2404 if (lcdc_dev->backlight) {
2405 lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
2406 backlight_update_status(lcdc_dev->backlight);
2414 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2415 .open = rk312x_lcdc_open,
2416 .load_screen = rk312x_load_screen,
2417 .set_par = rk312x_lcdc_set_par,
2418 .pan_display = rk312x_lcdc_pan_display,
2419 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2420 .blank = rk312x_lcdc_blank,
2421 .ioctl = rk312x_lcdc_ioctl,
2422 .get_win_state = rk312x_lcdc_get_win_state,
2423 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2424 .get_disp_info = rk312x_lcdc_get_disp_info,
2425 .fps_mgr = rk312x_lcdc_fps_mgr,
2426 .fb_get_win_id = rk312x_lcdc_get_win_id,
2427 .fb_win_remap = rk312x_fb_win_remap,
2428 .poll_vblank = rk312x_lcdc_poll_vblank,
2429 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2430 .cfg_done = rk312x_lcdc_cfg_done,
2431 .dump_reg = rk312x_lcdc_reg_dump,
2432 .dpi_open = rk312x_lcdc_dpi_open,
2433 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2434 .dpi_status = rk312x_lcdc_dpi_status,
2435 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2436 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2437 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2438 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2439 .open_bcsh = rk312x_lcdc_open_bcsh,
2440 .set_screen_scaler = rk312x_lcdc_set_scaler,
2441 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2442 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2443 .dsp_black = rk312x_lcdc_dsp_black,
2444 .mmu_en = rk312x_lcdc_mmu_en,
2447 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2448 .soc_type = VOP_RK3036,
2451 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2452 .soc_type = VOP_RK312X,
2455 #if defined(CONFIG_OF)
2456 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2459 .compatible = "rockchip,rk3036-lcdc",
2460 .data = (void *)&rk3036_lcdc_drvdata,
2464 .compatible = "rockchip,rk312x-lcdc",
2465 .data = (void *)&rk312x_lcdc_drvdata,
2470 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2472 struct device_node *np = lcdc_dev->dev->of_node;
2473 const struct of_device_id *match;
2474 const struct rk_lcdc_drvdata *lcdc_drvdata;
2477 #if defined(CONFIG_ROCKCHIP_IOMMU)
2478 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2479 lcdc_dev->driver.iommu_enabled = 0;
2481 lcdc_dev->driver.iommu_enabled = val;
2483 lcdc_dev->driver.iommu_enabled = 0;
2486 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2487 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2489 lcdc_dev->driver.fb_win_map = val;
2491 match = of_match_node(rk312x_lcdc_dt_ids, np);
2493 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2494 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2496 return PTR_ERR(match);
2502 static int rk312x_lcdc_probe(struct platform_device *pdev)
2504 struct lcdc_device *lcdc_dev = NULL;
2505 struct rk_lcdc_driver *dev_drv;
2506 struct device *dev = &pdev->dev;
2507 struct resource *res;
2510 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2512 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2515 platform_set_drvdata(pdev, lcdc_dev);
2516 lcdc_dev->dev = dev;
2517 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2518 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2522 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2523 lcdc_dev->reg_phy_base = res->start;
2524 lcdc_dev->len = resource_size(res);
2525 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2526 if (IS_ERR(lcdc_dev->regs)) {
2527 ret = PTR_ERR(lcdc_dev->regs);
2531 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2532 if (IS_ERR(lcdc_dev->regsbak)) {
2533 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2534 ret = PTR_ERR(lcdc_dev->regsbak);
2537 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2538 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2539 lcdc_dev->prop = PRMRY;
2540 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2541 dev_drv = &lcdc_dev->driver;
2543 dev_drv->prop = lcdc_dev->prop;
2544 dev_drv->id = lcdc_dev->id;
2545 dev_drv->ops = &lcdc_drv_ops;
2546 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2547 spin_lock_init(&lcdc_dev->reg_lock);
2549 lcdc_dev->irq = platform_get_irq(pdev, 0);
2550 if (lcdc_dev->irq < 0) {
2551 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2554 goto err_request_irq;
2557 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2558 IRQF_DISABLED | IRQF_SHARED,
2559 dev_name(dev), lcdc_dev);
2561 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2562 lcdc_dev->irq, ret);
2563 goto err_request_irq;
2566 if (dev_drv->iommu_enabled)
2567 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2569 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2571 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2572 goto err_register_fb;
2574 lcdc_dev->screen = dev_drv->screen0;
2576 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2577 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2582 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2585 devm_kfree(&pdev->dev, lcdc_dev);
2589 #if defined(CONFIG_PM)
2590 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2595 static int rk312x_lcdc_resume(struct platform_device *pdev)
2600 #define rk312x_lcdc_suspend NULL
2601 #define rk312x_lcdc_resume NULL
2604 static int rk312x_lcdc_remove(struct platform_device *pdev)
2609 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2611 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2613 rk312x_lcdc_deinit(lcdc_dev);
2614 rk312x_lcdc_clk_disable(lcdc_dev);
2615 rk_disp_pwr_disable(&lcdc_dev->driver);
2617 if (lcdc_dev->backlight)
2618 put_device(&lcdc_dev->backlight->dev);
2621 static struct platform_driver rk312x_lcdc_driver = {
2622 .probe = rk312x_lcdc_probe,
2623 .remove = rk312x_lcdc_remove,
2625 .name = "rk312x-lcdc",
2626 .owner = THIS_MODULE,
2627 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2629 .suspend = rk312x_lcdc_suspend,
2630 .resume = rk312x_lcdc_resume,
2631 .shutdown = rk312x_lcdc_shutdown,
2634 static int __init rk312x_lcdc_module_init(void)
2636 return platform_driver_register(&rk312x_lcdc_driver);
2639 static void __exit rk312x_lcdc_module_exit(void)
2641 platform_driver_unregister(&rk312x_lcdc_driver);
2644 fs_initcall(rk312x_lcdc_module_init);
2645 module_exit(rk312x_lcdc_module_exit);