0001
0002
0003
0004
0005
0006
0007
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
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
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
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
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
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);