[U-Boot] [PATCH 1/3] esdhc: Workaround for card can't be detected on T4240QDS

Card detection pin is ineffective on T4240QDS. This workaround force sdhc driver scan and initialize the card regardless of whether the card is inserted. if no card is in the slot, the error message "card is not inserted" will be prompted.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com --- drivers/mmc/fsl_esdhc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index e3cd0c7..e330379 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -500,6 +500,10 @@ static int esdhc_getcd(struct mmc *mmc) struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000;
+/* Card detecting pin is not functional on T4240QDS */ +#if defined(CONFIG_T4240QDS) + return 1; +#endif while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) udelay(1000);

The upper 4 data signals of esdhc are shared with spi flash. So detect if the upper 4 pins are assigned to esdhc before enable sdhc 8 bit width.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com --- drivers/mmc/fsl_esdhc.c | 6 ++++++ include/configs/T4240QDS.h | 2 ++ 2 files changed, 8 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index e330379..524cc10 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -593,6 +593,12 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) mmc->host_caps &= ~MMC_MODE_4BIT; }
+ /* Detect if the upper 4 pins are used for ESDHC */ +#if defined(CONFIG_T4240QDS) + if (!(readb(QIXIS_BASE + QIXIS_BRDCFG5) & QIXIS_MUX_SDHC_WIDTH8)) + mmc->host_caps &= ~MMC_MODE_8BIT; +#endif + if (caps & ESDHC_HOSTCAPBLT_HSS) mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
diff --git a/include/configs/T4240QDS.h b/include/configs/T4240QDS.h index 3777ccb..77e8ac0 100644 --- a/include/configs/T4240QDS.h +++ b/include/configs/T4240QDS.h @@ -165,6 +165,8 @@ unsigned long get_board_ddr_clk(void); #define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 #define QIXIS_RCFG_CTL_RECONFIG_START 0x21 #define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08 +#define QIXIS_BRDCFG5 0x55 +#define QIXIS_MUX_SDHC_WIDTH8 1 #define QIXIS_BASE_PHYS (0xf00000000ull | QIXIS_BASE)
#define CONFIG_SYS_CSPR3_EXT (0xf)

Hi Haijun,
On Dec 2, 2013, at 7:25 AM, Haijun Zhang wrote:
The upper 4 data signals of esdhc are shared with spi flash. So detect if the upper 4 pins are assigned to esdhc before enable sdhc 8 bit width.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com
drivers/mmc/fsl_esdhc.c | 6 ++++++ include/configs/T4240QDS.h | 2 ++ 2 files changed, 8 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index e330379..524cc10 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -593,6 +593,12 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) mmc->host_caps &= ~MMC_MODE_4BIT; }
- /* Detect if the upper 4 pins are used for ESDHC */
+#if defined(CONFIG_T4240QDS)
- if (!(readb(QIXIS_BASE + QIXIS_BRDCFG5) & QIXIS_MUX_SDHC_WIDTH8))
mmc->host_caps &= ~MMC_MODE_8BIT;
+#endif
Same comments as earlier.
Use a generic CONFIG quirk define.
if (caps & ESDHC_HOSTCAPBLT_HSS) mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
diff --git a/include/configs/T4240QDS.h b/include/configs/T4240QDS.h index 3777ccb..77e8ac0 100644 --- a/include/configs/T4240QDS.h +++ b/include/configs/T4240QDS.h @@ -165,6 +165,8 @@ unsigned long get_board_ddr_clk(void); #define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 #define QIXIS_RCFG_CTL_RECONFIG_START 0x21 #define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08 +#define QIXIS_BRDCFG5 0x55 +#define QIXIS_MUX_SDHC_WIDTH8 1 #define QIXIS_BASE_PHYS (0xf00000000ull | QIXIS_BASE)
#define CONFIG_SYS_CSPR3_EXT (0xf)
1.8.4
Regards
-- Pantelis

On BSC9131 and BSC9132: For High Capacity SD Cards (> 2 GBytes), the 32-bit source address specifies the memory address in block address format. Block length is fixed to 512 bytes as per the SD High Capacity specification. So we need to convert the block address format to byte address format to calculate the envaddr.
If there is no enough space for environment variables or envaddr is larger than 4GiB, we relocate the envaddr to 0x400. The address relocated is in the front of the first partition that is assigned for sdboot only.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com --- board/freescale/common/sdhc_boot.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c index f6e2b2b..9dc9988 100644 --- a/board/freescale/common/sdhc_boot.c +++ b/board/freescale/common/sdhc_boot.c @@ -16,6 +16,9 @@ #define ESDHC_BOOT_IMAGE_SIZE 0x48 #define ESDHC_BOOT_IMAGE_ADDR 0x50
+#define ESDHC_DEFAULT_ENVADDR 0x400 +#define UINT_MAX 0xFFFFFFFF + int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { u8 *tmp_buf; @@ -39,6 +42,34 @@ int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) /* Get the code size from offset 0x48 */ code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
+ /* + * On soc BSC9131, BSC9132: + * In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and + * code length of these soc specify the memory address in block address + * format. Block length is fixed to 512 bytes as per the SD High + * Capacity specification. + */ + if ((SVR_SOC_VER(get_svr()) == SVR_9131) || + (SVR_SOC_VER(get_svr()) == SVR_9132)) { + u64 tmp; + + if (mmc->high_capacity) { + tmp = (u64)code_offset * blklen; + tmp += code_len * blklen; + } else + tmp = code_offset + code_len; + + if (((tmp + CONFIG_ENV_SIZE) > mmc->capacity) || + (tmp > UINT_MAX)) + *env_addr = ESDHC_DEFAULT_ENVADDR; + else + *env_addr = tmp; + + free(tmp_buf); + + return 0; + } + *env_addr = code_offset + code_len;
free(tmp_buf);

Hi Haijun,
On Dec 2, 2013, at 7:25 AM, Haijun Zhang wrote:
On BSC9131 and BSC9132: For High Capacity SD Cards (> 2 GBytes), the 32-bit source address specifies the memory address in block address format. Block length is fixed to 512 bytes as per the SD High Capacity specification. So we need to convert the block address format to byte address format to calculate the envaddr.
If there is no enough space for environment variables or envaddr is larger than 4GiB, we relocate the envaddr to 0x400. The address relocated is in the front of the first partition that is assigned for sdboot only.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com
board/freescale/common/sdhc_boot.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c index f6e2b2b..9dc9988 100644 --- a/board/freescale/common/sdhc_boot.c +++ b/board/freescale/common/sdhc_boot.c @@ -16,6 +16,9 @@ #define ESDHC_BOOT_IMAGE_SIZE 0x48 #define ESDHC_BOOT_IMAGE_ADDR 0x50
+#define ESDHC_DEFAULT_ENVADDR 0x400 +#define UINT_MAX 0xFFFFFFFF
^ Definition of UINT_MAX in a c file?
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { u8 *tmp_buf; @@ -39,6 +42,34 @@ int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) /* Get the code size from offset 0x48 */ code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
- /*
* On soc BSC9131, BSC9132:
* In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and
* code length of these soc specify the memory address in block address
* format. Block length is fixed to 512 bytes as per the SD High
* Capacity specification.
*/
- if ((SVR_SOC_VER(get_svr()) == SVR_9131) ||
(SVR_SOC_VER(get_svr()) == SVR_9132)) {
u64 tmp;
if (mmc->high_capacity) {
tmp = (u64)code_offset * blklen;
tmp += code_len * blklen;
} else
tmp = code_offset + code_len;
if (((tmp + CONFIG_ENV_SIZE) > mmc->capacity) ||
(tmp > UINT_MAX))
Lose the parentheses and test against 0xffffffffU
*env_addr = ESDHC_DEFAULT_ENVADDR;
else
*env_addr = tmp;
free(tmp_buf);
return 0;
}
*env_addr = code_offset + code_len;
free(tmp_buf);
-- 1.8.4
Regards
-- Pantelis

Hi Haijun,
On Dec 2, 2013, at 7:25 AM, Haijun Zhang wrote:
Card detection pin is ineffective on T4240QDS. This workaround force sdhc driver scan and initialize the card regardless of whether the card is inserted. if no card is in the slot, the error message "card is not inserted" will be prompted.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com
drivers/mmc/fsl_esdhc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index e3cd0c7..e330379 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -500,6 +500,10 @@ static int esdhc_getcd(struct mmc *mmc) struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000;
+/* Card detecting pin is not functional on T4240QDS */ +#if defined(CONFIG_T4240QDS)
- return 1;
+#endif
Ugh, I don't like that much.
How about a CONFIG_SYS_FSL_ESDHC_BROKEN_CD instead?
We need to do the same for the following fragment in esdhc_xfertyp()
#if defined(CONFIG_MX53) || defined(CONFIG_T4240QDS) if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) xfertyp |= XFERTYP_CMDTYP_ABORT; #endif
CONFIG_SYS_FSL_ESDHC_STOP_ABORT
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) udelay(1000);
-- 1.8.4
Regards
-- Pantelis
P.S. Add me to the CC list on the next version of the patch.

Hi all
On Sun, Dec 8, 2013 at 12:46 PM, Pantelis Antoniou pantelis.antoniou@gmail.com wrote:
Hi Haijun,
On Dec 2, 2013, at 7:25 AM, Haijun Zhang wrote:
Card detection pin is ineffective on T4240QDS. This workaround force sdhc driver scan and initialize the card regardless of whether the card is inserted. if no card is in the slot, the error message "card is not inserted" will be prompted.
Signed-off-by: Haijun Zhang Haijun.Zhang@freescale.com
drivers/mmc/fsl_esdhc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index e3cd0c7..e330379 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -500,6 +500,10 @@ static int esdhc_getcd(struct mmc *mmc) struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; int timeout = 1000;
+/* Card detecting pin is not functional on T4240QDS */ +#if defined(CONFIG_T4240QDS)
return 1;
+#endif
Ugh, I don't like that much.
How about a CONFIG_SYS_FSL_ESDHC_BROKEN_CD instead?
I suggest to don't use any define but flags.
Michael
We need to do the same for the following fragment in esdhc_xfertyp()
#if defined(CONFIG_MX53) || defined(CONFIG_T4240QDS) if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) xfertyp |= XFERTYP_CMDTYP_ABORT; #endif
CONFIG_SYS_FSL_ESDHC_STOP_ABORT
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) udelay(1000);
-- 1.8.4
Regards
-- Pantelis
P.S. Add me to the CC list on the next version of the patch. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
participants (3)
-
Haijun Zhang
-
Michael Trimarchi
-
Pantelis Antoniou