| 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 | int				(*enable_device)(struct pci_host_bridge *, | 
|---|
| 49 | struct pci_dev *); | 
|---|
| 50 | void				(*disable_device)(struct pci_host_bridge *, | 
|---|
| 51 | struct pci_dev *); | 
|---|
| 52 | }; | 
|---|
| 53 |  | 
|---|
| 54 | /* | 
|---|
| 55 | * struct to hold the mappings of a config space window. This | 
|---|
| 56 | * is expected to be used as sysdata for PCI controllers that | 
|---|
| 57 | * use ECAM. | 
|---|
| 58 | */ | 
|---|
| 59 | struct pci_config_window { | 
|---|
| 60 | struct resource			res; | 
|---|
| 61 | struct resource			busr; | 
|---|
| 62 | unsigned int			bus_shift; | 
|---|
| 63 | void				*priv; | 
|---|
| 64 | const struct pci_ecam_ops	*ops; | 
|---|
| 65 | union { | 
|---|
| 66 | void __iomem		*win;	/* 64-bit single mapping */ | 
|---|
| 67 | void __iomem		**winp; /* 32-bit per-bus mapping */ | 
|---|
| 68 | }; | 
|---|
| 69 | struct device			*parent;/* ECAM res was from this dev */ | 
|---|
| 70 | }; | 
|---|
| 71 |  | 
|---|
| 72 | /* create and free pci_config_window */ | 
|---|
| 73 | struct pci_config_window *pci_ecam_create(struct device *dev, | 
|---|
| 74 | struct resource *cfgres, struct resource *busr, | 
|---|
| 75 | const struct pci_ecam_ops *ops); | 
|---|
| 76 | void pci_ecam_free(struct pci_config_window *cfg); | 
|---|
| 77 |  | 
|---|
| 78 | /* map_bus when ->sysdata is an instance of pci_config_window */ | 
|---|
| 79 | void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, | 
|---|
| 80 | int where); | 
|---|
| 81 | /* default ECAM ops */ | 
|---|
| 82 | extern const struct pci_ecam_ops pci_generic_ecam_ops; | 
|---|
| 83 |  | 
|---|
| 84 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | 
|---|
| 85 | extern const struct pci_ecam_ops pci_32b_ops;	/* 32-bit accesses only */ | 
|---|
| 86 | extern const struct pci_ecam_ops pci_32b_read_ops; /* 32-bit read only */ | 
|---|
| 87 | extern const struct pci_ecam_ops hisi_pcie_ops;	/* HiSilicon */ | 
|---|
| 88 | extern const struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */ | 
|---|
| 89 | extern const struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */ | 
|---|
| 90 | extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */ | 
|---|
| 91 | extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ | 
|---|
| 92 | extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */ | 
|---|
| 93 | extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */ | 
|---|
| 94 | extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */ | 
|---|
| 95 | #endif | 
|---|
| 96 | #endif | 
|---|
| 97 |  | 
|---|