Changeset 3765
- Timestamp:
- 11/21/08 18:14:40 (7 weeks ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/coreboot-v2/src/northbridge/intel/i82810/raminit.c
r3764 r3765 2 2 * This file is part of the coreboot project. 3 3 * 4 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>4 * Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de> 5 5 * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com> 6 * Copyright (C) 2008 Elia Yehuda <z4ziggy@gmail.com> 6 7 * 7 8 * This program is free software; you can redistribute it and/or modify … … 56 57 #define RAM_COMMAND_CBR 0x7 /* CBR */ 57 58 59 /* 60 * Table which returns the RAM size in MB when fed the DRP[7:4] or [3:0] value. 61 * Note that 2 is a value which the DRP should never be programmed to. 62 * Some size values appear twice, due to single-sided vs dual-sided banks. 63 */ 64 static const u16 translate_i82810_to_mb[] = { 65 /* DRP 0 1 (2) 3 4 5 6 7 8 9 A B C D E F */ 66 /* MB */0, 8, 0, 16, 16, 24, 32, 32, 48, 64, 64, 96, 128, 128, 192, 256, 67 }; 68 69 /* Size of bank#0 for dual-sided DIMMs */ 70 static const u8 translate_i82810_to_bank[] = { 71 /* DRP 0 1 (2) 3 4 5 6 7 8 9 A B C D E F */ 72 /* MB */0, 0, 0, 8, 0, 16, 16, 0, 32, 32, 0, 64, 64, 0, 128, 128, 73 }; 74 58 75 /*----------------------------------------------------------------------------- 59 76 SDRAM configuration functions. … … 63 80 * Send the specified RAM command to all DIMMs. 64 81 * 65 * @param TODO 66 * @param TODO 67 */ 68 static void do_ram_command(uint32_t command, uint32_t addr_offset, 69 uint32_t row_offset) 70 { 71 uint8_t reg; 72 73 /* TODO: Support for multiple DIMMs. */ 82 * @param The RAM command to send to the DIMM(s). 83 */ 84 static void do_ram_command(u8 command) 85 { 86 u32 addr, addr_offset; 87 u16 dimm_size, dimm_start, dimm_bank; 88 u8 reg8, drp; 89 int i, caslatency; 74 90 75 91 /* Configure the RAM command. */ 76 reg = pci_read_config8(PCI_DEV(0, 0, 0), DRAMT); 77 reg &= 0x1f; /* Clear bits 7-5. */ 78 reg |= command << 5; 79 pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, reg); 80 81 /* RAM_COMMAND_NORMAL affects only the memory controller and 82 doesn't need to be "sent" to the DIMMs. */ 83 /* if (command == RAM_COMMAND_NORMAL) return; */ 84 85 PRINT_DEBUG(" Sending RAM command 0x"); 86 PRINT_DEBUG_HEX8(reg); 87 PRINT_DEBUG(" to 0x"); 88 PRINT_DEBUG_HEX32(0 + addr_offset); // FIXME 89 PRINT_DEBUG("\r\n"); 90 91 /* Read from (DIMM start address + addr_offset). */ 92 read32(0 + addr_offset); //first offset is always 0 93 read32(row_offset + addr_offset); 92 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), DRAMT); 93 reg8 &= 0x1f; /* Clear bits 7-5. */ 94 reg8 |= command << 5; 95 pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, reg8); 96 97 /* 98 * RAM_COMMAND_NORMAL affects only the memory controller and 99 * doesn't need to be "sent" to the DIMMs. 100 */ 101 if (command == RAM_COMMAND_NORMAL) 102 return; 103 104 dimm_start = 0; 105 for (i = 0; i < DIMM_SOCKETS; i++) { 106 /* 107 * Calculate the address offset where we need to "send" the 108 * DIMM command to. For most commands the offset is 0, only 109 * RAM_COMMAND_MRS needs special values, see below. 110 * The final address offset bits depend on three things: 111 * 112 * (1) Some hardcoded values specified in the datasheet. 113 * (2) Which CAS latency we will use/set. This is the SMAA[4] 114 * bit, which is 1 for CL3, and 0 for CL2. The bitstring 115 * so far has the form '00000001X1010', X being SMAA[4]. 116 * (3) The DIMM to which we want to send the command. For 117 * DIMM0 no special handling is needed, but for DIMM1 we 118 * must invert the four bits SMAA[7:4] (see datasheet). 119 * 120 * Finally, the bitstring has to be shifted 3 bits to the left. 121 * See i810 datasheet pages 43, 85, and 86 for details. 122 */ 123 addr_offset = 0; 124 caslatency = 3; /* TODO: Dynamically get CAS latency later. */ 125 if (i == 0 && command == RAM_COMMAND_MRS && caslatency == 3) 126 addr_offset = 0x1d0; /* DIMM0, CL3, 0000111010000 */ 127 if (i == 1 && command == RAM_COMMAND_MRS && caslatency == 3) 128 addr_offset = 0x650; /* DIMM1, CL3, 0011001010000 */ 129 if (i == 0 && command == RAM_COMMAND_MRS && caslatency == 2) 130 addr_offset = 0x150; /* DIMM0, CL2, 0000101010000 */ 131 if (i == 1 && command == RAM_COMMAND_MRS && caslatency == 2) 132 addr_offset = 0x1a0; /* DIMM1, CL2, 0000110100000 */ 133 134 drp = pci_read_config8(PCI_DEV(0, 0, 0), DRP); 135 drp = (drp >> (i * 4)) & 0x0f; 136 137 dimm_size = translate_i82810_to_mb[drp]; 138 addr = (dimm_start * 1024 * 1024) + addr_offset; 139 if (dimm_size) { 140 PRINT_DEBUG(" Sending RAM command 0x"); 141 PRINT_DEBUG_HEX8(reg8); 142 PRINT_DEBUG(" to 0x"); 143 PRINT_DEBUG_HEX32(addr); 144 PRINT_DEBUG("\r\n"); 145 146 read32(addr); 147 } 148 149 dimm_bank = translate_i82810_to_bank[drp]; 150 addr = ((dimm_start + dimm_bank) * 1024 * 1024) + addr_offset; 151 if (dimm_bank) { 152 PRINT_DEBUG(" Sending RAM command 0x"); 153 PRINT_DEBUG_HEX8(reg8); 154 PRINT_DEBUG(" to 0x"); 155 PRINT_DEBUG_HEX32(addr); 156 PRINT_DEBUG("\r\n"); 157 158 read32(addr); 159 } 160 161 dimm_start += dimm_size; 162 } 94 163 } 95 164 … … 101 170 * Set DRP - DRAM Row Population Register (Device 0). 102 171 */ 103 static void spd_set_dram_size( uint32_t row_offset)172 static void spd_set_dram_size(void) 104 173 { 105 174 /* The variables drp and dimm_size have to be ints since all the … … 138 207 } 139 208 140 /* Set the row offset, in KBytes (should this be141 * Kbits?). Note that this offset is the start of the142 * next row.143 */144 row_offset = (dimm_size * 4 * 1024);145 146 /* This is the way I was doing this, it's provided147 * mainly as an alternative to the "new" way.148 */149 150 #if 0151 /* 8MB */152 if (dimm_size == 0x2)153 dimm_size = 0x1;154 /* 16MB */155 else if (dimm_size == 0x4)156 dimm_size = 0x4;157 /* 32MB */158 else if (dimm_size == 0x8)159 dimm_size = 0x7;160 /* 64 MB */161 else if (dimm_size == 0x10)162 dimm_size = 0xa;163 /* 128 MB */164 else if (dimm_size == 0x20)165 dimm_size = 0xd;166 else167 print_debug("Ram Size not supported\r\n");168 #endif169 170 209 /* This array is provided in raminit.h, because it got 171 210 * extremely messy. The above way is cleaner, but … … 213 252 /* 214 253 * TODO: BUFF_SC needs to be set according to the DRAM tech (x8, x16, 215 * or x32), but the datasheet doesn't list all the detai sl. Currently, it254 * or x32), but the datasheet doesn't list all the details. Currently, it 216 255 * needs to be pulled from the output of 'lspci -xxx Rx92'. 217 256 * … … 247 286 -----------------------------------------------------------------------------*/ 248 287 249 /**250 * TODO.251 */252 288 static void sdram_set_registers(void) 253 289 { … … 293 329 } 294 330 295 /**296 * TODO.297 */298 331 static void sdram_set_spd_registers(void) 299 332 { 300 /* spd_set_dram_size() moved into sdram_enable() to prevent having 301 * to pass a variable between here and there. 302 */ 333 spd_set_dram_size(); 303 334 set_dram_buffer_strength(); 304 305 335 set_dram_timing(); 306 336 } … … 313 343 int i; 314 344 315 /* Todo: this will currently work with either one dual sided or two316 * single sided DIMMs. Needs to work with 2 dual sided DIMMs in the317 * long run.318 */319 uint32_t row_offset;320 321 spd_set_dram_size(row_offset);322 323 345 /* 1. Apply NOP. */ 324 346 PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n"); 325 do_ram_command(RAM_COMMAND_NOP , 0, row_offset);347 do_ram_command(RAM_COMMAND_NOP); 326 348 udelay(200); 327 349 328 350 /* 2. Precharge all. Wait tRP. */ 329 351 PRINT_DEBUG("RAM Enable 2: Precharge all\r\n"); 330 do_ram_command(RAM_COMMAND_PRECHARGE , 0, row_offset);352 do_ram_command(RAM_COMMAND_PRECHARGE); 331 353 udelay(1); 332 354 333 355 /* 3. Perform 8 refresh cycles. Wait tRC each time. */ 334 356 PRINT_DEBUG("RAM Enable 3: CBR\r\n"); 335 do_ram_command(RAM_COMMAND_CBR, 0, row_offset);336 357 for (i = 0; i < 8; i++) { 337 read32(0); 338 read32(row_offset); 358 do_ram_command(RAM_COMMAND_CBR); 339 359 udelay(1); 340 360 } … … 342 362 /* 4. Mode register set. Wait two memory cycles. */ 343 363 PRINT_DEBUG("RAM Enable 4: Mode register set\r\n"); 344 do_ram_command(RAM_COMMAND_MRS , 0x1d0, row_offset);364 do_ram_command(RAM_COMMAND_MRS); 345 365 udelay(2); 346 366 347 367 /* 5. Normal operation (enables refresh) */ 348 368 PRINT_DEBUG("RAM Enable 5: Normal operation\r\n"); 349 do_ram_command(RAM_COMMAND_NORMAL , 0, row_offset);369 do_ram_command(RAM_COMMAND_NORMAL); 350 370 udelay(1); 351 371
