|
@@ -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 */
|