1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
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.
12 ********************************************************************************
13 Marvell Commercial License Option
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.
19 ********************************************************************************
20 Marvell GPL License Option
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.
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
33 ********************************************************************************
34 Marvell BSD License Option
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:
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
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.
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.
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.
63 *******************************************************************************/
65 #include "ctrlEnv/sys/mvSysPex.h"
67 /* this structure describes the mapping between a Pex Window and a CPU target*/
68 typedef struct _pexWinToTarget
75 /* this array is a priority array that define How Pex windows should be
76 configured , We have only 6 Pex Windows that can be configured , but we
77 have maximum of 9 CPU target windows ! the following array is a priority
78 array where the lowest index has the highest priotiy and the highest
79 index has the lowest priority of being cnfigured */
81 MV_U32 pexDevBarPrioTable[] =
83 #if defined(MV_INCLUDE_DEVICE_CS0)
86 #if defined(MV_INCLUDE_DEVICE_CS1)
89 #if defined(MV_INCLUDE_DEVICE_CS2)
92 #if defined(MV_INCLUDE_DEVICE_CS3)
96 #if defined(MV_INCLUDE_DEVICE_CS4)
104 /* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
105 /* register offsets and its function where its is located. */
106 /* Also, PEX address remap registers offsets are inconsecutive. This struct */
107 /* describes address remap register offsets */
108 typedef struct _pexWinRegInfo
110 MV_U32 baseLowRegOffs;
111 MV_U32 baseHighRegOffs;
113 MV_U32 remapLowRegOffs;
114 MV_U32 remapHighRegOffs;
118 static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
119 MV_ADDR_WIN *pAddrWin);
120 static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
121 PEX_WIN_REG_INFO *pWinRegInfo);
123 static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
125 static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
126 static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
127 MV_ADDR_WIN *pAddrWin);
128 const MV_8* pexBarNameGet( MV_U32 bar );
131 /*******************************************************************************
132 * mvPexInit - Initialize PEX interfaces
136 * This function is responsible of intialization of the Pex Interface , It
137 * configure the Pex Bars and Windows in the following manner:
140 * Bar0 is always internal registers bar
141 * Bar1 is always the DRAM bar
142 * Bar2 is always the Device bar
144 * 1) Sets the Internal registers bar base by obtaining the base from
146 * 2) Sets the DRAM bar base and size by getting the base and size from
147 * the CPU Interface when the size is the sum of all enabled DRAM
148 * chip selects and the base is the base of CS0 .
149 * 3) Sets the Device bar base and size by getting these values from the
150 * CPU Interface when the base is the base of the lowest base of the
151 * Device chip selects, and the
156 * pexIf - PEX interface number.
163 * MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
165 *******************************************************************************/
166 MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
171 MV_PEX_DEC_WIN pexWin;
172 MV_CPU_DEC_WIN addrDecWin;
176 /* default and exapntion rom
177 are always configured */
179 #ifndef MV_DISABLE_PEX_DEVICE_BAR
181 MV_U32 maxBase=0, sizeOfMaxBase=0;
182 MV_U32 pexStartWindow;
185 /* Parameter checking */
186 if(pexIf >= mvCtrlPexMaxIfGet())
188 mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
192 /* Enabled CPU access to PCI-Express */
193 mvCpuIfEnablePex(pexIf, pexType);
195 /* Start with bars */
196 /* First disable all PEX bars*/
197 for (bar = 0; bar < PEX_MAX_BARS; bar++)
199 if (PEX_INTER_REGS_BAR != bar)
201 if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
203 mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
211 /* and disable all PEX target windows */
212 for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
214 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
216 mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
223 /* Now, go through all bars*/
227 /******************************************************************************/
228 /* Internal registers bar */
229 /******************************************************************************/
230 bar = PEX_INTER_REGS_BAR;
232 /* we only open the bar , no need to open windows for this bar */
234 /* first get the CS attribute from the CPU Interface */
235 if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
237 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
241 pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
242 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
243 pexBar.addrWin.size = addrDecWin.addrWin.size;
244 pexBar.enable = MV_TRUE;
246 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
248 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
252 /******************************************************************************/
254 /******************************************************************************/
258 pexBar.addrWin.size = 0;
260 for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
263 status = mvCpuIfTargetWinGet(target,&addrDecWin);
265 if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
270 /* first get attributes from CPU If */
273 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
276 if (addrDecWin.enable == MV_TRUE)
278 /* the base is the base of DRAM CS0 always */
279 if (SDRAM_CS0 == target )
281 pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
282 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
286 /* increment the bar size to be the sum of the size of all
288 pexBar.addrWin.size += addrDecWin.addrWin.size;
290 /* set a Pex window for this target !
291 DRAM CS always will have a Pex Window , and is not a
292 part of the priority table */
293 pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
294 pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
295 pexWin.addrWin.size = addrDecWin.addrWin.size;
297 /* we disable the windows at first because we are not
298 sure that it is witihin bar boundries */
299 pexWin.enable =MV_FALSE;
300 pexWin.target = target;
301 pexWin.targetBar = bar;
303 if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
305 mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
311 /* check if the size of the bar is illeggal */
312 if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
314 /* try to get a good size */
315 pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
316 PXBCR_BAR_SIZE_ALIGNMENT);
319 /* check if the size and base are valid */
320 if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
322 mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
323 mvOsPrintf("it will be disabled\n");
324 mvOsPrintf("please check Pex and CPU windows configuration\n");
328 pexBar.enable = MV_TRUE;
330 /* configure the bar */
331 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
333 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
337 /* after the bar was configured then we enable the Pex windows*/
338 for (winNum = 0;winNum < pexCurrWin ;winNum++)
340 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
342 mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
349 /******************************************************************************/
351 /******************************************************************************/
353 /* Open the Device BAR for non linux only */
354 #ifndef MV_DISABLE_PEX_DEVICE_BAR
357 bar = PEX_DEVICE_BAR;
359 /* save the starting window */
360 pexStartWindow = pexCurrWin;
361 pexBar.addrWin.size = 0;
362 pexBar.addrWin.baseLow = 0xffffffff;
363 pexBar.addrWin.baseHigh = 0;
366 for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
368 status = mvCpuIfTargetWinGet(target,&addrDecWin);
370 if (MV_NO_SUCH == status)
377 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
381 if (addrDecWin.enable == MV_TRUE)
383 /* get the minimum base */
384 if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
386 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
389 /* get the maximum base */
390 if (addrDecWin.addrWin.baseLow > maxBase)
392 maxBase = addrDecWin.addrWin.baseLow;
393 sizeOfMaxBase = addrDecWin.addrWin.size;
396 /* search in the priority table for this target */
397 for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
400 if (pexDevBarPrioTable[winIndex] != target)
404 else if (pexDevBarPrioTable[winIndex] == target)
408 /* if the index of this target in the prio table is valid
409 then we set the Pex window for this target, a valid index is
410 an index that is lower than the number of the windows that
411 was not configured yet */
413 /* we subtract 2 always because the default and expantion
414 rom windows are always configured */
415 if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
417 /* set a Pex window for this target ! */
418 pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
419 pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
420 pexWin.addrWin.size = addrDecWin.addrWin.size;
422 /* we disable the windows at first because we are not
423 sure that it is witihin bar boundries */
424 pexWin.enable = MV_FALSE;
425 pexWin.target = target;
426 pexWin.targetBar = bar;
428 if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
431 mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
440 pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
441 pexBar.enable = MV_TRUE;
443 /* check if the size of the bar is illegal */
444 if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
446 /* try to get a good size */
447 pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
448 PXBCR_BAR_SIZE_ALIGNMENT);
451 /* check if the size and base are valid */
452 if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
454 mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
455 mvOsPrintf("it will be disabled\n");
456 mvOsPrintf("please check Pex and CPU windows configuration\n");
460 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
462 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
466 /* now enable the windows */
467 for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
469 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
471 mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
480 return mvPexHalInit(pexIf, pexType);
484 /*******************************************************************************
485 * mvPexTargetWinSet - Set PEX to peripheral target address window BAR
495 * MV_OK if PEX BAR target window was set correctly,
496 * MV_BAD_PARAM on bad params
498 * (e.g. address window overlapps with other active PEX target window).
500 *******************************************************************************/
501 MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
502 MV_PEX_DEC_WIN *pAddrDecWin)
506 PEX_WIN_REG_INFO winRegInfo;
507 MV_TARGET_ATTRIB targetAttribs;
509 /* Parameter checking */
510 if(pexIf >= mvCtrlPexMaxIfGet())
512 mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
516 if (winNum >= PEX_MAX_TARGET_WIN)
518 mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
523 /* get the pex Window registers offsets */
524 pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
527 if (MV_TRUE == pAddrDecWin->enable)
530 /* 2) Check if the requested window overlaps with current windows */
531 if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
533 mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
537 /* 2) Check if the requested window overlaps with current windows */
538 if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
540 mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
549 /* read base register*/
551 if (winRegInfo.baseLowRegOffs)
553 decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
560 if (winRegInfo.sizeRegOffs)
562 decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
569 if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
571 mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
576 if (MV_TRUE == pAddrDecWin->enable)
578 decRegs.sizeReg |= PXWCR_WIN_EN;
582 decRegs.sizeReg &= ~PXWCR_WIN_EN;
586 /* clear bit location */
587 decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
589 /* set bar Mapping */
590 if (pAddrDecWin->targetBar == 1)
592 decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
594 else if (pAddrDecWin->targetBar == 2)
596 decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
599 mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
602 decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
603 decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
605 decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
606 decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
609 /* 3) Write to address decode Base Address Register */
611 if (winRegInfo.baseLowRegOffs)
613 MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
617 if (winRegInfo.sizeRegOffs)
619 if ((MV_PEX_WIN_DEFAULT == winNum)||
620 (MV_PEX_WIN_EXP_ROM == winNum))
622 /* clear size because there is no size field*/
623 decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
625 /* clear enable because there is no enable field*/
626 decRegs.sizeReg &= ~PXWCR_WIN_EN;
630 MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
638 /*******************************************************************************
639 * mvPexTargetWinGet - Get PEX to peripheral target address window
642 * Get the PEX to peripheral target address window BAR.
645 * pexIf - PEX interface number.
646 * bar - BAR to be accessed by slave.
649 * pAddrBarWin - PEX target window information data structure.
652 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
654 *******************************************************************************/
655 MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
656 MV_PEX_DEC_WIN *pAddrDecWin)
658 MV_TARGET_ATTRIB targetAttrib;
661 PEX_WIN_REG_INFO winRegInfo;
663 /* Parameter checking */
664 if(pexIf >= mvCtrlPexMaxIfGet())
666 mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
670 if (winNum >= PEX_MAX_TARGET_WIN)
672 mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
677 /* get the pex Window registers offsets */
678 pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
680 /* read base register*/
681 if (winRegInfo.baseLowRegOffs)
683 decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
691 if (winRegInfo.sizeRegOffs)
693 decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
700 if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
702 mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
707 if (decRegs.sizeReg & PXWCR_WIN_EN)
709 pAddrDecWin->enable = MV_TRUE;
713 pAddrDecWin->enable = MV_FALSE;
719 if (-1 == pAddrDecWin->addrWin.size)
727 if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
729 pAddrDecWin->targetBar = 1;
731 else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
732 PXWCR_WIN_BAR_MAP_BAR2 )
734 pAddrDecWin->targetBar = 2;
737 /* attrib and targetId */
738 pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
740 pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
743 targetAttrib.attrib = pAddrDecWin->attrib;
744 targetAttrib.targetId = pAddrDecWin->targetId;
746 pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
753 /*******************************************************************************
754 * mvPexTargetWinEnable - Enable/disable a PEX BAR window
757 * This function enable/disable a PEX BAR window.
758 * if parameter 'enable' == MV_TRUE the routine will enable the
759 * window, thus enabling PEX accesses for that BAR (before enabling the
760 * window it is tested for overlapping). Otherwise, the window will
764 * pexIf - PEX interface number.
765 * bar - BAR to be accessed by slave.
766 * enable - Enable/disable parameter.
772 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
774 *******************************************************************************/
775 MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
777 PEX_WIN_REG_INFO winRegInfo;
778 MV_PEX_DEC_WIN addrDecWin;
780 /* Parameter checking */
781 if(pexIf >= mvCtrlPexMaxIfGet())
783 mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
787 if (winNum >= PEX_MAX_TARGET_WIN)
789 mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
795 /* get the pex Window registers offsets */
796 pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
799 /* if the address windows is disabled , we only disable the appropriare
800 pex window and ignore other settings */
802 if (MV_FALSE == enable)
805 /* this is not relevant to default and expantion rom
807 if (winRegInfo.sizeRegOffs)
809 if ((MV_PEX_WIN_DEFAULT != winNum)&&
810 (MV_PEX_WIN_EXP_ROM != winNum))
812 MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
819 if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
821 mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
825 /* Check if the requested window overlaps with current windows */
826 if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
828 mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
832 if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
834 mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
840 /* this is not relevant to default and expantion rom
842 if (winRegInfo.sizeRegOffs)
844 if ((MV_PEX_WIN_DEFAULT != winNum)&&
845 (MV_PEX_WIN_EXP_ROM != winNum))
847 MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
860 /*******************************************************************************
861 * mvPexTargetWinRemap - Set PEX to target address window remap.
864 * The PEX interface supports remap of the BAR original address window.
865 * For each BAR it is possible to define a remap address. For example
866 * an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
867 * according to remap register but will also be targeted to the
871 * pexIf - PEX interface number.
872 * bar - Peripheral target enumerator accessed by slave.
873 * pAddrWin - Address window to be checked.
879 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
881 *******************************************************************************/
882 MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
883 MV_PEX_REMAP_WIN *pAddrWin)
886 PEX_WIN_REG_INFO winRegInfo;
888 /* Parameter checking */
889 if (pexIf >= mvCtrlPexMaxIfGet())
891 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
895 if (MV_PEX_WIN_DEFAULT == winNum)
897 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
903 if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
905 mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
906 "\nAddress 0x%08x is unaligned to size 0x%x.\n",
909 pAddrWin->addrWin.baseLow,
910 pAddrWin->addrWin.size);
915 pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
917 /* Set remap low register value */
918 MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
920 /* Skip base high settings if the BAR has only base low (32-bit) */
921 if (0 != winRegInfo.remapHighRegOffs)
923 MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
927 if (pAddrWin->enable == MV_TRUE)
929 MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
933 MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
939 /*******************************************************************************
940 * mvPexTargetWinRemapEnable -
949 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
951 *******************************************************************************/
953 MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
956 PEX_WIN_REG_INFO winRegInfo;
958 /* Parameter checking */
959 if (pexIf >= mvCtrlPexMaxIfGet())
961 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
965 if (MV_PEX_WIN_DEFAULT == winNum)
967 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
974 pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
976 if (enable == MV_TRUE)
978 MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
982 MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
989 /*******************************************************************************
990 * mvPexBarSet - Set PEX bar address and size
1000 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
1002 *******************************************************************************/
1003 MV_STATUS mvPexBarSet(MV_U32 pexIf,
1005 MV_PEX_BAR *pAddrWin)
1008 MV_U32 regSize,sizeToReg;
1011 /* check parameters */
1012 if(pexIf >= mvCtrlPexMaxIfGet())
1014 mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
1015 return MV_BAD_PARAM;
1018 if(barNum >= PEX_MAX_BARS)
1020 mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
1021 return MV_BAD_PARAM;
1025 if (pAddrWin->addrWin.size == 0)
1027 mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
1028 return MV_BAD_PARAM;
1032 /* Check if the window complies with PEX spec */
1033 if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
1034 pAddrWin->addrWin.size))
1036 mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
1037 return MV_BAD_PARAM;
1040 /* 2) Check if the requested bar overlaps with current bars */
1041 if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
1043 mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
1044 return MV_BAD_PARAM;
1047 /* Get size register value according to window size */
1048 sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
1051 if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
1053 regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
1055 /* Size parameter validity check. */
1056 if (-1 == sizeToReg)
1058 mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
1059 return MV_BAD_PARAM;
1062 regSize &= ~PXBCR_BAR_SIZE_MASK;
1063 regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
1065 MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
1073 /* Read base address low */
1074 regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
1075 PEX_MV_BAR_BASE(barNum)));
1077 /* clear current base */
1078 if (PEX_INTER_REGS_BAR == barNum)
1080 regBaseLow &= ~PXBIR_BASE_MASK;
1081 regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
1085 regBaseLow &= ~PXBR_BASE_MASK;
1086 regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
1089 /* if we had a previous value that contain the bar type (MeM\IO), we want to
1091 regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
1095 /* write base low */
1096 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
1099 if (pAddrWin->addrWin.baseHigh != 0)
1101 /* Read base address high */
1102 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
1103 pAddrWin->addrWin.baseHigh);
1107 /* lastly enable the Bar */
1108 if (pAddrWin->enable == MV_TRUE)
1110 if (PEX_INTER_REGS_BAR != barNum) /* internal registers
1111 are enabled always */
1113 MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
1116 else if (MV_FALSE == pAddrWin->enable)
1118 if (PEX_INTER_REGS_BAR != barNum) /* internal registers
1119 are enabled always */
1121 MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
1132 /*******************************************************************************
1133 * mvPexBarGet - Get PEX bar address and size
1143 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
1145 *******************************************************************************/
1147 MV_STATUS mvPexBarGet(MV_U32 pexIf,
1149 MV_PEX_BAR *pAddrWin)
1151 /* check parameters */
1152 if(pexIf >= mvCtrlPexMaxIfGet())
1154 mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
1155 return MV_BAD_PARAM;
1158 if(barNum >= PEX_MAX_BARS)
1160 mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
1161 return MV_BAD_PARAM;
1165 pAddrWin->addrWin.baseLow =
1166 MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
1169 if (PEX_INTER_REGS_BAR == barNum)
1171 pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
1175 pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
1179 /* read base high */
1180 pAddrWin->addrWin.baseHigh =
1181 MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
1185 if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
1187 pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
1189 /* check if enable or not */
1190 if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
1192 pAddrWin->enable = MV_TRUE;
1196 pAddrWin->enable = MV_FALSE;
1199 /* now get the size */
1200 pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
1201 pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
1203 pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
1204 PXBCR_BAR_SIZE_ALIGNMENT);
1207 else /* PEX_INTER_REGS_BAR */
1209 pAddrWin->addrWin.size = INTER_REGS_SIZE;
1210 pAddrWin->enable = MV_TRUE;
1217 /*******************************************************************************
1228 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
1230 *******************************************************************************/
1233 MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
1238 /* check parameters */
1239 if(pexIf >= mvCtrlPexMaxIfGet())
1241 mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
1242 return MV_BAD_PARAM;
1246 if(barNum >= PEX_MAX_BARS)
1248 mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
1249 return MV_BAD_PARAM;
1252 if (PEX_INTER_REGS_BAR == barNum)
1254 if (MV_TRUE == enable)
1265 if (MV_FALSE == enable)
1267 /* disable bar and quit */
1268 MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
1274 if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
1276 mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
1281 if (MV_TRUE == pexBar.enable)
1283 /* it is already enabled !!! */
1287 /* else enable the bar*/
1289 pexBar.enable = MV_TRUE;
1291 if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
1293 mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
1302 /*******************************************************************************
1303 * pexWinOverlapDetect - Detect address windows overlapping
1306 * This function detects address window overlapping of a given address
1307 * window in PEX BARs.
1310 * pAddrWin - Address window to be checked.
1311 * bar - BAR to be accessed by slave.
1317 * MV_TRUE if the given address window overlap current address
1318 * decode map, MV_FALSE otherwise.
1320 *******************************************************************************/
1321 static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
1323 MV_ADDR_WIN *pAddrWin)
1326 MV_PEX_DEC_WIN addrDecWin;
1329 for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
1331 /* don't check our target or illegal targets */
1337 /* Get window parameters */
1338 if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
1340 mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
1345 /* Do not check disabled windows */
1346 if (MV_FALSE == addrDecWin.enable)
1352 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
1354 mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
1363 /*******************************************************************************
1364 * pexIsWinWithinBar - Detect if address is within PEX bar boundries
1374 * MV_TRUE if the given address window overlap current address
1375 * decode map, MV_FALSE otherwise.
1377 *******************************************************************************/
1378 static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
1379 MV_ADDR_WIN *pAddrWin)
1382 MV_PEX_BAR addrDecWin;
1384 for(bar = 0; bar < PEX_MAX_BARS; bar++)
1387 /* Get window parameters */
1388 if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
1390 mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
1394 /* Do not check disabled bars */
1395 if (MV_FALSE == addrDecWin.enable)
1401 if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
1411 /*******************************************************************************
1412 * pexBarOverlapDetect - Detect address windows overlapping
1415 * This function detects address window overlapping of a given address
1416 * window in PEX BARs.
1419 * pAddrWin - Address window to be checked.
1420 * bar - BAR to be accessed by slave.
1426 * MV_TRUE if the given address window overlap current address
1427 * decode map, MV_FALSE otherwise.
1429 *******************************************************************************/
1430 static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
1432 MV_ADDR_WIN *pAddrWin)
1435 MV_PEX_BAR barDecWin;
1438 for(bar = 0; bar < PEX_MAX_BARS; bar++)
1440 /* don't check our target or illegal targets */
1446 /* Get window parameters */
1447 if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
1449 mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
1453 /* don'nt check disabled bars */
1454 if (barDecWin.enable == MV_FALSE)
1460 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
1462 mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
1471 /*******************************************************************************
1472 * pexBarIsValid - Check if the given address window is valid
1475 * PEX spec restrict BAR base to be aligned to BAR size.
1476 * This function checks if the given address window is valid.
1479 * baseLow - 32bit low base address.
1480 * size - Window size.
1486 * MV_TRUE if the address window is valid, MV_FALSE otherwise.
1488 *******************************************************************************/
1489 static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
1492 /* PCI spec restrict BAR base to be aligned to BAR size */
1493 if(MV_IS_NOT_ALIGN(baseLow, size))
1505 /*******************************************************************************
1506 * pexBarRegInfoGet - Get BAR register information
1509 * PEX BARs registers offsets are inconsecutive.
1510 * This function gets a PEX BAR register information like register offsets
1511 * and function location of the BAR.
1514 * pexIf - PEX interface number.
1515 * bar - The PEX BAR in question.
1518 * pBarRegInfo - BAR register info struct.
1521 * MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
1523 *******************************************************************************/
1524 static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
1526 PEX_WIN_REG_INFO *pWinRegInfo)
1529 if ((winNum >= 0)&&(winNum <=3))
1531 pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
1532 pWinRegInfo->baseHighRegOffs = 0;
1533 pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
1534 pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
1535 pWinRegInfo->remapHighRegOffs = 0;
1537 else if ((winNum >= 4)&&(winNum <=5))
1539 pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
1540 pWinRegInfo->baseHighRegOffs = 0;
1541 pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
1542 pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
1543 pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
1546 else if (MV_PEX_WIN_DEFAULT == winNum)
1548 pWinRegInfo->baseLowRegOffs = 0;
1549 pWinRegInfo->baseHighRegOffs = 0;
1550 pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
1551 pWinRegInfo->remapLowRegOffs = 0;
1552 pWinRegInfo->remapHighRegOffs = 0;
1554 else if (MV_PEX_WIN_EXP_ROM == winNum)
1556 pWinRegInfo->baseLowRegOffs = 0;
1557 pWinRegInfo->baseHighRegOffs = 0;
1558 pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
1559 pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
1560 pWinRegInfo->remapHighRegOffs = 0;
1567 /*******************************************************************************
1568 * pexBarNameGet - Get the string name of PEX BAR.
1571 * This function get the string name of PEX BAR.
1574 * bar - PEX bar number.
1580 * pointer to the string name of PEX BAR.
1582 *******************************************************************************/
1583 const MV_8* pexBarNameGet( MV_U32 bar )
1587 case PEX_INTER_REGS_BAR:
1588 return "Internal Regs Bar0....";
1590 return "DRAM Bar1.............";
1591 case PEX_DEVICE_BAR:
1592 return "Devices Bar2..........";
1594 return "Bar unknown";
1597 /*******************************************************************************
1598 * mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
1601 * This function print the PEX address decode map (BARs and windows).
1612 *******************************************************************************/
1613 MV_VOID mvPexAddrDecShow(MV_VOID)
1620 for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
1622 if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
1624 mvOsOutput( "PEX%d:\n", pexIf );
1625 mvOsOutput( "-----\n" );
1627 mvOsOutput( "\nPex Bars \n\n");
1629 for( bar = 0; bar < PEX_MAX_BARS; bar++ )
1631 memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
1633 mvOsOutput( "%s ", pexBarNameGet(bar) );
1635 if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
1639 mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
1640 mvSizePrint( pexBar.addrWin.size );
1644 mvOsOutput( "disable\n" );
1647 mvOsOutput( "\nPex Decode Windows\n\n");
1649 for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
1651 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
1653 mvOsOutput( "win%d - ", winNum );
1655 if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
1659 mvOsOutput( "%s base %08x, ",
1660 mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
1661 mvOsOutput( "...." );
1662 mvSizePrint( win.addrWin.size );
1667 mvOsOutput( "disable\n" );
1673 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
1675 mvOsOutput( "default win - " );
1677 if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
1680 mvCtrlTargetNameGet(win.target) );
1683 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
1685 mvOsOutput( "Expansion ROM - " );
1687 if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
1690 mvCtrlTargetNameGet(win.target) );