brintos

brintos / linux-shallow public Read only

0
0
Text · 23.2 KiB · fe291a2 Raw
870 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Hisilicon NAND Flash controller driver4 *5 * Copyright © 2012-2014 HiSilicon Technologies Co., Ltd.6 *              http://www.hisilicon.com7 *8 * Author: Zhou Wang <wangzhou.bry@gmail.com>9 * The initial developer of the original code is Zhiyong Cai10 * <caizhiyong@huawei.com>11 */12#include <linux/of.h>13#include <linux/mtd/mtd.h>14#include <linux/sizes.h>15#include <linux/clk.h>16#include <linux/slab.h>17#include <linux/module.h>18#include <linux/delay.h>19#include <linux/interrupt.h>20#include <linux/mtd/rawnand.h>21#include <linux/dma-mapping.h>22#include <linux/platform_device.h>23#include <linux/mtd/partitions.h>24 25#define HINFC504_MAX_CHIP                               (4)26#define HINFC504_W_LATCH                                (5)27#define HINFC504_R_LATCH                                (7)28#define HINFC504_RW_LATCH                               (3)29 30#define HINFC504_NFC_TIMEOUT				(2 * HZ)31#define HINFC504_NFC_PM_TIMEOUT				(1 * HZ)32#define HINFC504_NFC_DMA_TIMEOUT			(5 * HZ)33#define HINFC504_CHIP_DELAY				(25)34 35#define HINFC504_REG_BASE_ADDRESS_LEN			(0x100)36#define HINFC504_BUFFER_BASE_ADDRESS_LEN		(2048 + 128)37 38#define HINFC504_ADDR_CYCLE_MASK			0x439 40#define HINFC504_CON					0x0041#define HINFC504_CON_OP_MODE_NORMAL			BIT(0)42#define HINFC504_CON_PAGEISZE_SHIFT			(1)43#define HINFC504_CON_PAGESIZE_MASK			(0x07)44#define HINFC504_CON_BUS_WIDTH				BIT(4)45#define HINFC504_CON_READY_BUSY_SEL			BIT(8)46#define HINFC504_CON_ECCTYPE_SHIFT			(9)47#define HINFC504_CON_ECCTYPE_MASK			(0x07)48 49#define HINFC504_PWIDTH					0x0450#define SET_HINFC504_PWIDTH(_w_lcnt, _r_lcnt, _rw_hcnt) \51	((_w_lcnt) | (((_r_lcnt) & 0x0F) << 4) | (((_rw_hcnt) & 0x0F) << 8))52 53#define HINFC504_CMD					0x0C54#define HINFC504_ADDRL					0x1055#define HINFC504_ADDRH					0x1456#define HINFC504_DATA_NUM				0x1857 58#define HINFC504_OP					0x1C59#define HINFC504_OP_READ_DATA_EN			BIT(1)60#define HINFC504_OP_WAIT_READY_EN			BIT(2)61#define HINFC504_OP_CMD2_EN				BIT(3)62#define HINFC504_OP_WRITE_DATA_EN			BIT(4)63#define HINFC504_OP_ADDR_EN				BIT(5)64#define HINFC504_OP_CMD1_EN				BIT(6)65#define HINFC504_OP_NF_CS_SHIFT                         (7)66#define HINFC504_OP_NF_CS_MASK				(3)67#define HINFC504_OP_ADDR_CYCLE_SHIFT			(9)68#define HINFC504_OP_ADDR_CYCLE_MASK			(7)69 70#define HINFC504_STATUS                                 0x2071#define HINFC504_READY					BIT(0)72 73#define HINFC504_INTEN					0x2474#define HINFC504_INTEN_DMA				BIT(9)75#define HINFC504_INTEN_UE				BIT(6)76#define HINFC504_INTEN_CE				BIT(5)77 78#define HINFC504_INTS					0x2879#define HINFC504_INTS_DMA				BIT(9)80#define HINFC504_INTS_UE				BIT(6)81#define HINFC504_INTS_CE				BIT(5)82 83#define HINFC504_INTCLR                                 0x2C84#define HINFC504_INTCLR_DMA				BIT(9)85#define HINFC504_INTCLR_UE				BIT(6)86#define HINFC504_INTCLR_CE				BIT(5)87 88#define HINFC504_ECC_STATUS                             0x5C89#define HINFC504_ECC_16_BIT_SHIFT                       1290 91#define HINFC504_DMA_CTRL				0x6092#define HINFC504_DMA_CTRL_DMA_START			BIT(0)93#define HINFC504_DMA_CTRL_WE				BIT(1)94#define HINFC504_DMA_CTRL_DATA_AREA_EN			BIT(2)95#define HINFC504_DMA_CTRL_OOB_AREA_EN			BIT(3)96#define HINFC504_DMA_CTRL_BURST4_EN			BIT(4)97#define HINFC504_DMA_CTRL_BURST8_EN			BIT(5)98#define HINFC504_DMA_CTRL_BURST16_EN			BIT(6)99#define HINFC504_DMA_CTRL_ADDR_NUM_SHIFT		(7)100#define HINFC504_DMA_CTRL_ADDR_NUM_MASK                 (1)101#define HINFC504_DMA_CTRL_CS_SHIFT			(8)102#define HINFC504_DMA_CTRL_CS_MASK			(0x03)103 104#define HINFC504_DMA_ADDR_DATA				0x64105#define HINFC504_DMA_ADDR_OOB				0x68106 107#define HINFC504_DMA_LEN				0x6C108#define HINFC504_DMA_LEN_OOB_SHIFT			(16)109#define HINFC504_DMA_LEN_OOB_MASK			(0xFFF)110 111#define HINFC504_DMA_PARA				0x70112#define HINFC504_DMA_PARA_DATA_RW_EN			BIT(0)113#define HINFC504_DMA_PARA_OOB_RW_EN			BIT(1)114#define HINFC504_DMA_PARA_DATA_EDC_EN			BIT(2)115#define HINFC504_DMA_PARA_OOB_EDC_EN			BIT(3)116#define HINFC504_DMA_PARA_DATA_ECC_EN			BIT(4)117#define HINFC504_DMA_PARA_OOB_ECC_EN			BIT(5)118 119#define HINFC_VERSION                                   0x74120#define HINFC504_LOG_READ_ADDR				0x7C121#define HINFC504_LOG_READ_LEN				0x80122 123#define HINFC504_NANDINFO_LEN				0x10124 125struct hinfc_host {126	struct nand_chip	chip;127	struct device		*dev;128	void __iomem		*iobase;129	void __iomem		*mmio;130	struct completion       cmd_complete;131	unsigned int		offset;132	unsigned int		command;133	int			chipselect;134	unsigned int		addr_cycle;135	u32                     addr_value[2];136	u32                     cache_addr_value[2];137	char			*buffer;138	dma_addr_t		dma_buffer;139	dma_addr_t		dma_oob;140	int			version;141	unsigned int            irq_status; /* interrupt status */142};143 144static inline unsigned int hinfc_read(struct hinfc_host *host, unsigned int reg)145{146	return readl(host->iobase + reg);147}148 149static inline void hinfc_write(struct hinfc_host *host, unsigned int value,150			       unsigned int reg)151{152	writel(value, host->iobase + reg);153}154 155static void wait_controller_finished(struct hinfc_host *host)156{157	unsigned long timeout = jiffies + HINFC504_NFC_TIMEOUT;158	int val;159 160	while (time_before(jiffies, timeout)) {161		val = hinfc_read(host, HINFC504_STATUS);162		if (host->command == NAND_CMD_ERASE2) {163			/* nfc is ready */164			while (!(val & HINFC504_READY))	{165				usleep_range(500, 1000);166				val = hinfc_read(host, HINFC504_STATUS);167			}168			return;169		}170 171		if (val & HINFC504_READY)172			return;173	}174 175	/* wait cmd timeout */176	dev_err(host->dev, "Wait NAND controller exec cmd timeout.\n");177}178 179static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev)180{181	struct nand_chip *chip = &host->chip;182	struct mtd_info	*mtd = nand_to_mtd(chip);183	unsigned long val;184	int ret;185 186	hinfc_write(host, host->dma_buffer, HINFC504_DMA_ADDR_DATA);187	hinfc_write(host, host->dma_oob, HINFC504_DMA_ADDR_OOB);188 189	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_NONE) {190		hinfc_write(host, ((mtd->oobsize & HINFC504_DMA_LEN_OOB_MASK)191			<< HINFC504_DMA_LEN_OOB_SHIFT), HINFC504_DMA_LEN);192 193		hinfc_write(host, HINFC504_DMA_PARA_DATA_RW_EN194			| HINFC504_DMA_PARA_OOB_RW_EN, HINFC504_DMA_PARA);195	} else {196		if (host->command == NAND_CMD_READOOB)197			hinfc_write(host, HINFC504_DMA_PARA_OOB_RW_EN198			| HINFC504_DMA_PARA_OOB_EDC_EN199			| HINFC504_DMA_PARA_OOB_ECC_EN, HINFC504_DMA_PARA);200		else201			hinfc_write(host, HINFC504_DMA_PARA_DATA_RW_EN202			| HINFC504_DMA_PARA_OOB_RW_EN203			| HINFC504_DMA_PARA_DATA_EDC_EN204			| HINFC504_DMA_PARA_OOB_EDC_EN205			| HINFC504_DMA_PARA_DATA_ECC_EN206			| HINFC504_DMA_PARA_OOB_ECC_EN, HINFC504_DMA_PARA);207 208	}209 210	val = (HINFC504_DMA_CTRL_DMA_START | HINFC504_DMA_CTRL_BURST4_EN211		| HINFC504_DMA_CTRL_BURST8_EN | HINFC504_DMA_CTRL_BURST16_EN212		| HINFC504_DMA_CTRL_DATA_AREA_EN | HINFC504_DMA_CTRL_OOB_AREA_EN213		| ((host->addr_cycle == 4 ? 1 : 0)214			<< HINFC504_DMA_CTRL_ADDR_NUM_SHIFT)215		| ((host->chipselect & HINFC504_DMA_CTRL_CS_MASK)216			<< HINFC504_DMA_CTRL_CS_SHIFT));217 218	if (todev)219		val |= HINFC504_DMA_CTRL_WE;220 221	init_completion(&host->cmd_complete);222 223	hinfc_write(host, val, HINFC504_DMA_CTRL);224	ret = wait_for_completion_timeout(&host->cmd_complete,225			HINFC504_NFC_DMA_TIMEOUT);226 227	if (!ret) {228		dev_err(host->dev, "DMA operation(irq) timeout!\n");229		/* sanity check */230		val = hinfc_read(host, HINFC504_DMA_CTRL);231		if (!(val & HINFC504_DMA_CTRL_DMA_START))232			dev_err(host->dev, "DMA is already done but without irq ACK!\n");233		else234			dev_err(host->dev, "DMA is really timeout!\n");235	}236}237 238static int hisi_nfc_send_cmd_pageprog(struct hinfc_host *host)239{240	host->addr_value[0] &= 0xffff0000;241 242	hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);243	hinfc_write(host, host->addr_value[1], HINFC504_ADDRH);244	hinfc_write(host, NAND_CMD_PAGEPROG << 8 | NAND_CMD_SEQIN,245		    HINFC504_CMD);246 247	hisi_nfc_dma_transfer(host, 1);248 249	return 0;250}251 252static int hisi_nfc_send_cmd_readstart(struct hinfc_host *host)253{254	struct mtd_info	*mtd = nand_to_mtd(&host->chip);255 256	if ((host->addr_value[0] == host->cache_addr_value[0]) &&257	    (host->addr_value[1] == host->cache_addr_value[1]))258		return 0;259 260	host->addr_value[0] &= 0xffff0000;261 262	hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);263	hinfc_write(host, host->addr_value[1], HINFC504_ADDRH);264	hinfc_write(host, NAND_CMD_READSTART << 8 | NAND_CMD_READ0,265		    HINFC504_CMD);266 267	hinfc_write(host, 0, HINFC504_LOG_READ_ADDR);268	hinfc_write(host, mtd->writesize + mtd->oobsize,269		    HINFC504_LOG_READ_LEN);270 271	hisi_nfc_dma_transfer(host, 0);272 273	host->cache_addr_value[0] = host->addr_value[0];274	host->cache_addr_value[1] = host->addr_value[1];275 276	return 0;277}278 279static int hisi_nfc_send_cmd_erase(struct hinfc_host *host)280{281	hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);282	hinfc_write(host, (NAND_CMD_ERASE2 << 8) | NAND_CMD_ERASE1,283		    HINFC504_CMD);284 285	hinfc_write(host, HINFC504_OP_WAIT_READY_EN286		| HINFC504_OP_CMD2_EN287		| HINFC504_OP_CMD1_EN288		| HINFC504_OP_ADDR_EN289		| ((host->chipselect & HINFC504_OP_NF_CS_MASK)290			<< HINFC504_OP_NF_CS_SHIFT)291		| ((host->addr_cycle & HINFC504_OP_ADDR_CYCLE_MASK)292			<< HINFC504_OP_ADDR_CYCLE_SHIFT),293		HINFC504_OP);294 295	wait_controller_finished(host);296 297	return 0;298}299 300static int hisi_nfc_send_cmd_readid(struct hinfc_host *host)301{302	hinfc_write(host, HINFC504_NANDINFO_LEN, HINFC504_DATA_NUM);303	hinfc_write(host, NAND_CMD_READID, HINFC504_CMD);304	hinfc_write(host, 0, HINFC504_ADDRL);305 306	hinfc_write(host, HINFC504_OP_CMD1_EN | HINFC504_OP_ADDR_EN307		| HINFC504_OP_READ_DATA_EN308		| ((host->chipselect & HINFC504_OP_NF_CS_MASK)309			<< HINFC504_OP_NF_CS_SHIFT)310		| 1 << HINFC504_OP_ADDR_CYCLE_SHIFT, HINFC504_OP);311 312	wait_controller_finished(host);313 314	return 0;315}316 317static int hisi_nfc_send_cmd_status(struct hinfc_host *host)318{319	hinfc_write(host, HINFC504_NANDINFO_LEN, HINFC504_DATA_NUM);320	hinfc_write(host, NAND_CMD_STATUS, HINFC504_CMD);321	hinfc_write(host, HINFC504_OP_CMD1_EN322		| HINFC504_OP_READ_DATA_EN323		| ((host->chipselect & HINFC504_OP_NF_CS_MASK)324			<< HINFC504_OP_NF_CS_SHIFT),325		HINFC504_OP);326 327	wait_controller_finished(host);328 329	return 0;330}331 332static int hisi_nfc_send_cmd_reset(struct hinfc_host *host, int chipselect)333{334	hinfc_write(host, NAND_CMD_RESET, HINFC504_CMD);335 336	hinfc_write(host, HINFC504_OP_CMD1_EN337		| ((chipselect & HINFC504_OP_NF_CS_MASK)338			<< HINFC504_OP_NF_CS_SHIFT)339		| HINFC504_OP_WAIT_READY_EN,340		HINFC504_OP);341 342	wait_controller_finished(host);343 344	return 0;345}346 347static void hisi_nfc_select_chip(struct nand_chip *chip, int chipselect)348{349	struct hinfc_host *host = nand_get_controller_data(chip);350 351	if (chipselect < 0)352		return;353 354	host->chipselect = chipselect;355}356 357static uint8_t hisi_nfc_read_byte(struct nand_chip *chip)358{359	struct hinfc_host *host = nand_get_controller_data(chip);360 361	if (host->command == NAND_CMD_STATUS)362		return *(uint8_t *)(host->mmio);363 364	host->offset++;365 366	if (host->command == NAND_CMD_READID)367		return *(uint8_t *)(host->mmio + host->offset - 1);368 369	return *(uint8_t *)(host->buffer + host->offset - 1);370}371 372static void373hisi_nfc_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)374{375	struct hinfc_host *host = nand_get_controller_data(chip);376 377	memcpy(host->buffer + host->offset, buf, len);378	host->offset += len;379}380 381static void hisi_nfc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)382{383	struct hinfc_host *host = nand_get_controller_data(chip);384 385	memcpy(buf, host->buffer + host->offset, len);386	host->offset += len;387}388 389static void set_addr(struct mtd_info *mtd, int column, int page_addr)390{391	struct nand_chip *chip = mtd_to_nand(mtd);392	struct hinfc_host *host = nand_get_controller_data(chip);393	unsigned int command = host->command;394 395	host->addr_cycle    = 0;396	host->addr_value[0] = 0;397	host->addr_value[1] = 0;398 399	/* Serially input address */400	if (column != -1) {401		/* Adjust columns for 16 bit buswidth */402		if (chip->options & NAND_BUSWIDTH_16 &&403				!nand_opcode_8bits(command))404			column >>= 1;405 406		host->addr_value[0] = column & 0xffff;407		host->addr_cycle    = 2;408	}409	if (page_addr != -1) {410		host->addr_value[0] |= (page_addr & 0xffff)411			<< (host->addr_cycle * 8);412		host->addr_cycle    += 2;413		if (chip->options & NAND_ROW_ADDR_3) {414			host->addr_cycle += 1;415			if (host->command == NAND_CMD_ERASE1)416				host->addr_value[0] |= ((page_addr >> 16) & 0xff) << 16;417			else418				host->addr_value[1] |= ((page_addr >> 16) & 0xff);419		}420	}421}422 423static void hisi_nfc_cmdfunc(struct nand_chip *chip, unsigned command,424			     int column, int page_addr)425{426	struct mtd_info *mtd = nand_to_mtd(chip);427	struct hinfc_host *host = nand_get_controller_data(chip);428	int is_cache_invalid = 1;429	unsigned int flag = 0;430 431	host->command =  command;432 433	switch (command) {434	case NAND_CMD_READ0:435	case NAND_CMD_READOOB:436		if (command == NAND_CMD_READ0)437			host->offset = column;438		else439			host->offset = column + mtd->writesize;440 441		is_cache_invalid = 0;442		set_addr(mtd, column, page_addr);443		hisi_nfc_send_cmd_readstart(host);444		break;445 446	case NAND_CMD_SEQIN:447		host->offset = column;448		set_addr(mtd, column, page_addr);449		break;450 451	case NAND_CMD_ERASE1:452		set_addr(mtd, column, page_addr);453		break;454 455	case NAND_CMD_PAGEPROG:456		hisi_nfc_send_cmd_pageprog(host);457		break;458 459	case NAND_CMD_ERASE2:460		hisi_nfc_send_cmd_erase(host);461		break;462 463	case NAND_CMD_READID:464		host->offset = column;465		memset(host->mmio, 0, 0x10);466		hisi_nfc_send_cmd_readid(host);467		break;468 469	case NAND_CMD_STATUS:470		flag = hinfc_read(host, HINFC504_CON);471		if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)472			hinfc_write(host,473				    flag & ~(HINFC504_CON_ECCTYPE_MASK <<474				    HINFC504_CON_ECCTYPE_SHIFT), HINFC504_CON);475 476		host->offset = 0;477		memset(host->mmio, 0, 0x10);478		hisi_nfc_send_cmd_status(host);479		hinfc_write(host, flag, HINFC504_CON);480		break;481 482	case NAND_CMD_RESET:483		hisi_nfc_send_cmd_reset(host, host->chipselect);484		break;485 486	default:487		dev_err(host->dev, "Error: unsupported cmd(cmd=%x, col=%x, page=%x)\n",488			command, column, page_addr);489	}490 491	if (is_cache_invalid) {492		host->cache_addr_value[0] = ~0;493		host->cache_addr_value[1] = ~0;494	}495}496 497static irqreturn_t hinfc_irq_handle(int irq, void *devid)498{499	struct hinfc_host *host = devid;500	unsigned int flag;501 502	flag = hinfc_read(host, HINFC504_INTS);503	/* store interrupts state */504	host->irq_status |= flag;505 506	if (flag & HINFC504_INTS_DMA) {507		hinfc_write(host, HINFC504_INTCLR_DMA, HINFC504_INTCLR);508		complete(&host->cmd_complete);509	} else if (flag & HINFC504_INTS_CE) {510		hinfc_write(host, HINFC504_INTCLR_CE, HINFC504_INTCLR);511	} else if (flag & HINFC504_INTS_UE) {512		hinfc_write(host, HINFC504_INTCLR_UE, HINFC504_INTCLR);513	}514 515	return IRQ_HANDLED;516}517 518static int hisi_nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,519				     int oob_required, int page)520{521	struct mtd_info *mtd = nand_to_mtd(chip);522	struct hinfc_host *host = nand_get_controller_data(chip);523	int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc;524	int stat_1, stat_2;525 526	nand_read_page_op(chip, page, 0, buf, mtd->writesize);527	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);528 529	/* errors which can not be corrected by ECC */530	if (host->irq_status & HINFC504_INTS_UE) {531		mtd->ecc_stats.failed++;532	} else if (host->irq_status & HINFC504_INTS_CE) {533		/* TODO: need add other ECC modes! */534		switch (chip->ecc.strength) {535		case 16:536			status_ecc = hinfc_read(host, HINFC504_ECC_STATUS) >>537					HINFC504_ECC_16_BIT_SHIFT & 0x0fff;538			stat_2 = status_ecc & 0x3f;539			stat_1 = status_ecc >> 6 & 0x3f;540			stat = stat_1 + stat_2;541			stat_max = max_t(int, stat_1, stat_2);542		}543		mtd->ecc_stats.corrected += stat;544		max_bitflips = max_t(int, max_bitflips, stat_max);545	}546	host->irq_status = 0;547 548	return max_bitflips;549}550 551static int hisi_nand_read_oob(struct nand_chip *chip, int page)552{553	struct mtd_info *mtd = nand_to_mtd(chip);554	struct hinfc_host *host = nand_get_controller_data(chip);555 556	nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);557 558	if (host->irq_status & HINFC504_INTS_UE) {559		host->irq_status = 0;560		return -EBADMSG;561	}562 563	host->irq_status = 0;564	return 0;565}566 567static int hisi_nand_write_page_hwecc(struct nand_chip *chip,568				      const uint8_t *buf, int oob_required,569				      int page)570{571	struct mtd_info *mtd = nand_to_mtd(chip);572 573	nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);574	if (oob_required)575		chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);576 577	return nand_prog_page_end_op(chip);578}579 580static void hisi_nfc_host_init(struct hinfc_host *host)581{582	struct nand_chip *chip = &host->chip;583	unsigned int flag = 0;584 585	host->version = hinfc_read(host, HINFC_VERSION);586	host->addr_cycle		= 0;587	host->addr_value[0]		= 0;588	host->addr_value[1]		= 0;589	host->cache_addr_value[0]	= ~0;590	host->cache_addr_value[1]	= ~0;591	host->chipselect		= 0;592 593	/* default page size: 2K, ecc_none. need modify */594	flag = HINFC504_CON_OP_MODE_NORMAL | HINFC504_CON_READY_BUSY_SEL595		| ((0x001 & HINFC504_CON_PAGESIZE_MASK)596			<< HINFC504_CON_PAGEISZE_SHIFT)597		| ((0x0 & HINFC504_CON_ECCTYPE_MASK)598			<< HINFC504_CON_ECCTYPE_SHIFT)599		| ((chip->options & NAND_BUSWIDTH_16) ?600			HINFC504_CON_BUS_WIDTH : 0);601	hinfc_write(host, flag, HINFC504_CON);602 603	memset(host->mmio, 0xff, HINFC504_BUFFER_BASE_ADDRESS_LEN);604 605	hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,606		    HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);607 608	/* enable DMA irq */609	hinfc_write(host, HINFC504_INTEN_DMA, HINFC504_INTEN);610}611 612static int hisi_ooblayout_ecc(struct mtd_info *mtd, int section,613			      struct mtd_oob_region *oobregion)614{615	/* FIXME: add ECC bytes position */616	return -ENOTSUPP;617}618 619static int hisi_ooblayout_free(struct mtd_info *mtd, int section,620			       struct mtd_oob_region *oobregion)621{622	if (section)623		return -ERANGE;624 625	oobregion->offset = 2;626	oobregion->length = 6;627 628	return 0;629}630 631static const struct mtd_ooblayout_ops hisi_ooblayout_ops = {632	.ecc = hisi_ooblayout_ecc,633	.free = hisi_ooblayout_free,634};635 636static int hisi_nfc_ecc_probe(struct hinfc_host *host)637{638	unsigned int flag;639	int size, strength, ecc_bits;640	struct device *dev = host->dev;641	struct nand_chip *chip = &host->chip;642	struct mtd_info *mtd = nand_to_mtd(chip);643 644	size = chip->ecc.size;645	strength = chip->ecc.strength;646	if (size != 1024) {647		dev_err(dev, "error ecc size: %d\n", size);648		return -EINVAL;649	}650 651	if ((size == 1024) && ((strength != 8) && (strength != 16) &&652				(strength != 24) && (strength != 40))) {653		dev_err(dev, "ecc size and strength do not match\n");654		return -EINVAL;655	}656 657	chip->ecc.size = size;658	chip->ecc.strength = strength;659 660	chip->ecc.read_page = hisi_nand_read_page_hwecc;661	chip->ecc.read_oob = hisi_nand_read_oob;662	chip->ecc.write_page = hisi_nand_write_page_hwecc;663 664	switch (chip->ecc.strength) {665	case 16:666		ecc_bits = 6;667		if (mtd->writesize == 2048)668			mtd_set_ooblayout(mtd, &hisi_ooblayout_ops);669 670		/* TODO: add more page size support */671		break;672 673	/* TODO: add more ecc strength support */674	default:675		dev_err(dev, "not support strength: %d\n", chip->ecc.strength);676		return -EINVAL;677	}678 679	flag = hinfc_read(host, HINFC504_CON);680	/* add ecc type configure */681	flag |= ((ecc_bits & HINFC504_CON_ECCTYPE_MASK)682						<< HINFC504_CON_ECCTYPE_SHIFT);683	hinfc_write(host, flag, HINFC504_CON);684 685	/* enable ecc irq */686	flag = hinfc_read(host, HINFC504_INTEN) & 0xfff;687	hinfc_write(host, flag | HINFC504_INTEN_UE | HINFC504_INTEN_CE,688		    HINFC504_INTEN);689 690	return 0;691}692 693static int hisi_nfc_attach_chip(struct nand_chip *chip)694{695	struct mtd_info *mtd = nand_to_mtd(chip);696	struct hinfc_host *host = nand_get_controller_data(chip);697	int flag;698 699	host->buffer = dmam_alloc_coherent(host->dev,700					   mtd->writesize + mtd->oobsize,701					   &host->dma_buffer, GFP_KERNEL);702	if (!host->buffer)703		return -ENOMEM;704 705	host->dma_oob = host->dma_buffer + mtd->writesize;706	memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize);707 708	flag = hinfc_read(host, HINFC504_CON);709	flag &= ~(HINFC504_CON_PAGESIZE_MASK << HINFC504_CON_PAGEISZE_SHIFT);710	switch (mtd->writesize) {711	case 2048:712		flag |= (0x001 << HINFC504_CON_PAGEISZE_SHIFT);713		break;714	/*715	 * TODO: add more pagesize support,716	 * default pagesize has been set in hisi_nfc_host_init717	 */718	default:719		dev_err(host->dev, "NON-2KB page size nand flash\n");720		return -EINVAL;721	}722	hinfc_write(host, flag, HINFC504_CON);723 724	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)725		hisi_nfc_ecc_probe(host);726 727	return 0;728}729 730static const struct nand_controller_ops hisi_nfc_controller_ops = {731	.attach_chip = hisi_nfc_attach_chip,732};733 734static int hisi_nfc_probe(struct platform_device *pdev)735{736	int ret = 0, irq, max_chips = HINFC504_MAX_CHIP;737	struct device *dev = &pdev->dev;738	struct hinfc_host *host;739	struct nand_chip  *chip;740	struct mtd_info   *mtd;741	struct device_node *np = dev->of_node;742 743	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);744	if (!host)745		return -ENOMEM;746	host->dev = dev;747 748	platform_set_drvdata(pdev, host);749	chip = &host->chip;750	mtd  = nand_to_mtd(chip);751 752	irq = platform_get_irq(pdev, 0);753	if (irq < 0)754		return -ENXIO;755 756	host->iobase = devm_platform_ioremap_resource(pdev, 0);757	if (IS_ERR(host->iobase))758		return PTR_ERR(host->iobase);759 760	host->mmio = devm_platform_ioremap_resource(pdev, 1);761	if (IS_ERR(host->mmio))762		return PTR_ERR(host->mmio);763 764	mtd->name		= "hisi_nand";765	mtd->dev.parent         = &pdev->dev;766 767	nand_set_controller_data(chip, host);768	nand_set_flash_node(chip, np);769	chip->legacy.cmdfunc	= hisi_nfc_cmdfunc;770	chip->legacy.select_chip	= hisi_nfc_select_chip;771	chip->legacy.read_byte	= hisi_nfc_read_byte;772	chip->legacy.write_buf	= hisi_nfc_write_buf;773	chip->legacy.read_buf	= hisi_nfc_read_buf;774	chip->legacy.chip_delay	= HINFC504_CHIP_DELAY;775	chip->legacy.set_features	= nand_get_set_features_notsupp;776	chip->legacy.get_features	= nand_get_set_features_notsupp;777 778	hisi_nfc_host_init(host);779 780	ret = devm_request_irq(dev, irq, hinfc_irq_handle, 0x0, "nandc", host);781	if (ret) {782		dev_err(dev, "failed to request IRQ\n");783		return ret;784	}785 786	chip->legacy.dummy_controller.ops = &hisi_nfc_controller_ops;787	ret = nand_scan(chip, max_chips);788	if (ret)789		return ret;790 791	ret = mtd_device_register(mtd, NULL, 0);792	if (ret) {793		dev_err(dev, "Err MTD partition=%d\n", ret);794		nand_cleanup(chip);795		return ret;796	}797 798	return 0;799}800 801static void hisi_nfc_remove(struct platform_device *pdev)802{803	struct hinfc_host *host = platform_get_drvdata(pdev);804	struct nand_chip *chip = &host->chip;805	int ret;806 807	ret = mtd_device_unregister(nand_to_mtd(chip));808	WARN_ON(ret);809	nand_cleanup(chip);810}811 812#ifdef CONFIG_PM_SLEEP813static int hisi_nfc_suspend(struct device *dev)814{815	struct hinfc_host *host = dev_get_drvdata(dev);816	unsigned long timeout = jiffies + HINFC504_NFC_PM_TIMEOUT;817 818	while (time_before(jiffies, timeout)) {819		if (((hinfc_read(host, HINFC504_STATUS) & 0x1) == 0x0) &&820		    (hinfc_read(host, HINFC504_DMA_CTRL) &821		     HINFC504_DMA_CTRL_DMA_START)) {822			cond_resched();823			return 0;824		}825	}826 827	dev_err(host->dev, "nand controller suspend timeout.\n");828 829	return -EAGAIN;830}831 832static int hisi_nfc_resume(struct device *dev)833{834	int cs;835	struct hinfc_host *host = dev_get_drvdata(dev);836	struct nand_chip *chip = &host->chip;837 838	for (cs = 0; cs < nanddev_ntargets(&chip->base); cs++)839		hisi_nfc_send_cmd_reset(host, cs);840	hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,841		    HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);842 843	return 0;844}845#endif846static SIMPLE_DEV_PM_OPS(hisi_nfc_pm_ops, hisi_nfc_suspend, hisi_nfc_resume);847 848static const struct of_device_id nfc_id_table[] = {849	{ .compatible = "hisilicon,504-nfc" },850	{}851};852MODULE_DEVICE_TABLE(of, nfc_id_table);853 854static struct platform_driver hisi_nfc_driver = {855	.driver = {856		.name  = "hisi_nand",857		.of_match_table = nfc_id_table,858		.pm = &hisi_nfc_pm_ops,859	},860	.probe		= hisi_nfc_probe,861	.remove_new	= hisi_nfc_remove,862};863 864module_platform_driver(hisi_nfc_driver);865 866MODULE_LICENSE("GPL");867MODULE_AUTHOR("Zhou Wang");868MODULE_AUTHOR("Zhiyong Cai");869MODULE_DESCRIPTION("Hisilicon Nand Flash Controller Driver");870