From patchwork Wed May 11 21:40:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 9075151 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D4544BF29F for ; Wed, 11 May 2016 21:41:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D2651201B9 for ; Wed, 11 May 2016 21:41:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BAEEF20155 for ; Wed, 11 May 2016 21:41:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752109AbcEKVld (ORCPT ); Wed, 11 May 2016 17:41:33 -0400 Received: from mail-pf0-f176.google.com ([209.85.192.176]:32873 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751563AbcEKVlV (ORCPT ); Wed, 11 May 2016 17:41:21 -0400 Received: by mail-pf0-f176.google.com with SMTP id 206so22846850pfu.0 for ; Wed, 11 May 2016 14:41:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=5d9f7CVll0jmPzWJgvjeSjl7Z+EL2CzJ0z6jt3mLVR0=; b=WPaXUWbntPoS5ZgJOOIyQOUoJyNVZSR2MUhVBMm7Sj45mubjLYeJBXOP7ZGstIbGO4 IeZpdbZQok+HEjp/zrrkilFN7FF0xlWmqoyPZ5tDm1Ite/LwETj3p+UdOsrI0Pe1+rqc lY7r6BK5bRCg0YpN2LkSVjBlVXiRonEl7454o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=5d9f7CVll0jmPzWJgvjeSjl7Z+EL2CzJ0z6jt3mLVR0=; b=jj3dlxyQ7Ccgbs+m0zmcMTA3/mRaM3e8UPlSLcdBkZPFZ9H+kpyTxOP6f3DwGshuCc 9LtmJ0ZHC79qgPyHUSddHQ4gFVnh5TtUKDIWSs+xJmYet1KIefm4iJSiAyJxhZObyCVt gjn8a/KX/+SJFWZlJ18Dbop+qv84jn7aikTPhgQvnrGVXA6Xrds3zFVjnHEVvOOFYgyQ gB3eOhbrY4I+/17h1PDTmxDc/ApHb3vNWYHhUZ/e3K5b5OzotG1lvIh5v+ZSEBpzDouD 5O7oEdDVRdkjesZc0LxBsclDZp8VuwlkXQOZC92hDNHM0bw3qKb2/Fup+xpzVzzl/VVO +f7Q== X-Gm-Message-State: AOPr4FXUOmUsRFD02h1hFAhr/vdJg72Xv7n7UM4ZT2js6lxvw+S/q/0m4UTal5fHnx6PEQ== X-Received: by 10.98.54.194 with SMTP id d185mr8411286pfa.34.1463002879995; Wed, 11 May 2016 14:41:19 -0700 (PDT) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by smtp.gmail.com with ESMTPSA id w15sm14477656pfa.34.2016.05.11.14.41.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 May 2016 14:41:19 -0700 (PDT) From: Douglas Anderson To: jh80.chung@samsung.com, Ulf Hansson , Heiko Stuebner , shawn.lin@rock-chips.com Cc: linux-rockchip@lists.infradead.org, briannorris@chromium.org, Douglas Anderson , linux-mmc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] mmc: dw_mmc: rockchip: Set the drive phase properly Date: Wed, 11 May 2016 14:40:48 -0700 Message-Id: <1463002848-580-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,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 Historically for Rockchip devices we've relied on the power-on default (or perhaps the firmware setting) to get the correct drive phase for dw_mmc devices. This worked OK for the most part, but: * Relying on the setting just "being right" is a bit fragile. * As soon as there is an instance where the power on default is wrong or where the firmware didn't configure this properly then we'll get a mysterious failure. Let's explicitly set this phase in the kernel. The comments inside this patch try to explain the situation quite throughly, but the high level overview of this is: Before this patch on rk3288 devices tested: * eMMC: 180 degrees * SDMMC/SDIO0/SDIO1: 90 degrees After this patch: * Use 90 degree phase offset usually. * Use 180 degree phase offset for MMC_DDR52, SDR104, HS200. That means we are _changing_ behavior for those devices in this way: * If we have HS200 eMMC or DDR52 eMMC, we'll run ID mode at 90 degrees (vs 180) but otherwise have no change. * For any non-HS200 / non-DDR52 eMMC devices we'll now _always_ run at 90 degrees (vs 180). It seems fairly unlikely that building modern hardware is using an eMMC that isn't using DDR52 or HS200, of course. * For SDR104 cards we'll now run with 180 degree phase offset (vs 90). It's expected that 90 degree phase offset would have worked OK, but this gives us extra margin. I have tested this by inserting my collection of uSD cards (mostly UHS, though a few not) into a veyron_minnie and confirmed that they still seem to enumerate properly. For a subset of them I tried putting a filesystem on them and also tried running mmc_test. Signed-off-by: Douglas Anderson Reviewed-by: Shawn Lin --- Changes in v2: - Now use 90 degrees for some modes; updated comments to say why. drivers/mmc/host/dw_mmc-rockchip.c | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 8c20b81cafd8..8068fa887db8 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -66,6 +66,70 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) /* Make sure we use phases which we can enumerate with */ if (!IS_ERR(priv->sample_clk)) clk_set_phase(priv->sample_clk, priv->default_sample_phase); + + /* + * Set the drive phase offset based on speed mode to achieve hold times. + * + * That this is _not_ a value that is dynamically tuned and is also + * _not_ a value that will vary from board to board. It is a value + * that could vary between different SoC models if they had massively + * different output clock delays inside their dw_mmc IP block (delay_o), + * but since it's OK to overshoot a little we don't need to do complex + * calculations and can pick values that will just work for everyone. + * + * When picking values we'll stick with picking 0/90/180/270 since + * those can be made very accurately on all known Rockchip SoCs. + * + * Note that these values match values from the DesignWare Databook + * tables for the most part except for SDR12 and "ID mode". For those + * two modes the databook calculations assume a clock in of 50MHz. As + * seen above, we always use a clock in rate that is exactly the + * card's input clock (times RK3288_CLKGEN_DIV, but that gets divided + * back out before the controller sees it). + * + * From measurement of a single device, it appears that delay_o is + * about .5 ns. Since we try to leave a bit of margin, it's expected + * that numbers here will be fine even with much larger delay_o + * (the 1.4 ns assumed by the DesignWare Databook would result in the + * same results, for instance). + */ + if (!IS_ERR(priv->drv_clk)) { + int phase; + + /* + * In almost all cases a 90 degree phase offset will provide + * sufficient hold times across all valid input clock rates + * assuming delay_o is not absurd for a given SoC. We'll use + * that as a default. + */ + phase = 90; + + switch (ios->timing) { + case MMC_TIMING_MMC_DDR52: + /* + * Since clock in rate with MMC_DDR52 is doubled when + * bus width is 8 we need to double the phase offset + * to get the same timings. + */ + if (ios->bus_width == MMC_BUS_WIDTH_8) + phase = 180; + break; + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + /* + * In the case of 150 MHz clock (typical max for + * Rockchip SoCs), 90 degree offset will add a delay + * of 1.67 ns. That will meet min hold time of .8 ns + * as long as clock output delay is < .87 ns. On + * SoCs measured this seems to be OK, but it doesn't + * hurt to give margin here, so we use 180. + */ + phase = 180; + break; + } + + clk_set_phase(priv->drv_clk, phase); + } } #define NUM_PHASES 360