All the drivers that implement HDR output call pretty much the same function to initialise the hdr_output_metadata property, and while the creation of that property is in a helper, every driver uses the same code to attach it.
Provide a helper for it as well
Signed-off-by: Maxime Ripard maxime@cerno.tech --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +--- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +-- drivers/gpu/drm/drm_connector.c | 21 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_hdmi.c | 3 +-- include/drm/drm_connector.h | 1 + 5 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 22124f76d0b5..06908a3cee0f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7017,9 +7017,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (connector_type == DRM_MODE_CONNECTOR_HDMIA || connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP) { - drm_object_attach_property( - &aconnector->base.base, - dm->ddev->mode_config.hdr_output_metadata_property, 0); + drm_connector_attach_hdr_output_metadata_property(&aconnector->base);
if (!aconnector->mst_port) drm_connector_attach_vrr_capable_property(&aconnector->base); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index dda4fa9a1a08..f24bbb840dbf 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2492,8 +2492,7 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) drm_connector_attach_max_bpc_property(connector, 8, 16);
if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) - drm_object_attach_property(&connector->base, - connector->dev->mode_config.hdr_output_metadata_property, 0); + drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 98b6ec45ef96..e25248e23e18 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2149,6 +2149,27 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector, } EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
+/** + * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property + * @connector: connector to attach the property on. + * + * This is used to allow the userspace to send HDR Metadata to the + * driver. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop = dev->mode_config.hdr_output_metadata_property; + + drm_object_attach_property(&connector->base, prop, 0); + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property); + /** * drm_connector_set_vrr_capable_property - sets the variable refresh rate * capable property for a connector diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index c5959590562b..52c051efb7b7 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2958,8 +2958,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c drm_connector_attach_content_type_property(connector);
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) - drm_object_attach_property(&connector->base, - connector->dev->mode_config.hdr_output_metadata_property, 0); + drm_connector_attach_hdr_output_metadata_property(connector);
if (!HAS_GMCH(dev_priv)) drm_connector_attach_max_bpc_property(connector, 8, 12); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 1922b278ffad..32172dab8427 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1671,6 +1671,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); +int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector); 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);
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 --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +------------- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +---------- drivers/gpu/drm/drm_connector.c | 28 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_atomic.c | 13 +-------- include/drm/drm_connector.h | 2 ++ 5 files changed, 33 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 06908a3cee0f..4eb5201e566a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5924,25 +5924,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) @@ -5960,7 +5941,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); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index f24bbb840dbf..f871e33c2fc9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -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); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index e25248e23e18..d781a3a1e9bf 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -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 diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index e00fdc47c0eb..efec9454af5a 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -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; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 32172dab8427..1f51d73ca715 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -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);
Hi Maxime,
I love your patch! Yet something to improve:
[auto build test ERROR on drm-intel/for-linux-next] [also build test ERROR on drm-tip/drm-tip linus/master v5.12-rc3 next-20210319] [cannot apply to anholt/for-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Maxime-Ripard/drm-connector-Create-... base: git://anongit.freedesktop.org/drm-intel for-linux-next config: sparc64-randconfig-r035-20210318 (attached as .config) compiler: sparc64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/e12a697958cd6235d678394450f4cb7dbf95... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Maxime-Ripard/drm-connector-Create-a-helper-to-attach-the-hdr_output_metadata-property/20210319-205157 git checkout e12a697958cd6235d678394450f4cb7dbf958ed5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=sparc64
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'amdgpu_dm_commit_cursors': drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:7678:44: warning: variable 'new_plane_state' set but not used [-Wunused-but-set-variable] 7678 | struct drm_plane_state *old_plane_state, *new_plane_state; | ^~~~~~~~~~~~~~~ drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'amdgpu_dm_atomic_commit_tail':
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:8327:4: error: implicit declaration of function 'is_hdr_metadata_different' [-Werror=implicit-function-declaration]
8327 | is_hdr_metadata_different(old_con_state, new_con_state); | ^~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors
Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for FRAME_POINTER Depends on DEBUG_KERNEL && (M68K || UML || SUPERH) || ARCH_WANT_FRAME_POINTERS || MCOUNT Selected by - LATENCYTOP && DEBUG_KERNEL && STACKTRACE_SUPPORT && PROC_FS && !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC && !X86 - LOCKDEP && DEBUG_KERNEL && LOCK_DEBUGGING_SUPPORT && !MIPS && !PPC && !ARM && !S390 && !MICROBLAZE && !ARC && !X86
vim +/is_hdr_metadata_different +8327 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c
e7b07ceef2a650 Harry Wentland 2017-08-10 8293 02d6a6fcdf68c4 David Francis 2018-12-18 8294 /* Handle connector state changes */ c2cea7063b85fc Leo (Sunpeng Li 2017-10-12 8295) for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { 54d76575246798 Leo (Sunpeng Li 2017-10-12 8296) struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); 54d76575246798 Leo (Sunpeng Li 2017-10-12 8297) struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); 54d76575246798 Leo (Sunpeng Li 2017-10-12 8298) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); efc8278eecfd5e Anson Jacob 2021-02-18 8299 struct dc_surface_update dummy_updates[MAX_SURFACES]; 19afd79951e630 Nathan Chancellor 2019-02-01 8300 struct dc_stream_update stream_update; b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8301 struct dc_info_packet hdr_packet; e7b07ceef2a650 Harry Wentland 2017-08-10 8302 struct dc_stream_status *status = NULL; b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8303 bool abm_changed, hdr_changed, scaling_changed; e7b07ceef2a650 Harry Wentland 2017-08-10 8304 efc8278eecfd5e Anson Jacob 2021-02-18 8305 memset(&dummy_updates, 0, sizeof(dummy_updates)); 19afd79951e630 Nathan Chancellor 2019-02-01 8306 memset(&stream_update, 0, sizeof(stream_update)); 19afd79951e630 Nathan Chancellor 2019-02-01 8307 44d09c6a577c8e Harry Wentland 2018-03-15 8308 if (acrtc) { 0bc9706db3a35b Leo (Sunpeng Li 2017-10-12 8309) new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); 44d09c6a577c8e Harry Wentland 2018-03-15 8310 old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); 44d09c6a577c8e Harry Wentland 2018-03-15 8311 } 0bc9706db3a35b Leo (Sunpeng Li 2017-10-12 8312) e7b07ceef2a650 Harry Wentland 2017-08-10 8313 /* Skip any modesets/resets */ 0bc9706db3a35b Leo (Sunpeng Li 2017-10-12 8314) if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state)) e7b07ceef2a650 Harry Wentland 2017-08-10 8315 continue; e7b07ceef2a650 Harry Wentland 2017-08-10 8316 54d76575246798 Leo (Sunpeng Li 2017-10-12 8317) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); c1ee92f94ce3b9 David Francis 2018-11-26 8318 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); c1ee92f94ce3b9 David Francis 2018-11-26 8319 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8320 scaling_changed = is_scaling_state_different(dm_new_con_state, b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8321 dm_old_con_state); b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8322 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8323 abm_changed = dm_new_crtc_state->abm_level != b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8324 dm_old_crtc_state->abm_level; b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8325 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8326 hdr_changed = b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 @8327 is_hdr_metadata_different(old_con_state, new_con_state); b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8328 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8329 if (!scaling_changed && !abm_changed && !hdr_changed) c1ee92f94ce3b9 David Francis 2018-11-26 8330 continue; e7b07ceef2a650 Harry Wentland 2017-08-10 8331 b6e881c947417e Dmytro Laktyushkin 2019-09-13 8332 stream_update.stream = dm_new_crtc_state->stream; b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8333 if (scaling_changed) { 54d76575246798 Leo (Sunpeng Li 2017-10-12 8334) update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode, b6e881c947417e Dmytro Laktyushkin 2019-09-13 8335 dm_new_con_state, dm_new_crtc_state->stream); e7b07ceef2a650 Harry Wentland 2017-08-10 8336 02d6a6fcdf68c4 David Francis 2018-12-18 8337 stream_update.src = dm_new_crtc_state->stream->src; 02d6a6fcdf68c4 David Francis 2018-12-18 8338 stream_update.dst = dm_new_crtc_state->stream->dst; 02d6a6fcdf68c4 David Francis 2018-12-18 8339 } 02d6a6fcdf68c4 David Francis 2018-12-18 8340 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8341 if (abm_changed) { 02d6a6fcdf68c4 David Francis 2018-12-18 8342 dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level; 02d6a6fcdf68c4 David Francis 2018-12-18 8343 02d6a6fcdf68c4 David Francis 2018-12-18 8344 stream_update.abm_level = &dm_new_crtc_state->abm_level; 02d6a6fcdf68c4 David Francis 2018-12-18 8345 } 70e8ffc55b98f3 Harry Wentland 2017-11-10 8346 b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8347 if (hdr_changed) { b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8348 fill_hdr_info_packet(new_con_state, &hdr_packet); b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8349 stream_update.hdr_static_metadata = &hdr_packet; b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8350 } b232d4ed92eafb Nicholas Kazlauskas 2019-05-28 8351 54d76575246798 Leo (Sunpeng Li 2017-10-12 8352) status = dc_stream_get_status(dm_new_crtc_state->stream); e7b07ceef2a650 Harry Wentland 2017-08-10 8353 WARN_ON(!status); 3be5262e353b8a Harry Wentland 2017-07-27 8354 WARN_ON(!status->plane_count); e7b07ceef2a650 Harry Wentland 2017-08-10 8355 02d6a6fcdf68c4 David Francis 2018-12-18 8356 /* 02d6a6fcdf68c4 David Francis 2018-12-18 8357 * TODO: DC refuses to perform stream updates without a dc_surface_update. 02d6a6fcdf68c4 David Francis 2018-12-18 8358 * Here we create an empty update on each plane. 02d6a6fcdf68c4 David Francis 2018-12-18 8359 * To fix this, DC should permit updating only stream properties. 02d6a6fcdf68c4 David Francis 2018-12-18 8360 */ 02d6a6fcdf68c4 David Francis 2018-12-18 8361 for (j = 0; j < status->plane_count; j++) efc8278eecfd5e Anson Jacob 2021-02-18 8362 dummy_updates[j].surface = status->plane_states[0]; 98e6436d3af5fe Anthony Koo 2018-08-21 8363 02d6a6fcdf68c4 David Francis 2018-12-18 8364 02d6a6fcdf68c4 David Francis 2018-12-18 8365 mutex_lock(&dm->dc_lock); 02d6a6fcdf68c4 David Francis 2018-12-18 8366 dc_commit_updates_for_stream(dm->dc, efc8278eecfd5e Anson Jacob 2021-02-18 8367 dummy_updates, 3be5262e353b8a Harry Wentland 2017-07-27 8368 status->plane_count, 02d6a6fcdf68c4 David Francis 2018-12-18 8369 dm_new_crtc_state->stream, efc8278eecfd5e Anson Jacob 2021-02-18 8370 &stream_update, efc8278eecfd5e Anson Jacob 2021-02-18 8371 dc_state); 02d6a6fcdf68c4 David Francis 2018-12-18 8372 mutex_unlock(&dm->dc_lock); e7b07ceef2a650 Harry Wentland 2017-08-10 8373 } e7b07ceef2a650 Harry Wentland 2017-08-10 8374 b5e83f6fe1f003 Nicholas Kazlauskas 2019-04-08 8375 /* Count number of newly disabled CRTCs for dropping PM refs later. */ e1fc2dca1295c4 Leo (Sunpeng Li 2017-10-18 8376) for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, e1fc2dca1295c4 Leo (Sunpeng Li 2017-10-18 8377) new_crtc_state, i) { fe2a19652918a5 Lyude Paul 2018-06-21 8378 if (old_crtc_state->active && !new_crtc_state->active) fe2a19652918a5 Lyude Paul 2018-06-21 8379 crtc_disable_count++; fe2a19652918a5 Lyude Paul 2018-06-21 8380 54d76575246798 Leo (Sunpeng Li 2017-10-12 8381) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); e1fc2dca1295c4 Leo (Sunpeng Li 2017-10-18 8382) dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); 66b0c973d7f74e Mario Kleiner 2019-03-29 8383 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8384 /* For freesync config update on crtc state and params for irq */ 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8385 update_stream_irq_parameters(dm, dm_new_crtc_state); 057be086603feb Nicholas Kazlauskas 2019-04-15 8386 66b0c973d7f74e Mario Kleiner 2019-03-29 8387 /* Handle vrr on->off / off->on transitions */ 66b0c973d7f74e Mario Kleiner 2019-03-29 8388 amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, 66b0c973d7f74e Mario Kleiner 2019-03-29 8389 dm_new_crtc_state); e7b07ceef2a650 Harry Wentland 2017-08-10 8390 } e7b07ceef2a650 Harry Wentland 2017-08-10 8391 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8392 /** 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8393 * Enable interrupts for CRTCs that are newly enabled or went through 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8394 * a modeset. It was intentionally deferred until after the front end 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8395 * state was modified to wait until the OTG was on and so the IRQ 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8396 * handlers didn't access stale or invalid state. 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8397 */ 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8398 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8399 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8400 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8401 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8402 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8403 if (new_crtc_state->active && 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8404 (!old_crtc_state->active || 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8405 drm_atomic_crtc_needs_modeset(new_crtc_state))) { 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8406 dc_stream_retain(dm_new_crtc_state->stream); 585d450c76d1d5 Aurabindo Pillai 2020-08-12 8407 acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; 8fe684e97c86e3 Nicholas Kazlauskas 2020-07-13 8408 manage_dm_interrupts(adev, acrtc, true); e2881d6d0a2653 Rodrigo Siqueira 2021-01-07 8409
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 2021-03-19 8:49 a.m., Maxime Ripard wrote:
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
Patches 1 & 2 are Reviewed-by: Harry Wentland harry.wentland@amd.com
Harry
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +------------- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +---------- drivers/gpu/drm/drm_connector.c | 28 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_atomic.c | 13 +-------- include/drm/drm_connector.h | 2 ++ 5 files changed, 33 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 06908a3cee0f..4eb5201e566a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5924,25 +5924,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)
@@ -5960,7 +5941,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);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index f24bbb840dbf..f871e33c2fc9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -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);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index e25248e23e18..d781a3a1e9bf 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -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
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index e00fdc47c0eb..efec9454af5a 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -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;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 32172dab8427..1f51d73ca715 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -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,
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);struct drm_connector_state *new_state);
Hi!
Dne petek, 19. marec 2021 ob 13:49:21 CET je Maxime Ripard napisal(a):
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
For bridge part: Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
Best regards, Jernej
From: Dave Stevenson dave.stevenson@raspberrypi.com
Now that we can export deeper colour depths, add in the signalling for HDR metadata.
Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Signed-off-by: Maxime Ripard maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_hdmi.c | 53 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_hdmi.h | 3 ++ 2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index eee9751009c2..c8846cf9dd24 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -214,6 +214,31 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) return ret; }
+static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + struct drm_connector_state *old_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_state = + drm_atomic_get_new_connector_state(state, connector); + struct drm_crtc *crtc = new_state->crtc; + + if (!crtc) + return 0; + + if (!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) { + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + crtc_state->mode_changed = true; + } + + return 0; +} + static void vc4_hdmi_connector_reset(struct drm_connector *connector) { struct vc4_hdmi_connector_state *old_state = @@ -263,6 +288,7 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { .get_modes = vc4_hdmi_connector_get_modes, + .atomic_check = vc4_hdmi_connector_atomic_check, };
static int vc4_hdmi_connector_init(struct drm_device *dev, @@ -299,6 +325,9 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, connector->interlace_allowed = 1; connector->doublescan_allowed = 0;
+ if (vc4_hdmi->variant->supports_hdr) + drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_encoder(connector, encoder);
return 0; @@ -432,6 +461,25 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder) vc4_hdmi_write_infoframe(encoder, &frame); }
+static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder) +{ + struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + struct drm_connector *connector = &vc4_hdmi->connector; + struct drm_connector_state *conn_state = connector->state; + union hdmi_infoframe frame; + + if (!vc4_hdmi->variant->supports_hdr) + return; + + if (!conn_state->hdr_output_metadata) + return; + + if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state)) + return; + + vc4_hdmi_write_infoframe(encoder, &frame); +} + static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); @@ -444,6 +492,8 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder) */ if (vc4_hdmi->audio.streaming) vc4_hdmi_set_audio_infoframe(encoder); + + vc4_hdmi_set_hdr_infoframe(encoder); }
static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder, @@ -2101,6 +2151,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = { .phy_rng_enable = vc4_hdmi_phy_rng_enable, .phy_rng_disable = vc4_hdmi_phy_rng_disable, .channel_map = vc4_hdmi_channel_map, + .supports_hdr = false, };
static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { @@ -2128,6 +2179,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { .phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_disable = vc5_hdmi_phy_rng_disable, .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, };
static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { @@ -2155,6 +2207,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { .phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_disable = vc5_hdmi_phy_rng_disable, .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, };
static const struct of_device_id vc4_hdmi_dt_match[] = { diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 3cebd1fd00fc..060bcaefbeb5 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -99,6 +99,9 @@ struct vc4_hdmi_variant {
/* Callback to get channel map */ u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask); + + /* Enables HDR metadata */ + bool supports_hdr; };
/* HDMI audio information */
Hi!
Dne petek, 19. marec 2021 ob 13:49:20 CET je Maxime Ripard napisal(a):
All the drivers that implement HDR output call pretty much the same function to initialise the hdr_output_metadata property, and while the creation of that property is in a helper, every driver uses the same code to attach it.
Provide a helper for it as well
Signed-off-by: Maxime Ripard maxime@cerno.tech
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +--- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +-- drivers/gpu/drm/drm_connector.c | 21 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_hdmi.c | 3 +-- include/drm/drm_connector.h | 1 + 5 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 22124f76d0b5..06908a3cee0f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7017,9 +7017,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, if (connector_type == DRM_MODE_CONNECTOR_HDMIA || connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP) {
drm_object_attach_property(
&aconnector->base.base,
dm->ddev-
mode_config.hdr_output_metadata_property, 0);
drm_connector_attach_hdr_output_metadata_property(&aconnector->base);
if (!aconnector->mst_port)
drm_connector_attach_vrr_capable_property(&aconnector->base);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index dda4fa9a1a08..f24bbb840dbf 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2492,8 +2492,7 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) drm_connector_attach_max_bpc_property(connector, 8, 16);
if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
drm_object_attach_property(&connector->base,
connector->dev-
mode_config.hdr_output_metadata_property, 0);
drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 98b6ec45ef96..e25248e23e18 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2149,6 +2149,27 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector, } EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
+/**
- drm_connector_attach_hdr_output_metadata_property - attach
"HDR_OUTPUT_METADA" property + * @connector: connector to attach the property on.
- This is used to allow the userspace to send HDR Metadata to the
- driver.
- Returns:
- Zero on success, negative errno on failure.
- */
+int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector) +{
- struct drm_device *dev = connector->dev;
- struct drm_property *prop = dev-
mode_config.hdr_output_metadata_property;
- drm_object_attach_property(&connector->base, prop, 0);
- return 0;
+} +EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
/**
- drm_connector_set_vrr_capable_property - sets the variable refresh rate
- capable property for a connector
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index c5959590562b..52c051efb7b7 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2958,8 +2958,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c drm_connector_attach_content_type_property(connector);
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
drm_object_attach_property(&connector->base,
connector->dev-
mode_config.hdr_output_metadata_property, 0);
drm_connector_attach_hdr_output_metadata_property(connector);
if (!HAS_GMCH(dev_priv)) drm_connector_attach_max_bpc_property(connector, 8,
12);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 1922b278ffad..32172dab8427 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1671,6 +1671,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); +int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector); 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);
For bridge part: Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
Best regards, Jernej
dri-devel@lists.freedesktop.org