Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PCIe Gen4 host controller driver for NXP Layerscape SoCs
0004  *
0005  * Copyright 2019-2020 NXP
0006  *
0007  * Author: Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/init.h>
0013 #include <linux/of_pci.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/of_irq.h>
0016 #include <linux/of_address.h>
0017 #include <linux/pci.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/resource.h>
0020 #include <linux/mfd/syscon.h>
0021 #include <linux/regmap.h>
0022 
0023 #include "pcie-mobiveil.h"
0024 
0025 /* LUT and PF control registers */
0026 #define PCIE_LUT_OFF            0x80000
0027 #define PCIE_PF_OFF         0xc0000
0028 #define PCIE_PF_INT_STAT        0x18
0029 #define PF_INT_STAT_PABRST      BIT(31)
0030 
0031 #define PCIE_PF_DBG         0x7fc
0032 #define PF_DBG_LTSSM_MASK       0x3f
0033 #define PF_DBG_LTSSM_L0         0x2d /* L0 state */
0034 #define PF_DBG_WE           BIT(31)
0035 #define PF_DBG_PABR         BIT(27)
0036 
0037 #define to_ls_g4_pcie(x)        platform_get_drvdata((x)->pdev)
0038 
0039 struct ls_g4_pcie {
0040     struct mobiveil_pcie pci;
0041     struct delayed_work dwork;
0042     int irq;
0043 };
0044 
0045 static inline u32 ls_g4_pcie_pf_readl(struct ls_g4_pcie *pcie, u32 off)
0046 {
0047     return ioread32(pcie->pci.csr_axi_slave_base + PCIE_PF_OFF + off);
0048 }
0049 
0050 static inline void ls_g4_pcie_pf_writel(struct ls_g4_pcie *pcie,
0051                     u32 off, u32 val)
0052 {
0053     iowrite32(val, pcie->pci.csr_axi_slave_base + PCIE_PF_OFF + off);
0054 }
0055 
0056 static int ls_g4_pcie_link_up(struct mobiveil_pcie *pci)
0057 {
0058     struct ls_g4_pcie *pcie = to_ls_g4_pcie(pci);
0059     u32 state;
0060 
0061     state = ls_g4_pcie_pf_readl(pcie, PCIE_PF_DBG);
0062     state = state & PF_DBG_LTSSM_MASK;
0063 
0064     if (state == PF_DBG_LTSSM_L0)
0065         return 1;
0066 
0067     return 0;
0068 }
0069 
0070 static void ls_g4_pcie_disable_interrupt(struct ls_g4_pcie *pcie)
0071 {
0072     struct mobiveil_pcie *mv_pci = &pcie->pci;
0073 
0074     mobiveil_csr_writel(mv_pci, 0, PAB_INTP_AMBA_MISC_ENB);
0075 }
0076 
0077 static void ls_g4_pcie_enable_interrupt(struct ls_g4_pcie *pcie)
0078 {
0079     struct mobiveil_pcie *mv_pci = &pcie->pci;
0080     u32 val;
0081 
0082     /* Clear the interrupt status */
0083     mobiveil_csr_writel(mv_pci, 0xffffffff, PAB_INTP_AMBA_MISC_STAT);
0084 
0085     val = PAB_INTP_INTX_MASK | PAB_INTP_MSI | PAB_INTP_RESET |
0086           PAB_INTP_PCIE_UE | PAB_INTP_IE_PMREDI | PAB_INTP_IE_EC;
0087     mobiveil_csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_ENB);
0088 }
0089 
0090 static int ls_g4_pcie_reinit_hw(struct ls_g4_pcie *pcie)
0091 {
0092     struct mobiveil_pcie *mv_pci = &pcie->pci;
0093     struct device *dev = &mv_pci->pdev->dev;
0094     u32 val, act_stat;
0095     int to = 100;
0096 
0097     /* Poll for pab_csb_reset to set and PAB activity to clear */
0098     do {
0099         usleep_range(10, 15);
0100         val = ls_g4_pcie_pf_readl(pcie, PCIE_PF_INT_STAT);
0101         act_stat = mobiveil_csr_readl(mv_pci, PAB_ACTIVITY_STAT);
0102     } while (((val & PF_INT_STAT_PABRST) == 0 || act_stat) && to--);
0103     if (to < 0) {
0104         dev_err(dev, "Poll PABRST&PABACT timeout\n");
0105         return -EIO;
0106     }
0107 
0108     /* clear PEX_RESET bit in PEX_PF0_DBG register */
0109     val = ls_g4_pcie_pf_readl(pcie, PCIE_PF_DBG);
0110     val |= PF_DBG_WE;
0111     ls_g4_pcie_pf_writel(pcie, PCIE_PF_DBG, val);
0112 
0113     val = ls_g4_pcie_pf_readl(pcie, PCIE_PF_DBG);
0114     val |= PF_DBG_PABR;
0115     ls_g4_pcie_pf_writel(pcie, PCIE_PF_DBG, val);
0116 
0117     val = ls_g4_pcie_pf_readl(pcie, PCIE_PF_DBG);
0118     val &= ~PF_DBG_WE;
0119     ls_g4_pcie_pf_writel(pcie, PCIE_PF_DBG, val);
0120 
0121     mobiveil_host_init(mv_pci, true);
0122 
0123     to = 100;
0124     while (!ls_g4_pcie_link_up(mv_pci) && to--)
0125         usleep_range(200, 250);
0126     if (to < 0) {
0127         dev_err(dev, "PCIe link training timeout\n");
0128         return -EIO;
0129     }
0130 
0131     return 0;
0132 }
0133 
0134 static irqreturn_t ls_g4_pcie_isr(int irq, void *dev_id)
0135 {
0136     struct ls_g4_pcie *pcie = (struct ls_g4_pcie *)dev_id;
0137     struct mobiveil_pcie *mv_pci = &pcie->pci;
0138     u32 val;
0139 
0140     val = mobiveil_csr_readl(mv_pci, PAB_INTP_AMBA_MISC_STAT);
0141     if (!val)
0142         return IRQ_NONE;
0143 
0144     if (val & PAB_INTP_RESET) {
0145         ls_g4_pcie_disable_interrupt(pcie);
0146         schedule_delayed_work(&pcie->dwork, msecs_to_jiffies(1));
0147     }
0148 
0149     mobiveil_csr_writel(mv_pci, val, PAB_INTP_AMBA_MISC_STAT);
0150 
0151     return IRQ_HANDLED;
0152 }
0153 
0154 static int ls_g4_pcie_interrupt_init(struct mobiveil_pcie *mv_pci)
0155 {
0156     struct ls_g4_pcie *pcie = to_ls_g4_pcie(mv_pci);
0157     struct platform_device *pdev = mv_pci->pdev;
0158     struct device *dev = &pdev->dev;
0159     int ret;
0160 
0161     pcie->irq = platform_get_irq_byname(pdev, "intr");
0162     if (pcie->irq < 0)
0163         return pcie->irq;
0164 
0165     ret = devm_request_irq(dev, pcie->irq, ls_g4_pcie_isr,
0166                    IRQF_SHARED, pdev->name, pcie);
0167     if (ret) {
0168         dev_err(dev, "Can't register PCIe IRQ, errno = %d\n", ret);
0169         return  ret;
0170     }
0171 
0172     return 0;
0173 }
0174 
0175 static void ls_g4_pcie_reset(struct work_struct *work)
0176 {
0177     struct delayed_work *dwork = container_of(work, struct delayed_work,
0178                           work);
0179     struct ls_g4_pcie *pcie = container_of(dwork, struct ls_g4_pcie, dwork);
0180     struct mobiveil_pcie *mv_pci = &pcie->pci;
0181     u16 ctrl;
0182 
0183     ctrl = mobiveil_csr_readw(mv_pci, PCI_BRIDGE_CONTROL);
0184     ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
0185     mobiveil_csr_writew(mv_pci, ctrl, PCI_BRIDGE_CONTROL);
0186 
0187     if (!ls_g4_pcie_reinit_hw(pcie))
0188         return;
0189 
0190     ls_g4_pcie_enable_interrupt(pcie);
0191 }
0192 
0193 static struct mobiveil_rp_ops ls_g4_pcie_rp_ops = {
0194     .interrupt_init = ls_g4_pcie_interrupt_init,
0195 };
0196 
0197 static const struct mobiveil_pab_ops ls_g4_pcie_pab_ops = {
0198     .link_up = ls_g4_pcie_link_up,
0199 };
0200 
0201 static int __init ls_g4_pcie_probe(struct platform_device *pdev)
0202 {
0203     struct device *dev = &pdev->dev;
0204     struct pci_host_bridge *bridge;
0205     struct mobiveil_pcie *mv_pci;
0206     struct ls_g4_pcie *pcie;
0207     struct device_node *np = dev->of_node;
0208     int ret;
0209 
0210     if (!of_parse_phandle(np, "msi-parent", 0)) {
0211         dev_err(dev, "Failed to find msi-parent\n");
0212         return -EINVAL;
0213     }
0214 
0215     bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
0216     if (!bridge)
0217         return -ENOMEM;
0218 
0219     pcie = pci_host_bridge_priv(bridge);
0220     mv_pci = &pcie->pci;
0221 
0222     mv_pci->pdev = pdev;
0223     mv_pci->ops = &ls_g4_pcie_pab_ops;
0224     mv_pci->rp.ops = &ls_g4_pcie_rp_ops;
0225     mv_pci->rp.bridge = bridge;
0226 
0227     platform_set_drvdata(pdev, pcie);
0228 
0229     INIT_DELAYED_WORK(&pcie->dwork, ls_g4_pcie_reset);
0230 
0231     ret = mobiveil_pcie_host_probe(mv_pci);
0232     if (ret) {
0233         dev_err(dev, "Fail to probe\n");
0234         return  ret;
0235     }
0236 
0237     ls_g4_pcie_enable_interrupt(pcie);
0238 
0239     return 0;
0240 }
0241 
0242 static const struct of_device_id ls_g4_pcie_of_match[] = {
0243     { .compatible = "fsl,lx2160a-pcie", },
0244     { },
0245 };
0246 
0247 static struct platform_driver ls_g4_pcie_driver = {
0248     .driver = {
0249         .name = "layerscape-pcie-gen4",
0250         .of_match_table = ls_g4_pcie_of_match,
0251         .suppress_bind_attrs = true,
0252     },
0253 };
0254 
0255 builtin_platform_driver_probe(ls_g4_pcie_driver, ls_g4_pcie_probe);