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].xact) |
474 v_DSP_HEIGHT(win->area[0].yact));
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 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
514 win->area[0].y_addr);
515 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
516 win->area[0].uv_addr);
517 } else if (win->id == 1) {
518 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
520 lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
521 } else if (win->id == 2) {
522 lcdc_msk_reg(lcdc_dev,
523 SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
524 v_HWC_EN(0) | v_HWC_LODAD_EN(0));
525 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
528 rk312x_lcdc_alpha_cfg(lcdc_dev);
531 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
534 spin_lock(&lcdc_dev->reg_lock);
535 if (likely(lcdc_dev->clk_on) &&
536 lcdc_dev->driver.win[win_id]->state != open) {
538 if (!lcdc_dev->atv_layer_cnt) {
539 dev_info(lcdc_dev->dev,
540 "wakeup from standby!\n");
541 lcdc_dev->standby = 0;
543 lcdc_dev->atv_layer_cnt |= (1 << win_id);
544 } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
545 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
547 lcdc_dev->driver.win[win_id]->state = open;
549 lcdc_layer_update_regs(lcdc_dev,
550 lcdc_dev->driver.win[win_id]);
551 lcdc_cfg_done(lcdc_dev);
553 /*if no layer used,disable lcdc */
554 if (!lcdc_dev->atv_layer_cnt) {
555 dev_info(lcdc_dev->dev,
556 "no layer is used,go to standby!\n");
557 lcdc_dev->standby = 1;
560 spin_unlock(&lcdc_dev->reg_lock);
563 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
565 struct lcdc_device *lcdc_dev =
566 container_of(dev_drv, struct lcdc_device, driver);
567 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
568 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
571 spin_lock(&lcdc_dev->reg_lock);
572 if (likely(lcdc_dev->clk_on)) {
573 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
574 v_LCDC_STANDBY(lcdc_dev->standby));
575 lcdc_layer_update_regs(lcdc_dev, win0);
576 lcdc_layer_update_regs(lcdc_dev, win1);
577 rk312x_lcdc_alpha_cfg(lcdc_dev);
578 lcdc_cfg_done(lcdc_dev);
581 spin_unlock(&lcdc_dev->reg_lock);
582 //if (dev_drv->wait_fs) {
584 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
585 init_completion(&dev_drv->frame_done);
586 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
587 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
589 (dev_drv->cur_screen->ft +
591 if (!timeout && (!dev_drv->frame_done.done)) {
592 dev_warn(lcdc_dev->dev,
593 "wait for new frame start time out!\n");
597 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
602 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
604 memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
607 static int rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
610 struct lcdc_device *lcdc_dev =
611 container_of(dev_drv, struct lcdc_device, driver);
613 /*spin_lock(&lcdc_dev->reg_lock);*/
614 if (likely(lcdc_dev->clk_on)) {
615 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
616 m_AXI_OUTSTANDING_MAX_NUM;
617 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
618 v_AXI_MAX_OUTSTANDING_EN(1);
619 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
621 /*spin_unlock(&lcdc_dev->reg_lock);*/
622 #if defined(CONFIG_ROCKCHIP_IOMMU)
623 if (dev_drv->iommu_enabled) {
624 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
625 lcdc_dev->iommu_status = 1;
626 rockchip_iovmm_activate(dev_drv->dev);
634 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
635 int *hwc_lut, int mode)
641 struct lcdc_device *lcdc_dev =
642 container_of(dev_drv, struct lcdc_device, driver);
643 if (dev_drv->hwc_lut == NULL)
644 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
646 spin_lock(&lcdc_dev->reg_lock);
647 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
648 lcdc_cfg_done(lcdc_dev);
650 for (i = 0; i < 256; i++) {
652 dev_drv->hwc_lut[i] = hwc_lut[i];
653 v = dev_drv->hwc_lut[i];
654 c = lcdc_dev->hwc_lut_addr_base + i;
655 writel_relaxed(v, c);
657 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
658 lcdc_cfg_done(lcdc_dev);
659 spin_unlock(&lcdc_dev->reg_lock);
664 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv,
670 struct lcdc_device *lcdc_dev =
671 container_of(dev_drv, struct lcdc_device, driver);
676 spin_lock(&lcdc_dev->reg_lock);
677 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
678 lcdc_cfg_done(lcdc_dev);
680 for (i = 0; i < 256; i++) {
682 c = lcdc_dev->dsp_lut_addr_base + i;
683 writel_relaxed(v, c);
685 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
686 lcdc_cfg_done(lcdc_dev);
687 spin_unlock(&lcdc_dev->reg_lock);
691 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
694 #ifdef CONFIG_RK_FPGA
698 struct lcdc_device *lcdc_dev =
699 container_of(dev_drv, struct lcdc_device, driver);
700 struct rk_screen *screen = dev_drv->cur_screen;
703 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
705 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
707 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
708 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
710 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
711 screen->ft = 1000 / fps;
712 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
713 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
717 /********do basic init*********/
718 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
720 struct lcdc_device *lcdc_dev = container_of(dev_drv,
721 struct lcdc_device, driver);
722 if (lcdc_dev->pre_init)
725 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
726 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
727 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
728 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
729 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
730 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
732 if (/*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
733 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
734 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
738 rk_disp_pwr_enable(dev_drv);
739 rk312x_lcdc_clk_enable(lcdc_dev);
741 /* backup reg config at uboot */
742 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
744 /* config for the FRC mode of dither down */
745 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
746 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
747 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
748 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
749 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
750 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
752 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
753 lcdc_cfg_done(lcdc_dev);
754 /*if (dev_drv->iommu_enabled)
755 {// disable all wins to workaround iommu pagefault
756 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
757 v_WIN0_EN(0) | v_WIN1_EN(0));
758 lcdc_cfg_done(lcdc_dev);
759 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
761 if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
762 if (support_uboot_display())
763 dev_drv->bcsh_init_status = 1;
765 dev_drv->ops->open_bcsh(dev_drv, 1);
767 lcdc_dev->pre_init = true;
772 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
774 rk312x_lcdc_disable_irq(lcdc_dev);
777 static u32 calc_sclk_freq(struct rk_screen *src_screen,
778 struct rk_screen *dst_screen)
786 if (!src_screen || !dst_screen)
789 dsp_vtotal = dst_screen->mode.yres;
790 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
791 dst_screen->mode.xres + dst_screen->mode.right_margin;
792 dsp_in_vtotal = src_screen->mode.yres;
793 dsp_in_htotal = src_screen->mode.left_margin +
794 src_screen->mode.hsync_len +
795 src_screen->mode.xres + src_screen->mode.right_margin;
796 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
797 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
799 return (u32)sclk_freq;
802 #define SCLK_PLL_LIMIT 594000000
803 #define GPU_FREQ_MAX_LIMIT 297000000
804 #define GPU_FREQ_NEED 400000000
806 static u32 calc_sclk_pll_freq(u32 sclk_freq)
810 if (sclk_freq < (SCLK_PLL_LIMIT / 10)) {
811 return (sclk_freq * 10);
813 multi_num = GPU_FREQ_NEED / sclk_freq;
814 return (sclk_freq * multi_num);
818 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
819 struct rk_screen *dst, u32 sclk_freq)
824 u64 T_BP_in, T_BP_out, T_Delta, Tin;
825 u32 src_pixclock, dst_pixclock;
827 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
829 if (unlikely(!src) || unlikely(!dst))
832 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
833 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
834 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
835 dst->mode.xres + dst->mode.right_margin;
836 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
837 dst->mode.yres + dst->mode.lower_margin;
838 src_htotal = src->mode.left_margin + src->mode.hsync_len +
839 src->mode.xres + src->mode.right_margin;
840 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
841 src->mode.yres + src->mode.lower_margin;
842 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
843 src->mode.hsync_len + src->mode.left_margin;
844 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
845 dst->mode.hsync_len + dst->mode.left_margin;
847 T_BP_in = BP_in * src_pixclock;
848 T_BP_out = BP_out * dst_pixclock;
849 Tin = src_vtotal * src_htotal * src_pixclock;
851 v_scale_ratio = src->mode.yres / dst->mode.yres;
852 if (v_scale_ratio <= 2)
853 T_Delta = 5 * src_htotal * src_pixclock;
855 T_Delta = 12 * src_htotal * src_pixclock;
857 if (T_BP_in + T_Delta > T_BP_out)
858 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
860 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
862 /* (T_frm_st = scl_vst * src_htotal * src_pixclock +
863 scl_hst * src_pixclock) */
864 temp = do_div(T_frm_st, src_pixclock);
865 temp = do_div(T_frm_st, src_htotal);
866 dst->scl_hst = temp - 1;
867 dst->scl_vst = T_frm_st;
872 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
873 struct rk_screen *dst_screen, bool enable)
875 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
876 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
877 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
878 u32 scl_v_factor, scl_h_factor;
879 u32 dst_frame_hst, dst_frame_vst;
880 u32 src_w, src_h, dst_w, dst_h;
886 struct rk_screen *src;
887 struct rk_screen *dst;
888 struct lcdc_device *lcdc_dev = container_of(dev_drv,
889 struct lcdc_device, driver);
890 struct dvfs_node *gpu_clk = clk_get_dvfs_node("clk_gpu");
892 if (unlikely(!lcdc_dev->clk_on))
896 spin_lock(&lcdc_dev->reg_lock);
897 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
898 m_SCALER_EN | m_SCALER_OUT_ZERO |
900 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(1) |
902 lcdc_cfg_done(lcdc_dev);
903 spin_unlock(&lcdc_dev->reg_lock);
904 if (lcdc_dev->sclk_on) {
905 clk_disable_unprepare(lcdc_dev->sclk);
906 lcdc_dev->sclk_on = false;
909 /* switch pll freq as default when sclk is no used */
910 if (clk_get_rate(lcdc_dev->pll_sclk) != GPU_FREQ_NEED) {
911 dvfs_clk_enable_limit(gpu_clk, GPU_FREQ_MAX_LIMIT,
913 clk_set_rate(lcdc_dev->pll_sclk, GPU_FREQ_NEED);
914 dvfs_clk_enable_limit(gpu_clk, 0, -1);
916 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
921 * rk312x used one lcdc to apply dual disp
922 * hdmi screen is used for scaler src
923 * prmry screen is used for scaler dst
926 src = dev_drv->cur_screen;
928 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
932 if (!lcdc_dev->sclk_on) {
933 clk_prepare_enable(lcdc_dev->sclk);
934 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
935 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
938 dvfs_clk_enable_limit(gpu_clk,
942 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
943 /* cancel limit gpu freq */
944 dvfs_clk_enable_limit(gpu_clk, 0, -1);
946 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
947 lcdc_dev->sclk_on = true;
948 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
949 lcdc_dev->s_pixclock);
952 /* config scale timing */
953 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
954 dst_frame_vst = dst->scl_vst;
955 dst_frame_hst = dst->scl_hst;
957 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
958 dst->mode.xres + dst->mode.right_margin;
959 dsp_hs_end = dst->mode.hsync_len;
961 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
962 dst->mode.yres + dst->mode.lower_margin;
963 dsp_vs_end = dst->mode.vsync_len;
965 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
967 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
968 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
970 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
972 dsp_hact_st = dsp_hbor_st + bor_left;
973 dsp_hact_end = dsp_hbor_end - bor_right;
974 dsp_vact_st = dsp_vbor_st + bor_up;
975 dsp_vact_end = dsp_vbor_end - bor_down;
977 src_w = src->mode.xres;
978 src_h = src->mode.yres;
979 dst_w = dsp_hact_end - dsp_hact_st;
980 dst_h = dsp_vact_end - dsp_vact_st;
982 /* calc scale factor */
983 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
984 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
986 spin_lock(&lcdc_dev->reg_lock);
987 if (dst->color_mode != src->color_mode) {
988 /*dev_drv->output_color = dst->color_mode;
989 if (dev_drv->output_color == COLOR_YCBCR)
990 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
992 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
993 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
994 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
997 lcdc_writel(lcdc_dev, SCALER_FACTOR,
998 v_SCALER_H_FACTOR(scl_h_factor) |
999 v_SCALER_V_FACTOR(scl_v_factor));
1001 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
1002 v_SCALER_FRAME_HST(dst_frame_hst) |
1003 v_SCALER_FRAME_VST(dst_frame_vst));
1004 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
1005 v_SCALER_HS_END(dsp_hs_end) |
1006 v_SCALER_HTOTAL(dsp_htotal));
1007 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
1008 v_SCALER_HAEP(dsp_hact_end) |
1009 v_SCALER_HASP(dsp_hact_st));
1010 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
1011 v_SCALER_VS_END(dsp_vs_end) |
1012 v_SCALER_VTOTAL(dsp_vtotal));
1013 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
1014 v_SCALER_VAEP(dsp_vact_end) |
1015 v_SCALER_VASP(dsp_vact_st));
1016 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
1017 v_SCALER_HBOR_END(dsp_hbor_end) |
1018 v_SCALER_HBOR_ST(dsp_hbor_st));
1019 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
1020 v_SCALER_VBOR_END(dsp_vbor_end) |
1021 v_SCALER_VBOR_ST(dsp_vbor_st));
1022 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1023 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
1024 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
1025 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1026 m_SCALER_EN | m_SCALER_OUT_ZERO |
1028 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) |
1029 v_SCALER_OUT_EN(1));
1031 lcdc_cfg_done(lcdc_dev);
1032 spin_unlock(&lcdc_dev->reg_lock);
1037 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
1038 struct lcdc_device *lcdc_dev)
1041 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1042 if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
1043 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1044 m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1045 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1047 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1048 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1051 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1053 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1054 if (dev_drv->output_color == COLOR_RGB) {
1056 bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1057 if (((bcsh_ctrl&m_BCSH_EN) == 1) ||
1058 (dev_drv->bcsh.enable == 1))/*bcsh enabled*/
1059 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1060 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1061 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1062 else/*bcsh disabled*/
1063 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1064 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1065 v_BCSH_R2Y_EN(0) | v_BCSH_Y2R_EN(0));
1066 } else /* RGB2YUV */
1067 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1069 m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1071 v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1076 static int rk312x_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1077 u16 *yact, int *format, u32 *dsp_addr)
1079 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1080 struct lcdc_device, driver);
1083 spin_lock(&lcdc_dev->reg_lock);
1085 val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1086 *xact = (val & m_ACT_WIDTH)+1;
1087 *yact = ((val & m_ACT_HEIGHT)>>16)+1;
1089 val = lcdc_readl(lcdc_dev, SYS_CTRL);
1091 *format = (val & m_WIN0_FORMAT) >> 3;
1092 *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1094 spin_unlock(&lcdc_dev->reg_lock);
1099 static int rk312x_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1100 int format, u16 xact, u16 yact, u16 xvir)
1102 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1103 struct lcdc_device, driver);
1106 mask = m_WIN0_FORMAT;
1107 val = v_WIN0_FORMAT(format);
1108 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1110 lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR,
1112 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(xact) |
1113 v_ACT_HEIGHT(yact));
1115 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1117 lcdc_cfg_done(lcdc_dev);
1122 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1125 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1126 struct lcdc_device, driver);
1127 struct rk_screen *screen = dev_drv->cur_screen;
1128 u16 right_margin = screen->mode.right_margin;
1129 u16 left_margin = screen->mode.left_margin;
1130 u16 lower_margin = screen->mode.lower_margin;
1131 u16 upper_margin = screen->mode.upper_margin;
1132 u16 x_res = screen->mode.xres;
1133 u16 y_res = screen->mode.yres;
1136 spin_lock(&lcdc_dev->reg_lock);
1137 if (likely(lcdc_dev->clk_on)) {
1138 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1139 m_LCDC_STANDBY, v_LCDC_STANDBY(1));
1140 lcdc_cfg_done(lcdc_dev);
1142 /* Select output color domain */
1143 /*dev_drv->output_color = screen->color_mode;
1144 if (lcdc_dev->soc_type == VOP_RK312X) {
1145 if (dev_drv->output_color == COLOR_YCBCR)
1146 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1148 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1150 dev_drv->output_color = COLOR_RGB;
1151 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1153 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1154 /*something wrong at yuv domain*/
1156 switch (screen->type) {
1158 if (lcdc_dev->soc_type == VOP_RK312X) {
1159 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1160 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1161 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1165 if (lcdc_dev->soc_type == VOP_RK312X) {
1166 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1167 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1168 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1172 if (lcdc_dev->soc_type == VOP_RK312X) {
1173 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1174 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1175 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1179 mask = m_HDMI_DCLK_EN;
1180 val = v_HDMI_DCLK_EN(1);
1181 if (screen->pixelrepeat) {
1182 mask |= m_CORE_CLK_DIV_EN;
1183 val |= v_CORE_CLK_DIV_EN(1);
1185 mask |= m_CORE_CLK_DIV_EN;
1186 val |= v_CORE_CLK_DIV_EN(0);
1188 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1189 if (lcdc_dev->soc_type == VOP_RK312X) {
1190 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1192 v_SW_UV_OFFSET_EN(0));
1193 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1195 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1196 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1197 v_HDMI_DEN_POL(screen->pin_den);
1198 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1200 mask = (1 << 4) | (1 << 5) | (1 << 6);
1201 val = (screen->pin_hsync << 4) |
1202 (screen->pin_vsync << 5) |
1203 (screen->pin_den << 6);
1204 grf_writel(RK3036_GRF_SOC_CON2,
1205 (mask << 16) | val);
1207 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1210 case SCREEN_TVOUT_TEST:
1211 mask = m_TVE_DAC_DCLK_EN;
1212 val = v_TVE_DAC_DCLK_EN(1);
1213 if (screen->pixelrepeat) {
1214 mask |= m_CORE_CLK_DIV_EN;
1215 val |= v_CORE_CLK_DIV_EN(1);
1217 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1218 if (x_res == 720 && y_res == 576)
1219 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1220 v_TVE_MODE(TV_PAL));
1221 else if (x_res == 720 && y_res == 480)
1222 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1223 v_TVE_MODE(TV_NTSC));
1225 dev_err(lcdc_dev->dev,
1226 "unsupported video timing!\n");
1229 if (lcdc_dev->soc_type == VOP_RK312X) {
1230 if (screen->type == SCREEN_TVOUT_TEST)
1231 /*for TVE index test,vop must ovarlay at yuv domain*/
1232 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1233 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1235 v_SW_UV_OFFSET_EN(1));
1237 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1241 dev_err(lcdc_dev->dev, "un supported interface!\n");
1244 if (lcdc_dev->soc_type == VOP_RK312X) {
1245 switch (dev_drv->screen0->face) {
1248 mask = m_DITHER_DOWN_EN |
1249 m_DITHER_DOWN_MODE |
1251 val = v_DITHER_DOWN_EN(1) |
1252 v_DITHER_DOWN_MODE(0) |
1253 v_DITHER_DOWN_SEL(1);
1254 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1258 mask = m_DITHER_DOWN_EN |
1259 m_DITHER_DOWN_MODE |
1261 val = v_DITHER_DOWN_EN(1) |
1262 v_DITHER_DOWN_MODE(1) |
1263 v_DITHER_DOWN_SEL(1);
1264 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1268 mask = m_DITHER_DOWN_EN |
1269 m_DITHER_DOWN_MODE |
1271 val = v_DITHER_DOWN_EN(1) |
1272 v_DITHER_DOWN_MODE(0) |
1273 v_DITHER_DOWN_SEL(1);
1274 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1278 mask = m_DITHER_DOWN_EN |
1279 m_DITHER_DOWN_MODE |
1281 val = v_DITHER_DOWN_EN(1) |
1282 v_DITHER_DOWN_MODE(1) |
1283 v_DITHER_DOWN_SEL(1);
1284 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1288 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1289 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1290 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1293 dev_err(lcdc_dev->dev, "un supported interface!\n");
1296 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1297 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1300 mask = m_HSYNC_POL | m_VSYNC_POL |
1301 m_DEN_POL | m_DCLK_POL;
1302 val = v_HSYNC_POL(screen->pin_hsync) |
1303 v_VSYNC_POL(screen->pin_vsync) |
1304 v_DEN_POL(screen->pin_den) |
1305 v_DCLK_POL(screen->pin_dclk);
1307 if (screen->type != SCREEN_HDMI) {
1308 mask |= m_DSP_OUT_FORMAT;
1309 val |= v_DSP_OUT_FORMAT(face);
1312 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1314 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1315 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1316 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1318 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1319 v_DSP_RB_SWAP(screen->swap_rb) |
1320 v_DSP_RG_SWAP(screen->swap_rg) |
1321 v_DSP_DELTA_SWAP(screen->swap_delta) |
1322 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1323 v_BLANK_EN(0) | v_BLACK_EN(0);
1324 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1327 val = v_HSYNC(screen->mode.hsync_len) |
1328 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1330 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1331 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1332 v_HASP(screen->mode.hsync_len + left_margin);
1333 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1335 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1336 /* First Field Timing */
1337 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1338 v_VSYNC(screen->mode.vsync_len) |
1339 v_VERPRD(2 * (screen->mode.vsync_len +
1341 lower_margin) + y_res + 1));
1342 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1343 v_VAEP(screen->mode.vsync_len +
1344 upper_margin + y_res / 2) |
1345 v_VASP(screen->mode.vsync_len +
1347 /* Second Field Timing */
1348 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1349 v_VSYNC_ST_F1(screen->mode.vsync_len +
1350 upper_margin + y_res / 2 +
1352 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1353 upper_margin + y_res / 2 +
1355 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1356 v_VAEP(2 * (screen->mode.vsync_len +
1358 y_res + lower_margin + 1) |
1359 v_VASP(2 * (screen->mode.vsync_len +
1361 y_res / 2 + lower_margin + 1));
1363 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1364 m_INTERLACE_DSP_EN |
1365 m_WIN0_YRGB_DEFLICK_EN |
1366 m_WIN0_CBR_DEFLICK_EN |
1367 m_INTERLACE_FIELD_POL |
1368 m_WIN0_INTERLACE_EN |
1369 m_WIN1_INTERLACE_EN,
1370 v_INTERLACE_DSP_EN(1) |
1371 v_WIN0_YRGB_DEFLICK_EN(1) |
1372 v_WIN0_CBR_DEFLICK_EN(1) |
1373 v_INTERLACE_FIELD_POL(0) |
1374 v_WIN0_INTERLACE_EN(1) |
1375 v_WIN1_INTERLACE_EN(1));
1376 mask = m_LF_INT_NUM;
1377 val = v_LF_INT_NUM(screen->mode.vsync_len +
1378 screen->mode.upper_margin +
1379 screen->mode.yres/2);
1380 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1382 val = v_VSYNC(screen->mode.vsync_len) |
1383 v_VERPRD(screen->mode.vsync_len + upper_margin +
1384 y_res + lower_margin);
1385 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1387 val = v_VAEP(screen->mode.vsync_len +
1388 upper_margin + y_res) |
1389 v_VASP(screen->mode.vsync_len + upper_margin);
1390 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1392 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1393 m_INTERLACE_DSP_EN |
1394 m_WIN0_YRGB_DEFLICK_EN |
1395 m_WIN0_CBR_DEFLICK_EN |
1396 m_INTERLACE_FIELD_POL |
1397 m_WIN0_INTERLACE_EN |
1398 m_WIN1_INTERLACE_EN,
1399 v_INTERLACE_DSP_EN(0) |
1400 v_WIN0_YRGB_DEFLICK_EN(0) |
1401 v_WIN0_CBR_DEFLICK_EN(0) |
1402 v_INTERLACE_FIELD_POL(0) |
1403 v_WIN0_INTERLACE_EN(0) |
1404 v_WIN1_INTERLACE_EN(0));
1405 mask = m_LF_INT_NUM;
1406 val = v_LF_INT_NUM(screen->mode.vsync_len +
1407 screen->mode.upper_margin +
1409 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1412 spin_unlock(&lcdc_dev->reg_lock);
1413 rk312x_lcdc_set_dclk(dev_drv, 1);
1414 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY, v_LCDC_STANDBY(0));
1415 lcdc_cfg_done(lcdc_dev);
1416 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1417 dev_drv->trsm_ops->enable();
1424 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1427 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1428 struct lcdc_device, driver);
1430 /* enable clk,when first layer open */
1431 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1432 rockchip_set_system_status(SYS_STATUS_LCDC0);
1433 rk312x_lcdc_pre_init(dev_drv);
1434 rk312x_lcdc_clk_enable(lcdc_dev);
1435 #if defined(CONFIG_ROCKCHIP_IOMMU)
1436 if (dev_drv->iommu_enabled) {
1437 if (!dev_drv->mmu_dev) {
1439 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1440 if (dev_drv->mmu_dev) {
1441 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1444 dev_err(dev_drv->dev,
1445 "failed to get rockchip iommu device\n");
1449 /*if (dev_drv->mmu_dev)
1450 rockchip_iovmm_activate(dev_drv->dev);*/
1453 rk312x_lcdc_reg_restore(lcdc_dev);
1454 /*if (dev_drv->iommu_enabled)
1455 rk312x_lcdc_mmu_en(dev_drv);*/
1456 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1457 rk312x_lcdc_set_dclk(dev_drv, 0);
1458 rk312x_lcdc_enable_irq(dev_drv);
1460 rk312x_load_screen(dev_drv, 1);
1463 /* set screen lut */
1464 if (dev_drv->cur_screen->dsp_lut)
1465 rk312x_lcdc_set_lut(dev_drv,
1466 dev_drv->cur_screen->dsp_lut);
1469 if (win_id < ARRAY_SIZE(lcdc_win))
1470 lcdc_layer_enable(lcdc_dev, win_id, open);
1472 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1474 /* when all layer closed,disable clk */
1475 /* if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1476 rk312x_lcdc_disable_irq(lcdc_dev);
1477 rk312x_lcdc_reg_update(dev_drv);
1478 #if defined(CONFIG_ROCKCHIP_IOMMU)
1479 if (dev_drv->iommu_enabled) {
1480 if (dev_drv->mmu_dev)
1481 rockchip_iovmm_deactivate(dev_drv->dev);
1484 rk312x_lcdc_clk_disable(lcdc_dev);
1485 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1490 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1492 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1493 struct lcdc_device, driver);
1494 struct rk_screen *screen = dev_drv->cur_screen;
1495 struct rk_lcdc_win *win = NULL;
1496 char fmt[9] = "NULL";
1499 dev_err(dev_drv->dev, "screen is null!\n");
1504 win = dev_drv->win[0];
1505 } else if (win_id == 1) {
1506 win = dev_drv->win[1];
1507 } else if (win_id == 2) {
1508 win = dev_drv->win[2];
1510 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1514 spin_lock(&lcdc_dev->reg_lock);
1515 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1516 screen->mode.hsync_len;
1517 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1518 win->area[0].ysize /= 2;
1519 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1520 screen->mode.upper_margin +
1521 screen->mode.vsync_len;
1523 win->area[0].dsp_sty = win->area[0].ypos +
1524 screen->mode.upper_margin +
1525 screen->mode.vsync_len;
1527 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1528 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1530 switch (win->area[0].format) {
1532 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1533 win->area[0].swap_rb = 0;
1536 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1537 win->area[0].swap_rb = 1;
1540 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1541 win->area[0].swap_rb = 1;
1544 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1545 win->area[0].swap_rb = 0;
1548 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1549 win->area[0].swap_rb = 0;
1553 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1555 CalScale(win->area[0].xact, win->area[0].xsize);
1557 CalScale(win->area[0].yact, win->area[0].ysize);
1558 win->area[0].swap_rb = 0;
1560 dev_err(lcdc_dev->driver.dev,
1561 "%s:un supported format!\n", __func__);
1566 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1567 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1568 win->area[0].xsize);
1570 CalScale(win->area[0].yact, win->area[0].ysize);
1571 win->area[0].swap_rb = 0;
1573 dev_err(lcdc_dev->driver.dev,
1574 "%s:un supported format!\n", __func__);
1579 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1581 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1583 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1584 win->area[0].swap_rb = 0;
1586 dev_err(lcdc_dev->driver.dev,
1587 "%s:un supported format!\n", __func__);
1591 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1595 spin_unlock(&lcdc_dev->reg_lock);
1598 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1599 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1600 get_format_string(win->area[0].format, fmt), win->area[0].xact,
1601 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1602 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1607 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1609 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1610 struct lcdc_device, driver);
1611 struct rk_lcdc_win *win = NULL;
1612 struct rk_screen *screen = dev_drv->cur_screen;
1615 dev_err(dev_drv->dev, "screen is null!\n");
1620 win = dev_drv->win[0];
1621 } else if (win_id == 1) {
1622 win = dev_drv->win[1];
1623 } else if (win_id == 2) {
1624 win = dev_drv->win[2];
1626 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1630 spin_lock(&lcdc_dev->reg_lock);
1631 if (likely(lcdc_dev->clk_on)) {
1632 win->area[0].y_addr =
1633 win->area[0].smem_start + win->area[0].y_offset;
1634 win->area[0].uv_addr =
1635 win->area[0].cbr_start + win->area[0].c_offset;
1636 if (win->area[0].y_addr)
1637 lcdc_layer_update_regs(lcdc_dev, win);
1638 /* lcdc_cfg_done(lcdc_dev); */
1640 spin_unlock(&lcdc_dev->reg_lock);
1642 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1643 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1644 win->area[0].y_offset);
1645 /* this is the first frame of the system,enable frame start interrupt */
1646 if ((dev_drv->first_frame)) {
1647 dev_drv->first_frame = 0;
1648 rk312x_lcdc_enable_irq(dev_drv);
1654 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1655 unsigned long arg, int win_id)
1657 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1658 struct lcdc_device, driver);
1660 void __user *argp = (void __user *)arg;
1661 struct color_key_cfg clr_key_cfg;
1664 case RK_FBIOGET_PANEL_SIZE:
1665 panel_size[0] = lcdc_dev->screen->mode.xres;
1666 panel_size[1] = lcdc_dev->screen->mode.yres;
1667 if (copy_to_user(argp, panel_size, 8))
1670 case RK_FBIOPUT_COLOR_KEY_CFG:
1671 if (copy_from_user(&clr_key_cfg, argp,
1672 sizeof(struct color_key_cfg)))
1674 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1675 clr_key_cfg.win0_color_key_cfg);
1676 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1677 clr_key_cfg.win1_color_key_cfg);
1686 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1691 mutex_lock(&dev_drv->fb_win_id_mutex);
1692 if (!strcmp(id, "fb0"))
1693 win_id = dev_drv->fb0_win_id;
1694 else if (!strcmp(id, "fb1"))
1695 win_id = dev_drv->fb1_win_id;
1696 else if (!strcmp(id, "fb2"))
1697 win_id = dev_drv->fb2_win_id;
1698 mutex_unlock(&dev_drv->fb_win_id_mutex);
1703 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1708 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1711 struct lcdc_device *lcdc_dev =
1712 container_of(dev_drv, struct lcdc_device, driver);
1715 spin_lock(&lcdc_dev->reg_lock);
1716 if (lcdc_dev->clk_on) {
1718 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1722 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1727 spin_unlock(&lcdc_dev->reg_lock);
1732 static int rk312x_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1734 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1735 struct lcdc_device, driver);
1736 struct device_node *backlight;
1738 if (lcdc_dev->backlight)
1741 backlight = of_parse_phandle(lcdc_dev->dev->of_node,
1744 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
1745 if (!lcdc_dev->backlight)
1746 dev_info(lcdc_dev->dev, "No find backlight device\n");
1748 dev_info(lcdc_dev->dev, "No find backlight device node\n");
1754 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1756 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1757 struct lcdc_device, driver);
1758 if (dev_drv->suspend_flag)
1761 /* close the backlight */
1762 rk312x_lcdc_get_backlight_device(dev_drv);
1763 if (lcdc_dev->backlight) {
1764 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
1765 backlight_update_status(lcdc_dev->backlight);
1768 dev_drv->suspend_flag = 1;
1769 flush_kthread_worker(&dev_drv->update_regs_worker);
1771 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1772 dev_drv->trsm_ops->disable();
1773 spin_lock(&lcdc_dev->reg_lock);
1774 if (likely(lcdc_dev->clk_on)) {
1775 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1776 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1777 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1778 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1779 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1781 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1783 lcdc_cfg_done(lcdc_dev);
1785 if (dev_drv->iommu_enabled) {
1786 if (dev_drv->mmu_dev)
1787 rockchip_iovmm_deactivate(dev_drv->dev);
1790 spin_unlock(&lcdc_dev->reg_lock);
1792 spin_unlock(&lcdc_dev->reg_lock);
1795 rk312x_lcdc_clk_disable(lcdc_dev);
1796 rk_disp_pwr_disable(dev_drv);
1800 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1802 struct lcdc_device *lcdc_dev =
1803 container_of(dev_drv, struct lcdc_device, driver);
1805 if (!dev_drv->suspend_flag)
1807 rk_disp_pwr_enable(dev_drv);
1809 rk312x_lcdc_clk_enable(lcdc_dev);
1810 rk312x_lcdc_reg_restore(lcdc_dev);
1812 /* config for the FRC mode of dither down */
1813 if (dev_drv->cur_screen &&
1814 dev_drv->cur_screen->face != OUT_P888) {
1815 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1816 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1817 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1818 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1819 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1820 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1823 /* set screen lut */
1824 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1825 rk312x_lcdc_set_lut(dev_drv,
1826 dev_drv->cur_screen->dsp_lut);
1828 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1830 spin_lock(&lcdc_dev->reg_lock);
1832 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1834 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1836 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1837 lcdc_cfg_done(lcdc_dev);
1839 if (dev_drv->iommu_enabled) {
1840 if (dev_drv->mmu_dev)
1841 rockchip_iovmm_activate(dev_drv->dev);
1844 spin_unlock(&lcdc_dev->reg_lock);
1845 dev_drv->suspend_flag = 0;
1847 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1848 dev_drv->trsm_ops->enable();
1854 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1855 int win_id, int blank_mode)
1857 switch (blank_mode) {
1858 case FB_BLANK_UNBLANK:
1859 rk312x_lcdc_early_resume(dev_drv);
1861 case FB_BLANK_NORMAL:
1862 rk312x_lcdc_early_suspend(dev_drv);
1865 rk312x_lcdc_early_suspend(dev_drv);
1869 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1874 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1876 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1877 struct lcdc_device, driver);
1879 struct rk_lcdc_win *win = NULL;
1881 spin_lock(&lcdc_dev->reg_lock);
1882 if (lcdc_dev->clk_on) {
1883 for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
1884 win = dev_drv->win[i];
1885 if ((win->state == 0) && (win->last_state == 1))
1886 lcdc_layer_update_regs(lcdc_dev, win);
1887 win->last_state = win->state;
1889 lcdc_cfg_done(lcdc_dev);
1891 spin_unlock(&lcdc_dev->reg_lock);
1897 sin_hue = sin(a)*256 +0x100;
1898 cos_hue = cos(a)*256;
1900 sin_hue = sin(a)*256;
1901 cos_hue = cos(a)*256;
1903 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1906 struct lcdc_device *lcdc_dev =
1907 container_of(dev_drv, struct lcdc_device, driver);
1910 spin_lock(&lcdc_dev->reg_lock);
1911 if (lcdc_dev->clk_on) {
1912 val = lcdc_readl(lcdc_dev, BCSH_H);
1915 val &= m_BCSH_SIN_HUE;
1918 val &= m_BCSH_COS_HUE;
1925 spin_unlock(&lcdc_dev->reg_lock);
1930 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
1933 struct lcdc_device *lcdc_dev =
1934 container_of(dev_drv, struct lcdc_device, driver);
1937 spin_lock(&lcdc_dev->reg_lock);
1938 if (lcdc_dev->clk_on) {
1939 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1940 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1941 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1942 lcdc_cfg_done(lcdc_dev);
1944 spin_unlock(&lcdc_dev->reg_lock);
1949 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1950 bcsh_bcs_mode mode, int value)
1952 struct lcdc_device *lcdc_dev =
1953 container_of(dev_drv, struct lcdc_device, driver);
1956 spin_lock(&lcdc_dev->reg_lock);
1957 if (lcdc_dev->clk_on) {
1960 /* from 0 to 255,typical is 128 */
1963 else if (value >= 0x80)
1964 value = value - 0x80;
1965 mask = m_BCSH_BRIGHTNESS;
1966 val = v_BCSH_BRIGHTNESS(value);
1969 /* from 0 to 510,typical is 256 */
1970 mask = m_BCSH_CONTRAST;
1971 val = v_BCSH_CONTRAST(value);
1974 /* from 0 to 1015,typical is 256 */
1975 mask = m_BCSH_SAT_CON;
1976 val = v_BCSH_SAT_CON(value);
1981 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
1982 lcdc_cfg_done(lcdc_dev);
1984 spin_unlock(&lcdc_dev->reg_lock);
1988 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1991 struct lcdc_device *lcdc_dev =
1992 container_of(dev_drv, struct lcdc_device, driver);
1995 spin_lock(&lcdc_dev->reg_lock);
1996 if (lcdc_dev->clk_on) {
1997 val = lcdc_readl(lcdc_dev, BCSH_BCS);
2000 val &= m_BCSH_BRIGHTNESS;
2007 val &= m_BCSH_CONTRAST;
2011 val &= m_BCSH_SAT_CON;
2018 spin_unlock(&lcdc_dev->reg_lock);
2022 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2024 struct lcdc_device *lcdc_dev =
2025 container_of(dev_drv, struct lcdc_device, driver);
2027 if (dev_drv->bcsh_init_status && open) {
2028 dev_drv->bcsh_init_status = 0;
2031 spin_lock(&lcdc_dev->reg_lock);
2032 if (lcdc_dev->clk_on) {
2034 lcdc_msk_reg(lcdc_dev,
2035 BCSH_CTRL, m_BCSH_EN | m_BCSH_OUT_MODE,
2036 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
2037 lcdc_writel(lcdc_dev, BCSH_BCS,
2038 v_BCSH_BRIGHTNESS(0x00) |
2039 v_BCSH_CONTRAST(0x80) |
2040 v_BCSH_SAT_CON(0x80));
2041 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
2042 dev_drv->bcsh.enable = 1;
2046 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
2047 dev_drv->bcsh.enable = 0;
2049 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
2050 lcdc_cfg_done(lcdc_dev);
2053 spin_unlock(&lcdc_dev->reg_lock);
2057 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2059 struct rk_lcdc_win_area area;
2060 int fb2_win_id, fb1_win_id, fb0_win_id;
2062 mutex_lock(&dev_drv->fb_win_id_mutex);
2063 if (order == FB_DEFAULT_ORDER)
2064 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
2066 fb2_win_id = order / 100;
2067 fb1_win_id = (order / 10) % 10;
2068 fb0_win_id = order % 10;
2070 if (fb0_win_id != dev_drv->fb0_win_id) {
2071 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
2072 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
2073 dev_drv->win[fb0_win_id]->area[0];
2074 dev_drv->win[fb0_win_id]->area[0] = area;
2075 dev_drv->fb0_win_id = fb0_win_id;
2077 dev_drv->fb1_win_id = fb1_win_id;
2078 dev_drv->fb2_win_id = fb2_win_id;
2080 mutex_unlock(&dev_drv->fb_win_id_mutex);
2085 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2088 struct lcdc_device *lcdc_dev =
2089 container_of(dev_drv, struct lcdc_device, driver);
2090 struct rk_screen *screen = dev_drv->cur_screen;
2095 u32 x_total, y_total;
2098 ft = div_u64(1000000000000llu, fps);
2100 screen->mode.upper_margin + screen->mode.lower_margin +
2101 screen->mode.yres + screen->mode.vsync_len;
2103 screen->mode.left_margin + screen->mode.right_margin +
2104 screen->mode.xres + screen->mode.hsync_len;
2105 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2106 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2107 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2110 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2111 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2112 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2113 screen->ft = 1000 / fps; /*one frame time in ms */
2116 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2117 clk_get_rate(lcdc_dev->dclk), fps);
2122 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
2125 struct lcdc_device *lcdc_dev =
2126 container_of(dev_drv,
2127 struct lcdc_device, driver);
2129 enable_irq(lcdc_dev->irq);
2131 disable_irq(lcdc_dev->irq);
2135 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2137 struct lcdc_device *lcdc_dev =
2138 container_of(dev_drv, struct lcdc_device, driver);
2142 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
2143 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
2144 if (int_reg & m_LF_INT_STA) {
2145 dev_drv->frame_time.last_framedone_t =
2146 dev_drv->frame_time.framedone_t;
2147 dev_drv->frame_time.framedone_t = cpu_clock(0);
2148 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
2150 ret = RK_LF_STATUS_FC;
2152 ret = RK_LF_STATUS_FR;
2155 ret = RK_LF_STATUS_NC;
2161 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2162 unsigned int *dsp_addr)
2164 struct lcdc_device *lcdc_dev =
2165 container_of(dev_drv, struct lcdc_device, driver);
2167 if (lcdc_dev->clk_on) {
2168 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2169 if (lcdc_dev->soc_type == VOP_RK3036)
2170 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
2171 else if (lcdc_dev->soc_type == VOP_RK312X)
2172 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2177 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2178 char *buf, int win_id)
2180 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
2182 char format_w0[9] = "NULL";
2183 char format_w1[9] = "NULL";
2184 char status_w0[9] = "NULL";
2185 char status_w1[9] = "NULL";
2186 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
2187 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
2188 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
2189 u16 x_factor, y_factor, x_scale, y_scale;
2191 u32 win1_dsp_yaddr = 0;
2193 spin_lock(&lcdc_dev->reg_lock);
2194 if (lcdc_dev->clk_on) {
2196 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2197 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2198 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2201 if (fmt_id & m_WIN0_EN)
2202 strcpy(status_w0, "enabled");
2204 strcpy(status_w0, "disabled");
2206 if ((fmt_id & m_WIN1_EN) >> 1)
2207 strcpy(status_w1, "enabled");
2209 strcpy(status_w1, "disabled");
2212 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2215 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2216 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2219 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2220 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2221 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2223 if (lcdc_dev->soc_type == VOP_RK3036) {
2224 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2225 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2226 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2227 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2228 /* rk312x unsupport win1 scaler,so have no act info */
2234 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2235 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2236 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2238 if (lcdc_dev->soc_type == VOP_RK3036)
2239 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2240 else if (lcdc_dev->soc_type == VOP_RK312X)
2241 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2242 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2243 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2246 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2247 x_st_w0 = dsp_st & m_DSP_STX;
2248 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2250 if (lcdc_dev->soc_type == VOP_RK3036)
2251 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2252 else if (lcdc_dev->soc_type == VOP_RK312X)
2253 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2255 x_st_w1 = dsp_st & m_DSP_STX;
2256 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2259 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2260 x_factor = factor & m_X_SCL_FACTOR;
2261 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2262 x_scale = 4096 * 100 / x_factor;
2263 y_scale = 4096 * 100 / y_factor;
2266 if (lcdc_dev->soc_type == VOP_RK3036)
2267 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2268 else if (lcdc_dev->soc_type == VOP_RK312X)
2269 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2271 spin_unlock(&lcdc_dev->reg_lock);
2274 spin_unlock(&lcdc_dev->reg_lock);
2275 return snprintf(buf, PAGE_SIZE,
2287 "YRGB buffer addr:0x%08x\n"
2288 "CBR buffer addr:0x%08x\n\n"
2298 "YRGB buffer addr:0x%08x\n"
2313 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2314 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2325 ovl ? "win0 on the top of win1\n" :
2326 "win1 on the top of win0\n");
2329 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2331 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2334 int *cbase = (int *)lcdc_dev->regs;
2335 int *regsbak = (int *)lcdc_dev->regsbak;
2338 pr_info("back up reg:\n");
2339 for (i = 0; i <= (0xDC >> 4); i++) {
2340 for (j = 0; j < 4; j++)
2341 pr_info("%08x ", *(regsbak + i * 4 + j));
2345 pr_info("lcdc reg:\n");
2346 for (i = 0; i <= (0xDC >> 4); i++) {
2347 for (j = 0; j < 4; j++)
2348 pr_info("%08x ", readl_relaxed(cbase + i * 4 + j));
2354 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2356 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2357 struct lcdc_device, driver);
2358 if (lcdc_dev->soc_type == VOP_RK312X) {
2359 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2360 v_DIRECT_PATH_EN(open));
2361 lcdc_cfg_done(lcdc_dev);
2366 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2368 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2369 struct lcdc_device, driver);
2371 if (lcdc_dev->soc_type == VOP_RK312X) {
2372 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2373 v_DIRECT_PATH_LAYER(win_id));
2374 lcdc_cfg_done(lcdc_dev);
2379 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2381 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2382 struct lcdc_device, driver);
2385 if (lcdc_dev->soc_type == VOP_RK312X)
2386 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2391 static int rk312x_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2393 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2394 struct lcdc_device, driver);
2396 rk312x_lcdc_get_backlight_device(dev_drv);
2399 /* close the backlight */
2400 if (lcdc_dev->backlight) {
2401 lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
2402 backlight_update_status(lcdc_dev->backlight);
2405 spin_lock(&lcdc_dev->reg_lock);
2406 if (likely(lcdc_dev->clk_on)) {
2407 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2409 lcdc_cfg_done(lcdc_dev);
2411 spin_unlock(&lcdc_dev->reg_lock);
2413 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2414 dev_drv->trsm_ops->disable();
2416 spin_lock(&lcdc_dev->reg_lock);
2417 if (likely(lcdc_dev->clk_on)) {
2418 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2420 lcdc_cfg_done(lcdc_dev);
2422 spin_unlock(&lcdc_dev->reg_lock);
2423 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2424 dev_drv->trsm_ops->enable();
2426 /* open the backlight */
2427 if (lcdc_dev->backlight) {
2428 lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
2429 backlight_update_status(lcdc_dev->backlight);
2437 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2438 .open = rk312x_lcdc_open,
2439 .load_screen = rk312x_load_screen,
2440 .get_dspbuf_info = rk312x_get_dspbuf_info,
2441 .post_dspbuf = rk312x_post_dspbuf,
2442 .set_par = rk312x_lcdc_set_par,
2443 .pan_display = rk312x_lcdc_pan_display,
2444 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2445 .blank = rk312x_lcdc_blank,
2446 .ioctl = rk312x_lcdc_ioctl,
2447 .get_win_state = rk312x_lcdc_get_win_state,
2448 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2449 .get_disp_info = rk312x_lcdc_get_disp_info,
2450 .fps_mgr = rk312x_lcdc_fps_mgr,
2451 .fb_get_win_id = rk312x_lcdc_get_win_id,
2452 .fb_win_remap = rk312x_fb_win_remap,
2453 .poll_vblank = rk312x_lcdc_poll_vblank,
2454 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2455 .cfg_done = rk312x_lcdc_cfg_done,
2456 .dump_reg = rk312x_lcdc_reg_dump,
2457 .dpi_open = rk312x_lcdc_dpi_open,
2458 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2459 .dpi_status = rk312x_lcdc_dpi_status,
2460 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2461 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2462 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2463 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2464 .open_bcsh = rk312x_lcdc_open_bcsh,
2465 .set_screen_scaler = rk312x_lcdc_set_scaler,
2466 .set_dsp_lut = rk312x_lcdc_set_lut,
2467 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2468 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2469 .dsp_black = rk312x_lcdc_dsp_black,
2470 .mmu_en = rk312x_lcdc_mmu_en,
2473 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2474 .soc_type = VOP_RK3036,
2477 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2478 .soc_type = VOP_RK312X,
2481 #if defined(CONFIG_OF)
2482 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2485 .compatible = "rockchip,rk3036-lcdc",
2486 .data = (void *)&rk3036_lcdc_drvdata,
2490 .compatible = "rockchip,rk312x-lcdc",
2491 .data = (void *)&rk312x_lcdc_drvdata,
2496 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2498 struct device_node *np = lcdc_dev->dev->of_node;
2499 const struct of_device_id *match;
2500 const struct rk_lcdc_drvdata *lcdc_drvdata;
2503 #if defined(CONFIG_ROCKCHIP_IOMMU)
2504 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2505 lcdc_dev->driver.iommu_enabled = 0;
2507 lcdc_dev->driver.iommu_enabled = val;
2509 lcdc_dev->driver.iommu_enabled = 0;
2512 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2513 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2515 lcdc_dev->driver.fb_win_map = val;
2517 match = of_match_node(rk312x_lcdc_dt_ids, np);
2519 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2520 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2522 return PTR_ERR(match);
2528 static int rk312x_lcdc_probe(struct platform_device *pdev)
2530 struct lcdc_device *lcdc_dev = NULL;
2531 struct rk_lcdc_driver *dev_drv;
2532 struct device *dev = &pdev->dev;
2533 struct resource *res;
2536 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2538 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2541 platform_set_drvdata(pdev, lcdc_dev);
2542 lcdc_dev->dev = dev;
2543 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2544 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2548 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2549 lcdc_dev->reg_phy_base = res->start;
2550 lcdc_dev->len = resource_size(res);
2551 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2552 if (IS_ERR(lcdc_dev->regs)) {
2553 ret = PTR_ERR(lcdc_dev->regs);
2557 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2558 if (IS_ERR(lcdc_dev->regsbak)) {
2559 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2560 ret = PTR_ERR(lcdc_dev->regsbak);
2563 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2564 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2565 lcdc_dev->prop = PRMRY;
2566 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2567 dev_drv = &lcdc_dev->driver;
2569 dev_drv->prop = lcdc_dev->prop;
2570 dev_drv->id = lcdc_dev->id;
2571 dev_drv->ops = &lcdc_drv_ops;
2572 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2573 spin_lock_init(&lcdc_dev->reg_lock);
2575 lcdc_dev->irq = platform_get_irq(pdev, 0);
2576 if (lcdc_dev->irq < 0) {
2577 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2580 goto err_request_irq;
2583 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2584 IRQF_DISABLED | IRQF_SHARED,
2585 dev_name(dev), lcdc_dev);
2587 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2588 lcdc_dev->irq, ret);
2589 goto err_request_irq;
2592 if (dev_drv->iommu_enabled)
2593 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2595 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2597 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2598 goto err_register_fb;
2600 lcdc_dev->screen = dev_drv->screen0;
2602 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2603 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2608 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2611 devm_kfree(&pdev->dev, lcdc_dev);
2615 #if defined(CONFIG_PM)
2616 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2621 static int rk312x_lcdc_resume(struct platform_device *pdev)
2626 #define rk312x_lcdc_suspend NULL
2627 #define rk312x_lcdc_resume NULL
2630 static int rk312x_lcdc_remove(struct platform_device *pdev)
2635 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2637 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2638 struct rk_lcdc_driver *dev_drv=&lcdc_dev->driver;
2640 flush_kthread_worker(&dev_drv->update_regs_worker);
2641 kthread_stop(dev_drv->update_regs_thread);
2643 rk312x_lcdc_deinit(lcdc_dev);
2644 rk312x_lcdc_clk_disable(lcdc_dev);
2645 rk_disp_pwr_disable(&lcdc_dev->driver);
2648 static struct platform_driver rk312x_lcdc_driver = {
2649 .probe = rk312x_lcdc_probe,
2650 .remove = rk312x_lcdc_remove,
2652 .name = "rk312x-lcdc",
2653 .owner = THIS_MODULE,
2654 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2656 .suspend = rk312x_lcdc_suspend,
2657 .resume = rk312x_lcdc_resume,
2658 .shutdown = rk312x_lcdc_shutdown,
2661 static int __init rk312x_lcdc_module_init(void)
2663 return platform_driver_register(&rk312x_lcdc_driver);
2666 static void __exit rk312x_lcdc_module_exit(void)
2668 platform_driver_unregister(&rk312x_lcdc_driver);
2671 fs_initcall(rk312x_lcdc_module_init);
2672 module_exit(rk312x_lcdc_module_exit);