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

Commit 1ce0cb61 authored by abeykun's avatar abeykun Committed by Srikanth Rajagopalan
Browse files

drm/msm/sde: expose 10 bit pixel format capabilities



Patch adds RGB 10bit both linear and compressed, P010 linear and
and TP10 compressed pixel formats to plane and writeback capabilities.

Change-Id: Ib5a0b2dacbc1ddc47c069b4348c0d1b9fbd7701e
Signed-off-by: default avatarAlexander Beykun <abeykun@codeaurora.org>
parent 4482a89a
Loading
Loading
Loading
Loading
+164 −7
Original line number Diff line number Diff line
@@ -405,6 +405,38 @@ static struct sde_prop_type vbif_prop[] = {
/*************************************************************
 * static API list
 *************************************************************/

/**
 * _sde_copy_formats   - copy formats from src_list to dst_list
 * @dst_list:          pointer to destination list where to copy formats
 * @dst_list_size:     size of destination list
 * @dst_list_pos:      starting position on the list where to copy formats
 * @src_list:          pointer to source list where to copy formats from
 * @src_list_size:     size of source list
 * Return: number of elements populated
 */
static uint32_t _sde_copy_formats(
		struct sde_format_extended *dst_list,
		uint32_t dst_list_size,
		uint32_t dst_list_pos,
		const struct sde_format_extended *src_list,
		uint32_t src_list_size)
{
	uint32_t cur_pos, i;

	if (!dst_list || !src_list || (dst_list_pos >= (dst_list_size - 1)))
		return 0;

	for (i = 0, cur_pos = dst_list_pos;
		(cur_pos < (dst_list_size - 1)) && src_list[i].fourcc_format
		&& (i < src_list_size); ++i, ++cur_pos)
		dst_list[cur_pos] = src_list[i];

	dst_list[cur_pos].fourcc_format = 0;

	return i;
}

static int _parse_dt_u32_handler(struct device_node *np,
	char *prop_name, u32 *offsets, int len, bool mandatory)
{
@@ -658,7 +690,7 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
	sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
	sspp->id = SSPP_VIG0 + *vig_count;
	sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count;
	sblk->format_list = plane_formats_yuv;
	sspp->type = SSPP_TYPE_VIG;
	set_bit(SDE_SSPP_QOS, &sspp->features);
	(*vig_count)++;

@@ -728,7 +760,7 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
	sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
	sspp->id = SSPP_RGB0 + *rgb_count;
	sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count;
	sblk->format_list = plane_formats;
	sspp->type = SSPP_TYPE_RGB;
	set_bit(SDE_SSPP_QOS, &sspp->features);
	(*rgb_count)++;

@@ -768,7 +800,7 @@ static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg,
	sblk->maxdwnscale = SSPP_UNITY_SCALE;
	sspp->id = SSPP_CURSOR0 + *cursor_count;
	sspp->clk_ctrl = SDE_CLK_CTRL_CURSOR0 + *cursor_count;
	sblk->format_list = plane_formats;
	sspp->type = SSPP_TYPE_CURSOR;
	(*cursor_count)++;
	snprintf(sspp->name, sizeof(sspp->name), "cursor%d", *cursor_count-1);
}
@@ -781,7 +813,7 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
	sblk->maxdwnscale = SSPP_UNITY_SCALE;
	sspp->id = SSPP_DMA0 + *dma_count;
	sspp->clk_ctrl = SDE_CLK_CTRL_DMA0 + *dma_count;
	sblk->format_list = plane_formats;
	sspp->type = SSPP_TYPE_DMA;
	set_bit(SDE_SSPP_QOS, &sspp->features);
	(*dma_count)++;
	snprintf(sspp->name, sizeof(sspp->name), "dma%d", *dma_count-1);
@@ -1258,7 +1290,6 @@ static int sde_wb_parse_dt(struct device_node *np,
		wb->xin_id = PROP_VALUE_ACCESS(prop_value, WB_XIN_ID, i);
		wb->vbif_idx = VBIF_NRT;
		wb->len = PROP_VALUE_ACCESS(prop_value, WB_LEN, 0);
		wb->format_list = wb2_formats;
		if (!prop_exists[WB_LEN])
			wb->len = DEFAULT_SDE_HW_BLOCK_LEN;
		sblk->maxlinewidth = sde_cfg->max_wb_linewidth;
@@ -1988,9 +2019,124 @@ end:
	return rc;
}

static void sde_hardware_caps(struct sde_mdss_cfg *sde_cfg,
static int sde_hardware_format_caps(struct sde_mdss_cfg *sde_cfg,
	uint32_t hw_rev)
{
	int i, 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)) {
		cursor_list_size = ARRAY_SIZE(cursor_formats);
		sde_cfg->cursor_formats = kcalloc(cursor_list_size,
			sizeof(struct sde_format_extended), GFP_KERNEL);
		if (!sde_cfg->cursor_formats) {
			rc = -ENOMEM;
			goto end;
		}
		index = _sde_copy_formats(sde_cfg->cursor_formats,
			cursor_list_size, 0, cursor_formats,
			ARRAY_SIZE(cursor_formats));
	}

	dma_list_size = ARRAY_SIZE(plane_formats);
	vig_list_size = ARRAY_SIZE(plane_formats_yuv);
	wb2_list_size = ARRAY_SIZE(wb2_formats);

	dma_list_size += ARRAY_SIZE(rgb_10bit_formats);
	vig_list_size += ARRAY_SIZE(rgb_10bit_formats)
		+ ARRAY_SIZE(tp10_ubwc_formats)
		+ ARRAY_SIZE(p010_formats);
	wb2_list_size += ARRAY_SIZE(rgb_10bit_formats)
		+ ARRAY_SIZE(tp10_ubwc_formats);

	sde_cfg->dma_formats = kcalloc(dma_list_size,
		sizeof(struct sde_format_extended), GFP_KERNEL);
	if (!sde_cfg->dma_formats) {
		rc = -ENOMEM;
		goto end;
	}

	sde_cfg->vig_formats = kcalloc(vig_list_size,
		sizeof(struct sde_format_extended), GFP_KERNEL);
	if (!sde_cfg->vig_formats) {
		rc = -ENOMEM;
		goto end;
	}

	sde_cfg->wb_formats = kcalloc(wb2_list_size,
		sizeof(struct sde_format_extended), GFP_KERNEL);
	if (!sde_cfg->wb_formats) {
		SDE_ERROR("failed to allocate wb format list\n");
		rc = -ENOMEM;
		goto end;
	}

	index = _sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
		0, plane_formats, ARRAY_SIZE(plane_formats));
	index += _sde_copy_formats(sde_cfg->dma_formats, dma_list_size,
		index, rgb_10bit_formats,
		ARRAY_SIZE(rgb_10bit_formats));

	index = _sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
		0, plane_formats_yuv, ARRAY_SIZE(plane_formats_yuv));
	index += _sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
		index, rgb_10bit_formats,
		ARRAY_SIZE(rgb_10bit_formats));
	index += _sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
		index, p010_formats, ARRAY_SIZE(p010_formats));

	index += _sde_copy_formats(sde_cfg->vig_formats, vig_list_size,
		index, tp10_ubwc_formats,
		ARRAY_SIZE(tp10_ubwc_formats));

	index = _sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
		0, wb2_formats, ARRAY_SIZE(wb2_formats));
	index += _sde_copy_formats(sde_cfg->wb_formats, wb2_list_size,
		index, rgb_10bit_formats,
		ARRAY_SIZE(rgb_10bit_formats));
	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)
{
	int rc = 0;

	switch (hw_rev) {
	case SDE_HW_VER_170:
	case SDE_HW_VER_171:
@@ -1998,10 +2144,14 @@ static void sde_hardware_caps(struct sde_mdss_cfg *sde_cfg,
		/* update msm8996 target here */
		break;
	case SDE_HW_VER_300:
	case SDE_HW_VER_301:
	case SDE_HW_VER_400:
		/* update cobalt and skunk target here */
		rc = sde_hardware_format_caps(sde_cfg, hw_rev);
		break;
	}

	return rc;
}

void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
@@ -2040,6 +2190,11 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
		}
	}

	kfree(sde_cfg->dma_formats);
	kfree(sde_cfg->cursor_formats);
	kfree(sde_cfg->vig_formats);
	kfree(sde_cfg->wb_formats);

	kfree(sde_cfg);
}

@@ -2109,7 +2264,9 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev,
	if (rc)
		SDE_DEBUG("virtual plane is not supported.\n");

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

	return sde_cfg;

+14 −2
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@
#define SDE_HW_VER_170	SDE_HW_VER(1, 7, 0) /* 8996 v1.0 */
#define SDE_HW_VER_171	SDE_HW_VER(1, 7, 1) /* 8996 v2.0 */
#define SDE_HW_VER_172	SDE_HW_VER(1, 7, 2) /* 8996 v3.0 */
#define SDE_HW_VER_300	SDE_HW_VER(3, 0, 0) /* cobalt v1.0 */
#define SDE_HW_VER_300	SDE_HW_VER(3, 0, 0) /* 8998 v1.0 */
#define SDE_HW_VER_301	SDE_HW_VER(3, 0, 1) /* 8998 v1.1 */
#define SDE_HW_VER_400	SDE_HW_VER(4, 0, 0) /* msmskunk v1.0 */

#define IS_MSMSKUNK_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_400)
@@ -458,6 +459,7 @@ struct sde_ctl_cfg {
 * @xin_id:            bus client identifier
 * @clk_ctrl           clock control identifier
 * @name               source pipe name
 * @type               sspp type identifier
 */
struct sde_sspp_cfg {
	SDE_HW_BLK_INFO;
@@ -465,6 +467,7 @@ struct sde_sspp_cfg {
	u32 xin_id;
	enum sde_clk_ctrl_type clk_ctrl;
	char name[SSPP_NAME_SIZE];
	u32 type;
};

/**
@@ -652,6 +655,10 @@ struct sde_vp_cfg {
 * @csc_type           csc or csc_10bit support.
 * @has_src_split      source split feature status
 * @has_cdp            Client driver prefetch feature status
 * @dma_formats        Supported formats for dma pipe
 * @cursor_formats     Supported formats for cursor pipe
 * @vig_formats        Supported formats for vig pipe
 * @wb_formats         Supported formats for wb
 */
struct sde_mdss_cfg {
	u32 hwversion;
@@ -704,6 +711,11 @@ struct sde_mdss_cfg {

	u32 vp_count;
	struct sde_vp_cfg vp[MAX_BLOCKS];

	struct sde_format_extended *dma_formats;
	struct sde_format_extended *cursor_formats;
	struct sde_format_extended *vig_formats;
	struct sde_format_extended *wb_formats;
};

struct sde_mdss_hw_cfg_handler {
+43 −0
Original line number Diff line number Diff line
@@ -94,13 +94,33 @@ static const struct sde_format_extended plane_formats_yuv[] = {
	{0, 0},
};

static const struct sde_format_extended cursor_formats[] = {
	{DRM_FORMAT_ARGB8888, 0},
	{DRM_FORMAT_ABGR8888, 0},
	{DRM_FORMAT_RGBA8888, 0},
	{DRM_FORMAT_BGRA8888, 0},
	{DRM_FORMAT_XRGB8888, 0},
	{DRM_FORMAT_ARGB1555, 0},
	{DRM_FORMAT_ABGR1555, 0},
	{DRM_FORMAT_RGBA5551, 0},
	{DRM_FORMAT_BGRA5551, 0},
	{DRM_FORMAT_ARGB4444, 0},
	{DRM_FORMAT_ABGR4444, 0},
	{DRM_FORMAT_RGBA4444, 0},
	{DRM_FORMAT_BGRA4444, 0},
	{0, 0},
};

static const struct sde_format_extended wb2_formats[] = {
	{DRM_FORMAT_RGB565, 0},
	{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_RGB888, 0},
	{DRM_FORMAT_ARGB8888, 0},
	{DRM_FORMAT_RGBA8888, 0},
	{DRM_FORMAT_RGBA8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_XRGB8888, 0},
	{DRM_FORMAT_RGBX8888, 0},
	{DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_ARGB1555, 0},
	{DRM_FORMAT_RGBA5551, 0},
	{DRM_FORMAT_XRGB1555, 0},
@@ -127,8 +147,31 @@ static const struct sde_format_extended wb2_formats[] = {

	{DRM_FORMAT_YUV420, 0},
	{DRM_FORMAT_NV12, 0},
	{DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_NV16, 0},
	{DRM_FORMAT_YUYV, 0},

	{0, 0},
};

static const struct sde_format_extended rgb_10bit_formats[] = {
	{DRM_FORMAT_BGRA1010102, 0},
	{DRM_FORMAT_BGRX1010102, 0},
	{DRM_FORMAT_RGBA1010102, 0},
	{DRM_FORMAT_RGBX1010102, 0},
	{DRM_FORMAT_ABGR2101010, 0},
	{DRM_FORMAT_ABGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_XBGR2101010, 0},
	{DRM_FORMAT_XBGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED},
	{DRM_FORMAT_ARGB2101010, 0},
	{DRM_FORMAT_XRGB2101010, 0},
};

static const struct sde_format_extended p010_formats[] = {
	{DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_DX},
};

static const struct sde_format_extended tp10_ubwc_formats[] = {
	{DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED |
		DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT},
};