msm: ep_pcie: Enable BME Deassert IRQ

Enable BUS_MASTER_EN_DEASSERT IRQ as part of aggregated IRQ and Print
error log when BME is deasserted to help in debugging.

Use the device tree flag to distinguish if the device supports BME
deassert IRQ or not and enable it only on supported devices.

Change-Id: I810619b995255dab02eaabf05a6bc5c6e7639419
Signed-off-by: Sai Chaitanya Kaveti <quic_skaveti@quicinc.com>
This commit is contained in:
Sai Chaitanya Kaveti 2022-12-28 12:17:12 +05:30
commit 70db347c24
2 changed files with 49 additions and 1 deletions

View file

@ -43,6 +43,9 @@
#define PCIE20_PARF_INT_ALL_STATUS 0x224
#define PCIE20_PARF_INT_ALL_CLEAR 0x228
#define PCIE20_PARF_INT_ALL_MASK 0x22C
#define PCIE20_PARF_INT_ALL_2_STATUS 0x500
#define PCIE20_PARF_INT_ALL_2_CLEAR 0x504
#define PCIE20_PARF_INT_ALL_2_MASK 0x508
#define PCIE20_PARF_CLKREQ_OVERRIDE 0x2B0
#define PCIE20_PARF_CLKREQ_IN_OVERRIDE_STS BIT(5)
@ -175,6 +178,7 @@
#define MSI_EXIT_L1SS_WAIT_MAX_COUNT 100
#define XMLH_LINK_UP 0x400
#define PARF_XMLH_LINK_UP 0x40000000
#define CFG_BUS_MASTER_EN_DEASSERT BIT(24)
#define MAX_PROP_SIZE 32
#define MAX_MSG_LEN 80
@ -363,6 +367,7 @@ struct ep_pcie_dev_t {
bool aoss_rst_clear;
bool avoid_reboot_in_d3hot;
bool pme_in_wake_from_d3cold;
bool bme_deassert_irq;
u32 dbi_base_reg;
u32 slv_space_reg;
u32 phy_status_reg;

View file

@ -874,8 +874,16 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured)
ep_pcie_write_mask(dev->parf +
PCIE20_PARF_INT_ALL_MASK, 0,
BIT(EP_PCIE_INT_EVT_L1SUB_TIMEOUT));
if (dev->bme_deassert_irq) {
ep_pcie_write_reg(dev->parf, PCIE20_PARF_INT_ALL_2_MASK, 0);
ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_2_MASK, 0,
CFG_BUS_MASTER_EN_DEASSERT);
EP_PCIE_INFO(dev,
"PCIe V%d: PCIE20_PARF_INT_ALL_2_MASK:0x%x\n", dev->rev,
readl_relaxed(dev->parf + PCIE20_PARF_INT_ALL_2_MASK));
}
EP_PCIE_DBG(dev, "PCIe V%d: PCIE20_PARF_INT_ALL_MASK:0x%x\n",
EP_PCIE_INFO(dev, "PCIe V%d: PCIE20_PARF_INT_ALL_MASK:0x%x\n",
dev->rev,
readl_relaxed(dev->parf + PCIE20_PARF_INT_ALL_MASK));
}
@ -2606,6 +2614,30 @@ static irqreturn_t ep_pcie_handle_clkreq_irq(int irq, void *data)
return IRQ_HANDLED;
}
/**
* ep_pcie_handle_bme_deassert_irq - Check the second status register of PCIe's
* interrupts and print error log for BME deassert IRQ.
* @dev: PCIe endpoint device structure.
* @status2: Second status register of PCIe's interrupts.
*/
static void ep_pcie_handle_bme_deassert_irq(struct ep_pcie_dev_t *dev, u32 status2)
{
bool bme;
u32 mask2 = readl_relaxed(dev->parf + PCIE20_PARF_INT_ALL_2_MASK);
ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_2_CLEAR, 0, status2);
EP_PCIE_DUMP(dev,
"PCIe V%d: Global IRQ received; status2:0x%x; mask2:0x%x\n",
dev->rev, status2, mask2);
if (status2 & CFG_BUS_MASTER_EN_DEASSERT) {
bme = readl_relaxed(dev->dm_core + PCIE20_COMMAND_STATUS) & BIT(2);
EP_PCIE_ERR(dev, "PCIe V%d: BME deassert IRQ received, BME = %d\n",
dev->rev, bme);
}
}
static irqreturn_t ep_pcie_handle_global_irq(int irq, void *data)
{
struct ep_pcie_dev_t *dev = data;
@ -2675,6 +2707,12 @@ static irqreturn_t ep_pcie_handle_global_irq(int irq, void *data)
}
}
if (dev->bme_deassert_irq) {
status = readl_relaxed(dev->parf + PCIE20_PARF_INT_ALL_2_STATUS);
if (status)
ep_pcie_handle_bme_deassert_irq(dev, status);
}
return IRQ_HANDLED;
}
@ -3496,6 +3534,11 @@ static int ep_pcie_probe(struct platform_device *pdev)
"PCIe V%d: PME is%s sent during wake from d3cold\n",
ep_pcie_dev.rev, ep_pcie_dev.pme_in_wake_from_d3cold ? "" : " not");
ep_pcie_dev.bme_deassert_irq = of_property_read_bool((&pdev->dev)->of_node,
"qcom,pcie-bme-deassert-irq");
EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: BME deassert irq is%s enabled\n",
ep_pcie_dev.rev, ep_pcie_dev.bme_deassert_irq ? "" : " not");
ret = of_property_read_u32((&pdev->dev)->of_node,
"qcom,mhi-soc-reset-offset",
&ep_pcie_dev.mhi_soc_reset_offset);