Lines Matching +full:non +full:- +full:prefetchable
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015 - 2016 Cavium, Inc.
12 #include <linux/pci-acpi.h>
13 #include <linux/pci-ecam.h>
15 #include <linux/io-64-nonatomic-lo-hi.h>
17 #include "pci-host-common.h"
27 * N.B. This is a non-standard platform-specific ECAM bus shift value. For
29 * include/linux/pci-ecam.h.
42 struct pci_config_window *cfg = bus->sysdata; in thunder_pem_bridge_read()
43 struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv; in thunder_pem_bridge_read()
49 * 32-bit accesses only. Write the address to the low order in thunder_pem_bridge_read()
51 * The config data lands in the upper 32-bits of PEM_CFG_RD. in thunder_pem_bridge_read()
54 writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_read()
55 read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_read()
60 * synthesize an EA capability for the BAR used by MSI-X. in thunder_pem_bridge_read()
75 case 0xb0: /* MSI-X Cap */ in thunder_pem_bridge_read()
83 writeq(0x70, pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_read()
84 tmp_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_read()
104 /* DW2 for type-1 */ in thunder_pem_bridge_read()
112 read_val = pem_pci->ea_entry[0]; in thunder_pem_bridge_read()
115 read_val = pem_pci->ea_entry[1]; in thunder_pem_bridge_read()
118 read_val = pem_pci->ea_entry[2]; in thunder_pem_bridge_read()
141 struct pci_config_window *cfg = bus->sysdata; in thunder_pem_config_read()
143 if (bus->number < cfg->busr.start || in thunder_pem_config_read()
144 bus->number > cfg->busr.end) in thunder_pem_config_read()
151 if (bus->number == cfg->busr.start) in thunder_pem_config_read()
158 * Some of the w1c_bits below also include read-only or non-writable
193 /* Some bits must be written to one so they appear to be read-only. */
200 /* Force 32-bit I/O addressing. */ in thunder_pem_bridge_w1_bits()
203 case 0x24: /* Prefetchable Memory Base / Prefetchable Memory Limit */ in thunder_pem_bridge_w1_bits()
204 /* Force 64-bit addressing */ in thunder_pem_bridge_w1_bits()
217 struct pci_config_window *cfg = bus->sysdata; in thunder_pem_bridge_write()
218 struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv; in thunder_pem_bridge_write()
228 * 32-bit accesses only. If the write is for a size smaller in thunder_pem_bridge_write()
229 * than 32-bits, we must first read the 32-bit value and merge in thunder_pem_bridge_write()
230 * in the desired bits and then write the whole 32-bits back in thunder_pem_bridge_write()
235 writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_write()
236 read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_write()
244 writeq(where_aligned, pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_write()
245 read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD); in thunder_pem_bridge_write()
272 * Some bits must be read-only with value of one. Since the in thunder_pem_bridge_write()
283 writeq(write_val, pem_pci->pem_reg_base + PEM_CFG_WR); in thunder_pem_bridge_write()
290 struct pci_config_window *cfg = bus->sysdata; in thunder_pem_config_write()
292 if (bus->number < cfg->busr.start || in thunder_pem_config_write()
293 bus->number > cfg->busr.end) in thunder_pem_config_write()
299 if (bus->number == cfg->busr.start) in thunder_pem_config_write()
314 return -ENOMEM; in thunder_pem_init()
316 pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000); in thunder_pem_init()
317 if (!pem_pci->pem_reg_base) in thunder_pem_init()
318 return -ENOMEM; in thunder_pem_init()
321 * The MSI-X BAR for the PEM and AER interrupts is located at in thunder_pem_init()
326 bar4_start = res_pem->start + 0xf00000; in thunder_pem_init()
327 pem_pci->ea_entry[0] = lower_32_bits(bar4_start) | 2; in thunder_pem_init()
328 pem_pci->ea_entry[1] = lower_32_bits(res_pem->end - bar4_start) & ~3u; in thunder_pem_init()
329 pem_pci->ea_entry[2] = upper_32_bits(bar4_start); in thunder_pem_init()
331 cfg->priv = pem_pci; in thunder_pem_init()
346 resource_size_t start = r->start, end = r->end; in thunder_pem_reserve_range()
354 res = request_mem_region(start, end - start + 1, regionid); in thunder_pem_reserve_range()
356 res->flags &= ~IORESOURCE_BUSY; in thunder_pem_reserve_range()
367 int node = acpi_get_node(root->device->handle); in thunder_pem_legacy_fw()
373 index = root->segment - PEM_MIN_DOM_IN_NODE; in thunder_pem_legacy_fw()
374 index -= node * PEM_MAX_DOM_IN_NODE; in thunder_pem_legacy_fw()
375 res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) | in thunder_pem_legacy_fw()
377 res_pem->flags = IORESOURCE_MEM; in thunder_pem_legacy_fw()
382 struct device *dev = cfg->parent; in thunder_pem_acpi_init()
388 res_pem = devm_kzalloc(&adev->dev, sizeof(*res_pem), GFP_KERNEL); in thunder_pem_acpi_init()
390 return -ENOMEM; in thunder_pem_acpi_init()
392 ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem); in thunder_pem_acpi_init()
396 * FW where we need to calculate PEM-specific resources manually. in thunder_pem_acpi_init()
405 thunder_pem_reserve_range(dev, root->segment, res_pem); in thunder_pem_acpi_init()
409 thunder_pem_reserve_range(dev, root->segment, &cfg->res); in thunder_pem_acpi_init()
431 struct device *dev = cfg->parent; in thunder_pem_platform_init()
435 if (!dev->of_node) in thunder_pem_platform_init()
436 return -EINVAL; in thunder_pem_platform_init()
446 return -EINVAL; in thunder_pem_platform_init()
464 .compatible = "cavium,pci-host-thunder-pem",