From patchwork Mon Apr 7 14:33:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 3945831 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D1B149F370 for ; Mon, 7 Apr 2014 14:33:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F213920240 for ; Mon, 7 Apr 2014 14:33:58 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CF712201D5 for ; Mon, 7 Apr 2014 14:33:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 075EE6E68B; Mon, 7 Apr 2014 07:33:57 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qc0-f171.google.com (mail-qc0-f171.google.com [209.85.216.171]) by gabe.freedesktop.org (Postfix) with ESMTP id A24616E692 for ; Mon, 7 Apr 2014 07:33:55 -0700 (PDT) Received: by mail-qc0-f171.google.com with SMTP id c9so6460841qcz.16 for ; Mon, 07 Apr 2014 07:33:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=sQBU9jt8O6VAdk06UdH4juRdphNsbty6aRBOFwOvBT0=; b=cDoD/zE3s6U1FjhrBCOuRo7njSiCjySbIOJuem5f+N78QpkId+PvA/k5VbfrN4TPRx aeSh6qvTAukepe2Supje+fvjdPQsvmqf3ozpuuXRYT3I2ET22Te97kSxbC01Yy65f4Xc hCvdA3/izUs4W9mkQ4vjc0MbOU5bbn4OpVnndEe81MvSrUrDqTNnIbAjaUl80QwLp2BL A7ma7hi1DZiFpFiYR56xtgxEJhiWzTNXm9dmNbvGSUJDndypJl8pwD89EABDGY9JmpAo Pk6WGyaT7nPL78AtPPc44/ohsXizBZJMUvMez/DFcC+OyBjN+YHdku5cS1bPmZzvNetm pdiA== X-Received: by 10.224.79.72 with SMTP id o8mr33937282qak.20.1396881235035; Mon, 07 Apr 2014 07:33:55 -0700 (PDT) Received: from localhost.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by mx.google.com with ESMTPSA id g18sm34612995qaa.11.2014.04.07.07.33.54 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Mon, 07 Apr 2014 07:33:54 -0700 (PDT) From: Alex Deucher To: dri-devel@lists.freedesktop.org, jani.nikula@linux.intel.com, ville.syrjala@linux.intel.com, treding@nvidia.com Subject: [PATCH 2/4] drm/dp/i2c: send bare addresses to properly reset i2c connections (v4) Date: Mon, 7 Apr 2014 10:33:44 -0400 Message-Id: <1396881226-29667-3-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1396881226-29667-1-git-send-email-alexander.deucher@amd.com> References: <1396881226-29667-1-git-send-email-alexander.deucher@amd.com> MIME-Version: 1.0 Cc: Alex Deucher , Jani Nikula X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 v3: drop leftover debugging code v4: integrate Thierry's comments - add comments about address only transactions - switch back to i and j Signed-off-by: Alex Deucher Cc: Ville Syrjälä Cc: Jani Nikula Cc: Thierry Reding Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/drm_dp_helper.c | 51 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 74724aa..6122a4f 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -665,11 +665,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, { struct drm_dp_aux *aux = adapter->algo_data; unsigned int i, j; + struct drm_dp_aux_msg msg; + int err = 0; - for (i = 0; i < num; i++) { - struct drm_dp_aux_msg msg; - int err; + memset(&msg, 0, sizeof(msg)); + for (i = 0; i < num; i++) { + msg.address = msgs[i].addr; + msg.request = (msgs[i].flags & I2C_M_RD) ? + DP_AUX_I2C_READ : + DP_AUX_I2C_WRITE; + msg.request |= DP_AUX_I2C_MOT; + /* Send a bare address packet to start the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.buffer = NULL; + msg.size = 0; + err = drm_dp_i2c_do_msg(aux, &msg); + if (err < 0) + break; /* * Many hardware implementations support FIFOs larger than a * single byte, but it has been empirically determined that @@ -678,30 +693,28 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, * 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; msg.size = 1; err = drm_dp_i2c_do_msg(aux, &msg); if (err < 0) - return err; + break; } + if (err < 0) + break; } + if (err >= 0) + err = num; + /* Send a bare address packet to close out the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.request &= ~DP_AUX_I2C_MOT; + msg.buffer = NULL; + msg.size = 0; + (void)drm_dp_i2c_do_msg(aux, &msg); - return num; + return err; } static const struct i2c_algorithm drm_dp_i2c_algo = {