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

This commit is contained in:
Linux Build Service Account 2017-06-27 04:28:20 -07:00 committed by Gerrit - the friendly Code Review server
commit 5728dc4956
6 changed files with 408 additions and 97 deletions

View file

@ -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,86 +552,55 @@ 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;
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;
/* Nothing in plane[1] */
/* 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);
/* 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 {
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;
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;
layout->num_planes = 3;
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);
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++)
layout->total_size += layout->plane_size[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,7 +933,8 @@ int sde_format_check_modified_format(
DRM_ERROR("invalid handle for plane %d\n", i);
return -EINVAL;
}
bos_total_size += bos[i]->size;
if ((i == 0) || (bos[i] != bos[0]))
bos_total_size += bos[i]->size;
}
if (bos_total_size < layout.total_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;

View 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;

View 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 {

View 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},
};

View file

@ -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;
};

View file

@ -241,8 +241,23 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
/*
* QTI DX Format
*
* Refers to a DX variant of the base format.
* Implementation may be platform and base-format specific.
*/
#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
/*
* QTI Tight Format
*
* Refers to a tightly packed variant of the base format.
* Implementation may be platform and base-format specific.
*/
#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4)
#if defined(__cplusplus)
}
#endif
#endif /* DRM_FOURCC_H */