diff options
author | Tom Rini <trini@konsulko.com> | 2018-05-11 11:45:28 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-05-11 11:45:28 -0400 |
commit | 3b52847a451a81001b578353e793d7d9739b69d6 (patch) | |
tree | 37c62b1f1665262974d955078ce0d22485b1ab09 /drivers/mtd | |
parent | c590e62d3b6f6dd72eae1183614f919e3fd7ffcb (diff) | |
parent | 4b87f2d500e94f877f38d9c11e4e47e1721f3fbe (diff) | |
download | u-boot-3b52847a451a81001b578353e793d7d9739b69d6.tar.gz |
Merge tag 'xilinx-for-v2018.07' of git://www.denx.de/git/u-boot-microblaze
Xilinx changes for v2018.07
microblaze:
- Align defconfig
zynq:
- Rework fpga initialization and cpuinfo handling
zynqmp:
- Add ZynqMP R5 support
- Wire and enable watchdog on zcu100-revC
- Setup MMU map for DDR at run time
- Show board info based on DT and cleanup IDENT_STRING
zynqmp tools:
- Add read partition support
- Add initial support for Xilinx bif format for boot.bin generation
mmc:
- Fix get_timer usage on 64bit cpus
- Add support for SD3.0 UHS mode
nand-zynq:
- Add support for 16bit buswidth
- Use address cycles from onfi params
scsi:
- convert ceva sata to UCLASS_AHCI
timer:
- Add Cadence TTC for ZynqMP r5
watchdog:
- Minor cadence driver cleanup
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/zynq_nand.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/drivers/mtd/nand/zynq_nand.c b/drivers/mtd/nand/zynq_nand.c index efd3c9b798..e932a58bf6 100644 --- a/drivers/mtd/nand/zynq_nand.c +++ b/drivers/mtd/nand/zynq_nand.c @@ -16,6 +16,7 @@ #include <linux/mtd/partitions.h> #include <linux/mtd/nand_ecc.h> #include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> /* The NAND flash driver defines */ #define ZYNQ_NAND_CMD_PHASE 1 @@ -83,6 +84,18 @@ #define ZYNQ_NAND_ECC_BUSY (1 << 6) /* ECC block is busy */ #define ZYNQ_NAND_ECC_MASK 0x00FFFFFF /* ECC value mask */ +#define ZYNQ_NAND_ROW_ADDR_CYCL_MASK 0x0F +#define ZYNQ_NAND_COL_ADDR_CYCL_MASK 0xF0 + +#define ZYNQ_NAND_MIO_NUM_NAND_8BIT 13 +#define ZYNQ_NAND_MIO_NUM_NAND_16BIT 8 + +enum zynq_nand_bus_width { + NAND_BW_UNKNOWN = -1, + NAND_BW_8BIT, + NAND_BW_16BIT, +}; + #ifndef NAND_CMD_LOCK_TIGHT #define NAND_CMD_LOCK_TIGHT 0x2c #endif @@ -768,6 +781,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, { struct nand_chip *chip = mtd->priv; const struct zynq_nand_command_format *curr_cmd = NULL; + u8 addr_cycles = 0; struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv; void *cmd_addr; unsigned long cmd_data = 0; @@ -818,8 +832,18 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, else end_cmd = curr_cmd->end_cmd; + if (command == NAND_CMD_READ0 || + command == NAND_CMD_SEQIN) { + addr_cycles = chip->onfi_params.addr_cycles & + ZYNQ_NAND_ROW_ADDR_CYCL_MASK; + addr_cycles += ((chip->onfi_params.addr_cycles & + ZYNQ_NAND_COL_ADDR_CYCL_MASK) >> 4); + } else { + addr_cycles = curr_cmd->addr_cycles; + } + cmd_phase_addr = (unsigned long)xnand->nand_base | - (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT) | + (addr_cycles << ADDR_CYCLES_SHIFT) | (end_cmd_valid << END_CMD_VALID_SHIFT) | (COMMAND_PHASE) | (end_cmd << END_CMD_SHIFT) | @@ -1005,6 +1029,23 @@ static int zynq_nand_device_ready(struct mtd_info *mtd) return 0; } +static int zynq_nand_check_is_16bit_bw_flash(void) +{ + int is_16bit_bw = NAND_BW_UNKNOWN; + int mio_num_8bit = 0, mio_num_16bit = 0; + + mio_num_8bit = zynq_slcr_get_mio_pin_status("nand8"); + if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT) + is_16bit_bw = NAND_BW_8BIT; + + mio_num_16bit = zynq_slcr_get_mio_pin_status("nand16"); + if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT && + mio_num_16bit == ZYNQ_NAND_MIO_NUM_NAND_16BIT) + is_16bit_bw = NAND_BW_16BIT; + + return is_16bit_bw; +} + static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) { struct zynq_nand_info *xnand; @@ -1016,6 +1057,7 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) unsigned long ecc_cfg; int ondie_ecc_enabled = 0; int err = -1; + int is_16bit_bw; xnand = calloc(1, sizeof(struct zynq_nand_info)); if (!xnand) { @@ -1045,6 +1087,16 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) nand_chip->read_buf = zynq_nand_read_buf; nand_chip->write_buf = zynq_nand_write_buf; + is_16bit_bw = zynq_nand_check_is_16bit_bw_flash(); + if (is_16bit_bw == NAND_BW_UNKNOWN) { + printf("%s: Unable detect NAND based on MIO settings\n", + __func__); + goto fail; + } + + if (is_16bit_bw == NAND_BW_16BIT) + nand_chip->options = NAND_BUSWIDTH_16; + nand_chip->bbt_options = NAND_BBT_USE_FLASH; /* Initialize the NAND flash interface on NAND controller */ |