/******************************************************************************* * mvCpuIfAddDecShow - Print the CPU address decode map. * * DESCRIPTION: * This function print the CPU address decode map. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * None. * *******************************************************************************/ MV_VOID mvCpuIfAddDecShow(MV_VOID) { MV_CPU_DEC_WIN win; MV_U32 target; mvOsOutput( "\n" ); mvOsOutput( "CPU Interface\n" ); mvOsOutput( "-------------\n" ); for( target = 0; target < MAX_TARGETS; target++ ) { memset( &win, 0, sizeof(MV_CPU_DEC_WIN) ); mvOsOutput( "%s ",mvCtrlTargetNameGet(target)); mvOsOutput( "...." ); if( mvCpuIfTargetWinGet( target, &win ) == MV_OK ) { if( win.enable ) { mvOsOutput( "base %08x, ", win.addrWin.baseLow ); mvSizePrint( win.addrWin.size ); mvOsOutput( "\n" ); } else mvOsOutput( "disable\n" ); } else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH ) { mvOsOutput( "no such\n" ); } } }
/******************************************************************************* * mvCpuIfTargetWinSizeGet - Get CPU target address window size * * DESCRIPTION: * Get the size of CPU-to-peripheral target window. * * INPUT: * target - Peripheral target enumerator * * OUTPUT: * None. * * RETURN: * 32bit size. Function also returns '0' if window is closed. * Function returns 0xFFFFFFFF in case of an error. * *******************************************************************************/ MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target) { MV_CPU_DEC_WIN addrDecWin; target = MV_CHANGE_BOOT_CS(target); /* Check parameters */ if (target >= MAX_TARGETS) { mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is illegal\n", target); return 0; } /* Get the winNum window */ if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin)) { mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n", target); return 0; } /* Check if window is enabled */ if (addrDecWin.enable == MV_TRUE) { return (addrDecWin.addrWin.size); } else { return 0; /* Window disabled. return 0 */ } }
/******************************************************************************* * mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high * * DESCRIPTION: * CPU-to-peripheral target address window base is constructed of * two parts: Low and high. * This function gets the CPU peripheral target high base address. * * INPUT: * target - Peripheral target enumerator * * OUTPUT: * None. * * RETURN: * 32bit high base address. * *******************************************************************************/ MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target) { MV_CPU_DEC_WIN addrDecWin; target = MV_CHANGE_BOOT_CS(target); /* Check parameters */ if (target >= MAX_TARGETS) { mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is illegal\n", target); return 0xffffffff; } /* Get the target window */ if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin)) { mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n", target); return 0xffffffff; } if (MV_FALSE == addrDecWin.enable) { return 0; } return (addrDecWin.addrWin.baseHigh); }
/******************************************************************************* * cpuTargetWinOverlap - Detect CPU address decode windows overlapping * * DESCRIPTION: * An unpredicted behaviur is expected in case CPU address decode * windows overlapps. * This function detects CPU address decode windows overlapping of a * specified target. The function does not check the target itself for * overlapping. The function also skipps disabled address decode windows. * * INPUT: * target - Peripheral target enumerator. * pAddrDecWin - An address decode window struct. * * OUTPUT: * None. * * RETURN: * MV_TRUE if the given address window overlaps current address * decode map, MV_FALSE otherwise. * *******************************************************************************/ static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin) { MV_U32 targetNum; MV_CPU_DEC_WIN addrDecWin; MV_STATUS status; for (targetNum = 0; targetNum < MAX_TARGETS; targetNum++) { /* don't check our target or illegal targets */ if (targetNum == target) continue; /* Get window parameters */ status = mvCpuIfTargetWinGet(targetNum, &addrDecWin); if (MV_NO_SUCH == status) continue; if (MV_OK != status) { DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n")); return MV_TRUE; } /* Do not check disabled windows */ if (MV_FALSE == addrDecWin.enable) continue; if (MV_TRUE == mvWinOverlapTest(pAddrWin, &addrDecWin.addrWin)) { DB(mvOsPrintf("cpuTargetWinOverlap: Required target %d overlap current %d\n", target, targetNum)); return MV_TRUE; } } return MV_FALSE; }
MV_STATUS mvCtrlAddrWinInfoGet(MV_UNIT_WIN_INFO *pAddrWinInfo, MV_ULONG physAddr) { MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 i; MV_TARGET_ATTRIB targetAttrib; MV_STATUS status; for (i = 0; i < MAX_TARGETS; i++) { status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin); if (status != MV_OK) continue; if ((physAddr >= cpuAddrDecWin.addrWin.baseLow) && (physAddr < cpuAddrDecWin.addrWin.baseLow + cpuAddrDecWin.addrWin.size)) { /* Found */ pAddrWinInfo->addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; pAddrWinInfo->addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; pAddrWinInfo->addrWin.size = cpuAddrDecWin.addrWin.size; if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) { mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCtrlAttribGet() failed.\n"); return MV_ERROR; } pAddrWinInfo->attrib = targetAttrib.attrib; pAddrWinInfo->targetId = targetAttrib.targetId; return MV_OK; } } /* not found */ return MV_NOT_FOUND; }
/******************************************************************************* * mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window * * DESCRIPTION: * This function enable/disable a CPU address decode window. * if parameter 'enable' == MV_TRUE the routine will enable the * window, thus enabling CPU accesses (before enabling the window it is * tested for overlapping). Otherwise, the window will be disabled. * * INPUT: * target - Peripheral target enumerator. * enable - Enable/disable parameter. * * OUTPUT: * N/A * * RETURN: * MV_ERROR if protection window number was wrong, or the window * overlapps other target window. * *******************************************************************************/ MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable) { MV_U32 winNum, temp; MV_CPU_DEC_WIN addrDecWin; /* Check parameters */ if (target >= MAX_TARGETS) { mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target); return MV_ERROR; } /* get the window and check if it exist */ temp = mvCpuIfTargetWinGet(target, &addrDecWin); if (MV_NO_SUCH == temp) { return (enable? MV_ERROR: MV_OK); } else if( MV_OK != temp) { mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target); return MV_ERROR; } /* check overlap */ if (MV_TRUE == enable) { if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin)) { DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target)); return MV_ERROR; } } if (!MV_TARGET_IS_DRAM(target)) { /* get the Window number associated with this target */ winNum = mvAhbToMbusWinTargetGet(target); if (winNum >= MAX_AHB_TO_MBUS_WINS) { return (enable? MV_ERROR: MV_OK); } if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK) { mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n", winNum); return MV_ERROR; } } return MV_OK; }
static MV_STATUS mvXorInitWinsUnit (MV_U32 unit) { MV_U32 winNum; MV_XOR_DEC_WIN addrDecWin; MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 status; MV_U32 winPrioIndex=0; /* Initiate XOR address decode */ /* First disable all address decode windows */ for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++) { mvXorTargetWinEnable(unit,winNum, MV_FALSE); } /* Go through all windows in user table until table terminator */ for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < XOR_MAX_ADDR_DEC_WIN));) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { addrDecWin.target = xorAddrDecPrioTap[winPrioIndex]; addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size; addrDecWin.enable = MV_TRUE; if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin)) { DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n")); return MV_ERROR; } winNum++; } winPrioIndex++; } return MV_OK; }
/******************************************************************************* * mvSdmmcWinInit - Initialize the integrated SDMMC target address window. * * DESCRIPTION: * Initialize the SDMMC peripheral target address window. * * INPUT: * * * OUTPUT: * * * RETURN: * MV_ERROR if register parameters are invalid. * *******************************************************************************/ MV_STATUS mvSdmmcWinInit(MV_VOID) { int winNum; MV_SDMMC_DEC_WIN sdmmcWin; MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 status, winPrioIndex = 0; /* Initiate Sdmmc address decode */ /* First disable all address decode windows */ for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++) { MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum)); regVal &= ~MV_SDMMC_WIN_ENABLE_MASK; MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal); } winNum = 0; while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) && (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) ) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size; sdmmcWin.enable = MV_TRUE; sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex]; if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin)) { return MV_ERROR; } winNum++; } winPrioIndex++; } return MV_OK; }
/******************************************************************************* * cpuTargetWinOverlap - Detect CPU address decode windows overlapping * * DESCRIPTION: * An unpredicted behaviur is expected in case CPU address decode * windows overlapps. * This function detects CPU address decode windows overlapping of a * specified target. The function does not check the target itself for * overlapping. The function also skipps disabled address decode windows. * * INPUT: * target - Peripheral target enumerator. * pAddrDecWin - An address decode window struct. * * OUTPUT: * None. * * RETURN: * MV_TRUE if the given address window overlaps current address * decode map, MV_FALSE otherwise. * *******************************************************************************/ static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin) { MV_U32 targetNum; MV_CPU_DEC_WIN addrDecWin; MV_STATUS status; for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++) { #if defined(MV_RUN_FROM_FLASH) if(MV_TARGET_IS_AS_BOOT(target)) { if (MV_CHANGE_BOOT_CS(targetNum) == target) continue; } #endif /* MV_RUN_FROM_FLASH */ /* don't check our target or illegal targets */ if (targetNum == target) { continue; } /* Get window parameters */ status = mvCpuIfTargetWinGet(targetNum, &addrDecWin); if(MV_NO_SUCH == status) { continue; } if(MV_OK != status) { DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n")); return MV_TRUE; } /* Do not check disabled windows */ if (MV_FALSE == addrDecWin.enable) { continue; } if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin)) { DB(mvOsPrintf( "cpuTargetWinOverlap: Required target %d overlap current %d\n", target, targetNum)); return MV_TRUE; } } return MV_FALSE; }
/******************************************************************************* * mvTsuWinInit * * DESCRIPTION: * Initialize the TSU unit address decode windows. * * INPUT: * None. * OUTPUT: * None. * RETURN: * MV_OK - on success, * *******************************************************************************/ MV_STATUS mvTsuWinInit(void) { MV_U32 winNum, status, winPrioIndex=0; MV_TSU_DEC_WIN tsuWin; MV_CPU_DEC_WIN cpuAddrDecWin; /* First disable all address decode windows */ for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++) { MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } /* Go through all windows in user table until table terminator */ for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < TSU_MAX_DECODE_WIN));) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if(MV_OK != status) { mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size; tsuWin.enable = MV_TRUE; tsuWin.target = tsuAddrDecPrioTap[winPrioIndex]; if(MV_OK != mvTsuWinSet(winNum, &tsuWin)) { mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n", winNum); return MV_ERROR; } winNum++; } winPrioIndex ++; } return MV_OK; }
/******************************************************************************* * mvDmaInit - Initialize IDMA engine * * DESCRIPTION: * This function initialize IDMA unit. It set the default address decode * windows of the unit. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvDmaInit (MV_VOID) { MV_U32 winNum, status; MV_DMA_DEC_WIN idmaWin; MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 winPrioIndex=0; /* Initiate IDMA address decode */ /* First disable all address decode windows */ MV_REG_WRITE(IDMA_BASE_ADDR_ENABLE_REG, IBAER_ENABLE_MASK); /* Go through all windows in user table until table terminator */ for (winNum = 0; ((dmaAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < IDMA_MAX_ADDR_DEC_WIN)); ) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(dmaAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("mvDmaInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { idmaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; idmaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; idmaWin.addrWin.size = cpuAddrDecWin.addrWin.size; idmaWin.enable = MV_TRUE; idmaWin.target = dmaAddrDecPrioTap[winPrioIndex]; if(MV_OK != mvDmaWinSet(winNum, &idmaWin)) { return MV_ERROR; } winNum++; } winPrioIndex++; } mvDmaHalInit(MV_IDMA_MAX_CHAN); return MV_OK; }
int dram_init (void) { DECLARE_GLOBAL_DATA_PTR; unsigned int i; #if defined(MV_INC_BOARD_DDIM) unsigned int dramTotalSize=0; #endif MV_32 memBase; #if defined(MV_INC_BOARD_DDIM) /* Call dramInit */ if (0 == (dramTotalSize = initdram(0))) { printf("DRAM Initialization Failed\n"); reset_cpu(); return (1); } #endif //mvIntrfaceParamPrint(); for(i = 0; i< MV_DRAM_MAX_CS; i++) { MV_CPU_DEC_WIN addrDecWin; if((mvCpuIfTargetWinGet(SDRAM_CS0 + i, &addrDecWin) == MV_OK) && (addrDecWin.enable == MV_TRUE)){ memBase = addrDecWin.addrWin.baseLow; gd->bd->bi_dram[i].start = memBase; gd->bd->bi_dram[i].size = addrDecWin.addrWin.size; } //dramTotalSize += gd->bd->bi_dram[i].size; // if (gd->bd->bi_dram[i].size) // { //printf("DRAM CS[%d] base 0x%08x ",i, gd->bd->bi_dram[i].start); //mvSizePrint(gd->bd->bi_dram[i].size); //printf("\n"); // } } // printf("DRAM Total "); // mvSizePrint(dramTotalSize); // mvIntrfaceWidthPrint(); // printf("\n"); #ifdef MV_INC_DRAM_MFG_TEST mvDramMfgTrst(); #endif return 0; }
/******************************************************************************* * mvCtrlAddrWinMapBuild * * DESCRIPTION: * Build the windows address decoding table, to be used for initializing * the unit's address decoding windows. * * INPUT: * pAddrWinMap: An array to hold the address decoding windows parameters. * len: Number of entries in pAddrWinMap. * * OUTPUT: * pAddrWinMap: Address window information. * * RETURN: * MV_BAD_PARAM: input array is smaller than needed to store all window * addresses. * MV_ERROR: Otherwise. * *******************************************************************************/ MV_STATUS mvCtrlAddrWinMapBuild(MV_UNIT_WIN_INFO *pAddrWinMap, MV_U32 len) { MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 i; MV_TARGET_ATTRIB targetAttrib; MV_STATUS status; /* Check size of CPU address win table */ if (len <= MAX_TARGETS) { mvOsPrintf("mvCtrlAddrWinMapBuild() - Table size too small.\n"); return MV_BAD_PARAM; } /* Fill in the pAddrWinMap fields */ for (i = 0; i < MAX_TARGETS; i++) { status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin); if (status != MV_OK) { if (status == MV_NO_SUCH) { pAddrWinMap[i].enable = MV_FALSE; continue; } else { mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCpuIfTargetWinGet() failed.\n"); return MV_ERROR; } } pAddrWinMap[i].addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; pAddrWinMap[i].addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; pAddrWinMap[i].addrWin.size = cpuAddrDecWin.addrWin.size; pAddrWinMap[i].enable = cpuAddrDecWin.enable; if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) { mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCtrlAttribGet() failed.\n"); return MV_ERROR; } pAddrWinMap[i].attrib = targetAttrib.attrib; pAddrWinMap[i].targetId = targetAttrib.targetId; } pAddrWinMap[i].addrWin.baseLow = TBL_TERM; pAddrWinMap[i].addrWin.baseHigh = TBL_TERM; pAddrWinMap[i].addrWin.size = TBL_TERM; pAddrWinMap[i].enable = TBL_TERM; pAddrWinMap[i].attrib = TBL_TERM; pAddrWinMap[i].targetId = TBL_TERM; return MV_OK; }
* mvTdmWinInit - Initialize TDM address decode windows * * DESCRIPTION: * This function initialize TDM window decode unit. It set the * default address decode * windows of the unit. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvTdmWinInit(void) { MV_U32 winNum; MV_U32 winPrioIndex = 0; MV_CPU_DEC_WIN cpuAddrDecWin; MV_TDM_DEC_WIN tdmWin; MV_STATUS status; /*Disable all windows*/ for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++) { mvTdmWinEnable(winNum, MV_FALSE); } for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < TDM_MBUS_MAX_WIN)); ) { status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if (MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size; tdmWin.enable = MV_TRUE; tdmWin.target = tdmAddrDecPrioTap[winPrioIndex]; if (MV_OK != mvTdmWinSet(winNum, &tdmWin)) { return MV_ERROR; } winNum++; } winPrioIndex++; } return MV_OK; }
/******************************************************************************* * mvAudioWinInit - Initialize the integrated AUDIO target address window. * * DESCRIPTION: * Initialize the AUDIO peripheral target address window. * * INPUT: * * * OUTPUT: * * * RETURN: * MV_ERROR if register parameters are invalid. * *******************************************************************************/ MV_STATUS mvAudioWinInit(int unit) { int winNum; MV_AUDIO_DEC_WIN audioWin; MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 status; /* Initiate Audio address decode */ /* First disable all address decode windows */ for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++) { MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(unit, winNum)); regVal &= ~MV_AUDIO_WIN_ENABLE_MASK; MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(unit, winNum), regVal); } for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++) { /* We will set the Window to DRAM_CS0 in default */ /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(SDRAM_CS0, &cpuAddrDecWin); if (MV_OK != status) { mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; audioWin.addrWin.size = cpuAddrDecWin.addrWin.size; audioWin.enable = MV_TRUE; audioWin.target = SDRAM_CS0; if(MV_OK != mvAudioWinSet(unit, winNum, &audioWin)) { return MV_ERROR; } } } return MV_OK; }
/******************************************************************************* * mvCpuIfTargetOfBaseAddressGet - Get the target according to base address * * DESCRIPTION: * * INPUT: * baseAddress - base address to be checked * * OUTPUT: * None. * * RETURN: * the target number that baseAddress belongs to or MAX_TARGETS is not * found * *******************************************************************************/ MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress) { MV_CPU_DEC_WIN win; MV_U32 target; for (target = 0; target < MAX_TARGETS; target++) { if (mvCpuIfTargetWinGet(target, &win) == MV_OK) { if (win.enable) { if ((baseAddress >= win.addrWin.baseLow) && (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break; } } else return MAX_TARGETS; } return target; }
/* Audio Recording*/ MV_STATUS mvAudioRecordControlSet(int unit, MV_AUDIO_RECORD_CTRL *ctrl) { MV_AUDIO_DEC_WIN audioWin; MV_CPU_DEC_WIN cpuWin; MV_ADDR_WIN bufAddrWin; MV_U32 target; MV_U32 reg; if (ctrl->monoChannel > AUDIO_REC_RIGHT_MONO) { mvOsPrintf("mvAudioRecordControlSet: Error ,illegal monoChannel %x\n", ctrl->monoChannel ); return MV_FAIL; } if ((ctrl->burst != AUDIO_32BYTE_BURST) && (ctrl->burst != AUDIO_128BYTE_BURST)) { mvOsPrintf("mvAudioRecordControlSet: Error ,illegal burst %x\n", ctrl->burst ); return MV_FAIL; } if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1)) { mvOsPrintf("mvAudioRecordControlSet: Error ,bufferPhyBase is not"\ "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN ); return MV_FAIL; } if ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))|| (ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))|| (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX)) ) { mvOsPrintf("mvAudioRecordControlSet: Error, bufferSize smaller"\ "\nthan or not multiple of 0x%x bytes or larger than"\ "\n 0x%x", audioBurstBytesNumGet(ctrl->burst), AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX)); return MV_FAIL; } reg = MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit)); reg &= ~(ARCR_RECORD_BURST_SIZE_MASK|ARCR_RECORDED_MONO_CHNL_MASK| ARCR_RECORD_SAMPLE_SIZE_MASK); switch (ctrl->sampleSize) { case SAMPLE_16BIT: case SAMPLE_16BIT_NON_COMPACT: case SAMPLE_20BIT: case SAMPLE_24BIT: case SAMPLE_32BIT: reg |= ctrl->sampleSize << ARCR_RECORD_SAMPLE_SIZE_OFFS; break; default: mvOsPrintf("mvAudioRecordControlSet: Error ,illegal sampleSize %x\n", ctrl->sampleSize ); return MV_FAIL; } reg |= ctrl->burst << ARCR_RECORD_BURST_SIZE_OFFS; reg |= ctrl->monoChannel << ARCR_RECORDED_MONO_CHNL_OFFS; MV_REG_WRITE(MV_AUDIO_RECORD_CTRL_REG(unit), reg); if (ctrl->mono) { MV_REG_BIT_SET (MV_AUDIO_RECORD_CTRL_REG(unit), ARCR_RECORD_MONO_MASK); } else { MV_REG_BIT_RESET (MV_AUDIO_RECORD_CTRL_REG(unit), ARCR_RECORD_MONO_MASK); } /* Get the details of the Record address window*/ if( mvAudioWinGet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK ) { mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n", MV_AUDIO_RECORD_WIN_NUM); return MV_FAIL; } bufAddrWin.baseHigh = 0; bufAddrWin.baseLow = ctrl->bufferPhyBase; bufAddrWin.size = ctrl->bufferSize; /* If Record window is not enabled or buffer address is not within window boundries then try to set a new value to the Record window by Geting the target of where the buffer exist, if the buffer is within the window of the new target then set the Record window to that target else return Fail */ if((audioWin.enable != MV_TRUE) || (MV_TRUE != ctrlWinWithinWinTest(&bufAddrWin, &audioWin.addrWin))) { /* Get the target of the buffer that user require*/ target = mvCpuIfTargetOfBaseAddressGet(ctrl->bufferPhyBase); if (MAX_TARGETS == target) { mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on address 0x%x\n", ctrl->bufferPhyBase); return MV_FAIL; } /* Get the window details of this target*/ if (MV_OK != mvCpuIfTargetWinGet(target, &cpuWin)) { mvOsPrintf("mvAudioRecordControlSet: Error calling mvCpuIfTargetWinGet on target %d\n", target); return MV_FAIL; } /* if the address window of the target is enabled and te user buffer is within that target address window then set the palyback\recording window to the target window */ if((cpuWin.enable == MV_TRUE) && (MV_TRUE == ctrlWinWithinWinTest(&bufAddrWin, &cpuWin.addrWin))) { audioWin.addrWin.baseHigh = cpuWin.addrWin.baseHigh; audioWin.addrWin.baseLow = cpuWin.addrWin.baseLow; audioWin.addrWin.size = cpuWin.addrWin.size; audioWin.enable = cpuWin.enable; audioWin.target = target; if( mvAudioWinSet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK ) { mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n", MV_AUDIO_RECORD_WIN_NUM); return MV_FAIL; } } else { mvOsPrintf("mvAudioRecordControlSet: Error buffer is not within a valid target\n"); return MV_FAIL; } } /* Set the interrupt byte count. */ reg = ctrl->intByteCount & ARBCI_BYTE_COUNT_MASK; MV_REG_WRITE(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit), reg); MV_REG_WRITE(MV_AUDIO_RECORD_START_ADDR_REG(unit), ctrl->bufferPhyBase); MV_REG_WRITE(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit), AUDIO_SIZE_TO_REG(ctrl->bufferSize)); return MV_OK; }
/******************************************************************************* * mvCtrlAddrWinMapBuild * * DESCRIPTION: * Build the windows address decoding table, to be used for initializing * the unit's address decoding windows. * * INPUT: * pAddrWinMap: An array to hold the address decoding windows parameters. * len: Number of entries in pAddrWinMap. * * OUTPUT: * pAddrWinMap: Address window information. * * RETURN: * MV_BAD_PARAM: input array is smaller than needed to store all window * addresses. * MV_ERROR: Otherwise. * *******************************************************************************/ MV_STATUS mvCtrlAddrWinMapBuild(MV_UNIT_WIN_INFO *pAddrWinMap, MV_U32 len) { MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 i, j; MV_TARGET_ATTRIB targetAttrib; MV_STATUS status; MV_U64 startAddr, endAddr; MV_UNIT_WIN_INFO ioDdrWin[MV_DRAM_MAX_CS]; MV_U32 base; MV_U64 size; /* Check size of CPU address win table */ if (len <= MAX_TARGETS) { mvOsPrintf("mvCtrlAddrWinMapBuild() - Table size too small.\n"); return MV_BAD_PARAM; } /* Prepare an array of DRAM info */ base = 0x0; j = 0; for (i = SDRAM_CS0; i <= SDRAM_CS3; i++) { status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin); if (status != MV_OK) { if (status == MV_NO_SUCH) { ioDdrWin[i].enable = MV_FALSE; continue; } else { mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCpuIfTargetWinGet() failed.\n"); return MV_ERROR; } } /* As all IO address decode windows support only 32-bit ** addresses, limit the DRAM base / size to 4GB max. */ startAddr = (MV_U64)((((MV_U64)cpuAddrDecWin.addrWin.baseHigh << 32ll)) + (MV_U64)cpuAddrDecWin.addrWin.baseLow); endAddr = (MV_U64)(startAddr + (MV_U64)cpuAddrDecWin.addrWin.size) - 1; if (endAddr > 0xFFFFFFFFll) { if (startAddr <= 0xFFFFFFFFll) cpuAddrDecWin.addrWin.size = (0x100000000ll - cpuAddrDecWin.addrWin.baseLow); else cpuAddrDecWin.enable = MV_FALSE; } if (cpuAddrDecWin.enable == MV_FALSE) continue; /* If the endAddr passes minBase, then we need to split ** this window to several windows up to minBase. ** For example: minBase=0xE0000000, and CS0=2, CS1=2G, ** Then we need to split the windwos as follows: ** Win0: CS-0, 2GB (Base 0x0) ** win1: CS-1, 1GB (Base 0x80000000) ** Win2: CS-1, 0.5GB (Base 0xC0000000) */ if (endAddr > MV_DRAM_IO_RESERVE_BASE) /* Need to cut down this CS to IO reserve base ** address. */ size = MV_DRAM_IO_RESERVE_BASE - cpuAddrDecWin.addrWin.baseLow; else size = cpuAddrDecWin.addrWin.size; if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) { mvOsPrintf("mvCtrlAddrWinMapBuild() - " "mvCtrlAttribGet() failed.\n"); return MV_ERROR; } /* Now, spread the last CS into several windows, and make sure ** that each of has a power-of-2 size. */ while (size != 0) { ioDdrWin[j].enable = MV_TRUE; ioDdrWin[j].attrib = targetAttrib.attrib; ioDdrWin[j].targetId = targetAttrib.targetId; ioDdrWin[j].addrWin.baseHigh = 0; if (MV_IS_POWER_OF_2(size)) ioDdrWin[j].addrWin.size = size; else ioDdrWin[j].addrWin.size = (MV_U64)(1ll << (MV_U64)mvLog2(size)); size -= ioDdrWin[j].addrWin.size; ioDdrWin[j].addrWin.baseLow = base; base += ioDdrWin[j].addrWin.size; j++; } /* Support only up to 4 DRAM address decode windows in the ** units. */ if (j == MV_DRAM_MAX_CS) break; } for (; j < MV_DRAM_MAX_CS; j++) ioDdrWin[j].enable = MV_FALSE; /* Fill in the pAddrWinMap fields */ for (i = 0; i < MAX_TARGETS; i++) { if (MV_TARGET_IS_DRAM(i)) { pAddrWinMap[i].addrWin.baseLow = ioDdrWin[i].addrWin.baseLow; pAddrWinMap[i].addrWin.baseHigh = ioDdrWin[i].addrWin.baseHigh; pAddrWinMap[i].addrWin.size = ioDdrWin[i].addrWin.size; pAddrWinMap[i].enable = ioDdrWin[i].enable; pAddrWinMap[i].attrib = ioDdrWin[i].attrib; pAddrWinMap[i].targetId = ioDdrWin[i].targetId; } else { status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin); if (status != MV_OK) { if (status == MV_NO_SUCH) { pAddrWinMap[i].enable = MV_FALSE; continue; } else { mvOsPrintf("mvCtrlAddrWinMapBuild()" " - mvCpuIfTargetWinGet() failed.\n"); return MV_ERROR; } } pAddrWinMap[i].addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; pAddrWinMap[i].addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; pAddrWinMap[i].addrWin.size = cpuAddrDecWin.addrWin.size; pAddrWinMap[i].enable = cpuAddrDecWin.enable; if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) { mvOsPrintf("mvCtrlAddrWinMapBuild() - " "mvCtrlAttribGet() failed.\n"); return MV_ERROR; } pAddrWinMap[i].attrib = targetAttrib.attrib; pAddrWinMap[i].targetId = targetAttrib.targetId; } } pAddrWinMap[i].addrWin.baseLow = TBL_TERM; pAddrWinMap[i].addrWin.baseHigh = TBL_TERM; pAddrWinMap[i].addrWin.size = TBL_TERM; pAddrWinMap[i].enable = TBL_TERM; pAddrWinMap[i].attrib = TBL_TERM; pAddrWinMap[i].targetId = TBL_TERM; return MV_OK; }
/******************************************************************************* * mvAudioPlaybackControlSet - Set Playback general parameters * * DESCRIPTION: * * INPUT: * ctrl: pointer to MV_AUDIO_PLAYBACK_CTRL structure * OUTPUT: * None * RETURN: * MV_OK on success , MV_FAIL on fail * *******************************************************************************/ MV_STATUS mvAudioPlaybackControlSet(MV_AUDIO_PLAYBACK_CTRL *ctrl) { MV_AUDIO_DEC_WIN audioWin; MV_CPU_DEC_WIN cpuWin; MV_ADDR_WIN bufAddrWin; MV_U32 target; MV_U32 reg; if (ctrl->monoMode >= AUDIO_PLAY_OTHER_MONO) { mvOsPrintf("mvAudioPlaybackControlSet: Error ,illegal monoMode %x\n", ctrl->monoMode ); return MV_FAIL; } if ((ctrl->burst != AUDIO_32BYTE_BURST) && (ctrl->burst != AUDIO_128BYTE_BURST)) { mvOsPrintf("mvAudioPlaybackControlSet: Error ,illegal burst %x\n", ctrl->burst ); return MV_FAIL; } if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1)) { mvOsPrintf("mvAudioPlaybackControlSet: Error ,bufferPhyBase is not"\ "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN ); return MV_FAIL; } if ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))|| (ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))|| (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX)) ) { mvOsPrintf("mvAudioPlaybackControlSet: Error, bufferSize smaller"\ "\nthan or not multiple of 0x%x bytes or larger than"\ "\n 0x%x", audioBurstBytesNumGet(ctrl->burst), AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX)); return MV_FAIL; } reg = MV_REG_READ(MV_AUDIO_PLAYBACK_CTRL_REG); reg &= ~(APCR_PLAY_BURST_SIZE_MASK|APCR_LOOPBACK_MASK|APCR_PLAY_MONO_MASK | APCR_PLAY_SAMPLE_SIZE_MASK); reg |= ctrl->burst << APCR_PLAY_BURST_SIZE_OFFS; reg |= ctrl->loopBack << APCR_LOOPBACK_OFFS; reg |= ctrl->monoMode << APCR_PLAY_MONO_OFFS; reg |= ctrl->sampleSize << APCR_PLAY_SAMPLE_SIZE_OFFS; MV_REG_WRITE(MV_AUDIO_PLAYBACK_CTRL_REG, reg); /* Get the details of the Playback address window*/ if( mvAudioWinGet( MV_AUDIO_PLAYBACK_WIN_NUM, &audioWin ) != MV_OK ) { mvOsPrintf("mvAudioPlaybackControlSet: Error calling mvAudioWinGet on win %d\n", MV_AUDIO_PLAYBACK_WIN_NUM); return MV_FAIL; } bufAddrWin.baseHigh = 0; bufAddrWin.baseLow = ctrl->bufferPhyBase; bufAddrWin.size = ctrl->bufferSize; /* If Playback window is not enabled or buffer address is not within window boundries then try to set a new value to the Playback window by Geting the target of where the buffer exist, if the buffer is within the window of the new target then set the Playback window to that target else return Fail */ if((audioWin.enable != MV_TRUE) || (MV_TRUE != ctrlWinWithinWinTest(&bufAddrWin, &audioWin.addrWin))) { /* Get the target of the buffer that user require*/ target = mvCpuIfTargetOfBaseAddressGet(ctrl->bufferPhyBase); if (MAX_TARGETS == target) { mvOsPrintf("mvCpuIfTargetOfBaseAddressGet: Error calling mvAudioWinGet on address 0x%x\n", ctrl->bufferPhyBase); return MV_FAIL; } /* Get the window details of this target*/ if (MV_OK != mvCpuIfTargetWinGet(target, &cpuWin)) { mvOsPrintf("mvAudioPlaybackControlSet: Error calling mvCpuIfTargetWinGet on target %d\n", target); return MV_FAIL; } /* if the address window of the target is enabled and te user buffer is within that target address window then set the palyback\recording window to the target window */ if((cpuWin.enable == MV_TRUE) && (MV_TRUE == ctrlWinWithinWinTest(&bufAddrWin, &cpuWin.addrWin))) { audioWin.addrWin.baseHigh = cpuWin.addrWin.baseHigh; audioWin.addrWin.baseLow = cpuWin.addrWin.baseLow; audioWin.addrWin.size = cpuWin.addrWin.size; audioWin.enable = cpuWin.enable; audioWin.target = target; if( mvAudioWinSet( MV_AUDIO_PLAYBACK_WIN_NUM, &audioWin ) != MV_OK ) { mvOsPrintf("mvAudioPlaybackControlSet: Error calling mvAudioWinGet on win %d\n", MV_AUDIO_PLAYBACK_WIN_NUM); return MV_FAIL; } } else { mvOsPrintf("mvAudioPlaybackControlSet: Error buffer is not within a valid target\n"); return MV_FAIL; } } /* Set the interrupt byte count. */ reg = ctrl->intByteCount & APBCI_BYTE_COUNT_MASK; MV_REG_WRITE(MV_AUDIO_PLAYBACK_BYTE_CNTR_INT_REG, reg); MV_REG_WRITE(MV_AUDIO_PLAYBACK_BUFF_START_REG, ctrl->bufferPhyBase); MV_REG_WRITE(MV_AUDIO_PLAYBACK_BUFF_SIZE_REG, AUDIO_SIZE_TO_REG(ctrl->bufferSize)); return MV_OK; }
/******************************************************************************* * mvPexInit - Initialize PEX interfaces * * DESCRIPTION: * * This function is responsible of intialization of the Pex Interface , It * configure the Pex Bars and Windows in the following manner: * * Assumptions : * Bar0 is always internal registers bar * Bar1 is always the DRAM bar * Bar2 is always the Device bar * * 1) Sets the Internal registers bar base by obtaining the base from * the CPU Interface * 2) Sets the DRAM bar base and size by getting the base and size from * the CPU Interface when the size is the sum of all enabled DRAM * chip selects and the base is the base of CS0 . * 3) Sets the Device bar base and size by getting these values from the * CPU Interface when the base is the base of the lowest base of the * Device chip selects, and the * * * INPUT: * * pexIf - PEX interface number. * * * OUTPUT: * None. * * RETURN: * MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM * *******************************************************************************/ MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType) { MV_U32 bar; MV_U32 winNum; MV_PEX_BAR pexBar; MV_PEX_DEC_WIN pexWin; MV_CPU_DEC_WIN addrDecWin; MV_TARGET target; MV_U32 pexCurrWin=0; MV_U32 status; /* default and exapntion rom are always configured */ #ifndef MV_DISABLE_PEX_DEVICE_BAR MV_U32 winIndex; MV_U32 maxBase=0, sizeOfMaxBase=0; MV_U32 pexStartWindow; #endif /* Parameter checking */ if(pexIf >= mvCtrlPexMaxIfGet()) { mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf); return MV_BAD_PARAM; } /* Enabled CPU access to PCI-Express */ mvCpuIfEnablePex(pexIf, pexType); /* Start with bars */ /* First disable all PEX bars*/ for (bar = 0; bar < PEX_MAX_BARS; bar++) { if (PEX_INTER_REGS_BAR != bar) { if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE)) { mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar); return MV_ERROR; } } } /* and disable all PEX target windows */ for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++) { if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE)) { mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n", winNum); return MV_ERROR; } } /* Now, go through all bars*/ /******************************************************************************/ /* Internal registers bar */ /******************************************************************************/ bar = PEX_INTER_REGS_BAR; /* we only open the bar , no need to open windows for this bar */ /* first get the CS attribute from the CPU Interface */ if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin)) { mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS); return MV_ERROR; } pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; pexBar.addrWin.size = addrDecWin.addrWin.size; pexBar.enable = MV_TRUE; if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) { mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); return MV_ERROR; } /******************************************************************************/ /* DRAM bar */ /******************************************************************************/ bar = PEX_DRAM_BAR; pexBar.addrWin.size = 0; for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ ) { status = mvCpuIfTargetWinGet(target,&addrDecWin); if((MV_NO_SUCH == status)&&(target != SDRAM_CS0)) { continue; } /* first get attributes from CPU If */ if (MV_OK != status) { mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target); return MV_ERROR; } if (addrDecWin.enable == MV_TRUE) { /* the base is the base of DRAM CS0 always */ if (SDRAM_CS0 == target ) { pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; } /* increment the bar size to be the sum of the size of all DRAM chips selecs */ pexBar.addrWin.size += addrDecWin.addrWin.size; /* set a Pex window for this target ! DRAM CS always will have a Pex Window , and is not a part of the priority table */ pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow; pexWin.addrWin.size = addrDecWin.addrWin.size; /* we disable the windows at first because we are not sure that it is witihin bar boundries */ pexWin.enable =MV_FALSE; pexWin.target = target; pexWin.targetBar = bar; if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin)) { mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n"); return MV_ERROR; } } } /* check if the size of the bar is illeggal */ if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT)) { /* try to get a good size */ pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT); } /* check if the size and base are valid */ if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin)) { mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar); mvOsPrintf("it will be disabled\n"); mvOsPrintf("please check Pex and CPU windows configuration\n"); } else { pexBar.enable = MV_TRUE; /* configure the bar */ if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) { mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); return MV_ERROR; } /* after the bar was configured then we enable the Pex windows*/ for (winNum = 0;winNum < pexCurrWin ;winNum++) { if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE)) { mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum); return MV_ERROR; } } } /******************************************************************************/ /* DEVICE bar */ /******************************************************************************/ /* Open the Device BAR for non linux only */ #ifndef MV_DISABLE_PEX_DEVICE_BAR /* then device bar*/ bar = PEX_DEVICE_BAR; /* save the starting window */ pexStartWindow = pexCurrWin; pexBar.addrWin.size = 0; pexBar.addrWin.baseLow = 0xffffffff; pexBar.addrWin.baseHigh = 0; maxBase = 0; for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ ) { status = mvCpuIfTargetWinGet(target,&addrDecWin); if (MV_NO_SUCH == status) { continue; } if (MV_OK != status) { mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target); return MV_ERROR; } if (addrDecWin.enable == MV_TRUE) { /* get the minimum base */ if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow) { pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow; } /* get the maximum base */ if (addrDecWin.addrWin.baseLow > maxBase) { maxBase = addrDecWin.addrWin.baseLow; sizeOfMaxBase = addrDecWin.addrWin.size; } /* search in the priority table for this target */ for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM; winIndex++) { if (pexDevBarPrioTable[winIndex] != target) { continue; } else if (pexDevBarPrioTable[winIndex] == target) { /*found it */ /* if the index of this target in the prio table is valid then we set the Pex window for this target, a valid index is an index that is lower than the number of the windows that was not configured yet */ /* we subtract 2 always because the default and expantion rom windows are always configured */ if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2) { /* set a Pex window for this target ! */ pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow; pexWin.addrWin.size = addrDecWin.addrWin.size; /* we disable the windows at first because we are not sure that it is witihin bar boundries */ pexWin.enable = MV_FALSE; pexWin.target = target; pexWin.targetBar = bar; if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++, &pexWin)) { mvOsPrintf("mvPexInit: ERR. Window Set failed\n"); return MV_ERROR; } } } } } } pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase; pexBar.enable = MV_TRUE; /* check if the size of the bar is illegal */ if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT)) { /* try to get a good size */ pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT); } /* check if the size and base are valid */ if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin)) { mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar); mvOsPrintf("it will be disabled\n"); mvOsPrintf("please check Pex and CPU windows configuration\n"); } else { if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar)) { mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar); return MV_ERROR; } /* now enable the windows */ for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++) { if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE)) { mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n", winNum); return MV_ERROR; } } } #endif return mvPexHalInit(pexIf, pexType); }
/******************************************************************************* * mvPciInit - Initialize PCI interfaces * * DESCRIPTION: * This function initiate the PCI interface: * 1) Set local bus number. In case of convential PCI it gets the bus * number using mvPciLocalBusNumGet(). In case of PCI-X this * information is read only. * 2) Interface device number. In case of conventional PCI it gets the * device number using mvPciLocalDevNumGet(). In case of PCI-X this * information is read only. * 3) PCI Arbiter if needed. * 4) Enable Master and Slave on PCI interfaces. * 5) Open PCI BARs according to default setting. * Note that PCI bridge (P2P) is NOT initialized. * 6) Enable CPU to PCI ordering. * * INPUT: * * pciIf - PCI interface number. * localBus - Local Bus of the PCI interface to be set * localDev - Local Dev of the PCI interface to be set * bFirstCall - Indicates wether this is the first call of this * function . * * * OUTPUT: * None. * * RETURN: * MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM * *******************************************************************************/ MV_STATUS mvPciInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod) { MV_PCI_BAR bar, barix; MV_PCI_BAR_WIN dramDecWin; MV_PCI_MODE pciMode; MV_CPU_DEC_WIN addrDecWin; MV_PCI_PROT_WIN pciProtWin; MV_PCI_BAR_WIN pciBarMap[PCI_MAX_BARS]; /* Parameter checking */ if (pciIf >= mvCtrlPciMaxIfGet()) { mvOsPrintf("mvPciInit: ERR. Invalid PCI interface %d\n", pciIf); return MV_BAD_PARAM; } /* device and bus numbers */ if (MV_OK != mvPciModeGet(pciIf, &pciMode)) { mvOsPrintf("mvPciInit: ERR. mvPciModeGet failed\n"); return MV_ERROR; } /* First disable all PCI target windows */ for (bar = 0; bar < PCI_MAX_BARS; bar++) { mvPciTargetWinEnable(pciIf, bar, MV_FALSE); } /* WA CQ 4382*/ MV_REG_BIT_SET(PCI_BASE_ADDR_ENABLE_REG(pciIf) ,BIT15); /* Building in run time the pci bar mapping table */ for (bar = 0; bar < PCI_MAX_BARS; bar++) { for(barix = 0 ;barix < PCI_MAX_BARS; barix++) { if(pciBarStatusMap[barix].bar == bar) { pciBarMap[bar].enable = pciBarStatusMap[barix].enable; break; } } if(bar == MEM_INTER_REGS_BAR || bar == IO_INTER_REGS_BAR) { pciBarMap[bar].addrWin.baseLow = mvCpuIfTargetWinBaseLowGet(pciBarToTarget(bar)); pciBarMap[bar].addrWin.baseHigh = mvCpuIfTargetWinBaseHighGet(pciBarToTarget(bar)); pciBarMap[bar].addrWin.size = mvCpuIfTargetWinSizeGet(pciBarToTarget(bar)); continue; } if(bar == P2P_MEM0 || bar == P2P_IO) { pciBarMap[bar].addrWin.baseLow = 0xFFFFFFFF; pciBarMap[bar].addrWin.baseHigh = 0; pciBarMap[bar].addrWin.size = 0xFFFFFFFF; continue; } if (mvCpuIfTargetWinGet(pciBarToTarget(bar), &addrDecWin) == MV_OK) { pciBarMap[bar].addrWin.baseLow = addrDecWin.addrWin.baseLow; pciBarMap[bar].addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pciBarMap[bar].addrWin.size = addrDecWin.addrWin.size; if(addrDecWin.enable == MV_FALSE) { pciBarMap[bar].enable = DIS; } } else { pciBarMap[bar].addrWin.baseLow = 0xFFFFFFFF; pciBarMap[bar].addrWin.baseHigh = 0; pciBarMap[bar].addrWin.size = 0xFFFFFFFF; pciBarMap[bar].enable = DIS; } } /* finally fill table with TBL_TERM entry */ bar = PCI_MAX_BARS - 1; pciBarMap[bar].addrWin.baseLow = TBL_TERM; pciBarMap[bar].addrWin.baseHigh = TBL_TERM; pciBarMap[bar].addrWin.size = TBL_TERM; pciBarMap[bar].enable = TBL_TERM; /* Memory Mapped Internal Registers BAR can not be disabled. */ /* Relocate its BAR first to avoid colisions with other BARs (e.g DRAM) */ if (MV_OK != mvPciTargetWinSet(pciIf, MEM_INTER_REGS_BAR, &pciBarMap[MEM_INTER_REGS_BAR])) { mvOsPrintf("mvPciInit: ERR. mvPciTargetWinSet failed\n"); return MV_ERROR; } /* Now, go through all targets in default table until table terminator */ for (bar = 0; pciBarMap[bar].enable != TBL_TERM; bar++) { /* Skip the P2P BARs. They should be configured seperately */ if (0xFFFFFFFF == pciBarMap[bar].addrWin.baseLow) { continue; } /* check if the size passed is zero ! */ if (0 == pciBarMap[bar].addrWin.size) { /* disable the bar */ mvPciTargetWinEnable(pciIf,bar,MV_FALSE); continue; } /* Get DRAM parameters from CPU interface */ if (MV_PCI_BAR_IS_DRAM_BAR(bar)) { if (MV_OK != mvCpuIfTargetWinGet(MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar), &addrDecWin)) { mvOsPrintf("mvPciInit:ERR. targetWinGet %d fail\n", bar); return MV_ERROR; } dramDecWin.addrWin.baseLow = addrDecWin.addrWin.baseLow; dramDecWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh; dramDecWin.addrWin.size = addrDecWin.addrWin.size; dramDecWin.enable = addrDecWin.enable; if (MV_OK != mvPciTargetWinSet(pciIf, bar, &dramDecWin)) { mvOsPrintf("mvPciInit: ERR. mvPciTargetWinSet %d failed\n",bar); return MV_ERROR; } continue; } if (MV_OK != mvPciTargetWinSet(pciIf, bar, &pciBarMap[bar])) { mvOsPrintf("mvPciInit: ERR. mvPciTargetWinSet %d failed\n", bar); return MV_ERROR; } } MV_REG_BIT_SET(PCI_ADDR_DECODE_CONTROL_REG(pciIf), PADCR_REMAP_REG_WR_DIS); /* configure access control unit 0 to DDR to enhance performance */ pciProtWin.addrWin.baseLow = 0; pciProtWin.addrWin.baseHigh = 0; pciProtWin.addrWin.size = mvDramIfSizeGet(); pciProtWin.attributes.access = ALLOWED; pciProtWin.attributes.write = ALLOWED; pciProtWin.attributes.swapType = MV_BYTE_SWAP; pciProtWin.attributes.readMaxBurst = 128; pciProtWin.attributes.readBurst = 256; pciProtWin.attributes.writeMaxBurst = 128; pciProtWin.attributes.pciOrder = MV_FALSE; pciProtWin.enable = MV_TRUE; if( mvPciProtWinSet(pciIf, 0, &pciProtWin) != MV_OK ) { mvOsPrintf("mvPciInit: ERR. mvPciProtWinSet failed\n"); return MV_ERROR; } mvPciHalInit(pciIf, pciIfmod); return MV_OK; }
/******************************************************************************* * mvDmaInit - Initialize IDMA engine * * DESCRIPTION: * This function initialize IDMA unit. It set the default address decode * windows of the unit. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvDmaInit (MV_VOID) { MV_U32 winNum, status; MV_U32 dmaChanNum; MV_DMA_DEC_WIN idmaWin; MV_CPU_DEC_WIN cpuAddrDecWin; MV_U32 winPrioIndex=0; /* Initiate IDMA address decode */ /* First disable all address decode windows */ MV_REG_WRITE(IDMA_BASE_ADDR_ENABLE_REG, IBAER_ENABLE_MASK); /* Go through all windows in user table until table terminator */ for (winNum = 0; ((dmaAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < IDMA_MAX_ADDR_DEC_WIN)); ) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(dmaAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("mvDmaInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { idmaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; idmaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; idmaWin.addrWin.size = cpuAddrDecWin.addrWin.size; idmaWin.enable = MV_TRUE; idmaWin.target = dmaAddrDecPrioTap[winPrioIndex]; if(MV_OK != mvDmaWinSet(winNum, &idmaWin)) { return MV_ERROR; } winNum++; } winPrioIndex++; } /* Abort any DMA activity */ for(dmaChanNum = 0; dmaChanNum < MV_IDMA_MAX_CHAN; dmaChanNum++) { mvDmaCommandSet(dmaChanNum, MV_STOP); #if defined(MV_CPU_LE) /* The following must be set */ mvDmaCtrlHighSet(dmaChanNum, (ICCHR_ENDIAN_LITTLE | ICCHR_DESC_BYTE_SWAP_EN)); #endif } MV_REG_WRITE( IDMA_CAUSE_REG, 0); return MV_OK; }
/* Configure EthDrv memory map registes. */ MV_STATUS mvEthWinInit (int port) { MV_U32 winNum, status, winPrioIndex=0, i, regVal=0; MV_ETH_DEC_WIN ethWin; MV_CPU_DEC_WIN cpuAddrDecWin; static MV_U32 accessProtReg = 0; #if (MV_ETH_VERSION <= 1) static MV_BOOL isFirst = MV_TRUE; if(isFirst == MV_FALSE) { MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg); return MV_OK; } isFirst = MV_FALSE; #endif /* MV_GIGA_ETH_VERSION */ /* Initiate Ethernet address decode */ /* First disable all address decode windows */ for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++) { regVal |= MV_BIT_MASK(winNum); } MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal); /* Go through all windows in user table until table terminator */ for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < ETH_MAX_DECODE_WIN)); ) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if (MV_OK != status) { mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; ethWin.addrWin.size = cpuAddrDecWin.addrWin.size; ethWin.enable = MV_TRUE; ethWin.target = ethAddrDecPrioTap[winPrioIndex]; if(MV_OK != mvEthWinSet(port, winNum, ðWin)) { mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n", winNum); return MV_ERROR; } winNum++; } winPrioIndex ++; } /* set full access to all windows. */ for(i=0; i<winNum; i++) { accessProtReg |= (FULL_ACCESS << (i*2)); } MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg); return MV_OK; }