Created
September 3, 2013 05:36
-
-
Save psyke83/6420048 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/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c | |
index f7f9071..8cc7faa 100755 | |
--- 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/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c | |
index 3af04ba..331b19a 100755 | |
--- a/arch/arm/mach-msm/pm2.c | |
+++ b/arch/arm/mach-msm/pm2.c | |
@@ -1782,9 +1782,11 @@ static uint32_t restart_reason = 0x776655AA; | |
struct smem_info { | |
unsigned int info; | |
}; | |
- | |
+ | |
+#ifdef CONFIG_DPRAM | |
extern struct smem_info *smem_flag; | |
extern void request_phone_power_off_reset(int flag); | |
+#endif | |
int power_off_done; | |
int (*set_recovery_mode)(void); | |
EXPORT_SYMBOL(set_recovery_mode); | |
@@ -1798,9 +1800,11 @@ static void msm_pm_power_off(void) | |
#if !defined(CONFIG_MACH_EUROPA) && !defined(CONFIG_MACH_CALLISTO) && !defined(CONFIG_MACH_COOPER) && !defined(CONFIG_MACH_GIO) && !defined(CONFIG_MACH_BENI) && !defined(CONFIG_MACH_TASS) && !defined(CONFIG_MACH_TASSDT) && !defined(CONFIG_MACH_LUCAS) | |
msm_proc_comm(PCOM_POWER_DOWN, 0, 0); | |
#else | |
+#ifdef CONFIG_DPRAM | |
smem_flag->info = 0x0; | |
printk("request_phone_power_off\n"); | |
request_phone_power_off_reset(1); | |
+#endif | |
power_off_done = 1; | |
printk("Do Nothing!!\n"); | |
#endif | |
@@ -1813,7 +1817,7 @@ static void msm_pm_restart(char str, const char *cmd) | |
is_modem_reset = 1; | |
pr_err("is_modem_reset = %d\n",is_modem_reset); | |
msm_rpcrouter_close(); | |
-#if defined(CONFIG_MACH_EUROPA) || defined(CONFIG_MACH_CALLISTO) || defined(CONFIG_MACH_COOPER) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_BENI) || defined(CONFIG_MACH_TASS) || defined(CONFIG_MACH_LUCAS) | |
+#if (defined(CONFIG_MACH_EUROPA) || defined(CONFIG_MACH_CALLISTO) || defined(CONFIG_MACH_COOPER) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_BENI) || defined(CONFIG_MACH_TASS) || defined(CONFIG_MACH_LUCAS)) && defined(CONFIG_DPRAM) | |
smem_flag->info = 0x0; | |
#endif | |
printk("send PCOM_RESET_CHIP\n"); | |
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c | |
index 92b5862..b4173ca 100755 | |
--- a/drivers/mtd/devices/msm_nand.c | |
+++ b/drivers/mtd/devices/msm_nand.c | |
@@ -161,6 +161,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 | |
*/ | |
@@ -3799,7 +3851,7 @@ void msm_read_param(char *mBuf) | |
ops.datbuf = data_buf; | |
ops.oobbuf = spare_buf; | |
- /* erasize == size of entire block == page size * pages per block */ | |
+ // erasize == size of entire block == page size * pages per block | |
while(msm_nand_block_isbad(current_mtd, (param_start_block * current_mtd->erasesize))) | |
{ | |
printk("msm_read_param: bad block\n"); | |
@@ -3838,7 +3890,7 @@ void msm_write_param(char *mBuf) | |
return; | |
} | |
param_erase_info->mtd = current_mtd; | |
- /* erasize == size of entire block == page size * pages per block */ | |
+ // 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_nand_erase(current_mtd, param_erase_info)) { | |
@@ -4066,10 +4118,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" | |
@@ -4089,13 +4141,13 @@ int msm_onenand_read_oob(struct mtd_info *mtd, | |
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[9]; | |
+ uint32_t sfcmd[14]; | |
uint32_t sfexec; | |
- uint32_t sfstat[9]; | |
+ uint32_t sfstat[14]; | |
uint32_t addr0; | |
uint32_t addr1; | |
uint32_t addr2; | |
@@ -4110,7 +4162,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; | |
@@ -4313,14 +4365,34 @@ 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.sfexec = 1; | |
dma_buffer->data.sfstat[0] = CLEAN_DATA_32; | |
dma_buffer->data.sfstat[1] = CLEAN_DATA_32; | |
@@ -4331,6 +4403,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) | | |
@@ -4363,7 +4440,12 @@ 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 */ | |
@@ -4505,7 +4587,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; | |
@@ -4554,7 +4636,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++; | |
@@ -4562,7 +4644,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++; | |
@@ -4579,13 +4661,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; | |
@@ -4601,16 +4683,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++; | |
} | |
} | |
@@ -4621,7 +4769,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++; | |
@@ -4636,12 +4784,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(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; | |
@@ -4664,7 +4812,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], | |
@@ -4673,7 +4821,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); | |
@@ -4687,7 +4840,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) && | |
@@ -4697,6 +4850,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__); | |
@@ -4776,13 +4940,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; | |
@@ -4797,7 +4961,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; | |
@@ -4923,13 +5087,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)) { | |
@@ -4963,7 +5127,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", | |
@@ -5022,26 +5186,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[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[6] = SFLASH_PREPCMD(1, 6, 0, | |
+ 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; | |
@@ -5053,6 +5237,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) | | |
@@ -5085,7 +5274,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; | |
/*************************************************************/ | |
@@ -5163,7 +5357,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; | |
@@ -5210,7 +5404,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++; | |
@@ -5222,36 +5416,36 @@ 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 = 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[8]); | |
cmd->dst = MSM_NAND_MACRO1_REG; | |
cmd->len = 4; | |
cmd++; | |
@@ -5266,9 +5460,73 @@ 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[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 = 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[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 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[14]); | |
+ cmd->len = 4; | |
+ cmd++; | |
+ | |
/*********************************************************/ | |
/* Issuing write command */ | |
@@ -5276,7 +5534,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[6]); | |
+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[10]); | |
cmd->dst = MSM_NAND_SFLASHC_CMD; | |
cmd->len = 4; | |
cmd++; | |
@@ -5291,7 +5549,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++; | |
@@ -5301,7 +5559,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++; | |
@@ -5316,7 +5574,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++; | |
@@ -5326,7 +5584,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++; | |
@@ -5341,7 +5599,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++; | |
@@ -5365,7 +5623,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++; | |
@@ -5380,12 +5638,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; | |
@@ -5405,7 +5663,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], | |
@@ -5415,7 +5673,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); | |
@@ -5427,10 +5690,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) && | |
@@ -5440,6 +5703,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__); | |
@@ -5454,7 +5728,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) { | |
@@ -5885,18 +6159,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; | |
@@ -5916,7 +6190,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; | |
@@ -5949,7 +6227,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; | |
@@ -6699,6 +6977,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; | |
@@ -6711,17 +7107,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; | |
@@ -6741,6 +7138,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; | |
} | |
@@ -6764,7 +7170,7 @@ int msm_nand_scan(struct mtd_info *mtd, int maxchips) | |
uint8_t index; | |
/* Probe the Flash device for ONFI compliance */ | |
-#if defined (CONFIG_MACH_COOPER) | |
+#if defined (CONFIG_MACH_COOPER) || defined (CONFIG_MACH_EUROPA) | |
/* Read the Flash ID from the Nand Flash Device */ | |
flash_id = flash_read_id(chip); | |
for (index = 1; index < ARRAY_SIZE(supported_flash); index++) | |
@@ -7176,4 +7582,4 @@ module_init(msm_nand_init); | |
module_exit(msm_nand_exit); | |
MODULE_LICENSE("GPL"); | |
-MODULE_DESCRIPTION("msm_nand flash driver code"); | |
+MODULE_DESCRIPTION("msm_nand flash driver code"); | |
\ No newline at end of file | |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c | |
index b8043a9..97b770d 100644 | |
--- a/drivers/mtd/mtdpart.c | |
+++ b/drivers/mtd/mtdpart.c | |
@@ -485,6 +485,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master, | |
} | |
slave->mtd.ecclayout = master->ecclayout; | |
+#if 0 | |
if (master->block_isbad) { | |
uint64_t offs = 0; | |
@@ -495,6 +496,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master, | |
offs += slave->mtd.erasesize; | |
} | |
} | |
+#endif | |
out_register: | |
/* register our partition */ | |
diff --git a/kernel/panic.c b/kernel/panic.c | |
index 3c6fb7a..15ebc30 100755 | |
--- a/kernel/panic.c | |
+++ b/kernel/panic.c | |
@@ -85,12 +85,14 @@ static void panic_blink_one_second(void) | |
#include <mach/msm_iomap.h> | |
#include <asm/io.h> | |
+#ifdef CONFIG_DPRAM | |
struct smem_info { | |
unsigned int info; | |
}; | |
extern struct smem_info *smem_flag; | |
extern int dump_enable_flag; | |
+#endif | |
#include <asm/io.h> | |
#endif | |
@@ -118,11 +120,13 @@ NORET_TYPE void panic(const char * fmt, ...) | |
#endif | |
#if defined(CONFIG_MACH_EUROPA) || defined(CONFIG_MACH_CALLISTO) || defined(CONFIG_MACH_COOPER) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_BENI) || defined(CONFIG_MACH_TASS) || defined(CONFIG_MACH_TASSDT) || defined(CONFIG_MACH_LUCAS) | |
+#ifdef CONFIG_DPRAM | |
if(dump_enable_flag) | |
writel(0xCCCC, MSM_SHARED_RAM_BASE + 0x30); // dump mode | |
else { | |
smem_flag->info = 0xAEAEAEAE; | |
} | |
+#endif | |
printk("[PANIC] call msm_proc_comm_reset_modem_now func\n"); | |
msm_proc_comm_reset_modem_now(); | |
diff --git a/kernel/sys.c b/kernel/sys.c | |
index 54d55dd..8f009d8 100755 | |
--- a/kernel/sys.c | |
+++ b/kernel/sys.c | |
@@ -57,8 +57,10 @@ | |
struct smem_info { | |
unsigned int info; | |
}; | |
- | |
+ | |
+#ifdef CONFIG_DPRAM | |
extern struct smem_info *smem_flag; | |
+#endif | |
#define POWER_OFF_TIME ( 15 * HZ ) // 10 secs | |
@@ -380,7 +382,9 @@ void power_off_registertimer(struct timer_list* ptimer, unsigned long timeover ) | |
void power_off_timeout(unsigned long arg) | |
{ | |
printk("%s\n",__func__); | |
+#ifdef CONFIG_DPRAM | |
smem_flag->info = 0xAEAEAEAE; | |
+#endif | |
msm_proc_comm_reset_modem_now(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment