uboot/arch/arm/mach-uniphier/boot-mode/boot-mode.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <mmc.h>
   9#include <spl.h>
  10#include <linux/err.h>
  11
  12#include "../sbc/sbc-regs.h"
  13#include "../soc-info.h"
  14#include "boot-device.h"
  15
  16u32 spl_boot_device_raw(void)
  17{
  18        if (boot_is_swapped())
  19                return BOOT_DEVICE_NOR;
  20
  21        switch (uniphier_get_soc_type()) {
  22#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
  23        case SOC_UNIPHIER_SLD3:
  24                return uniphier_sld3_boot_device();
  25#endif
  26#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_PRO4) || \
  27        defined(CONFIG_ARCH_UNIPHIER_SLD8)
  28        case SOC_UNIPHIER_LD4:
  29        case SOC_UNIPHIER_PRO4:
  30        case SOC_UNIPHIER_SLD8:
  31                return uniphier_ld4_boot_device();
  32#endif
  33#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
  34        case SOC_UNIPHIER_PRO5:
  35                return uniphier_pro5_boot_device();
  36#endif
  37#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
  38        case SOC_UNIPHIER_PXS2:
  39        case SOC_UNIPHIER_LD6B:
  40                return uniphier_pxs2_boot_device();
  41#endif
  42#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
  43        case SOC_UNIPHIER_LD11:
  44        case SOC_UNIPHIER_LD20:
  45                return uniphier_ld20_boot_device();
  46#endif
  47        default:
  48                return BOOT_DEVICE_NONE;
  49        }
  50}
  51
  52u32 spl_boot_device(void)
  53{
  54        u32 mode;
  55
  56        mode = spl_boot_device_raw();
  57
  58        switch (uniphier_get_soc_type()) {
  59#if defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
  60        case SOC_UNIPHIER_PXS2:
  61        case SOC_UNIPHIER_LD6B:
  62                if (mode == BOOT_DEVICE_USB)
  63                        mode = BOOT_DEVICE_NOR;
  64                break;
  65#endif
  66#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
  67        case SOC_UNIPHIER_LD11:
  68        case SOC_UNIPHIER_LD20:
  69                if (mode == BOOT_DEVICE_MMC1 || mode == BOOT_DEVICE_USB)
  70                        mode = BOOT_DEVICE_BOARD;
  71                break;
  72#endif
  73        default:
  74                break;
  75        }
  76
  77        return mode;
  78}
  79
  80u32 spl_boot_mode(const u32 boot_device)
  81{
  82        struct mmc *mmc;
  83
  84        /*
  85         * work around a bug in the Boot ROM of PH1-sLD3, LD4, Pro4, and sLD8:
  86         *
  87         * The boot ROM in these SoCs breaks the PARTITION_CONFIG [179] of
  88         * Extended CSD register; when switching to the Boot Partition 1, the
  89         * Boot ROM should issue the SWITCH command (CMD6) with Set Bits for
  90         * the Access Bits, but in fact it uses Write Byte for the Access Bits.
  91         * As a result, the BOOT_PARTITION_ENABLE field of the PARTITION_CONFIG
  92         * is lost.  This bug was fixed for PH1-Pro5 and later SoCs.
  93         *
  94         * Fixup mmc->part_config here because it is used to determine the
  95         * partition which the U-Boot image is read from.
  96         */
  97        mmc = find_mmc_device(0);
  98        mmc->part_config &= ~EXT_CSD_BOOT_PART_NUM(PART_ACCESS_MASK);
  99        mmc->part_config |= EXT_CSD_BOOT_PARTITION_ENABLE;
 100
 101        return MMCSD_MODE_EMMCBOOT;
 102}
 103
 104#if defined(CONFIG_DM_MMC) && !defined(CONFIG_SPL_BUILD)
 105static int find_first_mmc_device(void)
 106{
 107        struct mmc *mmc;
 108        int i;
 109
 110        for (i = 0; (mmc = find_mmc_device(i)); i++) {
 111                if (!mmc_init(mmc) && IS_MMC(mmc))
 112                        return i;
 113        }
 114
 115        return -ENODEV;
 116}
 117
 118int mmc_get_env_dev(void)
 119{
 120        return find_first_mmc_device();
 121}
 122
 123static int do_mmcsetn(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 124{
 125        int dev;
 126
 127        dev = find_first_mmc_device();
 128        if (dev < 0)
 129                return CMD_RET_FAILURE;
 130
 131        setenv_ulong("mmc_first_dev", dev);
 132        return CMD_RET_SUCCESS;
 133}
 134
 135U_BOOT_CMD(
 136           mmcsetn,     1,      1,      do_mmcsetn,
 137        "Set the first MMC (not SD) dev number to \"mmc_first_dev\" environment",
 138        ""
 139);
 140#endif
 141