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

Commit 203e3bae authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: support ubwc 2.0 feature" into msm-4.9

parents f7980354 32bcb004
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -117,6 +117,11 @@ Optional properties:
				type.
- qcom,sde-highest-bank-bit:	A u32 property to indicate GPU/Camera/Video highest memory
				bank bit used for tile format buffers.
- qcom,sde-ubwc-version:	Property to specify the UBWC feature version.
- qcom,sde-ubwc-static:	Property to specify the default UBWC static
				configuration value.
- qcom,sde-ubwc-swizzle:	Property to specify the default UBWC swizzle
				configuration value.
- qcom,sde-panic-per-pipe:	Boolean property to indicate if panic signal
				control feature is available on each source pipe.
- qcom,sde-has-src-split:	Boolean property to indicate if source split
@@ -388,6 +393,9 @@ Example:
    qcom,sde-sspp-linewidth = <2560>;
    qcom,sde-mixer-blendstages = <0x7>;
    qcom,sde-highest-bank-bit = <0x2>;
    qcom,sde-ubwc-version = <0x100>;
    qcom,sde-ubwc-static = <0x100>;
    qcom,sde-ubwc-swizzle = <0>;
    qcom,sde-panic-per-pipe;
    qcom,sde-has-cdp;
    qcom,sde-has-src-split;
+1 −1
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ static int sde_encoder_phys_wb_atomic_check(
	}

	if (SDE_FORMAT_IS_UBWC(fmt) &&
			!(wb_cfg->features & BIT(SDE_WB_UBWC_1_0))) {
			!(wb_cfg->features & BIT(SDE_WB_UBWC))) {
		SDE_ERROR("invalid output format %x\n", fmt->base.pixel_format);
		return -EINVAL;
	}
+52 −36
Original line number Diff line number Diff line
@@ -43,6 +43,15 @@
/* max bank bit for macro tile and ubwc format */
#define DEFAULT_SDE_HIGHEST_BANK_BIT 15

/* default ubwc version */
#define DEFAULT_SDE_UBWC_VERSION SDE_HW_UBWC_VER_10

/* default ubwc static config register value */
#define DEFAULT_SDE_UBWC_STATIC 0x0

/* default ubwc swizzle register value */
#define DEFAULT_SDE_UBWC_SWIZZLE 0x0

/* default hardware block size if dtsi entry is not present */
#define DEFAULT_SDE_HW_BLOCK_LEN 0x100

@@ -97,6 +106,9 @@ enum sde_prop {
	MIXER_BLEND,
	WB_LINEWIDTH,
	BANK_BIT,
	UBWC_VERSION,
	UBWC_STATIC,
	UBWC_SWIZZLE,
	QSEED_TYPE,
	CSC_TYPE,
	PANIC_PER_PIPE,
@@ -287,6 +299,9 @@ static struct sde_prop_type sde_prop[] = {
	{MIXER_BLEND, "qcom,sde-mixer-blendstages", false, PROP_TYPE_U32},
	{WB_LINEWIDTH, "qcom,sde-wb-linewidth", false, PROP_TYPE_U32},
	{BANK_BIT, "qcom,sde-highest-bank-bit", false, PROP_TYPE_U32},
	{UBWC_VERSION, "qcom,sde-ubwc-version", false, PROP_TYPE_U32},
	{UBWC_STATIC, "qcom,sde-ubwc-static", false, PROP_TYPE_U32},
	{UBWC_SWIZZLE, "qcom,sde-ubwc-swizzle", false, PROP_TYPE_U32},
	{QSEED_TYPE, "qcom,sde-qseed-type", false, PROP_TYPE_STRING},
	{CSC_TYPE, "qcom,sde-csc-type", false, PROP_TYPE_STRING},
	{PANIC_PER_PIPE, "qcom,sde-panic-per-pipe", false, PROP_TYPE_BOOL},
@@ -809,6 +824,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
		sblk->pcc_blk.len = 0;
		set_bit(SDE_SSPP_PCC, &sspp->features);
	}

	sblk->format_list = sde_cfg->vig_formats;
}

static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
@@ -856,15 +873,21 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
		sblk->pcc_blk.len = 0;
		set_bit(SDE_SSPP_PCC, &sspp->features);
	}

	sblk->format_list = sde_cfg->dma_formats;
}

static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg,
	struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk,
	struct sde_prop_value *prop_value, u32 *cursor_count)
{
	if (!IS_SDE_MAJOR_MINOR_SAME(sde_cfg->hwversion, SDE_HW_VER_300))
		SDE_ERROR("invalid sspp type %d, xin id %d\n",
				sspp->type, sspp->xin_id);
	set_bit(SDE_SSPP_CURSOR, &sspp->features);
	sblk->maxupscale = SSPP_UNITY_SCALE;
	sblk->maxdwnscale = SSPP_UNITY_SCALE;
	sblk->format_list = sde_cfg->cursor_formats;
	sspp->id = SSPP_CURSOR0 + *cursor_count;
	snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
	sspp->clk_ctrl = SDE_CLK_CTRL_CURSOR0 + *cursor_count;
@@ -878,6 +901,7 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
{
	sblk->maxupscale = SSPP_UNITY_SCALE;
	sblk->maxdwnscale = SSPP_UNITY_SCALE;
	sblk->format_list = sde_cfg->dma_formats;
	sspp->id = SSPP_DMA0 + *dma_count;
	sspp->clk_ctrl = SDE_CLK_CTRL_DMA0 + *dma_count;
	snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
@@ -1414,6 +1438,9 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
		set_bit(SDE_WB_TRAFFIC_SHAPER, &wb->features);
		set_bit(SDE_WB_YUV_CONFIG, &wb->features);

		if (sde_cfg->has_wb_ubwc)
			set_bit(SDE_WB_UBWC, &wb->features);

		for (j = 0; j < sde_cfg->mdp_count; j++) {
			sde_cfg->mdp[j].clk_ctrls[wb->clk_ctrl].reg_off =
				PROP_BITVALUE_ACCESS(prop_value,
@@ -1423,6 +1450,8 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
						WB_CLK_CTRL, i, 1);
		}

		wb->format_list = sde_cfg->wb_formats;

		SDE_DEBUG(
			"wb:%d xin:%d vbif:%d clk%d:%x/%d\n",
			wb->id - WB_0,
@@ -2037,6 +2066,19 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
	if (!prop_exists[BANK_BIT])
		cfg->mdp[0].highest_bank_bit = DEFAULT_SDE_HIGHEST_BANK_BIT;

	cfg->ubwc_version = PROP_VALUE_ACCESS(prop_value, UBWC_VERSION, 0);
	if (!prop_exists[UBWC_VERSION])
		cfg->ubwc_version = DEFAULT_SDE_UBWC_VERSION;

	cfg->mdp[0].ubwc_static = PROP_VALUE_ACCESS(prop_value, UBWC_STATIC, 0);
	if (!prop_exists[UBWC_STATIC])
		cfg->mdp[0].ubwc_static = DEFAULT_SDE_UBWC_STATIC;

	cfg->mdp[0].ubwc_swizzle = PROP_VALUE_ACCESS(prop_value,
			UBWC_SWIZZLE, 0);
	if (!prop_exists[UBWC_SWIZZLE])
		cfg->mdp[0].ubwc_swizzle = DEFAULT_SDE_UBWC_SWIZZLE;

	rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type);
	if (!rc && !strcmp(type, "qseedv3")) {
		cfg->qseed_type = SDE_SSPP_SCALER_QSEED3;
@@ -2154,10 +2196,9 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
static int sde_hardware_format_caps(struct sde_mdss_cfg *sde_cfg,
	uint32_t hw_rev)
{
	int i, rc = 0;
	int rc = 0;
	uint32_t dma_list_size, vig_list_size, wb2_list_size;
	uint32_t cursor_list_size = 0;
	struct sde_sspp_sub_blks *sblk;
	uint32_t index = 0;

	if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_300)) {
@@ -2239,43 +2280,17 @@ static int sde_hardware_format_caps(struct sde_mdss_cfg *sde_cfg,
	index += _sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
		index, tp10_ubwc_formats,
		ARRAY_SIZE(tp10_ubwc_formats));

	for (i = 0; i < sde_cfg->sspp_count; ++i) {
		struct sde_sspp_cfg *sspp = &sde_cfg->sspp[i];

		sblk = (struct sde_sspp_sub_blks *)sspp->sblk;
		switch (sspp->type) {
		case SSPP_TYPE_VIG:
			sblk->format_list = sde_cfg->vig_formats;
			break;
		case SSPP_TYPE_CURSOR:
			if (IS_SDE_MAJOR_MINOR_SAME((hw_rev), SDE_HW_VER_300))
				sblk->format_list = sde_cfg->cursor_formats;
			else
				SDE_ERROR("invalid sspp type %d, xin id %d\n",
					sspp->type, sspp->xin_id);
			break;
		case SSPP_TYPE_DMA:
			sblk->format_list = sde_cfg->dma_formats;
			break;
		default:
			SDE_ERROR("invalid sspp type %d\n", sspp->type);
			rc = -EINVAL;
			goto end;
		}
	}

	for (i = 0; i < sde_cfg->wb_count; ++i)
		sde_cfg->wb[i].format_list = sde_cfg->wb_formats;

end:
	return rc;
}

static int sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
static int _sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
{
	int rc = 0;

	if (!sde_cfg)
		return -EINVAL;

	switch (hw_rev) {
	case SDE_HW_VER_170:
	case SDE_HW_VER_171:
@@ -2287,6 +2302,7 @@ static int sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
	case SDE_HW_VER_400:
		/* update msm8998 and sdm845 target here */
		rc = sde_hardware_format_caps(sde_cfg, hw_rev);
		sde_cfg->has_wb_ubwc = true;
		break;
	}

@@ -2343,6 +2359,10 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)

	sde_cfg->hwversion = hw_rev;

	rc = _sde_hardware_caps(sde_cfg, hw_rev);
	if (rc)
		goto end;

	rc = sde_parse_dt(np, sde_cfg);
	if (rc)
		goto end;
@@ -2397,10 +2417,6 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)
	if (rc)
		goto end;

	rc = sde_hardware_caps(sde_cfg, hw_rev);
	if (rc)
		goto end;

	return sde_cfg;

end:
+21 −6
Original line number Diff line number Diff line
@@ -60,6 +60,17 @@
#define SDE_COLOR_PROCESS_MAJOR(version) (((version) & 0xFFFF0000) >> 16)
#define SDE_COLOR_PROCESS_MINOR(version) ((version) & 0xFFFF)

/**
 * Supported UBWC feature versions
 */
enum {
	SDE_HW_UBWC_VER_10 = 0x100,
	SDE_HW_UBWC_VER_20 = 0x200,
	SDE_HW_UBWC_VER_30 = 0x300,
};

#define IS_UBWC_20_SUPPORTED(rev)       ((rev) >= SDE_HW_UBWC_VER_20)

/**
 * MDP TOP BLOCK features
 * @SDE_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per pipe
@@ -207,9 +218,7 @@ enum {
 * @SDE_WB_DOWNSCALE,       Writeback integer downscaler,
 * @SDE_WB_DITHER,          Dither block
 * @SDE_WB_TRAFFIC_SHAPER,  Writeback traffic shaper bloc
 * @SDE_WB_UBWC_1_0,        Writeback Universal bandwidth compression 1.0
 *                          support
 * @SDE_WB_UBWC_1_5         UBWC 1.5 support
 * @SDE_WB_UBWC,            Writeback Universal bandwidth compression
 * @SDE_WB_YUV_CONFIG       Writeback supports output of YUV colorspace
 * @SDE_WB_PIPE_ALPHA       Writeback supports pipe alpha
 * @SDE_WB_XY_ROI_OFFSET    Writeback supports x/y-offset of out ROI in
@@ -225,7 +234,7 @@ enum {
	SDE_WB_DOWNSCALE,
	SDE_WB_DITHER,
	SDE_WB_TRAFFIC_SHAPER,
	SDE_WB_UBWC_1_0,
	SDE_WB_UBWC,
	SDE_WB_YUV_CONFIG,
	SDE_WB_PIPE_ALPHA,
	SDE_WB_XY_ROI_OFFSET,
@@ -447,11 +456,15 @@ struct sde_clk_ctrl_reg {
 * @base:              register base offset to mdss
 * @features           bit mask identifying sub-blocks/features
 * @highest_bank_bit:  UBWC parameter
 * @ubwc_static:       ubwc static configuration
 * @ubwc_swizzle:      ubwc default swizzle setting
 * @clk_ctrls          clock control register definition
 */
struct sde_mdp_cfg {
	SDE_HW_BLK_INFO;
	u32 highest_bank_bit;
	u32 ubwc_static;
	u32 ubwc_swizzle;
	struct sde_clk_ctrl_reg clk_ctrls[SDE_CLK_CTRL_MAX];
};

@@ -660,12 +673,13 @@ struct sde_perf_cfg {
 * @max_mixer_blendstages max layer mixer blend stages or
 *                       supported z order
 * @max_wb_linewidth   max writeback line width support.
 * @highest_bank_bit   highest memory bit setting for tile buffers.
 * @qseed_type         qseed2 or qseed3 support.
 * @csc_type           csc or csc_10bit support.
 * @smart_dma_rev      Supported version of SmartDMA feature.
 * @has_src_split      source split feature status
 * @has_cdp            Client driver prefetch feature status
 * @has_wb_ubwc        UBWC feature supported on WB
 * @ubwc_version       UBWC feature version (0x0 for not supported)
 * @dma_formats        Supported formats for dma pipe
 * @cursor_formats     Supported formats for cursor pipe
 * @vig_formats        Supported formats for vig pipe
@@ -678,13 +692,14 @@ struct sde_mdss_cfg {
	u32 max_mixer_width;
	u32 max_mixer_blendstages;
	u32 max_wb_linewidth;
	u32 highest_bank_bit;
	u32 qseed_type;
	u32 csc_type;
	u32 smart_dma_rev;
	bool has_src_split;
	bool has_cdp;
	bool has_dim_layer;
	bool has_wb_ubwc;
	u32 ubwc_version;

	u32 mdss_count;
	struct sde_mdss_base_cfg mdss[MAX_BLOCKS];
+11 −2
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@

#define SSPP_SRC_CONSTANT_COLOR            0x3c
#define SSPP_EXCL_REC_CTL                  0x40
#define SSPP_UBWC_STATIC_CTRL              0x44
#define SSPP_FETCH_CONFIG                  0x048
#define SSPP_DANGER_LUT                    0x60
#define SSPP_SAFE_LUT                      0x64
@@ -366,7 +367,11 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
		src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
		SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
			SDE_FETCH_CONFIG_RESET_VALUE |
			ctx->highest_bank_bit << 18);
			ctx->mdp->highest_bank_bit << 18);
		if (IS_UBWC_20_SUPPORTED(ctx->catalog->ubwc_version))
			SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
					BIT(31) | (ctx->mdp->ubwc_swizzle) |
					(ctx->mdp->highest_bank_bit << 4));
	}

	opmode |= MDSS_MDP_OP_PE_OVERRIDE;
@@ -1074,6 +1079,9 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
	struct sde_hw_pipe *hw_pipe;
	struct sde_sspp_cfg *cfg;

	if (!addr || !catalog)
		return ERR_PTR(-EINVAL);

	hw_pipe = kzalloc(sizeof(*hw_pipe), GFP_KERNEL);
	if (!hw_pipe)
		return ERR_PTR(-ENOMEM);
@@ -1085,10 +1093,11 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
	}

	/* Assign ops */
	hw_pipe->catalog = catalog;
	hw_pipe->mdp = &catalog->mdp[0];
	hw_pipe->idx = idx;
	hw_pipe->cap = cfg;
	_setup_layer_ops(hw_pipe, hw_pipe->cap->features);
	hw_pipe->highest_bank_bit = catalog->mdp[0].highest_bank_bit;

	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name,
			hw_pipe->hw.blk_off,
Loading