remove linux 2.4 specific build system code
[15.05/openwrt.git] / target / linux / generic-2.6 / 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