rename target/linux/generic-2.6 to generic
[15.05/openwrt.git] / target / linux / generic / files / crypto / ocf / kirkwood / mvHal / mv_hal / pex / mvPex.c
1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
3
4 This software file (the "File") is owned and distributed by Marvell 
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms.  Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
11
12 ********************************************************************************
13 Marvell Commercial License Option
14
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
18
19 ********************************************************************************
20 Marvell GPL License Option
21
22 If you received this File from Marvell, you may opt to use, redistribute and/or 
23 modify this File in accordance with the terms and conditions of the General 
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is 
25 available along with the File in the license.txt file or by writing to the Free 
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or 
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt. 
28
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED 
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY 
31 DISCLAIMED.  The GPL License provides additional details about this warranty 
32 disclaimer.
33 ********************************************************************************
34 Marvell BSD License Option
35
36 If you received this File from Marvell, you may opt to use, redistribute and/or 
37 modify this File under the following licensing terms. 
38 Redistribution and use in source and binary forms, with or without modification, 
39 are permitted provided that the following conditions are met:
40
41     *   Redistributions of source code must retain the above copyright notice,
42             this list of conditions and the following disclaimer. 
43
44     *   Redistributions in binary form must reproduce the above copyright
45         notice, this list of conditions and the following disclaimer in the
46         documentation and/or other materials provided with the distribution. 
47
48     *   Neither the name of Marvell nor the names of its contributors may be 
49         used to endorse or promote products derived from this software without 
50         specific prior written permission. 
51     
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
59 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63 *******************************************************************************/
64
65 #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
76 MV_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 *******************************************************************************/
203 MV_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 *******************************************************************************/
278 MV_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
285 MV_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 *******************************************************************************/
575 MV_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
582 MV_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 *******************************************************************************/
725 MV_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 *******************************************************************************/
783 MV_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 *******************************************************************************/
841 MV_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 *******************************************************************************/
895 MV_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 *******************************************************************************/
939 MV_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 *******************************************************************************/
991 MV_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
1014 MV_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
1029 MV_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 *******************************************************************************/
1059 MV_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 *******************************************************************************/
1100 MV_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
1116 MV_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
1127 MV_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