blob: 95ac7f2c935022e16f7394496deb61d9458f9756 [file] [log] [blame]
Aaron Williams4fd1e552021-04-23 19:56:32 +02001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
6#ifndef __CVMX_PCIE_H__
7#define __CVMX_PCIE_H__
8
9#define CVMX_PCIE_MAX_PORTS 4
10#define CVMX_PCIE_PORTS \
11 ((OCTEON_IS_MODEL(OCTEON_CN78XX) || OCTEON_IS_MODEL(OCTEON_CN73XX)) ? \
12 CVMX_PCIE_MAX_PORTS : \
13 (OCTEON_IS_MODEL(OCTEON_CN70XX) ? 3 : 2))
14
15/*
16 * The physical memory base mapped by BAR1. 256MB at the end of the
17 * first 4GB.
18 */
19#define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28))
20#define CVMX_PCIE_BAR1_PHYS_SIZE BIT_ULL(28)
21
22/*
23 * The RC base of BAR1. gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2,
24 * place BAR1 so it is the same for both.
25 */
26#define CVMX_PCIE_BAR1_RC_BASE BIT_ULL(41)
27
28typedef union {
29 u64 u64;
30 struct {
31 u64 upper : 2; /* Normally 2 for XKPHYS */
32 u64 reserved_49_61 : 13; /* Must be zero */
33 u64 io : 1; /* 1 for IO space access */
34 u64 did : 5; /* PCIe DID = 3 */
35 u64 subdid : 3; /* PCIe SubDID = 1 */
36 u64 reserved_38_39 : 2; /* Must be zero */
37 u64 node : 2; /* Numa node number */
38 u64 es : 2; /* Endian swap = 1 */
39 u64 port : 2; /* PCIe port 0,1 */
40 u64 reserved_29_31 : 3; /* Must be zero */
41 u64 ty : 1;
42 u64 bus : 8;
43 u64 dev : 5;
44 u64 func : 3;
45 u64 reg : 12;
46 } config;
47 struct {
48 u64 upper : 2; /* Normally 2 for XKPHYS */
49 u64 reserved_49_61 : 13; /* Must be zero */
50 u64 io : 1; /* 1 for IO space access */
51 u64 did : 5; /* PCIe DID = 3 */
52 u64 subdid : 3; /* PCIe SubDID = 2 */
53 u64 reserved_38_39 : 2; /* Must be zero */
54 u64 node : 2; /* Numa node number */
55 u64 es : 2; /* Endian swap = 1 */
56 u64 port : 2; /* PCIe port 0,1 */
57 u64 address : 32; /* PCIe IO address */
58 } io;
59 struct {
60 u64 upper : 2; /* Normally 2 for XKPHYS */
61 u64 reserved_49_61 : 13; /* Must be zero */
62 u64 io : 1; /* 1 for IO space access */
63 u64 did : 5; /* PCIe DID = 3 */
64 u64 subdid : 3; /* PCIe SubDID = 3-6 */
65 u64 reserved_38_39 : 2; /* Must be zero */
66 u64 node : 2; /* Numa node number */
67 u64 address : 36; /* PCIe Mem address */
68 } mem;
69} cvmx_pcie_address_t;
70
71/**
72 * Return the Core virtual base address for PCIe IO access. IOs are
73 * read/written as an offset from this address.
74 *
75 * @param pcie_port PCIe port the IO is for
76 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010077 * Return: 64bit Octeon IO base address for read/write
Aaron Williams4fd1e552021-04-23 19:56:32 +020078 */
79u64 cvmx_pcie_get_io_base_address(int pcie_port);
80
81/**
82 * Size of the IO address region returned at address
83 * cvmx_pcie_get_io_base_address()
84 *
85 * @param pcie_port PCIe port the IO is for
86 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010087 * Return: Size of the IO window
Aaron Williams4fd1e552021-04-23 19:56:32 +020088 */
89u64 cvmx_pcie_get_io_size(int pcie_port);
90
91/**
92 * Return the Core virtual base address for PCIe MEM access. Memory is
93 * read/written as an offset from this address.
94 *
95 * @param pcie_port PCIe port the IO is for
96 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010097 * Return: 64bit Octeon IO base address for read/write
Aaron Williams4fd1e552021-04-23 19:56:32 +020098 */
99u64 cvmx_pcie_get_mem_base_address(int pcie_port);
100
101/**
102 * Size of the Mem address region returned at address
103 * cvmx_pcie_get_mem_base_address()
104 *
105 * @param pcie_port PCIe port the IO is for
106 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100107 * Return: Size of the Mem window
Aaron Williams4fd1e552021-04-23 19:56:32 +0200108 */
109u64 cvmx_pcie_get_mem_size(int pcie_port);
110
111/**
112 * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus.
113 *
114 * @param pcie_port PCIe port to initialize
115 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100116 * Return: Zero on success
Aaron Williams4fd1e552021-04-23 19:56:32 +0200117 */
118int cvmx_pcie_rc_initialize(int pcie_port);
119
120/**
121 * Shutdown a PCIe port and put it in reset
122 *
123 * @param pcie_port PCIe port to shutdown
124 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100125 * Return: Zero on success
Aaron Williams4fd1e552021-04-23 19:56:32 +0200126 */
127int cvmx_pcie_rc_shutdown(int pcie_port);
128
129/**
130 * Read 8bits from a Device's config space
131 *
132 * @param pcie_port PCIe port the device is on
133 * @param bus Sub bus
134 * @param dev Device ID
135 * @param fn Device sub function
136 * @param reg Register to access
137 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100138 * Return: Result of the read
Aaron Williams4fd1e552021-04-23 19:56:32 +0200139 */
140u8 cvmx_pcie_config_read8(int pcie_port, int bus, int dev, int fn, int reg);
141
142/**
143 * Read 16bits from a Device's config space
144 *
145 * @param pcie_port PCIe port the device is on
146 * @param bus Sub bus
147 * @param dev Device ID
148 * @param fn Device sub function
149 * @param reg Register to access
150 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100151 * Return: Result of the read
Aaron Williams4fd1e552021-04-23 19:56:32 +0200152 */
153u16 cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, int reg);
154
155/**
156 * Read 32bits from a Device's config space
157 *
158 * @param pcie_port PCIe port the device is on
159 * @param bus Sub bus
160 * @param dev Device ID
161 * @param fn Device sub function
162 * @param reg Register to access
163 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100164 * Return: Result of the read
Aaron Williams4fd1e552021-04-23 19:56:32 +0200165 */
166u32 cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg);
167
168/**
169 * Write 8bits to a Device's config space
170 *
171 * @param pcie_port PCIe port the device is on
172 * @param bus Sub bus
173 * @param dev Device ID
174 * @param fn Device sub function
175 * @param reg Register to access
176 * @param val Value to write
177 */
178void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, int reg, u8 val);
179
180/**
181 * Write 16bits to a Device's config space
182 *
183 * @param pcie_port PCIe port the device is on
184 * @param bus Sub bus
185 * @param dev Device ID
186 * @param fn Device sub function
187 * @param reg Register to access
188 * @param val Value to write
189 */
190void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, int reg, u16 val);
191
192/**
193 * Write 32bits to a Device's config space
194 *
195 * @param pcie_port PCIe port the device is on
196 * @param bus Sub bus
197 * @param dev Device ID
198 * @param fn Device sub function
199 * @param reg Register to access
200 * @param val Value to write
201 */
202void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, u32 val);
203
204/**
205 * Read a PCIe config space register indirectly. This is used for
206 * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
207 *
208 * @param pcie_port PCIe port to read from
209 * @param cfg_offset Address to read
210 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100211 * Return: Value read
Aaron Williams4fd1e552021-04-23 19:56:32 +0200212 */
213u32 cvmx_pcie_cfgx_read(int pcie_port, u32 cfg_offset);
214u32 cvmx_pcie_cfgx_read_node(int node, int pcie_port, u32 cfg_offset);
215
216/**
217 * Write a PCIe config space register indirectly. This is used for
218 * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
219 *
220 * @param pcie_port PCIe port to write to
221 * @param cfg_offset Address to write
222 * @param val Value to write
223 */
224void cvmx_pcie_cfgx_write(int pcie_port, u32 cfg_offset, u32 val);
225void cvmx_pcie_cfgx_write_node(int node, int pcie_port, u32 cfg_offset, u32 val);
226
227/**
228 * Write a 32bit value to the Octeon NPEI register space
229 *
230 * @param address Address to write to
231 * @param val Value to write
232 */
233static inline void cvmx_pcie_npei_write32(u64 address, u32 val)
234{
235 cvmx_write64_uint32(address ^ 4, val);
236 cvmx_read64_uint32(address ^ 4);
237}
238
239/**
240 * Read a 32bit value from the Octeon NPEI register space
241 *
242 * @param address Address to read
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100243 * Return: The result
Aaron Williams4fd1e552021-04-23 19:56:32 +0200244 */
245static inline u32 cvmx_pcie_npei_read32(u64 address)
246{
247 return cvmx_read64_uint32(address ^ 4);
248}
249
250/**
251 * Initialize a PCIe port for use in target(EP) mode.
252 *
253 * @param pcie_port PCIe port to initialize
254 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100255 * Return: Zero on success
Aaron Williams4fd1e552021-04-23 19:56:32 +0200256 */
257int cvmx_pcie_ep_initialize(int pcie_port);
258
259/**
260 * Wait for posted PCIe read/writes to reach the other side of
261 * the internal PCIe switch. This will insure that core
262 * read/writes are posted before anything after this function
263 * is called. This may be necessary when writing to memory that
264 * will later be read using the DMA/PKT engines.
265 *
266 * @param pcie_port PCIe port to wait for
267 */
268void cvmx_pcie_wait_for_pending(int pcie_port);
269
270/**
271 * Returns if a PCIe port is in host or target mode.
272 *
273 * @param pcie_port PCIe port number (PEM number)
274 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100275 * Return: 0 if PCIe port is in target mode, !0 if in host mode.
Aaron Williams4fd1e552021-04-23 19:56:32 +0200276 */
277int cvmx_pcie_is_host_mode(int pcie_port);
278
279#endif