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

Commit 5728dc49 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 05632565 1ce0cb61
Loading
Loading
Loading
Loading
+157 −80
Original line number Diff line number Diff line
@@ -11,12 +11,15 @@
 */

#include <uapi/drm/drm_fourcc.h>
#include <uapi/media/msm_media_info.h>

#include "sde_kms.h"
#include "sde_formats.h"

#define SDE_UBWC_META_MACRO_W_H		16
#define SDE_UBWC_META_BLOCK_SIZE	256
#define SDE_UBWC_PLANE_SIZE_ALIGNMENT	4096

#define SDE_MAX_IMG_WIDTH		0x3FFF
#define SDE_MAX_IMG_HEIGHT		0x3FFF

@@ -42,7 +45,7 @@ bp, flg, fm, np) \
	.unpack_count = uc,                                               \
	.bpp = bp,                                                        \
	.fetch_mode = fm,                                                 \
	.flag = flg,                                                      \
	.flag = {(flg)},                                                  \
	.num_planes = np                                                  \
}

@@ -60,7 +63,7 @@ alpha, chroma, count, bp, flg, fm, np) \
	.unpack_count = count,                                            \
	.bpp = bp,                                                        \
	.fetch_mode = fm,                                                 \
	.flag = flg,                                                      \
	.flag = {(flg)},                                                  \
	.num_planes = np                                                  \
}

@@ -77,7 +80,24 @@ alpha, chroma, count, bp, flg, fm, np) \
	.unpack_count = 2,                                                \
	.bpp = 2,                                                         \
	.fetch_mode = fm,                                                 \
	.flag = flg,                                                      \
	.flag = {(flg)},                                                  \
	.num_planes = np                                                  \
}

#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
{                                                                         \
	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
	.fetch_planes = SDE_PLANE_PSEUDO_PLANAR,                          \
	.alpha_enable = false,                                            \
	.element = { (e0), (e1), 0, 0 },                                  \
	.bits = { g, b, r, a },                                           \
	.chroma_sample = chroma,                                          \
	.unpack_align_msb = 1,                                            \
	.unpack_tight = 0,                                                \
	.unpack_count = 2,                                                \
	.bpp = 2,                                                         \
	.fetch_mode = fm,                                                 \
	.flag = {(flg)},                                                  \
	.num_planes = np                                                  \
}

@@ -95,10 +115,20 @@ flg, fm, np) \
	.unpack_count = 1,                                                \
	.bpp = bp,                                                        \
	.fetch_mode = fm,                                                 \
	.flag = flg,                                                      \
	.flag = {(flg)},                                                  \
	.num_planes = np                                                  \
}

/*
 * struct sde_media_color_map - maps drm format to media format
 * @format: DRM base pixel format
 * @color: Media API color related to DRM format
 */
struct sde_media_color_map {
	uint32_t format;
	uint32_t color;
};

static const struct sde_format sde_format_map[] = {
	INTERLEAVED_RGB_FMT(ARGB8888,
		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
@@ -421,6 +451,30 @@ static const struct sde_format sde_format_map_ubwc[] = {
		SDE_FETCH_UBWC, 4),
};

static const struct sde_format sde_format_map_p010[] = {
	PSEUDO_YUV_FMT_LOOSE(NV12,
		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
		C1_B_Cb, C2_R_Cr,
		SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
		SDE_FETCH_LINEAR, 2),
};

static const struct sde_format sde_format_map_p010_ubwc[] = {
	PSEUDO_YUV_FMT_LOOSE(NV12,
		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
		C1_B_Cb, C2_R_Cr,
		SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
		SDE_FETCH_UBWC, 4),
};

static const struct sde_format sde_format_map_tp10_ubwc[] = {
	PSEUDO_YUV_FMT(NV12,
		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
		C1_B_Cb, C2_R_Cr,
		SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
		SDE_FETCH_UBWC, 4),
};

/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
 *   Note: Not using the drm_format_*_subsampling since we have formats
 */
@@ -452,6 +506,37 @@ static void _sde_get_v_h_subsample_rate(
	}
}

static int _sde_format_get_media_color_ubwc(const struct sde_format *fmt)
{
	static const struct sde_media_color_map sde_media_ubwc_map[] = {
		{DRM_FORMAT_RGBA8888, COLOR_FMT_RGBA8888_UBWC},
		{DRM_FORMAT_RGBX8888, COLOR_FMT_RGBA8888_UBWC},
		{DRM_FORMAT_RGBA1010102, COLOR_FMT_RGBA1010102_UBWC},
		{DRM_FORMAT_RGBX1010102, COLOR_FMT_RGBA1010102_UBWC},
		{DRM_FORMAT_RGB565, COLOR_FMT_RGB565_UBWC},
	};
	int color_fmt = -1;
	int i;

	if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
		if (SDE_FORMAT_IS_DX(fmt)) {
			if (fmt->unpack_tight)
				color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
			else
				color_fmt = COLOR_FMT_P010_UBWC;
		} else
			color_fmt = COLOR_FMT_NV12_UBWC;
		return color_fmt;
	}

	for (i = 0; i < ARRAY_SIZE(sde_media_ubwc_map); ++i)
		if (fmt->base.pixel_format == sde_media_ubwc_map[i].format) {
			color_fmt = sde_media_ubwc_map[i].color;
			break;
		}
	return color_fmt;
}

static int _sde_format_get_plane_sizes_ubwc(
		const struct sde_format *fmt,
		const uint32_t width,
@@ -459,6 +544,7 @@ static int _sde_format_get_plane_sizes_ubwc(
		struct sde_hw_fmt_layout *layout)
{
	int i;
	int color;

	memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
	layout->format = fmt;
@@ -466,84 +552,53 @@ static int _sde_format_get_plane_sizes_ubwc(
	layout->height = height;
	layout->num_planes = fmt->num_planes;

	if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
		uint32_t y_stride_alignment, uv_stride_alignment;
		uint32_t y_height_alignment, uv_height_alignment;
		uint32_t y_tile_width = 32;
		uint32_t y_tile_height = 8;
		uint32_t uv_tile_width = y_tile_width / 2;
		uint32_t uv_tile_height = y_tile_height;
		uint32_t y_bpp_numer = 1, y_bpp_denom = 1;
		uint32_t uv_bpp_numer = 1, uv_bpp_denom = 1;

		y_stride_alignment = 128;
		uv_stride_alignment = 64;
		y_height_alignment = 32;
		uv_height_alignment = 32;
		y_bpp_numer = 1;
		uv_bpp_numer = 2;
		y_bpp_denom = 1;
		uv_bpp_denom = 1;
	color = _sde_format_get_media_color_ubwc(fmt);
	if (color < 0) {
		DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
			fmt->base.pixel_format);
		return -EINVAL;
	}

	if (SDE_FORMAT_IS_YUV(layout->format)) {
		uint32_t y_sclines, uv_sclines;
		uint32_t y_meta_scanlines = 0;
		uint32_t uv_meta_scanlines = 0;

		layout->num_planes = 4;
		/* Y bitstream stride and plane size */
		layout->plane_pitch[0] = ALIGN(width, y_stride_alignment);
		layout->plane_pitch[0] = (layout->plane_pitch[0] * y_bpp_numer)
				/ y_bpp_denom;
		layout->plane_size[0] = ALIGN(layout->plane_pitch[0] *
				ALIGN(height, y_height_alignment), 4096);

		/* CbCr bitstream stride and plane size */
		layout->plane_pitch[1] = ALIGN(width / 2, uv_stride_alignment);
		layout->plane_pitch[1] = (layout->plane_pitch[1] * uv_bpp_numer)
				/ uv_bpp_denom;
		layout->plane_size[1] = ALIGN(layout->plane_pitch[1] *
			ALIGN(height / 2, uv_height_alignment), 4096);

		/* Y meta data stride and plane size */
		layout->plane_pitch[2] = ALIGN(
				DIV_ROUND_UP(width, y_tile_width), 64);
		layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
			ALIGN(DIV_ROUND_UP(height, y_tile_height), 16), 4096);

		/* CbCr meta data stride and plane size */
		layout->plane_pitch[3] = ALIGN(
				DIV_ROUND_UP(width / 2, uv_tile_width), 64);
		layout->plane_size[3] = ALIGN(layout->plane_pitch[3] *
			ALIGN(DIV_ROUND_UP(height / 2, uv_tile_height), 16),
			4096);

	} else if (fmt->base.pixel_format == DRM_FORMAT_ABGR8888 ||
		fmt->base.pixel_format == DRM_FORMAT_XBGR8888    ||
		fmt->base.pixel_format == DRM_FORMAT_BGRA1010102 ||
		fmt->base.pixel_format == DRM_FORMAT_BGRX1010102 ||
		fmt->base.pixel_format == DRM_FORMAT_BGR565) {

		uint32_t stride_alignment, aligned_bitstream_width;

		if (fmt->base.pixel_format == DRM_FORMAT_BGR565)
			stride_alignment = 128;
		else
			stride_alignment = 64;
		layout->num_planes = 3;
		layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width);
		y_sclines = VENUS_Y_SCANLINES(color, height);
		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
			y_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);

		layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width);
		uv_sclines = VENUS_UV_SCANLINES(color, height);
		layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] *
			uv_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);

		layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width);
		y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height);
		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
			y_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);

		layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width);
		uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height);
		layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] *
			uv_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);

	} else {
		uint32_t rgb_scanlines, rgb_meta_scanlines;

		/* Nothing in plane[1] */
		layout->num_planes = 3;

		/* RGB bitstream stride and plane size */
		aligned_bitstream_width = ALIGN(width, stride_alignment);
		layout->plane_pitch[0] = aligned_bitstream_width * fmt->bpp;
		layout->plane_size[0] = ALIGN(fmt->bpp * aligned_bitstream_width
				* ALIGN(height, 16), 4096);
		layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width);
		rgb_scanlines = VENUS_RGB_SCANLINES(color, height);
		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
			rgb_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);

		/* RGB meta data stride and plane size */
		layout->plane_pitch[2] = ALIGN(DIV_ROUND_UP(
				aligned_bitstream_width, 16), 64);
		layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
			ALIGN(DIV_ROUND_UP(height, 4), 16), 4096);
	} else {
		DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
			fmt->base.pixel_format);
		return -EINVAL;
		layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width);
		rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height);
		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
			rgb_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
	}

	for (i = 0; i < SDE_MAX_PLANES; i++)
@@ -574,6 +629,7 @@ static int _sde_format_get_plane_sizes_linear(
	} else {
		uint32_t v_subsample, h_subsample;
		uint32_t chroma_samp;
		uint32_t bpp = 1;

		chroma_samp = fmt->chroma_sample;
		_sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
@@ -584,8 +640,11 @@ static int _sde_format_get_plane_sizes_linear(
			return -EINVAL;
		}

		layout->plane_pitch[0] = width;
		layout->plane_pitch[1] = width / h_subsample;
		if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
			(SDE_FORMAT_IS_DX(fmt)))
			bpp = 2;
		layout->plane_pitch[0] = width * bpp;
		layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
		layout->plane_size[0] = layout->plane_pitch[0] * height;
		layout->plane_size[1] = layout->plane_pitch[1] *
				(height / v_subsample);
@@ -874,6 +933,7 @@ int sde_format_check_modified_format(
			DRM_ERROR("invalid handle for plane %d\n", i);
			return -EINVAL;
		}
		if ((i == 0) || (bos[i] != bos[0]))
			bos_total_size += bos[i]->size;
	}

@@ -926,6 +986,23 @@ const struct sde_format *sde_get_sde_format_ext(
		map_size = ARRAY_SIZE(sde_format_map_ubwc);
		DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED", format);
		break;
	case DRM_FORMAT_MOD_QCOM_DX:
		map = sde_format_map_p010;
		map_size = ARRAY_SIZE(sde_format_map_p010);
		DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_DX", format);
		break;
	case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED):
		map = sde_format_map_p010_ubwc;
		map_size = ARRAY_SIZE(sde_format_map_p010_ubwc);
		DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED/DX", format);
		break;
	case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED |
		DRM_FORMAT_MOD_QCOM_TIGHT):
		map = sde_format_map_tp10_ubwc;
		map_size = ARRAY_SIZE(sde_format_map_tp10_ubwc);
		DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED/DX/TIGHT",
			format);
		break;
	default:
		DRM_ERROR("unsupported format modifier %llX\n", mod0);
		return NULL;
+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},
};
+12 −5
Original line number Diff line number Diff line
@@ -41,11 +41,18 @@
#define SDE_MAX_DE_CURVES		3
#endif

#define SDE_FORMAT_FLAG_YUV		(1 << 0)
#define SDE_FORMAT_FLAG_DX		(1 << 1)
enum sde_format_flags {
	SDE_FORMAT_FLAG_YUV_BIT,
	SDE_FORMAT_FLAG_DX_BIT,
	SDE_FORMAT_FLAG_BIT_MAX,
};

#define SDE_FORMAT_IS_YUV(X)		((X)->flag & SDE_FORMAT_FLAG_YUV)
#define SDE_FORMAT_IS_DX(X)		((X)->flag & SDE_FORMAT_FLAG_DX)
#define SDE_FORMAT_FLAG_YUV		BIT(SDE_FORMAT_FLAG_YUV_BIT)
#define SDE_FORMAT_FLAG_DX		BIT(SDE_FORMAT_FLAG_DX_BIT)
#define SDE_FORMAT_IS_YUV(X)		\
	(test_bit(SDE_FORMAT_FLAG_YUV_BIT, (X)->flag))
#define SDE_FORMAT_IS_DX(X)		\
	(test_bit(SDE_FORMAT_FLAG_DX_BIT, (X)->flag))
#define SDE_FORMAT_IS_LINEAR(X)		((X)->fetch_mode == SDE_FETCH_LINEAR)
#define SDE_FORMAT_IS_UBWC(X)		((X)->fetch_mode == SDE_FETCH_UBWC)

@@ -357,7 +364,7 @@ struct sde_format {
	u8 alpha_enable;
	u8 num_planes;
	enum sde_fetch_type fetch_mode;
	u32 flag;
	DECLARE_BITMAP(flag, SDE_FORMAT_FLAG_BIT_MAX);
	u16 tile_width;
	u16 tile_height;
};
Loading