📄 harriersmc.c
字号:
*/ sdramTdp = SDRAM_TDP_DEFAULT; /* * Initialize the SDRAM Timing Parameter wdpl. This register setting * causes the Harrier to always wait until four clocks after the write * command portion of a single write before allowing a precharge to * occur. This can be cleared by software if unecessary. */ sdramSwrDpl = SDRAM_SWR_DPL_DEFAULT; /* * Load the SDRAM Control Register. The Harrier does not define the * use of all timing parameter bits. Mask off those not used and shift * the bits to the correct location in the register. The tDP parameter * uses the upper bit and requires a right shift prior to storing in the * register. */ pSmcReg->sdramTimingControl = ((sdramCl3 << HARRIER_SDTC_CL3_SHIFT) | (sdramTrc << HARRIER_SDTC_TRC_SHIFT) | (sdramTras << HARRIER_SDTC_TRAS_SHIFT) | (sdramSwrDpl << HARRIER_SDTC_WDPL_SHIFT) | ((sdramTdp >> 1) << HARRIER_SDTC_TDP_SHIFT) | (sdramTrp << HARRIER_SDTC_TRP_SHIFT) | (sdramTrcd << HARRIER_SDTC_TRCD_SHIFT)); /* disable error correction */ if (errDetChk == 0xFF) pSmcReg->sdramGeneralControl = HARRIER_SDGC_DERC; else pSmcReg->sdramGeneralControl = 0; } else { /* * If the board does not have any valid SPD data for the SDRAM * then we should default to a basic configuration. */ pSmcReg->sdramTimingControl = *((UINT32 *)HARRIER_SDRAM_TIMING_CONTROL_REG); pSmcReg->sdramGeneralControl = 0; sysSetRomStartError (HARRIER_GENERAL_PURPOSE0_REG, BOOTROM_DEFAULT_SMC_TIMING); } return; }/******************************************************************************** calcBankSize - calculate the size of a sdram bank** This function calculates the Harrier bank size code for a sdram bank using the* spd info.** RETURNS: Harrier SMC bank size code or 0 if invalid bank size.**/LOCAL UINT32 calcBankSize ( UCHAR *spdData, /* pointer to SPD buffer for current bank */ UINT32 *pBankSize /* calculated size of current bank in bytes */ ) { UINT32 sdramSize; /* SMC size code for current bank */ UINT32 devWidth; /* width of the devices in the current bank */ /* * Calculate the SDRAM Bank Size using the formula: * pBankSize = (Total Row Addresses * Total Column Addresses * * Number Device Banks * Data Width in Bytes); */ *pBankSize = ((1 << spdData[SPD_ROW_ADDR_INDEX]) * (1 << spdData[SPD_COL_ADDR_INDEX]) * spdData[SPD_DEV_BANKS_INDEX] * 8); /* * Get the Primary Device Width from the SDRAM SPD (Byte 13). * Use it to determine the device width attributes required by * the Harrier specification. */ devWidth = spdData[SPD_DEV_WIDTH_INDEX]; /* * use the bank size and device width to select the proper smc bank size * code. NOTE: A switch statement cannot be used because the absolute * addresses entered into the resulting jump table resolve to RAM addresses * and this code is executed before the image has been moved to RAM. the * nested if-else structure produces PC-relative branches which will always * work. */ if (*pBankSize == SIZE_32MB) /* 32 Meg */ if (devWidth == 16) sdramSize = HARRIER_SDBA_SIZE_32_4MX16; else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ else if (*pBankSize == SIZE_64MB) /* 64 Meg */ if (devWidth == 8) sdramSize = HARRIER_SDBA_SIZE_64_8MX8; else if (devWidth == 16) sdramSize = HARRIER_SDBA_SIZE_64_8MX16; else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ else if (*pBankSize == SIZE_128MB) /* 128 Meg */ if (devWidth == 4) sdramSize = HARRIER_SDBA_SIZE_128_16MX4; else if (devWidth == 8) sdramSize = HARRIER_SDBA_SIZE_128_16MX8; else if (devWidth == 16) sdramSize = HARRIER_SDBA_SIZE_128_16MX16; else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ else if (*pBankSize == SIZE_256MB) /* 256 Meg */ if (devWidth == 4) sdramSize = HARRIER_SDBA_SIZE_256_32MX4; else if (devWidth == 8) sdramSize = HARRIER_SDBA_SIZE_256_32MX8; else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ else if (*pBankSize == SIZE_512MB) /* 512 Meg */ if (devWidth == 4) sdramSize = HARRIER_SDBA_SIZE_512_64MX4; else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ else sdramSize = HARRIER_SDBA_SIZE_0; /* invalid */ return (sdramSize); }/******************************************************************************** sysHarrierSdramSizeInit - 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 UINT sysHarrierSdramSizeInit ( HARRIER_SMC * pSmcReg, /* points to caller's SMC register storage area */ UCHAR * spdArray[] /* array of pointers to SPD buffers */ /* (odd entries not used) */ ) { UCHAR * pData; /* SPD pointer for current bank */ register int bank; /* Bank index counter */ register int block; /* Block index counter */ register int shift; /* Shift index to register */ register int dimmBank; /* DimmBank index counter */ int validSpd; /* SPD Validity flag */ UINT numDimmBanks; /* Number of DIMM Banks supported */ UINT sdramSize; /* SDRAM Size for the bank */ UINT *pSdramBlock; /* Pointer to the block addressing register */ UINT baseAddr = 0x00000000; /* rolling bcurrent base address */ UINT bankSize = 0; /* bank size in bytes */ validSpd = FALSE; pSmcReg->sdramBlkAddrA = 0; /* Base Addressing Block A */ pSmcReg->sdramBlkAddrB = 0; /* Base Addressing Block B */ pSmcReg->sdramBlkAddrC = 0; /* Base Addressing Block C */ pSmcReg->sdramBlkAddrD = 0; /* Base Addressing Block D */ pSmcReg->sdramBlkAddrE = 0; /* Base Addressing Block E */ pSmcReg->sdramBlkAddrF = 0; /* Base Addressing Block F */ pSmcReg->sdramBlkAddrG = 0; /* Base Addressing Block G */ pSmcReg->sdramBlkAddrH = 0; /* Base Addressing Block H */ pSdramBlock = &pSmcReg->sdramBlkAddrA; /* Fill the attributes registers with bank data from the SPD devices. */ for (bank = 0; bank < HARRIER_SDRAM_BANKS; bank += 2) { if ((pData = spdArray[bank]) != NULL) { validSpd = TRUE; /* * Get the number of DIMM banks supported by this SPD. The * Harrier supports 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; /* Get the size attributes for the Bank. */ sdramSize = calcBankSize(pData, &bankSize); /* * Load the SDRAM Attributes and set the bank enable for any block * with a size greater than Zero. The Harrier has eight 32 bit * registers to store the base address and size. */ /* * Update the Harrier register for the number of DIMM Banks * supported by this size attribute information. */ for (dimmBank = 0; dimmBank < numDimmBanks; dimmBank++) { block = ((bank % 4) + dimmBank); shift = ((3 - block) * 8); *pSdramBlock = sdramSize | HARRIER_SDBA_ENB | (baseAddr << HARRIER_SDBA_BASE_SHIFT); baseAddr += bankSize; pSdramBlock += 4; } } } /* * Verify that we were able to read SDRAM size information from an * SPD device. If unable then reset the registers to the pre-init * values and continue. */ if (!validSpd) { UINT32 *blockReg = (UINT32 *)HARRIER_REG_SDRAM_BLOCK_ADDRESSING_A; int blockIndex = 0; pSdramBlock = &pSmcReg->sdramBlkAddrA; for (blockIndex = 0; blockIndex < HARRIER_SDRAM_BANKS; blockIndex++) *pSdramBlock++ = *blockReg++; baseAddr = SIZE_128MB; /* 128 Meg */ } return (baseAddr); }/******************************************************************************** getSpdData - read and validate the spd information.** This function reads the contents of the caller specified serial presence* detect EEPROM and validates the checksum.** RETURNS: TRUE if the SPD contents are valid, FALSE if not.**/STATUS sysGetSpdData ( UCHAR spdAddr, /* SROM address for current bank */ UCHAR offset, /* first byte of SROM to read */ UINT16 dataSize, /* number of SROM bytes to read */ UCHAR *spdData /* address of caller's SPD buffer */ ) { register UCHAR checksum = 0; /* running checksum */ register int index; /* index into SPD data buffer */ if ( sysMotI2cRangeRead (spdAddr, offset, dataSize, spdData, I2C_SINGLE_ADDRESS) == OK) { for (index = 0; index < SPD_CHECKSUM_INDEX; index++) checksum += spdData[index]; checksum %= 256; if (checksum == spdData[SPD_CHECKSUM_INDEX]) return (OK); } return (ERROR); }/******************************************************************************** sysHarrierParamConfig - calculate the proper harrier smc initialization values.** This function reads the serial presence detect EEPROM(s) and calculates the* proper values for configuring the harrier smc.** RETURNS: Size of memory configured.**/UINT32 sysHarrierParamConfig ( HARRIER_SMC * pSmcReg /* points to caller's SMC register storage area */ ) { /* * note: the harrier 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[HARRIER_SDRAM_BANKS]; /* spd buffer ptrs */ register int spd; /* Spd index counter */#ifndef BYPASS_SPD UCHAR spdData[HARRIER_SDRAM_BANKS / 2 * SPD_SIZE]; /* spd data */ UCHAR * pBfr = &spdData[0]; /* temp buffer ptr */#endif /* loop through each spd device */ for (spd = 0; spd < HARRIER_SDRAM_BANKS; spd +=2) { spdPtrs[spd] = NULL;#ifndef BYPASS_SPD /* read the spd data into the current buffer and validate */ if (sysGetSpdData (SPD_EEPROM_ADRS + spd, 0, SPD_SIZE, pBfr) == OK) { /* save current buffer address and advance to the next buffer */ spdPtrs[spd] = pBfr; pBfr += SPD_SIZE; }#endif } /* calculate the smc intialization parameters */ sysHarrierSdramSpeedInit (pSmcReg, &spdPtrs[0]); return(sysHarrierSdramSizeInit (pSmcReg, &spdPtrs[0])); }/******************************************************************************** sysSetRomStartError - Set a RomStartup error bit.** This routine sets one or more error flags in the RomStartup error registers.* The error registers are the 4 general purpose registers available in the* Harrier's Pci-Host Bridge (PHB). This mechanism allows low-level code to * save any errors detected before a debug console is available. Once the debug * console has been configured, these error flags are logged to the debug * console to aid in system debug.** RETURNS: N/A**/void sysSetRomStartError ( UINT32 offset, /* offset of the selected Harrier register */ UINT32 value /* bit(s) to merge into register contents */ ) { UINT32 * adrs; adrs = (UINT32 *)(HARRIER_XCSR_BASE + offset); *adrs |= value; }#ifdef DEBUG_SMCvoid harrierSmcSetupShow () { HARRIER_SMC SmcReg; /* SMC register storage area */ UINT32 memorySize = 0; memorySize = sysHarrierParamConfig(&SmcReg); printf("sdramBlkAddrA %x\r\n", SmcReg.sdramBlkAddrA); printf("sdramBlkAddrB %x\r\n", SmcReg.sdramBlkAddrB); printf("sdramBlkAddrC %x\r\n", SmcReg.sdramBlkAddrC); printf("sdramBlkAddrD %x\r\n", SmcReg.sdramBlkAddrD); printf("sdramBlkAddrE %x\r\n", SmcReg.sdramBlkAddrE); printf("sdramBlkAddrF %x\r\n", SmcReg.sdramBlkAddrF); printf("sdramBlkAddrG %x\r\n", SmcReg.sdramBlkAddrG); printf("sdramBlkAddrH %x\r\n", SmcReg.sdramBlkAddrH); printf("sdramGeneralControl %x\r\n", SmcReg.sdramGeneralControl); printf("sdramTimingControl %x\r\n", SmcReg.sdramTimingControl); printf("clkFrequency %x\r\n", SmcReg.clkFrequency); printf("memorySize %x\r\n", memorySize); }#endif /* DEBUG_SMC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -