193db446aSBoris Brezillon /* 293db446aSBoris Brezillon * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 393db446aSBoris Brezillon * Copyright 2008 Sascha Hauer, kernel@pengutronix.de 493db446aSBoris Brezillon * 593db446aSBoris Brezillon * This program is free software; you can redistribute it and/or 693db446aSBoris Brezillon * modify it under the terms of the GNU General Public License 793db446aSBoris Brezillon * as published by the Free Software Foundation; either version 2 893db446aSBoris Brezillon * of the License, or (at your option) any later version. 993db446aSBoris Brezillon * This program is distributed in the hope that it will be useful, 1093db446aSBoris Brezillon * but WITHOUT ANY WARRANTY; without even the implied warranty of 1193db446aSBoris Brezillon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1293db446aSBoris Brezillon * GNU General Public License for more details. 1393db446aSBoris Brezillon * 1493db446aSBoris Brezillon * You should have received a copy of the GNU General Public License 1593db446aSBoris Brezillon * along with this program; if not, write to the Free Software 1693db446aSBoris Brezillon * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 1793db446aSBoris Brezillon * MA 02110-1301, USA. 1893db446aSBoris Brezillon */ 1993db446aSBoris Brezillon 2093db446aSBoris Brezillon #include <linux/delay.h> 2193db446aSBoris Brezillon #include <linux/slab.h> 2293db446aSBoris Brezillon #include <linux/init.h> 2393db446aSBoris Brezillon #include <linux/module.h> 2493db446aSBoris Brezillon #include <linux/mtd/mtd.h> 2593db446aSBoris Brezillon #include <linux/mtd/rawnand.h> 2693db446aSBoris Brezillon #include <linux/mtd/partitions.h> 2793db446aSBoris Brezillon #include <linux/interrupt.h> 2893db446aSBoris Brezillon #include <linux/device.h> 2993db446aSBoris Brezillon #include <linux/platform_device.h> 3093db446aSBoris Brezillon #include <linux/clk.h> 3193db446aSBoris Brezillon #include <linux/err.h> 3293db446aSBoris Brezillon #include <linux/io.h> 3393db446aSBoris Brezillon #include <linux/irq.h> 3493db446aSBoris Brezillon #include <linux/completion.h> 3593db446aSBoris Brezillon #include <linux/of.h> 3693db446aSBoris Brezillon #include <linux/of_device.h> 3793db446aSBoris Brezillon 3893db446aSBoris Brezillon #include <asm/mach/flash.h> 3993db446aSBoris Brezillon #include <linux/platform_data/mtd-mxc_nand.h> 4093db446aSBoris Brezillon 4193db446aSBoris Brezillon #define DRIVER_NAME "mxc_nand" 4293db446aSBoris Brezillon 4393db446aSBoris Brezillon /* Addresses for NFC registers */ 4493db446aSBoris Brezillon #define NFC_V1_V2_BUF_SIZE (host->regs + 0x00) 4593db446aSBoris Brezillon #define NFC_V1_V2_BUF_ADDR (host->regs + 0x04) 4693db446aSBoris Brezillon #define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06) 4793db446aSBoris Brezillon #define NFC_V1_V2_FLASH_CMD (host->regs + 0x08) 4893db446aSBoris Brezillon #define NFC_V1_V2_CONFIG (host->regs + 0x0a) 4993db446aSBoris Brezillon #define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c) 5093db446aSBoris Brezillon #define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e) 51*3f77f244SMartin Kaiser #define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10) 5293db446aSBoris Brezillon #define NFC_V1_V2_WRPROT (host->regs + 0x12) 5393db446aSBoris Brezillon #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) 5493db446aSBoris Brezillon #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) 5593db446aSBoris Brezillon #define NFC_V21_UNLOCKSTART_BLKADDR0 (host->regs + 0x20) 5693db446aSBoris Brezillon #define NFC_V21_UNLOCKSTART_BLKADDR1 (host->regs + 0x24) 5793db446aSBoris Brezillon #define NFC_V21_UNLOCKSTART_BLKADDR2 (host->regs + 0x28) 5893db446aSBoris Brezillon #define NFC_V21_UNLOCKSTART_BLKADDR3 (host->regs + 0x2c) 5993db446aSBoris Brezillon #define NFC_V21_UNLOCKEND_BLKADDR0 (host->regs + 0x22) 6093db446aSBoris Brezillon #define NFC_V21_UNLOCKEND_BLKADDR1 (host->regs + 0x26) 6193db446aSBoris Brezillon #define NFC_V21_UNLOCKEND_BLKADDR2 (host->regs + 0x2a) 6293db446aSBoris Brezillon #define NFC_V21_UNLOCKEND_BLKADDR3 (host->regs + 0x2e) 6393db446aSBoris Brezillon #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18) 6493db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) 6593db446aSBoris Brezillon #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) 6693db446aSBoris Brezillon 6793db446aSBoris Brezillon #define NFC_V2_CONFIG1_ECC_MODE_4 (1 << 0) 6893db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_SP_EN (1 << 2) 6993db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3) 7093db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4) 7193db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_BIG (1 << 5) 7293db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_RST (1 << 6) 7393db446aSBoris Brezillon #define NFC_V1_V2_CONFIG1_CE (1 << 7) 7493db446aSBoris Brezillon #define NFC_V2_CONFIG1_ONE_CYCLE (1 << 8) 7593db446aSBoris Brezillon #define NFC_V2_CONFIG1_PPB(x) (((x) & 0x3) << 9) 7693db446aSBoris Brezillon #define NFC_V2_CONFIG1_FP_INT (1 << 11) 7793db446aSBoris Brezillon 7893db446aSBoris Brezillon #define NFC_V1_V2_CONFIG2_INT (1 << 15) 7993db446aSBoris Brezillon 8093db446aSBoris Brezillon /* 8193db446aSBoris Brezillon * Operation modes for the NFC. Valid for v1, v2 and v3 8293db446aSBoris Brezillon * type controllers. 8393db446aSBoris Brezillon */ 8493db446aSBoris Brezillon #define NFC_CMD (1 << 0) 8593db446aSBoris Brezillon #define NFC_ADDR (1 << 1) 8693db446aSBoris Brezillon #define NFC_INPUT (1 << 2) 8793db446aSBoris Brezillon #define NFC_OUTPUT (1 << 3) 8893db446aSBoris Brezillon #define NFC_ID (1 << 4) 8993db446aSBoris Brezillon #define NFC_STATUS (1 << 5) 9093db446aSBoris Brezillon 9193db446aSBoris Brezillon #define NFC_V3_FLASH_CMD (host->regs_axi + 0x00) 9293db446aSBoris Brezillon #define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04) 9393db446aSBoris Brezillon 9493db446aSBoris Brezillon #define NFC_V3_CONFIG1 (host->regs_axi + 0x34) 9593db446aSBoris Brezillon #define NFC_V3_CONFIG1_SP_EN (1 << 0) 9693db446aSBoris Brezillon #define NFC_V3_CONFIG1_RBA(x) (((x) & 0x7 ) << 4) 9793db446aSBoris Brezillon 9893db446aSBoris Brezillon #define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38) 9993db446aSBoris Brezillon 10093db446aSBoris Brezillon #define NFC_V3_LAUNCH (host->regs_axi + 0x40) 10193db446aSBoris Brezillon 10293db446aSBoris Brezillon #define NFC_V3_WRPROT (host->regs_ip + 0x0) 10393db446aSBoris Brezillon #define NFC_V3_WRPROT_LOCK_TIGHT (1 << 0) 10493db446aSBoris Brezillon #define NFC_V3_WRPROT_LOCK (1 << 1) 10593db446aSBoris Brezillon #define NFC_V3_WRPROT_UNLOCK (1 << 2) 10693db446aSBoris Brezillon #define NFC_V3_WRPROT_BLS_UNLOCK (2 << 6) 10793db446aSBoris Brezillon 10893db446aSBoris Brezillon #define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04) 10993db446aSBoris Brezillon 11093db446aSBoris Brezillon #define NFC_V3_CONFIG2 (host->regs_ip + 0x24) 11193db446aSBoris Brezillon #define NFC_V3_CONFIG2_PS_512 (0 << 0) 11293db446aSBoris Brezillon #define NFC_V3_CONFIG2_PS_2048 (1 << 0) 11393db446aSBoris Brezillon #define NFC_V3_CONFIG2_PS_4096 (2 << 0) 11493db446aSBoris Brezillon #define NFC_V3_CONFIG2_ONE_CYCLE (1 << 2) 11593db446aSBoris Brezillon #define NFC_V3_CONFIG2_ECC_EN (1 << 3) 11693db446aSBoris Brezillon #define NFC_V3_CONFIG2_2CMD_PHASES (1 << 4) 11793db446aSBoris Brezillon #define NFC_V3_CONFIG2_NUM_ADDR_PHASE0 (1 << 5) 11893db446aSBoris Brezillon #define NFC_V3_CONFIG2_ECC_MODE_8 (1 << 6) 11993db446aSBoris Brezillon #define NFC_V3_CONFIG2_PPB(x, shift) (((x) & 0x3) << shift) 12093db446aSBoris Brezillon #define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x) (((x) & 0x3) << 12) 12193db446aSBoris Brezillon #define NFC_V3_CONFIG2_INT_MSK (1 << 15) 12293db446aSBoris Brezillon #define NFC_V3_CONFIG2_ST_CMD(x) (((x) & 0xff) << 24) 12393db446aSBoris Brezillon #define NFC_V3_CONFIG2_SPAS(x) (((x) & 0xff) << 16) 12493db446aSBoris Brezillon 12593db446aSBoris Brezillon #define NFC_V3_CONFIG3 (host->regs_ip + 0x28) 12693db446aSBoris Brezillon #define NFC_V3_CONFIG3_ADD_OP(x) (((x) & 0x3) << 0) 12793db446aSBoris Brezillon #define NFC_V3_CONFIG3_FW8 (1 << 3) 12893db446aSBoris Brezillon #define NFC_V3_CONFIG3_SBB(x) (((x) & 0x7) << 8) 12993db446aSBoris Brezillon #define NFC_V3_CONFIG3_NUM_OF_DEVICES(x) (((x) & 0x7) << 12) 13093db446aSBoris Brezillon #define NFC_V3_CONFIG3_RBB_MODE (1 << 15) 13193db446aSBoris Brezillon #define NFC_V3_CONFIG3_NO_SDMA (1 << 20) 13293db446aSBoris Brezillon 13393db446aSBoris Brezillon #define NFC_V3_IPC (host->regs_ip + 0x2C) 13493db446aSBoris Brezillon #define NFC_V3_IPC_CREQ (1 << 0) 13593db446aSBoris Brezillon #define NFC_V3_IPC_INT (1 << 31) 13693db446aSBoris Brezillon 13793db446aSBoris Brezillon #define NFC_V3_DELAY_LINE (host->regs_ip + 0x34) 13893db446aSBoris Brezillon 13993db446aSBoris Brezillon struct mxc_nand_host; 14093db446aSBoris Brezillon 14193db446aSBoris Brezillon struct mxc_nand_devtype_data { 14293db446aSBoris Brezillon void (*preset)(struct mtd_info *); 14393db446aSBoris Brezillon int (*read_page)(struct nand_chip *chip, void *buf, void *oob, bool ecc, 14493db446aSBoris Brezillon int page); 14593db446aSBoris Brezillon void (*send_cmd)(struct mxc_nand_host *, uint16_t, int); 14693db446aSBoris Brezillon void (*send_addr)(struct mxc_nand_host *, uint16_t, int); 14793db446aSBoris Brezillon void (*send_page)(struct mtd_info *, unsigned int); 14893db446aSBoris Brezillon void (*send_read_id)(struct mxc_nand_host *); 14993db446aSBoris Brezillon uint16_t (*get_dev_status)(struct mxc_nand_host *); 15093db446aSBoris Brezillon int (*check_int)(struct mxc_nand_host *); 15193db446aSBoris Brezillon void (*irq_control)(struct mxc_nand_host *, int); 15293db446aSBoris Brezillon u32 (*get_ecc_status)(struct mxc_nand_host *); 15393db446aSBoris Brezillon const struct mtd_ooblayout_ops *ooblayout; 15493db446aSBoris Brezillon void (*select_chip)(struct mtd_info *mtd, int chip); 15593db446aSBoris Brezillon int (*setup_data_interface)(struct mtd_info *mtd, int csline, 15693db446aSBoris Brezillon const struct nand_data_interface *conf); 15793db446aSBoris Brezillon void (*enable_hwecc)(struct nand_chip *chip, bool enable); 15893db446aSBoris Brezillon 15993db446aSBoris Brezillon /* 16093db446aSBoris Brezillon * On i.MX21 the CONFIG2:INT bit cannot be read if interrupts are masked 16193db446aSBoris Brezillon * (CONFIG1:INT_MSK is set). To handle this the driver uses 16293db446aSBoris Brezillon * enable_irq/disable_irq_nosync instead of CONFIG1:INT_MSK 16393db446aSBoris Brezillon */ 16493db446aSBoris Brezillon int irqpending_quirk; 16593db446aSBoris Brezillon int needs_ip; 16693db446aSBoris Brezillon 16793db446aSBoris Brezillon size_t regs_offset; 16893db446aSBoris Brezillon size_t spare0_offset; 16993db446aSBoris Brezillon size_t axi_offset; 17093db446aSBoris Brezillon 17193db446aSBoris Brezillon int spare_len; 17293db446aSBoris Brezillon int eccbytes; 17393db446aSBoris Brezillon int eccsize; 17493db446aSBoris Brezillon int ppb_shift; 17593db446aSBoris Brezillon }; 17693db446aSBoris Brezillon 17793db446aSBoris Brezillon struct mxc_nand_host { 17893db446aSBoris Brezillon struct nand_chip nand; 17993db446aSBoris Brezillon struct device *dev; 18093db446aSBoris Brezillon 18193db446aSBoris Brezillon void __iomem *spare0; 18293db446aSBoris Brezillon void __iomem *main_area0; 18393db446aSBoris Brezillon 18493db446aSBoris Brezillon void __iomem *base; 18593db446aSBoris Brezillon void __iomem *regs; 18693db446aSBoris Brezillon void __iomem *regs_axi; 18793db446aSBoris Brezillon void __iomem *regs_ip; 18893db446aSBoris Brezillon int status_request; 18993db446aSBoris Brezillon struct clk *clk; 19093db446aSBoris Brezillon int clk_act; 19193db446aSBoris Brezillon int irq; 19293db446aSBoris Brezillon int eccsize; 19393db446aSBoris Brezillon int used_oobsize; 19493db446aSBoris Brezillon int active_cs; 19593db446aSBoris Brezillon 19693db446aSBoris Brezillon struct completion op_completion; 19793db446aSBoris Brezillon 19893db446aSBoris Brezillon uint8_t *data_buf; 19993db446aSBoris Brezillon unsigned int buf_start; 20093db446aSBoris Brezillon 20193db446aSBoris Brezillon const struct mxc_nand_devtype_data *devtype_data; 20293db446aSBoris Brezillon struct mxc_nand_platform_data pdata; 20393db446aSBoris Brezillon }; 20493db446aSBoris Brezillon 20593db446aSBoris Brezillon static const char * const part_probes[] = { 20693db446aSBoris Brezillon "cmdlinepart", "RedBoot", "ofpart", NULL }; 20793db446aSBoris Brezillon 20893db446aSBoris Brezillon static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) 20993db446aSBoris Brezillon { 21093db446aSBoris Brezillon int i; 21193db446aSBoris Brezillon u32 *t = trg; 21293db446aSBoris Brezillon const __iomem u32 *s = src; 21393db446aSBoris Brezillon 21493db446aSBoris Brezillon for (i = 0; i < (size >> 2); i++) 21593db446aSBoris Brezillon *t++ = __raw_readl(s++); 21693db446aSBoris Brezillon } 21793db446aSBoris Brezillon 21893db446aSBoris Brezillon static void memcpy16_fromio(void *trg, const void __iomem *src, size_t size) 21993db446aSBoris Brezillon { 22093db446aSBoris Brezillon int i; 22193db446aSBoris Brezillon u16 *t = trg; 22293db446aSBoris Brezillon const __iomem u16 *s = src; 22393db446aSBoris Brezillon 22493db446aSBoris Brezillon /* We assume that src (IO) is always 32bit aligned */ 22593db446aSBoris Brezillon if (PTR_ALIGN(trg, 4) == trg && IS_ALIGNED(size, 4)) { 22693db446aSBoris Brezillon memcpy32_fromio(trg, src, size); 22793db446aSBoris Brezillon return; 22893db446aSBoris Brezillon } 22993db446aSBoris Brezillon 23093db446aSBoris Brezillon for (i = 0; i < (size >> 1); i++) 23193db446aSBoris Brezillon *t++ = __raw_readw(s++); 23293db446aSBoris Brezillon } 23393db446aSBoris Brezillon 23493db446aSBoris Brezillon static inline void memcpy32_toio(void __iomem *trg, const void *src, int size) 23593db446aSBoris Brezillon { 23693db446aSBoris Brezillon /* __iowrite32_copy use 32bit size values so divide by 4 */ 23793db446aSBoris Brezillon __iowrite32_copy(trg, src, size / 4); 23893db446aSBoris Brezillon } 23993db446aSBoris Brezillon 24093db446aSBoris Brezillon static void memcpy16_toio(void __iomem *trg, const void *src, int size) 24193db446aSBoris Brezillon { 24293db446aSBoris Brezillon int i; 24393db446aSBoris Brezillon __iomem u16 *t = trg; 24493db446aSBoris Brezillon const u16 *s = src; 24593db446aSBoris Brezillon 24693db446aSBoris Brezillon /* We assume that trg (IO) is always 32bit aligned */ 24793db446aSBoris Brezillon if (PTR_ALIGN(src, 4) == src && IS_ALIGNED(size, 4)) { 24893db446aSBoris Brezillon memcpy32_toio(trg, src, size); 24993db446aSBoris Brezillon return; 25093db446aSBoris Brezillon } 25193db446aSBoris Brezillon 25293db446aSBoris Brezillon for (i = 0; i < (size >> 1); i++) 25393db446aSBoris Brezillon __raw_writew(*s++, t++); 25493db446aSBoris Brezillon } 25593db446aSBoris Brezillon 25693db446aSBoris Brezillon /* 25793db446aSBoris Brezillon * The controller splits a page into data chunks of 512 bytes + partial oob. 25893db446aSBoris Brezillon * There are writesize / 512 such chunks, the size of the partial oob parts is 25993db446aSBoris Brezillon * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then 26093db446aSBoris Brezillon * contains additionally the byte lost by rounding (if any). 26193db446aSBoris Brezillon * This function handles the needed shuffling between host->data_buf (which 26293db446aSBoris Brezillon * holds a page in natural order, i.e. writesize bytes data + oobsize bytes 26393db446aSBoris Brezillon * spare) and the NFC buffer. 26493db446aSBoris Brezillon */ 26593db446aSBoris Brezillon static void copy_spare(struct mtd_info *mtd, bool bfrom, void *buf) 26693db446aSBoris Brezillon { 26793db446aSBoris Brezillon struct nand_chip *this = mtd_to_nand(mtd); 26893db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(this); 26993db446aSBoris Brezillon u16 i, oob_chunk_size; 27093db446aSBoris Brezillon u16 num_chunks = mtd->writesize / 512; 27193db446aSBoris Brezillon 27293db446aSBoris Brezillon u8 *d = buf; 27393db446aSBoris Brezillon u8 __iomem *s = host->spare0; 27493db446aSBoris Brezillon u16 sparebuf_size = host->devtype_data->spare_len; 27593db446aSBoris Brezillon 27693db446aSBoris Brezillon /* size of oob chunk for all but possibly the last one */ 27793db446aSBoris Brezillon oob_chunk_size = (host->used_oobsize / num_chunks) & ~1; 27893db446aSBoris Brezillon 27993db446aSBoris Brezillon if (bfrom) { 28093db446aSBoris Brezillon for (i = 0; i < num_chunks - 1; i++) 28193db446aSBoris Brezillon memcpy16_fromio(d + i * oob_chunk_size, 28293db446aSBoris Brezillon s + i * sparebuf_size, 28393db446aSBoris Brezillon oob_chunk_size); 28493db446aSBoris Brezillon 28593db446aSBoris Brezillon /* the last chunk */ 28693db446aSBoris Brezillon memcpy16_fromio(d + i * oob_chunk_size, 28793db446aSBoris Brezillon s + i * sparebuf_size, 28893db446aSBoris Brezillon host->used_oobsize - i * oob_chunk_size); 28993db446aSBoris Brezillon } else { 29093db446aSBoris Brezillon for (i = 0; i < num_chunks - 1; i++) 29193db446aSBoris Brezillon memcpy16_toio(&s[i * sparebuf_size], 29293db446aSBoris Brezillon &d[i * oob_chunk_size], 29393db446aSBoris Brezillon oob_chunk_size); 29493db446aSBoris Brezillon 29593db446aSBoris Brezillon /* the last chunk */ 29693db446aSBoris Brezillon memcpy16_toio(&s[i * sparebuf_size], 29793db446aSBoris Brezillon &d[i * oob_chunk_size], 29893db446aSBoris Brezillon host->used_oobsize - i * oob_chunk_size); 29993db446aSBoris Brezillon } 30093db446aSBoris Brezillon } 30193db446aSBoris Brezillon 30293db446aSBoris Brezillon /* 30393db446aSBoris Brezillon * MXC NANDFC can only perform full page+spare or spare-only read/write. When 30493db446aSBoris Brezillon * the upper layers perform a read/write buf operation, the saved column address 30593db446aSBoris Brezillon * is used to index into the full page. So usually this function is called with 30693db446aSBoris Brezillon * column == 0 (unless no column cycle is needed indicated by column == -1) 30793db446aSBoris Brezillon */ 30893db446aSBoris Brezillon static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) 30993db446aSBoris Brezillon { 31093db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 31193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 31293db446aSBoris Brezillon 31393db446aSBoris Brezillon /* Write out column address, if necessary */ 31493db446aSBoris Brezillon if (column != -1) { 31593db446aSBoris Brezillon host->devtype_data->send_addr(host, column & 0xff, 31693db446aSBoris Brezillon page_addr == -1); 31793db446aSBoris Brezillon if (mtd->writesize > 512) 31893db446aSBoris Brezillon /* another col addr cycle for 2k page */ 31993db446aSBoris Brezillon host->devtype_data->send_addr(host, 32093db446aSBoris Brezillon (column >> 8) & 0xff, 32193db446aSBoris Brezillon false); 32293db446aSBoris Brezillon } 32393db446aSBoris Brezillon 32493db446aSBoris Brezillon /* Write out page address, if necessary */ 32593db446aSBoris Brezillon if (page_addr != -1) { 32693db446aSBoris Brezillon /* paddr_0 - p_addr_7 */ 32793db446aSBoris Brezillon host->devtype_data->send_addr(host, (page_addr & 0xff), false); 32893db446aSBoris Brezillon 32993db446aSBoris Brezillon if (mtd->writesize > 512) { 33093db446aSBoris Brezillon if (mtd->size >= 0x10000000) { 33193db446aSBoris Brezillon /* paddr_8 - paddr_15 */ 33293db446aSBoris Brezillon host->devtype_data->send_addr(host, 33393db446aSBoris Brezillon (page_addr >> 8) & 0xff, 33493db446aSBoris Brezillon false); 33593db446aSBoris Brezillon host->devtype_data->send_addr(host, 33693db446aSBoris Brezillon (page_addr >> 16) & 0xff, 33793db446aSBoris Brezillon true); 33893db446aSBoris Brezillon } else 33993db446aSBoris Brezillon /* paddr_8 - paddr_15 */ 34093db446aSBoris Brezillon host->devtype_data->send_addr(host, 34193db446aSBoris Brezillon (page_addr >> 8) & 0xff, true); 34293db446aSBoris Brezillon } else { 34393db446aSBoris Brezillon if (nand_chip->options & NAND_ROW_ADDR_3) { 34493db446aSBoris Brezillon /* paddr_8 - paddr_15 */ 34593db446aSBoris Brezillon host->devtype_data->send_addr(host, 34693db446aSBoris Brezillon (page_addr >> 8) & 0xff, 34793db446aSBoris Brezillon false); 34893db446aSBoris Brezillon host->devtype_data->send_addr(host, 34993db446aSBoris Brezillon (page_addr >> 16) & 0xff, 35093db446aSBoris Brezillon true); 35193db446aSBoris Brezillon } else 35293db446aSBoris Brezillon /* paddr_8 - paddr_15 */ 35393db446aSBoris Brezillon host->devtype_data->send_addr(host, 35493db446aSBoris Brezillon (page_addr >> 8) & 0xff, true); 35593db446aSBoris Brezillon } 35693db446aSBoris Brezillon } 35793db446aSBoris Brezillon } 35893db446aSBoris Brezillon 35993db446aSBoris Brezillon static int check_int_v3(struct mxc_nand_host *host) 36093db446aSBoris Brezillon { 36193db446aSBoris Brezillon uint32_t tmp; 36293db446aSBoris Brezillon 36393db446aSBoris Brezillon tmp = readl(NFC_V3_IPC); 36493db446aSBoris Brezillon if (!(tmp & NFC_V3_IPC_INT)) 36593db446aSBoris Brezillon return 0; 36693db446aSBoris Brezillon 36793db446aSBoris Brezillon tmp &= ~NFC_V3_IPC_INT; 36893db446aSBoris Brezillon writel(tmp, NFC_V3_IPC); 36993db446aSBoris Brezillon 37093db446aSBoris Brezillon return 1; 37193db446aSBoris Brezillon } 37293db446aSBoris Brezillon 37393db446aSBoris Brezillon static int check_int_v1_v2(struct mxc_nand_host *host) 37493db446aSBoris Brezillon { 37593db446aSBoris Brezillon uint32_t tmp; 37693db446aSBoris Brezillon 37793db446aSBoris Brezillon tmp = readw(NFC_V1_V2_CONFIG2); 37893db446aSBoris Brezillon if (!(tmp & NFC_V1_V2_CONFIG2_INT)) 37993db446aSBoris Brezillon return 0; 38093db446aSBoris Brezillon 38193db446aSBoris Brezillon if (!host->devtype_data->irqpending_quirk) 38293db446aSBoris Brezillon writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); 38393db446aSBoris Brezillon 38493db446aSBoris Brezillon return 1; 38593db446aSBoris Brezillon } 38693db446aSBoris Brezillon 38793db446aSBoris Brezillon static void irq_control_v1_v2(struct mxc_nand_host *host, int activate) 38893db446aSBoris Brezillon { 38993db446aSBoris Brezillon uint16_t tmp; 39093db446aSBoris Brezillon 39193db446aSBoris Brezillon tmp = readw(NFC_V1_V2_CONFIG1); 39293db446aSBoris Brezillon 39393db446aSBoris Brezillon if (activate) 39493db446aSBoris Brezillon tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; 39593db446aSBoris Brezillon else 39693db446aSBoris Brezillon tmp |= NFC_V1_V2_CONFIG1_INT_MSK; 39793db446aSBoris Brezillon 39893db446aSBoris Brezillon writew(tmp, NFC_V1_V2_CONFIG1); 39993db446aSBoris Brezillon } 40093db446aSBoris Brezillon 40193db446aSBoris Brezillon static void irq_control_v3(struct mxc_nand_host *host, int activate) 40293db446aSBoris Brezillon { 40393db446aSBoris Brezillon uint32_t tmp; 40493db446aSBoris Brezillon 40593db446aSBoris Brezillon tmp = readl(NFC_V3_CONFIG2); 40693db446aSBoris Brezillon 40793db446aSBoris Brezillon if (activate) 40893db446aSBoris Brezillon tmp &= ~NFC_V3_CONFIG2_INT_MSK; 40993db446aSBoris Brezillon else 41093db446aSBoris Brezillon tmp |= NFC_V3_CONFIG2_INT_MSK; 41193db446aSBoris Brezillon 41293db446aSBoris Brezillon writel(tmp, NFC_V3_CONFIG2); 41393db446aSBoris Brezillon } 41493db446aSBoris Brezillon 41593db446aSBoris Brezillon static void irq_control(struct mxc_nand_host *host, int activate) 41693db446aSBoris Brezillon { 41793db446aSBoris Brezillon if (host->devtype_data->irqpending_quirk) { 41893db446aSBoris Brezillon if (activate) 41993db446aSBoris Brezillon enable_irq(host->irq); 42093db446aSBoris Brezillon else 42193db446aSBoris Brezillon disable_irq_nosync(host->irq); 42293db446aSBoris Brezillon } else { 42393db446aSBoris Brezillon host->devtype_data->irq_control(host, activate); 42493db446aSBoris Brezillon } 42593db446aSBoris Brezillon } 42693db446aSBoris Brezillon 42793db446aSBoris Brezillon static u32 get_ecc_status_v1(struct mxc_nand_host *host) 42893db446aSBoris Brezillon { 42993db446aSBoris Brezillon return readw(NFC_V1_V2_ECC_STATUS_RESULT); 43093db446aSBoris Brezillon } 43193db446aSBoris Brezillon 43293db446aSBoris Brezillon static u32 get_ecc_status_v2(struct mxc_nand_host *host) 43393db446aSBoris Brezillon { 43493db446aSBoris Brezillon return readl(NFC_V1_V2_ECC_STATUS_RESULT); 43593db446aSBoris Brezillon } 43693db446aSBoris Brezillon 43793db446aSBoris Brezillon static u32 get_ecc_status_v3(struct mxc_nand_host *host) 43893db446aSBoris Brezillon { 43993db446aSBoris Brezillon return readl(NFC_V3_ECC_STATUS_RESULT); 44093db446aSBoris Brezillon } 44193db446aSBoris Brezillon 44293db446aSBoris Brezillon static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) 44393db446aSBoris Brezillon { 44493db446aSBoris Brezillon struct mxc_nand_host *host = dev_id; 44593db446aSBoris Brezillon 44693db446aSBoris Brezillon if (!host->devtype_data->check_int(host)) 44793db446aSBoris Brezillon return IRQ_NONE; 44893db446aSBoris Brezillon 44993db446aSBoris Brezillon irq_control(host, 0); 45093db446aSBoris Brezillon 45193db446aSBoris Brezillon complete(&host->op_completion); 45293db446aSBoris Brezillon 45393db446aSBoris Brezillon return IRQ_HANDLED; 45493db446aSBoris Brezillon } 45593db446aSBoris Brezillon 45693db446aSBoris Brezillon /* This function polls the NANDFC to wait for the basic operation to 45793db446aSBoris Brezillon * complete by checking the INT bit of config2 register. 45893db446aSBoris Brezillon */ 45993db446aSBoris Brezillon static int wait_op_done(struct mxc_nand_host *host, int useirq) 46093db446aSBoris Brezillon { 46193db446aSBoris Brezillon int ret = 0; 46293db446aSBoris Brezillon 46393db446aSBoris Brezillon /* 46493db446aSBoris Brezillon * If operation is already complete, don't bother to setup an irq or a 46593db446aSBoris Brezillon * loop. 46693db446aSBoris Brezillon */ 46793db446aSBoris Brezillon if (host->devtype_data->check_int(host)) 46893db446aSBoris Brezillon return 0; 46993db446aSBoris Brezillon 47093db446aSBoris Brezillon if (useirq) { 47193db446aSBoris Brezillon unsigned long timeout; 47293db446aSBoris Brezillon 47393db446aSBoris Brezillon reinit_completion(&host->op_completion); 47493db446aSBoris Brezillon 47593db446aSBoris Brezillon irq_control(host, 1); 47693db446aSBoris Brezillon 47793db446aSBoris Brezillon timeout = wait_for_completion_timeout(&host->op_completion, HZ); 47893db446aSBoris Brezillon if (!timeout && !host->devtype_data->check_int(host)) { 47993db446aSBoris Brezillon dev_dbg(host->dev, "timeout waiting for irq\n"); 48093db446aSBoris Brezillon ret = -ETIMEDOUT; 48193db446aSBoris Brezillon } 48293db446aSBoris Brezillon } else { 48393db446aSBoris Brezillon int max_retries = 8000; 48493db446aSBoris Brezillon int done; 48593db446aSBoris Brezillon 48693db446aSBoris Brezillon do { 48793db446aSBoris Brezillon udelay(1); 48893db446aSBoris Brezillon 48993db446aSBoris Brezillon done = host->devtype_data->check_int(host); 49093db446aSBoris Brezillon if (done) 49193db446aSBoris Brezillon break; 49293db446aSBoris Brezillon 49393db446aSBoris Brezillon } while (--max_retries); 49493db446aSBoris Brezillon 49593db446aSBoris Brezillon if (!done) { 49693db446aSBoris Brezillon dev_dbg(host->dev, "timeout polling for completion\n"); 49793db446aSBoris Brezillon ret = -ETIMEDOUT; 49893db446aSBoris Brezillon } 49993db446aSBoris Brezillon } 50093db446aSBoris Brezillon 50193db446aSBoris Brezillon WARN_ONCE(ret < 0, "timeout! useirq=%d\n", useirq); 50293db446aSBoris Brezillon 50393db446aSBoris Brezillon return ret; 50493db446aSBoris Brezillon } 50593db446aSBoris Brezillon 50693db446aSBoris Brezillon static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq) 50793db446aSBoris Brezillon { 50893db446aSBoris Brezillon /* fill command */ 50993db446aSBoris Brezillon writel(cmd, NFC_V3_FLASH_CMD); 51093db446aSBoris Brezillon 51193db446aSBoris Brezillon /* send out command */ 51293db446aSBoris Brezillon writel(NFC_CMD, NFC_V3_LAUNCH); 51393db446aSBoris Brezillon 51493db446aSBoris Brezillon /* Wait for operation to complete */ 51593db446aSBoris Brezillon wait_op_done(host, useirq); 51693db446aSBoris Brezillon } 51793db446aSBoris Brezillon 51893db446aSBoris Brezillon /* This function issues the specified command to the NAND device and 51993db446aSBoris Brezillon * waits for completion. */ 52093db446aSBoris Brezillon static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq) 52193db446aSBoris Brezillon { 52293db446aSBoris Brezillon dev_dbg(host->dev, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); 52393db446aSBoris Brezillon 52493db446aSBoris Brezillon writew(cmd, NFC_V1_V2_FLASH_CMD); 52593db446aSBoris Brezillon writew(NFC_CMD, NFC_V1_V2_CONFIG2); 52693db446aSBoris Brezillon 52793db446aSBoris Brezillon if (host->devtype_data->irqpending_quirk && (cmd == NAND_CMD_RESET)) { 52893db446aSBoris Brezillon int max_retries = 100; 52993db446aSBoris Brezillon /* Reset completion is indicated by NFC_CONFIG2 */ 53093db446aSBoris Brezillon /* being set to 0 */ 53193db446aSBoris Brezillon while (max_retries-- > 0) { 53293db446aSBoris Brezillon if (readw(NFC_V1_V2_CONFIG2) == 0) { 53393db446aSBoris Brezillon break; 53493db446aSBoris Brezillon } 53593db446aSBoris Brezillon udelay(1); 53693db446aSBoris Brezillon } 53793db446aSBoris Brezillon if (max_retries < 0) 53893db446aSBoris Brezillon dev_dbg(host->dev, "%s: RESET failed\n", __func__); 53993db446aSBoris Brezillon } else { 54093db446aSBoris Brezillon /* Wait for operation to complete */ 54193db446aSBoris Brezillon wait_op_done(host, useirq); 54293db446aSBoris Brezillon } 54393db446aSBoris Brezillon } 54493db446aSBoris Brezillon 54593db446aSBoris Brezillon static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast) 54693db446aSBoris Brezillon { 54793db446aSBoris Brezillon /* fill address */ 54893db446aSBoris Brezillon writel(addr, NFC_V3_FLASH_ADDR0); 54993db446aSBoris Brezillon 55093db446aSBoris Brezillon /* send out address */ 55193db446aSBoris Brezillon writel(NFC_ADDR, NFC_V3_LAUNCH); 55293db446aSBoris Brezillon 55393db446aSBoris Brezillon wait_op_done(host, 0); 55493db446aSBoris Brezillon } 55593db446aSBoris Brezillon 55693db446aSBoris Brezillon /* This function sends an address (or partial address) to the 55793db446aSBoris Brezillon * NAND device. The address is used to select the source/destination for 55893db446aSBoris Brezillon * a NAND command. */ 55993db446aSBoris Brezillon static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast) 56093db446aSBoris Brezillon { 56193db446aSBoris Brezillon dev_dbg(host->dev, "send_addr(host, 0x%x %d)\n", addr, islast); 56293db446aSBoris Brezillon 56393db446aSBoris Brezillon writew(addr, NFC_V1_V2_FLASH_ADDR); 56493db446aSBoris Brezillon writew(NFC_ADDR, NFC_V1_V2_CONFIG2); 56593db446aSBoris Brezillon 56693db446aSBoris Brezillon /* Wait for operation to complete */ 56793db446aSBoris Brezillon wait_op_done(host, islast); 56893db446aSBoris Brezillon } 56993db446aSBoris Brezillon 57093db446aSBoris Brezillon static void send_page_v3(struct mtd_info *mtd, unsigned int ops) 57193db446aSBoris Brezillon { 57293db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 57393db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 57493db446aSBoris Brezillon uint32_t tmp; 57593db446aSBoris Brezillon 57693db446aSBoris Brezillon tmp = readl(NFC_V3_CONFIG1); 57793db446aSBoris Brezillon tmp &= ~(7 << 4); 57893db446aSBoris Brezillon writel(tmp, NFC_V3_CONFIG1); 57993db446aSBoris Brezillon 58093db446aSBoris Brezillon /* transfer data from NFC ram to nand */ 58193db446aSBoris Brezillon writel(ops, NFC_V3_LAUNCH); 58293db446aSBoris Brezillon 58393db446aSBoris Brezillon wait_op_done(host, false); 58493db446aSBoris Brezillon } 58593db446aSBoris Brezillon 58693db446aSBoris Brezillon static void send_page_v2(struct mtd_info *mtd, unsigned int ops) 58793db446aSBoris Brezillon { 58893db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 58993db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 59093db446aSBoris Brezillon 59193db446aSBoris Brezillon /* NANDFC buffer 0 is used for page read/write */ 59293db446aSBoris Brezillon writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); 59393db446aSBoris Brezillon 59493db446aSBoris Brezillon writew(ops, NFC_V1_V2_CONFIG2); 59593db446aSBoris Brezillon 59693db446aSBoris Brezillon /* Wait for operation to complete */ 59793db446aSBoris Brezillon wait_op_done(host, true); 59893db446aSBoris Brezillon } 59993db446aSBoris Brezillon 60093db446aSBoris Brezillon static void send_page_v1(struct mtd_info *mtd, unsigned int ops) 60193db446aSBoris Brezillon { 60293db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 60393db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 60493db446aSBoris Brezillon int bufs, i; 60593db446aSBoris Brezillon 60693db446aSBoris Brezillon if (mtd->writesize > 512) 60793db446aSBoris Brezillon bufs = 4; 60893db446aSBoris Brezillon else 60993db446aSBoris Brezillon bufs = 1; 61093db446aSBoris Brezillon 61193db446aSBoris Brezillon for (i = 0; i < bufs; i++) { 61293db446aSBoris Brezillon 61393db446aSBoris Brezillon /* NANDFC buffer 0 is used for page read/write */ 61493db446aSBoris Brezillon writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); 61593db446aSBoris Brezillon 61693db446aSBoris Brezillon writew(ops, NFC_V1_V2_CONFIG2); 61793db446aSBoris Brezillon 61893db446aSBoris Brezillon /* Wait for operation to complete */ 61993db446aSBoris Brezillon wait_op_done(host, true); 62093db446aSBoris Brezillon } 62193db446aSBoris Brezillon } 62293db446aSBoris Brezillon 62393db446aSBoris Brezillon static void send_read_id_v3(struct mxc_nand_host *host) 62493db446aSBoris Brezillon { 62593db446aSBoris Brezillon /* Read ID into main buffer */ 62693db446aSBoris Brezillon writel(NFC_ID, NFC_V3_LAUNCH); 62793db446aSBoris Brezillon 62893db446aSBoris Brezillon wait_op_done(host, true); 62993db446aSBoris Brezillon 63093db446aSBoris Brezillon memcpy32_fromio(host->data_buf, host->main_area0, 16); 63193db446aSBoris Brezillon } 63293db446aSBoris Brezillon 63393db446aSBoris Brezillon /* Request the NANDFC to perform a read of the NAND device ID. */ 63493db446aSBoris Brezillon static void send_read_id_v1_v2(struct mxc_nand_host *host) 63593db446aSBoris Brezillon { 63693db446aSBoris Brezillon /* NANDFC buffer 0 is used for device ID output */ 63793db446aSBoris Brezillon writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); 63893db446aSBoris Brezillon 63993db446aSBoris Brezillon writew(NFC_ID, NFC_V1_V2_CONFIG2); 64093db446aSBoris Brezillon 64193db446aSBoris Brezillon /* Wait for operation to complete */ 64293db446aSBoris Brezillon wait_op_done(host, true); 64393db446aSBoris Brezillon 64493db446aSBoris Brezillon memcpy32_fromio(host->data_buf, host->main_area0, 16); 64593db446aSBoris Brezillon } 64693db446aSBoris Brezillon 64793db446aSBoris Brezillon static uint16_t get_dev_status_v3(struct mxc_nand_host *host) 64893db446aSBoris Brezillon { 64993db446aSBoris Brezillon writew(NFC_STATUS, NFC_V3_LAUNCH); 65093db446aSBoris Brezillon wait_op_done(host, true); 65193db446aSBoris Brezillon 65293db446aSBoris Brezillon return readl(NFC_V3_CONFIG1) >> 16; 65393db446aSBoris Brezillon } 65493db446aSBoris Brezillon 65593db446aSBoris Brezillon /* This function requests the NANDFC to perform a read of the 65693db446aSBoris Brezillon * NAND device status and returns the current status. */ 65793db446aSBoris Brezillon static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host) 65893db446aSBoris Brezillon { 65993db446aSBoris Brezillon void __iomem *main_buf = host->main_area0; 66093db446aSBoris Brezillon uint32_t store; 66193db446aSBoris Brezillon uint16_t ret; 66293db446aSBoris Brezillon 66393db446aSBoris Brezillon writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); 66493db446aSBoris Brezillon 66593db446aSBoris Brezillon /* 66693db446aSBoris Brezillon * The device status is stored in main_area0. To 66793db446aSBoris Brezillon * prevent corruption of the buffer save the value 66893db446aSBoris Brezillon * and restore it afterwards. 66993db446aSBoris Brezillon */ 67093db446aSBoris Brezillon store = readl(main_buf); 67193db446aSBoris Brezillon 67293db446aSBoris Brezillon writew(NFC_STATUS, NFC_V1_V2_CONFIG2); 67393db446aSBoris Brezillon wait_op_done(host, true); 67493db446aSBoris Brezillon 67593db446aSBoris Brezillon ret = readw(main_buf); 67693db446aSBoris Brezillon 67793db446aSBoris Brezillon writel(store, main_buf); 67893db446aSBoris Brezillon 67993db446aSBoris Brezillon return ret; 68093db446aSBoris Brezillon } 68193db446aSBoris Brezillon 68293db446aSBoris Brezillon static void mxc_nand_enable_hwecc_v1_v2(struct nand_chip *chip, bool enable) 68393db446aSBoris Brezillon { 68493db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 68593db446aSBoris Brezillon uint16_t config1; 68693db446aSBoris Brezillon 68793db446aSBoris Brezillon if (chip->ecc.mode != NAND_ECC_HW) 68893db446aSBoris Brezillon return; 68993db446aSBoris Brezillon 69093db446aSBoris Brezillon config1 = readw(NFC_V1_V2_CONFIG1); 69193db446aSBoris Brezillon 69293db446aSBoris Brezillon if (enable) 69393db446aSBoris Brezillon config1 |= NFC_V1_V2_CONFIG1_ECC_EN; 69493db446aSBoris Brezillon else 69593db446aSBoris Brezillon config1 &= ~NFC_V1_V2_CONFIG1_ECC_EN; 69693db446aSBoris Brezillon 69793db446aSBoris Brezillon writew(config1, NFC_V1_V2_CONFIG1); 69893db446aSBoris Brezillon } 69993db446aSBoris Brezillon 70093db446aSBoris Brezillon static void mxc_nand_enable_hwecc_v3(struct nand_chip *chip, bool enable) 70193db446aSBoris Brezillon { 70293db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 70393db446aSBoris Brezillon uint32_t config2; 70493db446aSBoris Brezillon 70593db446aSBoris Brezillon if (chip->ecc.mode != NAND_ECC_HW) 70693db446aSBoris Brezillon return; 70793db446aSBoris Brezillon 70893db446aSBoris Brezillon config2 = readl(NFC_V3_CONFIG2); 70993db446aSBoris Brezillon 71093db446aSBoris Brezillon if (enable) 71193db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_ECC_EN; 71293db446aSBoris Brezillon else 71393db446aSBoris Brezillon config2 &= ~NFC_V3_CONFIG2_ECC_EN; 71493db446aSBoris Brezillon 71593db446aSBoris Brezillon writel(config2, NFC_V3_CONFIG2); 71693db446aSBoris Brezillon } 71793db446aSBoris Brezillon 71893db446aSBoris Brezillon /* This functions is used by upper layer to checks if device is ready */ 71993db446aSBoris Brezillon static int mxc_nand_dev_ready(struct mtd_info *mtd) 72093db446aSBoris Brezillon { 72193db446aSBoris Brezillon /* 72293db446aSBoris Brezillon * NFC handles R/B internally. Therefore, this function 72393db446aSBoris Brezillon * always returns status as ready. 72493db446aSBoris Brezillon */ 72593db446aSBoris Brezillon return 1; 72693db446aSBoris Brezillon } 72793db446aSBoris Brezillon 72893db446aSBoris Brezillon static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob, 72993db446aSBoris Brezillon bool ecc, int page) 73093db446aSBoris Brezillon { 73193db446aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 73293db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 73393db446aSBoris Brezillon unsigned int bitflips_corrected = 0; 73493db446aSBoris Brezillon int no_subpages; 73593db446aSBoris Brezillon int i; 73693db446aSBoris Brezillon 73793db446aSBoris Brezillon host->devtype_data->enable_hwecc(chip, ecc); 73893db446aSBoris Brezillon 73993db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); 74093db446aSBoris Brezillon mxc_do_addr_cycle(mtd, 0, page); 74193db446aSBoris Brezillon 74293db446aSBoris Brezillon if (mtd->writesize > 512) 74393db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true); 74493db446aSBoris Brezillon 74593db446aSBoris Brezillon no_subpages = mtd->writesize >> 9; 74693db446aSBoris Brezillon 74793db446aSBoris Brezillon for (i = 0; i < no_subpages; i++) { 74893db446aSBoris Brezillon uint16_t ecc_stats; 74993db446aSBoris Brezillon 75093db446aSBoris Brezillon /* NANDFC buffer 0 is used for page read/write */ 75193db446aSBoris Brezillon writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); 75293db446aSBoris Brezillon 75393db446aSBoris Brezillon writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2); 75493db446aSBoris Brezillon 75593db446aSBoris Brezillon /* Wait for operation to complete */ 75693db446aSBoris Brezillon wait_op_done(host, true); 75793db446aSBoris Brezillon 75893db446aSBoris Brezillon ecc_stats = get_ecc_status_v1(host); 75993db446aSBoris Brezillon 76093db446aSBoris Brezillon ecc_stats >>= 2; 76193db446aSBoris Brezillon 76293db446aSBoris Brezillon if (buf && ecc) { 76393db446aSBoris Brezillon switch (ecc_stats & 0x3) { 76493db446aSBoris Brezillon case 0: 76593db446aSBoris Brezillon default: 76693db446aSBoris Brezillon break; 76793db446aSBoris Brezillon case 1: 76893db446aSBoris Brezillon mtd->ecc_stats.corrected++; 76993db446aSBoris Brezillon bitflips_corrected = 1; 77093db446aSBoris Brezillon break; 77193db446aSBoris Brezillon case 2: 77293db446aSBoris Brezillon mtd->ecc_stats.failed++; 77393db446aSBoris Brezillon break; 77493db446aSBoris Brezillon } 77593db446aSBoris Brezillon } 77693db446aSBoris Brezillon } 77793db446aSBoris Brezillon 77893db446aSBoris Brezillon if (buf) 77993db446aSBoris Brezillon memcpy32_fromio(buf, host->main_area0, mtd->writesize); 78093db446aSBoris Brezillon if (oob) 78193db446aSBoris Brezillon copy_spare(mtd, true, oob); 78293db446aSBoris Brezillon 78393db446aSBoris Brezillon return bitflips_corrected; 78493db446aSBoris Brezillon } 78593db446aSBoris Brezillon 78693db446aSBoris Brezillon static int mxc_nand_read_page_v2_v3(struct nand_chip *chip, void *buf, 78793db446aSBoris Brezillon void *oob, bool ecc, int page) 78893db446aSBoris Brezillon { 78993db446aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 79093db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 79193db446aSBoris Brezillon unsigned int max_bitflips = 0; 79293db446aSBoris Brezillon u32 ecc_stat, err; 79393db446aSBoris Brezillon int no_subpages; 79493db446aSBoris Brezillon u8 ecc_bit_mask, err_limit; 79593db446aSBoris Brezillon 79693db446aSBoris Brezillon host->devtype_data->enable_hwecc(chip, ecc); 79793db446aSBoris Brezillon 79893db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); 79993db446aSBoris Brezillon mxc_do_addr_cycle(mtd, 0, page); 80093db446aSBoris Brezillon 80193db446aSBoris Brezillon if (mtd->writesize > 512) 80293db446aSBoris Brezillon host->devtype_data->send_cmd(host, 80393db446aSBoris Brezillon NAND_CMD_READSTART, true); 80493db446aSBoris Brezillon 80593db446aSBoris Brezillon host->devtype_data->send_page(mtd, NFC_OUTPUT); 80693db446aSBoris Brezillon 80793db446aSBoris Brezillon if (buf) 80893db446aSBoris Brezillon memcpy32_fromio(buf, host->main_area0, mtd->writesize); 80993db446aSBoris Brezillon if (oob) 81093db446aSBoris Brezillon copy_spare(mtd, true, oob); 81193db446aSBoris Brezillon 81293db446aSBoris Brezillon ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf; 81393db446aSBoris Brezillon err_limit = (host->eccsize == 4) ? 0x4 : 0x8; 81493db446aSBoris Brezillon 81593db446aSBoris Brezillon no_subpages = mtd->writesize >> 9; 81693db446aSBoris Brezillon 81793db446aSBoris Brezillon ecc_stat = host->devtype_data->get_ecc_status(host); 81893db446aSBoris Brezillon 81993db446aSBoris Brezillon do { 82093db446aSBoris Brezillon err = ecc_stat & ecc_bit_mask; 82193db446aSBoris Brezillon if (err > err_limit) { 82293db446aSBoris Brezillon mtd->ecc_stats.failed++; 82393db446aSBoris Brezillon } else { 82493db446aSBoris Brezillon mtd->ecc_stats.corrected += err; 82593db446aSBoris Brezillon max_bitflips = max_t(unsigned int, max_bitflips, err); 82693db446aSBoris Brezillon } 82793db446aSBoris Brezillon 82893db446aSBoris Brezillon ecc_stat >>= 4; 82993db446aSBoris Brezillon } while (--no_subpages); 83093db446aSBoris Brezillon 83193db446aSBoris Brezillon return max_bitflips; 83293db446aSBoris Brezillon } 83393db446aSBoris Brezillon 83493db446aSBoris Brezillon static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, 83593db446aSBoris Brezillon uint8_t *buf, int oob_required, int page) 83693db446aSBoris Brezillon { 83793db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 83893db446aSBoris Brezillon void *oob_buf; 83993db446aSBoris Brezillon 84093db446aSBoris Brezillon if (oob_required) 84193db446aSBoris Brezillon oob_buf = chip->oob_poi; 84293db446aSBoris Brezillon else 84393db446aSBoris Brezillon oob_buf = NULL; 84493db446aSBoris Brezillon 84593db446aSBoris Brezillon return host->devtype_data->read_page(chip, buf, oob_buf, 1, page); 84693db446aSBoris Brezillon } 84793db446aSBoris Brezillon 84893db446aSBoris Brezillon static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 84993db446aSBoris Brezillon uint8_t *buf, int oob_required, int page) 85093db446aSBoris Brezillon { 85193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 85293db446aSBoris Brezillon void *oob_buf; 85393db446aSBoris Brezillon 85493db446aSBoris Brezillon if (oob_required) 85593db446aSBoris Brezillon oob_buf = chip->oob_poi; 85693db446aSBoris Brezillon else 85793db446aSBoris Brezillon oob_buf = NULL; 85893db446aSBoris Brezillon 85993db446aSBoris Brezillon return host->devtype_data->read_page(chip, buf, oob_buf, 0, page); 86093db446aSBoris Brezillon } 86193db446aSBoris Brezillon 86293db446aSBoris Brezillon static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, 86393db446aSBoris Brezillon int page) 86493db446aSBoris Brezillon { 86593db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 86693db446aSBoris Brezillon 86793db446aSBoris Brezillon return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0, 86893db446aSBoris Brezillon page); 86993db446aSBoris Brezillon } 87093db446aSBoris Brezillon 87193db446aSBoris Brezillon static int mxc_nand_write_page(struct nand_chip *chip, const uint8_t *buf, 87293db446aSBoris Brezillon bool ecc, int page) 87393db446aSBoris Brezillon { 87493db446aSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 87593db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 87693db446aSBoris Brezillon 87793db446aSBoris Brezillon host->devtype_data->enable_hwecc(chip, ecc); 87893db446aSBoris Brezillon 87993db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false); 88093db446aSBoris Brezillon mxc_do_addr_cycle(mtd, 0, page); 88193db446aSBoris Brezillon 88293db446aSBoris Brezillon memcpy32_toio(host->main_area0, buf, mtd->writesize); 88393db446aSBoris Brezillon copy_spare(mtd, false, chip->oob_poi); 88493db446aSBoris Brezillon 88593db446aSBoris Brezillon host->devtype_data->send_page(mtd, NFC_INPUT); 88693db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true); 88793db446aSBoris Brezillon mxc_do_addr_cycle(mtd, 0, page); 88893db446aSBoris Brezillon 88993db446aSBoris Brezillon return 0; 89093db446aSBoris Brezillon } 89193db446aSBoris Brezillon 89293db446aSBoris Brezillon static int mxc_nand_write_page_ecc(struct mtd_info *mtd, struct nand_chip *chip, 89393db446aSBoris Brezillon const uint8_t *buf, int oob_required, 89493db446aSBoris Brezillon int page) 89593db446aSBoris Brezillon { 89693db446aSBoris Brezillon return mxc_nand_write_page(chip, buf, true, page); 89793db446aSBoris Brezillon } 89893db446aSBoris Brezillon 89993db446aSBoris Brezillon static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 90093db446aSBoris Brezillon const uint8_t *buf, int oob_required, int page) 90193db446aSBoris Brezillon { 90293db446aSBoris Brezillon return mxc_nand_write_page(chip, buf, false, page); 90393db446aSBoris Brezillon } 90493db446aSBoris Brezillon 90593db446aSBoris Brezillon static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, 90693db446aSBoris Brezillon int page) 90793db446aSBoris Brezillon { 90893db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 90993db446aSBoris Brezillon 91093db446aSBoris Brezillon memset(host->data_buf, 0xff, mtd->writesize); 91193db446aSBoris Brezillon 91293db446aSBoris Brezillon return mxc_nand_write_page(chip, host->data_buf, false, page); 91393db446aSBoris Brezillon } 91493db446aSBoris Brezillon 91593db446aSBoris Brezillon static u_char mxc_nand_read_byte(struct mtd_info *mtd) 91693db446aSBoris Brezillon { 91793db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 91893db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 91993db446aSBoris Brezillon uint8_t ret; 92093db446aSBoris Brezillon 92193db446aSBoris Brezillon /* Check for status request */ 92293db446aSBoris Brezillon if (host->status_request) 92393db446aSBoris Brezillon return host->devtype_data->get_dev_status(host) & 0xFF; 92493db446aSBoris Brezillon 92593db446aSBoris Brezillon if (nand_chip->options & NAND_BUSWIDTH_16) { 92693db446aSBoris Brezillon /* only take the lower byte of each word */ 92793db446aSBoris Brezillon ret = *(uint16_t *)(host->data_buf + host->buf_start); 92893db446aSBoris Brezillon 92993db446aSBoris Brezillon host->buf_start += 2; 93093db446aSBoris Brezillon } else { 93193db446aSBoris Brezillon ret = *(uint8_t *)(host->data_buf + host->buf_start); 93293db446aSBoris Brezillon host->buf_start++; 93393db446aSBoris Brezillon } 93493db446aSBoris Brezillon 93593db446aSBoris Brezillon dev_dbg(host->dev, "%s: ret=0x%hhx (start=%u)\n", __func__, ret, host->buf_start); 93693db446aSBoris Brezillon return ret; 93793db446aSBoris Brezillon } 93893db446aSBoris Brezillon 93993db446aSBoris Brezillon static uint16_t mxc_nand_read_word(struct mtd_info *mtd) 94093db446aSBoris Brezillon { 94193db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 94293db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 94393db446aSBoris Brezillon uint16_t ret; 94493db446aSBoris Brezillon 94593db446aSBoris Brezillon ret = *(uint16_t *)(host->data_buf + host->buf_start); 94693db446aSBoris Brezillon host->buf_start += 2; 94793db446aSBoris Brezillon 94893db446aSBoris Brezillon return ret; 94993db446aSBoris Brezillon } 95093db446aSBoris Brezillon 95193db446aSBoris Brezillon /* Write data of length len to buffer buf. The data to be 95293db446aSBoris Brezillon * written on NAND Flash is first copied to RAMbuffer. After the Data Input 95393db446aSBoris Brezillon * Operation by the NFC, the data is written to NAND Flash */ 95493db446aSBoris Brezillon static void mxc_nand_write_buf(struct mtd_info *mtd, 95593db446aSBoris Brezillon const u_char *buf, int len) 95693db446aSBoris Brezillon { 95793db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 95893db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 95993db446aSBoris Brezillon u16 col = host->buf_start; 96093db446aSBoris Brezillon int n = mtd->oobsize + mtd->writesize - col; 96193db446aSBoris Brezillon 96293db446aSBoris Brezillon n = min(n, len); 96393db446aSBoris Brezillon 96493db446aSBoris Brezillon memcpy(host->data_buf + col, buf, n); 96593db446aSBoris Brezillon 96693db446aSBoris Brezillon host->buf_start += n; 96793db446aSBoris Brezillon } 96893db446aSBoris Brezillon 96993db446aSBoris Brezillon /* Read the data buffer from the NAND Flash. To read the data from NAND 97093db446aSBoris Brezillon * Flash first the data output cycle is initiated by the NFC, which copies 97193db446aSBoris Brezillon * the data to RAMbuffer. This data of length len is then copied to buffer buf. 97293db446aSBoris Brezillon */ 97393db446aSBoris Brezillon static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 97493db446aSBoris Brezillon { 97593db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 97693db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 97793db446aSBoris Brezillon u16 col = host->buf_start; 97893db446aSBoris Brezillon int n = mtd->oobsize + mtd->writesize - col; 97993db446aSBoris Brezillon 98093db446aSBoris Brezillon n = min(n, len); 98193db446aSBoris Brezillon 98293db446aSBoris Brezillon memcpy(buf, host->data_buf + col, n); 98393db446aSBoris Brezillon 98493db446aSBoris Brezillon host->buf_start += n; 98593db446aSBoris Brezillon } 98693db446aSBoris Brezillon 98793db446aSBoris Brezillon /* This function is used by upper layer for select and 98893db446aSBoris Brezillon * deselect of the NAND chip */ 98993db446aSBoris Brezillon static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) 99093db446aSBoris Brezillon { 99193db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 99293db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 99393db446aSBoris Brezillon 99493db446aSBoris Brezillon if (chip == -1) { 99593db446aSBoris Brezillon /* Disable the NFC clock */ 99693db446aSBoris Brezillon if (host->clk_act) { 99793db446aSBoris Brezillon clk_disable_unprepare(host->clk); 99893db446aSBoris Brezillon host->clk_act = 0; 99993db446aSBoris Brezillon } 100093db446aSBoris Brezillon return; 100193db446aSBoris Brezillon } 100293db446aSBoris Brezillon 100393db446aSBoris Brezillon if (!host->clk_act) { 100493db446aSBoris Brezillon /* Enable the NFC clock */ 100593db446aSBoris Brezillon clk_prepare_enable(host->clk); 100693db446aSBoris Brezillon host->clk_act = 1; 100793db446aSBoris Brezillon } 100893db446aSBoris Brezillon } 100993db446aSBoris Brezillon 101093db446aSBoris Brezillon static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) 101193db446aSBoris Brezillon { 101293db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 101393db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 101493db446aSBoris Brezillon 101593db446aSBoris Brezillon if (chip == -1) { 101693db446aSBoris Brezillon /* Disable the NFC clock */ 101793db446aSBoris Brezillon if (host->clk_act) { 101893db446aSBoris Brezillon clk_disable_unprepare(host->clk); 101993db446aSBoris Brezillon host->clk_act = 0; 102093db446aSBoris Brezillon } 102193db446aSBoris Brezillon return; 102293db446aSBoris Brezillon } 102393db446aSBoris Brezillon 102493db446aSBoris Brezillon if (!host->clk_act) { 102593db446aSBoris Brezillon /* Enable the NFC clock */ 102693db446aSBoris Brezillon clk_prepare_enable(host->clk); 102793db446aSBoris Brezillon host->clk_act = 1; 102893db446aSBoris Brezillon } 102993db446aSBoris Brezillon 103093db446aSBoris Brezillon host->active_cs = chip; 103193db446aSBoris Brezillon writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); 103293db446aSBoris Brezillon } 103393db446aSBoris Brezillon 103493db446aSBoris Brezillon #define MXC_V1_ECCBYTES 5 103593db446aSBoris Brezillon 103693db446aSBoris Brezillon static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, 103793db446aSBoris Brezillon struct mtd_oob_region *oobregion) 103893db446aSBoris Brezillon { 103993db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 104093db446aSBoris Brezillon 104193db446aSBoris Brezillon if (section >= nand_chip->ecc.steps) 104293db446aSBoris Brezillon return -ERANGE; 104393db446aSBoris Brezillon 104493db446aSBoris Brezillon oobregion->offset = (section * 16) + 6; 104593db446aSBoris Brezillon oobregion->length = MXC_V1_ECCBYTES; 104693db446aSBoris Brezillon 104793db446aSBoris Brezillon return 0; 104893db446aSBoris Brezillon } 104993db446aSBoris Brezillon 105093db446aSBoris Brezillon static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section, 105193db446aSBoris Brezillon struct mtd_oob_region *oobregion) 105293db446aSBoris Brezillon { 105393db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 105493db446aSBoris Brezillon 105593db446aSBoris Brezillon if (section > nand_chip->ecc.steps) 105693db446aSBoris Brezillon return -ERANGE; 105793db446aSBoris Brezillon 105893db446aSBoris Brezillon if (!section) { 105993db446aSBoris Brezillon if (mtd->writesize <= 512) { 106093db446aSBoris Brezillon oobregion->offset = 0; 106193db446aSBoris Brezillon oobregion->length = 5; 106293db446aSBoris Brezillon } else { 106393db446aSBoris Brezillon oobregion->offset = 2; 106493db446aSBoris Brezillon oobregion->length = 4; 106593db446aSBoris Brezillon } 106693db446aSBoris Brezillon } else { 106793db446aSBoris Brezillon oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6; 106893db446aSBoris Brezillon if (section < nand_chip->ecc.steps) 106993db446aSBoris Brezillon oobregion->length = (section * 16) + 6 - 107093db446aSBoris Brezillon oobregion->offset; 107193db446aSBoris Brezillon else 107293db446aSBoris Brezillon oobregion->length = mtd->oobsize - oobregion->offset; 107393db446aSBoris Brezillon } 107493db446aSBoris Brezillon 107593db446aSBoris Brezillon return 0; 107693db446aSBoris Brezillon } 107793db446aSBoris Brezillon 107893db446aSBoris Brezillon static const struct mtd_ooblayout_ops mxc_v1_ooblayout_ops = { 107993db446aSBoris Brezillon .ecc = mxc_v1_ooblayout_ecc, 108093db446aSBoris Brezillon .free = mxc_v1_ooblayout_free, 108193db446aSBoris Brezillon }; 108293db446aSBoris Brezillon 108393db446aSBoris Brezillon static int mxc_v2_ooblayout_ecc(struct mtd_info *mtd, int section, 108493db446aSBoris Brezillon struct mtd_oob_region *oobregion) 108593db446aSBoris Brezillon { 108693db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 108793db446aSBoris Brezillon int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; 108893db446aSBoris Brezillon 108993db446aSBoris Brezillon if (section >= nand_chip->ecc.steps) 109093db446aSBoris Brezillon return -ERANGE; 109193db446aSBoris Brezillon 109293db446aSBoris Brezillon oobregion->offset = (section * stepsize) + 7; 109393db446aSBoris Brezillon oobregion->length = nand_chip->ecc.bytes; 109493db446aSBoris Brezillon 109593db446aSBoris Brezillon return 0; 109693db446aSBoris Brezillon } 109793db446aSBoris Brezillon 109893db446aSBoris Brezillon static int mxc_v2_ooblayout_free(struct mtd_info *mtd, int section, 109993db446aSBoris Brezillon struct mtd_oob_region *oobregion) 110093db446aSBoris Brezillon { 110193db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 110293db446aSBoris Brezillon int stepsize = nand_chip->ecc.bytes == 9 ? 16 : 26; 110393db446aSBoris Brezillon 110493db446aSBoris Brezillon if (section >= nand_chip->ecc.steps) 110593db446aSBoris Brezillon return -ERANGE; 110693db446aSBoris Brezillon 110793db446aSBoris Brezillon if (!section) { 110893db446aSBoris Brezillon if (mtd->writesize <= 512) { 110993db446aSBoris Brezillon oobregion->offset = 0; 111093db446aSBoris Brezillon oobregion->length = 5; 111193db446aSBoris Brezillon } else { 111293db446aSBoris Brezillon oobregion->offset = 2; 111393db446aSBoris Brezillon oobregion->length = 4; 111493db446aSBoris Brezillon } 111593db446aSBoris Brezillon } else { 111693db446aSBoris Brezillon oobregion->offset = section * stepsize; 111793db446aSBoris Brezillon oobregion->length = 7; 111893db446aSBoris Brezillon } 111993db446aSBoris Brezillon 112093db446aSBoris Brezillon return 0; 112193db446aSBoris Brezillon } 112293db446aSBoris Brezillon 112393db446aSBoris Brezillon static const struct mtd_ooblayout_ops mxc_v2_ooblayout_ops = { 112493db446aSBoris Brezillon .ecc = mxc_v2_ooblayout_ecc, 112593db446aSBoris Brezillon .free = mxc_v2_ooblayout_free, 112693db446aSBoris Brezillon }; 112793db446aSBoris Brezillon 112893db446aSBoris Brezillon /* 112993db446aSBoris Brezillon * v2 and v3 type controllers can do 4bit or 8bit ecc depending 113093db446aSBoris Brezillon * on how much oob the nand chip has. For 8bit ecc we need at least 113193db446aSBoris Brezillon * 26 bytes of oob data per 512 byte block. 113293db446aSBoris Brezillon */ 113393db446aSBoris Brezillon static int get_eccsize(struct mtd_info *mtd) 113493db446aSBoris Brezillon { 113593db446aSBoris Brezillon int oobbytes_per_512 = 0; 113693db446aSBoris Brezillon 113793db446aSBoris Brezillon oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize; 113893db446aSBoris Brezillon 113993db446aSBoris Brezillon if (oobbytes_per_512 < 26) 114093db446aSBoris Brezillon return 4; 114193db446aSBoris Brezillon else 114293db446aSBoris Brezillon return 8; 114393db446aSBoris Brezillon } 114493db446aSBoris Brezillon 114593db446aSBoris Brezillon static void preset_v1(struct mtd_info *mtd) 114693db446aSBoris Brezillon { 114793db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 114893db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 114993db446aSBoris Brezillon uint16_t config1 = 0; 115093db446aSBoris Brezillon 115193db446aSBoris Brezillon if (nand_chip->ecc.mode == NAND_ECC_HW && mtd->writesize) 115293db446aSBoris Brezillon config1 |= NFC_V1_V2_CONFIG1_ECC_EN; 115393db446aSBoris Brezillon 115493db446aSBoris Brezillon if (!host->devtype_data->irqpending_quirk) 115593db446aSBoris Brezillon config1 |= NFC_V1_V2_CONFIG1_INT_MSK; 115693db446aSBoris Brezillon 115793db446aSBoris Brezillon host->eccsize = 1; 115893db446aSBoris Brezillon 115993db446aSBoris Brezillon writew(config1, NFC_V1_V2_CONFIG1); 116093db446aSBoris Brezillon /* preset operation */ 116193db446aSBoris Brezillon 116293db446aSBoris Brezillon /* Unlock the internal RAM Buffer */ 116393db446aSBoris Brezillon writew(0x2, NFC_V1_V2_CONFIG); 116493db446aSBoris Brezillon 116593db446aSBoris Brezillon /* Blocks to be unlocked */ 116693db446aSBoris Brezillon writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); 116793db446aSBoris Brezillon writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR); 116893db446aSBoris Brezillon 116993db446aSBoris Brezillon /* Unlock Block Command for given address range */ 117093db446aSBoris Brezillon writew(0x4, NFC_V1_V2_WRPROT); 117193db446aSBoris Brezillon } 117293db446aSBoris Brezillon 117393db446aSBoris Brezillon static int mxc_nand_v2_setup_data_interface(struct mtd_info *mtd, int csline, 117493db446aSBoris Brezillon const struct nand_data_interface *conf) 117593db446aSBoris Brezillon { 117693db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 117793db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 117893db446aSBoris Brezillon int tRC_min_ns, tRC_ps, ret; 117993db446aSBoris Brezillon unsigned long rate, rate_round; 118093db446aSBoris Brezillon const struct nand_sdr_timings *timings; 118193db446aSBoris Brezillon u16 config1; 118293db446aSBoris Brezillon 118393db446aSBoris Brezillon timings = nand_get_sdr_timings(conf); 118493db446aSBoris Brezillon if (IS_ERR(timings)) 118593db446aSBoris Brezillon return -ENOTSUPP; 118693db446aSBoris Brezillon 118793db446aSBoris Brezillon config1 = readw(NFC_V1_V2_CONFIG1); 118893db446aSBoris Brezillon 118993db446aSBoris Brezillon tRC_min_ns = timings->tRC_min / 1000; 119093db446aSBoris Brezillon rate = 1000000000 / tRC_min_ns; 119193db446aSBoris Brezillon 119293db446aSBoris Brezillon /* 119393db446aSBoris Brezillon * For tRC < 30ns we have to use EDO mode. In this case the controller 119493db446aSBoris Brezillon * does one access per clock cycle. Otherwise the controller does one 119593db446aSBoris Brezillon * access in two clock cycles, thus we have to double the rate to the 119693db446aSBoris Brezillon * controller. 119793db446aSBoris Brezillon */ 119893db446aSBoris Brezillon if (tRC_min_ns < 30) { 119993db446aSBoris Brezillon rate_round = clk_round_rate(host->clk, rate); 120093db446aSBoris Brezillon config1 |= NFC_V2_CONFIG1_ONE_CYCLE; 120193db446aSBoris Brezillon tRC_ps = 1000000000 / (rate_round / 1000); 120293db446aSBoris Brezillon } else { 120393db446aSBoris Brezillon rate *= 2; 120493db446aSBoris Brezillon rate_round = clk_round_rate(host->clk, rate); 120593db446aSBoris Brezillon config1 &= ~NFC_V2_CONFIG1_ONE_CYCLE; 120693db446aSBoris Brezillon tRC_ps = 1000000000 / (rate_round / 1000 / 2); 120793db446aSBoris Brezillon } 120893db446aSBoris Brezillon 120993db446aSBoris Brezillon /* 121093db446aSBoris Brezillon * The timing values compared against are from the i.MX25 Automotive 121193db446aSBoris Brezillon * datasheet, Table 50. NFC Timing Parameters 121293db446aSBoris Brezillon */ 121393db446aSBoris Brezillon if (timings->tCLS_min > tRC_ps - 1000 || 121493db446aSBoris Brezillon timings->tCLH_min > tRC_ps - 2000 || 121593db446aSBoris Brezillon timings->tCS_min > tRC_ps - 1000 || 121693db446aSBoris Brezillon timings->tCH_min > tRC_ps - 2000 || 121793db446aSBoris Brezillon timings->tWP_min > tRC_ps - 1500 || 121893db446aSBoris Brezillon timings->tALS_min > tRC_ps || 121993db446aSBoris Brezillon timings->tALH_min > tRC_ps - 3000 || 122093db446aSBoris Brezillon timings->tDS_min > tRC_ps || 122193db446aSBoris Brezillon timings->tDH_min > tRC_ps - 5000 || 122293db446aSBoris Brezillon timings->tWC_min > 2 * tRC_ps || 122393db446aSBoris Brezillon timings->tWH_min > tRC_ps - 2500 || 122493db446aSBoris Brezillon timings->tRR_min > 6 * tRC_ps || 122593db446aSBoris Brezillon timings->tRP_min > 3 * tRC_ps / 2 || 122693db446aSBoris Brezillon timings->tRC_min > 2 * tRC_ps || 122793db446aSBoris Brezillon timings->tREH_min > (tRC_ps / 2) - 2500) { 122893db446aSBoris Brezillon dev_dbg(host->dev, "Timing out of bounds\n"); 122993db446aSBoris Brezillon return -EINVAL; 123093db446aSBoris Brezillon } 123193db446aSBoris Brezillon 123293db446aSBoris Brezillon if (csline == NAND_DATA_IFACE_CHECK_ONLY) 123393db446aSBoris Brezillon return 0; 123493db446aSBoris Brezillon 123593db446aSBoris Brezillon ret = clk_set_rate(host->clk, rate); 123693db446aSBoris Brezillon if (ret) 123793db446aSBoris Brezillon return ret; 123893db446aSBoris Brezillon 123993db446aSBoris Brezillon writew(config1, NFC_V1_V2_CONFIG1); 124093db446aSBoris Brezillon 124193db446aSBoris Brezillon dev_dbg(host->dev, "Setting rate to %ldHz, %s mode\n", rate_round, 124293db446aSBoris Brezillon config1 & NFC_V2_CONFIG1_ONE_CYCLE ? "One cycle (EDO)" : 124393db446aSBoris Brezillon "normal"); 124493db446aSBoris Brezillon 124593db446aSBoris Brezillon return 0; 124693db446aSBoris Brezillon } 124793db446aSBoris Brezillon 124893db446aSBoris Brezillon static void preset_v2(struct mtd_info *mtd) 124993db446aSBoris Brezillon { 125093db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 125193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 125293db446aSBoris Brezillon uint16_t config1 = 0; 125393db446aSBoris Brezillon 125493db446aSBoris Brezillon config1 |= NFC_V2_CONFIG1_FP_INT; 125593db446aSBoris Brezillon 125693db446aSBoris Brezillon if (!host->devtype_data->irqpending_quirk) 125793db446aSBoris Brezillon config1 |= NFC_V1_V2_CONFIG1_INT_MSK; 125893db446aSBoris Brezillon 125993db446aSBoris Brezillon if (mtd->writesize) { 126093db446aSBoris Brezillon uint16_t pages_per_block = mtd->erasesize / mtd->writesize; 126193db446aSBoris Brezillon 126293db446aSBoris Brezillon if (nand_chip->ecc.mode == NAND_ECC_HW) 126393db446aSBoris Brezillon config1 |= NFC_V1_V2_CONFIG1_ECC_EN; 126493db446aSBoris Brezillon 126593db446aSBoris Brezillon host->eccsize = get_eccsize(mtd); 126693db446aSBoris Brezillon if (host->eccsize == 4) 126793db446aSBoris Brezillon config1 |= NFC_V2_CONFIG1_ECC_MODE_4; 126893db446aSBoris Brezillon 126993db446aSBoris Brezillon config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6); 127093db446aSBoris Brezillon } else { 127193db446aSBoris Brezillon host->eccsize = 1; 127293db446aSBoris Brezillon } 127393db446aSBoris Brezillon 127493db446aSBoris Brezillon writew(config1, NFC_V1_V2_CONFIG1); 127593db446aSBoris Brezillon /* preset operation */ 127693db446aSBoris Brezillon 1277*3f77f244SMartin Kaiser /* spare area size in 16-bit half-words */ 1278*3f77f244SMartin Kaiser writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA); 1279*3f77f244SMartin Kaiser 128093db446aSBoris Brezillon /* Unlock the internal RAM Buffer */ 128193db446aSBoris Brezillon writew(0x2, NFC_V1_V2_CONFIG); 128293db446aSBoris Brezillon 128393db446aSBoris Brezillon /* Blocks to be unlocked */ 128493db446aSBoris Brezillon writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0); 128593db446aSBoris Brezillon writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1); 128693db446aSBoris Brezillon writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2); 128793db446aSBoris Brezillon writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3); 128893db446aSBoris Brezillon writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0); 128993db446aSBoris Brezillon writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1); 129093db446aSBoris Brezillon writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2); 129193db446aSBoris Brezillon writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3); 129293db446aSBoris Brezillon 129393db446aSBoris Brezillon /* Unlock Block Command for given address range */ 129493db446aSBoris Brezillon writew(0x4, NFC_V1_V2_WRPROT); 129593db446aSBoris Brezillon } 129693db446aSBoris Brezillon 129793db446aSBoris Brezillon static void preset_v3(struct mtd_info *mtd) 129893db446aSBoris Brezillon { 129993db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 130093db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(chip); 130193db446aSBoris Brezillon uint32_t config2, config3; 130293db446aSBoris Brezillon int i, addr_phases; 130393db446aSBoris Brezillon 130493db446aSBoris Brezillon writel(NFC_V3_CONFIG1_RBA(0), NFC_V3_CONFIG1); 130593db446aSBoris Brezillon writel(NFC_V3_IPC_CREQ, NFC_V3_IPC); 130693db446aSBoris Brezillon 130793db446aSBoris Brezillon /* Unlock the internal RAM Buffer */ 130893db446aSBoris Brezillon writel(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK, 130993db446aSBoris Brezillon NFC_V3_WRPROT); 131093db446aSBoris Brezillon 131193db446aSBoris Brezillon /* Blocks to be unlocked */ 131293db446aSBoris Brezillon for (i = 0; i < NAND_MAX_CHIPS; i++) 131393db446aSBoris Brezillon writel(0xffff << 16, NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2)); 131493db446aSBoris Brezillon 131593db446aSBoris Brezillon writel(0, NFC_V3_IPC); 131693db446aSBoris Brezillon 131793db446aSBoris Brezillon config2 = NFC_V3_CONFIG2_ONE_CYCLE | 131893db446aSBoris Brezillon NFC_V3_CONFIG2_2CMD_PHASES | 131993db446aSBoris Brezillon NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) | 132093db446aSBoris Brezillon NFC_V3_CONFIG2_ST_CMD(0x70) | 132193db446aSBoris Brezillon NFC_V3_CONFIG2_INT_MSK | 132293db446aSBoris Brezillon NFC_V3_CONFIG2_NUM_ADDR_PHASE0; 132393db446aSBoris Brezillon 132493db446aSBoris Brezillon addr_phases = fls(chip->pagemask) >> 3; 132593db446aSBoris Brezillon 132693db446aSBoris Brezillon if (mtd->writesize == 2048) { 132793db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_PS_2048; 132893db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases); 132993db446aSBoris Brezillon } else if (mtd->writesize == 4096) { 133093db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_PS_4096; 133193db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases); 133293db446aSBoris Brezillon } else { 133393db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_PS_512; 133493db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1); 133593db446aSBoris Brezillon } 133693db446aSBoris Brezillon 133793db446aSBoris Brezillon if (mtd->writesize) { 133893db446aSBoris Brezillon if (chip->ecc.mode == NAND_ECC_HW) 133993db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_ECC_EN; 134093db446aSBoris Brezillon 134193db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_PPB( 134293db446aSBoris Brezillon ffs(mtd->erasesize / mtd->writesize) - 6, 134393db446aSBoris Brezillon host->devtype_data->ppb_shift); 134493db446aSBoris Brezillon host->eccsize = get_eccsize(mtd); 134593db446aSBoris Brezillon if (host->eccsize == 8) 134693db446aSBoris Brezillon config2 |= NFC_V3_CONFIG2_ECC_MODE_8; 134793db446aSBoris Brezillon } 134893db446aSBoris Brezillon 134993db446aSBoris Brezillon writel(config2, NFC_V3_CONFIG2); 135093db446aSBoris Brezillon 135193db446aSBoris Brezillon config3 = NFC_V3_CONFIG3_NUM_OF_DEVICES(0) | 135293db446aSBoris Brezillon NFC_V3_CONFIG3_NO_SDMA | 135393db446aSBoris Brezillon NFC_V3_CONFIG3_RBB_MODE | 135493db446aSBoris Brezillon NFC_V3_CONFIG3_SBB(6) | /* Reset default */ 135593db446aSBoris Brezillon NFC_V3_CONFIG3_ADD_OP(0); 135693db446aSBoris Brezillon 135793db446aSBoris Brezillon if (!(chip->options & NAND_BUSWIDTH_16)) 135893db446aSBoris Brezillon config3 |= NFC_V3_CONFIG3_FW8; 135993db446aSBoris Brezillon 136093db446aSBoris Brezillon writel(config3, NFC_V3_CONFIG3); 136193db446aSBoris Brezillon 136293db446aSBoris Brezillon writel(0, NFC_V3_DELAY_LINE); 136393db446aSBoris Brezillon } 136493db446aSBoris Brezillon 136593db446aSBoris Brezillon /* Used by the upper layer to write command to NAND Flash for 136693db446aSBoris Brezillon * different operations to be carried out on NAND Flash */ 136793db446aSBoris Brezillon static void mxc_nand_command(struct mtd_info *mtd, unsigned command, 136893db446aSBoris Brezillon int column, int page_addr) 136993db446aSBoris Brezillon { 137093db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 137193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 137293db446aSBoris Brezillon 137393db446aSBoris Brezillon dev_dbg(host->dev, "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", 137493db446aSBoris Brezillon command, column, page_addr); 137593db446aSBoris Brezillon 137693db446aSBoris Brezillon /* Reset command state information */ 137793db446aSBoris Brezillon host->status_request = false; 137893db446aSBoris Brezillon 137993db446aSBoris Brezillon /* Command pre-processing step */ 138093db446aSBoris Brezillon switch (command) { 138193db446aSBoris Brezillon case NAND_CMD_RESET: 138293db446aSBoris Brezillon host->devtype_data->preset(mtd); 138393db446aSBoris Brezillon host->devtype_data->send_cmd(host, command, false); 138493db446aSBoris Brezillon break; 138593db446aSBoris Brezillon 138693db446aSBoris Brezillon case NAND_CMD_STATUS: 138793db446aSBoris Brezillon host->buf_start = 0; 138893db446aSBoris Brezillon host->status_request = true; 138993db446aSBoris Brezillon 139093db446aSBoris Brezillon host->devtype_data->send_cmd(host, command, true); 139193db446aSBoris Brezillon WARN_ONCE(column != -1 || page_addr != -1, 139293db446aSBoris Brezillon "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n", 139393db446aSBoris Brezillon command, column, page_addr); 139493db446aSBoris Brezillon mxc_do_addr_cycle(mtd, column, page_addr); 139593db446aSBoris Brezillon break; 139693db446aSBoris Brezillon 139793db446aSBoris Brezillon case NAND_CMD_READID: 139893db446aSBoris Brezillon host->devtype_data->send_cmd(host, command, true); 139993db446aSBoris Brezillon mxc_do_addr_cycle(mtd, column, page_addr); 140093db446aSBoris Brezillon host->devtype_data->send_read_id(host); 140193db446aSBoris Brezillon host->buf_start = 0; 140293db446aSBoris Brezillon break; 140393db446aSBoris Brezillon 140493db446aSBoris Brezillon case NAND_CMD_ERASE1: 140593db446aSBoris Brezillon case NAND_CMD_ERASE2: 140693db446aSBoris Brezillon host->devtype_data->send_cmd(host, command, false); 140793db446aSBoris Brezillon WARN_ONCE(column != -1, 140893db446aSBoris Brezillon "Unexpected column value (cmd=%u, col=%d)\n", 140993db446aSBoris Brezillon command, column); 141093db446aSBoris Brezillon mxc_do_addr_cycle(mtd, column, page_addr); 141193db446aSBoris Brezillon 141293db446aSBoris Brezillon break; 141393db446aSBoris Brezillon case NAND_CMD_PARAM: 141493db446aSBoris Brezillon host->devtype_data->send_cmd(host, command, false); 141593db446aSBoris Brezillon mxc_do_addr_cycle(mtd, column, page_addr); 141693db446aSBoris Brezillon host->devtype_data->send_page(mtd, NFC_OUTPUT); 141793db446aSBoris Brezillon memcpy32_fromio(host->data_buf, host->main_area0, 512); 141893db446aSBoris Brezillon host->buf_start = 0; 141993db446aSBoris Brezillon break; 142093db446aSBoris Brezillon default: 142193db446aSBoris Brezillon WARN_ONCE(1, "Unimplemented command (cmd=%u)\n", 142293db446aSBoris Brezillon command); 142393db446aSBoris Brezillon break; 142493db446aSBoris Brezillon } 142593db446aSBoris Brezillon } 142693db446aSBoris Brezillon 1427b958758eSMiquel Raynal static int mxc_nand_set_features(struct mtd_info *mtd, struct nand_chip *chip, 1428b958758eSMiquel Raynal int addr, u8 *subfeature_param) 142993db446aSBoris Brezillon { 143093db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 143193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 143293db446aSBoris Brezillon int i; 143393db446aSBoris Brezillon 143493db446aSBoris Brezillon host->buf_start = 0; 143593db446aSBoris Brezillon 143693db446aSBoris Brezillon for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) 143793db446aSBoris Brezillon chip->write_byte(mtd, subfeature_param[i]); 143893db446aSBoris Brezillon 143993db446aSBoris Brezillon memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); 144093db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_SET_FEATURES, false); 144193db446aSBoris Brezillon mxc_do_addr_cycle(mtd, addr, -1); 144293db446aSBoris Brezillon host->devtype_data->send_page(mtd, NFC_INPUT); 144393db446aSBoris Brezillon 144493db446aSBoris Brezillon return 0; 144593db446aSBoris Brezillon } 144693db446aSBoris Brezillon 1447b958758eSMiquel Raynal static int mxc_nand_get_features(struct mtd_info *mtd, struct nand_chip *chip, 1448b958758eSMiquel Raynal int addr, u8 *subfeature_param) 144993db446aSBoris Brezillon { 145093db446aSBoris Brezillon struct nand_chip *nand_chip = mtd_to_nand(mtd); 145193db446aSBoris Brezillon struct mxc_nand_host *host = nand_get_controller_data(nand_chip); 145293db446aSBoris Brezillon int i; 145393db446aSBoris Brezillon 145493db446aSBoris Brezillon host->devtype_data->send_cmd(host, NAND_CMD_GET_FEATURES, false); 145593db446aSBoris Brezillon mxc_do_addr_cycle(mtd, addr, -1); 145693db446aSBoris Brezillon host->devtype_data->send_page(mtd, NFC_OUTPUT); 145793db446aSBoris Brezillon memcpy32_fromio(host->data_buf, host->main_area0, 512); 145893db446aSBoris Brezillon host->buf_start = 0; 145993db446aSBoris Brezillon 146093db446aSBoris Brezillon for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) 146193db446aSBoris Brezillon *subfeature_param++ = chip->read_byte(mtd); 146293db446aSBoris Brezillon 146393db446aSBoris Brezillon return 0; 146493db446aSBoris Brezillon } 146593db446aSBoris Brezillon 146693db446aSBoris Brezillon /* 146793db446aSBoris Brezillon * The generic flash bbt decriptors overlap with our ecc 146893db446aSBoris Brezillon * hardware, so define some i.MX specific ones. 146993db446aSBoris Brezillon */ 147093db446aSBoris Brezillon static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' }; 147193db446aSBoris Brezillon static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' }; 147293db446aSBoris Brezillon 147393db446aSBoris Brezillon static struct nand_bbt_descr bbt_main_descr = { 147493db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 147593db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 147693db446aSBoris Brezillon .offs = 0, 147793db446aSBoris Brezillon .len = 4, 147893db446aSBoris Brezillon .veroffs = 4, 147993db446aSBoris Brezillon .maxblocks = 4, 148093db446aSBoris Brezillon .pattern = bbt_pattern, 148193db446aSBoris Brezillon }; 148293db446aSBoris Brezillon 148393db446aSBoris Brezillon static struct nand_bbt_descr bbt_mirror_descr = { 148493db446aSBoris Brezillon .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 148593db446aSBoris Brezillon | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 148693db446aSBoris Brezillon .offs = 0, 148793db446aSBoris Brezillon .len = 4, 148893db446aSBoris Brezillon .veroffs = 4, 148993db446aSBoris Brezillon .maxblocks = 4, 149093db446aSBoris Brezillon .pattern = mirror_pattern, 149193db446aSBoris Brezillon }; 149293db446aSBoris Brezillon 149393db446aSBoris Brezillon /* v1 + irqpending_quirk: i.MX21 */ 149493db446aSBoris Brezillon static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { 149593db446aSBoris Brezillon .preset = preset_v1, 149693db446aSBoris Brezillon .read_page = mxc_nand_read_page_v1, 149793db446aSBoris Brezillon .send_cmd = send_cmd_v1_v2, 149893db446aSBoris Brezillon .send_addr = send_addr_v1_v2, 149993db446aSBoris Brezillon .send_page = send_page_v1, 150093db446aSBoris Brezillon .send_read_id = send_read_id_v1_v2, 150193db446aSBoris Brezillon .get_dev_status = get_dev_status_v1_v2, 150293db446aSBoris Brezillon .check_int = check_int_v1_v2, 150393db446aSBoris Brezillon .irq_control = irq_control_v1_v2, 150493db446aSBoris Brezillon .get_ecc_status = get_ecc_status_v1, 150593db446aSBoris Brezillon .ooblayout = &mxc_v1_ooblayout_ops, 150693db446aSBoris Brezillon .select_chip = mxc_nand_select_chip_v1_v3, 150793db446aSBoris Brezillon .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, 150893db446aSBoris Brezillon .irqpending_quirk = 1, 150993db446aSBoris Brezillon .needs_ip = 0, 151093db446aSBoris Brezillon .regs_offset = 0xe00, 151193db446aSBoris Brezillon .spare0_offset = 0x800, 151293db446aSBoris Brezillon .spare_len = 16, 151393db446aSBoris Brezillon .eccbytes = 3, 151493db446aSBoris Brezillon .eccsize = 1, 151593db446aSBoris Brezillon }; 151693db446aSBoris Brezillon 151793db446aSBoris Brezillon /* v1 + !irqpending_quirk: i.MX27, i.MX31 */ 151893db446aSBoris Brezillon static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { 151993db446aSBoris Brezillon .preset = preset_v1, 152093db446aSBoris Brezillon .read_page = mxc_nand_read_page_v1, 152193db446aSBoris Brezillon .send_cmd = send_cmd_v1_v2, 152293db446aSBoris Brezillon .send_addr = send_addr_v1_v2, 152393db446aSBoris Brezillon .send_page = send_page_v1, 152493db446aSBoris Brezillon .send_read_id = send_read_id_v1_v2, 152593db446aSBoris Brezillon .get_dev_status = get_dev_status_v1_v2, 152693db446aSBoris Brezillon .check_int = check_int_v1_v2, 152793db446aSBoris Brezillon .irq_control = irq_control_v1_v2, 152893db446aSBoris Brezillon .get_ecc_status = get_ecc_status_v1, 152993db446aSBoris Brezillon .ooblayout = &mxc_v1_ooblayout_ops, 153093db446aSBoris Brezillon .select_chip = mxc_nand_select_chip_v1_v3, 153193db446aSBoris Brezillon .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, 153293db446aSBoris Brezillon .irqpending_quirk = 0, 153393db446aSBoris Brezillon .needs_ip = 0, 153493db446aSBoris Brezillon .regs_offset = 0xe00, 153593db446aSBoris Brezillon .spare0_offset = 0x800, 153693db446aSBoris Brezillon .axi_offset = 0, 153793db446aSBoris Brezillon .spare_len = 16, 153893db446aSBoris Brezillon .eccbytes = 3, 153993db446aSBoris Brezillon .eccsize = 1, 154093db446aSBoris Brezillon }; 154193db446aSBoris Brezillon 154293db446aSBoris Brezillon /* v21: i.MX25, i.MX35 */ 154393db446aSBoris Brezillon static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { 154493db446aSBoris Brezillon .preset = preset_v2, 154593db446aSBoris Brezillon .read_page = mxc_nand_read_page_v2_v3, 154693db446aSBoris Brezillon .send_cmd = send_cmd_v1_v2, 154793db446aSBoris Brezillon .send_addr = send_addr_v1_v2, 154893db446aSBoris Brezillon .send_page = send_page_v2, 154993db446aSBoris Brezillon .send_read_id = send_read_id_v1_v2, 155093db446aSBoris Brezillon .get_dev_status = get_dev_status_v1_v2, 155193db446aSBoris Brezillon .check_int = check_int_v1_v2, 155293db446aSBoris Brezillon .irq_control = irq_control_v1_v2, 155393db446aSBoris Brezillon .get_ecc_status = get_ecc_status_v2, 155493db446aSBoris Brezillon .ooblayout = &mxc_v2_ooblayout_ops, 155593db446aSBoris Brezillon .select_chip = mxc_nand_select_chip_v2, 155693db446aSBoris Brezillon .setup_data_interface = mxc_nand_v2_setup_data_interface, 155793db446aSBoris Brezillon .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, 155893db446aSBoris Brezillon .irqpending_quirk = 0, 155993db446aSBoris Brezillon .needs_ip = 0, 156093db446aSBoris Brezillon .regs_offset = 0x1e00, 156193db446aSBoris Brezillon .spare0_offset = 0x1000, 156293db446aSBoris Brezillon .axi_offset = 0, 156393db446aSBoris Brezillon .spare_len = 64, 156493db446aSBoris Brezillon .eccbytes = 9, 156593db446aSBoris Brezillon .eccsize = 0, 156693db446aSBoris Brezillon }; 156793db446aSBoris Brezillon 156893db446aSBoris Brezillon /* v3.2a: i.MX51 */ 156993db446aSBoris Brezillon static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { 157093db446aSBoris Brezillon .preset = preset_v3, 157193db446aSBoris Brezillon .read_page = mxc_nand_read_page_v2_v3, 157293db446aSBoris Brezillon .send_cmd = send_cmd_v3, 157393db446aSBoris Brezillon .send_addr = send_addr_v3, 157493db446aSBoris Brezillon .send_page = send_page_v3, 157593db446aSBoris Brezillon .send_read_id = send_read_id_v3, 157693db446aSBoris Brezillon .get_dev_status = get_dev_status_v3, 157793db446aSBoris Brezillon .check_int = check_int_v3, 157893db446aSBoris Brezillon .irq_control = irq_control_v3, 157993db446aSBoris Brezillon .get_ecc_status = get_ecc_status_v3, 158093db446aSBoris Brezillon .ooblayout = &mxc_v2_ooblayout_ops, 158193db446aSBoris Brezillon .select_chip = mxc_nand_select_chip_v1_v3, 158293db446aSBoris Brezillon .enable_hwecc = mxc_nand_enable_hwecc_v3, 158393db446aSBoris Brezillon .irqpending_quirk = 0, 158493db446aSBoris Brezillon .needs_ip = 1, 158593db446aSBoris Brezillon .regs_offset = 0, 158693db446aSBoris Brezillon .spare0_offset = 0x1000, 158793db446aSBoris Brezillon .axi_offset = 0x1e00, 158893db446aSBoris Brezillon .spare_len = 64, 158993db446aSBoris Brezillon .eccbytes = 0, 159093db446aSBoris Brezillon .eccsize = 0, 159193db446aSBoris Brezillon .ppb_shift = 7, 159293db446aSBoris Brezillon }; 159393db446aSBoris Brezillon 159493db446aSBoris Brezillon /* v3.2b: i.MX53 */ 159593db446aSBoris Brezillon static const struct mxc_nand_devtype_data imx53_nand_devtype_data = { 159693db446aSBoris Brezillon .preset = preset_v3, 159793db446aSBoris Brezillon .read_page = mxc_nand_read_page_v2_v3, 159893db446aSBoris Brezillon .send_cmd = send_cmd_v3, 159993db446aSBoris Brezillon .send_addr = send_addr_v3, 160093db446aSBoris Brezillon .send_page = send_page_v3, 160193db446aSBoris Brezillon .send_read_id = send_read_id_v3, 160293db446aSBoris Brezillon .get_dev_status = get_dev_status_v3, 160393db446aSBoris Brezillon .check_int = check_int_v3, 160493db446aSBoris Brezillon .irq_control = irq_control_v3, 160593db446aSBoris Brezillon .get_ecc_status = get_ecc_status_v3, 160693db446aSBoris Brezillon .ooblayout = &mxc_v2_ooblayout_ops, 160793db446aSBoris Brezillon .select_chip = mxc_nand_select_chip_v1_v3, 160893db446aSBoris Brezillon .enable_hwecc = mxc_nand_enable_hwecc_v3, 160993db446aSBoris Brezillon .irqpending_quirk = 0, 161093db446aSBoris Brezillon .needs_ip = 1, 161193db446aSBoris Brezillon .regs_offset = 0, 161293db446aSBoris Brezillon .spare0_offset = 0x1000, 161393db446aSBoris Brezillon .axi_offset = 0x1e00, 161493db446aSBoris Brezillon .spare_len = 64, 161593db446aSBoris Brezillon .eccbytes = 0, 161693db446aSBoris Brezillon .eccsize = 0, 161793db446aSBoris Brezillon .ppb_shift = 8, 161893db446aSBoris Brezillon }; 161993db446aSBoris Brezillon 162093db446aSBoris Brezillon static inline int is_imx21_nfc(struct mxc_nand_host *host) 162193db446aSBoris Brezillon { 162293db446aSBoris Brezillon return host->devtype_data == &imx21_nand_devtype_data; 162393db446aSBoris Brezillon } 162493db446aSBoris Brezillon 162593db446aSBoris Brezillon static inline int is_imx27_nfc(struct mxc_nand_host *host) 162693db446aSBoris Brezillon { 162793db446aSBoris Brezillon return host->devtype_data == &imx27_nand_devtype_data; 162893db446aSBoris Brezillon } 162993db446aSBoris Brezillon 163093db446aSBoris Brezillon static inline int is_imx25_nfc(struct mxc_nand_host *host) 163193db446aSBoris Brezillon { 163293db446aSBoris Brezillon return host->devtype_data == &imx25_nand_devtype_data; 163393db446aSBoris Brezillon } 163493db446aSBoris Brezillon 163593db446aSBoris Brezillon static inline int is_imx51_nfc(struct mxc_nand_host *host) 163693db446aSBoris Brezillon { 163793db446aSBoris Brezillon return host->devtype_data == &imx51_nand_devtype_data; 163893db446aSBoris Brezillon } 163993db446aSBoris Brezillon 164093db446aSBoris Brezillon static inline int is_imx53_nfc(struct mxc_nand_host *host) 164193db446aSBoris Brezillon { 164293db446aSBoris Brezillon return host->devtype_data == &imx53_nand_devtype_data; 164393db446aSBoris Brezillon } 164493db446aSBoris Brezillon 164593db446aSBoris Brezillon static const struct platform_device_id mxcnd_devtype[] = { 164693db446aSBoris Brezillon { 164793db446aSBoris Brezillon .name = "imx21-nand", 164893db446aSBoris Brezillon .driver_data = (kernel_ulong_t) &imx21_nand_devtype_data, 164993db446aSBoris Brezillon }, { 165093db446aSBoris Brezillon .name = "imx27-nand", 165193db446aSBoris Brezillon .driver_data = (kernel_ulong_t) &imx27_nand_devtype_data, 165293db446aSBoris Brezillon }, { 165393db446aSBoris Brezillon .name = "imx25-nand", 165493db446aSBoris Brezillon .driver_data = (kernel_ulong_t) &imx25_nand_devtype_data, 165593db446aSBoris Brezillon }, { 165693db446aSBoris Brezillon .name = "imx51-nand", 165793db446aSBoris Brezillon .driver_data = (kernel_ulong_t) &imx51_nand_devtype_data, 165893db446aSBoris Brezillon }, { 165993db446aSBoris Brezillon .name = "imx53-nand", 166093db446aSBoris Brezillon .driver_data = (kernel_ulong_t) &imx53_nand_devtype_data, 166193db446aSBoris Brezillon }, { 166293db446aSBoris Brezillon /* sentinel */ 166393db446aSBoris Brezillon } 166493db446aSBoris Brezillon }; 166593db446aSBoris Brezillon MODULE_DEVICE_TABLE(platform, mxcnd_devtype); 166693db446aSBoris Brezillon 166793db446aSBoris Brezillon #ifdef CONFIG_OF 166893db446aSBoris Brezillon static const struct of_device_id mxcnd_dt_ids[] = { 166993db446aSBoris Brezillon { 167093db446aSBoris Brezillon .compatible = "fsl,imx21-nand", 167193db446aSBoris Brezillon .data = &imx21_nand_devtype_data, 167293db446aSBoris Brezillon }, { 167393db446aSBoris Brezillon .compatible = "fsl,imx27-nand", 167493db446aSBoris Brezillon .data = &imx27_nand_devtype_data, 167593db446aSBoris Brezillon }, { 167693db446aSBoris Brezillon .compatible = "fsl,imx25-nand", 167793db446aSBoris Brezillon .data = &imx25_nand_devtype_data, 167893db446aSBoris Brezillon }, { 167993db446aSBoris Brezillon .compatible = "fsl,imx51-nand", 168093db446aSBoris Brezillon .data = &imx51_nand_devtype_data, 168193db446aSBoris Brezillon }, { 168293db446aSBoris Brezillon .compatible = "fsl,imx53-nand", 168393db446aSBoris Brezillon .data = &imx53_nand_devtype_data, 168493db446aSBoris Brezillon }, 168593db446aSBoris Brezillon { /* sentinel */ } 168693db446aSBoris Brezillon }; 168793db446aSBoris Brezillon MODULE_DEVICE_TABLE(of, mxcnd_dt_ids); 168893db446aSBoris Brezillon 168993db446aSBoris Brezillon static int __init mxcnd_probe_dt(struct mxc_nand_host *host) 169093db446aSBoris Brezillon { 169193db446aSBoris Brezillon struct device_node *np = host->dev->of_node; 169293db446aSBoris Brezillon const struct of_device_id *of_id = 169393db446aSBoris Brezillon of_match_device(mxcnd_dt_ids, host->dev); 169493db446aSBoris Brezillon 169593db446aSBoris Brezillon if (!np) 169693db446aSBoris Brezillon return 1; 169793db446aSBoris Brezillon 169893db446aSBoris Brezillon host->devtype_data = of_id->data; 169993db446aSBoris Brezillon 170093db446aSBoris Brezillon return 0; 170193db446aSBoris Brezillon } 170293db446aSBoris Brezillon #else 170393db446aSBoris Brezillon static int __init mxcnd_probe_dt(struct mxc_nand_host *host) 170493db446aSBoris Brezillon { 170593db446aSBoris Brezillon return 1; 170693db446aSBoris Brezillon } 170793db446aSBoris Brezillon #endif 170893db446aSBoris Brezillon 170993db446aSBoris Brezillon static int mxcnd_probe(struct platform_device *pdev) 171093db446aSBoris Brezillon { 171193db446aSBoris Brezillon struct nand_chip *this; 171293db446aSBoris Brezillon struct mtd_info *mtd; 171393db446aSBoris Brezillon struct mxc_nand_host *host; 171493db446aSBoris Brezillon struct resource *res; 171593db446aSBoris Brezillon int err = 0; 171693db446aSBoris Brezillon 171793db446aSBoris Brezillon /* Allocate memory for MTD device structure and private data */ 171893db446aSBoris Brezillon host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host), 171993db446aSBoris Brezillon GFP_KERNEL); 172093db446aSBoris Brezillon if (!host) 172193db446aSBoris Brezillon return -ENOMEM; 172293db446aSBoris Brezillon 172393db446aSBoris Brezillon /* allocate a temporary buffer for the nand_scan_ident() */ 172493db446aSBoris Brezillon host->data_buf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL); 172593db446aSBoris Brezillon if (!host->data_buf) 172693db446aSBoris Brezillon return -ENOMEM; 172793db446aSBoris Brezillon 172893db446aSBoris Brezillon host->dev = &pdev->dev; 172993db446aSBoris Brezillon /* structures must be linked */ 173093db446aSBoris Brezillon this = &host->nand; 173193db446aSBoris Brezillon mtd = nand_to_mtd(this); 173293db446aSBoris Brezillon mtd->dev.parent = &pdev->dev; 173393db446aSBoris Brezillon mtd->name = DRIVER_NAME; 173493db446aSBoris Brezillon 173593db446aSBoris Brezillon /* 50 us command delay time */ 173693db446aSBoris Brezillon this->chip_delay = 5; 173793db446aSBoris Brezillon 173893db446aSBoris Brezillon nand_set_controller_data(this, host); 173993db446aSBoris Brezillon nand_set_flash_node(this, pdev->dev.of_node), 174093db446aSBoris Brezillon this->dev_ready = mxc_nand_dev_ready; 174193db446aSBoris Brezillon this->cmdfunc = mxc_nand_command; 174293db446aSBoris Brezillon this->read_byte = mxc_nand_read_byte; 174393db446aSBoris Brezillon this->read_word = mxc_nand_read_word; 174493db446aSBoris Brezillon this->write_buf = mxc_nand_write_buf; 174593db446aSBoris Brezillon this->read_buf = mxc_nand_read_buf; 1746b958758eSMiquel Raynal this->set_features = mxc_nand_set_features; 1747b958758eSMiquel Raynal this->get_features = mxc_nand_get_features; 174893db446aSBoris Brezillon 174993db446aSBoris Brezillon host->clk = devm_clk_get(&pdev->dev, NULL); 175093db446aSBoris Brezillon if (IS_ERR(host->clk)) 175193db446aSBoris Brezillon return PTR_ERR(host->clk); 175293db446aSBoris Brezillon 175393db446aSBoris Brezillon err = mxcnd_probe_dt(host); 175493db446aSBoris Brezillon if (err > 0) { 175593db446aSBoris Brezillon struct mxc_nand_platform_data *pdata = 175693db446aSBoris Brezillon dev_get_platdata(&pdev->dev); 175793db446aSBoris Brezillon if (pdata) { 175893db446aSBoris Brezillon host->pdata = *pdata; 175993db446aSBoris Brezillon host->devtype_data = (struct mxc_nand_devtype_data *) 176093db446aSBoris Brezillon pdev->id_entry->driver_data; 176193db446aSBoris Brezillon } else { 176293db446aSBoris Brezillon err = -ENODEV; 176393db446aSBoris Brezillon } 176493db446aSBoris Brezillon } 176593db446aSBoris Brezillon if (err < 0) 176693db446aSBoris Brezillon return err; 176793db446aSBoris Brezillon 176893db446aSBoris Brezillon this->setup_data_interface = host->devtype_data->setup_data_interface; 176993db446aSBoris Brezillon 177093db446aSBoris Brezillon if (host->devtype_data->needs_ip) { 177193db446aSBoris Brezillon res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 177293db446aSBoris Brezillon host->regs_ip = devm_ioremap_resource(&pdev->dev, res); 177393db446aSBoris Brezillon if (IS_ERR(host->regs_ip)) 177493db446aSBoris Brezillon return PTR_ERR(host->regs_ip); 177593db446aSBoris Brezillon 177693db446aSBoris Brezillon res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 177793db446aSBoris Brezillon } else { 177893db446aSBoris Brezillon res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 177993db446aSBoris Brezillon } 178093db446aSBoris Brezillon 178193db446aSBoris Brezillon host->base = devm_ioremap_resource(&pdev->dev, res); 178293db446aSBoris Brezillon if (IS_ERR(host->base)) 178393db446aSBoris Brezillon return PTR_ERR(host->base); 178493db446aSBoris Brezillon 178593db446aSBoris Brezillon host->main_area0 = host->base; 178693db446aSBoris Brezillon 178793db446aSBoris Brezillon if (host->devtype_data->regs_offset) 178893db446aSBoris Brezillon host->regs = host->base + host->devtype_data->regs_offset; 178993db446aSBoris Brezillon host->spare0 = host->base + host->devtype_data->spare0_offset; 179093db446aSBoris Brezillon if (host->devtype_data->axi_offset) 179193db446aSBoris Brezillon host->regs_axi = host->base + host->devtype_data->axi_offset; 179293db446aSBoris Brezillon 179393db446aSBoris Brezillon this->ecc.bytes = host->devtype_data->eccbytes; 179493db446aSBoris Brezillon host->eccsize = host->devtype_data->eccsize; 179593db446aSBoris Brezillon 179693db446aSBoris Brezillon this->select_chip = host->devtype_data->select_chip; 179793db446aSBoris Brezillon this->ecc.size = 512; 179893db446aSBoris Brezillon mtd_set_ooblayout(mtd, host->devtype_data->ooblayout); 179993db446aSBoris Brezillon 180093db446aSBoris Brezillon if (host->pdata.hw_ecc) { 180193db446aSBoris Brezillon this->ecc.mode = NAND_ECC_HW; 180293db446aSBoris Brezillon } else { 180393db446aSBoris Brezillon this->ecc.mode = NAND_ECC_SOFT; 180493db446aSBoris Brezillon this->ecc.algo = NAND_ECC_HAMMING; 180593db446aSBoris Brezillon } 180693db446aSBoris Brezillon 180793db446aSBoris Brezillon /* NAND bus width determines access functions used by upper layer */ 180893db446aSBoris Brezillon if (host->pdata.width == 2) 180993db446aSBoris Brezillon this->options |= NAND_BUSWIDTH_16; 181093db446aSBoris Brezillon 181193db446aSBoris Brezillon /* update flash based bbt */ 181293db446aSBoris Brezillon if (host->pdata.flash_bbt) 181393db446aSBoris Brezillon this->bbt_options |= NAND_BBT_USE_FLASH; 181493db446aSBoris Brezillon 181593db446aSBoris Brezillon init_completion(&host->op_completion); 181693db446aSBoris Brezillon 181793db446aSBoris Brezillon host->irq = platform_get_irq(pdev, 0); 181893db446aSBoris Brezillon if (host->irq < 0) 181993db446aSBoris Brezillon return host->irq; 182093db446aSBoris Brezillon 182193db446aSBoris Brezillon /* 182293db446aSBoris Brezillon * Use host->devtype_data->irq_control() here instead of irq_control() 182393db446aSBoris Brezillon * because we must not disable_irq_nosync without having requested the 182493db446aSBoris Brezillon * irq. 182593db446aSBoris Brezillon */ 182693db446aSBoris Brezillon host->devtype_data->irq_control(host, 0); 182793db446aSBoris Brezillon 182893db446aSBoris Brezillon err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq, 182993db446aSBoris Brezillon 0, DRIVER_NAME, host); 183093db446aSBoris Brezillon if (err) 183193db446aSBoris Brezillon return err; 183293db446aSBoris Brezillon 183393db446aSBoris Brezillon err = clk_prepare_enable(host->clk); 183493db446aSBoris Brezillon if (err) 183593db446aSBoris Brezillon return err; 183693db446aSBoris Brezillon host->clk_act = 1; 183793db446aSBoris Brezillon 183893db446aSBoris Brezillon /* 183993db446aSBoris Brezillon * Now that we "own" the interrupt make sure the interrupt mask bit is 184093db446aSBoris Brezillon * cleared on i.MX21. Otherwise we can't read the interrupt status bit 184193db446aSBoris Brezillon * on this machine. 184293db446aSBoris Brezillon */ 184393db446aSBoris Brezillon if (host->devtype_data->irqpending_quirk) { 184493db446aSBoris Brezillon disable_irq_nosync(host->irq); 184593db446aSBoris Brezillon host->devtype_data->irq_control(host, 1); 184693db446aSBoris Brezillon } 184793db446aSBoris Brezillon 184893db446aSBoris Brezillon /* first scan to find the device and get the page size */ 184993db446aSBoris Brezillon err = nand_scan_ident(mtd, is_imx25_nfc(host) ? 4 : 1, NULL); 185093db446aSBoris Brezillon if (err) 185193db446aSBoris Brezillon goto escan; 185293db446aSBoris Brezillon 185393db446aSBoris Brezillon switch (this->ecc.mode) { 185493db446aSBoris Brezillon case NAND_ECC_HW: 185593db446aSBoris Brezillon this->ecc.read_page = mxc_nand_read_page; 185693db446aSBoris Brezillon this->ecc.read_page_raw = mxc_nand_read_page_raw; 185793db446aSBoris Brezillon this->ecc.read_oob = mxc_nand_read_oob; 185893db446aSBoris Brezillon this->ecc.write_page = mxc_nand_write_page_ecc; 185993db446aSBoris Brezillon this->ecc.write_page_raw = mxc_nand_write_page_raw; 186093db446aSBoris Brezillon this->ecc.write_oob = mxc_nand_write_oob; 186193db446aSBoris Brezillon break; 186293db446aSBoris Brezillon 186393db446aSBoris Brezillon case NAND_ECC_SOFT: 186493db446aSBoris Brezillon break; 186593db446aSBoris Brezillon 186693db446aSBoris Brezillon default: 186793db446aSBoris Brezillon err = -EINVAL; 186893db446aSBoris Brezillon goto escan; 186993db446aSBoris Brezillon } 187093db446aSBoris Brezillon 187193db446aSBoris Brezillon if (this->bbt_options & NAND_BBT_USE_FLASH) { 187293db446aSBoris Brezillon this->bbt_td = &bbt_main_descr; 187393db446aSBoris Brezillon this->bbt_md = &bbt_mirror_descr; 187493db446aSBoris Brezillon } 187593db446aSBoris Brezillon 187693db446aSBoris Brezillon /* allocate the right size buffer now */ 187793db446aSBoris Brezillon devm_kfree(&pdev->dev, (void *)host->data_buf); 187893db446aSBoris Brezillon host->data_buf = devm_kzalloc(&pdev->dev, mtd->writesize + mtd->oobsize, 187993db446aSBoris Brezillon GFP_KERNEL); 188093db446aSBoris Brezillon if (!host->data_buf) { 188193db446aSBoris Brezillon err = -ENOMEM; 188293db446aSBoris Brezillon goto escan; 188393db446aSBoris Brezillon } 188493db446aSBoris Brezillon 188593db446aSBoris Brezillon /* Call preset again, with correct writesize this time */ 188693db446aSBoris Brezillon host->devtype_data->preset(mtd); 188793db446aSBoris Brezillon 188893db446aSBoris Brezillon if (!this->ecc.bytes) { 188993db446aSBoris Brezillon if (host->eccsize == 8) 189093db446aSBoris Brezillon this->ecc.bytes = 18; 189193db446aSBoris Brezillon else if (host->eccsize == 4) 189293db446aSBoris Brezillon this->ecc.bytes = 9; 189393db446aSBoris Brezillon } 189493db446aSBoris Brezillon 189593db446aSBoris Brezillon /* 189693db446aSBoris Brezillon * Experimentation shows that i.MX NFC can only handle up to 218 oob 189793db446aSBoris Brezillon * bytes. Limit used_oobsize to 218 so as to not confuse copy_spare() 189893db446aSBoris Brezillon * into copying invalid data to/from the spare IO buffer, as this 189993db446aSBoris Brezillon * might cause ECC data corruption when doing sub-page write to a 190093db446aSBoris Brezillon * partially written page. 190193db446aSBoris Brezillon */ 190293db446aSBoris Brezillon host->used_oobsize = min(mtd->oobsize, 218U); 190393db446aSBoris Brezillon 190493db446aSBoris Brezillon if (this->ecc.mode == NAND_ECC_HW) { 190593db446aSBoris Brezillon if (is_imx21_nfc(host) || is_imx27_nfc(host)) 190693db446aSBoris Brezillon this->ecc.strength = 1; 190793db446aSBoris Brezillon else 190893db446aSBoris Brezillon this->ecc.strength = (host->eccsize == 4) ? 4 : 8; 190993db446aSBoris Brezillon } 191093db446aSBoris Brezillon 191193db446aSBoris Brezillon /* second phase scan */ 191293db446aSBoris Brezillon err = nand_scan_tail(mtd); 191393db446aSBoris Brezillon if (err) 191493db446aSBoris Brezillon goto escan; 191593db446aSBoris Brezillon 191693db446aSBoris Brezillon /* Register the partitions */ 1917be051bf2SMiquel Raynal err = mtd_device_parse_register(mtd, part_probes, NULL, 191893db446aSBoris Brezillon host->pdata.parts, 191993db446aSBoris Brezillon host->pdata.nr_parts); 1920be051bf2SMiquel Raynal if (err) 1921be051bf2SMiquel Raynal goto cleanup_nand; 192293db446aSBoris Brezillon 192393db446aSBoris Brezillon platform_set_drvdata(pdev, host); 192493db446aSBoris Brezillon 192593db446aSBoris Brezillon return 0; 192693db446aSBoris Brezillon 1927be051bf2SMiquel Raynal cleanup_nand: 1928be051bf2SMiquel Raynal nand_cleanup(this); 192993db446aSBoris Brezillon escan: 193093db446aSBoris Brezillon if (host->clk_act) 193193db446aSBoris Brezillon clk_disable_unprepare(host->clk); 193293db446aSBoris Brezillon 193393db446aSBoris Brezillon return err; 193493db446aSBoris Brezillon } 193593db446aSBoris Brezillon 193693db446aSBoris Brezillon static int mxcnd_remove(struct platform_device *pdev) 193793db446aSBoris Brezillon { 193893db446aSBoris Brezillon struct mxc_nand_host *host = platform_get_drvdata(pdev); 193993db446aSBoris Brezillon 194093db446aSBoris Brezillon nand_release(nand_to_mtd(&host->nand)); 194193db446aSBoris Brezillon if (host->clk_act) 194293db446aSBoris Brezillon clk_disable_unprepare(host->clk); 194393db446aSBoris Brezillon 194493db446aSBoris Brezillon return 0; 194593db446aSBoris Brezillon } 194693db446aSBoris Brezillon 194793db446aSBoris Brezillon static struct platform_driver mxcnd_driver = { 194893db446aSBoris Brezillon .driver = { 194993db446aSBoris Brezillon .name = DRIVER_NAME, 195093db446aSBoris Brezillon .of_match_table = of_match_ptr(mxcnd_dt_ids), 195193db446aSBoris Brezillon }, 195293db446aSBoris Brezillon .id_table = mxcnd_devtype, 195393db446aSBoris Brezillon .probe = mxcnd_probe, 195493db446aSBoris Brezillon .remove = mxcnd_remove, 195593db446aSBoris Brezillon }; 195693db446aSBoris Brezillon module_platform_driver(mxcnd_driver); 195793db446aSBoris Brezillon 195893db446aSBoris Brezillon MODULE_AUTHOR("Freescale Semiconductor, Inc."); 195993db446aSBoris Brezillon MODULE_DESCRIPTION("MXC NAND MTD driver"); 196093db446aSBoris Brezillon MODULE_LICENSE("GPL"); 1961