diff options
author | Thomas Chou <thomas@wytron.com.tw> | 2015-11-07 14:31:08 +0800 |
---|---|---|
committer | Thomas Chou <thomas@wytron.com.tw> | 2015-11-12 08:26:58 +0800 |
commit | f1056910434d87051ff8af80a84e248dd1670abb (patch) | |
tree | bf6a6407ffb49e7bc01aa9f1d75cea3961991526 /drivers/mtd | |
parent | d85879938d3fc3557f6ff74a60f95e0975a314ce (diff) | |
download | u-boot-imx-f1056910434d87051ff8af80a84e248dd1670abb.zip u-boot-imx-f1056910434d87051ff8af80a84e248dd1670abb.tar.gz u-boot-imx-f1056910434d87051ff8af80a84e248dd1670abb.tar.bz2 |
cfi_flash: convert to driver model
Convert cfi flash to driver model.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/Kconfig | 11 | ||||
-rw-r--r-- | drivers/mtd/cfi_flash.c | 78 |
2 files changed, 89 insertions, 0 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 23dff48..57e4b86 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -8,6 +8,17 @@ config MTD flash, RAM and similar chips, often used for solid state file systems on embedded devices. +config CFI_FLASH + bool "Enable Driver Model for CFI Flash driver" + depends on MTD + help + The Common Flash Interface specification was developed by Intel, + AMD and other flash manufactures. It provides a universal method + for probing the capabilities of flash devices. If you wish to + support any device that is CFI-compliant, you need to enable this + option. Visit <http://www.amd.com/products/nvd/overview/cfi.html> + for more information on CFI. + endmenu source "drivers/mtd/nand/Kconfig" diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index fc7a878..e3cb598 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -18,6 +18,9 @@ /* #define DEBUG */ #include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdt_support.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/byteorder.h> @@ -47,6 +50,8 @@ * reading and writing ... (yes there is such a Hardware). */ +DECLARE_GLOBAL_DATA_PTR; + static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT }; #ifdef CONFIG_FLASH_CFI_MTD static uint flash_verbose = 1; @@ -87,10 +92,36 @@ static u16 cfi_flash_config_reg(int i) int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT; #endif +#ifdef CONFIG_CFI_FLASH /* for driver model */ +static void cfi_flash_init_dm(void) +{ + struct udevice *dev; + + cfi_flash_num_flash_banks = 0; + /* + * The uclass_first_device() will probe the first device and + * uclass_next_device() will probe the rest if they exist. So + * that cfi_flash_probe() will get called assigning the base + * addresses that are available. + */ + for (uclass_first_device(UCLASS_MTD, &dev); + dev; + uclass_next_device(&dev)) { + } +} + +static phys_addr_t cfi_flash_base[CFI_MAX_FLASH_BANKS]; + +phys_addr_t cfi_flash_bank_addr(int i) +{ + return cfi_flash_base[i]; +} +#else __weak phys_addr_t cfi_flash_bank_addr(int i) { return ((phys_addr_t [])CONFIG_SYS_FLASH_BANKS_LIST)[i]; } +#endif __weak unsigned long cfi_flash_bank_size(int i) { @@ -2322,6 +2353,10 @@ unsigned long flash_init (void) getenv_f("unlock", s, sizeof(s)); #endif +#ifdef CONFIG_CFI_FLASH /* for driver model */ + cfi_flash_init_dm(); +#endif + /* Init: no FLASHes known */ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_UNKNOWN; @@ -2398,3 +2433,46 @@ unsigned long flash_init (void) return (size); } + +#ifdef CONFIG_CFI_FLASH /* for driver model */ +static int cfi_flash_probe(struct udevice *dev) +{ + void *blob = (void *)gd->fdt_blob; + int node = dev->of_offset; + const fdt32_t *cell; + phys_addr_t addr; + int parent, addrc, sizec; + int len, idx; + + parent = fdt_parent_offset(blob, node); + of_bus_default_count_cells(blob, parent, &addrc, &sizec); + /* decode regs, there may be multiple reg tuples. */ + cell = fdt_getprop(blob, node, "reg", &len); + if (!cell) + return -ENOENT; + idx = 0; + len /= sizeof(fdt32_t); + while (idx < len) { + addr = fdt_translate_address((void *)blob, + node, cell + idx); + cfi_flash_base[cfi_flash_num_flash_banks++] = addr; + idx += addrc + sizec; + } + gd->bd->bi_flashstart = cfi_flash_base[0]; + + return 0; +} + +static const struct udevice_id cfi_flash_ids[] = { + { .compatible = "cfi-flash" }, + { .compatible = "jedec-flash" }, + {} +}; + +U_BOOT_DRIVER(cfi_flash) = { + .name = "cfi_flash", + .id = UCLASS_MTD, + .of_match = cfi_flash_ids, + .probe = cfi_flash_probe, +}; +#endif /* CONFIG_CFI_FLASH */ |