struct arch_global_data {
#if defined(CONFIG_FSL_ESDHC)
u32 sdhc_clk;
+#if defined(CONFIG_FSL_ESDHC_ADAPTER_IDENT)
+ u8 sdhc_adapter;
+#endif
#endif
#if defined(CONFIG_8xx)
unsigned long brg_clk;
qixis_write_i2c(offsetof(struct qixis, reg), value)
#endif
+/* Use for SDHC adapter card type identification and operation */
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+#define QIXIS_SDID_MASK 0x07
+#define QIXIS_ESDHC_ADAPTER_TYPE_EMMC45 0x1 /* eMMC Card Rev4.5 */
+#define QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY 0x2 /* SD/MMC Legacy Card */
+#define QIXIS_ESDHC_ADAPTER_TYPE_EMMC44 0x3 /* eMMC Card Rev4.4 */
+#define QIXIS_ESDHC_ADAPTER_TYPE_RSV 0x4 /* Reserved */
+#define QIXIS_ESDHC_ADAPTER_TYPE_MMC 0x5 /* MMC Card */
+#define QIXIS_ESDHC_ADAPTER_TYPE_SD 0x6 /* SD Card Rev2.0 3.0 */
+#define QIXIS_ESDHC_NO_ADAPTER 0x7 /* No Card is Present*/
+#define QIXIS_SDCLKIN 0x08
+#define QIXIS_SDCLKOUT 0x02
+#endif
+
#endif
-CONFIG_SYS_FSL_ESDHC_LE means ESDHC IP is in little-endian mode.
-CONFIG_SYS_FSL_ESDHC_BE means ESDHC IP is in big-endian mode.
-CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT forces to run at 1.8V.
+Freescale esdhc-specific options
-Accessing ESDHC registers can be determined by ESDHC IP's endian
-mode or processor's endian mode.
+ - CONFIG_FSL_ESDHC_ADAPTER_IDENT
+ Support Freescale adapter card type identification. This is implemented by
+ operating Qixis FPGA relevant registers. The STAT_PRES1 register has SDHC
+ Card ID[0:2] bits showing the type of card installed in the SDHC Adapter Slot.
+
+ SDHC Card ID[0:2] Adapter Card Type
+ 0b000 reserved
+ 0b001 eMMC Card Rev4.5
+ 0b010 SD/MMC Legacy Card
+ 0b011 eMMC Card Rev4.4
+ 0b100 reserved
+ 0b101 MMC Card
+ 0b110 SD Card Rev2.0/3.0
+ 0b111 No card is present
+ - CONFIG_SYS_FSL_ESDHC_LE
+ ESDHC IP is in little-endian mode. Accessing ESDHC registers can be
+ determined by ESDHC IP's endian mode or processor's endian mode.
+ - CONFIG_SYS_FSL_ESDHC_BE
+ ESDHC IP is in big-endian mode. Accessing ESDHC registers can be determined
+ by ESDHC IP's endian mode or processor's endian mode.
+
+ - CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT forces to run at 1.8V.
return fsl_esdhc_initialize(bis, cfg);
}
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+void mmc_adapter_card_type_ident(void)
+{
+ u8 card_id;
+ u8 value;
+
+ card_id = QIXIS_READ(present) & QIXIS_SDID_MASK;
+ gd->arch.sdhc_adapter = card_id;
+
+ switch (card_id) {
+ case QIXIS_ESDHC_ADAPTER_TYPE_EMMC45:
+ break;
+ case QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY:
+ break;
+ case QIXIS_ESDHC_ADAPTER_TYPE_EMMC44:
+ value = QIXIS_READ(brdcfg[5]);
+ value |= (QIXIS_SDCLKIN | QIXIS_SDCLKOUT);
+ QIXIS_WRITE(brdcfg[5], value);
+ break;
+ case QIXIS_ESDHC_ADAPTER_TYPE_RSV:
+ break;
+ case QIXIS_ESDHC_ADAPTER_TYPE_MMC:
+ break;
+ case QIXIS_ESDHC_ADAPTER_TYPE_SD:
+ break;
+ case QIXIS_ESDHC_NO_ADAPTER:
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
#ifdef CONFIG_OF_LIBFDT
void fdt_fixup_esdhc(void *blob, bd_t *bd)
{
do_fixup_by_compat_u32(blob, compat, "clock-frequency",
gd->arch.sdhc_clk, 1);
-
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+ do_fixup_by_compat_u32(blob, compat, "adapter-type",
+ (u32)(gd->arch.sdhc_adapter), 1);
+#endif
do_fixup_by_compat(blob, compat, "status", "okay",
4 + 1, 1);
}
if (mmc->has_init)
return 0;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+ mmc_adapter_card_type_ident();
+#endif
board_mmc_power_init();
/* made sure it's not NULL earlier */
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+ mmc_set_preinit(m, 1);
+#endif
if (m->preinit)
mmc_start_init(m);
}
struct mmc_data *data);
extern int mmc_send_status(struct mmc *mmc, int timeout);
extern int mmc_set_blocklen(struct mmc *mmc, int len);
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+void mmc_adapter_card_type_ident(void);
+#endif
#ifndef CONFIG_SPL_BUILD
/* needed for the mmc_cfg definition */
#include <mmc.h>
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+#include "../board/freescale/common/qixis.h"
+#endif
+
/* FSL eSDHC-specific constants */
#define SYSCTL 0x0002e02c
#define SYSCTL_INITA 0x08000000