sec.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <linux/libfdt.h>
  7. #include <fdt_support.h>
  8. #if CONFIG_SYS_FSL_SEC_COMPAT == 2 || CONFIG_SYS_FSL_SEC_COMPAT >= 4
  9. #include <fsl_sec.h>
  10. #endif
  11. /*
  12. * update crypto node properties to a specified revision of the SEC
  13. * called with sec_rev == 0 if not on an E processor
  14. */
  15. #if CONFIG_SYS_FSL_SEC_COMPAT == 2 /* SEC 2.x/3.x */
  16. void fdt_fixup_crypto_node(void *blob, int sec_rev)
  17. {
  18. static const struct sec_rev_prop {
  19. u32 sec_rev;
  20. u32 num_channels;
  21. u32 channel_fifo_len;
  22. u32 exec_units_mask;
  23. u32 descriptor_types_mask;
  24. } sec_rev_prop_list[] = {
  25. { 0x0200, 4, 24, 0x07e, 0x01010ebf }, /* SEC 2.0 */
  26. { 0x0201, 4, 24, 0x0fe, 0x012b0ebf }, /* SEC 2.1 */
  27. { 0x0202, 1, 24, 0x04c, 0x0122003f }, /* SEC 2.2 */
  28. { 0x0204, 4, 24, 0x07e, 0x012b0ebf }, /* SEC 2.4 */
  29. { 0x0300, 4, 24, 0x9fe, 0x03ab0ebf }, /* SEC 3.0 */
  30. { 0x0301, 4, 24, 0xbfe, 0x03ab0ebf }, /* SEC 3.1 */
  31. { 0x0303, 4, 24, 0x97c, 0x03a30abf }, /* SEC 3.3 */
  32. };
  33. static char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
  34. sizeof("fsl,secX.Y")];
  35. int crypto_node, sec_idx, err;
  36. char *p;
  37. u32 val;
  38. /* locate crypto node based on lowest common compatible */
  39. crypto_node = fdt_node_offset_by_compatible(blob, -1, "fsl,sec2.0");
  40. if (crypto_node == -FDT_ERR_NOTFOUND)
  41. return;
  42. /* delete it if not on an E-processor */
  43. if (crypto_node > 0 && !sec_rev) {
  44. fdt_del_node(blob, crypto_node);
  45. return;
  46. }
  47. /* else we got called for possible uprev */
  48. for (sec_idx = 0; sec_idx < ARRAY_SIZE(sec_rev_prop_list); sec_idx++)
  49. if (sec_rev_prop_list[sec_idx].sec_rev == sec_rev)
  50. break;
  51. if (sec_idx == ARRAY_SIZE(sec_rev_prop_list)) {
  52. puts("warning: unknown SEC revision number\n");
  53. return;
  54. }
  55. err = fdt_setprop_u32(blob, crypto_node, "fsl,num-channels",
  56. sec_rev_prop_list[sec_idx].num_channels);
  57. if (err < 0)
  58. printf("WARNING: could not set crypto property: %s\n",
  59. fdt_strerror(err));
  60. err = fdt_setprop_u32(blob, crypto_node, "fsl,descriptor-types-mask",
  61. sec_rev_prop_list[sec_idx].descriptor_types_mask);
  62. if (err < 0)
  63. printf("WARNING: could not set crypto property: %s\n",
  64. fdt_strerror(err));
  65. err = fdt_setprop_u32(blob, crypto_node, "fsl,exec-units-mask",
  66. sec_rev_prop_list[sec_idx].exec_units_mask);
  67. if (err < 0)
  68. printf("WARNING: could not set crypto property: %s\n",
  69. fdt_strerror(err));
  70. err = fdt_setprop_u32(blob, crypto_node, "fsl,channel-fifo-len",
  71. sec_rev_prop_list[sec_idx].channel_fifo_len);
  72. if (err < 0)
  73. printf("WARNING: could not set crypto property: %s\n",
  74. fdt_strerror(err));
  75. val = 0;
  76. while (sec_idx >= 0) {
  77. p = compat_strlist + val;
  78. val += sprintf(p, "fsl,sec%d.%d",
  79. (sec_rev_prop_list[sec_idx].sec_rev & 0xff00) >> 8,
  80. sec_rev_prop_list[sec_idx].sec_rev & 0x00ff) + 1;
  81. sec_idx--;
  82. }
  83. err = fdt_setprop(blob, crypto_node, "compatible", &compat_strlist,
  84. val);
  85. if (err < 0)
  86. printf("WARNING: could not set crypto property: %s\n",
  87. fdt_strerror(err));
  88. }
  89. #elif CONFIG_SYS_FSL_SEC_COMPAT >= 4 /* SEC4 */
  90. /**
  91. * caam_get_era() - fetch the CAAM's era
  92. *
  93. * The SEC module povides an "Era" which can be used to differentiate
  94. * between different revisions.
  95. *
  96. * Return: era of the SEC.
  97. */
  98. u8 caam_get_era(void)
  99. {
  100. static const struct {
  101. u16 ip_id;
  102. u8 maj_rev;
  103. u8 era;
  104. } caam_eras[] = {
  105. {0x0A10, 1, 1},
  106. {0x0A10, 2, 2},
  107. {0x0A12, 1, 3},
  108. {0x0A14, 1, 3},
  109. {0x0A14, 2, 4},
  110. {0x0A16, 1, 4},
  111. {0x0A10, 3, 4},
  112. {0x0A11, 1, 4},
  113. {0x0A18, 1, 4},
  114. {0x0A11, 2, 5},
  115. {0x0A12, 2, 5},
  116. {0x0A13, 1, 5},
  117. {0x0A1C, 1, 5}
  118. };
  119. ccsr_sec_t __iomem *sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
  120. u32 secvid_ms = sec_in32(&sec->secvid_ms);
  121. u32 ccbvid = sec_in32(&sec->ccbvid);
  122. u16 ip_id = (secvid_ms & SEC_SECVID_MS_IPID_MASK) >>
  123. SEC_SECVID_MS_IPID_SHIFT;
  124. u8 maj_rev = (secvid_ms & SEC_SECVID_MS_MAJ_REV_MASK) >>
  125. SEC_SECVID_MS_MAJ_REV_SHIFT;
  126. u8 era = (ccbvid & SEC_CCBVID_ERA_MASK) >> SEC_CCBVID_ERA_SHIFT;
  127. int i;
  128. if (era) /* This is '0' prior to CAAM ERA-6 */
  129. return era;
  130. for (i = 0; i < ARRAY_SIZE(caam_eras); i++)
  131. if (caam_eras[i].ip_id == ip_id &&
  132. caam_eras[i].maj_rev == maj_rev)
  133. return caam_eras[i].era;
  134. return 0;
  135. }
  136. static void fdt_fixup_crypto_era(void *blob, u32 era)
  137. {
  138. int err;
  139. int crypto_node;
  140. crypto_node = fdt_path_offset(blob, "crypto");
  141. if (crypto_node < 0) {
  142. printf("WARNING: Missing crypto node\n");
  143. return;
  144. }
  145. err = fdt_setprop_u32(blob, crypto_node, "fsl,sec-era", era);
  146. if (err < 0) {
  147. printf("ERROR: could not set fsl,sec-era property: %s\n",
  148. fdt_strerror(err));
  149. }
  150. }
  151. void fdt_fixup_crypto_node(void *blob, int sec_rev)
  152. {
  153. u8 era;
  154. if (!sec_rev) {
  155. fdt_del_node_and_alias(blob, "crypto");
  156. return;
  157. }
  158. /* Add SEC ERA information in compatible */
  159. era = caam_get_era();
  160. if (era) {
  161. fdt_fixup_crypto_era(blob, era);
  162. } else {
  163. printf("WARNING: Unable to get ERA for CAAM rev: %d\n",
  164. sec_rev);
  165. }
  166. }
  167. #endif