uboot/common/spl/spl_mmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2010
   4 * Texas Instruments, <www.ti.com>
   5 *
   6 * Aneesh V <aneesh@ti.com>
   7 */
   8#include <common.h>
   9#include <dm.h>
  10#include <spl.h>
  11#include <linux/compiler.h>
  12#include <errno.h>
  13#include <asm/u-boot.h>
  14#include <errno.h>
  15#include <mmc.h>
  16#include <image.h>
  17
  18static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
  19                           ulong sector, struct image_header *header)
  20{
  21        u32 image_size_sectors;
  22        unsigned long count;
  23        int ret;
  24
  25        ret = spl_parse_image_header(spl_image, header);
  26        if (ret)
  27                return ret;
  28
  29        /* convert size to sectors - round up */
  30        image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
  31                             mmc->read_bl_len;
  32
  33        /* Read the header too to avoid extra memcpy */
  34        count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
  35                          (void *)(ulong)spl_image->load_addr);
  36        debug("read %x sectors to %lx\n", image_size_sectors,
  37              spl_image->load_addr);
  38        if (count != image_size_sectors)
  39                return -EIO;
  40
  41        return 0;
  42}
  43
  44static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
  45                             ulong count, void *buf)
  46{
  47        struct mmc *mmc = load->dev;
  48
  49        return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
  50}
  51
  52static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
  53{
  54#if IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR)
  55        if (part == 0)
  56                return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET;
  57#endif
  58
  59        return 0;
  60}
  61
  62static __maybe_unused
  63int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
  64                              struct mmc *mmc, unsigned long sector)
  65{
  66        unsigned long count;
  67        struct image_header *header;
  68        struct blk_desc *bd = mmc_get_blk_desc(mmc);
  69        int ret = 0;
  70
  71        header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
  72
  73        /* read image header to find the image size & load address */
  74        count = blk_dread(bd, sector, 1, header);
  75        debug("hdr read sector %lx, count=%lu\n", sector, count);
  76        if (count == 0) {
  77                ret = -EIO;
  78                goto end;
  79        }
  80
  81        if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
  82            image_get_magic(header) == FDT_MAGIC) {
  83                struct spl_load_info load;
  84
  85                debug("Found FIT\n");
  86                load.dev = mmc;
  87                load.priv = NULL;
  88                load.filename = NULL;
  89                load.bl_len = mmc->read_bl_len;
  90                load.read = h_spl_load_read;
  91                ret = spl_load_simple_fit(spl_image, &load, sector, header);
  92        } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
  93                struct spl_load_info load;
  94
  95                load.dev = mmc;
  96                load.priv = NULL;
  97                load.filename = NULL;
  98                load.bl_len = mmc->read_bl_len;
  99                load.read = h_spl_load_read;
 100
 101                ret = spl_load_imx_container(spl_image, &load, sector);
 102        } else {
 103                ret = mmc_load_legacy(spl_image, mmc, sector, header);
 104        }
 105
 106end:
 107        if (ret) {
 108#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 109                puts("mmc_load_image_raw_sector: mmc block read error\n");
 110#endif
 111                return -1;
 112        }
 113
 114        return 0;
 115}
 116
 117static int spl_mmc_get_device_index(u32 boot_device)
 118{
 119        switch (boot_device) {
 120        case BOOT_DEVICE_MMC1:
 121                return 0;
 122        case BOOT_DEVICE_MMC2:
 123        case BOOT_DEVICE_MMC2_2:
 124                return 1;
 125        }
 126
 127#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 128        printf("spl: unsupported mmc boot device.\n");
 129#endif
 130
 131        return -ENODEV;
 132}
 133
 134static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
 135{
 136        int err, mmc_dev;
 137
 138        mmc_dev = spl_mmc_get_device_index(boot_device);
 139        if (mmc_dev < 0)
 140                return mmc_dev;
 141
 142#if CONFIG_IS_ENABLED(DM_MMC)
 143        err = mmc_init_device(mmc_dev);
 144#else
 145        err = mmc_initialize(NULL);
 146#endif /* DM_MMC */
 147        if (err) {
 148#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 149                printf("spl: could not initialize mmc. error: %d\n", err);
 150#endif
 151                return err;
 152        }
 153        *mmcp = find_mmc_device(mmc_dev);
 154        err = *mmcp ? 0 : -ENODEV;
 155        if (err) {
 156#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 157                printf("spl: could not find mmc device %d. error: %d\n",
 158                       mmc_dev, err);
 159#endif
 160                return err;
 161        }
 162
 163        return 0;
 164}
 165
 166#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
 167static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
 168                                        struct mmc *mmc, int partition,
 169                                        unsigned long sector)
 170{
 171        disk_partition_t info;
 172        int err;
 173
 174#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
 175        int type_part;
 176        /* Only support MBR so DOS_ENTRY_NUMBERS */
 177        for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
 178                err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
 179                if (err)
 180                        continue;
 181                if (info.sys_ind == 
 182                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
 183                        partition = type_part;
 184                        break;
 185                }
 186        }
 187#endif
 188
 189        err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
 190        if (err) {
 191#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 192                puts("spl: partition error\n");
 193#endif
 194                return -1;
 195        }
 196
 197#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
 198        return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector);
 199#else
 200        return mmc_load_image_raw_sector(spl_image, mmc, info.start);
 201#endif
 202}
 203#endif
 204
 205#ifdef CONFIG_SPL_OS_BOOT
 206static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
 207                                 struct mmc *mmc)
 208{
 209        int ret;
 210
 211#if defined(CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
 212        unsigned long count;
 213
 214        count = blk_dread(mmc_get_blk_desc(mmc),
 215                CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
 216                CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
 217                (void *) CONFIG_SYS_SPL_ARGS_ADDR);
 218        if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
 219#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 220                puts("mmc_load_image_raw_os: mmc block read error\n");
 221#endif
 222                return -1;
 223        }
 224#endif  /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
 225
 226        ret = mmc_load_image_raw_sector(spl_image, mmc,
 227                CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
 228        if (ret)
 229                return ret;
 230
 231        if (spl_image->os != IH_OS_LINUX) {
 232                puts("Expected Linux image is not found. Trying to start U-boot\n");
 233                return -ENOENT;
 234        }
 235
 236        return 0;
 237}
 238#else
 239int spl_start_uboot(void)
 240{
 241        return 1;
 242}
 243static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
 244                                 struct mmc *mmc)
 245{
 246        return -ENOSYS;
 247}
 248#endif
 249
 250#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
 251static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
 252                              const char *filename)
 253{
 254        int err = -ENOSYS;
 255
 256#ifdef CONFIG_SPL_FS_FAT
 257        if (!spl_start_uboot()) {
 258                err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
 259                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
 260                if (!err)
 261                        return err;
 262        }
 263#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
 264        err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
 265                                 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
 266                                 filename);
 267        if (!err)
 268                return err;
 269#endif
 270#endif
 271#ifdef CONFIG_SPL_FS_EXT4
 272        if (!spl_start_uboot()) {
 273                err = spl_load_image_ext_os(spl_image, mmc_get_blk_desc(mmc),
 274                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
 275                if (!err)
 276                        return err;
 277        }
 278#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
 279        err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
 280                                 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
 281                                 filename);
 282        if (!err)
 283                return err;
 284#endif
 285#endif
 286
 287#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
 288        err = -ENOENT;
 289#endif
 290
 291        return err;
 292}
 293#else
 294static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
 295                              const char *filename)
 296{
 297        return -ENOSYS;
 298}
 299#endif
 300
 301u32 __weak spl_boot_mode(const u32 boot_device)
 302{
 303#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
 304        return MMCSD_MODE_FS;
 305#elif defined(CONFIG_SUPPORT_EMMC_BOOT)
 306        return MMCSD_MODE_EMMCBOOT;
 307#else
 308        return MMCSD_MODE_RAW;
 309#endif
 310}
 311
 312#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
 313__weak
 314int spl_boot_partition(const u32 boot_device)
 315{
 316        return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
 317}
 318#endif
 319
 320unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
 321                                                  unsigned long raw_sect)
 322{
 323        return raw_sect;
 324}
 325
 326int spl_mmc_load(struct spl_image_info *spl_image,
 327                 struct spl_boot_device *bootdev,
 328                 const char *filename,
 329                 int raw_part,
 330                 unsigned long raw_sect)
 331{
 332        static struct mmc *mmc;
 333        u32 boot_mode;
 334        int err = 0;
 335        __maybe_unused int part = 0;
 336
 337        /* Perform peripheral init only once */
 338        if (!mmc) {
 339                err = spl_mmc_find_device(&mmc, bootdev->boot_device);
 340                if (err)
 341                        return err;
 342
 343                err = mmc_init(mmc);
 344                if (err) {
 345                        mmc = NULL;
 346#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 347                        printf("spl: mmc init failed with error: %d\n", err);
 348#endif
 349                        return err;
 350                }
 351        }
 352
 353        boot_mode = spl_boot_mode(bootdev->boot_device);
 354        err = -EINVAL;
 355        switch (boot_mode) {
 356        case MMCSD_MODE_EMMCBOOT:
 357#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
 358                part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION;
 359#else
 360                /*
 361                 * We need to check what the partition is configured to.
 362                 * 1 and 2 match up to boot0 / boot1 and 7 is user data
 363                 * which is the first physical partition (0).
 364                 */
 365                part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
 366
 367                if (part == 7)
 368                        part = 0;
 369#endif
 370
 371                if (CONFIG_IS_ENABLED(MMC_TINY))
 372                        err = mmc_switch_part(mmc, part);
 373                else
 374                        err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
 375
 376                if (err) {
 377#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 378                        puts("spl: mmc partition switch failed\n");
 379#endif
 380                        return err;
 381                }
 382                /* Fall through */
 383        case MMCSD_MODE_RAW:
 384                debug("spl: mmc boot mode: raw\n");
 385
 386                if (!spl_start_uboot()) {
 387                        err = mmc_load_image_raw_os(spl_image, mmc);
 388                        if (!err)
 389                                return err;
 390                }
 391
 392                raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
 393
 394#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
 395                err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
 396                                                   raw_sect);
 397                if (!err)
 398                        return err;
 399#endif
 400#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
 401                err = mmc_load_image_raw_sector(spl_image, mmc,
 402                                raw_sect + spl_mmc_raw_uboot_offset(part));
 403                if (!err)
 404                        return err;
 405#endif
 406                /* If RAW mode fails, try FS mode. */
 407        case MMCSD_MODE_FS:
 408                debug("spl: mmc boot mode: fs\n");
 409
 410                err = spl_mmc_do_fs_boot(spl_image, mmc, filename);
 411                if (!err)
 412                        return err;
 413
 414                break;
 415#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 416        default:
 417                puts("spl: mmc: wrong boot mode\n");
 418#endif
 419        }
 420
 421        return err;
 422}
 423
 424int spl_mmc_load_image(struct spl_image_info *spl_image,
 425                       struct spl_boot_device *bootdev)
 426{
 427        return spl_mmc_load(spl_image, bootdev,
 428#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
 429                            CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
 430#else
 431                            NULL,
 432#endif
 433#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
 434                            spl_boot_partition(bootdev->boot_device),
 435#else
 436                            0,
 437#endif
 438#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
 439                            CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
 440#else
 441                            0);
 442#endif
 443}
 444
 445SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
 446SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
 447SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
 448