]> git.ipfire.org Git - people/ms/u-boot.git/blob - common/cmd_sf.c
cmd_nand: show nand scrub confirmation character
[people/ms/u-boot.git] / common / cmd_sf.c
1 /*
2 * Command for accessing SPI flash.
3 *
4 * Copyright (C) 2008 Atmel Corporation
5 * Licensed under the GPL-2 or later.
6 */
7
8 #include <common.h>
9 #include <spi_flash.h>
10
11 #include <asm/io.h>
12
13 #ifndef CONFIG_SF_DEFAULT_SPEED
14 # define CONFIG_SF_DEFAULT_SPEED 1000000
15 #endif
16 #ifndef CONFIG_SF_DEFAULT_MODE
17 # define CONFIG_SF_DEFAULT_MODE SPI_MODE_3
18 #endif
19
20 static struct spi_flash *flash;
21
22 static int do_spi_flash_probe(int argc, char *argv[])
23 {
24 unsigned int bus = 0;
25 unsigned int cs;
26 unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
27 unsigned int mode = CONFIG_SF_DEFAULT_MODE;
28 char *endp;
29 struct spi_flash *new;
30
31 if (argc < 2)
32 goto usage;
33
34 cs = simple_strtoul(argv[1], &endp, 0);
35 if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
36 goto usage;
37 if (*endp == ':') {
38 if (endp[1] == 0)
39 goto usage;
40
41 bus = cs;
42 cs = simple_strtoul(endp + 1, &endp, 0);
43 if (*endp != 0)
44 goto usage;
45 }
46
47 if (argc >= 3) {
48 speed = simple_strtoul(argv[2], &endp, 0);
49 if (*argv[2] == 0 || *endp != 0)
50 goto usage;
51 }
52 if (argc >= 4) {
53 mode = simple_strtoul(argv[3], &endp, 16);
54 if (*argv[3] == 0 || *endp != 0)
55 goto usage;
56 }
57
58 new = spi_flash_probe(bus, cs, speed, mode);
59 if (!new) {
60 printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
61 return 1;
62 }
63
64 if (flash)
65 spi_flash_free(flash);
66 flash = new;
67
68 printf("%u KiB %s at %u:%u is now current device\n",
69 flash->size >> 10, flash->name, bus, cs);
70
71 return 0;
72
73 usage:
74 puts("Usage: sf probe [bus:]cs [hz] [mode]\n");
75 return 1;
76 }
77
78 static int do_spi_flash_read_write(int argc, char *argv[])
79 {
80 unsigned long addr;
81 unsigned long offset;
82 unsigned long len;
83 void *buf;
84 char *endp;
85 int ret;
86
87 if (argc < 4)
88 goto usage;
89
90 addr = simple_strtoul(argv[1], &endp, 16);
91 if (*argv[1] == 0 || *endp != 0)
92 goto usage;
93 offset = simple_strtoul(argv[2], &endp, 16);
94 if (*argv[2] == 0 || *endp != 0)
95 goto usage;
96 len = simple_strtoul(argv[3], &endp, 16);
97 if (*argv[3] == 0 || *endp != 0)
98 goto usage;
99
100 buf = map_physmem(addr, len, MAP_WRBACK);
101 if (!buf) {
102 puts("Failed to map physical memory\n");
103 return 1;
104 }
105
106 if (strcmp(argv[0], "read") == 0)
107 ret = spi_flash_read(flash, offset, len, buf);
108 else
109 ret = spi_flash_write(flash, offset, len, buf);
110
111 unmap_physmem(buf, len);
112
113 if (ret) {
114 printf("SPI flash %s failed\n", argv[0]);
115 return 1;
116 }
117
118 return 0;
119
120 usage:
121 printf("Usage: sf %s addr offset len\n", argv[0]);
122 return 1;
123 }
124
125 static int do_spi_flash_erase(int argc, char *argv[])
126 {
127 unsigned long offset;
128 unsigned long len;
129 char *endp;
130 int ret;
131
132 if (argc < 3)
133 goto usage;
134
135 offset = simple_strtoul(argv[1], &endp, 16);
136 if (*argv[1] == 0 || *endp != 0)
137 goto usage;
138 len = simple_strtoul(argv[2], &endp, 16);
139 if (*argv[2] == 0 || *endp != 0)
140 goto usage;
141
142 ret = spi_flash_erase(flash, offset, len);
143 if (ret) {
144 printf("SPI flash %s failed\n", argv[0]);
145 return 1;
146 }
147
148 return 0;
149
150 usage:
151 puts("Usage: sf erase offset len\n");
152 return 1;
153 }
154
155 static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
156 {
157 const char *cmd;
158
159 /* need at least two arguments */
160 if (argc < 2)
161 goto usage;
162
163 cmd = argv[1];
164
165 if (strcmp(cmd, "probe") == 0)
166 return do_spi_flash_probe(argc - 1, argv + 1);
167
168 /* The remaining commands require a selected device */
169 if (!flash) {
170 puts("No SPI flash selected. Please run `sf probe'\n");
171 return 1;
172 }
173
174 if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0)
175 return do_spi_flash_read_write(argc - 1, argv + 1);
176 if (strcmp(cmd, "erase") == 0)
177 return do_spi_flash_erase(argc - 1, argv + 1);
178
179 usage:
180 cmd_usage(cmdtp);
181 return 1;
182 }
183
184 U_BOOT_CMD(
185 sf, 5, 1, do_spi_flash,
186 "SPI flash sub-system",
187 "probe [bus:]cs [hz] [mode] - init flash device on given SPI bus\n"
188 " and chip select\n"
189 "sf read addr offset len - read `len' bytes starting at\n"
190 " `offset' to memory at `addr'\n"
191 "sf write addr offset len - write `len' bytes from memory\n"
192 " at `addr' to flash at `offset'\n"
193 "sf erase offset len - erase `len' bytes from `offset'"
194 );