1/***********************license start***************
2 * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3 * reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *   * Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 *
13 *   * Redistributions in binary form must reproduce the above
14 *     copyright notice, this list of conditions and the following
15 *     disclaimer in the documentation and/or other materials provided
16 *     with the distribution.
17
18 *   * Neither the name of Cavium Inc. nor the names of
19 *     its contributors may be used to endorse or promote products
20 *     derived from this software without specific prior written
21 *     permission.
22
23 * This Software, including technical data, may be subject to U.S. export  control
24 * laws, including the U.S. Export Administration Act and its  associated
25 * regulations, and may be subject to export or import  regulations in other
26 * countries.
27
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
39
40
41
42
43
44
45
46/**
47 * @file
48 *
49 * Interface to PCIe as a host(RC) or target(EP)
50 *
51 * <hr>$Revision: 70030 $<hr>
52 */
53
54#ifndef __CVMX_PCIE_H__
55#define __CVMX_PCIE_H__
56
57#ifdef	__cplusplus
58extern "C" {
59#endif
60
61/*
62 * The physical memory base mapped by BAR1.  256MB at the end of the
63 * first 4GB.
64 */
65#define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28))
66#define CVMX_PCIE_BAR1_PHYS_SIZE (1ull << 28)
67
68/*
69 * The RC base of BAR1.  gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2,
70 * place BAR1 so it is the same for both.
71 */
72#define CVMX_PCIE_BAR1_RC_BASE (1ull << 41)
73
74typedef union
75{
76    uint64_t    u64;
77    struct
78    {
79        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
80        uint64_t    reserved_49_61  : 13;   /* Must be zero */
81        uint64_t    io              : 1;    /* 1 for IO space access */
82        uint64_t    did             : 5;    /* PCIe DID = 3 */
83        uint64_t    subdid          : 3;    /* PCIe SubDID = 1 */
84        uint64_t    reserved_36_39  : 4;    /* Must be zero */
85        uint64_t    es              : 2;    /* Endian swap = 1 */
86        uint64_t    port            : 2;    /* PCIe port 0,1 */
87        uint64_t    reserved_29_31  : 3;    /* Must be zero */
88        uint64_t    ty              : 1;    /* Selects the type of the configuration request (0 = type 0, 1 = type 1). */
89        uint64_t    bus             : 8;    /* Target bus number sent in the ID in the request. */
90        uint64_t    dev             : 5;    /* Target device number sent in the ID in the request. Note that Dev must be
91                                                zero for type 0 configuration requests. */
92        uint64_t    func            : 3;    /* Target function number sent in the ID in the request. */
93        uint64_t    reg             : 12;   /* Selects a register in the configuration space of the target. */
94    } config;
95    struct
96    {
97        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
98        uint64_t    reserved_49_61  : 13;   /* Must be zero */
99        uint64_t    io              : 1;    /* 1 for IO space access */
100        uint64_t    did             : 5;    /* PCIe DID = 3 */
101        uint64_t    subdid          : 3;    /* PCIe SubDID = 2 */
102        uint64_t    reserved_36_39  : 4;    /* Must be zero */
103        uint64_t    es              : 2;    /* Endian swap = 1 */
104        uint64_t    port            : 2;    /* PCIe port 0,1 */
105        uint64_t    address         : 32;   /* PCIe IO address */
106    } io;
107    struct
108    {
109        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
110        uint64_t    reserved_49_61  : 13;   /* Must be zero */
111        uint64_t    io              : 1;    /* 1 for IO space access */
112        uint64_t    did             : 5;    /* PCIe DID = 3 */
113        uint64_t    subdid          : 3;    /* PCIe SubDID = 3-6 */
114        uint64_t    reserved_36_39  : 4;    /* Must be zero */
115        uint64_t    address         : 36;   /* PCIe Mem address */
116    } mem;
117} cvmx_pcie_address_t;
118
119
120/**
121 * Return the Core virtual base address for PCIe IO access. IOs are
122 * read/written as an offset from this address.
123 *
124 * @param pcie_port PCIe port the IO is for
125 *
126 * @return 64bit Octeon IO base address for read/write
127 */
128uint64_t cvmx_pcie_get_io_base_address(int pcie_port);
129
130/**
131 * Size of the IO address region returned at address
132 * cvmx_pcie_get_io_base_address()
133 *
134 * @param pcie_port PCIe port the IO is for
135 *
136 * @return Size of the IO window
137 */
138uint64_t cvmx_pcie_get_io_size(int pcie_port);
139
140/**
141 * Return the Core virtual base address for PCIe MEM access. Memory is
142 * read/written as an offset from this address.
143 *
144 * @param pcie_port PCIe port the IO is for
145 *
146 * @return 64bit Octeon IO base address for read/write
147 */
148uint64_t cvmx_pcie_get_mem_base_address(int pcie_port);
149
150/**
151 * Size of the Mem address region returned at address
152 * cvmx_pcie_get_mem_base_address()
153 *
154 * @param pcie_port PCIe port the IO is for
155 *
156 * @return Size of the Mem window
157 */
158uint64_t cvmx_pcie_get_mem_size(int pcie_port);
159
160/**
161 * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus.
162 *
163 * @param pcie_port PCIe port to initialize
164 *
165 * @return Zero on success
166 */
167int cvmx_pcie_rc_initialize(int pcie_port);
168
169/**
170 * Shutdown a PCIe port and put it in reset
171 *
172 * @param pcie_port PCIe port to shutdown
173 *
174 * @return Zero on success
175 */
176int cvmx_pcie_rc_shutdown(int pcie_port);
177
178/**
179 * Read 8bits from a Device's config space
180 *
181 * @param pcie_port PCIe port the device is on
182 * @param bus       Sub bus
183 * @param dev       Device ID
184 * @param fn        Device sub function
185 * @param reg       Register to access
186 *
187 * @return Result of the read
188 */
189uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev, int fn, int reg);
190
191/**
192 * Read 16bits from a Device's config space
193 *
194 * @param pcie_port PCIe port the device is on
195 * @param bus       Sub bus
196 * @param dev       Device ID
197 * @param fn        Device sub function
198 * @param reg       Register to access
199 *
200 * @return Result of the read
201 */
202uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, int reg);
203
204/**
205 * Read 32bits from a Device's config space
206 *
207 * @param pcie_port PCIe port the device is on
208 * @param bus       Sub bus
209 * @param dev       Device ID
210 * @param fn        Device sub function
211 * @param reg       Register to access
212 *
213 * @return Result of the read
214 */
215uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg);
216
217/**
218 * Write 8bits to a Device's config space
219 *
220 * @param pcie_port PCIe port the device is on
221 * @param bus       Sub bus
222 * @param dev       Device ID
223 * @param fn        Device sub function
224 * @param reg       Register to access
225 * @param val       Value to write
226 */
227void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, int reg, uint8_t val);
228
229/**
230 * Write 16bits to a Device's config space
231 *
232 * @param pcie_port PCIe port the device is on
233 * @param bus       Sub bus
234 * @param dev       Device ID
235 * @param fn        Device sub function
236 * @param reg       Register to access
237 * @param val       Value to write
238 */
239void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, int reg, uint16_t val);
240
241/**
242 * Write 32bits to a Device's config space
243 *
244 * @param pcie_port PCIe port the device is on
245 * @param bus       Sub bus
246 * @param dev       Device ID
247 * @param fn        Device sub function
248 * @param reg       Register to access
249 * @param val       Value to write
250 */
251void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, uint32_t val);
252
253/**
254 * Read a PCIe config space register indirectly. This is used for
255 * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
256 *
257 * @param pcie_port  PCIe port to read from
258 * @param cfg_offset Address to read
259 *
260 * @return Value read
261 */
262uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset);
263
264/**
265 * Write a PCIe config space register indirectly. This is used for
266 * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
267 *
268 * @param pcie_port  PCIe port to write to
269 * @param cfg_offset Address to write
270 * @param val        Value to write
271 */
272void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset, uint32_t val);
273
274/**
275 * Write a 32bit value to the Octeon NPEI register space
276 *
277 * @param address Address to write to
278 * @param val     Value to write
279 */
280static inline void cvmx_pcie_npei_write32(uint64_t address, uint32_t val)
281{
282	cvmx_write64_uint32(address ^ 4, val);
283	cvmx_read64_uint32(address ^ 4);
284}
285
286/**
287 * Read a 32bit value from the Octeon NPEI register space
288 *
289 * @param address Address to read
290 * @return The result
291 */
292static inline uint32_t cvmx_pcie_npei_read32(uint64_t address)
293{
294	return cvmx_read64_uint32(address ^ 4);
295}
296
297/**
298 * Initialize a PCIe port for use in target(EP) mode.
299 *
300 * @param pcie_port PCIe port to initialize
301 *
302 * @return Zero on success
303 */
304int cvmx_pcie_ep_initialize(int pcie_port);
305
306/**
307 * Wait for posted PCIe read/writes to reach the other side of
308 * the internal PCIe switch. This will insure that core
309 * read/writes are posted before anything after this function
310 * is called. This may be necessary when writing to memory that
311 * will later be read using the DMA/PKT engines.
312 *
313 * @param pcie_port PCIe port to wait for
314 */
315void cvmx_pcie_wait_for_pending(int pcie_port);
316
317#ifdef	__cplusplus
318}
319#endif
320
321#endif
322