gsi_reg.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (C) 2023-2024 Linaro Ltd. */
  3. #include <linux/io.h>
  4. #include <linux/platform_device.h>
  5. #include "gsi.h"
  6. #include "gsi_reg.h"
  7. #include "reg.h"
  8. /* Is this register ID valid for the current GSI version? */
  9. static bool gsi_reg_id_valid(struct gsi *gsi, enum gsi_reg_id reg_id)
  10. {
  11. switch (reg_id) {
  12. case INTER_EE_SRC_CH_IRQ_MSK:
  13. case INTER_EE_SRC_EV_CH_IRQ_MSK:
  14. return gsi->version >= IPA_VERSION_3_5;
  15. case HW_PARAM_2:
  16. return gsi->version >= IPA_VERSION_3_5_1;
  17. case HW_PARAM_4:
  18. return gsi->version >= IPA_VERSION_5_0;
  19. case CH_C_CNTXT_0:
  20. case CH_C_CNTXT_1:
  21. case CH_C_CNTXT_2:
  22. case CH_C_CNTXT_3:
  23. case CH_C_QOS:
  24. case CH_C_SCRATCH_0:
  25. case CH_C_SCRATCH_1:
  26. case CH_C_SCRATCH_2:
  27. case CH_C_SCRATCH_3:
  28. case EV_CH_E_CNTXT_0:
  29. case EV_CH_E_CNTXT_1:
  30. case EV_CH_E_CNTXT_2:
  31. case EV_CH_E_CNTXT_3:
  32. case EV_CH_E_CNTXT_4:
  33. case EV_CH_E_CNTXT_8:
  34. case EV_CH_E_CNTXT_9:
  35. case EV_CH_E_CNTXT_10:
  36. case EV_CH_E_CNTXT_11:
  37. case EV_CH_E_CNTXT_12:
  38. case EV_CH_E_CNTXT_13:
  39. case EV_CH_E_SCRATCH_0:
  40. case EV_CH_E_SCRATCH_1:
  41. case CH_C_DOORBELL_0:
  42. case EV_CH_E_DOORBELL_0:
  43. case GSI_STATUS:
  44. case CH_CMD:
  45. case EV_CH_CMD:
  46. case GENERIC_CMD:
  47. case CNTXT_TYPE_IRQ:
  48. case CNTXT_TYPE_IRQ_MSK:
  49. case CNTXT_SRC_CH_IRQ:
  50. case CNTXT_SRC_CH_IRQ_MSK:
  51. case CNTXT_SRC_CH_IRQ_CLR:
  52. case CNTXT_SRC_EV_CH_IRQ:
  53. case CNTXT_SRC_EV_CH_IRQ_MSK:
  54. case CNTXT_SRC_EV_CH_IRQ_CLR:
  55. case CNTXT_SRC_IEOB_IRQ:
  56. case CNTXT_SRC_IEOB_IRQ_MSK:
  57. case CNTXT_SRC_IEOB_IRQ_CLR:
  58. case CNTXT_GLOB_IRQ_STTS:
  59. case CNTXT_GLOB_IRQ_EN:
  60. case CNTXT_GLOB_IRQ_CLR:
  61. case CNTXT_GSI_IRQ_STTS:
  62. case CNTXT_GSI_IRQ_EN:
  63. case CNTXT_GSI_IRQ_CLR:
  64. case CNTXT_INTSET:
  65. case ERROR_LOG:
  66. case ERROR_LOG_CLR:
  67. case CNTXT_SCRATCH_0:
  68. return true;
  69. default:
  70. return false;
  71. }
  72. }
  73. const struct reg *gsi_reg(struct gsi *gsi, enum gsi_reg_id reg_id)
  74. {
  75. if (WARN(!gsi_reg_id_valid(gsi, reg_id), "invalid reg %u\n", reg_id))
  76. return NULL;
  77. return reg(gsi->regs, reg_id);
  78. }
  79. static const struct regs *gsi_regs(struct gsi *gsi)
  80. {
  81. switch (gsi->version) {
  82. case IPA_VERSION_3_1:
  83. return &gsi_regs_v3_1;
  84. case IPA_VERSION_3_5_1:
  85. return &gsi_regs_v3_5_1;
  86. case IPA_VERSION_4_2:
  87. return &gsi_regs_v4_0;
  88. case IPA_VERSION_4_5:
  89. case IPA_VERSION_4_7:
  90. return &gsi_regs_v4_5;
  91. case IPA_VERSION_4_9:
  92. return &gsi_regs_v4_9;
  93. case IPA_VERSION_4_11:
  94. return &gsi_regs_v4_11;
  95. case IPA_VERSION_5_0:
  96. case IPA_VERSION_5_5:
  97. return &gsi_regs_v5_0;
  98. default:
  99. return NULL;
  100. }
  101. }
  102. /* Sets gsi->virt and I/O maps the "gsi" memory range for registers */
  103. int gsi_reg_init(struct gsi *gsi, struct platform_device *pdev)
  104. {
  105. struct device *dev = &pdev->dev;
  106. struct resource *res;
  107. resource_size_t size;
  108. /* Get GSI memory range and map it */
  109. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsi");
  110. if (!res) {
  111. dev_err(dev, "DT error getting \"gsi\" memory property\n");
  112. return -ENODEV;
  113. }
  114. size = resource_size(res);
  115. if (res->start > U32_MAX || size > U32_MAX - res->start) {
  116. dev_err(dev, "DT memory resource \"gsi\" out of range\n");
  117. return -EINVAL;
  118. }
  119. gsi->regs = gsi_regs(gsi);
  120. if (!gsi->regs) {
  121. dev_err(dev, "unsupported IPA version %u (?)\n", gsi->version);
  122. return -EINVAL;
  123. }
  124. gsi->virt = ioremap(res->start, size);
  125. if (!gsi->virt) {
  126. dev_err(dev, "unable to remap \"gsi\" memory\n");
  127. return -ENOMEM;
  128. }
  129. return 0;
  130. }
  131. /* Inverse of gsi_reg_init() */
  132. void gsi_reg_exit(struct gsi *gsi)
  133. {
  134. iounmap(gsi->virt);
  135. gsi->virt = NULL;
  136. gsi->regs = NULL;
  137. }