Loading drivers/gpu/drm/msm/sde/sde_connector.c +2 −11 Original line number Diff line number Diff line Loading @@ -572,8 +572,6 @@ void sde_connector_complete_commit(struct drm_connector *connector) { struct drm_device *dev; struct msm_drm_private *priv; struct sde_connector *c_conn; struct sde_kms *sde_kms; if (!connector) { SDE_ERROR("invalid connector\n"); Loading @@ -582,7 +580,6 @@ void sde_connector_complete_commit(struct drm_connector *connector) dev = connector->dev; priv = dev->dev_private; sde_kms = to_sde_kms(priv->kms); /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0); Loading @@ -590,14 +587,8 @@ void sde_connector_complete_commit(struct drm_connector *connector) /* after first vsync comes, * early splash resource should start to be released. */ if (sde_splash_get_lk_complete_status(&sde_kms->splash_info)) { c_conn = to_sde_connector(connector); sde_splash_clean_up_free_resource(priv->kms, &priv->phandle, c_conn->connector_type, c_conn->display); } if (sde_splash_get_lk_complete_status(priv->kms)) sde_splash_free_resource(priv->kms, &priv->phandle); } Loading drivers/gpu/drm/msm/sde/sde_crtc.c +19 −2 Original line number Diff line number Diff line Loading @@ -304,6 +304,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) struct sde_crtc_mixer *mixer = sde_crtc->mixers; struct sde_hw_ctl *ctl; struct sde_hw_mixer *lm; struct sde_splash_info *sinfo; struct sde_kms *sde_kms = _sde_crtc_get_kms(crtc); int i; Loading @@ -314,6 +316,17 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) return; } if (!sde_kms) { SDE_ERROR("invalid sde_kms\n"); return; } sinfo = &sde_kms->splash_info; if (!sinfo) { SDE_ERROR("invalid splash info\n"); return; } for (i = 0; i < sde_crtc->num_mixers; i++) { if (!mixer[i].hw_lm || !mixer[i].hw_ctl) { SDE_ERROR("invalid lm or ctl assigned to mixer\n"); Loading @@ -323,7 +336,10 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].flush_mask = 0; if (mixer[i].hw_ctl->ops.clear_all_blendstages) mixer[i].hw_ctl->ops.clear_all_blendstages( mixer[i].hw_ctl); mixer[i].hw_ctl, sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS); } /* initialize stage cfg */ Loading @@ -350,7 +366,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].flush_mask); ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, &sde_crtc->stage_cfg, i); &sde_crtc->stage_cfg, i, sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS); } } Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.c +96 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -258,6 +258,35 @@ static inline int sde_hw_ctl_get_bitmask_cdm(struct sde_hw_ctl *ctx, return 0; } static inline int sde_hw_ctl_get_splash_mixercfg(const u32 *resv_pipes, u32 length) { int i = 0; u32 mixercfg = 0; for (i = 0; i < length; i++) { /* LK's splash VIG layer always stays on top */ switch (resv_pipes[i]) { case SSPP_VIG0: mixercfg |= 0x7 << 0; break; case SSPP_VIG1: mixercfg |= 0x7 << 3; break; case SSPP_VIG2: mixercfg |= 0x7 << 6; break; case SSPP_VIG3: mixercfg |= 0x7 << 26; break; default: break; } } return mixercfg; } static u32 sde_hw_ctl_poll_reset_status(struct sde_hw_ctl *ctx, u32 count) { struct sde_hw_blk_reg_map *c = &ctx->hw; Loading Loading @@ -312,15 +341,29 @@ static int sde_hw_ctl_wait_reset_status(struct sde_hw_ctl *ctx) return 0; } static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length) { struct sde_hw_blk_reg_map *c = &ctx->hw; int i; for (i = 0; i < ctx->mixer_count; i++) { int mixer_id = ctx->mixer_hw_caps[i].id; u32 mixercfg = 0; /* * if bootloaer still has early RVC running, mixer status * can't be direcly cleared. */ if (handoff) { mixercfg = sde_hw_ctl_get_splash_mixercfg(resv_pipes, resv_pipes_length); mixercfg &= SDE_REG_READ(c, CTL_LAYER(mixer_id)); } SDE_REG_WRITE(c, CTL_LAYER(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER(mixer_id), mixercfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); Loading @@ -328,7 +371,8 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) } static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index) enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length) { struct sde_hw_blk_reg_map *c = &ctx->hw; u32 mixercfg, mixercfg_ext, mix, ext, mixercfg_ext2; Loading @@ -353,6 +397,20 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, mixercfg_ext = 0; mixercfg_ext2 = 0; /* * if bootloader still have RVC running, its mixer stauts * should be updated to kernel's mixer setup. */ if (handoff) { mixercfg = sde_hw_ctl_get_splash_mixercfg(resv_pipes, resv_pipes_length); mixercfg &= SDE_REG_READ(c, CTL_LAYER(lm)); mixercfg |= BIT(24); stages--; } for (i = 0; i <= stages; i++) { /* overflow to ext register if 'i + 1 > 7' */ mix = (i + 1) & 0x7; Loading Loading @@ -458,6 +516,38 @@ static void sde_hw_ctl_intf_cfg(struct sde_hw_ctl *ctx, SDE_REG_WRITE(c, CTL_TOP, intf_cfg); } static inline u32 sde_hw_ctl_read_ctl_top_for_splash(struct sde_hw_ctl *ctx) { struct sde_hw_blk_reg_map *c; u32 ctl_top; if (!ctx) { pr_err("Invalid ctx\n"); return 0; } c = &ctx->hw; ctl_top = SDE_REG_READ(c, CTL_TOP); return ctl_top; } static inline u32 sde_hw_ctl_read_ctl_layers_for_splash(struct sde_hw_ctl *ctx, int index) { struct sde_hw_blk_reg_map *c; u32 ctl_top; if (!ctx) { pr_err("Invalid ctx\n"); return 0; } c = &ctx->hw; ctl_top = SDE_REG_READ(c, CTL_LAYER(index)); return ctl_top; } static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, unsigned long cap) { Loading @@ -478,6 +568,8 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->get_bitmask_intf = sde_hw_ctl_get_bitmask_intf; ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm; ops->get_bitmask_wb = sde_hw_ctl_get_bitmask_wb; ops->read_ctl_top_for_splash = sde_hw_ctl_read_ctl_top_for_splash; ops->read_ctl_layers_for_splash = sde_hw_ctl_read_ctl_layers_for_splash; }; struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.h +26 −3 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -146,17 +146,40 @@ struct sde_hw_ctl_ops { /** * Set all blend stages to disabled * @ctx : ctl path ctx pointer * @handoff : handoff flag * @resv_pipes : reserved pipes in DT * @resv_pipes_length: array size of array reserved_pipes */ void (*clear_all_blendstages)(struct sde_hw_ctl *ctx); void (*clear_all_blendstages)(struct sde_hw_ctl *ctx, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length); /** * Configure layer mixer to pipe configuration * @ctx : ctl path ctx pointer * @lm : layer mixer enumeration * @cfg : blend stage configuration * @handoff : handoff flag * @resv_pipes : reserved pipes in DT * @resv_pipes_length: array size of array reserved_pipes */ void (*setup_blendstage)(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index); enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length); /** * read CTL_TOP register value for splash case * @ctx : ctl path ctx pointer * @Return : CTL top register value */ u32 (*read_ctl_top_for_splash)(struct sde_hw_ctl *ctx); /** * read CTL layers register value for splash case * @ctx : ctl path ctx pointer * @index : layer index for this ctl path * @Return : CTL layers register value */ u32 (*read_ctl_layers_for_splash)(struct sde_hw_ctl *ctx, int index); }; /** Loading drivers/gpu/drm/msm/sde/sde_kms.c +3 −2 Original line number Diff line number Diff line Loading @@ -343,8 +343,9 @@ static void sde_kms_prepare_commit(struct msm_kms *kms, struct drm_device *dev = sde_kms->dev; struct msm_drm_private *priv = dev->dev_private; if (sde_kms->splash_info.handoff) sde_splash_clean_up_exit_lk(kms); if (sde_kms->splash_info.handoff && sde_kms->splash_info.display_splash_enabled) sde_splash_lk_stop_splash(kms); else sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); Loading Loading
drivers/gpu/drm/msm/sde/sde_connector.c +2 −11 Original line number Diff line number Diff line Loading @@ -572,8 +572,6 @@ void sde_connector_complete_commit(struct drm_connector *connector) { struct drm_device *dev; struct msm_drm_private *priv; struct sde_connector *c_conn; struct sde_kms *sde_kms; if (!connector) { SDE_ERROR("invalid connector\n"); Loading @@ -582,7 +580,6 @@ void sde_connector_complete_commit(struct drm_connector *connector) dev = connector->dev; priv = dev->dev_private; sde_kms = to_sde_kms(priv->kms); /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0); Loading @@ -590,14 +587,8 @@ void sde_connector_complete_commit(struct drm_connector *connector) /* after first vsync comes, * early splash resource should start to be released. */ if (sde_splash_get_lk_complete_status(&sde_kms->splash_info)) { c_conn = to_sde_connector(connector); sde_splash_clean_up_free_resource(priv->kms, &priv->phandle, c_conn->connector_type, c_conn->display); } if (sde_splash_get_lk_complete_status(priv->kms)) sde_splash_free_resource(priv->kms, &priv->phandle); } Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +19 −2 Original line number Diff line number Diff line Loading @@ -304,6 +304,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) struct sde_crtc_mixer *mixer = sde_crtc->mixers; struct sde_hw_ctl *ctl; struct sde_hw_mixer *lm; struct sde_splash_info *sinfo; struct sde_kms *sde_kms = _sde_crtc_get_kms(crtc); int i; Loading @@ -314,6 +316,17 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) return; } if (!sde_kms) { SDE_ERROR("invalid sde_kms\n"); return; } sinfo = &sde_kms->splash_info; if (!sinfo) { SDE_ERROR("invalid splash info\n"); return; } for (i = 0; i < sde_crtc->num_mixers; i++) { if (!mixer[i].hw_lm || !mixer[i].hw_ctl) { SDE_ERROR("invalid lm or ctl assigned to mixer\n"); Loading @@ -323,7 +336,10 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].flush_mask = 0; if (mixer[i].hw_ctl->ops.clear_all_blendstages) mixer[i].hw_ctl->ops.clear_all_blendstages( mixer[i].hw_ctl); mixer[i].hw_ctl, sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS); } /* initialize stage cfg */ Loading @@ -350,7 +366,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].flush_mask); ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, &sde_crtc->stage_cfg, i); &sde_crtc->stage_cfg, i, sinfo->handoff, sinfo->reserved_pipe_info, MAX_BLOCKS); } } Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.c +96 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -258,6 +258,35 @@ static inline int sde_hw_ctl_get_bitmask_cdm(struct sde_hw_ctl *ctx, return 0; } static inline int sde_hw_ctl_get_splash_mixercfg(const u32 *resv_pipes, u32 length) { int i = 0; u32 mixercfg = 0; for (i = 0; i < length; i++) { /* LK's splash VIG layer always stays on top */ switch (resv_pipes[i]) { case SSPP_VIG0: mixercfg |= 0x7 << 0; break; case SSPP_VIG1: mixercfg |= 0x7 << 3; break; case SSPP_VIG2: mixercfg |= 0x7 << 6; break; case SSPP_VIG3: mixercfg |= 0x7 << 26; break; default: break; } } return mixercfg; } static u32 sde_hw_ctl_poll_reset_status(struct sde_hw_ctl *ctx, u32 count) { struct sde_hw_blk_reg_map *c = &ctx->hw; Loading Loading @@ -312,15 +341,29 @@ static int sde_hw_ctl_wait_reset_status(struct sde_hw_ctl *ctx) return 0; } static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length) { struct sde_hw_blk_reg_map *c = &ctx->hw; int i; for (i = 0; i < ctx->mixer_count; i++) { int mixer_id = ctx->mixer_hw_caps[i].id; u32 mixercfg = 0; /* * if bootloaer still has early RVC running, mixer status * can't be direcly cleared. */ if (handoff) { mixercfg = sde_hw_ctl_get_splash_mixercfg(resv_pipes, resv_pipes_length); mixercfg &= SDE_REG_READ(c, CTL_LAYER(mixer_id)); } SDE_REG_WRITE(c, CTL_LAYER(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER(mixer_id), mixercfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); SDE_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); Loading @@ -328,7 +371,8 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) } static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index) enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, u32 index, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length) { struct sde_hw_blk_reg_map *c = &ctx->hw; u32 mixercfg, mixercfg_ext, mix, ext, mixercfg_ext2; Loading @@ -353,6 +397,20 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, mixercfg_ext = 0; mixercfg_ext2 = 0; /* * if bootloader still have RVC running, its mixer stauts * should be updated to kernel's mixer setup. */ if (handoff) { mixercfg = sde_hw_ctl_get_splash_mixercfg(resv_pipes, resv_pipes_length); mixercfg &= SDE_REG_READ(c, CTL_LAYER(lm)); mixercfg |= BIT(24); stages--; } for (i = 0; i <= stages; i++) { /* overflow to ext register if 'i + 1 > 7' */ mix = (i + 1) & 0x7; Loading Loading @@ -458,6 +516,38 @@ static void sde_hw_ctl_intf_cfg(struct sde_hw_ctl *ctx, SDE_REG_WRITE(c, CTL_TOP, intf_cfg); } static inline u32 sde_hw_ctl_read_ctl_top_for_splash(struct sde_hw_ctl *ctx) { struct sde_hw_blk_reg_map *c; u32 ctl_top; if (!ctx) { pr_err("Invalid ctx\n"); return 0; } c = &ctx->hw; ctl_top = SDE_REG_READ(c, CTL_TOP); return ctl_top; } static inline u32 sde_hw_ctl_read_ctl_layers_for_splash(struct sde_hw_ctl *ctx, int index) { struct sde_hw_blk_reg_map *c; u32 ctl_top; if (!ctx) { pr_err("Invalid ctx\n"); return 0; } c = &ctx->hw; ctl_top = SDE_REG_READ(c, CTL_LAYER(index)); return ctl_top; } static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, unsigned long cap) { Loading @@ -478,6 +568,8 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->get_bitmask_intf = sde_hw_ctl_get_bitmask_intf; ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm; ops->get_bitmask_wb = sde_hw_ctl_get_bitmask_wb; ops->read_ctl_top_for_splash = sde_hw_ctl_read_ctl_top_for_splash; ops->read_ctl_layers_for_splash = sde_hw_ctl_read_ctl_layers_for_splash; }; struct sde_hw_ctl *sde_hw_ctl_init(enum sde_ctl idx, Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.h +26 −3 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -146,17 +146,40 @@ struct sde_hw_ctl_ops { /** * Set all blend stages to disabled * @ctx : ctl path ctx pointer * @handoff : handoff flag * @resv_pipes : reserved pipes in DT * @resv_pipes_length: array size of array reserved_pipes */ void (*clear_all_blendstages)(struct sde_hw_ctl *ctx); void (*clear_all_blendstages)(struct sde_hw_ctl *ctx, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length); /** * Configure layer mixer to pipe configuration * @ctx : ctl path ctx pointer * @lm : layer mixer enumeration * @cfg : blend stage configuration * @handoff : handoff flag * @resv_pipes : reserved pipes in DT * @resv_pipes_length: array size of array reserved_pipes */ void (*setup_blendstage)(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index); enum sde_lm lm, struct sde_hw_stage_cfg *cfg, u32 index, bool handoff, const u32 *resv_pipes, u32 resv_pipes_length); /** * read CTL_TOP register value for splash case * @ctx : ctl path ctx pointer * @Return : CTL top register value */ u32 (*read_ctl_top_for_splash)(struct sde_hw_ctl *ctx); /** * read CTL layers register value for splash case * @ctx : ctl path ctx pointer * @index : layer index for this ctl path * @Return : CTL layers register value */ u32 (*read_ctl_layers_for_splash)(struct sde_hw_ctl *ctx, int index); }; /** Loading
drivers/gpu/drm/msm/sde/sde_kms.c +3 −2 Original line number Diff line number Diff line Loading @@ -343,8 +343,9 @@ static void sde_kms_prepare_commit(struct msm_kms *kms, struct drm_device *dev = sde_kms->dev; struct msm_drm_private *priv = dev->dev_private; if (sde_kms->splash_info.handoff) sde_splash_clean_up_exit_lk(kms); if (sde_kms->splash_info.handoff && sde_kms->splash_info.display_splash_enabled) sde_splash_lk_stop_splash(kms); else sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); Loading