root/drivers/pci/controller/dwc/pcie-al.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. al_pcie_map_bus
  2. al_pcie_init
  3. al_pcie_controller_readl
  4. al_pcie_controller_writel
  5. al_pcie_rev_id_get
  6. al_pcie_reg_offsets_set
  7. al_pcie_target_bus_set
  8. al_pcie_conf_addr_map
  9. al_pcie_rd_other_conf
  10. al_pcie_wr_other_conf
  11. al_pcie_config_prepare
  12. al_pcie_host_init
  13. al_add_pcie_port
  14. al_pcie_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * PCIe host controller driver for Amazon's Annapurna Labs IP (used in chips
   4  * such as Graviton and Alpine)
   5  *
   6  * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   7  *
   8  * Author: Jonathan Chocron <jonnyc@amazon.com>
   9  */
  10 
  11 #include <linux/pci.h>
  12 #include <linux/pci-ecam.h>
  13 #include <linux/pci-acpi.h>
  14 #include "../../pci.h"
  15 
  16 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
  17 
  18 struct al_pcie_acpi  {
  19         void __iomem *dbi_base;
  20 };
  21 
  22 static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
  23                                      int where)
  24 {
  25         struct pci_config_window *cfg = bus->sysdata;
  26         struct al_pcie_acpi *pcie = cfg->priv;
  27         void __iomem *dbi_base = pcie->dbi_base;
  28 
  29         if (bus->number == cfg->busr.start) {
  30                 /*
  31                  * The DW PCIe core doesn't filter out transactions to other
  32                  * devices/functions on the root bus num, so we do this here.
  33                  */
  34                 if (PCI_SLOT(devfn) > 0)
  35                         return NULL;
  36                 else
  37                         return dbi_base + where;
  38         }
  39 
  40         return pci_ecam_map_bus(bus, devfn, where);
  41 }
  42 
  43 static int al_pcie_init(struct pci_config_window *cfg)
  44 {
  45         struct device *dev = cfg->parent;
  46         struct acpi_device *adev = to_acpi_device(dev);
  47         struct acpi_pci_root *root = acpi_driver_data(adev);
  48         struct al_pcie_acpi *al_pcie;
  49         struct resource *res;
  50         int ret;
  51 
  52         al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
  53         if (!al_pcie)
  54                 return -ENOMEM;
  55 
  56         res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
  57         if (!res)
  58                 return -ENOMEM;
  59 
  60         ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res);
  61         if (ret) {
  62                 dev_err(dev, "can't get rc dbi base address for SEG %d\n",
  63                         root->segment);
  64                 return ret;
  65         }
  66 
  67         dev_dbg(dev, "Root port dbi res: %pR\n", res);
  68 
  69         al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
  70         if (IS_ERR(al_pcie->dbi_base)) {
  71                 long err = PTR_ERR(al_pcie->dbi_base);
  72 
  73                 dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n",
  74                         res, err);
  75                 return err;
  76         }
  77 
  78         cfg->priv = al_pcie;
  79 
  80         return 0;
  81 }
  82 
  83 struct pci_ecam_ops al_pcie_ops = {
  84         .bus_shift    = 20,
  85         .init         =  al_pcie_init,
  86         .pci_ops      = {
  87                 .map_bus    = al_pcie_map_bus,
  88                 .read       = pci_generic_config_read,
  89                 .write      = pci_generic_config_write,
  90         }
  91 };
  92 
  93 #endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
  94 
  95 #ifdef CONFIG_PCIE_AL
  96 
  97 #include <linux/of_pci.h>
  98 #include "pcie-designware.h"
  99 
 100 #define AL_PCIE_REV_ID_2        2
 101 #define AL_PCIE_REV_ID_3        3
 102 #define AL_PCIE_REV_ID_4        4
 103 
 104 #define AXI_BASE_OFFSET         0x0
 105 
 106 #define DEVICE_ID_OFFSET        0x16c
 107 
 108 #define DEVICE_REV_ID                   0x0
 109 #define DEVICE_REV_ID_DEV_ID_MASK       GENMASK(31, 16)
 110 
 111 #define DEVICE_REV_ID_DEV_ID_X4         0
 112 #define DEVICE_REV_ID_DEV_ID_X8         2
 113 #define DEVICE_REV_ID_DEV_ID_X16        4
 114 
 115 #define OB_CTRL_REV1_2_OFFSET   0x0040
 116 #define OB_CTRL_REV3_5_OFFSET   0x0030
 117 
 118 #define CFG_TARGET_BUS                  0x0
 119 #define CFG_TARGET_BUS_MASK_MASK        GENMASK(7, 0)
 120 #define CFG_TARGET_BUS_BUSNUM_MASK      GENMASK(15, 8)
 121 
 122 #define CFG_CONTROL                     0x4
 123 #define CFG_CONTROL_SUBBUS_MASK         GENMASK(15, 8)
 124 #define CFG_CONTROL_SEC_BUS_MASK        GENMASK(23, 16)
 125 
 126 struct al_pcie_reg_offsets {
 127         unsigned int ob_ctrl;
 128 };
 129 
 130 struct al_pcie_target_bus_cfg {
 131         u8 reg_val;
 132         u8 reg_mask;
 133         u8 ecam_mask;
 134 };
 135 
 136 struct al_pcie {
 137         struct dw_pcie *pci;
 138         void __iomem *controller_base; /* base of PCIe unit (not DW core) */
 139         struct device *dev;
 140         resource_size_t ecam_size;
 141         unsigned int controller_rev_id;
 142         struct al_pcie_reg_offsets reg_offsets;
 143         struct al_pcie_target_bus_cfg target_bus_cfg;
 144 };
 145 
 146 #define PCIE_ECAM_DEVFN(x)              (((x) & 0xff) << 12)
 147 
 148 #define to_al_pcie(x)           dev_get_drvdata((x)->dev)
 149 
 150 static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
 151 {
 152         return readl_relaxed(pcie->controller_base + offset);
 153 }
 154 
 155 static inline void al_pcie_controller_writel(struct al_pcie *pcie, u32 offset,
 156                                              u32 val)
 157 {
 158         writel_relaxed(val, pcie->controller_base + offset);
 159 }
 160 
 161 static int al_pcie_rev_id_get(struct al_pcie *pcie, unsigned int *rev_id)
 162 {
 163         u32 dev_rev_id_val;
 164         u32 dev_id_val;
 165 
 166         dev_rev_id_val = al_pcie_controller_readl(pcie, AXI_BASE_OFFSET +
 167                                                   DEVICE_ID_OFFSET +
 168                                                   DEVICE_REV_ID);
 169         dev_id_val = FIELD_GET(DEVICE_REV_ID_DEV_ID_MASK, dev_rev_id_val);
 170 
 171         switch (dev_id_val) {
 172         case DEVICE_REV_ID_DEV_ID_X4:
 173                 *rev_id = AL_PCIE_REV_ID_2;
 174                 break;
 175         case DEVICE_REV_ID_DEV_ID_X8:
 176                 *rev_id = AL_PCIE_REV_ID_3;
 177                 break;
 178         case DEVICE_REV_ID_DEV_ID_X16:
 179                 *rev_id = AL_PCIE_REV_ID_4;
 180                 break;
 181         default:
 182                 dev_err(pcie->dev, "Unsupported dev_id_val (0x%x)\n",
 183                         dev_id_val);
 184                 return -EINVAL;
 185         }
 186 
 187         dev_dbg(pcie->dev, "dev_id_val: 0x%x\n", dev_id_val);
 188 
 189         return 0;
 190 }
 191 
 192 static int al_pcie_reg_offsets_set(struct al_pcie *pcie)
 193 {
 194         switch (pcie->controller_rev_id) {
 195         case AL_PCIE_REV_ID_2:
 196                 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV1_2_OFFSET;
 197                 break;
 198         case AL_PCIE_REV_ID_3:
 199         case AL_PCIE_REV_ID_4:
 200                 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV3_5_OFFSET;
 201                 break;
 202         default:
 203                 dev_err(pcie->dev, "Unsupported controller rev_id: 0x%x\n",
 204                         pcie->controller_rev_id);
 205                 return -EINVAL;
 206         }
 207 
 208         return 0;
 209 }
 210 
 211 static inline void al_pcie_target_bus_set(struct al_pcie *pcie,
 212                                           u8 target_bus,
 213                                           u8 mask_target_bus)
 214 {
 215         u32 reg;
 216 
 217         reg = FIELD_PREP(CFG_TARGET_BUS_MASK_MASK, mask_target_bus) |
 218               FIELD_PREP(CFG_TARGET_BUS_BUSNUM_MASK, target_bus);
 219 
 220         al_pcie_controller_writel(pcie, AXI_BASE_OFFSET +
 221                                   pcie->reg_offsets.ob_ctrl + CFG_TARGET_BUS,
 222                                   reg);
 223 }
 224 
 225 static void __iomem *al_pcie_conf_addr_map(struct al_pcie *pcie,
 226                                            unsigned int busnr,
 227                                            unsigned int devfn)
 228 {
 229         struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;
 230         unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;
 231         unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask;
 232         struct pcie_port *pp = &pcie->pci->pp;
 233         void __iomem *pci_base_addr;
 234 
 235         pci_base_addr = (void __iomem *)((uintptr_t)pp->va_cfg0_base +
 236                                          (busnr_ecam << 20) +
 237                                          PCIE_ECAM_DEVFN(devfn));
 238 
 239         if (busnr_reg != target_bus_cfg->reg_val) {
 240                 dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n",
 241                         target_bus_cfg->reg_val, busnr_reg);
 242                 target_bus_cfg->reg_val = busnr_reg;
 243                 al_pcie_target_bus_set(pcie,
 244                                        target_bus_cfg->reg_val,
 245                                        target_bus_cfg->reg_mask);
 246         }
 247 
 248         return pci_base_addr;
 249 }
 250 
 251 static int al_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 252                                  unsigned int devfn, int where, int size,
 253                                  u32 *val)
 254 {
 255         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 256         struct al_pcie *pcie = to_al_pcie(pci);
 257         unsigned int busnr = bus->number;
 258         void __iomem *pci_addr;
 259         int rc;
 260 
 261         pci_addr = al_pcie_conf_addr_map(pcie, busnr, devfn);
 262 
 263         rc = dw_pcie_read(pci_addr + where, size, val);
 264 
 265         dev_dbg(pci->dev, "%d-byte config read from %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n",
 266                 size, pci_domain_nr(bus), bus->number,
 267                 PCI_SLOT(devfn), PCI_FUNC(devfn), where,
 268                 (pci_addr + where), *val);
 269 
 270         return rc;
 271 }
 272 
 273 static int al_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 274                                  unsigned int devfn, int where, int size,
 275                                  u32 val)
 276 {
 277         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 278         struct al_pcie *pcie = to_al_pcie(pci);
 279         unsigned int busnr = bus->number;
 280         void __iomem *pci_addr;
 281         int rc;
 282 
 283         pci_addr = al_pcie_conf_addr_map(pcie, busnr, devfn);
 284 
 285         rc = dw_pcie_write(pci_addr + where, size, val);
 286 
 287         dev_dbg(pci->dev, "%d-byte config write to %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n",
 288                 size, pci_domain_nr(bus), bus->number,
 289                 PCI_SLOT(devfn), PCI_FUNC(devfn), where,
 290                 (pci_addr + where), val);
 291 
 292         return rc;
 293 }
 294 
 295 static void al_pcie_config_prepare(struct al_pcie *pcie)
 296 {
 297         struct al_pcie_target_bus_cfg *target_bus_cfg;
 298         struct pcie_port *pp = &pcie->pci->pp;
 299         unsigned int ecam_bus_mask;
 300         u32 cfg_control_offset;
 301         u8 subordinate_bus;
 302         u8 secondary_bus;
 303         u32 cfg_control;
 304         u32 reg;
 305 
 306         target_bus_cfg = &pcie->target_bus_cfg;
 307 
 308         ecam_bus_mask = (pcie->ecam_size >> 20) - 1;
 309         if (ecam_bus_mask > 255) {
 310                 dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");
 311                 ecam_bus_mask = 255;
 312         }
 313 
 314         /* This portion is taken from the transaction address */
 315         target_bus_cfg->ecam_mask = ecam_bus_mask;
 316         /* This portion is taken from the cfg_target_bus reg */
 317         target_bus_cfg->reg_mask = ~target_bus_cfg->ecam_mask;
 318         target_bus_cfg->reg_val = pp->busn->start & target_bus_cfg->reg_mask;
 319 
 320         al_pcie_target_bus_set(pcie, target_bus_cfg->reg_val,
 321                                target_bus_cfg->reg_mask);
 322 
 323         secondary_bus = pp->busn->start + 1;
 324         subordinate_bus = pp->busn->end;
 325 
 326         /* Set the valid values of secondary and subordinate buses */
 327         cfg_control_offset = AXI_BASE_OFFSET + pcie->reg_offsets.ob_ctrl +
 328                              CFG_CONTROL;
 329 
 330         cfg_control = al_pcie_controller_readl(pcie, cfg_control_offset);
 331 
 332         reg = cfg_control &
 333               ~(CFG_CONTROL_SEC_BUS_MASK | CFG_CONTROL_SUBBUS_MASK);
 334 
 335         reg |= FIELD_PREP(CFG_CONTROL_SUBBUS_MASK, subordinate_bus) |
 336                FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
 337 
 338         al_pcie_controller_writel(pcie, cfg_control_offset, reg);
 339 }
 340 
 341 static int al_pcie_host_init(struct pcie_port *pp)
 342 {
 343         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 344         struct al_pcie *pcie = to_al_pcie(pci);
 345         int rc;
 346 
 347         rc = al_pcie_rev_id_get(pcie, &pcie->controller_rev_id);
 348         if (rc)
 349                 return rc;
 350 
 351         rc = al_pcie_reg_offsets_set(pcie);
 352         if (rc)
 353                 return rc;
 354 
 355         al_pcie_config_prepare(pcie);
 356 
 357         return 0;
 358 }
 359 
 360 static const struct dw_pcie_host_ops al_pcie_host_ops = {
 361         .rd_other_conf = al_pcie_rd_other_conf,
 362         .wr_other_conf = al_pcie_wr_other_conf,
 363         .host_init = al_pcie_host_init,
 364 };
 365 
 366 static int al_add_pcie_port(struct pcie_port *pp,
 367                             struct platform_device *pdev)
 368 {
 369         struct device *dev = &pdev->dev;
 370         int ret;
 371 
 372         pp->ops = &al_pcie_host_ops;
 373 
 374         ret = dw_pcie_host_init(pp);
 375         if (ret) {
 376                 dev_err(dev, "failed to initialize host\n");
 377                 return ret;
 378         }
 379 
 380         return 0;
 381 }
 382 
 383 static const struct dw_pcie_ops dw_pcie_ops = {
 384 };
 385 
 386 static int al_pcie_probe(struct platform_device *pdev)
 387 {
 388         struct device *dev = &pdev->dev;
 389         struct resource *controller_res;
 390         struct resource *ecam_res;
 391         struct resource *dbi_res;
 392         struct al_pcie *al_pcie;
 393         struct dw_pcie *pci;
 394 
 395         al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
 396         if (!al_pcie)
 397                 return -ENOMEM;
 398 
 399         pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
 400         if (!pci)
 401                 return -ENOMEM;
 402 
 403         pci->dev = dev;
 404         pci->ops = &dw_pcie_ops;
 405 
 406         al_pcie->pci = pci;
 407         al_pcie->dev = dev;
 408 
 409         dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
 410         pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
 411         if (IS_ERR(pci->dbi_base)) {
 412                 dev_err(dev, "couldn't remap dbi base %pR\n", dbi_res);
 413                 return PTR_ERR(pci->dbi_base);
 414         }
 415 
 416         ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 417         if (!ecam_res) {
 418                 dev_err(dev, "couldn't find 'config' reg in DT\n");
 419                 return -ENOENT;
 420         }
 421         al_pcie->ecam_size = resource_size(ecam_res);
 422 
 423         controller_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 424                                                       "controller");
 425         al_pcie->controller_base = devm_ioremap_resource(dev, controller_res);
 426         if (IS_ERR(al_pcie->controller_base)) {
 427                 dev_err(dev, "couldn't remap controller base %pR\n",
 428                         controller_res);
 429                 return PTR_ERR(al_pcie->controller_base);
 430         }
 431 
 432         dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n",
 433                 dbi_res, controller_res);
 434 
 435         platform_set_drvdata(pdev, al_pcie);
 436 
 437         return al_add_pcie_port(&pci->pp, pdev);
 438 }
 439 
 440 static const struct of_device_id al_pcie_of_match[] = {
 441         { .compatible = "amazon,al-alpine-v2-pcie",
 442         },
 443         { .compatible = "amazon,al-alpine-v3-pcie",
 444         },
 445         {},
 446 };
 447 
 448 static struct platform_driver al_pcie_driver = {
 449         .driver = {
 450                 .name   = "al-pcie",
 451                 .of_match_table = al_pcie_of_match,
 452                 .suppress_bind_attrs = true,
 453         },
 454         .probe = al_pcie_probe,
 455 };
 456 builtin_platform_driver(al_pcie_driver);
 457 
 458 #endif /* CONFIG_PCIE_AL*/

/* [<][>][^][v][top][bottom][index][help] */