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