Commit f750ba9b8db2a926c315ccfa9e95d12fe4590a22

Authored by Shawn Guo
Committed by Sascha Hauer
1 parent 1b929995eb

arm/imx: fix imx6q mmc error when mounting rootfs

The following error is seen in some case when mounting rootfs from
SD/MMC cards.

  Waiting for root device /dev/mmcblk0p1...
  mmc1: host does not support reading read-only switch. assuming write-enable.
  mmc1: new high speed SDHC card at address b368
  mmcblk0: mmc1:b368 SDC   3.74 GiB
   mmcblk0: p1
  mmc1: Timeout waiting for hardware interrupt.
  mmcblk0: error -110 transferring data, sector 3678224, nr 40, cmd response 0x900, card status 0xc00
  end_request: I/O error, dev mmcblk0, sector 3678225
  Buffer I/O error on device mmcblk0p1, logical block 458754
  lost page write due to I/O error on mmcblk0p1

This patch fixes the problem by lowering the usdhc clock and correcting
watermark configuration.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Cc: Chris Ball <cjb@laptop.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Showing 2 changed files with 24 additions and 1 deletions Side-by-side Diff

arch/arm/mach-imx/clock-imx6q.c
... ... @@ -1139,7 +1139,7 @@
1139 1139 return -EINVAL;
1140 1140  
1141 1141 max_div = ((d->bm_pred >> d->bp_pred) + 1) *
1142   - ((d->bm_pred >> d->bp_pred) + 1);
  1142 + ((d->bm_podf >> d->bp_podf) + 1);
1143 1143  
1144 1144 div = parent_rate / rate;
1145 1145 if (div == 0)
... ... @@ -2001,6 +2001,21 @@
2001 2001 clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
2002 2002 clk_set_rate(&asrc_serial_clk, 1500000);
2003 2003 clk_set_rate(&enfc_clk, 11000000);
  2004 +
  2005 + /*
  2006 + * Before pinctrl API is available, we have to rely on the pad
  2007 + * configuration set up by bootloader. For usdhc example here,
  2008 + * u-boot sets up the pads for 49.5 MHz case, and we have to lower
  2009 + * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
  2010 + *
  2011 + * FIXME: This is should be removed after pinctrl API is available.
  2012 + * At that time, usdhc driver can call pinctrl API to change pad
  2013 + * configuration dynamically per different usdhc clock settings.
  2014 + */
  2015 + clk_set_rate(&usdhc1_clk, 49500000);
  2016 + clk_set_rate(&usdhc2_clk, 49500000);
  2017 + clk_set_rate(&usdhc3_clk, 49500000);
  2018 + clk_set_rate(&usdhc4_clk, 49500000);
2004 2019  
2005 2020 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
2006 2021 base = of_iomap(np, 0);
drivers/mmc/host/sdhci-esdhc-imx.c
... ... @@ -32,6 +32,7 @@
32 32 /* VENDOR SPEC register */
33 33 #define SDHCI_VENDOR_SPEC 0xC0
34 34 #define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
  35 +#define SDHCI_WTMK_LVL 0x44
35 36 #define SDHCI_MIX_CTRL 0x48
36 37  
37 38 /*
... ... @@ -475,6 +476,13 @@
475 476  
476 477 if (is_imx53_esdhc(imx_data))
477 478 imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
  479 +
  480 + /*
  481 + * The imx6q ROM code will change the default watermark level setting
  482 + * to something insane. Change it back here.
  483 + */
  484 + if (is_imx6q_usdhc(imx_data))
  485 + writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL);
478 486  
479 487 boarddata = &imx_data->boarddata;
480 488 if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {