From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thomas Chou Date: Sun, 11 Oct 2015 15:30:28 +0800 Subject: [U-Boot] [PATCH v2] dm: implement a cfi flash uclass In-Reply-To: <1444289667-23775-1-git-send-email-thomas@wytron.com.tw> References: <1444289667-23775-1-git-send-email-thomas@wytron.com.tw> Message-ID: <1444548628-10119-1-git-send-email-thomas@wytron.com.tw> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Implement a cfi flash uclass to work with drivers/mtd/cfi-flash.c. The flash base address is extracted from device tree, and passed to cfi_flash_bank_addr(). The current code supports only one bank. It should be extended to support multiple banks by decoding multiple "reg" tuples, eg, reg = <0 0x00000000 0x02000000 0 0x02000000 0x02000000>; Signed-off-by: Thomas Chou --- v2 add dts binding. add more help to Kconfig. move struct platdata to top of file as Simon suggested. common/board_r.c | 3 + configs/nios2-generic_defconfig | 1 + doc/device-tree-bindings/mtd/mtd-physmap.txt | 88 ++++++++++++++++++++++++++++ drivers/mtd/Kconfig | 16 +++++ drivers/mtd/Makefile | 1 + drivers/mtd/cfi-flash-uclass.c | 70 ++++++++++++++++++++++ drivers/mtd/cfi_flash.c | 18 ++++++ include/cfi-flash.h | 27 +++++++++ include/dm/uclass-id.h | 1 + 9 files changed, 225 insertions(+) create mode 100644 doc/device-tree-bindings/mtd/mtd-physmap.txt create mode 100644 drivers/mtd/cfi-flash-uclass.c create mode 100644 include/cfi-flash.h diff --git a/common/board_r.c b/common/board_r.c index a4facf8..fceaea6 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -38,6 +38,7 @@ #include #endif #include +#include #include #include #include @@ -348,6 +349,8 @@ static int initr_flash(void) /* update start of FLASH memory */ #ifdef CONFIG_SYS_FLASH_BASE bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; +#else + bd->bi_flashstart = cfi_flash_bank_addr(0); #endif /* size of FLASH memory (final value) */ bd->bi_flashsize = flash_size; diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig index 3d404b2..7b504ba 100644 --- a/configs/nios2-generic_defconfig +++ b/configs/nios2-generic_defconfig @@ -18,6 +18,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_ALTERA_PIO=y CONFIG_MISC=y CONFIG_ALTERA_SYSID=y +CONFIG_CFI_FLASH=y CONFIG_ALTERA_JTAG_UART=y CONFIG_ALTERA_JTAG_UART_BYPASS=y CONFIG_TIMER=y diff --git a/doc/device-tree-bindings/mtd/mtd-physmap.txt b/doc/device-tree-bindings/mtd/mtd-physmap.txt new file mode 100644 index 0000000..a04d6e8 --- /dev/null +++ b/doc/device-tree-bindings/mtd/mtd-physmap.txt @@ -0,0 +1,88 @@ +CFI or JEDEC memory-mapped NOR flash, MTD-RAM (NVRAM...) + +Flash chips (Memory Technology Devices) are often used for solid state +file systems on embedded devices. + + - compatible : should contain the specific model of mtd chip(s) + used, if known, followed by either "cfi-flash", "jedec-flash", + "mtd-ram" or "mtd-rom". + - reg : Address range(s) of the mtd chip(s) + It's possible to (optionally) define multiple "reg" tuples so that + non-identical chips can be described in one node. + - bank-width : Width (in bytes) of the bank. Equal to the + device width times the number of interleaved chips. + - device-width : (optional) Width of a single mtd chip. If + omitted, assumed to be equal to 'bank-width'. + - #address-cells, #size-cells : Must be present if the device has + sub-nodes representing partitions (see below). In this case + both #address-cells and #size-cells must be equal to 1. + - no-unaligned-direct-access: boolean to disable the default direct + mapping of the flash. + On some platforms (e.g. MPC5200) a direct 1:1 mapping may cause + problems with JFFS2 usage, as the local bus (LPB) doesn't support + unaligned accesses as implemented in the JFFS2 code via memcpy(). + By defining "no-unaligned-direct-access", the flash will not be + exposed directly to the MTD users (e.g. JFFS2) any more. + - linux,mtd-name: allow to specify the mtd name for retro capability with + physmap-flash drivers as boot loader pass the mtd partition via the old + device name physmap-flash. + - use-advanced-sector-protection: boolean to enable support for the + advanced sector protection (Spansion: PPB - Persistent Protection + Bits) locking. + +For JEDEC compatible devices, the following additional properties +are defined: + + - vendor-id : Contains the flash chip's vendor id (1 byte). + - device-id : Contains the flash chip's device id (1 byte). + +For ROM compatible devices (and ROM fallback from cfi-flash), the following +additional (optional) property is defined: + + - erase-size : The chip's physical erase block size in bytes. + +The device tree may optionally contain sub-nodes describing partitions of the +address space. See partition.txt for more detail. + +Example: + + flash at ff000000 { + compatible = "amd,am29lv128ml", "cfi-flash"; + reg = ; + bank-width = <4>; + device-width = <1>; + #address-cells = <1>; + #size-cells = <1>; + fs at 0 { + label = "fs"; + reg = <0 f80000>; + }; + firmware at f80000 { + label ="firmware"; + reg = ; + read-only; + }; + }; + +Here an example with multiple "reg" tuples: + + flash at f0000000,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "intel,PC48F4400P0VB", "cfi-flash"; + reg = <0 0x00000000 0x02000000 + 0 0x02000000 0x02000000>; + bank-width = <2>; + partition at 0 { + label = "test-part1"; + reg = <0 0x04000000>; + }; + }; + +An example using SRAM: + + sram at 2,0 { + compatible = "samsung,k6f1616u6a", "mtd-ram"; + reg = <2 0 0x00200000>; + bank-width = <2>; + }; diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 59278d1..b1addb5 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1,3 +1,19 @@ +menu "CFI Flash Support" + +config CFI_FLASH + bool "Enable Driver Model for CFI Flash driver" + depends on DM + help + The Common Flash Interface specification was developed by Intel, + AMD and other flash manufactures that 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 + for more information on CFI. This driver uses the same API as + drivers/mtd/cfi_flash.c. But now implemented by the uclass. + +endmenu + source "drivers/mtd/nand/Kconfig" source "drivers/mtd/spi/Kconfig" diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index a623f4c..0bcc76c 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -11,6 +11,7 @@ endif obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_HAS_DATAFLASH) += at45.o +obj-$(CONFIG_CFI_FLASH) += cfi-flash-uclass.o obj-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o obj-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o obj-$(CONFIG_HAS_DATAFLASH) += dataflash.o diff --git a/drivers/mtd/cfi-flash-uclass.c b/drivers/mtd/cfi-flash-uclass.c new file mode 100644 index 0000000..62c914b --- /dev/null +++ b/drivers/mtd/cfi-flash-uclass.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 Thomas Chou + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct cfi_flash_platdata { + phys_addr_t base; +}; + +/* + * Implement a cfi flash uclass to work with drivers/mtd/cfi-flash.c. + */ + +phys_addr_t cfi_flash_get_base(struct udevice *dev) +{ + struct cfi_flash_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + return uc_priv->base; +} + +UCLASS_DRIVER(cfi_flash) = { + .id = UCLASS_CFI_FLASH, + .name = "cfi_flash", + .per_device_auto_alloc_size = sizeof(struct cfi_flash_dev_priv), +}; + +static int cfi_flash_probe(struct udevice *dev) +{ + struct cfi_flash_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct cfi_flash_platdata *plat = dev->platdata; + + uc_priv->base = plat->base; + + return 0; +} + +static int cfi_flash_ofdata_to_platdata(struct udevice *dev) +{ + struct cfi_flash_platdata *plat = dev_get_platdata(dev); + fdt_size_t size; + + fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size); + plat->base = (phys_addr_t)ioremap(dev_get_addr(dev), size); + + return 0; +} + +static const struct udevice_id cfi_flash_ids[] = { + { .compatible = "cfi-flash", }, + { } +}; + +U_BOOT_DRIVER(cfi_flash) = { + .name = "cfi_flash", + .id = UCLASS_CFI_FLASH, + .of_match = cfi_flash_ids, + .ofdata_to_platdata = cfi_flash_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct cfi_flash_platdata), + .probe = cfi_flash_probe, +}; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 50983b8..9204596 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -18,6 +18,9 @@ /* #define DEBUG */ #include +#include +#include +#include #include #include #include @@ -87,10 +90,25 @@ 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 +phys_addr_t cfi_flash_bank_addr(int i) +{ + struct udevice *dev; + int ret; + + /* FIXME: the current code supports only one bank */ + ret = uclass_get_device(UCLASS_CFI_FLASH, i, &dev); + if (ret) + return ret; + + return cfi_flash_get_base(dev); +} +#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) { diff --git a/include/cfi-flash.h b/include/cfi-flash.h new file mode 100644 index 0000000..192df97 --- /dev/null +++ b/include/cfi-flash.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Thomas Chou + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CFI_FLASH_H_ +#define _CFI_FLASH_H_ + +/* + * Get the cfi flash base address + * + * @dev: The cfi flash device + * @return: the cfi flash base address + */ +phys_addr_t cfi_flash_get_base(struct udevice *dev); + +/* + * struct cfi_flash_dev_priv - information about a device used by the uclass + * + * @base: the cfi flash base address + */ +struct cfi_flash_dev_priv { + phys_addr_t base; +}; + +#endif /* _CFI_FLASH_H_ */ diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index a6982ab..09e370c 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -25,6 +25,7 @@ enum uclass_id { UCLASS_SIMPLE_BUS, /* bus with child devices */ /* U-Boot uclasses start here - in alphabetical order */ + UCLASS_CFI_FLASH, /* cfi flash */ UCLASS_CLK, /* Clock source, e.g. used by peripherals */ UCLASS_CPU, /* CPU, typically part of an SoC */ UCLASS_CROS_EC, /* Chrome OS EC */ -- 2.1.4