Sfoglia il codice sorgente

qcacmn: Add support to configure MSI registers for Direct Link CE

The MSI address and data information for Direct Link
copy engines will be available once the WiFi driver
on LPASS is initialized. Add support to configure the
IPCC address and data values into Direct Link copy
engines at runtime.

Change-Id: I5e7dff90c2f1ff764462c235deb5795ed019a16b
CRs-Fixed: 3316679
Yeshwanth Sriram Guntuka 2 anni fa
parent
commit
e228622034

+ 29 - 0
hal/wifi3.0/hal_api.h

@@ -3387,4 +3387,33 @@ uint16_t hal_srng_dst_get_hpidx(hal_ring_handle_t hal_ring_hdl)
 
 	return hp / srng->entry_size;
 }
+
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * hal_srng_set_msi_irq_config() - Set the MSI irq configuration for srng
+ * @hal_soc_hdl: hal soc handle
+ * @hal_ring_hdl: srng handle
+ * @addr: MSI address
+ * @data: MSI data
+ *
+ * Return: QDF status
+ */
+static inline QDF_STATUS
+hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl,
+			    hal_ring_handle_t hal_ring_hdl,
+			    struct hal_srng_params *ring_params)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	return hal_soc->ops->hal_srng_set_msi_config(hal_ring_hdl, ring_params);
+}
+#else
+static inline QDF_STATUS
+hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl,
+			    hal_ring_handle_t hal_ring_hdl,
+			    struct hal_srng_params *ring_params)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
 #endif /* _HAL_APIH_ */

+ 91 - 0
hal/wifi3.0/hal_generic_api.h

@@ -571,4 +571,95 @@ static inline void hal_srng_hw_reg_offset_init_generic(struct hal_soc *hal_soc)
 #endif
 }
 
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * hal_srng_set_msi_config() - Set the MSI config and enable the SRNG
+ * @hal_ring_hdl: srng handle
+ * @params: ring parameters
+ *
+ * Return: QDF status
+ */
+static inline
+QDF_STATUS hal_srng_set_msi_config(hal_ring_handle_t ring_hdl,
+				   void *params)
+{
+	struct hal_srng *srng = (struct hal_srng *)ring_hdl;
+	struct hal_srng_params *ring_params = (struct hal_srng_params *)params;
+	uint32_t reg_val;
+
+	srng->intr_timer_thres_us = ring_params->intr_timer_thres_us;
+	srng->intr_batch_cntr_thres_entries =
+				ring_params->intr_batch_cntr_thres_entries;
+	srng->msi_addr = ring_params->msi_addr;
+	srng->msi_data = ring_params->msi_data;
+
+	if (srng->ring_dir == HAL_SRNG_SRC_RING) {
+		reg_val = 0;
+
+		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
+				   srng->msi_addr & 0xffffffff);
+		reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
+				  (uint64_t)(srng->msi_addr) >> 32) |
+				  SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
+						       MSI1_ENABLE), 1);
+		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
+		SRNG_SRC_REG_WRITE(srng, MSI1_DATA,
+				   qdf_cpu_to_le32(srng->msi_data));
+
+		reg_val = 0;
+
+		if (srng->intr_timer_thres_us) {
+			reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
+				INTERRUPT_TIMER_THRESHOLD),
+				srng->intr_timer_thres_us);
+		}
+
+		if (srng->intr_batch_cntr_thres_entries) {
+			reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
+				BATCH_COUNTER_THRESHOLD),
+				srng->intr_batch_cntr_thres_entries *
+				srng->entry_size);
+		}
+		SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
+	} else {
+		reg_val = 0;
+
+		SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
+				   srng->msi_addr & 0xffffffff);
+		reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
+				  (uint64_t)(srng->msi_addr) >> 32) |
+				  SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
+						       MSI1_ENABLE), 1);
+		SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
+		SRNG_DST_REG_WRITE(srng, MSI1_DATA,
+				   qdf_cpu_to_le32(srng->msi_data));
+
+		reg_val = 0;
+
+		if (srng->intr_timer_thres_us) {
+			reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
+				INTERRUPT_TIMER_THRESHOLD),
+				srng->intr_timer_thres_us >> 3);
+		}
+
+		if (srng->intr_batch_cntr_thres_entries) {
+			reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
+				BATCH_COUNTER_THRESHOLD),
+				srng->intr_batch_cntr_thres_entries *
+				srng->entry_size);
+		}
+
+		SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline
+QDF_STATUS hal_srng_set_msi_config(hal_ring_handle_t ring_hdl,
+				   void *params)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
 #endif /* HAL_GENERIC_API_H_ */

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

@@ -1213,6 +1213,10 @@ struct hal_hw_txrx_ops {
 					 uint8_t mac_id, uint64_t *value);
 	void (*hal_get_tqm_scratch_reg)(hal_soc_handle_t hal_soc_hdl,
 					uint64_t *value);
+#ifdef FEATURE_DIRECT_LINK
+	QDF_STATUS (*hal_srng_set_msi_config)(hal_ring_handle_t ring_hdl,
+					      void *ring_params);
+#endif
 };
 
 /**

+ 3 - 0
hal/wifi3.0/kiwi/hal_kiwi.c

@@ -2303,6 +2303,9 @@ static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc)
 	hal_soc->ops->hal_get_tsf_time = hal_get_tsf_time_kiwi;
 	hal_soc->ops->hal_rx_reo_ent_get_src_link_id =
 					hal_rx_reo_ent_get_src_link_id_kiwi;
+#ifdef FEATURE_DIRECT_LINK
+	hal_soc->ops->hal_srng_set_msi_config = hal_srng_set_msi_config;
+#endif
 };
 
 struct hal_hw_srng_config hw_srng_table_kiwi[] = {

+ 21 - 0
hif/inc/hif.h

@@ -2437,4 +2437,25 @@ QDF_STATUS hif_unregister_umac_reset_handler(struct hif_opaque_softc *hif_scn)
 
 #endif /* DP_UMAC_HW_RESET_SUPPORT */
 
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * hif_set_irq_config_by_ceid() - Set irq configuration for CE given by id
+ * @scn: hif opaque handle
+ * @ce_id: CE id
+ * @addr: irq trigger address
+ * @data: irq trigger data
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
+			   uint64_t addr, uint32_t data);
+#else
+static inline QDF_STATUS
+hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
+			   uint64_t addr, uint32_t data)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif /* _HIF_H_ */

+ 5 - 0
hif/src/ce/ce_api.h

@@ -597,6 +597,11 @@ struct ce_ops {
 			    struct pld_shadow_reg_v3_cfg **shadow_config,
 			    int *num_shadow_registers_configured);
 #endif
+#ifdef FEATURE_DIRECT_LINK
+	QDF_STATUS (*ce_set_irq_config_by_ceid)(struct hif_softc *scn,
+						uint8_t ce_id, uint64_t addr,
+						uint32_t data);
+#endif
 };
 
 int hif_ce_bus_early_suspend(struct hif_softc *scn);

+ 7 - 5
hif/src/ce/ce_assignment.h

@@ -1573,8 +1573,9 @@ static struct CE_pipe_config target_ce_config_wlan_qca6750[] = {
 #define KIWI_CE_COUNT 9
 static struct CE_attr host_ce_config_wlan_kiwi[] = {
 	/* host->target HTC control and raw streams */
-#ifdef FEATURE_XPAN
-	{ /* CE0 */ CE_ATTR_FLAGS, 0, 8, 2048, 0, NULL,},
+#ifdef FEATURE_DIRECT_LINK
+	{ /* CE0 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, 8, 2048, 0,
+	 NULL,},
 #else
 	{ /* CE0 */ CE_ATTR_FLAGS, 0, 16, 2048, 0, NULL,},
 #endif
@@ -1591,8 +1592,9 @@ static struct CE_attr host_ce_config_wlan_kiwi[] = {
 	/* target -> host PKTLOG */
 	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,},
 #else
-#ifdef FEATURE_XPAN
-	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 256, 32, NULL,},
+#ifdef FEATURE_DIRECT_LINK
+	{ /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, 0, 256, 32,
+	 NULL,},
 #else
 	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 0, NULL,},
 #endif
@@ -1632,7 +1634,7 @@ static struct CE_pipe_config target_ce_config_wlan_kiwi[] = {
 	/* Target -> host PKTLOG */
 	{ /* CE5 */ 5, PIPEDIR_IN,  32, 2048, CE_ATTR_FLAGS, 0,},
 #else
-#ifdef FEATURE_XPAN
+#ifdef FEATURE_DIRECT_LINK
 	{ /* CE5 */ 5, PIPEDIR_IN,  16, 256, CE_ATTR_FLAGS, 0,},
 #else
 	{ /* CE5 */ 5, PIPEDIR_IN,  0, 2048, CE_ATTR_FLAGS, 0,},

+ 21 - 2
hif/src/ce/ce_main.c

@@ -1133,7 +1133,7 @@ static struct service_to_pipe target_service_to_ce_map_kiwi[] = {
 	{ WMI_DATA_VI_SVC, PIPEDIR_IN, 2, },
 	{ WMI_CONTROL_SVC, PIPEDIR_OUT, 3, },
 	{ WMI_CONTROL_SVC, PIPEDIR_IN, 2, },
-#ifdef FEATURE_XPAN
+#ifdef FEATURE_DIRECT_LINK
 	{ HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 4, },
 #else
 	{ HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, },
@@ -1144,7 +1144,7 @@ static struct service_to_pipe target_service_to_ce_map_kiwi[] = {
 #ifdef WLAN_FEATURE_WMI_DIAG_OVER_CE7
 	{ WMI_CONTROL_DIAG_SVC, PIPEDIR_IN, 7, },
 #endif
-#ifdef FEATURE_XPAN
+#ifdef FEATURE_DIRECT_LINK
 	{ LPASS_DATA_MSG_SVC, PIPEDIR_OUT, 0, },
 	{ LPASS_DATA_MSG_SVC, PIPEDIR_IN, 5, },
 #endif
@@ -5304,4 +5304,23 @@ void hif_log_ce_info(struct hif_softc *scn, uint8_t *data,
 	qdf_mem_copy(data + *offset, &info, size);
 	*offset = *offset + size;
 }
+
+#ifdef FEATURE_DIRECT_LINK
+QDF_STATUS
+hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
+			   uint64_t addr, uint32_t data)
+{
+	struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn);
+	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+
+	if (hif_state->ce_services->ce_set_irq_config_by_ceid)
+		return hif_state->ce_services->ce_set_irq_config_by_ceid(
+									hif_ctx,
+									ce_id,
+									addr,
+									data);
+
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
 #endif

+ 61 - 0
hif/src/ce/ce_service_srng.c

@@ -1097,6 +1097,64 @@ int ce_get_index_info_srng(struct hif_softc *scn, void *ce_state,
 }
 #endif
 
+#ifdef FEATURE_DIRECT_LINK
+/**
+ * ce_set_srng_msi_irq_config_by_ceid(): Set srng MSI irq configuration for CE
+ *  given by id
+ * @scn: HIF Context
+ * @ce_state: CE opaque handle
+ * @info: CE info
+ *
+ * Return: 0 for success and non zero for failure
+ */
+static QDF_STATUS
+ce_set_srng_msi_irq_config_by_ceid(struct hif_softc *scn, uint8_t ce_id,
+				   uint64_t addr, uint32_t data)
+{
+	struct CE_state *ce_state;
+	hal_ring_handle_t ring_hdl;
+	struct hal_srng_params ring_params = {0};
+
+	ce_state = scn->ce_id_to_state[ce_id];
+	if (!ce_state)
+		return QDF_STATUS_E_NOSUPPORT;
+
+	ring_params.msi_addr = addr;
+	ring_params.msi_data = data;
+
+	if (ce_state->src_ring) {
+		ring_hdl = ce_state->src_ring->srng_ctx;
+
+		ring_params.intr_timer_thres_us = 0;
+		ring_params.intr_batch_cntr_thres_entries = 1;
+		ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER;
+	} else if (ce_state->dest_ring) {
+		ring_hdl = ce_state->status_ring->srng_ctx;
+
+		ce_status_ring_config_int_threshold(scn, &ring_params);
+
+		hal_srng_set_msi_irq_config(scn->hal_soc, ring_hdl,
+					    &ring_params);
+
+		if (ce_is_status_ring_timer_thresh_war_needed()) {
+			ce_srng_initialize_dest_timer_interrupt_war(
+					ce_state->dest_ring, &ring_params);
+		} else {
+			ce_srng_initialize_dest_ring_thresh(ce_state->dest_ring,
+							    &ring_params);
+		}
+		ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER;
+		ring_hdl = ce_state->dest_ring->srng_ctx;
+	} else {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	hal_srng_set_msi_irq_config(scn->hal_soc, ring_hdl, &ring_params);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 static struct ce_ops ce_service_srng = {
 	.ce_get_desc_size = ce_get_desc_size_srng,
 	.ce_ring_setup = ce_ring_setup_srng,
@@ -1122,6 +1180,9 @@ static struct ce_ops ce_service_srng = {
 	.ce_get_index_info =
 		ce_get_index_info_srng,
 #endif
+#ifdef FEATURE_DIRECT_LINK
+	.ce_set_irq_config_by_ceid = ce_set_srng_msi_irq_config_by_ceid,
+#endif
 };
 
 struct ce_ops *ce_services_srng()