⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kahluamemparam.c

📁 vxworks mv2100 vxworks BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* kahluaMemParam.c - Memory Controller Parameter Initialization *//* Copyright 1984-2000 Wind River Systems, Inc. *//* Copyright 1998-2000 Motorola, Inc., All Rights Reserved *//*modification history--------------------01g,15jun00,dmw  updated following WRS code review.01f,07jul99,srr  Changed bank start and end addresses for rev "C" hardware.01e,21jun99,dmw  Changed bank enable to reflect rev "C" hardware.01d,28may99,dmw  Update to WindRiver coding standards.01c,18may99,rhk  minor cleanup, made sysRomGetBusSpd global.01b,28mar99,dmw  Removed debug function sysMemParamConfigTest from build.01a,03mar99,dmw  Written (based on hawkSmc.c version 01i.)*//*DESCRIPTIONThis file contains the routines used to calculate the proper configurationvalues for the Memory Controller using information containedin the Serial Presence Detect (SPD) EEPROMs. The SPD information is used todetermine memory timing, bank sizes and starting addresses.CAVEATS:This code executes very early in the startup sequence (called from romInit.s),before the image has been copied to RAM (assuming a non-ROM image). As such,this file must be added to the BOOT_EXTRA list in the Makefile to prevent itfrom being compressed during keernel generation. Additionally, extreme cautionmust be exercised when modifying these routines to prevent the use of absolutememory addresses which reference locations in the RAM-relocated image. Theselocations are invalid and references to them will cause unpredictable behavior.Absolute memory addresses are generated by the compiler when referencing tables,static data structures and global variables. All of these must be avoided. Insome places in the code, nested if-else constructs are used to avoid the jumptable created when a simple switch construct is used. The jump table address wasloaded using an absolute address and the code broke because the execution imagehad not been copied to the RAM address produced by the compiler.*//* includes */#include "vxWorks.h"#include "config.h"#include "sysMotVpd.h"#include "sdramSpd.h"#include "kahluaMemParam.h"/* defines *//* typedefs *//* globals *//* locals *//* forward declarations *//* external references */IMPORT STATUS sysVpdPktInit(UCHAR, UCHAR, VPD *, VPD_PACKET **, UINT32, UINT32);IMPORT STATUS sysVpdPktRead(UCHAR, UCHAR, UCHAR, UINT32, VPD_PACKET *, UINT32);IMPORT STATUS i2cRead(UCHAR, UCHAR, UINT16, UCHAR *);IMPORT STATUS i2cDrvInit(int);/******************************************************************************** sysRomGetBusSpd - rom-phase routine to get the speed of the 60x processor bus** This routine reads the VPD and returns the speed (in MHz) of the 60x system* bus. If the VPD is invalid, a default value is returned. This routine is* executed before the memory controller is initialized.** RETURNS: The bus speed (in Hz).*/UINT sysRomGetBusSpd (void)    {    VPD vpd;                                     /* temp vpd storage area */    VPD_PACKET * vpdPkts[VPD_PKT_LIMIT] = { 0 }; /* temp vpd storage area */    VPD_PACKET vpdPkt;				 /* bus speed pkt */    /*     * Read the vpd and find the external clock frequency packet.      * Normally, we would read the entire VPD and parse it in RAM     * but since the I2C interface on Kahlua is so incredibly slow,      * only read the bus speed out of the I2C device rather than the      * whole 256 bytes.     */    if ( sysVpdPktInit (VPD_BRD_EEPROM_ADRS, VPD_BRD_OFFSET, &vpd,                        &vpdPkts[0], VPD_PKT_LIMIT, 0) == OK)        if ( sysVpdPktRead (VPD_BRD_EEPROM_ADRS, VPD_BRD_OFFSET, VPD_PID_ECS,                             0, &vpdPkt, sizeof(UINT32)) == OK )            {            if ( vpdPkt.size == sizeof (UINT32) )                return (*(UINT32 *)vpdPkt.data);            }    return (0);    }/******************************************************************************** sysSdramSpeedInit - routine to initialize the sdram control reg.** This function's purpose is to initialize the memory control register.* The register value is placed in a structure pointer and returned to* the calling program.** RETURNS: N/A*/LOCAL void sysSdramSpeedInit    (    sramConfigReg *pMemControlReg,	/* ptr to memory control structure */    UCHAR * spdArray[]			/* ptr to SPD data arrays */    )    {    UCHAR * pData;    register int bank;			/* Bank index counter */    int validSpd = FALSE;		/* SPD Validity flag */    UINT spdValue;			/* Temp SPD Data Value */    UINT busSpeed;			/* Bus Speed for the board */    UINT clockPeriod;			/* NanoSeconds per clock cycle */    UINT casLatency = 0xFF;		/* Cas Latency of the SDRAM */    UINT tCycReducedCl = 0;		/* Cycle Time @ reduced CAS Latency */    UINT tRefreshRate = 0;		/* Cycle Time @ reduced CAS Latency */    UINT errDetChk = 0xFF;		/* Error detection/correction */    UINT sdramTrc = 0;			/* SDRAM tRC value */     UINT sdramTras = 0;			/* SDRAM tRAS value */    UINT sdramTrp = 0;			/* SDRAM tRP value */    UINT sdramTrrd = 0;			/* SDRAM tRRD value */    UINT sdramTrcd = 0;			/* SDRAM tRCD value */    UINT sdramTdp = 0;			/* SDRAM tDP value */    UINT sdramSwrDpl = 0;		/* SDRAM swr_dpl value */    UINT romFal;			/* ROM first access time in clocks */    UINT casLatType;			/* CAS Latency Type */    UINT preToAct = 0;			/* Row precharge time */    UINT actToPre = 0;			/* RAS pulse width */    UINT asrise;			/* width of the address strobe */         /*     * Get the BusSpeed in Hertz from the VPD SROM.  First convert the        * BusSpeed into nanoseconds, then convert bus_speed to Mhz to     * store in the CLK Frequency register.     */    busSpeed = sysRomGetBusSpd ();    if (busSpeed == 0)        {        pMemControlReg->MCCR1 = 0;        busSpeed = DEFAULT_BUS_CLOCK;         return;        }    /*      * Calculate the clock period as equal to the number of nano seconds in      * one second over the Bus speed (In Hertz):     *    ClockPeriod = 1/10(-9) / BusSpeed     */    clockPeriod = (NANO2SEC / busSpeed);    pMemControlReg->clkFrequency = (busSpeed / MHZ);    /* Start with the first Bank and check all Banks for memory. */    for (bank = 0; bank < NUM_SDRAM_BANKS; bank += 2)        {           /* Get valid SPD data from the current SPD Address. */        pData = spdArray[bank];        if (pData != NULL)            {             validSpd = TRUE;            /*             * Get the SDRAM Device Attributes CAS latency. The CL             * parameter must be the greater of all SDRAM CAS latencies.             */            spdValue = pData[SPD_CL_INDEX];            casLatency &= spdValue;               /* Get the SDRAM Device CAS latency type. */            spdValue = pData[SPD_CS_LATENCY_INDEX];            casLatType = spdValue;            /*             * Get the SDRAM Minimum Clock Cycle Time at Reduced CAS             * latency, X-1.  Ignore fractional precision.  Use upper             * nibble only.             */            spdValue = (pData[SPD_TCYC_RCL_INDEX] >> 4);            if (spdValue > tCycReducedCl)                tCycReducedCl = spdValue;                        /*              * Get the refresh rate/type of the SRAM.  Strip self              * refresh bit, if any.              */            spdValue = (pData[SPD_REFRESH_RATE_INDEX]) & ~SPD_REF_SELF_REFRESH;                       /*             * Calculate burst read time based on clock.             * Note: Hardware designer specified a value of 15 clks across             * the board (no regard for bus speed).             */            if (pMemControlReg->clkFrequency == SPEED66MHZ)                romFal = ((MEMORY_WAIT_CLK_4 + 2) * 3);            else if (pMemControlReg->clkFrequency == SPEED83MHZ)                romFal = ((MEMORY_WAIT_CLK_6 + 2) * 3);            else if (pMemControlReg->clkFrequency == SPEED100MHZ)                romFal = ((MEMORY_WAIT_CLK_7 + 2) * 3);            else                romFal = ((MEMORY_WAIT_CLK_4 + 2) * 3);            /*             * Calculate REFINT without using floating point.              * Note: this code cannot be a "switch" since it is             * ROM based.              */            if (spdValue == SPD_REF_NORMAL_15)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_NORMAL;            else if (spdValue == SPD_REF_REDUCED_DIV4)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_REDUCED_DIV4;            else if (spdValue == SPD_REF_REDUCED_DIV2)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_REDUCED_DIV2;            else if (spdValue == SPD_REF_EXTENDED_2X)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_EXTENDED_2X;            else if (spdValue == SPD_REF_EXTENDED_4X)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_EXTENDED_4X;            else if (spdValue == SPD_REF_EXTENDED_8X)            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_EXTENDED_8X;            else            	tRefreshRate = pMemControlReg->clkFrequency *                                KAHLUA_REFINT_REFR_NORMAL;            tRefreshRate /= 1000;            tRefreshRate -= romFal;            /*             * Get the SDRAM Minimum RAS Pulse Width (tRAS).  Ignore             * fractional precision. Use upper nibble only.             */            spdValue = pData[SPD_TRAS_INDEX];            if (spdValue > sdramTras)                sdramTras = spdValue;            /* Calculate the maximum page open time (PGMAX). */            pMemControlReg->MPMR = ((pMemControlReg->clkFrequency * 100) -                     (sdramTras - 2))/64;               actToPre = sdramTras / clockPeriod;            /* Check for rounding. */            if ((actToPre * clockPeriod) < sdramTras)                actToPre += 1;            actToPre += 2;            /*             * Get the SDRAM Minimum Row Precharge Time (tRP).  Ignore             * fractional precision. Use upper nibble only.             */            if (pData[SPD_TRP_INDEX] > sdramTrp)                sdramTrp = pData[SPD_TRP_INDEX];              sdramTrrd = pData[SPD_TRRD_INDEX];            if (spdValue > sdramTrrd)                sdramTrrd = spdValue;            preToAct = (sdramTrp / clockPeriod) + 1;            /*             * Check if rounding occured. preToAct times the clock             * period can not be less than sdramTrp.             */            if ((preToAct * clockPeriod) < sdramTrp)                preToAct += 1;            /*             * Get the SDRAM Minimum RAS to CAS Delay.  Ignore fractional              * precision. Use upper nibble only.             */            spdValue =pData[SPD_TRCD_INDEX];            if (spdValue > sdramTrcd)                 sdramTrcd = spdValue;            /*             * Get the SDRAM error detection/correction type.              * Use the worst type found.             */            spdValue = pData[SPD_DIMM_TYPE_INDEX];            if (spdValue < errDetChk)                 errDetChk = spdValue;            }          }       if (validSpd)        {        /*         * Calculate the timing for the SDRAM Timing Parameter tRC. Add the         * tRAS and tRP timing to get tRC.         */        if (sdramTras && sdramTrp)            {            sdramTrc = (((sdramTras + sdramTrp) +                          (clockPeriod - 1)) / clockPeriod);            if (sdramTrc < 6 || sdramTrc > 11)                sdramTrc = (sdramTrc < 6 ? 6 : 11);            }        else            sdramTrc = SDRAM_TRC_DEFAULT;          /*           * tRAS equals the Minimum RAS Pulse Width divided by the ClockPeriod.         * The Kahlua spec requirement for tRAS is 4 to 7 clocks, adjust any          * value outside of this requirement to the closest spec value.         */           if (sdramTras)            {            sdramTras = ((sdramTras + (clockPeriod - 1)) / clockPeriod);            if (sdramTras < 4 || sdramTras > 7)                sdramTras = (sdramTras < 4 ? 4 : 7);            }        else            sdramTras = SDRAM_TRAS_DEFAULT;           /*           * tRP equals the Minimum Row Precharge Time divided by the ClockPeriod.         * Adjust any value to 2 or 3 clocks.         */        if (sdramTrp)            {            sdramTrp = ((sdramTrp + (clockPeriod - 1)) / clockPeriod);            if (sdramTrp < 2 || sdramTrp > 3)                sdramTrp = (sdramTrp < 2 ? 2 : 3);            }        else            sdramTrp = SDRAM_TRP_DEFAULT;           /*         * tRCD equals the Minimum RAS to CAS delay divided by the ClockPeriod.         * Adjust any value to 2 or 3 clocks.         */             if (sdramTrcd)            {            sdramTrcd = ((sdramTrcd + (clockPeriod - 1)) / clockPeriod);            if (sdramTrcd < 2 || sdramTrcd > 3)                sdramTrcd = (sdramTrcd < 2 ? 2 : 3);            }        else            sdramTrcd = SDRAM_TRCD_DEFAULT;           /*         * The tDP cannot be determined by the SDRAM SPD definitions.  It should         * be set to the default.         */        sdramTdp = SDRAM_TDP_DEFAULT;           /*         * Initialize the SDRAM Timing Parameter swr_dpl. This register setting         * causes the memory controller 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;            /*         * Calculate asrise.  This value needs to be a minimum of 50ns         * for the mv2100.         */        asrise = (50 / clockPeriod) + 1;        if (errDetChk == 0xFF)            errDetChk = 0;#ifndef INCLUDE_ECC        errDetChk = 0;#endif /* INCLUDE_ECC */        /*         * Load the Memory Interface Control Registers.         * ROMNAL (ROM nibble access time), ROMFAL (ROM first access time),         * ASRISE and ASFALL are ROM timing parameters and are based on         * the bus speed.  Note: this code cannot be a "switch" since it         * is ROM based.         */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -