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 66/* includes */ 67#include "ctrlEnv/sys/mvAhbToMbus.h" 68#include "ctrlEnv/mvCtrlEnvAddrDec.h" 69 70#undef MV_DEBUG 71/* defines */ 72#ifdef MV_DEBUG 73 #define DB(x) x 74#else 75 #define DB(x) 76#endif 77 78/* typedefs */ 79 80 81/* CPU address remap registers offsets are inconsecutive. This struct */ 82/* describes address remap register offsets */ 83typedef struct _ahbToMbusRemapRegOffs 84{ 85 MV_U32 lowRegOffs; /* Low 32-bit remap register offset */ 86 MV_U32 highRegOffs; /* High 32 bit remap register offset */ 87}AHB_TO_MBUS_REMAP_REG_OFFS; 88 89/* locals */ 90static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum, 91 AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs); 92 93/******************************************************************************* 94* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map ! 95* 96* DESCRIPTION: 97* 98* INPUT: 99* None. 100* 101* OUTPUT: 102* None. 103* 104* RETURN: 105* MV_OK laways. 106* 107*******************************************************************************/ 108MV_STATUS mvAhbToMbusInit(void) 109{ 110 return MV_OK; 111 112} 113 114/******************************************************************************* 115* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window 116* 117* DESCRIPTION: 118* This function sets 119* address window, also known as address decode window. 120* A new address decode window is set for specified winNum address window. 121* If address decode window parameter structure enables the window, 122* the routine will also enable the winNum window, allowing CPU to access 123* the winNum window. 124* 125* INPUT: 126* winNum - Windows number. 127* pAddrDecWin - CPU winNum window data structure. 128* 129* OUTPUT: 130* N/A 131* 132* RETURN: 133* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of 134* address window overlapps with other active CPU winNum window or 135* trying to assign 36bit base address while CPU does not support that. 136* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported. 137* 138*******************************************************************************/ 139MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin) 140{ 141 MV_TARGET_ATTRIB targetAttribs; 142 MV_DEC_REGS decRegs; 143 144 /* Parameter checking */ 145 if (winNum >= MAX_AHB_TO_MBUS_WINS) 146 { 147 mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum); 148 return MV_NOT_SUPPORTED; 149 } 150 151 152 /* read base register*/ 153 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 154 { 155 decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum)); 156 } 157 else 158 { 159 decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG); 160 } 161 162 /* check if address is aligned to the size */ 163 if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) 164 { 165 mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\ 166 "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n", 167 winNum, 168 mvCtrlTargetNameGet(pAddrDecWin->target), 169 pAddrDecWin->addrWin.baseLow, 170 pAddrDecWin->addrWin.size); 171 return MV_ERROR; 172 } 173 174 /* read control register*/ 175 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 176 { 177 decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum)); 178 } 179 180 if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) 181 { 182 mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n"); 183 return MV_ERROR; 184 } 185 186 /* enable\Disable */ 187 if (MV_TRUE == pAddrDecWin->enable) 188 { 189 decRegs.sizeReg |= ATMWCR_WIN_ENABLE; 190 } 191 else 192 { 193 decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE; 194 } 195 196 mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs); 197 198 /* set attributes */ 199 decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK; 200 decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS; 201 /* set target ID */ 202 decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK; 203 decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS; 204 205#if !defined(MV_RUN_FROM_FLASH) 206 /* To be on the safe side we disable the window before writing the */ 207 /* new values. */ 208 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 209 { 210 mvAhbToMbusWinEnable(winNum,MV_FALSE); 211 } 212#endif 213 214 /* 3) Write to address decode Base Address Register */ 215 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 216 { 217 MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg); 218 } 219 else 220 { 221 MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg); 222 } 223 224 225 /* Internal register space have no size */ 226 /* register. Do not perform size register assigment for those targets */ 227 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 228 { 229 /* Write to address decode Size Register */ 230 MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg); 231 } 232 233 return MV_OK; 234} 235 236/******************************************************************************* 237* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window 238* 239* DESCRIPTION: 240* Get the CPU peripheral winNum address window. 241* 242* INPUT: 243* winNum - Peripheral winNum enumerator 244* 245* OUTPUT: 246* pAddrDecWin - CPU winNum window information data structure. 247* 248* RETURN: 249* MV_OK if winNum exist, MV_ERROR otherwise. 250* 251*******************************************************************************/ 252MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin) 253{ 254 MV_DEC_REGS decRegs; 255 MV_TARGET_ATTRIB targetAttrib; 256 257 258 /* Parameter checking */ 259 if (winNum >= MAX_AHB_TO_MBUS_WINS) 260 { 261 mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum); 262 return MV_NOT_SUPPORTED; 263 } 264 265 266 /* Internal register space size have no size register*/ 267 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 268 { 269 decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum)); 270 } 271 else 272 { 273 decRegs.sizeReg = 0; 274 } 275 276 277 /* Read base and size */ 278 if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) 279 { 280 decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum)); 281 } 282 else 283 { 284 decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG); 285 } 286 287 288 289 if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin))) 290 { 291 mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n"); 292 return MV_ERROR; 293 } 294 295 if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) 296 { 297 pAddrDecWin->addrWin.size = INTER_REGS_SIZE; 298 pAddrDecWin->target = INTER_REGS; 299 pAddrDecWin->enable = MV_TRUE; 300 301 return MV_OK; 302 } 303 304 305 if (decRegs.sizeReg & ATMWCR_WIN_ENABLE) 306 { 307 pAddrDecWin->enable = MV_TRUE; 308 } 309 else 310 { 311 pAddrDecWin->enable = MV_FALSE; 312 313 } 314 315 316 317 if (-1 == pAddrDecWin->addrWin.size) 318 { 319 return MV_ERROR; 320 } 321 322 /* attrib and targetId */ 323 targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >> 324 ATMWCR_WIN_ATTR_OFFS; 325 targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >> 326 ATMWCR_WIN_TARGET_OFFS; 327 328 pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib); 329 330 return MV_OK; 331} 332 333/******************************************************************************* 334* mvAhbToMbusWinTargetGet - Get Window number associated with target 335* 336* DESCRIPTION: 337* 338* INPUT: 339* 340* OUTPUT: 341* 342* RETURN: 343* 344*******************************************************************************/ 345MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target) 346{ 347 MV_AHB_TO_MBUS_DEC_WIN decWin; 348 MV_U32 winNum; 349 350 /* Check parameters */ 351 if (target >= MAX_TARGETS) 352 { 353 mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target); 354 return 0xffffffff; 355 } 356 357 if (INTER_REGS == target) 358 { 359 return MV_AHB_TO_MBUS_INTREG_WIN; 360 } 361 362 for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++) 363 { 364 if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) 365 continue; 366 367 if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK) 368 { 369 mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n"); 370 return 0xffffffff; 371 372 } 373 374 if (decWin.enable == MV_TRUE) 375 { 376 if (decWin.target == target) 377 { 378 return winNum; 379 } 380 381 } 382 383 } 384 385 return 0xFFFFFFFF; 386 387 388} 389 390/******************************************************************************* 391* mvAhbToMbusWinAvailGet - Get First Available window number. 392* 393* DESCRIPTION: 394* 395* INPUT: 396* 397* OUTPUT: 398* 399* RETURN: 400* 401*******************************************************************************/ 402MV_U32 mvAhbToMbusWinAvailGet(MV_VOID) 403{ 404 MV_AHB_TO_MBUS_DEC_WIN decWin; 405 MV_U32 winNum; 406 407 for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++) 408 { 409 if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) 410 continue; 411 412 if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK) 413 { 414 mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n"); 415 return 0xffffffff; 416 417 } 418 419 if (decWin.enable == MV_FALSE) 420 { 421 return winNum; 422 } 423 424 } 425 426 return 0xFFFFFFFF; 427} 428 429 430/******************************************************************************* 431* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window 432* 433* DESCRIPTION: 434* This function enable/disable a CPU address decode window. 435* if parameter 'enable' == MV_TRUE the routine will enable the 436* window, thus enabling CPU accesses (before enabling the window it is 437* tested for overlapping). Otherwise, the window will be disabled. 438* 439* INPUT: 440* winNum - Peripheral winNum enumerator. 441* enable - Enable/disable parameter. 442* 443* OUTPUT: 444* N/A 445* 446* RETURN: 447* MV_ERROR if protection window number was wrong, or the window 448* overlapps other winNum window. 449* 450*******************************************************************************/ 451MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable) 452{ 453 454 /* Parameter checking */ 455 if (winNum >= MAX_AHB_TO_MBUS_WINS) 456 { 457 mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum); 458 return MV_NOT_SUPPORTED; 459 } 460 461 /* Internal registers bar can't be disable or enabled */ 462 if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) 463 { 464 return (enable ? MV_OK : MV_ERROR); 465 } 466 467 if (enable == MV_TRUE) 468 { 469 /* enable the window */ 470 MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE); 471 } 472 else 473 { /* Disable address decode winNum window */ 474 MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE); 475 } 476 477 return MV_OK; 478} 479 480 481/******************************************************************************* 482* mvAhbToMbusWinRemap - Set CPU remap register for address windows. 483* 484* DESCRIPTION: 485* After a CPU address hits one of PCI address decode windows there is an 486* option to remap the address to a different one. For example, CPU 487* executes a read from PCI winNum window address 0x1200.0000. This 488* can be modified so the address on the PCI bus would be 0x1400.0000 489* Using the PCI address remap mechanism. 490* 491* INPUT: 492* winNum - Peripheral winNum enumerator. Must be a PCI winNum. 493* pAddrDecWin - CPU winNum window information data structure. 494* Note that caller has to fill in the base field only. The 495* size field is ignored. 496* 497* OUTPUT: 498* None. 499* 500* RETURN: 501* MV_ERROR if winNum is not a PCI one, MV_OK otherwise. 502* 503*******************************************************************************/ 504MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin) 505{ 506 MV_U32 baseAddr; 507 AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs; 508 509 MV_U32 effectiveBaseAddress=0, 510 baseAddrValue=0,windowSizeValue=0; 511 512 513 /* Get registers offsets of given winNum */ 514 if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs)) 515 { 516 return 0xffffffff; 517 } 518 519 /* 1) Set address remap low */ 520 baseAddr = pAddrWin->baseLow; 521 522 /* Check base address aligment */ 523 /* 524 if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT)) 525 { 526 mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n", 527 baseAddr); 528 return MV_ERROR; 529 } 530 */ 531 532 /* BaseLow[31:16] => base register [31:16] */ 533 baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK; 534 535 MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr); 536 537 MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh); 538 539 540 baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum)); 541 windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum)); 542 543 baseAddrValue &= ATMWBR_BASE_MASK; 544 windowSizeValue &=ATMWCR_WIN_SIZE_MASK; 545 546 /* Start calculating the effective Base Address */ 547 effectiveBaseAddress = baseAddrValue ; 548 549 /* The effective base address will be combined from the chopped (if any) 550 remap value (according to the size value and remap mechanism) and the 551 window's base address */ 552 effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow); 553 /* If the effectiveBaseAddress exceed the window boundaries return an 554 invalid value. */ 555 556 if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff))) 557 { 558 mvOsPrintf("mvAhbToMbusPciRemap: Error\n"); 559 return 0xffffffff; 560 } 561 562 return effectiveBaseAddress; 563 564 565} 566/******************************************************************************* 567* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets 568* 569* DESCRIPTION: 570* 571* INPUT: 572* target1 - CPU Interface target 1 573* target2 - CPU Interface target 2 574* 575* OUTPUT: 576* None. 577* 578* RETURN: 579* MV_ERROR if targets are illigal, or if one of the targets is not 580* associated to a valid window . 581* MV_OK otherwise. 582* 583*******************************************************************************/ 584 585 586MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2) 587{ 588 MV_U32 winNum1,winNum2; 589 MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp; 590 AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2; 591 MV_U32 remapBaseLow1=0,remapBaseLow2=0; 592 MV_U32 remapBaseHigh1=0,remapBaseHigh2=0; 593 594 595 /* Check parameters */ 596 if (target1 >= MAX_TARGETS) 597 { 598 mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1); 599 return MV_ERROR; 600 } 601 602 if (target2 >= MAX_TARGETS) 603 { 604 mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1); 605 return MV_ERROR; 606 } 607 608 609 /* get window associated with this target */ 610 winNum1 = mvAhbToMbusWinTargetGet(target1); 611 612 if (winNum1 == 0xffffffff) 613 { 614 mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n", 615 target1,winNum1); 616 return MV_ERROR; 617 618 } 619 620 /* get window associated with this target */ 621 winNum2 = mvAhbToMbusWinTargetGet(target2); 622 623 if (winNum2 == 0xffffffff) 624 { 625 mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n", 626 target2,winNum2); 627 return MV_ERROR; 628 629 } 630 631 /* now Get original values of both Windows */ 632 if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1)) 633 { 634 mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n", 635 winNum1); 636 return MV_ERROR; 637 638 } 639 if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2)) 640 { 641 mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n", 642 winNum2); 643 return MV_ERROR; 644 645 } 646 647 648 /* disable both windows */ 649 if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE)) 650 { 651 mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n", 652 winNum1); 653 return MV_ERROR; 654 655 } 656 if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE)) 657 { 658 mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n", 659 winNum2); 660 return MV_ERROR; 661 662 } 663 664 665 /* now swap targets */ 666 667 /* first save winDec2 values */ 668 winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh; 669 winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow; 670 winDecTemp.addrWin.size = winDec2.addrWin.size; 671 winDecTemp.enable = winDec2.enable; 672 winDecTemp.target = winDec2.target; 673 674 /* winDec2 = winDec1 */ 675 winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh; 676 winDec2.addrWin.baseLow = winDec1.addrWin.baseLow; 677 winDec2.addrWin.size = winDec1.addrWin.size; 678 winDec2.enable = winDec1.enable; 679 winDec2.target = winDec1.target; 680 681 682 /* winDec1 = winDecTemp */ 683 winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh; 684 winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow; 685 winDec1.addrWin.size = winDecTemp.addrWin.size; 686 winDec1.enable = winDecTemp.enable; 687 winDec1.target = winDecTemp.target; 688 689 690 /* now set the new values */ 691 692 693 mvAhbToMbusWinSet(winNum1,&winDec1); 694 mvAhbToMbusWinSet(winNum2,&winDec2); 695 696 697 698 699 700 /* now we will treat the remap windows if exist */ 701 702 703 /* now check if one or both windows has a remap window 704 as well after the swap ! */ 705 706 /* if a window had a remap value differnt than the base value 707 before the swap , then after the swap the remap value will be 708 equal to the base value unless both windows has a remap windows*/ 709 710 /* first get old values */ 711 if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1)) 712 { 713 remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs); 714 remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs); 715 716 } 717 if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2)) 718 { 719 remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs); 720 remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs); 721 722 723 } 724 725 /* now do the swap */ 726 if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1)) 727 { 728 if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2)) 729 { 730 /* Two windows has a remap !!! so swap */ 731 732 MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1); 733 MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1); 734 735 MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2); 736 MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2); 737 738 739 740 } 741 else 742 { 743 /* remap == base */ 744 MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh); 745 MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow); 746 747 } 748 749 } 750 else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2)) 751 { 752 /* remap == base */ 753 MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh); 754 MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow); 755 756 } 757 758 759 760 return MV_OK; 761 762 763} 764 765 766 767#if defined(MV_88F1181) 768 769/******************************************************************************* 770* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration. 771* 772* DESCRIPTION: 773* This function sets CPU Mbus Arbiter 774* 775* INPUT: 776* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At 777* each clock cycle, the crossbar arbiter samples all 778* requests and gives the bus to the next agent according 779* to the "pizza". 780* 781* OUTPUT: 782* N/A 783* 784* RETURN: 785* MV_ERROR if paramers to function invalid. 786* 787*******************************************************************************/ 788MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray) 789{ 790 MV_U32 sliceNum; 791 MV_U32 xbarCtrl = 0; 792 MV_MBUS_ARB_TARGET xbarTarget; 793 794 /* 1) Set crossbar control low register */ 795 for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++) 796 { 797 xbarTarget = pPizzaArbArray[sliceNum]; 798 799 /* sliceNum parameter check */ 800 if (xbarTarget > MAX_MBUS_ARB_TARGETS) 801 { 802 mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n", 803 xbarTarget); 804 return MV_ERROR; 805 } 806 xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum)); 807 } 808 /* Write to crossbar control low register */ 809 MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl); 810 811 xbarCtrl = 0; 812 813 /* 2) Set crossbar control high register */ 814 for (sliceNum = MRLR_SLICE_NUM; 815 sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM; 816 sliceNum++) 817 { 818 819 xbarTarget = pPizzaArbArray[sliceNum]; 820 821 /* sliceNum parameter check */ 822 if (xbarTarget > MAX_MBUS_ARB_TARGETS) 823 { 824 mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n", 825 xbarTarget); 826 return MV_ERROR; 827 } 828 xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum)); 829 } 830 /* Write to crossbar control high register */ 831 MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl); 832 833 return MV_OK; 834} 835 836/******************************************************************************* 837* mvMbusArbCtrlSet - Set MBus Arbiter control register 838* 839* DESCRIPTION: 840* 841* INPUT: 842* ctrl - pointer to MV_MBUS_ARB_CTRL register 843* 844* OUTPUT: 845* N/A 846* 847* RETURN: 848* MV_ERROR if paramers to function invalid. 849* 850*******************************************************************************/ 851MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl) 852{ 853 854 if (ctrl->highPrio == MV_FALSE) 855 { 856 MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP); 857 } 858 else 859 { 860 MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP); 861 } 862 863 if (ctrl->fixedRoundRobin == MV_FALSE) 864 { 865 MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED); 866 } 867 else 868 { 869 MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED); 870 } 871 872 if (ctrl->starvEn == MV_FALSE) 873 { 874 MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN); 875 } 876 else 877 { 878 MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN); 879 } 880 881 return MV_OK; 882} 883 884/******************************************************************************* 885* mvMbusArbCtrlGet - Get MBus Arbiter control register 886* 887* DESCRIPTION: 888* 889* INPUT: 890* ctrl - pointer to MV_MBUS_ARB_CTRL register 891* 892* OUTPUT: 893* ctrl - pointer to MV_MBUS_ARB_CTRL register 894* 895* RETURN: 896* MV_ERROR if paramers to function invalid. 897* 898*******************************************************************************/ 899MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl) 900{ 901 902 MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG); 903 904 if (ctrlReg & MACR_ARB_ARM_TOP) 905 { 906 ctrl->highPrio = MV_TRUE; 907 } 908 else 909 { 910 ctrl->highPrio = MV_FALSE; 911 } 912 913 if (ctrlReg & MACR_ARB_TARGET_FIXED) 914 { 915 ctrl->fixedRoundRobin = MV_TRUE; 916 } 917 else 918 { 919 ctrl->fixedRoundRobin = MV_FALSE; 920 } 921 922 if (ctrlReg & MACR_ARB_REQ_CTRL_EN) 923 { 924 ctrl->starvEn = MV_TRUE; 925 } 926 else 927 { 928 ctrl->starvEn = MV_FALSE; 929 } 930 931 932 return MV_OK; 933} 934 935#endif /* #if defined(MV_88F1181) */ 936 937 938 939/******************************************************************************* 940* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets 941* 942* DESCRIPTION: 943* CPU to PCI address remap registers offsets are inconsecutive. 944* This function returns PCI address remap registers offsets. 945* 946* INPUT: 947* winNum - Address decode window number. See MV_U32 enumerator. 948* 949* OUTPUT: 950* None. 951* 952* RETURN: 953* MV_ERROR if winNum is not a PCI one. 954* 955*******************************************************************************/ 956static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum, 957 AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs) 958{ 959 switch (winNum) 960 { 961 case 0: 962 case 1: 963 pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum); 964 pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum); 965 break; 966 case 2: 967 case 3: 968 if((mvCtrlModelGet() == MV_5281_DEV_ID) || 969 (mvCtrlModelGet() == MV_1281_DEV_ID) || 970 (mvCtrlModelGet() == MV_6183_DEV_ID) || 971 (mvCtrlModelGet() == MV_6183L_DEV_ID)) 972 { 973 pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum); 974 pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum); 975 break; 976 } 977 else 978 { 979 pRemapRegs->lowRegOffs = 0; 980 pRemapRegs->highRegOffs = 0; 981 982 DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n", 983 winNum)); 984 return MV_NO_SUCH; 985 } 986 default: 987 { 988 pRemapRegs->lowRegOffs = 0; 989 pRemapRegs->highRegOffs = 0; 990 991 DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n", 992 winNum)); 993 return MV_NO_SUCH; 994 } 995 } 996 997 return MV_OK; 998} 999 1000/******************************************************************************* 1001* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map. 1002* 1003* DESCRIPTION: 1004* This function print the CPU address decode map. 1005* 1006* INPUT: 1007* None. 1008* 1009* OUTPUT: 1010* None. 1011* 1012* RETURN: 1013* None. 1014* 1015*******************************************************************************/ 1016MV_VOID mvAhbToMbusAddDecShow(MV_VOID) 1017{ 1018 MV_AHB_TO_MBUS_DEC_WIN win; 1019 MV_U32 winNum; 1020 mvOsOutput( "\n" ); 1021 mvOsOutput( "AHB To MBUS Bridge:\n" ); 1022 mvOsOutput( "-------------------\n" ); 1023 1024 for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ ) 1025 { 1026 memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) ); 1027 1028 mvOsOutput( "win%d - ", winNum ); 1029 1030 if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK ) 1031 { 1032 if( win.enable ) 1033 { 1034 mvOsOutput( "%s base %08x, ", 1035 mvCtrlTargetNameGet(win.target), win.addrWin.baseLow ); 1036 mvOsOutput( "...." ); 1037 mvSizePrint( win.addrWin.size ); 1038 1039 mvOsOutput( "\n" ); 1040 1041 } 1042 else 1043 mvOsOutput( "disable\n" ); 1044 } 1045 } 1046 1047} 1048 1049