Explorar o código

disp: msm: sde: add system cache support for writeback

Add support to enable writeback block to use system cache for writing
the output buffer. This is useful in cases where output is routed to
primary source pipes with 2-pass composition. The implementation is
modelled based on existing pipe based cache configuration.

Change-Id: I2b9a96c5b42eb5727d11ca0f337aeeb4e69362c9
Signed-off-by: Veera Sundaram Sankaran <[email protected]>
Veera Sundaram Sankaran %!s(int64=4) %!d(string=hai) anos
pai
achega
825bb55976
Modificáronse 7 ficheiros con 131 adicións e 70 borrados
  1. 3 3
      msm/sde/sde_crtc.c
  2. 44 21
      msm/sde/sde_hw_catalog.c
  3. 9 6
      msm/sde/sde_hw_catalog.h
  4. 5 5
      msm/sde/sde_hw_sspp.c
  5. 26 0
      msm/sde/sde_hw_wb.c
  6. 25 0
      msm/sde/sde_hw_wb.h
  7. 19 35
      msm/sde/sde_plane.c

+ 3 - 3
msm/sde/sde_crtc.c

@@ -5882,7 +5882,7 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
 			ARRAY_SIZE(e_secure_level), 0,
 			CRTC_PROP_SECURITY_LEVEL);
 
-	if (test_bit(SDE_FEATURE_SYSCACHE, catalog->features))
+	if (catalog->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache)
 		msm_property_install_enum(&sde_crtc->property_info, "cache_state",
 			0x0, 0, e_cache_state,
 			ARRAY_SIZE(e_cache_state), 0,
@@ -7020,8 +7020,8 @@ void sde_crtc_static_img_control(struct drm_crtc *crtc,
 		return;
 	}
 
-	if (!test_bit(SDE_FEATURE_SYSCACHE, sde_kms->catalog->features)) {
-		SDE_DEBUG("syscache not supported\n");
+	if (!sde_kms->catalog->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache) {
+		SDE_DEBUG("DISP syscache not supported\n");
 		return;
 	}
 

+ 44 - 21
msm/sde/sde_hw_catalog.c

@@ -2559,8 +2559,10 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
 		if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
 			set_bit(SDE_WB_INPUT_CTRL, &wb->features);
 
-		if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900))
+		if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900)) {
 			set_bit(SDE_WB_PROG_LINE, &wb->features);
+			set_bit(SDE_WB_SYS_CACHE, &wb->features);
+		}
 
 		rc = _add_to_irq_offset_list(sde_cfg, SDE_INTR_HWBLK_WB, wb->id, wb->base);
 
@@ -3487,36 +3489,57 @@ static int sde_cache_parse_dt(struct device_node *np,
 		struct sde_mdss_cfg *sde_cfg)
 {
 	struct llcc_slice_desc *slice;
-	struct sde_sc_cfg *sc_cfg = sde_cfg->sc_cfg;
 	struct device_node *llcc_node;
+	int i;
 
 	if (!sde_cfg) {
 		SDE_ERROR("invalid argument\n");
 		return -EINVAL;
 	}
 
-	if (!test_bit(SDE_FEATURE_SYSCACHE, sde_cfg->features))
-		return 0;
-
 	llcc_node = of_find_node_by_name(NULL, "cache-controller");
 	if (!llcc_node) {
 		SDE_DEBUG("cache controller missing, will disable img cache\n");
 		return 0;
 	}
 
-	slice = llcc_slice_getd(LLCC_DISP);
-	if (IS_ERR_OR_NULL(slice)) {
-		SDE_ERROR("failed to get system cache %ld\n", PTR_ERR(slice));
-		return -EINVAL;
-	}
+	for (i = 0; i < SDE_SYS_CACHE_MAX; i++) {
+		struct sde_sc_cfg *sc_cfg = &sde_cfg->sc_cfg[i];
+		u32 usecase_id = 0;
 
-	sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true;
-	sc_cfg[SDE_SYS_CACHE_DISP].llcc_scid = llcc_get_slice_id(slice);
-	sc_cfg[SDE_SYS_CACHE_DISP].llcc_slice_size = llcc_get_slice_size(slice);
-	SDE_DEBUG("img cache scid:%d slice_size:%zu kb\n",
-			sc_cfg[SDE_SYS_CACHE_DISP].llcc_scid,
-			sc_cfg[SDE_SYS_CACHE_DISP].llcc_slice_size);
-	llcc_slice_putd(slice);
+		if (!sc_cfg->has_sys_cache)
+			continue;
+
+		switch (i) {
+		case SDE_SYS_CACHE_DISP:
+			usecase_id = LLCC_DISP;
+			break;
+
+		case SDE_SYS_CACHE_DISP_WB:
+			usecase_id = LLCC_DISP;
+			break;
+
+		default:
+			usecase_id = 0;
+			SDE_DEBUG("invalid sys cache:%d\n", i);
+			break;
+		}
+
+		if (!usecase_id)
+			continue;
+
+		slice = llcc_slice_getd(usecase_id);
+		if (IS_ERR_OR_NULL(slice)) {
+			SDE_ERROR("failed to get system cache %ld\n", PTR_ERR(slice));
+			return -EINVAL;
+		}
+
+		sc_cfg->llcc_scid = llcc_get_slice_id(slice);
+		sc_cfg->llcc_slice_size = llcc_get_slice_size(slice);
+		SDE_DEBUG("img cache:%d usecase_id:%d, scid:%d slice_size:%zu kb\n",
+				i, usecase_id, sc_cfg->llcc_scid, sc_cfg->llcc_slice_size);
+		llcc_slice_putd(slice);
+	}
 
 	return 0;
 }
@@ -5010,7 +5033,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		set_bit(SDE_FEATURE_DITHER_LUMA_MODE, sde_cfg->features);
 		sde_cfg->mdss_hw_block_size = 0x158;
 		set_bit(SDE_FEATURE_TRUSTED_VM, sde_cfg->features);
-		set_bit(SDE_FEATURE_SYSCACHE, sde_cfg->features);
+		sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true;
 	} else if (IS_HOLI_TARGET(hw_rev)) {
 		set_bit(SDE_FEATURE_QSYNC, sde_cfg->features);
 		sde_cfg->perf.min_prefill_lines = 24;
@@ -5040,7 +5063,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		set_bit(SDE_FEATURE_VBIF_DISABLE_SHAREABLE, sde_cfg->features);
 		sde_cfg->mdss_hw_block_size = 0x158;
 		set_bit(SDE_FEATURE_TRUSTED_VM, sde_cfg->features);
-		set_bit(SDE_FEATURE_SYSCACHE, sde_cfg->features);
+		sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true;
 	} else if (IS_WAIPIO_TARGET(hw_rev)) {
 		sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH;
 		set_bit(SDE_FEATURE_DEDICATED_CWB, sde_cfg->features);
@@ -5062,7 +5085,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		set_bit(SDE_FEATURE_VBIF_DISABLE_SHAREABLE, sde_cfg->features);
 		set_bit(SDE_FEATURE_DITHER_LUMA_MODE, sde_cfg->features);
 		sde_cfg->mdss_hw_block_size = 0x158;
-		set_bit(SDE_FEATURE_SYSCACHE, sde_cfg->features);
+		sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true;
 		set_bit(SDE_FEATURE_MULTIRECT_ERROR, sde_cfg->features);
 		set_bit(SDE_FEATURE_FP16, sde_cfg->features);
 		set_bit(SDE_MDP_PERIPH_TOP_0_REMOVED, &sde_cfg->mdp[0].features);
@@ -5104,7 +5127,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		set_bit(SDE_FEATURE_VIG_P010, sde_cfg->features);
 		set_bit(SDE_FEATURE_VBIF_DISABLE_SHAREABLE, sde_cfg->features);
 		set_bit(SDE_FEATURE_DITHER_LUMA_MODE, sde_cfg->features);
-		set_bit(SDE_FEATURE_SYSCACHE, sde_cfg->features);
 		set_bit(SDE_FEATURE_MULTIRECT_ERROR, sde_cfg->features);
 		set_bit(SDE_FEATURE_FP16, sde_cfg->features);
 		set_bit(SDE_MDP_PERIPH_TOP_0_REMOVED, &sde_cfg->mdp[0].features);
@@ -5113,6 +5135,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		set_bit(SDE_FEATURE_HW_VSYNC_TS, sde_cfg->features);
 		set_bit(SDE_FEATURE_AVR_STEP, sde_cfg->features);
 		set_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_cfg->features);
+		sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true;
 		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;

+ 9 - 6
msm/sde/sde_hw_catalog.h

@@ -166,13 +166,13 @@ enum {
 		IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_UBWC_VER_40)
 
 /**
- * Supported SSPP system cache settings
+ * Supported system cache settings
  */
-#define SSPP_SYS_CACHE_EN_FLAG	BIT(0)
-#define SSPP_SYS_CACHE_SCID		BIT(1)
-#define SSPP_SYS_CACHE_OP_MODE	BIT(2)
-#define SSPP_SYS_CACHE_OP_TYPE	BIT(3)
-#define SSPP_SYS_CACHE_NO_ALLOC	BIT(4)
+#define SYS_CACHE_EN_FLAG	BIT(0)
+#define SYS_CACHE_SCID		BIT(1)
+#define SYS_CACHE_OP_MODE	BIT(2)
+#define SYS_CACHE_OP_TYPE	BIT(3)
+#define SYS_CACHE_NO_ALLOC	BIT(4)
 
 /**
  * sde_sys_cache_type: Types of system cache supported
@@ -182,6 +182,7 @@ enum {
  */
 enum sde_sys_cache_type {
 	SDE_SYS_CACHE_DISP,
+	SDE_SYS_CACHE_DISP_WB,
 	SDE_SYS_CACHE_MAX,
 	SDE_SYS_CACHE_NONE = SDE_SYS_CACHE_MAX
 };
@@ -550,6 +551,7 @@ enum {
  * @SDE_WB_HAS_CWB          Writeback block supports concurrent writeback
  * @SDE_WB_HAS_DCWB         Writeback block supports dedicated CWB
  * @SDE_WB_CROP             CWB supports cropping
+ * @SDE_WB_SYS_CACHE        Writeback block supports system cache usage
  * @SDE_WB_CWB_CTRL         Separate CWB control is available for configuring
  * @SDE_WB_DCWB_CTRL        Separate DCWB control is available for configuring
  * @SDE_WB_CWB_DITHER_CTRL  CWB dither is available for configuring
@@ -572,6 +574,7 @@ enum {
 	SDE_WB_HAS_CWB,
 	SDE_WB_HAS_DCWB,
 	SDE_WB_CROP,
+	SDE_WB_SYS_CACHE,
 	SDE_WB_CWB_CTRL,
 	SDE_WB_DCWB_CTRL,
 	SDE_WB_CWB_DITHER_CTRL,

+ 5 - 5
msm/sde/sde_hw_sspp.c

@@ -1148,19 +1148,19 @@ static void sde_hw_sspp_setup_sys_cache(struct sde_hw_pipe *ctx,
 
 	val = SDE_REG_READ(&ctx->hw, SSPP_SYS_CACHE_MODE + idx);
 
-	if (cfg->flags & SSPP_SYS_CACHE_EN_FLAG)
+	if (cfg->flags & SYS_CACHE_EN_FLAG)
 		val = (val & ~BIT(15)) | ((cfg->rd_en & 0x1) << 15);
 
-	if (cfg->flags & SSPP_SYS_CACHE_SCID)
+	if (cfg->flags & SYS_CACHE_SCID)
 		val = (val & ~0x1F00) | ((cfg->rd_scid & 0x1f) << 8);
 
-	if (cfg->flags & SSPP_SYS_CACHE_OP_MODE)
+	if (cfg->flags & SYS_CACHE_OP_MODE)
 		val = (val & ~0xC0000) | ((cfg->op_mode & 0x3) << 18);
 
-	if (cfg->flags & SSPP_SYS_CACHE_OP_TYPE)
+	if (cfg->flags & SYS_CACHE_OP_TYPE)
 		val = (val & ~0xF) | ((cfg->rd_op_type & 0xf) << 0);
 
-	if (cfg->flags & SSPP_SYS_CACHE_NO_ALLOC)
+	if (cfg->flags & SYS_CACHE_NO_ALLOC)
 		val = (val & ~0x10) | ((cfg->rd_noallocate & 0x1) << 4);
 
 	SDE_REG_WRITE(&ctx->hw, SSPP_SYS_CACHE_MODE + idx, val);

+ 26 - 0
msm/sde/sde_hw_wb.c

@@ -43,6 +43,7 @@
 #define WB_UBWC_ERROR_STATUS		0x2BC
 #define WB_OUT_IMAGE_SIZE		0x2C0
 #define WB_OUT_XY			0x2C4
+#define WB_SYS_CACHE_MODE		0x094
 
 #define CWB_CTRL_SRC_SEL		0x0
 #define CWB_CTRL_MODE			0x4
@@ -399,6 +400,28 @@ static void sde_hw_wb_program_cwb_ctrl(struct sde_hw_wb *ctx,
 	}
 }
 
+static void sde_hw_wb_setup_sys_cache(struct sde_hw_wb *ctx, struct sde_hw_wb_sc_cfg *cfg)
+{
+	u32 val = 0;
+
+	if (!ctx || !cfg)
+		return;
+
+	if (cfg->flags & SYS_CACHE_EN_FLAG)
+		val |= BIT(15);
+
+	if (cfg->flags & SYS_CACHE_SCID)
+		val |= ((cfg->wr_scid & 0x1f) << 8);
+
+	if (cfg->flags & SYS_CACHE_OP_TYPE)
+		val |= ((cfg->wr_op_type & 0xf) << 0);
+
+	if (cfg->flags & SYS_CACHE_NO_ALLOC)
+		val |= ((cfg->wr_noallocate & 0x1) << 4);
+
+	SDE_REG_WRITE(&ctx->hw, WB_SYS_CACHE_MODE, val);
+}
+
 static void sde_hw_wb_program_cwb_dither_ctrl(struct sde_hw_wb *ctx,
 		const enum sde_dcwb dcwb_idx, void *cfg, size_t len, bool enable)
 {
@@ -596,6 +619,9 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
 		ops->bind_dcwb_pp_blk = sde_hw_wb_bind_dcwb_pp_blk;
 	}
 
+	if (test_bit(SDE_WB_SYS_CACHE, &features))
+		ops->setup_sys_cache = sde_hw_wb_setup_sys_cache;
+
 	if (test_bit(SDE_WB_CWB_DITHER_CTRL, &features))
 		ops->program_cwb_dither_ctrl = sde_hw_wb_program_cwb_dither_ctrl;
 

+ 25 - 0
msm/sde/sde_hw_wb.h

@@ -61,6 +61,24 @@ struct sde_hw_wb_qos_cfg {
 	bool danger_safe_en;
 };
 
+/**
+ * struct sde_hw_wb_sc_cfg - system cache configuration
+ * @wr_en: system cache read enable
+ * @wr_scid: system cache read block id
+ * @wr_noallocate: system cache read no allocate attribute
+ * @wr_op_type: system cache read operation type
+ * @flags: dirty flags to change the configuration
+ * @type: sys cache type
+ */
+struct sde_hw_wb_sc_cfg {
+	bool wr_en;
+	u32 wr_scid;
+	bool wr_noallocate;
+	u32 wr_op_type;
+	u32 flags;
+	enum sde_sys_cache_type type;
+};
+
 /**
  *
  * struct sde_hw_wb_ops : Interface to the wb Hw driver functions
@@ -152,6 +170,13 @@ struct sde_hw_wb_ops {
 	void (*program_dcwb_ctrl)(struct sde_hw_wb *ctx, const enum sde_dcwb cwb,
 		const enum sde_cwb data_src, int tap_location, bool enable);
 
+	/**
+	 * setup_sys_cache - setup system cache configuration
+	 * @ctx: Pointer to wb context
+	 * @cfg: Pointer to wb system cache configuration
+	 */
+	void (*setup_sys_cache)(struct sde_hw_wb *ctx, struct sde_hw_wb_sc_cfg *cfg);
+
 	/**
 	 * program_cwb_dither_ctrl - program cwb dither block config
 	 * @ctx: Pointer to wb context

+ 19 - 35
msm/sde/sde_plane.c

@@ -2783,48 +2783,32 @@ static void _sde_plane_sspp_setup_sys_cache(struct sde_plane *psde,
 		struct sde_plane_state *pstate)
 {
 	struct sde_sc_cfg *sc_cfg = psde->catalog->sc_cfg;
-	bool prev_rd_en;
+	struct sde_hw_pipe_sc_cfg *cfg = &pstate->sc_cfg;
+	bool prev_rd_en = cfg->rd_en;
 
-	/* Only display system cache is currently supported */
 	if (!sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache)
 		return;
 
-	prev_rd_en = pstate->sc_cfg.rd_en;
-
-	SDE_DEBUG_PLANE(psde, "features:0x%x\n", psde->features);
-
-	pstate->sc_cfg.rd_en = false;
-	pstate->sc_cfg.rd_scid = 0x0;
-	pstate->sc_cfg.flags = SSPP_SYS_CACHE_EN_FLAG |
-			SSPP_SYS_CACHE_SCID;
-	pstate->sc_cfg.type = SDE_SYS_CACHE_NONE;
-
-	if (pstate->static_cache_state == CACHE_STATE_FRAME_WRITE) {
-		pstate->sc_cfg.rd_en = true;
-		pstate->sc_cfg.rd_scid =
-				sc_cfg[SDE_SYS_CACHE_DISP].llcc_scid;
-		pstate->sc_cfg.rd_noallocate = false;
-		pstate->sc_cfg.flags = SSPP_SYS_CACHE_EN_FLAG |
-				SSPP_SYS_CACHE_SCID | SSPP_SYS_CACHE_NO_ALLOC;
-		pstate->sc_cfg.type = SDE_SYS_CACHE_DISP;
-	} else if (pstate->static_cache_state == CACHE_STATE_FRAME_READ) {
-		pstate->sc_cfg.rd_en = true;
-		pstate->sc_cfg.rd_scid =
-				sc_cfg[SDE_SYS_CACHE_DISP].llcc_scid;
-		pstate->sc_cfg.rd_noallocate = true;
-		pstate->sc_cfg.flags = SSPP_SYS_CACHE_EN_FLAG |
-				SSPP_SYS_CACHE_SCID | SSPP_SYS_CACHE_NO_ALLOC;
-		pstate->sc_cfg.type = SDE_SYS_CACHE_DISP;
-	}
-
-	if (!pstate->sc_cfg.rd_en && !prev_rd_en)
+	cfg->rd_en = false;
+	cfg->rd_scid = 0x0;
+	cfg->flags = SYS_CACHE_EN_FLAG | SYS_CACHE_SCID;
+	cfg->type = SDE_SYS_CACHE_NONE;
+
+	if ((pstate->static_cache_state == CACHE_STATE_FRAME_WRITE)
+			|| (pstate->static_cache_state == CACHE_STATE_FRAME_READ)) {
+		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->flags |= SYS_CACHE_NO_ALLOC;
+		cfg->type = SDE_SYS_CACHE_DISP;
+	}
+
+	if (!cfg->rd_en && !prev_rd_en)
 		return;
 
-	SDE_EVT32(DRMID(&psde->base), pstate->sc_cfg.rd_scid,
-			pstate->sc_cfg.rd_en, pstate->sc_cfg.rd_noallocate);
+	SDE_EVT32(DRMID(&psde->base), cfg->rd_scid, cfg->rd_en, cfg->rd_noallocate, cfg->flags);
 
-	psde->pipe_hw->ops.setup_sys_cache(
-		psde->pipe_hw, &pstate->sc_cfg);
+	psde->pipe_hw->ops.setup_sys_cache(psde->pipe_hw, cfg);
 }
 
 void sde_plane_static_img_control(struct drm_plane *plane,