Re: [U-Boot] [PATCH v3 1/7] nand: Add zynq nand controller driver support

2014-02-27 Thread Scott Wood
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

2014-02-25 Thread Michal Simek
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

2014-02-17 Thread Siva Durga Prasad Paladugu
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