X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Frockchip%2Frockchip_drm_vop.c;h=5d450332c2fd79fd8c1052aca84d7d15c5db3ef8;hb=c9dc281d91aed57251e94c7cca81a5c8777e3e4a;hp=45589d6ce65ed0fd0a7e1be60f83dd03bd3d47b5;hpb=ef3ad0898a60d30da7f170032992914998c366e5;p=karo-tx-linux.git diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 45589d6ce65e..2900f1410d95 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop) return !!line_flag_irq; } -static void vop_line_flag_irq_enable(struct vop *vop, int line_num) +static void vop_line_flag_irq_enable(struct vop *vop) { unsigned long flags; @@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int line_num) spin_lock_irqsave(&vop->irq_lock, flags); - VOP_CTRL_SET(vop, line_flag_num[0], line_num); VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1); VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); @@ -501,7 +500,7 @@ static void vop_line_flag_irq_disable(struct vop *vop) static int vop_enable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); - int ret; + int ret, i; ret = pm_runtime_get_sync(vop->dev); if (ret < 0) { @@ -534,6 +533,20 @@ static int vop_enable(struct drm_crtc *crtc) } memcpy(vop->regs, vop->regsbak, vop->len); + /* + * We need to make sure that all windows are disabled before we + * enable the crtc. Otherwise we might try to scan from a destroyed + * buffer later. + */ + for (i = 0; i < vop->data->win_size; i++) { + struct vop_win *vop_win = &vop->win[i]; + const struct vop_win_data *win = vop_win->data; + + spin_lock(&vop->reg_lock); + VOP_WIN_SET(vop, win, enable, 0); + spin_unlock(&vop->reg_lock); + } + vop_cfg_done(vop); /* @@ -567,28 +580,11 @@ err_put_pm_runtime: static void vop_crtc_disable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); - int i; WARN_ON(vop->event); rockchip_drm_psr_deactivate(&vop->crtc); - /* - * We need to make sure that all windows are disabled before we - * disable that crtc. Otherwise we might try to scan from a destroyed - * buffer later. - */ - for (i = 0; i < vop->data->win_size; i++) { - struct vop_win *vop_win = &vop->win[i]; - const struct vop_win_data *win = vop_win->data; - - spin_lock(&vop->reg_lock); - VOP_WIN_SET(vop, win, enable, 0); - spin_unlock(&vop->reg_lock); - } - - vop_cfg_done(vop); - drm_crtc_vblank_off(crtc); /* @@ -683,8 +679,10 @@ static int vop_plane_atomic_check(struct drm_plane *plane, * Src.x1 can be odd when do clip, but yuv plane start point * need align with 2 pixel. */ - if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2)) + if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2)) { + DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n"); return -EINVAL; + } return 0; } @@ -765,7 +763,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, spin_lock(&vop->reg_lock); VOP_WIN_SET(vop, win, format, format); - VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2); + VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); if (is_yuv_support(fb->format->format)) { int hsub = drm_format_horz_chroma_subsampling(fb->format->format); @@ -779,7 +777,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, offset += (src->y1 >> 16) * fb->pitches[1] / vsub; dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; - VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2); + VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); VOP_WIN_SET(vop, win, uv_mst, dma_addr); } @@ -989,6 +987,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc) VOP_CTRL_SET(vop, vact_st_end, val); VOP_CTRL_SET(vop, vpost_st_end, val); + VOP_CTRL_SET(vop, line_flag_num[0], vact_end); + clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); VOP_CTRL_SET(vop, standby, 0); @@ -1125,16 +1125,17 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc, #ifdef CONFIG_DRM_ANALOGIX_DP static struct drm_connector *vop_get_edp_connector(struct vop *vop) { - struct drm_crtc *crtc = &vop->crtc; struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; - mutex_lock(&crtc->dev->mode_config.mutex); - drm_for_each_connector(connector, crtc->dev) + drm_connector_list_iter_begin(vop->drm_dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - mutex_unlock(&crtc->dev->mode_config.mutex); + drm_connector_list_iter_end(&conn_iter); return connector; } - mutex_unlock(&crtc->dev->mode_config.mutex); + } + drm_connector_list_iter_end(&conn_iter); return NULL; } @@ -1515,19 +1516,16 @@ static void vop_win_init(struct vop *vop) } /** - * rockchip_drm_wait_line_flag - acqiure the give line flag event + * rockchip_drm_wait_vact_end * @crtc: CRTC to enable line flag - * @line_num: interested line number * @mstimeout: millisecond for timeout * - * Driver would hold here until the interested line flag interrupt have - * happened or timeout to wait. + * Wait for vact_end line flag irq or timeout. * * Returns: * Zero on success, negative errno on failure. */ -int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, - unsigned int mstimeout) +int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout) { struct vop *vop = to_vop(crtc); unsigned long jiffies_left; @@ -1535,14 +1533,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, if (!crtc || !vop->is_enabled) return -ENODEV; - if (line_num > crtc->mode.vtotal || mstimeout <= 0) + if (mstimeout <= 0) return -EINVAL; if (vop_line_flag_irq_is_enabled(vop)) return -EBUSY; reinit_completion(&vop->line_flag_completion); - vop_line_flag_irq_enable(vop, line_num); + vop_line_flag_irq_enable(vop); jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion, msecs_to_jiffies(mstimeout)); @@ -1555,7 +1553,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, return 0; } -EXPORT_SYMBOL(rockchip_drm_wait_line_flag); +EXPORT_SYMBOL(rockchip_drm_wait_vact_end); static int vop_bind(struct device *dev, struct device *master, void *data) {