1 /*\r
2 *\r
3 * Copyright (C) 2010-2016 Texas Instruments Incorporated - http://www.ti.com/ \r
4 * \r
5 * \r
6 * Redistribution and use in source and binary forms, with or without \r
7 * modification, are permitted provided that the following conditions \r
8 * are met:\r
9 *\r
10 * Redistributions of source code must retain the above copyright \r
11 * notice, this list of conditions and the following disclaimer.\r
12 *\r
13 * Redistributions in binary form must reproduce the above copyright\r
14 * notice, this list of conditions and the following disclaimer in the \r
15 * documentation and/or other materials provided with the \r
16 * distribution.\r
17 *\r
18 * Neither the name of Texas Instruments Incorporated nor the names of\r
19 * its contributors may be used to endorse or promote products derived\r
20 * from this software without specific prior written permission.\r
21 *\r
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
33 *\r
34 */\r
35 \r
36 /*\r
37 * File Name: pcie.c\r
38 *\r
39 * Processing/configuration functions for the PCIe driver.\r
40 *\r
41 */\r
42 \r
43 #include <ti/drv/pcie/pcie.h>\r
44 #include <ti/drv/pcie/src/pcieloc.h>\r
45 \r
46 #include <string.h>\r
47 \r
48 /* Global Variable which describes the PCIE LLD Version Information */\r
49 const char PCIELLDVersionStr[] = pcie_LLD_VERSION_STR ":" __DATE__ ":" __TIME__;\r
50 \r
51 /*****************************************************************************\r
52 * check if handle is valid\r
53 ****************************************************************************/\r
54 int32_t pcie_check_handle_fcn (Pcie_Handle handle)\r
55 {\r
56 int32_t i;\r
57 int32_t ret_val = 0;\r
58 if (handle) {\r
59 for (i = 0; i < pcie_MAX_PERIPHS; i++) {\r
60 if (handle == &pcieLObj.insts[i]) {\r
61 ret_val = 1;\r
62 break;\r
63 }\r
64 }\r
65 }\r
66 return ret_val;\r
67 } /* pcie_check_handle_fcn */\r
68 \r
69 \r
70 /*****************************************************************************\r
71 * Convert the handle (which is a configuration base address) into\r
72 * associated Pcie_DeviceCfgBaseAddr\r
73 ****************************************************************************/\r
74 Pcie_DeviceCfgBaseAddr *pcie_handle_to_cfg (Pcie_Handle handle)\r
75 {\r
76 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
77 \r
78 return &h->bases;\r
79 } /* pcie_handle_to_cfg */\r
80 \r
81 \r
82 /*****************************************************************************\r
83 ********** External APIs **********************\r
84 ****************************************************************************/\r
85 \r
86 /*********************************************************************\r
87 * FUNCTION PURPOSE: Sets PCIe mode to RC or EP for interface\r
88 * specified by handle\r
89 *********************************************************************/\r
90 pcieRet_e Pcie_setInterfaceMode\r
91 (\r
92 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
93 pcieMode_e mode /**< [in] PCIE Mode */\r
94 )\r
95 {\r
96 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
97 pcieRet_e ret_val;\r
98 if (h == 0)\r
99 {\r
100 ret_val = pcie_RET_INV_HANDLE;\r
101 }\r
102 else\r
103 {\r
104 if ((h->fxnTable.setInterfaceMode) == 0)\r
105 {\r
106 ret_val = pcie_RET_INV_FXNPTR;\r
107 }\r
108 else\r
109 {\r
110 ret_val = h->fxnTable.setInterfaceMode (handle, mode);\r
111 }\r
112 }\r
113 return ret_val;\r
114 } /* Pcie_setInterfaceMode */\r
115 \r
116 \r
117 /*********************************************************************\r
118 * FUNCTION PURPOSE: Returns amount of reserved space between beginning\r
119 * of hardware's data area and the base returned\r
120 * by @ref Pcie_getMemSpaceRange. This enables\r
121 * sw to position windows correctly\r
122 *********************************************************************/\r
123 pcieRet_e Pcie_getMemSpaceReserved \r
124 (\r
125 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
126 uint32_t *resSize /**< [out] Reserved space */\r
127 )\r
128 {\r
129 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
130 pcieRet_e ret_val;\r
131 if (h == 0)\r
132 {\r
133 ret_val = pcie_RET_INV_HANDLE;\r
134 }\r
135 else\r
136 {\r
137 if ((h->fxnTable.getMemSpaceReserved) == 0)\r
138 {\r
139 ret_val = pcie_RET_INV_FXNPTR;\r
140 }\r
141 else\r
142 {\r
143 ret_val = h->fxnTable.getMemSpaceReserved (handle, resSize);\r
144 }\r
145 }\r
146 return ret_val;\r
147 } /* Pcie_getMemSpaceReserved */\r
148 \r
149 \r
150 /*********************************************************************\r
151 * FUNCTION PURPOSE: Returns the PCIe Internal Address Range for the \r
152 * Memory Space. This range is used for accessing memory.\r
153 *********************************************************************/\r
154 pcieRet_e Pcie_getMemSpaceRange \r
155 (\r
156 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
157 void **base, /**< [out] Memory Space base address */\r
158 uint32_t *size /**< [out] Memory Space total size */\r
159 )\r
160 {\r
161 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
162 pcieRet_e ret_val;\r
163 if (h == 0)\r
164 {\r
165 ret_val = pcie_RET_INV_HANDLE;\r
166 }\r
167 else\r
168 {\r
169 if ((h->fxnTable.getMemSpaceRange) == 0)\r
170 {\r
171 ret_val = pcie_RET_INV_FXNPTR;\r
172 }\r
173 else\r
174 {\r
175 ret_val = h->fxnTable.getMemSpaceRange (handle, base, size);\r
176 }\r
177 }\r
178 return ret_val;\r
179 } /* Pcie_getMemSpaceRange */\r
180 \r
181 /*********************************************************************\r
182 * FUNCTION PURPOSE: Reads any register\r
183 ********************************************************************/\r
184 pcieRet_e Pcie_readRegs \r
185 (\r
186 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
187 pcieLocation_e location, /**< [in] Local or remote peripheral */\r
188 pcieRegisters_t *readRegs /**< [in/out] List of registers to read */\r
189 )\r
190 {\r
191 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
192 pcieRet_e ret_val;\r
193 if (h == 0)\r
194 {\r
195 ret_val = pcie_RET_INV_HANDLE;\r
196 }\r
197 else\r
198 {\r
199 if ((h->fxnTable.readRegs) == 0)\r
200 {\r
201 ret_val = pcie_RET_INV_FXNPTR;\r
202 }\r
203 else\r
204 {\r
205 ret_val = h->fxnTable.readRegs (handle, location, readRegs);\r
206 }\r
207 }\r
208 return ret_val;\r
209 } /* Pcie_readRegs */\r
210 \r
211 \r
212 /*********************************************************************\r
213 * FUNCTION PURPOSE: Writes any register\r
214 ********************************************************************/\r
215 pcieRet_e Pcie_writeRegs \r
216 (\r
217 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
218 pcieLocation_e location, /**< [in] Local or remote peripheral */\r
219 pcieRegisters_t *writeRegs /**< [in] List of registers to write */\r
220 )\r
221 {\r
222 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
223 pcieRet_e ret_val;\r
224 if (h == 0)\r
225 {\r
226 ret_val = pcie_RET_INV_HANDLE;\r
227 }\r
228 else\r
229 {\r
230 if ((h->fxnTable.writeRegs) == 0)\r
231 {\r
232 ret_val = pcie_RET_INV_FXNPTR;\r
233 }\r
234 else\r
235 {\r
236 ret_val = h->fxnTable.writeRegs (handle, location, writeRegs);\r
237 }\r
238 }\r
239 return ret_val;\r
240 } /* Pcie_writeRegs */\r
241 \r
242 \r
243 /*********************************************************************\r
244 * FUNCTION PURPOSE: Configures the Outbound Offset registers \r
245 * for outbound address translation\r
246 ********************************************************************/\r
247 pcieRet_e Pcie_cfgObOffset \r
248 (\r
249 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
250 uint32_t obAddrLo, /**< [in] Low Outbound address offset (32bits) */\r
251 uint32_t obAddrHi, /**< [in] High Outbound address offset (32bits) */\r
252 uint8_t region /**< [in] Identifies the Outbound region (0-31) */\r
253 )\r
254 {\r
255 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
256 pcieRet_e ret_val;\r
257 if (h == 0)\r
258 {\r
259 ret_val = pcie_RET_INV_HANDLE;\r
260 }\r
261 else\r
262 {\r
263 if ((h->fxnTable.cfgObOffset) == 0)\r
264 {\r
265 ret_val = pcie_RET_INV_FXNPTR;\r
266 }\r
267 else\r
268 {\r
269 ret_val = h->fxnTable.cfgObOffset (handle, obAddrLo, obAddrHi, region);\r
270 }\r
271 }\r
272 return ret_val;\r
273 } /* Pcie_cfgObOffset */\r
274 \r
275 \r
276 /*********************************************************************\r
277 * FUNCTION PURPOSE: Configures the Inbound Translation registers \r
278 ********************************************************************/\r
279 pcieRet_e Pcie_cfgIbTrans \r
280 (\r
281 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
282 const pcieIbTransCfg_t *ibCfg /**< [in] Inbound Translation Configuration parameters */\r
283 )\r
284 {\r
285 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
286 pcieRet_e ret_val;\r
287 if (h == 0)\r
288 {\r
289 ret_val = pcie_RET_INV_HANDLE;\r
290 }\r
291 else\r
292 {\r
293 if ((h->fxnTable.cfgIbTrans) == 0)\r
294 {\r
295 ret_val = pcie_RET_INV_FXNPTR;\r
296 }\r
297 else\r
298 {\r
299 ret_val = h->fxnTable.cfgIbTrans (handle, ibCfg);\r
300 }\r
301 }\r
302 return ret_val;\r
303 } /* Pcie_cfgIbTrans */\r
304 \r
305 \r
306 /*********************************************************************\r
307 * FUNCTION PURPOSE: Configures a BAR Register (32bits)\r
308 ********************************************************************/\r
309 pcieRet_e Pcie_cfgBar \r
310 (\r
311 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
312 const pcieBarCfg_t *barCfg /**< [in] BAR configuration parameters */\r
313 )\r
314 {\r
315 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
316 pcieRet_e ret_val;\r
317 if (h == 0)\r
318 {\r
319 ret_val = pcie_RET_INV_HANDLE;\r
320 }\r
321 else\r
322 {\r
323 if ((h->fxnTable.cfgBar) == 0)\r
324 {\r
325 ret_val = pcie_RET_INV_FXNPTR;\r
326 }\r
327 else\r
328 {\r
329 ret_val = h->fxnTable.cfgBar (handle, barCfg);\r
330 }\r
331 }\r
332 return ret_val;\r
333 } /* Pcie_cfgBar */\r
334 \r
335 \r
336 /*********************************************************************\r
337 * FUNCTION PURPOSE: Configures the ATU (address translation) unit\r
338 ********************************************************************/\r
339 pcieRet_e Pcie_atuRegionConfig \r
340 (\r
341 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
342 pcieLocation_e location, /**< [in] local/remote */\r
343 uint32_t atuRegionIndex, /* [in] index number to configure */\r
344 const pcieAtuRegionParams_t *atuRegionParams /* [in] config structure */\r
345 )\r
346 {\r
347 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
348 pcieRet_e ret_val;\r
349 if (h == 0)\r
350 {\r
351 ret_val = pcie_RET_INV_HANDLE;\r
352 }\r
353 else\r
354 {\r
355 if ((h->fxnTable.cfgAtu) == 0)\r
356 {\r
357 ret_val = pcie_RET_INV_FXNPTR;\r
358 }\r
359 else\r
360 {\r
361 ret_val = h->fxnTable.cfgAtu (handle, location, atuRegionIndex, atuRegionParams);\r
362 }\r
363 }\r
364 return ret_val;\r
365 } /* Pcie_atuRegionConfig */\r
366 \r
367 \r
368 /*********************************************************************\r
369 * FUNCTION PURPOSE: Read which functional (MSI/INTX) interrupts are pending\r
370 ********************************************************************/\r
371 pcieRet_e Pcie_getPendingFuncInts \r
372 (\r
373 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
374 void *pendingBits,/**< [out] revision specific interrupt spec */\r
375 int32_t sizeMsiBits,/**< [in] size of msiBits in MAU */\r
376 void *msiBits /**< [out] rev-specific msi pending bits to check */\r
377 )\r
378 {\r
379 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
380 pcieRet_e ret_val;\r
381 if (h == 0)\r
382 {\r
383 ret_val = pcie_RET_INV_HANDLE;\r
384 }\r
385 else\r
386 {\r
387 if ((h->fxnTable.getPendingFuncInts) == 0)\r
388 {\r
389 ret_val = pcie_RET_INV_FXNPTR;\r
390 }\r
391 else\r
392 {\r
393 ret_val = h->fxnTable.getPendingFuncInts (handle, pendingBits, \r
394 sizeMsiBits, msiBits);\r
395 }\r
396 }\r
397 return ret_val;\r
398 } /* Pcie_getPendingFuncInts */\r
399 \r
400 \r
401 /*********************************************************************\r
402 * FUNCTION PURPOSE: Clear specified pending functional (MSI/INTX) interrupts\r
403 ********************************************************************/\r
404 pcieRet_e Pcie_clrPendingFuncInts \r
405 (\r
406 Pcie_Handle handle, /**< [in] The PCIE LLD instance identifier */\r
407 void *pendingBits,/**< [in] revision specific interrupt spec */\r
408 int32_t sizeMsiBits,/**< [in] size of msiBits in MAU */\r
409 void *msiBits /**< [in] rev-specific msi pending bits to ack */\r
410 )\r
411 {\r
412 Pcie_IntHandle h = (Pcie_IntHandle)handle;\r
413 pcieRet_e ret_val;\r
414 if (h == 0)\r
415 {\r
416 ret_val = pcie_RET_INV_HANDLE;\r
417 }\r
418 else\r
419 {\r
420 if ((h->fxnTable.clrPendingFuncInts) == 0)\r
421 {\r
422 ret_val = pcie_RET_INV_FXNPTR;\r
423 }\r
424 else\r
425 {\r
426 ret_val = h->fxnTable.clrPendingFuncInts (handle, pendingBits, \r
427 sizeMsiBits, msiBits);\r
428 }\r
429 }\r
430 return ret_val;\r
431 } /* Pcie_clrPendingFuncInts */\r
432 \r
433 \r
434 /*********************************************************************\r
435 * FUNCTION PURPOSE: Returns version number\r
436 ********************************************************************/\r
437 uint32_t Pcie_getVersion \r
438 (\r
439 void\r
440 )\r
441 {\r
442 return pcie_LLD_VERSION_ID;\r
443 } /* Pcie_getVersion */\r
444 \r
445 /*********************************************************************\r
446 * FUNCTION PURPOSE: Returns version string\r
447 ********************************************************************/\r
448 const char* Pcie_getVersionStr\r
449 (\r
450 void\r
451 )\r
452 {\r
453 return PCIELLDVersionStr;\r
454 } /* Pcie_getVersionStr */\r
455 \r
456 /* Nothing past this point */\r
457 \r