cmd_fuse.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * (C) Copyright 2009-2013 ADVANSEE
  3. * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
  4. *
  5. * Based on the mpc512x iim code:
  6. * Copyright 2008 Silicon Turnkey Express, Inc.
  7. * Martha Marx <mmarx@silicontkx.com>
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. #include <common.h>
  12. #include <command.h>
  13. #include <fuse.h>
  14. #include <asm/errno.h>
  15. static int strtou32(const char *str, unsigned int base, u32 *result)
  16. {
  17. char *ep;
  18. *result = simple_strtoul(str, &ep, base);
  19. if (ep == str || *ep != '\0')
  20. return -EINVAL;
  21. return 0;
  22. }
  23. static int confirm_prog(void)
  24. {
  25. puts("Warning: Programming fuses is an irreversible operation!\n"
  26. " This may brick your system.\n"
  27. " Use this command only if you are sure of "
  28. "what you are doing!\n"
  29. "\nReally perform this fuse programming? <y/N>\n");
  30. if (getc() == 'y') {
  31. int c;
  32. putc('y');
  33. c = getc();
  34. putc('\n');
  35. if (c == '\r')
  36. return 1;
  37. }
  38. puts("Fuse programming aborted\n");
  39. return 0;
  40. }
  41. static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  42. {
  43. const char *op = argc >= 2 ? argv[1] : NULL;
  44. int confirmed = argc >= 3 && !strcmp(argv[2], "-y");
  45. u32 bank, word, cnt, val;
  46. int ret, i;
  47. argc -= 2 + confirmed;
  48. argv += 2 + confirmed;
  49. if (argc < 2 || strtou32(argv[0], 0, &bank) ||
  50. strtou32(argv[1], 0, &word))
  51. return CMD_RET_USAGE;
  52. if (!strcmp(op, "read")) {
  53. if (argc == 2)
  54. cnt = 1;
  55. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  56. return CMD_RET_USAGE;
  57. printf("Reading bank %u:\n", bank);
  58. for (i = 0; i < cnt; i++, word++) {
  59. if (!(i % 4))
  60. printf("\nWord 0x%.8x:", word);
  61. ret = fuse_read(bank, word, &val);
  62. if (ret)
  63. goto err;
  64. printf(" %.8x", val);
  65. }
  66. putc('\n');
  67. } else if (!strcmp(op, "sense")) {
  68. if (argc == 2)
  69. cnt = 1;
  70. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  71. return CMD_RET_USAGE;
  72. printf("Sensing bank %u:\n", bank);
  73. for (i = 0; i < cnt; i++, word++) {
  74. if (!(i % 4))
  75. printf("\nWord 0x%.8x:", word);
  76. ret = fuse_sense(bank, word, &val);
  77. if (ret)
  78. goto err;
  79. printf(" %.8x", val);
  80. }
  81. putc('\n');
  82. } else if (!strcmp(op, "prog")) {
  83. if (argc < 3)
  84. return CMD_RET_USAGE;
  85. for (i = 2; i < argc; i++, word++) {
  86. if (strtou32(argv[i], 16, &val))
  87. return CMD_RET_USAGE;
  88. printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
  89. bank, word, val);
  90. if (!confirmed && !confirm_prog())
  91. return CMD_RET_FAILURE;
  92. ret = fuse_prog(bank, word, val);
  93. if (ret)
  94. goto err;
  95. }
  96. } else if (!strcmp(op, "override")) {
  97. if (argc < 3)
  98. return CMD_RET_USAGE;
  99. for (i = 2; i < argc; i++, word++) {
  100. if (strtou32(argv[i], 16, &val))
  101. return CMD_RET_USAGE;
  102. printf("Overriding bank %u word 0x%.8x with "
  103. "0x%.8x...\n", bank, word, val);
  104. ret = fuse_override(bank, word, val);
  105. if (ret)
  106. goto err;
  107. }
  108. } else {
  109. return CMD_RET_USAGE;
  110. }
  111. return 0;
  112. err:
  113. puts("ERROR\n");
  114. return ret;
  115. }
  116. U_BOOT_CMD(
  117. fuse, CONFIG_SYS_MAXARGS, 0, do_fuse,
  118. "Fuse sub-system",
  119. "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n"
  120. " starting at 'word'\n"
  121. "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n"
  122. " starting at 'word'\n"
  123. "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n"
  124. " several fuse words, starting at 'word' (PERMANENT)\n"
  125. "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n"
  126. " several fuse words, starting at 'word'"
  127. );