Received: by 2002:a05:6a10:eb17:0:0:0:0 with SMTP id hx23csp457969pxb; Thu, 9 Sep 2021 05:03:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzno+8uz+Bxp92iqoi2L0/w17V48Kx0s7quAInbcCDNCXdLOifzqnXyf0xtxPrVjHn/lBoy X-Received: by 2002:a50:998c:: with SMTP id m12mr2898112edb.327.1631189022582; Thu, 09 Sep 2021 05:03:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631189022; cv=none; d=google.com; s=arc-20160816; b=aAs692WyVEOS5qSYrCXxKOkq7sbmKUGEcR6EmiqBYiq6R7h1Jcm1fZwvATVJSF3py4 giro6ybYXcjOZSFjJQrx1kfI7o/Psm7R+K7zfmAujnVHwlJMLxA5fWb4H667JHRdh096 SB5B9vKhD2r8KhuVA+nSvrnPNMA6iWP3R9ueSjUTZhm/yKlZzUZB5VUcYIsYweA4+o12 XUT0ZcLmtNu21nvVrJGHp10MTLc5FtO+5PXgNng9VvXGkPjLi4NOXwRJ0fF1XwuKtQww kPUxfzlt6iW6N2plWOO1p7iSUQnsn6PUdWsKdHchGwSYxSVis2qP6sVupGWbfcMDkmPS k+kA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1F1DzgIBSGNhZQRYC5a2sbKXEiOXjBBepJDj42rOhcc=; b=l94x/rtwC0k/yJoDQuvgdTeyaOHT3+eUxd04pkTs1rvGPUnR+oGkicobSaKGSGDg6w plnYGWrodRAx7qCO2oxj6n4ue2MAfC3LIGP61gsqwLwrS9JGOYU/pfiw3ym9mGc2UsyO HMU0d2VK6VBOiURxszNmRY4mRSG8t8/bDKHupo0Zdi8LTCGbpV5yO3dN0ZIO4rWlsZiN HLrknOtoVt0mAEiBpBcjtcW9emm0cLxIlcc3kf9v9LAGZvusf7V4LLuVudEUDCPUG/lk WE61WZ+7YAG3CPvfFK07qf3uJEERBJ4XOEOtip/AcAT1HWuzk5YEwFswdl1MXy2MzM18 jyNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=NZjmLzSU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id de3si1669796edb.351.2021.09.09.05.03.07; Thu, 09 Sep 2021 05:03:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=NZjmLzSU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344308AbhIIMCM (ORCPT + 99 others); Thu, 9 Sep 2021 08:02:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:34210 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240710AbhIIL54 (ORCPT ); Thu, 9 Sep 2021 07:57:56 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8F7C9613E8; Thu, 9 Sep 2021 11:45:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631187937; bh=YK12GWAxZTbr0JzIwxzmGeiwWHiDJ0ouZj/3THpaviI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NZjmLzSU6Noc+dsXcHLW/SBnATtbYJeGF5bjpNYvuXjF7NgdW/3EKF/Kjt/+W0+mz Gze+CP9KUoGJhv1rxEiJKXQjL0mLStqPCaSEVTGzq2xoFvvATcigQ1PcCpmpN6IPkb SNLQbkHx27DZQB+ai/6MU8V5UdHEuDgWnyYEEVaajWEZ/2cqx6jKEw1GCOISX1fElL v9cWRMqmH3McUpmUSc2v1GqbnQsqpZszOruwolVbeePQyIXYuu/vmkDCrJfT0M8Nwx EH622anoC1rZ9WJXEaiFBlLy9/W4U5zXBPhQhxAH8D6PCk6qUa1I6YBM8R0dXvZ9my BKjtz8FTmBNMg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Thomas Hebb , Ulf Hansson , Sasha Levin , linux-mmc@vger.kernel.org Subject: [PATCH AUTOSEL 5.14 208/252] mmc: rtsx_pci: Fix long reads when clock is prescaled Date: Thu, 9 Sep 2021 07:40:22 -0400 Message-Id: <20210909114106.141462-208-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210909114106.141462-1-sashal@kernel.org> References: <20210909114106.141462-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Hebb [ Upstream commit 3ac5e45291f3f0d699a721357380d4593bc2dcb3 ] For unexplained reasons, the prescaler register for this device needs to be cleared (set to 1) while performing a data read or else the command will hang. This does not appear to affect the real clock rate sent out on the bus, so I assume it's purely to work around a hardware bug. During normal operation, the prescaler is already set to 1, so nothing needs to be done. However, in "initial mode" (which is used for sub-MHz clock speeds, like the core sets while enumerating cards), it's set to 128 and so we need to reset it during data reads. We currently fail to do this for long reads. This has no functional affect on the driver's operation currently written, as the MMC core always sets a clock above 1MHz before attempting any long reads. However, the core could conceivably set any clock speed at any time and the driver should still work, so I think this fix is worthwhile. I personally encountered this issue while performing data recovery on an external chip. My connections had poor signal integrity, so I modified the core code to reduce the clock speed. Without this change, I saw the card enumerate but was unable to actually read any data. Writes don't seem to work in the situation described above even with this change (and even if the workaround is extended to encompass data write commands). I was not able to find a way to get them working. Signed-off-by: Thomas Hebb Link: https://lore.kernel.org/r/2fef280d8409ab0100c26c6ac7050227defd098d.1627818365.git.tommyhebb@gmail.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/rtsx_pci_sdmmc.c | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 4ca937415734..58cfaffa3c2d 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -542,9 +542,22 @@ static int sd_write_long_data(struct realtek_pci_sdmmc *host, return 0; } +static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); +} + +static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); +} + static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) { struct mmc_data *data = mrq->data; + int err; if (host->sg_count < 0) { data->error = host->sg_count; @@ -553,22 +566,19 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) return data->error; } - if (data->flags & MMC_DATA_READ) - return sd_read_long_data(host, mrq); + if (data->flags & MMC_DATA_READ) { + if (host->initial_mode) + sd_disable_initial_mode(host); - return sd_write_long_data(host, mrq); -} + err = sd_read_long_data(host, mrq); -static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); -} + if (host->initial_mode) + sd_enable_initial_mode(host); -static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + return err; + } + + return sd_write_long_data(host, mrq); } static void sd_normal_rw(struct realtek_pci_sdmmc *host, -- 2.30.2