mp_dev.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include "hif_io32.h"
  19. #include "hif_debug.h"
  20. #include "mp_dev.h"
  21. /*chaninfo*/
  22. #define CHANINFOMEM_S2_READ_MASK 0x00000008
  23. #define CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK 0x00000001
  24. #define CHANINFO_CTRL_CHANINFOMEM_BW_MASK 0x00000030
  25. #define MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK 0x00000007
  26. /*agc*/
  27. #define GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK 0x00040000
  28. #define GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK 0x00080000
  29. #define GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK 0x00100000
  30. #define GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK 0x00200000
  31. #define AGC_HISTORY_DUMP_MASK (\
  32. GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK| \
  33. GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK| \
  34. GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK| \
  35. GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK \
  36. )
  37. #define BB_chaninfo_ctrl 0x1a370
  38. #define BB_multichain_enable 0x1a2a0
  39. #define BB_chn_tables_intf_addr 0x19894
  40. #define BB_chn1_tables_intf_addr 0x1a894
  41. #define BB_chn_tables_intf_data 0x19898
  42. #define BB_chn1_tables_intf_data 0x1a898
  43. #define BB_gains_min_offsets 0x19e08
  44. #define BB_chaninfo_tab_b0 0x03200
  45. #define BB_chaninfo_tab_b1 0x03300
  46. #define BB_watchdog_status 0x1a7c0
  47. #define BB_watchdog_ctrl_1 0x1a7c4
  48. #define BB_watchdog_ctrl_2 0x1a7c8
  49. #define BB_watchdog_status_B 0x1a7e0
  50. #define PHY_BB_CHN_TABLES_INTF_ADDR 0x19894
  51. #define PHY_BB_CHN_TABLES_INTF_DATA 0x19898
  52. #define PHY_BB_CHN1_TABLES_INTF_ADDR 0x1a894
  53. #define PHY_BB_CHN1_TABLES_INTF_DATA 0x1a898
  54. struct priv_ctrl_ctx {
  55. uint32_t chaninfo_ctrl_orig;
  56. uint32_t gain_min_offsets_orig;
  57. uint32_t anyreg_start;
  58. uint32_t anyreg_len;
  59. };
  60. static struct priv_ctrl_ctx g_priv_dump_ctx;
  61. static inline void set_target_reg_bits(struct hif_softc *scn,
  62. void __iomem *mem, uint32_t reg,
  63. uint32_t bitmask, uint32_t val)
  64. {
  65. uint32_t value = hif_read32_mb(scn, mem + (reg));
  66. uint32_t shift = 0;
  67. value &= ~(bitmask);
  68. while (!((bitmask >> shift) & 0x01))
  69. shift++;
  70. value |= (((val) << shift) & (bitmask));
  71. hif_write32_mb(scn, mem + (reg), value);
  72. }
  73. static inline uint32_t get_target_reg_bits(struct hif_softc *scn,
  74. void __iomem *mem,
  75. uint32_t reg, uint32_t bitmask)
  76. {
  77. uint32_t value = hif_read32_mb(scn, mem + (reg));
  78. uint32_t shift = 0;
  79. while (!((bitmask >> shift) & 0x01))
  80. shift++;
  81. return (value >> shift) & bitmask;
  82. }
  83. void priv_start_cap_chaninfo(struct hif_softc *scn)
  84. {
  85. set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
  86. CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK, 1);
  87. }
  88. void priv_start_agc(struct hif_softc *scn)
  89. {
  90. g_priv_dump_ctx.gain_min_offsets_orig =
  91. hif_read32_mb(scn, scn->mem + BB_gains_min_offsets);
  92. set_target_reg_bits(scn, scn->mem, BB_gains_min_offsets,
  93. AGC_HISTORY_DUMP_MASK,
  94. 0x0f);
  95. }
  96. static void priv_stop_agc(struct hif_softc *scn)
  97. {
  98. set_target_reg_bits(scn, scn->mem, BB_gains_min_offsets,
  99. AGC_HISTORY_DUMP_MASK,
  100. 0);
  101. }
  102. void priv_dump_chaninfo(struct hif_softc *scn)
  103. {
  104. uint32_t bw, val;
  105. uint32_t len, i, tmp;
  106. uint32_t chain_mask;
  107. uint32_t chain0, chain1;
  108. chain_mask =
  109. get_target_reg_bits(scn, scn->mem, BB_multichain_enable,
  110. MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
  111. chain0 = chain_mask & 1;
  112. chain1 = chain_mask & 2;
  113. HIF_TRACE("%s: E", __func__);
  114. bw = get_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
  115. CHANINFO_CTRL_CHANINFOMEM_BW_MASK);
  116. if (bw == 0)
  117. len = 53;
  118. else if (bw == 1)
  119. len = 57;
  120. else if (bw == 2)
  121. len = 59 * 2 - 1;
  122. else
  123. len = 60 * 2 + 61 * 2;
  124. /*
  125. * each tone is 16 bit valid, write to 32bit buffer each.
  126. * bw==0(legacy20): 53 tones.
  127. * bw==1(ht/vht20): 57 tones.
  128. * bw==2(ht/vht40): 59+58 tones.
  129. * bw==3(vht80): 60*2+61*2 tones.
  130. */
  131. if (chain0) {
  132. hif_write32_mb(scn, scn->mem + BB_chn_tables_intf_addr,
  133. 0x80003200);
  134. }
  135. if (chain1) {
  136. hif_write32_mb(scn, scn->mem + BB_chn1_tables_intf_addr,
  137. 0x80003200);
  138. }
  139. set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
  140. CHANINFOMEM_S2_READ_MASK, 0);
  141. if (chain0) {
  142. if (bw < 2) {
  143. len = (bw == 0) ? 53 : 57;
  144. for (i = 0; i < len; i++) {
  145. val = hif_read32_mb(scn, scn->mem +
  146. BB_chn_tables_intf_data) &
  147. 0x0000ffff;
  148. qdf_debug("0x%x\t", val);
  149. if (i % 4 == 0)
  150. qdf_debug("\n");
  151. }
  152. } else {
  153. len = (bw == 2) ? 59 : 60;
  154. for (i = 0; i < len; i++) {
  155. tmp = hif_read32_mb(scn, scn->mem +
  156. BB_chn_tables_intf_data);
  157. qdf_debug("0x%x\t", ((tmp >> 16) & 0x0000ffff));
  158. qdf_debug("0x%x\t", (tmp & 0x0000ffff));
  159. if (i % 2 == 0)
  160. qdf_debug("\n");
  161. }
  162. if (bw > 2) {
  163. /* bw == 3 for vht80 */
  164. hif_write32_mb(scn, scn->mem +
  165. BB_chn_tables_intf_addr,
  166. 0x80003300);
  167. len = 61;
  168. for (i = 0; i < len; i++) {
  169. tmp = hif_read32_mb(scn, scn->mem +
  170. BB_chn_tables_intf_data);
  171. qdf_debug("0x%x\t",
  172. ((tmp >> 16) & 0x0000ffff));
  173. qdf_debug("0x%x\t", (tmp & 0x0000ffff));
  174. if (i % 2 == 0)
  175. qdf_debug("\n");
  176. }
  177. }
  178. }
  179. }
  180. if (chain1) {
  181. if (bw < 2) {
  182. len = (bw == 0) ? 53 : 57;
  183. for (i = 0; i < len; i++) {
  184. val =
  185. hif_read32_mb(scn, scn->mem +
  186. BB_chn1_tables_intf_data) &
  187. 0x0000ffff;
  188. qdf_debug("0x%x\t", val);
  189. if (i % 4 == 0)
  190. qdf_debug("\n");
  191. }
  192. } else {
  193. len = (bw == 2) ? 59 : 60;
  194. for (i = 0; i < len; i++) {
  195. tmp =
  196. hif_read32_mb(scn, scn->mem +
  197. BB_chn1_tables_intf_data);
  198. qdf_debug("0x%x", (tmp >> 16) & 0x0000ffff);
  199. qdf_debug("0x%x", tmp & 0x0000ffff);
  200. if (i % 2 == 0)
  201. qdf_debug("\n");
  202. }
  203. if (bw > 2) {
  204. /* bw == 3 for vht80 */
  205. hif_write32_mb(scn, scn->mem +
  206. BB_chn1_tables_intf_addr,
  207. 0x80003300);
  208. len = 61;
  209. for (i = 0; i < len; i++) {
  210. tmp =
  211. hif_read32_mb(scn, scn->mem +
  212. BB_chn1_tables_intf_data);
  213. qdf_debug("0x%x\t",
  214. ((tmp >> 16) & 0x0000ffff));
  215. qdf_debug("0x%x\t", (tmp & 0x0000ffff));
  216. if (i % 2 == 0)
  217. qdf_debug("\n");
  218. }
  219. }
  220. }
  221. }
  222. HIF_TRACE("%s: X", __func__);
  223. }
  224. void priv_dump_agc(struct hif_softc *scn)
  225. {
  226. int i, len = 30; /* check this value for Rome and Peregrine */
  227. uint32_t chain0, chain1, chain_mask, val;
  228. if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
  229. return;
  230. chain_mask =
  231. get_target_reg_bits(scn, scn->mem, BB_multichain_enable,
  232. MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
  233. chain0 = chain_mask & 1;
  234. chain1 = chain_mask & 2;
  235. len = len << 1; /* each agc item is 64bit, total*2 */
  236. priv_stop_agc(scn);
  237. set_target_reg_bits(scn, scn->mem, BB_chaninfo_ctrl,
  238. CHANINFOMEM_S2_READ_MASK, 0);
  239. HIF_TRACE("%s: AGC history buffer dump: E", __func__);
  240. if (chain0) {
  241. for (i = 0; i < len; i++) {
  242. hif_write32_mb(scn, scn->mem +
  243. PHY_BB_CHN_TABLES_INTF_ADDR,
  244. BB_chaninfo_tab_b0 + i * 4);
  245. val = hif_read32_mb(scn, scn->mem +
  246. PHY_BB_CHN_TABLES_INTF_DATA);
  247. qdf_debug("0x%x\t", val);
  248. if (i % 4 == 0)
  249. qdf_debug("\n");
  250. }
  251. }
  252. if (chain1) {
  253. for (i = 0; i < len; i++) {
  254. hif_write32_mb(scn, scn->mem +
  255. PHY_BB_CHN1_TABLES_INTF_ADDR,
  256. BB_chaninfo_tab_b0 + i * 4);
  257. val = hif_read32_mb(scn, scn->mem +
  258. PHY_BB_CHN1_TABLES_INTF_DATA);
  259. qdf_debug("0x%x\t", val);
  260. if (i % 4 == 0)
  261. qdf_debug("\n");
  262. }
  263. }
  264. HIF_TRACE("%s: AGC history buffer dump X", __func__);
  265. /* restore original value */
  266. hif_write32_mb(scn, scn->mem + BB_gains_min_offsets,
  267. g_priv_dump_ctx.gain_min_offsets_orig);
  268. Q_TARGET_ACCESS_END(scn);
  269. }
  270. void priv_dump_bbwatchdog(struct hif_softc *scn)
  271. {
  272. uint32_t val;
  273. HIF_TRACE("%s: BB watchdog dump E", __func__);
  274. val = hif_read32_mb(scn, scn->mem + BB_watchdog_status);
  275. qdf_debug("0x%x\t", val);
  276. val = hif_read32_mb(scn, scn->mem + BB_watchdog_ctrl_1);
  277. qdf_debug("0x%x\t", val);
  278. val = hif_read32_mb(scn, scn->mem + BB_watchdog_ctrl_2);
  279. qdf_debug("0x%x\t", val);
  280. val = hif_read32_mb(scn, scn->mem + BB_watchdog_status_B);
  281. qdf_debug("0x%x", val);
  282. HIF_TRACE("%s: BB watchdog dump X", __func__);
  283. }