mp_dev.c 8.7 KB

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