Commit dd70e51e authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge remote-tracking branch 'lorenzo/pci/host/fixes' into for-linus

  - correct GPIO name to fix HiSilicon Kirin probing issue (Loic Poulain)

  - fix MRRS setting in Marvell Armada Aardvark (Evan Wang)

  - fix interrupts by using ISR1 on Marvell Armada Aardvark (Victor Gu)

  - fix config accesses on Marvell Armada Aardvark (Victor Gu)

* lorenzo/pci/host/fixes:
  PCI: kirin: Fix reset gpio name
  PCI: aardvark: Fix PCIe Max Read Request Size setting
  PCI: aardvark: Use ISR1 instead of ISR0 interrupt in legacy irq mode
  PCI: aardvark: Set PIO_ADDR_LS correctly in advk_pcie_rd_conf()
  PCI: aardvark: Fix logic in advk_pcie_{rd,wr}_conf()
parents 60cc43fc 5db8f8d1
...@@ -486,7 +486,7 @@ static int kirin_pcie_probe(struct platform_device *pdev) ...@@ -486,7 +486,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)
return ret; return ret;
kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node, kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node,
"reset-gpio", 0); "reset-gpios", 0);
if (kirin_pcie->gpio_id_reset < 0) if (kirin_pcie->gpio_id_reset < 0)
return -ENODEV; return -ENODEV;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5
#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2
#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
#define PCIE_CORE_LINK_L0S_ENTRY BIT(0) #define PCIE_CORE_LINK_L0S_ENTRY BIT(0)
#define PCIE_CORE_LINK_TRAINING BIT(5) #define PCIE_CORE_LINK_TRAINING BIT(5)
...@@ -100,7 +101,8 @@ ...@@ -100,7 +101,8 @@
#define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C)
#define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4)
#define PCIE_ISR1_FLUSH BIT(5) #define PCIE_ISR1_FLUSH BIT(5)
#define PCIE_ISR1_ALL_MASK GENMASK(5, 4) #define PCIE_ISR1_INTX_ASSERT(val) BIT(8 + (val))
#define PCIE_ISR1_ALL_MASK GENMASK(11, 4)
#define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50)
#define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54)
#define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58)
...@@ -172,8 +174,6 @@ ...@@ -172,8 +174,6 @@
#define PCIE_CONFIG_WR_TYPE0 0xa #define PCIE_CONFIG_WR_TYPE0 0xa
#define PCIE_CONFIG_WR_TYPE1 0xb #define PCIE_CONFIG_WR_TYPE1 0xb
/* PCI_BDF shifts 8bit, so we need extra 4bit shift */
#define PCIE_BDF(dev) (dev << 4)
#define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20) #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20)
#define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15) #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15)
#define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12) #define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12)
...@@ -296,7 +296,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) ...@@ -296,7 +296,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
(7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ <<
PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT);
advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
/* Program PCIe Control 2 to disable strict ordering */ /* Program PCIe Control 2 to disable strict ordering */
...@@ -437,7 +438,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, ...@@ -437,7 +438,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
u32 reg; u32 reg;
int ret; int ret;
if (PCI_SLOT(devfn) != 0) { if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) {
*val = 0xffffffff; *val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
...@@ -456,7 +457,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, ...@@ -456,7 +457,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
advk_writel(pcie, reg, PIO_CTRL); advk_writel(pcie, reg, PIO_CTRL);
/* Program the address registers */ /* Program the address registers */
reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); reg = PCIE_CONF_ADDR(bus->number, devfn, where);
advk_writel(pcie, reg, PIO_ADDR_LS); advk_writel(pcie, reg, PIO_ADDR_LS);
advk_writel(pcie, 0, PIO_ADDR_MS); advk_writel(pcie, 0, PIO_ADDR_MS);
...@@ -491,7 +492,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -491,7 +492,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int offset; int offset;
int ret; int ret;
if (PCI_SLOT(devfn) != 0) if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
if (where % size) if (where % size)
...@@ -609,9 +610,9 @@ static void advk_pcie_irq_mask(struct irq_data *d) ...@@ -609,9 +610,9 @@ static void advk_pcie_irq_mask(struct irq_data *d)
irq_hw_number_t hwirq = irqd_to_hwirq(d); irq_hw_number_t hwirq = irqd_to_hwirq(d);
u32 mask; u32 mask;
mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
mask |= PCIE_ISR0_INTX_ASSERT(hwirq); mask |= PCIE_ISR1_INTX_ASSERT(hwirq);
advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
} }
static void advk_pcie_irq_unmask(struct irq_data *d) static void advk_pcie_irq_unmask(struct irq_data *d)
...@@ -620,9 +621,9 @@ static void advk_pcie_irq_unmask(struct irq_data *d) ...@@ -620,9 +621,9 @@ static void advk_pcie_irq_unmask(struct irq_data *d)
irq_hw_number_t hwirq = irqd_to_hwirq(d); irq_hw_number_t hwirq = irqd_to_hwirq(d);
u32 mask; u32 mask;
mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq); mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq);
advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
} }
static int advk_pcie_irq_map(struct irq_domain *h, static int advk_pcie_irq_map(struct irq_domain *h,
...@@ -765,29 +766,35 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie) ...@@ -765,29 +766,35 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie)
static void advk_pcie_handle_int(struct advk_pcie *pcie) static void advk_pcie_handle_int(struct advk_pcie *pcie)
{ {
u32 val, mask, status; u32 isr0_val, isr0_mask, isr0_status;
u32 isr1_val, isr1_mask, isr1_status;
int i, virq; int i, virq;
val = advk_readl(pcie, PCIE_ISR0_REG); isr0_val = advk_readl(pcie, PCIE_ISR0_REG);
mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
status = val & ((~mask) & PCIE_ISR0_ALL_MASK); isr0_status = isr0_val & ((~isr0_mask) & PCIE_ISR0_ALL_MASK);
isr1_val = advk_readl(pcie, PCIE_ISR1_REG);
isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
if (!status) { if (!isr0_status && !isr1_status) {
advk_writel(pcie, val, PCIE_ISR0_REG); advk_writel(pcie, isr0_val, PCIE_ISR0_REG);
advk_writel(pcie, isr1_val, PCIE_ISR1_REG);
return; return;
} }
/* Process MSI interrupts */ /* Process MSI interrupts */
if (status & PCIE_ISR0_MSI_INT_PENDING) if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
advk_pcie_handle_msi(pcie); advk_pcie_handle_msi(pcie);
/* Process legacy interrupts */ /* Process legacy interrupts */
for (i = 0; i < PCI_NUM_INTX; i++) { for (i = 0; i < PCI_NUM_INTX; i++) {
if (!(status & PCIE_ISR0_INTX_ASSERT(i))) if (!(isr1_status & PCIE_ISR1_INTX_ASSERT(i)))
continue; continue;
advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i), advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i),
PCIE_ISR0_REG); PCIE_ISR1_REG);
virq = irq_find_mapping(pcie->irq_domain, i); virq = irq_find_mapping(pcie->irq_domain, i);
generic_handle_irq(virq); generic_handle_irq(virq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment