summaryrefslogtreecommitdiff
path: root/include/linux/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mtd')
-rw-r--r--include/linux/mtd/cfi.h1
-rw-r--r--include/linux/mtd/ftl.h38
-rw-r--r--include/linux/mtd/map.h1
-rw-r--r--include/linux/mtd/mtd.h75
-rw-r--r--include/linux/mtd/nand.h7
-rw-r--r--include/linux/mtd/partitions.h6
-rw-r--r--include/linux/mtd/pfow.h159
-rw-r--r--include/linux/mtd/physmap.h1
-rw-r--r--include/linux/mtd/qinfo.h91
-rw-r--r--include/linux/mtd/sharpsl.h20
10 files changed, 354 insertions, 45 deletions
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 00e2b575021f..88d3d8fbf9f2 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -520,6 +520,7 @@ struct cfi_fixup {
#define CFI_MFR_AMD 0x0001
#define CFI_MFR_ATMEL 0x001F
+#define CFI_MFR_SAMSUNG 0x00EC
#define CFI_MFR_ST 0x0020 /* STMicroelectronics */
void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups);
diff --git a/include/linux/mtd/ftl.h b/include/linux/mtd/ftl.h
index 0be442f881dd..0555f7a0b9ed 100644
--- a/include/linux/mtd/ftl.h
+++ b/include/linux/mtd/ftl.h
@@ -32,25 +32,25 @@
#define _LINUX_FTL_H
typedef struct erase_unit_header_t {
- u_int8_t LinkTargetTuple[5];
- u_int8_t DataOrgTuple[10];
- u_int8_t NumTransferUnits;
- u_int32_t EraseCount;
- u_int16_t LogicalEUN;
- u_int8_t BlockSize;
- u_int8_t EraseUnitSize;
- u_int16_t FirstPhysicalEUN;
- u_int16_t NumEraseUnits;
- u_int32_t FormattedSize;
- u_int32_t FirstVMAddress;
- u_int16_t NumVMPages;
- u_int8_t Flags;
- u_int8_t Code;
- u_int32_t SerialNumber;
- u_int32_t AltEUHOffset;
- u_int32_t BAMOffset;
- u_int8_t Reserved[12];
- u_int8_t EndTuple[2];
+ uint8_t LinkTargetTuple[5];
+ uint8_t DataOrgTuple[10];
+ uint8_t NumTransferUnits;
+ uint32_t EraseCount;
+ uint16_t LogicalEUN;
+ uint8_t BlockSize;
+ uint8_t EraseUnitSize;
+ uint16_t FirstPhysicalEUN;
+ uint16_t NumEraseUnits;
+ uint32_t FormattedSize;
+ uint32_t FirstVMAddress;
+ uint16_t NumVMPages;
+ uint8_t Flags;
+ uint8_t Code;
+ uint32_t SerialNumber;
+ uint32_t AltEUHOffset;
+ uint32_t BAMOffset;
+ uint8_t Reserved[12];
+ uint8_t EndTuple[2];
} erase_unit_header_t;
/* Flags in erase_unit_header_t */
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index aa30244492c6..b981b8772217 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -223,6 +223,7 @@ struct map_info {
must leave it enabled. */
void (*set_vpp)(struct map_info *, int);
+ unsigned long pfow_base;
unsigned long map_priv_1;
unsigned long map_priv_2;
void *fldrv_priv;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 64433eb411d7..3aa5d77c2cdb 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -15,6 +15,8 @@
#include <linux/mtd/compatmac.h>
#include <mtd/mtd-abi.h>
+#include <asm/div64.h>
+
#define MTD_CHAR_MAJOR 90
#define MTD_BLOCK_MAJOR 31
#define MAX_MTD_DEVICES 32
@@ -25,20 +27,20 @@
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
-#define MTD_FAIL_ADDR_UNKNOWN 0xffffffff
+#define MTD_FAIL_ADDR_UNKNOWN -1LL
/* If the erase fails, fail_addr might indicate exactly which block failed. If
fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not
specific to any particular block. */
struct erase_info {
struct mtd_info *mtd;
- u_int32_t addr;
- u_int32_t len;
- u_int32_t fail_addr;
+ uint64_t addr;
+ uint64_t len;
+ uint64_t fail_addr;
u_long time;
u_long retries;
- u_int dev;
- u_int cell;
+ unsigned dev;
+ unsigned cell;
void (*callback) (struct erase_info *self);
u_long priv;
u_char state;
@@ -46,9 +48,9 @@ struct erase_info {
};
struct mtd_erase_region_info {
- u_int32_t offset; /* At which this region starts, from the beginning of the MTD */
- u_int32_t erasesize; /* For this region */
- u_int32_t numblocks; /* Number of blocks of erasesize in this region */
+ uint64_t offset; /* At which this region starts, from the beginning of the MTD */
+ uint32_t erasesize; /* For this region */
+ uint32_t numblocks; /* Number of blocks of erasesize in this region */
unsigned long *lockmap; /* If keeping bitmap of locks */
};
@@ -100,14 +102,14 @@ struct mtd_oob_ops {
struct mtd_info {
u_char type;
- u_int32_t flags;
- u_int32_t size; // Total size of the MTD
+ uint32_t flags;
+ uint64_t size; // Total size of the MTD
/* "Major" erase size for the device. Naïve users may take this
* to be the only erase size available, or may use the more detailed
* information below if they desire
*/
- u_int32_t erasesize;
+ uint32_t erasesize;
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
* though individual bits can be cleared), in case of NAND flash it is
* one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
@@ -115,10 +117,20 @@ struct mtd_info {
* Any driver registering a struct mtd_info must ensure a writesize of
* 1 or larger.
*/
- u_int32_t writesize;
+ uint32_t writesize;
+
+ uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
+ uint32_t oobavail; // Available OOB bytes per block
- u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
- u_int32_t oobavail; // Available OOB bytes per block
+ /*
+ * If erasesize is a power of 2 then the shift is stored in
+ * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
+ */
+ unsigned int erasesize_shift;
+ unsigned int writesize_shift;
+ /* Masks based on erasesize_shift and writesize_shift */
+ unsigned int erasesize_mask;
+ unsigned int writesize_mask;
// Kernel-only stuff starts here.
const char *name;
@@ -190,8 +202,8 @@ struct mtd_info {
void (*sync) (struct mtd_info *mtd);
/* Chip-supported device locking */
- int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
- int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
+ int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+ int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
/* Power Management functions */
int (*suspend) (struct mtd_info *mtd);
@@ -221,6 +233,35 @@ struct mtd_info {
void (*put_device) (struct mtd_info *mtd);
};
+static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
+{
+ if (mtd->erasesize_shift)
+ return sz >> mtd->erasesize_shift;
+ do_div(sz, mtd->erasesize);
+ return sz;
+}
+
+static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
+{
+ if (mtd->erasesize_shift)
+ return sz & mtd->erasesize_mask;
+ return do_div(sz, mtd->erasesize);
+}
+
+static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
+{
+ if (mtd->writesize_shift)
+ return sz >> mtd->writesize_shift;
+ do_div(sz, mtd->writesize);
+ return sz;
+}
+
+static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
+{
+ if (mtd->writesize_shift)
+ return sz & mtd->writesize_mask;
+ return do_div(sz, mtd->writesize);
+}
/* Kernel-side ioctl definitions */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 733d3f3b4eb8..db5b63da2a7e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -335,17 +335,12 @@ struct nand_buffers {
* @erase_cmd: [INTERN] erase command write function, selectable due to AND support
* @scan_bbt: [REPLACEABLE] function to scan bad block table
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
- * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
* @state: [INTERN] the current state of the NAND device
* @oob_poi: poison value buffer
* @page_shift: [INTERN] number of address bits in a page (column address bits)
* @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
* @chip_shift: [INTERN] number of address bits in one chip
- * @datbuf: [INTERN] internal buffer for one page + oob
- * @oobbuf: [INTERN] oob buffer for one eraseblock
- * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
- * @data_poi: [INTERN] pointer to a data buffer
* @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
* special functionality. See the defines for further explanation
* @badblockpos: [INTERN] position of the bad block marker in the oob area
@@ -399,7 +394,7 @@ struct nand_chip {
int bbt_erase_shift;
int chip_shift;
int numchips;
- unsigned long chipsize;
+ uint64_t chipsize;
int pagemask;
int pagebuf;
int subpagesize;
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index c92b4d439609..a45dd831b3f8 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -36,9 +36,9 @@
struct mtd_partition {
char *name; /* identifier string */
- u_int32_t size; /* partition size */
- u_int32_t offset; /* offset within the master MTD space */
- u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
+ uint64_t size; /* partition size */
+ uint64_t offset; /* offset within the master MTD space */
+ uint32_t mask_flags; /* master MTD flags to mask out for this partition */
struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/
struct mtd_info **mtdp; /* pointer to store the MTD object */
};
diff --git a/include/linux/mtd/pfow.h b/include/linux/mtd/pfow.h
new file mode 100644
index 000000000000..b730d4f84655
--- /dev/null
+++ b/include/linux/mtd/pfow.h
@@ -0,0 +1,159 @@
+/* Primary function overlay window definitions
+ * and service functions used by LPDDR chips
+ */
+#ifndef __LINUX_MTD_PFOW_H
+#define __LINUX_MTD_PFOW_H
+
+#include <linux/mtd/qinfo.h>
+
+/* PFOW registers addressing */
+/* Address of symbol "P" */
+#define PFOW_QUERY_STRING_P 0x0000
+/* Address of symbol "F" */
+#define PFOW_QUERY_STRING_F 0x0002
+/* Address of symbol "O" */
+#define PFOW_QUERY_STRING_O 0x0004
+/* Address of symbol "W" */
+#define PFOW_QUERY_STRING_W 0x0006
+/* Identification info for LPDDR chip */
+#define PFOW_MANUFACTURER_ID 0x0020
+#define PFOW_DEVICE_ID 0x0022
+/* Address in PFOW where prog buffer can can be found */
+#define PFOW_PROGRAM_BUFFER_OFFSET 0x0040
+/* Size of program buffer in words */
+#define PFOW_PROGRAM_BUFFER_SIZE 0x0042
+/* Address command code register */
+#define PFOW_COMMAND_CODE 0x0080
+/* command data register */
+#define PFOW_COMMAND_DATA 0x0084
+/* command address register lower address bits */
+#define PFOW_COMMAND_ADDRESS_L 0x0088
+/* command address register upper address bits */
+#define PFOW_COMMAND_ADDRESS_H 0x008a
+/* number of bytes to be proggrammed lower address bits */
+#define PFOW_DATA_COUNT_L 0x0090
+/* number of bytes to be proggrammed higher address bits */
+#define PFOW_DATA_COUNT_H 0x0092
+/* command execution register, the only possible value is 0x01 */
+#define PFOW_COMMAND_EXECUTE 0x00c0
+/* 0x01 should be written at this address to clear buffer */
+#define PFOW_CLEAR_PROGRAM_BUFFER 0x00c4
+/* device program/erase suspend register */
+#define PFOW_PROGRAM_ERASE_SUSPEND 0x00c8
+/* device status register */
+#define PFOW_DSR 0x00cc
+
+/* LPDDR memory device command codes */
+/* They are possible values of PFOW command code register */
+#define LPDDR_WORD_PROGRAM 0x0041
+#define LPDDR_BUFF_PROGRAM 0x00E9
+#define LPDDR_BLOCK_ERASE 0x0020
+#define LPDDR_LOCK_BLOCK 0x0061
+#define LPDDR_UNLOCK_BLOCK 0x0062
+#define LPDDR_READ_BLOCK_LOCK_STATUS 0x0065
+#define LPDDR_INFO_QUERY 0x0098
+#define LPDDR_READ_OTP 0x0097
+#define LPDDR_PROG_OTP 0x00C0
+#define LPDDR_RESUME 0x00D0
+
+/* Defines possible value of PFOW command execution register */
+#define LPDDR_START_EXECUTION 0x0001
+
+/* Defines possible value of PFOW program/erase suspend register */
+#define LPDDR_SUSPEND 0x0001
+
+/* Possible values of PFOW device status register */
+/* access R - read; RC read & clearable */
+#define DSR_DPS (1<<1) /* RC; device protect status
+ * 0 - not protected 1 - locked */
+#define DSR_PSS (1<<2) /* R; program suspend status;
+ * 0-prog in progress/completed,
+ * 1- prog suspended */
+#define DSR_VPPS (1<<3) /* RC; 0-Vpp OK, * 1-Vpp low */
+#define DSR_PROGRAM_STATUS (1<<4) /* RC; 0-successful, 1-error */
+#define DSR_ERASE_STATUS (1<<5) /* RC; erase or blank check status;
+ * 0-success erase/blank check,
+ * 1 blank check error */
+#define DSR_ESS (1<<6) /* R; erase suspend status;
+ * 0-erase in progress/complete,
+ * 1 erase suspended */
+#define DSR_READY_STATUS (1<<7) /* R; Device status
+ * 0-busy,
+ * 1-ready */
+#define DSR_RPS (0x3<<8) /* RC; region program status
+ * 00 - Success,
+ * 01-re-program attempt in region with
+ * object mode data,
+ * 10-object mode program w attempt in
+ * region with control mode data
+ * 11-attempt to program invalid half
+ * with 0x41 command */
+#define DSR_AOS (1<<12) /* RC; 1- AO related failure */
+#define DSR_AVAILABLE (1<<15) /* R; Device availbility
+ * 1 - Device available
+ * 0 - not available */
+
+/* The superset of all possible error bits in DSR */
+#define DSR_ERR 0x133A
+
+static inline void send_pfow_command(struct map_info *map,
+ unsigned long cmd_code, unsigned long adr,
+ unsigned long len, map_word *datum)
+{
+ int bits_per_chip = map_bankwidth(map) * 8;
+ int chipnum;
+ struct lpddr_private *lpddr = map->fldrv_priv;
+ chipnum = adr >> lpddr->chipshift;
+
+ map_write(map, CMD(cmd_code), map->pfow_base + PFOW_COMMAND_CODE);
+ map_write(map, CMD(adr & ((1<<bits_per_chip) - 1)),
+ map->pfow_base + PFOW_COMMAND_ADDRESS_L);
+ map_write(map, CMD(adr>>bits_per_chip),
+ map->pfow_base + PFOW_COMMAND_ADDRESS_H);
+ if (len) {
+ map_write(map, CMD(len & ((1<<bits_per_chip) - 1)),
+ map->pfow_base + PFOW_DATA_COUNT_L);
+ map_write(map, CMD(len>>bits_per_chip),
+ map->pfow_base + PFOW_DATA_COUNT_H);
+ }
+ if (datum)
+ map_write(map, *datum, map->pfow_base + PFOW_COMMAND_DATA);
+
+ /* Command execution start */
+ map_write(map, CMD(LPDDR_START_EXECUTION),
+ map->pfow_base + PFOW_COMMAND_EXECUTE);
+}
+
+static inline void print_drs_error(unsigned dsr)
+{
+ int prog_status = (dsr & DSR_RPS) >> 8;
+
+ if (!(dsr & DSR_AVAILABLE))
+ printk(KERN_NOTICE"DSR.15: (0) Device not Available\n");
+ if (prog_status & 0x03)
+ printk(KERN_NOTICE"DSR.9,8: (11) Attempt to program invalid "
+ "half with 41h command\n");
+ else if (prog_status & 0x02)
+ printk(KERN_NOTICE"DSR.9,8: (10) Object Mode Program attempt "
+ "in region with Control Mode data\n");
+ else if (prog_status & 0x01)
+ printk(KERN_NOTICE"DSR.9,8: (01) Program attempt in region "
+ "with Object Mode data\n");
+ if (!(dsr & DSR_READY_STATUS))
+ printk(KERN_NOTICE"DSR.7: (0) Device is Busy\n");
+ if (dsr & DSR_ESS)
+ printk(KERN_NOTICE"DSR.6: (1) Erase Suspended\n");
+ if (dsr & DSR_ERASE_STATUS)
+ printk(KERN_NOTICE"DSR.5: (1) Erase/Blank check error\n");
+ if (dsr & DSR_PROGRAM_STATUS)
+ printk(KERN_NOTICE"DSR.4: (1) Program Error\n");
+ if (dsr & DSR_VPPS)
+ printk(KERN_NOTICE"DSR.3: (1) Vpp low detect, operation "
+ "aborted\n");
+ if (dsr & DSR_PSS)
+ printk(KERN_NOTICE"DSR.2: (1) Program suspended\n");
+ if (dsr & DSR_DPS)
+ printk(KERN_NOTICE"DSR.1: (1) Aborted Erase/Program attempt "
+ "on locked block\n");
+}
+#endif /* __LINUX_MTD_PFOW_H */
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
index c8e63a5ee72e..76f7cabf07d3 100644
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -24,6 +24,7 @@ struct physmap_flash_data {
unsigned int width;
void (*set_vpp)(struct map_info *, int);
unsigned int nr_parts;
+ unsigned int pfow_base;
struct mtd_partition *parts;
};
diff --git a/include/linux/mtd/qinfo.h b/include/linux/mtd/qinfo.h
new file mode 100644
index 000000000000..7b3d487d8b3f
--- /dev/null
+++ b/include/linux/mtd/qinfo.h
@@ -0,0 +1,91 @@
+#ifndef __LINUX_MTD_QINFO_H
+#define __LINUX_MTD_QINFO_H
+
+#include <linux/mtd/map.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/flashchip.h>
+#include <linux/mtd/partitions.h>
+
+/* lpddr_private describes lpddr flash chip in memory map
+ * @ManufactId - Chip Manufacture ID
+ * @DevId - Chip Device ID
+ * @qinfo - pointer to qinfo records describing the chip
+ * @numchips - number of chips including virual RWW partitions
+ * @chipshift - Chip/partiton size 2^chipshift
+ * @chips - per-chip data structure
+ */
+struct lpddr_private {
+ uint16_t ManufactId;
+ uint16_t DevId;
+ struct qinfo_chip *qinfo;
+ int numchips;
+ unsigned long chipshift;
+ struct flchip chips[0];
+};
+
+/* qinfo_query_info structure contains request information for
+ * each qinfo record
+ * @major - major number of qinfo record
+ * @major - minor number of qinfo record
+ * @id_str - descriptive string to access the record
+ * @desc - detailed description for the qinfo record
+ */
+struct qinfo_query_info {
+ uint8_t major;
+ uint8_t minor;
+ char *id_str;
+ char *desc;
+};
+
+/*
+ * qinfo_chip structure contains necessary qinfo records data
+ * @DevSizeShift - Device size 2^n bytes
+ * @BufSizeShift - Program buffer size 2^n bytes
+ * @TotalBlocksNum - Total number of blocks
+ * @UniformBlockSizeShift - Uniform block size 2^UniformBlockSizeShift bytes
+ * @HWPartsNum - Number of hardware partitions
+ * @SuspEraseSupp - Suspend erase supported
+ * @SingleWordProgTime - Single word program 2^SingleWordProgTime u-sec
+ * @ProgBufferTime - Program buffer write 2^ProgBufferTime u-sec
+ * @BlockEraseTime - Block erase 2^BlockEraseTime m-sec
+ */
+struct qinfo_chip {
+ /* General device info */
+ uint16_t DevSizeShift;
+ uint16_t BufSizeShift;
+ /* Erase block information */
+ uint16_t TotalBlocksNum;
+ uint16_t UniformBlockSizeShift;
+ /* Partition information */
+ uint16_t HWPartsNum;
+ /* Optional features */
+ uint16_t SuspEraseSupp;
+ /* Operation typical time */
+ uint16_t SingleWordProgTime;
+ uint16_t ProgBufferTime;
+ uint16_t BlockEraseTime;
+};
+
+/* defines for fixup usage */
+#define LPDDR_MFR_ANY 0xffff
+#define LPDDR_ID_ANY 0xffff
+#define NUMONYX_MFGR_ID 0x0089
+#define R18_DEVICE_ID_1G 0x893c
+
+static inline map_word lpddr_build_cmd(u_long cmd, struct map_info *map)
+{
+ map_word val = { {0} };
+ val.x[0] = cmd;
+ return val;
+}
+
+#define CMD(x) lpddr_build_cmd(x, map)
+#define CMDVAL(cmd) cmd.x[0]
+
+struct mtd_info *lpddr_cmdset(struct map_info *);
+
+#endif
+
diff --git a/include/linux/mtd/sharpsl.h b/include/linux/mtd/sharpsl.h
new file mode 100644
index 000000000000..25f4d2a845c1
--- /dev/null
+++ b/include/linux/mtd/sharpsl.h
@@ -0,0 +1,20 @@
+/*
+ * SharpSL NAND support
+ *
+ * Copyright (C) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+struct sharpsl_nand_platform_data {
+ struct nand_bbt_descr *badblock_pattern;
+ struct nand_ecclayout *ecc_layout;
+ struct mtd_partition *partitions;
+ unsigned int nr_partitions;
+};