blob: 099978149696968452e2851530687f6b358d2c4f [file] [log] [blame]
Reinhard Meyer52cb0a72010-10-05 16:56:40 +02001/*
2 * (C) Copyright 2010
3 * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * Note: RAMTRON SPI FRAMs are ferroelectric, nonvolatile RAMs
26 * with an interface identical to SPI flash devices.
27 * However since they behave like RAM there are no delays or
28 * busy polls required. They can sustain read or write at the
29 * allowed SPI bus speed, which can be 40 MHz for some devices.
30 *
31 * Unfortunately some RAMTRON devices do not have a means of
32 * identifying them. They will leave the SO line undriven when
33 * the READ-ID command is issued. It is therefore mandatory
34 * that the MISO line has a proper pull-up, so that READ-ID
35 * will return a row of 0xff. This 0xff pseudo-id will cause
36 * probes by all vendor specific functions that are designed
37 * to handle it. If the MISO line is not pulled up, READ-ID
38 * could return any random noise, even mimicking another
39 * device.
40 *
41 * We use CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
42 * to define which device will be assumed after a simple status
43 * register verify. This method is prone to false positive
44 * detection and should therefore be the last to be tried.
45 * Enter it in the last position in the table in spi_flash.c!
46 *
47 * The define CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC both activates
48 * compilation of the special handler and defines the device
49 * to assume.
50 */
51
52#include <common.h>
53#include <malloc.h>
54#include <spi_flash.h>
55#include "spi_flash_internal.h"
56
Reinhard Meyer52cb0a72010-10-05 16:56:40 +020057/*
58 * Properties of supported FRAMs
59 * Note: speed is currently not used because we have no method to deliver that
60 * value to the upper layers
61 */
62struct ramtron_spi_fram_params {
63 u32 size; /* size in bytes */
64 u8 addr_len; /* number of address bytes */
65 u8 merge_cmd; /* some address bits are in the command byte */
66 u8 id1; /* device ID 1 (family, density) */
67 u8 id2; /* device ID 2 (sub, rev, rsvd) */
68 u32 speed; /* max. SPI clock in Hz */
69 const char *name; /* name for display and/or matching */
70};
71
72struct ramtron_spi_fram {
73 struct spi_flash flash;
74 const struct ramtron_spi_fram_params *params;
75};
76
77static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
78 *flash)
79{
80 return container_of(flash, struct ramtron_spi_fram, flash);
81}
82
83/*
84 * table describing supported FRAM chips:
85 * chips without RDID command must have the values 0xff for id1 and id2
86 */
87static const struct ramtron_spi_fram_params ramtron_spi_fram_table[] = {
88 {
89 .size = 32*1024,
90 .addr_len = 2,
91 .merge_cmd = 0,
92 .id1 = 0x22,
93 .id2 = 0x00,
94 .speed = 40000000,
95 .name = "FM25V02",
96 },
97 {
98 .size = 32*1024,
99 .addr_len = 2,
100 .merge_cmd = 0,
101 .id1 = 0x22,
102 .id2 = 0x01,
103 .speed = 40000000,
104 .name = "FM25VN02",
105 },
106 {
107 .size = 64*1024,
108 .addr_len = 2,
109 .merge_cmd = 0,
110 .id1 = 0x23,
111 .id2 = 0x00,
112 .speed = 40000000,
113 .name = "FM25V05",
114 },
115 {
116 .size = 64*1024,
117 .addr_len = 2,
118 .merge_cmd = 0,
119 .id1 = 0x23,
120 .id2 = 0x01,
121 .speed = 40000000,
122 .name = "FM25VN05",
123 },
124 {
125 .size = 128*1024,
126 .addr_len = 3,
127 .merge_cmd = 0,
128 .id1 = 0x24,
129 .id2 = 0x00,
130 .speed = 40000000,
131 .name = "FM25V10",
132 },
133 {
134 .size = 128*1024,
135 .addr_len = 3,
136 .merge_cmd = 0,
137 .id1 = 0x24,
138 .id2 = 0x01,
139 .speed = 40000000,
140 .name = "FM25VN10",
141 },
142#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
143 {
144 .size = 256*1024,
145 .addr_len = 3,
146 .merge_cmd = 0,
147 .id1 = 0xff,
148 .id2 = 0xff,
149 .speed = 40000000,
150 .name = "FM25H20",
151 },
152#endif
153};
154
155static int ramtron_common(struct spi_flash *flash,
156 u32 offset, size_t len, void *buf, u8 command)
157{
158 struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
159 u8 cmd[4];
160 int cmd_len;
161 int ret;
162
163 if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
164 cmd[0] = command;
165 cmd[1] = offset >> 16;
166 cmd[2] = offset >> 8;
167 cmd[3] = offset;
168 cmd_len = 4;
169 } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
170 cmd[0] = command;
171 cmd[1] = offset >> 8;
172 cmd[2] = offset;
173 cmd_len = 3;
174 } else {
175 printf("SF: unsupported addr_len or merge_cmd\n");
176 return -1;
177 }
178
179 /* claim the bus */
180 ret = spi_claim_bus(flash->spi);
181 if (ret) {
182 debug("SF: Unable to claim SPI bus\n");
183 return ret;
184 }
185
Mike Frysinger1302bec2012-01-28 16:26:03 -0800186 if (command == CMD_PAGE_PROGRAM) {
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200187 /* send WREN */
Mike Frysinger8ec7f4c2011-04-23 23:05:55 +0000188 ret = spi_flash_cmd_write_enable(flash);
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200189 if (ret < 0) {
190 debug("SF: Enabling Write failed\n");
191 goto releasebus;
192 }
193 }
194
195 /* do the transaction */
Mike Frysinger1302bec2012-01-28 16:26:03 -0800196 if (command == CMD_PAGE_PROGRAM)
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200197 ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, buf, len);
198 else
199 ret = spi_flash_cmd_read(flash->spi, cmd, cmd_len, buf, len);
200 if (ret < 0)
201 debug("SF: Transaction failed\n");
202
203releasebus:
204 /* release the bus */
205 spi_release_bus(flash->spi);
206 return ret;
207}
208
209static int ramtron_read(struct spi_flash *flash,
210 u32 offset, size_t len, void *buf)
211{
212 return ramtron_common(flash, offset, len, buf,
Mike Frysinger1302bec2012-01-28 16:26:03 -0800213 CMD_READ_ARRAY_SLOW);
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200214}
215
216static int ramtron_write(struct spi_flash *flash,
217 u32 offset, size_t len, const void *buf)
218{
219 return ramtron_common(flash, offset, len, (void *)buf,
Mike Frysinger1302bec2012-01-28 16:26:03 -0800220 CMD_PAGE_PROGRAM);
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200221}
222
Mike Frysingeraea4e172011-04-12 01:51:29 -0400223static int ramtron_erase(struct spi_flash *flash, u32 offset, size_t len)
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200224{
225 debug("SF: Erase of RAMTRON FRAMs is pointless\n");
226 return -1;
227}
228
229/*
230 * nore: we are called here with idcode pointing to the first non-0x7f byte
231 * already!
232 */
233struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
234{
235 const struct ramtron_spi_fram_params *params;
236 struct ramtron_spi_fram *sn;
237 unsigned int i;
238#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
239 int ret;
240 u8 sr;
241#endif
242
243 /* NOTE: the bus has been claimed before this function is called! */
244 switch (idcode[0]) {
245 case 0xc2:
246 /* JEDEC conformant RAMTRON id */
247 for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
248 params = &ramtron_spi_fram_table[i];
249 if (idcode[1] == params->id1 && idcode[2] == params->id2)
250 goto found;
251 }
252 break;
253#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
254 case 0xff:
255 /*
256 * probably open MISO line, pulled up.
257 * We COULD have a non JEDEC conformant FRAM here,
258 * read the status register to verify
259 */
Mike Frysinger1302bec2012-01-28 16:26:03 -0800260 ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1);
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200261 if (ret)
262 return NULL;
263
264 /* Bits 5,4,0 are fixed 0 for all devices */
265 if ((sr & 0x31) != 0x00)
266 return NULL;
267 /* now find the device */
268 for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
269 params = &ramtron_spi_fram_table[i];
270 if (!strcmp(params->name, CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC))
271 goto found;
272 }
273 debug("SF: Unsupported non-JEDEC RAMTRON device "
274 CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC "\n");
275 break;
276#endif
277 default:
278 break;
279 }
280
281 /* arriving here means no method has found a device we can handle */
282 debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
283 idcode[0], idcode[1], idcode[2]);
284 return NULL;
285
286found:
287 sn = malloc(sizeof(*sn));
288 if (!sn) {
289 debug("SF: Failed to allocate memory\n");
290 return NULL;
291 }
292
293 sn->params = params;
294 sn->flash.spi = spi;
295 sn->flash.name = params->name;
296
297 sn->flash.write = ramtron_write;
298 sn->flash.read = ramtron_read;
299 sn->flash.erase = ramtron_erase;
300 sn->flash.size = params->size;
301
Reinhard Meyer52cb0a72010-10-05 16:56:40 +0200302 return &sn->flash;
303}