From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [PATCH 2/4] drm/dp/i2c: send bare addresses to properly reset i2c connections (v2) Date: Fri, 4 Apr 2014 21:46:30 +0300 Message-ID: <20140404184630.GA4481@intel.com> References: <1396633926-10403-1-git-send-email-alexander.deucher@amd.com> <1396633926-10403-3-git-send-email-alexander.deucher@amd.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 2F3C76EDE2 for ; Fri, 4 Apr 2014 11:47:34 -0700 (PDT) Content-Disposition: inline In-Reply-To: <1396633926-10403-3-git-send-email-alexander.deucher@amd.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Alex Deucher Cc: Alex Deucher , Jani Nikula , treding@nvidia.com, dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org On Fri, Apr 04, 2014 at 01:52:04PM -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. > = > v2: update as per Ville's comments > - Set buffer to NULL for zero sized packets > - abort the entre transaction if one of the messages fails > = > Signed-off-by: Alex Deucher > Cc: Ville Syrj=E4l=E4 > Cc: Jani Nikula > Cc: Thierry Reding > --- > drivers/gpu/drm/drm_dp_helper.c | 54 +++++++++++++++++++++++------------= ------ > 1 file changed, 31 insertions(+), 23 deletions(-) > = > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_hel= per.c > index 74724aa..125f84d 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -664,12 +664,25 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adap= ter, struct i2c_msg *msgs, > int num) > { > struct drm_dp_aux *aux =3D adapter->algo_data; > - unsigned int i, j; > + unsigned int m, b; > + struct drm_dp_aux_msg msg; > + int err =3D 0; > = > - for (i =3D 0; i < num; i++) { > - struct drm_dp_aux_msg msg; > - int err; > + memset(&msg, 0, sizeof(msg)); > = > + for (m =3D 0; m < num; m++) { > + msg.address =3D msgs[m].addr; > + msg.request =3D (msgs[m].flags & I2C_M_RD) ? > + DP_AUX_I2C_READ : > + DP_AUX_I2C_WRITE; > + msg.request |=3D DP_AUX_I2C_MOT; > + msg.buffer =3D NULL; > + msg.size =3D 0; > + err =3D drm_dp_i2c_do_msg(aux, &msg); > + if (err < 0) { > + printk("error %d in bare address write\n", err); I guess this printk was some leftover debug thing? Either should be dropped or converted to some more appropriate DRM_ thing I suppose. But otherwise the patch looks good: Reviewed-by: Ville Syrj=E4l=E4 > + break; > + } > /* > * Many hardware implementations support FIFOs larger than a > * single byte, but it has been empirically determined that > @@ -677,31 +690,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adap= ter, struct i2c_msg *msgs, > * decreased performance. Therefore each message is simply > * transferred byte-by-byte. > */ > - for (j =3D 0; j < msgs[i].len; j++) { > - memset(&msg, 0, sizeof(msg)); > - msg.address =3D msgs[i].addr; > - > - msg.request =3D (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 |=3D DP_AUX_I2C_MOT; > - > - msg.buffer =3D msgs[i].buf + j; > + for (b =3D 0; b < msgs[m].len; b++) { > + msg.buffer =3D msgs[m].buf + b; > msg.size =3D 1; > = > err =3D drm_dp_i2c_do_msg(aux, &msg); > if (err < 0) > - return err; > + break; > } > + if (err < 0) > + break; > } > - > - return num; > + if (err >=3D 0) > + err =3D num; > + /* send a bare address packet to close out the connection */ > + msg.request &=3D ~DP_AUX_I2C_MOT; > + msg.buffer =3D NULL; > + msg.size =3D 0; > + (void)drm_dp_i2c_do_msg(aux, &msg); > + > + return err; > } > = > static const struct i2c_algorithm drm_dp_i2c_algo =3D { > -- = > 1.8.3.1 -- = Ville Syrj=E4l=E4 Intel OTC