|
@@ -2655,6 +2655,11 @@ error:
|
|
drm_framebuffer_put(fb);
|
|
drm_framebuffer_put(fb);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ drm_for_each_crtc(crtc, dev) {
|
|
|
|
+ if (!ret && crtc_mask & drm_crtc_mask(crtc))
|
|
|
|
+ sde_kms_cancel_delayed_work(crtc);
|
|
|
|
+ }
|
|
|
|
+
|
|
end:
|
|
end:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -3881,6 +3886,7 @@ static int sde_kms_trigger_null_flush(struct msm_kms *kms)
|
|
{
|
|
{
|
|
struct sde_kms *sde_kms;
|
|
struct sde_kms *sde_kms;
|
|
struct sde_splash_display *splash_display;
|
|
struct sde_splash_display *splash_display;
|
|
|
|
+ struct drm_crtc *crtc;
|
|
int i, rc = 0;
|
|
int i, rc = 0;
|
|
|
|
|
|
if (!kms) {
|
|
if (!kms) {
|
|
@@ -3890,28 +3896,42 @@ static int sde_kms_trigger_null_flush(struct msm_kms *kms)
|
|
|
|
|
|
sde_kms = to_sde_kms(kms);
|
|
sde_kms = to_sde_kms(kms);
|
|
|
|
|
|
- if (!sde_kms->splash_data.num_splash_displays ||
|
|
|
|
- sde_kms->dsi_display_count == sde_kms->splash_data.num_splash_displays)
|
|
|
|
- return rc;
|
|
|
|
|
|
+ /* If splash handoff is done, early return*/
|
|
|
|
+ if (!sde_kms->splash_data.num_splash_displays)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* If all builtin-displays are having cont splash enabled, ignore lastclose*/
|
|
|
|
+ if (sde_kms->dsi_display_count == sde_kms->splash_data.num_splash_displays)
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Trigger NULL flush if built-in secondary/primary is stuck in splash
|
|
|
|
+ * while the primary/secondary is running respectively before lastclose.
|
|
|
|
+ */
|
|
for (i = 0; i < MAX_DSI_DISPLAYS; i++) {
|
|
for (i = 0; i < MAX_DSI_DISPLAYS; i++) {
|
|
splash_display = &sde_kms->splash_data.splash_display[i];
|
|
splash_display = &sde_kms->splash_data.splash_display[i];
|
|
|
|
|
|
if (splash_display->cont_splash_enabled && splash_display->encoder) {
|
|
if (splash_display->cont_splash_enabled && splash_display->encoder) {
|
|
|
|
+ crtc = splash_display->encoder->crtc;
|
|
SDE_DEBUG("triggering null commit on enc:%d\n",
|
|
SDE_DEBUG("triggering null commit on enc:%d\n",
|
|
DRMID(splash_display->encoder));
|
|
DRMID(splash_display->encoder));
|
|
SDE_EVT32(DRMID(splash_display->encoder), SDE_EVTLOG_FUNC_ENTRY);
|
|
SDE_EVT32(DRMID(splash_display->encoder), SDE_EVTLOG_FUNC_ENTRY);
|
|
rc = _sde_kms_null_commit(sde_kms->dev, splash_display->encoder);
|
|
rc = _sde_kms_null_commit(sde_kms->dev, splash_display->encoder);
|
|
|
|
+
|
|
|
|
+ if (!rc && crtc)
|
|
|
|
+ sde_kms_cancel_delayed_work(crtc);
|
|
|
|
+ if (rc)
|
|
|
|
+ DRM_ERROR("null flush commit failure during lastclose\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return rc;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
|
static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
|
struct device *dev)
|
|
struct device *dev)
|
|
{
|
|
{
|
|
- int i, ret, crtc_id = 0;
|
|
|
|
|
|
+ int ret, crtc_id = 0;
|
|
struct drm_device *ddev = dev_get_drvdata(dev);
|
|
struct drm_device *ddev = dev_get_drvdata(dev);
|
|
struct drm_connector *conn;
|
|
struct drm_connector *conn;
|
|
struct drm_connector_list_iter conn_iter;
|
|
struct drm_connector_list_iter conn_iter;
|
|
@@ -3948,15 +3968,7 @@ static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
|
|
}
|
|
}
|
|
drm_connector_list_iter_end(&conn_iter);
|
|
drm_connector_list_iter_end(&conn_iter);
|
|
|
|
|
|
- for (i = 0; i < priv->num_crtcs; i++) {
|
|
|
|
- if (priv->disp_thread[i].thread)
|
|
|
|
- kthread_flush_worker(
|
|
|
|
- &priv->disp_thread[i].worker);
|
|
|
|
- if (priv->event_thread[i].thread)
|
|
|
|
- kthread_flush_worker(
|
|
|
|
- &priv->event_thread[i].worker);
|
|
|
|
- }
|
|
|
|
- kthread_flush_worker(&priv->pp_event_worker);
|
|
|
|
|
|
+ msm_atomic_flush_display_threads(priv);
|
|
}
|
|
}
|
|
|
|
|
|
struct msm_display_mode *sde_kms_get_msm_mode(struct drm_connector_state *conn_state)
|
|
struct msm_display_mode *sde_kms_get_msm_mode(struct drm_connector_state *conn_state)
|