summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/intel/i855pm/raminit.c268
1 files changed, 123 insertions, 145 deletions
diff --git a/src/northbridge/intel/i855pm/raminit.c b/src/northbridge/intel/i855pm/raminit.c
index cd103d54ef..b95bf48588 100644
--- a/src/northbridge/intel/i855pm/raminit.c
+++ b/src/northbridge/intel/i855pm/raminit.c
@@ -2,6 +2,20 @@
/* This was originally for the e7500, modified for i855pm
*/
+/* the 855pm uses only
+ * memory type (must be ddr)
+ * number of row addresses, not counting bank addresses
+ * number of column addresses
+ * number of so-dimm banks
+ * ecc, no ecc
+ * refresh rate/type
+ * number banks on each device
+ *
+ * that's it. No other bytes are used.
+ * these are bytes
+ * 2, 3, 4, 5, 11, 12 17
+ */
+
/* converted to C 6/2004 yhlu */
#define DEBUG_RAM_CONFIG 1
@@ -152,7 +166,7 @@ static const long register_values[] = {
* granularity.
*/
/* Conservatively say each row has 32MB of ram, we will fix this up later */
- 0x60, 0x00000000, (0x01 << 0) | (0x02 << 8) | (0x03 << 16) | (0x04 << 24),
+ 0x40, 0x00000000, (0x01 << 0) | (0x02 << 8) | (0x03 << 16) | (0x04 << 24),
/* DRA - DRAM Row Attribute Register
* 0x70 Row 0,1
* 0x71 Row 2,3
@@ -175,85 +189,68 @@ static const long register_values[] = {
(((0<<3)|(0<<0))<<28),
*/
/* DRT - DRAM Time Register
- * 0x78
- * [31:31] Additional CKE to CS Clock for Read/Write
- * [30:30] Additional CKE to CS clock for Precharge/Activate
- * [29:29] Back to Back Write-Read Turn Around
- * Intel recommends set to 1
+ * 0x60
+ * [31:31] tWTR -- MBZ
+ * [30:30] tWR 0 is 2, 1 is 3 clocks
+ * [29:28] back to back write-read commands spacing
+ * different rows
+ * 00 4, 01 3, 10 2, 11 reserved
*
- * [28:28] Back to Back Read-Write Turn Around
- * Intel recommends 0 for CL 2.5 and 1 for CL 2
+ * [27:26] same or different
+ * CL + .5x BL + TA(RD-WR) - DQSS
+ * wow that's hard!
+ * 00 7, 01 6, 10 5, 11 4
+ * 00 4, 01 3, 10 2, 11 reserved
*
- * [27:27] Back to Back Read Turn Around
- * Intel recommends 1 for all configs
- *
- * [26:24] Read Delay (tRD)
- * 000 == 9 clocks
- * 001 == 8 clocks
- * 010 == 7 clocks
- * 011 == 6 clocks
- * 100 == 5 clocks
- * 101 == 4 clocks
- * 110 == 3 clocks
- * Others == Reserved
- * [23:20] Reserved
- * [19:19] No Wake for DDR page closes
- * 0 is default
- * [18:16] Page Close Counter
- * 000 == infinite
- * 010 == 8-15 clocks
- * 011 == 16-31 clocks
- * 100 == 64-127 clocks
- * 101 == 128-255 clocks
- * 110 == 192-383 clocks
- * 111 == 255-510 clocks
+ * [25:25] Back to Back Read-read spacing
+ * .5xBL + TA(RD-RD)
+ * 0 4 , 1 3
+ *
+ * [24:15] Reserved
+ *
+ * [14:12] Refresh cycle time
+ * 000 14, 001 13, 010 12, 011 11, 100 10, 101 9, 110 8, 111 7
*
- * [15:12] Reserved
- * [11:11] DQS Slave DLL Dynamic Management
- * power saving, when set to 1, slave DLLS disabled
- * we'll leave it at 0 for now
+ * [11:11] tRAS, max
+ * 0 120 us, 1 reserved
+ *
* [10:09] Active to Precharge (tRAS)
- * 00 == 7 clocks
- * 01 == 6 clocks
- * 10 == 5 clocks
- * 11 == Reserved
- * [08:06] Reserved
- * [05:04] Cas Latency (tCL)
+ * 00 == 8 clocks
+ * 01 == 7 clocks
+ * 10 == 6 clocks
+ * 11 == 5 clocks
+ * [08:07] Reserved
+ * [06:05] Cas Latency (tCL)
* 00 == 2.5 Clocks
* 01 == 2.0 Clocks (default)
- * 10 == 1.5 Clocks
+ * 10 == Reserved
* 11 == Reserved
- * [03:03] Reserved
- * [02:02] Ras# to Cas# Delay (tRCD)
- * 0 == 3 DRAM Clocks
- * 1 == 2 DRAM Clocks
- * [01:01] Reserved
- * [00:00] DRAM RAS# to Precharge (tRP)
- * 0 == 3 DRAM Clocks
- * 1 == 2 DRAM Clocks
+ * [04:04] Reserved
+ * [03:02] Ras# to Cas# Delay (tRCD)
+ * 00 == 4 DRAM Clocks
+ * 01 == 3 DRAM Clocks
+ * 10 == 2 DRAM Clocks
+ * 11 == reserved
+ * [01:00] DRAM RAS# to Precharge (tRP)
+ * 00 == 4 DRAM Clocks
+ * 01 == 3 DRAM Clocks
+ * 10 == 2 DRAM Clocks
+ * 11 == reserved
*/
-#define DRT_CAS_2_5 (0<<4)
-#define DRT_CAS_2_0 (1<<4)
-#define DRT_CAS_1_5 (2<<4)
-#define DRT_CAS_MASK (3<<4)
+#define DRT_CAS_2_5 (0<<5)
+#define DRT_CAS_2_0 (1<<5)
+#define DRT_CAS_MASK (3<<5)
#if CAS_LATENCY == CAS_2_5
#define DRT_CL DRT_CAS_2_5
#elif CAS_LATENCY == CAS_2_0
#define DRT_CL DRT_CAS_2_0
-#elif CAS_LATENCY == CAS_1_5
-#define DRT_CL DRT_CAS_1_5
#endif
- /* Most unaggressive settings possible */
- /* clear bits 26:24,18:16,11,10:9,5:4,2:2,0 */
- /* ~ (7<<26)|(7<<18)|(1<<11)|(3<<10)|(3<<5)|(1<<2)|1 */
-// 0x78, 0xc0fff8c4, (1<<29)|(1<<28)|(1<<27)|(2<<24)|(2<<9)|DRT_CL|(1<<3)|(1<<1)|(1<<0),
-// 0x78, 0xc0f8f8c0, (1<<29)|(1<<28)|(1<<27)|(1<<24)|(1<<16)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0),
-// 0x78, 0xc0f8f9c0, (1<<29)|(1<<28)|(1<<27)|(1<<24)|(1<<16)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0),
- 0x78, ~((7<<26)|(7<<18)|(1<<11)|(3<<10)|(3<<5)|(1<<2)|1),
- (1<<29)|(1<<28)|(9<<26)|(0<<18)|(0<<11)|(0<<10)|(0<<5)|(0<<2)|(0<<0),
+ /* bios is 0x2a004425 */
+ /* default hardware is 18004425 */
+ /* no setting for now */
/* FDHC - Fixed DRAM Hole Control
* 0x97
@@ -332,11 +329,7 @@ static const long register_values[] = {
* [03:01] Reserved
* [00:00] DRAM type --hardwired to 1 to indicate DDR
*/
-// .long 0x7c, 0xffcefcff, (1<<22)|(2 << 20)|(1 << 16)| (0 << 8),
-// .long 0x7c, 0xff8cfcff, (1<<22)|(2 << 20)|(1 << 17)|(1 << 16)| (0 << 8),
-// .long 0x7c, 0xff80fcff, (1<<22)|(2 << 20)|(1 << 18)|(1 << 17)|(1 << 16)| (0 << 8),
-// 0x7c, 0xff82fcff, (1<<22)|(2 << 20)|(1 << 18)|(1 << 16)| (0 << 8),
- 0x7c, 0xff82f8ff, (1<<22)|(2 << 20)|(1 << 18)|(1 << 16)| (0 << 8),
+ 0x70, 0xdf0f6c7f, 0,
};
@@ -501,7 +494,7 @@ static void ram_set_d0f0_regs(const struct mem_controller *ctrl) {
#endif
}
static void sdram_set_registers(const struct mem_controller *ctrl){
- ram_set_rcomp_regs(ctrl);
+ // ram_set_rcomp_regs(ctrl);
ram_set_d0f0_regs(ctrl);
}
@@ -771,7 +764,7 @@ hw_err:
*/
static long spd_set_row_attributes(const struct mem_controller *ctrl, long dimm_mask) {
int i;
- uint32_t dword=0;
+ uint16_t word=0x7777;
int value;
@@ -803,14 +796,17 @@ static long spd_set_row_attributes(const struct mem_controller *ctrl, long dimm_
print_err("unsupported page size\r\n");
}
- /* double because I have 2 channels */
- sz.side1++;
-
/* Convert to the format needed for the DRA register */
+ /* subtract 3 (there are 8 bytes)
+ * then subtract 11
+ * (since 12 bit size should map to a value of 1)
+ * so subtract 14 total
+ */
sz.side1-=14;
/* Place in the %ebp the dra place holder */ //i
- dword |= sz.side1<<(i<<3);
+ word &= ~(7<<i);
+ word |= sz.side1<<(i<<3);
/* Test to see if the second side is present */
@@ -821,47 +817,20 @@ static long spd_set_row_attributes(const struct mem_controller *ctrl, long dimm_
print_err("unsupported page size\r\n");
}
- /* double because I have 2 channels */
- sz.side2++;
-
/* Convert to the format needed for the DRA register */
sz.side2-=14;
/* Place in the %ebp the dra place holder */ //i
- dword |= sz.side2<<((i<<3) + 4 );
+ word &= ~(7<<i);
+ word |= sz.side2<<((i<<3) + 4 );
}
}
-
- /* Now add the SDRAM chip width to the DRA */
- struct dimm_width wd;
- wd = sdram_spd_get_width(ctrl->channel0[i]);
-
-#if DEBUG_RAM_CONFIG
- print_debug("width =");
- print_debug_hex32(wd.side1);
- print_debug(" ");
- print_debug_hex32(wd.side2);
- print_debug("\r\n");
-#endif
-
- if(wd.side1 == 0) continue;
- if(wd.side1 == 4) {
- /* Enable an x4 device */
- dword |= 0x08 << (i<<3);
- }
-
- if(wd.side2 == 0) continue;
- if(wd.side2 == 4) {
- /* Enable an x4 device */
- dword |= 0x08 << ((i<<3 ) + 4);
- }
-
/* go to the next DIMM */
}
/* Write the new row attributes register */
- pci_write_config32(ctrl->d0, 0x70, dword);
+ pci_write_config32(ctrl->d0, 0x50, word);
return dimm_mask;
@@ -1122,9 +1091,9 @@ static const uint32_t refresh_rate_index[] = {
* 7.8us -> 7.8us
* 31.3s -> 15.6us
* 62.5us -> 15.6us
- * 125us -> 64us
+ * 125us -> 15.6us
*/
- 1, 0xff, 2, 1, 1, 3
+ 1, 0xff, 2, 1, 1, 1
};
#define MAX_SPD_REFRESH_RATE 5
@@ -1135,9 +1104,19 @@ static long spd_set_dram_controller_mode (const struct mem_controller *ctrl, lon
int value;
uint32_t ecx;
uint32_t edx;
+ /* on this chipset we only do refresh "slow" or "fast" for now */
+ /* we start out assuming "slow" (15.6 microseconds) */
+ uint32_t refrate = 1; /* better than 7.8 */
/* Read the inititial state */
- dword = pci_read_config32(ctrl->d0, 0x7c);
+ dword = pci_read_config32(ctrl->d0, 0x70);
+ // WTF?
+ //dword |= 0x10000;
+#if 0 // DEBUG_RAM_CONFIG
+ print_debug("spd_detect_dimms: 0x70.l is:");
+ print_debug_hex32(dword);
+ print_debug("\r\n");
+#endif
#if 0
/* Test if ECC cmos option is enabled */
@@ -1165,8 +1144,17 @@ static long spd_set_dram_controller_mode (const struct mem_controller *ctrl, lon
value = spd_read_byte(ctrl->channel0[i], 11); /* SDRAM type */
if(value < 0) continue;
if(value !=2 ) {
+#if DEBUG_RAM_CONFIG
+ print_debug("spd_detect_dimms:\r\n");
+#endif
/* Clear the ecc enable */
dword &= ~(3 << 20);
+#if 0 &&DEBUG_RAM_CONFIG
+ print_debug("spd_detect_dimms: no ecc so set:");
+ print_debug_hex32(dword);
+ print_debug("\r\n");
+#endif
+
}
value = spd_read_byte(ctrl->channel0[i], 12); /* SDRAM refresh rate */
if(value < 0 ) continue;
@@ -1174,34 +1162,36 @@ static long spd_set_dram_controller_mode (const struct mem_controller *ctrl, lon
if(value > MAX_SPD_REFRESH_RATE) { print_err("unsupported refresh rate\r\n");}
// if(value == 0xff) { print_err("unsupported refresh rate\r\n");}
- ecx = refresh_rate_index[value];
-
- /* Isolate the old refresh rate setting */
- /* Load the refresh rate ranks */
- edx = refresh_rate_rank[(dword >> 8) & 3]<<8;
- edx |= refresh_rate_rank[ecx] & 0xff;
-
- /* See if the new refresh rate is more conservative than the old
- * refresh rate setting. (Lower ranks are more conservative)
- */
- if((edx & 0xff)< ((edx >> 8) & 0xff) ) {
- /* Clear the old refresh rate */
- dword &= ~(3<<8);
- /* Move in the new refresh rate */
- dword |= (ecx<<8);
- }
-
+#if DEBUG_RAM_CONFIG
+ print_debug("spd_detect_dimms: ref rate index:");
+ print_debug_hex8(value);
+ print_debug("\r\n");
+#endif
+ if (value == 2) /* have to go faster */
+ refrate = 2;
+#if 0 &&DEBUG_RAM_CONFIG
+ print_debug("spd_detect_dimms: dword is now w/refresh:");
+ print_debug_hex32(dword);
+ print_debug("\r\n");
+#endif
+ /* no applicability here but there are similar things
+ * we'll try later.
+ */
+#if 0
value = spd_read_byte(ctrl->channel0[i], 33); /* Address and command hold time after clock */
if(value < 0) continue;
if(value >= 0xa0) { /* At 133Mhz this constant should be 0x75 */
dword &= ~(1<<16); /* Use two clock cyles instead of one */
}
+#endif
/* go to the next DIMM */
}
+ /* set the refrate now */
+ dword |= (refrate << 7);
/* Now write the controller mode */
- pci_write_config32(ctrl->d0, 0x7c, dword);
+ pci_write_config32(ctrl->d0, 0x70, dword);
return dimm_mask;
@@ -1396,14 +1386,15 @@ static long spd_set_dram_timing(const struct mem_controller *ctrl, long dimm_mas
int value;
/* Read the inititial state */
- dword = pci_read_config32(ctrl->d0, 0x78);
+ dword = pci_read_config32(ctrl->d0, 0x60);
#if 0
# Intel clears top bit here, should we?
# No the default is on and for normal timming it should be on. Tom Z
andl $0x7f, %esi
#endif
-
+
+HERE. WHat's the frequency kenneth?
for(i = 0; i < DIMM_SOCKETS; i++) {
if (!(dimm_mask & (1 << i))) {
continue;
@@ -1485,7 +1476,7 @@ static long spd_set_dram_timing(const struct mem_controller *ctrl, long dimm_mas
dword |= (1<<29);
}
- pci_write_config32(ctrl->d0, 0x78, dword);
+ pci_write_config32(ctrl->d0, 0x60, dword);
return dimm_mask;
@@ -1512,23 +1503,7 @@ static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
dimm_mask |= (1 << i);
}
}
-#if 0
- device = ctrl->channel1[i];
- if (device) {
- byte = spd_read_byte(ctrl->channel1[i], 2);
- if (byte == 7) {
- dimm_mask |= (1 << (i + DIMM_SOCKETS));
- }
- }
-#endif
}
-#if 1
- i = (dimm_mask>>DIMM_SOCKETS);
- if(i != (dimm_mask & ( (1<<DIMM_SOCKETS) - 1) ) ) {
- die("now we only support dual channel\r\n");
- }
-
-#endif
return dimm_mask;
}
@@ -1661,12 +1636,15 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl) {
print_debug(spd_pre_set);
#endif
dimm_mask = spd_set_row_attributes(ctrl,dimm_mask);
+
if (dimm_mask < 0)
goto hw_spd_err;
dimm_mask = spd_set_dram_controller_mode(ctrl,dimm_mask);
+
if (dimm_mask < 0)
goto hw_spd_err;
dimm_mask = spd_set_cas_latency(ctrl,dimm_mask);
+ dump_pci_device(PCI_DEV(0,0,1));
if (dimm_mask < 0)
goto hw_spd_err;
dimm_mask = spd_set_dram_timing(ctrl,dimm_mask);