u-boot/arch/arm/mach-uniphier/boot-mode/boot-mode.c
Masahiro Yamada 569e4be172 ARM: uniphier: add a command to find the first MMC (non-SD) device
UniPhier SoC family supports both (e)MMC boot and SD card boot;
however, both of them are handled in the same uclass.

When booting from the eMMC, we want to know the device number
of the (e)MMC, not SD.  This command is useful to find the first
MMC (non-SD) device.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2016-02-29 03:50:16 +09:00

113 lines
2.6 KiB
C

/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mmc.h>
#include <spl.h>
#include <linux/err.h>
#include "../sbc/sbc-regs.h"
#include "../soc-info.h"
#include "boot-device.h"
u32 spl_boot_device_raw(void)
{
if (boot_is_swapped())
return BOOT_DEVICE_NOR;
switch (uniphier_get_soc_type()) {
#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3)
case SOC_UNIPHIER_PH1_SLD3:
return ph1_sld3_boot_device();
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) || \
defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) || \
defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8)
case SOC_UNIPHIER_PH1_LD4:
case SOC_UNIPHIER_PH1_PRO4:
case SOC_UNIPHIER_PH1_SLD8:
return ph1_ld4_boot_device();
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5)
case SOC_UNIPHIER_PH1_PRO5:
return ph1_pro5_boot_device();
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) || \
defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B)
case SOC_UNIPHIER_PROXSTREAM2:
case SOC_UNIPHIER_PH1_LD6B:
return proxstream2_boot_device();
#endif
default:
return BOOT_DEVICE_NONE;
}
}
u32 spl_boot_device(void)
{
u32 ret;
ret = spl_boot_device_raw();
return ret == BOOT_DEVICE_USB ? BOOT_DEVICE_NOR : ret;
}
u32 spl_boot_mode(void)
{
struct mmc *mmc;
/*
* work around a bug in the Boot ROM of PH1-sLD3, LD4, Pro4, and sLD8:
*
* The boot ROM in these SoCs breaks the PARTITION_CONFIG [179] of
* Extended CSD register; when switching to the Boot Partition 1, the
* Boot ROM should issue the SWITCH command (CMD6) with Set Bits for
* the Access Bits, but in fact it uses Write Byte for the Access Bits.
* As a result, the BOOT_PARTITION_ENABLE field of the PARTITION_CONFIG
* is lost. This bug was fixed for PH1-Pro5 and later SoCs.
*
* Fixup mmc->part_config here because it is used to determine the
* partition which the U-Boot image is read from.
*/
mmc = find_mmc_device(0);
mmc->part_config &= ~EXT_CSD_BOOT_PART_NUM(PART_ACCESS_MASK);
mmc->part_config |= EXT_CSD_BOOT_PARTITION_ENABLE;
return MMCSD_MODE_EMMCBOOT;
}
#if defined(CONFIG_DM_MMC) && !defined(CONFIG_SPL_BUILD)
static int find_first_mmc_device(void)
{
struct mmc *mmc;
int i;
for (i = 0; (mmc = find_mmc_device(i)); i++) {
if (!mmc_init(mmc) && IS_MMC(mmc))
return i;
}
return -ENODEV;
}
static int do_mmcsetn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int dev;
dev = find_first_mmc_device();
if (dev < 0)
return CMD_RET_FAILURE;
setenv_ulong("mmc_first_dev", dev);
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
mmcsetn, 1, 1, do_mmcsetn,
"Set the first MMC (not SD) dev number to \"mmc_first_dev\" enviroment",
""
);
#endif