All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@linux.intel.com>
To: Douglas Anderson <dianders@chromium.org>,
	Thierry Reding <thierry.reding@gmail.com>,
	Rob Herring <robh+dt@kernel.org>, Sam Ravnborg <sam@ravnborg.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	linux-arm-msm@vger.kernel.org,
	Bjorn Andersson <bjorn.andersson@linaro.org>,
	Linus W <linus.walleij@linaro.org>,
	Daniel Vetter <daniel@ffwll.ch>,
	devicetree@vger.kernel.org, Steev Klimaszewski <steev@kali.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Maxime Ripard <mripard@kernel.org>,
	David Airlie <airlied@linux.ie>,
	dri-devel@lists.freedesktop.org,
	Douglas Anderson <dianders@chromium.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 03/16] drm/edid: Allow the querying/working with the panel ID from the EDID
Date: Mon, 06 Sep 2021 13:05:34 +0300	[thread overview]
Message-ID: <87h7ey81e9.fsf@intel.com> (raw)
In-Reply-To: <20210901131531.v3.3.I4a672175ba1894294d91d3dbd51da11a8239cf4a@changeid>

On Wed, 01 Sep 2021, Douglas Anderson <dianders@chromium.org> wrote:
> EDIDs have 32-bits worth of data which is intended to be used to
> uniquely identify the make/model of a panel. This has historically
> been used only internally in the EDID processing code to identify
> quirks with panels.
>
> We'd like to use this panel ID in panel-simple to identify which panel
> is hooked up and from that information figure out power sequence
> timings. Let's expose this information from the EDID code and also
> allow it to be accessed early, before a connector has been created.
>
> To make matching in the panel-simple code easier, we'll return the
> panel ID as a 32-bit value. We'll provide some functions for
> converting this value back and forth to something more human readable.
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
>
> Changes in v3:
> - Decode hex product ID w/ same endianness as everyone else.
>
>  drivers/gpu/drm/drm_edid.c | 59 ++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_edid.h     | 47 ++++++++++++++++++++++++++++++
>  2 files changed, 106 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index a22c38482a90..ac128bc3478a 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -2086,6 +2086,65 @@ struct edid *drm_get_edid(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +/**
> + * drm_get_panel_id - Get a panel's ID through DDC
> + * @adapter: I2C adapter to use for DDC
> + *
> + * This function reads 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.
> + *
> + * 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).
> + *
> + * 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 encode_edid_id() and decode_edid_id() for some
> + *         details on the structure of this ID.
> + */
> +u32 drm_get_panel_id(struct i2c_adapter *adapter)

Please call it drm_edid_get_panel_id() because that's what it is, and
this is in drm_edid.[ch].

> +{
> +	struct edid *edid;
> +	u32 val;
> +
> +	edid = drm_do_get_edid_blk0(drm_do_probe_ddc_edid, adapter, NULL, NULL);
> +
> +	/*
> +	 * There are no manufacturer IDs of 0, so if there is a problem reading
> +	 * the EDID then we'll just return 0.
> +	 */
> +	if (IS_ERR_OR_NULL(edid))
> +		return 0;
> +
> +	/*
> +	 * In theory we could try to de-obfuscate this like edid_get_quirks()
> +	 * does, but it's easier to just deal with a 32-bit number.

Hmm, but is it, really? AFAICT this is just an internal representation
for a table, where it could just as well be stored in a struct that
could be just as compact now, but extensible later. You populate the
table via an encoding macro, then decode the id using a function - while
it could be in a format that's directly usable without the decode. If
suitably chosen, the struct could perhaps be reused between the quirks
code and your code.

> +	 *
> +	 * NOTE that we deal with endianness differently for the top half
> +	 * of this ID than for the bottom half. The bottom half (the product
> +	 * id) gets decoded as little endian by the EDID_PRODUCT_ID because
> +	 * that's how everyone seems to interpret it. The top half (the mfg_id)
> +	 * gets stored as big endian because that makes encode_edid_id() and
> +	 * decode_edid_id() easier to write (it's easier to extract the ASCII).
> +	 * It doesn't really matter, though, as long as the number here is
> +	 * unique.
> +	 */
> +	val = (u32)edid->mfg_id[0] << 24   |
> +	      (u32)edid->mfg_id[1] << 16   |
> +	      (u32)EDID_PRODUCT_ID(edid);
> +
> +	kfree(edid);
> +
> +	return val;
> +}
> +EXPORT_SYMBOL(drm_get_panel_id);
> +
>  /**
>   * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
>   * @connector: connector we're probing
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index deccfd39e6db..73da40d0b5d1 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -508,6 +508,52 @@ static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
>  	return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
>  }
>  
> +/**
> + * encode_edid_id - Encode an ID for matching against drm_get_panel_id()
> + * @vend_chr_0: First character of the vendor string.
> + * @vend_chr_2: Second character of the vendor string.
> + * @vend_chr_3: Third character of the vendor string.
> + * @product_id: The 16-bit product ID.
> + *
> + * This is a macro so that it can be calculated at compile time and used
> + * as an initializer.
> + *
> + * For instance:
> + *   encode_edid_id('B', 'O', 'E', 0x2d08) => 0x09e52d08
> + *
> + * Return: a 32-bit ID per panel.
> + */
> +#define encode_edid_id(vend_chr_0, vend_chr_1, vend_chr_2, product_id) \
> +	((((u32)(vend_chr_0) - '@') & 0x1f) << 26 | \
> +	 (((u32)(vend_chr_1) - '@') & 0x1f) << 21 | \
> +	 (((u32)(vend_chr_2) - '@') & 0x1f) << 16 | \
> +	 ((product_id) & 0xffff))
> +
> +/**
> + * decode_edid_id - Decode a panel ID from encode_edid_id()
> + * @panel_id: The panel ID to decode.
> + * @vend: A 4-byte buffer to store the 3-letter vendor string plus a '\0'
> + *	  termination
> + * @product_id: The product ID will be returned here.
> + *
> + * For instance, after:
> + *   decode_edid_id(0x09e52d08, vend, &product_id)
> + * These will be true:
> + *   vend[0] = 'B'
> + *   vend[1] = 'O'
> + *   vend[2] = 'E'
> + *   vend[3] = '\0'
> + *   product_id = 0x2d08
> + */
> +static inline void decode_edid_id(u32 panel_id, char vend[4], u16 *product_id)
> +{
> +	*product_id = (u16)(panel_id & 0xffff);
> +	vend[0] = '@' + ((panel_id >> 26) & 0x1f);
> +	vend[1] = '@' + ((panel_id >> 21) & 0x1f);
> +	vend[2] = '@' + ((panel_id >> 16) & 0x1f);
> +	vend[3] = '\0';
> +}

I think the names here could use a drm_edid_ prefix too.

Maybe drm_edid_encode_panel_id and drm_edid_decode_panel_id, aligning
nicely with drm_edid_get_panel_id.

BR,
Jani.

> +
>  bool drm_probe_ddc(struct i2c_adapter *adapter);
>  struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
> @@ -515,6 +561,7 @@ 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_get_panel_id(struct i2c_adapter *adapter);
>  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 Open Source Graphics Center

  parent reply	other threads:[~2021-09-06 10:05 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20210902221015eucas1p26fae8f6ba4c70087dc7b007a271dce4b@eucas1p2.samsung.com>
2021-09-01 20:19 ` [PATCH v3 00/16] eDP: Support probing eDP panels dynamically instead of hardcoding Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 01/16] dt-bindings: drm/panel-simple-edp: Introduce generic eDP panels Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 02/16] drm/edid: Break out reading block 0 of the EDID Douglas Anderson
2021-09-06  9:50     ` Jani Nikula
2021-09-01 20:19   ` [PATCH v3 03/16] drm/edid: Allow the querying/working with the panel ID from " Douglas Anderson
2021-09-05 18:17     ` Sam Ravnborg
2021-09-06 10:05     ` Jani Nikula [this message]
2021-09-09  0:24       ` Doug Anderson
2021-09-14 17:59         ` Jani Nikula
2021-09-01 20:19   ` [PATCH v3 04/16] drm/panel-simple: Reorder logicpd_type_28 / mitsubishi_aa070mc01 Douglas Anderson
2021-09-09 20:48     ` Doug Anderson
2021-09-01 20:19   ` [PATCH v3 05/16] drm/panel-simple-edp: Split eDP panels out of panel-simple Douglas Anderson
2021-09-05 18:42     ` Sam Ravnborg
2021-09-09 19:33       ` Doug Anderson
2021-09-01 20:19   ` [PATCH v3 06/16] ARM: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP Douglas Anderson
2021-09-01 21:12     ` Olof Johansson
2021-09-01 23:10       ` Doug Anderson
2021-09-03  7:18         ` Andrzej Hajda
2021-09-03  7:18           ` Andrzej Hajda
2021-09-03 20:38         ` Stephen Boyd
2021-09-08 22:36           ` Doug Anderson
2021-09-08 23:08             ` Olof Johansson
2021-09-01 20:19   ` [PATCH v3 07/16] arm64: defconfig: " Douglas Anderson
2021-09-01 20:19     ` Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 08/16] MIPS: configs: " Douglas Anderson
2021-09-01 20:39     ` Paul Cercueil
2021-09-01 20:19   ` [PATCH v3 09/16] drm/panel-simple-edp: Move some wayward panels to the eDP driver Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 10/16] drm/panel-simple: Non-eDP panels don't need "HPD" handling Douglas Anderson
2021-09-05 18:46     ` Sam Ravnborg
2021-09-08 21:10       ` Doug Anderson
2021-09-09 20:47         ` Sam Ravnborg
2021-09-01 20:19   ` [PATCH v3 11/16] drm/panel-simple-edp: Split the delay structure out Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 12/16] drm/panel-simple-edp: Better describe eDP panel delays Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 13/16] drm/panel-simple-edp: hpd_reliable shouldn't be subtraced from hpd_absent Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 14/16] drm/panel-simple-edp: Fix "prepare_to_enable" if panel doesn't handle HPD Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 15/16] drm/panel-simple-edp: Don't re-read the EDID every time we power off the panel Douglas Anderson
2021-09-01 20:19   ` [PATCH v3 16/16] drm/panel-simple-edp: Implement generic "edp-panel"s probed by EDID Douglas Anderson
2021-09-02 22:10   ` [PATCH v3 00/16] eDP: Support probing eDP panels dynamically instead of hardcoding Andrzej Hajda
2021-09-02 22:10     ` Andrzej Hajda
2021-09-02 22:33     ` Doug Anderson
2021-09-02 22:33       ` Doug Anderson
2021-09-05 18:55   ` Sam Ravnborg
2021-09-09  0:24     ` Doug Anderson

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=87h7ey81e9.fsf@intel.com \
    --to=jani.nikula@linux.intel.com \
    --cc=airlied@linux.ie \
    --cc=bjorn.andersson@linaro.org \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dianders@chromium.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=sam@ravnborg.org \
    --cc=steev@kali.org \
    --cc=thierry.reding@gmail.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.