f2169793b849447123db633b6a326c634f96ccc0
[openwrt.git] / target / linux / generic-2.4 / files / crypto / ocf / kirkwood / mvHal / mv_hal / pci-if / pci_util / mvPciUtils.c
1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
3
4 This software file (the "File") is owned and distributed by Marvell
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms. Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
11
12 ********************************************************************************
13 Marvell Commercial License Option
14
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
18
19 ********************************************************************************
20 Marvell GPL License Option
21
22 If you received this File from Marvell, you may opt to use, redistribute and/or
23 modify this File in accordance with the terms and conditions of the General
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25 available along with the File in the license.txt file or by writing to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31 DISCLAIMED. The GPL License provides additional details about this warranty
32 disclaimer.
33 ********************************************************************************
34 Marvell BSD License Option
35
36 If you received this File from Marvell, you may opt to use, redistribute and/or
37 modify this File under the following licensing terms.
38 Redistribution and use in source and binary forms, with or without modification,
39 are permitted provided that the following conditions are met:
40
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
43
44 * Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
47
48 * Neither the name of Marvell nor the names of its contributors may be
49 used to endorse or promote products derived from this software without
50 specific prior written permission.
51
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63 *******************************************************************************/
64
65 /* includes */
66 #include "mvPciUtils.h"
67
68 #include "ctrlEnv/mvCtrlEnvLib.h"
69
70 /* #define MV_DEBUG */
71 /* defines */
72 #ifdef MV_DEBUG
73 #define DB(x) x
74 #define mvOsPrintf printf
75 #else
76 #define DB(x)
77 #endif
78
79 /*
80 This module only support scanning of Header type 00h of pci devices
81 There is no suppotr for Header type 01h of pci devices ( PCI bridges )
82 */
83
84
85 static MV_STATUS pciDetectDevice(MV_U32 pciIf,
86 MV_U32 bus,
87 MV_U32 dev,
88 MV_U32 func,
89 MV_PCI_DEVICE *pPciAgent);
90
91 static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
92 MV_U32 bus,
93 MV_U32 dev,
94 MV_U32 func,
95 MV_PCI_DEVICE *pPciAgent);
96
97
98
99
100
101
102 /*******************************************************************************
103 * mvPciScan - Scan a PCI interface bus
104 *
105 * DESCRIPTION:
106 * Performs a full scan on a PCI interface and returns all possible details
107 * on the agents found on the bus.
108 *
109 * INPUT:
110 * pciIf - PCI Interface
111 * pPciAgents - Pointer to an Array of the pci agents to be detected
112 * pPciAgentsNum - pPciAgents array maximum number of elements
113 *
114 * OUTPUT:
115 * pPciAgents - Array of the pci agents detected on the bus
116 * pPciAgentsNum - Number of pci agents detected on the bus
117 *
118 * RETURN:
119 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
120 *
121 *******************************************************************************/
122
123 MV_STATUS mvPciScan(MV_U32 pciIf,
124 MV_PCI_DEVICE *pPciAgents,
125 MV_U32 *pPciAgentsNum)
126 {
127
128 MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
129 MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
130 MV_PCI_DEVICE *pPciDevice;
131 MV_PCI_DEVICE *pMainDevice;
132
133 DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
134 /* Parameter checking */
135 if (pciIf >= mvCtrlPexMaxIfGet())
136 {
137 DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
138 return MV_BAD_PARAM;
139 }
140 if (NULL == pPciAgents)
141 {
142 DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
143 return MV_BAD_PARAM;
144 }
145 if (NULL == pPciAgentsNum)
146 {
147 DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
148 return MV_BAD_PARAM;
149 }
150
151
152 DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
153 /* Master enable the MV PCI master */
154 if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
155 {
156 DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
157 return MV_ERROR;
158
159 }
160
161 DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
162
163 /* go through all busses */
164 for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
165 {
166 /* go through all possible devices on the local bus */
167 for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
168 {
169 /* always start with function equal to zero */
170 funcIndex=0;
171
172 pPciDevice=&pPciAgents[detectedDevNum];
173 DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
174
175 if (MV_ERROR == pciDetectDevice(pciIf,
176 busIndex,
177 devIndex,
178 funcIndex,
179 pPciDevice))
180 {
181 /* no device detected , try the next address */
182 continue;
183 }
184
185 /* We are here ! means we have detected a device*/
186 /* always we start with only one function per device */
187 pMainDevice = pPciDevice;
188 pPciDevice->funtionsNum = 1;
189
190
191 /* move on */
192 detectedDevNum++;
193
194
195 /* check if we have no more room for a new device */
196 if (detectedDevNum == *pPciAgentsNum)
197 {
198 DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
199 return MV_ERROR;
200 }
201
202 /* check the detected device if it is a multi functional device then
203 scan all device functions*/
204 if (pPciDevice->isMultiFunction == MV_TRUE)
205 {
206 /* start with function number 1 because we have already detected
207 function 0 */
208 for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
209 {
210 pPciDevice=&pPciAgents[detectedDevNum];
211
212 if (MV_ERROR == pciDetectDevice(pciIf,
213 busIndex,
214 devIndex,
215 funcIndex,
216 pPciDevice))
217 {
218 /* no device detected means no more functions !*/
219 continue;
220 }
221 /* We are here ! means we have detected a device */
222
223 /* move on */
224 pMainDevice->funtionsNum++;
225 detectedDevNum++;
226
227 /* check if we have no more room for a new device */
228 if (detectedDevNum == *pPciAgentsNum)
229 {
230 DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
231 return MV_ERROR;
232 }
233
234
235 }
236 }
237
238 }
239
240 }
241
242 /* return the number of devices actually detected on the bus ! */
243 *pPciAgentsNum = detectedDevNum;
244
245 return MV_OK;
246
247 }
248
249
250 /*******************************************************************************
251 * pciDetectDevice - Detect a pci device parameters
252 *
253 * DESCRIPTION:
254 * This function detect if a pci agent exist on certain address !
255 * and if exists then it fills all possible information on the
256 * agent
257 *
258 * INPUT:
259 * pciIf - PCI Interface
260 * bus - Bus number
261 * dev - Device number
262 * func - Function number
263 *
264 *
265 *
266 * OUTPUT:
267 * pPciAgent - pointer to the pci agent filled with its information
268 *
269 * RETURN:
270 * MV_ERROR if no device , MV_OK otherwise
271 *
272 *******************************************************************************/
273
274 static MV_STATUS pciDetectDevice(MV_U32 pciIf,
275 MV_U32 bus,
276 MV_U32 dev,
277 MV_U32 func,
278 MV_PCI_DEVICE *pPciAgent)
279 {
280 MV_U32 pciData;
281
282 /* no Parameters checking ! because it is static function and it is assumed
283 that all parameters were checked in the calling function */
284
285
286 /* Try read the PCI Vendor ID and Device ID */
287
288 /* We will scan only ourselves and the PCI slots that exist on the
289 board, because we may have a case that we have one slot that has
290 a Cardbus connector, and because CardBus answers all IDsels we want
291 to scan only this slot and ourseleves.
292
293 */
294 #if defined(MV_INCLUDE_PCI)
295 if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
296 (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
297 (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
298 (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
299 {
300
301 if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
302 {
303 return MV_ERROR;
304 }
305 }
306 #endif /* defined(MV_INCLUDE_PCI) */
307
308 pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
309
310 if (PCI_ERROR_CODE == pciData)
311 {
312 /* no device exist */
313 return MV_ERROR;
314 }
315
316 /* we are here ! means a device is detected */
317
318 /* fill basic information */
319 pPciAgent->busNumber=bus;
320 pPciAgent->deviceNum=dev;
321 pPciAgent->function=func;
322
323 /* Fill the PCI Vendor ID and Device ID */
324
325 pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
326 pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
327
328 /* Read Status and command */
329 pciData = mvPciIfConfigRead(pciIf,
330 bus,dev,func,
331 PCI_STATUS_AND_COMMAND);
332
333
334 /* Fill related Status and Command information*/
335
336 if (pciData & PSCR_TAR_FAST_BB)
337 {
338 pPciAgent->isFastB2BCapable = MV_TRUE;
339 }
340 else
341 {
342 pPciAgent->isFastB2BCapable = MV_FALSE;
343 }
344
345 if (pciData & PSCR_CAP_LIST)
346 {
347 pPciAgent->isCapListSupport=MV_TRUE;
348 }
349 else
350 {
351 pPciAgent->isCapListSupport=MV_FALSE;
352 }
353
354 if (pciData & PSCR_66MHZ_EN)
355 {
356 pPciAgent->is66MHZCapable=MV_TRUE;
357 }
358 else
359 {
360 pPciAgent->is66MHZCapable=MV_FALSE;
361 }
362
363 /* Read Class Code and Revision */
364 pciData = mvPciIfConfigRead(pciIf,
365 bus,dev,func,
366 PCI_CLASS_CODE_AND_REVISION_ID);
367
368
369 pPciAgent->baseClassCode =
370 (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
371
372 pPciAgent->subClassCode =
373 (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
374
375 pPciAgent->progIf =
376 (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
377
378 pPciAgent->revisionID =
379 (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
380
381 /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
382 pciData = mvPciIfConfigRead(pciIf,
383 bus,dev,func,
384 PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
385
386
387
388 pPciAgent->pciCacheLine=
389 (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
390 pPciAgent->pciLatencyTimer=
391 (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
392
393 switch (pciData & PBHTLTCLR_HEADER_MASK)
394 {
395 case PBHTLTCLR_HEADER_STANDARD:
396
397 pPciAgent->pciHeader=MV_PCI_STANDARD;
398 break;
399 case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
400
401 pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
402 break;
403
404 }
405
406 if (pciData & PBHTLTCLR_MULTI_FUNC)
407 {
408 pPciAgent->isMultiFunction=MV_TRUE;
409 }
410 else
411 {
412 pPciAgent->isMultiFunction=MV_FALSE;
413 }
414
415 if (pciData & PBHTLTCLR_BISTCAP)
416 {
417 pPciAgent->isBISTCapable=MV_TRUE;
418 }
419 else
420 {
421 pPciAgent->isBISTCapable=MV_FALSE;
422 }
423
424
425 /* read this device pci bars */
426
427 pciDetectDeviceBars(pciIf,
428 bus,dev,func,
429 pPciAgent);
430
431
432 /* check if we are bridge*/
433 if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
434 (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
435 {
436
437 /* Read P2P_BUSSES_NUM */
438 pciData = mvPciIfConfigRead(pciIf,
439 bus,dev,func,
440 P2P_BUSSES_NUM);
441
442 pPciAgent->p2pPrimBusNum =
443 (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
444
445 pPciAgent->p2pSecBusNum =
446 (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
447
448 pPciAgent->p2pSubBusNum =
449 (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
450
451 pPciAgent->p2pSecLatencyTimer =
452 (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
453
454 /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
455 pciData = mvPciIfConfigRead(pciIf,
456 bus,dev,func,
457 P2P_IO_BASE_LIMIT_SEC_STATUS);
458
459 pPciAgent->p2pSecStatus =
460 (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
461
462
463 pPciAgent->p2pIObase =
464 (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
465
466 /* clear low address (should be zero)*/
467 pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
468
469 pPciAgent->p2pIOLimit =
470 (pciData & PIBLSS_IO_LIMIT_MASK);
471
472 /* fill low address with 0xfff */
473 pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
474
475
476 switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
477 {
478 case PIBLSS_ADD_CAP_16BIT:
479
480 pPciAgent->bIO32 = MV_FALSE;
481
482 break;
483 case PIBLSS_ADD_CAP_32BIT:
484
485 pPciAgent->bIO32 = MV_TRUE;
486
487 /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
488 pciData = mvPciIfConfigRead(pciIf,
489 bus,dev,func,
490 P2P_IO_BASE_LIMIT_UPPER_16);
491
492 pPciAgent->p2pIObase |=
493 (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
494
495
496 pPciAgent->p2pIOLimit |=
497 (pciData & PRBU_IO_UPP_LIMIT_MASK);
498
499 break;
500
501 }
502
503
504 /* Read P2P_MEM_BASE_LIMIT */
505 pciData = mvPciIfConfigRead(pciIf,
506 bus,dev,func,
507 P2P_MEM_BASE_LIMIT);
508
509 pPciAgent->p2pMemBase =
510 (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
511
512 /* clear low address */
513 pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
514
515 pPciAgent->p2pMemLimit =
516 (pciData & PMBL_MEM_LIMIT_MASK);
517
518 /* add 0xfffff */
519 pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
520
521
522 /* Read P2P_PREF_MEM_BASE_LIMIT */
523 pciData = mvPciIfConfigRead(pciIf,
524 bus,dev,func,
525 P2P_PREF_MEM_BASE_LIMIT);
526
527
528 pPciAgent->p2pPrefMemBase =
529 (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
530
531 /* get high address only */
532 pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
533
534
535
536 pPciAgent->p2pPrefMemLimit =
537 (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
538
539 /* add 0xfffff */
540 pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
541
542 switch (pciData & PRMBL_ADD_CAP_MASK)
543 {
544 case PRMBL_ADD_CAP_32BIT:
545
546 pPciAgent->bPrefMem64 = MV_FALSE;
547
548 /* Read P2P_PREF_BASE_UPPER_32 */
549 pPciAgent->p2pPrefBaseUpper32Bits = 0;
550
551 /* Read P2P_PREF_LIMIT_UPPER_32 */
552 pPciAgent->p2pPrefLimitUpper32Bits = 0;
553
554 break;
555 case PRMBL_ADD_CAP_64BIT:
556
557 pPciAgent->bPrefMem64 = MV_TRUE;
558
559 /* Read P2P_PREF_BASE_UPPER_32 */
560 pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
561 bus,dev,func,
562 P2P_PREF_BASE_UPPER_32);
563
564 /* Read P2P_PREF_LIMIT_UPPER_32 */
565 pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
566 bus,dev,func,
567 P2P_PREF_LIMIT_UPPER_32);
568
569 break;
570
571 }
572
573 }
574 else /* no bridge */
575 {
576 /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
577 pciData = mvPciIfConfigRead(pciIf,
578 bus,dev,func,
579 PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
580
581
582 pPciAgent->subSysVenID =
583 (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
584 pPciAgent->subSysID =
585 (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
586
587
588 /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
589 pciData = mvPciIfConfigRead(pciIf,
590 bus,dev,func,
591 PCI_EXPANSION_ROM_BASE_ADDR_REG);
592
593
594 if (pciData & PERBAR_EXPROMEN)
595 {
596 pPciAgent->isExpRom = MV_TRUE;
597 }
598 else
599 {
600 pPciAgent->isExpRom = MV_FALSE;
601 }
602
603 pPciAgent->expRomAddr =
604 (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
605
606 }
607
608
609 if (MV_TRUE == pPciAgent->isCapListSupport)
610 {
611 /* Read PCI_CAPABILTY_LIST_POINTER */
612 pciData = mvPciIfConfigRead(pciIf,
613 bus,dev,func,
614 PCI_CAPABILTY_LIST_POINTER);
615
616 pPciAgent->capListPointer =
617 (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
618
619 }
620
621 /* Read PCI_INTERRUPT_PIN_AND_LINE */
622 pciData = mvPciIfConfigRead(pciIf,
623 bus,dev,func,
624 PCI_INTERRUPT_PIN_AND_LINE);
625
626
627 pPciAgent->irqLine=
628 (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
629
630 pPciAgent->intPin=
631 (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
632
633 pPciAgent->minGrant=
634 (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
635 pPciAgent->maxLatency=
636 (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
637
638 mvPciClassNameGet(pPciAgent->baseClassCode,
639 (MV_8 *)pPciAgent->type);
640
641 return MV_OK;
642
643
644 }
645
646 /*******************************************************************************
647 * pciDetectDeviceBars - Detect a pci device bars
648 *
649 * DESCRIPTION:
650 * This function detects all pci agent bars
651 *
652 * INPUT:
653 * pciIf - PCI Interface
654 * bus - Bus number
655 * dev - Device number
656 * func - Function number
657 *
658 *
659 *
660 * OUTPUT:
661 * pPciAgent - pointer to the pci agent filled with its information
662 *
663 * RETURN:
664 * detected bars number
665 *
666 *******************************************************************************/
667 static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
668 MV_U32 bus,
669 MV_U32 dev,
670 MV_U32 func,
671 MV_PCI_DEVICE *pPciAgent)
672 {
673 MV_U32 pciData,barIndex,detectedBar=0;
674 MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
675 MV_U32 pciMaxBars=0;
676
677 pPciAgent->barsNum=0;
678
679 /* check if we are bridge*/
680 if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
681 (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
682 {
683 pciMaxBars = 2;
684 }
685 else /* no bridge */
686 {
687 pciMaxBars = 6;
688 }
689
690 /* read this device pci bars */
691 for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
692 {
693 /* Read PCI_MEMORY_BAR_BASE_ADDR */
694 tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
695 bus,dev,func,
696 PCI_MEMORY_BAR_BASE_ADDR(barIndex));
697
698 pPciAgent->pciBar[detectedBar].barOffset =
699 PCI_MEMORY_BAR_BASE_ADDR(barIndex);
700
701 /* check if the bar is 32bit or 64bit bar */
702 switch (pciData & PBBLR_TYPE_MASK)
703 {
704 case PBBLR_TYPE_32BIT_ADDR:
705 pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
706 break;
707 case PBBLR_TYPE_64BIT_ADDR:
708 pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
709 break;
710
711 }
712
713 /* check if it is memory or IO bar */
714 if (pciData & PBBLR_IOSPACE)
715 {
716 pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
717 }
718 else
719 {
720 pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
721 }
722
723 /* if it is memory bar then check if it is prefetchable */
724 if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
725 {
726 if (pciData & PBBLR_PREFETCH_EN)
727 {
728 pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
729 }
730 else
731 {
732 pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
733 }
734
735 pPciAgent->pciBar[detectedBar].barBaseLow =
736 pciData & PBBLR_MEM_BASE_MASK;
737
738
739 }
740 else /* IO Bar */
741 {
742 pPciAgent->pciBar[detectedBar].barBaseLow =
743 pciData & PBBLR_IO_BASE_MASK;
744
745 }
746
747 pPciAgent->pciBar[detectedBar].barBaseHigh=0;
748
749 if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
750 {
751 barIndex++;
752
753 tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
754 mvPciIfConfigRead(pciIf,
755 bus,dev,func,
756 PCI_MEMORY_BAR_BASE_ADDR(barIndex));
757
758
759 }
760
761 /* calculating full base address (64bit) */
762 pPciAgent->pciBar[detectedBar].barBaseAddr =
763 (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
764
765 pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
766
767 pPciAgent->pciBar[detectedBar].barBaseAddr |=
768 (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
769
770
771
772 /* get the sizes of the the bar */
773
774 pPciAgent->pciBar[detectedBar].barSizeHigh=0;
775
776 if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
777 (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
778
779 {
780 /* write oxffffffff to the bar to get the size */
781 /* start with sizelow ( original value was saved in tmpBaseLow ) */
782 mvPciIfConfigWrite(pciIf,
783 bus,dev,func,
784 PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
785 0xffffffff);
786
787 /* read size */
788 pPciAgent->pciBar[detectedBar].barSizeLow =
789 mvPciIfConfigRead(pciIf,
790 bus,dev,func,
791 PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
792
793
794
795 /* restore original value */
796 mvPciIfConfigWrite(pciIf,
797 bus,dev,func,
798 PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
799 tmpBaseLow);
800
801
802 /* now do the same for BaseHigh */
803
804 /* write oxffffffff to the bar to get the size */
805 mvPciIfConfigWrite(pciIf,
806 bus,dev,func,
807 PCI_MEMORY_BAR_BASE_ADDR(barIndex),
808 0xffffffff);
809
810 /* read size */
811 pPciAgent->pciBar[detectedBar].barSizeHigh =
812 mvPciIfConfigRead(pciIf,
813 bus,dev,func,
814 PCI_MEMORY_BAR_BASE_ADDR(barIndex));
815
816 /* restore original value */
817 mvPciIfConfigWrite(pciIf,
818 bus,dev,func,
819 PCI_MEMORY_BAR_BASE_ADDR(barIndex),
820 tmpBaseHigh);
821
822 if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
823 (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
824 {
825 /* this bar is not applicable for this device,
826 ignore all previous settings and check the next bar*/
827
828 /* we though this was a 64bit bar , and it seems this
829 was wrong ! so decrement barIndex */
830 barIndex--;
831 continue;
832 }
833
834 /* calculate the full 64 bit size */
835
836 if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
837 {
838 pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
839
840 pPciAgent->pciBar[detectedBar].barSizeLow =
841 ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
842
843 pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
844
845 }
846 else
847 {
848
849 pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
850
851 pPciAgent->pciBar[detectedBar].barSizeLow =
852 ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
853
854 pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
855
856 }
857
858
859
860 }
861 else /* 32bit bar */
862 {
863 /* write oxffffffff to the bar to get the size */
864 mvPciIfConfigWrite(pciIf,
865 bus,dev,func,
866 PCI_MEMORY_BAR_BASE_ADDR(barIndex),
867 0xffffffff);
868
869 /* read size */
870 pPciAgent->pciBar[detectedBar].barSizeLow =
871 mvPciIfConfigRead(pciIf,
872 bus,dev,func,
873 PCI_MEMORY_BAR_BASE_ADDR(barIndex));
874
875 if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
876 {
877 /* this bar is not applicable for this device,
878 ignore all previous settings and check the next bar*/
879 continue;
880 }
881
882
883 /* restore original value */
884 mvPciIfConfigWrite(pciIf,
885 bus,dev,func,
886 PCI_MEMORY_BAR_BASE_ADDR(barIndex),
887 tmpBaseLow);
888
889 /* calculate size low */
890
891 if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
892 {
893 pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
894 }
895 else
896 {
897 pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
898 }
899
900 pPciAgent->pciBar[detectedBar].barSizeLow =
901 ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
902
903 pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
904 pPciAgent->pciBar[detectedBar].barSize =
905 (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
906
907
908 }
909
910 /* we are here ! this means we have already detected a bar for
911 this device , now move on */
912
913 detectedBar++;
914 pPciAgent->barsNum++;
915 }
916
917 return detectedBar;
918 }
919
920
921 /*******************************************************************************
922 * mvPciClassNameGet - get PCI class name
923 *
924 * DESCRIPTION:
925 * This function returns the PCI class name
926 *
927 * INPUT:
928 * baseClassCode - Base Class Code.
929 *
930 * OUTPUT:
931 * pType - the class name
932 *
933 * RETURN:
934 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
935 *
936 *******************************************************************************/
937 MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
938 {
939
940 switch(baseClassCode)
941 {
942 case 0x0:
943 strcpy(pType,"Old generation device");
944 break;
945 case 0x1:
946 strcpy(pType,"Mass storage controller");
947 break;
948 case 0x2:
949 strcpy(pType,"Network controller");
950 break;
951 case 0x3:
952 strcpy(pType,"Display controller");
953 break;
954 case 0x4:
955 strcpy(pType,"Multimedia device");
956 break;
957 case 0x5:
958 strcpy(pType,"Memory controller");
959 break;
960 case 0x6:
961 strcpy(pType,"Bridge Device");
962 break;
963 case 0x7:
964 strcpy(pType,"Simple Communication controllers");
965 break;
966 case 0x8:
967 strcpy(pType,"Base system peripherals");
968 break;
969 case 0x9:
970 strcpy(pType,"Input Devices");
971 break;
972 case 0xa:
973 strcpy(pType,"Docking stations");
974 break;
975 case 0xb:
976 strcpy(pType,"Processors");
977 break;
978 case 0xc:
979 strcpy(pType,"Serial bus controllers");
980 break;
981 case 0xd:
982 strcpy(pType,"Wireless controllers");
983 break;
984 case 0xe:
985 strcpy(pType,"Intelligent I/O controllers");
986 break;
987 case 0xf:
988 strcpy(pType,"Satellite communication controllers");
989 break;
990 case 0x10:
991 strcpy(pType,"Encryption/Decryption controllers");
992 break;
993 case 0x11:
994 strcpy(pType,"Data acquisition and signal processing controllers");
995 break;
996 default:
997 strcpy(pType,"Unknown device");
998 break;
999 }
1000
1001 return MV_OK;
1002
1003 }
1004
1005
1006
This page took 0.10422 seconds and 3 git commands to generate.