ccu-rst.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
  4. *
  5. * Authors:
  6. * Serge Semin <[email protected]>
  7. *
  8. * Baikal-T1 CCU Resets interface driver
  9. */
  10. #define pr_fmt(fmt) "bt1-ccu-rst: " fmt
  11. #include <linux/bits.h>
  12. #include <linux/delay.h>
  13. #include <linux/kernel.h>
  14. #include <linux/of.h>
  15. #include <linux/printk.h>
  16. #include <linux/regmap.h>
  17. #include <linux/reset-controller.h>
  18. #include <linux/slab.h>
  19. #include <dt-bindings/reset/bt1-ccu.h>
  20. #include "ccu-rst.h"
  21. #define CCU_AXI_MAIN_BASE 0x030
  22. #define CCU_AXI_DDR_BASE 0x034
  23. #define CCU_AXI_SATA_BASE 0x038
  24. #define CCU_AXI_GMAC0_BASE 0x03C
  25. #define CCU_AXI_GMAC1_BASE 0x040
  26. #define CCU_AXI_XGMAC_BASE 0x044
  27. #define CCU_AXI_PCIE_M_BASE 0x048
  28. #define CCU_AXI_PCIE_S_BASE 0x04C
  29. #define CCU_AXI_USB_BASE 0x050
  30. #define CCU_AXI_HWA_BASE 0x054
  31. #define CCU_AXI_SRAM_BASE 0x058
  32. #define CCU_SYS_DDR_BASE 0x02c
  33. #define CCU_SYS_SATA_REF_BASE 0x060
  34. #define CCU_SYS_APB_BASE 0x064
  35. #define CCU_SYS_PCIE_BASE 0x144
  36. #define CCU_RST_DELAY_US 1
  37. #define CCU_RST_TRIG(_base, _ofs) \
  38. { \
  39. .type = CCU_RST_TRIG, \
  40. .base = _base, \
  41. .mask = BIT(_ofs), \
  42. }
  43. #define CCU_RST_DIR(_base, _ofs) \
  44. { \
  45. .type = CCU_RST_DIR, \
  46. .base = _base, \
  47. .mask = BIT(_ofs), \
  48. }
  49. struct ccu_rst_info {
  50. enum ccu_rst_type type;
  51. unsigned int base;
  52. unsigned int mask;
  53. };
  54. /*
  55. * Each AXI-bus clock divider is equipped with the corresponding clock-consumer
  56. * domain reset (it's self-deasserted reset control).
  57. */
  58. static const struct ccu_rst_info axi_rst_info[] = {
  59. [CCU_AXI_MAIN_RST] = CCU_RST_TRIG(CCU_AXI_MAIN_BASE, 1),
  60. [CCU_AXI_DDR_RST] = CCU_RST_TRIG(CCU_AXI_DDR_BASE, 1),
  61. [CCU_AXI_SATA_RST] = CCU_RST_TRIG(CCU_AXI_SATA_BASE, 1),
  62. [CCU_AXI_GMAC0_RST] = CCU_RST_TRIG(CCU_AXI_GMAC0_BASE, 1),
  63. [CCU_AXI_GMAC1_RST] = CCU_RST_TRIG(CCU_AXI_GMAC1_BASE, 1),
  64. [CCU_AXI_XGMAC_RST] = CCU_RST_TRIG(CCU_AXI_XGMAC_BASE, 1),
  65. [CCU_AXI_PCIE_M_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_M_BASE, 1),
  66. [CCU_AXI_PCIE_S_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_S_BASE, 1),
  67. [CCU_AXI_USB_RST] = CCU_RST_TRIG(CCU_AXI_USB_BASE, 1),
  68. [CCU_AXI_HWA_RST] = CCU_RST_TRIG(CCU_AXI_HWA_BASE, 1),
  69. [CCU_AXI_SRAM_RST] = CCU_RST_TRIG(CCU_AXI_SRAM_BASE, 1),
  70. };
  71. /*
  72. * SATA reference clock domain and APB-bus domain are connected with the
  73. * sefl-deasserted reset control, which can be activated via the corresponding
  74. * clock divider register. DDR and PCIe sub-domains can be reset with directly
  75. * controlled reset signals. Resetting the DDR controller though won't end up
  76. * well while the Linux kernel is working.
  77. */
  78. static const struct ccu_rst_info sys_rst_info[] = {
  79. [CCU_SYS_SATA_REF_RST] = CCU_RST_TRIG(CCU_SYS_SATA_REF_BASE, 1),
  80. [CCU_SYS_APB_RST] = CCU_RST_TRIG(CCU_SYS_APB_BASE, 1),
  81. [CCU_SYS_DDR_FULL_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 1),
  82. [CCU_SYS_DDR_INIT_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 2),
  83. [CCU_SYS_PCIE_PCS_PHY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 0),
  84. [CCU_SYS_PCIE_PIPE0_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 4),
  85. [CCU_SYS_PCIE_CORE_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 8),
  86. [CCU_SYS_PCIE_PWR_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 9),
  87. [CCU_SYS_PCIE_STICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 10),
  88. [CCU_SYS_PCIE_NSTICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 11),
  89. [CCU_SYS_PCIE_HOT_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 12),
  90. };
  91. static int ccu_rst_reset(struct reset_controller_dev *rcdev, unsigned long idx)
  92. {
  93. struct ccu_rst *rst = to_ccu_rst(rcdev);
  94. const struct ccu_rst_info *info = &rst->rsts_info[idx];
  95. if (info->type != CCU_RST_TRIG)
  96. return -EOPNOTSUPP;
  97. regmap_update_bits(rst->sys_regs, info->base, info->mask, info->mask);
  98. /* The next delay must be enough to cover all the resets. */
  99. udelay(CCU_RST_DELAY_US);
  100. return 0;
  101. }
  102. static int ccu_rst_set(struct reset_controller_dev *rcdev,
  103. unsigned long idx, bool high)
  104. {
  105. struct ccu_rst *rst = to_ccu_rst(rcdev);
  106. const struct ccu_rst_info *info = &rst->rsts_info[idx];
  107. if (info->type != CCU_RST_DIR)
  108. return high ? -EOPNOTSUPP : 0;
  109. return regmap_update_bits(rst->sys_regs, info->base,
  110. info->mask, high ? info->mask : 0);
  111. }
  112. static int ccu_rst_assert(struct reset_controller_dev *rcdev,
  113. unsigned long idx)
  114. {
  115. return ccu_rst_set(rcdev, idx, true);
  116. }
  117. static int ccu_rst_deassert(struct reset_controller_dev *rcdev,
  118. unsigned long idx)
  119. {
  120. return ccu_rst_set(rcdev, idx, false);
  121. }
  122. static int ccu_rst_status(struct reset_controller_dev *rcdev,
  123. unsigned long idx)
  124. {
  125. struct ccu_rst *rst = to_ccu_rst(rcdev);
  126. const struct ccu_rst_info *info = &rst->rsts_info[idx];
  127. u32 val;
  128. if (info->type != CCU_RST_DIR)
  129. return -EOPNOTSUPP;
  130. regmap_read(rst->sys_regs, info->base, &val);
  131. return !!(val & info->mask);
  132. }
  133. static const struct reset_control_ops ccu_rst_ops = {
  134. .reset = ccu_rst_reset,
  135. .assert = ccu_rst_assert,
  136. .deassert = ccu_rst_deassert,
  137. .status = ccu_rst_status,
  138. };
  139. struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init)
  140. {
  141. struct ccu_rst *rst;
  142. int ret;
  143. if (!rst_init)
  144. return ERR_PTR(-EINVAL);
  145. rst = kzalloc(sizeof(*rst), GFP_KERNEL);
  146. if (!rst)
  147. return ERR_PTR(-ENOMEM);
  148. rst->sys_regs = rst_init->sys_regs;
  149. if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-axi")) {
  150. rst->rcdev.nr_resets = ARRAY_SIZE(axi_rst_info);
  151. rst->rsts_info = axi_rst_info;
  152. } else if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-sys")) {
  153. rst->rcdev.nr_resets = ARRAY_SIZE(sys_rst_info);
  154. rst->rsts_info = sys_rst_info;
  155. } else {
  156. pr_err("Incompatible DT node '%s' specified\n",
  157. of_node_full_name(rst_init->np));
  158. ret = -EINVAL;
  159. goto err_kfree_rst;
  160. }
  161. rst->rcdev.owner = THIS_MODULE;
  162. rst->rcdev.ops = &ccu_rst_ops;
  163. rst->rcdev.of_node = rst_init->np;
  164. ret = reset_controller_register(&rst->rcdev);
  165. if (ret) {
  166. pr_err("Couldn't register '%s' reset controller\n",
  167. of_node_full_name(rst_init->np));
  168. goto err_kfree_rst;
  169. }
  170. return rst;
  171. err_kfree_rst:
  172. kfree(rst);
  173. return ERR_PTR(ret);
  174. }
  175. void ccu_rst_hw_unregister(struct ccu_rst *rst)
  176. {
  177. reset_controller_unregister(&rst->rcdev);
  178. kfree(rst);
  179. }