174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2ff4569c7SDavid Brownell /* 3ff4569c7SDavid Brownell * davinci_nand.c - NAND Flash Driver for DaVinci family chips 4ff4569c7SDavid Brownell * 5ff4569c7SDavid Brownell * Copyright © 2006 Texas Instruments. 6ff4569c7SDavid Brownell * 7ff4569c7SDavid Brownell * Port to 2.6.23 Copyright © 2008 by: 8ff4569c7SDavid Brownell * Sander Huijsen <Shuijsen@optelecom-nkf.com> 9ff4569c7SDavid Brownell * Troy Kisky <troy.kisky@boundarydevices.com> 10ff4569c7SDavid Brownell * Dirk Behme <Dirk.Behme@gmail.com> 11ff4569c7SDavid Brownell */ 12ff4569c7SDavid Brownell 13ff4569c7SDavid Brownell #include <linux/kernel.h> 14ff4569c7SDavid Brownell #include <linux/module.h> 15ff4569c7SDavid Brownell #include <linux/platform_device.h> 16ff4569c7SDavid Brownell #include <linux/err.h> 17547aa7c2SBoris Brezillon #include <linux/iopoll.h> 18d4092d76SBoris Brezillon #include <linux/mtd/rawnand.h> 19ff4569c7SDavid Brownell #include <linux/mtd/partitions.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 21cdeadd71SHeiko Schocher #include <linux/of_device.h> 22c4f8cde8SSachin Kamat #include <linux/of.h> 23ff4569c7SDavid Brownell 24ec2a0833SArnd Bergmann #include <linux/platform_data/mtd-davinci.h> 25ec2a0833SArnd Bergmann #include <linux/platform_data/mtd-davinci-aemif.h> 26ff4569c7SDavid Brownell 27ff4569c7SDavid Brownell /* 28ff4569c7SDavid Brownell * This is a device driver for the NAND flash controller found on the 29ff4569c7SDavid Brownell * various DaVinci family chips. It handles up to four SoC chipselects, 30ff4569c7SDavid Brownell * and some flavors of secondary chipselect (e.g. based on A12) as used 31ff4569c7SDavid Brownell * with multichip packages. 32ff4569c7SDavid Brownell * 336a4123e5SDavid Brownell * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC 34ff4569c7SDavid Brownell * available on chips like the DM355 and OMAP-L137 and needed with the 35ff4569c7SDavid Brownell * more error-prone MLC NAND chips. 36ff4569c7SDavid Brownell * 37ff4569c7SDavid Brownell * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY 38ff4569c7SDavid Brownell * outputs in a "wire-AND" configuration, with no per-chip signals. 39ff4569c7SDavid Brownell */ 40ff4569c7SDavid Brownell struct davinci_nand_info { 413626fdcfSBoris Brezillon struct nand_controller controller; 42ff4569c7SDavid Brownell struct nand_chip chip; 43ff4569c7SDavid Brownell 44b2342c1cSMiquel Raynal struct platform_device *pdev; 45ff4569c7SDavid Brownell 466a4123e5SDavid Brownell bool is_readmode; 476a4123e5SDavid Brownell 48ff4569c7SDavid Brownell void __iomem *base; 49ff4569c7SDavid Brownell void __iomem *vaddr; 50ff4569c7SDavid Brownell 51c5b76d8dSBoris Brezillon void __iomem *current_cs; 52ff4569c7SDavid Brownell 53ff4569c7SDavid Brownell uint32_t mask_chipsel; 54ff4569c7SDavid Brownell uint32_t mask_ale; 55ff4569c7SDavid Brownell uint32_t mask_cle; 56ff4569c7SDavid Brownell 57ff4569c7SDavid Brownell uint32_t core_chipsel; 58a88dbc5bSSekhar Nori 59a88dbc5bSSekhar Nori struct davinci_aemif_timing *timing; 60ff4569c7SDavid Brownell }; 61ff4569c7SDavid Brownell 62ff4569c7SDavid Brownell static DEFINE_SPINLOCK(davinci_nand_lock); 636a4123e5SDavid Brownell static bool ecc4_busy; 64ff4569c7SDavid Brownell 65a5cfb4dbSBoris BREZILLON static inline struct davinci_nand_info *to_davinci_nand(struct mtd_info *mtd) 66a5cfb4dbSBoris BREZILLON { 67a5cfb4dbSBoris BREZILLON return container_of(mtd_to_nand(mtd), struct davinci_nand_info, chip); 68a5cfb4dbSBoris BREZILLON } 69ff4569c7SDavid Brownell 70ff4569c7SDavid Brownell static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info, 71ff4569c7SDavid Brownell int offset) 72ff4569c7SDavid Brownell { 73ff4569c7SDavid Brownell return __raw_readl(info->base + offset); 74ff4569c7SDavid Brownell } 75ff4569c7SDavid Brownell 76ff4569c7SDavid Brownell static inline void davinci_nand_writel(struct davinci_nand_info *info, 77ff4569c7SDavid Brownell int offset, unsigned long value) 78ff4569c7SDavid Brownell { 79ff4569c7SDavid Brownell __raw_writel(value, info->base + offset); 80ff4569c7SDavid Brownell } 81ff4569c7SDavid Brownell 82ff4569c7SDavid Brownell /*----------------------------------------------------------------------*/ 83ff4569c7SDavid Brownell 84ff4569c7SDavid Brownell /* 85ff4569c7SDavid Brownell * 1-bit hardware ECC ... context maintained for each core chipselect 86ff4569c7SDavid Brownell */ 87ff4569c7SDavid Brownell 88ff4569c7SDavid Brownell static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd) 89ff4569c7SDavid Brownell { 90ff4569c7SDavid Brownell struct davinci_nand_info *info = to_davinci_nand(mtd); 91ff4569c7SDavid Brownell 92ff4569c7SDavid Brownell return davinci_nand_readl(info, NANDF1ECC_OFFSET 93ff4569c7SDavid Brownell + 4 * info->core_chipsel); 94ff4569c7SDavid Brownell } 95ff4569c7SDavid Brownell 96ec47636cSBoris Brezillon static void nand_davinci_hwctl_1bit(struct nand_chip *chip, int mode) 97ff4569c7SDavid Brownell { 98ff4569c7SDavid Brownell struct davinci_nand_info *info; 99ff4569c7SDavid Brownell uint32_t nandcfr; 100ff4569c7SDavid Brownell unsigned long flags; 101ff4569c7SDavid Brownell 102ec47636cSBoris Brezillon info = to_davinci_nand(nand_to_mtd(chip)); 103ff4569c7SDavid Brownell 104ff4569c7SDavid Brownell /* Reset ECC hardware */ 105ec47636cSBoris Brezillon nand_davinci_readecc_1bit(nand_to_mtd(chip)); 106ff4569c7SDavid Brownell 107ff4569c7SDavid Brownell spin_lock_irqsave(&davinci_nand_lock, flags); 108ff4569c7SDavid Brownell 109ff4569c7SDavid Brownell /* Restart ECC hardware */ 110ff4569c7SDavid Brownell nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET); 111ff4569c7SDavid Brownell nandcfr |= BIT(8 + info->core_chipsel); 112ff4569c7SDavid Brownell davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr); 113ff4569c7SDavid Brownell 114ff4569c7SDavid Brownell spin_unlock_irqrestore(&davinci_nand_lock, flags); 115ff4569c7SDavid Brownell } 116ff4569c7SDavid Brownell 117ff4569c7SDavid Brownell /* 118ff4569c7SDavid Brownell * Read hardware ECC value and pack into three bytes 119ff4569c7SDavid Brownell */ 120af37d2c3SBoris Brezillon static int nand_davinci_calculate_1bit(struct nand_chip *chip, 121ff4569c7SDavid Brownell const u_char *dat, u_char *ecc_code) 122ff4569c7SDavid Brownell { 123af37d2c3SBoris Brezillon unsigned int ecc_val = nand_davinci_readecc_1bit(nand_to_mtd(chip)); 124ff4569c7SDavid Brownell unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4); 125ff4569c7SDavid Brownell 126ff4569c7SDavid Brownell /* invert so that erased block ecc is correct */ 127ff4569c7SDavid Brownell ecc24 = ~ecc24; 128ff4569c7SDavid Brownell ecc_code[0] = (u_char)(ecc24); 129ff4569c7SDavid Brownell ecc_code[1] = (u_char)(ecc24 >> 8); 130ff4569c7SDavid Brownell ecc_code[2] = (u_char)(ecc24 >> 16); 131ff4569c7SDavid Brownell 132ff4569c7SDavid Brownell return 0; 133ff4569c7SDavid Brownell } 134ff4569c7SDavid Brownell 13500da2ea9SBoris Brezillon static int nand_davinci_correct_1bit(struct nand_chip *chip, u_char *dat, 136ff4569c7SDavid Brownell u_char *read_ecc, u_char *calc_ecc) 137ff4569c7SDavid Brownell { 138ff4569c7SDavid Brownell uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) | 139ff4569c7SDavid Brownell (read_ecc[2] << 16); 140ff4569c7SDavid Brownell uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) | 141ff4569c7SDavid Brownell (calc_ecc[2] << 16); 142ff4569c7SDavid Brownell uint32_t diff = eccCalc ^ eccNand; 143ff4569c7SDavid Brownell 144ff4569c7SDavid Brownell if (diff) { 145ff4569c7SDavid Brownell if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) { 146ff4569c7SDavid Brownell /* Correctable error */ 147ff4569c7SDavid Brownell if ((diff >> (12 + 3)) < chip->ecc.size) { 148ff4569c7SDavid Brownell dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7); 149ff4569c7SDavid Brownell return 1; 150ff4569c7SDavid Brownell } else { 1516e941192SBoris BREZILLON return -EBADMSG; 152ff4569c7SDavid Brownell } 153ff4569c7SDavid Brownell } else if (!(diff & (diff - 1))) { 154ff4569c7SDavid Brownell /* Single bit ECC error in the ECC itself, 155ff4569c7SDavid Brownell * nothing to fix */ 156ff4569c7SDavid Brownell return 1; 157ff4569c7SDavid Brownell } else { 158ff4569c7SDavid Brownell /* Uncorrectable error */ 1596e941192SBoris BREZILLON return -EBADMSG; 160ff4569c7SDavid Brownell } 161ff4569c7SDavid Brownell 162ff4569c7SDavid Brownell } 163ff4569c7SDavid Brownell return 0; 164ff4569c7SDavid Brownell } 165ff4569c7SDavid Brownell 166ff4569c7SDavid Brownell /*----------------------------------------------------------------------*/ 167ff4569c7SDavid Brownell 168ff4569c7SDavid Brownell /* 1696a4123e5SDavid Brownell * 4-bit hardware ECC ... context maintained over entire AEMIF 1706a4123e5SDavid Brownell * 171ef24f97dSMiquel Raynal * This is a syndrome engine, but we avoid NAND_ECC_PLACEMENT_INTERLEAVED 1726a4123e5SDavid Brownell * since that forces use of a problematic "infix OOB" layout. 1736a4123e5SDavid Brownell * Among other things, it trashes manufacturer bad block markers. 1746a4123e5SDavid Brownell * Also, and specific to this hardware, it ECC-protects the "prepad" 1756a4123e5SDavid Brownell * in the OOB ... while having ECC protection for parts of OOB would 1766a4123e5SDavid Brownell * seem useful, the current MTD stack sometimes wants to update the 1776a4123e5SDavid Brownell * OOB without recomputing ECC. 1786a4123e5SDavid Brownell */ 1796a4123e5SDavid Brownell 180ec47636cSBoris Brezillon static void nand_davinci_hwctl_4bit(struct nand_chip *chip, int mode) 1816a4123e5SDavid Brownell { 182ec47636cSBoris Brezillon struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip)); 1836a4123e5SDavid Brownell unsigned long flags; 1846a4123e5SDavid Brownell u32 val; 1856a4123e5SDavid Brownell 186f6d7c1b5SKarl Beldan /* Reset ECC hardware */ 187f6d7c1b5SKarl Beldan davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET); 188f6d7c1b5SKarl Beldan 1896a4123e5SDavid Brownell spin_lock_irqsave(&davinci_nand_lock, flags); 1906a4123e5SDavid Brownell 1916a4123e5SDavid Brownell /* Start 4-bit ECC calculation for read/write */ 1926a4123e5SDavid Brownell val = davinci_nand_readl(info, NANDFCR_OFFSET); 1936a4123e5SDavid Brownell val &= ~(0x03 << 4); 1946a4123e5SDavid Brownell val |= (info->core_chipsel << 4) | BIT(12); 1956a4123e5SDavid Brownell davinci_nand_writel(info, NANDFCR_OFFSET, val); 1966a4123e5SDavid Brownell 1976a4123e5SDavid Brownell info->is_readmode = (mode == NAND_ECC_READ); 1986a4123e5SDavid Brownell 1996a4123e5SDavid Brownell spin_unlock_irqrestore(&davinci_nand_lock, flags); 2006a4123e5SDavid Brownell } 2016a4123e5SDavid Brownell 2026a4123e5SDavid Brownell /* Read raw ECC code after writing to NAND. */ 2036a4123e5SDavid Brownell static void 2046a4123e5SDavid Brownell nand_davinci_readecc_4bit(struct davinci_nand_info *info, u32 code[4]) 2056a4123e5SDavid Brownell { 2066a4123e5SDavid Brownell const u32 mask = 0x03ff03ff; 2076a4123e5SDavid Brownell 2086a4123e5SDavid Brownell code[0] = davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET) & mask; 2096a4123e5SDavid Brownell code[1] = davinci_nand_readl(info, NAND_4BIT_ECC2_OFFSET) & mask; 2106a4123e5SDavid Brownell code[2] = davinci_nand_readl(info, NAND_4BIT_ECC3_OFFSET) & mask; 2116a4123e5SDavid Brownell code[3] = davinci_nand_readl(info, NAND_4BIT_ECC4_OFFSET) & mask; 2126a4123e5SDavid Brownell } 2136a4123e5SDavid Brownell 2146a4123e5SDavid Brownell /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */ 215af37d2c3SBoris Brezillon static int nand_davinci_calculate_4bit(struct nand_chip *chip, 2166a4123e5SDavid Brownell const u_char *dat, u_char *ecc_code) 2176a4123e5SDavid Brownell { 218af37d2c3SBoris Brezillon struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip)); 2196a4123e5SDavid Brownell u32 raw_ecc[4], *p; 2206a4123e5SDavid Brownell unsigned i; 2216a4123e5SDavid Brownell 2226a4123e5SDavid Brownell /* After a read, terminate ECC calculation by a dummy read 2236a4123e5SDavid Brownell * of some 4-bit ECC register. ECC covers everything that 2246a4123e5SDavid Brownell * was read; correct() just uses the hardware state, so 2256a4123e5SDavid Brownell * ecc_code is not needed. 2266a4123e5SDavid Brownell */ 2276a4123e5SDavid Brownell if (info->is_readmode) { 2286a4123e5SDavid Brownell davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET); 2296a4123e5SDavid Brownell return 0; 2306a4123e5SDavid Brownell } 2316a4123e5SDavid Brownell 2326a4123e5SDavid Brownell /* Pack eight raw 10-bit ecc values into ten bytes, making 2336a4123e5SDavid Brownell * two passes which each convert four values (in upper and 2346a4123e5SDavid Brownell * lower halves of two 32-bit words) into five bytes. The 2356a4123e5SDavid Brownell * ROM boot loader uses this same packing scheme. 2366a4123e5SDavid Brownell */ 2376a4123e5SDavid Brownell nand_davinci_readecc_4bit(info, raw_ecc); 2386a4123e5SDavid Brownell for (i = 0, p = raw_ecc; i < 2; i++, p += 2) { 2396a4123e5SDavid Brownell *ecc_code++ = p[0] & 0xff; 2406a4123e5SDavid Brownell *ecc_code++ = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); 2416a4123e5SDavid Brownell *ecc_code++ = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); 2426a4123e5SDavid Brownell *ecc_code++ = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); 2436a4123e5SDavid Brownell *ecc_code++ = (p[1] >> 18) & 0xff; 2446a4123e5SDavid Brownell } 2456a4123e5SDavid Brownell 2466a4123e5SDavid Brownell return 0; 2476a4123e5SDavid Brownell } 2486a4123e5SDavid Brownell 2496a4123e5SDavid Brownell /* Correct up to 4 bits in data we just read, using state left in the 2506a4123e5SDavid Brownell * hardware plus the ecc_code computed when it was first written. 2516a4123e5SDavid Brownell */ 25200da2ea9SBoris Brezillon static int nand_davinci_correct_4bit(struct nand_chip *chip, u_char *data, 25300da2ea9SBoris Brezillon u_char *ecc_code, u_char *null) 2546a4123e5SDavid Brownell { 2556a4123e5SDavid Brownell int i; 25600da2ea9SBoris Brezillon struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip)); 2576a4123e5SDavid Brownell unsigned short ecc10[8]; 2586a4123e5SDavid Brownell unsigned short *ecc16; 2596a4123e5SDavid Brownell u32 syndrome[4]; 2601c3275b6SSudhakar Rajashekhara u32 ecc_state; 2616a4123e5SDavid Brownell unsigned num_errors, corrected; 2622bdb053aSWolfram Sang unsigned long timeo; 2636a4123e5SDavid Brownell 2646a4123e5SDavid Brownell /* Unpack ten bytes into eight 10 bit values. We know we're 2656a4123e5SDavid Brownell * little-endian, and use type punning for less shifting/masking. 2666a4123e5SDavid Brownell */ 267cc53d5caSBoris Brezillon if (WARN_ON(0x01 & (uintptr_t)ecc_code)) 2686a4123e5SDavid Brownell return -EINVAL; 2696a4123e5SDavid Brownell ecc16 = (unsigned short *)ecc_code; 2706a4123e5SDavid Brownell 2716a4123e5SDavid Brownell ecc10[0] = (ecc16[0] >> 0) & 0x3ff; 2726a4123e5SDavid Brownell ecc10[1] = ((ecc16[0] >> 10) & 0x3f) | ((ecc16[1] << 6) & 0x3c0); 2736a4123e5SDavid Brownell ecc10[2] = (ecc16[1] >> 4) & 0x3ff; 2746a4123e5SDavid Brownell ecc10[3] = ((ecc16[1] >> 14) & 0x3) | ((ecc16[2] << 2) & 0x3fc); 2756a4123e5SDavid Brownell ecc10[4] = (ecc16[2] >> 8) | ((ecc16[3] << 8) & 0x300); 2766a4123e5SDavid Brownell ecc10[5] = (ecc16[3] >> 2) & 0x3ff; 2776a4123e5SDavid Brownell ecc10[6] = ((ecc16[3] >> 12) & 0xf) | ((ecc16[4] << 4) & 0x3f0); 2786a4123e5SDavid Brownell ecc10[7] = (ecc16[4] >> 6) & 0x3ff; 2796a4123e5SDavid Brownell 2806a4123e5SDavid Brownell /* Tell ECC controller about the expected ECC codes. */ 2816a4123e5SDavid Brownell for (i = 7; i >= 0; i--) 2826a4123e5SDavid Brownell davinci_nand_writel(info, NAND_4BIT_ECC_LOAD_OFFSET, ecc10[i]); 2836a4123e5SDavid Brownell 2846a4123e5SDavid Brownell /* Allow time for syndrome calculation ... then read it. 2856a4123e5SDavid Brownell * A syndrome of all zeroes 0 means no detected errors. 2866a4123e5SDavid Brownell */ 2876a4123e5SDavid Brownell davinci_nand_readl(info, NANDFSR_OFFSET); 2886a4123e5SDavid Brownell nand_davinci_readecc_4bit(info, syndrome); 2896a4123e5SDavid Brownell if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3])) 2906a4123e5SDavid Brownell return 0; 2916a4123e5SDavid Brownell 292f12a9473SSneha Narnakaje /* 293f12a9473SSneha Narnakaje * Clear any previous address calculation by doing a dummy read of an 294f12a9473SSneha Narnakaje * error address register. 295f12a9473SSneha Narnakaje */ 296f12a9473SSneha Narnakaje davinci_nand_readl(info, NAND_ERR_ADD1_OFFSET); 297f12a9473SSneha Narnakaje 2986a4123e5SDavid Brownell /* Start address calculation, and wait for it to complete. 2996a4123e5SDavid Brownell * We _could_ start reading more data while this is working, 3006a4123e5SDavid Brownell * to speed up the overall page read. 3016a4123e5SDavid Brownell */ 3026a4123e5SDavid Brownell davinci_nand_writel(info, NANDFCR_OFFSET, 3036a4123e5SDavid Brownell davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13)); 3041c3275b6SSudhakar Rajashekhara 3051c3275b6SSudhakar Rajashekhara /* 3061c3275b6SSudhakar Rajashekhara * ECC_STATE field reads 0x3 (Error correction complete) immediately 3071c3275b6SSudhakar Rajashekhara * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately 3081c3275b6SSudhakar Rajashekhara * begin trying to poll for the state, you may fall right out of your 3091c3275b6SSudhakar Rajashekhara * loop without any of the correction calculations having taken place. 310eea116edSWolfram Sang * The recommendation from the hardware team is to initially delay as 311eea116edSWolfram Sang * long as ECC_STATE reads less than 4. After that, ECC HW has entered 312eea116edSWolfram Sang * correction state. 3131c3275b6SSudhakar Rajashekhara */ 3142bdb053aSWolfram Sang timeo = jiffies + usecs_to_jiffies(100); 3151c3275b6SSudhakar Rajashekhara do { 3161c3275b6SSudhakar Rajashekhara ecc_state = (davinci_nand_readl(info, 3171c3275b6SSudhakar Rajashekhara NANDFSR_OFFSET) >> 8) & 0x0f; 3181c3275b6SSudhakar Rajashekhara cpu_relax(); 3191c3275b6SSudhakar Rajashekhara } while ((ecc_state < 4) && time_before(jiffies, timeo)); 3201c3275b6SSudhakar Rajashekhara 3216a4123e5SDavid Brownell for (;;) { 3226a4123e5SDavid Brownell u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET); 3236a4123e5SDavid Brownell 3246a4123e5SDavid Brownell switch ((fsr >> 8) & 0x0f) { 3256a4123e5SDavid Brownell case 0: /* no error, should not happen */ 326f12a9473SSneha Narnakaje davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET); 3276a4123e5SDavid Brownell return 0; 3286a4123e5SDavid Brownell case 1: /* five or more errors detected */ 329f12a9473SSneha Narnakaje davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET); 3306e941192SBoris BREZILLON return -EBADMSG; 3316a4123e5SDavid Brownell case 2: /* error addresses computed */ 3326a4123e5SDavid Brownell case 3: 3336a4123e5SDavid Brownell num_errors = 1 + ((fsr >> 16) & 0x03); 3346a4123e5SDavid Brownell goto correct; 3356a4123e5SDavid Brownell default: /* still working on it */ 3366a4123e5SDavid Brownell cpu_relax(); 3376a4123e5SDavid Brownell continue; 3386a4123e5SDavid Brownell } 3396a4123e5SDavid Brownell } 3406a4123e5SDavid Brownell 3416a4123e5SDavid Brownell correct: 3426a4123e5SDavid Brownell /* correct each error */ 3436a4123e5SDavid Brownell for (i = 0, corrected = 0; i < num_errors; i++) { 3446a4123e5SDavid Brownell int error_address, error_value; 3456a4123e5SDavid Brownell 3466a4123e5SDavid Brownell if (i > 1) { 3476a4123e5SDavid Brownell error_address = davinci_nand_readl(info, 3486a4123e5SDavid Brownell NAND_ERR_ADD2_OFFSET); 3496a4123e5SDavid Brownell error_value = davinci_nand_readl(info, 3506a4123e5SDavid Brownell NAND_ERR_ERRVAL2_OFFSET); 3516a4123e5SDavid Brownell } else { 3526a4123e5SDavid Brownell error_address = davinci_nand_readl(info, 3536a4123e5SDavid Brownell NAND_ERR_ADD1_OFFSET); 3546a4123e5SDavid Brownell error_value = davinci_nand_readl(info, 3556a4123e5SDavid Brownell NAND_ERR_ERRVAL1_OFFSET); 3566a4123e5SDavid Brownell } 3576a4123e5SDavid Brownell 3586a4123e5SDavid Brownell if (i & 1) { 3596a4123e5SDavid Brownell error_address >>= 16; 3606a4123e5SDavid Brownell error_value >>= 16; 3616a4123e5SDavid Brownell } 3626a4123e5SDavid Brownell error_address &= 0x3ff; 3636a4123e5SDavid Brownell error_address = (512 + 7) - error_address; 3646a4123e5SDavid Brownell 3656a4123e5SDavid Brownell if (error_address < 512) { 3666a4123e5SDavid Brownell data[error_address] ^= error_value; 3676a4123e5SDavid Brownell corrected++; 3686a4123e5SDavid Brownell } 3696a4123e5SDavid Brownell } 3706a4123e5SDavid Brownell 3716a4123e5SDavid Brownell return corrected; 3726a4123e5SDavid Brownell } 3736a4123e5SDavid Brownell 37474e24cd2SMiquel Raynal /** 37574e24cd2SMiquel Raynal * nand_read_page_hwecc_oob_first - hw ecc, read oob first 37674e24cd2SMiquel Raynal * @chip: nand chip info structure 37774e24cd2SMiquel Raynal * @buf: buffer to store read data 37874e24cd2SMiquel Raynal * @oob_required: caller requires OOB data read to chip->oob_poi 37974e24cd2SMiquel Raynal * @page: page number to read 38074e24cd2SMiquel Raynal * 38174e24cd2SMiquel Raynal * Hardware ECC for large page chips, require OOB to be read first. For this 38274e24cd2SMiquel Raynal * ECC mode, the write_page method is re-used from ECC_HW. These methods 38374e24cd2SMiquel Raynal * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with 38474e24cd2SMiquel Raynal * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from 38574e24cd2SMiquel Raynal * the data area, by overwriting the NAND manufacturer bad block markings. 38674e24cd2SMiquel Raynal */ 38774e24cd2SMiquel Raynal static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip, 38874e24cd2SMiquel Raynal uint8_t *buf, 38974e24cd2SMiquel Raynal int oob_required, int page) 39074e24cd2SMiquel Raynal { 39174e24cd2SMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip); 39274e24cd2SMiquel Raynal int i, eccsize = chip->ecc.size, ret; 39374e24cd2SMiquel Raynal int eccbytes = chip->ecc.bytes; 39474e24cd2SMiquel Raynal int eccsteps = chip->ecc.steps; 39574e24cd2SMiquel Raynal uint8_t *p = buf; 39674e24cd2SMiquel Raynal uint8_t *ecc_code = chip->ecc.code_buf; 39774e24cd2SMiquel Raynal uint8_t *ecc_calc = chip->ecc.calc_buf; 39874e24cd2SMiquel Raynal unsigned int max_bitflips = 0; 39974e24cd2SMiquel Raynal 40074e24cd2SMiquel Raynal /* Read the OOB area first */ 40174e24cd2SMiquel Raynal ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); 40274e24cd2SMiquel Raynal if (ret) 40374e24cd2SMiquel Raynal return ret; 40474e24cd2SMiquel Raynal 40574e24cd2SMiquel Raynal ret = nand_read_page_op(chip, page, 0, NULL, 0); 40674e24cd2SMiquel Raynal if (ret) 40774e24cd2SMiquel Raynal return ret; 40874e24cd2SMiquel Raynal 40974e24cd2SMiquel Raynal ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, 41074e24cd2SMiquel Raynal chip->ecc.total); 41174e24cd2SMiquel Raynal if (ret) 41274e24cd2SMiquel Raynal return ret; 41374e24cd2SMiquel Raynal 41474e24cd2SMiquel Raynal for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 41574e24cd2SMiquel Raynal int stat; 41674e24cd2SMiquel Raynal 41774e24cd2SMiquel Raynal chip->ecc.hwctl(chip, NAND_ECC_READ); 41874e24cd2SMiquel Raynal 41974e24cd2SMiquel Raynal ret = nand_read_data_op(chip, p, eccsize, false, false); 42074e24cd2SMiquel Raynal if (ret) 42174e24cd2SMiquel Raynal return ret; 42274e24cd2SMiquel Raynal 42374e24cd2SMiquel Raynal chip->ecc.calculate(chip, p, &ecc_calc[i]); 42474e24cd2SMiquel Raynal 42574e24cd2SMiquel Raynal stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); 42674e24cd2SMiquel Raynal if (stat == -EBADMSG && 42774e24cd2SMiquel Raynal (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { 42874e24cd2SMiquel Raynal /* check for empty pages with bitflips */ 42974e24cd2SMiquel Raynal stat = nand_check_erased_ecc_chunk(p, eccsize, 43074e24cd2SMiquel Raynal &ecc_code[i], 43174e24cd2SMiquel Raynal eccbytes, NULL, 0, 43274e24cd2SMiquel Raynal chip->ecc.strength); 43374e24cd2SMiquel Raynal } 43474e24cd2SMiquel Raynal 43574e24cd2SMiquel Raynal if (stat < 0) { 43674e24cd2SMiquel Raynal mtd->ecc_stats.failed++; 43774e24cd2SMiquel Raynal } else { 43874e24cd2SMiquel Raynal mtd->ecc_stats.corrected += stat; 43974e24cd2SMiquel Raynal max_bitflips = max_t(unsigned int, max_bitflips, stat); 44074e24cd2SMiquel Raynal } 44174e24cd2SMiquel Raynal } 44274e24cd2SMiquel Raynal return max_bitflips; 44374e24cd2SMiquel Raynal } 44474e24cd2SMiquel Raynal 4456a4123e5SDavid Brownell /*----------------------------------------------------------------------*/ 4466a4123e5SDavid Brownell 4476a4123e5SDavid Brownell /* An ECC layout for using 4-bit ECC with small-page flash, storing 4486a4123e5SDavid Brownell * ten ECC bytes plus the manufacturer's bad block marker byte, and 4496a4123e5SDavid Brownell * and not overlapping the default BBT markers. 4506a4123e5SDavid Brownell */ 451e4aacaa1SBoris Brezillon static int hwecc4_ooblayout_small_ecc(struct mtd_info *mtd, int section, 452e4aacaa1SBoris Brezillon struct mtd_oob_region *oobregion) 453e4aacaa1SBoris Brezillon { 454e4aacaa1SBoris Brezillon if (section > 2) 455e4aacaa1SBoris Brezillon return -ERANGE; 4566a4123e5SDavid Brownell 457e4aacaa1SBoris Brezillon if (!section) { 458e4aacaa1SBoris Brezillon oobregion->offset = 0; 459e4aacaa1SBoris Brezillon oobregion->length = 5; 460e4aacaa1SBoris Brezillon } else if (section == 1) { 461e4aacaa1SBoris Brezillon oobregion->offset = 6; 462e4aacaa1SBoris Brezillon oobregion->length = 2; 463e4aacaa1SBoris Brezillon } else { 464e4aacaa1SBoris Brezillon oobregion->offset = 13; 465e4aacaa1SBoris Brezillon oobregion->length = 3; 466e4aacaa1SBoris Brezillon } 4676a4123e5SDavid Brownell 468e4aacaa1SBoris Brezillon return 0; 469e4aacaa1SBoris Brezillon } 470e4aacaa1SBoris Brezillon 471e4aacaa1SBoris Brezillon static int hwecc4_ooblayout_small_free(struct mtd_info *mtd, int section, 472e4aacaa1SBoris Brezillon struct mtd_oob_region *oobregion) 473e4aacaa1SBoris Brezillon { 474e4aacaa1SBoris Brezillon if (section > 1) 475e4aacaa1SBoris Brezillon return -ERANGE; 476e4aacaa1SBoris Brezillon 477e4aacaa1SBoris Brezillon if (!section) { 478e4aacaa1SBoris Brezillon oobregion->offset = 8; 479e4aacaa1SBoris Brezillon oobregion->length = 5; 480e4aacaa1SBoris Brezillon } else { 481e4aacaa1SBoris Brezillon oobregion->offset = 16; 482e4aacaa1SBoris Brezillon oobregion->length = mtd->oobsize - 16; 483e4aacaa1SBoris Brezillon } 484e4aacaa1SBoris Brezillon 485e4aacaa1SBoris Brezillon return 0; 486e4aacaa1SBoris Brezillon } 487e4aacaa1SBoris Brezillon 488e4aacaa1SBoris Brezillon static const struct mtd_ooblayout_ops hwecc4_small_ooblayout_ops = { 489e4aacaa1SBoris Brezillon .ecc = hwecc4_ooblayout_small_ecc, 490e4aacaa1SBoris Brezillon .free = hwecc4_ooblayout_small_free, 491a11244c0SSandeep Paulraj }; 492a11244c0SSandeep Paulraj 493cdeadd71SHeiko Schocher #if defined(CONFIG_OF) 494cdeadd71SHeiko Schocher static const struct of_device_id davinci_nand_of_match[] = { 495cdeadd71SHeiko Schocher {.compatible = "ti,davinci-nand", }, 49628c015a9SMurali Karicheri {.compatible = "ti,keystone-nand", }, 497cdeadd71SHeiko Schocher {}, 49813daa22fSSergei Shtylyov }; 499cdeadd71SHeiko Schocher MODULE_DEVICE_TABLE(of, davinci_nand_of_match); 500cdeadd71SHeiko Schocher 501cdeadd71SHeiko Schocher static struct davinci_nand_pdata 502cdeadd71SHeiko Schocher *nand_davinci_get_pdata(struct platform_device *pdev) 503cdeadd71SHeiko Schocher { 504453810b7SJingoo Han if (!dev_get_platdata(&pdev->dev) && pdev->dev.of_node) { 505cdeadd71SHeiko Schocher struct davinci_nand_pdata *pdata; 506cdeadd71SHeiko Schocher const char *mode; 507cdeadd71SHeiko Schocher u32 prop; 508cdeadd71SHeiko Schocher 509cdeadd71SHeiko Schocher pdata = devm_kzalloc(&pdev->dev, 510cdeadd71SHeiko Schocher sizeof(struct davinci_nand_pdata), 511cdeadd71SHeiko Schocher GFP_KERNEL); 512cdeadd71SHeiko Schocher pdev->dev.platform_data = pdata; 513cdeadd71SHeiko Schocher if (!pdata) 514f735a4d0SIvan Khoronzhuk return ERR_PTR(-ENOMEM); 515cdeadd71SHeiko Schocher if (!of_property_read_u32(pdev->dev.of_node, 516cdeadd71SHeiko Schocher "ti,davinci-chipselect", &prop)) 517fd065806SBartosz Golaszewski pdata->core_chipsel = prop; 51805103825SIvan Khoronzhuk else 51905103825SIvan Khoronzhuk return ERR_PTR(-EINVAL); 52005103825SIvan Khoronzhuk 521cdeadd71SHeiko Schocher if (!of_property_read_u32(pdev->dev.of_node, 522cdeadd71SHeiko Schocher "ti,davinci-mask-ale", &prop)) 523cdeadd71SHeiko Schocher pdata->mask_ale = prop; 524cdeadd71SHeiko Schocher if (!of_property_read_u32(pdev->dev.of_node, 525cdeadd71SHeiko Schocher "ti,davinci-mask-cle", &prop)) 526cdeadd71SHeiko Schocher pdata->mask_cle = prop; 527cdeadd71SHeiko Schocher if (!of_property_read_u32(pdev->dev.of_node, 528cdeadd71SHeiko Schocher "ti,davinci-mask-chipsel", &prop)) 529cdeadd71SHeiko Schocher pdata->mask_chipsel = prop; 530cdeadd71SHeiko Schocher if (!of_property_read_string(pdev->dev.of_node, 531cdeadd71SHeiko Schocher "ti,davinci-ecc-mode", &mode)) { 532cdeadd71SHeiko Schocher if (!strncmp("none", mode, 4)) 533bace41f8SMiquel Raynal pdata->engine_type = NAND_ECC_ENGINE_TYPE_NONE; 534cdeadd71SHeiko Schocher if (!strncmp("soft", mode, 4)) 535bace41f8SMiquel Raynal pdata->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; 536cdeadd71SHeiko Schocher if (!strncmp("hw", mode, 2)) 537bace41f8SMiquel Raynal pdata->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; 538cdeadd71SHeiko Schocher } 539cdeadd71SHeiko Schocher if (!of_property_read_u32(pdev->dev.of_node, 540cdeadd71SHeiko Schocher "ti,davinci-ecc-bits", &prop)) 541cdeadd71SHeiko Schocher pdata->ecc_bits = prop; 54275be1ea2SIvan Khoronzhuk 543363b5db2SBoris Brezillon if (!of_property_read_u32(pdev->dev.of_node, 544363b5db2SBoris Brezillon "ti,davinci-nand-buswidth", &prop) && prop == 16) 545cdeadd71SHeiko Schocher pdata->options |= NAND_BUSWIDTH_16; 546363b5db2SBoris Brezillon 54775be1ea2SIvan Khoronzhuk if (of_property_read_bool(pdev->dev.of_node, 54875be1ea2SIvan Khoronzhuk "ti,davinci-nand-use-bbt")) 549cdeadd71SHeiko Schocher pdata->bbt_options = NAND_BBT_USE_FLASH; 55028c015a9SMurali Karicheri 55165a2c1caSSekhar Nori /* 55265a2c1caSSekhar Nori * Since kernel v4.8, this driver has been fixed to enable 55365a2c1caSSekhar Nori * use of 4-bit hardware ECC with subpages and verified on 55465a2c1caSSekhar Nori * TI's keystone EVMs (K2L, K2HK and K2E). 55565a2c1caSSekhar Nori * However, in the interest of not breaking systems using 55665a2c1caSSekhar Nori * existing UBI partitions, sub-page writes are not being 55765a2c1caSSekhar Nori * (re)enabled. If you want to use subpage writes on Keystone 55865a2c1caSSekhar Nori * platforms (i.e. do not have any existing UBI partitions), 55965a2c1caSSekhar Nori * then use "ti,davinci-nand" as the compatible in your 56065a2c1caSSekhar Nori * device-tree file. 56165a2c1caSSekhar Nori */ 56228c015a9SMurali Karicheri if (of_device_is_compatible(pdev->dev.of_node, 56328c015a9SMurali Karicheri "ti,keystone-nand")) { 56428c015a9SMurali Karicheri pdata->options |= NAND_NO_SUBPAGE_WRITE; 56528c015a9SMurali Karicheri } 566cdeadd71SHeiko Schocher } 567cdeadd71SHeiko Schocher 568453810b7SJingoo Han return dev_get_platdata(&pdev->dev); 569cdeadd71SHeiko Schocher } 570cdeadd71SHeiko Schocher #else 571cdeadd71SHeiko Schocher static struct davinci_nand_pdata 572cdeadd71SHeiko Schocher *nand_davinci_get_pdata(struct platform_device *pdev) 573cdeadd71SHeiko Schocher { 574453810b7SJingoo Han return dev_get_platdata(&pdev->dev); 575cdeadd71SHeiko Schocher } 576cdeadd71SHeiko Schocher #endif 577cdeadd71SHeiko Schocher 578b2342c1cSMiquel Raynal static int davinci_nand_attach_chip(struct nand_chip *chip) 579b2342c1cSMiquel Raynal { 580b2342c1cSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip); 581b2342c1cSMiquel Raynal struct davinci_nand_info *info = to_davinci_nand(mtd); 582b2342c1cSMiquel Raynal struct davinci_nand_pdata *pdata = nand_davinci_get_pdata(info->pdev); 583b2342c1cSMiquel Raynal int ret = 0; 584b2342c1cSMiquel Raynal 585b2342c1cSMiquel Raynal if (IS_ERR(pdata)) 586b2342c1cSMiquel Raynal return PTR_ERR(pdata); 587b2342c1cSMiquel Raynal 5883500bd70SMiquel Raynal /* Use board-specific ECC config */ 589*b75e17b0SMiquel Raynal chip->ecc.engine_type = pdata->engine_type; 590*b75e17b0SMiquel Raynal chip->ecc.placement = pdata->ecc_placement; 5913500bd70SMiquel Raynal 592*b75e17b0SMiquel Raynal switch (chip->ecc.engine_type) { 593bace41f8SMiquel Raynal case NAND_ECC_ENGINE_TYPE_NONE: 594b2342c1cSMiquel Raynal pdata->ecc_bits = 0; 595b2342c1cSMiquel Raynal break; 596bace41f8SMiquel Raynal case NAND_ECC_ENGINE_TYPE_SOFT: 597b2342c1cSMiquel Raynal pdata->ecc_bits = 0; 598b2342c1cSMiquel Raynal /* 599bace41f8SMiquel Raynal * This driver expects Hamming based ECC when engine_type is set 600bace41f8SMiquel Raynal * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to 601bace41f8SMiquel Raynal * NAND_ECC_ALGO_HAMMING to avoid adding an extra ->ecc_algo 602bace41f8SMiquel Raynal * field to davinci_nand_pdata. 603b2342c1cSMiquel Raynal */ 604*b75e17b0SMiquel Raynal chip->ecc.algo = NAND_ECC_ALGO_HAMMING; 605b2342c1cSMiquel Raynal break; 606bace41f8SMiquel Raynal case NAND_ECC_ENGINE_TYPE_ON_HOST: 607b2342c1cSMiquel Raynal if (pdata->ecc_bits == 4) { 60874e24cd2SMiquel Raynal int chunks = mtd->writesize / 512; 60974e24cd2SMiquel Raynal 61074e24cd2SMiquel Raynal if (!chunks || mtd->oobsize < 16) { 61174e24cd2SMiquel Raynal dev_dbg(&info->pdev->dev, "too small\n"); 61274e24cd2SMiquel Raynal return -EINVAL; 61374e24cd2SMiquel Raynal } 61474e24cd2SMiquel Raynal 615b2342c1cSMiquel Raynal /* 616b2342c1cSMiquel Raynal * No sanity checks: CPUs must support this, 617b2342c1cSMiquel Raynal * and the chips may not use NAND_BUSWIDTH_16. 618b2342c1cSMiquel Raynal */ 619b2342c1cSMiquel Raynal 620b2342c1cSMiquel Raynal /* No sharing 4-bit hardware between chipselects yet */ 621b2342c1cSMiquel Raynal spin_lock_irq(&davinci_nand_lock); 622b2342c1cSMiquel Raynal if (ecc4_busy) 623b2342c1cSMiquel Raynal ret = -EBUSY; 624b2342c1cSMiquel Raynal else 625b2342c1cSMiquel Raynal ecc4_busy = true; 626b2342c1cSMiquel Raynal spin_unlock_irq(&davinci_nand_lock); 627b2342c1cSMiquel Raynal 628b2342c1cSMiquel Raynal if (ret == -EBUSY) 629b2342c1cSMiquel Raynal return ret; 630b2342c1cSMiquel Raynal 631*b75e17b0SMiquel Raynal chip->ecc.calculate = nand_davinci_calculate_4bit; 632*b75e17b0SMiquel Raynal chip->ecc.correct = nand_davinci_correct_4bit; 633*b75e17b0SMiquel Raynal chip->ecc.hwctl = nand_davinci_hwctl_4bit; 634*b75e17b0SMiquel Raynal chip->ecc.bytes = 10; 635*b75e17b0SMiquel Raynal chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; 636*b75e17b0SMiquel Raynal chip->ecc.algo = NAND_ECC_ALGO_BCH; 63774e24cd2SMiquel Raynal 63874e24cd2SMiquel Raynal /* 63974e24cd2SMiquel Raynal * Update ECC layout if needed ... for 1-bit HW ECC, the 64074e24cd2SMiquel Raynal * default is OK, but it allocates 6 bytes when only 3 64174e24cd2SMiquel Raynal * are needed (for each 512 bytes). For 4-bit HW ECC, 64274e24cd2SMiquel Raynal * the default is not usable: 10 bytes needed, not 6. 64374e24cd2SMiquel Raynal * 64474e24cd2SMiquel Raynal * For small page chips, preserve the manufacturer's 64574e24cd2SMiquel Raynal * badblock marking data ... and make sure a flash BBT 64674e24cd2SMiquel Raynal * table marker fits in the free bytes. 64774e24cd2SMiquel Raynal */ 64874e24cd2SMiquel Raynal if (chunks == 1) { 64974e24cd2SMiquel Raynal mtd_set_ooblayout(mtd, 65074e24cd2SMiquel Raynal &hwecc4_small_ooblayout_ops); 65174e24cd2SMiquel Raynal } else if (chunks == 4 || chunks == 8) { 6521e3b37aaSMiquel Raynal mtd_set_ooblayout(mtd, 6531e3b37aaSMiquel Raynal nand_get_large_page_ooblayout()); 654*b75e17b0SMiquel Raynal chip->ecc.read_page = nand_davinci_read_page_hwecc_oob_first; 65574e24cd2SMiquel Raynal } else { 65674e24cd2SMiquel Raynal return -EIO; 65774e24cd2SMiquel Raynal } 658b2342c1cSMiquel Raynal } else { 659b2342c1cSMiquel Raynal /* 1bit ecc hamming */ 660*b75e17b0SMiquel Raynal chip->ecc.calculate = nand_davinci_calculate_1bit; 661*b75e17b0SMiquel Raynal chip->ecc.correct = nand_davinci_correct_1bit; 662*b75e17b0SMiquel Raynal chip->ecc.hwctl = nand_davinci_hwctl_1bit; 663*b75e17b0SMiquel Raynal chip->ecc.bytes = 3; 664*b75e17b0SMiquel Raynal chip->ecc.algo = NAND_ECC_ALGO_HAMMING; 665b2342c1cSMiquel Raynal } 666*b75e17b0SMiquel Raynal chip->ecc.size = 512; 667*b75e17b0SMiquel Raynal chip->ecc.strength = pdata->ecc_bits; 668b2342c1cSMiquel Raynal break; 669b2342c1cSMiquel Raynal default: 670b2342c1cSMiquel Raynal return -EINVAL; 671b2342c1cSMiquel Raynal } 672b2342c1cSMiquel Raynal 673b2342c1cSMiquel Raynal return ret; 674b2342c1cSMiquel Raynal } 675b2342c1cSMiquel Raynal 676547aa7c2SBoris Brezillon static void nand_davinci_data_in(struct davinci_nand_info *info, void *buf, 677547aa7c2SBoris Brezillon unsigned int len, bool force_8bit) 678547aa7c2SBoris Brezillon { 679547aa7c2SBoris Brezillon u32 alignment = ((uintptr_t)buf | len) & 3; 680547aa7c2SBoris Brezillon 681547aa7c2SBoris Brezillon if (force_8bit || (alignment & 1)) 682547aa7c2SBoris Brezillon ioread8_rep(info->current_cs, buf, len); 683547aa7c2SBoris Brezillon else if (alignment & 3) 684547aa7c2SBoris Brezillon ioread16_rep(info->current_cs, buf, len >> 1); 685547aa7c2SBoris Brezillon else 686547aa7c2SBoris Brezillon ioread32_rep(info->current_cs, buf, len >> 2); 687547aa7c2SBoris Brezillon } 688547aa7c2SBoris Brezillon 689547aa7c2SBoris Brezillon static void nand_davinci_data_out(struct davinci_nand_info *info, 690547aa7c2SBoris Brezillon const void *buf, unsigned int len, 691547aa7c2SBoris Brezillon bool force_8bit) 692547aa7c2SBoris Brezillon { 693547aa7c2SBoris Brezillon u32 alignment = ((uintptr_t)buf | len) & 3; 694547aa7c2SBoris Brezillon 695547aa7c2SBoris Brezillon if (force_8bit || (alignment & 1)) 696547aa7c2SBoris Brezillon iowrite8_rep(info->current_cs, buf, len); 697547aa7c2SBoris Brezillon else if (alignment & 3) 698547aa7c2SBoris Brezillon iowrite16_rep(info->current_cs, buf, len >> 1); 699547aa7c2SBoris Brezillon else 700547aa7c2SBoris Brezillon iowrite32_rep(info->current_cs, buf, len >> 2); 701547aa7c2SBoris Brezillon } 702547aa7c2SBoris Brezillon 703547aa7c2SBoris Brezillon static int davinci_nand_exec_instr(struct davinci_nand_info *info, 704547aa7c2SBoris Brezillon const struct nand_op_instr *instr) 705547aa7c2SBoris Brezillon { 706547aa7c2SBoris Brezillon unsigned int i, timeout_us; 707547aa7c2SBoris Brezillon u32 status; 708547aa7c2SBoris Brezillon int ret; 709547aa7c2SBoris Brezillon 710547aa7c2SBoris Brezillon switch (instr->type) { 711547aa7c2SBoris Brezillon case NAND_OP_CMD_INSTR: 712547aa7c2SBoris Brezillon iowrite8(instr->ctx.cmd.opcode, 713547aa7c2SBoris Brezillon info->current_cs + info->mask_cle); 714547aa7c2SBoris Brezillon break; 715547aa7c2SBoris Brezillon 716547aa7c2SBoris Brezillon case NAND_OP_ADDR_INSTR: 717547aa7c2SBoris Brezillon for (i = 0; i < instr->ctx.addr.naddrs; i++) { 718547aa7c2SBoris Brezillon iowrite8(instr->ctx.addr.addrs[i], 719547aa7c2SBoris Brezillon info->current_cs + info->mask_ale); 720547aa7c2SBoris Brezillon } 721547aa7c2SBoris Brezillon break; 722547aa7c2SBoris Brezillon 723547aa7c2SBoris Brezillon case NAND_OP_DATA_IN_INSTR: 724547aa7c2SBoris Brezillon nand_davinci_data_in(info, instr->ctx.data.buf.in, 725547aa7c2SBoris Brezillon instr->ctx.data.len, 726547aa7c2SBoris Brezillon instr->ctx.data.force_8bit); 727547aa7c2SBoris Brezillon break; 728547aa7c2SBoris Brezillon 729547aa7c2SBoris Brezillon case NAND_OP_DATA_OUT_INSTR: 730547aa7c2SBoris Brezillon nand_davinci_data_out(info, instr->ctx.data.buf.out, 731547aa7c2SBoris Brezillon instr->ctx.data.len, 732547aa7c2SBoris Brezillon instr->ctx.data.force_8bit); 733547aa7c2SBoris Brezillon break; 734547aa7c2SBoris Brezillon 735547aa7c2SBoris Brezillon case NAND_OP_WAITRDY_INSTR: 736547aa7c2SBoris Brezillon timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; 737547aa7c2SBoris Brezillon ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET, 738547aa7c2SBoris Brezillon status, status & BIT(0), 100, 739547aa7c2SBoris Brezillon timeout_us); 740547aa7c2SBoris Brezillon if (ret) 741547aa7c2SBoris Brezillon return ret; 742547aa7c2SBoris Brezillon 743547aa7c2SBoris Brezillon break; 744547aa7c2SBoris Brezillon } 745547aa7c2SBoris Brezillon 746547aa7c2SBoris Brezillon if (instr->delay_ns) 747547aa7c2SBoris Brezillon ndelay(instr->delay_ns); 748547aa7c2SBoris Brezillon 749547aa7c2SBoris Brezillon return 0; 750547aa7c2SBoris Brezillon } 751547aa7c2SBoris Brezillon 752547aa7c2SBoris Brezillon static int davinci_nand_exec_op(struct nand_chip *chip, 753547aa7c2SBoris Brezillon const struct nand_operation *op, 754547aa7c2SBoris Brezillon bool check_only) 755547aa7c2SBoris Brezillon { 756547aa7c2SBoris Brezillon struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip)); 757547aa7c2SBoris Brezillon unsigned int i; 758547aa7c2SBoris Brezillon 759547aa7c2SBoris Brezillon if (check_only) 760547aa7c2SBoris Brezillon return 0; 761547aa7c2SBoris Brezillon 762547aa7c2SBoris Brezillon info->current_cs = info->vaddr + (op->cs * info->mask_chipsel); 763547aa7c2SBoris Brezillon 764547aa7c2SBoris Brezillon for (i = 0; i < op->ninstrs; i++) { 765547aa7c2SBoris Brezillon int ret; 766547aa7c2SBoris Brezillon 767547aa7c2SBoris Brezillon ret = davinci_nand_exec_instr(info, &op->instrs[i]); 768547aa7c2SBoris Brezillon if (ret) 769547aa7c2SBoris Brezillon return ret; 770547aa7c2SBoris Brezillon } 771547aa7c2SBoris Brezillon 772547aa7c2SBoris Brezillon return 0; 773547aa7c2SBoris Brezillon } 774547aa7c2SBoris Brezillon 775b2342c1cSMiquel Raynal static const struct nand_controller_ops davinci_nand_controller_ops = { 776b2342c1cSMiquel Raynal .attach_chip = davinci_nand_attach_chip, 777547aa7c2SBoris Brezillon .exec_op = davinci_nand_exec_op, 778b2342c1cSMiquel Raynal }; 779b2342c1cSMiquel Raynal 780eaaa4a9aSIvan Khoronzhuk static int nand_davinci_probe(struct platform_device *pdev) 781ff4569c7SDavid Brownell { 782cdeadd71SHeiko Schocher struct davinci_nand_pdata *pdata; 783ff4569c7SDavid Brownell struct davinci_nand_info *info; 784ff4569c7SDavid Brownell struct resource *res1; 785ff4569c7SDavid Brownell struct resource *res2; 786ff4569c7SDavid Brownell void __iomem *vaddr; 787ff4569c7SDavid Brownell void __iomem *base; 788ff4569c7SDavid Brownell int ret; 789ff4569c7SDavid Brownell uint32_t val; 790a5cfb4dbSBoris BREZILLON struct mtd_info *mtd; 791ff4569c7SDavid Brownell 792cdeadd71SHeiko Schocher pdata = nand_davinci_get_pdata(pdev); 793f735a4d0SIvan Khoronzhuk if (IS_ERR(pdata)) 794f735a4d0SIvan Khoronzhuk return PTR_ERR(pdata); 795f735a4d0SIvan Khoronzhuk 796533a0149SDavid Brownell /* insist on board-specific configuration */ 797533a0149SDavid Brownell if (!pdata) 798533a0149SDavid Brownell return -ENODEV; 799533a0149SDavid Brownell 800ff4569c7SDavid Brownell /* which external chipselect will we be managing? */ 801fd065806SBartosz Golaszewski if (pdata->core_chipsel < 0 || pdata->core_chipsel > 3) 802ff4569c7SDavid Brownell return -ENODEV; 803ff4569c7SDavid Brownell 804ef4e0c21SMrugesh Katepallewar info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 80500669231SJingoo Han if (!info) 80630a3970cSIvan Khoronzhuk return -ENOMEM; 807ff4569c7SDavid Brownell 808ff4569c7SDavid Brownell platform_set_drvdata(pdev, info); 809ff4569c7SDavid Brownell 810ff4569c7SDavid Brownell res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 811ff4569c7SDavid Brownell res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 812ff4569c7SDavid Brownell if (!res1 || !res2) { 813ff4569c7SDavid Brownell dev_err(&pdev->dev, "resource missing\n"); 81430a3970cSIvan Khoronzhuk return -EINVAL; 815ff4569c7SDavid Brownell } 816ff4569c7SDavid Brownell 81759bff7fbSLaurent Navet vaddr = devm_ioremap_resource(&pdev->dev, res1); 81830a3970cSIvan Khoronzhuk if (IS_ERR(vaddr)) 81930a3970cSIvan Khoronzhuk return PTR_ERR(vaddr); 82030a3970cSIvan Khoronzhuk 8210966a416SIvan Khoronzhuk /* 8220966a416SIvan Khoronzhuk * This registers range is used to setup NAND settings. In case with 8230966a416SIvan Khoronzhuk * TI AEMIF driver, the same memory address range is requested already 8240966a416SIvan Khoronzhuk * by AEMIF, so we cannot request it twice, just ioremap. 8250966a416SIvan Khoronzhuk * The AEMIF and NAND drivers not use the same registers in this range. 8260966a416SIvan Khoronzhuk */ 8270966a416SIvan Khoronzhuk base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); 8280966a416SIvan Khoronzhuk if (!base) { 8290966a416SIvan Khoronzhuk dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); 8300966a416SIvan Khoronzhuk return -EADDRNOTAVAIL; 8310966a416SIvan Khoronzhuk } 832ff4569c7SDavid Brownell 833b2342c1cSMiquel Raynal info->pdev = pdev; 834ff4569c7SDavid Brownell info->base = base; 835ff4569c7SDavid Brownell info->vaddr = vaddr; 836ff4569c7SDavid Brownell 837a5cfb4dbSBoris BREZILLON mtd = nand_to_mtd(&info->chip); 838a5cfb4dbSBoris BREZILLON mtd->dev.parent = &pdev->dev; 839a61ae81aSBrian Norris nand_set_flash_node(&info->chip, pdev->dev.of_node); 84087f39f04SDavid Brownell 841bb9ebd4eSBrian Norris /* options such as NAND_BBT_USE_FLASH */ 842a40f7341SBrian Norris info->chip.bbt_options = pdata->bbt_options; 843a40f7341SBrian Norris /* options such as 16-bit widths */ 844533a0149SDavid Brownell info->chip.options = pdata->options; 845f611a79fSMark A. Greer info->chip.bbt_td = pdata->bbt_td; 846f611a79fSMark A. Greer info->chip.bbt_md = pdata->bbt_md; 847a88dbc5bSSekhar Nori info->timing = pdata->timing; 848ff4569c7SDavid Brownell 849c5b76d8dSBoris Brezillon info->current_cs = info->vaddr; 850fd065806SBartosz Golaszewski info->core_chipsel = pdata->core_chipsel; 851ff4569c7SDavid Brownell info->mask_chipsel = pdata->mask_chipsel; 852ff4569c7SDavid Brownell 853ff4569c7SDavid Brownell /* use nandboot-capable ALE/CLE masks by default */ 8545cd0be8eSHemant Pedanekar info->mask_ale = pdata->mask_ale ? : MASK_ALE; 855533a0149SDavid Brownell info->mask_cle = pdata->mask_cle ? : MASK_CLE; 856ff4569c7SDavid Brownell 857363b5db2SBoris Brezillon spin_lock_irq(&davinci_nand_lock); 858363b5db2SBoris Brezillon 859363b5db2SBoris Brezillon /* put CSxNAND into NAND mode */ 860363b5db2SBoris Brezillon val = davinci_nand_readl(info, NANDFCR_OFFSET); 861363b5db2SBoris Brezillon val |= BIT(info->core_chipsel); 862363b5db2SBoris Brezillon davinci_nand_writel(info, NANDFCR_OFFSET, val); 863363b5db2SBoris Brezillon 864363b5db2SBoris Brezillon spin_unlock_irq(&davinci_nand_lock); 865363b5db2SBoris Brezillon 866363b5db2SBoris Brezillon /* Scan to find existence of the device(s) */ 8673626fdcfSBoris Brezillon nand_controller_init(&info->controller); 8683626fdcfSBoris Brezillon info->controller.ops = &davinci_nand_controller_ops; 8693626fdcfSBoris Brezillon info->chip.controller = &info->controller; 87000ad378fSBoris Brezillon ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1); 871363b5db2SBoris Brezillon if (ret < 0) { 872363b5db2SBoris Brezillon dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); 873a8e3923aSSekhar Nori return ret; 874363b5db2SBoris Brezillon } 875363b5db2SBoris Brezillon 876192afdbfSMurali Karicheri if (pdata->parts) 87729597ca1SRafał Miłecki ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); 878a61ae81aSBrian Norris else 879a5cfb4dbSBoris BREZILLON ret = mtd_device_register(mtd, NULL, 0); 880ff4569c7SDavid Brownell if (ret < 0) 8814acc3046SMiquel Raynal goto err_cleanup_nand; 882ff4569c7SDavid Brownell 883ff4569c7SDavid Brownell val = davinci_nand_readl(info, NRCSR_OFFSET); 884ff4569c7SDavid Brownell dev_info(&pdev->dev, "controller rev. %d.%d\n", 885ff4569c7SDavid Brownell (val >> 8) & 0xff, val & 0xff); 886ff4569c7SDavid Brownell 887ff4569c7SDavid Brownell return 0; 888ff4569c7SDavid Brownell 8894acc3046SMiquel Raynal err_cleanup_nand: 8904acc3046SMiquel Raynal nand_cleanup(&info->chip); 8914acc3046SMiquel Raynal 892ff4569c7SDavid Brownell return ret; 893ff4569c7SDavid Brownell } 894ff4569c7SDavid Brownell 895eaaa4a9aSIvan Khoronzhuk static int nand_davinci_remove(struct platform_device *pdev) 896ff4569c7SDavid Brownell { 897ff4569c7SDavid Brownell struct davinci_nand_info *info = platform_get_drvdata(pdev); 898a9575c48SMiquel Raynal struct nand_chip *chip = &info->chip; 899a9575c48SMiquel Raynal int ret; 900ff4569c7SDavid Brownell 9016a4123e5SDavid Brownell spin_lock_irq(&davinci_nand_lock); 902*b75e17b0SMiquel Raynal if (chip->ecc.placement == NAND_ECC_PLACEMENT_INTERLEAVED) 9036a4123e5SDavid Brownell ecc4_busy = false; 9046a4123e5SDavid Brownell spin_unlock_irq(&davinci_nand_lock); 9056a4123e5SDavid Brownell 906a9575c48SMiquel Raynal ret = mtd_device_unregister(nand_to_mtd(chip)); 907a9575c48SMiquel Raynal WARN_ON(ret); 908a9575c48SMiquel Raynal nand_cleanup(chip); 909ff4569c7SDavid Brownell 910ff4569c7SDavid Brownell return 0; 911ff4569c7SDavid Brownell } 912ff4569c7SDavid Brownell 913ff4569c7SDavid Brownell static struct platform_driver nand_davinci_driver = { 914eaaa4a9aSIvan Khoronzhuk .probe = nand_davinci_probe, 915eaaa4a9aSIvan Khoronzhuk .remove = nand_davinci_remove, 916ff4569c7SDavid Brownell .driver = { 917ff4569c7SDavid Brownell .name = "davinci_nand", 918c4f8cde8SSachin Kamat .of_match_table = of_match_ptr(davinci_nand_of_match), 919ff4569c7SDavid Brownell }, 920ff4569c7SDavid Brownell }; 921ff4569c7SDavid Brownell MODULE_ALIAS("platform:davinci_nand"); 922ff4569c7SDavid Brownell 923eaaa4a9aSIvan Khoronzhuk module_platform_driver(nand_davinci_driver); 924ff4569c7SDavid Brownell 925ff4569c7SDavid Brownell MODULE_LICENSE("GPL"); 926ff4569c7SDavid Brownell MODULE_AUTHOR("Texas Instruments"); 927ff4569c7SDavid Brownell MODULE_DESCRIPTION("Davinci NAND flash driver"); 928ff4569c7SDavid Brownell 929