msm_vidc_variant.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/errno.h>
  7. #include <linux/iopoll.h>
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_driver.h"
  10. #include "msm_vidc_state.h"
  11. #include "msm_vidc_debug.h"
  12. #include "msm_vidc_variant.h"
  13. #include "msm_vidc_platform.h"
  14. static void __fatal_error(bool fatal)
  15. {
  16. WARN_ON(fatal);
  17. }
  18. static int __strict_check(struct msm_vidc_core *core, const char *function)
  19. {
  20. bool fatal = !mutex_is_locked(&core->lock);
  21. __fatal_error(fatal);
  22. if (fatal)
  23. d_vpr_e("%s: strict check failed\n", function);
  24. return fatal ? -EINVAL : 0;
  25. }
  26. int __write_register(struct msm_vidc_core *core, u32 reg, u32 value)
  27. {
  28. u32 hwiosymaddr = reg;
  29. u8 *base_addr;
  30. int rc = 0;
  31. if (!core || !core->resource) {
  32. d_vpr_e("%s: invalid params\n", __func__);
  33. return -EINVAL;
  34. }
  35. rc = __strict_check(core, __func__);
  36. if (rc)
  37. return rc;
  38. if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
  39. d_vpr_e("HFI Write register failed : Power is OFF\n");
  40. return -EINVAL;
  41. }
  42. base_addr = core->resource->register_base_addr;
  43. d_vpr_l("regwrite(%pK + %#x) = %#x\n", base_addr, hwiosymaddr, value);
  44. base_addr += hwiosymaddr;
  45. writel_relaxed(value, base_addr);
  46. /*
  47. * Memory barrier to make sure value is written into the register.
  48. */
  49. wmb();
  50. return rc;
  51. }
  52. /*
  53. * Argument mask is used to specify which bits to update. In case mask is 0x11,
  54. * only bits 0 & 4 will be updated with corresponding bits from value. To update
  55. * entire register with value, set mask = 0xFFFFFFFF.
  56. */
  57. int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value,
  58. u32 mask)
  59. {
  60. u32 prev_val, new_val;
  61. u8 *base_addr;
  62. int rc = 0;
  63. if (!core || !core->resource) {
  64. d_vpr_e("%s: invalid params\n", __func__);
  65. return -EINVAL;
  66. }
  67. rc = __strict_check(core, __func__);
  68. if (rc)
  69. return rc;
  70. if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
  71. d_vpr_e("%s: register write failed, power is off\n",
  72. __func__);
  73. return -EINVAL;
  74. }
  75. base_addr = core->resource->register_base_addr;
  76. base_addr += reg;
  77. prev_val = readl_relaxed(base_addr);
  78. /*
  79. * Memory barrier to ensure register read is correct
  80. */
  81. rmb();
  82. new_val = (prev_val & ~mask) | (value & mask);
  83. d_vpr_l(
  84. "Base addr: %pK, writing to: %#x, previous-value: %#x, value: %#x, mask: %#x, new-value: %#x...\n",
  85. base_addr, reg, prev_val, value, mask, new_val);
  86. writel_relaxed(new_val, base_addr);
  87. /*
  88. * Memory barrier to make sure value is written into the register.
  89. */
  90. wmb();
  91. return rc;
  92. }
  93. int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value)
  94. {
  95. int rc = 0;
  96. u8 *base_addr;
  97. if (!core || !core->resource || !value) {
  98. d_vpr_e("%s: invalid params\n", __func__);
  99. return -EINVAL;
  100. }
  101. if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
  102. d_vpr_e("HFI Read register failed : Power is OFF\n");
  103. return -EINVAL;
  104. }
  105. base_addr = core->resource->register_base_addr;
  106. *value = readl_relaxed(base_addr + reg);
  107. /*
  108. * Memory barrier to make sure value is read correctly from the
  109. * register.
  110. */
  111. rmb();
  112. d_vpr_l("regread(%pK + %#x) = %#x\n", base_addr, reg, *value);
  113. return rc;
  114. }
  115. int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
  116. u32 mask, u32 exp_val, u32 sleep_us,
  117. u32 timeout_us)
  118. {
  119. int rc = 0;
  120. u32 val = 0;
  121. u8 *addr;
  122. if (!core || !core->resource) {
  123. d_vpr_e("%s: invalid params\n", __func__);
  124. return -EINVAL;
  125. }
  126. if (!is_core_sub_state(core, CORE_SUBSTATE_POWER_ENABLE)) {
  127. d_vpr_e("%s failed: Power is OFF\n", __func__);
  128. return -EINVAL;
  129. }
  130. addr = (u8 *)core->resource->register_base_addr + reg;
  131. rc = readl_relaxed_poll_timeout(addr, val, ((val & mask) == exp_val), sleep_us, timeout_us);
  132. /*
  133. * Memory barrier to make sure value is read correctly from the
  134. * register.
  135. */
  136. rmb();
  137. d_vpr_l(
  138. "regread(%pK + %#x) = %#x. rc %d, mask %#x, exp_val %#x, cond %u, sleep %u, timeout %u\n",
  139. core->resource->register_base_addr, reg, val, rc, mask, exp_val,
  140. ((val & mask) == exp_val), sleep_us, timeout_us);
  141. return rc;
  142. }
  143. int __set_registers(struct msm_vidc_core *core)
  144. {
  145. const struct reg_preset_table *reg_prst;
  146. unsigned int prst_count;
  147. int cnt, rc = 0;
  148. if (!core || !core->platform) {
  149. d_vpr_e("core resources null, cannot set registers\n");
  150. return -EINVAL;
  151. }
  152. reg_prst = core->platform->data.reg_prst_tbl;
  153. prst_count = core->platform->data.reg_prst_tbl_size;
  154. /* skip if there is no preset reg available */
  155. if (!reg_prst || !prst_count)
  156. return 0;
  157. for (cnt = 0; cnt < prst_count; cnt++) {
  158. rc = __write_register_masked(core, reg_prst->reg,
  159. reg_prst->value, reg_prst->mask);
  160. if (rc)
  161. return rc;
  162. }
  163. return rc;
  164. }