Skip to content
Permalink
Browse files
drm/connector: Add helper to compare HDR metadata
All the drivers that support the HDR metadata property have a similar
function to compare the metadata from one connector state to the next,
and force a mode change if they differ.

All these functions run pretty much the same code, so let's turn it into
an helper that can be shared across those drivers.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
  • Loading branch information
mripard authored and intel-lab-lkp committed Mar 19, 2021
1 parent 9958fb5 commit e12a697958cd6235d678394450f4cb7dbf958ed5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 48 deletions.
@@ -5958,25 +5958,6 @@ static int fill_hdr_info_packet(const struct drm_connector_state *state,
return 0;
}

static bool
is_hdr_metadata_different(const struct drm_connector_state *old_state,
const struct drm_connector_state *new_state)
{
struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
struct drm_property_blob *new_blob = new_state->hdr_output_metadata;

if (old_blob != new_blob) {
if (old_blob && new_blob &&
old_blob->length == new_blob->length)
return memcmp(old_blob->data, new_blob->data,
old_blob->length);

return true;
}

return false;
}

static int
amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
struct drm_atomic_state *state)
@@ -5994,7 +5975,7 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
if (!crtc)
return 0;

if (is_hdr_metadata_different(old_con_state, new_con_state)) {
if (!drm_connector_atomic_hdr_metadata_equal(old_con_state, new_con_state)) {
struct dc_info_packet hdr_infopacket;

ret = fill_hdr_info_packet(new_con_state, &hdr_infopacket);
@@ -2395,21 +2395,6 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
return ret;
}

static bool hdr_metadata_equal(const struct drm_connector_state *old_state,
const struct drm_connector_state *new_state)
{
struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
struct drm_property_blob *new_blob = new_state->hdr_output_metadata;

if (!old_blob || !new_blob)
return old_blob == new_blob;

if (old_blob->length != new_blob->length)
return false;

return !memcmp(old_blob->data, new_blob->data, old_blob->length);
}

static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
struct drm_atomic_state *state)
{
@@ -2423,7 +2408,7 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
if (!crtc)
return 0;

if (!hdr_metadata_equal(old_state, new_state)) {
if (!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
@@ -2170,6 +2170,34 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn
}
EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);

/**
* drm_connector_atomic_hdr_metadata_equal - checks if the hdr metadata changed
* @old_state: old connector state to compare
* @new_state: new connector state to compare
*
* This is used by HDR-enabled drivers to test whether the HDR metadata
* have changed between two different connector state (and thus probably
* requires a full blown mode change).
*
* Returns:
* True if the metadata are equal, False otherwise
*/
bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
struct drm_connector_state *new_state)
{
struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
struct drm_property_blob *new_blob = new_state->hdr_output_metadata;

if (!old_blob || !new_blob)
return old_blob == new_blob;

if (old_blob->length != new_blob->length)
return false;

return !memcmp(old_blob->data, new_blob->data, old_blob->length);
}
EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);

/**
* drm_connector_set_vrr_capable_property - sets the variable refresh rate
* capable property for a connector
@@ -109,16 +109,6 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector,
return -EINVAL;
}

static bool blob_equal(const struct drm_property_blob *a,
const struct drm_property_blob *b)
{
if (a && b)
return a->length == b->length &&
!memcmp(a->data, b->data, a->length);

return !a == !b;
}

int intel_digital_connector_atomic_check(struct drm_connector *conn,
struct drm_atomic_state *state)
{
@@ -149,8 +139,7 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn,
new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio ||
new_conn_state->base.content_type != old_conn_state->base.content_type ||
new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode ||
!blob_equal(new_conn_state->base.hdr_output_metadata,
old_conn_state->base.hdr_output_metadata))
!drm_connector_atomic_hdr_metadata_equal(old_state, new_state))
crtc_state->mode_changed = true;

return 0;
@@ -1672,6 +1672,8 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
int drm_connector_attach_vrr_capable_property(
struct drm_connector *connector);
int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
struct drm_connector_state *new_state);
int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector);
int drm_mode_create_dp_colorspace_property(struct drm_connector *connector);

0 comments on commit e12a697

Please sign in to comment.