reset-socfpga.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Socfpga Reset Controller Driver
  4. *
  5. * Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
  6. *
  7. * based on
  8. * Allwinner SoCs Reset Controller driver
  9. *
  10. * Copyright 2013 Maxime Ripard
  11. *
  12. * Maxime Ripard <maxime.ripard@free-electrons.com>
  13. */
  14. #include <common.h>
  15. #include <dm.h>
  16. #include <log.h>
  17. #include <malloc.h>
  18. #include <dm/lists.h>
  19. #include <dm/of_access.h>
  20. #include <env.h>
  21. #include <reset-uclass.h>
  22. #include <wait_bit.h>
  23. #include <linux/bitops.h>
  24. #include <linux/io.h>
  25. #include <linux/sizes.h>
  26. #define BANK_INCREMENT 4
  27. #define NR_BANKS 8
  28. struct socfpga_reset_data {
  29. void __iomem *modrst_base;
  30. };
  31. /*
  32. * For compatibility with Kernels that don't support peripheral reset, this
  33. * driver can keep the old behaviour of not asserting peripheral reset before
  34. * starting the OS and deasserting all peripheral resets (enabling all
  35. * peripherals).
  36. *
  37. * For that, the reset driver checks the environment variable
  38. * "socfpga_legacy_reset_compat". If this variable is '1', perihperals are not
  39. * reset again once taken out of reset and all peripherals in 'permodrst' are
  40. * taken out of reset before booting into the OS.
  41. * Note that this should be required for gen5 systems only that are running
  42. * Linux kernels without proper peripheral reset support for all drivers used.
  43. */
  44. static bool socfpga_reset_keep_enabled(void)
  45. {
  46. #if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(ENV_SUPPORT)
  47. const char *env_str;
  48. long val;
  49. env_str = env_get("socfpga_legacy_reset_compat");
  50. if (env_str) {
  51. val = simple_strtol(env_str, NULL, 0);
  52. if (val == 1)
  53. return true;
  54. }
  55. #endif
  56. return false;
  57. }
  58. static int socfpga_reset_assert(struct reset_ctl *reset_ctl)
  59. {
  60. struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev);
  61. int id = reset_ctl->id;
  62. int reg_width = sizeof(u32);
  63. int bank = id / (reg_width * BITS_PER_BYTE);
  64. int offset = id % (reg_width * BITS_PER_BYTE);
  65. setbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset));
  66. return 0;
  67. }
  68. static int socfpga_reset_deassert(struct reset_ctl *reset_ctl)
  69. {
  70. struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev);
  71. int id = reset_ctl->id;
  72. int reg_width = sizeof(u32);
  73. int bank = id / (reg_width * BITS_PER_BYTE);
  74. int offset = id % (reg_width * BITS_PER_BYTE);
  75. clrbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset));
  76. return wait_for_bit_le32(data->modrst_base + (bank * BANK_INCREMENT),
  77. BIT(offset),
  78. false, 500, false);
  79. }
  80. static const struct reset_ops socfpga_reset_ops = {
  81. .rst_assert = socfpga_reset_assert,
  82. .rst_deassert = socfpga_reset_deassert,
  83. };
  84. static int socfpga_reset_probe(struct udevice *dev)
  85. {
  86. struct socfpga_reset_data *data = dev_get_priv(dev);
  87. u32 modrst_offset;
  88. void __iomem *membase;
  89. membase = dev_read_addr_ptr(dev);
  90. modrst_offset = dev_read_u32_default(dev, "altr,modrst-offset", 0x10);
  91. data->modrst_base = membase + modrst_offset;
  92. return 0;
  93. }
  94. static int socfpga_reset_remove(struct udevice *dev)
  95. {
  96. struct socfpga_reset_data *data = dev_get_priv(dev);
  97. if (socfpga_reset_keep_enabled()) {
  98. puts("Deasserting all peripheral resets\n");
  99. writel(0, data->modrst_base + 4);
  100. }
  101. return 0;
  102. }
  103. static int socfpga_reset_bind(struct udevice *dev)
  104. {
  105. int ret;
  106. struct udevice *sys_child;
  107. /*
  108. * The sysreset driver does not have a device node, so bind it here.
  109. * Bind it to the node, too, so that it can get its base address.
  110. */
  111. ret = device_bind_driver_to_node(dev, "socfpga_sysreset", "sysreset",
  112. dev_ofnode(dev), &sys_child);
  113. if (ret)
  114. debug("Warning: No sysreset driver: ret=%d\n", ret);
  115. return 0;
  116. }
  117. static const struct udevice_id socfpga_reset_match[] = {
  118. { .compatible = "altr,rst-mgr" },
  119. { /* sentinel */ },
  120. };
  121. U_BOOT_DRIVER(socfpga_reset) = {
  122. .name = "socfpga-reset",
  123. .id = UCLASS_RESET,
  124. .of_match = socfpga_reset_match,
  125. .bind = socfpga_reset_bind,
  126. .probe = socfpga_reset_probe,
  127. .priv_auto = sizeof(struct socfpga_reset_data),
  128. .ops = &socfpga_reset_ops,
  129. .remove = socfpga_reset_remove,
  130. .flags = DM_FLAG_OS_PREPARE,
  131. };