fuse.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2009-2013 ADVANSEE
  4. * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
  5. *
  6. * Based on the mpc512x iim code:
  7. * Copyright 2008 Silicon Turnkey Express, Inc.
  8. * Martha Marx <mmarx@silicontkx.com>
  9. */
  10. #include <common.h>
  11. #include <command.h>
  12. #include <console.h>
  13. #include <fuse.h>
  14. #include <linux/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 (confirm_yesno())
  31. return 1;
  32. puts("Fuse programming aborted\n");
  33. return 0;
  34. }
  35. static int do_fuse(struct cmd_tbl *cmdtp, int flag, int argc,
  36. char *const argv[])
  37. {
  38. const char *op = argc >= 2 ? argv[1] : NULL;
  39. int confirmed = argc >= 3 && !strcmp(argv[2], "-y");
  40. u32 bank, word, cnt, val;
  41. int ret, i;
  42. argc -= 2 + confirmed;
  43. argv += 2 + confirmed;
  44. if (argc < 2 || strtou32(argv[0], 0, &bank) ||
  45. strtou32(argv[1], 0, &word))
  46. return CMD_RET_USAGE;
  47. if (!strcmp(op, "read")) {
  48. if (argc == 2)
  49. cnt = 1;
  50. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  51. return CMD_RET_USAGE;
  52. printf("Reading bank %u:\n", bank);
  53. for (i = 0; i < cnt; i++, word++) {
  54. if (!(i % 4))
  55. printf("\nWord 0x%.8x:", word);
  56. ret = fuse_read(bank, word, &val);
  57. if (ret)
  58. goto err;
  59. printf(" %.8x", val);
  60. }
  61. putc('\n');
  62. } else if (!strcmp(op, "sense")) {
  63. if (argc == 2)
  64. cnt = 1;
  65. else if (argc != 3 || strtou32(argv[2], 0, &cnt))
  66. return CMD_RET_USAGE;
  67. printf("Sensing bank %u:\n", bank);
  68. for (i = 0; i < cnt; i++, word++) {
  69. if (!(i % 4))
  70. printf("\nWord 0x%.8x:", word);
  71. ret = fuse_sense(bank, word, &val);
  72. if (ret)
  73. goto err;
  74. printf(" %.8x", val);
  75. }
  76. putc('\n');
  77. } else if (!strcmp(op, "prog")) {
  78. if (argc < 3)
  79. return CMD_RET_USAGE;
  80. for (i = 2; i < argc; i++, word++) {
  81. if (strtou32(argv[i], 16, &val))
  82. return CMD_RET_USAGE;
  83. printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
  84. bank, word, val);
  85. if (!confirmed && !confirm_prog())
  86. return CMD_RET_FAILURE;
  87. ret = fuse_prog(bank, word, val);
  88. if (ret)
  89. goto err;
  90. }
  91. } else if (!strcmp(op, "override")) {
  92. if (argc < 3)
  93. return CMD_RET_USAGE;
  94. for (i = 2; i < argc; i++, word++) {
  95. if (strtou32(argv[i], 16, &val))
  96. return CMD_RET_USAGE;
  97. printf("Overriding bank %u word 0x%.8x with "
  98. "0x%.8x...\n", bank, word, val);
  99. ret = fuse_override(bank, word, val);
  100. if (ret)
  101. goto err;
  102. }
  103. } else {
  104. return CMD_RET_USAGE;
  105. }
  106. return 0;
  107. err:
  108. puts("ERROR\n");
  109. return CMD_RET_FAILURE;
  110. }
  111. U_BOOT_CMD(
  112. fuse, CONFIG_SYS_MAXARGS, 0, do_fuse,
  113. "Fuse sub-system",
  114. "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n"
  115. " starting at 'word'\n"
  116. "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n"
  117. " starting at 'word'\n"
  118. "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n"
  119. " several fuse words, starting at 'word' (PERMANENT)\n"
  120. "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n"
  121. " several fuse words, starting at 'word'"
  122. );