/******************************************************************************* * mvCpuIfInit - Initialize Controller CPU interface * * DESCRIPTION: * This function initialize Controller CPU interface: * 1. Set CPU interface configuration registers. * 2. Set CPU master Pizza arbiter control according to static * configuration described in configuration file. * 3. Opens CPU address decode windows. DRAM windows are assumed to be * already set (auto detection). * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * None. * *******************************************************************************/ MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap) { MV_U32 regVal; MV_TARGET target; MV_ADDR_WIN addrWin; int ii; if (cpuAddrWinMap == NULL) { DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n")); return MV_ERROR; } /* Set ARM Configuration register */ regVal = MV_REG_READ(CPU_CONFIG_REG); regVal &= ~CPU_CONFIG_DEFAULT_MASK; /* regVal |= CPU_CONFIG_DEFAULT; Note: not needed */ MV_REG_WRITE(CPU_CONFIG_REG,regVal); /* First disable all CPU target windows */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS)) { continue; } #if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PCI(target)) { continue; } #endif #if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PEX(target)) { continue; } #endif #if defined(MV_RUN_FROM_FLASH) /* Don't disable the boot device. */ if (target == DEV_BOOCS) { continue; } #endif /* MV_RUN_FROM_FLASH */ mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE); } /* TODO */ for (ii = 0; ii < 8; ii++) MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(ii), 0); #if defined(MV_RUN_FROM_FLASH) /* Resize the bootcs windows before other windows, because this */ /* window is enabled and will cause an overlap if not resized. */ target = DEV_BOOCS; if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); return MV_ERROR; } addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) { DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", cpuAddrWinMap[target].winNum)); } #endif /* MV_RUN_FROM_FLASH */ /* Go through all targets in user table until table terminator */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { #if defined(MV_RUN_FROM_FLASH) if (target == DEV_BOOCS) { continue; } #endif /* MV_RUN_FROM_FLASH */ /* if DRAM auto sizing is used do not initialized DRAM target windows, */ /* assuming this already has been done earlier. */ #ifdef MV_DRAM_AUTO_SIZE if (MV_TARGET_IS_DRAM(target)) { continue; } #endif #if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PCI(target)) { continue; } #endif #if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PEX(target)) { continue; } #endif /* If the target attribute is the same as the boot device attribute */ /* then it's stays disable */ if (MV_TARGET_IS_AS_BOOT(target)) { continue; } if((0 == cpuAddrWinMap[target].addrWin.size) || (DIS == cpuAddrWinMap[target].enable)) { if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE)) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n")); return MV_ERROR; } } else { if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); return MV_ERROR; } addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) { DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", cpuAddrWinMap[target].winNum)); } } } #ifdef MV_INCLUDE_PEX mvCpuIfEnablePex(); #endif #ifdef MV_INCLUDE_PMU mvCpuIfEnablePmu(); #endif return MV_OK; }
/******************************************************************************* * mvCpuIfInit - Initialize Controller CPU interface * * DESCRIPTION: * This function initialize Controller CPU interface: * 1. Set CPU interface configuration registers. * 2. Set CPU master Pizza arbiter control according to static * configuration described in configuration file. * 3. Opens CPU address decode windows. DRAM windows are assumed to be * already set (auto detection). * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * None. * *******************************************************************************/ MV_STATUS mvCpuIfInit(void) { MV_U32 regVal; MV_TARGET target; MV_ADDR_WIN addrWin; /* Set ARM Configuration register */ regVal = MV_REG_READ(CPU_CONFIG_REG); regVal &= ~CPU_CONFIG_DEFAULT_MASK; regVal |= CPU_CONFIG_DEFAULT; MV_REG_WRITE(CPU_CONFIG_REG,regVal); /* Set ARM Control and Status register */ regVal = MV_REG_READ(CPU_CTRL_STAT_REG); regVal &= ~CPU_CTRL_STAT_DEFAULT_MASK; regVal |= CPU_CTRL_STAT_DEFAULT; MV_REG_WRITE(CPU_CTRL_STAT_REG,regVal); /* First disable all CPU target windows */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS)) { continue; } mvCpuIfTargetWinEnable(target,MV_FALSE); } /* Go through all targets in user table until table terminator */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { /* if DRAM auto sizing is used do not initialized DRAM target windows, */ /* assuming this already has been done earlier. */ #ifdef MV_DRAM_AUTO_SIZE if (MV_TARGET_IS_DRAM(target)) { continue; } #endif if((0 == cpuAddrWinMap[target].addrWin.size) || (MV_FALSE == cpuAddrWinMap[target].enable)) { if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE)) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n")); return MV_ERROR; } } else { if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); return MV_ERROR; } addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) { DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", cpuAddrWinMap[target].winNum)); } } } return MV_OK; }
/******************************************************************************* * mvCpuIfInit - Initialize Controller CPU interface * * DESCRIPTION: * This function initialize Controller CPU interface: * 1. Set CPU interface configuration registers. * 2. Set CPU master Pizza arbiter control according to static * configuration described in configuration file. * 3. Opens CPU address decode windows. DRAM windows are assumed to be * already set (auto detection). * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * None. * *******************************************************************************/ MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap) { MV_U32 regVal; MV_TARGET target; MV_ADDR_WIN addrWin; if (cpuAddrWinMap == NULL) { DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n")); return MV_ERROR; } /*Initialize the boot target array according to device type*/ if(mvCtrlModelGet() == MV_6180_DEV_ID || mvCtrlModelGet() == MV_6280_DEV_ID) sampleAtResetTargetArray = sampleAtResetTargetArray6180P; else sampleAtResetTargetArray = sampleAtResetTargetArrayP; /* Set ARM Configuration register */ regVal = MV_REG_READ(CPU_CONFIG_REG); regVal &= ~CPU_CONFIG_DEFAULT_MASK; regVal |= CPU_CONFIG_DEFAULT; MV_REG_WRITE(CPU_CONFIG_REG,regVal); /* First disable all CPU target windows */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS)) { continue; } #if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PCI(target)) { continue; } #endif #if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PEX(target)) { continue; } #endif #if defined(MV_RUN_FROM_FLASH) /* Don't disable the boot device. */ if (target == DEV_BOOCS) { continue; } #endif /* MV_RUN_FROM_FLASH */ /* Only MV88F6282 have 2 PCIe interfaces */ if((mvCtrlModelGet() != MV_6282_DEV_ID) && MV_TARGET_IS_PEX1(target)) continue; mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE); } #if defined(MV_RUN_FROM_FLASH) /* Resize the bootcs windows before other windows, because this */ /* window is enabled and will cause an overlap if not resized. */ target = DEV_BOOCS; if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); return MV_ERROR; } addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) { DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", cpuAddrWinMap[target].winNum)); } #endif /* MV_RUN_FROM_FLASH */ /* Go through all targets in user table until table terminator */ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) { #if defined(MV_RUN_FROM_FLASH) if (target == DEV_BOOCS) { continue; } #endif /* MV_RUN_FROM_FLASH */ /* if DRAM auto sizing is used do not initialized DRAM target windows, */ /* assuming this already has been done earlier. */ #ifdef MV_DRAM_AUTO_SIZE if (MV_TARGET_IS_DRAM(target)) { continue; } #endif #if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PCI(target)) { continue; } #endif #if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ if (MV_TARGET_IS_PEX(target)) { continue; } #endif /* If the target attribute is the same as the boot device attribute */ /* then it's stays disable */ if (MV_TARGET_IS_AS_BOOT(target)) { continue; } /* Only MV88F6282 have 2 PCIe interfaces */ if((mvCtrlModelGet() != MV_6282_DEV_ID) && MV_TARGET_IS_PEX1(target)) continue; if((0 == cpuAddrWinMap[target].addrWin.size) || (DIS == cpuAddrWinMap[target].enable)) { if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE)) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n")); return MV_ERROR; } } else { if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) { DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); return MV_ERROR; } addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) { DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", cpuAddrWinMap[target].winNum)); } } } return MV_OK; }
/******************************************************************************* * mvDramIfDetect - Prepare DRAM interface configuration values. * * DESCRIPTION: * This function implements the full DRAM detection and timing * configuration for best system performance. * Since this routine runs from a ROM device (Boot Flash), its stack * resides on RAM, that might be the system DRAM. Changing DRAM * configuration values while keeping vital data in DRAM is risky. That * is why the function does not preform the configuration setting but * prepare those in predefined 32bit registers (in this case IDMA * registers are used) for other routine to perform the settings. * The function will call for board DRAM SPD information for each DRAM * chip select. The function will then analyze those SPD parameters of * all DRAM banks in order to decide on DRAM configuration compatible * for all DRAM banks. * The function will set the CPU DRAM address decode registers. * Note: This routine prepares values that will overide configuration of * mvDramBasicAsmInit(). * * INPUT: * forcedCl - Forced CAL Latency. If equal to zero, do not force. * * OUTPUT: * None. * * RETURN: * None. * *******************************************************************************/ MV_STATUS mvDramIfDetect(MV_U32 forcedCl) { MV_U32 retVal = MV_OK; /* return value */ MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS]; MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW; MV_U8 minCas; MV_DRAM_DEC_WIN dramDecWin; dramDecWin.addrWin.baseHigh = 0; busClk = mvBoardSysClkGet(); if (0 == busClk) { mvOsPrintf("Dram: ERR. Can't detect system clock! \n"); return MV_ERROR; } /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */ for(i= SDRAM_CS1; i <= SDRAM_CS3; i++) mvCpuIfTargetWinEnable(i, MV_FALSE); /* we will use bank 0 as the representative of the all the DRAM banks, */ /* since bank 0 must exist. */ for(i = 0; i < MV_DRAM_MAX_CS; i++) { /* if Bank exist */ if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i])) { /* check it isn't SDRAM */ if(bankInfo[i].memoryType == MEM_TYPE_SDRAM) { mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n"); return MV_ERROR; } /* All banks must support registry in order to activate it */ if(bankInfo[i].registeredAddrAndControlInputs != bankInfo[0].registeredAddrAndControlInputs) { mvOsPrintf("Dram: ERR. different Registered settings !!!\n"); return MV_ERROR; } /* Init the CPU window decode */ /* Note that the size in Bank info is in MB units */ /* Note that the Dimm width might be different then the device DRAM width */ temp = MV_REG_READ(SDRAM_CONFIG_REG); deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32; dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16); size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); /* We can not change DRAM window settings while excecuting */ /* code from it. That is why we skip the DRAM CS[0], saving */ /* it to the ROM configuration routine */ if(i == SDRAM_CS0) { MV_U32 sizeToReg; /* Translate the given window size to register format */ sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT); /* Size parameter validity check. */ if (-1 == sizeToReg) { mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n" ,i); return MV_BAD_PARAM; } /* Size is located at upper 16 bits */ sizeToReg <<= SCSR_SIZE_OFFS; /* enable it */ sizeToReg |= SCSR_WIN_EN; MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg); } else { dramDecWin.addrWin.baseLow = base; dramDecWin.addrWin.size = size; dramDecWin.enable = MV_TRUE; if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin)) { mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i); return MV_ERROR; } } base += size; /* update the suportedCasLatencies mask */ bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies; } else { if( i == 0 ) /* bank 0 doesn't exist */ { mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n"); return MV_ERROR; } else { DB(mvOsPrintf("Dram: Could not find bank %d\n", i)); bankInfo[i].size = 0; /* Mark this bank as non exist */ } } } /* calculate minimum CAS */ minCas = minCasCalc(&bankInfo[0], busClk, forcedCl); if (0 == minCas) { mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n", (busClk / 1000000)); if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2) { minCas = DDR2_CL_4; /* Continue with this CAS */ mvOsPrintf("Set default CAS latency 4\n"); } else { minCas = DDR1_CL_3; /* Continue with this CAS */ mvOsPrintf("Set default CAS latency 3\n"); } } /* calc SDRAM_CONFIG_REG and save it to temp register */ temp = sdramConfigRegCalc(&bankInfo[0], busClk); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG1, temp); /* calc SDRAM_MODE_REG and save it to temp register */ temp = sdramModeRegCalc(minCas); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG2, temp); /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */ temp = sdramExtModeRegCalc(&bankInfo[0]); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG10, temp); /* calc D_UNIT_CONTROL_LOW and save it to temp register */ temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas); if(-1 == temp) { mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG3, temp); /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */ temp = sdramAddrCtrlRegCalc(&bankInfo[0]); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG4, temp); /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */ temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG5, temp); /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */ temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk); if(-1 == temp) { mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n"); return MV_ERROR; } MV_REG_WRITE(DRAM_BUF_REG6, temp); /* Config DDR2 On Die Termination (ODT) registers */ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2) { sdramDDr2OdtConfig(bankInfo); } /* Note that DDR SDRAM Address/Control and Data pad calibration */ /* settings is done in mvSdramIfConfig.s */ return retVal; }