1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * linux/include/linux/mtd/onenand.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright © 2005-2009 Samsung Electronics 6*4882a593Smuzhiyun * Kyungmin Park <kyungmin.park@samsung.com> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef __LINUX_MTD_ONENAND_H 10*4882a593Smuzhiyun #define __LINUX_MTD_ONENAND_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #include <linux/spinlock.h> 13*4882a593Smuzhiyun #include <linux/completion.h> 14*4882a593Smuzhiyun #include <linux/mtd/flashchip.h> 15*4882a593Smuzhiyun #include <linux/mtd/onenand_regs.h> 16*4882a593Smuzhiyun #include <linux/mtd/bbm.h> 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define MAX_DIES 2 19*4882a593Smuzhiyun #define MAX_BUFFERRAM 2 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* Scan and identify a OneNAND device */ 22*4882a593Smuzhiyun extern int onenand_scan(struct mtd_info *mtd, int max_chips); 23*4882a593Smuzhiyun /* Free resources held by the OneNAND device */ 24*4882a593Smuzhiyun extern void onenand_release(struct mtd_info *mtd); 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun /** 27*4882a593Smuzhiyun * struct onenand_bufferram - OneNAND BufferRAM Data 28*4882a593Smuzhiyun * @blockpage: block & page address in BufferRAM 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun struct onenand_bufferram { 31*4882a593Smuzhiyun int blockpage; 32*4882a593Smuzhiyun }; 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /** 35*4882a593Smuzhiyun * struct onenand_chip - OneNAND Private Flash Chip Data 36*4882a593Smuzhiyun * @base: [BOARDSPECIFIC] address to access OneNAND 37*4882a593Smuzhiyun * @dies: [INTERN][FLEX-ONENAND] number of dies on chip 38*4882a593Smuzhiyun * @boundary: [INTERN][FLEX-ONENAND] Boundary of the dies 39*4882a593Smuzhiyun * @diesize: [INTERN][FLEX-ONENAND] Size of the dies 40*4882a593Smuzhiyun * @chipsize: [INTERN] the size of one chip for multichip arrays 41*4882a593Smuzhiyun * FIXME For Flex-OneNAND, chipsize holds maximum possible 42*4882a593Smuzhiyun * device size ie when all blocks are considered MLC 43*4882a593Smuzhiyun * @device_id: [INTERN] device ID 44*4882a593Smuzhiyun * @density_mask: chip density, used for DDP devices 45*4882a593Smuzhiyun * @verstion_id: [INTERN] version ID 46*4882a593Smuzhiyun * @options: [BOARDSPECIFIC] various chip options. They can 47*4882a593Smuzhiyun * partly be set to inform onenand_scan about 48*4882a593Smuzhiyun * @erase_shift: [INTERN] number of address bits in a block 49*4882a593Smuzhiyun * @page_shift: [INTERN] number of address bits in a page 50*4882a593Smuzhiyun * @page_mask: [INTERN] a page per block mask 51*4882a593Smuzhiyun * @writesize: [INTERN] a real page size 52*4882a593Smuzhiyun * @bufferram_index: [INTERN] BufferRAM index 53*4882a593Smuzhiyun * @bufferram: [INTERN] BufferRAM info 54*4882a593Smuzhiyun * @readw: [REPLACEABLE] hardware specific function for read short 55*4882a593Smuzhiyun * @writew: [REPLACEABLE] hardware specific function for write short 56*4882a593Smuzhiyun * @command: [REPLACEABLE] hardware specific function for writing 57*4882a593Smuzhiyun * commands to the chip 58*4882a593Smuzhiyun * @wait: [REPLACEABLE] hardware specific function for wait on ready 59*4882a593Smuzhiyun * @bbt_wait: [REPLACEABLE] hardware specific function for bbt wait on ready 60*4882a593Smuzhiyun * @unlock_all: [REPLACEABLE] hardware specific function for unlock all 61*4882a593Smuzhiyun * @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 62*4882a593Smuzhiyun * @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 63*4882a593Smuzhiyun * @read_word: [REPLACEABLE] hardware specific function for read 64*4882a593Smuzhiyun * register of OneNAND 65*4882a593Smuzhiyun * @write_word: [REPLACEABLE] hardware specific function for write 66*4882a593Smuzhiyun * register of OneNAND 67*4882a593Smuzhiyun * @mmcontrol: sync burst read function 68*4882a593Smuzhiyun * @chip_probe: [REPLACEABLE] hardware specific function for chip probe 69*4882a593Smuzhiyun * @block_markbad: function to mark a block as bad 70*4882a593Smuzhiyun * @scan_bbt: [REPLACEALBE] hardware specific function for scanning 71*4882a593Smuzhiyun * Bad block Table 72*4882a593Smuzhiyun * @chip_lock: [INTERN] spinlock used to protect access to this 73*4882a593Smuzhiyun * structure and the chip 74*4882a593Smuzhiyun * @wq: [INTERN] wait queue to sleep on if a OneNAND 75*4882a593Smuzhiyun * operation is in progress 76*4882a593Smuzhiyun * @state: [INTERN] the current state of the OneNAND device 77*4882a593Smuzhiyun * @page_buf: [INTERN] page main data buffer 78*4882a593Smuzhiyun * @oob_buf: [INTERN] page oob data buffer 79*4882a593Smuzhiyun * @subpagesize: [INTERN] holds the subpagesize 80*4882a593Smuzhiyun * @bbm: [REPLACEABLE] pointer to Bad Block Management 81*4882a593Smuzhiyun * @priv: [OPTIONAL] pointer to private chip date 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun struct onenand_chip { 84*4882a593Smuzhiyun void __iomem *base; 85*4882a593Smuzhiyun unsigned dies; 86*4882a593Smuzhiyun unsigned boundary[MAX_DIES]; 87*4882a593Smuzhiyun loff_t diesize[MAX_DIES]; 88*4882a593Smuzhiyun unsigned int chipsize; 89*4882a593Smuzhiyun unsigned int device_id; 90*4882a593Smuzhiyun unsigned int version_id; 91*4882a593Smuzhiyun unsigned int technology; 92*4882a593Smuzhiyun unsigned int density_mask; 93*4882a593Smuzhiyun unsigned int options; 94*4882a593Smuzhiyun unsigned int badblockpos; 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun unsigned int erase_shift; 97*4882a593Smuzhiyun unsigned int page_shift; 98*4882a593Smuzhiyun unsigned int page_mask; 99*4882a593Smuzhiyun unsigned int writesize; 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun unsigned int bufferram_index; 102*4882a593Smuzhiyun struct onenand_bufferram bufferram[MAX_BUFFERRAM]; 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len); 105*4882a593Smuzhiyun int (*wait)(struct mtd_info *mtd, int state); 106*4882a593Smuzhiyun int (*bbt_wait)(struct mtd_info *mtd, int state); 107*4882a593Smuzhiyun void (*unlock_all)(struct mtd_info *mtd); 108*4882a593Smuzhiyun int (*read_bufferram)(struct mtd_info *mtd, int area, 109*4882a593Smuzhiyun unsigned char *buffer, int offset, size_t count); 110*4882a593Smuzhiyun int (*write_bufferram)(struct mtd_info *mtd, int area, 111*4882a593Smuzhiyun const unsigned char *buffer, int offset, size_t count); 112*4882a593Smuzhiyun unsigned short (*read_word)(void __iomem *addr); 113*4882a593Smuzhiyun void (*write_word)(unsigned short value, void __iomem *addr); 114*4882a593Smuzhiyun void (*mmcontrol)(struct mtd_info *mtd, int sync_read); 115*4882a593Smuzhiyun int (*chip_probe)(struct mtd_info *mtd); 116*4882a593Smuzhiyun int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); 117*4882a593Smuzhiyun int (*scan_bbt)(struct mtd_info *mtd); 118*4882a593Smuzhiyun int (*enable)(struct mtd_info *mtd); 119*4882a593Smuzhiyun int (*disable)(struct mtd_info *mtd); 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun struct completion complete; 122*4882a593Smuzhiyun int irq; 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun spinlock_t chip_lock; 125*4882a593Smuzhiyun wait_queue_head_t wq; 126*4882a593Smuzhiyun flstate_t state; 127*4882a593Smuzhiyun unsigned char *page_buf; 128*4882a593Smuzhiyun unsigned char *oob_buf; 129*4882a593Smuzhiyun #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE 130*4882a593Smuzhiyun unsigned char *verify_buf; 131*4882a593Smuzhiyun #endif 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun int subpagesize; 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun void *bbm; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun void *priv; 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun /* 140*4882a593Smuzhiyun * Shows that the current operation is composed 141*4882a593Smuzhiyun * of sequence of commands. For example, cache program. 142*4882a593Smuzhiyun * Such command status OnGo bit is checked at the end of 143*4882a593Smuzhiyun * sequence. 144*4882a593Smuzhiyun */ 145*4882a593Smuzhiyun unsigned int ongoing; 146*4882a593Smuzhiyun }; 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* 149*4882a593Smuzhiyun * Helper macros 150*4882a593Smuzhiyun */ 151*4882a593Smuzhiyun #define ONENAND_PAGES_PER_BLOCK (1<<6) 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun #define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) 154*4882a593Smuzhiyun #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) 155*4882a593Smuzhiyun #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) 156*4882a593Smuzhiyun #define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1) 157*4882a593Smuzhiyun #define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) 158*4882a593Smuzhiyun #define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun #define FLEXONENAND(this) \ 161*4882a593Smuzhiyun (this->device_id & DEVICE_IS_FLEXONENAND) 162*4882a593Smuzhiyun #define ONENAND_GET_SYS_CFG1(this) \ 163*4882a593Smuzhiyun (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) 164*4882a593Smuzhiyun #define ONENAND_SET_SYS_CFG1(v, this) \ 165*4882a593Smuzhiyun (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun #define ONENAND_IS_DDP(this) \ 168*4882a593Smuzhiyun (this->device_id & ONENAND_DEVICE_IS_DDP) 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun #define ONENAND_IS_MLC(this) \ 171*4882a593Smuzhiyun (this->technology & ONENAND_TECHNOLOGY_IS_MLC) 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun #ifdef CONFIG_MTD_ONENAND_2X_PROGRAM 174*4882a593Smuzhiyun #define ONENAND_IS_2PLANE(this) \ 175*4882a593Smuzhiyun (this->options & ONENAND_HAS_2PLANE) 176*4882a593Smuzhiyun #else 177*4882a593Smuzhiyun #define ONENAND_IS_2PLANE(this) (0) 178*4882a593Smuzhiyun #endif 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun #define ONENAND_IS_CACHE_PROGRAM(this) \ 181*4882a593Smuzhiyun (this->options & ONENAND_HAS_CACHE_PROGRAM) 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun #define ONENAND_IS_NOP_1(this) \ 184*4882a593Smuzhiyun (this->options & ONENAND_HAS_NOP_1) 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun /* Check byte access in OneNAND */ 187*4882a593Smuzhiyun #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun #define ONENAND_BADBLOCK_POS 0 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun /* 192*4882a593Smuzhiyun * Options bits 193*4882a593Smuzhiyun */ 194*4882a593Smuzhiyun #define ONENAND_HAS_CONT_LOCK (0x0001) 195*4882a593Smuzhiyun #define ONENAND_HAS_UNLOCK_ALL (0x0002) 196*4882a593Smuzhiyun #define ONENAND_HAS_2PLANE (0x0004) 197*4882a593Smuzhiyun #define ONENAND_HAS_4KB_PAGE (0x0008) 198*4882a593Smuzhiyun #define ONENAND_HAS_CACHE_PROGRAM (0x0010) 199*4882a593Smuzhiyun #define ONENAND_HAS_NOP_1 (0x0020) 200*4882a593Smuzhiyun #define ONENAND_SKIP_UNLOCK_CHECK (0x0100) 201*4882a593Smuzhiyun #define ONENAND_PAGEBUF_ALLOC (0x1000) 202*4882a593Smuzhiyun #define ONENAND_OOBBUF_ALLOC (0x2000) 203*4882a593Smuzhiyun #define ONENAND_SKIP_INITIAL_UNLOCKING (0x4000) 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun #define ONENAND_IS_4KB_PAGE(this) \ 206*4882a593Smuzhiyun (this->options & ONENAND_HAS_4KB_PAGE) 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun /* 209*4882a593Smuzhiyun * OneNAND Flash Manufacturer ID Codes 210*4882a593Smuzhiyun */ 211*4882a593Smuzhiyun #define ONENAND_MFR_SAMSUNG 0xec 212*4882a593Smuzhiyun #define ONENAND_MFR_NUMONYX 0x20 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun /** 215*4882a593Smuzhiyun * struct onenand_manufacturers - NAND Flash Manufacturer ID Structure 216*4882a593Smuzhiyun * @name: Manufacturer name 217*4882a593Smuzhiyun * @id: manufacturer ID code of device. 218*4882a593Smuzhiyun */ 219*4882a593Smuzhiyun struct onenand_manufacturers { 220*4882a593Smuzhiyun int id; 221*4882a593Smuzhiyun char *name; 222*4882a593Smuzhiyun }; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 225*4882a593Smuzhiyun struct mtd_oob_ops *ops); 226*4882a593Smuzhiyun unsigned onenand_block(struct onenand_chip *this, loff_t addr); 227*4882a593Smuzhiyun loff_t onenand_addr(struct onenand_chip *this, int block); 228*4882a593Smuzhiyun int flexonenand_region(struct mtd_info *mtd, loff_t addr); 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun struct mtd_partition; 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun struct onenand_platform_data { 233*4882a593Smuzhiyun void (*mmcontrol)(struct mtd_info *mtd, int sync_read); 234*4882a593Smuzhiyun int (*read_bufferram)(struct mtd_info *mtd, int area, 235*4882a593Smuzhiyun unsigned char *buffer, int offset, size_t count); 236*4882a593Smuzhiyun struct mtd_partition *parts; 237*4882a593Smuzhiyun unsigned int nr_parts; 238*4882a593Smuzhiyun }; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun #endif /* __LINUX_MTD_ONENAND_H */ 241