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