ipa_reg.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
  3. * Copyright (C) 2019-2024 Linaro Ltd.
  4. */
  5. #include <linux/io.h>
  6. #include <linux/platform_device.h>
  7. #include "ipa.h"
  8. #include "ipa_reg.h"
  9. /* Is this register ID valid for the current IPA version? */
  10. static bool ipa_reg_id_valid(struct ipa *ipa, enum ipa_reg_id reg_id)
  11. {
  12. enum ipa_version version = ipa->version;
  13. switch (reg_id) {
  14. case FILT_ROUT_HASH_EN:
  15. return version == IPA_VERSION_4_2;
  16. case FILT_ROUT_HASH_FLUSH:
  17. return version < IPA_VERSION_5_0 && version != IPA_VERSION_4_2;
  18. case FILT_ROUT_CACHE_FLUSH:
  19. case ENDP_FILTER_CACHE_CFG:
  20. case ENDP_ROUTER_CACHE_CFG:
  21. return version >= IPA_VERSION_5_0;
  22. case IPA_BCR:
  23. case COUNTER_CFG:
  24. return version < IPA_VERSION_4_5;
  25. case IPA_TX_CFG:
  26. case FLAVOR_0:
  27. case IDLE_INDICATION_CFG:
  28. return version >= IPA_VERSION_3_5;
  29. case QTIME_TIMESTAMP_CFG:
  30. case TIMERS_XO_CLK_DIV_CFG:
  31. case TIMERS_PULSE_GRAN_CFG:
  32. return version >= IPA_VERSION_4_5;
  33. case SRC_RSRC_GRP_45_RSRC_TYPE:
  34. case DST_RSRC_GRP_45_RSRC_TYPE:
  35. return version <= IPA_VERSION_3_1 ||
  36. version == IPA_VERSION_4_5 ||
  37. version >= IPA_VERSION_5_0;
  38. case SRC_RSRC_GRP_67_RSRC_TYPE:
  39. case DST_RSRC_GRP_67_RSRC_TYPE:
  40. return version <= IPA_VERSION_3_1 ||
  41. version >= IPA_VERSION_5_0;
  42. case ENDP_FILTER_ROUTER_HSH_CFG:
  43. return version < IPA_VERSION_5_0 &&
  44. version != IPA_VERSION_4_2;
  45. case IRQ_SUSPEND_EN:
  46. case IRQ_SUSPEND_CLR:
  47. return version >= IPA_VERSION_3_1;
  48. case COMP_CFG:
  49. case CLKON_CFG:
  50. case ROUTE:
  51. case SHARED_MEM_SIZE:
  52. case QSB_MAX_WRITES:
  53. case QSB_MAX_READS:
  54. case STATE_AGGR_ACTIVE:
  55. case LOCAL_PKT_PROC_CNTXT:
  56. case AGGR_FORCE_CLOSE:
  57. case SRC_RSRC_GRP_01_RSRC_TYPE:
  58. case SRC_RSRC_GRP_23_RSRC_TYPE:
  59. case DST_RSRC_GRP_01_RSRC_TYPE:
  60. case DST_RSRC_GRP_23_RSRC_TYPE:
  61. case ENDP_INIT_CTRL:
  62. case ENDP_INIT_CFG:
  63. case ENDP_INIT_NAT:
  64. case ENDP_INIT_HDR:
  65. case ENDP_INIT_HDR_EXT:
  66. case ENDP_INIT_HDR_METADATA_MASK:
  67. case ENDP_INIT_MODE:
  68. case ENDP_INIT_AGGR:
  69. case ENDP_INIT_HOL_BLOCK_EN:
  70. case ENDP_INIT_HOL_BLOCK_TIMER:
  71. case ENDP_INIT_DEAGGR:
  72. case ENDP_INIT_RSRC_GRP:
  73. case ENDP_INIT_SEQ:
  74. case ENDP_STATUS:
  75. case IPA_IRQ_STTS:
  76. case IPA_IRQ_EN:
  77. case IPA_IRQ_CLR:
  78. case IPA_IRQ_UC:
  79. case IRQ_SUSPEND_INFO:
  80. return true; /* These should be defined for all versions */
  81. default:
  82. return false;
  83. }
  84. }
  85. const struct reg *ipa_reg(struct ipa *ipa, enum ipa_reg_id reg_id)
  86. {
  87. if (WARN(!ipa_reg_id_valid(ipa, reg_id), "invalid reg %u\n", reg_id))
  88. return NULL;
  89. return reg(ipa->regs, reg_id);
  90. }
  91. static const struct regs *ipa_regs(enum ipa_version version)
  92. {
  93. switch (version) {
  94. case IPA_VERSION_3_1:
  95. return &ipa_regs_v3_1;
  96. case IPA_VERSION_3_5_1:
  97. return &ipa_regs_v3_5_1;
  98. case IPA_VERSION_4_2:
  99. return &ipa_regs_v4_2;
  100. case IPA_VERSION_4_5:
  101. return &ipa_regs_v4_5;
  102. case IPA_VERSION_4_7:
  103. return &ipa_regs_v4_7;
  104. case IPA_VERSION_4_9:
  105. return &ipa_regs_v4_9;
  106. case IPA_VERSION_4_11:
  107. return &ipa_regs_v4_11;
  108. case IPA_VERSION_5_0:
  109. return &ipa_regs_v5_0;
  110. case IPA_VERSION_5_5:
  111. return &ipa_regs_v5_5;
  112. default:
  113. return NULL;
  114. }
  115. }
  116. int ipa_reg_init(struct ipa *ipa, struct platform_device *pdev)
  117. {
  118. struct device *dev = &pdev->dev;
  119. const struct regs *regs;
  120. struct resource *res;
  121. regs = ipa_regs(ipa->version);
  122. if (!regs)
  123. return -EINVAL;
  124. if (WARN_ON(regs->reg_count > IPA_REG_ID_COUNT))
  125. return -EINVAL;
  126. /* Setup IPA register memory */
  127. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipa-reg");
  128. if (!res) {
  129. dev_err(dev, "DT error getting \"ipa-reg\" memory property\n");
  130. return -ENODEV;
  131. }
  132. ipa->reg_virt = ioremap(res->start, resource_size(res));
  133. if (!ipa->reg_virt) {
  134. dev_err(dev, "unable to remap \"ipa-reg\" memory\n");
  135. return -ENOMEM;
  136. }
  137. ipa->regs = regs;
  138. return 0;
  139. }
  140. void ipa_reg_exit(struct ipa *ipa)
  141. {
  142. iounmap(ipa->reg_virt);
  143. }