reset-ipq4019.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2020 Sartura Ltd.
  4. *
  5. * Author: Robert Marko <robert.marko@sartura.hr>
  6. *
  7. * Based on Linux driver
  8. */
  9. #include <asm/io.h>
  10. #include <common.h>
  11. #include <dm.h>
  12. #include <dt-bindings/reset/qcom,ipq4019-reset.h>
  13. #include <reset-uclass.h>
  14. #include <linux/bitops.h>
  15. #include <malloc.h>
  16. struct ipq4019_reset_priv {
  17. phys_addr_t base;
  18. };
  19. struct qcom_reset_map {
  20. unsigned int reg;
  21. u8 bit;
  22. };
  23. static const struct qcom_reset_map gcc_ipq4019_resets[] = {
  24. [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
  25. [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
  26. [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
  27. [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
  28. [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
  29. [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
  30. [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
  31. [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
  32. [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
  33. [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
  34. [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
  35. [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
  36. [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
  37. [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
  38. [USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
  39. [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
  40. [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
  41. [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
  42. [PCIE_AHB_ARES] = { 0x1d010, 10 },
  43. [PCIE_PWR_ARES] = { 0x1d010, 9 },
  44. [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
  45. [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
  46. [PCIE_PHY_ARES] = { 0x1d010, 6 },
  47. [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
  48. [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
  49. [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
  50. [PCIE_PIPE_ARES] = { 0x1d010, 2 },
  51. [PCIE_AXI_S_ARES] = { 0x1d010, 1 },
  52. [PCIE_AXI_M_ARES] = { 0x1d010, 0 },
  53. [ESS_RESET] = { 0x12008, 0},
  54. [GCC_BLSP1_BCR] = {0x01000, 0},
  55. [GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
  56. [GCC_BLSP1_UART1_BCR] = {0x02038, 0},
  57. [GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
  58. [GCC_BLSP1_UART2_BCR] = {0x03028, 0},
  59. [GCC_BIMC_BCR] = {0x04000, 0},
  60. [GCC_TLMM_BCR] = {0x05000, 0},
  61. [GCC_IMEM_BCR] = {0x0E000, 0},
  62. [GCC_ESS_BCR] = {0x12008, 0},
  63. [GCC_PRNG_BCR] = {0x13000, 0},
  64. [GCC_BOOT_ROM_BCR] = {0x13008, 0},
  65. [GCC_CRYPTO_BCR] = {0x16000, 0},
  66. [GCC_SDCC1_BCR] = {0x18000, 0},
  67. [GCC_SEC_CTRL_BCR] = {0x1A000, 0},
  68. [GCC_AUDIO_BCR] = {0x1B008, 0},
  69. [GCC_QPIC_BCR] = {0x1C000, 0},
  70. [GCC_PCIE_BCR] = {0x1D000, 0},
  71. [GCC_USB2_BCR] = {0x1E008, 0},
  72. [GCC_USB2_PHY_BCR] = {0x1E018, 0},
  73. [GCC_USB3_BCR] = {0x1E024, 0},
  74. [GCC_USB3_PHY_BCR] = {0x1E034, 0},
  75. [GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
  76. [GCC_PCNOC_BCR] = {0x2102C, 0},
  77. [GCC_DCD_BCR] = {0x21038, 0},
  78. [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
  79. [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
  80. [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
  81. [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
  82. [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
  83. [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
  84. [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
  85. [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
  86. [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
  87. [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
  88. [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
  89. [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
  90. [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
  91. [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
  92. [GCC_TCSR_BCR] = {0x22000, 0},
  93. [GCC_MPM_BCR] = {0x24000, 0},
  94. [GCC_SPDM_BCR] = {0x25000, 0},
  95. };
  96. static int ipq4019_reset_assert(struct reset_ctl *rst)
  97. {
  98. struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
  99. const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
  100. const struct qcom_reset_map *map;
  101. u32 value;
  102. map = &reset_map[rst->id];
  103. value = readl(priv->base + map->reg);
  104. value |= BIT(map->bit);
  105. writel(value, priv->base + map->reg);
  106. return 0;
  107. }
  108. static int ipq4019_reset_deassert(struct reset_ctl *rst)
  109. {
  110. struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev);
  111. const struct qcom_reset_map *reset_map = gcc_ipq4019_resets;
  112. const struct qcom_reset_map *map;
  113. u32 value;
  114. map = &reset_map[rst->id];
  115. value = readl(priv->base + map->reg);
  116. value &= ~BIT(map->bit);
  117. writel(value, priv->base + map->reg);
  118. return 0;
  119. }
  120. static int ipq4019_reset_free(struct reset_ctl *rst)
  121. {
  122. return 0;
  123. }
  124. static int ipq4019_reset_request(struct reset_ctl *rst)
  125. {
  126. return 0;
  127. }
  128. static const struct reset_ops ipq4019_reset_ops = {
  129. .request = ipq4019_reset_request,
  130. .rfree = ipq4019_reset_free,
  131. .rst_assert = ipq4019_reset_assert,
  132. .rst_deassert = ipq4019_reset_deassert,
  133. };
  134. static const struct udevice_id ipq4019_reset_ids[] = {
  135. { .compatible = "qcom,gcc-reset-ipq4019" },
  136. { }
  137. };
  138. static int ipq4019_reset_probe(struct udevice *dev)
  139. {
  140. struct ipq4019_reset_priv *priv = dev_get_priv(dev);
  141. priv->base = dev_read_addr(dev);
  142. if (priv->base == FDT_ADDR_T_NONE)
  143. return -EINVAL;
  144. return 0;
  145. }
  146. U_BOOT_DRIVER(ipq4019_reset) = {
  147. .name = "ipq4019_reset",
  148. .id = UCLASS_RESET,
  149. .of_match = ipq4019_reset_ids,
  150. .ops = &ipq4019_reset_ops,
  151. .probe = ipq4019_reset_probe,
  152. .priv_auto = sizeof(struct ipq4019_reset_priv),
  153. };