aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/patches-4.3/0040-nand-add-mtk-nand-hack-hook.patch
blob: 51fd8ee6a49ef054b076bf35f1cfb515a69ed4c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
From 61e17c2f864698033f4661e1fc7ba63d4d982491 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 7 Dec 2015 17:21:55 +0100
Subject: [PATCH 40/53] nand: add mtk-nand hack/hook

Signed-off-by: John Crispin <blogic@openwrt.org>
---
 drivers/mtd/nand/mtk_nand.c         |   34 ++++++++++++++++++++++++++++++----
 drivers/mtd/nand/nand_base.c        |    9 ++++++++-
 drivers/mtd/nand/nand_device_list.h |    2 ++
 include/linux/mtd/nand.h            |    4 ++++
 4 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c
index 00e150c..808e9c3 100644
--- a/drivers/mtd/nand/mtk_nand.c
+++ b/drivers/mtd/nand/mtk_nand.c
@@ -110,6 +110,10 @@ int part_num = NUM_PARTITIONS;
 int manu_id;
 int dev_id;
 
+/* this constant was taken from linux/nand/nand.h v 3.14
+ * in later versions it seems it was removed in order to save a bit of space
+ */
+#define NAND_MAX_OOBSIZE 774
 static u8 local_oob_buf[NAND_MAX_OOBSIZE];
 
 static u8 nand_badblock_offset = 0;
@@ -348,7 +352,7 @@ mtk_nand_check_bch_error(struct mtd_info *mtd, u8 * pDataBuf, u32 u4SecIndex, u3
 		if (0xF == u4ErrNum) {
 			mtd->ecc_stats.failed++;
 			bRet = false;
-			//printk(KERN_ERR"UnCorrectable at PageAddr=%d\n", u4PageAddr);
+			printk(KERN_ERR"mtk_nand: UnCorrectable at PageAddr=%d\n", u4PageAddr);
 		} else {
 			for (i = 0; i < ((u4ErrNum + 1) >> 1); ++i) {
 				au4ErrBitLoc[i] = DRV_Reg32(ECC_DECEL0_REG32 + i);
@@ -1422,7 +1426,7 @@ mtk_nand_erase_hw(struct mtd_info *mtd, int page)
 {
 	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
 
-	chip->erase_cmd(mtd, page);
+	chip->erase(mtd, page);
 
 	return chip->waitfunc(mtd, chip);
 }
@@ -2094,8 +2098,8 @@ mtk_nand_probe(struct platform_device *pdev)
 	nand_chip->write_page = mtk_nand_write_page;
 	nand_chip->ecc.write_oob = mtk_nand_write_oob;
 	nand_chip->block_markbad = mtk_nand_block_markbad;   // need to add nand_get_device()/nand_release_device().
-	//	nand_chip->erase = mtk_nand_erase;	
-	//    nand_chip->read_page = mtk_nand_read_page;
+	nand_chip->erase_mtk = mtk_nand_erase;	
+	nand_chip->read_page = mtk_nand_read_page;
 	nand_chip->ecc.read_oob = mtk_nand_read_oob;
 	nand_chip->block_bad = mtk_nand_block_bad;
 
@@ -2175,6 +2179,21 @@ mtk_nand_probe(struct platform_device *pdev)
 	nand_chip->pagemask = (nand_chip->chipsize >> nand_chip->page_shift) - 1;
 	nand_chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
 	nand_chip->chip_shift = ffs(nand_chip->chipsize) - 1;//0x1C;//ffs(nand_chip->chipsize) - 1;
+
+	/* allocate buffers or call select_chip here or a bit earlier*/
+	{
+		struct nand_buffers *nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize + mtd->oobsize * 3, GFP_KERNEL);
+		if (!nbuf) {
+			return -ENOMEM;
+		}
+		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
+		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
+		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+
+		nand_chip->buffers = nbuf;
+		nand_chip->options |= NAND_OWN_BUFFERS;
+	}
+
 	nand_chip->oob_poi = nand_chip->buffers->databuf + mtd->writesize;
 	nand_chip->badblockpos = 0;
 
@@ -2251,6 +2270,9 @@ out:
 	MSG(INIT, "[NFI] mtk_nand_probe fail, err = %d!\n", err);
 	nand_release(mtd);
 	platform_set_drvdata(pdev, NULL);
+	if ( NULL != nand_chip->buffers) {
+		kfree(nand_chip->buffers);
+	}
 	kfree(host);
 	nand_disable_clock();
 	return err;
@@ -2261,8 +2283,12 @@ mtk_nand_remove(struct platform_device *pdev)
 {
 	struct mtk_nand_host *host = platform_get_drvdata(pdev);
 	struct mtd_info *mtd = &host->mtd;
+	struct nand_chip *nand_chip = &host->nand_chip;
 
 	nand_release(mtd);
+	if ( NULL != nand_chip->buffers) {
+		kfree(nand_chip->buffers);
+	}
 	kfree(host);
 	nand_disable_clock();
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 04dbc69..c5ed6fc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1592,6 +1592,9 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 						 __func__, buf);
 
 read_retry:
+#ifdef CONFIG_MTK_MTD_NAND
+			ret = chip->read_page(mtd, chip, bufpoi, page);
+#else
 			chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
 
 			/*
@@ -1610,6 +1613,7 @@ read_retry:
 			else
 				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 							  oob_required, page);
+#endif /* CONFIG_MTK_MTD_NAND */
 			if (ret < 0) {
 				if (use_bufpoi)
 					/* Invalidate page cache */
@@ -2786,8 +2790,11 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 		if (page <= chip->pagebuf && chip->pagebuf <
 		    (page + pages_per_block))
 			chip->pagebuf = -1;
-
+#ifdef CONFIG_MTK_MTD_NAND
+		status = chip->erase_mtk(mtd, page & chip->pagemask);
+#else
 		status = chip->erase(mtd, page & chip->pagemask);
+#endif /* CONFIG_MTK_MTD_NAND */
 
 		/*
 		 * See if operation failed and additional status checks are
diff --git a/drivers/mtd/nand/nand_device_list.h b/drivers/mtd/nand/nand_device_list.h
index 4c36b3a..267fd0c 100644
--- a/drivers/mtd/nand/nand_device_list.h
+++ b/drivers/mtd/nand/nand_device_list.h
@@ -43,6 +43,8 @@ static const flashdev_info gen_FlashTable[]={
 	{0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0},
     {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0},
     {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0},
+	{0xC8DA, 0x909544, 5, 8, 256, 128, 2048, 64, 0x30C77fff, "F59L2G81A", 0},
+	{0xC8DC, 0x909554, 5, 8, 512, 128, 2048, 64, 0x30C77fff, "F59L4G81A", 0},
 	{0xECD3, 0x519558, 5, 8, 1024, 128, 2048, 64, 0x44333, "K9K8G8000", 0},
     {0xC2F1, 0x801DC2, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "MX30LF1G08AA", 0},
     {0x98D3, 0x902676, 5, 8, 1024, 256, 4096, 224, 0x00C25332, "TC58NVG3S0F", 0},
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 272f429..b633b84 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -671,6 +671,10 @@ struct nand_chip {
 	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offset, int data_len, const uint8_t *buf,
 			int oob_required, int page, int cached, int raw);
+#ifdef CONFIG_MTK_MTD_NAND
+	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, u8 *buf, int page);
+	int (*erase_mtk)(struct mtd_info *mtd, int page);
+#endif /* CONFIG_MTK_MTD_NAND */
 	int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
 			int feature_addr, uint8_t *subfeature_para);
 	int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
-- 
1.7.10.4