turris_mox.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <clk.h>
  8. #include <spi.h>
  9. #include <linux/string.h>
  10. #ifdef CONFIG_WDT_ARMADA_3720
  11. #include <wdt.h>
  12. #endif
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #ifdef CONFIG_WDT_ARMADA_3720
  15. static struct udevice *watchdog_dev;
  16. void watchdog_reset(void)
  17. {
  18. static ulong next_reset;
  19. ulong now;
  20. if (!watchdog_dev)
  21. return;
  22. now = timer_get_us();
  23. /* Do not reset the watchdog too often */
  24. if (now > next_reset) {
  25. wdt_reset(watchdog_dev);
  26. next_reset = now + 100000;
  27. }
  28. }
  29. #endif
  30. int board_init(void)
  31. {
  32. /* address of boot parameters */
  33. gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
  34. #ifdef CONFIG_WDT_ARMADA_3720
  35. if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
  36. printf("Cannot find Armada 3720 watchdog!\n");
  37. } else {
  38. printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
  39. wdt_start(watchdog_dev, 180000, 0);
  40. }
  41. #endif
  42. return 0;
  43. }
  44. int last_stage_init(void)
  45. {
  46. struct spi_slave *slave;
  47. struct udevice *dev;
  48. u8 din[10], dout[10];
  49. int ret, i;
  50. size_t len = 0;
  51. char module_topology[128];
  52. ret = spi_get_bus_and_cs(0, 1, 20000000, SPI_CPHA, "spi_generic_drv",
  53. "mox-modules@1", &dev, &slave);
  54. if (ret)
  55. goto fail;
  56. ret = spi_claim_bus(slave);
  57. if (ret)
  58. goto fail_free;
  59. memset(din, 0, 10);
  60. memset(dout, 0, 10);
  61. ret = spi_xfer(slave, 80, dout, din, SPI_XFER_ONCE);
  62. if (ret)
  63. goto fail_release;
  64. if (din[0] != 0x00 && din[0] != 0xff)
  65. goto fail_release;
  66. printf("Module Topology:\n");
  67. for (i = 1; i < 10 && din[i] != 0xff; ++i) {
  68. u8 mid = din[i] & 0xf;
  69. size_t mlen;
  70. const char *mname = "";
  71. switch (mid) {
  72. case 0x1:
  73. mname = "sfp-";
  74. printf("% 4i: SFP Module\n", i);
  75. break;
  76. case 0x2:
  77. mname = "pci-";
  78. printf("% 4i: Mini-PCIe Module\n", i);
  79. break;
  80. case 0x3:
  81. mname = "topaz-";
  82. printf("% 4i: Topaz Switch Module\n", i);
  83. break;
  84. default:
  85. printf("% 4i: unknown (ID %i)\n", i, mid);
  86. }
  87. mlen = strlen(mname);
  88. if (len + mlen < sizeof(module_topology)) {
  89. strcpy(module_topology + len, mname);
  90. len += mlen;
  91. }
  92. }
  93. printf("\n");
  94. module_topology[len > 0 ? len - 1 : 0] = '\0';
  95. env_set("module_topology", module_topology);
  96. fail_release:
  97. spi_release_bus(slave);
  98. fail_free:
  99. spi_free_slave(slave);
  100. fail:
  101. if (ret)
  102. printf("Cannot read module topology!\n");
  103. return ret;
  104. }