Loading drivers/gpu/drm/msm/sde/sde_crtc.c +19 −1 Original line number Diff line number Diff line Loading @@ -867,10 +867,12 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, static void sde_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct drm_encoder *encoder; struct sde_crtc *sde_crtc; struct drm_device *dev; struct drm_plane *plane; unsigned long flags; struct sde_crtc_state *cstate; if (!crtc) { SDE_ERROR("invalid crtc\n"); Loading @@ -886,7 +888,7 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, SDE_DEBUG("crtc%d\n", crtc->base.id); sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); dev = crtc->dev; if (sde_crtc->event) { Loading @@ -908,6 +910,17 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, /* wait for acquire fences before anything else is done */ _sde_crtc_wait_for_fences(crtc); if (!cstate->rsc_update) { drm_for_each_encoder(encoder, dev) { if (encoder->crtc != crtc) continue; cstate->rsc_client = sde_encoder_update_rsc_client(encoder, true); } cstate->rsc_update = true; } /* update performance setting before crtc kickoff */ sde_core_perf_crtc_update(crtc, 1, false); Loading Loading @@ -1078,6 +1091,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) { struct msm_drm_private *priv; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; struct sde_kms *sde_kms; Loading @@ -1086,6 +1100,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); sde_kms = _sde_crtc_get_kms(crtc); priv = sde_kms->dev->dev_private; Loading Loading @@ -1122,6 +1137,9 @@ static void sde_crtc_disable(struct drm_crtc *crtc) if (encoder->crtc != crtc) continue; sde_encoder_register_frame_event_callback(encoder, NULL, NULL); sde_encoder_update_rsc_client(encoder, false); cstate->rsc_client = NULL; cstate->rsc_update = false; } memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); Loading drivers/gpu/drm/msm/sde/sde_crtc.h +8 −5 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ struct sde_crtc { * @connectors : Currently associated drm connectors * @num_connectors: Number of associated drm connectors * @intf_mode : Interface mode of the primary connector * @rsc_mode : Client vote through sde rsc * @rsc_client : sde rsc client when mode is valid * @property_values: Current crtc property values * @input_fence_timeout_ns : Cached input fence timeout, in ns Loading @@ -167,8 +166,8 @@ struct sde_crtc_state { struct drm_connector *connectors[MAX_CONNECTORS]; int num_connectors; enum sde_intf_mode intf_mode; bool rsc_mode; struct sde_rsc_client *rsc_client; bool rsc_update; uint64_t property_values[CRTC_PROP_COUNT]; uint64_t input_fence_timeout_ns; Loading Loading @@ -286,13 +285,17 @@ static inline enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc) * sde_crtc_get_client_type - check the crtc type- rt, nrt, rsc, etc. * @crtc: Pointer to crtc */ static inline bool sde_crtc_get_client_type(struct drm_crtc *crtc) static inline enum sde_crtc_client_type sde_crtc_get_client_type( struct drm_crtc *crtc) { struct sde_crtc_state *cstate = crtc ? to_sde_crtc_state(crtc->state) : NULL; return cstate && (cstate->intf_mode == INTF_MODE_WB_LINE) ? NRT_CLIENT : cstate && cstate->rsc_mode ? RT_RSC_CLIENT : RT_CLIENT; if (!cstate) return NRT_CLIENT; return cstate->rsc_client ? RT_RSC_CLIENT : (cstate->intf_mode == INTF_MODE_WB_LINE ? NRT_CLIENT : RT_CLIENT); } /** Loading drivers/gpu/drm/msm/sde/sde_encoder.c +47 −42 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ struct sde_encoder_virt { struct sde_rsc_client *rsc_client; struct msm_display_info disp_info; bool rsc_state_update; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -375,8 +376,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0, ret; enum sde_rsc_state rsc_state; int i = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); Loading @@ -399,8 +399,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); sde_enc->cur_master = NULL; rsc_state = sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ? SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading @@ -423,19 +421,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) SDE_ERROR("virt encoder has no master! num_phys %d\n", i); else if (sde_enc->cur_master->ops.enable) sde_enc->cur_master->ops.enable(sde_enc->cur_master); /** * this should be after interface enable because interface enable api * turns on panel, configure the TE for command mode and turns on * timing engine for video mode. The RSC api call is going to wait * for vsync after it switches the mode - that requires te/timing engine * enabled. */ ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, NULL, drm_enc->crtc ? drm_enc->crtc->index : -1); if (ret) SDE_ERROR("sde rsc client update failed ret:%d\n", ret); } static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) Loading Loading @@ -487,8 +472,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) sde_rm_release(&sde_kms->rm, drm_enc); sde_rsc_client_state_update(sde_enc->rsc_client, SDE_RSC_IDLE_STATE, NULL, -1); sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false); } Loading Loading @@ -586,6 +569,49 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, } } struct sde_rsc_client *sde_encoder_update_rsc_client( struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; enum sde_rsc_state rsc_state; struct sde_rsc_cmd_config rsc_config; int ret; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return NULL; } sde_enc = to_sde_encoder_virt(drm_enc); if (!sde_enc->disp_info.is_primary) return NULL; rsc_state = enable ? (sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ? SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE; if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_update) { rsc_config.fps = sde_enc->disp_info.frame_rate; rsc_config.vtotal = sde_enc->disp_info.vtotal; rsc_config.prefill_lines = sde_enc->disp_info.prefill_lines; rsc_config.jitter = sde_enc->disp_info.jitter; sde_enc->rsc_state_update = true; ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, &rsc_config, drm_enc->crtc ? drm_enc->crtc->index : -1); } else { ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, NULL, drm_enc->crtc ? drm_enc->crtc->index : -1); } if (ret) SDE_ERROR("sde rsc client update failed ret:%d\n", ret); return sde_enc->rsc_client; } void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc, void (*frame_event_cb)(void *, u32 event), void *frame_event_cb_data) Loading Loading @@ -848,7 +874,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) struct sde_encoder_phys *phys; bool needs_hw_reset = false; unsigned int i; int ret; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); Loading @@ -859,14 +884,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) SDE_DEBUG_ENC(sde_enc, "\n"); SDE_EVT32(DRMID(drm_enc)); if (sde_enc->disp_info.is_primary) { ret = sde_rsc_client_vote(sde_enc->rsc_client, SDE_POWER_HANDLE_DATA_BUS_IB_QUOTA, SDE_POWER_HANDLE_DATA_BUS_AB_QUOTA); if (ret) SDE_ERROR("sde rsc client vote failed ret:%d\n", ret); } /* prepare for next kickoff, may include waiting on previous kickoff */ for (i = 0; i < sde_enc->num_phys_encs; i++) { phys = sde_enc->phys_encs[i]; Loading Loading @@ -1380,6 +1397,7 @@ struct drm_encoder *sde_encoder_init( PTR_ERR(sde_enc->rsc_client)); sde_enc->rsc_client = NULL; } memcpy(&sde_enc->disp_info, disp_info, sizeof(*disp_info)); SDE_DEBUG_ENC(sde_enc, "created\n"); Loading Loading @@ -1446,16 +1464,3 @@ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder) return INTF_MODE_NONE; } bool sde_encoder_get_intf_primary(struct drm_encoder *encoder) { struct sde_encoder_virt *sde_enc = NULL; if (!encoder) { SDE_ERROR("invalid encoder\n"); return INTF_MODE_NONE; } sde_enc = to_sde_encoder_virt(encoder); return sde_enc->disp_info.is_primary; } drivers/gpu/drm/msm/sde/sde_encoder.h +9 −6 Original line number Diff line number Diff line Loading @@ -72,6 +72,15 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *encoder, void sde_encoder_register_frame_event_callback(struct drm_encoder *encoder, void (*cb)(void *, u32), void *data); /** * sde_encoder_update_rsc_client - updates the rsc client state for primary * for primary display. * @encoder: encoder pointer * @enable: enable/disable the client */ struct sde_rsc_client *sde_encoder_update_rsc_client( struct drm_encoder *encoder, bool enable); /** * sde_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl * path (i.e. ctl flush and start) at next appropriate time. Loading Loading @@ -104,12 +113,6 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /* * sde_encoder_get_intf_primary - is primary display connected with encoder * @encoder: Pointer to drm encoder object */ bool sde_encoder_get_intf_primary(struct drm_encoder *encoder); /** * sde_encoder_init - initialize virtual encoder object * @dev: Pointer to drm device structure Loading drivers/gpu/drm/msm/sde/sde_plane.c +1 −1 Original line number Diff line number Diff line Loading @@ -2687,7 +2687,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, _sde_plane_init_debugfs(psde, kms); DRM_INFO("%s created for pipe %u\n", psde->pipe_name, pipe); SDE_DEBUG("%s created for pipe %u\n", psde->pipe_name, pipe); return plane; clean_sspp: Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +19 −1 Original line number Diff line number Diff line Loading @@ -867,10 +867,12 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, static void sde_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct drm_encoder *encoder; struct sde_crtc *sde_crtc; struct drm_device *dev; struct drm_plane *plane; unsigned long flags; struct sde_crtc_state *cstate; if (!crtc) { SDE_ERROR("invalid crtc\n"); Loading @@ -886,7 +888,7 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, SDE_DEBUG("crtc%d\n", crtc->base.id); sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); dev = crtc->dev; if (sde_crtc->event) { Loading @@ -908,6 +910,17 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, /* wait for acquire fences before anything else is done */ _sde_crtc_wait_for_fences(crtc); if (!cstate->rsc_update) { drm_for_each_encoder(encoder, dev) { if (encoder->crtc != crtc) continue; cstate->rsc_client = sde_encoder_update_rsc_client(encoder, true); } cstate->rsc_update = true; } /* update performance setting before crtc kickoff */ sde_core_perf_crtc_update(crtc, 1, false); Loading Loading @@ -1078,6 +1091,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) { struct msm_drm_private *priv; struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *encoder; struct sde_kms *sde_kms; Loading @@ -1086,6 +1100,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) return; } sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); sde_kms = _sde_crtc_get_kms(crtc); priv = sde_kms->dev->dev_private; Loading Loading @@ -1122,6 +1137,9 @@ static void sde_crtc_disable(struct drm_crtc *crtc) if (encoder->crtc != crtc) continue; sde_encoder_register_frame_event_callback(encoder, NULL, NULL); sde_encoder_update_rsc_client(encoder, false); cstate->rsc_client = NULL; cstate->rsc_update = false; } memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +8 −5 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ struct sde_crtc { * @connectors : Currently associated drm connectors * @num_connectors: Number of associated drm connectors * @intf_mode : Interface mode of the primary connector * @rsc_mode : Client vote through sde rsc * @rsc_client : sde rsc client when mode is valid * @property_values: Current crtc property values * @input_fence_timeout_ns : Cached input fence timeout, in ns Loading @@ -167,8 +166,8 @@ struct sde_crtc_state { struct drm_connector *connectors[MAX_CONNECTORS]; int num_connectors; enum sde_intf_mode intf_mode; bool rsc_mode; struct sde_rsc_client *rsc_client; bool rsc_update; uint64_t property_values[CRTC_PROP_COUNT]; uint64_t input_fence_timeout_ns; Loading Loading @@ -286,13 +285,17 @@ static inline enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc) * sde_crtc_get_client_type - check the crtc type- rt, nrt, rsc, etc. * @crtc: Pointer to crtc */ static inline bool sde_crtc_get_client_type(struct drm_crtc *crtc) static inline enum sde_crtc_client_type sde_crtc_get_client_type( struct drm_crtc *crtc) { struct sde_crtc_state *cstate = crtc ? to_sde_crtc_state(crtc->state) : NULL; return cstate && (cstate->intf_mode == INTF_MODE_WB_LINE) ? NRT_CLIENT : cstate && cstate->rsc_mode ? RT_RSC_CLIENT : RT_CLIENT; if (!cstate) return NRT_CLIENT; return cstate->rsc_client ? RT_RSC_CLIENT : (cstate->intf_mode == INTF_MODE_WB_LINE ? NRT_CLIENT : RT_CLIENT); } /** Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +47 −42 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ struct sde_encoder_virt { struct sde_rsc_client *rsc_client; struct msm_display_info disp_info; bool rsc_state_update; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -375,8 +376,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) struct sde_encoder_virt *sde_enc = NULL; struct msm_drm_private *priv; struct sde_kms *sde_kms; int i = 0, ret; enum sde_rsc_state rsc_state; int i = 0; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); Loading @@ -399,8 +399,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); sde_enc->cur_master = NULL; rsc_state = sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ? SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading @@ -423,19 +421,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) SDE_ERROR("virt encoder has no master! num_phys %d\n", i); else if (sde_enc->cur_master->ops.enable) sde_enc->cur_master->ops.enable(sde_enc->cur_master); /** * this should be after interface enable because interface enable api * turns on panel, configure the TE for command mode and turns on * timing engine for video mode. The RSC api call is going to wait * for vsync after it switches the mode - that requires te/timing engine * enabled. */ ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, NULL, drm_enc->crtc ? drm_enc->crtc->index : -1); if (ret) SDE_ERROR("sde rsc client update failed ret:%d\n", ret); } static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) Loading Loading @@ -487,8 +472,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) sde_rm_release(&sde_kms->rm, drm_enc); sde_rsc_client_state_update(sde_enc->rsc_client, SDE_RSC_IDLE_STATE, NULL, -1); sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false); } Loading Loading @@ -586,6 +569,49 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc, } } struct sde_rsc_client *sde_encoder_update_rsc_client( struct drm_encoder *drm_enc, bool enable) { struct sde_encoder_virt *sde_enc; enum sde_rsc_state rsc_state; struct sde_rsc_cmd_config rsc_config; int ret; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); return NULL; } sde_enc = to_sde_encoder_virt(drm_enc); if (!sde_enc->disp_info.is_primary) return NULL; rsc_state = enable ? (sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ? SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE; if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_update) { rsc_config.fps = sde_enc->disp_info.frame_rate; rsc_config.vtotal = sde_enc->disp_info.vtotal; rsc_config.prefill_lines = sde_enc->disp_info.prefill_lines; rsc_config.jitter = sde_enc->disp_info.jitter; sde_enc->rsc_state_update = true; ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, &rsc_config, drm_enc->crtc ? drm_enc->crtc->index : -1); } else { ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, NULL, drm_enc->crtc ? drm_enc->crtc->index : -1); } if (ret) SDE_ERROR("sde rsc client update failed ret:%d\n", ret); return sde_enc->rsc_client; } void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc, void (*frame_event_cb)(void *, u32 event), void *frame_event_cb_data) Loading Loading @@ -848,7 +874,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) struct sde_encoder_phys *phys; bool needs_hw_reset = false; unsigned int i; int ret; if (!drm_enc) { SDE_ERROR("invalid encoder\n"); Loading @@ -859,14 +884,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) SDE_DEBUG_ENC(sde_enc, "\n"); SDE_EVT32(DRMID(drm_enc)); if (sde_enc->disp_info.is_primary) { ret = sde_rsc_client_vote(sde_enc->rsc_client, SDE_POWER_HANDLE_DATA_BUS_IB_QUOTA, SDE_POWER_HANDLE_DATA_BUS_AB_QUOTA); if (ret) SDE_ERROR("sde rsc client vote failed ret:%d\n", ret); } /* prepare for next kickoff, may include waiting on previous kickoff */ for (i = 0; i < sde_enc->num_phys_encs; i++) { phys = sde_enc->phys_encs[i]; Loading Loading @@ -1380,6 +1397,7 @@ struct drm_encoder *sde_encoder_init( PTR_ERR(sde_enc->rsc_client)); sde_enc->rsc_client = NULL; } memcpy(&sde_enc->disp_info, disp_info, sizeof(*disp_info)); SDE_DEBUG_ENC(sde_enc, "created\n"); Loading Loading @@ -1446,16 +1464,3 @@ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder) return INTF_MODE_NONE; } bool sde_encoder_get_intf_primary(struct drm_encoder *encoder) { struct sde_encoder_virt *sde_enc = NULL; if (!encoder) { SDE_ERROR("invalid encoder\n"); return INTF_MODE_NONE; } sde_enc = to_sde_encoder_virt(encoder); return sde_enc->disp_info.is_primary; }
drivers/gpu/drm/msm/sde/sde_encoder.h +9 −6 Original line number Diff line number Diff line Loading @@ -72,6 +72,15 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *encoder, void sde_encoder_register_frame_event_callback(struct drm_encoder *encoder, void (*cb)(void *, u32), void *data); /** * sde_encoder_update_rsc_client - updates the rsc client state for primary * for primary display. * @encoder: encoder pointer * @enable: enable/disable the client */ struct sde_rsc_client *sde_encoder_update_rsc_client( struct drm_encoder *encoder, bool enable); /** * sde_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl * path (i.e. ctl flush and start) at next appropriate time. Loading Loading @@ -104,12 +113,6 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); */ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder); /* * sde_encoder_get_intf_primary - is primary display connected with encoder * @encoder: Pointer to drm encoder object */ bool sde_encoder_get_intf_primary(struct drm_encoder *encoder); /** * sde_encoder_init - initialize virtual encoder object * @dev: Pointer to drm device structure Loading
drivers/gpu/drm/msm/sde/sde_plane.c +1 −1 Original line number Diff line number Diff line Loading @@ -2687,7 +2687,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, _sde_plane_init_debugfs(psde, kms); DRM_INFO("%s created for pipe %u\n", psde->pipe_name, pipe); SDE_DEBUG("%s created for pipe %u\n", psde->pipe_name, pipe); return plane; clean_sspp: Loading