Patchwork exit from self-refresh on AMD K8 CPUs (pre revF)

login
register
about
Submitter Rudolf Marek
Date 2010-12-11 23:50:23
Message ID <4D040E3F.10300@assembler.cz>
Download mbox | patch
Permalink /patch/2420/
State Accepted
Commit r6172
Headers show

Comments

Rudolf Marek - 2010-12-11 23:50:23
On 4.12.2010 20:55, Rudolf Marek wrote:
> Hello,
>
> Following patch adds support to bring out the memory out of self refresh
> when doing resume.
>
> Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
>
> The patch is based on my 2008 patch.

Removed compilation warning & refreshed to match current tree.

Thanks,
Rudolf
Peter Stuge - 2010-12-12 22:44:01
Rudolf Marek wrote:
> On 4.12.2010 20:55, Rudolf Marek wrote:
>> Hello,
>>
>> Following patch adds support to bring out the memory out of self refresh
>> when doing resume.
>>
>> Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
>>
>> The patch is based on my 2008 patch.
>
> Removed compilation warning & refreshed to match current tree.

Acked-by: Peter Stuge <peter@stuge.se>


> +++ coreboot/src/northbridge/amd/amdk8/raminit.c	2010-12-12 00:42:07.000000000 +0100
..
> +#if 0
> +			/* the registers are marked read-only but code zeros them */
>  			dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
>  			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
> +#endif

Why not just remove the code?
Fengwei Zhang - 2010-12-14 02:48:17
Hi Rudolf,

I have tested S3 on m2v-mx_se. It works perfectly. Except following 
situation.

As you know, there are two Dimms in m2v board. if I put 1 memory module 
on it, S3 would work perfectly. If I put 2 memory module on both two 
dimms. The coreboot cannot boot. it would stop at post_cache_as_ram() 
function.

In the beginning, you read resume_backup_memory from 
backup_resume()function. resume_backup_memory should be 0 when we booting.
However, it will change after calling disable_cache_as_ram_bsp() 
function, and resume_backup_memory == 0xffffffff.

Then it will get into memcopy() function, which would stop booting.

If I am guessing right, you just put one memory module in your board for 
your testing, right?

Best,
Fengwei
Rudolf Marek - 2010-12-14 08:12:03
Hi,

Thanks for the test, although this patch is just for socket 939 and not for AM2 
;) Yes I tested with one DDR2 (I dont have two sticks)

Maybe there is something wrong with the cbmem TOC pointer. Please try to find 
out what exactly is wrong. Maybe just the memory is failing for some reason and 
it works only by luck with one dimm.

Thanks,
Rudolf

Patch

Index: coreboot/src/northbridge/amd/amdk8/raminit.c
===================================================================
--- coreboot.orig/src/northbridge/amd/amdk8/raminit.c	2010-12-12 00:42:00.000000000 +0100
+++ coreboot/src/northbridge/amd/amdk8/raminit.c	2010-12-12 00:42:07.000000000 +0100
@@ -2226,6 +2226,12 @@ 
 #endif
 {
 	int i;
+	u32 whatWait = 0;
+#if CONFIG_HAVE_ACPI_RESUME == 1
+	int suspend = acpi_is_wakeup_early();
+#else
+	int suspend = 0;
+#endif
 
 	/* Error if I don't have memory */
 	if (memory_end_k(ctrl, controllers) == 0) {
@@ -2277,13 +2283,31 @@ 
 			}
 			pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
 		}
-		dcl |= DCL_DisDqsHys;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+
+		if (!suspend) {
+			dcl |= DCL_DisDqsHys;
+			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+		}
 		dcl &= ~DCL_DisDqsHys;
 		dcl &= ~DCL_DLL_Disable;
 		dcl &= ~DCL_D_DRV;
 		dcl &= ~DCL_QFC_EN;
-		dcl |= DCL_DramInit;
+
+		if (suspend) {
+			enable_lapic();
+			init_timer();
+			dcl |= (DCL_ESR | DCL_SRS);
+			/* Handle errata 85 Insufficient Delay Between MEMCLK Startup
+			   and CKE Assertion During Resume From S3 */
+			udelay(10); /* for unregistered */
+			if (is_registered(&ctrl[i])) {
+				udelay(100); /* 110us for registered (we wait 10us already) */
+			}
+			whatWait = DCL_ESR;
+		} else {
+			dcl |= DCL_DramInit;
+			whatWait = DCL_DramInit;
+		}
 		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
 	}
 
@@ -2305,7 +2329,7 @@ 
 			if ((loops & 1023) == 0) {
 				printk(BIOS_DEBUG, ".");
 			}
-		} while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
+		} while(((dcl & whatWait) != 0) && (loops < TIMEOUT_LOOPS));
 		if (loops >= TIMEOUT_LOOPS) {
 			printk(BIOS_DEBUG, " failed\n");
 			continue;
@@ -2313,11 +2337,15 @@ 
 
 		if (!is_cpu_pre_c0()) {
 			/* Wait until it is safe to touch memory */
+#if 0
+			/* the registers are marked read-only but code zeros them */
 			dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
 			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+#endif
 			do {
 				dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-			} while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
+			} while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) ||
+					((dcl & DCL_SRS)));
 		}
 
 		printk(BIOS_DEBUG, " done\n");