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);
79 irq_active = int_reg & INT_STA_MSK;
81 lcdc_writel(lcdc_dev, INT_STATUS,
82 int_reg | (irq_active << INT_CLR_SHIFT));
84 if (int_reg & m_FS_INT_STA) {
85 timestamp = ktime_get();
87 /*if (lcdc_dev->driver.wait_fs) {*/
89 spin_lock(&(lcdc_dev->driver.cpl_lock));
90 complete(&(lcdc_dev->driver.frame_done));
91 spin_unlock(&(lcdc_dev->driver.cpl_lock));
93 lcdc_dev->driver.vsync_info.timestamp = timestamp;
94 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
97 if (int_reg & m_LF_INT_STA) {
98 lcdc_dev->driver.frame_time.last_framedone_t =
99 lcdc_dev->driver.frame_time.framedone_t;
100 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
103 if (int_reg & m_HS_INT_STA) {
104 spin_lock(&lcdc_dev->driver.cpl_lock);
105 complete(&lcdc_dev->driver.frame_done);
106 spin_unlock(&lcdc_dev->driver.cpl_lock);
109 #ifdef LCDC_IRQ_EMPTY_DEBUG
110 if (int_reg & m_WIN0_EMPTY_INT_STA) {
111 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN0_EMPTY_INT_CLEAR,
112 v_WIN0_EMPTY_INT_CLEAR(1));
113 dev_info(lcdc_dev->dev, "win0 empty irq\n");
114 } else if (int_reg & m_WIN1_EMPTY_INT_STA) {
115 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_WIN1_EMPTY_INT_CLEAR,
116 v_WIN1_EMPTY_INT_CLEAR(1));
117 dev_info(lcdc_dev->dev, "win1 empty irq\n");
124 static int rk312x_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
126 #ifdef CONFIG_RK_FPGA
127 lcdc_dev->clk_on = 1;
130 if (!lcdc_dev->clk_on) {
131 clk_prepare_enable(lcdc_dev->hclk);
132 clk_prepare_enable(lcdc_dev->dclk);
133 clk_prepare_enable(lcdc_dev->aclk);
134 clk_prepare_enable(lcdc_dev->pd);
135 spin_lock(&lcdc_dev->reg_lock);
136 lcdc_dev->clk_on = 1;
137 spin_unlock(&lcdc_dev->reg_lock);
143 static int rk312x_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
145 #ifdef CONFIG_RK_FPGA
146 lcdc_dev->clk_on = 0;
149 if (lcdc_dev->clk_on) {
150 spin_lock(&lcdc_dev->reg_lock);
151 lcdc_dev->clk_on = 0;
152 spin_unlock(&lcdc_dev->reg_lock);
154 clk_disable_unprepare(lcdc_dev->dclk);
155 clk_disable_unprepare(lcdc_dev->hclk);
156 clk_disable_unprepare(lcdc_dev->aclk);
157 clk_disable_unprepare(lcdc_dev->pd);
163 static int rk312x_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
166 struct lcdc_device *lcdc_dev = container_of(dev_drv,
167 struct lcdc_device, driver);
168 /*struct rk_screen *screen = dev_drv->cur_screen;*/
170 spin_lock(&lcdc_dev->reg_lock);
171 if (likely(lcdc_dev->clk_on)) {
172 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
173 m_LF_INT_CLEAR | m_LF_INT_EN |
174 m_HS_INT_CLEAR | m_HS_INT_EN |
175 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
176 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) |
177 v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
178 v_HS_INT_CLEAR(1) | v_HS_INT_EN(1) |
179 v_BUS_ERR_INT_CLEAR(1) | v_BUS_ERR_INT_EN(0);
181 mask |= m_LF_INT_NUM;
182 val |= v_LF_INT_NUM(screen->mode.vsync_len +
183 screen->mode.upper_margin +
186 #ifdef LCDC_IRQ_EMPTY_DEBUG
187 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
188 val |= v_WIN0_EMPTY_INT_EN(1) | v_WIN1_EMPTY_INT_EN(1);
191 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
192 spin_unlock(&lcdc_dev->reg_lock);
194 spin_unlock(&lcdc_dev->reg_lock);
200 static int rk312x_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
204 spin_lock(&lcdc_dev->reg_lock);
205 if (likely(lcdc_dev->clk_on)) {
206 mask = m_FS_INT_CLEAR | m_FS_INT_EN |
207 m_LF_INT_CLEAR | m_LF_INT_EN |
208 m_HS_INT_CLEAR | m_HS_INT_EN |
209 m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
210 val = v_FS_INT_CLEAR(0) | v_FS_INT_EN(0) |
211 v_LF_INT_CLEAR(0) | v_LF_INT_EN(0) |
212 v_HS_INT_CLEAR(0) | v_HS_INT_EN(0) |
213 v_BUS_ERR_INT_CLEAR(0) | v_BUS_ERR_INT_EN(0);
214 #ifdef LCDC_IRQ_EMPTY_DEBUG
215 mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN;
216 val |= v_WIN0_EMPTY_INT_EN(0) | v_WIN1_EMPTY_INT_EN(0);
219 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
220 spin_unlock(&lcdc_dev->reg_lock);
222 spin_unlock(&lcdc_dev->reg_lock);
229 static int win0_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
231 spin_lock(&lcdc_dev->reg_lock);
232 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, addr);
233 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(1));
234 lcdc_cfg_done(lcdc_dev);
235 spin_unlock(&lcdc_dev->reg_lock);
240 static int win1_set_addr(struct lcdc_device *lcdc_dev, u32 addr)
242 spin_lock(&lcdc_dev->reg_lock);
243 if (lcdc_dev->soc_type == VOP_RK3036)
244 lcdc_writel(lcdc_dev, WIN1_MST, addr);
246 lcdc_writel(lcdc_dev, WIN1_MST_RK312X, addr);
247 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(1));
248 lcdc_cfg_done(lcdc_dev);
249 spin_unlock(&lcdc_dev->reg_lock);
253 int rk312x_lcdc_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
254 int win_id, u32 addr)
256 struct lcdc_device *lcdc_dev = container_of(dev_drv,
257 struct lcdc_device, driver);
259 win0_set_addr(lcdc_dev, addr);
261 win1_set_addr(lcdc_dev, addr);
266 static void rk_lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
270 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
271 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
273 spin_lock(&lcdc_dev->reg_lock);
274 for (reg = 0; reg < 0xe0; reg += 4) {
275 val = lcdc_readl_backup(lcdc_dev, reg);
276 if (reg == WIN0_ACT_INFO) {
277 win0->area[0].xact = (val & m_ACT_WIDTH)+1;
278 win0->area[0].yact = ((val & m_ACT_HEIGHT)>>16)+1;
281 if (lcdc_dev->soc_type == VOP_RK312X) {
282 if (reg == WIN1_DSP_INFO_RK312X) {
283 win1->area[0].xact = (val & m_DSP_WIDTH) + 1;
285 ((val & m_DSP_HEIGHT) >> 16) + 1;
288 if (reg == WIN1_ACT_INFO) {
289 win1->area[0].xact = (val & m_ACT_WIDTH) + 1;
291 ((val & m_ACT_HEIGHT) >> 16) + 1;
295 spin_unlock(&lcdc_dev->reg_lock);
298 static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
302 enum data_format win0_format = lcdc_dev->driver.win[0]->area[0].format;
303 enum data_format win1_format = lcdc_dev->driver.win[1]->area[0].format;
305 int win0_alpha_en = ((win0_format == ARGB888) ||
306 (win0_format == ABGR888)) ? 1 : 0;
307 int win1_alpha_en = ((win1_format == ARGB888) ||
308 (win1_format == ABGR888)) ? 1 : 0;
309 int atv_layer_cnt = lcdc_dev->driver.win[0]->state +
310 lcdc_dev->driver.win[1]->state;
311 u32 *_pv = (u32 *)lcdc_dev->regsbak;
313 _pv += (DSP_CTRL0 >> 2);
314 win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
315 if (win0_top && (atv_layer_cnt >= 2) && (win0_alpha_en)) {
316 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
317 val = v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0);
318 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
320 mask = m_WIN0_ALPHA_MODE |
321 m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
322 val = v_WIN0_ALPHA_MODE(1) |
323 v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
324 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
325 /*this vop bg layer not support yuv domain overlay,so bg val
326 have to set 0x800a80 equeal to 0x000000 at rgb domian,after
327 android start we recover to 0x00000*/
329 val = v_BG_COLOR(0x000000);
330 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
331 } else if ((!win0_top) && (atv_layer_cnt >= 2) &&
333 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
334 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
335 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
337 mask = m_WIN1_ALPHA_MODE |
338 m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
339 if (lcdc_dev->driver.overlay_mode == VOP_YUV_DOMAIN)
340 val = v_WIN0_ALPHA_MODE(1) |
341 v_ALPHA_MODE_SEL0(0) |
342 v_ALPHA_MODE_SEL1(0);
344 val = v_WIN1_ALPHA_MODE(1) |
345 v_ALPHA_MODE_SEL0(1) |
346 v_ALPHA_MODE_SEL1(0);
347 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
348 /*this vop bg layer not support yuv domain overlay,so bg val
349 have to set 0x800a80 equeal to 0x000000 at rgb domian,after
350 android start we recover to 0x00000*/
352 val = v_BG_COLOR(0x000000);
353 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
355 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
356 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
357 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
360 if (lcdc_dev->driver.win[2]->state == 1) {
361 mask = m_HWC_ALPAH_EN;
362 val = v_HWC_ALPAH_EN(1);
363 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
365 mask = m_HWC_ALPHA_MODE;
366 val = v_HWC_ALPHA_MODE(1);
367 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
369 mask = m_HWC_ALPAH_EN;
370 val = v_HWC_ALPAH_EN(0);
371 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
377 static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
378 struct rk_lcdc_win *win)
380 struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
381 struct rk_screen *screen = dev_drv->cur_screen;
383 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
384 switch (win->area[0].fmt_cfg) {
385 case VOP_FORMAT_ARGB888:
386 case VOP_FORMAT_RGB888:
387 case VOP_FORMAT_RGB565:
388 if ((screen->mode.xres < 1280) &&
389 (screen->mode.yres < 720)) {
390 win->csc_mode = VOP_R2Y_CSC_BT601;
392 win->csc_mode = VOP_R2Y_CSC_BT709;
399 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_CSC_MODE,
400 v_WIN0_CSC_MODE(win->csc_mode));
401 } else if (win->id == 1) {
402 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
403 v_WIN1_CSC_MODE(win->csc_mode));
405 } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
406 switch (win->area[0].fmt_cfg) {
407 case VOP_FORMAT_YCBCR420:
409 win->csc_mode = VOP_Y2R_CSC_MPEG;
410 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
412 v_WIN0_CSC_MODE(win->csc_mode));
422 static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
423 struct rk_lcdc_win *win)
428 if (win->state == 1) {
429 if (lcdc_dev->soc_type == VOP_RK312X)
430 lcdc_layer_csc_mode(lcdc_dev, win);
433 mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP |
435 val = v_WIN0_EN(win->state) |
436 v_WIN0_FORMAT(win->area[0].fmt_cfg) |
437 v_WIN0_RB_SWAP(win->area[0].swap_rb) |
438 v_WIN0_UV_SWAP(win->area[0].swap_uv);
439 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
440 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
441 v_X_SCL_FACTOR(win->scale_yrgb_x) |
442 v_Y_SCL_FACTOR(win->scale_yrgb_y));
443 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
444 v_X_SCL_FACTOR(win->scale_cbcr_x) |
445 v_Y_SCL_FACTOR(win->scale_cbcr_y));
447 lcdc_msk_reg(lcdc_dev, WIN0_VIR,
448 m_YRGB_VIR | m_CBBR_VIR,
449 v_YRGB_VIR(win->area[0].y_vir_stride) |
450 v_CBCR_VIR(win->area[0].uv_vir_stride));
451 lcdc_writel(lcdc_dev, WIN0_ACT_INFO,
452 v_ACT_WIDTH(win->area[0].xact) |
453 v_ACT_HEIGHT(win->area[0].yact));
454 lcdc_writel(lcdc_dev, WIN0_DSP_ST,
455 v_DSP_STX(win->area[0].dsp_stx) |
456 v_DSP_STY(win->area[0].dsp_sty));
457 lcdc_writel(lcdc_dev, WIN0_DSP_INFO,
458 v_DSP_WIDTH(win->area[0].xsize) |
459 v_DSP_HEIGHT(win->area[0].ysize));
461 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
462 win->area[0].y_addr);
463 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
464 win->area[0].uv_addr);
465 } else if (win->id == 1) {
466 mask = m_WIN1_EN | m_WIN1_FORMAT | m_WIN1_RB_SWAP;
467 val = v_WIN1_EN(win->state) |
468 v_WIN1_FORMAT(win->area[0].fmt_cfg) |
469 v_WIN1_RB_SWAP(win->area[0].swap_rb);
470 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
471 /* rk312x unsupport win1 scale */
472 if (lcdc_dev->soc_type == VOP_RK3036) {
473 lcdc_writel(lcdc_dev, WIN1_SCL_FACTOR_YRGB,
474 v_X_SCL_FACTOR(win->scale_yrgb_x) |
475 v_Y_SCL_FACTOR(win->scale_yrgb_y));
476 lcdc_writel(lcdc_dev, WIN1_ACT_INFO,
477 v_ACT_WIDTH(win->area[0].xact) |
478 v_ACT_HEIGHT(win->area[0].yact));
479 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,
480 v_DSP_WIDTH(win->area[0].xsize) |
481 v_DSP_HEIGHT(win->area[0].ysize));
482 lcdc_writel(lcdc_dev, WIN1_DSP_ST,
483 v_DSP_STX(win->area[0].dsp_stx) |
484 v_DSP_STY(win->area[0].dsp_sty));
485 lcdc_writel(lcdc_dev,
486 WIN1_MST, win->area[0].y_addr);
488 lcdc_writel(lcdc_dev, WIN1_DSP_INFO_RK312X,
489 v_DSP_WIDTH(win->area[0].xsize) |
490 v_DSP_HEIGHT(win->area[0].ysize));
491 lcdc_writel(lcdc_dev, WIN1_DSP_ST_RK312X,
492 v_DSP_STX(win->area[0].dsp_stx) |
493 v_DSP_STY(win->area[0].dsp_sty));
495 lcdc_writel(lcdc_dev,
497 win->area[0].y_addr);
500 lcdc_msk_reg(lcdc_dev, WIN1_VIR, m_YRGB_VIR,
501 v_YRGB_VIR(win->area[0].y_vir_stride));
504 } else if (win->id == 2) {
505 mask = m_HWC_EN | m_HWC_LODAD_EN;
506 val = v_HWC_EN(win->state) | v_HWC_LODAD_EN(1);
507 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
508 if ((win->area[0].xsize == 32) &&
509 (win->area[0].ysize == 32))
511 else if ((win->area[0].xsize == 64) &&
512 (win->area[0].ysize == 64))
515 dev_err(lcdc_dev->dev, "unsupport hwc size:x=%d,y=%d\n",
516 win->area[0].xsize, win->area[0].ysize);
517 lcdc_writel(lcdc_dev, HWC_DSP_ST,
518 v_DSP_STX(win->area[0].dsp_stx) |
519 v_DSP_STY(win->area[0].dsp_sty));
521 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
524 win->area[0].y_addr = 0;
525 win->area[0].uv_addr = 0;
527 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
529 lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
530 win->area[0].y_addr);
531 lcdc_writel(lcdc_dev, WIN0_CBR_MST,
532 win->area[0].uv_addr);
533 } else if (win->id == 1) {
534 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
536 lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
537 } else if (win->id == 2) {
538 lcdc_msk_reg(lcdc_dev,
539 SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
540 v_HWC_EN(0) | v_HWC_LODAD_EN(0));
541 lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
544 rk312x_lcdc_alpha_cfg(lcdc_dev);
547 static void lcdc_layer_enable(struct lcdc_device *lcdc_dev, unsigned int win_id,
550 spin_lock(&lcdc_dev->reg_lock);
551 if (likely(lcdc_dev->clk_on) &&
552 lcdc_dev->driver.win[win_id]->state != open) {
554 if (!lcdc_dev->atv_layer_cnt) {
555 dev_info(lcdc_dev->dev,
556 "wakeup from standby!\n");
557 lcdc_dev->standby = 0;
559 lcdc_dev->atv_layer_cnt |= (1 << win_id);
560 } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
561 lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
563 lcdc_dev->driver.win[win_id]->state = open;
565 lcdc_layer_update_regs(lcdc_dev,
566 lcdc_dev->driver.win[win_id]);
567 lcdc_cfg_done(lcdc_dev);
569 /*if no layer used,disable lcdc */
570 if (!lcdc_dev->atv_layer_cnt) {
571 dev_info(lcdc_dev->dev,
572 "no layer is used,go to standby!\n");
573 lcdc_dev->standby = 1;
576 spin_unlock(&lcdc_dev->reg_lock);
579 static int rk312x_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
581 struct lcdc_device *lcdc_dev =
582 container_of(dev_drv, struct lcdc_device, driver);
583 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
584 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
587 spin_lock(&lcdc_dev->reg_lock);
588 if (likely(lcdc_dev->clk_on)) {
589 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
590 v_LCDC_STANDBY(lcdc_dev->standby));
591 lcdc_layer_update_regs(lcdc_dev, win0);
592 lcdc_layer_update_regs(lcdc_dev, win1);
593 rk312x_lcdc_alpha_cfg(lcdc_dev);
594 lcdc_cfg_done(lcdc_dev);
597 spin_unlock(&lcdc_dev->reg_lock);
598 //if (dev_drv->wait_fs) {
600 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
601 init_completion(&dev_drv->frame_done);
602 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
603 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
605 (dev_drv->cur_screen->ft +
607 if (!timeout && (!dev_drv->frame_done.done)) {
608 dev_warn(lcdc_dev->dev,
609 "wait for new frame start time out!\n");
613 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
618 static void rk312x_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
620 memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0xe0);
623 static int rk312x_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
626 struct lcdc_device *lcdc_dev =
627 container_of(dev_drv, struct lcdc_device, driver);
629 /*spin_lock(&lcdc_dev->reg_lock);*/
630 if (likely(lcdc_dev->clk_on)) {
631 mask = m_MMU_EN | m_AXI_MAX_OUTSTANDING_EN |
632 m_AXI_OUTSTANDING_MAX_NUM;
633 val = v_MMU_EN(1) | v_AXI_OUTSTANDING_MAX_NUM(31) |
634 v_AXI_MAX_OUTSTANDING_EN(1);
635 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
637 /*spin_unlock(&lcdc_dev->reg_lock);*/
638 if (dev_drv->iommu_enabled) {
639 if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
640 lcdc_dev->iommu_status = 1;
641 rockchip_iovmm_activate(dev_drv->dev);
648 static int rk312x_lcdc_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
649 int *hwc_lut, int mode)
655 struct lcdc_device *lcdc_dev =
656 container_of(dev_drv, struct lcdc_device, driver);
657 if (dev_drv->hwc_lut == NULL)
658 dev_drv->hwc_lut = devm_kzalloc(lcdc_dev->dev, len, GFP_KERNEL);
660 spin_lock(&lcdc_dev->reg_lock);
661 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(0));
662 lcdc_cfg_done(lcdc_dev);
664 for (i = 0; i < 256; i++) {
666 dev_drv->hwc_lut[i] = hwc_lut[i];
667 v = dev_drv->hwc_lut[i];
668 c = lcdc_dev->hwc_lut_addr_base + i;
669 writel_relaxed(v, c);
671 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_LUT_EN, v_HWC_LUT_EN(1));
672 lcdc_cfg_done(lcdc_dev);
673 spin_unlock(&lcdc_dev->reg_lock);
678 static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv,
684 struct lcdc_device *lcdc_dev =
685 container_of(dev_drv, struct lcdc_device, driver);
690 spin_lock(&lcdc_dev->reg_lock);
691 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
692 lcdc_cfg_done(lcdc_dev);
694 for (i = 0; i < 256; i++) {
696 c = lcdc_dev->dsp_lut_addr_base + i;
697 writel_relaxed(v, c);
699 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
700 lcdc_cfg_done(lcdc_dev);
701 spin_unlock(&lcdc_dev->reg_lock);
705 static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
708 #ifdef CONFIG_RK_FPGA
712 struct lcdc_device *lcdc_dev =
713 container_of(dev_drv, struct lcdc_device, driver);
714 struct rk_screen *screen = dev_drv->cur_screen;
717 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
719 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
721 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
722 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
724 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
725 screen->ft = 1000 / fps;
726 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
727 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
731 static int rk312x_lcdc_standby(struct rk_lcdc_driver *dev_drv, bool enable)
733 struct lcdc_device *vop_dev =
734 container_of(dev_drv, struct lcdc_device, driver);
738 if (unlikely(!vop_dev->clk_on))
741 if (dev_drv->standby && !enable) {
742 dev_drv->standby = 0;
743 lcdc_msk_reg(vop_dev, SYS_CTRL, m_LCDC_STANDBY,
746 } else if (!dev_drv->standby && enable) {
747 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
748 init_completion(&dev_drv->frame_done);
749 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
751 lcdc_msk_reg(vop_dev, SYS_CTRL, m_LCDC_STANDBY,
753 /* wait for standby hold valid */
754 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
755 msecs_to_jiffies(25));
757 if (!timeout && (!dev_drv->frame_done.done)) {
758 dev_info(dev_drv->dev,
759 "wait for standy hold valid start time out!\n");
763 dev_drv->standby = 1;
769 /********do basic init*********/
770 static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
772 struct lcdc_device *lcdc_dev = container_of(dev_drv,
773 struct lcdc_device, driver);
774 if (lcdc_dev->pre_init)
777 lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
778 lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
779 lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
780 lcdc_dev->sclk = devm_clk_get(lcdc_dev->dev, "sclk_lcdc");
781 lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
782 lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
784 if (/*IS_ERR(lcdc_dev->pd) || */ (IS_ERR(lcdc_dev->aclk)) ||
785 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
786 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
790 rk_disp_pwr_enable(dev_drv);
791 rk312x_lcdc_clk_enable(lcdc_dev);
793 /* backup reg config at uboot */
794 rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
796 /* config for the FRC mode of dither down */
797 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
798 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
799 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
800 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
801 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
802 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
804 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN, v_AUTO_GATING_EN(0));
805 lcdc_cfg_done(lcdc_dev);
806 /*if (dev_drv->iommu_enabled)
807 {// disable all wins to workaround iommu pagefault
808 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN | m_WIN1_EN,
809 v_WIN0_EN(0) | v_WIN1_EN(0));
810 lcdc_cfg_done(lcdc_dev);
811 while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
813 if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
814 if (support_uboot_display())
815 dev_drv->bcsh_init_status = 1;
817 dev_drv->ops->open_bcsh(dev_drv, 1);
819 lcdc_dev->pre_init = true;
824 static void rk312x_lcdc_deinit(struct lcdc_device *lcdc_dev)
826 rk312x_lcdc_disable_irq(lcdc_dev);
829 static u32 calc_sclk_freq(struct rk_screen *src_screen,
830 struct rk_screen *dst_screen)
838 if (!src_screen || !dst_screen)
841 dsp_vtotal = dst_screen->mode.yres;
842 dsp_htotal = dst_screen->mode.left_margin + dst_screen->mode.hsync_len +
843 dst_screen->mode.xres + dst_screen->mode.right_margin;
844 dsp_in_vtotal = src_screen->mode.yres;
845 dsp_in_htotal = src_screen->mode.left_margin +
846 src_screen->mode.hsync_len +
847 src_screen->mode.xres + src_screen->mode.right_margin;
848 sclk_freq = dsp_vtotal * dsp_htotal * src_screen->mode.pixclock;
849 do_div(sclk_freq, dsp_in_vtotal * dsp_in_htotal);
851 return (u32)sclk_freq;
854 #define SCLK_PLL_LIMIT 594000000
855 #define GPU_FREQ_MAX_LIMIT 297000000
856 #define GPU_FREQ_NEED 400000000
858 static u32 calc_sclk_pll_freq(u32 sclk_freq)
862 if (sclk_freq < (SCLK_PLL_LIMIT / 10)) {
863 return (sclk_freq * 10);
865 multi_num = GPU_FREQ_NEED / sclk_freq;
866 return (sclk_freq * multi_num);
870 static int calc_dsp_frm_vst_hst(struct rk_screen *src,
871 struct rk_screen *dst, u32 sclk_freq)
876 u64 T_BP_in, T_BP_out, T_Delta, Tin;
877 u32 src_pixclock, dst_pixclock;
879 u32 dsp_htotal, dsp_vtotal, src_htotal, src_vtotal;
881 if (unlikely(!src) || unlikely(!dst))
884 src_pixclock = div_u64(1000000000000llu, src->mode.pixclock);
885 dst_pixclock = div_u64(1000000000000llu, sclk_freq);
886 dsp_htotal = dst->mode.left_margin + dst->mode.hsync_len +
887 dst->mode.xres + dst->mode.right_margin;
888 dsp_vtotal = dst->mode.upper_margin + dst->mode.vsync_len +
889 dst->mode.yres + dst->mode.lower_margin;
890 src_htotal = src->mode.left_margin + src->mode.hsync_len +
891 src->mode.xres + src->mode.right_margin;
892 src_vtotal = src->mode.upper_margin + src->mode.vsync_len +
893 src->mode.yres + src->mode.lower_margin;
894 BP_in = (src->mode.upper_margin + src->mode.vsync_len) * src_htotal +
895 src->mode.hsync_len + src->mode.left_margin;
896 BP_out = (dst->mode.upper_margin + dst->mode.vsync_len) * dsp_htotal +
897 dst->mode.hsync_len + dst->mode.left_margin;
899 T_BP_in = BP_in * src_pixclock;
900 T_BP_out = BP_out * dst_pixclock;
901 Tin = src_vtotal * src_htotal * src_pixclock;
903 v_scale_ratio = src->mode.yres / dst->mode.yres;
904 if (v_scale_ratio <= 2)
905 T_Delta = 5 * src_htotal * src_pixclock;
907 T_Delta = 12 * src_htotal * src_pixclock;
909 if (T_BP_in + T_Delta > T_BP_out)
910 T_frm_st = (T_BP_in + T_Delta - T_BP_out);
912 T_frm_st = Tin - (T_BP_out - (T_BP_in + T_Delta));
914 /* (T_frm_st = scl_vst * src_htotal * src_pixclock +
915 scl_hst * src_pixclock) */
916 temp = do_div(T_frm_st, src_pixclock);
917 temp = do_div(T_frm_st, src_htotal);
918 dst->scl_hst = temp - 1;
919 dst->scl_vst = T_frm_st;
924 static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
925 struct rk_screen *dst_screen, bool enable)
927 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end;
928 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end;
929 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st;
930 u32 scl_v_factor, scl_h_factor;
931 u32 dst_frame_hst, dst_frame_vst;
932 u32 src_w, src_h, dst_w, dst_h;
938 struct rk_screen *src;
939 struct rk_screen *dst;
940 struct lcdc_device *lcdc_dev = container_of(dev_drv,
941 struct lcdc_device, driver);
942 struct dvfs_node *gpu_clk = clk_get_dvfs_node("clk_gpu");
944 if (unlikely(!lcdc_dev->clk_on))
948 spin_lock(&lcdc_dev->reg_lock);
949 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
950 m_SCALER_EN | m_SCALER_OUT_ZERO |
952 v_SCALER_EN(0) | v_SCALER_OUT_ZERO(1) |
954 lcdc_cfg_done(lcdc_dev);
955 spin_unlock(&lcdc_dev->reg_lock);
956 if (lcdc_dev->sclk_on) {
957 clk_disable_unprepare(lcdc_dev->sclk);
958 lcdc_dev->sclk_on = false;
961 /* switch pll freq as default when sclk is no used */
962 if (clk_get_rate(lcdc_dev->pll_sclk) != GPU_FREQ_NEED) {
963 dvfs_clk_enable_limit(gpu_clk, GPU_FREQ_MAX_LIMIT,
965 clk_set_rate(lcdc_dev->pll_sclk, GPU_FREQ_NEED);
966 dvfs_clk_enable_limit(gpu_clk, 0, -1);
968 dev_dbg(lcdc_dev->dev, "%s: disable\n", __func__);
973 * rk312x used one lcdc to apply dual disp
974 * hdmi screen is used for scaler src
975 * prmry screen is used for scaler dst
978 src = dev_drv->cur_screen;
980 dev_err(lcdc_dev->dev, "%s: dst screen is null!\n", __func__);
984 if (!lcdc_dev->sclk_on) {
985 clk_prepare_enable(lcdc_dev->sclk);
986 lcdc_dev->s_pixclock = calc_sclk_freq(src, dst);
987 pll_freq = calc_sclk_pll_freq(lcdc_dev->s_pixclock);
990 dvfs_clk_enable_limit(gpu_clk,
994 clk_set_rate(lcdc_dev->pll_sclk, pll_freq);
995 /* cancel limit gpu freq */
996 dvfs_clk_enable_limit(gpu_clk, 0, -1);
998 clk_set_rate(lcdc_dev->sclk, lcdc_dev->s_pixclock);
999 lcdc_dev->sclk_on = true;
1000 dev_info(lcdc_dev->dev, "%s:sclk=%d\n", __func__,
1001 lcdc_dev->s_pixclock);
1004 /* config scale timing */
1005 calc_dsp_frm_vst_hst(src, dst, lcdc_dev->s_pixclock);
1006 dst_frame_vst = dst->scl_vst;
1007 dst_frame_hst = dst->scl_hst;
1009 dsp_htotal = dst->mode.hsync_len + dst->mode.left_margin +
1010 dst->mode.xres + dst->mode.right_margin;
1011 dsp_hs_end = dst->mode.hsync_len;
1013 dsp_vtotal = dst->mode.vsync_len + dst->mode.upper_margin +
1014 dst->mode.yres + dst->mode.lower_margin;
1015 dsp_vs_end = dst->mode.vsync_len;
1017 dsp_hbor_end = dst->mode.hsync_len + dst->mode.left_margin +
1019 dsp_hbor_st = dst->mode.hsync_len + dst->mode.left_margin;
1020 dsp_vbor_end = dst->mode.vsync_len + dst->mode.upper_margin +
1022 dsp_vbor_st = dst->mode.vsync_len + dst->mode.upper_margin;
1024 dsp_hact_st = dsp_hbor_st + bor_left;
1025 dsp_hact_end = dsp_hbor_end - bor_right;
1026 dsp_vact_st = dsp_vbor_st + bor_up;
1027 dsp_vact_end = dsp_vbor_end - bor_down;
1029 src_w = src->mode.xres;
1030 src_h = src->mode.yres;
1031 dst_w = dsp_hact_end - dsp_hact_st;
1032 dst_h = dsp_vact_end - dsp_vact_st;
1034 /* calc scale factor */
1035 scl_h_factor = ((src_w - 1) << 12) / (dst_w - 1);
1036 scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1);
1038 spin_lock(&lcdc_dev->reg_lock);
1039 if (dst->color_mode != src->color_mode) {
1040 /*dev_drv->output_color = dst->color_mode;
1041 if (dev_drv->output_color == COLOR_YCBCR)
1042 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1044 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1045 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1046 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));*/
1049 lcdc_writel(lcdc_dev, SCALER_FACTOR,
1050 v_SCALER_H_FACTOR(scl_h_factor) |
1051 v_SCALER_V_FACTOR(scl_v_factor));
1053 lcdc_writel(lcdc_dev, SCALER_FRAME_ST,
1054 v_SCALER_FRAME_HST(dst_frame_hst) |
1055 v_SCALER_FRAME_VST(dst_frame_vst));
1056 lcdc_writel(lcdc_dev, SCALER_DSP_HOR_TIMING,
1057 v_SCALER_HS_END(dsp_hs_end) |
1058 v_SCALER_HTOTAL(dsp_htotal));
1059 lcdc_writel(lcdc_dev, SCALER_DSP_HACT_ST_END,
1060 v_SCALER_HAEP(dsp_hact_end) |
1061 v_SCALER_HASP(dsp_hact_st));
1062 lcdc_writel(lcdc_dev, SCALER_DSP_VER_TIMING,
1063 v_SCALER_VS_END(dsp_vs_end) |
1064 v_SCALER_VTOTAL(dsp_vtotal));
1065 lcdc_writel(lcdc_dev, SCALER_DSP_VACT_ST_END,
1066 v_SCALER_VAEP(dsp_vact_end) |
1067 v_SCALER_VASP(dsp_vact_st));
1068 lcdc_writel(lcdc_dev, SCALER_DSP_HBOR_TIMING,
1069 v_SCALER_HBOR_END(dsp_hbor_end) |
1070 v_SCALER_HBOR_ST(dsp_hbor_st));
1071 lcdc_writel(lcdc_dev, SCALER_DSP_VBOR_TIMING,
1072 v_SCALER_VBOR_END(dsp_vbor_end) |
1073 v_SCALER_VBOR_ST(dsp_vbor_st));
1074 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1075 m_SCALER_VSYNC_VST | m_SCALER_VSYNC_MODE,
1076 v_SCALER_VSYNC_VST(4) | v_SCALER_VSYNC_MODE(2));
1077 lcdc_msk_reg(lcdc_dev, SCALER_CTRL,
1078 m_SCALER_EN | m_SCALER_OUT_ZERO |
1080 v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) |
1081 v_SCALER_OUT_EN(1));
1083 lcdc_cfg_done(lcdc_dev);
1084 spin_unlock(&lcdc_dev->reg_lock);
1089 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
1090 struct lcdc_device *lcdc_dev)
1093 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1094 if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
1095 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1096 m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
1097 v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
1099 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1100 m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
1103 v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1105 } else { /* overlay_mode=VOP_RGB_DOMAIN */
1106 if (dev_drv->output_color == COLOR_RGB) {
1108 bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
1109 if (((bcsh_ctrl&m_BCSH_EN) == 1) ||
1110 (dev_drv->bcsh.enable == 1))/*bcsh enabled*/
1111 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1112 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1113 v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
1114 else/*bcsh disabled*/
1115 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1116 m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
1117 v_BCSH_R2Y_EN(0) | v_BCSH_Y2R_EN(0));
1118 } else /* RGB2YUV */
1119 lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
1121 m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
1123 v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1128 static int rk312x_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1129 u16 *yact, int *format, u32 *dsp_addr,
1132 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1133 struct lcdc_device, driver);
1136 spin_lock(&lcdc_dev->reg_lock);
1138 val = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1139 *xact = (val & m_ACT_WIDTH)+1;
1140 *yact = ((val & m_ACT_HEIGHT)>>16)+1;
1142 val = lcdc_readl(lcdc_dev, SYS_CTRL);
1144 *format = (val & m_WIN0_FORMAT) >> 3;
1145 *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
1147 spin_unlock(&lcdc_dev->reg_lock);
1152 static int rk312x_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1153 int format, u16 xact, u16 yact, u16 xvir,
1156 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1157 struct lcdc_device, driver);
1158 struct rk_lcdc_win *win = dev_drv->win[0];
1161 mask = m_WIN0_FORMAT;
1162 val = v_WIN0_FORMAT(format);
1163 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1165 lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_YRGB_VIR,
1167 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(xact) |
1168 v_ACT_HEIGHT(yact));
1170 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
1172 lcdc_cfg_done(lcdc_dev);
1174 win->last_state = 1;
1179 static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1182 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1183 struct lcdc_device, driver);
1184 struct rk_screen *screen = dev_drv->cur_screen;
1185 u16 right_margin = screen->mode.right_margin;
1186 u16 left_margin = screen->mode.left_margin;
1187 u16 lower_margin = screen->mode.lower_margin;
1188 u16 upper_margin = screen->mode.upper_margin;
1189 u16 x_res = screen->mode.xres;
1190 u16 y_res = screen->mode.yres;
1193 spin_lock(&lcdc_dev->reg_lock);
1194 if (likely(lcdc_dev->clk_on)) {
1195 /* Select output color domain */
1196 dev_drv->output_color = screen->color_mode;
1197 /*if (lcdc_dev->soc_type == VOP_RK312X) {
1198 if (dev_drv->output_color == COLOR_YCBCR)
1199 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1201 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1203 dev_drv->output_color = COLOR_RGB;
1204 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1206 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1207 /*something wrong at yuv domain*/
1209 switch (screen->type) {
1211 if (lcdc_dev->soc_type == VOP_RK312X) {
1212 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
1213 val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
1214 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1218 if (lcdc_dev->soc_type == VOP_RK312X) {
1219 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
1220 val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
1221 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1225 if (lcdc_dev->soc_type == VOP_RK312X) {
1226 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
1227 val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
1228 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1232 mask = m_HDMI_DCLK_EN;
1233 val = v_HDMI_DCLK_EN(1);
1234 if (screen->pixelrepeat) {
1235 mask |= m_CORE_CLK_DIV_EN;
1236 val |= v_CORE_CLK_DIV_EN(1);
1238 mask |= m_CORE_CLK_DIV_EN;
1239 val |= v_CORE_CLK_DIV_EN(0);
1241 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1242 if (lcdc_dev->soc_type == VOP_RK312X) {
1243 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1245 v_SW_UV_OFFSET_EN(0));
1246 mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
1248 val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
1249 v_HDMI_VSYNC_POL(screen->pin_vsync) |
1250 v_HDMI_DEN_POL(screen->pin_den);
1251 lcdc_msk_reg(lcdc_dev, INT_SCALER, mask, val);
1253 mask = (1 << 4) | (1 << 5) | (1 << 6);
1254 val = (screen->pin_hsync << 4) |
1255 (screen->pin_vsync << 5) |
1256 (screen->pin_den << 6);
1257 grf_writel(RK3036_GRF_SOC_CON2,
1258 (mask << 16) | val);
1260 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1263 case SCREEN_TVOUT_TEST:
1264 mask = m_TVE_DAC_DCLK_EN;
1265 val = v_TVE_DAC_DCLK_EN(1);
1266 if (screen->pixelrepeat) {
1267 mask |= m_CORE_CLK_DIV_EN;
1268 val |= v_CORE_CLK_DIV_EN(1);
1270 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
1271 if (x_res == 720 && y_res == 576)
1272 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1273 v_TVE_MODE(TV_PAL));
1274 else if (x_res == 720 && y_res == 480)
1275 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_TVE_MODE,
1276 v_TVE_MODE(TV_NTSC));
1278 dev_err(lcdc_dev->dev,
1279 "unsupported video timing!\n");
1282 if (lcdc_dev->soc_type == VOP_RK312X) {
1283 if (screen->type == SCREEN_TVOUT_TEST)
1284 /*for TVE index test,vop must ovarlay at yuv domain*/
1285 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1286 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1288 v_SW_UV_OFFSET_EN(1));
1290 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
1294 dev_err(lcdc_dev->dev, "un supported interface!\n");
1297 if (lcdc_dev->soc_type == VOP_RK312X) {
1298 switch (dev_drv->screen0->face) {
1301 mask = m_DITHER_DOWN_EN |
1302 m_DITHER_DOWN_MODE |
1304 val = v_DITHER_DOWN_EN(1) |
1305 v_DITHER_DOWN_MODE(0) |
1306 v_DITHER_DOWN_SEL(1);
1307 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1311 mask = m_DITHER_DOWN_EN |
1312 m_DITHER_DOWN_MODE |
1314 val = v_DITHER_DOWN_EN(1) |
1315 v_DITHER_DOWN_MODE(1) |
1316 v_DITHER_DOWN_SEL(1);
1317 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1321 mask = m_DITHER_DOWN_EN |
1322 m_DITHER_DOWN_MODE |
1324 val = v_DITHER_DOWN_EN(1) |
1325 v_DITHER_DOWN_MODE(0) |
1326 v_DITHER_DOWN_SEL(1);
1327 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1331 mask = m_DITHER_DOWN_EN |
1332 m_DITHER_DOWN_MODE |
1334 val = v_DITHER_DOWN_EN(1) |
1335 v_DITHER_DOWN_MODE(1) |
1336 v_DITHER_DOWN_SEL(1);
1337 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1341 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1342 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1343 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1346 dev_err(lcdc_dev->dev, "un supported interface!\n");
1349 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
1350 v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
1353 mask = m_HSYNC_POL | m_VSYNC_POL |
1354 m_DEN_POL | m_DCLK_POL;
1355 val = v_HSYNC_POL(screen->pin_hsync) |
1356 v_VSYNC_POL(screen->pin_vsync) |
1357 v_DEN_POL(screen->pin_den) |
1358 v_DCLK_POL(screen->pin_dclk);
1360 if (screen->type != SCREEN_HDMI) {
1361 mask |= m_DSP_OUT_FORMAT;
1362 val |= v_DSP_OUT_FORMAT(face);
1365 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1367 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
1368 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1369 m_DSP_DUMMY_SWAP | m_BLANK_EN | m_BLACK_EN;
1371 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
1372 v_DSP_RB_SWAP(screen->swap_rb) |
1373 v_DSP_RG_SWAP(screen->swap_rg) |
1374 v_DSP_DELTA_SWAP(screen->swap_delta) |
1375 v_DSP_DUMMY_SWAP(screen->swap_dumy) |
1376 v_BLANK_EN(0) | v_BLACK_EN(0);
1377 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1380 val = v_HSYNC(screen->mode.hsync_len) |
1381 v_HORPRD(screen->mode.hsync_len + left_margin + x_res +
1383 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
1384 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
1385 v_HASP(screen->mode.hsync_len + left_margin);
1386 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
1388 if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1389 /* First Field Timing */
1390 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END,
1391 v_VSYNC(screen->mode.vsync_len) |
1392 v_VERPRD(2 * (screen->mode.vsync_len +
1394 lower_margin) + y_res + 1));
1395 lcdc_writel(lcdc_dev, DSP_VACT_ST_END,
1396 v_VAEP(screen->mode.vsync_len +
1397 upper_margin + y_res / 2) |
1398 v_VASP(screen->mode.vsync_len +
1400 /* Second Field Timing */
1401 lcdc_writel(lcdc_dev, DSP_VS_ST_END_F1,
1402 v_VSYNC_ST_F1(screen->mode.vsync_len +
1403 upper_margin + y_res / 2 +
1405 v_VSYNC_END_F1(2 * screen->mode.vsync_len +
1406 upper_margin + y_res / 2 +
1408 lcdc_writel(lcdc_dev, DSP_VACT_ST_END_F1,
1409 v_VAEP(2 * (screen->mode.vsync_len +
1411 y_res + lower_margin + 1) |
1412 v_VASP(2 * (screen->mode.vsync_len +
1414 y_res / 2 + lower_margin + 1));
1416 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1417 m_INTERLACE_DSP_EN |
1418 m_WIN0_YRGB_DEFLICK_EN |
1419 m_WIN0_CBR_DEFLICK_EN |
1420 m_INTERLACE_FIELD_POL |
1421 m_WIN0_INTERLACE_EN |
1422 m_WIN1_INTERLACE_EN,
1423 v_INTERLACE_DSP_EN(1) |
1424 v_WIN0_YRGB_DEFLICK_EN(1) |
1425 v_WIN0_CBR_DEFLICK_EN(1) |
1426 v_INTERLACE_FIELD_POL(0) |
1427 v_WIN0_INTERLACE_EN(1) |
1428 v_WIN1_INTERLACE_EN(1));
1429 mask = m_LF_INT_NUM;
1430 val = v_LF_INT_NUM(screen->mode.vsync_len +
1431 screen->mode.upper_margin +
1432 screen->mode.yres/2);
1433 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1435 val = v_VSYNC(screen->mode.vsync_len) |
1436 v_VERPRD(screen->mode.vsync_len + upper_margin +
1437 y_res + lower_margin);
1438 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
1440 val = v_VAEP(screen->mode.vsync_len +
1441 upper_margin + y_res) |
1442 v_VASP(screen->mode.vsync_len + upper_margin);
1443 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
1445 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
1446 m_INTERLACE_DSP_EN |
1447 m_WIN0_YRGB_DEFLICK_EN |
1448 m_WIN0_CBR_DEFLICK_EN |
1449 m_INTERLACE_FIELD_POL |
1450 m_WIN0_INTERLACE_EN |
1451 m_WIN1_INTERLACE_EN,
1452 v_INTERLACE_DSP_EN(0) |
1453 v_WIN0_YRGB_DEFLICK_EN(0) |
1454 v_WIN0_CBR_DEFLICK_EN(0) |
1455 v_INTERLACE_FIELD_POL(0) |
1456 v_WIN0_INTERLACE_EN(0) |
1457 v_WIN1_INTERLACE_EN(0));
1458 mask = m_LF_INT_NUM;
1459 val = v_LF_INT_NUM(screen->mode.vsync_len +
1460 screen->mode.upper_margin +
1462 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
1465 spin_unlock(&lcdc_dev->reg_lock);
1467 rk312x_lcdc_set_dclk(dev_drv, 1);
1468 lcdc_cfg_done(lcdc_dev);
1470 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1471 dev_drv->trsm_ops->enable();
1478 static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1481 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1482 struct lcdc_device, driver);
1484 /* enable clk,when first layer open */
1485 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1486 rockchip_set_system_status(SYS_STATUS_LCDC0);
1487 rk312x_lcdc_pre_init(dev_drv);
1488 rk312x_lcdc_clk_enable(lcdc_dev);
1489 if (dev_drv->iommu_enabled) {
1490 if (!dev_drv->mmu_dev) {
1492 rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1493 if (dev_drv->mmu_dev) {
1494 rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1497 dev_err(dev_drv->dev,
1498 "failed to get rockchip iommu device\n");
1502 /*if (dev_drv->mmu_dev)
1503 rockchip_iovmm_activate(dev_drv->dev);*/
1505 rk312x_lcdc_reg_restore(lcdc_dev);
1506 /*if (dev_drv->iommu_enabled)
1507 rk312x_lcdc_mmu_en(dev_drv);*/
1508 if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
1509 rk312x_lcdc_set_dclk(dev_drv, 0);
1510 rk312x_lcdc_enable_irq(dev_drv);
1512 dev_drv->standby = 1;
1513 rk312x_load_screen(dev_drv, 1);
1514 rk312x_lcdc_standby(dev_drv, false);
1517 /* set screen lut */
1518 if (dev_drv->cur_screen->dsp_lut)
1519 rk312x_lcdc_set_lut(dev_drv,
1520 dev_drv->cur_screen->dsp_lut);
1523 if (win_id < ARRAY_SIZE(lcdc_win))
1524 lcdc_layer_enable(lcdc_dev, win_id, open);
1526 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1528 /* when all layer closed,disable clk */
1529 /* if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1530 rk312x_lcdc_disable_irq(lcdc_dev);
1531 rk312x_lcdc_reg_update(dev_drv);
1532 if (dev_drv->iommu_enabled) {
1533 if (dev_drv->mmu_dev)
1534 rockchip_iovmm_deactivate(dev_drv->dev);
1536 rk312x_lcdc_clk_disable(lcdc_dev);
1537 rockchip_clear_system_status(SYS_STATUS_LCDC0);
1542 static int rk312x_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1544 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1545 struct lcdc_device, driver);
1546 struct rk_screen *screen = dev_drv->cur_screen;
1547 struct rk_lcdc_win *win = NULL;
1548 char fmt[9] = "NULL";
1551 dev_err(dev_drv->dev, "screen is null!\n");
1556 win = dev_drv->win[0];
1557 } else if (win_id == 1) {
1558 win = dev_drv->win[1];
1559 } else if (win_id == 2) {
1560 win = dev_drv->win[2];
1562 dev_err(dev_drv->dev, "un supported win number:%d\n", win_id);
1566 spin_lock(&lcdc_dev->reg_lock);
1567 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1568 screen->mode.hsync_len;
1570 if ((win->area[0].xact != win->area[0].xsize) ||
1571 (win->area[0].yact != win->area[0].ysize)) {
1572 pr_err("win[1],not support scale\n");
1573 pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
1574 win->area[0].xact,win->area[0].yact,
1575 win->area[0].xsize,win->area[0].ysize);
1576 win->area[0].xsize = win->area[0].xact;
1577 win->area[0].ysize = win->area[0].yact;
1580 if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1581 win->area[0].ysize /= 2;
1582 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1583 screen->mode.upper_margin +
1584 screen->mode.vsync_len;
1586 win->area[0].dsp_sty = win->area[0].ypos +
1587 screen->mode.upper_margin +
1588 screen->mode.vsync_len;
1590 win->scale_yrgb_x = CalScale(win->area[0].xact, win->area[0].xsize);
1591 win->scale_yrgb_y = CalScale(win->area[0].yact, win->area[0].ysize);
1593 switch (win->area[0].format) {
1595 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1596 win->area[0].swap_rb = 0;
1597 win->area[0].swap_uv = 0;
1600 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1601 win->area[0].swap_rb = 1;
1602 win->area[0].swap_uv = 0;
1605 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1606 win->area[0].swap_rb = 1;
1607 win->area[0].swap_uv = 0;
1610 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1611 win->area[0].swap_rb = 0;
1612 win->area[0].swap_uv = 0;
1615 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1616 win->area[0].swap_rb = 0;
1620 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1622 CalScale(win->area[0].xact, win->area[0].xsize);
1624 CalScale(win->area[0].yact, win->area[0].ysize);
1625 win->area[0].swap_rb = 0;
1626 win->area[0].swap_uv = 0;
1628 dev_err(lcdc_dev->driver.dev,
1629 "%s:un supported format!\n", __func__);
1634 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1635 win->scale_cbcr_x = CalScale((win->area[0].xact / 2),
1636 win->area[0].xsize);
1638 CalScale(win->area[0].yact, win->area[0].ysize);
1639 win->area[0].swap_rb = 0;
1640 win->area[0].swap_uv = 0;
1642 dev_err(lcdc_dev->driver.dev,
1643 "%s:un supported format!\n", __func__);
1648 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1650 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1652 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1653 win->area[0].swap_rb = 0;
1654 win->area[0].swap_uv = 0;
1656 dev_err(lcdc_dev->driver.dev,
1657 "%s:un supported format!\n", __func__);
1662 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1664 CalScale(win->area[0].xact / 2, win->area[0].xsize);
1666 CalScale(win->area[0].yact / 2, win->area[0].ysize);
1667 win->area[0].swap_rb = 0;
1668 win->area[0].swap_uv = 1;
1670 dev_err(lcdc_dev->driver.dev,
1671 "%s:un supported format!\n", __func__);
1675 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
1679 spin_unlock(&lcdc_dev->reg_lock);
1682 "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
1683 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id, __func__,
1684 get_format_string(win->area[0].format, fmt), win->area[0].xact,
1685 win->area[0].yact, win->area[0].xsize, win->area[0].ysize,
1686 win->area[0].xvir, win->area[0].yvir, win->area[0].xpos,
1691 static int rk312x_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1693 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1694 struct lcdc_device, driver);
1695 struct rk_lcdc_win *win = NULL;
1696 struct rk_screen *screen = dev_drv->cur_screen;
1699 dev_err(dev_drv->dev, "screen is null!\n");
1704 win = dev_drv->win[0];
1705 } else if (win_id == 1) {
1706 win = dev_drv->win[1];
1707 } else if (win_id == 2) {
1708 win = dev_drv->win[2];
1710 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1714 spin_lock(&lcdc_dev->reg_lock);
1715 if (likely(lcdc_dev->clk_on)) {
1716 win->area[0].y_addr =
1717 win->area[0].smem_start + win->area[0].y_offset;
1718 win->area[0].uv_addr =
1719 win->area[0].cbr_start + win->area[0].c_offset;
1720 if (win->area[0].y_addr)
1721 lcdc_layer_update_regs(lcdc_dev, win);
1722 /* lcdc_cfg_done(lcdc_dev); */
1724 spin_unlock(&lcdc_dev->reg_lock);
1726 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1727 lcdc_dev->id, __func__, win->area[0].y_addr, win->area[0].uv_addr,
1728 win->area[0].y_offset);
1729 /* this is the first frame of the system,enable frame start interrupt */
1730 if ((dev_drv->first_frame)) {
1731 dev_drv->first_frame = 0;
1732 rk312x_lcdc_enable_irq(dev_drv);
1738 static int rk312x_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1739 unsigned long arg, int win_id)
1741 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1742 struct lcdc_device, driver);
1744 void __user *argp = (void __user *)arg;
1745 struct color_key_cfg clr_key_cfg;
1748 case RK_FBIOGET_PANEL_SIZE:
1749 panel_size[0] = lcdc_dev->screen->mode.xres;
1750 panel_size[1] = lcdc_dev->screen->mode.yres;
1751 if (copy_to_user(argp, panel_size, 8))
1754 case RK_FBIOPUT_COLOR_KEY_CFG:
1755 if (copy_from_user(&clr_key_cfg, argp,
1756 sizeof(struct color_key_cfg)))
1758 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
1759 clr_key_cfg.win0_color_key_cfg);
1760 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
1761 clr_key_cfg.win1_color_key_cfg);
1770 static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1775 mutex_lock(&dev_drv->fb_win_id_mutex);
1776 if (!strcmp(id, "fb0"))
1777 win_id = dev_drv->fb0_win_id;
1778 else if (!strcmp(id, "fb1"))
1779 win_id = dev_drv->fb1_win_id;
1780 else if (!strcmp(id, "fb2"))
1781 win_id = dev_drv->fb2_win_id;
1782 mutex_unlock(&dev_drv->fb_win_id_mutex);
1787 static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
1791 struct lcdc_device *lcdc_dev =
1792 container_of(dev_drv, struct lcdc_device, driver);
1796 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_WIN0_EN);
1797 else if (win_id == 1)
1798 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_WIN1_EN);
1799 else if (win_id == 2)
1800 win_status = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_HWC_EN);
1802 pr_err("!!!%s,win_id :%d,unsupport!!!\n",__func__,win_id);
1807 static int rk312x_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1810 struct lcdc_device *lcdc_dev =
1811 container_of(dev_drv, struct lcdc_device, driver);
1814 spin_lock(&lcdc_dev->reg_lock);
1815 if (lcdc_dev->clk_on) {
1817 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1821 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1826 spin_unlock(&lcdc_dev->reg_lock);
1831 static int rk312x_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1833 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1834 struct lcdc_device, driver);
1835 struct device_node *backlight;
1837 if (lcdc_dev->backlight)
1840 backlight = of_parse_phandle(lcdc_dev->dev->of_node,
1843 lcdc_dev->backlight = of_find_backlight_by_node(backlight);
1844 if (!lcdc_dev->backlight)
1845 dev_info(lcdc_dev->dev, "No find backlight device\n");
1847 dev_info(lcdc_dev->dev, "No find backlight device node\n");
1853 static int rk312x_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
1855 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1856 struct lcdc_device, driver);
1857 if (dev_drv->suspend_flag)
1860 /* close the backlight */
1861 rk312x_lcdc_get_backlight_device(dev_drv);
1862 if (lcdc_dev->backlight) {
1863 lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
1864 backlight_update_status(lcdc_dev->backlight);
1867 dev_drv->suspend_flag = 1;
1868 flush_kthread_worker(&dev_drv->update_regs_worker);
1870 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1871 dev_drv->trsm_ops->disable();
1872 spin_lock(&lcdc_dev->reg_lock);
1873 if (likely(lcdc_dev->clk_on)) {
1874 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(1));
1875 lcdc_msk_reg(lcdc_dev, INT_STATUS,
1876 m_FS_INT_CLEAR | m_LF_INT_CLEAR,
1877 v_FS_INT_CLEAR(1) | v_LF_INT_CLEAR(1));
1878 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1880 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1882 lcdc_cfg_done(lcdc_dev);
1884 if (dev_drv->iommu_enabled) {
1885 if (dev_drv->mmu_dev)
1886 rockchip_iovmm_deactivate(dev_drv->dev);
1889 spin_unlock(&lcdc_dev->reg_lock);
1891 spin_unlock(&lcdc_dev->reg_lock);
1894 rk312x_lcdc_clk_disable(lcdc_dev);
1895 rk_disp_pwr_disable(dev_drv);
1899 static int rk312x_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1901 struct lcdc_device *lcdc_dev =
1902 container_of(dev_drv, struct lcdc_device, driver);
1904 if (!dev_drv->suspend_flag)
1906 rk_disp_pwr_enable(dev_drv);
1908 rk312x_lcdc_clk_enable(lcdc_dev);
1909 rk312x_lcdc_reg_restore(lcdc_dev);
1911 /* config for the FRC mode of dither down */
1912 if (dev_drv->cur_screen &&
1913 dev_drv->cur_screen->face != OUT_P888) {
1914 lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
1915 lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
1916 lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0x55aaaa55);
1917 lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x55aaaa55);
1918 lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
1919 lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
1922 /* set screen lut */
1923 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1924 rk312x_lcdc_set_lut(dev_drv,
1925 dev_drv->cur_screen->dsp_lut);
1927 rk312x_lcdc_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1929 spin_lock(&lcdc_dev->reg_lock);
1931 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1933 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1935 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN, v_BLANK_EN(0));
1936 lcdc_cfg_done(lcdc_dev);
1938 if (dev_drv->iommu_enabled) {
1939 if (dev_drv->mmu_dev) {
1941 * At here, maybe win is enabled and buffer address
1942 * is not a vaild iommu mapped addr, incase crash,
1943 * delay 30ms to ensure H/W switch done.
1946 rockchip_iovmm_activate(dev_drv->dev);
1950 spin_unlock(&lcdc_dev->reg_lock);
1951 dev_drv->suspend_flag = 0;
1953 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1954 dev_drv->trsm_ops->enable();
1960 static int rk312x_lcdc_blank(struct rk_lcdc_driver *dev_drv,
1961 int win_id, int blank_mode)
1963 switch (blank_mode) {
1964 case FB_BLANK_UNBLANK:
1965 rk312x_lcdc_early_resume(dev_drv);
1967 case FB_BLANK_NORMAL:
1968 rk312x_lcdc_early_suspend(dev_drv);
1971 rk312x_lcdc_early_suspend(dev_drv);
1975 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1980 static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
1982 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1983 struct lcdc_device, driver);
1985 struct rk_lcdc_win *win = NULL;
1987 spin_lock(&lcdc_dev->reg_lock);
1988 if (lcdc_dev->clk_on) {
1989 for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
1990 win = dev_drv->win[i];
1991 if ((win->state == 0) && (win->last_state == 1))
1992 lcdc_layer_update_regs(lcdc_dev, win);
1993 win->last_state = win->state;
1995 lcdc_cfg_done(lcdc_dev);
1997 spin_unlock(&lcdc_dev->reg_lock);
2003 sin_hue = sin(a)*256 +0x100;
2004 cos_hue = cos(a)*256;
2006 sin_hue = sin(a)*256;
2007 cos_hue = cos(a)*256;
2009 static int rk312x_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
2012 struct lcdc_device *lcdc_dev =
2013 container_of(dev_drv, struct lcdc_device, driver);
2016 spin_lock(&lcdc_dev->reg_lock);
2017 if (lcdc_dev->clk_on) {
2018 val = lcdc_readl(lcdc_dev, BCSH_H);
2021 val &= m_BCSH_SIN_HUE;
2024 val &= m_BCSH_COS_HUE;
2031 spin_unlock(&lcdc_dev->reg_lock);
2036 static int rk312x_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, int sin_hue,
2039 struct lcdc_device *lcdc_dev =
2040 container_of(dev_drv, struct lcdc_device, driver);
2043 spin_lock(&lcdc_dev->reg_lock);
2044 if (lcdc_dev->clk_on) {
2045 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
2046 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
2047 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
2048 lcdc_cfg_done(lcdc_dev);
2050 spin_unlock(&lcdc_dev->reg_lock);
2055 static int rk312x_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2056 bcsh_bcs_mode mode, int value)
2058 struct lcdc_device *lcdc_dev =
2059 container_of(dev_drv, struct lcdc_device, driver);
2062 spin_lock(&lcdc_dev->reg_lock);
2063 if (lcdc_dev->clk_on) {
2066 /* from 0 to 255,typical is 128 */
2069 else if (value >= 0x80)
2070 value = value - 0x80;
2071 mask = m_BCSH_BRIGHTNESS;
2072 val = v_BCSH_BRIGHTNESS(value);
2075 /* from 0 to 510,typical is 256 */
2076 mask = m_BCSH_CONTRAST;
2077 val = v_BCSH_CONTRAST(value);
2080 /* from 0 to 1015,typical is 256 */
2081 mask = m_BCSH_SAT_CON;
2082 val = v_BCSH_SAT_CON(value);
2087 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
2088 lcdc_cfg_done(lcdc_dev);
2090 spin_unlock(&lcdc_dev->reg_lock);
2094 static int rk312x_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2097 struct lcdc_device *lcdc_dev =
2098 container_of(dev_drv, struct lcdc_device, driver);
2101 spin_lock(&lcdc_dev->reg_lock);
2102 if (lcdc_dev->clk_on) {
2103 val = lcdc_readl(lcdc_dev, BCSH_BCS);
2106 val &= m_BCSH_BRIGHTNESS;
2113 val &= m_BCSH_CONTRAST;
2117 val &= m_BCSH_SAT_CON;
2124 spin_unlock(&lcdc_dev->reg_lock);
2128 static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2130 struct lcdc_device *lcdc_dev =
2131 container_of(dev_drv, struct lcdc_device, driver);
2133 if (dev_drv->bcsh_init_status && open) {
2134 dev_drv->bcsh_init_status = 0;
2137 spin_lock(&lcdc_dev->reg_lock);
2138 if (lcdc_dev->clk_on) {
2140 lcdc_msk_reg(lcdc_dev,
2141 BCSH_CTRL, m_BCSH_EN | m_BCSH_OUT_MODE,
2142 v_BCSH_EN(1) | v_BCSH_OUT_MODE(3));
2143 lcdc_writel(lcdc_dev, BCSH_BCS,
2144 v_BCSH_BRIGHTNESS(0x00) |
2145 v_BCSH_CONTRAST(0x80) |
2146 v_BCSH_SAT_CON(0x80));
2147 lcdc_writel(lcdc_dev, BCSH_H, v_BCSH_COS_HUE(0x80));
2148 dev_drv->bcsh.enable = 1;
2152 lcdc_msk_reg(lcdc_dev, BCSH_CTRL, mask, val);
2153 dev_drv->bcsh.enable = 0;
2155 rk312x_lcdc_select_bcsh(dev_drv, lcdc_dev);
2156 lcdc_cfg_done(lcdc_dev);
2159 spin_unlock(&lcdc_dev->reg_lock);
2163 static int rk312x_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2165 struct rk_lcdc_win_area area;
2166 int fb2_win_id, fb1_win_id, fb0_win_id;
2168 mutex_lock(&dev_drv->fb_win_id_mutex);
2169 if (order == FB_DEFAULT_ORDER)
2170 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
2172 fb2_win_id = order / 100;
2173 fb1_win_id = (order / 10) % 10;
2174 fb0_win_id = order % 10;
2176 if (fb0_win_id != dev_drv->fb0_win_id) {
2177 area = dev_drv->win[(int)dev_drv->fb0_win_id]->area[0];
2178 dev_drv->win[(int)dev_drv->fb0_win_id]->area[0] =
2179 dev_drv->win[fb0_win_id]->area[0];
2180 dev_drv->win[fb0_win_id]->area[0] = area;
2181 dev_drv->fb0_win_id = fb0_win_id;
2183 dev_drv->fb1_win_id = fb1_win_id;
2184 dev_drv->fb2_win_id = fb2_win_id;
2186 mutex_unlock(&dev_drv->fb_win_id_mutex);
2191 static int rk312x_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2194 struct lcdc_device *lcdc_dev =
2195 container_of(dev_drv, struct lcdc_device, driver);
2196 struct rk_screen *screen = dev_drv->cur_screen;
2201 u32 x_total, y_total;
2204 ft = div_u64(1000000000000llu, fps);
2206 screen->mode.upper_margin + screen->mode.lower_margin +
2207 screen->mode.yres + screen->mode.vsync_len;
2209 screen->mode.left_margin + screen->mode.right_margin +
2210 screen->mode.xres + screen->mode.hsync_len;
2211 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2212 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2213 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2216 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2217 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2218 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2219 screen->ft = 1000 / fps; /*one frame time in ms */
2222 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2223 clk_get_rate(lcdc_dev->dclk), fps);
2228 static int rk312x_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
2231 struct lcdc_device *lcdc_dev =
2232 container_of(dev_drv,
2233 struct lcdc_device, driver);
2235 enable_irq(lcdc_dev->irq);
2237 disable_irq(lcdc_dev->irq);
2241 static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
2243 struct lcdc_device *lcdc_dev =
2244 container_of(dev_drv, struct lcdc_device, driver);
2248 if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
2249 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
2250 if (int_reg & m_LF_INT_STA) {
2251 dev_drv->frame_time.last_framedone_t =
2252 dev_drv->frame_time.framedone_t;
2253 dev_drv->frame_time.framedone_t = cpu_clock(0);
2254 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
2256 ret = RK_LF_STATUS_FC;
2258 ret = RK_LF_STATUS_FR;
2261 ret = RK_LF_STATUS_NC;
2267 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2268 unsigned int dsp_addr[][4])
2270 struct lcdc_device *lcdc_dev =
2271 container_of(dev_drv, struct lcdc_device, driver);
2273 if (lcdc_dev->clk_on) {
2274 dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
2275 if (lcdc_dev->soc_type == VOP_RK3036)
2276 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
2277 else if (lcdc_dev->soc_type == VOP_RK312X)
2278 dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2283 static ssize_t rk312x_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2284 char *buf, int win_id)
2286 struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device,
2288 char format_w0[9] = "NULL";
2289 char format_w1[9] = "NULL";
2290 char status_w0[9] = "NULL";
2291 char status_w1[9] = "NULL";
2292 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
2293 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0, x_st_w0, y_st_w0;
2294 u16 xvir_w1, x_act_w1, y_act_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
2295 u16 x_factor, y_factor, x_scale, y_scale;
2297 u32 win1_dsp_yaddr = 0;
2299 spin_lock(&lcdc_dev->reg_lock);
2300 if (lcdc_dev->clk_on) {
2302 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
2303 get_format_string((fmt_id & m_WIN0_FORMAT) >> 3, format_w0);
2304 get_format_string((fmt_id & m_WIN1_FORMAT) >> 6, format_w1);
2307 if (fmt_id & m_WIN0_EN)
2308 strcpy(status_w0, "enabled");
2310 strcpy(status_w0, "disabled");
2312 if ((fmt_id & m_WIN1_EN) >> 1)
2313 strcpy(status_w1, "enabled");
2315 strcpy(status_w1, "disabled");
2318 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
2321 xvir_w0 = lcdc_readl(lcdc_dev, WIN0_VIR) & m_YRGB_VIR;
2322 xvir_w1 = lcdc_readl(lcdc_dev, WIN1_VIR) & m_YRGB_VIR;
2325 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
2326 x_act_w0 = (act_info & m_ACT_WIDTH) + 1;
2327 y_act_w0 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2329 if (lcdc_dev->soc_type == VOP_RK3036) {
2330 act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
2331 x_act_w1 = (act_info & m_ACT_WIDTH) + 1;
2332 y_act_w1 = ((act_info & m_ACT_HEIGHT) >> 16) + 1;
2333 } else if (lcdc_dev->soc_type == VOP_RK312X) {
2334 /* rk312x unsupport win1 scaler,so have no act info */
2340 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
2341 x_dsp_w0 = (dsp_info & m_DSP_WIDTH) + 1;
2342 y_dsp_w0 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2344 if (lcdc_dev->soc_type == VOP_RK3036)
2345 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
2346 else if (lcdc_dev->soc_type == VOP_RK312X)
2347 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO_RK312X);
2348 x_dsp_w1 = (dsp_info & m_DSP_WIDTH) + 1;
2349 y_dsp_w1 = ((dsp_info & m_DSP_HEIGHT) >> 16) + 1;
2352 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
2353 x_st_w0 = dsp_st & m_DSP_STX;
2354 y_st_w0 = (dsp_st & m_DSP_STY) >> 16;
2356 if (lcdc_dev->soc_type == VOP_RK3036)
2357 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
2358 else if (lcdc_dev->soc_type == VOP_RK312X)
2359 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST_RK312X);
2361 x_st_w1 = dsp_st & m_DSP_STX;
2362 y_st_w1 = (dsp_st & m_DSP_STY) >> 16;
2365 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
2366 x_factor = factor & m_X_SCL_FACTOR;
2367 y_factor = (factor & m_Y_SCL_FACTOR) >> 16;
2368 x_scale = 4096 * 100 / x_factor;
2369 y_scale = 4096 * 100 / y_factor;
2372 if (lcdc_dev->soc_type == VOP_RK3036)
2373 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST);
2374 else if (lcdc_dev->soc_type == VOP_RK312X)
2375 win1_dsp_yaddr = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
2377 spin_unlock(&lcdc_dev->reg_lock);
2380 spin_unlock(&lcdc_dev->reg_lock);
2381 return snprintf(buf, PAGE_SIZE,
2393 "YRGB buffer addr:0x%08x\n"
2394 "CBR buffer addr:0x%08x\n\n"
2404 "YRGB buffer addr:0x%08x\n"
2419 lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2420 lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2431 ovl ? "win0 on the top of win1\n" :
2432 "win1 on the top of win0\n");
2435 static int rk312x_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
2437 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2440 int *cbase = (int *)lcdc_dev->regs;
2441 int *regsbak = (int *)lcdc_dev->regsbak;
2444 pr_info("back up reg:\n");
2445 for (i = 0; i <= (0xDC >> 4); i++) {
2446 for (j = 0; j < 4; j++)
2447 pr_info("%08x ", *(regsbak + i * 4 + j));
2451 pr_info("lcdc reg:\n");
2452 for (i = 0; i <= (0xDC >> 4); i++) {
2453 for (j = 0; j < 4; j++)
2454 pr_info("%08x ", readl_relaxed(cbase + i * 4 + j));
2460 static int rk312x_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
2462 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2463 struct lcdc_device, driver);
2464 if (lcdc_dev->soc_type == VOP_RK312X) {
2465 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
2466 v_DIRECT_PATH_EN(open));
2467 lcdc_cfg_done(lcdc_dev);
2472 static int rk312x_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
2474 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2475 struct lcdc_device, driver);
2477 if (lcdc_dev->soc_type == VOP_RK312X) {
2478 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAYER,
2479 v_DIRECT_PATH_LAYER(win_id));
2480 lcdc_cfg_done(lcdc_dev);
2485 static int rk312x_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
2487 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2488 struct lcdc_device, driver);
2491 if (lcdc_dev->soc_type == VOP_RK312X)
2492 ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
2497 static int rk312x_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2499 struct lcdc_device *lcdc_dev = container_of(dev_drv,
2500 struct lcdc_device, driver);
2502 rk312x_lcdc_get_backlight_device(dev_drv);
2505 /* close the backlight */
2506 if (lcdc_dev->backlight) {
2507 lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
2508 backlight_update_status(lcdc_dev->backlight);
2511 spin_lock(&lcdc_dev->reg_lock);
2512 if (likely(lcdc_dev->clk_on)) {
2513 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2515 lcdc_cfg_done(lcdc_dev);
2517 spin_unlock(&lcdc_dev->reg_lock);
2519 rk312x_lcdc_standby(dev_drv, true);
2521 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2522 dev_drv->trsm_ops->disable();
2524 spin_lock(&lcdc_dev->reg_lock);
2525 if (likely(lcdc_dev->clk_on)) {
2526 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLACK_EN,
2528 lcdc_cfg_done(lcdc_dev);
2530 spin_unlock(&lcdc_dev->reg_lock);
2532 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2533 dev_drv->trsm_ops->enable();
2535 rk312x_lcdc_standby(dev_drv, false);
2538 /* open the backlight */
2539 if (lcdc_dev->backlight) {
2540 lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
2541 backlight_update_status(lcdc_dev->backlight);
2549 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2550 .open = rk312x_lcdc_open,
2551 .load_screen = rk312x_load_screen,
2552 .get_dspbuf_info = rk312x_get_dspbuf_info,
2553 .post_dspbuf = rk312x_post_dspbuf,
2554 .set_par = rk312x_lcdc_set_par,
2555 .pan_display = rk312x_lcdc_pan_display,
2556 .direct_set_addr = rk312x_lcdc_direct_set_win_addr,
2557 .blank = rk312x_lcdc_blank,
2558 .ioctl = rk312x_lcdc_ioctl,
2559 .get_win_state = rk312x_lcdc_get_win_state,
2560 .ovl_mgr = rk312x_lcdc_ovl_mgr,
2561 .get_disp_info = rk312x_lcdc_get_disp_info,
2562 .fps_mgr = rk312x_lcdc_fps_mgr,
2563 .fb_get_win_id = rk312x_lcdc_get_win_id,
2564 .fb_win_remap = rk312x_fb_win_remap,
2565 .poll_vblank = rk312x_lcdc_poll_vblank,
2566 .get_dsp_addr = rk312x_lcdc_get_dsp_addr,
2567 .cfg_done = rk312x_lcdc_cfg_done,
2568 .dump_reg = rk312x_lcdc_reg_dump,
2569 .dpi_open = rk312x_lcdc_dpi_open,
2570 .dpi_win_sel = rk312x_lcdc_dpi_win_sel,
2571 .dpi_status = rk312x_lcdc_dpi_status,
2572 .set_dsp_bcsh_hue = rk312x_lcdc_set_bcsh_hue,
2573 .set_dsp_bcsh_bcs = rk312x_lcdc_set_bcsh_bcs,
2574 .get_dsp_bcsh_hue = rk312x_lcdc_get_bcsh_hue,
2575 .get_dsp_bcsh_bcs = rk312x_lcdc_get_bcsh_bcs,
2576 .open_bcsh = rk312x_lcdc_open_bcsh,
2577 .set_screen_scaler = rk312x_lcdc_set_scaler,
2578 .set_dsp_lut = rk312x_lcdc_set_lut,
2579 .set_hwc_lut = rk312x_lcdc_set_hwc_lut,
2580 .set_irq_to_cpu = rk312x_lcdc_set_irq_to_cpu,
2581 .dsp_black = rk312x_lcdc_dsp_black,
2582 .mmu_en = rk312x_lcdc_mmu_en,
2585 static const struct rk_lcdc_drvdata rk3036_lcdc_drvdata = {
2586 .soc_type = VOP_RK3036,
2589 static const struct rk_lcdc_drvdata rk312x_lcdc_drvdata = {
2590 .soc_type = VOP_RK312X,
2593 #if defined(CONFIG_OF)
2594 static const struct of_device_id rk312x_lcdc_dt_ids[] = {
2597 .compatible = "rockchip,rk3036-lcdc",
2598 .data = (void *)&rk3036_lcdc_drvdata,
2602 .compatible = "rockchip,rk312x-lcdc",
2603 .data = (void *)&rk312x_lcdc_drvdata,
2608 static int rk312x_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
2610 struct device_node *np = lcdc_dev->dev->of_node;
2611 const struct of_device_id *match;
2612 const struct rk_lcdc_drvdata *lcdc_drvdata;
2615 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2616 lcdc_dev->driver.iommu_enabled = 0;
2618 lcdc_dev->driver.iommu_enabled = val;
2620 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2621 lcdc_dev->driver.fb_win_map = FB_DEFAULT_ORDER;
2623 lcdc_dev->driver.fb_win_map = val;
2625 match = of_match_node(rk312x_lcdc_dt_ids, np);
2627 lcdc_drvdata = (const struct rk_lcdc_drvdata *)match->data;
2628 lcdc_dev->soc_type = lcdc_drvdata->soc_type;
2630 return PTR_ERR(match);
2636 static int rk312x_lcdc_probe(struct platform_device *pdev)
2638 struct lcdc_device *lcdc_dev = NULL;
2639 struct rk_lcdc_driver *dev_drv;
2640 struct device *dev = &pdev->dev;
2641 struct resource *res;
2644 lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
2646 dev_err(&pdev->dev, "rk312x lcdc device kzalloc fail!\n");
2649 platform_set_drvdata(pdev, lcdc_dev);
2650 lcdc_dev->dev = dev;
2651 if (rk312x_lcdc_parse_dt(lcdc_dev)) {
2652 dev_err(lcdc_dev->dev, "rk312x lcdc parse dt failed!\n");
2656 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2657 lcdc_dev->reg_phy_base = res->start;
2658 lcdc_dev->len = resource_size(res);
2659 lcdc_dev->regs = devm_ioremap_resource(dev, res);
2660 if (IS_ERR(lcdc_dev->regs)) {
2661 ret = PTR_ERR(lcdc_dev->regs);
2665 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
2666 if (IS_ERR(lcdc_dev->regsbak)) {
2667 dev_err(&pdev->dev, "rk312x lcdc device kmalloc fail!\n");
2668 ret = PTR_ERR(lcdc_dev->regsbak);
2671 lcdc_dev->hwc_lut_addr_base = (lcdc_dev->regs + HWC_LUT_ADDR);
2672 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
2673 lcdc_dev->prop = PRMRY;
2674 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
2675 dev_drv = &lcdc_dev->driver;
2677 dev_drv->prop = lcdc_dev->prop;
2678 dev_drv->id = lcdc_dev->id;
2679 dev_drv->ops = &lcdc_drv_ops;
2680 dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
2681 spin_lock_init(&lcdc_dev->reg_lock);
2683 lcdc_dev->irq = platform_get_irq(pdev, 0);
2684 if (lcdc_dev->irq < 0) {
2685 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
2688 goto err_request_irq;
2691 ret = devm_request_irq(dev, lcdc_dev->irq, rk312x_lcdc_isr,
2692 IRQF_DISABLED | IRQF_SHARED,
2693 dev_name(dev), lcdc_dev);
2695 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
2696 lcdc_dev->irq, ret);
2697 goto err_request_irq;
2700 if (dev_drv->iommu_enabled)
2701 strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME);
2703 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
2705 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
2706 goto err_register_fb;
2708 lcdc_dev->screen = dev_drv->screen0;
2710 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2711 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2716 devm_kfree(lcdc_dev->dev, lcdc_dev->regsbak);
2719 devm_kfree(&pdev->dev, lcdc_dev);
2723 #if defined(CONFIG_PM)
2724 static int rk312x_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
2729 static int rk312x_lcdc_resume(struct platform_device *pdev)
2734 #define rk312x_lcdc_suspend NULL
2735 #define rk312x_lcdc_resume NULL
2738 static int rk312x_lcdc_remove(struct platform_device *pdev)
2743 static void rk312x_lcdc_shutdown(struct platform_device *pdev)
2745 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
2746 struct rk_lcdc_driver *dev_drv=&lcdc_dev->driver;
2748 flush_kthread_worker(&dev_drv->update_regs_worker);
2749 kthread_stop(dev_drv->update_regs_thread);
2751 rk312x_lcdc_standby(dev_drv, true);
2752 rk312x_lcdc_deinit(lcdc_dev);
2753 rk312x_lcdc_clk_disable(lcdc_dev);
2754 rk_disp_pwr_disable(&lcdc_dev->driver);
2757 static struct platform_driver rk312x_lcdc_driver = {
2758 .probe = rk312x_lcdc_probe,
2759 .remove = rk312x_lcdc_remove,
2761 .name = "rk312x-lcdc",
2762 .owner = THIS_MODULE,
2763 .of_match_table = of_match_ptr(rk312x_lcdc_dt_ids),
2765 .suspend = rk312x_lcdc_suspend,
2766 .resume = rk312x_lcdc_resume,
2767 .shutdown = rk312x_lcdc_shutdown,
2770 static int __init rk312x_lcdc_module_init(void)
2772 return platform_driver_register(&rk312x_lcdc_driver);
2775 static void __exit rk312x_lcdc_module_exit(void)
2777 platform_driver_unregister(&rk312x_lcdc_driver);
2780 fs_initcall(rk312x_lcdc_module_init);
2781 module_exit(rk312x_lcdc_module_exit);