diff options
| author | abeykun <abeykun@codeaurora.org> | 2016-12-20 13:06:09 -0500 |
|---|---|---|
| committer | Srikanth Rajagopalan <rasrik@codeaurora.org> | 2017-06-26 19:35:01 -0700 |
| commit | 1ce0cb61aac3f2e399184059ea06f39ef8f6ba99 (patch) | |
| tree | 745f30c2a8bf117c8ef3307940650a3a77211ff1 | |
| parent | 4482a89a67a07b6eef2381c2f4a5a559017d9581 (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.c | 171 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.h | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h | 43 |
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}, +}; |
