Commit | Line | Data |
---|---|---|
1b79c528 CP |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2017 Cadence | |
3 | // Cadence PCIe controller driver. | |
4 | // Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com> | |
5 | ||
6 | #ifndef _PCIE_CADENCE_H | |
7 | #define _PCIE_CADENCE_H | |
8 | ||
9 | #include <linux/kernel.h> | |
10 | #include <linux/pci.h> | |
dfb80534 | 11 | #include <linux/phy/phy.h> |
1b79c528 CP |
12 | |
13 | /* | |
14 | * Local Management Registers | |
15 | */ | |
16 | #define CDNS_PCIE_LM_BASE 0x00100000 | |
17 | ||
18 | /* Vendor ID Register */ | |
19 | #define CDNS_PCIE_LM_ID (CDNS_PCIE_LM_BASE + 0x0044) | |
20 | #define CDNS_PCIE_LM_ID_VENDOR_MASK GENMASK(15, 0) | |
21 | #define CDNS_PCIE_LM_ID_VENDOR_SHIFT 0 | |
22 | #define CDNS_PCIE_LM_ID_VENDOR(vid) \ | |
23 | (((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK) | |
24 | #define CDNS_PCIE_LM_ID_SUBSYS_MASK GENMASK(31, 16) | |
25 | #define CDNS_PCIE_LM_ID_SUBSYS_SHIFT 16 | |
26 | #define CDNS_PCIE_LM_ID_SUBSYS(sub) \ | |
27 | (((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK) | |
28 | ||
29 | /* Root Port Requestor ID Register */ | |
30 | #define CDNS_PCIE_LM_RP_RID (CDNS_PCIE_LM_BASE + 0x0228) | |
31 | #define CDNS_PCIE_LM_RP_RID_MASK GENMASK(15, 0) | |
32 | #define CDNS_PCIE_LM_RP_RID_SHIFT 0 | |
33 | #define CDNS_PCIE_LM_RP_RID_(rid) \ | |
34 | (((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK) | |
35 | ||
37dddf14 CP |
36 | /* Endpoint Bus and Device Number Register */ |
37 | #define CDNS_PCIE_LM_EP_ID (CDNS_PCIE_LM_BASE + 0x022c) | |
38 | #define CDNS_PCIE_LM_EP_ID_DEV_MASK GENMASK(4, 0) | |
39 | #define CDNS_PCIE_LM_EP_ID_DEV_SHIFT 0 | |
40 | #define CDNS_PCIE_LM_EP_ID_BUS_MASK GENMASK(15, 8) | |
41 | #define CDNS_PCIE_LM_EP_ID_BUS_SHIFT 8 | |
42 | ||
43 | /* Endpoint Function f BAR b Configuration Registers */ | |
44 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \ | |
45 | (CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008) | |
46 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \ | |
47 | (CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008) | |
48 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \ | |
49 | (GENMASK(4, 0) << ((b) * 8)) | |
50 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \ | |
51 | (((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b)) | |
52 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \ | |
53 | (GENMASK(7, 5) << ((b) * 8)) | |
54 | #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \ | |
55 | (((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)) | |
56 | ||
57 | /* Endpoint Function Configuration Register */ | |
58 | #define CDNS_PCIE_LM_EP_FUNC_CFG (CDNS_PCIE_LM_BASE + 0x02c0) | |
59 | ||
1b79c528 CP |
60 | /* Root Complex BAR Configuration Register */ |
61 | #define CDNS_PCIE_LM_RC_BAR_CFG (CDNS_PCIE_LM_BASE + 0x0300) | |
62 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK GENMASK(5, 0) | |
63 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \ | |
64 | (((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK) | |
65 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK GENMASK(8, 6) | |
66 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \ | |
67 | (((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK) | |
68 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK GENMASK(13, 9) | |
69 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \ | |
70 | (((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK) | |
71 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK GENMASK(16, 14) | |
72 | #define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \ | |
73 | (((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK) | |
74 | #define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE BIT(17) | |
75 | #define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS 0 | |
76 | #define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS BIT(18) | |
77 | #define CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE BIT(19) | |
78 | #define CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS 0 | |
79 | #define CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS BIT(20) | |
80 | #define CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE BIT(31) | |
81 | ||
82 | /* BAR control values applicable to both Endpoint Function and Root Complex */ | |
83 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED 0x0 | |
84 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS 0x1 | |
85 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS 0x4 | |
86 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS 0x5 | |
87 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS 0x6 | |
88 | #define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS 0x7 | |
89 | ||
90 | ||
37dddf14 CP |
91 | /* |
92 | * Endpoint Function Registers (PCI configuration space for endpoint functions) | |
93 | */ | |
94 | #define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12)) | |
95 | ||
96 | #define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90 | |
97 | ||
1b79c528 CP |
98 | /* |
99 | * Root Port Registers (PCI configuration space for the root port function) | |
100 | */ | |
101 | #define CDNS_PCIE_RP_BASE 0x00200000 | |
102 | ||
103 | ||
104 | /* | |
105 | * Address Translation Registers | |
106 | */ | |
107 | #define CDNS_PCIE_AT_BASE 0x00400000 | |
108 | ||
109 | /* Region r Outbound AXI to PCIe Address Translation Register 0 */ | |
110 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \ | |
111 | (CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1f) * 0x0020) | |
112 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK GENMASK(5, 0) | |
113 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \ | |
114 | (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK) | |
115 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12) | |
116 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \ | |
117 | (((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK) | |
118 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20) | |
119 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \ | |
120 | (((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK) | |
121 | ||
122 | /* Region r Outbound AXI to PCIe Address Translation Register 1 */ | |
123 | #define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \ | |
124 | (CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1f) * 0x0020) | |
125 | ||
126 | /* Region r Outbound PCIe Descriptor Register 0 */ | |
127 | #define CDNS_PCIE_AT_OB_REGION_DESC0(r) \ | |
128 | (CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1f) * 0x0020) | |
129 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK GENMASK(3, 0) | |
130 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM 0x2 | |
131 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO 0x6 | |
132 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0 0xa | |
133 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1 0xb | |
134 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG 0xc | |
135 | #define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG 0xd | |
136 | /* Bit 23 MUST be set in RC mode. */ | |
137 | #define CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23) | |
138 | #define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24) | |
139 | #define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \ | |
140 | (((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK) | |
141 | ||
142 | /* Region r Outbound PCIe Descriptor Register 1 */ | |
143 | #define CDNS_PCIE_AT_OB_REGION_DESC1(r) \ | |
144 | (CDNS_PCIE_AT_BASE + 0x000c + ((r) & 0x1f) * 0x0020) | |
145 | #define CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK GENMASK(7, 0) | |
146 | #define CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \ | |
147 | ((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK) | |
148 | ||
149 | /* Region r AXI Region Base Address Register 0 */ | |
150 | #define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \ | |
151 | (CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1f) * 0x0020) | |
152 | #define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK GENMASK(5, 0) | |
153 | #define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \ | |
154 | (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK) | |
155 | ||
156 | /* Region r AXI Region Base Address Register 1 */ | |
157 | #define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \ | |
158 | (CDNS_PCIE_AT_BASE + 0x001c + ((r) & 0x1f) * 0x0020) | |
159 | ||
160 | /* Root Port BAR Inbound PCIe to AXI Address Translation Register */ | |
161 | #define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \ | |
162 | (CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008) | |
163 | #define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK GENMASK(5, 0) | |
164 | #define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \ | |
165 | (((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK) | |
166 | #define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \ | |
167 | (CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008) | |
168 | ||
ee12c9ef AD |
169 | /* AXI link down register */ |
170 | #define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824) | |
171 | ||
1b79c528 CP |
172 | enum cdns_pcie_rp_bar { |
173 | RP_BAR0, | |
174 | RP_BAR1, | |
175 | RP_NO_BAR | |
176 | }; | |
177 | ||
37dddf14 CP |
178 | /* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */ |
179 | #define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ | |
180 | (CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008) | |
181 | #define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \ | |
182 | (CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008) | |
183 | ||
184 | /* Normal/Vendor specific message access: offset inside some outbound region */ | |
185 | #define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK GENMASK(7, 5) | |
186 | #define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \ | |
187 | (((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK) | |
188 | #define CDNS_PCIE_NORMAL_MSG_CODE_MASK GENMASK(15, 8) | |
189 | #define CDNS_PCIE_NORMAL_MSG_CODE(code) \ | |
190 | (((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK) | |
191 | #define CDNS_PCIE_MSG_NO_DATA BIT(16) | |
192 | ||
193 | enum cdns_pcie_msg_code { | |
194 | MSG_CODE_ASSERT_INTA = 0x20, | |
195 | MSG_CODE_ASSERT_INTB = 0x21, | |
196 | MSG_CODE_ASSERT_INTC = 0x22, | |
197 | MSG_CODE_ASSERT_INTD = 0x23, | |
198 | MSG_CODE_DEASSERT_INTA = 0x24, | |
199 | MSG_CODE_DEASSERT_INTB = 0x25, | |
200 | MSG_CODE_DEASSERT_INTC = 0x26, | |
201 | MSG_CODE_DEASSERT_INTD = 0x27, | |
202 | }; | |
203 | ||
204 | enum cdns_pcie_msg_routing { | |
205 | /* Route to Root Complex */ | |
206 | MSG_ROUTING_TO_RC, | |
207 | ||
208 | /* Use Address Routing */ | |
209 | MSG_ROUTING_BY_ADDR, | |
210 | ||
211 | /* Use ID Routing */ | |
212 | MSG_ROUTING_BY_ID, | |
213 | ||
214 | /* Route as Broadcast Message from Root Complex */ | |
215 | MSG_ROUTING_BCAST, | |
216 | ||
217 | /* Local message; terminate at receiver (INTx messages) */ | |
218 | MSG_ROUTING_LOCAL, | |
219 | ||
220 | /* Gather & route to Root Complex (PME_TO_Ack message) */ | |
221 | MSG_ROUTING_GATHER, | |
222 | }; | |
223 | ||
1b79c528 CP |
224 | /** |
225 | * struct cdns_pcie - private data for Cadence PCIe controller drivers | |
226 | * @reg_base: IO mapped register base | |
227 | * @mem_res: start/end offsets in the physical system memory to map PCI accesses | |
37dddf14 | 228 | * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint. |
1b79c528 CP |
229 | * @bus: In Root Complex mode, the bus number |
230 | */ | |
231 | struct cdns_pcie { | |
232 | void __iomem *reg_base; | |
233 | struct resource *mem_res; | |
37dddf14 | 234 | bool is_rc; |
1b79c528 | 235 | u8 bus; |
dfb80534 AD |
236 | int phy_count; |
237 | struct phy **phy; | |
238 | struct device_link **link; | |
1b79c528 CP |
239 | }; |
240 | ||
241 | /* Register access */ | |
242 | static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value) | |
243 | { | |
244 | writeb(value, pcie->reg_base + reg); | |
245 | } | |
246 | ||
247 | static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value) | |
248 | { | |
249 | writew(value, pcie->reg_base + reg); | |
250 | } | |
251 | ||
252 | static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value) | |
253 | { | |
254 | writel(value, pcie->reg_base + reg); | |
255 | } | |
256 | ||
257 | static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg) | |
258 | { | |
259 | return readl(pcie->reg_base + reg); | |
260 | } | |
261 | ||
262 | /* Root Port register access */ | |
263 | static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie, | |
264 | u32 reg, u8 value) | |
265 | { | |
266 | writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg); | |
267 | } | |
268 | ||
269 | static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie, | |
270 | u32 reg, u16 value) | |
271 | { | |
272 | writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg); | |
273 | } | |
274 | ||
37dddf14 CP |
275 | /* Endpoint Function register access */ |
276 | static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn, | |
277 | u32 reg, u8 value) | |
278 | { | |
279 | writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
280 | } | |
281 | ||
282 | static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn, | |
283 | u32 reg, u16 value) | |
284 | { | |
285 | writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
286 | } | |
287 | ||
288 | static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn, | |
7e37dc1d | 289 | u32 reg, u32 value) |
37dddf14 CP |
290 | { |
291 | writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
292 | } | |
293 | ||
294 | static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg) | |
295 | { | |
296 | return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
297 | } | |
298 | ||
299 | static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg) | |
300 | { | |
301 | return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
302 | } | |
303 | ||
304 | static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg) | |
305 | { | |
306 | return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg); | |
307 | } | |
308 | ||
309 | void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn, | |
310 | u32 r, bool is_io, | |
311 | u64 cpu_addr, u64 pci_addr, size_t size); | |
312 | ||
313 | void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn, | |
314 | u32 r, u64 cpu_addr); | |
315 | ||
316 | void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r); | |
dfb80534 AD |
317 | void cdns_pcie_disable_phy(struct cdns_pcie *pcie); |
318 | int cdns_pcie_enable_phy(struct cdns_pcie *pcie); | |
319 | int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie); | |
ee12c9ef | 320 | extern const struct dev_pm_ops cdns_pcie_pm_ops; |
37dddf14 | 321 | |
1b79c528 | 322 | #endif /* _PCIE_CADENCE_H */ |