OSDN Git Service

drm/msm/sde: expose 10 bit pixel format capabilities
authorabeykun <abeykun@codeaurora.org>
Tue, 20 Dec 2016 18:06:09 +0000 (13:06 -0500)
committerSrikanth Rajagopalan <rasrik@codeaurora.org>
Tue, 27 Jun 2017 02:35:01 +0000 (19:35 -0700)
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>
drivers/gpu/drm/msm/sde/sde_hw_catalog.c
drivers/gpu/drm/msm/sde/sde_hw_catalog.h
drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h

index 17b678c..4f84e31 100644 (file)
@@ -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;
 
index bca221d..01204df 100644 (file)
@@ -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 {
index 2966944..ca3ebfb 100644 (file)
@@ -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},
+};