diff options
author | David Huang <d-huang@ti.com> | 2017-07-18 05:01:51 -0500 |
---|---|---|
committer | David Huang <d-huang@ti.com> | 2017-07-18 05:01:51 -0500 |
commit | abb109459b420c512fbd40f222c2f4688efcc3c5 (patch) | |
tree | 9abe78b59d62d63b380279c24dd6300eb4c44bef | |
parent | 7bd3f32c9c9e81da119c040bbfa857363e62ff51 (diff) | |
parent | a979feec846a1dfffdfc2252c4a7c1a4e413dca9 (diff) | |
download | jacinto6evm-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.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap5/sys_proto.h | 7 | ||||
-rw-r--r-- | arch/arm/include/asm/omap_mmc.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 | ||||
-rw-r--r-- | board/ti/am57xx/board.c | 61 | ||||
-rw-r--r-- | board/ti/am57xx/mux_data.h | 132 | ||||
-rw-r--r-- | board/ti/dra7xx/evm.c | 74 | ||||
-rw-r--r-- | board/ti/dra7xx/mux_data.h | 261 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 50 | ||||
-rw-r--r-- | drivers/mmc/omap_hsmmc.c | 361 | ||||
-rw-r--r-- | include/mmc.h | 1 |
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 ∅ +} -#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; |