Skip to content

Instantly share code, notes, and snippets.

Created September 2, 2014 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2f23ef3561a7e225f2c8 to your computer and use it in GitHub Desktop.
Save anonymous/2f23ef3561a7e225f2c8 to your computer and use it in GitHub Desktop.
diff --git a/arch/arm/configs/cyanogenmod/cyanogenmod_cooper_defconfig b/arch/arm/configs/cyanogenmod/cyanogenmod_cooper_defconfig
index 817c643..ef995b4 100644
--- a/arch/arm/configs/cyanogenmod/cyanogenmod_cooper_defconfig
+++ b/arch/arm/configs/cyanogenmod/cyanogenmod_cooper_defconfig
@@ -419,7 +419,6 @@ CONFIG_MSM_PM2=y
#
CONFIG_CPU_V6=y
CONFIG_CPU_32v6=y
-CONFIG_CPU_32v6K=y
CONFIG_CPU_ABRT_EV6=y
CONFIG_CPU_PABRT_V6=y
CONFIG_CPU_CACHE_V6=y
@@ -948,7 +947,90 @@ CONFIG_GENLOCK=y
CONFIG_GENLOCK_MISCDEVICE=y
# CONFIG_SYNC is not set
# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_TESTS=m
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_MSM_NAND=m
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
@@ -2093,6 +2175,8 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y
# CONFIG_LINE6_USB is not set
# CONFIG_VT6656 is not set
# CONFIG_IIO is not set
+# CONFIG_SNAPPY_COMPRESS is not set
+# CONFIG_SNAPPY_DECOMPRESS is not set
# CONFIG_XVMALLOC is not set
# CONFIG_ZRAM is not set
# CONFIG_ZCACHE is not set
@@ -2125,26 +2209,19 @@ CONFIG_CLKDEV_LOOKUP=y
#
# Dpram support
#
-CONFIG_DPRAM=y
-CONFIG_DPRAM_WHITELIST=y
+# CONFIG_DPRAM is not set
+# CONFIG_DPRAM_WHITELIST is not set
#
# LinuStoreIII Flash Devices (FSR)
#
-CONFIG_RFS_FSR=m
-CONFIG_RFS_FSR_STL=m
-CONFIG_RFS_STL_DELETE=y
-# CONFIG_RFS_FSR_STL_BENCHMARK is not set
-# CONFIG_FSR_DUAL_VOLUME is not set
-CONFIG_FSR_FLASH_PHYS_ADDR=0x00100000
-CONFIG_LINUSTOREIII_DEBUG_VERBOSE=0
-CONFIG_LINUSTOREIII_DEBUG=y
+# CONFIG_RFS_FSR is not set
#
# Samsung Param support
#
# CONFIG_ENABLE_MSM_PARAM is not set
-CONFIG_MSM_PARAM=m
+# CONFIG_MSM_PARAM is not set
#
# TinyFSR Support for cramfs
@@ -2223,6 +2300,8 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_YAFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 73a9bda..a27c2c6 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -387,6 +387,7 @@ struct platform_device msm_device_nand = {
.platform_data = &msm_nand_data,
},
};
+EXPORT_SYMBOL(msm_nand_data);
struct platform_device msm_device_smd = {
.name = "msm_smd",
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 5ced423..0d00d2d 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -62,7 +62,7 @@ uint32_t enable_bch_ecc;
#define FLASH_READ_ONFI_PARAMETERS_COMMAND 0xEC
#define FLASH_READ_ONFI_PARAMETERS_ADDRESS 0x00
-#define VERBOSE 0
+#define VERBOSE 1
struct msm_nand_chip {
struct device *dev;
@@ -78,6 +78,10 @@ struct msm_nand_chip {
unsigned cw_size;
};
+struct mtd_info *current_mtd = NULL;
+unsigned param_start_block;
+unsigned param_end_block;
+
#define CFG1_WIDE_FLASH (1U << 1)
/* TODO: move datamover code out */
@@ -200,6 +204,58 @@ static struct nand_ecclayout msm_nand_oob_256 = {
}
};
+/*
+ * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
+ * For now, we expose only 64 out of 80 ecc bytes
+ */
+static struct nand_ecclayout msm_flexonenand_oob_128 = {
+ .eccbytes = 64,
+ .eccpos = {
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 102, 103, 104, 105
+ },
+ .oobavail = 32,
+ .oobfree = {
+ {2, 4}, {18, 4}, {34, 4}, {50, 4},
+ {66, 4}, {82, 4}, {98, 4}, {114, 4}
+ }
+};
+
+/*
+ * onenand_oob_128 - oob info for OneNAND with 4KB page
+ *
+ * Based on specification:
+ * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
+ *
+ * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
+ *
+ * oobfree uses the spare area fields marked as
+ * "Managed by internal ECC logic for Logical Sector Number area"
+ */
+static struct nand_ecclayout msm_onenand_oob_128 = {
+ .eccbytes = 64,
+ .eccpos = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 119
+ },
+ .oobavail = 24,
+ .oobfree = {
+ {2, 3}, {18, 3}, {34, 3}, {50, 3},
+ {66, 3}, {82, 3}, {98, 3}, {114, 3}
+ }
+};
+
/**
* msm_onenand_oob_64 - oob info for large (2KB) page
*/
@@ -3991,10 +4047,10 @@ uint32_t flash_onenand_probe(struct msm_nand_chip *chip)
"==========================\n");
if ((onenand_info.manufacturer_id != 0x00EC)
- || ((onenand_info.device_id & 0x0040) != 0x0040)
+ || ((onenand_info.device_id & 0x0050) != 0x0050)
|| (onenand_info.data_buf_size != 0x0800)
|| (onenand_info.boot_buf_size != 0x0200)
- || (onenand_info.num_of_buffers != 0x0201)
+ || (onenand_info.num_of_buffers != 0x0101)
|| (onenand_info.technology != 0)) {
pr_info("%s: Detected an unsupported device\n"
@@ -4014,13 +4070,15 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
struct msm_nand_chip *chip = mtd->priv;
struct {
- dmov_s cmd[53];
+ dmov_s cmd[100];
unsigned cmdptr;
struct {
uint32_t sfbcfg;
- uint32_t sfcmd[9];
+ uint32_t sfcmd[14];
+ uint32_t xfr[7];
+ uint32_t cmd_addr[3];
uint32_t sfexec;
- uint32_t sfstat[9];
+ uint32_t sfstat[14];
uint32_t addr0;
uint32_t addr1;
uint32_t addr2;
@@ -4035,7 +4093,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
uint32_t data4;
uint32_t data5;
uint32_t data6;
- uint32_t macro[5];
+ uint32_t macro[10];
} data;
} *dma_buffer;
dmov_s *cmd;
@@ -4198,12 +4256,14 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
onenand_startaddr8 = (((uint32_t)from_curr &
(mtd->erasesize - 1)) / mtd->writesize) << 2;
onenand_startbuffer = DATARAM0_0 << 8;
- onenand_sysconfig1 = (ops->mode == MTD_OOB_RAW) ?
+ /*onenand_sysconfig1 = (ops->mode == MTD_OOB_RAW) ?
ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
- ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
+ ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);*/
+ onenand_sysconfig1 = 0x80FE;
- dma_buffer->data.sfbcfg = SFLASH_BCFG |
- (nand_sfcmd_mode ? 0 : (1 << 24));
+/* dma_buffer->data.sfbcfg = SFLASH_BCFG |
+ (nand_sfcmd_mode ? 0 : (1 << 24));*/
+ dma_buffer->data.sfbcfg = SFLASH_BCFG;
dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
@@ -4232,14 +4292,58 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
MSM_NAND_SFCMD_DATXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_DATRD);
- dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(32, 0, 0,
+ dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_DATXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATRD);
+ dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_DATXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATRD);
+ dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_DATXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATRD);
+ dma_buffer->data.sfcmd[10] = SFLASH_PREPCMD(256, 0, 0,
MSM_NAND_SFCMD_DATXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_DATRD);
- dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(4, 10, 0,
+ dma_buffer->data.sfcmd[11] = SFLASH_PREPCMD(32, 0, 0,
+ MSM_NAND_SFCMD_DATXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATRD);
+ dma_buffer->data.sfcmd[12] = SFLASH_PREPCMD(4, 10, 0,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_REGWR);
+ dma_buffer->data.sfcmd[13] = SFLASH_PREPCMD(32, 0, 0,
+ MSM_NAND_SFCMD_DATXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATRD);
+/*
+ dma_buffer->data.sfcmd[0] = 0x100003;
+ dma_buffer->data.sfcmd[1] = 0x100005;
+ dma_buffer->data.sfcmd[2] = 0x100002;
+ dma_buffer->data.sfcmd[4] = 0x10000006;
+ dma_buffer->data.sfcmd[5] = 0x10000006;
+ dma_buffer->data.sfcmd[6] = 0x10000006;
+ dma_buffer->data.sfcmd[7] = 0x10000006;
+ dma_buffer->data.sfcmd[8] = 0x10000006;
+ dma_buffer->data.sfcmd[9] = 0x10000006;
+ dma_buffer->data.sfcmd[10] = 0x10000006;
+ dma_buffer->data.sfcmd[11] = 0x10000006;
+ dma_buffer->data.sfcmd[12] = 0x10000006;
+ dma_buffer->data.sfcmd[13] = 0x100003;*/
+ dma_buffer->data.xfr[0] = 0x47804780;
+ dma_buffer->data.xfr[1] = 0x03A003A0;
+ dma_buffer->data.xfr[2] = 0x11B911B9;
+ dma_buffer->data.xfr[3] = 0x85A085A0;
+ dma_buffer->data.xfr[4] = 0xC020C020;
+ dma_buffer->data.xfr[5] = 0xC020C020;
+ dma_buffer->data.xfr[6] = 0xC020C020;
+ dma_buffer->data.cmd_addr[0] = 0;
+ dma_buffer->data.cmd_addr[1] = 0;
+ dma_buffer->data.cmd_addr[2] = 0;
dma_buffer->data.sfexec = 1;
dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
@@ -4250,6 +4354,11 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[10] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[11] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[12] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[13] = CLEAN_DATA_32;
dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
(ONENAND_SYSTEM_CONFIG_1);
dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
@@ -4282,12 +4391,87 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
dma_buffer->data.macro[1] = 0x0300;
dma_buffer->data.macro[2] = 0x0400;
dma_buffer->data.macro[3] = 0x0500;
- dma_buffer->data.macro[4] = 0x8010;
+ dma_buffer->data.macro[4] = 0x0600;
+ dma_buffer->data.macro[5] = 0x0700;
+ dma_buffer->data.macro[6] = 0x0800;
+ dma_buffer->data.macro[7] = 0x0900;
+ dma_buffer->data.macro[8] = 0x8010;
+ dma_buffer->data.macro[9] = 0x8030;
/*************************************************************/
/* Write necessary address registers in the onenand device */
/*************************************************************/
+ /* Write MSM_NAND_DEV_CMD0 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd_addr[0]);
+ cmd->dst = MSM_NAND_DEV_CMD0;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write MSM_NAND_DEV_CMD1 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd_addr[1]);
+ cmd->dst = MSM_NAND_DEV_CMD1;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write MSM_NAND_DEV_CMD2 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd_addr[2]);
+ cmd->dst = MSM_NAND_DEV_CMD2;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP1 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[0]);
+ cmd->dst = MSM_NAND_XFR_STEP1;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP2 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[1]);
+ cmd->dst = MSM_NAND_XFR_STEP2;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP3 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[2]);
+ cmd->dst = MSM_NAND_XFR_STEP3;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP4 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[3]);
+ cmd->dst = MSM_NAND_XFR_STEP4;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP5 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[4]);
+ cmd->dst = MSM_NAND_XFR_STEP5;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP6 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[5]);
+ cmd->dst = MSM_NAND_XFR_STEP6;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write XFR_STEP7 */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.xfr[6]);
+ cmd->dst = MSM_NAND_XFR_STEP7;
+ cmd->len = 4;
+ cmd++;
+
/* Enable and configure the SFlash controller */
cmd->cmd = 0;
cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
@@ -4424,7 +4608,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
(ONENAND_CMDLOAD);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 8; i++) {
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
@@ -4473,7 +4657,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
cmd->src = msm_virt_to_dma(chip,
- &dma_buffer->data.sfcmd[7]);
+ &dma_buffer->data.sfcmd[11]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -4481,7 +4665,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
/* Write the MACRO1 register */
cmd->cmd = 0;
cmd->src = msm_virt_to_dma(chip,
- &dma_buffer->data.macro[4]);
+ &dma_buffer->data.macro[8]);
cmd->dst = MSM_NAND_MACRO1_REG;
cmd->len = 4;
cmd++;
@@ -4498,13 +4682,13 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
cmd->dst = msm_virt_to_dma(chip,
- &dma_buffer->data.sfstat[7]);
+ &dma_buffer->data.sfstat[11]);
cmd->len = 4;
cmd++;
/* Transfer nand ctlr buffer contents into usr buf */
if (ops->mode == MTD_OOB_AUTO) {
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
+ for (i = 0; i < 4; i++) {
cmd->cmd = 0;
cmd->src = MSM_NAND_FLASH_BUFFER +
mtd->ecclayout->oobfree[i].offset;
@@ -4520,16 +4704,82 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
cmd->cmd = 0;
cmd->src = MSM_NAND_FLASH_BUFFER;
cmd->dst = oob_dma_addr_curr;
- cmd->len = mtd->oobsize;
- oob_dma_addr_curr += mtd->oobsize;
+ cmd->len = 64;
+ oob_dma_addr_curr += 64;
cmd++;
}
if (ops->mode == MTD_OOB_RAW) {
cmd->cmd = 0;
cmd->src = MSM_NAND_FLASH_BUFFER;
cmd->dst = data_dma_addr_curr;
- cmd->len = mtd->oobsize;
- data_dma_addr_curr += mtd->oobsize;
+ cmd->len = 64;
+ data_dma_addr_curr += 64;
+ cmd++;
+ }
+ }
+ // read second spareRAM
+ if ((ops->oobbuf) || (ops->mode == MTD_OOB_RAW)) {
+
+ /* Block on cmd ready and write CMD register */
+ cmd->cmd = DST_CRCI_NAND_CMD;
+ cmd->src = msm_virt_to_dma(chip,
+ &dma_buffer->data.sfcmd[13]);
+ cmd->dst = MSM_NAND_SFLASHC_CMD;
+ cmd->len = 4;
+ cmd++;
+
+ /* Write the MACRO1 register */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip,
+ &dma_buffer->data.macro[9]);
+ cmd->dst = MSM_NAND_MACRO1_REG;
+ cmd->len = 4;
+ cmd++;
+
+ /* Kick the execute command */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip,
+ &dma_buffer->data.sfexec);
+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
+ cmd->len = 4;
+ cmd++;
+
+ /* Block on data ready, and read status register */
+ cmd->cmd = SRC_CRCI_NAND_DATA;
+ cmd->src = MSM_NAND_SFLASHC_STATUS;
+ cmd->dst = msm_virt_to_dma(chip,
+ &dma_buffer->data.sfstat[13]);
+ cmd->len = 4;
+ cmd++;
+
+ /* Transfer nand ctlr buffer contents into usr buf */
+ if (ops->mode == MTD_OOB_AUTO) {
+ for (i = 4; i < 8; i++) {
+ cmd->cmd = 0;
+ cmd->src = MSM_NAND_FLASH_BUFFER +
+ (mtd->ecclayout->oobfree[i].offset - 64);
+ cmd->dst = oob_dma_addr_curr;
+ cmd->len =
+ mtd->ecclayout->oobfree[i].length;
+ oob_dma_addr_curr +=
+ mtd->ecclayout->oobfree[i].length;
+ cmd++;
+ }
+ }
+ if (ops->mode == MTD_OOB_PLACE) {
+ cmd->cmd = 0;
+ cmd->src = MSM_NAND_FLASH_BUFFER;
+ cmd->dst = oob_dma_addr_curr;
+ cmd->len = 64;
+ oob_dma_addr_curr += 64;
+ cmd++;
+ }
+ if (ops->mode == MTD_OOB_RAW) {
+ cmd->cmd = 0;
+ cmd->src = MSM_NAND_FLASH_BUFFER;
+ cmd->dst = data_dma_addr_curr;
+ cmd->len = 64;
+ data_dma_addr_curr += 64;
cmd++;
}
}
@@ -4540,7 +4790,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[12]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -4555,12 +4805,12 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[12]);
cmd->len = 4;
cmd++;
- BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
+ BUILD_BUG_ON(100 != ARRAY_SIZE(dma_buffer->cmd));
BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
dma_buffer->cmd[0].cmd |= CMD_OCB;
cmd[-1].cmd |= CMD_OCU | CMD_LC;
@@ -4583,7 +4833,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
#if VERBOSE
pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
- "%x %x\n", __func__,
+ "%x %x %x %x %x %x %x\n", __func__,
dma_buffer->data.sfstat[0],
dma_buffer->data.sfstat[1],
dma_buffer->data.sfstat[2],
@@ -4592,7 +4842,12 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
dma_buffer->data.sfstat[5],
dma_buffer->data.sfstat[6],
dma_buffer->data.sfstat[7],
- dma_buffer->data.sfstat[8]);
+ dma_buffer->data.sfstat[8],
+ dma_buffer->data.sfstat[9],
+ dma_buffer->data.sfstat[10],
+ dma_buffer->data.sfstat[11],
+ dma_buffer->data.sfstat[12],
+ dma_buffer->data.sfstat[13]);
pr_info("%s: controller_status = %x\n", __func__,
controller_status);
@@ -4606,7 +4861,7 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
|| (dma_buffer->data.sfstat[0] & 0x110)
|| (dma_buffer->data.sfstat[1] & 0x110)
|| (dma_buffer->data.sfstat[2] & 0x110)
- || (dma_buffer->data.sfstat[8] & 0x110)
+ || (dma_buffer->data.sfstat[12] & 0x110)
|| ((dma_buffer->data.sfstat[3] & 0x110) &&
(ops->datbuf))
|| ((dma_buffer->data.sfstat[4] & 0x110) &&
@@ -4616,6 +4871,17 @@ int msm_onenand_read_oob(struct mtd_info *mtd,
|| ((dma_buffer->data.sfstat[6] & 0x110) &&
(ops->datbuf))
|| ((dma_buffer->data.sfstat[7] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[8] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[9] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[10] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[11] & 0x110) &&
+ ((ops->oobbuf)
+ || (ops->mode == MTD_OOB_RAW)))
+ || ((dma_buffer->data.sfstat[13] & 0x110) &&
((ops->oobbuf)
|| (ops->mode == MTD_OOB_RAW)))) {
pr_info("%s: ECC/MPU/OP error\n", __func__);
@@ -4695,13 +4961,13 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
struct msm_nand_chip *chip = mtd->priv;
struct {
- dmov_s cmd[53];
+ dmov_s cmd[78];
unsigned cmdptr;
struct {
uint32_t sfbcfg;
- uint32_t sfcmd[10];
+ uint32_t sfcmd[15];
uint32_t sfexec;
- uint32_t sfstat[10];
+ uint32_t sfstat[15];
uint32_t addr0;
uint32_t addr1;
uint32_t addr2;
@@ -4716,7 +4982,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
uint32_t data4;
uint32_t data5;
uint32_t data6;
- uint32_t macro[5];
+ uint32_t macro[10];
} data;
} *dma_buffer;
dmov_s *cmd;
@@ -4844,13 +5110,13 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
return -EINVAL;
}
- init_spare_bytes = kmalloc(64, GFP_KERNEL);
+ init_spare_bytes = kmalloc(mtd->oobsize, GFP_KERNEL);
if (!init_spare_bytes) {
pr_err("%s: failed to alloc init_spare_bytes buffer\n",
__func__);
return -ENOMEM;
}
- for (i = 0; i < 64; i++)
+ for (i = 0; i < mtd->oobsize; i++)
init_spare_bytes[i] = 0xFF;
if ((ops->oobbuf) && (ops->mode == MTD_OOB_AUTO)) {
@@ -4884,7 +5150,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
}
}
- init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, 64,
+ init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, mtd->oobsize,
DMA_TO_DEVICE);
if (dma_mapping_error(chip->dev, init_dma_addr)) {
pr_err("%s: failed to get dma addr for %p\n",
@@ -4943,26 +5209,46 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_DATWR);
- dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(32, 0, 0,
+ dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_CMDXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATWR);
+ dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(256, 0, 0,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_DATWR);
- dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(1, 6, 0,
+ dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_CMDXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATWR);
+ dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(256, 0, 0,
+ MSM_NAND_SFCMD_CMDXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATWR);
+ dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(32, 0, 0,
+ MSM_NAND_SFCMD_CMDXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATWR);
+ dma_buffer->data.sfcmd[10] = SFLASH_PREPCMD(1, 6, 0,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_REGWR);
- dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(0, 0, 32,
+ dma_buffer->data.sfcmd[11] = SFLASH_PREPCMD(0, 0, 32,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_INTHI);
- dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(3, 7, 0,
+ dma_buffer->data.sfcmd[12] = SFLASH_PREPCMD(3, 7, 0,
MSM_NAND_SFCMD_DATXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_REGRD);
- dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(4, 10, 0,
+ dma_buffer->data.sfcmd[13] = SFLASH_PREPCMD(4, 10, 0,
MSM_NAND_SFCMD_CMDXS,
nand_sfcmd_mode,
MSM_NAND_SFCMD_REGWR);
+ dma_buffer->data.sfcmd[14] = SFLASH_PREPCMD(32, 0, 0,
+ MSM_NAND_SFCMD_CMDXS,
+ nand_sfcmd_mode,
+ MSM_NAND_SFCMD_DATWR);
dma_buffer->data.sfexec = 1;
dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
@@ -4974,6 +5260,11 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[10] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[11] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[12] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[13] = CLEAN_DATA_32;
+ dma_buffer->data.sfstat[14] = CLEAN_DATA_32;
dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
(ONENAND_SYSTEM_CONFIG_1);
dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
@@ -5006,7 +5297,12 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
dma_buffer->data.macro[1] = 0x0300;
dma_buffer->data.macro[2] = 0x0400;
dma_buffer->data.macro[3] = 0x0500;
- dma_buffer->data.macro[4] = 0x8010;
+ dma_buffer->data.macro[4] = 0x0600;
+ dma_buffer->data.macro[5] = 0x0700;
+ dma_buffer->data.macro[6] = 0x0800;
+ dma_buffer->data.macro[7] = 0x0900;
+ dma_buffer->data.macro[8] = 0x8010;
+ dma_buffer->data.macro[9] = 0x8030;
/*************************************************************/
@@ -5084,7 +5380,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
(ONENAND_CMDPROG);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 8; i++) {
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
@@ -5131,7 +5427,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[5]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -5143,36 +5439,99 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
cmd->cmd = 0;
cmd->src = init_dma_addr;
cmd->dst = MSM_NAND_FLASH_BUFFER;
- cmd->len = mtd->oobsize;
+ cmd->len = 64;
+ cmd++;
+ }
+ if (ops->mode == MTD_OOB_PLACE) {
+ cmd->cmd = 0;
+ cmd->src = oob_dma_addr_curr;
+ cmd->dst = MSM_NAND_FLASH_BUFFER;
+ cmd->len = 64;
+ oob_dma_addr_curr += 64;
+ cmd++;
+ }
+ if (ops->mode == MTD_OOB_RAW) {
+ cmd->cmd = 0;
+ cmd->src = data_dma_addr_curr;
+ cmd->dst = MSM_NAND_FLASH_BUFFER;
+ cmd->len = 64;
+ data_dma_addr_curr += 64;
+ cmd++;
+ }
+ } else {
+ cmd->cmd = 0;
+ cmd->src = init_dma_addr;
+ cmd->dst = MSM_NAND_FLASH_BUFFER;
+ cmd->len = 64;
+ cmd++;
+ }
+
+ /* Write the MACRO1 register */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[8]);
+ cmd->dst = MSM_NAND_MACRO1_REG;
+ cmd->len = 4;
+ cmd++;
+
+ /* Kick the execute command */
+ cmd->cmd = 0;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
+ cmd->len = 4;
+ cmd++;
+
+ /* Block on data ready, and read the status register */
+ cmd->cmd = SRC_CRCI_NAND_DATA;
+ cmd->src = MSM_NAND_SFLASHC_STATUS;
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
+ cmd->len = 4;
+ cmd++;
+
+ //write the 2o spareRAM
+ /* Block on cmd ready and write CMD register */
+ cmd->cmd = DST_CRCI_NAND_CMD;
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[14]);
+ cmd->dst = MSM_NAND_SFLASHC_CMD;
+ cmd->len = 4;
+ cmd++;
+
+ if ((ops->oobbuf) || (ops->mode == MTD_OOB_RAW)) {
+
+ /* Transfer user buf contents into nand ctlr buffer */
+ if (ops->mode == MTD_OOB_AUTO) {
+ cmd->cmd = 0;
+ cmd->src = (init_dma_addr + 64);
+ cmd->dst = MSM_NAND_FLASH_BUFFER;
+ cmd->len = 64;
cmd++;
}
if (ops->mode == MTD_OOB_PLACE) {
cmd->cmd = 0;
cmd->src = oob_dma_addr_curr;
cmd->dst = MSM_NAND_FLASH_BUFFER;
- cmd->len = mtd->oobsize;
- oob_dma_addr_curr += mtd->oobsize;
+ cmd->len = 64;
+ oob_dma_addr_curr += 64;
cmd++;
}
if (ops->mode == MTD_OOB_RAW) {
cmd->cmd = 0;
cmd->src = data_dma_addr_curr;
cmd->dst = MSM_NAND_FLASH_BUFFER;
- cmd->len = mtd->oobsize;
- data_dma_addr_curr += mtd->oobsize;
+ cmd->len = 64;
+ data_dma_addr_curr += 64;
cmd++;
}
} else {
cmd->cmd = 0;
cmd->src = init_dma_addr;
cmd->dst = MSM_NAND_FLASH_BUFFER;
- cmd->len = mtd->oobsize;
+ cmd->len = 64;
cmd++;
}
/* Write the MACRO1 register */
cmd->cmd = 0;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[4]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[9]);
cmd->dst = MSM_NAND_MACRO1_REG;
cmd->len = 4;
cmd++;
@@ -5187,17 +5546,18 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[5]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[14]);
cmd->len = 4;
cmd++;
+
/*********************************************************/
/* Issuing write command */
/*********************************************************/
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[6]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[10]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -5212,7 +5572,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[6]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[10]);
cmd->len = 4;
cmd++;
@@ -5222,7 +5582,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[7]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[11]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -5237,7 +5597,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[7]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[11]);
cmd->len = 4;
cmd++;
@@ -5247,7 +5607,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[12]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -5262,7 +5622,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[12]);
cmd->len = 4;
cmd++;
@@ -5286,7 +5646,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on cmd ready and write CMD register */
cmd->cmd = DST_CRCI_NAND_CMD;
- cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[13]);
cmd->dst = MSM_NAND_SFLASHC_CMD;
cmd->len = 4;
cmd++;
@@ -5301,12 +5661,12 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Block on data ready, and read the status register */
cmd->cmd = SRC_CRCI_NAND_DATA;
cmd->src = MSM_NAND_SFLASHC_STATUS;
- cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[13]);
cmd->len = 4;
cmd++;
- BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
+ BUILD_BUG_ON(78 != ARRAY_SIZE(dma_buffer->cmd));
BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
dma_buffer->cmd[0].cmd |= CMD_OCB;
cmd[-1].cmd |= CMD_OCU | CMD_LC;
@@ -5326,7 +5686,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
#if VERBOSE
pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
- " %x %x %x\n", __func__,
+ " %x %x %x %x %x %x %x %x\n", __func__,
dma_buffer->data.sfstat[0],
dma_buffer->data.sfstat[1],
dma_buffer->data.sfstat[2],
@@ -5336,7 +5696,12 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
dma_buffer->data.sfstat[6],
dma_buffer->data.sfstat[7],
dma_buffer->data.sfstat[8],
- dma_buffer->data.sfstat[9]);
+ dma_buffer->data.sfstat[9],
+ dma_buffer->data.sfstat[10],
+ dma_buffer->data.sfstat[11],
+ dma_buffer->data.sfstat[12],
+ dma_buffer->data.sfstat[13],
+ dma_buffer->data.sfstat[14]);
pr_info("%s: controller_status = %x\n", __func__,
controller_status);
@@ -5348,10 +5713,10 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
/* Check for errors, protection violations etc */
if ((controller_status != 0)
|| (dma_buffer->data.sfstat[0] & 0x110)
- || (dma_buffer->data.sfstat[6] & 0x110)
- || (dma_buffer->data.sfstat[7] & 0x110)
- || (dma_buffer->data.sfstat[8] & 0x110)
- || (dma_buffer->data.sfstat[9] & 0x110)
+ || (dma_buffer->data.sfstat[10] & 0x110)
+ || (dma_buffer->data.sfstat[11] & 0x110)
+ || (dma_buffer->data.sfstat[12] & 0x110)
+ || (dma_buffer->data.sfstat[13] & 0x110)
|| ((dma_buffer->data.sfstat[1] & 0x110) &&
(ops->datbuf))
|| ((dma_buffer->data.sfstat[2] & 0x110) &&
@@ -5361,6 +5726,17 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
|| ((dma_buffer->data.sfstat[4] & 0x110) &&
(ops->datbuf))
|| ((dma_buffer->data.sfstat[5] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[6] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[7] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[8] & 0x110) &&
+ (ops->datbuf))
+ || ((dma_buffer->data.sfstat[9] & 0x110) &&
+ ((ops->oobbuf)
+ || (ops->mode == MTD_OOB_RAW)))
+ || ((dma_buffer->data.sfstat[14] & 0x110) &&
((ops->oobbuf)
|| (ops->mode == MTD_OOB_RAW)))) {
pr_info("%s: ECC/MPU/OP error\n", __func__);
@@ -5375,7 +5751,7 @@ static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
- dma_unmap_page(chip->dev, init_dma_addr, 64, DMA_TO_DEVICE);
+ dma_unmap_page(chip->dev, init_dma_addr, mtd->oobsize, DMA_TO_DEVICE);
err_dma_map_initbuf_failed:
if (ops->oobbuf) {
@@ -5806,18 +6182,18 @@ static int msm_onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
return -EINVAL;
}
- buffer = kmalloc(2112, GFP_KERNEL|GFP_DMA);
+ buffer = kmalloc(4224, GFP_KERNEL|GFP_DMA);
if (buffer == 0) {
pr_err("%s: Could not kmalloc for buffer\n",
__func__);
return -ENOMEM;
}
- memset(buffer, 0x00, 2112);
- oobptr = &(buffer[2048]);
+ memset(buffer, 0x00, 4224);
+ oobptr = &(buffer[4096]);
ops.mode = MTD_OOB_RAW;
- ops.len = 2112;
+ ops.len = 4224;
ops.retlen = 0;
ops.ooblen = 0;
ops.oobretlen = 0;
@@ -5837,7 +6213,11 @@ static int msm_onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) ||
(oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) ||
(oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) ||
- (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF)
+ (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF) ||
+ (oobptr[64] != 0xFF) || (oobptr[65] != 0xFF) ||
+ (oobptr[80] != 0xFF) || (oobptr[81] != 0xFF) ||
+ (oobptr[96] != 0xFF) || (oobptr[97] != 0xFF) ||
+ (oobptr[112] != 0xFF) || (oobptr[113] != 0xFF)
) {
ret = 1;
break;
@@ -5870,7 +6250,7 @@ static int msm_onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
buffer = page_address(ZERO_PAGE());
ops.mode = MTD_OOB_RAW;
- ops.len = 2112;
+ ops.len = 4224;
ops.retlen = 0;
ops.ooblen = 0;
ops.oobretlen = 0;
@@ -6620,6 +7000,124 @@ static int msm_onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return err;
}
+int msm_onenand_read_dpram(char *mBuf, unsigned size)
+{
+ //char spare_buf[128] = { 0, };
+ struct mtd_oob_ops ops = { 0, };
+ unsigned offset = 0;
+
+ if(NULL == current_mtd)
+ {
+ printk("[msm_nand_read_dpram] MTD not initialized\n");
+ return -1;
+ }
+ if(size < current_mtd->writesize)
+ {
+ printk("[msm_nand_read_dpram] given buffer has invalid size\n");
+ return -1;
+ }
+
+ /* needed data is hardcoded at 5th page of the last block */
+ offset = ((5 * current_mtd->writesize) + (current_mtd->erasesize * (((unsigned )current_mtd->size / (unsigned )current_mtd->erasesize) - 1)));
+
+ //ops.mode = MTD_OOB_RAW;
+ ops.mode = MTD_OOB_PLACE;
+ ops.datbuf = mBuf;
+ //ops.len = current_mtd->writesize + current_mtd->oobsize;
+ ops.len = current_mtd->writesize;
+ ops.oobbuf = NULL;
+ ops.ooblen = 0;
+ ops.retlen = 0;
+ ops.oobretlen = 0;
+
+ printk("[msm_onenand_read_dpram] number of blocks = %u, offset = %u, page size = %u, block size = %u\n", (unsigned )current_mtd->size / (unsigned )current_mtd->erasesize, offset, current_mtd->writesize, current_mtd->erasesize);
+
+ return msm_onenand_read_oob(current_mtd, offset, &ops);
+}
+EXPORT_SYMBOL(msm_onenand_read_dpram);
+
+void msm_onenand_read_param(char *mBuf)
+{
+ char data_buf[4096] = { 0, };
+ struct mtd_oob_ops ops = { 0, };
+ int data_size = 0;
+
+ if (current_mtd->oobsize == 64) {
+ data_size = 2048;
+ }
+ else if (current_mtd->oobsize == 128) {
+ data_size = 4096;
+ }
+
+ ops.mode = MTD_OOB_PLACE;
+ ops.len = data_size;
+ ops.retlen = 0;
+ ops.oobretlen = 0;
+ ops.ooblen = 0;
+ ops.datbuf = data_buf;
+ ops.oobbuf = NULL;
+
+ // erasize == size of entire block == page size * pages per block
+ while(msm_onenand_block_isbad(current_mtd, (param_start_block * current_mtd->erasesize)))
+ {
+ printk("msm_read_param: bad block\n");
+ param_start_block++;
+ }
+
+ if ( param_start_block >= param_end_block) {
+ param_start_block = param_end_block - 1;
+ printk("All nand block in param partition has been crashed\n");
+ }
+
+ msm_onenand_read_oob(current_mtd, (param_start_block * current_mtd->erasesize), &ops);
+ memcpy(mBuf,data_buf,sizeof(data_buf));
+}
+EXPORT_SYMBOL(msm_onenand_read_param);
+
+void msm_onenand_write_param(char *mBuf)
+{
+ char data_buf[4096] = { 0, };
+ struct mtd_oob_ops ops = { 0, };
+ struct erase_info *param_erase_info = 0;
+ int data_size = 0;
+
+ if (current_mtd->oobsize == 64) {
+ data_size = 2048;
+ }
+ else if (current_mtd->oobsize == 128) {
+ data_size = 4096;
+ }
+
+ param_erase_info = kzalloc(sizeof(struct erase_info), GFP_KERNEL);
+ if(0 == param_erase_info)
+ {
+ printk("msm_write_param: memory allocation error\n");
+ return;
+ }
+ param_erase_info->mtd = current_mtd;
+ // erasize == size of entire block == page size * pages per block
+ param_erase_info->addr = param_start_block * current_mtd->erasesize;
+ param_erase_info->len = current_mtd->erasesize;
+ if(!msm_onenand_erase(current_mtd, param_erase_info)) {
+ pr_info("parameter block erase success\n");
+ }
+
+ memcpy(data_buf,mBuf,sizeof(data_buf));
+
+ ops.mode = MTD_OOB_PLACE;
+ ops.len = data_size;
+ ops.retlen = 0;
+ ops.oobretlen = 0;
+ ops.ooblen = 0;
+ ops.datbuf = data_buf;
+ ops.oobbuf = NULL;
+
+ msm_onenand_write_oob(current_mtd, param_erase_info->addr, &ops);
+
+ kfree(param_erase_info);
+}
+EXPORT_SYMBOL(msm_onenand_write_param);
+
static int msm_onenand_suspend(struct mtd_info *mtd)
{
return 0;
@@ -6632,17 +7130,18 @@ static void msm_onenand_resume(struct mtd_info *mtd)
int msm_onenand_scan(struct mtd_info *mtd, int maxchips)
{
struct msm_nand_chip *chip = mtd->priv;
+ int i;
/* Probe and check whether onenand device is present */
if (flash_onenand_probe(chip))
return -ENODEV;
mtd->size = 0x1000000 << ((onenand_info.device_id & 0xF0) >> 4);
- mtd->writesize = onenand_info.data_buf_size;
+ mtd->writesize = onenand_info.data_buf_size << 1;
mtd->oobsize = mtd->writesize >> 5;
mtd->erasesize = mtd->writesize << 6;
- mtd->oobavail = msm_onenand_oob_64.oobavail;
- mtd->ecclayout = &msm_onenand_oob_64;
+ mtd->oobavail = msm_onenand_oob_128.oobavail;
+ mtd->ecclayout = &msm_onenand_oob_128;
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
@@ -6662,6 +7161,15 @@ int msm_onenand_scan(struct mtd_info *mtd, int maxchips)
mtd->owner = THIS_MODULE;
pr_info("Found a supported onenand device\n");
+
+ current_mtd = mtd; // for PARAMETER block
+
+ for ( i = 0 ; i < msm_nand_data.nr_parts ; i++) {
+ if (!strcmp(msm_nand_data.parts[i].name , "parameter")) {
+ param_start_block = msm_nand_data.parts[i].offset;
+ param_end_block = msm_nand_data.parts[i].offset + msm_nand_data.parts[i].size; // should match with bootloader
+ }
+ }
return 0;
}
@@ -6688,10 +7196,13 @@ int msm_nand_scan(struct mtd_info *mtd, int maxchips)
struct nand_flash_dev *flashdev = NULL;
struct nand_manufacturers *flashman = NULL;
+#if !defined (CONFIG_MACH_COOPER) && !defined (CONFIG_MACH_EUROPA)
/* Probe the Flash device for ONFI compliance */
if (!flash_onfi_probe(chip)) {
dev_found = 1;
- } else {
+ } else
+#endif
+ {
/* Read the Flash ID from the Nand Flash Device */
flash_id = flash_read_id(chip);
manid = flash_id & 0xFF;
diff --git a/drivers/mtd/devices/msm_nand.h b/drivers/mtd/devices/msm_nand.h
index 2729c6b..d0bd3d0 100644
--- a/drivers/mtd/devices/msm_nand.h
+++ b/drivers/mtd/devices/msm_nand.h
@@ -116,7 +116,8 @@ extern unsigned long ebi2_register_base;
#define SFLASH_PREPCMD(numxfr, offval, delval, trnstp, mode, opcode) \
((numxfr<<20)|(offval<<12)|(delval<<6)|(trnstp<<5)|(mode<<4)|opcode)
-#define SFLASH_BCFG 0x20100327
+//#define SFLASH_BCFG 0x20100327
+#define SFLASH_BCFG 0x60100327
/* Onenand addresses */
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 630be3e..63cc80e 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -542,6 +542,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
}
slave->mtd.ecclayout = master->ecclayout;
+#if 0
if (master->block_isbad) {
uint64_t offs = 0;
@@ -552,6 +553,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
offs += slave->mtd.erasesize;
}
}
+#endif
out_register:
return slave;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment