aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-09-05 18:40:31 -0500
committerMartin Roth <martinroth@google.com>2015-10-30 18:19:37 +0100
commit59d0e040c89b5eea5f2febfa73de57d45a9ae535 (patch)
treeb5e51d168e40dcb8025a32ea0695f68ef66dd7ff /src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
parent4ea0cc087eb7adf5ce49f445bf590129b9ba97e0 (diff)
northbridge/amd/amdmct/mct_ddr3: Add initial Suspend to RAM (S3) support
Change-Id: Ic97567851fa40295bc21cefd7537407b99d71709 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11952 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/mct_d.c')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.c154
1 files changed, 82 insertions, 72 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index 81a75768ab..b92375b022 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -282,91 +282,101 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
u8 Node, NodesWmem;
u32 node_sys_base;
+ uint8_t s3resume = acpi_is_wakeup_s3();
+
restartinit:
mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/
- NodesWmem = 0;
- node_sys_base = 0;
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
+ if (s3resume) {
+#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: Restoring DCT configuration from NVRAM\n");
+ restore_mct_information_from_nvram();
+#endif
+ } else {
+ NodesWmem = 0;
+ node_sys_base = 0;
+ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
+ struct DCTStatStruc *pDCTstat;
+ pDCTstat = pDCTstatA + Node;
- /* Zero out data structures to avoid false detection of DIMMs */
- memset(pDCTstat, 0, sizeof(struct DCTStatStruc));
-
- /* Initialize data structures */
- pDCTstat->Node_ID = Node;
- pDCTstat->dev_host = PA_HOST(Node);
- pDCTstat->dev_map = PA_MAP(Node);
- pDCTstat->dev_dct = PA_DCT(Node);
- pDCTstat->dev_nbmisc = PA_NBMISC(Node);
- pDCTstat->NodeSysBase = node_sys_base;
-
- printk(BIOS_DEBUG, "%s: mct_init Node %d\n", __func__, Node);
- mct_init(pMCTstat, pDCTstat);
- mctNodeIDDebugPort_D();
- pDCTstat->NodePresent = NodePresent_D(Node);
- if (pDCTstat->NodePresent) { /* See if Node is there*/
- printk(BIOS_DEBUG, "%s: clear_legacy_Mode\n", __func__);
- clear_legacy_Mode(pMCTstat, pDCTstat);
- pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node);
-
- printk(BIOS_DEBUG, "%s: mct_InitialMCT_D\n", __func__);
- mct_InitialMCT_D(pMCTstat, pDCTstat);
-
- printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__);
- mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/
-
- printk(BIOS_DEBUG, "%s: mct_initDCT\n", __func__);
- mct_initDCT(pMCTstat, pDCTstat);
- if (pDCTstat->ErrCode == SC_FatalErr) {
- goto fatalexit; /* any fatal errors?*/
- } else if (pDCTstat->ErrCode < SC_StopError) {
- NodesWmem++;
- }
- } /* if Node present */
- node_sys_base = pDCTstat->NodeSysBase;
- node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F;
- }
- if (NodesWmem == 0) {
- printk(BIOS_DEBUG, "No Nodes?!\n");
- goto fatalexit;
- }
+ /* Zero out data structures to avoid false detection of DIMMs */
+ memset(pDCTstat, 0, sizeof(struct DCTStatStruc));
+
+ /* Initialize data structures */
+ pDCTstat->Node_ID = Node;
+ pDCTstat->dev_host = PA_HOST(Node);
+ pDCTstat->dev_map = PA_MAP(Node);
+ pDCTstat->dev_dct = PA_DCT(Node);
+ pDCTstat->dev_nbmisc = PA_NBMISC(Node);
+ pDCTstat->NodeSysBase = node_sys_base;
+
+ printk(BIOS_DEBUG, "%s: mct_init Node %d\n", __func__, Node);
+ mct_init(pMCTstat, pDCTstat);
+ mctNodeIDDebugPort_D();
+ pDCTstat->NodePresent = NodePresent_D(Node);
+ if (pDCTstat->NodePresent) { /* See if Node is there*/
+ printk(BIOS_DEBUG, "%s: clear_legacy_Mode\n", __func__);
+ clear_legacy_Mode(pMCTstat, pDCTstat);
+ pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node);
+
+ printk(BIOS_DEBUG, "%s: mct_InitialMCT_D\n", __func__);
+ mct_InitialMCT_D(pMCTstat, pDCTstat);
+
+ printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__);
+ mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/
+
+ printk(BIOS_DEBUG, "%s: mct_initDCT\n", __func__);
+ mct_initDCT(pMCTstat, pDCTstat);
+ if (pDCTstat->ErrCode == SC_FatalErr) {
+ goto fatalexit; /* any fatal errors?*/
+ } else if (pDCTstat->ErrCode < SC_StopError) {
+ NodesWmem++;
+ }
+ } /* if Node present */
+ node_sys_base = pDCTstat->NodeSysBase;
+ node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F;
+ }
+ if (NodesWmem == 0) {
+ printk(BIOS_DEBUG, "No Nodes?!\n");
+ goto fatalexit;
+ }
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
- SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
+ SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n");
- HTMemMapInit_D(pMCTstat, pDCTstatA); /* Map local memory into system address space.*/
- mctHookAfterHTMap();
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n");
+ HTMemMapInit_D(pMCTstat, pDCTstatA); /* Map local memory into system address space.*/
+ mctHookAfterHTMap();
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
- CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */
- mctHookAfterCPU(); /* Setup external northbridge(s) */
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
+ CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */
+ mctHookAfterCPU(); /* Setup external northbridge(s) */
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n");
- DQSTiming_D(pMCTstat, pDCTstatA); /* Get Receiver Enable and DQS signal timing*/
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n");
+ DQSTiming_D(pMCTstat, pDCTstatA); /* Get Receiver Enable and DQS signal timing*/
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
- UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
+ UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n");
- mct_OtherTiming(pMCTstat, pDCTstatA);
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n");
+ mct_OtherTiming(pMCTstat, pDCTstatA);
- if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/
- goto restartinit;
- }
- InterleaveNodes_D(pMCTstat, pDCTstatA);
- InterleaveChannels_D(pMCTstat, pDCTstatA);
+ if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/
+ goto restartinit;
+ }
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
- if (ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
- MCTMemClr_D(pMCTstat,pDCTstatA);
- }
+ InterleaveNodes_D(pMCTstat, pDCTstatA);
+ InterleaveChannels_D(pMCTstat, pDCTstatA);
+
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
+ if (ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
+ MCTMemClr_D(pMCTstat,pDCTstatA);
+ }
- mct_FinalMCT_D(pMCTstat, pDCTstatA);
- printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus);
+ mct_FinalMCT_D(pMCTstat, pDCTstatA);
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus);
+ }
return;