uboot/common/spl/spl_mmc.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Texas Instruments, <www.ti.com>
   4 *
   5 * Aneesh V <aneesh@ti.com>
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9#include <common.h>
  10#include <spl.h>
  11#include <asm/u-boot.h>
  12#include <mmc.h>
  13#include <version.h>
  14#include <image.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
  19{
  20        unsigned long err;
  21        u32 image_size_sectors;
  22        struct image_header *header;
  23
  24        header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
  25                                                sizeof(struct image_header));
  26
  27        /* read image header to find the image size & load address */
  28        err = mmc->block_dev.block_read(0, sector, 1, header);
  29        if (err == 0)
  30                goto end;
  31
  32        if (image_get_magic(header) != IH_MAGIC)
  33                return -1;
  34
  35        spl_parse_image_header(header);
  36
  37        /* convert size to sectors - round up */
  38        image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
  39                                mmc->read_bl_len;
  40
  41        /* Read the header too to avoid extra memcpy */
  42        err = mmc->block_dev.block_read(0, sector, image_size_sectors,
  43                                        (void *)spl_image.load_addr);
  44
  45end:
  46#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
  47        if (err == 0)
  48                printf("spl: mmc blk read err - %lu\n", err);
  49#endif
  50
  51        return (err == 0);
  52}
  53
  54#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
  55static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
  56{
  57        disk_partition_t info;
  58
  59        if (get_partition_info(&mmc->block_dev, partition, &info)) {
  60#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
  61                printf("spl: partition error\n");
  62#endif
  63                return -1;
  64        }
  65
  66        return mmc_load_image_raw_sector(mmc, info.start);
  67}
  68#endif
  69
  70#ifdef CONFIG_SPL_OS_BOOT
  71static int mmc_load_image_raw_os(struct mmc *mmc)
  72{
  73        if (!mmc->block_dev.block_read(0,
  74                                       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
  75                                       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
  76                                       (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
  77#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
  78                printf("mmc args blk read error\n");
  79#endif
  80                return -1;
  81        }
  82
  83        return mmc_load_image_raw_sector(mmc,
  84                                                CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
  85}
  86#endif
  87
  88void spl_mmc_load_image(void)
  89{
  90        struct mmc *mmc;
  91        int err;
  92        u32 boot_mode;
  93
  94        mmc_initialize(gd->bd);
  95        /* We register only one device. So, the dev id is always 0 */
  96        mmc = find_mmc_device(0);
  97        if (!mmc) {
  98#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
  99                puts("spl: mmc device not found!!\n");
 100#endif
 101                hang();
 102        }
 103
 104        err = mmc_init(mmc);
 105        if (err) {
 106#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 107                printf("spl: mmc init failed: err - %d\n", err);
 108#endif
 109                hang();
 110        }
 111
 112        boot_mode = spl_boot_mode();
 113        if (boot_mode == MMCSD_MODE_RAW) {
 114                debug("boot mode - RAW\n");
 115#ifdef CONFIG_SPL_OS_BOOT
 116                if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
 117#endif
 118#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
 119                err = mmc_load_image_raw_partition(mmc,
 120                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
 121#else
 122                err = mmc_load_image_raw_sector(mmc,
 123                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
 124#endif
 125#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
 126        }
 127        if (err || boot_mode == MMCSD_MODE_FS) {
 128                debug("boot mode - FS\n");
 129#ifdef CONFIG_SPL_FAT_SUPPORT
 130#ifdef CONFIG_SPL_OS_BOOT
 131                if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev,
 132                                                                CONFIG_SYS_MMCSD_FS_BOOT_PARTITION))
 133#endif
 134                err = spl_load_image_fat(&mmc->block_dev,
 135                                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
 136                                        CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
 137                if(err)
 138#endif /* CONFIG_SPL_FAT_SUPPORT */
 139                {
 140#ifdef CONFIG_SPL_EXT_SUPPORT
 141#ifdef CONFIG_SPL_OS_BOOT
 142                if (spl_start_uboot() || spl_load_image_ext_os(&mmc->block_dev,
 143                                                                CONFIG_SYS_MMCSD_FS_BOOT_PARTITION))
 144#endif
 145                err = spl_load_image_ext(&mmc->block_dev,
 146                                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
 147                                        CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
 148#endif /* CONFIG_SPL_EXT_SUPPORT */
 149                }
 150#endif /* defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) */
 151#ifdef CONFIG_SUPPORT_EMMC_BOOT
 152        } else if (boot_mode == MMCSD_MODE_EMMCBOOT) {
 153                /*
 154                 * We need to check what the partition is configured to.
 155                 * 1 and 2 match up to boot0 / boot1 and 7 is user data
 156                 * which is the first physical partition (0).
 157                 */
 158                int part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
 159
 160                if (part == 7)
 161                        part = 0;
 162
 163                if (mmc_switch_part(0, part)) {
 164#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 165                        puts("MMC partition switch failed\n");
 166#endif
 167                        hang();
 168                }
 169#ifdef CONFIG_SPL_OS_BOOT
 170                if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
 171#endif
 172                err = mmc_load_image_raw_sector(mmc,
 173                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
 174#endif
 175        }
 176
 177        switch(boot_mode){
 178                case MMCSD_MODE_RAW:
 179#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
 180                case MMCSD_MODE_FS:
 181#endif
 182#ifdef CONFIG_SUPPORT_EMMC_BOOT
 183                case MMCSD_MODE_EMMCBOOT:
 184#endif
 185                        /* Boot mode is ok. Nothing to do. */
 186                        break;
 187                case MMCSD_MODE_UNDEFINED:
 188                default:
 189#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 190                        puts("spl: wrong MMC boot mode\n");
 191#endif
 192                        hang();
 193        }
 194
 195        if (err)
 196                hang();
 197}
 198