clk_prepare_enable(vop_dev->hclk_noc);
if (vop_dev->aclk_noc)
clk_prepare_enable(vop_dev->aclk_noc);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ pm_runtime_get_sync(vop_dev->dev);
+#endif
spin_lock(&vop_dev->reg_lock);
vop_dev->clk_on = 1;
spin_unlock(&vop_dev->reg_lock);
vop_dev->clk_on = 0;
spin_unlock(&vop_dev->reg_lock);
mdelay(25);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ pm_runtime_put(vop_dev->dev);
+#endif
clk_disable_unprepare(vop_dev->dclk);
clk_disable_unprepare(vop_dev->hclk);
clk_disable_unprepare(vop_dev->aclk);
{
struct vop_device *vop_dev =
container_of(drv, struct vop_device, driver);
+
+ drv->win[win_id]->state = en;
if (win_id == 0)
win0_enable(vop_dev, en);
else if (win_id == 1)
vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb);
vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de);
- vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(0));
+ vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(1));
vop_msk_reg(vop_dev, DSP_CTRL1, V_DITHER_UP_EN(1));
vop_cfg_done(vop_dev);
vop_dev->pre_init = true;
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
int output_color = dev_drv->output_color;
- int win_csc, overlay_mode;
+ int win_csc = 0, overlay_mode = 0;
u64 val;
if (VOP_CHIP(vop_dev) == VOP_RK322X) {
struct alpha_config alpha_config;
u64 val;
int ppixel_alpha = 0, global_alpha = 0, i;
- u32 src_alpha_ctl, dst_alpha_ctl;
+ u32 src_alpha_ctl = 0, dst_alpha_ctl = 0;
int alpha_en = 1;
+ memset(&alpha_config, 0, sizeof(struct alpha_config));
for (i = 0; i < win->area_num; i++) {
ppixel_alpha |= ((win->area[i].format == ARGB888) ||
(win->area[i].format == FBDC_ARGB_888) ||
static int vop_fbdc_reg_update(struct vop_device *vop_dev, int win_id)
{
struct rk_lcdc_win *win = vop_dev->driver.win[win_id];
- u32 val;
+ u64 val;
val = V_VOP_FBDC_WIN_SEL(win_id) |
V_AFBCD_HREG_PIXEL_PACKING_FMT(win->area[0].fbdc_fmt_cfg) |
return 0;
}
- win->area[0].fbdc_mb_width = win->area[0].xact;
+ win->area[0].fbdc_mb_width = win->area[0].xvir;
win->area[0].fbdc_mb_height = win->area[0].yact;
win->area[0].fbdc_cor_en = 0; /* hreg_block_split */
- win->area[0].fbdc_fmt_cfg |= 0 << 4;
+ win->area[0].fbdc_fmt_cfg |= AFBDC_YUV_COLOR_TRANSFORM << 4;
return 0;
}
val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val);
- if (win->alpha_en == 1) {
- vop_alpha_cfg(dev_drv, win_id);
- } else {
- val = V_WIN0_SRC_ALPHA_EN(0);
- vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val);
- }
-
} else {
val = V_WIN0_EN(win->state);
vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
val = V_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
- val = V_WIN2_DSP_WIDTH0(win->area[0].xsize) |
- V_WIN2_DSP_HEIGHT0(win->area[0].ysize);
+ val = V_WIN2_DSP_WIDTH0(win->area[0].xsize - 1) |
+ V_WIN2_DSP_HEIGHT0(win->area[0].ysize - 1);
vop_writel(vop_dev, WIN2_DSP_INFO0 + off, val);
val = V_WIN2_DSP_XST0(win->area[0].dsp_stx) |
V_WIN2_DSP_YST0(win->area[0].dsp_sty);
val = V_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
vop_msk_reg(vop_dev, WIN2_VIR0_1 + off, val);
- val = V_WIN2_DSP_WIDTH1(win->area[1].xsize) |
- V_WIN2_DSP_HEIGHT1(win->area[1].ysize);
+ val = V_WIN2_DSP_WIDTH1(win->area[1].xsize - 1) |
+ V_WIN2_DSP_HEIGHT1(win->area[1].ysize - 1);
vop_writel(vop_dev, WIN2_DSP_INFO1 + off, val);
val = V_WIN2_DSP_XST1(win->area[1].dsp_stx) |
V_WIN2_DSP_YST1(win->area[1].dsp_sty);
val = V_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
- val = V_WIN2_DSP_WIDTH2(win->area[2].xsize) |
- V_WIN2_DSP_HEIGHT2(win->area[2].ysize);
+ val = V_WIN2_DSP_WIDTH2(win->area[2].xsize - 1) |
+ V_WIN2_DSP_HEIGHT2(win->area[2].ysize - 1);
vop_writel(vop_dev, WIN2_DSP_INFO2 + off, val);
val = V_WIN2_DSP_XST2(win->area[2].dsp_stx) |
V_WIN2_DSP_YST2(win->area[2].dsp_sty);
val = V_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
vop_msk_reg(vop_dev, WIN2_VIR2_3 + off, val);
- val = V_WIN2_DSP_WIDTH3(win->area[3].xsize) |
- V_WIN2_DSP_HEIGHT3(win->area[3].ysize);
+ val = V_WIN2_DSP_WIDTH3(win->area[3].xsize - 1) |
+ V_WIN2_DSP_HEIGHT3(win->area[3].ysize - 1);
vop_writel(vop_dev, WIN2_DSP_INFO3 + off, val);
val = V_WIN2_DSP_XST3(win->area[3].dsp_stx) |
V_WIN2_DSP_YST3(win->area[3].dsp_sty);
val = V_WIN2_MST3_EN(0);
vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
}
-
- if (win->alpha_en == 1) {
- vop_alpha_cfg(dev_drv, win_id);
- } else {
- val = V_WIN2_SRC_ALPHA_EN(0);
- vop_msk_reg(vop_dev, WIN2_SRC_ALPHA_CTRL + off, val);
- }
} else {
val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
V_HWC_DSP_YST(win->area[0].dsp_sty);
vop_msk_reg(vop_dev, HWC_DSP_ST, val);
-
- if (win->alpha_en == 1) {
- vop_alpha_cfg(dev_drv, win_id);
- } else {
- val = V_WIN2_SRC_ALPHA_EN(0);
- vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val);
- }
} else {
val = V_HWC_EN(win->state);
vop_msk_reg(vop_dev, HWC_CTRL0, val);
vop_msk_reg(vop_dev, LINE_FLAG, val);
}
vop_post_cfg(dev_drv);
+ if ((x_res <= VOP_INPUT_MAX_WIDTH / 2) && (vop_dev->id == 0))
+ vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(1));
+ else
+ vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(0));
return 0;
}
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
struct rk_screen *screen = dev_drv->cur_screen;
- u64 val;
+ u64 val = 0;
if (unlikely(!vop_dev->clk_on)) {
pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
V_DITHER_DOWN_SEL(0) |
V_DITHER_DOWN_MODE(0);
break;
+ case OUT_YUV_422:
+ face = OUT_YUV_422;
+ val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
+ V_PRE_DITHER_DOWN_EN(1) |
+ V_DITHER_DOWN_SEL(0) |
+ V_DITHER_DOWN_MODE(0);
+ break;
+ case OUT_YUV_422_10BIT:
+ face = OUT_YUV_422;
+ val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
+ V_PRE_DITHER_DOWN_EN(0) |
+ V_DITHER_DOWN_SEL(0) |
+ V_DITHER_DOWN_MODE(0);
+ break;
case OUT_P101010:
face = OUT_P101010;
val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) |
vop_msk_reg(vop_dev, SYS_CTRL, val);
break;
case SCREEN_HDMI:
- if ((screen->face == OUT_P888) ||
- (screen->face == OUT_P101010))
- face = OUT_P101010; /*RGB 101010 output*/
+ if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
+ ((screen->face == OUT_P888) ||
+ (screen->face == OUT_P101010))) {
+ if (vop_dev->id == 0)
+ face = OUT_P101010; /*RGB 10bit output*/
+ else
+ face = OUT_P888;
+ }
val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
vop_msk_reg(vop_dev, SYS_CTRL, val);
+ val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
+ V_HDMI_VSYNC_POL(screen->pin_vsync) |
+ V_HDMI_DEN_POL(screen->pin_den) |
+ V_HDMI_DCLK_POL(screen->pin_dclk);
+ /*hsync vsync den dclk polo,dither */
+ vop_msk_reg(vop_dev, DSP_CTRL1, val);
break;
case SCREEN_RGB:
case SCREEN_LVDS:
val = V_RGB_OUT_EN(1);
vop_msk_reg(vop_dev, SYS_CTRL, val);
+ break;
case SCREEN_MIPI:
val = V_MIPI_OUT_EN(1);
vop_msk_reg(vop_dev, SYS_CTRL, val);
+ val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
+ V_MIPI_VSYNC_POL(screen->pin_vsync) |
+ V_MIPI_DEN_POL(screen->pin_den) |
+ V_MIPI_DCLK_POL(screen->pin_dclk);
+ /*hsync vsync den dclk polo,dither */
+ vop_msk_reg(vop_dev, DSP_CTRL1, val);
+ break;
+ case SCREEN_DUAL_MIPI:
+ val = V_MIPI_OUT_EN(1) | V_MIPI_DUAL_CHANNEL_EN(1);
+ vop_msk_reg(vop_dev, SYS_CTRL, val);
+ val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
+ V_MIPI_VSYNC_POL(screen->pin_vsync) |
+ V_MIPI_DEN_POL(screen->pin_den) |
+ V_MIPI_DCLK_POL(screen->pin_dclk);
+ /*hsync vsync den dclk polo,dither */
+ vop_msk_reg(vop_dev, DSP_CTRL1, val);
+ break;
case SCREEN_EDP:
+ if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
+ (vop_dev->id == 0))
+ face = OUT_P101010;
val = V_EDP_OUT_EN(1);
vop_msk_reg(vop_dev, SYS_CTRL, val);
+ val = V_EDP_HSYNC_POL(screen->pin_hsync) |
+ V_EDP_VSYNC_POL(screen->pin_vsync) |
+ V_EDP_DEN_POL(screen->pin_den) |
+ V_EDP_DCLK_POL(screen->pin_dclk);
+ /*hsync vsync den dclk polo,dither */
+ vop_msk_reg(vop_dev, DSP_CTRL1, val);
+ break;
+ case SCREEN_DP:
+ dclk_ddr = 0;
+ if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
+ ((screen->face == OUT_P888) ||
+ (screen->face == OUT_P101010))) {
+ if (vop_dev->id == 0)
+ face = OUT_P101010;
+ else
+ face = OUT_P888;
+ }
+ val = V_DP_OUT_EN(1);
+ vop_msk_reg(vop_dev, SYS_CTRL, val);
+ val = V_DP_HSYNC_POL(screen->pin_hsync) |
+ V_DP_VSYNC_POL(screen->pin_vsync) |
+ V_DP_DEN_POL(screen->pin_den) |
+ V_DP_DCLK_POL(screen->pin_dclk);
+ /*hsync vsync den dclk polo,dither */
+ vop_msk_reg(vop_dev, DSP_CTRL1, val);
break;
default:
dev_err(vop_dev->dev, "un supported interface[%d]!\n",
screen->type);
break;
}
- val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
- V_HDMI_VSYNC_POL(screen->pin_vsync) |
- V_HDMI_DEN_POL(screen->pin_den) |
- V_HDMI_DCLK_POL(screen->pin_dclk);
- /*hsync vsync den dclk polo,dither */
- vop_msk_reg(vop_dev, DSP_CTRL1, val);
if (screen->color_mode == COLOR_RGB)
dev_drv->overlay_mode = VOP_RGB_DOMAIN;
return 0;
}
+static int vop_early_suspend(struct rk_lcdc_driver *dev_drv);
+static int vop_early_resume(struct rk_lcdc_driver *dev_drv);
/*enable layer,open:1,enable;0 disable*/
static void vop_layer_enable(struct vop_device *vop_dev,
unsigned int win_id, bool open)
vop_dev->driver.win[win_id]);
vop_cfg_done(vop_dev);
}
- /* if no layer used,disable lcdc */
- if (!vop_dev->atv_layer_cnt) {
+ }
+ spin_unlock(&vop_dev->reg_lock);
+ /* if no layer used,disable lcdc */
+ if (vop_dev->prop == EXTEND) {
+ if (!vop_dev->atv_layer_cnt && !open) {
+ vop_early_suspend(&vop_dev->driver);
dev_info(vop_dev->dev,
"no layer is used,go to standby!\n");
vop_dev->standby = 1;
+ } else if (open) {
+ vop_early_resume(&vop_dev->driver);
+ dev_info(vop_dev->dev, "wake up from standby!\n");
}
}
- spin_unlock(&vop_dev->reg_lock);
+
}
static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
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;
+ val |= val << 16;
- vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val);
+ vop_msk_reg(vop_dev, INTR_EN0, val);
return 0;
}
static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen)
{
- u16 srcW;
- u16 srcH;
- u16 dstW;
- u16 dstH;
- u16 yrgb_srcW;
- u16 yrgb_srcH;
- u16 yrgb_dstW;
- u16 yrgb_dstH;
- u32 yrgb_vscalednmult;
- u32 yrgb_xscl_factor;
- u32 yrgb_yscl_factor;
+ u16 srcW = 0;
+ u16 srcH = 0;
+ u16 dstW = 0;
+ u16 dstH = 0;
+ u16 yrgb_srcW = 0;
+ u16 yrgb_srcH = 0;
+ u16 yrgb_dstW = 0;
+ u16 yrgb_dstH = 0;
+ u32 yrgb_vscalednmult = 0;
+ u32 yrgb_xscl_factor = 0;
+ u32 yrgb_yscl_factor = 0;
u8 yrgb_vsd_bil_gt2 = 0;
u8 yrgb_vsd_bil_gt4 = 0;
- u16 cbcr_srcW;
- u16 cbcr_srcH;
- u16 cbcr_dstW;
- u16 cbcr_dstH;
- u32 cbcr_vscalednmult;
- u32 cbcr_xscl_factor;
- u32 cbcr_yscl_factor;
+ u16 cbcr_srcW = 0;
+ u16 cbcr_srcH = 0;
+ u16 cbcr_dstW = 0;
+ u16 cbcr_dstH = 0;
+ u32 cbcr_vscalednmult = 0;
+ u32 cbcr_xscl_factor = 0;
+ u32 cbcr_yscl_factor = 0;
u8 cbcr_vsd_bil_gt2 = 0;
u8 cbcr_vsd_bil_gt4 = 0;
u8 yuv_fmt = 0;
static int win_0_1_set_par(struct vop_device *vop_dev,
struct rk_screen *screen, struct rk_lcdc_win *win)
{
- u32 xact, yact, xvir, yvir, xpos, ypos;
- u8 fmt_cfg = 0, swap_rb, swap_uv = 0;
+ u32 xact = 0, yact = 0, xvir = 0, yvir = 0, xpos = 0, ypos = 0;
+ u8 fmt_cfg = 0, swap_rb = 0, swap_uv = 0;
char fmt[9] = "NULL";
xpos = dsp_x_pos(win->xmirror, screen, &win->area[0]);
struct rk_screen *screen, struct rk_lcdc_win *win)
{
int i;
- u8 fmt_cfg, swap_rb;
+ u8 fmt_cfg = 0, swap_rb = 0;
char fmt[9] = "NULL";
if (VOP_CHIP(vop_dev) == VOP_RK322X) {
static int hwc_set_par(struct vop_device *vop_dev,
struct rk_screen *screen, struct rk_lcdc_win *win)
{
- u32 xact, yact, xvir, yvir, xpos, ypos;
- u8 fmt_cfg = 0, swap_rb;
+ u32 xact = 0, yact = 0, xvir = 0, yvir = 0, xpos = 0, ypos = 0;
+ u8 fmt_cfg = 0, swap_rb = 0;
char fmt[9] = "NULL";
xpos = win->area[0].xpos + screen->mode.left_margin +
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
struct rk_lcdc_win *win = NULL;
- int i, ovl;
+ int i, ovl = 0;
u64 val;
int z_order_num = 0;
- int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
+ int layer0_sel = 0, layer1_sel = 1, layer2_sel = 2, layer3_sel = 3;
if (swap == 0) {
for (i = 0; i < dev_drv->lcdc_win_num; i++) {
spin_unlock(&vop_dev->reg_lock);
size += snprintf(dsp_buf, 80,
"z-order:\n win[%d]\n win[%d]\n win[%d]\n win[%d]\n",
- layer1_sel, layer0_sel, layer2_sel, layer3_sel);
+ layer3_sel, layer2_sel, layer1_sel, layer0_sel);
strcat(buf, dsp_buf);
memset(dsp_buf, 0, sizeof(dsp_buf));
/* win0 */
vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
for (i = 0; i < dev_drv->lcdc_win_num; i++) {
win = dev_drv->win[i];
+ vop_alpha_cfg(dev_drv, i);
fbdc_en |= win->area[0].fbdc_en;
+ vop_dev->atv_layer_cnt &= ~(1 << win->id);
+ vop_dev->atv_layer_cnt |= (win->state << win->id);
if ((win->state == 0) && (win->last_state == 1)) {
switch (win->id) {
case 0:
if (enable)
enable_irq(vop_dev->irq);
else
- disable_irq(vop_dev->irq);
+ disable_irq_nosync(vop_dev->irq);
return 0;
}
{
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
- u32 val;
+ u32 val = 0;
spin_lock(&vop_dev->reg_lock);
if (vop_dev->clk_on) {
{
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
- u64 val;
+ u64 val = 0;
spin_lock(&vop_dev->reg_lock);
if (vop_dev->clk_on) {
{
struct vop_device *vop_dev =
container_of(dev_drv, struct vop_device, driver);
- u64 val;
+ u64 val = 0;
spin_lock(&vop_dev->reg_lock);
if (vop_dev->clk_on) {
platform_set_drvdata(pdev, vop_dev);
vop_dev->dev = dev;
vop_parse_dt(vop_dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ /* enable power domain */
+ pm_runtime_enable(dev);
+#endif
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
vop_dev->reg_phy_base = res->start;
vop_dev->len = resource_size(res);
- vop_dev->regs = devm_ioremap_resource(dev, res);
+ vop_dev->regs = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (IS_ERR(vop_dev->regs))
return PTR_ERR(vop_dev->regs);
vop_deint(vop_dev);
vop_clk_disable(vop_dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ pm_runtime_disable(vop_dev->dev);
+#endif
rk_disp_pwr_disable(dev_drv);
}