From 47808175d4427cbef3718ece3c1c4e2ab205f610 Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Fri, 6 May 2016 10:04:21 -0700 Subject: [PATCH] qcacmn: Use CE index register values during init Shadow registers and DDR are not guaranteed to reflect the actual copy engine register values before transactions are performed. Also adds debug code to verify that the register values make sense. Change-Id: Ied0352638765571545f92b2e0dc18b4ca7a399a7 CRs-Fixed: 1012744 --- hif/src/ce/ce_main.c | 39 +++++++++++++++++++++++++++++++++++---- hif/src/ce/ce_reg.h | 41 +++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 18580eda3ead..7cdc6a0212c3 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -381,6 +381,25 @@ bool ce_mark_datapath(struct CE_state *ce_state) return rc; } +/** + * ce_ring_test_initial_indexes() - tests the initial ce ring indexes + * @ce_id: ce in question + * @ring: ring state being examined + * @type: "src_ring" or "dest_ring" string for identifying the ring + * + * Warns on non-zero index values. + * Causes a kernel panic if the ring is not empty durring initialization. + */ +static void ce_ring_test_initial_indexes(int ce_id, struct CE_ring_state *ring, + char *type) +{ + if (ring->write_index != 0 || ring->sw_index != 0) + HIF_ERROR("ce %d, %s, initial sw_index = %d, initial write_index =%d", + ce_id, type, ring->sw_index, ring->write_index); + if (ring->write_index != ring->sw_index) + QDF_BUG(0); +} + /* * Initialize a Copy Engine based on caller-supplied attributes. * This may be called once to initialize both source and destination @@ -487,10 +506,16 @@ struct CE_handle *ce_init(struct hif_softc *scn, if (Q_TARGET_ACCESS_BEGIN(scn) < 0) goto error_target_access; src_ring->hw_index = - CE_SRC_RING_READ_IDX_GET(scn, ctrl_addr); + CE_SRC_RING_READ_IDX_GET_FROM_REGISTER(scn, + ctrl_addr); src_ring->sw_index = src_ring->hw_index; src_ring->write_index = - CE_SRC_RING_WRITE_IDX_GET(scn, ctrl_addr); + CE_SRC_RING_WRITE_IDX_GET_FROM_REGISTER(scn, + ctrl_addr); + + ce_ring_test_initial_indexes(CE_id, src_ring, + "src_ring"); + if (Q_TARGET_ACCESS_END(scn) < 0) goto error_target_access; @@ -629,9 +654,15 @@ struct CE_handle *ce_init(struct hif_softc *scn, if (Q_TARGET_ACCESS_BEGIN(scn) < 0) goto error_target_access; dest_ring->sw_index = - CE_DEST_RING_READ_IDX_GET(scn, ctrl_addr); + CE_DEST_RING_READ_IDX_GET_FROM_REGISTER(scn, + ctrl_addr); dest_ring->write_index = - CE_DEST_RING_WRITE_IDX_GET(scn, ctrl_addr); + CE_DEST_RING_WRITE_IDX_GET_FROM_REGISTER(scn, + ctrl_addr); + + ce_ring_test_initial_indexes(CE_id, dest_ring, + "dest_ring"); + if (Q_TARGET_ACCESS_END(scn) < 0) goto error_target_access; diff --git a/hif/src/ce/ce_reg.h b/hif/src/ce/ce_reg.h index 026e8a8c05a2..1fcf71510567 100644 --- a/hif/src/ce/ce_reg.h +++ b/hif/src/ce/ce_reg.h @@ -264,6 +264,11 @@ uint32_t DEBUG_CE_DEST_RING_READ_IDX_GET(struct hif_softc *scn, #define SRRI_FROM_DDR_ADDR(addr) ((*(addr)) & 0xFFFF) #define DRRI_FROM_DDR_ADDR(addr) (((*(addr))>>16) & 0xFFFF) +#define CE_SRC_RING_READ_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) \ + A_TARGET_READ(scn, (CE_ctrl_addr) + CURRENT_SRRI_ADDRESS) +#define CE_DEST_RING_READ_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) \ + A_TARGET_READ(scn, (CE_ctrl_addr) + CURRENT_DRRI_ADDRESS) + #ifdef ADRASTEA_RRI_ON_DDR #ifdef SHADOW_REG_DEBUG #define CE_SRC_RING_READ_IDX_GET_FROM_DDR(scn, CE_ctrl_addr)\ @@ -288,9 +293,9 @@ unsigned int hif_get_dst_ring_read_index(struct hif_softc *scn, hif_get_dst_ring_read_index(scn, CE_ctrl_addr) #else #define CE_SRC_RING_READ_IDX_GET(scn, CE_ctrl_addr) \ - A_TARGET_READ(scn, (CE_ctrl_addr) + CURRENT_SRRI_ADDRESS) + CE_SRC_RING_READ_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) #define CE_DEST_RING_READ_IDX_GET(scn, CE_ctrl_addr)\ - A_TARGET_READ(scn, (CE_ctrl_addr) + CURRENT_DRRI_ADDRESS) + CE_DEST_RING_READ_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) /** * if RRI on DDR is not enabled, get idx from ddr defaults to @@ -299,7 +304,6 @@ unsigned int hif_get_dst_ring_read_index(struct hif_softc *scn, */ #define CE_SRC_RING_READ_IDX_GET_FROM_DDR(scn, CE_ctrl_addr)\ A_TARGET_READ(scn, (CE_ctrl_addr) + CURRENT_SRRI_ADDRESS) - #endif #define CE_SRC_RING_BASE_ADDR_SET(scn, CE_ctrl_addr, addr) \ @@ -507,38 +511,35 @@ unsigned int hif_get_dst_ring_read_index(struct hif_softc *scn, #define CE0_BASE_ADDRESS (scn->target_ce_def->d_CE0_BASE_ADDRESS) #define CE1_BASE_ADDRESS (scn->target_ce_def->d_CE1_BASE_ADDRESS) + #ifdef ADRASTEA_SHADOW_REGISTERS - #define NUM_SHADOW_REGISTERS 24 - u32 shadow_sr_wr_ind_addr(struct hif_softc *scn, u32 ctrl_addr); u32 shadow_dst_wr_ind_addr(struct hif_softc *scn, u32 ctrl_addr); +#endif + + +#ifdef ADRASTEA_SHADOW_REGISTERS #define CE_SRC_RING_WRITE_IDX_SET(scn, CE_ctrl_addr, n) \ A_TARGET_WRITE(scn, shadow_sr_wr_ind_addr(scn, CE_ctrl_addr), n) - -#define CE_SRC_RING_WRITE_IDX_GET(scn, CE_ctrl_addr) \ - A_TARGET_READ(scn, shadow_sr_wr_ind_addr(scn, CE_ctrl_addr)) - #define CE_DEST_RING_WRITE_IDX_SET(scn, CE_ctrl_addr, n) \ A_TARGET_WRITE(scn, shadow_dst_wr_ind_addr(scn, CE_ctrl_addr), n) -#define CE_DEST_RING_WRITE_IDX_GET(scn, CE_ctrl_addr) \ - A_TARGET_READ(scn, shadow_dst_wr_ind_addr(scn, CE_ctrl_addr)) - #else #define CE_SRC_RING_WRITE_IDX_SET(scn, CE_ctrl_addr, n) \ A_TARGET_WRITE(scn, (CE_ctrl_addr) + SR_WR_INDEX_ADDRESS, (n)) - -#define CE_SRC_RING_WRITE_IDX_GET(scn, CE_ctrl_addr) \ - A_TARGET_READ(scn, (CE_ctrl_addr) + SR_WR_INDEX_ADDRESS) - #define CE_DEST_RING_WRITE_IDX_SET(scn, CE_ctrl_addr, n) \ A_TARGET_WRITE(scn, (CE_ctrl_addr) + DST_WR_INDEX_ADDRESS, (n)) - -#define CE_DEST_RING_WRITE_IDX_GET(scn, CE_ctrl_addr) \ - A_TARGET_READ(scn, (CE_ctrl_addr) + DST_WR_INDEX_ADDRESS) - #endif +/* The write index read is only needed durring initialization because + * we keep track of the index that was last written. Thus the register + * is the only hardware supported location to read the initial value from. + */ +#define CE_SRC_RING_WRITE_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) \ + A_TARGET_READ(scn, (CE_ctrl_addr) + SR_WR_INDEX_ADDRESS) +#define CE_DEST_RING_WRITE_IDX_GET_FROM_REGISTER(scn, CE_ctrl_addr) \ + A_TARGET_READ(scn, (CE_ctrl_addr) + DST_WR_INDEX_ADDRESS) + #endif /* __CE_REG_H__ */