123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- /*
- * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- /*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
- #include "hif_io32.h"
- #include "hif_debug.h"
- /*chaninfo*/
- #define CHANINFOMEM_S2_READ_MASK 0x00000008
- #define CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK 0x00000001
- #define CHANINFO_CTRL_CHANINFOMEM_BW_MASK 0x00000030
- #define MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK 0x00000007
- /*agc*/
- #define GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK 0x00040000
- #define GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK 0x00080000
- #define GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK 0x00100000
- #define GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK 0x00200000
- #define AGC_HISTORY_DUMP_MASK (\
- GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK| \
- GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK| \
- GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK| \
- GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK \
- )
- #define BB_chaninfo_ctrl 0x1a370
- #define BB_multichain_enable 0x1a2a0
- #define BB_chn_tables_intf_addr 0x19894
- #define BB_chn1_tables_intf_addr 0x1a894
- #define BB_chn_tables_intf_data 0x19898
- #define BB_chn1_tables_intf_data 0x1a898
- #define BB_gains_min_offsets 0x19e08
- #define BB_chaninfo_tab_b0 0x03200
- #define BB_chaninfo_tab_b1 0x03300
- #define BB_watchdog_status 0x1a7c0
- #define BB_watchdog_ctrl_1 0x1a7c4
- #define BB_watchdog_ctrl_2 0x1a7c8
- #define BB_watchdog_status_B 0x1a7e0
- #define PHY_BB_CHN_TABLES_INTF_ADDR 0x19894
- #define PHY_BB_CHN_TABLES_INTF_DATA 0x19898
- #define PHY_BB_CHN1_TABLES_INTF_ADDR 0x1a894
- #define PHY_BB_CHN1_TABLES_INTF_DATA 0x1a898
- struct priv_ctrl_ctx {
- uint32_t chaninfo_ctrl_orig;
- uint32_t gain_min_offsets_orig;
- uint32_t anyreg_start;
- uint32_t anyreg_len;
- };
- static struct priv_ctrl_ctx g_priv_dump_ctx;
- static inline void set_target_reg_bits(void __iomem *mem, uint32_t reg,
- uint32_t bitmask, uint32_t val)
- {
- uint32_t value = hif_read32_mb(mem + (reg));
- uint32_t shift = 0;
- value &= ~(bitmask);
- while (!((bitmask >> shift) & 0x01))
- shift++;
- value |= (((val) << shift) & (bitmask));
- hif_write32_mb(mem + (reg), value);
- }
- static inline uint32_t get_target_reg_bits(void __iomem *mem,
- uint32_t reg, uint32_t bitmask)
- {
- uint32_t value = hif_read32_mb(mem + (reg));
- uint32_t shift = 0;
- while (!((bitmask >> shift) & 0x01))
- shift++;
- return (value >> shift) & bitmask;
- }
- void priv_start_cap_chaninfo(struct hif_softc *scn)
- {
- set_target_reg_bits(scn->mem, BB_chaninfo_ctrl,
- CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK, 1);
- }
- void priv_start_agc(struct hif_softc *scn)
- {
- g_priv_dump_ctx.gain_min_offsets_orig =
- hif_read32_mb(scn->mem + BB_gains_min_offsets);
- set_target_reg_bits(scn->mem, BB_gains_min_offsets,
- AGC_HISTORY_DUMP_MASK,
- 0x0f);
- }
- void priv_stop_agc(struct hif_softc *scn)
- {
- set_target_reg_bits(scn->mem, BB_gains_min_offsets,
- AGC_HISTORY_DUMP_MASK,
- 0);
- }
- void priv_dump_chaninfo(struct hif_softc *scn)
- {
- uint32_t bw, val;
- uint32_t len, i, tmp;
- uint32_t chain_mask;
- uint32_t chain0, chain1;
- chain_mask =
- get_target_reg_bits(scn->mem, BB_multichain_enable,
- MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
- chain0 = chain_mask & 1;
- chain1 = chain_mask & 2;
- HIF_TRACE("%s: E", __func__);
- bw = get_target_reg_bits(scn->mem, BB_chaninfo_ctrl,
- CHANINFO_CTRL_CHANINFOMEM_BW_MASK);
- if (bw == 0)
- len = 53;
- else if (bw == 1)
- len = 57;
- else if (bw == 2)
- len = 59 * 2 - 1;
- else
- len = 60 * 2 + 61 * 2;
- /*
- * each tone is 16 bit valid, write to 32bit buffer each.
- * bw==0(legacy20): 53 tones.
- * bw==1(ht/vht20): 57 tones.
- * bw==2(ht/vht40): 59+58 tones.
- * bw==3(vht80): 60*2+61*2 tones.
- */
- if (chain0) {
- hif_write32_mb(scn->mem + BB_chn_tables_intf_addr,
- 0x80003200);
- }
- if (chain1) {
- hif_write32_mb(scn->mem + BB_chn1_tables_intf_addr,
- 0x80003200);
- }
- set_target_reg_bits(scn->mem, BB_chaninfo_ctrl,
- CHANINFOMEM_S2_READ_MASK, 0);
- if (chain0) {
- if (bw < 2) {
- len = (bw == 0) ? 53 : 57;
- for (i = 0; i < len; i++) {
- val =
- hif_read32_mb(scn->mem +
- BB_chn_tables_intf_data) &
- 0x0000ffff;
- qdf_print("0x%x\t", val);
- if (i % 4 == 0)
- qdf_print("\n");
- }
- } else {
- len = (bw == 2) ? 59 : 60;
- for (i = 0; i < len; i++) {
- tmp =
- hif_read32_mb(scn->mem +
- BB_chn_tables_intf_data);
- qdf_print("0x%x\t", ((tmp >> 16) & 0x0000ffff));
- qdf_print("0x%x\t", (tmp & 0x0000ffff));
- if (i % 2 == 0)
- qdf_print("\n");
- }
- if (bw > 2) {
- /* bw == 3 for vht80 */
- hif_write32_mb(scn->mem +
- BB_chn_tables_intf_addr,
- 0x80003300);
- len = 61;
- for (i = 0; i < len; i++) {
- tmp =
- hif_read32_mb(scn->mem +
- BB_chn_tables_intf_data);
- qdf_print("0x%x\t",
- ((tmp >> 16) & 0x0000ffff));
- qdf_print("0x%x\t", (tmp & 0x0000ffff));
- if (i % 2 == 0)
- qdf_print("\n");
- }
- }
- }
- }
- if (chain1) {
- if (bw < 2) {
- len = (bw == 0) ? 53 : 57;
- for (i = 0; i < len; i++) {
- val =
- hif_read32_mb(scn->mem +
- BB_chn1_tables_intf_data) &
- 0x0000ffff;
- qdf_print("0x%x\t", val);
- if (i % 4 == 0)
- qdf_print("\n");
- }
- } else {
- len = (bw == 2) ? 59 : 60;
- for (i = 0; i < len; i++) {
- tmp =
- hif_read32_mb(scn->mem +
- BB_chn1_tables_intf_data);
- qdf_print("0x%x\n", (tmp >> 16) & 0x0000ffff);
- qdf_print("0x%x\n", tmp & 0x0000ffff);
- if (i % 2 == 0)
- qdf_print("\n");
- }
- if (bw > 2) {
- /* bw == 3 for vht80 */
- hif_write32_mb(scn->mem +
- BB_chn1_tables_intf_addr,
- 0x80003300);
- len = 61;
- for (i = 0; i < len; i++) {
- tmp =
- hif_read32_mb(scn->mem +
- BB_chn1_tables_intf_data);
- qdf_print("0x%x\t",
- ((tmp >> 16) & 0x0000ffff));
- qdf_print("0x%x\t", (tmp & 0x0000ffff));
- if (i % 2 == 0)
- qdf_print("\n");
- }
- }
- }
- }
- HIF_TRACE("%s: X", __func__);
- }
- void priv_dump_agc(struct hif_softc *scn)
- {
- int i, len = 30; /* check this value for Rome and Peregrine */
- uint32_t chain0, chain1, chain_mask, val;
- if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
- return;
- chain_mask =
- get_target_reg_bits(scn->mem, BB_multichain_enable,
- MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK);
- chain0 = chain_mask & 1;
- chain1 = chain_mask & 2;
- len = len << 1; /* each agc item is 64bit, total*2 */
- priv_stop_agc(scn);
- set_target_reg_bits(scn->mem, BB_chaninfo_ctrl,
- CHANINFOMEM_S2_READ_MASK, 0);
- HIF_TRACE("%s: AGC history buffer dump: E", __func__);
- if (chain0) {
- for (i = 0; i < len; i++) {
- hif_write32_mb(scn->mem +
- PHY_BB_CHN_TABLES_INTF_ADDR,
- BB_chaninfo_tab_b0 + i * 4);
- val = hif_read32_mb(scn->mem +
- PHY_BB_CHN_TABLES_INTF_DATA);
- qdf_print("0x%x\t", val);
- if (i % 4 == 0)
- qdf_print("\n");
- }
- }
- if (chain1) {
- for (i = 0; i < len; i++) {
- hif_write32_mb(scn->mem +
- PHY_BB_CHN1_TABLES_INTF_ADDR,
- BB_chaninfo_tab_b0 + i * 4);
- val = hif_read32_mb(scn->mem +
- PHY_BB_CHN1_TABLES_INTF_DATA);
- qdf_print("0x%x\t", val);
- if (i % 4 == 0)
- qdf_print("\n");
- }
- }
- HIF_TRACE("%s: AGC history buffer dump X", __func__);
- /* restore original value */
- hif_write32_mb(scn->mem + BB_gains_min_offsets,
- g_priv_dump_ctx.gain_min_offsets_orig);
- Q_TARGET_ACCESS_END(scn);
- return;
- }
- void priv_dump_bbwatchdog(struct hif_softc *scn)
- {
- uint32_t val;
- HIF_TRACE("%s: BB watchdog dump E", __func__);
- val = hif_read32_mb(scn->mem + BB_watchdog_status);
- qdf_print("0x%x\t", val);
- val = hif_read32_mb(scn->mem + BB_watchdog_ctrl_1);
- qdf_print("0x%x\t", val);
- val = hif_read32_mb(scn->mem + BB_watchdog_ctrl_2);
- qdf_print("0x%x\t", val);
- val = hif_read32_mb(scn->mem + BB_watchdog_status_B);
- qdf_print("0x%x", val);
- HIF_TRACE("%s: BB watchdog dump X", __func__);
- }
|