reset-jh7110.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
  4. * Author: samin <samin.guo@starfivetech.com>
  5. * yanhong <yanhong.wang@starfivetech.com>
  6. *
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <errno.h>
  11. #include <log.h>
  12. #include <malloc.h>
  13. #include <reset-uclass.h>
  14. #include <linux/io.h>
  15. #include <linux/delay.h>
  16. #include <linux/iopoll.h>
  17. #include <dt-bindings/reset/starfive-jh7110.h>
  18. #define AONCRG_RESET_ASSERT 0x38
  19. #define AONCRG_RESET_STATUS 0x3C
  20. #define ISPCRG_RESET_ASSERT 0x38
  21. #define ISPCRG_RESET_STATUS 0x3C
  22. #define VOUTCRG_RESET_ASSERT 0x48
  23. #define VOUTCRG_RESET_STATUS 0x4C
  24. #define STGCRG_RESET_ASSERT 0x74
  25. #define STGCRG_RESET_STATUS 0x78
  26. #define SYSCRG_RESET_ASSERT0 0x2F8
  27. #define SYSCRG_RESET_ASSERT1 0x2FC
  28. #define SYSCRG_RESET_ASSERT2 0x300
  29. #define SYSCRG_RESET_ASSERT3 0x304
  30. #define SYSCRG_RESET_STATUS0 0x308
  31. #define SYSCRG_RESET_STATUS1 0x30C
  32. #define SYSCRG_RESET_STATUS2 0x310
  33. #define SYSCRG_RESET_STATUS3 0x314
  34. struct reset_assert_t {
  35. void __iomem *assert;
  36. void __iomem *status;
  37. };
  38. enum JH7110_RESET_CRG_GROUP {
  39. SYSCRG_0 = 0,
  40. SYSCRG_1,
  41. SYSCRG_2,
  42. SYSCRG_3,
  43. STGCRG,
  44. AONCRG,
  45. ISPCRG,
  46. VOUTCRG,
  47. };
  48. struct jh7110_reset_priv {
  49. void __iomem *syscrg;
  50. void __iomem *stgcrg;
  51. void __iomem *aoncrg;
  52. void __iomem *ispcrg;
  53. void __iomem *voutcrg;
  54. };
  55. static int jh7110_get_reset(struct jh7110_reset_priv *priv,
  56. struct reset_assert_t *reset,
  57. unsigned long group)
  58. {
  59. switch (group) {
  60. case SYSCRG_0:
  61. reset->assert = priv->syscrg + SYSCRG_RESET_ASSERT0;
  62. reset->status = priv->syscrg + SYSCRG_RESET_STATUS0;
  63. break;
  64. case SYSCRG_1:
  65. reset->assert = priv->syscrg + SYSCRG_RESET_ASSERT1;
  66. reset->status = priv->syscrg + SYSCRG_RESET_STATUS1;
  67. break;
  68. case SYSCRG_2:
  69. reset->assert = priv->syscrg + SYSCRG_RESET_ASSERT2;
  70. reset->status = priv->syscrg + SYSCRG_RESET_STATUS2;
  71. break;
  72. case SYSCRG_3:
  73. reset->assert = priv->syscrg + SYSCRG_RESET_ASSERT3;
  74. reset->status = priv->syscrg + SYSCRG_RESET_STATUS3;
  75. break;
  76. case STGCRG:
  77. reset->assert = priv->stgcrg + STGCRG_RESET_ASSERT;
  78. reset->status = priv->stgcrg + STGCRG_RESET_STATUS;
  79. break;
  80. case AONCRG:
  81. reset->assert = priv->aoncrg + AONCRG_RESET_ASSERT;
  82. reset->status = priv->aoncrg + AONCRG_RESET_STATUS;
  83. break;
  84. case ISPCRG:
  85. reset->assert = priv->ispcrg + ISPCRG_RESET_ASSERT;
  86. reset->status = priv->ispcrg + ISPCRG_RESET_STATUS;
  87. break;
  88. case VOUTCRG:
  89. reset->assert = priv->voutcrg + VOUTCRG_RESET_ASSERT;
  90. reset->status = priv->voutcrg + VOUTCRG_RESET_STATUS;
  91. break;
  92. default:
  93. return -EINVAL;
  94. }
  95. return 0;
  96. }
  97. static int jh7110_reset_trigger(struct jh7110_reset_priv *priv,
  98. unsigned long id, bool assert)
  99. {
  100. struct reset_assert_t reset;
  101. unsigned long group;
  102. u32 mask, value, done = 0;
  103. int ret;
  104. u32 loop;
  105. group = id / 32;
  106. mask = BIT(id % 32);
  107. ret = jh7110_get_reset(priv, &reset, group);
  108. if (ret) {
  109. debug("reset: bad reset id.\n");
  110. return ret;
  111. }
  112. if (!assert)
  113. done ^= mask;
  114. value = readl(reset.assert);
  115. if (assert)
  116. value |= mask;
  117. else
  118. value &= ~mask;
  119. writel(value, reset.assert);
  120. loop = 10000; /*Addd loop condition inorder to avoid hang here*/
  121. do{
  122. value = in_le32(reset.status);
  123. }while((value & mask) != done && --loop != 0);
  124. return ret;
  125. }
  126. static int jh7110_reset_assert(struct reset_ctl *rst)
  127. {
  128. struct jh7110_reset_priv *priv = dev_get_priv(rst->dev);
  129. jh7110_reset_trigger(priv, rst->id, true);
  130. return 0;
  131. }
  132. static int jh7110_reset_deassert(struct reset_ctl *rst)
  133. {
  134. struct jh7110_reset_priv *priv = dev_get_priv(rst->dev);
  135. jh7110_reset_trigger(priv, rst->id, false);
  136. return 0;
  137. }
  138. static int jh7110_reset_free(struct reset_ctl *rst)
  139. {
  140. return 0;
  141. }
  142. static int jh7110_reset_request(struct reset_ctl *rst)
  143. {
  144. if (rst->id >= RSTN_JH7110_RESET_END)
  145. return -EINVAL;
  146. return 0;
  147. }
  148. struct reset_ops jh7110_reset_reset_ops = {
  149. .rfree = jh7110_reset_free,
  150. .request = jh7110_reset_request,
  151. .rst_assert = jh7110_reset_assert,
  152. .rst_deassert = jh7110_reset_deassert,
  153. };
  154. static const struct udevice_id jh7110_reset_ids[] = {
  155. { .compatible = "starfive,jh7110-reset" },
  156. { /* sentinel */ }
  157. };
  158. static int jh7110_reset_probe(struct udevice *dev)
  159. {
  160. struct jh7110_reset_priv *priv = dev_get_priv(dev);
  161. priv->syscrg = dev_remap_addr_name(dev, "syscrg");
  162. if (!priv->syscrg)
  163. return -EINVAL;
  164. priv->stgcrg = dev_remap_addr_name(dev, "stgcrg");
  165. if (!priv->stgcrg)
  166. return -EINVAL;
  167. priv->aoncrg = dev_remap_addr_name(dev, "aoncrg");
  168. if (!priv->aoncrg)
  169. return -EINVAL;
  170. priv->ispcrg = dev_remap_addr_name(dev, "ispcrg");
  171. if (!priv->ispcrg)
  172. return -EINVAL;
  173. priv->voutcrg = dev_remap_addr_name(dev, "voutcrg");
  174. if (!priv->voutcrg)
  175. return -EINVAL;
  176. return 0;
  177. }
  178. U_BOOT_DRIVER(jh7110_reset) = {
  179. .name = "jh7110-reset",
  180. .id = UCLASS_RESET,
  181. .of_match = jh7110_reset_ids,
  182. .ops = &jh7110_reset_reset_ops,
  183. .probe = jh7110_reset_probe,
  184. .priv_auto = sizeof(struct jh7110_reset_priv),
  185. };