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 |
421 val = v_WIN0_EN(win->state) |
422 v_WIN0_FORMAT(win->area[0].fmt_cfg) |
423 v_WIN0_RB_SWAP(win->area[0].swap_rb) |
424 v_WIN0_UV_SWAP(win->area[0].swap_uv);
425 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
426 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
427 v_X_SCL_FACTOR(win->scale_yrgb_x) |
428 v_Y_SCL_FACTOR(win->scale_yrgb_y));
429 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
430 v_X_SCL_FACTOR(win->scale_cbcr_x) |
431 v_Y_SCL_FACTOR(win->scale_cbcr_y));
433 lcdc_msk_reg(lcdc_dev, WIN0_VIR,
434 m_YRGB_VIR | m_CBBR_VIR,
435 v_YRGB_VIR(win->area[0].y_vir_stride) |
436 v_CBCR_VIR(win->area[0].uv_vir_stride));
437 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
438 v_ACT_WIDTH(win->area[0].xact) |
439 v_ACT_HEIGHT(win->area[0].yact));
440 lcdc_writel(lcdc_dev, WIN0_DSP_ST,
441 v_DSP_STX(win->area[0].dsp_stx) |
442 v_DSP_STY(win->area[0].dsp_sty));
443 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
444 v_DSP_WIDTH(win->area[0].xsize) |
445 v_DSP_HEIGHT(win->area[0].ysize));
447 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
448 win->area[0].y_addr);
449 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
450 win->area[0].uv_addr);
451 } else if (win->id == 1) {
452 mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
453 val = v_WIN1_EN(win->state) |
454 v_WIN1_FORMAT(win->area[0].fmt_cfg) |
455 v_WIN1_RB_SWAP(win->area[0].swap_rb);
456 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
457 /* rk312x unsupport win1 scale */
458 if (lcdc_dev->soc_type == VOP_RK3036) {
459 lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
460 v_X_SCL_FACTOR(win->scale_yrgb_x) |
461 v_Y_SCL_FACTOR(win->scale_yrgb_y));
462 lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
463 v_ACT_WIDTH(win->area[0].xact) |
464 v_ACT_HEIGHT(win->area[0].yact));
465 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
466 v_DSP_WIDTH(win->area[0].xsize) |
467 v_DSP_HEIGHT(win->area[0].ysize));
468 lcdc_writel(lcdc_dev, WIN1_DSP_ST,
469 v_DSP_STX(win->area[0].dsp_stx) |
470 v_DSP_STY(win->area[0].dsp_sty));
471 lcdc_writel(lcdc_dev,
472 WIN1_MST, win->area[0].y_addr);
474 lcdc_writel(lcdc_dev, WIN1_DSP_INFO_RK312X,
475 v_DSP_WIDTH(win->area[0].xsize) |
476 v_DSP_HEIGHT(win->area[0].ysize));
477 lcdc_writel(lcdc_dev, WIN1_DSP_ST_RK312X,
478 v_DSP_STX(win->area[0].dsp_stx) |
479 v_DSP_STY(win->area[0].dsp_sty));
481 lcdc_writel(lcdc_dev,
483 win->area[0].y_addr);
486 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
487 v_YRGB_VIR(win->area[0].y_vir_stride));
490 } else if (win->id == 2) {
491 mask = m_HWC_EN | m_HWC_LODAD_EN;
492 val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
493 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
494 if ((win->area[0].xsize == 32) &&
495 (win->area[0].ysize == 32))
497 else if ((win->area[0].xsize == 64) &&
498 (win->area[0].ysize == 64))
501 dev_err(lcdc_dev->dev, "unsupport hwc size:x=%d,y=%d\n",
502 win->area[0].xsize, win->area[0].ysize);
503 lcdc_writel(lcdc_dev, HWC_DSP_ST,
504 v_DSP_STX(win->area[0].dsp_stx) |
505 v_DSP_STY(win->area[0].dsp_sty));
507 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
510 win->area[0].y_addr = 0;
511 win->area[0].uv_addr = 0;
513 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
515 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
516 win->area[0].y_addr);
517 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
518 win->area[0].uv_addr);
519 } else if (win->id == 1) {
520 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
522 lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
523 } else if (win->id == 2) {
524 lcdc_msk_reg(lcdc_dev,
525 SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
526 v_HWC_EN(0) | v_HWC_LODAD_EN(0));
527 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
530 rk312x_lcdc_alpha_cfg(lcdc_dev);
533 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
536 spin_lock(&lcdc_dev->reg_lock);
537 if (likely(lcdc_dev->clk_on) &&
538 lcdc_dev->driver.win[win_id]->state != open) {
540 if (!lcdc_dev->atv_layer_cnt) {
541 dev_info(lcdc_dev->dev,
542 "wakeup from standby!\n");
543 lcdc_dev->standby = 0;
545 lcdc_dev->atv_layer_cnt |= (1 << win_id);
546 } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
547 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
549 lcdc_dev->driver.win[win_id]->state = open;
551 lcdc_layer_update_regs(lcdc_dev,
552 lcdc_dev->driver.win[win_id]);
553 lcdc_cfg_done(lcdc_dev);
555 /*if no layer used,disable lcdc */
556 if (!lcdc_dev->atv_layer_cnt) {
557 dev_info(lcdc_dev->dev,
558 "no layer is used,go to standby!\n");
559 lcdc_dev->standby = 1;
562 spin_unlock(&lcdc_dev->reg_lock);
565 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
567 struct lcdc_device *lcdc_dev =
568 container_of(dev_drv, struct lcdc_device, driver);
569 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
570 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
573 spin_lock(&lcdc_dev->reg_lock);
574 if (likely(lcdc_dev->clk_on)) {
575 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
576 v_LCDC_STANDBY(lcdc_dev->standby));
577 lcdc_layer_update_regs(lcdc_dev, win0);
578 lcdc_layer_update_regs(lcdc_dev, win1);
579 rk312x_lcdc_alpha_cfg(lcdc_dev);
580 lcdc_cfg_done(lcdc_dev);
583 spin_unlock(&lcdc_dev->reg_lock);
584 //if (dev_drv->wait_fs) {
586 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
587 init_completion(&dev_drv->frame_done);
588 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
589 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
591 (dev_drv->cur_screen->ft +
593 if (!timeout && (!dev_drv->frame_done.done)) {
594 dev_warn(lcdc_dev->dev,
595 "wait for new frame start time out!\n");
599 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
604 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
606 memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
609 static int rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
612 struct lcdc_device *lcdc_dev =
613 container_of(dev_drv, struct lcdc_device, driver);
615 /*spin_lock(&lcdc_dev->reg_lock);*/
616 if (likely(lcdc_dev->clk_on)) {
617 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
618 m_AXI_OUTSTANDING_MAX_NUM;
619 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
620 v_AXI_MAX_OUTSTANDING_EN(1);
621 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
623 /*spin_unlock(&lcdc_dev->reg_lock);*/
624 #if defined(CONFIG_ROCKCHIP_IOMMU)
625 if (dev_drv->iommu_enabled) {
626 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
627 lcdc_dev->iommu_status = 1;
628 rockchip_iovmm_activate(dev_drv->dev);
636 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
637 int *hwc_lut, int mode)
643 struct lcdc_device *lcdc_dev =
644 container_of(dev_drv, struct lcdc_device, driver);
645 if (dev_drv->hwc_lut == NULL)
646 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
648 spin_lock(&lcdc_dev->reg_lock);
649 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
650 lcdc_cfg_done(lcdc_dev);
652 for (i = 0; i < 256; i++) {
654 dev_drv->hwc_lut[i] = hwc_lut[i];
655 v = dev_drv->hwc_lut[i];
656 c = lcdc_dev->hwc_lut_addr_base + i;
657 writel_relaxed(v, c);
659 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
660 lcdc_cfg_done(lcdc_dev);
661 spin_unlock(&lcdc_dev->reg_lock);
666 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv,
672 struct lcdc_device *lcdc_dev =
673 container_of(dev_drv, struct lcdc_device, driver);
678 spin_lock(&lcdc_dev->reg_lock);
679 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
680 lcdc_cfg_done(lcdc_dev);
682 for (i = 0; i < 256; i++) {
684 c = lcdc_dev->dsp_lut_addr_base + i;
685 writel_relaxed(v, c);
687 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
688 lcdc_cfg_done(lcdc_dev);
689 spin_unlock(&lcdc_dev->reg_lock);
693 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
696 #ifdef CONFIG_RK_FPGA
700 struct lcdc_device *lcdc_dev =
701 container_of(dev_drv, struct lcdc_device, driver);
702 struct rk_screen *screen = dev_drv->cur_screen;
705 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
707 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
709 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
710 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
712 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
713 screen->ft = 1000 / fps;
714 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
715 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
719 /********do basic init*********/
720 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
722 struct lcdc_device *lcdc_dev = container_of(dev_drv,
723 struct lcdc_device, driver);
724 if (lcdc_dev->pre_init)
727 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
728 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
729 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
730 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
731 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
732 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
734 if (/*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
735 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
736 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
740 rk_disp_pwr_enable(dev_drv);
741 rk312x_lcdc_clk_enable(lcdc_dev);
743 /* backup reg config at uboot */
744 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
746 /* config for the FRC mode of dither down */
747 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
748 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
749 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
750 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
751 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
752 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
754 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
755 lcdc_cfg_done(lcdc_dev);
756 /*if (dev_drv->iommu_enabled)
757 {// disable all wins to workaround iommu pagefault
758 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
759 v_WIN0_EN(0) | v_WIN1_EN(0));
760 lcdc_cfg_done(lcdc_dev);
761 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
763 if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
764 if (support_uboot_display())
765 dev_drv->bcsh_init_status = 1;
767 dev_drv->ops->open_bcsh(dev_drv, 1);
769 lcdc_dev->pre_init = true;
774 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
776 rk312x_lcdc_disable_irq(lcdc_dev);
779 static u32 calc_sclk_freq(struct rk_screen *src_screen,
780 struct rk_screen *dst_screen)
788 if (!src_screen || !dst_screen)
791 dsp_vtotal = dst_screen->mode.yres;
792 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
793 dst_screen->mode.xres + dst_screen->mode.right_margin;
794 dsp_in_vtotal = src_screen->mode.yres;
795 dsp_in_htotal = src_screen->mode.left_margin +
796 src_screen->mode.hsync_len +
797 src_screen->mode.xres + src_screen->mode.right_margin;
798 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
799 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
801 return (u32)sclk_freq;
804 #define SCLK_PLL_LIMIT 594000000
805 #define GPU_FREQ_MAX_LIMIT 297000000
806 #define GPU_FREQ_NEED 400000000
808 static u32 calc_sclk_pll_freq(u32 sclk_freq)
812 if (sclk_freq < (SCLK_PLL_LIMIT / 10)) {
813 return (sclk_freq * 10);
815 multi_num = GPU_FREQ_NEED / sclk_freq;
816 return (sclk_freq * multi_num);
820 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
821 struct rk_screen *dst, u32 sclk_freq)
826 u64 T_BP_in, T_BP_out, T_Delta, Tin;
827 u32 src_pixclock, dst_pixclock;
829 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
831 if (unlikely(!src) || unlikely(!dst))
834 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
835 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
836 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
837 dst->mode.xres + dst->mode.right_margin;
838 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
839 dst->mode.yres + dst->mode.lower_margin;
840 src_htotal = src->mode.left_margin + src->mode.hsync_len +
841 src->mode.xres + src->mode.right_margin;
842 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
843 src->mode.yres + src->mode.lower_margin;
844 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
845 src->mode.hsync_len + src->mode.left_margin;
846 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
847 dst->mode.hsync_len + dst->mode.left_margin;
849 T_BP_in = BP_in * src_pixclock;
850 T_BP_out = BP_out * dst_pixclock;
851 Tin = src_vtotal * src_htotal * src_pixclock;
853 v_scale_ratio = src->mode.yres / dst->mode.yres;
854 if (v_scale_ratio <= 2)
855 T_Delta = 5 * src_htotal * src_pixclock;
857 T_Delta = 12 * src_htotal * src_pixclock;
859 if (T_BP_in + T_Delta > T_BP_out)
860 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
862 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
864 /* (T_frm_st = scl_vst * src_htotal * src_pixclock +
865 scl_hst * src_pixclock) */
866 temp = do_div(T_frm_st, src_pixclock);
867 temp = do_div(T_frm_st, src_htotal);
868 dst->scl_hst = temp - 1;
869 dst->scl_vst = T_frm_st;
874 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
875 struct rk_screen *dst_screen, bool enable)
877 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
878 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
879 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
880 u32 scl_v_factor, scl_h_factor;
881 u32 dst_frame_hst, dst_frame_vst;
882 u32 src_w, src_h, dst_w, dst_h;
888 struct rk_screen *src;
889 struct rk_screen *dst;
890 struct lcdc_device *lcdc_dev = container_of(dev_drv,
891 struct lcdc_device, driver);
892 struct dvfs_node *gpu_clk = clk_get_dvfs_node("clk_gpu");
894 if (unlikely(!lcdc_dev->clk_on))
898 spin_lock(&lcdc_dev->reg_lock);
899 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
900 m_SCALER_EN | m_SCALER_OUT_ZERO |
902 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(1) |
904 lcdc_cfg_done(lcdc_dev);
905 spin_unlock(&lcdc_dev->reg_lock);
906 if (lcdc_dev->sclk_on) {
907 clk_disable_unprepare(lcdc_dev->sclk);
908 lcdc_dev->sclk_on = false;
911 /* switch pll freq as default when sclk is no used */
912 if (clk_get_rate(lcdc_dev->pll_sclk) != GPU_FREQ_NEED) {
913 dvfs_clk_enable_limit(gpu_clk, GPU_FREQ_MAX_LIMIT,
915 clk_set_rate(lcdc_dev->pll_sclk, GPU_FREQ_NEED);
916 dvfs_clk_enable_limit(gpu_clk, 0, -1);
918 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
923 * rk312x used one lcdc to apply dual disp
924 * hdmi screen is used for scaler src
925 * prmry screen is used for scaler dst
928 src = dev_drv->cur_screen;
930 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
934 if (!lcdc_dev->sclk_on) {
935 clk_prepare_enable(lcdc_dev->sclk);
936 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
937 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
940 dvfs_clk_enable_limit(gpu_clk,
944 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
945 /* cancel limit gpu freq */
946 dvfs_clk_enable_limit(gpu_clk, 0, -1);
948 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
949 lcdc_dev->sclk_on = true;
950 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
951 lcdc_dev->s_pixclock);
954 /* config scale timing */
955 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
956 dst_frame_vst = dst->scl_vst;
957 dst_frame_hst = dst->scl_hst;
959 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
960 dst->mode.xres + dst->mode.right_margin;
961 dsp_hs_end = dst->mode.hsync_len;
963 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
964 dst->mode.yres + dst->mode.lower_margin;
965 dsp_vs_end = dst->mode.vsync_len;
967 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
969 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
970 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
972 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
974 dsp_hact_st = dsp_hbor_st + bor_left;
975 dsp_hact_end = dsp_hbor_end - bor_right;
976 dsp_vact_st = dsp_vbor_st + bor_up;
977 dsp_vact_end = dsp_vbor_end - bor_down;
979 src_w = src->mode.xres;
980 src_h = src->mode.yres;
981 dst_w = dsp_hact_end - dsp_hact_st;
982 dst_h = dsp_vact_end - dsp_vact_st;
984 /* calc scale factor */
985 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
986 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
988 spin_lock(&lcdc_dev->reg_lock);
989 if (dst->color_mode != src->color_mode) {
990 /*dev_drv->output_color = dst->color_mode;
991 if (dev_drv->output_color == COLOR_YCBCR)
992 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
994 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
995 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
996 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
999 lcdc_writel(lcdc_dev, SCALER_FACTOR,
1000 v_SCALER_H_FACTOR(scl_h_factor) |
1001 v_SCALER_V_FACTOR(scl_v_factor));
1003 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
1004 v_SCALER_FRAME_HST(dst_frame_hst) |
1005 v_SCALER_FRAME_VST(dst_frame_vst));
1006 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
1007 v_SCALER_HS_END(dsp_hs_end) |
1008 v_SCALER_HTOTAL(dsp_htotal));
1009 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
1010 v_SCALER_HAEP(dsp_hact_end) |
1011 v_SCALER_HASP(dsp_hact_st));
1012 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
1013 v_SCALER_VS_END(dsp_vs_end) |
1014 v_SCALER_VTOTAL(dsp_vtotal));
1015 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
1016 v_SCALER_VAEP(dsp_vact_end) |
1017 v_SCALER_VASP(dsp_vact_st));
1018 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
1019 v_SCALER_HBOR_END(dsp_hbor_end) |
1020 v_SCALER_HBOR_ST(dsp_hbor_st));
1021 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
1022 v_SCALER_VBOR_END(dsp_vbor_end) |
1023 v_SCALER_VBOR_ST(dsp_vbor_st));
1024 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1025 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
1026 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
1027 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1028 m_SCALER_EN | m_SCALER_OUT_ZERO |
1030 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) |
1031 v_SCALER_OUT_EN(1));
1033 lcdc_cfg_done(lcdc_dev);
1034 spin_unlock(&lcdc_dev->reg_lock);
1039 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
1040 struct lcdc_device *lcdc_dev)
1043 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1044 if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
1045 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1046 m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1047 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1049 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1050 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1053 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1055 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1056 if (dev_drv->output_color == COLOR_RGB) {
1058 bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1059 if (((bcsh_ctrl&m_BCSH_EN) == 1) ||
1060 (dev_drv->bcsh.enable == 1))/*bcsh enabled*/
1061 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1062 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1063 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1064 else/*bcsh disabled*/
1065 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1066 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1067 v_BCSH_R2Y_EN(0) | v_BCSH_Y2R_EN(0));
1068 } else /* RGB2YUV */
1069 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1071 m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1073 v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1078 static int rk312x_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1079 u16 *yact, int *format, u32 *dsp_addr)
1081 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1082 struct lcdc_device, driver);
1085 spin_lock(&lcdc_dev->reg_lock);
1087 val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1088 *xact = (val & m_ACT_WIDTH)+1;
1089 *yact = ((val & m_ACT_HEIGHT)>>16)+1;
1091 val = lcdc_readl(lcdc_dev, SYS_CTRL);
1093 *format = (val & m_WIN0_FORMAT) >> 3;
1094 *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1096 spin_unlock(&lcdc_dev->reg_lock);
1101 static int rk312x_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1102 int format, u16 xact, u16 yact, u16 xvir)
1104 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1105 struct lcdc_device, driver);
1108 mask = m_WIN0_FORMAT;
1109 val = v_WIN0_FORMAT(format);
1110 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1112 lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR,
1114 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(xact) |
1115 v_ACT_HEIGHT(yact));
1117 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1119 lcdc_cfg_done(lcdc_dev);
1124 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1127 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1128 struct lcdc_device, driver);
1129 struct rk_screen *screen = dev_drv->cur_screen;
1130 u16 right_margin = screen->mode.right_margin;
1131 u16 left_margin = screen->mode.left_margin;
1132 u16 lower_margin = screen->mode.lower_margin;
1133 u16 upper_margin = screen->mode.upper_margin;
1134 u16 x_res = screen->mode.xres;
1135 u16 y_res = screen->mode.yres;
1138 spin_lock(&lcdc_dev->reg_lock);
1139 if (likely(lcdc_dev->clk_on)) {
1140 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
1141 m_LCDC_STANDBY, v_LCDC_STANDBY(1));
1142 lcdc_cfg_done(lcdc_dev);
1144 /* Select output color domain */
1145 /*dev_drv->output_color = screen->color_mode;
1146 if (lcdc_dev->soc_type == VOP_RK312X) {
1147 if (dev_drv->output_color == COLOR_YCBCR)
1148 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1150 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1152 dev_drv->output_color = COLOR_RGB;
1153 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1155 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1156 /*something wrong at yuv domain*/
1158 switch (screen->type) {
1160 if (lcdc_dev->soc_type == VOP_RK312X) {
1161 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1162 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1163 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1167 if (lcdc_dev->soc_type == VOP_RK312X) {
1168 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1169 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1170 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1174 if (lcdc_dev->soc_type == VOP_RK312X) {
1175 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1176 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1177 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1181 mask = m_HDMI_DCLK_EN;
1182 val = v_HDMI_DCLK_EN(1);
1183 if (screen->pixelrepeat) {
1184 mask |= m_CORE_CLK_DIV_EN;
1185 val |= v_CORE_CLK_DIV_EN(1);
1187 mask |= m_CORE_CLK_DIV_EN;
1188 val |= v_CORE_CLK_DIV_EN(0);
1190 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1191 if (lcdc_dev->soc_type == VOP_RK312X) {
1192 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1194 v_SW_UV_OFFSET_EN(0));
1195 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1197 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1198 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1199 v_HDMI_DEN_POL(screen->pin_den);
1200 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1202 mask = (1 << 4) | (1 << 5) | (1 << 6);
1203 val = (screen->pin_hsync << 4) |
1204 (screen->pin_vsync << 5) |
1205 (screen->pin_den << 6);
1206 grf_writel(RK3036_GRF_SOC_CON2,
1207 (mask << 16) | val);
1209 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1212 case SCREEN_TVOUT_TEST:
1213 mask = m_TVE_DAC_DCLK_EN;
1214 val = v_TVE_DAC_DCLK_EN(1);
1215 if (screen->pixelrepeat) {
1216 mask |= m_CORE_CLK_DIV_EN;
1217 val |= v_CORE_CLK_DIV_EN(1);
1219 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1220 if (x_res == 720 && y_res == 576)
1221 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1222 v_TVE_MODE(TV_PAL));
1223 else if (x_res == 720 && y_res == 480)
1224 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1225 v_TVE_MODE(TV_NTSC));
1227 dev_err(lcdc_dev->dev,
1228 "unsupported video timing!\n");
1231 if (lcdc_dev->soc_type == VOP_RK312X) {
1232 if (screen->type == SCREEN_TVOUT_TEST)
1233 /*for TVE index test,vop must ovarlay at yuv domain*/
1234 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1235 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1237 v_SW_UV_OFFSET_EN(1));
1239 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1243 dev_err(lcdc_dev->dev, "un supported interface!\n");
1246 if (lcdc_dev->soc_type == VOP_RK312X) {
1247 switch (dev_drv->screen0->face) {
1250 mask = m_DITHER_DOWN_EN |
1251 m_DITHER_DOWN_MODE |
1253 val = v_DITHER_DOWN_EN(1) |
1254 v_DITHER_DOWN_MODE(0) |
1255 v_DITHER_DOWN_SEL(1);
1256 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1260 mask = m_DITHER_DOWN_EN |
1261 m_DITHER_DOWN_MODE |
1263 val = v_DITHER_DOWN_EN(1) |
1264 v_DITHER_DOWN_MODE(1) |
1265 v_DITHER_DOWN_SEL(1);
1266 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1270 mask = m_DITHER_DOWN_EN |
1271 m_DITHER_DOWN_MODE |
1273 val = v_DITHER_DOWN_EN(1) |
1274 v_DITHER_DOWN_MODE(0) |
1275 v_DITHER_DOWN_SEL(1);
1276 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1280 mask = m_DITHER_DOWN_EN |
1281 m_DITHER_DOWN_MODE |
1283 val = v_DITHER_DOWN_EN(1) |
1284 v_DITHER_DOWN_MODE(1) |
1285 v_DITHER_DOWN_SEL(1);
1286 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1290 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1291 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1292 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1295 dev_err(lcdc_dev->dev, "un supported interface!\n");
1298 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1299 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1302 mask = m_HSYNC_POL | m_VSYNC_POL |
1303 m_DEN_POL | m_DCLK_POL;
1304 val = v_HSYNC_POL(screen->pin_hsync) |
1305 v_VSYNC_POL(screen->pin_vsync) |
1306 v_DEN_POL(screen->pin_den) |
1307 v_DCLK_POL(screen->pin_dclk);
1309 if (screen->type != SCREEN_HDMI) {
1310 mask |= m_DSP_OUT_FORMAT;
1311 val |= v_DSP_OUT_FORMAT(face);
1314 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1316 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1317 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1318 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1320 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1321 v_DSP_RB_SWAP(screen->swap_rb) |
1322 v_DSP_RG_SWAP(screen->swap_rg) |
1323 v_DSP_DELTA_SWAP(screen->swap_delta) |
1324 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1325 v_BLANK_EN(0) | v_BLACK_EN(0);
1326 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1329 val = v_HSYNC(screen->mode.hsync_len) |
1330 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1332 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1333 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1334 v_HASP(screen->mode.hsync_len + left_margin);
1335 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1337 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1338 /* First Field Timing */
1339 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1340 v_VSYNC(screen->mode.vsync_len) |
1341 v_VERPRD(2 * (screen->mode.vsync_len +
1343 lower_margin) + y_res + 1));
1344 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1345 v_VAEP(screen->mode.vsync_len +
1346 upper_margin + y_res / 2) |
1347 v_VASP(screen->mode.vsync_len +
1349 /* Second Field Timing */
1350 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1351 v_VSYNC_ST_F1(screen->mode.vsync_len +
1352 upper_margin + y_res / 2 +
1354 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1355 upper_margin + y_res / 2 +
1357 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1358 v_VAEP(2 * (screen->mode.vsync_len +
1360 y_res + lower_margin + 1) |
1361 v_VASP(2 * (screen->mode.vsync_len +
1363 y_res / 2 + lower_margin + 1));
1365 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1366 m_INTERLACE_DSP_EN |
1367 m_WIN0_YRGB_DEFLICK_EN |
1368 m_WIN0_CBR_DEFLICK_EN |
1369 m_INTERLACE_FIELD_POL |
1370 m_WIN0_INTERLACE_EN |
1371 m_WIN1_INTERLACE_EN,
1372 v_INTERLACE_DSP_EN(1) |
1373 v_WIN0_YRGB_DEFLICK_EN(1) |
1374 v_WIN0_CBR_DEFLICK_EN(1) |
1375 v_INTERLACE_FIELD_POL(0) |
1376 v_WIN0_INTERLACE_EN(1) |
1377 v_WIN1_INTERLACE_EN(1));
1378 mask = m_LF_INT_NUM;
1379 val = v_LF_INT_NUM(screen->mode.vsync_len +
1380 screen->mode.upper_margin +
1381 screen->mode.yres/2);
1382 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1384 val = v_VSYNC(screen->mode.vsync_len) |
1385 v_VERPRD(screen->mode.vsync_len + upper_margin +
1386 y_res + lower_margin);
1387 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1389 val = v_VAEP(screen->mode.vsync_len +
1390 upper_margin + y_res) |
1391 v_VASP(screen->mode.vsync_len + upper_margin);
1392 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1394 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1395 m_INTERLACE_DSP_EN |
1396 m_WIN0_YRGB_DEFLICK_EN |
1397 m_WIN0_CBR_DEFLICK_EN |
1398 m_INTERLACE_FIELD_POL |
1399 m_WIN0_INTERLACE_EN |
1400 m_WIN1_INTERLACE_EN,
1401 v_INTERLACE_DSP_EN(0) |
1402 v_WIN0_YRGB_DEFLICK_EN(0) |
1403 v_WIN0_CBR_DEFLICK_EN(0) |
1404 v_INTERLACE_FIELD_POL(0) |
1405 v_WIN0_INTERLACE_EN(0) |
1406 v_WIN1_INTERLACE_EN(0));
1407 mask = m_LF_INT_NUM;
1408 val = v_LF_INT_NUM(screen->mode.vsync_len +
1409 screen->mode.upper_margin +
1411 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1414 spin_unlock(&lcdc_dev->reg_lock);
1415 rk312x_lcdc_set_dclk(dev_drv, 1);
1416 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY, v_LCDC_STANDBY(0));
1417 lcdc_cfg_done(lcdc_dev);
1418 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1419 dev_drv->trsm_ops->enable();
1426 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1429 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1430 struct lcdc_device, driver);
1432 /* enable clk,when first layer open */
1433 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1434 rockchip_set_system_status(SYS_STATUS_LCDC0);
1435 rk312x_lcdc_pre_init(dev_drv);
1436 rk312x_lcdc_clk_enable(lcdc_dev);
1437 #if defined(CONFIG_ROCKCHIP_IOMMU)
1438 if (dev_drv->iommu_enabled) {
1439 if (!dev_drv->mmu_dev) {
1441 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1442 if (dev_drv->mmu_dev) {
1443 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1446 dev_err(dev_drv->dev,
1447 "failed to get rockchip iommu device\n");
1451 /*if (dev_drv->mmu_dev)
1452 rockchip_iovmm_activate(dev_drv->dev);*/
1455 rk312x_lcdc_reg_restore(lcdc_dev);
1456 /*if (dev_drv->iommu_enabled)
1457 rk312x_lcdc_mmu_en(dev_drv);*/
1458 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1459 rk312x_lcdc_set_dclk(dev_drv, 0);
1460 rk312x_lcdc_enable_irq(dev_drv);
1462 rk312x_load_screen(dev_drv, 1);
1465 /* set screen lut */
1466 if (dev_drv->cur_screen->dsp_lut)
1467 rk312x_lcdc_set_lut(dev_drv,
1468 dev_drv->cur_screen->dsp_lut);
1471 if (win_id < ARRAY_SIZE(lcdc_win))
1472 lcdc_layer_enable(lcdc_dev, win_id, open);
1474 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1476 /* when all layer closed,disable clk */
1477 /* if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1478 rk312x_lcdc_disable_irq(lcdc_dev);
1479 rk312x_lcdc_reg_update(dev_drv);
1480 #if defined(CONFIG_ROCKCHIP_IOMMU)
1481 if (dev_drv->iommu_enabled) {
1482 if (dev_drv->mmu_dev)
1483 rockchip_iovmm_deactivate(dev_drv->dev);
1486 rk312x_lcdc_clk_disable(lcdc_dev);
1487 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1492 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1494 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1495 struct lcdc_device, driver);
1496 struct rk_screen *screen = dev_drv->cur_screen;
1497 struct rk_lcdc_win *win = NULL;
1498 char fmt[9] = "NULL";
1501 dev_err(dev_drv->dev, "screen is null!\n");
1506 win = dev_drv->win[0];
1507 } else if (win_id == 1) {
1508 win = dev_drv->win[1];
1509 } else if (win_id == 2) {
1510 win = dev_drv->win[2];
1512 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1516 spin_lock(&lcdc_dev->reg_lock);
1517 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1518 screen->mode.hsync_len;
1520 if ((win->area[0].xact != win->area[0].xsize) ||
1521 (win->area[0].yact != win->area[0].ysize)) {
1522 pr_err("win[1],not support scale\n");
1523 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
1524 win->area[0].xact,win->area[0].yact,
1525 win->area[0].xsize,win->area[0].ysize);
1526 win->area[0].xsize = win->area[0].xact;
1527 win->area[0].ysize = win->area[0].yact;
1530 if (screen->mode.vmode == FB_VMODE_INTERLACED) {
1531 win->area[0].ysize /= 2;
1532 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1533 screen->mode.upper_margin +
1534 screen->mode.vsync_len;
1536 win->area[0].dsp_sty = win->area[0].ypos +
1537 screen->mode.upper_margin +
1538 screen->mode.vsync_len;
1540 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1541 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1543 switch (win->area[0].format) {
1545 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1546 win->area[0].swap_rb = 0;
1547 win->area[0].swap_uv = 0;
1550 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1551 win->area[0].swap_rb = 1;
1552 win->area[0].swap_uv = 0;
1555 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1556 win->area[0].swap_rb = 1;
1557 win->area[0].swap_uv = 0;
1560 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1561 win->area[0].swap_rb = 0;
1562 win->area[0].swap_uv = 0;
1565 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1566 win->area[0].swap_rb = 0;
1570 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1572 CalScale(win->area[0].xact, win->area[0].xsize);
1574 CalScale(win->area[0].yact, win->area[0].ysize);
1575 win->area[0].swap_rb = 0;
1576 win->area[0].swap_uv = 0;
1578 dev_err(lcdc_dev->driver.dev,
1579 "%s:un supported format!\n", __func__);
1584 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1585 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1586 win->area[0].xsize);
1588 CalScale(win->area[0].yact, win->area[0].ysize);
1589 win->area[0].swap_rb = 0;
1590 win->area[0].swap_uv = 0;
1592 dev_err(lcdc_dev->driver.dev,
1593 "%s:un supported format!\n", __func__);
1598 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1600 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1602 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1603 win->area[0].swap_rb = 0;
1604 win->area[0].swap_uv = 0;
1606 dev_err(lcdc_dev->driver.dev,
1607 "%s:un supported format!\n", __func__);
1612 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1614 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1616 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1617 win->area[0].swap_rb = 0;
1618 win->area[0].swap_uv = 1;
1620 dev_err(lcdc_dev->driver.dev,
1621 "%s:un supported format!\n", __func__);
1625 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1629 spin_unlock(&lcdc_dev->reg_lock);
1632 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1633 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1634 get_format_string(win->area[0].format, fmt), win->area[0].xact,
1635 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1636 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1641 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1643 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1644 struct lcdc_device, driver);
1645 struct rk_lcdc_win *win = NULL;
1646 struct rk_screen *screen = dev_drv->cur_screen;
1649 dev_err(dev_drv->dev, "screen is null!\n");
1654 win = dev_drv->win[0];
1655 } else if (win_id == 1) {
1656 win = dev_drv->win[1];
1657 } else if (win_id == 2) {
1658 win = dev_drv->win[2];
1660 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1664 spin_lock(&lcdc_dev->reg_lock);
1665 if (likely(lcdc_dev->clk_on)) {
1666 win->area[0].y_addr =
1667 win->area[0].smem_start + win->area[0].y_offset;
1668 win->area[0].uv_addr =
1669 win->area[0].cbr_start + win->area[0].c_offset;
1670 if (win->area[0].y_addr)
1671 lcdc_layer_update_regs(lcdc_dev, win);
1672 /* lcdc_cfg_done(lcdc_dev); */
1674 spin_unlock(&lcdc_dev->reg_lock);
1676 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1677 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1678 win->area[0].y_offset);
1679 /* this is the first frame of the system,enable frame start interrupt */
1680 if ((dev_drv->first_frame)) {
1681 dev_drv->first_frame = 0;
1682 rk312x_lcdc_enable_irq(dev_drv);
1688 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1689 unsigned long arg, int win_id)
1691 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1692 struct lcdc_device, driver);
1694 void __user *argp = (void __user *)arg;
1695 struct color_key_cfg clr_key_cfg;
1698 case RK_FBIOGET_PANEL_SIZE:
1699 panel_size[0] = lcdc_dev->screen->mode.xres;
1700 panel_size[1] = lcdc_dev->screen->mode.yres;
1701 if (copy_to_user(argp, panel_size, 8))
1704 case RK_FBIOPUT_COLOR_KEY_CFG:
1705 if (copy_from_user(&clr_key_cfg, argp,
1706 sizeof(struct color_key_cfg)))
1708 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1709 clr_key_cfg.win0_color_key_cfg);
1710 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1711 clr_key_cfg.win1_color_key_cfg);
1720 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1725 mutex_lock(&dev_drv->fb_win_id_mutex);
1726 if (!strcmp(id, "fb0"))
1727 win_id = dev_drv->fb0_win_id;
1728 else if (!strcmp(id, "fb1"))
1729 win_id = dev_drv->fb1_win_id;
1730 else if (!strcmp(id, "fb2"))
1731 win_id = dev_drv->fb2_win_id;
1732 mutex_unlock(&dev_drv->fb_win_id_mutex);
1737 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
1741 struct lcdc_device *lcdc_dev =
1742 container_of(dev_drv, struct lcdc_device, driver);
1746 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_WIN0_EN);
1747 else if (win_id == 1)
1748 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_WIN1_EN);
1749 else if (win_id == 2)
1750 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_HWC_EN);
1752 pr_err("!!!%s,win_id :%d,unsupport!!!\n",__func__,win_id);
1757 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1760 struct lcdc_device *lcdc_dev =
1761 container_of(dev_drv, struct lcdc_device, driver);
1764 spin_lock(&lcdc_dev->reg_lock);
1765 if (lcdc_dev->clk_on) {
1767 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1771 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1776 spin_unlock(&lcdc_dev->reg_lock);
1781 static int rk312x_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1783 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1784 struct lcdc_device, driver);
1785 struct device_node *backlight;
1787 if (lcdc_dev->backlight)
1790 backlight = of_parse_phandle(lcdc_dev->dev->of_node,
1793 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
1794 if (!lcdc_dev->backlight)
1795 dev_info(lcdc_dev->dev, "No find backlight device\n");
1797 dev_info(lcdc_dev->dev, "No find backlight device node\n");
1803 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1805 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1806 struct lcdc_device, driver);
1807 if (dev_drv->suspend_flag)
1810 /* close the backlight */
1811 rk312x_lcdc_get_backlight_device(dev_drv);
1812 if (lcdc_dev->backlight) {
1813 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
1814 backlight_update_status(lcdc_dev->backlight);
1817 dev_drv->suspend_flag = 1;
1818 flush_kthread_worker(&dev_drv->update_regs_worker);
1820 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1821 dev_drv->trsm_ops->disable();
1822 spin_lock(&lcdc_dev->reg_lock);
1823 if (likely(lcdc_dev->clk_on)) {
1824 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1825 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1826 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1827 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1828 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1830 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1832 lcdc_cfg_done(lcdc_dev);
1834 if (dev_drv->iommu_enabled) {
1835 if (dev_drv->mmu_dev)
1836 rockchip_iovmm_deactivate(dev_drv->dev);
1839 spin_unlock(&lcdc_dev->reg_lock);
1841 spin_unlock(&lcdc_dev->reg_lock);
1844 rk312x_lcdc_clk_disable(lcdc_dev);
1845 rk_disp_pwr_disable(dev_drv);
1849 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1851 struct lcdc_device *lcdc_dev =
1852 container_of(dev_drv, struct lcdc_device, driver);
1854 if (!dev_drv->suspend_flag)
1856 rk_disp_pwr_enable(dev_drv);
1858 rk312x_lcdc_clk_enable(lcdc_dev);
1859 rk312x_lcdc_reg_restore(lcdc_dev);
1861 /* config for the FRC mode of dither down */
1862 if (dev_drv->cur_screen &&
1863 dev_drv->cur_screen->face != OUT_P888) {
1864 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1865 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1866 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1867 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1868 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1869 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1872 /* set screen lut */
1873 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1874 rk312x_lcdc_set_lut(dev_drv,
1875 dev_drv->cur_screen->dsp_lut);
1877 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1879 spin_lock(&lcdc_dev->reg_lock);
1881 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1883 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1885 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1886 lcdc_cfg_done(lcdc_dev);
1888 if (dev_drv->iommu_enabled) {
1889 if (dev_drv->mmu_dev)
1890 rockchip_iovmm_activate(dev_drv->dev);
1893 spin_unlock(&lcdc_dev->reg_lock);
1894 dev_drv->suspend_flag = 0;
1896 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1897 dev_drv->trsm_ops->enable();
1903 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1904 int win_id, int blank_mode)
1906 switch (blank_mode) {
1907 case FB_BLANK_UNBLANK:
1908 rk312x_lcdc_early_resume(dev_drv);
1910 case FB_BLANK_NORMAL:
1911 rk312x_lcdc_early_suspend(dev_drv);
1914 rk312x_lcdc_early_suspend(dev_drv);
1918 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1923 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1925 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1926 struct lcdc_device, driver);
1928 struct rk_lcdc_win *win = NULL;
1930 spin_lock(&lcdc_dev->reg_lock);
1931 if (lcdc_dev->clk_on) {
1932 for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
1933 win = dev_drv->win[i];
1934 if ((win->state == 0) && (win->last_state == 1))
1935 lcdc_layer_update_regs(lcdc_dev, win);
1936 win->last_state = win->state;
1938 lcdc_cfg_done(lcdc_dev);
1940 spin_unlock(&lcdc_dev->reg_lock);
1946 sin_hue = sin(a)*256 +0x100;
1947 cos_hue = cos(a)*256;
1949 sin_hue = sin(a)*256;
1950 cos_hue = cos(a)*256;
1952 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
1955 struct lcdc_device *lcdc_dev =
1956 container_of(dev_drv, struct lcdc_device, driver);
1959 spin_lock(&lcdc_dev->reg_lock);
1960 if (lcdc_dev->clk_on) {
1961 val = lcdc_readl(lcdc_dev, BCSH_H);
1964 val &= m_BCSH_SIN_HUE;
1967 val &= m_BCSH_COS_HUE;
1974 spin_unlock(&lcdc_dev->reg_lock);
1979 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
1982 struct lcdc_device *lcdc_dev =
1983 container_of(dev_drv, struct lcdc_device, driver);
1986 spin_lock(&lcdc_dev->reg_lock);
1987 if (lcdc_dev->clk_on) {
1988 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
1989 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
1990 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
1991 lcdc_cfg_done(lcdc_dev);
1993 spin_unlock(&lcdc_dev->reg_lock);
1998 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
1999 bcsh_bcs_mode mode, int value)
2001 struct lcdc_device *lcdc_dev =
2002 container_of(dev_drv, struct lcdc_device, driver);
2005 spin_lock(&lcdc_dev->reg_lock);
2006 if (lcdc_dev->clk_on) {
2009 /* from 0 to 255,typical is 128 */
2012 else if (value >= 0x80)
2013 value = value - 0x80;
2014 mask = m_BCSH_BRIGHTNESS;
2015 val = v_BCSH_BRIGHTNESS(value);
2018 /* from 0 to 510,typical is 256 */
2019 mask = m_BCSH_CONTRAST;
2020 val = v_BCSH_CONTRAST(value);
2023 /* from 0 to 1015,typical is 256 */
2024 mask = m_BCSH_SAT_CON;
2025 val = v_BCSH_SAT_CON(value);
2030 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2031 lcdc_cfg_done(lcdc_dev);
2033 spin_unlock(&lcdc_dev->reg_lock);
2037 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2040 struct lcdc_device *lcdc_dev =
2041 container_of(dev_drv, struct lcdc_device, driver);
2044 spin_lock(&lcdc_dev->reg_lock);
2045 if (lcdc_dev->clk_on) {
2046 val = lcdc_readl(lcdc_dev, BCSH_BCS);
2049 val &= m_BCSH_BRIGHTNESS;
2056 val &= m_BCSH_CONTRAST;
2060 val &= m_BCSH_SAT_CON;
2067 spin_unlock(&lcdc_dev->reg_lock);
2071 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2073 struct lcdc_device *lcdc_dev =
2074 container_of(dev_drv, struct lcdc_device, driver);
2076 if (dev_drv->bcsh_init_status && open) {
2077 dev_drv->bcsh_init_status = 0;
2080 spin_lock(&lcdc_dev->reg_lock);
2081 if (lcdc_dev->clk_on) {
2083 lcdc_msk_reg(lcdc_dev,
2084 BCSH_CTRL, m_BCSH_EN | m_BCSH_OUT_MODE,
2085 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
2086 lcdc_writel(lcdc_dev, BCSH_BCS,
2087 v_BCSH_BRIGHTNESS(0x00) |
2088 v_BCSH_CONTRAST(0x80) |
2089 v_BCSH_SAT_CON(0x80));
2090 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
2091 dev_drv->bcsh.enable = 1;
2095 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
2096 dev_drv->bcsh.enable = 0;
2098 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
2099 lcdc_cfg_done(lcdc_dev);
2102 spin_unlock(&lcdc_dev->reg_lock);
2106 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2108 struct rk_lcdc_win_area area;
2109 int fb2_win_id, fb1_win_id, fb0_win_id;
2111 mutex_lock(&dev_drv->fb_win_id_mutex);
2112 if (order == FB_DEFAULT_ORDER)
2113 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
2115 fb2_win_id = order / 100;
2116 fb1_win_id = (order / 10) % 10;
2117 fb0_win_id = order % 10;
2119 if (fb0_win_id != dev_drv->fb0_win_id) {
2120 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
2121 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
2122 dev_drv->win[fb0_win_id]->area[0];
2123 dev_drv->win[fb0_win_id]->area[0] = area;
2124 dev_drv->fb0_win_id = fb0_win_id;
2126 dev_drv->fb1_win_id = fb1_win_id;
2127 dev_drv->fb2_win_id = fb2_win_id;
2129 mutex_unlock(&dev_drv->fb_win_id_mutex);
2134 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2137 struct lcdc_device *lcdc_dev =
2138 container_of(dev_drv, struct lcdc_device, driver);
2139 struct rk_screen *screen = dev_drv->cur_screen;
2144 u32 x_total, y_total;
2147 ft = div_u64(1000000000000llu, fps);
2149 screen->mode.upper_margin + screen->mode.lower_margin +
2150 screen->mode.yres + screen->mode.vsync_len;
2152 screen->mode.left_margin + screen->mode.right_margin +
2153 screen->mode.xres + screen->mode.hsync_len;
2154 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2155 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2156 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2159 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2160 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2161 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2162 screen->ft = 1000 / fps; /*one frame time in ms */
2165 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2166 clk_get_rate(lcdc_dev->dclk), fps);
2171 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
2174 struct lcdc_device *lcdc_dev =
2175 container_of(dev_drv,
2176 struct lcdc_device, driver);
2178 enable_irq(lcdc_dev->irq);
2180 disable_irq(lcdc_dev->irq);
2184 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2186 struct lcdc_device *lcdc_dev =
2187 container_of(dev_drv, struct lcdc_device, driver);
2191 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
2192 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
2193 if (int_reg & m_LF_INT_STA) {
2194 dev_drv->frame_time.last_framedone_t =
2195 dev_drv->frame_time.framedone_t;
2196 dev_drv->frame_time.framedone_t = cpu_clock(0);
2197 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
2199 ret = RK_LF_STATUS_FC;
2201 ret = RK_LF_STATUS_FR;
2204 ret = RK_LF_STATUS_NC;
2210 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2211 unsigned int dsp_addr[][4])
2213 struct lcdc_device *lcdc_dev =
2214 container_of(dev_drv, struct lcdc_device, driver);
2216 if (lcdc_dev->clk_on) {
2217 dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2218 if (lcdc_dev->soc_type == VOP_RK3036)
2219 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
2220 else if (lcdc_dev->soc_type == VOP_RK312X)
2221 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2226 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2227 char *buf, int win_id)
2229 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
2231 char format_w0[9] = "NULL";
2232 char format_w1[9] = "NULL";
2233 char status_w0[9] = "NULL";
2234 char status_w1[9] = "NULL";
2235 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
2236 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
2237 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
2238 u16 x_factor, y_factor, x_scale, y_scale;
2240 u32 win1_dsp_yaddr = 0;
2242 spin_lock(&lcdc_dev->reg_lock);
2243 if (lcdc_dev->clk_on) {
2245 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2246 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2247 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2250 if (fmt_id & m_WIN0_EN)
2251 strcpy(status_w0, "enabled");
2253 strcpy(status_w0, "disabled");
2255 if ((fmt_id & m_WIN1_EN) >> 1)
2256 strcpy(status_w1, "enabled");
2258 strcpy(status_w1, "disabled");
2261 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2264 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2265 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2268 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2269 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2270 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2272 if (lcdc_dev->soc_type == VOP_RK3036) {
2273 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2274 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2275 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2276 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2277 /* rk312x unsupport win1 scaler,so have no act info */
2283 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2284 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2285 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2287 if (lcdc_dev->soc_type == VOP_RK3036)
2288 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2289 else if (lcdc_dev->soc_type == VOP_RK312X)
2290 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2291 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2292 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2295 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2296 x_st_w0 = dsp_st & m_DSP_STX;
2297 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2299 if (lcdc_dev->soc_type == VOP_RK3036)
2300 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2301 else if (lcdc_dev->soc_type == VOP_RK312X)
2302 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2304 x_st_w1 = dsp_st & m_DSP_STX;
2305 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2308 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2309 x_factor = factor & m_X_SCL_FACTOR;
2310 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2311 x_scale = 4096 * 100 / x_factor;
2312 y_scale = 4096 * 100 / y_factor;
2315 if (lcdc_dev->soc_type == VOP_RK3036)
2316 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2317 else if (lcdc_dev->soc_type == VOP_RK312X)
2318 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2320 spin_unlock(&lcdc_dev->reg_lock);
2323 spin_unlock(&lcdc_dev->reg_lock);
2324 return snprintf(buf, PAGE_SIZE,
2336 "YRGB buffer addr:0x%08x\n"
2337 "CBR buffer addr:0x%08x\n\n"
2347 "YRGB buffer addr:0x%08x\n"
2362 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2363 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2374 ovl ? "win0 on the top of win1\n" :
2375 "win1 on the top of win0\n");
2378 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2380 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2383 int *cbase = (int *)lcdc_dev->regs;
2384 int *regsbak = (int *)lcdc_dev->regsbak;
2387 pr_info("back up reg:\n");
2388 for (i = 0; i <= (0xDC >> 4); i++) {
2389 for (j = 0; j < 4; j++)
2390 pr_info("%08x ", *(regsbak + i * 4 + j));
2394 pr_info("lcdc reg:\n");
2395 for (i = 0; i <= (0xDC >> 4); i++) {
2396 for (j = 0; j < 4; j++)
2397 pr_info("%08x ", readl_relaxed(cbase + i * 4 + j));
2403 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2405 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2406 struct lcdc_device, driver);
2407 if (lcdc_dev->soc_type == VOP_RK312X) {
2408 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2409 v_DIRECT_PATH_EN(open));
2410 lcdc_cfg_done(lcdc_dev);
2415 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2417 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2418 struct lcdc_device, driver);
2420 if (lcdc_dev->soc_type == VOP_RK312X) {
2421 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2422 v_DIRECT_PATH_LAYER(win_id));
2423 lcdc_cfg_done(lcdc_dev);
2428 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2430 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2431 struct lcdc_device, driver);
2434 if (lcdc_dev->soc_type == VOP_RK312X)
2435 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2440 static int rk312x_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2442 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2443 struct lcdc_device, driver);
2445 rk312x_lcdc_get_backlight_device(dev_drv);
2448 /* close the backlight */
2449 if (lcdc_dev->backlight) {
2450 lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
2451 backlight_update_status(lcdc_dev->backlight);
2454 spin_lock(&lcdc_dev->reg_lock);
2455 if (likely(lcdc_dev->clk_on)) {
2456 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2458 lcdc_cfg_done(lcdc_dev);
2460 spin_unlock(&lcdc_dev->reg_lock);
2462 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2463 dev_drv->trsm_ops->disable();
2465 spin_lock(&lcdc_dev->reg_lock);
2466 if (likely(lcdc_dev->clk_on)) {
2467 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2469 lcdc_cfg_done(lcdc_dev);
2471 spin_unlock(&lcdc_dev->reg_lock);
2472 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2473 dev_drv->trsm_ops->enable();
2475 /* open the backlight */
2476 if (lcdc_dev->backlight) {
2477 lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
2478 backlight_update_status(lcdc_dev->backlight);
2486 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2487 .open = rk312x_lcdc_open,
2488 .load_screen = rk312x_load_screen,
2489 .get_dspbuf_info = rk312x_get_dspbuf_info,
2490 .post_dspbuf = rk312x_post_dspbuf,
2491 .set_par = rk312x_lcdc_set_par,
2492 .pan_display = rk312x_lcdc_pan_display,
2493 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2494 .blank = rk312x_lcdc_blank,
2495 .ioctl = rk312x_lcdc_ioctl,
2496 .get_win_state = rk312x_lcdc_get_win_state,
2497 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2498 .get_disp_info = rk312x_lcdc_get_disp_info,
2499 .fps_mgr = rk312x_lcdc_fps_mgr,
2500 .fb_get_win_id = rk312x_lcdc_get_win_id,
2501 .fb_win_remap = rk312x_fb_win_remap,
2502 .poll_vblank = rk312x_lcdc_poll_vblank,
2503 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2504 .cfg_done = rk312x_lcdc_cfg_done,
2505 .dump_reg = rk312x_lcdc_reg_dump,
2506 .dpi_open = rk312x_lcdc_dpi_open,
2507 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2508 .dpi_status = rk312x_lcdc_dpi_status,
2509 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2510 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2511 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2512 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2513 .open_bcsh = rk312x_lcdc_open_bcsh,
2514 .set_screen_scaler = rk312x_lcdc_set_scaler,
2515 .set_dsp_lut = rk312x_lcdc_set_lut,
2516 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2517 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2518 .dsp_black = rk312x_lcdc_dsp_black,
2519 .mmu_en = rk312x_lcdc_mmu_en,
2522 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2523 .soc_type = VOP_RK3036,
2526 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2527 .soc_type = VOP_RK312X,
2530 #if defined(CONFIG_OF)
2531 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2534 .compatible = "rockchip,rk3036-lcdc",
2535 .data = (void *)&rk3036_lcdc_drvdata,
2539 .compatible = "rockchip,rk312x-lcdc",
2540 .data = (void *)&rk312x_lcdc_drvdata,
2545 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2547 struct device_node *np = lcdc_dev->dev->of_node;
2548 const struct of_device_id *match;
2549 const struct rk_lcdc_drvdata *lcdc_drvdata;
2552 #if defined(CONFIG_ROCKCHIP_IOMMU)
2553 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2554 lcdc_dev->driver.iommu_enabled = 0;
2556 lcdc_dev->driver.iommu_enabled = val;
2558 lcdc_dev->driver.iommu_enabled = 0;
2561 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2562 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2564 lcdc_dev->driver.fb_win_map = val;
2566 match = of_match_node(rk312x_lcdc_dt_ids, np);
2568 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2569 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2571 return PTR_ERR(match);
2577 static int rk312x_lcdc_probe(struct platform_device *pdev)
2579 struct lcdc_device *lcdc_dev = NULL;
2580 struct rk_lcdc_driver *dev_drv;
2581 struct device *dev = &pdev->dev;
2582 struct resource *res;
2585 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2587 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2590 platform_set_drvdata(pdev, lcdc_dev);
2591 lcdc_dev->dev = dev;
2592 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2593 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2597 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2598 lcdc_dev->reg_phy_base = res->start;
2599 lcdc_dev->len = resource_size(res);
2600 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2601 if (IS_ERR(lcdc_dev->regs)) {
2602 ret = PTR_ERR(lcdc_dev->regs);
2606 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2607 if (IS_ERR(lcdc_dev->regsbak)) {
2608 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2609 ret = PTR_ERR(lcdc_dev->regsbak);
2612 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2613 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2614 lcdc_dev->prop = PRMRY;
2615 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2616 dev_drv = &lcdc_dev->driver;
2618 dev_drv->prop = lcdc_dev->prop;
2619 dev_drv->id = lcdc_dev->id;
2620 dev_drv->ops = &lcdc_drv_ops;
2621 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2622 spin_lock_init(&lcdc_dev->reg_lock);
2624 lcdc_dev->irq = platform_get_irq(pdev, 0);
2625 if (lcdc_dev->irq < 0) {
2626 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2629 goto err_request_irq;
2632 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2633 IRQF_DISABLED | IRQF_SHARED,
2634 dev_name(dev), lcdc_dev);
2636 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2637 lcdc_dev->irq, ret);
2638 goto err_request_irq;
2641 if (dev_drv->iommu_enabled)
2642 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2644 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2646 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2647 goto err_register_fb;
2649 lcdc_dev->screen = dev_drv->screen0;
2651 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2652 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2657 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2660 devm_kfree(&pdev->dev, lcdc_dev);
2664 #if defined(CONFIG_PM)
2665 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2670 static int rk312x_lcdc_resume(struct platform_device *pdev)
2675 #define rk312x_lcdc_suspend NULL
2676 #define rk312x_lcdc_resume NULL
2679 static int rk312x_lcdc_remove(struct platform_device *pdev)
2684 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2686 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2687 struct rk_lcdc_driver *dev_drv=&lcdc_dev->driver;
2689 flush_kthread_worker(&dev_drv->update_regs_worker);
2690 kthread_stop(dev_drv->update_regs_thread);
2692 rk312x_lcdc_deinit(lcdc_dev);
2693 rk312x_lcdc_clk_disable(lcdc_dev);
2694 rk_disp_pwr_disable(&lcdc_dev->driver);
2697 static struct platform_driver rk312x_lcdc_driver = {
2698 .probe = rk312x_lcdc_probe,
2699 .remove = rk312x_lcdc_remove,
2701 .name = "rk312x-lcdc",
2702 .owner = THIS_MODULE,
2703 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2705 .suspend = rk312x_lcdc_suspend,
2706 .resume = rk312x_lcdc_resume,
2707 .shutdown = rk312x_lcdc_shutdown,
2710 static int __init rk312x_lcdc_module_init(void)
2712 return platform_driver_register(&rk312x_lcdc_driver);
2715 static void __exit rk312x_lcdc_module_exit(void)
2717 platform_driver_unregister(&rk312x_lcdc_driver);
2720 fs_initcall(rk312x_lcdc_module_init);
2721 module_exit(rk312x_lcdc_module_exit);