summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2022-10-24 15:33:40 +0300
committerJani Nikula <jani.nikula@intel.com>2022-10-26 09:53:51 +0300
commit794aca0ec214bb23ff4fcb28c053ac6fdfa3ce07 (patch)
tree16512b42faf3bc1b055ceb9a7ab1ab72a52f955e /drivers/gpu/drm/drm_edid.c
parenta05992d5ea779da174246186d88bfeaf2d2754f2 (diff)
drm/edid: use struct drm_edid for override/firmware EDID
There's a lot going on here, but the main thing is switching the firmware EDID loader to use struct drm_edid. Unfortunately, it's difficult to reasonably split to smaller pieces. Convert the EDID loader to struct drm_edid. There's a functional change in validation; it no longer tries to fix errors or filter invalid blocks. It's stricter in this sense. Hopefully this will not be an issue. As a by-product, this change also allows HF-EEODB extended EDIDs to be passed via override/firmware EDID. 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/e64267c28eca483e83c802bc06ddd149bdcdfc66.1666614699.git.jani.nikula@intel.com
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5e5e1463e45f..9078d1fb6d00 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2202,25 +2202,20 @@ static void connector_bad_edid(struct drm_connector *connector,
}
/* Get override or firmware EDID */
-static struct edid *drm_get_override_edid(struct drm_connector *connector,
- size_t *alloc_size)
+static const struct drm_edid *drm_edid_override_get(struct drm_connector *connector)
{
- struct edid *override = NULL;
+ const struct drm_edid *override = NULL;
mutex_lock(&connector->edid_override_mutex);
if (connector->edid_override)
- override = drm_edid_duplicate(connector->edid_override->edid);
+ override = drm_edid_dup(connector->edid_override);
mutex_unlock(&connector->edid_override_mutex);
if (!override)
override = drm_edid_load_firmware(connector);
- /* FIXME: Get alloc size from deeper down the stack */
- if (!IS_ERR_OR_NULL(override) && alloc_size)
- *alloc_size = edid_size(override);
-
return IS_ERR(override) ? NULL : override;
}
@@ -2296,14 +2291,14 @@ int drm_edid_override_reset(struct drm_connector *connector)
*/
int drm_edid_override_connector_update(struct drm_connector *connector)
{
- struct edid *override;
+ const struct drm_edid *override;
int num_modes = 0;
- override = drm_get_override_edid(connector, NULL);
+ override = drm_edid_override_get(connector);
if (override) {
- drm_connector_update_edid_property(connector, override);
- num_modes = drm_add_edid_modes(connector, override);
- kfree(override);
+ num_modes = drm_edid_connector_update(connector, override);
+
+ drm_edid_free(override);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] adding %d modes via fallback override/firmware EDID\n",
connector->base.id, connector->name, num_modes);
@@ -2354,12 +2349,19 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector,
{
enum edid_block_status status;
int i, num_blocks, invalid_blocks = 0;
+ const struct drm_edid *override;
struct edid *edid, *new;
size_t alloc_size = EDID_LENGTH;
- edid = drm_get_override_edid(connector, &alloc_size);
- if (edid)
+ override = drm_edid_override_get(connector);
+ if (override) {
+ alloc_size = override->size;
+ edid = kmemdup(override->edid, alloc_size, GFP_KERNEL);
+ drm_edid_free(override);
+ if (!edid)
+ return NULL;
goto ok;
+ }
edid = kmalloc(alloc_size, GFP_KERNEL);
if (!edid)