1210284Sjmallett/***********************license start***************
2232812Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18232812Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49210284Sjmallett * Interface to PCIe as a host(RC) or target(EP)
50210284Sjmallett *
51232812Sjmallett * <hr>$Revision: 70030 $<hr>
52210284Sjmallett */
53210284Sjmallett
54210284Sjmallett#ifndef __CVMX_PCIE_H__
55210284Sjmallett#define __CVMX_PCIE_H__
56210284Sjmallett
57210284Sjmallett#ifdef	__cplusplus
58210284Sjmallettextern "C" {
59210284Sjmallett#endif
60210284Sjmallett
61215990Sjmallett/*
62215990Sjmallett * The physical memory base mapped by BAR1.  256MB at the end of the
63215990Sjmallett * first 4GB.
64215990Sjmallett */
65215990Sjmallett#define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28))
66215990Sjmallett#define CVMX_PCIE_BAR1_PHYS_SIZE (1ull << 28)
67215990Sjmallett
68215990Sjmallett/*
69215990Sjmallett * The RC base of BAR1.  gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2,
70215990Sjmallett * place BAR1 so it is the same for both.
71215990Sjmallett */
72215990Sjmallett#define CVMX_PCIE_BAR1_RC_BASE (1ull << 41)
73215990Sjmallett
74210284Sjmalletttypedef union
75210284Sjmallett{
76210284Sjmallett    uint64_t    u64;
77210284Sjmallett    struct
78210284Sjmallett    {
79210284Sjmallett        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
80210284Sjmallett        uint64_t    reserved_49_61  : 13;   /* Must be zero */
81210284Sjmallett        uint64_t    io              : 1;    /* 1 for IO space access */
82210284Sjmallett        uint64_t    did             : 5;    /* PCIe DID = 3 */
83210284Sjmallett        uint64_t    subdid          : 3;    /* PCIe SubDID = 1 */
84210284Sjmallett        uint64_t    reserved_36_39  : 4;    /* Must be zero */
85210284Sjmallett        uint64_t    es              : 2;    /* Endian swap = 1 */
86210284Sjmallett        uint64_t    port            : 2;    /* PCIe port 0,1 */
87210284Sjmallett        uint64_t    reserved_29_31  : 3;    /* Must be zero */
88210284Sjmallett        uint64_t    ty              : 1;    /* Selects the type of the configuration request (0 = type 0, 1 = type 1). */
89210284Sjmallett        uint64_t    bus             : 8;    /* Target bus number sent in the ID in the request. */
90210284Sjmallett        uint64_t    dev             : 5;    /* Target device number sent in the ID in the request. Note that Dev must be
91210284Sjmallett                                                zero for type 0 configuration requests. */
92210284Sjmallett        uint64_t    func            : 3;    /* Target function number sent in the ID in the request. */
93210284Sjmallett        uint64_t    reg             : 12;   /* Selects a register in the configuration space of the target. */
94210284Sjmallett    } config;
95210284Sjmallett    struct
96210284Sjmallett    {
97210284Sjmallett        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
98210284Sjmallett        uint64_t    reserved_49_61  : 13;   /* Must be zero */
99210284Sjmallett        uint64_t    io              : 1;    /* 1 for IO space access */
100210284Sjmallett        uint64_t    did             : 5;    /* PCIe DID = 3 */
101210284Sjmallett        uint64_t    subdid          : 3;    /* PCIe SubDID = 2 */
102210284Sjmallett        uint64_t    reserved_36_39  : 4;    /* Must be zero */
103210284Sjmallett        uint64_t    es              : 2;    /* Endian swap = 1 */
104210284Sjmallett        uint64_t    port            : 2;    /* PCIe port 0,1 */
105210284Sjmallett        uint64_t    address         : 32;   /* PCIe IO address */
106210284Sjmallett    } io;
107210284Sjmallett    struct
108210284Sjmallett    {
109210284Sjmallett        uint64_t    upper           : 2;    /* Normally 2 for XKPHYS */
110210284Sjmallett        uint64_t    reserved_49_61  : 13;   /* Must be zero */
111210284Sjmallett        uint64_t    io              : 1;    /* 1 for IO space access */
112210284Sjmallett        uint64_t    did             : 5;    /* PCIe DID = 3 */
113210284Sjmallett        uint64_t    subdid          : 3;    /* PCIe SubDID = 3-6 */
114210284Sjmallett        uint64_t    reserved_36_39  : 4;    /* Must be zero */
115210284Sjmallett        uint64_t    address         : 36;   /* PCIe Mem address */
116210284Sjmallett    } mem;
117210284Sjmallett} cvmx_pcie_address_t;
118210284Sjmallett
119210284Sjmallett
120210284Sjmallett/**
121210284Sjmallett * Return the Core virtual base address for PCIe IO access. IOs are
122210284Sjmallett * read/written as an offset from this address.
123210284Sjmallett *
124210284Sjmallett * @param pcie_port PCIe port the IO is for
125210284Sjmallett *
126210284Sjmallett * @return 64bit Octeon IO base address for read/write
127210284Sjmallett */
128210284Sjmallettuint64_t cvmx_pcie_get_io_base_address(int pcie_port);
129210284Sjmallett
130210284Sjmallett/**
131210284Sjmallett * Size of the IO address region returned at address
132210284Sjmallett * cvmx_pcie_get_io_base_address()
133210284Sjmallett *
134210284Sjmallett * @param pcie_port PCIe port the IO is for
135210284Sjmallett *
136210284Sjmallett * @return Size of the IO window
137210284Sjmallett */
138210284Sjmallettuint64_t cvmx_pcie_get_io_size(int pcie_port);
139210284Sjmallett
140210284Sjmallett/**
141210284Sjmallett * Return the Core virtual base address for PCIe MEM access. Memory is
142210284Sjmallett * read/written as an offset from this address.
143210284Sjmallett *
144210284Sjmallett * @param pcie_port PCIe port the IO is for
145210284Sjmallett *
146210284Sjmallett * @return 64bit Octeon IO base address for read/write
147210284Sjmallett */
148210284Sjmallettuint64_t cvmx_pcie_get_mem_base_address(int pcie_port);
149210284Sjmallett
150210284Sjmallett/**
151210284Sjmallett * Size of the Mem address region returned at address
152210284Sjmallett * cvmx_pcie_get_mem_base_address()
153210284Sjmallett *
154210284Sjmallett * @param pcie_port PCIe port the IO is for
155210284Sjmallett *
156210284Sjmallett * @return Size of the Mem window
157210284Sjmallett */
158210284Sjmallettuint64_t cvmx_pcie_get_mem_size(int pcie_port);
159210284Sjmallett
160210284Sjmallett/**
161210284Sjmallett * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus.
162210284Sjmallett *
163210284Sjmallett * @param pcie_port PCIe port to initialize
164210284Sjmallett *
165210284Sjmallett * @return Zero on success
166210284Sjmallett */
167210284Sjmallettint cvmx_pcie_rc_initialize(int pcie_port);
168210284Sjmallett
169210284Sjmallett/**
170210284Sjmallett * Shutdown a PCIe port and put it in reset
171210284Sjmallett *
172210284Sjmallett * @param pcie_port PCIe port to shutdown
173210284Sjmallett *
174210284Sjmallett * @return Zero on success
175210284Sjmallett */
176210284Sjmallettint cvmx_pcie_rc_shutdown(int pcie_port);
177210284Sjmallett
178210284Sjmallett/**
179210284Sjmallett * Read 8bits from a Device's config space
180210284Sjmallett *
181210284Sjmallett * @param pcie_port PCIe port the device is on
182210284Sjmallett * @param bus       Sub bus
183210284Sjmallett * @param dev       Device ID
184210284Sjmallett * @param fn        Device sub function
185210284Sjmallett * @param reg       Register to access
186210284Sjmallett *
187210284Sjmallett * @return Result of the read
188210284Sjmallett */
189210284Sjmallettuint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev, int fn, int reg);
190210284Sjmallett
191210284Sjmallett/**
192210284Sjmallett * Read 16bits from a Device's config space
193210284Sjmallett *
194210284Sjmallett * @param pcie_port PCIe port the device is on
195210284Sjmallett * @param bus       Sub bus
196210284Sjmallett * @param dev       Device ID
197210284Sjmallett * @param fn        Device sub function
198210284Sjmallett * @param reg       Register to access
199210284Sjmallett *
200210284Sjmallett * @return Result of the read
201210284Sjmallett */
202210284Sjmallettuint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, int reg);
203210284Sjmallett
204210284Sjmallett/**
205210284Sjmallett * Read 32bits from a Device's config space
206210284Sjmallett *
207210284Sjmallett * @param pcie_port PCIe port the device is on
208210284Sjmallett * @param bus       Sub bus
209210284Sjmallett * @param dev       Device ID
210210284Sjmallett * @param fn        Device sub function
211210284Sjmallett * @param reg       Register to access
212210284Sjmallett *
213210284Sjmallett * @return Result of the read
214210284Sjmallett */
215210284Sjmallettuint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg);
216210284Sjmallett
217210284Sjmallett/**
218210284Sjmallett * Write 8bits to a Device's config space
219210284Sjmallett *
220210284Sjmallett * @param pcie_port PCIe port the device is on
221210284Sjmallett * @param bus       Sub bus
222210284Sjmallett * @param dev       Device ID
223210284Sjmallett * @param fn        Device sub function
224210284Sjmallett * @param reg       Register to access
225210284Sjmallett * @param val       Value to write
226210284Sjmallett */
227210284Sjmallettvoid cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, int reg, uint8_t val);
228210284Sjmallett
229210284Sjmallett/**
230210284Sjmallett * Write 16bits to a Device's config space
231210284Sjmallett *
232210284Sjmallett * @param pcie_port PCIe port the device is on
233210284Sjmallett * @param bus       Sub bus
234210284Sjmallett * @param dev       Device ID
235210284Sjmallett * @param fn        Device sub function
236210284Sjmallett * @param reg       Register to access
237210284Sjmallett * @param val       Value to write
238210284Sjmallett */
239210284Sjmallettvoid cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, int reg, uint16_t val);
240210284Sjmallett
241210284Sjmallett/**
242210284Sjmallett * Write 32bits to a Device's config space
243210284Sjmallett *
244210284Sjmallett * @param pcie_port PCIe port the device is on
245210284Sjmallett * @param bus       Sub bus
246210284Sjmallett * @param dev       Device ID
247210284Sjmallett * @param fn        Device sub function
248210284Sjmallett * @param reg       Register to access
249210284Sjmallett * @param val       Value to write
250210284Sjmallett */
251210284Sjmallettvoid cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, uint32_t val);
252210284Sjmallett
253210284Sjmallett/**
254210284Sjmallett * Read a PCIe config space register indirectly. This is used for
255210284Sjmallett * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
256210284Sjmallett *
257210284Sjmallett * @param pcie_port  PCIe port to read from
258210284Sjmallett * @param cfg_offset Address to read
259210284Sjmallett *
260210284Sjmallett * @return Value read
261210284Sjmallett */
262210284Sjmallettuint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset);
263210284Sjmallett
264210284Sjmallett/**
265210284Sjmallett * Write a PCIe config space register indirectly. This is used for
266210284Sjmallett * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
267210284Sjmallett *
268210284Sjmallett * @param pcie_port  PCIe port to write to
269210284Sjmallett * @param cfg_offset Address to write
270210284Sjmallett * @param val        Value to write
271210284Sjmallett */
272210284Sjmallettvoid cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset, uint32_t val);
273210284Sjmallett
274210284Sjmallett/**
275210284Sjmallett * Write a 32bit value to the Octeon NPEI register space
276210284Sjmallett *
277210284Sjmallett * @param address Address to write to
278210284Sjmallett * @param val     Value to write
279210284Sjmallett */
280210284Sjmallettstatic inline void cvmx_pcie_npei_write32(uint64_t address, uint32_t val)
281210284Sjmallett{
282210284Sjmallett	cvmx_write64_uint32(address ^ 4, val);
283210284Sjmallett	cvmx_read64_uint32(address ^ 4);
284210284Sjmallett}
285210284Sjmallett
286210284Sjmallett/**
287210284Sjmallett * Read a 32bit value from the Octeon NPEI register space
288210284Sjmallett *
289210284Sjmallett * @param address Address to read
290210284Sjmallett * @return The result
291210284Sjmallett */
292210284Sjmallettstatic inline uint32_t cvmx_pcie_npei_read32(uint64_t address)
293210284Sjmallett{
294210284Sjmallett	return cvmx_read64_uint32(address ^ 4);
295210284Sjmallett}
296210284Sjmallett
297210284Sjmallett/**
298210284Sjmallett * Initialize a PCIe port for use in target(EP) mode.
299210284Sjmallett *
300215990Sjmallett * @param pcie_port PCIe port to initialize
301215990Sjmallett *
302210284Sjmallett * @return Zero on success
303210284Sjmallett */
304215990Sjmallettint cvmx_pcie_ep_initialize(int pcie_port);
305210284Sjmallett
306210284Sjmallett/**
307210284Sjmallett * Wait for posted PCIe read/writes to reach the other side of
308210284Sjmallett * the internal PCIe switch. This will insure that core
309210284Sjmallett * read/writes are posted before anything after this function
310210284Sjmallett * is called. This may be necessary when writing to memory that
311210284Sjmallett * will later be read using the DMA/PKT engines.
312210284Sjmallett *
313210284Sjmallett * @param pcie_port PCIe port to wait for
314210284Sjmallett */
315210284Sjmallettvoid cvmx_pcie_wait_for_pending(int pcie_port);
316210284Sjmallett
317210284Sjmallett#ifdef	__cplusplus
318210284Sjmallett}
319210284Sjmallett#endif
320210284Sjmallett
321210284Sjmallett#endif
322