summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorabeykun <abeykun@codeaurora.org>2016-12-20 13:06:09 -0500
committerSrikanth Rajagopalan <rasrik@codeaurora.org>2017-06-26 19:35:01 -0700
commit1ce0cb61aac3f2e399184059ea06f39ef8f6ba99 (patch)
tree745f30c2a8bf117c8ef3307940650a3a77211ff1
parent4482a89a67a07b6eef2381c2f4a5a559017d9581 (diff)
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: Alexander Beykun <abeykun@codeaurora.org>
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.c171
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.h16
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h43
3 files changed, 221 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index 17b678cfca46..4f84e31db5f6 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -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;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
index bca221d2a959..01204df48871 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
@@ -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)
@@ -457,7 +458,8 @@ struct sde_ctl_cfg {
* @sblk: SSPP sub-blocks information
* @xin_id: bus client identifier
* @clk_ctrl clock control identifier
- *@name source pipe name
+ * @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 {
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h
index 296694422653..ca3ebfb44a91 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h
@@ -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},
+};