qcacmn: Add delayed register write support in HAL

In case the bus is in low power mode, the register writes (followed by a
memory barrier) may take a long time (~4ms). This can cause the caller
to block till the PCIe write is completed. Thus, even though PCI
writes are posted, it can still block the caller.

Hence, in case the bus is in low power mode (not in M0), or not in high
throughput scenarios, queue the register write in a workqueue. The
register write will happen in the delayed work context. In other cases,
i.e ,when the bus is not in low power mode or in high thoughput
scenarios, do the register writes in caller context.

Change-Id: Idf218e4581545bc6ac67b91d0f70d495387ca90e
CRs-Fixed: 2602029
This commit is contained in:
Mohit Khanna
2020-02-07 11:40:13 -08:00
committed by nshrivas
parent d5a7a4ca89
commit b4429e8278
6 changed files with 525 additions and 7 deletions

View File

@@ -438,10 +438,29 @@ void hal_write_address_32_mb(struct hal_soc *hal_soc,
}
#ifdef DP_HAL_MULTIWINDOW_DIRECT_ACCESS
#define hal_srng_write_address_32_mb(_a, _b, _c) qdf_iowrite32(_b, _c)
static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
qdf_iowrite32(addr, value);
}
#elif defined(FEATURE_HAL_DELAYED_WRITE)
static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
hal_delayed_reg_write(hal_soc, srng, addr, value);
}
#else
#define hal_srng_write_address_32_mb(_a, _b, _c) \
hal_write_address_32_mb(_a, _b, _c)
static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
hal_write_address_32_mb(hal_soc, addr, value);
}
#endif
#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \
@@ -467,8 +486,7 @@ void hal_write_address_32_mb(struct hal_soc *hal_soc,
*
* Return: < 0 for failure/>= 0 for success
*/
static inline
uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
{
uint32_t ret;
unsigned long flags;
@@ -536,6 +554,32 @@ uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset)
}
#endif
#ifdef FEATURE_HAL_DELAYED_REG_WRITE
/**
* hal_dump_reg_write_srng_stats() - dump SRNG reg write stats
* @hal_soc: HAL soc handle
*
* Return: none
*/
void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl);
/**
* hal_dump_reg_write_stats() - dump reg write stats
* @hal_soc: HAL soc handle
*
* Return: none
*/
void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl);
#else
static inline void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl)
{
}
static inline void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl)
{
}
#endif
/**
* hal_read_address_32_mb() - Read 32-bit value from the register
* @soc: soc handle
@@ -1425,10 +1469,12 @@ hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
} else {
if (srng->ring_dir == HAL_SRNG_SRC_RING)
hal_srng_write_address_32_mb(hal_soc,
srng,
srng->u.src_ring.hp_addr,
srng->u.src_ring.hp);
else
hal_srng_write_address_32_mb(hal_soc,
srng,
srng->u.dst_ring.tp_addr,
srng->u.dst_ring.tp);
}