xref: /rk3399_rockchip-uboot/common/spl/spl_mmc.c (revision 8112f5fa1be9a2344a09edf25ca00f5abaf874bb)
1ade8a1a6SYing Zhang /*
2ade8a1a6SYing Zhang  * (C) Copyright 2010
3ade8a1a6SYing Zhang  * Texas Instruments, <www.ti.com>
4ade8a1a6SYing Zhang  *
5ade8a1a6SYing Zhang  * Aneesh V <aneesh@ti.com>
6ade8a1a6SYing Zhang  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
8ade8a1a6SYing Zhang  */
9ade8a1a6SYing Zhang #include <common.h>
10ade8a1a6SYing Zhang #include <spl.h>
11ade8a1a6SYing Zhang #include <asm/u-boot.h>
12ade8a1a6SYing Zhang #include <mmc.h>
13ade8a1a6SYing Zhang #include <fat.h>
14ade8a1a6SYing Zhang #include <version.h>
15e4c444b3STom Rini #include <image.h>
16ade8a1a6SYing Zhang 
17ade8a1a6SYing Zhang DECLARE_GLOBAL_DATA_PTR;
18ade8a1a6SYing Zhang 
19721931f8SPeter Korsgaard static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
20ade8a1a6SYing Zhang {
21ade8a1a6SYing Zhang 	unsigned long err;
22ade8a1a6SYing Zhang 	u32 image_size_sectors;
23ade8a1a6SYing Zhang 	struct image_header *header;
24ade8a1a6SYing Zhang 
25ade8a1a6SYing Zhang 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
26ade8a1a6SYing Zhang 						sizeof(struct image_header));
27ade8a1a6SYing Zhang 
28ade8a1a6SYing Zhang 	/* read image header to find the image size & load address */
29721931f8SPeter Korsgaard 	err = mmc->block_dev.block_read(0, sector, 1, header);
30ade8a1a6SYing Zhang 	if (err == 0)
31ade8a1a6SYing Zhang 		goto end;
32ade8a1a6SYing Zhang 
33e4c444b3STom Rini 	if (image_get_magic(header) != IH_MAGIC)
34e4c444b3STom Rini 		return -1;
35e4c444b3STom Rini 
36ade8a1a6SYing Zhang 	spl_parse_image_header(header);
37ade8a1a6SYing Zhang 
38ade8a1a6SYing Zhang 	/* convert size to sectors - round up */
39ade8a1a6SYing Zhang 	image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
40ade8a1a6SYing Zhang 				mmc->read_bl_len;
41ade8a1a6SYing Zhang 
42ade8a1a6SYing Zhang 	/* Read the header too to avoid extra memcpy */
43721931f8SPeter Korsgaard 	err = mmc->block_dev.block_read(0, sector, image_size_sectors,
44721931f8SPeter Korsgaard 					(void *)spl_image.load_addr);
45ade8a1a6SYing Zhang 
46ade8a1a6SYing Zhang end:
47*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
4879adb7a2SPeter Korsgaard 	if (err == 0)
49ade8a1a6SYing Zhang 		printf("spl: mmc blk read err - %lu\n", err);
50*8112f5faSPaul Burton #endif
5179adb7a2SPeter Korsgaard 
5279adb7a2SPeter Korsgaard 	return (err == 0);
53ade8a1a6SYing Zhang }
54ade8a1a6SYing Zhang 
552b75b0adSPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
562b75b0adSPeter Korsgaard static int mmc_load_image_raw_os(struct mmc *mmc)
572b75b0adSPeter Korsgaard {
582b75b0adSPeter Korsgaard 	if (!mmc->block_dev.block_read(0,
592b75b0adSPeter Korsgaard 				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
602b75b0adSPeter Korsgaard 				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
612b75b0adSPeter Korsgaard 				       (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
62*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
632b75b0adSPeter Korsgaard 		printf("mmc args blk read error\n");
64*8112f5faSPaul Burton #endif
652b75b0adSPeter Korsgaard 		return -1;
662b75b0adSPeter Korsgaard 	}
672b75b0adSPeter Korsgaard 
682b75b0adSPeter Korsgaard 	return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
692b75b0adSPeter Korsgaard }
702b75b0adSPeter Korsgaard #endif
712b75b0adSPeter Korsgaard 
72ade8a1a6SYing Zhang #ifdef CONFIG_SPL_FAT_SUPPORT
732fabd0bcSPeter Korsgaard static int mmc_load_image_fat(struct mmc *mmc, const char *filename)
74ade8a1a6SYing Zhang {
75ade8a1a6SYing Zhang 	int err;
76ade8a1a6SYing Zhang 	struct image_header *header;
77ade8a1a6SYing Zhang 
78ade8a1a6SYing Zhang 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
79ade8a1a6SYing Zhang 						sizeof(struct image_header));
80ade8a1a6SYing Zhang 
812fabd0bcSPeter Korsgaard 	err = file_fat_read(filename, header, sizeof(struct image_header));
82ade8a1a6SYing Zhang 	if (err <= 0)
83ade8a1a6SYing Zhang 		goto end;
84ade8a1a6SYing Zhang 
85ade8a1a6SYing Zhang 	spl_parse_image_header(header);
86ade8a1a6SYing Zhang 
872fabd0bcSPeter Korsgaard 	err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
88ade8a1a6SYing Zhang 
89ade8a1a6SYing Zhang end:
90*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
9179adb7a2SPeter Korsgaard 	if (err <= 0)
92ade8a1a6SYing Zhang 		printf("spl: error reading image %s, err - %d\n",
932fabd0bcSPeter Korsgaard 		       filename, err);
94*8112f5faSPaul Burton #endif
9579adb7a2SPeter Korsgaard 
9679adb7a2SPeter Korsgaard 	return (err <= 0);
97ade8a1a6SYing Zhang }
987ad2cc79SPeter Korsgaard 
997ad2cc79SPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
1007ad2cc79SPeter Korsgaard static int mmc_load_image_fat_os(struct mmc *mmc)
1017ad2cc79SPeter Korsgaard {
1027ad2cc79SPeter Korsgaard 	int err;
1037ad2cc79SPeter Korsgaard 
1047ad2cc79SPeter Korsgaard 	err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME,
1057ad2cc79SPeter Korsgaard 			    (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
1067ad2cc79SPeter Korsgaard 	if (err <= 0) {
107*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1087ad2cc79SPeter Korsgaard 		printf("spl: error reading image %s, err - %d\n",
1097ad2cc79SPeter Korsgaard 		       CONFIG_SPL_FAT_LOAD_ARGS_NAME, err);
110*8112f5faSPaul Burton #endif
1117ad2cc79SPeter Korsgaard 		return -1;
1127ad2cc79SPeter Korsgaard 	}
1137ad2cc79SPeter Korsgaard 
1147ad2cc79SPeter Korsgaard 	return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME);
1157ad2cc79SPeter Korsgaard }
1167ad2cc79SPeter Korsgaard #endif
1177ad2cc79SPeter Korsgaard 
118ade8a1a6SYing Zhang #endif
119ade8a1a6SYing Zhang 
120ade8a1a6SYing Zhang void spl_mmc_load_image(void)
121ade8a1a6SYing Zhang {
122ade8a1a6SYing Zhang 	struct mmc *mmc;
123ade8a1a6SYing Zhang 	int err;
124ade8a1a6SYing Zhang 	u32 boot_mode;
125ade8a1a6SYing Zhang 
126ade8a1a6SYing Zhang 	mmc_initialize(gd->bd);
127ade8a1a6SYing Zhang 	/* We register only one device. So, the dev id is always 0 */
128ade8a1a6SYing Zhang 	mmc = find_mmc_device(0);
129ade8a1a6SYing Zhang 	if (!mmc) {
130*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
131ade8a1a6SYing Zhang 		puts("spl: mmc device not found!!\n");
132*8112f5faSPaul Burton #endif
133ade8a1a6SYing Zhang 		hang();
134ade8a1a6SYing Zhang 	}
135ade8a1a6SYing Zhang 
136ade8a1a6SYing Zhang 	err = mmc_init(mmc);
137ade8a1a6SYing Zhang 	if (err) {
138*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
139ade8a1a6SYing Zhang 		printf("spl: mmc init failed: err - %d\n", err);
140*8112f5faSPaul Burton #endif
141ade8a1a6SYing Zhang 		hang();
142ade8a1a6SYing Zhang 	}
14379adb7a2SPeter Korsgaard 
144ade8a1a6SYing Zhang 	boot_mode = spl_boot_mode();
145ade8a1a6SYing Zhang 	if (boot_mode == MMCSD_MODE_RAW) {
146ade8a1a6SYing Zhang 		debug("boot mode - RAW\n");
1472b75b0adSPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
1482b75b0adSPeter Korsgaard 		if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
1492b75b0adSPeter Korsgaard #endif
150721931f8SPeter Korsgaard 		err = mmc_load_image_raw(mmc,
151721931f8SPeter Korsgaard 					 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
152ade8a1a6SYing Zhang #ifdef CONFIG_SPL_FAT_SUPPORT
153ade8a1a6SYing Zhang 	} else if (boot_mode == MMCSD_MODE_FAT) {
154ade8a1a6SYing Zhang 		debug("boot mode - FAT\n");
1552fabd0bcSPeter Korsgaard 
1562fabd0bcSPeter Korsgaard 		err = fat_register_device(&mmc->block_dev,
1572fabd0bcSPeter Korsgaard 					  CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
1582fabd0bcSPeter Korsgaard 		if (err) {
159*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1602fabd0bcSPeter Korsgaard 			printf("spl: fat register err - %d\n", err);
161*8112f5faSPaul Burton #endif
1622fabd0bcSPeter Korsgaard 			hang();
1632fabd0bcSPeter Korsgaard 		}
1642fabd0bcSPeter Korsgaard 
1657ad2cc79SPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
1667ad2cc79SPeter Korsgaard 		if (spl_start_uboot() || mmc_load_image_fat_os(mmc))
1677ad2cc79SPeter Korsgaard #endif
1682fabd0bcSPeter Korsgaard 		err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
169ade8a1a6SYing Zhang #endif
170ade8a1a6SYing Zhang 	} else {
171*8112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
172ade8a1a6SYing Zhang 		puts("spl: wrong MMC boot mode\n");
173*8112f5faSPaul Burton #endif
174ade8a1a6SYing Zhang 		hang();
175ade8a1a6SYing Zhang 	}
17679adb7a2SPeter Korsgaard 
17779adb7a2SPeter Korsgaard 	if (err)
17879adb7a2SPeter Korsgaard 		hang();
179ade8a1a6SYing Zhang }
180