Loading...
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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | /* * Command for accessing SPI flash. * * Copyright (C) 2008 Atmel Corporation */ #include <common.h> #include <spi_flash.h> #include <asm/io.h> #ifndef CONFIG_SF_DEFAULT_SPEED # define CONFIG_SF_DEFAULT_SPEED 1000000 #endif #ifndef CONFIG_SF_DEFAULT_MODE # define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 #endif static struct spi_flash *flash; static int do_spi_flash_probe(int argc, char *argv[]) { unsigned int bus = 0; unsigned int cs; unsigned int speed = CONFIG_SF_DEFAULT_SPEED; unsigned int mode = CONFIG_SF_DEFAULT_MODE; char *endp; struct spi_flash *new; if (argc < 2) goto usage; cs = simple_strtoul(argv[1], &endp, 0); if (*argv[1] == 0 || (*endp != 0 && *endp != ':')) goto usage; if (*endp == ':') { if (endp[1] == 0) goto usage; bus = cs; cs = simple_strtoul(endp + 1, &endp, 0); if (*endp != 0) goto usage; } if (argc >= 3) { speed = simple_strtoul(argv[2], &endp, 0); if (*argv[2] == 0 || *endp != 0) goto usage; } if (argc >= 4) { mode = simple_strtoul(argv[3], &endp, 0); if (*argv[3] == 0 || *endp != 0) goto usage; } new = spi_flash_probe(bus, cs, speed, mode); if (!new) { printf("Failed to initialize SPI flash at %u:%u\n", bus, cs); return 1; } if (flash) spi_flash_free(flash); flash = new; printf("%u KiB %s at %u:%u is now current device\n", flash->size >> 10, flash->name, bus, cs); return 0; usage: puts("Usage: sf probe [bus:]cs [hz] [mode]\n"); return 1; } static int do_spi_flash_read_write(int argc, char *argv[]) { unsigned long addr; unsigned long offset; unsigned long len; void *buf; char *endp; int ret; if (argc < 4) goto usage; addr = simple_strtoul(argv[1], &endp, 16); if (*argv[1] == 0 || *endp != 0) goto usage; offset = simple_strtoul(argv[2], &endp, 16); if (*argv[2] == 0 || *endp != 0) goto usage; len = simple_strtoul(argv[3], &endp, 16); if (*argv[3] == 0 || *endp != 0) goto usage; buf = map_physmem(addr, len, MAP_WRBACK); if (!buf) { puts("Failed to map physical memory\n"); return 1; } if (strcmp(argv[0], "read") == 0) ret = spi_flash_read(flash, offset, len, buf); else ret = spi_flash_write(flash, offset, len, buf); unmap_physmem(buf, len); if (ret) { printf("SPI flash %s failed\n", argv[0]); return 1; } return 0; usage: printf("Usage: sf %s addr offset len\n", argv[0]); return 1; } static int do_spi_flash_erase(int argc, char *argv[]) { unsigned long offset; unsigned long len; char *endp; int ret; if (argc < 3) goto usage; offset = simple_strtoul(argv[1], &endp, 16); if (*argv[1] == 0 || *endp != 0) goto usage; len = simple_strtoul(argv[2], &endp, 16); if (*argv[2] == 0 || *endp != 0) goto usage; ret = spi_flash_erase(flash, offset, len); if (ret) { printf("SPI flash %s failed\n", argv[0]); return 1; } return 0; usage: puts("Usage: sf erase offset len\n"); return 1; } static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { const char *cmd; /* need at least two arguments */ if (argc < 2) goto usage; cmd = argv[1]; if (strcmp(cmd, "probe") == 0) return do_spi_flash_probe(argc - 1, argv + 1); /* The remaining commands require a selected device */ if (!flash) { puts("No SPI flash selected. Please run `sf probe'\n"); return 1; } if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0) return do_spi_flash_read_write(argc - 1, argv + 1); if (strcmp(cmd, "erase") == 0) return do_spi_flash_erase(argc - 1, argv + 1); usage: printf("Usage:\n%s\n", cmdtp->usage); return 1; } U_BOOT_CMD( sf, 5, 1, do_spi_flash, "sf - SPI flash sub-system\n", "probe [bus:]cs [hz] [mode] - init flash device on given SPI bus\n" " and chip select\n" "sf read addr offset len - read `len' bytes starting at\n" " `offset' to memory at `addr'\n" "sf write addr offset len - write `len' bytes from memory\n" " at `addr' to flash at `offset'\n" "sf erase offset len - erase `len' bytes from `offset'\n"); |