cmd_sf.c 3.9 KB

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