summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-10-02 21:13:54 +0200
committerHans de Goede <hdegoede@redhat.com>2014-10-24 09:35:38 +0200
commite79c7c881047ca99191cc79b6d83ec64b898cd9b (patch)
tree6b8a24be2edbbc0c0c4a6580a32459983060a8cb
parent2ccfac01fca3c58ee87db7bbe54c8243e3980d02 (diff)
downloadu-boot-imx-e79c7c881047ca99191cc79b6d83ec64b898cd9b.zip
u-boot-imx-e79c7c881047ca99191cc79b6d83ec64b898cd9b.tar.gz
u-boot-imx-e79c7c881047ca99191cc79b6d83ec64b898cd9b.tar.bz2
sunxi: When we've both mmc0 and mmc2, detect from which one we're booting
sunxi SOCs can boot from both mmc0 and mmc2, detect from which one we're booting, and make that one "mmc dev 0" so that a single u-boot binary can be used for both the onboard eMMC and for external sdcards. When we're booting from mmc2, we make it dev 0 because that is where the SPL will load the tertiary payload (the actual u-boot binary in our case) from, see: common/spl/spl_mmc.c, which has dev 0 hardcoded everywhere. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>
-rw-r--r--arch/arm/include/asm/arch-sunxi/mmc.h2
-rw-r--r--board/sunxi/board.c30
-rw-r--r--drivers/mmc/sunxi_mmc.c7
3 files changed, 31 insertions, 8 deletions
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 6a31184..70d7875 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -123,5 +123,5 @@ struct sunxi_mmc {
#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0)
#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1)
-int sunxi_mmc_init(int sdc_no);
+struct mmc *sunxi_mmc_init(int sdc_no);
#endif /* _SUNXI_MMC_H */
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index cfe22b6..f310e8d 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -12,6 +12,7 @@
*/
#include <common.h>
+#include <mmc.h>
#ifdef CONFIG_AXP152_POWER
#include <axp152.h>
#endif
@@ -104,11 +105,36 @@ static void mmc_pinmux_setup(int sdc)
int board_mmc_init(bd_t *bis)
{
+ __maybe_unused struct mmc *mmc0, *mmc1;
+ __maybe_unused char buf[512];
+
mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
- sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
+ mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
+ if (!mmc0)
+ return -1;
+
#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
- sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+ mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+ if (!mmc1)
+ return -1;
+#endif
+
+#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
+ /*
+ * Both mmc0 and mmc2 are bootable, figure out where we're booting
+ * from. Try mmc0 first, just like the brom does.
+ */
+ if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
+ mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
+ buf[12] = 0;
+ if (strcmp(&buf[4], "eGON.BT0") == 0)
+ return 0;
+ }
+
+ /* no bootable card in mmc0, so we must be booting from mmc2, swap */
+ mmc0->block_dev.dev = 1;
+ mmc1->block_dev.dev = 0;
#endif
return 0;
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index b47376a..d3b1039 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -373,7 +373,7 @@ static const struct mmc_ops sunxi_mmc_ops = {
.getcd = sunxi_mmc_getcd,
};
-int sunxi_mmc_init(int sdc_no)
+struct mmc *sunxi_mmc_init(int sdc_no)
{
struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
@@ -396,8 +396,5 @@ int sunxi_mmc_init(int sdc_no)
mmc_resource_init(sdc_no);
mmc_clk_io_on(sdc_no);
- if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL)
- return -1;
-
- return 0;
+ return mmc_create(cfg, &mmc_host[sdc_no]);
}