1*a430fa06SMiquel Raynal // SPDX-License-Identifier: GPL-2.0+ 2*a430fa06SMiquel Raynal /* 3*a430fa06SMiquel Raynal * Copyright (c) 2011 The Chromium OS Authors. 4*a430fa06SMiquel Raynal * (C) Copyright 2011 NVIDIA Corporation <www.nvidia.com> 5*a430fa06SMiquel Raynal * (C) Copyright 2006 Detlev Zundel, dzu@denx.de 6*a430fa06SMiquel Raynal * (C) Copyright 2006 DENX Software Engineering 7*a430fa06SMiquel Raynal */ 8*a430fa06SMiquel Raynal 9*a430fa06SMiquel Raynal #include <common.h> 10*a430fa06SMiquel Raynal #include <asm/io.h> 11*a430fa06SMiquel Raynal #include <memalign.h> 12*a430fa06SMiquel Raynal #include <nand.h> 13*a430fa06SMiquel Raynal #include <asm/arch/clock.h> 14*a430fa06SMiquel Raynal #include <asm/arch/funcmux.h> 15*a430fa06SMiquel Raynal #include <asm/arch-tegra/clk_rst.h> 16*a430fa06SMiquel Raynal #include <linux/errno.h> 17*a430fa06SMiquel Raynal #include <asm/gpio.h> 18*a430fa06SMiquel Raynal #include <fdtdec.h> 19*a430fa06SMiquel Raynal #include <bouncebuf.h> 20*a430fa06SMiquel Raynal #include <dm.h> 21*a430fa06SMiquel Raynal #include "tegra_nand.h" 22*a430fa06SMiquel Raynal 23*a430fa06SMiquel Raynal DECLARE_GLOBAL_DATA_PTR; 24*a430fa06SMiquel Raynal 25*a430fa06SMiquel Raynal #define NAND_CMD_TIMEOUT_MS 10 26*a430fa06SMiquel Raynal 27*a430fa06SMiquel Raynal #define SKIPPED_SPARE_BYTES 4 28*a430fa06SMiquel Raynal 29*a430fa06SMiquel Raynal /* ECC bytes to be generated for tag data */ 30*a430fa06SMiquel Raynal #define TAG_ECC_BYTES 4 31*a430fa06SMiquel Raynal 32*a430fa06SMiquel Raynal static const struct udevice_id tegra_nand_dt_ids[] = { 33*a430fa06SMiquel Raynal { 34*a430fa06SMiquel Raynal .compatible = "nvidia,tegra20-nand", 35*a430fa06SMiquel Raynal }, 36*a430fa06SMiquel Raynal { /* sentinel */ } 37*a430fa06SMiquel Raynal }; 38*a430fa06SMiquel Raynal 39*a430fa06SMiquel Raynal /* 64 byte oob block info for large page (== 2KB) device 40*a430fa06SMiquel Raynal * 41*a430fa06SMiquel Raynal * OOB flash layout for Tegra with Reed-Solomon 4 symbol correct ECC: 42*a430fa06SMiquel Raynal * Skipped bytes(4) 43*a430fa06SMiquel Raynal * Main area Ecc(36) 44*a430fa06SMiquel Raynal * Tag data(20) 45*a430fa06SMiquel Raynal * Tag data Ecc(4) 46*a430fa06SMiquel Raynal * 47*a430fa06SMiquel Raynal * Yaffs2 will use 16 tag bytes. 48*a430fa06SMiquel Raynal */ 49*a430fa06SMiquel Raynal static struct nand_ecclayout eccoob = { 50*a430fa06SMiquel Raynal .eccbytes = 36, 51*a430fa06SMiquel Raynal .eccpos = { 52*a430fa06SMiquel Raynal 4, 5, 6, 7, 8, 9, 10, 11, 12, 53*a430fa06SMiquel Raynal 13, 14, 15, 16, 17, 18, 19, 20, 21, 54*a430fa06SMiquel Raynal 22, 23, 24, 25, 26, 27, 28, 29, 30, 55*a430fa06SMiquel Raynal 31, 32, 33, 34, 35, 36, 37, 38, 39, 56*a430fa06SMiquel Raynal }, 57*a430fa06SMiquel Raynal .oobavail = 20, 58*a430fa06SMiquel Raynal .oobfree = { 59*a430fa06SMiquel Raynal { 60*a430fa06SMiquel Raynal .offset = 40, 61*a430fa06SMiquel Raynal .length = 20, 62*a430fa06SMiquel Raynal }, 63*a430fa06SMiquel Raynal } 64*a430fa06SMiquel Raynal }; 65*a430fa06SMiquel Raynal 66*a430fa06SMiquel Raynal enum { 67*a430fa06SMiquel Raynal ECC_OK, 68*a430fa06SMiquel Raynal ECC_TAG_ERROR = 1 << 0, 69*a430fa06SMiquel Raynal ECC_DATA_ERROR = 1 << 1 70*a430fa06SMiquel Raynal }; 71*a430fa06SMiquel Raynal 72*a430fa06SMiquel Raynal /* Timing parameters */ 73*a430fa06SMiquel Raynal enum { 74*a430fa06SMiquel Raynal FDT_NAND_MAX_TRP_TREA, 75*a430fa06SMiquel Raynal FDT_NAND_TWB, 76*a430fa06SMiquel Raynal FDT_NAND_MAX_TCR_TAR_TRR, 77*a430fa06SMiquel Raynal FDT_NAND_TWHR, 78*a430fa06SMiquel Raynal FDT_NAND_MAX_TCS_TCH_TALS_TALH, 79*a430fa06SMiquel Raynal FDT_NAND_TWH, 80*a430fa06SMiquel Raynal FDT_NAND_TWP, 81*a430fa06SMiquel Raynal FDT_NAND_TRH, 82*a430fa06SMiquel Raynal FDT_NAND_TADL, 83*a430fa06SMiquel Raynal 84*a430fa06SMiquel Raynal FDT_NAND_TIMING_COUNT 85*a430fa06SMiquel Raynal }; 86*a430fa06SMiquel Raynal 87*a430fa06SMiquel Raynal /* Information about an attached NAND chip */ 88*a430fa06SMiquel Raynal struct fdt_nand { 89*a430fa06SMiquel Raynal struct nand_ctlr *reg; 90*a430fa06SMiquel Raynal int enabled; /* 1 to enable, 0 to disable */ 91*a430fa06SMiquel Raynal struct gpio_desc wp_gpio; /* write-protect GPIO */ 92*a430fa06SMiquel Raynal s32 width; /* bit width, normally 8 */ 93*a430fa06SMiquel Raynal u32 timing[FDT_NAND_TIMING_COUNT]; 94*a430fa06SMiquel Raynal }; 95*a430fa06SMiquel Raynal 96*a430fa06SMiquel Raynal struct nand_drv { 97*a430fa06SMiquel Raynal struct nand_ctlr *reg; 98*a430fa06SMiquel Raynal struct fdt_nand config; 99*a430fa06SMiquel Raynal }; 100*a430fa06SMiquel Raynal 101*a430fa06SMiquel Raynal struct tegra_nand_info { 102*a430fa06SMiquel Raynal struct udevice *dev; 103*a430fa06SMiquel Raynal struct nand_drv nand_ctrl; 104*a430fa06SMiquel Raynal struct nand_chip nand_chip; 105*a430fa06SMiquel Raynal }; 106*a430fa06SMiquel Raynal 107*a430fa06SMiquel Raynal /** 108*a430fa06SMiquel Raynal * Wait for command completion 109*a430fa06SMiquel Raynal * 110*a430fa06SMiquel Raynal * @param reg nand_ctlr structure 111*a430fa06SMiquel Raynal * @return 112*a430fa06SMiquel Raynal * 1 - Command completed 113*a430fa06SMiquel Raynal * 0 - Timeout 114*a430fa06SMiquel Raynal */ 115*a430fa06SMiquel Raynal static int nand_waitfor_cmd_completion(struct nand_ctlr *reg) 116*a430fa06SMiquel Raynal { 117*a430fa06SMiquel Raynal u32 reg_val; 118*a430fa06SMiquel Raynal int running; 119*a430fa06SMiquel Raynal int i; 120*a430fa06SMiquel Raynal 121*a430fa06SMiquel Raynal for (i = 0; i < NAND_CMD_TIMEOUT_MS * 1000; i++) { 122*a430fa06SMiquel Raynal if ((readl(®->command) & CMD_GO) || 123*a430fa06SMiquel Raynal !(readl(®->status) & STATUS_RBSY0) || 124*a430fa06SMiquel Raynal !(readl(®->isr) & ISR_IS_CMD_DONE)) { 125*a430fa06SMiquel Raynal udelay(1); 126*a430fa06SMiquel Raynal continue; 127*a430fa06SMiquel Raynal } 128*a430fa06SMiquel Raynal reg_val = readl(®->dma_mst_ctrl); 129*a430fa06SMiquel Raynal /* 130*a430fa06SMiquel Raynal * If DMA_MST_CTRL_EN_A_ENABLE or DMA_MST_CTRL_EN_B_ENABLE 131*a430fa06SMiquel Raynal * is set, that means DMA engine is running. 132*a430fa06SMiquel Raynal * 133*a430fa06SMiquel Raynal * Then we have to wait until DMA_MST_CTRL_IS_DMA_DONE 134*a430fa06SMiquel Raynal * is cleared, indicating DMA transfer completion. 135*a430fa06SMiquel Raynal */ 136*a430fa06SMiquel Raynal running = reg_val & (DMA_MST_CTRL_EN_A_ENABLE | 137*a430fa06SMiquel Raynal DMA_MST_CTRL_EN_B_ENABLE); 138*a430fa06SMiquel Raynal if (!running || (reg_val & DMA_MST_CTRL_IS_DMA_DONE)) 139*a430fa06SMiquel Raynal return 1; 140*a430fa06SMiquel Raynal udelay(1); 141*a430fa06SMiquel Raynal } 142*a430fa06SMiquel Raynal return 0; 143*a430fa06SMiquel Raynal } 144*a430fa06SMiquel Raynal 145*a430fa06SMiquel Raynal /** 146*a430fa06SMiquel Raynal * Read one byte from the chip 147*a430fa06SMiquel Raynal * 148*a430fa06SMiquel Raynal * @param mtd MTD device structure 149*a430fa06SMiquel Raynal * @return data byte 150*a430fa06SMiquel Raynal * 151*a430fa06SMiquel Raynal * Read function for 8bit bus-width 152*a430fa06SMiquel Raynal */ 153*a430fa06SMiquel Raynal static uint8_t read_byte(struct mtd_info *mtd) 154*a430fa06SMiquel Raynal { 155*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd); 156*a430fa06SMiquel Raynal struct nand_drv *info; 157*a430fa06SMiquel Raynal 158*a430fa06SMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip); 159*a430fa06SMiquel Raynal 160*a430fa06SMiquel Raynal writel(CMD_GO | CMD_PIO | CMD_RX | CMD_CE0 | CMD_A_VALID, 161*a430fa06SMiquel Raynal &info->reg->command); 162*a430fa06SMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) 163*a430fa06SMiquel Raynal printf("Command timeout\n"); 164*a430fa06SMiquel Raynal 165*a430fa06SMiquel Raynal return (uint8_t)readl(&info->reg->resp); 166*a430fa06SMiquel Raynal } 167*a430fa06SMiquel Raynal 168*a430fa06SMiquel Raynal /** 169*a430fa06SMiquel Raynal * Read len bytes from the chip into a buffer 170*a430fa06SMiquel Raynal * 171*a430fa06SMiquel Raynal * @param mtd MTD device structure 172*a430fa06SMiquel Raynal * @param buf buffer to store data to 173*a430fa06SMiquel Raynal * @param len number of bytes to read 174*a430fa06SMiquel Raynal * 175*a430fa06SMiquel Raynal * Read function for 8bit bus-width 176*a430fa06SMiquel Raynal */ 177*a430fa06SMiquel Raynal static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 178*a430fa06SMiquel Raynal { 179*a430fa06SMiquel Raynal int i, s; 180*a430fa06SMiquel Raynal unsigned int reg; 181*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd); 182*a430fa06SMiquel Raynal struct nand_drv *info = (struct nand_drv *)nand_get_controller_data(chip); 183*a430fa06SMiquel Raynal 184*a430fa06SMiquel Raynal for (i = 0; i < len; i += 4) { 185*a430fa06SMiquel Raynal s = (len - i) > 4 ? 4 : len - i; 186*a430fa06SMiquel Raynal writel(CMD_PIO | CMD_RX | CMD_A_VALID | CMD_CE0 | 187*a430fa06SMiquel Raynal ((s - 1) << CMD_TRANS_SIZE_SHIFT) | CMD_GO, 188*a430fa06SMiquel Raynal &info->reg->command); 189*a430fa06SMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) 190*a430fa06SMiquel Raynal puts("Command timeout during read_buf\n"); 191*a430fa06SMiquel Raynal reg = readl(&info->reg->resp); 192*a430fa06SMiquel Raynal memcpy(buf + i, ®, s); 193*a430fa06SMiquel Raynal } 194*a430fa06SMiquel Raynal } 195*a430fa06SMiquel Raynal 196*a430fa06SMiquel Raynal /** 197*a430fa06SMiquel Raynal * Check NAND status to see if it is ready or not 198*a430fa06SMiquel Raynal * 199*a430fa06SMiquel Raynal * @param mtd MTD device structure 200*a430fa06SMiquel Raynal * @return 201*a430fa06SMiquel Raynal * 1 - ready 202*a430fa06SMiquel Raynal * 0 - not ready 203*a430fa06SMiquel Raynal */ 204*a430fa06SMiquel Raynal static int nand_dev_ready(struct mtd_info *mtd) 205*a430fa06SMiquel Raynal { 206*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd); 207*a430fa06SMiquel Raynal int reg_val; 208*a430fa06SMiquel Raynal struct nand_drv *info; 209*a430fa06SMiquel Raynal 210*a430fa06SMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip); 211*a430fa06SMiquel Raynal 212*a430fa06SMiquel Raynal reg_val = readl(&info->reg->status); 213*a430fa06SMiquel Raynal if (reg_val & STATUS_RBSY0) 214*a430fa06SMiquel Raynal return 1; 215*a430fa06SMiquel Raynal else 216*a430fa06SMiquel Raynal return 0; 217*a430fa06SMiquel Raynal } 218*a430fa06SMiquel Raynal 219*a430fa06SMiquel Raynal /* Dummy implementation: we don't support multiple chips */ 220*a430fa06SMiquel Raynal static void nand_select_chip(struct mtd_info *mtd, int chipnr) 221*a430fa06SMiquel Raynal { 222*a430fa06SMiquel Raynal switch (chipnr) { 223*a430fa06SMiquel Raynal case -1: 224*a430fa06SMiquel Raynal case 0: 225*a430fa06SMiquel Raynal break; 226*a430fa06SMiquel Raynal 227*a430fa06SMiquel Raynal default: 228*a430fa06SMiquel Raynal BUG(); 229*a430fa06SMiquel Raynal } 230*a430fa06SMiquel Raynal } 231*a430fa06SMiquel Raynal 232*a430fa06SMiquel Raynal /** 233*a430fa06SMiquel Raynal * Clear all interrupt status bits 234*a430fa06SMiquel Raynal * 235*a430fa06SMiquel Raynal * @param reg nand_ctlr structure 236*a430fa06SMiquel Raynal */ 237*a430fa06SMiquel Raynal static void nand_clear_interrupt_status(struct nand_ctlr *reg) 238*a430fa06SMiquel Raynal { 239*a430fa06SMiquel Raynal u32 reg_val; 240*a430fa06SMiquel Raynal 241*a430fa06SMiquel Raynal /* Clear interrupt status */ 242*a430fa06SMiquel Raynal reg_val = readl(®->isr); 243*a430fa06SMiquel Raynal writel(reg_val, ®->isr); 244*a430fa06SMiquel Raynal } 245*a430fa06SMiquel Raynal 246*a430fa06SMiquel Raynal /** 247*a430fa06SMiquel Raynal * Send command to NAND device 248*a430fa06SMiquel Raynal * 249*a430fa06SMiquel Raynal * @param mtd MTD device structure 250*a430fa06SMiquel Raynal * @param command the command to be sent 251*a430fa06SMiquel Raynal * @param column the column address for this command, -1 if none 252*a430fa06SMiquel Raynal * @param page_addr the page address for this command, -1 if none 253*a430fa06SMiquel Raynal */ 254*a430fa06SMiquel Raynal static void nand_command(struct mtd_info *mtd, unsigned int command, 255*a430fa06SMiquel Raynal int column, int page_addr) 256*a430fa06SMiquel Raynal { 257*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd); 258*a430fa06SMiquel Raynal struct nand_drv *info; 259*a430fa06SMiquel Raynal 260*a430fa06SMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip); 261*a430fa06SMiquel Raynal 262*a430fa06SMiquel Raynal /* 263*a430fa06SMiquel Raynal * Write out the command to the device. 264*a430fa06SMiquel Raynal * 265*a430fa06SMiquel Raynal * Only command NAND_CMD_RESET or NAND_CMD_READID will come 266*a430fa06SMiquel Raynal * here before mtd->writesize is initialized. 267*a430fa06SMiquel Raynal */ 268*a430fa06SMiquel Raynal 269*a430fa06SMiquel Raynal /* Emulate NAND_CMD_READOOB */ 270*a430fa06SMiquel Raynal if (command == NAND_CMD_READOOB) { 271*a430fa06SMiquel Raynal assert(mtd->writesize != 0); 272*a430fa06SMiquel Raynal column += mtd->writesize; 273*a430fa06SMiquel Raynal command = NAND_CMD_READ0; 274*a430fa06SMiquel Raynal } 275*a430fa06SMiquel Raynal 276*a430fa06SMiquel Raynal /* Adjust columns for 16 bit bus-width */ 277*a430fa06SMiquel Raynal if (column != -1 && (chip->options & NAND_BUSWIDTH_16)) 278*a430fa06SMiquel Raynal column >>= 1; 279*a430fa06SMiquel Raynal 280*a430fa06SMiquel Raynal nand_clear_interrupt_status(info->reg); 281*a430fa06SMiquel Raynal 282*a430fa06SMiquel Raynal /* Stop DMA engine, clear DMA completion status */ 283*a430fa06SMiquel Raynal writel(DMA_MST_CTRL_EN_A_DISABLE 284*a430fa06SMiquel Raynal | DMA_MST_CTRL_EN_B_DISABLE 285*a430fa06SMiquel Raynal | DMA_MST_CTRL_IS_DMA_DONE, 286*a430fa06SMiquel Raynal &info->reg->dma_mst_ctrl); 287*a430fa06SMiquel Raynal 288*a430fa06SMiquel Raynal /* 289*a430fa06SMiquel Raynal * Program and erase have their own busy handlers 290*a430fa06SMiquel Raynal * status and sequential in needs no delay 291*a430fa06SMiquel Raynal */ 292*a430fa06SMiquel Raynal switch (command) { 293*a430fa06SMiquel Raynal case NAND_CMD_READID: 294*a430fa06SMiquel Raynal writel(NAND_CMD_READID, &info->reg->cmd_reg1); 295*a430fa06SMiquel Raynal writel(column & 0xFF, &info->reg->addr_reg1); 296*a430fa06SMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0, 297*a430fa06SMiquel Raynal &info->reg->command); 298*a430fa06SMiquel Raynal break; 299*a430fa06SMiquel Raynal case NAND_CMD_PARAM: 300*a430fa06SMiquel Raynal writel(NAND_CMD_PARAM, &info->reg->cmd_reg1); 301*a430fa06SMiquel Raynal writel(column & 0xFF, &info->reg->addr_reg1); 302*a430fa06SMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0, 303*a430fa06SMiquel Raynal &info->reg->command); 304*a430fa06SMiquel Raynal break; 305*a430fa06SMiquel Raynal case NAND_CMD_READ0: 306*a430fa06SMiquel Raynal writel(NAND_CMD_READ0, &info->reg->cmd_reg1); 307*a430fa06SMiquel Raynal writel(NAND_CMD_READSTART, &info->reg->cmd_reg2); 308*a430fa06SMiquel Raynal writel((page_addr << 16) | (column & 0xFFFF), 309*a430fa06SMiquel Raynal &info->reg->addr_reg1); 310*a430fa06SMiquel Raynal writel(page_addr >> 16, &info->reg->addr_reg2); 311*a430fa06SMiquel Raynal return; 312*a430fa06SMiquel Raynal case NAND_CMD_SEQIN: 313*a430fa06SMiquel Raynal writel(NAND_CMD_SEQIN, &info->reg->cmd_reg1); 314*a430fa06SMiquel Raynal writel(NAND_CMD_PAGEPROG, &info->reg->cmd_reg2); 315*a430fa06SMiquel Raynal writel((page_addr << 16) | (column & 0xFFFF), 316*a430fa06SMiquel Raynal &info->reg->addr_reg1); 317*a430fa06SMiquel Raynal writel(page_addr >> 16, 318*a430fa06SMiquel Raynal &info->reg->addr_reg2); 319*a430fa06SMiquel Raynal return; 320*a430fa06SMiquel Raynal case NAND_CMD_PAGEPROG: 321*a430fa06SMiquel Raynal return; 322*a430fa06SMiquel Raynal case NAND_CMD_ERASE1: 323*a430fa06SMiquel Raynal writel(NAND_CMD_ERASE1, &info->reg->cmd_reg1); 324*a430fa06SMiquel Raynal writel(NAND_CMD_ERASE2, &info->reg->cmd_reg2); 325*a430fa06SMiquel Raynal writel(page_addr, &info->reg->addr_reg1); 326*a430fa06SMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE | 327*a430fa06SMiquel Raynal CMD_SEC_CMD | CMD_CE0 | CMD_ALE_BYTES3, 328*a430fa06SMiquel Raynal &info->reg->command); 329*a430fa06SMiquel Raynal break; 330*a430fa06SMiquel Raynal case NAND_CMD_ERASE2: 331*a430fa06SMiquel Raynal return; 332*a430fa06SMiquel Raynal case NAND_CMD_STATUS: 333*a430fa06SMiquel Raynal writel(NAND_CMD_STATUS, &info->reg->cmd_reg1); 334*a430fa06SMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_PIO | CMD_RX 335*a430fa06SMiquel Raynal | ((1 - 0) << CMD_TRANS_SIZE_SHIFT) 336*a430fa06SMiquel Raynal | CMD_CE0, 337*a430fa06SMiquel Raynal &info->reg->command); 338*a430fa06SMiquel Raynal break; 339*a430fa06SMiquel Raynal case NAND_CMD_RESET: 340*a430fa06SMiquel Raynal writel(NAND_CMD_RESET, &info->reg->cmd_reg1); 341*a430fa06SMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_CE0, 342*a430fa06SMiquel Raynal &info->reg->command); 343*a430fa06SMiquel Raynal break; 344*a430fa06SMiquel Raynal case NAND_CMD_RNDOUT: 345*a430fa06SMiquel Raynal default: 346*a430fa06SMiquel Raynal printf("%s: Unsupported command %d\n", __func__, command); 347*a430fa06SMiquel Raynal return; 348*a430fa06SMiquel Raynal } 349*a430fa06SMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) 350*a430fa06SMiquel Raynal printf("Command 0x%02X timeout\n", command); 351*a430fa06SMiquel Raynal } 352*a430fa06SMiquel Raynal 353*a430fa06SMiquel Raynal /** 354*a430fa06SMiquel Raynal * Check whether the pointed buffer are all 0xff (blank). 355*a430fa06SMiquel Raynal * 356*a430fa06SMiquel Raynal * @param buf data buffer for blank check 357*a430fa06SMiquel Raynal * @param len length of the buffer in byte 358*a430fa06SMiquel Raynal * @return 359*a430fa06SMiquel Raynal * 1 - blank 360*a430fa06SMiquel Raynal * 0 - non-blank 361*a430fa06SMiquel Raynal */ 362*a430fa06SMiquel Raynal static int blank_check(u8 *buf, int len) 363*a430fa06SMiquel Raynal { 364*a430fa06SMiquel Raynal int i; 365*a430fa06SMiquel Raynal 366*a430fa06SMiquel Raynal for (i = 0; i < len; i++) 367*a430fa06SMiquel Raynal if (buf[i] != 0xFF) 368*a430fa06SMiquel Raynal return 0; 369*a430fa06SMiquel Raynal return 1; 370*a430fa06SMiquel Raynal } 371*a430fa06SMiquel Raynal 372*a430fa06SMiquel Raynal /** 373*a430fa06SMiquel Raynal * After a DMA transfer for read, we call this function to see whether there 374*a430fa06SMiquel Raynal * is any uncorrectable error on the pointed data buffer or oob buffer. 375*a430fa06SMiquel Raynal * 376*a430fa06SMiquel Raynal * @param reg nand_ctlr structure 377*a430fa06SMiquel Raynal * @param databuf data buffer 378*a430fa06SMiquel Raynal * @param a_len data buffer length 379*a430fa06SMiquel Raynal * @param oobbuf oob buffer 380*a430fa06SMiquel Raynal * @param b_len oob buffer length 381*a430fa06SMiquel Raynal * @return 382*a430fa06SMiquel Raynal * ECC_OK - no ECC error or correctable ECC error 383*a430fa06SMiquel Raynal * ECC_TAG_ERROR - uncorrectable tag ECC error 384*a430fa06SMiquel Raynal * ECC_DATA_ERROR - uncorrectable data ECC error 385*a430fa06SMiquel Raynal * ECC_DATA_ERROR + ECC_TAG_ERROR - uncorrectable data+tag ECC error 386*a430fa06SMiquel Raynal */ 387*a430fa06SMiquel Raynal static int check_ecc_error(struct nand_ctlr *reg, u8 *databuf, 388*a430fa06SMiquel Raynal int a_len, u8 *oobbuf, int b_len) 389*a430fa06SMiquel Raynal { 390*a430fa06SMiquel Raynal int return_val = ECC_OK; 391*a430fa06SMiquel Raynal u32 reg_val; 392*a430fa06SMiquel Raynal 393*a430fa06SMiquel Raynal if (!(readl(®->isr) & ISR_IS_ECC_ERR)) 394*a430fa06SMiquel Raynal return ECC_OK; 395*a430fa06SMiquel Raynal 396*a430fa06SMiquel Raynal /* 397*a430fa06SMiquel Raynal * Area A is used for the data block (databuf). Area B is used for 398*a430fa06SMiquel Raynal * the spare block (oobbuf) 399*a430fa06SMiquel Raynal */ 400*a430fa06SMiquel Raynal reg_val = readl(®->dec_status); 401*a430fa06SMiquel Raynal if ((reg_val & DEC_STATUS_A_ECC_FAIL) && databuf) { 402*a430fa06SMiquel Raynal reg_val = readl(®->bch_dec_status_buf); 403*a430fa06SMiquel Raynal /* 404*a430fa06SMiquel Raynal * If uncorrectable error occurs on data area, then see whether 405*a430fa06SMiquel Raynal * they are all FF. If all are FF, it's a blank page. 406*a430fa06SMiquel Raynal * Not error. 407*a430fa06SMiquel Raynal */ 408*a430fa06SMiquel Raynal if ((reg_val & BCH_DEC_STATUS_FAIL_SEC_FLAG_MASK) && 409*a430fa06SMiquel Raynal !blank_check(databuf, a_len)) 410*a430fa06SMiquel Raynal return_val |= ECC_DATA_ERROR; 411*a430fa06SMiquel Raynal } 412*a430fa06SMiquel Raynal 413*a430fa06SMiquel Raynal if ((reg_val & DEC_STATUS_B_ECC_FAIL) && oobbuf) { 414*a430fa06SMiquel Raynal reg_val = readl(®->bch_dec_status_buf); 415*a430fa06SMiquel Raynal /* 416*a430fa06SMiquel Raynal * If uncorrectable error occurs on tag area, then see whether 417*a430fa06SMiquel Raynal * they are all FF. If all are FF, it's a blank page. 418*a430fa06SMiquel Raynal * Not error. 419*a430fa06SMiquel Raynal */ 420*a430fa06SMiquel Raynal if ((reg_val & BCH_DEC_STATUS_FAIL_TAG_MASK) && 421*a430fa06SMiquel Raynal !blank_check(oobbuf, b_len)) 422*a430fa06SMiquel Raynal return_val |= ECC_TAG_ERROR; 423*a430fa06SMiquel Raynal } 424*a430fa06SMiquel Raynal 425*a430fa06SMiquel Raynal return return_val; 426*a430fa06SMiquel Raynal } 427*a430fa06SMiquel Raynal 428*a430fa06SMiquel Raynal /** 429*a430fa06SMiquel Raynal * Set GO bit to send command to device 430*a430fa06SMiquel Raynal * 431*a430fa06SMiquel Raynal * @param reg nand_ctlr structure 432*a430fa06SMiquel Raynal */ 433*a430fa06SMiquel Raynal static void start_command(struct nand_ctlr *reg) 434*a430fa06SMiquel Raynal { 435*a430fa06SMiquel Raynal u32 reg_val; 436*a430fa06SMiquel Raynal 437*a430fa06SMiquel Raynal reg_val = readl(®->command); 438*a430fa06SMiquel Raynal reg_val |= CMD_GO; 439*a430fa06SMiquel Raynal writel(reg_val, ®->command); 440*a430fa06SMiquel Raynal } 441*a430fa06SMiquel Raynal 442*a430fa06SMiquel Raynal /** 443*a430fa06SMiquel Raynal * Clear command GO bit, DMA GO bit, and DMA completion status 444*a430fa06SMiquel Raynal * 445*a430fa06SMiquel Raynal * @param reg nand_ctlr structure 446*a430fa06SMiquel Raynal */ 447*a430fa06SMiquel Raynal static void stop_command(struct nand_ctlr *reg) 448*a430fa06SMiquel Raynal { 449*a430fa06SMiquel Raynal /* Stop command */ 450*a430fa06SMiquel Raynal writel(0, ®->command); 451*a430fa06SMiquel Raynal 452*a430fa06SMiquel Raynal /* Stop DMA engine and clear DMA completion status */ 453*a430fa06SMiquel Raynal writel(DMA_MST_CTRL_GO_DISABLE 454*a430fa06SMiquel Raynal | DMA_MST_CTRL_IS_DMA_DONE, 455*a430fa06SMiquel Raynal ®->dma_mst_ctrl); 456*a430fa06SMiquel Raynal } 457*a430fa06SMiquel Raynal 458*a430fa06SMiquel Raynal /** 459*a430fa06SMiquel Raynal * Set up NAND bus width and page size 460*a430fa06SMiquel Raynal * 461*a430fa06SMiquel Raynal * @param info nand_info structure 462*a430fa06SMiquel Raynal * @param *reg_val address of reg_val 463*a430fa06SMiquel Raynal * @return 0 if ok, -1 on error 464*a430fa06SMiquel Raynal */ 465*a430fa06SMiquel Raynal static int set_bus_width_page_size(struct mtd_info *our_mtd, 466*a430fa06SMiquel Raynal struct fdt_nand *config, u32 *reg_val) 467*a430fa06SMiquel Raynal { 468*a430fa06SMiquel Raynal if (config->width == 8) 469*a430fa06SMiquel Raynal *reg_val = CFG_BUS_WIDTH_8BIT; 470*a430fa06SMiquel Raynal else if (config->width == 16) 471*a430fa06SMiquel Raynal *reg_val = CFG_BUS_WIDTH_16BIT; 472*a430fa06SMiquel Raynal else { 473*a430fa06SMiquel Raynal debug("%s: Unsupported bus width %d\n", __func__, 474*a430fa06SMiquel Raynal config->width); 475*a430fa06SMiquel Raynal return -1; 476*a430fa06SMiquel Raynal } 477*a430fa06SMiquel Raynal 478*a430fa06SMiquel Raynal if (our_mtd->writesize == 512) 479*a430fa06SMiquel Raynal *reg_val |= CFG_PAGE_SIZE_512; 480*a430fa06SMiquel Raynal else if (our_mtd->writesize == 2048) 481*a430fa06SMiquel Raynal *reg_val |= CFG_PAGE_SIZE_2048; 482*a430fa06SMiquel Raynal else if (our_mtd->writesize == 4096) 483*a430fa06SMiquel Raynal *reg_val |= CFG_PAGE_SIZE_4096; 484*a430fa06SMiquel Raynal else { 485*a430fa06SMiquel Raynal debug("%s: Unsupported page size %d\n", __func__, 486*a430fa06SMiquel Raynal our_mtd->writesize); 487*a430fa06SMiquel Raynal return -1; 488*a430fa06SMiquel Raynal } 489*a430fa06SMiquel Raynal 490*a430fa06SMiquel Raynal return 0; 491*a430fa06SMiquel Raynal } 492*a430fa06SMiquel Raynal 493*a430fa06SMiquel Raynal /** 494*a430fa06SMiquel Raynal * Page read/write function 495*a430fa06SMiquel Raynal * 496*a430fa06SMiquel Raynal * @param mtd mtd info structure 497*a430fa06SMiquel Raynal * @param chip nand chip info structure 498*a430fa06SMiquel Raynal * @param buf data buffer 499*a430fa06SMiquel Raynal * @param page page number 500*a430fa06SMiquel Raynal * @param with_ecc 1 to enable ECC, 0 to disable ECC 501*a430fa06SMiquel Raynal * @param is_writing 0 for read, 1 for write 502*a430fa06SMiquel Raynal * @return 0 when successfully completed 503*a430fa06SMiquel Raynal * -EIO when command timeout 504*a430fa06SMiquel Raynal */ 505*a430fa06SMiquel Raynal static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, 506*a430fa06SMiquel Raynal uint8_t *buf, int page, int with_ecc, int is_writing) 507*a430fa06SMiquel Raynal { 508*a430fa06SMiquel Raynal u32 reg_val; 509*a430fa06SMiquel Raynal int tag_size; 510*a430fa06SMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree; 511*a430fa06SMiquel Raynal /* 4*128=512 (byte) is the value that our HW can support. */ 512*a430fa06SMiquel Raynal ALLOC_CACHE_ALIGN_BUFFER(u32, tag_buf, 128); 513*a430fa06SMiquel Raynal char *tag_ptr; 514*a430fa06SMiquel Raynal struct nand_drv *info; 515*a430fa06SMiquel Raynal struct fdt_nand *config; 516*a430fa06SMiquel Raynal unsigned int bbflags; 517*a430fa06SMiquel Raynal struct bounce_buffer bbstate, bbstate_oob; 518*a430fa06SMiquel Raynal 519*a430fa06SMiquel Raynal if ((uintptr_t)buf & 0x03) { 520*a430fa06SMiquel Raynal printf("buf %p has to be 4-byte aligned\n", buf); 521*a430fa06SMiquel Raynal return -EINVAL; 522*a430fa06SMiquel Raynal } 523*a430fa06SMiquel Raynal 524*a430fa06SMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip); 525*a430fa06SMiquel Raynal config = &info->config; 526*a430fa06SMiquel Raynal if (set_bus_width_page_size(mtd, config, ®_val)) 527*a430fa06SMiquel Raynal return -EINVAL; 528*a430fa06SMiquel Raynal 529*a430fa06SMiquel Raynal /* Need to be 4-byte aligned */ 530*a430fa06SMiquel Raynal tag_ptr = (char *)tag_buf; 531*a430fa06SMiquel Raynal 532*a430fa06SMiquel Raynal stop_command(info->reg); 533*a430fa06SMiquel Raynal 534*a430fa06SMiquel Raynal if (is_writing) 535*a430fa06SMiquel Raynal bbflags = GEN_BB_READ; 536*a430fa06SMiquel Raynal else 537*a430fa06SMiquel Raynal bbflags = GEN_BB_WRITE; 538*a430fa06SMiquel Raynal 539*a430fa06SMiquel Raynal bounce_buffer_start(&bbstate, (void *)buf, 1 << chip->page_shift, 540*a430fa06SMiquel Raynal bbflags); 541*a430fa06SMiquel Raynal writel((1 << chip->page_shift) - 1, &info->reg->dma_cfg_a); 542*a430fa06SMiquel Raynal writel(virt_to_phys(bbstate.bounce_buffer), &info->reg->data_block_ptr); 543*a430fa06SMiquel Raynal 544*a430fa06SMiquel Raynal /* Set ECC selection, configure ECC settings */ 545*a430fa06SMiquel Raynal if (with_ecc) { 546*a430fa06SMiquel Raynal if (is_writing) 547*a430fa06SMiquel Raynal memcpy(tag_ptr, chip->oob_poi + free->offset, 548*a430fa06SMiquel Raynal chip->ecc.layout->oobavail + TAG_ECC_BYTES); 549*a430fa06SMiquel Raynal tag_size = chip->ecc.layout->oobavail + TAG_ECC_BYTES; 550*a430fa06SMiquel Raynal reg_val |= (CFG_SKIP_SPARE_SEL_4 551*a430fa06SMiquel Raynal | CFG_SKIP_SPARE_ENABLE 552*a430fa06SMiquel Raynal | CFG_HW_ECC_CORRECTION_ENABLE 553*a430fa06SMiquel Raynal | CFG_ECC_EN_TAG_DISABLE 554*a430fa06SMiquel Raynal | CFG_HW_ECC_SEL_RS 555*a430fa06SMiquel Raynal | CFG_HW_ECC_ENABLE 556*a430fa06SMiquel Raynal | CFG_TVAL4 557*a430fa06SMiquel Raynal | (tag_size - 1)); 558*a430fa06SMiquel Raynal 559*a430fa06SMiquel Raynal if (!is_writing) 560*a430fa06SMiquel Raynal tag_size += SKIPPED_SPARE_BYTES; 561*a430fa06SMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)tag_ptr, tag_size, 562*a430fa06SMiquel Raynal bbflags); 563*a430fa06SMiquel Raynal } else { 564*a430fa06SMiquel Raynal tag_size = mtd->oobsize; 565*a430fa06SMiquel Raynal reg_val |= (CFG_SKIP_SPARE_DISABLE 566*a430fa06SMiquel Raynal | CFG_HW_ECC_CORRECTION_DISABLE 567*a430fa06SMiquel Raynal | CFG_ECC_EN_TAG_DISABLE 568*a430fa06SMiquel Raynal | CFG_HW_ECC_DISABLE 569*a430fa06SMiquel Raynal | (tag_size - 1)); 570*a430fa06SMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, 571*a430fa06SMiquel Raynal tag_size, bbflags); 572*a430fa06SMiquel Raynal } 573*a430fa06SMiquel Raynal writel(reg_val, &info->reg->config); 574*a430fa06SMiquel Raynal writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr); 575*a430fa06SMiquel Raynal writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config); 576*a430fa06SMiquel Raynal writel(tag_size - 1, &info->reg->dma_cfg_b); 577*a430fa06SMiquel Raynal 578*a430fa06SMiquel Raynal nand_clear_interrupt_status(info->reg); 579*a430fa06SMiquel Raynal 580*a430fa06SMiquel Raynal reg_val = CMD_CLE | CMD_ALE 581*a430fa06SMiquel Raynal | CMD_SEC_CMD 582*a430fa06SMiquel Raynal | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT) 583*a430fa06SMiquel Raynal | CMD_A_VALID 584*a430fa06SMiquel Raynal | CMD_B_VALID 585*a430fa06SMiquel Raynal | (CMD_TRANS_SIZE_PAGE << CMD_TRANS_SIZE_SHIFT) 586*a430fa06SMiquel Raynal | CMD_CE0; 587*a430fa06SMiquel Raynal if (!is_writing) 588*a430fa06SMiquel Raynal reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX); 589*a430fa06SMiquel Raynal else 590*a430fa06SMiquel Raynal reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX); 591*a430fa06SMiquel Raynal writel(reg_val, &info->reg->command); 592*a430fa06SMiquel Raynal 593*a430fa06SMiquel Raynal /* Setup DMA engine */ 594*a430fa06SMiquel Raynal reg_val = DMA_MST_CTRL_GO_ENABLE 595*a430fa06SMiquel Raynal | DMA_MST_CTRL_BURST_8WORDS 596*a430fa06SMiquel Raynal | DMA_MST_CTRL_EN_A_ENABLE 597*a430fa06SMiquel Raynal | DMA_MST_CTRL_EN_B_ENABLE; 598*a430fa06SMiquel Raynal 599*a430fa06SMiquel Raynal if (!is_writing) 600*a430fa06SMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_READ; 601*a430fa06SMiquel Raynal else 602*a430fa06SMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_WRITE; 603*a430fa06SMiquel Raynal 604*a430fa06SMiquel Raynal writel(reg_val, &info->reg->dma_mst_ctrl); 605*a430fa06SMiquel Raynal 606*a430fa06SMiquel Raynal start_command(info->reg); 607*a430fa06SMiquel Raynal 608*a430fa06SMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) { 609*a430fa06SMiquel Raynal if (!is_writing) 610*a430fa06SMiquel Raynal printf("Read Page 0x%X timeout ", page); 611*a430fa06SMiquel Raynal else 612*a430fa06SMiquel Raynal printf("Write Page 0x%X timeout ", page); 613*a430fa06SMiquel Raynal if (with_ecc) 614*a430fa06SMiquel Raynal printf("with ECC"); 615*a430fa06SMiquel Raynal else 616*a430fa06SMiquel Raynal printf("without ECC"); 617*a430fa06SMiquel Raynal printf("\n"); 618*a430fa06SMiquel Raynal return -EIO; 619*a430fa06SMiquel Raynal } 620*a430fa06SMiquel Raynal 621*a430fa06SMiquel Raynal bounce_buffer_stop(&bbstate_oob); 622*a430fa06SMiquel Raynal bounce_buffer_stop(&bbstate); 623*a430fa06SMiquel Raynal 624*a430fa06SMiquel Raynal if (with_ecc && !is_writing) { 625*a430fa06SMiquel Raynal memcpy(chip->oob_poi, tag_ptr, 626*a430fa06SMiquel Raynal SKIPPED_SPARE_BYTES); 627*a430fa06SMiquel Raynal memcpy(chip->oob_poi + free->offset, 628*a430fa06SMiquel Raynal tag_ptr + SKIPPED_SPARE_BYTES, 629*a430fa06SMiquel Raynal chip->ecc.layout->oobavail); 630*a430fa06SMiquel Raynal reg_val = (u32)check_ecc_error(info->reg, (u8 *)buf, 631*a430fa06SMiquel Raynal 1 << chip->page_shift, 632*a430fa06SMiquel Raynal (u8 *)(tag_ptr + SKIPPED_SPARE_BYTES), 633*a430fa06SMiquel Raynal chip->ecc.layout->oobavail); 634*a430fa06SMiquel Raynal if (reg_val & ECC_TAG_ERROR) 635*a430fa06SMiquel Raynal printf("Read Page 0x%X tag ECC error\n", page); 636*a430fa06SMiquel Raynal if (reg_val & ECC_DATA_ERROR) 637*a430fa06SMiquel Raynal printf("Read Page 0x%X data ECC error\n", 638*a430fa06SMiquel Raynal page); 639*a430fa06SMiquel Raynal if (reg_val & (ECC_DATA_ERROR | ECC_TAG_ERROR)) 640*a430fa06SMiquel Raynal return -EIO; 641*a430fa06SMiquel Raynal } 642*a430fa06SMiquel Raynal return 0; 643*a430fa06SMiquel Raynal } 644*a430fa06SMiquel Raynal 645*a430fa06SMiquel Raynal /** 646*a430fa06SMiquel Raynal * Hardware ecc based page read function 647*a430fa06SMiquel Raynal * 648*a430fa06SMiquel Raynal * @param mtd mtd info structure 649*a430fa06SMiquel Raynal * @param chip nand chip info structure 650*a430fa06SMiquel Raynal * @param buf buffer to store read data 651*a430fa06SMiquel Raynal * @param page page number to read 652*a430fa06SMiquel Raynal * @return 0 when successfully completed 653*a430fa06SMiquel Raynal * -EIO when command timeout 654*a430fa06SMiquel Raynal */ 655*a430fa06SMiquel Raynal static int nand_read_page_hwecc(struct mtd_info *mtd, 656*a430fa06SMiquel Raynal struct nand_chip *chip, uint8_t *buf, int oob_required, int page) 657*a430fa06SMiquel Raynal { 658*a430fa06SMiquel Raynal return nand_rw_page(mtd, chip, buf, page, 1, 0); 659*a430fa06SMiquel Raynal } 660*a430fa06SMiquel Raynal 661*a430fa06SMiquel Raynal /** 662*a430fa06SMiquel Raynal * Hardware ecc based page write function 663*a430fa06SMiquel Raynal * 664*a430fa06SMiquel Raynal * @param mtd mtd info structure 665*a430fa06SMiquel Raynal * @param chip nand chip info structure 666*a430fa06SMiquel Raynal * @param buf data buffer 667*a430fa06SMiquel Raynal */ 668*a430fa06SMiquel Raynal static int nand_write_page_hwecc(struct mtd_info *mtd, 669*a430fa06SMiquel Raynal struct nand_chip *chip, const uint8_t *buf, int oob_required, 670*a430fa06SMiquel Raynal int page) 671*a430fa06SMiquel Raynal { 672*a430fa06SMiquel Raynal nand_rw_page(mtd, chip, (uint8_t *)buf, page, 1, 1); 673*a430fa06SMiquel Raynal return 0; 674*a430fa06SMiquel Raynal } 675*a430fa06SMiquel Raynal 676*a430fa06SMiquel Raynal 677*a430fa06SMiquel Raynal /** 678*a430fa06SMiquel Raynal * Read raw page data without ecc 679*a430fa06SMiquel Raynal * 680*a430fa06SMiquel Raynal * @param mtd mtd info structure 681*a430fa06SMiquel Raynal * @param chip nand chip info structure 682*a430fa06SMiquel Raynal * @param buf buffer to store read data 683*a430fa06SMiquel Raynal * @param page page number to read 684*a430fa06SMiquel Raynal * @return 0 when successfully completed 685*a430fa06SMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned 686*a430fa06SMiquel Raynal * -EIO when command timeout 687*a430fa06SMiquel Raynal */ 688*a430fa06SMiquel Raynal static int nand_read_page_raw(struct mtd_info *mtd, 689*a430fa06SMiquel Raynal struct nand_chip *chip, uint8_t *buf, int oob_required, int page) 690*a430fa06SMiquel Raynal { 691*a430fa06SMiquel Raynal return nand_rw_page(mtd, chip, buf, page, 0, 0); 692*a430fa06SMiquel Raynal } 693*a430fa06SMiquel Raynal 694*a430fa06SMiquel Raynal /** 695*a430fa06SMiquel Raynal * Raw page write function 696*a430fa06SMiquel Raynal * 697*a430fa06SMiquel Raynal * @param mtd mtd info structure 698*a430fa06SMiquel Raynal * @param chip nand chip info structure 699*a430fa06SMiquel Raynal * @param buf data buffer 700*a430fa06SMiquel Raynal */ 701*a430fa06SMiquel Raynal static int nand_write_page_raw(struct mtd_info *mtd, 702*a430fa06SMiquel Raynal struct nand_chip *chip, const uint8_t *buf, 703*a430fa06SMiquel Raynal int oob_required, int page) 704*a430fa06SMiquel Raynal { 705*a430fa06SMiquel Raynal nand_rw_page(mtd, chip, (uint8_t *)buf, page, 0, 1); 706*a430fa06SMiquel Raynal return 0; 707*a430fa06SMiquel Raynal } 708*a430fa06SMiquel Raynal 709*a430fa06SMiquel Raynal /** 710*a430fa06SMiquel Raynal * OOB data read/write function 711*a430fa06SMiquel Raynal * 712*a430fa06SMiquel Raynal * @param mtd mtd info structure 713*a430fa06SMiquel Raynal * @param chip nand chip info structure 714*a430fa06SMiquel Raynal * @param page page number to read 715*a430fa06SMiquel Raynal * @param with_ecc 1 to enable ECC, 0 to disable ECC 716*a430fa06SMiquel Raynal * @param is_writing 0 for read, 1 for write 717*a430fa06SMiquel Raynal * @return 0 when successfully completed 718*a430fa06SMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned 719*a430fa06SMiquel Raynal * -EIO when command timeout 720*a430fa06SMiquel Raynal */ 721*a430fa06SMiquel Raynal static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip, 722*a430fa06SMiquel Raynal int page, int with_ecc, int is_writing) 723*a430fa06SMiquel Raynal { 724*a430fa06SMiquel Raynal u32 reg_val; 725*a430fa06SMiquel Raynal int tag_size; 726*a430fa06SMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree; 727*a430fa06SMiquel Raynal struct nand_drv *info; 728*a430fa06SMiquel Raynal unsigned int bbflags; 729*a430fa06SMiquel Raynal struct bounce_buffer bbstate_oob; 730*a430fa06SMiquel Raynal 731*a430fa06SMiquel Raynal if (((int)chip->oob_poi) & 0x03) 732*a430fa06SMiquel Raynal return -EINVAL; 733*a430fa06SMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip); 734*a430fa06SMiquel Raynal if (set_bus_width_page_size(mtd, &info->config, ®_val)) 735*a430fa06SMiquel Raynal return -EINVAL; 736*a430fa06SMiquel Raynal 737*a430fa06SMiquel Raynal stop_command(info->reg); 738*a430fa06SMiquel Raynal 739*a430fa06SMiquel Raynal /* Set ECC selection */ 740*a430fa06SMiquel Raynal tag_size = mtd->oobsize; 741*a430fa06SMiquel Raynal if (with_ecc) 742*a430fa06SMiquel Raynal reg_val |= CFG_ECC_EN_TAG_ENABLE; 743*a430fa06SMiquel Raynal else 744*a430fa06SMiquel Raynal reg_val |= (CFG_ECC_EN_TAG_DISABLE); 745*a430fa06SMiquel Raynal 746*a430fa06SMiquel Raynal reg_val |= ((tag_size - 1) | 747*a430fa06SMiquel Raynal CFG_SKIP_SPARE_DISABLE | 748*a430fa06SMiquel Raynal CFG_HW_ECC_CORRECTION_DISABLE | 749*a430fa06SMiquel Raynal CFG_HW_ECC_DISABLE); 750*a430fa06SMiquel Raynal writel(reg_val, &info->reg->config); 751*a430fa06SMiquel Raynal 752*a430fa06SMiquel Raynal if (is_writing && with_ecc) 753*a430fa06SMiquel Raynal tag_size -= TAG_ECC_BYTES; 754*a430fa06SMiquel Raynal 755*a430fa06SMiquel Raynal if (is_writing) 756*a430fa06SMiquel Raynal bbflags = GEN_BB_READ; 757*a430fa06SMiquel Raynal else 758*a430fa06SMiquel Raynal bbflags = GEN_BB_WRITE; 759*a430fa06SMiquel Raynal 760*a430fa06SMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, tag_size, 761*a430fa06SMiquel Raynal bbflags); 762*a430fa06SMiquel Raynal writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr); 763*a430fa06SMiquel Raynal 764*a430fa06SMiquel Raynal writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config); 765*a430fa06SMiquel Raynal 766*a430fa06SMiquel Raynal writel(tag_size - 1, &info->reg->dma_cfg_b); 767*a430fa06SMiquel Raynal 768*a430fa06SMiquel Raynal nand_clear_interrupt_status(info->reg); 769*a430fa06SMiquel Raynal 770*a430fa06SMiquel Raynal reg_val = CMD_CLE | CMD_ALE 771*a430fa06SMiquel Raynal | CMD_SEC_CMD 772*a430fa06SMiquel Raynal | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT) 773*a430fa06SMiquel Raynal | CMD_B_VALID 774*a430fa06SMiquel Raynal | CMD_CE0; 775*a430fa06SMiquel Raynal if (!is_writing) 776*a430fa06SMiquel Raynal reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX); 777*a430fa06SMiquel Raynal else 778*a430fa06SMiquel Raynal reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX); 779*a430fa06SMiquel Raynal writel(reg_val, &info->reg->command); 780*a430fa06SMiquel Raynal 781*a430fa06SMiquel Raynal /* Setup DMA engine */ 782*a430fa06SMiquel Raynal reg_val = DMA_MST_CTRL_GO_ENABLE 783*a430fa06SMiquel Raynal | DMA_MST_CTRL_BURST_8WORDS 784*a430fa06SMiquel Raynal | DMA_MST_CTRL_EN_B_ENABLE; 785*a430fa06SMiquel Raynal if (!is_writing) 786*a430fa06SMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_READ; 787*a430fa06SMiquel Raynal else 788*a430fa06SMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_WRITE; 789*a430fa06SMiquel Raynal 790*a430fa06SMiquel Raynal writel(reg_val, &info->reg->dma_mst_ctrl); 791*a430fa06SMiquel Raynal 792*a430fa06SMiquel Raynal start_command(info->reg); 793*a430fa06SMiquel Raynal 794*a430fa06SMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) { 795*a430fa06SMiquel Raynal if (!is_writing) 796*a430fa06SMiquel Raynal printf("Read OOB of Page 0x%X timeout\n", page); 797*a430fa06SMiquel Raynal else 798*a430fa06SMiquel Raynal printf("Write OOB of Page 0x%X timeout\n", page); 799*a430fa06SMiquel Raynal return -EIO; 800*a430fa06SMiquel Raynal } 801*a430fa06SMiquel Raynal 802*a430fa06SMiquel Raynal bounce_buffer_stop(&bbstate_oob); 803*a430fa06SMiquel Raynal 804*a430fa06SMiquel Raynal if (with_ecc && !is_writing) { 805*a430fa06SMiquel Raynal reg_val = (u32)check_ecc_error(info->reg, 0, 0, 806*a430fa06SMiquel Raynal (u8 *)(chip->oob_poi + free->offset), 807*a430fa06SMiquel Raynal chip->ecc.layout->oobavail); 808*a430fa06SMiquel Raynal if (reg_val & ECC_TAG_ERROR) 809*a430fa06SMiquel Raynal printf("Read OOB of Page 0x%X tag ECC error\n", page); 810*a430fa06SMiquel Raynal } 811*a430fa06SMiquel Raynal return 0; 812*a430fa06SMiquel Raynal } 813*a430fa06SMiquel Raynal 814*a430fa06SMiquel Raynal /** 815*a430fa06SMiquel Raynal * OOB data read function 816*a430fa06SMiquel Raynal * 817*a430fa06SMiquel Raynal * @param mtd mtd info structure 818*a430fa06SMiquel Raynal * @param chip nand chip info structure 819*a430fa06SMiquel Raynal * @param page page number to read 820*a430fa06SMiquel Raynal */ 821*a430fa06SMiquel Raynal static int nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, 822*a430fa06SMiquel Raynal int page) 823*a430fa06SMiquel Raynal { 824*a430fa06SMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); 825*a430fa06SMiquel Raynal nand_rw_oob(mtd, chip, page, 0, 0); 826*a430fa06SMiquel Raynal return 0; 827*a430fa06SMiquel Raynal } 828*a430fa06SMiquel Raynal 829*a430fa06SMiquel Raynal /** 830*a430fa06SMiquel Raynal * OOB data write function 831*a430fa06SMiquel Raynal * 832*a430fa06SMiquel Raynal * @param mtd mtd info structure 833*a430fa06SMiquel Raynal * @param chip nand chip info structure 834*a430fa06SMiquel Raynal * @param page page number to write 835*a430fa06SMiquel Raynal * @return 0 when successfully completed 836*a430fa06SMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned 837*a430fa06SMiquel Raynal * -EIO when command timeout 838*a430fa06SMiquel Raynal */ 839*a430fa06SMiquel Raynal static int nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, 840*a430fa06SMiquel Raynal int page) 841*a430fa06SMiquel Raynal { 842*a430fa06SMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); 843*a430fa06SMiquel Raynal 844*a430fa06SMiquel Raynal return nand_rw_oob(mtd, chip, page, 0, 1); 845*a430fa06SMiquel Raynal } 846*a430fa06SMiquel Raynal 847*a430fa06SMiquel Raynal /** 848*a430fa06SMiquel Raynal * Set up NAND memory timings according to the provided parameters 849*a430fa06SMiquel Raynal * 850*a430fa06SMiquel Raynal * @param timing Timing parameters 851*a430fa06SMiquel Raynal * @param reg NAND controller register address 852*a430fa06SMiquel Raynal */ 853*a430fa06SMiquel Raynal static void setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT], 854*a430fa06SMiquel Raynal struct nand_ctlr *reg) 855*a430fa06SMiquel Raynal { 856*a430fa06SMiquel Raynal u32 reg_val, clk_rate, clk_period, time_val; 857*a430fa06SMiquel Raynal 858*a430fa06SMiquel Raynal clk_rate = (u32)clock_get_periph_rate(PERIPH_ID_NDFLASH, 859*a430fa06SMiquel Raynal CLOCK_ID_PERIPH) / 1000000; 860*a430fa06SMiquel Raynal clk_period = 1000 / clk_rate; 861*a430fa06SMiquel Raynal reg_val = ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) << 862*a430fa06SMiquel Raynal TIMING_TRP_RESP_CNT_SHIFT) & TIMING_TRP_RESP_CNT_MASK; 863*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_TWB] / clk_period) << 864*a430fa06SMiquel Raynal TIMING_TWB_CNT_SHIFT) & TIMING_TWB_CNT_MASK; 865*a430fa06SMiquel Raynal time_val = timing[FDT_NAND_MAX_TCR_TAR_TRR] / clk_period; 866*a430fa06SMiquel Raynal if (time_val > 2) 867*a430fa06SMiquel Raynal reg_val |= ((time_val - 2) << TIMING_TCR_TAR_TRR_CNT_SHIFT) & 868*a430fa06SMiquel Raynal TIMING_TCR_TAR_TRR_CNT_MASK; 869*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_TWHR] / clk_period) << 870*a430fa06SMiquel Raynal TIMING_TWHR_CNT_SHIFT) & TIMING_TWHR_CNT_MASK; 871*a430fa06SMiquel Raynal time_val = timing[FDT_NAND_MAX_TCS_TCH_TALS_TALH] / clk_period; 872*a430fa06SMiquel Raynal if (time_val > 1) 873*a430fa06SMiquel Raynal reg_val |= ((time_val - 1) << TIMING_TCS_CNT_SHIFT) & 874*a430fa06SMiquel Raynal TIMING_TCS_CNT_MASK; 875*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_TWH] / clk_period) << 876*a430fa06SMiquel Raynal TIMING_TWH_CNT_SHIFT) & TIMING_TWH_CNT_MASK; 877*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_TWP] / clk_period) << 878*a430fa06SMiquel Raynal TIMING_TWP_CNT_SHIFT) & TIMING_TWP_CNT_MASK; 879*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_TRH] / clk_period) << 880*a430fa06SMiquel Raynal TIMING_TRH_CNT_SHIFT) & TIMING_TRH_CNT_MASK; 881*a430fa06SMiquel Raynal reg_val |= ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) << 882*a430fa06SMiquel Raynal TIMING_TRP_CNT_SHIFT) & TIMING_TRP_CNT_MASK; 883*a430fa06SMiquel Raynal writel(reg_val, ®->timing); 884*a430fa06SMiquel Raynal 885*a430fa06SMiquel Raynal reg_val = 0; 886*a430fa06SMiquel Raynal time_val = timing[FDT_NAND_TADL] / clk_period; 887*a430fa06SMiquel Raynal if (time_val > 2) 888*a430fa06SMiquel Raynal reg_val = (time_val - 2) & TIMING2_TADL_CNT_MASK; 889*a430fa06SMiquel Raynal writel(reg_val, ®->timing2); 890*a430fa06SMiquel Raynal } 891*a430fa06SMiquel Raynal 892*a430fa06SMiquel Raynal /** 893*a430fa06SMiquel Raynal * Decode NAND parameters from the device tree 894*a430fa06SMiquel Raynal * 895*a430fa06SMiquel Raynal * @param dev Driver model device 896*a430fa06SMiquel Raynal * @param config Device tree NAND configuration 897*a430fa06SMiquel Raynal * @return 0 if ok, -ve on error (FDT_ERR_...) 898*a430fa06SMiquel Raynal */ 899*a430fa06SMiquel Raynal static int fdt_decode_nand(struct udevice *dev, struct fdt_nand *config) 900*a430fa06SMiquel Raynal { 901*a430fa06SMiquel Raynal int err; 902*a430fa06SMiquel Raynal 903*a430fa06SMiquel Raynal config->reg = (struct nand_ctlr *)dev_read_addr(dev); 904*a430fa06SMiquel Raynal config->enabled = dev_read_enabled(dev); 905*a430fa06SMiquel Raynal config->width = dev_read_u32_default(dev, "nvidia,nand-width", 8); 906*a430fa06SMiquel Raynal err = gpio_request_by_name(dev, "nvidia,wp-gpios", 0, &config->wp_gpio, 907*a430fa06SMiquel Raynal GPIOD_IS_OUT); 908*a430fa06SMiquel Raynal if (err) 909*a430fa06SMiquel Raynal return err; 910*a430fa06SMiquel Raynal err = dev_read_u32_array(dev, "nvidia,timing", config->timing, 911*a430fa06SMiquel Raynal FDT_NAND_TIMING_COUNT); 912*a430fa06SMiquel Raynal if (err < 0) 913*a430fa06SMiquel Raynal return err; 914*a430fa06SMiquel Raynal 915*a430fa06SMiquel Raynal return 0; 916*a430fa06SMiquel Raynal } 917*a430fa06SMiquel Raynal 918*a430fa06SMiquel Raynal static int tegra_probe(struct udevice *dev) 919*a430fa06SMiquel Raynal { 920*a430fa06SMiquel Raynal struct tegra_nand_info *tegra = dev_get_priv(dev); 921*a430fa06SMiquel Raynal struct nand_chip *nand = &tegra->nand_chip; 922*a430fa06SMiquel Raynal struct nand_drv *info = &tegra->nand_ctrl; 923*a430fa06SMiquel Raynal struct fdt_nand *config = &info->config; 924*a430fa06SMiquel Raynal struct mtd_info *our_mtd; 925*a430fa06SMiquel Raynal int ret; 926*a430fa06SMiquel Raynal 927*a430fa06SMiquel Raynal if (fdt_decode_nand(dev, config)) { 928*a430fa06SMiquel Raynal printf("Could not decode nand-flash in device tree\n"); 929*a430fa06SMiquel Raynal return -1; 930*a430fa06SMiquel Raynal } 931*a430fa06SMiquel Raynal if (!config->enabled) 932*a430fa06SMiquel Raynal return -1; 933*a430fa06SMiquel Raynal info->reg = config->reg; 934*a430fa06SMiquel Raynal nand->ecc.mode = NAND_ECC_HW; 935*a430fa06SMiquel Raynal nand->ecc.layout = &eccoob; 936*a430fa06SMiquel Raynal 937*a430fa06SMiquel Raynal nand->options = LP_OPTIONS; 938*a430fa06SMiquel Raynal nand->cmdfunc = nand_command; 939*a430fa06SMiquel Raynal nand->read_byte = read_byte; 940*a430fa06SMiquel Raynal nand->read_buf = read_buf; 941*a430fa06SMiquel Raynal nand->ecc.read_page = nand_read_page_hwecc; 942*a430fa06SMiquel Raynal nand->ecc.write_page = nand_write_page_hwecc; 943*a430fa06SMiquel Raynal nand->ecc.read_page_raw = nand_read_page_raw; 944*a430fa06SMiquel Raynal nand->ecc.write_page_raw = nand_write_page_raw; 945*a430fa06SMiquel Raynal nand->ecc.read_oob = nand_read_oob; 946*a430fa06SMiquel Raynal nand->ecc.write_oob = nand_write_oob; 947*a430fa06SMiquel Raynal nand->ecc.strength = 1; 948*a430fa06SMiquel Raynal nand->select_chip = nand_select_chip; 949*a430fa06SMiquel Raynal nand->dev_ready = nand_dev_ready; 950*a430fa06SMiquel Raynal nand_set_controller_data(nand, &tegra->nand_ctrl); 951*a430fa06SMiquel Raynal 952*a430fa06SMiquel Raynal /* Disable subpage writes as we do not provide ecc->hwctl */ 953*a430fa06SMiquel Raynal nand->options |= NAND_NO_SUBPAGE_WRITE; 954*a430fa06SMiquel Raynal 955*a430fa06SMiquel Raynal /* Adjust controller clock rate */ 956*a430fa06SMiquel Raynal clock_start_periph_pll(PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH, 52000000); 957*a430fa06SMiquel Raynal 958*a430fa06SMiquel Raynal /* Adjust timing for NAND device */ 959*a430fa06SMiquel Raynal setup_timing(config->timing, info->reg); 960*a430fa06SMiquel Raynal 961*a430fa06SMiquel Raynal dm_gpio_set_value(&config->wp_gpio, 1); 962*a430fa06SMiquel Raynal 963*a430fa06SMiquel Raynal our_mtd = nand_to_mtd(nand); 964*a430fa06SMiquel Raynal ret = nand_scan_ident(our_mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL); 965*a430fa06SMiquel Raynal if (ret) 966*a430fa06SMiquel Raynal return ret; 967*a430fa06SMiquel Raynal 968*a430fa06SMiquel Raynal nand->ecc.size = our_mtd->writesize; 969*a430fa06SMiquel Raynal nand->ecc.bytes = our_mtd->oobsize; 970*a430fa06SMiquel Raynal 971*a430fa06SMiquel Raynal ret = nand_scan_tail(our_mtd); 972*a430fa06SMiquel Raynal if (ret) 973*a430fa06SMiquel Raynal return ret; 974*a430fa06SMiquel Raynal 975*a430fa06SMiquel Raynal ret = nand_register(0, our_mtd); 976*a430fa06SMiquel Raynal if (ret) { 977*a430fa06SMiquel Raynal dev_err(dev, "Failed to register MTD: %d\n", ret); 978*a430fa06SMiquel Raynal return ret; 979*a430fa06SMiquel Raynal } 980*a430fa06SMiquel Raynal 981*a430fa06SMiquel Raynal return 0; 982*a430fa06SMiquel Raynal } 983*a430fa06SMiquel Raynal 984*a430fa06SMiquel Raynal U_BOOT_DRIVER(tegra_nand) = { 985*a430fa06SMiquel Raynal .name = "tegra-nand", 986*a430fa06SMiquel Raynal .id = UCLASS_MTD, 987*a430fa06SMiquel Raynal .of_match = tegra_nand_dt_ids, 988*a430fa06SMiquel Raynal .probe = tegra_probe, 989*a430fa06SMiquel Raynal .priv_auto_alloc_size = sizeof(struct tegra_nand_info), 990*a430fa06SMiquel Raynal }; 991*a430fa06SMiquel Raynal 992*a430fa06SMiquel Raynal void board_nand_init(void) 993*a430fa06SMiquel Raynal { 994*a430fa06SMiquel Raynal struct udevice *dev; 995*a430fa06SMiquel Raynal int ret; 996*a430fa06SMiquel Raynal 997*a430fa06SMiquel Raynal ret = uclass_get_device_by_driver(UCLASS_MTD, 998*a430fa06SMiquel Raynal DM_GET_DRIVER(tegra_nand), &dev); 999*a430fa06SMiquel Raynal if (ret && ret != -ENODEV) 1000*a430fa06SMiquel Raynal pr_err("Failed to initialize %s. (error %d)\n", dev->name, 1001*a430fa06SMiquel Raynal ret); 1002*a430fa06SMiquel Raynal } 1003