PCI: mediatek: Fixup MSI enablement logic by enabling MSI before clocks
authorHonghui Zhang <honghui.zhang@mediatek.com>
Mon, 15 Oct 2018 08:08:56 +0000 (16:08 +0800)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Wed, 17 Oct 2018 14:36:17 +0000 (15:36 +0100)
Commit 43e6409db64d ("PCI: mediatek: Add MSI support for MT2712 and
MT7622") added MSI support but enabled MSI in the wrong place, at a step
in the probe sequence where clocks were not still enabled.

Fix this issue by calling mtk_pcie_enable_msi() in mtk_pcie_startup_port_v2()
since clocks are enabled when mtk_pcie_startup_port_v2() is called.

To avoid forward declaration of mtk_pcie_enable_msi(), move the
mtk_pcie_startup_port_v2() function definition in the file.

Fixes: 43e6409db64d ("PCI: mediatek: Add MSI support for MT2712 and MT7622")
Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
[lorenzo.pieralisi@arm.com: squashed commit and adapted log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
drivers/pci/controller/pcie-mediatek.c

index 6f08490..aa900b0 100644 (file)
@@ -392,75 +392,6 @@ static struct pci_ops mtk_pcie_ops_v2 = {
        .write = mtk_pcie_config_write,
 };
 
-static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
-{
-       struct mtk_pcie *pcie = port->pcie;
-       struct resource *mem = &pcie->mem;
-       const struct mtk_pcie_soc *soc = port->pcie->soc;
-       u32 val;
-       size_t size;
-       int err;
-
-       /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */
-       if (pcie->base) {
-               val = readl(pcie->base + PCIE_SYS_CFG_V2);
-               val |= PCIE_CSR_LTSSM_EN(port->slot) |
-                      PCIE_CSR_ASPM_L1_EN(port->slot);
-               writel(val, pcie->base + PCIE_SYS_CFG_V2);
-       }
-
-       /* Assert all reset signals */
-       writel(0, port->base + PCIE_RST_CTRL);
-
-       /*
-        * Enable PCIe link down reset, if link status changed from link up to
-        * link down, this will reset MAC control registers and configuration
-        * space.
-        */
-       writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL);
-
-       /* De-assert PHY, PE, PIPE, MAC and configuration reset */
-       val = readl(port->base + PCIE_RST_CTRL);
-       val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
-              PCIE_MAC_SRSTB | PCIE_CRSTB;
-       writel(val, port->base + PCIE_RST_CTRL);
-
-       /* Set up vendor ID and class code */
-       if (soc->need_fix_class_id) {
-               val = PCI_VENDOR_ID_MEDIATEK;
-               writew(val, port->base + PCIE_CONF_VEND_ID);
-
-               val = PCI_CLASS_BRIDGE_PCI;
-               writew(val, port->base + PCIE_CONF_CLASS_ID);
-       }
-
-       /* 100ms timeout value should be enough for Gen1/2 training */
-       err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
-                                !!(val & PCIE_PORT_LINKUP_V2), 20,
-                                100 * USEC_PER_MSEC);
-       if (err)
-               return -ETIMEDOUT;
-
-       /* Set INTx mask */
-       val = readl(port->base + PCIE_INT_MASK);
-       val &= ~INTX_MASK;
-       writel(val, port->base + PCIE_INT_MASK);
-
-       /* Set AHB to PCIe translation windows */
-       size = mem->end - mem->start;
-       val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size));
-       writel(val, port->base + PCIE_AHB_TRANS_BASE0_L);
-
-       val = upper_32_bits(mem->start);
-       writel(val, port->base + PCIE_AHB_TRANS_BASE0_H);
-
-       /* Set PCIe to AXI translation memory space.*/
-       val = fls(0xffffffff) | WIN_ENABLE;
-       writel(val, port->base + PCIE_AXI_WINDOW0);
-
-       return 0;
-}
-
 static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
        struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data);
@@ -637,8 +568,6 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port,
                ret = mtk_pcie_allocate_msi_domains(port);
                if (ret)
                        return ret;
-
-               mtk_pcie_enable_msi(port);
        }
 
        return 0;
@@ -705,6 +634,78 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
        return 0;
 }
 
+static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
+{
+       struct mtk_pcie *pcie = port->pcie;
+       struct resource *mem = &pcie->mem;
+       const struct mtk_pcie_soc *soc = port->pcie->soc;
+       u32 val;
+       size_t size;
+       int err;
+
+       /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */
+       if (pcie->base) {
+               val = readl(pcie->base + PCIE_SYS_CFG_V2);
+               val |= PCIE_CSR_LTSSM_EN(port->slot) |
+                      PCIE_CSR_ASPM_L1_EN(port->slot);
+               writel(val, pcie->base + PCIE_SYS_CFG_V2);
+       }
+
+       /* Assert all reset signals */
+       writel(0, port->base + PCIE_RST_CTRL);
+
+       /*
+        * Enable PCIe link down reset, if link status changed from link up to
+        * link down, this will reset MAC control registers and configuration
+        * space.
+        */
+       writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL);
+
+       /* De-assert PHY, PE, PIPE, MAC and configuration reset */
+       val = readl(port->base + PCIE_RST_CTRL);
+       val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
+              PCIE_MAC_SRSTB | PCIE_CRSTB;
+       writel(val, port->base + PCIE_RST_CTRL);
+
+       /* Set up vendor ID and class code */
+       if (soc->need_fix_class_id) {
+               val = PCI_VENDOR_ID_MEDIATEK;
+               writew(val, port->base + PCIE_CONF_VEND_ID);
+
+               val = PCI_CLASS_BRIDGE_PCI;
+               writew(val, port->base + PCIE_CONF_CLASS_ID);
+       }
+
+       /* 100ms timeout value should be enough for Gen1/2 training */
+       err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
+                                !!(val & PCIE_PORT_LINKUP_V2), 20,
+                                100 * USEC_PER_MSEC);
+       if (err)
+               return -ETIMEDOUT;
+
+       /* Set INTx mask */
+       val = readl(port->base + PCIE_INT_MASK);
+       val &= ~INTX_MASK;
+       writel(val, port->base + PCIE_INT_MASK);
+
+       if (IS_ENABLED(CONFIG_PCI_MSI))
+               mtk_pcie_enable_msi(port);
+
+       /* Set AHB to PCIe translation windows */
+       size = mem->end - mem->start;
+       val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size));
+       writel(val, port->base + PCIE_AHB_TRANS_BASE0_L);
+
+       val = upper_32_bits(mem->start);
+       writel(val, port->base + PCIE_AHB_TRANS_BASE0_H);
+
+       /* Set PCIe to AXI translation memory space.*/
+       val = fls(0xffffffff) | WIN_ENABLE;
+       writel(val, port->base + PCIE_AXI_WINDOW0);
+
+       return 0;
+}
+
 static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus,
                                      unsigned int devfn, int where)
 {