1 From 5278eeece5b7b66019cf9c1a833c815cff9819ec Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 19 Mar 2021 13:05:53 +0100
4 Subject: [PATCH] drm/connector: Add helper to compare HDR metadata
6 All the drivers that support the HDR metadata property have a similar
7 function to compare the metadata from one connector state to the next,
8 and force a mode change if they differ.
10 All these functions run pretty much the same code, so let's turn it into
11 an helper that can be shared across those drivers.
13 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
15 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +-------------
16 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +----------
17 drivers/gpu/drm/drm_connector.c | 28 +++++++++++++++++++
18 drivers/gpu/drm/i915/display/intel_atomic.c | 13 +--------
19 include/drm/drm_connector.h | 2 ++
20 5 files changed, 33 insertions(+), 48 deletions(-)
22 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
23 +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
24 @@ -5509,25 +5509,6 @@ static int fill_hdr_info_packet(const st
29 -is_hdr_metadata_different(const struct drm_connector_state *old_state,
30 - const struct drm_connector_state *new_state)
32 - struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
33 - struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
35 - if (old_blob != new_blob) {
36 - if (old_blob && new_blob &&
37 - old_blob->length == new_blob->length)
38 - return memcmp(old_blob->data, new_blob->data,
48 amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
49 struct drm_atomic_state *state)
50 @@ -5543,7 +5524,7 @@ amdgpu_dm_connector_atomic_check(struct
54 - if (is_hdr_metadata_different(old_con_state, new_con_state)) {
55 + if (!drm_connector_atomic_hdr_metadata_equal(old_con_state, new_con_state)) {
56 struct dc_info_packet hdr_infopacket;
58 ret = fill_hdr_info_packet(new_con_state, &hdr_infopacket);
59 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
60 +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
61 @@ -2403,21 +2403,6 @@ static int dw_hdmi_connector_get_modes(s
65 -static bool hdr_metadata_equal(const struct drm_connector_state *old_state,
66 - const struct drm_connector_state *new_state)
68 - struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
69 - struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
71 - if (!old_blob || !new_blob)
72 - return old_blob == new_blob;
74 - if (old_blob->length != new_blob->length)
77 - return !memcmp(old_blob->data, new_blob->data, old_blob->length);
80 static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
81 struct drm_atomic_state *state)
83 @@ -2431,7 +2416,7 @@ static int dw_hdmi_connector_atomic_chec
87 - if (!hdr_metadata_equal(old_state, new_state)) {
88 + if (!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
89 crtc_state = drm_atomic_get_crtc_state(state, crtc);
90 if (IS_ERR(crtc_state))
91 return PTR_ERR(crtc_state);
92 --- a/drivers/gpu/drm/drm_connector.c
93 +++ b/drivers/gpu/drm/drm_connector.c
94 @@ -2168,6 +2168,34 @@ int drm_connector_attach_hdr_output_meta
95 EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
98 + * drm_connector_atomic_hdr_metadata_equal - checks if the hdr metadata changed
99 + * @old_state: old connector state to compare
100 + * @new_state: new connector state to compare
102 + * This is used by HDR-enabled drivers to test whether the HDR metadata
103 + * have changed between two different connector state (and thus probably
104 + * requires a full blown mode change).
107 + * True if the metadata are equal, False otherwise
109 +bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
110 + struct drm_connector_state *new_state)
112 + struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
113 + struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
115 + if (!old_blob || !new_blob)
116 + return old_blob == new_blob;
118 + if (old_blob->length != new_blob->length)
121 + return !memcmp(old_blob->data, new_blob->data, old_blob->length);
123 +EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
126 * drm_connector_set_vrr_capable_property - sets the variable refresh rate
127 * capable property for a connector
128 * @connector: drm connector
129 --- a/drivers/gpu/drm/i915/display/intel_atomic.c
130 +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
131 @@ -109,16 +109,6 @@ int intel_digital_connector_atomic_set_p
135 -static bool blob_equal(const struct drm_property_blob *a,
136 - const struct drm_property_blob *b)
139 - return a->length == b->length &&
140 - !memcmp(a->data, b->data, a->length);
145 int intel_digital_connector_atomic_check(struct drm_connector *conn,
146 struct drm_atomic_state *state)
148 @@ -150,8 +140,7 @@ int intel_digital_connector_atomic_check
149 new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio ||
150 new_conn_state->base.content_type != old_conn_state->base.content_type ||
151 new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode ||
152 - !blob_equal(new_conn_state->base.hdr_output_metadata,
153 - old_conn_state->base.hdr_output_metadata))
154 + !drm_connector_atomic_hdr_metadata_equal(old_state, new_state))
155 crtc_state->mode_changed = true;
158 --- a/include/drm/drm_connector.h
159 +++ b/include/drm/drm_connector.h
160 @@ -1623,6 +1623,8 @@ int drm_connector_attach_scaling_mode_pr
161 int drm_connector_attach_vrr_capable_property(
162 struct drm_connector *connector);
163 int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
164 +bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
165 + struct drm_connector_state *new_state);
166 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
167 int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector);
168 int drm_mode_create_dp_colorspace_property(struct drm_connector *connector);