]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/spl/spl_spi.c
Prepare for multiple bootcount drivers
[people/ms/u-boot.git] / common / spl / spl_spi.c
CommitLineData
32b11273
CR
1/*
2 * Copyright (C) 2011 OMICRON electronics GmbH
3 *
4 * based on drivers/mtd/nand/nand_spl_load.c
5 *
6 * Copyright (C) 2011
7 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
8 *
1a459660 9 * SPDX-License-Identifier: GPL-2.0+
32b11273
CR
10 */
11
12#include <common.h>
ff0960f9 13#include <spi.h>
32b11273 14#include <spi_flash.h>
36afd451 15#include <errno.h>
a4cc1c48 16#include <spl.h>
32b11273 17
2bac55bc
PT
18DECLARE_GLOBAL_DATA_PTR;
19
fa1a73fa
TR
20#ifdef CONFIG_SPL_OS_BOOT
21/*
22 * Load the kernel, check for a valid header we can parse, and if found load
23 * the kernel and then device tree.
24 */
2a2ee2ac
SG
25static int spi_load_image_os(struct spl_image_info *spl_image,
26 struct spi_flash *flash,
fa1a73fa
TR
27 struct image_header *header)
28{
7e0f2267
MV
29 int err;
30
fa1a73fa
TR
31 /* Read for a header, parse or error out. */
32 spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
33 (void *)header);
34
35 if (image_get_magic(header) != IH_MAGIC)
36 return -1;
37
2a2ee2ac 38 err = spl_parse_image_header(spl_image, header);
7e0f2267
MV
39 if (err)
40 return err;
fa1a73fa
TR
41
42 spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
2a2ee2ac 43 spl_image->size, (void *)spl_image->load_addr);
fa1a73fa
TR
44
45 /* Read device tree. */
46 spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
47 CONFIG_SYS_SPI_ARGS_SIZE,
48 (void *)CONFIG_SYS_SPL_ARGS_ADDR);
49
50 return 0;
51}
52#endif
53
00d55956
LV
54static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
55 ulong count, void *buf)
56{
57 struct spi_flash *flash = load->dev;
58 ulong ret;
59
60 ret = spi_flash_read(flash, sector, count, buf);
61 if (!ret)
62 return count;
63 else
64 return 0;
65}
32b11273
CR
66/*
67 * The main entry for SPI booting. It's necessary that SDRAM is already
68 * configured and available since this code loads the main U-Boot image
69 * from SPI into SDRAM and starts it from there.
70 */
2a2ee2ac
SG
71static int spl_spi_load_image(struct spl_image_info *spl_image,
72 struct spl_boot_device *bootdev)
32b11273 73{
36afd451 74 int err = 0;
2bac55bc 75 unsigned payload_offs = CONFIG_SYS_SPI_U_BOOT_OFFS;
32b11273 76 struct spi_flash *flash;
a4cc1c48 77 struct image_header *header;
32b11273
CR
78
79 /*
80 * Load U-Boot image from SPI flash into RAM
81 */
82
88e34e5f
NK
83 flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
84 CONFIG_SF_DEFAULT_CS,
85 CONFIG_SF_DEFAULT_SPEED,
86 CONFIG_SF_DEFAULT_MODE);
32b11273 87 if (!flash) {
a4cc1c48 88 puts("SPI probe failed.\n");
36afd451 89 return -ENODEV;
32b11273
CR
90 }
91
a4cc1c48
TR
92 /* use CONFIG_SYS_TEXT_BASE as temporary storage area */
93 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
32b11273 94
2bac55bc
PT
95#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
96 payload_offs = fdtdec_get_config_int(gd->fdt_blob,
97 "u-boot,spl-payload-offset",
98 payload_offs);
99#endif
100
fa1a73fa 101#ifdef CONFIG_SPL_OS_BOOT
2a2ee2ac 102 if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header))
fa1a73fa
TR
103#endif
104 {
105 /* Load u-boot, mkimage header is 64 bytes. */
2bac55bc 106 err = spi_flash_read(flash, payload_offs, 0x40,
36afd451 107 (void *)header);
a7044900
SG
108 if (err) {
109 debug("%s: Failed to read from SPI flash (err=%d)\n",
110 __func__, err);
36afd451 111 return err;
a7044900 112 }
36afd451 113
f72250e7 114 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
115 image_get_magic(header) == FDT_MAGIC) {
00d55956
LV
116 struct spl_load_info load;
117
118 debug("Found FIT\n");
119 load.dev = flash;
120 load.priv = NULL;
121 load.filename = NULL;
122 load.bl_len = 1;
123 load.read = spl_spi_fit_read;
f4d7d859 124 err = spl_load_simple_fit(spl_image, &load,
2bac55bc 125 payload_offs,
00d55956
LV
126 header);
127 } else {
2a2ee2ac 128 err = spl_parse_image_header(spl_image, header);
00d55956
LV
129 if (err)
130 return err;
2bac55bc 131 err = spi_flash_read(flash, payload_offs,
2a2ee2ac
SG
132 spl_image->size,
133 (void *)spl_image->load_addr);
00d55956 134 }
fa1a73fa 135 }
36afd451
NK
136
137 return err;
32b11273 138}
139db7af 139/* Use priorty 1 so that boards can override this */
ebc4ef61 140SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image);