Blame view

drivers/mmc/fsl_esdhc_spl.c 3.42 KB
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
1
2
3
  /*
   * Copyright 2013 Freescale Semiconductor, Inc.
   *
bf9025662   York Sun   SPDX-License-Iden...
4
   * SPDX-License-Identifier:	GPL-2.0+
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   */
  
  #include <common.h>
  #include <mmc.h>
  #include <malloc.h>
  
  /*
   * The environment variables are written to just after the u-boot image
   * on SDCard, so we must read the MBR to get the start address and code
   * length of the u-boot image, then calculate the address of the env.
   */
  #define ESDHC_BOOT_IMAGE_SIZE	0x48
  #define ESDHC_BOOT_IMAGE_ADDR	0x50
  #define MBRDBR_BOOT_SIG_55	0x1fe
  #define MBRDBR_BOOT_SIG_AA	0x1ff
  #define CONFIG_CFG_DATA_SECTOR	0
1eaa742d8   Prabhakar Kushwaha   driver: Add suppo...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  
  void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
  {
  	uint blk_start, blk_cnt, err;
  
  	struct mmc *mmc = find_mmc_device(0);
  	if (!mmc) {
  		puts("spl: mmc device not found!!
  ");
  		hang();
  	}
  
  	if (mmc_init(mmc)) {
  		puts("MMC init failed
  ");
  		return;
  	}
  
  	blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
  	blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
7c4213f6a   Stephen Warren   block: pass block...
41
42
  	err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
  					vdst);
1eaa742d8   Prabhakar Kushwaha   driver: Add suppo...
43
44
45
46
47
48
  	if (err != blk_cnt) {
  		puts("spl: mmc read failed!!
  ");
  		hang();
  	}
  }
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
49
50
51
52
53
54
55
56
57
58
  /*
   * The main entry for mmc booting. It's necessary that SDRAM is already
   * configured and available since this code loads the main U-Boot image
   * from mmc into SDRAM and starts it from there.
   */
  
  void __noreturn mmc_boot(void)
  {
  	__attribute__((noreturn)) void (*uboot)(void);
  	uint blk_start, blk_cnt, err;
613ab32c4   Prabhakar Kushwaha   driver/mmc: fix c...
59
  #ifndef CONFIG_FSL_CORENET
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
60
  	uchar *tmp_buf;
613ab32c4   Prabhakar Kushwaha   driver/mmc: fix c...
61
  	u32 blklen;
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
62
63
  	uchar val;
  	uint i, byte_num;
613ab32c4   Prabhakar Kushwaha   driver/mmc: fix c...
64
  #endif
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
65
66
67
68
69
70
71
72
73
  	u32 offset, code_len;
  	struct mmc *mmc;
  
  	mmc = find_mmc_device(0);
  	if (!mmc) {
  		puts("spl: mmc device not found!!
  ");
  		hang();
  	}
4520a2f28   Priyanka Jain   powerpc: mmc: Add...
74
75
76
77
  #ifdef CONFIG_FSL_CORENET
  	offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
  	code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
  #else
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
78
79
80
81
82
83
84
85
86
87
88
89
  	blklen = mmc->read_bl_len;
  	tmp_buf = malloc(blklen);
  	if (!tmp_buf) {
  		puts("spl: malloc memory failed!!
  ");
  		hang();
  	}
  	memset(tmp_buf, 0, blklen);
  
  	/*
  	* Read source addr from sd card
  	*/
7c4213f6a   Stephen Warren   block: pass block...
90
91
  	err = mmc->block_dev.block_read(&mmc->block_dev,
  					CONFIG_CFG_DATA_SECTOR, 1, tmp_buf);
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  	if (err != 1) {
  		puts("spl: mmc read failed!!
  ");
  		free(tmp_buf);
  		hang();
  	}
  
  	val = *(tmp_buf + MBRDBR_BOOT_SIG_55);
  	if (0x55 != val) {
  		puts("spl: mmc signature is not valid!!
  ");
  		free(tmp_buf);
  		hang();
  	}
  	val = *(tmp_buf + MBRDBR_BOOT_SIG_AA);
  	if (0xAA != val) {
  		puts("spl: mmc signature is not valid!!
  ");
  		free(tmp_buf);
  		hang();
  	}
  
  	byte_num = 4;
  	offset = 0;
  	for (i = 0; i < byte_num; i++) {
  		val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i);
  		offset = (offset << 8) + val;
  	}
  	offset += CONFIG_SYS_MMC_U_BOOT_OFFS;
  	/* Get the code size from offset 0x48 */
  	byte_num = 4;
  	code_len = 0;
  	for (i = 0; i < byte_num; i++) {
  		val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i);
  		code_len = (code_len << 8) + val;
  	}
  	code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS;
  	/*
  	* Load U-Boot image from mmc into RAM
  	*/
4520a2f28   Priyanka Jain   powerpc: mmc: Add...
132
  #endif
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
133
134
  	blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
  	blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
7c4213f6a   Stephen Warren   block: pass block...
135
  	err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
136
137
138
139
  					(uchar *)CONFIG_SYS_MMC_U_BOOT_DST);
  	if (err != blk_cnt) {
  		puts("spl: mmc read failed!!
  ");
613ab32c4   Prabhakar Kushwaha   driver/mmc: fix c...
140
  #ifndef CONFIG_FSL_CORENET
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
141
  		free(tmp_buf);
613ab32c4   Prabhakar Kushwaha   driver/mmc: fix c...
142
  #endif
bb0dc1084   Ying Zhang   powerpc: mpc85xx:...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  		hang();
  	}
  
  	/*
  	* Clean d-cache and invalidate i-cache, to
  	* make sure that no stale data is executed.
  	*/
  	flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE);
  
  	/*
  	* Jump to U-Boot image
  	*/
  	uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START;
  	(*uboot)();
  }