qcacmn: Use multi window write and read for pine

Write into hal register using three floating windows instead of one.
This change is done to avoid frequent window changes for writing into
DP and CE registers. Instead 3 windows are used. One window is statically
mapped to CE block and another window is mapped statically to DP block.
Due to this design there is no need to change the window register to
write into these blocks and write can be done on corresponding window
with single iowrite32. Similar loginc is used for ioread32.

Also modified the hp_addr and tp_addr in initialisation stage so that
hal_write will not have multiple if checks.

Change-Id: Ibb99ec4da7f63323082e46a28afbe90e1f555545
CRs-fixed: 2507441
diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h
index 4dee382..ab7e1ad 100644
--- a/hal/wifi3.0/hal_api.h
+++ b/hal/wifi3.0/hal_api.h
@@ -178,6 +178,12 @@
 }
 #endif
 
+static inline qdf_iomem_t hal_get_window_address(struct hal_soc *hal_soc,
+						 qdf_iomem_t addr)
+{
+	return hal_soc->ops->hal_get_window_address(hal_soc, addr);
+}
+
 /**
  * hal_write32_mb() - Access registers to update configuration
  * @hal_soc: hal soc handle
@@ -209,12 +215,17 @@
 				  uint32_t value, bool ret_confirm)
 {
 	unsigned long flags;
+	qdf_iomem_t new_addr;
 
 	if (!hal_soc->use_register_windowing ||
 	    offset < MAX_UNWINDOWED_ADDRESS) {
 		qdf_iowrite32(hal_soc->dev_base_addr + offset, value);
 		hal_reg_write_result_check(hal_soc, offset,
 					   value, ret_confirm);
+	} else if (hal_soc->static_window_map) {
+		new_addr = hal_get_window_address(hal_soc,
+				hal_soc->dev_base_addr + offset);
+		qdf_iowrite32(new_addr, value);
 	} else {
 		hal_lock_reg_access(hal_soc, &flags);
 		hal_select_window(hal_soc, offset, ret_confirm);
@@ -228,6 +239,28 @@
 		hal_unlock_reg_access(hal_soc, &flags);
 	}
 }
+
+/**
+ * hal_write_address_32_mb - write a value to a register
+ *
+ */
+static inline
+void hal_write_address_32_mb(struct hal_soc *hal_soc,
+			     qdf_iomem_t addr, uint32_t value)
+{
+	uint32_t offset;
+	qdf_iomem_t new_addr;
+
+	if (!hal_soc->use_register_windowing)
+		return qdf_iowrite32(addr, value);
+
+	offset = addr - hal_soc->dev_base_addr;
+	if (hal_soc->static_window_map) {
+		new_addr = hal_get_window_address(hal_soc, addr);
+		return qdf_iowrite32(new_addr, value);
+	}
+	hal_write32_mb(hal_soc, offset, value, false);
+}
 #else
 static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
 				  uint32_t value, bool ret_confirm)
@@ -279,7 +312,6 @@
 		}
 	}
 }
-#endif
 
 /**
  * hal_write_address_32_mb - write a value to a register
@@ -287,7 +319,7 @@
  */
 static inline
 void hal_write_address_32_mb(struct hal_soc *hal_soc,
-			     void __iomem *addr, uint32_t value)
+			     qdf_iomem_t addr, uint32_t value)
 {
 	uint32_t offset;
 
@@ -297,6 +329,14 @@
 	offset = addr - hal_soc->dev_base_addr;
 	hal_write32_mb(hal_soc, offset, value, false);
 }
+#endif
+
+#ifdef DP_HAL_MULTIWINDOW_DIRECT_ACCESS
+#define hal_srng_write_address_32_mb(_a, _b, _c) qdf_iowrite32(_b, _c)
+#else
+#define hal_srng_write_address_32_mb(_a, _b, _c) \
+		hal_write_address_32_mb(_a, _b, _c)
+#endif
 
 #if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490)
 /**
@@ -325,10 +365,14 @@
 {
 	uint32_t ret;
 	unsigned long flags;
+	qdf_iomem_t new_addr;
 
 	if (!hal_soc->use_register_windowing ||
 	    offset < MAX_UNWINDOWED_ADDRESS) {
 		return qdf_ioread32(hal_soc->dev_base_addr + offset);
+	} else if (hal_soc->static_window_map) {
+		new_addr = hal_get_window_address(hal_soc, hal_soc->dev_base_addr + offset);
+		return qdf_ioread32(new_addr);
 	}
 
 	hal_lock_reg_access(hal_soc, &flags);
@@ -388,15 +432,21 @@
  */
 static inline
 uint32_t hal_read_address_32_mb(struct hal_soc *soc,
-				void __iomem *addr)
+				qdf_iomem_t addr)
 {
 	uint32_t offset;
 	uint32_t ret;
+	qdf_iomem_t new_addr;
 
 	if (!soc->use_register_windowing)
 		return qdf_ioread32(addr);
 
 	offset = addr - soc->dev_base_addr;
+	if (soc->static_window_map) {
+		new_addr = hal_get_window_address(soc, addr);
+		return qdf_ioread32(new_addr);
+	}
+
 	ret = hal_read32_mb(soc, offset);
 	return ret;
 }
@@ -1267,13 +1317,13 @@
 		}
 	} else {
 		if (srng->ring_dir == HAL_SRNG_SRC_RING)
-			hal_write_address_32_mb(hal_soc,
-				srng->u.src_ring.hp_addr,
-				srng->u.src_ring.hp);
+			hal_srng_write_address_32_mb(hal_soc,
+						     srng->u.src_ring.hp_addr,
+						     srng->u.src_ring.hp);
 		else
-			hal_write_address_32_mb(hal_soc,
-				srng->u.dst_ring.tp_addr,
-				srng->u.dst_ring.tp);
+			hal_srng_write_address_32_mb(hal_soc,
+						     srng->u.dst_ring.tp_addr,
+						     srng->u.dst_ring.tp);
 	}
 }
 
diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h
index 76f4c08..c2773ff 100644
--- a/hal/wifi3.0/hal_internal.h
+++ b/hal/wifi3.0/hal_internal.h
@@ -353,6 +353,8 @@
 				uint32_t scatter_buf_size,
 				uint32_t last_buf_end_offset,
 				uint32_t num_entries);
+	qdf_iomem_t (*hal_get_window_address)(struct hal_soc *hal_soc,
+					      qdf_iomem_t addr);
 
 	/* tx */
 	void (*hal_tx_desc_set_dscp_tid_table_id)(void *desc, uint8_t id);
@@ -498,6 +500,9 @@
 	uint32_t register_window;
 	qdf_spinlock_t register_access_lock;
 
+	/* Static window map configuration for multiple window write*/
+	bool static_window_map;
+
 	/* srng table */
 	struct hal_hw_srng_config *hw_srng_table;
 	int32_t *hal_hw_reg_offset;
diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c
index 30836e5..be215f2 100644
--- a/hal/wifi3.0/hal_srng.c
+++ b/hal/wifi3.0/hal_srng.c
@@ -273,6 +273,11 @@
 #ifdef QCA_WIFI_QCN9000
 	case TARGET_TYPE_QCN9000:
 		hal->use_register_windowing = true;
+		/*
+		 * Static window map  is enabled for qcn9000 to use 2mb bar
+		 * size and use multiple windows to write into registers.
+		 */
+		hal->static_window_map = true;
 		hal_qcn9000_attach(hal);
 	break;
 #endif
@@ -676,7 +681,9 @@
 					HAL_SRNG_LMAC1_ID_START]);
 			srng->flags |= HAL_SRNG_LMAC_RING;
 		} else if (ignore_shadow || (srng->u.src_ring.hp_addr == 0)) {
-			srng->u.src_ring.hp_addr = SRNG_SRC_ADDR(srng, HP);
+			srng->u.src_ring.hp_addr =
+				hal_get_window_address(hal,
+						SRNG_SRC_ADDR(srng, HP));
 
 			if (CHECK_SHADOW_REGISTERS) {
 				QDF_TRACE(QDF_MODULE_ID_TXRX,
@@ -711,7 +718,9 @@
 				HAL_SRNG_LMAC1_ID_START]);
 			srng->flags |= HAL_SRNG_LMAC_RING;
 		} else if (ignore_shadow || srng->u.dst_ring.tp_addr == 0) {
-			srng->u.dst_ring.tp_addr = SRNG_DST_ADDR(srng, TP);
+			srng->u.dst_ring.tp_addr =
+				hal_get_window_address(hal,
+						SRNG_DST_ADDR(srng, TP));
 
 			if (CHECK_SHADOW_REGISTERS) {
 				QDF_TRACE(QDF_MODULE_ID_TXRX,
diff --git a/hal/wifi3.0/qca6290/hal_6290.c b/hal/wifi3.0/qca6290/hal_6290.c
index 024bcb8..a848e15 100644
--- a/hal/wifi3.0/qca6290/hal_6290.c
+++ b/hal/wifi3.0/qca6290/hal_6290.c
@@ -977,6 +977,19 @@
 	return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info);
 }
 
+/**
+ * hal_get_window_address_6290(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_6290(struct hal_soc *hal_soc,
+							qdf_iomem_t addr)
+{
+	return addr;
+}
+
 struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = {
 	/* init and setup */
 	hal_srng_dst_hw_init_generic,
@@ -984,6 +997,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_6290,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_6290,
diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c
index 9b747bd..56e7f3d 100644
--- a/hal/wifi3.0/qca6390/hal_6390.c
+++ b/hal/wifi3.0/qca6390/hal_6390.c
@@ -973,6 +973,19 @@
 	return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info);
 }
 
+/**
+ * hal_get_window_address_6390(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_6390(struct hal_soc *hal_soc,
+						      qdf_iomem_t addr)
+{
+	return addr;
+}
+
 struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = {
 	/* init and setup */
 	hal_srng_dst_hw_init_generic,
@@ -980,6 +993,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_6390,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_6390,
diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c
index b06cb19..7a349b0 100644
--- a/hal/wifi3.0/qca6490/hal_6490.c
+++ b/hal/wifi3.0/qca6490/hal_6490.c
@@ -1291,6 +1291,19 @@
 	return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info);
 }
 
+/**
+ * hal_get_window_address_6490(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_6490(struct hal_soc *hal_soc,
+						      qdf_iomem_t addr)
+{
+	return addr;
+}
+
 struct hal_hw_txrx_ops qca6490_hal_hw_txrx_ops = {
 	/* init and setup */
 	hal_srng_dst_hw_init_generic,
@@ -1298,6 +1311,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_6490,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_6490,
diff --git a/hal/wifi3.0/qca8074v1/hal_8074v1.c b/hal/wifi3.0/qca8074v1/hal_8074v1.c
index a97473f..d758b1f 100644
--- a/hal/wifi3.0/qca8074v1/hal_8074v1.c
+++ b/hal/wifi3.0/qca8074v1/hal_8074v1.c
@@ -104,6 +104,18 @@
 #include <hal_generic_api.h>
 #include <hal_wbm.h>
 
+/**
+ * hal_get_window_address_8074(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_8074(struct hal_soc *hal_soc,
+						      qdf_iomem_t addr)
+{
+	return addr;
+}
 
 /**
  * hal_rx_get_rx_fragment_number_8074v1(): Function to retrieve
@@ -981,6 +993,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_8074,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_8074,
diff --git a/hal/wifi3.0/qca8074v2/hal_8074v2.c b/hal/wifi3.0/qca8074v2/hal_8074v2.c
index f476cc7..61f5cc7 100644
--- a/hal/wifi3.0/qca8074v2/hal_8074v2.c
+++ b/hal/wifi3.0/qca8074v2/hal_8074v2.c
@@ -970,6 +970,19 @@
 	return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info);
 }
 
+/**
+ * hal_get_window_address_8074v2(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_8074v2(struct hal_soc *hal_soc,
+							     qdf_iomem_t addr)
+{
+	return addr;
+}
+
 struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = {
 
 	/* init and setup */
@@ -978,6 +991,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_8074v2,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_8074v2,
diff --git a/hal/wifi3.0/qcn9000/hal_9000.c b/hal/wifi3.0/qcn9000/hal_9000.c
index f9d2ceb..dcbd53e 100644
--- a/hal/wifi3.0/qcn9000/hal_9000.c
+++ b/hal/wifi3.0/qcn9000/hal_9000.c
@@ -101,6 +101,17 @@
 #define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \
 	WBM_RELEASE_RING_6_TX_RATE_STATS_TSF_DIRECTLY_AFTER_PPDU_TRANSMISSION_LSB
 
+#define CE_WINDOW_ADDRESS_9000 \
+		((CE_WFSS_CE_REG_BASE >> WINDOW_SHIFT) & WINDOW_VALUE_MASK)
+
+#define UMAC_WINDOW_ADDRESS_9000 \
+		((SEQ_WCSS_UMAC_OFFSET >> WINDOW_SHIFT) & WINDOW_VALUE_MASK)
+
+#define WINDOW_CONFIGURATION_VALUE_9000 \
+		((CE_WINDOW_ADDRESS_9000 << 6) |\
+		 (UMAC_WINDOW_ADDRESS_9000 << 12) | \
+		 WINDOW_ENABLE_BIT)
+
 /* Including hkv2 files as the functions between hkv2 and pine are exactly
  * similar
  */
@@ -979,6 +990,49 @@
 	return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info);
 }
 
+/**
+ * hal_get_window_address_9000(): Function to get hp/tp address
+ * @hal_soc: Pointer to hal_soc
+ * @addr: address offset of register
+ *
+ * Return: modified address offset of register
+ */
+static inline qdf_iomem_t hal_get_window_address_9000(struct hal_soc *hal_soc,
+						      qdf_iomem_t addr)
+{
+	uint32_t offset = addr - hal_soc->dev_base_addr;
+	qdf_iomem_t new_offset;
+
+	/*
+	 * If offset lies within DP register range, use 3rd window to write
+	 * into DP region.
+	 */
+	if ((offset ^ SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) {
+		new_offset = (hal_soc->dev_base_addr + (3 * WINDOW_START) +
+			  (offset & WINDOW_RANGE_MASK));
+	/*
+	 * If offset lies within CE register range, use 2nd window to write
+	 * into CE region.
+	 */
+	} else if ((offset ^ CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) {
+		new_offset = (hal_soc->dev_base_addr + (2 * WINDOW_START) +
+			  (offset & WINDOW_RANGE_MASK));
+	} else {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: ERROR: Accessing Wrong register\n", __func__);
+		qdf_assert_always(0);
+		return 0;
+	}
+	return new_offset;
+}
+
+static inline void hal_write_window_register(struct hal_soc *hal_soc)
+{
+	/* Write value into window configuration register */
+	qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS,
+		      WINDOW_CONFIGURATION_VALUE_9000);
+}
+
 struct hal_hw_txrx_ops qcn9000_hal_hw_txrx_ops = {
 
 	/* init and setup */
@@ -987,6 +1041,7 @@
 	hal_get_hw_hptp_generic,
 	hal_reo_setup_generic,
 	hal_setup_link_idle_list_generic,
+	hal_get_window_address_9000,
 
 	/* tx */
 	hal_tx_desc_set_dscp_tid_table_id_8074v2,
@@ -1511,7 +1566,6 @@
 	REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1),
 };
 
-
 /**
  * hal_qcn9000_attach()- Attach 9000 target specific hal_soc ops,
  *			  offset and srng table
@@ -1522,4 +1576,6 @@
 	hal_soc->hw_srng_table = hw_srng_table_9000;
 	hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qcn9000;
 	hal_soc->ops = &qcn9000_hal_hw_txrx_ops;
+	if (hal_soc->static_window_map)
+		hal_write_window_register(hal_soc);
 }
diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h
index 1c5536c..79ccbf2 100644
--- a/qdf/inc/qdf_types.h
+++ b/qdf/inc/qdf_types.h
@@ -190,7 +190,7 @@
 	qdf_dma_mem_context(memctx);
 } qdf_shared_mem_t;
 
-#define qdf_iomem_t __qdf_iomem_t;
+#define qdf_iomem_t __qdf_iomem_t
 
 /**
  * typedef enum QDF_TIMER_TYPE - QDF timer type
diff --git a/qdf/linux/src/i_qdf_types.h b/qdf/linux/src/i_qdf_types.h
index ac519dd..cb2a352 100644
--- a/qdf/linux/src/i_qdf_types.h
+++ b/qdf/linux/src/i_qdf_types.h
@@ -274,7 +274,7 @@
 
 typedef size_t __qdf_size_t;
 typedef off_t __qdf_off_t;
-typedef uint8_t __iomem *__qdf_iomem_t;
+typedef void __iomem* __qdf_iomem_t;
 
 typedef uint32_t ath_dma_addr_t;