qcacmn: Fix NOC issue for PCIE select window fail
Select window failed sometimes, then following register writing by offset leaded to NOC error. PCIe local register space is mapped to BAR0 lower address, don't need select window when write wake up umac register. Add read back to confirm select window register writing passed through. Change-Id: Iaa5359722e9b7a3434efd1a819a951ce6c8d3f4f CRs-Fixed: 2952127
This commit is contained in:

committed by
Madan Koyyalamudi

parent
e49edb3186
commit
2a7b60ac61
@@ -143,29 +143,56 @@ bool hif_target_access_allowed(struct hif_softc *scn)
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_util.h"
|
||||
|
||||
/**
|
||||
* hif_reg_write_result_check() - check register writing result
|
||||
* @sc: hif pcie context
|
||||
* @offset: register offset to read
|
||||
* @exp_val: the expected value of register
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void hif_reg_write_result_check(struct hif_pci_softc *sc,
|
||||
uint32_t offset,
|
||||
uint32_t exp_val)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = qdf_ioread32(sc->mem + offset);
|
||||
if (exp_val != value) {
|
||||
hif_err("Reg write failed. write val 0x%x read val 0x%x offset 0x%x",
|
||||
exp_val,
|
||||
value,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PCIE_REG_WINDOW_LOCAL_NO_CACHE
|
||||
/**
|
||||
* hif_select_window(): Update the register window
|
||||
* hif_select_window_confirm(): Update the register window
|
||||
* @sc: HIF pci handle
|
||||
* @offset: reg offset to read from or write to
|
||||
*
|
||||
* Calculate the window using the offset provided and update
|
||||
* the window reg value accordingly for windowed read/write reg
|
||||
* access.
|
||||
*
|
||||
* Read back to make sure the window is written to the register.
|
||||
* Return: None
|
||||
*/
|
||||
static inline void hif_select_window(struct hif_pci_softc *sc, uint32_t offset)
|
||||
static inline
|
||||
void hif_select_window_confirm(struct hif_pci_softc *sc, uint32_t offset)
|
||||
{
|
||||
uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK;
|
||||
|
||||
qdf_iowrite32(sc->mem + WINDOW_REG_ADDRESS,
|
||||
WINDOW_ENABLE_BIT | window);
|
||||
sc->register_window = window;
|
||||
hif_reg_write_result_check(sc, WINDOW_REG_ADDRESS,
|
||||
WINDOW_ENABLE_BIT | window);
|
||||
}
|
||||
#else /* PCIE_REG_WINDOW_LOCAL_NO_CACHE */
|
||||
|
||||
static inline void hif_select_window(struct hif_pci_softc *sc, uint32_t offset)
|
||||
static inline
|
||||
void hif_select_window_confirm(struct hif_pci_softc *sc, uint32_t offset)
|
||||
{
|
||||
uint32_t window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK;
|
||||
|
||||
@@ -173,6 +200,8 @@ static inline void hif_select_window(struct hif_pci_softc *sc, uint32_t offset)
|
||||
qdf_iowrite32(sc->mem + WINDOW_REG_ADDRESS,
|
||||
WINDOW_ENABLE_BIT | window);
|
||||
sc->register_window = window;
|
||||
hif_reg_write_result_check(sc, WINDOW_REG_ADDRESS,
|
||||
WINDOW_ENABLE_BIT | window);
|
||||
}
|
||||
}
|
||||
#endif /* PCIE_REG_WINDOW_LOCAL_NO_CACHE */
|
||||
@@ -239,7 +268,7 @@ static inline void hif_write32_mb_reg_window(void *scn,
|
||||
qdf_iowrite32(addr, value);
|
||||
} else {
|
||||
hif_lock_reg_access(sc, &flags);
|
||||
hif_select_window(sc, offset);
|
||||
hif_select_window_confirm(sc, offset);
|
||||
qdf_iowrite32(sc->mem + WINDOW_START +
|
||||
(offset & WINDOW_RANGE_MASK), value);
|
||||
hif_unlock_reg_access(sc, &flags);
|
||||
@@ -258,7 +287,7 @@ static inline uint32_t hif_read32_mb_reg_window(void *scn, void __iomem *addr)
|
||||
return qdf_ioread32(addr);
|
||||
}
|
||||
hif_lock_reg_access(sc, &flags);
|
||||
hif_select_window(sc, offset);
|
||||
hif_select_window_confirm(sc, offset);
|
||||
ret = qdf_ioread32(sc->mem + WINDOW_START +
|
||||
(offset & WINDOW_RANGE_MASK));
|
||||
hif_unlock_reg_access(sc, &flags);
|
||||
|
@@ -52,10 +52,11 @@ struct hif_ipci_stats {
|
||||
uint32_t soc_force_wake_release_success;
|
||||
};
|
||||
|
||||
/* Register offset to wake the UMAC from power collapse */
|
||||
#define PCIE_REG_WAKE_UMAC_OFFSET 0x3004
|
||||
/* Register to wake the UMAC from power collapse */
|
||||
#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
|
||||
/* Register used for handshake mechanism to validate UMAC is awake */
|
||||
#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004)
|
||||
|
||||
/* Timeout duration to validate UMAC wake status */
|
||||
#ifdef HAL_CONFIG_SLUB_DEBUG_ON
|
||||
#define FORCE_WAKE_DELAY_TIMEOUT_MS 500
|
||||
|
@@ -3734,8 +3734,7 @@ int hif_force_wake_request(struct hif_opaque_softc *hif_handle)
|
||||
hif_info("state-change event races, ignore");
|
||||
|
||||
HIF_STATS_INC(pci_scn, mhi_force_wake_success, 1);
|
||||
hif_write32_mb(scn, scn->mem +
|
||||
PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1);
|
||||
hif_write32_mb(scn, scn->mem + PCIE_REG_WAKE_UMAC_OFFSET, 1);
|
||||
HIF_STATS_INC(pci_scn, soc_force_wake_register_write_success, 1);
|
||||
/*
|
||||
* do not reset the timeout
|
||||
@@ -3777,8 +3776,7 @@ int hif_force_wake_release(struct hif_opaque_softc *hif_handle)
|
||||
}
|
||||
|
||||
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_write32_mb(scn, scn->mem + PCIE_REG_WAKE_UMAC_OFFSET, 0);
|
||||
HIF_STATS_INC(pci_scn, soc_force_wake_release_success, 1);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -31,10 +31,11 @@
|
||||
#include "ce_main.h"
|
||||
|
||||
#ifdef FORCE_WAKE
|
||||
/* Register to wake the UMAC from power collapse */
|
||||
#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
|
||||
/* Register offset to wake the UMAC from power collapse */
|
||||
#define PCIE_REG_WAKE_UMAC_OFFSET 0x3004
|
||||
/* Register used for handshake mechanism to validate UMAC is awake */
|
||||
#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004)
|
||||
#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
|
||||
|
||||
/* Timeout duration to validate UMAC wake status */
|
||||
#ifdef HAL_CONFIG_SLUB_DEBUG_ON
|
||||
#define FORCE_WAKE_DELAY_TIMEOUT_MS 500
|
||||
|
Reference in New Issue
Block a user