Uwe Hermann wrote:
On Mon, Feb 26, 2007 at 04:24:04PM -0500, Corey Osgood wrote:
I'm currently playing with the raminit.c that I've attached, it's from one of his old posts. Uwe, have you done anything more since this? And do you have a new northbridge.c also? Mine's a hack from what was there (fixing regs, etc), I have no idea if it works right or not.
I'll post a full patch which should work out of the box (the infrastructure for building the target at least).
Okay, thanks. I'm not sure if my target's set up right or not, but it seems to be working for now. Even if mine is correct, yours will probably be cleaner by far ;)
I did try some more things to get the code to work properly, but with no success so far. I'm pretty sure it's some small quirk I got wrong, but I haven't found out what it is, yet. Maybe a timing issue...
The code will probably not work for you as is, you must adjust it to the extact RAM you're using (and location of the RAM, i.e. in which RAM slot it is located).
Just out of curiousity, in sdram_set_registers, are those values you decided to send, or ones from a running system?
Yes, mostly. I got them from a running Linux on exactly the same system (you should not change jumpers, RAM parts, CPU, whatever, or else those values will probably also change).
You can get the northbridge values via: lspci -xxx -v -s 00:00.0
I've already gotten the DRB registers set up for my configuration, along with changing a half a dozen registers or so to fit my lspci -xxx and the 440zx docs (for instance, your NBXCFG sets ECC, which the 440zx doesn't support). It hasn't made any huge difference though. There was one register that I meant to point out to you as having an odd value, but I can't remember now which one it was.
I don't know if you've noticed this or not, but with your raminit.c, your do_ram_command seems to be doubling the value it should be setting. I added this to the end of it:
RAM_DEBUG_MESSAGE(" SDRAMC = "); print_debug_hex16(pci_read_config16(ctrl->d0, SDRAMC)); RAM_DEBUG_MESSAGE("\r\n");
And got this:
Ram Enable 1: Power up Ram Enable 2: Start clocks Ram Enable 3: Apply NOP SDRAMC = 0120 Ram Enable 4: Precharge all SDRAMC = 0140 Ram Enable 8: CBR SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 SDRAMC = 0180 Ram Enable 9: Mode register set SDRAMC = 0160 Ram Enable 11: Normal operation SDRAMC = 0100 Finally enabling refresh
If you can't see the problem, I can't really explain it...NOP should be 0110, Precharge should be 0120, and so on, they're all double in the 3rd value. So, I commented all the do_ram_commands out (since I can't see the problem with it) and did ram init using pci_write_config16, setting what I know the values should be, and then NOP would not report as being set (and ram still failed). So, I set up a for loop to set NOP until the northbridge reported that it was set...I got an infinite loop. My loop might be wrong (it's a bit hackish), can someone tell me if it should work? Or does NOP simply not set?
/* 3. Apply NOP. */ RAM_DEBUG_MESSAGE("Ram Enable 3: Apply NOP\r\n"); int s; for( s = 0; s != 0110; s = pci_read_config16( ctrl->d0, SDRAMC ) ) { RAM_DEBUG_MESSAGE("Do NOPs til it cooperates!\r\n"); pci_write_config8(ctrl->d0, SDRAMC, 0x0110); read32(0x04000000); EXTRA_DELAY }
If that's all set, I suspect there's some register that has to be changed before it will set NOP, perhaps one not in the docs.
Finally, is there any reason not to use a for loop during CBR? I've noticed that noone seems to, but it would make the code so much cleaner.
-Corey