summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVidya Sagar <vidyas@nvidia.com>2019-08-13 07:36:19 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-08-13 10:51:55 -0400
commit5b0841fa653f6c156500ecfe7e996837884363c4 (patch)
tree69a8f642514a9047c55a871eb8e54c8b300d379c
parent7a6854f6874ff416afa6552706a0011418f07888 (diff)
PCI: dwc: Add extended configuration space capability search API
Add extended configuration space capability search API using struct dw_pcie* pointer. Signed-off-by: Vidya Sagar <vidyas@nvidia.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com> Acked-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.c41
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h1
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 7818b4febb08..181449e342f1 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -53,6 +53,47 @@ u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
53} 53}
54EXPORT_SYMBOL_GPL(dw_pcie_find_capability); 54EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
55 55
56static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
57 u8 cap)
58{
59 u32 header;
60 int ttl;
61 int pos = PCI_CFG_SPACE_SIZE;
62
63 /* minimum 8 bytes per capability */
64 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
65
66 if (start)
67 pos = start;
68
69 header = dw_pcie_readl_dbi(pci, pos);
70 /*
71 * If we have no capabilities, this is indicated by cap ID,
72 * cap version and next pointer all being 0.
73 */
74 if (header == 0)
75 return 0;
76
77 while (ttl-- > 0) {
78 if (PCI_EXT_CAP_ID(header) == cap && pos != start)
79 return pos;
80
81 pos = PCI_EXT_CAP_NEXT(header);
82 if (pos < PCI_CFG_SPACE_SIZE)
83 break;
84
85 header = dw_pcie_readl_dbi(pci, pos);
86 }
87
88 return 0;
89}
90
91u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
92{
93 return dw_pcie_find_next_ext_capability(pci, 0, cap);
94}
95EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
96
56int dw_pcie_read(void __iomem *addr, int size, u32 *val) 97int dw_pcie_read(void __iomem *addr, int size, u32 *val)
57{ 98{
58 if (!IS_ALIGNED((uintptr_t)addr, size)) { 99 if (!IS_ALIGNED((uintptr_t)addr, size)) {
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index d8c66a6827dc..11c223471416 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -252,6 +252,7 @@ struct dw_pcie {
252 container_of((endpoint), struct dw_pcie, ep) 252 container_of((endpoint), struct dw_pcie, ep)
253 253
254u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); 254u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
255u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
255 256
256int dw_pcie_read(void __iomem *addr, int size, u32 *val); 257int dw_pcie_read(void __iomem *addr, int size, u32 *val);
257int dw_pcie_write(void __iomem *addr, int size, u32 val); 258int dw_pcie_write(void __iomem *addr, int size, u32 val);