Revert "disp: msm: sde: remove all preclose logic"
This change reverts commit ae2dceb0b6
("disp: msm:
sde: remove all preclose logic"). This change also
modifies the force disable plane logic since
__drm_atomic_helper_disable_plane is not exposed to
drivers.
Change-Id: I89e19dead9ade724798952b1934b45b5663e1a42
Signed-off-by: Jayaprakash Madisetty <jmadiset@codeaurora.org>
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:

committed by
Samantha Tran

parent
6a01182c1e
commit
2df01bf3aa
@@ -967,6 +967,15 @@ static void context_close(struct msm_file_private *ctx)
|
|||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msm_preclose(struct drm_device *dev, struct drm_file *file)
|
||||||
|
{
|
||||||
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
|
struct msm_kms *kms = priv->kms;
|
||||||
|
|
||||||
|
if (kms && kms->funcs && kms->funcs->preclose)
|
||||||
|
kms->funcs->preclose(kms, file);
|
||||||
|
}
|
||||||
|
|
||||||
static void msm_postclose(struct drm_device *dev, struct drm_file *file)
|
static void msm_postclose(struct drm_device *dev, struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
@@ -1675,6 +1684,7 @@ static struct drm_driver msm_driver = {
|
|||||||
DRIVER_ATOMIC |
|
DRIVER_ATOMIC |
|
||||||
DRIVER_MODESET,
|
DRIVER_MODESET,
|
||||||
.open = msm_open,
|
.open = msm_open,
|
||||||
|
.preclose = msm_preclose,
|
||||||
.postclose = msm_postclose,
|
.postclose = msm_postclose,
|
||||||
.lastclose = msm_lastclose,
|
.lastclose = msm_lastclose,
|
||||||
.irq_handler = msm_irq,
|
.irq_handler = msm_irq,
|
||||||
|
@@ -97,6 +97,7 @@ struct msm_kms_funcs {
|
|||||||
struct drm_encoder *slave_encoder,
|
struct drm_encoder *slave_encoder,
|
||||||
bool is_cmd_mode);
|
bool is_cmd_mode);
|
||||||
void (*postopen)(struct msm_kms *kms, struct drm_file *file);
|
void (*postopen)(struct msm_kms *kms, struct drm_file *file);
|
||||||
|
void (*preclose)(struct msm_kms *kms, struct drm_file *file);
|
||||||
void (*postclose)(struct msm_kms *kms, struct drm_file *file);
|
void (*postclose)(struct msm_kms *kms, struct drm_file *file);
|
||||||
void (*lastclose)(struct msm_kms *kms);
|
void (*lastclose)(struct msm_kms *kms);
|
||||||
int (*register_events)(struct msm_kms *kms,
|
int (*register_events)(struct msm_kms *kms,
|
||||||
|
@@ -2396,6 +2396,143 @@ static void sde_kms_destroy(struct msm_kms *kms)
|
|||||||
kfree(sde_kms);
|
kfree(sde_kms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _sde_kms_plane_force_remove(struct drm_plane *plane,
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
struct drm_plane_state *plane_state;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
||||||
|
if (IS_ERR(plane_state)) {
|
||||||
|
ret = PTR_ERR(plane_state);
|
||||||
|
SDE_ERROR("error %d getting plane %d state\n",
|
||||||
|
ret, plane->base.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
plane->old_fb = plane->fb;
|
||||||
|
|
||||||
|
SDE_DEBUG("disabling plane %d\n", plane->base.id);
|
||||||
|
|
||||||
|
ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
SDE_ERROR("error %d disabling plane %d\n", ret,
|
||||||
|
plane->base.id);
|
||||||
|
|
||||||
|
drm_atomic_set_fb_for_plane(plane_state, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file,
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = sde_kms->dev;
|
||||||
|
struct drm_framebuffer *fb, *tfb;
|
||||||
|
struct list_head fbs;
|
||||||
|
struct drm_plane *plane;
|
||||||
|
int ret = 0;
|
||||||
|
u32 plane_mask = 0;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&fbs);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(fb, tfb, &file->fbs, filp_head) {
|
||||||
|
if (drm_framebuffer_read_refcount(fb) > 1) {
|
||||||
|
list_move_tail(&fb->filp_head, &fbs);
|
||||||
|
|
||||||
|
drm_for_each_plane(plane, dev) {
|
||||||
|
if (plane->fb == fb) {
|
||||||
|
plane_mask |=
|
||||||
|
1 << drm_plane_index(plane);
|
||||||
|
_sde_kms_plane_force_remove(
|
||||||
|
plane, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list_del_init(&fb->filp_head);
|
||||||
|
drm_framebuffer_put(fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_empty(&fbs)) {
|
||||||
|
SDE_DEBUG("skip commit as no fb(s)\n");
|
||||||
|
drm_atomic_state_put(state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDE_DEBUG("committing after removing all the pipes\n");
|
||||||
|
ret = drm_atomic_commit(state);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
/*
|
||||||
|
* move the fbs back to original list, so it would be
|
||||||
|
* handled during drm_release
|
||||||
|
*/
|
||||||
|
list_for_each_entry_safe(fb, tfb, &fbs, filp_head)
|
||||||
|
list_move_tail(&fb->filp_head, &file->fbs);
|
||||||
|
|
||||||
|
SDE_ERROR("atomic commit failed in preclose, ret:%d\n", ret);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!list_empty(&fbs)) {
|
||||||
|
fb = list_first_entry(&fbs, typeof(*fb), filp_head);
|
||||||
|
|
||||||
|
list_del_init(&fb->filp_head);
|
||||||
|
drm_framebuffer_put(fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sde_kms_preclose(struct msm_kms *kms, struct drm_file *file)
|
||||||
|
{
|
||||||
|
struct sde_kms *sde_kms = to_sde_kms(kms);
|
||||||
|
struct drm_device *dev = sde_kms->dev;
|
||||||
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
|
unsigned int i;
|
||||||
|
struct drm_atomic_state *state = NULL;
|
||||||
|
struct drm_modeset_acquire_ctx ctx;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* cancel pending flip event */
|
||||||
|
for (i = 0; i < priv->num_crtcs; i++)
|
||||||
|
sde_crtc_complete_flip(priv->crtcs[i], file);
|
||||||
|
|
||||||
|
drm_modeset_acquire_init(&ctx, 0);
|
||||||
|
retry:
|
||||||
|
ret = drm_modeset_lock_all_ctx(dev, &ctx);
|
||||||
|
if (ret == -EDEADLK) {
|
||||||
|
drm_modeset_backoff(&ctx);
|
||||||
|
goto retry;
|
||||||
|
} else if (WARN_ON(ret)) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = drm_atomic_state_alloc(dev);
|
||||||
|
if (!state) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->acquire_ctx = &ctx;
|
||||||
|
|
||||||
|
for (i = 0; i < TEARDOWN_DEADLOCK_RETRY_MAX; i++) {
|
||||||
|
ret = _sde_kms_remove_fbs(sde_kms, file, state);
|
||||||
|
if (ret != -EDEADLK)
|
||||||
|
break;
|
||||||
|
drm_atomic_state_clear(state);
|
||||||
|
drm_modeset_backoff(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (state)
|
||||||
|
drm_atomic_state_put(state);
|
||||||
|
|
||||||
|
SDE_DEBUG("sde preclose done, ret:%d\n", ret);
|
||||||
|
drm_modeset_drop_locks(&ctx);
|
||||||
|
drm_modeset_acquire_fini(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static int _sde_kms_helper_reset_custom_properties(struct sde_kms *sde_kms,
|
static int _sde_kms_helper_reset_custom_properties(struct sde_kms *sde_kms,
|
||||||
struct drm_atomic_state *state)
|
struct drm_atomic_state *state)
|
||||||
{
|
{
|
||||||
@@ -3818,6 +3955,7 @@ static const struct msm_kms_funcs kms_funcs = {
|
|||||||
.irq_postinstall = sde_irq_postinstall,
|
.irq_postinstall = sde_irq_postinstall,
|
||||||
.irq_uninstall = sde_irq_uninstall,
|
.irq_uninstall = sde_irq_uninstall,
|
||||||
.irq = sde_irq,
|
.irq = sde_irq,
|
||||||
|
.preclose = sde_kms_preclose,
|
||||||
.lastclose = sde_kms_lastclose,
|
.lastclose = sde_kms_lastclose,
|
||||||
.prepare_fence = sde_kms_prepare_fence,
|
.prepare_fence = sde_kms_prepare_fence,
|
||||||
.prepare_commit = sde_kms_prepare_commit,
|
.prepare_commit = sde_kms_prepare_commit,
|
||||||
|
Reference in New Issue
Block a user