I'm still working on getting the DRAM running on our E7501-based board. I've run across something in the E7501 raminit code that doesn't look right.
The E7501 datasheet isn't clear about how RAM commands get sent to the DIMMs. All it says is (for example): "NOP Command Enable - All processor cycles to DRAM result in a NOP command on the DRAM interface". It isn't clear whether a single access to DRAM causes the command to go to all DIMMs, or only to the one addressed by the access. I ran some experiments and it appears that only the addressed DIMM gets the command.
So, the raminit.c code that sends commands to RAM (below) needs to loop over all the possible DIMMs, accessing a memory address that lies within each.
static inline void do_ram_command (const struct mem_controller *ctrl, uint32_t value) { uint32_t dword; uint8_t byte; int i; uint32_t result;
/* Compute the offset */ dword = value >> 16; for(i=0;i<8;i++) { /* Set the ram command */ byte = pci_read_config8(ctrl->d0, 0x7c); byte &= 0x8f; byte |= (uint8_t)(value & 0xff); pci_write_config8(ctrl->d0, 0x7c, byte);
/* Assert the command to the memory */
result = read32(dword);
/* Go to the next base address */ dword += 0x04000000;
}
/* The command has been sent to all dimms so get out */ }
The problem is that the code assumes that the address "distance" from one DIMM to the next is always 0x04000000. Depending on the DIMM geometry, that may not be the case. Instead, shouldn't the code be using the previously-initialized DRAM boundary registers to construct addresses for each DIMM? And for systems with more than 4 GB, shouldn't it have the ability to access 36-bit addresses?
Steve Magnani www.digidescorp.com
I would need to look at that code more, but what is typically done is the boundary registers are programmed so that the ram "size" is 0x4000000 and all the commands for setup are sent to the ram. Once all the ram init is done, then the actual row boundaries are set.
We do it this way because it saves a lot of computation that is not really needed.
ron
The boundaries are configured during the "sdram_set_registers" phase of setup, but (for E7501) the "sdram_set_spd_registers" phase overrides those values before the RAM commands are sent in the "sdram_enable" phase. There is evidence in the code that this was not always the case.
Steve
-----Original Message----- From: Ronald G. Minnich [mailto:rminnich@lanl.gov] Sent: Tuesday, June 14, 2005 9:25 AM To: Steven J. Magnani Cc: linuxbios@openbios.org Subject: Re: [LinuxBIOS] E7501 SDRAM command bug?
I would need to look at that code more, but what is typically done is the boundary registers are programmed so that the ram "size" is 0x4000000 and all the commands for setup are sent to the ram. Once all the ram init is
done, then the actual row boundaries are set.
We do it this way because it saves a lot of computation that is not really needed.
ron
On Tue, 14 Jun 2005, Steven J. Magnani wrote:
The boundaries are configured during the "sdram_set_registers" phase of setup, but (for E7501) the "sdram_set_spd_registers" phase overrides those values before the RAM commands are sent in the "sdram_enable" phase. There is evidence in the code that this was not always the case.
yes, that is a wrong sequence. boundaries should always be set LAST.
do you want to take a stab at fixing this?
ron
I am working on a substantial rewrite of E7501's raminit.c to get it into a form that is easier to understand. I'll fix it there. But the changes may be too radical for the LB community-at-large, and probably won't be available for a few weeks.
Steve
-----Original Message----- From: Ronald G. Minnich [mailto:rminnich@lanl.gov] Sent: Tuesday, June 14, 2005 10:38 AM To: Steven J. Magnani Cc: linuxbios@openbios.org Subject: RE: [LinuxBIOS] E7501 SDRAM command bug?
On Tue, 14 Jun 2005, Steven J. Magnani wrote:
The boundaries are configured during the "sdram_set_registers" phase of setup, but (for E7501) the "sdram_set_spd_registers" phase overrides those values before the RAM commands are sent in the "sdram_enable" phase. There is evidence in the code that this was not always the case.
yes, that is a wrong sequence. boundaries should always be set LAST.
do you want to take a stab at fixing this?
ron
Another suspicious looking bit of E7501 RAM initialization code...in spd_set_dram_controller_mode() there is code that reads the SPD address/command hold time and configures the E7501 for "1n rule" or "2n rule" operation:
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 */ }
The issues here are frequency and scale.
The rest of the E7501 code assumes 133 MHz operation. So it looks from the comments like the comparison to 0xa0 should really be to 0x75.
But the SPD value is in _tenths_ of nanoseconds. So the above code translates to, "if the address/hold time is more than 1 ns, use 2 clock cycles per command". But the clock period is 10 ns for 100 MHz or 7.5 ns for 133 MHz, which is an order of magnitude larger than the SPD values.
I didn't see code for any other chipset that did something like this, except the Intel 855pm - where it's #ifdef'd out. I'm thinking this code should be removed.
Steve www.digidescorp.com
can you comment that code, out, and add your comment to it. Sometimes a history is very helpful for people who come later and say "Why didn't they do this?"
ron