diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 8a0a48c255..14ff8519aa 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -7419,9 +7419,18 @@ void sde_crtc_static_img_control(struct drm_crtc *crtc, return; } + if (test_bit(SDE_SYS_CACHE_DISP_1, sde_kms->catalog->sde_sys_cache_type_map)) { + if (state == CACHE_STATE_FRAME_WRITE) + sde_crtc->cache_type = (sde_crtc->cache_type == SDE_SYS_CACHE_DISP) ? + SDE_SYS_CACHE_DISP_1 : SDE_SYS_CACHE_DISP; + } else { + sde_crtc->cache_type = SDE_SYS_CACHE_DISP; + } + SDE_EVT32(DRMID(crtc), state, sde_crtc->cache_state, sde_crtc->cache_type); + sde_crtc->cache_state = state; drm_atomic_crtc_for_each_plane(plane, crtc) - sde_plane_static_img_control(plane, state); + sde_plane_static_img_control(plane, sde_crtc->cache_state, sde_crtc->cache_type); } /* diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index e32219d274..9c5120840f 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -308,6 +308,7 @@ struct sde_frame_data { * @target_bpp : target bpp used to calculate compression ratio * @static_cache_read_work: delayed worker to transition cache state to read * @cache_state : Current static image cache state + * @cache_type : Current static image cache type to use * @dspp_blob_info : blob containing dspp hw capability information * @cached_encoder_mask : cached encoder_mask for vblank work * @valid_skip_blend_plane: flag to indicate if skip blend plane is valid @@ -410,6 +411,7 @@ struct sde_crtc { struct kthread_delayed_work static_cache_read_work; enum sde_sys_cache_state cache_state; + enum sde_sys_cache_type cache_type; struct drm_property_blob *dspp_blob_info; u32 cached_encoder_mask; diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index 82acf8b0ef..1e4681845c 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -446,7 +446,7 @@ struct sde_encoder_phys_cmd { * @bo_disable: Buffer object(s) to use during the disabling state * @fb_disable: Frame buffer to use during the disabling state * @sc_cfg: Stores wb system cache config - * @crtc Pointer to drm_crtc + * @crtc: Pointer to drm_crtc * @prog_line: Cached programmable line value used to trigger early wb-fence */ struct sde_encoder_phys_wb { diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 443a79e7c1..acd139d173 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1097,16 +1097,19 @@ static void _sde_encoder_phys_wb_setup_sys_cache(struct sde_encoder_phys *phys_e } /* - * - use LLCC_DISP for cwb static display - * - use LLCC_DISP_1 for cwb static display read path only + * - use LLCC_DISP/LLCC_DISP_1 for cwb static display * - use LLCC_DISP_WB for 2-pass composition using offline-wb */ if (phys_enc->in_clone_mode) { - cache_rd_type = SDE_SYS_CACHE_DISP; - if (test_bit(SDE_SYS_CACHE_DISP_1, hw_wb->catalog->sde_sys_cache_type_map)) + /* toggle system cache SCID between consecutive CWB writes */ + if (test_bit(SDE_SYS_CACHE_DISP_1, hw_wb->catalog->sde_sys_cache_type_map) + && cfg->type == SDE_SYS_CACHE_DISP) { cache_wr_type = SDE_SYS_CACHE_DISP_1; - else + cache_rd_type = SDE_SYS_CACHE_DISP_1; + } else { cache_wr_type = SDE_SYS_CACHE_DISP; + cache_rd_type = SDE_SYS_CACHE_DISP; + } } else { cache_rd_type = SDE_SYS_CACHE_DISP_WB; cache_wr_type = SDE_SYS_CACHE_DISP_WB; @@ -2212,6 +2215,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); struct sde_hw_wb *hw_wb = wb_enc->hw_wb; struct sde_crtc *sde_crtc = to_sde_crtc(wb_enc->crtc); + struct sde_hw_wb_sc_cfg cfg = { 0 }; int i; if (phys_enc->enable_state == SDE_ENC_DISABLED) { @@ -2233,9 +2237,8 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) /* reset system cache properties */ if (wb_enc->sc_cfg.wr_en) { - memset(&wb_enc->sc_cfg, 0, sizeof(struct sde_hw_wb_sc_cfg)); if (hw_wb->ops.setup_sys_cache) - hw_wb->ops.setup_sys_cache(hw_wb, &wb_enc->sc_cfg); + hw_wb->ops.setup_sys_cache(hw_wb, &cfg); /* * avoid llcc_active reset for crtc while in clone mode as it will reset it for diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index b209d9c596..3de7cd0a69 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -5152,6 +5152,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) set_bit(SDE_SYS_CACHE_DISP, sde_cfg->sde_sys_cache_type_map); set_bit(SDE_SYS_CACHE_DISP_1, sde_cfg->sde_sys_cache_type_map); set_bit(SDE_SYS_CACHE_DISP_WB, sde_cfg->sde_sys_cache_type_map); + set_bit(SDE_FEATURE_SYS_CACHE_NSE, sde_cfg->features); sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH; sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2; sde_cfg->perf.min_prefill_lines = 40; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index b0a8adb968..aac0d8a829 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -720,6 +720,7 @@ enum { * @SDE_FEATURE_UBWC_STATS UBWC statistics supported * @SDE_FEATURE_VBIF_CLK_SPLIT VBIF clock split supported * @SDE_FEATURE_CTL_DONE Support for CTL DONE irq + * @SDE_FEATURE_SYS_CACHE_NSE Support for no-self-evict feature * @SDE_FEATURE_MAX: MAX features value */ enum sde_mdss_features { @@ -759,6 +760,7 @@ enum sde_mdss_features { SDE_FEATURE_UBWC_STATS, SDE_FEATURE_VBIF_CLK_SPLIT, SDE_FEATURE_CTL_DONE, + SDE_FEATURE_SYS_CACHE_NSE, SDE_FEATURE_MAX }; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 880f5389ce..b4c68c48cb 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1557,6 +1557,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms, static void sde_kms_wait_for_commit_done(struct msm_kms *kms, struct drm_crtc *crtc) { + struct sde_kms *sde_kms; struct drm_encoder *encoder; struct drm_device *dev; int ret; @@ -1568,6 +1569,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, } dev = crtc->dev; + sde_kms = to_sde_kms(kms); if (!crtc->state->enable) { SDE_DEBUG("[crtc:%d] not enable\n", crtc->base.id); @@ -1614,7 +1616,9 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, sde_encoder_virt_reset(encoder); } - sde_crtc_static_cache_read_kickoff(crtc); + /* avoid system cache update to set rd-noalloc bit when NSE feature is enabled */ + if (!test_bit(SDE_FEATURE_SYS_CACHE_NSE, sde_kms->catalog->features)) + sde_crtc_static_cache_read_kickoff(crtc); SDE_ATRACE_END("sde_ksm_wait_for_commit_done"); } diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 8b622e4c3b..1dcd618f5e 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2853,22 +2853,23 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde, struct sde_hw_pipe_sc_cfg *cfg = &pstate->sc_cfg; bool prev_rd_en = cfg->rd_en; u32 cache_flag, cache_rd_type, cache_wr_type; + enum sde_sys_cache_state cache_state; if (!state->fb) { SDE_ERROR("invalid fb on plane %d\n", DRMID(&psde->base)); return; } + cache_state = pstate->static_cache_state; msm_framebuffer_get_cache_hint(state->fb, &cache_flag, &cache_rd_type, &cache_wr_type); cfg->rd_en = false; cfg->rd_scid = 0x0; cfg->flags = SYS_CACHE_EN_FLAG | SYS_CACHE_SCID; - cfg->type = SDE_SYS_CACHE_NONE; /* * if condition handles static display legacy path, where internal state machine is - * transitioning the "static_cache_state" variable to program the LLCC cache through + * transitioning the "cache_state" variable to program the LLCC cache through * SSPP hardware using SDE_SYS_CACHE_DISP SCID. * else condition handles static display and IWE path, were the frame is programmed to * LLCC cache through WB/CWB path and read back by SSPP hardware. The FB cache hints are @@ -2876,17 +2877,23 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde, * keep active. */ if (test_bit(SDE_SYS_CACHE_DISP, psde->catalog->sde_sys_cache_type_map) - && ((pstate->static_cache_state == CACHE_STATE_FRAME_WRITE) - || (pstate->static_cache_state == CACHE_STATE_FRAME_READ))) { + && ((cache_state == CACHE_STATE_FRAME_WRITE) + || (cache_state == CACHE_STATE_FRAME_READ))) { + cfg->type = pstate->static_cache_type; cfg->rd_en = true; - cfg->rd_scid = sc_cfg[SDE_SYS_CACHE_DISP].llcc_scid; - cfg->rd_noallocate = (pstate->static_cache_state == CACHE_STATE_FRAME_READ); + cfg->rd_scid = sc_cfg[cfg->type].llcc_scid; + if (test_bit(SDE_FEATURE_SYS_CACHE_NSE, psde->catalog->features)) { + cfg->rd_noallocate = false; + pstate->static_cache_state = CACHE_STATE_NORMAL; + } else { + cfg->rd_noallocate = (cache_state == CACHE_STATE_FRAME_READ); + } cfg->flags |= SYS_CACHE_NO_ALLOC; - cfg->type = SDE_SYS_CACHE_DISP; } else if (test_bit(cache_rd_type, psde->catalog->sde_sys_cache_type_map) && cache_flag) { cfg->rd_en = true; + cfg->type = cache_rd_type; cfg->rd_scid = sc_cfg[cache_rd_type].llcc_scid; - cfg->rd_noallocate = true; + cfg->rd_noallocate = false; cfg->flags |= SYS_CACHE_NO_ALLOC; cache_flag = MSM_FB_CACHE_READ_EN; @@ -2896,13 +2903,14 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde, if (!cfg->rd_en && !prev_rd_en) return; - SDE_EVT32(DRMID(&psde->base), cfg->rd_scid, cfg->rd_en, cfg->rd_noallocate, cfg->flags, - cache_flag, cache_rd_type, cache_wr_type, state->fb->base.id); + SDE_EVT32(DRMID(&psde->base), cfg->type, cfg->rd_scid, cfg->rd_en, cfg->rd_noallocate, + cfg->flags, cache_state, cache_flag, cache_rd_type, cache_wr_type, + state->fb->base.id); psde->pipe_hw->ops.setup_sys_cache(psde->pipe_hw, cfg); } void sde_plane_static_img_control(struct drm_plane *plane, - enum sde_sys_cache_state state) + enum sde_sys_cache_state state, enum sde_sys_cache_type type) { struct sde_plane *psde; struct sde_plane_state *pstate; @@ -2916,6 +2924,7 @@ void sde_plane_static_img_control(struct drm_plane *plane, pstate = to_sde_plane_state(plane->state); pstate->static_cache_state = state; + pstate->static_cache_type = type; if (state == CACHE_STATE_FRAME_WRITE || state == CACHE_STATE_FRAME_READ) _sde_plane_sspp_setup_sys_cache(psde, pstate); diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index 9056fa7843..3d518246f7 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -144,6 +144,7 @@ struct sde_plane_state { struct sde_hw_pipe_sc_cfg sc_cfg; uint32_t rotation; uint32_t static_cache_state; + uint32_t static_cache_type; struct sde_hw_pipe_cdp_cfg cdp_cfg; @@ -359,9 +360,10 @@ bool sde_plane_is_cache_required(struct drm_plane *plane, * sde_plane_static_img_control - Switch the static image state * @plane: Pointer to drm plane structure * @state: state to set + * @type: cache type to set */ void sde_plane_static_img_control(struct drm_plane *plane, - enum sde_sys_cache_state state); + enum sde_sys_cache_state state, enum sde_sys_cache_type type); void sde_plane_add_data_to_minidump_va(struct drm_plane *plane); #endif /* _SDE_PLANE_H_ */