Loading drivers/gpu/drm/msm/sde/sde_hw_rot.c +4 −0 Original line number Diff line number Diff line Loading @@ -588,6 +588,10 @@ static int sde_hw_rot_commit(struct sde_hw_rot *hw, struct sde_hw_rot_cmd *data, cmd_type = SDE_ROTATOR_INLINE_CMD_CLEANUP; priv_handle = data->priv_handle; break; case SDE_HW_ROT_CMD_RESET: cmd_type = SDE_ROTATOR_INLINE_CMD_ABORT; priv_handle = data->priv_handle; break; default: SDE_ERROR("invalid hw rotator command %d\n", hw_cmd); return -EINVAL; Loading drivers/gpu/drm/msm/sde/sde_hw_rot.h +2 −0 Original line number Diff line number Diff line Loading @@ -28,12 +28,14 @@ struct sde_hw_rot; * @SDE_HW_ROT_CMD_COMMIT: commit/execute rotator command * @SDE_HW_ROT_CMD_START: mdp is ready to start * @SDE_HW_ROT_CMD_CLEANUP: cleanup rotator command after it is done * @SDE_HW_ROT_CMD_RESET: request rotator h/w reset */ enum sde_hw_rot_cmd_type { SDE_HW_ROT_CMD_VALIDATE, SDE_HW_ROT_CMD_COMMIT, SDE_HW_ROT_CMD_START, SDE_HW_ROT_CMD_CLEANUP, SDE_HW_ROT_CMD_RESET, }; /** Loading drivers/gpu/drm/msm/sde/sde_plane.c +107 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ enum sde_plane_qos { * @sbuf_mode: force stream buffer mode if set * @sbuf_writeback: force stream buffer writeback if set * @revalidate: force revalidation of all the plane properties * @xin_halt_forced_clk: whether or not clocks were forced on for xin halt * @blob_rot_caps: Pointer to rotator capability blob */ struct sde_plane { Loading @@ -128,6 +129,7 @@ struct sde_plane { u32 sbuf_mode; u32 sbuf_writeback; bool revalidate; bool xin_halt_forced_clk; struct sde_csc_cfg csc_cfg; struct sde_csc_cfg *csc_usr_ptr; Loading Loading @@ -2489,6 +2491,111 @@ static void sde_plane_rot_atomic_update(struct drm_plane *plane, msm_framebuffer_cleanup(state->fb, pstate->aspace); } static bool _sde_plane_halt_requests(struct drm_plane *plane, uint32_t xin_id, bool halt_forced_clk, bool enable) { struct sde_plane *psde; struct msm_drm_private *priv; struct sde_vbif_set_xin_halt_params halt_params; if (!plane || !plane->dev) { SDE_ERROR("invalid arguments\n"); return false; } psde = to_sde_plane(plane); if (!psde->pipe_hw || !psde->pipe_hw->cap) { SDE_ERROR("invalid pipe reference\n"); return false; } priv = plane->dev->dev_private; if (!priv || !priv->kms) { SDE_ERROR("invalid KMS reference\n"); return false; } memset(&halt_params, 0, sizeof(halt_params)); halt_params.vbif_idx = VBIF_RT; halt_params.xin_id = xin_id; halt_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl; halt_params.forced_on = halt_forced_clk; halt_params.enable = enable; return sde_vbif_set_xin_halt(to_sde_kms(priv->kms), &halt_params); } void sde_plane_halt_requests(struct drm_plane *plane, bool enable) { struct sde_plane *psde; if (!plane) { SDE_ERROR("invalid plane\n"); return; } psde = to_sde_plane(plane); if (!psde->pipe_hw || !psde->pipe_hw->cap) { SDE_ERROR("invalid pipe reference\n"); return; } SDE_EVT32(DRMID(plane), psde->xin_halt_forced_clk, enable); psde->xin_halt_forced_clk = _sde_plane_halt_requests(plane, psde->pipe_hw->cap->xin_id, psde->xin_halt_forced_clk, enable); } int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state) { struct sde_plane *psde; struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; bool halt_ret[MAX_BLOCKS] = {false}; signed int i, count; if (!plane || !state) { SDE_ERROR("invalid plane\n"); return -EINVAL; } psde = to_sde_plane(plane); pstate = to_sde_plane_state(state); rstate = &pstate->rot; /* do nothing if not master rotator plane */ if (!rstate->out_sbuf || !rstate->rot_hw || !rstate->rot_hw->caps || (rstate->out_xpos != 0)) return 0; count = (signed int)rstate->rot_hw->caps->xin_count; if (count > ARRAY_SIZE(halt_ret)) count = ARRAY_SIZE(halt_ret); SDE_DEBUG_PLANE(psde, "issuing reset for rotator\n"); SDE_EVT32(DRMID(plane), count); for (i = 0; i < count; i++) { const struct sde_rot_vbif_cfg *cfg = &rstate->rot_hw->caps->vbif_cfg[i]; halt_ret[i] = _sde_plane_halt_requests(plane, cfg->xin_id, false, true); } sde_plane_rot_submit_command(plane, state, SDE_HW_ROT_CMD_RESET); for (i = count - 1; i >= 0; --i) { const struct sde_rot_vbif_cfg *cfg = &rstate->rot_hw->caps->vbif_cfg[i]; _sde_plane_halt_requests(plane, cfg->xin_id, halt_ret[i], false); } return 0; } int sde_plane_kickoff_rot(struct drm_plane *plane) { struct sde_plane_state *pstate; Loading drivers/gpu/drm/msm/sde/sde_plane.h +17 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,23 @@ void sde_plane_restore(struct drm_plane *plane); */ void sde_plane_flush(struct drm_plane *plane); /** * sde_plane_halt_requests - control halting of vbif transactions for this plane * This function isn't thread safe. Plane halt enable/disable requests * should always be made from the same commit cycle. * @plane: Pointer to drm plane structure * @enable: Whether to enable/disable halting of vbif transactions */ void sde_plane_halt_requests(struct drm_plane *plane, bool enable); /** * sde_plane_reset_rot - reset rotator operations before commit kickoff * @plane: Pointer to drm plane structure * @state: Pointer to plane state associated with reset request * Returns: Zero on success */ int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state); /** * sde_plane_kickoff_rot - final plane rotator operations before commit kickoff * @plane: Pointer to drm plane structure Loading drivers/gpu/drm/msm/sde/sde_vbif.c +56 −2 Original line number Diff line number Diff line Loading @@ -230,13 +230,15 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { if (sde_kms->hw_vbif[i] && sde_kms->hw_vbif[i]->idx == params->vbif_idx) sde_kms->hw_vbif[i]->idx == params->vbif_idx) { vbif = sde_kms->hw_vbif[i]; break; } } if (!vbif || !mdp) { SDE_DEBUG("invalid arguments vbif %d mdp %d\n", vbif != 0, mdp != 0); vbif != NULL, mdp != NULL); return; } Loading Loading @@ -275,6 +277,58 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, return; } bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, struct sde_vbif_set_xin_halt_params *params) { struct sde_hw_vbif *vbif = NULL; struct sde_hw_mdp *mdp; bool forced_on = false; int ret, i; if (!sde_kms || !params) { SDE_ERROR("invalid arguments\n"); return false; } mdp = sde_kms->hw_mdp; for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { if (sde_kms->hw_vbif[i] && sde_kms->hw_vbif[i]->idx == params->vbif_idx) { vbif = sde_kms->hw_vbif[i]; break; } } if (!vbif || !mdp) { SDE_DEBUG("invalid arguments vbif %d mdp %d\n", vbif != NULL, mdp != NULL); return false; } if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_halt_ctrl) return false; if (params->enable) { forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id, SDE_EVTLOG_ERROR); } else { vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); if (params->forced_on) mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); } return forced_on; } void sde_vbif_set_qos_remap(struct sde_kms *sde_kms, struct sde_vbif_set_qos_params *params) { Loading Loading
drivers/gpu/drm/msm/sde/sde_hw_rot.c +4 −0 Original line number Diff line number Diff line Loading @@ -588,6 +588,10 @@ static int sde_hw_rot_commit(struct sde_hw_rot *hw, struct sde_hw_rot_cmd *data, cmd_type = SDE_ROTATOR_INLINE_CMD_CLEANUP; priv_handle = data->priv_handle; break; case SDE_HW_ROT_CMD_RESET: cmd_type = SDE_ROTATOR_INLINE_CMD_ABORT; priv_handle = data->priv_handle; break; default: SDE_ERROR("invalid hw rotator command %d\n", hw_cmd); return -EINVAL; Loading
drivers/gpu/drm/msm/sde/sde_hw_rot.h +2 −0 Original line number Diff line number Diff line Loading @@ -28,12 +28,14 @@ struct sde_hw_rot; * @SDE_HW_ROT_CMD_COMMIT: commit/execute rotator command * @SDE_HW_ROT_CMD_START: mdp is ready to start * @SDE_HW_ROT_CMD_CLEANUP: cleanup rotator command after it is done * @SDE_HW_ROT_CMD_RESET: request rotator h/w reset */ enum sde_hw_rot_cmd_type { SDE_HW_ROT_CMD_VALIDATE, SDE_HW_ROT_CMD_COMMIT, SDE_HW_ROT_CMD_START, SDE_HW_ROT_CMD_CLEANUP, SDE_HW_ROT_CMD_RESET, }; /** Loading
drivers/gpu/drm/msm/sde/sde_plane.c +107 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ enum sde_plane_qos { * @sbuf_mode: force stream buffer mode if set * @sbuf_writeback: force stream buffer writeback if set * @revalidate: force revalidation of all the plane properties * @xin_halt_forced_clk: whether or not clocks were forced on for xin halt * @blob_rot_caps: Pointer to rotator capability blob */ struct sde_plane { Loading @@ -128,6 +129,7 @@ struct sde_plane { u32 sbuf_mode; u32 sbuf_writeback; bool revalidate; bool xin_halt_forced_clk; struct sde_csc_cfg csc_cfg; struct sde_csc_cfg *csc_usr_ptr; Loading Loading @@ -2489,6 +2491,111 @@ static void sde_plane_rot_atomic_update(struct drm_plane *plane, msm_framebuffer_cleanup(state->fb, pstate->aspace); } static bool _sde_plane_halt_requests(struct drm_plane *plane, uint32_t xin_id, bool halt_forced_clk, bool enable) { struct sde_plane *psde; struct msm_drm_private *priv; struct sde_vbif_set_xin_halt_params halt_params; if (!plane || !plane->dev) { SDE_ERROR("invalid arguments\n"); return false; } psde = to_sde_plane(plane); if (!psde->pipe_hw || !psde->pipe_hw->cap) { SDE_ERROR("invalid pipe reference\n"); return false; } priv = plane->dev->dev_private; if (!priv || !priv->kms) { SDE_ERROR("invalid KMS reference\n"); return false; } memset(&halt_params, 0, sizeof(halt_params)); halt_params.vbif_idx = VBIF_RT; halt_params.xin_id = xin_id; halt_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl; halt_params.forced_on = halt_forced_clk; halt_params.enable = enable; return sde_vbif_set_xin_halt(to_sde_kms(priv->kms), &halt_params); } void sde_plane_halt_requests(struct drm_plane *plane, bool enable) { struct sde_plane *psde; if (!plane) { SDE_ERROR("invalid plane\n"); return; } psde = to_sde_plane(plane); if (!psde->pipe_hw || !psde->pipe_hw->cap) { SDE_ERROR("invalid pipe reference\n"); return; } SDE_EVT32(DRMID(plane), psde->xin_halt_forced_clk, enable); psde->xin_halt_forced_clk = _sde_plane_halt_requests(plane, psde->pipe_hw->cap->xin_id, psde->xin_halt_forced_clk, enable); } int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state) { struct sde_plane *psde; struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; bool halt_ret[MAX_BLOCKS] = {false}; signed int i, count; if (!plane || !state) { SDE_ERROR("invalid plane\n"); return -EINVAL; } psde = to_sde_plane(plane); pstate = to_sde_plane_state(state); rstate = &pstate->rot; /* do nothing if not master rotator plane */ if (!rstate->out_sbuf || !rstate->rot_hw || !rstate->rot_hw->caps || (rstate->out_xpos != 0)) return 0; count = (signed int)rstate->rot_hw->caps->xin_count; if (count > ARRAY_SIZE(halt_ret)) count = ARRAY_SIZE(halt_ret); SDE_DEBUG_PLANE(psde, "issuing reset for rotator\n"); SDE_EVT32(DRMID(plane), count); for (i = 0; i < count; i++) { const struct sde_rot_vbif_cfg *cfg = &rstate->rot_hw->caps->vbif_cfg[i]; halt_ret[i] = _sde_plane_halt_requests(plane, cfg->xin_id, false, true); } sde_plane_rot_submit_command(plane, state, SDE_HW_ROT_CMD_RESET); for (i = count - 1; i >= 0; --i) { const struct sde_rot_vbif_cfg *cfg = &rstate->rot_hw->caps->vbif_cfg[i]; _sde_plane_halt_requests(plane, cfg->xin_id, halt_ret[i], false); } return 0; } int sde_plane_kickoff_rot(struct drm_plane *plane) { struct sde_plane_state *pstate; Loading
drivers/gpu/drm/msm/sde/sde_plane.h +17 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,23 @@ void sde_plane_restore(struct drm_plane *plane); */ void sde_plane_flush(struct drm_plane *plane); /** * sde_plane_halt_requests - control halting of vbif transactions for this plane * This function isn't thread safe. Plane halt enable/disable requests * should always be made from the same commit cycle. * @plane: Pointer to drm plane structure * @enable: Whether to enable/disable halting of vbif transactions */ void sde_plane_halt_requests(struct drm_plane *plane, bool enable); /** * sde_plane_reset_rot - reset rotator operations before commit kickoff * @plane: Pointer to drm plane structure * @state: Pointer to plane state associated with reset request * Returns: Zero on success */ int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state); /** * sde_plane_kickoff_rot - final plane rotator operations before commit kickoff * @plane: Pointer to drm plane structure Loading
drivers/gpu/drm/msm/sde/sde_vbif.c +56 −2 Original line number Diff line number Diff line Loading @@ -230,13 +230,15 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { if (sde_kms->hw_vbif[i] && sde_kms->hw_vbif[i]->idx == params->vbif_idx) sde_kms->hw_vbif[i]->idx == params->vbif_idx) { vbif = sde_kms->hw_vbif[i]; break; } } if (!vbif || !mdp) { SDE_DEBUG("invalid arguments vbif %d mdp %d\n", vbif != 0, mdp != 0); vbif != NULL, mdp != NULL); return; } Loading Loading @@ -275,6 +277,58 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, return; } bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, struct sde_vbif_set_xin_halt_params *params) { struct sde_hw_vbif *vbif = NULL; struct sde_hw_mdp *mdp; bool forced_on = false; int ret, i; if (!sde_kms || !params) { SDE_ERROR("invalid arguments\n"); return false; } mdp = sde_kms->hw_mdp; for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { if (sde_kms->hw_vbif[i] && sde_kms->hw_vbif[i]->idx == params->vbif_idx) { vbif = sde_kms->hw_vbif[i]; break; } } if (!vbif || !mdp) { SDE_DEBUG("invalid arguments vbif %d mdp %d\n", vbif != NULL, mdp != NULL); return false; } if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_halt_ctrl) return false; if (params->enable) { forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id, SDE_EVTLOG_ERROR); } else { vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); if (params->forced_on) mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); } return forced_on; } void sde_vbif_set_qos_remap(struct sde_kms *sde_kms, struct sde_vbif_set_qos_params *params) { Loading