Lines Matching +full:device +full:- +full:addr
1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/io-64-nonatomic-lo-hi.h>
4 #include <linux/device.h>
16 * CXL device capabilities are enumerated by PCI DVSEC (Designated
17 * Vendor-specific) and / or descriptors provided by platform firmware.
18 * They can be defined as a set like the device and component registers
19 * mandated by CXL Section 8.1.12.2 Memory Device PCIe Capabilities and
28 * cxl_probe_component_regs() - Detect CXL Component register blocks
29 * @dev: Host device of the @base mapping
34 * See CXL 2.0 8.2.5.5 CXL Device Register Interface
38 void cxl_probe_component_regs(struct device *dev, void __iomem *base, in cxl_probe_component_regs()
86 rmap = &map->hdm_decoder; in cxl_probe_component_regs()
93 rmap = &map->ras; in cxl_probe_component_regs()
103 rmap->valid = true; in cxl_probe_component_regs()
104 rmap->id = cap_id; in cxl_probe_component_regs()
105 rmap->offset = CXL_CM_OFFSET + offset; in cxl_probe_component_regs()
106 rmap->size = length; in cxl_probe_component_regs()
112 * cxl_probe_device_regs() - Detect CXL Device register blocks
113 * @dev: Host device of the @base mapping
114 * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface
117 * Probe for device register information and return it in map object.
119 void cxl_probe_device_regs(struct device *dev, void __iomem *base, in cxl_probe_device_regs()
148 rmap = &map->status; in cxl_probe_device_regs()
152 rmap = &map->mbox; in cxl_probe_device_regs()
158 dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); in cxl_probe_device_regs()
159 rmap = &map->memdev; in cxl_probe_device_regs()
171 rmap->valid = true; in cxl_probe_device_regs()
172 rmap->id = cap_id; in cxl_probe_device_regs()
173 rmap->offset = offset; in cxl_probe_device_regs()
174 rmap->size = length; in cxl_probe_device_regs()
179 void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, in devm_cxl_iomap_block() argument
185 if (WARN_ON_ONCE(addr == CXL_RESOURCE_NONE)) in devm_cxl_iomap_block()
188 res = devm_request_mem_region(dev, addr, length, dev_name(dev)); in devm_cxl_iomap_block()
190 resource_size_t end = addr + length - 1; in devm_cxl_iomap_block()
192 dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end); in devm_cxl_iomap_block()
196 ret_val = devm_ioremap(dev, addr, length); in devm_cxl_iomap_block()
207 struct device *host = map->host; in cxl_map_component_regs()
210 void __iomem **addr; in cxl_map_component_regs() member
212 { &map->component_map.hdm_decoder, ®s->hdm_decoder }, in cxl_map_component_regs()
213 { &map->component_map.ras, ®s->ras }, in cxl_map_component_regs()
219 resource_size_t addr; in cxl_map_component_regs() local
222 if (!mi->rmap->valid) in cxl_map_component_regs()
224 if (!test_bit(mi->rmap->id, &map_mask)) in cxl_map_component_regs()
226 addr = map->resource + mi->rmap->offset; in cxl_map_component_regs()
227 length = mi->rmap->size; in cxl_map_component_regs()
228 *(mi->addr) = devm_cxl_iomap_block(host, addr, length); in cxl_map_component_regs()
229 if (!*(mi->addr)) in cxl_map_component_regs()
230 return -ENOMEM; in cxl_map_component_regs()
240 struct device *host = map->host; in cxl_map_device_regs()
241 resource_size_t phys_addr = map->resource; in cxl_map_device_regs()
244 void __iomem **addr; in cxl_map_device_regs() member
246 { &map->device_map.status, ®s->status, }, in cxl_map_device_regs()
247 { &map->device_map.mbox, ®s->mbox, }, in cxl_map_device_regs()
248 { &map->device_map.memdev, ®s->memdev, }, in cxl_map_device_regs()
255 resource_size_t addr; in cxl_map_device_regs() local
257 if (!mi->rmap->valid) in cxl_map_device_regs()
260 addr = phys_addr + mi->rmap->offset; in cxl_map_device_regs()
261 length = mi->rmap->size; in cxl_map_device_regs()
262 *(mi->addr) = devm_cxl_iomap_block(host, addr, length); in cxl_map_device_regs()
263 if (!*(mi->addr)) in cxl_map_device_regs()
264 return -ENOMEM; in cxl_map_device_regs()
280 dev_warn(&pdev->dev, in cxl_decode_regblock()
282 &pdev->resource[bar], &offset, reg_type); in cxl_decode_regblock()
286 map->reg_type = reg_type; in cxl_decode_regblock()
287 map->resource = pci_resource_start(pdev, bar) + offset; in cxl_decode_regblock()
288 map->max_size = pci_resource_len(pdev, bar) - offset; in cxl_decode_regblock()
293 * __cxl_find_regblock_instance() - Locate a register block or count instances by type / index
297 * 0 - if register block enumerated.
298 * >= 0 - if counting instances.
299 * < 0 - error code otherwise.
309 .host = &pdev->dev, in __cxl_find_regblock_instance()
316 return -ENXIO; in __cxl_find_regblock_instance()
322 regblocks = (regloc_size - CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET) / 8; in __cxl_find_regblock_instance()
333 if (map->reg_type == type) { in __cxl_find_regblock_instance()
340 map->resource = CXL_RESOURCE_NONE; in __cxl_find_regblock_instance()
344 return -ENODEV; in __cxl_find_regblock_instance()
348 * cxl_find_regblock_instance() - Locate a register block by type / index
349 * @pdev: The CXL PCI device to enumerate.
368 * cxl_find_regblock() - Locate register blocks by type
369 * @pdev: The CXL PCI device to enumerate.
386 * cxl_count_regblock() - Count instances of a given regblock type.
387 * @pdev: The CXL PCI device to enumerate.
392 * Return: non-negative count of matching regblocks, negative error code otherwise.
404 struct device *dev = map->host; in cxl_map_pmu_regs()
407 phys_addr = map->resource; in cxl_map_pmu_regs()
408 regs->pmu = devm_cxl_iomap_block(dev, phys_addr, CXL_PMU_REGMAP_SIZE); in cxl_map_pmu_regs()
409 if (!regs->pmu) in cxl_map_pmu_regs()
410 return -ENOMEM; in cxl_map_pmu_regs()
418 struct device *host = map->host; in cxl_map_regblock()
420 map->base = ioremap(map->resource, map->max_size); in cxl_map_regblock()
421 if (!map->base) { in cxl_map_regblock()
423 return -ENOMEM; in cxl_map_regblock()
426 dev_dbg(host, "Mapped CXL Memory Device resource %pa\n", &map->resource); in cxl_map_regblock()
432 iounmap(map->base); in cxl_unmap_regblock()
433 map->base = NULL; in cxl_unmap_regblock()
440 struct device *host = map->host; in cxl_probe_regs()
441 void __iomem *base = map->base; in cxl_probe_regs()
443 switch (map->reg_type) { in cxl_probe_regs()
445 comp_map = &map->component_map; in cxl_probe_regs()
450 dev_map = &map->device_map; in cxl_probe_regs()
452 if (!dev_map->status.valid || !dev_map->mbox.valid || in cxl_probe_regs()
453 !dev_map->memdev.valid) { in cxl_probe_regs()
455 !dev_map->status.valid ? "status " : "", in cxl_probe_regs()
456 !dev_map->mbox.valid ? "mbox " : "", in cxl_probe_regs()
457 !dev_map->memdev.valid ? "memdev " : ""); in cxl_probe_regs()
458 return -ENXIO; in cxl_probe_regs()
461 dev_dbg(host, "Probing device registers...\n"); in cxl_probe_regs()
485 u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb) in cxl_rcrb_to_aer()
487 void __iomem *addr; in cxl_rcrb_to_aer() local
497 addr = ioremap(rcrb, SZ_4K); in cxl_rcrb_to_aer()
498 if (!addr) in cxl_rcrb_to_aer()
501 cap_hdr = readl(addr + offset); in cxl_rcrb_to_aer()
508 cap_hdr = readl(addr + offset); in cxl_rcrb_to_aer()
514 iounmap(addr); in cxl_rcrb_to_aer()
521 static resource_size_t cxl_rcrb_to_linkcap(struct device *dev, struct cxl_dport *dport) in cxl_rcrb_to_linkcap()
523 resource_size_t rcrb = dport->rcrb.base; in cxl_rcrb_to_linkcap()
524 void __iomem *addr; in cxl_rcrb_to_linkcap() local
531 addr = ioremap(rcrb, SZ_4K); in cxl_rcrb_to_linkcap()
532 if (!addr) { in cxl_rcrb_to_linkcap()
533 dev_err(dev, "Failed to map region %pr\n", addr); in cxl_rcrb_to_linkcap()
538 offset = FIELD_GET(PCI_RCRB_CAP_LIST_ID_MASK, readw(addr + PCI_CAPABILITY_LIST)); in cxl_rcrb_to_linkcap()
539 cap_hdr = readl(addr + offset); in cxl_rcrb_to_linkcap()
546 cap_hdr = readl(addr + offset); in cxl_rcrb_to_linkcap()
549 iounmap(addr); in cxl_rcrb_to_linkcap()
563 ri = &dport->rcrb; in cxl_dport_map_rcd_linkcap()
564 pos = cxl_rcrb_to_linkcap(&pdev->dev, dport); in cxl_dport_map_rcd_linkcap()
566 return -ENXIO; in cxl_dport_map_rcd_linkcap()
568 dport_pcie_cap = devm_cxl_iomap_block(&pdev->dev, in cxl_dport_map_rcd_linkcap()
569 ri->base + pos, in cxl_dport_map_rcd_linkcap()
571 dport->regs.rcd_pcie_cap = dport_pcie_cap; in cxl_dport_map_rcd_linkcap()
577 resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri, in __rcrb_to_component()
581 resource_size_t rcrb = ri->base; in __rcrb_to_component()
582 void __iomem *addr; in __rcrb_to_component() local
598 addr = ioremap(rcrb, SZ_4K); in __rcrb_to_component()
599 if (!addr) { in __rcrb_to_component()
600 dev_err(dev, "Failed to map region %pr\n", addr); in __rcrb_to_component()
605 id = readl(addr + PCI_VENDOR_ID); in __rcrb_to_component()
606 cmd = readw(addr + PCI_COMMAND); in __rcrb_to_component()
607 bar0 = readl(addr + PCI_BASE_ADDRESS_0); in __rcrb_to_component()
608 bar1 = readl(addr + PCI_BASE_ADDRESS_1); in __rcrb_to_component()
609 iounmap(addr); in __rcrb_to_component()
613 * Sanity check, see CXL 3.0 Figure 9-8 CXL Device that Does Not in __rcrb_to_component()
641 resource_size_t cxl_rcd_component_reg_phys(struct device *dev, in cxl_rcd_component_reg_phys()
644 if (!dport->rch) in cxl_rcd_component_reg_phys()
646 return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); in cxl_rcd_component_reg_phys()