Forráskód Böngészése

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
Nandha Kishore Easwaran 5 éve
szülő
commit
bcf953583a

+ 59 - 9
hal/wifi3.0/hal_api.h

@@ -178,6 +178,12 @@ static inline void hal_select_window(struct hal_soc *hal_soc, uint32_t offset,
 }
 #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 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
 				  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 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
 		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 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
 		}
 	}
 }
-#endif
 
 /**
  * hal_write_address_32_mb - write a value to a register
@@ -287,7 +319,7 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset,
  */
 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 @@ void hal_write_address_32_mb(struct hal_soc *hal_soc,
 	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 hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
 {
 	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 @@ uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
  */
 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 @@ hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
 		}
 	} 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);
 	}
 }
 

+ 5 - 0
hal/wifi3.0/hal_internal.h

@@ -353,6 +353,8 @@ struct hal_hw_txrx_ops {
 				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 @@ struct hal_soc {
 	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;

+ 11 - 2
hal/wifi3.0/hal_srng.c

@@ -273,6 +273,11 @@ static void hal_target_based_configure(struct hal_soc *hal)
 #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 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
 					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 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
 				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,

+ 14 - 0
hal/wifi3.0/qca6290/hal_6290.c

@@ -977,6 +977,19 @@ uint16_t hal_rx_get_rx_sequence_6290(uint8_t *buf)
 	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 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = {
 	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,

+ 14 - 0
hal/wifi3.0/qca6390/hal_6390.c

@@ -973,6 +973,19 @@ uint16_t hal_rx_get_rx_sequence_6390(uint8_t *buf)
 	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 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = {
 	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,

+ 14 - 0
hal/wifi3.0/qca6490/hal_6490.c

@@ -1291,6 +1291,19 @@ uint16_t hal_rx_get_rx_sequence_6490(uint8_t *buf)
 	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 @@ struct hal_hw_txrx_ops qca6490_hal_hw_txrx_ops = {
 	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,

+ 13 - 0
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 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = {
 	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,

+ 14 - 0
hal/wifi3.0/qca8074v2/hal_8074v2.c

@@ -970,6 +970,19 @@ uint16_t hal_rx_get_rx_sequence_8074v2(uint8_t *buf)
 	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 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = {
 	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,

+ 57 - 1
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 @@ uint16_t hal_rx_get_rx_sequence_9000(uint8_t *buf)
 	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 @@ struct hal_hw_txrx_ops qcn9000_hal_hw_txrx_ops = {
 	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 @@ int32_t hal_hw_reg_offset_qcn9000[] = {
 	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 @@ void hal_qcn9000_attach(struct hal_soc *hal_soc)
 	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);
 }

+ 1 - 1
qdf/inc/qdf_types.h

@@ -190,7 +190,7 @@ typedef struct qdf_shared_mem {
 	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

+ 1 - 1
qdf/linux/src/i_qdf_types.h

@@ -274,7 +274,7 @@ typedef struct __qdf_device *__qdf_device_t;
 
 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;