summaryrefslogtreecommitdiff
path: root/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch
blob: f386eee4bfe244ca4ba821e8c37c186f96ee128e (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
169
From 3af3addee645bd81537be1ddee49969f8dfc64ee Mon Sep 17 00:00:00 2001
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Date: Sun, 13 Oct 2013 15:24:56 +0200
Subject: sf: add support for 4-byte addressing

Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 732ddf8..c5e8eb1 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -38,12 +38,14 @@
 #define CMD_READ_ID			0x9f
 
 /* Bank addr access commands */
-#ifdef CONFIG_SPI_FLASH_BAR
-# define CMD_BANKADDR_BRWR		0x17
-# define CMD_BANKADDR_BRRD		0x16
-# define CMD_EXTNADDR_WREAR		0xC5
-# define CMD_EXTNADDR_RDEAR		0xC8
-#endif
+#define CMD_BANKADDR_BRWR		0x17
+#define CMD_BANKADDR_BRRD		0x16
+#define CMD_EXTNADDR_WREAR		0xC5
+#define CMD_EXTNADDR_RDEAR		0xC8
+
+/* Macronix style 4-byte addressing */
+#define CMD_EN4B			0xb7
+#define CMD_EX4B			0xe9
 
 /* Common status */
 #define STATUS_WIP			0x01
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index 207adf5..1d072f8 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -21,6 +21,7 @@ static void spi_flash_addr(const struct spi_flash *flash, u32 addr, u8 *cmd)
 	cmd[1] = addr >> (flash->addr_width * 8 - 8);
 	cmd[2] = addr >> (flash->addr_width * 8 - 16);
 	cmd[3] = addr >> (flash->addr_width * 8 - 24);
+	cmd[4] = addr >> (flash->addr_width * 8 - 32);
 }
 
 static int spi_flash_cmdsz(const struct spi_flash *flash)
@@ -163,7 +164,7 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 {
 	u32 erase_size;
-	u8 cmd[4], cmd_len;
+	u8 cmd[5], cmd_len;
 	int ret = -1;
 
 	erase_size = flash->erase_size;
@@ -188,8 +189,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 		spi_flash_addr(flash, offset, cmd);
 		cmd_len = spi_flash_cmdsz(flash);
 
-		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-		      cmd[2], cmd[3], offset);
+		debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+		      cmd[2], cmd[3], cmd[4], offset);
 
 		ret = spi_flash_write_common(flash, cmd, cmd_len, NULL, 0);
 		if (ret < 0) {
@@ -212,7 +213,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 {
 	unsigned long byte_addr, page_size;
 	size_t chunk_len, actual;
-	u8 cmd[4], cmd_len;
+	u8 cmd[5], cmd_len;
 	int ret = -1;
 
 	ret = spi_claim_bus(flash->spi);
@@ -239,8 +240,8 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 		spi_flash_addr(flash, offset, cmd);
 		cmd_len = spi_flash_cmdsz(flash);
 
-		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
-		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n",
+		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len);
 
 		ret = spi_flash_write_common(flash, cmd, cmd_len,
 					buf + actual, chunk_len);
@@ -276,9 +277,13 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		size_t len, void *data)
 {
-	u8 cmd[5], cmd_len, bank_sel = 0;
-	u32 remain_len, read_len;
+	u8 cmd[6], cmd_len;
+	u32 read_len;
 	int ret = -1;
+#ifdef CONFIG_SPI_FLASH_BAR
+	u8 bank_sel = 0;
+	u32 remain_len;
+#endif
 
 	ret = spi_claim_bus(flash->spi);
 	if (ret) {
@@ -305,12 +310,15 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 			debug("SF: fail to set bank%d\n", bank_sel);
 			goto done;
 		}
-#endif
+
 		remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset;
 		if (len < remain_len)
 			read_len = len;
 		else
 			read_len = remain_len;
+#else
+		read_len = len;
+#endif
 
 		spi_flash_addr(flash, offset, cmd);
 		cmd_len = spi_flash_cmdsz(flash);
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 84289db..ac44287 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -153,6 +153,25 @@ static const struct spi_flash_params spi_flash_params_table[] = {
 	 */
 };
 
+int spi_flash_4byte_set(struct spi_flash *flash, u8 idcode0, int enable)
+{
+	u8 cmd, bankaddr;
+
+	switch (idcode0) {
+	case 0xc2:
+	case 0xef:
+	case 0x1c:
+		/* Macronix style */
+		cmd = enable ? CMD_EN4B : CMD_EX4B;
+		return spi_flash_cmd(flash->spi, cmd, NULL, 0);
+	default:
+		/* Spansion style */
+		cmd = CMD_BANKADDR_BRWR;
+		bankaddr = enable << 7;
+		return spi_flash_cmd_write(flash->spi, &cmd, 1, &bankaddr, 1);
+	}
+}
+
 static int spi_flash_validate_params(struct spi_flash *flash,
 		u8 *idcode)
 {
@@ -218,8 +237,18 @@ static int spi_flash_validate_params(struct spi_flash *flash,
 		flash->poll_cmd = CMD_FLAG_STATUS;
 #endif
 
+#ifndef CONFIG_SPI_FLASH_BAR
+	/* enable 4-byte addressing if the device exceeds 16MiB */
+	if (flash->size > SPI_FLASH_16MB_BOUN) {
+		flash->addr_width = 4;
+		spi_flash_4byte_set(flash, idcode[0], 1);
+	} else {
+		flash->addr_width = 3;
+	}
+#else
 	/* Configure default 3-byte addressing */
 	flash->addr_width = 3;
+#endif
 
 	/* Configure the BAR - discover bank cmds and read current bank */
 #ifdef CONFIG_SPI_FLASH_BAR
-- 
1.8.3.2