Loading drivers/gpu/drm/msm/sde/sde_formats.c +157 −80 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -42,7 +45,7 @@ bp, flg, fm, np) \ .unpack_count = uc, \ .bpp = bp, \ .fetch_mode = fm, \ .flag = flg, \ .flag = {(flg)}, \ .num_planes = np \ } Loading @@ -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 \ } Loading @@ -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 \ } Loading @@ -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, Loading Loading @@ -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 */ Loading Loading @@ -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, Loading @@ -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; Loading @@ -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++) Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.c +164 −7 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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)++; Loading Loading @@ -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)++; Loading Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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: Loading @@ -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) Loading Loading @@ -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); } Loading Loading @@ -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; Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.h +14 −2 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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; }; /** Loading Loading @@ -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; Loading Loading @@ -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 { Loading drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h +43 −0 Original line number Diff line number Diff line Loading @@ -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}, Loading @@ -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}, }; drivers/gpu/drm/msm/sde/sde_hw_mdss.h +12 −5 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 Loading
drivers/gpu/drm/msm/sde/sde_formats.c +157 −80 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -42,7 +45,7 @@ bp, flg, fm, np) \ .unpack_count = uc, \ .bpp = bp, \ .fetch_mode = fm, \ .flag = flg, \ .flag = {(flg)}, \ .num_planes = np \ } Loading @@ -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 \ } Loading @@ -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 \ } Loading @@ -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, Loading Loading @@ -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 */ Loading Loading @@ -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, Loading @@ -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; Loading @@ -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++) Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.c +164 −7 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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)++; Loading Loading @@ -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)++; Loading Loading @@ -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); } Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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: Loading @@ -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) Loading Loading @@ -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); } Loading Loading @@ -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; Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.h +14 −2 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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; }; /** Loading Loading @@ -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; Loading Loading @@ -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 { Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog_format.h +43 −0 Original line number Diff line number Diff line Loading @@ -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}, Loading @@ -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}, };
drivers/gpu/drm/msm/sde/sde_hw_mdss.h +12 −5 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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