📄 spd_sdram.c.svn-base
字号:
program all the registers. -------------------------------------------------------------------*/#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) /* disable memcontroller so updates work */ sdram0_cfg = 0; mtsdram0( mem_mcopt1, sdram0_cfg );#ifndef CONFIG_405EP /* not on PPC405EP */ mtsdram0( mem_besra , sdram0_besr0 ); mtsdram0( mem_besrb , sdram0_besr1 ); mtsdram0( mem_ecccf , sdram0_ecccfg ); mtsdram0( mem_eccerr, sdram0_eccesr );#endif mtsdram0( mem_rtr , sdram0_rtr ); mtsdram0( mem_pmit , sdram0_pmit ); mtsdram0( mem_mb0cf , sdram0_b0cr ); mtsdram0( mem_mb1cf , sdram0_b1cr );#ifndef CONFIG_405EP /* not on PPC405EP */ mtsdram0( mem_mb2cf , sdram0_b2cr ); mtsdram0( mem_mb3cf , sdram0_b3cr );#endif mtsdram0( mem_sdtr1 , sdram0_tr ); /* SDRAM have a power on delay, 500 micro should do */ udelay(500); sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR; if(ecc_on) sdram0_cfg |= SDRAM0_CFG_MEMCHK; mtsdram0( mem_mcopt1, sdram0_cfg ); /* kernel 2.4.2 from mvista has a bug with memory over 128MB */#ifdef MVISTA_MEM_BUG if (total_size > 128*1024*1024 ) total_size=128*1024*1024;#endif return (total_size);}int spd_read(uint addr){ char data[2]; if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0) return (int)data[0]; else return 0;}#else /* CONFIG_440 *//*-----------------------------------------------------------------------------| Memory Controller Options 0+-----------------------------------------------------------------------------*/#define SDRAM_CFG0_DCEN 0x80000000 /* SDRAM Controller Enable */#define SDRAM_CFG0_MCHK_MASK 0x30000000 /* Memory data errchecking mask */#define SDRAM_CFG0_MCHK_NON 0x00000000 /* No ECC generation */#define SDRAM_CFG0_MCHK_GEN 0x20000000 /* ECC generation */#define SDRAM_CFG0_MCHK_CHK 0x30000000 /* ECC generation and checking */#define SDRAM_CFG0_RDEN 0x08000000 /* Registered DIMM enable */#define SDRAM_CFG0_PMUD 0x04000000 /* Page management unit */#define SDRAM_CFG0_DMWD_MASK 0x02000000 /* DRAM width mask */#define SDRAM_CFG0_DMWD_32 0x00000000 /* 32 bits */#define SDRAM_CFG0_DMWD_64 0x02000000 /* 64 bits */#define SDRAM_CFG0_UIOS_MASK 0x00C00000 /* Unused IO State */#define SDRAM_CFG0_PDP 0x00200000 /* Page deallocation policy *//*-----------------------------------------------------------------------------| Memory Controller Options 1+-----------------------------------------------------------------------------*/#define SDRAM_CFG1_SRE 0x80000000 /* Self-Refresh Entry */#define SDRAM_CFG1_PMEN 0x40000000 /* Power Management Enable *//*-----------------------------------------------------------------------------+| SDRAM DEVPOT Options+-----------------------------------------------------------------------------*/#define SDRAM_DEVOPT_DLL 0x80000000#define SDRAM_DEVOPT_DS 0x40000000/*-----------------------------------------------------------------------------+| SDRAM MCSTS Options+-----------------------------------------------------------------------------*/#define SDRAM_MCSTS_MRSC 0x80000000#define SDRAM_MCSTS_SRMS 0x40000000#define SDRAM_MCSTS_CIS 0x20000000/*-----------------------------------------------------------------------------| SDRAM Refresh Timer Register+-----------------------------------------------------------------------------*/#define SDRAM_RTR_RINT_MASK 0xFFFF0000#define SDRAM_RTR_RINT_ENCODE(n) (((n) << 16) & SDRAM_RTR_RINT_MASK)#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))/*-----------------------------------------------------------------------------+| SDRAM UABus Base Address Reg+-----------------------------------------------------------------------------*/#define SDRAM_UABBA_UBBA_MASK 0x0000000F/*-----------------------------------------------------------------------------+| Memory Bank 0-7 configuration+-----------------------------------------------------------------------------*/#define SDRAM_BXCR_SDBA_MASK 0xff800000 /* Base address */#define SDRAM_BXCR_SDSZ_MASK 0x000e0000 /* Size */#define SDRAM_BXCR_SDSZ_8 0x00020000 /* 8M */#define SDRAM_BXCR_SDSZ_16 0x00040000 /* 16M */#define SDRAM_BXCR_SDSZ_32 0x00060000 /* 32M */#define SDRAM_BXCR_SDSZ_64 0x00080000 /* 64M */#define SDRAM_BXCR_SDSZ_128 0x000a0000 /* 128M */#define SDRAM_BXCR_SDSZ_256 0x000c0000 /* 256M */#define SDRAM_BXCR_SDSZ_512 0x000e0000 /* 512M */#define SDRAM_BXCR_SDAM_MASK 0x0000e000 /* Addressing mode */#define SDRAM_BXCR_SDAM_1 0x00000000 /* Mode 1 */#define SDRAM_BXCR_SDAM_2 0x00002000 /* Mode 2 */#define SDRAM_BXCR_SDAM_3 0x00004000 /* Mode 3 */#define SDRAM_BXCR_SDAM_4 0x00006000 /* Mode 4 */#define SDRAM_BXCR_SDBE 0x00000001 /* Memory Bank Enable *//*-----------------------------------------------------------------------------+| SDRAM TR0 Options+-----------------------------------------------------------------------------*/#define SDRAM_TR0_SDWR_MASK 0x80000000#define SDRAM_TR0_SDWR_2_CLK 0x00000000#define SDRAM_TR0_SDWR_3_CLK 0x80000000#define SDRAM_TR0_SDWD_MASK 0x40000000#define SDRAM_TR0_SDWD_0_CLK 0x00000000#define SDRAM_TR0_SDWD_1_CLK 0x40000000#define SDRAM_TR0_SDCL_MASK 0x01800000#define SDRAM_TR0_SDCL_2_0_CLK 0x00800000#define SDRAM_TR0_SDCL_2_5_CLK 0x01000000#define SDRAM_TR0_SDCL_3_0_CLK 0x01800000#define SDRAM_TR0_SDPA_MASK 0x000C0000#define SDRAM_TR0_SDPA_2_CLK 0x00040000#define SDRAM_TR0_SDPA_3_CLK 0x00080000#define SDRAM_TR0_SDPA_4_CLK 0x000C0000#define SDRAM_TR0_SDCP_MASK 0x00030000#define SDRAM_TR0_SDCP_2_CLK 0x00000000#define SDRAM_TR0_SDCP_3_CLK 0x00010000#define SDRAM_TR0_SDCP_4_CLK 0x00020000#define SDRAM_TR0_SDCP_5_CLK 0x00030000#define SDRAM_TR0_SDLD_MASK 0x0000C000#define SDRAM_TR0_SDLD_1_CLK 0x00000000#define SDRAM_TR0_SDLD_2_CLK 0x00004000#define SDRAM_TR0_SDRA_MASK 0x0000001C#define SDRAM_TR0_SDRA_6_CLK 0x00000000#define SDRAM_TR0_SDRA_7_CLK 0x00000004#define SDRAM_TR0_SDRA_8_CLK 0x00000008#define SDRAM_TR0_SDRA_9_CLK 0x0000000C#define SDRAM_TR0_SDRA_10_CLK 0x00000010#define SDRAM_TR0_SDRA_11_CLK 0x00000014#define SDRAM_TR0_SDRA_12_CLK 0x00000018#define SDRAM_TR0_SDRA_13_CLK 0x0000001C#define SDRAM_TR0_SDRD_MASK 0x00000003#define SDRAM_TR0_SDRD_2_CLK 0x00000001#define SDRAM_TR0_SDRD_3_CLK 0x00000002#define SDRAM_TR0_SDRD_4_CLK 0x00000003/*-----------------------------------------------------------------------------+| SDRAM TR1 Options+-----------------------------------------------------------------------------*/#define SDRAM_TR1_RDSS_MASK 0xC0000000#define SDRAM_TR1_RDSS_TR0 0x00000000#define SDRAM_TR1_RDSS_TR1 0x40000000#define SDRAM_TR1_RDSS_TR2 0x80000000#define SDRAM_TR1_RDSS_TR3 0xC0000000#define SDRAM_TR1_RDSL_MASK 0x00C00000#define SDRAM_TR1_RDSL_STAGE1 0x00000000#define SDRAM_TR1_RDSL_STAGE2 0x00400000#define SDRAM_TR1_RDSL_STAGE3 0x00800000#define SDRAM_TR1_RDCD_MASK 0x00000800#define SDRAM_TR1_RDCD_RCD_0_0 0x00000000#define SDRAM_TR1_RDCD_RCD_1_2 0x00000800#define SDRAM_TR1_RDCT_MASK 0x000001FF#define SDRAM_TR1_RDCT_ENCODE(x) (((x) << 0) & SDRAM_TR1_RDCT_MASK)#define SDRAM_TR1_RDCT_DECODE(x) (((x) & SDRAM_TR1_RDCT_MASK) >> 0)#define SDRAM_TR1_RDCT_MIN 0x00000000#define SDRAM_TR1_RDCT_MAX 0x000001FF/*-----------------------------------------------------------------------------+| SDRAM WDDCTR Options+-----------------------------------------------------------------------------*/#define SDRAM_WDDCTR_WRCP_MASK 0xC0000000#define SDRAM_WDDCTR_WRCP_0DEG 0x00000000#define SDRAM_WDDCTR_WRCP_90DEG 0x40000000#define SDRAM_WDDCTR_WRCP_180DEG 0x80000000#define SDRAM_WDDCTR_DCD_MASK 0x000001FF/*-----------------------------------------------------------------------------+| SDRAM CLKTR Options+-----------------------------------------------------------------------------*/#define SDRAM_CLKTR_CLKP_MASK 0xC0000000#define SDRAM_CLKTR_CLKP_0DEG 0x00000000#define SDRAM_CLKTR_CLKP_90DEG 0x40000000#define SDRAM_CLKTR_CLKP_180DEG 0x80000000#define SDRAM_CLKTR_DCDT_MASK 0x000001FF/*-----------------------------------------------------------------------------+| SDRAM DLYCAL Options+-----------------------------------------------------------------------------*/#define SDRAM_DLYCAL_DLCV_MASK 0x000003FC#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)/*-----------------------------------------------------------------------------+| General Definition+-----------------------------------------------------------------------------*/#define DEFAULT_SPD_ADDR1 0x53#define DEFAULT_SPD_ADDR2 0x52#define ONE_BILLION 1000000000#define MAXBANKS 4 /* at most 4 dimm banks */#define MAX_SPD_BYTES 256#define NUMHALFCYCLES 4#define NUMMEMTESTS 8#define NUMMEMWORDS 8#define MAXBXCR 4#define TRUE 1#define FALSE 0const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}, {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000}, {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555}, {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA}, {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A}, {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5}, {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA}, {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};unsigned char spd_read(uchar chip, uint addr);void get_spd_info(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void check_mem_type (unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void check_volt_type (unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void program_cfg0(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void program_cfg1(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void program_rtr (unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void program_tr0 (unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);void program_tr1 (void);void program_ecc (unsigned long num_bytes);unsignedlong program_bxcr(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks);/* * This function is reading data from the DIMM module EEPROM over the SPD bus * and uses that to program the sdram controller. * * This works on boards that has the same schematics that the IBM walnut has. * * BUG: Don't handle ECC memory * BUG: A few values in the TR register is currently hardcoded */long int spd_sdram(void) { unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS; unsigned long dimm_populated[sizeof(iic0_dimm_addr)]; unsigned long total_size; unsigned long cfg0; unsigned long mcsts; unsigned long num_dimm_banks; /* on board dimm banks */ num_dimm_banks = sizeof(iic0_dimm_addr); /* * Make sure I2C controller is initialized * before continuing. */ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); /* * Read the SPD information using I2C interface. Check to see if the * DIMM slots are populated. */ get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * Check the memory type for the dimms plugged. */ check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * Check the voltage type for the dimms plugged. */ check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program 440GP SDRAM controller options (SDRAM0_CFG0) */ program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program 440GP SDRAM controller options (SDRAM0_CFG1) */ program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program SDRAM refresh register (SDRAM0_RTR) */ program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program SDRAM Timing Register 0 (SDRAM0_TR0) */ program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program the BxCR registers to find out total sdram installed */ total_size = program_bxcr(dimm_populated, iic0_dimm_addr, num_dimm_banks); /* * program SDRAM Clock Timing Register (SDRAM0_CLKTR) */ mtsdram(mem_clktr, 0x40000000); /* * delay to ensure 200 usec has elapsed */ udelay(400); /* * enable the memory controller */ mfsdram(mem_cfg0, cfg0); mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN); /* * wait for SDRAM_CFG0_DC_EN to complete */ while(1) { mfsdram(mem_mcsts, mcsts); if ((mcsts & SDRAM_MCSTS_MRSC) != 0) { break; } } /* * program SDRAM Timing Register 1, adding some delays */ program_tr1(); /* * if ECC is enabled, initialize parity bits */ return total_size;}unsigned char spd_read(uchar chip, uint addr) { unsigned char data[2]; if (i2c_read(chip, addr, 1, data, 1) == 0) return data[0]; else return 0;}void get_spd_info(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long dimm_found; unsigned char num_of_bytes; unsigned char total_size; dimm_found = FALSE; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { num_of_bytes = 0; total_size = 0; num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); total_size = spd_read(iic0_dimm_addr[dimm_num], 1); if ((num_of_bytes != 0) && (total_size != 0)) { dimm_populated[dimm_num] = TRUE; dimm_found = TRUE;#if 0 printf("DIMM slot %lu: populated\n", dimm_num);#endif } else { dimm_populated[dimm_num] = FALSE;#if 0 printf("DIMM slot %lu: Not populated\n", dimm_num);#endif } } if (dimm_found == FALSE) { printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); hang(); }}void check_mem_type(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned char dimm_type; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); switch (dimm_type) { case 7:#if 0 printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);#endif break; default: printf("ERROR: Unsupported DIMM detected in slot %lu.\n", dimm_num); printf("Only DDR SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -