1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCIe controller EP driver for Freescale Layerscape SoCs 4 * 5 * Copyright (C) 2018 NXP Semiconductor. 6 * 7 * Author: Xiaowei Bao <xiaowei.bao@nxp.com> 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <linux/of_pci.h> 13 #include <linux/of_platform.h> 14 #include <linux/of_address.h> 15 #include <linux/pci.h> 16 #include <linux/platform_device.h> 17 #include <linux/resource.h> 18 19 #include "pcie-designware.h" 20 21 #define PEX_PF0_CONFIG 0xC0014 22 #define PEX_PF0_CFG_READY BIT(0) 23 24 /* PEX PFa PCIE PME and message interrupt registers*/ 25 #define PEX_PF0_PME_MES_DR 0xC0020 26 #define PEX_PF0_PME_MES_DR_LUD BIT(7) 27 #define PEX_PF0_PME_MES_DR_LDD BIT(9) 28 #define PEX_PF0_PME_MES_DR_HRD BIT(10) 29 30 #define PEX_PF0_PME_MES_IER 0xC0028 31 #define PEX_PF0_PME_MES_IER_LUDIE BIT(7) 32 #define PEX_PF0_PME_MES_IER_LDDIE BIT(9) 33 #define PEX_PF0_PME_MES_IER_HRDIE BIT(10) 34 35 #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev) 36 37 struct ls_pcie_ep_drvdata { 38 u32 func_offset; 39 const struct dw_pcie_ep_ops *ops; 40 const struct dw_pcie_ops *dw_pcie_ops; 41 }; 42 43 struct ls_pcie_ep { 44 struct dw_pcie *pci; 45 struct pci_epc_features *ls_epc; 46 const struct ls_pcie_ep_drvdata *drvdata; 47 int irq; 48 bool big_endian; 49 }; 50 51 static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset) 52 { 53 struct dw_pcie *pci = pcie->pci; 54 55 if (pcie->big_endian) 56 return ioread32be(pci->dbi_base + offset); 57 else 58 return ioread32(pci->dbi_base + offset); 59 } 60 61 static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset, u32 value) 62 { 63 struct dw_pcie *pci = pcie->pci; 64 65 if (pcie->big_endian) 66 iowrite32be(value, pci->dbi_base + offset); 67 else 68 iowrite32(value, pci->dbi_base + offset); 69 } 70 71 static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id) 72 { 73 struct ls_pcie_ep *pcie = dev_id; 74 struct dw_pcie *pci = pcie->pci; 75 u32 val, cfg; 76 77 val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR); 78 ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val); 79 80 if (!val) 81 return IRQ_NONE; 82 83 if (val & PEX_PF0_PME_MES_DR_LUD) { 84 cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG); 85 cfg |= PEX_PF0_CFG_READY; 86 ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg); 87 dw_pcie_ep_linkup(&pci->ep); 88 89 dev_dbg(pci->dev, "Link up\n"); 90 } else if (val & PEX_PF0_PME_MES_DR_LDD) { 91 dev_dbg(pci->dev, "Link down\n"); 92 } else if (val & PEX_PF0_PME_MES_DR_HRD) { 93 dev_dbg(pci->dev, "Hot reset\n"); 94 } 95 96 return IRQ_HANDLED; 97 } 98 99 static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie, 100 struct platform_device *pdev) 101 { 102 u32 val; 103 int ret; 104 105 pcie->irq = platform_get_irq_byname(pdev, "pme"); 106 if (pcie->irq < 0) 107 return pcie->irq; 108 109 ret = devm_request_irq(&pdev->dev, pcie->irq, ls_pcie_ep_event_handler, 110 IRQF_SHARED, pdev->name, pcie); 111 if (ret) { 112 dev_err(&pdev->dev, "Can't register PCIe IRQ\n"); 113 return ret; 114 } 115 116 /* Enable interrupts */ 117 val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER); 118 val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE | 119 PEX_PF0_PME_MES_IER_LUDIE; 120 ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val); 121 122 return 0; 123 } 124 125 static const struct pci_epc_features* 126 ls_pcie_ep_get_features(struct dw_pcie_ep *ep) 127 { 128 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 129 struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci); 130 131 return pcie->ls_epc; 132 } 133 134 static void ls_pcie_ep_init(struct dw_pcie_ep *ep) 135 { 136 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 137 struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci); 138 struct dw_pcie_ep_func *ep_func; 139 enum pci_barno bar; 140 141 ep_func = dw_pcie_ep_get_func_from_ep(ep, 0); 142 if (!ep_func) 143 return; 144 145 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 146 dw_pcie_ep_reset_bar(pci, bar); 147 148 pcie->ls_epc->msi_capable = ep_func->msi_cap ? true : false; 149 pcie->ls_epc->msix_capable = ep_func->msix_cap ? true : false; 150 } 151 152 static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 153 enum pci_epc_irq_type type, u16 interrupt_num) 154 { 155 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 156 157 switch (type) { 158 case PCI_EPC_IRQ_LEGACY: 159 return dw_pcie_ep_raise_legacy_irq(ep, func_no); 160 case PCI_EPC_IRQ_MSI: 161 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 162 case PCI_EPC_IRQ_MSIX: 163 return dw_pcie_ep_raise_msix_irq_doorbell(ep, func_no, 164 interrupt_num); 165 default: 166 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 167 return -EINVAL; 168 } 169 } 170 171 static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep *ep, 172 u8 func_no) 173 { 174 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 175 struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci); 176 177 WARN_ON(func_no && !pcie->drvdata->func_offset); 178 return pcie->drvdata->func_offset * func_no; 179 } 180 181 static const struct dw_pcie_ep_ops ls_pcie_ep_ops = { 182 .ep_init = ls_pcie_ep_init, 183 .raise_irq = ls_pcie_ep_raise_irq, 184 .get_features = ls_pcie_ep_get_features, 185 .func_conf_select = ls_pcie_ep_func_conf_select, 186 }; 187 188 static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = { 189 .ops = &ls_pcie_ep_ops, 190 }; 191 192 static const struct ls_pcie_ep_drvdata ls2_ep_drvdata = { 193 .func_offset = 0x20000, 194 .ops = &ls_pcie_ep_ops, 195 }; 196 197 static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = { 198 .func_offset = 0x8000, 199 .ops = &ls_pcie_ep_ops, 200 }; 201 202 static const struct of_device_id ls_pcie_ep_of_match[] = { 203 { .compatible = "fsl,ls1028a-pcie-ep", .data = &ls1_ep_drvdata }, 204 { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata }, 205 { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata }, 206 { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata }, 207 { .compatible = "fsl,lx2160ar2-pcie-ep", .data = &lx2_ep_drvdata }, 208 { }, 209 }; 210 211 static int __init ls_pcie_ep_probe(struct platform_device *pdev) 212 { 213 struct device *dev = &pdev->dev; 214 struct dw_pcie *pci; 215 struct ls_pcie_ep *pcie; 216 struct pci_epc_features *ls_epc; 217 struct resource *dbi_base; 218 int ret; 219 220 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 221 if (!pcie) 222 return -ENOMEM; 223 224 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 225 if (!pci) 226 return -ENOMEM; 227 228 ls_epc = devm_kzalloc(dev, sizeof(*ls_epc), GFP_KERNEL); 229 if (!ls_epc) 230 return -ENOMEM; 231 232 pcie->drvdata = of_device_get_match_data(dev); 233 234 pci->dev = dev; 235 pci->ops = pcie->drvdata->dw_pcie_ops; 236 237 ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4); 238 ls_epc->linkup_notifier = true; 239 240 pcie->pci = pci; 241 pcie->ls_epc = ls_epc; 242 243 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 244 pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); 245 if (IS_ERR(pci->dbi_base)) 246 return PTR_ERR(pci->dbi_base); 247 248 pci->ep.ops = &ls_pcie_ep_ops; 249 250 pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian"); 251 252 platform_set_drvdata(pdev, pcie); 253 254 ret = dw_pcie_ep_init(&pci->ep); 255 if (ret) 256 return ret; 257 258 return ls_pcie_ep_interrupt_init(pcie, pdev); 259 } 260 261 static struct platform_driver ls_pcie_ep_driver = { 262 .driver = { 263 .name = "layerscape-pcie-ep", 264 .of_match_table = ls_pcie_ep_of_match, 265 .suppress_bind_attrs = true, 266 }, 267 }; 268 builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe); 269