Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d21973f authored by Yue Ma's avatar Yue Ma
Browse files

cnss2: Dump device PCIe shadow registers for debug purpose



Dump device PCIe shadow related registers into a buffer before
setting device to RDDM to get more information for debug.

Change-Id: If884b6f1739156fdcfa9a97cc4e8a14d096478ca
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent 769dcc5a
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -95,6 +95,14 @@ static DEFINE_SPINLOCK(pci_link_down_lock);

#define QCA6390_CE_REG_INTERVAL			0x2000

#define SHADOW_REG_COUNT			36
#define QCA6390_PCIE_SHADOW_REG_VALUE_0		0x1E03024
#define QCA6390_PCIE_SHADOW_REG_VALUE_35	0x1E030B0

#define SHADOW_REG_INTER_COUNT			43
#define QCA6390_PCIE_SHADOW_REG_INTER_0		0x1E05000
#define QCA6390_PCIE_SHADOW_REG_HUNG		0x1E050A8

#define QDSS_APB_DEC_CSR_BASE			0x1C01000

#define QDSS_APB_DEC_CSR_ETRIRQCTRL_OFFSET	0x6C
@@ -529,6 +537,45 @@ int cnss_pci_update_status(struct cnss_pci_data *pci_priv,
	return 0;
}

static void cnss_pci_dump_shadow_reg(struct cnss_pci_data *pci_priv)
{
	int i, j = 0, array_size = SHADOW_REG_COUNT + SHADOW_REG_INTER_COUNT;
	gfp_t gfp = GFP_KERNEL;
	u32 reg_offset;

	if (cnss_pci_check_link_status(pci_priv))
		return;

	if (in_interrupt() || irqs_disabled())
		gfp = GFP_ATOMIC;

	if (!pci_priv->debug_reg) {
		pci_priv->debug_reg = devm_kzalloc(&pci_priv->pci_dev->dev,
						   sizeof(*pci_priv->debug_reg)
						   * array_size, gfp);
		if (!pci_priv->debug_reg)
			return;
	}

	cnss_pr_dbg("Start to dump shadow registers\n");

	for (i = 0; i < SHADOW_REG_COUNT; i++, j++) {
		reg_offset = QCA6390_PCIE_SHADOW_REG_VALUE_0 + i * 4;
		pci_priv->debug_reg[j].offset = reg_offset;
		if (cnss_pci_reg_read(pci_priv, reg_offset,
				      &pci_priv->debug_reg[j].val))
			return;
	}

	for (i = 0; i < SHADOW_REG_INTER_COUNT; i++, j++) {
		reg_offset = QCA6390_PCIE_SHADOW_REG_INTER_0 + i * 4;
		pci_priv->debug_reg[j].offset = reg_offset;
		if (cnss_pci_reg_read(pci_priv, reg_offset,
				      &pci_priv->debug_reg[j].val))
			return;
	}
}

#ifdef CONFIG_CNSS2_DEBUG
static void cnss_pci_collect_dump(struct cnss_pci_data *pci_priv)
{
@@ -1713,6 +1760,8 @@ int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv)
	if (!plat_priv)
		return -ENODEV;

	cnss_pci_dump_shadow_reg(pci_priv);

	ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM);
	if (ret) {
		cnss_fatal_err("Failed to trigger RDDM, err = %d\n", ret);
@@ -2119,10 +2168,13 @@ static void cnss_pci_dump_qdss_reg(struct cnss_pci_data *pci_priv)
	if (in_interrupt() || irqs_disabled())
		gfp = GFP_ATOMIC;

	if (!plat_priv->qdss_reg)
	if (!plat_priv->qdss_reg) {
		plat_priv->qdss_reg = devm_kzalloc(&pci_priv->pci_dev->dev,
						   sizeof(*plat_priv->qdss_reg)
						   * array_size, gfp);
		if (!plat_priv->qdss_reg)
			return;
	}

	for (i = 0; qdss_csr[i].name; i++) {
		reg_offset = QDSS_APB_DEC_CSR_BASE + qdss_csr[i].offset;
+6 −0
Original line number Diff line number Diff line
@@ -42,6 +42,11 @@ struct cnss_pci_reg {
	u32 offset;
};

struct cnss_pci_debug_reg {
	u32 offset;
	u32 val;
};

struct cnss_pci_data {
	struct pci_dev *pci_dev;
	struct cnss_plat_data *plat_priv;
@@ -72,6 +77,7 @@ struct cnss_pci_data {
	u32 remap_window;
	struct timer_list dev_rddm_timer;
	u8 disable_pc;
	struct cnss_pci_debug_reg *debug_reg;
};

static inline void cnss_set_pci_priv(struct pci_dev *pci_dev, void *data)