From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Alex Deucher <alexdeucher@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 2/3] drm/dp/i2c: send bare addresses to properly reset i2c connections
Date: Fri, 4 Apr 2014 18:31:24 +0300 [thread overview]
Message-ID: <20140404153124.GC12024@intel.com> (raw)
In-Reply-To: <1396622458-2092-3-git-send-email-alexander.deucher@amd.com>
On Fri, Apr 04, 2014 at 10:40:57AM -0400, Alex Deucher wrote:
> We need bare address packets at the start and end of
> each i2c over aux transaction to properly reset the connection
> between transactions. This mirrors what the existing dp i2c
> over aux algo currently does.
>
> This fixes EDID fetches on certain monitors especially with
> dp bridges.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/drm_dp_helper.c | 53 +++++++++++++++++++++++------------------
> 1 file changed, 30 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index f4babed..f0c2850 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -664,12 +664,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
> int num)
> {
> struct drm_dp_aux *aux = adapter->algo_data;
> - unsigned int i, j;
> + unsigned int m, b;
> + struct drm_dp_aux_msg msg;
> + int err = 0;
> + u8 buf = 0;
>
> - for (i = 0; i < num; i++) {
> - struct drm_dp_aux_msg msg;
> - int err;
> + memset(&msg, 0, sizeof(msg));
>
> + for (m = 0; m < num; m++) {
> + msg.address = msgs[m].addr;
> + msg.request = (msgs[m].flags & I2C_M_RD) ?
> + DP_AUX_I2C_READ :
> + DP_AUX_I2C_WRITE;
> + msg.request |= DP_AUX_I2C_MOT;
> + msg.buffer = &buf;
Maybe just pass NULL and let buggy implementations explode?
> + msg.size = 0;
> + err = drm_dp_i2c_do_msg(aux, &msg);
> + if (err < 0) {
> + printk("error %d in bare address write\n", err);
> + break;
> + }
> /*
> * Many hardware implementations support FIFOs larger than a
> * single byte, but it has been empirically determined that
> @@ -677,31 +691,24 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
> * decreased performance. Therefore each message is simply
> * transferred byte-by-byte.
> */
> - for (j = 0; j < msgs[i].len; j++) {
> - memset(&msg, 0, sizeof(msg));
> - msg.address = msgs[i].addr;
> -
> - msg.request = (msgs[i].flags & I2C_M_RD) ?
> - DP_AUX_I2C_READ :
> - DP_AUX_I2C_WRITE;
> -
> - /*
> - * All messages except the last one are middle-of-
> - * transfer messages.
> - */
> - if ((i < num - 1) || (j < msgs[i].len - 1))
> - msg.request |= DP_AUX_I2C_MOT;
> -
> - msg.buffer = msgs[i].buf + j;
> + for (b = 0; b < msgs[m].len; b++) {
> + msg.buffer = msgs[m].buf + b;
> msg.size = 1;
>
> err = drm_dp_i2c_do_msg(aux, &msg);
> if (err < 0)
> - return err;
> + break;
This will abort the current message, but it'll keep going and try to
tranfer the next message. We need to abort the entire thing and proceed
to generate the i2c STOP.
Also you're now reusing the msg and expecting .transfer() to not clobber
any of the fields (apart from msg.reply). Hmm, actually the retry loop
in drm_dp_i2c_do_msg() already requires such a contract between the
caller and the callee. As we can't make the msg const due to msg.reply,
it would be nice if the documentation mentioned this somewhat important
detail.
> }
> }
> -
> - return num;
> + if (err >= 0)
> + err = num;
> + /* send a bare address packet to close out the connection */
> + msg.request &= ~DP_AUX_I2C_MOT;
> + msg.buffer = &buf;
Another chance to make buggy drivers explode ;)
> + msg.size = 0;
> + (void)drm_dp_i2c_do_msg(aux, &msg);
> +
> + return err;
> }
>
> static const struct i2c_algorithm drm_dp_i2c_algo = {
> --
> 1.8.3.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Ville Syrjälä
Intel OTC
next prev parent reply other threads:[~2014-04-04 15:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-04 14:40 [PATCH 0/3] Reset i2c connection between xfers Alex Deucher
2014-04-04 14:40 ` [PATCH 1/3] drm/radeon/dp: handle zero sized i2c over aux transactions Alex Deucher
2014-04-04 14:40 ` [PATCH 2/3] drm/dp/i2c: send bare addresses to properly reset i2c connections Alex Deucher
2014-04-04 15:31 ` Ville Syrjälä [this message]
2014-04-04 15:32 ` Daniel Vetter
2014-04-04 14:40 ` [PATCH 3/3] drm/radeon/dp: switch to the common i2c over aux code Alex Deucher
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=20140404153124.GC12024@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=alexander.deucher@amd.com \
--cc=alexdeucher@gmail.com \
--cc=dri-devel@lists.freedesktop.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 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.