Commit d21fc5df authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Rob Clark
Browse files

drm/msm/dpu1: add support for qseed3lite used on sm8250



SM8250 has quite unique qseed lut type: qseed3lite, which is a
lightweight version of qseed3 scaler.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 9fc41843
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@
#define VIG_SC7180_MASK \
	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))

#define VIG_SM8250_MASK \
	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3LITE))

#define DMA_SDM845_MASK \
	(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
@@ -185,7 +188,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
static const struct dpu_caps sm8250_dpu_caps = {
	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
	.max_mixer_blendstages = 0xb,
	.qseed_type = DPU_SSPP_SCALER_QSEED3, /* TODO: qseed3 lite */
	.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
	.ubwc_version = DPU_HW_UBWC_VER_40,
	.has_src_split = true,
@@ -444,6 +447,34 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
		sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
};

static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
				_VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
				_VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
				_VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
				_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);

static const struct dpu_sspp_cfg sm8250_sspp[] = {
	SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
		sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
	SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
		sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
	SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
		sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
	SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
		sm8250_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
	SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
		sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
	SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
		sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
	SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
		sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
	SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
		sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
};

/*************************************************************
 * MIXER sub blocks config
 *************************************************************/
@@ -974,9 +1005,8 @@ static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
		.mdp = sm8250_mdp,
		.ctl_count = ARRAY_SIZE(sm8150_ctl),
		.ctl = sm8150_ctl,
		/* TODO: sspp qseed version differs from 845 */
		.sspp_count = ARRAY_SIZE(sdm845_sspp),
		.sspp = sdm845_sspp,
		.sspp_count = ARRAY_SIZE(sm8250_sspp),
		.sspp = sm8250_sspp,
		.mixer_count = ARRAY_SIZE(sm8150_lm),
		.mixer = sm8150_lm,
		.dspp_count = ARRAY_SIZE(sm8150_dspp),
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ enum {
 * @DPU_SSPP_SRC             Src and fetch part of the pipes,
 * @DPU_SSPP_SCALER_QSEED2,  QSEED2 algorithm support
 * @DPU_SSPP_SCALER_QSEED3,  QSEED3 alogorithm support
 * @DPU_SSPP_SCALER_QSEED3LITE,  QSEED3 Lite alogorithm support
 * @DPU_SSPP_SCALER_QSEED4,  QSEED4 algorithm support
 * @DPU_SSPP_SCALER_RGB,     RGB Scaler, supported by RGB pipes
 * @DPU_SSPP_CSC,            Support of Color space converion
@@ -114,6 +115,7 @@ enum {
	DPU_SSPP_SRC = 0x1,
	DPU_SSPP_SCALER_QSEED2,
	DPU_SSPP_SCALER_QSEED3,
	DPU_SSPP_SCALER_QSEED3LITE,
	DPU_SSPP_SCALER_QSEED4,
	DPU_SSPP_SCALER_RGB,
	DPU_SSPP_CSC,
+1 −0
Original line number Diff line number Diff line
@@ -673,6 +673,7 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;

	if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
			test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) ||
			test_bit(DPU_SSPP_SCALER_QSEED4, &features)) {
		c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3;
		c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver;
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct dpu_hw_pipe;
#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
	(1UL << DPU_SSPP_SCALER_QSEED2) | \
	 (1UL << DPU_SSPP_SCALER_QSEED3) | \
	 (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
	  (1UL << DPU_SSPP_SCALER_QSEED4))

/**
+70 −3
Original line number Diff line number Diff line
@@ -59,6 +59,19 @@ static u32 dpu_hw_util_log_mask = DPU_DBG_MASK_NONE;
#define QSEED3_SEP_LUT_SIZE \
	(QSEED3_LUT_SIZE * QSEED3_SEPARABLE_LUTS * sizeof(u32))

/* DPU_SCALER_QSEED3LITE */
#define QSEED3LITE_COEF_LUT_Y_SEP_BIT         4
#define QSEED3LITE_COEF_LUT_UV_SEP_BIT        5
#define QSEED3LITE_COEF_LUT_CTRL              0x4C
#define QSEED3LITE_COEF_LUT_SWAP_BIT          0
#define QSEED3LITE_DIR_FILTER_WEIGHT          0x60
#define QSEED3LITE_FILTERS                 2
#define QSEED3LITE_SEPARABLE_LUTS             10
#define QSEED3LITE_LUT_SIZE                   33
#define QSEED3LITE_SEP_LUT_SIZE \
	        (QSEED3LITE_LUT_SIZE * QSEED3LITE_SEPARABLE_LUTS * sizeof(u32))


void dpu_reg_write(struct dpu_hw_blk_reg_map *c,
		u32 reg_off,
		u32 val,
@@ -156,6 +169,57 @@ static void _dpu_hw_setup_scaler3_lut(struct dpu_hw_blk_reg_map *c,

}

static void _dpu_hw_setup_scaler3lite_lut(struct dpu_hw_blk_reg_map *c,
		struct dpu_hw_scaler3_cfg *scaler3_cfg, u32 offset)
{
	int j, filter;
	int config_lut = 0x0;
	unsigned long lut_flags;
	u32 lut_addr, lut_offset;
	u32 *lut[QSEED3LITE_FILTERS] = {NULL, NULL};
	static const uint32_t off_tbl[QSEED3_FILTERS] = { 0x000, 0x200 };

	DPU_REG_WRITE(c, QSEED3LITE_DIR_FILTER_WEIGHT + offset, scaler3_cfg->dir_weight);

	if (!scaler3_cfg->sep_lut)
		return;

	lut_flags = (unsigned long) scaler3_cfg->lut_flag;
	if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) &&
		(scaler3_cfg->y_rgb_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) &&
		(scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) {
		lut[0] = scaler3_cfg->sep_lut +
			scaler3_cfg->y_rgb_sep_lut_idx * QSEED3LITE_LUT_SIZE;
		config_lut = 1;
	}
	if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) &&
		(scaler3_cfg->uv_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) &&
		(scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) {
		lut[1] = scaler3_cfg->sep_lut +
			scaler3_cfg->uv_sep_lut_idx * QSEED3LITE_LUT_SIZE;
		config_lut = 1;
	}

	if (config_lut) {
		for (filter = 0; filter < QSEED3LITE_FILTERS; filter++) {
			if (!lut[filter])
				continue;
			lut_offset = 0;
			lut_addr = QSEED3_COEF_LUT + offset + off_tbl[filter];
			for (j = 0; j < QSEED3LITE_LUT_SIZE; j++) {
				DPU_REG_WRITE(c,
					lut_addr,
					(lut[filter])[lut_offset++]);
				lut_addr += 4;
			}
		}
	}

	if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags))
		DPU_REG_WRITE(c, QSEED3_COEF_LUT_CTRL + offset, BIT(0));

}

static void _dpu_hw_setup_scaler3_de(struct dpu_hw_blk_reg_map *c,
		struct dpu_hw_scaler3_de_cfg *de_cfg, u32 offset)
{
@@ -242,9 +306,12 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
		op_mode |= BIT(8);
	}

	if (scaler3_cfg->lut_flag)
		_dpu_hw_setup_scaler3_lut(c, scaler3_cfg,
								scaler_offset);
	if (scaler3_cfg->lut_flag) {
		if (scaler_version < 0x2004)
			_dpu_hw_setup_scaler3_lut(c, scaler3_cfg, scaler_offset);
		else
			_dpu_hw_setup_scaler3lite_lut(c, scaler3_cfg, scaler_offset);
	}

	if (scaler_version == 0x1002) {
		phase_init =
Loading