Created
September 2, 2014 19:50
-
-
Save anonymous/2f23ef3561a7e225f2c8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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