Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1af65196 authored by Prabhanjan Kandula's avatar Prabhanjan Kandula Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: update drm plane with initial status



If continuous splash is enabled, this change provides
drm plane initial status with the connected crtc to client.
Onus is on client to make sure underlying pipe usage is not
switched to any other crtc before hand-off of the specific
display. This change also validates source address of the
staged sspp against the splash memory of the display.

Change-Id: I52989381a43eefb4c8bbb6b7c2afb43fcf3823d5
Signed-off-by: default avatarPrabhanjan Kandula <pkandula@codeaurora.org>
parent 7599b0b2
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@
#define CTL_FLUSH_MASK_ROT              BIT(27)
#define CTL_FLUSH_MASK_CTL              BIT(17)

#define CTL_NUM_EXT			4
#define CTL_SSPP_MAX_RECTS		2

#define SDE_REG_RESET_TIMEOUT_US        2000

#define UPDATE_MASK(m, idx, en)           \
@@ -142,6 +145,40 @@ static const u32 cdm_flush_tbl[CDM_MAX] = {SDE_NONE, 0};
static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, SDE_NONE, 2, 3,
	4, 5};

/**
 * struct ctl_sspp_stage_reg_map: Describes bit layout for a sspp stage cfg
 * @ext: Index to indicate LAYER_x_EXT id for given sspp
 * @start: Start position of blend stage bits for given sspp
 * @bits: Number of bits from @start assigned for given sspp
 * @sec_bit_mask: Bitmask to add to LAYER_x_EXT1 for missing bit of sspp
 */
struct ctl_sspp_stage_reg_map {
	u32 ext;
	u32 start;
	u32 bits;
	u32 sec_bit_mask;
};

/* list of ctl_sspp_stage_reg_map for all the sppp */
static const struct ctl_sspp_stage_reg_map
sspp_reg_cfg_tbl[SSPP_MAX][CTL_SSPP_MAX_RECTS] = {
	/* SSPP_NONE */{ {0, 0, 0, 0}, {0, 0, 0, 0} },
	/* SSPP_VIG0 */{ {0, 0, 3, BIT(0)}, {3, 0, 4, 0} },
	/* SSPP_VIG1 */{ {0, 3, 3, BIT(2)}, {3, 4, 4, 0} },
	/* SSPP_VIG2 */{ {0, 6, 3, BIT(4)}, {3, 8, 4, 0} },
	/* SSPP_VIG3 */{ {0, 26, 3, BIT(6)}, {3, 12, 4, 0} },
	/* SSPP_RGB0 */{ {0, 9, 3, BIT(8)}, {0, 0, 0, 0} },
	/* SSPP_RGB1 */{ {0, 12, 3, BIT(10)}, {0, 0, 0, 0} },
	/* SSPP_RGB2 */{ {0, 15, 3, BIT(12)}, {0, 0, 0, 0} },
	/* SSPP_RGB3 */{ {0, 29, 3, BIT(14)}, {0, 0, 0, 0} },
	/* SSPP_DMA0 */{ {0, 18, 3, BIT(16)}, {2, 8, 4, 0} },
	/* SSPP_DMA1 */{ {0, 21, 3, BIT(18)}, {2, 12, 4, 0} },
	/* SSPP_DMA2 */{ {2, 0, 4, 0}, {2, 16, 4, 0} },
	/* SSPP_DMA3 */{ {2, 4, 4, 0}, {2, 20, 4, 0} },
	/* SSPP_CURSOR0 */{ {1, 20, 4, 0}, {0, 0, 0, 0} },
	/* SSPP_CURSOR1 */{ {0, 26, 4, 0}, {0, 0, 0, 0} }
};

/**
 * Individual flush bit in CTL_FLUSH
 */
@@ -880,6 +917,52 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx,
	SDE_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3);
}

static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm,
		struct sde_sspp_index_info *info, u32 info_max_cnt)
{
	int i, j;
	u32 count = 0;
	u32 mask = 0;
	bool staged;
	u32 mixercfg[CTL_NUM_EXT];
	struct sde_hw_blk_reg_map *c;
	const struct ctl_sspp_stage_reg_map *sspp_cfg;

	if (!ctx || (lm >= LM_MAX) || !info)
		return count;

	c = &ctx->hw;
	mixercfg[0] = SDE_REG_READ(c, CTL_LAYER(lm));
	mixercfg[1] = SDE_REG_READ(c, CTL_LAYER_EXT(lm));
	mixercfg[2] = SDE_REG_READ(c, CTL_LAYER_EXT2(lm));
	mixercfg[3] = SDE_REG_READ(c, CTL_LAYER_EXT3(lm));

	for (i = SSPP_VIG0; i < SSPP_MAX; i++) {
		for (j = 0; j < CTL_SSPP_MAX_RECTS; j++) {
			if (count >= info_max_cnt)
				goto end;

			sspp_cfg = &sspp_reg_cfg_tbl[i][j];
			if (!sspp_cfg->bits || sspp_cfg->ext >= CTL_NUM_EXT)
				continue;

			mask = ((0x1 << sspp_cfg->bits) - 1) << sspp_cfg->start;
			staged = mixercfg[sspp_cfg->ext] & mask;
			if (!staged)
				staged = mixercfg[1] & sspp_cfg->sec_bit_mask;

			if (staged) {
				info[count].sspp = i;
				info[count].is_virtual = j;
				count++;
			}
		}
	}

end:
	return count;
}

static int sde_hw_ctl_intf_cfg_v1(struct sde_hw_ctl *ctx,
		struct sde_hw_intf_cfg_v1 *cfg)
{
@@ -1196,6 +1279,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
	ops->wait_reset_status = sde_hw_ctl_wait_reset_status;
	ops->clear_all_blendstages = sde_hw_ctl_clear_all_blendstages;
	ops->setup_blendstage = sde_hw_ctl_setup_blendstage;
	ops->get_staged_sspp = sde_hw_ctl_get_staged_sspp;
	ops->update_bitmask_sspp = sde_hw_ctl_update_bitmask_sspp;
	ops->update_bitmask_mixer = sde_hw_ctl_update_bitmask_mixer;
	ops->update_bitmask_dspp = sde_hw_ctl_update_bitmask_dspp;
+16 −0
Original line number Diff line number Diff line
@@ -448,6 +448,22 @@ struct sde_hw_ctl_ops {
	void (*setup_blendstage)(struct sde_hw_ctl *ctx,
		enum sde_lm lm, struct sde_hw_stage_cfg *cfg);

	/**
	 * Get all the sspp staged on a layer mixer
	 * @ctx       : ctl path ctx pointer
	 * @lm        : layer mixer enumeration
	 * @info      : array address to populate connected sspp index info
	 * @info_max_cnt : maximum sspp info elements based on array size
	 * @Return: count of sspps info  elements populated
	 */
	u32 (*get_staged_sspp)(struct sde_hw_ctl *ctx, enum sde_lm lm,
		struct sde_sspp_index_info *info, u32 info_max_cnt);

	/**
	 * Setup the stream buffer config like rotation mode
	 * @ctx       : ctl path ctx pointer
	 * Returns: 0 on success or -error
	 */
	int (*setup_sbuf_cfg)(struct sde_hw_ctl *ctx,
		struct sde_ctl_sbuf_cfg *cfg);

+15 −1
Original line number Diff line number Diff line
@@ -567,19 +567,31 @@ struct sde_splash_mem {
	u32 ref_cnt;
};

/**
 * struct sde_sspp_index_info - Struct containing sspp identifier info
 * @sspp:	Enum value indicates sspp id
 * @is_virtual: Boolean to identify if virtual or base
 */
struct sde_sspp_index_info {
	enum sde_sspp sspp;
	bool is_virtual;
};

/**
 * struct sde_splash_data - Struct contains details of resources and hw blocks
 * used in continuous splash on a specific display.
 * @cont_splash_enabled:  Stores the cont_splash status (enabled/disabled)
 * @single_flush_en: Stores if the single flush is enabled
 * @encoder:	Pointer points to the drm encoder object used for this display
 * @encoder:	Pointer to the drm encoder object used for this display
 * @splash:     Pointer to struct sde_splash_mem used for this display
 * @ctl_ids:	Stores the valid MDSS ctl block ids for the current mode
 * @lm_ids:	Stores the valid MDSS layer mixer block ids for the current mode
 * @dsc_ids:	Stores the valid MDSS DSC block ids for the current mode
 * @pipes:      Array of sspp info detected on this display
 * @ctl_cnt:    Stores the active number of MDSS "top" blks of the current mode
 * @lm_cnt:	Stores the active number of MDSS "LM" blks for the current mode
 * @dsc_cnt:	Stores the active number of MDSS "dsc" blks for the current mode
 * @pipe_cnt:	Stores the active number of "sspp" blks connected
 */
struct sde_splash_display {
	bool cont_splash_enabled;
@@ -589,9 +601,11 @@ struct sde_splash_display {
	u8 ctl_ids[MAX_DATA_PATH_PER_DSIPLAY];
	u8 lm_ids[MAX_DATA_PATH_PER_DSIPLAY];
	u8 dsc_ids[MAX_DATA_PATH_PER_DSIPLAY];
	struct sde_sspp_index_info pipes[MAX_DATA_PATH_PER_DSIPLAY];
	u8 ctl_cnt;
	u8 lm_cnt;
	u8 dsc_cnt;
	u8 pipe_cnt;
};

/**
+14 −0
Original line number Diff line number Diff line
@@ -724,6 +724,19 @@ static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
	}
}

u32 sde_hw_sspp_get_source_addr(struct sde_hw_pipe *ctx, bool is_virtual)
{
	u32 idx;
	u32 offset = 0;

	if (!ctx || _sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
		return 0;

	offset =  is_virtual ? (SSPP_SRC1_ADDR + idx) : (SSPP_SRC0_ADDR + idx);

	return SDE_REG_READ(&ctx->hw, offset);
}

static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
		struct sde_csc_cfg *data)
{
@@ -1094,6 +1107,7 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
		c->ops.setup_format = sde_hw_sspp_setup_format;
		c->ops.setup_rects = sde_hw_sspp_setup_rects;
		c->ops.setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
		c->ops.get_sourceaddress = sde_hw_sspp_get_source_addr;
		c->ops.setup_solidfill = sde_hw_sspp_setup_solidfill;
		c->ops.setup_pe = sde_hw_sspp_setup_pe_config;
		c->ops.setup_secure_address = sde_hw_sspp_setup_secure;
+6 −0
Original line number Diff line number Diff line
@@ -346,6 +346,12 @@ struct sde_hw_sspp_ops {
			struct sde_hw_pipe_cfg *cfg,
			enum sde_sspp_multirect_index index);

	/* get_sourceaddress - get pipe current source addresses of a plane
	 * @ctx: Pointer to pipe context
	 * @is_virtual: If true get address programmed for R1 in multirect
	 */
	u32 (*get_sourceaddress)(struct sde_hw_pipe *ctx, bool is_virtual);

	/**
	 * setup_csc - setup color space conversion
	 * @ctx: Pointer to pipe context
Loading