Root/target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c

1/*******************************************************************************
2Copyright (C) Marvell International Ltd. and its affiliates
3
4This software file (the "File") is owned and distributed by Marvell
5International Ltd. and/or its affiliates ("Marvell") under the following
6alternative licensing terms. Once you have made an election to distribute the
7File under one of the following license alternatives, please (i) delete this
8introductory statement regarding license alternatives, (ii) delete the two
9license alternatives that you have not elected to use and (iii) preserve the
10Marvell copyright notice above.
11
12********************************************************************************
13Marvell Commercial License Option
14
15If you received this File from Marvell and you have entered into a commercial
16license agreement (a "Commercial License") with Marvell, the File is licensed
17to you under the terms of the applicable Commercial License.
18
19********************************************************************************
20Marvell GPL License Option
21
22If you received this File from Marvell, you may opt to use, redistribute and/or
23modify this File in accordance with the terms and conditions of the General
24Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25available along with the File in the license.txt file or by writing to the Free
26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28
29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31DISCLAIMED. The GPL License provides additional details about this warranty
32disclaimer.
33********************************************************************************
34Marvell BSD License Option
35
36If you received this File from Marvell, you may opt to use, redistribute and/or
37modify this File under the following licensing terms.
38Redistribution and use in source and binary forms, with or without modification,
39are 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    
52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59ANY 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
61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63*******************************************************************************/
64
65#include "pex/mvPex.h"
66
67#include "ctrlEnv/mvCtrlEnvLib.h"
68
69/* defines */
70#ifdef MV_DEBUG
71#define DB(x) x
72#else
73#define DB(x)
74#endif
75
76MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
77{
78    MV_PEX_MODE pexMode;
79    MV_U32 regVal;
80    MV_U32 status;
81 
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 */
85 
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))
97    {
98
99        /* Read current value of TXAMP */
100        MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
101
102        regVal = MV_REG_READ(0x41b00); /* Extract the data */
103
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 */
109
110    }
111    else
112    {
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)
117        {
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 */
123
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 */
129        }
130    }
131
132        if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
133        {
134                mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
135                return MV_ERROR;
136        }
137
138        /* Check that required PEX type is the one set in reset time */
139        if (pexType != pexMode.pexType)
140        {
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);
144                return MV_ERROR;
145        }
146
147        if (MV_PEX_ROOT_COMPLEX == pexType)
148        {
149                mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
150                mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
151        
152                /* Local device master Enable */
153                mvPexMasterEnable(pexIf, MV_TRUE);
154        
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);
162        }
163
164        /* now wait 500 ms to be sure the link is valid (spec compliant) */
165        mvOsDelay(500);
166    /* Check if we have link */
167    if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
168    {
169        mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
170        return MV_NO_SUCH;
171    }
172
173    if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
174    {
175        mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
176    }
177    else
178    {
179        mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
180    }
181
182#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
183    mvPexVrtBrgInit(pexIf);
184#endif
185    return MV_OK;
186}
187
188/*******************************************************************************
189* mvPexModeGet - Get Pex Mode
190*
191* DESCRIPTION:
192*
193* INPUT:
194* pexIf - PEX interface number.
195*
196* OUTPUT:
197* pexMode - Pex mode structure
198*
199* RETURN:
200* MV_OK on success , MV_ERROR otherwise
201*
202*******************************************************************************/
203MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
204{
205    MV_U32 pexData;
206
207    /* Parameter checking */
208    if (PEX_DEFAULT_IF != pexIf)
209    {
210        if (pexIf >= mvCtrlPexMaxIfGet())
211        {
212            mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
213            return MV_ERROR;
214        }
215    }
216
217    pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
218
219    switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
220    {
221    case PXCR_DEV_TYPE_CTRL_CMPLX:
222        pexMode->pexType = MV_PEX_ROOT_COMPLEX;
223        break;
224    case PXCR_DEV_TYPE_CTRL_POINT:
225        pexMode->pexType = MV_PEX_END_POINT;
226        break;
227
228    }
229
230    /* Check if we have link */
231    if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
232    {
233        pexMode->pexLinkUp = MV_FALSE;
234        
235        /* If there is no link, the auto negotiation data is worthless */
236        pexMode->pexWidth = MV_PEX_WITDH_INVALID;
237    }
238    else
239    {
240        pexMode->pexLinkUp = MV_TRUE;
241
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);
246    }
247
248    return MV_OK;
249}
250
251
252/* PEX configuration space read write */
253
254/*******************************************************************************
255* mvPexConfigRead - Read from configuration space
256*
257* DESCRIPTION:
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).
263*
264* INPUT:
265* pexIf - PEX interface number.
266* bus - PEX segment bus number.
267* dev - PEX device number.
268* func - Function number.
269* regOffs - Register offset.
270*
271* OUTPUT:
272* None.
273*
274* RETURN:
275* 32bit register data, 0xffffffff on error
276*
277*******************************************************************************/
278MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
279                        MV_U32 regOff)
280{
281#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
282        return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
283}
284
285MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
286                        MV_U32 regOff)
287{
288#endif
289    MV_U32 pexData = 0;
290    MV_U32 localDev,localBus;
291
292    /* Parameter checking */
293    if (PEX_DEFAULT_IF != pexIf)
294    {
295        if (pexIf >= mvCtrlPexMaxIfGet())
296        {
297            mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
298            return 0xFFFFFFFF;
299        }
300    }
301
302    if (dev >= MAX_PEX_DEVICES)
303    {
304        DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
305        return 0xFFFFFFFF;
306    }
307    
308    if (func >= MAX_PEX_FUNCS)
309    {
310        DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
311        return 0xFFFFFFFF;
312    }
313    
314    if (bus >= MAX_PEX_BUSSES)
315    {
316        DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
317        return MV_ERROR;
318    }
319             
320    DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
321                   pexIf, bus, dev, func, regOff));
322    
323    localDev = mvPexLocalDevNumGet(pexIf);
324    localBus = mvPexLocalBusNumGet(pexIf);
325                                     
326    /* Speed up the process. In case on no link, return MV_ERROR */
327    if ((dev != localDev) || (bus != localBus))
328    {
329        pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
330
331        if ((pexData & PXSR_DL_DOWN))
332        {
333            return MV_ERROR;
334        }
335    }
336
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 */
341    if (bus == localBus)
342    {
343        if (localDev == 0)
344        {
345            /* if local dev is 0 then the first number we encounter
346            after 0 is 1 */
347            if ((dev != 1)&&(dev != localDev))
348            {
349                return MV_ERROR;
350            }
351        }
352        else
353        {
354            /* if local dev is not 0 then the first number we encounter
355            is 0 */
356    
357            if ((dev != 0)&&(dev != localDev))
358            {
359                return MV_ERROR;
360            }
361        }
362        if(func != 0 ) /* i.e bridge */
363        {
364            return MV_ERROR;
365        }
366    }
367    
368    
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);
377
378    pexData |= PXCAR_CONFIG_EN;
379    
380    /* Write the address to the PEX configuration address register */
381    MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
382
383    DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
384    
385    
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)))
389    {
390        return MV_ERROR;
391    }
392
393    /* cleaning Master Abort */
394    MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
395                   PXSAC_MABORT);
396#if 0
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) ) &&
402        (
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())
413        ))
414    {
415
416        /* PCI-Express configuration read work-around */
417
418        /* we will use one of the Punit (AHBToMbus) windows to access the xbar
419        and read the data from there */
420        /*
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
424        for PEX0/1:
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
428        
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
437        */
438
439        #include "ctrlEnv/sys/mvAhbToMbus.h"
440        {
441            MV_U32 winNum;
442            MV_AHB_TO_MBUS_DEC_WIN originWin;
443            MV_U32 pciAddr=0;
444            MV_U32 remapLow=0,remapHigh=0;
445
446            /*
447            We will use DEV_CS2\Flash window for this workarround
448            */
449            
450            winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
451
452            /* save remap values if exist */
453            if ((1 == winNum)||(0 == winNum))
454            {
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));
457
458            }
459            
460
461            /* save the original window values */
462            mvAhbToMbusWinGet(winNum,&originWin);
463
464            if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
465            {
466                /* set the window as xbar window */
467                if (pexIf)
468                {
469                    MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
470                    (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
471                }
472                else
473                {
474                    MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
475                    (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
476                }
477
478                MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
479                             originWin.addrWin.baseLow);
480
481                /*pciAddr = originWin.addrWin.baseLow;*/
482                pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
483                    (MV_U32)originWin.addrWin.baseLow);
484            
485            }
486            else
487            {
488                /* set the window as xbar window */
489                if (pexIf)
490                {
491                    MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
492                    (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
493                }
494                else
495                {
496                    MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
497                    (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
498                }
499
500                MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
501                             PEX_CONFIG_RW_WA_BASE);
502
503                pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
504            }
505            
506            
507            /* remap should be as base */
508            if ((1 == winNum)||(0 == winNum))
509            {
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);
512
513            }
514
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 */
520
521            pexData = *(MV_U32*)pciAddr;
522            pexData = MV_32BIT_LE(pexData); /* Data always in LE */
523
524            /* restore the original window values */
525            mvAhbToMbusWinSet(winNum,&originWin);
526
527            /* restore original remap values*/
528            if ((1 == winNum)||(0 == winNum))
529            {
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);
532
533            }
534        }
535    }
536    else
537#endif
538    {
539        /* Read the Data returned in the PEX Data register */
540        pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
541
542    }
543
544    DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
545    
546    return pexData;
547
548}
549
550/*******************************************************************************
551* mvPexConfigWrite - Write to configuration space
552*
553* DESCRIPTION:
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).
559*
560* INPUT:
561* pexIf - PEX interface number.
562* bus - PEX segment bus number.
563* dev - PEX device number.
564* func - Function number.
565* regOffs - Register offset.
566* data - 32bit data.
567*
568* OUTPUT:
569* None.
570*
571* RETURN:
572* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
573*
574*******************************************************************************/
575MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
576                           MV_U32 func, MV_U32 regOff, MV_U32 data)
577{
578#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
579        return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
580}
581
582MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
583                           MV_U32 func, MV_U32 regOff, MV_U32 data)
584{
585#endif
586    MV_U32 pexData = 0;
587    MV_U32 localDev,localBus;
588
589    /* Parameter checking */
590    if (PEX_DEFAULT_IF != pexIf)
591    {
592        if (pexIf >= mvCtrlPexMaxIfGet())
593        {
594            mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
595                                                                        pexIf);
596            return MV_ERROR;
597        }
598    }
599
600    if (dev >= MAX_PEX_DEVICES)
601    {
602        mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
603        return MV_BAD_PARAM;
604    }
605
606    if (func >= MAX_PEX_FUNCS)
607    {
608        mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
609        return MV_ERROR;
610    }
611
612    if (bus >= MAX_PEX_BUSSES)
613    {
614        mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
615        return MV_ERROR;
616    }
617
618
619
620    localDev = mvPexLocalDevNumGet(pexIf);
621    localBus = mvPexLocalBusNumGet(pexIf);
622
623    
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 */
628    if (bus == localBus)
629    {
630
631        if (localDev == 0)
632        {
633            /* if local dev is 0 then the first number we encounter
634            after 0 is 1 */
635            if ((dev != 1)&&(dev != localDev))
636            {
637                return MV_ERROR;
638            }
639    
640        }
641        else
642        {
643            /* if local dev is not 0 then the first number we encounter
644            is 0 */
645    
646            if ((dev != 0)&&(dev != localDev))
647            {
648                return MV_ERROR;
649            }
650        }
651
652        
653    }
654
655    /* if we are not accessing ourselves , then check the link */
656    if ((dev != localDev) || (bus != localBus) )
657    {
658        /* workarround */
659        /* when no link return MV_ERROR */
660
661        pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
662
663        if ((pexData & PXSR_DL_DOWN))
664        {
665            return MV_ERROR;
666        }
667
668    }
669
670    pexData =0;
671
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;
681    
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) );
684
685    /* Write the address to the PEX configuration address register */
686    MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
687
688    /* Clear CPU pipe. Important where CPU can perform OOO execution */
689        CPU_PIPE_FLUSH;
690
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)))
694    {
695        return MV_ERROR;
696    }
697
698    /* Write the Data passed to the PEX Data register */
699    MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
700
701    return MV_OK;
702
703}
704
705/*******************************************************************************
706* mvPexMasterEnable - Enable/disale PEX interface master transactions.
707*
708* DESCRIPTION:
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.
713*
714* INPUT:
715* pexIf - PEX interface number.
716* enable - Enable/disable parameter.
717*
718* OUTPUT:
719* None.
720*
721* RETURN:
722* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
723*
724*******************************************************************************/
725MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
726{
727    MV_U32 pexCommandStatus;
728    MV_U32 localBus;
729    MV_U32 localDev;
730
731    /* Parameter checking */
732    if (pexIf >= mvCtrlPexMaxIfGet())
733    {
734        mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
735        return MV_ERROR;
736    }
737
738    localBus = mvPexLocalBusNumGet(pexIf);
739    localDev = mvPexLocalDevNumGet(pexIf);
740    
741    pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
742                                PEX_STATUS_AND_COMMAND));
743
744
745    if (MV_TRUE == enable)
746    {
747        pexCommandStatus |= PXSAC_MASTER_EN;
748    }
749    else
750    {
751        pexCommandStatus &= ~PXSAC_MASTER_EN;
752    }
753
754    
755    MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
756                 pexCommandStatus);
757
758    return MV_OK;
759}
760
761
762/*******************************************************************************
763* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
764*
765* DESCRIPTION:
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).
770*
771* INPUT:
772* pexIf - PEX interface number.
773* dev - PEX device number.
774* enable - Enable/disable parameter.
775*
776* OUTPUT:
777* None.
778*
779* RETURN:
780* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
781*
782*******************************************************************************/
783MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
784{
785    MV_U32 pexCommandStatus;
786    MV_U32 RegOffs;
787
788    /* Parameter checking */
789    if (pexIf >= mvCtrlPexMaxIfGet())
790    {
791        mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
792        return MV_BAD_PARAM;
793    }
794    if (dev >= MAX_PEX_DEVICES)
795    {
796        mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
797        return MV_BAD_PARAM;
798
799    }
800
801    
802    RegOffs = PEX_STATUS_AND_COMMAND;
803    
804    pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
805
806    if (MV_TRUE == enable)
807    {
808        pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
809    }
810    else
811    {
812        pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
813    }
814
815    mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
816
817    return MV_OK;
818
819}
820
821/*******************************************************************************
822* mvPexLocalBusNumSet - Set PEX interface local bus number.
823*
824* DESCRIPTION:
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.
827*
828* INPUT:
829* pexIf - PEX interface number.
830* busNum - Bus number.
831*
832* OUTPUT:
833* None.
834*
835* RETURN:
836* MV_NOT_ALLOWED in case PEX interface is PEX-X.
837* MV_BAD_PARAM on bad parameters ,
838* otherwise MV_OK
839*
840*******************************************************************************/
841MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
842{
843    MV_U32 pexStatus;
844    MV_U32 localBus;
845    MV_U32 localDev;
846
847
848    /* Parameter checking */
849    if (pexIf >= mvCtrlPexMaxIfGet())
850    {
851        mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
852        return MV_BAD_PARAM;
853    }
854    if (busNum >= MAX_PEX_BUSSES)
855    {
856        mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
857        return MV_ERROR;
858
859    }
860
861    localBus = mvPexLocalBusNumGet(pexIf);
862    localDev = mvPexLocalDevNumGet(pexIf);
863
864
865
866    pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
867
868    pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
869
870    pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
871
872    MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
873
874
875    return MV_OK;
876}
877
878
879/*******************************************************************************
880* mvPexLocalBusNumGet - Get PEX interface local bus number.
881*
882* DESCRIPTION:
883* This function gets the local bus number of a given PEX interface.
884*
885* INPUT:
886* pexIf - PEX interface number.
887*
888* OUTPUT:
889* None.
890*
891* RETURN:
892* Local bus number.0xffffffff on Error
893*
894*******************************************************************************/
895MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
896{
897    MV_U32 pexStatus;
898
899    /* Parameter checking */
900    if (PEX_DEFAULT_IF != pexIf)
901    {
902        if (pexIf >= mvCtrlPexMaxIfGet())
903        {
904            mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
905            return 0xFFFFFFFF;
906        }
907    }
908
909
910    pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
911
912    pexStatus &= PXSR_PEX_BUS_NUM_MASK;
913
914    return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
915
916}
917
918
919/*******************************************************************************
920* mvPexLocalDevNumSet - Set PEX interface local device number.
921*
922* DESCRIPTION:
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.
925*
926* INPUT:
927* pexIf - PEX interface number.
928* devNum - Device number.
929*
930* OUTPUT:
931* None.
932*
933* RETURN:
934* MV_NOT_ALLOWED in case PEX interface is PEX-X.
935* MV_BAD_PARAM on bad parameters ,
936* otherwise MV_OK
937*
938*******************************************************************************/
939MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
940{
941    MV_U32 pexStatus;
942    MV_U32 localBus;
943    MV_U32 localDev;
944
945    /* Parameter checking */
946    if (pexIf >= mvCtrlPexMaxIfGet())
947    {
948        mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
949        return MV_BAD_PARAM;
950    }
951    if (devNum >= MAX_PEX_DEVICES)
952    {
953        mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
954                                                                       devNum);
955        return MV_BAD_PARAM;
956
957    }
958    
959    localBus = mvPexLocalBusNumGet(pexIf);
960    localDev = mvPexLocalDevNumGet(pexIf);
961
962
963    pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
964
965    pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
966
967    pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
968
969    MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
970
971
972    return MV_OK;
973}
974
975/*******************************************************************************
976* mvPexLocalDevNumGet - Get PEX interface local device number.
977*
978* DESCRIPTION:
979* This function gets the local device number of a given PEX interface.
980*
981* INPUT:
982* pexIf - PEX interface number.
983*
984* OUTPUT:
985* None.
986*
987* RETURN:
988* Local device number. 0xffffffff on Error
989*
990*******************************************************************************/
991MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
992{
993    MV_U32 pexStatus;
994
995    /* Parameter checking */
996    
997    if (PEX_DEFAULT_IF != pexIf)
998    {
999        if (pexIf >= mvCtrlPexMaxIfGet())
1000        {
1001            mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
1002                                                                           pexIf);
1003            return 0xFFFFFFFF;
1004        }
1005    }
1006    
1007    pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
1008
1009    pexStatus &= PXSR_PEX_DEV_NUM_MASK;
1010
1011    return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
1012}
1013
1014MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
1015{
1016
1017    MV_U32 regAddr;
1018    if (pexIf >= mvCtrlPexMaxIfGet())
1019    {
1020        mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
1021        return;
1022    }
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));
1026}
1027
1028
1029MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
1030{
1031
1032    MV_U32 regAddr;
1033    if(pexIf >= mvCtrlPexMaxIfGet())
1034    {
1035        mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
1036        return;
1037    }
1038    regAddr = (((regOffset & 0x3fff) << 16) | value);
1039    MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
1040}
1041
1042/*******************************************************************************
1043* mvPexActiveStateLinkPMEnable
1044*
1045* DESCRIPTION:
1046* Enable Active Link State Power Management
1047*
1048* INPUT:
1049* pexIf - PEX interface number.
1050* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
1051*
1052* OUTPUT:
1053* None
1054*
1055* RETURN:
1056* MV_OK on success , MV_ERROR otherwise
1057*
1058*******************************************************************************/
1059MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
1060{
1061    MV_U32 reg;
1062
1063    if(pexIf >= mvCtrlPexMaxIfGet())
1064    {
1065        mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
1066        return MV_ERROR;
1067    }
1068
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);
1073
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);
1080
1081    return MV_OK;
1082}
1083
1084
1085/*******************************************************************************
1086* mvPexForceX1
1087*
1088* DESCRIPTION:
1089* shut down lanes 1-3 if recognize that attached to an x1 end-point
1090* INPUT:
1091* pexIf - PEX interface number.
1092*
1093* OUTPUT:
1094* None
1095*
1096* RETURN:
1097* MV_OK on success , MV_ERROR otherwise
1098*
1099*******************************************************************************/
1100MV_U32 mvPexForceX1(MV_U32 pexIf)
1101{
1102    MV_U32 regData = 0;
1103    if(pexIf >= mvCtrlPexMaxIfGet())
1104    {
1105        mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
1106        return MV_BAD_PARAM;
1107    }
1108
1109    regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
1110    regData |= PXCR_CONF_LINK_X1;
1111
1112    MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
1113    return MV_OK;
1114}
1115
1116MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
1117{
1118    if(pexIf >= mvCtrlPexMaxIfGet())
1119    {
1120        mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
1121        return MV_FALSE;
1122    }
1123    return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
1124}
1125
1126
1127MV_VOID mvPexPowerDown(MV_U32 pexIf)
1128{
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) )
1133    {
1134        mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
1135    }
1136    else
1137    {
1138        MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
1139    }
1140}
1141
1142
1143
1144

Archive Download this file



interactive