From 993f61c91dbfbb6ff433f9577e06b0c5a6fadf54 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 22 Jul 2021 10:46:46 -0700 Subject: [PATCH] disp: msm: sde: expose system cache support for writeback Add a custom cache_enable property in writeback connector to allow user-mode to control the cache setting on a frame basis. Configure the hw and activate/deactivate the llcc based on the property. The custom property is added based on the availability of the system cache for writeback. Change-Id: I812b31955eb36c75c33ac279b56502a13f7cdcbf Signed-off-by: Veera Sundaram Sankaran --- msm/msm_drv.h | 1 + msm/sde/sde_crtc.c | 2 +- msm/sde/sde_crtc.h | 22 ++----------- msm/sde/sde_encoder_phys.h | 2 ++ msm/sde/sde_encoder_phys_wb.c | 58 +++++++++++++++++++++++++++++++++++ msm/sde/sde_hw_mdss.h | 18 +++++++++++ msm/sde/sde_plane.c | 2 +- msm/sde/sde_plane.h | 2 +- msm/sde/sde_wb.c | 25 ++++++++++++++- 9 files changed, 108 insertions(+), 24 deletions(-) diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 04cd4c2e41..a4961fcdcd 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -230,6 +230,7 @@ enum msm_mdp_conn_property { CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE, CONNECTOR_PROP_SET_PANEL_MODE, CONNECTOR_PROP_AVR_STEP, + CONNECTOR_PROP_CACHE_STATE, CONNECTOR_PROP_DSC_MODE, /* total # of properties */ diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 1a380c1a1e..41cafc67cc 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -7004,7 +7004,7 @@ static int _sde_crtc_init_events(struct sde_crtc *sde_crtc) } void sde_crtc_static_img_control(struct drm_crtc *crtc, - enum sde_crtc_cache_state state, + enum sde_sys_cache_state state, bool is_vidmode) { struct drm_plane *plane; diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index e6c5b90fd8..729510836e 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -75,24 +75,6 @@ enum sde_crtc_idle_pc_state { IDLE_PC_DISABLE, }; -/** - * enum sde_crtc_cache_state: states of disp system cache - * CACHE_STATE_DISABLED: sys cache has been disabled - * CACHE_STATE_ENABLED: sys cache has been enabled - * CACHE_STATE_NORMAL: sys cache is normal state - * CACHE_STATE_PRE_CACHE: frame cache is being prepared - * CACHE_STATE_FRAME_WRITE: sys cache is being written to - * CACHE_STATE_FRAME_READ: sys cache is being read - */ -enum sde_crtc_cache_state { - CACHE_STATE_DISABLED, - CACHE_STATE_ENABLED, - CACHE_STATE_NORMAL, - CACHE_STATE_PRE_CACHE, - CACHE_STATE_FRAME_WRITE, - CACHE_STATE_FRAME_READ -}; - /** * enum sde_crtc_vm_req: request for VM operations * @VM_REQ_NONE: no request. Normal VM operations. @@ -426,7 +408,7 @@ struct sde_crtc { int target_bpp; struct kthread_delayed_work static_cache_read_work; - enum sde_crtc_cache_state cache_state; + enum sde_sys_cache_state cache_state; struct drm_property_blob *dspp_blob_info; u32 cached_encoder_mask; @@ -1031,7 +1013,7 @@ static inline void sde_crtc_set_bpp(struct sde_crtc *sde_crtc, int src_bpp, * @is_vidmode: if encoder is video mode */ void sde_crtc_static_img_control(struct drm_crtc *crtc, - enum sde_crtc_cache_state state, bool is_vidmode); + enum sde_sys_cache_state state, bool is_vidmode); /** * sde_crtc_static_cache_read_kickoff - kickoff cache read work diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index 97a1ae41c7..7595b7052a 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -436,6 +436,7 @@ struct sde_encoder_phys_cmd { * @wb_dev: Pointer to writeback device * @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 * @prog_line: Cached programmable line value used to trigger early wb-fence */ @@ -455,6 +456,7 @@ struct sde_encoder_phys_wb { struct sde_wb_device *wb_dev; struct drm_gem_object *bo_disable[SDE_MAX_PLANES]; struct drm_framebuffer *fb_disable; + struct sde_hw_wb_sc_cfg sc_cfg; struct drm_crtc *crtc; u32 prog_line; }; diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 617ce3d342..1eaa92d61e 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -961,6 +961,49 @@ static int sde_encoder_phys_wb_atomic_check( return rc; } +static void _sde_encoder_phys_wb_setup_cache(struct sde_encoder_phys_wb *wb_enc) +{ + struct sde_wb_device *wb_dev = wb_enc->wb_dev; + struct drm_connector_state *state = wb_dev->connector->state; + struct sde_hw_wb *hw_wb = wb_enc->hw_wb; + struct sde_crtc *sde_crtc = to_sde_crtc(wb_enc->crtc); + struct sde_sc_cfg *sc_cfg = &hw_wb->catalog->sc_cfg[SDE_SYS_CACHE_DISP_WB]; + struct sde_hw_wb_sc_cfg *cfg = &wb_enc->sc_cfg; + u32 cache_enable; + + if (!sc_cfg->has_sys_cache) { + SDE_DEBUG("sys cache feature not enabled\n"); + return; + } + + if (!hw_wb || !hw_wb->ops.setup_sys_cache) { + SDE_DEBUG("unsupported ops: setup_sys_cache WB %d\n", WBID(wb_enc)); + return; + } + + cache_enable = sde_connector_get_property(state, CONNECTOR_PROP_CACHE_STATE); + + if (!cfg->wr_en && !cache_enable) + return; + + cfg->wr_en = cache_enable; + cfg->flags = SYS_CACHE_EN_FLAG | SYS_CACHE_SCID; + + if (cache_enable) { + cfg->wr_scid = sc_cfg->llcc_scid; + cfg->type = SDE_SYS_CACHE_DISP_WB; + } else { + cfg->wr_scid = 0x0; + cfg->type = SDE_SYS_CACHE_NONE; + } + + sde_crtc->new_perf.llcc_active[SDE_SYS_CACHE_DISP_WB] = cache_enable; + sde_core_perf_crtc_update_llcc(wb_enc->crtc); + + hw_wb->ops.setup_sys_cache(hw_wb, cfg); + SDE_EVT32(WBID(wb_enc), cfg->wr_scid, cfg->flags, cfg->type, cache_enable); +} + static void _sde_encoder_phys_wb_update_cwb_flush( struct sde_encoder_phys *phys_enc, bool enable) { @@ -1236,6 +1279,8 @@ static void sde_encoder_phys_wb_setup( sde_encoder_phys_wb_setup_cdp(phys_enc, wb_enc->wb_fmt); + _sde_encoder_phys_wb_setup_cache(wb_enc); + _sde_encoder_phys_wb_setup_cwb(phys_enc, true); _sde_encoder_phys_wb_setup_prog_line(phys_enc); @@ -1915,6 +1960,8 @@ 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); + int i; if (phys_enc->enable_state == SDE_ENC_DISABLED) { SDE_ERROR("encoder is already disabled\n"); @@ -1931,6 +1978,17 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) goto exit; } + /* 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); + + for (i = 0; i < SDE_SYS_CACHE_MAX; i++) + sde_crtc->new_perf.llcc_active[i] = 0; + sde_core_perf_crtc_update_llcc(wb_enc->crtc); + } + if (phys_enc->in_clone_mode) { _sde_encoder_phys_wb_setup_cwb(phys_enc, false); _sde_encoder_phys_wb_update_cwb_flush(phys_enc, false); diff --git a/msm/sde/sde_hw_mdss.h b/msm/sde/sde_hw_mdss.h index 11be954c2e..30b77daece 100644 --- a/msm/sde/sde_hw_mdss.h +++ b/msm/sde/sde_hw_mdss.h @@ -468,6 +468,24 @@ enum sde_3d_blend_mode { BLEND_3D_MAX }; +/** + * enum sde_sys_cache_state: states of disp system cache + * CACHE_STATE_DISABLED: sys cache has been disabled + * CACHE_STATE_ENABLED: sys cache has been enabled + * CACHE_STATE_NORMAL: sys cache is normal state + * CACHE_STATE_PRE_CACHE: frame cache is being prepared + * CACHE_STATE_FRAME_WRITE: sys cache is being written to + * CACHE_STATE_FRAME_READ: sys cache is being read + */ +enum sde_sys_cache_state { + CACHE_STATE_DISABLED, + CACHE_STATE_ENABLED, + CACHE_STATE_NORMAL, + CACHE_STATE_PRE_CACHE, + CACHE_STATE_FRAME_WRITE, + CACHE_STATE_FRAME_READ +}; + /** struct sde_format - defines the format configuration which * allows SDE HW to correctly fetch and decode the format * @base: base msm_format struture containing fourcc code diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index a9599a2984..4e99c6f6f4 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2812,7 +2812,7 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde, } void sde_plane_static_img_control(struct drm_plane *plane, - enum sde_crtc_cache_state state) + enum sde_sys_cache_state state) { struct sde_plane *psde; struct sde_plane_state *pstate; diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index 56617b9a25..af3669ae2d 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -356,7 +356,7 @@ bool sde_plane_is_cache_required(struct drm_plane *plane, * @state: state to set */ void sde_plane_static_img_control(struct drm_plane *plane, - enum sde_crtc_cache_state state); + enum sde_sys_cache_state state); void sde_plane_add_data_to_minidump_va(struct drm_plane *plane); #endif /* _SDE_PLANE_H_ */ diff --git a/msm/sde/sde_wb.c b/msm/sde/sde_wb.c index 79e7899c6c..8f4cafcb73 100644 --- a/msm/sde/sde_wb.c +++ b/msm/sde/sde_wb.c @@ -530,20 +530,43 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display) { struct sde_connector *c_conn; struct sde_wb_device *wb_dev = display; + struct msm_drm_private *priv; + struct sde_kms *sde_kms; + struct sde_mdss_cfg *catalog; + struct sde_sc_cfg *sde_cfg; static const struct drm_prop_enum_list e_fb_translation_mode[] = { {SDE_DRM_FB_NON_SEC, "non_sec"}, {SDE_DRM_FB_SEC, "sec"}, }; + static const struct drm_prop_enum_list e_cache_state[] = { + {CACHE_STATE_DISABLED, "cache_state_disabled"}, + {CACHE_STATE_ENABLED, "cache_state_enabled"}, + }; - if (!connector || !display || !wb_dev->wb_cfg) { + if (!connector || !display || !wb_dev->wb_cfg || !wb_dev->drm_dev->dev_private) { SDE_ERROR("invalid params\n"); return -EINVAL; } + priv = wb_dev->drm_dev->dev_private; + sde_kms = to_sde_kms(priv->kms); + if (!sde_kms || !sde_kms->catalog) { + SDE_ERROR("invalid sde_kms\n"); + return -EINVAL; + } + + catalog = sde_kms->catalog; + sde_cfg = &catalog->sc_cfg[SDE_SYS_CACHE_DISP_WB]; + c_conn = to_sde_connector(connector); wb_dev->connector = connector; wb_dev->detect_status = connector_status_connected; + if (sde_cfg->has_sys_cache) + msm_property_install_enum(&c_conn->property_info, "cache_state", + 0x0, 0, e_cache_state, ARRAY_SIZE(e_cache_state), + 0, CONNECTOR_PROP_CACHE_STATE); + /* * Add extra connector properties */