Merge git://git.denx.de/u-boot-nand-flash
This commit is contained in:
commit
fd42e1b589
@ -241,6 +241,20 @@
|
||||
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
|
||||
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
|
||||
};
|
||||
|
||||
nand_cs2_pins_a: nand_cs@2 {
|
||||
allwinner,pins = "PC17";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
nand_cs3_pins_a: nand_cs@3 {
|
||||
allwinner,pins = "PC18";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&sram_a {
|
||||
|
@ -155,6 +155,21 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&nfc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
|
||||
status = "okay";
|
||||
|
||||
nand@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
reg = <0>;
|
||||
allwinner,rb = <0>;
|
||||
nand-ecc-mode = "hw";
|
||||
allwinner,randomize;
|
||||
};
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -142,6 +142,21 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&nfc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
|
||||
status = "okay";
|
||||
|
||||
nand@0 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
reg = <0>;
|
||||
allwinner,rb = <0>;
|
||||
nand-ecc-mode = "hw";
|
||||
nand-on-flash-bbt;
|
||||
};
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -356,6 +356,17 @@
|
||||
#dma-cells = <2>;
|
||||
};
|
||||
|
||||
nfc: nand@01c03000 {
|
||||
compatible = "allwinner,sun4i-a10-nand";
|
||||
reg = <0x01c03000 0x1000>;
|
||||
interrupts = <37>;
|
||||
clocks = <&ahb_gates 13>, <&nand_clk>;
|
||||
clock-names = "ahb", "mod";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi0: spi@01c05000 {
|
||||
compatible = "allwinner,sun4i-a10-spi";
|
||||
reg = <0x01c05000 0x1000>;
|
||||
@ -548,6 +559,44 @@
|
||||
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
|
||||
};
|
||||
|
||||
nand_pins_a: nand_base0@0 {
|
||||
allwinner,pins = "PC0", "PC1", "PC2",
|
||||
"PC5", "PC8", "PC9", "PC10",
|
||||
"PC11", "PC12", "PC13", "PC14",
|
||||
"PC15";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
nand_cs0_pins_a: nand_cs@0 {
|
||||
allwinner,pins = "PC4";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
nand_cs1_pins_a: nand_cs@1 {
|
||||
allwinner,pins = "PC3";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
nand_rb0_pins_a: nand_rb@0 {
|
||||
allwinner,pins = "PC6";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
nand_rb1_pins_a: nand_rb@1 {
|
||||
allwinner,pins = "PC7";
|
||||
allwinner,function = "nand0";
|
||||
allwinner,drive = <0>;
|
||||
allwinner,pull = <0>;
|
||||
};
|
||||
|
||||
uart3_pins_a: uart3@0 {
|
||||
allwinner,pins = "PG9", "PG10";
|
||||
allwinner,function = "uart3";
|
||||
|
@ -269,6 +269,11 @@ struct sunxi_ccm_reg {
|
||||
#define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2
|
||||
#define CCM_MBUS_CTRL_GATE (0x1 << 31)
|
||||
|
||||
#define CCM_NAND_CTRL_M(x) ((x) - 1)
|
||||
#define CCM_NAND_CTRL_N(x) ((x) << 16)
|
||||
#define CCM_NAND_CTRL_OSCM24 (0x0 << 24)
|
||||
#define CCM_NAND_CTRL_PLL6 (0x1 << 24)
|
||||
#define CCM_NAND_CTRL_PLL5 (0x2 << 24)
|
||||
#define CCM_NAND_CTRL_ENABLE (0x1 << 31)
|
||||
|
||||
#define CCM_MMC_CTRL_M(x) ((x) - 1)
|
||||
|
@ -136,7 +136,7 @@ int dram_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
|
||||
#if defined(CONFIG_NAND_SUNXI)
|
||||
static void nand_pinmux_setup(void)
|
||||
{
|
||||
unsigned int pin;
|
||||
@ -173,6 +173,9 @@ void board_nand_init(void)
|
||||
{
|
||||
nand_pinmux_setup();
|
||||
nand_clock_setup();
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
sunxi_nand_init();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1493,7 +1493,7 @@ static int spread_partitions(void)
|
||||
part = list_entry(pentry, struct part_info, link);
|
||||
|
||||
debug("spread_partitions: device = %s%d, partition %d ="
|
||||
" (%s) 0x%08x@0x%08x\n",
|
||||
" (%s) 0x%08llx@0x%08llx\n",
|
||||
MTD_DEV_TYPE(dev->id->type), dev->id->num,
|
||||
part_num, part->name, part->size,
|
||||
part->offset);
|
||||
@ -2025,7 +2025,7 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
|
||||
if (!strcmp(&argv[1][3], ".spread")) {
|
||||
spread_partition(mtd, p, &next_offset);
|
||||
debug("increased %s to %d bytes\n", p->name, p->size);
|
||||
debug("increased %s to %llu bytes\n", p->name, p->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
15
cmd/nand.c
15
cmd/nand.c
@ -306,7 +306,7 @@ static void nand_print_and_set_info(int idx)
|
||||
}
|
||||
|
||||
static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
|
||||
ulong count, int read)
|
||||
ulong count, int read, int no_verify)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@ -324,7 +324,7 @@ static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
|
||||
ret = mtd_read_oob(mtd, off, &ops);
|
||||
} else {
|
||||
ret = mtd_write_oob(mtd, off, &ops);
|
||||
if (!ret)
|
||||
if (!ret && !no_verify)
|
||||
ret = nand_verify_page_oob(mtd, &ops, off);
|
||||
}
|
||||
|
||||
@ -546,6 +546,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
ulong pagecount = 1;
|
||||
int read;
|
||||
int raw = 0;
|
||||
int no_verify = 0;
|
||||
|
||||
if (argc < 4)
|
||||
goto usage;
|
||||
@ -557,9 +558,12 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
|
||||
s = strchr(cmd, '.');
|
||||
|
||||
if (s && !strcmp(s, ".raw")) {
|
||||
if (s && !strncmp(s, ".raw", 4)) {
|
||||
raw = 1;
|
||||
|
||||
if (!strcmp(s, ".raw.noverify"))
|
||||
no_verify = 1;
|
||||
|
||||
if (mtd_arg_off(argv[3], &dev, &off, &size, &maxsize,
|
||||
MTD_DEV_TYPE_NAND,
|
||||
nand_info[dev]->size))
|
||||
@ -633,7 +637,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
else
|
||||
ret = mtd_write_oob(mtd, off, &ops);
|
||||
} else if (raw) {
|
||||
ret = raw_access(mtd, addr, off, pagecount, read);
|
||||
ret = raw_access(mtd, addr, off, pagecount, read,
|
||||
no_verify);
|
||||
} else {
|
||||
printf("Unknown nand command suffix '%s'.\n", s);
|
||||
return 1;
|
||||
@ -786,7 +791,7 @@ static char nand_help_text[] =
|
||||
" read/write 'size' bytes starting at offset 'off'\n"
|
||||
" to/from memory address 'addr', skipping bad blocks.\n"
|
||||
"nand read.raw - addr off|partition [count]\n"
|
||||
"nand write.raw - addr off|partition [count]\n"
|
||||
"nand write.raw[.noverify] - addr off|partition [count]\n"
|
||||
" Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
|
||||
#ifdef CONFIG_CMD_NAND_TRIMFFS
|
||||
"nand write.trimffs - addr off|partition size\n"
|
||||
|
@ -64,12 +64,14 @@ config NAND_PXA3XX
|
||||
PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
|
||||
|
||||
config NAND_SUNXI
|
||||
bool "Support for NAND on Allwinner SoCs in SPL"
|
||||
bool "Support for NAND on Allwinner SoCs"
|
||||
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
|
||||
select SYS_NAND_SELF_INIT
|
||||
---help---
|
||||
Enable support for NAND. This option allows SPL to read from
|
||||
sunxi NAND using DMA transfers.
|
||||
Enable support for NAND. This option enables the standard and
|
||||
SPL drivers.
|
||||
The SPL driver only supports reading from the NAND using DMA
|
||||
transfers.
|
||||
|
||||
config NAND_ARASAN
|
||||
bool "Configure Arasan Nand"
|
||||
|
@ -66,6 +66,7 @@ obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
|
||||
obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
|
||||
obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
|
||||
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
|
||||
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
|
||||
|
||||
else # minimal SPL drivers
|
||||
|
||||
|
@ -29,6 +29,9 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
#include <common.h>
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
#include <fdtdec.h>
|
||||
#endif
|
||||
#include <malloc.h>
|
||||
#include <watchdog.h>
|
||||
#include <linux/err.h>
|
||||
@ -2411,7 +2414,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
|
||||
int cached = writelen > bytes && page != blockmask;
|
||||
uint8_t *wbuf = buf;
|
||||
int use_bufpoi;
|
||||
int part_pagewr = (column || writelen < (mtd->writesize - 1));
|
||||
int part_pagewr = (column || writelen < mtd->writesize);
|
||||
|
||||
if (part_pagewr)
|
||||
use_bufpoi = 1;
|
||||
@ -3763,6 +3766,66 @@ ident_done:
|
||||
return type;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
|
||||
{
|
||||
int ret, ecc_mode = -1, ecc_strength, ecc_step;
|
||||
const void *blob = gd->fdt_blob;
|
||||
const char *str;
|
||||
|
||||
ret = fdtdec_get_int(blob, node, "nand-bus-width", -1);
|
||||
if (ret == 16)
|
||||
chip->options |= NAND_BUSWIDTH_16;
|
||||
|
||||
if (fdtdec_get_bool(blob, node, "nand-on-flash-bbt"))
|
||||
chip->bbt_options |= NAND_BBT_USE_FLASH;
|
||||
|
||||
str = fdt_getprop(blob, node, "nand-ecc-mode", NULL);
|
||||
if (str) {
|
||||
if (!strcmp(str, "none"))
|
||||
ecc_mode = NAND_ECC_NONE;
|
||||
else if (!strcmp(str, "soft"))
|
||||
ecc_mode = NAND_ECC_SOFT;
|
||||
else if (!strcmp(str, "hw"))
|
||||
ecc_mode = NAND_ECC_HW;
|
||||
else if (!strcmp(str, "hw_syndrome"))
|
||||
ecc_mode = NAND_ECC_HW_SYNDROME;
|
||||
else if (!strcmp(str, "hw_oob_first"))
|
||||
ecc_mode = NAND_ECC_HW_OOB_FIRST;
|
||||
else if (!strcmp(str, "soft_bch"))
|
||||
ecc_mode = NAND_ECC_SOFT_BCH;
|
||||
}
|
||||
|
||||
|
||||
ecc_strength = fdtdec_get_int(blob, node, "nand-ecc-strength", -1);
|
||||
ecc_step = fdtdec_get_int(blob, node, "nand-ecc-step-size", -1);
|
||||
|
||||
if ((ecc_step >= 0 && !(ecc_strength >= 0)) ||
|
||||
(!(ecc_step >= 0) && ecc_strength >= 0)) {
|
||||
pr_err("must set both strength and step size in DT\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ecc_mode >= 0)
|
||||
chip->ecc.mode = ecc_mode;
|
||||
|
||||
if (ecc_strength >= 0)
|
||||
chip->ecc.strength = ecc_strength;
|
||||
|
||||
if (ecc_step > 0)
|
||||
chip->ecc.size = ecc_step;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
|
||||
|
||||
/**
|
||||
* nand_scan_ident - [NAND Interface] Scan for the NAND device
|
||||
* @mtd: MTD device structure
|
||||
@ -3779,6 +3842,13 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
|
||||
int i, nand_maf_id, nand_dev_id;
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
struct nand_flash_dev *type;
|
||||
int ret;
|
||||
|
||||
if (chip->flash_node) {
|
||||
ret = nand_dt_init(mtd, chip, chip->flash_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the default functions */
|
||||
nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
|
||||
|
@ -62,6 +62,10 @@ struct nand_flash_dev nand_flash_ids[] = {
|
||||
{ .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} },
|
||||
SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640,
|
||||
NAND_ECC_INFO(40, SZ_1K), 4 },
|
||||
{"H27QCG8T2E5R‐BCF 64G 3.3V 8-bit",
|
||||
{ .id = {0xad, 0xde, 0x14, 0xa7, 0x42, 0x4a} },
|
||||
SZ_16K, SZ_8K, SZ_4M, NAND_NEED_SCRAMBLING, 6, 1664,
|
||||
NAND_ECC_INFO(56, SZ_1K), 1 },
|
||||
|
||||
LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS),
|
||||
LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
|
||||
|
1845
drivers/mtd/nand/sunxi_nand.c
Normal file
1845
drivers/mtd/nand/sunxi_nand.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -134,7 +134,10 @@
|
||||
#define CONFIG_SERIAL_TAG
|
||||
|
||||
#ifdef CONFIG_NAND_SUNXI
|
||||
#define CONFIG_SYS_NAND_MAX_ECCPOS 1664
|
||||
#define CONFIG_SPL_NAND_SUPPORT 1
|
||||
#define CONFIG_SYS_NAND_ONFI_DETECTION
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 8
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_SPI_SUNXI
|
||||
|
@ -155,6 +155,7 @@ enum fdt_compat_id {
|
||||
COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */
|
||||
COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */
|
||||
COMPAT_INTEL_IVYBRIDGE_FSP, /* Intel Ivy Bridge FSP */
|
||||
COMPAT_SUNXI_NAND, /* SUNXI NAND controller */
|
||||
|
||||
COMPAT_COUNT,
|
||||
};
|
||||
|
@ -500,5 +500,10 @@ int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
|
||||
int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
|
||||
loff_t *size, loff_t *maxsize, int devtype,
|
||||
uint64_t chipsize);
|
||||
|
||||
/* drivers/mtd/mtdcore.c */
|
||||
void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
|
||||
const uint64_t length, uint64_t *len_incl_bad,
|
||||
int *truncated);
|
||||
#endif
|
||||
#endif /* __MTD_MTD_H__ */
|
||||
|
@ -48,7 +48,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
|
||||
* is supported now. If you add a chip with bigger oobsize/page
|
||||
* adjust this accordingly.
|
||||
*/
|
||||
#define NAND_MAX_OOBSIZE 1216
|
||||
#define NAND_MAX_OOBSIZE 1664
|
||||
#define NAND_MAX_PAGESIZE 16384
|
||||
|
||||
/*
|
||||
@ -590,6 +590,7 @@ struct nand_buffers {
|
||||
* flash device
|
||||
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
|
||||
* flash device.
|
||||
* @flash_node: [BOARDSPECIFIC] device node describing this instance
|
||||
* @read_byte: [REPLACEABLE] read one byte from the chip
|
||||
* @read_word: [REPLACEABLE] read one word from the chip
|
||||
* @write_byte: [REPLACEABLE] write a single byte to the chip on the
|
||||
@ -689,6 +690,8 @@ struct nand_chip {
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
|
||||
int flash_node;
|
||||
|
||||
uint8_t (*read_byte)(struct mtd_info *mtd);
|
||||
u16 (*read_word)(struct mtd_info *mtd);
|
||||
void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
|
||||
|
@ -142,3 +142,6 @@ __attribute__((noreturn)) void nand_boot(void);
|
||||
int get_nand_env_oob(struct mtd_info *mtd, unsigned long *result);
|
||||
#endif
|
||||
int spl_nand_erase_one(int block, int page);
|
||||
|
||||
/* platform specific init functions */
|
||||
void sunxi_nand_init(void);
|
||||
|
@ -65,6 +65,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
|
||||
COMPAT(INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
|
||||
COMPAT(INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
|
||||
COMPAT(INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"),
|
||||
COMPAT(COMPAT_SUNXI_NAND, "allwinner,sun4i-a10-nand"),
|
||||
};
|
||||
|
||||
const char *fdtdec_get_compatible(enum fdt_compat_id id)
|
||||
|
Loading…
Reference in New Issue
Block a user