From 5988af2319781bc8e0ce418affec4e09cfa77907 Mon Sep 17 00:00:00 2001 From: Rohit Hagargundgi Date: Tue, 12 May 2009 13:46:57 -0700 Subject: mtd: Flex-OneNAND support Add support for Samsung Flex-OneNAND devices. Flex-OneNAND combines SLC and MLC technologies into a single device. SLC area provides increased reliability and speed, suitable for storing code such as bootloader, kernel and root file system. MLC area provides high density and is suitable for storing user data. SLC and MLC regions can be configured through kernel parameter. [akpm@linux-foundation.org: export flexoand_region and onenand_addr] Signed-off-by: Rohit Hagargundgi Signed-off-by: Kyungmin Park Cc: Vishak G Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- include/linux/mtd/onenand.h | 18 ++++++++++++++++++ include/linux/mtd/onenand_regs.h | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 0fa3ac4..9aab82c 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -17,6 +17,7 @@ #include #include +#define MAX_DIES 2 #define MAX_BUFFERRAM 2 /* Scan and identify a OneNAND device */ @@ -51,7 +52,12 @@ struct onenand_bufferram { /** * struct onenand_chip - OneNAND Private Flash Chip Data * @base: [BOARDSPECIFIC] address to access OneNAND + * @dies: [INTERN][FLEX-ONENAND] number of dies on chip + * @boundary: [INTERN][FLEX-ONENAND] Boundary of the dies + * @diesize: [INTERN][FLEX-ONENAND] Size of the dies * @chipsize: [INTERN] the size of one chip for multichip arrays + * FIXME For Flex-OneNAND, chipsize holds maximum possible + * device size ie when all blocks are considered MLC * @device_id: [INTERN] device ID * @density_mask: chip density, used for DDP devices * @verstion_id: [INTERN] version ID @@ -92,9 +98,13 @@ struct onenand_bufferram { */ struct onenand_chip { void __iomem *base; + unsigned dies; + unsigned boundary[MAX_DIES]; + loff_t diesize[MAX_DIES]; unsigned int chipsize; unsigned int device_id; unsigned int version_id; + unsigned int technology; unsigned int density_mask; unsigned int options; @@ -145,6 +155,8 @@ struct onenand_chip { #define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) #define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) +#define FLEXONENAND(this) \ + (this->device_id & DEVICE_IS_FLEXONENAND) #define ONENAND_GET_SYS_CFG1(this) \ (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) #define ONENAND_SET_SYS_CFG1(v, this) \ @@ -153,6 +165,9 @@ struct onenand_chip { #define ONENAND_IS_DDP(this) \ (this->device_id & ONENAND_DEVICE_IS_DDP) +#define ONENAND_IS_MLC(this) \ + (this->technology & ONENAND_TECHNOLOGY_IS_MLC) + #ifdef CONFIG_MTD_ONENAND_2X_PROGRAM #define ONENAND_IS_2PLANE(this) \ (this->options & ONENAND_HAS_2PLANE) @@ -190,5 +205,8 @@ struct onenand_manufacturers { int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); +unsigned onenand_block(struct onenand_chip *this, loff_t addr); +loff_t onenand_addr(struct onenand_chip *this, int block); +int flexonenand_region(struct mtd_info *mtd, loff_t addr); #endif /* __LINUX_MTD_ONENAND_H */ diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h index 0c6bbe2..86a6bbe 100644 --- a/include/linux/mtd/onenand_regs.h +++ b/include/linux/mtd/onenand_regs.h @@ -67,6 +67,9 @@ /* * Device ID Register F001h (R) */ +#define DEVICE_IS_FLEXONENAND (1 << 9) +#define FLEXONENAND_PI_MASK (0x3ff) +#define FLEXONENAND_PI_UNLOCK_SHIFT (14) #define ONENAND_DEVICE_DENSITY_MASK (0xf) #define ONENAND_DEVICE_DENSITY_SHIFT (4) #define ONENAND_DEVICE_IS_DDP (1 << 3) @@ -84,6 +87,11 @@ #define ONENAND_VERSION_PROCESS_SHIFT (8) /* + * Technology Register F006h (R) + */ +#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0) + +/* * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W) */ #define ONENAND_DDP_SHIFT (15) @@ -93,7 +101,8 @@ /* * Start Address 8 F107h (R/W) */ -#define ONENAND_FPA_MASK (0x3f) +/* Note: It's actually 0x3f in case of SLC */ +#define ONENAND_FPA_MASK (0x7f) #define ONENAND_FPA_SHIFT (2) #define ONENAND_FSA_MASK (0x03) @@ -105,7 +114,8 @@ #define ONENAND_BSA_BOOTRAM (0 << 2) #define ONENAND_BSA_DATARAM0 (2 << 2) #define ONENAND_BSA_DATARAM1 (3 << 2) -#define ONENAND_BSC_MASK (0x03) +/* Note: It's actually 0x03 in case of SLC */ +#define ONENAND_BSC_MASK (0x07) /* * Command Register F220h (R/W) @@ -124,9 +134,13 @@ #define ONENAND_CMD_RESET (0xF0) #define ONENAND_CMD_OTP_ACCESS (0x65) #define ONENAND_CMD_READID (0x90) +#define FLEXONENAND_CMD_PI_UPDATE (0x05) +#define FLEXONENAND_CMD_PI_ACCESS (0x66) +#define FLEXONENAND_CMD_RECOVER_LSB (0x05) /* NOTE: Those are not *REAL* commands */ #define ONENAND_CMD_BUFFERRAM (0x1978) +#define FLEXONENAND_CMD_READ_PI (0x1985) /* * System Configuration 1 Register F221h (R, R/W) @@ -192,10 +206,12 @@ #define ONENAND_ECC_1BIT_ALL (0x5555) #define ONENAND_ECC_2BIT (1 << 1) #define ONENAND_ECC_2BIT_ALL (0xAAAA) +#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010) /* * One-Time Programmable (OTP) */ +#define FLEXONENAND_OTP_LOCK_OFFSET (2048) #define ONENAND_OTP_LOCK_OFFSET (14) #endif /* __ONENAND_REG_H */ -- cgit v1.1