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/module.h>
11#include <linux/pci.h>
12#include <linux/pci-epf.h>
13#include <linux/phy/phy.h>
14#include "pcie-cadence-lga-regs.h"
15#include "pcie-cadence-hpa-regs.h"
16
17enum cdns_pcie_rp_bar {
18 RP_BAR_UNDEFINED = -1,
19 RP_BAR0,
20 RP_BAR1,
21 RP_NO_BAR
22};
23
24struct cdns_pcie_rp_ib_bar {
25 u64 size;
26 bool free;
27};
28
29struct cdns_pcie;
30struct cdns_pcie_rc;
31
32enum cdns_pcie_reg_bank {
33 REG_BANK_RP,
34 REG_BANK_IP_REG,
35 REG_BANK_IP_CFG_CTRL_REG,
36 REG_BANK_AXI_MASTER_COMMON,
37 REG_BANK_AXI_MASTER,
38 REG_BANK_AXI_SLAVE,
39 REG_BANK_AXI_HLS,
40 REG_BANK_AXI_RAS,
41 REG_BANK_AXI_DTI,
42 REG_BANKS_MAX,
43};
44
45struct cdns_pcie_ops {
46 int (*start_link)(struct cdns_pcie *pcie);
47 void (*stop_link)(struct cdns_pcie *pcie);
48 bool (*link_up)(struct cdns_pcie *pcie);
49 u64 (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
50};
51
52/**
53 * struct cdns_plat_pcie_of_data - Register bank offset for a platform
54 * @is_rc: controller is a RC
55 * @ip_reg_bank_offset: ip register bank start offset
56 * @ip_cfg_ctrl_reg_offset: ip config control register start offset
57 * @axi_mstr_common_offset: AXI master common register start offset
58 * @axi_slave_offset: AXI slave start offset
59 * @axi_master_offset: AXI master start offset
60 * @axi_hls_offset: AXI HLS offset start
61 * @axi_ras_offset: AXI RAS offset
62 * @axi_dti_offset: AXI DTI offset
63 */
64struct cdns_plat_pcie_of_data {
65 u32 is_rc:1;
66 u32 ip_reg_bank_offset;
67 u32 ip_cfg_ctrl_reg_offset;
68 u32 axi_mstr_common_offset;
69 u32 axi_slave_offset;
70 u32 axi_master_offset;
71 u32 axi_hls_offset;
72 u32 axi_ras_offset;
73 u32 axi_dti_offset;
74};
75
76/**
77 * struct cdns_pcie - private data for Cadence PCIe controller drivers
78 * @reg_base: IO mapped register base
79 * @mem_res: start/end offsets in the physical system memory to map PCI accesses
80 * @msg_res: Region for send message to map PCI accesses
81 * @dev: PCIe controller
82 * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
83 * @phy_count: number of supported PHY devices
84 * @phy: list of pointers to specific PHY control blocks
85 * @link: list of pointers to corresponding device link representations
86 * @ops: Platform-specific ops to control various inputs from Cadence PCIe
87 * wrapper
88 * @cdns_pcie_reg_offsets: Register bank offsets for different SoC
89 */
90struct cdns_pcie {
91 void __iomem *reg_base;
92 struct resource *mem_res;
93 struct resource *msg_res;
94 struct device *dev;
95 bool is_rc;
96 int phy_count;
97 struct phy **phy;
98 struct device_link **link;
99 const struct cdns_pcie_ops *ops;
100 const struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets;
101};
102
103/**
104 * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
105 * @pcie: Cadence PCIe controller
106 * @cfg_res: start/end offsets in the physical system memory to map PCI
107 * configuration space accesses
108 * @cfg_base: IO mapped window to access the PCI configuration space of a
109 * single function at a time
110 * @vendor_id: PCI vendor ID
111 * @device_id: PCI device ID
112 * @avail_ib_bar: Status of RP_BAR0, RP_BAR1 and RP_NO_BAR if it's free or
113 * available
114 * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
115 * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
116 * @ecam_supported: Whether the ECAM is supported
117 * @no_inbound_map: Whether inbound mapping is supported
118 */
119struct cdns_pcie_rc {
120 struct cdns_pcie pcie;
121 struct resource *cfg_res;
122 void __iomem *cfg_base;
123 u32 vendor_id;
124 u32 device_id;
125 bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
126 unsigned int quirk_retrain_flag:1;
127 unsigned int quirk_detect_quiet_flag:1;
128 unsigned int ecam_supported:1;
129 unsigned int no_inbound_map:1;
130};
131
132/**
133 * struct cdns_pcie_epf - Structure to hold info about endpoint function
134 * @epf: Info about virtual functions attached to the physical function
135 * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
136 */
137struct cdns_pcie_epf {
138 struct cdns_pcie_epf *epf;
139 struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
140};
141
142/**
143 * struct cdns_pcie_ep - private data for this PCIe endpoint controller driver
144 * @pcie: Cadence PCIe controller
145 * @max_regions: maximum number of regions supported by hardware
146 * @ob_region_map: bitmask of mapped outbound regions
147 * @ob_addr: base addresses in the AXI bus where the outbound regions start
148 * @irq_phys_addr: base address on the AXI bus where the MSI/INTX IRQ
149 * dedicated outbound regions is mapped.
150 * @irq_cpu_addr: base address in the CPU space where a write access triggers
151 * the sending of a memory write (MSI) / normal message (INTX
152 * IRQ) TLP through the PCIe bus.
153 * @irq_pci_addr: used to save the current mapping of the MSI/INTX IRQ
154 * dedicated outbound region.
155 * @irq_pci_fn: the latest PCI function that has updated the mapping of
156 * the MSI/INTX IRQ dedicated outbound region.
157 * @irq_pending: bitmask of asserted INTX IRQs.
158 * @lock: spin lock to disable interrupts while modifying PCIe controller
159 * registers fields (RMW) accessible by both remote RC and EP to
160 * minimize time between read and write
161 * @epf: Structure to hold info about endpoint function
162 * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
163 * @quirk_disable_flr: Disable FLR (Function Level Reset) quirk flag
164 */
165struct cdns_pcie_ep {
166 struct cdns_pcie pcie;
167 u32 max_regions;
168 unsigned long ob_region_map;
169 phys_addr_t *ob_addr;
170 phys_addr_t irq_phys_addr;
171 void __iomem *irq_cpu_addr;
172 u64 irq_pci_addr;
173 u8 irq_pci_fn;
174 u8 irq_pending;
175 /* protect writing to PCI_STATUS while raising INTX interrupts */
176 spinlock_t lock;
177 struct cdns_pcie_epf *epf;
178 unsigned int quirk_detect_quiet_flag:1;
179 unsigned int quirk_disable_flr:1;
180};
181
182static inline u32 cdns_reg_bank_to_off(struct cdns_pcie *pcie, enum cdns_pcie_reg_bank bank)
183{
184 u32 offset = 0x0;
185
186 switch (bank) {
187 case REG_BANK_RP:
188 offset = 0;
189 break;
190 case REG_BANK_IP_REG:
191 offset = pcie->cdns_pcie_reg_offsets->ip_reg_bank_offset;
192 break;
193 case REG_BANK_IP_CFG_CTRL_REG:
194 offset = pcie->cdns_pcie_reg_offsets->ip_cfg_ctrl_reg_offset;
195 break;
196 case REG_BANK_AXI_MASTER_COMMON:
197 offset = pcie->cdns_pcie_reg_offsets->axi_mstr_common_offset;
198 break;
199 case REG_BANK_AXI_MASTER:
200 offset = pcie->cdns_pcie_reg_offsets->axi_master_offset;
201 break;
202 case REG_BANK_AXI_SLAVE:
203 offset = pcie->cdns_pcie_reg_offsets->axi_slave_offset;
204 break;
205 case REG_BANK_AXI_HLS:
206 offset = pcie->cdns_pcie_reg_offsets->axi_hls_offset;
207 break;
208 case REG_BANK_AXI_RAS:
209 offset = pcie->cdns_pcie_reg_offsets->axi_ras_offset;
210 break;
211 case REG_BANK_AXI_DTI:
212 offset = pcie->cdns_pcie_reg_offsets->axi_dti_offset;
213 break;
214 default:
215 break;
216 }
217 return offset;
218}
219
220/* Register access */
221static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
222{
223 writel(val: value, addr: pcie->reg_base + reg);
224}
225
226static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
227{
228 return readl(addr: pcie->reg_base + reg);
229}
230
231static inline void cdns_pcie_hpa_writel(struct cdns_pcie *pcie,
232 enum cdns_pcie_reg_bank bank,
233 u32 reg,
234 u32 value)
235{
236 u32 offset = cdns_reg_bank_to_off(pcie, bank);
237
238 reg += offset;
239 writel(val: value, addr: pcie->reg_base + reg);
240}
241
242static inline u32 cdns_pcie_hpa_readl(struct cdns_pcie *pcie,
243 enum cdns_pcie_reg_bank bank,
244 u32 reg)
245{
246 u32 offset = cdns_reg_bank_to_off(pcie, bank);
247
248 reg += offset;
249 return readl(addr: pcie->reg_base + reg);
250}
251
252static inline u16 cdns_pcie_readw(struct cdns_pcie *pcie, u32 reg)
253{
254 return readw(addr: pcie->reg_base + reg);
255}
256
257static inline u8 cdns_pcie_readb(struct cdns_pcie *pcie, u32 reg)
258{
259 return readb(addr: pcie->reg_base + reg);
260}
261
262static inline int cdns_pcie_read_cfg_byte(struct cdns_pcie *pcie, int where,
263 u8 *val)
264{
265 *val = cdns_pcie_readb(pcie, reg: where);
266 return PCIBIOS_SUCCESSFUL;
267}
268
269static inline int cdns_pcie_read_cfg_word(struct cdns_pcie *pcie, int where,
270 u16 *val)
271{
272 *val = cdns_pcie_readw(pcie, reg: where);
273 return PCIBIOS_SUCCESSFUL;
274}
275
276static inline int cdns_pcie_read_cfg_dword(struct cdns_pcie *pcie, int where,
277 u32 *val)
278{
279 *val = cdns_pcie_readl(pcie, reg: where);
280 return PCIBIOS_SUCCESSFUL;
281}
282
283static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size)
284{
285 void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
286 unsigned int offset = (unsigned long)addr & 0x3;
287 u32 val = readl(addr: aligned_addr);
288
289 if (!IS_ALIGNED((uintptr_t)addr, size)) {
290 pr_warn("Address %p and size %d are not aligned\n", addr, size);
291 return 0;
292 }
293
294 if (size > 2)
295 return val;
296
297 return (val >> (8 * offset)) & ((1 << (size * 8)) - 1);
298}
299
300static inline void cdns_pcie_write_sz(void __iomem *addr, int size, u32 value)
301{
302 void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
303 unsigned int offset = (unsigned long)addr & 0x3;
304 u32 mask;
305 u32 val;
306
307 if (!IS_ALIGNED((uintptr_t)addr, size)) {
308 pr_warn("Address %p and size %d are not aligned\n", addr, size);
309 return;
310 }
311
312 if (size > 2) {
313 writel(val: value, addr);
314 return;
315 }
316
317 mask = ~(((1 << (size * 8)) - 1) << (offset * 8));
318 val = readl(addr: aligned_addr) & mask;
319 val |= value << (offset * 8);
320 writel(val, addr: aligned_addr);
321}
322
323/* Root Port register access */
324static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
325 u32 reg, u8 value)
326{
327 void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
328
329 cdns_pcie_write_sz(addr, size: 0x1, value);
330}
331
332static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
333 u32 reg, u16 value)
334{
335 void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
336
337 cdns_pcie_write_sz(addr, size: 0x2, value);
338}
339
340static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg)
341{
342 void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
343
344 return cdns_pcie_read_sz(addr, size: 0x2);
345}
346
347static inline void cdns_pcie_hpa_rp_writeb(struct cdns_pcie *pcie,
348 u32 reg, u8 value)
349{
350 void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
351
352 cdns_pcie_write_sz(addr, size: 0x1, value);
353}
354
355static inline void cdns_pcie_hpa_rp_writew(struct cdns_pcie *pcie,
356 u32 reg, u16 value)
357{
358 void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
359
360 cdns_pcie_write_sz(addr, size: 0x2, value);
361}
362
363static inline u16 cdns_pcie_hpa_rp_readw(struct cdns_pcie *pcie, u32 reg)
364{
365 void __iomem *addr = pcie->reg_base + CDNS_PCIE_HPA_RP_BASE + reg;
366
367 return cdns_pcie_read_sz(addr, size: 0x2);
368}
369
370/* Endpoint Function register access */
371static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
372 u32 reg, u8 value)
373{
374 void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
375
376 cdns_pcie_write_sz(addr, size: 0x1, value);
377}
378
379static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
380 u32 reg, u16 value)
381{
382 void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
383
384 cdns_pcie_write_sz(addr, size: 0x2, value);
385}
386
387static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
388 u32 reg, u32 value)
389{
390 writel(val: value, addr: pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
391}
392
393static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
394{
395 void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
396
397 return cdns_pcie_read_sz(addr, size: 0x2);
398}
399
400static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
401{
402 return readl(addr: pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
403}
404
405static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
406{
407 if (pcie->ops && pcie->ops->start_link)
408 return pcie->ops->start_link(pcie);
409
410 return 0;
411}
412
413static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie)
414{
415 if (pcie->ops && pcie->ops->stop_link)
416 pcie->ops->stop_link(pcie);
417}
418
419static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
420{
421 if (pcie->ops && pcie->ops->link_up)
422 return pcie->ops->link_up(pcie);
423
424 return true;
425}
426
427#if IS_ENABLED(CONFIG_PCIE_CADENCE_HOST)
428int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
429int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
430int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
431void cdns_pcie_host_disable(struct cdns_pcie_rc *rc);
432void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
433 int where);
434int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc);
435#else
436static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
437{
438 return 0;
439}
440
441static inline int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
442{
443 return 0;
444}
445
446static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
447{
448 return 0;
449}
450
451static inline int cdns_pcie_hpa_host_setup(struct cdns_pcie_rc *rc)
452{
453 return 0;
454}
455
456static inline void cdns_pcie_host_disable(struct cdns_pcie_rc *rc)
457{
458}
459
460static inline void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
461 int where)
462{
463 return NULL;
464}
465#endif
466
467#if IS_ENABLED(CONFIG_PCIE_CADENCE_EP)
468int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep);
469void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep);
470int cdns_pcie_hpa_ep_setup(struct cdns_pcie_ep *ep);
471#else
472static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
473{
474 return 0;
475}
476
477static inline void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
478{
479}
480
481static inline int cdns_pcie_hpa_ep_setup(struct cdns_pcie_ep *ep)
482{
483 return 0;
484}
485
486#endif
487
488u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap);
489u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap);
490bool cdns_pcie_linkup(struct cdns_pcie *pcie);
491
492void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
493
494void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
495 u32 r, bool is_io,
496 u64 cpu_addr, u64 pci_addr, size_t size);
497
498void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
499 u8 busnr, u8 fn,
500 u32 r, u64 cpu_addr);
501
502void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
503void cdns_pcie_disable_phy(struct cdns_pcie *pcie);
504int cdns_pcie_enable_phy(struct cdns_pcie *pcie);
505int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie);
506void cdns_pcie_hpa_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
507void cdns_pcie_hpa_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
508 u32 r, bool is_io,
509 u64 cpu_addr, u64 pci_addr, size_t size);
510void cdns_pcie_hpa_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
511 u8 busnr, u8 fn,
512 u32 r, u64 cpu_addr);
513int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc);
514void __iomem *cdns_pci_hpa_map_bus(struct pci_bus *bus, unsigned int devfn,
515 int where);
516int cdns_pcie_hpa_host_start_link(struct cdns_pcie_rc *rc);
517int cdns_pcie_hpa_start_link(struct cdns_pcie *pcie);
518void cdns_pcie_hpa_stop_link(struct cdns_pcie *pcie);
519bool cdns_pcie_hpa_link_up(struct cdns_pcie *pcie);
520
521extern const struct dev_pm_ops cdns_pcie_pm_ops;
522
523#endif /* _PCIE_CADENCE_H */
524

source code of linux/drivers/pci/controller/cadence/pcie-cadence.h