1b74e6985SXiaolei Li // SPDX-License-Identifier: GPL-2.0 OR MIT 293db446aSBoris Brezillon /* 393db446aSBoris Brezillon * MTK NAND Flash controller driver. 493db446aSBoris Brezillon * Copyright (C) 2016 MediaTek Inc. 593db446aSBoris Brezillon * Authors: Xiaolei Li <xiaolei.li@mediatek.com> 693db446aSBoris Brezillon * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> 793db446aSBoris Brezillon */ 893db446aSBoris Brezillon 993db446aSBoris Brezillon #include <linux/platform_device.h> 1093db446aSBoris Brezillon #include <linux/dma-mapping.h> 1193db446aSBoris Brezillon #include <linux/interrupt.h> 1293db446aSBoris Brezillon #include <linux/delay.h> 1393db446aSBoris Brezillon #include <linux/clk.h> 1493db446aSBoris Brezillon #include <linux/mtd/rawnand.h> 1593db446aSBoris Brezillon #include <linux/mtd/mtd.h> 1693db446aSBoris Brezillon #include <linux/module.h> 1793db446aSBoris Brezillon #include <linux/iopoll.h> 1893db446aSBoris Brezillon #include <linux/of.h> 1993db446aSBoris Brezillon #include <linux/of_device.h> 2093db446aSBoris Brezillon #include "mtk_ecc.h" 2193db446aSBoris Brezillon 2293db446aSBoris Brezillon /* NAND controller register definition */ 2393db446aSBoris Brezillon #define NFI_CNFG (0x00) 2493db446aSBoris Brezillon #define CNFG_AHB BIT(0) 2593db446aSBoris Brezillon #define CNFG_READ_EN BIT(1) 2693db446aSBoris Brezillon #define CNFG_DMA_BURST_EN BIT(2) 2793db446aSBoris Brezillon #define CNFG_BYTE_RW BIT(6) 2893db446aSBoris Brezillon #define CNFG_HW_ECC_EN BIT(8) 2993db446aSBoris Brezillon #define CNFG_AUTO_FMT_EN BIT(9) 3093db446aSBoris Brezillon #define CNFG_OP_CUST (6 << 12) 3193db446aSBoris Brezillon #define NFI_PAGEFMT (0x04) 3293db446aSBoris Brezillon #define PAGEFMT_FDM_ECC_SHIFT (12) 3393db446aSBoris Brezillon #define PAGEFMT_FDM_SHIFT (8) 3493db446aSBoris Brezillon #define PAGEFMT_SEC_SEL_512 BIT(2) 3593db446aSBoris Brezillon #define PAGEFMT_512_2K (0) 3693db446aSBoris Brezillon #define PAGEFMT_2K_4K (1) 3793db446aSBoris Brezillon #define PAGEFMT_4K_8K (2) 3893db446aSBoris Brezillon #define PAGEFMT_8K_16K (3) 3993db446aSBoris Brezillon /* NFI control */ 4093db446aSBoris Brezillon #define NFI_CON (0x08) 4193db446aSBoris Brezillon #define CON_FIFO_FLUSH BIT(0) 4293db446aSBoris Brezillon #define CON_NFI_RST BIT(1) 4393db446aSBoris Brezillon #define CON_BRD BIT(8) /* burst read */ 4493db446aSBoris Brezillon #define CON_BWR BIT(9) /* burst write */ 4593db446aSBoris Brezillon #define CON_SEC_SHIFT (12) 4693db446aSBoris Brezillon /* Timming control register */ 4793db446aSBoris Brezillon #define NFI_ACCCON (0x0C) 4893db446aSBoris Brezillon #define NFI_INTR_EN (0x10) 4993db446aSBoris Brezillon #define INTR_AHB_DONE_EN BIT(6) 5093db446aSBoris Brezillon #define NFI_INTR_STA (0x14) 5193db446aSBoris Brezillon #define NFI_CMD (0x20) 5293db446aSBoris Brezillon #define NFI_ADDRNOB (0x30) 5393db446aSBoris Brezillon #define NFI_COLADDR (0x34) 5493db446aSBoris Brezillon #define NFI_ROWADDR (0x38) 5593db446aSBoris Brezillon #define NFI_STRDATA (0x40) 5693db446aSBoris Brezillon #define STAR_EN (1) 5793db446aSBoris Brezillon #define STAR_DE (0) 5893db446aSBoris Brezillon #define NFI_CNRNB (0x44) 5993db446aSBoris Brezillon #define NFI_DATAW (0x50) 6093db446aSBoris Brezillon #define NFI_DATAR (0x54) 6193db446aSBoris Brezillon #define NFI_PIO_DIRDY (0x58) 6293db446aSBoris Brezillon #define PIO_DI_RDY (0x01) 6393db446aSBoris Brezillon #define NFI_STA (0x60) 6493db446aSBoris Brezillon #define STA_CMD BIT(0) 6593db446aSBoris Brezillon #define STA_ADDR BIT(1) 6693db446aSBoris Brezillon #define STA_BUSY BIT(8) 6793db446aSBoris Brezillon #define STA_EMP_PAGE BIT(12) 6893db446aSBoris Brezillon #define NFI_FSM_CUSTDATA (0xe << 16) 6993db446aSBoris Brezillon #define NFI_FSM_MASK (0xf << 16) 7093db446aSBoris Brezillon #define NFI_ADDRCNTR (0x70) 7193db446aSBoris Brezillon #define CNTR_MASK GENMASK(16, 12) 7293db446aSBoris Brezillon #define ADDRCNTR_SEC_SHIFT (12) 7393db446aSBoris Brezillon #define ADDRCNTR_SEC(val) \ 7493db446aSBoris Brezillon (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT) 7593db446aSBoris Brezillon #define NFI_STRADDR (0x80) 7693db446aSBoris Brezillon #define NFI_BYTELEN (0x84) 7793db446aSBoris Brezillon #define NFI_CSEL (0x90) 7893db446aSBoris Brezillon #define NFI_FDML(x) (0xA0 + (x) * sizeof(u32) * 2) 7993db446aSBoris Brezillon #define NFI_FDMM(x) (0xA4 + (x) * sizeof(u32) * 2) 8093db446aSBoris Brezillon #define NFI_FDM_MAX_SIZE (8) 8193db446aSBoris Brezillon #define NFI_FDM_MIN_SIZE (1) 8242d13a09SXiaolei Li #define NFI_DEBUG_CON1 (0x220) 8342d13a09SXiaolei Li #define STROBE_MASK GENMASK(4, 3) 8442d13a09SXiaolei Li #define STROBE_SHIFT (3) 8542d13a09SXiaolei Li #define MAX_STROBE_DLY (3) 8693db446aSBoris Brezillon #define NFI_MASTER_STA (0x224) 8793db446aSBoris Brezillon #define MASTER_STA_MASK (0x0FFF) 8893db446aSBoris Brezillon #define NFI_EMPTY_THRESH (0x23C) 8993db446aSBoris Brezillon 9093db446aSBoris Brezillon #define MTK_NAME "mtk-nand" 9193db446aSBoris Brezillon #define KB(x) ((x) * 1024UL) 9293db446aSBoris Brezillon #define MB(x) (KB(x) * 1024UL) 9393db446aSBoris Brezillon 9493db446aSBoris Brezillon #define MTK_TIMEOUT (500000) 9593db446aSBoris Brezillon #define MTK_RESET_TIMEOUT (1000000) 9693db446aSBoris Brezillon #define MTK_NAND_MAX_NSELS (2) 9793db446aSBoris Brezillon #define MTK_NFC_MIN_SPARE (16) 9893db446aSBoris Brezillon #define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \ 9993db446aSBoris Brezillon ((tpoecs) << 28 | (tprecs) << 22 | (tc2r) << 16 | \ 10093db446aSBoris Brezillon (tw2r) << 12 | (twh) << 8 | (twst) << 4 | (trlt)) 10193db446aSBoris Brezillon 10293db446aSBoris Brezillon struct mtk_nfc_caps { 10393db446aSBoris Brezillon const u8 *spare_size; 10493db446aSBoris Brezillon u8 num_spare_size; 10593db446aSBoris Brezillon u8 pageformat_spare_shift; 10693db446aSBoris Brezillon u8 nfi_clk_div; 10793db446aSBoris Brezillon u8 max_sector; 10893db446aSBoris Brezillon u32 max_sector_size; 10993db446aSBoris Brezillon }; 11093db446aSBoris Brezillon 11193db446aSBoris Brezillon struct mtk_nfc_bad_mark_ctl { 11293db446aSBoris Brezillon void (*bm_swap)(struct mtd_info *, u8 *buf, int raw); 11393db446aSBoris Brezillon u32 sec; 11493db446aSBoris Brezillon u32 pos; 11593db446aSBoris Brezillon }; 11693db446aSBoris Brezillon 11793db446aSBoris Brezillon /* 11893db446aSBoris Brezillon * FDM: region used to store free OOB data 11993db446aSBoris Brezillon */ 12093db446aSBoris Brezillon struct mtk_nfc_fdm { 12193db446aSBoris Brezillon u32 reg_size; 12293db446aSBoris Brezillon u32 ecc_size; 12393db446aSBoris Brezillon }; 12493db446aSBoris Brezillon 12593db446aSBoris Brezillon struct mtk_nfc_nand_chip { 12693db446aSBoris Brezillon struct list_head node; 12793db446aSBoris Brezillon struct nand_chip nand; 12893db446aSBoris Brezillon 12993db446aSBoris Brezillon struct mtk_nfc_bad_mark_ctl bad_mark; 13093db446aSBoris Brezillon struct mtk_nfc_fdm fdm; 13193db446aSBoris Brezillon u32 spare_per_sector; 13293db446aSBoris Brezillon 13393db446aSBoris Brezillon int nsels; 13449f1c330SGustavo A. R. Silva u8 sels[]; 13593db446aSBoris Brezillon /* nothing after this field */ 13693db446aSBoris Brezillon }; 13793db446aSBoris Brezillon 13893db446aSBoris Brezillon struct mtk_nfc_clk { 13993db446aSBoris Brezillon struct clk *nfi_clk; 14093db446aSBoris Brezillon struct clk *pad_clk; 14193db446aSBoris Brezillon }; 14293db446aSBoris Brezillon 14393db446aSBoris Brezillon struct mtk_nfc { 1447da45139SMiquel Raynal struct nand_controller controller; 14593db446aSBoris Brezillon struct mtk_ecc_config ecc_cfg; 14693db446aSBoris Brezillon struct mtk_nfc_clk clk; 14793db446aSBoris Brezillon struct mtk_ecc *ecc; 14893db446aSBoris Brezillon 14993db446aSBoris Brezillon struct device *dev; 15093db446aSBoris Brezillon const struct mtk_nfc_caps *caps; 15193db446aSBoris Brezillon void __iomem *regs; 15293db446aSBoris Brezillon 15393db446aSBoris Brezillon struct completion done; 15493db446aSBoris Brezillon struct list_head chips; 15593db446aSBoris Brezillon 15693db446aSBoris Brezillon u8 *buffer; 1578dbd7b10SXiaolei Li 1588dbd7b10SXiaolei Li unsigned long assigned_cs; 15993db446aSBoris Brezillon }; 16093db446aSBoris Brezillon 16193db446aSBoris Brezillon /* 16293db446aSBoris Brezillon * supported spare size of each IP. 16393db446aSBoris Brezillon * order should be the same with the spare size bitfiled defination of 16493db446aSBoris Brezillon * register NFI_PAGEFMT. 16593db446aSBoris Brezillon */ 16693db446aSBoris Brezillon static const u8 spare_size_mt2701[] = { 16793db446aSBoris Brezillon 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 63, 64 16893db446aSBoris Brezillon }; 16993db446aSBoris Brezillon 17093db446aSBoris Brezillon static const u8 spare_size_mt2712[] = { 17193db446aSBoris Brezillon 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 61, 63, 64, 67, 17293db446aSBoris Brezillon 74 17393db446aSBoris Brezillon }; 17493db446aSBoris Brezillon 17593db446aSBoris Brezillon static const u8 spare_size_mt7622[] = { 17693db446aSBoris Brezillon 16, 26, 27, 28 17793db446aSBoris Brezillon }; 17893db446aSBoris Brezillon 17993db446aSBoris Brezillon static inline struct mtk_nfc_nand_chip *to_mtk_nand(struct nand_chip *nand) 18093db446aSBoris Brezillon { 18193db446aSBoris Brezillon return container_of(nand, struct mtk_nfc_nand_chip, nand); 18293db446aSBoris Brezillon } 18393db446aSBoris Brezillon 18493db446aSBoris Brezillon static inline u8 *data_ptr(struct nand_chip *chip, const u8 *p, int i) 18593db446aSBoris Brezillon { 18693db446aSBoris Brezillon return (u8 *)p + i * chip->ecc.size; 18793db446aSBoris Brezillon } 18893db446aSBoris Brezillon 18993db446aSBoris Brezillon static inline u8 *oob_ptr(struct nand_chip *chip, int i) 19093db446aSBoris Brezillon { 19193db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 19293db446aSBoris Brezillon u8 *poi; 19393db446aSBoris Brezillon 19493db446aSBoris Brezillon /* map the sector's FDM data to free oob: 19593db446aSBoris Brezillon * the beginning of the oob area stores the FDM data of bad mark sectors 19693db446aSBoris Brezillon */ 19793db446aSBoris Brezillon 19893db446aSBoris Brezillon if (i < mtk_nand->bad_mark.sec) 19993db446aSBoris Brezillon poi = chip->oob_poi + (i + 1) * mtk_nand->fdm.reg_size; 20093db446aSBoris Brezillon else if (i == mtk_nand->bad_mark.sec) 20193db446aSBoris Brezillon poi = chip->oob_poi; 20293db446aSBoris Brezillon else 20393db446aSBoris Brezillon poi = chip->oob_poi + i * mtk_nand->fdm.reg_size; 20493db446aSBoris Brezillon 20593db446aSBoris Brezillon return poi; 20693db446aSBoris Brezillon } 20793db446aSBoris Brezillon 20893db446aSBoris Brezillon static inline int mtk_data_len(struct nand_chip *chip) 20993db446aSBoris Brezillon { 21093db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 21193db446aSBoris Brezillon 21293db446aSBoris Brezillon return chip->ecc.size + mtk_nand->spare_per_sector; 21393db446aSBoris Brezillon } 21493db446aSBoris Brezillon 21593db446aSBoris Brezillon static inline u8 *mtk_data_ptr(struct nand_chip *chip, int i) 21693db446aSBoris Brezillon { 21793db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 21893db446aSBoris Brezillon 21993db446aSBoris Brezillon return nfc->buffer + i * mtk_data_len(chip); 22093db446aSBoris Brezillon } 22193db446aSBoris Brezillon 22293db446aSBoris Brezillon static inline u8 *mtk_oob_ptr(struct nand_chip *chip, int i) 22393db446aSBoris Brezillon { 22493db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 22593db446aSBoris Brezillon 22693db446aSBoris Brezillon return nfc->buffer + i * mtk_data_len(chip) + chip->ecc.size; 22793db446aSBoris Brezillon } 22893db446aSBoris Brezillon 22993db446aSBoris Brezillon static inline void nfi_writel(struct mtk_nfc *nfc, u32 val, u32 reg) 23093db446aSBoris Brezillon { 23193db446aSBoris Brezillon writel(val, nfc->regs + reg); 23293db446aSBoris Brezillon } 23393db446aSBoris Brezillon 23493db446aSBoris Brezillon static inline void nfi_writew(struct mtk_nfc *nfc, u16 val, u32 reg) 23593db446aSBoris Brezillon { 23693db446aSBoris Brezillon writew(val, nfc->regs + reg); 23793db446aSBoris Brezillon } 23893db446aSBoris Brezillon 23993db446aSBoris Brezillon static inline void nfi_writeb(struct mtk_nfc *nfc, u8 val, u32 reg) 24093db446aSBoris Brezillon { 24193db446aSBoris Brezillon writeb(val, nfc->regs + reg); 24293db446aSBoris Brezillon } 24393db446aSBoris Brezillon 24493db446aSBoris Brezillon static inline u32 nfi_readl(struct mtk_nfc *nfc, u32 reg) 24593db446aSBoris Brezillon { 24693db446aSBoris Brezillon return readl_relaxed(nfc->regs + reg); 24793db446aSBoris Brezillon } 24893db446aSBoris Brezillon 24993db446aSBoris Brezillon static inline u16 nfi_readw(struct mtk_nfc *nfc, u32 reg) 25093db446aSBoris Brezillon { 25193db446aSBoris Brezillon return readw_relaxed(nfc->regs + reg); 25293db446aSBoris Brezillon } 25393db446aSBoris Brezillon 25493db446aSBoris Brezillon static inline u8 nfi_readb(struct mtk_nfc *nfc, u32 reg) 25593db446aSBoris Brezillon { 25693db446aSBoris Brezillon return readb_relaxed(nfc->regs + reg); 25793db446aSBoris Brezillon } 25893db446aSBoris Brezillon 25993db446aSBoris Brezillon static void mtk_nfc_hw_reset(struct mtk_nfc *nfc) 26093db446aSBoris Brezillon { 26193db446aSBoris Brezillon struct device *dev = nfc->dev; 26293db446aSBoris Brezillon u32 val; 26393db446aSBoris Brezillon int ret; 26493db446aSBoris Brezillon 26593db446aSBoris Brezillon /* reset all registers and force the NFI master to terminate */ 26693db446aSBoris Brezillon nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON); 26793db446aSBoris Brezillon 26893db446aSBoris Brezillon /* wait for the master to finish the last transaction */ 26993db446aSBoris Brezillon ret = readl_poll_timeout(nfc->regs + NFI_MASTER_STA, val, 27093db446aSBoris Brezillon !(val & MASTER_STA_MASK), 50, 27193db446aSBoris Brezillon MTK_RESET_TIMEOUT); 27293db446aSBoris Brezillon if (ret) 27393db446aSBoris Brezillon dev_warn(dev, "master active in reset [0x%x] = 0x%x\n", 27493db446aSBoris Brezillon NFI_MASTER_STA, val); 27593db446aSBoris Brezillon 27693db446aSBoris Brezillon /* ensure any status register affected by the NFI master is reset */ 27793db446aSBoris Brezillon nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON); 27893db446aSBoris Brezillon nfi_writew(nfc, STAR_DE, NFI_STRDATA); 27993db446aSBoris Brezillon } 28093db446aSBoris Brezillon 28193db446aSBoris Brezillon static int mtk_nfc_send_command(struct mtk_nfc *nfc, u8 command) 28293db446aSBoris Brezillon { 28393db446aSBoris Brezillon struct device *dev = nfc->dev; 28493db446aSBoris Brezillon u32 val; 28593db446aSBoris Brezillon int ret; 28693db446aSBoris Brezillon 28793db446aSBoris Brezillon nfi_writel(nfc, command, NFI_CMD); 28893db446aSBoris Brezillon 28993db446aSBoris Brezillon ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val, 29093db446aSBoris Brezillon !(val & STA_CMD), 10, MTK_TIMEOUT); 29193db446aSBoris Brezillon if (ret) { 29293db446aSBoris Brezillon dev_warn(dev, "nfi core timed out entering command mode\n"); 29393db446aSBoris Brezillon return -EIO; 29493db446aSBoris Brezillon } 29593db446aSBoris Brezillon 29693db446aSBoris Brezillon return 0; 29793db446aSBoris Brezillon } 29893db446aSBoris Brezillon 29993db446aSBoris Brezillon static int mtk_nfc_send_address(struct mtk_nfc *nfc, int addr) 30093db446aSBoris Brezillon { 30193db446aSBoris Brezillon struct device *dev = nfc->dev; 30293db446aSBoris Brezillon u32 val; 30393db446aSBoris Brezillon int ret; 30493db446aSBoris Brezillon 30593db446aSBoris Brezillon nfi_writel(nfc, addr, NFI_COLADDR); 30693db446aSBoris Brezillon nfi_writel(nfc, 0, NFI_ROWADDR); 30793db446aSBoris Brezillon nfi_writew(nfc, 1, NFI_ADDRNOB); 30893db446aSBoris Brezillon 30993db446aSBoris Brezillon ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val, 31093db446aSBoris Brezillon !(val & STA_ADDR), 10, MTK_TIMEOUT); 31193db446aSBoris Brezillon if (ret) { 31293db446aSBoris Brezillon dev_warn(dev, "nfi core timed out entering address mode\n"); 31393db446aSBoris Brezillon return -EIO; 31493db446aSBoris Brezillon } 31593db446aSBoris Brezillon 31693db446aSBoris Brezillon return 0; 31793db446aSBoris Brezillon } 31893db446aSBoris Brezillon 31993db446aSBoris Brezillon static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd) 32093db446aSBoris Brezillon { 32193db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 32293db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 32393db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 32493db446aSBoris Brezillon u32 fmt, spare, i; 32593db446aSBoris Brezillon 32693db446aSBoris Brezillon if (!mtd->writesize) 32793db446aSBoris Brezillon return 0; 32893db446aSBoris Brezillon 32993db446aSBoris Brezillon spare = mtk_nand->spare_per_sector; 33093db446aSBoris Brezillon 33193db446aSBoris Brezillon switch (mtd->writesize) { 33293db446aSBoris Brezillon case 512: 33393db446aSBoris Brezillon fmt = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512; 33493db446aSBoris Brezillon break; 33593db446aSBoris Brezillon case KB(2): 33693db446aSBoris Brezillon if (chip->ecc.size == 512) 33793db446aSBoris Brezillon fmt = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512; 33893db446aSBoris Brezillon else 33993db446aSBoris Brezillon fmt = PAGEFMT_512_2K; 34093db446aSBoris Brezillon break; 34193db446aSBoris Brezillon case KB(4): 34293db446aSBoris Brezillon if (chip->ecc.size == 512) 34393db446aSBoris Brezillon fmt = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512; 34493db446aSBoris Brezillon else 34593db446aSBoris Brezillon fmt = PAGEFMT_2K_4K; 34693db446aSBoris Brezillon break; 34793db446aSBoris Brezillon case KB(8): 34893db446aSBoris Brezillon if (chip->ecc.size == 512) 34993db446aSBoris Brezillon fmt = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512; 35093db446aSBoris Brezillon else 35193db446aSBoris Brezillon fmt = PAGEFMT_4K_8K; 35293db446aSBoris Brezillon break; 35393db446aSBoris Brezillon case KB(16): 35493db446aSBoris Brezillon fmt = PAGEFMT_8K_16K; 35593db446aSBoris Brezillon break; 35693db446aSBoris Brezillon default: 35793db446aSBoris Brezillon dev_err(nfc->dev, "invalid page len: %d\n", mtd->writesize); 35893db446aSBoris Brezillon return -EINVAL; 35993db446aSBoris Brezillon } 36093db446aSBoris Brezillon 36193db446aSBoris Brezillon /* 36293db446aSBoris Brezillon * the hardware will double the value for this eccsize, so we need to 36393db446aSBoris Brezillon * halve it 36493db446aSBoris Brezillon */ 36593db446aSBoris Brezillon if (chip->ecc.size == 1024) 36693db446aSBoris Brezillon spare >>= 1; 36793db446aSBoris Brezillon 36893db446aSBoris Brezillon for (i = 0; i < nfc->caps->num_spare_size; i++) { 36993db446aSBoris Brezillon if (nfc->caps->spare_size[i] == spare) 37093db446aSBoris Brezillon break; 37193db446aSBoris Brezillon } 37293db446aSBoris Brezillon 37393db446aSBoris Brezillon if (i == nfc->caps->num_spare_size) { 37493db446aSBoris Brezillon dev_err(nfc->dev, "invalid spare size %d\n", spare); 37593db446aSBoris Brezillon return -EINVAL; 37693db446aSBoris Brezillon } 37793db446aSBoris Brezillon 37893db446aSBoris Brezillon fmt |= i << nfc->caps->pageformat_spare_shift; 37993db446aSBoris Brezillon 38093db446aSBoris Brezillon fmt |= mtk_nand->fdm.reg_size << PAGEFMT_FDM_SHIFT; 38193db446aSBoris Brezillon fmt |= mtk_nand->fdm.ecc_size << PAGEFMT_FDM_ECC_SHIFT; 38293db446aSBoris Brezillon nfi_writel(nfc, fmt, NFI_PAGEFMT); 38393db446aSBoris Brezillon 38493db446aSBoris Brezillon nfc->ecc_cfg.strength = chip->ecc.strength; 38593db446aSBoris Brezillon nfc->ecc_cfg.len = chip->ecc.size + mtk_nand->fdm.ecc_size; 38693db446aSBoris Brezillon 38793db446aSBoris Brezillon return 0; 38893db446aSBoris Brezillon } 38993db446aSBoris Brezillon 39093db446aSBoris Brezillon static inline void mtk_nfc_wait_ioready(struct mtk_nfc *nfc) 39193db446aSBoris Brezillon { 39293db446aSBoris Brezillon int rc; 39393db446aSBoris Brezillon u8 val; 39493db446aSBoris Brezillon 39593db446aSBoris Brezillon rc = readb_poll_timeout_atomic(nfc->regs + NFI_PIO_DIRDY, val, 39693db446aSBoris Brezillon val & PIO_DI_RDY, 10, MTK_TIMEOUT); 39793db446aSBoris Brezillon if (rc < 0) 39893db446aSBoris Brezillon dev_err(nfc->dev, "data not ready\n"); 39993db446aSBoris Brezillon } 40093db446aSBoris Brezillon 4017e534323SBoris Brezillon static inline u8 mtk_nfc_read_byte(struct nand_chip *chip) 40293db446aSBoris Brezillon { 40393db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 40493db446aSBoris Brezillon u32 reg; 40593db446aSBoris Brezillon 40693db446aSBoris Brezillon /* after each byte read, the NFI_STA reg is reset by the hardware */ 40793db446aSBoris Brezillon reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK; 40893db446aSBoris Brezillon if (reg != NFI_FSM_CUSTDATA) { 40993db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG); 41093db446aSBoris Brezillon reg |= CNFG_BYTE_RW | CNFG_READ_EN; 41193db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 41293db446aSBoris Brezillon 41393db446aSBoris Brezillon /* 41493db446aSBoris Brezillon * set to max sector to allow the HW to continue reading over 41593db446aSBoris Brezillon * unaligned accesses 41693db446aSBoris Brezillon */ 41793db446aSBoris Brezillon reg = (nfc->caps->max_sector << CON_SEC_SHIFT) | CON_BRD; 41893db446aSBoris Brezillon nfi_writel(nfc, reg, NFI_CON); 41993db446aSBoris Brezillon 42093db446aSBoris Brezillon /* trigger to fetch data */ 42193db446aSBoris Brezillon nfi_writew(nfc, STAR_EN, NFI_STRDATA); 42293db446aSBoris Brezillon } 42393db446aSBoris Brezillon 42493db446aSBoris Brezillon mtk_nfc_wait_ioready(nfc); 42593db446aSBoris Brezillon 42693db446aSBoris Brezillon return nfi_readb(nfc, NFI_DATAR); 42793db446aSBoris Brezillon } 42893db446aSBoris Brezillon 4297e534323SBoris Brezillon static void mtk_nfc_read_buf(struct nand_chip *chip, u8 *buf, int len) 43093db446aSBoris Brezillon { 43193db446aSBoris Brezillon int i; 43293db446aSBoris Brezillon 43393db446aSBoris Brezillon for (i = 0; i < len; i++) 4347e534323SBoris Brezillon buf[i] = mtk_nfc_read_byte(chip); 43593db446aSBoris Brezillon } 43693db446aSBoris Brezillon 437c0739d85SBoris Brezillon static void mtk_nfc_write_byte(struct nand_chip *chip, u8 byte) 43893db446aSBoris Brezillon { 439c0739d85SBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 44093db446aSBoris Brezillon u32 reg; 44193db446aSBoris Brezillon 44293db446aSBoris Brezillon reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK; 44393db446aSBoris Brezillon 44493db446aSBoris Brezillon if (reg != NFI_FSM_CUSTDATA) { 44593db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG) | CNFG_BYTE_RW; 44693db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 44793db446aSBoris Brezillon 44893db446aSBoris Brezillon reg = nfc->caps->max_sector << CON_SEC_SHIFT | CON_BWR; 44993db446aSBoris Brezillon nfi_writel(nfc, reg, NFI_CON); 45093db446aSBoris Brezillon 45193db446aSBoris Brezillon nfi_writew(nfc, STAR_EN, NFI_STRDATA); 45293db446aSBoris Brezillon } 45393db446aSBoris Brezillon 45493db446aSBoris Brezillon mtk_nfc_wait_ioready(nfc); 45593db446aSBoris Brezillon nfi_writeb(nfc, byte, NFI_DATAW); 45693db446aSBoris Brezillon } 45793db446aSBoris Brezillon 458c0739d85SBoris Brezillon static void mtk_nfc_write_buf(struct nand_chip *chip, const u8 *buf, int len) 45993db446aSBoris Brezillon { 46093db446aSBoris Brezillon int i; 46193db446aSBoris Brezillon 46293db446aSBoris Brezillon for (i = 0; i < len; i++) 463c0739d85SBoris Brezillon mtk_nfc_write_byte(chip, buf[i]); 46493db446aSBoris Brezillon } 46593db446aSBoris Brezillon 4665197360fSBoris Brezillon static int mtk_nfc_exec_instr(struct nand_chip *chip, 4675197360fSBoris Brezillon const struct nand_op_instr *instr) 4685197360fSBoris Brezillon { 4695197360fSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 4705197360fSBoris Brezillon unsigned int i; 4715197360fSBoris Brezillon u32 status; 4725197360fSBoris Brezillon 4735197360fSBoris Brezillon switch (instr->type) { 4745197360fSBoris Brezillon case NAND_OP_CMD_INSTR: 4755197360fSBoris Brezillon mtk_nfc_send_command(nfc, instr->ctx.cmd.opcode); 4765197360fSBoris Brezillon return 0; 4775197360fSBoris Brezillon case NAND_OP_ADDR_INSTR: 4785197360fSBoris Brezillon for (i = 0; i < instr->ctx.addr.naddrs; i++) 4795197360fSBoris Brezillon mtk_nfc_send_address(nfc, instr->ctx.addr.addrs[i]); 4805197360fSBoris Brezillon return 0; 4815197360fSBoris Brezillon case NAND_OP_DATA_IN_INSTR: 4825197360fSBoris Brezillon mtk_nfc_read_buf(chip, instr->ctx.data.buf.in, 4835197360fSBoris Brezillon instr->ctx.data.len); 4845197360fSBoris Brezillon return 0; 4855197360fSBoris Brezillon case NAND_OP_DATA_OUT_INSTR: 4865197360fSBoris Brezillon mtk_nfc_write_buf(chip, instr->ctx.data.buf.out, 4875197360fSBoris Brezillon instr->ctx.data.len); 4885197360fSBoris Brezillon return 0; 4895197360fSBoris Brezillon case NAND_OP_WAITRDY_INSTR: 4905197360fSBoris Brezillon return readl_poll_timeout(nfc->regs + NFI_STA, status, 4915197360fSBoris Brezillon status & STA_BUSY, 20, 4925197360fSBoris Brezillon instr->ctx.waitrdy.timeout_ms); 4935197360fSBoris Brezillon default: 4945197360fSBoris Brezillon break; 4955197360fSBoris Brezillon } 4965197360fSBoris Brezillon 4975197360fSBoris Brezillon return -EINVAL; 4985197360fSBoris Brezillon } 4995197360fSBoris Brezillon 5005197360fSBoris Brezillon static void mtk_nfc_select_target(struct nand_chip *nand, unsigned int cs) 5015197360fSBoris Brezillon { 5025197360fSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(nand); 5035197360fSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand); 5045197360fSBoris Brezillon 5055197360fSBoris Brezillon mtk_nfc_hw_runtime_config(nand_to_mtd(nand)); 5065197360fSBoris Brezillon 5075197360fSBoris Brezillon nfi_writel(nfc, mtk_nand->sels[cs], NFI_CSEL); 5085197360fSBoris Brezillon } 5095197360fSBoris Brezillon 5105197360fSBoris Brezillon static int mtk_nfc_exec_op(struct nand_chip *chip, 5115197360fSBoris Brezillon const struct nand_operation *op, 5125197360fSBoris Brezillon bool check_only) 5135197360fSBoris Brezillon { 5145197360fSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 5155197360fSBoris Brezillon unsigned int i; 5165197360fSBoris Brezillon int ret = 0; 5175197360fSBoris Brezillon 5185197360fSBoris Brezillon if (check_only) 5195197360fSBoris Brezillon return 0; 5205197360fSBoris Brezillon 5215197360fSBoris Brezillon mtk_nfc_hw_reset(nfc); 5225197360fSBoris Brezillon nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG); 5235197360fSBoris Brezillon mtk_nfc_select_target(chip, op->cs); 5245197360fSBoris Brezillon 5255197360fSBoris Brezillon for (i = 0; i < op->ninstrs; i++) { 5265197360fSBoris Brezillon ret = mtk_nfc_exec_instr(chip, &op->instrs[i]); 5275197360fSBoris Brezillon if (ret) 5285197360fSBoris Brezillon break; 5295197360fSBoris Brezillon } 5305197360fSBoris Brezillon 5315197360fSBoris Brezillon return ret; 5325197360fSBoris Brezillon } 5335197360fSBoris Brezillon 5344c46667bSMiquel Raynal static int mtk_nfc_setup_interface(struct nand_chip *chip, int csline, 5354c46667bSMiquel Raynal const struct nand_interface_config *conf) 53693db446aSBoris Brezillon { 537858838b8SBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 53893db446aSBoris Brezillon const struct nand_sdr_timings *timings; 539e1884ffdSXiaolei Li u32 rate, tpoecs, tprecs, tc2r, tw2r, twh, twst = 0, trlt = 0; 54042d13a09SXiaolei Li u32 temp, tsel = 0; 54193db446aSBoris Brezillon 54293db446aSBoris Brezillon timings = nand_get_sdr_timings(conf); 54393db446aSBoris Brezillon if (IS_ERR(timings)) 54493db446aSBoris Brezillon return -ENOTSUPP; 54593db446aSBoris Brezillon 54693db446aSBoris Brezillon if (csline == NAND_DATA_IFACE_CHECK_ONLY) 54793db446aSBoris Brezillon return 0; 54893db446aSBoris Brezillon 54993db446aSBoris Brezillon rate = clk_get_rate(nfc->clk.nfi_clk); 55093db446aSBoris Brezillon /* There is a frequency divider in some IPs */ 55193db446aSBoris Brezillon rate /= nfc->caps->nfi_clk_div; 55293db446aSBoris Brezillon 55393db446aSBoris Brezillon /* turn clock rate into KHZ */ 55493db446aSBoris Brezillon rate /= 1000; 55593db446aSBoris Brezillon 55693db446aSBoris Brezillon tpoecs = max(timings->tALH_min, timings->tCLH_min) / 1000; 55793db446aSBoris Brezillon tpoecs = DIV_ROUND_UP(tpoecs * rate, 1000000); 55893db446aSBoris Brezillon tpoecs &= 0xf; 55993db446aSBoris Brezillon 56093db446aSBoris Brezillon tprecs = max(timings->tCLS_min, timings->tALS_min) / 1000; 56193db446aSBoris Brezillon tprecs = DIV_ROUND_UP(tprecs * rate, 1000000); 56293db446aSBoris Brezillon tprecs &= 0x3f; 56393db446aSBoris Brezillon 56493db446aSBoris Brezillon /* sdr interface has no tCR which means CE# low to RE# low */ 56593db446aSBoris Brezillon tc2r = 0; 56693db446aSBoris Brezillon 56793db446aSBoris Brezillon tw2r = timings->tWHR_min / 1000; 56893db446aSBoris Brezillon tw2r = DIV_ROUND_UP(tw2r * rate, 1000000); 56993db446aSBoris Brezillon tw2r = DIV_ROUND_UP(tw2r - 1, 2); 57093db446aSBoris Brezillon tw2r &= 0xf; 57193db446aSBoris Brezillon 57293db446aSBoris Brezillon twh = max(timings->tREH_min, timings->tWH_min) / 1000; 57393db446aSBoris Brezillon twh = DIV_ROUND_UP(twh * rate, 1000000) - 1; 57493db446aSBoris Brezillon twh &= 0xf; 57593db446aSBoris Brezillon 576e1884ffdSXiaolei Li /* Calculate real WE#/RE# hold time in nanosecond */ 57742d13a09SXiaolei Li temp = (twh + 1) * 1000000 / rate; 578e1884ffdSXiaolei Li /* nanosecond to picosecond */ 57942d13a09SXiaolei Li temp *= 1000; 580e1884ffdSXiaolei Li 581e1884ffdSXiaolei Li /* 582e1884ffdSXiaolei Li * WE# low level time should be expaned to meet WE# pulse time 583e1884ffdSXiaolei Li * and WE# cycle time at the same time. 584e1884ffdSXiaolei Li */ 58542d13a09SXiaolei Li if (temp < timings->tWC_min) 58642d13a09SXiaolei Li twst = timings->tWC_min - temp; 587e1884ffdSXiaolei Li twst = max(timings->tWP_min, twst) / 1000; 58893db446aSBoris Brezillon twst = DIV_ROUND_UP(twst * rate, 1000000) - 1; 58993db446aSBoris Brezillon twst &= 0xf; 59093db446aSBoris Brezillon 591e1884ffdSXiaolei Li /* 59242d13a09SXiaolei Li * RE# low level time should be expaned to meet RE# pulse time 59342d13a09SXiaolei Li * and RE# cycle time at the same time. 594e1884ffdSXiaolei Li */ 59542d13a09SXiaolei Li if (temp < timings->tRC_min) 59642d13a09SXiaolei Li trlt = timings->tRC_min - temp; 59742d13a09SXiaolei Li trlt = max(trlt, timings->tRP_min) / 1000; 59893db446aSBoris Brezillon trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1; 59993db446aSBoris Brezillon trlt &= 0xf; 60093db446aSBoris Brezillon 60142d13a09SXiaolei Li /* Calculate RE# pulse time in nanosecond. */ 60242d13a09SXiaolei Li temp = (trlt + 1) * 1000000 / rate; 60342d13a09SXiaolei Li /* nanosecond to picosecond */ 60442d13a09SXiaolei Li temp *= 1000; 60542d13a09SXiaolei Li /* 60642d13a09SXiaolei Li * If RE# access time is bigger than RE# pulse time, 60742d13a09SXiaolei Li * delay sampling data timing. 60842d13a09SXiaolei Li */ 60942d13a09SXiaolei Li if (temp < timings->tREA_max) { 61042d13a09SXiaolei Li tsel = timings->tREA_max / 1000; 61142d13a09SXiaolei Li tsel = DIV_ROUND_UP(tsel * rate, 1000000); 61242d13a09SXiaolei Li tsel -= (trlt + 1); 61342d13a09SXiaolei Li if (tsel > MAX_STROBE_DLY) { 61442d13a09SXiaolei Li trlt += tsel - MAX_STROBE_DLY; 61542d13a09SXiaolei Li tsel = MAX_STROBE_DLY; 61642d13a09SXiaolei Li } 61742d13a09SXiaolei Li } 61842d13a09SXiaolei Li temp = nfi_readl(nfc, NFI_DEBUG_CON1); 61942d13a09SXiaolei Li temp &= ~STROBE_MASK; 62042d13a09SXiaolei Li temp |= tsel << STROBE_SHIFT; 62142d13a09SXiaolei Li nfi_writel(nfc, temp, NFI_DEBUG_CON1); 62242d13a09SXiaolei Li 62393db446aSBoris Brezillon /* 62493db446aSBoris Brezillon * ACCON: access timing control register 62593db446aSBoris Brezillon * ------------------------------------- 62693db446aSBoris Brezillon * 31:28: tpoecs, minimum required time for CS post pulling down after 62793db446aSBoris Brezillon * accessing the device 62893db446aSBoris Brezillon * 27:22: tprecs, minimum required time for CS pre pulling down before 62993db446aSBoris Brezillon * accessing the device 63093db446aSBoris Brezillon * 21:16: tc2r, minimum required time from NCEB low to NREB low 63193db446aSBoris Brezillon * 15:12: tw2r, minimum required time from NWEB high to NREB low. 63293db446aSBoris Brezillon * 11:08: twh, write enable hold time 63393db446aSBoris Brezillon * 07:04: twst, write wait states 63493db446aSBoris Brezillon * 03:00: trlt, read wait states 63593db446aSBoris Brezillon */ 63693db446aSBoris Brezillon trlt = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt); 63793db446aSBoris Brezillon nfi_writel(nfc, trlt, NFI_ACCCON); 63893db446aSBoris Brezillon 63993db446aSBoris Brezillon return 0; 64093db446aSBoris Brezillon } 64193db446aSBoris Brezillon 64293db446aSBoris Brezillon static int mtk_nfc_sector_encode(struct nand_chip *chip, u8 *data) 64393db446aSBoris Brezillon { 64493db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 64593db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 64693db446aSBoris Brezillon int size = chip->ecc.size + mtk_nand->fdm.reg_size; 64793db446aSBoris Brezillon 64893db446aSBoris Brezillon nfc->ecc_cfg.mode = ECC_DMA_MODE; 64993db446aSBoris Brezillon nfc->ecc_cfg.op = ECC_ENCODE; 65093db446aSBoris Brezillon 65193db446aSBoris Brezillon return mtk_ecc_encode(nfc->ecc, &nfc->ecc_cfg, data, size); 65293db446aSBoris Brezillon } 65393db446aSBoris Brezillon 65493db446aSBoris Brezillon static void mtk_nfc_no_bad_mark_swap(struct mtd_info *a, u8 *b, int c) 65593db446aSBoris Brezillon { 65693db446aSBoris Brezillon /* nop */ 65793db446aSBoris Brezillon } 65893db446aSBoris Brezillon 65993db446aSBoris Brezillon static void mtk_nfc_bad_mark_swap(struct mtd_info *mtd, u8 *buf, int raw) 66093db446aSBoris Brezillon { 66193db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 66293db446aSBoris Brezillon struct mtk_nfc_nand_chip *nand = to_mtk_nand(chip); 66393db446aSBoris Brezillon u32 bad_pos = nand->bad_mark.pos; 66493db446aSBoris Brezillon 66593db446aSBoris Brezillon if (raw) 66693db446aSBoris Brezillon bad_pos += nand->bad_mark.sec * mtk_data_len(chip); 66793db446aSBoris Brezillon else 66893db446aSBoris Brezillon bad_pos += nand->bad_mark.sec * chip->ecc.size; 66993db446aSBoris Brezillon 67093db446aSBoris Brezillon swap(chip->oob_poi[0], buf[bad_pos]); 67193db446aSBoris Brezillon } 67293db446aSBoris Brezillon 67393db446aSBoris Brezillon static int mtk_nfc_format_subpage(struct mtd_info *mtd, u32 offset, 67493db446aSBoris Brezillon u32 len, const u8 *buf) 67593db446aSBoris Brezillon { 67693db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 67793db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 67893db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 67993db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 68093db446aSBoris Brezillon u32 start, end; 68193db446aSBoris Brezillon int i, ret; 68293db446aSBoris Brezillon 68393db446aSBoris Brezillon start = offset / chip->ecc.size; 68493db446aSBoris Brezillon end = DIV_ROUND_UP(offset + len, chip->ecc.size); 68593db446aSBoris Brezillon 68693db446aSBoris Brezillon memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); 68793db446aSBoris Brezillon for (i = 0; i < chip->ecc.steps; i++) { 68893db446aSBoris Brezillon memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i), 68993db446aSBoris Brezillon chip->ecc.size); 69093db446aSBoris Brezillon 69193db446aSBoris Brezillon if (start > i || i >= end) 69293db446aSBoris Brezillon continue; 69393db446aSBoris Brezillon 69493db446aSBoris Brezillon if (i == mtk_nand->bad_mark.sec) 69593db446aSBoris Brezillon mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); 69693db446aSBoris Brezillon 69793db446aSBoris Brezillon memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size); 69893db446aSBoris Brezillon 69993db446aSBoris Brezillon /* program the CRC back to the OOB */ 70093db446aSBoris Brezillon ret = mtk_nfc_sector_encode(chip, mtk_data_ptr(chip, i)); 70193db446aSBoris Brezillon if (ret < 0) 70293db446aSBoris Brezillon return ret; 70393db446aSBoris Brezillon } 70493db446aSBoris Brezillon 70593db446aSBoris Brezillon return 0; 70693db446aSBoris Brezillon } 70793db446aSBoris Brezillon 70893db446aSBoris Brezillon static void mtk_nfc_format_page(struct mtd_info *mtd, const u8 *buf) 70993db446aSBoris Brezillon { 71093db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 71193db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 71293db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 71393db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 71493db446aSBoris Brezillon u32 i; 71593db446aSBoris Brezillon 71693db446aSBoris Brezillon memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); 71793db446aSBoris Brezillon for (i = 0; i < chip->ecc.steps; i++) { 71893db446aSBoris Brezillon if (buf) 71993db446aSBoris Brezillon memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i), 72093db446aSBoris Brezillon chip->ecc.size); 72193db446aSBoris Brezillon 72293db446aSBoris Brezillon if (i == mtk_nand->bad_mark.sec) 72393db446aSBoris Brezillon mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); 72493db446aSBoris Brezillon 72593db446aSBoris Brezillon memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size); 72693db446aSBoris Brezillon } 72793db446aSBoris Brezillon } 72893db446aSBoris Brezillon 72993db446aSBoris Brezillon static inline void mtk_nfc_read_fdm(struct nand_chip *chip, u32 start, 73093db446aSBoris Brezillon u32 sectors) 73193db446aSBoris Brezillon { 73293db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 73393db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 73493db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 73593db446aSBoris Brezillon u32 vall, valm; 73693db446aSBoris Brezillon u8 *oobptr; 73793db446aSBoris Brezillon int i, j; 73893db446aSBoris Brezillon 73993db446aSBoris Brezillon for (i = 0; i < sectors; i++) { 74093db446aSBoris Brezillon oobptr = oob_ptr(chip, start + i); 74193db446aSBoris Brezillon vall = nfi_readl(nfc, NFI_FDML(i)); 74293db446aSBoris Brezillon valm = nfi_readl(nfc, NFI_FDMM(i)); 74393db446aSBoris Brezillon 74493db446aSBoris Brezillon for (j = 0; j < fdm->reg_size; j++) 74593db446aSBoris Brezillon oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); 74693db446aSBoris Brezillon } 74793db446aSBoris Brezillon } 74893db446aSBoris Brezillon 74993db446aSBoris Brezillon static inline void mtk_nfc_write_fdm(struct nand_chip *chip) 75093db446aSBoris Brezillon { 75193db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 75293db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 75393db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 75493db446aSBoris Brezillon u32 vall, valm; 75593db446aSBoris Brezillon u8 *oobptr; 75693db446aSBoris Brezillon int i, j; 75793db446aSBoris Brezillon 75893db446aSBoris Brezillon for (i = 0; i < chip->ecc.steps; i++) { 75993db446aSBoris Brezillon oobptr = oob_ptr(chip, i); 76093db446aSBoris Brezillon vall = 0; 76193db446aSBoris Brezillon valm = 0; 76293db446aSBoris Brezillon for (j = 0; j < 8; j++) { 76393db446aSBoris Brezillon if (j < 4) 76493db446aSBoris Brezillon vall |= (j < fdm->reg_size ? oobptr[j] : 0xff) 76593db446aSBoris Brezillon << (j * 8); 76693db446aSBoris Brezillon else 76793db446aSBoris Brezillon valm |= (j < fdm->reg_size ? oobptr[j] : 0xff) 76893db446aSBoris Brezillon << ((j - 4) * 8); 76993db446aSBoris Brezillon } 77093db446aSBoris Brezillon nfi_writel(nfc, vall, NFI_FDML(i)); 77193db446aSBoris Brezillon nfi_writel(nfc, valm, NFI_FDMM(i)); 77293db446aSBoris Brezillon } 77393db446aSBoris Brezillon } 77493db446aSBoris Brezillon 77593db446aSBoris Brezillon static int mtk_nfc_do_write_page(struct mtd_info *mtd, struct nand_chip *chip, 77693db446aSBoris Brezillon const u8 *buf, int page, int len) 77793db446aSBoris Brezillon { 77893db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 77993db446aSBoris Brezillon struct device *dev = nfc->dev; 78093db446aSBoris Brezillon dma_addr_t addr; 78193db446aSBoris Brezillon u32 reg; 78293db446aSBoris Brezillon int ret; 78393db446aSBoris Brezillon 78493db446aSBoris Brezillon addr = dma_map_single(dev, (void *)buf, len, DMA_TO_DEVICE); 78593db446aSBoris Brezillon ret = dma_mapping_error(nfc->dev, addr); 78693db446aSBoris Brezillon if (ret) { 78793db446aSBoris Brezillon dev_err(nfc->dev, "dma mapping error\n"); 78893db446aSBoris Brezillon return -EINVAL; 78993db446aSBoris Brezillon } 79093db446aSBoris Brezillon 79193db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AHB | CNFG_DMA_BURST_EN; 79293db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 79393db446aSBoris Brezillon 79493db446aSBoris Brezillon nfi_writel(nfc, chip->ecc.steps << CON_SEC_SHIFT, NFI_CON); 79593db446aSBoris Brezillon nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR); 79693db446aSBoris Brezillon nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN); 79793db446aSBoris Brezillon 79893db446aSBoris Brezillon init_completion(&nfc->done); 79993db446aSBoris Brezillon 80093db446aSBoris Brezillon reg = nfi_readl(nfc, NFI_CON) | CON_BWR; 80193db446aSBoris Brezillon nfi_writel(nfc, reg, NFI_CON); 80293db446aSBoris Brezillon nfi_writew(nfc, STAR_EN, NFI_STRDATA); 80393db446aSBoris Brezillon 80493db446aSBoris Brezillon ret = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500)); 80593db446aSBoris Brezillon if (!ret) { 80693db446aSBoris Brezillon dev_err(dev, "program ahb done timeout\n"); 80793db446aSBoris Brezillon nfi_writew(nfc, 0, NFI_INTR_EN); 80893db446aSBoris Brezillon ret = -ETIMEDOUT; 80993db446aSBoris Brezillon goto timeout; 81093db446aSBoris Brezillon } 81193db446aSBoris Brezillon 81293db446aSBoris Brezillon ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg, 81393db446aSBoris Brezillon ADDRCNTR_SEC(reg) >= chip->ecc.steps, 81493db446aSBoris Brezillon 10, MTK_TIMEOUT); 81593db446aSBoris Brezillon if (ret) 81693db446aSBoris Brezillon dev_err(dev, "hwecc write timeout\n"); 81793db446aSBoris Brezillon 81893db446aSBoris Brezillon timeout: 81993db446aSBoris Brezillon 82093db446aSBoris Brezillon dma_unmap_single(nfc->dev, addr, len, DMA_TO_DEVICE); 82193db446aSBoris Brezillon nfi_writel(nfc, 0, NFI_CON); 82293db446aSBoris Brezillon 82393db446aSBoris Brezillon return ret; 82493db446aSBoris Brezillon } 82593db446aSBoris Brezillon 82693db446aSBoris Brezillon static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, 82793db446aSBoris Brezillon const u8 *buf, int page, int raw) 82893db446aSBoris Brezillon { 82993db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 83093db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 83193db446aSBoris Brezillon size_t len; 83293db446aSBoris Brezillon const u8 *bufpoi; 83393db446aSBoris Brezillon u32 reg; 83493db446aSBoris Brezillon int ret; 83593db446aSBoris Brezillon 8365197360fSBoris Brezillon mtk_nfc_select_target(chip, chip->cur_cs); 83793db446aSBoris Brezillon nand_prog_page_begin_op(chip, page, 0, NULL, 0); 83893db446aSBoris Brezillon 83993db446aSBoris Brezillon if (!raw) { 84093db446aSBoris Brezillon /* OOB => FDM: from register, ECC: from HW */ 84193db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN; 84293db446aSBoris Brezillon nfi_writew(nfc, reg | CNFG_HW_ECC_EN, NFI_CNFG); 84393db446aSBoris Brezillon 84493db446aSBoris Brezillon nfc->ecc_cfg.op = ECC_ENCODE; 84593db446aSBoris Brezillon nfc->ecc_cfg.mode = ECC_NFI_MODE; 84693db446aSBoris Brezillon ret = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg); 84793db446aSBoris Brezillon if (ret) { 84893db446aSBoris Brezillon /* clear NFI config */ 84993db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG); 85093db446aSBoris Brezillon reg &= ~(CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); 85193db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 85293db446aSBoris Brezillon 85393db446aSBoris Brezillon return ret; 85493db446aSBoris Brezillon } 85593db446aSBoris Brezillon 85693db446aSBoris Brezillon memcpy(nfc->buffer, buf, mtd->writesize); 85793db446aSBoris Brezillon mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, raw); 85893db446aSBoris Brezillon bufpoi = nfc->buffer; 85993db446aSBoris Brezillon 86093db446aSBoris Brezillon /* write OOB into the FDM registers (OOB area in MTK NAND) */ 86193db446aSBoris Brezillon mtk_nfc_write_fdm(chip); 86293db446aSBoris Brezillon } else { 86393db446aSBoris Brezillon bufpoi = buf; 86493db446aSBoris Brezillon } 86593db446aSBoris Brezillon 86693db446aSBoris Brezillon len = mtd->writesize + (raw ? mtd->oobsize : 0); 86793db446aSBoris Brezillon ret = mtk_nfc_do_write_page(mtd, chip, bufpoi, page, len); 86893db446aSBoris Brezillon 86993db446aSBoris Brezillon if (!raw) 87093db446aSBoris Brezillon mtk_ecc_disable(nfc->ecc); 87193db446aSBoris Brezillon 87293db446aSBoris Brezillon if (ret) 87393db446aSBoris Brezillon return ret; 87493db446aSBoris Brezillon 87593db446aSBoris Brezillon return nand_prog_page_end_op(chip); 87693db446aSBoris Brezillon } 87793db446aSBoris Brezillon 878767eb6fbSBoris Brezillon static int mtk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, 87993db446aSBoris Brezillon int oob_on, int page) 88093db446aSBoris Brezillon { 881767eb6fbSBoris Brezillon return mtk_nfc_write_page(nand_to_mtd(chip), chip, buf, page, 0); 88293db446aSBoris Brezillon } 88393db446aSBoris Brezillon 884767eb6fbSBoris Brezillon static int mtk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, 885767eb6fbSBoris Brezillon int oob_on, int pg) 88693db446aSBoris Brezillon { 887767eb6fbSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 88893db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 88993db446aSBoris Brezillon 89093db446aSBoris Brezillon mtk_nfc_format_page(mtd, buf); 89193db446aSBoris Brezillon return mtk_nfc_write_page(mtd, chip, nfc->buffer, pg, 1); 89293db446aSBoris Brezillon } 89393db446aSBoris Brezillon 894767eb6fbSBoris Brezillon static int mtk_nfc_write_subpage_hwecc(struct nand_chip *chip, u32 offset, 89593db446aSBoris Brezillon u32 data_len, const u8 *buf, 89693db446aSBoris Brezillon int oob_on, int page) 89793db446aSBoris Brezillon { 898767eb6fbSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 89993db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 90093db446aSBoris Brezillon int ret; 90193db446aSBoris Brezillon 90293db446aSBoris Brezillon ret = mtk_nfc_format_subpage(mtd, offset, data_len, buf); 90393db446aSBoris Brezillon if (ret < 0) 90493db446aSBoris Brezillon return ret; 90593db446aSBoris Brezillon 90693db446aSBoris Brezillon /* use the data in the private buffer (now with FDM and CRC) */ 90793db446aSBoris Brezillon return mtk_nfc_write_page(mtd, chip, nfc->buffer, page, 1); 90893db446aSBoris Brezillon } 90993db446aSBoris Brezillon 910767eb6fbSBoris Brezillon static int mtk_nfc_write_oob_std(struct nand_chip *chip, int page) 91193db446aSBoris Brezillon { 912767eb6fbSBoris Brezillon return mtk_nfc_write_page_raw(chip, NULL, 1, page); 91393db446aSBoris Brezillon } 91493db446aSBoris Brezillon 915336d4b13SXiaolei Li static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 start, 916336d4b13SXiaolei Li u32 sectors) 91793db446aSBoris Brezillon { 91893db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 91993db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 92093db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 92193db446aSBoris Brezillon struct mtk_ecc_stats stats; 922336d4b13SXiaolei Li u32 reg_size = mtk_nand->fdm.reg_size; 92393db446aSBoris Brezillon int rc, i; 92493db446aSBoris Brezillon 92593db446aSBoris Brezillon rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE; 92693db446aSBoris Brezillon if (rc) { 92793db446aSBoris Brezillon memset(buf, 0xff, sectors * chip->ecc.size); 92893db446aSBoris Brezillon for (i = 0; i < sectors; i++) 929336d4b13SXiaolei Li memset(oob_ptr(chip, start + i), 0xff, reg_size); 93093db446aSBoris Brezillon return 0; 93193db446aSBoris Brezillon } 93293db446aSBoris Brezillon 93393db446aSBoris Brezillon mtk_ecc_get_stats(nfc->ecc, &stats, sectors); 93493db446aSBoris Brezillon mtd->ecc_stats.corrected += stats.corrected; 93593db446aSBoris Brezillon mtd->ecc_stats.failed += stats.failed; 93693db446aSBoris Brezillon 93793db446aSBoris Brezillon return stats.bitflips; 93893db446aSBoris Brezillon } 93993db446aSBoris Brezillon 94093db446aSBoris Brezillon static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, 94193db446aSBoris Brezillon u32 data_offs, u32 readlen, 94293db446aSBoris Brezillon u8 *bufpoi, int page, int raw) 94393db446aSBoris Brezillon { 94493db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 94593db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 94693db446aSBoris Brezillon u32 spare = mtk_nand->spare_per_sector; 94793db446aSBoris Brezillon u32 column, sectors, start, end, reg; 94893db446aSBoris Brezillon dma_addr_t addr; 949336d4b13SXiaolei Li int bitflips = 0; 95093db446aSBoris Brezillon size_t len; 95193db446aSBoris Brezillon u8 *buf; 95293db446aSBoris Brezillon int rc; 95393db446aSBoris Brezillon 9545197360fSBoris Brezillon mtk_nfc_select_target(chip, chip->cur_cs); 95593db446aSBoris Brezillon start = data_offs / chip->ecc.size; 95693db446aSBoris Brezillon end = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size); 95793db446aSBoris Brezillon 95893db446aSBoris Brezillon sectors = end - start; 95993db446aSBoris Brezillon column = start * (chip->ecc.size + spare); 96093db446aSBoris Brezillon 96193db446aSBoris Brezillon len = sectors * chip->ecc.size + (raw ? sectors * spare : 0); 96293db446aSBoris Brezillon buf = bufpoi + start * chip->ecc.size; 96393db446aSBoris Brezillon 96493db446aSBoris Brezillon nand_read_page_op(chip, page, column, NULL, 0); 96593db446aSBoris Brezillon 96693db446aSBoris Brezillon addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE); 96793db446aSBoris Brezillon rc = dma_mapping_error(nfc->dev, addr); 96893db446aSBoris Brezillon if (rc) { 96993db446aSBoris Brezillon dev_err(nfc->dev, "dma mapping error\n"); 97093db446aSBoris Brezillon 97193db446aSBoris Brezillon return -EINVAL; 97293db446aSBoris Brezillon } 97393db446aSBoris Brezillon 97493db446aSBoris Brezillon reg = nfi_readw(nfc, NFI_CNFG); 97593db446aSBoris Brezillon reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_AHB; 97693db446aSBoris Brezillon if (!raw) { 97793db446aSBoris Brezillon reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; 97893db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 97993db446aSBoris Brezillon 98093db446aSBoris Brezillon nfc->ecc_cfg.mode = ECC_NFI_MODE; 98193db446aSBoris Brezillon nfc->ecc_cfg.sectors = sectors; 98293db446aSBoris Brezillon nfc->ecc_cfg.op = ECC_DECODE; 98393db446aSBoris Brezillon rc = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg); 98493db446aSBoris Brezillon if (rc) { 98593db446aSBoris Brezillon dev_err(nfc->dev, "ecc enable\n"); 98693db446aSBoris Brezillon /* clear NFI_CNFG */ 98793db446aSBoris Brezillon reg &= ~(CNFG_DMA_BURST_EN | CNFG_AHB | CNFG_READ_EN | 98893db446aSBoris Brezillon CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); 98993db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 99093db446aSBoris Brezillon dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); 99193db446aSBoris Brezillon 99293db446aSBoris Brezillon return rc; 99393db446aSBoris Brezillon } 99493db446aSBoris Brezillon } else { 99593db446aSBoris Brezillon nfi_writew(nfc, reg, NFI_CNFG); 99693db446aSBoris Brezillon } 99793db446aSBoris Brezillon 99893db446aSBoris Brezillon nfi_writel(nfc, sectors << CON_SEC_SHIFT, NFI_CON); 99993db446aSBoris Brezillon nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN); 100093db446aSBoris Brezillon nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR); 100193db446aSBoris Brezillon 100293db446aSBoris Brezillon init_completion(&nfc->done); 100393db446aSBoris Brezillon reg = nfi_readl(nfc, NFI_CON) | CON_BRD; 100493db446aSBoris Brezillon nfi_writel(nfc, reg, NFI_CON); 100593db446aSBoris Brezillon nfi_writew(nfc, STAR_EN, NFI_STRDATA); 100693db446aSBoris Brezillon 100793db446aSBoris Brezillon rc = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500)); 100893db446aSBoris Brezillon if (!rc) 100993db446aSBoris Brezillon dev_warn(nfc->dev, "read ahb/dma done timeout\n"); 101093db446aSBoris Brezillon 101193db446aSBoris Brezillon rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg, 101293db446aSBoris Brezillon ADDRCNTR_SEC(reg) >= sectors, 10, 101393db446aSBoris Brezillon MTK_TIMEOUT); 101493db446aSBoris Brezillon if (rc < 0) { 101593db446aSBoris Brezillon dev_err(nfc->dev, "subpage done timeout\n"); 101693db446aSBoris Brezillon bitflips = -EIO; 1017336d4b13SXiaolei Li } else if (!raw) { 101893db446aSBoris Brezillon rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE); 101993db446aSBoris Brezillon bitflips = rc < 0 ? -ETIMEDOUT : 1020336d4b13SXiaolei Li mtk_nfc_update_ecc_stats(mtd, buf, start, sectors); 102193db446aSBoris Brezillon mtk_nfc_read_fdm(chip, start, sectors); 102293db446aSBoris Brezillon } 102393db446aSBoris Brezillon 102493db446aSBoris Brezillon dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); 102593db446aSBoris Brezillon 102693db446aSBoris Brezillon if (raw) 102793db446aSBoris Brezillon goto done; 102893db446aSBoris Brezillon 102993db446aSBoris Brezillon mtk_ecc_disable(nfc->ecc); 103093db446aSBoris Brezillon 103193db446aSBoris Brezillon if (clamp(mtk_nand->bad_mark.sec, start, end) == mtk_nand->bad_mark.sec) 103293db446aSBoris Brezillon mtk_nand->bad_mark.bm_swap(mtd, bufpoi, raw); 103393db446aSBoris Brezillon done: 103493db446aSBoris Brezillon nfi_writel(nfc, 0, NFI_CON); 103593db446aSBoris Brezillon 103693db446aSBoris Brezillon return bitflips; 103793db446aSBoris Brezillon } 103893db446aSBoris Brezillon 1039b9761687SBoris Brezillon static int mtk_nfc_read_subpage_hwecc(struct nand_chip *chip, u32 off, 104093db446aSBoris Brezillon u32 len, u8 *p, int pg) 104193db446aSBoris Brezillon { 1042b9761687SBoris Brezillon return mtk_nfc_read_subpage(nand_to_mtd(chip), chip, off, len, p, pg, 1043b9761687SBoris Brezillon 0); 104493db446aSBoris Brezillon } 104593db446aSBoris Brezillon 1046b9761687SBoris Brezillon static int mtk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *p, int oob_on, 1047b9761687SBoris Brezillon int pg) 104893db446aSBoris Brezillon { 1049b9761687SBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 1050b9761687SBoris Brezillon 105193db446aSBoris Brezillon return mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, p, pg, 0); 105293db446aSBoris Brezillon } 105393db446aSBoris Brezillon 1054b9761687SBoris Brezillon static int mtk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on, 1055b9761687SBoris Brezillon int page) 105693db446aSBoris Brezillon { 1057b9761687SBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 105893db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 105993db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(chip); 106093db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 106193db446aSBoris Brezillon int i, ret; 106293db446aSBoris Brezillon 106393db446aSBoris Brezillon memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); 106493db446aSBoris Brezillon ret = mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, nfc->buffer, 106593db446aSBoris Brezillon page, 1); 106693db446aSBoris Brezillon if (ret < 0) 106793db446aSBoris Brezillon return ret; 106893db446aSBoris Brezillon 106993db446aSBoris Brezillon for (i = 0; i < chip->ecc.steps; i++) { 107093db446aSBoris Brezillon memcpy(oob_ptr(chip, i), mtk_oob_ptr(chip, i), fdm->reg_size); 107193db446aSBoris Brezillon 107293db446aSBoris Brezillon if (i == mtk_nand->bad_mark.sec) 107393db446aSBoris Brezillon mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); 107493db446aSBoris Brezillon 107593db446aSBoris Brezillon if (buf) 107693db446aSBoris Brezillon memcpy(data_ptr(chip, buf, i), mtk_data_ptr(chip, i), 107793db446aSBoris Brezillon chip->ecc.size); 107893db446aSBoris Brezillon } 107993db446aSBoris Brezillon 108093db446aSBoris Brezillon return ret; 108193db446aSBoris Brezillon } 108293db446aSBoris Brezillon 1083b9761687SBoris Brezillon static int mtk_nfc_read_oob_std(struct nand_chip *chip, int page) 108493db446aSBoris Brezillon { 1085b9761687SBoris Brezillon return mtk_nfc_read_page_raw(chip, NULL, 1, page); 108693db446aSBoris Brezillon } 108793db446aSBoris Brezillon 108893db446aSBoris Brezillon static inline void mtk_nfc_hw_init(struct mtk_nfc *nfc) 108993db446aSBoris Brezillon { 109093db446aSBoris Brezillon /* 109193db446aSBoris Brezillon * CNRNB: nand ready/busy register 109293db446aSBoris Brezillon * ------------------------------- 109393db446aSBoris Brezillon * 7:4: timeout register for polling the NAND busy/ready signal 109493db446aSBoris Brezillon * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles. 109593db446aSBoris Brezillon */ 109693db446aSBoris Brezillon nfi_writew(nfc, 0xf1, NFI_CNRNB); 109793db446aSBoris Brezillon nfi_writel(nfc, PAGEFMT_8K_16K, NFI_PAGEFMT); 109893db446aSBoris Brezillon 109993db446aSBoris Brezillon mtk_nfc_hw_reset(nfc); 110093db446aSBoris Brezillon 110193db446aSBoris Brezillon nfi_readl(nfc, NFI_INTR_STA); 110293db446aSBoris Brezillon nfi_writel(nfc, 0, NFI_INTR_EN); 110393db446aSBoris Brezillon } 110493db446aSBoris Brezillon 110593db446aSBoris Brezillon static irqreturn_t mtk_nfc_irq(int irq, void *id) 110693db446aSBoris Brezillon { 110793db446aSBoris Brezillon struct mtk_nfc *nfc = id; 110893db446aSBoris Brezillon u16 sta, ien; 110993db446aSBoris Brezillon 111093db446aSBoris Brezillon sta = nfi_readw(nfc, NFI_INTR_STA); 111193db446aSBoris Brezillon ien = nfi_readw(nfc, NFI_INTR_EN); 111293db446aSBoris Brezillon 111393db446aSBoris Brezillon if (!(sta & ien)) 111493db446aSBoris Brezillon return IRQ_NONE; 111593db446aSBoris Brezillon 111693db446aSBoris Brezillon nfi_writew(nfc, ~sta & ien, NFI_INTR_EN); 111793db446aSBoris Brezillon complete(&nfc->done); 111893db446aSBoris Brezillon 111993db446aSBoris Brezillon return IRQ_HANDLED; 112093db446aSBoris Brezillon } 112193db446aSBoris Brezillon 112293db446aSBoris Brezillon static int mtk_nfc_enable_clk(struct device *dev, struct mtk_nfc_clk *clk) 112393db446aSBoris Brezillon { 112493db446aSBoris Brezillon int ret; 112593db446aSBoris Brezillon 112693db446aSBoris Brezillon ret = clk_prepare_enable(clk->nfi_clk); 112793db446aSBoris Brezillon if (ret) { 112893db446aSBoris Brezillon dev_err(dev, "failed to enable nfi clk\n"); 112993db446aSBoris Brezillon return ret; 113093db446aSBoris Brezillon } 113193db446aSBoris Brezillon 113293db446aSBoris Brezillon ret = clk_prepare_enable(clk->pad_clk); 113393db446aSBoris Brezillon if (ret) { 113493db446aSBoris Brezillon dev_err(dev, "failed to enable pad clk\n"); 113593db446aSBoris Brezillon clk_disable_unprepare(clk->nfi_clk); 113693db446aSBoris Brezillon return ret; 113793db446aSBoris Brezillon } 113893db446aSBoris Brezillon 113993db446aSBoris Brezillon return 0; 114093db446aSBoris Brezillon } 114193db446aSBoris Brezillon 114293db446aSBoris Brezillon static void mtk_nfc_disable_clk(struct mtk_nfc_clk *clk) 114393db446aSBoris Brezillon { 114493db446aSBoris Brezillon clk_disable_unprepare(clk->nfi_clk); 114593db446aSBoris Brezillon clk_disable_unprepare(clk->pad_clk); 114693db446aSBoris Brezillon } 114793db446aSBoris Brezillon 114893db446aSBoris Brezillon static int mtk_nfc_ooblayout_free(struct mtd_info *mtd, int section, 114993db446aSBoris Brezillon struct mtd_oob_region *oob_region) 115093db446aSBoris Brezillon { 115193db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 115293db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 115393db446aSBoris Brezillon struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; 115493db446aSBoris Brezillon u32 eccsteps; 115593db446aSBoris Brezillon 115693db446aSBoris Brezillon eccsteps = mtd->writesize / chip->ecc.size; 115793db446aSBoris Brezillon 115893db446aSBoris Brezillon if (section >= eccsteps) 115993db446aSBoris Brezillon return -ERANGE; 116093db446aSBoris Brezillon 116193db446aSBoris Brezillon oob_region->length = fdm->reg_size - fdm->ecc_size; 116293db446aSBoris Brezillon oob_region->offset = section * fdm->reg_size + fdm->ecc_size; 116393db446aSBoris Brezillon 116493db446aSBoris Brezillon return 0; 116593db446aSBoris Brezillon } 116693db446aSBoris Brezillon 116793db446aSBoris Brezillon static int mtk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, 116893db446aSBoris Brezillon struct mtd_oob_region *oob_region) 116993db446aSBoris Brezillon { 117093db446aSBoris Brezillon struct nand_chip *chip = mtd_to_nand(mtd); 117193db446aSBoris Brezillon struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 117293db446aSBoris Brezillon u32 eccsteps; 117393db446aSBoris Brezillon 117493db446aSBoris Brezillon if (section) 117593db446aSBoris Brezillon return -ERANGE; 117693db446aSBoris Brezillon 117793db446aSBoris Brezillon eccsteps = mtd->writesize / chip->ecc.size; 117893db446aSBoris Brezillon oob_region->offset = mtk_nand->fdm.reg_size * eccsteps; 117993db446aSBoris Brezillon oob_region->length = mtd->oobsize - oob_region->offset; 118093db446aSBoris Brezillon 118193db446aSBoris Brezillon return 0; 118293db446aSBoris Brezillon } 118393db446aSBoris Brezillon 118493db446aSBoris Brezillon static const struct mtd_ooblayout_ops mtk_nfc_ooblayout_ops = { 118593db446aSBoris Brezillon .free = mtk_nfc_ooblayout_free, 118693db446aSBoris Brezillon .ecc = mtk_nfc_ooblayout_ecc, 118793db446aSBoris Brezillon }; 118893db446aSBoris Brezillon 118993db446aSBoris Brezillon static void mtk_nfc_set_fdm(struct mtk_nfc_fdm *fdm, struct mtd_info *mtd) 119093db446aSBoris Brezillon { 119193db446aSBoris Brezillon struct nand_chip *nand = mtd_to_nand(mtd); 119293db446aSBoris Brezillon struct mtk_nfc_nand_chip *chip = to_mtk_nand(nand); 119393db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(nand); 119493db446aSBoris Brezillon u32 ecc_bytes; 119593db446aSBoris Brezillon 119693db446aSBoris Brezillon ecc_bytes = DIV_ROUND_UP(nand->ecc.strength * 119793db446aSBoris Brezillon mtk_ecc_get_parity_bits(nfc->ecc), 8); 119893db446aSBoris Brezillon 119993db446aSBoris Brezillon fdm->reg_size = chip->spare_per_sector - ecc_bytes; 120093db446aSBoris Brezillon if (fdm->reg_size > NFI_FDM_MAX_SIZE) 120193db446aSBoris Brezillon fdm->reg_size = NFI_FDM_MAX_SIZE; 120293db446aSBoris Brezillon 120393db446aSBoris Brezillon /* bad block mark storage */ 120493db446aSBoris Brezillon fdm->ecc_size = 1; 120593db446aSBoris Brezillon } 120693db446aSBoris Brezillon 120793db446aSBoris Brezillon static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl, 120893db446aSBoris Brezillon struct mtd_info *mtd) 120993db446aSBoris Brezillon { 121093db446aSBoris Brezillon struct nand_chip *nand = mtd_to_nand(mtd); 121193db446aSBoris Brezillon 121293db446aSBoris Brezillon if (mtd->writesize == 512) { 121393db446aSBoris Brezillon bm_ctl->bm_swap = mtk_nfc_no_bad_mark_swap; 121493db446aSBoris Brezillon } else { 121593db446aSBoris Brezillon bm_ctl->bm_swap = mtk_nfc_bad_mark_swap; 121693db446aSBoris Brezillon bm_ctl->sec = mtd->writesize / mtk_data_len(nand); 121793db446aSBoris Brezillon bm_ctl->pos = mtd->writesize % mtk_data_len(nand); 121893db446aSBoris Brezillon } 121993db446aSBoris Brezillon } 122093db446aSBoris Brezillon 122193db446aSBoris Brezillon static int mtk_nfc_set_spare_per_sector(u32 *sps, struct mtd_info *mtd) 122293db446aSBoris Brezillon { 122393db446aSBoris Brezillon struct nand_chip *nand = mtd_to_nand(mtd); 122493db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(nand); 122593db446aSBoris Brezillon const u8 *spare = nfc->caps->spare_size; 122693db446aSBoris Brezillon u32 eccsteps, i, closest_spare = 0; 122793db446aSBoris Brezillon 122893db446aSBoris Brezillon eccsteps = mtd->writesize / nand->ecc.size; 122993db446aSBoris Brezillon *sps = mtd->oobsize / eccsteps; 123093db446aSBoris Brezillon 123193db446aSBoris Brezillon if (nand->ecc.size == 1024) 123293db446aSBoris Brezillon *sps >>= 1; 123393db446aSBoris Brezillon 123493db446aSBoris Brezillon if (*sps < MTK_NFC_MIN_SPARE) 123593db446aSBoris Brezillon return -EINVAL; 123693db446aSBoris Brezillon 123793db446aSBoris Brezillon for (i = 0; i < nfc->caps->num_spare_size; i++) { 123893db446aSBoris Brezillon if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) { 123993db446aSBoris Brezillon closest_spare = i; 124093db446aSBoris Brezillon if (*sps == spare[i]) 124193db446aSBoris Brezillon break; 124293db446aSBoris Brezillon } 124393db446aSBoris Brezillon } 124493db446aSBoris Brezillon 124593db446aSBoris Brezillon *sps = spare[closest_spare]; 124693db446aSBoris Brezillon 124793db446aSBoris Brezillon if (nand->ecc.size == 1024) 124893db446aSBoris Brezillon *sps <<= 1; 124993db446aSBoris Brezillon 125093db446aSBoris Brezillon return 0; 125193db446aSBoris Brezillon } 125293db446aSBoris Brezillon 125393db446aSBoris Brezillon static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) 125493db446aSBoris Brezillon { 125593db446aSBoris Brezillon struct nand_chip *nand = mtd_to_nand(mtd); 125693db446aSBoris Brezillon struct mtk_nfc *nfc = nand_get_controller_data(nand); 125793db446aSBoris Brezillon u32 spare; 125893db446aSBoris Brezillon int free, ret; 125993db446aSBoris Brezillon 126093db446aSBoris Brezillon /* support only ecc hw mode */ 1261bace41f8SMiquel Raynal if (nand->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) { 1262bace41f8SMiquel Raynal dev_err(dev, "ecc.engine_type not supported\n"); 126393db446aSBoris Brezillon return -EINVAL; 126493db446aSBoris Brezillon } 126593db446aSBoris Brezillon 126693db446aSBoris Brezillon /* if optional dt settings not present */ 126793db446aSBoris Brezillon if (!nand->ecc.size || !nand->ecc.strength) { 126893db446aSBoris Brezillon /* use datasheet requirements */ 12696a1b66d6SBoris Brezillon nand->ecc.strength = nand->base.eccreq.strength; 12706a1b66d6SBoris Brezillon nand->ecc.size = nand->base.eccreq.step_size; 127193db446aSBoris Brezillon 127293db446aSBoris Brezillon /* 127393db446aSBoris Brezillon * align eccstrength and eccsize 127493db446aSBoris Brezillon * this controller only supports 512 and 1024 sizes 127593db446aSBoris Brezillon */ 127693db446aSBoris Brezillon if (nand->ecc.size < 1024) { 127793db446aSBoris Brezillon if (mtd->writesize > 512 && 127893db446aSBoris Brezillon nfc->caps->max_sector_size > 512) { 127993db446aSBoris Brezillon nand->ecc.size = 1024; 128093db446aSBoris Brezillon nand->ecc.strength <<= 1; 128193db446aSBoris Brezillon } else { 128293db446aSBoris Brezillon nand->ecc.size = 512; 128393db446aSBoris Brezillon } 128493db446aSBoris Brezillon } else { 128593db446aSBoris Brezillon nand->ecc.size = 1024; 128693db446aSBoris Brezillon } 128793db446aSBoris Brezillon 128893db446aSBoris Brezillon ret = mtk_nfc_set_spare_per_sector(&spare, mtd); 128993db446aSBoris Brezillon if (ret) 129093db446aSBoris Brezillon return ret; 129193db446aSBoris Brezillon 129293db446aSBoris Brezillon /* calculate oob bytes except ecc parity data */ 129393db446aSBoris Brezillon free = (nand->ecc.strength * mtk_ecc_get_parity_bits(nfc->ecc) 129493db446aSBoris Brezillon + 7) >> 3; 129593db446aSBoris Brezillon free = spare - free; 129693db446aSBoris Brezillon 129793db446aSBoris Brezillon /* 129893db446aSBoris Brezillon * enhance ecc strength if oob left is bigger than max FDM size 129993db446aSBoris Brezillon * or reduce ecc strength if oob size is not enough for ecc 130093db446aSBoris Brezillon * parity data. 130193db446aSBoris Brezillon */ 130293db446aSBoris Brezillon if (free > NFI_FDM_MAX_SIZE) { 130393db446aSBoris Brezillon spare -= NFI_FDM_MAX_SIZE; 130493db446aSBoris Brezillon nand->ecc.strength = (spare << 3) / 130593db446aSBoris Brezillon mtk_ecc_get_parity_bits(nfc->ecc); 130693db446aSBoris Brezillon } else if (free < 0) { 130793db446aSBoris Brezillon spare -= NFI_FDM_MIN_SIZE; 130893db446aSBoris Brezillon nand->ecc.strength = (spare << 3) / 130993db446aSBoris Brezillon mtk_ecc_get_parity_bits(nfc->ecc); 131093db446aSBoris Brezillon } 131193db446aSBoris Brezillon } 131293db446aSBoris Brezillon 131393db446aSBoris Brezillon mtk_ecc_adjust_strength(nfc->ecc, &nand->ecc.strength); 131493db446aSBoris Brezillon 131593db446aSBoris Brezillon dev_info(dev, "eccsize %d eccstrength %d\n", 131693db446aSBoris Brezillon nand->ecc.size, nand->ecc.strength); 131793db446aSBoris Brezillon 131893db446aSBoris Brezillon return 0; 131993db446aSBoris Brezillon } 132093db446aSBoris Brezillon 13211ce7826dSMiquel Raynal static int mtk_nfc_attach_chip(struct nand_chip *chip) 13221ce7826dSMiquel Raynal { 13231ce7826dSMiquel Raynal struct mtd_info *mtd = nand_to_mtd(chip); 13241ce7826dSMiquel Raynal struct device *dev = mtd->dev.parent; 13251ce7826dSMiquel Raynal struct mtk_nfc *nfc = nand_get_controller_data(chip); 13261ce7826dSMiquel Raynal struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); 13271ce7826dSMiquel Raynal int len; 13281ce7826dSMiquel Raynal int ret; 13291ce7826dSMiquel Raynal 13301ce7826dSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16) { 13311ce7826dSMiquel Raynal dev_err(dev, "16bits buswidth not supported"); 13321ce7826dSMiquel Raynal return -EINVAL; 13331ce7826dSMiquel Raynal } 13341ce7826dSMiquel Raynal 13351ce7826dSMiquel Raynal /* store bbt magic in page, cause OOB is not protected */ 13361ce7826dSMiquel Raynal if (chip->bbt_options & NAND_BBT_USE_FLASH) 13371ce7826dSMiquel Raynal chip->bbt_options |= NAND_BBT_NO_OOB; 13381ce7826dSMiquel Raynal 13391ce7826dSMiquel Raynal ret = mtk_nfc_ecc_init(dev, mtd); 13401ce7826dSMiquel Raynal if (ret) 13411ce7826dSMiquel Raynal return ret; 13421ce7826dSMiquel Raynal 13431ce7826dSMiquel Raynal ret = mtk_nfc_set_spare_per_sector(&mtk_nand->spare_per_sector, mtd); 13441ce7826dSMiquel Raynal if (ret) 13451ce7826dSMiquel Raynal return ret; 13461ce7826dSMiquel Raynal 13471ce7826dSMiquel Raynal mtk_nfc_set_fdm(&mtk_nand->fdm, mtd); 13481ce7826dSMiquel Raynal mtk_nfc_set_bad_mark_ctl(&mtk_nand->bad_mark, mtd); 13491ce7826dSMiquel Raynal 13501ce7826dSMiquel Raynal len = mtd->writesize + mtd->oobsize; 13511ce7826dSMiquel Raynal nfc->buffer = devm_kzalloc(dev, len, GFP_KERNEL); 13521ce7826dSMiquel Raynal if (!nfc->buffer) 13531ce7826dSMiquel Raynal return -ENOMEM; 13541ce7826dSMiquel Raynal 13551ce7826dSMiquel Raynal return 0; 13561ce7826dSMiquel Raynal } 13571ce7826dSMiquel Raynal 13581ce7826dSMiquel Raynal static const struct nand_controller_ops mtk_nfc_controller_ops = { 13591ce7826dSMiquel Raynal .attach_chip = mtk_nfc_attach_chip, 13604c46667bSMiquel Raynal .setup_interface = mtk_nfc_setup_interface, 13615197360fSBoris Brezillon .exec_op = mtk_nfc_exec_op, 13621ce7826dSMiquel Raynal }; 13631ce7826dSMiquel Raynal 136493db446aSBoris Brezillon static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, 136593db446aSBoris Brezillon struct device_node *np) 136693db446aSBoris Brezillon { 136793db446aSBoris Brezillon struct mtk_nfc_nand_chip *chip; 136893db446aSBoris Brezillon struct nand_chip *nand; 136993db446aSBoris Brezillon struct mtd_info *mtd; 13701ce7826dSMiquel Raynal int nsels; 137193db446aSBoris Brezillon u32 tmp; 137293db446aSBoris Brezillon int ret; 137393db446aSBoris Brezillon int i; 137493db446aSBoris Brezillon 137593db446aSBoris Brezillon if (!of_get_property(np, "reg", &nsels)) 137693db446aSBoris Brezillon return -ENODEV; 137793db446aSBoris Brezillon 137893db446aSBoris Brezillon nsels /= sizeof(u32); 137993db446aSBoris Brezillon if (!nsels || nsels > MTK_NAND_MAX_NSELS) { 138093db446aSBoris Brezillon dev_err(dev, "invalid reg property size %d\n", nsels); 138193db446aSBoris Brezillon return -EINVAL; 138293db446aSBoris Brezillon } 138393db446aSBoris Brezillon 138493db446aSBoris Brezillon chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8), 138593db446aSBoris Brezillon GFP_KERNEL); 138693db446aSBoris Brezillon if (!chip) 138793db446aSBoris Brezillon return -ENOMEM; 138893db446aSBoris Brezillon 138993db446aSBoris Brezillon chip->nsels = nsels; 139093db446aSBoris Brezillon for (i = 0; i < nsels; i++) { 139193db446aSBoris Brezillon ret = of_property_read_u32_index(np, "reg", i, &tmp); 139293db446aSBoris Brezillon if (ret) { 139393db446aSBoris Brezillon dev_err(dev, "reg property failure : %d\n", ret); 139493db446aSBoris Brezillon return ret; 139593db446aSBoris Brezillon } 13968dbd7b10SXiaolei Li 13978dbd7b10SXiaolei Li if (tmp >= MTK_NAND_MAX_NSELS) { 13988dbd7b10SXiaolei Li dev_err(dev, "invalid CS: %u\n", tmp); 13998dbd7b10SXiaolei Li return -EINVAL; 14008dbd7b10SXiaolei Li } 14018dbd7b10SXiaolei Li 14028dbd7b10SXiaolei Li if (test_and_set_bit(tmp, &nfc->assigned_cs)) { 14038dbd7b10SXiaolei Li dev_err(dev, "CS %u already assigned\n", tmp); 14048dbd7b10SXiaolei Li return -EINVAL; 14058dbd7b10SXiaolei Li } 14068dbd7b10SXiaolei Li 140793db446aSBoris Brezillon chip->sels[i] = tmp; 140893db446aSBoris Brezillon } 140993db446aSBoris Brezillon 141093db446aSBoris Brezillon nand = &chip->nand; 141193db446aSBoris Brezillon nand->controller = &nfc->controller; 141293db446aSBoris Brezillon 141393db446aSBoris Brezillon nand_set_flash_node(nand, np); 141493db446aSBoris Brezillon nand_set_controller_data(nand, nfc); 141593db446aSBoris Brezillon 1416ce8148d7SMiquel Raynal nand->options |= NAND_USES_DMA | NAND_SUBPAGE_READ; 141793db446aSBoris Brezillon 141893db446aSBoris Brezillon /* set default mode in case dt entry is missing */ 1419bace41f8SMiquel Raynal nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; 142093db446aSBoris Brezillon 142193db446aSBoris Brezillon nand->ecc.write_subpage = mtk_nfc_write_subpage_hwecc; 142293db446aSBoris Brezillon nand->ecc.write_page_raw = mtk_nfc_write_page_raw; 142393db446aSBoris Brezillon nand->ecc.write_page = mtk_nfc_write_page_hwecc; 142493db446aSBoris Brezillon nand->ecc.write_oob_raw = mtk_nfc_write_oob_std; 142593db446aSBoris Brezillon nand->ecc.write_oob = mtk_nfc_write_oob_std; 142693db446aSBoris Brezillon 142793db446aSBoris Brezillon nand->ecc.read_subpage = mtk_nfc_read_subpage_hwecc; 142893db446aSBoris Brezillon nand->ecc.read_page_raw = mtk_nfc_read_page_raw; 142993db446aSBoris Brezillon nand->ecc.read_page = mtk_nfc_read_page_hwecc; 143093db446aSBoris Brezillon nand->ecc.read_oob_raw = mtk_nfc_read_oob_std; 143193db446aSBoris Brezillon nand->ecc.read_oob = mtk_nfc_read_oob_std; 143293db446aSBoris Brezillon 143393db446aSBoris Brezillon mtd = nand_to_mtd(nand); 143493db446aSBoris Brezillon mtd->owner = THIS_MODULE; 143593db446aSBoris Brezillon mtd->dev.parent = dev; 143693db446aSBoris Brezillon mtd->name = MTK_NAME; 143793db446aSBoris Brezillon mtd_set_ooblayout(mtd, &mtk_nfc_ooblayout_ops); 143893db446aSBoris Brezillon 143993db446aSBoris Brezillon mtk_nfc_hw_init(nfc); 144093db446aSBoris Brezillon 144100ad378fSBoris Brezillon ret = nand_scan(nand, nsels); 144293db446aSBoris Brezillon if (ret) 144393db446aSBoris Brezillon return ret; 144493db446aSBoris Brezillon 144529597ca1SRafał Miłecki ret = mtd_device_register(mtd, NULL, 0); 144693db446aSBoris Brezillon if (ret) { 144793db446aSBoris Brezillon dev_err(dev, "mtd parse partition error\n"); 14488a82bbcaSMiquel Raynal nand_cleanup(nand); 144993db446aSBoris Brezillon return ret; 145093db446aSBoris Brezillon } 145193db446aSBoris Brezillon 145293db446aSBoris Brezillon list_add_tail(&chip->node, &nfc->chips); 145393db446aSBoris Brezillon 145493db446aSBoris Brezillon return 0; 145593db446aSBoris Brezillon } 145693db446aSBoris Brezillon 145793db446aSBoris Brezillon static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc) 145893db446aSBoris Brezillon { 145993db446aSBoris Brezillon struct device_node *np = dev->of_node; 146093db446aSBoris Brezillon struct device_node *nand_np; 146193db446aSBoris Brezillon int ret; 146293db446aSBoris Brezillon 146393db446aSBoris Brezillon for_each_child_of_node(np, nand_np) { 146493db446aSBoris Brezillon ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np); 146593db446aSBoris Brezillon if (ret) { 146693db446aSBoris Brezillon of_node_put(nand_np); 146793db446aSBoris Brezillon return ret; 146893db446aSBoris Brezillon } 146993db446aSBoris Brezillon } 147093db446aSBoris Brezillon 147193db446aSBoris Brezillon return 0; 147293db446aSBoris Brezillon } 147393db446aSBoris Brezillon 147493db446aSBoris Brezillon static const struct mtk_nfc_caps mtk_nfc_caps_mt2701 = { 147593db446aSBoris Brezillon .spare_size = spare_size_mt2701, 147693db446aSBoris Brezillon .num_spare_size = 16, 147793db446aSBoris Brezillon .pageformat_spare_shift = 4, 147893db446aSBoris Brezillon .nfi_clk_div = 1, 147993db446aSBoris Brezillon .max_sector = 16, 148093db446aSBoris Brezillon .max_sector_size = 1024, 148193db446aSBoris Brezillon }; 148293db446aSBoris Brezillon 148393db446aSBoris Brezillon static const struct mtk_nfc_caps mtk_nfc_caps_mt2712 = { 148493db446aSBoris Brezillon .spare_size = spare_size_mt2712, 148593db446aSBoris Brezillon .num_spare_size = 19, 148693db446aSBoris Brezillon .pageformat_spare_shift = 16, 148793db446aSBoris Brezillon .nfi_clk_div = 2, 148893db446aSBoris Brezillon .max_sector = 16, 148993db446aSBoris Brezillon .max_sector_size = 1024, 149093db446aSBoris Brezillon }; 149193db446aSBoris Brezillon 149293db446aSBoris Brezillon static const struct mtk_nfc_caps mtk_nfc_caps_mt7622 = { 149393db446aSBoris Brezillon .spare_size = spare_size_mt7622, 149493db446aSBoris Brezillon .num_spare_size = 4, 149593db446aSBoris Brezillon .pageformat_spare_shift = 4, 149693db446aSBoris Brezillon .nfi_clk_div = 1, 149793db446aSBoris Brezillon .max_sector = 8, 149893db446aSBoris Brezillon .max_sector_size = 512, 149993db446aSBoris Brezillon }; 150093db446aSBoris Brezillon 150193db446aSBoris Brezillon static const struct of_device_id mtk_nfc_id_table[] = { 150293db446aSBoris Brezillon { 150393db446aSBoris Brezillon .compatible = "mediatek,mt2701-nfc", 150493db446aSBoris Brezillon .data = &mtk_nfc_caps_mt2701, 150593db446aSBoris Brezillon }, { 150693db446aSBoris Brezillon .compatible = "mediatek,mt2712-nfc", 150793db446aSBoris Brezillon .data = &mtk_nfc_caps_mt2712, 150893db446aSBoris Brezillon }, { 150993db446aSBoris Brezillon .compatible = "mediatek,mt7622-nfc", 151093db446aSBoris Brezillon .data = &mtk_nfc_caps_mt7622, 151193db446aSBoris Brezillon }, 151293db446aSBoris Brezillon {} 151393db446aSBoris Brezillon }; 151493db446aSBoris Brezillon MODULE_DEVICE_TABLE(of, mtk_nfc_id_table); 151593db446aSBoris Brezillon 151693db446aSBoris Brezillon static int mtk_nfc_probe(struct platform_device *pdev) 151793db446aSBoris Brezillon { 151893db446aSBoris Brezillon struct device *dev = &pdev->dev; 151993db446aSBoris Brezillon struct device_node *np = dev->of_node; 152093db446aSBoris Brezillon struct mtk_nfc *nfc; 152193db446aSBoris Brezillon struct resource *res; 152293db446aSBoris Brezillon int ret, irq; 152393db446aSBoris Brezillon 152493db446aSBoris Brezillon nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); 152593db446aSBoris Brezillon if (!nfc) 152693db446aSBoris Brezillon return -ENOMEM; 152793db446aSBoris Brezillon 1528b5c2defcSBoris Brezillon nand_controller_init(&nfc->controller); 152993db446aSBoris Brezillon INIT_LIST_HEAD(&nfc->chips); 15301ce7826dSMiquel Raynal nfc->controller.ops = &mtk_nfc_controller_ops; 153193db446aSBoris Brezillon 153293db446aSBoris Brezillon /* probe defer if not ready */ 153393db446aSBoris Brezillon nfc->ecc = of_mtk_ecc_get(np); 153493db446aSBoris Brezillon if (IS_ERR(nfc->ecc)) 153593db446aSBoris Brezillon return PTR_ERR(nfc->ecc); 153693db446aSBoris Brezillon else if (!nfc->ecc) 153793db446aSBoris Brezillon return -ENODEV; 153893db446aSBoris Brezillon 153936bf2eb9SRyder Lee nfc->caps = of_device_get_match_data(dev); 154093db446aSBoris Brezillon nfc->dev = dev; 154193db446aSBoris Brezillon 154293db446aSBoris Brezillon res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 154393db446aSBoris Brezillon nfc->regs = devm_ioremap_resource(dev, res); 154493db446aSBoris Brezillon if (IS_ERR(nfc->regs)) { 154593db446aSBoris Brezillon ret = PTR_ERR(nfc->regs); 154693db446aSBoris Brezillon goto release_ecc; 154793db446aSBoris Brezillon } 154893db446aSBoris Brezillon 154993db446aSBoris Brezillon nfc->clk.nfi_clk = devm_clk_get(dev, "nfi_clk"); 155093db446aSBoris Brezillon if (IS_ERR(nfc->clk.nfi_clk)) { 155193db446aSBoris Brezillon dev_err(dev, "no clk\n"); 155293db446aSBoris Brezillon ret = PTR_ERR(nfc->clk.nfi_clk); 155393db446aSBoris Brezillon goto release_ecc; 155493db446aSBoris Brezillon } 155593db446aSBoris Brezillon 155693db446aSBoris Brezillon nfc->clk.pad_clk = devm_clk_get(dev, "pad_clk"); 155793db446aSBoris Brezillon if (IS_ERR(nfc->clk.pad_clk)) { 155893db446aSBoris Brezillon dev_err(dev, "no pad clk\n"); 155993db446aSBoris Brezillon ret = PTR_ERR(nfc->clk.pad_clk); 156093db446aSBoris Brezillon goto release_ecc; 156193db446aSBoris Brezillon } 156293db446aSBoris Brezillon 156393db446aSBoris Brezillon ret = mtk_nfc_enable_clk(dev, &nfc->clk); 156493db446aSBoris Brezillon if (ret) 156593db446aSBoris Brezillon goto release_ecc; 156693db446aSBoris Brezillon 156793db446aSBoris Brezillon irq = platform_get_irq(pdev, 0); 156893db446aSBoris Brezillon if (irq < 0) { 156993db446aSBoris Brezillon ret = -EINVAL; 157093db446aSBoris Brezillon goto clk_disable; 157193db446aSBoris Brezillon } 157293db446aSBoris Brezillon 157393db446aSBoris Brezillon ret = devm_request_irq(dev, irq, mtk_nfc_irq, 0x0, "mtk-nand", nfc); 157493db446aSBoris Brezillon if (ret) { 157593db446aSBoris Brezillon dev_err(dev, "failed to request nfi irq\n"); 157693db446aSBoris Brezillon goto clk_disable; 157793db446aSBoris Brezillon } 157893db446aSBoris Brezillon 157993db446aSBoris Brezillon ret = dma_set_mask(dev, DMA_BIT_MASK(32)); 158093db446aSBoris Brezillon if (ret) { 158193db446aSBoris Brezillon dev_err(dev, "failed to set dma mask\n"); 158293db446aSBoris Brezillon goto clk_disable; 158393db446aSBoris Brezillon } 158493db446aSBoris Brezillon 158593db446aSBoris Brezillon platform_set_drvdata(pdev, nfc); 158693db446aSBoris Brezillon 158793db446aSBoris Brezillon ret = mtk_nfc_nand_chips_init(dev, nfc); 158893db446aSBoris Brezillon if (ret) { 158993db446aSBoris Brezillon dev_err(dev, "failed to init nand chips\n"); 159093db446aSBoris Brezillon goto clk_disable; 159193db446aSBoris Brezillon } 159293db446aSBoris Brezillon 159393db446aSBoris Brezillon return 0; 159493db446aSBoris Brezillon 159593db446aSBoris Brezillon clk_disable: 159693db446aSBoris Brezillon mtk_nfc_disable_clk(&nfc->clk); 159793db446aSBoris Brezillon 159893db446aSBoris Brezillon release_ecc: 159993db446aSBoris Brezillon mtk_ecc_release(nfc->ecc); 160093db446aSBoris Brezillon 160193db446aSBoris Brezillon return ret; 160293db446aSBoris Brezillon } 160393db446aSBoris Brezillon 160493db446aSBoris Brezillon static int mtk_nfc_remove(struct platform_device *pdev) 160593db446aSBoris Brezillon { 160693db446aSBoris Brezillon struct mtk_nfc *nfc = platform_get_drvdata(pdev); 16071fec333aSMiquel Raynal struct mtk_nfc_nand_chip *mtk_chip; 16081fec333aSMiquel Raynal struct nand_chip *chip; 16091fec333aSMiquel Raynal int ret; 161093db446aSBoris Brezillon 161193db446aSBoris Brezillon while (!list_empty(&nfc->chips)) { 16121fec333aSMiquel Raynal mtk_chip = list_first_entry(&nfc->chips, 16131fec333aSMiquel Raynal struct mtk_nfc_nand_chip, node); 16141fec333aSMiquel Raynal chip = &mtk_chip->nand; 16151fec333aSMiquel Raynal ret = mtd_device_unregister(nand_to_mtd(chip)); 16161fec333aSMiquel Raynal WARN_ON(ret); 16171fec333aSMiquel Raynal nand_cleanup(chip); 16181fec333aSMiquel Raynal list_del(&mtk_chip->node); 161993db446aSBoris Brezillon } 162093db446aSBoris Brezillon 162193db446aSBoris Brezillon mtk_ecc_release(nfc->ecc); 162293db446aSBoris Brezillon mtk_nfc_disable_clk(&nfc->clk); 162393db446aSBoris Brezillon 162493db446aSBoris Brezillon return 0; 162593db446aSBoris Brezillon } 162693db446aSBoris Brezillon 162793db446aSBoris Brezillon #ifdef CONFIG_PM_SLEEP 162893db446aSBoris Brezillon static int mtk_nfc_suspend(struct device *dev) 162993db446aSBoris Brezillon { 163093db446aSBoris Brezillon struct mtk_nfc *nfc = dev_get_drvdata(dev); 163193db446aSBoris Brezillon 163293db446aSBoris Brezillon mtk_nfc_disable_clk(&nfc->clk); 163393db446aSBoris Brezillon 163493db446aSBoris Brezillon return 0; 163593db446aSBoris Brezillon } 163693db446aSBoris Brezillon 163793db446aSBoris Brezillon static int mtk_nfc_resume(struct device *dev) 163893db446aSBoris Brezillon { 163993db446aSBoris Brezillon struct mtk_nfc *nfc = dev_get_drvdata(dev); 164093db446aSBoris Brezillon struct mtk_nfc_nand_chip *chip; 164193db446aSBoris Brezillon struct nand_chip *nand; 164293db446aSBoris Brezillon int ret; 164393db446aSBoris Brezillon u32 i; 164493db446aSBoris Brezillon 164593db446aSBoris Brezillon udelay(200); 164693db446aSBoris Brezillon 164793db446aSBoris Brezillon ret = mtk_nfc_enable_clk(dev, &nfc->clk); 164893db446aSBoris Brezillon if (ret) 164993db446aSBoris Brezillon return ret; 165093db446aSBoris Brezillon 165193db446aSBoris Brezillon /* reset NAND chip if VCC was powered off */ 165293db446aSBoris Brezillon list_for_each_entry(chip, &nfc->chips, node) { 165393db446aSBoris Brezillon nand = &chip->nand; 165493db446aSBoris Brezillon for (i = 0; i < chip->nsels; i++) 165593db446aSBoris Brezillon nand_reset(nand, i); 165693db446aSBoris Brezillon } 165793db446aSBoris Brezillon 165893db446aSBoris Brezillon return 0; 165993db446aSBoris Brezillon } 166093db446aSBoris Brezillon 166193db446aSBoris Brezillon static SIMPLE_DEV_PM_OPS(mtk_nfc_pm_ops, mtk_nfc_suspend, mtk_nfc_resume); 166293db446aSBoris Brezillon #endif 166393db446aSBoris Brezillon 166493db446aSBoris Brezillon static struct platform_driver mtk_nfc_driver = { 166593db446aSBoris Brezillon .probe = mtk_nfc_probe, 166693db446aSBoris Brezillon .remove = mtk_nfc_remove, 166793db446aSBoris Brezillon .driver = { 166893db446aSBoris Brezillon .name = MTK_NAME, 166993db446aSBoris Brezillon .of_match_table = mtk_nfc_id_table, 167093db446aSBoris Brezillon #ifdef CONFIG_PM_SLEEP 167193db446aSBoris Brezillon .pm = &mtk_nfc_pm_ops, 167293db446aSBoris Brezillon #endif 167393db446aSBoris Brezillon }, 167493db446aSBoris Brezillon }; 167593db446aSBoris Brezillon 167693db446aSBoris Brezillon module_platform_driver(mtk_nfc_driver); 167793db446aSBoris Brezillon 1678b74e6985SXiaolei Li MODULE_LICENSE("Dual MIT/GPL"); 167993db446aSBoris Brezillon MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>"); 168093db446aSBoris Brezillon MODULE_DESCRIPTION("MTK Nand Flash Controller Driver"); 1681