diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2012-04-07 16:53:03 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-11 16:04:58 -0400 |
commit | bce5bbbb23f780a792be7e594af7cd4b4aae1cd4 (patch) | |
tree | d140d8badb0ed24f4ccc2f89266772ae6836f0f3 /arch/tile/include/gxio/trio.h | |
parent | 10104a1ad670889adc1ae3779df968db621b5dbd (diff) |
arch/tile: provide kernel support for the tilegx TRIO shim
Provide kernel support for the tilegx "Transaction I/O" (TRIO) on-chip
hardware. This hardware implements the PCIe interface for tilegx;
the driver changes to use TRIO for PCIe are in a subsequent commit.
The change is layered on top of the tilegx GXIO IORPC subsystem.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/include/gxio/trio.h')
-rw-r--r-- | arch/tile/include/gxio/trio.h | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/arch/tile/include/gxio/trio.h b/arch/tile/include/gxio/trio.h new file mode 100644 index 000000000000..77b80cdd46d8 --- /dev/null +++ b/arch/tile/include/gxio/trio.h | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * | ||
17 | * An API for allocating, configuring, and manipulating TRIO hardware | ||
18 | * resources | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * | ||
23 | * The TILE-Gx TRIO shim provides connections to external devices via | ||
24 | * PCIe or other transaction IO standards. The gxio_trio_ API, | ||
25 | * declared in <gxio/trio.h>, allows applications to allocate and | ||
26 | * configure TRIO IO resources like DMA command rings, memory map | ||
27 | * windows, and device interrupts. The following sections introduce | ||
28 | * the various components of the API. We strongly recommend reading | ||
29 | * the TRIO section of the IO Device Guide (UG404) before working with | ||
30 | * this API. | ||
31 | * | ||
32 | * @section trio__ingress TRIO Ingress Hardware Resources | ||
33 | * | ||
34 | * The TRIO ingress hardware is responsible for examining incoming | ||
35 | * PCIe or StreamIO packets and choosing a processing mechanism based | ||
36 | * on the packets' bus address. The gxio_trio_ API can be used to | ||
37 | * configure different handlers for different ranges of bus address | ||
38 | * space. The user can configure "mapped memory" and "scatter queue" | ||
39 | * regions to match incoming packets within 4kB-aligned ranges of bus | ||
40 | * addresses. Each range specifies a different set of mapping | ||
41 | * parameters to be applied when handling the ingress packet. The | ||
42 | * following sections describe how to work with MapMem and scatter | ||
43 | * queue regions. | ||
44 | * | ||
45 | * @subsection trio__mapmem TRIO MapMem Regions | ||
46 | * | ||
47 | * TRIO mapped memory (or MapMem) regions allow the user to map | ||
48 | * incoming read and write requests directly to the application's | ||
49 | * memory space. MapMem regions are allocated via | ||
50 | * gxio_trio_alloc_memory_maps(). Given an integer MapMem number, | ||
51 | * applications can use gxio_trio_init_memory_map() to specify the | ||
52 | * range of bus addresses that will match the region and the range of | ||
53 | * virtual addresses to which those packets will be applied. | ||
54 | * | ||
55 | * As with many other gxio APIs, the programmer must be sure to | ||
56 | * register memory pages that will be used with MapMem regions. Pages | ||
57 | * can be registered with TRIO by allocating an ASID (address space | ||
58 | * identifier) and then using gxio_trio_register_page() to register up to | ||
59 | * 16 pages with the hardware. The initialization functions for | ||
60 | * resources that require registered memory (MapMem, scatter queues, | ||
61 | * push DMA, and pull DMA) then take an 'asid' parameter in order to | ||
62 | * configure which set of registered pages is used by each resource. | ||
63 | * | ||
64 | * @subsection trio__scatter_queue TRIO Scatter Queues | ||
65 | * | ||
66 | * The TRIO shim's scatter queue regions allow users to dynamically | ||
67 | * map buffers from a large address space into a small range of bus | ||
68 | * addresses. This is particularly helpful for PCIe endpoint devices, | ||
69 | * where the host generally limits the size of BARs to tens of | ||
70 | * megabytes. | ||
71 | * | ||
72 | * Each scatter queue consists of a memory map region, a queue of | ||
73 | * tile-side buffer VAs to be mapped to that region, and a bus-mapped | ||
74 | * "doorbell" register that the remote endpoint can write to trigger a | ||
75 | * dequeue of the current buffer VA, thus swapping in a new buffer. | ||
76 | * The VAs pushed onto a scatter queue must be 4kB aligned, so | ||
77 | * applications may need to use higher-level protocols to inform | ||
78 | * remote entities that they should apply some additional, sub-4kB | ||
79 | * offset when reading or writing the scatter queue region. For more | ||
80 | * information, see the IO Device Guide (UG404). | ||
81 | * | ||
82 | * @section trio__egress TRIO Egress Hardware Resources | ||
83 | * | ||
84 | * The TRIO shim supports two mechanisms for egress packet generation: | ||
85 | * programmed IO (PIO) and push/pull DMA. PIO allows applications to | ||
86 | * create MMIO mappings for PCIe or StreamIO address space, such that | ||
87 | * the application can generate word-sized read or write transactions | ||
88 | * by issuing load or store instructions. Push and pull DMA are tuned | ||
89 | * for larger transactions; they use specialized hardware engines to | ||
90 | * transfer large blocks of data at line rate. | ||
91 | * | ||
92 | * @subsection trio__pio TRIO Programmed IO | ||
93 | * | ||
94 | * Programmed IO allows applications to create MMIO mappings for PCIe | ||
95 | * or StreamIO address space. The hardware PIO regions support access | ||
96 | * to PCIe configuration, IO, and memory space, but the gxio_trio API | ||
97 | * only supports memory space accesses. PIO regions are allocated | ||
98 | * with gxio_trio_alloc_pio_regions() and initialized via | ||
99 | * gxio_trio_init_pio_region(). Once a region is bound to a range of | ||
100 | * bus address via the initialization function, the application can | ||
101 | * use gxio_trio_map_pio_region() to create MMIO mappings from its VA | ||
102 | * space onto the range of bus addresses supported by the PIO region. | ||
103 | * | ||
104 | * @subsection trio_dma TRIO Push and Pull DMA | ||
105 | * | ||
106 | * The TRIO push and pull DMA engines allow users to copy blocks of | ||
107 | * data between application memory and the bus. Push DMA generates | ||
108 | * write packets that copy from application memory to the bus and pull | ||
109 | * DMA generates read packets that copy from the bus into application | ||
110 | * memory. The DMA engines are managed via an API that is very | ||
111 | * similar to the mPIPE eDMA interface. For a detailed explanation of | ||
112 | * the eDMA queue API, see @ref gxio_mpipe_wrappers. | ||
113 | * | ||
114 | * Push and pull DMA queues are allocated via | ||
115 | * gxio_trio_alloc_push_dma_ring() / gxio_trio_alloc_pull_dma_ring(). | ||
116 | * Once allocated, users generally use a ::gxio_trio_dma_queue_t | ||
117 | * object to manage the queue, providing easy wrappers for reserving | ||
118 | * command slots in the DMA command ring, filling those slots, and | ||
119 | * waiting for commands to complete. DMA queues can be initialized | ||
120 | * via gxio_trio_init_push_dma_queue() or | ||
121 | * gxio_trio_init_pull_dma_queue(). | ||
122 | * | ||
123 | * See @ref trio/push_dma/app.c for an example of how to use push DMA. | ||
124 | * | ||
125 | * @section trio_shortcomings Plans for Future API Revisions | ||
126 | * | ||
127 | * The simulation framework is incomplete. Future features include: | ||
128 | * | ||
129 | * - Support for reset and deallocation of resources. | ||
130 | * | ||
131 | * - Support for pull DMA. | ||
132 | * | ||
133 | * - Support for interrupt regions and user-space interrupt delivery. | ||
134 | * | ||
135 | * - Support for getting BAR mappings and reserving regions of BAR | ||
136 | * address space. | ||
137 | */ | ||
138 | #ifndef _GXIO_TRIO_H_ | ||
139 | #define _GXIO_TRIO_H_ | ||
140 | |||
141 | #include <linux/types.h> | ||
142 | |||
143 | #include "common.h" | ||
144 | #include "dma_queue.h" | ||
145 | |||
146 | #include <arch/trio_constants.h> | ||
147 | #include <arch/trio.h> | ||
148 | #include <arch/trio_pcie_intfc.h> | ||
149 | #include <arch/trio_pcie_rc.h> | ||
150 | #include <arch/trio_shm.h> | ||
151 | #include <hv/drv_trio_intf.h> | ||
152 | #include <hv/iorpc.h> | ||
153 | |||
154 | /* A context object used to manage TRIO hardware resources. */ | ||
155 | typedef struct { | ||
156 | |||
157 | /* File descriptor for calling up to Linux (and thus the HV). */ | ||
158 | int fd; | ||
159 | |||
160 | /* The VA at which the MAC MMIO registers are mapped. */ | ||
161 | char *mmio_base_mac; | ||
162 | |||
163 | /* The VA at which the PIO config space are mapped for each PCIe MAC. | ||
164 | Gx36 has max 3 PCIe MACs per TRIO shim. */ | ||
165 | char *mmio_base_pio_cfg[TILEGX_TRIO_PCIES]; | ||
166 | |||
167 | #ifdef USE_SHARED_PCIE_CONFIG_REGION | ||
168 | /* Index of the shared PIO region for PCI config access. */ | ||
169 | int pio_cfg_index; | ||
170 | #else | ||
171 | /* Index of the PIO region for PCI config access per MAC. */ | ||
172 | int pio_cfg_index[TILEGX_TRIO_PCIES]; | ||
173 | #endif | ||
174 | |||
175 | /* The VA at which the push DMA MMIO registers are mapped. */ | ||
176 | char *mmio_push_dma[TRIO_NUM_PUSH_DMA_RINGS]; | ||
177 | |||
178 | /* The VA at which the pull DMA MMIO registers are mapped. */ | ||
179 | char *mmio_pull_dma[TRIO_NUM_PUSH_DMA_RINGS]; | ||
180 | |||
181 | /* Application space ID. */ | ||
182 | unsigned int asid; | ||
183 | |||
184 | } gxio_trio_context_t; | ||
185 | |||
186 | /* Command descriptor for push or pull DMA. */ | ||
187 | typedef TRIO_DMA_DESC_t gxio_trio_dma_desc_t; | ||
188 | |||
189 | /* A convenient, thread-safe interface to an eDMA ring. */ | ||
190 | typedef struct { | ||
191 | |||
192 | /* State object for tracking head and tail pointers. */ | ||
193 | __gxio_dma_queue_t dma_queue; | ||
194 | |||
195 | /* The ring entries. */ | ||
196 | gxio_trio_dma_desc_t *dma_descs; | ||
197 | |||
198 | /* The number of entries minus one. */ | ||
199 | unsigned long mask_num_entries; | ||
200 | |||
201 | /* The log2() of the number of entries. */ | ||
202 | unsigned int log2_num_entries; | ||
203 | |||
204 | } gxio_trio_dma_queue_t; | ||
205 | |||
206 | /* Initialize a TRIO context. | ||
207 | * | ||
208 | * This function allocates a TRIO "service domain" and maps the MMIO | ||
209 | * registers into the the caller's VA space. | ||
210 | * | ||
211 | * @param trio_index Which TRIO shim; Gx36 must pass 0. | ||
212 | * @param context Context object to be initialized. | ||
213 | */ | ||
214 | extern int gxio_trio_init(gxio_trio_context_t *context, | ||
215 | unsigned int trio_index); | ||
216 | |||
217 | /* This indicates that an ASID hasn't been allocated. */ | ||
218 | #define GXIO_ASID_NULL -1 | ||
219 | |||
220 | /* Ordering modes for map memory regions and scatter queue regions. */ | ||
221 | typedef enum gxio_trio_order_mode_e { | ||
222 | /* Writes are not ordered. Reads always wait for previous writes. */ | ||
223 | GXIO_TRIO_ORDER_MODE_UNORDERED = | ||
224 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_UNORDERED, | ||
225 | /* Both writes and reads wait for previous transactions to complete. */ | ||
226 | GXIO_TRIO_ORDER_MODE_STRICT = | ||
227 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_STRICT, | ||
228 | /* Writes are ordered unless the incoming packet has the | ||
229 | relaxed-ordering attributes set. */ | ||
230 | GXIO_TRIO_ORDER_MODE_OBEY_PACKET = | ||
231 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_REL_ORD | ||
232 | } gxio_trio_order_mode_t; | ||
233 | |||
234 | /* Initialize a memory mapping region. | ||
235 | * | ||
236 | * @param context An initialized TRIO context. | ||
237 | * @param map A Memory map region allocated by gxio_trio_alloc_memory_map(). | ||
238 | * @param target_mem VA of backing memory, should be registered via | ||
239 | * gxio_trio_register_page() and aligned to 4kB. | ||
240 | * @param target_size Length of the memory mapping, must be a multiple | ||
241 | * of 4kB. | ||
242 | * @param asid ASID to be used for Tile-side address translation. | ||
243 | * @param mac MAC number. | ||
244 | * @param bus_address Bus address at which the mapping starts. | ||
245 | * @param order_mode Memory ordering mode for this mapping. | ||
246 | * @return Zero on success, else ::GXIO_TRIO_ERR_BAD_MEMORY_MAP, | ||
247 | * GXIO_TRIO_ERR_BAD_ASID, or ::GXIO_TRIO_ERR_BAD_BUS_RANGE. | ||
248 | */ | ||
249 | extern int gxio_trio_init_memory_map(gxio_trio_context_t *context, | ||
250 | unsigned int map, void *target_mem, | ||
251 | size_t target_size, unsigned int asid, | ||
252 | unsigned int mac, uint64_t bus_address, | ||
253 | gxio_trio_order_mode_t order_mode); | ||
254 | |||
255 | /* Flags that can be passed to resource allocation functions. */ | ||
256 | enum gxio_trio_alloc_flags_e { | ||
257 | GXIO_TRIO_ALLOC_FIXED = HV_TRIO_ALLOC_FIXED, | ||
258 | }; | ||
259 | |||
260 | /* Flags that can be passed to memory registration functions. */ | ||
261 | enum gxio_trio_mem_flags_e { | ||
262 | /* Do not fill L3 when writing, and invalidate lines upon egress. */ | ||
263 | GXIO_TRIO_MEM_FLAG_NT_HINT = IORPC_MEM_BUFFER_FLAG_NT_HINT, | ||
264 | |||
265 | /* L3 cache fills should only populate IO cache ways. */ | ||
266 | GXIO_TRIO_MEM_FLAG_IO_PIN = IORPC_MEM_BUFFER_FLAG_IO_PIN, | ||
267 | }; | ||
268 | |||
269 | /* Flag indicating a request generator uses a special traffic | ||
270 | class. */ | ||
271 | #define GXIO_TRIO_FLAG_TRAFFIC_CLASS(N) HV_TRIO_FLAG_TC(N) | ||
272 | |||
273 | /* Flag indicating a request generator uses a virtual function | ||
274 | number. */ | ||
275 | #define GXIO_TRIO_FLAG_VFUNC(N) HV_TRIO_FLAG_VFUNC(N) | ||
276 | |||
277 | /***************************************************************** | ||
278 | * Memory Registration * | ||
279 | ******************************************************************/ | ||
280 | |||
281 | /* Allocate Application Space Identifiers (ASIDs). Each ASID can | ||
282 | * register up to 16 page translations. ASIDs are used by memory map | ||
283 | * regions, scatter queues, and DMA queues to translate application | ||
284 | * VAs into memory system PAs. | ||
285 | * | ||
286 | * @param context An initialized TRIO context. | ||
287 | * @param count Number of ASIDs required. | ||
288 | * @param first Index of first ASID if ::GXIO_TRIO_ALLOC_FIXED flag | ||
289 | * is set, otherwise ignored. | ||
290 | * @param flags Flag bits, including bits from ::gxio_trio_alloc_flags_e. | ||
291 | * @return Index of first ASID, or ::GXIO_TRIO_ERR_NO_ASID if allocation | ||
292 | * failed. | ||
293 | */ | ||
294 | extern int gxio_trio_alloc_asids(gxio_trio_context_t *context, | ||
295 | unsigned int count, unsigned int first, | ||
296 | unsigned int flags); | ||
297 | |||
298 | #endif /* ! _GXIO_TRIO_H_ */ | ||