Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/edid: add drm_edid_connector_update()

Add a new function drm_edid_connector_update() to replace the
combination of calls drm_connector_update_edid_property() and
drm_add_edid_modes(). Usually they are called in the drivers in this
order, however the former needs information from the latter.

Since the new drm_edid_read*() functions no longer call the connector
updates directly, and the read and update are separated, we'll need this
new function for the connector update.

This is all in drm_edid.c simply to keep struct drm_edid opaque.

v2:
- Share code with drm_connector_update_edid_property() (Ville)
- Add comment about override EDID handling

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/75aa3dbc8c9aa26ebbcdeacd98a466ef8d8827f4.1656494768.git.jani.nikula@intel.com

+81 -24
+79 -24
drivers/gpu/drm/drm_edid.c
··· 6160 6160 return num_modes; 6161 6161 } 6162 6162 6163 - static int drm_edid_connector_update(struct drm_connector *connector, 6164 - const struct drm_edid *drm_edid) 6163 + static int _drm_edid_connector_update(struct drm_connector *connector, 6164 + const struct drm_edid *drm_edid) 6165 6165 { 6166 6166 int num_modes = 0; 6167 6167 u32 quirks; ··· 6227 6227 static void _drm_update_tile_info(struct drm_connector *connector, 6228 6228 const struct drm_edid *drm_edid); 6229 6229 6230 - static int _drm_connector_update_edid_property(struct drm_connector *connector, 6230 + static int _drm_edid_connector_property_update(struct drm_connector *connector, 6231 6231 const struct drm_edid *drm_edid) 6232 6232 { 6233 6233 struct drm_device *dev = connector->dev; 6234 6234 int ret; 6235 - 6236 - /* ignore requests to set edid when overridden */ 6237 - if (connector->override_edid) 6238 - return 0; 6239 - 6240 - /* 6241 - * Set the display info, using edid if available, otherwise resetting 6242 - * the values to defaults. This duplicates the work done in 6243 - * drm_add_edid_modes, but that function is not consistently called 6244 - * before this one in all drivers and the computation is cheap enough 6245 - * that it seems better to duplicate it rather than attempt to ensure 6246 - * some arbitrary ordering of calls. 6247 - */ 6248 - if (drm_edid) 6249 - update_display_info(connector, drm_edid); 6250 - else 6251 - drm_reset_display_info(connector); 6252 - 6253 - _drm_update_tile_info(connector, drm_edid); 6254 6235 6255 6236 if (connector->edid_blob_ptr) { 6256 6237 const struct edid *old_edid = connector->edid_blob_ptr->data; ··· 6279 6298 } 6280 6299 6281 6300 /** 6301 + * drm_edid_connector_update - Update connector information from EDID 6302 + * @connector: Connector 6303 + * @drm_edid: EDID 6304 + * 6305 + * Update the connector mode list, display info, ELD, HDR metadata, relevant 6306 + * properties, etc. from the passed in EDID. 6307 + * 6308 + * If EDID is NULL, reset the information. 6309 + * 6310 + * Return: The number of modes added or 0 if we couldn't find any. 6311 + */ 6312 + int drm_edid_connector_update(struct drm_connector *connector, 6313 + const struct drm_edid *drm_edid) 6314 + { 6315 + int count; 6316 + 6317 + /* 6318 + * FIXME: Reconcile the differences in override_edid handling between 6319 + * this and drm_connector_update_edid_property(). 6320 + * 6321 + * If override_edid is set, and the EDID passed in here originates from 6322 + * drm_edid_read() and friends, it will be the override EDID, and there 6323 + * are no issues. drm_connector_update_edid_property() ignoring requests 6324 + * to set the EDID dates back to a time when override EDID was not 6325 + * handled at the low level EDID read. 6326 + * 6327 + * The only way the EDID passed in here can be different from the 6328 + * override EDID is when a driver passes in an EDID that does *not* 6329 + * originate from drm_edid_read() and friends, or passes in a stale 6330 + * cached version. This, in turn, is a question of when an override EDID 6331 + * set via debugfs should take effect. 6332 + */ 6333 + 6334 + count = _drm_edid_connector_update(connector, drm_edid); 6335 + 6336 + _drm_update_tile_info(connector, drm_edid); 6337 + 6338 + /* Note: Ignore errors for now. */ 6339 + _drm_edid_connector_property_update(connector, drm_edid); 6340 + 6341 + return count; 6342 + } 6343 + EXPORT_SYMBOL(drm_edid_connector_update); 6344 + 6345 + static int _drm_connector_update_edid_property(struct drm_connector *connector, 6346 + const struct drm_edid *drm_edid) 6347 + { 6348 + /* ignore requests to set edid when overridden */ 6349 + if (connector->override_edid) 6350 + return 0; 6351 + 6352 + /* 6353 + * Set the display info, using edid if available, otherwise resetting 6354 + * the values to defaults. This duplicates the work done in 6355 + * drm_add_edid_modes, but that function is not consistently called 6356 + * before this one in all drivers and the computation is cheap enough 6357 + * that it seems better to duplicate it rather than attempt to ensure 6358 + * some arbitrary ordering of calls. 6359 + */ 6360 + if (drm_edid) 6361 + update_display_info(connector, drm_edid); 6362 + else 6363 + drm_reset_display_info(connector); 6364 + 6365 + _drm_update_tile_info(connector, drm_edid); 6366 + 6367 + return _drm_edid_connector_property_update(connector, drm_edid); 6368 + } 6369 + 6370 + /** 6282 6371 * drm_connector_update_edid_property - update the edid property of a connector 6283 6372 * @connector: drm connector 6284 6373 * @edid: new value of the edid property ··· 6358 6307 * Since we also parse tile information from EDID's displayID block, we also 6359 6308 * set the connector's tile property here. See drm_connector_set_tile_property() 6360 6309 * for more details. 6310 + * 6311 + * This function is deprecated. Use drm_edid_connector_update() instead. 6361 6312 * 6362 6313 * Returns: 6363 6314 * Zero on success, negative errno on failure. ··· 6383 6330 * &drm_display_info structure and ELD in @connector with any information which 6384 6331 * can be derived from the edid. 6385 6332 * 6333 + * This function is deprecated. Use drm_edid_connector_update() instead. 6334 + * 6386 6335 * Return: The number of modes added or 0 if we couldn't find any. 6387 6336 */ 6388 6337 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) ··· 6397 6342 edid = NULL; 6398 6343 } 6399 6344 6400 - return drm_edid_connector_update(connector, 6401 - drm_edid_legacy_init(&drm_edid, edid)); 6345 + return _drm_edid_connector_update(connector, 6346 + drm_edid_legacy_init(&drm_edid, edid)); 6402 6347 } 6403 6348 EXPORT_SYMBOL(drm_add_edid_modes); 6404 6349
+2
include/drm/drm_edid.h
··· 603 603 const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector, 604 604 int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len), 605 605 void *context); 606 + int drm_edid_connector_update(struct drm_connector *connector, 607 + const struct drm_edid *edid); 606 608 const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid, 607 609 int ext_id, int *ext_index); 608 610