From: Huang Jiachai Date: Mon, 25 Jan 2016 12:04:19 +0000 (+0800) Subject: video: rockchip: vop: 322x: sync with develop-3.10 X-Git-Tag: firefly_0821_release~3468 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dbbe2a6bb425b4dd7c0dc33a5e465b2e16e59f5f;p=firefly-linux-kernel-4.4.55.git video: rockchip: vop: 322x: sync with develop-3.10 Change-Id: Iab27d3ac659df8f22198ec0c058cb864fec37c1d Signed-off-by: Huang Jiachai --- diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.c b/drivers/video/rockchip/lcdc/rk322x_lcdc.c index d444b0b872ea..50e1ceb80de8 100644 --- a/drivers/video/rockchip/lcdc/rk322x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.c @@ -180,6 +180,8 @@ static int vop_clk_enable(struct vop_device *vop_dev) clk_prepare_enable(vop_dev->hclk); clk_prepare_enable(vop_dev->dclk); clk_prepare_enable(vop_dev->aclk); + clk_prepare_enable(vop_dev->hclk_noc); + clk_prepare_enable(vop_dev->aclk_noc); spin_lock(&vop_dev->reg_lock); vop_dev->clk_on = 1; spin_unlock(&vop_dev->reg_lock); @@ -198,6 +200,8 @@ static int vop_clk_disable(struct vop_device *vop_dev) clk_disable_unprepare(vop_dev->dclk); clk_disable_unprepare(vop_dev->hclk); clk_disable_unprepare(vop_dev->aclk); + clk_disable_unprepare(vop_dev->hclk_noc); + clk_disable_unprepare(vop_dev->aclk_noc); } return 0; @@ -207,10 +211,10 @@ static int __maybe_unused vop_disable_irq(struct vop_device *vop_dev) { if (likely(vop_dev->clk_on)) { spin_lock(&vop_dev->reg_lock); - vop_writel(vop_dev, INTR_EN0, 0); - vop_writel(vop_dev, INTR_EN1, 0); - vop_writel(vop_dev, INTR_CLEAR0, 0xffff); - vop_writel(vop_dev, INTR_CLEAR1, 0xffff); + vop_writel(vop_dev, INTR_EN0, 0xffff0000); + vop_writel(vop_dev, INTR_EN1, 0xffff0000); + vop_writel(vop_dev, INTR_CLEAR0, 0xffffffff); + vop_writel(vop_dev, INTR_CLEAR1, 0xffffffff); vop_cfg_done(vop_dev); spin_unlock(&vop_dev->reg_lock); }; @@ -387,15 +391,16 @@ static int vop_pre_init(struct rk_lcdc_driver *dev_drv) if (vop_dev->pre_init) return 0; - vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc"); - vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc"); - vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc"); + vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_vop"); + vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_vop"); + vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_vop"); + vop_dev->hclk_noc = devm_clk_get(vop_dev->dev, "hclk_vop_noc"); + vop_dev->aclk_noc = devm_clk_get(vop_dev->dev, "aclk_vop_noc"); - if ((IS_ERR(vop_dev->aclk)) || (IS_ERR(vop_dev->dclk)) || - (IS_ERR(vop_dev->hclk))) { - dev_err(vop_dev->dev, "failed to get lcdc%d clk source\n", - vop_dev->id); - } + if (IS_ERR(vop_dev->aclk) || IS_ERR(vop_dev->dclk) || + IS_ERR(vop_dev->hclk) || IS_ERR(vop_dev->hclk_noc) || + IS_ERR(vop_dev->aclk_noc)) + dev_err(vop_dev->dev, "failed to get clk source\n"); if (!support_uboot_display()) rk_disp_pwr_enable(dev_drv); vop_clk_enable(vop_dev); @@ -443,6 +448,7 @@ static void vop_deint(struct vop_device *vop_dev) vop_cfg_done(vop_dev); spin_unlock(&vop_dev->reg_lock); + mdelay(50); } } @@ -783,7 +789,6 @@ static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id) int ppixel_alpha = 0, global_alpha = 0, i; u32 src_alpha_ctl, dst_alpha_ctl; int alpha_en = 1; - int layer_count = 0; for (i = 0; i < win->area_num; i++) { ppixel_alpha |= ((win->area[i].format == ARGB888) || @@ -795,13 +800,16 @@ static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id) global_alpha = (win->g_alpha_val == 0) ? 0 : 1; for (i = 0; i < dev_drv->lcdc_win_num; i++) { - if (dev_drv->win[i]->state) - layer_count++; + if (!dev_drv->win[i]->state) + continue; + if (win->z_order > dev_drv->win[i]->z_order) + break; } + /* - * vop not support ppixel_alpha mode when only enable 1 layer. + * The bottom layer not support ppixel_alpha mode. */ - if (layer_count == 1) + if (i == dev_drv->lcdc_win_num) ppixel_alpha = 0; alpha_config.src_global_alpha_val = win->g_alpha_val; win->alpha_mode = AB_SRC_OVER; @@ -937,13 +945,16 @@ static int vop_axi_gather_cfg(struct vop_device *vop_dev, case YUV444: case YUV422: case YUV420: + case YUV420_A: + case YUV422_A: + case YUV444_A: case YUV420_NV21: yrgb_gather_num = 1; cbcr_gather_num = 2; break; default: - dev_err(vop_dev->driver.dev, "%s:un supported format!\n", - __func__); + dev_err(vop_dev->driver.dev, "%s:un supported format[%d]\n", + __func__, win->area[0].format); return -EINVAL; } @@ -968,18 +979,57 @@ static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) struct rk_lcdc_win *win = dev_drv->win[win_id]; u64 val; uint32_t off; + int format; off = win_id * 0x40; if (win->state == 1) { vop_axi_gather_cfg(vop_dev, win); + + /* + * rk322x have a bug on windows 0 and 1: + * + * When switch win format from RGB to YUV, would flash + * some green lines on the top of the windows. + * + * Use bg_en show one blank frame to skip the error frame. + */ + if (IS_YUV(win->area[0].fmt_cfg)) { + val = vop_readl(vop_dev, WIN0_CTRL0); + format = (val & MASK(WIN0_DATA_FMT)) >> 1; + + if (!IS_YUV(format)) { + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { + val = V_WIN0_DSP_BG_RED(0x200) | + V_WIN0_DSP_BG_GREEN(0x40) | + V_WIN0_DSP_BG_BLUE(0x200) | + V_WIN0_BG_EN(1); + vop_msk_reg(vop_dev, WIN0_DSP_BG + off, + val); + } else { + val = V_WIN0_DSP_BG_RED(0) | + V_WIN0_DSP_BG_GREEN(0) | + V_WIN0_DSP_BG_BLUE(0) | + V_WIN0_BG_EN(1); + vop_msk_reg(vop_dev, WIN0_DSP_BG + off, + val); + } + } else { + val = V_WIN0_BG_EN(0); + vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val); + } + } else { + val = V_WIN0_BG_EN(0); + vop_msk_reg(vop_dev, WIN0_DSP_BG + off, val); + } + val = V_WIN0_EN(win->state) | V_WIN0_DATA_FMT(win->area[0].fmt_cfg) | V_WIN0_FMT_10(win->fmt_10) | V_WIN0_LB_MODE(win->win_lb_mode) | V_WIN0_RB_SWAP(win->area[0].swap_rb) | - V_WIN0_X_MIR_EN(win->mirror_en) | - V_WIN0_Y_MIR_EN(win->mirror_en) | + V_WIN0_X_MIR_EN(win->xmirror) | + V_WIN0_Y_MIR_EN(win->ymirror) | V_WIN0_UV_SWAP(win->area[0].swap_uv); vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); val = V_WIN0_BIC_COE_SEL(win->bic_coe_el) | @@ -1027,15 +1077,6 @@ static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val); } - if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED) { - if (win->area[0].yact == 2 * win->area[0].ysize) - val = V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - else - val = V_WIN0_YRGB_DEFLICK(1) | - V_WIN0_CBR_DEFLICK(1); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - } } else { val = V_WIN0_EN(win->state); vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); @@ -1070,7 +1111,8 @@ static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) (win->area[0].ysize == 128)) hwc_size = 3; else - dev_err(vop_dev->dev, "un supported hwc size!\n"); + dev_err(vop_dev->dev, "un supported hwc size[%dx%d]!\n", + win->area[0].xsize, win->area[0].ysize); val = V_HWC_SIZE(hwc_size); vop_msk_reg(vop_dev, HWC_CTRL0, val); @@ -1152,7 +1194,8 @@ static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate) if (reset_rate) ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock); if (ret) - dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", vop_dev->id); + dev_err(dev_drv->dev, "set lcdc%d dclk[%d] failed\n", + vop_dev->id, screen->mode.pixclock); vop_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk)); vop_dev->driver.pixclock = vop_dev->pixclock; @@ -1218,25 +1261,12 @@ static int vop_config_timing(struct rk_lcdc_driver *dev_drv) vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val); vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0)); - val = V_WIN0_INTERLACE_READ(1) | V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - - val = V_WIN1_INTERLACE_READ(1) | V_WIN1_YRGB_DEFLICK(0) | - V_WIN1_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - - val = V_WIN2_INTERLACE_READ(1); - vop_msk_reg(vop_dev, WIN2_CTRL0, val); - val = V_WIN3_INTERLACE_READ(1); - vop_msk_reg(vop_dev, WIN3_CTRL0, val); + val = V_DSP_LINE_FLAG_NUM_0(lower_margin ? + vact_end_f1 : vact_end_f1 - 1); - val = V_HWC_INTERLACE_READ(1); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - - val = V_DSP_LINE_FLAG_NUM_0(vact_end_f1) | - V_DSP_LINE_FLAG_NUM_1(vact_end_f1); + val |= V_DSP_LINE_FLAG_NUM_1(lower_margin ? + vact_end_f1 : vact_end_f1 - 1); vop_msk_reg(vop_dev, LINE_FLAG, val); } else { val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total); @@ -1249,23 +1279,6 @@ static int vop_config_timing(struct rk_lcdc_driver *dev_drv) vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) | V_DSP_FIELD_POL(0)); - val = V_WIN0_INTERLACE_READ(0) | V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - - val = V_WIN1_INTERLACE_READ(0) | V_WIN1_YRGB_DEFLICK(0) | - V_WIN1_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - - val = V_WIN2_INTERLACE_READ(0); - vop_msk_reg(vop_dev, WIN2_CTRL0, val); - - val = V_WIN3_INTERLACE_READ(0); - vop_msk_reg(vop_dev, WIN3_CTRL0, val); - - val = V_HWC_INTERLACE_READ(0); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) | V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res); vop_msk_reg(vop_dev, LINE_FLAG, val); @@ -1315,7 +1328,8 @@ static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) } static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, - u16 *yact, int *format, u32 *dsp_addr) + u16 *yact, int *format, u32 *dsp_addr, + int *ymirror) { struct vop_device *vop_dev = container_of(dev_drv, struct vop_device, driver); @@ -1329,6 +1343,7 @@ static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, val = vop_readl(vop_dev, WIN0_CTRL0); *format = (val & MASK(WIN0_DATA_FMT)) >> 1; + *ymirror = (val & MASK(WIN0_Y_MIR_EN)) >> 22; *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST); spin_unlock(&vop_dev->reg_lock); @@ -1337,14 +1352,17 @@ static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, } static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir) + int format, u16 xact, u16 yact, u16 xvir, + int ymirror) { struct vop_device *vop_dev = container_of(dev_drv, struct vop_device, driver); int swap = (format == RGB888) ? 1 : 0; + struct rk_lcdc_win *win = dev_drv->win[0]; u64 val; - val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap); + val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap) | + V_WIN0_Y_MIR_EN(ymirror); vop_msk_reg(vop_dev, WIN0_CTRL0, val); vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir)); @@ -1355,6 +1373,15 @@ static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, vop_cfg_done(vop_dev); + if (format == RGB888) + win->area[0].format = BGR888; + else + win->area[0].format = format; + + win->ymirror = ymirror; + win->state = 1; + win->last_state = 1; + return 0; } @@ -1411,17 +1438,52 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) if (likely(vop_dev->clk_on)) { switch (screen->face) { case OUT_P888: - face = OUT_P888; - val = V_DITHER_DOWN_EN(0); + if (rockchip_get_cpu_version()) + face = OUT_P101010; + else + face = OUT_P888; + + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(0) + | V_PRE_DITHER_DOWN_EN(1); break; case OUT_YUV_420: - /*yuv420 output prefer yuv domain overlay */ - face = OUT_YUV_420; - dclk_ddr = 1; - val = V_DITHER_DOWN_EN(0); + if (rockchip_get_cpu_version()) { + face = OUT_YUV_420; + dclk_ddr = 1; + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(0) + | V_PRE_DITHER_DOWN_EN(1); + break; + } + dev_err(vop_dev->dev, + "This chip can't supported screen face[%d]\n", + screen->face); + break; + case OUT_YUV_420_10BIT: + if (rockchip_get_cpu_version()) { + face = OUT_YUV_420; + dclk_ddr = 1; + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) + | V_PRE_DITHER_DOWN_EN(0); + break; + } + dev_err(vop_dev->dev, + "This chip can't supported screen face[%d]\n", + screen->face); + break; + case OUT_P101010: + if (rockchip_get_cpu_version()) { + face = OUT_P101010; + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) + | V_PRE_DITHER_DOWN_EN(0); + break; + } + dev_err(vop_dev->dev, + "This chip can't supported screen face[%d]\n", + screen->face); break; default: - dev_err(vop_dev->dev, "un supported interface!\n"); + dev_err(vop_dev->dev, "un supported screen face[%d]!\n", + screen->face); break; } @@ -1444,7 +1506,8 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) vop_msk_reg(vop_dev, SYS_CTRL, val); break; default: - dev_err(vop_dev->dev, "un supported interface!\n"); + dev_err(vop_dev->dev, "un supported interface[%d]!\n", + screen->type); break; } val = V_HDMI_HSYNC_POL(screen->pin_hsync) | @@ -1476,19 +1539,31 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) V_DSP_BLANK_EN(0) | V_DSP_BLACK_EN(0) | V_DSP_X_MIR_EN(screen->x_mirror) | V_DSP_Y_MIR_EN(screen->y_mirror); - if (screen->pixelrepeat) - val |= V_SW_CORE_DCLK_SEL(1); + val |= V_SW_CORE_DCLK_SEL(!!screen->pixelrepeat); if (screen->mode.vmode & FB_VMODE_INTERLACED) val |= V_SW_HDMI_CLK_I_SEL(1); + else + val |= V_SW_HDMI_CLK_I_SEL(0); vop_msk_reg(vop_dev, DSP_CTRL0, val); - /* BG color */ - if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) - val = V_DSP_BG_BLUE(0x80) | V_DSP_BG_GREEN(0x10) | - V_DSP_BG_RED(0x80); + + if (screen->mode.vmode & FB_VMODE_INTERLACED) + vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(1)); else + vop_msk_reg(vop_dev, SYS_CTRL1, V_REG_DONE_FRM(0)); + /* BG color */ + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { + val = V_DSP_OUT_RGB_YUV(1); + vop_msk_reg(vop_dev, POST_SCL_CTRL, val); + val = V_DSP_BG_BLUE(0x200) | V_DSP_BG_GREEN(0x40) | + V_DSP_BG_RED(0x200); + vop_msk_reg(vop_dev, DSP_BG, val); + } else { + val = V_DSP_OUT_RGB_YUV(0); + vop_msk_reg(vop_dev, POST_SCL_CTRL, val); val = V_DSP_BG_BLUE(0) | V_DSP_BG_GREEN(0) | V_DSP_BG_RED(0); - vop_msk_reg(vop_dev, DSP_BG, val); + vop_msk_reg(vop_dev, DSP_BG, val); + } dev_drv->output_color = screen->color_mode; vop_bcsh_path_sel(dev_drv); vop_config_timing(dev_drv); @@ -1548,7 +1623,10 @@ static int vop_enable_irq(struct rk_lcdc_driver *dev_drv) vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK); - val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1; + val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 | + INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY | + INTR_POST_BUF_EMPTY; + vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val); return 0; @@ -1880,7 +1958,7 @@ static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen) break; } - if (win->mirror_en == 1) + if (win->ymirror == 1) win->yrgb_vsd_mode = SCALE_DOWN_BIL; if (screen->mode.vmode & FB_VMODE_INTERLACED) { /* interlace mode must bill */ @@ -2136,18 +2214,14 @@ static int dsp_y_pos(int mirror_en, struct rk_screen *screen, if (screen->y_mirror && mirror_en) pr_err("not support both win and global mirror\n"); - if (screen->mode.vmode & FB_VMODE_NONINTERLACED) { - if ((!mirror_en) && (!screen->y_mirror)) - pos = area->ypos + screen->mode.upper_margin + - screen->mode.vsync_len; - else - pos = screen->mode.yres - area->ypos - - area->ysize + screen->mode.upper_margin + - screen->mode.vsync_len; - } else if (screen->mode.vmode & FB_VMODE_INTERLACED) { - pos = area->ypos / 2 + screen->mode.upper_margin + + + if ((!mirror_en) && (!screen->y_mirror)) + pos = area->ypos + screen->mode.upper_margin + + screen->mode.vsync_len; + else + pos = screen->mode.yres - area->ypos - + area->ysize + screen->mode.upper_margin + screen->mode.vsync_len; - } return pos; } @@ -2159,8 +2233,8 @@ static int win_0_1_set_par(struct vop_device *vop_dev, u8 fmt_cfg = 0, swap_rb, swap_uv = 0; char fmt[9] = "NULL"; - xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]); - ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]); + xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]); + ypos = dsp_y_pos(win->ymirror, screen, &win->area[0]); spin_lock(&vop_dev->reg_lock); if (likely(vop_dev->clk_on)) { @@ -2201,6 +2275,11 @@ static int win_0_1_set_par(struct vop_device *vop_dev, swap_rb = 1; win->fmt_10 = 0; break; + case BGR888: + fmt_cfg = 1; + swap_rb = 1; + win->fmt_10 = 0; + break; case RGB888: fmt_cfg = 1; swap_rb = 0; @@ -2248,8 +2327,8 @@ static int win_0_1_set_par(struct vop_device *vop_dev, win->fmt_10 = 1; break; default: - dev_err(vop_dev->driver.dev, "%s:unsupport format!\n", - __func__); + dev_err(vop_dev->dev, "%s:unsupport format[%d]!\n", + __func__, win->area[0].format); break; } win->area[0].fmt_cfg = fmt_cfg; @@ -2307,8 +2386,8 @@ static int hwc_set_par(struct vop_device *vop_dev, swap_rb = 0; break; default: - dev_err(vop_dev->driver.dev, - "%s:un supported format!\n", __func__); + dev_err(vop_dev->dev, "%s:un supported format[%d]!\n", + __func__, win->area[0].format); break; } win->area[0].fmt_cfg = fmt_cfg; @@ -2320,7 +2399,7 @@ static int hwc_set_par(struct vop_device *vop_dev, xvir = win->area[0].xvir; yvir = win->area[0].yvir; } - vop_hwc_reg_update(&vop_dev->driver, 4); + vop_hwc_reg_update(&vop_dev->driver, 2); spin_unlock(&vop_dev->reg_lock); DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d", @@ -3359,8 +3438,29 @@ static irqreturn_t vop_isr(int irq, void *dev_id) if (intr_status & INTR_BUS_ERROR) { intr_status &= ~INTR_BUS_ERROR; - dev_warn(vop_dev->dev, "bus error!"); + dev_warn_ratelimited(vop_dev->dev, "bus error!"); + } + + if (intr_status & INTR_WIN0_EMPTY) { + intr_status &= ~INTR_WIN0_EMPTY; + dev_warn_ratelimited(vop_dev->dev, "intr win0 empty!"); } + + if (intr_status & INTR_WIN1_EMPTY) { + intr_status &= ~INTR_WIN1_EMPTY; + dev_warn_ratelimited(vop_dev->dev, "intr win1 empty!"); + } + + if (intr_status & INTR_HWC_EMPTY) { + intr_status &= ~INTR_HWC_EMPTY; + dev_warn_ratelimited(vop_dev->dev, "intr hwc empty!"); + } + + if (intr_status & INTR_POST_BUF_EMPTY) { + intr_status &= ~INTR_POST_BUF_EMPTY; + dev_warn_ratelimited(vop_dev->dev, "intr post buf empty!"); + } + if (intr_status) dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status); @@ -3467,10 +3567,9 @@ static int vop_probe(struct platform_device *pdev) return -EPROBE_DEFER; } vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL); - if (!vop_dev) { - dev_err(&pdev->dev, "rk3228 lcdc device kmalloc fail!"); + if (!vop_dev) return -ENOMEM; - } + platform_set_drvdata(pdev, vop_dev); vop_dev->dev = dev; vop_parse_dt(vop_dev); @@ -3495,7 +3594,7 @@ static int vop_probe(struct platform_device *pdev) dev_drv->id = vop_dev->id; dev_drv->ops = &lcdc_drv_ops; dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win); - dev_drv->reserved_fb = 1;/*only need reserved 1 buffer*/ + dev_drv->reserved_fb = 0; spin_lock_init(&vop_dev->reg_lock); spin_lock_init(&vop_dev->irq_lock); @@ -3520,7 +3619,7 @@ static int vop_probe(struct platform_device *pdev) ret = rk_fb_register(dev_drv, vop_win, vop_dev->id); if (ret < 0) { - dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id); + dev_err(dev, "register fb for failed!\n"); return ret; } vop_dev->screen = dev_drv->screen0; diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.h b/drivers/video/rockchip/lcdc/rk322x_lcdc.h index 3be4be76ff09..c26473ce8e92 100644 --- a/drivers/video/rockchip/lcdc/rk322x_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.h @@ -275,6 +275,7 @@ static inline u64 val_mask(int val, u64 msk, int shift) #define V_AXI_OUTSTANDING_MAX_NUM(x) VAL_MASK(x, 5, 13) #define V_NOC_HURRY_W_MODE(x) VAL_MASK(x, 2, 20) #define V_NOC_HURRY_W_VALUE(x) VAL_MASK(x, 2, 22) +#define V_REG_DONE_FRM(x) VAL_MASK(x, 1, 24) #define V_DSP_FP_STANDBY(x) VAL_MASK(x, 1, 31) #define DSP_CTRL0 0x00000010 #define V_DSP_OUT_MODE(x) VAL_MASK(x, 4, 0) @@ -326,9 +327,9 @@ static inline u64 val_mask(int val, u64 msk, int shift) #define V_MIPI_DEN_POL(x) VAL_MASK(x, 1, 30) #define V_MIPI_DCLK_POL(x) VAL_MASK(x, 1, 31) #define DSP_BG 0x00000018 -#define V_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_DSP_BG_BLUE(x) VAL_MASK(x, 10, 0) +#define V_DSP_BG_GREEN(x) VAL_MASK(x, 10, 10) +#define V_DSP_BG_RED(x) VAL_MASK(x, 10, 20) #define MCU_CTRL 0x0000001c #define V_MCU_PIX_TOTAL(x) VAL_MASK(x, 6, 0) #define V_MCU_CS_PST(x) VAL_MASK(x, 4, 6) @@ -788,6 +789,7 @@ static inline u64 val_mask(int val, u64 msk, int shift) #define POST_SCL_CTRL 0x00000180 #define V_POST_HOR_SD_EN(x) VAL_MASK(x, 1, 0) #define V_POST_VER_SD_EN(x) VAL_MASK(x, 1, 1) +#define V_DSP_OUT_RGB_YUV(x) VAL_MASK(x, 1, 2) #define POST_DSP_VACT_INFO_F1 0x00000184 #define V_DSP_VACT_END_POST(x) VAL_MASK(x, 13, 0) #define V_DSP_VACT_ST_POST(x) VAL_MASK(x, 13, 16) @@ -1119,24 +1121,24 @@ static inline u64 val_mask(int val, u64 msk, int shift) #define V_BLANKING_VALUE_CONFIG_EN(x) VAL_MASK(x, 1, 24) #define MCU_BYPASS_PORT 0x000002ac #define WIN0_DSP_BG 0x000002b0 -#define V_WIN0_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN0_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN0_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN0_DSP_BG_BLUE(x) VAL_MASK(x, 10, 0) +#define V_WIN0_DSP_BG_GREEN(x) VAL_MASK(x, 10, 10) +#define V_WIN0_DSP_BG_RED(x) VAL_MASK(x, 10, 20) #define V_WIN0_BG_EN(x) VAL_MASK(x, 1, 31) #define WIN1_DSP_BG 0x000002b4 -#define V_WIN1_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN1_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN1_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN1_DSP_BG_BLUE(x) VAL_MASK(x, 10, 0) +#define V_WIN1_DSP_BG_GREEN(x) VAL_MASK(x, 10, 10) +#define V_WIN1_DSP_BG_RED(x) VAL_MASK(x, 10, 20) #define V_WIN1_BG_EN(x) VAL_MASK(x, 1, 31) #define WIN2_DSP_BG 0x000002b8 -#define V_WIN2_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN2_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN2_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN2_DSP_BG_BLUE(x) VAL_MASK(x, 10, 0) +#define V_WIN2_DSP_BG_GREEN(x) VAL_MASK(x, 10, 10) +#define V_WIN2_DSP_BG_RED(x) VAL_MASK(x, 10, 20) #define V_WIN2_BG_EN(x) VAL_MASK(x, 1, 31) #define WIN3_DSP_BG 0x000002bc -#define V_WIN3_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN3_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN3_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN3_DSP_BG_BLUE(x) VAL_MASK(x, 10, 0) +#define V_WIN3_DSP_BG_GREEN(x) VAL_MASK(x, 10, 10) +#define V_WIN3_DSP_BG_RED(x) VAL_MASK(x, 10, 20) #define V_WIN3_BG_EN(x) VAL_MASK(x, 1, 31) #define YUV2YUV_WIN 0x000002c0 #define V_WIN0_YUV2YUV_EN(x) VAL_MASK(x, 1, 0) @@ -1321,6 +1323,8 @@ struct vop_device { struct clk *hclk; /*lcdc AHP clk*/ struct clk *dclk; /*lcdc dclk*/ struct clk *aclk; /*lcdc share memory frequency*/ + struct clk *hclk_noc; + struct clk *aclk_noc; u32 pixclock; u32 standby; /*1:standby,0:wrok*/