diff mbox

mmc: sdhci-esdhc-imx: Fix i.MX53 eSDHCv3 clock

Message ID 20180114184305.4018-1-benoit.thebaudeau.dev@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Benoît Thébaudeau Jan. 14, 2018, 6:43 p.m. UTC
Commit 5143c953a786 ("mmc: sdhci-esdhc-imx: Allow all supported
prescaler values") made it possible to set SYSCTL.SDCLKFS to 0 in SDR
mode, thus bypassing the SD clock frequency prescaler, in order to be
able to get higher SD clock frequencies in some contexts. However, that
commit missed the fact that this value is illegal on the eSDHCv3
instance of the i.MX53. This seems to be the only exception on i.MX,
this value being legal even for the eSDHCv2 instances of the i.MX53.

Fix this issue by changing the minimum prescaler value if the i.MX53
eSDHCv3 is detected. According to the i.MX53 reference manual, if
DLLCTRL[10] can be set, then the controller is eSDHCv3, else it is
eSDHCv2.

This commit fixes the following issue, which was preventing the i.MX53
Loco (IMX53QSB) board from booting Linux 4.15.0-rc5:
[    1.882668] mmcblk1: error -84 transferring data, sector 2048, nr 8, cmd response 0x900, card status 0xc00
[    2.002255] mmcblk1: error -84 transferring data, sector 2050, nr 6, cmd response 0x900, card status 0xc00
[   12.645056] mmc1: Timeout waiting for hardware interrupt.
[   12.650473] mmc1: sdhci: ============ SDHCI REGISTER DUMP ===========
[   12.656921] mmc1: sdhci: Sys addr:  0x00000000 | Version:  0x00001201
[   12.663366] mmc1: sdhci: Blk size:  0x00000004 | Blk cnt:  0x00000000
[   12.669813] mmc1: sdhci: Argument:  0x00000000 | Trn mode: 0x00000013
[   12.676258] mmc1: sdhci: Present:   0x01f8028f | Host ctl: 0x00000013
[   12.682703] mmc1: sdhci: Power:     0x00000002 | Blk gap:  0x00000000
[   12.689148] mmc1: sdhci: Wake-up:   0x00000000 | Clock:    0x0000003f
[   12.695594] mmc1: sdhci: Timeout:   0x0000008e | Int stat: 0x00000000
[   12.702039] mmc1: sdhci: Int enab:  0x107f004b | Sig enab: 0x107f004b
[   12.708485] mmc1: sdhci: AC12 err:  0x00000000 | Slot int: 0x00001201
[   12.714930] mmc1: sdhci: Caps:      0x07eb0000 | Caps_1:   0x08100810
[   12.721375] mmc1: sdhci: Cmd:       0x0000163a | Max curr: 0x00000000
[   12.727821] mmc1: sdhci: Resp[0]:   0x00000920 | Resp[1]:  0x00000000
[   12.734265] mmc1: sdhci: Resp[2]:   0x00000000 | Resp[3]:  0x00000000
[   12.740709] mmc1: sdhci: Host ctl2: 0x00000000
[   12.745157] mmc1: sdhci: ADMA Err:  0x00000001 | ADMA Ptr: 0xc8049200
[   12.751601] mmc1: sdhci: ============================================
[   12.758110] print_req_error: I/O error, dev mmcblk1, sector 2050
[   12.764135] Buffer I/O error on dev mmcblk1p1, logical block 0, lost sync page write
[   12.775163] EXT4-fs (mmcblk1p1): mounted filesystem without journal. Opts: (null)
[   12.782746] VFS: Mounted root (ext4 filesystem) on device 179:9.
[   12.789151] mmcblk1: response CRC error sending SET_BLOCK_COUNT command, card status 0x900

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Reported-by: Wladimir J. van der Laan <laanwj@gmail.com>
Tested-by: Wladimir J. van der Laan <laanwj@gmail.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Ulf Hansson Jan. 15, 2018, 12:54 p.m. UTC | #1
On 14 January 2018 at 19:43, Benoît Thébaudeau
<benoit.thebaudeau.dev@gmail.com> wrote:
> Commit 5143c953a786 ("mmc: sdhci-esdhc-imx: Allow all supported
> prescaler values") made it possible to set SYSCTL.SDCLKFS to 0 in SDR
> mode, thus bypassing the SD clock frequency prescaler, in order to be
> able to get higher SD clock frequencies in some contexts. However, that
> commit missed the fact that this value is illegal on the eSDHCv3
> instance of the i.MX53. This seems to be the only exception on i.MX,
> this value being legal even for the eSDHCv2 instances of the i.MX53.
>
> Fix this issue by changing the minimum prescaler value if the i.MX53
> eSDHCv3 is detected. According to the i.MX53 reference manual, if
> DLLCTRL[10] can be set, then the controller is eSDHCv3, else it is
> eSDHCv2.
>
> This commit fixes the following issue, which was preventing the i.MX53
> Loco (IMX53QSB) board from booting Linux 4.15.0-rc5:
> [    1.882668] mmcblk1: error -84 transferring data, sector 2048, nr 8, cmd response 0x900, card status 0xc00
> [    2.002255] mmcblk1: error -84 transferring data, sector 2050, nr 6, cmd response 0x900, card status 0xc00
> [   12.645056] mmc1: Timeout waiting for hardware interrupt.
> [   12.650473] mmc1: sdhci: ============ SDHCI REGISTER DUMP ===========
> [   12.656921] mmc1: sdhci: Sys addr:  0x00000000 | Version:  0x00001201
> [   12.663366] mmc1: sdhci: Blk size:  0x00000004 | Blk cnt:  0x00000000
> [   12.669813] mmc1: sdhci: Argument:  0x00000000 | Trn mode: 0x00000013
> [   12.676258] mmc1: sdhci: Present:   0x01f8028f | Host ctl: 0x00000013
> [   12.682703] mmc1: sdhci: Power:     0x00000002 | Blk gap:  0x00000000
> [   12.689148] mmc1: sdhci: Wake-up:   0x00000000 | Clock:    0x0000003f
> [   12.695594] mmc1: sdhci: Timeout:   0x0000008e | Int stat: 0x00000000
> [   12.702039] mmc1: sdhci: Int enab:  0x107f004b | Sig enab: 0x107f004b
> [   12.708485] mmc1: sdhci: AC12 err:  0x00000000 | Slot int: 0x00001201
> [   12.714930] mmc1: sdhci: Caps:      0x07eb0000 | Caps_1:   0x08100810
> [   12.721375] mmc1: sdhci: Cmd:       0x0000163a | Max curr: 0x00000000
> [   12.727821] mmc1: sdhci: Resp[0]:   0x00000920 | Resp[1]:  0x00000000
> [   12.734265] mmc1: sdhci: Resp[2]:   0x00000000 | Resp[3]:  0x00000000
> [   12.740709] mmc1: sdhci: Host ctl2: 0x00000000
> [   12.745157] mmc1: sdhci: ADMA Err:  0x00000001 | ADMA Ptr: 0xc8049200
> [   12.751601] mmc1: sdhci: ============================================
> [   12.758110] print_req_error: I/O error, dev mmcblk1, sector 2050
> [   12.764135] Buffer I/O error on dev mmcblk1p1, logical block 0, lost sync page write
> [   12.775163] EXT4-fs (mmcblk1p1): mounted filesystem without journal. Opts: (null)
> [   12.782746] VFS: Mounted root (ext4 filesystem) on device 179:9.
> [   12.789151] mmcblk1: response CRC error sending SET_BLOCK_COUNT command, card status 0x900
>
> Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
> Reported-by: Wladimir J. van der Laan <laanwj@gmail.com>
> Tested-by: Wladimir J. van der Laan <laanwj@gmail.com>

Thanks, applied for fixes - adding a fixes tag as well as a stable tag!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 85140c9af581..8b941f814472 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -687,6 +687,20 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
>                 return;
>         }
>
> +       /* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
> +       if (is_imx53_esdhc(imx_data)) {
> +               /*
> +                * According to the i.MX53 reference manual, if DLLCTRL[10] can
> +                * be set, then the controller is eSDHCv3, else it is eSDHCv2.
> +                */
> +               val = readl(host->ioaddr + ESDHC_DLL_CTRL);
> +               writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL);
> +               temp = readl(host->ioaddr + ESDHC_DLL_CTRL);
> +               writel(val, host->ioaddr + ESDHC_DLL_CTRL);
> +               if (temp & BIT(10))
> +                       pre_div = 2;
> +       }
> +
>         temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
>         temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
>                 | ESDHC_CLOCK_MASK);
> --
> 2.14.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 85140c9af581..8b941f814472 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -687,6 +687,20 @@  static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 		return;
 	}
 
+	/* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
+	if (is_imx53_esdhc(imx_data)) {
+		/*
+		 * According to the i.MX53 reference manual, if DLLCTRL[10] can
+		 * be set, then the controller is eSDHCv3, else it is eSDHCv2.
+		 */
+		val = readl(host->ioaddr + ESDHC_DLL_CTRL);
+		writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL);
+		temp = readl(host->ioaddr + ESDHC_DLL_CTRL);
+		writel(val, host->ioaddr + ESDHC_DLL_CTRL);
+		if (temp & BIT(10))
+			pre_div = 2;
+	}
+
 	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
 	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
 		| ESDHC_CLOCK_MASK);