sfp.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright 2021 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <caam.h>
  12. #include <common/debug.h>
  13. #include <drivers/delay_timer.h>
  14. #include <sfp.h>
  15. #include <sfp_error_codes.h>
  16. static uintptr_t g_nxp_sfp_addr;
  17. static uint32_t srk_hash[SRK_HASH_SIZE/sizeof(uint32_t)]
  18. __aligned(CACHE_WRITEBACK_GRANULE);
  19. void sfp_init(uintptr_t nxp_sfp_addr)
  20. {
  21. g_nxp_sfp_addr = nxp_sfp_addr;
  22. }
  23. uintptr_t get_sfp_addr(void)
  24. {
  25. return g_nxp_sfp_addr;
  26. }
  27. uint32_t *get_sfp_srk_hash(void)
  28. {
  29. struct sfp_ccsr_regs_t *sfp_ccsr_regs =
  30. (void *) (g_nxp_sfp_addr + SFP_FUSE_REGS_OFFSET);
  31. int i = 0;
  32. /* Add comparison of hash with SFP hash here */
  33. for (i = 0; i < SRK_HASH_SIZE/sizeof(uint32_t); i++)
  34. srk_hash[i] =
  35. mmio_read_32((uintptr_t)&sfp_ccsr_regs->srk_hash[i]);
  36. return srk_hash;
  37. }
  38. void set_sfp_wr_disable(void)
  39. {
  40. /*
  41. * Mark SFP Write Disable and Write Disable Lock
  42. * Bit to prevent write to SFP fuses like
  43. * OUID's, Key Revocation fuse etc
  44. */
  45. void *sfpcr = (void *)(g_nxp_sfp_addr + SFP_SFPCR_OFFSET);
  46. uint32_t sfpcr_val;
  47. sfpcr_val = sfp_read32(sfpcr);
  48. sfpcr_val |= (SFP_SFPCR_WD | SFP_SFPCR_WDL);
  49. sfp_write32(sfpcr, sfpcr_val);
  50. }
  51. int sfp_program_fuses(void)
  52. {
  53. uint32_t ingr;
  54. uint32_t sfp_cmd_status = 0U;
  55. int ret = 0;
  56. /* Program SFP fuses from mirror registers */
  57. sfp_write32((void *)(g_nxp_sfp_addr + SFP_INGR_OFFSET),
  58. SFP_INGR_PROGFB_CMD);
  59. /* Wait until fuse programming is successful */
  60. do {
  61. ingr = sfp_read32(g_nxp_sfp_addr + SFP_INGR_OFFSET);
  62. } while (ingr & SFP_INGR_PROGFB_CMD);
  63. /* Check for SFP fuse programming error */
  64. sfp_cmd_status = sfp_read32(g_nxp_sfp_addr + SFP_INGR_OFFSET)
  65. & SFP_INGR_ERROR_MASK;
  66. if (sfp_cmd_status != 0U) {
  67. return ERROR_PROGFB_CMD;
  68. }
  69. return ret;
  70. }
  71. uint32_t sfp_read_oem_uid(uint8_t oem_uid)
  72. {
  73. uint32_t val = 0U;
  74. struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr
  75. + SFP_FUSE_REGS_OFFSET);
  76. if (oem_uid > MAX_OEM_UID) {
  77. ERROR("Invalid OEM UID received.\n");
  78. return ERROR_OEMUID_WRITE;
  79. }
  80. val = sfp_read32(&sfp_ccsr_regs->oem_uid[oem_uid]);
  81. return val;
  82. }
  83. /*
  84. * return val: 0 - No update required.
  85. * 1 - successful update done.
  86. * ERROR_OEMUID_WRITE - Invalid OEM UID
  87. */
  88. uint32_t sfp_write_oem_uid(uint8_t oem_uid, uint32_t sfp_val)
  89. {
  90. uint32_t val = 0U;
  91. struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr
  92. + SFP_FUSE_REGS_OFFSET);
  93. val = sfp_read_oem_uid(oem_uid);
  94. if (val == ERROR_OEMUID_WRITE) {
  95. return ERROR_OEMUID_WRITE;
  96. }
  97. /* Counter already set. No need to do anything */
  98. if ((val & sfp_val) != 0U) {
  99. return 0U;
  100. }
  101. val |= sfp_val;
  102. INFO("SFP Value is %x for setting sfp_val = %d\n", val, sfp_val);
  103. sfp_write32(&sfp_ccsr_regs->oem_uid[oem_uid], val);
  104. return 1U;
  105. }
  106. int sfp_check_its(void)
  107. {
  108. struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr
  109. + SFP_FUSE_REGS_OFFSET);
  110. if ((sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_ITS_MASK) != 0) {
  111. return 1;
  112. } else {
  113. return 0;
  114. }
  115. }
  116. int sfp_check_oem_wp(void)
  117. {
  118. struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr
  119. + SFP_FUSE_REGS_OFFSET);
  120. if ((sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_WP_MASK) != 0) {
  121. return 1;
  122. } else {
  123. return 0;
  124. }
  125. }
  126. /* This function returns ospr's key_revoc values.*/
  127. uint32_t get_key_revoc(void)
  128. {
  129. struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(g_nxp_sfp_addr
  130. + SFP_FUSE_REGS_OFFSET);
  131. return (sfp_read32(&sfp_ccsr_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
  132. OSPR_KEY_REVOC_SHIFT;
  133. }