qcacmn: Use pld msi allocation for CE
Use the msi vectors allocated by the platform driver for the copy engine interrupts. Change-Id: I3fa96daa3222524ffe31659c12b3c0f5a2725e18 CRs-Fixed: 1093364
This commit is contained in:

committed by
qcabuildsw

parent
9e2bb31af7
commit
15010778ea
@@ -28,6 +28,7 @@
|
||||
#include "hif_main.h"
|
||||
#include "hif_debug.h"
|
||||
#include "hal_api.h"
|
||||
#include "pld_common.h"
|
||||
|
||||
/*
|
||||
* Support for Copy Engine hardware, which is mainly used for
|
||||
@@ -584,11 +585,47 @@ uint32_t ce_get_desc_size_srng(uint8_t ring_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ce_srng_msi_ring_params_setup(struct hif_softc *scn, uint32_t ce_id,
|
||||
struct hal_srng_params *ring_params)
|
||||
{
|
||||
uint32_t addr_low;
|
||||
uint32_t addr_high;
|
||||
uint32_t msi_data_start;
|
||||
uint32_t msi_data_count;
|
||||
uint32_t msi_irq_start;
|
||||
int ret;
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
HIF_INFO("%s: ce_id %d, msi_start: %d, msi_count %d", __func__, ce_id,
|
||||
msi_data_start, msi_data_count);
|
||||
|
||||
pld_get_msi_address(scn->qdf_dev->dev, &addr_low, &addr_high);
|
||||
|
||||
ring_params->msi_addr = addr_low;
|
||||
ring_params->msi_addr |= (qdf_dma_addr_t)(((uint64_t)addr_high) << 32);
|
||||
ring_params->msi_data = (ce_id % msi_data_count) + msi_data_start;
|
||||
ring_params->flags |= HAL_SRNG_MSI_INTR;
|
||||
|
||||
HIF_INFO("%s: ce_id %d, msi_addr %p, msi_data %d", __func__, ce_id,
|
||||
(void *)ring_params->msi_addr, ring_params->msi_data);
|
||||
}
|
||||
|
||||
void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
|
||||
struct CE_ring_state *src_ring)
|
||||
{
|
||||
struct hal_srng_params ring_params = {0};
|
||||
|
||||
HIF_INFO("%s: ce_id %d", __func__, ce_id);
|
||||
|
||||
ce_srng_msi_ring_params_setup(scn, ce_id, &ring_params);
|
||||
|
||||
ring_params.ring_base_paddr = src_ring->base_addr_CE_space;
|
||||
ring_params.ring_base_vaddr = src_ring->base_addr_owner_space;
|
||||
ring_params.num_entries = src_ring->nentries;
|
||||
@@ -617,6 +654,10 @@ void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
|
||||
{
|
||||
struct hal_srng_params ring_params = {0};
|
||||
|
||||
HIF_INFO("%s: ce_id %d", __func__, ce_id);
|
||||
|
||||
ce_srng_msi_ring_params_setup(scn, ce_id, &ring_params);
|
||||
|
||||
ring_params.ring_base_paddr = dest_ring->base_addr_CE_space;
|
||||
ring_params.ring_base_vaddr = dest_ring->base_addr_owner_space;
|
||||
ring_params.num_entries = dest_ring->nentries;
|
||||
@@ -640,6 +681,10 @@ void ce_srng_status_ring_setup(struct hif_softc *scn, uint32_t ce_id,
|
||||
{
|
||||
struct hal_srng_params ring_params = {0};
|
||||
|
||||
HIF_INFO("%s: ce_id %d", __func__, ce_id);
|
||||
|
||||
ce_srng_msi_ring_params_setup(scn, ce_id, &ring_params);
|
||||
|
||||
ring_params.ring_base_paddr = status_ring->base_addr_CE_space;
|
||||
ring_params.ring_base_vaddr = status_ring->base_addr_owner_space;
|
||||
ring_params.num_entries = status_ring->nentries;
|
||||
|
@@ -2546,6 +2546,38 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hif_ce_srng_msi_free_irq(struct hif_softc *scn)
|
||||
{
|
||||
int ret;
|
||||
int ce_id, irq;
|
||||
uint32_t msi_data_start;
|
||||
uint32_t msi_data_count;
|
||||
uint32_t msi_irq_start;
|
||||
struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn);
|
||||
|
||||
ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE",
|
||||
&msi_data_count, &msi_data_start,
|
||||
&msi_irq_start);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* needs to match the ce_id -> irq data mapping
|
||||
* used in the srng parameter configuration
|
||||
*/
|
||||
for (ce_id = 0; ce_id < scn->ce_count; ce_id++) {
|
||||
unsigned int msi_data;
|
||||
msi_data = (ce_id % msi_data_count) + msi_irq_start;
|
||||
irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data);
|
||||
|
||||
HIF_INFO("%s: (ce_id %d, msi_data %d, irq %d)", __func__,
|
||||
ce_id, msi_data, irq);
|
||||
|
||||
free_irq(irq, &ce_sc->tasklets[ce_id]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_nointrs(): disable IRQ
|
||||
*
|
||||
@@ -2557,13 +2589,15 @@ end:
|
||||
*/
|
||||
void hif_pci_nointrs(struct hif_softc *scn)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
|
||||
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
|
||||
|
||||
if (scn->request_irq_done == false)
|
||||
return;
|
||||
if (sc->num_msi_intrs > 0) {
|
||||
|
||||
ret = hif_ce_srng_msi_free_irq(scn);
|
||||
if (ret != 0 && sc->num_msi_intrs > 0) {
|
||||
/* MSI interrupt(s) */
|
||||
for (i = 0; i < sc->num_msi_intrs; i++) {
|
||||
free_irq(sc->irq + i, sc);
|
||||
@@ -3510,6 +3544,63 @@ int hif_ahb_configure_irq(struct hif_pci_softc *sc)
|
||||
}
|
||||
#endif
|
||||
|
||||
irqreturn_t hif_ce_interrupt_handler(int irq, void *context)
|
||||
{
|
||||
struct ce_tasklet_entry *tasklet_entry = context;
|
||||
return ce_dispatch_interrupt(tasklet_entry->ce_id, tasklet_entry);
|
||||
}
|
||||
extern const char *ce_name[];
|
||||
|
||||
static int hif_ce_srng_msi_request_irq(struct hif_softc *scn)
|
||||
{
|
||||
int ret;
|
||||
int ce_id, irq;
|
||||
uint32_t msi_data_start;
|
||||
uint32_t msi_data_count;
|
||||
uint32_t msi_irq_start;
|
||||
struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn);
|
||||
|
||||
ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE",
|
||||
&msi_data_count, &msi_data_start,
|
||||
&msi_irq_start);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* needs to match the ce_id -> irq data mapping
|
||||
* used in the srng parameter configuration
|
||||
*/
|
||||
for (ce_id = 0; ce_id < scn->ce_count; ce_id++) {
|
||||
unsigned int msi_data = (ce_id % msi_data_count) +
|
||||
msi_irq_start;
|
||||
irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data);
|
||||
|
||||
HIF_INFO("%s: (ce_id %d, msi_data %d, irq %d tasklet %p)",
|
||||
__func__, ce_id, msi_data, irq,
|
||||
&ce_sc->tasklets[ce_id]);
|
||||
ret = request_irq(irq, hif_ce_interrupt_handler,
|
||||
IRQF_SHARED,
|
||||
ce_name[ce_id],
|
||||
&ce_sc->tasklets[ce_id]);
|
||||
if (ret)
|
||||
goto free_irq;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
free_irq:
|
||||
/* the request_irq for the last ce_id failed so skip it. */
|
||||
while (ce_id > 0 && ce_id < scn->ce_count) {
|
||||
unsigned int msi_data;
|
||||
|
||||
ce_id--;
|
||||
msi_data = (ce_id % msi_data_count) + msi_data_start;
|
||||
irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data);
|
||||
free_irq(irq, &ce_sc->tasklets[ce_id]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_configure_irq() - configure interrupt
|
||||
*
|
||||
@@ -3529,6 +3620,11 @@ int hif_configure_irq(struct hif_softc *scn)
|
||||
|
||||
hif_init_reschedule_tasklet_work(sc);
|
||||
|
||||
ret = hif_ce_srng_msi_request_irq(scn);
|
||||
if (ret == 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ENABLE_MSI) {
|
||||
ret = hif_configure_msi(sc);
|
||||
if (ret == 0)
|
||||
|
@@ -176,6 +176,28 @@ static inline void pld_intr_notify_q6(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int pld_get_user_msi_assignment(struct device *dev,
|
||||
char *user_name, int *num_vectors,
|
||||
uint32_t *user_base_data, uint32_t *base_vector)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* should not be called if pld_get_user_msi_assignment returns error */
|
||||
static inline int pld_get_msi_irq(struct device *dev, unsigned int vector)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* should not be called if pld_get_user_msi_assignment returns error */
|
||||
static inline void pld_get_msi_address(struct device *dev,
|
||||
uint32_t *msi_addr_low,
|
||||
uint32_t *msi_addr_high)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int pld_ce_request_irq(struct device *dev, unsigned int ce_id,
|
||||
irqreturn_t (*handler)(int, void *),
|
||||
unsigned long flags, const char *name,
|
||||
|
Reference in New Issue
Block a user