18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * SuperH FLCTL nand controller 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright © 2008 Renesas Solutions Corp. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef __SH_FLCTL_H__ 98c2ecf20Sopenharmony_ci#define __SH_FLCTL_H__ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/completion.h> 128c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 138c2ecf20Sopenharmony_ci#include <linux/mtd/rawnand.h> 148c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 158c2ecf20Sopenharmony_ci#include <linux/pm_qos.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* FLCTL registers */ 188c2ecf20Sopenharmony_ci#define FLCMNCR(f) (f->reg + 0x0) 198c2ecf20Sopenharmony_ci#define FLCMDCR(f) (f->reg + 0x4) 208c2ecf20Sopenharmony_ci#define FLCMCDR(f) (f->reg + 0x8) 218c2ecf20Sopenharmony_ci#define FLADR(f) (f->reg + 0xC) 228c2ecf20Sopenharmony_ci#define FLADR2(f) (f->reg + 0x3C) 238c2ecf20Sopenharmony_ci#define FLDATAR(f) (f->reg + 0x10) 248c2ecf20Sopenharmony_ci#define FLDTCNTR(f) (f->reg + 0x14) 258c2ecf20Sopenharmony_ci#define FLINTDMACR(f) (f->reg + 0x18) 268c2ecf20Sopenharmony_ci#define FLBSYTMR(f) (f->reg + 0x1C) 278c2ecf20Sopenharmony_ci#define FLBSYCNT(f) (f->reg + 0x20) 288c2ecf20Sopenharmony_ci#define FLDTFIFO(f) (f->reg + 0x24) 298c2ecf20Sopenharmony_ci#define FLECFIFO(f) (f->reg + 0x28) 308c2ecf20Sopenharmony_ci#define FLTRCR(f) (f->reg + 0x2C) 318c2ecf20Sopenharmony_ci#define FLHOLDCR(f) (f->reg + 0x38) 328c2ecf20Sopenharmony_ci#define FL4ECCRESULT0(f) (f->reg + 0x80) 338c2ecf20Sopenharmony_ci#define FL4ECCRESULT1(f) (f->reg + 0x84) 348c2ecf20Sopenharmony_ci#define FL4ECCRESULT2(f) (f->reg + 0x88) 358c2ecf20Sopenharmony_ci#define FL4ECCRESULT3(f) (f->reg + 0x8C) 368c2ecf20Sopenharmony_ci#define FL4ECCCR(f) (f->reg + 0x90) 378c2ecf20Sopenharmony_ci#define FL4ECCCNT(f) (f->reg + 0x94) 388c2ecf20Sopenharmony_ci#define FLERRADR(f) (f->reg + 0x98) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* FLCMNCR control bits */ 418c2ecf20Sopenharmony_ci#define _4ECCCNTEN (0x1 << 24) 428c2ecf20Sopenharmony_ci#define _4ECCEN (0x1 << 23) 438c2ecf20Sopenharmony_ci#define _4ECCCORRECT (0x1 << 22) 448c2ecf20Sopenharmony_ci#define SHBUSSEL (0x1 << 20) 458c2ecf20Sopenharmony_ci#define SEL_16BIT (0x1 << 19) 468c2ecf20Sopenharmony_ci#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/ 478c2ecf20Sopenharmony_ci#define QTSEL_E (0x1 << 17) 488c2ecf20Sopenharmony_ci#define ENDIAN (0x1 << 16) /* 1 = little endian */ 498c2ecf20Sopenharmony_ci#define FCKSEL_E (0x1 << 15) 508c2ecf20Sopenharmony_ci#define ACM_SACCES_MODE (0x01 << 10) 518c2ecf20Sopenharmony_ci#define NANWF_E (0x1 << 9) 528c2ecf20Sopenharmony_ci#define SE_D (0x1 << 8) /* Spare area disable */ 538c2ecf20Sopenharmony_ci#define CE1_ENABLE (0x1 << 4) /* Chip Enable 1 */ 548c2ecf20Sopenharmony_ci#define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */ 558c2ecf20Sopenharmony_ci#define TYPESEL_SET (0x1 << 0) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * Clock settings using the PULSEx registers from FLCMNCR 598c2ecf20Sopenharmony_ci * 608c2ecf20Sopenharmony_ci * Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E 618c2ecf20Sopenharmony_ci * to control the clock divider used between the High-Speed Peripheral Clock 628c2ecf20Sopenharmony_ci * and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit 638c2ecf20Sopenharmony_ci * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16 648c2ecf20Sopenharmony_ci * bit version the divider is seperate for the pulse width of high and low 658c2ecf20Sopenharmony_ci * signals. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ci#define PULSE3 (0x1 << 27) 688c2ecf20Sopenharmony_ci#define PULSE2 (0x1 << 17) 698c2ecf20Sopenharmony_ci#define PULSE1 (0x1 << 15) 708c2ecf20Sopenharmony_ci#define PULSE0 (0x1 << 9) 718c2ecf20Sopenharmony_ci#define CLK_8B_0_5 PULSE1 728c2ecf20Sopenharmony_ci#define CLK_8B_1 0x0 738c2ecf20Sopenharmony_ci#define CLK_8B_1_5 (PULSE1 | PULSE2) 748c2ecf20Sopenharmony_ci#define CLK_8B_2 PULSE0 758c2ecf20Sopenharmony_ci#define CLK_8B_3 (PULSE0 | PULSE1 | PULSE2) 768c2ecf20Sopenharmony_ci#define CLK_8B_4 (PULSE0 | PULSE2) 778c2ecf20Sopenharmony_ci#define CLK_16B_6L_2H PULSE0 788c2ecf20Sopenharmony_ci#define CLK_16B_9L_3H (PULSE0 | PULSE1 | PULSE2) 798c2ecf20Sopenharmony_ci#define CLK_16B_12L_4H (PULSE0 | PULSE2) 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* FLCMDCR control bits */ 828c2ecf20Sopenharmony_ci#define ADRCNT2_E (0x1 << 31) /* 5byte address enable */ 838c2ecf20Sopenharmony_ci#define ADRMD_E (0x1 << 26) /* Sector address access */ 848c2ecf20Sopenharmony_ci#define CDSRC_E (0x1 << 25) /* Data buffer selection */ 858c2ecf20Sopenharmony_ci#define DOSR_E (0x1 << 24) /* Status read check */ 868c2ecf20Sopenharmony_ci#define SELRW (0x1 << 21) /* 0:read 1:write */ 878c2ecf20Sopenharmony_ci#define DOADR_E (0x1 << 20) /* Address stage execute */ 888c2ecf20Sopenharmony_ci#define ADRCNT_1 (0x00 << 18) /* Address data bytes: 1byte */ 898c2ecf20Sopenharmony_ci#define ADRCNT_2 (0x01 << 18) /* Address data bytes: 2byte */ 908c2ecf20Sopenharmony_ci#define ADRCNT_3 (0x02 << 18) /* Address data bytes: 3byte */ 918c2ecf20Sopenharmony_ci#define ADRCNT_4 (0x03 << 18) /* Address data bytes: 4byte */ 928c2ecf20Sopenharmony_ci#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */ 938c2ecf20Sopenharmony_ci#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */ 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* FLINTDMACR control bits */ 968c2ecf20Sopenharmony_ci#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ 978c2ecf20Sopenharmony_ci#define AC1CLR (0x1 << 19) /* ECC FIFO clear */ 988c2ecf20Sopenharmony_ci#define AC0CLR (0x1 << 18) /* Data FIFO clear */ 998c2ecf20Sopenharmony_ci#define DREQ0EN (0x1 << 16) /* FLDTFIFODMA Request Enable */ 1008c2ecf20Sopenharmony_ci#define ECERB (0x1 << 9) /* ECC error */ 1018c2ecf20Sopenharmony_ci#define STERB (0x1 << 8) /* Status error */ 1028c2ecf20Sopenharmony_ci#define STERINTE (0x1 << 4) /* Status error enable */ 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* FLTRCR control bits */ 1058c2ecf20Sopenharmony_ci#define TRSTRT (0x1 << 0) /* translation start */ 1068c2ecf20Sopenharmony_ci#define TREND (0x1 << 1) /* translation end */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* 1098c2ecf20Sopenharmony_ci * FLHOLDCR control bits 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * HOLDEN: Bus Occupancy Enable (inverted) 1128c2ecf20Sopenharmony_ci * Enable this bit when the external bus might be used in between transfers. 1138c2ecf20Sopenharmony_ci * If not set and the bus gets used by other modules, a deadlock occurs. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci#define HOLDEN (0x1 << 0) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/* FL4ECCCR control bits */ 1188c2ecf20Sopenharmony_ci#define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */ 1198c2ecf20Sopenharmony_ci#define _4ECCEND (0x1 << 1) /* 4 symbols end */ 1208c2ecf20Sopenharmony_ci#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */ 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define LOOP_TIMEOUT_MAX 0x00010000 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cienum flctl_ecc_res_t { 1258c2ecf20Sopenharmony_ci FL_SUCCESS, 1268c2ecf20Sopenharmony_ci FL_REPAIRABLE, 1278c2ecf20Sopenharmony_ci FL_ERROR, 1288c2ecf20Sopenharmony_ci FL_TIMEOUT 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistruct dma_chan; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistruct sh_flctl { 1348c2ecf20Sopenharmony_ci struct nand_chip chip; 1358c2ecf20Sopenharmony_ci struct platform_device *pdev; 1368c2ecf20Sopenharmony_ci struct dev_pm_qos_request pm_qos; 1378c2ecf20Sopenharmony_ci void __iomem *reg; 1388c2ecf20Sopenharmony_ci resource_size_t fifo; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ 1418c2ecf20Sopenharmony_ci int read_bytes; 1428c2ecf20Sopenharmony_ci unsigned int index; 1438c2ecf20Sopenharmony_ci int seqin_column; /* column in SEQIN cmd */ 1448c2ecf20Sopenharmony_ci int seqin_page_addr; /* page_addr in SEQIN cmd */ 1458c2ecf20Sopenharmony_ci uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ 1468c2ecf20Sopenharmony_ci int erase1_page_addr; /* page_addr in ERASE1 cmd */ 1478c2ecf20Sopenharmony_ci uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */ 1488c2ecf20Sopenharmony_ci uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */ 1498c2ecf20Sopenharmony_ci uint32_t flcmncr_base; /* base value of FLCMNCR */ 1508c2ecf20Sopenharmony_ci uint32_t flintdmacr_base; /* irq enable bits */ 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */ 1538c2ecf20Sopenharmony_ci unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ 1548c2ecf20Sopenharmony_ci unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ 1558c2ecf20Sopenharmony_ci unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci /* DMA related objects */ 1588c2ecf20Sopenharmony_ci struct dma_chan *chan_fifo0_rx; 1598c2ecf20Sopenharmony_ci struct dma_chan *chan_fifo0_tx; 1608c2ecf20Sopenharmony_ci struct completion dma_complete; 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistruct sh_flctl_platform_data { 1648c2ecf20Sopenharmony_ci struct mtd_partition *parts; 1658c2ecf20Sopenharmony_ci int nr_parts; 1668c2ecf20Sopenharmony_ci unsigned long flcmncr_val; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci unsigned has_hwecc:1; 1698c2ecf20Sopenharmony_ci unsigned use_holden:1; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci unsigned int slave_id_fifo0_tx; 1728c2ecf20Sopenharmony_ci unsigned int slave_id_fifo0_rx; 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci#endif /* __SH_FLCTL_H__ */ 181