Re: [U-Boot] [PATCH v3 1/7] nand: Add zynq nand controller driver support
On Mon, 2014-02-17 at 17:56 +0530, Siva Durga Prasad Paladugu wrote: +/* Generic flash bbt decriptors */ +static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; +static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 4, + .len = 4, + .veroffs = 20, + .maxblocks = 4, + .pattern = bbt_pattern +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 4, + .len = 4, + .veroffs = 20, + .maxblocks = 4, + .pattern = mirror_pattern +}; If this BBT description is only for chips with on-die ECC, chips with 64-byte OOB, etc., say so in a comment -- and don't label them Generic flash bbt descriptors. :-) +/* + * onehot - onehot function + * @value: value to check for onehot + * + * This function checks whether a value is onehot or not. + * onehot is if and only if one bit is set. + * + * FIXME: Try to move this in common.h + */ +static bool onehot(unsigned short value) +{ + bool onehot; + + onehot = value !(value (value - 1)); + return onehot; +} + +/* + * zynq_nand_correct_data - ECC correction function + * @mtd: Pointer to the mtd_info structure + * @buf: Pointer to the page data + * @read_ecc:Pointer to the ECC value read from spare data area + * @calc_ecc:Pointer to the calculated ECC value + * + * This function corrects the ECC single bit errors detects 2-bit errors. + * + * returns: 0 if no ECC errors found + * 1 if single bit error found and corrected. + * -1 if multiple ECC errors found. + */ +static int zynq_nand_correct_data(struct mtd_info *mtd, unsigned char *buf, + unsigned char *read_ecc, unsigned char *calc_ecc) +{ + unsigned char bit_addr; + unsigned int byte_addr; + unsigned short ecc_odd, ecc_even; + unsigned short read_ecc_lower, read_ecc_upper; + unsigned short calc_ecc_lower, calc_ecc_upper; + + read_ecc_lower = (read_ecc[0] | (read_ecc[1] 8)) 0xfff; + read_ecc_upper = ((read_ecc[1] 4) | (read_ecc[2] 4)) 0xfff; + + calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] 8)) 0xfff; + calc_ecc_upper = ((calc_ecc[1] 4) | (calc_ecc[2] 4)) 0xfff; + + ecc_odd = read_ecc_lower ^ calc_ecc_lower; + ecc_even = read_ecc_upper ^ calc_ecc_upper; + + if ((ecc_odd == 0) (ecc_even == 0)) + return 0; /* no error */ + + if (ecc_odd == (~ecc_even 0xfff)) { + /* bits [11:3] of error code is byte offset */ + byte_addr = (ecc_odd 3) 0x1ff; + /* bits [2:0] of error code is bit offset */ + bit_addr = ecc_odd 0x7; + /* Toggling error bit */ + buf[byte_addr] ^= (1 bit_addr); + return 1; + } + + if (onehot(ecc_odd | ecc_even) == 1) Why are you comparing a bool to an integer? + } else if (page_addr != -1) /* Erase */ + cmd_data = page_addr; + else if (column != -1) { /* Change read/write column, read id etc */ + /* Adjust columns for 16 bit bus width */ Please use braces here. + if ((chip-options NAND_BUSWIDTH_16) + ((command == NAND_CMD_READ0) || + (command == NAND_CMD_SEQIN) || + (command == NAND_CMD_RNDOUT) || + (command == NAND_CMD_RNDIN))) + column = 1; + cmd_data = column; + } + + writel(cmd_data, cmd_addr); + + if (curr_cmd-end_cmd_valid) { + xnand-end_cmd = curr_cmd-end_cmd; + xnand-end_cmd_pending = 1; + } + + ndelay(100); + + if ((command == NAND_CMD_READ0) || + (command == NAND_CMD_RESET) || + (command == NAND_CMD_PARAM) || + (command == NAND_CMD_GET_FEATURES)) + /* wait until command is processed */ + nand_wait_ready(mtd); + +} Don't put newlines before an ending brace. + +/* + * zynq_nand_read_buf - read chip data into buffer + * @mtd:MTD device structure + * @buf:buffer to store date + * @len:number of bytes to read + */ +static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct nand_chip *chip = mtd-priv; + + /* Make sure that buf is 32 bit aligned */ + if (((int)buf 0x3) != 0) { + if (((int)buf 0x1) != 0) { + if (len) { + *buf = readb(chip-IO_ADDR_R); + buf += 1; + len--; + } + } + + if
Re: [U-Boot] [PATCH v3 1/7] nand: Add zynq nand controller driver support
Hi Scott, On 02/17/2014 01:26 PM, Siva Durga Prasad Paladugu wrote: From: Jagannadha Sutradharudu Teki jaga...@xilinx.com Added support for Zynq Nand controller driver. Signed-off-by: Siva Durga Prasad Paladugu siva...@xilinx.com Signed-off-by: Jagannadha Sutradharudu Teki jaga...@xilinx.com --- Changes for v3: -Fixed all review comments on v1 as some comments are not fixed on v2. -Separeted out the nand patch series as per Michal comment. Changes for v2: -Fixed issues pointed by Scott --- README|3 + arch/arm/include/asm/arch-zynq/hardware.h |2 + drivers/mtd/nand/Makefile |1 + drivers/mtd/nand/zynq_nand.c | 1188 + 4 files changed, 1194 insertions(+), 0 deletions(-) create mode 100755 drivers/mtd/nand/zynq_nand.c One note: Here is incorrect file permission. Can you please review this driver? Patches 2-7 should go through ARM tree but this first one should go through your tree. Thanks, Michal -- Michal Simek, Ing. (M.Eng), OpenPGP - KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/ Maintainer of Linux kernel - Xilinx Zynq ARM architecture Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform signature.asc Description: OpenPGP digital signature ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v3 1/7] nand: Add zynq nand controller driver support
From: Jagannadha Sutradharudu Teki jaga...@xilinx.com Added support for Zynq Nand controller driver. Signed-off-by: Siva Durga Prasad Paladugu siva...@xilinx.com Signed-off-by: Jagannadha Sutradharudu Teki jaga...@xilinx.com --- Changes for v3: -Fixed all review comments on v1 as some comments are not fixed on v2. -Separeted out the nand patch series as per Michal comment. Changes for v2: -Fixed issues pointed by Scott --- README|3 + arch/arm/include/asm/arch-zynq/hardware.h |2 + drivers/mtd/nand/Makefile |1 + drivers/mtd/nand/zynq_nand.c | 1188 + 4 files changed, 1194 insertions(+), 0 deletions(-) create mode 100755 drivers/mtd/nand/zynq_nand.c diff --git a/README b/README index fe48ccd..b1974b9 100644 --- a/README +++ b/README @@ -3950,6 +3950,9 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. environment. If redundant environment is used, it will be copied to CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE. +- CONFIG_NAND_ZYNQ + Define this for enabling zynq nand controller with onfi detection support. + - CONFIG_ENV_IS_IN_UBI: Define this if you have an UBI volume that you want to use for the diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index cd69677..2e504cf 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -19,6 +19,8 @@ #define ZYNQ_I2C_BASEADDR1 0xE0005000 #define ZYNQ_SPI_BASEADDR0 0xE0006000 #define ZYNQ_SPI_BASEADDR1 0xE0007000 +#define ZYNQ_SMC_BASEADDR 0xE000E000 +#define ZYNQ_NAND_BASEADDR 0xE100 #define ZYNQ_DDRC_BASEADDR 0xF8006000 /* Reflect slcr offsets */ diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 02b149c..abe9330 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -59,6 +59,7 @@ 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_DOCG4) += docg4.o +obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o else # minimal SPL drivers diff --git a/drivers/mtd/nand/zynq_nand.c b/drivers/mtd/nand/zynq_nand.c new file mode 100755 index 000..8a432df --- /dev/null +++ b/drivers/mtd/nand/zynq_nand.c @@ -0,0 +1,1188 @@ +/* + * (C) Copyright 2013 Xilinx, Inc. + * + * Xilinx Zynq NAND Flash Controller Driver + * This driver is based on plat_nand.c and mxc_nand.c drivers + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include common.h +#include malloc.h +#include asm/io.h +#include asm/errno.h +#include nand.h +#include linux/mtd/mtd.h +#include linux/mtd/nand.h +#include linux/mtd/partitions.h +#include linux/mtd/nand_ecc.h +#include asm/arch/hardware.h + +/* The NAND flash driver defines */ +#define ZYNQ_NAND_CMD_PHASE1 +#define ZYNQ_NAND_DATA_PHASE 2 +#define ZYNQ_NAND_ECC_SIZE 512 +#define ZYNQ_NAND_SET_OPMODE_8BIT (0 0) +#define ZYNQ_NAND_SET_OPMODE_16BIT (1 0) +#define ZYNQ_NAND_ECC_STATUS (1 6) +#define ZYNQ_MEMC_CLRCR_INT_CLR1 (1 4) +#define ZYNQ_MEMC_SR_RAW_INT_ST1 (1 6) +#define ZYNQ_MEMC_SR_INT_ST1 (1 4) + +/* Flash memory controller operating parameters */ +#define ZYNQ_NAND_CLR_CONFIG ((0x1 1) | /* Disable interrupt */ \ + (0x1 4) | /* Clear interrupt */ \ + (0x1 6)) /* Disable ECC interrupt */ + +/* Assuming 50MHz clock (20ns cycle time) and 3V operation */ +#define ZYNQ_NAND_SET_CYCLES ((0x2 20) | /* t_rr from nand_cycles */ \ + (0x2 17) | /* t_ar from nand_cycles */ \ + (0x1 14) | /* t_clr from nand_cycles */ \ + (0x3 11) | /* t_wp from nand_cycles */ \ + (0x2 8) | /* t_rea from nand_cycles */ \ + (0x5 4) | /* t_wc from nand_cycles */ \ + (0x5 0)) /* t_rc from nand_cycles */ + + +#define ZYNQ_NAND_DIRECT_CMD ((0x4 23) | /* Chip 0 from interface 1 */ \ + (0x2 21))/* UpdateRegs operation */ + +#define ZYNQ_NAND_ECC_CONFIG ((0x1 2) | /* ECC available on APB */ \ + (0x1 4) | /* ECC read at end of page */ \ + (0x0 5)) /* No Jumping */ + +#define ZYNQ_NAND_ECC_CMD1 ((0x80) | /* Write command */ \ + (0x00 8) | /* Read command */ \ + (0x30 16) | /* Read End command */ \ + (0x1 24))/* Read End command calid */ + +#define ZYNQ_NAND_ECC_CMD2 ((0x85) | /* Write col change cmd */ \ + (0x05