Skip to content

Commit

Permalink
drm/color: Add color space plane property
Browse files Browse the repository at this point in the history
Add color space definitions for BT601, BT709, BT2020, and DCI-P3.

Default to BT709, the sRGB color space.

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
  • Loading branch information
Bhawanpreet Lakha authored and intel-lab-lkp committed Jul 30, 2021
1 parent bfba036 commit 72da10e
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 5 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Expand Up @@ -7279,8 +7279,10 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
BIT(DRM_COLOR_YCBCR_BT2020),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_SRGB),
DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_SRGB);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/arm/display/komeda/komeda_plane.c
Expand Up @@ -302,9 +302,11 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
BIT(DRM_COLOR_YCBCR_BT2020),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);
if (err)
goto cleanup;
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/arm/malidp_planes.c
Expand Up @@ -1023,15 +1023,17 @@ int malidp_de_planes_init(struct drm_device *drm)
/* default encoding for YUV->RGB is BT601 NARROW */
enum drm_color_encoding enc = DRM_COLOR_YCBCR_BT601;
enum drm_color_range range = DRM_COLOR_YCBCR_LIMITED_RANGE;
enum drm_color_space space = DRM_COLOR_SPACE_BT709;

ret = drm_plane_create_color_properties(&plane->base,
BIT(DRM_COLOR_YCBCR_BT601) | \
BIT(DRM_COLOR_YCBCR_BT709) | \
BIT(DRM_COLOR_YCBCR_BT2020),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
enc, range,
enc, range, space,
DRM_TF_UNDEFINED);
if (!ret)
/* program the HW registers */
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/armada/armada_overlay.c
Expand Up @@ -596,9 +596,11 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
BIT(DRM_COLOR_YCBCR_BT601) |
BIT(DRM_COLOR_YCBCR_BT709),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DEFAULT_ENCODING,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);

return ret;
Expand Down
58 changes: 55 additions & 3 deletions drivers/gpu/drm/drm_color_mgmt.c
Expand Up @@ -526,6 +526,13 @@ static const char * const color_range_name[] = {
[DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
};

static const char * const color_space_name[] = {
[DRM_COLOR_SPACE_BT601] = "ITU-R BT.601 RGB",
[DRM_COLOR_SPACE_BT709] = "ITU-R BT.709 RGB",
[DRM_COLOR_SPACE_BT2020] = "ITU-R BT.2020 RGB",
[DRM_COLOR_SPACE_P3] = "DCI-P3",
};

/**
* drm_get_color_encoding_name - return a string for color encoding
* @encoding: color encoding to compute name of
Expand Down Expand Up @@ -556,6 +563,21 @@ const char *drm_get_color_range_name(enum drm_color_range range)
return color_range_name[range];
}

/**
* drm_get_color_space_name - return a string for color space
* @space: color space to compute name of
*
* In contrast to the other drm_get_*_name functions this one here returns a
* const pointer and hence is threadsafe.
*/
const char *drm_get_color_space_name(enum drm_color_space space)
{
if (WARN_ON(space >= ARRAY_SIZE(color_space_name)))
return "unknown";

return color_space_name[space];
}

int drm_plane_create_sdr_white_level_property(struct drm_plane *plane){

struct drm_property *prop;
Expand Down Expand Up @@ -592,23 +614,28 @@ const char *drm_get_transfer_function_name(enum drm_transfer_function tf)
* @plane: plane object
* @supported_encodings: bitfield indicating supported color encodings
* @supported_ranges: bitfileld indicating supported color ranges
* @supported_spaces: bitfield indicating supported color spaces
* @supported_tfs: bitfield indicating supported transfer functions
* @default_encoding: default color encoding
* @default_range: default color range
* @default_space: default color space
* @default_tf: default color transfer function
*
* Create and attach plane specific COLOR_ENCODING, COLOR_RANGE and TRANSFER_FUNCTION
* properties to @plane. The supported encodings, ranges and tfs should
* be provided in supported_encodings, supported_ranges and supported_tfs bitmasks.
* Create and attach plane specific COLOR_ENCODING, COLOR_RANGE, COLOR_SPACE,
* and TRANSFER_FUNCTION properties to @plane. The supported encodings, ranges,
* spaces, and tfs should be provided in supported_encodings, supported_ranges,
* supported_spaces, and supported_tfs bitmasks.
* Each bit set in the bitmask indicates that its number as enum
* value is supported.
*/
int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
u32 supported_spaces,
u32 supported_tfs,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range,
enum drm_color_space default_space,
enum drm_transfer_function default_tf)
{
struct drm_device *dev = plane->dev;
Expand All @@ -628,6 +655,11 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
(supported_ranges & BIT(default_range)) == 0))
return -EINVAL;

if (WARN_ON(supported_spaces == 0 ||
(supported_spaces & -BIT(DRM_COLOR_SPACE_MAX)) != 0 ||
(supported_spaces & BIT(default_space)) == 0))
return -EINVAL;

if (WARN_ON(supported_tfs == 0 ||
(supported_tfs & -BIT(DRM_TF_MAX)) != 0 ||
(supported_tfs & BIT(default_tf)) == 0))
Expand Down Expand Up @@ -672,6 +704,26 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
plane->state->color_range = default_range;


len = 0;
for (i = 0; i < DRM_COLOR_SPACE_MAX; i++) {
if ((supported_spaces & BIT(i)) == 0)
continue;

enum_list[len].type = i;
enum_list[len].name = color_space_name[i];
len++;
}

prop = drm_property_create_enum(dev, 0, "COLOR_SPACE",
enum_list, len);
if (!prop)
return -ENOMEM;
plane->color_space_property = prop;
drm_object_attach_property(&plane->base, prop, default_space);
if (plane->state)
plane->state->color_space = default_space;


len = 0;
for (i = 0; i < DRM_TF_MAX; i++) {
if ((supported_tfs & BIT(i)) == 0)
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/display/intel_sprite.c
Expand Up @@ -1850,9 +1850,11 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
BIT(DRM_COLOR_YCBCR_BT709),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT709,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);

zpos = sprite + 1;
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/display/skl_universal_plane.c
Expand Up @@ -2160,9 +2160,11 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
supported_csc,
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT709,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);

drm_plane_create_alpha_property(&plane->base);
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/dispnv04/overlay.c
Expand Up @@ -345,9 +345,11 @@ nv10_overlay_init(struct drm_device *device)
BIT(DRM_COLOR_YCBCR_BT601) |
BIT(DRM_COLOR_YCBCR_BT709),
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);

plane->set_params = nv10_set_params;
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/omapdrm/omap_plane.c
Expand Up @@ -325,9 +325,11 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
BIT(DRM_COLOR_YCBCR_BT709),
BIT(DRM_COLOR_YCBCR_FULL_RANGE) |
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
BIT(DRM_COLOR_SPACE_BT709),
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_FULL_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);

return plane;
Expand Down
6 changes: 5 additions & 1 deletion drivers/gpu/drm/sun4i/sun8i_vi_layer.c
Expand Up @@ -543,7 +543,7 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
struct sun8i_mixer *mixer,
int index)
{
u32 supported_encodings, supported_ranges;
u32 supported_encodings, supported_ranges, supported_spaces;
unsigned int plane_cnt, format_count;
struct sun8i_vi_layer *layer;
const u32 *formats;
Expand Down Expand Up @@ -597,12 +597,16 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
BIT(DRM_COLOR_YCBCR_FULL_RANGE);

supported_spaces = BIT(DRM_COLOR_SPACE_BT709);

ret = drm_plane_create_color_properties(&layer->plane,
supported_encodings,
supported_ranges,
supported_spaces,
BIT(DRM_TF_UNDEFINED),
DRM_COLOR_YCBCR_BT709,
DRM_COLOR_YCBCR_LIMITED_RANGE,
DRM_COLOR_SPACE_BT709,
DRM_TF_UNDEFINED);
if (ret) {
dev_err(drm->dev, "Couldn't add encoding and range properties!\n");
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/tidss/tidss_plane.c
Expand Up @@ -186,9 +186,11 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
BIT(DRM_COLOR_YCBCR_BT709));
u32 color_ranges = (BIT(DRM_COLOR_YCBCR_FULL_RANGE) |
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE));
u32 color_spaces = BIT(DRM_COLOR_SPACE_BY709);
u32 transfer_functions = BIT(DRM_TF_UNDEFINED;
u32 default_encoding = DRM_COLOR_YCBCR_BT601;
u32 default_range = DRM_COLOR_YCBCR_FULL_RANGE;
u32 default_space = DRM_COLOR_SPACE_BT709;
u32 default_tf = DRM_TF_UNDEFINED;;
u32 blend_modes = (BIT(DRM_MODE_BLEND_PREMULTI) |
BIT(DRM_MODE_BLEND_COVERAGE));
Expand Down Expand Up @@ -219,9 +221,11 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
ret = drm_plane_create_color_properties(&tplane->plane,
color_encodings,
color_ranges,
color_spaces,
transfer_functions,
default_encoding,
default_range,
default_space,
default_tf);
if (ret)
goto err;
Expand Down
16 changes: 16 additions & 0 deletions include/drm/drm_color_mgmt.h
Expand Up @@ -99,6 +99,9 @@ static inline int drm_color_lut_size(const struct drm_property_blob *blob)
return blob->length / sizeof(struct drm_color_lut);
}

/**
* drm_color_encoding - describes the coefficient for YCbCr-RGB conversion
*/
enum drm_color_encoding {
DRM_COLOR_YCBCR_BT601,
DRM_COLOR_YCBCR_BT709,
Expand All @@ -112,12 +115,25 @@ enum drm_color_range {
DRM_COLOR_RANGE_MAX,
};

/**
* drm_color_space - describes the color space (primaries & white point)
*/
enum drm_color_space {
DRM_COLOR_SPACE_BT601,
DRM_COLOR_SPACE_BT709,
DRM_COLOR_SPACE_BT2020,
DRM_COLOR_SPACE_P3,
DRM_COLOR_SPACE_MAX,
};

int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
u32 supported_spaces,
u32 supported_tf,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range,
enum drm_color_space default_space,
enum drm_transfer_function default_tf);

/**
Expand Down
16 changes: 16 additions & 0 deletions include/drm/drm_plane.h
Expand Up @@ -179,6 +179,13 @@ struct drm_plane_state {
*/
enum drm_color_range color_range;

/**
* @color_space
*
* Color space (primaries & white point) of the plane
*/
enum drm_color_space color_space;

/**
* @transfer_function:
*
Expand Down Expand Up @@ -754,6 +761,15 @@ struct drm_plane {
* See drm_plane_create_color_properties().
*/
struct drm_property *color_range_property;
/**
* @color_space_property:
*
* Optional "COLOR_SPACE" enum property for specifying
* the color space (i.e. primaries and white point) of
* the plane.
* See drm_plane_create_color_properties().
*/
struct drm_property *color_space_property;
/**
* @transfer_function_property:
*
Expand Down

0 comments on commit 72da10e

Please sign in to comment.