]>
Commit | Line | Data |
---|---|---|
9ea5c6ef SS |
1 | /* |
2 | * (C) Copyright 2010 | |
3 | * Texas Instruments, <www.ti.com> | |
4 | * | |
5 | * Aneesh V <aneesh@ti.com> | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
9ea5c6ef SS |
8 | */ |
9 | #include <common.h> | |
47f7bcae | 10 | #include <spl.h> |
91199f4a | 11 | #include <linux/compiler.h> |
9ea5c6ef | 12 | #include <asm/u-boot.h> |
9ea5c6ef | 13 | #include <mmc.h> |
e4c444b3 | 14 | #include <image.h> |
9ea5c6ef SS |
15 | |
16 | DECLARE_GLOBAL_DATA_PTR; | |
17 | ||
b97300b6 | 18 | static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) |
9ea5c6ef | 19 | { |
2e222105 PK |
20 | unsigned long err; |
21 | u32 image_size_sectors; | |
22 | struct image_header *header; | |
9ea5c6ef SS |
23 | |
24 | header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - | |
91199f4a | 25 | sizeof(struct image_header)); |
9ea5c6ef SS |
26 | |
27 | /* read image header to find the image size & load address */ | |
721931f8 | 28 | err = mmc->block_dev.block_read(0, sector, 1, header); |
2e222105 | 29 | if (err == 0) |
9ea5c6ef SS |
30 | goto end; |
31 | ||
e4c444b3 TR |
32 | if (image_get_magic(header) != IH_MAGIC) |
33 | return -1; | |
34 | ||
9ea5c6ef SS |
35 | spl_parse_image_header(header); |
36 | ||
37 | /* convert size to sectors - round up */ | |
f0881250 | 38 | image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / |
91199f4a | 39 | mmc->read_bl_len; |
9ea5c6ef SS |
40 | |
41 | /* Read the header too to avoid extra memcpy */ | |
721931f8 PK |
42 | err = mmc->block_dev.block_read(0, sector, image_size_sectors, |
43 | (void *)spl_image.load_addr); | |
9ea5c6ef SS |
44 | |
45 | end: | |
8112f5fa | 46 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT |
79adb7a2 | 47 | if (err == 0) |
91199f4a | 48 | printf("spl: mmc block read error\n"); |
8112f5fa | 49 | #endif |
79adb7a2 PK |
50 | |
51 | return (err == 0); | |
9ea5c6ef SS |
52 | } |
53 | ||
b97300b6 PK |
54 | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION |
55 | static 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 | ||
2b75b0ad PK |
70 | #ifdef CONFIG_SPL_OS_BOOT |
71 | static int mmc_load_image_raw_os(struct mmc *mmc) | |
72 | { | |
91199f4a PK |
73 | unsigned long err; |
74 | ||
75 | err = mmc->block_dev.block_read(0, | |
76 | CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, | |
77 | CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, | |
78 | (void *)CONFIG_SYS_SPL_ARGS_ADDR); | |
9d3b5654 | 79 | if (err == 0) { |
8112f5fa | 80 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT |
91199f4a | 81 | printf("spl: mmc block read error\n"); |
8112f5fa | 82 | #endif |
2b75b0ad PK |
83 | return -1; |
84 | } | |
85 | ||
b97300b6 | 86 | return mmc_load_image_raw_sector(mmc, |
91199f4a | 87 | CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); |
2b75b0ad PK |
88 | } |
89 | #endif | |
90 | ||
9ea5c6ef SS |
91 | void spl_mmc_load_image(void) |
92 | { | |
93 | struct mmc *mmc; | |
9ea5c6ef | 94 | u32 boot_mode; |
91199f4a PK |
95 | int err; |
96 | __maybe_unused int part; | |
9ea5c6ef SS |
97 | |
98 | mmc_initialize(gd->bd); | |
91199f4a | 99 | |
9ea5c6ef SS |
100 | /* We register only one device. So, the dev id is always 0 */ |
101 | mmc = find_mmc_device(0); | |
102 | if (!mmc) { | |
8112f5fa | 103 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT |
91199f4a | 104 | puts("spl: mmc device not found\n"); |
8112f5fa | 105 | #endif |
9ea5c6ef SS |
106 | hang(); |
107 | } | |
108 | ||
109 | err = mmc_init(mmc); | |
110 | if (err) { | |
8112f5fa | 111 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT |
91199f4a | 112 | printf("spl: mmc init failed with error: %d\n", err); |
8112f5fa | 113 | #endif |
9ea5c6ef SS |
114 | hang(); |
115 | } | |
79adb7a2 | 116 | |
37189a19 | 117 | boot_mode = spl_boot_mode(); |
91199f4a PK |
118 | switch (boot_mode) { |
119 | case MMCSD_MODE_RAW: | |
120 | debug("spl: mmc boot mode: raw\n"); | |
121 | ||
2b75b0ad | 122 | #ifdef CONFIG_SPL_OS_BOOT |
91199f4a PK |
123 | if (!spl_start_uboot()) { |
124 | err = mmc_load_image_raw_os(mmc); | |
125 | if (!err) | |
126 | return; | |
127 | } | |
2b75b0ad | 128 | #endif |
b97300b6 PK |
129 | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION |
130 | err = mmc_load_image_raw_partition(mmc, | |
131 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); | |
132 | #else | |
133 | err = mmc_load_image_raw_sector(mmc, | |
773b5940 | 134 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); |
b97300b6 | 135 | #endif |
91199f4a PK |
136 | if (!err) |
137 | return; | |
592f9222 | 138 | #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) |
91199f4a PK |
139 | case MMCSD_MODE_FS: |
140 | debug("spl: mmc boot mode: fs\n"); | |
141 | ||
592f9222 | 142 | #ifdef CONFIG_SPL_FAT_SUPPORT |
7ad2cc79 | 143 | #ifdef CONFIG_SPL_OS_BOOT |
91199f4a PK |
144 | if (!spl_start_uboot()) { |
145 | err = spl_load_image_fat_os(&mmc->block_dev, | |
146 | CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); | |
147 | if (!err) | |
148 | return; | |
149 | } | |
7ad2cc79 | 150 | #endif |
773b5940 | 151 | err = spl_load_image_fat(&mmc->block_dev, |
91199f4a PK |
152 | CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, |
153 | CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); | |
154 | if (!err) | |
155 | return; | |
156 | #endif | |
592f9222 GG |
157 | #ifdef CONFIG_SPL_EXT_SUPPORT |
158 | #ifdef CONFIG_SPL_OS_BOOT | |
91199f4a PK |
159 | if (!spl_start_uboot()) { |
160 | err = spl_load_image_ext_os(&mmc->block_dev, | |
161 | CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); | |
162 | if (!err) | |
163 | return; | |
164 | } | |
7dbe63bc | 165 | #endif |
592f9222 | 166 | err = spl_load_image_ext(&mmc->block_dev, |
91199f4a PK |
167 | CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, |
168 | CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); | |
169 | if (!err) | |
170 | return; | |
171 | #endif | |
172 | #endif | |
7dbe63bc | 173 | #ifdef CONFIG_SUPPORT_EMMC_BOOT |
91199f4a | 174 | case MMCSD_MODE_EMMCBOOT: |
7dbe63bc TR |
175 | /* |
176 | * We need to check what the partition is configured to. | |
177 | * 1 and 2 match up to boot0 / boot1 and 7 is user data | |
178 | * which is the first physical partition (0). | |
179 | */ | |
91199f4a | 180 | part = (mmc->part_config >> 3) & PART_ACCESS_MASK; |
7dbe63bc TR |
181 | |
182 | if (part == 7) | |
183 | part = 0; | |
184 | ||
185 | if (mmc_switch_part(0, part)) { | |
186 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT | |
91199f4a | 187 | puts("spl: mmc partition switch failed\n"); |
7dbe63bc TR |
188 | #endif |
189 | hang(); | |
190 | } | |
91199f4a | 191 | |
7dbe63bc | 192 | #ifdef CONFIG_SPL_OS_BOOT |
91199f4a PK |
193 | if (!spl_start_uboot()) { |
194 | err = mmc_load_image_raw_os(mmc); | |
195 | if (!err) | |
196 | return; | |
197 | } | |
7dbe63bc | 198 | #endif |
ecb30139 PK |
199 | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION |
200 | err = mmc_load_image_raw_partition(mmc, | |
201 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); | |
202 | #else | |
b97300b6 | 203 | err = mmc_load_image_raw_sector(mmc, |
7dbe63bc | 204 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); |
ecb30139 | 205 | #endif |
91199f4a PK |
206 | if (!err) |
207 | return; | |
0da113e9 | 208 | #endif |
91199f4a PK |
209 | case MMCSD_MODE_UNDEFINED: |
210 | default: | |
8112f5fa | 211 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT |
91199f4a PK |
212 | if (err) |
213 | puts("spl: mmc: no boot mode left to try\n"); | |
214 | else | |
215 | puts("spl: mmc: wrong boot mode\n"); | |
8112f5fa | 216 | #endif |
79adb7a2 | 217 | hang(); |
91199f4a | 218 | } |
9ea5c6ef | 219 | } |