提交 e334d48b 编写于 作者: Z zain wang 提交者: Heiko Stuebner

drm/rockchip: add mutex vop lock

Add a lock to vop to avoid disabling the crtc while waiting for a line
flag while enabling psr. If we disable in the middle of waiting for the
line flag, we'll end up timing out or worse.
Signed-off-by: Nzain wang <wzz@rock-chips.com>
Signed-off-by: NSean Paul <seanpaul@chromium.org>
Signed-off-by: NThierry Escande <thierry.escande@collabora.com>
Signed-off-by: NEnric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: NHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180309222327.18689-5-enric.balletbo@collabora.com
上级 f9d56805
...@@ -117,6 +117,8 @@ struct vop { ...@@ -117,6 +117,8 @@ struct vop {
spinlock_t reg_lock; spinlock_t reg_lock;
/* lock vop irq reg */ /* lock vop irq reg */
spinlock_t irq_lock; spinlock_t irq_lock;
/* protects crtc enable/disable */
struct mutex vop_lock;
unsigned int irq; unsigned int irq;
...@@ -569,6 +571,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -569,6 +571,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
WARN_ON(vop->event); WARN_ON(vop->event);
mutex_lock(&vop->vop_lock);
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
/* /*
...@@ -604,6 +607,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -604,6 +607,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable(vop->aclk); clk_disable(vop->aclk);
clk_disable(vop->hclk); clk_disable(vop->hclk);
pm_runtime_put(vop->dev); pm_runtime_put(vop->dev);
mutex_unlock(&vop->vop_lock);
if (crtc->state->event && !crtc->state->active) { if (crtc->state->event && !crtc->state->active) {
spin_lock_irq(&crtc->dev->event_lock); spin_lock_irq(&crtc->dev->event_lock);
...@@ -868,10 +872,13 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -868,10 +872,13 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
uint32_t pin_pol, val; uint32_t pin_pol, val;
int ret; int ret;
mutex_lock(&vop->vop_lock);
WARN_ON(vop->event); WARN_ON(vop->event);
ret = vop_enable(crtc); ret = vop_enable(crtc);
if (ret) { if (ret) {
mutex_unlock(&vop->vop_lock);
DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret); DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
return; return;
} }
...@@ -935,6 +942,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -935,6 +942,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
VOP_REG_SET(vop, common, standby, 0); VOP_REG_SET(vop, common, standby, 0);
mutex_unlock(&vop->vop_lock);
} }
static bool vop_fs_irq_is_pending(struct vop *vop) static bool vop_fs_irq_is_pending(struct vop *vop)
...@@ -1473,15 +1481,21 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout) ...@@ -1473,15 +1481,21 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
{ {
struct vop *vop = to_vop(crtc); struct vop *vop = to_vop(crtc);
unsigned long jiffies_left; unsigned long jiffies_left;
int ret = 0;
if (!crtc || !vop->is_enabled) if (!crtc || !vop->is_enabled)
return -ENODEV; return -ENODEV;
if (mstimeout <= 0) mutex_lock(&vop->vop_lock);
return -EINVAL; if (mstimeout <= 0) {
ret = -EINVAL;
goto out;
}
if (vop_line_flag_irq_is_enabled(vop)) if (vop_line_flag_irq_is_enabled(vop)) {
return -EBUSY; ret = -EBUSY;
goto out;
}
reinit_completion(&vop->line_flag_completion); reinit_completion(&vop->line_flag_completion);
vop_line_flag_irq_enable(vop); vop_line_flag_irq_enable(vop);
...@@ -1492,10 +1506,13 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout) ...@@ -1492,10 +1506,13 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
if (jiffies_left == 0) { if (jiffies_left == 0) {
DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n"); DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
return -ETIMEDOUT; ret = -ETIMEDOUT;
goto out;
} }
return 0; out:
mutex_unlock(&vop->vop_lock);
return ret;
} }
EXPORT_SYMBOL(rockchip_drm_wait_vact_end); EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
...@@ -1545,6 +1562,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) ...@@ -1545,6 +1562,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
spin_lock_init(&vop->reg_lock); spin_lock_init(&vop->reg_lock);
spin_lock_init(&vop->irq_lock); spin_lock_init(&vop->irq_lock);
mutex_init(&vop->vop_lock);
ret = devm_request_irq(dev, vop->irq, vop_isr, ret = devm_request_irq(dev, vop->irq, vop_isr,
IRQF_SHARED, dev_name(dev), vop); IRQF_SHARED, dev_name(dev), vop);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册