root/drivers/pci/controller/pci-thunder-pem.c

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

DEFINITIONS

This source file includes following definitions.
  1. thunder_pem_bridge_read
  2. thunder_pem_config_read
  3. thunder_pem_bridge_w1c_bits
  4. thunder_pem_bridge_w1_bits
  5. thunder_pem_bridge_write
  6. thunder_pem_config_write
  7. thunder_pem_init
  8. thunder_pem_reserve_range
  9. thunder_pem_legacy_fw
  10. thunder_pem_acpi_init
  11. thunder_pem_platform_init
  12. thunder_pem_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2015 - 2016 Cavium, Inc.
   4  */
   5 
   6 #include <linux/bitfield.h>
   7 #include <linux/kernel.h>
   8 #include <linux/init.h>
   9 #include <linux/of_address.h>
  10 #include <linux/of_pci.h>
  11 #include <linux/pci-acpi.h>
  12 #include <linux/pci-ecam.h>
  13 #include <linux/platform_device.h>
  14 #include "../pci.h"
  15 
  16 #if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
  17 
  18 #define PEM_CFG_WR 0x28
  19 #define PEM_CFG_RD 0x30
  20 
  21 struct thunder_pem_pci {
  22         u32             ea_entry[3];
  23         void __iomem    *pem_reg_base;
  24 };
  25 
  26 static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
  27                                    int where, int size, u32 *val)
  28 {
  29         u64 read_val, tmp_val;
  30         struct pci_config_window *cfg = bus->sysdata;
  31         struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
  32 
  33         if (devfn != 0 || where >= 2048) {
  34                 *val = ~0;
  35                 return PCIBIOS_DEVICE_NOT_FOUND;
  36         }
  37 
  38         /*
  39          * 32-bit accesses only.  Write the address to the low order
  40          * bits of PEM_CFG_RD, then trigger the read by reading back.
  41          * The config data lands in the upper 32-bits of PEM_CFG_RD.
  42          */
  43         read_val = where & ~3ull;
  44         writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD);
  45         read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
  46         read_val >>= 32;
  47 
  48         /*
  49          * The config space contains some garbage, fix it up.  Also
  50          * synthesize an EA capability for the BAR used by MSI-X.
  51          */
  52         switch (where & ~3) {
  53         case 0x40:
  54                 read_val &= 0xffff00ff;
  55                 read_val |= 0x00007000; /* Skip MSI CAP */
  56                 break;
  57         case 0x70: /* Express Cap */
  58                 /*
  59                  * Change PME interrupt to vector 2 on T88 where it
  60                  * reads as 0, else leave it alone.
  61                  */
  62                 if (!(read_val & (0x1f << 25)))
  63                         read_val |= (2u << 25);
  64                 break;
  65         case 0xb0: /* MSI-X Cap */
  66                 /* TableSize=2 or 4, Next Cap is EA */
  67                 read_val &= 0xc00000ff;
  68                 /*
  69                  * If Express Cap(0x70) raw PME vector reads as 0 we are on
  70                  * T88 and TableSize is reported as 4, else TableSize
  71                  * is 2.
  72                  */
  73                 writeq(0x70, pem_pci->pem_reg_base + PEM_CFG_RD);
  74                 tmp_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
  75                 tmp_val >>= 32;
  76                 if (!(tmp_val & (0x1f << 25)))
  77                         read_val |= 0x0003bc00;
  78                 else
  79                         read_val |= 0x0001bc00;
  80                 break;
  81         case 0xb4:
  82                 /* Table offset=0, BIR=0 */
  83                 read_val = 0x00000000;
  84                 break;
  85         case 0xb8:
  86                 /* BPA offset=0xf0000, BIR=0 */
  87                 read_val = 0x000f0000;
  88                 break;
  89         case 0xbc:
  90                 /* EA, 1 entry, no next Cap */
  91                 read_val = 0x00010014;
  92                 break;
  93         case 0xc0:
  94                 /* DW2 for type-1 */
  95                 read_val = 0x00000000;
  96                 break;
  97         case 0xc4:
  98                 /* Entry BEI=0, PP=0x00, SP=0xff, ES=3 */
  99                 read_val = 0x80ff0003;
 100                 break;
 101         case 0xc8:
 102                 read_val = pem_pci->ea_entry[0];
 103                 break;
 104         case 0xcc:
 105                 read_val = pem_pci->ea_entry[1];
 106                 break;
 107         case 0xd0:
 108                 read_val = pem_pci->ea_entry[2];
 109                 break;
 110         default:
 111                 break;
 112         }
 113         read_val >>= (8 * (where & 3));
 114         switch (size) {
 115         case 1:
 116                 read_val &= 0xff;
 117                 break;
 118         case 2:
 119                 read_val &= 0xffff;
 120                 break;
 121         default:
 122                 break;
 123         }
 124         *val = read_val;
 125         return PCIBIOS_SUCCESSFUL;
 126 }
 127 
 128 static int thunder_pem_config_read(struct pci_bus *bus, unsigned int devfn,
 129                                    int where, int size, u32 *val)
 130 {
 131         struct pci_config_window *cfg = bus->sysdata;
 132 
 133         if (bus->number < cfg->busr.start ||
 134             bus->number > cfg->busr.end)
 135                 return PCIBIOS_DEVICE_NOT_FOUND;
 136 
 137         /*
 138          * The first device on the bus is the PEM PCIe bridge.
 139          * Special case its config access.
 140          */
 141         if (bus->number == cfg->busr.start)
 142                 return thunder_pem_bridge_read(bus, devfn, where, size, val);
 143 
 144         return pci_generic_config_read(bus, devfn, where, size, val);
 145 }
 146 
 147 /*
 148  * Some of the w1c_bits below also include read-only or non-writable
 149  * reserved bits, this makes the code simpler and is OK as the bits
 150  * are not affected by writing zeros to them.
 151  */
 152 static u32 thunder_pem_bridge_w1c_bits(u64 where_aligned)
 153 {
 154         u32 w1c_bits = 0;
 155 
 156         switch (where_aligned) {
 157         case 0x04: /* Command/Status */
 158         case 0x1c: /* Base and I/O Limit/Secondary Status */
 159                 w1c_bits = 0xff000000;
 160                 break;
 161         case 0x44: /* Power Management Control and Status */
 162                 w1c_bits = 0xfffffe00;
 163                 break;
 164         case 0x78: /* Device Control/Device Status */
 165         case 0x80: /* Link Control/Link Status */
 166         case 0x88: /* Slot Control/Slot Status */
 167         case 0x90: /* Root Status */
 168         case 0xa0: /* Link Control 2 Registers/Link Status 2 */
 169                 w1c_bits = 0xffff0000;
 170                 break;
 171         case 0x104: /* Uncorrectable Error Status */
 172         case 0x110: /* Correctable Error Status */
 173         case 0x130: /* Error Status */
 174         case 0x160: /* Link Control 4 */
 175                 w1c_bits = 0xffffffff;
 176                 break;
 177         default:
 178                 break;
 179         }
 180         return w1c_bits;
 181 }
 182 
 183 /* Some bits must be written to one so they appear to be read-only. */
 184 static u32 thunder_pem_bridge_w1_bits(u64 where_aligned)
 185 {
 186         u32 w1_bits;
 187 
 188         switch (where_aligned) {
 189         case 0x1c: /* I/O Base / I/O Limit, Secondary Status */
 190                 /* Force 32-bit I/O addressing. */
 191                 w1_bits = 0x0101;
 192                 break;
 193         case 0x24: /* Prefetchable Memory Base / Prefetchable Memory Limit */
 194                 /* Force 64-bit addressing */
 195                 w1_bits = 0x00010001;
 196                 break;
 197         default:
 198                 w1_bits = 0;
 199                 break;
 200         }
 201         return w1_bits;
 202 }
 203 
 204 static int thunder_pem_bridge_write(struct pci_bus *bus, unsigned int devfn,
 205                                     int where, int size, u32 val)
 206 {
 207         struct pci_config_window *cfg = bus->sysdata;
 208         struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
 209         u64 write_val, read_val;
 210         u64 where_aligned = where & ~3ull;
 211         u32 mask = 0;
 212 
 213 
 214         if (devfn != 0 || where >= 2048)
 215                 return PCIBIOS_DEVICE_NOT_FOUND;
 216 
 217         /*
 218          * 32-bit accesses only.  If the write is for a size smaller
 219          * than 32-bits, we must first read the 32-bit value and merge
 220          * in the desired bits and then write the whole 32-bits back
 221          * out.
 222          */
 223         switch (size) {
 224         case 1:
 225                 writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD);
 226                 read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
 227                 read_val >>= 32;
 228                 mask = ~(0xff << (8 * (where & 3)));
 229                 read_val &= mask;
 230                 val = (val & 0xff) << (8 * (where & 3));
 231                 val |= (u32)read_val;
 232                 break;
 233         case 2:
 234                 writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD);
 235                 read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
 236                 read_val >>= 32;
 237                 mask = ~(0xffff << (8 * (where & 3)));
 238                 read_val &= mask;
 239                 val = (val & 0xffff) << (8 * (where & 3));
 240                 val |= (u32)read_val;
 241                 break;
 242         default:
 243                 break;
 244         }
 245 
 246         /*
 247          * By expanding the write width to 32 bits, we may
 248          * inadvertently hit some W1C bits that were not intended to
 249          * be written.  Calculate the mask that must be applied to the
 250          * data to be written to avoid these cases.
 251          */
 252         if (mask) {
 253                 u32 w1c_bits = thunder_pem_bridge_w1c_bits(where);
 254 
 255                 if (w1c_bits) {
 256                         mask &= w1c_bits;
 257                         val &= ~mask;
 258                 }
 259         }
 260 
 261         /*
 262          * Some bits must be read-only with value of one.  Since the
 263          * access method allows these to be cleared if a zero is
 264          * written, force them to one before writing.
 265          */
 266         val |= thunder_pem_bridge_w1_bits(where_aligned);
 267 
 268         /*
 269          * Low order bits are the config address, the high order 32
 270          * bits are the data to be written.
 271          */
 272         write_val = (((u64)val) << 32) | where_aligned;
 273         writeq(write_val, pem_pci->pem_reg_base + PEM_CFG_WR);
 274         return PCIBIOS_SUCCESSFUL;
 275 }
 276 
 277 static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn,
 278                                     int where, int size, u32 val)
 279 {
 280         struct pci_config_window *cfg = bus->sysdata;
 281 
 282         if (bus->number < cfg->busr.start ||
 283             bus->number > cfg->busr.end)
 284                 return PCIBIOS_DEVICE_NOT_FOUND;
 285         /*
 286          * The first device on the bus is the PEM PCIe bridge.
 287          * Special case its config access.
 288          */
 289         if (bus->number == cfg->busr.start)
 290                 return thunder_pem_bridge_write(bus, devfn, where, size, val);
 291 
 292 
 293         return pci_generic_config_write(bus, devfn, where, size, val);
 294 }
 295 
 296 static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
 297                             struct resource *res_pem)
 298 {
 299         struct thunder_pem_pci *pem_pci;
 300         resource_size_t bar4_start;
 301 
 302         pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL);
 303         if (!pem_pci)
 304                 return -ENOMEM;
 305 
 306         pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000);
 307         if (!pem_pci->pem_reg_base)
 308                 return -ENOMEM;
 309 
 310         /*
 311          * The MSI-X BAR for the PEM and AER interrupts is located at
 312          * a fixed offset from the PEM register base.  Generate a
 313          * fragment of the synthesized Enhanced Allocation capability
 314          * structure here for the BAR.
 315          */
 316         bar4_start = res_pem->start + 0xf00000;
 317         pem_pci->ea_entry[0] = (u32)bar4_start | 2;
 318         pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u;
 319         pem_pci->ea_entry[2] = (u32)(bar4_start >> 32);
 320 
 321         cfg->priv = pem_pci;
 322         return 0;
 323 }
 324 
 325 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
 326 
 327 #define PEM_RES_BASE            0x87e0c0000000UL
 328 #define PEM_NODE_MASK           GENMASK(45, 44)
 329 #define PEM_INDX_MASK           GENMASK(26, 24)
 330 #define PEM_MIN_DOM_IN_NODE     4
 331 #define PEM_MAX_DOM_IN_NODE     10
 332 
 333 static void thunder_pem_reserve_range(struct device *dev, int seg,
 334                                       struct resource *r)
 335 {
 336         resource_size_t start = r->start, end = r->end;
 337         struct resource *res;
 338         const char *regionid;
 339 
 340         regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
 341         if (!regionid)
 342                 return;
 343 
 344         res = request_mem_region(start, end - start + 1, regionid);
 345         if (res)
 346                 res->flags &= ~IORESOURCE_BUSY;
 347         else
 348                 kfree(regionid);
 349 
 350         dev_info(dev, "%pR %s reserved\n", r,
 351                  res ? "has been" : "could not be");
 352 }
 353 
 354 static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
 355                                  struct resource *res_pem)
 356 {
 357         int node = acpi_get_node(root->device->handle);
 358         int index;
 359 
 360         if (node == NUMA_NO_NODE)
 361                 node = 0;
 362 
 363         index = root->segment - PEM_MIN_DOM_IN_NODE;
 364         index -= node * PEM_MAX_DOM_IN_NODE;
 365         res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
 366                                         FIELD_PREP(PEM_INDX_MASK, index);
 367         res_pem->flags = IORESOURCE_MEM;
 368 }
 369 
 370 static int thunder_pem_acpi_init(struct pci_config_window *cfg)
 371 {
 372         struct device *dev = cfg->parent;
 373         struct acpi_device *adev = to_acpi_device(dev);
 374         struct acpi_pci_root *root = acpi_driver_data(adev);
 375         struct resource *res_pem;
 376         int ret;
 377 
 378         res_pem = devm_kzalloc(&adev->dev, sizeof(*res_pem), GFP_KERNEL);
 379         if (!res_pem)
 380                 return -ENOMEM;
 381 
 382         ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
 383 
 384         /*
 385          * If we fail to gather resources it means that we run with old
 386          * FW where we need to calculate PEM-specific resources manually.
 387          */
 388         if (ret) {
 389                 thunder_pem_legacy_fw(root, res_pem);
 390                 /*
 391                  * Reserve 64K size PEM specific resources. The full 16M range
 392                  * size is required for thunder_pem_init() call.
 393                  */
 394                 res_pem->end = res_pem->start + SZ_64K - 1;
 395                 thunder_pem_reserve_range(dev, root->segment, res_pem);
 396                 res_pem->end = res_pem->start + SZ_16M - 1;
 397 
 398                 /* Reserve PCI configuration space as well. */
 399                 thunder_pem_reserve_range(dev, root->segment, &cfg->res);
 400         }
 401 
 402         return thunder_pem_init(dev, cfg, res_pem);
 403 }
 404 
 405 struct pci_ecam_ops thunder_pem_ecam_ops = {
 406         .bus_shift      = 24,
 407         .init           = thunder_pem_acpi_init,
 408         .pci_ops        = {
 409                 .map_bus        = pci_ecam_map_bus,
 410                 .read           = thunder_pem_config_read,
 411                 .write          = thunder_pem_config_write,
 412         }
 413 };
 414 
 415 #endif
 416 
 417 #ifdef CONFIG_PCI_HOST_THUNDER_PEM
 418 
 419 static int thunder_pem_platform_init(struct pci_config_window *cfg)
 420 {
 421         struct device *dev = cfg->parent;
 422         struct platform_device *pdev = to_platform_device(dev);
 423         struct resource *res_pem;
 424 
 425         if (!dev->of_node)
 426                 return -EINVAL;
 427 
 428         /*
 429          * The second register range is the PEM bridge to the PCIe
 430          * bus.  It has a different config access method than those
 431          * devices behind the bridge.
 432          */
 433         res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 434         if (!res_pem) {
 435                 dev_err(dev, "missing \"reg[1]\"property\n");
 436                 return -EINVAL;
 437         }
 438 
 439         return thunder_pem_init(dev, cfg, res_pem);
 440 }
 441 
 442 static struct pci_ecam_ops pci_thunder_pem_ops = {
 443         .bus_shift      = 24,
 444         .init           = thunder_pem_platform_init,
 445         .pci_ops        = {
 446                 .map_bus        = pci_ecam_map_bus,
 447                 .read           = thunder_pem_config_read,
 448                 .write          = thunder_pem_config_write,
 449         }
 450 };
 451 
 452 static const struct of_device_id thunder_pem_of_match[] = {
 453         { .compatible = "cavium,pci-host-thunder-pem" },
 454         { },
 455 };
 456 
 457 static int thunder_pem_probe(struct platform_device *pdev)
 458 {
 459         return pci_host_common_probe(pdev, &pci_thunder_pem_ops);
 460 }
 461 
 462 static struct platform_driver thunder_pem_driver = {
 463         .driver = {
 464                 .name = KBUILD_MODNAME,
 465                 .of_match_table = thunder_pem_of_match,
 466                 .suppress_bind_attrs = true,
 467         },
 468         .probe = thunder_pem_probe,
 469 };
 470 builtin_platform_driver(thunder_pem_driver);
 471 
 472 #endif
 473 #endif

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