File Index
Files and directories
Sign in
FILE

pcie-cadence.h

File preview with syntax highlighting.

linux-6.19.14/drivers/pci/controller/cadence/pcie-cadence.h C
  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(value, pcie->reg_base + reg);
224}
225
226static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
227{
228	return readl(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(value, 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(pcie->reg_base + reg);
250}
251
252static inline u16 cdns_pcie_readw(struct cdns_pcie *pcie, u32 reg)
253{
254	return readw(pcie->reg_base + reg);
255}
256
257static inline u8 cdns_pcie_readb(struct cdns_pcie *pcie, u32 reg)
258{
259	return readb(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, 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, 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, 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(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(value, addr);
314		return;
315	}
316
317	mask = ~(((1 << (size * 8)) - 1) << (offset * 8));
318	val = readl(aligned_addr) & mask;
319	val |= value << (offset * 8);
320	writel(val, 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, 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, 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, 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, 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, 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, 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, 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, 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(value, 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, 0x2);
398}
399
400static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
401{
402	return readl(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 */
~/ Read-only file preview.