浏览代码

qcacmn: add MSI and timer/batch intr threshold config support

WCN6450 CE provides registers for configuring MSI and timer/batch
interrupt thresholds like Lithium SRNGs.

Configure MSI and timer/batch interrupt threshold registers
during CE ring setup.

Change-Id: Ifa4c5a4d14caa70ae644123409cccc6f56476d85
CRs-Fixed: 3381135
Venkateswara Naralasetty 2 年之前
父节点
当前提交
4728143e0e
共有 2 个文件被更改,包括 200 次插入0 次删除
  1. 60 0
      hif/src/ce/ce_reg.h
  2. 140 0
      hif/src/ce/ce_service_legacy.c

+ 60 - 0
hif/src/ce/ce_reg.h

@@ -132,6 +132,10 @@
 #define CE_MSI_ADDRESS_HIGH       (scn->target_ce_def->d_CE_MSI_ADDRESS_HIGH)
 #define CE_MSI_ADDRESS_HIGH       (scn->target_ce_def->d_CE_MSI_ADDRESS_HIGH)
 #define CE_MSI_DATA               (scn->target_ce_def->d_CE_MSI_DATA)
 #define CE_MSI_DATA               (scn->target_ce_def->d_CE_MSI_DATA)
 #define CE_MSI_ENABLE_BIT         (scn->target_ce_def->d_CE_MSI_ENABLE_BIT)
 #define CE_MSI_ENABLE_BIT         (scn->target_ce_def->d_CE_MSI_ENABLE_BIT)
+#define CE_SRC_BATCH_TIMER_INT_SETUP \
+	(scn->target_ce_def->d_CE_SRC_BATCH_TIMER_INT_SETUP)
+#define CE_DST_BATCH_TIMER_INT_SETUP \
+	(scn->target_ce_def->d_CE_DST_BATCH_TIMER_INT_SETUP)
 #define MISC_IE_ADDRESS           (scn->target_ce_def->d_MISC_IE_ADDRESS)
 #define MISC_IE_ADDRESS           (scn->target_ce_def->d_MISC_IE_ADDRESS)
 #define MISC_IS_AXI_ERR_MASK      (scn->target_ce_def->d_MISC_IS_AXI_ERR_MASK)
 #define MISC_IS_AXI_ERR_MASK      (scn->target_ce_def->d_MISC_IS_AXI_ERR_MASK)
 #define MISC_IS_DST_ADDR_ERR_MASK \
 #define MISC_IS_DST_ADDR_ERR_MASK \
@@ -369,9 +373,65 @@ unsigned int hif_get_dst_ring_read_index(struct hif_softc *scn,
 #define CE_MSI_ADDR_HIGH_SET(scn, CE_ctrl_addr, addr) \
 #define CE_MSI_ADDR_HIGH_SET(scn, CE_ctrl_addr, addr) \
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_MSI_ADDRESS_HIGH, (addr))
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_MSI_ADDRESS_HIGH, (addr))
 
 
+#define CE_MSI_ADDR_HIGH_GET(scn, CE_ctrl_addr) \
+	A_TARGET_READ(scn, (CE_ctrl_addr) + CE_MSI_ADDRESS_HIGH)
+
 #define CE_MSI_DATA_SET(scn, CE_ctrl_addr, data) \
 #define CE_MSI_DATA_SET(scn, CE_ctrl_addr, data) \
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_MSI_DATA, (data))
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_MSI_DATA, (data))
 
 
+#define CE_MSI_EN_SET(scn, CE_ctrl_addr) \
+	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_CTRL1_ADDRESS, \
+	(A_TARGET_READ(scn, (CE_ctrl_addr) + CE_CTRL1_ADDRESS) \
+	| CE_MSI_ENABLE_BIT))
+
+#define CE_SRC_BATCH_TIMER_THRESHOLD 0
+#define CE_SRC_BATCH_COUNTER_THRESHOLD 1
+#define CE_DST_BATCH_TIMER_THRESHOLD 512
+#define CE_DST_BATCH_COUNTER_THRESHOLD 0
+
+#define CE_SRC_BATCH_TIMER_THRESH_MASK \
+	(scn->target_ce_def->d_CE_SRC_BATCH_TIMER_THRESH_MASK)
+#define CE_SRC_BATCH_TIMER_THRESH_LSB \
+	(scn->target_ce_def->d_CE_SRC_BATCH_TIMER_THRESH_LSB)
+#define CE_SRC_BATCH_COUNTER_THRESH_MASK \
+	(scn->target_ce_def->d_CE_SRC_BATCH_COUNTER_THRESH_MASK)
+#define CE_SRC_BATCH_COUNTER_THRESH_LSB \
+	(scn->target_ce_def->d_CE_SRC_BATCH_COUNTER_THRESH_LSB)
+#define CE_DST_BATCH_TIMER_THRESH_MASK \
+	(scn->target_ce_def->d_CE_DST_BATCH_TIMER_THRESH_MASK)
+#define CE_DST_BATCH_TIMER_THRESH_LSB \
+	(scn->target_ce_def->d_CE_DST_BATCH_TIMER_THRESH_LSB)
+#define CE_DST_BATCH_COUNTER_THRESH_MASK \
+	(scn->target_ce_def->d_CE_DST_BATCH_COUNTER_THRESH_MASK)
+#define CE_DST_BATCH_COUNTER_THRESH_LSB \
+	(scn->target_ce_def->d_CE_DST_BATCH_COUNTER_THRESH_LSB)
+
+#define CE_CHANNEL_SRC_BATCH_TIMER_INT_SETUP_GET(scn, CE_ctrl_addr) \
+	A_TARGET_READ(scn, (CE_ctrl_addr) + CE_SRC_BATCH_TIMER_INT_SETUP)
+#define CE_CHANNEL_DST_BATCH_TIMER_INT_SETUP_GET(scn, CE_ctrl_addr) \
+	A_TARGET_READ(scn, (CE_ctrl_addr) + CE_DST_BATCH_TIMER_INT_SETUP)
+
+#define CE_CHANNEL_SRC_BATCH_TIMER_INT_SETUP(scn, CE_ctrl_addr, data) \
+	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_SRC_BATCH_TIMER_INT_SETUP, data)
+#define CE_CHANNEL_DST_BATCH_TIMER_INT_SETUP(scn, CE_ctrl_addr, data) \
+	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_DST_BATCH_TIMER_INT_SETUP, data)
+
+#define HOST_IE_SRC_TIMER_BATCH_MASK \
+	(scn->target_ce_def->d_HOST_IE_SRC_TIMER_BATCH_MASK)
+#define HOST_IE_DST_TIMER_BATCH_MASK \
+	(scn->target_ce_def->d_HOST_IE_DST_TIMER_BATCH_MASK)
+
+#define CE_CHANNEL_SRC_TIMER_BATCH_INT_EN(scn, CE_ctrl_addr) \
+	A_TARGET_WRITE(scn, (CE_ctrl_addr) + HOST_IE_ADDRESS, \
+		       A_TARGET_READ(scn, \
+		       (CE_ctrl_addr) + HOST_IE_ADDRESS) | \
+		       HOST_IE_SRC_TIMER_BATCH_MASK)
+#define CE_CHANNEL_DST_TIMER_BATCH_INT_EN(scn, CE_ctrl_addr) \
+	A_TARGET_WRITE(scn, (CE_ctrl_addr) + HOST_IE_ADDRESS, \
+		       A_TARGET_READ(scn, \
+		       (CE_ctrl_addr) + HOST_IE_ADDRESS) | \
+		       HOST_IE_DST_TIMER_BATCH_MASK)
+
 #define CE_CTRL_REGISTER1_SET(scn, CE_ctrl_addr, val) \
 #define CE_CTRL_REGISTER1_SET(scn, CE_ctrl_addr, val) \
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_CTRL1_ADDRESS, val)
 	A_TARGET_WRITE(scn, (CE_ctrl_addr) + CE_CTRL1_ADDRESS, val)
 
 

+ 140 - 0
hif/src/ce/ce_service_legacy.c

@@ -1118,12 +1118,128 @@ ce_per_engine_handler_adjust_legacy(struct CE_state *CE_state,
 	Q_TARGET_ACCESS_END(scn);
 	Q_TARGET_ACCESS_END(scn);
 }
 }
 
 
+#ifdef QCA_WIFI_WCN6450
+static void ce_legacy_msi_param_setup(struct hif_softc *scn, uint32_t ctrl_addr,
+				      uint32_t ce_id, struct CE_attr *attr)
+{
+	uint32_t addr_low;
+	uint32_t addr_high;
+	uint32_t msi_data_start;
+	uint32_t msi_data_count;
+	uint32_t msi_irq_start;
+	uint32_t tmp;
+	int ret;
+	int irq_id;
+
+	ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE",
+					  &msi_data_count, &msi_data_start,
+					  &msi_irq_start);
+
+	/* msi config not found */
+	if (ret) {
+		hif_debug("%s: failed to get user msi assignment ret %d",
+			  __func__, ret);
+		return;
+	}
+
+	irq_id = scn->int_assignment->msi_idx[ce_id];
+	pld_get_msi_address(scn->qdf_dev->dev, &addr_low, &addr_high);
+
+	CE_MSI_ADDR_LOW_SET(scn, ctrl_addr, addr_low);
+	tmp = CE_MSI_ADDR_HIGH_GET(scn, ctrl_addr);
+	tmp &= ~CE_RING_BASE_ADDR_HIGH_MASK;
+	tmp |= (addr_high & CE_RING_BASE_ADDR_HIGH_MASK);
+	CE_MSI_ADDR_HIGH_SET(scn, ctrl_addr, tmp);
+	CE_MSI_DATA_SET(scn, ctrl_addr, irq_id + msi_data_start);
+	CE_MSI_EN_SET(scn, ctrl_addr);
+}
+
+static void ce_legacy_src_intr_thres_setup(struct hif_softc *scn,
+					   uint32_t ctrl_addr,
+					   struct CE_attr *attr,
+					   uint32_t timer_thrs,
+					   uint32_t count_thrs)
+{
+	uint32_t tmp;
+
+	tmp = CE_CHANNEL_SRC_BATCH_TIMER_INT_SETUP_GET(scn, ctrl_addr);
+
+	if (count_thrs) {
+		tmp &= ~(CE_SRC_BATCH_COUNTER_THRESH_MASK <<
+			 CE_SRC_BATCH_COUNTER_THRESH_LSB);
+		tmp |= ((count_thrs & CE_SRC_BATCH_COUNTER_THRESH_MASK) <<
+			CE_SRC_BATCH_COUNTER_THRESH_LSB);
+	}
+
+	if (timer_thrs) {
+		tmp &= ~(CE_SRC_BATCH_TIMER_THRESH_MASK <<
+			 CE_SRC_BATCH_TIMER_THRESH_LSB);
+		tmp |= ((timer_thrs & CE_SRC_BATCH_TIMER_THRESH_MASK) <<
+			CE_SRC_BATCH_TIMER_THRESH_LSB);
+	}
+
+	CE_CHANNEL_SRC_BATCH_TIMER_INT_SETUP(scn, ctrl_addr, tmp);
+	CE_CHANNEL_SRC_TIMER_BATCH_INT_EN(scn, ctrl_addr);
+}
+
+static void ce_legacy_dest_intr_thres_setup(struct hif_softc *scn,
+					    uint32_t ctrl_addr,
+					    struct CE_attr *attr,
+					    uint32_t timer_thrs,
+					    uint32_t count_thrs)
+{
+	uint32_t tmp;
+
+	tmp = CE_CHANNEL_DST_BATCH_TIMER_INT_SETUP_GET(scn, ctrl_addr);
+
+	if (count_thrs) {
+		tmp &= ~(CE_DST_BATCH_COUNTER_THRESH_MASK <<
+			 CE_DST_BATCH_COUNTER_THRESH_LSB);
+		tmp |= ((count_thrs & CE_DST_BATCH_COUNTER_THRESH_MASK) <<
+			CE_DST_BATCH_COUNTER_THRESH_LSB);
+	}
+
+	if (timer_thrs) {
+		tmp &= ~(CE_DST_BATCH_TIMER_THRESH_MASK <<
+			 CE_DST_BATCH_TIMER_THRESH_LSB);
+		tmp |= ((timer_thrs & CE_DST_BATCH_TIMER_THRESH_MASK) <<
+			CE_DST_BATCH_TIMER_THRESH_LSB);
+	}
+
+	CE_CHANNEL_DST_BATCH_TIMER_INT_SETUP(scn, ctrl_addr, tmp);
+	CE_CHANNEL_DST_TIMER_BATCH_INT_EN(scn, ctrl_addr);
+}
+#else
+static void ce_legacy_msi_param_setup(struct hif_softc *scn, uint32_t ctrl_addr,
+				      uint32_t ce_id, struct CE_attr *attr)
+{
+}
+
+static void ce_legacy_src_intr_thres_setup(struct hif_softc *scn,
+					   uint32_t ctrl_addr,
+					   struct CE_attr *attr,
+					   uint32_t timer_thrs,
+					   uint32_t count_thrs)
+{
+}
+
+static void ce_legacy_dest_intr_thres_setup(struct hif_softc *scn,
+					    uint32_t ctrl_addr,
+					    struct CE_attr *attr,
+					    uint32_t timer_thrs,
+					    uint32_t count_thrs)
+{
+}
+#endif /* QCA_WIFI_WCN6450 */
+
 static void ce_legacy_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 static void ce_legacy_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 				     struct CE_ring_state *src_ring,
 				     struct CE_ring_state *src_ring,
 				     struct CE_attr *attr)
 				     struct CE_attr *attr)
 {
 {
 	uint32_t ctrl_addr;
 	uint32_t ctrl_addr;
 	uint64_t dma_addr;
 	uint64_t dma_addr;
+	uint32_t timer_thrs;
+	uint32_t count_thrs;
 
 
 	QDF_ASSERT(ce_id < scn->ce_count);
 	QDF_ASSERT(ce_id < scn->ce_count);
 	ctrl_addr = CE_BASE_ADDRESS(ce_id);
 	ctrl_addr = CE_BASE_ADDRESS(ce_id);
@@ -1157,6 +1273,17 @@ static void ce_legacy_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 #endif
 #endif
 	CE_SRC_RING_LOWMARK_SET(scn, ctrl_addr, 0);
 	CE_SRC_RING_LOWMARK_SET(scn, ctrl_addr, 0);
 	CE_SRC_RING_HIGHMARK_SET(scn, ctrl_addr, src_ring->nentries);
 	CE_SRC_RING_HIGHMARK_SET(scn, ctrl_addr, src_ring->nentries);
+
+	if (!(CE_ATTR_DISABLE_INTR & attr->flags)) {
+		/* In 8us units */
+		timer_thrs = CE_SRC_BATCH_TIMER_THRESHOLD >> 3;
+		/* Batch counter threshold 1 in Dwrod units */
+		count_thrs = (CE_SRC_BATCH_COUNTER_THRESHOLD *
+			      (sizeof(struct CE_src_desc) >> 2));
+		ce_legacy_msi_param_setup(scn, ctrl_addr, ce_id, attr);
+		ce_legacy_src_intr_thres_setup(scn, ctrl_addr, attr,
+					       timer_thrs, count_thrs);
+	}
 }
 }
 
 
 static void ce_legacy_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 static void ce_legacy_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
@@ -1165,6 +1292,8 @@ static void ce_legacy_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 {
 {
 	uint32_t ctrl_addr;
 	uint32_t ctrl_addr;
 	uint64_t dma_addr;
 	uint64_t dma_addr;
+	uint32_t timer_thrs;
+	uint32_t count_thrs;
 
 
 	QDF_ASSERT(ce_id < scn->ce_count);
 	QDF_ASSERT(ce_id < scn->ce_count);
 	ctrl_addr = CE_BASE_ADDRESS(ce_id);
 	ctrl_addr = CE_BASE_ADDRESS(ce_id);
@@ -1196,6 +1325,17 @@ static void ce_legacy_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 #endif
 #endif
 	CE_DEST_RING_LOWMARK_SET(scn, ctrl_addr, 0);
 	CE_DEST_RING_LOWMARK_SET(scn, ctrl_addr, 0);
 	CE_DEST_RING_HIGHMARK_SET(scn, ctrl_addr, dest_ring->nentries);
 	CE_DEST_RING_HIGHMARK_SET(scn, ctrl_addr, dest_ring->nentries);
+
+	if (!(CE_ATTR_DISABLE_INTR & attr->flags)) {
+		/* In 8us units */
+		timer_thrs = CE_DST_BATCH_TIMER_THRESHOLD >> 3;
+		/* Batch counter threshold 1 in Dwrod units */
+		count_thrs = CE_DST_BATCH_COUNTER_THRESHOLD;
+
+		ce_legacy_msi_param_setup(scn, ctrl_addr, ce_id, attr);
+		ce_legacy_dest_intr_thres_setup(scn, ctrl_addr, attr,
+						timer_thrs, count_thrs);
+	}
 }
 }
 
 
 static uint32_t ce_get_desc_size_legacy(uint8_t ring_type)
 static uint32_t ce_get_desc_size_legacy(uint8_t ring_type)