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 <veeras@codeaurora.org>
This commit is contained in:
@@ -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 */
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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_ */
|
||||
|
@@ -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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user