From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 12/15] drm/edid: use struct drm_edid for override/firmware EDID
Date: Wed, 19 Oct 2022 23:01:22 +0300 [thread overview]
Message-ID: <Y1BXkgjUZbdjgvuF@intel.com> (raw)
In-Reply-To: <de3f22db32feed871901408c52d0dc3a513bf686.1665496046.git.jani.nikula@intel.com>
On Tue, Oct 11, 2022 at 04:49:46PM +0300, Jani Nikula wrote:
> 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.
Was pondering about that reading the earlier patch. Figured I'd keep
on reading, and voila here it is.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/drm_edid.c | 32 ++++++------
> drivers/gpu/drm/drm_edid_load.c | 86 +++++++--------------------------
> include/drm/drm_edid.h | 4 +-
> 3 files changed, 36 insertions(+), 86 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 2c66a901474d..935bdf4e6269 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2202,21 +2202,16 @@ 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;
>
> if (connector->edid_override)
> - override = drm_edid_duplicate(connector->edid_override->edid);
> + override = drm_edid_dup(connector->edid_override);
>
> 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;
> }
>
> @@ -2277,14 +2272,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);
> @@ -2335,12 +2330,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)
> diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
> index bc6b96abd1b3..248f0685c33e 100644
> --- a/drivers/gpu/drm/drm_edid_load.c
> +++ b/drivers/gpu/drm/drm_edid_load.c
> @@ -159,22 +159,12 @@ static const u8 generic_edid[GENERIC_EDIDS][128] = {
> },
> };
>
> -static int edid_size(const u8 *edid, int data_size)
> -{
> - if (data_size < EDID_LENGTH)
> - return 0;
> -
> - return (edid[0x7e] + 1) * EDID_LENGTH;
> -}
> -
> -static void *edid_load(struct drm_connector *connector, const char *name)
> +static const struct drm_edid *edid_load(struct drm_connector *connector, const char *name)
> {
> const struct firmware *fw = NULL;
> const u8 *fwdata;
> - u8 *edid;
> + const struct drm_edid *drm_edid;
> int fwsize, builtin;
> - int i, valid_extensions = 0;
> - bool print_bad_edid = !connector->bad_edid_counter || drm_debug_enabled(DRM_UT_KMS);
>
> builtin = match_string(generic_edid_name, GENERIC_EDIDS, name);
> if (builtin >= 0) {
> @@ -203,69 +193,26 @@ static void *edid_load(struct drm_connector *connector, const char *name)
> fwsize = fw->size;
> }
>
> - if (edid_size(fwdata, fwsize) != fwsize) {
> - DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
> - "(expected %d, got %d\n", name,
> - edid_size(fwdata, fwsize), (int)fwsize);
> - edid = ERR_PTR(-EINVAL);
> - goto out;
> - }
> -
> - edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
> - if (edid == NULL) {
> - edid = ERR_PTR(-ENOMEM);
> - goto out;
> - }
> -
> - if (!drm_edid_block_valid(edid, 0, print_bad_edid,
> - &connector->edid_corrupt)) {
> - connector->bad_edid_counter++;
> - DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
> - name);
> - kfree(edid);
> - edid = ERR_PTR(-EINVAL);
> - goto out;
> - }
> -
> - for (i = 1; i <= edid[0x7e]; i++) {
> - if (i != valid_extensions + 1)
> - memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
> - edid + i * EDID_LENGTH, EDID_LENGTH);
> - if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
> - print_bad_edid,
> - NULL))
> - valid_extensions++;
> - }
> -
> - if (valid_extensions != edid[0x7e]) {
> - u8 *new_edid;
> + drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] Loaded %s firmware EDID \"%s\"\n",
> + connector->base.id, connector->name,
> + builtin >= 0 ? "built-in" : "external", name);
>
> - edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> - DRM_INFO("Found %d valid extensions instead of %d in EDID data "
> - "\"%s\" for connector \"%s\"\n", valid_extensions,
> - edid[0x7e], name, connector->name);
> - edid[0x7e] = valid_extensions;
> -
> - new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
> - GFP_KERNEL);
> - if (new_edid)
> - edid = new_edid;
> + drm_edid = drm_edid_alloc(fwdata, fwsize);
> + if (!drm_edid_valid(drm_edid)) {
> + drm_err(connector->dev, "Invalid firmware EDID \"%s\"\n", name);
> + drm_edid_free(drm_edid);
> + drm_edid = ERR_PTR(-EINVAL);
> }
Lovely diffstat ratio there.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> - DRM_INFO("Got %s EDID base block and %d extension%s from "
> - "\"%s\" for connector \"%s\"\n", (builtin >= 0) ? "built-in" :
> - "external", valid_extensions, valid_extensions == 1 ? "" : "s",
> - name, connector->name);
> -
> -out:
> release_firmware(fw);
> - return edid;
> +
> + return drm_edid;
> }
>
> -struct edid *drm_edid_load_firmware(struct drm_connector *connector)
> +const struct drm_edid *drm_edid_load_firmware(struct drm_connector *connector)
> {
> char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
> - struct edid *edid;
> + const struct drm_edid *drm_edid;
>
> if (edid_firmware[0] == '\0')
> return ERR_PTR(-ENOENT);
> @@ -308,8 +255,9 @@ struct edid *drm_edid_load_firmware(struct drm_connector *connector)
> if (*last == '\n')
> *last = '\0';
>
> - edid = edid_load(connector, edidname);
> + drm_edid = edid_load(connector, edidname);
> +
> kfree(fwstr);
>
> - return edid;
> + return drm_edid;
> }
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index dc7467d25cd8..8138613f4e4e 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -388,11 +388,11 @@ int drm_av_sync_delay(struct drm_connector *connector,
> const struct drm_display_mode *mode);
>
> #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
> -struct edid *drm_edid_load_firmware(struct drm_connector *connector);
> +const struct drm_edid *drm_edid_load_firmware(struct drm_connector *connector);
> int __drm_set_edid_firmware_path(const char *path);
> int __drm_get_edid_firmware_path(char *buf, size_t bufsize);
> #else
> -static inline struct edid *
> +static inline const struct drm_edid *
> drm_edid_load_firmware(struct drm_connector *connector)
> {
> return ERR_PTR(-ENOENT);
> --
> 2.34.1
--
Ville Syrjälä
Intel
next prev parent reply other threads:[~2022-10-19 20:01 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-11 13:49 [Intel-gfx] [PATCH 00/15] drm/edid: EDID override refactoring and fixes Jani Nikula
2022-10-11 13:49 ` [Intel-gfx] [PATCH 01/15] drm/i915/hdmi: do dual mode detect only if connected Jani Nikula
2022-10-13 18:41 ` Ville Syrjälä
2022-10-13 19:24 ` Ville Syrjälä
2022-10-14 8:14 ` Jani Nikula
2022-10-19 18:56 ` Ville Syrjälä
2022-10-19 19:23 ` Ville Syrjälä
2022-10-20 8:57 ` Jani Nikula
2022-10-20 9:25 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 02/15] drm/i915/hdmi: stop using connector->override_edid Jani Nikula
2022-10-19 19:36 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 03/15] drm/amd/display: " Jani Nikula
2022-10-11 14:07 ` Harry Wentland
2022-10-11 14:11 ` Jani Nikula
2022-10-11 14:19 ` Alex Deucher
2022-10-11 13:49 ` [Intel-gfx] [PATCH 04/15] drm/edid: debug log EDID override set/reset Jani Nikula
2022-10-19 19:36 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 05/15] drm/edid: abstract debugfs override EDID show better Jani Nikula
2022-10-19 19:37 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 06/15] drm/edid: rename drm_add_override_edid_modes() to drm_edid_override_connector_update() Jani Nikula
2022-10-19 20:04 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 07/15] drm/edid: split drm_edid block count helper Jani Nikula
2022-10-19 19:44 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 08/15] drm/edid: add function for checking drm_edid validity Jani Nikula
2022-10-19 19:46 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 09/15] drm/edid: detach debugfs EDID override from EDID property update Jani Nikula
2022-10-19 20:07 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 10/15] drm/edid/firmware: drop redundant connector_name variable/parameter Jani Nikula
2022-10-19 19:52 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 11/15] drm/edid/firmware: rename drm_load_edid_firmware() to drm_edid_load_firmware() Jani Nikula
2022-10-19 20:07 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 12/15] drm/edid: use struct drm_edid for override/firmware EDID Jani Nikula
2022-10-19 20:01 ` Ville Syrjälä [this message]
2022-10-11 13:49 ` [Intel-gfx] [PATCH 13/15] drm/edid: move edid load declarations to internal header Jani Nikula
2022-10-19 20:08 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 14/15] drm/edid/firmware: convert to drm device specific logging Jani Nikula
2022-10-19 20:10 ` Ville Syrjälä
2022-10-11 13:49 ` [Intel-gfx] [PATCH 15/15] drm/edid: convert to " Jani Nikula
2022-10-19 20:12 ` Ville Syrjälä
2022-10-11 15:30 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/edid: EDID override refactoring and fixes Patchwork
2022-10-11 15:30 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-10-11 15:52 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-10-11 18:49 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y1BXkgjUZbdjgvuF@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox