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 "ctrlEnv/sys/mvSysPex.h" 66 67/* this structure describes the mapping between a Pex Window and a CPU target*/ 68typedef struct _pexWinToTarget 69{ 70 MV_TARGET target; 71 MV_BOOL enable; 72 73}PEX_WIN_TO_TARGET; 74 75/* this array is a priority array that define How Pex windows should be 76configured , We have only 6 Pex Windows that can be configured , but we 77have maximum of 9 CPU target windows ! the following array is a priority 78array where the lowest index has the highest priotiy and the highest 79index has the lowest priority of being cnfigured */ 80 81MV_U32 pexDevBarPrioTable[] = 82{ 83#if defined(MV_INCLUDE_DEVICE_CS0) 84 DEVICE_CS0, 85#endif 86#if defined(MV_INCLUDE_DEVICE_CS1) 87 DEVICE_CS1, 88#endif 89#if defined(MV_INCLUDE_DEVICE_CS2) 90 DEVICE_CS2, 91#endif 92#if defined(MV_INCLUDE_DEVICE_CS3) 93 DEVICE_CS3, 94#endif 95/* 96#if defined(MV_INCLUDE_DEVICE_CS4) 97 DEVICE_CS4, 98#endif 99*/ 100 TBL_TERM 101}; 102 103 104/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */ 105/* register offsets and its function where its is located. */ 106/* Also, PEX address remap registers offsets are inconsecutive. This struct */ 107/* describes address remap register offsets */ 108typedef struct _pexWinRegInfo 109{ 110 MV_U32 baseLowRegOffs; 111 MV_U32 baseHighRegOffs; 112 MV_U32 sizeRegOffs; 113 MV_U32 remapLowRegOffs; 114 MV_U32 remapHighRegOffs; 115 116}PEX_WIN_REG_INFO; 117 118static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum, 119 MV_ADDR_WIN *pAddrWin); 120static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum, 121 PEX_WIN_REG_INFO *pWinRegInfo); 122 123static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size); 124 125static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin); 126static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum, 127 MV_ADDR_WIN *pAddrWin); 128const MV_8* pexBarNameGet( MV_U32 bar ); 129 130 131/******************************************************************************* 132* mvPexInit - Initialize PEX interfaces 133* 134* DESCRIPTION: 135* 136* This function is responsible of intialization of the Pex Interface , It 137* configure the Pex Bars and Windows in the following manner: 138* 139* Assumptions : 140* Bar0 is always internal registers bar 141* Bar1 is always the DRAM bar 142* Bar2 is always the Device bar 143* 144* 1) Sets the Internal registers bar base by obtaining the base from 145* the CPU Interface 146* 2) Sets the DRAM bar base and size by getting the base and size from 147* the CPU Interface when the size is the sum of all enabled DRAM 148* chip selects and the base is the base of CS0 . 149* 3) Sets the Device bar base and size by getting these values from the 150* CPU Interface when the base is the base of the lowest base of the 151* Device chip selects, and the 152* 153* 154* INPUT: 155* 156* pexIf - PEX interface number. 157* 158* 159* OUTPUT: 160* None. 161* 162* RETURN: 163* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM 164* 165*******************************************************************************/ 166MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType) 167{ 168 MV_U32 bar; 169 MV_U32 winNum; 170 MV_PEX_BAR pexBar; 171 MV_PEX_DEC_WIN pexWin; 172 MV_CPU_DEC_WIN addrDecWin; 173 MV_TARGET target; 174 MV_U32 pexCurrWin=0; 175 MV_U32 status; 176 /* default and exapntion rom 177 are always configured */ 178 179#ifndef MV_DISABLE_PEX_DEVICE_BAR 180 MV_U32 winIndex; 181 MV_U32 maxBase=0, sizeOfMaxBase=0; 182 MV_U32 pexStartWindow; 183#endif 184 185 /* Parameter checking */ 186 if(pexIf >= mvCtrlPexMaxIfGet()) 187 { 188 mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf); 189 return MV_BAD_PARAM; 190 } 191 192 /* Enabled CPU access to PCI-Express */ 193 mvCpuIfEnablePex(pexIf, pexType); 194 195 /* Start with bars */ 196 /* First disable all PEX bars*/ 197 for (bar = 0; bar < PEX_MAX_BARS; bar++) 198 { 199 if (PEX_INTER_REGS_BAR != bar) 200 { 201 if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE)) 202 { 203 mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar); 204 return MV_ERROR; 205 } 206 207 } 208 209 } 210 211 /* and disable all PEX target windows */ 212 for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++) 213 { 214 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE)) 215 { 216 mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n", 217 winNum); 218 return MV_ERROR; 219 220 } 221 } 222 223 /* Now, go through all bars*/ 224 225 226 227/******************************************************************************/ 228/* Internal registers bar */ 229/******************************************************************************/ 230 bar = PEX_INTER_REGS_BAR; 231 232 /* we only open the bar , no need to open windows for this bar */ 233 234 /* first get the CS attribute from the CPU Interface */ 235 if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin)) 236 { 237 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS); 238 return MV_ERROR; 239 } 240 241 pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; 242 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; 243 pexBar.addrWin.size = addrDecWin.addrWin.size; 244 pexBar.enable = MV_TRUE; 245 246 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) 247 { 248 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); 249 return MV_ERROR; 250 } 251 252/******************************************************************************/ 253/* DRAM bar */ 254/******************************************************************************/ 255 256 bar = PEX_DRAM_BAR; 257 258 pexBar.addrWin.size = 0; 259 260 for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ ) 261 { 262 263 status = mvCpuIfTargetWinGet(target,&addrDecWin); 264 265 if((MV_NO_SUCH == status)&&(target != SDRAM_CS0)) 266 { 267 continue; 268 } 269 270 /* first get attributes from CPU If */ 271 if (MV_OK != status) 272 { 273 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target); 274 return MV_ERROR; 275 } 276 if (addrDecWin.enable == MV_TRUE) 277 { 278 /* the base is the base of DRAM CS0 always */ 279 if (SDRAM_CS0 == target ) 280 { 281 pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; 282 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; 283 284 } 285 286 /* increment the bar size to be the sum of the size of all 287 DRAM chips selecs */ 288 pexBar.addrWin.size += addrDecWin.addrWin.size; 289 290 /* set a Pex window for this target ! 291 DRAM CS always will have a Pex Window , and is not a 292 part of the priority table */ 293 pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; 294 pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow; 295 pexWin.addrWin.size = addrDecWin.addrWin.size; 296 297 /* we disable the windows at first because we are not 298 sure that it is witihin bar boundries */ 299 pexWin.enable =MV_FALSE; 300 pexWin.target = target; 301 pexWin.targetBar = bar; 302 303 if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin)) 304 { 305 mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n"); 306 return MV_ERROR; 307 } 308 } 309 } 310 311 /* check if the size of the bar is illeggal */ 312 if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT)) 313 { 314 /* try to get a good size */ 315 pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size, 316 PXBCR_BAR_SIZE_ALIGNMENT); 317 } 318 319 /* check if the size and base are valid */ 320 if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin)) 321 { 322 mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar); 323 mvOsPrintf("it will be disabled\n"); 324 mvOsPrintf("please check Pex and CPU windows configuration\n"); 325 } 326 else 327 { 328 pexBar.enable = MV_TRUE; 329 330 /* configure the bar */ 331 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) 332 { 333 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); 334 return MV_ERROR; 335 } 336 337 /* after the bar was configured then we enable the Pex windows*/ 338 for (winNum = 0;winNum < pexCurrWin ;winNum++) 339 { 340 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE)) 341 { 342 mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum); 343 return MV_ERROR; 344 } 345 346 } 347 } 348 349/******************************************************************************/ 350/* DEVICE bar */ 351/******************************************************************************/ 352 353/* Open the Device BAR for non linux only */ 354#ifndef MV_DISABLE_PEX_DEVICE_BAR 355 356 /* then device bar*/ 357 bar = PEX_DEVICE_BAR; 358 359 /* save the starting window */ 360 pexStartWindow = pexCurrWin; 361 pexBar.addrWin.size = 0; 362 pexBar.addrWin.baseLow = 0xffffffff; 363 pexBar.addrWin.baseHigh = 0; 364 maxBase = 0; 365 366 for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ ) 367 { 368 status = mvCpuIfTargetWinGet(target,&addrDecWin); 369 370 if (MV_NO_SUCH == status) 371 { 372 continue; 373 } 374 375 if (MV_OK != status) 376 { 377 mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target); 378 return MV_ERROR; 379 } 380 381 if (addrDecWin.enable == MV_TRUE) 382 { 383 /* get the minimum base */ 384 if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow) 385 { 386 pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; 387 } 388 389 /* get the maximum base */ 390 if (addrDecWin.addrWin.baseLow > maxBase) 391 { 392 maxBase = addrDecWin.addrWin.baseLow; 393 sizeOfMaxBase = addrDecWin.addrWin.size; 394 } 395 396 /* search in the priority table for this target */ 397 for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM; 398 winIndex++) 399 { 400 if (pexDevBarPrioTable[winIndex] != target) 401 { 402 continue; 403 } 404 else if (pexDevBarPrioTable[winIndex] == target) 405 { 406 /*found it */ 407 408 /* if the index of this target in the prio table is valid 409 then we set the Pex window for this target, a valid index is 410 an index that is lower than the number of the windows that 411 was not configured yet */ 412 413 /* we subtract 2 always because the default and expantion 414 rom windows are always configured */ 415 if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2) 416 { 417 /* set a Pex window for this target ! */ 418 pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; 419 pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow; 420 pexWin.addrWin.size = addrDecWin.addrWin.size; 421 422 /* we disable the windows at first because we are not 423 sure that it is witihin bar boundries */ 424 pexWin.enable = MV_FALSE; 425 pexWin.target = target; 426 pexWin.targetBar = bar; 427 428 if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++, 429 &pexWin)) 430 { 431 mvOsPrintf("mvPexInit: ERR. Window Set failed\n"); 432 return MV_ERROR; 433 } 434 } 435 } 436 } 437 } 438 } 439 440 pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase; 441 pexBar.enable = MV_TRUE; 442 443 /* check if the size of the bar is illegal */ 444 if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT)) 445 { 446 /* try to get a good size */ 447 pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size, 448 PXBCR_BAR_SIZE_ALIGNMENT); 449 } 450 451 /* check if the size and base are valid */ 452 if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin)) 453 { 454 mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar); 455 mvOsPrintf("it will be disabled\n"); 456 mvOsPrintf("please check Pex and CPU windows configuration\n"); 457 } 458 else 459 { 460 if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) 461 { 462 mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); 463 return MV_ERROR; 464 } 465 466 /* now enable the windows */ 467 for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++) 468 { 469 if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE)) 470 { 471 mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n", 472 winNum); 473 return MV_ERROR; 474 } 475 } 476 } 477 478#endif 479 480 return mvPexHalInit(pexIf, pexType); 481 482} 483 484/******************************************************************************* 485* mvPexTargetWinSet - Set PEX to peripheral target address window BAR 486* 487* DESCRIPTION: 488* 489* INPUT: 490* 491* OUTPUT: 492* N/A 493* 494* RETURN: 495* MV_OK if PEX BAR target window was set correctly, 496* MV_BAD_PARAM on bad params 497* MV_ERROR otherwise 498* (e.g. address window overlapps with other active PEX target window). 499* 500*******************************************************************************/ 501MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum, 502 MV_PEX_DEC_WIN *pAddrDecWin) 503{ 504 505 MV_DEC_REGS decRegs; 506 PEX_WIN_REG_INFO winRegInfo; 507 MV_TARGET_ATTRIB targetAttribs; 508 509 /* Parameter checking */ 510 if(pexIf >= mvCtrlPexMaxIfGet()) 511 { 512 mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf); 513 return MV_BAD_PARAM; 514 } 515 516 if (winNum >= PEX_MAX_TARGET_WIN) 517 { 518 mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum); 519 return MV_BAD_PARAM; 520 521 } 522 523 /* get the pex Window registers offsets */ 524 pexWinRegInfoGet(pexIf,winNum,&winRegInfo); 525 526 527 if (MV_TRUE == pAddrDecWin->enable) 528 { 529 530 /* 2) Check if the requested window overlaps with current windows */ 531 if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin)) 532 { 533 mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum); 534 return MV_BAD_PARAM; 535 } 536 537 /* 2) Check if the requested window overlaps with current windows */ 538 if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin)) 539 { 540 mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n", 541 winNum); 542 return MV_BAD_PARAM; 543 } 544 545 } 546 547 548 549 /* read base register*/ 550 551 if (winRegInfo.baseLowRegOffs) 552 { 553 decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs); 554 } 555 else 556 { 557 decRegs.baseReg = 0; 558 } 559 560 if (winRegInfo.sizeRegOffs) 561 { 562 decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs); 563 } 564 else 565 { 566 decRegs.sizeReg =0; 567 } 568 569 if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) 570 { 571 mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n"); 572 return MV_ERROR; 573 } 574 575 /* enable\Disable */ 576 if (MV_TRUE == pAddrDecWin->enable) 577 { 578 decRegs.sizeReg |= PXWCR_WIN_EN; 579 } 580 else 581 { 582 decRegs.sizeReg &= ~PXWCR_WIN_EN; 583 } 584 585 586 /* clear bit location */ 587 decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK; 588 589 /* set bar Mapping */ 590 if (pAddrDecWin->targetBar == 1) 591 { 592 decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1; 593 } 594 else if (pAddrDecWin->targetBar == 2) 595 { 596 decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2; 597 } 598 599 mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs); 600 601 /* set attributes */ 602 decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK; 603 decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS; 604 /* set target ID */ 605 decRegs.sizeReg &= ~PXWCR_TARGET_MASK; 606 decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS; 607 608 609 /* 3) Write to address decode Base Address Register */ 610 611 if (winRegInfo.baseLowRegOffs) 612 { 613 MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg); 614 } 615 616 /* write size reg */ 617 if (winRegInfo.sizeRegOffs) 618 { 619 if ((MV_PEX_WIN_DEFAULT == winNum)|| 620 (MV_PEX_WIN_EXP_ROM == winNum)) 621 { 622 /* clear size because there is no size field*/ 623 decRegs.sizeReg &= ~PXWCR_SIZE_MASK; 624 625 /* clear enable because there is no enable field*/ 626 decRegs.sizeReg &= ~PXWCR_WIN_EN; 627 628 } 629 630 MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg); 631 } 632 633 634 return MV_OK; 635 636} 637 638/******************************************************************************* 639* mvPexTargetWinGet - Get PEX to peripheral target address window 640* 641* DESCRIPTION: 642* Get the PEX to peripheral target address window BAR. 643* 644* INPUT: 645* pexIf - PEX interface number. 646* bar - BAR to be accessed by slave. 647* 648* OUTPUT: 649* pAddrBarWin - PEX target window information data structure. 650* 651* RETURN: 652* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 653* 654*******************************************************************************/ 655MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum, 656 MV_PEX_DEC_WIN *pAddrDecWin) 657{ 658 MV_TARGET_ATTRIB targetAttrib; 659 MV_DEC_REGS decRegs; 660 661 PEX_WIN_REG_INFO winRegInfo; 662 663 /* Parameter checking */ 664 if(pexIf >= mvCtrlPexMaxIfGet()) 665 { 666 mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf); 667 return MV_BAD_PARAM; 668 } 669 670 if (winNum >= PEX_MAX_TARGET_WIN) 671 { 672 mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum); 673 return MV_BAD_PARAM; 674 675 } 676 677 /* get the pex Window registers offsets */ 678 pexWinRegInfoGet(pexIf,winNum,&winRegInfo); 679 680 /* read base register*/ 681 if (winRegInfo.baseLowRegOffs) 682 { 683 decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs); 684 } 685 else 686 { 687 decRegs.baseReg = 0; 688 } 689 690 /* read size reg */ 691 if (winRegInfo.sizeRegOffs) 692 { 693 decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs); 694 } 695 else 696 { 697 decRegs.sizeReg =0; 698 } 699 700 if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin))) 701 { 702 mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n"); 703 return MV_ERROR; 704 705 } 706 707 if (decRegs.sizeReg & PXWCR_WIN_EN) 708 { 709 pAddrDecWin->enable = MV_TRUE; 710 } 711 else 712 { 713 pAddrDecWin->enable = MV_FALSE; 714 715 } 716 717 718 #if 0 719 if (-1 == pAddrDecWin->addrWin.size) 720 { 721 return MV_ERROR; 722 } 723 #endif 724 725 726 /* get target bar */ 727 if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 ) 728 { 729 pAddrDecWin->targetBar = 1; 730 } 731 else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == 732 PXWCR_WIN_BAR_MAP_BAR2 ) 733 { 734 pAddrDecWin->targetBar = 2; 735 } 736 737 /* attrib and targetId */ 738 pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >> 739 PXWCR_ATTRIB_OFFS; 740 pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >> 741 PXWCR_TARGET_OFFS; 742 743 targetAttrib.attrib = pAddrDecWin->attrib; 744 targetAttrib.targetId = pAddrDecWin->targetId; 745 746 pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib); 747 748 return MV_OK; 749 750} 751 752 753/******************************************************************************* 754* mvPexTargetWinEnable - Enable/disable a PEX BAR window 755* 756* DESCRIPTION: 757* This function enable/disable a PEX BAR window. 758* if parameter 'enable' == MV_TRUE the routine will enable the 759* window, thus enabling PEX accesses for that BAR (before enabling the 760* window it is tested for overlapping). Otherwise, the window will 761* be disabled. 762* 763* INPUT: 764* pexIf - PEX interface number. 765* bar - BAR to be accessed by slave. 766* enable - Enable/disable parameter. 767* 768* OUTPUT: 769* None. 770* 771* RETURN: 772* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 773* 774*******************************************************************************/ 775MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable) 776{ 777 PEX_WIN_REG_INFO winRegInfo; 778 MV_PEX_DEC_WIN addrDecWin; 779 780 /* Parameter checking */ 781 if(pexIf >= mvCtrlPexMaxIfGet()) 782 { 783 mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf); 784 return MV_BAD_PARAM; 785 } 786 787 if (winNum >= PEX_MAX_TARGET_WIN) 788 { 789 mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum); 790 return MV_BAD_PARAM; 791 792 } 793 794 795 /* get the pex Window registers offsets */ 796 pexWinRegInfoGet(pexIf,winNum,&winRegInfo); 797 798 799 /* if the address windows is disabled , we only disable the appropriare 800 pex window and ignore other settings */ 801 802 if (MV_FALSE == enable) 803 { 804 805 /* this is not relevant to default and expantion rom 806 windows */ 807 if (winRegInfo.sizeRegOffs) 808 { 809 if ((MV_PEX_WIN_DEFAULT != winNum)&& 810 (MV_PEX_WIN_EXP_ROM != winNum)) 811 { 812 MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN); 813 } 814 } 815 816 } 817 else 818 { 819 if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin)) 820 { 821 mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n"); 822 return MV_ERROR; 823 } 824 825 /* Check if the requested window overlaps with current windows */ 826 if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin)) 827 { 828 mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum); 829 return MV_BAD_PARAM; 830 } 831 832 if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin)) 833 { 834 mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n", 835 winNum); 836 return MV_BAD_PARAM; 837 } 838 839 840 /* this is not relevant to default and expantion rom 841 windows */ 842 if (winRegInfo.sizeRegOffs) 843 { 844 if ((MV_PEX_WIN_DEFAULT != winNum)&& 845 (MV_PEX_WIN_EXP_ROM != winNum)) 846 { 847 MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN); 848 } 849 } 850 851 852 } 853 854 return MV_OK; 855 856} 857 858 859 860/******************************************************************************* 861* mvPexTargetWinRemap - Set PEX to target address window remap. 862* 863* DESCRIPTION: 864* The PEX interface supports remap of the BAR original address window. 865* For each BAR it is possible to define a remap address. For example 866* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified 867* according to remap register but will also be targeted to the 868* SDRAM CS[0]. 869* 870* INPUT: 871* pexIf - PEX interface number. 872* bar - Peripheral target enumerator accessed by slave. 873* pAddrWin - Address window to be checked. 874* 875* OUTPUT: 876* None. 877* 878* RETURN: 879* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 880* 881*******************************************************************************/ 882MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum, 883 MV_PEX_REMAP_WIN *pAddrWin) 884{ 885 886 PEX_WIN_REG_INFO winRegInfo; 887 888 /* Parameter checking */ 889 if (pexIf >= mvCtrlPexMaxIfGet()) 890 { 891 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n", 892 pexIf); 893 return MV_BAD_PARAM; 894 } 895 if (MV_PEX_WIN_DEFAULT == winNum) 896 { 897 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n", 898 winNum); 899 return MV_BAD_PARAM; 900 901 } 902 903 if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT)) 904 { 905 mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\ 906 "\nAddress 0x%08x is unaligned to size 0x%x.\n", 907 pexIf, 908 winNum, 909 pAddrWin->addrWin.baseLow, 910 pAddrWin->addrWin.size); 911 912 return MV_ERROR; 913 } 914 915 pexWinRegInfoGet(pexIf, winNum, &winRegInfo); 916 917 /* Set remap low register value */ 918 MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow); 919 920 /* Skip base high settings if the BAR has only base low (32-bit) */ 921 if (0 != winRegInfo.remapHighRegOffs) 922 { 923 MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh); 924 } 925 926 927 if (pAddrWin->enable == MV_TRUE) 928 { 929 MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); 930 } 931 else 932 { 933 MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); 934 } 935 936 return MV_OK; 937} 938 939/******************************************************************************* 940* mvPexTargetWinRemapEnable - 941* 942* DESCRIPTION: 943* 944* INPUT: 945* 946* OUTPUT: 947* 948* RETURN: 949* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 950* 951*******************************************************************************/ 952 953MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum, 954 MV_BOOL enable) 955{ 956 PEX_WIN_REG_INFO winRegInfo; 957 958 /* Parameter checking */ 959 if (pexIf >= mvCtrlPexMaxIfGet()) 960 { 961 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n", 962 pexIf); 963 return MV_BAD_PARAM; 964 } 965 if (MV_PEX_WIN_DEFAULT == winNum) 966 { 967 mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n", 968 winNum); 969 return MV_BAD_PARAM; 970 971 } 972 973 974 pexWinRegInfoGet(pexIf, winNum, &winRegInfo); 975 976 if (enable == MV_TRUE) 977 { 978 MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); 979 } 980 else 981 { 982 MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); 983 } 984 985 return MV_OK; 986 987} 988 989/******************************************************************************* 990* mvPexBarSet - Set PEX bar address and size 991* 992* DESCRIPTION: 993* 994* INPUT: 995* 996* OUTPUT: 997* None. 998* 999* RETURN: 1000* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 1001* 1002*******************************************************************************/ 1003MV_STATUS mvPexBarSet(MV_U32 pexIf, 1004 MV_U32 barNum, 1005 MV_PEX_BAR *pAddrWin) 1006{ 1007 MV_U32 regBaseLow; 1008 MV_U32 regSize,sizeToReg; 1009 1010 1011 /* check parameters */ 1012 if(pexIf >= mvCtrlPexMaxIfGet()) 1013 { 1014 mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf); 1015 return MV_BAD_PARAM; 1016 } 1017 1018 if(barNum >= PEX_MAX_BARS) 1019 { 1020 mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum); 1021 return MV_BAD_PARAM; 1022 } 1023 1024 1025 if (pAddrWin->addrWin.size == 0) 1026 { 1027 mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" ); 1028 return MV_BAD_PARAM; 1029 } 1030 1031 1032 /* Check if the window complies with PEX spec */ 1033 if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow, 1034 pAddrWin->addrWin.size)) 1035 { 1036 mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum); 1037 return MV_BAD_PARAM; 1038 } 1039 1040 /* 2) Check if the requested bar overlaps with current bars */ 1041 if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin)) 1042 { 1043 mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum); 1044 return MV_BAD_PARAM; 1045 } 1046 1047 /* Get size register value according to window size */ 1048 sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT); 1049 1050 /* Read bar size */ 1051 if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */ 1052 { 1053 regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum)); 1054 1055 /* Size parameter validity check. */ 1056 if (-1 == sizeToReg) 1057 { 1058 mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum); 1059 return MV_BAD_PARAM; 1060 } 1061 1062 regSize &= ~PXBCR_BAR_SIZE_MASK; 1063 regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ; 1064 1065 MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize); 1066 1067 } 1068 1069 /* set size */ 1070 1071 1072 1073 /* Read base address low */ 1074 regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, 1075 PEX_MV_BAR_BASE(barNum))); 1076 1077 /* clear current base */ 1078 if (PEX_INTER_REGS_BAR == barNum) 1079 { 1080 regBaseLow &= ~PXBIR_BASE_MASK; 1081 regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK); 1082 } 1083 else 1084 { 1085 regBaseLow &= ~PXBR_BASE_MASK; 1086 regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK); 1087 } 1088 1089 /* if we had a previous value that contain the bar type (MeM\IO), we want to 1090 restore it */ 1091 regBaseLow |= PEX_BAR_DEFAULT_ATTRIB; 1092 1093 1094 1095 /* write base low */ 1096 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)), 1097 regBaseLow); 1098 1099 if (pAddrWin->addrWin.baseHigh != 0) 1100 { 1101 /* Read base address high */ 1102 MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)), 1103 pAddrWin->addrWin.baseHigh); 1104 1105 } 1106 1107 /* lastly enable the Bar */ 1108 if (pAddrWin->enable == MV_TRUE) 1109 { 1110 if (PEX_INTER_REGS_BAR != barNum) /* internal registers 1111 are enabled always */ 1112 { 1113 MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN); 1114 } 1115 } 1116 else if (MV_FALSE == pAddrWin->enable) 1117 { 1118 if (PEX_INTER_REGS_BAR != barNum) /* internal registers 1119 are enabled always */ 1120 { 1121 MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN); 1122 } 1123 1124 } 1125 1126 1127 1128 return MV_OK; 1129} 1130 1131 1132/******************************************************************************* 1133* mvPexBarGet - Get PEX bar address and size 1134* 1135* DESCRIPTION: 1136* 1137* INPUT: 1138* 1139* OUTPUT: 1140* None. 1141* 1142* RETURN: 1143* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 1144* 1145*******************************************************************************/ 1146 1147MV_STATUS mvPexBarGet(MV_U32 pexIf, 1148 MV_U32 barNum, 1149 MV_PEX_BAR *pAddrWin) 1150{ 1151 /* check parameters */ 1152 if(pexIf >= mvCtrlPexMaxIfGet()) 1153 { 1154 mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf); 1155 return MV_BAD_PARAM; 1156 } 1157 1158 if(barNum >= PEX_MAX_BARS) 1159 { 1160 mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum); 1161 return MV_BAD_PARAM; 1162 } 1163 1164 /* read base low */ 1165 pAddrWin->addrWin.baseLow = 1166 MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum))); 1167 1168 1169 if (PEX_INTER_REGS_BAR == barNum) 1170 { 1171 pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK; 1172 } 1173 else 1174 { 1175 pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK; 1176 } 1177 1178 1179 /* read base high */ 1180 pAddrWin->addrWin.baseHigh = 1181 MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum))); 1182 1183 1184 /* Read bar size */ 1185 if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */ 1186 { 1187 pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum)); 1188 1189 /* check if enable or not */ 1190 if (pAddrWin->addrWin.size & PXBCR_BAR_EN) 1191 { 1192 pAddrWin->enable = MV_TRUE; 1193 } 1194 else 1195 { 1196 pAddrWin->enable = MV_FALSE; 1197 } 1198 1199 /* now get the size */ 1200 pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK; 1201 pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS; 1202 1203 pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size, 1204 PXBCR_BAR_SIZE_ALIGNMENT); 1205 1206 } 1207 else /* PEX_INTER_REGS_BAR */ 1208 { 1209 pAddrWin->addrWin.size = INTER_REGS_SIZE; 1210 pAddrWin->enable = MV_TRUE; 1211 } 1212 1213 1214 return MV_OK; 1215} 1216 1217/******************************************************************************* 1218* mvPexBarEnable - 1219* 1220* DESCRIPTION: 1221* 1222* INPUT: 1223* 1224* OUTPUT: 1225* None. 1226* 1227* RETURN: 1228* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK 1229* 1230*******************************************************************************/ 1231 1232 1233MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable) 1234{ 1235 1236 MV_PEX_BAR pexBar; 1237 1238 /* check parameters */ 1239 if(pexIf >= mvCtrlPexMaxIfGet()) 1240 { 1241 mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf); 1242 return MV_BAD_PARAM; 1243 } 1244 1245 1246 if(barNum >= PEX_MAX_BARS) 1247 { 1248 mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum); 1249 return MV_BAD_PARAM; 1250 } 1251 1252 if (PEX_INTER_REGS_BAR == barNum) 1253 { 1254 if (MV_TRUE == enable) 1255 { 1256 return MV_OK; 1257 } 1258 else 1259 { 1260 return MV_ERROR; 1261 } 1262 } 1263 1264 1265 if (MV_FALSE == enable) 1266 { 1267 /* disable bar and quit */ 1268 MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN); 1269 return MV_OK; 1270 } 1271 1272 /* else */ 1273 1274 if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK) 1275 { 1276 mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n"); 1277 return MV_ERROR; 1278 1279 } 1280 1281 if (MV_TRUE == pexBar.enable) 1282 { 1283 /* it is already enabled !!! */ 1284 return MV_OK; 1285 } 1286 1287 /* else enable the bar*/ 1288 1289 pexBar.enable = MV_TRUE; 1290 1291 if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK) 1292 { 1293 mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n"); 1294 return MV_ERROR; 1295 1296 } 1297 1298 return MV_OK; 1299} 1300 1301 1302/******************************************************************************* 1303* pexWinOverlapDetect - Detect address windows overlapping 1304* 1305* DESCRIPTION: 1306* This function detects address window overlapping of a given address 1307* window in PEX BARs. 1308* 1309* INPUT: 1310* pAddrWin - Address window to be checked. 1311* bar - BAR to be accessed by slave. 1312* 1313* OUTPUT: 1314* None. 1315* 1316* RETURN: 1317* MV_TRUE if the given address window overlap current address 1318* decode map, MV_FALSE otherwise. 1319* 1320*******************************************************************************/ 1321static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf, 1322 MV_U32 winNum, 1323 MV_ADDR_WIN *pAddrWin) 1324{ 1325 MV_U32 win; 1326 MV_PEX_DEC_WIN addrDecWin; 1327 1328 1329 for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++) 1330 { 1331 /* don't check our target or illegal targets */ 1332 if (winNum == win) 1333 { 1334 continue; 1335 } 1336 1337 /* Get window parameters */ 1338 if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin)) 1339 { 1340 mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n", 1341 win); 1342 return MV_ERROR; 1343 } 1344 1345 /* Do not check disabled windows */ 1346 if (MV_FALSE == addrDecWin.enable) 1347 { 1348 continue; 1349 } 1350 1351 1352 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin)) 1353 { 1354 mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n", 1355 winNum, win); 1356 return MV_TRUE; 1357 } 1358 } 1359 1360 return MV_FALSE; 1361} 1362 1363/******************************************************************************* 1364* pexIsWinWithinBar - Detect if address is within PEX bar boundries 1365* 1366* DESCRIPTION: 1367* 1368* INPUT: 1369* 1370* OUTPUT: 1371* None. 1372* 1373* RETURN: 1374* MV_TRUE if the given address window overlap current address 1375* decode map, MV_FALSE otherwise. 1376* 1377*******************************************************************************/ 1378static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf, 1379 MV_ADDR_WIN *pAddrWin) 1380{ 1381 MV_U32 bar; 1382 MV_PEX_BAR addrDecWin; 1383 1384 for(bar = 0; bar < PEX_MAX_BARS; bar++) 1385 { 1386 1387 /* Get window parameters */ 1388 if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin)) 1389 { 1390 mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n"); 1391 return MV_ERROR; 1392 } 1393 1394 /* Do not check disabled bars */ 1395 if (MV_FALSE == addrDecWin.enable) 1396 { 1397 continue; 1398 } 1399 1400 1401 if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin)) 1402 { 1403 return MV_TRUE; 1404 } 1405 } 1406 1407 return MV_FALSE; 1408 1409} 1410 1411/******************************************************************************* 1412* pexBarOverlapDetect - Detect address windows overlapping 1413* 1414* DESCRIPTION: 1415* This function detects address window overlapping of a given address 1416* window in PEX BARs. 1417* 1418* INPUT: 1419* pAddrWin - Address window to be checked. 1420* bar - BAR to be accessed by slave. 1421* 1422* OUTPUT: 1423* None. 1424* 1425* RETURN: 1426* MV_TRUE if the given address window overlap current address 1427* decode map, MV_FALSE otherwise. 1428* 1429*******************************************************************************/ 1430static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf, 1431 MV_U32 barNum, 1432 MV_ADDR_WIN *pAddrWin) 1433{ 1434 MV_U32 bar; 1435 MV_PEX_BAR barDecWin; 1436 1437 1438 for(bar = 0; bar < PEX_MAX_BARS; bar++) 1439 { 1440 /* don't check our target or illegal targets */ 1441 if (barNum == bar) 1442 { 1443 continue; 1444 } 1445 1446 /* Get window parameters */ 1447 if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin)) 1448 { 1449 mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n"); 1450 return MV_ERROR; 1451 } 1452 1453 /* don'nt check disabled bars */ 1454 if (barDecWin.enable == MV_FALSE) 1455 { 1456 continue; 1457 } 1458 1459 1460 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin)) 1461 { 1462 mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n", 1463 barNum, bar); 1464 return MV_TRUE; 1465 } 1466 } 1467 1468 return MV_FALSE; 1469} 1470 1471/******************************************************************************* 1472* pexBarIsValid - Check if the given address window is valid 1473* 1474* DESCRIPTION: 1475* PEX spec restrict BAR base to be aligned to BAR size. 1476* This function checks if the given address window is valid. 1477* 1478* INPUT: 1479* baseLow - 32bit low base address. 1480* size - Window size. 1481* 1482* OUTPUT: 1483* None. 1484* 1485* RETURN: 1486* MV_TRUE if the address window is valid, MV_FALSE otherwise. 1487* 1488*******************************************************************************/ 1489static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size) 1490{ 1491 1492 /* PCI spec restrict BAR base to be aligned to BAR size */ 1493 if(MV_IS_NOT_ALIGN(baseLow, size)) 1494 { 1495 return MV_ERROR; 1496 } 1497 else 1498 { 1499 return MV_TRUE; 1500 } 1501 1502 return MV_TRUE; 1503} 1504 1505/******************************************************************************* 1506* pexBarRegInfoGet - Get BAR register information 1507* 1508* DESCRIPTION: 1509* PEX BARs registers offsets are inconsecutive. 1510* This function gets a PEX BAR register information like register offsets 1511* and function location of the BAR. 1512* 1513* INPUT: 1514* pexIf - PEX interface number. 1515* bar - The PEX BAR in question. 1516* 1517* OUTPUT: 1518* pBarRegInfo - BAR register info struct. 1519* 1520* RETURN: 1521* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK 1522* 1523*******************************************************************************/ 1524static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, 1525 MV_U32 winNum, 1526 PEX_WIN_REG_INFO *pWinRegInfo) 1527{ 1528 1529 if ((winNum >= 0)&&(winNum <=3)) 1530 { 1531 pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum); 1532 pWinRegInfo->baseHighRegOffs = 0; 1533 pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum); 1534 pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum); 1535 pWinRegInfo->remapHighRegOffs = 0; 1536 } 1537 else if ((winNum >= 4)&&(winNum <=5)) 1538 { 1539 pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum); 1540 pWinRegInfo->baseHighRegOffs = 0; 1541 pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum); 1542 pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum); 1543 pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum); 1544 1545 } 1546 else if (MV_PEX_WIN_DEFAULT == winNum) 1547 { 1548 pWinRegInfo->baseLowRegOffs = 0; 1549 pWinRegInfo->baseHighRegOffs = 0; 1550 pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf); 1551 pWinRegInfo->remapLowRegOffs = 0; 1552 pWinRegInfo->remapHighRegOffs = 0; 1553 } 1554 else if (MV_PEX_WIN_EXP_ROM == winNum) 1555 { 1556 pWinRegInfo->baseLowRegOffs = 0; 1557 pWinRegInfo->baseHighRegOffs = 0; 1558 pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf); 1559 pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf); 1560 pWinRegInfo->remapHighRegOffs = 0; 1561 1562 } 1563 1564 return MV_OK; 1565} 1566 1567/******************************************************************************* 1568* pexBarNameGet - Get the string name of PEX BAR. 1569* 1570* DESCRIPTION: 1571* This function get the string name of PEX BAR. 1572* 1573* INPUT: 1574* bar - PEX bar number. 1575* 1576* OUTPUT: 1577* None. 1578* 1579* RETURN: 1580* pointer to the string name of PEX BAR. 1581* 1582*******************************************************************************/ 1583const MV_8* pexBarNameGet( MV_U32 bar ) 1584{ 1585 switch( bar ) 1586 { 1587 case PEX_INTER_REGS_BAR: 1588 return "Internal Regs Bar0...."; 1589 case PEX_DRAM_BAR: 1590 return "DRAM Bar1............."; 1591 case PEX_DEVICE_BAR: 1592 return "Devices Bar2.........."; 1593 default: 1594 return "Bar unknown"; 1595 } 1596} 1597/******************************************************************************* 1598* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows). 1599* 1600* DESCRIPTION: 1601* This function print the PEX address decode map (BARs and windows). 1602* 1603* INPUT: 1604* None. 1605* 1606* OUTPUT: 1607* None. 1608* 1609* RETURN: 1610* None. 1611* 1612*******************************************************************************/ 1613MV_VOID mvPexAddrDecShow(MV_VOID) 1614{ 1615 MV_PEX_BAR pexBar; 1616 MV_PEX_DEC_WIN win; 1617 MV_U32 pexIf; 1618 MV_U32 bar,winNum; 1619 1620 for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ ) 1621 { 1622 if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue; 1623 mvOsOutput( "\n" ); 1624 mvOsOutput( "PEX%d:\n", pexIf ); 1625 mvOsOutput( "-----\n" ); 1626 1627 mvOsOutput( "\nPex Bars \n\n"); 1628 1629 for( bar = 0; bar < PEX_MAX_BARS; bar++ ) 1630 { 1631 memset( &pexBar, 0, sizeof(MV_PEX_BAR) ); 1632 1633 mvOsOutput( "%s ", pexBarNameGet(bar) ); 1634 1635 if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK ) 1636 { 1637 if( pexBar.enable ) 1638 { 1639 mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow ); 1640 mvSizePrint( pexBar.addrWin.size ); 1641 mvOsOutput( "\n" ); 1642 } 1643 else 1644 mvOsOutput( "disable\n" ); 1645 } 1646 } 1647 mvOsOutput( "\nPex Decode Windows\n\n"); 1648 1649 for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++) 1650 { 1651 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) ); 1652 1653 mvOsOutput( "win%d - ", winNum ); 1654 1655 if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK) 1656 { 1657 if (win.enable) 1658 { 1659 mvOsOutput( "%s base %08x, ", 1660 mvCtrlTargetNameGet(win.target), win.addrWin.baseLow ); 1661 mvOsOutput( "...." ); 1662 mvSizePrint( win.addrWin.size ); 1663 1664 mvOsOutput( "\n" ); 1665 } 1666 else 1667 mvOsOutput( "disable\n" ); 1668 1669 1670 } 1671 } 1672 1673 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) ); 1674 1675 mvOsOutput( "default win - " ); 1676 1677 if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK) 1678 { 1679 mvOsOutput( "%s ", 1680 mvCtrlTargetNameGet(win.target) ); 1681 mvOsOutput( "\n" ); 1682 } 1683 memset( &win, 0,sizeof(MV_PEX_DEC_WIN) ); 1684 1685 mvOsOutput( "Expansion ROM - " ); 1686 1687 if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK) 1688 { 1689 mvOsOutput( "%s ", 1690 mvCtrlTargetNameGet(win.target) ); 1691 mvOsOutput( "\n" ); 1692 } 1693 1694 } 1695} 1696 1697 1698