summaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdk8
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdk8')
-rw-r--r--src/northbridge/amd/amdk8/Kconfig138
-rw-r--r--src/northbridge/amd/amdk8/Makefile.inc42
-rw-r--r--src/northbridge/amd/amdk8/acpi.c311
-rw-r--r--src/northbridge/amd/amdk8/acpi.h25
-rw-r--r--src/northbridge/amd/amdk8/amdk8.h27
-rw-r--r--src/northbridge/amd/amdk8/bootblock.c20
-rw-r--r--src/northbridge/amd/amdk8/coherent_ht.c1809
-rw-r--r--src/northbridge/amd/amdk8/debug.c259
-rw-r--r--src/northbridge/amd/amdk8/debug.h32
-rw-r--r--src/northbridge/amd/amdk8/early_ht.c154
-rw-r--r--src/northbridge/amd/amdk8/exit_from_self.c193
-rw-r--r--src/northbridge/amd/amdk8/f.h606
-rw-r--r--src/northbridge/amd/amdk8/f_pci.c73
-rw-r--r--src/northbridge/amd/amdk8/get_sblk_pci1234.c217
-rw-r--r--src/northbridge/amd/amdk8/incoherent_ht.c821
-rw-r--r--src/northbridge/amd/amdk8/misc_control.c246
-rw-r--r--src/northbridge/amd/amdk8/northbridge.c1288
-rw-r--r--src/northbridge/amd/amdk8/northbridge.h19
-rw-r--r--src/northbridge/amd/amdk8/pre_f.h285
-rw-r--r--src/northbridge/amd/amdk8/raminit.c2507
-rw-r--r--src/northbridge/amd/amdk8/raminit.h60
-rw-r--r--src/northbridge/amd/amdk8/raminit_f.c3211
-rw-r--r--src/northbridge/amd/amdk8/raminit_f_dqs.c2058
-rw-r--r--src/northbridge/amd/amdk8/raminit_test.c409
-rw-r--r--src/northbridge/amd/amdk8/resourcemap.c271
-rw-r--r--src/northbridge/amd/amdk8/setup_resource_map.c117
-rw-r--r--src/northbridge/amd/amdk8/thermal_mixin.asl285
-rw-r--r--src/northbridge/amd/amdk8/util.asl329
-rw-r--r--src/northbridge/amd/amdk8/util.c269
29 files changed, 1 insertions, 16080 deletions
diff --git a/src/northbridge/amd/amdk8/Kconfig b/src/northbridge/amd/amdk8/Kconfig
deleted file mode 100644
index 83f70c90c2..0000000000
--- a/src/northbridge/amd/amdk8/Kconfig
+++ /dev/null
@@ -1,138 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright (C) 2007-2009 coresystems GmbH
-##
-## 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.
-##
-
-config NORTHBRIDGE_AMD_AMDK8
- bool
- select HAVE_DEBUG_RAM_SETUP
- select HAVE_DEBUG_SMBUS
- select HAVE_DEBUG_CAR
- select HYPERTRANSPORT_PLUGIN_SUPPORT
- select LATE_CBMEM_INIT
-
-if NORTHBRIDGE_AMD_AMDK8
-
-config NO_MMCONF_SUPPORT
- bool
- default y
- help
- If you want to remove this, you need to make sure any access to CPU
- nodes 0:18.0, 0:19.0, ... continue to use PCI IO config access.
-
-config AGP_APERTURE_SIZE
- hex
- default 0x4000000
-
-config K8_HT_FREQ_1G_SUPPORT
- bool
- default n
-
-config RAMINIT_SYSINFO
- bool
- default n
-
-config WAIT_BEFORE_CPUS_INIT
- bool
- default n
-
-# Force 2T DRAM timing (vendor BIOS does it even for single DIMM setups and
-# single DIMM is indeed unreliable without it).
-config K8_FORCE_2T_DRAM_TIMING
- bool
- default n
-
-config HW_MEM_HOLE_SIZEK
- hex
- default 0x100000
-
-config HW_MEM_HOLE_SIZE_AUTO_INC
- bool
- default n
-
-config BOOTBLOCK_NORTHBRIDGE_INIT
- string
- default "northbridge/amd/amdk8/bootblock.c"
-
-config SB_HT_CHAIN_UNITID_OFFSET_ONLY
- bool
- default n
-
-config HT_CHAIN_DISTRIBUTE
- def_bool n
-
-config QRANK_DIMM_SUPPORT
- bool
- default n
-
-config K8_ALLOCATE_IO_RANGE
- bool
- default n
-
-config K8_REV_F_SUPPORT
- bool
- select RAMINIT_SYSINFO
- default n
-
-if K8_REV_F_SUPPORT
-
-config DIMM_DDR2
- bool
- default n
-
-config DIMM_REGISTERED
- bool
- default n
-
-if DIMM_DDR2
- if DIMM_REGISTERED
- config DIMM_SUPPORT
- hex
- default 0x0104
- endif
-
- if !DIMM_REGISTERED
- config DIMM_SUPPORT
- hex
- default 0x0004
- endif
-endif #DIMM_DDR2
-
-config MEM_TRAIN_SEQ
- int
- default 0
-
-endif #K8_REV_F_SUPPORT
-
-# TODO: Reservation for heap seems excessive
-config HEAP_SIZE
- hex
- default 0x40000
-
-config IOMMU
- bool
- default y
-
-config CBB
- hex
- default 0x00
-
-config CDB
- hex
- default 0x18
-
-config MAX_REBOOT_CNT
- int
- default 6
-
-endif #NORTHBRIDGE_AMD_K8
diff --git a/src/northbridge/amd/amdk8/Makefile.inc b/src/northbridge/amd/amdk8/Makefile.inc
deleted file mode 100644
index 263e06f201..0000000000
--- a/src/northbridge/amd/amdk8/Makefile.inc
+++ /dev/null
@@ -1,42 +0,0 @@
-ifeq ($(CONFIG_NORTHBRIDGE_AMD_AMDK8),y)
-
-ramstage-y += northbridge.c
-ramstage-y += misc_control.c
-ramstage-y += get_sblk_pci1234.c
-ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
-
-romstage-y += debug.c
-ifeq ($(CONFIG_K8_REV_F_SUPPORT),y)
-romstage-$(CONFIG_HAVE_ACPI_RESUME) += exit_from_self.c
-romstage-y += raminit_f.c
-endif
-
-romstage-y += reset_test.c
-romstage-y += coherent_ht.c
-
-# Enable this if you want to check the values of the PCI routing registers.
-# Call show_all_routes() anywhere amdk8.h is included.
-#ramstage-y += util.c
-
-# Not sure what to do with these yet. How did raminit_test even work?
-# Should be a target in -y form.
-#if IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
-#
-#makerule raminit_test
-# depends "$(TOP)/src/northbridge/amd/amdk8/raminit_test.c"
-# depends "$(TOP)/src/northbridge/amd/amdk8/raminit_f.c"
-# action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g $< -o $@"
-#end
-#
-#else
-#
-#makerule raminit_test
-# depends "$(TOP)/src/northbridge/amd/amdk8/raminit_test.c"
-# depends "$(TOP)/src/northbridge/amd/amdk8/raminit.c"
-# action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g $< -o $@"
-#end
-#
-#end
-#
-
-endif
diff --git a/src/northbridge/amd/amdk8/acpi.c b/src/northbridge/amd/amdk8/acpi.c
deleted file mode 100644
index 0d42911697..0000000000
--- a/src/northbridge/amd/amdk8/acpi.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Advanced Micro Devices, Inc.
- * Copyright (C) 2010 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.
- */
-
-/*
- * Description: Add madt lapic creat dynamically and SRAT related by yhlu
-*/
-
-#include <console/console.h>
-#include <string.h>
-#include <arch/acpi.h>
-#include <arch/acpigen.h>
-#include <device/pci.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-#include <cpu/amd/amdk8_sysconf.h>
-#include "acpi.h"
-
-//it seems some functions can be moved arch/x86/boot/acpi.c
-
-unsigned long acpi_create_madt_lapic_nmis(unsigned long current, u16 flags, u8 lint)
-{
- struct device *cpu;
- int cpu_index = 0;
-
- for (cpu = all_devices; cpu; cpu = cpu->next) {
- if ((cpu->path.type != DEVICE_PATH_APIC) ||
- (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) {
- continue;
- }
- if (!cpu->enabled) {
- continue;
- }
- current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, cpu_index, flags, lint);
- cpu_index++;
- }
- return current;
-}
-
-unsigned long acpi_create_srat_lapics(unsigned long current)
-{
- struct device *cpu;
- int cpu_index = 0;
-
- for (cpu = all_devices; cpu; cpu = cpu->next) {
- if ((cpu->path.type != DEVICE_PATH_APIC) ||
- (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) {
- continue;
- }
- if (!cpu->enabled) {
- continue;
- }
- printk(BIOS_DEBUG, "SRAT: lapic cpu_index=%02x, node_id=%02x, apic_id=%02x\n", cpu_index, cpu->path.apic.node_id, cpu->path.apic.apic_id);
- current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current, cpu->path.apic.node_id, cpu->path.apic.apic_id);
- cpu_index++;
- }
- return current;
-}
-
-static unsigned long resk(uint64_t value)
-{
- unsigned long resultk;
- if (value < (1ULL << 42)) {
- resultk = value >> 10;
- } else {
- resultk = 0xffffffff;
- }
- return resultk;
-}
-
-struct acpi_srat_mem_state {
- unsigned long current;
-};
-
-static void set_srat_mem(void *gp, struct device *dev, struct resource *res)
-{
- struct acpi_srat_mem_state *state = gp;
- unsigned long basek, sizek;
- basek = resk(res->base);
- sizek = resk(res->size);
-
- printk(BIOS_DEBUG, "set_srat_mem: dev %s, res->index=%04lx startk=%08lx, sizek=%08lx\n",
- dev_path(dev), res->index, basek, sizek);
- /*
- * 0-640K must be on node 0
- * next range is from 1M---
- * So will cut off before 1M in the mem range
- */
- if ((basek+sizek)<1024) return;
-
- if (basek < 1024) {
- sizek -= 1024 - basek;
- basek = 1024;
- }
-
- // need to figure out NV
- state->current += acpi_create_srat_mem((acpi_srat_mem_t *)state->current, (res->index & 0xf), basek, sizek, 1);
-}
-
-static unsigned long acpi_fill_srat(unsigned long current)
-{
- struct acpi_srat_mem_state srat_mem_state;
-
- /* create all subtables for processors */
- current = acpi_create_srat_lapics(current);
-
- /* create all subteble for memory range */
-
- /* 0-640K must be on node 0 */
- current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, 0, 640, 1);//enable
-
- srat_mem_state.current = current;
- search_global_resources(
- IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
- set_srat_mem, &srat_mem_state);
-
- current = srat_mem_state.current;
- return current;
-}
-
-static unsigned long acpi_fill_slit(unsigned long current)
-{
- /* need to find out the node num at first */
- /* fill the first 8 byte with that num */
- /* fill the next num*num byte with distance, local is 10, 1 hop mean 20, and 2 hop with 30.... */
-
- /* because We has assume that we know the topology of the HT connection, So we can have set if we know the node_num */
- static u8 hops_8[] = { 0, 1, 1, 2, 2, 3, 3, 4,
- 1, 0, 2, 1, 3, 2, 4, 3,
- 1, 2, 0, 1, 1, 2, 2, 3,
- 2, 1, 1, 0, 2, 1, 3, 2,
- 2, 3, 1, 2, 0, 1, 1, 2,
- 3, 2, 2, 1, 1, 0, 2, 1,
- 3, 4, 2, 3, 1, 2, 0, 1,
- 4, 4, 3, 2, 2, 1, 1, 0 };
-
- u8 *p = (u8 *)current;
- int nodes = sysconf.nodes;
- int i,j;
- memset(p, 0, 8+nodes*nodes);
- *p = (u8) nodes;
- p += 8;
-
- for (i = 0; i < nodes; i++) {
- for (j = 0; j < nodes; j++) {
- if (i == j) {
- p[i*nodes+j] = 10;
- } else {
- p[i*nodes+j] = hops_8[i*nodes+j] * 2 + 10;
-
- }
- }
- }
-
- current += 8+nodes*nodes;
-
- return current;
-}
-
-unsigned long northbridge_write_acpi_tables(
- struct device *device,
- unsigned long start,
- acpi_rsdp_t *rsdp)
-{
- unsigned long current;
- acpi_srat_t *srat;
- acpi_slit_t *slit;
-
- current = start;
-
- /* Fills sysconf structure needed for SRAT and SLIT. */
- get_bus_conf();
-
- current = ALIGN(current, 16);
- srat = (acpi_srat_t *) current;
- printk(BIOS_DEBUG, "ACPI: * SRAT @ %p\n", srat);
- acpi_create_srat(srat, acpi_fill_srat);
- current += srat->header.length;
- acpi_add_table(rsdp, srat);
-
- /* SLIT */
- current = ALIGN(current, 16);
- slit = (acpi_slit_t *) current;
- printk(BIOS_DEBUG, "ACPI: * SLIT @ %p\n", slit);
- acpi_create_slit(slit, acpi_fill_slit);
- current+=slit->header.length;
- acpi_add_table(rsdp,slit);
-
- return current;
-}
-
-static void k8acpi_write_HT(void) {
- int i;
-
- acpigen_write_name("HCLK");
- acpigen_write_package(HC_POSSIBLE_NUM);
-
- for (i = 0; i < sysconf.hc_possible_num; i++) {
- acpigen_write_dword(sysconf.pci1234[i]);
- }
- for (i = sysconf.hc_possible_num; i < HC_POSSIBLE_NUM; i++) { // in case we set array size to other than 8
- acpigen_write_dword(0x0);
- }
-
- acpigen_pop_len();
-
- acpigen_write_name("HCDN");
- acpigen_write_package(HC_POSSIBLE_NUM);
-
- for (i = 0; i < sysconf.hc_possible_num; i++) {
- acpigen_write_dword(sysconf.hcdn[i]);
- }
- for (i = sysconf.hc_possible_num; i < HC_POSSIBLE_NUM; i++) { // in case we set array size to other than 8
- acpigen_write_dword(0x20202020);
- }
- acpigen_pop_len();
-}
-
-static void k8acpi_write_pci_data(int dlen, const char *name, int offset) {
- struct device *dev;
- uint32_t dword;
- int i;
-
- dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
-
- acpigen_write_name(name);
- acpigen_write_package(dlen);
- for (i = 0; i < dlen; i++) {
- dword = pci_read_config32(dev, offset+i*4);
- acpigen_write_dword(dword);
- }
- // minus the opcode
- acpigen_pop_len();
-}
-
-void k8acpi_write_vars(struct device *device)
-{
- /*
- * If more than one physical CPU is installed k8acpi_write_vars()
- * is called more than once. If we don't prevent it, a SSDT table
- * with duplicate variables will cause some ACPI parsers to be
- * confused enough to fail.
- */
- static uint8_t ssdt_generated = 0;
- if (ssdt_generated)
- return;
- ssdt_generated = 1;
-
- msr_t msr;
- char pscope[] = "\\_SB.PCI0";
-
- acpigen_write_scope(pscope);
- k8acpi_write_pci_data(4, "BUSN", 0xe0);
- k8acpi_write_pci_data(8, "PCIO", 0xc0);
- k8acpi_write_pci_data(16, "MMIO", 0x80);
- acpigen_write_name_byte("SBLK", sysconf.sblk);
- acpigen_write_name_byte("CBST",
- ((sysconf.pci1234[0] >> 12) & 0xff) ? 0xf : 0x0);
- acpigen_write_name_dword("SBDN", sysconf.sbdn);
- msr = rdmsr(TOP_MEM);
- acpigen_write_name_dword("TOM1", msr.lo);
- msr = rdmsr(TOP_MEM2);
- /*
- * Since XP only implements parts of ACPI 2.0, we can't use a qword
- * here.
- * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
- * slide 22ff.
- * Shift value right by 20 bit to make it fit into 32bit,
- * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
- */
- acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
-
- k8acpi_write_HT();
- //minus opcode
- acpigen_pop_len();
-}
-
-void update_ssdtx(void *ssdtx, int i)
-{
- u8 *PCI;
- u8 *HCIN;
- u8 *UID;
-
- PCI = ssdtx + 0x32;
- HCIN = ssdtx + 0x39;
- UID = ssdtx + 0x40;
-
- if (i < 7) {
- *PCI = (u8) ('4' + i - 1);
- } else {
- *PCI = (u8) ('A' + i - 1 - 6);
- }
- *HCIN = (u8) i;
- *UID = (u8) (i + 3);
-
- /* FIXME: need to update the GSI id in the ssdtx too */
-
-}
diff --git a/src/northbridge/amd/amdk8/acpi.h b/src/northbridge/amd/amdk8/acpi.h
deleted file mode 100644
index 934792d1cc..0000000000
--- a/src/northbridge/amd/amdk8/acpi.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz>
- *
- * 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.
- */
-
-#ifndef AMDK8_ACPI_H
-#define AMDK8_ACPI_H
-#include <arch/acpigen.h>
-
-void k8acpi_write_vars(struct device *device);
-unsigned long northbridge_write_acpi_tables(struct device *device,
- unsigned long start,
- acpi_rsdp_t *rsdp);
-
-#endif
diff --git a/src/northbridge/amd/amdk8/amdk8.h b/src/northbridge/amd/amdk8/amdk8.h
index 363e9a45b1..d8cbc36ff8 100644
--- a/src/northbridge/amd/amdk8/amdk8.h
+++ b/src/northbridge/amd/amdk8/amdk8.h
@@ -12,18 +12,9 @@
*/
#ifndef AMDK8_H
-
#define AMDK8_H
-#if IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
-
-#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
-
- #include "f.h"
-#else
- #include "pre_f.h"
-#endif
-
+#define HT_INIT_CONTROL 0x6C
#define HTIC_ColdR_Detect (1<<4)
#define HTIC_BIOSR_Detect (1<<5)
#define HTIC_INIT_Detect (1<<6)
@@ -32,25 +23,9 @@
#define NODE_MP(x) PCI_DEV(0,24+x,1)
#define NODE_MC(x) PCI_DEV(0,24+x,3)
-
-#ifdef __PRE_RAM__
-void showallroutes(int level, pci_devfn_t dev);
-void setup_resource_map_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base);
-void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a, const uint16_t *spd_addr);
-int optimize_link_coherent_ht(void);
-unsigned int get_nodes(void);
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void setup_coherent_ht_domain(void);
-#else
-int setup_coherent_ht_domain(void);
-#endif
-#endif
-
void set_bios_reset(void);
void distinguish_cpu_resets(unsigned int nodeid);
unsigned int get_sblk(void);
unsigned int get_sbbusn(unsigned sblk);
-void cpus_ready_for_init(void);
-
#endif /* AMDK8_H */
diff --git a/src/northbridge/amd/amdk8/bootblock.c b/src/northbridge/amd/amdk8/bootblock.c
deleted file mode 100644
index 411b58ad07..0000000000
--- a/src/northbridge/amd/amdk8/bootblock.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <arch/io.h>
-#include <device/pci_def.h>
-#include "northbridge/amd/amdk8/early_ht.c"
-
-static void bootblock_northbridge_init(void) {
- enumerate_ht_chain();
-}
diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c
deleted file mode 100644
index 1f8b9cedc2..0000000000
--- a/src/northbridge/amd/amdk8/coherent_ht.c
+++ /dev/null
@@ -1,1809 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * written by Stefan Reinauer <stepan@openbios.org>
- * (c) 2003-2004 by SuSE Linux AG
- *
- * (c) 2004 Tyan Computer
- * 2004.12 yhlu added support to create routing table dynamically.
- * it also support 8 ways too. (8 ways ladder or 8 ways crossbar)
- *
- * 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.
- */
-
-/* coherent hypertransport initialization for AMD64
- */
-
-/*
- * This algorithm assumes a grid configuration as follows:
- *
- * nodes : 1 2 4 6 8
- * org. : 1x1 2x1 2x2 2x3 2x4
- Ladder:
- CPU7-------------CPU6
- | |
- | |
- | |
- | |
- | |
- | |
- CPU5-------------CPU4
- | |
- | |
- | |
- | |
- | |
- | |
- CPU3-------------CPU2
- | |
- | |
- | |
- | |
- | |
- | |
- CPU1-------------CPU0
- CROSS_BAR_47_56:
- CPU7-------------CPU6
- | \____ ___/ |
- | \ / |
- | \/ |
- | /\ |
- | / \ |
- | ____/ \___ |
- CPU5 CPU4
- | |
- | |
- | |
- | |
- | |
- | |
- CPU3-------------CPU2
- | |
- | |
- | |
- | |
- | |
- | |
- CPU1-------------CPU0
- */
-
-#include <console/console.h>
-#include <cpu/amd/model_fxx_rev.h>
-#include <device/pci_def.h>
-#include <device/pci_ids.h>
-#include <device/hypertransport_def.h>
-#include <lib.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <arch/io.h>
-#include <pc80/mc146818rtc.h>
-#if IS_ENABLED(CONFIG_HAVE_OPTION_TABLE)
-#include "option_table.h"
-#endif
-
-#include "amdk8.h"
-
-#define enable_bsp_routing() enable_routing(0)
-
-#define DEFAULT 0x00010101 /* default row entry */
-
-
-#ifndef CROSS_BAR_47_56
- #define CROSS_BAR_47_56 0
-#endif
-
-#ifndef TRY_HIGH_FIRST
- #define TRY_HIGH_FIRST 0
-#endif
-
-#ifndef K8_HT_CHECK_PENDING_LINK
- #if CONFIG_MAX_PHYSICAL_CPUS >= 4
- #define K8_HT_CHECK_PENDING_LINK 1
- #else
- #define K8_HT_CHECK_PENDING_LINK 0
- #endif
-#endif
-
-#ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
- #define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
-#endif
-
-static inline void print_linkn (const char *strval, uint8_t byteval)
-{
- printk(BIOS_DEBUG, "%s%02x\n", strval, byteval);
-}
-
-static void disable_probes(void)
-{
- /* disable read/write/fill probes for uniprocessor setup
- * they don't make sense if only one CPU is available
- */
-
- /* Hypetransport Transaction Control Register
- * F0:0x68
- * [ 0: 0] Disable read byte probe
- * 0 = Probes issues
- * 1 = Probes not issued
- * [ 1: 1] Disable Read Doubleword probe
- * 0 = Probes issued
- * 1 = Probes not issued
- * [ 2: 2] Disable write byte probes
- * 0 = Probes issued
- * 1 = Probes not issued
- * [ 3: 3] Disable Write Doubleword Probes
- * 0 = Probes issued
- * 1 = Probes not issued.
- * [10:10] Disable Fill Probe
- * 0 = Probes issued for cache fills
- * 1 = Probes not issued for cache fills.
- */
-
- u32 val;
-
- printk(BIOS_SPEW, "Disabling read/write/fill probes for UP... ");
-
- val = pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
- val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
- HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P |
- HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
- pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
-
- printk(BIOS_SPEW, "done.\n");
-
-}
-
-static void enable_routing(u8 node)
-{
- u32 val;
-
- /* HT Initialization Control Register
- * F0:0x6C
- * [ 0: 0] Routing Table Disable
- * 0 = Packets are routed according to routing tables
- * 1 = Packets are routed according to the default link field
- * [ 1: 1] Request Disable (BSP should clear this)
- * 0 = Request packets may be generated
- * 1 = Request packets may not be generated.
- * [ 3: 2] Default Link (Read-only)
- * 00 = LDT0
- * 01 = LDT1
- * 10 = LDT2
- * 11 = CPU on same node
- * [ 4: 4] Cold Reset
- * - Scratch bit cleared by a cold reset
- * [ 5: 5] BIOS Reset Detect
- * - Scratch bit cleared by a cold reset
- * [ 6: 6] INIT Detect
- * - Scratch bit cleared by a warm or cold reset not by an INIT
- *
- */
-
- /* Enable routing table */
- printk(BIOS_SPEW, "Enabling routing table for node %d", node);
-
- val = pci_read_config32(NODE_HT(node), 0x6c);
- val &= ~((1<<1)|(1<<0));
- pci_write_config32(NODE_HT(node), 0x6c, val);
-
- printk(BIOS_SPEW, " done.\n");
-}
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 1
-static void fill_row(u8 node, u8 row, u32 value)
-{
- pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
-}
-
-static u8 link_to_register(int ldt)
-{
- /*
- * [ 0: 3] Request Route
- * [0] Route to this node
- * [1] Route to Link 0
- * [2] Route to Link 1
- * [3] Route to Link 2
- */
-
- if (ldt&0x08) return 0x40;
- if (ldt&0x04) return 0x20;
- if (ldt&0x02) return 0x00;
-
- /* we should never get here */
- printk(BIOS_SPEW, "Unknown Link\n");
- return 0;
-}
-
-static u32 get_row(u8 node, u8 row)
-{
- return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
-}
-
-static int link_connection(u8 src, u8 dest)
-{
- return get_row(src, dest) & 0x0f;
-}
-
-static void rename_temp_node(u8 node)
-{
- uint32_t val;
-
- printk(BIOS_SPEW, "Renaming current temporary node to %d", node);
-
- val = pci_read_config32(NODE_HT(7), 0x60);
- val &= (~7); /* clear low bits. */
- val |= node; /* new node */
- pci_write_config32(NODE_HT(7), 0x60, val);
-
- printk(BIOS_SPEW, " done.\n");
-}
-
-static int verify_connection(u8 dest)
-{
- /* See if we have a valid connection to dest */
- u32 val;
-
- /* Verify that the coherent hypertransport link is
- * established and actually working by reading the
- * remode node's vendor/device id
- */
- val = pci_read_config32(NODE_HT(dest),0);
- if (val != 0x11001022)
- return 0;
-
- return 1;
-}
-
-static uint16_t read_freq_cap(pci_devfn_t dev, uint8_t pos)
-{
- /* Handle bugs in valid hypertransport frequency reporting */
- uint16_t freq_cap;
- uint32_t id;
-
- freq_cap = pci_read_config16(dev, pos);
- freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
-
-#if IS_ENABLED(CONFIG_K8_HT_FREQ_1G_SUPPORT)
- #if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (!is_cpu_pre_e0())
- #endif
- {
- return freq_cap;
- }
-#endif
-
- id = pci_read_config32(dev, 0);
-
- /* AMD K8 Unsupported 1GHz? */
- if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
- freq_cap &= ~(1 << HT_FREQ_1000Mhz);
- }
-
- return freq_cap;
-}
-
-static int optimize_connection(pci_devfn_t node1, uint8_t link1,
- pci_devfn_t node2, uint8_t link2)
-{
- static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
- static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
- uint16_t freq_cap1, freq_cap2;
- uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
- uint8_t freq, old_freq;
- int needs_reset;
- /* Set link width and frequency */
-
- /* Initially assume everything is already optimized and I don't need a reset */
- needs_reset = 0;
-
- /* Get the frequency capabilities */
- freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
- freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
-
- /* Calculate the highest possible frequency */
- freq = log2(freq_cap1 & freq_cap2);
-
- /* See if I am changing the link freqency */
- old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
- old_freq &= 0x0f;
- needs_reset |= old_freq != freq;
- old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
- old_freq &= 0x0f;
- needs_reset |= old_freq != freq;
-
- /* Set the Calulcated link frequency */
- pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
- pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
-
- /* Get the width capabilities */
- width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
- width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
-
- /* Calculate node1's input width */
- ln_width1 = link_width_to_pow2[width_cap1 & 7];
- ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
- if (ln_width1 > ln_width2) {
- ln_width1 = ln_width2;
- }
- width = pow2_to_link_width[ln_width1];
- /* Calculate node1's output width */
- ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
- ln_width2 = link_width_to_pow2[width_cap2 & 7];
- if (ln_width1 > ln_width2) {
- ln_width1 = ln_width2;
- }
- width |= pow2_to_link_width[ln_width1] << 4;
-
- /* See if I am changing node1's width */
- old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
- old_width &= 0x77;
- needs_reset |= old_width != width;
-
- /* Set node1's widths */
- pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
-
- // * Calculate node2's width */
- width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
-
- /* See if I am changing node2's width */
- old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
- old_width &= 0x77;
- needs_reset |= old_width != width;
-
- /* Set node2's widths */
- pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
-
- return needs_reset;
-}
-
-static uint8_t get_linkn_first(uint8_t byte)
-{
- if (byte & 0x02) { byte = 0; }
- else if (byte & 0x04) { byte = 1; }
- else if (byte & 0x08) { byte = 2; }
- return byte;
-}
-
-#if TRY_HIGH_FIRST == 1
-static uint8_t get_linkn_last(uint8_t byte)
-{
- if (byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
- if (byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
- if (byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
- return byte>>4;
-}
-#endif
-
-#if (CONFIG_MAX_PHYSICAL_CPUS > 2) || CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
-static uint8_t get_linkn_last_count(uint8_t byte)
-{
- byte &= 0x0f;
- if (byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
- if (byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
- if (byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
- return byte>>4;
-}
-#endif
-
-static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
-{
- uint8_t linkn;
- uint32_t val;
- val = 1;
- for (linkn = 0; linkn < 3; linkn++) {
- uint8_t regpos;
- uint32_t reg;
- regpos = 0x98 + 0x20 * linkn;
- reg = pci_read_config32(NODE_HT(source), regpos);
- if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
- val |= 1<<(linkn+1);
- }
- val <<= 16;
- val |= 0x0101;
- fill_row(source,row, val);
-}
-
-static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
-{
- uint32_t val;
- uint32_t val_s;
- val = 1<<(linkn+1);
- val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
-
- if (((source &1)!=(dest &1))
-#if CROSS_BAR_47_56
- && ((source < 4)||(source > 5)) //(6,7) (7,6) should still be here
- //(6,5) (7,4) should be here
-#endif
- ) {
- val |= (1<<16);
- } else {
- /*for CROSS_BAR_47_56 47, 56, should be here too
- and for 47, 56, 57, 75, 46, 64 we need to substract another link to
- 6, 7, 6, 6, 7, 7
- */
- val_s = get_row(temp, source);
- val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
- }
-
- fill_row(temp,dest, val);
-}
-
-#if CROSS_BAR_47_56
-static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout)
-{
- uint32_t val;
- val = get_row(source, dest);
- val -= link_connection(source, kickout)<<16;
- fill_row(source, dest, val);
-}
-
-static void opt_broadcast_rt_group(const u8 *conn, int num)
-{
- int i;
-
- for (i = 0; i < num; i+=3) {
- opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
- }
-}
-
-static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout)
-{
- uint32_t val;
- val = get_row(source, dest);
- val += link_connection(source, kickout)<<16;
- fill_row(source, dest, val);
-}
-
-static void opt_broadcast_rt_plus_group(const u8 *conn, int num)
-{
- int i;
-
- for (i = 0; i < num; i+=3) {
- opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
- }
-}
-#endif
-
-static void setup_row_direct(u8 source, u8 dest, u8 linkn)
-{
- setup_row_direct_x(source, source, dest, linkn);
-}
-
-static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn)
-{
- setup_row_direct_x(7, source, dest, linkn);
-}
-
-static void setup_temp_row(u8 source, u8 dest)
-{
- /* copy value from (source, dest) to (source,7) */
- fill_row(source, 7, get_row(source, dest));
-}
-
-static void setup_remote_node(u8 node)
-{
- static const uint8_t pci_reg[] = {
- 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
- 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
- 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
- 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
- 0xc4, 0xcc, 0xd4, 0xdc,
- 0xc0, 0xc8, 0xd0, 0xd8,
- 0xe0, 0xe4, 0xe8, 0xec,
- };
- int i;
-
- printk(BIOS_SPEW, "setup_remote_node: ");
-
- /* copy the default resource map from node 0 */
- for (i = 0; i < ARRAY_SIZE(pci_reg); i++) {
- uint32_t value;
- uint8_t reg;
- reg = pci_reg[i];
- value = pci_read_config32(NODE_MP(0), reg);
- pci_write_config32(NODE_MP(7), reg, value);
-
- }
- printk(BIOS_SPEW, "done\n");
-}
-
-#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
-
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
-#if !CROSS_BAR_47_56
-static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
-#else
-static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
-#endif
-{
- /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
- uint32_t val_s;
- uint32_t val;
-#if !CROSS_BAR_47_56
- u8 gateway;
- u8 diff;
- if (source < dest) {
- gateway = source + 2;
- } else {
- gateway = source - 2;
- }
-#endif
- val_s = get_row(temp, source);
- val = get_row(temp, gateway);
-
- val &= 0xffff;
- val_s >>= 16;
- val_s &= 0xfe;
-
-#if !CROSS_BAR_47_56
- diff = ((source&1)!=(dest &1));
-#endif
-
- if (diff && (val_s!=(val&0xff))) { /* use another connect as response*/
- val_s -= val & 0xff;
-#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
- uint8_t byte;
- /* Some node have two links left
- * don't worry we only have (2, (3 as source need to handle
- */
- byte = val_s;
- byte = get_linkn_last_count(byte);
- if ((byte>>2)>1) { /* make sure not the corner*/
- if (source < dest) {
- val_s-=link_connection(temp, source-2); /* -down*/
- } else {
-#if CROSS_BAR_47_56
- if (source < gateway) { // for 5, 4 via 7
- val_s-=link_connection(temp, source-2);
- } else
-#endif
- val_s-=link_connection(temp, source+2); /* -up*/
- }
- }
-#endif
- val &= 0xff;
- val |= (val_s<<8);
- }
-
- if (diff) { /* cross rung?*/
- val |= (1<<16);
- }
- else {
- val_s = get_row(temp, source);
- val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
- }
-
- fill_row(temp, dest, val);
-
-}
-
-#if !CROSS_BAR_47_56
-static void setup_row_indirect(u8 source, u8 dest)
-{
- setup_row_indirect_x(source, source, dest);
-}
-#else
-static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
-{
- setup_row_indirect_x(source, source, dest, gateway, diff);
-}
-#endif
-
-static void setup_row_indirect_group(const u8 *conn, int num)
-{
- int i;
-
-#if !CROSS_BAR_47_56
- for (i = 0; i < num; i+=2) {
- setup_row_indirect(conn[i], conn[i+1]);
-#else
- for (i = 0; i < num; i+=4) {
- setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
-#endif
-
- }
-}
-
-#if !CROSS_BAR_47_56
-static void setup_remote_row_indirect(u8 source, u8 dest)
-{
- setup_row_indirect_x(7, source, dest);
-}
-#else
-static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
-{
- setup_row_indirect_x(7, source, dest, gateway, diff);
-}
-#endif
-
-static void setup_remote_row_indirect_group(const u8 *conn, int num)
-{
- int i;
-
-#if !CROSS_BAR_47_56
- for (i = 0; i < num; i+=2) {
- setup_remote_row_indirect(conn[i], conn[i+1]);
-#else
- for (i = 0; i < num; i+=4) {
- setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
-#endif
- }
-}
-
-#endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
-
-
-static void setup_uniprocessor(void)
-{
- printk(BIOS_SPEW, "Enabling UP settings\n");
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
- unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
- if (tmp > 0) return;
-#endif
- disable_probes();
-}
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
-static int optimize_connection_group(const u8 *opt_conn, int num)
-{
- int needs_reset = 0;
- int i;
- for (i = 0; i < num; i+=2) {
- needs_reset = optimize_connection(
- NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
- NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])));
- }
- return needs_reset;
-}
-#endif
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 1
-static unsigned setup_smp2(void)
-{
- unsigned nodes;
- u8 byte;
- uint32_t val;
- nodes = 2;
-
- setup_row_local(0, 0); /* it will update the broadcast RT*/
-
- val = get_row(0,0);
- byte = (val>>16) & 0xfe;
- if (byte < 0x2) { /* no coherent connection so get out.*/
- nodes = 1;
- return nodes;
- }
-
- /* Setup and check a temporary connection to node 1 */
-#if TRY_HIGH_FIRST == 1
- byte = get_linkn_last(byte); /* Max Link to node1 */
-#else
- byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
-#endif
- print_linkn("(0,1) link=", byte);
- setup_row_direct(0,1, byte);
- setup_temp_row(0, 1);
-
- verify_connection(7);
-
- /* We found 2 nodes so far */
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
- print_linkn("(1,0) link=", byte);
- setup_row_local(7,1);
- setup_remote_row_direct(1, 0, byte);
-
-#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
- val = get_row(7,1);
- byte = (val>>16) & 0xfe;
- byte = get_linkn_last_count(byte);
- if ((byte>>2) == 3) { /* Oh! we need to treat it as node2. So use another link*/
- val = get_row(0,0);
- byte = (val>>16) & 0xfe;
-#if TRY_HIGH_FIRST == 1
- byte = get_linkn_first(byte); /* Min link to Node1 */
-#else
- byte = get_linkn_last(byte); /* Max link to Node1*/
-#endif
- print_linkn("\t-->(0,1) link=", byte);
- setup_row_direct(0,1, byte);
- setup_temp_row(0, 1);
-
- verify_connection(7);
-
- /* We found 2 nodes so far */
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
- print_linkn("\t-->(1,0) link=", byte);
- setup_row_local(7,1);
- setup_remote_row_direct(1, 0, byte);
- }
-#endif
-
- setup_remote_node(1); /* Setup the regs on the remote node */
- rename_temp_node(1); /* Rename Node 7 to Node 1 */
- enable_routing(1); /* Enable routing on Node 1 */
-
- return nodes;
-}
-#endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
-
-static unsigned setup_smp4(void)
-{
- unsigned nodes;
- u8 byte;
- uint32_t val;
-
- nodes = 4;
-
- /* Setup and check temporary connection from Node 0 to Node 2 */
- val = get_row(0,0);
- byte = ((val>>16) & 0xfe) - link_connection(0,1);
- byte = get_linkn_last_count(byte);
-
- if ((byte>>2) == 0) { /* We should have two coherent for 4p and above*/
- nodes = 2;
- return nodes;
- }
-
- byte &= 3; /* bit [3,2] is count-1*/
- print_linkn("(0,2) link=", byte);
- setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
-
- /* We found 3 nodes so far. Now setup a temporary
- * connection from node 0 to node 3 via node 1
- */
- setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
- /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
- val = get_row(1,1);
- byte = ((val>>16) & 0xfe) - link_connection(1,0);
- byte = get_linkn_first(byte);
- print_linkn("(1,3) link=", byte);
- setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
-
- /* We found 4 nodes so far. Now setup all nodes for 4p */
- // We need to make sure 0,2 and 1,3 link is set already
-#if !CROSS_BAR_47_56
- static const u8 conn4_1[] = {
- 0,3,
- 1,2,
- };
-#else
- static const u8 conn4_1[] = {
- 0,3,2,1,
- 1,2,3,1,
- };
-#endif
-
- setup_row_indirect_group(conn4_1, ARRAY_SIZE(conn4_1));
-
- setup_temp_row(0,2);
- verify_connection(7);
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
- print_linkn("(2,0) link=", byte);
-
- setup_row_local(7,2);
- setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
- setup_remote_node(2); /* Setup the regs on the remote node */
-
- rename_temp_node(2); /* Rename Node 7 to Node 2 */
- enable_routing(2); /* Enable routing on Node 2 */
-
- setup_temp_row(0,1);
- setup_temp_row(1,3);
- verify_connection(7);
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
- print_linkn("(3,1) link=", byte);
-
- setup_row_local(7,3);
- setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
- setup_remote_node(3); /* Setup the regs on the remote node */
-
- /* We need to init link between 2, and 3 direct link */
- val = get_row(2,2);
- byte = ((val>>16) & 0xfe) - link_connection(2,0);
- byte = get_linkn_last_count(byte);
- print_linkn("(2,3) link=", byte & 3);
-
- setup_row_direct(2,3, byte & 0x3);
- setup_temp_row(0,2);
- setup_temp_row(2,3);
- verify_connection(7); /* to 3*/
-
-#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
- /* We need to find out which link is to node3 */
- if ((byte>>2) == 2) { /* one to node3, one to node0, one to node4*/
- val = get_row(7,3);
- if ((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
- val = get_row(2,2);
- byte = ((val>>16) & 0xfe) - link_connection(2,0);
- byte = get_linkn_first(byte);
- print_linkn("\t-->(2,3) link=", byte);
- setup_row_direct(2,3,byte);
- setup_temp_row(2,3);
- verify_connection(7); /* to 3*/
- }
- }
-#endif
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
- print_linkn("(3,2) link=", byte);
- setup_remote_row_direct(3,2, byte);
-
-#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
- /* set link from 3 to 5 before enable it*/
- val = get_row(7,3);
- byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
- byte = get_linkn_last_count(byte);
- if ((byte>>2) == 1) { /* We should have three coherent links on node 3 for 6p and above*/
- byte &= 3; /*bit [3,2] is count-2*/
- print_linkn("(3,5) link=", byte);
- setup_remote_row_direct(3, 5, byte);
- }
-
- val = get_row(2,2);
- byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
- byte = get_linkn_last_count(byte);
-
- if ((byte>>2) == 1) { /* We should have three coherent link on node 2 for 6p and above*/
- byte &= 3; /* bit [3,2] is count-2*/
- print_linkn("(2,4) link=", byte);
- setup_row_direct(2, 4, byte);
- }
-#endif
-
- //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
-#if !CROSS_BAR_47_56
- static const u8 conn4_3[] = {
- 3,0,
- };
-#else
- static const u8 conn4_3[] = {
- 3,0,1,1,
- };
-#endif
- setup_remote_row_indirect_group(conn4_3, ARRAY_SIZE(conn4_3));
-
-/* ready to enable RT for Node 3 */
- rename_temp_node(3);
- enable_routing(3); /* enable routing on node 3 (temp.) */
-
- // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
-#if !CROSS_BAR_47_56
- static const u8 conn4_2[] = {
- 2,1,
- };
-#else
- static const u8 conn4_2[] = {
- 2,1,0,1,
- };
-#endif
- setup_row_indirect_group(conn4_2, ARRAY_SIZE(conn4_2));
-
- return nodes;
-
-}
-
-#endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 4
-
-static unsigned setup_smp6(void)
-{
- unsigned nodes;
- u8 byte;
- uint32_t val;
-
- nodes = 6;
-
- /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
- val = get_row(2,2);
- byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
- byte = get_linkn_last_count(byte);
-
- if ((byte>>2) == 0) { /* We should have three coherent link on node 2 for 6p and above*/
- nodes = 4;
- return nodes;
- }
-
- /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
- /* set link from 3 to 5 before enable it*/
- val = get_row(3,3);
- byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
- byte = get_linkn_last_count(byte);
- if ((byte>>2) == 0) { /* We should have three coherent links on node 3 for 6p and above*/
- nodes = 4;
- return nodes;
- }
-
- /* We found 6 nodes so far. Now setup all nodes for 6p */
-#warning "FIXME we need to find out the correct gateway for 6p"
- static const u8 conn6_1[] = {
-#if !CROSS_BAR_47_56
- 0, 4,
- 0, 5,
- 1, 4,
- 1, 5,
- 2, 5,
- 3, 4,
-#else
- 0, 4, 2, 0,
- 0, 5, 2, 1,
- 1, 4, 3, 1,
- 1, 5, 3, 0,
- 2, 5, 3, 0,
- 3, 4, 2, 0,
-#endif
- };
-
- setup_row_indirect_group(conn6_1, ARRAY_SIZE(conn6_1));
-
- for (byte = 0; byte < 4; byte+=2) {
- setup_temp_row(byte,byte+2);
- }
- verify_connection(7);
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
- print_linkn("(4,2) link=", byte);
-
- setup_row_local(7,4);
- setup_remote_row_direct(4, 2, byte);
- setup_remote_node(4); /* Setup the regs on the remote node */
-
- /* Set indirect connection to 0, to 3 */
- //we only need to set 4,0 here
- static const u8 conn6_2[] = {
-#if !CROSS_BAR_47_56
- 4, 0,
-#else
- 4, 0, 2, 0,
-#endif
- };
-
- setup_remote_row_indirect_group(conn6_2, ARRAY_SIZE(conn6_2));
-
- rename_temp_node(4);
- enable_routing(4);
-
- setup_temp_row(0,1);
- for (byte = 0; byte < 4; byte+=2) {
- setup_temp_row(byte+1,byte+3);
- }
- verify_connection(7);
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
- print_linkn("(5,3) link=", byte);
- setup_row_local(7,5);
- setup_remote_row_direct(5, 3, byte);
- setup_remote_node(5); /* Setup the regs on the remote node */
-
-#if !CROSS_BAR_47_56
- /* We need to init link between 4, and 5 direct link */
- val = get_row(4,4);
- byte = ((val>>16) & 0xfe) - link_connection(4,2);
- byte = get_linkn_last_count(byte);
- print_linkn("(4,5) link=", byte & 3);
-
- setup_row_direct(4,5, byte & 0x3);
- setup_temp_row(0,2);
- setup_temp_row(2,4);
- setup_temp_row(4,5);
- verify_connection(7); /* to 5*/
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 6
- /* We need to find out which link is to node5 */
-
- if ((byte>>2) == 2) { /* one to node5, one to node2, one to node6*/
- val = get_row(7,5);
- if ((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
- val = get_row(4,4);
- byte = ((val>>16) & 0xfe) - link_connection(4,2);
- byte = get_linkn_first(byte);
- print_linkn("\t-->(4,5) link=", byte);
- setup_row_direct(4,5,byte);
- setup_temp_row(4,5);
- verify_connection(7); /* to 5*/
- }
- }
-#endif
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
- print_linkn("(5,4) link=", byte);
- setup_remote_row_direct(5,4, byte);
-
- //init 5, 7 here
- val = get_row(7,5);
- byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
- byte = get_linkn_last_count(byte);
- if ((byte>>2) == 1) { /* We should have three coherent links on node 5 for 6p and above*/
- byte &= 3; /*bit [3,2] is count-2*/
- print_linkn("(5,7) link=", byte);
- setup_remote_row_direct(5, 7, byte);
- }
-
- //init 4,6 here
- val = get_row(4,4);
- byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
- byte = get_linkn_last_count(byte);
-
- if ((byte>>2) == 1) { /* We should have three coherent link on node 4 for 6p and above*/
- byte &= 3; /* bit [3,2] is count-2*/
- print_linkn("(4,6) link=", byte);
- setup_row_direct(4, 6, byte);
- }
-
-#endif
-
- //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
- /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
- static const u8 conn6_3[] = {
-#if !CROSS_BAR_47_56
- 5, 0,
-#else
- 5, 0, 3, 0,
-#endif
- };
-
- setup_remote_row_indirect_group(conn6_3, ARRAY_SIZE(conn6_3));
-
-/* ready to enable RT for 5 */
- rename_temp_node(5);
- enable_routing(5); /* enable routing on node 5 (temp.) */
-
- static const u8 conn6_4[] = {
-#if !CROSS_BAR_47_56
- 4, 1,
- 4, 3,
-
- 5, 2,
- 5, 1,
-
-#else
- 4, 1, 2, 0,
- 4, 3, 2, 0,
- 4, 5, 2, 0,
-
- 5, 2, 3, 0,
- 5, 1, 3, 0,
- 5, 4, 3, 0,
-
-#endif
- };
-
- setup_row_indirect_group(conn6_4, ARRAY_SIZE(conn6_4));
-
- return nodes;
-
-}
-
-#endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 6
-
-static unsigned setup_smp8(void)
-{
- unsigned nodes;
- u8 byte;
- uint32_t val;
-
- nodes = 8;
-
- /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
- val = get_row(4,4);
-#if CROSS_BAR_47_56
- byte = ((val>>16) & 0xfe) - link_connection(4,2);
-#else
- byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
- byte = get_linkn_last_count(byte); /* Max link to 6*/
- if ((byte>>2) == 0) { /* We should have two or three coherent links on node 4 for 8p*/
- nodes = 6;
- return nodes;
- }
-#endif
-
-#if CROSS_BAR_47_56
- byte = get_linkn_last_count(byte); /* Max link to 6*/
- if ((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
- nodes = 6;
- return nodes;
- }
-#if TRY_HIGH_FIRST == 1
- byte = ((val>>16) & 0xfe) - link_connection(4,2);
- byte = get_linkn_first(byte); /*Min link to 6*/
-#else
- byte &= 3; /* bit [3,2] is count-1 or 2*/
-#endif
- print_linkn("(4,6) link=", byte);
- setup_row_direct(4, 6, byte);
-#endif
-
-#if !CROSS_BAR_47_56
- /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
- val = get_row(5,5);
- byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
- byte = get_linkn_last_count(byte);
- if ((byte>>2) == 0) { /* We should have three coherent links on node 5 for 6p and above*/
- nodes = 6;
- return nodes;
- }
-#endif
-
- /* We found 8 nodes so far. Now setup all nodes for 8p */
- static const u8 conn8_1[] = {
-#if !CROSS_BAR_47_56
- 0, 6,
- /*0, 7,*/
- 1, 6,
- /*1, 7,*/
- 2, 6,
- /*2, 7,*/
- 3, 6,
- /*3, 7,*/
- /*4, 7,*/
- 5, 6,
-#else
- 0, 6, 2, 0,
- /*0, 7, 2, 0,*/
- 1, 6, 3, 0,
- /*1, 7, 3, 0,*/
- 2, 6, 4, 0,
- /*2, 7, 4, 0,*/
- 3, 6, 5, 1,
- /*3, 7, 5, 0,*/
-#endif
- };
-
- setup_row_indirect_group(conn8_1,ARRAY_SIZE(conn8_1));
-
- for (byte = 0; byte < 6; byte+=2) {
- setup_temp_row(byte,byte+2);
- }
- verify_connection(7);
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
- print_linkn("(6,4) link=", byte);
-
- setup_row_local(7,6);
- setup_remote_row_direct(6, 4, byte);
- setup_remote_node(6); /* Setup the regs on the remote node */
- /* Set indirect connection to 0, to 3 */
-#warning "FIXME we need to find out the correct gateway for 8p"
- static const u8 conn8_2[] = {
-#if !CROSS_BAR_47_56
- 6, 0,
-#else
- 6, 0, 4, 0,
-#endif
- };
-
- setup_remote_row_indirect_group(conn8_2, ARRAY_SIZE(conn8_2));
-
-#if CROSS_BAR_47_56
- //init 5, 6 here
- /* here init 5, 6 */
- /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
- val = get_row(5,5);
- byte = ((val>>16) & 0xfe) - link_connection(5,3);
-#if TRY_HIGH_FIRST == 1
- byte = get_linkn_first(byte);
-#else
- byte = get_linkn_last(byte);
-#endif
- print_linkn("(5,6) link=", byte);
- setup_row_direct(5, 6, byte);
-
- setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
- for (byte = 0; byte < 4; byte+=2) {
- setup_temp_row(byte+1,byte+3);
- }
- setup_temp_row(5,6);
-
- verify_connection(7);
-
- val = get_row(7,6); // to chect it if it is node6 before renaming
- if ((val>>16) == 1) { // it is real node 7 so swap it
- /* We need to recompute link to 6 */
- val = get_row(5,5);
- byte = ((val>>16) & 0xfe) - link_connection(5,3);
-#if TRY_HIGH_FIRST == 1
- byte = get_linkn_first(byte);
-#else
- byte = get_linkn_last(byte);
-#endif
- print_linkn("\t-->(5,6) link=", byte);
- setup_row_direct(5, 6, byte);
- setup_temp_row(5,6);
-
- verify_connection(7);
- }
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
- print_linkn("(6,5) link=", byte);
- setup_remote_row_direct(6, 5, byte);
- /*Till now 56, 65 done */
-#endif
-
- rename_temp_node(6);
- enable_routing(6);
-
-#if !CROSS_BAR_47_56
- setup_temp_row(0,1);
- for (byte = 0; byte < 6; byte+=2) {
- setup_temp_row(byte+1,byte+3);
- }
-
- verify_connection(7);
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
- print_linkn("(7,5) link=", byte);
- setup_row_local(7,7);
- setup_remote_row_direct(7, 5, byte);
-
-#else
- val = get_row(4,4);
- byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
- byte = get_linkn_first(byte);
- print_linkn("(4,7) link=", byte);
- setup_row_direct(4, 7, byte);
-
- /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
- for (byte = 0; byte < 4; byte+=2) {
- setup_temp_row(byte,byte+2);
- }
-
- verify_connection(7);
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
- print_linkn("(7,4) link=", byte);
- setup_row_local(7,7);
- setup_remote_row_direct(7, 4, byte);
- /* till now 4-7, 7-4 done. */
-#endif
- setup_remote_node(7); /* Setup the regs on the remote node */
-
-#if CROSS_BAR_47_56
- /* here init 5, 7 */
- /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
- val = get_row(5,5);
- byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
- byte = get_linkn_first(byte);
- print_linkn("(5,7) link=", byte);
- setup_row_direct(5, 7, byte);
-
- setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
- for (byte = 0; byte < 4; byte+=2) {
- setup_temp_row(byte+1,byte+3);
- }
-
- verify_connection(7);
-
- val = pci_read_config32(NODE_HT(7), 0x6c);
- byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
- print_linkn("(7,5) link=", byte);
- setup_remote_row_direct(7, 5, byte);
- /*Till now 57, 75 done */
-
-#endif
-
- /* We need to init link between 6, and 7 direct link */
- val = get_row(6,6);
-#if !CROSS_BAR_47_56
- byte = ((val>>16) & 0xfe) - link_connection(6,4);
-#else
- byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
-#endif
- byte = get_linkn_first(byte);
- print_linkn("(6,7) link=", byte);
- setup_row_direct(6,7, byte);
-
- val = get_row(7,7);
-#if !CROSS_BAR_47_56
- byte = ((val>>16) & 0xfe) - link_connection(7,5);
-#else
- byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
-#endif
- byte = get_linkn_first(byte);
- print_linkn("(7,6) link=", byte);
- setup_row_direct(7,6, byte);
-
- /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
- static const u8 conn8_3[] = {
-#if !CROSS_BAR_47_56
- 0, 7, /* restore it*/
- 1, 7,
- 2, 7,
- 3, 7,
- 4, 7,
-
- 6, 1,
- 6, 2,
- 6, 3,
- 6, 5,
-
- 7, 0,
- 7, 1,
- 7, 2,
- 7, 3,
- 7, 4,
-#else
-
-
- 4, 5, 6, 1,
- 5, 4, 7, 1,
-
- 6, 1, 5, 0, // or 4, 1
- 6, 2, 4, 0,
- 6, 3, 5, 0, // or 4, 1
-
- 7, 0, 4, 0, // or 5, 1
- 7, 1, 5, 0,
- 7, 2, 4, 0, // or 5, 1
- 7, 3, 5, 0,
-
- 0, 7, 2, 0, /* restore it*/
- 1, 7, 3, 0,
- 2, 7, 4, 1,
- 3, 7, 5, 0,
-
- 2, 5, 4, 1, /* reset it */
- 3, 4, 5, 1,
-
- 4, 1, 2, 1, /* reset it */
- 4, 3, 2, 1,
-
- 5, 2, 3, 1, /* reset it */
- 5, 0, 3, 1,
-
-#endif
- };
-
- setup_row_indirect_group(conn8_3, ARRAY_SIZE(conn8_3));
-
-#if CROSS_BAR_47_56
- /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
- 6, 7, 6, 6, 7, 7 */
- static const u8 conn8_4[] = {
-//direct
- 4, 7, 6,
- 5, 6, 7,
- 5, 7, 6,
- 7, 5, 6,
- 4, 6, 7,
- 6, 4, 7,
-
-//in direct
- 0, 6, 1,
- 0, 7, 1,
-
- 1, 6, 0,
- 1, 7, 0,
-
- 2, 6, 3,
-// 2, 7, 3, +
-
-// 3, 6, 1, +
- 3, 7, 2,
-
- 6, 0, 7,
- 6, 1, 7, // needed for via 5
- 6, 1, 4, // ???
- 6, 2, 7,
- 6, 3, 7, // needed for via 5
- 6, 3, 4, //???
- 7, 0, 6, // needed for via 4
- 7, 0, 5, //???
- 7, 1, 6,
- 7, 2, 6, // needed for via 4
- 7, 2, 5, //???
- 7, 3, 6,
- };
-
- opt_broadcast_rt_group(conn8_4, ARRAY_SIZE(conn8_4));
-
- static const u8 conn8_5[] = {
- 2, 7, 0,
-
- 3, 6, 1,
- };
-
- opt_broadcast_rt_plus_group(conn8_5, ARRAY_SIZE(conn8_5));
-#endif
-
-
-
-/* ready to enable RT for Node 7 */
- enable_routing(7); /* enable routing on node 7 (temp.) */
-
- return nodes;
-}
-
-#endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
-
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 1
-
-static unsigned setup_smp(void)
-{
- unsigned nodes;
-
- printk(BIOS_SPEW, "Enabling SMP settings\n");
-
- nodes = setup_smp2();
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
- if (nodes == 2)
- nodes = setup_smp4();
-#endif
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 4
- if (nodes == 4)
- nodes = setup_smp6();
-#endif
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 6
- if (nodes == 6)
- nodes = setup_smp8();
-#endif
-
- printk(BIOS_DEBUG, "%02x nodes initialized.\n", nodes);
-
- return nodes;
-}
-
-static unsigned verify_mp_capabilities(unsigned nodes)
-{
- unsigned node, mask;
-
- mask = 0x06; /* BigMPCap */
-
- for (node = 0; node < nodes; node++) {
- mask &= pci_read_config32(NODE_MC(node), 0xe8);
- }
-
- switch(mask) {
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
- case 0x02: /* MPCap */
- if (nodes > 2) {
- printk(BIOS_ERR, "Going back to DP\n");
- return 2;
- }
- break;
-#endif
- case 0x00: /* Non SMP */
- if (nodes >1) {
- printk(BIOS_ERR, "Going back to UP\n");
- return 1;
- }
- break;
- }
-
- return nodes;
-
-}
-
-
-static void clear_dead_routes(unsigned nodes)
-{
- int last_row;
- int node, row;
-#if CONFIG_MAX_PHYSICAL_CPUS == 8
- if (nodes == 8) return;/* don't touch (7,7)*/
-#endif
- last_row = nodes;
- if (nodes == 1) {
- last_row = 0;
- }
- for (node = 7; node >= 0; node--) {
- for (row = 7; row >= last_row; row--) {
- fill_row(node, row, DEFAULT);
- }
- }
-
- /* Update the local row */
- for (node = 0; node < nodes; node++) {
- uint32_t val = 0;
- for (row =0; row < nodes; row++) {
- val |= get_row(node, row);
- }
- fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
- }
-}
-#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
-
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
-static unsigned verify_dualcore(unsigned nodes)
-{
- unsigned node, totalcpus, tmp;
-
- totalcpus = 0;
- for (node = 0; node < nodes; node++) {
- tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3;
- totalcpus += (tmp + 1);
- }
-
- return totalcpus;
-
-}
-#endif
-
-static void coherent_ht_finalize(unsigned nodes)
-{
- unsigned node;
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- int rev_a0;
-#endif
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
- unsigned total_cpus;
-
- if (read_option(multi_core, 0) == 0) { /* multi_core */
- total_cpus = verify_dualcore(nodes);
- }
- else {
- total_cpus = nodes;
- }
-#endif
-
- /* set up CPU count and node count and enable Limit
- * Config Space Range for all available CPUs.
- * Also clear non coherent hypertransport bus range
- * registers on Hammer A0 revision.
- */
-
- printk(BIOS_SPEW, "coherent_ht_finalize\n");
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- rev_a0 = is_cpu_rev_a0();
-#endif
- for (node = 0; node < nodes; node++) {
- pci_devfn_t dev;
- uint32_t val;
- dev = NODE_HT(node);
-
- /* Set the Total CPU and Node count in the system */
- val = pci_read_config32(dev, 0x60);
- val &= (~0x000F0070);
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
- val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
-#else
- val |= ((nodes-1)<<16)|((nodes-1)<<4);
-#endif
- pci_write_config32(dev, 0x60, val);
-
- /* Only respond to real CPU pci configuration cycles
- * and optimize the HT settings
- */
- val = pci_read_config32(dev, HT_TRANSACTION_CONTROL);
- val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
- (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
- (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
- val |= HTTC_LIMIT_CLDT_CFG |
- (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
- (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
- (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
- pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
-
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (rev_a0) {
- pci_write_config32(dev, 0x94, 0);
- pci_write_config32(dev, 0xb4, 0);
- pci_write_config32(dev, 0xd4, 0);
- }
-#endif
- }
-
- printk(BIOS_SPEW, "done\n");
-}
-
-static int apply_cpu_errata_fixes(unsigned nodes)
-{
- unsigned node;
- int needs_reset = 0;
- for (node = 0; node < nodes; node++) {
- pci_devfn_t dev;
- uint32_t cmd;
- dev = NODE_MC(node);
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (is_cpu_pre_c0()) {
-
- /* Errata 66
- * Limit the number of downstream posted requests to 1
- */
- cmd = pci_read_config32(dev, 0x70);
- if ((cmd & (3 << 0)) != 2) {
- cmd &= ~(3<<0);
- cmd |= (2<<0);
- pci_write_config32(dev, 0x70, cmd);
- needs_reset = 1;
- }
- cmd = pci_read_config32(dev, 0x7c);
- if ((cmd & (3 << 4)) != 0) {
- cmd &= ~(3<<4);
- cmd |= (0<<4);
- pci_write_config32(dev, 0x7c, cmd);
- needs_reset = 1;
- }
- /* Clock Power/Timing Low */
- cmd = pci_read_config32(dev, 0xd4);
- if (cmd != 0x000D0001) {
- cmd = 0x000D0001;
- pci_write_config32(dev, 0xd4, cmd);
- needs_reset = 1; /* Needed? */
- }
-
- }
- else if (is_cpu_pre_d0()) { // d0 later don't need it
- uint32_t cmd_ref;
- /* Errata 98
- * Set Clk Ramp Hystersis to 7
- * Clock Power/Timing Low
- */
- cmd_ref = 0x04e20707; /* Registered */
- cmd = pci_read_config32(dev, 0xd4);
- if (cmd != cmd_ref) {
- pci_write_config32(dev, 0xd4, cmd_ref);
- needs_reset = 1; /* Needed? */
- }
- }
-#endif
-
-
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- /* I can't touch this msr on early buggy cpus, and cannot apply either 169 or 131 */
- if (!is_cpu_pre_b3())
-#endif
- {
- /* Errata 169 */
- /* We also need to set some bits in NB_CFG_MSR, which is handled in src/cpu/amd/model_fxx/ */
- dev = NODE_HT(node);
- cmd = pci_read_config32(dev, 0x68);
- cmd &= ~(1 << 22);
- cmd |= (1 << 21);
- pci_write_config32(dev, 0x68, cmd);
- }
- }
- return needs_reset;
-}
-
-static int optimize_link_read_pointers(unsigned nodes)
-{
- unsigned node;
- int needs_reset = 0;
- for (node = 0; node < nodes; node++) {
- pci_devfn_t f0_dev, f3_dev;
- uint32_t cmd_ref, cmd;
- int link;
- f0_dev = NODE_HT(node);
- f3_dev = NODE_MC(node);
- cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
- for (link = 0; link < 3; link++) {
- uint32_t link_type;
- unsigned reg;
- /* This works on an Athlon64 because unimplemented links return 0 */
- reg = 0x98 + (link * 0x20);
- link_type = pci_read_config32(f0_dev, reg);
- /* Only handle coherent links */
- if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
- (LinkConnected|InitComplete))
- {
- cmd &= ~(0xff << (link *8));
- cmd |= 0x25 << (link *8);
- }
- }
- if (cmd != cmd_ref) {
- pci_write_config32(f3_dev, 0xdc, cmd);
- needs_reset = 1;
- }
- }
- return needs_reset;
-}
-
-unsigned int get_nodes(void)
-{
- return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
-}
-
-int optimize_link_coherent_ht(void)
-{
- int needs_reset = 0;
-
- unsigned nodes;
-
- nodes = get_nodes();
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 1
- if (nodes > 1) {
- needs_reset |= optimize_connection(
- NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
- NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)));
- }
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 2
- if (nodes > 2) {
- /* optimize physical connections - by LYH */
- static const u8 opt_conn4[] = {
- 0,2,
- 1,3,
- 2,3,
- };
- needs_reset |= optimize_connection_group(opt_conn4, ARRAY_SIZE(opt_conn4));
- }
-#endif
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 4
- if (nodes > 4) {
- static const uint8_t opt_conn6[] ={
- 2, 4,
- 3, 5,
- #if !CROSS_BAR_47_56
- 4, 5,
- #endif
- };
- needs_reset |= optimize_connection_group(opt_conn6, ARRAY_SIZE(opt_conn6));
- }
-#endif
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 6
- if (nodes > 6) {
- static const uint8_t opt_conn8[] ={
- 4, 6,
- #if CROSS_BAR_47_56
- 4, 7,
- 5, 6,
- #endif
- 5, 7,
- 6, 7,
- };
- needs_reset |= optimize_connection_group(opt_conn8, ARRAY_SIZE(opt_conn8));
- }
-#endif
-
-#endif
-
- needs_reset |= apply_cpu_errata_fixes(nodes);
- needs_reset |= optimize_link_read_pointers(nodes);
-
- return needs_reset;
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void setup_coherent_ht_domain(void)
-#else
-int setup_coherent_ht_domain(void)
-#endif
-{
- unsigned nodes;
- nodes = 1;
-
- enable_bsp_routing();
-
-#if CONFIG_MAX_PHYSICAL_CPUS > 1
- nodes = setup_smp();
- nodes = verify_mp_capabilities(nodes);
- clear_dead_routes(nodes);
-#endif
-
- if (nodes == 1) {
- setup_uniprocessor();
- }
- coherent_ht_finalize(nodes);
-
-#if !IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- return optimize_link_coherent_ht();
-#endif
-}
diff --git a/src/northbridge/amd/amdk8/debug.c b/src/northbridge/amd/amdk8/debug.c
deleted file mode 100644
index 6480db48ed..0000000000
--- a/src/northbridge/amd/amdk8/debug.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-/*
- * generic K8 debug code, used by mainboard specific romstage.c
- *
- */
-
-#include "debug.h"
-#include <console/console.h>
-#include <arch/io.h>
-#include <device/pci_def.h>
-#include <delay.h>
-#include "raminit.h"
-
-void print_debug_addr(const char *str, void *val)
-{
-#if IS_ENABLED(CONFIG_DEBUG_CAR)
- printk(BIOS_DEBUG, "------Address debug: %s%p------\n", str, val);
-#endif
-}
-
-#if 1
-void print_debug_pci_dev(unsigned dev)
-{
- printk(BIOS_DEBUG, "PCI: %02x:%02x.%02x", (dev>>20) & 0xff, (dev>>15) & 0x1f, (dev>>12) & 0x7);
-}
-
-void print_pci_devices(void)
-{
- pci_devfn_t dev;
- for (dev = PCI_DEV(0, 0, 0);
- dev <= PCI_DEV(0xff, 0x1f, 0x7);
- dev += PCI_DEV(0,0,1)) {
- uint32_t id;
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000)) {
- continue;
- }
- print_debug_pci_dev(dev);
- printk(BIOS_DEBUG, " %04x:%04x\n", (id & 0xffff), (id>>16));
- if (((dev>>12) & 0x07) == 0) {
- uint8_t hdr_type;
- hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
- if ((hdr_type & 0x80) != 0x80) {
- dev += PCI_DEV(0,0,7);
- }
- }
- }
-}
-
-void dump_pci_device(unsigned dev)
-{
- int i;
- print_debug_pci_dev(dev);
-
- for (i = 0; i < 256; i++) {
- unsigned char val;
- if ((i & 0x0f) == 0) {
- printk(BIOS_DEBUG, "\n%02x:",i);
- }
- val = pci_read_config8(dev, i);
- printk(BIOS_DEBUG, " %02x", val);
- }
- printk(BIOS_DEBUG, "\n");
-}
-
-#if IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
-void dump_pci_device_index_wait(unsigned dev, uint32_t index_reg)
-{
- int i;
- print_debug_pci_dev(dev);
- printk(BIOS_DEBUG, " -- index_reg=%08x", index_reg);
-
- for (i = 0; i < 0x40; i++) {
- uint32_t val;
- int j;
- printk(BIOS_DEBUG, "\n%02x:",i);
- val = pci_read_config32_index_wait(dev, index_reg, i);
- for (j = 0; j < 4; j++) {
- printk(BIOS_DEBUG, " %02x", val & 0xff);
- val >>= 8;
- }
-
- }
- printk(BIOS_DEBUG, "\n");
-}
-#endif
-
-void dump_pci_devices(void)
-{
- pci_devfn_t dev;
- for (dev = PCI_DEV(0, 0, 0);
- dev <= PCI_DEV(0xff, 0x1f, 0x7);
- dev += PCI_DEV(0,0,1)) {
- uint32_t id;
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000)) {
- continue;
- }
- dump_pci_device(dev);
-
- if (((dev>>12) & 0x07) == 0) {
- uint8_t hdr_type;
- hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
- if ((hdr_type & 0x80) != 0x80) {
- dev += PCI_DEV(0,0,7);
- }
- }
- }
-}
-
-void dump_pci_devices_on_bus(unsigned busn)
-{
- pci_devfn_t dev;
- for (dev = PCI_DEV(busn, 0, 0);
- dev <= PCI_DEV(busn, 0x1f, 0x7);
- dev += PCI_DEV(0,0,1)) {
- uint32_t id;
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000)) {
- continue;
- }
- dump_pci_device(dev);
-
- if (((dev>>12) & 0x07) == 0) {
- uint8_t hdr_type;
- hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
- if ((hdr_type & 0x80) != 0x80) {
- dev += PCI_DEV(0,0,7);
- }
- }
- }
-}
-
-#if IS_ENABLED(CONFIG_DEBUG_SMBUS)
-
-void dump_spd_registers(const struct mem_controller *ctrl)
-{
- int i;
- printk(BIOS_DEBUG, "\n");
- for (i = 0; i < 4; i++) {
- unsigned device;
- device = ctrl->channel0[i];
- if (device) {
- int j;
- printk(BIOS_DEBUG, "dimm: %02x.0: %02x", i, device);
- for (j = 0; j < 128; j++) {
- int status;
- unsigned char byte;
- if ((j & 0xf) == 0) {
- printk(BIOS_DEBUG, "\n%02x: ", j);
- }
- status = spd_read_byte(device, j);
- if (status < 0) {
- break;
- }
- byte = status & 0xff;
- printk(BIOS_DEBUG, "%02x ", byte);
- }
- printk(BIOS_DEBUG, "\n");
- }
- device = ctrl->channel1[i];
- if (device) {
- int j;
- printk(BIOS_DEBUG, "dimm: %02x.1: %02x", i, device);
- for (j = 0; j < 128; j++) {
- int status;
- unsigned char byte;
- if ((j & 0xf) == 0) {
- printk(BIOS_DEBUG, "\n%02x: ", j);
- }
- status = spd_read_byte(device, j);
- if (status < 0) {
- break;
- }
- byte = status & 0xff;
- printk(BIOS_DEBUG, "%02x ", byte);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
-}
-void dump_smbus_registers(void)
-{
- unsigned device;
- printk(BIOS_DEBUG, "\n");
- for (device = 1; device < 0x80; device++) {
- int j;
- if (spd_read_byte(device, 0) < 0)
- continue;
- printk(BIOS_DEBUG, "smbus: %02x", device);
- for (j = 0; j < 256; j++) {
- int status;
- unsigned char byte;
- status = spd_read_byte(device, j);
- if (status < 0) {
- break;
- }
- if ((j & 0xf) == 0) {
- printk(BIOS_DEBUG, "\n%02x: ",j);
- }
- byte = status & 0xff;
- printk(BIOS_DEBUG, "%02x ", byte);
- }
- printk(BIOS_DEBUG, "\n");
- }
-}
-#endif
-
-void dump_io_resources(unsigned port)
-{
-
- int i;
- udelay(2000);
- printk(BIOS_DEBUG, "%04x:\n", port);
- for (i = 0; i < 256; i++) {
- uint8_t val;
- if ((i & 0x0f) == 0) {
- printk(BIOS_DEBUG, "%02x:", i);
- }
- val = inb(port);
- printk(BIOS_DEBUG, " %02x",val);
- if ((i & 0x0f) == 0x0f) {
- printk(BIOS_DEBUG, "\n");
- }
- port++;
- }
-}
-
-void dump_mem(unsigned start, unsigned end)
-{
- unsigned i;
- printk(BIOS_DEBUG, "dump_mem:");
- for (i = start; i < end; i++) {
- if ((i & 0xf) == 0) {
- printk(BIOS_DEBUG, "\n%08x:", i);
- }
- printk(BIOS_DEBUG, " %02x", (unsigned char)*((unsigned char *)i));
- }
- printk(BIOS_DEBUG, "\n");
- }
-#endif
diff --git a/src/northbridge/amd/amdk8/debug.h b/src/northbridge/amd/amdk8/debug.h
deleted file mode 100644
index 06ed51923b..0000000000
--- a/src/northbridge/amd/amdk8/debug.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef AMDK8_DEBUG_H
-#define AMDK8_DEBUG_H
-
-#include <inttypes.h>
-#include <arch/io.h>
-
-void print_debug_addr(const char *str, void *val);
-void print_debug_pci_dev(unsigned int dev);
-void print_pci_devices(void);
-void dump_pci_device(unsigned int dev);
-void dump_pci_device_index_wait(unsigned int dev, uint32_t index_reg);
-uint32_t pci_read_config32_index_wait(pci_devfn_t dev,
- uint32_t index_reg, uint32_t index);
-void dump_pci_devices(void);
-void dump_pci_devices_on_bus(unsigned int busn);
-void dump_io_resources(unsigned int port);
-void dump_mem(unsigned start, unsigned end);
-
-#endif
diff --git a/src/northbridge/amd/amdk8/early_ht.c b/src/northbridge/amd/amdk8/early_ht.c
deleted file mode 100644
index 0683579656..0000000000
--- a/src/northbridge/amd/amdk8/early_ht.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 2005.11 yhlu add let the real sb to use small unitid
- *
- * 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.
- */
-
-// only for sb ht chain
-static void enumerate_ht_chain(void)
-{
-#if CONFIG_HT_CHAIN_UNITID_BASE != 0
-/* CONFIG_HT_CHAIN_UNITID_BASE could be 0 (only one ht device in the ht chain), if so, don't need to go through the chain */
-
- /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
- * On most boards this just happens. If a CPU has multiple
- * non Coherent links the appropriate bus registers for the
- * links needs to be programed to point at bus 0.
- */
- unsigned next_unitid, last_unitid;
- pci_devfn_t dev;
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- //let't record the device of last ht device, So we can set the Unitid to CONFIG_HT_CHAIN_END_UNITID_BASE
- unsigned real_last_unitid = 0;
- uint8_t real_last_pos = 0;
- int ht_dev_num = 0; // except host_bridge
- uint8_t end_used = 0;
-#endif
-
- dev = PCI_DEV(0,0,0);
- next_unitid = CONFIG_HT_CHAIN_UNITID_BASE;
- do {
- uint32_t id;
- uint8_t hdr_type, pos;
- last_unitid = next_unitid;
-
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- /* If the chain is enumerated quit */
- if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000))
- {
- break;
- }
-
- hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
- pos = 0;
- hdr_type &= 0x7f;
-
- if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
- (hdr_type == PCI_HEADER_TYPE_BRIDGE))
- {
- pos = pci_read_config8(dev, PCI_CAPABILITY_LIST);
- }
- while (pos != 0) {
- uint8_t cap;
- cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
- if (cap == PCI_CAP_ID_HT) {
- uint16_t flags;
- /* Read and write and reread flags so the link
- * direction bit is valid.
- */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- if ((flags >> 13) == 0) {
- unsigned count;
- unsigned ctrl, ctrl_off;
- pci_devfn_t devx;
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- if (next_unitid >= 0x18) { // don't get mask out by k8, at this time BSP, RT is not enabled, it will response from 0x18,0--0x1f.
- if (!end_used) {
- next_unitid = CONFIG_HT_CHAIN_END_UNITID_BASE;
- end_used = 1;
- } else {
- goto out;
- }
- }
- real_last_unitid = next_unitid;
- real_last_pos = pos;
- ht_dev_num++;
-#endif
-
- flags &= ~0x1f;
- flags |= next_unitid & 0x1f;
- count = (flags >> 5) & 0x1f;
-
- devx = PCI_DEV(0, next_unitid, 0);
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
-
- next_unitid += count;
-
- flags = pci_read_config16(devx, pos + PCI_CAP_FLAGS);
- /* Test for end of chain */
- ctrl_off = ((flags >> 10) & 1)?
- PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1; // another end
-
- do {
- ctrl = pci_read_config16(devx, pos + ctrl_off);
- /* Is this the end of the hypertransport chain? */
- if (ctrl & (1 << 6)) {
- goto out;
- }
-
- if (ctrl & ((1 << 4) | (1 << 8))) {
- /*
- * Either the link has failed, or we have
- * a CRC error.
- * Sometimes this can happen due to link
- * retrain, so lets knock it down and see
- * if its transient
- */
- ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
- pci_write_config16(devx, pos + ctrl_off, ctrl);
- ctrl = pci_read_config16(devx, pos + ctrl_off);
- if (ctrl & ((1 << 4) | (1 << 8))) {
- // can not clear the error
- break;
- }
- }
- } while ((ctrl & (1 << 5)) == 0);
-
- break;
- }
- }
- pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
- }
- } while (last_unitid != next_unitid);
-
-out:
- ;
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- if ((ht_dev_num > 1) && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE) && !end_used) {
- uint16_t flags;
- dev = PCI_DEV(0,real_last_unitid, 0);
- flags = pci_read_config16(dev, real_last_pos + PCI_CAP_FLAGS);
- flags &= ~0x1f;
- flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f;
- pci_write_config16(dev, real_last_pos + PCI_CAP_FLAGS, flags);
- }
-#endif
-
-#endif
-
-}
diff --git a/src/northbridge/amd/amdk8/exit_from_self.c b/src/northbridge/amd/amdk8/exit_from_self.c
deleted file mode 100644
index 4b6f4e2a57..0000000000
--- a/src/northbridge/amd/amdk8/exit_from_self.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz>
- *
- * 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.
- */
-
-#include <arch/io.h>
-#include <console/console.h>
-#include <cpu/x86/lapic.h>
-#include <delay.h>
-#include <cpu/amd/mtrr.h>
-#include "raminit.h"
-#include "f.h"
-
-void exit_from_self(int controllers, const struct mem_controller *ctrl,
- struct sys_info *sysinfo)
-{
- int i;
- u32 dcl, dch;
- u32 pcidev;
- u8 bitmask;
- u8 is_post_rev_g;
- u32 local_cpuid;
-
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[i])
- continue;
- /* Skip everything if I don't have any memory on this controller */
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
- if (!(dch & DCH_MemClkFreqVal)) {
- continue;
- }
-
- local_cpuid = pci_read_config32(ctrl[i].f3, 0xfc);
- is_post_rev_g = ((local_cpuid & 0xfff00) > 0x50f00);
-
- /* ChipKill */
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- if (dcl & DCL_DimmEccEn) {
- u32 mnc;
- printk(BIOS_SPEW, "ECC enabled\n");
- mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
- mnc |= MNC_ECC_EN;
- if (dcl & DCL_Width128) {
- mnc |= MNC_CHIPKILL_EN;
- }
- pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
- }
-
- printk(BIOS_DEBUG, "before resume errata #%d\n",
- (is_post_rev_g) ? 270 : 125);
- /*
- 1. Restore memory controller registers as normal.
- 2. Set the DisAutoRefresh bit (Dev:2x8C[18]). (270 only)
- 3. Set the EnDramInit bit (Dev:2x7C[31]), clear all other bits in the same register).
- 4. Wait at least 750 us.
- 5. Clear the EnDramInit bit.
- 6. Clear the DisAutoRefresh bit. (270 only)
- 7. Read the value of Dev:2x80 and write that value back to Dev:2x80.
- 8. Set the exit from the self refresh bit (Dev:2x90[1]).
- 9. Clear the exit from self refresh bit immediately.
- Note: Steps 8 and 9 must be executed in a single 64-byte aligned uninterrupted instruction stream.
- */
-
- enable_lapic();
- init_timer();
-
- printk(BIOS_DEBUG, "before exit errata - timer enabled\n");
-
- if (is_post_rev_g) {
- dcl =
- pci_read_config32(ctrl[i].f2,
- DRAM_TIMING_HIGH);
- dcl |= (1 << 18);
- pci_write_config32(ctrl[i].f2, DRAM_TIMING_HIGH,
- dcl);
- }
-
- dcl = DI_EnDramInit;
- pci_write_config32(ctrl[i].f2, DRAM_INIT, dcl);
-
- udelay(800);
-
- printk(BIOS_DEBUG, "before exit errata - after mdelay\n");
-
- dcl = pci_read_config32(ctrl[i].f2, DRAM_INIT);
- dcl &= ~DI_EnDramInit;
- pci_write_config32(ctrl[i].f2, DRAM_INIT, dcl);
-
- if (is_post_rev_g) {
- dcl =
- pci_read_config32(ctrl[i].f2,
- DRAM_TIMING_HIGH);
- dcl &= ~(1 << 18);
- pci_write_config32(ctrl[i].f2, DRAM_TIMING_HIGH,
- dcl);
- }
-
- dcl = pci_read_config32(ctrl[i].f2, DRAM_BANK_ADDR_MAP);
- pci_write_config32(ctrl[i].f2, DRAM_BANK_ADDR_MAP, dcl);
-
- /* I was unable to do that like: ctrl[i].f2->path.pci.devfn << 8 */
- pcidev =
- 0x80000000 | ((((ctrl[i].node_id + 0x18) << 3) | 0x2)
- << 8) | 0x90;
- printk(BIOS_DEBUG, "pcidev is %x\n", pcidev);
- bitmask = 2;
- __asm__ __volatile__("pushl %0\n\t"
- "movw $0xcf8, %%dx\n\t"
- "out %%eax, (%%dx)\n\t"
- "movw $0xcfc, %%dx\n\t"
- "inl %%dx, %%eax\n\t"
- "orb %1, %%al\n\t"
- "not %1\n\t"
- ".align 64\n\t"
- "outl %%eax, (%%dx)\n\t"
- "andb %1, %%al\n\t"
- "outl %%eax, (%%dx)\n\t"
- "popl %0\n\t"::"a"(pcidev),
- "q"(bitmask):"edx");
- }
-
- printk(BIOS_DEBUG, "after exit errata\n");
-
-
- for (i = 0; i < controllers; i++) {
- u32 dcm;
- if (!sysinfo->ctrl_present[i])
- continue;
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00)
- continue;
-
- printk(BIOS_DEBUG, "Exiting memory from self refresh: ");
- int loops = 0;
- do {
- loops++;
- if ((loops & 1023) == 0) {
- printk(BIOS_DEBUG, ".");
- }
- dcm =
- pci_read_config32(ctrl[i].f2, DRAM_CTRL_MISC);
- } while (((dcm & DCM_MemClrStatus) ==
- 0) /* || ((dcm & DCM_DramEnabled) == 0) */);
-
- if (loops >= TIMEOUT_LOOPS) {
- printk(BIOS_DEBUG, "timeout with with cntrl[%d]\n", i);
- continue;
- }
-
- printk(BIOS_DEBUG, " done\n");
- }
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- /* init hw mem hole here */
- /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
- set_hw_mem_hole(controllers, ctrl);
-#endif
-
- /* store tom to sysinfo, and it will be used by dqs_timing */
- {
- msr_t msr;
- //[1M, TOM)
- msr = rdmsr(TOP_MEM);
- sysinfo->tom_k = ((msr.hi << 24) | (msr.lo >> 8)) >> 2;
-
- //[4G, TOM2)
- msr = rdmsr(TOP_MEM2);
- sysinfo->tom2_k = ((msr.hi << 24) | (msr.lo >> 8)) >> 2;
- }
-
- for (i = 0; i < controllers; i++) {
-
- if (!sysinfo->ctrl_present[i])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00)
- continue;
-
- dqs_restore_MC_NVRAM((ctrl + i)->f2);
- sysinfo->mem_trained[i] = 1; // mem was trained
- }
-}
diff --git a/src/northbridge/amd/amdk8/f.h b/src/northbridge/amd/amdk8/f.h
deleted file mode 100644
index ec70cb0167..0000000000
--- a/src/northbridge/amd/amdk8/f.h
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef AMDK8_F_H
-#define AMDK8_F_H
-
-#include <compiler.h>
-
-/* Definitions of various K8 registers */
-/* Function 0 */
-#define HT_TRANSACTION_CONTROL 0x68
-#define HTTC_DIS_RD_B_P (1 << 0)
-#define HTTC_DIS_RD_DW_P (1 << 1)
-#define HTTC_DIS_WR_B_P (1 << 2)
-#define HTTC_DIS_WR_DW_P (1 << 3)
-#define HTTC_DIS_MTS (1 << 4)
-#define HTTC_CPU1_EN (1 << 5)
-#define HTTC_CPU_REQ_PASS_PW (1 << 6)
-#define HTTC_CPU_RD_RSP_PASS_PW (1 << 7)
-#define HTTC_DIS_P_MEM_C (1 << 8)
-#define HTTC_DIS_RMT_MEM_C (1 << 9)
-#define HTTC_DIS_FILL_P (1 << 10)
-#define HTTC_RSP_PASS_PW (1 << 11)
-#define HTTC_CHG_ISOC_TO_ORD (1 << 12)
-#define HTTC_BUF_REL_PRI_SHIFT 13
-#define HTTC_BUF_REL_PRI_MASK 3
-#define HTTC_BUF_REL_PRI_64 0
-#define HTTC_BUF_REL_PRI_16 1
-#define HTTC_BUF_REL_PRI_8 2
-#define HTTC_BUF_REL_PRI_2 3
-#define HTTC_LIMIT_CLDT_CFG (1 << 15)
-#define HTTC_LINT_EN (1 << 16)
-#define HTTC_APIC_EXT_BRD_CST (1 << 17)
-#define HTTC_APIC_EXT_ID (1 << 18)
-#define HTTC_APIC_EXT_SPUR (1 << 19)
-#define HTTC_SEQ_ID_SRC_NODE_EN (1 << 20)
-#define HTTC_DS_NP_REQ_LIMIT_SHIFT 21
-#define HTTC_DS_NP_REQ_LIMIT_MASK 3
-#define HTTC_DS_NP_REQ_LIMIT_NONE 0
-#define HTTC_DS_NP_REQ_LIMIT_1 1
-#define HTTC_DS_NP_REQ_LIMIT_4 2
-#define HTTC_DS_NP_REQ_LIMIT_8 3
-#define HTTC_MED_PRI_BYP_CNT_SHIFT 24
-#define HTTC_MED_PRI_BYP_CNT_MASK 3
-#define HTTC_HI_PRI_BYP_CNT_SHIFT 26
-#define HTTC_HI_PRI_BYP_CNT_MASK 3
-
-
-/* Function 1 */
-#define PCI_IO_BASE0 0xc0
-#define PCI_IO_BASE1 0xc8
-#define PCI_IO_BASE2 0xd0
-#define PCI_IO_BASE3 0xd8
-#define PCI_IO_BASE_VGA_EN (1 << 4)
-#define PCI_IO_BASE_NO_ISA (1 << 5)
-
-
-/* Function 2 */
-#define DRAM_CSBASE 0x40
-#define DRAM_CSMASK 0x60
-#define DRAM_BANK_ADDR_MAP 0x80
-
-#define DRAM_CTRL 0x78
-#define DC_RdPtrInit_SHIFT 0
-#define DC_RdPrtInit_MASK 0xf
-#define DC_RdPadRcvFifoDly_SHIFT 4
-#define DC_RdPadRcvFifoDly_MASK 7
-#define DC_RdPadRcvFiloDly_1_5_CLK 2
-#define DC_RdPadRcvFiloDly_2_CLK 3
-#define DC_RdPadRcvFiloDly_2_5_CLK 4
-#define DC_RdPadRcvFiloDly_3_CLK 5
-#define DC_RdPadRcvFiloDly_3_5_CLK 6
-#define DC_AltVidC3MemClkTriEn (1<<16)
-#define DC_DllTempAdjTime_SHIFT 17
-#define DC_DllTempAdjTime_MASK 1
-#define DC_DllTempAdjTime_5_MS 0
-#define DC_DllTempAdjTime_1_MS 1
-#define DC_DqsRcvEnTrain (1<<18)
-
-#define DRAM_INIT 0x7c
-#define DI_MrsAddress_SHIFT 0
-#define DI_MrsAddress_MASK 0xffff
-#define DI_MrsBank_SHIFT 16
-#define DI_MrsBank_MASK 7
-#define DI_SendRchgAll (1<<24)
-#define DI_SendAutoRefresh (1<<25)
-#define DI_SendMrsCmd (1<<26)
-#define DI_DeassertMemRstX (1<<27)
-#define DI_AssertCke (1<<28)
-#define DI_EnDramInit (1<<31)
-
-#define DRAM_TIMING_LOW 0x88
-#define DTL_TCL_SHIFT 0
-#define DTL_TCL_MASK 7
-#define DTL_TCL_BASE 1
-#define DTL_TCL_MIN 3
-#define DTL_TCL_MAX 6
-#define DTL_TRCD_SHIFT 4
-#define DTL_TRCD_MASK 3
-#define DTL_TRCD_BASE 3
-#define DTL_TRCD_MIN 3
-#define DTL_TRCD_MAX 6
-#define DTL_TRP_SHIFT 8
-#define DTL_TRP_MASK 3
-#define DTL_TRP_BASE 3
-#define DTL_TRP_MIN 3
-#define DTL_TRP_MAX 6
-#define DTL_TRTP_SHIFT 11
-#define DTL_TRTP_MASK 1
-#define DTL_TRTP_BASE 2
-#define DTL_TRTP_MIN 2 /* 4 for 64 bytes*/
-#define DTL_TRTP_MAX 3 /* 5 for 64 bytes */
-#define DTL_TRAS_SHIFT 12
-#define DTL_TRAS_MASK 0xf
-#define DTL_TRAS_BASE 3
-#define DTL_TRAS_MIN 5
-#define DTL_TRAS_MAX 18
-#define DTL_TRC_SHIFT 16
-#define DTL_TRC_MASK 0xf
-#define DTL_TRC_BASE 11
-#define DTL_TRC_MIN 11
-#define DTL_TRC_MAX 26
-#define DTL_TWR_SHIFT 20
-#define DTL_TWR_MASK 3
-#define DTL_TWR_BASE 3
-#define DTL_TWR_MIN 3
-#define DTL_TWR_MAX 6
-#define DTL_TRRD_SHIFT 22
-#define DTL_TRRD_MASK 3
-#define DTL_TRRD_BASE 2
-#define DTL_TRRD_MIN 2
-#define DTL_TRRD_MAX 5
-#define DTL_MemClkDis_SHIFT 24 /* Channel A */
-#define DTL_MemClkDis3 (1 << 26)
-#define DTL_MemClkDis2 (1 << 27)
-#define DTL_MemClkDis1 (1 << 28)
-#define DTL_MemClkDis0 (1 << 29)
-#define DTL_MemClkDis1_AM2 (0x51 << 24)
-#define DTL_MemClkDis0_AM2 (0xa2 << 24)
-#define DTL_MemClkDis0_S1g1 (0xa2 << 24)
-
-/* DTL_MemClkDis for m2 and s1g1 is different */
-
-#define DRAM_TIMING_HIGH 0x8c
-#define DTH_TRWTTO_SHIFT 4
-#define DTH_TRWTTO_MASK 7
-#define DTH_TRWTTO_BASE 2
-#define DTH_TRWTTO_MIN 2
-#define DTH_TRWTTO_MAX 9
-#define DTH_TWTR_SHIFT 8
-#define DTH_TWTR_MASK 3
-#define DTH_TWTR_BASE 0
-#define DTH_TWTR_MIN 1
-#define DTH_TWTR_MAX 3
-#define DTH_TWRRD_SHIFT 10
-#define DTH_TWRRD_MASK 3
-#define DTH_TWRRD_BASE 0
-#define DTH_TWRRD_MIN 0
-#define DTH_TWRRD_MAX 3
-#define DTH_TWRWR_SHIFT 12
-#define DTH_TWRWR_MASK 3
-#define DTH_TWRWR_BASE 1
-#define DTH_TWRWR_MIN 1
-#define DTH_TWRWR_MAX 3
-#define DTH_TRDRD_SHIFT 14
-#define DTH_TRDRD_MASK 3
-#define DTH_TRDRD_BASE 2
-#define DTH_TRDRD_MIN 2
-#define DTH_TRDRD_MAX 5
-#define DTH_TREF_SHIFT 16
-#define DTH_TREF_MASK 3
-#define DTH_TREF_7_8_US 2
-#define DTH_TREF_3_9_US 3
-#define DTH_TRFC0_SHIFT 20 /* for Logical DIMM0 */
-#define DTH_TRFC_MASK 7
-#define DTH_TRFC_75_256M 0
-#define DTH_TRFC_105_512M 1
-#define DTH_TRFC_127_5_1G 2
-#define DTH_TRFC_195_2G 3
-#define DTH_TRFC_327_5_4G 4
-#define DTH_TRFC1_SHIFT 23 /*for Logical DIMM1 */
-#define DTH_TRFC2_SHIFT 26 /*for Logical DIMM2 */
-#define DTH_TRFC3_SHIFT 29 /*for Logical DIMM3 */
-
-#define DRAM_CONFIG_LOW 0x90
-#define DCL_InitDram (1<<0)
-#define DCL_ExitSelfRef (1<<1)
-#define DCL_DramTerm_SHIFT 4
-#define DCL_DramTerm_MASK 3
-#define DCL_DramTerm_No 0
-#define DCL_DramTerm_75_OH 1
-#define DCL_DramTerm_150_OH 2
-#define DCL_DramTerm_50_OH 3
-#define DCL_DrvWeak (1<<7)
-#define DCL_ParEn (1<<8)
-#define DCL_SelfRefRateEn (1<<9)
-#define DCL_BurstLength32 (1<<10)
-#define DCL_Width128 (1<<11)
-#define DCL_X4Dimm_SHIFT 12
-#define DCL_X4Dimm_MASK 0xf
-#define DCL_UnBuffDimm (1<<16)
-#define DCL_DimmEccEn (1<<19)
-
-#define DRAM_CONFIG_HIGH 0x94
-#define DCH_MemClkFreq_SHIFT 0
-#define DCH_MemClkFreq_MASK 7
-#define DCH_MemClkFreq_200MHz 0
-#define DCH_MemClkFreq_266MHz 1
-#define DCH_MemClkFreq_333MHz 2
-#define DCH_MemClkFreq_400MHz 3
-#define DCH_MemClkFreqVal (1<<3)
-#define DCH_MaxAsyncLat_SHIFT 4
-#define DCH_MaxAsyncLat_MASK 0xf
-#define DCH_MaxAsyncLat_BASE 0
-#define DCH_MaxAsyncLat_MIN 0
-#define DCH_MaxAsyncLat_MAX 15
-#define DCH_RDqsEn (1<<12)
-#define DCH_DisDramInterface (1<<14)
-#define DCH_PowerDownEn (1<<15)
-#define DCH_PowerDownMode_SHIFT 16
-#define DCH_PowerDownMode_MASK 1
-#define DCH_PowerDownMode_Channel_CKE 0
-#define DCH_PowerDownMode_ChipSelect_CKE 1
-#define DCH_FourRankSODimm (1<<17)
-#define DCH_FourRankRDimm (1<<18)
-#define DCH_SlowAccessMode (1<<19)
-#define DCH_BankSwizzleMode (1<<22)
-#define DCH_DcqBypassMax_SHIFT 24
-#define DCH_DcqBypassMax_MASK 0xf
-#define DCH_DcqBypassMax_BASE 0
-#define DCH_DcqBypassMax_MIN 0
-#define DCH_DcqBypassMax_MAX 15
-#define DCH_FourActWindow_SHIFT 28
-#define DCH_FourActWindow_MASK 0xf
-#define DCH_FourActWindow_BASE 7
-#define DCH_FourActWindow_MIN 8
-#define DCH_FourActWindow_MAX 20
-
-
-// for 0x98 index and 0x9c data
-#define DRAM_CTRL_ADDI_DATA_OFFSET 0x98
-#define DCAO_DctOffset_SHIFT 0
-#define DCAO_DctOffset_MASK 0x3fffffff
-#define DCAO_DctAccessWrite (1<<30)
-#define DCAO_DctAccessDone (1<<31)
-
-#define DRAM_CTRL_ADDI_DATA_PORT 0x9c
-
-#define DRAM_OUTPUT_DRV_COMP_CTRL 0x00
-#define DODCC_CkeDrvStren_SHIFT 0
-#define DODCC_CkeDrvStren_MASK 3
-#define DODCC_CkeDrvStren_1_0X 0
-#define DODCC_CkeDrvStren_1_25X 1
-#define DODCC_CkeDrvStren_1_5X 2
-#define DODCC_CkeDrvStren_2_0X 3
-#define DODCC_CsOdtDrvStren_SHIFT 4
-#define DODCC_CsOdtDrvStren_MASK 3
-#define DODCC_CsOdtDrvStren_1_0X 0
-#define DODCC_CsOdtDrvStren_1_25X 1
-#define DODCC_CsOdtDrvStren_1_5X 2
-#define DODCC_CsOdtDrvStren_2_0X 3
-#define DODCC_AddrCmdDrvStren_SHIFT 8
-#define DODCC_AddrCmdDrvStren_MASK 3
-#define DODCC_AddrCmdDrvStren_1_0X 0
-#define DODCC_AddrCmdDrvStren_1_25X 1
-#define DODCC_AddrCmdDrvStren_1_5X 2
-#define DODCC_AddrCmdDrvStren_2_0X 3
-#define DODCC_ClkDrvStren_SHIFT 12
-#define DODCC_ClkDrvStren_MASK 3
-#define DODCC_ClkDrvStren_0_75X 0
-#define DODCC_ClkDrvStren_1_0X 1
-#define DODCC_ClkDrvStren_1_25X 2
-#define DODCC_ClkDrvStren_1_5X 3
-#define DODCC_DataDrvStren_SHIFT 16
-#define DODCC_DataDrvStren_MASK 3
-#define DODCC_DataDrvStren_0_75X 0
-#define DODCC_DataDrvStren_1_0X 1
-#define DODCC_DataDrvStren_1_25X 2
-#define DODCC_DataDrvStren_1_5X 3
-#define DODCC_DqsDrvStren_SHIFT 20
-#define DODCC_DqsDrvStren_MASK 3
-#define DODCC_DqsDrvStren_0_75X 0
-#define DODCC_DqsDrvStren_1_0X 1
-#define DODCC_DqsDrvStren_1_25X 2
-#define DODCC_DqsDrvStren_1_5X 3
-#define DODCC_ProcOdt_SHIFT 28
-#define DODCC_ProcOdt_MASK 3
-#define DODCC_ProcOdt_300_OHMS 0
-#define DODCC_ProcOdt_150_OHMS 1
-#define DODCC_ProcOdt_75_OHMS 2
-
-#define DRAM_WRITE_DATA_TIMING_CTRL_LOW 0x01
-#define DWDTCL_WrDatTimeByte0_SHIFT 0
-#define DWDTC_WrDatTimeByte_MASK 0x3f
-#define DWDTC_WrDatTimeByte_BASE 0
-#define DWDTC_WrDatTimeByte_MIN 0
-#define DWDTC_WrDatTimeByte_MAX 47
-#define DWDTCL_WrDatTimeByte1_SHIFT 8
-#define DWDTCL_WrDatTimeByte2_SHIFT 16
-#define DWDTCL_WrDatTimeByte3_SHIFT 24
-
-#define DRAM_WRITE_DATA_TIMING_CTRL_HIGH 0x02
-#define DWDTCH_WrDatTimeByte4_SHIFT 0
-#define DWDTCH_WrDatTimeByte5_SHIFT 8
-#define DWDTCH_WrDatTimeByte6_SHIFT 16
-#define DWDTCH_WrDatTimeByte7_SHIFT 24
-
-#define DRAM_WRITE_DATA_ECC_TIMING_CTRL 0x03
-#define DWDETC_WrChkTime_SHIFT 0
-#define DWDETC_WrChkTime_MASK 0x3f
-#define DWDETC_WrChkTime_BASE 0
-#define DWDETC_WrChkTime_MIN 0
-#define DWDETC_WrChkTime_MAX 47
-
-#define DRAM_ADDR_TIMING_CTRL 0x04
-#define DATC_CkeFineDelay_SHIFT 0
-#define DATC_CkeFineDelay_MASK 0x1f
-#define DATC_CkeFineDelay_BASE 0
-#define DATC_CkeFineDelay_MIN 0
-#define DATC_CkeFineDelay_MAX 31
-#define DATC_CkeSetup (1<<5)
-#define DATC_CsOdtFineDelay_SHIFT 8
-#define DATC_CsOdtFineDelay_MASK 0x1f
-#define DATC_CsOdtFineDelay_BASE 0
-#define DATC_CsOdtFineDelay_MIN 0
-#define DATC_CsOdtFineDelay_MAX 31
-#define DATC_CsOdtSetup (1<<13)
-#define DATC_AddrCmdFineDelay_SHIFT 16
-#define DATC_AddrCmdFineDelay_MASK 0x1f
-#define DATC_AddrCmdFineDelay_BASE 0
-#define DATC_AddrCmdFineDelay_MIN 0
-#define DATC_AddrCmdFineDelay_MAX 31
-#define DATC_AddrCmdSetup (1<<21)
-
-#define DRAM_READ_DQS_TIMING_CTRL_LOW 0x05
-#define DRDTCL_RdDqsTimeByte0_SHIFT 0
-#define DRDTC_RdDqsTimeByte_MASK 0x3f
-#define DRDTC_RdDqsTimeByte_BASE 0
-#define DRDTC_RdDqsTimeByte_MIN 0
-#define DRDTC_RdDqsTimeByte_MAX 47
-#define DRDTCL_RdDqsTimeByte1_SHIFT 8
-#define DRDTCL_RdDqsTimeByte2_SHIFT 16
-#define DRDTCL_RdDqsTimeByte3_SHIFT 24
-
-#define DRAM_READ_DQS_TIMING_CTRL_HIGH 0x06
-#define DRDTCH_RdDqsTimeByte4_SHIFT 0
-#define DRDTCH_RdDqsTimeByte5_SHIFT 8
-#define DRDTCH_RdDqsTimeByte6_SHIFT 16
-#define DRDTCH_RdDqsTimeByte7_SHIFT 24
-
-#define DRAM_READ_DQS_ECC_TIMING_CTRL 0x07
-#define DRDETC_RdDqsTimeCheck_SHIFT 0
-#define DRDETC_RdDqsTimeCheck_MASK 0x3f
-#define DRDETC_RdDqsTimeCheck_BASE 0
-#define DRDETC_RdDqsTimeCheck_MIN 0
-#define DRDETC_RdDqsTimeCheck_MAX 47
-
-#define DRAM_DQS_RECV_ENABLE_TIME0 0x10
-#define DDRET_DqsRcvEnDelay_SHIFT 0
-#define DDRET_DqsRcvEnDelay_MASK 0xff
-#define DDRET_DqsRcvEnDelay_BASE 0
-#define DDRET_DqsRcvEnDelay_MIN 0
-#define DDRET_DqsRcvEnDelay_MAX 0xae /* unit is 50ps */
-
-#define DRAM_DQS_RECV_ENABLE_TIME1 0x13
-#define DRAM_DQS_RECV_ENABLE_TIME2 0x16
-#define DRAM_DQS_RECV_ENABLE_TIME3 0x19
-
-/* there are index 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x30, 0x33, 0x36, 0x39
-that are corresponding to 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x13, 0x16, 0x19
-*/
-#define DRAM_CTRL_MISC 0xa0
-#define DCM_MemClrStatus (1<<0)
-#define DCM_DisableJitter (1<<1)
-#define DCM_RdWrQByp_SHIFT 2
-#define DCM_RdWrQByp_MASK 3
-#define DCM_RdWrQByp_2 0
-#define DCM_RdWrQByp_4 1
-#define DCM_RdWrQByp_8 2
-#define DCM_RdWrQByp_16 3
-#define DCM_Mode64BitMux (1<<4)
-#define DCM_DCC_EN (1<<5)
-#define DCM_ILD_lmt_SHIFT 6
-#define DCM_ILD_lmt_MASK 7
-#define DCM_ILD_lmt_0 0
-#define DCM_ILD_lmt_4 1
-#define DCM_ILD_lmt_8 2
-#define DCM_ILD_lmt_16 3
-#define DCM_ILD_lmt_32 4
-#define DCM_ILD_lmt_64 5
-#define DCM_ILD_lmt_128 6
-#define DCM_ILD_lmt_256 7
-#define DCM_DramEnabled (1<<9)
-#define DCM_MemClkDis_SHIFT 24 /* Channel B */
-#define DCM_MemClkDis3 (1 << 26)
-#define DCM_MemClkDis2 (1 << 27)
-#define DCM_MemClkDis1 (1 << 28)
-#define DCM_MemClkDis0 (1 << 29)
-
-
-/* Function 3 */
-#define MCA_NB_CONFIG 0x44
-#define MNC_ECC_EN (1 << 22)
-#define MNC_CHIPKILL_EN (1 << 23)
-
-#define SCRUB_CONTROL 0x58
-#define SCRUB_NONE 0
-#define SCRUB_40ns 1
-#define SCRUB_80ns 2
-#define SCRUB_160ns 3
-#define SCRUB_320ns 4
-#define SCRUB_640ns 5
-#define SCRUB_1_28us 6
-#define SCRUB_2_56us 7
-#define SCRUB_5_12us 8
-#define SCRUB_10_2us 9
-#define SCRUB_20_5us 10
-#define SCRUB_41_0us 11
-#define SCRUB_81_9us 12
-#define SCRUB_163_8us 13
-#define SCRUB_327_7us 14
-#define SCRUB_655_4us 15
-#define SCRUB_1_31ms 16
-#define SCRUB_2_62ms 17
-#define SCRUB_5_24ms 18
-#define SCRUB_10_49ms 19
-#define SCRUB_20_97ms 20
-#define SCRUB_42ms 21
-#define SCRUB_84ms 22
-#define SC_DRAM_SCRUB_RATE_SHFIT 0
-#define SC_DRAM_SCRUB_RATE_MASK 0x1f
-#define SC_L2_SCRUB_RATE_SHIFT 8
-#define SC_L2_SCRUB_RATE_MASK 0x1f
-#define SC_L1D_SCRUB_RATE_SHIFT 16
-#define SC_L1D_SCRUB_RATE_MASK 0x1f
-
-#define SCRUB_ADDR_LOW 0x5C
-
-#define SCRUB_ADDR_HIGH 0x60
-
-#define NORTHBRIDGE_CAP 0xE8
-#define NBCAP_128Bit (1 << 0)
-#define NBCAP_MP (1 << 1)
-#define NBCAP_BIG_MP (1 << 2)
-#define NBCAP_ECC (1 << 3)
-#define NBCAP_CHIPKILL_ECC (1 << 4)
-#define NBCAP_MEMCLK_SHIFT 5
-#define NBCAP_MEMCLK_MASK 3
-#define NBCAP_MEMCLK_200MHZ 3
-#define NBCAP_MEMCLK_266MHZ 2
-#define NBCAP_MEMCLK_333MHZ 1
-#define NBCAP_MEMCLK_NOLIMIT 0
-#define NBCAP_MEMCTRL (1 << 8)
-#define NBCAP_HtcCap (1<<10)
-#define NBCAP_CmpCap_SHIFT 12
-#define NBCAP_CmpCap_MASK 3
-
-
-#define LinkConnected (1 << 0)
-#define InitComplete (1 << 1)
-#define NonCoherent (1 << 2)
-#define ConnectionPending (1 << 4)
-
-#include "raminit.h"
-//struct definitions
-
-struct dimm_size {
- uint8_t per_rank; // it is rows + col + bank_lines + data lines */
- uint8_t rows;
- uint8_t col;
- uint8_t bank; //1, 2, 3 mean 2, 4, 8
- uint8_t rank;
-} __packed;
-
-struct mem_info { // pernode
- uint32_t dimm_mask;
- struct dimm_size sz[DIMM_SOCKETS];
- uint32_t x4_mask;
- uint32_t x16_mask;
- uint32_t single_rank_mask;
- uint32_t page_1k_mask;
-// uint32_t ecc_mask;
-// uint32_t registered_mask;
- uint8_t is_opteron;
- uint8_t is_registered;
- uint8_t is_ecc;
- uint8_t is_Width128;
- uint8_t is_64MuxMode;
- uint8_t memclk_set; // we need to use this to retrieve the mem param
- uint8_t rsv[2];
-} __packed;
-
-struct link_pair_st {
- pci_devfn_t udev;
- uint32_t upos;
- uint32_t uoffs;
- pci_devfn_t dev;
- uint32_t pos;
- uint32_t offs;
-
-} __packed;
-
-struct sys_info {
- uint8_t ctrl_present[NODE_NUMS];
- struct mem_info meminfo[NODE_NUMS];
- struct mem_controller ctrl[NODE_NUMS];
- uint8_t mem_trained[NODE_NUMS]; //0: no dimm, 1: trained, 0x80: not started, 0x81: recv1 fail, 0x82: Pos Fail, 0x83:recv2 fail
- uint32_t tom_k;
- uint32_t tom2_k;
-
- uint32_t mem_base[NODE_NUMS];
- uint32_t cs_base[NODE_NUMS*8]; //8 cs_idx
- uint32_t hole_reg[NODE_NUMS]; // can we spare it to one, and put ctrl idx in it
-
- uint8_t dqs_delay_a[NODE_NUMS*2*2*9]; //8 node channel 2, direction 2 , bytelane *9
- uint8_t dqs_rcvr_dly_a[NODE_NUMS*2*8]; //8 node, channel 2, receiver 8
- uint32_t nodes;
- struct link_pair_st link_pair[16];// enough? only in_conherent
- uint32_t link_pair_num;
- uint32_t ht_c_num;
- uint32_t sbdn;
- uint32_t sblk;
- uint32_t sbbusn;
-} __packed;
-
-#ifdef __PRE_RAM__
-#include <arch/early_variables.h>
-extern struct sys_info sysinfo_car;
-#endif
-
-#include <reset.h>
-
-#if ((CONFIG_MEM_TRAIN_SEQ != 1) && defined(__PRE_RAM__)) || \
- ((CONFIG_MEM_TRAIN_SEQ == 1) && !defined(__PRE_RAM__))
-static inline void wait_all_core0_mem_trained(struct sys_info *sysinfo)
-{
-
- int i;
- uint32_t mask = 0;
- unsigned needs_reset = 0;
-
-
- if (sysinfo->nodes == 1) return; // in case only one CPU installed
-
- for (i = 1; i < sysinfo->nodes; i++) {
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->mem_trained[i]== 0x00) continue;
-
- mask |= (1<<i);
-
- }
-
- i = 1;
- while (1) {
- if (mask & (1<<i)) {
- if ((sysinfo->mem_trained[i])!=0x80) {
- mask &= ~(1<<i);
- }
- }
-
- if (!mask) break;
-
- i++;
- i%=sysinfo->nodes;
- }
-
- for (i = 0; i < sysinfo->nodes; i++) {
- printk(BIOS_DEBUG, "mem_trained[%02x]=%02x\n", i, sysinfo->mem_trained[i]);
- switch(sysinfo->mem_trained[i]) {
- case 0: //don't need train
- case 1: //trained
- break;
- case 0x81: //recv1: fail
- case 0x82: //Pos :fail
- case 0x83: //recv2: fail
- needs_reset = 1;
- break;
- }
- }
- if (needs_reset) {
- printk(BIOS_DEBUG, "mem trained failed\n");
-#ifdef __PRE_RAM__
- soft_reset();
-#else
- hard_reset();
-#endif
- }
-
-}
-#endif
-
-void dqs_restore_MC_NVRAM(unsigned int dev);
-void train_ram_on_node(unsigned nodeid, unsigned coreid,
- struct sys_info *sysinfo, unsigned retcall);
-
-#endif /* AMDK8_F_H */
diff --git a/src/northbridge/amd/amdk8/f_pci.c b/src/northbridge/amd/amdk8/f_pci.c
deleted file mode 100644
index 9c259b008a..0000000000
--- a/src/northbridge/amd/amdk8/f_pci.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef AMDK8_F_PCI_C
-#define AMDK8_F_PCI_C
-
-#include "debug.h"
-
-#ifdef UNUSED_CODE
-/* bit [10,8] are dev func, bit[1,0] are dev index */
-static uint32_t pci_read_config32_index(pci_devfn_t dev, uint32_t index_reg,
- uint32_t index)
-{
- uint32_t dword;
-
- pci_write_config32(dev, index_reg, index);
-
- dword = pci_read_config32(dev, index_reg+0x4);
-
- return dword;
-}
-
-static void pci_write_config32_index(pci_devfn_t dev, uint32_t index_reg,
- uint32_t index, uint32_t data)
-{
- pci_write_config32(dev, index_reg, index);
-
- pci_write_config32(dev, index_reg + 0x4, data);
-}
-#endif
-
-uint32_t pci_read_config32_index_wait(pci_devfn_t dev,
- uint32_t index_reg, uint32_t index)
-{
- uint32_t dword;
-
- index &= ~(1<<30);
- pci_write_config32(dev, index_reg, index);
-
- do {
- dword = pci_read_config32(dev, index_reg);
- } while (!(dword & (1<<31)));
-
- dword = pci_read_config32(dev, index_reg+0x4);
-
- return dword;
-}
-
-static void pci_write_config32_index_wait(pci_devfn_t dev, uint32_t index_reg,
- uint32_t index, uint32_t data)
-{
- uint32_t dword;
-
- pci_write_config32(dev, index_reg + 0x4, data);
-
- index |= (1<<30);
- pci_write_config32(dev, index_reg, index);
- do {
- dword = pci_read_config32(dev, index_reg);
- } while (!(dword & (1<<31)));
-}
-
-#endif
diff --git a/src/northbridge/amd/amdk8/get_sblk_pci1234.c b/src/northbridge/amd/amdk8/get_sblk_pci1234.c
deleted file mode 100644
index fd9584f349..0000000000
--- a/src/northbridge/amd/amdk8/get_sblk_pci1234.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 - 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2007 coresystems GmbH
- *
- * 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.
- */
-
-
-// 2005.9 yhlu serengeti support
-// 2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB
-// 2007.9 stepan improve code documentation
-
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <string.h>
-#include <stdint.h>
-
-#include <cpu/amd/amdk8_sysconf.h>
-
-/*
- * Why we need the pci1234[] array
- *
- * It will keep the sequence of HT devices in the HT link registers even when a
- * given HT I/O card is not installed.
- *
- * The final result for pci1234[] will be
- *
- * pci1234[0] will record the south bridge link and bus range
- * pci1234[i] will record HT chain i.
- *
- * For example, on the Tyan S2885 ramstage will put the AMD8151 chain (HT
- * link 0) into the register 0xE0, and the AMD8131/8111 HT chain into the
- * register 0xE4.
- *
- * So we need to make sure that the south bridge link will always be on
- * pci1234[0].
- *
- * Imagine a scenario with multiple HT I/O cards, where you don't install HT I/O 1,
- * but you only install HT I/O 2 and HT I/O 3. The HT I/Os will end up in registers
- * 0xE4 and 0xE8.
- *
- * But we want to leave pci1234[1] to HT I/O 1 (even though it is disabled),
- * and let HT I/O 2 and HT I/O 3 still use pci1234[2] and pci1234[3].
- *
- * So we keep the sequence. You need to preset the pci1234[1], pci1234[2],
- * pci1234[3] for this purpose.
- *
- * For this example you need to set
- *
- * unsigned pci1234[] = {
- * 0x0000ff0,
- * 0x0000f10, // HT IO 1 card always on node 1
- * 0x0000f20, // HT IO 2 card always on node 2
- * 0x0000f30 // HT IO 3 card always on node 3
- * };
- *
- * For 2P + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P + htio(n2) + htio(n3):
- * You need an array pci1234[6]:
- *
- * unsigned pci1234[] = {
- * 0x0000ff0,
- * 0x0000010, // HT IO 1 card always on node 1
- * 0x0000f00, // HT IO 2 card always on node 0
- * 0x0000110, // HT IO 3 card always on node 1
- * 0x0000f20, // HT IO 4 card always on node 2
- * 0x0000f30 // HT IO 5 card always on node 3
- * };
- *
- *
- * For 4p+htio(n1)+htio(n2)+htio(n3),4p+htio(n1)+4p+htio(n6)+htio(n7):
- * You need an array pci1234[6]:
- *
- * unsigned pci1234[] = {
- * 0x0000ff0,
- * 0x0000f10, // HT IO 1 card always on node 1
- * 0x0000f20, // HT IO 2 card always on node 2
- * 0x0000f30, // HT IO 3 card always on node 3
- * 0x0000f60, // HT IO 4 card always on node 6
- * 0x0000f70 // HT IO 5 card always on node 7
- * };
- *
- *
- * For 2p + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P +
- * htio(n2) + htio(n3), 2P + htio(n1) + 4P + htio(n4) + htio(n5),
- * you need an array pci1234[8]:
- *
- * unsigned pci1234[] = {
- * 0x0000ff0,
- * 0x0000010, // HT IO 1 card always on node 1
- * 0x0000f00, // HT IO 2 card always on node 0
- * 0x0000110, // HT IO 3 card always on node 1
- * 0x0000f20, // HT IO 4 card always on node 2
- * 0x0000f30 // HT IO 5 card always on node 3
- * 0x0000f40, // HT IO 6 card always on node 4
- * 0x0000f50 // HT IO 7 card always on node 5
- * };
- *
- *
- * For 4P + htio(n1) + htio(n2) + htio(n3), 4p + htio(n1) + 2p + htio(n4) +
- * htio(n5), 4p + htio(n1) + 4p + htio(n6) + htio(n7),
- * you need an array pci1234[8]:
- *
- * unsigned pci1234[] = {
- * 0x0000ff0,
- * 0x0000f10, // HT IO 1 card always on node 1
- * 0x0000f20, // HT IO 2 card always on node 2
- * 0x0000f30, // HT IO 3 card always on node 3
- * 0x0000f40, // HT IO 4 card always on node 4
- * 0x0000f50 // HT IO 5 card always on node 5
- * 0x0000f60, // HT IO 6 card always on node 6
- * 0x0000f70 // HT IO 7 card always on node 7
- * };
- *
- *
- * So the maximum posible value of HC_POSSIBLE_NUM is 8. (FIXME Why?)
- *
- * 1n: 3
- * 2n: 2x2 - 1
- * 4n: 1x4 - 2
- * 6n: 2
- * 8n: 2
- * Total: 12
- *
- * Just put all the possible HT Node/link to the list tp pci1234[] in
- * src/mainboard/<vendor>/<mainboard>get_bus_conf.c
- *
- * What about co-processor in socket 1 on a 2 way system? Or socket 2 and
- * socket 3 on a 4 way system? Treat that as an HC, too!
- *
- */
-
-void get_sblk_pci1234(void)
-{
-
- struct device *dev;
- int i,j;
- uint32_t dword;
-
- /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
- dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
- dword = pci_read_config32(dev, 0x64);
- sysconf.sblk = (dword>>8) & 0x3;
-
- dword &=0x0300;
- dword |= 1;
- sysconf.pci1234[0] = dword;
- sysconf.hcid[0] = 0;
-
- /* About hardcoded numbering for HT_IO support
- *
- * Set the node_id and link_id that could have a HT chain in the one
- * array, (FIXME: which one?) then check if is enabled. Then update
- * final value
- */
-
- /* Here we need to set hcdn
- *
- * 1. hypertransport.c needs to record hcdn_reg together with 0xe0,
- * 0xe4, 0xe8, 0xec when are set (FIXME: when WHAT is set?)
- *
- * 2. So at the same time we need update hcdn with hcdn_reg here. FIXME: Why?
- */
-
- dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
-
- for (j = 0; j < 4; j++) {
- uint32_t dwordx;
- dwordx = pci_read_config32(dev, 0xe0 + j*4);
- dwordx &=0xffff0ff1; /* keep bus num, node_id, link_num, enable bits */
- if ((dwordx & 0xff1) == dword) { /* SBLINK */
- sysconf.pci1234[0] = dwordx;
- sysconf.hcdn[0] = sysconf.hcdn_reg[j];
- continue;
- }
-
- if ((dwordx & 1) == 1) {
- /* We need to find out the number of HC
- * for exact match
- */
- for (i = 1; i < sysconf.hc_possible_num; i++) {
- if ((dwordx & 0xff0) == (sysconf.pci1234[i] & 0xff0)) {
- sysconf.pci1234[i] = dwordx;
- sysconf.hcdn[i] = sysconf.hcdn_reg[j];
- break;
- }
- }
-
- /* For 0xff0 match or same node */
- for (i = 1; i < sysconf.hc_possible_num; i++) {
- if ((dwordx & 0xff0) == (dwordx & sysconf.pci1234[i] & 0xff0)) {
- sysconf.pci1234[i] = dwordx;
- sysconf.hcdn[i] = sysconf.hcdn_reg[j];
- break;
- }
- }
- }
- }
-
- for (i = 1; i < sysconf.hc_possible_num; i++) {
- if ((sysconf.pci1234[i] & 1) != 1) {
- sysconf.pci1234[i] = 0;
- sysconf.hcdn[i] = 0x20202020;
- }
- sysconf.hcid[i] = 0;
- }
-
-}
diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c
deleted file mode 100644
index 614c199735..0000000000
--- a/src/northbridge/amd/amdk8/incoherent_ht.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 2004.12 yhlu add multi ht chain dynamically support
- * 2005.11 yhlu add let real sb to use small unitid
- *
- * 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.
- */
-
-#include <device/pci_def.h>
-#include <device/pci_ids.h>
-#include <device/hypertransport_def.h>
-#include <lib.h>
-#include "amdk8.h"
-
-// Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM
-#ifndef K8_ALLOCATE_MMIO_RANGE
- #define K8_ALLOCATE_MMIO_RANGE 0
-#endif
-
-static inline void print_linkn_in (const char *strval, uint8_t byteval)
-{
- printk(BIOS_DEBUG, "%s%02x\n", strval, byteval);
-}
-
-static uint8_t ht_lookup_capability(pci_devfn_t dev, uint16_t val)
-{
- uint8_t pos;
- uint8_t hdr_type;
-
- hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
- pos = 0;
- hdr_type &= 0x7f;
-
- if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
- (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
- pos = PCI_CAPABILITY_LIST;
- }
- if (pos > PCI_CAP_LIST_NEXT) {
- pos = pci_read_config8(dev, pos);
- }
- while (pos != 0) { /* loop through the linked list */
- uint8_t cap;
- cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
- if (cap == PCI_CAP_ID_HT) {
- uint16_t flags;
-
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- if ((flags >> 13) == val) {
- /* Entry is a slave or host , success... */
- break;
- }
- }
- pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
- }
- return pos;
-}
-
-static uint8_t ht_lookup_slave_capability(pci_devfn_t dev)
-{
- return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format
-}
-
-static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid)
-{
- pci_devfn_t dev;
-
- //actually, only for one HT device HT chain, and unitid is 0
-#if !CONFIG_HT_CHAIN_UNITID_BASE
- if (offset_unitid) {
- return;
- }
-#endif
-
- /* Check if is already collapsed */
- if ((!offset_unitid) || (offset_unitid && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0) && (CONFIG_HT_CHAIN_END_UNITID_BASE <CONFIG_HT_CHAIN_UNITID_BASE))))) {
- uint32_t id;
- dev = PCI_DEV(bus, 0, 0);
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if (!((id == 0xffffffff) || (id == 0x00000000) ||
- (id == 0x0000ffff) || (id == 0xffff0000))) {
- return;
- }
- }
-
- /* Spin through the devices and collapse any previous
- * hypertransport enumeration.
- */
- for (dev = PCI_DEV(bus, 1, 0); dev <= PCI_DEV(bus, 0x1f, 0x7); dev += PCI_DEV(0, 1, 0)) {
- uint32_t id;
- uint8_t pos;
- uint16_t flags;
-
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if ((id == 0xffffffff) || (id == 0x00000000) ||
- (id == 0x0000ffff) || (id == 0xffff0000)) {
- continue;
- }
-
- pos = ht_lookup_slave_capability(dev);
- if (!pos) {
- continue;
- }
-
- /* Clear the unitid */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- flags &= ~0x1f;
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
- }
-}
-
-static uint16_t ht_read_freq_cap(pci_devfn_t dev, uint8_t pos)
-{
- /* Handle bugs in valid hypertransport frequency reporting */
- uint16_t freq_cap;
- uint32_t id;
-
- freq_cap = pci_read_config16(dev, pos);
- printk(BIOS_SPEW, "pos=0x%x, unfiltered freq_cap=0x%x\n", pos, freq_cap);
- freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
-
- id = pci_read_config32(dev, 0);
-
- /* AMD 8131 Errata 48 */
- if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
- freq_cap &= ~(1 << HT_FREQ_800Mhz);
- return freq_cap;
- }
-
- /* AMD 8151 Errata 23 */
- if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
- freq_cap &= ~(1 << HT_FREQ_800Mhz);
- return freq_cap;
- }
-
- /* AMD K8 Unsupported 1GHz? */
- if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
- #if IS_ENABLED(CONFIG_K8_HT_FREQ_1G_SUPPORT)
- #if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (is_cpu_pre_e0()) { // only E0 later support 1GHz
- freq_cap &= ~(1 << HT_FREQ_1000Mhz);
- }
- #endif
- #else
- freq_cap &= ~(1 << HT_FREQ_1000Mhz);
- #endif
- }
-
- printk(BIOS_SPEW, "pos=0x%x, filtered freq_cap=0x%x\n", pos, freq_cap);
-
- return freq_cap;
-}
-
-static uint8_t ht_read_width_cap(pci_devfn_t dev, uint8_t pos)
-{
- uint8_t width_cap = pci_read_config8(dev, pos);
-
- uint32_t id;
-
- id = pci_read_config32(dev, 0);
-
- /* netlogic micro cap doesn't support 16 bit yet */
- if (id == (0x184e | (0x0001 << 16))) {
- if ((width_cap & 0x77) == 0x11) {
- width_cap &= 0x88;
- }
- }
-
- return width_cap;
-
-}
-
-#define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
- (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
-
-#define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF)
-#define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF)
-#define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF)
-#define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
-
-#define PCI_HT_HOST_OFFS LINK_OFFS( \
- PCI_HT_CAP_HOST_CTRL, \
- PCI_HT_CAP_HOST_WIDTH, \
- PCI_HT_CAP_HOST_FREQ, \
- PCI_HT_CAP_HOST_FREQ_CAP)
-
-#define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
- PCI_HT_CAP_SLAVE_CTRL0, \
- PCI_HT_CAP_SLAVE_WIDTH0, \
- PCI_HT_CAP_SLAVE_FREQ0, \
- PCI_HT_CAP_SLAVE_FREQ_CAP0)
-
-#define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
- PCI_HT_CAP_SLAVE_CTRL1, \
- PCI_HT_CAP_SLAVE_WIDTH1, \
- PCI_HT_CAP_SLAVE_FREQ1, \
- PCI_HT_CAP_SLAVE_FREQ_CAP1)
-
-static int ht_optimize_link(
- pci_devfn_t dev1, uint8_t pos1, unsigned offs1,
- pci_devfn_t dev2, uint8_t pos2, unsigned offs2)
-{
- static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
- static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
- uint16_t freq_cap1, freq_cap2;
- uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
- uint8_t freq, old_freq;
- int needs_reset;
- /* Set link width and frequency */
-
- printk(BIOS_SPEW, "entering ht_optimize_link\n");
- /* Initially assume everything is already optimized and I don't need a reset */
- needs_reset = 0;
-
- /* Get the frequency capabilities */
- freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
- freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
- printk(BIOS_SPEW, "freq_cap1=0x%x, freq_cap2=0x%x\n", freq_cap1, freq_cap2);
-
- /* Calculate the highest possible frequency */
- freq = log2(freq_cap1 & freq_cap2);
-
- /* See if I am changing the link freqency */
- old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
- old_freq &= 0x0f;
- needs_reset |= old_freq != freq;
- printk(BIOS_SPEW, "dev1 old_freq=0x%x, freq=0x%x, needs_reset=0x%0x\n", old_freq, freq, needs_reset);
- old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
- old_freq &= 0x0f;
- needs_reset |= old_freq != freq;
- printk(BIOS_SPEW, "dev2 old_freq=0x%x, freq=0x%x, needs_reset=0x%0x\n", old_freq, freq, needs_reset);
-
- /* Set the Calculated link frequency */
- pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
- pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
-
- /* Get the width capabilities */
- width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
- width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
- printk(BIOS_SPEW, "width_cap1=0x%x, width_cap2=0x%x\n", width_cap1, width_cap2);
-
- /* Calculate dev1's input width */
- ln_width1 = link_width_to_pow2[width_cap1 & 7];
- ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
- printk(BIOS_SPEW, "dev1 input ln_width1=0x%x, ln_width2=0x%x\n", ln_width1, ln_width2);
- if (ln_width1 > ln_width2) {
- ln_width1 = ln_width2;
- }
- width = pow2_to_link_width[ln_width1];
- printk(BIOS_SPEW, "dev1 input width=0x%x\n", width);
- /* Calculate dev1's output width */
- ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
- ln_width2 = link_width_to_pow2[width_cap2 & 7];
- printk(BIOS_SPEW, "dev1 output ln_width1=0x%x, ln_width2=0x%x\n", ln_width1, ln_width2);
- if (ln_width1 > ln_width2) {
- ln_width1 = ln_width2;
- }
- width |= pow2_to_link_width[ln_width1] << 4;
- printk(BIOS_SPEW, "dev1 input|output width=0x%x\n", width);
-
- /* See if I am changing dev1's width */
- old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
- old_width &= 0x77;
- needs_reset |= old_width != width;
- printk(BIOS_SPEW, "old dev1 input|output width=0x%x\n", width);
-
- /* Set dev1's widths */
- pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
-
- /* Calculate dev2's width */
- width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
- printk(BIOS_SPEW, "dev2 input|output width=0x%x\n", width);
-
- /* See if I am changing dev2's width */
- old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
- old_width &= 0x77;
- needs_reset |= old_width != width;
- printk(BIOS_SPEW, "old dev2 input|output width=0x%x\n", width);
-
- /* Set dev2's widths */
- pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
-
- return needs_reset;
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-static void ht_setup_chainx(pci_devfn_t udev, uint8_t upos, uint8_t bus,
- unsigned offset_unitid, struct sys_info *sysinfo)
-#else
-static int ht_setup_chainx(pci_devfn_t udev, uint8_t upos, uint8_t bus,
- unsigned offset_unitid)
-#endif
-{
- //even CONFIG_HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
-
- uint8_t next_unitid, last_unitid;
- unsigned uoffs;
-
-#if !IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- int reset_needed = 0;
-#endif
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- //let't record the device of last ht device, So we can set the Unitid to CONFIG_HT_CHAIN_END_UNITID_BASE
- unsigned real_last_unitid = 0;
- uint8_t real_last_pos = 0;
- int ht_dev_num = 0;
- uint8_t end_used = 0;
-#endif
-
- uoffs = PCI_HT_HOST_OFFS;
- next_unitid = (offset_unitid) ? CONFIG_HT_CHAIN_UNITID_BASE:1;
-
- do {
- uint32_t id;
- uint8_t pos;
- uint16_t flags, ctrl;
- uint8_t count;
- unsigned offs;
-
- /* Wait until the link initialization is complete */
- do {
- ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
- /* Is this the end of the hypertransport chain? */
- if (ctrl & (1 << 6)) {
- goto end_of_chain;
- }
-
- if (ctrl & ((1 << 4) | (1 << 8))) {
- /*
- * Either the link has failed, or we have
- * a CRC error.
- * Sometimes this can happen due to link
- * retrain, so lets knock it down and see
- * if its transient
- */
- ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
- pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
- ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
- if (ctrl & ((1 << 4) | (1 << 8))) {
- printk(BIOS_ERR, "Detected error on Hypertransport Link\n");
- break;
- }
- }
- } while ((ctrl & (1 << 5)) == 0);
-
- pci_devfn_t dev = PCI_DEV(bus, 0, 0);
- last_unitid = next_unitid;
-
- id = pci_read_config32(dev, PCI_VENDOR_ID);
-
- /* If the chain is enumerated quit */
- if ((id == 0xffffffff) || (id == 0x00000000) ||
- (id == 0x0000ffff) || (id == 0xffff0000))
- {
- break;
- }
-
- pos = ht_lookup_slave_capability(dev);
- if (!pos) {
- printk(BIOS_ERR, "udev=%08x", udev);
- printk(BIOS_ERR, "\tupos=%08x", upos);
- printk(BIOS_ERR, "\tuoffs=%08x", uoffs);
- printk(BIOS_ERR, "\tHT link capability not found\n");
- break;
- }
-
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- if (offset_unitid) {
- if (next_unitid >= (bus ? 0x20:0x18)) {
- if (!end_used) {
- next_unitid = CONFIG_HT_CHAIN_END_UNITID_BASE;
- end_used = 1;
- } else {
- goto out;
- }
-
- }
- real_last_pos = pos;
- real_last_unitid = next_unitid;
- ht_dev_num++;
- }
-#endif
- /* Update the Unitid of the current device */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- flags &= ~0x1f; /* mask out the base Unit ID */
- flags |= next_unitid & 0x1f;
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
-
- /* Compute the number of unitids consumed */
- count = (flags >> 5) & 0x1f;
-
- /* Note the change in device number */
- dev = PCI_DEV(bus, next_unitid, 0);
-
- next_unitid += count;
-
- /* Find which side of the ht link we are on,
- * by reading which direction our last write to PCI_CAP_FLAGS
- * came from.
- */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
-
- #if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
- {
- struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
- link_pair->udev = udev;
- link_pair->upos = upos;
- link_pair->uoffs = uoffs;
- link_pair->dev = dev;
- link_pair->pos = pos;
- link_pair->offs = offs;
- sysinfo->link_pair_num++;
- }
- #else
- reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
- #endif
-
- /* Remeber the location of the last device */
- udev = dev;
- upos = pos;
- uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
-
- } while (last_unitid != next_unitid);
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
-out:
-#endif
-end_of_chain:;
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
- if (offset_unitid && (ht_dev_num > 1) && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE) && !end_used) {
- uint16_t flags;
- flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
- flags &= ~0x1f;
- flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f;
- pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
-
- #if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- // Here need to change the dev in the array
- int i;
- for (i = 0; i < sysinfo->link_pair_num; i++)
- {
- struct link_pair_st *link_pair = &sysinfo->link_pair[i];
- if (link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
- link_pair->udev = PCI_DEV(bus, CONFIG_HT_CHAIN_END_UNITID_BASE, 0);
- continue;
- }
- if (link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
- link_pair->dev = PCI_DEV(bus, CONFIG_HT_CHAIN_END_UNITID_BASE, 0);
- }
- }
- #endif
-
- }
-#endif
-
-#if !IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- return reset_needed;
-#endif
-
-}
-
-static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
-{
- uint32_t dword, dword_old;
- uint8_t link_type;
-
- /* This works on an Athlon64 because unimplemented links return 0 */
- dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
- link_type = dword & 0xff;
-
-
- if ((link_type & 7) == linkt) { /* Coherent Link only linkt = 3, ncoherent = 7*/
- dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
- dword &= ~(0xff<<(linkn *8));
- dword |= val << (linkn *8);
-
- if (dword != dword_old) {
- pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
-{
- int reset_needed;
- uint8_t i;
-
- reset_needed = 0;
-
- /* First one is SB HT chain. */
- for (i = 0; i < ht_c_num; i++) {
- uint32_t reg;
- uint8_t nodeid, linkn;
- uint8_t busn;
- uint8_t val;
- unsigned devn;
-
- reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
-
- nodeid = ((reg & 0xf0)>>4); // nodeid
- linkn = ((reg & 0xf00)>>8); // link n
- busn = (reg & 0xff0000)>>16; //busn
-
- devn = offset_unit_id(i == 0) ? CONFIG_HT_CHAIN_UNITID_BASE : 1;
-
- reg = pci_read_config32(PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
- if ((reg & 0xffff) == PCI_VENDOR_ID_AMD) {
- val = 0x25;
- } else if ((reg & 0xffff) == PCI_VENDOR_ID_NVIDIA) {
- val = 0x25;//???
- } else {
- continue;
- }
-
- reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
-
- }
-
- return reset_needed;
-}
-
-#if IS_ENABLED(CONFIG_SOUTHBRIDGE_NVIDIA_CK804)
-static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
-{
- uint32_t dword;
- uint8_t link_type;
- unsigned regpos;
- pci_devfn_t dev;
-
- /* This works on an Athlon64 because unimplemented links return 0 */
- regpos = 0x98 + (linkn * 0x20);
- dev = PCI_DEV(0,0x18+node,0);
- dword = pci_read_config32(dev, regpos);
- link_type = dword & 0xff;
-
- if ((link_type & 0x7) == linkt) { /* Coherent Link only linkt = 3, ncoherent = 7*/
- regpos = 0x90 + (linkn * 0x20);
- dword = pci_read_config32(dev, regpos);
-
- if (dword != val) {
- pci_write_config32(dev, regpos, val);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val)
-{
- int reset_needed;
- uint8_t i;
-
- reset_needed = 0;
-
- for (i = 0; i < ht_c_num; i++) {
- uint32_t reg;
- uint8_t nodeid, linkn;
- uint8_t busn;
- unsigned devn;
-
- reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
- if ((reg & 3) != 3) continue; // not enabled
-
- nodeid = ((reg & 0xf0)>>4); // nodeid
- linkn = ((reg & 0xf00)>>8); // link n
- busn = (reg & 0xff0000)>>16; //busn
-
- for (devn = 0; devn < 0x20; devn++) {
- reg = pci_read_config32(PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
- if ((reg & 0xffff) == vendorid) {
- reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
- break;
- }
- }
- }
-
- return reset_needed;
-}
-#endif
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
-#else
-static int ht_setup_chains(uint8_t ht_c_num)
-#endif
-{
- /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
- * On most boards this just happens. If a CPU has multiple
- * non Coherent links the appropriate bus registers for the
- * links needs to be programed to point at bus 0.
- */
- uint8_t upos;
- pci_devfn_t udev;
- uint8_t i;
-
-#if !IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- int reset_needed = 0;
-#else
- sysinfo->link_pair_num = 0;
-#endif
-
- /* First one is SB HT chain. */
- for (i = 0; i < ht_c_num; i++) {
- uint32_t reg;
- uint8_t devpos;
- unsigned regpos;
- uint32_t dword;
- uint8_t busn;
-
- reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
-
- //We need setup 0x94, 0xb4, and 0xd4 according to the reg
- devpos = ((reg & 0xf0)>>4)+0x18; // nodeid;it will decide 0x18 or 0x19
- regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n;it will decide 0x94 or 0xb4, 0x0xd4;
- busn = (reg & 0xff0000)>>16;
-
- dword = pci_read_config32(PCI_DEV(0, devpos, 0), regpos);
- dword &= ~(0xffff<<8);
- dword |= (reg & 0xffff0000)>>8;
- pci_write_config32(PCI_DEV(0, devpos,0), regpos , dword);
-
- /* Make certain the HT bus is not enumerated */
- ht_collapse_previous_enumeration(busn, offset_unit_id(i == 0));
-
- upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
- udev = PCI_DEV(0, devpos, 0);
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- ht_setup_chainx(udev,upos,busn, offset_unit_id(i == 0), sysinfo); // all not
-#else
- reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unit_id(i == 0)); //all not
-#endif
-
- }
-
-#if !IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
-
- return reset_needed;
-#endif
-
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-static void ht_setup_chains_x(struct sys_info *sysinfo)
-#else
-static int ht_setup_chains_x(void)
-#endif
-{
- uint8_t nodeid;
- uint32_t reg;
- uint32_t tempreg;
- uint8_t next_busn;
- uint8_t ht_c_num;
- uint8_t nodes;
-#if IS_ENABLED(CONFIG_K8_ALLOCATE_IO_RANGE)
- unsigned next_io_base;
-#endif
-
- nodes = get_nodes();
-
- /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
- reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
- /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn = 0x3f+1 */
- print_linkn_in("SBLink=", ((reg>>8) & 3));
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- sysinfo->sblk = (reg>>8) & 3;
- sysinfo->sbbusn = 0;
- sysinfo->nodes = nodes;
-#endif
- tempreg = 3 | (0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
-
- next_busn = 0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
-
-#if IS_ENABLED(CONFIG_K8_ALLOCATE_IO_RANGE)
- /* io range allocation */
- tempreg = 0 | (((reg>>8) & 0x3) << 4)| (0x3<<12); //limit
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
- tempreg = 3 | (3<<4) | (0<<12); //base
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
- next_io_base = 0x3+0x1;
-#endif
-
- /* clean others */
- for (ht_c_num = 1;ht_c_num < 4; ht_c_num++) {
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
-
-#if IS_ENABLED(CONFIG_K8_ALLOCATE_IO_RANGE)
- /* io range allocation */
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
-#endif
- }
-
- for (nodeid = 0; nodeid < nodes; nodeid++) {
- pci_devfn_t dev;
- uint8_t linkn;
- dev = PCI_DEV(0, 0x18+nodeid,0);
- for (linkn = 0; linkn < 3; linkn++) {
- unsigned regpos;
- regpos = 0x98 + 0x20 * linkn;
- reg = pci_read_config32(dev, regpos);
- if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
- print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
- tempreg = 3 | (nodeid <<4) | (linkn<<8);
- /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
- for (ht_c_num = 0;ht_c_num < 4; ht_c_num++) {
- reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
- if (((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/
- break;
- }
- }
- if (ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
- /*update to 0xe0...*/
- if ((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
- print_linkn_in("\tbusn=", next_busn);
- tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
- next_busn+=0x3f+1;
-
-#if IS_ENABLED(CONFIG_K8_ALLOCATE_IO_RANGE)
- /* io range allocation */
- tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
- tempreg = 3 /*| (3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
- pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
- next_io_base += 0x3+0x1;
-#endif
-
- }
- }
- /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
-
- for (nodeid = 1; nodeid < nodes; nodeid++) {
- int i;
- pci_devfn_t dev;
- dev = PCI_DEV(0, 0x18+nodeid,1);
- for (i = 0; i < 4; i++) {
- unsigned regpos;
- regpos = 0xe0 + i * 4;
- reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
- pci_write_config32(dev, regpos, reg);
- }
-
-#if IS_ENABLED(CONFIG_K8_ALLOCATE_IO_RANGE)
- /* io range allocation */
- for (i = 0; i < 4; i++) {
- unsigned regpos;
- regpos = 0xc4 + i * 8;
- reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
- pci_write_config32(dev, regpos, reg);
- }
- for (i = 0; i < 4; i++) {
- unsigned regpos;
- regpos = 0xc0 + i * 8;
- reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
- pci_write_config32(dev, regpos, reg);
- }
-#endif
- }
-
- /* recount ht_c_num*/
- uint8_t i = 0;
- for (ht_c_num = 0;ht_c_num < 4; ht_c_num++) {
- reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
- if (((reg & 0xf) != 0x0)) {
- i++;
- }
- }
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
- sysinfo->ht_c_num = i;
- ht_setup_chains(i, sysinfo);
- sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
-#else
- return ht_setup_chains(i);
-#endif
-
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
-{
- // We need to use recorded link pair info to optimize the link
- int i;
- int reset_needed = 0;
-
- unsigned link_pair_num = sysinfo->link_pair_num;
-
- printk(BIOS_SPEW, "entering optimize_link_incoherent_ht\n");
- printk(BIOS_SPEW, "sysinfo->link_pair_num=0x%x\n", link_pair_num);
- for (i = 0; i < link_pair_num; i++) {
- struct link_pair_st *link_pair= &sysinfo->link_pair[i];
- reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
- printk(BIOS_SPEW, "after ht_optimize_link for link pair %d, reset_needed=0x%x\n", i, reset_needed);
- }
-
- reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);
- printk(BIOS_SPEW, "after optimize_link_read_pointers_chain, reset_needed=0x%x\n", reset_needed);
-
- return reset_needed;
-
-}
-#endif
diff --git a/src/northbridge/amd/amdk8/misc_control.c b/src/northbridge/amd/amdk8/misc_control.c
deleted file mode 100644
index 0edd58c2dd..0000000000
--- a/src/northbridge/amd/amdk8/misc_control.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * written in 2003 by Eric Biederman
- *
- * - Athlon64 workarounds by Stefan Reinauer
- * - "reset once" logic by Yinghai Lu
- *
- * 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.
- */
-
-/* Turn off machine check triggers when reading
- * PCI space where there are no devices.
- * This is necessary when scanning the bus for
- * devices which is done by the kernel
- *
- */
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <reset.h>
-#include <pc80/mc146818rtc.h>
-#include <lib.h>
-#include <cpu/amd/model_fxx_rev.h>
-
-#include "amdk8.h"
-
-/**
- * @brief Read resources for AGP aperture
- *
- * @param dev
- *
- * There is only one AGP aperture resource needed. The resource is added to
- * the northbridge of BSP.
- *
- * The same trick can be used to augment legacy VGA resources which can
- * be detect by generic PCI resource allocator for VGA devices.
- * BAD: it is more tricky than I think, the resource allocation code is
- * implemented in a way to NOT DOING legacy VGA resource allocation on
- * purpose :-(.
- */
-static void mcf3_read_resources(struct device *dev)
-{
- struct resource *resource;
- unsigned char iommu;
- /* Read the generic PCI resources */
- pci_dev_read_resources(dev);
-
- /* If we are not the first processor don't allocate the GART aperture */
- if (dev->path.pci.devfn != PCI_DEVFN(0x18, 3)) {
- return;
- }
-
- iommu = CONFIG_IOMMU;
- get_option(&iommu, "iommu");
-
- if (iommu) {
- /* Add a GART aperture resource */
- resource = new_resource(dev, 0x94);
- resource->size = CONFIG_AGP_APERTURE_SIZE;
- resource->align = log2(resource->size);
- resource->gran = log2(resource->size);
- resource->limit = 0xffffffff; /* 4G */
- resource->flags = IORESOURCE_MEM;
- }
-}
-
-static void set_agp_aperture(struct device *dev)
-{
- struct resource *resource;
-
- resource = probe_resource(dev, 0x94);
- if (resource) {
- struct device *pdev;
- uint32_t gart_base, gart_acr;
-
- /* Remember this resource has been stored */
- resource->flags |= IORESOURCE_STORED;
-
- /* Find the size of the GART aperture */
- gart_acr = (0<<6)|(0<<5)|(0<<4)|((resource->gran - 25) << 1)|(0<<0);
-
- /* Get the base address */
- gart_base = ((resource->base) >> 25) & 0x00007fff;
-
- /* Update the other northbridges */
- pdev = 0;
- while ((pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev))) {
- /* Store the GART size but don't enable it */
- pci_write_config32(pdev, 0x90, gart_acr);
-
- /* Store the GART base address */
- pci_write_config32(pdev, 0x94, gart_base);
-
- /* Don't set the GART Table base address */
- pci_write_config32(pdev, 0x98, 0);
-
- /* Report the resource has been stored... */
- report_resource_stored(pdev, resource, " <gart>");
- }
- }
-}
-
-static void mcf3_set_resources(struct device *dev)
-{
- /* Set the gart apeture */
- set_agp_aperture(dev);
-
- /* Set the generic PCI resources */
- pci_dev_set_resources(dev);
-}
-
-static void misc_control_init(struct device *dev)
-{
- uint32_t cmd, cmd_ref;
- int needs_reset;
- struct device *f0_dev;
-
- printk(BIOS_DEBUG, "NB: Function 3 Misc Control.. ");
- needs_reset = 0;
-
- /* Disable Machine checks from Invalid Locations.
- * This is needed for PC backwards compatibility.
- */
- cmd = pci_read_config32(dev, 0x44);
- cmd |= (1<<6) | (1<<25);
- pci_write_config32(dev, 0x44, cmd);
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (is_cpu_pre_c0()) {
-
- /* Errata 58
- * Disable CPU low power states C2, C1 and throttling
- */
- cmd = pci_read_config32(dev, 0x80);
- cmd &= ~(1<<0);
- pci_write_config32(dev, 0x80, cmd);
- cmd = pci_read_config32(dev, 0x84);
- cmd &= ~(1<<24);
- cmd &= ~(1<<8);
- pci_write_config32(dev, 0x84, cmd);
-
- /* Errata 66
- * Limit the number of downstream posted requests to 1
- */
- cmd = pci_read_config32(dev, 0x70);
- if ((cmd & (3 << 0)) != 2) {
- cmd &= ~(3<<0);
- cmd |= (2<<0);
- pci_write_config32(dev, 0x70, cmd);
- needs_reset = 1;
- }
- cmd = pci_read_config32(dev, 0x7c);
- if ((cmd & (3 << 4)) != 0) {
- cmd &= ~(3<<4);
- cmd |= (0<<4);
- pci_write_config32(dev, 0x7c, cmd);
- needs_reset = 1;
- }
- /* Clock Power/Timing Low */
- cmd = pci_read_config32(dev, 0xd4);
- if (cmd != 0x000D0001) {
- cmd = 0x000D0001;
- pci_write_config32(dev, 0xd4, cmd);
- needs_reset = 1; /* Needed? */
- }
- }
- else if (is_cpu_pre_d0()) {
- struct device *f2_dev;
- uint32_t dcl;
- f2_dev = dev_find_slot(0, dev->path.pci.devfn - 3 + 2);
- /* Errata 98
- * Set Clk Ramp Hystersis to 7
- * Clock Power/Timing Low
- */
- cmd_ref = 0x04e20707; /* Registered */
- dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
- if (dcl & DCL_UnBuffDimm) {
- cmd_ref = 0x000D0701; /* Unbuffered */
- }
- cmd = pci_read_config32(dev, 0xd4);
- if (cmd != cmd_ref) {
- pci_write_config32(dev, 0xd4, cmd_ref);
- needs_reset = 1; /* Needed? */
- }
- }
-#endif
- /* Optimize the Link read pointers */
- f0_dev = dev_find_slot(0, dev->path.pci.devfn - 3);
- if (f0_dev) {
- int link;
- cmd_ref = cmd = pci_read_config32(dev, 0xdc);
- for (link = 0; link < 3; link++) {
- uint32_t link_type;
- unsigned reg;
- /* This works on an Athlon64 because unimplemented links return 0 */
- reg = 0x98 + (link * 0x20);
- link_type = pci_read_config32(f0_dev, reg);
- /* Only handle coherent link here please */
- if ((link_type & (LinkConnected|InitComplete|NonCoherent))
- == (LinkConnected|InitComplete))
- {
- cmd &= ~(0xff << (link *8));
- /* FIXME this assumes the device on the other side is an AMD device */
- cmd |= 0x25 << (link *8);
- }
- }
- if (cmd != cmd_ref) {
- pci_write_config32(dev, 0xdc, cmd);
- needs_reset = 1;
- }
- }
- else {
- printk(BIOS_ERR, "Missing f0 device!\n");
- }
- if (needs_reset) {
- printk(BIOS_DEBUG, "resetting cpu\n");
- hard_reset();
- }
- printk(BIOS_DEBUG, "done.\n");
-}
-
-
-static struct device_operations mcf3_ops = {
- .read_resources = mcf3_read_resources,
- .set_resources = mcf3_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = misc_control_init,
- .scan_bus = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver mcf3_driver __pci_driver = {
- .ops = &mcf3_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x1103,
-};
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c
deleted file mode 100644
index ab6be96ddb..0000000000
--- a/src/northbridge/amd/amdk8/northbridge.c
+++ /dev/null
@@ -1,1288 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 2004.12 yhlu add dual core support
- * 2005.01 yhlu add support move apic before pci_domain in MB devicetree.cb
- * 2005.02 yhlu add e0 memory hole support
- * 2005.11 yhlu add put sb ht chain on bus 0
- *
- * 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.
- */
-
-#include <console/console.h>
-#include <arch/io.h>
-#include <stdint.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/hypertransport.h>
-#include <stdlib.h>
-#include <string.h>
-#include <lib.h>
-#include <cpu/cpu.h>
-#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
-#include <arch/acpi.h>
-#include "acpi.h"
-#endif
-
-#include <cpu/x86/lapic.h>
-#include <cpu/amd/mtrr.h>
-
-#include <cpu/amd/multicore.h>
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
-#include <pc80/mc146818rtc.h>
-#endif
-
-#include "northbridge.h"
-
-#include "amdk8.h"
-
-#include <cpu/amd/model_fxx_rev.h>
-
-#include <cpu/amd/amdk8_sysconf.h>
-
-struct amdk8_sysconf_t sysconf;
-
-#define MAX_FX_DEVS 8
-static struct device *__f0_dev[MAX_FX_DEVS];
-static struct device *__f1_dev[MAX_FX_DEVS];
-static unsigned fx_devs = 0;
-
-static void get_fx_devs(void)
-{
- int i;
- for (i = 0; i < MAX_FX_DEVS; i++) {
- __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
- __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
- if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
- fx_devs = i+1;
- }
- if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
- die("Cannot find 0:0x18.[0|1]\n");
- }
-}
-
-static u32 f1_read_config32(unsigned reg)
-{
- if (fx_devs == 0)
- get_fx_devs();
- return pci_read_config32(__f1_dev[0], reg);
-}
-
-static void f1_write_config32(unsigned reg, u32 value)
-{
- int i;
- if (fx_devs == 0)
- get_fx_devs();
- for (i = 0; i < fx_devs; i++) {
- struct device *dev;
- dev = __f1_dev[i];
- if (dev && dev->enabled) {
- pci_write_config32(dev, reg, value);
- }
- }
-}
-
-typedef enum {
- HT_ROUTE_CLOSE,
- HT_ROUTE_SCAN,
- HT_ROUTE_FINAL,
-} scan_state;
-
-static void ht_route_link(struct bus *link, scan_state mode)
-{
- struct device *dev = link->dev;
- struct bus *parent = dev->bus;
- u32 busses;
-
- if (mode == HT_ROUTE_SCAN) {
- if (link->dev->bus->subordinate == 0)
- link->secondary = 0;
- else
- link->secondary = parent->subordinate + 1;
-
- link->subordinate = link->secondary;
- }
-
- /* Configure the bus numbers for this bridge: the configuration
- * transactions will not be propagated by the bridge if it is
- * not correctly configured
- */
- busses = pci_read_config32(link->dev, link->cap + 0x14);
- busses &= 0xff000000;
- busses |= parent->secondary & 0xff;
- if (mode == HT_ROUTE_CLOSE) {
- busses |= 0xfeff << 8;
- } else if (mode == HT_ROUTE_SCAN) {
- busses |= ((u32) link->secondary & 0xff) << 8;
- busses |= 0xff << 16;
- } else if (mode == HT_ROUTE_FINAL) {
- busses |= ((u32) link->secondary & 0xff) << 8;
- busses |= ((u32) link->subordinate & 0xff) << 16;
- }
- pci_write_config32(link->dev, link->cap + 0x14, busses);
-
- if (mode == HT_ROUTE_FINAL) {
- /* Second chain will be on 0x40, third 0x80, forth 0xc0. */
- if (CONFIG_HT_CHAIN_DISTRIBUTE)
- parent->subordinate = ALIGN_UP(link->subordinate, 0x40) - 1;
- else
- parent->subordinate = link->subordinate;
- }
-}
-
-static u32 amdk8_nodeid(struct device *dev)
-{
- return (dev->path.pci.devfn >> 3) - 0x18;
-}
-
-static void amdk8_scan_chain(struct bus *link)
-{
- unsigned int next_unitid;
- int index;
- u32 config_busses;
- u32 free_reg, config_reg;
- u32 nodeid = amdk8_nodeid(link->dev);
-
- /* See if there is an available configuration space mapping
- * register in function 1.
- */
- free_reg = 0;
- for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
- u32 config;
- config = f1_read_config32(config_reg);
- if (!free_reg && ((config & 3) == 0)) {
- free_reg = config_reg;
- continue;
- }
- if (((config & 3) == 3) &&
- (((config >> 4) & 7) == nodeid) &&
- (((config >> 8) & 3) == link->link_num)) {
- break;
- }
- }
- if (free_reg && (config_reg > 0xec)) {
- config_reg = free_reg;
- }
- /* If we can't find an available configuration space mapping
- * register skip this bus
- */
- if (config_reg > 0xec) {
- return;
- }
-
- /* Set up the primary, secondary and subordinate bus numbers.
- * We have no idea how many busses are behind this bridge yet,
- * so we set the subordinate bus number to 0xff for the moment.
- */
-
- ht_route_link(link, HT_ROUTE_SCAN);
-
- config_busses = f1_read_config32(config_reg);
- config_busses &= 0x000fc88;
- config_busses |=
- (3 << 0) | /* rw enable, no device compare */
- ((nodeid & 7) << 4) |
- ((link->link_num & 3) << 8) |
- ((link->secondary) << 16) |
- (0xff << 24);
- f1_write_config32(config_reg, config_busses);
-
- /* Now we can scan all of the subordinate busses i.e. the
- * chain on the hypertranport link
- */
-
- next_unitid = hypertransport_scan_chain(link);
-
- /* Now that nothing is overlapping it is safe to scan the children. */
- pci_scan_bus(link, 0x00, ((next_unitid - 1) << 3) | 7);
-
- /* We know the number of busses behind this bridge. Set the
- * subordinate bus number to it's real value
- */
-
- ht_route_link(link, HT_ROUTE_FINAL);
-
- config_busses = (config_busses & 0x00ffffff) |
- (link->subordinate << 24);
- f1_write_config32(config_reg, config_busses);
-
- index = (config_reg-0xe0) >> 2;
- sysconf.hcdn_reg[index] = link->hcdn_reg;
-}
-
-/* Do sb ht chain at first, in case s2885 put sb chain
- * (8131/8111) on link2, but put 8151 on link0.
- */
-static void relocate_sb_ht_chain(void)
-{
- struct device *dev;
- struct bus *link, *prev = NULL;
- u8 sblink;
-
- dev = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
- sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
- link = dev->link_list;
-
- while (link) {
- if (link->link_num == sblink) {
- if (!prev)
- return;
- prev->next = link->next;
- link->next = dev->link_list;
- dev->link_list = link;
- return;
- }
- prev = link;
- link = link->next;
- }
-}
-
-static void trim_ht_chain(struct device *dev)
-{
- struct bus *link;
-
- /* Check for connected links. */
- for (link = dev->link_list; link; link = link->next) {
- link->cap = 0x80 + (link->link_num * 0x20);
- link->ht_link_up = ht_is_non_coherent_link(link);
- }
-}
-
-static void amdk8_scan_chains(struct device *dev)
-{
- struct bus *link;
-
- trim_ht_chain(dev);
-
- for (link = dev->link_list; link; link = link->next) {
- if (link->ht_link_up)
- amdk8_scan_chain(link);
- }
-}
-
-
-static int reg_useable(unsigned reg, struct device *goal_dev,
- unsigned goal_nodeid, unsigned goal_link)
-{
- struct resource *res;
- unsigned nodeid, link = 0;
- int result;
- res = 0;
- for (nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
- struct device *dev;
- dev = __f0_dev[nodeid];
- if (!dev)
- continue;
- for (link = 0; !res && (link < 3); link++) {
- res = probe_resource(dev, IOINDEX(0x100 + reg, link));
- }
- }
- result = 2;
- if (res) {
- result = 0;
- if ( (goal_link == (link - 1)) &&
- (goal_nodeid == (nodeid - 1)) &&
- (res->flags <= 1)) {
- result = 1;
- }
- }
- return result;
-}
-
-static unsigned amdk8_find_reg(struct device *dev, unsigned nodeid,
- unsigned link, unsigned min, unsigned max)
-{
- unsigned resource;
- unsigned free_reg, reg;
- resource = 0;
- free_reg = 0;
- for (reg = min; reg <= max; reg += 0x8) {
- int result;
- result = reg_useable(reg, dev, nodeid, link);
- if (result == 1) {
- /* I have been allocated this one */
- break;
- }
- else if (result > 1) {
- /* I have a free register pair */
- free_reg = reg;
- }
- }
- if (reg > max) {
- reg = free_reg;
- }
- if (reg > 0) {
- resource = IOINDEX(0x100 + reg, link);
- }
- return resource;
-}
-
-static unsigned amdk8_find_iopair(struct device *dev, unsigned nodeid,
- unsigned link)
-{
- return amdk8_find_reg(dev, nodeid, link, 0xc0, 0xd8);
-}
-
-static unsigned amdk8_find_mempair(struct device *dev, unsigned nodeid,
- unsigned link)
-{
- return amdk8_find_reg(dev, nodeid, link, 0x80, 0xb8);
-}
-
-static void amdk8_link_read_bases(struct device *dev, unsigned nodeid,
- unsigned link)
-{
- struct resource *resource;
-
- /* Initialize the io space constraints on the current bus */
- resource = new_resource(dev, IOINDEX(0, link));
- if (resource) {
- resource->base = 0;
- resource->size = 0;
- resource->align = log2(HT_IO_HOST_ALIGN);
- resource->gran = log2(HT_IO_HOST_ALIGN);
- resource->limit = 0xffffUL;
- resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
- }
-
- /* Initialize the prefetchable memory constraints on the current bus */
- resource = new_resource(dev, IOINDEX(2, link));
- if (resource) {
- resource->base = 0;
- resource->size = 0;
- resource->align = log2(HT_MEM_HOST_ALIGN);
- resource->gran = log2(HT_MEM_HOST_ALIGN);
- resource->limit = 0xffffffffffULL;
- resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- resource->flags |= IORESOURCE_BRIDGE;
- }
-
- /* Initialize the memory constraints on the current bus */
- resource = new_resource(dev, IOINDEX(1, link));
- if (resource) {
- resource->base = 0;
- resource->size = 0;
- resource->align = log2(HT_MEM_HOST_ALIGN);
- resource->gran = log2(HT_MEM_HOST_ALIGN);
- resource->limit = 0xffffffffULL;
- resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
- }
-}
-
-static void amdk8_create_vga_resource(struct device *dev, unsigned nodeid);
-
-static void amdk8_read_resources(struct device *dev)
-{
- unsigned nodeid;
- struct bus *link;
- nodeid = amdk8_nodeid(dev);
- for (link = dev->link_list; link; link = link->next) {
- if (link->children) {
- amdk8_link_read_bases(dev, nodeid, link->link_num);
- }
- }
- amdk8_create_vga_resource(dev, nodeid);
-}
-
-static void amdk8_set_resource(struct device *dev, struct resource *resource,
- unsigned nodeid)
-{
- struct bus *link;
- resource_t rbase, rend;
- unsigned reg, link_num;
- char buf[50];
-
- /* Make certain the resource has actually been set */
- if (!(resource->flags & IORESOURCE_ASSIGNED)) {
- printk(BIOS_ERR, "%s: can't set unassigned resource @%lx %lx\n",
- __func__, resource->index, resource->flags);
- return;
- }
-
- /* If I have already stored this resource don't worry about it */
- if (resource->flags & IORESOURCE_STORED) {
- printk(BIOS_ERR, "%s: can't set stored resource @%lx %lx\n", __func__,
- resource->index, resource->flags);
- return;
- }
-
- /* Only handle PCI memory and IO resources */
- if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- return;
-
- /* Ensure I am actually looking at a resource of function 1 */
- if (resource->index < 0x100) {
- return;
- }
-
- if (resource->size == 0)
- return;
-
- /* Get the base address */
- rbase = resource->base;
-
- /* Get the limit (rounded up) */
- rend = resource_end(resource);
-
- /* Get the register and link */
- reg = resource->index & 0xfc;
- link_num = IOINDEX_LINK(resource->index);
-
- for (link = dev->link_list; link; link = link->next)
- if (link->link_num == link_num)
- break;
-
- if (link == NULL) {
- printk(BIOS_ERR, "%s: can't find link %x for %lx\n", __func__,
- link_num, resource->index);
- return;
- }
-
- if (resource->flags & IORESOURCE_IO) {
- u32 base, limit;
- base = f1_read_config32(reg);
- limit = f1_read_config32(reg + 0x4);
- base &= 0xfe000fcc;
- base |= rbase & 0x01fff000;
- base |= 3;
- limit &= 0xfe000fc8;
- limit |= rend & 0x01fff000;
- limit |= (link_num & 3) << 4;
- limit |= (nodeid & 7);
-
- if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
- printk(BIOS_SPEW, "%s, enabling legacy VGA IO forwarding for %s link 0x%x\n",
- __func__, dev_path(dev), link_num);
- base |= PCI_IO_BASE_VGA_EN;
- }
- if (link->bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
- base |= PCI_IO_BASE_NO_ISA;
- }
-
- f1_write_config32(reg + 0x4, limit);
- f1_write_config32(reg, base);
- }
- else if (resource->flags & IORESOURCE_MEM) {
- u32 base, limit;
- base = f1_read_config32(reg);
- limit = f1_read_config32(reg + 0x4);
- base &= 0x000000f0;
- base |= (rbase >> 8) & 0xffffff00;
- base |= 3;
- limit &= 0x00000048;
- limit |= (rend >> 8) & 0xffffff00;
- limit |= (link_num & 3) << 4;
- limit |= (nodeid & 7);
- f1_write_config32(reg + 0x4, limit);
- f1_write_config32(reg, base);
- }
- resource->flags |= IORESOURCE_STORED;
- snprintf(buf, sizeof(buf), " <node %x link %x>",
- nodeid, link_num);
- report_resource_stored(dev, resource, buf);
-}
-
-static void amdk8_create_vga_resource(struct device *dev, unsigned nodeid)
-{
- struct resource *resource;
- struct bus *link;
-
- /* find out which link the VGA card is connected,
- * we only deal with the 'first' vga card */
- for (link = dev->link_list; link; link = link->next) {
- if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
-#if IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)
- extern struct device *vga_pri; // the primary vga device, defined in device.c
- printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d link bus range [%d,%d]\n", vga_pri->bus->secondary,
- link->secondary,link->subordinate);
- /* We need to make sure the vga_pri is under the link */
- if ((vga_pri->bus->secondary >= link->secondary) &&
- (vga_pri->bus->secondary <= link->subordinate)
- )
-#endif
- break;
- }
- }
-
- /* no VGA card installed */
- if (link == NULL)
- return;
-
- printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link->link_num);
-
- /* allocate a temp resource for the legacy VGA buffer */
- resource = new_resource(dev, IOINDEX(4, link->link_num));
- if (!resource) {
- printk(BIOS_DEBUG, "VGA: %s out of resources.\n", dev_path(dev));
- return;
- }
- resource->base = 0xa0000;
- resource->size = 0x20000;
- resource->limit = 0xffffffff;
- resource->flags = IORESOURCE_FIXED | IORESOURCE_MEM |
- IORESOURCE_ASSIGNED;
-}
-
-static void amdk8_set_resources(struct device *dev)
-{
- unsigned nodeid;
- struct bus *bus;
- struct resource *res;
-
- /* Find the nodeid */
- nodeid = amdk8_nodeid(dev);
-
- /* Set each resource we have found */
- for (res = dev->resource_list; res; res = res->next) {
- struct resource *old = NULL;
- unsigned index;
-
- if (res->size == 0) /* No need to allocate registers. */
- continue;
-
- if (res->flags & IORESOURCE_IO)
- index = amdk8_find_iopair(dev, nodeid,
- IOINDEX_LINK(res->index));
- else
- index = amdk8_find_mempair(dev, nodeid,
- IOINDEX_LINK(res->index));
-
- old = probe_resource(dev, index);
- if (old) {
- res->index = old->index;
- old->index = 0;
- old->flags = 0;
- }
- else
- res->index = index;
-
- amdk8_set_resource(dev, res, nodeid);
- }
-
- compact_resources(dev);
-
- for (bus = dev->link_list; bus; bus = bus->next) {
- if (bus->children) {
- assign_resources(bus);
- }
- }
-}
-
-static void mcf0_control_init(struct device *dev)
-{
-}
-
-static struct device_operations northbridge_operations = {
- .read_resources = amdk8_read_resources,
- .set_resources = amdk8_set_resources,
- .enable_resources = pci_dev_enable_resources,
-#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
- .acpi_fill_ssdt_generator = k8acpi_write_vars,
- .write_acpi_tables = northbridge_write_acpi_tables,
-#endif
- .init = mcf0_control_init,
- .scan_bus = amdk8_scan_chains,
- .enable = 0,
- .ops_pci = 0,
-};
-
-
-static const struct pci_driver mcf0_driver __pci_driver = {
- .ops = &northbridge_operations,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x1100,
-};
-
-static void amdk8_nb_init(void *chip_info)
-{
- relocate_sb_ht_chain();
-}
-
-struct chip_operations northbridge_amd_amdk8_ops = {
- CHIP_NAME("AMD K8 Northbridge")
- .enable_dev = 0,
- .init = amdk8_nb_init,
-};
-
-static void amdk8_domain_read_resources(struct device *dev)
-{
- unsigned reg;
-
- /* Find the already assigned resource pairs */
- get_fx_devs();
- for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
- u32 base, limit;
- base = f1_read_config32(reg);
- limit = f1_read_config32(reg + 0x04);
- /* Is this register allocated? */
- if ((base & 3) != 0) {
- unsigned nodeid, reg_link;
- struct device *reg_dev;
- nodeid = limit & 7;
- reg_link = (limit >> 4) & 3;
- reg_dev = __f0_dev[nodeid];
- if (reg_dev) {
- /* Reserve the resource */
- struct resource *res;
- res = new_resource(reg_dev, IOINDEX(0x100 + reg, reg_link));
- if (res) {
- res->base = base;
- res->limit = limit;
- res->flags = 1;
- }
- }
- }
- }
-
- pci_domain_read_resources(dev);
-}
-
-static void my_tolm_test(void *gp, struct device *dev, struct resource *new)
-{
- struct resource **best_p = gp;
- struct resource *best;
- best = *best_p;
- /* Skip VGA. */
- if (!best || (best->base > new->base && new->base > 0xa0000)) {
- best = new;
- }
- *best_p = best;
-}
-
-static u32 my_find_pci_tolm(struct bus *bus)
-{
- struct resource *min;
- u32 tolm;
- min = 0;
- search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, my_tolm_test, &min);
- tolm = 0xffffffffUL;
- if (min && tolm > min->base) {
- tolm = min->base;
- }
- return tolm;
-}
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
-
-struct hw_mem_hole_info {
- unsigned hole_startk;
- int node_id;
-};
-
-static struct hw_mem_hole_info get_hw_mem_hole_info(void)
-{
- struct hw_mem_hole_info mem_hole;
- int i;
-
- mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
- mem_hole.node_id = -1;
-
- for (i = 0; i < fx_devs; i++) {
- u32 base;
- u32 hole;
- base = f1_read_config32(0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
-
- hole = pci_read_config32(__f1_dev[i], 0xf0);
- if (hole & 1) { // we find the hole
- mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
- mem_hole.node_id = i; // record the node No with hole
- break; // only one hole
- }
- }
-
- /* We need to double check if there is special set on base reg and limit reg
- * are not continuous instead of hole, it will find out its hole_startk.
- */
- if (mem_hole.node_id==-1) {
- u32 limitk_pri = 0;
- for (i = 0; i < 8; i++) {
- u32 base, limit;
- unsigned base_k, limit_k;
- base = f1_read_config32(0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
-
- base_k = (base & 0xffff0000) >> 2;
- if (limitk_pri != base_k) { // we find the hole
- mem_hole.hole_startk = limitk_pri;
- mem_hole.node_id = i;
- break; //only one hole
- }
-
- limit = f1_read_config32(0x44 + (i << 3));
- limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
- limitk_pri = limit_k;
- }
- }
- return mem_hole;
-}
-
-static void disable_hoist_memory(unsigned long hole_startk, int node_id)
-{
- int i;
- struct device *dev;
- u32 base, limit;
- u32 hoist;
- u32 hole_sizek;
-
-
- //1. find which node has hole
- //2. change limit in that node.
- //3. change base and limit in later node
- //4. clear that node f0
-
- //if there is not mem hole enabled, we need to change it's base instead
-
- hole_sizek = (4*1024*1024) - hole_startk;
-
- for (i = 7; i > node_id; i--) {
-
- base = f1_read_config32(0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- limit = f1_read_config32(0x44 + (i << 3));
- f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
- f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
- }
- limit = f1_read_config32(0x44 + (node_id << 3));
- f1_write_config32(0x44 + (node_id << 3),limit - (hole_sizek << 2));
- dev = __f1_dev[node_id];
- if (dev == NULL) {
- printk(BIOS_ERR, "%s: node %x is NULL!\n", __func__, node_id);
- return;
- }
- hoist = pci_read_config32(dev, 0xf0);
- if (hoist & 1) {
- pci_write_config32(dev, 0xf0, 0);
- } else {
- base = pci_read_config32(dev, 0x40 + (node_id << 3));
- f1_write_config32(0x40 + (node_id << 3),base - (hole_sizek << 2));
- }
-}
-
-static u32 hoist_memory(unsigned long hole_startk, int node_id)
-{
- int i;
- u32 carry_over;
- struct device *dev;
- u32 base, limit;
- u32 basek;
- u32 hoist;
-
- carry_over = (4*1024*1024) - hole_startk;
-
- for (i = 7; i > node_id; i--) {
-
- base = f1_read_config32(0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- limit = f1_read_config32(0x44 + (i << 3));
- f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
- f1_write_config32(0x40 + (i << 3),base + (carry_over << 2));
- }
- limit = f1_read_config32(0x44 + (node_id << 3));
- f1_write_config32(0x44 + (node_id << 3),limit + (carry_over << 2));
- dev = __f1_dev[node_id];
- base = pci_read_config32(dev, 0x40 + (node_id << 3));
- basek = (base & 0xffff0000) >> 2;
- if (basek == hole_startk) {
- //don't need set memhole here, because hole off set will be 0, overflow
- //so need to change base reg instead, new basek will be 4*1024*1024
- base &= 0x0000ffff;
- base |= (4*1024*1024)<<2;
- f1_write_config32(0x40 + (node_id<<3), base);
- }
- else if (dev)
- {
- hoist = /* hole start address */
- ((hole_startk << 10) & 0xff000000) +
- /* hole address to memory controller address */
- (((basek + carry_over) >> 6) & 0x0000ff00) +
- /* enable */
- 1;
-
- pci_write_config32(dev, 0xf0, hoist);
- }
-
- return carry_over;
-}
-#endif
-
-#include <cbmem.h>
-
-static void setup_uma_memory(void)
-{
-#if IS_ENABLED(CONFIG_GFXUMA)
- uint32_t topmem = (uint32_t) bsp_topmem();
-
- switch (topmem) {
- case 0x10000000: /* 256M system memory */
- uma_memory_size = 0x2000000; /* 32M recommended UMA */
- break;
-
- case 0x18000000: /* 384M system memory */
- uma_memory_size = 0x4000000; /* 64M recommended UMA */
- break;
-
- case 0x20000000: /* 512M system memory */
- uma_memory_size = 0x4000000; /* 64M recommended UMA */
- break;
-
- default: /* 1GB and above system memory */
- uma_memory_size = 0x8000000; /* 128M recommended UMA */
- break;
- }
-
- uma_memory_base = topmem - uma_memory_size; /* TOP_MEM1 */
- printk(BIOS_INFO, "%s: uma size 0x%08llx, memory start 0x%08llx\n",
- __func__, uma_memory_size, uma_memory_base);
-#endif
-}
-
-static void amdk8_domain_set_resources(struct device *dev)
-{
- unsigned long mmio_basek;
- u32 pci_tolm;
- u64 ramtop = 0;
- int i, idx;
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- struct hw_mem_hole_info mem_hole;
- u32 reset_memhole = 1;
-#endif
-
- pci_tolm = my_find_pci_tolm(dev->link_list);
-
- // FIXME handle interleaved nodes. If you fix this here, please fix
- // amdfam10, too.
- mmio_basek = pci_tolm >> 10;
- /* Round mmio_basek to something the processor can support */
- mmio_basek &= ~((1 << 6) -1);
-
- // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
- // MMIO hole. If you fix this here, please fix amdfam10, too.
- /* Round the mmio hole to 64M */
- mmio_basek &= ~((64*1024) - 1);
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- /* if the hw mem hole is already set in raminit stage, here we will compare mmio_basek and hole_basek
- * if mmio_basek is bigger that hole_basek and will use hole_basek as mmio_basek and we don't need to reset hole.
- * otherwise We reset the hole to the mmio_basek
- */
- #if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (!is_cpu_pre_e0()) {
- #endif
-
- mem_hole = get_hw_mem_hole_info();
-
- if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) { //We will use hole_basek as mmio_basek, and we don't need to reset hole anymore
- mmio_basek = mem_hole.hole_startk;
- reset_memhole = 0;
- }
-
- if (reset_memhole) {
- if (mem_hole.node_id!=-1) { // We need to select CONFIG_HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too....!
- // We need to reset our Mem Hole, because We want more big HOLE than we already set
- //Before that We need to disable mem hole at first, becase memhole could already be set on i+1 instead
- disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
- }
-
- #if IS_ENABLED(CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC)
- //We need to double check if the mmio_basek is valid for hole setting, if it is equal to basek, we need to decrease it some
- u32 basek_pri;
- for (i = 0; i < fx_devs; i++) {
- u32 base;
- u32 basek;
- base = f1_read_config32(0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
-
- basek = (base & 0xffff0000) >> 2;
- if (mmio_basek == basek) {
- mmio_basek -= (basek - basek_pri)>>1; // increase mem hole size to make sure it is on middle of pri node
- break;
- }
- basek_pri = basek;
- }
- #endif
- }
-
-#if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- } // is_cpu_pre_e0
-#endif
-
-#endif
-
- idx = 0x10;
- for (i = 0; i < fx_devs; i++) {
- u32 base, limit;
- u32 basek, limitk, sizek;
- base = f1_read_config32(0x40 + (i << 3));
- limit = f1_read_config32(0x44 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- basek = (base & 0xffff0000) >> 2;
- limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
- sizek = limitk - basek;
-
- /* see if we need a hole from 0xa0000 to 0xbffff */
- if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
- ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
- idx += 0x10;
- basek = (8*64)+(16*16);
- sizek = limitk - ((8*64)+(16*16));
-
- }
-
-
-#if IS_ENABLED(CONFIG_GFXUMA)
- printk(BIOS_DEBUG, "node %d : uma_memory_base/1024=0x%08llx, mmio_basek=0x%08lx, basek=0x%08x, limitk=0x%08x\n", i, uma_memory_base >> 10, mmio_basek, basek, limitk);
- if ((uma_memory_base >> 10) < mmio_basek)
- printk(BIOS_ALERT, "node %d: UMA memory starts below mmio_basek\n", i);
-#endif
-
- /* See if I need to split the region to accommodate pci memory space */
- if ((basek < 4*1024*1024) && (limitk > mmio_basek)) {
- if (basek <= mmio_basek) {
- unsigned pre_sizek;
- pre_sizek = mmio_basek - basek;
- if (pre_sizek > 0) {
- ram_resource(dev, (idx | i), basek, pre_sizek);
- idx += 0x10;
- sizek -= pre_sizek;
- if (!ramtop)
- ramtop = mmio_basek * 1024;
- }
- #if CONFIG_HW_MEM_HOLE_SIZEK != 0
- if (reset_memhole)
- #if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- if (!is_cpu_pre_e0())
- #endif
- sizek += hoist_memory(mmio_basek,i);
- #endif
-
- basek = mmio_basek;
- }
- if ((basek + sizek) <= 4*1024*1024) {
- sizek = 0;
- }
- else {
- basek = 4*1024*1024;
- sizek -= (4*1024*1024 - mmio_basek);
- }
- }
-
- ram_resource(dev, (idx | i), basek, sizek);
- idx += 0x10;
- printk(BIOS_DEBUG, "%d: mmio_basek=%08lx, basek=%08x, limitk=%08x\n",
- i, mmio_basek, basek, limitk);
- if (!ramtop)
- ramtop = limitk * 1024;
- }
-
-#if IS_ENABLED(CONFIG_GFXUMA)
- set_late_cbmem_top(uma_memory_base);
- uma_resource(dev, 7, uma_memory_base >> 10, uma_memory_size >> 10);
-#else
- set_late_cbmem_top(ramtop);
-#endif
- assign_resources(dev->link_list);
-
-}
-
-static void amdk8_domain_scan_bus(struct device *dev)
-{
- u32 reg;
- int i;
- struct bus *link = dev->link_list;
-
- /* Unmap all of the HT chains */
- for (reg = 0xe0; reg <= 0xec; reg += 4) {
- f1_write_config32(reg, 0);
- }
-
- link->secondary = dev->bus->subordinate;
- pci_scan_bus(link, PCI_DEVFN(0x18, 0), 0xff);
- dev->bus->subordinate = link->subordinate;
-
- /* Tune the hypertransport transaction for best performance.
- * Including enabling relaxed ordering if it is safe.
- */
- get_fx_devs();
- for (i = 0; i < fx_devs; i++) {
- struct device *f0_dev;
- f0_dev = __f0_dev[i];
- if (f0_dev && f0_dev->enabled) {
- u32 httc;
- httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
- httc &= ~HTTC_RSP_PASS_PW;
- if (!dev->link_list->disable_relaxed_ordering) {
- httc |= HTTC_RSP_PASS_PW;
- }
- printk(BIOS_SPEW, "%s passpw: %s\n",
- dev_path(dev),
- (!dev->link_list->disable_relaxed_ordering)?
- "enabled":"disabled");
- pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
- }
- }
-}
-
-static struct device_operations pci_domain_ops = {
- .read_resources = amdk8_domain_read_resources,
- .set_resources = amdk8_domain_set_resources,
- .enable_resources = NULL,
- .init = NULL,
- .scan_bus = amdk8_domain_scan_bus,
-};
-
-static void add_more_links(struct device *dev, unsigned total_links)
-{
- struct bus *link, *last = NULL;
- int link_num = -1;
-
- for (link = dev->link_list; link; link = link->next) {
- if (link_num < link->link_num)
- link_num = link->link_num;
- last = link;
- }
-
- if (last) {
- int links = total_links - (link_num + 1);
- if (links > 0) {
- link = malloc(links*sizeof(*link));
- if (!link)
- die("Couldn't allocate more links!\n");
- memset(link, 0, links*sizeof(*link));
- last->next = link;
- }
- }
- else {
- link = malloc(total_links*sizeof(*link));
- memset(link, 0, total_links*sizeof(*link));
- dev->link_list = link;
- }
-
- for (link_num = link_num + 1; link_num < total_links; link_num++) {
- link->link_num = link_num;
- link->dev = dev;
- link->next = link + 1;
- last = link;
- link = link->next;
- }
- last->next = NULL;
-}
-
-static void remap_bsp_lapic(struct bus *cpu_bus)
-{
- struct device_path cpu_path;
- struct device *cpu;
- u32 bsp_lapic_id = lapicid();
-
- if (bsp_lapic_id) {
- cpu_path.type = DEVICE_PATH_APIC;
- cpu_path.apic.apic_id = 0;
- cpu = find_dev_path(cpu_bus, &cpu_path);
- if (cpu)
- cpu->path.apic.apic_id = bsp_lapic_id;
- }
-}
-
-static void cpu_bus_scan(struct device *dev)
-{
- struct bus *cpu_bus;
- struct device *dev_mc;
- int bsp_apicid;
- int i,j;
- unsigned nb_cfg_54;
- unsigned siblings;
- int e0_later_single_core;
- int disable_siblings;
-
- nb_cfg_54 = 0;
- sysconf.enabled_apic_ext_id = 0;
- sysconf.lift_bsp_apicid = 0;
- siblings = 0;
-
- /* Find the bootstrap processors apicid */
- bsp_apicid = lapicid();
- sysconf.apicid_offset = bsp_apicid;
-
- disable_siblings = !CONFIG_LOGICAL_CPUS;
-#if IS_ENABLED(CONFIG_LOGICAL_CPUS)
- get_option(&disable_siblings, "multi_core");
-#endif
-
- // for pre_e0, nb_cfg_54 can not be set, (when you read it still is 0)
- // How can I get the nb_cfg_54 of every node's nb_cfg_54 in bsp???
- // and differ d0 and e0 single core
- nb_cfg_54 = read_nb_cfg_54();
-
- dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- if (!dev_mc) {
- die("0:18.0 not found?");
- }
-
- sysconf.nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
-
-
- if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
- {
- sysconf.enabled_apic_ext_id = 1;
- if (bsp_apicid == 0) {
- /* bsp apic id is not changed */
- sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET;
- } else
- {
- sysconf.lift_bsp_apicid = 1;
- }
-
- }
-
- /* Find which cpus are present */
- cpu_bus = dev->link_list;
-
- /* Always use the devicetree node with lapic_id 0 for BSP. */
- remap_bsp_lapic(cpu_bus);
-
- for (i = 0; i < sysconf.nodes; i++) {
- struct device *cpu_dev;
-
- /* Find the cpu's pci device */
- cpu_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
- if (!cpu_dev) {
- /* If I am probing things in a weird order
- * ensure all of the cpu's pci devices are found.
- */
- int local_j;
- struct device *dev_f0;
- for (local_j = 0; local_j <= 3; local_j++) {
- cpu_dev = pci_probe_dev(NULL, dev_mc->bus,
- PCI_DEVFN(0x18 + i, local_j));
- }
- /* Ok, We need to set the links for that device.
- * otherwise the device under it will not be scanned
- */
- dev_f0 = dev_find_slot(0, PCI_DEVFN(0x18+i,0));
- if (dev_f0) {
- add_more_links(dev_f0, 3);
- }
- }
-
- e0_later_single_core = 0;
- int enable_node = cpu_dev && cpu_dev->enabled;
- if (enable_node) {
- j = pci_read_config32(cpu_dev, 0xe8);
- j = (j >> 12) & 3; // dev is func 3
- printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(cpu_dev), j);
-
- if (nb_cfg_54) {
- // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4....
- // ----> you can mixed single core e0 and dual core e0 at any sequence
- // That is the typical case
-
- if (j == 0) {
- #if !IS_ENABLED(CONFIG_K8_REV_F_SUPPORT)
- e0_later_single_core = is_e0_later_in_bsp(i); // single core
- #else
- e0_later_single_core = is_cpu_f0_in_bsp(i); // We can read cpuid(1) from Func3
- #endif
- } else {
- e0_later_single_core = 0;
- }
- if (e0_later_single_core) {
- printk(BIOS_DEBUG, "\tFound Rev E or Rev F later single core\n");
-
- j = 1;
- }
-
- if (siblings > j) {
- }
- else {
- siblings = j;
- }
- } else {
- siblings = j;
- }
- }
-
- u32 jj;
- if (e0_later_single_core || disable_siblings) {
- jj = 0;
- } else
- {
- jj = siblings;
- }
-
- for (j = 0; j <= jj; j++) {
- u32 apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
- if (sysconf.enabled_apic_ext_id) {
- if (apic_id != 0 || sysconf.lift_bsp_apicid) {
- apic_id += sysconf.apicid_offset;
- }
- }
-
- struct device *cpu = add_cpu_device(cpu_bus, apic_id,
- enable_node);
- if (cpu)
- amd_cpu_topology(cpu, i, j);
- } //j
- }
-}
-
-static void cpu_bus_init(struct device *dev)
-{
-#if IS_ENABLED(CONFIG_WAIT_BEFORE_CPUS_INIT)
- cpus_ready_for_init();
-#endif
- initialize_cpus(dev->link_list);
-}
-
-static struct device_operations cpu_bus_ops = {
- .read_resources = DEVICE_NOOP,
- .set_resources = DEVICE_NOOP,
- .enable_resources = DEVICE_NOOP,
- .init = cpu_bus_init,
- .scan_bus = cpu_bus_scan,
-};
-
-static void root_complex_enable_dev(struct device *dev)
-{
- static int done = 0;
-
- /* Do not delay UMA setup, as a device on the PCI bus may evaluate
- the global uma_memory variables already in its enable function. */
- if (!done) {
- setup_bsp_ramtop();
- setup_uma_memory();
- done = 1;
- }
-
- /* Set the operations if it is a special bus type */
- if (dev->path.type == DEVICE_PATH_DOMAIN) {
- dev->ops = &pci_domain_ops;
- }
- else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
- dev->ops = &cpu_bus_ops;
- }
-}
-
-struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
- CHIP_NAME("AMD K8 Root Complex")
- .enable_dev = root_complex_enable_dev,
-};
diff --git a/src/northbridge/amd/amdk8/northbridge.h b/src/northbridge/amd/amdk8/northbridge.h
deleted file mode 100644
index 9fe434ac88..0000000000
--- a/src/northbridge/amd/amdk8/northbridge.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef NORTHBRIDGE_AMD_AMDK8_H
-#define NORTHBRIDGE_AMD_AMDK8_H
-
-extern unsigned int amdk8_scan_root_bus(struct device *root, unsigned int max);
-
-#endif /* NORTHBRIDGE_AMD_AMDK8_H */
diff --git a/src/northbridge/amd/amdk8/pre_f.h b/src/northbridge/amd/amdk8/pre_f.h
deleted file mode 100644
index 1d2aaede1f..0000000000
--- a/src/northbridge/amd/amdk8/pre_f.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef AMDK8_PRE_F_H
-#define AMDK8_PRE_F_H
-
-#include <compiler.h>
-
-/* Definitions of various K8 registers */
-/* Function 0 */
-#define HT_TRANSACTION_CONTROL 0x68
-#define HTTC_DIS_RD_B_P (1 << 0)
-#define HTTC_DIS_RD_DW_P (1 << 1)
-#define HTTC_DIS_WR_B_P (1 << 2)
-#define HTTC_DIS_WR_DW_P (1 << 3)
-#define HTTC_DIS_MTS (1 << 4)
-#define HTTC_CPU1_EN (1 << 5)
-#define HTTC_CPU_REQ_PASS_PW (1 << 6)
-#define HTTC_CPU_RD_RSP_PASS_PW (1 << 7)
-#define HTTC_DIS_P_MEM_C (1 << 8)
-#define HTTC_DIS_RMT_MEM_C (1 << 9)
-#define HTTC_DIS_FILL_P (1 << 10)
-#define HTTC_RSP_PASS_PW (1 << 11)
-#define HTTC_CHG_ISOC_TO_ORD (1 << 12)
-#define HTTC_BUF_REL_PRI_SHIFT 13
-#define HTTC_BUF_REL_PRI_MASK 3
-#define HTTC_BUF_REL_PRI_64 0
-#define HTTC_BUF_REL_PRI_16 1
-#define HTTC_BUF_REL_PRI_8 2
-#define HTTC_BUF_REL_PRI_2 3
-#define HTTC_LIMIT_CLDT_CFG (1 << 15)
-#define HTTC_LINT_EN (1 << 16)
-#define HTTC_APIC_EXT_BRD_CST (1 << 17)
-#define HTTC_APIC_EXT_ID (1 << 18)
-#define HTTC_APIC_EXT_SPUR (1 << 19)
-#define HTTC_SEQ_ID_SRC_NODE_EN (1 << 20)
-#define HTTC_DS_NP_REQ_LIMIT_SHIFT 21
-#define HTTC_DS_NP_REQ_LIMIT_MASK 3
-#define HTTC_DS_NP_REQ_LIMIT_NONE 0
-#define HTTC_DS_NP_REQ_LIMIT_1 1
-#define HTTC_DS_NP_REQ_LIMIT_4 2
-#define HTTC_DS_NP_REQ_LIMIT_8 3
-#define HTTC_MED_PRI_BYP_CNT_SHIFT 24
-#define HTTC_MED_PRI_BYP_CNT_MASK 3
-#define HTTC_HI_PRI_BYP_CNT_SHIFT 26
-#define HTTC_HI_PRI_BYP_CNT_MASK 3
-
-
-/* Function 1 */
-#define PCI_IO_BASE0 0xc0
-#define PCI_IO_BASE1 0xc8
-#define PCI_IO_BASE2 0xd0
-#define PCI_IO_BASE3 0xd8
-#define PCI_IO_BASE_VGA_EN (1 << 4)
-#define PCI_IO_BASE_NO_ISA (1 << 5)
-
-
-/* Function 2 */
-#define DRAM_CSBASE 0x40
-#define DRAM_CSMASK 0x60
-#define DRAM_BANK_ADDR_MAP 0x80
-
-#define DRAM_TIMING_LOW 0x88
-#define DTL_TCL_SHIFT 0
-#define DTL_TCL_MASK 0x7
-#define DTL_CL_2 1
-#define DTL_CL_3 2
-#define DTL_CL_2_5 5
-#define DTL_TRC_SHIFT 4
-#define DTL_TRC_MASK 0xf
-#define DTL_TRC_BASE 7
-#define DTL_TRC_MIN 7
-#define DTL_TRC_MAX 22
-#define DTL_TRFC_SHIFT 8
-#define DTL_TRFC_MASK 0xf
-#define DTL_TRFC_BASE 9
-#define DTL_TRFC_MIN 9
-#define DTL_TRFC_MAX 24
-#define DTL_TRCD_SHIFT 12
-#define DTL_TRCD_MASK 0x7
-#define DTL_TRCD_BASE 0
-#define DTL_TRCD_MIN 2
-#define DTL_TRCD_MAX 6
-#define DTL_TRRD_SHIFT 16
-#define DTL_TRRD_MASK 0x7
-#define DTL_TRRD_BASE 0
-#define DTL_TRRD_MIN 2
-#define DTL_TRRD_MAX 4
-#define DTL_TRAS_SHIFT 20
-#define DTL_TRAS_MASK 0xf
-#define DTL_TRAS_BASE 0
-#define DTL_TRAS_MIN 5
-#define DTL_TRAS_MAX 15
-#define DTL_TRP_SHIFT 24
-#define DTL_TRP_MASK 0x7
-#define DTL_TRP_BASE 0
-#define DTL_TRP_MIN 2
-#define DTL_TRP_MAX 6
-#define DTL_TWR_SHIFT 28
-#define DTL_TWR_MASK 0x1
-#define DTL_TWR_BASE 2
-#define DTL_TWR_MIN 2
-#define DTL_TWR_MAX 3
-
-#define DRAM_TIMING_HIGH 0x8c
-#define DTH_TWTR_SHIFT 0
-#define DTH_TWTR_MASK 0x1
-#define DTH_TWTR_BASE 1
-#define DTH_TWTR_MIN 1
-#define DTH_TWTR_MAX 2
-#define DTH_TRWT_SHIFT 4
-#define DTH_TRWT_MASK 0x7
-#define DTH_TRWT_BASE 1
-#define DTH_TRWT_MIN 1
-#define DTH_TRWT_MAX 6
-#define DTH_TREF_SHIFT 8
-#define DTH_TREF_MASK 0x1f
-#define DTH_TREF_100MHZ_4K 0x00
-#define DTH_TREF_133MHZ_4K 0x01
-#define DTH_TREF_166MHZ_4K 0x02
-#define DTH_TREF_200MHZ_4K 0x03
-#define DTH_TREF_100MHZ_8K 0x08
-#define DTH_TREF_133MHZ_8K 0x09
-#define DTH_TREF_166MHZ_8K 0x0A
-#define DTH_TREF_200MHZ_8K 0x0B
-#define DTH_TWCL_SHIFT 20
-#define DTH_TWCL_MASK 0x7
-#define DTH_TWCL_BASE 1
-#define DTH_TWCL_MIN 1
-#define DTH_TWCL_MAX 2
-
-#define DRAM_CONFIG_LOW 0x90
-#define DCL_DLL_Disable (1<<0)
-#define DCL_D_DRV (1<<1)
-#define DCL_QFC_EN (1<<2)
-#define DCL_DisDqsHys (1<<3)
-#define DCL_Burst2Opt (1<<5)
-#define DCL_DramInit (1<<8)
-#define DCL_DualDIMMen (1<<9)
-#define DCL_DramEnable (1<<10)
-#define DCL_MemClrStatus (1<<11)
-#define DCL_ESR (1<<12)
-#define DCL_SRS (1<<13)
-#define DCL_128BitEn (1<<16)
-#define DCL_DimmEccEn (1<<17)
-#define DCL_UnBuffDimm (1<<18)
-#define DCL_32ByteEn (1<<19)
-#define DCL_x4DIMM_SHIFT 20
-#define DCL_DisInRcvrs (1<<24)
-#define DCL_BypMax_SHIFT 25
-#define DCL_En2T (1<<28)
-#define DCL_UpperCSMap (1<<29)
-
-#define DRAM_CONFIG_HIGH 0x94
-#define DCH_ASYNC_LAT_SHIFT 0
-#define DCH_ASYNC_LAT_MASK 0xf
-#define DCH_ASYNC_LAT_BASE 0
-#define DCH_ASYNC_LAT_MIN 0
-#define DCH_ASYNC_LAT_MAX 15
-#define DCH_RDPREAMBLE_SHIFT 8
-#define DCH_RDPREAMBLE_MASK 0xf
-#define DCH_RDPREAMBLE_BASE ((2<<1)+0) /* 2.0 ns */
-#define DCH_RDPREAMBLE_MIN ((2<<1)+0) /* 2.0 ns */
-#define DCH_RDPREAMBLE_MAX ((9<<1)+1) /* 9.5 ns */
-#define DCH_IDLE_LIMIT_SHIFT 16
-#define DCH_IDLE_LIMIT_MASK 0x7
-#define DCH_IDLE_LIMIT_0 0
-#define DCH_IDLE_LIMIT_4 1
-#define DCH_IDLE_LIMIT_8 2
-#define DCH_IDLE_LIMIT_16 3
-#define DCH_IDLE_LIMIT_32 4
-#define DCH_IDLE_LIMIT_64 5
-#define DCH_IDLE_LIMIT_128 6
-#define DCH_IDLE_LIMIT_256 7
-#define DCH_DYN_IDLE_CTR_EN (1 << 19)
-#define DCH_MEMCLK_SHIFT 20
-#define DCH_MEMCLK_MASK 0x7
-#define DCH_MEMCLK_100MHZ 0
-#define DCH_MEMCLK_133MHZ 2
-#define DCH_MEMCLK_166MHZ 5
-#define DCH_MEMCLK_200MHZ 7
-#define DCH_MEMCLK_VALID (1 << 25)
-#define DCH_MEMCLK_EN0 (1 << 26)
-#define DCH_MEMCLK_EN1 (1 << 27)
-#define DCH_MEMCLK_EN2 (1 << 28)
-#define DCH_MEMCLK_EN3 (1 << 29)
-
-/* Function 3 */
-#define MCA_NB_CONFIG 0x44
-#define MNC_ECC_EN (1 << 22)
-#define MNC_CHIPKILL_EN (1 << 23)
-#define SCRUB_CONTROL 0x58
-#define SCRUB_NONE 0
-#define SCRUB_40ns 1
-#define SCRUB_80ns 2
-#define SCRUB_160ns 3
-#define SCRUB_320ns 4
-#define SCRUB_640ns 5
-#define SCRUB_1_28us 6
-#define SCRUB_2_56us 7
-#define SCRUB_5_12us 8
-#define SCRUB_10_2us 9
-#define SCRUB_20_5us 10
-#define SCRUB_41_0us 11
-#define SCRUB_81_9us 12
-#define SCRUB_163_8us 13
-#define SCRUB_327_7us 14
-#define SCRUB_655_4us 15
-#define SCRUB_1_31ms 16
-#define SCRUB_2_62ms 17
-#define SCRUB_5_24ms 18
-#define SCRUB_10_49ms 19
-#define SCRUB_20_97ms 20
-#define SCRUB_42ms 21
-#define SCRUB_84ms 22
-#define SC_DRAM_SCRUB_RATE_SHFIT 0
-#define SC_DRAM_SCRUB_RATE_MASK 0x1f
-#define SC_L2_SCRUB_RATE_SHIFT 8
-#define SC_L2_SCRUB_RATE_MASK 0x1f
-#define SC_L1D_SCRUB_RATE_SHIFT 16
-#define SC_L1D_SCRUB_RATE_MASK 0x1f
-#define SCRUB_ADDR_LOW 0x5C
-#define SCRUB_ADDR_HIGH 0x60
-#define NORTHBRIDGE_CAP 0xE8
-#define NBCAP_128Bit (1 << 0)
-#define NBCAP_MP (1 << 1)
-#define NBCAP_BIG_MP (1 << 2)
-#define NBCAP_ECC (1 << 3)
-#define NBCAP_CHIPKILL_ECC (1 << 4)
-#define NBCAP_MEMCLK_SHIFT 5
-#define NBCAP_MEMCLK_MASK 3
-#define NBCAP_MEMCLK_100MHZ 3
-#define NBCAP_MEMCLK_133MHZ 2
-#define NBCAP_MEMCLK_166MHZ 1
-#define NBCAP_MEMCLK_200MHZ 0
-#define NBCAP_MEMCTRL (1 << 8)
-
-
-#define LinkConnected (1 << 0)
-#define InitComplete (1 << 1)
-#define NonCoherent (1 << 2)
-#define ConnectionPending (1 << 4)
-
-#include "raminit.h"
-//struct definitions
-
-struct link_pair_st {
- pci_devfn_t udev;
- uint32_t upos;
- uint32_t uoffs;
- pci_devfn_t dev;
- uint32_t pos;
- uint32_t offs;
-
-} __packed;
-
-struct sys_info {
- uint8_t ctrl_present[NODE_NUMS];
- struct mem_controller ctrl[NODE_NUMS];
-
- uint32_t nodes;
- struct link_pair_st link_pair[16];// enough? only in_conherent
- uint32_t link_pair_num;
- uint32_t ht_c_num;
- uint32_t sbdn;
- uint32_t sblk;
- uint32_t sbbusn;
-} __packed;
-
-#ifdef __PRE_RAM__
-#include <arch/early_variables.h>
-extern struct sys_info sysinfo_car;
-#endif
-
-#endif /* AMDK8_PRE_F_H */
diff --git a/src/northbridge/amd/amdk8/raminit.c b/src/northbridge/amd/amdk8/raminit.c
deleted file mode 100644
index ac1fced750..0000000000
--- a/src/northbridge/amd/amdk8/raminit.c
+++ /dev/null
@@ -1,2507 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 2004.11 yhlu add 4 rank DIMM support
- * 2004.12 yhlu add D0 support
- * 2005.02 yhlu add E0 memory hole support
- *
- * 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.
- */
-
-#include <cpu/x86/cache.h>
-#include <cpu/x86/lapic.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-#include <lib.h>
-#include <stdlib.h>
-#include <arch/acpi.h>
-#include <reset.h>
-#include "raminit.h"
-#include "amdk8.h"
-#if IS_ENABLED(CONFIG_HAVE_OPTION_TABLE)
-#include "option_table.h"
-#endif
-
-#include <arch/early_variables.h>
-struct sys_info sysinfo_car CAR_GLOBAL;
-
-void setup_resource_map(const unsigned int *register_values, int max)
-{
- int i;
- for (i = 0; i < max; i += 3) {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg;
- dev = register_values[i] & ~0xfff;
- where = register_values[i] & 0xfff;
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+1];
- reg |= register_values[i+2];
- pci_write_config32(dev, where, reg);
- }
-}
-
-static int controller_present(const struct mem_controller *ctrl)
-{
- return pci_read_config32(ctrl->f0, 0) == 0x11001022;
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void sdram_set_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-#else
-void sdram_set_registers(const struct mem_controller *ctrl)
-#endif
-{
- static const unsigned int register_values[] = {
-
- /* Careful set limit registers before base registers which
- contain the enables */
- /* DRAM Limit i Registers
- * F1:0x44 i = 0
- * F1:0x4C i = 1
- * F1:0x54 i = 2
- * F1:0x5C i = 3
- * F1:0x64 i = 4
- * F1:0x6C i = 5
- * F1:0x74 i = 6
- * F1:0x7C i = 7
- * [ 2: 0] Destination Node ID
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 7: 3] Reserved
- * [10: 8] Interleave select
- * specifies the values of A[14:12] to use with interleave enable.
- * [15:11] Reserved
- * [31:16] DRAM Limit Address i Bits 39-24
- * This field defines the upper address bits of a 40 bit address
- * that define the end of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
- PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
- PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
- PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
- PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
- PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
- PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
- /* DRAM Base i Registers
- * F1:0x40 i = 0
- * F1:0x48 i = 1
- * F1:0x50 i = 2
- * F1:0x58 i = 3
- * F1:0x60 i = 4
- * F1:0x68 i = 5
- * F1:0x70 i = 6
- * F1:0x78 i = 7
- * [ 0: 0] Read Enable
- * 0 = Reads Disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes Disabled
- * 1 = Writes Enabled
- * [ 7: 2] Reserved
- * [10: 8] Interleave Enable
- * 000 = No interleave
- * 001 = Interleave on A[12] (2 nodes)
- * 010 = reserved
- * 011 = Interleave on A[12] and A[14] (4 nodes)
- * 100 = reserved
- * 101 = reserved
- * 110 = reserved
- * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
- * [15:11] Reserved
- * [13:16] DRAM Base Address i Bits 39-24
- * This field defines the upper address bits of a 40-bit address
- * that define the start of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
- /* DRAM CS Base Address i Registers
- * F2:0x40 i = 0
- * F2:0x44 i = 1
- * F2:0x48 i = 2
- * F2:0x4C i = 3
- * F2:0x50 i = 4
- * F2:0x54 i = 5
- * F2:0x58 i = 6
- * F2:0x5C i = 7
- * [ 0: 0] Chip-Select Bank Enable
- * 0 = Bank Disabled
- * 1 = Bank Enabled
- * [ 8: 1] Reserved
- * [15: 9] Base Address (19-13)
- * An optimization used when all DIMM are the same size...
- * [20:16] Reserved
- * [31:21] Base Address (35-25)
- * This field defines the top 11 addresses bit of a 40-bit
- * address that define the memory address space. These
- * bits decode 32-MByte blocks of memory.
- */
- PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x50), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x54), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x58), 0x001f01fe, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x5C), 0x001f01fe, 0x00000000,
- /* DRAM CS Mask Address i Registers
- * F2:0x60 i = 0
- * F2:0x64 i = 1
- * F2:0x68 i = 2
- * F2:0x6C i = 3
- * F2:0x70 i = 4
- * F2:0x74 i = 5
- * F2:0x78 i = 6
- * F2:0x7C i = 7
- * Select bits to exclude from comparison with the DRAM Base address register.
- * [ 8: 0] Reserved
- * [15: 9] Address Mask (19-13)
- * Address to be excluded from the optimized case
- * [20:16] Reserved
- * [29:21] Address Mask (33-25)
- * The bits with an address mask of 1 are excluded from address comparison
- * [31:30] Reserved
- *
- */
- PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x70), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x74), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x78), 0xC01f01ff, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x7C), 0xC01f01ff, 0x00000000,
- /* DRAM Bank Address Mapping Register
- * F2:0x80
- * Specify the memory module size
- * [ 2: 0] CS1/0
- * [ 6: 4] CS3/2
- * [10: 8] CS5/4
- * [14:12] CS7/6
- * 000 = 32Mbyte (Rows = 12 & Col = 8)
- * 001 = 64Mbyte (Rows = 12 & Col = 9)
- * 010 = 128Mbyte (Rows = 13 & Col = 9)|(Rows = 12 & Col = 10)
- * 011 = 256Mbyte (Rows = 13 & Col = 10)|(Rows = 12 & Col = 11)
- * 100 = 512Mbyte (Rows = 13 & Col = 11)|(Rows = 14 & Col = 10)
- * 101 = 1Gbyte (Rows = 14 & Col = 11)|(Rows = 13 & Col = 12)
- * 110 = 2Gbyte (Rows = 14 & Col = 12)
- * 111 = reserved
- * [ 3: 3] Reserved
- * [ 7: 7] Reserved
- * [11:11] Reserved
- * [31:15]
- */
- PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000000,
- /* DRAM Timing Low Register
- * F2:0x88
- * [ 2: 0] Tcl (Cas# Latency, Cas# to read-data-valid)
- * 000 = reserved
- * 001 = CL 2
- * 010 = CL 3
- * 011 = reserved
- * 100 = reserved
- * 101 = CL 2.5
- * 110 = reserved
- * 111 = reserved
- * [ 3: 3] Reserved
- * [ 7: 4] Trc (Row Cycle Time, Ras#-active to Ras#-active/bank auto refresh)
- * 0000 = 7 bus clocks
- * 0001 = 8 bus clocks
- * ...
- * 1110 = 21 bus clocks
- * 1111 = 22 bus clocks
- * [11: 8] Trfc (Row refresh Cycle time, Auto-refresh-active to RAS#-active or RAS#auto-refresh)
- * 0000 = 9 bus clocks
- * 0010 = 10 bus clocks
- * ....
- * 1110 = 23 bus clocks
- * 1111 = 24 bus clocks
- * [14:12] Trcd (Ras#-active to Case#-read/write Delay)
- * 000 = reserved
- * 001 = reserved
- * 010 = 2 bus clocks
- * 011 = 3 bus clocks
- * 100 = 4 bus clocks
- * 101 = 5 bus clocks
- * 110 = 6 bus clocks
- * 111 = reserved
- * [15:15] Reserved
- * [18:16] Trrd (Ras# to Ras# Delay)
- * 000 = reserved
- * 001 = reserved
- * 010 = 2 bus clocks
- * 011 = 3 bus clocks
- * 100 = 4 bus clocks
- * 101 = reserved
- * 110 = reserved
- * 111 = reserved
- * [19:19] Reserved
- * [23:20] Tras (Minmum Ras# Active Time)
- * 0000 to 0100 = reserved
- * 0101 = 5 bus clocks
- * ...
- * 1111 = 15 bus clocks
- * [26:24] Trp (Row Precharge Time)
- * 000 = reserved
- * 001 = reserved
- * 010 = 2 bus clocks
- * 011 = 3 bus clocks
- * 100 = 4 bus clocks
- * 101 = 5 bus clocks
- * 110 = 6 bus clocks
- * 111 = reserved
- * [27:27] Reserved
- * [28:28] Twr (Write Recovery Time)
- * 0 = 2 bus clocks
- * 1 = 3 bus clocks
- * [31:29] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x88), 0xe8088008, 0x02522001 /* 0x03623125 */ ,
- /* DRAM Timing High Register
- * F2:0x8C
- * [ 0: 0] Twtr (Write to Read Delay)
- * 0 = 1 bus Clocks
- * 1 = 2 bus Clocks
- * [ 3: 1] Reserved
- * [ 6: 4] Trwt (Read to Write Delay)
- * 000 = 1 bus clocks
- * 001 = 2 bus clocks
- * 010 = 3 bus clocks
- * 011 = 4 bus clocks
- * 100 = 5 bus clocks
- * 101 = 6 bus clocks
- * 110 = reserved
- * 111 = reserved
- * [ 7: 7] Reserved
- * [12: 8] Tref (Refresh Rate)
- * 00000 = 100MHz 4K rows
- * 00001 = 133MHz 4K rows
- * 00010 = 166MHz 4K rows
- * 00011 = 200MHz 4K rows
- * 01000 = 100MHz 8K/16K rows
- * 01001 = 133MHz 8K/16K rows
- * 01010 = 166MHz 8K/16K rows
- * 01011 = 200MHz 8K/16K rows
- * [19:13] Reserved
- * [22:20] Twcl (Write CAS Latency)
- * 000 = 1 Mem clock after CAS# (Unbuffered Dimms)
- * 001 = 2 Mem clocks after CAS# (Registered Dimms)
- * [31:23] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x8c), 0xff8fe08e, (0 << 20)|(0 << 8)|(0 << 4)|(0 << 0),
- /* DRAM Config Low Register
- * F2:0x90
- * [ 0: 0] DLL Disable
- * 0 = Enabled
- * 1 = Disabled
- * [ 1: 1] D_DRV
- * 0 = Normal Drive
- * 1 = Weak Drive
- * [ 2: 2] QFC_EN
- * 0 = Disabled
- * 1 = Enabled
- * [ 3: 3] Disable DQS Hystersis (FIXME handle this one carefully)
- * 0 = Enable DQS input filter
- * 1 = Disable DQS input filtering
- * [ 7: 4] Reserved
- * [ 8: 8] DRAM_Init
- * 0 = Initialization done or not yet started.
- * 1 = Initiate DRAM intialization sequence
- * [ 9: 9] SO-Dimm Enable
- * 0 = Do nothing
- * 1 = SO-Dimms present
- * [10:10] DramEnable
- * 0 = DRAM not enabled
- * 1 = DRAM initialized and enabled
- * [11:11] Memory Clear Status
- * 0 = Memory Clear function has not completed
- * 1 = Memory Clear function has completed
- * [12:12] Exit Self-Refresh
- * 0 = Exit from self-refresh done or not yet started
- * 1 = DRAM exiting from self refresh
- * [13:13] Self-Refresh Status
- * 0 = Normal Operation
- * 1 = Self-refresh mode active
- * [15:14] Read/Write Queue Bypass Count
- * 00 = 2
- * 01 = 4
- * 10 = 8
- * 11 = 16
- * [16:16] 128-bit/64-Bit
- * 0 = 64bit Interface to DRAM
- * 1 = 128bit Interface to DRAM
- * [17:17] DIMM ECC Enable
- * 0 = Some DIMMs do not have ECC
- * 1 = ALL DIMMS have ECC bits
- * [18:18] UnBuffered DIMMs
- * 0 = Buffered DIMMS
- * 1 = Unbuffered DIMMS
- * [19:19] Enable 32-Byte Granularity
- * 0 = Optimize for 64byte bursts
- * 1 = Optimize for 32byte bursts
- * [20:20] DIMM 0 is x4
- * [21:21] DIMM 1 is x4
- * [22:22] DIMM 2 is x4
- * [23:23] DIMM 3 is x4
- * 0 = DIMM is not x4
- * 1 = x4 DIMM present
- * [24:24] Disable DRAM Receivers
- * 0 = Receivers enabled
- * 1 = Receivers disabled
- * [27:25] Bypass Max
- * 000 = Arbiters chois is always respected
- * 001 = Oldest entry in DCQ can be bypassed 1 time
- * 010 = Oldest entry in DCQ can be bypassed 2 times
- * 011 = Oldest entry in DCQ can be bypassed 3 times
- * 100 = Oldest entry in DCQ can be bypassed 4 times
- * 101 = Oldest entry in DCQ can be bypassed 5 times
- * 110 = Oldest entry in DCQ can be bypassed 6 times
- * 111 = Oldest entry in DCQ can be bypassed 7 times
- * [31:28] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x90), 0xf0000000,
- (4 << 25)|(0 << 24)|
- (0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)|
- (1 << 19)|(0 << 18)|(1 << 17)|(0 << 16)|
- (2 << 14)|(0 << 13)|(0 << 12)|
- (0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)|
- (0 << 3) |(0 << 1) |(0 << 0),
- /* DRAM Config High Register
- * F2:0x94
- * [ 0: 3] Maximum Asynchronous Latency
- * 0000 = 0 ns
- * ...
- * 1111 = 15 ns
- * [ 7: 4] Reserved
- * [11: 8] Read Preamble
- * 0000 = 2.0 ns
- * 0001 = 2.5 ns
- * 0010 = 3.0 ns
- * 0011 = 3.5 ns
- * 0100 = 4.0 ns
- * 0101 = 4.5 ns
- * 0110 = 5.0 ns
- * 0111 = 5.5 ns
- * 1000 = 6.0 ns
- * 1001 = 6.5 ns
- * 1010 = 7.0 ns
- * 1011 = 7.5 ns
- * 1100 = 8.0 ns
- * 1101 = 8.5 ns
- * 1110 = 9.0 ns
- * 1111 = 9.5 ns
- * [15:12] Reserved
- * [18:16] Idle Cycle Limit
- * 000 = 0 cycles
- * 001 = 4 cycles
- * 010 = 8 cycles
- * 011 = 16 cycles
- * 100 = 32 cycles
- * 101 = 64 cycles
- * 110 = 128 cycles
- * 111 = 256 cycles
- * [19:19] Dynamic Idle Cycle Center Enable
- * 0 = Use Idle Cycle Limit
- * 1 = Generate a dynamic Idle cycle limit
- * [22:20] DRAM MEMCLK Frequency
- * 000 = 100MHz
- * 001 = reserved
- * 010 = 133MHz
- * 011 = reserved
- * 100 = reserved
- * 101 = 166MHz
- * 110 = reserved
- * 111 = reserved
- * [24:23] Reserved
- * [25:25] Memory Clock Ratio Valid (FIXME carefully enable memclk)
- * 0 = Disable MemClks
- * 1 = Enable MemClks
- * [26:26] Memory Clock 0 Enable
- * 0 = Disabled
- * 1 = Enabled
- * [27:27] Memory Clock 1 Enable
- * 0 = Disabled
- * 1 = Enabled
- * [28:28] Memory Clock 2 Enable
- * 0 = Disabled
- * 1 = Enabled
- * [29:29] Memory Clock 3 Enable
- * 0 = Disabled
- * 1 = Enabled
- * [31:30] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x94), 0xc180f0f0,
- (0 << 29)|(0 << 28)|(0 << 27)|(0 << 26)|(0 << 25)|
- (0 << 20)|(0 << 19)|(DCH_IDLE_LIMIT_16 << 16)|(0 << 8)|(0 << 0),
- /* DRAM Delay Line Register
- * F2:0x98
- * Adjust the skew of the input DQS strobe relative to DATA
- * [15: 0] Reserved
- * [23:16] Delay Line Adjust
- * Adjusts the DLL derived PDL delay by one or more delay stages
- * in either the faster or slower direction.
- * [24:24} Adjust Slower
- * 0 = Do Nothing
- * 1 = Adj is used to increase the PDL delay
- * [25:25] Adjust Faster
- * 0 = Do Nothing
- * 1 = Adj is used to decrease the PDL delay
- * [31:26] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x98), 0xfc00ffff, 0x00000000,
- /* MCA NB Status Low reg */
- PCI_ADDR(0, 0x18, 3, 0x48), 0x00f00000, 0x00000000,
- /* MCA NB Status high reg */
- PCI_ADDR(0, 0x18, 3, 0x4c), 0x01801e8c, 0x00000000,
- /* MCA NB address Low reg */
- PCI_ADDR(0, 0x18, 3, 0x50), 0x00000007, 0x00000000,
- /* MCA NB address high reg */
- PCI_ADDR(0, 0x18, 3, 0x54), 0xffffff00, 0x00000000,
- /* DRAM Scrub Control Register
- * F3:0x58
- * [ 4: 0] DRAM Scrube Rate
- * [ 7: 5] reserved
- * [12: 8] L2 Scrub Rate
- * [15:13] reserved
- * [20:16] Dcache Scrub
- * [31:21] reserved
- * Scrub Rates
- * 00000 = Do not scrub
- * 00001 = 40.00 ns
- * 00010 = 80.00 ns
- * 00011 = 160.00 ns
- * 00100 = 320.00 ns
- * 00101 = 640.00 ns
- * 00110 = 1.28 us
- * 00111 = 2.56 us
- * 01000 = 5.12 us
- * 01001 = 10.20 us
- * 01011 = 41.00 us
- * 01100 = 81.90 us
- * 01101 = 163.80 us
- * 01110 = 327.70 us
- * 01111 = 655.40 us
- * 10000 = 1.31 ms
- * 10001 = 2.62 ms
- * 10010 = 5.24 ms
- * 10011 = 10.49 ms
- * 10100 = 20.97 ms
- * 10101 = 42.00 ms
- * 10110 = 84.00 ms
- * All Others = Reserved
- */
- PCI_ADDR(0, 0x18, 3, 0x58), 0xffe0e0e0, 0x00000000,
- /* DRAM Scrub Address Low Register
- * F3:0x5C
- * [ 0: 0] DRAM Scrubber Redirect Enable
- * 0 = Do nothing
- * 1 = Scrubber Corrects errors found in normal operation
- * [ 5: 1] Reserved
- * [31: 6] DRAM Scrub Address 31-6
- */
- PCI_ADDR(0, 0x18, 3, 0x5C), 0x0000003e, 0x00000000,
- /* DRAM Scrub Address High Register
- * F3:0x60
- * [ 7: 0] DRAM Scrubb Address 39-32
- * [31: 8] Reserved
- */
- PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
- };
- int i;
- int max;
-
- if (!controller_present(ctrl)) {
- return;
- }
- printk(BIOS_SPEW, "setting up CPU%02x northbridge registers\n", ctrl->node_id);
- max = ARRAY_SIZE(register_values);
- for (i = 0; i < max; i += 3) {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg;
- dev = (register_values[i] & ~0xfff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
- where = register_values[i] & 0xfff;
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+1];
- reg |= register_values[i+2];
- pci_write_config32(dev, where, reg);
- }
- printk(BIOS_SPEW, "done.\n");
-}
-
-static void hw_enable_ecc(const struct mem_controller *ctrl)
-{
- uint32_t dcl, nbcap;
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_DimmEccEn;
- if (nbcap & NBCAP_ECC) {
- dcl |= DCL_DimmEccEn;
- }
- if (read_option(ECC_memory, 1) == 0) {
- dcl &= ~DCL_DimmEccEn;
- }
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-}
-
-static int is_dual_channel(const struct mem_controller *ctrl)
-{
- uint32_t dcl;
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- return dcl & DCL_128BitEn;
-}
-
-static int is_opteron(const struct mem_controller *ctrl)
-{
- /* Test to see if I am an Opteron. Socket 939 based Athlon64
- * have dual channel capability, too, so we need a better test
- * for Opterons.
- * However, all code uses is_opteron() to find out whether to
- * use dual channel, so if we really check for opteron here, we
- * need to fix up all code using this function, too.
- */
- uint32_t nbcap;
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- return !!(nbcap & NBCAP_128Bit);
-}
-
-static int is_registered(const struct mem_controller *ctrl)
-{
- /* Test to see if we are dealing with registered SDRAM.
- * If we are not registered we are unbuffered.
- * This function must be called after spd_handle_unbuffered_dimms.
- */
- uint32_t dcl;
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- return !(dcl & DCL_UnBuffDimm);
-}
-
-struct dimm_size {
- unsigned long side1;
- unsigned long side2;
- unsigned long rows;
- unsigned long col;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- unsigned long rank;
-#endif
-};
-
-static struct dimm_size spd_get_dimm_size(unsigned device)
-{
- /* Calculate the log base 2 size of a DIMM in bits */
- struct dimm_size sz;
- int value, low;
- sz.side1 = 0;
- sz.side2 = 0;
- sz.rows = 0;
- sz.col = 0;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- sz.rank = 0;
-#endif
-
- /* Note it might be easier to use byte 31 here, it has the DIMM size as
- * a multiple of 4MB. The way we do it now we can size both
- * sides of an assymetric dimm.
- */
- value = spd_read_byte(device, 3); /* rows */
- if (value < 0) goto hw_err;
- if ((value & 0xf) == 0) goto val_err;
- sz.side1 += value & 0xf;
- sz.rows = value & 0xf;
-
- value = spd_read_byte(device, 4); /* columns */
- if (value < 0) goto hw_err;
- if ((value & 0xf) == 0) goto val_err;
- sz.side1 += value & 0xf;
- sz.col = value & 0xf;
-
- value = spd_read_byte(device, 17); /* banks */
- if (value < 0) goto hw_err;
- if ((value & 0xff) == 0) goto val_err;
- sz.side1 += log2(value & 0xff);
-
- /* Get the module data width and convert it to a power of two */
- value = spd_read_byte(device, 7); /* (high byte) */
- if (value < 0) goto hw_err;
- value &= 0xff;
- value <<= 8;
-
- low = spd_read_byte(device, 6); /* (low byte) */
- if (low < 0) goto hw_err;
- value = value | (low & 0xff);
- if ((value != 72) && (value != 64)) goto val_err;
- sz.side1 += log2(value);
-
- /* side 2 */
- value = spd_read_byte(device, 5); /* number of physical banks */
- if (value < 0) goto hw_err;
- if (value == 1) goto out;
- if ((value != 2) && (value != 4)) {
- goto val_err;
- }
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- sz.rank = value;
-#endif
-
- /* Start with the symmetrical case */
- sz.side2 = sz.side1;
-
- value = spd_read_byte(device, 3); /* rows */
- if (value < 0) goto hw_err;
- if ((value & 0xf0) == 0) goto out; /* If symmetrical we are done */
- sz.side2 -= (value & 0x0f); /* Subtract out rows on side 1 */
- sz.side2 += ((value >> 4) & 0x0f); /* Add in rows on side 2 */
-
- value = spd_read_byte(device, 4); /* columns */
- if (value < 0) goto hw_err;
- if ((value & 0xff) == 0) goto val_err;
- sz.side2 -= (value & 0x0f); /* Subtract out columns on side 1 */
- sz.side2 += ((value >> 4) & 0x0f); /* Add in columsn on side 2 */
-
- goto out;
-
- val_err:
- die("Bad SPD value\n");
- /* If an hw_error occurs report that I have no memory */
-hw_err:
- sz.side1 = 0;
- sz.side2 = 0;
- sz.rows = 0;
- sz.col = 0;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- sz.rank = 0;
-#endif
-out:
- return sz;
-}
-
-
-static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
-{
- uint32_t base0, base1;
- uint32_t dch;
-
- if (sz.side1 != sz.side2) {
- sz.side2 = 0;
- }
-
- /* For each base register.
- * Place the dimm size in 32 MB quantities in the bits 31 - 21.
- * The initialize dimm size is in bits.
- * Set the base enable bit0.
- */
-
- base0 = base1 = 0;
-
- /* Make certain side1 of the dimm is at least 32MB */
- if (sz.side1 >= (25 +3)) {
- base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
- }
-
- /* Make certain side2 of the dimm is at least 32MB */
- if (sz.side2 >= (25 + 3)) {
- base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
- }
-
- /* Double the size if we are using dual channel memory */
- if (is_dual_channel(ctrl)) {
- base0 = (base0 << 1) | (base0 & 1);
- base1 = (base1 << 1) | (base1 & 1);
- }
-
- /* Clear the reserved bits */
- base0 &= ~0x001ffffe;
- base1 &= ~0x001ffffe;
-
- /* Set the appropriate DIMM base address register */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz.rank == 4) {
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), base0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), base1);
- }
-#endif
-
- /* Enable the memory clocks for this DIMM */
- if (base0) {
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch |= DCH_MEMCLK_EN0 << index;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz.rank == 4) {
- dch |= DCH_MEMCLK_EN0 << (index + 2);
- }
-#endif
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
- }
-}
-
-static void set_dimm_map(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
-{
- static const unsigned cs_map_aa[] = {
- /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */
- 0, 1, 3, 6, 0,
- 0, 2, 4, 7, 9,
- 0, 0, 5, 8,10,
- };
-
- uint32_t map;
-
- map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
- map &= ~(0xf << (index * 4));
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz.rank == 4) {
- map &= ~(0xf << ((index + 2) * 4));
- }
-#endif
-
-
- /* Make certain side1 of the dimm is at least 32MB */
- if (sz.side1 >= (25 +3)) {
- if (is_cpu_pre_d0()) {
- map |= (sz.side1 - (25 + 3)) << (index *4);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz.rank == 4) {
- map |= (sz.side1 - (25 + 3)) << ((index + 2) * 4);
- }
-#endif
- }
- else {
- map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz.rank == 4) {
- map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << ((index + 2) * 4);
- }
-#endif
- }
- }
-
- pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);
-
-}
-
-static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
-{
- int i;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- struct dimm_size sz;
- if (!(dimm_mask & (1 << i))) {
- continue;
- }
- sz = spd_get_dimm_size(ctrl->channel0[i]);
- if (sz.side1 == 0) {
- return -1; /* Report SPD error */
- }
- set_dimm_size(ctrl, sz, i);
- set_dimm_map (ctrl, sz, i);
- }
- return dimm_mask;
-}
-
-static void route_dram_accesses(const struct mem_controller *ctrl,
- unsigned long base_k, unsigned long limit_k)
-{
- /* Route the addresses to the controller node */
- unsigned node_id;
- unsigned limit;
- unsigned base;
- unsigned index;
- unsigned limit_reg, base_reg;
- pci_devfn_t device;
-
- node_id = ctrl->node_id;
- index = (node_id << 3);
- limit = (limit_k << 2);
- limit &= 0xffff0000;
- limit -= 0x00010000;
- limit |= (0 << 8) | (node_id << 0);
- base = (base_k << 2);
- base &= 0xffff0000;
- base |= (0 << 8) | (1<<1) | (1<<0);
-
- limit_reg = 0x44 + index;
- base_reg = 0x40 + index;
- for (device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device += PCI_DEV(0, 1, 0)) {
- pci_write_config32(device, limit_reg, limit);
- pci_write_config32(device, base_reg, base);
- }
-}
-
-static void set_top_mem(unsigned tom_k, unsigned hole_startk)
-{
- /* Error if I don't have memory */
- if (!tom_k) {
- die("No memory?");
- }
-
- /* Report the amount of memory. */
- printk(BIOS_DEBUG, "RAM end at 0x%08x kB\n", tom_k);
-
- /* Now set top of memory */
- msr_t msr;
- if (tom_k > (4*1024*1024)) {
- printk(BIOS_SPEW, "Handling memory mapped above 4 GB\n");
- printk(BIOS_SPEW, "Upper RAM end at 0x%08x kB\n", tom_k);
- msr.lo = (tom_k & 0x003fffff) << 10;
- msr.hi = (tom_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM2, msr);
- printk(BIOS_SPEW, "Correcting memory amount mapped below 4 GB\n");
- }
-
- /* Leave a 64M hole between TOP_MEM and TOP_MEM2
- * so I can see my ROM chip and other I/O devices.
- */
- if (tom_k >= 0x003f0000) {
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- if (hole_startk != 0) {
- tom_k = hole_startk;
- } else
-#endif
- tom_k = 0x3f0000;
- printk(BIOS_SPEW, "Adjusting lower RAM end\n");
- }
- printk(BIOS_SPEW, "Lower RAM end at 0x%08x kB\n", tom_k);
- msr.lo = (tom_k & 0x003fffff) << 10;
- msr.hi = (tom_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM, msr);
-}
-
-static unsigned long interleave_chip_selects(const struct mem_controller *ctrl)
-{
- /* 35 - 25 */
- static const uint8_t csbase_low_shift[] = {
- /* 32MB */ (13 - 4),
- /* 64MB */ (14 - 4),
- /* 128MB */ (14 - 4),
- /* 256MB */ (15 - 4),
- /* 512MB */ (15 - 4),
- /* 1GB */ (16 - 4),
- /* 2GB */ (16 - 4),
- };
-
- static const uint8_t csbase_low_d0_shift[] = {
- /* 32MB */ (13 - 4),
- /* 64MB */ (14 - 4),
- /* 128MB */ (14 - 4),
- /* 128MB */ (15 - 4),
- /* 256MB */ (15 - 4),
- /* 512MB */ (15 - 4),
- /* 256MB */ (16 - 4),
- /* 512MB */ (16 - 4),
- /* 1GB */ (16 - 4),
- /* 1GB */ (17 - 4),
- /* 2GB */ (17 - 4),
- };
-
- /* cs_base_high is not changed */
-
- uint32_t csbase_inc;
- int chip_selects, index;
- int bits;
- unsigned common_size;
- unsigned common_cs_mode;
- uint32_t csbase, csmask;
-
- /* See if all of the memory chip selects are the same size
- * and if so count them.
- */
- chip_selects = 0;
- common_size = 0;
- common_cs_mode = 0;
- for (index = 0; index < 8; index++) {
- unsigned size;
- unsigned cs_mode;
- uint32_t value;
-
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
- chip_selects++;
- size = value >> 21;
- if (common_size == 0) {
- common_size = size;
- }
- /* The size differed fail */
- if (common_size != size) {
- return 0;
- }
-
- value = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
- cs_mode =(value >> ((index>>1)*4)) & 0xf;
- if (cs_mode == 0) continue;
- if (common_cs_mode == 0) {
- common_cs_mode = cs_mode;
- }
- /* The cs_mode differed fail */
- if (common_cs_mode != cs_mode) {
- return 0;
- }
- }
-
- /* Chip selects can only be interleaved when there is
- * more than one and their is a power of two of them.
- */
- bits = log2(chip_selects);
- if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) {
- return 0;
- }
-
- /* Find the bits of csbase that we need to interleave on */
- if (is_cpu_pre_d0()) {
- csbase_inc = 1 << csbase_low_shift[common_cs_mode];
- if (is_dual_channel(ctrl)) {
- /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */
- if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
- return 0;
- }
- csbase_inc <<=1;
- }
- }
- else {
- csbase_inc = 1 << csbase_low_d0_shift[common_cs_mode];
- if (is_dual_channel(ctrl)) {
- if ((bits == 3) && (common_cs_mode > 8)) {
- return 0;
- }
- csbase_inc <<=1;
- }
- }
-
- /* Compute the initial values for csbase and csbask.
- * In csbase just set the enable bit and the base to zero.
- * In csmask set the mask bits for the size and page level interleave.
- */
- csbase = 0 | 1;
- csmask = (((common_size << bits) - 1) << 21);
- csmask |= 0xfe00 & ~((csbase_inc << bits) - csbase_inc);
- for (index = 0; index < 8; index++) {
- uint32_t value;
-
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (index << 2), csbase);
- pci_write_config32(ctrl->f2, DRAM_CSMASK + (index << 2), csmask);
- csbase += csbase_inc;
- }
-
- printk(BIOS_SPEW, "Interleaved\n");
-
- /* Return the memory size in K */
- return common_size << (15 + bits);
-}
-
-static unsigned long order_chip_selects(const struct mem_controller *ctrl)
-{
- unsigned long tom;
-
- /* Remember which registers we have used in the high 8 bits of tom */
- tom = 0;
- for (;;) {
- /* Find the largest remaining candidate */
- unsigned index, candidate;
- uint32_t csbase, csmask;
- unsigned size;
- csbase = 0;
- candidate = 0;
- for (index = 0; index < 8; index++) {
- uint32_t value;
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
-
- /* Is it greater? */
- if (value <= csbase) {
- continue;
- }
-
- /* Has it already been selected */
- if (tom & (1 << (index + 24))) {
- continue;
- }
- /* I have a new candidate */
- csbase = value;
- candidate = index;
- }
-
- /* See if I have found a new candidate */
- if (csbase == 0) {
- break;
- }
-
- /* Remember the dimm size */
- size = csbase >> 21;
-
- /* Remember I have used this register */
- tom |= (1 << (candidate + 24));
-
- /* Recompute the cs base register value */
- csbase = (tom << 21) | 1;
-
- /* Increment the top of memory */
- tom += size;
-
- /* Compute the memory mask */
- csmask = ((size -1) << 21);
- csmask |= 0xfe00; /* For now don't optimize */
-
- /* Write the new base register */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (candidate << 2), csbase);
- /* Write the new mask register */
- pci_write_config32(ctrl->f2, DRAM_CSMASK + (candidate << 2), csmask);
-
- }
- /* Return the memory size in K */
- return (tom & ~0xff000000) << 15;
-}
-
-static unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
-{
- unsigned node_id;
- unsigned end_k;
- /* Find the last memory address used */
- end_k = 0;
- for (node_id = 0; node_id < max_node_id; node_id++) {
- uint32_t limit, base;
- unsigned index;
- index = node_id << 3;
- base = pci_read_config32(ctrl->f1, 0x40 + index);
- /* Only look at the limit if the base is enabled */
- if ((base & 3) == 3) {
- limit = pci_read_config32(ctrl->f1, 0x44 + index);
- end_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
- }
- }
- return end_k;
-}
-
-static void order_dimms(const struct mem_controller *ctrl)
-{
- unsigned long tom_k, base_k;
-
- if (read_option(interleave_chip_selects, 1) != 0) {
- tom_k = interleave_chip_selects(ctrl);
- } else {
- printk(BIOS_DEBUG, "Interleaving disabled\n");
- tom_k = 0;
- }
-
- if (!tom_k) {
- tom_k = order_chip_selects(ctrl);
- }
-
- /* Compute the memory base address */
- base_k = memory_end_k(ctrl, ctrl->node_id);
- tom_k += base_k;
- route_dram_accesses(ctrl, base_k, tom_k);
- set_top_mem(tom_k, 0);
-}
-
-static long disable_dimm(const struct mem_controller *ctrl, unsigned index, long dimm_mask)
-{
- printk(BIOS_DEBUG, "disabling dimm %02x\n", index);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), 0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), 0);
- dimm_mask &= ~(1 << index);
- return dimm_mask;
-}
-
-static long spd_handle_unbuffered_dimms(const struct mem_controller *ctrl,
- long dimm_mask)
-{
- int i;
- int registered;
- int unbuffered;
- int has_dualch = is_opteron(ctrl);
- uint32_t dcl;
- unbuffered = 0;
- registered = 0;
- for (i = 0; (i < DIMM_SOCKETS); i++) {
- int value;
- if (!(dimm_mask & (1 << i))) {
- continue;
- }
- value = spd_read_byte(ctrl->channel0[i], 21);
- if (value < 0) {
- return -1;
- }
-
- /* Registered dimm ? */
- if (value & (1 << 1)) {
- registered = 1;
- }
- /* Otherwise it must be an unbuffered dimm */
- else {
- unbuffered = 1;
- }
- }
- if (unbuffered && registered) {
- die("Mixed buffered and registered dimms not supported");
- }
-
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_UnBuffDimm;
- if (unbuffered) {
- if ((has_dualch) && (!is_cpu_pre_d0())) {
- dcl |= DCL_UnBuffDimm;
-#if IS_ENABLED(CONFIG_CPU_AMD_SOCKET_939)
- if ((cpuid_eax(1) & 0x30) == 0x30) {
- /* CS[7:4] is copy of CS[3:0], should be set for 939 socket */
- dcl |= DCL_UpperCSMap;
- }
-#endif
- } else {
- dcl |= DCL_UnBuffDimm;
- }
- }
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-
- if (is_registered(ctrl)) {
- printk(BIOS_SPEW, "Registered\n");
- } else {
- printk(BIOS_SPEW, "Unbuffered\n");
- }
-
- return dimm_mask;
-}
-
-static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
-{
- unsigned dimm_mask;
- int i;
- dimm_mask = 0;
- for (i = 0; i < DIMM_SOCKETS; i++) {
- int byte;
- unsigned device;
- device = ctrl->channel0[i];
- if (device) {
- byte = spd_read_byte(ctrl->channel0[i], 2); /* Type */
- if (byte == 7) {
- dimm_mask |= (1 << i);
- }
- }
- device = ctrl->channel1[i];
- if (device) {
- byte = spd_read_byte(ctrl->channel1[i], 2);
- if (byte == 7) {
- dimm_mask |= (1 << (i + DIMM_SOCKETS));
- }
- }
- }
- return dimm_mask;
-}
-
-static long spd_enable_2channels(const struct mem_controller *ctrl, long dimm_mask)
-{
- int i;
- uint32_t nbcap;
- /* SPD addresses to verify are identical */
- static const uint8_t addresses[] = {
- 2, /* Type should be DDR SDRAM */
- 3, /* *Row addresses */
- 4, /* *Column addresses */
- 5, /* *Physical Banks */
- 6, /* *Module Data Width low */
- 7, /* *Module Data Width high */
- 9, /* *Cycle time at highest CAS Latency CL = X */
- 11, /* *SDRAM Type */
- 13, /* *SDRAM Width */
- 17, /* *Logical Banks */
- 18, /* *Supported CAS Latencies */
- 21, /* *SDRAM Module Attributes */
- 23, /* *Cycle time at CAS Latency (CLX - 0.5) */
- 25, /* *Cycle time at CAS Latency (CLX - 1.0) */
- 27, /* *tRP Row precharge time */
- 28, /* *Minimum Row Active to Row Active Delay (tRRD) */
- 29, /* *tRCD RAS to CAS */
- 30, /* *tRAS Activate to Precharge */
- 41, /* *Minimum Active to Active/Auto Refresh Time(Trc) */
- 42, /* *Minimum Auto Refresh Command Time(Trfc) */
- };
- /* If the dimms are not in pairs do not do dual channels */
- if ((dimm_mask & ((1 << DIMM_SOCKETS) - 1)) !=
- ((dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) {
- goto single_channel;
- }
- /* If the CPU is not capable of doing dual channels don't do dual channels */
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- if (!(nbcap & NBCAP_128Bit)) {
- goto single_channel;
- }
- for (i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
- unsigned device0, device1;
- int value0, value1;
- int j;
- /* If I don't have a dimm skip this one */
- if (!(dimm_mask & (1 << i))) {
- continue;
- }
- device0 = ctrl->channel0[i];
- device1 = ctrl->channel1[i];
- for (j = 0; j < ARRAY_SIZE(addresses); j++) {
- unsigned addr;
- addr = addresses[j];
- value0 = spd_read_byte(device0, addr);
- if (value0 < 0) {
- return -1;
- }
- value1 = spd_read_byte(device1, addr);
- if (value1 < 0) {
- return -1;
- }
- if (value0 != value1) {
- goto single_channel;
- }
- }
- }
- printk(BIOS_SPEW, "Enabling dual channel memory\n");
- uint32_t dcl;
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_32ByteEn;
- dcl |= DCL_128BitEn;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- return dimm_mask;
- single_channel:
- dimm_mask &= ~((1 << (DIMM_SOCKETS *2)) - (1 << DIMM_SOCKETS));
- return dimm_mask;
-}
-
-struct mem_param {
- uint8_t cycle_time;
- uint8_t divisor; /* In 1/2 ns increments */
- uint8_t tRC;
- uint8_t tRFC;
- uint32_t dch_memclk;
- uint16_t dch_tref4k, dch_tref8k;
- uint8_t dtl_twr;
- uint8_t dtl_twtr;
- uint8_t dtl_trwt[3][3]; /* first index is CAS_LAT 2/2.5/3 and 128/registered64/64 */
- uint8_t rdpreamble[4]; /* 0 is for registered, 1 for 1-2 DIMMS, 2 and 3 for 3 or 4 unreg dimm slots */
- char name[9];
-};
-
-static const struct mem_param *get_mem_param(int freq)
-{
- static const struct mem_param speed[] = {
- [NBCAP_MEMCLK_100MHZ] = {
- .name = "100MHz",
- .cycle_time = 0xa0,
- .divisor = (10 <<1),
- .tRC = 0x46,
- .tRFC = 0x50,
- .dch_memclk = DCH_MEMCLK_100MHZ << DCH_MEMCLK_SHIFT,
- .dch_tref4k = DTH_TREF_100MHZ_4K,
- .dch_tref8k = DTH_TREF_100MHZ_8K,
- .dtl_twr = 2,
- .dtl_twtr = 1,
- .dtl_trwt = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
- .rdpreamble = { ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0) }
- },
- [NBCAP_MEMCLK_133MHZ] = {
- .name = "133MHz",
- .cycle_time = 0x75,
- .divisor = (7<<1)+1,
- .tRC = 0x41,
- .tRFC = 0x4B,
- .dch_memclk = DCH_MEMCLK_133MHZ << DCH_MEMCLK_SHIFT,
- .dch_tref4k = DTH_TREF_133MHZ_4K,
- .dch_tref8k = DTH_TREF_133MHZ_8K,
- .dtl_twr = 2,
- .dtl_twtr = 1,
- .dtl_trwt = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
- .rdpreamble = { ((8 << 1) + 0), ((7 << 1) + 0), ((7 << 1) + 1), ((7 << 1) + 0) }
- },
- [NBCAP_MEMCLK_166MHZ] = {
- .name = "166MHz",
- .cycle_time = 0x60,
- .divisor = (6<<1),
- .tRC = 0x3C,
- .tRFC = 0x48,
- .dch_memclk = DCH_MEMCLK_166MHZ << DCH_MEMCLK_SHIFT,
- .dch_tref4k = DTH_TREF_166MHZ_4K,
- .dch_tref8k = DTH_TREF_166MHZ_8K,
- .dtl_twr = 3,
- .dtl_twtr = 1,
- .dtl_trwt = { { 3, 2, 3 }, { 3, 3, 4 }, { 4, 3, 4 }},
- .rdpreamble = { ((7 << 1) + 1), ((6 << 1) + 0), ((6 << 1) + 1), ((6 << 1) + 0) }
- },
- [NBCAP_MEMCLK_200MHZ] = {
- .name = "200MHz",
- .cycle_time = 0x50,
- .divisor = (5<<1),
- .tRC = 0x37,
- .tRFC = 0x46,
- .dch_memclk = DCH_MEMCLK_200MHZ << DCH_MEMCLK_SHIFT,
- .dch_tref4k = DTH_TREF_200MHZ_4K,
- .dch_tref8k = DTH_TREF_200MHZ_8K,
- .dtl_twr = 3,
- .dtl_twtr = 2,
- .dtl_trwt = { { 0, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
- .rdpreamble = { ((7 << 1) + 0), ((5 << 1) + 0), ((5 << 1) + 1), ((5 << 1) + 1) }
- }
- };
- const struct mem_param *param;
-
- param = speed + freq;
- printk(BIOS_SPEW, "%s\n", param->name);
- return param;
-}
-
-struct spd_set_memclk_result {
- const struct mem_param *param;
- long dimm_mask;
-};
-
-static int spd_dimm_loading_socket(const struct mem_controller *ctrl, long dimm_mask, int *freq_1t)
-{
-
-#if IS_ENABLED(CONFIG_CPU_AMD_SOCKET_939)
-
-/* + 1 raise so we detect 0 as bad field */
-#define DDR200 (NBCAP_MEMCLK_100MHZ + 1)
-#define DDR333 (NBCAP_MEMCLK_166MHZ + 1)
-#define DDR400 (NBCAP_MEMCLK_200MHZ + 1)
-#define DDR_2T 0x80
-#define DDR_MASK 0x7
-
-#define DDR200_2T (DDR_2T | DDR200)
-#define DDR333_2T (DDR_2T | DDR333)
-#define DDR400_2T (DDR_2T | DDR400)
-
-/*
- Following table comes directly from BKDG (unbuffered DIMM support)
- [Y][X] Y = ch0_0, ch1_0, ch0_1, ch1_1 1 = present 0 = empty
- X uses same layout but 1 means double rank 0 is single rank/empty
-
- Following tables come from BKDG the ch{0_0,1_0,0_1,1_1} maps to
- MEMCS_{1L,1H,2L,2H} in i the PDF. PreE is table 45, and revE table 46.
-*/
-
- static const unsigned char dimm_loading_config_preE[16][16] = {
- [0x8] = {[0x0] = DDR400,[0x8] = DDR400},
- [0x2] = {[0x0] = DDR333,[0x2] = DDR400},
- [0xa] = {[0x0] = DDR400_2T,[0x2] = DDR400_2T,
- [0x8] = DDR400_2T,[0xa] = DDR333_2T},
- [0xc] = {[0x0] = DDR400,[0xc] = DDR400},
- [0x3] = {[0x0] = DDR333,[0x3] = DDR400},
- [0xf] = {[0x0] = DDR400_2T,[0x3] = DDR400_2T,
- [0xc] = DDR400_2T,[0xf] = DDR333_2T},
- };
-
- static const unsigned char dimm_loading_config_revE[16][16] = {
- [0x8] = {[0x0] = DDR400, [0x8] = DDR400},
- [0x2] = {[0x0] = DDR333, [0x2] = DDR400},
- [0x4] = {[0x0] = DDR400, [0x4] = DDR400},
- [0x1] = {[0x0] = DDR333, [0x1] = DDR400},
- [0xa] = {[0x0] = DDR400_2T, [0x2] = DDR400_2T,
- [0x8] = DDR400_2T, [0xa] = DDR333_2T},
- [0x5] = {[0x0] = DDR400_2T, [0x1] = DDR400_2T,
- [0x4] = DDR400_2T, [0x5] = DDR333_2T},
- [0xc] = {[0x0] = DDR400, [0xc] = DDR400, [0x4] = DDR400, [0x8] = DDR400},
- [0x3] = {[0x0] = DDR333, [0x1] = DDR333, [0x2] = DDR333, [0x3] = DDR400},
- [0xe] = {[0x0] = DDR400_2T, [0x4] = DDR400_2T, [0x2] = DDR400_2T,
- [0x6] = DDR400_2T, [0x8] = DDR400_2T, [0xc] = DDR400_2T,
- [0xa] = DDR333_2T, [0xe] = DDR333_2T},
- [0xb] = {[0x0] = DDR333, [0x1] = DDR400_2T, [0x2] = DDR333_2T,
- [0x3] = DDR400_2T, [0x8] = DDR333_2T, [0x9] = DDR400_2T,
- [0xa] = DDR333_2T, [0xb] = DDR333_2T},
- [0xd] = {[0x0] = DDR400_2T, [0x8] = DDR400_2T, [0x1] = DDR400_2T,
- [0x9] = DDR333_2T, [0x4] = DDR400_2T, [0xc] = DDR400_2T,
- [0x5] = DDR333_2T, [0xd] = DDR333_2T},
- [0x7] = {[0x0] = DDR333, [0x2] = DDR400_2T, [0x1] = DDR333_2T,
- [0x3] = DDR400_2T, [0x4] = DDR333_2T, [0x6] = DDR400_2T,
- [0x5] = DDR333_2T, [0x7] = DDR333_2T},
- [0xf] = {[0x0] = DDR400_2T, [0x1] = DDR400_2T, [0x4] = DDR400_2T,
- [0x5] = DDR333_2T, [0x2] = DDR400_2T, [0x3] = DDR400_2T,
- [0x6] = DDR400_2T, [0x7] = DDR333_2T, [0x8] = DDR400_2T,
- [0x9] = DDR400_2T, [0xc] = DDR400_2T, [0xd] = DDR333_2T,
- [0xa] = DDR333_2T, [0xb] = DDR333_2T, [0xe] = DDR333_2T,
- [0xf] = DDR333_2T},
- };
- /*The dpos matches channel positions defined in BKDG and above arrays
- The rpos is bitmask of dual rank dimms in same order as dpos */
- unsigned int dloading = 0, i, rpos = 0, dpos = 0;
- const unsigned char (*dimm_loading_config)[16] = dimm_loading_config_revE;
- int rank;
- uint32_t dcl;
-
- if (is_cpu_pre_e0()) {
- dimm_loading_config = dimm_loading_config_preE;
- }
-
- /* only DIMMS two per channel */
- for (i = 0; i < 2; i++) {
- if ((dimm_mask & (1 << i))) {
- /* read rank channel 0 */
- rank = spd_read_byte(ctrl->channel0[i], 5);
- if (rank < 0) goto hw_error;
- rpos |= (rank == 2) ? (1 << (3 - (i * 2))) : 0;
- dpos |= (1 << (3 - (i * 2)));
- }
-
- if ((dimm_mask & (1 << (i+DIMM_SOCKETS)))) {
- /* read rank channel 1*/
- rank = spd_read_byte(ctrl->channel1[i], 5);
- if (rank < 0) goto hw_error;
- rpos |= (rank == 2) ? (1 << (2 - (i * 2))) : 0;
- dpos |= (1 << (2 - (i * 2)));
- }
- }
- /* now the lookup, decode the max speed DDR400_2T etc */
- dloading = dimm_loading_config[dpos][rpos] & DDR_MASK;
-
-hw_error:
- if (dloading != 0) {
- /* we have valid combination check the restrictions */
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl |= ((dimm_loading_config[dpos][rpos] & DDR_2T) || CONFIG_K8_FORCE_2T_DRAM_TIMING) ? (DCL_En2T) : 0;
- /* Set DuallDimm is second channel is completely empty (revD+) */
- if (((cpuid_eax(1) & 0xfff0f) >= 0x10f00) && ((dpos & 0x5) == 0)) {
- printk(BIOS_DEBUG, "Setting DualDIMMen\n");
- dcl |= DCL_DualDIMMen;
- }
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- return dloading - 1;
- } else {
- /* if we don't find it we se it to DDR400 */
- printk(BIOS_WARNING, "Detected strange DIMM configuration, may not work! (or bug)\n");
- return NBCAP_MEMCLK_200MHZ;
- }
-
-#elif IS_ENABLED(CONFIG_CPU_AMD_SOCKET_754)
-
-#define CFGIDX(DIMM1,DIMM2,DIMM3) ((DIMM3)*9+(DIMM2)*3+(DIMM1))
-
-#define EMPTY 0
-#define X8S_X16 1
-#define X8D 2
-
-#define DDR200 NBCAP_MEMCLK_100MHZ
-#define DDR333 NBCAP_MEMCLK_166MHZ
-#define DDR400 NBCAP_MEMCLK_200MHZ
-
- /* this is table 42 from the BKDG, ignoring footnote 4,
- * with the EMPTY, EMPTY, EMPTY row added */
- static const unsigned char cfgtable[][2] = {
- [CFGIDX(EMPTY, EMPTY, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(X8S_X16, EMPTY, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(EMPTY, X8S_X16, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(EMPTY, EMPTY, X8S_X16 )] = { DDR400, DDR400 },
- [CFGIDX(X8D, EMPTY, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(EMPTY, X8D, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(EMPTY, EMPTY, X8D )] = { DDR400, DDR400 },
- [CFGIDX(X8S_X16, X8S_X16, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(X8S_X16, X8D, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(X8S_X16, EMPTY, X8S_X16 )] = { DDR400, DDR400 },
- [CFGIDX(X8S_X16, EMPTY, X8D )] = { DDR400, DDR400 },
- [CFGIDX(X8D, X8S_X16, EMPTY )] = { DDR400, DDR400 },
- [CFGIDX(X8D, X8D, EMPTY )] = { DDR333, DDR333 },
- [CFGIDX(X8D, EMPTY, X8S_X16 )] = { DDR400, DDR400 },
- [CFGIDX(X8D, EMPTY, X8D )] = { DDR333, DDR333 },
- [CFGIDX(EMPTY, X8S_X16, X8S_X16 )] = { DDR333, DDR400 },
- [CFGIDX(EMPTY, X8S_X16, X8D )] = { DDR200, DDR400 },
- [CFGIDX(EMPTY, X8D, X8S_X16 )] = { DDR200, DDR400 },
- [CFGIDX(EMPTY, X8D, X8D )] = { DDR200, DDR333 },
- [CFGIDX(X8S_X16, X8S_X16, X8S_X16 )] = { DDR333, DDR400 },
- [CFGIDX(X8S_X16, X8S_X16, X8D )] = { DDR200, DDR333 },
- [CFGIDX(X8S_X16, X8D, X8S_X16 )] = { DDR200, DDR333 },
- [CFGIDX(X8S_X16, X8D, X8D )] = { DDR200, DDR333 },
- [CFGIDX(X8D, X8S_X16, X8S_X16 )] = { DDR333, DDR333 },
- [CFGIDX(X8D, X8S_X16, X8D )] = { DDR200, DDR333 },
- [CFGIDX(X8D, X8D, X8S_X16 )] = { DDR200, DDR333 },
- [CFGIDX(X8D, X8D, X8D )] = { DDR200, DDR333 }
- };
-
- int i, rank, width, dimmtypes[3];
- const unsigned char *cfg;
-
- for (i = 0; i < 3; i++) {
- if (dimm_mask & (1 << i)) {
- rank = spd_read_byte(ctrl->channel0[i], 5);
- width = spd_read_byte(ctrl->channel0[i], 13);
- if (rank < 0 || width < 0) die("failed to read SPD");
- width &= 0x7f;
- /* this is my guess as to how the criteria in the table
- * are to be understood:
- */
- dimmtypes[i] = width >= (rank == 1 ? 8 : 16) ? X8S_X16 : X8D;
- } else {
- dimmtypes[i] = EMPTY;
- }
- }
- cfg = cfgtable[CFGIDX(dimmtypes[0], dimmtypes[1], dimmtypes[2])];
- *freq_1t = cfg[0];
- return is_cpu_c0() ? cfg[0] : cfg[1];
-
-#else /* CONFIG_CPU_AMD_SOCKET_* */
-
-/* well, there are socket 940 boards supported which obviously fail to
- * compile with this */
-// #error load dependent memory clock limiting is not implemented for this socket
-
- /* see BKDG 4.1.3--if you just want to test a setup that doesn't
- * require limiting, you may use the following code */
-
- *freq_1t = NBCAP_MEMCLK_200MHZ;
- return NBCAP_MEMCLK_200MHZ;
-
-#endif /* CONFIG_CPU_AMD_SOCKET_* */
-
-}
-
-static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller *ctrl, long dimm_mask)
-{
- struct spd_set_memclk_result result;
- unsigned char cl_at_freq[NBCAP_MEMCLK_MASK + 1];
- int dimm, freq, max_freq_bios, max_freq_dloading, max_freq_1t;
- uint32_t value;
-
- static const uint8_t spd_min_cycle_time_indices[] = { 9, 23, 25 };
- static const unsigned char cycle_time_at_freq[] = {
- [NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */
- [NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */
- [NBCAP_MEMCLK_133MHZ] = 0x75, /* 7.5ns */
- [NBCAP_MEMCLK_100MHZ] = 0xa0, /* 10ns */
- };
-
- /* BEWARE that the constants for frequencies order in reverse of what
- * would be intuitive. 200 MHz has the lowest constant, 100 MHz the
- * highest. Thus, all comparisons and traversal directions having to
- * do with frequencies are/have to be the opposite of what would be
- * intuitive.
- */
-
- /* the CLs supported by the controller: */
- memset(cl_at_freq, 0x1c, sizeof(cl_at_freq));
- memset(cl_at_freq, 0x00,
- (pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP) >>
- NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK);
- max_freq_bios = read_option(max_mem_clock, 0);
- if (max_freq_bios <= NBCAP_MEMCLK_100MHZ)
- memset(cl_at_freq, 0x00, max_freq_bios);
- for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
- int x,i,spd_cls,cl,spd_min_cycle_time;
- unsigned char cl_at_freq_mask[sizeof(cl_at_freq)];
-
- if (!(dimm_mask & (1 << dimm)))
- continue;
- /* Byte 18 for DDR SDRAM is interpreted:
- * bit 0 == CAS Latency = 1.0
- * bit 1 == CAS Latency = 1.5
- * bit 2 == CAS Latency = 2.0
- * bit 3 == CAS Latency = 2.5
- * bit 4 == CAS Latency = 3.0
- * bit 5 == CAS Latency = 3.5
- * bit 6 == CAS Latency = 4.0
- * bit 7 == TBD
- */
- spd_cls = spd_read_byte(ctrl->channel0[dimm], 18);
- if (spd_cls <= 0)
- goto hw_error;
- memset(cl_at_freq_mask, 0x00, sizeof(cl_at_freq_mask));
- for (cl = 1 << log2(spd_cls), i = 0; i < 3; cl >>= 1, i++) {
- if (!(spd_cls & cl))
- continue;
- spd_min_cycle_time = spd_read_byte(ctrl->channel0[dimm],
- spd_min_cycle_time_indices[i]);
- if (spd_min_cycle_time < 0)
- goto hw_error;
- if ((!spd_min_cycle_time) || (spd_min_cycle_time & 0x0f) > 9)
- continue;
- for (x = 0; x < sizeof(cl_at_freq_mask); x++)
- if (cycle_time_at_freq[x] >= spd_min_cycle_time)
- cl_at_freq_mask[x] |= cl;
- }
- for (x = 0; x < sizeof(cl_at_freq_mask); x++)
- cl_at_freq[x] &= cl_at_freq_mask[x];
- }
-
- freq = NBCAP_MEMCLK_200MHZ;
- while (freq < sizeof(cl_at_freq) && !cl_at_freq[freq])
- freq++;
-
- max_freq_dloading = spd_dimm_loading_socket(ctrl, dimm_mask, &max_freq_1t);
- if (max_freq_dloading > freq) {
- printk(BIOS_WARNING, "Memory speed reduced due to signal loading conditions\n");
- freq = max_freq_dloading;
- while (freq < sizeof(cl_at_freq) && !cl_at_freq[freq])
- freq++;
- }
-
- /* if the next lower frequency gives a CL at least one whole cycle
- * shorter, select that (see end of BKDG 4.1.1.1) */
- if (freq < sizeof(cl_at_freq)-1 && cl_at_freq[freq+1] &&
- __ffs(cl_at_freq[freq]) - __ffs(cl_at_freq[freq+1]) >= 2)
- freq++;
-
- if (freq == sizeof(cl_at_freq))
- goto hw_error;
-
-#if IS_ENABLED(CONFIG_CPU_AMD_SOCKET_754)
- if (freq < max_freq_1t || CONFIG_K8_FORCE_2T_DRAM_TIMING) {
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW,
- pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW) | DCL_En2T);
- }
-#endif
-
- result.param = get_mem_param(freq);
-
- /* Update DRAM Config High with our selected memory speed */
- value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- value &= ~(DCH_MEMCLK_MASK << DCH_MEMCLK_SHIFT);
-
- value |= result.param->dch_memclk;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
-
- static const unsigned latencies[] = { DTL_CL_2, DTL_CL_2_5, DTL_CL_3 };
-
- /* Update DRAM Timing Low with our selected cas latency */
- value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- value &= ~(DTL_TCL_MASK << DTL_TCL_SHIFT);
- value |= latencies[__ffs(cl_at_freq[freq]) - 2] << DTL_TCL_SHIFT;
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, value);
-
- result.dimm_mask = dimm_mask;
- return result;
- hw_error:
- result.param = (const struct mem_param *)0;
- result.dimm_mask = -1;
- return result;
-}
-
-
-static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 41);
- if (value < 0) return -1;
- if ((value == 0) || (value == 0xff)) {
- value = param->tRC;
- }
- clocks = CEIL_DIV((value << 1), param->divisor);
- if (clocks < DTL_TRC_MIN) {
- clocks = DTL_TRC_MIN;
- }
- if (clocks > DTL_TRC_MAX) {
- return 0;
- }
-
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRC_SHIFT) & DTL_TRC_MASK) + DTL_TRC_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRC_MASK << DTL_TRC_SHIFT);
- dtl |= ((clocks - DTL_TRC_BASE) << DTL_TRC_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 42);
- if (value < 0) return -1;
- if ((value == 0) || (value == 0xff)) {
- value = param->tRFC;
- }
- clocks = CEIL_DIV((value << 1), param->divisor);
- if (clocks < DTL_TRFC_MIN) {
- clocks = DTL_TRFC_MIN;
- }
- if (clocks > DTL_TRFC_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRFC_SHIFT) & DTL_TRFC_MASK) + DTL_TRFC_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRFC_MASK << DTL_TRFC_SHIFT);
- dtl |= ((clocks - DTL_TRFC_BASE) << DTL_TRFC_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-
-static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 29);
- if (value < 0) return -1;
- clocks = CEIL_DIV(value, (param->divisor << 1));
- if (clocks < DTL_TRCD_MIN) {
- clocks = DTL_TRCD_MIN;
- }
- if (clocks > DTL_TRCD_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRCD_SHIFT) & DTL_TRCD_MASK) + DTL_TRCD_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRCD_MASK << DTL_TRCD_SHIFT);
- dtl |= ((clocks - DTL_TRCD_BASE) << DTL_TRCD_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 28);
- if (value < 0) return -1;
- clocks = CEIL_DIV(value, (param->divisor << 1));
- if (clocks < DTL_TRRD_MIN) {
- clocks = DTL_TRRD_MIN;
- }
- if (clocks > DTL_TRRD_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRRD_SHIFT) & DTL_TRRD_MASK) + DTL_TRRD_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRRD_MASK << DTL_TRRD_SHIFT);
- dtl |= ((clocks - DTL_TRRD_BASE) << DTL_TRRD_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 30);
- if (value < 0) return -1;
- clocks = CEIL_DIV((value << 1), param->divisor);
- if (clocks < DTL_TRAS_MIN) {
- clocks = DTL_TRAS_MIN;
- }
- if (clocks > DTL_TRAS_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRAS_SHIFT) & DTL_TRAS_MASK) + DTL_TRAS_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRAS_MASK << DTL_TRAS_SHIFT);
- dtl |= ((clocks - DTL_TRAS_BASE) << DTL_TRAS_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 27);
- if (value < 0) return -1;
- clocks = CEIL_DIV(value, (param->divisor << 1));
- if (clocks < DTL_TRP_MIN) {
- clocks = DTL_TRP_MIN;
- }
- if (clocks > DTL_TRP_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRP_SHIFT) & DTL_TRP_MASK) + DTL_TRP_BASE;
- if (old_clocks > clocks) {
- clocks = old_clocks;
- }
- dtl &= ~(DTL_TRP_MASK << DTL_TRP_SHIFT);
- dtl |= ((clocks - DTL_TRP_BASE) << DTL_TRP_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static void set_Twr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dtl;
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- dtl &= ~(DTL_TWR_MASK << DTL_TWR_SHIFT);
- dtl |= (param->dtl_twr - DTL_TWR_BASE) << DTL_TWR_SHIFT;
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-}
-
-
-static void init_Tref(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dth;
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
- dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
- dth |= (param->dch_tref4k << DTH_TREF_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- uint32_t dth;
- int value;
- unsigned tref, old_tref;
- value = spd_read_byte(ctrl->channel0[i], 3);
- if (value < 0) return -1;
- value &= 0xf;
-
- tref = param->dch_tref8k;
- if (value == 12) {
- tref = param->dch_tref4k;
- }
-
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
- old_tref = (dth >> DTH_TREF_SHIFT) & DTH_TREF_MASK;
- if ((value == 12) && (old_tref == param->dch_tref4k)) {
- tref = param->dch_tref4k;
- } else {
- tref = param->dch_tref8k;
- }
- dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
- dth |= (tref << DTH_TREF_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
- return 1;
-}
-
-
-static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- uint32_t dcl;
- int value;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- int rank;
-#endif
- int dimm;
- value = spd_read_byte(ctrl->channel0[i], 13);
- if (value < 0) {
- return -1;
- }
-
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- rank = spd_read_byte(ctrl->channel0[i], 5); /* number of physical banks */
- if (rank < 0) {
- return -1;
- }
-#endif
-
- dimm = 1<<(DCL_x4DIMM_SHIFT+i);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (rank == 4) {
- dimm |= 1<<(DCL_x4DIMM_SHIFT+i+2);
- }
-#endif
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~dimm;
- if (value == 4) {
- dcl |= dimm;
- }
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- return 1;
-}
-
-static int update_dimm_ecc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
- uint32_t dcl;
- int value;
- value = spd_read_byte(ctrl->channel0[i], 11);
- if (value < 0) {
- return -1;
- }
- if (value != 2) {
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_DimmEccEn;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- }
- return 1;
-}
-
-static int count_dimms(const struct mem_controller *ctrl)
-{
- int dimms;
- unsigned index;
- dimms = 0;
- for (index = 0; index < 8; index += 2) {
- uint32_t csbase;
- csbase = pci_read_config32(ctrl->f2, (DRAM_CSBASE + (index << 2)));
- if (csbase & 1) {
- dimms += 1;
- }
- }
- return dimms;
-}
-
-static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dth;
-
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
- dth &= ~(DTH_TWTR_MASK << DTH_TWTR_SHIFT);
- dth |= ((param->dtl_twtr - DTH_TWTR_BASE) << DTH_TWTR_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dth, dtl;
- unsigned latency;
- unsigned clocks;
- int lat, mtype;
-
- clocks = 0;
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- latency = (dtl >> DTL_TCL_SHIFT) & DTL_TCL_MASK;
-
- if (is_opteron(ctrl)) {
- mtype = 0; /* dual channel */
- } else if (is_registered(ctrl)) {
- mtype = 1; /* registered 64bit interface */
- } else {
- mtype = 2; /* unbuffered 64bit interface */
- }
-
- switch (latency) {
- case DTL_CL_2:
- lat = 0;
- break;
- case DTL_CL_2_5:
- lat = 1;
- break;
- case DTL_CL_3:
- lat = 2;
- break;
- default:
- die("Unknown LAT for Trwt");
- }
-
- clocks = param->dtl_trwt[lat][mtype];
- if ((clocks < DTH_TRWT_MIN) || (clocks > DTH_TRWT_MAX)) {
- die("Unknown Trwt\n");
- }
-
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
- dth &= ~(DTH_TRWT_MASK << DTH_TRWT_SHIFT);
- dth |= ((clocks - DTH_TRWT_BASE) << DTH_TRWT_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
- return;
-}
-
-static void set_Twcl(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- /* Memory Clocks after CAS# */
- uint32_t dth;
- unsigned clocks;
- if (is_registered(ctrl)) {
- clocks = 2;
- } else {
- clocks = 1;
- }
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
- dth &= ~(DTH_TWCL_MASK << DTH_TWCL_SHIFT);
- dth |= ((clocks - DTH_TWCL_BASE) << DTH_TWCL_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-
-static void set_read_preamble(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dch;
- unsigned rdpreamble;
- int slots, i;
-
- slots = 0;
-
- for (i = 0; i < 4; i++) {
- if (ctrl->channel0[i]) {
- slots += 1;
- }
- }
-
- /* map to index to param.rdpreamble array */
- if (is_registered(ctrl)) {
- i = 0;
- } else if (slots < 3) {
- i = 1;
- } else if (slots == 3) {
- i = 2;
- } else if (slots == 4) {
- i = 3;
- } else {
- die("Unknown rdpreamble for this nr of slots");
- }
-
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch &= ~(DCH_RDPREAMBLE_MASK << DCH_RDPREAMBLE_SHIFT);
- rdpreamble = param->rdpreamble[i];
-
- if ((rdpreamble < DCH_RDPREAMBLE_MIN) || (rdpreamble > DCH_RDPREAMBLE_MAX)) {
- die("Unknown rdpreamble");
- }
-
- dch |= (rdpreamble - DCH_RDPREAMBLE_BASE) << DCH_RDPREAMBLE_SHIFT;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dch;
- unsigned async_lat;
- int dimms;
-
- dimms = count_dimms(ctrl);
-
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch &= ~(DCH_ASYNC_LAT_MASK << DCH_ASYNC_LAT_SHIFT);
- async_lat = 0;
- if (is_registered(ctrl)) {
- if (dimms == 4) {
- /* 9ns */
- async_lat = 9;
- }
- else {
- /* 8ns */
- async_lat = 8;
- }
- }
- else {
- if (dimms > 3) {
- die("Too many unbuffered dimms");
- }
- else if (dimms == 3) {
- /* 7ns */
- async_lat = 7;
- }
- else {
- /* 6ns */
- async_lat = 6;
- }
- }
- dch |= ((async_lat - DCH_ASYNC_LAT_BASE) << DCH_ASYNC_LAT_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_idle_cycle_limit(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dch;
- /* AMD says to Hardcode this */
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch &= ~(DCH_IDLE_LIMIT_MASK << DCH_IDLE_LIMIT_SHIFT);
- dch |= DCH_IDLE_LIMIT_16 << DCH_IDLE_LIMIT_SHIFT;
- dch |= DCH_DYN_IDLE_CTR_EN;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static long spd_set_dram_timing(const struct mem_controller *ctrl, const struct mem_param *param, long dimm_mask)
-{
- int i;
-
- init_Tref(ctrl, param);
- for (i = 0; i < DIMM_SOCKETS; i++) {
- int rc;
- if (!(dimm_mask & (1 << i))) {
- continue;
- }
- /* DRAM Timing Low Register */
- if ((rc = update_dimm_Trc (ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_Trfc(ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_Trcd(ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_Trrd(ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_Tras(ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_Trp (ctrl, param, i)) <= 0) goto dimm_err;
-
- /* DRAM Timing High Register */
- if ((rc = update_dimm_Tref(ctrl, param, i)) <= 0) goto dimm_err;
-
-
- /* DRAM Config Low */
- if ((rc = update_dimm_x4 (ctrl, param, i)) <= 0) goto dimm_err;
- if ((rc = update_dimm_ecc(ctrl, param, i)) <= 0) goto dimm_err;
- continue;
- dimm_err:
- if (rc < 0) {
- return -1;
- }
- dimm_mask = disable_dimm(ctrl, i, dimm_mask);
- }
- /* DRAM Timing Low Register */
- set_Twr(ctrl, param);
-
- /* DRAM Timing High Register */
- set_Twtr(ctrl, param);
- set_Trwt(ctrl, param);
- set_Twcl(ctrl, param);
-
- /* DRAM Config High */
- set_read_preamble(ctrl, param);
- set_max_async_latency(ctrl, param);
- set_idle_cycle_limit(ctrl, param);
- return dimm_mask;
-}
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void sdram_set_spd_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-#else
-void sdram_set_spd_registers(const struct mem_controller *ctrl)
-#endif
-{
- struct spd_set_memclk_result result;
- const struct mem_param *param;
- long dimm_mask;
-#if 1
- if (!controller_present(ctrl)) {
- return;
- }
-#endif
- hw_enable_ecc(ctrl);
- activate_spd_rom(ctrl);
- dimm_mask = spd_detect_dimms(ctrl);
- if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
- printk(BIOS_DEBUG, "No memory for this cpu\n");
- return;
- }
- dimm_mask = spd_enable_2channels(ctrl, dimm_mask);
- if (dimm_mask < 0)
- goto hw_spd_err;
- dimm_mask = spd_set_ram_size(ctrl , dimm_mask);
- if (dimm_mask < 0)
- goto hw_spd_err;
- dimm_mask = spd_handle_unbuffered_dimms(ctrl, dimm_mask);
- if (dimm_mask < 0)
- goto hw_spd_err;
- result = spd_set_memclk(ctrl, dimm_mask);
- param = result.param;
- dimm_mask = result.dimm_mask;
- if (dimm_mask < 0)
- goto hw_spd_err;
- dimm_mask = spd_set_dram_timing(ctrl, param , dimm_mask);
- if (dimm_mask < 0)
- goto hw_spd_err;
- order_dimms(ctrl);
- return;
- hw_spd_err:
- /* Unrecoverable error reading SPD data */
- printk(BIOS_ERR, "SPD error - reset\n");
- hard_reset();
- return;
-}
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
-static uint32_t hoist_memory(int controllers, const struct mem_controller *ctrl,unsigned hole_startk, int i)
-{
- int ii;
- uint32_t carry_over;
- pci_devfn_t dev;
- uint32_t base, limit;
- uint32_t basek;
- uint32_t hoist;
- int j;
-
- carry_over = (4*1024*1024) - hole_startk;
-
- for (ii = controllers - 1; ii > i; ii--) {
- base = pci_read_config32(ctrl[0].f1, 0x40 + (ii << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (ii << 3));
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x44 + (ii << 3), limit + (carry_over << 2));
- pci_write_config32(ctrl[j].f1, 0x40 + (ii << 3), base + (carry_over << 2));
- }
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x44 + (i << 3), limit + (carry_over << 2));
- }
- dev = ctrl[i].f1;
- base = pci_read_config32(dev, 0x40 + (i << 3));
- basek = (base & 0xffff0000) >> 2;
- if (basek == hole_startk) {
- //don't need set memhole here, because hole off set will be 0, overflow
- //so need to change base reg instead, new basek will be 4*1024*1024
- base &= 0x0000ffff;
- base |= (4*1024*1024)<<2;
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x40 + (i<<3), base);
- }
- }
- else {
- hoist = /* hole start address */
- ((hole_startk << 10) & 0xff000000) +
- /* hole address to memory controller address */
- (((basek + carry_over) >> 6) & 0x0000ff00) +
- /* enable */
- 1;
- pci_write_config32(dev, 0xf0, hoist);
- }
-
- return carry_over;
-}
-
-void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl)
-{
-
- uint32_t hole_startk;
- int i;
-
- hole_startk = 4*1024*1024 - CONFIG_HW_MEM_HOLE_SIZEK;
-
- printk(BIOS_SPEW, "Handling memory hole at 0x%08x (default)\n", hole_startk);
-#if IS_ENABLED(CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC)
- /* We need to double check if hole_startk is valid.
- * If it is equal to the dram base address in K (base_k),
- * we need to decrease it.
- */
- uint32_t basek_pri;
- for (i = 0; i < controllers; i++) {
- uint32_t base;
- unsigned base_k;
- base = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- base_k = (base & 0xffff0000) >> 2;
- if (base_k == hole_startk) {
- /* decrease memory hole startk to make sure it is
- * in the middle of the previous node
- */
- hole_startk -= (base_k - basek_pri)>>1;
- break; /* only one hole */
- }
- basek_pri = base_k;
- }
-
- printk(BIOS_SPEW, "Handling memory hole at 0x%08x (adjusted)\n", hole_startk);
-#endif
- /* Find node number that needs the memory hole configured */
- for (i = 0; i < controllers; i++) {
- uint32_t base, limit;
- unsigned base_k, limit_k;
- base = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
- base_k = (base & 0xffff0000) >> 2;
- limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
- if ((base_k <= hole_startk) && (limit_k > hole_startk)) {
- unsigned end_k;
- hoist_memory(controllers, ctrl, hole_startk, i);
- end_k = memory_end_k(ctrl, controllers);
- set_top_mem(end_k, hole_startk);
- break; /* only one hole */
- }
- }
-
-}
-
-#endif
-
-#if IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
-#else
-void sdram_enable(int controllers, const struct mem_controller *ctrl)
-#endif
-{
- int i;
- u32 whatWait = 0;
- int suspend = acpi_is_wakeup_s3();
-
- /* Error if I don't have memory */
- if (memory_end_k(ctrl, controllers) == 0) {
- die("No memory\n");
- }
-
- /* Before enabling memory start the memory clocks */
- for (i = 0; i < controllers; i++) {
- uint32_t dch;
- if (!controller_present(ctrl + i))
- continue;
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
- if (dch & (DCH_MEMCLK_EN0|DCH_MEMCLK_EN1|DCH_MEMCLK_EN2|DCH_MEMCLK_EN3)) {
- dch |= DCH_MEMCLK_VALID;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
- }
- else {
- /* Disable dram receivers */
- uint32_t dcl;
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- dcl |= DCL_DisInRcvrs;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
- }
- }
-
- /* We need to wait a minimum of 20 MEMCLKS to enable the InitDram */
- /* And if necessary toggle the the reset on the dimms by hand */
- memreset(controllers, ctrl);
-
- for (i = 0; i < controllers; i++) {
- uint32_t dcl, dch;
- if (!controller_present(ctrl + i))
- continue;
- /* Skip everything if I don't have any memory on this controller */
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
- if (!(dch & DCH_MEMCLK_VALID)) {
- continue;
- }
-
- /* Toggle DisDqsHys to get it working */
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- if (dcl & DCL_DimmEccEn) {
- uint32_t mnc;
- printk(BIOS_SPEW, "ECC enabled\n");
- mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
- mnc |= MNC_ECC_EN;
- if (dcl & DCL_128BitEn) {
- mnc |= MNC_CHIPKILL_EN;
- }
- pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
- }
-
- 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;
-
- 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);
- }
-
- for (i = 0; i < controllers; i++) {
- uint32_t dcl, dch;
- if (!controller_present(ctrl + i))
- continue;
- /* Skip everything if I don't have any memory on this controller */
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
- if (!(dch & DCH_MEMCLK_VALID)) {
- continue;
- }
-
- printk(BIOS_DEBUG, "Initializing memory: ");
- int loops = 0;
- do {
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- loops++;
- if ((loops & 1023) == 0) {
- printk(BIOS_DEBUG, ".");
- }
- } while (((dcl & whatWait) != 0) && (loops < TIMEOUT_LOOPS));
- if (loops >= TIMEOUT_LOOPS) {
- printk(BIOS_DEBUG, " failed\n");
- continue;
- }
-
- if (!is_cpu_pre_c0()) {
- /* Wait until it is safe to touch memory */
- do {
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- } while (((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) ||
- ((dcl & DCL_SRS)));
- }
-
- printk(BIOS_DEBUG, " done\n");
- }
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- // init hw mem hole here
- /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
- if (!is_cpu_pre_e0())
- set_hw_mem_hole(controllers, ctrl);
-#endif
-
- //FIXME add enable node interleaving here -- yhlu
- /*needed?
- 1. check how many nodes we have , if not all has RAM installed get out
- 2. check cs_base lo is 0, node 0 f2 0x40,,,,, if any one is not using lo is CS_BASE, get out
- 3. check if other node is the same as node 0 about f2 0x40,,,,, otherwise get out
- 4. if all ready enable node_interleaving in f1 0x40..... of every node
- 5. for node interleaving we need to set mem hole to every node (need recalcute hole offset in f0 for every node)
- */
-
-}
-
-void set_sysinfo_in_ram(unsigned val)
-{
-}
-
-void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a,
- const uint16_t *spd_addr)
-{
- int i;
- int j;
- struct mem_controller *ctrl;
- for (i = 0; i < controllers; i++) {
- ctrl = &ctrl_a[i];
- ctrl->node_id = i;
- ctrl->f0 = PCI_DEV(0, 0x18+i, 0);
- ctrl->f1 = PCI_DEV(0, 0x18+i, 1);
- ctrl->f2 = PCI_DEV(0, 0x18+i, 2);
- ctrl->f3 = PCI_DEV(0, 0x18+i, 3);
-
- if (spd_addr == (void *)0) continue;
-
- for (j = 0; j < DIMM_SOCKETS; j++) {
- ctrl->channel0[j] = spd_addr[(i*2+0)*DIMM_SOCKETS + j];
- ctrl->channel1[j] = spd_addr[(i*2+1)*DIMM_SOCKETS + j];
- }
- }
-}
diff --git a/src/northbridge/amd/amdk8/raminit.h b/src/northbridge/amd/amdk8/raminit.h
deleted file mode 100644
index 002c5adbec..0000000000
--- a/src/northbridge/amd/amdk8/raminit.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#ifndef RAMINIT_H
-#define RAMINIT_H
-
-#include <arch/io.h>
-
-#define NODE_ID 0x60
-#define HT_INIT_CONTROL 0x6c
-
-#define NODE_NUMS 8
-
-#define DIMM_SOCKETS 4
-struct mem_controller {
- unsigned node_id;
- pci_devfn_t f0, f1, f2, f3;
- uint16_t channel0[DIMM_SOCKETS];
- uint16_t channel1[DIMM_SOCKETS];
-};
-
-struct sys_info;
-
-void exit_from_self(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo);
-void setup_resource_map(const unsigned int *register_values, int max);
-void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl);
-int spd_read_byte(unsigned device, unsigned address);
-void activate_spd_rom(const struct mem_controller *ctrl);
-void memreset(int controllers, const struct mem_controller *ctrl);
-void set_sysinfo_in_ram(unsigned int val);
-
-#define TIMEOUT_LOOPS 300000
-
-#if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_RAMINIT_SYSINFO)
-void sdram_initialize(int controllers, const struct mem_controller *ctrl, void *sysinfo);
-void sdram_enable(int controllers, const struct mem_controller *ctrl,
- struct sys_info *sysinfo);
-void sdram_set_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo);
-void sdram_set_spd_registers(const struct mem_controller *ctrl,
- struct sys_info *sysinfo);
-void dump_spd_registers(const struct mem_controller *ctrl);
-void dump_smbus_registers(void);
-#else
-void sdram_set_registers(const struct mem_controller *ctrl);
-void sdram_set_spd_registers(const struct mem_controller *ctrl);
-void sdram_enable(int controllers, const struct mem_controller *ctrl);
-void sdram_initialize(int controllers, const struct mem_controller *ctrl);
-#endif
-
-#endif /* RAMINIT_H */
diff --git a/src/northbridge/amd/amdk8/raminit_f.c b/src/northbridge/amd/amdk8/raminit_f.c
deleted file mode 100644
index ba17df28f9..0000000000
--- a/src/northbridge/amd/amdk8/raminit_f.c
+++ /dev/null
@@ -1,3211 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2002 Linux Networx
- * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
- * Copyright (C) 2004 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.
-*/
-
-#include <arch/io.h>
-#include <console/console.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/msr.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/tsc.h>
-#include <cpu/amd/mtrr.h>
-#include <pc80/mc146818rtc.h>
-
-#include <lib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <arch/acpi.h>
-#include "amdk8.h"
-#include "raminit.h"
-#include "f.h"
-#include <spd_ddr2.h>
-#if IS_ENABLED(CONFIG_HAVE_OPTION_TABLE)
-#include "option_table.h"
-#endif
-
-#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
-#define printk_raminit(args...) printk(BIOS_DEBUG, args)
-#else
-#define printk_raminit(args...)
-#endif
-
-#include <arch/early_variables.h>
-struct sys_info sysinfo_car CAR_GLOBAL;
-
-#include "f_pci.c"
-
- /* for PCI_ADDR(0, 0x18, 2, 0x98) index,
- and PCI_ADDR(0x, 0x18, 2, 0x9c) data */
- /*
-index:
- [29: 0] DctOffset (Dram Controller Offset)
- [30:30] DctAccessWrite (Dram Controller Read/Write Select)
- 0 = read access
- 1 = write access
- [31:31] DctAccessDone (Dram Controller Access Done)
- 0 = Access in progress
- 1 = No access is progress
-
- Data:
- [31: 0] DctOffsetData (Dram Controller Offset Data)
-
- Read:
- - Write the register num to DctOffset with
- DctAccessWrite = 0
- - poll the DctAccessDone until it = 1
- - Read the data from DctOffsetData
- Write:
- - Write the data to DctOffsetData
- - Write register num to DctOffset with DctAccessWrite = 1
- - poll the DctAccessDone until it = 1
- */
-
-
-void setup_resource_map(const unsigned int *register_values, int max)
-{
- int i;
- for (i = 0; i < max; i += 3) {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg;
- dev = register_values[i] & ~0xff;
- where = register_values[i] & 0xff;
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+1];
- reg |= register_values[i+2];
- pci_write_config32(dev, where, reg);
- }
-}
-
-static int controller_present(const struct mem_controller *ctrl)
-{
- return pci_read_config32(ctrl->f0, 0) == 0x11001022;
-}
-
-void sdram_set_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
- static const unsigned int register_values[] = {
-
- /* Careful set limit registers before base registers which
- contain the enables */
- /* DRAM Limit i Registers
- * F1:0x44 i = 0
- * F1:0x4C i = 1
- * F1:0x54 i = 2
- * F1:0x5C i = 3
- * F1:0x64 i = 4
- * F1:0x6C i = 5
- * F1:0x74 i = 6
- * F1:0x7C i = 7
- * [ 2: 0] Destination Node ID
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 7: 3] Reserved
- * [10: 8] Interleave select
- * specifies the values of A[14:12] to use with interleave enable.
- * [15:11] Reserved
- * [31:16] DRAM Limit Address i Bits 39-24
- * This field defines the upper address bits of a 40 bit address
- * that define the end of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
- PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
- PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
- PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
- PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
- PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
- PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
- /* DRAM Base i Registers
- * F1:0x40 i = 0
- * F1:0x48 i = 1
- * F1:0x50 i = 2
- * F1:0x58 i = 3
- * F1:0x60 i = 4
- * F1:0x68 i = 5
- * F1:0x70 i = 6
- * F1:0x78 i = 7
- * [ 0: 0] Read Enable
- * 0 = Reads Disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes Disabled
- * 1 = Writes Enabled
- * [ 7: 2] Reserved
- * [10: 8] Interleave Enable
- * 000 = No interleave
- * 001 = Interleave on A[12] (2 nodes)
- * 010 = reserved
- * 011 = Interleave on A[12] and A[14] (4 nodes)
- * 100 = reserved
- * 101 = reserved
- * 110 = reserved
- * 111 = Interleave on A[12] and A[13] and A[14] (8 nodes)
- * [15:11] Reserved
- * [13:16] DRAM Base Address i Bits 39-24
- * This field defines the upper address bits of a 40-bit address
- * that define the start of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
- /* DRAM CS Base Address i Registers
- * F2:0x40 i = 0
- * F2:0x44 i = 1
- * F2:0x48 i = 2
- * F2:0x4C i = 3
- * F2:0x50 i = 4
- * F2:0x54 i = 5
- * F2:0x58 i = 6
- * F2:0x5C i = 7
- * [ 0: 0] Chip-Select Bank Enable
- * 0 = Bank Disabled
- * 1 = Bank Enabled
- * [ 1: 1] Spare Rank
- * [ 2: 2] Memory Test Failed
- * [ 4: 3] Reserved
- * [13: 5] Base Address (21-13)
- * An optimization used when all DIMM are the same size...
- * [18:14] Reserved
- * [28:19] Base Address (36-27)
- * This field defines the top 11 addresses bit of a 40-bit
- * address that define the memory address space. These
- * bits decode 32-MByte blocks of memory.
- * [31:29] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x40), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x44), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x48), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x4C), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x50), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x54), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x58), 0xe007c018, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x5C), 0xe007c018, 0x00000000,
- /* DRAM CS Mask Address i Registers
- * F2:0x60 i = 0,1
- * F2:0x64 i = 2,3
- * F2:0x68 i = 4,5
- * F2:0x6C i = 6,7
- * Select bits to exclude from comparison with the DRAM Base address register.
- * [ 4: 0] Reserved
- * [13: 5] Address Mask (21-13)
- * Address to be excluded from the optimized case
- * [18:14] Reserved
- * [28:19] Address Mask (36-27)
- * The bits with an address mask of 1 are excluded from address comparison
- * [31:29] Reserved
- *
- */
- PCI_ADDR(0, 0x18, 2, 0x60), 0xe007c01f, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x64), 0xe007c01f, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x68), 0xe007c01f, 0x00000000,
- PCI_ADDR(0, 0x18, 2, 0x6C), 0xe007c01f, 0x00000000,
-
- /* DRAM Control Register
- * F2:0x78
- * [ 3: 0] RdPtrInit (Read Pointer Initial Value)
- * 0x03-0x00: reserved
- * [ 6: 4] RdPadRcvFifoDly (Read Delay from Pad Receive FIFO)
- * 000 = reserved
- * 001 = reserved
- * 010 = 1.5 Memory Clocks
- * 011 = 2 Memory Clocks
- * 100 = 2.5 Memory Clocks
- * 101 = 3 Memory Clocks
- * 110 = 3.5 Memory Clocks
- * 111 = Reserved
- * [15: 7] Reserved
- * [16:16] AltVidC3MemClkTriEn (AltVID Memory Clock Tristate Enable)
- * Enables the DDR memory clocks to be tristated when alternate VID
- * mode is enabled. This bit has no effect if the DisNbClkRamp bit
- * (F3, 0x88) is set
- * [17:17] DllTempAdjTime (DLL Temperature Adjust Cycle Time)
- * 0 = 5 ms
- * 1 = 1 ms
- * [18:18] DqsRcvEnTrain (DQS Receiver Enable Training Mode)
- * 0 = Normal DQS Receiver enable operation
- * 1 = DQS receiver enable training mode
- * [31:19] reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x78), 0xfff80000, (6<<4)|(6<<0),
-
- /* DRAM Initialization Register
- * F2:0x7C
- * [15: 0] MrsAddress (Address for MRS/EMRS Commands)
- * this field specifies the data driven on the DRAM address pins
- * 15-0 for MRS and EMRS commands
- * [18:16] MrsBank (Bank Address for MRS/EMRS Commands)
- * this files specifies the data driven on the DRAM bank pins for
- * the MRS and EMRS commands
- * [23:19] reserved
- * [24:24] SendPchgAll (Send Precharge All Command)
- * Setting this bit causes the DRAM controller to send a precharge
- * all command. This bit is cleared by the hardware after the
- * command completes
- * [25:25] SendAutoRefresh (Send Auto Refresh Command)
- * Setting this bit causes the DRAM controller to send an auto
- * refresh command. This bit is cleared by the hardware after the
- * command completes
- * [26:26] SendMrsCmd (Send MRS/EMRS Command)
- * Setting this bit causes the DRAM controller to send the MRS or
- * EMRS command defined by the MrsAddress and MrsBank fields. This
- * bit is cleared by the hardware after the command completes
- * [27:27] DeassertMemRstX (De-assert Memory Reset)
- * Setting this bit causes the DRAM controller to de-assert the
- * memory reset pin. This bit cannot be used to assert the memory
- * reset pin
- * [28:28] AssertCke (Assert CKE)
- * setting this bit causes the DRAM controller to assert the CKE
- * pins. This bit cannot be used to de-assert the CKE pins
- * [30:29] reserved
- * [31:31] EnDramInit (Enable DRAM Initialization)
- * Setting this bit puts the DRAM controller in a BIOS controlled
- * DRAM initialization mode. BIOS must clear this bit aster DRAM
- * initialization is complete.
- */
-// PCI_ADDR(0, 0x18, 2, 0x7C), 0x60f80000, 0,
-
-
- /* DRAM Bank Address Mapping Register
- * F2:0x80
- * Specify the memory module size
- * [ 3: 0] CS1/0
- * [ 7: 4] CS3/2
- * [11: 8] CS5/4
- * [15:12] CS7/6
- * [31:16]
- row col bank
- 0: 13 9 2 :128M
- 1: 13 10 2 :256M
- 2: 14 10 2 :512M
- 3: 13 11 2 :512M
- 4: 13 10 3 :512M
- 5: 14 10 3 :1G
- 6: 14 11 2 :1G
- 7: 15 10 3 :2G
- 8: 14 11 3 :2G
- 9: 15 11 3 :4G
- 10: 16 10 3 :4G
- 11: 16 11 3 :8G
- */
- PCI_ADDR(0, 0x18, 2, 0x80), 0xffff0000, 0x00000000,
- /* DRAM Timing Low Register
- * F2:0x88
- * [ 2: 0] Tcl (Cas# Latency, Cas# to read-data-valid)
- * 000 = reserved
- * 001 = reserved
- * 010 = CL 3
- * 011 = CL 4
- * 100 = CL 5
- * 101 = CL 6
- * 110 = reserved
- * 111 = reserved
- * [ 3: 3] Reserved
- * [ 5: 4] Trcd (Ras#-active to Cas# read/write delay)
- * 00 = 3 clocks
- * 01 = 4 clocks
- * 10 = 5 clocks
- * 11 = 6 clocks
- * [ 7: 6] Reserved
- * [ 9: 8] Trp (Row Precharge Time, Precharge-to-Active or Auto-Refresh)
- * 00 = 3 clocks
- * 01 = 4 clocks
- * 10 = 5 clocks
- * 11 = 6 clocks
- * [10:10] Reserved
- * [11:11] Trtp (Read to Precharge Time, read Cas# to precharge time)
- * 0 = 2 clocks for Burst Length of 32 Bytes
- * 4 clocks for Burst Length of 64 Bytes
- * 1 = 3 clocks for Burst Length of 32 Bytes
- * 5 clocks for Burst Length of 64 Bytes
- * [15:12] Tras (Minimum Ras# Active Time)
- * 0000 = reserved
- * 0001 = reserved
- * 0010 = 5 bus clocks
- * ...
- * 1111 = 18 bus clocks
- * [19:16] Trc (Row Cycle Time, Ras#-active to Ras#-active or auto
- * refresh of the same bank)
- * 0000 = 11 bus clocks
- * 0010 = 12 bus clocks
- * ...
- * 1110 = 25 bus clocks
- * 1111 = 26 bus clocks
- * [21:20] Twr (Write Recovery Time, From the last data to precharge,
- * writes can go back-to-back)
- * 00 = 3 bus clocks
- * 01 = 4 bus clocks
- * 10 = 5 bus clocks
- * 11 = 6 bus clocks
- * [23:22] Trrd (Active-to-active(Ras#-to-Ras#) Delay of different banks)
- * 00 = 2 bus clocks
- * 01 = 3 bus clocks
- * 10 = 4 bus clocks
- * 11 = 5 bus clocks
- * [31:24] MemClkDis (Disable the MEMCLK outputs for DRAM channel A,
- * BIOS should set it to reduce the power consumption)
- * Bit F(1207) M2 Package S1g1 Package
- * 0 N/A MA1_CLK1 N/A
- * 1 N/A MA0_CLK1 MA0_CLK1
- * 2 MA3_CLK N/A N/A
- * 3 MA2_CLK N/A N/A
- * 4 MA1_CLK MA1_CLK0 N/A
- * 5 MA0_CLK MA0_CLK0 MA0_CLK0
- * 6 N/A MA1_CLK2 N/A
- * 7 N/A MA0_CLK2 MA0_CLK2
- */
- PCI_ADDR(0, 0x18, 2, 0x88), 0x000004c8, 0xff000002 /* 0x03623125 */ ,
- /* DRAM Timing High Register
- * F2:0x8C
- * [ 3: 0] Reserved
- * [ 6: 4] TrwtTO (Read-to-Write Turnaround for Data, DQS Contention)
- * 000 = 2 bus clocks
- * 001 = 3 bus clocks
- * 010 = 4 bus clocks
- * 011 = 5 bus clocks
- * 100 = 6 bus clocks
- * 101 = 7 bus clocks
- * 110 = 8 bus clocks
- * 111 = 9 bus clocks
- * [ 7: 7] Reserved
- * [ 9: 8] Twtr (Internal DRAM Write-to-Read Command Delay,
- * Minimum write-to-read delay when both access the same chip select)
- * 00 = Reserved
- * 01 = 1 bus clocks
- * 10 = 2 bus clocks
- * 11 = 3 bus clocks
- * [11:10] Twrrd (Write to Read DIMM Termination Turnaround, minimum
- * write-to-read delay when accessing two different DIMMs)
- * 00 = 0 bus clocks
- * 01 = 1 bus clocks
- * 10 = 2 bus clocks
- * 11 = 3 bus clocks
- * [13:12] Twrwr (Write to Write Timing)
- * 00 = 1 bus clocks (0 idle cycle on the bus)
- * 01 = 2 bus clocks (1 idle cycle on the bus)
- * 10 = 3 bus clocks (2 idle cycles on the bus)
- * 11 = Reserved
- * [15:14] Trdrd (Read to Read Timing)
- * 00 = 2 bus clocks (1 idle cycle on the bus)
- * 01 = 3 bus clocks (2 idle cycles on the bus)
- * 10 = 4 bus clocks (3 idle cycles on the bus)
- * 11 = 5 bus clocks (4 idle cycles on the bus)
- * [17:16] Tref (Refresh Rate)
- * 00 = Undefined behavior
- * 01 = Reserved
- * 10 = Refresh interval of 7.8 microseconds
- * 11 = Refresh interval of 3.9 microseconds
- * [19:18] Reserved
- * [22:20] Trfc0 (Auto-Refresh Row Cycle Time for the Logical DIMM0,
- * based on DRAM density and speed)
- * 000 = 75 ns (all speeds, 256Mbit)
- * 001 = 105 ns (all speeds, 512Mbit)
- * 010 = 127.5 ns (all speeds, 1Gbit)
- * 011 = 195 ns (all speeds, 2Gbit)
- * 100 = 327.5 ns (all speeds, 4Gbit)
- * 101 = reserved
- * 110 = reserved
- * 111 = reserved
- * [25:23] Trfc1 (Auto-Refresh Row Cycle Time for the Logical DIMM1,
- * based on DRAM density and speed)
- * [28:26] Trfc2 (Auto-Refresh Row Cycle Time for the Logical DIMM2,
- * based on DRAM density and speed)
- * [31:29] Trfc3 (Auto-Refresh Row Cycle Time for the Logical DIMM3,
- * based on DRAM density and speed)
- */
- PCI_ADDR(0, 0x18, 2, 0x8c), 0x000c008f, (2 << 16)|(1 << 8),
- /* DRAM Config Low Register
- * F2:0x90
- * [ 0: 0] InitDram (Initialize DRAM)
- * 1 = write 1 cause DRAM controller to execute the DRAM
- * initialization, when done it read to 0
- * [ 1: 1] ExitSelfRef (Exit Self Refresh Command)
- * 1 = write 1 causes the DRAM controller to bring the DRAMs out
- * for self refresh mode
- * [ 3: 2] Reserved
- * [ 5: 4] DramTerm (DRAM Termination)
- * 00 = On die termination disabled
- * 01 = 75 ohms
- * 10 = 150 ohms
- * 11 = 50 ohms
- * [ 6: 6] Reserved
- * [ 7: 7] DramDrvWeak (DRAM Drivers Weak Mode)
- * 0 = Normal drive strength mode.
- * 1 = Weak drive strength mode
- * [ 8: 8] ParEn (Parity Enable)
- * 1 = Enable address parity computation output, PAR,
- * and enables the parity error input, ERR
- * [ 9: 9] SelfRefRateEn (Faster Self Refresh Rate Enable)
- * 1 = Enable high temperature (two times normal)
- * self refresh rate
- * [10:10] BurstLength32 (DRAM Burst Length Set for 32 Bytes)
- * 0 = 64-byte mode
- * 1 = 32-byte mode
- * [11:11] Width128 (Width of DRAM interface)
- * 0 = the controller DRAM interface is 64-bits wide
- * 1 = the controller DRAM interface is 128-bits wide
- * [12:12] X4Dimm (DIMM 0 is x4)
- * [13:13] X4Dimm (DIMM 1 is x4)
- * [14:14] X4Dimm (DIMM 2 is x4)
- * [15:15] X4Dimm (DIMM 3 is x4)
- * 0 = DIMM is not x4
- * 1 = x4 DIMM present
- * [16:16] UnBuffDimm (Unbuffered DIMMs)
- * 0 = Buffered DIMMs
- * 1 = Unbuffered DIMMs
- * [18:17] Reserved
- * [19:19] DimmEccEn (DIMM ECC Enable)
- * 1 = ECC checking is being enabled for all DIMMs on the DRAM
- * controller (Through F3 0x44[EccEn])
- * [31:20] Reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x90), 0xfff6004c, 0x00000010,
- /* DRAM Config High Register
- * F2:0x94
- * [ 0: 2] MemClkFreq (Memory Clock Frequency)
- * 000 = 200MHz
- * 001 = 266MHz
- * 010 = 333MHz
- * 011 = reserved
- * 1xx = reserved
- * [ 3: 3] MemClkFreqVal (Memory Clock Frequency Valid)
- * 1 = BIOS need to set the bit when setting up MemClkFreq to
- * the proper value
- * [ 7: 4] MaxAsyncLat (Maximum Asynchronous Latency)
- * 0000 = 0 ns
- * ...
- * 1111 = 15 ns
- * [11: 8] Reserved
- * [12:12] RDqsEn (Read DQS Enable) This bit is only be set if x8
- * registered DIMMs are present in the system
- * 0 = DM pins function as data mask pins
- * 1 = DM pins function as read DQS pins
- * [13:13] Reserved
- * [14:14] DisDramInterface (Disable the DRAM interface) When this bit
- * is set, the DRAM controller is disabled, and interface in low power
- * state
- * 0 = Enabled (default)
- * 1 = Disabled
- * [15:15] PowerDownEn (Power Down Mode Enable)
- * 0 = Disabled (default)
- * 1 = Enabled
- * [16:16] PowerDown (Power Down Mode)
- * 0 = Channel CKE Control
- * 1 = Chip Select CKE Control
- * [17:17] FourRankSODimm (Four Rank SO-DIMM)
- * 1 = this bit is set by BIOS to indicate that a four rank
- * SO-DIMM is present
- * [18:18] FourRankRDimm (Four Rank Registered DIMM)
- * 1 = this bit is set by BIOS to indicate that a four rank
- * registered DIMM is present
- * [19:19] Reserved
- * [20:20] SlowAccessMode (Slow Access Mode (2T Mode))
- * 0 = DRAM address and control signals are driven for one
- * MEMCLK cycle
- * 1 = One additional MEMCLK of setup time is provided on all
- * DRAM address and control signals except CS, CKE, and ODT;
- * i.e., these signals are driven for two MEMCLK cycles
- * rather than one
- * [21:21] Reserved
- * [22:22] BankSwizzleMode (Bank Swizzle Mode),
- * 0 = Disabled (default)
- * 1 = Enabled
- * [23:23] Reserved
- * [27:24] DcqBypassMax (DRAM Controller Queue Bypass Maximum)
- * 0000 = No bypass; the oldest request is never bypassed
- * 0001 = The oldest request may be bypassed no more than 1 time
- * ...
- * 1111 = The oldest request may be bypassed no more than 15\
- * times
- * [31:28] FourActWindow (Four Bank Activate Window) , not more than
- * 4 banks in a 8 bank device are activated
- * 0000 = No tFAW window restriction
- * 0001 = 8 MEMCLK cycles
- * 0010 = 9 MEMCLK cycles
- * ...
- * 1101 = 20 MEMCLK cycles
- * 111x = reserved
- */
- PCI_ADDR(0, 0x18, 2, 0x94), 0x00a82f00,0x00008000,
- /* DRAM Delay Line Register
- * F2:0xa0
- * [ 0: 0] MemClrStatus (Memory Clear Status) : Readonly
- * when set, this bit indicates that the memory clear function
- * is complete. Only clear by reset. BIOS should not write or
- * read the DRAM until this bit is set by hardware
- * [ 1: 1] DisableJitter (Disable Jitter)
- * When set the DDR compensation circuit will not change the
- * values unless the change is more than one step from the
- * current value
- * [ 3: 2] RdWrQByp (Read/Write Queue Bypass Count)
- * 00 = 2
- * 01 = 4
- * 10 = 8
- * 11 = 16
- * [ 4: 4] Mode64BitMux (Mismatched DIMM Support Enable)
- * 1 When bit enables support for mismatched DIMMs when using
- * 128-bit DRAM interface, the Width128 no effect, only for
- * AM2 and s1g1
- * [ 5: 5] DCC_EN (Dynamic Idle Cycle Counter Enable)
- * When set to 1, indicates that each entry in the page tables
- * dynamically adjusts the idle cycle limit based on page
- * Conflict/Page Miss (PC/PM) traffic
- * [ 8: 6] ILD_lmt (Idle Cycle Limit)
- * 000 = 0 cycles
- * 001 = 4 cycles
- * 010 = 8 cycles
- * 011 = 16 cycles
- * 100 = 32 cycles
- * 101 = 64 cycles
- * 110 = 128 cycles
- * 111 = 256 cycles
- * [ 9: 9] DramEnabled (DRAM Enabled)
- * When Set, this bit indicates that the DRAM is enabled, this
- * bit is set by hardware after DRAM initialization or on an exit
- * from self refresh. The DRAM controller is initialized after the
- * hardware-controlled initialization process (initiated by the
- * F2 0x90[DramInit]) completes or when the BIOS-controlled
- * initialization process completes (F2 0x7c(EnDramInit] is
- * written from 1 to 0)
- * [23:10] Reserved
- * [31:24] MemClkDis (Disable the MEMCLK outputs for DRAM channel B,
- * BIOS should set it to reduce the power consumption)
- * Bit F(1207) M2 Package S1g1 Package
- * 0 N/A MA1_CLK1 N/A
- * 1 N/A MA0_CLK1 MA0_CLK1
- * 2 MA3_CLK N/A N/A
- * 3 MA2_CLK N/A N/A
- * 4 MA1_CLK MA1_CLK0 N/A
- * 5 MA0_CLK MA0_CLK0 MA0_CLK0
- * 6 N/A MA1_CLK2 N/A
- * 7 N/A MA0_CLK2 MA0_CLK2
- */
- PCI_ADDR(0, 0x18, 2, 0xa0), 0x00fffc00, 0xff000000,
-
- /* DRAM Scrub Control Register
- * F3:0x58
- * [ 4: 0] DRAM Scrub Rate
- * [ 7: 5] reserved
- * [12: 8] L2 Scrub Rate
- * [15:13] reserved
- * [20:16] Dcache Scrub
- * [31:21] reserved
- * Scrub Rates
- * 00000 = Do not scrub
- * 00001 = 40.00 ns
- * 00010 = 80.00 ns
- * 00011 = 160.00 ns
- * 00100 = 320.00 ns
- * 00101 = 640.00 ns
- * 00110 = 1.28 us
- * 00111 = 2.56 us
- * 01000 = 5.12 us
- * 01001 = 10.20 us
- * 01011 = 41.00 us
- * 01100 = 81.90 us
- * 01101 = 163.80 us
- * 01110 = 327.70 us
- * 01111 = 655.40 us
- * 10000 = 1.31 ms
- * 10001 = 2.62 ms
- * 10010 = 5.24 ms
- * 10011 = 10.49 ms
- * 10100 = 20.97 ms
- * 10101 = 42.00 ms
- * 10110 = 84.00 ms
- * All Others = Reserved
- */
- PCI_ADDR(0, 0x18, 3, 0x58), 0xffe0e0e0, 0x00000000,
- /* DRAM Scrub Address Low Register
- * F3:0x5C
- * [ 0: 0] DRAM Scrubber Redirect Enable
- * 0 = Do nothing
- * 1 = Scrubber Corrects errors found in normal operation
- * [ 5: 1] Reserved
- * [31: 6] DRAM Scrub Address 31-6
- */
- PCI_ADDR(0, 0x18, 3, 0x5C), 0x0000003e, 0x00000000,
- /* DRAM Scrub Address High Register
- * F3:0x60
- * [ 7: 0] DRAM Scrub Address 39-32
- * [31: 8] Reserved
- */
- PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
- };
- /* for PCI_ADDR(0, 0x18, 2, 0x98) index,
- and PCI_ADDR(0x, 0x18, 2, 0x9c) data */
- /*
-index:
- [29: 0] DctOffset (Dram Controller Offset)
- [30:30] DctAccessWrite (Dram Controller Read/Write Select)
- 0 = read access
- 1 = write access
- [31:31] DctAccessDone (Dram Controller Access Done)
- 0 = Access in progress
- 1 = No access is progress
-
- Data:
- [31: 0] DctOffsetData (Dram Controller Offset Data)
-
- Read:
- - Write the register num to DctOffset with DctAccessWrite = 0
- - poll the DctAccessDone until it = 1
- - Read the data from DctOffsetData
- Write:
- - Write the data to DctOffsetData
- - Write register num to DctOffset with DctAccessWrite = 1
- - poll the DctAccessDone until it = 1
-
- */
- int i;
- int max;
-
- if (!controller_present(ctrl)) {
- sysinfo->ctrl_present[ctrl->node_id] = 0;
- return;
- }
- sysinfo->ctrl_present[ctrl->node_id] = 1;
-
- printk(BIOS_SPEW, "setting up CPU %02x northbridge registers\n", ctrl->node_id);
- max = ARRAY_SIZE(register_values);
- for (i = 0; i < max; i += 3) {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg;
- dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
- where = register_values[i] & 0xff;
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+1];
- reg |= register_values[i+2];
- pci_write_config32(dev, where, reg);
- }
- printk(BIOS_SPEW, "done.\n");
-}
-
-static int is_opteron(const struct mem_controller *ctrl)
-{
- /* Test to see if I am an Opteron. M2 and S1G1 support dual
- * channel, too, but only support unbuffered DIMMs so we need a
- * better test for Opterons.
- * However, all code uses is_opteron() to find out whether to
- * use dual channel, so if we really check for opteron here, we
- * need to fix up all code using this function, too.
- */
-
- uint32_t nbcap;
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- return !!(nbcap & NBCAP_128Bit);
-}
-
-static void spd_get_dimm_size(unsigned device, struct dimm_size *sz)
-{
- /* Calculate the log base 2 size of a DIMM in bits */
- int value;
- sz->per_rank = 0;
- sz->rows = 0;
- sz->col = 0;
- sz->rank = 0;
-
- value = spd_read_byte(device, SPD_ROW_NUM); /* rows */
- if (value < 0) goto hw_err;
- if ((value & 0xff) == 0) goto val_err; /* max is 16 ? */
- sz->per_rank += value & 0xff;
- sz->rows = value & 0xff;
-
- value = spd_read_byte(device, SPD_COL_NUM); /* columns */
- if (value < 0) goto hw_err;
- if ((value & 0xff) == 0) goto val_err; /* max is 11 */
- sz->per_rank += value & 0xff;
- sz->col = value & 0xff;
-
- value = spd_read_byte(device, SPD_BANK_NUM); /* banks */
- if (value < 0) goto hw_err;
- if ((value & 0xff) == 0) goto val_err;
- sz->bank = log2(value & 0xff); // convert 4 to 2, and 8 to 3
- sz->per_rank += sz->bank;
-
- /* Get the module data width and convert it to a power of two */
- value = spd_read_byte(device, SPD_DATA_WIDTH);
- if (value < 0) goto hw_err;
- value &= 0xff;
- if ((value != 72) && (value != 64)) goto val_err;
- sz->per_rank += log2(value) - 3; //64 bit So another 3 lines
-
- /* How many ranks? */
- /* number of physical banks */
- value = spd_read_byte(device, SPD_MOD_ATTRIB_RANK);
- if (value < 0) goto hw_err;
- value &= SPD_MOD_ATTRIB_RANK_NUM_MASK;
- value += SPD_MOD_ATTRIB_RANK_NUM_BASE; // 0-->1, 1-->2, 3-->4
- /*
- rank == 1 only one rank or say one side
- rank == 2 two side , and two ranks
- rank == 4 two side , and four ranks total
- Some one side two ranks, because of stacked
- */
- if ((value != 1) && (value != 2) && (value != 4)) {
- goto val_err;
- }
- sz->rank = value;
-
- /* verify if per_rank is equal byte 31
- it has the DIMM size as a multiple of 128MB.
- */
- value = spd_read_byte(device, SPD_RANK_SIZE);
- if (value < 0) goto hw_err;
- value &= 0xff;
- value = log2(value);
- if (value <= 4) value += 8; // add back to 1G to high
- value += (27-5); // make 128MB to the real lines
- if (value != (sz->per_rank)) {
- printk(BIOS_ERR, "Bad RANK Size --\n");
- goto val_err;
- }
-
- goto out;
-
- val_err:
- die("Bad SPD value\n");
- /* If an hw_error occurs report that I have no memory */
- hw_err:
- sz->per_rank = 0;
- sz->rows = 0;
- sz->col = 0;
- sz->bank = 0;
- sz->rank = 0;
-out:
- return;
-}
-
-
-static void set_dimm_size(const struct mem_controller *ctrl,
- struct dimm_size *sz, unsigned index,
- struct mem_info *meminfo)
-{
- uint32_t base0, base1;
-
- /* For each base register.
- * Place the dimm size in 32 MB quantities in the bits 31 - 21.
- * The initialize dimm size is in bits.
- * Set the base enable bit0.
- */
-
- base0 = base1 = 0;
-
- /* Make certain side1 of the dimm is at least 128MB */
- if (sz->per_rank >= 27) {
- base0 = (1 << ((sz->per_rank - 27) + 19)) | 1;
- }
-
- /* Make certain side2 of the dimm is at least 128MB */
- if (sz->rank > 1) { // 2 ranks or 4 ranks
- base1 = (1 << ((sz->per_rank - 27) + 19)) | 1;
- }
-
- /* Double the size if we are using dual channel memory */
- if (meminfo->is_Width128) {
- base0 = (base0 << 1) | (base0 & 1);
- base1 = (base1 << 1) | (base1 & 1);
- }
-
- /* Clear the reserved bits */
- base0 &= ~0xe007fffe;
- base1 &= ~0xe007fffe;
-
- if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), base0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), base1);
- } else {
- /* Set the appropriate DIMM base address register */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 0) << 2), base0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 1) << 2), base1);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz->rank == 4) {
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), base0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), base1);
- }
-#endif
- }
-
- /* Enable the memory clocks for this DIMM by Clear the MemClkDis bit*/
- if (base0) {
- uint32_t dword;
- uint32_t ClkDis0;
-#if CONFIG_CPU_SOCKET_TYPE == 0x10 /* L1 */
- ClkDis0 = DTL_MemClkDis0;
-#elif CONFIG_CPU_SOCKET_TYPE == 0x11 /* AM2 */
- ClkDis0 = DTL_MemClkDis0_AM2;
-#elif CONFIG_CPU_SOCKET_TYPE == 0x12 /* S1G1 */
- ClkDis0 = DTL_MemClkDis0_S1g1;
-#endif
-
- if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */
- dword = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
- dword &= ~(ClkDis0 >> index);
- pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dword);
-
- } else {
- dword = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW); //Channel A
- dword &= ~(ClkDis0 >> index);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz->rank == 4) {
- dword &= ~(ClkDis0 >> (index+2));
- }
-#endif
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dword);
-
- if (meminfo->is_Width128) { // ChannelA+B
- dword = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
- dword &= ~(ClkDis0 >> index);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz->rank == 4) {
- dword &= ~(ClkDis0 >> (index+2));
- }
-#endif
- pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dword);
- }
- }
-
- }
-}
-
-/* row col bank for 64 bit
- 0: 13 9 2 :128M
- 1: 13 10 2 :256M
- 2: 14 10 2 :512M
- 3: 13 11 2 :512M
- 4: 13 10 3 :512M
- 5: 14 10 3 :1G
- 6: 14 11 2 :1G
- 7: 15 10 3 :2G
- 8: 14 11 3 :2G
- 9: 15 11 3 :4G
- 10: 16 10 3 :4G
- 11: 16 11 3 :8G
-*/
-
-
-static void set_dimm_cs_map(const struct mem_controller *ctrl,
- struct dimm_size *sz, unsigned index,
- struct mem_info *meminfo)
-{
- static const uint8_t cs_map_aaa[24] = {
- /* (bank=2, row=13, col=9)(3, 16, 11) ---> (0, 0, 0) (1, 3, 2) */
- //Bank2
- 0, 1, 3,
- 0, 2, 6,
- 0, 0, 0,
- 0, 0, 0,
- //Bank3
- 0, 4, 0,
- 0, 5, 8,
- 0, 7, 9,
- 0,10,11,
- };
-
- uint32_t map;
-
- if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */
- index += 2;
- }
- map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
- map &= ~(0xf << (index * 4));
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz->rank == 4) {
- map &= ~(0xf << ((index + 2) * 4));
- }
-#endif
-
- /* Make certain side1 of the dimm is at least 128MB */
- if (sz->per_rank >= 27) {
- unsigned temp_map;
- temp_map = cs_map_aaa[(sz->bank-2)*3*4 + (sz->rows - 13)*3 + (sz->col - 9) ];
- map |= temp_map << (index*4);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (sz->rank == 4) {
- map |= temp_map << ((index + 2) * 4);
- }
-#endif
- }
-
- pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);
-
-}
-
-
-static long spd_set_ram_size(const struct mem_controller *ctrl,
- struct mem_info *meminfo)
-{
- int i;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- struct dimm_size *sz = &(meminfo->sz[i]);
- u32 spd_device = ctrl->channel0[i];
-
- if (!(meminfo->dimm_mask & (1 << i))) {
- if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- } else {
- continue;
- }
- }
-
- spd_get_dimm_size(spd_device, sz);
- if (sz->per_rank == 0) {
- return -1; /* Report SPD error */
- }
- set_dimm_size(ctrl, sz, i, meminfo);
- set_dimm_cs_map(ctrl, sz, i, meminfo);
- }
- return meminfo->dimm_mask;
-}
-
-static void route_dram_accesses(const struct mem_controller *ctrl,
- unsigned long base_k, unsigned long limit_k)
-{
- /* Route the addresses to the controller node */
- unsigned node_id;
- unsigned limit;
- unsigned base;
- unsigned index;
- unsigned limit_reg, base_reg;
- pci_devfn_t device;
-
- node_id = ctrl->node_id;
- index = (node_id << 3);
- limit = (limit_k << 2);
- limit &= 0xffff0000;
- limit -= 0x00010000;
- limit |= (0 << 8) | (node_id << 0);
- base = (base_k << 2);
- base &= 0xffff0000;
- base |= (0 << 8) | (1<<1) | (1<<0);
-
- limit_reg = 0x44 + index;
- base_reg = 0x40 + index;
- for (device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1);
- device += PCI_DEV(0, 1, 0)) {
- pci_write_config32(device, limit_reg, limit);
- pci_write_config32(device, base_reg, base);
- }
-}
-
-static void set_top_mem(unsigned tom_k, unsigned hole_startk)
-{
- /* Error if I don't have memory */
- if (!tom_k) {
- die("No memory?");
- }
-
- /* Report the amount of memory. */
- printk(BIOS_DEBUG, "RAM end at 0x%08x kB\n", tom_k);
-
- /* Now set top of memory */
- msr_t msr;
- if (tom_k > (4*1024*1024)) {
- printk_raminit("Handling memory mapped above 4 GB\n");
- printk_raminit("Upper RAM end at 0x%08x kB\n", tom_k);
- msr.lo = (tom_k & 0x003fffff) << 10;
- msr.hi = (tom_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM2, msr);
- printk_raminit("Correcting memory amount mapped below 4 GB\n");
- }
-
- /* Leave a 64M hole between TOP_MEM and TOP_MEM2
- * so I can see my ROM chip and other I/O devices.
- */
- if (tom_k >= 0x003f0000) {
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- if (hole_startk != 0) {
- tom_k = hole_startk;
- } else
-#endif
- tom_k = 0x3f0000;
- printk_raminit("Adjusting lower RAM end\n");
- }
- printk_raminit("Lower RAM end at 0x%08x kB\n", tom_k);
- msr.lo = (tom_k & 0x003fffff) << 10;
- msr.hi = (tom_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM, msr);
-}
-
-static unsigned long interleave_chip_selects(const struct mem_controller *ctrl, int is_Width128)
-{
- /* 35 - 27 */
-
- static const uint8_t csbase_low_f0_shift[] = {
- /* 128MB */ (14 - (13-5)),
- /* 256MB */ (15 - (13-5)),
- /* 512MB */ (15 - (13-5)),
- /* 512MB */ (16 - (13-5)),
- /* 512MB */ (16 - (13-5)),
- /* 1GB */ (16 - (13-5)),
- /* 1GB */ (16 - (13-5)),
- /* 2GB */ (16 - (13-5)),
- /* 2GB */ (17 - (13-5)),
- /* 4GB */ (17 - (13-5)),
- /* 4GB */ (16 - (13-5)),
- /* 8GB */ (17 - (13-5)),
- };
-
- /* cs_base_high is not changed */
-
- uint32_t csbase_inc;
- int chip_selects, index;
- int bits;
- unsigned common_size;
- unsigned common_cs_mode;
- uint32_t csbase, csmask;
-
- /* See if all of the memory chip selects are the same size
- * and if so count them.
- */
-#if defined(CMOS_VSTART_interleave_chip_selects)
- if (read_option(interleave_chip_selects, 1) == 0)
- return 0;
-#else
-#if !defined(CONFIG_INTERLEAVE_CHIP_SELECTS) || !CONFIG_INTERLEAVE_CHIP_SELECTS
- return 0;
-#endif
-#endif
-
- chip_selects = 0;
- common_size = 0;
- common_cs_mode = 0xff;
- for (index = 0; index < 8; index++) {
- unsigned size;
- unsigned cs_mode;
- uint32_t value;
-
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
- chip_selects++;
- size = (value >> 19) & 0x3ff;
- if (common_size == 0) {
- common_size = size;
- }
- /* The size differed fail */
- if (common_size != size) {
- return 0;
- }
-
- value = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
- cs_mode =(value >> ((index>>1)*4)) & 0xf;
- if (common_cs_mode == 0xff) {
- common_cs_mode = cs_mode;
- }
- /* The cs_mode differed fail */
- if (common_cs_mode != cs_mode) {
- return 0;
- }
- }
-
- /* Chip selects can only be interleaved when there is
- * more than one and their is a power of two of them.
- */
- bits = log2(chip_selects);
- if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) {
- //chip_selects max = 8
- return 0;
- }
-
- /* Find the bits of csbase that we need to interleave on */
- csbase_inc = 1 << (csbase_low_f0_shift[common_cs_mode]);
- if (is_Width128) {
- csbase_inc <<=1;
- }
-
- /* Compute the initial values for csbase and csmask.
- * In csbase just set the enable bit and the base to zero.
- * In csmask set the mask bits for the size and page level interleave.
- */
- csbase = 0 | 1;
- csmask = (((common_size << bits) - 1) << 19);
- csmask |= 0x3fe0 & ~((csbase_inc << bits) - csbase_inc);
- for (index = 0; index < 8; index++) {
- uint32_t value;
-
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (index << 2), csbase);
- if ((index & 1) == 0) { //only have 4 CSMASK
- pci_write_config32(ctrl->f2, DRAM_CSMASK + ((index>>1) << 2), csmask);
- }
- csbase += csbase_inc;
- }
-
- printk(BIOS_DEBUG, "Interleaved\n");
-
- /* Return the memory size in K */
- return common_size << ((27-10) + bits);
-}
-
-static unsigned long order_chip_selects(const struct mem_controller *ctrl)
-{
- unsigned long tom;
-
- /* Remember which registers we have used in the high 8 bits of tom */
- tom = 0;
- for (;;) {
- /* Find the largest remaining candidate */
- unsigned index, canidate;
- uint32_t csbase, csmask;
- unsigned size;
- csbase = 0;
- canidate = 0;
- for (index = 0; index < 8; index++) {
- uint32_t value;
- value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
- /* Is it enabled? */
- if (!(value & 1)) {
- continue;
- }
-
- /* Is it greater? */
- if (value <= csbase) {
- continue;
- }
-
- /* Has it already been selected */
- if (tom & (1 << (index + 24))) {
- continue;
- }
- /* I have a new candidate */
- csbase = value;
- canidate = index;
- }
-
- /* See if I have found a new candidate */
- if (csbase == 0) {
- break;
- }
-
- /* Remember the dimm size */
- size = csbase >> 19;
-
- /* Remember I have used this register */
- tom |= (1 << (canidate + 24));
-
- /* Recompute the cs base register value */
- csbase = (tom << 19) | 1;
-
- /* Increment the top of memory */
- tom += size;
-
- /* Compute the memory mask */
- csmask = ((size -1) << 19);
- csmask |= 0x3fe0; /* For now don't optimize */
-
- /* Write the new base register */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (canidate << 2), csbase);
- /* Write the new mask register */
- if ((canidate & 1) == 0) { //only have 4 CSMASK
- pci_write_config32(ctrl->f2, DRAM_CSMASK + ((canidate >> 1) << 2), csmask);
- }
-
- }
- /* Return the memory size in K */
- return (tom & ~0xff000000) << (27-10);
-}
-
-static unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
-{
- unsigned node_id;
- unsigned end_k;
- /* Find the last memory address used */
- end_k = 0;
- for (node_id = 0; node_id < max_node_id; node_id++) {
- uint32_t limit, base;
- unsigned index;
- index = node_id << 3;
- base = pci_read_config32(ctrl->f1, 0x40 + index);
- /* Only look at the limit if the base is enabled */
- if ((base & 3) == 3) {
- limit = pci_read_config32(ctrl->f1, 0x44 + index);
- end_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
- }
- }
- return end_k;
-}
-
-static void order_dimms(const struct mem_controller *ctrl,
- struct mem_info *meminfo)
-{
- unsigned long tom_k, base_k;
-
- tom_k = interleave_chip_selects(ctrl, meminfo->is_Width128);
-
- if (!tom_k) {
- printk(BIOS_DEBUG, "Interleaving disabled\n");
- tom_k = order_chip_selects(ctrl);
- }
-
- /* Compute the memory base address */
- base_k = memory_end_k(ctrl, ctrl->node_id);
- tom_k += base_k;
- route_dram_accesses(ctrl, base_k, tom_k);
- set_top_mem(tom_k, 0);
-}
-
-static long disable_dimm(const struct mem_controller *ctrl, unsigned index,
- struct mem_info *meminfo)
-{
- printk(BIOS_DEBUG, "disabling dimm %02x\n", index);
- if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), 0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), 0);
- } else {
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 0) << 2), 0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 1) << 2), 0);
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (meminfo->sz[index].rank == 4) {
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), 0);
- pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), 0);
- }
-#endif
- }
-
- meminfo->dimm_mask &= ~(1 << index);
- return meminfo->dimm_mask;
-}
-
-static long spd_handle_unbuffered_dimms(const struct mem_controller *ctrl,
- struct mem_info *meminfo)
-{
- int i;
- uint32_t registered;
- uint32_t dcl;
- registered = 0;
- for (i = 0; (i < DIMM_SOCKETS); i++) {
- int value;
- u32 spd_device = ctrl->channel0[i];
- if (!(meminfo->dimm_mask & (1 << i))) {
- if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- } else {
- continue;
- }
- }
- value = spd_read_byte(spd_device, SPD_DIMM_TYPE);
- if (value < 0) {
- return -1;
- }
-
- /* Registered dimm ? */
- value &= 0x3f;
- if ((value == SPD_DIMM_TYPE_RDIMM) || (value == SPD_DIMM_TYPE_mRDIMM)) {
- //check SPD_MOD_ATTRIB to verify it is SPD_MOD_ATTRIB_REGADC (0x11)?
- registered |= (1<<i);
- }
- }
-
- if (is_opteron(ctrl)) {
- }
-
-
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_UnBuffDimm;
- meminfo->is_registered = 1;
- if (!registered) {
- dcl |= DCL_UnBuffDimm;
- meminfo->is_registered = 0;
- }
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-
- if (meminfo->is_registered) {
- printk(BIOS_SPEW, "Registered\n");
- } else {
- printk(BIOS_SPEW, "Unbuffered\n");
- }
- return meminfo->dimm_mask;
-}
-
-static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
-{
- unsigned dimm_mask;
- int i;
- dimm_mask = 0;
- for (i = 0; i < DIMM_SOCKETS; i++) {
- int byte;
- unsigned device;
- device = ctrl->channel0[i];
- printk_raminit("DIMM socket %i, channel 0 SPD device is 0x%02x\n", i, device);
- if (device) {
- byte = spd_read_byte(ctrl->channel0[i], SPD_MEM_TYPE); /* Type */
- if (byte == SPD_MEM_TYPE_SDRAM_DDR2) {
- printk_raminit("\tDIMM detected\n");
- dimm_mask |= (1 << i);
- }
- }
- device = ctrl->channel1[i];
- printk_raminit("DIMM socket %i, channel 1 SPD device is 0x%02x\n", i, device);
- if (device) {
- byte = spd_read_byte(ctrl->channel1[i], SPD_MEM_TYPE);
- if (byte == SPD_MEM_TYPE_SDRAM_DDR2) {
- printk_raminit("\tDIMM detected\n");
- dimm_mask |= (1 << (i + DIMM_SOCKETS));
- }
- }
- }
- return dimm_mask;
-}
-
-static long spd_enable_2channels(const struct mem_controller *ctrl, struct mem_info *meminfo)
-{
- int i;
- uint32_t nbcap;
- /* SPD addresses to verify are identical */
- static const uint8_t addresses[] = {
- 2, /* Type should be DDR2 SDRAM */
- 3, /* *Row addresses */
- 4, /* *Column addresses */
- 5, /* *Number of DIMM Ranks */
- 6, /* *Module Data Width*/
- 11, /* *DIMM Conf Type */
- 13, /* *Pri SDRAM Width */
- 17, /* *Logical Banks */
- 20, /* *DIMM Type Info */
- 21, /* *SDRAM Module Attributes */
- 27, /* *tRP Row precharge time */
- 28, /* *Minimum Row Active to Row Active Delay (tRRD) */
- 29, /* *tRCD RAS to CAS */
- 30, /* *tRAS Activate to Precharge */
- 36, /* *Write recovery time (tWR) */
- 37, /* *Internal write to read command delay (tRDP) */
- 38, /* *Internal read to precharge command delay (tRTP) */
- 40, /* *Extension of Byte 41 tRC and Byte 42 tRFC */
- 41, /* *Minimum Active to Active/Auto Refresh Time(Trc) */
- 42, /* *Minimum Auto Refresh Command Time(Trfc) */
- /* The SPD addresses 18, 9, 23, 26 need special treatment like
- * in spd_set_memclk. Right now they cause many false negatives.
- * Keep them at the end to see other mismatches (if any).
- */
- 18, /* *Supported CAS Latencies */
- 9, /* *Cycle time at highest CAS Latency CL=X */
- 23, /* *Cycle time at CAS Latency (CLX - 1) */
- 25, /* *Cycle time at CAS Latency (CLX - 2) */
- };
- u32 dcl, dcm;
- u8 common_cl;
-
-/* S1G1 and AM2 sockets are Mod64BitMux capable. */
-#if CONFIG_CPU_SOCKET_TYPE == 0x11 || CONFIG_CPU_SOCKET_TYPE == 0x12
- u8 mux_cap = 1;
-#else
- u8 mux_cap = 0;
-#endif
-
- /* If the dimms are not in pairs do not do dual channels */
- if ((meminfo->dimm_mask & ((1 << DIMM_SOCKETS) - 1)) !=
- ((meminfo->dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) {
- goto single_channel;
- }
- /* If the CPU is not capable of doing dual channels don't do dual channels */
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- if (!(nbcap & NBCAP_128Bit)) {
- goto single_channel;
- }
- for (i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
- unsigned device0, device1;
- int value0, value1;
- int j;
- /* If I don't have a dimm skip this one */
- if (!(meminfo->dimm_mask & (1 << i))) {
- continue;
- }
- device0 = ctrl->channel0[i];
- device1 = ctrl->channel1[i];
- /* Abort if the chips don't support a common CAS latency. */
- common_cl = spd_read_byte(device0, 18) & spd_read_byte(device1, 18);
- if (!common_cl) {
- printk(BIOS_DEBUG, "No common CAS latency supported\n");
- goto single_channel;
- } else {
- printk_raminit("Common CAS latency bitfield: 0x%02x\n", common_cl);
- }
- for (j = 0; j < ARRAY_SIZE(addresses); j++) {
- unsigned addr;
- addr = addresses[j];
- value0 = spd_read_byte(device0, addr);
- if (value0 < 0) {
- return -1;
- }
- value1 = spd_read_byte(device1, addr);
- if (value1 < 0) {
- return -1;
- }
- if (value0 != value1) {
- printk_raminit("SPD values differ between channel 0/1 for byte %i\n", addr);
- goto single_channel;
- }
- }
- }
- printk(BIOS_SPEW, "Enabling dual channel memory\n");
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_BurstLength32; /* 32byte mode may be preferred in platforms that include graphics controllers that generate a lot of 32-bytes system memory accesses
- 32byte mode is not supported when the DRAM interface is 128 bits wide, even 32byte mode is set, system still use 64 byte mode */
- dcl |= DCL_Width128;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- meminfo->is_Width128 = 1;
- return meminfo->dimm_mask;
-
- single_channel:
- meminfo->is_Width128 = 0;
- meminfo->is_64MuxMode = 0;
-
- /* single dimm */
- if ((meminfo->dimm_mask & ((1 << DIMM_SOCKETS) - 1)) !=
- ((meminfo->dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) {
- if (((meminfo->dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) {
- /* mux capable and single dimm in channelB */
- if (mux_cap) {
- printk(BIOS_SPEW, "Enable 64MuxMode & BurstLength32\n");
- dcm = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
- dcm |= DCM_Mode64BitMux;
- pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dcm);
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- meminfo->is_64MuxMode = 1;
- } else {
- meminfo->dimm_mask &= ~((1 << (DIMM_SOCKETS * 2)) - (1 << DIMM_SOCKETS));
- }
- }
- } else { /* unmatched dual dimms ? */
- /* unmatched dual dimms not supported by meminit code. Use single channelA dimm. */
- meminfo->dimm_mask &= ~((1 << (DIMM_SOCKETS * 2)) - (1 << DIMM_SOCKETS));
- printk(BIOS_SPEW, "Unmatched dual dimms. Use single channelA dimm.\n");
- }
- return meminfo->dimm_mask;
-}
-
-struct mem_param {
- uint16_t cycle_time;
- uint8_t divisor; /* In 1/40 ns increments */
- uint8_t TrwtTO;
- uint8_t Twrrd;
- uint8_t Twrwr;
- uint8_t Trdrd;
- uint8_t DcqByPassMax;
- uint32_t dch_memclk;
- char name[9];
-};
-
- static const struct mem_param speed[] = {
- {
- .name = "200MHz",
- .cycle_time = 0x500,
- .divisor = 200, // how many 1/40ns per clock
- .dch_memclk = DCH_MemClkFreq_200MHz, //0
- .TrwtTO = 7,
- .Twrrd = 2,
- .Twrwr = 2,
- .Trdrd = 3,
- .DcqByPassMax = 4,
-
- },
- {
- .name = "266MHz",
- .cycle_time = 0x375,
- .divisor = 150, //????
- .dch_memclk = DCH_MemClkFreq_266MHz, //1
- .TrwtTO = 7,
- .Twrrd = 2,
- .Twrwr = 2,
- .Trdrd = 3,
- .DcqByPassMax = 4,
- },
- {
- .name = "333MHz",
- .cycle_time = 0x300,
- .divisor = 120,
- .dch_memclk = DCH_MemClkFreq_333MHz, //2
- .TrwtTO = 7,
- .Twrrd = 2,
- .Twrwr = 2,
- .Trdrd = 3,
- .DcqByPassMax = 4,
-
- },
- {
- .name = "400MHz",
- .cycle_time = 0x250,
- .divisor = 100,
- .dch_memclk = DCH_MemClkFreq_400MHz,//3
- .TrwtTO = 7,
- .Twrrd = 2,
- .Twrwr = 2,
- .Trdrd = 3,
- .DcqByPassMax = 4,
- },
- {
- .cycle_time = 0x000,
- },
- };
-
-static const struct mem_param *get_mem_param(unsigned min_cycle_time)
-{
-
- const struct mem_param *param;
- for (param = &speed[0]; param->cycle_time; param++) {
- if (min_cycle_time > (param+1)->cycle_time) {
- break;
- }
- }
- if (!param->cycle_time) {
- die("min_cycle_time to low");
- }
- printk(BIOS_SPEW, "%s\n", param->name);
- return param;
-}
-
-static uint8_t get_exact_divisor(int i, uint8_t divisor)
-{
- //input divisor could be 200(200), 150(266), 120(333), 100 (400)
- static const uint8_t dv_a[] = {
- /* 200 266 333 400 */
- /*4 */ 250, 250, 250, 250,
- /*5 */ 200, 200, 200, 100,
- /*6 */ 200, 166, 166, 100,
- /*7 */ 200, 171, 142, 100,
-
- /*8 */ 200, 150, 125, 100,
- /*9 */ 200, 156, 133, 100,
- /*10*/ 200, 160, 120, 100,
- /*11*/ 200, 163, 127, 100,
-
- /*12*/ 200, 150, 133, 100,
- /*13*/ 200, 153, 123, 100,
- /*14*/ 200, 157, 128, 100,
- /*15*/ 200, 160, 120, 100,
- };
-
-
- int index;
- msr_t msr;
-
- /* Check for FID control support */
- struct cpuid_result cpuid1;
- cpuid1 = cpuid(0x80000007);
- if (cpuid1.edx & 0x02) {
- /* Use current FID */
- unsigned fid_cur;
- msr = rdmsr(0xc0010042);
- fid_cur = msr.lo & 0x3f;
-
- index = fid_cur>>1;
- } else {
- /* Use startup FID */
- unsigned fid_start;
- msr = rdmsr(0xc0010015);
- fid_start = (msr.lo & (0x3f << 24));
-
- index = fid_start>>25;
- }
-
- if (index > 12) return divisor;
-
- if (i > 3) return divisor;
-
- return dv_a[index * 4+i];
-
-}
-
-
-struct spd_set_memclk_result {
- const struct mem_param *param;
- long dimm_mask;
-};
-
-
-static unsigned convert_to_linear(unsigned value)
-{
- static const unsigned fraction[] = { 0x25, 0x33, 0x66, 0x75 };
- unsigned valuex;
-
- /* We need to convert value to more readable */
- if ((value & 0xf) < 10) { //no .25, .33, .66, .75
- value <<= 4;
- } else {
- valuex = ((value & 0xf0) << 4) | fraction [(value & 0xf)-10];
- value = valuex;
- }
- return value;
-}
-
-static const uint8_t latency_indicies[] = { 25, 23, 9 };
-
-static int find_optimum_spd_latency(u32 spd_device, unsigned *min_latency, unsigned *min_cycle_time)
-{
- int new_cycle_time, new_latency;
- int index;
- int latencies;
- int latency;
-
- /* First find the supported CAS latencies
- * Byte 18 for DDR SDRAM is interpreted:
- * bit 3 == CAS Latency = 3
- * bit 4 == CAS Latency = 4
- * bit 5 == CAS Latency = 5
- * bit 6 == CAS Latency = 6
- */
- new_cycle_time = 0x500;
- new_latency = 6;
-
- latencies = spd_read_byte(spd_device, SPD_CAS_LAT);
- if (latencies <= 0)
- return 1;
-
- printk_raminit("\tlatencies: %08x\n", latencies);
- /* Compute the lowest cas latency which can be expressed in this
- * particular SPD EEPROM. You can store at most settings for 3
- * contiguous CAS latencies, so by taking the highest CAS
- * latency marked as supported in the SPD and subtracting 2 you
- * get the lowest expressible CAS latency. That latency is not
- * necessarily supported, but a (maybe invalid) entry exists
- * for it.
- */
- latency = log2(latencies) - 2;
-
- /* Loop through and find a fast clock with a low latency */
- for (index = 0; index < 3; index++, latency++) {
- int value;
- if ((latency < 3) || (latency > 6) ||
- (!(latencies & (1 << latency)))) {
- continue;
- }
- value = spd_read_byte(spd_device, latency_indicies[index]);
- if (value < 0) {
- return -1;
- }
-
- printk_raminit("\tindex: %08x\n", index);
- printk_raminit("\t\tlatency: %08x\n", latency);
- printk_raminit("\t\tvalue1: %08x\n", value);
-
- value = convert_to_linear(value);
-
- printk_raminit("\t\tvalue2: %08x\n", value);
-
- /* Only increase the latency if we decrease the clock */
- if (value >= *min_cycle_time) {
- if (value < new_cycle_time) {
- new_cycle_time = value;
- new_latency = latency;
- } else if (value == new_cycle_time) {
- if (new_latency > latency) {
- new_latency = latency;
- }
- }
- }
- printk_raminit("\t\tnew_cycle_time: %08x\n", new_cycle_time);
- printk_raminit("\t\tnew_latency: %08x\n", new_latency);
-
- }
-
- if (new_latency > 6) {
- return 1;
- }
-
- /* Does min_latency need to be increased? */
- if (new_cycle_time > *min_cycle_time) {
- *min_cycle_time = new_cycle_time;
- }
-
- /* Does min_cycle_time need to be increased? */
- if (new_latency > *min_latency) {
- *min_latency = new_latency;
- }
-
- printk_raminit("2 min_cycle_time: %08x\n", *min_cycle_time);
- printk_raminit("2 min_latency: %08x\n", *min_latency);
-
- return 0;
-}
-
-static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller *ctrl, struct mem_info *meminfo)
-{
- /* Compute the minimum cycle time for these dimms */
- struct spd_set_memclk_result result;
- unsigned min_cycle_time, min_latency, bios_cycle_time;
- int i;
- uint32_t value;
-
- static const uint16_t min_cycle_times[] = { // use full speed to compare
- [NBCAP_MEMCLK_NOLIMIT] = 0x250, /*2.5ns */
- [NBCAP_MEMCLK_333MHZ] = 0x300, /* 3.0ns */
- [NBCAP_MEMCLK_266MHZ] = 0x375, /* 3.75ns */
- [NBCAP_MEMCLK_200MHZ] = 0x500, /* 5.0s */
- };
-
-
- value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
- bios_cycle_time = min_cycle_times[
-#ifdef CMOS_VSTART_max_mem_clock
- read_option(max_mem_clock, 0)
-#else
-#if defined(CONFIG_MAX_MEM_CLOCK)
- CONFIG_MAX_MEM_CLOCK
-#else
- 0 // use DDR400 as default
-#endif
-#endif
- ];
-
- if (bios_cycle_time > min_cycle_time) {
- min_cycle_time = bios_cycle_time;
- }
- min_latency = 3;
-
- printk_raminit("1 min_cycle_time: %08x\n", min_cycle_time);
-
- /* Compute the least latency with the fastest clock supported
- * by both the memory controller and the dimms.
- */
- for (i = 0; i < DIMM_SOCKETS; i++) {
- u32 spd_device;
-
- printk_raminit("1.1 dimm_mask: %08x\n", meminfo->dimm_mask);
- printk_raminit("i: %08x\n",i);
-
- if (meminfo->dimm_mask & (1 << i)) {
- spd_device = ctrl->channel0[i];
- printk_raminit("Channel 0 settings:\n");
-
- switch (find_optimum_spd_latency(spd_device, &min_latency, &min_cycle_time)) {
- case -1:
- goto hw_error;
- break;
- case 1:
- continue;
- }
- }
- if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) {
- spd_device = ctrl->channel1[i];
- printk_raminit("Channel 1 settings:\n");
-
- switch (find_optimum_spd_latency(spd_device, &min_latency, &min_cycle_time)) {
- case -1:
- goto hw_error;
- break;
- case 1:
- continue;
- }
- }
-
- }
- /* Make a second pass through the dimms and disable
- * any that cannot support the selected memclk and cas latency.
- */
-
- printk_raminit("3 min_cycle_time: %08x\n", min_cycle_time);
- printk_raminit("3 min_latency: %08x\n", min_latency);
-
- for (i = 0; (i < DIMM_SOCKETS); i++) {
- int latencies;
- int latency;
- int index;
- int val;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(meminfo->dimm_mask & (1 << i))) {
- if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- } else {
- continue;
- }
- }
-
- latencies = spd_read_byte(spd_device, SPD_CAS_LAT);
- if (latencies < 0) goto hw_error;
- if (latencies == 0) {
- continue;
- }
-
- /* Compute the lowest cas latency supported */
- latency = log2(latencies) -2;
-
- /* Walk through searching for the selected latency */
- for (index = 0; index < 3; index++, latency++) {
- if (!(latencies & (1 << latency))) {
- continue;
- }
- if (latency == min_latency)
- break;
- }
- /* If I can't find the latency or my index is bad error */
- if ((latency != min_latency) || (index >= 3)) {
- goto dimm_err;
- }
-
- /* Read the min_cycle_time for this latency */
- val = spd_read_byte(spd_device, latency_indicies[index]);
- if (val < 0) goto hw_error;
-
- val = convert_to_linear(val);
- /* All is good if the selected clock speed
- * is what I need or slower.
- */
- if (val <= min_cycle_time) {
- continue;
- }
- /* Otherwise I have an error, disable the dimm */
- dimm_err:
- meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo);
- }
-
- printk_raminit("4 min_cycle_time: %08x\n", min_cycle_time);
-
- /* Now that I know the minimum cycle time lookup the memory parameters */
- result.param = get_mem_param(min_cycle_time);
-
- /* Update DRAM Config High with our selected memory speed */
- value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- value &= ~(DCH_MemClkFreq_MASK << DCH_MemClkFreq_SHIFT);
-
- value |= result.param->dch_memclk << DCH_MemClkFreq_SHIFT;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
-
- printk(BIOS_DEBUG, "%s\n", result.param->name);
-
- /* Update DRAM Timing Low with our selected cas latency */
- value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- value &= ~(DTL_TCL_MASK << DTL_TCL_SHIFT);
- value |= (min_latency - DTL_TCL_BASE) << DTL_TCL_SHIFT;
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, value);
-
- result.dimm_mask = meminfo->dimm_mask;
- return result;
- hw_error:
- result.param = (const struct mem_param *)0;
- result.dimm_mask = -1;
- return result;
-}
-
-static unsigned convert_to_1_4(unsigned value)
-{
- static const uint8_t fraction[] = { 0, 1, 2, 2, 3, 3, 0 };
- unsigned valuex;
-
- /* We need to convert value to more readable */
- valuex = fraction [value & 0x7];
- return valuex;
-}
-
-static int get_dimm_Trc_clocks(u32 spd_device, const struct mem_param *param)
-{
- int value;
- int value2;
- int clocks;
- value = spd_read_byte(spd_device, SPD_TRC);
- if (value < 0)
- return -1;
- printk_raminit("update_dimm_Trc: tRC (41) = %08x\n", value);
-
- value2 = spd_read_byte(spd_device, SPD_TRC -1);
- value <<= 2;
- value += convert_to_1_4(value2>>4);
-
- value *= 10;
- printk_raminit("update_dimm_Trc: tRC final value = %i\n", value);
-
- clocks = CEIL_DIV(value, param->divisor);
- printk_raminit("update_dimm_Trc: clocks = %i\n", clocks);
-
- if (clocks < DTL_TRC_MIN) {
- // We might want to die here instead or (at least|better) disable this bank.
- printk(BIOS_NOTICE, "update_dimm_Trc: Can't refresh fast enough, "
- "want %i clocks, minimum is %i clocks.\n", clocks, DTL_TRC_MIN);
- clocks = DTL_TRC_MIN;
- }
- return clocks;
-}
-
-static int update_dimm_Trc(const struct mem_controller *ctrl,
- const struct mem_param *param,
- int i, long dimm_mask)
-{
- int clocks, old_clocks;
- uint32_t dtl;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(dimm_mask & (1 << i)) && (dimm_mask & (1 << (DIMM_SOCKETS + i)))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- }
-
- clocks = get_dimm_Trc_clocks(spd_device, param);
- if (clocks == -1)
- return clocks;
- if (clocks > DTL_TRC_MAX) {
- return 0;
- }
- printk_raminit("update_dimm_Trc: clocks after adjustment = %i\n", clocks);
-
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRC_SHIFT) & DTL_TRC_MASK) + DTL_TRC_BASE;
- if (old_clocks >= clocks) { //?? someone did it
- // clocks = old_clocks;
- return 1;
- }
- dtl &= ~(DTL_TRC_MASK << DTL_TRC_SHIFT);
- dtl |= ((clocks - DTL_TRC_BASE) << DTL_TRC_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i, struct mem_info *meminfo)
-{
- unsigned clocks, old_clocks;
- uint32_t dth;
- int value;
- u8 ch_b = 0;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(meminfo->dimm_mask & (1 << i)) && (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i)))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- ch_b = 2; /* offset to channelB trfc setting */
- }
-
- //get the cs_size --> logic dimm size
- value = spd_read_byte(spd_device, SPD_PRI_WIDTH);
- if (value < 0) {
- return -1;
- }
-
- value = 6 - log2(value); //4-->4, 8-->3, 16-->2
-
- clocks = meminfo->sz[i].per_rank - 27 + 2 - value;
-
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-
- old_clocks = ((dth >> (DTH_TRFC0_SHIFT + ((i + ch_b) * 3))) & DTH_TRFC_MASK);
-
- if (old_clocks >= clocks) { // some one did it?
- return 1;
- }
- dth &= ~(DTH_TRFC_MASK << (DTH_TRFC0_SHIFT + ((i + ch_b) * 3)));
- dth |= clocks << (DTH_TRFC0_SHIFT + ((i + ch_b) * 3));
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
- return 1;
-}
-
-static int update_dimm_TT_1_4(const struct mem_controller *ctrl, const struct mem_param *param, int i, long dimm_mask,
- unsigned TT_REG,
- unsigned SPD_TT, unsigned TT_SHIFT, unsigned TT_MASK, unsigned TT_BASE, unsigned TT_MIN, unsigned TT_MAX)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(dimm_mask & (1 << i)) && (dimm_mask & (1 << (DIMM_SOCKETS + i)))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- }
-
- value = spd_read_byte(spd_device, SPD_TT); //already in 1/4 ns
- if (value < 0) return -1;
- value *=10;
- clocks = CEIL_DIV(value, param->divisor);
- if (clocks < TT_MIN) {
- clocks = TT_MIN;
- }
-
- if (clocks > TT_MAX) {
- printk(BIOS_INFO, "warning spd byte : %x = %x > TT_MAX: %x, setting TT_MAX", SPD_TT, value, TT_MAX);
- clocks = TT_MAX;
- }
-
- dtl = pci_read_config32(ctrl->f2, TT_REG);
-
- old_clocks = ((dtl >> TT_SHIFT) & TT_MASK) + TT_BASE;
- if (old_clocks >= clocks) { //some one did it?
- return 1;
- }
- dtl &= ~(TT_MASK << TT_SHIFT);
- dtl |= ((clocks - TT_BASE) << TT_SHIFT);
- pci_write_config32(ctrl->f2, TT_REG, dtl);
- return 1;
-}
-
-static int update_dimm_Trcd(const struct mem_controller *ctrl,
- const struct mem_param *param, int i, long dimm_mask)
-{
- return update_dimm_TT_1_4(ctrl, param, i, dimm_mask, DRAM_TIMING_LOW, SPD_TRCD, DTL_TRCD_SHIFT, DTL_TRCD_MASK, DTL_TRCD_BASE, DTL_TRCD_MIN, DTL_TRCD_MAX);
-}
-
-static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i, long dimm_mask)
-{
- return update_dimm_TT_1_4(ctrl, param, i, dimm_mask, DRAM_TIMING_LOW, SPD_TRRD, DTL_TRRD_SHIFT, DTL_TRRD_MASK, DTL_TRRD_BASE, DTL_TRRD_MIN, DTL_TRRD_MAX);
-}
-
-static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i, long dimm_mask)
-{
- unsigned clocks, old_clocks;
- uint32_t dtl;
- int value;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(dimm_mask & (1 << i)) && (dimm_mask & (1 << (DIMM_SOCKETS + i)))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- }
-
- value = spd_read_byte(spd_device, SPD_TRAS); //in 1 ns
- if (value < 0) return -1;
- printk_raminit("update_dimm_Tras: 0 value= %08x\n", value);
-
- value <<= 2; //convert it to in 1/4ns
-
- value *= 10;
- printk_raminit("update_dimm_Tras: 1 value= %08x\n", value);
-
- clocks = CEIL_DIV(value, param->divisor);
- printk_raminit("update_dimm_Tras: divisor= %08x\n", param->divisor);
- printk_raminit("update_dimm_Tras: clocks= %08x\n", clocks);
- if (clocks < DTL_TRAS_MIN) {
- clocks = DTL_TRAS_MIN;
- }
- if (clocks > DTL_TRAS_MAX) {
- return 0;
- }
- dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
- old_clocks = ((dtl >> DTL_TRAS_SHIFT) & DTL_TRAS_MASK) + DTL_TRAS_BASE;
- if (old_clocks >= clocks) { // someone did it?
- return 1;
- }
- dtl &= ~(DTL_TRAS_MASK << DTL_TRAS_SHIFT);
- dtl |= ((clocks - DTL_TRAS_BASE) << DTL_TRAS_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
- return 1;
-}
-
-static int update_dimm_Trp(const struct mem_controller *ctrl,
- const struct mem_param *param, int i, long dimm_mask)
-{
- return update_dimm_TT_1_4(ctrl, param, i, dimm_mask, DRAM_TIMING_LOW, SPD_TRP, DTL_TRP_SHIFT, DTL_TRP_MASK, DTL_TRP_BASE, DTL_TRP_MIN, DTL_TRP_MAX);
-}
-
-
-static int update_dimm_Trtp(const struct mem_controller *ctrl,
- const struct mem_param *param, int i, struct mem_info *meminfo)
-{
- /* need to figure if it is 32 byte burst or 64 bytes burst */
- int offset = 2;
- if (!meminfo->is_Width128) {
- uint32_t dword;
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- if ((dword & DCL_BurstLength32)) offset = 0;
- }
- return update_dimm_TT_1_4(ctrl, param, i, meminfo->dimm_mask, DRAM_TIMING_LOW, SPD_TRTP, DTL_TRTP_SHIFT, DTL_TRTP_MASK, DTL_TRTP_BASE+offset, DTL_TRTP_MIN+offset, DTL_TRTP_MAX+offset);
-}
-
-
-static int update_dimm_Twr(const struct mem_controller *ctrl, const struct mem_param *param, int i, long dimm_mask)
-{
- return update_dimm_TT_1_4(ctrl, param, i, dimm_mask, DRAM_TIMING_LOW, SPD_TWR, DTL_TWR_SHIFT, DTL_TWR_MASK, DTL_TWR_BASE, DTL_TWR_MIN, DTL_TWR_MAX);
-}
-
-
-static int update_dimm_Tref(const struct mem_controller *ctrl,
- const struct mem_param *param, int i, long dimm_mask)
-{
- uint32_t dth, dth_old;
- int value;
- u32 spd_device = ctrl->channel0[i];
-
- if (!(dimm_mask & (1 << i)) && (dimm_mask & (1 << (DIMM_SOCKETS + i)))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- }
-
- value = spd_read_byte(spd_device, SPD_TREF); // 0: 15.625us, 1: 3.9us 2: 7.8 us....
- if (value < 0) return -1;
-
- if (value == 1) {
- value = 3;
- } else {
- value = 2;
- }
-
- dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-
- dth_old = dth;
- dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
- dth |= (value << DTH_TREF_SHIFT);
- if (dth_old != dth) {
- pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
- }
- return 1;
-}
-
-static void set_4RankRDimm(const struct mem_controller *ctrl,
- const struct mem_param *param, struct mem_info *meminfo)
-{
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- int value;
- int i;
- long dimm_mask = meminfo->dimm_mask;
-
-
- if (!(meminfo->is_registered)) return;
-
- value = 0;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- if (!(dimm_mask & (1 << i))) {
- continue;
- }
-
- if (meminfo->sz[i].rank == 4) {
- value = 1;
- break;
- }
- }
-
- if (value == 1) {
- uint32_t dch;
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch |= DCH_FourRankRDimm;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
- }
-#endif
-}
-
-static uint32_t get_extra_dimm_mask(const struct mem_controller *ctrl,
- struct mem_info *meminfo)
-{
- int i;
-
- uint32_t mask_x4;
- uint32_t mask_x16;
- uint32_t mask_single_rank;
- uint32_t mask_page_1k;
- int value;
-#if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- int rank;
-#endif
-
- long dimm_mask = meminfo->dimm_mask;
-
-
- mask_x4 = 0;
- mask_x16 = 0;
- mask_single_rank = 0;
- mask_page_1k = 0;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- u32 spd_device = ctrl->channel0[i];
- if (!(dimm_mask & (1 << i))) {
- if (dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- } else {
- continue;
- }
- }
-
- if (meminfo->sz[i].rank == 1) {
- mask_single_rank |= 1<<i;
- }
-
- if (meminfo->sz[i].col == 10) {
- mask_page_1k |= 1<<i;
- }
-
-
- value = spd_read_byte(spd_device, SPD_PRI_WIDTH);
-
- #if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- rank = meminfo->sz[i].rank;
- #endif
-
- if (value == 4) {
- mask_x4 |= (1<<i);
- #if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (rank == 4) {
- mask_x4 |= 1<<(i+2);
- }
- #endif
- } else if (value == 16) {
- mask_x16 |= (1<<i);
- #if IS_ENABLED(CONFIG_QRANK_DIMM_SUPPORT)
- if (rank == 4) {
- mask_x16 |= 1<<(i+2);
- }
- #endif
- }
-
- }
-
- meminfo->x4_mask= mask_x4;
- meminfo->x16_mask = mask_x16;
-
- meminfo->single_rank_mask = mask_single_rank;
- meminfo->page_1k_mask = mask_page_1k;
-
- return mask_x4;
-
-}
-
-
-static void set_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
-{
- uint32_t dcl;
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~(DCL_X4Dimm_MASK<<DCL_X4Dimm_SHIFT);
- dcl |= ((meminfo->x4_mask) & 0xf) << (DCL_X4Dimm_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-}
-
-
-static int count_ones(uint32_t dimm_mask)
-{
- int dimms;
- unsigned index;
- dimms = 0;
- for (index = 0; index < (2 * DIMM_SOCKETS); index++, dimm_mask >>= 1) {
- if (dimm_mask & 1) {
- dimms++;
- }
- }
- return dimms;
-}
-
-
-static void set_DramTerm(const struct mem_controller *ctrl,
- const struct mem_param *param, struct mem_info *meminfo)
-{
- uint32_t dcl;
- unsigned odt;
- odt = 1; // 75 ohms
-
- if (param->divisor == 100) { //DDR2 800
- if (meminfo->is_Width128) {
- if (count_ones(meminfo->dimm_mask & 0x0f) == 2) {
- odt = 3; //50 ohms
- }
- }
-
- }
-
-
-#if CONFIG_DIMM_SUPPORT == 0x0204
- odt = 0x2; /* 150 ohms */
-#endif
-
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~(DCL_DramTerm_MASK<<DCL_DramTerm_SHIFT);
- dcl |= (odt & DCL_DramTerm_MASK) << (DCL_DramTerm_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-}
-
-static void set_ecc(const struct mem_controller *ctrl,
- const struct mem_param *param, struct mem_info *meminfo)
-{
- int i;
- int value;
-
- uint32_t dcl, nbcap;
- nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
- dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dcl &= ~DCL_DimmEccEn;
- if (nbcap & NBCAP_ECC) {
- dcl |= DCL_DimmEccEn;
- }
-#ifdef CMOS_VSTART_ECC_memory
- if (read_option(ECC_memory, 1) == 0) {
- dcl &= ~DCL_DimmEccEn;
- }
-#else // CMOS_VSTART_ECC_memory not defined
-#if 1 // was !IS_ENABLED CONFIG_ECC_MEMORY
- dcl &= ~DCL_DimmEccEn;
-#endif
-#endif
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-
- meminfo->is_ecc = 1;
- if (!(dcl & DCL_DimmEccEn)) {
- meminfo->is_ecc = 0;
- printk(BIOS_DEBUG, "set_ecc: ECC disabled\n");
- return; // already disabled the ECC, so don't need to read SPD any more
- }
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- u32 spd_device = ctrl->channel0[i];
- if (!(meminfo->dimm_mask & (1 << i))) {
- if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */
- spd_device = ctrl->channel1[i];
- printk(BIOS_DEBUG, "set_ecc spd_device: 0x%x\n", spd_device);
- } else {
- continue;
- }
- }
-
- value = spd_read_byte(ctrl->channel0[i], SPD_DIMM_CONF_TYPE);
-
- if (!(value & SPD_DIMM_CONF_TYPE_ECC)) {
- dcl &= ~DCL_DimmEccEn;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
- meminfo->is_ecc = 0;
- return;
- }
-
- }
-}
-
-
-static int update_dimm_Twtr(const struct mem_controller *ctrl,
- const struct mem_param *param, int i, long dimm_mask)
-{
- return update_dimm_TT_1_4(ctrl, param, i, dimm_mask, DRAM_TIMING_HIGH, SPD_TWTR, DTH_TWTR_SHIFT, DTH_TWTR_MASK, DTH_TWTR_BASE, DTH_TWTR_MIN, DTH_TWTR_MAX);
-}
-
-static void set_TT(const struct mem_controller *ctrl,
- const struct mem_param *param, unsigned TT_REG, unsigned TT_SHIFT,
- unsigned TT_MASK, unsigned TT_BASE, unsigned TT_MIN, unsigned TT_MAX,
- unsigned val, const char *str)
-{
- uint32_t reg;
-
- if ((val < TT_MIN) || (val > TT_MAX)) {
- printk(BIOS_ERR, "%s", str);
- die(" Unknown\n");
- }
-
- reg = pci_read_config32(ctrl->f2, TT_REG);
- reg &= ~(TT_MASK << TT_SHIFT);
- reg |= ((val - TT_BASE) << TT_SHIFT);
- pci_write_config32(ctrl->f2, TT_REG, reg);
- return;
-}
-
-
-static void set_TrwtTO(const struct mem_controller *ctrl,
- const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TRWTTO_SHIFT, DTH_TRWTTO_MASK,DTH_TRWTTO_BASE, DTH_TRWTTO_MIN, DTH_TRWTTO_MAX, param->TrwtTO, "TrwtTO");
-}
-
-
-static void set_Twrrd(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TWRRD_SHIFT, DTH_TWRRD_MASK,DTH_TWRRD_BASE, DTH_TWRRD_MIN, DTH_TWRRD_MAX, param->Twrrd, "Twrrd");
-}
-
-
-static void set_Twrwr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TWRWR_SHIFT, DTH_TWRWR_MASK,DTH_TWRWR_BASE, DTH_TWRWR_MIN, DTH_TWRWR_MAX, param->Twrwr, "Twrwr");
-}
-
-static void set_Trdrd(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TRDRD_SHIFT, DTH_TRDRD_MASK,DTH_TRDRD_BASE, DTH_TRDRD_MIN, DTH_TRDRD_MAX, param->Trdrd, "Trdrd");
-}
-
-static void set_DcqBypassMax(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_CONFIG_HIGH, DCH_DcqBypassMax_SHIFT, DCH_DcqBypassMax_MASK,DCH_DcqBypassMax_BASE, DCH_DcqBypassMax_MIN, DCH_DcqBypassMax_MAX, param->DcqByPassMax, "DcqBypassMax"); // value need to be in CMOS
-}
-
-static void set_Tfaw(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
-{
- static const uint8_t faw_1k[] = {8, 10, 13, 14};
- static const uint8_t faw_2k[] = {10, 14, 17, 18};
- unsigned memclkfreq_index;
- unsigned faw;
-
-
- memclkfreq_index = param->dch_memclk;
-
- if (meminfo->page_1k_mask != 0) { //1k page
- faw = faw_1k[memclkfreq_index];
- } else {
- faw = faw_2k[memclkfreq_index];
- }
-
- set_TT(ctrl, param, DRAM_CONFIG_HIGH, DCH_FourActWindow_SHIFT, DCH_FourActWindow_MASK, DCH_FourActWindow_BASE, DCH_FourActWindow_MIN, DCH_FourActWindow_MAX, faw, "FourActWindow");
-}
-
-static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
-{
- uint32_t dch;
- unsigned async_lat;
-
-
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dch &= ~(DCH_MaxAsyncLat_MASK << DCH_MaxAsyncLat_SHIFT);
-
- //FIXME: We need to use Max of DqsRcvEnDelay + 6ns here: After training and get that from index reg 0x10, 0x13, 0x16, 0x19, 0x30, 0x33, 0x36, 0x39
- async_lat = 6 + 6;
-
-
- dch |= ((async_lat - DCH_MaxAsyncLat_BASE) << DCH_MaxAsyncLat_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-#if (CONFIG_DIMM_SUPPORT & 0x0100) == 0x0000 /* 2T mode only used for unbuffered DIMM */
-static void set_SlowAccessMode(const struct mem_controller *ctrl)
-{
- uint32_t dch;
-
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-
- dch |= (1<<20);
-
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-#endif
-
-/*
- DRAM_OUTPUT_DRV_COMP_CTRL 0, 0x20
- DRAM_ADDR_TIMING_CTRL 04, 0x24
-*/
-static void set_misc_timing(const struct mem_controller *ctrl, struct mem_info *meminfo)
-{
- uint32_t dword;
- uint32_t dwordx;
-#if (CONFIG_DIMM_SUPPORT & 0x0100) == 0x0000 /* 2T mode only used for unbuffered DIMM */
- unsigned SlowAccessMode = 0;
-#endif
-
-#if CONFIG_DIMM_SUPPORT == 0x0104 /* DDR2 and REG */
- long dimm_mask = meminfo->dimm_mask & 0x0f;
- /* for REG DIMM */
- dword = 0x00111222;
- dwordx = 0x002f0000;
- switch (meminfo->memclk_set) {
- case DCH_MemClkFreq_266MHz:
- if ((dimm_mask == 0x03) || (dimm_mask == 0x02) || (dimm_mask == 0x01)) {
- dwordx = 0x002f2700;
- }
- break;
- case DCH_MemClkFreq_333MHz:
- if ((dimm_mask == 0x03) || (dimm_mask == 0x02) || (dimm_mask == 0x01)) {
- if ((meminfo->single_rank_mask & 0x03)!=0x03) { //any double rank there?
- dwordx = 0x002f2f00;
- }
- }
- break;
- case DCH_MemClkFreq_400MHz:
- dwordx = 0x002f3300;
- break;
- }
-
-#endif
-
-#if CONFIG_DIMM_SUPPORT == 0x0204 /* DDR2 and SO-DIMM, S1G1 */
- dword = 0x00111222;
- dwordx = 0x002F2F00;
-
- switch (meminfo->memclk_set) {
- case DCH_MemClkFreq_200MHz: /* nothing to be set here */
- break;
- case DCH_MemClkFreq_266MHz:
- if ((meminfo->single_rank_mask == 0)
- && (meminfo->x4_mask == 0) && (meminfo->x16_mask))
- dwordx = 0x002C2C00; /* Double rank x8 */
- /* else SRx16, SRx8, DRx16 == 0x002F2F00 */
- break;
- case DCH_MemClkFreq_333MHz:
- if ((meminfo->single_rank_mask == 1)
- && (meminfo->x16_mask == 1)) /* SR x16 */
- dwordx = 0x00272700;
- else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0)
- && (meminfo->single_rank_mask == 0)) { /* DR x8 */
- SlowAccessMode = 1;
- dwordx = 0x00002800;
- } else { /* SR x8, DR x16 */
- dwordx = 0x002A2A00;
- }
- break;
- case DCH_MemClkFreq_400MHz:
- if ((meminfo->single_rank_mask == 1)
- && (meminfo->x16_mask == 1)) /* SR x16 */
- dwordx = 0x00292900;
- else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0)
- && (meminfo->single_rank_mask == 0)) { /* DR x8 */
- SlowAccessMode = 1;
- dwordx = 0x00002A00;
- } else { /* SR x8, DR x16 */
- dwordx = 0x002A2A00;
- }
- break;
- }
-#endif
-
-#if CONFIG_DIMM_SUPPORT == 0x0004 /* DDR2 and unbuffered */
- long dimm_mask = meminfo->dimm_mask & 0x0f;
- /* for UNBUF DIMM */
- dword = 0x00111222;
- dwordx = 0x002f2f00;
- switch (meminfo->memclk_set) {
- case DCH_MemClkFreq_200MHz:
- if (dimm_mask == 0x03) {
- SlowAccessMode = 1;
- dword = 0x00111322;
- }
- break;
- case DCH_MemClkFreq_266MHz:
- if (dimm_mask == 0x03) {
- SlowAccessMode = 1;
- dword = 0x00111322;
- if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0)) {
- switch (meminfo->single_rank_mask) {
- case 0x03:
- dwordx = 0x00002f00; //x8 single Rank
- break;
- case 0x00:
- dwordx = 0x00342f00; //x8 double Rank
- break;
- default:
- dwordx = 0x00372f00; //x8 single Rank and double Rank mixed
- }
- } else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x01) && (meminfo->single_rank_mask == 0x01)) {
- dwordx = 0x00382f00; //x8 Double Rank and x16 single Rank mixed
- } else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x02) && (meminfo->single_rank_mask == 0x02)) {
- dwordx = 0x00382f00; //x16 single Rank and x8 double Rank mixed
- }
-
- } else {
- if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x00) && ((meminfo->single_rank_mask == 0x01)||(meminfo->single_rank_mask == 0x02))) { //x8 single rank
- dwordx = 0x002f2f00;
- } else {
- dwordx = 0x002b2f00;
- }
- }
- break;
- case DCH_MemClkFreq_333MHz:
- dwordx = 0x00202220;
- if (dimm_mask == 0x03) {
- SlowAccessMode = 1;
- dword = 0x00111322;
- if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0)) {
- switch (meminfo->single_rank_mask) {
- case 0x03:
- dwordx = 0x00302220; //x8 single Rank
- break;
- case 0x00:
- dwordx = 0x002b2220; //x8 double Rank
- break;
- default:
- dwordx = 0x002a2220; //x8 single Rank and double Rank mixed
- }
- } else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x01) && (meminfo->single_rank_mask == 0x01)) {
- dwordx = 0x002c2220; //x8 Double Rank and x16 single Rank mixed
- } else if ((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x02) && (meminfo->single_rank_mask == 0x02)) {
- dwordx = 0x002c2220; //x16 single Rank and x8 double Rank mixed
- }
- }
- break;
- case DCH_MemClkFreq_400MHz:
- dwordx = 0x00202520;
- SlowAccessMode = 1;
- if (dimm_mask == 0x03) {
- dword = 0x00113322;
- } else {
- dword = 0x00113222;
- }
- break;
- }
-
- printk_raminit("\tdimm_mask = %08x\n", meminfo->dimm_mask);
- printk_raminit("\tx4_mask = %08x\n", meminfo->x4_mask);
- printk_raminit("\tx16_mask = %08x\n", meminfo->x16_mask);
- printk_raminit("\tsingle_rank_mask = %08x\n", meminfo->single_rank_mask);
- printk_raminit("\tODC = %08x\n", dword);
- printk_raminit("\tAddr Timing= %08x\n", dwordx);
-#endif
-
-#if (CONFIG_DIMM_SUPPORT & 0x0100) == 0x0000 /* 2T mode only used for unbuffered DIMM */
- if (SlowAccessMode) {
- set_SlowAccessMode(ctrl);
- }
-#endif
-
- if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */
- /* Program the Output Driver Compensation Control Registers (Function 2:Offset 0x9c, index 0, 0x20) */
- pci_write_config32_index_wait(ctrl->f2, 0x98, 0x20, dword);
-
- /* Program the Address Timing Control Registers (Function 2:Offset 0x9c, index 4, 0x24) */
- pci_write_config32_index_wait(ctrl->f2, 0x98, 0x24, dwordx);
- } else {
- /* Program the Output Driver Compensation Control Registers (Function 2:Offset 0x9c, index 0, 0x20) */
- pci_write_config32_index_wait(ctrl->f2, 0x98, 0, dword);
- if (meminfo->is_Width128) {
- pci_write_config32_index_wait(ctrl->f2, 0x98, 0x20, dword);
- }
-
- /* Program the Address Timing Control Registers (Function 2:Offset 0x9c, index 4, 0x24) */
- pci_write_config32_index_wait(ctrl->f2, 0x98, 4, dwordx);
- if (meminfo->is_Width128) {
- pci_write_config32_index_wait(ctrl->f2, 0x98, 0x24, dwordx);
- }
- }
-}
-
-
-static void set_RDqsEn(const struct mem_controller *ctrl,
- const struct mem_param *param, struct mem_info *meminfo)
-{
-#if CONFIG_CPU_SOCKET_TYPE == 0x10
- //only need to set for reg and x8
- uint32_t dch;
-
- dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-
- dch &= ~DCH_RDqsEn;
- if ((!meminfo->x4_mask) && (!meminfo->x16_mask)) {
- dch |= DCH_RDqsEn;
- }
-
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-#endif
-}
-
-static void set_idle_cycle_limit(const struct mem_controller *ctrl,
- const struct mem_param *param)
-{
- uint32_t dcm;
- /* AMD says to Hardcode this */
- dcm = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
- dcm &= ~(DCM_ILD_lmt_MASK << DCM_ILD_lmt_SHIFT);
- dcm |= DCM_ILD_lmt_16 << DCM_ILD_lmt_SHIFT;
- dcm |= DCM_DCC_EN;
- pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dcm);
-}
-
-static void set_RdWrQByp(const struct mem_controller *ctrl,
- const struct mem_param *param)
-{
- set_TT(ctrl, param, DRAM_CTRL_MISC, DCM_RdWrQByp_SHIFT, DCM_RdWrQByp_MASK,0, 0, 3, 2, "RdWrQByp");
-}
-
-static long spd_set_dram_timing(const struct mem_controller *ctrl,
- const struct mem_param *param,
- struct mem_info *meminfo)
-{
- int i;
-
- for (i = 0; i < DIMM_SOCKETS; i++) {
- int rc;
- if (!(meminfo->dimm_mask & (1 << i)) &&
- !(meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i)))) {
- continue;
- }
- printk_raminit("spd_set_dram_timing dimm socket: %08x\n", i);
- /* DRAM Timing Low Register */
- printk_raminit("\ttrc\n");
- if ((rc = update_dimm_Trc (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttrcd\n");
- if ((rc = update_dimm_Trcd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttrrd\n");
- if ((rc = update_dimm_Trrd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttras\n");
- if ((rc = update_dimm_Tras(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttrp\n");
- if ((rc = update_dimm_Trp (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttrtp\n");
- if ((rc = update_dimm_Trtp(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
-
- printk_raminit("\ttwr\n");
- if ((rc = update_dimm_Twr (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- /* DRAM Timing High Register */
- printk_raminit("\ttref\n");
- if ((rc = update_dimm_Tref(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttwtr\n");
- if ((rc = update_dimm_Twtr(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
-
- printk_raminit("\ttrfc\n");
- if ((rc = update_dimm_Trfc(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
-
- /* DRAM Config Low */
-
- continue;
- dimm_err:
- printk(BIOS_DEBUG, "spd_set_dram_timing dimm_err!\n");
- if (rc < 0) {
- return -1;
- }
- meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo);
- }
-
- get_extra_dimm_mask(ctrl, meminfo); // will be used by RDqsEn and dimm_x4
- /* DRAM Timing Low Register */
-
- /* DRAM Timing High Register */
- set_TrwtTO(ctrl, param);
- set_Twrrd (ctrl, param);
- set_Twrwr (ctrl, param);
- set_Trdrd (ctrl, param);
-
- set_4RankRDimm(ctrl, param, meminfo);
-
- /* DRAM Config High */
- set_Tfaw(ctrl, param, meminfo);
- set_DcqBypassMax(ctrl, param);
- set_max_async_latency(ctrl, param);
- set_RDqsEn(ctrl, param, meminfo);
-
- /* DRAM Config Low */
- set_ecc(ctrl, param, meminfo);
- set_dimm_x4(ctrl, param, meminfo);
- set_DramTerm(ctrl, param, meminfo);
-
- /* DRAM Control Misc */
- set_idle_cycle_limit(ctrl, param);
- set_RdWrQByp(ctrl, param);
-
- return meminfo->dimm_mask;
-}
-
-void sdram_set_spd_registers(const struct mem_controller *ctrl,
- struct sys_info *sysinfo)
-{
- struct spd_set_memclk_result result;
- const struct mem_param *param;
- struct mem_param paramx;
- struct mem_info *meminfo;
-#if 1
- if (!sysinfo->ctrl_present[ctrl->node_id]) {
- return;
- }
-#endif
- meminfo = &sysinfo->meminfo[ctrl->node_id];
-
- printk(BIOS_DEBUG, "sdram_set_spd_registers: paramx :%p\n", &paramx);
-
- activate_spd_rom(ctrl);
- meminfo->dimm_mask = spd_detect_dimms(ctrl);
-
- printk_raminit("sdram_set_spd_registers: dimm_mask=0x%x\n", meminfo->dimm_mask);
-
- if (!(meminfo->dimm_mask & ((1 << 2*DIMM_SOCKETS) - 1)))
- {
- printk(BIOS_DEBUG, "No memory for this cpu\n");
- return;
- }
- meminfo->dimm_mask = spd_enable_2channels(ctrl, meminfo);
- printk_raminit("spd_enable_2channels: dimm_mask=0x%x\n", meminfo->dimm_mask);
- if (meminfo->dimm_mask == -1)
- goto hw_spd_err;
-
- meminfo->dimm_mask = spd_set_ram_size(ctrl, meminfo);
- printk_raminit("spd_set_ram_size: dimm_mask=0x%x\n", meminfo->dimm_mask);
- if (meminfo->dimm_mask == -1)
- goto hw_spd_err;
-
- meminfo->dimm_mask = spd_handle_unbuffered_dimms(ctrl, meminfo);
- printk_raminit("spd_handle_unbuffered_dimms: dimm_mask=0x%x\n", meminfo->dimm_mask);
- if (meminfo->dimm_mask == -1)
- goto hw_spd_err;
-
- result = spd_set_memclk(ctrl, meminfo);
- param = result.param;
- meminfo->dimm_mask = result.dimm_mask;
- printk_raminit("spd_set_memclk: dimm_mask=0x%x\n", meminfo->dimm_mask);
- if (meminfo->dimm_mask == -1)
- goto hw_spd_err;
-
- //store memclk set to sysinfo, in case we need rebuilt param again
- meminfo->memclk_set = param->dch_memclk;
-
- memcpy(&paramx, param, sizeof(paramx));
-
- paramx.divisor = get_exact_divisor(param->dch_memclk, paramx.divisor);
-
- meminfo->dimm_mask = spd_set_dram_timing(ctrl, &paramx, meminfo);
- printk_raminit("spd_set_dram_timing: dimm_mask=0x%x\n", meminfo->dimm_mask);
- if (meminfo->dimm_mask == -1)
- goto hw_spd_err;
-
- order_dimms(ctrl, meminfo);
-
- return;
- hw_spd_err:
- /* Unrecoverable error reading SPD data */
- die("Unrecoverable error reading SPD data. No qualified DIMMs?");
- return;
-}
-
-#include "raminit_f_dqs.c"
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
-static uint32_t hoist_memory(int controllers, const struct mem_controller *ctrl,unsigned hole_startk, int i)
-{
- int ii;
- uint32_t carry_over;
- pci_devfn_t dev;
- uint32_t base, limit;
- uint32_t basek;
- uint32_t hoist;
- int j;
-
- carry_over = (4*1024*1024) - hole_startk;
-
- for (ii = controllers - 1; ii > i; ii--) {
- base = pci_read_config32(ctrl[0].f1, 0x40 + (ii << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (ii << 3));
- limit += (carry_over << 2);
- base += (carry_over << 2);
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x44 + (ii << 3), limit);
- pci_write_config32(ctrl[j].f1, 0x40 + (ii << 3), base);
- }
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
- limit += (carry_over << 2);
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x44 + (i << 3), limit);
- }
- dev = ctrl[i].f1;
- base = pci_read_config32(dev, 0x40 + (i << 3));
- basek = (base & 0xffff0000) >> 2;
- if (basek == hole_startk) {
- //don't need set memhole here, because hole off set will be 0, overflow
- //so need to change base reg instead, new basek will be 4*1024*1024
- base &= 0x0000ffff;
- base |= (4*1024*1024)<<2;
- for (j = 0; j < controllers; j++) {
- pci_write_config32(ctrl[j].f1, 0x40 + (i<<3), base);
- }
- } else {
- hoist = /* hole start address */
- ((hole_startk << 10) & 0xff000000) +
- /* hole address to memory controller address */
- (((basek + carry_over) >> 6) & 0x0000ff00) +
- /* enable */
- 1;
- pci_write_config32(dev, 0xf0, hoist);
- }
-
- return carry_over;
-}
-
-void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl)
-{
-
- uint32_t hole_startk;
- int i;
-
- hole_startk = 4*1024*1024 - CONFIG_HW_MEM_HOLE_SIZEK;
-
- printk_raminit("Handling memory hole at 0x%08x (default)\n", hole_startk);
-#if IS_ENABLED(CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC)
- /* We need to double check if the hole_startk is valid, if it is equal
- to basek, we need to decrease it some */
- uint32_t basek_pri;
- for (i = 0; i < controllers; i++) {
- uint32_t base;
- unsigned base_k;
- base = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- base_k = (base & 0xffff0000) >> 2;
- if (base_k == hole_startk) {
- /* decrease mem hole startk to make sure it is
- on middle of previous node */
- hole_startk -= (base_k - basek_pri) >> 1;
- break; //only one hole
- }
- basek_pri = base_k;
- }
- printk_raminit("Handling memory hole at 0x%08x (adjusted)\n", hole_startk);
-#endif
- /* find node index that need do set hole */
- for (i = 0; i < controllers; i++) {
- uint32_t base, limit;
- unsigned base_k, limit_k;
- base = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
- if ((base & ((1 << 1) | (1 << 0))) != ((1 << 1) | (1 << 0))) {
- continue;
- }
- limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
- base_k = (base & 0xffff0000) >> 2;
- limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
- if ((base_k <= hole_startk) && (limit_k > hole_startk)) {
- unsigned end_k;
- hoist_memory(controllers, ctrl, hole_startk, i);
- end_k = memory_end_k(ctrl, controllers);
- set_top_mem(end_k, hole_startk);
- break; //only one hole
- }
- }
-
-}
-#endif
-
-void sdram_enable(int controllers, const struct mem_controller *ctrl,
- struct sys_info *sysinfo)
-{
- int i;
- int suspend = acpi_is_wakeup_s3();
-
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- unsigned cpu_f0_f1[8];
- /* FIXME: How about 32 node machine later? */
- tsc_t tsc, tsc0[8];
-
- printk(BIOS_DEBUG, "sdram_enable: tsc0[8]: %p", &tsc0[0]);
- uint32_t dword;
-#endif
-
- /* Error if I don't have memory */
- if (memory_end_k(ctrl, controllers) == 0) {
- die("No memory\n");
- }
-
- /* Before enabling memory start the memory clocks */
- for (i = 0; i < controllers; i++) {
- uint32_t dch;
- if (!sysinfo->ctrl_present[ i ])
- continue;
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
-
- /* if no memory installed, disabled the interface */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) {
- dch |= DCH_DisDramInterface;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
-
- } else {
- dch |= DCH_MemClkFreqVal;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
- /* address timing and Output driver comp Control */
- set_misc_timing(ctrl+i, sysinfo->meminfo+i);
- }
- }
-
- /* We need to wait a minimum of 20 MEMCLKS to enable the InitDram */
- memreset(controllers, ctrl);
-
- /* lets override the rest of the routine */
- if (suspend) {
- printk(BIOS_DEBUG, "Wakeup!\n");
- exit_from_self(controllers, ctrl, sysinfo);
- printk(BIOS_DEBUG, "Mem running !\n");
- return;
- }
-
- for (i = 0; i < controllers; i++) {
- uint32_t dcl, dch;
- if (!sysinfo->ctrl_present[ i ])
- continue;
- /* Skip everything if I don't have any memory on this controller */
- dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
- if (!(dch & DCH_MemClkFreqVal)) {
- continue;
- }
-
- /* ChipKill */
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- if (dcl & DCL_DimmEccEn) {
- uint32_t mnc;
- printk(BIOS_SPEW, "ECC enabled\n");
- mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
- mnc |= MNC_ECC_EN;
- if (dcl & DCL_Width128) {
- mnc |= MNC_CHIPKILL_EN;
- }
- pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
- }
-
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- cpu_f0_f1[i] = is_cpu_pre_f2_in_bsp(i);
- if (cpu_f0_f1[i]) {
- //Rev F0/F1 workaround
-#if 1
- /* Set the DqsRcvEnTrain bit */
- dword = pci_read_config32(ctrl[i].f2, DRAM_CTRL);
- dword |= DC_DqsRcvEnTrain;
- pci_write_config32(ctrl[i].f2, DRAM_CTRL, dword);
-#endif
- tsc0[i] = rdtsc();
- }
-#endif
-
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
- dcl |= DCL_InitDram;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
- }
-
- for (i = 0; i < controllers; i++) {
- uint32_t dcl, dcm;
- if (!sysinfo->ctrl_present[ i ])
- continue;
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- printk(BIOS_DEBUG, "Initializing memory: ");
- int loops = 0;
- do {
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- loops++;
- if ((loops & 1023) == 0) {
- printk(BIOS_DEBUG, ".");
- }
- } while (((dcl & DCL_InitDram) != 0) && (loops < TIMEOUT_LOOPS));
- if (loops >= TIMEOUT_LOOPS) {
- printk(BIOS_DEBUG, " failed\n");
- continue;
- }
-
- /* Wait until it is safe to touch memory */
- do {
- dcm = pci_read_config32(ctrl[i].f2, DRAM_CTRL_MISC);
- } while (((dcm & DCM_MemClrStatus) == 0) /* || ((dcm & DCM_DramEnabled) == 0)*/);
-
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- if (cpu_f0_f1[i]) {
- tsc= rdtsc();
-
- print_debug_dqs_tsc("\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2);
- print_debug_dqs_tsc("end tsc ", i, tsc.hi, tsc.lo, 2);
-
- if (tsc.lo < tsc0[i].lo) {
- tsc.hi--;
- }
- tsc.lo -= tsc0[i].lo;
- tsc.hi -= tsc0[i].hi;
-
- tsc0[i].lo = tsc.lo;
- tsc0[i].hi = tsc.hi;
-
- print_debug_dqs_tsc(" dtsc0", i, tsc0[i].hi, tsc0[i].lo, 2);
- }
-#endif
- printk(BIOS_DEBUG, " done\n");
- }
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- /* init hw mem hole here */
- /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
- set_hw_mem_hole(controllers, ctrl);
-#endif
-
- /* store tom to sysinfo, and it will be used by dqs_timing */
- {
- msr_t msr;
- //[1M, TOM)
- msr = rdmsr(TOP_MEM);
- sysinfo->tom_k = ((msr.hi<<24) | (msr.lo>>8))>>2;
-
- //[4G, TOM2)
- msr = rdmsr(TOP_MEM2);
- sysinfo->tom2_k = ((msr.hi<<24)| (msr.lo>>8))>>2;
- }
-
- for (i = 0; i < controllers; i++) {
- sysinfo->mem_trained[i] = 0;
-
- if (!sysinfo->ctrl_present[ i ])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00)
- continue;
-
- sysinfo->mem_trained[i] = 0x80; // mem need to be trained
- }
-
-
-#if CONFIG_MEM_TRAIN_SEQ == 0
- #if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- dqs_timing(controllers, ctrl, tsc0, sysinfo);
- #else
- dqs_timing(controllers, ctrl, sysinfo);
- #endif
-#else
-
-#if CONFIG_MEM_TRAIN_SEQ == 2
- /* need to enable mtrr, so dqs training could access the test address */
- setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
-#endif
-
- for (i = 0; i < controllers; i++) {
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->mem_trained[i]!=0x80)
- continue;
-
- dqs_timing(i, &ctrl[i], sysinfo, 1);
-
-#if CONFIG_MEM_TRAIN_SEQ == 1
- break; // only train the first node with ram
-#endif
- }
-
-#if CONFIG_MEM_TRAIN_SEQ == 2
- clear_mtrr_dqs(sysinfo->tom2_k);
-#endif
-
-#endif
-
-#if CONFIG_MEM_TRAIN_SEQ != 1
- wait_all_core0_mem_trained(sysinfo);
-#endif
-
-}
-
-void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a,
- const uint16_t *spd_addr)
-{
- int i;
- int j;
- struct mem_controller *ctrl;
- for (i = 0; i < controllers; i++) {
- ctrl = &ctrl_a[i];
- ctrl->node_id = i;
- ctrl->f0 = PCI_DEV(0, 0x18+i, 0);
- ctrl->f1 = PCI_DEV(0, 0x18+i, 1);
- ctrl->f2 = PCI_DEV(0, 0x18+i, 2);
- ctrl->f3 = PCI_DEV(0, 0x18+i, 3);
-
- if (spd_addr == (void *)0) continue;
-
- for (j = 0; j < DIMM_SOCKETS; j++) {
- ctrl->channel0[j] = spd_addr[(i*2+0)*DIMM_SOCKETS + j];
- ctrl->channel1[j] = spd_addr[(i*2+1)*DIMM_SOCKETS + j];
- }
- }
-}
diff --git a/src/northbridge/amd/amdk8/raminit_f_dqs.c b/src/northbridge/amd/amdk8/raminit_f_dqs.c
deleted file mode 100644
index 1573ce1899..0000000000
--- a/src/northbridge/amd/amdk8/raminit_f_dqs.c
+++ /dev/null
@@ -1,2058 +0,0 @@
-/*
- * 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.
-*/
-
-#include <arch/stages.h>
-#include <cpu/x86/cr.h>
-#include <cpu/x86/mtrr.h>
-#include <arch/early_variables.h>
-#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700)
-#include <southbridge/amd/sb700/sb700.h>
-#endif
-
-//0: mean no debug info
-#define DQS_TRAIN_DEBUG 0
-
-static inline void print_debug_dqs(const char *str, unsigned val, unsigned level)
-{
-#if DQS_TRAIN_DEBUG > 0
- if (DQS_TRAIN_DEBUG > level) {
- printk(BIOS_DEBUG, "%s%x\n", str, val);
- }
-#endif
-}
-
-static inline void print_debug_dqs_pair(const char *str, unsigned val, const char *str2, unsigned val2, unsigned level)
-{
-#if DQS_TRAIN_DEBUG > 0
- if (DQS_TRAIN_DEBUG > level) {
- printk(BIOS_DEBUG, "%s%08x%s%08x\n", str, val, str2, val2);
- }
-#endif
-}
-
-static inline void print_debug_dqs_tsc(const char *str, unsigned i, unsigned val, unsigned val2, unsigned level)
-{
-#if DQS_TRAIN_DEBUG > 0
- if (DQS_TRAIN_DEBUG > level) {
- printk(BIOS_DEBUG, "%s[%02x]=%08x%08x\n", str, i, val, val2);
- }
-#endif
-}
-
-static inline void print_debug_dqs_tsc_x(const char *str, unsigned i, unsigned val, unsigned val2)
-{
- printk(BIOS_DEBUG, "%s[%02x]=%08x%08x\n", str, i, val, val2);
-
-}
-
-static void fill_mem_cs_sysinfo(unsigned nodeid, const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
-
- int i;
- sysinfo->mem_base[nodeid] = pci_read_config32(ctrl->f1, 0x40 + (nodeid << 3));
-
- for (i = 0; i < 8; i++) {
- sysinfo->cs_base[nodeid*8+i] = pci_read_config32(ctrl->f2, 0x40 + (i << 2));
- }
-
- sysinfo->hole_reg[nodeid] = pci_read_config32(ctrl->f1, 0xf0);
-
-}
-static unsigned Get_MCTSysAddr(const struct mem_controller *ctrl, unsigned cs_idx, struct sys_info *sysinfo)
-{
- uint32_t dword;
- uint32_t mem_base;
- unsigned nodeid = ctrl->node_id;
-
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- uint32_t hole_reg;
-#endif
-
- //get the local base addr of the chipselect
- dword = sysinfo->cs_base[nodeid * 8 + cs_idx];
- dword &= 0xfffffff0;
-
- //sys addr= node base + local cs base
- mem_base = sysinfo->mem_base[nodeid];
- mem_base &= 0xffff0000;
-
- dword += mem_base;
-#if CONFIG_HW_MEM_HOLE_SIZEK != 0
- hole_reg = sysinfo->hole_reg[nodeid];
- if (hole_reg & 1) {
- unsigned hole_startk;
- hole_startk = (hole_reg & (0xff << 24)) >> 10;
- if ((dword >= (hole_startk << 2)) && (dword < ((4*1024*1024) << 2))) {
- dword += ((4*1024*1024 - hole_startk) << 2);
- }
- }
-#endif
-
- //add 1MB offset to avoid compat area
- dword += (1<<(20-8));
-
- //So final result is upper 32 bit addr
-
- return dword;
-
-}
-
-static unsigned Get_RcvrSysAddr(const struct mem_controller * ctrl, unsigned channel, unsigned cs_idx, struct sys_info *sysinfo)
-{
- return Get_MCTSysAddr(ctrl, cs_idx, sysinfo);
-
-}
-
-static inline void enable_sse2(void)
-{
- unsigned long cr4;
- cr4 = read_cr4();
- cr4 |= (1<<9);
- write_cr4(cr4);
-}
-
-static inline void disable_sse2(void)
-{
- unsigned long cr4;
- cr4 = read_cr4();
- cr4 &= ~(1<<9);
- write_cr4(cr4);
-}
-
-
-static void set_wrap32dis(void) {
- msr_t msr;
-
- msr = rdmsr(0xc0010015);
- msr.lo |= (1<<17);
-
- wrmsr(0xc0010015, msr);
-
-}
-
-static void clear_wrap32dis(void) {
- msr_t msr;
-
- msr = rdmsr(0xc0010015);
- msr.lo &= ~(1<<17);
-
- wrmsr(0xc0010015, msr);
-
-}
-
-static void set_FSBASE(uint32_t addr_hi)
-{
- msr_t msr;
-
- //set fs and use fs prefix to access the mem
- msr.hi = addr_hi;
- msr.lo = 0;
- wrmsr(0xc0000100, msr); //FS_BASE
-
-}
-
-static unsigned ChipSelPresent(const struct mem_controller *ctrl, unsigned cs_idx, struct sys_info *sysinfo)
-{
- unsigned enabled;
- unsigned nodeid = ctrl->node_id;
-
-
- enabled = sysinfo->cs_base[nodeid * 8 + cs_idx];
- enabled &= 1;
-
- return enabled;
-
-}
-
-static unsigned RcvrRankEnabled(const struct mem_controller *ctrl, int channel, int cs_idx, unsigned is_Width128, struct sys_info *sysinfo)
-{
- return ChipSelPresent(ctrl, cs_idx, sysinfo);
-}
-
-static void WriteLNTestPattern(unsigned addr_lo, uint8_t *buf_a, unsigned line_num)
-{
- __asm__ volatile (
- "1:\n\t"
- "movdqa (%3), %%xmm0\n\t"
- "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
- "addl %1, %0\n\t"
- "addl %1, %3\n\t"
- "loop 1b\n\t"
-
- :: "a" (addr_lo), "d" (16), "c" (line_num * 4), "b"(buf_a)
- );
-
-
-}
-
-static void Write1LTestPattern(unsigned addr, unsigned p, uint8_t *buf_a, uint8_t *buf_b)
-{
- uint8_t *buf;
- if (p == 1) { buf = buf_b; }
- else { buf = buf_a; }
-
- set_FSBASE (addr >> 24);
-
- WriteLNTestPattern(addr << 8, buf, 1);
-}
-
-static void Read1LTestPattern(unsigned addr)
-{
- unsigned value;
-
- set_FSBASE(addr>>24);
-
- /* 1st move causes read fill (to exclusive or shared)*/
- __asm__ volatile (
- "movl %%fs:(%1), %0\n\t"
- :"=b"(value): "a" (addr << 8)
- );
-
-}
-
-#define DQS_PASS 0
-#define DQS_FAIL 1
-
-#define DQS_FIRST_PASS 1
-#define DQS_SECOND_PASS 2
-
-#define SB_NORCVREN 11
-#define RCVREN_MARGIN 6
-#define SB_SmallRCVR 13
-#define SB_CHA2BRCVREN 12
-#define SB_NODQSPOS 14
-#define MIN_DQS_WNDW 3
-#define SB_SMALLDQS 15
-
-
-static unsigned CompareTestPatternQW0(unsigned channel, unsigned addr, unsigned pattern, const uint32_t *TestPattern0, const uint32_t *TestPattern1, const uint32_t *TestPattern2, unsigned Pass, unsigned is_Width128)
-{
- uint32_t addr_lo;
- uint32_t *test_buf;
- uint32_t value;
- uint32_t value_test;
- unsigned result = DQS_FAIL;
-
- if (Pass == DQS_FIRST_PASS) {
- if (pattern == 1) {
- test_buf = (uint32_t *)TestPattern1;
- }
- else {
- test_buf = (uint32_t *)TestPattern0;
- }
- }
- else {
- test_buf = (uint32_t *)TestPattern2;
- }
-
- set_FSBASE(addr >> 24);
-
- addr_lo = addr << 8;
-
- if (is_Width128 && (channel == 1)) {
- addr_lo += 8; //second channel
- test_buf += 2;
- }
-
- __asm__ volatile (
- "movl %%fs:(%1), %0\n\t"
- :"=b"(value): "a" (addr_lo)
- );
-
- value_test = *test_buf;
-
-
- print_debug_dqs_pair("\t\t\t\t\t\tQW0.lo : test_buf= ", (unsigned)test_buf, " value = ", value_test, 4);
- print_debug_dqs_pair("\t\t\t\t\t\tQW0.lo : addr_lo = ", addr_lo, " value = ", value, 4);
-
- if (value == value_test) {
- addr_lo += 4;
- test_buf++;
- __asm__ volatile (
- "movl %%fs:(%1), %0\n\t"
- :"=b"(value): "a" (addr_lo)
- );
- value_test = *test_buf;
- print_debug_dqs_pair("\t\t\t\t\t\tQW0.hi : test_buf= ", (unsigned)test_buf, " value = ", value_test, 4);
- print_debug_dqs_pair("\t\t\t\t\t\tQW0.hi : addr_lo = ", addr_lo, " value = ", value, 4);
-
- if (value == value_test) {
- result = DQS_PASS;
- }
- }
-
- if (Pass == DQS_SECOND_PASS) { // second pass need to be inverted
- if (result == DQS_PASS) {
- result = DQS_FAIL;
- }
- else {
- result = DQS_PASS;
- }
- }
-
- return result;
-
-}
-
-static void SetMaxAL_RcvrDly(const struct mem_controller *ctrl, unsigned dly)
-{
- uint32_t reg;
-
- dly += (20-1); // round it
- dly /= 20; // convert from unit 50ps to 1ns
-
- dly += 6;
-
-
- reg = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- reg &= ~(DCH_MaxAsyncLat_MASK << DCH_MaxAsyncLat_SHIFT);
- reg |= ((dly - DCH_MaxAsyncLat_BASE) << DCH_MaxAsyncLat_SHIFT);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, reg);
-
-}
-
-/*
- Set the Target range to WT IO (using an IORR overlapping the already existing
- WB dram type). Use IORR0
-*/
-static void SetTargetWTIO(unsigned addr)
-{
- msr_t msr;
- msr.hi = addr >> 24;
- msr.lo = addr << 8;
- wrmsr(0xc0010016, msr); //IORR0 BASE
-
- msr.hi = 0xff;
- msr.lo = 0xfc000800; // 64MB Mask
- wrmsr(0xc0010017, msr); // IORR0 Mask
-}
-
-static void ResetTargetWTIO(void)
-{
- msr_t msr;
-
- msr.hi = 0;
- msr.lo = 0;
- wrmsr(0xc0010017, msr); // IORR0 Mask
-}
-
-static void proc_CLFLUSH(unsigned addr)
-{
-
- set_FSBASE(addr>>24);
-
- /* 1st move causes read fill (to exclusive or shared)*/
- __asm__ volatile (
- /* clflush fs:[eax] */
- "clflush %%fs:(%0)\n\t"
- ::"a" (addr << 8)
- );
-
-}
-static void proc_IOCLFLUSH(unsigned addr)
-{
- SetTargetWTIO(addr);
- proc_CLFLUSH(addr);
- ResetTargetWTIO();
-}
-
-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);
-
-}
-
-
-static uint16_t get_exact_T1000(unsigned i)
-{
- // 200 266, 333, 400
- static const uint16_t T1000_a[]= { 5000, 3759, 3003, 2500 };
-
- static const uint16_t TT_a[] = {
- /*200 266 333 400 */
- /*4 */ 6250, 6250, 6250, 6250,
- /*5 */ 5000, 5000, 5000, 2500,
- /*6 */ 5000, 4166, 4166, 2500,
- /*7 */ 5000, 4285, 3571, 2500,
-
- /*8 */ 5000, 3750, 3125, 2500,
- /*9 */ 5000, 3888, 3333, 2500,
- /*10*/ 5000, 4000, 3000, 2500,
- /*11*/ 5000, 4090, 3181, 2500,
-
- /*12*/ 5000, 3750, 3333, 2500,
- /*13*/ 5000, 3846, 3076, 2500,
- /*14*/ 5000, 3928, 3214, 2500,
- /*15*/ 5000, 4000, 3000, 2500,
- };
-
- int index;
- msr_t msr;
-
- /* Check for FID control support */
- struct cpuid_result cpuid1;
- cpuid1 = cpuid(0x80000007);
- if (cpuid1.edx & 0x02) {
- /* Use current FID */
- unsigned fid_cur;
- msr = rdmsr(0xc0010042);
- fid_cur = msr.lo & 0x3f;
-
- index = fid_cur>>1;
- } else {
- /* Use startup FID */
- unsigned fid_start;
- msr = rdmsr(0xc0010015);
- fid_start = (msr.lo & (0x3f << 24));
-
- index = fid_start>>25;
- }
-
- if (index > 12) return T1000_a[i];
-
- return TT_a[index * 4+i];
-
-}
-
-static void InitDQSPos4RcvrEn(const struct mem_controller *ctrl)
-{
- int i;
- uint32_t dword;
-
- dword = 0x00000000;
- for (i = 1; i <= 3; i++) {
- /* Program the DQS Write Timing Control Registers (Function 2:Offset 0x9c, index 0x01-0x03, 0x21-0x23) to 0x00 for all bytes */
- pci_write_config32_index_wait(ctrl->f2, 0x98, i, dword);
- pci_write_config32_index_wait(ctrl->f2, 0x98, i+0x20, dword);
- }
-
- dword = 0x2f2f2f2f;
- for (i = 5; i <= 7; i++) {
- /* Program the DQS Write Timing Control Registers (Function 2:Offset 0x9c, index 0x05-0x07, 0x25-0x27) to 0x2f for all bytes */
- pci_write_config32_index_wait(ctrl->f2, 0x98, i, dword);
- pci_write_config32_index_wait(ctrl->f2, 0x98, i+0x20, dword);
- }
-
-
-}
-
-static unsigned TrainRcvrEn(const struct mem_controller *ctrl, unsigned Pass, struct sys_info *sysinfo)
-{
-
- static const uint32_t TestPattern0[] = {
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- };
- static const uint32_t TestPattern1[] = {
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- };
- static const uint32_t TestPattern2[] = {
- 0x12345678, 0x87654321, 0x23456789, 0x98765432,
- 0x59385824, 0x30496724, 0x24490795, 0x99938733,
- 0x40385642, 0x38465245, 0x29432163, 0x05067894,
- 0x12349045, 0x98723467, 0x12387634, 0x34587623,
- };
-
- uint8_t pattern_buf_x[64 * 4 + 16]; // We need to two cache line So have more 16 bytes to keep 16 byte alignment */
- uint8_t *buf_a, *buf_b;
- uint32_t ecc_bit;
- uint32_t dword;
- uint8_t *dqs_rcvr_dly_a = &sysinfo->dqs_rcvr_dly_a[ctrl->node_id * 2* 8]; //8 node, channel 2, receiver 8
-
- int i;
-
- unsigned channel, receiver;
-
- unsigned Errors;
- unsigned CTLRMaxDelay;
- unsigned T1000;
-
- unsigned LastTest;
- unsigned CurrTest;
- unsigned Test0, Test1;
-
- unsigned RcvrEnDlyRmin;
-
- unsigned two_ranks;
- unsigned RcvrEnDly;
-
- unsigned PatternA;
- unsigned PatternB;
-
- unsigned TestAddr0, TestAddr0B, TestAddr1 = 0, TestAddr1B = 0;
-
- unsigned CurrRcvrCHADelay = 0;
-
- unsigned tmp;
-
- unsigned is_Width128 = sysinfo->meminfo[ctrl->node_id].is_Width128;
-
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- unsigned cpu_f0_f1 = 0;
-#endif
-
- if (Pass == DQS_FIRST_PASS) {
- InitDQSPos4RcvrEn(ctrl);
- }
-
- //enable SSE2
- enable_sse2();
-
- //wrap32dis
- set_wrap32dis();
-
- //disable ECC temp
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- ecc_bit = dword & DCL_DimmEccEn;
- dword &= ~(DCL_DimmEccEn);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
-
-
- if (Pass == DQS_FIRST_PASS) {
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- cpu_f0_f1 = is_cpu_pre_f2_in_bsp(ctrl->node_id);
- if (!cpu_f0_f1)
-#endif
- {
-#if 1
- /* Set the DqsRcvEnTrain bit */
- dword = pci_read_config32(ctrl->f2, DRAM_CTRL);
- dword |= DC_DqsRcvEnTrain;
- pci_write_config32(ctrl->f2, DRAM_CTRL, dword);
-#endif
- }
- }
-
- //get T1000 figures (cycle time (ns)) * 1K
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
- dword &= DCH_MemClkFreq_MASK;
-
- T1000 = get_exact_T1000(dword);
-
- // SetupRcvrPattern
- buf_a = (uint8_t *)(((uint32_t)(&pattern_buf_x[0]) + 0x10) & (0xfffffff0));
- buf_b = buf_a + 128; //??
- if (Pass == DQS_FIRST_PASS) {
- for (i = 0; i < 16; i++) {
- *((uint32_t *)(buf_a + i*4)) = TestPattern0[i];
- *((uint32_t *)(buf_b + i*4)) = TestPattern1[i];
- }
- }
- else {
- for (i = 0; i < 16; i++) {
- *((uint32_t *)(buf_a + i*4)) = TestPattern2[i];
- *((uint32_t *)(buf_b + i*4)) = TestPattern2[i];
- }
- }
-
- print_debug_dqs("\nTrainRcvEn: 0 ctrl", ctrl->node_id, 0);
-
- print_debug_addr("TrainRcvEn: buf_a:", buf_a);
-
- Errors = 0;
- /* for each channel */
- CTLRMaxDelay = 0;
- 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);
-
- /* for each rank */
- /* there are four receiver pairs, loosely associated with CS */
- for (receiver = 0; (receiver < 8) && (!Errors); receiver+=2)
- {
-
- unsigned index=(receiver>>1) * 3 + 0x10;
-
- print_debug_dqs("\t\tTrainRcvEn52: index ", index, 2);
-
- if (is_Width128) {
- if (channel) {
- dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
- CurrRcvrCHADelay= dword & 0xff;
- }
- }
- else {
- if (channel) {
- index += 0x20;
- }
- }
-
- LastTest = DQS_FAIL;
- RcvrEnDlyRmin = 0xaf;
-
- if (!RcvrRankEnabled(ctrl, channel, receiver, is_Width128, sysinfo)) continue;
-
- /* for each DQS receiver enable setting */
-
- TestAddr0 = Get_RcvrSysAddr(ctrl, channel, receiver, sysinfo);
-
- TestAddr0B = TestAddr0 + (1<<(20+2-8)); // 4MB
-
- if (RcvrRankEnabled(ctrl, channel, receiver+1, is_Width128, sysinfo)) {
- TestAddr1 = Get_RcvrSysAddr(ctrl, channel, receiver+1, sysinfo);
- TestAddr1B = TestAddr1 + (1<<(20+2-8)); //4MB
- two_ranks = 1;
- }
- else {
- two_ranks = 0;
- }
-
- print_debug_dqs("\t\tTrainRcvEn53: TestAddr0B ", TestAddr0B, 2);
-
- Write1LTestPattern(TestAddr0, 0, buf_a, buf_b); // rank0 of dimm, test p0
- Write1LTestPattern(TestAddr0B, 1, buf_a, buf_b); //rank0 of dimm, test p1
-
- if (two_ranks == 1) {
- Write1LTestPattern(TestAddr1, 0, buf_a, buf_b); //rank 1 of dimm
- Write1LTestPattern(TestAddr1B, 1, buf_a, buf_b);//rank 1 of dimm
- }
-
- if (Pass == DQS_FIRST_PASS) {
- RcvrEnDly = 0;
- } else {
- RcvrEnDly = dqs_rcvr_dly_a[channel * 8 + receiver];
- }
-
- while (RcvrEnDly < 0xaf) { // Sweep Delay value here
- print_debug_dqs("\t\t\tTrainRcvEn541: RcvrEnDly ", RcvrEnDly, 3);
-
- if (RcvrEnDly & 1) {
- /* Odd steps get another pattern such that even
- * and odd steps alternate.
- * The pointers to the patterns will be swapped
- * at the end of the loop so they are correspond
- */
- PatternA = 1;
- PatternB = 0;
- }
- else {
- /* Even step */
- PatternA = 0;
- PatternB = 1;
- }
-
- /* Program current Receiver enable delay */
- pci_write_config32_index_wait(ctrl->f2, 0x98, index, RcvrEnDly);
- /* FIXME: 64bit MUX */
-
- if (is_Width128) {
- /* Program current Receiver enable delay channel b */
- pci_write_config32_index_wait(ctrl->f2, 0x98, index+ 0x20, RcvrEnDly);
- }
-
- /* Program the MaxAsyncLat filed with the
- * current DQS receiver enable setting plus 6ns
- */
- /* Program MaxAsyncLat to correspond with current delay */
- SetMaxAL_RcvrDly(ctrl, RcvrEnDly);
-
- CurrTest = DQS_FAIL;
-
- Read1LTestPattern(TestAddr0); //Cache Fill
- /* ROM vs cache compare */
- Test0 = CompareTestPatternQW0(channel, TestAddr0, PatternA, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
- proc_IOCLFLUSH(TestAddr0);
-
- ResetDCTWrPtr(ctrl);
-
- print_debug_dqs("\t\t\tTrainRcvEn542: Test0 ", Test0, 3);
-
- if (Test0 == DQS_PASS) {
-
- Read1LTestPattern(TestAddr0B);
- Test1 = CompareTestPatternQW0(channel, TestAddr0B, PatternB, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
- proc_IOCLFLUSH(TestAddr0B);
-
- ResetDCTWrPtr(ctrl);
-
- print_debug_dqs("\t\t\tTrainRcvEn543: Test1 ", Test1, 3);
-
- if (Test1 == DQS_PASS) {
- if (two_ranks) {
- Read1LTestPattern(TestAddr1);
- Test0 = CompareTestPatternQW0(channel, TestAddr1, PatternA, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
- proc_IOCLFLUSH(TestAddr1);
- ResetDCTWrPtr(ctrl);
-
- if (Test0 == DQS_PASS) {
- Read1LTestPattern(TestAddr1B);
- Test1 = CompareTestPatternQW0(channel, TestAddr1B, PatternB, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
- proc_IOCLFLUSH(TestAddr1B);
- ResetDCTWrPtr(ctrl);
-
- if (Test1 == DQS_PASS) {
- CurrTest = DQS_PASS;
- }
- }
- print_debug_dqs("\t\t\tTrainRcvEn544: Test0 ", Test0, 3);
- }
- else {
- CurrTest = DQS_PASS;
- }
- }
- }
-
- print_debug_dqs("\t\t\tTrainRcvEn55: RcvrEnDly ", RcvrEnDly, 3);
-
- if (CurrTest == DQS_PASS) {
- if (LastTest == DQS_FAIL) {
- RcvrEnDlyRmin = RcvrEnDly;
- break;
- }
- }
-
- LastTest = CurrTest;
-
- /* swap the rank 0 pointers */
- tmp = TestAddr0;
- TestAddr0 = TestAddr0B;
- TestAddr0B = tmp;
-
- /* swap the rank 1 pointers */
- tmp = TestAddr1;
- TestAddr1 = TestAddr1B;
- TestAddr1B = tmp;
-
- print_debug_dqs("\t\t\tTrainRcvEn56: RcvrEnDly ", RcvrEnDly, 3);
-
- RcvrEnDly++;
-
- } // while RcvrEnDly
-
- print_debug_dqs("\t\tTrainRcvEn61: RcvrEnDly ", RcvrEnDly, 2);
-
- if (RcvrEnDlyRmin == 0xaf) {
- //no passing window
- Errors |= SB_NORCVREN;
- }
-
- if (Pass == DQS_FIRST_PASS) {
- // We need a better value for DQSPos training
- RcvrEnDly = RcvrEnDlyRmin /* + RCVREN_MARGIN * T1000/64/50 */;
- } else {
- RcvrEnDly = RcvrEnDlyRmin;
- }
-
- if (RcvrEnDly > 0xae) {
- //passing window too narrow, too far delayed
- Errors |= SB_SmallRCVR;
- RcvrEnDly = 0xae;
- }
-
- if (Pass == DQS_SECOND_PASS) { //second pass must average vales
- RcvrEnDly += dqs_rcvr_dly_a[channel * 8 + receiver] /* - (RCVREN_MARGIN * T1000/64/50)*/;
- RcvrEnDly >>= 1;
- }
-
- dqs_rcvr_dly_a[channel * 8 + receiver] = RcvrEnDly;
-
- //Set final RcvrEnDly for this DIMM and Channel
- pci_write_config32_index_wait(ctrl->f2, 0x98, index, RcvrEnDly);
-
- if (is_Width128) {
- pci_write_config32_index_wait(ctrl->f2, 0x98, index+0x20, RcvrEnDly); // channel B
- if (channel) {
- pci_write_config32_index_wait(ctrl->f2, 0x98, index, CurrRcvrCHADelay);
- if (RcvrEnDly > CurrRcvrCHADelay) {
- dword = RcvrEnDly - CurrRcvrCHADelay;
- }
- else {
- dword = CurrRcvrCHADelay - RcvrEnDly;
- }
- dword *= 50;
- if (dword > T1000) {
- Errors |= SB_CHA2BRCVREN;
- }
- }
- }
-
- print_debug_dqs("\t\tTrainRcvEn63: RcvrEnDly ", RcvrEnDly, 2);
-
- if (RcvrEnDly > CTLRMaxDelay) {
- CTLRMaxDelay = RcvrEnDly;
- }
-
- print_debug_dqs("\t\tTrainRcvEn64: CTLRMaxDelay ", CTLRMaxDelay, 2);
-
- } /* receiver */
- } /* channel */
-
- print_debug_dqs("\tTrainRcvEn65: CTLRMaxDelay ", CTLRMaxDelay, 1);
-
- /* Program the MaxAsysncLat field with the largest DQS Receiver Enable setting */
- SetMaxAL_RcvrDly(ctrl, CTLRMaxDelay);
- ResetDCTWrPtr(ctrl);
-
- //Enable ECC again
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dword &= ~(DCL_DimmEccEn);
- dword |= ecc_bit;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
-
- if (Pass == DQS_FIRST_PASS) {
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- if (!cpu_f0_f1)
-#endif
- {
- dword = pci_read_config32(ctrl->f2, DRAM_CTRL);
- dword &= ~DC_DqsRcvEnTrain;
- pci_write_config32(ctrl->f2, DRAM_CTRL, dword);
- }
- }
-
- //Clear wrap32dis
-
- clear_wrap32dis();
-
- //restore SSE2 setting
- disable_sse2();
-
-#if CONFIG_MEM_TRAIN_SEQ != 1
- /* We need tidy output for type 1 */
- printk(BIOS_DEBUG, " CTLRMaxDelay=%02x\n", CTLRMaxDelay);
-#endif
-
- return (CTLRMaxDelay == 0xae)?1:0;
-
-}
-
-#define DQS_READDIR 1
-#define DQS_WRITEDIR 0
-
-
-static void SetDQSDelayCSR(const struct mem_controller *ctrl, unsigned channel, unsigned bytelane, unsigned direction, unsigned dqs_delay)
-{ //ByteLane could be 0-8, last is for ECC
- unsigned index;
- uint32_t dword;
- unsigned shift;
-
- dqs_delay &= 0xff;
-
- index = (bytelane>>2) + 1 + channel * 0x20 + (direction << 2);
- shift = bytelane;
- while (shift > 3) {
- shift-=4;
- }
- shift <<= 3; // 8 bit
-
- dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
- dword &= ~(0x3f << shift);
- dword |= (dqs_delay << shift);
- pci_write_config32_index_wait(ctrl->f2, 0x98, index, dword);
-
-}
-
-static void SetDQSDelayAllCSR(const struct mem_controller *ctrl, unsigned channel, unsigned direction, unsigned dqs_delay)
-{
- unsigned index;
- uint32_t dword;
- int i;
-
- dword = 0;
- dqs_delay &= 0xff;
- for (i = 0; i < 4; i++) {
- dword |= dqs_delay << (i*8);
- }
-
- index = 1 + channel * 0x20 + direction * 4;
-
- for (i = 0; i < 2; i++) {
- pci_write_config32_index_wait(ctrl->f2, 0x98, index + i, dword);
- }
-
-}
-
-static unsigned MiddleDQS(unsigned min_d, unsigned max_d)
-{
- unsigned size_d;
- size_d = max_d-min_d;
- if (size_d & 1) { //need round up
- min_d++;
- }
- return (min_d + (size_d>>1));
-}
-
-static inline void save_dqs_delay(unsigned channel, unsigned bytelane, unsigned direction, uint8_t *dqs_delay_a, uint8_t dqs_delay)
-{
- dqs_delay_a[channel * 2*9 + direction * 9 + bytelane] = dqs_delay;
-}
-
-static void WriteDQSTestPattern(unsigned addr_lo, unsigned pattern , uint8_t *buf_a)
-{
- WriteLNTestPattern(addr_lo, buf_a, (pattern+1) * 9);
-}
-
-static void ReadL18TestPattern(unsigned addr_lo)
-{
- //set fs and use fs prefix to access the mem
- __asm__ volatile (
- "movl %%fs:-128(%%esi), %%eax\n\t" //TestAddr cache line
- "movl %%fs:-64(%%esi), %%eax\n\t" //+1
- "movl %%fs:(%%esi), %%eax\n\t" //+2
- "movl %%fs:64(%%esi), %%eax\n\t" //+3
-
- "movl %%fs:-128(%%edi), %%eax\n\t" //+4
- "movl %%fs:-64(%%edi), %%eax\n\t" //+5
- "movl %%fs:(%%edi), %%eax\n\t" //+6
- "movl %%fs:64(%%edi), %%eax\n\t" //+7
-
- "movl %%fs:-128(%%ebx), %%eax\n\t" //+8
- "movl %%fs:-64(%%ebx), %%eax\n\t" //+9
- "movl %%fs:(%%ebx), %%eax\n\t" //+10
- "movl %%fs:64(%%ebx), %%eax\n\t" //+11
-
- "movl %%fs:-128(%%ecx), %%eax\n\t" //+12
- "movl %%fs:-64(%%ecx), %%eax\n\t" //+13
- "movl %%fs:(%%ecx), %%eax\n\t" //+14
- "movl %%fs:64(%%ecx), %%eax\n\t" //+15
-
- "movl %%fs:-128(%%edx), %%eax\n\t" //+16
- "movl %%fs:-64(%%edx), %%eax\n\t" //+17
-
- :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), "d" (addr_lo +128+16*64), "S"(addr_lo+128), "D"(addr_lo+128+4*64)
- );
-
-}
-
-static void ReadL9TestPattern(unsigned addr_lo)
-{
-
- //set fs and use fs prefix to access the mem
- __asm__ volatile (
-
- "movl %%fs:-128(%%ecx), %%eax\n\t" //TestAddr cache line
- "movl %%fs:-64(%%ecx), %%eax\n\t" //+1
- "movl %%fs:(%%ecx), %%eax\n\t" //+2
- "movl %%fs:64(%%ecx), %%eax\n\t" //+3
-
- "movl %%fs:-128(%%edx), %%eax\n\t" //+4
- "movl %%fs:-64(%%edx), %%eax\n\t" //+5
- "movl %%fs:(%%edx), %%eax\n\t" //+6
- "movl %%fs:64(%%edx), %%eax\n\t" //+7
-
- "movl %%fs:-128(%%ebx), %%eax\n\t" //+8
-
- :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128), "d"(addr_lo+128+4*64)
- );
-
-}
-
-
-static void ReadDQSTestPattern(unsigned addr_lo, unsigned pattern)
-{
- if (pattern == 0) {
- ReadL9TestPattern(addr_lo);
- }
- else {
- ReadL18TestPattern(addr_lo);
- }
-}
-
-static void FlushDQSTestPattern_L9(unsigned addr_lo)
-{
- __asm__ volatile (
- "clflush %%fs:-128(%%ecx)\n\t"
- "clflush %%fs:-64(%%ecx)\n\t"
- "clflush %%fs:(%%ecx)\n\t"
- "clflush %%fs:64(%%ecx)\n\t"
-
- "clflush %%fs:-128(%%eax)\n\t"
- "clflush %%fs:-64(%%eax)\n\t"
- "clflush %%fs:(%%eax)\n\t"
- "clflush %%fs:64(%%eax)\n\t"
-
- "clflush %%fs:-128(%%ebx)\n\t"
-
- :: "b" (addr_lo+128+8*64), "c"(addr_lo+128), "a"(addr_lo+128+4*64)
- );
-
-}
-static __attribute__((noinline)) void FlushDQSTestPattern_L18(unsigned addr_lo)
-{
- __asm__ volatile (
- "clflush %%fs:-128(%%eax)\n\t"
- "clflush %%fs:-64(%%eax)\n\t"
- "clflush %%fs:(%%eax)\n\t"
- "clflush %%fs:64(%%eax)\n\t"
-
- "clflush %%fs:-128(%%edi)\n\t"
- "clflush %%fs:-64(%%edi)\n\t"
- "clflush %%fs:(%%edi)\n\t"
- "clflush %%fs:64(%%edi)\n\t"
-
- "clflush %%fs:-128(%%ebx)\n\t"
- "clflush %%fs:-64(%%ebx)\n\t"
- "clflush %%fs:(%%ebx)\n\t"
- "clflush %%fs:64(%%ebx)\n\t"
-
- "clflush %%fs:-128(%%ecx)\n\t"
- "clflush %%fs:-64(%%ecx)\n\t"
- "clflush %%fs:(%%ecx)\n\t"
- "clflush %%fs:64(%%ecx)\n\t"
-
- "clflush %%fs:-128(%%edx)\n\t"
- "clflush %%fs:-64(%%edx)\n\t"
-
- :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), "d" (addr_lo +128+16*64), "a"(addr_lo+128), "D"(addr_lo+128+4*64)
- );
-}
-
-static void FlushDQSTestPattern(unsigned addr_lo, unsigned pattern)
-{
-
- if (pattern == 0) {
- FlushDQSTestPattern_L9(addr_lo);
- }
- else {
- FlushDQSTestPattern_L18(addr_lo);
- }
-}
-
-static unsigned CompareDQSTestPattern(unsigned channel, unsigned addr_lo, unsigned pattern, uint8_t *buf_a)
-{
- uint32_t *test_buf;
- unsigned bitmap = 0xff;
- unsigned bytelane;
- int i;
- uint32_t value;
- int j;
- uint32_t value_test;
-
- test_buf = (uint32_t *)buf_a;
-
-
- if (pattern && channel) {
- addr_lo += 8; //second channel
- test_buf+= 2;
- }
-
- bytelane = 0;
- for (i = 0; i < 9*64/4; i++) {
- __asm__ volatile (
- "movl %%fs:(%1), %0\n\t"
- :"=b"(value): "a" (addr_lo)
- );
- value_test = *test_buf;
-
- print_debug_dqs_pair("\t\t\t\t\t\ttest_buf= ", (unsigned)test_buf, " value = ", value_test, 7);
- print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ",addr_lo, " value = ", value, 7);
-
- for (j = 0; j < 4*8; j+=8) {
- if (((value>>j)&0xff) != ((value_test>>j)& 0xff)) {
- bitmap &= ~(1 << bytelane);
- }
-
- bytelane++;
- bytelane &= 0x7;
- }
- print_debug_dqs("\t\t\t\t\t\tbitmap = ", bitmap, 7);
-
- if (bytelane == 0) {
- if (pattern == 1) { //dual channel
- addr_lo += 8; //skip over other channel's data
- test_buf += 2;
- }
- }
- addr_lo += 4;
- test_buf +=1;
-
- }
-
-
- return bitmap;
-
-}
-
-static unsigned TrainDQSPos(const struct mem_controller *ctrl, unsigned channel, unsigned Direction, unsigned Pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
-{
- unsigned ByteLane;
- unsigned Errors;
- unsigned BanksPresent;
-
- unsigned MutualCSPassW[48];
-
- unsigned ChipSel;
- unsigned DQSDelay;
-
- unsigned TestAddr;
-
- unsigned LastTest;
- unsigned RnkDlyFilterMax, RnkDlyFilterMin = 0;
- unsigned RnkDlySeqPassMax, RnkDlySeqPassMin = 0;
-
- Errors = 0;
- BanksPresent = 0;
-
- print_debug_dqs("\t\t\tTrainDQSPos begin ", 0, 3);
-
- printk(BIOS_DEBUG, "TrainDQSPos: MutualCSPassW[48] :%p\n", MutualCSPassW);
-
- for (DQSDelay = 0; DQSDelay < 48; DQSDelay++) {
- MutualCSPassW[DQSDelay] = 0xff; // Bitmapped status per delay setting, 0xff=All positions passing (1= PASS)
- }
-
- for (ChipSel = 0; ChipSel < 8; ChipSel++) { //logical register chipselects 0..7
- print_debug_dqs("\t\t\t\tTrainDQSPos: 11 ChipSel ", ChipSel, 4);
- //FIXME: process 64MUXedMode
- if (!ChipSelPresent(ctrl, ChipSel, sysinfo)) continue;
- BanksPresent = 1;
-
- TestAddr = Get_MCTSysAddr(ctrl, ChipSel, sysinfo);
-
- print_debug_dqs("\t\t\t\tTrainDQSPos: 12 TestAddr ", TestAddr, 4);
-
- //set fs and use fs prefix to access the mem
- set_FSBASE(TestAddr>>24);
-
- if (Direction == DQS_READDIR) {
- print_debug_dqs("\t\t\t\tTrainDQSPos: 13 for read so write at first", 0, 4);
- WriteDQSTestPattern(TestAddr << 8, Pattern, buf_a);
- }
-
- for (DQSDelay = 0; DQSDelay < 48; DQSDelay++) {
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 141 DQSDelay ", DQSDelay, 5);
- if (MutualCSPassW[DQSDelay] == 0) continue; //skip current delay value if other chipselects have failed all 8 bytelanes
- SetDQSDelayAllCSR(ctrl, channel, Direction, DQSDelay);
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 142 MutualCSPassW ", MutualCSPassW[DQSDelay], 5);
- if (Direction == DQS_WRITEDIR) {
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 143 for write", 0, 5);
- WriteDQSTestPattern(TestAddr << 8, Pattern, buf_a);
- }
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 144 Pattern ", Pattern, 5);
- ReadDQSTestPattern(TestAddr << 8, Pattern);
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 145 MutualCSPassW ", MutualCSPassW[DQSDelay], 5);
- MutualCSPassW[DQSDelay] &= CompareDQSTestPattern(channel, TestAddr << 8, Pattern, buf_a); //0: fail, 1=pass
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 146 MutualCSPassW ", MutualCSPassW[DQSDelay], 5);
- SetTargetWTIO(TestAddr);
- FlushDQSTestPattern(TestAddr << 8, Pattern);
- ResetTargetWTIO();
- }
- }
-
- if (BanksPresent)
- for (ByteLane = 0; ByteLane < 8; ByteLane++) {
- print_debug_dqs("\t\t\t\tTrainDQSPos: 31 ByteLane ",ByteLane, 4);
-
- LastTest = DQS_FAIL;
- RnkDlySeqPassMax = 0;
- RnkDlyFilterMax = 0;
- RnkDlyFilterMin = 0;
- for (DQSDelay = 0; DQSDelay < 48; DQSDelay++) {
- if (MutualCSPassW[DQSDelay] & (1 << ByteLane)) {
-
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 321 DQSDelay ", DQSDelay, 5);
- print_debug_dqs("\t\t\t\t\tTrainDQSPos: 322 MutualCSPassW ", MutualCSPassW[DQSDelay], 5);
-
- RnkDlySeqPassMax = DQSDelay;
- if (LastTest == DQS_FAIL) {
- RnkDlySeqPassMin = DQSDelay; //start sequential run
- }
- if ((RnkDlySeqPassMax - RnkDlySeqPassMin)>(RnkDlyFilterMax-RnkDlyFilterMin)) {
- RnkDlyFilterMin = RnkDlySeqPassMin;
- RnkDlyFilterMax = RnkDlySeqPassMax;
- }
- LastTest = DQS_PASS;
- }
- else {
- LastTest = DQS_FAIL;
- }
- }
- print_debug_dqs("\t\t\t\tTrainDQSPos: 33 RnkDlySeqPassMax ", RnkDlySeqPassMax, 4);
-
- if (RnkDlySeqPassMax == 0) {
- Errors |= SB_NODQSPOS; // no passing window
- }
- else {
- print_debug_dqs("\t\t\t\tTrainDQSPos: 34 RnkDlyFilterMax ", RnkDlyFilterMax, 4);
- print_debug_dqs("\t\t\t\tTrainDQSPos: 34 RnkDlyFilterMin ", RnkDlyFilterMin, 4);
- if ((RnkDlyFilterMax - RnkDlyFilterMin)< MIN_DQS_WNDW) {
- Errors |= SB_SMALLDQS;
- }
- else {
- unsigned middle_dqs;
- middle_dqs = MiddleDQS(RnkDlyFilterMin, RnkDlyFilterMax);
- print_debug_dqs("\t\t\t\tTrainDQSPos: 35 middle_dqs ",middle_dqs, 4);
- SetDQSDelayCSR(ctrl, channel, ByteLane, Direction, middle_dqs);
- save_dqs_delay(channel, ByteLane, Direction, dqs_delay_a, middle_dqs);
- }
- }
-
- }
-
- print_debug_dqs("\t\t\tTrainDQSPos: end", 0xff, 3);
-
- return Errors;
-
-
-}
-
-static unsigned TrainReadDQS(const struct mem_controller *ctrl, unsigned channel, unsigned pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
-{
- print_debug_dqs("\t\tTrainReadPos", 0, 2);
- return TrainDQSPos(ctrl, channel, DQS_READDIR, pattern, buf_a, dqs_delay_a, sysinfo);
-}
-
-static unsigned TrainWriteDQS(const struct mem_controller *ctrl, unsigned channel, unsigned pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
-{
- print_debug_dqs("\t\tTrainWritePos", 0, 2);
- return TrainDQSPos(ctrl, channel, DQS_WRITEDIR, pattern, buf_a, dqs_delay_a, sysinfo);
-}
-
-
-
-static unsigned TrainDQSRdWrPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
- static const uint32_t TestPatternJD1a[] = {
- 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, // QW0-1, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW2-3, ALL-EVEN
- 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, // QW4-5, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW6-7, ALL-EVEN
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW0-1, DQ0-ODD
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW2-3, DQ0-ODD
- 0x01010101,0x01010101,0xFeFeFeFe,0xFeFeFeFe, // QW4-5, DQ0-ODD
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW6-7, DQ0-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW0-1, DQ1-ODD
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW2-3, DQ1-ODD
- 0xFdFdFdFd,0xFdFdFdFd,0x02020202,0x02020202, // QW4-5, DQ1-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW6-7, DQ1-ODD
- 0x04040404,0x04040404,0xfBfBfBfB,0xfBfBfBfB, // QW0-1, DQ2-ODD
- 0x04040404,0x04040404,0x04040404,0x04040404, // QW2-3, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW4-5, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW6-7, DQ2-ODD
- 0x08080808,0x08080808,0xF7F7F7F7,0xF7F7F7F7, // QW0-1, DQ3-ODD
- 0x08080808,0x08080808,0x08080808,0x08080808, // QW2-3, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0x08080808,0x08080808, // QW4-5, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW6-7, DQ3-ODD
- 0x10101010,0x10101010,0x10101010,0x10101010, // QW0-1, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, // QW2-3, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW4-5, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, // QW6-7, DQ4-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW0-1, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0x20202020,0x20202020, // QW2-3, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW4-5, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW6-7, DQ5-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW0-1, DQ6-ODD
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW2-3, DQ6-ODD
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW4-5, DQ6-ODD
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW6-7, DQ6-ODD
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW0-1, DQ7-ODD
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW2-3, DQ7-ODD
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW4-5, DQ7-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080 // QW6-7, DQ7-ODD
- };
- static const uint32_t TestPatternJD1b[] = {
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW0,CHA-B, ALL-EVEN
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, // QW1,CHA-B, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW2,CHA-B, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW3,CHA-B, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW4,CHA-B, ALL-EVEN
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, // QW5,CHA-B, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW6,CHA-B, ALL-EVEN
- 0x00000000,0x00000000,0x00000000,0x00000000, // QW7,CHA-B, ALL-EVEN
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW0,CHA-B, DQ0-ODD
- 0x01010101,0x01010101,0x01010101,0x01010101, // QW1,CHA-B, DQ0-ODD
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW2,CHA-B, DQ0-ODD
- 0x01010101,0x01010101,0x01010101,0x01010101, // QW3,CHA-B, DQ0-ODD
- 0x01010101,0x01010101,0x01010101,0x01010101, // QW4,CHA-B, DQ0-ODD
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW5,CHA-B, DQ0-ODD
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW6,CHA-B, DQ0-ODD
- 0x01010101,0x01010101,0x01010101,0x01010101, // QW7,CHA-B, DQ0-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW0,CHA-B, DQ1-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW1,CHA-B, DQ1-ODD
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW2,CHA-B, DQ1-ODD
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW3,CHA-B, DQ1-ODD
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW4,CHA-B, DQ1-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW5,CHA-B, DQ1-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW6,CHA-B, DQ1-ODD
- 0x02020202,0x02020202,0x02020202,0x02020202, // QW7,CHA-B, DQ1-ODD
- 0x04040404,0x04040404,0x04040404,0x04040404, // QW0,CHA-B, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW1,CHA-B, DQ2-ODD
- 0x04040404,0x04040404,0x04040404,0x04040404, // QW2,CHA-B, DQ2-ODD
- 0x04040404,0x04040404,0x04040404,0x04040404, // QW3,CHA-B, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW4,CHA-B, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW5,CHA-B, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW6,CHA-B, DQ2-ODD
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW7,CHA-B, DQ2-ODD
- 0x08080808,0x08080808,0x08080808,0x08080808, // QW0,CHA-B, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW1,CHA-B, DQ3-ODD
- 0x08080808,0x08080808,0x08080808,0x08080808, // QW2,CHA-B, DQ3-ODD
- 0x08080808,0x08080808,0x08080808,0x08080808, // QW3,CHA-B, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW4,CHA-B, DQ3-ODD
- 0x08080808,0x08080808,0x08080808,0x08080808, // QW5,CHA-B, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW6,CHA-B, DQ3-ODD
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW7,CHA-B, DQ3-ODD
- 0x10101010,0x10101010,0x10101010,0x10101010, // QW0,CHA-B, DQ4-ODD
- 0x10101010,0x10101010,0x10101010,0x10101010, // QW1,CHA-B, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW2,CHA-B, DQ4-ODD
- 0x10101010,0x10101010,0x10101010,0x10101010, // QW3,CHA-B, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW4,CHA-B, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW5,CHA-B, DQ4-ODD
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW6,CHA-B, DQ4-ODD
- 0x10101010,0x10101010,0x10101010,0x10101010, // QW7,CHA-B, DQ4-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW0,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW1,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW2,CHA-B, DQ5-ODD
- 0x20202020,0x20202020,0x20202020,0x20202020, // QW3,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW4,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW5,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW6,CHA-B, DQ5-ODD
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW7,CHA-B, DQ5-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW0,CHA-B, DQ6-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW1,CHA-B, DQ6-ODD
- 0x40404040,0x40404040,0x40404040,0x40404040, // QW2,CHA-B, DQ6-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW3,CHA-B, DQ6-ODD
- 0x40404040,0x40404040,0x40404040,0x40404040, // QW4,CHA-B, DQ6-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW5,CHA-B, DQ6-ODD
- 0x40404040,0x40404040,0x40404040,0x40404040, // QW6,CHA-B, DQ6-ODD
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW7,CHA-B, DQ6-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080, // QW0,CHA-B, DQ7-ODD
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW1,CHA-B, DQ7-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080, // QW2,CHA-B, DQ7-ODD
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW3,CHA-B, DQ7-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080, // QW4,CHA-B, DQ7-ODD
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW5,CHA-B, DQ7-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080, // QW6,CHA-B, DQ7-ODD
- 0x80808080,0x80808080,0x80808080,0x80808080 // QW7,CHA-B, DQ7-ODD
- };
- uint8_t pattern_buf_x[64 * 18 + 16]; // We need to two cache line So have more 16 bytes to keep 16 byte alignment */
- uint8_t *buf_a;
-
- unsigned pattern;
- uint32_t dword;
- uint32_t ecc_bit;
- unsigned Errors;
- unsigned channel;
- int i;
- unsigned DQSWrDelay;
- unsigned is_Width128 = sysinfo->meminfo[ctrl->node_id].is_Width128;
- uint8_t *dqs_delay_a = &sysinfo->dqs_delay_a[ctrl->node_id * 2*2*9]; //channel 2, direction 2 , bytelane *9
-
- //enable SSE2
- enable_sse2();
-
- //wrap32dis
- set_wrap32dis();
-
- //disable ECC temp
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- ecc_bit = dword & DCL_DimmEccEn;
- dword &= ~(DCL_DimmEccEn);
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
-
- //SetupDqsPattern
- buf_a = (uint8_t *)(((uint32_t)(&pattern_buf_x[0]) + 0x10) & (~0xf));
-
- if (is_Width128) {
- pattern = 1;
- for (i = 0; i < 16*18; i++) {
- *((uint32_t *)(buf_a + i*4)) = TestPatternJD1b[i];
- }
- }
- else {
- pattern = 0;
- for (i = 0; i < 16*9; i++) {
- *((uint32_t *)(buf_a + i*4)) = TestPatternJD1a[i];
- }
-
- }
-
- print_debug_dqs("\nTrainDQSRdWrPos: 0 ctrl ", ctrl->node_id, 0);
-
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: buf_a:%p\n", 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++) {
- unsigned err;
- SetDQSDelayAllCSR(ctrl, channel, DQS_WRITEDIR, DQSWrDelay);
- print_debug_dqs("\t\tTrainDQSRdWrPos: 21 DQSWrDelay ", DQSWrDelay, 2);
- err= TrainReadDQS(ctrl, channel, pattern, buf_a, dqs_delay_a, sysinfo);
- print_debug_dqs("\t\tTrainDQSRdWrPos: 22 err ",err, 2);
- if (err == 0) break;
- Errors |= err;
- }
-
- print_debug_dqs("\tTrainDQSRdWrPos: 3 DQSWrDelay ", DQSWrDelay, 1);
-
- if (DQSWrDelay < 48) {
- Errors = TrainWriteDQS(ctrl, channel, pattern, buf_a, dqs_delay_a, sysinfo);
- print_debug_dqs("\tTrainDQSRdWrPos: 4 Errors ", Errors, 1);
-
- }
- channel++;
- if (!is_Width128) {
- //FIXME: 64MuxMode??
- channel++; // skip channel if 64-bit mode
- }
- }
-
- //Enable ECC again
- dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
- dword &= ~(DCL_DimmEccEn);
- dword |= ecc_bit;
- pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
-
- //Clear wrap32dis
-
- clear_wrap32dis();
-
- //restore SSE2 setting
- disable_sse2();
-
- print_debug_dqs("TrainDQSRdWrPos: ", 5, 0);
-
- return Errors;
-
-}
-static inline uint8_t get_dqs_delay(unsigned channel, unsigned bytelane, unsigned direction, uint8_t *dqs_delay_a)
-{
- return dqs_delay_a[channel * 2*9 + direction * 9 + bytelane];
-}
-
-static unsigned CalcEccDQSPos(unsigned channel,unsigned ByteLane0, unsigned ByteLane1, unsigned InterFactor, unsigned Direction, uint8_t *dqs_delay_a)
-/* InterFactor: 0: 100% ByteLane 0
- 0x80: 50% between ByteLane 0 and 1
- 0xff: 99.6% ByteLane 1 and 0.4% like 0
-*/
-{
- unsigned DQSDelay0, DQSDelay1;
- unsigned DQSDelay;
-
- DQSDelay0 = get_dqs_delay(channel, ByteLane0, Direction, dqs_delay_a);
- DQSDelay1 = get_dqs_delay(channel, ByteLane1, Direction, dqs_delay_a);
-
- if (DQSDelay0 > DQSDelay1) {
- DQSDelay = DQSDelay0 - DQSDelay1;
- InterFactor = 0xff - InterFactor;
- }
- else {
- DQSDelay = DQSDelay1 - DQSDelay0;
- }
-
- DQSDelay *= InterFactor;
-
- DQSDelay >>= 8; // /255
-
- if (DQSDelay0 > DQSDelay1) {
- DQSDelay += DQSDelay1;
- }
- else {
- DQSDelay += DQSDelay0;
- }
-
- return DQSDelay;
-
-}
-
-static void SetEccDQSRdWrPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
- unsigned channel;
- unsigned ByteLane;
- unsigned Direction;
- unsigned lane0, lane1, ratio;
- unsigned dqs_delay;
-
- unsigned direction[] = { DQS_READDIR, DQS_WRITEDIR };
- int i;
- uint8_t *dqs_delay_a = &sysinfo->dqs_delay_a[ctrl->node_id * 2*2*9]; //channel 2, direction 2 , bytelane *9
-
- ByteLane = 8;
-
- for (channel = 0; channel < 2; channel++) {
- for (i = 0; i < 2; i++) {
- Direction = direction[i];
- lane0 = 4; lane1 = 5; ratio = 0;
- dqs_delay = CalcEccDQSPos(channel, lane0, lane1, ratio, Direction, dqs_delay_a);
- print_debug_dqs_pair("\t\tSetEccDQSRdWrPos: channel ", channel, Direction == DQS_READDIR? " R dqs_delay":" W dqs_delay", dqs_delay, 2);
- SetDQSDelayCSR(ctrl, channel, ByteLane, Direction, dqs_delay);
- save_dqs_delay(channel, ByteLane, Direction, dqs_delay_a, dqs_delay);
- }
- }
-}
-
-static unsigned train_DqsRcvrEn(const struct mem_controller *ctrl, unsigned Pass, struct sys_info *sysinfo)
-{
- print_debug_dqs("\ntrain_DqsRcvrEn: begin ctrl ", ctrl->node_id, 0);
- if (TrainRcvrEn(ctrl, Pass, sysinfo)) {
- return 1;
- }
- print_debug_dqs("\ntrain_DqsRcvrEn: end ctrl ", ctrl->node_id, 0);
- return 0;
-
-}
-static unsigned train_DqsPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
- print_debug_dqs("\ntrain_DqsPos: begin ctrl ", ctrl->node_id, 0);
- if (TrainDQSRdWrPos(ctrl, sysinfo) != 0) {
- printk(BIOS_ERR, "\nDQS Training Rd Wr failed ctrl%02x\n", ctrl->node_id);
- return 1;
- }
- else {
- SetEccDQSRdWrPos(ctrl, sysinfo);
- }
- print_debug_dqs("\ntrain_DqsPos: end ctrl ", ctrl->node_id, 0);
- return 0;
-
-}
-
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
-static void f0_svm_workaround(int controllers, const struct mem_controller *ctrl, tsc_t *tsc0, struct sys_info *sysinfo)
-{
- tsc_t tsc1[8];
- unsigned cpu_f0_f1[8];
- int i;
-
- print_debug_addr("dqs_timing: tsc1[8] :", tsc1);
-
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[i])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- uint32_t dword;
-
- cpu_f0_f1[i] = is_cpu_pre_f2_in_bsp(i);
-
- if (!cpu_f0_f1[i]) continue;
-
- dword = pci_read_config32(ctrl[i].f2, DRAM_CTRL);
- dword &= ~DC_DqsRcvEnTrain;
- pci_write_config32(ctrl[i].f2, DRAM_CTRL, dword);
-
- dword = pci_read_config32(ctrl[i].f2, DRAM_INIT);
- dword |= DI_EnDramInit;
- pci_write_config32(ctrl[i].f2, DRAM_INIT, dword);
- dword &= ~DI_EnDramInit;
- pci_write_config32(ctrl[i].f2, DRAM_INIT, dword);
-
- tsc1[i] = rdtsc();
- print_debug_dqs_tsc("begin: tsc1", i, tsc1[i].hi, tsc1[i].lo, 2);
-
- dword = tsc1[i].lo + tsc0[i].lo;
- if ((dword < tsc1[i].lo) || (dword < tsc0[i].lo)) {
- tsc1[i].hi++;
- }
- tsc1[i].lo = dword;
- tsc1[i].hi+= tsc0[i].hi;
-
- print_debug_dqs_tsc("end : tsc1", i, tsc1[i].hi, tsc1[i].lo, 2);
-
- }
-
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[i])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- if (!cpu_f0_f1[i]) continue;
-
- tsc_t tsc;
-
- do {
- tsc = rdtsc();
- } while ((tsc1[i].hi > tsc.hi) || ((tsc1[i].hi == tsc.hi) && (tsc1[i].lo > tsc.lo)));
-
- print_debug_dqs_tsc("end : tsc ", i, tsc.hi, tsc.lo, 2);
- }
-
-}
-
-#endif
-
-
-/* setting variable mtrr, comes from linux kernel source */
-static void set_var_mtrr_dqs(
- unsigned int reg, unsigned long basek, unsigned long sizek,
- unsigned char type, unsigned address_bits)
-{
- msr_t base, mask;
- unsigned address_mask_high;
-
- address_mask_high = ((1u << (address_bits - 32u)) - 1u);
-
- base.hi = basek >> 22;
- base.lo = basek << 10;
-
- if (sizek < 4*1024*1024) {
- mask.hi = address_mask_high;
- mask.lo = ~((sizek << 10) -1);
- }
- else {
- mask.hi = address_mask_high & (~((sizek >> 22) -1));
- mask.lo = 0;
- }
-
- if (reg >= 8)
- return;
-
- if (sizek == 0) {
- msr_t zero;
- zero.lo = zero.hi = 0;
- /* The invalid bit is kept in the mask, so we simply clear the
- relevant mask register to disable a range. */
- wrmsr (MTRR_PHYS_MASK(reg), zero);
- } else {
- /* Bit 32-35 of MTRRphysMask should be set to 1 */
- base.lo |= type;
- mask.lo |= 0x800;
- wrmsr (MTRR_PHYS_BASE(reg), base);
- wrmsr (MTRR_PHYS_MASK(reg), mask);
- }
-}
-
-static unsigned int range_to_mtrr(unsigned int reg,
- unsigned long range_startk, unsigned long range_sizek,
- unsigned long next_range_startk, unsigned char type, unsigned address_bits)
-{
- if (!range_sizek || (reg >= 8)) {
- return reg;
- }
- while (range_sizek) {
- unsigned long max_align, align;
- unsigned long sizek;
- /* Compute the maximum size I can make a range */
- max_align = fls(range_startk);
- align = fms(range_sizek);
- if (align > max_align) {
- align = max_align;
- }
- sizek = 1 << align;
-#if CONFIG_MEM_TRAIN_SEQ != 1
- printk(BIOS_DEBUG, "Setting variable MTRR %d, base: %4ldMB, range: %4ldMB, type %s\n",
- reg, range_startk >>10, sizek >> 10,
- (type == MTRR_TYPE_UNCACHEABLE)?"UC":
- ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
- );
-#endif
- set_var_mtrr_dqs(reg++, range_startk, sizek, type, address_bits);
- range_startk += sizek;
- range_sizek -= sizek;
- if (reg >= 8)
- break;
- }
- return reg;
-}
-
-#if CONFIG_MEM_TRAIN_SEQ == 1
-static void set_top_mem_ap(unsigned tom_k, unsigned tom2_k)
-{
- msr_t msr;
-
- /* Now set top of memory */
- msr.lo = (tom2_k & 0x003fffff) << 10;
- msr.hi = (tom2_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM2, msr);
-
- msr.lo = (tom_k & 0x003fffff) << 10;
- msr.hi = (tom_k & 0xffc00000) >> 22;
- wrmsr(TOP_MEM, msr);
-}
-#endif
-
-static void setup_mtrr_dqs(unsigned tom_k, unsigned tom2_k)
-{
- msr_t msr;
-
- //[0,512k), [512k, 640k)
- msr.hi = 0x1e1e1e1e;
- msr.lo = msr.hi;
- wrmsr(0x250, msr);
- wrmsr(0x258, msr);
-
- //[1M, TOM)
- range_to_mtrr(2, 0, tom_k,4*1024*1024, MTRR_TYPE_WRBACK, 40);
-
- //[4G, TOM2)
- if (tom2_k) {
- //enable tom2 and type
- msr = rdmsr(SYSCFG_MSR);
- msr.lo |= (1<<21) | (1<<22); //MtrrTom2En and Tom2ForceMemTypeWB
- wrmsr(SYSCFG_MSR, msr);
- }
-
-}
-
-static void clear_mtrr_dqs(unsigned tom2_k)
-{
- msr_t msr;
- unsigned i;
-
- //still enable from cache_as_ram.inc
- msr = rdmsr(SYSCFG_MSR);
- msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
- wrmsr(SYSCFG_MSR,msr);
-
- //[0,512k), [512k, 640k)
- msr.hi = 0;
- msr.lo = msr.hi;
- wrmsr(0x250, msr);
- wrmsr(0x258, msr);
-
- //[1M, TOM)
- for (i = 0x204; i < 0x210; i++) {
- wrmsr(i, msr);
- }
-
- //[4G, TOM2)
- if (tom2_k) {
- //enable tom2 and type
- msr = rdmsr(SYSCFG_MSR);
- msr.lo &= ~((1<<21) | (1<<22)); //MtrrTom2En and Tom2ForceMemTypeWB
- wrmsr(SYSCFG_MSR, msr);
- }
-}
-
-#if CONFIG_MEM_TRAIN_SEQ == 1
-static void set_htic_bit(unsigned i, unsigned val, unsigned bit)
-{
- uint32_t dword;
- dword = pci_read_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL);
- dword &= ~(1 << bit);
- dword |= ((val & 1) << bit);
- pci_write_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL, dword);
-}
-
-static unsigned get_htic_bit(unsigned i, unsigned bit)
-{
- uint32_t dword;
- dword = pci_read_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL);
- dword &= (1 << bit);
- return dword;
-}
-
-static void wait_till_sysinfo_in_ram(void)
-{
- while (1) {
- if (get_htic_bit(0, 9)) return;
- }
-}
-#endif
-
-void set_sysinfo_in_ram(unsigned val)
-{
-#if CONFIG_MEM_TRAIN_SEQ == 1
- set_htic_bit(0, val, 9);
-#endif
-}
-
-#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
-
-#if CONFIG_MEM_TRAIN_SEQ == 0
-static int save_index_to_pos(unsigned int dev, int size, int index, int nvram_pos)
-{
- u32 dword = pci_read_config32_index_wait(dev, 0x98, index);
-
- return s3_save_nvram_early(dword, size, nvram_pos);
-}
-#endif
-
-static int load_index_to_pos(unsigned int dev, int size, int index, int nvram_pos)
-{
-
- u32 old_dword = pci_read_config32_index_wait(dev, 0x98, index);
- nvram_pos = s3_load_nvram_early(size, &old_dword, nvram_pos);
- pci_write_config32_index_wait(dev, 0x98, index, old_dword);
- return nvram_pos;
-}
-
-static int dqs_load_MC_NVRAM_ch(unsigned int dev, int ch, int pos)
-{
- /* 30 bytes per channel */
- ch *= 0x20;
- pos = load_index_to_pos(dev, 4, 0x00 + ch, pos);
- pos = load_index_to_pos(dev, 4, 0x01 + ch, pos);
- pos = load_index_to_pos(dev, 4, 0x02 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x03 + ch, pos);
- pos = load_index_to_pos(dev, 4, 0x04 + ch, pos);
- pos = load_index_to_pos(dev, 4, 0x05 + ch, pos);
- pos = load_index_to_pos(dev, 4, 0x06 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x07 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x10 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x13 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x16 + ch, pos);
- pos = load_index_to_pos(dev, 1, 0x19 + ch, pos);
- return pos;
-}
-
-#if CONFIG_MEM_TRAIN_SEQ == 0
-static int dqs_save_MC_NVRAM_ch(unsigned int dev, int ch, int pos)
-{
- /* 30 bytes per channel */
- ch *= 0x20;
- pos = save_index_to_pos(dev, 4, 0x00 + ch, pos);
- pos = save_index_to_pos(dev, 4, 0x01 + ch, pos);
- pos = save_index_to_pos(dev, 4, 0x02 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x03 + ch, pos);
- pos = save_index_to_pos(dev, 4, 0x04 + ch, pos);
- pos = save_index_to_pos(dev, 4, 0x05 + ch, pos);
- pos = save_index_to_pos(dev, 4, 0x06 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x07 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x10 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x13 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x16 + ch, pos);
- pos = save_index_to_pos(dev, 1, 0x19 + ch, pos);
- return pos;
-}
-
-static void dqs_save_MC_NVRAM(unsigned int dev)
-{
- int pos = 0;
- u32 reg;
- printk(BIOS_DEBUG, "DQS SAVE NVRAM: %x\n", dev);
- pos = dqs_save_MC_NVRAM_ch(dev, 0, pos);
- pos = dqs_save_MC_NVRAM_ch(dev, 1, pos);
- /* save the maxasync lat here */
- reg = pci_read_config32(dev, DRAM_CONFIG_HIGH);
- pos = s3_save_nvram_early(reg, 4, pos);
-}
-#endif
-
-void dqs_restore_MC_NVRAM(unsigned int dev)
-{
- int pos = 0;
- u32 reg;
-
- printk(BIOS_DEBUG, "DQS RESTORE FROM NVRAM: %x\n", dev);
- pos = dqs_load_MC_NVRAM_ch(dev, 0, pos);
- pos = dqs_load_MC_NVRAM_ch(dev, 1, pos);
- /* load the maxasync lat here */
- pos = s3_load_nvram_early(4, &reg, pos);
- reg &= (DCH_MaxAsyncLat_MASK << DCH_MaxAsyncLat_SHIFT);
- reg |= pci_read_config32(dev, DRAM_CONFIG_HIGH);
- pci_write_config32(dev, DRAM_CONFIG_HIGH, reg);
-}
-#endif
-
-#if CONFIG_MEM_TRAIN_SEQ == 0
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
-static void dqs_timing(int controllers, const struct mem_controller *ctrl, tsc_t *tsc0, struct sys_info *sysinfo)
-#else
-static void dqs_timing(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
-#endif
-{
- int i;
-
- tsc_t tsc[5];
-
- //need to enable mtrr, so dqs training could access the test address
- setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
-
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[ i ])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- fill_mem_cs_sysinfo(i, ctrl+i, sysinfo);
- }
-
- tsc[0] = rdtsc();
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[ i ])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- printk(BIOS_DEBUG, "DQS Training:RcvrEn:Pass1: %02x\n", i);
- if (train_DqsRcvrEn(ctrl+i, 1, sysinfo)) goto out;
- printk(BIOS_DEBUG, " done\n");
- }
-
- tsc[1] = rdtsc();
-#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
- f0_svm_workaround(controllers, ctrl, tsc0, sysinfo);
-#endif
-
- tsc[2] = rdtsc();
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[i])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- printk(BIOS_DEBUG, "DQS Training:DQSPos: %02x\n", i);
- if (train_DqsPos(ctrl+i, sysinfo)) goto out;
- printk(BIOS_DEBUG, " done\n");
- }
-
- tsc[3] = rdtsc();
- for (i = 0; i < controllers; i++) {
- if (!sysinfo->ctrl_present[i])
- continue;
-
- /* Skip everything if I don't have any memory on this controller */
- if (sysinfo->meminfo[i].dimm_mask == 0x00) continue;
-
- printk(BIOS_DEBUG, "DQS Training:RcvrEn:Pass2: %02x\n", i);
- if (train_DqsRcvrEn(ctrl+i, 2, sysinfo)) goto out;
- printk(BIOS_DEBUG, " done\n");
- sysinfo->mem_trained[i]=1;
-#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
- dqs_save_MC_NVRAM((ctrl+i)->f2);
-#endif
- }
-
-out:
- tsc[4] = rdtsc();
- clear_mtrr_dqs(sysinfo->tom2_k);
-
-
- for (i = 0; i < 5; i++) {
- print_debug_dqs_tsc_x("DQS Training:tsc", i, tsc[i].hi, tsc[i].lo);
- }
-
-
-
-}
-
-#endif
-
-
-#if CONFIG_MEM_TRAIN_SEQ > 0
-
-static void dqs_timing(int i, const struct mem_controller *ctrl, struct sys_info *sysinfo, unsigned v)
-{
-
- int ii;
-
- tsc_t tsc[4];
-
- if (sysinfo->mem_trained[i] != 0x80) return;
-
-#if CONFIG_MEM_TRAIN_SEQ == 1
- //need to enable mtrr, so dqs training could access the test address
- setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
-#endif
-
- fill_mem_cs_sysinfo(i, ctrl, sysinfo);
-
- if (v) {
- tsc[0] = rdtsc();
-
- printk(BIOS_DEBUG, "set DQS timing:RcvrEn:Pass1: %02x\n", i);
- }
- if (train_DqsRcvrEn(ctrl, 1, sysinfo)) {
- sysinfo->mem_trained[i]=0x81; //
- goto out;
- }
-
- if (v) {
- printk(BIOS_DEBUG, " done\n");
- tsc[1] = rdtsc();
- printk(BIOS_DEBUG, "set DQS timing:DQSPos: %02x\n", i);
- }
-
- if (train_DqsPos(ctrl, sysinfo)) {
- sysinfo->mem_trained[i]=0x82; //
- goto out;
- }
-
- if (v) {
- printk(BIOS_DEBUG, " done\n");
- tsc[2] = rdtsc();
-
- printk(BIOS_DEBUG, "set DQS timing:RcvrEn:Pass2: %02x\n", i);
- }
- if (train_DqsRcvrEn(ctrl, 2, sysinfo)) {
- sysinfo->mem_trained[i]=0x83; //
- goto out;
- }
-
- if (v) {
- printk(BIOS_DEBUG, " done\n");
-
- tsc[3] = rdtsc();
- }
-
-out:
-#if CONFIG_MEM_TRAIN_SEQ == 1
- clear_mtrr_dqs(sysinfo->tom2_k);
-#endif
-
- if (v) {
- for (ii = 0; ii < 4; ii++) {
- print_debug_dqs_tsc_x("Total DQS Training : tsc ", ii, tsc[ii].hi, tsc[ii].lo);
- }
- }
-
- if (sysinfo->mem_trained[i] == 0x80) {
- sysinfo->mem_trained[i]=1;
- }
-
-}
-#endif
-
-#if CONFIG_MEM_TRAIN_SEQ == 1
-static void train_ram(unsigned nodeid, struct sys_info *sysinfo, struct sys_info *sysinfox)
-{
- dqs_timing(nodeid, &sysinfo->ctrl[nodeid], sysinfo, 0); // keep the output tidy
- sysinfox->mem_trained[nodeid] = sysinfo->mem_trained[nodeid];
-
-}
-
-void train_ram_on_node(unsigned nodeid, unsigned coreid, struct sys_info *sysinfo, unsigned retcall)
-{
- if (coreid) return; // only do it on core0
- struct sys_info *sysinfox;
- uintptr_t migrated_base = CONFIG_RAMTOP - car_data_size();
-
- sysinfox = (void *)(migrated_base + car_object_offset(&sysinfo_car));
-
- wait_till_sysinfo_in_ram(); // use pci to get it
-
- if (sysinfox->mem_trained[nodeid] == 0x80) {
- memcpy(sysinfo, sysinfox, sizeof(*sysinfo));
- set_top_mem_ap(sysinfo->tom_k, sysinfo->tom2_k); // keep the ap's tom consistent with bsp's
- printk(BIOS_DEBUG, "CODE IN ROM AND RUN ON NODE: %02x\n", nodeid);
- train_ram(nodeid, sysinfo, sysinfox);
- }
-}
-#endif
diff --git a/src/northbridge/amd/amdk8/raminit_test.c b/src/northbridge/amd/amdk8/raminit_test.c
deleted file mode 100644
index a22db10129..0000000000
--- a/src/northbridge/amd/amdk8/raminit_test.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <unistd.h>
-#include <limits.h>
-#include <lib.h>
-#include <stdint.h>
-#include <string.h>
-#include <setjmp.h>
-#include <device/pci_def.h>
-#include <stdlib.h>
-#include "amdk8.h"
-
-jmp_buf end_buf;
-
-static int is_cpu_pre_c0(void)
-{
- return 0;
-}
-
-#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
- (((BUS) & 0xFF) << 16) | \
- (((DEV) & 0x1f) << 11) | \
- (((FN) & 0x07) << 8) | \
- ((WHERE) & 0xFF))
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFF) << 16) | \
- (((DEV) & 0x1f) << 11) | \
- (((FN) & 0x7) << 8))
-
-#define PCI_ID(VENDOR_ID, DEVICE_ID) \
- ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
-
-typedef unsigned device_t;
-
-unsigned char pci_register[256*5*3*256];
-
-static uint8_t pci_read_config8(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = dev | where;
- return pci_register[addr];
-}
-
-static uint16_t pci_read_config16(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = dev | where;
- return pci_register[addr] | (pci_register[addr + 1] << 8);
-}
-
-static uint32_t pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- uint32_t value;
- addr = dev | where;
- value = pci_register[addr] |
- (pci_register[addr + 1] << 8) |
- (pci_register[addr + 2] << 16) |
- (pci_register[addr + 3] << 24);
- return value;
-
-}
-
-static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
-{
- unsigned addr;
- addr = dev | where;
- pci_register[addr] = value;
-}
-
-static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
-{
- unsigned addr;
- addr = dev | where;
- pci_register[addr] = value & 0xff;
- pci_register[addr + 1] = (value >> 8) & 0xff;
-}
-
-static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
-{
- unsigned addr;
- addr = dev | where;
- pci_register[addr] = value & 0xff;
- pci_register[addr + 1] = (value >> 8) & 0xff;
- pci_register[addr + 2] = (value >> 16) & 0xff;
- pci_register[addr + 3] = (value >> 24) & 0xff;
-}
-
-#define PCI_DEV_INVALID (0xffffffffU)
-static device_t pci_locate_device(unsigned pci_id, device_t dev)
-{
- for (; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
- unsigned int id;
- id = pci_read_config32(dev, 0);
- if (id == pci_id) {
- return dev;
- }
- }
- return PCI_DEV_INVALID;
-}
-
-
-
-
-static void uart_tx_byte(unsigned char data)
-{
- write(STDOUT_FILENO, &data, 1);
-}
-static void hlt(void)
-{
- longjmp(end_buf, 2);
-}
-#include "console/console.c"
-
-unsigned long log2(unsigned long x)
-{
- // assume 8 bits per byte.
- unsigned long i = 1 << (sizeof(x)*8 - 1);
- unsigned long pow = sizeof(x) * 8 - 1;
-
- if (! x) {
- static const char errmsg[] = " called with invalid parameter of 0\n";
- write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
- write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
- hlt();
- }
- for (; i > x; i >>= 1, pow--)
- ;
-
- return pow;
-}
-
-typedef struct msr_struct
-{
- unsigned lo;
- unsigned hi;
-} msr_t;
-
-static inline msr_t rdmsr(unsigned index)
-{
- msr_t result;
- result.lo = 0;
- result.hi = 0;
- return result;
-}
-
-static inline void wrmsr(unsigned index, msr_t msr)
-{
-}
-
-#include "raminit.h"
-
-#define SIO_BASE 0x2e
-
-static void hard_reset(void)
-{
- /* FIXME implement the hard reset case... */
- longjmp(end_buf, 3);
-}
-
-static void memreset_setup(void)
-{
- /* Nothing to do */
-}
-
-static void memreset(int controllers, const struct mem_controller *ctrl)
-{
- /* Nothing to do */
-}
-
-void activate_spd_rom(const struct mem_controller *ctrl)
-{
- /* nothing to do */
-}
-
-
-static uint8_t spd_mt4lsdt464a[256] =
-{
- 0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70,
- 0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01,
- 0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
-
- 0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
- 0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x08, 0x09, 0x00,
-};
-
-static uint8_t spd_micron_512MB_DDR333[256] =
-{
- 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60,
- 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
- 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
- 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31,
- 0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43,
- 0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-static uint8_t spd_micron_256MB_DDR333[256] =
-{
- 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60,
- 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
- 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
- 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36,
- 0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
- 0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-#define MAX_DIMMS 16
-static uint8_t spd_data[MAX_DIMMS*256];
-
-static unsigned spd_count, spd_fail_count;
-static int spd_read_byte(unsigned device, unsigned address)
-{
- int result;
- spd_count++;
- if ((device < DIMM0) || (device >= (DIMM0 + MAX_DIMMS))) {
- result = -1;
- }
- else {
- device -= DIMM0; /* 0x50 */
-
- if (address > 256) {
- result = -1;
- }
- else if (spd_data[(device << 8) | 2] != 7) {
- result = -1;
- }
- else {
- result = spd_data[(device << 8) | address];
- }
- }
- if (spd_count >= spd_fail_count) {
- result = -1;
- }
- return result;
-}
-
-/* no specific code here. this should go away completely */
-static void coherent_ht_mainboard(unsigned cpus)
-{
-}
-
-#include "raminit.c"
-#include "../../../lib/generic_sdram.c"
-
-#define FIRST_CPU 1
-#define SECOND_CPU 1
-#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
-static void raminit_main(void)
-{
- /*
- * GPIO28 of 8111 will control H0_MEMRESET_L
- * GPIO29 of 8111 will control H1_MEMRESET_L
- */
- static const struct mem_controller cpu[] = {
-#if FIRST_CPU
- {
- .node_id = 0,
- .f0 = PCI_DEV(0, 0x18, 0),
- .f1 = PCI_DEV(0, 0x18, 1),
- .f2 = PCI_DEV(0, 0x18, 2),
- .f3 = PCI_DEV(0, 0x18, 3),
- .channel0 = { DIMM0+0, DIMM0+2, DIMM0+4, DIMM0+6 },
- .channel1 = { DIMM0+1, DIMM0+3, DIMM0+5, DIMM0+7 },
- },
-#endif
-#if SECOND_CPU
- {
- .node_id = 1,
- .f0 = PCI_DEV(0, 0x19, 0),
- .f1 = PCI_DEV(0, 0x19, 1),
- .f2 = PCI_DEV(0, 0x19, 2),
- .f3 = PCI_DEV(0, 0x19, 3),
- .channel0 = { DIMM0+8, DIMM0+10, DIMM0+12, DIMM0+14 },
- .channel1 = { DIMM0+9, DIMM0+11, DIMM0+13, DIMM0+15 },
- },
-#endif
- };
- console_init();
- memreset_setup();
- sdram_initialize(ARRAY_SIZE(cpu), cpu);
-
-}
-
-static void reset_tests(void)
-{
- /* Clear the results of any previous tests */
- memset(pci_register, 0, sizeof(pci_register));
- memset(spd_data, 0, sizeof(spd_data));
- spd_count = 0;
- spd_fail_count = UINT_MAX;
-
- pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
- NBCAP_128Bit |
- NBCAP_MP| NBCAP_BIG_MP |
- /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
- (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
- NBCAP_MEMCTRL);
-
- pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
- NBCAP_128Bit |
- NBCAP_MP| NBCAP_BIG_MP |
- /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
- (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
- NBCAP_MEMCTRL);
-}
-
-static void test1(void)
-{
- reset_tests();
-
- memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
- memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
- raminit_main();
-}
-
-
-static void do_test2(int i)
-{
- jmp_buf tmp_buf;
- memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
- if (setjmp(end_buf) != 0) {
- goto done;
- }
- reset_tests();
- spd_fail_count = i;
-
- printk(BIOS_DEBUG, "\nSPD will fail after: %d accesses.\n", %d);
-
- memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
- memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
-
- raminit_main();
-
-done:
- memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
-}
-
-static void test2(void)
-{
- int i;
- for (i = 0; i < 0x48; i++) {
- do_test2(i);
- }
-
-}
-
-int main(int argc, char **argv)
-{
- if (setjmp(end_buf) != 0) {
- return -1;
- }
- test1();
- test2();
- return 0;
-}
diff --git a/src/northbridge/amd/amdk8/resourcemap.c b/src/northbridge/amd/amdk8/resourcemap.c
deleted file mode 100644
index 2bf868050c..0000000000
--- a/src/northbridge/amd/amdk8/resourcemap.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-static void setup_default_resource_map(void)
-{
- static const unsigned int register_values[] = {
- /* Careful set limit registers before base registers which contain the enables */
- /* DRAM Limit i Registers
- * F1:0x44 i = 0
- * F1:0x4C i = 1
- * F1:0x54 i = 2
- * F1:0x5C i = 3
- * F1:0x64 i = 4
- * F1:0x6C i = 5
- * F1:0x74 i = 6
- * F1:0x7C i = 7
- * [ 2: 0] Destination Node ID
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 7: 3] Reserved
- * [10: 8] Interleave select
- * specifies the values of A[14:12] to use with interleave enable.
- * [15:11] Reserved
- * [31:16] DRAM Limit Address i Bits 39-24
- * This field defines the upper address bits of a 40 bit address
- * that define the end of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
- PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
- PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
- PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
- PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
- PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
- PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
- /* DRAM Base i Registers
- * F1:0x40 i = 0
- * F1:0x48 i = 1
- * F1:0x50 i = 2
- * F1:0x58 i = 3
- * F1:0x60 i = 4
- * F1:0x68 i = 5
- * F1:0x70 i = 6
- * F1:0x78 i = 7
- * [ 0: 0] Read Enable
- * 0 = Reads Disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes Disabled
- * 1 = Writes Enabled
- * [ 7: 2] Reserved
- * [10: 8] Interleave Enable
- * 000 = No interleave
- * 001 = Interleave on A[12] (2 nodes)
- * 010 = reserved
- * 011 = Interleave on A[12] and A[14] (4 nodes)
- * 100 = reserved
- * 101 = reserved
- * 110 = reserved
- * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
- * [15:11] Reserved
- * [13:16] DRAM Base Address i Bits 39-24
- * This field defines the upper address bits of a 40-bit address
- * that define the start of the DRAM region.
- */
- PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
- /* Memory-Mapped I/O Limit i Registers
- * F1:0x84 i = 0
- * F1:0x8C i = 1
- * F1:0x94 i = 2
- * F1:0x9C i = 3
- * F1:0xA4 i = 4
- * F1:0xAC i = 5
- * F1:0xB4 i = 6
- * F1:0xBC i = 7
- * [ 2: 0] Destination Node ID
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 3: 3] Reserved
- * [ 5: 4] Destination Link ID
- * 00 = Link 0
- * 01 = Link 1
- * 10 = Link 2
- * 11 = Reserved
- * [ 6: 6] Reserved
- * [ 7: 7] Non-Posted
- * 0 = CPU writes may be posted
- * 1 = CPU writes must be non-posted
- * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
- * This field defines the upp adddress bits of a 40-bit address that
- * defines the end of a memory-mapped I/O region n
- */
- PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00,
-
- /* Memory-Mapped I/O Base i Registers
- * F1:0x80 i = 0
- * F1:0x88 i = 1
- * F1:0x90 i = 2
- * F1:0x98 i = 3
- * F1:0xA0 i = 4
- * F1:0xA8 i = 5
- * F1:0xB0 i = 6
- * F1:0xB8 i = 7
- * [ 0: 0] Read Enable
- * 0 = Reads disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes disabled
- * 1 = Writes Enabled
- * [ 2: 2] Cpu Disable
- * 0 = Cpu can use this I/O range
- * 1 = Cpu requests do not use this I/O range
- * [ 3: 3] Lock
- * 0 = base/limit registers i are read/write
- * 1 = base/limit registers i are read-only
- * [ 7: 4] Reserved
- * [31: 8] Memory-Mapped I/O Base Address i (39-16)
- * This field defines the upper address bits of a 40bit address
- * that defines the start of memory-mapped I/O region i
- */
- PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
-
- /* PCI I/O Limit i Registers
- * F1:0xC4 i = 0
- * F1:0xCC i = 1
- * F1:0xD4 i = 2
- * F1:0xDC i = 3
- * [ 2: 0] Destination Node ID
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 3: 3] Reserved
- * [ 5: 4] Destination Link ID
- * 00 = Link 0
- * 01 = Link 1
- * 10 = Link 2
- * 11 = reserved
- * [11: 6] Reserved
- * [24:12] PCI I/O Limit Address i
- * This field defines the end of PCI I/O region n
- * [31:25] Reserved
- */
- PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff000,
- PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
-
- /* PCI I/O Base i Registers
- * F1:0xC0 i = 0
- * F1:0xC8 i = 1
- * F1:0xD0 i = 2
- * F1:0xD8 i = 3
- * [ 0: 0] Read Enable
- * 0 = Reads Disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes Disabled
- * 1 = Writes Enabled
- * [ 3: 2] Reserved
- * [ 4: 4] VGA Enable
- * 0 = VGA matches Disabled
- * 1 = matches all address < 64K and where A[9:0] is in the
- * range 3B0-3BB or 3C0-3DF independen of the base & limit registers
- * [ 5: 5] ISA Enable
- * 0 = ISA matches Disabled
- * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
- * from matching agains this base/limit pair
- * [11: 6] Reserved
- * [24:12] PCI I/O Base i
- * This field defines the start of PCI I/O region n
- * [31:25] Reserved
- */
- PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003,
- PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
-
- /* Config Base and Limit i Registers
- * F1:0xE0 i = 0
- * F1:0xE4 i = 1
- * F1:0xE8 i = 2
- * F1:0xEC i = 3
- * [ 0: 0] Read Enable
- * 0 = Reads Disabled
- * 1 = Reads Enabled
- * [ 1: 1] Write Enable
- * 0 = Writes Disabled
- * 1 = Writes Enabled
- * [ 2: 2] Device Number Compare Enable
- * 0 = The ranges are based on bus number
- * 1 = The ranges are ranges of devices on bus 0
- * [ 3: 3] Reserved
- * [ 6: 4] Destination Node
- * 000 = Node 0
- * 001 = Node 1
- * 010 = Node 2
- * 011 = Node 3
- * 100 = Node 4
- * 101 = Node 5
- * 110 = Node 6
- * 111 = Node 7
- * [ 7: 7] Reserved
- * [ 9: 8] Destination Link
- * 00 = Link 0
- * 01 = Link 1
- * 10 = Link 2
- * 11 - Reserved
- * [15:10] Reserved
- * [23:16] Bus Number Base i
- * This field defines the lowest bus number in configuration region i
- * [31:24] Bus Number Limit i
- * This field defines the highest bus number in configuration region i
- */
- PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000003,
- PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
- PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
- };
- int max;
- max = ARRAY_SIZE(register_values);
- setup_resource_map(register_values, max);
-}
diff --git a/src/northbridge/amd/amdk8/setup_resource_map.c b/src/northbridge/amd/amdk8/setup_resource_map.c
deleted file mode 100644
index 23d2949b1d..0000000000
--- a/src/northbridge/amd/amdk8/setup_resource_map.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include "amdk8.h"
-
-#define RES_DEBUG 0
-
-void setup_resource_map_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base)
-{
- int i;
-#if RES_DEBUG
- printk(BIOS_DEBUG, "setting up resource map offset....\n");
-#endif
- for (i = 0; i < max; i += 3) {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg = 0;
-#if RES_DEBUG
- prink_debug("%08x <- %08x\n", register_values[i] + offset_pci_dev, register_values[i+2]);
-#endif
- dev = (register_values[i] & ~0xfff) + offset_pci_dev;
- where = register_values[i] & 0xfff;
- if (register_values[i+1])
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+1];
- reg |= register_values[i+2] + offset_io_base;
- pci_write_config32(dev, where, reg);
- }
-#if RES_DEBUG
- printk(BIOS_DEBUG, "done.\n");
-#endif
-}
-
-#define RES_PCI_IO 0x10
-#define RES_PORT_IO_8 0x22
-#define RES_PORT_IO_32 0x20
-#define RES_MEM_IO 0x40
-
-static void setup_resource_map_x_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base)
-{
- int i;
-
-#if RES_DEBUG
- printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
-#endif
- for (i = 0; i < max; i += 4) {
-#if RES_DEBUG
- printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
- i>>2, register_values[i],
- register_values[i+1] + ((register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0),
- register_values[i+2],
- register_values[i+3] + (((register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
- );
-#endif
- switch (register_values[i]) {
- case RES_PCI_IO: //PCI
- {
- pci_devfn_t dev;
- unsigned where;
- unsigned long reg = 0;
- dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
- where = register_values[i+1] & 0xfff;
- if (register_values[i+2])
- reg = pci_read_config32(dev, where);
- reg &= register_values[i+2];
- reg |= register_values[i+3];
- pci_write_config32(dev, where, reg);
- }
- break;
- case RES_PORT_IO_8: // io 8
- {
- unsigned where;
- unsigned reg = 0;
- where = register_values[i+1] + offset_io_base;
- if (register_values[i+2])
- reg = inb(where);
- reg &= register_values[i+2];
- reg |= register_values[i+3];
- outb(reg, where);
- }
- break;
- case RES_PORT_IO_32: //io32
- {
- unsigned where;
- unsigned long reg = 0;
- where = register_values[i+1] + offset_io_base;
- if (register_values[i+2])
- reg = inl(where);
- reg &= register_values[i+2];
- reg |= register_values[i+3];
- outl(reg, where);
- }
- break;
- } // switch
-
-
- }
-
-#if RES_DEBUG
- printk(BIOS_DEBUG, "done.\n");
-#endif
-}
-
-static inline void setup_resource_map_x(const unsigned int *register_values, int max)
-{
- setup_resource_map_x_offset(register_values, max, 0, 0);
-}
diff --git a/src/northbridge/amd/amdk8/thermal_mixin.asl b/src/northbridge/amd/amdk8/thermal_mixin.asl
deleted file mode 100644
index b738d965c8..0000000000
--- a/src/northbridge/amd/amdk8/thermal_mixin.asl
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Christoph Grenz <christophg+cb@grenz-bonn.de>
- *
- * 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.
- */
-
-/*
- * include this file into a mainboards DSDT inside the PCI device
- * "K8 Miscellaneous Control" and it will expose the temperature
- * sensors of the processor as thermal zones.
- *
- * If, for example, the K8 Misc. Control device is on 0:18.3, include the
- * following inside the PCI0 device:
- *
- * Device(K8MC) {
- * Name (_ADR, 0x00180003)
- * #include northbridge/amd/amdk8/thermal_mixin.asl
- * }
- *
- * Note: as only the current temperature and the trip temperature for
- * "Software Thermal Control" are available in the PCI registers, but the
- * linux driver for thermal zones needs a critical temperature value, a
- * reasonable critical temperature is calculated by simply adding 6°C to
- * the trip temperature.
- *
- * The used registers are documented in the "BIOS and Kernel Developer's
- * Guide for AMD NPT Family 0Fh Processors"
- * http://support.amd.com/us/Processor_TechDocs/32559.pdf
- *
- */
-
-#ifndef K8TEMP_CRITICAL_ADD
-# define K8TEMP_CRITICAL_ADD 6
-#endif
-
-OperationRegion(K8TR, PCI_Config, 0xE4, 0x4)
-Field(K8TR, DWordAcc, NoLock, Preserve) {
- , 1,
- THTP, 1, /* Temperature sensor trip occurred */
- CORE, 1, /* Select Core */
- TTS0, 1, /* Temperature sensor trip on CPU1 (or single core CPU0) */
- TTS1, 1, /* Temperature sensor trip on CPU0 */
- TTEN, 1, /* Temperature sensor trip enabled */
- PLAC, 1, /* Select Sensor */
- , 1,
- DOFF, 6, /* Diode offset (signed 6bit-Integer) in °C */
- TFRC, 2, /* Temperature fractions */
- TVAL, 8, /* Temperature value in °C biased by -49 */
- TJOF, 5,
- , 2,
- SWTT, 1, /* Induce a thermtrip event (for diagnostic purposes) */
-}
-
-OperationRegion(K8ST, PCI_Config, 0x70, 0x1)
-Field(K8ST, ByteAcc, NoLock, Preserve) {
- TMAX, 5, /* Maximum temperature for software thermal control, in °C, biased by 52 */
-}
-
-/* Calculates temperature in tenths Kelvin from given TVAL and TFRC values */
-Method(K8PT, 2) {
- Divide(Multiply(Arg1, 5), 2, , Local0)
- Return (Add(Multiply(Add(Arg0, 224),10), Local0))
-}
-
-/* Calculates the diode offset from a DOFF value */
-Method(K8PO, 1) {
- If (And(Arg0, 0x20))
- {
- Return (Multiply(Subtract(Xor(Arg0, 0x3F), 1), 10))
- }
- Else {
- Return (Multiply(Arg0, 10))
- }
-}
-
-ThermalZone (K8T0) {
- Name(_HID, EisaId("PNP0C11"))
- Name(_UID, "k8-0")
- Name(_STR, Unicode("K8 compatible CPU Core 1 Thermal Sensor 1"))
-
- Method(_STA) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(Zero, PLAC)
- If (LOr(PLAC, CORE)) {
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x00)
- }
-
- If (LOr(LNot(TVAL), LEqual(TVAL, 0xFF))) {
- Return (0x00)
- }
-
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x0F)
- }
-
- Method(_TMP) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(Zero, PLAC)
-
- Store (K8PT(TVAL, TFRC), Local2)
- Add (K8PO(DOFF), Local2, Local2)
- Store(Local0, CORE)
- Store(Local1, PLAC)
-
- Return (Local2)
- }
-
- Method(_CRT) {
- Add(TMAX, 325, Local0)
- Add(Local0, K8TEMP_CRITICAL_ADD, Local0)
- Return (Multiply(Local0, 10))
- }
-}
-
-ThermalZone (K8T1) {
- Name(_HID, EisaId("PNP0C11"))
- Name(_UID, "k8-1")
- Name(_STR, Unicode("K8 compatible CPU Core 1 Thermal Sensor 2"))
-
- Name(_TZD, Package () {\_PR.CP00})
-
- Method(_STA) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(Zero, PLAC)
- If (LOr(PLAC, CORE)) {
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x00)
- }
-
- Store(One, PLAC)
- If (LOr(LNot(TVAL), LEqual(TVAL, 0xFF))) {
- Return (0x00)
- }
-
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x0F)
- }
-
- Method(_TMP) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(One, PLAC)
-
- Store (K8PT(TVAL, TFRC), Local2)
- Add (K8PO(DOFF), Local2, Local2)
- Store(Local0, CORE)
- Store(Local1, PLAC)
-
- Return (Local2)
- }
-
- Method(_CRT) {
- Add(TMAX, 325, Local0)
- Add(Local0, K8TEMP_CRITICAL_ADD, Local0)
- Return (Multiply(Local0, 10))
- }
-}
-
-ThermalZone (K8T2) {
- Name(_HID, EisaId("PNP0C11"))
- Name(_UID, "k8-2")
- Name(_STR, Unicode("K8 compatible CPU Core 2 Thermal Sensor 1"))
-
- Name(_TZD, Package () {\_PR.CP00})
-
- Method(_STA) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(Zero, PLAC)
- If (LOr(PLAC, CORE)) {
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x00)
- }
-
- Store(One, CORE)
- If (LOr(LNot(TVAL), LEqual(TVAL, 0xFF))) {
- Return (0x00)
- }
-
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x0F)
- }
-
- Method(_TMP) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(One, CORE)
- Store(Zero, PLAC)
-
- Store (K8PT(TVAL, TFRC), Local2)
- Add (K8PO(DOFF), Local2, Local2)
- Store(Local0, CORE)
- Store(Local1, PLAC)
-
- Return (Local2)
- }
-
- Method(_CRT) {
- Add(TMAX, 325, Local0)
- Add(Local0, K8TEMP_CRITICAL_ADD, Local0)
- Return (Multiply(Local0, 10))
- }
-}
-
-ThermalZone (K8T3) {
- Name(_HID, EisaId("PNP0C11"))
- Name(_UID, "k8-3")
- Name(_STR, Unicode("K8 compatible CPU Core 2 Thermal Sensor 2"))
-
- Name(_TZD, Package () {\_PR.CP00})
-
- Method(_STA) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(Zero, CORE)
- Store(Zero, PLAC)
- If (LOr(PLAC, CORE)) {
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x00)
- }
-
- Store(One, CORE)
- Store(One, PLAC)
- If (LOr(LNot(TVAL), LEqual(TVAL, 0xFF))) {
- Return (0x00)
- }
-
- Store(Local0, CORE)
- Store(Local1, PLAC)
- Return (0x0F)
- }
-
- Method(_TMP) {
- Store(CORE, Local0)
- Store(PLAC, Local1)
-
- Store(One, CORE)
- Store(One, PLAC)
-
- Store (K8PT(TVAL, TFRC), Local2)
- Add (K8PO(DOFF), Local2, Local2)
- Store(Local0, CORE)
- Store(Local1, PLAC)
-
- Return (Local2)
- }
-
- Method(_CRT) {
- Add(TMAX, 325, Local0)
- Add(Local0, K8TEMP_CRITICAL_ADD, Local0)
- Return (Multiply(Local0, 10))
- }
-}
diff --git a/src/northbridge/amd/amdk8/util.asl b/src/northbridge/amd/amdk8/util.asl
deleted file mode 100644
index d272233d2d..0000000000
--- a/src/northbridge/amd/amdk8/util.asl
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2005 AMD
- *
- * 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.
- */
-
-//AMD k8 util for BUSB and res range
-
-Scope (\_SB)
-{
-
- Name (OSTB, Ones)
- Method (OSVR, 0, NotSerialized)
- {
- If (LEqual (^OSTB, Ones))
- {
- Store (0x00, ^OSTB)
- }
-
- Return (^OSTB)
- }
-
- Method (SEQL, 2, Serialized)
- {
- Store (SizeOf (Arg0), Local0)
- Store (SizeOf (Arg1), Local1)
- If (LNot (LEqual (Local0, Local1))) { Return (Zero) }
-
- Name (BUF0, Buffer (Local0) {})
- Store (Arg0, BUF0)
- Name (BUF1, Buffer (Local0) {})
- Store (Arg1, BUF1)
- Store (Zero, Local2)
- While (LLess (Local2, Local0))
- {
- Store (DerefOf (Index (BUF0, Local2)), Local3)
- Store (DerefOf (Index (BUF1, Local2)), Local4)
- If (LNot (LEqual (Local3, Local4))) { Return (Zero) }
-
- Increment (Local2)
- }
-
- Return (One)
- }
-
-
- Method (DADD, 2, NotSerialized)
- {
- Store(Arg1, Local0)
- Store(Arg0, Local1)
- Add(ShiftLeft(Local1,16), Local0, Local0)
- Return (Local0)
- }
-
-
- Method (GHCE, 1, NotSerialized) // check if the HC enabled
- {
- Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
- if (LEqual (And(Local1, 0x01), 0x01)) { Return (0x0F) }
- Else { Return (0x00) }
- }
-
- Method (GHCN, 1, NotSerialized) // get the node num for the HC
- {
- Store (0x00, Local0)
- Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
- Store (ShiftRight(And (Local1, 0xf0), 0x04), Local0)
- Return (Local0)
- }
-
- Method (GHCL, 1, NotSerialized) // get the link num on node for the HC
- {
- Store (0x00, Local0)
- Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
- Store (ShiftRight(And (Local1, 0xf00), 0x08), Local0)
- Return (Local0)
- }
-
- Method (GHCD, 2, NotSerialized) // get the unit id base for the HT device in HC
- {
- Store (0x00, Local0)
- Store (DerefOf (Index (\_SB.PCI0.HCDN, Arg0)), Local1)
- Store (Arg1, Local2) // Arg1 could be 3, 2, 1, 0
- Multiply (Local2, 0x08, Local2) // change to 24, 16, 8, 0
- Store (And (ShiftRight(Local1, Local2), 0xff), Local0)
- Return (Local0)
- }
-
- /* GetBus(Node, Link) */
- Method (GBUS, 2, NotSerialized)
- {
- Store (0x00, Local0)
- While (LLess (Local0, 0x04))
- {
- Store (DerefOf (Index (\_SB.PCI0.BUSN, Local0)), Local1)
- If (LEqual (And (Local1, 0x03), 0x03))
- {
- If (LEqual (Arg0, ShiftRight (And (Local1, 0x70), 0x04)))
- {
- If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local1, 0x0300), 0x08))))
- {
- Return (ShiftRight (And (Local1, 0x00FF0000), 0x10))
- }
- }
- }
-
- Increment (Local0)
- }
-
- Return (0x00)
- }
-
- /* GetBusResources(Node, Link) */
- Method (GWBN, 2, Serialized)
- {
- Name (BUF0, ResourceTemplate ()
- {
- WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
- 0x0000, // Address Space Granularity
- 0x0000, // Address Range Minimum
- 0x0000, // Address Range Maximum
- 0x0000, // Address Translation Offset
- 0x0001,,,)
- })
- CreateWordField (BUF0, 0x08, BMIN)
- CreateWordField (BUF0, 0x0A, BMAX)
- CreateWordField (BUF0, 0x0E, BLEN)
- Store (0x00, Local0)
- While (LLess (Local0, 0x04))
- {
- Store (DerefOf (Index (\_SB.PCI0.BUSN, Local0)), Local1)
- If (LEqual (And (Local1, 0x03), 0x03))
- {
- If (LEqual (Arg0, ShiftRight (And (Local1, 0x70), 0x04)))
- {
- If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local1, 0x0300), 0x08))))
- {
- Store (ShiftRight (And (Local1, 0x00FF0000), 0x10), BMIN)
- Store (ShiftRight (Local1, 0x18), BMAX)
- Subtract (BMAX, BMIN, BLEN)
- Increment (BLEN)
- Return (RTAG (BUF0))
- }
- }
- }
-
- Increment (Local0)
- }
-
- Return (RTAG (BUF0))
- }
-
- /* GetMemoryResources(Node, Link) */
- Method (GMEM, 2, Serialized)
- {
- Name (BUF0, ResourceTemplate ()
- {
- DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
- 0x00000000, // Address Space Granularity
- 0x00000000, // Address Range Minimum
- 0x00000000, // Address Range Maximum
- 0x00000000, // Address Translation Offset
- 0x00000001,,,
- , AddressRangeMemory, TypeStatic)
- })
- CreateDWordField (BUF0, 0x0A, MMIN)
- CreateDWordField (BUF0, 0x0E, MMAX)
- CreateDWordField (BUF0, 0x16, MLEN)
- Store (0x00, Local0)
- Store (0x00, Local4)
- Store (0x00, Local3)
- While (LLess (Local0, 0x10))
- {
- /* Get value of the first register */
- Store (DerefOf (Index (\_SB.PCI0.MMIO, Local0)), Local1)
- Increment (Local0)
- Store (DerefOf (Index (\_SB.PCI0.MMIO, Local0)), Local2)
- If (LEqual (And (Local1, 0x03), 0x03)) /* Pair enabled? */
- {
- If (LEqual (Arg0, And (Local2, 0x07))) /* Node matches? */
- {
- /* If Link Matches (or we got passed 0xFF) */
- If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local2, 0x30), 0x04))))
- {
- /* Extract the Base and Limit values */
- Store (ShiftLeft (And (Local1, 0xFFFFFF00), 0x08), MMIN)
- Store (ShiftLeft (And (Local2, 0xFFFFFF00), 0x08), MMAX)
- Or (MMAX, 0xFFFF, MMAX)
- Subtract (MMAX, MMIN, MLEN)
- Increment (MLEN)
-
- If (Local4) /* I've already done this once */
- {
- Concatenate (RTAG (BUF0), Local3, Local5)
- Store (Local5, Local3)
- }
- Else
- {
- Store (RTAG (BUF0), Local3)
- }
-
- Increment (Local4)
- }
- }
- }
-
- Increment (Local0)
- }
-
- If (LNot (Local4)) /* No resources for this node and link. */
- {
- Store (RTAG (BUF0), Local3)
- }
-
- Return (Local3)
- }
-
- /* GetIOResources(Node, Link) */
- Method (GIOR, 2, Serialized)
- {
- Name (BUF0, ResourceTemplate ()
- {
- DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
- 0x00000000, // Address Space Granularity
- 0x00000000, // Address Range Minimum
- 0x00000000, // Address Range Maximum
- 0x00000000, // Address Translation Offset
- 0x00000001,,,
- , TypeStatic)
- })
- CreateDWordField (BUF0, 0x0A, PMIN)
- CreateDWordField (BUF0, 0x0E, PMAX)
- CreateDWordField (BUF0, 0x16, PLEN)
- Store (0x00, Local0)
- Store (0x00, Local4)
- Store (0x00, Local3)
- While (LLess (Local0, 0x08))
- {
- Store (DerefOf (Index (\_SB.PCI0.PCIO, Local0)), Local1)
- Increment (Local0)
- Store (DerefOf (Index (\_SB.PCI0.PCIO, Local0)), Local2)
- If (LEqual (And (Local1, 0x03), 0x03)) /* Pair enabled? */
- {
- If (LEqual (Arg0, And (Local2, 0x07))) /* Node matches? */
- {
- /* If Link Matches (or we got passed 0xFF) */
- If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local2, 0x30), 0x04))))
- {
- /* Extract the Base and Limit values */
- Store (And (Local1, 0x01FFF000), PMIN)
- Store (And (Local2, 0x01FFF000), PMAX)
- Or (PMAX, 0x0FFF, PMAX)
- Subtract (PMAX, PMIN, PLEN)
- Increment (PLEN)
-
- If (Local4) /* I've already done this once */
- {
- Concatenate (RTAG (BUF0), Local3, Local5)
- Store (Local5, Local3)
- }
- Else
- {
- If (LGreater (PMAX, PMIN))
- {
- If (LOr (LAnd (LEqual (Arg1, 0xFF), LEqual (Arg0, 0x00)), LEqual (Arg1, \_SB.PCI0.SBLK)))
- {
- Store (0x0D00, PMIN)
- Subtract (PMAX, PMIN, PLEN)
- Increment (PLEN)
- }
-
- Store (RTAG (BUF0), Local3)
- Increment (Local4)
- }
-
- If (And (Local1, 0x10))
- {
- Store (0x03B0, PMIN)
- Store (0x03DF, PMAX)
- Store (0x30, PLEN)
-
- If (Local4)
- {
- Concatenate (RTAG (BUF0), Local3, Local5)
- Store (Local5, Local3)
- }
- Else
- {
- Store (RTAG (BUF0), Local3)
- }
- }
- }
-
- Increment (Local4)
- }
- }
- }
-
- Increment (Local0)
- }
-
- If (LNot (Local4)) /* No resources for this node and link. */
- {
- Store (RTAG (BUF0), Local3)
- }
-
- Return (Local3)
- }
-
- Method (RTAG, 1, NotSerialized)
- {
- Store (Arg0, Local0)
- Store (SizeOf (Local0), Local1)
- Subtract (Local1, 0x02, Local1)
- Multiply (Local1, 0x08, Local1)
- CreateField (Local0, 0x00, Local1, RETB)
- Store (RETB, Local2)
- Return (Local2)
- }
-}
diff --git a/src/northbridge/amd/amdk8/util.c b/src/northbridge/amd/amdk8/util.c
deleted file mode 100644
index aea046935c..0000000000
--- a/src/northbridge/amd/amdk8/util.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Vincent Legoll <vincent.legoll@gmail.com>
- * Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
- *
- * 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.
- */
-
-/*
- * K8 northbridge utilities (dump routing registers).
- * Designed to be called at any time.
- * It can be called before RAM is set up by including this file.
- * It can be called after RAM is set up by including amdk8.h and enabling the
- * compilation of this file in src/northbridge/amd/amdk8/Makefile.inc.
- */
-#ifndef __PRE_RAM__
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#endif
-#include "amdk8.h"
-
-/* Function 1 */
-/* the DRAM, MMIO,and PCIIO routing are 64-bit registers, hence the ending at
- * 0x78, 0xb8, and 0xd8
- */
-#define DRAM_ROUTE_START 0x40
-#define DRAM_ROUTE_END 0x78
-#define MMIO_ROUTE_START 0x80
-#define MMIO_ROUTE_END 0xb8
-#define PCIIO_ROUTE_START 0xc0
-#define PCIIO_ROUTE_END 0xd8
-#define CONFIG_ROUTE_START 0xe0
-#define CONFIG_ROUTE_END 0xec
-
-#define PCI_IO_BASE0 0xc0
-#define PCI_IO_BASE1 0xc8
-#define PCI_IO_BASE2 0xd0
-#define PCI_IO_BASE3 0xd8
-#define PCI_IO_BASE_VGA_EN (1 << 4)
-#define PCI_IO_BASE_NO_ISA (1 << 5)
-
-#define BITS(r, shift, mask) (((r>>shift)&mask))
-
-/**
- * Return "R" if the register has read-enable bit set.
- */
-static const char *re(u32 i)
-{
- return ((i & 1) ? "R" : "");
-}
-
-/**
- * Return "W" if the register has write-enable bit set.
- */
-static const char *we(u32 i)
-{
- return ((i & 1) ? "W" : "");
-}
-
-/**
- * Return a string containing the interleave settings.
- */
-static const char *ileave(u32 base)
-{
- switch ((base >> 8) & 7) {
- case 0:
- return "No interleave";
- case 1:
- return "2 nodes";
- case 3:
- return "4 nodes";
- case 7:
- return "8 nodes";
- default:
- return "Reserved";
- }
-}
-
-/**
- * Return the node number.
- * For one case (config registers) these are not the right bit fields.
- */
-static int r_node(u32 reg)
-{
- return BITS(reg, 0, 0x7);
-}
-
-/**
- * Return the link number.
- * For one case (config registers) these are not the right bit fields.
- */
-static int r_link(u32 reg)
-{
- return BITS(reg, 4, 0x3);
-}
-
-/**
- * Print the DRAM routing info for one base/limit pair.
- *
- * Show base, limit, dest node, dest link on that node, read and write
- * enable, and interleave information.
- *
- * @param level Printing level
- * @param which Register number
- * @param base Base register
- * @param lim Limit register
- */
-static void showdram(int level, u8 which, u32 base, u32 lim)
-{
- printk(level, "DRAM(%02x)%010llx-%010llx, ->(%d), %s, %s, %s, %d\n",
- which, (((u64) base & 0xffff0000) << 8),
- (((u64) lim & 0xffff0000) << 8) + 0xffffff,
- r_node(lim), re(base), we(base), ileave(base), (lim >> 8) & 3);
-}
-
-/**
- * Print the config routing info for a config register.
- *
- * Show base, limit, dest node, dest link on that node, read and write
- * enable, and device number compare enable
- *
- * @param level Printing level
- * @param which Register number
- * @param reg Config register
- */
-static void showconfig(int level, u8 which, u32 reg)
-{
- /* Don't use r_node() and r_link() here. */
- printk(level, "CONFIG(%02x)%02x-%02x ->(%d,%d),%s %s (%s numbers)\n",
- which, BITS(reg, 16, 0xff), BITS(reg, 24, 0xff),
- BITS(reg, 4, 0x7), BITS(reg, 8, 0x3),
- re(reg), we(reg),
- BITS(reg, 2, 0x1)?"dev":"bus");
-}
-
-/**
- * Print the PCIIO routing info for one base/limit pair.
- *
- * Show base, limit, dest node, dest link on that node, read and write
- * enable, and VGA and ISA Enable.
- *
- * @param level Printing level
- * @param which Register number
- * @param base Base register
- * @param lim Limit register
- */
-static void showpciio(int level, u8 which, u32 base, u32 lim)
-{
- printk(level, "PCIIO(%02x)%07x-%07x, ->(%d,%d), %s, %s,VGA %d ISA %d\n",
- which, BITS(base, 12, 0x3fff) << 12,
- (BITS(lim, 12, 0x3fff) << 12) + 0xfff, r_node(lim), r_link(lim),
- re(base), we(base), BITS(base, 4, 0x1), BITS(base, 5, 0x1));
-}
-
-/**
- * Print the MMIO routing info for one base/limit pair.
- *
- * Show base, limit, dest node, dest link on that node, read and write
- * enable, and CPU Disable, Lock, and Non-posted.
- *
- * @param level Printing level
- * @param which Register number
- * @param base Base register
- * @param lim Limit register
- */
-static void showmmio(int level, u8 which, u32 base, u32 lim)
-{
- printk(level, "MMIO(%02x)%010llx-%010llx, ->(%d,%d), %s, %s, "
- "CPU disable %d, Lock %d, Non posted %d\n",
- which, ((u64) BITS(base, 0, 0xffffff00)) << 8,
- (((u64) BITS(lim, 0, 0xffffff00)) << 8) + 0xffff, r_node(lim),
- r_link(lim), re(base), we(base), BITS(base, 4, 0x1),
- BITS(base, 7, 0x1), BITS(lim, 7, 0x1));
-}
-
-/**
- * Show all DRAM routing registers. This function is callable at any time.
- *
- * @param level The debug level.
- * @param dev A 32-bit number in the standard bus/dev/fn format which is used
- * raw config space.
- */
-static void showalldram(int level, struct device *dev)
-{
- u8 reg;
- for (reg = DRAM_ROUTE_START; reg <= DRAM_ROUTE_END; reg += 8) {
- u32 base = pci_read_config32(dev, reg);
- u32 lim = pci_read_config32(dev, reg + 4);
- if (base || lim!=(reg-DRAM_ROUTE_START)/8)
- showdram(level, reg, base, lim);
- }
-}
-
-/**
- * Show all MMIO routing registers. This function is callable at any time.
- *
- * @param level The debug level.
- * @param dev A 32-bit number in the standard bus/dev/fn format which is used
- * raw config space.
- */
-static void showallmmio(int level, struct device *dev)
-{
- u8 reg;
- for (reg = MMIO_ROUTE_START; reg <= MMIO_ROUTE_END; reg += 8) {
- u32 base = pci_read_config32(dev, reg);
- u32 lim = pci_read_config32(dev, reg + 4);
- if (base || lim)
- showmmio(level, reg, base, lim);
- }
-}
-
-/**
- * Show all PCIIO routing registers. This function is callable at any time.
- *
- * @param level The debug level.
- * @param dev A 32-bit number in the standard bus/dev/fn format which is used
- * raw config space.
- */
-static void showallpciio(int level, struct device *dev)
-{
- u8 reg;
- for (reg = PCIIO_ROUTE_START; reg <= PCIIO_ROUTE_END; reg += 8) {
- u32 base = pci_read_config32(dev, reg);
- u32 lim = pci_read_config32(dev, reg + 4);
- if (base || lim)
- showpciio(level, reg, base, lim);
- }
-}
-
-/**
- * Show all config routing registers. This function is callable at any time.
- *
- * @param level The debug level.
- * @param dev A 32-bit number in the standard bus/dev/fn format which is used
- * raw config space.
- */
-static void showallconfig(int level, struct device *dev)
-{
- u8 reg;
- for (reg = CONFIG_ROUTE_START; reg <= CONFIG_ROUTE_END; reg += 4) {
- u32 val = pci_read_config32(dev, reg);
- if (val)
- showconfig(level, reg, val);
- }
-}
-
-/**
- * Show all routing registers. This function is callable at any time.
- *
- * @param level The debug level.
- * @param dev A 32-bit number in the standard bus/dev/fn format which is used
- * raw config space.
- */
-void showallroutes(int level, struct device *dev)
-{
- showalldram(level, dev);
- showallmmio(level, dev);
- showallpciio(level, dev);
- showallconfig(level, dev);
-}