aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdk8/raminit_f_dqs.c
diff options
context:
space:
mode:
authorMarc Jones <marc.jones@amd.com>2008-09-29 18:09:51 +0000
committerMarc Jones <marc.jones@amd.com>2008-09-29 18:09:51 +0000
commitb5623d18ccc642e14f7df73f5d439bac47e337ae (patch)
tree9fc39704b1f37256d1593eb9fea3c0e956990faa /src/northbridge/amd/amdk8/raminit_f_dqs.c
parenta67aab70834fe28c34d4a1c9203f6f1b8462cc38 (diff)
This patch for the AMD K8 allows a single DIMM to be populated in the
ChannelB slot. Previously a DIMM could only be populated in ChannelB if there was a DIMM already in ChannelA. This patch doesn't allow unmatched DIMMs to be populate in ChannelA and ChannelB. In an A & B configuration the DIMM must still be matched. Signed-off-by: Marc Jones <marc.jones@amd.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3614 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/northbridge/amd/amdk8/raminit_f_dqs.c')
-rw-r--r--src/northbridge/amd/amdk8/raminit_f_dqs.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/src/northbridge/amd/amdk8/raminit_f_dqs.c b/src/northbridge/amd/amdk8/raminit_f_dqs.c
index 1b5af6864f..4c97bd40df 100644
--- a/src/northbridge/amd/amdk8/raminit_f_dqs.c
+++ b/src/northbridge/amd/amdk8/raminit_f_dqs.c
@@ -1,6 +1,23 @@
/*
- yhlu 2005.10 dqs training
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 YingHai Lu
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
//0: mean no debug info
#define DQS_TRAIN_DEBUG 0
@@ -187,11 +204,6 @@ static unsigned ChipSelPresent(const struct mem_controller *ctrl, unsigned cs_id
static unsigned RcvrRankEnabled(const struct mem_controller *ctrl, int channel, int cs_idx, unsigned is_Width128, struct sys_info *sysinfo)
{
- /* FIXME: process 64Muxed */
- if(!is_Width128) {
- if(channel) return 0; // no channel b
- }
-
return ChipSelPresent(ctrl, cs_idx, sysinfo);
}
@@ -386,7 +398,11 @@ static void ResetDCTWrPtr(const struct mem_controller *ctrl)
{
uint32_t dword;
unsigned index = 0x10;
-
+
+ dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
+ pci_write_config32_index_wait(ctrl->f2, 0x98, index, dword);
+
+ index += 0x20;
dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
pci_write_config32_index_wait(ctrl->f2, 0x98, index, dword);
@@ -504,9 +520,9 @@ static unsigned TrainRcvrEn(const struct mem_controller *ctrl, unsigned Pass, st
unsigned PatternA;
unsigned PatternB;
- unsigned TestAddr0, TestAddr0B, TestAddr1, TestAddr1B;
+ unsigned TestAddr0, TestAddr0B, TestAddr1, TestAddr1B = 0;
- unsigned CurrRcvrCHADelay;
+ unsigned CurrRcvrCHADelay = 0;
unsigned tmp;
@@ -575,7 +591,14 @@ static unsigned TrainRcvrEn(const struct mem_controller *ctrl, unsigned Pass, st
Errors = 0;
/* for each channel */
CTLRMaxDelay = 0;
- for(channel = 0; (channel < 2) && (!Errors); channel++)
+ channel = 0;
+
+ if (!(sysinfo->meminfo[ctrl->node_id].dimm_mask & 0x0F) &&
+ (sysinfo->meminfo[ctrl->node_id].dimm_mask & 0xF0)) { /* channelB only? */
+ channel = 1;
+ }
+
+ for ( ; (channel < 2) && (!Errors); channel++)
{
print_debug_dqs("\tTrainRcvEn51: channel ",channel, 1);
@@ -1104,8 +1127,8 @@ static unsigned TrainDQSPos(const struct mem_controller *ctrl, unsigned channel,
unsigned TestAddr;
unsigned LastTest;
- unsigned RnkDlyFilterMax, RnkDlyFilterMin;
- unsigned RnkDlySeqPassMax, RnkDlySeqPassMin;
+ unsigned RnkDlyFilterMax, RnkDlyFilterMin = 0;
+ unsigned RnkDlySeqPassMax, RnkDlySeqPassMin = 0;
Errors = 0;
BanksPresent = 0;
@@ -1388,8 +1411,13 @@ static unsigned TrainDQSRdWrPos(const struct mem_controller *ctrl, struct sys_in
print_debug_addr("TrainDQSRdWrPos: buf_a:", buf_a);
Errors = 0;
-
channel = 0;
+
+ if (!(sysinfo->meminfo[ctrl->node_id].dimm_mask & 0x0F) &&
+ (sysinfo->meminfo[ctrl->node_id].dimm_mask & 0xF0)) { /* channelB only? */
+ channel = 1;
+ }
+
while( (channel<2) && (!Errors)) {
print_debug_dqs("\tTrainDQSRdWrPos: 1 channel ",channel, 1);
for(DQSWrDelay = 0; DQSWrDelay < 48; DQSWrDelay++) {