summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-10-18 09:32:21 -0400
committerTom Rini <trini@konsulko.com>2017-10-18 09:32:21 -0400
commit002e91087c817f8281fccee327e0d8e98c691a2f (patch)
treeb64fb1bd69ee0b7e1cb87663540b1df4e5ca75b1 /drivers
parenteb0044db392247aa1c43e29f2703418d5668018a (diff)
parentca1ac16da097bf0ab176b1a201653553160dc042 (diff)
Merge git://git.denx.de/u-boot-spi
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/spi_flash.c33
-rw-r--r--drivers/mtd/spi/sunxi_spi_spl.c39
2 files changed, 65 insertions, 7 deletions
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 34f68881ed..51e28bf07b 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -113,6 +113,27 @@ static int write_cr(struct spi_flash *flash, u8 wc)
#endif
#ifdef CONFIG_SPI_FLASH_BAR
+/*
+ * This "clean_bar" is necessary in a situation when one was accessing
+ * spi flash memory > 16 MiB by using Bank Address Register's BA24 bit.
+ *
+ * After it the BA24 bit shall be cleared to allow access to correct
+ * memory region after SW reset (by calling "reset" command).
+ *
+ * Otherwise, the BA24 bit may be left set and then after reset, the
+ * ROM would read/write/erase SPL from 16 MiB * bank_sel address.
+ */
+static int clean_bar(struct spi_flash *flash)
+{
+ u8 cmd, bank_sel = 0;
+
+ if (flash->bank_curr == 0)
+ return 0;
+ cmd = flash->bank_write_cmd;
+
+ return spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
+}
+
static int write_bar(struct spi_flash *flash, u32 offset)
{
u8 cmd, bank_sel;
@@ -339,6 +360,10 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
len -= erase_size;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
return ret;
}
@@ -397,6 +422,10 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
offset += chunk_len;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
return ret;
}
@@ -500,6 +529,10 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
data += read_len;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
free(cmd);
return ret;
}
diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c
index 852abd41de..35835c2798 100644
--- a/drivers/mtd/spi/sunxi_spi_spl.c
+++ b/drivers/mtd/spi/sunxi_spi_spl.c
@@ -8,6 +8,7 @@
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <libfdt.h>
#ifdef CONFIG_SPL_OS_BOOT
#error CONFIG_SPL_OS_BOOT is not supported yet
@@ -261,27 +262,51 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
}
}
+static ulong spi_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ spi0_read_data(buf, sector, count);
+
+ return count;
+}
+
/*****************************************************************************/
static int spl_spi_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
- int err;
+ int ret = 0;
struct image_header *header;
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
spi0_init();
spi0_read_data((void *)header, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40);
- err = spl_parse_image_header(spl_image, header);
- if (err)
- return err;
- spi0_read_data((void *)spl_image->load_addr, CONFIG_SYS_SPI_U_BOOT_OFFS,
- spl_image->size);
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT image\n");
+ load.dev = NULL;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+ load.read = spi_load_read;
+ ret = spl_load_simple_fit(spl_image, &load,
+ CONFIG_SYS_SPI_U_BOOT_OFFS, header);
+ } else {
+ ret = spl_parse_image_header(spl_image, header);
+ if (ret)
+ return ret;
+
+ spi0_read_data((void *)spl_image->load_addr,
+ CONFIG_SYS_SPI_U_BOOT_OFFS, spl_image->size);
+ }
spi0_deinit();
- return 0;
+
+ return ret;
}
/* Use priorty 0 to override the default if it happens to be linked in */
SPL_LOAD_IMAGE_METHOD("sunxi SPI", 0, BOOT_DEVICE_SPI, spl_spi_load_image);