drivers: pcie: ep: iproc: Add reset interrupt handlers
Add reset interrupt handlers for all three types of reset interrupts that iProc PCIe EP can receive - namely PERST, INB PERST and FLR. Signed-off-by: Shivaraj Shetty <shivaraj.shetty@broadcom.com> Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
This commit is contained in:
parent
19417b2a99
commit
7d587abc6e
4 changed files with 148 additions and 0 deletions
|
@ -10,6 +10,8 @@
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_REGISTER(iproc_pcie);
|
LOG_MODULE_REGISTER(iproc_pcie);
|
||||||
|
|
||||||
|
#include <soc.h>
|
||||||
|
|
||||||
#include "pcie_ep_bcm_iproc.h"
|
#include "pcie_ep_bcm_iproc.h"
|
||||||
#include "pcie_ep_bcm_iproc_regs.h"
|
#include "pcie_ep_bcm_iproc_regs.h"
|
||||||
|
|
||||||
|
@ -238,6 +240,118 @@ static int iproc_pcie_raise_irq(struct device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, perst)
|
||||||
|
static void iproc_pcie_perst(void *arg)
|
||||||
|
{
|
||||||
|
struct device *dev = arg;
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
data = sys_read32(CRMU_MCU_EXTRA_EVENT_STATUS);
|
||||||
|
|
||||||
|
if (data & PCIE0_PERST_INTR) {
|
||||||
|
LOG_DBG("PERST interrupt [0x%x]", data);
|
||||||
|
sys_write32(PCIE0_PERST_INTR, CRMU_MCU_EXTRA_EVENT_CLEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, perst_inband)
|
||||||
|
static void iproc_pcie_hot_reset(void *arg)
|
||||||
|
{
|
||||||
|
struct device *dev = arg;
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
data = sys_read32(CRMU_MCU_EXTRA_EVENT_STATUS);
|
||||||
|
|
||||||
|
if (data & PCIE0_PERST_INB_INTR) {
|
||||||
|
LOG_DBG("INBAND PERST interrupt [0x%x]", data);
|
||||||
|
sys_write32(PCIE0_PERST_INB_INTR, CRMU_MCU_EXTRA_EVENT_CLEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, flr)
|
||||||
|
static void iproc_pcie_flr(void *arg)
|
||||||
|
{
|
||||||
|
struct device *dev = arg;
|
||||||
|
const struct iproc_pcie_ep_config *cfg = dev->config_info;
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
data = pcie_read32(&cfg->base->paxb_paxb_intr_status);
|
||||||
|
|
||||||
|
if (data & PCIE0_FLR_INTR) {
|
||||||
|
LOG_DBG("FLR interrupt[0x%x]", data);
|
||||||
|
pcie_write32(PCIE0_FLR_INTR, &cfg->base->paxb_paxb_intr_clear);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Other interrupts like PAXB ECC Error interrupt
|
||||||
|
* could show up at the beginning which are harmless.
|
||||||
|
* So simply clearing those interrupts here
|
||||||
|
*/
|
||||||
|
LOG_DBG("PAXB interrupt[0x%x]", data);
|
||||||
|
pcie_write32(data, &cfg->base->paxb_paxb_intr_clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear FLR in Progress bit */
|
||||||
|
iproc_pcie_conf_read(dev, PCIE_DEV_CTRL_OFFSET, &data);
|
||||||
|
data |= FLR_IN_PROGRESS;
|
||||||
|
iproc_pcie_conf_write(dev, PCIE_DEV_CTRL_OFFSET, data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEVICE_DECLARE(iproc_pcie_ep_0);
|
||||||
|
|
||||||
|
static void iproc_pcie_reset_config(struct device *dev)
|
||||||
|
{
|
||||||
|
uint32_t data;
|
||||||
|
const struct iproc_pcie_ep_config *cfg = dev->config_info;
|
||||||
|
|
||||||
|
/* Clear any possible prior pending interrupts */
|
||||||
|
sys_write32(PCIE0_PERST_INTR | PCIE0_PERST_INB_INTR,
|
||||||
|
CRMU_MCU_EXTRA_EVENT_CLEAR);
|
||||||
|
pcie_write32(PCIE0_FLR_INTR, &cfg->base->paxb_paxb_intr_clear);
|
||||||
|
|
||||||
|
/* Enable PERST and Inband PERST interrupts */
|
||||||
|
data = sys_read32(PCIE_PERSTB_INTR_CTL_STS);
|
||||||
|
data |= (PCIE0_PERST_FE_INTR | PCIE0_PERST_INB_FE_INTR);
|
||||||
|
sys_write32(data, PCIE_PERSTB_INTR_CTL_STS);
|
||||||
|
|
||||||
|
data = sys_read32(CRMU_MCU_EXTRA_EVENT_MASK);
|
||||||
|
data &= ~(PCIE0_PERST_INTR | PCIE0_PERST_INB_INTR);
|
||||||
|
sys_write32(data, CRMU_MCU_EXTRA_EVENT_MASK);
|
||||||
|
|
||||||
|
/* Set auto clear FLR and auto clear CRS post FLR */
|
||||||
|
iproc_pcie_conf_read(dev, PCIE_TL_CTRL0_OFFSET, &data);
|
||||||
|
data |= (AUTO_CLR_CRS_POST_FLR | AUTO_CLR_FLR_AFTER_DELAY);
|
||||||
|
iproc_pcie_conf_write(dev, PCIE_TL_CTRL0_OFFSET, data);
|
||||||
|
|
||||||
|
/* Enable Function Level Reset */
|
||||||
|
data = pcie_read32(&cfg->base->paxb_paxb_intr_en);
|
||||||
|
data |= PCIE0_FLR_INTR;
|
||||||
|
pcie_write32(data, &cfg->base->paxb_paxb_intr_en);
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, perst)
|
||||||
|
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, perst, irq),
|
||||||
|
DT_INST_IRQ_BY_NAME(0, perst, priority),
|
||||||
|
iproc_pcie_perst, DEVICE_GET(iproc_pcie_ep_0), 0);
|
||||||
|
irq_enable(DT_INST_IRQ_BY_NAME(0, perst, irq));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, perst_inband)
|
||||||
|
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, perst_inband, irq),
|
||||||
|
DT_INST_IRQ_BY_NAME(0, perst_inband, priority),
|
||||||
|
iproc_pcie_hot_reset, DEVICE_GET(iproc_pcie_ep_0), 0);
|
||||||
|
irq_enable(DT_INST_IRQ_BY_NAME(0, perst_inband, irq));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DT_INST_IRQ_HAS_NAME(0, flr)
|
||||||
|
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, flr, irq),
|
||||||
|
DT_INST_IRQ_BY_NAME(0, flr, priority),
|
||||||
|
iproc_pcie_flr, DEVICE_GET(iproc_pcie_ep_0), 0);
|
||||||
|
irq_enable(DT_INST_IRQ_BY_NAME(0, flr, irq));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCIE_EP_BCM_IPROC_INIT_CFG
|
#ifdef CONFIG_PCIE_EP_BCM_IPROC_INIT_CFG
|
||||||
static void iproc_pcie_msix_config(struct device *dev)
|
static void iproc_pcie_msix_config(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -300,6 +414,8 @@ static int iproc_pcie_ep_init(struct device *dev)
|
||||||
iproc_pcie_msix_config(dev);
|
iproc_pcie_msix_config(dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
iproc_pcie_reset_config(dev);
|
||||||
|
|
||||||
ctx->highmem_in_use = false;
|
ctx->highmem_in_use = false;
|
||||||
ctx->lowmem_in_use = false;
|
ctx->lowmem_in_use = false;
|
||||||
LOG_INF("PCIe initialized successfully\n");
|
LOG_INF("PCIe initialized successfully\n");
|
||||||
|
|
|
@ -42,6 +42,16 @@
|
||||||
|
|
||||||
#define PAXB_OARR_VALID BIT(0)
|
#define PAXB_OARR_VALID BIT(0)
|
||||||
|
|
||||||
|
#define PCIE_DEV_CTRL_OFFSET 0x4d8
|
||||||
|
#define FLR_IN_PROGRESS BIT(27)
|
||||||
|
|
||||||
|
#define PCIE_TL_CTRL0_OFFSET 0x800
|
||||||
|
#define AUTO_CLR_FLR_AFTER_DELAY BIT(13) /* Clears FLR after 55ms */
|
||||||
|
#define AUTO_CLR_CRS_POST_FLR BIT(14)
|
||||||
|
|
||||||
|
#define PCIE0_FLR_INTR BIT(20)
|
||||||
|
#define PCIE0_FLR_PERST_INTR BIT(21)
|
||||||
|
|
||||||
enum pcie_outbound_map {
|
enum pcie_outbound_map {
|
||||||
PCIE_MAP_LOWMEM_IDX,
|
PCIE_MAP_LOWMEM_IDX,
|
||||||
PCIE_MAP_HIGHMEM_IDX,
|
PCIE_MAP_HIGHMEM_IDX,
|
||||||
|
|
|
@ -282,4 +282,15 @@ typedef enum IRQn {
|
||||||
#define __MPU_PRESENT 1
|
#define __MPU_PRESENT 1
|
||||||
#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS
|
#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS
|
||||||
|
|
||||||
|
/* CRMU registers block */
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_STATUS 0x40070054
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_CLEAR 0x4007005c
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_MASK 0x40070064
|
||||||
|
#define PCIE0_PERST_INTR BIT(4)
|
||||||
|
#define PCIE0_PERST_INB_INTR BIT(6)
|
||||||
|
|
||||||
|
#define PCIE_PERSTB_INTR_CTL_STS 0x400700e4
|
||||||
|
#define PCIE0_PERST_FE_INTR BIT(1)
|
||||||
|
#define PCIE0_PERST_INB_FE_INTR BIT(3)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -284,4 +284,15 @@ typedef enum IRQn {
|
||||||
#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS
|
#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* CRMU registers block */
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_STATUS 0x40070054
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_CLEAR 0x4007005c
|
||||||
|
#define CRMU_MCU_EXTRA_EVENT_MASK 0x40070064
|
||||||
|
#define PCIE0_PERST_INTR BIT(4)
|
||||||
|
#define PCIE0_PERST_INB_INTR BIT(6)
|
||||||
|
|
||||||
|
#define PCIE_PERSTB_INTR_CTL_STS 0x400700f0
|
||||||
|
#define PCIE0_PERST_FE_INTR BIT(1)
|
||||||
|
#define PCIE0_PERST_INB_FE_INTR BIT(3)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue