disp: msm: sde: add support for LLCC_DISP_1 SCID

Currently only LLCC_DISP SCID is used to read and write to
system cache during static display use case.

This changes adds SCID LLCC_DISP_1 to allow each SCID to
have a dedicated function (read/write).

Change-Id: I5604ec1183d99a8492b005ec06ac94e5db60b5f7
Signed-off-by: Amine Najahi <quic_anajahi@quicinc.com>
This commit is contained in:
Amine Najahi
2022-04-22 10:41:19 -04:00
parent 50092909c0
commit bffdc0271d
7 changed files with 98 additions and 43 deletions

View File

@@ -1260,8 +1260,10 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
struct drm_gem_object **bos); struct drm_gem_object **bos);
struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd); struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
void msm_framebuffer_set_cache_hint(struct drm_framebuffer *fb, u32 flags, u32 type); int msm_framebuffer_set_cache_hint(struct drm_framebuffer *fb,
void msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb, u32 *flags, u32 *type); u32 flags, u32 rd_type, u32 wr_type);
int msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb,
u32 *flags, u32 *rd_type, u32 *wr_type);
struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
void msm_fbdev_free(struct drm_device *dev); void msm_fbdev_free(struct drm_device *dev);

View File

@@ -31,7 +31,8 @@ struct msm_framebuffer {
struct drm_framebuffer base; struct drm_framebuffer base;
const struct msm_format *format; const struct msm_format *format;
u32 cache_flags; u32 cache_flags;
u32 cache_type; u32 cache_rd_type;
u32 cache_wr_type;
}; };
#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
@@ -284,29 +285,34 @@ fail:
return ERR_PTR(ret); return ERR_PTR(ret);
} }
void msm_framebuffer_set_cache_hint(struct drm_framebuffer *fb, u32 flags, u32 type) int msm_framebuffer_set_cache_hint(struct drm_framebuffer *fb,
u32 flags, u32 rd_type, u32 wr_type)
{ {
struct msm_framebuffer *msm_fb; struct msm_framebuffer *msm_fb;
if (!fb) if (!fb)
return; return -EINVAL;
msm_fb = to_msm_framebuffer(fb); msm_fb = to_msm_framebuffer(fb);
msm_fb->cache_flags = flags; msm_fb->cache_flags = flags;
msm_fb->cache_type = type; msm_fb->cache_rd_type = rd_type;
msm_fb->cache_wr_type = wr_type;
return 0;
} }
void msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb, u32 *flags, u32 *type) int msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb,
u32 *flags, u32 *rd_type, u32 *wr_type)
{ {
struct msm_framebuffer *msm_fb; struct msm_framebuffer *msm_fb;
if (!fb) { if (!fb)
*flags = 0; return -EINVAL;
*type = 0;
return;
}
msm_fb = to_msm_framebuffer(fb); msm_fb = to_msm_framebuffer(fb);
*flags = msm_fb->cache_flags; *flags = msm_fb->cache_flags;
*type = msm_fb->cache_type; *rd_type = msm_fb->cache_rd_type;
*wr_type = msm_fb->cache_wr_type;
return 0;
} }

View File

@@ -389,8 +389,7 @@ static void _sde_core_perf_crtc_set_llcc_cache_type(struct sde_kms *kms,
u32 llcc_active = 0; u32 llcc_active = 0;
if (!test_bit(type, kms->perf.catalog->sde_sys_cache_type_map)) { if (!test_bit(type, kms->perf.catalog->sde_sys_cache_type_map)) {
SDE_DEBUG("System Cache %d is not enabled!. Won't use\n", SDE_DEBUG("system cache %d is not enabled!. Won't use\n", type);
type);
return; return;
} }

View File

@@ -1074,7 +1074,7 @@ static int sde_encoder_phys_wb_atomic_check(struct sde_encoder_phys *phys_enc,
return rc; return rc;
} }
static void _sde_encoder_phys_wb_setup_cache(struct sde_encoder_phys *phys_enc, static void _sde_encoder_phys_wb_setup_sys_cache(struct sde_encoder_phys *phys_enc,
struct drm_framebuffer *fb) struct drm_framebuffer *fb)
{ {
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
@@ -1084,17 +1084,32 @@ static void _sde_encoder_phys_wb_setup_cache(struct sde_encoder_phys *phys_enc,
struct sde_crtc *sde_crtc = to_sde_crtc(wb_enc->crtc); struct sde_crtc *sde_crtc = to_sde_crtc(wb_enc->crtc);
struct sde_sc_cfg *sc_cfg; struct sde_sc_cfg *sc_cfg;
struct sde_hw_wb_sc_cfg *cfg = &wb_enc->sc_cfg; struct sde_hw_wb_sc_cfg *cfg = &wb_enc->sc_cfg;
u32 cache_enable, cache_type; u32 cache_enable, cache_flag, cache_rd_type, cache_wr_type;
if (!fb) {
SDE_ERROR("invalid fb on wb %d\n", WBID(wb_enc));
return;
}
/* /*
* - use LLCC_DISP for cwb static display * - use LLCC_DISP for cwb static display
* - use LLCC_DISP_1 for cwb static display read path only
* - use LLCC_DISP_WB for 2-pass composition using offline-wb * - use LLCC_DISP_WB for 2-pass composition using offline-wb
*/ */
cache_type = phys_enc->in_clone_mode ? SDE_SYS_CACHE_DISP : SDE_SYS_CACHE_DISP_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))
cache_wr_type = SDE_SYS_CACHE_DISP_1;
else
cache_wr_type = SDE_SYS_CACHE_DISP;
} else {
cache_rd_type = SDE_SYS_CACHE_DISP_WB;
cache_wr_type = SDE_SYS_CACHE_DISP_WB;
}
sc_cfg = &hw_wb->catalog->sc_cfg[cache_type]; sc_cfg = &hw_wb->catalog->sc_cfg[cache_wr_type];
if (!test_bit(cache_type, hw_wb->catalog->sde_sys_cache_type_map)) { if (!test_bit(cache_wr_type, hw_wb->catalog->sde_sys_cache_type_map)) {
SDE_DEBUG("sys cache type %d not enabled\n", cache_type); SDE_DEBUG("sys cache type %d not enabled\n", cache_wr_type);
return; return;
} }
@@ -1113,25 +1128,31 @@ static void _sde_encoder_phys_wb_setup_cache(struct sde_encoder_phys *phys_enc,
if (cache_enable) { if (cache_enable) {
cfg->wr_scid = sc_cfg->llcc_scid; cfg->wr_scid = sc_cfg->llcc_scid;
cfg->type = cache_type; cfg->type = cache_wr_type;
msm_framebuffer_set_cache_hint(fb, MSM_FB_CACHE_WRITE_EN, cache_type); cache_flag = MSM_FB_CACHE_WRITE_EN;
} else { } else {
cfg->wr_scid = 0x0; cfg->wr_scid = 0x0;
cfg->type = SDE_SYS_CACHE_NONE; cfg->type = SDE_SYS_CACHE_NONE;
msm_framebuffer_set_cache_hint(fb, MSM_FB_CACHE_NONE, SDE_SYS_CACHE_NONE); cache_flag = MSM_FB_CACHE_NONE;
cache_rd_type = SDE_SYS_CACHE_NONE;
cache_wr_type = SDE_SYS_CACHE_NONE;
} }
msm_framebuffer_set_cache_hint(fb, cache_flag, cache_rd_type, cache_wr_type);
/* /*
* avoid llcc_active reset for crtc while in clone mode as it will reset it for * avoid llcc_active reset for crtc while in clone mode as it will reset it for
* primary display as well * primary display as well
*/ */
if (cache_enable || !phys_enc->in_clone_mode) { if (cache_enable || !phys_enc->in_clone_mode) {
sde_crtc->new_perf.llcc_active[cache_type] = cache_enable; sde_crtc->new_perf.llcc_active[cache_wr_type] = cache_enable;
sde_crtc->new_perf.llcc_active[cache_rd_type] = cache_enable;
sde_core_perf_crtc_update_llcc(wb_enc->crtc); sde_core_perf_crtc_update_llcc(wb_enc->crtc);
} }
hw_wb->ops.setup_sys_cache(hw_wb, cfg); hw_wb->ops.setup_sys_cache(hw_wb, cfg);
SDE_EVT32(WBID(wb_enc), cfg->wr_scid, cfg->flags, cfg->type, cache_enable); SDE_EVT32(WBID(wb_enc), cfg->wr_scid, cfg->flags, cfg->type, cache_enable,
phys_enc->in_clone_mode, cache_flag, cache_rd_type,
cache_wr_type, fb->base.id);
} }
static void _sde_encoder_phys_wb_update_cwb_flush_helper( static void _sde_encoder_phys_wb_update_cwb_flush_helper(
@@ -1493,7 +1514,7 @@ static void sde_encoder_phys_wb_setup(struct sde_encoder_phys *phys_enc)
_sde_encoder_phys_wb_setup_ctl(phys_enc, wb_enc->wb_fmt); _sde_encoder_phys_wb_setup_ctl(phys_enc, wb_enc->wb_fmt);
_sde_encoder_phys_wb_setup_cache(phys_enc, fb); _sde_encoder_phys_wb_setup_sys_cache(phys_enc, fb);
_sde_encoder_phys_wb_setup_cwb(phys_enc, true); _sde_encoder_phys_wb_setup_cwb(phys_enc, true);

View File

@@ -3488,11 +3488,13 @@ static int sde_cache_parse_dt(struct device_node *np,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
const u32 sde_sys_cache_usecase_id[SDE_SYS_CACHE_MAX] = { const u32 sde_sys_cache_usecase_id[SDE_SYS_CACHE_MAX] = {
[SDE_SYS_CACHE_DISP] = LLCC_DISP, [SDE_SYS_CACHE_DISP] = LLCC_DISP,
[SDE_SYS_CACHE_DISP_1] = LLCC_DISP_1,
[SDE_SYS_CACHE_DISP_WB] = LLCC_DISP_WB, [SDE_SYS_CACHE_DISP_WB] = LLCC_DISP_WB,
}; };
#else #else
const u32 sde_sys_cache_usecase_id[SDE_SYS_CACHE_MAX] = { const u32 sde_sys_cache_usecase_id[SDE_SYS_CACHE_MAX] = {
[SDE_SYS_CACHE_DISP] = LLCC_DISP, [SDE_SYS_CACHE_DISP] = LLCC_DISP,
[SDE_SYS_CACHE_DISP_1] = 0,
[SDE_SYS_CACHE_DISP_WB] = 0, [SDE_SYS_CACHE_DISP_WB] = 0,
}; };
#endif #endif
@@ -5148,6 +5150,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
set_bit(SDE_FEATURE_CTL_DONE, sde_cfg->features); set_bit(SDE_FEATURE_CTL_DONE, sde_cfg->features);
set_bit(SDE_FEATURE_TRUSTED_VM, sde_cfg->features); set_bit(SDE_FEATURE_TRUSTED_VM, sde_cfg->features);
set_bit(SDE_SYS_CACHE_DISP, sde_cfg->sde_sys_cache_type_map); 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_SYS_CACHE_DISP_WB, sde_cfg->sde_sys_cache_type_map);
sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH; sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH;
sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2; sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2;

View File

@@ -205,12 +205,15 @@ enum {
/** /**
* sde_sys_cache_type: Types of system cache supported * sde_sys_cache_type: Types of system cache supported
* SDE_SYS_CACHE_DISP: Static img system cache * SDE_SYS_CACHE_DISP: System cache for static display read/write path use case
* SDE_SYS_CACHE_MAX: Maximum number of sys cache users * SDE_SYS_CACHE_DISP_1: System cache for static display write path use case
* SDE_SYS_CACHE_NONE: Sys cache not used * SDE_SYS_CACHE_DISP_WB: System cache for IWE use case
* SDE_SYS_CACHE_MAX: Maximum number of system cache users
* SDE_SYS_CACHE_NONE: System cache not used
*/ */
enum sde_sys_cache_type { enum sde_sys_cache_type {
SDE_SYS_CACHE_DISP, SDE_SYS_CACHE_DISP,
SDE_SYS_CACHE_DISP_1,
SDE_SYS_CACHE_DISP_WB, SDE_SYS_CACHE_DISP_WB,
SDE_SYS_CACHE_MAX, SDE_SYS_CACHE_MAX,
SDE_SYS_CACHE_NONE = SDE_SYS_CACHE_MAX SDE_SYS_CACHE_NONE = SDE_SYS_CACHE_MAX

View File

@@ -2852,16 +2852,30 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde,
struct sde_sc_cfg *sc_cfg = psde->catalog->sc_cfg; struct sde_sc_cfg *sc_cfg = psde->catalog->sc_cfg;
struct sde_hw_pipe_sc_cfg *cfg = &pstate->sc_cfg; struct sde_hw_pipe_sc_cfg *cfg = &pstate->sc_cfg;
bool prev_rd_en = cfg->rd_en; bool prev_rd_en = cfg->rd_en;
u32 fb_cache_flag, fb_cache_type; u32 cache_flag, cache_rd_type, cache_wr_type;
msm_framebuffer_get_cache_hint(state->fb, &fb_cache_flag, &fb_cache_type); if (!state->fb) {
SDE_ERROR("invalid fb on plane %d\n", DRMID(&psde->base));
return;
}
msm_framebuffer_get_cache_hint(state->fb, &cache_flag, &cache_rd_type, &cache_wr_type);
cfg->rd_en = false; cfg->rd_en = false;
cfg->rd_scid = 0x0; cfg->rd_scid = 0x0;
cfg->flags = SYS_CACHE_EN_FLAG | SYS_CACHE_SCID; cfg->flags = SYS_CACHE_EN_FLAG | SYS_CACHE_SCID;
cfg->type = SDE_SYS_CACHE_NONE; cfg->type = SDE_SYS_CACHE_NONE;
if ((test_bit(SDE_SYS_CACHE_DISP, psde->catalog->sde_sys_cache_type_map)) /*
* if condition handles static display legacy path, where internal state machine is
* transitioning the "static_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
* used to pass information on which SCID to use during read path and LLCC cache to
* 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_WRITE)
|| (pstate->static_cache_state == CACHE_STATE_FRAME_READ))) { || (pstate->static_cache_state == CACHE_STATE_FRAME_READ))) {
cfg->rd_en = true; cfg->rd_en = true;
@@ -2869,23 +2883,21 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde,
cfg->rd_noallocate = (pstate->static_cache_state == CACHE_STATE_FRAME_READ); cfg->rd_noallocate = (pstate->static_cache_state == CACHE_STATE_FRAME_READ);
cfg->flags |= SYS_CACHE_NO_ALLOC; cfg->flags |= SYS_CACHE_NO_ALLOC;
cfg->type = SDE_SYS_CACHE_DISP; cfg->type = SDE_SYS_CACHE_DISP;
} else if (test_bit(cache_rd_type, psde->catalog->sde_sys_cache_type_map) && cache_flag) {
} else if (test_bit(fb_cache_type, psde->catalog->sde_sys_cache_type_map)
&& fb_cache_flag) {
cfg->rd_en = true; cfg->rd_en = true;
cfg->rd_scid = sc_cfg[fb_cache_type].llcc_scid; cfg->rd_scid = sc_cfg[cache_rd_type].llcc_scid;
cfg->rd_noallocate = true; cfg->rd_noallocate = true;
cfg->flags |= SYS_CACHE_NO_ALLOC; cfg->flags |= SYS_CACHE_NO_ALLOC;
cfg->type = fb_cache_type; cache_flag = MSM_FB_CACHE_READ_EN;
msm_framebuffer_set_cache_hint(state->fb, MSM_FB_CACHE_READ_EN, fb_cache_type); msm_framebuffer_set_cache_hint(state->fb, cache_flag, cache_rd_type, cache_wr_type);
} }
if (!cfg->rd_en && !prev_rd_en) if (!cfg->rd_en && !prev_rd_en)
return; return;
SDE_EVT32(DRMID(&psde->base), cfg->rd_scid, cfg->rd_en, cfg->rd_noallocate, cfg->flags, SDE_EVT32(DRMID(&psde->base), cfg->rd_scid, cfg->rd_en, cfg->rd_noallocate, cfg->flags,
fb_cache_flag, fb_cache_type); cache_flag, cache_rd_type, cache_wr_type, state->fb->base.id);
psde->pipe_hw->ops.setup_sys_cache(psde->pipe_hw, cfg); psde->pipe_hw->ops.setup_sys_cache(psde->pipe_hw, cfg);
} }
@@ -3585,6 +3597,7 @@ bool sde_plane_is_cache_required(struct drm_plane *plane,
enum sde_sys_cache_type type) enum sde_sys_cache_type type)
{ {
struct sde_plane_state *pstate; struct sde_plane_state *pstate;
u32 cache_flag, cache_rd_type, cache_wr_type;
if (!plane || !plane->state) { if (!plane || !plane->state) {
SDE_ERROR("invalid plane\n"); SDE_ERROR("invalid plane\n");
@@ -3592,12 +3605,20 @@ bool sde_plane_is_cache_required(struct drm_plane *plane,
} }
pstate = to_sde_plane_state(plane->state); pstate = to_sde_plane_state(plane->state);
msm_framebuffer_get_cache_hint(plane->state->fb, &cache_flag, &cache_rd_type,
&cache_wr_type);
/* check if llcc is required for the plane */ /* check if llcc is required for the plane */
if (pstate->sc_cfg.rd_en && (pstate->sc_cfg.type == type)) if (pstate->sc_cfg.rd_en && ((pstate->sc_cfg.type == type)
|| (cache_flag && (cache_rd_type == type))
|| (cache_flag && (cache_wr_type == type)))) {
SDE_EVT32_VERBOSE(DRMID(plane), type, pstate->sc_cfg.rd_en, pstate->sc_cfg.type,
cache_flag, cache_rd_type, cache_wr_type,
plane->state->fb->base.id);
return true; return true;
else }
return false;
return false;
} }
static void _sde_plane_install_master_only_properties(struct sde_plane *psde) static void _sde_plane_install_master_only_properties(struct sde_plane *psde)