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

📄 harriersmc.c

📁 vxworks的bsp开发包(基于POWERPC的PRPMC800)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* harrierSmc.c - Support for the Harrier's System Memory Controller *//* Copyright 1999-2001 Wind River Systems, Inc. *//* Copyright 1998-2001 Motorola, Inc., All Rights Reserved *//*modification history--------------------01f,17nov00,dmw  Code cleanup.01e,14nov00,dmw  Commented out debug function harrierSmcSetupShow().01d,09oct00,dmw  Added ECC and fixed defines for Harrier.01c,08oct00,dmw  hardcoded sysCalcBusSpd to 100MHz.01b,07sep00,dmw  Updated I2C access names.01a,31aug00,dmw  Written (from verison 01d of mcpn765/hawkSmc.c).*//*DESCRIPTIONThis file contains the routines used to calculate the proper configurationvalues for the Harrier's Memory Controller (SMC) 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 "harrierSmc.h"#include "drv/sio/i8250Sio.h"/* defines */#define MHZ        1000000#define NANO2SEC   1000000000  /* number of nanoseconds per second *//* typedefs *//* globals *//* locals *//* forward declarations */void sysSetRomStartError (UINT32 offset, UINT32 value);/* external references */IMPORT UINT32 sysTimeEdges (UINT32 edges);IMPORT STATUS sysMotI2cRangeRead (UCHAR spdAddr, UCHAR offset,                                   UINT16 dataSize, UCHAR *spdData, int num);/******************************************************************************** sysCalcBusSpd - routine to calculate the speed of the 60x processor bus** This routine calculates the 60x processor bus frequency using the UART's* crystal and baud rate generator as a reference. The UART is configured* for 9600 baud, which produces a (9600 x 16) Hz frequency reference on the* UART's BAUDOUT pin, this signal is visible as bit 1 in the board status* register. The processor's bus frequency can be determined by noting the* number of elapsed "ticks" required for a given number of BAUDOUT edges and* applying for formula below. The constants are: 2 = number edge per period.* 16 = the baud rate to BAUDOUT multiplier. 4 = The processor's time base* registers are driven by a clock which is 1/4 the bus frequency.**.CS*          edges counted            elapsed ticks*  T =  ----------------------  =  --------------------*         2 * baud rate * 16        bus frequency / 4****         2 * baud rate * 16        bus frequency / 4*  F = ----------------------  = ----------------------*           edges counted           elapsed ticks***       2 * baud rate * 16 * ticks * 4*  F = ---------------------------------- = bus Frequency*               edges counted*.CE** To keep everything in 32 bits, the number of ticks must be below 3495. At* 100 MHz, 3495 time base ticks is only 140 uSecs or 43 BAUDOUT edges. At* these numbers, each time base tick is worth 29.25 KHz. By setting the number* of edges equal to the baud rate, (baud rate / edges counted) = 1 the * equation reduces to:**.CS* F = 2 * 16 * ticks * 4 = Bus Frequency.*.CE** Using this equation, the sampling interval is increased to about 31 mSecs,* each time base tick is only worth 128 Hz and there is no danger of overflowing* 32 bits.** RETURNS: The bus speed (in Hz).** NOTE: This routine must be called before interrupts are enabled and before* the serial port baud rate has been configured. Since it is usually called* very early in the start up sequence, this should not be a problem.*/#define BAUD_RATE           9600#define BAUD_RATE_CODE      12#define EDGES_PER_PERIOD    2        /* one rising, one falling = 2 */#define BAUD_CLOCK_RATIO    16       /* UART's BAUDOUT is 16x baud rate */#define TIME_BASE_RATIO     4        /* time base clock is 1/4 bus frequency */#define MULTIPLIER (EDGES_PER_PERIOD * BAUD_CLOCK_RATIO * TIME_BASE_RATIO)UINT32 sysCalcBusSpd (void)    {    UCHAR * pUart = (UCHAR *) HARRIER_UART_0_RTDL_REG;    /* configure the uart for 9600 baud */    pUart[UART_LCR * UART_REG_ADDR_INTERVAL] |= I8250_LCR_DLAB;    pUart[UART_BRDL * UART_REG_ADDR_INTERVAL] = BAUD_RATE_CODE;    pUart[UART_BRDH * UART_REG_ADDR_INTERVAL] = 0;    pUart[UART_LCR * UART_REG_ADDR_INTERVAL] &= ~I8250_LCR_DLAB;    EIEIO_SYNC;    /*     * call low-level edge timing routine, calculate bus frequency and     * return the result.     */    return (sysTimeEdges (BAUD_RATE) * MULTIPLIER);    }/******************************************************************************** sysHarrierSdramSpeedInit - routine to initialize the harrier's sdram control * reg.** This function's purpose is to initialize the SDRAM Control Register.* The register value is placed in a structure pointer and returned to* the calling program.** RETURNS: N/A*/LOCAL void sysHarrierSdramSpeedInit    (    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;       /* address of SPD buffer */    register int bank;   /* Bank index counter */    int validSpd;        /* SPD Validity flag */    UINT spdValue;       /* Temp SPD Data Value */    UINT busSpeed;       /* Bus Speed for the board */    UINT clockPeriod;    /* NanoSeconds per clock cycle */    UINT casLatency;     /* Cas Latency of the SDRAM */    UINT tCycReducedCl;  /* Cycle Time @ reduced CAS Latency */    UINT sdramTrc;       /* SDRAM Control Reg tRC field */     UINT sdramTras;      /* SDRAM Control Reg tRAS field */    UINT sdramTrp;       /* SDRAM Control Reg tRP field */    UINT sdramTrcd;      /* SDRAM Control Reg tRCD field */    UINT sdramCl3;       /* SDRAM Control Reg cl3 field */    UINT sdramTdp;       /* SDRAM Control Reg tDP field */    UINT sdramSwrDpl;    /* SDRAM Control Reg swr_dpl field */    UINT errDetChk = 0xFF;		/* Error detection/correction */        /*     * Get the BusSpeed in Hertz.  First convert the        * BusSpeed into nanoseconds, then convert bus_speed to Mhz to     * store in the CLK Frequency register.     */    /*     * BAUDOUT (sysCalcBusSpd) is not a dependable clock source on Harrier      * so this will have to be reworked.  For now the bus speed is hardcoded.      */    busSpeed = DEFAULT_BUS_CLOCK;    /*      * 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);    pSmcReg->clkFrequency = (busSpeed + (MHZ/2)) / MHZ;    validSpd      = FALSE;    sdramTras     = 0;    sdramTrp      = 0;    sdramTrcd     = 0;    sdramTdp      = 0;    sdramTrc      = 0;    sdramSwrDpl   = 0;    tCycReducedCl = 0;     casLatency    = 0xFF;     /* Start with the first Bank and check all Banks for memory. */    for (bank = 0; bank < HARRIER_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 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 SDRAM Minimum RAS Pulse Width (tRAS).  Ignore             * fractional precision. Use upper nibble only.             */            spdValue = pData[SPD_TRAS_INDEX];            if (spdValue > sdramTras)                sdramTras = spdValue;               /*             * Get the SDRAM Minimum Row Precharge Time (tRP).  Ignore             * fractional precision. Use upper nibble only.             */            spdValue = pData[SPD_TRP_INDEX];            if (spdValue > sdramTrp)                sdramTrp = spdValue;               /*             * 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;            /*             * Get the SDRAM Refresh Rate.  (Fix for 256 MB DRAMs)             * If the value is 2, then cut the harrier refresh rate in half.             */            if (pData[SPD_REFRESH_RATE_INDEX] == 2)                pSmcReg->clkFrequency = (busSpeed / MHZ) >> 1;            }          }       if (validSpd)        {        /*          * Determine the CAS latency for cl3, This will be determined by the         * SDRAM Minimum Cycle Time at reduced CAS Latency, X-1 (Byte 23) and         * the SDRAM Device Attributes CAS latency (Byte 17).  Initialize the         * cl3 parameter to 1 for a CAS latency of 3.  If the reduced CAS         * Latency, X-1, is set in byte 17 then check if the minimum cyle time         * at CAS latency X-1 is less than or equal to the ClockPeriod.  If it         * is, set the cl3 parameter to 0 for the reduced CAS latency X-1.         */        sdramCl3 = 0x01;        if (casLatency != 0xFF)            if (casLatency & 0x02)                if (tCycReducedCl <= clockPeriod)                    sdramCl3 = 0x00;         /*         * 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);            /* Adjust to Harrier defines */                      switch (sdramTrc)                {                case 8:                case 9:                case 10:                case 11:                    sdramTrc -= 8;                    break;                case 6:                case 7:                    break;                }            }        else            sdramTrc = SDRAM_TRC_DEFAULT;           /*           * tRAS equals the Minimum RAS Pulse Width divided by the ClockPeriod.         * The Harrier 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);            /* Adjust to Harrier defines */            sdramTras -= 4;            }        else            sdramTras = SDRAM_TRAS_DEFAULT;           /*           * tRP equals the Minimum Row Precharge Time divided by the ClockPeriod.         * The Harrier spec requirement for tRP is 2 (0) or 3 (1) clocks,          * adjust any value outside of this requirement to the closest spec          * value.         */        if (sdramTrp)            {            sdramTrp = ((sdramTrp + (clockPeriod - 1)) / clockPeriod);            if (sdramTrp < 2 || sdramTrp > 3)                sdramTrp = (sdramTrp < 2 ? 2 : 3);            /* Adjust to Harrier defines */            if (sdramTrp == 2)                sdramTrp = 0;            else                sdramTrp = 1;            }        else            sdramTrp = SDRAM_TRP_DEFAULT;           /*         * tRCD equals the Minimum RAS to CAS delay divided by the ClockPeriod.         * The Harrier spec requirement for tRCD is 2 or 3 clocks, adjust any          * value outside of this requirement to the closest spec value         */             if (sdramTrcd)            {            sdramTrcd = ((sdramTrcd + (clockPeriod - 1)) / clockPeriod);            if (sdramTrcd < 2 || sdramTrcd > 3)                sdramTrcd = (sdramTrcd < 2 ? 2 : 3);            /* Adjust to Harrier defines */            if (sdramTrcd == 2)                sdramTrcd = 0;            else                sdramTrcd = 1;            }        else            sdramTrcd = SDRAM_TRCD_DEFAULT;           /*         * The tDP cannot be determined by the SDRAM SPD definitions.  It should         * be set to the default.

⌨️ 快捷键说明

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