📄 mpc8266ads.c
字号:
int j; /* Keep the compiler from complaining about potentially uninitialized vars */ data_width = rows = banks = cols = caslatency = 0; /* * Read the SDRAM SPD EEPROM via I2C. */ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); i2c_read(SDRAM_SPD_ADDR, 0, 1, &data, 1); spd_size = data; cksum = data; for(j = 1; j < 64; j++) { /* read only the checksummed bytes */ /* note: the I2C address autoincrements when alen == 0 */ i2c_read(SDRAM_SPD_ADDR, 0, 0, &data, 1); /*printf("addr %d = 0x%02x\n", j, data);*/ if(j == 5) chipselects = data & 0x0F; else if(j == 6) data_width = data; else if(j == 7) data_width |= data << 8; else if(j == 3) rows = data & 0x0F; else if(j == 4) cols = data & 0x0F; else if(j == 12) { /* * Refresh rate: this assumes the prescaler is set to * approximately 0.39uSec per tick and the target refresh period * is about 85% of maximum. */ switch(data & 0x7F) { default: case 0: psrt = 0x21; /* 15.625uS */ break; case 1: psrt = 0x07; /* 3.9uS */ break; case 2: psrt = 0x0F; /* 7.8uS */ break; case 3: psrt = 0x43; /* 31.3uS */ break; case 4: psrt = 0x87; /* 62.5uS */ break; case 5: psrt = 0xFF; /* 125uS */ break; } } else if(j == 17) banks = data; else if(j == 18) { caslatency = 3; /* default CL */# if(PESSIMISTIC_SDRAM) if((data & 0x04) != 0) caslatency = 3; else if((data & 0x02) != 0) caslatency = 2; else if((data & 0x01) != 0) caslatency = 1;# else if((data & 0x01) != 0) caslatency = 1; else if((data & 0x02) != 0) caslatency = 2; else if((data & 0x04) != 0) caslatency = 3;# endif else { printf ("WARNING: Unknown CAS latency 0x%02X, using 3\n", data); } } else if(j == 63) { if(data != cksum) { printf ("WARNING: Configuration data checksum failure:" " is 0x%02x, calculated 0x%02x\n", data, cksum); } } cksum += data; } /* We don't trust CL less than 2 (only saw it on an old 16MByte DIMM) */ if(caslatency < 2) { printf("CL was %d, forcing to 2\n", caslatency); caslatency = 2; } if(rows > 14) { printf("This doesn't look good, rows = %d, should be <= 14\n", rows); rows = 14; } if(cols > 11) { printf("This doesn't look good, columns = %d, should be <= 11\n", cols); cols = 11; } if((data_width != 64) && (data_width != 72)) { printf("WARNING: SDRAM width unsupported, is %d, expected 64 or 72.\n", data_width); } width = 3; /* 2^3 = 8 bytes = 64 bits wide */ /* * Convert banks into log2(banks) */ if (banks == 2) banks = 1; else if(banks == 4) banks = 2; else if(banks == 8) banks = 3; sdram_size = 1 << (rows + cols + banks + width);#if(CONFIG_PBI == 0) /* bank-based interleaving */ rowst = ((32 - 6) - (rows + cols + width)) * 2;#else rowst = 32 - (rows + banks + cols + width);#endif or = ~(sdram_size - 1) | /* SDAM address mask */ ((banks-1) << 13) | /* banks per device */ (rowst << 9) | /* rowst */ ((rows - 9) << 6); /* numr */ /*printf("memctl->memc_or2 = 0x%08x\n", or);*/ /* * SDAM specifies the number of columns that are multiplexed * (reference AN2165/D), defined to be (columns - 6) for page * interleave, (columns - 8) for bank interleave. * * BSMA is 14 - max(rows, cols). The bank select lines come * into play above the highest "address" line going into the * the SDRAM. */#if(CONFIG_PBI == 0) /* bank-based interleaving */ sdam = cols - 8; bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); sda10 = sdam + 2;#else sdam = cols - 6; bsma = ((31 - width) - 14) - ((rows > cols) ? rows : cols); sda10 = sdam;#endif#if(PESSIMISTIC_SDRAM) psdmr = (CONFIG_PBI |\ PSDMR_RFEN |\ PSDMR_RFRC_16_CLK |\ PSDMR_PRETOACT_8W |\ PSDMR_ACTTORW_8W |\ PSDMR_WRC_4C |\ PSDMR_EAMUX |\ PSDMR_BUFCMD) |\ caslatency |\ ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ (sdam << 24) |\ (bsma << 21) |\ (sda10 << 18);#else psdmr = (CONFIG_PBI |\ PSDMR_RFEN |\ PSDMR_RFRC_7_CLK |\ PSDMR_PRETOACT_3W | /* 1 for 7E parts (fast PC-133) */ \ PSDMR_ACTTORW_2W | /* 1 for 7E parts (fast PC-133) */ \ PSDMR_WRC_1C | /* 1 clock + 7nSec */ EAMUX |\ BUFCMD) |\ caslatency |\ ((caslatency - 1) << 6) | /* LDOTOPRE is CL - 1 */ \ (sdam << 24) |\ (bsma << 21) |\ (sda10 << 18);#endif /*printf("psdmr = 0x%08x\n", psdmr);*/ /* * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35): * * "At system reset, initialization software must set up the * programmable parameters in the memory controller banks registers * (ORx, BRx, P/LSDMR). After all memory parameters are configured, * system software should execute the following initialization sequence * for each SDRAM device. * * 1. Issue a PRECHARGE-ALL-BANKS command * 2. Issue eight CBR REFRESH commands * 3. Issue a MODE-SET command to initialize the mode register * * Quote from Micron MT48LC8M16A2 data sheet: * * "...the SDRAM requires a 100uS delay prior to issuing any * command other than a COMMAND INHIBIT or NOP. Starting at some * point during this 100uS period and continuing at least through * the end of this period, COMMAND INHIBIT or NOP commands should * be applied." * * "Once the 100uS delay has been satisfied with at least one COMMAND * INHIBIT or NOP command having been applied, a /PRECHARGE command/ * should be applied. All banks must then be precharged, thereby * placing the device in the all banks idle state." * * "Once in the idle state, /two/ AUTO REFRESH cycles must be * performed. After the AUTO REFRESH cycles are complete, the * SDRAM is ready for mode register programming." * * (/emphasis/ mine, gvb) * * The way I interpret this, Micron start up sequence is: * 1. Issue a PRECHARGE-BANK command (initial precharge) * 2. Issue a PRECHARGE-ALL-BANKS command ("all banks ... precharged") * 3. Issue two (presumably, doing eight is OK) CBR REFRESH commands * 4. Issue a MODE-SET command to initialize the mode register * * -------- * * The initial commands are executed by setting P/LSDMR[OP] and * accessing the SDRAM with a single-byte transaction." * * The appropriate BRx/ORx registers have already been set when we * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE. */ memctl->memc_mptpr = CFG_MPTPR; memctl->memc_psrt = psrt; memctl->memc_br2 = CFG_BR2_PRELIM; memctl->memc_or2 = or; memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; for (i = 0; i < 8; i++) *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; *ramaddr = c; /* * Do it a second time for the second set of chips if the DIMM has * two chip selects (double sided). */ if(chipselects > 1) { ramaddr += sdram_size; memctl->memc_br3 = CFG_BR3_PRELIM + sdram_size; memctl->memc_or3 = or; memctl->memc_psdmr = psdmr | PSDMR_OP_PREA; *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR; for (i = 0; i < 8; i++) *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_MRW; *ramaddr = c; memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN; *ramaddr = c; } /* print info */ printf("SDRAM configuration read from SPD\n"); printf("\tSize per side = %dMB\n", sdram_size >> 20); printf("\tOrganization: %d sides, %d banks, %d Columns, %d Rows, Data width = %d bits\n", chipselects, 1<<(banks), cols, rows, data_width); printf("\tRefresh rate = %d, CAS latency = %d\n", psrt, caslatency); printf("\tTotal size: "); return (sdram_size * chipselects); /*return (16 * 1024 * 1024);*/}#ifdef CONFIG_PCIstruct pci_controller hose;extern void pci_mpc8250_init(struct pci_controller *);void pci_init_board(void){ pci_mpc8250_init(&hose);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -