summaryrefslogtreecommitdiff
path: root/hif/src/mp_dev.c
diff options
context:
space:
mode:
authorPrakash Dhavali <pdhavali@codeaurora.org>2016-03-02 00:54:45 -0800
committerPrakash Dhavali <pdhavali@codeaurora.org>2016-03-03 01:02:02 -0800
commit142cee4bf22a1d052da15f3d8d050002121e4e77 (patch)
tree367efbdeac65122d4759c59068890d55cdfa0754 /hif/src/mp_dev.c
parentabcec8c47e8ff57bf9ef22d56be4eec50406b6b9 (diff)
Initial host-common file folder cleanup and moves
Initial host-common file folder cleanup and moves on top of baseline reference of MCL WLAN driver SU#5.0.0.160. Move dp, ht comm, hif, wmi and qdf folders one level up Change-Id: I2120898024b1eafd5d651c48768dbf48bf05995d
Diffstat (limited to 'hif/src/mp_dev.c')
-rw-r--r--hif/src/mp_dev.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/hif/src/mp_dev.c b/hif/src/mp_dev.c
new file mode 100644
index 000000000000..6d261735c580
--- /dev/null
+++ b/hif/src/mp_dev.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2013-2014 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 ol_softc *scn)
+{
+ set_target_reg_bits(scn->mem, BB_chaninfo_ctrl,
+ CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK, 1);
+}
+
+void priv_start_agc(struct ol_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 ol_softc *scn)
+{
+ set_target_reg_bits(scn->mem, BB_gains_min_offsets,
+ AGC_HISTORY_DUMP_MASK,
+ 0);
+}
+
+void priv_dump_chaninfo(struct ol_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;
+ cdf_print("0x%x\t", val);
+ if (i % 4 == 0)
+ cdf_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);
+ cdf_print("0x%x\t", ((tmp >> 16) & 0x0000ffff));
+ cdf_print("0x%x\t", (tmp & 0x0000ffff));
+ if (i % 2 == 0)
+ cdf_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);
+ cdf_print("0x%x\t",
+ ((tmp >> 16) & 0x0000ffff));
+ cdf_print("0x%x\t", (tmp & 0x0000ffff));
+ if (i % 2 == 0)
+ cdf_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;
+ cdf_print("0x%x\t", val);
+ if (i % 4 == 0)
+ cdf_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);
+ cdf_print("0x%x\n", (tmp >> 16) & 0x0000ffff);
+ cdf_print("0x%x\n", tmp & 0x0000ffff);
+ if (i % 2 == 0)
+ cdf_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);
+ cdf_print("0x%x\t",
+ ((tmp >> 16) & 0x0000ffff));
+ cdf_print("0x%x\t", (tmp & 0x0000ffff));
+ if (i % 2 == 0)
+ cdf_print("\n");
+ }
+ }
+ }
+ }
+ HIF_TRACE("%s: X", __func__);
+}
+
+void priv_dump_agc(struct ol_softc *scn)
+{
+ int i, len = 30; /* check this value for Rome and Peregrine */
+ uint32_t chain0, chain1, chain_mask, val;
+
+ A_TARGET_ACCESS_BEGIN(scn);
+
+ 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);
+ cdf_print("0x%x\t", val);
+ if (i % 4 == 0)
+ cdf_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);
+ cdf_print("0x%x\t", val);
+ if (i % 4 == 0)
+ cdf_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);
+
+ A_TARGET_ACCESS_END(scn);
+
+ return;
+}
+
+void priv_dump_bbwatchdog(struct ol_softc *scn)
+{
+ uint32_t val;
+
+ HIF_TRACE("%s: BB watchdog dump E", __func__);
+ val = hif_read32_mb(scn->mem + BB_watchdog_status);
+ cdf_print("0x%x\t", val);
+ val = hif_read32_mb(scn->mem + BB_watchdog_ctrl_1);
+ cdf_print("0x%x\t", val);
+ val = hif_read32_mb(scn->mem + BB_watchdog_ctrl_2);
+ cdf_print("0x%x\t", val);
+ val = hif_read32_mb(scn->mem + BB_watchdog_status_B);
+ cdf_print("0x%x", val);
+ HIF_TRACE("%s: BB watchdog dump X", __func__);
+}