From: Jani Nikula <jani.nikula@linux.intel.com>
To: Hsin-Yi Wang <hsinyi@chromium.org>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Douglas Anderson <dianders@chromium.org>
Cc: Neil Armstrong <neil.armstrong@linaro.org>,
Jessica Zhang <quic_jesszhan@quicinc.com>,
Sam Ravnborg <sam@ravnborg.org>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 1/5] drm_edid: Add a function to get EDID base block
Date: Wed, 06 Mar 2024 10:43:09 +0200 [thread overview]
Message-ID: <87v85zzr6q.fsf@intel.com> (raw)
In-Reply-To: <20240306004347.974304-2-hsinyi@chromium.org>
On Tue, 05 Mar 2024, Hsin-Yi Wang <hsinyi@chromium.org> wrote:
> It's found that some panels have variants that they share the same panel id
> although their EDID and names are different. Besides panel id, now we need
> more information from the EDID base block to distinguish these panel
> variants.
>
> Add drm_edid_read_base_block() to return the EDID base block, which is
> wrapped in struct drm_edid.
>
> Caller can further use it to get panel id or check if the block contains
> certain strings, such as panel name.
>
> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> ---
> v3->v4: change drm_edid_read_base_block return type to drm_edid.
> ---
> drivers/gpu/drm/drm_edid.c | 63 +++++++++++++++++++------------
> drivers/gpu/drm/panel/panel-edp.c | 8 +++-
> include/drm/drm_edid.h | 3 +-
> 3 files changed, 46 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 923c4423151c..f9e09f327f81 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2770,58 +2770,71 @@ static u32 edid_extract_panel_id(const struct edid *edid)
> }
>
> /**
> - * drm_edid_get_panel_id - Get a panel's ID through DDC
> - * @adapter: I2C adapter to use for DDC
> + * drm_edid_get_panel_id - Get a panel's ID from EDID
> + * @drm_edid: EDID that contains panel ID.
> *
> - * This function reads the first block of the EDID of a panel and (assuming
> + * This function uses the first block of the EDID of a panel and (assuming
> * that the EDID is valid) extracts the ID out of it. The ID is a 32-bit value
> * (16 bits of manufacturer ID and 16 bits of per-manufacturer ID) that's
> * supposed to be different for each different modem of panel.
> *
> + * Return: A 32-bit ID that should be different for each make/model of panel.
> + * See the functions drm_edid_encode_panel_id() and
> + * drm_edid_decode_panel_id() for some details on the structure of this
> + * ID.
> + */
> +u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid)
> +{
> + return edid_extract_panel_id(drm_edid->edid);
> +}
> +EXPORT_SYMBOL(drm_edid_get_panel_id);
> +
> +/**
> + * drm_edid_read_base_block - Get a panel's EDID base block
> + * @adapter: I2C adapter to use for DDC
> + *
> + * This function returns the drm_edid containing the first block of the EDID of
> + * a panel.
> + *
> * This function is intended to be used during early probing on devices where
> * more than one panel might be present. Because of its intended use it must
> - * assume that the EDID of the panel is correct, at least as far as the ID
> - * is concerned (in other words, we don't process any overrides here).
> + * assume that the EDID of the panel is correct, at least as far as the base
> + * block is concerned (in other words, we don't process any overrides here).
> + *
> + * Caller should call drm_edid_free() after use.
> *
> * NOTE: it's expected that this function and drm_do_get_edid() will both
> * be read the EDID, but there is no caching between them. Since we're only
> * reading the first block, hopefully this extra overhead won't be too big.
> *
> - * Return: A 32-bit ID that should be different for each make/model of panel.
> - * See the functions drm_edid_encode_panel_id() and
> - * drm_edid_decode_panel_id() for some details on the structure of this
> - * ID.
> + * WARNING: Only use this function when the connector is unknown. For example,
> + * during the early probe of panel. The EDID read from the function is temporary
> + * and should be replaced by the full EDID returned from other drm_edid_read.
> + *
> + * Return: Pointer to allocated EDID base block, or NULL on any failure.
> */
> -
> -u32 drm_edid_get_panel_id(struct i2c_adapter *adapter)
> +const struct drm_edid *drm_edid_read_base_block(struct i2c_adapter *adapter)
> {
> enum edid_block_status status;
> void *base_block;
> - u32 panel_id = 0;
> -
> - /*
> - * There are no manufacturer IDs of 0, so if there is a problem reading
> - * the EDID then we'll just return 0.
> - */
>
> base_block = kzalloc(EDID_LENGTH, GFP_KERNEL);
> if (!base_block)
> - return 0;
> + return NULL;
>
> status = edid_block_read(base_block, 0, drm_do_probe_ddc_edid, adapter);
>
> edid_block_status_print(status, base_block, 0);
>
> - if (edid_block_status_valid(status, edid_block_tag(base_block)))
> - panel_id = edid_extract_panel_id(base_block);
> - else
> + if (!edid_block_status_valid(status, edid_block_tag(base_block))) {
> edid_block_dump(KERN_NOTICE, base_block, 0);
> + kfree(base_block);
> + return NULL;
> + }
>
> - kfree(base_block);
> -
> - return panel_id;
> + return drm_edid_alloc(base_block, EDID_LENGTH);
This leaks base_block. Please use _drm_edid_alloc() (with underscore) to
only allocate the container without kmemduping the data.
Otherwise LGTM.
BR,
Jani.
> }
> -EXPORT_SYMBOL(drm_edid_get_panel_id);
> +EXPORT_SYMBOL(drm_edid_read_base_block);
>
> /**
> * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
> diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
> index 745f3e48f02a..d094cfc43da8 100644
> --- a/drivers/gpu/drm/panel/panel-edp.c
> +++ b/drivers/gpu/drm/panel/panel-edp.c
> @@ -766,6 +766,7 @@ static const struct edp_panel_entry *find_edp_panel(u32 panel_id);
> static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
> {
> struct panel_desc *desc;
> + const struct drm_edid *base_block;
> u32 panel_id;
> char vend[4];
> u16 product_id;
> @@ -795,8 +796,11 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
> goto exit;
> }
>
> - panel_id = drm_edid_get_panel_id(panel->ddc);
> - if (!panel_id) {
> + base_block = drm_edid_read_base_block(panel->ddc);
> + if (base_block) {
> + panel_id = drm_edid_get_panel_id(base_block);
> + drm_edid_free(base_block);
> + } else {
> dev_err(dev, "Couldn't identify panel via EDID\n");
> ret = -EIO;
> goto exit;
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 7923bc00dc7a..9686a7cee6a6 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -410,7 +410,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> void *data);
> struct edid *drm_get_edid(struct drm_connector *connector,
> struct i2c_adapter *adapter);
> -u32 drm_edid_get_panel_id(struct i2c_adapter *adapter);
> +const struct drm_edid *drm_edid_read_base_block(struct i2c_adapter *adapter);
> +u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid);
> struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
> struct i2c_adapter *adapter);
> struct edid *drm_edid_duplicate(const struct edid *edid);
--
Jani Nikula, Intel
next prev parent reply other threads:[~2024-03-06 8:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-06 0:34 [PATCH v4 0/5] Match panel with identity Hsin-Yi Wang
2024-03-06 0:34 ` [PATCH v4 1/5] drm_edid: Add a function to get EDID base block Hsin-Yi Wang
2024-03-06 8:43 ` Jani Nikula [this message]
2024-03-06 0:34 ` [PATCH v4 2/5] drm/edid: Add a function to match EDID with identity Hsin-Yi Wang
2024-03-06 9:16 ` Jani Nikula
2024-03-06 19:08 ` Hsin-Yi Wang
2024-03-06 0:34 ` [PATCH v4 3/5] drm/edid: Match edid quirks " Hsin-Yi Wang
2024-03-06 9:18 ` Jani Nikula
2024-03-06 0:34 ` [PATCH v4 4/5] drm/panel-edp: Match edp_panels with panel identity Hsin-Yi Wang
2024-03-06 9:23 ` Jani Nikula
2024-03-06 18:48 ` Hsin-Yi Wang
2024-03-06 0:34 ` [PATCH v4 5/5] drm/panel-edp: Fix AUO 0x405c panel naming and add a variant Hsin-Yi Wang
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=87v85zzr6q.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=airlied@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dianders@chromium.org \
--cc=dmitry.baryshkov@linaro.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=hsinyi@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=quic_jesszhan@quicinc.com \
--cc=sam@ravnborg.org \
--cc=tzimmermann@suse.de \
/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;
as well as URLs for NNTP newsgroup(s).