2 * rockchip VOP(Video Output Processer) hardware driver.
4 * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
5 * Author: WenLong Zhuang <daisen.zhuang@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 <linux/pm_runtime.h>
31 #include <linux/rockchip-iovmm.h>
32 #include <asm/div64.h>
33 #include <linux/uaccess.h>
34 #include <linux/rockchip/cpu.h>
35 #include <linux/rockchip/iomap.h>
36 #include <linux/rockchip/grf.h>
37 #include <linux/rockchip/common.h>
38 #include <dt-bindings/clock/rk_system_status.h>
40 #include "rk_vop_lite.h"
42 static int dbg_thresd;
43 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
45 #define DBG(level, x...) do { \
46 if (unlikely(dbg_thresd >= level)) \
50 #define to_vop_dev(drv) container_of(drv, struct vop_device, driver)
52 static struct rk_lcdc_win vop_win[] = {
53 { .name = "win0", .id = 0},
54 { .name = "win1", .id = 1},
55 { .name = "hwc", .id = 2}
58 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
60 static int vop_clk_enable(struct vop_device *vop_dev)
62 if (!vop_dev->clk_on) {
63 pm_runtime_get_sync(vop_dev->dev);
65 clk_enable(vop_dev->hclk);
66 clk_enable(vop_dev->aclk);
67 clk_enable(vop_dev->dclk);
68 spin_lock(&vop_dev->reg_lock);
70 spin_unlock(&vop_dev->reg_lock);
76 static int vop_clk_disable(struct vop_device *vop_dev)
78 if (vop_dev->clk_on) {
79 spin_lock(&vop_dev->reg_lock);
81 spin_unlock(&vop_dev->reg_lock);
82 clk_disable(vop_dev->dclk);
83 clk_disable(vop_dev->aclk);
84 clk_disable(vop_dev->hclk);
86 pm_runtime_put(vop_dev->dev);
92 static int vop_irq_enable(struct vop_device *vop_dev)
96 spin_lock(&vop_dev->reg_lock);
97 if (likely(vop_dev->clk_on)) {
98 vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, INTR_MASK);
100 val = INTR_FS0 | INTR_FS1 | INTR_LINE_FLAG0 | INTR_LINE_FLAG1 |
101 INTR_BUS_ERROR | INTR_WIN0_EMPTY | INTR_WIN1_EMPTY |
103 vop_mask_writel(vop_dev, INTR_EN, INTR_MASK, val);
105 spin_unlock(&vop_dev->reg_lock);
110 static int vop_irq_disable(struct vop_device *vop_dev)
112 spin_lock(&vop_dev->reg_lock);
113 if (likely(vop_dev->clk_on)) {
114 spin_lock(&vop_dev->reg_lock);
115 vop_writel(vop_dev, INTR_EN, 0xffff0000);
116 vop_writel(vop_dev, INTR_CLEAR, 0xffffffff);
117 vop_cfg_done(vop_dev);
119 spin_unlock(&vop_dev->reg_lock);
124 static int vop_standby_enable(struct vop_device *vop_dev)
129 spin_lock(&vop_dev->reg_lock);
130 if (likely(vop_dev->clk_on)) {
131 vop_dev->sync.stdbyfin.done = 0;
133 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(1));
134 /*vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK);*/
135 val = V_IMD_VOP_STANDBY_EN(1) | V_IMD_VOP_DMA_STOP(1) |
136 V_IMD_DSP_OUT_ZERO(1);
137 vop_msk_reg(vop_dev, SYS_CTRL2, val);
138 vop_cfg_done(vop_dev);
139 spin_unlock(&vop_dev->reg_lock);
141 /* wait for standby hold valid */
142 ret = vop_completion_timeout_ms(&vop_dev->sync.stdbyfin,
143 vop_dev->sync.stdbyfin_to);
145 dev_err(vop_dev->dev,
146 "wait standby hold valid timeout %dms\n",
147 vop_dev->sync.stdbyfin_to);
151 spin_unlock(&vop_dev->reg_lock);
157 static int vop_standby_disable(struct vop_device *vop_dev)
162 spin_lock(&vop_dev->reg_lock);
163 if (likely(vop_dev->clk_on)) {
164 vop_dev->sync.frmst.done = 0;
165 val = V_IMD_VOP_STANDBY_EN(0) | V_IMD_VOP_DMA_STOP(0) |
166 V_IMD_DSP_OUT_ZERO(0);
167 vop_msk_reg(vop_dev, SYS_CTRL2, val);
168 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_BLANK_EN(0));
169 vop_cfg_done(vop_dev);
170 spin_unlock(&vop_dev->reg_lock);
172 /* win address maybe effect after next frame start,
173 * but mmu maybe effect right now, so need wait frame start
175 ret = vop_completion_timeout_ms(&vop_dev->sync.frmst,
176 vop_dev->sync.frmst_to);
178 dev_err(vop_dev->dev, "wait frame start timeout %dms\n",
179 vop_dev->sync.frmst_to);
183 spin_unlock(&vop_dev->reg_lock);
189 static int vop_mmu_enable(struct rk_lcdc_driver *dev_drv)
191 struct vop_device *vop_dev = to_vop_dev(dev_drv);
193 if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
194 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
199 spin_lock(&vop_dev->reg_lock);
200 if (likely(vop_dev->clk_on)) {
201 if (!vop_dev->iommu_status) {
202 vop_dev->iommu_status = 1;
203 rockchip_iovmm_activate(dev_drv->dev);
206 spin_unlock(&vop_dev->reg_lock);
211 static int vop_mmu_disable(struct rk_lcdc_driver *dev_drv)
213 struct vop_device *vop_dev = to_vop_dev(dev_drv);
215 if (!dev_drv->iommu_enabled || !dev_drv->mmu_dev) {
216 pr_debug("%s: VOP iommu is disabled or not find mmu dev\n",
221 spin_lock(&vop_dev->reg_lock);
222 if (likely(vop_dev->clk_on)) {
223 if (vop_dev->iommu_status) {
224 vop_dev->iommu_status = 0;
225 rockchip_iovmm_deactivate(dev_drv->dev);
228 spin_unlock(&vop_dev->reg_lock);
233 static int vop_reg_dump(struct rk_lcdc_driver *dev_drv)
235 struct vop_device *vop_dev = to_vop_dev(dev_drv);
236 int *cbase = (int *)vop_dev->regs;
237 int *regsbak = (int *)vop_dev->regsbak;
239 char dbg_message[30];
242 spin_lock(&vop_dev->reg_lock);
243 if (likely(vop_dev->clk_on)) {
244 pr_info("vop back up reg:\n");
245 memset(dbg_message, 0, sizeof(dbg_message));
246 memset(buf, 0, sizeof(buf));
247 for (i = 0; i <= (0x200 >> 4); i++) {
248 val = sprintf(dbg_message, "0x%04x: ", i * 16);
249 for (j = 0; j < 4; j++) {
250 val = sprintf(buf, "%08x ",
251 *(regsbak + i * 4 + j));
252 strcat(dbg_message, buf);
254 pr_info("%s\n", dbg_message);
255 memset(dbg_message, 0, sizeof(dbg_message));
256 memset(buf, 0, sizeof(buf));
259 pr_info("vop reg:\n");
260 for (i = 0; i <= (0x200 >> 4); i++) {
261 val = sprintf(dbg_message, "0x%04x: ", i * 16);
262 for (j = 0; j < 4; j++) {
263 sprintf(buf, "%08x ",
264 readl_relaxed(cbase + i * 4 + j));
265 strcat(dbg_message, buf);
267 pr_info("%s\n", dbg_message);
268 memset(dbg_message, 0, sizeof(dbg_message));
269 memset(buf, 0, sizeof(buf));
272 spin_unlock(&vop_dev->reg_lock);
278 static int win##id##_enable(struct vop_device *vop_dev, int en) \
280 spin_lock(&vop_dev->reg_lock); \
281 vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \
282 vop_cfg_done(vop_dev); \
283 spin_unlock(&vop_dev->reg_lock); \
291 * enable/disable win directly
293 static int vop_win_direct_en(struct rk_lcdc_driver *drv,
296 struct vop_device *vop_dev = to_vop_dev(drv);
299 win0_enable(vop_dev, en);
300 else if (win_id == 1)
301 win1_enable(vop_dev, en);
303 dev_err(vop_dev->dev, "invalid win number:%d\n", win_id);
307 #define SET_WIN_ADDR(id) \
308 static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \
310 spin_lock(&vop_dev->reg_lock); \
311 vop_writel(vop_dev, WIN##id##_YRGB_MST, addr); \
312 vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1)); \
313 vop_cfg_done(vop_dev); \
314 spin_unlock(&vop_dev->reg_lock); \
321 static int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
322 int win_id, u32 addr)
324 struct vop_device *vop_dev = to_vop_dev(dev_drv);
327 set_win0_addr(vop_dev, addr);
329 set_win1_addr(vop_dev, addr);
334 static void vop_read_reg_default_cfg(struct vop_device *vop_dev)
338 struct rk_screen *screen = vop_dev->driver.cur_screen;
339 u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
340 u32 V_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
342 struct rk_lcdc_win *win0 = vop_dev->driver.win[0];
344 spin_lock(&vop_dev->reg_lock);
345 for (reg = 0; reg < vop_dev->len; reg += 4) {
346 val = vop_readl_backup(vop_dev, reg);
349 win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
351 ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
354 win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1;
355 win0->area[0].ysize =
356 ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
359 st_x = val & MASK(WIN0_DSP_XST);
360 st_y = (val & MASK(WIN0_DSP_YST)) >> 16;
361 win0->area[0].xpos = st_x - h_pw_bp;
362 win0->area[0].ypos = st_y - V_pw_bp;
365 win0->state = val & MASK(WIN0_EN);
366 win0->area[0].fmt_cfg =
367 (val & MASK(WIN0_DATA_FMT)) >> 1;
368 win0->area[0].format = win0->area[0].fmt_cfg;
371 win0->area[0].y_vir_stride =
372 val & MASK(WIN0_YRGB_VIR_STRIDE);
373 win0->area[0].uv_vir_stride =
374 (val & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
375 if (win0->area[0].format == ARGB888)
376 win0->area[0].xvir = win0->area[0].y_vir_stride;
377 else if (win0->area[0].format == RGB888)
379 win0->area[0].y_vir_stride * 4 / 3;
380 else if (win0->area[0].format == RGB565)
382 2 * win0->area[0].y_vir_stride;
385 4 * win0->area[0].y_vir_stride;
388 win0->area[0].smem_start = val;
391 win0->area[0].cbr_start = val;
397 spin_unlock(&vop_dev->reg_lock);
400 static int vop_pre_init(struct rk_lcdc_driver *dev_drv)
402 struct vop_device *vop_dev = to_vop_dev(dev_drv);
404 if (vop_dev->pre_init)
407 if (dev_drv->iommu_enabled) {
408 dev_drv->mmu_dev = rk_fb_get_sysmmu_device_by_compatible(
409 dev_drv->mmu_dts_name);
410 if (dev_drv->mmu_dev)
411 rk_fb_platform_set_sysmmu(
412 dev_drv->mmu_dev, dev_drv->dev);
414 dev_err(dev_drv->dev, "fail get rk iommu device\n");
417 if (!support_uboot_display())
418 rk_disp_pwr_enable(dev_drv);
420 vop_clk_enable(vop_dev);
422 /* backup reg config at uboot */
423 vop_read_reg_default_cfg(vop_dev);
425 /* vop io voltage select-->0: 3.3v; 1: 1.8v */
426 if (vop_dev->pwr18 == 1)
427 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
430 vop_grf_writel(vop_dev->grf_base, GRF_IO_VSEL,
433 vop_msk_reg(vop_dev, SYS_CTRL1, V_SW_AXI_MAX_OUTSTAND_EN(1) |
434 V_SW_AXI_MAX_OUTSTAND_NUM(31));
435 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_AUTO_GATING_EN(0));
436 vop_cfg_done(vop_dev);
437 vop_dev->pre_init = true;
442 static void vop_deinit(struct vop_device *vop_dev)
444 struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
446 vop_standby_enable(vop_dev);
447 vop_irq_disable(vop_dev);
448 vop_mmu_disable(dev_drv);
449 vop_clk_disable(vop_dev);
450 clk_unprepare(vop_dev->dclk);
451 clk_unprepare(vop_dev->aclk);
452 clk_unprepare(vop_dev->hclk);
453 pm_runtime_disable(vop_dev->dev);
456 static void __maybe_unused
457 vop_win_csc_mode(struct vop_device *vop_dev, struct rk_lcdc_win *win,
462 spin_lock(&vop_dev->reg_lock);
463 if (likely(vop_dev->clk_on)) {
465 val = V_WIN0_CSC_MODE(csc_mode);
466 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
467 } else if (win->id == 1) {
468 val = V_WIN1_CSC_MODE(csc_mode);
469 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
471 dev_err(vop_dev->dev, "%s win%d unsupport csc mode",
475 spin_unlock(&vop_dev->reg_lock);
478 static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
480 struct vop_device *vop_dev = to_vop_dev(dev_drv);
481 struct rk_lcdc_win *win;
484 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
485 win = dev_drv->win[i];
488 vop_writel(vop_dev, WIN0_COLOR_KEY, win->color_key_val);
491 vop_writel(vop_dev, WIN1_COLOR_KEY, win->color_key_val);
494 pr_info("%s:un support win num:%d\n",
502 static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id)
504 struct vop_device *vop_dev = to_vop_dev(dev_drv);
505 struct rk_lcdc_win *win = dev_drv->win[win_id];
507 int ppixel_alpha = 0;
508 int alpha_en = win->alpha_en;
513 val = V_WIN0_ALPHA_EN(0);
514 vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
516 val = V_WIN1_ALPHA_EN(0);
517 vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
522 ppixel_alpha = ((win->area[0].format == ARGB888) ||
523 (win->area[0].format == ABGR888)) ? 1 : 0;
525 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
526 if (!dev_drv->win[i]->state)
528 if (win->z_order > dev_drv->win[i]->z_order)
533 * The bottom layer not support ppixel_alpha mode.
535 if (i == dev_drv->lcdc_win_num) {
541 val = V_WIN0_ALPHA_EN(alpha_en) |
542 V_WIN0_ALPHA_MODE(ppixel_alpha) |
543 V_WIN0_ALPHA_PRE_MUL(ppixel_alpha) |
544 V_WIN0_ALPHA_SAT_MODE(0);
545 vop_msk_reg(vop_dev, WIN0_ALPHA_CTRL, val);
546 } else if (win_id == 1) {
547 val = V_WIN1_ALPHA_EN(alpha_en) |
548 V_WIN1_ALPHA_MODE(ppixel_alpha) |
549 V_WIN1_ALPHA_PRE_MUL(ppixel_alpha) |
550 V_WIN1_ALPHA_SAT_MODE(0);
551 vop_msk_reg(vop_dev, WIN1_ALPHA_CTRL, val);
553 dev_err(vop_dev->dev, "%s: invalid win id=%d or unsupport\n",
560 static int vop_axi_gather_cfg(struct vop_device *vop_dev,
561 struct rk_lcdc_win *win)
564 u16 yrgb_gather_num = 3;
565 u16 cbcr_gather_num = 1;
567 switch (win->area[0].format) {
588 dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n",
589 __func__, win->area[0].format);
594 val = V_WIN0_YRGB_AXI_GATHER_EN(1) |
595 V_WIN0_CBR_AXI_GATHER_EN(1) |
596 V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) |
597 V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num);
598 vop_msk_reg(vop_dev, WIN0_CTRL1, val);
599 } else if (win->id == 1) {
600 val = V_WIN1_AXI_GATHER_EN(1) |
601 V_WIN1_AXI_GATHER_NUM(yrgb_gather_num);
602 vop_msk_reg(vop_dev, WIN1_CTRL1, val);
607 static int vop_win0_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
609 struct vop_device *vop_dev = to_vop_dev(dev_drv);
610 struct rk_lcdc_win *win = dev_drv->win[win_id];
613 if (win->state == 1) {
614 vop_axi_gather_cfg(vop_dev, win);
615 val = V_WIN0_EN(win->state) |
616 V_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
617 V_WIN0_RB_SWAP(win->area[0].swap_rb) |
618 V_WIN0_UV_SWAP(win->area[0].swap_uv);
619 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
620 val |= V_WIN0_INTERLACE_READ(1);
621 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
623 val = V_WIN0_YRGB_VIR_STRIDE(win->area[0].y_vir_stride) |
624 V_WIN0_CBR_VIR_STRIDE(win->area[0].uv_vir_stride);
625 vop_writel(vop_dev, WIN0_VIR, val);
627 val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) |
628 V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1);
629 vop_writel(vop_dev, WIN0_DSP_INFO, val);
631 val = V_WIN0_DSP_XST(win->area[0].dsp_stx) |
632 V_WIN0_DSP_YST(win->area[0].dsp_sty);
633 vop_writel(vop_dev, WIN0_DSP_ST, val);
635 /* only win0 support scale and yuv */
636 val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) |
637 V_WIN0_ACT_HEIGHT(win->area[0].yact - 1);
638 vop_writel(vop_dev, WIN0_ACT_INFO, val);
640 val = V_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
641 V_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
642 vop_writel(vop_dev, WIN0_SCL_FACTOR_YRGB, val);
644 val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
645 V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
646 vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR, val);
648 if (win->area[0].y_addr > 0)
649 vop_writel(vop_dev, WIN0_YRGB_MST, win->area[0].y_addr);
650 if (win->area[0].uv_addr > 0)
651 vop_writel(vop_dev, WIN0_CBR_MST, win->area[0].uv_addr);
653 vop_alpha_cfg(dev_drv, win_id);
655 val = V_WIN0_EN(win->state);
656 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
662 static int vop_win1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
664 struct vop_device *vop_dev = to_vop_dev(dev_drv);
665 struct rk_lcdc_win *win = dev_drv->win[win_id];
668 if (win->state == 1) {
669 vop_axi_gather_cfg(vop_dev, win);
670 val = V_WIN1_EN(win->state) |
671 V_WIN1_DATA_FMT(win->area[0].fmt_cfg) |
672 V_WIN1_RB_SWAP(win->area[0].swap_rb);
673 if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED)
674 val |= V_WIN1_INTERLACE_READ(1);
675 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
677 val = V_WIN1_VIR_STRIDE(win->area[0].y_vir_stride);
678 vop_writel(vop_dev, WIN1_VIR, val);
680 val = V_WIN1_DSP_WIDTH(win->area[0].xsize - 1) |
681 V_WIN1_DSP_HEIGHT(win->area[0].ysize - 1);
682 vop_writel(vop_dev, WIN1_DSP_INFO, val);
684 val = V_WIN1_DSP_XST(win->area[0].dsp_stx) |
685 V_WIN1_DSP_YST(win->area[0].dsp_sty);
686 vop_writel(vop_dev, WIN1_DSP_ST, val);
688 if (win->area[0].y_addr > 0)
689 vop_writel(vop_dev, WIN1_YRGB_MST, win->area[0].y_addr);
691 vop_alpha_cfg(dev_drv, win_id);
693 val = V_WIN1_EN(win->state);
694 vop_msk_reg(vop_dev, WIN1_CTRL0, val);
700 static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
702 struct vop_device *vop_dev = to_vop_dev(dev_drv);
703 struct rk_lcdc_win *win = dev_drv->win[win_id];
704 unsigned int hwc_size = 0;
707 if (win->state == 1) {
708 vop_axi_gather_cfg(vop_dev, win);
710 if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
712 else if ((win->area[0].xsize == 64) &&
713 (win->area[0].ysize == 64))
716 dev_err(vop_dev->dev, "unsupported hwc size[%dx%d]!\n",
717 win->area[0].xsize, win->area[0].ysize);
719 val = V_HWC_EN(1) | V_HWC_SIZE(hwc_size);
720 vop_msk_reg(vop_dev, HWC_CTRL0, val);
722 val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
723 V_HWC_DSP_YST(win->area[0].dsp_sty);
724 vop_msk_reg(vop_dev, HWC_DSP_ST, val);
726 if (win->area[0].y_addr > 0)
727 vop_writel(vop_dev, HWC_MST, win->area[0].y_addr);
729 val = V_HWC_EN(win->state);
730 vop_msk_reg(vop_dev, HWC_CTRL0, val);
736 static int vop_layer_update_regs(struct vop_device *vop_dev,
737 struct rk_lcdc_win *win)
739 struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
741 vop_msk_reg(vop_dev, SYS_CTRL2,
742 V_IMD_VOP_STANDBY_EN(vop_dev->standby));
744 vop_win0_reg_update(dev_drv, win->id);
745 else if (win->id == 1)
746 vop_win1_reg_update(dev_drv, win->id);
747 else if (win->id == 2)
748 vop_hwc_reg_update(dev_drv, win->id);
749 vop_cfg_done(vop_dev);
751 DBG(2, "%s for vop%d\n", __func__, vop_dev->id);
755 static int vop_set_hwc_lut(struct rk_lcdc_driver *dev_drv,
756 int *hwc_lut, int mode)
761 int len = 256 * sizeof(u32);
762 struct vop_device *vop_dev = to_vop_dev(dev_drv);
764 if (!dev_drv->hwc_lut)
765 dev_drv->hwc_lut = devm_kzalloc(vop_dev->dev, len, GFP_KERNEL);
767 spin_lock(&vop_dev->reg_lock);
768 if (likely(vop_dev->clk_on)) {
769 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(0));
770 vop_cfg_done(vop_dev);
772 for (i = 0; i < 256; i++) {
774 dev_drv->hwc_lut[i] = hwc_lut[i];
776 v = dev_drv->hwc_lut[i];
777 c = vop_dev->hwc_lut_addr_base + i;
778 writel_relaxed(v, c);
780 vop_msk_reg(vop_dev, HWC_CTRL0, V_HWC_LUT_EN(1));
781 vop_cfg_done(vop_dev);
783 spin_unlock(&vop_dev->reg_lock);
788 static int vop_set_lut(struct rk_lcdc_driver *dev_drv, int *dsp_lut)
793 struct vop_device *vop_dev = to_vop_dev(dev_drv);
798 spin_lock(&vop_dev->reg_lock);
799 if (likely(vop_dev->clk_on)) {
800 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(0));
801 vop_cfg_done(vop_dev);
803 for (i = 0; i < 256; i++) {
805 c = vop_dev->dsp_lut_addr_base + i;
806 writel_relaxed(v, c);
808 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_LUT_EN(1));
809 vop_cfg_done(vop_dev);
811 spin_unlock(&vop_dev->reg_lock);
816 static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate)
818 int ret = 0, fps = 0;
819 struct vop_device *vop_dev = to_vop_dev(dev_drv);
820 struct rk_screen *screen = dev_drv->cur_screen;
823 ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock);
825 dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n",
826 vop_dev->id, screen->mode.pixclock);
828 div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
829 vop_dev->driver.pixclock = vop_dev->pixclock;
831 fps = rk_fb_calc_fps(screen, vop_dev->pixclock);
832 screen->ft = 1000 / fps;
833 dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ",
834 vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps);
838 static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
840 struct vop_device *vop_dev = to_vop_dev(dev_drv);
841 struct rk_screen *screen = dev_drv->cur_screen;
842 u16 hsync_len = screen->mode.hsync_len;
843 u16 left_margin = screen->mode.left_margin;
844 u16 right_margin = screen->mode.right_margin;
845 u16 vsync_len = screen->mode.vsync_len;
846 u16 upper_margin = screen->mode.upper_margin;
847 u16 lower_margin = screen->mode.lower_margin;
848 u16 x_res = screen->mode.xres;
849 u16 y_res = screen->mode.yres;
851 u16 h_total, v_total;
852 u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
854 /* config timing reg valid immediately or after frame start */
855 if (screen->mode.vmode & FB_VMODE_INTERLACED) /* after frame start */
856 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(1));
857 else /* timing reg valid immediately */
858 vop_msk_reg(vop_dev, SYS_CTRL2, V_IMD_DSP_TIMING_IMD(0));
860 h_total = hsync_len + left_margin + x_res + right_margin;
861 v_total = vsync_len + upper_margin + y_res + lower_margin;
863 val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total);
864 vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val);
866 val = V_DSP_HACT_END(hsync_len + left_margin + x_res) |
867 V_DSP_HACT_ST(hsync_len + left_margin);
868 vop_msk_reg(vop_dev, DSP_HACT_ST_END, val);
870 if (screen->mode.vmode & FB_VMODE_INTERLACED) {
871 /* First Field Timing */
872 val = V_DSP_VS_END(vsync_len) |
873 V_DSP_VTOTAL(2 * (vsync_len + upper_margin +
874 lower_margin) + y_res + 1);
875 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
877 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
878 V_DSP_VACT_ST(vsync_len + upper_margin);
879 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
881 /* Second Field Timing */
882 vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
883 vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
885 val = V_DSP_VS_ST_F1(vs_st_f1) | V_DSP_VS_END_F1(vs_end_f1);
886 vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val);
888 vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
890 vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
892 val = V_DSP_VACT_END_F1(vact_end_f1) |
893 V_DSP_VACT_ST_F1(vact_st_f1);
894 vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val);
896 val = V_DSP_LINE_FLAG0_NUM(lower_margin ?
897 vact_end_f1 : vact_end_f1 - 1);
899 val |= V_DSP_LINE_FLAG1_NUM(lower_margin ?
900 vact_end_f1 : vact_end_f1 - 1);
901 vop_msk_reg(vop_dev, LINE_FLAG, val);
903 val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total);
904 vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val);
906 val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) |
907 V_DSP_VACT_ST(vsync_len + upper_margin);
908 vop_msk_reg(vop_dev, DSP_VACT_ST_END, val);
910 val = V_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) |
911 V_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res);
912 vop_msk_reg(vop_dev, LINE_FLAG, val);
918 static int vop_config_source(struct rk_lcdc_driver *dev_drv)
920 struct vop_device *vop_dev = to_vop_dev(dev_drv);
921 struct rk_screen *screen = dev_drv->cur_screen;
924 switch (screen->type) {
926 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON5,
927 V_RGB_VOP_SEL(dev_drv->id));
928 val = V_RGB_DCLK_EN(1) | V_RGB_DCLK_POL(screen->pin_dclk) |
929 V_RGB_HSYNC_POL(screen->pin_hsync) |
930 V_RGB_VSYNC_POL(screen->pin_vsync) |
931 V_RGB_DEN_POL(screen->pin_den);
934 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
935 V_HDMI_VOP_SEL(dev_drv->id));
936 val = V_HDMI_DCLK_EN(1) | V_HDMI_DCLK_POL(screen->pin_dclk) |
937 V_HDMI_HSYNC_POL(screen->pin_hsync) |
938 V_HDMI_VSYNC_POL(screen->pin_vsync) |
939 V_HDMI_DEN_POL(screen->pin_den);
942 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
943 V_LVDS_VOP_SEL(dev_drv->id));
944 val = V_LVDS_DCLK_EN(1) | V_LVDS_DCLK_POL(screen->pin_dclk) |
945 V_LVDS_HSYNC_POL(screen->pin_hsync) |
946 V_LVDS_VSYNC_POL(screen->pin_vsync) |
947 V_LVDS_DEN_POL(screen->pin_den);
950 vop_grf_writel(vop_dev->grf_base, GRF_SOC_CON0,
951 V_DSI0_VOP_SEL(dev_drv->id));
952 val = V_MIPI_DCLK_EN(1) | V_MIPI_DCLK_POL(screen->pin_dclk) |
953 V_MIPI_HSYNC_POL(screen->pin_hsync) |
954 V_MIPI_VSYNC_POL(screen->pin_vsync) |
955 V_MIPI_DEN_POL(screen->pin_den);
958 dev_err(vop_dev->dev, "un supported interface[%d]!\n",
963 val |= V_SW_CORE_CLK_SEL(!!screen->pixelrepeat);
964 if (screen->mode.vmode & FB_VMODE_INTERLACED)
965 val |= V_SW_HDMI_CLK_I_SEL(1);
967 val |= V_SW_HDMI_CLK_I_SEL(0);
968 vop_msk_reg(vop_dev, DSP_CTRL0, val);
973 static int vop_config_interface(struct rk_lcdc_driver *dev_drv)
975 struct vop_device *vop_dev = to_vop_dev(dev_drv);
976 struct rk_screen *screen = dev_drv->cur_screen;
979 /* FRC dither down init */
980 if (screen->face != OUT_P888) {
981 vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821);
982 vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412);
983 vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696);
984 vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969);
985 vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
986 vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
989 switch (screen->face) {
991 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(0);
994 val = V_DSP_OUT_MODE(OUT_P565) | V_DITHER_DOWN(1) |
995 V_DITHER_DOWN_MODE(DITHER_888_565) |
996 V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
999 val = V_DSP_OUT_MODE(OUT_P666) | V_DITHER_DOWN(1) |
1000 V_DITHER_DOWN_MODE(DITHER_888_666) |
1001 V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1004 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1005 V_DITHER_DOWN_MODE(DITHER_888_565) |
1006 V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1009 val = V_DSP_OUT_MODE(OUT_P888) | V_DITHER_DOWN(1) |
1010 V_DITHER_DOWN_MODE(DITHER_888_666) |
1011 V_DITHER_DOWN_SEL(DITHER_SEL_FRC);
1014 dev_err(vop_dev->dev, "un supported screen face[%d]!\n",
1019 if (screen->mode.vmode & FB_VMODE_INTERLACED)
1020 val |= V_DSP_INTERLACE(1) | V_INTERLACE_FIELD_POL(0);
1022 dev_drv->output_color = screen->color_mode;
1023 if (screen->color_mode == COLOR_RGB)
1024 dev_drv->overlay_mode = VOP_RGB_DOMAIN;
1026 dev_drv->overlay_mode = VOP_YUV_DOMAIN;
1028 val |= V_SW_OVERLAY_MODE(dev_drv->overlay_mode) |
1029 V_DSP_BG_SWAP(screen->swap_gb) |
1030 V_DSP_RB_SWAP(screen->swap_rb) |
1031 V_DSP_RG_SWAP(screen->swap_rg) |
1032 V_DSP_DELTA_SWAP(screen->swap_delta) |
1033 V_DSP_DUMMY_SWAP(screen->swap_dumy) |
1034 V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0);
1035 vop_msk_reg(vop_dev, DSP_CTRL2, val);
1040 static void vop_config_background(struct rk_lcdc_driver *dev_drv, int rgb)
1042 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1045 int g = (rgb >> 8) & 0xff;
1046 int r = (rgb >> 16) & 0xff;
1048 val = V_DSP_BG_BLUE(b) | V_DSP_BG_GREEN(g) | V_DSP_BG_RED(r);
1049 vop_msk_reg(vop_dev, DSP_BG, val);
1052 static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
1054 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1056 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
1057 if (dev_drv->output_color == COLOR_YCBCR) /* bypass */
1058 vop_msk_reg(vop_dev, BCSH_CTRL,
1059 V_SW_BCSH_Y2R_EN(0) | V_SW_BCSH_R2Y_EN(0));
1061 vop_msk_reg(vop_dev, BCSH_CTRL, V_SW_BCSH_Y2R_EN(1) |
1062 V_SW_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1063 V_SW_BCSH_R2Y_EN(0));
1065 /* overlay_mode=VOP_RGB_DOMAIN */
1066 /* bypass --need check,if bcsh close? */
1067 if (dev_drv->output_color == COLOR_RGB) {
1068 if (dev_drv->bcsh.enable == 1)
1069 vop_msk_reg(vop_dev, BCSH_CTRL,
1070 V_SW_BCSH_R2Y_EN(1) |
1071 V_SW_BCSH_Y2R_EN(1));
1073 vop_msk_reg(vop_dev, BCSH_CTRL,
1074 V_SW_BCSH_R2Y_EN(0) |
1075 V_SW_BCSH_Y2R_EN(0));
1078 vop_msk_reg(vop_dev, BCSH_CTRL,
1079 V_SW_BCSH_R2Y_EN(1) |
1080 V_SW_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
1081 V_SW_BCSH_Y2R_EN(0));
1086 static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
1087 u16 *yact, int *format, u32 *dsp_addr,
1090 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1093 spin_lock(&vop_dev->reg_lock);
1094 if (likely(vop_dev->clk_on)) {
1095 val = vop_readl(vop_dev, WIN0_ACT_INFO);
1096 *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1;
1097 *yact = ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1099 val = vop_readl(vop_dev, WIN0_CTRL0);
1100 *format = (val & MASK(WIN0_DATA_FMT)) >> 1;
1101 *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST);
1103 spin_unlock(&vop_dev->reg_lock);
1108 static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
1109 int format, u16 xact, u16 yact, u16 xvir,
1112 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1113 int swap = (format == RGB888) ? 1 : 0;
1116 spin_lock(&vop_dev->reg_lock);
1117 if (likely(vop_dev->clk_on)) {
1118 val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap);
1119 vop_msk_reg(vop_dev, WIN0_CTRL0, val);
1121 vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_YRGB_VIR_STRIDE(xvir));
1122 vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) |
1123 V_WIN0_ACT_HEIGHT(yact - 1));
1125 vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst);
1127 vop_cfg_done(vop_dev);
1129 spin_unlock(&vop_dev->reg_lock);
1134 static void vop_reg_restore(struct rk_lcdc_driver *dev_drv)
1136 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1139 spin_lock(&vop_dev->reg_lock);
1141 if (likely(vop_dev->clk_on))
1142 memcpy(vop_dev->regs, vop_dev->regsbak, len);
1144 spin_unlock(&vop_dev->reg_lock);
1146 /* set screen GAMMA lut */
1147 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1148 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1151 vop_set_hwc_lut(dev_drv, dev_drv->hwc_lut, 0);
1154 static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1156 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1157 struct rk_screen *screen = dev_drv->cur_screen;
1159 /*if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1))*/
1160 /* flush_kthread_worker(&dev_drv->update_regs_worker);*/
1162 spin_lock(&vop_dev->reg_lock);
1163 if (likely(vop_dev->clk_on)) {
1164 vop_config_interface(dev_drv);
1165 vop_config_source(dev_drv);
1166 vop_config_timing(dev_drv);
1167 if (dev_drv->overlay_mode == VOP_YUV_DOMAIN)
1168 vop_config_background(dev_drv, 0x801080);
1170 vop_config_background(dev_drv, 0x000000);
1172 vop_bcsh_path_sel(dev_drv);
1173 vop_cfg_done(vop_dev);
1175 spin_unlock(&vop_dev->reg_lock);
1177 vop_set_dclk(dev_drv, 1);
1185 * enable or disable layer according to win id
1186 * @open: 1 enable; 0 disable
1188 static void vop_layer_enable(struct vop_device *vop_dev,
1189 unsigned int win_id, bool open)
1191 spin_lock(&vop_dev->reg_lock);
1192 if (likely(vop_dev->clk_on) &&
1193 vop_dev->driver.win[win_id]->state != open) {
1195 if (!vop_dev->atv_layer_cnt) {
1196 dev_info(vop_dev->dev,
1197 "wakeup from standby!\n");
1198 vop_dev->standby = 0;
1200 vop_dev->atv_layer_cnt |= (1 << win_id);
1202 if (vop_dev->atv_layer_cnt & (1 << win_id))
1203 vop_dev->atv_layer_cnt &= ~(1 << win_id);
1205 vop_dev->driver.win[win_id]->state = open;
1207 vop_layer_update_regs(vop_dev,
1208 vop_dev->driver.win[win_id]);
1209 vop_cfg_done(vop_dev);
1211 /* if no layer used,disable lcdc */
1212 if (!vop_dev->atv_layer_cnt) {
1213 dev_info(vop_dev->dev,
1214 "no layer is used,go to standby!\n");
1215 vop_dev->standby = 1;
1218 spin_unlock(&vop_dev->reg_lock);
1221 static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id,
1224 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1226 /* enable clk,when first layer open */
1227 if ((open) && (!vop_dev->atv_layer_cnt)) {
1228 /* rockchip_set_system_status(sys_status); */
1229 vop_pre_init(dev_drv);
1230 vop_clk_enable(vop_dev);
1231 vop_irq_enable(vop_dev);
1233 if (support_uboot_display() && (vop_dev->prop == PRMRY)) {
1234 vop_set_dclk(dev_drv, 0);
1236 vop_load_screen(dev_drv, 1);
1237 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1238 dev_drv->trsm_ops->enable();
1240 if (dev_drv->bcsh.enable)
1241 vop_set_bcsh(dev_drv, 1);
1243 /* set screen GAMMA lut */
1244 if (dev_drv->cur_screen && dev_drv->cur_screen->dsp_lut)
1245 vop_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut);
1248 if (win_id < ARRAY_SIZE(vop_win))
1249 vop_layer_enable(vop_dev, win_id, open);
1251 dev_err(vop_dev->dev, "invalid win id:%d\n", win_id);
1253 dev_drv->first_frame = 0;
1257 static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1259 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1260 struct rk_lcdc_win *win = NULL;
1261 struct rk_screen *screen = dev_drv->cur_screen;
1264 dev_err(dev_drv->dev, "screen is null!\n");
1268 if (win_id >= dev_drv->lcdc_win_num) {
1269 dev_err(dev_drv->dev, "invalid win id:%d!\n", win_id);
1273 win = dev_drv->win[win_id];
1274 win->area[0].y_addr = win->area[0].smem_start + win->area[0].y_offset;
1275 /* only win0 support yuv format */
1277 win->area[0].uv_addr =
1278 win->area[0].cbr_start + win->area[0].c_offset;
1280 win->area[0].uv_addr = 0;
1282 DBG(2, "lcdc[%d]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
1283 vop_dev->id, win->id, win->area[0].y_addr, win->area[0].uv_addr);
1284 DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
1285 win->area[0].y_offset, win->area[0].c_offset);
1289 static int win_0_1_set_par(struct vop_device *vop_dev,
1290 struct rk_screen *screen, struct rk_lcdc_win *win)
1292 char fmt[9] = "NULL";
1294 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1295 screen->mode.hsync_len;
1296 if (screen->mode.vmode & FB_VMODE_INTERLACED) {
1297 win->area[0].ysize /= 2;
1298 win->area[0].dsp_sty = win->area[0].ypos / 2 +
1299 screen->mode.upper_margin + screen->mode.vsync_len;
1301 win->area[0].dsp_sty = win->area[0].ypos +
1302 screen->mode.upper_margin + screen->mode.vsync_len;
1305 win->scale_yrgb_x = CALSCALE(win->area[0].xact, win->area[0].xsize);
1306 win->scale_yrgb_y = CALSCALE(win->area[0].yact, win->area[0].ysize);
1308 switch (win->area[0].format) {
1310 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1311 win->area[0].swap_rb = 0;
1315 win->area[0].fmt_cfg = VOP_FORMAT_ARGB888;
1316 win->area[0].swap_rb = 1;
1319 win->area[0].fmt_cfg = VOP_FORMAT_RGB888;
1320 win->area[0].swap_rb = 0;
1323 win->area[0].fmt_cfg = VOP_FORMAT_RGB565;
1324 win->area[0].swap_rb = 0;
1328 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR422;
1329 win->area[0].swap_rb = 0;
1330 win->area[0].swap_uv = 0;
1331 win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1332 win->area[0].xsize);
1333 win->scale_cbcr_y = CALSCALE(win->area[0].yact,
1334 win->area[0].ysize);
1336 dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1342 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1343 win->area[0].swap_rb = 0;
1344 win->area[0].swap_uv = 0;
1345 win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1346 win->area[0].xsize);
1347 win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1348 win->area[0].ysize);
1350 dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1357 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR420;
1358 win->area[0].swap_rb = 0;
1359 win->area[0].swap_uv = 1;
1360 win->scale_cbcr_x = CALSCALE(win->area[0].xact / 2,
1361 win->area[0].xsize);
1362 win->scale_cbcr_y = CALSCALE(win->area[0].yact / 2,
1363 win->area[0].ysize);
1365 dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1371 win->area[0].fmt_cfg = VOP_FORMAT_YCBCR444;
1372 win->area[0].swap_rb = 0;
1373 win->area[0].swap_uv = 0;
1375 CALSCALE(win->area[0].xact, win->area[0].xsize);
1377 CALSCALE(win->area[0].yact, win->area[0].ysize);
1379 dev_err(vop_dev->dev, "%s:win%d unsupport YUV format\n",
1384 dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n",
1385 __func__, win->area[0].format);
1389 DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
1390 vop_dev->id, win->id, get_format_string(win->area[0].format, fmt),
1391 win->area[0].xact, win->area[0].yact, win->area[0].xsize);
1392 DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
1393 win->area[0].ysize, win->area[0].xvir, win->area[0].yvir,
1394 win->area[0].xpos, win->area[0].ypos);
1399 static int hwc_set_par(struct vop_device *vop_dev,
1400 struct rk_screen *screen, struct rk_lcdc_win *win)
1402 win->area[0].dsp_stx = win->area[0].xpos + screen->mode.left_margin +
1403 screen->mode.hsync_len;
1404 win->area[0].dsp_sty = win->area[0].ypos + screen->mode.upper_margin +
1405 screen->mode.vsync_len;
1407 DBG(1, "lcdc[%d]:hwc>>%s\n>>xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d",
1408 vop_dev->id, __func__, win->area[0].xsize, win->area[0].ysize,
1409 win->area[0].xpos, win->area[0].ypos);
1413 static int vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
1415 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1416 struct rk_screen *screen = dev_drv->cur_screen;
1419 dev_err(dev_drv->dev, "screen is null!\n");
1425 win_0_1_set_par(vop_dev, screen, dev_drv->win[0]);
1428 win_0_1_set_par(vop_dev, screen, dev_drv->win[1]);
1431 hwc_set_par(vop_dev, screen, dev_drv->win[2]);
1434 dev_err(dev_drv->dev, "%s: unsupported win id:%d\n",
1441 static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
1442 unsigned long arg, int win_id)
1444 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1446 void __user *argp = (void __user *)arg;
1447 struct color_key_cfg clr_key_cfg;
1450 case RK_FBIOGET_PANEL_SIZE:
1451 panel_size[0] = vop_dev->screen->mode.xres;
1452 panel_size[1] = vop_dev->screen->mode.yres;
1453 if (copy_to_user(argp, panel_size, 8))
1456 case RK_FBIOPUT_COLOR_KEY_CFG:
1457 if (copy_from_user(&clr_key_cfg, argp,
1458 sizeof(struct color_key_cfg)))
1460 vop_clr_key_cfg(dev_drv);
1461 vop_writel(vop_dev, WIN0_COLOR_KEY,
1462 clr_key_cfg.win0_color_key_cfg);
1463 vop_writel(vop_dev, WIN1_COLOR_KEY,
1464 clr_key_cfg.win1_color_key_cfg);
1473 static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv)
1475 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1476 struct device_node *backlight;
1477 struct property *prop;
1478 u32 *brightness_levels;
1479 u32 length, max, last;
1481 if (vop_dev->backlight)
1483 backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0);
1485 vop_dev->backlight = of_find_backlight_by_node(backlight);
1486 if (!vop_dev->backlight)
1487 dev_info(vop_dev->dev, "No find backlight device\n");
1489 dev_info(vop_dev->dev, "No find backlight device node\n");
1491 prop = of_find_property(backlight, "brightness-levels", &length);
1494 max = length / sizeof(u32);
1496 brightness_levels = kmalloc(256, GFP_KERNEL);
1497 if (brightness_levels)
1500 if (!of_property_read_u32_array(backlight, "brightness-levels",
1501 brightness_levels, max)) {
1502 if (brightness_levels[0] > brightness_levels[last])
1503 dev_drv->cabc_pwm_pol = 1;/*negative*/
1505 dev_drv->cabc_pwm_pol = 0;/*positive*/
1507 dev_info(vop_dev->dev,
1508 "Can not read brightness-levels value\n");
1511 kfree(brightness_levels);
1516 static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable)
1518 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1520 if (dev_drv->suspend_flag)
1523 vop_get_backlight_device(dev_drv);
1526 /* close the backlight */
1527 if (vop_dev->backlight) {
1528 vop_dev->backlight->props.power = FB_BLANK_POWERDOWN;
1529 backlight_update_status(vop_dev->backlight);
1531 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1532 dev_drv->trsm_ops->disable();
1534 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1535 dev_drv->trsm_ops->enable();
1537 /* open the backlight */
1538 if (vop_dev->backlight) {
1539 vop_dev->backlight->props.power = FB_BLANK_UNBLANK;
1540 backlight_update_status(vop_dev->backlight);
1547 static int vop_early_suspend(struct rk_lcdc_driver *dev_drv)
1549 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1551 if (dev_drv->suspend_flag)
1554 dev_drv->suspend_flag = 1;
1556 flush_kthread_worker(&dev_drv->update_regs_worker);
1558 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
1559 dev_drv->trsm_ops->disable();
1561 vop_standby_enable(vop_dev);
1562 vop_mmu_disable(dev_drv);
1563 vop_clk_disable(vop_dev);
1564 rk_disp_pwr_disable(dev_drv);
1569 static int vop_early_resume(struct rk_lcdc_driver *dev_drv)
1571 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1573 if (!dev_drv->suspend_flag)
1576 rk_disp_pwr_enable(dev_drv);
1577 vop_clk_enable(vop_dev);
1578 vop_reg_restore(dev_drv);
1579 vop_standby_disable(vop_dev);
1580 vop_mmu_enable(dev_drv);
1581 dev_drv->suspend_flag = 0;
1583 if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1584 dev_drv->trsm_ops->enable();
1589 static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode)
1591 switch (blank_mode) {
1592 case FB_BLANK_UNBLANK:
1593 vop_early_resume(dev_drv);
1595 case FB_BLANK_NORMAL:
1596 vop_early_suspend(dev_drv);
1599 vop_early_suspend(dev_drv);
1603 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
1608 static int vop_get_win_state(struct rk_lcdc_driver *dev_drv,
1609 int win_id, int area_id)
1611 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1612 u32 area_status = 0, state = 0;
1614 spin_lock(&vop_dev->reg_lock);
1615 if (likely(vop_dev->clk_on)) {
1619 vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0));
1623 vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0));
1627 vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0));
1630 pr_err("%s: win[%d]area[%d],unsupport!!!\n",
1631 __func__, win_id, area_id);
1635 spin_unlock(&vop_dev->reg_lock);
1637 state = (area_status > 0) ? 1 : 0;
1641 static int vop_get_area_num(struct rk_lcdc_driver *dev_drv,
1642 unsigned int *area_support)
1644 area_support[0] = 1;
1645 area_support[1] = 1;
1650 static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set)
1652 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1655 spin_lock(&vop_dev->reg_lock);
1656 if (likely(vop_dev->clk_on)) {
1658 vop_msk_reg(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(swap));
1662 vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1667 spin_unlock(&vop_dev->reg_lock);
1672 static char *vop_format_to_string(int format, char *fmt)
1679 strcpy(fmt, "ARGB888");
1682 strcpy(fmt, "RGB888");
1685 strcpy(fmt, "RGB565");
1688 strcpy(fmt, "YCbCr420");
1691 strcpy(fmt, "YCbCr422");
1694 strcpy(fmt, "YCbCr444");
1697 strcpy(fmt, "invalid\n");
1703 static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
1704 char *buf, int win_id)
1706 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1707 struct rk_screen *screen = dev_drv->cur_screen;
1708 u16 hsync_len = screen->mode.hsync_len;
1709 u16 left_margin = screen->mode.left_margin;
1710 u16 vsync_len = screen->mode.vsync_len;
1711 u16 upper_margin = screen->mode.upper_margin;
1712 u32 h_pw_bp = hsync_len + left_margin;
1713 u32 v_pw_bp = vsync_len + upper_margin;
1715 char format_w0[9] = "NULL";
1716 char format_w1[9] = "NULL";
1718 u32 win_ctrl, ovl, vir_info, act_info, dsp_info, dsp_st;
1719 u32 y_factor, uv_factor;
1720 u8 w0_state, w1_state;
1722 u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
1723 u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
1724 u32 w1_vir_y, w1_dsp_x, w1_dsp_y;
1725 u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
1726 u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
1731 dclk_freq = screen->mode.pixclock;
1732 /*vop_reg_dump(dev_drv); */
1734 spin_lock(&vop_dev->reg_lock);
1735 if (likely(vop_dev->clk_on)) {
1736 ovl = vop_read_bit(vop_dev, DSP_CTRL2, V_DSP_WIN0_TOP(0));
1738 win_ctrl = vop_readl(vop_dev, WIN0_CTRL0);
1739 w0_state = win_ctrl & MASK(WIN0_EN);
1740 fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1;
1741 vop_format_to_string(fmt_id, format_w0);
1742 vir_info = vop_readl(vop_dev, WIN0_VIR);
1743 act_info = vop_readl(vop_dev, WIN0_ACT_INFO);
1744 dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO);
1745 dsp_st = vop_readl(vop_dev, WIN0_DSP_ST);
1746 y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB);
1747 uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR);
1748 w0_vir_y = vir_info & MASK(WIN0_YRGB_VIR_STRIDE);
1749 w0_vir_uv = (vir_info & MASK(WIN0_CBR_VIR_STRIDE)) >> 16;
1750 w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1;
1751 w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1;
1752 w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1;
1753 w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1;
1755 w0_st_x = dsp_st & MASK(WIN0_DSP_XST);
1756 w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16;
1758 w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB);
1759 w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16;
1760 w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR);
1761 w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16;
1764 win_ctrl = vop_readl(vop_dev, WIN1_CTRL0);
1765 w1_state = win_ctrl & MASK(WIN1_EN);
1766 fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1;
1767 vop_format_to_string(fmt_id, format_w1);
1768 vir_info = vop_readl(vop_dev, WIN1_VIR);
1769 dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO);
1770 dsp_st = vop_readl(vop_dev, WIN1_DSP_ST);
1771 w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE);
1772 w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1;
1773 w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1;
1775 w1_st_x = dsp_st & MASK(WIN1_DSP_XST);
1776 w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16;
1779 spin_unlock(&vop_dev->reg_lock);
1782 spin_unlock(&vop_dev->reg_lock);
1784 size += snprintf(dsp_buf, 80,
1785 "win0:\n state:%d, fmt:%7s\n y_vir:%4d, uv_vir:%4d,",
1786 w0_state, format_w0, w0_vir_y, w0_vir_uv);
1787 strcat(buf, dsp_buf);
1788 memset(dsp_buf, 0, sizeof(dsp_buf));
1790 size += snprintf(dsp_buf, 80,
1791 " x_act :%5d, y_act :%5d, dsp_x :%5d, dsp_y :%5d\n",
1792 w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
1793 strcat(buf, dsp_buf);
1794 memset(dsp_buf, 0, sizeof(dsp_buf));
1796 size += snprintf(dsp_buf, 80,
1797 " x_st :%4d, y_st :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
1798 w0_st_x - h_pw_bp, w0_st_y - v_pw_bp, w0_y_h_fac, w0_y_v_fac);
1799 strcat(buf, dsp_buf);
1800 memset(dsp_buf, 0, sizeof(dsp_buf));
1802 size += snprintf(dsp_buf, 80,
1803 "uv_h_fac:%5d, uv_v_fac:%5d\n y_addr:0x%08x, uv_addr:0x%08x\n",
1804 w0_uv_h_fac, w0_uv_v_fac, vop_readl(vop_dev, WIN0_YRGB_MST),
1805 vop_readl(vop_dev, WIN0_CBR_MST));
1806 strcat(buf, dsp_buf);
1807 memset(dsp_buf, 0, sizeof(dsp_buf));
1810 size += snprintf(dsp_buf, 80,
1811 "win1:\n state:%d, fmt:%7s\n y_vir:%4d,",
1812 w1_state, format_w1, w1_vir_y);
1813 strcat(buf, dsp_buf);
1814 memset(dsp_buf, 0, sizeof(dsp_buf));
1816 size += snprintf(dsp_buf, 80,
1817 " dsp_x :%5d, dsp_y :%5d\n",
1818 w1_dsp_x, w1_dsp_y);
1819 strcat(buf, dsp_buf);
1820 memset(dsp_buf, 0, sizeof(dsp_buf));
1822 size += snprintf(dsp_buf, 80,
1823 " x_st :%4d, y_st :%4d, ",
1824 w1_st_x - h_pw_bp, w1_st_y - v_pw_bp);
1825 strcat(buf, dsp_buf);
1826 memset(dsp_buf, 0, sizeof(dsp_buf));
1828 size += snprintf(dsp_buf, 80,
1830 vop_readl(vop_dev, WIN1_YRGB_MST));
1831 strcat(buf, dsp_buf);
1832 memset(dsp_buf, 0, sizeof(dsp_buf));
1835 size += snprintf(dsp_buf, 80,
1836 ovl ? "win0 on the top of win1\n" :
1837 "win1 on the top of win0\n");
1838 strcat(buf, dsp_buf);
1839 memset(dsp_buf, 0, sizeof(dsp_buf));
1844 static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set)
1846 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1847 struct rk_screen *screen = dev_drv->cur_screen;
1852 u32 x_total, y_total;
1856 dev_info(dev_drv->dev, "unsupport set fps=0\n");
1859 ft = div_u64(1000000000000llu, fps);
1861 screen->mode.upper_margin + screen->mode.lower_margin +
1862 screen->mode.yres + screen->mode.vsync_len;
1864 screen->mode.left_margin + screen->mode.right_margin +
1865 screen->mode.xres + screen->mode.hsync_len;
1866 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1867 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1868 ret = clk_set_rate(vop_dev->dclk, dotclk);
1871 pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk));
1872 vop_dev->pixclock = pixclock;
1873 dev_drv->pixclock = vop_dev->pixclock;
1874 fps = rk_fb_calc_fps(screen, pixclock);
1875 screen->ft = 1000 / fps; /*one frame time in ms */
1878 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1879 clk_get_rate(vop_dev->dclk), fps);
1884 static int vop_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
1886 mutex_lock(&dev_drv->fb_win_id_mutex);
1887 if (order == FB_DEFAULT_ORDER)
1888 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
1889 dev_drv->fb4_win_id = order / 10000;
1890 dev_drv->fb3_win_id = (order / 1000) % 10;
1891 dev_drv->fb2_win_id = (order / 100) % 10;
1892 dev_drv->fb1_win_id = (order / 10) % 10;
1893 dev_drv->fb0_win_id = order % 10;
1894 mutex_unlock(&dev_drv->fb_win_id_mutex);
1899 static int vop_get_win_id(struct rk_lcdc_driver *dev_drv, const char *id)
1903 mutex_lock(&dev_drv->fb_win_id_mutex);
1904 if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
1905 win_id = dev_drv->fb0_win_id;
1906 else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
1907 win_id = dev_drv->fb1_win_id;
1908 else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
1909 win_id = dev_drv->fb2_win_id;
1910 else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
1911 win_id = dev_drv->fb3_win_id;
1912 else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
1913 win_id = dev_drv->fb4_win_id;
1914 mutex_unlock(&dev_drv->fb_win_id_mutex);
1919 static int vop_config_done(struct rk_lcdc_driver *dev_drv)
1921 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1923 struct rk_lcdc_win *win = NULL;
1925 spin_lock(&vop_dev->reg_lock);
1926 if (likely(vop_dev->clk_on)) {
1927 for (i = 0; i < dev_drv->lcdc_win_num; i++) {
1928 win = dev_drv->win[i];
1929 vop_layer_update_regs(vop_dev, win);
1931 vop_cfg_done(vop_dev);
1933 spin_unlock(&vop_dev->reg_lock);
1938 static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1940 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1942 spin_lock(&vop_dev->reg_lock);
1943 if (likely(vop_dev->clk_on)) {
1944 vop_msk_reg(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(open));
1945 vop_cfg_done(vop_dev);
1947 spin_unlock(&vop_dev->reg_lock);
1952 static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1954 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1956 spin_lock(&vop_dev->reg_lock);
1957 if (likely(vop_dev->clk_on)) {
1958 vop_msk_reg(vop_dev, SYS_CTRL0,
1959 V_DIRECT_PATH_LAYER_SEL(win_id));
1960 vop_cfg_done(vop_dev);
1962 spin_unlock(&vop_dev->reg_lock);
1966 static int vop_dpi_status(struct rk_lcdc_driver *dev_drv)
1968 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1971 spin_lock(&vop_dev->reg_lock);
1973 if (likely(vop_dev->clk_on))
1974 status = vop_read_bit(vop_dev, SYS_CTRL0, V_DIRECT_PATH_EN(0));
1976 spin_unlock(&vop_dev->reg_lock);
1981 static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
1983 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1986 enable_irq(vop_dev->irq);
1988 disable_irq(vop_dev->irq);
1992 static int vop_poll_vblank(struct rk_lcdc_driver *dev_drv)
1994 struct vop_device *vop_dev = to_vop_dev(dev_drv);
1998 if (vop_dev->clk_on && (!dev_drv->suspend_flag)) {
1999 int_reg = vop_readl(vop_dev, INTR_STATUS);
2000 if (int_reg & INTR_LINE_FLAG0) {
2001 vop_dev->driver.frame_time.last_framedone_t =
2002 vop_dev->driver.frame_time.framedone_t;
2003 vop_dev->driver.frame_time.framedone_t = cpu_clock(0);
2004 vop_mask_writel(vop_dev, INTR_CLEAR, INTR_LINE_FLAG0,
2006 ret = RK_LF_STATUS_FC;
2008 ret = RK_LF_STATUS_FR;
2011 ret = RK_LF_STATUS_NC;
2017 static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
2018 unsigned int dsp_addr[][4])
2020 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2022 spin_lock(&vop_dev->reg_lock);
2023 if (likely(vop_dev->clk_on)) {
2024 dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST);
2025 dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST);
2026 dsp_addr[2][0] = vop_readl(vop_dev, HWC_MST);
2028 spin_unlock(&vop_dev->reg_lock);
2034 * sin_hue = sin(a)*256 +0x100;
2035 * cos_hue = cos(a)*256;
2037 * sin_hue = sin(a)*256;
2038 * cos_hue = cos(a)*256;
2040 static int vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode)
2042 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2045 spin_lock(&vop_dev->reg_lock);
2046 if (likely(vop_dev->clk_on)) {
2047 val = vop_readl(vop_dev, BCSH_H);
2050 val &= MASK(SIN_HUE);
2054 val &= MASK(COS_HUE);
2062 spin_unlock(&vop_dev->reg_lock);
2067 static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
2068 int sin_hue, int cos_hue)
2070 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2073 spin_lock(&vop_dev->reg_lock);
2074 if (likely(vop_dev->clk_on)) {
2076 * config range is [0, 510), typical value is 256
2077 * register range is [0, 255], cos_hue typical value is 128
2078 * sin_hue typical value is 0
2080 val = V_SIN_HUE(sin_hue >> 1) | V_COS_HUE(cos_hue >> 1);
2081 vop_msk_reg(vop_dev, BCSH_H, val);
2082 vop_cfg_done(vop_dev);
2084 spin_unlock(&vop_dev->reg_lock);
2089 static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
2090 bcsh_bcs_mode mode, int value)
2092 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2095 spin_lock(&vop_dev->reg_lock);
2096 if (likely(vop_dev->clk_on)) {
2100 * user range is [0, 255], typical value is 128
2101 * register range is [-32, 31], typical value is 0
2103 value >>= 2; /* 0-->32-->63 for user, typical is 32 */
2106 else if (value >= 0x20)
2107 value = value - 0x20;
2108 val = V_BRIGHTNESS(value);
2112 * config range is [0, 510), typical value is 256
2113 * register range is [0, 255], typical value is 128
2116 val = V_CONTRAST(value);
2120 * config range is [0, 1015], typical value is 512
2121 * register range is [0, 255], typical value is 128
2124 val = V_SAT_CON(value);
2129 vop_msk_reg(vop_dev, BCSH_BCS, val);
2130 vop_cfg_done(vop_dev);
2132 spin_unlock(&vop_dev->reg_lock);
2137 static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode)
2139 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2142 spin_lock(&vop_dev->reg_lock);
2143 if (likely(vop_dev->clk_on)) {
2144 val = vop_readl(vop_dev, BCSH_BCS);
2147 val &= MASK(BRIGHTNESS);
2155 val &= MASK(CONTRAST);
2160 val &= MASK(SAT_CON);
2168 spin_unlock(&vop_dev->reg_lock);
2172 static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
2174 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2176 spin_lock(&vop_dev->reg_lock);
2177 if (likely(vop_dev->clk_on)) {
2179 vop_writel(vop_dev, BCSH_BCS,
2180 V_BRIGHTNESS(0x00) | V_CONTRAST(0x80) |
2182 vop_writel(vop_dev, BCSH_H,
2183 V_SIN_HUE(0x00) | V_COS_HUE(0x80));
2184 vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(1) |
2185 V_VIDEO_MODE(BCSH_MODE_VIDEO));
2186 dev_drv->bcsh.enable = 1;
2188 vop_msk_reg(vop_dev, BCSH_CTRL, V_BCSH_EN(0));
2189 dev_drv->bcsh.enable = 0;
2191 vop_bcsh_path_sel(dev_drv);
2192 vop_cfg_done(vop_dev);
2194 spin_unlock(&vop_dev->reg_lock);
2199 static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
2201 if (!enable || !dev_drv->bcsh.enable) {
2202 vop_open_bcsh(dev_drv, false);
2206 if (dev_drv->bcsh.brightness <= 255 ||
2207 dev_drv->bcsh.contrast < 510 ||
2208 dev_drv->bcsh.sat_con <= 1015 ||
2209 (dev_drv->bcsh.sin_hue < 510 && dev_drv->bcsh.cos_hue < 510)) {
2210 vop_open_bcsh(dev_drv, true);
2211 if (dev_drv->bcsh.brightness <= 255)
2212 vop_set_bcsh_bcs(dev_drv, BRIGHTNESS,
2213 dev_drv->bcsh.brightness);
2214 if (dev_drv->bcsh.contrast < 510)
2215 vop_set_bcsh_bcs(dev_drv, CONTRAST,
2216 dev_drv->bcsh.contrast);
2217 if (dev_drv->bcsh.sat_con <= 1015)
2218 vop_set_bcsh_bcs(dev_drv, SAT_CON,
2219 dev_drv->bcsh.sat_con);
2220 if (dev_drv->bcsh.sin_hue < 510 &&
2221 dev_drv->bcsh.cos_hue < 510)
2222 vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue,
2223 dev_drv->bcsh.cos_hue);
2229 static int __maybe_unused
2230 vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
2232 struct vop_device *vop_dev = to_vop_dev(dev_drv);
2235 spin_lock(&vop_dev->reg_lock);
2236 if (likely(vop_dev->clk_on)) {
2237 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1));
2238 vop_cfg_done(vop_dev);
2240 spin_unlock(&vop_dev->reg_lock);
2242 spin_lock(&vop_dev->reg_lock);
2243 if (likely(vop_dev->clk_on)) {
2244 vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0));
2245 vop_cfg_done(vop_dev);
2247 spin_unlock(&vop_dev->reg_lock);
2253 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
2255 .win_direct_en = vop_win_direct_en,
2256 .load_screen = vop_load_screen,
2257 .get_dspbuf_info = vop_get_dspbuf_info,
2258 .post_dspbuf = vop_post_dspbuf,
2259 .set_par = vop_set_par,
2260 .pan_display = vop_pan_display,
2261 .direct_set_addr = vop_direct_set_win_addr,
2264 .suspend = vop_early_suspend,
2265 .resume = vop_early_resume,
2266 .get_win_state = vop_get_win_state,
2267 .area_support_num = vop_get_area_num,
2268 .ovl_mgr = vop_ovl_mgr,
2269 .get_disp_info = vop_get_disp_info,
2270 .fps_mgr = vop_fps_mgr,
2271 .fb_get_win_id = vop_get_win_id,
2272 .fb_win_remap = vop_fb_win_remap,
2273 .poll_vblank = vop_poll_vblank,
2274 .dpi_open = vop_dpi_open,
2275 .dpi_win_sel = vop_dpi_win_sel,
2276 .dpi_status = vop_dpi_status,
2277 .get_dsp_addr = vop_get_dsp_addr,
2278 .set_dsp_bcsh_hue = vop_set_bcsh_hue,
2279 .set_dsp_bcsh_bcs = vop_set_bcsh_bcs,
2280 .get_dsp_bcsh_hue = vop_get_bcsh_hue,
2281 .get_dsp_bcsh_bcs = vop_get_bcsh_bcs,
2282 .open_bcsh = vop_open_bcsh,
2283 .set_dsp_lut = vop_set_lut,
2284 .set_hwc_lut = vop_set_hwc_lut,
2285 .dump_reg = vop_reg_dump,
2286 .cfg_done = vop_config_done,
2287 .set_irq_to_cpu = vop_set_irq_to_cpu,
2288 /*.dsp_black = vop_dsp_black,*/
2289 .backlight_close = vop_backlight_close,
2290 .mmu_en = vop_mmu_enable,
2293 static irqreturn_t vop_isr(int irq, void *dev_id)
2295 struct vop_device *vop_dev = (struct vop_device *)dev_id;
2296 ktime_t timestamp = ktime_get();
2298 unsigned long flags;
2300 spin_lock_irqsave(&vop_dev->irq_lock, flags);
2302 intr_status = vop_readl(vop_dev, INTR_STATUS);
2303 vop_mask_writel(vop_dev, INTR_CLEAR, INTR_MASK, intr_status);
2305 spin_unlock_irqrestore(&vop_dev->irq_lock, flags);
2307 intr_status &= 0xffff; /* ignore raw status at 16~32bit */
2308 /* This is expected for vop iommu irqs, since the irq is shared */
2312 if (intr_status & INTR_FS0) {
2313 timestamp = ktime_get();
2314 vop_dev->driver.vsync_info.timestamp = timestamp;
2315 wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait);
2316 complete(&vop_dev->sync.frmst);
2317 intr_status &= ~INTR_FS0;
2320 /* fs1 interrupt occur only when the address is different */
2321 if (intr_status & INTR_FS1)
2322 intr_status &= ~INTR_FS1;
2324 if (intr_status & INTR_ADDR_SAME)
2325 intr_status &= ~INTR_ADDR_SAME;
2327 if (intr_status & INTR_DSP_HOLD_VALID) {
2328 complete(&vop_dev->sync.stdbyfin);
2329 intr_status &= ~INTR_DSP_HOLD_VALID;
2332 if (intr_status & INTR_LINE_FLAG0)
2333 intr_status &= ~INTR_LINE_FLAG0;
2335 if (intr_status & INTR_LINE_FLAG1)
2336 intr_status &= ~INTR_LINE_FLAG1;
2338 if (intr_status & INTR_BUS_ERROR) {
2339 intr_status &= ~INTR_BUS_ERROR;
2340 dev_warn_ratelimited(vop_dev->dev, "bus error!");
2343 if (intr_status & INTR_WIN0_EMPTY) {
2344 intr_status &= ~INTR_WIN0_EMPTY;
2345 dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!");
2348 if (intr_status & INTR_WIN1_EMPTY) {
2349 intr_status &= ~INTR_WIN1_EMPTY;
2350 dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!");
2353 if (intr_status & INTR_DMA_FINISH)
2354 intr_status &= ~INTR_DMA_FINISH;
2356 if (intr_status & INTR_MMU_STATUS)
2357 intr_status &= ~INTR_MMU_STATUS;
2360 dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status);
2365 #if defined(CONFIG_PM)
2366 static int vop_suspend(struct platform_device *pdev, pm_message_t state)
2371 static int vop_resume(struct platform_device *pdev)
2376 #define vop_suspend NULL
2377 #define vop_resume NULL
2380 static int vop_parse_dt(struct vop_device *vop_dev)
2382 struct device_node *np = vop_dev->dev->of_node;
2383 struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2386 if (of_property_read_u32(np, "rockchip,prop", &val))
2387 vop_dev->prop = PRMRY; /*default set it as primary */
2389 vop_dev->prop = val;
2391 if (of_property_read_u32(np, "rockchip,mirror", &val))
2392 dev_drv->rotate_mode = NO_MIRROR;
2394 dev_drv->rotate_mode = val;
2396 if (of_property_read_u32(np, "rockchip,pwr18", &val))
2397 /*default set it as 3.xv power supply */
2398 vop_dev->pwr18 = false;
2400 vop_dev->pwr18 = (val ? true : false);
2402 if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
2403 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
2405 dev_drv->fb_win_map = val;
2407 if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
2408 dev_drv->bcsh.enable = false;
2410 dev_drv->bcsh.enable = (val ? true : false);
2412 if (of_property_read_u32(np, "rockchip,brightness", &val))
2413 dev_drv->bcsh.brightness = 0xffff;
2415 dev_drv->bcsh.brightness = val;
2417 if (of_property_read_u32(np, "rockchip,contrast", &val))
2418 dev_drv->bcsh.contrast = 0xffff;
2420 dev_drv->bcsh.contrast = val;
2422 if (of_property_read_u32(np, "rockchip,sat-con", &val))
2423 dev_drv->bcsh.sat_con = 0xffff;
2425 dev_drv->bcsh.sat_con = val;
2427 if (of_property_read_u32(np, "rockchip,hue", &val)) {
2428 dev_drv->bcsh.sin_hue = 0xffff;
2429 dev_drv->bcsh.cos_hue = 0xffff;
2431 dev_drv->bcsh.sin_hue = val & 0xff;
2432 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
2435 if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
2436 dev_drv->iommu_enabled = 0;
2438 dev_drv->iommu_enabled = val;
2443 static int vop_probe(struct platform_device *pdev)
2445 struct vop_device *vop_dev = NULL;
2446 struct rk_lcdc_driver *dev_drv;
2447 struct device *dev = &pdev->dev;
2448 struct resource *res;
2449 struct device_node *np = pdev->dev.of_node;
2454 * if the primary lcdc has not registered ,the extend
2455 * lcdc register later
2457 of_property_read_u32(np, "rockchip,prop", &prop);
2458 if (prop == EXTEND) {
2459 if (!is_prmry_rk_lcdc_registered())
2460 return -EPROBE_DEFER;
2462 vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL);
2466 platform_set_drvdata(pdev, vop_dev);
2468 vop_parse_dt(vop_dev);
2470 /* enable power domain */
2471 pm_runtime_enable(dev);
2473 vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_vop");
2474 if (IS_ERR(vop_dev->hclk)) {
2475 dev_err(vop_dev->dev, "failed to get hclk source\n");
2476 return PTR_ERR(vop_dev->hclk);
2478 vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_vop");
2479 if (IS_ERR(vop_dev->aclk)) {
2480 dev_err(vop_dev->dev, "failed to get aclk source\n");
2481 return PTR_ERR(vop_dev->aclk);
2483 vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_vop");
2484 if (IS_ERR(vop_dev->dclk)) {
2485 dev_err(vop_dev->dev, "failed to get dclk source\n");
2486 return PTR_ERR(vop_dev->dclk);
2488 clk_prepare(vop_dev->hclk);
2489 clk_prepare(vop_dev->aclk);
2490 clk_prepare(vop_dev->dclk);
2492 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2493 vop_dev->regs = devm_ioremap_resource(dev, res);
2494 if (IS_ERR(vop_dev->regs)) {
2495 ret = PTR_ERR(vop_dev->regs);
2499 vop_dev->reg_phy_base = res->start;
2500 vop_dev->len = resource_size(res);
2501 vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL);
2502 if (!vop_dev->regsbak) {
2507 vop_dev->hwc_lut_addr_base = (vop_dev->regs + HWC_LUT_ADDR);
2508 vop_dev->dsp_lut_addr_base = (vop_dev->regs + GAMMA_LUT_ADDR);
2509 vop_dev->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
2510 if (IS_ERR(vop_dev->grf_base)) {
2511 dev_err(vop_dev->dev, "ERROR!! can't find grf reg property\n");
2512 vop_dev->grf_base = NULL;
2516 dev_set_name(vop_dev->dev, "vop%d", vop_dev->id);
2517 dev_drv = &vop_dev->driver;
2519 dev_drv->prop = prop;
2520 dev_drv->id = vop_dev->id;
2521 dev_drv->ops = &lcdc_drv_ops;
2522 dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win);
2523 dev_drv->reserved_fb = 0;
2524 spin_lock_init(&vop_dev->reg_lock);
2525 spin_lock_init(&vop_dev->irq_lock);
2526 init_completion(&vop_dev->sync.stdbyfin);
2527 init_completion(&vop_dev->sync.frmst);
2528 vop_dev->sync.stdbyfin_to = 50; /* timeout 50 ms */
2529 vop_dev->sync.frmst_to = 50;
2531 vop_dev->irq = platform_get_irq(pdev, 0);
2532 if (vop_dev->irq < 0) {
2533 dev_err(dev, "cannot find IRQ for lcdc%d\n", vop_dev->id);
2538 ret = devm_request_irq(dev, vop_dev->irq, vop_isr,
2540 dev_name(dev), vop_dev);
2542 dev_err(dev, "cannot requeset irq %d - err %d\n",
2547 if (dev_drv->iommu_enabled)
2548 strcpy(dev_drv->mmu_dts_name, VOPL_IOMMU_COMPATIBLE_NAME);
2550 ret = rk_fb_register(dev_drv, vop_win, vop_dev->id);
2552 dev_err(dev, "register fb for failed!\n");
2555 vop_dev->screen = dev_drv->screen0;
2556 dev_info(dev, "lcdc%d probe ok, iommu %s\n",
2557 vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
2562 clk_unprepare(vop_dev->dclk);
2563 clk_unprepare(vop_dev->aclk);
2564 clk_unprepare(vop_dev->hclk);
2565 pm_runtime_disable(dev);
2570 static int vop_remove(struct platform_device *pdev)
2575 static void vop_shutdown(struct platform_device *pdev)
2577 struct vop_device *vop_dev = platform_get_drvdata(pdev);
2578 struct rk_lcdc_driver *dev_drv = &vop_dev->driver;
2580 dev_drv->suspend_flag = 1;
2582 flush_kthread_worker(&dev_drv->update_regs_worker);
2583 kthread_stop(dev_drv->update_regs_thread);
2585 if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2586 dev_drv->trsm_ops->disable();
2588 vop_deinit(vop_dev);
2589 rk_disp_pwr_disable(dev_drv);
2592 #if defined(CONFIG_OF)
2593 static const struct of_device_id vop_dt_ids[] = {
2594 {.compatible = "rockchip,rk3366-lcdc-lite",},
2599 static struct platform_driver vop_driver = {
2601 .remove = vop_remove,
2603 .name = "rk-vop-lite",
2604 .owner = THIS_MODULE,
2605 .of_match_table = of_match_ptr(vop_dt_ids),
2607 .suspend = vop_suspend,
2608 .resume = vop_resume,
2609 .shutdown = vop_shutdown,
2612 static int __init vop_module_init(void)
2614 return platform_driver_register(&vop_driver);
2617 static void __exit vop_module_exit(void)
2619 platform_driver_unregister(&vop_driver);
2622 fs_initcall(vop_module_init);
2623 module_exit(vop_module_exit);