0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/pci.h>
0012 #include <linux/pci-ecam.h>
0013 #include <linux/pci-acpi.h>
0014 #include "../../pci.h"
0015
0016 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
0017
0018 struct al_pcie_acpi {
0019 void __iomem *dbi_base;
0020 };
0021
0022 static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
0023 int where)
0024 {
0025 struct pci_config_window *cfg = bus->sysdata;
0026 struct al_pcie_acpi *pcie = cfg->priv;
0027 void __iomem *dbi_base = pcie->dbi_base;
0028
0029 if (bus->number == cfg->busr.start) {
0030
0031
0032
0033
0034 if (PCI_SLOT(devfn) > 0)
0035 return NULL;
0036 else
0037 return dbi_base + where;
0038 }
0039
0040 return pci_ecam_map_bus(bus, devfn, where);
0041 }
0042
0043 static int al_pcie_init(struct pci_config_window *cfg)
0044 {
0045 struct device *dev = cfg->parent;
0046 struct acpi_device *adev = to_acpi_device(dev);
0047 struct acpi_pci_root *root = acpi_driver_data(adev);
0048 struct al_pcie_acpi *al_pcie;
0049 struct resource *res;
0050 int ret;
0051
0052 al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
0053 if (!al_pcie)
0054 return -ENOMEM;
0055
0056 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
0057 if (!res)
0058 return -ENOMEM;
0059
0060 ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res);
0061 if (ret) {
0062 dev_err(dev, "can't get rc dbi base address for SEG %d\n",
0063 root->segment);
0064 return ret;
0065 }
0066
0067 dev_dbg(dev, "Root port dbi res: %pR\n", res);
0068
0069 al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
0070 if (IS_ERR(al_pcie->dbi_base))
0071 return PTR_ERR(al_pcie->dbi_base);
0072
0073 cfg->priv = al_pcie;
0074
0075 return 0;
0076 }
0077
0078 const struct pci_ecam_ops al_pcie_ops = {
0079 .init = al_pcie_init,
0080 .pci_ops = {
0081 .map_bus = al_pcie_map_bus,
0082 .read = pci_generic_config_read,
0083 .write = pci_generic_config_write,
0084 }
0085 };
0086
0087 #endif
0088
0089 #ifdef CONFIG_PCIE_AL
0090
0091 #include <linux/of_pci.h>
0092 #include "pcie-designware.h"
0093
0094 #define AL_PCIE_REV_ID_2 2
0095 #define AL_PCIE_REV_ID_3 3
0096 #define AL_PCIE_REV_ID_4 4
0097
0098 #define AXI_BASE_OFFSET 0x0
0099
0100 #define DEVICE_ID_OFFSET 0x16c
0101
0102 #define DEVICE_REV_ID 0x0
0103 #define DEVICE_REV_ID_DEV_ID_MASK GENMASK(31, 16)
0104
0105 #define DEVICE_REV_ID_DEV_ID_X4 0
0106 #define DEVICE_REV_ID_DEV_ID_X8 2
0107 #define DEVICE_REV_ID_DEV_ID_X16 4
0108
0109 #define OB_CTRL_REV1_2_OFFSET 0x0040
0110 #define OB_CTRL_REV3_5_OFFSET 0x0030
0111
0112 #define CFG_TARGET_BUS 0x0
0113 #define CFG_TARGET_BUS_MASK_MASK GENMASK(7, 0)
0114 #define CFG_TARGET_BUS_BUSNUM_MASK GENMASK(15, 8)
0115
0116 #define CFG_CONTROL 0x4
0117 #define CFG_CONTROL_SUBBUS_MASK GENMASK(15, 8)
0118 #define CFG_CONTROL_SEC_BUS_MASK GENMASK(23, 16)
0119
0120 struct al_pcie_reg_offsets {
0121 unsigned int ob_ctrl;
0122 };
0123
0124 struct al_pcie_target_bus_cfg {
0125 u8 reg_val;
0126 u8 reg_mask;
0127 u8 ecam_mask;
0128 };
0129
0130 struct al_pcie {
0131 struct dw_pcie *pci;
0132 void __iomem *controller_base;
0133 struct device *dev;
0134 resource_size_t ecam_size;
0135 unsigned int controller_rev_id;
0136 struct al_pcie_reg_offsets reg_offsets;
0137 struct al_pcie_target_bus_cfg target_bus_cfg;
0138 };
0139
0140 #define to_al_pcie(x) dev_get_drvdata((x)->dev)
0141
0142 static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
0143 {
0144 return readl_relaxed(pcie->controller_base + offset);
0145 }
0146
0147 static inline void al_pcie_controller_writel(struct al_pcie *pcie, u32 offset,
0148 u32 val)
0149 {
0150 writel_relaxed(val, pcie->controller_base + offset);
0151 }
0152
0153 static int al_pcie_rev_id_get(struct al_pcie *pcie, unsigned int *rev_id)
0154 {
0155 u32 dev_rev_id_val;
0156 u32 dev_id_val;
0157
0158 dev_rev_id_val = al_pcie_controller_readl(pcie, AXI_BASE_OFFSET +
0159 DEVICE_ID_OFFSET +
0160 DEVICE_REV_ID);
0161 dev_id_val = FIELD_GET(DEVICE_REV_ID_DEV_ID_MASK, dev_rev_id_val);
0162
0163 switch (dev_id_val) {
0164 case DEVICE_REV_ID_DEV_ID_X4:
0165 *rev_id = AL_PCIE_REV_ID_2;
0166 break;
0167 case DEVICE_REV_ID_DEV_ID_X8:
0168 *rev_id = AL_PCIE_REV_ID_3;
0169 break;
0170 case DEVICE_REV_ID_DEV_ID_X16:
0171 *rev_id = AL_PCIE_REV_ID_4;
0172 break;
0173 default:
0174 dev_err(pcie->dev, "Unsupported dev_id_val (0x%x)\n",
0175 dev_id_val);
0176 return -EINVAL;
0177 }
0178
0179 dev_dbg(pcie->dev, "dev_id_val: 0x%x\n", dev_id_val);
0180
0181 return 0;
0182 }
0183
0184 static int al_pcie_reg_offsets_set(struct al_pcie *pcie)
0185 {
0186 switch (pcie->controller_rev_id) {
0187 case AL_PCIE_REV_ID_2:
0188 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV1_2_OFFSET;
0189 break;
0190 case AL_PCIE_REV_ID_3:
0191 case AL_PCIE_REV_ID_4:
0192 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV3_5_OFFSET;
0193 break;
0194 default:
0195 dev_err(pcie->dev, "Unsupported controller rev_id: 0x%x\n",
0196 pcie->controller_rev_id);
0197 return -EINVAL;
0198 }
0199
0200 return 0;
0201 }
0202
0203 static inline void al_pcie_target_bus_set(struct al_pcie *pcie,
0204 u8 target_bus,
0205 u8 mask_target_bus)
0206 {
0207 u32 reg;
0208
0209 reg = FIELD_PREP(CFG_TARGET_BUS_MASK_MASK, mask_target_bus) |
0210 FIELD_PREP(CFG_TARGET_BUS_BUSNUM_MASK, target_bus);
0211
0212 al_pcie_controller_writel(pcie, AXI_BASE_OFFSET +
0213 pcie->reg_offsets.ob_ctrl + CFG_TARGET_BUS,
0214 reg);
0215 }
0216
0217 static void __iomem *al_pcie_conf_addr_map_bus(struct pci_bus *bus,
0218 unsigned int devfn, int where)
0219 {
0220 struct dw_pcie_rp *pp = bus->sysdata;
0221 struct al_pcie *pcie = to_al_pcie(to_dw_pcie_from_pp(pp));
0222 unsigned int busnr = bus->number;
0223 struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;
0224 unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;
0225 unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask;
0226
0227 if (busnr_reg != target_bus_cfg->reg_val) {
0228 dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n",
0229 target_bus_cfg->reg_val, busnr_reg);
0230 target_bus_cfg->reg_val = busnr_reg;
0231 al_pcie_target_bus_set(pcie,
0232 target_bus_cfg->reg_val,
0233 target_bus_cfg->reg_mask);
0234 }
0235
0236 return pp->va_cfg0_base + PCIE_ECAM_OFFSET(busnr_ecam, devfn, where);
0237 }
0238
0239 static struct pci_ops al_child_pci_ops = {
0240 .map_bus = al_pcie_conf_addr_map_bus,
0241 .read = pci_generic_config_read,
0242 .write = pci_generic_config_write,
0243 };
0244
0245 static void al_pcie_config_prepare(struct al_pcie *pcie)
0246 {
0247 struct al_pcie_target_bus_cfg *target_bus_cfg;
0248 struct dw_pcie_rp *pp = &pcie->pci->pp;
0249 unsigned int ecam_bus_mask;
0250 u32 cfg_control_offset;
0251 u8 subordinate_bus;
0252 u8 secondary_bus;
0253 u32 cfg_control;
0254 u32 reg;
0255 struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
0256
0257 target_bus_cfg = &pcie->target_bus_cfg;
0258
0259 ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;
0260 if (ecam_bus_mask > 255) {
0261 dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");
0262 ecam_bus_mask = 255;
0263 }
0264
0265
0266 target_bus_cfg->ecam_mask = ecam_bus_mask;
0267
0268 target_bus_cfg->reg_mask = ~target_bus_cfg->ecam_mask;
0269 target_bus_cfg->reg_val = bus->start & target_bus_cfg->reg_mask;
0270
0271 al_pcie_target_bus_set(pcie, target_bus_cfg->reg_val,
0272 target_bus_cfg->reg_mask);
0273
0274 secondary_bus = bus->start + 1;
0275 subordinate_bus = bus->end;
0276
0277
0278 cfg_control_offset = AXI_BASE_OFFSET + pcie->reg_offsets.ob_ctrl +
0279 CFG_CONTROL;
0280
0281 cfg_control = al_pcie_controller_readl(pcie, cfg_control_offset);
0282
0283 reg = cfg_control &
0284 ~(CFG_CONTROL_SEC_BUS_MASK | CFG_CONTROL_SUBBUS_MASK);
0285
0286 reg |= FIELD_PREP(CFG_CONTROL_SUBBUS_MASK, subordinate_bus) |
0287 FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
0288
0289 al_pcie_controller_writel(pcie, cfg_control_offset, reg);
0290 }
0291
0292 static int al_pcie_host_init(struct dw_pcie_rp *pp)
0293 {
0294 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
0295 struct al_pcie *pcie = to_al_pcie(pci);
0296 int rc;
0297
0298 pp->bridge->child_ops = &al_child_pci_ops;
0299
0300 rc = al_pcie_rev_id_get(pcie, &pcie->controller_rev_id);
0301 if (rc)
0302 return rc;
0303
0304 rc = al_pcie_reg_offsets_set(pcie);
0305 if (rc)
0306 return rc;
0307
0308 al_pcie_config_prepare(pcie);
0309
0310 return 0;
0311 }
0312
0313 static const struct dw_pcie_host_ops al_pcie_host_ops = {
0314 .host_init = al_pcie_host_init,
0315 };
0316
0317 static int al_pcie_probe(struct platform_device *pdev)
0318 {
0319 struct device *dev = &pdev->dev;
0320 struct resource *controller_res;
0321 struct resource *ecam_res;
0322 struct al_pcie *al_pcie;
0323 struct dw_pcie *pci;
0324
0325 al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
0326 if (!al_pcie)
0327 return -ENOMEM;
0328
0329 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
0330 if (!pci)
0331 return -ENOMEM;
0332
0333 pci->dev = dev;
0334 pci->pp.ops = &al_pcie_host_ops;
0335
0336 al_pcie->pci = pci;
0337 al_pcie->dev = dev;
0338
0339 ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
0340 if (!ecam_res) {
0341 dev_err(dev, "couldn't find 'config' reg in DT\n");
0342 return -ENOENT;
0343 }
0344 al_pcie->ecam_size = resource_size(ecam_res);
0345
0346 controller_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
0347 "controller");
0348 al_pcie->controller_base = devm_ioremap_resource(dev, controller_res);
0349 if (IS_ERR(al_pcie->controller_base)) {
0350 dev_err(dev, "couldn't remap controller base %pR\n",
0351 controller_res);
0352 return PTR_ERR(al_pcie->controller_base);
0353 }
0354
0355 dev_dbg(dev, "From DT: controller_base: %pR\n", controller_res);
0356
0357 platform_set_drvdata(pdev, al_pcie);
0358
0359 return dw_pcie_host_init(&pci->pp);
0360 }
0361
0362 static const struct of_device_id al_pcie_of_match[] = {
0363 { .compatible = "amazon,al-alpine-v2-pcie",
0364 },
0365 { .compatible = "amazon,al-alpine-v3-pcie",
0366 },
0367 {},
0368 };
0369
0370 static struct platform_driver al_pcie_driver = {
0371 .driver = {
0372 .name = "al-pcie",
0373 .of_match_table = al_pcie_of_match,
0374 .suppress_bind_attrs = true,
0375 },
0376 .probe = al_pcie_probe,
0377 };
0378 builtin_platform_driver(al_pcie_driver);
0379
0380 #endif