📄 kahluamemparam.c
字号:
if (pMemControlReg->clkFrequency == 66) { pMemControlReg->MCCR1 |= (MEMORY_WAIT_CLK_4 << KAHLUA_MCC1_ROMNAL_SHIFT) | (MEMORY_WAIT_CLK_5 << KAHLUA_MCC1_ROMFAL_SHIFT) | (KAHLUA_MCC1_BURST) | (KAHLUA_MCC1_SREN); pMemControlReg->MCCR2 |= (asrise << KAHLUA_MCC2_ASRISE_SHIFT) | (MEMORY_WAIT_CLK_1 << KAHLUA_MCC2_ASFALL_SHIFT) | ((errDetChk == SPD_CONF_ERR_ECC) ? (KAHLUA_MCC2_WR_PAR_CHK_EN | KAHLUA_MCC2_RD_PARECC_EN | KAHLUA_MCC2_RMW_PAR) : (0)) | (tRefreshRate << KAHLUA_MCC2_REFINT_SHIFT); } else if (pMemControlReg->clkFrequency == 83) { pMemControlReg->MCCR1 |= (MEMORY_WAIT_CLK_5 << KAHLUA_MCC1_ROMNAL_SHIFT) | (MEMORY_WAIT_CLK_6 << KAHLUA_MCC1_ROMFAL_SHIFT) | (KAHLUA_MCC1_BURST) | (KAHLUA_MCC1_SREN); pMemControlReg->MCCR2 |= (asrise << KAHLUA_MCC2_ASRISE_SHIFT) | (MEMORY_WAIT_CLK_1 << KAHLUA_MCC2_ASFALL_SHIFT) | ((errDetChk == SPD_CONF_ERR_ECC) ? (KAHLUA_MCC2_WR_PAR_CHK_EN | KAHLUA_MCC2_RD_PARECC_EN | KAHLUA_MCC2_RMW_PAR) : (0)) | (tRefreshRate << KAHLUA_MCC2_REFINT_SHIFT); } else if (pMemControlReg->clkFrequency == 100) { pMemControlReg->MCCR1 |= (MEMORY_WAIT_CLK_6 << KAHLUA_MCC1_ROMNAL_SHIFT) | (MEMORY_WAIT_CLK_7 << KAHLUA_MCC1_ROMFAL_SHIFT) | (KAHLUA_MCC1_BURST) | (KAHLUA_MCC1_SREN); pMemControlReg->MCCR2 |= (asrise << KAHLUA_MCC2_ASRISE_SHIFT) | (MEMORY_WAIT_CLK_1 << KAHLUA_MCC2_ASFALL_SHIFT) | ((errDetChk == SPD_CONF_ERR_ECC) ? (KAHLUA_MCC2_WR_PAR_CHK_EN | KAHLUA_MCC2_RD_PARECC_EN | KAHLUA_MCC2_RMW_PAR) : (0)) | (tRefreshRate << KAHLUA_MCC2_REFINT_SHIFT); } pMemControlReg->MCCR3 |= (KAHLUA_MCC3_BSTORE_DFLT << KAHLUA_MCC3_BSTOPRE_25_S) | ((casLatency + 4) << KAHLUA_MCC3_REFREC_SHIFT) | ((errDetChk == SPD_CONF_ERR_ECC) ? ((sdramTrp + 2) << KAHLUA_MCC3_RDLAT_SHIFT) : (sdramTrp << KAHLUA_MCC3_RDLAT_SHIFT)); pMemControlReg->MCCR4 |= (preToAct << KAHLUA_MCC4_PRETOACT_SHIFT) | (actToPre << KAHLUA_MCC4_ACTOPRE_SHIFT) | ((errDetChk == SPD_CONF_ERR_ECC) ? (KAHLUA_MCC4_INLINE) : (0)) | (KAHLUA_MCC4_BSTORE_DFLT << KAHLUA_MCC4_BSTOPRE_01_SHIFT) | (sdramTrp << KAHLUA_MCC4_SDMODE_CAS_SHF) | (KAHLUA_MCC4_BURST_LEN << KAHLUA_MCC4_SDMODE_SHIFT) | (sdramTrcd << KAHLUA_MCC4_ACTORW_SHIFT) | (KAHLUA_MCC4_BSTPRE_DFLT); } else { /* If the board does not have any valid SPD data for the SDRAM * then we should default to the basic configuration that got * us to this point in the Firmware. Set MCCR1 to 0 as a test * for romInit. */ pMemControlReg->MCCR1 = 0; } return; }/******************************************************************************** calcBankSize - calculate the size of a sdram bank** This function calculates the size of a sdram bank based on SPD data.** RETURNS: the size of a sdram bank*/LOCAL UINT32 calcBankSize ( UCHAR *spdData /* This bank's SPD data */ ) { UINT32 bankSize; /* * Calculate the SDRAM Bank Size using the formula: * BankSize = (Total Row Addresses * Total Column Addresses * * Number Device Banks * Data Width in Bytes); */ bankSize = ((1 << spdData[SPD_ROW_ADDR_INDEX]) * (1 << spdData[SPD_COL_ADDR_INDEX]) * spdData[SPD_DEV_BANKS_INDEX] * 8); return (bankSize); }/******************************************************************************** calcMemAddress - calculate the memory bank end and start addresses.** This function calculates the memory bank ending address based on* the size of the memory, the bank and the existing ending address* value. This function also updates the total amount of memory.** RETURNS: N/A*/void calcMemAddress ( UINT32 sdramSize, /* size of this bank */ UINT32 bank, /* bank number */ UINT32 *endAddr, /* rolling ending address */ UINT32 *startAddr, /* start address for this bank */ UINT32 *totalSize /* running total amount of memory */ ) { *startAddr |= ((*totalSize >> KAHLUA_MEM_ADDR_SHIFT) << (bank * KAHLUA_MEM_BANK_INDEX)); *totalSize += sdramSize; *endAddr |= (((*totalSize - 1) >> KAHLUA_MEM_ADDR_SHIFT) << (bank * KAHLUA_MEM_BANK_INDEX)); }/******************************************************************************** sysSdramSizeInit - initialize the SDRAM Size Attributes** This function's purpose is to determine the correct size attributes* for all banks and to set the ram enable for banks consisting of* a valid memory configuration.** RETURNS: N/A**/LOCAL void sysSdramSizeInit ( sramConfigReg *pMemControlReg, /* ptr to memory control structure */ UCHAR * spdArray[] /* ptr to SPD data arrays */ ) { UCHAR * pData; register int bank; /* Bank index counter */ UINT spdNum; /* spd index for the bank */ int validSpd; /* SPD Validity flag */ UINT numDimmBanks; /* Number of DIMM Banks supported */ int bankIndex; /* Index for current bank */ UINT sdramSize = 0; /* SDRAM Size for the bank */ validSpd = FALSE; /* Fill the memory interface values with bank data from the SPD devices. */ for (bank = 0; bank < NUM_SDRAM_BANKS; bank += 2) { if ((pData = spdArray[bank]) != NULL) { validSpd = TRUE; /* * Get the number of DIMM banks supported by this SPD. * In general, a memory controller will support up to 2 * DIMM Banks for each SPD. Any number other than 1 or 2 * should be considered erroneous and reset to 1 for this * device. */ numDimmBanks = pData[SPD_NUM_DIMMBANKS_INDEX]; if (numDimmBanks < 1 || numDimmBanks > 2) numDimmBanks = 1; /* Calculate the size of the Bank. */ sdramSize = calcBankSize(pData); /* * Set the bank enable and start and end addresses * for any bank with a size greater than Zero. */ if (sdramSize) { spdNum = bank/2; for (bankIndex=0; bankIndex < numDimmBanks; bankIndex++) { pMemControlReg->MBER |= (1 << (bank + bankIndex)); if (bank < 4) { calcMemAddress (sdramSize, bank + bankIndex, &pMemControlReg->MER3_2_1_0, &pMemControlReg->MSR3_2_1_0, &pMemControlReg->sdramSize); } else { calcMemAddress (sdramSize, (bank - 4) + bankIndex, &pMemControlReg->MER7_6_5_4, &pMemControlReg->MSR7_6_5_4, &pMemControlReg->sdramSize); } } } } } /* * Verify a valid total size (non-zero) or at least one valid * SPD device was found. Set MCCR1 to 0 if invalid so that default * memory settings can be used. */ if ((!validSpd) || (pMemControlReg->sdramSize == 0)) { pMemControlReg->MCCR1 = 0; } }/******************************************************************************** sysGetSpdData - read and validate the spd information.** This function reads the contents of the caller specified serial presence* detect EEPROM and validates the checksum.** RETURNS: OK if the SPD contents are valid, ERROR if not.*/STATUS sysGetSpdData ( UCHAR spdAddr, UCHAR offset, UINT16 dataSize, UCHAR *spdData ) { if (i2cRead (spdAddr, offset, dataSize, spdData) == OK) { /* * The Kahlua I2C interface is painfully slow (5 secs to read * 256 bytes). Since we only read 31 (SPD_SIZE) bytes of SPD * data, the checksum cannot be validated. Since this is the * case, check for SDRAM. No other memory types are supported. */ if (spdData[SPD_MEMORY_TYPE_INDEX] == SPD_TYPE_SDRAM) return (OK); else return (ERROR); } return (ERROR); }/******************************************************************************** sysMemParamConfig - calculate the proper memory interface init values.** This function reads the serial presence detect EEPROM(s) and calculates the* proper values for configuring the memory interface.** RETURNS: Size of memory configured.*/UINT32 sysMemParamConfig ( sramConfigReg *pMemControlReg /* register image storage */ ) { /* * note: the SDRAM banks are arranged in pairs with one spd device per * bank pair. therefore only the even numbered entries in the spdPtrs * array are used. */ UCHAR * spdPtrs[NUM_SDRAM_BANKS]; /* spd buffer ptrs */ register int spd; /* Spd index counter */ UCHAR spdData[NUM_SDRAM_BANKS / 2 * SPD_SIZE]; /* spd data */ UCHAR * pBfr = &spdData[0]; /* temp buffer ptr */ /* Initialize structure */ pMemControlReg->MCCR1 = 0; pMemControlReg->MCCR2 = 0; pMemControlReg->MCCR3 = 0; pMemControlReg->MCCR4 = 0; pMemControlReg->MSR3_2_1_0 = 0; pMemControlReg->MSR7_6_5_4 = 0; pMemControlReg->MER3_2_1_0 = 0; pMemControlReg->MER7_6_5_4 = 0; pMemControlReg->MSER3_2_1_0 = 0; pMemControlReg->MSER7_6_5_4 = 0; pMemControlReg->MEER3_2_1_0 = 0; pMemControlReg->MEER7_6_5_4 = 0; pMemControlReg->MPMR = 0; pMemControlReg->MBER = 0; pMemControlReg->sdramSize = 0; /* Initialize the I2C interface. */ if (i2cDrvInit(I2C_DRV_TYPE) == ERROR) { return (0); } /* Loop through each spd device */ for (spd = 0; spd < NUM_SDRAM_BANKS; spd +=2) { spdPtrs[spd] = NULL; /* Read the spd data into the current buffer and validate */ if (sysGetSpdData (SPD_EEPROM_ADRS0 + spd, 0, SPD_SIZE, pBfr) == OK) { /* Save current buffer address and advance to the next buffer */ spdPtrs[spd] = pBfr; pBfr += SPD_SIZE; } } /* Calculate the memory controller initialization parameters */ sysSdramSpeedInit (pMemControlReg, &spdPtrs[0]); sysSdramSizeInit (pMemControlReg, &spdPtrs[0]); return(pMemControlReg->sdramSize); }#ifdef DEBUG_MEMCONFIG/******************************************************************************** sysMemParamConfigTest - debug function.** This routine simulates the call done in romInit. The routine * can print memory values calculated.** RETURNS: N/A*/void sysMemParamConfigTest (void) { sramConfigReg memControlReg = {0}; sysMemParamConfig(&memControlReg); printf("MCCR1: %x\n", memControlReg.MCCR1); printf("MCCR2: %x\n", memControlReg.MCCR2); printf("MCCR3: %x\n", memControlReg.MCCR3); printf("MCCR4: %x\n\n", memControlReg.MCCR4); printf("MSR3_2_1_0: %x\n", memControlReg.MSR3_2_1_0); printf("MSR7_6_5_4: %x\n", memControlReg.MSR7_6_5_4); printf("MSER3_2_1_0: %x\n", memControlReg.MSER3_2_1_0); printf("MSER7_6_5_4: %x\n\n", memControlReg.MSER7_6_5_4); printf("MER3_2_1_0: %x\n", memControlReg.MER3_2_1_0); printf("MER7_6_5_4: %x\n", memControlReg.MER7_6_5_4); printf("MEER3_2_1_0: %x\n", memControlReg.MEER3_2_1_0); printf("MEER7_6_5_4: %x\n\n", memControlReg.MEER7_6_5_4); printf("MPMR: %x\n", memControlReg.MPMR); printf("MBER: %x\n\n", memControlReg.MBER); printf("sdramSize: %x\n", memControlReg.sdramSize); printf("clkFrequency: %x\n", memControlReg.clkFrequency); return; }#endif /* DEBUG_MEMCONFIG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -