reset-socfpga.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 int socfpga_reset_request(struct reset_ctl *reset_ctl)
  81. {
  82. debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__,
  83. reset_ctl, reset_ctl->dev, reset_ctl->id);
  84. return 0;
  85. }
  86. static int socfpga_reset_free(struct reset_ctl *reset_ctl)
  87. {
  88. debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
  89. reset_ctl->dev, reset_ctl->id);
  90. return 0;
  91. }
  92. static const struct reset_ops socfpga_reset_ops = {
  93. .request = socfpga_reset_request,
  94. .rfree = socfpga_reset_free,
  95. .rst_assert = socfpga_reset_assert,
  96. .rst_deassert = socfpga_reset_deassert,
  97. };
  98. static int socfpga_reset_probe(struct udevice *dev)
  99. {
  100. struct socfpga_reset_data *data = dev_get_priv(dev);
  101. u32 modrst_offset;
  102. void __iomem *membase;
  103. membase = dev_read_addr_ptr(dev);
  104. modrst_offset = dev_read_u32_default(dev, "altr,modrst-offset", 0x10);
  105. data->modrst_base = membase + modrst_offset;
  106. return 0;
  107. }
  108. static int socfpga_reset_remove(struct udevice *dev)
  109. {
  110. struct socfpga_reset_data *data = dev_get_priv(dev);
  111. if (socfpga_reset_keep_enabled()) {
  112. puts("Deasserting all peripheral resets\n");
  113. writel(0, data->modrst_base + 4);
  114. }
  115. return 0;
  116. }
  117. static int socfpga_reset_bind(struct udevice *dev)
  118. {
  119. int ret;
  120. struct udevice *sys_child;
  121. /*
  122. * The sysreset driver does not have a device node, so bind it here.
  123. * Bind it to the node, too, so that it can get its base address.
  124. */
  125. ret = device_bind_driver_to_node(dev, "socfpga_sysreset", "sysreset",
  126. dev_ofnode(dev), &sys_child);
  127. if (ret)
  128. debug("Warning: No sysreset driver: ret=%d\n", ret);
  129. return 0;
  130. }
  131. static const struct udevice_id socfpga_reset_match[] = {
  132. { .compatible = "altr,rst-mgr" },
  133. { /* sentinel */ },
  134. };
  135. U_BOOT_DRIVER(socfpga_reset) = {
  136. .name = "socfpga-reset",
  137. .id = UCLASS_RESET,
  138. .of_match = socfpga_reset_match,
  139. .bind = socfpga_reset_bind,
  140. .probe = socfpga_reset_probe,
  141. .priv_auto = sizeof(struct socfpga_reset_data),
  142. .ops = &socfpga_reset_ops,
  143. .remove = socfpga_reset_remove,
  144. .flags = DM_FLAG_OS_PREPARE,
  145. };