aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Huang <d-huang@ti.com>2017-07-18 05:01:51 -0500
committerDavid Huang <d-huang@ti.com>2017-07-18 05:01:51 -0500
commitabb109459b420c512fbd40f222c2f4688efcc3c5 (patch)
tree9abe78b59d62d63b380279c24dd6300eb4c44bef
parent7bd3f32c9c9e81da119c040bbfa857363e62ff51 (diff)
parenta979feec846a1dfffdfc2252c4a7c1a4e413dca9 (diff)
downloadjacinto6evm-abb109459b420c512fbd40f222c2f4688efcc3c5.tar.gz
Merge branch 'ti-u-boot-2016.05' of git://git.ti.com/ti-u-boot/ti-u-boot into p-ti-u-boot-2016.05
Auto Merge of: TI-Feature: 2016.05 TI-Tree: git://git.ti.com/ti-u-boot/ti-u-boot.git TI-Branch: ti-u-boot-2016.05 * 'ti-u-boot-2016.05' of git://git.ti.com/ti-u-boot/ti-u-boot: arm: omap: enable high speed mode support in SPL for the eMMC on AM572 and AM571 arm: omap: enable high speed mode support in SPL for the eMMC on DRA7x and DRA72. drivers: omap_hsmmc: Add debug information about the selected timing drivers: omap_hsmmc: If DM_MMC is not used, get the iodelays and the pinmux from the platform code mmc: omap_hsmmc: support for HS200 and DDR52 modes without DM_MMC mmc: omap_hsmmc: re-arrange code layout. mmc: omap_hsmmc: Configure PBIAS only for MMC1 mmc: omap_hsmmc: Enable ADMA support even if DM_MMC is not used omap: Update the base address of the MMC controllers drivers: mmc: fall back to lower performance modes if HS200 or DDR52 fail during the initialization Signed-off-by: David Huang <d-huang@ti.com>
-rw-r--r--arch/arm/include/asm/arch-am33xx/mmc_host_def.h4
-rw-r--r--arch/arm/include/asm/arch-omap4/mmc_host_def.h6
-rw-r--r--arch/arm/include/asm/arch-omap5/mmc_host_def.h6
-rw-r--r--arch/arm/include/asm/arch-omap5/sys_proto.h7
-rw-r--r--arch/arm/include/asm/omap_mmc.h5
-rw-r--r--arch/arm/mach-keystone/include/mach/mmc_host_def.h4
-rw-r--r--board/ti/am57xx/board.c61
-rw-r--r--board/ti/am57xx/mux_data.h132
-rw-r--r--board/ti/dra7xx/evm.c74
-rw-r--r--board/ti/dra7xx/mux_data.h261
-rw-r--r--drivers/mmc/mmc.c50
-rw-r--r--drivers/mmc/omap_hsmmc.c361
-rw-r--r--include/mmc.h1
13 files changed, 802 insertions, 170 deletions
diff --git a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
index 724e252946..5a2ea8faef 100644
--- a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h
@@ -21,8 +21,8 @@
/*
* OMAP HSMMC register definitions
*/
-#define OMAP_HSMMC1_BASE 0x48060100
-#define OMAP_HSMMC2_BASE 0x481D8100
+#define OMAP_HSMMC1_BASE 0x48060000
+#define OMAP_HSMMC2_BASE 0x481D8000
#if defined(CONFIG_TI814X)
#undef MMC_CLOCK_REFERENCE
diff --git a/arch/arm/include/asm/arch-omap4/mmc_host_def.h b/arch/arm/include/asm/arch-omap4/mmc_host_def.h
index 9c8ccb6c83..d06779956f 100644
--- a/arch/arm/include/asm/arch-omap4/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-omap4/mmc_host_def.h
@@ -31,8 +31,8 @@
* OMAP HSMMC register definitions
*/
-#define OMAP_HSMMC1_BASE 0x4809C100
-#define OMAP_HSMMC2_BASE 0x480B4100
-#define OMAP_HSMMC3_BASE 0x480AD100
+#define OMAP_HSMMC1_BASE 0x4809C000
+#define OMAP_HSMMC2_BASE 0x480B4000
+#define OMAP_HSMMC3_BASE 0x480AD000
#endif /* MMC_HOST_DEF_H */
diff --git a/arch/arm/include/asm/arch-omap5/mmc_host_def.h b/arch/arm/include/asm/arch-omap5/mmc_host_def.h
index 9c8ccb6c83..d06779956f 100644
--- a/arch/arm/include/asm/arch-omap5/mmc_host_def.h
+++ b/arch/arm/include/asm/arch-omap5/mmc_host_def.h
@@ -31,8 +31,8 @@
* OMAP HSMMC register definitions
*/
-#define OMAP_HSMMC1_BASE 0x4809C100
-#define OMAP_HSMMC2_BASE 0x480B4100
-#define OMAP_HSMMC3_BASE 0x480AD100
+#define OMAP_HSMMC1_BASE 0x4809C000
+#define OMAP_HSMMC2_BASE 0x480B4000
+#define OMAP_HSMMC3_BASE 0x480AD000
#endif /* MMC_HOST_DEF_H */
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index c870a72980..fb563ee542 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -35,6 +35,13 @@ struct pad_conf_entry {
u32 val;
};
+struct omap_hsmmc_pinctrl_state {
+ struct pad_conf_entry *padconf;
+ int npads;
+ struct iodelay_cfg_entry *iodelay;
+ int niodelays;
+};
+
struct omap_sysinfo {
char *board_string;
};
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 767f8ec50a..406010bbbe 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -26,7 +26,7 @@
#define OMAP_MMC_H_
struct hsmmc {
-#ifdef CONFIG_DM_MMC
+#ifndef CONFIG_OMAP34XX
unsigned int hl_rev;
unsigned int hl_hwinfo;
unsigned int hl_sysconfig;
@@ -225,7 +225,8 @@ struct hsmmc {
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio);
-
int platform_fixup_disable_uhs_mode(void);
+struct omap_hsmmc_pinctrl_state *platform_fixup_get_pinctrl_by_mode
+ (struct hsmmc *base, const char *mode);
void vmmc_pbias_config(uint voltage);
#endif /* OMAP_MMC_H_ */
diff --git a/arch/arm/mach-keystone/include/mach/mmc_host_def.h b/arch/arm/mach-keystone/include/mach/mmc_host_def.h
index a5050ac0f1..b8eed7d29b 100644
--- a/arch/arm/mach-keystone/include/mach/mmc_host_def.h
+++ b/arch/arm/mach-keystone/include/mach/mmc_host_def.h
@@ -16,7 +16,7 @@
* OMAP HSMMC register definitions
*/
-#define OMAP_HSMMC1_BASE 0x23000100
-#define OMAP_HSMMC2_BASE 0x23100100
+#define OMAP_HSMMC1_BASE 0x23000000
+#define OMAP_HSMMC2_BASE 0x23100000
#endif /* K2G_MMC_HOST_DEF_H */
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index 9922047f8d..72c4312837 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -721,6 +721,67 @@ int board_mmc_init(bd_t *bis)
}
#endif
+#if defined(CONFIG_IODELAY_RECALIBRATION) && \
+ (defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DM_MMC))
+
+struct pinctrl_desc {
+ const char *name;
+ struct omap_hsmmc_pinctrl_state *pinctrl;
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc1[] = {
+ {"default", &hsmmc1_default},
+ {"hs", &hsmmc1_default},
+ {NULL}
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc2_am572[] = {
+ {"default", &hsmmc2_default_hs},
+ {"hs", &hsmmc2_default_hs},
+ {"ddr_1_8v", &hsmmc2_ddr_am572},
+ {NULL}
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc2_am571[] = {
+ {"default", &hsmmc2_default_hs},
+ {"hs", &hsmmc2_default_hs},
+ {"ddr_1_8v", &hsmmc2_ddr_am571},
+ {NULL}
+};
+
+struct omap_hsmmc_pinctrl_state *platform_fixup_get_pinctrl_by_mode
+ (struct hsmmc *base, const char *mode)
+{
+ struct pinctrl_desc *p = NULL;
+
+ switch ((uint32_t)base) {
+ case OMAP_HSMMC1_BASE:
+ p = pinctrl_descs_hsmmc1;
+ break;
+ case OMAP_HSMMC2_BASE:
+ if (is_dra72x())
+ p = pinctrl_descs_hsmmc2_am571;
+ else
+ p = pinctrl_descs_hsmmc2_am572;
+ break;
+ default:
+ break;
+ }
+
+ if (!p) {
+ printf("%s no pinctrl defined for MMC@%p\n", __func__,
+ base);
+ return NULL;
+ }
+ while (p->name) {
+ if (strcmp(mode, p->name) == 0)
+ return p->pinctrl;
+ p++;
+ }
+ return NULL;
+}
+#endif
+
#ifdef CONFIG_OMAP_HSMMC
int platform_fixup_disable_uhs_mode(void)
{
diff --git a/board/ti/am57xx/mux_data.h b/board/ti/am57xx/mux_data.h
index aff274c74f..3c99905dd2 100644
--- a/board/ti/am57xx/mux_data.h
+++ b/board/ti/am57xx/mux_data.h
@@ -985,4 +985,136 @@ const struct iodelay_cfg_entry iodelay_cfg_array_am571x_idk[] = {
};
#endif
+
+#if defined(CONFIG_IODELAY_RECALIBRATION) && \
+ (defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DM_MMC))
+
+static struct iodelay_cfg_entry mmc2_iodelay_ddr_am572[] = {
+ {0x18c, 270, 0 /* CFG_GPMC_A19_IN */},
+ {0x1a4, 0, 0 /* CFG_GPMC_A20_IN */},
+ {0x1b0, 170, 0 /* CFG_GPMC_A21_IN */},
+ {0x1bc, 758, 0 /* CFG_GPMC_A22_IN */},
+ {0x1c8, 0, 0 /* CFG_GPMC_A23_IN */},
+ {0x1d4, 81, 0 /* CFG_GPMC_A24_IN */},
+ {0x1e0, 286, 0 /* CFG_GPMC_A25_IN */},
+ {0x1ec, 0, 0 /* CFG_GPMC_A26_IN */},
+ {0x1f8, 123, 0 /* CFG_GPMC_A27_IN */},
+ {0x360, 346, 0 /* CFG_GPMC_CS1_IN */},
+ {0x190, 0, 0 /* CFG_GPMC_A19_OEN */},
+ {0x194, 55, 0 /* CFG_GPMC_A19_OUT */},
+ {0x1a8, 0, 0 /* CFG_GPMC_A20_OEN */},
+ {0x1ac, 422, 0 /* CFG_GPMC_A20_OUT */},
+ {0x1b4, 642, 0 /* CFG_GPMC_A21_OEN */},
+ {0x1b8, 0, 0 /* CFG_GPMC_A21_OUT */},
+ {0x1c0, 0, 0 /* CFG_GPMC_A22_OEN */},
+ {0x1c4, 128, 0 /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 0, 0 /* CFG_GPMC_A23_OUT */},
+ {0x1d8, 0, 0 /* CFG_GPMC_A24_OEN */},
+ {0x1dc, 395, 0 /* CFG_GPMC_A24_OUT */},
+ {0x1e4, 0, 0 /* CFG_GPMC_A25_OEN */},
+ {0x1e8, 0, 0 /* CFG_GPMC_A25_OUT */},
+ {0x1f0, 623, 0 /* CFG_GPMC_A26_OEN */},
+ {0x1f4, 0, 0 /* CFG_GPMC_A26_OUT */},
+ {0x1fc, 54, 0 /* CFG_GPMC_A27_OEN */},
+ {0x200, 0, 0 /* CFG_GPMC_A27_OUT */},
+ {0x364, 0, 0 /* CFG_GPMC_CS1_OEN */},
+ {0x368, 0, 0 /* CFG_GPMC_CS1_OUT */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_ddr_am571[] = {
+ {0x18c, 0, 0, /* CFG_GPMC_A19_IN */},
+ {0x1a4, 121, 0, /* CFG_GPMC_A20_IN */},
+ {0x1b0, 0, 0, /* CFG_GPMC_A21_IN */},
+ {0x1bc, 20, 0, /* CFG_GPMC_A22_IN */},
+ {0x1c8, 108, 0, /* CFG_GPMC_A23_IN */},
+ {0x1d4, 31, 0, /* CFG_GPMC_A24_IN */},
+ {0x1e0, 0, 0, /* CFG_GPMC_A25_IN */},
+ {0x1ec, 24, 0, /* CFG_GPMC_A26_IN */},
+ {0x1f8, 0, 0, /* CFG_GPMC_A27_IN */},
+ {0x360, 0, 0, /* CFG_GPMC_CS1_IN */},
+ {0x194, 152, 0, /* CFG_GPMC_A19_OUT */},
+ {0x1ac, 206, 0, /* CFG_GPMC_A20_OUT */},
+ {0x1b8, 78, 0, /* CFG_GPMC_A21_OUT */},
+ {0x1c4, 2, 0, /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 266, 0, /* CFG_GPMC_A23_OUT */},
+ {0x1dc, 0, 0, /* CFG_GPMC_A24_OUT */},
+ {0x1e8, 0, 0, /* CFG_GPMC_A25_OUT */},
+ {0x1f4, 43, 0, /* CFG_GPMC_A26_OUT */},
+ {0x200, 0, 0, /* CFG_GPMC_A27_OUT */},
+ {0x368, 0, 0, /* CFG_GPMC_CS1_OUT */},
+ {0x190, 0, 0, /* CFG_GPMC_A19_OEN */},
+ {0x1a8, 0, 0, /* CFG_GPMC_A20_OEN */},
+ {0x1b4, 0, 0, /* CFG_GPMC_A21_OEN */},
+ {0x1c0, 0, 0, /* CFG_GPMC_A22_OEN */},
+ {0x1d8, 0, 0, /* CFG_GPMC_A24_OEN */},
+ {0x1e4, 0, 0, /* CFG_GPMC_A25_OEN */},
+ {0x1f0, 0, 0, /* CFG_GPMC_A26_OEN */},
+ {0x1fc, 0, 0, /* CFG_GPMC_A27_OEN */},
+ {0x364, 0, 0, /* CFG_GPMC_CS1_OEN */},
+};
+
+static struct pad_conf_entry hsmmc1_default_padconf[] = {
+ {MMC1_CLK, (M0 | PIN_INPUT_PULLUP) /* mmc1_clk.clk */},
+ {MMC1_CMD, (M0 | PIN_INPUT_PULLUP) /* mmc1_cmd.cmd */},
+ {MMC1_DAT0, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat0.dat0 */},
+ {MMC1_DAT1, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat1.dat1 */},
+ {MMC1_DAT2, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat2.dat2 */},
+ {MMC1_DAT3, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat3.dat3 */},
+};
+
+static struct pad_conf_entry mmc2_pins_ddr[] = {
+ {GPMC_A23, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a23.mmc2_clk */},
+ {GPMC_CS1, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_cs1.mmc2_cmd */},
+ {GPMC_A24, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a24.mmc2_dat0 */},
+ {GPMC_A25, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a25.mmc2_dat1 */},
+ {GPMC_A26, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a26.mmc2_dat2 */},
+ {GPMC_A27, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a27.mmc2_dat3 */},
+ {GPMC_A19, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a19.mmc2_dat4 */},
+ {GPMC_A20, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a20.mmc2_dat5 */},
+ {GPMC_A21, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a21.mmc2_dat6 */},
+ {GPMC_A22, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a22.mmc2_dat7 */},
+};
+
+static struct pad_conf_entry mmc2_pins_default_hs[] = {
+ {GPMC_A23, (M1 | PIN_INPUT_PULLUP) /* g pmc_a23.mmc2_clk */},
+ {GPMC_CS1, (M1 | PIN_INPUT_PULLUP) /* gpmc_cs1.mmc2_cmd */},
+ {GPMC_A24, (M1 | PIN_INPUT_PULLUP) /* gpmc_a24.mmc2_dat0 */},
+ {GPMC_A25, (M1 | PIN_INPUT_PULLUP) /* gpmc_a25.mmc2_dat1 */},
+ {GPMC_A26, (M1 | PIN_INPUT_PULLUP) /* gpmc_a26.mmc2_dat2 */},
+ {GPMC_A27, (M1 | PIN_INPUT_PULLUP) /* gpmc_a27.mmc2_dat3 */},
+ {GPMC_A19, (M1 | PIN_INPUT_PULLUP) /* gpmc_a19.mmc2_dat4 */},
+ {GPMC_A20, (M1 | PIN_INPUT_PULLUP) /* gpmc_a20.mmc2_dat5 */},
+ {GPMC_A21, (M1 | PIN_INPUT_PULLUP) /* gpmc_a21.mmc2_dat6 */},
+ {GPMC_A22, (M1 | PIN_INPUT_PULLUP) /* gpmc_a22.mmc2_dat7 */},
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc1_default = {
+ .padconf = hsmmc1_default_padconf,
+ .npads = ARRAY_SIZE(hsmmc1_default_padconf),
+ .iodelay = NULL,
+ .niodelays = 0,
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_default_hs = {
+ .padconf = mmc2_pins_default_hs,
+ .npads = ARRAY_SIZE(mmc2_pins_default_hs),
+ .iodelay = NULL,
+ .niodelays = 0,
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_ddr_am572 = {
+ .padconf = mmc2_pins_ddr,
+ .npads = ARRAY_SIZE(mmc2_pins_ddr),
+ .iodelay = mmc2_iodelay_ddr_am572,
+ .niodelays = ARRAY_SIZE(mmc2_iodelay_ddr_am572),
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_ddr_am571 = {
+ .padconf = mmc2_pins_ddr,
+ .npads = ARRAY_SIZE(mmc2_pins_ddr),
+ .iodelay = mmc2_iodelay_ddr_am571,
+ .niodelays = ARRAY_SIZE(mmc2_iodelay_ddr_am571),
+};
+
+#endif
#endif /* _MUX_DATA_BEAGLE_X15_H_ */
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index d2e65b157c..8378488cb7 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -725,6 +725,80 @@ int board_mmc_init(bd_t *bis)
#endif
#ifdef CONFIG_OMAP_HSMMC
+#if defined(CONFIG_IODELAY_RECALIBRATION) && \
+ (defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DM_MMC))
+
+struct pinctrl_desc {
+ const char *name;
+ struct omap_hsmmc_pinctrl_state *pinctrl;
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc1[] = {
+ {"default", &hsmmc1_default},
+ {"hs", &hsmmc1_default},
+ {NULL}
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc2_rev20[] = {
+ {"default", &hsmmc2_default_hs},
+ {"hs", &hsmmc2_default_hs},
+ {"ddr_1_8v", &hsmmc2_ddr_1v8_rev20},
+ {"hs200_1_8v", &hsmmc2_hs200_1v8_rev20},
+ {NULL}
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc2_rev11[] = {
+ {"default", &hsmmc2_default_hs},
+ {"hs", &hsmmc2_default_hs},
+ {"ddr_1_8v", &hsmmc2_ddr_1v8_rev11},
+ {"hs200_1_8v", &hsmmc2_hs200_1v8_rev11},
+ {NULL}
+};
+
+static struct pinctrl_desc pinctrl_descs_hsmmc2_dra72x[] = {
+ {"default", &hsmmc2_default_hs},
+ {"hs", &hsmmc2_default_hs},
+ {"ddr_1_8v", &hsmmc2_ddr_1v8_dra72},
+ {"hs200_1_8v", &hsmmc2_hs200_1v8_dra72},
+ {NULL}
+};
+
+struct omap_hsmmc_pinctrl_state *platform_fixup_get_pinctrl_by_mode
+ (struct hsmmc *base, const char *mode)
+{
+ struct pinctrl_desc *p = NULL;
+
+ switch ((uint32_t)base) {
+ case OMAP_HSMMC1_BASE:
+ p = pinctrl_descs_hsmmc1;
+ break;
+ case OMAP_HSMMC2_BASE:
+ if ((omap_revision() == DRA752_ES1_0) ||
+ (omap_revision() == DRA752_ES1_1))
+ p = pinctrl_descs_hsmmc2_rev11;
+ else if (is_dra72x())
+ p = pinctrl_descs_hsmmc2_dra72x;
+ else if (is_dra7xx())
+ p = pinctrl_descs_hsmmc2_rev20;
+ break;
+ default:
+ break;
+ }
+
+ if (!p) {
+ printf("%s no pinctrl defined for MMC@%p\n", __func__,
+ base);
+ return NULL;
+ }
+ while (p->name) {
+ if (strcmp(mode, p->name) == 0)
+ return p->pinctrl;
+ p++;
+ }
+ return NULL;
+}
+#endif
+
int platform_fixup_disable_uhs_mode(void)
{
return omap_revision() == DRA752_ES1_1;
diff --git a/board/ti/dra7xx/mux_data.h b/board/ti/dra7xx/mux_data.h
index 931d76d8eb..e70f8e6b8c 100644
--- a/board/ti/dra7xx/mux_data.h
+++ b/board/ti/dra7xx/mux_data.h
@@ -1079,4 +1079,265 @@ const struct iodelay_cfg_entry dra742_es2_0_iodelay_cfg_array[] = {
};
#endif
+
+#if defined(CONFIG_IODELAY_RECALIBRATION) && \
+ (defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DM_MMC)) && \
+ defined(CONFIG_OMAP_HSMMC)
+
+static struct pad_conf_entry hsmmc1_default_padconf[] = {
+ {MMC1_CLK, (M0 | PIN_INPUT_PULLUP) /* mmc1_clk.clk */},
+ {MMC1_CMD, (M0 | PIN_INPUT_PULLUP) /* mmc1_cmd.cmd */},
+ {MMC1_DAT0, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat0.dat0 */},
+ {MMC1_DAT1, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat1.dat1 */},
+ {MMC1_DAT2, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat2.dat2 */},
+ {MMC1_DAT3, (M0 | PIN_INPUT_PULLUP) /* mmc1_dat3.dat3 */},
+};
+
+static struct pad_conf_entry mmc2_pins_default_hs[] = {
+ {GPMC_A23, (M1 | PIN_INPUT_PULLUP) /* g pmc_a23.mmc2_clk */},
+ {GPMC_CS1, (M1 | PIN_INPUT_PULLUP) /* gpmc_cs1.mmc2_cmd */},
+ {GPMC_A24, (M1 | PIN_INPUT_PULLUP) /* gpmc_a24.mmc2_dat0 */},
+ {GPMC_A25, (M1 | PIN_INPUT_PULLUP) /* gpmc_a25.mmc2_dat1 */},
+ {GPMC_A26, (M1 | PIN_INPUT_PULLUP) /* gpmc_a26.mmc2_dat2 */},
+ {GPMC_A27, (M1 | PIN_INPUT_PULLUP) /* gpmc_a27.mmc2_dat3 */},
+ {GPMC_A19, (M1 | PIN_INPUT_PULLUP) /* gpmc_a19.mmc2_dat4 */},
+ {GPMC_A20, (M1 | PIN_INPUT_PULLUP) /* gpmc_a20.mmc2_dat5 */},
+ {GPMC_A21, (M1 | PIN_INPUT_PULLUP) /* gpmc_a21.mmc2_dat6 */},
+ {GPMC_A22, (M1 | PIN_INPUT_PULLUP) /* gpmc_a22.mmc2_dat7 */},
+};
+
+static struct pad_conf_entry mmc2_pins_ddr_hs200_1_8v[] = {
+ {GPMC_A23, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a23.mmc2_clk */},
+ {GPMC_CS1, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_cs1.mmc2_cmd */},
+ {GPMC_A24, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a24.mmc2_dat0 */},
+ {GPMC_A25, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a25.mmc2_dat1 */},
+ {GPMC_A26, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a26.mmc2_dat2 */},
+ {GPMC_A27, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a27.mmc2_dat3 */},
+ {GPMC_A19, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a19.mmc2_dat4 */},
+ {GPMC_A20, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a20.mmc2_dat5 */},
+ {GPMC_A21, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a21.mmc2_dat6 */},
+ {GPMC_A22, (M1 | PIN_INPUT_PULLUP | MANUAL_MODE) /* gpmc_a22.mmc2_dat7 */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_hs200_1_8v_rev11_conf[] = {
+ {0x190, 621, 600 /* CFG_GPMC_A19_OEN */},
+ {0x194, 300, 0 /* CFG_GPMC_A19_OUT */},
+ {0x1a8, 739, 600 /* CFG_GPMC_A20_OEN */},
+ {0x1ac, 240, 0 /* CFG_GPMC_A20_OUT */},
+ {0x1b4, 812, 600 /* CFG_GPMC_A21_OEN */},
+ {0x1b8, 240, 0 /* CFG_GPMC_A21_OUT */},
+ {0x1c0, 954, 600 /* CFG_GPMC_A22_OEN */},
+ {0x1c4, 60, 0 /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 1340, 420 /* CFG_GPMC_A23_OUT */},
+ {0x1d8, 935, 600 /* CFG_GPMC_A24_OEN */},
+ {0x1dc, 0, 0 /* CFG_GPMC_A24_OUT */},
+ {0x1e4, 525, 600 /* CFG_GPMC_A25_OEN */},
+ {0x1e8, 120, 0 /* CFG_GPMC_A25_OUT */},
+ {0x1f0, 767, 600 /* CFG_GPMC_A26_OEN */},
+ {0x1f4, 225, 0 /* CFG_GPMC_A26_OUT */},
+ {0x1fc, 565, 600 /* CFG_GPMC_A27_OEN */},
+ {0x200, 60, 0 /* CFG_GPMC_A27_OUT */},
+ {0x364, 969, 600 /* CFG_GPMC_CS1_OEN */},
+ {0x368, 180, 0 /* CFG_GPMC_CS1_OUT */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_hs200_1_8v_rev20_conf[] = {
+ {0x190, 274, 0 /* CFG_GPMC_A19_OEN */},
+ {0x194, 162, 0 /* CFG_GPMC_A19_OUT */},
+ {0x1a8, 401, 0 /* CFG_GPMC_A20_OEN */},
+ {0x1ac, 73, 0 /* CFG_GPMC_A20_OUT */},
+ {0x1b4, 465, 0 /* CFG_GPMC_A21_OEN */},
+ {0x1b8, 115, 0 /* CFG_GPMC_A21_OUT */},
+ {0x1c0, 633, 0 /* CFG_GPMC_A22_OEN */},
+ {0x1c4, 47, 0 /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 935, 280 /* CFG_GPMC_A23_OUT */},
+ {0x1d8, 621, 0 /* CFG_GPMC_A24_OEN */},
+ {0x1dc, 0, 0 /* CFG_GPMC_A24_OUT */},
+ {0x1e4, 183, 0 /* CFG_GPMC_A25_OEN */},
+ {0x1e8, 0, 0 /* CFG_GPMC_A25_OUT */},
+ {0x1f0, 467, 0 /* CFG_GPMC_A26_OEN */},
+ {0x1f4, 0, 0 /* CFG_GPMC_A26_OUT */},
+ {0x1fc, 262, 0 /* CFG_GPMC_A27_OEN */},
+ {0x200, 46, 0 /* CFG_GPMC_A27_OUT */},
+ {0x364, 684, 0 /* CFG_GPMC_CS1_OEN */},
+ {0x368, 76, 0 /* CFG_GPMC_CS1_OUT */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_ddr_1_8v_rev11_conf[] = {
+ {0x18c, 0, 0 /* CFG_GPMC_A19_IN */},
+ {0x1a4, 274, 240 /* CFG_GPMC_A20_IN */},
+ {0x1b0, 0, 60 /* CFG_GPMC_A21_IN */},
+ {0x1bc, 0, 60 /* CFG_GPMC_A22_IN */},
+ {0x1c8, 514, 360 /* CFG_GPMC_A23_IN */},
+ {0x1d4, 187, 120 /* CFG_GPMC_A24_IN */},
+ {0x1e0, 0, 0 /* CFG_GPMC_A25_IN */},
+ {0x1ec, 0, 60 /* CFG_GPMC_A26_IN */},
+ {0x1f8, 121, 60 /* CFG_GPMC_A27_IN */},
+ {0x360, 0, 0 /* CFG_GPMC_CS1_IN */},
+ {0x190, 0, 0 /* CFG_GPMC_A19_OEN */},
+ {0x194, 174, 0 /* CFG_GPMC_A19_OUT */},
+ {0x1a8, 0, 0 /* CFG_GPMC_A20_OEN */},
+ {0x1ac, 168, 0 /* CFG_GPMC_A20_OUT */},
+ {0x1b4, 0, 0 /* CFG_GPMC_A21_OEN */},
+ {0x1b8, 136, 0 /* CFG_GPMC_A21_OUT */},
+ {0x1c0, 0, 0 /* CFG_GPMC_A22_OEN */},
+ {0x1c4, 0, 0 /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 879, 0 /* CFG_GPMC_A23_OUT */},
+ {0x1d8, 0, 0 /* CFG_GPMC_A24_OEN */},
+ {0x1dc, 0, 0 /* CFG_GPMC_A24_OUT */},
+ {0x1e4, 0, 0 /* CFG_GPMC_A25_OEN */},
+ {0x1e8, 34, 0 /* CFG_GPMC_A25_OUT */},
+ {0x1f0, 0, 0 /* CFG_GPMC_A26_OEN */},
+ {0x1f4, 120, 0 /* CFG_GPMC_A26_OUT */},
+ {0x1fc, 0, 0 /* CFG_GPMC_A27_OEN */},
+ {0x200, 0, 0 /* CFG_GPMC_A27_OUT */},
+ {0x364, 0, 0 /* CFG_GPMC_CS1_OEN */},
+ {0x368, 11, 0 /* CFG_GPMC_CS1_OUT */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_ddr_1_8v_rev20_conf[] = {
+ {0x18c, 270, 0 /* CFG_GPMC_A19_IN */},
+ {0x1a4, 0, 0 /* CFG_GPMC_A20_IN */},
+ {0x1b0, 170, 0 /* CFG_GPMC_A21_IN */},
+ {0x1bc, 758, 0 /* CFG_GPMC_A22_IN */},
+ {0x1c8, 0, 0 /* CFG_GPMC_A23_IN */},
+ {0x1d4, 81, 0 /* CFG_GPMC_A24_IN */},
+ {0x1e0, 286, 0 /* CFG_GPMC_A25_IN */},
+ {0x1ec, 0, 0 /* CFG_GPMC_A26_IN */},
+ {0x1f8, 123, 0 /* CFG_GPMC_A27_IN */},
+ {0x360, 346, 0 /* CFG_GPMC_CS1_IN */},
+ {0x190, 0, 0 /* CFG_GPMC_A19_OEN */},
+ {0x194, 55, 0 /* CFG_GPMC_A19_OUT */},
+ {0x1a8, 0, 0 /* CFG_GPMC_A20_OEN */},
+ {0x1ac, 422, 0 /* CFG_GPMC_A20_OUT */},
+ {0x1b4, 642, 0 /* CFG_GPMC_A21_OEN */},
+ {0x1b8, 0, 0 /* CFG_GPMC_A21_OUT */},
+ {0x1c0, 0, 0 /* CFG_GPMC_A22_OEN */},
+ {0x1c4, 128, 0 /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 0, 0 /* CFG_GPMC_A23_OUT */},
+ {0x1d8, 0, 0 /* CFG_GPMC_A24_OEN */},
+ {0x1dc, 395, 0 /* CFG_GPMC_A24_OUT */},
+ {0x1e4, 0, 0 /* CFG_GPMC_A25_OEN */},
+ {0x1e8, 0, 0 /* CFG_GPMC_A25_OUT */},
+ {0x1f0, 623, 0 /* CFG_GPMC_A26_OEN */},
+ {0x1f4, 0, 0 /* CFG_GPMC_A26_OUT */},
+ {0x1fc, 54, 0 /* CFG_GPMC_A27_OEN */},
+ {0x200, 0, 0 /* CFG_GPMC_A27_OUT */},
+ {0x364, 0, 0 /* CFG_GPMC_CS1_OEN */},
+ {0x368, 0, 0 /* CFG_GPMC_CS1_OUT */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_ddr_1_8v_dra72_conf[] = {
+ {0x18c, 0, 0, /* CFG_GPMC_A19_IN */},
+ {0x1a4, 121, 0, /* CFG_GPMC_A20_IN */},
+ {0x1b0, 0, 0, /* CFG_GPMC_A21_IN */},
+ {0x1bc, 20, 0, /* CFG_GPMC_A22_IN */},
+ {0x1c8, 108, 0, /* CFG_GPMC_A23_IN */},
+ {0x1d4, 31, 0, /* CFG_GPMC_A24_IN */},
+ {0x1e0, 0, 0, /* CFG_GPMC_A25_IN */},
+ {0x1ec, 24, 0, /* CFG_GPMC_A26_IN */},
+ {0x1f8, 0, 0, /* CFG_GPMC_A27_IN */},
+ {0x360, 0, 0, /* CFG_GPMC_CS1_IN */},
+ {0x194, 152, 0, /* CFG_GPMC_A19_OUT */},
+ {0x1ac, 206, 0, /* CFG_GPMC_A20_OUT */},
+ {0x1b8, 78, 0, /* CFG_GPMC_A21_OUT */},
+ {0x1c4, 2, 0, /* CFG_GPMC_A22_OUT */},
+ {0x1d0, 266, 0, /* CFG_GPMC_A23_OUT */},
+ {0x1dc, 0, 0, /* CFG_GPMC_A24_OUT */},
+ {0x1e8, 0, 0, /* CFG_GPMC_A25_OUT */},
+ {0x1f4, 43, 0, /* CFG_GPMC_A26_OUT */},
+ {0x200, 0, 0, /* CFG_GPMC_A27_OUT */},
+ {0x368, 0, 0, /* CFG_GPMC_CS1_OUT */},
+ {0x190, 0, 0, /* CFG_GPMC_A19_OEN */},
+ {0x1a8, 0, 0, /* CFG_GPMC_A20_OEN */},
+ {0x1b4, 0, 0, /* CFG_GPMC_A21_OEN */},
+ {0x1c0, 0, 0, /* CFG_GPMC_A22_OEN */},
+ {0x1d8, 0, 0, /* CFG_GPMC_A24_OEN */},
+ {0x1e4, 0, 0, /* CFG_GPMC_A25_OEN */},
+ {0x1f0, 0, 0, /* CFG_GPMC_A26_OEN */},
+ {0x1fc, 0, 0, /* CFG_GPMC_A27_OEN */},
+ {0x364, 0, 0, /* CFG_GPMC_CS1_OEN */},
+};
+
+static struct iodelay_cfg_entry mmc2_iodelay_hs200_1_8v_dra72_conf[] = {
+ {0x194, 150 , 95 /* CFG_GPMC_A19_OUT */},
+ {0x1AC, 250 , 0 /* CFG_GPMC_A20_OUT */},
+ {0x1B8, 125 , 0 /* CFG_GPMC_A21_OUT */},
+ {0x1C4, 100 , 0 /* CFG_GPMC_A22_OUT */},
+ {0x1D0, 870 , 415 /* CFG_GPMC_A23_OUT */},
+ {0x1DC, 30 , 0 /* CFG_GPMC_A24_OUT */},
+ {0x1E8, 200 , 0 /* CFG_GPMC_A25_OUT */},
+ {0x1F4, 200 , 0 /* CFG_GPMC_A26_OUT */},
+ {0x200, 0 , 0 /* CFG_GPMC_A27_OUT */},
+ {0x368, 240 , 0 /* CFG_GPMC_CS1_OUT */},
+ {0x190, 695 , 0 /* CFG_GPMC_A19_OEN */},
+ {0x1A8, 924 , 0 /* CFG_GPMC_A20_OEN */},
+ {0x1B4, 719 , 0 /* CFG_GPMC_A21_OEN */},
+ {0x1C0, 824 , 0 /* CFG_GPMC_A22_OEN */},
+ {0x1D8, 877 , 0 /* CFG_GPMC_A24_OEN */},
+ {0x1E4, 446 , 0 /* CFG_GPMC_A25_OEN */},
+ {0x1F0, 847 , 0 /* CFG_GPMC_A26_OEN */},
+ {0x1FC, 586 , 0 /* CFG_GPMC_A27_OEN */},
+ {0x364, 1039 , 0 /* CFG_GPMC_CS1_OEN */},
+};
+
+#define dimof(t) (sizeof(t) / sizeof(t[0]))
+static struct omap_hsmmc_pinctrl_state hsmmc1_default = {
+ .padconf = hsmmc1_default_padconf,
+ .npads = dimof(hsmmc1_default_padconf),
+ .iodelay = NULL,
+ .niodelays = 0,
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_default_hs = {
+ .padconf = mmc2_pins_default_hs,
+ .npads = dimof(mmc2_pins_default_hs),
+ .iodelay = NULL,
+ .niodelays = 0,
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_ddr_1v8_rev11 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_ddr_1_8v_rev11_conf,
+ .niodelays = dimof(mmc2_iodelay_ddr_1_8v_rev11_conf),
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_ddr_1v8_rev20 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_ddr_1_8v_rev20_conf,
+ .niodelays = dimof(mmc2_iodelay_ddr_1_8v_rev20_conf),
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_hs200_1v8_rev11 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_hs200_1_8v_rev11_conf,
+ .niodelays = dimof(mmc2_iodelay_hs200_1_8v_rev11_conf),
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_hs200_1v8_rev20 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_hs200_1_8v_rev20_conf,
+ .niodelays = dimof(mmc2_iodelay_hs200_1_8v_rev20_conf),
+};
+
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_ddr_1v8_dra72 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_ddr_1_8v_dra72_conf,
+ .niodelays = dimof(mmc2_iodelay_ddr_1_8v_dra72_conf),
+};
+
+static struct omap_hsmmc_pinctrl_state hsmmc2_hs200_1v8_dra72 = {
+ .padconf = mmc2_pins_ddr_hs200_1_8v,
+ .npads = dimof(mmc2_pins_ddr_hs200_1_8v),
+ .iodelay = mmc2_iodelay_hs200_1_8v_dra72_conf,
+ .niodelays = dimof(mmc2_iodelay_hs200_1_8v_dra72_conf),
+};
+#endif
+
#endif /* _MUX_DATA_DRA7XX_H_ */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0670b16a2e..82a023190b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -386,7 +386,7 @@ static int mmc_go_idle(struct mmc *mmc)
static int mmc_host_uhs(struct mmc *mmc)
{
- return mmc->cfg->host_caps &
+ return mmc->host_ok_caps &
(MMC_MODE_UHS_SDR12 | MMC_MODE_UHS_SDR25 |
MMC_MODE_UHS_SDR50 | MMC_MODE_UHS_SDR104 |
MMC_MODE_UHS_DDR50);
@@ -663,7 +663,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
static void mmc_select_card_type(struct mmc *mmc, char card_type)
{
- u32 caps = mmc->cfg->host_caps;
+ u32 caps = mmc->host_ok_caps;
uint hs_max_dtr = mmc->tran_speed;
if (caps & MMC_MODE_HS &&
@@ -1094,7 +1094,7 @@ static int mmc_app_set_bus_width(struct mmc *mmc, int width)
static void sd_update_bus_speed_mode(struct mmc *mmc)
{
- u32 caps = mmc->cfg->host_caps;
+ u32 caps = mmc->host_ok_caps;
/*
* If the host doesn't support any of the UHS-I modes, fallback on
* default speed.
@@ -1238,8 +1238,8 @@ static int mmc_sd_switch_hs(struct mmc *mmc)
* This can avoid furthur problem when the card runs in different
* mode between the host.
*/
- if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
- (mmc->cfg->host_caps & MMC_MODE_HS)))
+ if (!((mmc->host_ok_caps & MMC_MODE_HS_52MHz) &&
+ (mmc->host_ok_caps & MMC_MODE_HS)))
return -EINVAL;
if (!(mmc->card_caps & MMC_MODE_HS))
@@ -1350,7 +1350,7 @@ retry_scr:
mmc->card_caps |= MMC_MODE_HS;
/* Restrict card's capabilities by what the host can do */
- mmc->card_caps &= mmc->cfg->host_caps;
+ mmc->card_caps &= mmc->host_ok_caps;
if (mmc->ocr & OCR_S18R) {
mmc_sd_init_uhs_card(mmc);
@@ -1513,16 +1513,15 @@ static int mmc_select_bus_width(struct mmc *mmc)
MMC_BUS_WIDTH_8,
MMC_BUS_WIDTH_4,
};
- const struct mmc_config *cfg = mmc->cfg;
ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
unsigned idx = 0, bus_width = 0;
int err = 0;
- if (!(cfg->host_caps & (MMC_MODE_8BIT | MMC_MODE_4BIT)))
+ if (!(mmc->host_ok_caps & (MMC_MODE_8BIT | MMC_MODE_4BIT)))
return 0;
- idx = (cfg->host_caps & MMC_MODE_8BIT) ? 0 : 1;
+ idx = (mmc->host_ok_caps & MMC_MODE_8BIT) ? 0 : 1;
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
@@ -1887,16 +1886,22 @@ static int mmc_startup(struct mmc *mmc)
if (mmc->timing == MMC_TIMING_MMC_HS200) {
err = mmc->cfg->ops->execute_tuning(mmc,
MMC_SEND_TUNING_BLOCK_HS200);
- if (err)
- return err;
+ if (err) {
+ printf("Tuning failed, dropping HS200 mode.\n");
+ mmc->host_ok_caps &= ~MMC_MODE_HS200;
+ return -EAGAIN;
+ }
} else if (mmc->timing == MMC_TIMING_MMC_HS) {
err = mmc_select_bus_width(mmc);
if (err)
return err;
err = mmc_select_hs_ddr(mmc);
- if (err)
- return err;
+ if (err) {
+ printf("dropping DDR52 mode.\n");
+ mmc->host_ok_caps &= ~MMC_MODE_DDR_52MHz;
+ return -EAGAIN;
+ }
}
}
@@ -2161,19 +2166,26 @@ static int mmc_complete_init(struct mmc *mmc)
int mmc_init(struct mmc *mmc)
{
int err = 0;
- unsigned start;
+ int retries = 0;
+ __maybe_unused unsigned start;
if (mmc->has_init)
return 0;
+ mmc->host_ok_caps = mmc->cfg->host_caps;
start = get_timer(0);
- if (!mmc->init_in_progress)
- err = mmc_start_init(mmc);
+ do {
+ retries++;
+ if (!mmc->init_in_progress)
+ err = mmc_start_init(mmc);
- if (!err)
- err = mmc_complete_init(mmc);
- debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
+ if (!err)
+ err = mmc_complete_init(mmc);
+ } while (err == -EAGAIN);
+
+ debug("%s: %d, time %lu (retries %d)\n", __func__, err,
+ get_timer(start), retries - 1);
return err;
}
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 4d4962ac8a..0162be44ad 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -59,13 +59,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define SYSCTL_SRC (1 << 25)
#define SYSCTL_SRD (1 << 26)
-#ifdef CONFIG_IODELAY_RECALIBRATION
-struct omap_hsmmc_pinctrl_state {
- struct pad_conf_entry *padconf;
- int npads;
- struct iodelay_cfg_entry *iodelay;
- int niodelays;
-};
+#ifndef CONFIG_OMAP34XX
+#define SUPPORTS_ADMA
#endif
struct omap_hsmmc_data {
@@ -83,17 +78,22 @@ struct omap_hsmmc_data {
int wp_gpio;
#endif
#endif
-#ifdef CONFIG_DM_MMC
- uint iov;
- uint timing;
+
+#ifdef SUPPORTS_ADMA
u8 controller_flags;
struct omap_hsmmc_adma_desc *adma_desc_table;
uint desc_slot;
- int node;
+#endif
+ ushort last_cmd;
+ uint iov;
+ uint timing;
char *version;
+
+#ifdef CONFIG_DM_MMC
+ int node;
struct udevice *vmmc_supply;
struct udevice *vmmc_aux_supply;
- ushort last_cmd;
+#endif
#ifdef CONFIG_IODELAY_RECALIBRATION
struct omap_hsmmc_pinctrl_state *default_pinctrl_state;
struct omap_hsmmc_pinctrl_state *hs_pinctrl_state;
@@ -105,11 +105,10 @@ struct omap_hsmmc_data {
struct omap_hsmmc_pinctrl_state *sdr25_pinctrl_state;
struct omap_hsmmc_pinctrl_state *sdr12_pinctrl_state;
#endif
-#endif
uint signal_voltage;
};
-#ifdef CONFIG_DM_MMC
+#ifdef SUPPORTS_ADMA
struct omap_hsmmc_adma_desc {
u8 attr;
u8 reserved;
@@ -245,8 +244,51 @@ void mmc_init_stream(struct hsmmc *mmc_base)
writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
}
-#ifdef CONFIG_DM_MMC
#ifdef CONFIG_IODELAY_RECALIBRATION
+#ifdef DEBUG
+static inline void show_mmc_timing(struct mmc *mmc)
+{
+ const char *str;
+ switch (mmc->timing) {
+ case MMC_TIMING_MMC_HS200:
+ str = "HS200";
+ break;
+ case MMC_TIMING_UHS_SDR104:
+ str = "SDR104";
+ break;
+ case MMC_TIMING_UHS_DDR50:
+ str = "DDR50";
+ break;
+ case MMC_TIMING_UHS_SDR50:
+ str = "SDR50";
+ break;
+ case MMC_TIMING_UHS_SDR25:
+ str = "SDR25";
+ break;
+ case MMC_TIMING_UHS_SDR12:
+ str = "SDR12";
+ break;
+ case MMC_TIMING_SD_HS:
+ str = "HS(sd)";
+ break;
+ case MMC_TIMING_MMC_HS:
+ str = "HS(mmc)";
+ break;
+ case MMC_TIMING_MMC_DDR52:
+ str = "DDR52";
+ break;
+ default:
+ str = "std";
+ break;
+ }
+ printf("mmc %d mode %s\n", mmc->block_dev.devnum + 1, str);
+}
+#else
+static inline void show_mmc_timing(struct mmc *mmc)
+{
+}
+#endif
+
static void omap_hsmmc_set_timing(struct mmc *mmc)
{
u32 val;
@@ -317,9 +359,9 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
omap_hsmmc_start_clock(mmc_base);
priv->timing = mmc->timing;
+ show_mmc_timing(mmc);
}
#endif
-#endif
static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)
{
@@ -346,7 +388,6 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)
writel(val, &mmc_base->hctl);
}
-#if defined(CONFIG_DM_MMC)
static int omap_hsmmc_card_busy_low(struct mmc *mmc)
{
u32 val;
@@ -454,7 +495,6 @@ static int omap_hsmmc_set_io_regulator(struct mmc *mmc, int uV)
return 0;
}
#endif
-#endif
static int omap_hsmmc_set_signal_voltage(struct mmc *mmc)
{
@@ -480,7 +520,9 @@ static int omap_hsmmc_set_signal_voltage(struct mmc *mmc)
#if CONFIG_IS_ENABLED(DM_REGULATOR) && defined(CONFIG_DM_MMC)
return omap_hsmmc_set_io_regulator(mmc, 3000000);
#else
- vmmc_pbias_config(LDO_VOLT_3V0);
+ /* PBIAS config needed for MMC1 only */
+ if ((uint32_t) mmc_base == OMAP_HSMMC1_BASE)
+ vmmc_pbias_config(LDO_VOLT_3V0);
#endif
#endif
} else if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
@@ -498,7 +540,9 @@ static int omap_hsmmc_set_signal_voltage(struct mmc *mmc)
#if CONFIG_IS_ENABLED(DM_REGULATOR) && defined(CONFIG_DM_MMC)
return omap_hsmmc_set_io_regulator(mmc, 1800000);
#else
- vmmc_pbias_config(LDO_VOLT_1V8);
+ /* PBIAS config needed for MMC1 only */
+ if ((uint32_t) mmc_base == OMAP_HSMMC1_BASE)
+ vmmc_pbias_config(LDO_VOLT_1V8);
#endif
#endif
} else {
@@ -537,6 +581,7 @@ static void omap_hsmmc_set_capabilities(struct mmc *mmc)
writel(val, &mmc_base->capa);
}
+#endif
static void omap_hsmmc_disable_tuning(struct mmc *mmc)
{
@@ -670,7 +715,6 @@ static int omap_hsmmc_set_vdd(struct mmc *mmc, int enable)
return 0;
}
#endif
-#endif
static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd)
{
@@ -698,11 +742,9 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
unsigned int reg_val;
unsigned int dsor;
ulong start;
-#ifdef CONFIG_DM_MMC
struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
-#endif
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
+ mmc_base = priv->base_addr;
mmc_board_init(mmc);
writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
@@ -724,12 +766,15 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
}
}
-#ifdef CONFIG_DM_MMC
- omap_hsmmc_set_capabilities(mmc);
- omap_hsmmc_conf_bus_power(mmc, priv->iov);
+#ifdef SUPPORTS_ADMA
reg_val = readl(&mmc_base->hl_hwinfo);
if (reg_val & MADMA_EN)
priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
+#endif
+
+#ifdef CONFIG_DM_MMC
+ omap_hsmmc_set_capabilities(mmc);
+ omap_hsmmc_conf_bus_power(mmc, priv->iov);
#else
writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
@@ -814,7 +859,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
}
}
-#ifdef CONFIG_DM_MMC
+#ifdef SUPPORTS_ADMA
static int omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end)
{
struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
@@ -931,7 +976,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct hsmmc *mmc_base;
unsigned int flags, mmc_stat;
ulong start;
-#ifdef CONFIG_DM_MMC
+#ifdef SUPPORTS_ADMA
struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
priv->last_cmd = cmd->cmdidx;
#endif
@@ -1010,7 +1055,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
else
flags |= (DP_DATA | DDIR_WRITE);
-#ifdef CONFIG_DM_MMC
+#ifdef SUPPORTS_ADMA
if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) &&
cmd->cmdidx != MMC_SEND_TUNING_BLOCK_HS200) {
omap_hsmmc_prepare_data(mmc, data);
@@ -1055,7 +1100,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
}
-#ifdef CONFIG_DM_MMC
+#ifdef SUPPORTS_ADMA
if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) && data &&
cmd->cmdidx != MMC_SEND_TUNING_BLOCK_HS200) {
if (mmc_stat & IE_ADMAE) {
@@ -1290,7 +1335,7 @@ static int omap_hsmmc_set_ios(struct mmc *mmc)
else
omap_hsmmc_start_clock(mmc_base);
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_IODELAY_RECALIBRATION)
+#if defined(CONFIG_IODELAY_RECALIBRATION)
if (priv_data->timing != mmc->timing)
omap_hsmmc_set_timing(mmc);
#endif
@@ -1367,104 +1412,35 @@ static const struct mmc_ops omap_hsmmc_ops = {
.getcd = omap_hsmmc_getcd,
.getwp = omap_hsmmc_getwp,
#endif
-#ifdef CONFIG_DM_MMC
.execute_tuning = omap_hsmmc_execute_tuning,
.card_busy = omap_hsmmc_card_busy,
#if CONFIG_IS_ENABLED(DM_REGULATOR) && defined(CONFIG_DM_MMC)
.set_vdd = omap_hsmmc_set_vdd,
#endif
-#endif
};
-#ifndef CONFIG_DM_MMC
-int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
- int wp_gpio)
+#ifdef CONFIG_IODELAY_RECALIBRATION
+#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DM_MMC)
+__weak struct omap_hsmmc_pinctrl_state *platform_fixup_get_pinctrl_by_mode
+ (struct hsmmc *base, const char *mode)
{
- struct mmc *mmc;
- struct omap_hsmmc_data *priv_data;
- struct mmc_config *cfg;
- uint host_caps_val;
-
- priv_data = malloc(sizeof(*priv_data));
- if (priv_data == NULL)
- return -1;
-
- host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
-
- switch (dev_index) {
- case 0:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
- break;
-#ifdef OMAP_HSMMC2_BASE
- case 1:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
-#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
- defined(CONFIG_DRA7XX) || \
- defined(CONFIG_AM43XX) || defined(CONFIG_SOC_KEYSTONE)) && \
- defined(CONFIG_HSMMC2_8BIT)
- /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
- host_caps_val |= MMC_MODE_8BIT;
-#endif
- break;
-#endif
-#ifdef OMAP_HSMMC3_BASE
- case 2:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
-#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
- /* Enable 8-bit interface for eMMC on DRA7XX */
- host_caps_val |= MMC_MODE_8BIT;
-#endif
- break;
-#endif
- default:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
- return 1;
- }
-#ifdef OMAP_HSMMC_USE_GPIO
- /* on error gpio values are set to -1, which is what we want */
- priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
- priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
-#endif
-
- cfg = &priv_data->cfg;
-
- cfg->name = "OMAP SD/MMC";
- cfg->ops = &omap_hsmmc_ops;
-
- cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
- cfg->host_caps = host_caps_val & ~host_caps_mask;
-
- cfg->f_min = 400000;
-
- if (f_max != 0)
- cfg->f_max = f_max;
- else {
- if (cfg->host_caps & MMC_MODE_HS) {
- if (cfg->host_caps & MMC_MODE_HS_52MHz)
- cfg->f_max = 52000000;
- else
- cfg->f_max = 26000000;
- } else
- cfg->f_max = 20000000;
- }
-
- cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ static struct omap_hsmmc_pinctrl_state empty = {
+ .padconf = NULL,
+ .npads = 0,
+ .iodelay = NULL,
+ .niodelays = 0,
+ };
+ return &empty;
+}
-#if defined(CONFIG_OMAP34XX)
- /*
- * Silicon revs 2.1 and older do not support multiblock transfers.
- */
- if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
- cfg->b_max = 1;
-#endif
- mmc = mmc_create(cfg, priv_data);
- if (mmc == NULL)
- return -1;
+static struct omap_hsmmc_pinctrl_state *
+omap_hsmmc_get_pinctrl_by_mode(struct mmc *mmc, char *mode)
+{
+ struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
- return 0;
+ return platform_fixup_get_pinctrl_by_mode(priv->base_addr, mode);
}
#else
-#ifdef CONFIG_IODELAY_RECALIBRATION
static struct pad_conf_entry *
omap_hsmmc_get_pad_conf_entry(const fdt32_t *pinctrl, int count)
{
@@ -1708,6 +1684,7 @@ err_pinctrl_state:
kfree(pinctrl_state);
return 0;
}
+#endif
#define OMAP_HSMMC_SETUP_PINCTRL(capmask, mode) \
do { \
@@ -1761,6 +1738,133 @@ static int omap_hsmmc_get_pinctrl_state(struct mmc *mmc)
}
#endif
+__weak int platform_fixup_disable_uhs_mode(void)
+{
+ return 0;
+}
+
+static int omap_hsmmc_platform_fixup(struct mmc *mmc)
+{
+ struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
+ struct mmc_config *cfg = &priv->cfg;
+
+ priv->version = NULL;
+
+ if (platform_fixup_disable_uhs_mode()) {
+ priv->version = "rev11";
+ cfg->host_caps &= ~(MMC_MODE_HS200 | MMC_MODE_UHS_SDR104
+ | MMC_MODE_UHS_SDR50);
+ }
+
+ return 0;
+}
+
+#ifndef CONFIG_DM_MMC
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
+ int wp_gpio)
+{
+ struct mmc *mmc;
+ struct omap_hsmmc_data *priv_data;
+ struct mmc_config *cfg;
+ uint host_caps_val;
+#ifdef CONFIG_IODELAY_RECALIBRATION
+ int ret;
+#endif
+
+ priv_data = malloc(sizeof(*priv_data));
+ if (priv_data == NULL)
+ return -1;
+
+ host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
+#if defined(CONFIG_OMAP54XX)
+ host_caps_val |= MMC_MODE_DDR_52MHz | MMC_MODE_HS200;
+ priv_data->controller_flags |= OMAP_HSMMC_REQUIRE_IODELAY;
+#endif
+ switch (dev_index) {
+ case 0:
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+ break;
+#ifdef OMAP_HSMMC2_BASE
+ case 1:
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
+#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
+ defined(CONFIG_DRA7XX) || \
+ defined(CONFIG_AM43XX) || defined(CONFIG_SOC_KEYSTONE)) && \
+ defined(CONFIG_HSMMC2_8BIT)
+ /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
+ host_caps_val |= MMC_MODE_8BIT;
+#endif
+ break;
+#endif
+#ifdef OMAP_HSMMC3_BASE
+ case 2:
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
+#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
+ /* Enable 8-bit interface for eMMC on DRA7XX */
+ host_caps_val |= MMC_MODE_8BIT;
+#endif
+ break;
+#endif
+ default:
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+ return 1;
+ }
+#ifdef OMAP_HSMMC_USE_GPIO
+ /* on error gpio values are set to -1, which is what we want */
+ priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
+ priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
+#endif
+
+ cfg = &priv_data->cfg;
+
+ cfg->name = "OMAP SD/MMC";
+ cfg->ops = &omap_hsmmc_ops;
+
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->host_caps = host_caps_val & ~host_caps_mask;
+
+
+ cfg->f_min = 400000;
+
+ if (f_max != 0) {
+ cfg->f_max = f_max;
+ } else {
+ if (cfg->host_caps & MMC_MODE_HS200)
+ cfg->f_max = 200000000;
+ else if (cfg->host_caps & MMC_MODE_DDR_52MHz)
+ cfg->f_max = 52000000;
+ else if (cfg->host_caps & MMC_MODE_HS_52MHz)
+ cfg->f_max = 52000000;
+ else if (cfg->host_caps & MMC_MODE_HS)
+ cfg->f_max = 26000000;
+ else
+ cfg->f_max = 20000000;
+ }
+
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+#if defined(CONFIG_OMAP34XX)
+ /*
+ * Silicon revs 2.1 and older do not support multiblock transfers.
+ */
+ if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
+ cfg->b_max = 1;
+#endif
+ mmc = mmc_create(cfg, priv_data);
+ if (mmc == NULL)
+ return -1;
+
+ omap_hsmmc_platform_fixup(mmc);
+
+#ifdef CONFIG_IODELAY_RECALIBRATION
+ ret = omap_hsmmc_get_pinctrl_state(mmc);
+ if (ret < 0)
+ return ret;
+#endif
+
+ return 0;
+}
+#else
static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
{
struct omap_hsmmc_data *priv = dev_get_priv(dev);
@@ -1793,27 +1897,6 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
return 0;
}
-__weak int platform_fixup_disable_uhs_mode(void)
-{
- return 0;
-}
-
-static int omap_hsmmc_platform_fixup(struct mmc *mmc)
-{
- struct omap_hsmmc_data *priv = (struct omap_hsmmc_data *)mmc->priv;
- struct mmc_config *cfg = &priv->cfg;
-
- priv->version = NULL;
-
- if (platform_fixup_disable_uhs_mode()) {
- priv->version = "rev11";
- cfg->host_caps &= ~(MMC_MODE_HS200 | MMC_MODE_UHS_SDR104
- | MMC_MODE_UHS_SDR50);
- }
-
- return 0;
-}
-
static int omap_hsmmc_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
diff --git a/include/mmc.h b/include/mmc.h
index 8cdad5a800..c7aeb74b49 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -450,6 +450,7 @@ struct mmc {
struct blk_desc block_dev;
char op_cond_pending; /* 1 if we are waiting on an op_cond command */
char init_in_progress; /* 1 if we have done mmc_start_init() */
+ uint host_ok_caps; /* host caps that are not yet proven wrong */
char preinit; /* start init as early as possible */
int ddr_mode;
unsigned int sd_bus_speed;