blob: 51add39f7ebac44ba9ee3d8f48fbc8ccef622f0a [file] [log] [blame]
Simon Schwarze21d2d82011-09-14 15:33:34 -04001/*
2 * (C) Copyright 2010
3 * Texas Instruments, <www.ti.com>
4 *
5 * Aneesh V <aneesh@ti.com>
6 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Simon Schwarze21d2d82011-09-14 15:33:34 -04008 */
9#include <common.h>
Tom Rini28591df2012-08-13 12:03:19 -070010#include <spl.h>
Paul Kocialkowski0d139722015-04-27 10:20:22 +020011#include <linux/compiler.h>
Simon Schwarze21d2d82011-09-14 15:33:34 -040012#include <asm/u-boot.h>
Simon Schwarze21d2d82011-09-14 15:33:34 -040013#include <mmc.h>
Tom Rini1530e8a2013-06-28 14:43:01 -040014#include <image.h>
Simon Schwarze21d2d82011-09-14 15:33:34 -040015
16DECLARE_GLOBAL_DATA_PTR;
17
Paul Kocialkowski17675c82014-11-08 23:14:56 +010018static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
Simon Schwarze21d2d82011-09-14 15:33:34 -040019{
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020020 unsigned long count;
Peter Korsgaardf2471292013-03-21 04:55:17 +000021 u32 image_size_sectors;
22 struct image_header *header;
Simon Schwarze21d2d82011-09-14 15:33:34 -040023
24 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
Paul Kocialkowski0d139722015-04-27 10:20:22 +020025 sizeof(struct image_header));
Simon Schwarze21d2d82011-09-14 15:33:34 -040026
27 /* read image header to find the image size & load address */
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020028 count = mmc->block_dev.block_read(0, sector, 1, header);
Simon Glass5614db82015-06-23 15:38:47 -060029 debug("read sector %lx, count=%lu\n", sector, count);
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020030 if (count == 0)
Simon Schwarze21d2d82011-09-14 15:33:34 -040031 goto end;
32
Simon Glass5614db82015-06-23 15:38:47 -060033 if (image_get_magic(header) != IH_MAGIC) {
34 puts("bad magic\n");
Tom Rini1530e8a2013-06-28 14:43:01 -040035 return -1;
Simon Glass5614db82015-06-23 15:38:47 -060036 }
Tom Rini1530e8a2013-06-28 14:43:01 -040037
Simon Schwarze21d2d82011-09-14 15:33:34 -040038 spl_parse_image_header(header);
39
40 /* convert size to sectors - round up */
Tom Rinia0b9fa52012-08-14 10:25:15 -070041 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
Paul Kocialkowski0d139722015-04-27 10:20:22 +020042 mmc->read_bl_len;
Simon Schwarze21d2d82011-09-14 15:33:34 -040043
44 /* Read the header too to avoid extra memcpy */
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020045 count = mmc->block_dev.block_read(0, sector, image_size_sectors,
Simon Glass5614db82015-06-23 15:38:47 -060046 (void *)spl_image.load_addr);
47 debug("read %x sectors to %x\n", image_size_sectors,
48 spl_image.load_addr);
Simon Schwarze21d2d82011-09-14 15:33:34 -040049
50end:
Paul Kocialkowski01c723f2015-06-03 18:48:51 +020051 if (count == 0) {
Paul Burtona8015fd2013-09-04 16:12:24 +010052#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski01c723f2015-06-03 18:48:51 +020053 puts("spl: mmc block read error\n");
Paul Burtona8015fd2013-09-04 16:12:24 +010054#endif
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020055 return -1;
Paul Kocialkowski01c723f2015-06-03 18:48:51 +020056 }
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020057
58 return 0;
Simon Schwarze21d2d82011-09-14 15:33:34 -040059}
60
Paul Kocialkowski17675c82014-11-08 23:14:56 +010061#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
62static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
63{
64 disk_partition_t info;
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020065 int err;
Paul Kocialkowski17675c82014-11-08 23:14:56 +010066
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020067 err = get_partition_info(&mmc->block_dev, partition, &info);
68 if (err) {
Paul Kocialkowski17675c82014-11-08 23:14:56 +010069#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski01c723f2015-06-03 18:48:51 +020070 puts("spl: partition error\n");
Paul Kocialkowski17675c82014-11-08 23:14:56 +010071#endif
72 return -1;
73 }
74
75 return mmc_load_image_raw_sector(mmc, info.start);
76}
77#endif
78
Peter Korsgaard01b542f2013-05-13 08:36:29 +000079#ifdef CONFIG_SPL_OS_BOOT
80static int mmc_load_image_raw_os(struct mmc *mmc)
81{
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020082 unsigned long count;
Paul Kocialkowski0d139722015-04-27 10:20:22 +020083
Paul Kocialkowski2d69f252015-05-22 12:45:35 +020084 count = mmc->block_dev.block_read(0,
85 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
86 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
87 (void *) CONFIG_SYS_SPL_ARGS_ADDR);
88 if (count == 0) {
Paul Burtona8015fd2013-09-04 16:12:24 +010089#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski01c723f2015-06-03 18:48:51 +020090 puts("spl: mmc block read error\n");
Paul Burtona8015fd2013-09-04 16:12:24 +010091#endif
Peter Korsgaard01b542f2013-05-13 08:36:29 +000092 return -1;
93 }
94
Paul Kocialkowski17675c82014-11-08 23:14:56 +010095 return mmc_load_image_raw_sector(mmc,
Paul Kocialkowski0d139722015-04-27 10:20:22 +020096 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
Peter Korsgaard01b542f2013-05-13 08:36:29 +000097}
98#endif
99
Simon Schwarze21d2d82011-09-14 15:33:34 -0400100void spl_mmc_load_image(void)
101{
102 struct mmc *mmc;
Simon Schwarze21d2d82011-09-14 15:33:34 -0400103 u32 boot_mode;
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200104 int err;
105 __maybe_unused int part;
Simon Schwarze21d2d82011-09-14 15:33:34 -0400106
107 mmc_initialize(gd->bd);
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200108
Simon Schwarze21d2d82011-09-14 15:33:34 -0400109 /* We register only one device. So, the dev id is always 0 */
110 mmc = find_mmc_device(0);
111 if (!mmc) {
Paul Burtona8015fd2013-09-04 16:12:24 +0100112#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200113 puts("spl: mmc device not found\n");
Paul Burtona8015fd2013-09-04 16:12:24 +0100114#endif
Simon Schwarze21d2d82011-09-14 15:33:34 -0400115 hang();
116 }
117
118 err = mmc_init(mmc);
119 if (err) {
Paul Burtona8015fd2013-09-04 16:12:24 +0100120#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200121 printf("spl: mmc init failed with error: %d\n", err);
Paul Burtona8015fd2013-09-04 16:12:24 +0100122#endif
Simon Schwarze21d2d82011-09-14 15:33:34 -0400123 hang();
124 }
Peter Korsgaard5e5483d2013-05-13 08:36:25 +0000125
Tom Rinia76ff952012-08-14 09:19:44 -0700126 boot_mode = spl_boot_mode();
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200127 switch (boot_mode) {
128 case MMCSD_MODE_RAW:
129 debug("spl: mmc boot mode: raw\n");
130
Peter Korsgaard01b542f2013-05-13 08:36:29 +0000131#ifdef CONFIG_SPL_OS_BOOT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200132 if (!spl_start_uboot()) {
133 err = mmc_load_image_raw_os(mmc);
134 if (!err)
135 return;
136 }
Peter Korsgaard01b542f2013-05-13 08:36:29 +0000137#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200138#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
Paul Kocialkowski17675c82014-11-08 23:14:56 +0100139 err = mmc_load_image_raw_partition(mmc,
140 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200141 if (!err)
142 return;
143#elif defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR)
Paul Kocialkowski17675c82014-11-08 23:14:56 +0100144 err = mmc_load_image_raw_sector(mmc,
Dan Murphyb7b5b0c2014-01-16 11:23:29 -0600145 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200146 if (!err)
147 return;
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200148#endif
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200149 case MMCSD_MODE_FS:
150 debug("spl: mmc boot mode: fs\n");
151
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200152#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
Guillaume GARDET1eb410c2014-10-15 17:53:12 +0200153#ifdef CONFIG_SPL_FAT_SUPPORT
Peter Korsgaard465f1f82013-05-13 08:36:27 +0000154#ifdef CONFIG_SPL_OS_BOOT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200155 if (!spl_start_uboot()) {
156 err = spl_load_image_fat_os(&mmc->block_dev,
157 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
158 if (!err)
159 return;
160 }
Peter Korsgaard465f1f82013-05-13 08:36:27 +0000161#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200162#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
Dan Murphyb7b5b0c2014-01-16 11:23:29 -0600163 err = spl_load_image_fat(&mmc->block_dev,
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200164 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
165 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
166 if (!err)
167 return;
168#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200169#endif
Guillaume GARDET1eb410c2014-10-15 17:53:12 +0200170#ifdef CONFIG_SPL_EXT_SUPPORT
171#ifdef CONFIG_SPL_OS_BOOT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200172 if (!spl_start_uboot()) {
173 err = spl_load_image_ext_os(&mmc->block_dev,
174 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
175 if (!err)
176 return;
177 }
Tom Rinia0d8cca2012-08-10 09:27:14 -0700178#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200179#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
Guillaume GARDET1eb410c2014-10-15 17:53:12 +0200180 err = spl_load_image_ext(&mmc->block_dev,
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200181 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
182 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
183 if (!err)
184 return;
185#endif
186#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200187#endif
Tom Rinicc612692014-02-05 10:24:18 -0500188#ifdef CONFIG_SUPPORT_EMMC_BOOT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200189 case MMCSD_MODE_EMMCBOOT:
Tom Rinicc612692014-02-05 10:24:18 -0500190 /*
191 * We need to check what the partition is configured to.
192 * 1 and 2 match up to boot0 / boot1 and 7 is user data
193 * which is the first physical partition (0).
194 */
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200195 part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
Tom Rinicc612692014-02-05 10:24:18 -0500196
197 if (part == 7)
198 part = 0;
199
200 if (mmc_switch_part(0, part)) {
201#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200202 puts("spl: mmc partition switch failed\n");
Tom Rinicc612692014-02-05 10:24:18 -0500203#endif
204 hang();
205 }
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200206
Tom Rinicc612692014-02-05 10:24:18 -0500207#ifdef CONFIG_SPL_OS_BOOT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200208 if (!spl_start_uboot()) {
209 err = mmc_load_image_raw_os(mmc);
210 if (!err)
211 return;
212 }
Tom Rinicc612692014-02-05 10:24:18 -0500213#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200214#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
Paul Kocialkowski409d4f72015-04-27 10:20:23 +0200215 err = mmc_load_image_raw_partition(mmc,
216 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200217 if (!err)
218 return;
219#elif defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR)
Paul Kocialkowski17675c82014-11-08 23:14:56 +0100220 err = mmc_load_image_raw_sector(mmc,
Tom Rinicc612692014-02-05 10:24:18 -0500221 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200222 if (!err)
223 return;
Guillaume GARDET1143b0a2014-12-16 12:00:44 +0100224#endif
Paul Kocialkowski4bd66e72015-06-08 23:05:09 +0200225#endif
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200226 case MMCSD_MODE_UNDEFINED:
227 default:
Paul Burtona8015fd2013-09-04 16:12:24 +0100228#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200229 if (err)
230 puts("spl: mmc: no boot mode left to try\n");
231 else
232 puts("spl: mmc: wrong boot mode\n");
Paul Burtona8015fd2013-09-04 16:12:24 +0100233#endif
Peter Korsgaard5e5483d2013-05-13 08:36:25 +0000234 hang();
Paul Kocialkowski0d139722015-04-27 10:20:22 +0200235 }
Simon Schwarze21d2d82011-09-14 15:33:34 -0400236}