Loading drivers/gpu/drm/msm/sde/sde_connector.c +11 −4 Original line number Diff line number Diff line Loading @@ -572,6 +572,7 @@ void sde_connector_complete_commit(struct drm_connector *connector) { struct drm_device *dev; struct msm_drm_private *priv; struct sde_connector *c_conn; if (!connector) { SDE_ERROR("invalid connector\n"); Loading @@ -584,11 +585,17 @@ void sde_connector_complete_commit(struct drm_connector *connector) /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0); /* after first vsync comes, * early splash resource should start to be released. /* * After LK totally exits, LK's early splash resource * should be released. */ if (sde_splash_get_lk_complete_status(priv->kms)) sde_splash_free_resource(priv->kms, &priv->phandle); if (sde_splash_get_lk_complete_status(priv->kms)) { c_conn = to_sde_connector(connector); sde_splash_free_resource(priv->kms, &priv->phandle, c_conn->connector_type, c_conn->display); } } Loading drivers/gpu/drm/msm/sde/sde_kms.c +4 −4 Original line number Diff line number Diff line Loading @@ -345,8 +345,8 @@ static void sde_kms_prepare_commit(struct msm_kms *kms, if (sde_kms->splash_info.handoff && sde_kms->splash_info.display_splash_enabled) sde_splash_lk_stop_splash(kms); else sde_splash_lk_stop_splash(kms, state); sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); } Loading drivers/gpu/drm/msm/sde/sde_splash.c +110 −24 Original line number Diff line number Diff line Loading @@ -313,6 +313,15 @@ static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms) kfree(event_string); } static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo, u32 *hdmi_cnt, u32 *dsi_cnt) { mutex_lock(&sde_splash_lock); *hdmi_cnt = sinfo->hdmi_connector_cnt; *dsi_cnt = sinfo->dsi_connector_cnt; mutex_unlock(&sde_splash_lock); } static int _sde_splash_free_module_resource(struct msm_mmu *mmu, struct sde_splash_info *sinfo) { Loading @@ -339,6 +348,29 @@ static int _sde_splash_free_module_resource(struct msm_mmu *mmu, return 0; } static bool _sde_splash_validate_commit(struct sde_kms *sde_kms, struct drm_atomic_state *state) { int i, nplanes; struct drm_plane *plane; struct drm_device *dev = sde_kms->dev; nplanes = dev->mode_config.num_total_plane; for (i = 0; i < nplanes; i++) { plane = state->planes[i]; /* * As plane state has been swapped, we need to check * fb in state->planes, not fb in state->plane_state. */ if (plane && plane->fb) return true; } return false; } __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms) { struct sde_kms *sde_kms; Loading Loading @@ -369,8 +401,7 @@ __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms) sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); ret = -EINVAL; break; return -EINVAL; } } Loading Loading @@ -716,11 +747,17 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms) } int sde_splash_free_resource(struct msm_kms *kms, struct sde_power_handle *phandle) struct sde_power_handle *phandle, int connector_type, void *display) { struct sde_kms *sde_kms; struct sde_splash_info *sinfo; struct msm_mmu *mmu; struct dsi_display *dsi_display = display; int ret = 0; int hdmi_conn_count = 0; int dsi_conn_count = 0; static const char *last_commit_display_type = "unknown"; if (!phandle || !kms) { SDE_ERROR("invalid phandle/kms.\n"); Loading @@ -734,12 +771,21 @@ int sde_splash_free_resource(struct msm_kms *kms, return -EINVAL; } /* Get connector number where the early splash in on. */ _sde_splash_get_connector_ref_cnt(sinfo, &hdmi_conn_count, &dsi_conn_count); mutex_lock(&sde_splash_lock); if (!sinfo->handoff) { mutex_unlock(&sde_splash_lock); return 0; } /* * Start to free all LK's resource till user commit happens * on each display which early splash is enabled on. */ if (hdmi_conn_count == 0 && dsi_conn_count == 0) { mmu = sde_kms->aspace[0]->mmu; if (!mmu) { mutex_unlock(&sde_splash_lock); Loading @@ -759,24 +805,63 @@ int sde_splash_free_resource(struct msm_kms *kms, sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); /* * Turn off MDP core power to keep power on/off operations * be matched, as MDP core power is enabled already when * early splash is enabled. */ sde_power_resource_enable(phandle, sde_kms->core_client, false); /* send uevent to notify user to recycle resource */ _sde_splash_sent_pipe_update_uevent(sde_kms); /* Finally mark handoff flag to false to say handoff is complete */ /* Finally mark handoff flag to false to say * handoff is complete. */ sinfo->handoff = false; DRM_INFO("HDMI and DSI resource handoff is completed\n"); mutex_unlock(&sde_splash_lock); return 0; } /* * Ensure user commit happens on different connectors * who has splash. */ switch (connector_type) { case DRM_MODE_CONNECTOR_HDMIA: if (sinfo->hdmi_connector_cnt == 1) sinfo->hdmi_connector_cnt--; break; case DRM_MODE_CONNECTOR_DSI: if (strcmp(dsi_display->display_type, "unknown") && strcmp(last_commit_display_type, dsi_display->display_type)) { if (sinfo->dsi_connector_cnt >= 1) sinfo->dsi_connector_cnt--; last_commit_display_type = dsi_display->display_type; } break; default: ret = -EINVAL; SDE_ERROR("%s: invalid connector_type %d\n", __func__, connector_type); } mutex_unlock(&sde_splash_lock); return ret; } /* * In below function, it will * 1. Notify LK to stop display splash. * 2. Set DOMAIN_ATTR_EARLY_MAP to 1 to enable stage 1 translation in iommu. */ int sde_splash_lk_stop_splash(struct msm_kms *kms) int sde_splash_lk_stop_splash(struct msm_kms *kms, struct drm_atomic_state *state) { struct sde_splash_info *sinfo; struct msm_mmu *mmu; Loading @@ -792,7 +877,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms) /* Monitor LK's status and tell it to exit. */ mutex_lock(&sde_splash_lock); if (sinfo->display_splash_enabled) { if (_sde_splash_validate_commit(sde_kms, state) && sinfo->display_splash_enabled) { if (_sde_splash_lk_check(sde_kms->hw_intr)) _sde_splash_notify_lk_stop_splash(sde_kms->hw_intr); Loading drivers/gpu/drm/msm/sde/sde_splash.h +12 −12 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ #include "msm_mmu.h" #include "sde_hw_mdss.h" #define SPLASH_CTL_MAX 5 #define SPLASH_LM_MAX 7 enum splash_connector_type { SPLASH_DSI = 0, SPLASH_HDMI, Loading @@ -35,13 +32,13 @@ struct splash_ctl_top { u32 value; u8 intf_sel; u8 ctl_lm_cnt; struct splash_lm_hw lm[SPLASH_LM_MAX]; struct splash_lm_hw lm[LM_MAX - LM_0]; }; struct sde_res_data { struct splash_ctl_top top[SPLASH_CTL_MAX]; u8 ctl_ids[SPLASH_CTL_MAX]; u8 lm_ids[SPLASH_LM_MAX]; struct splash_ctl_top top[CTL_MAX - CTL_0]; u8 ctl_ids[CTL_MAX - CTL_0]; u8 lm_ids[LM_MAX - LM_0]; u8 ctl_top_cnt; u8 lm_cnt; }; Loading Loading @@ -121,18 +118,21 @@ void sde_splash_setup_connector_count(struct sde_splash_info *sinfo, /** * sde_splash_lk_stop_splash. * * Tell LK to stop display splash. * Tell LK to stop display splash once one valid user commit arrives. */ int sde_splash_lk_stop_splash(struct msm_kms *kms); int sde_splash_lk_stop_splash(struct msm_kms *kms, struct drm_atomic_state *state); /** * sde_splash_free_resource. * * According to input connector_type, free * HDMI's and DSI's resource respectively. * To free all LK's resource, including free reserved memory to system, * withdraw data bus vote, disable MDP core power, send uevent to user * to recycle pipe etc. */ int sde_splash_free_resource(struct msm_kms *kms, struct sde_power_handle *phandle); struct sde_power_handle *phandle, int connector_type, void *display); /** * sde_splash_parse_memory_dt. Loading Loading
drivers/gpu/drm/msm/sde/sde_connector.c +11 −4 Original line number Diff line number Diff line Loading @@ -572,6 +572,7 @@ void sde_connector_complete_commit(struct drm_connector *connector) { struct drm_device *dev; struct msm_drm_private *priv; struct sde_connector *c_conn; if (!connector) { SDE_ERROR("invalid connector\n"); Loading @@ -584,11 +585,17 @@ void sde_connector_complete_commit(struct drm_connector *connector) /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0); /* after first vsync comes, * early splash resource should start to be released. /* * After LK totally exits, LK's early splash resource * should be released. */ if (sde_splash_get_lk_complete_status(priv->kms)) sde_splash_free_resource(priv->kms, &priv->phandle); if (sde_splash_get_lk_complete_status(priv->kms)) { c_conn = to_sde_connector(connector); sde_splash_free_resource(priv->kms, &priv->phandle, c_conn->connector_type, c_conn->display); } } Loading
drivers/gpu/drm/msm/sde/sde_kms.c +4 −4 Original line number Diff line number Diff line Loading @@ -345,8 +345,8 @@ static void sde_kms_prepare_commit(struct msm_kms *kms, if (sde_kms->splash_info.handoff && sde_kms->splash_info.display_splash_enabled) sde_splash_lk_stop_splash(kms); else sde_splash_lk_stop_splash(kms, state); sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); } Loading
drivers/gpu/drm/msm/sde/sde_splash.c +110 −24 Original line number Diff line number Diff line Loading @@ -313,6 +313,15 @@ static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms) kfree(event_string); } static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo, u32 *hdmi_cnt, u32 *dsi_cnt) { mutex_lock(&sde_splash_lock); *hdmi_cnt = sinfo->hdmi_connector_cnt; *dsi_cnt = sinfo->dsi_connector_cnt; mutex_unlock(&sde_splash_lock); } static int _sde_splash_free_module_resource(struct msm_mmu *mmu, struct sde_splash_info *sinfo) { Loading @@ -339,6 +348,29 @@ static int _sde_splash_free_module_resource(struct msm_mmu *mmu, return 0; } static bool _sde_splash_validate_commit(struct sde_kms *sde_kms, struct drm_atomic_state *state) { int i, nplanes; struct drm_plane *plane; struct drm_device *dev = sde_kms->dev; nplanes = dev->mode_config.num_total_plane; for (i = 0; i < nplanes; i++) { plane = state->planes[i]; /* * As plane state has been swapped, we need to check * fb in state->planes, not fb in state->plane_state. */ if (plane && plane->fb) return true; } return false; } __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms) { struct sde_kms *sde_kms; Loading Loading @@ -369,8 +401,7 @@ __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms) sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); ret = -EINVAL; break; return -EINVAL; } } Loading Loading @@ -716,11 +747,17 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms) } int sde_splash_free_resource(struct msm_kms *kms, struct sde_power_handle *phandle) struct sde_power_handle *phandle, int connector_type, void *display) { struct sde_kms *sde_kms; struct sde_splash_info *sinfo; struct msm_mmu *mmu; struct dsi_display *dsi_display = display; int ret = 0; int hdmi_conn_count = 0; int dsi_conn_count = 0; static const char *last_commit_display_type = "unknown"; if (!phandle || !kms) { SDE_ERROR("invalid phandle/kms.\n"); Loading @@ -734,12 +771,21 @@ int sde_splash_free_resource(struct msm_kms *kms, return -EINVAL; } /* Get connector number where the early splash in on. */ _sde_splash_get_connector_ref_cnt(sinfo, &hdmi_conn_count, &dsi_conn_count); mutex_lock(&sde_splash_lock); if (!sinfo->handoff) { mutex_unlock(&sde_splash_lock); return 0; } /* * Start to free all LK's resource till user commit happens * on each display which early splash is enabled on. */ if (hdmi_conn_count == 0 && dsi_conn_count == 0) { mmu = sde_kms->aspace[0]->mmu; if (!mmu) { mutex_unlock(&sde_splash_lock); Loading @@ -759,24 +805,63 @@ int sde_splash_free_resource(struct msm_kms *kms, sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); /* * Turn off MDP core power to keep power on/off operations * be matched, as MDP core power is enabled already when * early splash is enabled. */ sde_power_resource_enable(phandle, sde_kms->core_client, false); /* send uevent to notify user to recycle resource */ _sde_splash_sent_pipe_update_uevent(sde_kms); /* Finally mark handoff flag to false to say handoff is complete */ /* Finally mark handoff flag to false to say * handoff is complete. */ sinfo->handoff = false; DRM_INFO("HDMI and DSI resource handoff is completed\n"); mutex_unlock(&sde_splash_lock); return 0; } /* * Ensure user commit happens on different connectors * who has splash. */ switch (connector_type) { case DRM_MODE_CONNECTOR_HDMIA: if (sinfo->hdmi_connector_cnt == 1) sinfo->hdmi_connector_cnt--; break; case DRM_MODE_CONNECTOR_DSI: if (strcmp(dsi_display->display_type, "unknown") && strcmp(last_commit_display_type, dsi_display->display_type)) { if (sinfo->dsi_connector_cnt >= 1) sinfo->dsi_connector_cnt--; last_commit_display_type = dsi_display->display_type; } break; default: ret = -EINVAL; SDE_ERROR("%s: invalid connector_type %d\n", __func__, connector_type); } mutex_unlock(&sde_splash_lock); return ret; } /* * In below function, it will * 1. Notify LK to stop display splash. * 2. Set DOMAIN_ATTR_EARLY_MAP to 1 to enable stage 1 translation in iommu. */ int sde_splash_lk_stop_splash(struct msm_kms *kms) int sde_splash_lk_stop_splash(struct msm_kms *kms, struct drm_atomic_state *state) { struct sde_splash_info *sinfo; struct msm_mmu *mmu; Loading @@ -792,7 +877,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms) /* Monitor LK's status and tell it to exit. */ mutex_lock(&sde_splash_lock); if (sinfo->display_splash_enabled) { if (_sde_splash_validate_commit(sde_kms, state) && sinfo->display_splash_enabled) { if (_sde_splash_lk_check(sde_kms->hw_intr)) _sde_splash_notify_lk_stop_splash(sde_kms->hw_intr); Loading
drivers/gpu/drm/msm/sde/sde_splash.h +12 −12 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ #include "msm_mmu.h" #include "sde_hw_mdss.h" #define SPLASH_CTL_MAX 5 #define SPLASH_LM_MAX 7 enum splash_connector_type { SPLASH_DSI = 0, SPLASH_HDMI, Loading @@ -35,13 +32,13 @@ struct splash_ctl_top { u32 value; u8 intf_sel; u8 ctl_lm_cnt; struct splash_lm_hw lm[SPLASH_LM_MAX]; struct splash_lm_hw lm[LM_MAX - LM_0]; }; struct sde_res_data { struct splash_ctl_top top[SPLASH_CTL_MAX]; u8 ctl_ids[SPLASH_CTL_MAX]; u8 lm_ids[SPLASH_LM_MAX]; struct splash_ctl_top top[CTL_MAX - CTL_0]; u8 ctl_ids[CTL_MAX - CTL_0]; u8 lm_ids[LM_MAX - LM_0]; u8 ctl_top_cnt; u8 lm_cnt; }; Loading Loading @@ -121,18 +118,21 @@ void sde_splash_setup_connector_count(struct sde_splash_info *sinfo, /** * sde_splash_lk_stop_splash. * * Tell LK to stop display splash. * Tell LK to stop display splash once one valid user commit arrives. */ int sde_splash_lk_stop_splash(struct msm_kms *kms); int sde_splash_lk_stop_splash(struct msm_kms *kms, struct drm_atomic_state *state); /** * sde_splash_free_resource. * * According to input connector_type, free * HDMI's and DSI's resource respectively. * To free all LK's resource, including free reserved memory to system, * withdraw data bus vote, disable MDP core power, send uevent to user * to recycle pipe etc. */ int sde_splash_free_resource(struct msm_kms *kms, struct sde_power_handle *phandle); struct sde_power_handle *phandle, int connector_type, void *display); /** * sde_splash_parse_memory_dt. Loading