1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright 2016 Broadcom |
4 | */ |
5 | #ifndef DRIVERS_PCI_ECAM_H |
6 | #define DRIVERS_PCI_ECAM_H |
7 | |
8 | #include <linux/pci.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/platform_device.h> |
11 | |
12 | /* |
13 | * Memory address shift values for the byte-level address that |
14 | * can be used when accessing the PCI Express Configuration Space. |
15 | */ |
16 | |
17 | /* |
18 | * Enhanced Configuration Access Mechanism (ECAM) |
19 | * |
20 | * See PCI Express Base Specification, Revision 5.0, Version 1.0, |
21 | * Section 7.2.2, Table 7-1, p. 677. |
22 | */ |
23 | #define PCIE_ECAM_BUS_SHIFT 20 /* Bus number */ |
24 | #define PCIE_ECAM_DEVFN_SHIFT 12 /* Device and Function number */ |
25 | |
26 | #define PCIE_ECAM_BUS_MASK 0xff |
27 | #define PCIE_ECAM_DEVFN_MASK 0xff |
28 | #define PCIE_ECAM_REG_MASK 0xfff /* Limit offset to a maximum of 4K */ |
29 | |
30 | #define PCIE_ECAM_BUS(x) (((x) & PCIE_ECAM_BUS_MASK) << PCIE_ECAM_BUS_SHIFT) |
31 | #define PCIE_ECAM_DEVFN(x) (((x) & PCIE_ECAM_DEVFN_MASK) << PCIE_ECAM_DEVFN_SHIFT) |
32 | #define PCIE_ECAM_REG(x) ((x) & PCIE_ECAM_REG_MASK) |
33 | |
34 | #define PCIE_ECAM_OFFSET(bus, devfn, where) \ |
35 | (PCIE_ECAM_BUS(bus) | \ |
36 | PCIE_ECAM_DEVFN(devfn) | \ |
37 | PCIE_ECAM_REG(where)) |
38 | |
39 | /* |
40 | * struct to hold pci ops and bus shift of the config window |
41 | * for a PCI controller. |
42 | */ |
43 | struct pci_config_window; |
44 | struct pci_ecam_ops { |
45 | unsigned int bus_shift; |
46 | struct pci_ops pci_ops; |
47 | int (*init)(struct pci_config_window *); |
48 | }; |
49 | |
50 | /* |
51 | * struct to hold the mappings of a config space window. This |
52 | * is expected to be used as sysdata for PCI controllers that |
53 | * use ECAM. |
54 | */ |
55 | struct pci_config_window { |
56 | struct resource res; |
57 | struct resource busr; |
58 | unsigned int bus_shift; |
59 | void *priv; |
60 | const struct pci_ecam_ops *ops; |
61 | union { |
62 | void __iomem *win; /* 64-bit single mapping */ |
63 | void __iomem **winp; /* 32-bit per-bus mapping */ |
64 | }; |
65 | struct device *parent;/* ECAM res was from this dev */ |
66 | }; |
67 | |
68 | /* create and free pci_config_window */ |
69 | struct pci_config_window *pci_ecam_create(struct device *dev, |
70 | struct resource *cfgres, struct resource *busr, |
71 | const struct pci_ecam_ops *ops); |
72 | void pci_ecam_free(struct pci_config_window *cfg); |
73 | |
74 | /* map_bus when ->sysdata is an instance of pci_config_window */ |
75 | void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, |
76 | int where); |
77 | /* default ECAM ops */ |
78 | extern const struct pci_ecam_ops pci_generic_ecam_ops; |
79 | |
80 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) |
81 | extern const struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ |
82 | extern const struct pci_ecam_ops pci_32b_read_ops; /* 32-bit read only */ |
83 | extern const struct pci_ecam_ops hisi_pcie_ops; /* HiSilicon */ |
84 | extern const struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */ |
85 | extern const struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */ |
86 | extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */ |
87 | extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ |
88 | extern const struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */ |
89 | extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ |
90 | extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ |
91 | #endif |
92 | |
93 | #if IS_ENABLED(CONFIG_PCI_HOST_COMMON) |
94 | /* for DT-based PCI controllers that support ECAM */ |
95 | int pci_host_common_probe(struct platform_device *pdev); |
96 | int pci_host_common_remove(struct platform_device *pdev); |
97 | #endif |
98 | #endif |
99 | |