Эх сурвалжийг харах

qcacmn: Add support to map generic shadow regs

Add apis to map generic registers to shadow region. Existing
logic includes mapping only srng based regs to the shadow
region.
Add support to map REO control regs and WBM2SW2 rel
ring HP reg address to the shadow region in case the direct
reg writes in IPA enable/disable autonomy fail due to UMAC
block being in a power collapsed state.
Shadow reg mapping for these regs is provided to FW during
init. Add stat shadow_reg_write_fail to track shadow reg
write failure and shadow_reg_write_succ to track successful
shadow writes.

Change-Id: I04790765a3de80047689657e2cad0b73123440b9
CRs-Fixed: 2790321
Nisha Menon 4 жил өмнө
parent
commit
a377301c78

+ 6 - 1
dp/wifi3.0/dp_ipa.c

@@ -31,6 +31,9 @@
 #include "dp_rx.h"
 #include "dp_rx.h"
 #include "dp_ipa.h"
 #include "dp_ipa.h"
 
 
+/* Ring index for WBM2SW2 release ring */
+#define IPA_TX_COMP_RING_IDX HAL_IPA_TX_COMP_RING_IDX
+
 /* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
 /* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
 #define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT            (2048)
 #define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT            (2048)
 
 
@@ -1766,7 +1769,9 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 	}
 	}
 
 
 	if (soc->ipa_first_tx_db_access) {
 	if (soc->ipa_first_tx_db_access) {
-		hal_srng_dst_init_hp(wbm_srng, ipa_res->tx_comp_doorbell_vaddr);
+		hal_srng_dst_init_hp(
+			soc->hal_soc, wbm_srng,
+			ipa_res->tx_comp_doorbell_vaddr);
 		soc->ipa_first_tx_db_access = false;
 		soc->ipa_first_tx_db_access = false;
 	}
 	}
 
 

+ 0 - 1
dp/wifi3.0/dp_ipa.h

@@ -21,7 +21,6 @@
 #ifdef IPA_OFFLOAD
 #ifdef IPA_OFFLOAD
 
 
 #define DP_IPA_MAX_IFACE	3
 #define DP_IPA_MAX_IFACE	3
-#define IPA_TX_COMP_RING_IDX	2
 #define IPA_REO_DEST_RING_IDX	3
 #define IPA_REO_DEST_RING_IDX	3
 #define IPA_RX_REFILL_BUF_RING_IDX	2
 #define IPA_RX_REFILL_BUF_RING_IDX	2
 
 

+ 203 - 7
hal/wifi3.0/hal_api.h

@@ -27,6 +27,9 @@
 #include "hif_io32.h"
 #include "hif_io32.h"
 #include "qdf_platform.h"
 #include "qdf_platform.h"
 
 
+/* Ring index for WBM2SW2 release ring */
+#define HAL_IPA_TX_COMP_RING_IDX 2
+
 /* calculate the register address offset from bar0 of shadow register x */
 /* calculate the register address offset from bar0 of shadow register x */
 #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490)
 #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490)
 #define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x000008FC
 #define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x000008FC
@@ -597,6 +600,135 @@ uint32_t hal_read32_mb_cmem(struct hal_soc *hal_soc, uint32_t offset)
 }
 }
 #endif
 #endif
 
 
+#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+/* To check shadow config index range between 0..31 */
+#define HAL_SHADOW_REG_INDEX_LOW 32
+/* To check shadow config index range between 32..39 */
+#define HAL_SHADOW_REG_INDEX_HIGH 40
+/* Dirty bit reg offsets corresponding to shadow config index */
+#define HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET 0x30C8
+#define HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET 0x30C4
+/* PCIE_PCIE_TOP base addr offset */
+#define HAL_PCIE_PCIE_TOP_WRAPPER 0x01E00000
+/* Max retry attempts to read the dirty bit reg */
+#ifdef HAL_CONFIG_SLUB_DEBUG_ON
+#define HAL_SHADOW_DIRTY_BIT_POLL_MAX 10000
+#else
+#define HAL_SHADOW_DIRTY_BIT_POLL_MAX 2000
+#endif
+/* Delay in usecs for polling dirty bit reg */
+#define HAL_SHADOW_DIRTY_BIT_POLL_DELAY 5
+
+/**
+ * hal_poll_dirty_bit_reg() - Poll dirty register bit to confirm
+ * write was successful
+ * @hal_soc: hal soc handle
+ * @shadow_config_index: index of shadow reg used to confirm
+ * write
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS hal_poll_dirty_bit_reg(struct hal_soc *hal,
+						int shadow_config_index)
+{
+	uint32_t read_value = 0;
+	int retry_cnt = 0;
+	uint32_t reg_offset = 0;
+
+	if (shadow_config_index > 0 &&
+	    shadow_config_index < HAL_SHADOW_REG_INDEX_LOW) {
+		reg_offset =
+			HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET;
+	} else if (shadow_config_index >= HAL_SHADOW_REG_INDEX_LOW &&
+		   shadow_config_index < HAL_SHADOW_REG_INDEX_HIGH) {
+		reg_offset =
+			HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET;
+	} else {
+		hal_err("Invalid shadow_config_index = %d",
+			shadow_config_index);
+		return QDF_STATUS_E_INVAL;
+	}
+	while (retry_cnt < HAL_SHADOW_DIRTY_BIT_POLL_MAX) {
+		read_value = hal_read32_mb(
+				hal, HAL_PCIE_PCIE_TOP_WRAPPER + reg_offset);
+		/* Check if dirty bit corresponding to shadow_index is set */
+		if (read_value & BIT(shadow_config_index)) {
+			/* Dirty reg bit not reset */
+			qdf_udelay(HAL_SHADOW_DIRTY_BIT_POLL_DELAY);
+			retry_cnt++;
+		} else {
+			hal_debug("Shadow write: offset 0x%x read val 0x%x",
+				  reg_offset, read_value);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_E_TIMEOUT;
+}
+
+/**
+ * hal_write32_mb_shadow_confirm() - write to shadow reg and
+ * poll dirty register bit to confirm write
+ * @hal_soc: hal soc handle
+ * @reg_offset: target reg offset address from BAR
+ * @value: value to write
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static inline QDF_STATUS hal_write32_mb_shadow_confirm(
+	struct hal_soc *hal,
+	uint32_t reg_offset,
+	uint32_t value)
+{
+	int i;
+	QDF_STATUS ret;
+	uint32_t shadow_reg_offset;
+	uint32_t read_value;
+	int shadow_config_index;
+	bool is_reg_offset_present = false;
+
+	for (i = 0; i < MAX_GENERIC_SHADOW_REG; i++) {
+		/* Found the shadow config for the reg_offset */
+		struct shadow_reg_config *hal_shadow_reg_list =
+			&hal->list_shadow_reg_config[i];
+		if (hal_shadow_reg_list->target_register ==
+			reg_offset) {
+			shadow_config_index =
+				hal_shadow_reg_list->shadow_config_index;
+			shadow_reg_offset =
+				SHADOW_REGISTER(shadow_config_index);
+			hal_write32_mb_confirm(
+				hal, shadow_reg_offset, value);
+			is_reg_offset_present = true;
+			break;
+		}
+		ret = QDF_STATUS_E_FAILURE;
+	}
+	if (is_reg_offset_present) {
+		ret = hal_poll_dirty_bit_reg(hal, shadow_config_index);
+		read_value = hal_read32_mb(hal, reg_offset);
+		hal_info("Shadow retry:reg 0x%x val 0x%x readval 0x%x ret %d",
+			 reg_offset, value, read_value, ret);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			HAL_STATS_INC(hal, shadow_reg_write_fail, 1);
+			return ret;
+		}
+		HAL_STATS_INC(hal, shadow_reg_write_succ, 1);
+	}
+	return ret;
+}
+
+#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */
+
+static inline QDF_STATUS hal_write32_mb_shadow_confirm(
+	struct hal_soc *hal_soc,
+	uint32_t offset,
+	uint32_t value)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */
+
 /* Max times allowed for register writing retry */
 /* Max times allowed for register writing retry */
 #define HAL_REG_WRITE_RETRY_MAX		5
 #define HAL_REG_WRITE_RETRY_MAX		5
 /* Delay milliseconds for each time retry */
 /* Delay milliseconds for each time retry */
@@ -624,6 +756,7 @@ static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc,
 {
 {
 	uint8_t retry_cnt = 0;
 	uint8_t retry_cnt = 0;
 	uint32_t read_value;
 	uint32_t read_value;
+	QDF_STATUS ret;
 
 
 	while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) {
 	while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) {
 		hal_write32_mb_confirm(hal_soc, offset, value);
 		hal_write32_mb_confirm(hal_soc, offset, value);
@@ -638,8 +771,12 @@ static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc,
 		retry_cnt++;
 		retry_cnt++;
 	}
 	}
 
 
-	if (retry_cnt > HAL_REG_WRITE_RETRY_MAX && recovery)
-		qdf_trigger_self_recovery(NULL, QDF_HAL_REG_WRITE_FAILURE);
+	if (retry_cnt > HAL_REG_WRITE_RETRY_MAX) {
+		ret = hal_write32_mb_shadow_confirm(hal_soc, offset, value);
+		if (QDF_IS_STATUS_ERROR(ret) && recovery)
+			qdf_trigger_self_recovery(
+				NULL, QDF_HAL_REG_WRITE_FAILURE);
+	}
 }
 }
 
 
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE
@@ -889,12 +1026,13 @@ struct hal_srng_params {
 	uint32_t prefetch_timer;
 	uint32_t prefetch_timer;
 };
 };
 
 
-/* hal_construct_shadow_config() - initialize the shadow registers for dp rings
+/* hal_construct_srng_shadow_regs() - initialize the shadow
+ * registers for srngs
  * @hal_soc: hal handle
  * @hal_soc: hal handle
  *
  *
  * Return: QDF_STATUS_OK on success
  * Return: QDF_STATUS_OK on success
  */
  */
-extern QDF_STATUS hal_construct_shadow_config(void *hal_soc);
+QDF_STATUS hal_construct_srng_shadow_regs(void *hal_soc);
 
 
 /* hal_set_one_shadow_config() - add a config for the specified ring
 /* hal_set_one_shadow_config() - add a config for the specified ring
  * @hal_soc: hal handle
  * @hal_soc: hal handle
@@ -911,8 +1049,8 @@ extern QDF_STATUS hal_construct_shadow_config(void *hal_soc);
  *
  *
  * Return: QDF_STATUS_OK on success
  * Return: QDF_STATUS_OK on success
  */
  */
-extern QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type,
-					    int ring_num);
+QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type,
+				     int ring_num);
 /**
 /**
  * hal_get_shadow_config() - retrieve the config table
  * hal_get_shadow_config() - retrieve the config table
  * @hal_soc: hal handle
  * @hal_soc: hal handle
@@ -1012,10 +1150,13 @@ extern void hal_srng_dst_set_hp_paddr(struct hal_srng *sring, uint64_t paddr);
 
 
 /**
 /**
  * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer
  * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer
+ * @hal_soc: hal_soc handle
  * @srng: sring pointer
  * @srng: sring pointer
  * @vaddr: virtual address
  * @vaddr: virtual address
  */
  */
-extern void hal_srng_dst_init_hp(struct hal_srng *srng, uint32_t *vaddr);
+void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc,
+			  struct hal_srng *srng,
+			  uint32_t *vaddr);
 
 
 /**
 /**
  * hal_srng_cleanup - Deinitialize HW SRNG ring.
  * hal_srng_cleanup - Deinitialize HW SRNG ring.
@@ -2415,4 +2556,59 @@ static inline void hal_reo_set_err_dst_remap(hal_soc_handle_t hal_soc_hdl)
 	if (hal_soc->ops->hal_reo_set_err_dst_remap)
 	if (hal_soc->ops->hal_reo_set_err_dst_remap)
 		hal_soc->ops->hal_reo_set_err_dst_remap(hal_soc);
 		hal_soc->ops->hal_reo_set_err_dst_remap(hal_soc);
 }
 }
+
+#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+
+/**
+ * hal_set_one_target_reg_config() - Populate the target reg
+ * offset in hal_soc for one non srng related register at the
+ * given list index
+ * @hal_soc: hal handle
+ * @target_reg_offset: target register offset
+ * @list_index: index in hal list for shadow regs
+ *
+ * Return: none
+ */
+void hal_set_one_target_reg_config(struct hal_soc *hal,
+				   uint32_t target_reg_offset,
+				   int list_index);
+
+/**
+ * hal_set_shadow_regs() - Populate register offset for
+ * registers that need to be populated in list_shadow_reg_config
+ * in order to be sent to FW. These reg offsets will be mapped
+ * to shadow registers.
+ * @hal_soc: hal handle
+ *
+ * Return: QDF_STATUS_OK on success
+ */
+QDF_STATUS hal_set_shadow_regs(void *hal_soc);
+
+/**
+ * hal_construct_shadow_regs() - initialize the shadow registers
+ * for non-srng related register configs
+ * @hal_soc: hal handle
+ *
+ * Return: QDF_STATUS_OK on success
+ */
+QDF_STATUS hal_construct_shadow_regs(void *hal_soc);
+
+#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */
+static inline void hal_set_one_target_reg_config(
+	struct hal_soc *hal,
+	uint32_t target_reg_offset,
+	int list_index)
+{
+}
+
+static inline QDF_STATUS hal_set_shadow_regs(void *hal_soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS hal_construct_shadow_regs(void *hal_soc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */
 #endif /* _HAL_APIH_ */
 #endif /* _HAL_APIH_ */

+ 38 - 2
hal/wifi3.0/hal_internal.h

@@ -440,6 +440,26 @@ struct hal_hw_srng_config {
 };
 };
 
 
 #define MAX_SHADOW_REGISTERS 36
 #define MAX_SHADOW_REGISTERS 36
+#define MAX_GENERIC_SHADOW_REG 5
+
+/**
+ * struct shadow_reg_config - Hal soc structure that contains
+ * the list of generic shadow registers
+ * @target_register: target reg offset
+ * @shadow_config_index: shadow config index in shadow config
+ *				list sent to FW
+ * @va: virtual addr of shadow reg
+ *
+ * This structure holds the generic registers that are mapped to
+ * the shadow region and holds the mapping of the target
+ * register offset to shadow config index provided to FW during
+ * init
+ */
+struct shadow_reg_config {
+	uint32_t target_register;
+	int shadow_config_index;
+	uint64_t va;
+};
 
 
 /* REO parameters to be passed to hal_reo_setup */
 /* REO parameters to be passed to hal_reo_setup */
 struct hal_reo_params {
 struct hal_reo_params {
@@ -628,6 +648,8 @@ struct hal_hw_txrx_ops {
  * struct hal_soc_stats - Hal layer stats
  * struct hal_soc_stats - Hal layer stats
  * @reg_write_fail: number of failed register writes
  * @reg_write_fail: number of failed register writes
  * @wstats: delayed register write stats
  * @wstats: delayed register write stats
+ * @shadow_reg_write_fail: shadow reg write failure stats
+ * @shadow_reg_write_succ: shadow reg write success stats
  *
  *
  * This structure holds all the statistics at HAL layer.
  * This structure holds all the statistics at HAL layer.
  */
  */
@@ -636,6 +658,10 @@ struct hal_soc_stats {
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE
 	struct hal_reg_write_soc_stats wstats;
 	struct hal_reg_write_soc_stats wstats;
 #endif
 #endif
+#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+	uint32_t shadow_reg_write_fail;
+	uint32_t shadow_reg_write_succ;
+#endif
 };
 };
 
 
 #ifdef ENABLE_HAL_REG_WR_HISTORY
 #ifdef ENABLE_HAL_REG_WR_HISTORY
@@ -673,8 +699,13 @@ struct hal_reg_write_fail_history {
 #endif
 #endif
 
 
 /**
 /**
- * HAL context to be used to access SRNG APIs (currently used by data path
- * and transport (CE) modules)
+ * struct hal_soc - HAL context to be used to access SRNG APIs
+ *		    (currently used by data path and
+ *		    transport (CE) modules)
+ * @list_shadow_reg_config: array of generic regs mapped to
+ *			    shadow regs
+ * @num_generic_shadow_regs_configured: number of generic regs
+ *					mapped to shadow regs
  */
  */
 struct hal_soc {
 struct hal_soc {
 	/* HIF handle to access HW registers */
 	/* HIF handle to access HW registers */
@@ -741,6 +772,11 @@ struct hal_soc {
 	uint32_t read_idx;
 	uint32_t read_idx;
 #endif
 #endif
 	qdf_atomic_t active_work_cnt;
 	qdf_atomic_t active_work_cnt;
+#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+	struct shadow_reg_config
+		list_shadow_reg_config[MAX_GENERIC_SHADOW_REG];
+	int num_generic_shadow_regs_configured;
+#endif
 };
 };
 
 
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE
 #ifdef FEATURE_HAL_DELAYED_REG_WRITE

+ 86 - 5
hal/wifi3.0/hal_srng.c

@@ -161,6 +161,79 @@ static void hal_update_srng_hp_tp_address(struct hal_soc *hal_soc,
 
 
 }
 }
 
 
+#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
+void hal_set_one_target_reg_config(struct hal_soc *hal,
+				   uint32_t target_reg_offset,
+				   int list_index)
+{
+	int i = list_index;
+
+	qdf_assert_always(i < MAX_GENERIC_SHADOW_REG);
+	hal->list_shadow_reg_config[i].target_register =
+		target_reg_offset;
+	hal->num_generic_shadow_regs_configured++;
+}
+
+qdf_export_symbol(hal_set_one_target_reg_config);
+
+#define REO_R0_DESTINATION_RING_CTRL_ADDR_OFFSET 0x4
+#define MAX_REO_REMAP_SHADOW_REGS 4
+QDF_STATUS hal_set_shadow_regs(void *hal_soc)
+{
+	uint32_t target_reg_offset;
+	struct hal_soc *hal = (struct hal_soc *)hal_soc;
+	int i;
+	struct hal_hw_srng_config *srng_config =
+		&hal->hw_srng_table[WBM2SW_RELEASE];
+
+	target_reg_offset =
+		HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR(
+			SEQ_WCSS_UMAC_REO_REG_OFFSET);
+
+	for (i = 0; i < MAX_REO_REMAP_SHADOW_REGS; i++) {
+		hal_set_one_target_reg_config(hal, target_reg_offset, i);
+		target_reg_offset += REO_R0_DESTINATION_RING_CTRL_ADDR_OFFSET;
+	}
+
+	target_reg_offset = srng_config->reg_start[HP_OFFSET_IN_REG_START];
+	target_reg_offset += (srng_config->reg_size[HP_OFFSET_IN_REG_START]
+			      * HAL_IPA_TX_COMP_RING_IDX);
+
+	hal_set_one_target_reg_config(hal, target_reg_offset, i);
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(hal_set_shadow_regs);
+
+QDF_STATUS hal_construct_shadow_regs(void *hal_soc)
+{
+	struct hal_soc *hal = (struct hal_soc *)hal_soc;
+	int shadow_config_index = hal->num_shadow_registers_configured;
+	int i;
+	int num_regs = hal->num_generic_shadow_regs_configured;
+
+	for (i = 0; i < num_regs; i++) {
+		qdf_assert_always(shadow_config_index < MAX_SHADOW_REGISTERS);
+		hal->shadow_config[shadow_config_index].addr =
+			hal->list_shadow_reg_config[i].target_register;
+		hal->list_shadow_reg_config[i].shadow_config_index =
+			shadow_config_index;
+		hal->list_shadow_reg_config[i].va =
+			SHADOW_REGISTER(shadow_config_index) +
+			(uint64_t)hal->dev_base_addr;
+		hal_debug("target_reg %x, shadow register 0x%x shadow_index 0x%x",
+			  hal->shadow_config[shadow_config_index].addr,
+			  SHADOW_REGISTER(shadow_config_index),
+			  shadow_config_index);
+		shadow_config_index++;
+		hal->num_shadow_registers_configured++;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(hal_construct_shadow_regs);
+#endif
+
 QDF_STATUS hal_set_one_shadow_config(void *hal_soc,
 QDF_STATUS hal_set_one_shadow_config(void *hal_soc,
 				     int ring_type,
 				     int ring_type,
 				     int ring_num)
 				     int ring_num)
@@ -202,7 +275,7 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc,
 
 
 qdf_export_symbol(hal_set_one_shadow_config);
 qdf_export_symbol(hal_set_one_shadow_config);
 
 
-QDF_STATUS hal_construct_shadow_config(void *hal_soc)
+QDF_STATUS hal_construct_srng_shadow_regs(void *hal_soc)
 {
 {
 	int ring_type, ring_num;
 	int ring_type, ring_num;
 	struct hal_soc *hal = (struct hal_soc *)hal_soc;
 	struct hal_soc *hal = (struct hal_soc *)hal_soc;
@@ -227,7 +300,7 @@ QDF_STATUS hal_construct_shadow_config(void *hal_soc)
 	return QDF_STATUS_SUCCESS;
 	return QDF_STATUS_SUCCESS;
 }
 }
 
 
-qdf_export_symbol(hal_construct_shadow_config);
+qdf_export_symbol(hal_construct_srng_shadow_regs);
 
 
 void hal_get_shadow_config(void *hal_soc,
 void hal_get_shadow_config(void *hal_soc,
 	struct pld_shadow_reg_v2_cfg **shadow_config,
 	struct pld_shadow_reg_v2_cfg **shadow_config,
@@ -1015,18 +1088,26 @@ void hal_srng_dst_set_hp_paddr(struct hal_srng *srng,
 }
 }
 
 
 /**
 /**
- * hal_srng_dst_init_hp() - Initilaize destination ring head pointer
+ * hal_srng_dst_init_hp() - Initialize destination ring head
+ * pointer
+ * @hal_soc: hal_soc handle
  * @srng: sring pointer
  * @srng: sring pointer
  * @vaddr: virtual address
  * @vaddr: virtual address
  */
  */
-void hal_srng_dst_init_hp(struct hal_srng *srng,
+void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc,
+			  struct hal_srng *srng,
 			  uint32_t *vaddr)
 			  uint32_t *vaddr)
 {
 {
+	uint32_t reg_offset;
+	struct hal_soc *hal = (struct hal_soc *)hal_soc;
+
 	if (!srng)
 	if (!srng)
 		return;
 		return;
 
 
 	srng->u.dst_ring.hp_addr = vaddr;
 	srng->u.dst_ring.hp_addr = vaddr;
-	SRNG_DST_REG_WRITE_CONFIRM(srng, HP, srng->u.dst_ring.cached_hp);
+	reg_offset = SRNG_DST_ADDR(srng, HP) - hal->dev_base_addr;
+	HAL_REG_WRITE_CONFIRM_RETRY(
+		hal, reg_offset, srng->u.dst_ring.cached_hp, true);
 
 
 	if (vaddr) {
 	if (vaddr) {
 		*srng->u.dst_ring.hp_addr = srng->u.dst_ring.cached_hp;
 		*srng->u.dst_ring.hp_addr = srng->u.dst_ring.cached_hp;

+ 3 - 3
hif/src/ce/ce_service_srng.c

@@ -944,10 +944,10 @@ static void ce_prepare_shadow_register_v2_cfg_srng(struct hif_softc *scn,
 		/* return with original configuration*/
 		/* return with original configuration*/
 		return;
 		return;
 	}
 	}
-
-	hal_construct_shadow_config(scn->hal_soc);
+	hal_construct_srng_shadow_regs(scn->hal_soc);
 	ce_construct_shadow_config_srng(scn);
 	ce_construct_shadow_config_srng(scn);
-
+	hal_set_shadow_regs(scn->hal_soc);
+	hal_construct_shadow_regs(scn->hal_soc);
 	/* get updated configuration */
 	/* get updated configuration */
 	hal_get_shadow_config(scn->hal_soc, shadow_config,
 	hal_get_shadow_config(scn->hal_soc, shadow_config,
 			      num_shadow_registers_configured);
 			      num_shadow_registers_configured);

+ 2 - 2
hif/src/ipcie/if_ipci.h

@@ -53,9 +53,9 @@ struct hif_ipci_stats {
 };
 };
 
 
 /* Register to wake the UMAC from power collapse */
 /* Register to wake the UMAC from power collapse */
-#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG 0x4040
+#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
 /* Register used for handshake mechanism to validate UMAC is awake */
 /* Register used for handshake mechanism to validate UMAC is awake */
-#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG 0x3004
+#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004)
 /* Timeout duration to validate UMAC wake status */
 /* Timeout duration to validate UMAC wake status */
 #ifdef HAL_CONFIG_SLUB_DEBUG_ON
 #ifdef HAL_CONFIG_SLUB_DEBUG_ON
 #define FORCE_WAKE_DELAY_TIMEOUT_MS 500
 #define FORCE_WAKE_DELAY_TIMEOUT_MS 500

+ 23 - 6
hif/src/pcie/if_pci.c

@@ -3647,6 +3647,28 @@ int hif_force_wake_request(struct hif_opaque_softc *hif_handle)
 	return 0;
 	return 0;
 }
 }
 
 
+int hif_force_wake_release(struct hif_opaque_softc *hif_handle)
+{
+	int ret;
+	struct hif_softc *scn = (struct hif_softc *)hif_handle;
+	struct hif_pci_softc *pci_scn = HIF_GET_PCI_SOFTC(scn);
+
+	ret = pld_force_wake_release(scn->qdf_dev->dev);
+	if (ret) {
+		hif_err("force wake release failure");
+		HIF_STATS_INC(pci_scn, mhi_force_wake_release_failure, 1);
+		return ret;
+	}
+
+	HIF_STATS_INC(pci_scn, mhi_force_wake_release_success, 1);
+	hif_write32_mb(scn,
+		       scn->mem +
+		       PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG,
+		       0);
+	HIF_STATS_INC(pci_scn, soc_force_wake_release_success, 1);
+	return 0;
+}
+
 #else /* DEVICE_FORCE_WAKE_ENABLE */
 #else /* DEVICE_FORCE_WAKE_ENABLE */
 /** hif_force_wake_request() - Disable the PCIE scratch register
 /** hif_force_wake_request() - Disable the PCIE scratch register
  * write/read
  * write/read
@@ -3683,7 +3705,6 @@ int hif_force_wake_request(struct hif_opaque_softc *hif_handle)
 
 
 	return 0;
 	return 0;
 }
 }
-#endif /* DEVICE_FORCE_WAKE_ENABLE */
 
 
 int hif_force_wake_release(struct hif_opaque_softc *hif_handle)
 int hif_force_wake_release(struct hif_opaque_softc *hif_handle)
 {
 {
@@ -3699,13 +3720,9 @@ int hif_force_wake_release(struct hif_opaque_softc *hif_handle)
 	}
 	}
 
 
 	HIF_STATS_INC(pci_scn, mhi_force_wake_release_success, 1);
 	HIF_STATS_INC(pci_scn, mhi_force_wake_release_success, 1);
-	hif_write32_mb(scn,
-		       scn->mem +
-		       PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG,
-		       0);
-	HIF_STATS_INC(pci_scn, soc_force_wake_release_success, 1);
 	return 0;
 	return 0;
 }
 }
+#endif /* DEVICE_FORCE_WAKE_ENABLE */
 
 
 void hif_print_pci_stats(struct hif_pci_softc *pci_handle)
 void hif_print_pci_stats(struct hif_pci_softc *pci_handle)
 {
 {

+ 2 - 2
hif/src/pcie/if_pci.h

@@ -32,9 +32,9 @@
 
 
 #ifdef FORCE_WAKE
 #ifdef FORCE_WAKE
 /* Register to wake the UMAC from power collapse */
 /* Register to wake the UMAC from power collapse */
-#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG 0x4040
+#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
 /* Register used for handshake mechanism to validate UMAC is awake */
 /* Register used for handshake mechanism to validate UMAC is awake */
-#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG 0x3004
+#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004)
 /* Timeout duration to validate UMAC wake status */
 /* Timeout duration to validate UMAC wake status */
 #ifdef HAL_CONFIG_SLUB_DEBUG_ON
 #ifdef HAL_CONFIG_SLUB_DEBUG_ON
 #define FORCE_WAKE_DELAY_TIMEOUT_MS 500
 #define FORCE_WAKE_DELAY_TIMEOUT_MS 500