drm/msm/sde: disable vblank ref power on crtc disable
Update vblank reference counts via the exposed sde_crtc_vblank function, rather than attempting to zero it on the side during CRTC disable operations. This allows the power voting to be updated correctly based on the vblank reference count value. CRs-Fixed: 2037677 Change-Id: I7026a1b239503a2b1d97ad7bb61fbc0a4a38d7ea Signed-off-by: Clarence Ip <cip@codeaurora.org>
This commit is contained in:
parent
e67107812d
commit
7477f5db6e
1 changed files with 34 additions and 27 deletions
|
@ -1133,6 +1133,33 @@ static void sde_crtc_reset(struct drm_crtc *crtc)
|
|||
crtc->state = &cstate->base;
|
||||
}
|
||||
|
||||
static int _sde_crtc_vblank_no_lock(struct sde_crtc *sde_crtc, bool en)
|
||||
{
|
||||
if (!sde_crtc) {
|
||||
SDE_ERROR("invalid crtc\n");
|
||||
return -EINVAL;
|
||||
} else if (en && atomic_inc_return(&sde_crtc->vblank_refcount) == 1) {
|
||||
SDE_DEBUG("crtc%d vblank enable\n", sde_crtc->base.base.id);
|
||||
if (!sde_crtc->suspend)
|
||||
_sde_crtc_vblank_enable_nolock(sde_crtc, true);
|
||||
} else if (!en && atomic_read(&sde_crtc->vblank_refcount) < 1) {
|
||||
SDE_ERROR("crtc%d invalid vblank disable\n",
|
||||
sde_crtc->base.base.id);
|
||||
return -EINVAL;
|
||||
} else if (!en && atomic_dec_return(&sde_crtc->vblank_refcount) == 0) {
|
||||
SDE_DEBUG("crtc%d vblank disable\n", sde_crtc->base.base.id);
|
||||
if (!sde_crtc->suspend)
|
||||
_sde_crtc_vblank_enable_nolock(sde_crtc, false);
|
||||
} else {
|
||||
SDE_DEBUG("crtc%d vblank %s refcount:%d\n",
|
||||
sde_crtc->base.base.id,
|
||||
en ? "enable" : "disable",
|
||||
atomic_read(&sde_crtc->vblank_refcount));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sde_crtc_disable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
|
@ -1163,14 +1190,10 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
|
|||
if (atomic_read(&sde_crtc->vblank_refcount) && !sde_crtc->suspend) {
|
||||
SDE_ERROR("crtc%d invalid vblank refcount\n",
|
||||
crtc->base.id);
|
||||
SDE_EVT32(DRMID(crtc));
|
||||
drm_for_each_encoder(encoder, crtc->dev) {
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
sde_encoder_register_vblank_callback(encoder, NULL,
|
||||
NULL);
|
||||
}
|
||||
atomic_set(&sde_crtc->vblank_refcount, 0);
|
||||
SDE_EVT32(DRMID(crtc), atomic_read(&sde_crtc->vblank_refcount));
|
||||
while (atomic_read(&sde_crtc->vblank_refcount))
|
||||
if (_sde_crtc_vblank_no_lock(sde_crtc, false))
|
||||
break;
|
||||
}
|
||||
|
||||
if (atomic_read(&sde_crtc->frame_pending)) {
|
||||
|
@ -1390,7 +1413,7 @@ end:
|
|||
int sde_crtc_vblank(struct drm_crtc *crtc, bool en)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
if (!crtc) {
|
||||
SDE_ERROR("invalid crtc\n");
|
||||
|
@ -1399,25 +1422,9 @@ int sde_crtc_vblank(struct drm_crtc *crtc, bool en)
|
|||
sde_crtc = to_sde_crtc(crtc);
|
||||
|
||||
mutex_lock(&sde_crtc->crtc_lock);
|
||||
if (en && atomic_inc_return(&sde_crtc->vblank_refcount) == 1) {
|
||||
SDE_DEBUG("crtc%d vblank enable\n", crtc->base.id);
|
||||
if (!sde_crtc->suspend)
|
||||
_sde_crtc_vblank_enable_nolock(sde_crtc, true);
|
||||
} else if (!en && atomic_read(&sde_crtc->vblank_refcount) < 1) {
|
||||
SDE_ERROR("crtc%d invalid vblank disable\n", crtc->base.id);
|
||||
rc = -EINVAL;
|
||||
} else if (!en && atomic_dec_return(&sde_crtc->vblank_refcount) == 0) {
|
||||
SDE_DEBUG("crtc%d vblank disable\n", crtc->base.id);
|
||||
if (!sde_crtc->suspend)
|
||||
_sde_crtc_vblank_enable_nolock(sde_crtc, false);
|
||||
} else {
|
||||
SDE_DEBUG("crtc%d vblank %s refcount:%d\n",
|
||||
crtc->base.id,
|
||||
en ? "enable" : "disable",
|
||||
atomic_read(&sde_crtc->vblank_refcount));
|
||||
}
|
||||
|
||||
rc = _sde_crtc_vblank_no_lock(sde_crtc, en);
|
||||
mutex_unlock(&sde_crtc->crtc_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue