mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
sf: Enable FDT-based configuration and memory mapping
Enable device tree control of SPI flash, and use this to implement memory-mapped SPI flash, which is supported on Intel chips. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
5e6fb69778
commit
bb8215f437
4 changed files with 48 additions and 1 deletions
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
static void spi_flash_addr(u32 addr, u8 *cmd)
|
static void spi_flash_addr(u32 addr, u8 *cmd)
|
||||||
{
|
{
|
||||||
/* cmd[0] is actual command */
|
/* cmd[0] is actual command */
|
||||||
|
@ -146,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
|
||||||
{
|
{
|
||||||
u8 cmd[5];
|
u8 cmd[5];
|
||||||
|
|
||||||
|
/* Handle memory-mapped SPI */
|
||||||
|
if (flash->memory_map)
|
||||||
|
memcpy(data, flash->memory_map + offset, len);
|
||||||
|
|
||||||
cmd[0] = CMD_READ_ARRAY_FAST;
|
cmd[0] = CMD_READ_ARRAY_FAST;
|
||||||
spi_flash_addr(offset, cmd);
|
spi_flash_addr(offset, cmd);
|
||||||
cmd[4] = 0x00;
|
cmd[4] = 0x00;
|
||||||
|
@ -275,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
|
||||||
|
{
|
||||||
|
fdt_addr_t addr;
|
||||||
|
fdt_size_t size;
|
||||||
|
int node;
|
||||||
|
|
||||||
|
/* If there is no node, do nothing */
|
||||||
|
node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
|
||||||
|
if (node < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
|
||||||
|
if (addr == FDT_ADDR_T_NONE) {
|
||||||
|
debug("%s: Cannot decode address\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flash->size != size) {
|
||||||
|
debug("%s: Memory map must cover entire device\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
flash->memory_map = (void *)addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OF_CONTROL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following table holds all device probe functions
|
* The following table holds all device probe functions
|
||||||
*
|
*
|
||||||
|
@ -391,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
|
||||||
goto err_manufacturer_probe;
|
goto err_manufacturer_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
|
||||||
|
debug("SF: FDT decode error\n");
|
||||||
|
goto err_manufacturer_probe;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
printf("SF: Detected %s with page size ", flash->name);
|
printf("SF: Detected %s with page size ", flash->name);
|
||||||
print_size(flash->sector_size, ", total ");
|
print_size(flash->sector_size, ", total ");
|
||||||
print_size(flash->size, "\n");
|
print_size(flash->size, "");
|
||||||
|
if (flash->memory_map)
|
||||||
|
printf(", mapped at %p", flash->memory_map);
|
||||||
|
puts("\n");
|
||||||
|
|
||||||
spi_release_bus(spi);
|
spi_release_bus(spi);
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ enum fdt_compat_id {
|
||||||
COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */
|
COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */
|
||||||
COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */
|
COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */
|
||||||
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
|
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
|
||||||
|
COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
|
||||||
|
|
||||||
COMPAT_COUNT,
|
COMPAT_COUNT,
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct spi_flash {
|
||||||
/* Erase (sector) size */
|
/* Erase (sector) size */
|
||||||
u32 sector_size;
|
u32 sector_size;
|
||||||
|
|
||||||
|
void *memory_map; /* Address of read-only SPI flash access */
|
||||||
int (*read)(struct spi_flash *flash, u32 offset,
|
int (*read)(struct spi_flash *flash, u32 offset,
|
||||||
size_t len, void *buf);
|
size_t len, void *buf);
|
||||||
int (*write)(struct spi_flash *flash, u32 offset,
|
int (*write)(struct spi_flash *flash, u32 offset,
|
||||||
|
|
|
@ -59,6 +59,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
|
||||||
COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
|
COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
|
||||||
COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
|
COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
|
||||||
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
|
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
|
||||||
|
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *fdtdec_get_compatible(enum fdt_compat_id id)
|
const char *fdtdec_get_compatible(enum fdt_compat_id id)
|
||||||
|
|
Loading…
Reference in a new issue