
I didn't see HS400 working on my IMX7d, even thought it appears it should be supported.
The problem appears to be when this bit of code in fsl_esdhc.c, which dates to a patch "mmc: fsl_esdhc: support SDR104 and HS200":
static struct esdhc_soc_data usdhc_imx7d_data = { .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 | ESDHC_FLAG_HS400, .caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz | MMC_MODE_HS_52MHz | MMC_MODE_HS, };
Notice that MMC_MODE_HS400 isn't in the caps list. Once I add that uboot will attempt HS400 and it appears to work correctly.
I think maybe this patch should have added this to the caps?
Alternatively, there is a property that can be added to the device tree, mmc-hs400-1_8v, that will add this cap. But the code to parse those dt properties, mmc_of_parse(), isn't used by the fsl_esdhc driver, which has its own parsing code that doesn't know about mmc- hs400-1_8v.
So maybe fsl-esdhc should use mmc_of_parse() and the appropriate iMX DTs should add those properties?
I think the DT method might be better, since it would allow the DT to not list a mode that doesn't work due to the the board. I.e., the iMX host supports the mode, the eMMC supports the mode, but the board layout doesn't have traces that can support it. Too long, not matched well enough, etc. It doesn't seem like there's an nice way to remove a mode otherwise.