blob: a08cd4ae7eb3c755ad2ff5feb7de5789b521bc6c [file] [log] [blame]
AlexeiFedorov9f0dc012024-09-10 10:22:06 +01001/*
Arunachalam Ganapathy503b89a2025-06-19 10:34:11 +01002 * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
AlexeiFedorov9f0dc012024-09-10 10:22:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef PCIE_H
8#define PCIE_H
9
Arunachalam Ganapathyb0833d22025-06-26 11:05:51 +010010#include <stdbool.h>
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010011#include <cdefs.h>
12#include <stdint.h>
13#include <utils_def.h>
14
Soby Mathew2c2810f2024-11-15 17:11:24 +000015/* platforms need to ensure that number of entries is less that this value */
16#define MAX_PCIE_INFO_ENTRIES 5
17
Arunachalam Ganapathyb0833d22025-06-26 11:05:51 +010018#define PCIE_DEVICES_MAX 128
19
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010020typedef struct {
21 unsigned long ecam_base; /* ECAM base address */
22 unsigned int segment_num; /* Segment number of this ECAM */
23 unsigned int start_bus_num; /* Start bus number for this ECAM space */
24 unsigned int end_bus_num; /* Last bus number */
25} pcie_info_block_t;
26
Soby Mathew2c2810f2024-11-15 17:11:24 +000027struct pcie_info_table{
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010028 unsigned int num_entries; /* Number of entries */
Soby Mathew2c2810f2024-11-15 17:11:24 +000029 pcie_info_block_t block[MAX_PCIE_INFO_ENTRIES];
30};
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010031
Arunachalam Ganapathyb0833d22025-06-26 11:05:51 +010032/* Flags for PCIe device capability */
33#define PCIE_DEV_CFLAG_DOE (U(1) << 0)
34#define PCIE_DEV_CFLAG_IDE (U(1) << 1)
35#define PCIE_DEV_CFLAG_DVSEC_RMEDA (U(1) << 3)
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010036
Arunachalam Ganapathyb0833d22025-06-26 11:05:51 +010037#define pcie_dev_has_doe(_d) (((_d)->cflags & PCIE_DEV_CFLAG_DOE) != 0U)
38#define pcie_dev_has_ide(_d) (((_d)->cflags & PCIE_DEV_CFLAG_IDE) != 0U)
39#define pcie_dev_has_dvsec_rmeda(_d) \
40 (((_d)->cflags & PCIE_DEV_CFLAG_DVSEC_RMEDA) != 0U)
41
42struct pcie_dev {
43 uint32_t bdf;
44
45 /* Pointer to rootport device if this is a endpoint */
46 struct pcie_dev *rp_dev;
47
48 /* PCIe capabilities flags */
49 uint32_t cflags;
50
51 uint32_t doe_cap_base;
52 uint32_t ide_cap_base;
53 uint32_t dvsec_rmeda_cap_base;
54
55 /* Device port type */
56 uint32_t dp_type;
57
58 unsigned long ecam_base;
59};
60typedef struct pcie_dev pcie_dev_t;
61
62typedef struct {
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010063 uint32_t num_entries;
Arunachalam Ganapathyb0833d22025-06-26 11:05:51 +010064 pcie_dev_t device[PCIE_DEVICES_MAX];
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010065} pcie_device_bdf_table_t;
66
67/* Address initialisation structure */
68typedef struct {
69 /* 64 bit prefetchable memory start address */
70 uint64_t bar64_p_start;
71 uint64_t rp_bar64_value;
72 /* 32 bit non-prefetchable memory start address */
73 uint32_t bar32_np_start;
74 /* 32 bit prefetchable memory start address */
75 uint32_t bar32_p_start;
76 uint32_t rp_bar32_value;
77} pcie_bar_init_t;
78
Arunachalam Ganapathy716c8cc2025-02-25 18:22:45 +000079#define PCIE_EXTRACT_BDF_SEG(bdf) ((bdf >> 16) & 0xFF)
80#define PCIE_EXTRACT_BDF_BUS(bdf) ((bdf >> 8) & 0xFF)
81#define PCIE_EXTRACT_BDF_DEV(bdf) ((bdf >> 3) & 0x1F)
82#define PCIE_EXTRACT_BDF_FUNC(bdf) (bdf & 0x7)
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010083
84/* PCI-compatible region */
85#define PCI_CMP_CFG_SIZE 256
86
87/* PCI Express Extended Configuration Space */
88#define PCIE_CFG_SIZE 4096
89
90#define PCIE_MAX_BUS 256
91#define PCIE_MAX_DEV 32
92#define PCIE_MAX_FUNC 8
93
94#define PCIE_CREATE_BDF(Seg, Bus, Dev, Func) \
Arunachalam Ganapathy716c8cc2025-02-25 18:22:45 +000095 ((Seg << 16) | (Bus << 8) | (Dev << 3) | Func)
AlexeiFedorov9f0dc012024-09-10 10:22:06 +010096
97#define PCIE_SUCCESS 0x00000000 /* Operation completed successfully */
98#define PCIE_NO_MAPPING 0x10000001 /* A mapping to a Function does not exist */
99#define PCIE_CAP_NOT_FOUND 0x10000010 /* The specified capability was not found */
100#define PCIE_UNKNOWN_RESPONSE 0xFFFFFFFF /* Function not found or UR response from completer */
101
AlexeiFedorov9f0dc012024-09-10 10:22:06 +0100102typedef enum {
103 HEADER = 0,
104 PCIE_CAP = 1,
105 PCIE_ECAP = 2
106} bitfield_reg_type_t;
107
108typedef enum {
109 HW_INIT = 0,
110 READ_ONLY = 1,
111 STICKY_RO = 2,
112 RSVDP_RO = 3,
113 RSVDZ_RO = 4,
114 READ_WRITE = 5,
115 STICKY_RW = 6
116} bitfield_attr_type_t;
117
118/* Class Code Masks */
119#define CC_SUB_MASK 0xFF /* Sub Class */
120#define CC_BASE_MASK 0xFF /* Base Class */
121
122/* Class Code Shifts */
123#define CC_SHIFT 8
124#define CC_SUB_SHIFT 16
125#define CC_BASE_SHIFT 24
126
Soby Mathew5929bfe2024-11-28 12:28:00 +0000127void pcie_init(void);
Arunachalam Ganapathy503b89a2025-06-19 10:34:11 +0100128
AlexeiFedorov9f0dc012024-09-10 10:22:06 +0100129pcie_device_bdf_table_t *pcie_get_bdf_table(void);
130uint32_t pcie_find_capability(uint32_t bdf, uint32_t cid_type, uint32_t cid,
131 uint32_t *cid_offset);
132uint32_t pcie_read_cfg(uint32_t bdf, uint32_t offset);
133void pcie_write_cfg(uint32_t bdf, uint32_t offset, uint32_t data);
134
135#endif /* PCIE_H */