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
This commit is contained in:
Yeshwanth Sriram Guntuka
2022-11-04 00:59:05 +05:30
committed by Madan Koyyalamudi
parent 99615e170d
commit e228622034
9 changed files with 242 additions and 7 deletions

View File

@@ -3387,4 +3387,33 @@ uint16_t hal_srng_dst_get_hpidx(hal_ring_handle_t hal_ring_hdl)
return hp / srng->entry_size; 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_ */ #endif /* _HAL_APIH_ */

View File

@@ -571,4 +571,95 @@ static inline void hal_srng_hw_reg_offset_init_generic(struct hal_soc *hal_soc)
#endif #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_ */ #endif /* HAL_GENERIC_API_H_ */

View File

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

View File

@@ -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_get_tsf_time = hal_get_tsf_time_kiwi;
hal_soc->ops->hal_rx_reo_ent_get_src_link_id = hal_soc->ops->hal_rx_reo_ent_get_src_link_id =
hal_rx_reo_ent_get_src_link_id_kiwi; 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[] = { struct hal_hw_srng_config hw_srng_table_kiwi[] = {

View File

@@ -2437,4 +2437,25 @@ QDF_STATUS hif_unregister_umac_reset_handler(struct hif_opaque_softc *hif_scn)
#endif /* DP_UMAC_HW_RESET_SUPPORT */ #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_ */ #endif /* _HIF_H_ */

View File

@@ -597,6 +597,11 @@ struct ce_ops {
struct pld_shadow_reg_v3_cfg **shadow_config, struct pld_shadow_reg_v3_cfg **shadow_config,
int *num_shadow_registers_configured); int *num_shadow_registers_configured);
#endif #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); int hif_ce_bus_early_suspend(struct hif_softc *scn);

View File

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

View File

@@ -1133,7 +1133,7 @@ static struct service_to_pipe target_service_to_ce_map_kiwi[] = {
{ WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, },
{ WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, },
{ WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, { WMI_CONTROL_SVC, PIPEDIR_IN, 2, },
#ifdef FEATURE_XPAN #ifdef FEATURE_DIRECT_LINK
{ HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 4, }, { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 4, },
#else #else
{ HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, { 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 #ifdef WLAN_FEATURE_WMI_DIAG_OVER_CE7
{ WMI_CONTROL_DIAG_SVC, PIPEDIR_IN, 7, }, { WMI_CONTROL_DIAG_SVC, PIPEDIR_IN, 7, },
#endif #endif
#ifdef FEATURE_XPAN #ifdef FEATURE_DIRECT_LINK
{ LPASS_DATA_MSG_SVC, PIPEDIR_OUT, 0, }, { LPASS_DATA_MSG_SVC, PIPEDIR_OUT, 0, },
{ LPASS_DATA_MSG_SVC, PIPEDIR_IN, 5, }, { LPASS_DATA_MSG_SVC, PIPEDIR_IN, 5, },
#endif #endif
@@ -5304,4 +5304,23 @@ void hif_log_ce_info(struct hif_softc *scn, uint8_t *data,
qdf_mem_copy(data + *offset, &info, size); qdf_mem_copy(data + *offset, &info, size);
*offset = *offset + 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 #endif

View File

@@ -1097,6 +1097,64 @@ int ce_get_index_info_srng(struct hif_softc *scn, void *ce_state,
} }
#endif #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 = { static struct ce_ops ce_service_srng = {
.ce_get_desc_size = ce_get_desc_size_srng, .ce_get_desc_size = ce_get_desc_size_srng,
.ce_ring_setup = ce_ring_setup_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 =
ce_get_index_info_srng, ce_get_index_info_srng,
#endif #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() struct ce_ops *ce_services_srng()