+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa@artecdesign.ee>
+ * Copyright (C) 2006 Ronald G. Minnich <rminnich@gmail.com>
+ * Copyright (C) 2007 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/**************************************************************************
+;*
+;* SetDelayControl
+;*
+;*************************************************************************/
+#include "cpu/x86/msr.h"
+
+
+
+
+/**
+ * Delay Control Settings table from AMD (MCP 0x4C00000F).
+ */
+static const msrinit_t delay_msr_table[] = {
+ {CPU_BC_MSS_ARRAY_CTL0, {.hi = 0x00000000, .lo = 0x2814D352}},
+ {CPU_BC_MSS_ARRAY_CTL1, {.hi = 0x00000000, .lo = 0x1068334D}},
+ {CPU_BC_MSS_ARRAY_CTL2, {.hi = 0x00000106, .lo = 0x83104104}},
+};
+
+
+
+static const struct delay_controls {
+ u8 dimms;
+ u8 devices;
+ u32 slow_hi;
+ u32 slow_low;
+ u32 fast_hi;
+ u32 fast_low;
+} delay_control_table[] = {
+ /* DIMMs Devs Slow (<=333MHz) Fast (>334MHz) */
+ { 1, 4, 0x0837100FF, 0x056960004, 0x0827100FF, 0x056960004 },
+ { 1, 8, 0x0837100AA, 0x056960004, 0x0827100AA, 0x056960004 },
+ { 1, 16, 0x0837100AA, 0x056960004, 0x082710055, 0x056960004 },
+ { 2, 8, 0x0837100A5, 0x056960004, 0x082710000, 0x056960004 },
+ { 2, 16, 0x0937100A5, 0x056960004, 0x0C27100A5, 0x056960004 },
+ { 2, 20, 0x0B37100A5, 0x056960004, 0x0B27100A5, 0x056960004 },
+ { 2, 24, 0x0B37100A5, 0x056960004, 0x0B27100A5, 0x056960004 },
+ { 2, 32, 0x0B37100A5, 0x056960004, 0x0B2710000, 0x056960004 },
+};
+
+/*
+ * Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM
+ * in slot 0, but it should be clear for all 2 DIMM settings and if a
+ * single DIMM is in slot 1. Bits 54:52 should always be set to '111'.
+ *
+ * Settings for single DIMM and no VTT termination (like DB800 platform)
+ * 0xF2F100FF 0x56960004
+ * -------------------------------------
+ * ADDR/CTL have 22 ohm series R
+ * DQ/DQM/DQS have 33 ohm series R
+ */
+
+/**
+ * This is Black Magic DRAM timing juju[1].
+ *
+ * DRAM delay depends on CPU clock, memory bus clock, memory bus loading,
+ * memory bus termination, your middle initial (ha! caught you!), GeodeLink
+ * clock rate, and DRAM timing specifications.
+ *
+ * From this the code computes a number which is "known to work". No,
+ * hardware is not an exact science. And, finally, if an FS2 (JTAG debugger)
+ * is hooked up, then just don't do anything. This code was written by a master
+ * of the Dark Arts at AMD and should not be modified in any way.
+ *
+ * [1] (http://www.thefreedictionary.com/juju)
+ *
+ * @param dimm0 The SMBus address of DIMM 0 (mainboard dependent).
+ * @param dimm1 The SMBus address of DIMM 1 (mainboard dependent).
+ * @param terminated The bus is terminated. (mainboard dependent).
+ */
+static void SetDelayControl(u8 dimm0, u8 dimm1, int terminated)
+{
+ u32 glspeed;
+ u8 spdbyte0, spdbyte1, dimms, i;