From e2286220349851f182284d25c2457002d595dbaa Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Fri, 4 Nov 2022 00:59:05 +0530 Subject: [PATCH] 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 --- hal/wifi3.0/hal_api.h | 29 +++++++++++ hal/wifi3.0/hal_generic_api.h | 91 +++++++++++++++++++++++++++++++++++ hal/wifi3.0/hal_internal.h | 4 ++ hal/wifi3.0/kiwi/hal_kiwi.c | 3 ++ hif/inc/hif.h | 21 ++++++++ hif/src/ce/ce_api.h | 5 ++ hif/src/ce/ce_assignment.h | 12 +++-- hif/src/ce/ce_main.c | 23 ++++++++- hif/src/ce/ce_service_srng.c | 61 +++++++++++++++++++++++ 9 files changed, 242 insertions(+), 7 deletions(-) diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 1cda41320e..98f11383ca 100644 --- a/hal/wifi3.0/hal_api.h +++ b/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_ */ diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 8dea3921a6..93a6c5320b 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/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_ */ diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index fba8d52f20..a040887a64 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/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 }; /** diff --git a/hal/wifi3.0/kiwi/hal_kiwi.c b/hal/wifi3.0/kiwi/hal_kiwi.c index 35af63478e..6318758b22 100644 --- a/hal/wifi3.0/kiwi/hal_kiwi.c +++ b/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[] = { diff --git a/hif/inc/hif.h b/hif/inc/hif.h index ec7c4cbb6d..2b1f19dad8 100644 --- a/hif/inc/hif.h +++ b/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_ */ diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h index a73b69c19f..a85f88080b 100644 --- a/hif/src/ce/ce_api.h +++ b/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); diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h index 8632ca024b..4f78074313 100644 --- a/hif/src/ce/ce_assignment.h +++ b/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,}, diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 3126d81f1c..4f3dff1ac4 100644 --- a/hif/src/ce/ce_main.c +++ b/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 diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 0e9d03f78b..514712f432 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/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()