aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger2009-07-23 15:37:03 -0500
committerWolfgang Denk2009-09-04 14:31:30 -0500
commit65f6f07b72a71b83d775c4d20d7ebcd6b2d2086d (patch)
tree2466e9708dff31bd5f9f40bec8d12b00f8dece53 /examples
parentcb95c7a935ab9b52dac5d08e5ba4007c5a480f97 (diff)
downloadu-boot-65f6f07b72a71b83d775c4d20d7ebcd6b2d2086d.tar.gz
u-boot-65f6f07b72a71b83d775c4d20d7ebcd6b2d2086d.tar.xz
u-boot-65f6f07b72a71b83d775c4d20d7ebcd6b2d2086d.zip
atmel_df_pow2: standalone to convert dataflashes to pow2
Atmel DataFlashes by default operate with pages that are slightly bigger than normal binary sizes (i.e. many are 1056 byte pages rather than 1024 bytes). However, they also have a "power of 2" mode where the pages show up with the normal binary size. The latter mode is required in order to boot with a Blackfin processor, so many people wish to convert their DataFlashes on their development systems to this mode. This standalone application does just that. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'examples')
-rw-r--r--examples/standalone/.gitignore1
-rw-r--r--examples/standalone/Makefile4
-rw-r--r--examples/standalone/atmel_df_pow2.c209
3 files changed, 214 insertions, 0 deletions
diff --git a/examples/standalone/.gitignore b/examples/standalone/.gitignore
index 0d1864cc28..7b783fc213 100644
--- a/examples/standalone/.gitignore
+++ b/examples/standalone/.gitignore
@@ -1,4 +1,5 @@
1/82559_eeprom 1/82559_eeprom
2/atmel_df_pow2
2/hello_world 3/hello_world
3/interrupt 4/interrupt
4/mem_to_mem_idma2intr 5/mem_to_mem_idma2intr
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile
index d2e811a8b5..9a9b6c38ef 100644
--- a/examples/standalone/Makefile
+++ b/examples/standalone/Makefile
@@ -86,6 +86,10 @@ ELF = hello_world
86SREC = hello_world.srec 86SREC = hello_world.srec
87BIN = hello_world.bin 87BIN = hello_world.bin
88 88
89ELF += atmel_df_pow2
90SREC += atmel_df_pow2.srec
91BIN += atmel_df_pow2.bin
92
89ifeq ($(CPU),mpc8xx) 93ifeq ($(CPU),mpc8xx)
90ELF += test_burst 94ELF += test_burst
91SREC += test_burst.srec 95SREC += test_burst.srec
diff --git a/examples/standalone/atmel_df_pow2.c b/examples/standalone/atmel_df_pow2.c
new file mode 100644
index 0000000000..db0cd693a9
--- /dev/null
+++ b/examples/standalone/atmel_df_pow2.c
@@ -0,0 +1,209 @@
1/*
2 * atmel_df_pow2.c - convert Atmel Dataflashes to Power of 2 mode
3 *
4 * Copyright 2009 Analog Devices Inc.
5 *
6 * Licensed under the 2-clause BSD.
7 */
8
9#include <common.h>
10#include <exports.h>
11
12#define CMD_ID 0x9f
13#define CMD_STAT 0xd7
14#define CMD_CFG 0x3d
15
16static int flash_cmd(struct spi_slave *slave, uchar cmd, uchar *buf, int len)
17{
18 buf[0] = cmd;
19 return spi_xfer(slave, 8 * len, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END);
20}
21
22static int flash_status(struct spi_slave *slave)
23{
24 uchar buf[2];
25 if (flash_cmd(slave, CMD_STAT, buf, sizeof(buf)))
26 return -1;
27 return buf[1];
28}
29
30static int flash_set_pow2(struct spi_slave *slave)
31{
32 int ret;
33 uchar buf[4];
34
35 buf[1] = 0x2a;
36 buf[2] = 0x80;
37 buf[3] = 0xa6;
38
39 ret = flash_cmd(slave, CMD_CFG, buf, sizeof(buf));
40 if (ret)
41 return ret;
42
43 /* wait Tp, or 6 msec */
44 udelay(6000);
45
46 ret = flash_status(slave);
47 if (ret == -1)
48 return 1;
49
50 return ret & 0x1 ? 0 : 1;
51}
52
53static int flash_check(struct spi_slave *slave)
54{
55 int ret;
56 uchar buf[4];
57
58 ret = flash_cmd(slave, CMD_ID, buf, sizeof(buf));
59 if (ret)
60 return ret;
61
62 if (buf[1] != 0x1F) {
63 printf("atmel flash not found (id[0] = %#x)\n", buf[1]);
64 return 1;
65 }
66
67 if ((buf[2] >> 5) != 0x1) {
68 printf("AT45 flash not found (id[0] = %#x)\n", buf[2]);
69 return 2;
70 }
71
72 return 0;
73}
74
75static char *getline(void)
76{
77 static char buffer[100];
78 char c;
79 size_t i;
80
81 i = 0;
82 while (1) {
83 buffer[i] = '\0';
84
85 c = getc();
86
87 switch (c) {
88 case '\r': /* Enter/Return key */
89 case '\n':
90 puts("\n");
91 return buffer;
92
93 case 0x03: /* ^C - break */
94 return NULL;
95
96 case 0x5F:
97 case 0x08: /* ^H - backspace */
98 case 0x7F: /* DEL - backspace */
99 if (i) {
100 puts("\b \b");
101 i--;
102 }
103 break;
104
105 default:
106 /* Ignore control characters */
107 if (c < 0x20)
108 break;
109 /* Queue up all other characters */
110 buffer[i++] = c;
111 printf("%c", c);
112 break;
113 }
114 }
115}
116
117int atmel_df_pow2(int argc, char *argv[])
118{
119 /* Print the ABI version */
120 app_startup(argv);
121 if (XF_VERSION != get_version()) {
122 printf("Expects ABI version %d\n", XF_VERSION);
123 printf("Actual U-Boot ABI version %lu\n", get_version());
124 printf("Can't run\n\n");
125 return 1;
126 }
127
128 spi_init();
129
130 while (1) {
131 struct spi_slave *slave;
132 char *line, *p;
133 int bus, cs, status;
134
135 puts("\nenter the [BUS:]CS of the SPI flash: ");
136 line = getline();
137
138 /* CTRL+C */
139 if (!line)
140 return 0;
141 if (line[0] == '\0')
142 continue;
143
144 bus = cs = simple_strtoul(line, &p, 10);
145 if (*p) {
146 if (*p == ':') {
147 ++p;
148 cs = simple_strtoul(p, &p, 10);
149 }
150 if (*p) {
151 puts("invalid format, please try again\n");
152 continue;
153 }
154 } else
155 bus = 0;
156
157 printf("\ngoing to work with dataflash at %i:%i\n", bus, cs);
158
159 /* use a low speed -- it'll work with all devices, and
160 * speed here doesn't really matter.
161 */
162 slave = spi_setup_slave(bus, cs, 1000, SPI_MODE_3);
163 if (!slave) {
164 puts("unable to setup slave\n");
165 continue;
166 }
167
168 if (spi_claim_bus(slave)) {
169 spi_free_slave(slave);
170 continue;
171 }
172
173 if (flash_check(slave)) {
174 puts("no flash found\n");
175 goto done;
176 }
177
178 status = flash_status(slave);
179 if (status == -1) {
180 puts("unable to read status register\n");
181 goto done;
182 }
183 if (status & 0x1) {
184 puts("flash is already in power-of-2 mode!\n");
185 goto done;
186 }
187
188 puts("are you sure you wish to set power-of-2 mode?\n");
189 puts("this operation is permanent and irreversible\n");
190 printf("enter YES to continue: ");
191 line = getline();
192 if (!line || strcmp(line, "YES"))
193 goto done;
194
195 if (flash_set_pow2(slave)) {
196 puts("setting pow2 mode failed\n");
197 goto done;
198 }
199
200 puts(
201 "Configuration should be updated now. You will have to\n"
202 "power cycle the part in order to finish the conversion.\n"
203 );
204
205 done:
206 spi_release_bus(slave);
207 spi_free_slave(slave);
208 }
209}