misc.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * RK3399: Architecture common definitions
  4. *
  5. * Copyright (C) 2019 Collabora Inc - https://www.collabora.com/
  6. * Rohan Garg <rohan.garg@collabora.com>
  7. *
  8. * Based on puma-rk3399.c:
  9. * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
  10. */
  11. #include <common.h>
  12. #include <env.h>
  13. #include <dm.h>
  14. #include <hash.h>
  15. #include <log.h>
  16. #include <dm/uclass-internal.h>
  17. #include <misc.h>
  18. #include <u-boot/crc.h>
  19. #include <u-boot/sha256.h>
  20. #include <asm/arch-rockchip/misc.h>
  21. int rockchip_setup_macaddr(void)
  22. {
  23. #if CONFIG_IS_ENABLED(CMD_NET)
  24. int ret;
  25. const char *cpuid = env_get("cpuid#");
  26. u8 hash[SHA256_SUM_LEN];
  27. int size = sizeof(hash);
  28. u8 mac_addr[6];
  29. /* Only generate a MAC address, if none is set in the environment */
  30. if (env_get("ethaddr"))
  31. return 0;
  32. if (!cpuid) {
  33. debug("%s: could not retrieve 'cpuid#'\n", __func__);
  34. return -1;
  35. }
  36. ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
  37. if (ret) {
  38. debug("%s: failed to calculate SHA256\n", __func__);
  39. return -1;
  40. }
  41. /* Copy 6 bytes of the hash to base the MAC address on */
  42. memcpy(mac_addr, hash, 6);
  43. /* Make this a valid MAC address and set it */
  44. mac_addr[0] &= 0xfe; /* clear multicast bit */
  45. mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
  46. eth_env_set_enetaddr("ethaddr", mac_addr);
  47. #endif
  48. return 0;
  49. }
  50. int rockchip_cpuid_from_efuse(const u32 cpuid_offset,
  51. const u32 cpuid_length,
  52. u8 *cpuid)
  53. {
  54. #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) || CONFIG_IS_ENABLED(ROCKCHIP_OTP)
  55. struct udevice *dev;
  56. int ret;
  57. /* retrieve the device */
  58. #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
  59. ret = uclass_get_device_by_driver(UCLASS_MISC,
  60. DM_GET_DRIVER(rockchip_efuse), &dev);
  61. #elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
  62. ret = uclass_get_device_by_driver(UCLASS_MISC,
  63. DM_GET_DRIVER(rockchip_otp), &dev);
  64. #endif
  65. if (ret) {
  66. debug("%s: could not find efuse device\n", __func__);
  67. return -1;
  68. }
  69. /* read the cpu_id range from the efuses */
  70. ret = misc_read(dev, cpuid_offset, cpuid, cpuid_length);
  71. if (ret) {
  72. debug("%s: reading cpuid from the efuses failed\n",
  73. __func__);
  74. return -1;
  75. }
  76. #endif
  77. return 0;
  78. }
  79. int rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length)
  80. {
  81. u8 low[cpuid_length / 2], high[cpuid_length / 2];
  82. char cpuid_str[cpuid_length * 2 + 1];
  83. u64 serialno;
  84. char serialno_str[17];
  85. const char *oldid;
  86. int i;
  87. memset(cpuid_str, 0, sizeof(cpuid_str));
  88. for (i = 0; i < 16; i++)
  89. sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]);
  90. debug("cpuid: %s\n", cpuid_str);
  91. /*
  92. * Mix the cpuid bytes using the same rules as in
  93. * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c
  94. */
  95. for (i = 0; i < 8; i++) {
  96. low[i] = cpuid[1 + (i << 1)];
  97. high[i] = cpuid[i << 1];
  98. }
  99. serialno = crc32_no_comp(0, low, 8);
  100. serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
  101. snprintf(serialno_str, sizeof(serialno_str), "%016llx", serialno);
  102. oldid = env_get("cpuid#");
  103. if (oldid && strcmp(oldid, cpuid_str) != 0)
  104. printf("cpuid: value %s present in env does not match hardware %s\n",
  105. oldid, cpuid_str);
  106. env_set("cpuid#", cpuid_str);
  107. /* Only generate serial# when none is set yet */
  108. if (!env_get("serial#"))
  109. env_set("serial#", serialno_str);
  110. return 0;
  111. }