cmd_sf.c 3.9 KB

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