From: "Niklas Söderlund" <niklas.soderlund@ragnatech.se>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Maling list - DRI developers <dri-devel@lists.freedesktop.org>,
Linux Media Mailing List <linux-media@vger.kernel.org>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Archit Taneja <architt@codeaurora.org>
Subject: Re: [PATCH] drm/bridge: adv7511: fix support for large EDIDs
Date: Fri, 26 Mar 2021 01:39:13 +0100 [thread overview]
Message-ID: <YF0tMe30JkLE/E8I@oden.dyn.berto.se> (raw)
In-Reply-To: <904185be-19ea-a321-a227-d4e659fe1b68@xs4all.nl>
Hi Hans,
Thanks for your patch.
On 2021-03-24 09:53:32 +0100, Hans Verkuil wrote:
> While testing support for large (> 256 bytes) EDIDs on the Renesas
> Koelsch board I noticed that the adv7511 bridge driver only read the
> first two blocks.
>
> The media V4L2 version for the adv7511 (drivers/media/i2c/adv7511-v4l2.c)
> handled this correctly.
>
> Besides a simple bug when setting the segment register (it was set to the
> block number instead of block / 2), the logic of the code was also weird.
> In particular reading the DDC_STATUS is odd: this is unrelated to EDID
> reading.
>
> The reworked code just waits for any EDID segment reads to finish (this
> does nothing if the a segment is already read), checks if the desired
> segment matches the read segment, and if not, then it requests the new
> segment and waits again for the EDID segment to be read.
>
> Finally it checks if the currently buffered EDID segment contains the
> desired EDID block, and if not it will update the EDID buffer from
> the adv7511.
>
> Tested with my Koelsch board and with EDIDs of 1, 2, 3 and 4 blocks.
>
> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> Testing on the Renesas board also requires these two adv7604 patches
> if you want to test with an HDMI cable between the HDMI input and output:
>
> https://patchwork.linuxtv.org/project/linux-media/patch/00882808-472a-d429-c565-a701da579ead@xs4all.nl/
> https://patchwork.linuxtv.org/project/linux-media/patch/c7093e76-ffb4-b19c-f576-b264f935a3ce@xs4all.nl/
> ---
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index 76555ae64e9c..9e8db1c60167 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -328,6 +328,7 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
> static void __adv7511_power_on(struct adv7511 *adv7511)
> {
> adv7511->current_edid_segment = -1;
> + adv7511->edid_read = false;
>
> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
> ADV7511_POWER_POWER_DOWN, 0);
> @@ -529,29 +530,35 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
> struct adv7511 *adv7511 = data;
> struct i2c_msg xfer[2];
> uint8_t offset;
> + unsigned int cur_segment;
> unsigned int i;
> int ret;
>
> if (len > 128)
> return -EINVAL;
>
> - if (adv7511->current_edid_segment != block / 2) {
> - unsigned int status;
> + /* wait for any EDID segment reads to finish */
> + adv7511_wait_for_edid(adv7511, 200);
>
> - ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS,
> - &status);
> + ret = regmap_read(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, &cur_segment);
> + if (ret < 0)
> + return ret;
> +
> + /*
> + * If the current read segment does not match what we need, then
> + * write the new segment and wait for it to be read.
> + */
> + if (cur_segment != block / 2) {
> + adv7511->edid_read = false;
> + cur_segment = block / 2;
> + regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
> + cur_segment);
> + ret = adv7511_wait_for_edid(adv7511, 200);
> if (ret < 0)
> return ret;
> + }
>
> - if (status != 2) {
> - adv7511->edid_read = false;
> - regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
> - block);
> - ret = adv7511_wait_for_edid(adv7511, 200);
> - if (ret < 0)
> - return ret;
> - }
> -
> + if (adv7511->current_edid_segment != cur_segment) {
> /* Break this apart, hopefully more I2C controllers will
> * support 64 byte transfers than 256 byte transfers
> */
> @@ -579,7 +586,7 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
> offset += 64;
> }
>
> - adv7511->current_edid_segment = block / 2;
> + adv7511->current_edid_segment = cur_segment;
> }
>
> if (block % 2 == 0)
--
Regards,
Niklas Söderlund
next prev parent reply other threads:[~2021-03-26 0:40 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-24 8:53 [PATCH] drm/bridge: adv7511: fix support for large EDIDs Hans Verkuil
2021-03-26 0:39 ` Niklas Söderlund [this message]
2021-03-26 1:00 ` Laurent Pinchart
2021-03-26 6:17 ` Hans Verkuil
2021-03-26 6:31 ` Hans Verkuil
2021-03-26 12:33 ` Laurent Pinchart
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=YF0tMe30JkLE/E8I@oden.dyn.berto.se \
--to=niklas.soderlund@ragnatech.se \
--cc=architt@codeaurora.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=hverkuil@xs4all.nl \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
/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).