]> Git Repo - J-u-boot.git/blame - drivers/mmc/fsl_esdhc_spl.c
Merge tag 'xilinx-for-v2024.07-rc1' of https://source.denx.de/u-boot/custodians/u...
[J-u-boot.git] / drivers / mmc / fsl_esdhc_spl.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
bb0dc108
YZ
2/*
3 * Copyright 2013 Freescale Semiconductor, Inc.
bb0dc108
YZ
4 */
5
6#include <common.h>
1eb69ae4 7#include <cpu_func.h>
db41d65a 8#include <hang.h>
bb0dc108
YZ
9#include <mmc.h>
10#include <malloc.h>
11
65cc0e2a 12#ifndef CFG_SYS_MMC_U_BOOT_OFFS
5a428e75
T
13extern uchar mmc_u_boot_offs[];
14#endif
15
bb0dc108
YZ
16/*
17 * The environment variables are written to just after the u-boot image
18 * on SDCard, so we must read the MBR to get the start address and code
19 * length of the u-boot image, then calculate the address of the env.
20 */
0f58f033
T
21#define ESDHC_BOOT_SIGNATURE_OFF 0x40
22#define ESDHC_BOOT_SIGNATURE 0x424f4f54
bb0dc108
YZ
23#define ESDHC_BOOT_IMAGE_SIZE 0x48
24#define ESDHC_BOOT_IMAGE_ADDR 0x50
25#define MBRDBR_BOOT_SIG_55 0x1fe
26#define MBRDBR_BOOT_SIG_AA 0x1ff
bb0dc108 27
1eaa742d
PK
28
29void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
30{
31 uint blk_start, blk_cnt, err;
32
33 struct mmc *mmc = find_mmc_device(0);
34 if (!mmc) {
35 puts("spl: mmc device not found!!\n");
36 hang();
37 }
38
39 if (mmc_init(mmc)) {
40 puts("MMC init failed\n");
41 return;
42 }
43
44 blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
45 blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
46
7c4213f6
SW
47 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
48 vdst);
1eaa742d
PK
49 if (err != blk_cnt) {
50 puts("spl: mmc read failed!!\n");
51 hang();
52 }
53}
54
bb0dc108
YZ
55/*
56 * The main entry for mmc booting. It's necessary that SDRAM is already
57 * configured and available since this code loads the main U-Boot image
58 * from mmc into SDRAM and starts it from there.
59 */
60
61void __noreturn mmc_boot(void)
62{
63 __attribute__((noreturn)) void (*uboot)(void);
64 uint blk_start, blk_cnt, err;
bb0dc108 65 uchar *tmp_buf;
613ab32c 66 u32 blklen;
0980cbba 67 u32 blk_off;
04e9cd7a 68#ifndef CONFIG_FSL_CORENET
bb0dc108 69 uchar val;
0f58f033
T
70#ifndef CONFIG_SPL_FSL_PBL
71 u32 val32;
72#endif
bb0dc108 73 uint i, byte_num;
0980cbba 74 u32 sector;
613ab32c 75#endif
bb0dc108
YZ
76 u32 offset, code_len;
77 struct mmc *mmc;
78
79 mmc = find_mmc_device(0);
80 if (!mmc) {
81 puts("spl: mmc device not found!!\n");
82 hang();
83 }
84
57d527e7
T
85 if (mmc_init(mmc)) {
86 puts("spl: mmc device init failed!\n");
87 hang();
88 }
89
bb0dc108 90 blklen = mmc->read_bl_len;
0980cbba
T
91 if (blklen < 512)
92 blklen = 512;
bb0dc108
YZ
93 tmp_buf = malloc(blklen);
94 if (!tmp_buf) {
95 puts("spl: malloc memory failed!!\n");
96 hang();
97 }
0980cbba 98
04e9cd7a 99#ifdef CONFIG_FSL_CORENET
65cc0e2a 100 offset = CFG_SYS_MMC_U_BOOT_OFFS;
04e9cd7a 101#else
0980cbba
T
102 sector = 0;
103again:
bb0dc108
YZ
104 memset(tmp_buf, 0, blklen);
105
106 /*
107 * Read source addr from sd card
108 */
0980cbba
T
109 blk_start = (sector * 512) / mmc->read_bl_len;
110 blk_off = (sector * 512) % mmc->read_bl_len;
111 blk_cnt = DIV_ROUND_UP(512, mmc->read_bl_len);
112 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, tmp_buf);
c1abf765 113 if (err != blk_cnt) {
bb0dc108 114 puts("spl: mmc read failed!!\n");
bb0dc108
YZ
115 hang();
116 }
117
0f58f033 118#ifdef CONFIG_SPL_FSL_PBL
0980cbba 119 val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_55);
bb0dc108 120 if (0x55 != val) {
0f58f033 121 puts("spl: mmc MBR/DBR signature is not valid!!\n");
bb0dc108
YZ
122 hang();
123 }
0980cbba 124 val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_AA);
bb0dc108 125 if (0xAA != val) {
0f58f033 126 puts("spl: mmc MBR/DBR signature is not valid!!\n");
bb0dc108
YZ
127 hang();
128 }
0f58f033
T
129#else
130 /*
131 * Booting from On-Chip ROM (eSDHC or eSPI), Document Number: AN3659, Rev. 2, 06/2012.
132 * Pre-PBL BootROMs (MPC8536E, MPC8569E, P2020, P1011, P1012, P1013, P1020, P1021, P1022)
133 * require custom BOOT signature on sector 0 and MBR/DBR signature is not required at all.
134 */
135 byte_num = 4;
136 val32 = 0;
137 for (i = 0; i < byte_num; i++) {
0980cbba 138 val = *(tmp_buf + blk_off + ESDHC_BOOT_SIGNATURE_OFF + i);
0f58f033
T
139 val32 = (val32 << 8) + val;
140 }
141 if (val32 != ESDHC_BOOT_SIGNATURE) {
0980cbba
T
142 /* BOOT signature may be on the first 24 sectors (each being 512 bytes) */
143 if (++sector < 24)
144 goto again;
0f58f033
T
145 puts("spl: mmc BOOT signature is not valid!!\n");
146 hang();
147 }
148#endif
bb0dc108
YZ
149
150 byte_num = 4;
151 offset = 0;
152 for (i = 0; i < byte_num; i++) {
0980cbba 153 val = *(tmp_buf + blk_off + ESDHC_BOOT_IMAGE_ADDR + i);
bb0dc108
YZ
154 offset = (offset << 8) + val;
155 }
65cc0e2a 156#ifndef CFG_SYS_MMC_U_BOOT_OFFS
5a428e75
T
157 offset += (ulong)&mmc_u_boot_offs - CONFIG_SPL_TEXT_BASE;
158#else
65cc0e2a 159 offset += CFG_SYS_MMC_U_BOOT_OFFS;
5a428e75 160#endif
a91998d8 161#endif
bb0dc108
YZ
162 /*
163 * Load U-Boot image from mmc into RAM
164 */
65cc0e2a 165 code_len = CFG_SYS_MMC_U_BOOT_SIZE;
04e9cd7a
T
166 blk_start = offset / mmc->read_bl_len;
167 blk_off = offset % mmc->read_bl_len;
168 blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len + 1;
169 if (blk_off) {
170 err = mmc->block_dev.block_read(&mmc->block_dev,
171 blk_start, 1, tmp_buf);
172 if (err != 1) {
173 puts("spl: mmc read failed!!\n");
174 hang();
175 }
176 blk_start++;
177 }
7c4213f6 178 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
65cc0e2a 179 (uchar *)CFG_SYS_MMC_U_BOOT_DST +
04e9cd7a 180 (blk_off ? (mmc->read_bl_len - blk_off) : 0));
bb0dc108
YZ
181 if (err != blk_cnt) {
182 puts("spl: mmc read failed!!\n");
183 free(tmp_buf);
184 hang();
185 }
04e9cd7a
T
186 /*
187 * SDHC DMA may erase bytes at dst + bl_len - blk_off - 8
188 * due to unaligned access. So copy leading bytes from tmp_buf
189 * after SDHC DMA transfer.
190 */
191 if (blk_off)
65cc0e2a 192 memcpy((uchar *)CFG_SYS_MMC_U_BOOT_DST,
04e9cd7a 193 tmp_buf + blk_off, mmc->read_bl_len - blk_off);
bb0dc108
YZ
194
195 /*
196 * Clean d-cache and invalidate i-cache, to
197 * make sure that no stale data is executed.
198 */
65cc0e2a 199 flush_cache(CFG_SYS_MMC_U_BOOT_DST, CFG_SYS_MMC_U_BOOT_SIZE);
bb0dc108
YZ
200
201 /*
202 * Jump to U-Boot image
203 */
65cc0e2a 204 uboot = (void *)CFG_SYS_MMC_U_BOOT_START;
bb0dc108
YZ
205 (*uboot)();
206}
This page took 0.444178 seconds and 4 git commands to generate.