Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp5020717imm; Fri, 18 May 2018 15:05:02 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqri9b6whi0GaJMWp1ImVNAQFD5sVRftPzsdPkRF7eG22ABsSzzlNvfvTId9pHaqfO2kNtV X-Received: by 2002:a63:7c51:: with SMTP id l17-v6mr4873780pgn.205.1526681102681; Fri, 18 May 2018 15:05:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526681102; cv=none; d=google.com; s=arc-20160816; b=bIX440UnA6CpC5WTRzBPODYUKwJPRVbF+qqC8LxBnxJZldvglwPag/svTR1hyCYKiC IsqfabWFKG9iR/Y68J9xwjxZvcMl114mtmu4cXmzLDiZSrOJxWnm8rS9PEHgg+wao4vd 7T5HMNy0ME64JzI4T9aR0P7l7wvzJhbg8WKaBfd33EheVpy7Hu+WJ4jNP4mHhq+LXhe5 3kBTduib/XWasqoYVFsDllnPPXnU9JK2Ia4yEdBv0PugSnks7NZQVaS5S8ReVbMR/0jQ Ddk7Bc5uBG6yI06F4w1t2FhCJHhNQbvrwwfdP6xNBOWsP3o8/Co9ktRDv/+J1ULJyKr+ A0Gw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=P9TmFE4C8QLPHvF9WtnZuh1tM46GYImRJSgqnKrVENs=; b=Mcy9c5GC6ZSpVK0hv5AdGxxAN3kVfk3ZUnra5pgUeHALHA5Y2B3IDkMgTdDyX46I8P E2DiQ1ay7lOHkF98BiE0lku69p/0UGxxoWoLJ0f319zCirdt/JZFukb/3fKfKZjSyNOl oa4Y3Q9Zj82eCg70BjiXHITVfuPeDjPgNuDZB+YUpE5uLi1XFIFG8mTxrH80cyr7XPKK 8qRSUUN6r/JQMMH2X71PtJXTnZAeeyyKNfl24Q2VEGQfROK70QYX2ZS48coBoBcfpDRB taHcOma1KRDKjv6aZliCafXDlKzFnau0gLoDzBAvNel7k9J1Y9QhNMrEgbRamULLa5/N URMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=GcoxulEA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d190-v6si8672814pfg.142.2018.05.18.15.04.47; Fri, 18 May 2018 15:05:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=GcoxulEA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752419AbeERWET (ORCPT + 99 others); Fri, 18 May 2018 18:04:19 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:35595 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752349AbeERWEN (ORCPT ); Fri, 18 May 2018 18:04:13 -0400 Received: by mail-qt0-f194.google.com with SMTP id f5-v6so12245159qth.2 for ; Fri, 18 May 2018 15:04:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=P9TmFE4C8QLPHvF9WtnZuh1tM46GYImRJSgqnKrVENs=; b=GcoxulEA0cHbFF0dSwalGfHnoG++2d4i8/lATrPkyfUJsR9yRCh4hzNJS/9tvs6qt5 CUWK+zWiGyOnLsApgdhZLv3yF0wfd6q5eKJY1pWpzGgUnaP38LfasM+Y+GaY4Js20MPq +1zv/D0TRpxmIIbWOI9nIHuEtM9gYIEkYmKzA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=P9TmFE4C8QLPHvF9WtnZuh1tM46GYImRJSgqnKrVENs=; b=n2SuWdQzipR5qs/Hujm4Bi+uzBoJjdE5ayEItTf6xm3flGWfuIICRJ1OgqBW66GLbr GtRltIj659ZOSkVh178wzE15hfCS6bUjfdPESIdfMrmRzrAWq0XwNOJ1mkx5Y+bdjHpc BxTnuQ7JKt0UU0GJFE9lDUSh/9Aus7cpMLmjn+3h7OF3m3Qb+MILG5ls4ySmBiPmFe1o uzozNwqkSbcZ2ZlR+mvma5PhAdgptSqXpt7O0lfCocl8CaN66daC9IN91orjIBaSB9A6 iD3ffPZxFmh9LA8GAij3syg4Hn1iFbzOxOLkKKI8nWKxJCm8mIiamg+ASxcoyRucZyEC l0HQ== X-Gm-Message-State: ALKqPwcZcFQEbt68vRbBoWyTTgy3zoD9K13l8BnXbeHvQqKiLheDtfVD jg9MzQuCMlECzX1irjCYlzXOnA== X-Received: by 2002:aed:3ead:: with SMTP id n42-v6mr11028984qtf.56.1526681052870; Fri, 18 May 2018 15:04:12 -0700 (PDT) Received: from lbrmn-lnxub113.ric.broadcom.com ([192.19.228.250]) by smtp.gmail.com with ESMTPSA id m4-v6sm1829866qkf.91.2018.05.18.15.04.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 18 May 2018 15:04:12 -0700 (PDT) From: Scott Branden To: Adrian Hunter , Ulf Hansson Cc: BCM Kernel Feedback , linux-mmc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Corneliu Doban , Scott Branden Subject: [PATCH 2/3] mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register Date: Fri, 18 May 2018 15:03:56 -0700 Message-Id: <1526681037-2074-3-git-send-email-scott.branden@broadcom.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1526681037-2074-1-git-send-email-scott.branden@broadcom.com> References: <1526681037-2074-1-git-send-email-scott.branden@broadcom.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Corneliu Doban When the host controller accepts only 32bit writes, the value of the 16bit TRANSFER_MODE register, that has the same 32bit address as the 16bit COMMAND register, needs to be saved and it will be written in a 32bit write together with the command as this will trigger the host to send the command on the SD interface. When sending the tuning command, TRANSFER_MODE is written and then sdhci_set_transfer_mode reads it back to clear AUTO_CMD12 bit and write it again resulting in wrong value to be written because the initial write value was saved in a shadow and the read-back returned a wrong value, from the register. Fix sdhci_iproc_readw to return the saved value of TRANSFER_MODE when a saved value exist. Same fix for read of BLOCK_SIZE and BLOCK_COUNT registers, that are saved for a different reason, although a scenario that will cause the mentioned problem on this registers is not probable. Fixes: b580c52d58d9 ("mmc: sdhci-iproc: add IPROC SDHCI driver") Signed-off-by: Corneliu Doban Signed-off-by: Scott Branden --- drivers/mmc/host/sdhci-iproc.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c index 6f430da..1f0ab08 100644 --- a/drivers/mmc/host/sdhci-iproc.c +++ b/drivers/mmc/host/sdhci-iproc.c @@ -33,6 +33,8 @@ struct sdhci_iproc_host { const struct sdhci_iproc_data *data; u32 shadow_cmd; u32 shadow_blk; + bool is_cmd_shadowed; + bool is_blk_shadowed; }; #define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18) @@ -48,8 +50,22 @@ static inline u32 sdhci_iproc_readl(struct sdhci_host *host, int reg) static u16 sdhci_iproc_readw(struct sdhci_host *host, int reg) { - u32 val = sdhci_iproc_readl(host, (reg & ~3)); - u16 word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host); + u32 val; + u16 word; + + if ((reg == SDHCI_TRANSFER_MODE) && iproc_host->is_cmd_shadowed) { + /* Get the saved transfer mode */ + val = iproc_host->shadow_cmd; + } else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) && + iproc_host->is_blk_shadowed) { + /* Get the saved block info */ + val = iproc_host->shadow_blk; + } else { + val = sdhci_iproc_readl(host, (reg & ~3)); + } + word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff; return word; } @@ -105,13 +121,15 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg) if (reg == SDHCI_COMMAND) { /* Write the block now as we are issuing a command */ - if (iproc_host->shadow_blk != 0) { + if (iproc_host->is_blk_shadowed) { sdhci_iproc_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); - iproc_host->shadow_blk = 0; + iproc_host->is_blk_shadowed = false; } oldval = iproc_host->shadow_cmd; - } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { + iproc_host->is_cmd_shadowed = false; + } else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) && + iproc_host->is_blk_shadowed) { /* Block size and count are stored in shadow reg */ oldval = iproc_host->shadow_blk; } else { @@ -123,9 +141,11 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg) if (reg == SDHCI_TRANSFER_MODE) { /* Save the transfer mode until the command is issued */ iproc_host->shadow_cmd = newval; + iproc_host->is_cmd_shadowed = true; } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { /* Save the block info until the command is issued */ iproc_host->shadow_blk = newval; + iproc_host->is_blk_shadowed = true; } else { /* Command or other regular 32-bit write */ sdhci_iproc_writel(host, newval, reg & ~3); -- 2.5.0