mpfs_icicle.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019 Microchip Technology Inc.
  4. * Padmarao Begari <padmarao.begari@microchip.com>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <env.h>
  9. #include <init.h>
  10. #include <asm/global_data.h>
  11. #include <asm/io.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. #define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088)
  14. #define MPFS_SYS_SERVICE_CR ((unsigned int *)0x37020050)
  15. #define MPFS_SYS_SERVICE_SR ((unsigned int *)0x37020054)
  16. #define MPFS_SYS_SERVICE_MAILBOX ((unsigned char *)0x37020800)
  17. #define PERIPH_RESET_VALUE 0x1e8u
  18. #define SERVICE_CR_REQ 0x1u
  19. #define SERVICE_SR_BUSY 0x2u
  20. static void read_device_serial_number(u8 *response, u8 response_size)
  21. {
  22. u8 idx;
  23. u8 *response_buf;
  24. unsigned int val;
  25. response_buf = (u8 *)response;
  26. writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR);
  27. /*
  28. * REQ bit will remain set till the system controller starts
  29. * processing.
  30. */
  31. do {
  32. val = readl(MPFS_SYS_SERVICE_CR);
  33. } while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ));
  34. /*
  35. * Once system controller starts processing the busy bit will
  36. * go high and service is completed when busy bit is gone low
  37. */
  38. do {
  39. val = readl(MPFS_SYS_SERVICE_SR);
  40. } while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY));
  41. for (idx = 0; idx < response_size; idx++)
  42. response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
  43. }
  44. int board_init(void)
  45. {
  46. /* For now nothing to do here. */
  47. return 0;
  48. }
  49. int board_early_init_f(void)
  50. {
  51. unsigned int val;
  52. /* Reset uart, mmc peripheral */
  53. val = readl(MPFS_SYSREG_SOFT_RESET);
  54. val = (val & ~(PERIPH_RESET_VALUE));
  55. writel(val, MPFS_SYSREG_SOFT_RESET);
  56. return 0;
  57. }
  58. int board_late_init(void)
  59. {
  60. u32 ret;
  61. u32 node;
  62. u8 idx;
  63. u8 device_serial_number[16] = { 0 };
  64. unsigned char mac_addr[6];
  65. char icicle_mac_addr[20];
  66. void *blob = (void *)gd->fdt_blob;
  67. node = fdt_path_offset(blob, "ethernet0");
  68. if (node < 0) {
  69. printf("No ethernet0 path offset\n");
  70. return -ENODEV;
  71. }
  72. ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6);
  73. if (ret) {
  74. printf("No local-mac-address property\n");
  75. return -EINVAL;
  76. }
  77. read_device_serial_number(device_serial_number, 16);
  78. /* Update MAC address with device serial number */
  79. mac_addr[0] = 0x00;
  80. mac_addr[1] = 0x04;
  81. mac_addr[2] = 0xA3;
  82. mac_addr[3] = device_serial_number[2];
  83. mac_addr[4] = device_serial_number[1];
  84. mac_addr[5] = device_serial_number[0];
  85. ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6);
  86. if (ret) {
  87. printf("Error setting local-mac-address property\n");
  88. return -ENODEV;
  89. }
  90. icicle_mac_addr[0] = '[';
  91. sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
  92. icicle_mac_addr[18] = ']';
  93. icicle_mac_addr[19] = '\0';
  94. for (idx = 0; idx < 20; idx++) {
  95. if (icicle_mac_addr[idx] == ':')
  96. icicle_mac_addr[idx] = ' ';
  97. }
  98. env_set("icicle_mac_addr", icicle_mac_addr);
  99. return 0;
  100. }