Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f750ba9b authored by Shawn Guo's avatar Shawn Guo Committed by Sascha Hauer
Browse files

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: default avatarShawn Guo <shawn.guo@linaro.org>
Cc: Chris Ball <cjb@laptop.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
parent 1b929995
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -1139,7 +1139,7 @@ static int _clk_set_rate(struct clk *clk, unsigned long rate)
		return -EINVAL;

	max_div = ((d->bm_pred >> d->bp_pred) + 1) *
		  ((d->bm_pred >> d->bp_pred) + 1);
		  ((d->bm_podf >> d->bp_podf) + 1);

	div = parent_rate / rate;
	if (div == 0)
@@ -2002,6 +2002,21 @@ int __init mx6q_clocks_init(void)
	clk_set_rate(&asrc_serial_clk, 1500000);
	clk_set_rate(&enfc_clk, 11000000);

	/*
	 * Before pinctrl API is available, we have to rely on the pad
	 * configuration set up by bootloader.  For usdhc example here,
	 * u-boot sets up the pads for 49.5 MHz case, and we have to lower
	 * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
	 *
	 * FIXME: This is should be removed after pinctrl API is available.
	 * At that time, usdhc driver can call pinctrl API to change pad
	 * configuration dynamically per different usdhc clock settings.
	 */
	clk_set_rate(&usdhc1_clk, 49500000);
	clk_set_rate(&usdhc2_clk, 49500000);
	clk_set_rate(&usdhc3_clk, 49500000);
	clk_set_rate(&usdhc4_clk, 49500000);

	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
	base = of_iomap(np, 0);
	WARN_ON(!base);
+8 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC		0xC0
#define  SDHCI_VENDOR_SPEC_SDIO_QUIRK	0x00000002
#define SDHCI_WTMK_LVL			0x44
#define SDHCI_MIX_CTRL			0x48

/*
@@ -476,6 +477,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
	if (is_imx53_esdhc(imx_data))
		imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;

	/*
	 * The imx6q ROM code will change the default watermark level setting
	 * to something insane.  Change it back here.
	 */
	if (is_imx6q_usdhc(imx_data))
		writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL);

	boarddata = &imx_data->boarddata;
	if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
		if (!host->mmc->parent->platform_data) {