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

Commit dd70e51e authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;


+30 −23
Original line number Original line Diff line number Diff line
@@ -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 @@
#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 @@
#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)
	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,
	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,
	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,
	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)
	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)
	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)


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);