From patchwork Mon May 13 13:47:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 2558561 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E783E3FE37 for ; Mon, 13 May 2013 13:48:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752707Ab3EMNsS (ORCPT ); Mon, 13 May 2013 09:48:18 -0400 Received: from eu1sys200aog115.obsmtp.com ([207.126.144.139]:49660 "EHLO eu1sys200aog115.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752727Ab3EMNsR (ORCPT ); Mon, 13 May 2013 09:48:17 -0400 Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob115.postini.com ([207.126.147.11]) with SMTP ID DSNKUZDu+zDRPZz+Yp6S8KATETEFozyKCz8v@postini.com; Mon, 13 May 2013 13:48:17 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 78426D2; Mon, 13 May 2013 13:47:35 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 220D23FD; Mon, 13 May 2013 13:47:35 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 0D95824C2AB; Mon, 13 May 2013 15:47:27 +0200 (CEST) Received: from steludxu1397.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.279.5; Mon, 13 May 2013 15:47:34 +0200 From: Ulf Hansson To: , Russell King Cc: , Chris Ball , Daniel Lezcano , Linus Walleij , Rickard Andersson , Ulf Hansson , Johan Rudholm Subject: [PATCH 2/3] mmc: mmci: Adapt to register write restrictions Date: Mon, 13 May 2013 15:47:16 +0200 Message-ID: <1368452837-31458-3-git-send-email-ulf.hansson@stericsson.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1368452837-31458-1-git-send-email-ulf.hansson@stericsson.com> References: <1368452837-31458-1-git-send-email-ulf.hansson@stericsson.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Ulf Hansson After a write to the MMCICLOCK register data cannot be written to this register for three feedback clock cycles. Writes to the MMCIPOWER register must be separated by three MCLK cycles. Previously no issues has been observered, but using higher ARM clock frequencies on STE- platforms has triggered this problem. The MMCICLOCK register is written to in .set_ios and for some data transmissions for SDIO. We do not need a delay at the data transmission path, because sending and receiving data will require more than three clock cycles. Then we use a simple logic to only delay in .set_ios and thus we don't affect throughput performance. Signed-off-by: Ulf Hansson Signed-off-by: Johan Rudholm --- drivers/mmc/host/mmci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 98b0c16..7815816 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -166,6 +166,21 @@ static int mmci_validate_data(struct mmci_host *host, return 0; } +static void mmci_reg_delay(struct mmci_host *host) +{ + /* + * According to the spec, at least three feedback clock cycles + * of max 52 MHz must pass between two writes to the MMCICLOCK reg. + * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. + * Worst delay time during card init is at 100 kHz => 30 us. + * Worst delay time when up and running is at 25 MHz => 120 ns. + */ + if (host->cclk < 20000000) + udelay(30); + else + ndelay(120); +} + /* * This must be called with host->lock held */ @@ -1212,6 +1227,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmci_set_clkreg(host, ios->clock); mmci_write_pwrreg(host, pwr); + mmci_reg_delay(host); spin_unlock_irqrestore(&host->lock, flags);