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 "pex/mvPex.h"
67 #include "ctrlEnv/mvCtrlEnvLib.h"
76 MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
82 /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
83 /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
84 /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
86 if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
87 (mvCtrlModelGet() != MV_6281_DEV_ID) &&
88 (mvCtrlModelGet() != MV_6192_DEV_ID) &&
89 (mvCtrlModelGet() != MV_6190_DEV_ID) &&
90 (mvCtrlModelGet() != MV_6180_DEV_ID) &&
91 (mvCtrlModelGet() != MV_6183_DEV_ID) &&
92 (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
93 (mvCtrlModelGet() != MV_78100_DEV_ID) &&
94 (mvCtrlModelGet() != MV_78200_DEV_ID) &&
95 (mvCtrlModelGet() != MV_76100_DEV_ID) &&
96 (mvCtrlModelGet() != MV_78XX0_DEV_ID))
99 /* Read current value of TXAMP */
100 MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
102 regVal = MV_REG_READ(0x41b00); /* Extract the data */
104 /* Prepare new data for write */
105 regVal &= ~0x7; /* Clear bits [2:0] */
106 regVal |= 0x4; /* Set the new value */
107 regVal &= ~0x80000000; /* Set "write" command */
108 MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
113 /* Implement 1.0V termination GL for 88F1281 device only */
114 /* BIT0 - Common mode feedback */
115 /* BIT3 - TxBuf, extra drive for 1.0V termination */
116 if (mvCtrlModelGet() == MV_1281_DEV_ID)
118 MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
119 regVal = MV_REG_READ(0x41b00); /* Extract the data */
120 regVal |= (BIT0 | BIT3);
121 regVal &= ~0x80000000; /* Set "write" command */
122 MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
124 MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
125 regVal = MV_REG_READ(0x31b00); /* Extract the data */
126 regVal |= (BIT0 | BIT3);
127 regVal &= ~0x80000000; /* Set "write" command */
128 MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
132 if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
134 mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
138 /* Check that required PEX type is the one set in reset time */
139 if (pexType != pexMode.pexType)
141 /* No Link. Shut down the Phy */
142 mvPexPowerDown(pexIf);
143 mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
147 if (MV_PEX_ROOT_COMPLEX == pexType)
149 mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
150 mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
152 /* Local device master Enable */
153 mvPexMasterEnable(pexIf, MV_TRUE);
155 /* Local device slave Enable */
156 mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
157 mvPexLocalDevNumGet(pexIf), MV_TRUE);
158 /* Interrupt disable */
159 status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
160 status |= PXSAC_INT_DIS;
161 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
164 /* now wait 500 ms to be sure the link is valid (spec compliant) */
166 /* Check if we have link */
167 if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
169 mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
173 if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
175 mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
179 mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
182 #ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
183 mvPexVrtBrgInit(pexIf);
188 /*******************************************************************************
189 * mvPexModeGet - Get Pex Mode
194 * pexIf - PEX interface number.
197 * pexMode - Pex mode structure
200 * MV_OK on success , MV_ERROR otherwise
202 *******************************************************************************/
203 MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
207 /* Parameter checking */
208 if (PEX_DEFAULT_IF != pexIf)
210 if (pexIf >= mvCtrlPexMaxIfGet())
212 mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
217 pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
219 switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
221 case PXCR_DEV_TYPE_CTRL_CMPLX:
222 pexMode->pexType = MV_PEX_ROOT_COMPLEX;
224 case PXCR_DEV_TYPE_CTRL_POINT:
225 pexMode->pexType = MV_PEX_END_POINT;
230 /* Check if we have link */
231 if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
233 pexMode->pexLinkUp = MV_FALSE;
235 /* If there is no link, the auto negotiation data is worthless */
236 pexMode->pexWidth = MV_PEX_WITDH_INVALID;
240 pexMode->pexLinkUp = MV_TRUE;
242 /* We have link. The link width is now valid */
243 pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
244 pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
245 PXLCSR_NEG_LNK_WDTH_OFFS);
252 /* PEX configuration space read write */
254 /*******************************************************************************
255 * mvPexConfigRead - Read from configuration space
258 * This function performs a 32 bit read from PEX configuration space.
259 * It supports both type 0 and type 1 of Configuration Transactions
260 * (local and over bridge). In order to read from local bus segment, use
261 * bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
262 * will result configuration transaction of type 1 (over bridge).
265 * pexIf - PEX interface number.
266 * bus - PEX segment bus number.
267 * dev - PEX device number.
268 * func - Function number.
269 * regOffs - Register offset.
275 * 32bit register data, 0xffffffff on error
277 *******************************************************************************/
278 MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
281 #if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
282 return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
285 MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
290 MV_U32 localDev,localBus;
292 /* Parameter checking */
293 if (PEX_DEFAULT_IF != pexIf)
295 if (pexIf >= mvCtrlPexMaxIfGet())
297 mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
302 if (dev >= MAX_PEX_DEVICES)
304 DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
308 if (func >= MAX_PEX_FUNCS)
310 DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
314 if (bus >= MAX_PEX_BUSSES)
316 DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
320 DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
321 pexIf, bus, dev, func, regOff));
323 localDev = mvPexLocalDevNumGet(pexIf);
324 localBus = mvPexLocalBusNumGet(pexIf);
326 /* Speed up the process. In case on no link, return MV_ERROR */
327 if ((dev != localDev) || (bus != localBus))
329 pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
331 if ((pexData & PXSR_DL_DOWN))
337 /* in PCI Express we have only one device number */
338 /* and this number is the first number we encounter
339 else that the localDev*/
340 /* spec pex define return on config read/write on any device */
345 /* if local dev is 0 then the first number we encounter
347 if ((dev != 1)&&(dev != localDev))
354 /* if local dev is not 0 then the first number we encounter
357 if ((dev != 0)&&(dev != localDev))
362 if(func != 0 ) /* i.e bridge */
369 /* Creating PEX address to be passed */
370 pexData = (bus << PXCAR_BUS_NUM_OFFS);
371 pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
372 pexData |= (func << PXCAR_FUNC_NUM_OFFS);
373 pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
374 /* extended register space */
375 pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
376 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
378 pexData |= PXCAR_CONFIG_EN;
380 /* Write the address to the PEX configuration address register */
381 MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
383 DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
386 /* In order to let the PEX controller absorbed the address of the read */
387 /* transaction we perform a validity check that the address was written */
388 if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
393 /* cleaning Master Abort */
394 MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
397 /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
398 /* This guideline is relevant for all devices except of the following devices:
399 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
400 88F6183 A0 and above, 88F6183L */
401 if ( ( (dev != localDev) || (bus != localBus) ) &&
403 !(MV_5281_DEV_ID == mvCtrlModelGet())&&
404 !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
405 !(MV_1281_DEV_ID == mvCtrlModelGet())&&
406 !(MV_6183_DEV_ID == mvCtrlModelGet())&&
407 !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
408 !(MV_6281_DEV_ID == mvCtrlModelGet())&&
409 !(MV_6192_DEV_ID == mvCtrlModelGet())&&
410 !(MV_6190_DEV_ID == mvCtrlModelGet())&&
411 !(MV_6180_DEV_ID == mvCtrlModelGet())&&
412 !(MV_78XX0_DEV_ID == mvCtrlModelGet())
416 /* PCI-Express configuration read work-around */
418 /* we will use one of the Punit (AHBToMbus) windows to access the xbar
419 and read the data from there */
421 Need to configure the 2 free Punit (AHB to MBus bridge)
422 address decoding windows:
423 Configure the flash Window to handle Configuration space requests
425 1. write 0x7931/0x7941 to the flash window and the size,
426 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
427 2. write base to flash window
429 Configuration transactions from the CPU should write/read the data
430 to/from address of the form:
431 addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
432 addr[27:24] = extended register number
433 addr[23:16] = bus number
434 addr[15:11] = device number
435 addr[10:8] = function number
436 addr[7:0] = register number
439 #include "ctrlEnv/sys/mvAhbToMbus.h"
442 MV_AHB_TO_MBUS_DEC_WIN originWin;
444 MV_U32 remapLow=0,remapHigh=0;
447 We will use DEV_CS2\Flash window for this workarround
450 winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
452 /* save remap values if exist */
453 if ((1 == winNum)||(0 == winNum))
455 remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
456 remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
461 /* save the original window values */
462 mvAhbToMbusWinGet(winNum,&originWin);
464 if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
466 /* set the window as xbar window */
469 MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
470 (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
474 MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
475 (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
478 MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
479 originWin.addrWin.baseLow);
481 /*pciAddr = originWin.addrWin.baseLow;*/
482 pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
483 (MV_U32)originWin.addrWin.baseLow);
488 /* set the window as xbar window */
491 MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
492 (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
496 MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
497 (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
500 MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
501 PEX_CONFIG_RW_WA_BASE);
503 pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
507 /* remap should be as base */
508 if ((1 == winNum)||(0 == winNum))
510 MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
511 MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
515 /* extended register space */
516 pciAddr |= (bus << 16);
517 pciAddr |= (dev << 11);
518 pciAddr |= (func << 8);
519 pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
521 pexData = *(MV_U32*)pciAddr;
522 pexData = MV_32BIT_LE(pexData); /* Data always in LE */
524 /* restore the original window values */
525 mvAhbToMbusWinSet(winNum,&originWin);
527 /* restore original remap values*/
528 if ((1 == winNum)||(0 == winNum))
530 MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
531 MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
539 /* Read the Data returned in the PEX Data register */
540 pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
544 DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
550 /*******************************************************************************
551 * mvPexConfigWrite - Write to configuration space
554 * This function performs a 32 bit write to PEX configuration space.
555 * It supports both type 0 and type 1 of Configuration Transactions
556 * (local and over bridge). In order to write to local bus segment, use
557 * bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
558 * will result configuration transaction of type 1 (over bridge).
561 * pexIf - PEX interface number.
562 * bus - PEX segment bus number.
563 * dev - PEX device number.
564 * func - Function number.
565 * regOffs - Register offset.
572 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
574 *******************************************************************************/
575 MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
576 MV_U32 func, MV_U32 regOff, MV_U32 data)
578 #if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
579 return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
582 MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
583 MV_U32 func, MV_U32 regOff, MV_U32 data)
587 MV_U32 localDev,localBus;
589 /* Parameter checking */
590 if (PEX_DEFAULT_IF != pexIf)
592 if (pexIf >= mvCtrlPexMaxIfGet())
594 mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
600 if (dev >= MAX_PEX_DEVICES)
602 mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
606 if (func >= MAX_PEX_FUNCS)
608 mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
612 if (bus >= MAX_PEX_BUSSES)
614 mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
620 localDev = mvPexLocalDevNumGet(pexIf);
621 localBus = mvPexLocalBusNumGet(pexIf);
624 /* in PCI Express we have only one device number other than ourselves*/
625 /* and this number is the first number we encounter
626 else than the localDev that can be any valid dev number*/
627 /* pex spec define return on config read/write on any device */
633 /* if local dev is 0 then the first number we encounter
635 if ((dev != 1)&&(dev != localDev))
643 /* if local dev is not 0 then the first number we encounter
646 if ((dev != 0)&&(dev != localDev))
655 /* if we are not accessing ourselves , then check the link */
656 if ((dev != localDev) || (bus != localBus) )
659 /* when no link return MV_ERROR */
661 pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
663 if ((pexData & PXSR_DL_DOWN))
672 /* Creating PEX address to be passed */
673 pexData |= (bus << PXCAR_BUS_NUM_OFFS);
674 pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
675 pexData |= (func << PXCAR_FUNC_NUM_OFFS);
676 pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
677 /* extended register space */
678 pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
679 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
680 pexData |= PXCAR_CONFIG_EN;
682 DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
683 pexIf,bus,func,dev,regOff,data,pexData) );
685 /* Write the address to the PEX configuration address register */
686 MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
688 /* Clear CPU pipe. Important where CPU can perform OOO execution */
691 /* In order to let the PEX controller absorbed the address of the read */
692 /* transaction we perform a validity check that the address was written */
693 if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
698 /* Write the Data passed to the PEX Data register */
699 MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
705 /*******************************************************************************
706 * mvPexMasterEnable - Enable/disale PEX interface master transactions.
709 * This function performs read modified write to PEX command status
710 * (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
711 * master is allowed to gain ownership on the bus, otherwise it is
712 * incapable to do so.
715 * pexIf - PEX interface number.
716 * enable - Enable/disable parameter.
722 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
724 *******************************************************************************/
725 MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
727 MV_U32 pexCommandStatus;
731 /* Parameter checking */
732 if (pexIf >= mvCtrlPexMaxIfGet())
734 mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
738 localBus = mvPexLocalBusNumGet(pexIf);
739 localDev = mvPexLocalDevNumGet(pexIf);
741 pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
742 PEX_STATUS_AND_COMMAND));
745 if (MV_TRUE == enable)
747 pexCommandStatus |= PXSAC_MASTER_EN;
751 pexCommandStatus &= ~PXSAC_MASTER_EN;
755 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
762 /*******************************************************************************
763 * mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
766 * This function performs read modified write to PEX command status
767 * (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
768 * the PEX slave is allowed to respond to PEX IO space access (bit 0)
769 * and PEX memory space access (bit 1).
772 * pexIf - PEX interface number.
773 * dev - PEX device number.
774 * enable - Enable/disable parameter.
780 * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
782 *******************************************************************************/
783 MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
785 MV_U32 pexCommandStatus;
788 /* Parameter checking */
789 if (pexIf >= mvCtrlPexMaxIfGet())
791 mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
794 if (dev >= MAX_PEX_DEVICES)
796 mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
802 RegOffs = PEX_STATUS_AND_COMMAND;
804 pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
806 if (MV_TRUE == enable)
808 pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
812 pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
815 mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
821 /*******************************************************************************
822 * mvPexLocalBusNumSet - Set PEX interface local bus number.
825 * This function sets given PEX interface its local bus number.
826 * Note: In case the PEX interface is PEX-X, the information is read-only.
829 * pexIf - PEX interface number.
830 * busNum - Bus number.
836 * MV_NOT_ALLOWED in case PEX interface is PEX-X.
837 * MV_BAD_PARAM on bad parameters ,
840 *******************************************************************************/
841 MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
848 /* Parameter checking */
849 if (pexIf >= mvCtrlPexMaxIfGet())
851 mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
854 if (busNum >= MAX_PEX_BUSSES)
856 mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
861 localBus = mvPexLocalBusNumGet(pexIf);
862 localDev = mvPexLocalDevNumGet(pexIf);
866 pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
868 pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
870 pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
872 MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
879 /*******************************************************************************
880 * mvPexLocalBusNumGet - Get PEX interface local bus number.
883 * This function gets the local bus number of a given PEX interface.
886 * pexIf - PEX interface number.
892 * Local bus number.0xffffffff on Error
894 *******************************************************************************/
895 MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
899 /* Parameter checking */
900 if (PEX_DEFAULT_IF != pexIf)
902 if (pexIf >= mvCtrlPexMaxIfGet())
904 mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
910 pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
912 pexStatus &= PXSR_PEX_BUS_NUM_MASK;
914 return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
919 /*******************************************************************************
920 * mvPexLocalDevNumSet - Set PEX interface local device number.
923 * This function sets given PEX interface its local device number.
924 * Note: In case the PEX interface is PEX-X, the information is read-only.
927 * pexIf - PEX interface number.
928 * devNum - Device number.
934 * MV_NOT_ALLOWED in case PEX interface is PEX-X.
935 * MV_BAD_PARAM on bad parameters ,
938 *******************************************************************************/
939 MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
945 /* Parameter checking */
946 if (pexIf >= mvCtrlPexMaxIfGet())
948 mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
951 if (devNum >= MAX_PEX_DEVICES)
953 mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
959 localBus = mvPexLocalBusNumGet(pexIf);
960 localDev = mvPexLocalDevNumGet(pexIf);
963 pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
965 pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
967 pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
969 MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
975 /*******************************************************************************
976 * mvPexLocalDevNumGet - Get PEX interface local device number.
979 * This function gets the local device number of a given PEX interface.
982 * pexIf - PEX interface number.
988 * Local device number. 0xffffffff on Error
990 *******************************************************************************/
991 MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
995 /* Parameter checking */
997 if (PEX_DEFAULT_IF != pexIf)
999 if (pexIf >= mvCtrlPexMaxIfGet())
1001 mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
1007 pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
1009 pexStatus &= PXSR_PEX_DEV_NUM_MASK;
1011 return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
1014 MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
1018 if (pexIf >= mvCtrlPexMaxIfGet())
1020 mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
1023 regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
1024 MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
1025 *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
1029 MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
1033 if(pexIf >= mvCtrlPexMaxIfGet())
1035 mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
1038 regAddr = (((regOffset & 0x3fff) << 16) | value);
1039 MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
1042 /*******************************************************************************
1043 * mvPexActiveStateLinkPMEnable
1046 * Enable Active Link State Power Management
1049 * pexIf - PEX interface number.
1050 * enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
1056 * MV_OK on success , MV_ERROR otherwise
1058 *******************************************************************************/
1059 MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
1063 if(pexIf >= mvCtrlPexMaxIfGet())
1065 mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
1069 reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
1070 if(enable == MV_TRUE)
1071 reg |= PXPMER_L1_ASPM_EN_MASK;
1072 MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
1074 /* Enable / Disable L0/1 entry */
1075 reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
1076 & ~PXLCSR_ASPM_CNT_MASK;
1077 if(enable == MV_TRUE)
1078 reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
1079 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
1085 /*******************************************************************************
1089 * shut down lanes 1-3 if recognize that attached to an x1 end-point
1091 * pexIf - PEX interface number.
1097 * MV_OK on success , MV_ERROR otherwise
1099 *******************************************************************************/
1100 MV_U32 mvPexForceX1(MV_U32 pexIf)
1103 if(pexIf >= mvCtrlPexMaxIfGet())
1105 mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
1106 return MV_BAD_PARAM;
1109 regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
1110 regData |= PXCR_CONF_LINK_X1;
1112 MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
1116 MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
1118 if(pexIf >= mvCtrlPexMaxIfGet())
1120 mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
1123 return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
1127 MV_VOID mvPexPowerDown(MV_U32 pexIf)
1129 if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
1130 (mvCtrlModelGet() == MV_76100_DEV_ID) ||
1131 (mvCtrlModelGet() == MV_78100_DEV_ID) ||
1132 (mvCtrlModelGet() == MV_78200_DEV_ID) )
1134 mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
1138 MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);