diff options
author | Martin Roth <gaumless@gmail.com> | 2017-10-15 14:16:37 -0600 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2018-01-15 23:22:59 +0000 |
commit | 99c45dee0ae62254be36a312d67764784450b564 (patch) | |
tree | 193b20bb742056464374373ba65b07bc901f07c7 /src/northbridge/amd | |
parent | b94b2c73068eba434cdd162fac1d50cf22524259 (diff) |
AMD GX2 boards & chips: Remove - using LATE_CBMEM_INIT
All boards and chips that are still using LATE_CBMEM_INIT are being
removed as previously discussed.
If these boards and chips are updated to not use LATE_CBMEM_INIT, they
can be restored to the active codebase from the 4.7 branch.
chips:
cpu/amd/geode_gx2
northbridge/amd/gx2
southbridge/amd/cs5535
Mainboards:
mainboard/amd/rumba
mainboard/lippert/frontrunner
mainboard/wyse/s50
Change-Id: I81c130f53bbfa001edbfdb7a878ef115757f620c
Signed-off-by: Martin Roth <gaumless@gmail.com>
Reviewed-on: https://review.coreboot.org/22025
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src/northbridge/amd')
-rw-r--r-- | src/northbridge/amd/gx2/Kconfig | 73 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/Makefile.inc | 7 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/grphinit.c | 85 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/northbridge.c | 347 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/northbridge.h | 16 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/northbridgeinit.c | 673 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/pll_reset.c | 195 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/raminit.c | 606 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/raminit.h | 12 |
9 files changed, 0 insertions, 2014 deletions
diff --git a/src/northbridge/amd/gx2/Kconfig b/src/northbridge/amd/gx2/Kconfig deleted file mode 100644 index fcba106bc6..0000000000 --- a/src/northbridge/amd/gx2/Kconfig +++ /dev/null @@ -1,73 +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_GX2 - bool - select GEODE_VSA - select LATE_CBMEM_INIT - -if NORTHBRIDGE_AMD_GX2 - -choice - prompt "Framebuffer size" - default GX2_VIDEO_MB_8MB - -config GX2_VIDEO_MB_4MB - bool "4MB" -config GX2_VIDEO_MB_8MB - bool "8MB" -config GX2_VIDEO_MB_16MB - bool "16MB" -config GX2_VIDEO_MB_32MB - bool "32MB" -config GX2_VIDEO_MB_64MB - bool "64MB" -config GX2_VIDEO_MB_128MB - bool "128MB" -config GX2_VIDEO_MB_256MB - bool "256MB" -config GX2_VIDEO_MB_CMOS - bool "Use CMOS option" - -endchoice - -config VIDEO_MB - int - default 4 if GX2_VIDEO_MB_4MB - default 8 if GX2_VIDEO_MB_8MB - default 16 if GX2_VIDEO_MB_16MB - default 32 if GX2_VIDEO_MB_32MB - default 64 if GX2_VIDEO_MB_64MB - default 128 if GX2_VIDEO_MB_128MB - default 256 if GX2_VIDEO_MB_256MB - default -1 if GX2_VIDEO_MB_CMOS - -# The GX2_PROCESSOR_MHZ options let you chose the correct GX2 processor -# speed in the mainboard's Kconfig file. -config GX2_PROCESSOR_MHZ_300 - bool -config GX2_PROCESSOR_MHZ_366 - bool -config GX2_PROCESSOR_MHZ_400 - bool - -# Map the config names to an integer (MHz). -config GX2_PROCESSOR_MHZ - int - default 300 if GX2_PROCESSOR_MHZ_300 - default 366 if GX2_PROCESSOR_MHZ_366 - default 400 if GX2_PROCESSOR_MHZ_400 - -endif # NORTHBRIDGE_AMD_GX2 diff --git a/src/northbridge/amd/gx2/Makefile.inc b/src/northbridge/amd/gx2/Makefile.inc deleted file mode 100644 index 7936acb137..0000000000 --- a/src/northbridge/amd/gx2/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -ifeq ($(CONFIG_NORTHBRIDGE_AMD_GX2),y) - -ramstage-y += northbridge.c -ramstage-y += northbridgeinit.c -ramstage-y += grphinit.c - -endif diff --git a/src/northbridge/amd/gx2/grphinit.c b/src/northbridge/amd/gx2/grphinit.c deleted file mode 100644 index 5f1c88e11a..0000000000 --- a/src/northbridge/amd/gx2/grphinit.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2012 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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 <stdint.h> -#include <cpu/amd/vr.h> -#include <console/console.h> -#include <cpu/amd/gx2def.h> -#include <cpu/x86/msr.h> -#include <stdlib.h> - -void geodegx2_vga_msr_init(void); -void graphics_init(void); - -struct msrinit { - u32 msrnum; - msr_t msr; -}; - -static const struct msrinit geodegx2_vga_msr[] = { - /* Enable the GLIU Memory routing to the memory A0000-BFFFF - * PDID1 : Port 4, GLIU0 - * PBASE : 0x000A0 - * PMASK : 0xFFFE0 - */ - {.msrnum = GLIU0_P2D_BM_4, {.lo = 0x0a0fffe0, .hi = 0x80000000}}, -}; - -void geodegx2_vga_msr_init(void) -{ - int i; - for (i = 0; i < ARRAY_SIZE(geodegx2_vga_msr); i++) - wrmsr(geodegx2_vga_msr[i].msrnum, geodegx2_vga_msr[i].msr); -} - - -/* This function mirrors the Graphics_Init routine in GeodeROM. */ -void graphics_init(void) -{ - uint16_t wClassIndex, wData, res; - - /* SoftVG initialization */ - printk(BIOS_DEBUG, "Graphics init...\n"); - - geodegx2_vga_msr_init(); - - /* Call SoftVG with the main configuration parameters. */ - /* NOTE: SoftVG expects the memory size to be given in 512 KB blocks */ - - wClassIndex = (VRC_VG << 8) + VG_CONFIG; - - /* - * Graphics Driver Enabled (13) 0, NO (lets BIOS controls the GP) - * External Monochrome Card Support(12) 0, NO - * Controller Priority Select(11) 1, Primary - * Display Select(10:8) 0x0, CRT - * Graphics Memory Size(7:1) CONFIG_VIDEO_MB >> 1, - * defined in devicetree.cb - * PLL Reference Clock Bypass(0) 0, Default - */ - - /* Video RAM has to be given in 512KB chunks - * the value is read @ 7:1 (value in 7:0 looks like /2) - * so we can add the real value in megabytes - */ - - wData = VG_CFG_PRIORITY | VG_CFG_DSCRT | ((CONFIG_VIDEO_MB * 2) & VG_MEM_MASK); - vrWrite(wClassIndex, wData); - - res = vrRead(wClassIndex); - printk(BIOS_DEBUG, "VRC_VG value: 0x%04x\n", res); -} diff --git a/src/northbridge/amd/gx2/northbridge.c b/src/northbridge/amd/gx2/northbridge.c deleted file mode 100644 index ef3b30a80d..0000000000 --- a/src/northbridge/amd/gx2/northbridge.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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 <stdlib.h> -#include <string.h> -#include "northbridge.h" -#include <cpu/x86/msr.h> -#include <cpu/x86/cache.h> -#include <cpu/amd/vr.h> -#include <cpu/cpu.h> -#include "../../../southbridge/amd/cs5536/cs5536.h" - -void print_conf(void); - -/* Print the platform configuration - do before PCI init or it will not - * work right. - */ -void print_conf(void) -{ -#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_ERR - int i; - unsigned long iol; - msr_t msr; - - int cpu_msr_defs[] = { CPU_IM_CONFIG, CPU_DM_CONFIG0, - CPU_RCONF_DEFAULT, CPU_RCONF_BYPASS, CPU_RCONF_A0_BF, - CPU_RCONF_C0_DF, CPU_RCONF_E0_FF, CPU_RCONF_SMM, CPU_RCONF_DMM, - GLCP_DELAY_CONTROLS, GL_END - }; - - int gliu0_msr_defs[] = { GLIU0_P2D_BM_0, GLIU0_P2D_BM_1, - GLIU0_P2D_BM_2, GLIU0_P2D_BM_3, GLIU0_P2D_BM_4, - GLIU0_P2D_BM_5, GLIU0_P2D_BMO_0, GLIU0_P2D_BMO_1, - GLIU0_P2D_R_0, GLIU0_P2D_RO_0, GLIU0_P2D_RO_1, - GLIU0_P2D_RO_2, GLIU0_P2D_SC_0, GLIU0_IOD_BM_0, GLIU0_IOD_BM_1, - GLIU0_IOD_BM_2, GLIU0_IOD_SC_0, GLIU0_IOD_SC_1, GLIU0_IOD_SC_2, - GLIU0_IOD_SC_3, GLIU0_IOD_SC_4, GLIU0_IOD_SC_5, - GLIU0_GLD_MSR_COH, GL_END - }; - - int gliu1_msr_defs[] = { GLIU1_P2D_BM_0, GLIU1_P2D_BM_1, - GLIU1_P2D_BM_2, GLIU1_P2D_BM_3, GLIU1_P2D_BM_4, - GLIU1_P2D_BM_5, GLIU1_P2D_BM_6, GLIU1_P2D_BM_7, - GLIU1_P2D_BM_8, GLIU1_P2D_R_0, GLIU1_P2D_R_1, - GLIU1_P2D_R_2, GLIU1_P2D_R_3, GLIU1_P2D_SC_0, - GLIU1_IOD_BM_0, GLIU1_IOD_BM_1, GLIU1_IOD_BM_2, GLIU1_IOD_SC_0, - GLIU1_IOD_SC_1, GLIU1_IOD_SC_2, GLIU1_IOD_SC_3, GLIU1_IOD_SC_4, - GLIU1_IOD_SC_5, GLIU1_GLD_MSR_COH, GL_END - }; - - int rconf_msr[] = { CPU_RCONF0, CPU_RCONF1, CPU_RCONF2, CPU_RCONF3, - CPU_RCONF4, CPU_RCONF5, CPU_RCONF6, CPU_RCONF7, GL_END - }; - - int lbar_msr[] = { MDD_LBAR_GPIO, MDD_LBAR_FLSH0, MDD_LBAR_FLSH1, GL_END - }; - - int irq_msr[] = { MDD_IRQM_YLOW, MDD_IRQM_YHIGH, MDD_IRQM_ZLOW, MDD_IRQM_ZHIGH, - MDD_IRQM_PRIM, GL_END - }; - - int pci_msr[] = { GLPCI_CTRL, GLPCI_ARB, GLPCI_REN, GLPCI_A0_BF, - GLPCI_C0_DF, GLPCI_E0_FF, GLPCI_RC0, GLPCI_RC1, GLPCI_RC2, - GLPCI_RC3, GLPCI_ExtMSR, GLPCI_SPARE, GL_END - }; - - int dma_msr[] = { MDD_DMA_MAP, MDD_DMA_SHAD1, MDD_DMA_SHAD2, - MDD_DMA_SHAD3, MDD_DMA_SHAD4, MDD_DMA_SHAD5, MDD_DMA_SHAD6, - MDD_DMA_SHAD7, MDD_DMA_SHAD8, MDD_DMA_SHAD9, GL_END - }; - - printk(BIOS_DEBUG, "---------- CPU ------------\n"); - - for (i = 0; cpu_msr_defs[i] != GL_END; i++) { - msr = rdmsr(cpu_msr_defs[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", - cpu_msr_defs[i], msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- GLIU 0 ------------\n"); - - for (i = 0; gliu0_msr_defs[i] != GL_END; i++) { - msr = rdmsr(gliu0_msr_defs[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", - gliu0_msr_defs[i], msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- GLIU 1 ------------\n"); - - for (i = 0; gliu1_msr_defs[i] != GL_END; i++) { - msr = rdmsr(gliu1_msr_defs[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", - gliu1_msr_defs[i], msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- RCONF ------------\n"); - - for (i = 0; rconf_msr[i] != GL_END; i++) { - msr = rdmsr(rconf_msr[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", rconf_msr[i], - msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- VARIA ------------\n"); - msr = rdmsr(ATA_SB_IDE_CFG); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", ATA_SB_IDE_CFG, msr.hi, - msr.lo); - - msr = rdmsr(MDD_LEG_IO); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", MDD_LEG_IO, msr.hi, - msr.lo); - - msr = rdmsr(MDD_PIN_OPT); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", MDD_PIN_OPT, msr.hi, - msr.lo); - - printk(BIOS_DEBUG, "---------- PCI ------------\n"); - - for (i = 0; pci_msr[i] != GL_END; i++) { - msr = rdmsr(pci_msr[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", pci_msr[i], - msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- LPC/UART DMA ------------\n"); - - for (i = 0; dma_msr[i] != GL_END; i++) { - msr = rdmsr(dma_msr[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", dma_msr[i], - msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- DIVIL IRQ ------------\n"); - - for (i = 0; irq_msr[i] != GL_END; i++) { - msr = rdmsr(irq_msr[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", irq_msr[i], - msr.hi, msr.lo); - } - - printk(BIOS_DEBUG, "---------- DIVIL LBAR -----------\n"); - - for (i = 0; lbar_msr[i] != GL_END; i++) { - msr = rdmsr(lbar_msr[i]); - printk(BIOS_DEBUG, "MSR 0x%08X is now 0x%08X:0x%08X\n", lbar_msr[i], - msr.hi, msr.lo); - } - - iol = inl(GPIO_IO_BASE + GPIOL_INPUT_ENABLE); - printk(BIOS_DEBUG, "IOR 0x%08X is now 0x%08lX\n", - GPIO_IO_BASE + GPIOL_INPUT_ENABLE, iol); - iol = inl(GPIOL_EVENTS_ENABLE); - printk(BIOS_DEBUG, "IOR 0x%08X is now 0x%08lX\n", - GPIO_IO_BASE + GPIOL_EVENTS_ENABLE, iol); - iol = inl(GPIOL_INPUT_INVERT_ENABLE); - printk(BIOS_DEBUG, "IOR 0x%08X is now 0x%08lX\n", - GPIO_IO_BASE + GPIOL_INPUT_INVERT_ENABLE, iol); - iol = inl(GPIO_MAPPER_X); - printk(BIOS_DEBUG, "IOR 0x%08X is now 0x%08lX\n", GPIO_IO_BASE + GPIO_MAPPER_X, - iol); -#endif /* CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_ERR */ -} - -/* todo: add a resource record. We don't do this here because this may be called when - * very little of the platform is actually working. - */ -int sizeram(void) -{ - msr_t msr; - int sizem = 0; - unsigned short dimm; - - /* Get the RAM size from the memory controller as calculated and set by auto_size_dimm() */ - msr = rdmsr(MC_CF07_DATA); - printk(BIOS_DEBUG, "sizeram: _MSR MC_CF07_DATA: %08x:%08x\n", msr.hi, msr.lo); - - /* dimm 0 */ - dimm = msr.hi; - /* installed? */ - if ((dimm & 7) != 7) - sizem = (1 << ((dimm >> 12)-1)) * 8; - - /* dimm 1 */ - dimm = msr.hi >> 16; - /* installed? */ - if ((dimm & 7) != 7) - sizem += (1 << ((dimm >> 12)-1)) * 8; - - printk(BIOS_DEBUG, "sizeram: sizem 0x%x\n", sizem); - return sizem; -} - -static void enable_shadow(device_t dev) -{ - -} - -static void northbridge_init(device_t dev) -{ - printk(BIOS_SPEW, ">> Entering northbridge: %s()\n", __func__); - - enable_shadow(dev); -} - -static void northbridge_set_resources(struct device *dev) -{ - uint8_t line; - - struct bus *bus; - - for (bus = dev->link_list; bus; bus = bus->next) { - if (bus->children) { - printk(BIOS_DEBUG, "my_dev_set_resources: assign_resources %d\n", - bus->secondary); - assign_resources(bus); - } - } - - /* set a default latency timer */ - pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40); - - /* set a default secondary latency timer */ - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) { - pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40); - } - - /* zero the irq settings */ - line = pci_read_config8(dev, PCI_INTERRUPT_PIN); - if (line) { - pci_write_config8(dev, PCI_INTERRUPT_LINE, 0); - } - /* set the cache line size, so far 64 bytes is good for everyone */ - pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2); -} - -static struct device_operations northbridge_operations = { - .read_resources = pci_dev_read_resources, - .set_resources = northbridge_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = northbridge_init, - .enable = 0, - .ops_pci = 0, -}; - -static const struct pci_driver northbridge_driver __pci_driver = { - .ops = &northbridge_operations, - .vendor = PCI_VENDOR_ID_NS, - .device = PCI_DEVICE_ID_NS_GX2, -}; - -#include <cbmem.h> - -static void pci_domain_set_resources(device_t dev) -{ - int idx; - u32 tomk; - device_t mc_dev; - - printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __func__); - - mc_dev = dev->link_list->children; - if (mc_dev) { - tomk = get_systop() / 1024; - /* Report the memory regions - All memory up to systop except 0xa0000-0xbffff */ - idx = 10; - ram_resource(dev, idx++, 0, 640); - ram_resource(dev, idx++, 768, tomk - 768); /* Systop - 0xc0000 -> KB */ - - set_late_cbmem_top(tomk * 1024); - } - - assign_resources(dev->link_list); -} - -static void pci_domain_enable(device_t dev) -{ - printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __func__); - - /* do this here for now -- this chip really breaks our device model */ - northbridge_init_early(); - cpubug(); - chipsetinit(); - print_conf(); - do_vsmbios(); - graphics_init(); -} - -static struct device_operations pci_domain_ops = { - .read_resources = pci_domain_read_resources, - .set_resources = pci_domain_set_resources, - .enable_resources = NULL, - .scan_bus = pci_domain_scan_bus, - .enable = pci_domain_enable, - .ops_pci_bus = pci_bus_default_ops, -}; - -static void cpu_bus_init(device_t dev) -{ - printk(BIOS_SPEW, ">> Entering northbridge.c: %s\n", __func__); - - 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 = 0, -}; - -static void enable_dev(struct device *dev) -{ - printk(BIOS_SPEW, ">> Entering northbridge.c: %s with path %d\n", - __func__, dev->path.type); - - /* 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_gx2_ops = { - CHIP_NAME("AMD GX (previously GX2) Northbridge") - .enable_dev = enable_dev, -}; diff --git a/src/northbridge/amd/gx2/northbridge.h b/src/northbridge/amd/gx2/northbridge.h deleted file mode 100644 index a4cd272a83..0000000000 --- a/src/northbridge/amd/gx2/northbridge.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NORTHBRIDGE_AMD_GX2_H -#define NORTHBRIDGE_AMD_GX2_H - -#include <cpu/amd/gx2def.h> - -/* northbridge.c */ -unsigned int gx2_scan_root_bus(device_t root, unsigned int max); -int sizeram(void); -void do_vsmbios(void); -void graphics_init(void); - -/* northbridgeinit.c */ -void northbridge_init_early(void); -uint32_t get_systop(void); - -#endif /* NORTHBRIDGE_AMD_GX2_H */ diff --git a/src/northbridge/amd/gx2/northbridgeinit.c b/src/northbridge/amd/gx2/northbridgeinit.c deleted file mode 100644 index 3b020165b3..0000000000 --- a/src/northbridge/amd/gx2/northbridgeinit.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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 <stdlib.h> -#include <string.h> -#include "northbridge.h" -#include <cpu/amd/gx2def.h> -#include <cpu/x86/msr.h> -#include <cpu/x86/cache.h> - -struct gliutable -{ - unsigned long desc_name; - unsigned short desc_type; - unsigned long hi, lo; -}; - -struct gliutable gliu0table[] = { - {.desc_name = GLIU0_P2D_BM_0, .desc_type= BM,.hi= MSR_MC + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ - {.desc_name = GLIU0_P2D_BM_1, .desc_type= BM,.hi= MSR_MC + 0x0,.lo=(0x80 << 20) + 0x0FFFE0}, /* 80000-9ffff to Mc */ - {.desc_name = GLIU0_P2D_SC_0, .desc_type= SC_SHADOW,.hi= MSR_MC + 0x0,.lo= 0x03}, /* C0000-Fffff split to MC and PCI (sub decode) A0000-Bffff handled by SoftVideo */ - {.desc_name = GLIU0_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_MC,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU0_P2D_BMO_0, .desc_type= BMO_SMM,.hi= MSR_MC,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU0_GLD_MSR_COH, .desc_type= OTHER,.hi= 0x0,.lo= GL0_CPU}, - {.desc_name = GL_END, .desc_type= GL_END,.hi= 0x0,.lo= 0x0}, -}; - -struct gliutable gliu1table[] = { - {.desc_name = GLIU1_P2D_BM_0, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ - {.desc_name = GLIU1_P2D_BM_1, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= (0x80 << 20) + 0x0FFFE0},/* 80000-9ffff to Mc */ - {.desc_name = GLIU1_P2D_SC_0, .desc_type= SC_SHADOW,.hi= MSR_GL0 + 0x0,.lo= 0x03}, /* C0000-Fffff split to MC and PCI (sub decode) */ - {.desc_name = GLIU1_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU1_P2D_BM_3, .desc_type= BM_SMM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU1_GLD_MSR_COH, .desc_type= OTHER,.hi= 0x0,.lo= GL1_GLIU0}, - {.desc_name = GLIU1_IOD_SC_0, .desc_type= SCIO,.hi= (GL1_GLCP << 29) + 0x0,.lo= 0x033000F0}, /* FooGlue FPU 0xF0 */ - {.desc_name = GL_END, .desc_type= GL_END,.hi= 0x0,.lo= 0x0}, -}; - -struct gliutable *gliutables[] = { gliu0table, gliu1table, 0 }; - -struct msrinit -{ - unsigned long msrnum; - msr_t msr; -}; - -struct msrinit ClockGatingDefault[] = { - {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - /* MC must stay off in SDR mode. It is turned on in CPUBug??? lotus #77.142 */ - {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, - {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - {VG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, /* lotus #77.163 */ - {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, - {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0155}}, - {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {FG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, /* Always on */ - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* All On */ -struct msrinit ClockGatingAllOn[] = { - {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {VG_GLD_MSR_PM, {.hi = 0x00, .lo = 0x00}}, - {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x000000001}}, - {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {FG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* Performance */ -struct msrinit ClockGatingPerformance[] = { - {VG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, /* lotus #77.163 */ - {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0001}}, - {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0155}}, - {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* SET GeodeLink PRIORITY */ -struct msrinit GeodeLinkPriorityTable[] = { - {CPU_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0220}}, /* CPU Priority. */ - {DF_GLD_MSR_MASTER_CONF, {.hi = 0x00,.lo = 0x0000}}, /* DF Priority. */ - {VG_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0720}}, /* VG Primary and Secondary Priority. */ - {GP_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0010}}, /* Graphics Priority. */ - {GLPCI_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0027}}, /* GLPCI Priority + PID */ - {GLCP_GLD_MSR_CONF, {.hi = 0x00,.lo = 0x0001}}, /* GLCP Priority + PID */ - {FG_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0622}}, /* FG PID */ - {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, /* END */ -}; - -static void writeglmsr(struct gliutable *gl) -{ - msr_t msr; - - msr.lo = gl->lo; - msr.hi = gl->hi; - wrmsr(gl->desc_name, msr); /* MSR - see table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void ShadowInit(struct gliutable *gl) -{ - msr_t msr; - - msr = rdmsr(gl->desc_name); - - if (msr.lo == 0) { - writeglmsr(gl); - } -} - -static void SysmemInit(struct gliutable *gl) -{ - msr_t msr; - int sizembytes, sizebytes; - - /* Figure out how much RAM is in the machine and alocate all to the - * system. We will adjust for SMM now and Frame Buffer later. - */ - sizembytes = sizeram(); - printk(BIOS_DEBUG, "%s: enable for %dMBytes\n", __func__, sizembytes); - sizebytes = sizembytes << 20; - - sizebytes -= ((SMM_SIZE * 1024) + 1); - - /* 20 bit address The bottom 12 bits go into bits 20-31 in msr.lo - The top 8 bits go into 0-7 of msr.hi. */ - sizebytes --; - msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24); - sizebytes <<= 8; /* move bits 23:12 in bits 31:20. */ - sizebytes &= 0xfff00000; - sizebytes |= 0x100; /* start at 1MB */ - msr.lo = sizebytes; - wrmsr(gl->desc_name, msr); /* MSR - see table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, - gl->desc_name, msr.hi, msr.lo); -} - -static void SMMGL0Init(struct gliutable *gl) -{ - msr_t msr; - int sizebytes = sizeram() << 20; - long offset; - - sizebytes -= (SMM_SIZE * 1024); - - printk(BIOS_DEBUG, "%s: %d bytes\n", __func__, sizebytes); - - offset = sizebytes - SMM_OFFSET; - offset = (offset >> 12) & 0x000fffff; - printk(BIOS_DEBUG, "%s: offset is 0x%08x\n", __func__, SMM_OFFSET); - - msr.hi = offset << 8 | gl->hi; - msr.hi |= SMM_OFFSET >> 24; - - msr.lo = (SMM_OFFSET & 0x00ffffff) << 8; - msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; - - wrmsr(gl->desc_name, msr); /* MSR - See table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void SMMGL1Init(struct gliutable *gl) -{ - msr_t msr; - printk(BIOS_DEBUG, "%s:\n", __func__); - - msr.hi = gl->hi; - /* I don't think this is needed */ - msr.hi &= 0xffffff00; - msr.hi |= (SMM_OFFSET >> 24); - msr.lo = (SMM_OFFSET & 0x00fff000) << 8; - msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; - - wrmsr(gl->desc_name, msr); /* MSR - See table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void GLIUInit(struct gliutable *gl) -{ - while (gl->desc_type != GL_END) { - switch (gl->desc_type) { - default: - writeglmsr(gl); - case SC_SHADOW: /* Check for a Shadow entry */ - ShadowInit(gl); - break; - - case R_SYSMEM: /* check for a SYSMEM entry */ - SysmemInit(gl); - break; - - case BMO_SMM: /* check for a SMM entry */ - SMMGL0Init(gl); - break; - - case BM_SMM: /* check for a SMM entry */ - SMMGL1Init(gl); - break; - } - gl++; - } -} - -/* Set up GLPCI settings for reads/write into memory. - * - * R0: 0-640KB, - * R1: 1MB - Top of System Memory - * R2: SMM Memory - * R3: Framebuffer? - not set up yet - * R4: ?? - */ -static void GLPCIInit(void) -{ - struct gliutable *gl = 0; - int i; - msr_t msr; - int msrnum; - - /* R0 - GLPCI settings for Conventional Memory space. */ - msr.hi = (0x09F000 >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; /* 640 */ - msr.lo = 0; /* 0 */ - msr.lo |= GLPCI_RC_LOWER_EN_SET + GLPCI_RC_LOWER_PF_SET + GLPCI_RC_LOWER_WC_SET; - msrnum = GLPCI_RC0; - wrmsr(msrnum, msr); - - /* R1 - GLPCI settings for SysMem space. */ - /* Get systop from GLIU0 SYSTOP Descriptor */ - for (i = 0; gliu0table[i].desc_name != GL_END; i++) { - if (gliu0table[i].desc_type == R_SYSMEM) { - gl = &gliu0table[i]; - break; - } - } - if (gl) { - unsigned long pah, pal; - msrnum = gl->desc_name; - msr = rdmsr(msrnum); - /* example R_SYSMEM value: 20:00:00:0f:fb:f0:01:00 - * translates to a base of 0x00100000 and top of 0xffbf0000 - * base of 1M and top of around 256M - */ - /* we have to create a page-aligned (4KB page) address for base and top - * so we need a high page aligned addresss (pah) and low page aligned address (pal) - * pah is from msr.hi << 12 | msr.low >> 20. pal is msr.lo << 12 - */ - pah = ((msr.hi & 0xff) << 12) | ((msr.lo >> 20) & 0xfff); - /* we have the page address. Now make it a page-aligned address */ - pah <<= 12; - - pal = msr.lo << 12; - msr.hi = pah; - msr.lo = pal; - msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | GLPCI_RC_LOWER_WC_SET; - printk(BIOS_DEBUG, "GLPCI R1: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); - msrnum = GLPCI_RC1; - wrmsr(msrnum, msr); - } - - /* R2 - GLPCI settings for SMM space. */ - msr.hi = ((SMM_OFFSET + (SMM_SIZE * 1024 - 1)) >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; - msr.lo = (SMM_OFFSET >> 12) << GLPCI_RC_LOWER_BASE_SHIFT; - msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET; - printk(BIOS_DEBUG, "GLPCI R2: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); - msrnum = GLPCI_RC2; - wrmsr(msrnum, msr); - - /* this is done elsewhere already, but it does no harm to do it more than once */ - /* write serialize memory hole to PCI. Need to unWS when something is shadowed regardless of cachablility. */ - msr.lo = 0x021212121; /* cache disabled and write serialized */ - msr.hi = 0x021212121; /* cache disabled and write serialized */ - - msrnum = CPU_RCONF_A0_BF; - wrmsr(msrnum, msr); - - msrnum = CPU_RCONF_C0_DF; - wrmsr(msrnum, msr); - - msrnum = CPU_RCONF_E0_FF; - wrmsr(msrnum, msr); - - /* Set Non-Cacheable Read Only for NorthBound Transactions to Memory. The Enable bit is handled in the Shadow setup. */ - msrnum = GLPCI_A0_BF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - msrnum = GLPCI_C0_DF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - msrnum = GLPCI_E0_FF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - /* Set WSREQ */ - msrnum = CPU_DM_CONFIG0; - msr = rdmsr(msrnum); - msr.hi &= ~(7 << DM_CONFIG0_UPPER_WSREQ_SHIFT); - msr.hi |= 2 << DM_CONFIG0_UPPER_WSREQ_SHIFT ; /* reduce to 1 for safe mode. */ - wrmsr(msrnum, msr); - - /* we are ignoring the 5530 case for now, and perhaps forever. */ - - /* 553X NB Init */ - - /* Arbiter setup */ - msrnum = GLPCI_ARB; - msr = rdmsr(msrnum); - msr.hi |= GLPCI_ARB_UPPER_PRE0_SET | GLPCI_ARB_UPPER_PRE1_SET; - msr.lo |= GLPCI_ARB_LOWER_IIE_SET; - wrmsr(msrnum, msr); - - msrnum = GLPCI_CTRL; - msr = rdmsr(msrnum); - - msr.lo |= GLPCI_CTRL_LOWER_ME_SET | GLPCI_CTRL_LOWER_OWC_SET | GLPCI_CTRL_LOWER_PCD_SET; /* (Out will be disabled in CPUBUG649 for < 2.0 parts .) */ - msr.lo |= GLPCI_CTRL_LOWER_LDE_SET; - - msr.lo &= ~(0x03 << GLPCI_CTRL_LOWER_IRFC_SHIFT); - msr.lo |= 0x02 << GLPCI_CTRL_LOWER_IRFC_SHIFT; - - msr.lo &= ~(0x07 << GLPCI_CTRL_LOWER_IRFT_SHIFT); - msr.lo |= 0x06 << GLPCI_CTRL_LOWER_IRFT_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_FTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_FTH_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_RTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_RTH_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_SBRTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_SBRTH_SHIFT; - - msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_WTO_SHIFT); - msr.hi |= 0x06 << GLPCI_CTRL_UPPER_WTO_SHIFT; - - msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_ILTO_SHIFT); - msr.hi |= 0x00 << GLPCI_CTRL_UPPER_ILTO_SHIFT; - wrmsr(msrnum, msr); - - /* Set GLPCI Latency Timer. */ - msrnum = GLPCI_CTRL; - msr = rdmsr(msrnum); - msr.hi |= 0x1F << GLPCI_CTRL_UPPER_LAT_SHIFT; /* Change once 1.x is gone. */ - wrmsr(msrnum, msr); - - /* GLPCI_SPARE */ - msrnum = GLPCI_SPARE; - msr = rdmsr(msrnum); - msr.lo &= ~0x7; - msr.lo |= GLPCI_SPARE_LOWER_AILTO_SET | GLPCI_SPARE_LOWER_PPD_SET | GLPCI_SPARE_LOWER_PPC_SET | GLPCI_SPARE_LOWER_MPC_SET | GLPCI_SPARE_LOWER_NSE_SET | GLPCI_SPARE_LOWER_SUPO_SET; - wrmsr(msrnum, msr); -} - -/* Enable Clock Gating. */ -static void ClockGatingInit(void) -{ - msr_t msr; - struct msrinit *gating = ClockGatingDefault; - int i; - - for (i = 0; gating->msrnum != 0xffffffff; i++) { - msr = rdmsr(gating->msrnum); - msr.hi |= gating->msr.hi; - msr.lo |= gating->msr.lo; - wrmsr(gating->msrnum, msr); /* MSR - See the table above */ - gating += 1; - } -} - -static void GeodeLinkPriority(void) -{ - msr_t msr = { 0, 0 }; - - struct msrinit *prio = GeodeLinkPriorityTable; - int i; - - for (i = 0; prio->msrnum != 0xffffffff; i++) { - msr = rdmsr(prio->msrnum); - msr.hi |= prio->msr.hi; - msr.lo &= ~0xfff; - msr.lo |= prio->msr.lo; - wrmsr(prio->msrnum, msr); /* MSR - See the table above */ - prio += 1; - } -} - -/* Get the GLIU0 shadow register settings. - * - * If the setShadow function is used then all shadow descriptors - * will stay sync'ed. - */ -static uint64_t getShadow(void) -{ - msr_t msr = { 0, 0 }; - - msr = rdmsr(GLIU0_P2D_SC_0); - return (((uint64_t) msr.hi) << 32) | msr.lo; -} - -/* Set the cache RConf registers for the memory hole. - * - * Keeps all cache shadow descriptors sync'ed. - * This is part of the PCI lockup solution. - * - * Entry: EDX:EAX is the shadow settings. - */ -static void setShadowRCONF(uint32_t shadowHi, uint32_t shadowLo) -{ - /* ok this is whacky bit translation time. */ - int bit; - uint8_t shadowByte; - msr_t msr = { 0, 0 }; - shadowByte = (uint8_t) (shadowLo >> 16); - - /* load up D000 settings in edx. */ - for (bit = 8; (bit > 4); bit--) { - msr.hi <<= 8; - msr.hi |= 1; /* cache disable PCI/Shadow memory */ - if (shadowByte && (1 << bit)) - msr.hi |= 0x20; /* write serialize PCI memory */ - } - - /* load up C000 settings in eax. */ - for (; bit; bit--) { - msr.lo <<= 8; - msr.lo |= 1; /* cache disable PCI/Shadow memory */ - if (shadowByte && (1 << bit)) - msr.lo |= 0x20; /* write serialize PCI memory */ - } - - wrmsr(CPU_RCONF_C0_DF, msr); - - shadowByte = (uint8_t) (shadowLo >> 24); - - /* load up F000 settings in edx. */ - for (bit = 8; (bit > 4); bit--) { - msr.hi <<= 8; - msr.hi |= 1; /* cache disable PCI/Shadow memory */ - if (shadowByte && (1 << bit)) - msr.hi |= 0x20; /* write serialize PCI memory */ - } - - /* load up E000 settings in eax. */ - for (; bit; bit--) { - msr.lo <<= 8; - msr.lo |= 1; /* cache disable PCI/Shadow memory */ - if (shadowByte && (1 << bit)) - msr.lo |= 0x20; /* write serialize PCI memory */ - } - - wrmsr(CPU_RCONF_E0_FF, msr); -} - -/* Set the GLPCI registers for the memory hole. - * Keeps all cache shadow descriptors sync'ed. - * Entry: EDX:EAX is the shadow settings - */ -static void setShadowGLPCI(uint32_t shadowHi, uint32_t shadowLo) -{ - msr_t msr; - - /* Set the Enable Register. */ - msr = rdmsr(GLPCI_REN); - msr.lo &= 0xFFFF00FF; - msr.lo |= ((shadowLo & 0xFFFF0000) >> 8); - wrmsr(GLPCI_REN, msr); -} - -/* Set the GLIU SC register settings. Scans descriptor tables for SC_SHADOW. - * Keeps all shadow descriptors sync'ed. - * Entry: EDX:EAX is the shadow settings - */ -static void setShadow(uint64_t shadowSettings) -{ - int i; - msr_t msr; - struct gliutable *pTable; - uint32_t shadowLo, shadowHi; - - shadowLo = (uint32_t) shadowSettings; - shadowHi = (uint32_t) (shadowSettings >> 32); - - setShadowRCONF(shadowHi, shadowLo); - setShadowGLPCI(shadowHi, shadowLo); - - for (i = 0; gliutables[i]; i++) { - for (pTable = gliutables[i]; pTable->desc_type != GL_END; pTable++) { - if (pTable->desc_type == SC_SHADOW) { - - msr = rdmsr(pTable->desc_name); - msr.lo = (uint32_t) shadowSettings; - msr.hi &= 0xFFFF0000; /* maintain PDID in upper EDX */ - msr.hi |= ((uint32_t) (shadowSettings >> 32)) & 0x0000FFFF; - wrmsr(pTable->desc_name, msr); /* MSR - See the table above */ - - } - } - } -} - -static void rom_shadow_settings(void) -{ - uint64_t shadowSettings = getShadow(); - shadowSettings &= (uint64_t) 0xFFFF00000000FFFFULL; /* Disable read & writes */ - shadowSettings |= (uint64_t) 0x0000FFFFFFFF0000ULL; /* Enable reads for C0000-FFFFF */ - setShadow(shadowSettings); -} - -/* Set up RCONF_DEFAULT and any other RCONF registers needed. - * - * DEVRC_RCONF_DEFAULT: - * ROMRC(63:56) = 04h ; write protect ROMBASE - * ROMBASE(36:55) = 0FFFC0h ; Top of PCI/bottom of ROM chipselect area - * DEVRC(35:28) = 39h ; cache disabled in PCI memory + WS bit on + Write Combine + write burst. - * SYSTOP(27:8) = top of system memory - * SYSRC(7:0) = 00h ; writeback, can set to 08h to make writethrough - */ -#define SYSMEM_RCONF_WRITETHROUGH 8 -#define DEVRC_RCONF_DEFAULT 0x21ul -#define ROMBASE_RCONF_DEFAULT 0xFFFC0000 -#define ROMRC_RCONF_DEFAULT 0x25 - -static void enable_L_cache(void) -{ - struct gliutable *gl = 0; - int i; - msr_t msr; - uint8_t SysMemCacheProp; - - /* Locate SYSMEM entry in GLIU0table */ - for (i = 0; gliu0table[i].desc_name != GL_END; i++) { - if (gliu0table[i].desc_type == R_SYSMEM) { - gl = &gliu0table[i]; - break; - } - } - if (gl == 0) { - post_code(0xCE); /* POST_RCONFInitError */ - while (1); - } - -/* sysdescfound: */ - msr = rdmsr(gl->desc_name); - - /* 20 bit address - The bottom 12 bits go into bits 20-31 in eax, the - * top 8 bits go into 0-7 of edx. - */ - msr.lo = (msr.lo & 0xFFFFFF00) | (msr.hi & 0xFF); - msr.lo = ((msr.lo << 12) | (msr.lo >> 20)) & 0x000FFFFF; - msr.lo <<= RCONF_DEFAULT_LOWER_SYSTOP_SHIFT; /* 8 */ - - /* Set Default SYSMEM region properties */ - msr.lo &= ~SYSMEM_RCONF_WRITETHROUGH; /* NOT writethrough == writeback 8 (or ~8) */ - - /* Set PCI space cache properties */ - msr.hi = (DEVRC_RCONF_DEFAULT >> 4); /* setting is split betwwen hi and lo... */ - msr.lo |= (DEVRC_RCONF_DEFAULT << 28); - - /* Set the ROMBASE. This is usually FFFC0000h */ - msr.hi |= (ROMBASE_RCONF_DEFAULT >> 12) << RCONF_DEFAULT_UPPER_ROMBASE_SHIFT; - - /* Set ROMBASE cache properties. */ - msr.hi |= ((ROMRC_RCONF_DEFAULT >> 8) | (ROMRC_RCONF_DEFAULT << 24)); - - /* now program RCONF_DEFAULT */ - wrmsr(CPU_RCONF_DEFAULT, msr); - printk(BIOS_DEBUG, "CPU_RCONF_DEFAULT (1808): 0x%08X:0x%08X\n", msr.hi, msr.lo); - - /* RCONF_BYPASS: Cache tablewalk properties and SMM header access properties. */ - /* Set to match system memory cache properties. */ - msr = rdmsr(CPU_RCONF_DEFAULT); - SysMemCacheProp = (uint8_t) (msr.lo & 0xFF); - msr = rdmsr(CPU_RCONF_BYPASS); - msr.lo = (msr.lo & 0xFFFF0000) | (SysMemCacheProp << 8) | SysMemCacheProp; - wrmsr(CPU_RCONF_BYPASS, msr); - printk(BIOS_DEBUG, "CPU_RCONF_BYPASS (180A): 0x%08x : 0x%08x\n", msr.hi, msr.lo); -} - -static void setup_gx2_cache(void) -{ - msr_t msr; - - enable_L_cache(); - - /* Make sure all INVD instructions are treated as WBINVD. We do this - * because we've found some programs which require this behavior. - */ - msr = rdmsr(CPU_DM_CONFIG0); - msr.lo |= DM_CONFIG0_LOWER_WBINVD_SET; - wrmsr(CPU_DM_CONFIG0, msr); - - x86_enable_cache(); - wbinvd(); -} - -uint32_t get_systop(void) -{ - struct gliutable *gl = 0; - uint32_t systop; - msr_t msr; - int i; - - for (i = 0; gliu0table[i].desc_name != GL_END; i++) { - if (gliu0table[i].desc_type == R_SYSMEM) { - gl = &gliu0table[i]; - break; - } - } - if (gl) { - msr = rdmsr(gl->desc_name); - systop = ((msr.hi & 0xFF) << 24) | ((msr.lo & 0xFFF00000) >> 8); - systop += 0x1000; /* 4K */ - } else { - systop = - ((sizeram() - CONFIG_VIDEO_MB) * 1024) - SMM_SIZE - 1024; - } - return systop; -} - -/* Core Logic initialization: Host bridge. */ -void northbridge_init_early(void) -{ - int i; - printk(BIOS_DEBUG, "Enter %s\n", __func__); - - for (i = 0; gliutables[i]; i++) - GLIUInit(gliutables[i]); - - /* Now that the descriptor to memory is set up. */ - /* The memory controller needs one read to synch its lines before it can be used. */ - read32(zeroptr); - - GeodeLinkPriority(); - - setup_gx2_cache(); - - rom_shadow_settings(); - - GLPCIInit(); - - ClockGatingInit(); - - __asm__ __volatile__("FINIT\n"); - printk(BIOS_DEBUG, "Exit %s\n", __func__); -} diff --git a/src/northbridge/amd/gx2/pll_reset.c b/src/northbridge/amd/gx2/pll_reset.c deleted file mode 100644 index 0bae76dda0..0000000000 --- a/src/northbridge/amd/gx2/pll_reset.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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/tsc.h> - -#define CLOCK_TICK_RATE 1193180U /* Underlying HZ */ -#define CALIBRATE_INTERVAL ((20*CLOCK_TICK_RATE)/1000) /* 20ms */ -#define CALIBRATE_DIVISOR (20*1000) /* 20ms / 20000 == 1usec */ - -/* spll_raw_clk = SYSREF * FbDIV, - * GLIU Clock = spll_raw_clk / MDIV - * CPU Clock = spll_raw_clk / VDIV - */ - -/* table for Feedback divisor to FbDiv register value */ -static const unsigned char plldiv2fbdiv[] = { - 0, 0, 0, 0, 0, 0, 15, 7, 3, 1, 0, 32, 16, 40, 20, 42, /* pll div 0 - 15 */ - 21, 10, 37, 50, 25, 12, 38, 19, 9, 4, 34, 17, 8, 36, 18, 41, /* pll div 16 - 31 */ - 52, 26, 45, 54, 27, 13, 6, 35, 49, 56, 28, 46, 23, 11, 05, 02, /* pll div 32 - 47 */ - 33, 48, 24, 44, 22, 43, 53, 58, 29, 14, 39, 51, 57, 60, 30, 47, /* pll div 48 - 63 */ -}; - -/* table for FbDiv register value to Feedback divisor */ -static const unsigned char fbdiv2plldiv[] = { - 10, 9, 47, 8, 25, 46, 38, 7, 28, 24, 17, 45, 21, 37, 57, 6, - 12, 27, 30, 23, 14, 16, 52, 44, 50, 20, 33, 36, 42, 56, 0, 0, - 11, 48, 26, 39, 29, 18, 22, 58, 13, 31, 15, 53, 51, 34, 43, 0, - 49, 40, 19, 59, 32, 54, 35, 0, 41, 60, 55, 0, 61, 0, 0, 0 -}; - -/* FbDIV VDIV MDIV CPU/GeodeLink */ -/* 12 2 3 200/133 */ -/* 16 2 3 266/177 */ -/* 18 2 3 300/200 */ -/* 20 2 3 333/222 */ -/* 22 2 3 366/244 */ -/* 24 2 3 400/266 */ -/* 26 2 3 433/289 */ - -/* PLLCHECK_COMPLETED is the "we've already done this" flag */ -#define PLLCHECK_COMPLETED (1 << RSTPLL_LOWER_SWFLAGS_SHIFT) - -#ifndef RSTPPL_LOWER_BYPASS_SET -#define RSTPPL_LOWER_BYPASS_SET (1 << GLCP_SYS_RSTPLL_BYPASS) -#endif // RSTPPL_LOWER_BYPASS_SET - -#define DEFAULT_MDIV 3 -#define DEFAULT_VDIV 2 - -static void pll_reset(void) -{ - msr_t msrGlcpSysRstpll; - unsigned MDIV_VDIV_FBDIV; - unsigned SyncBits; /* store the sync bits in up ebx */ - unsigned DEFAULT_FBDIV; - - if (CONFIG_GX2_PROCESSOR_MHZ == 400) { - DEFAULT_FBDIV = 24; - } else if (CONFIG_GX2_PROCESSOR_MHZ == 366) { - DEFAULT_FBDIV = 22; - } else if (CONFIG_GX2_PROCESSOR_MHZ == 300) { - DEFAULT_FBDIV = 18; - } else { - post_code(POST_PLL_CPU_VER_FAIL); - die("Unsupported GX2_PROCESSOR_MHZ setting!\n"); - } - - /* clear the Bypass bit */ - - /* If the straps say we are in bypass and the syspll is not AND there are no software */ - /* bits set then FS2 or something set up the PLL and we should not change it. */ - - msrGlcpSysRstpll = rdmsr(GLCP_SYS_RSTPLL); - msrGlcpSysRstpll.lo &= ~RSTPPL_LOWER_BYPASS_SET; - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - /* If the "we've already been here" flag is set, don't reconfigure the pll */ - if (!(msrGlcpSysRstpll.lo & PLLCHECK_COMPLETED)) - { /* we haven't configured the PLL; do it now */ - - /* Store PCI33(0)/66(1), SDR(0)/DDR(1), and CRT(0)/TFT(1) in upper esi to get to the */ - /* correct Strap Table. */ - post_code(POST_PLL_INIT); - - /* configure for DDR */ - msrGlcpSysRstpll.lo &= ~(1 << RSTPPL_LOWER_SDRMODE_SHIFT); - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - /* Use Manual settings */ - /* UseManual: */ - post_code(POST_PLL_MANUAL); - - /* DIV settings manually entered. */ - /* ax = VDIV, upper eax = MDIV, upper ecx = FbDIV */ - /* use gs and fs since we don't need them. */ - - /* ProgramClocks: */ - /* ax = VDIV, upper eax = MDIV, upper ecx = FbDIV */ - /* move everything into ebx */ - /* VDIV */ - MDIV_VDIV_FBDIV = ((DEFAULT_VDIV - 2) << RSTPLL_UPPER_VDIV_SHIFT); - - /* MDIV */ - MDIV_VDIV_FBDIV |= ((DEFAULT_MDIV - 2) << RSTPLL_UPPER_MDIV_SHIFT); - - /* FbDIV */ - MDIV_VDIV_FBDIV |= (plldiv2fbdiv[DEFAULT_FBDIV] << RSTPLL_UPPER_FBDIV_SHIFT); - - /* write GLCP_SYS_RSTPPL (GLCP reg 0x14) with clock values */ - msrGlcpSysRstpll.lo &= ~(1 << RSTPPL_LOWER_SDRMODE_SHIFT); - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - msrGlcpSysRstpll.hi = MDIV_VDIV_FBDIV; - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - /* Set Reset, LockWait, and SW flag */ - /* DoReset: */ - - /* CheckSemiSync proc */ - /* Check for Semi-Sync in GeodeLink and CPU. */ - /* We need to do this here since the strap settings don't account for these bits. */ - SyncBits = 0; /* store the sync bits in up ebx */ - - /* Check for Bypass mode. */ - if (msrGlcpSysRstpll.lo & RSTPPL_LOWER_BYPASS_SET) - { - /* If we are in BYPASS PCI may or may not be sync'd but CPU and GeodeLink will. */ - SyncBits |= RSTPPL_LOWER_CPU_SEMI_SYNC_SET; - } - else - { - /* CheckPCIsync: */ - /* If FBdiv/Mdiv is evenly divisible then set the PCI semi-sync. FB is always greater */ - /* look up the real divider... if we get a 0 we have serious problems */ - if (!(fbdiv2plldiv[((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_FBDIV_SHIFT) & 0x3f)] % - (((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_MDIV_SHIFT) & 0x0F) + 2))) - { - SyncBits |= RSTPPL_LOWER_PCI_SEMI_SYNC_SET; - } - - /* CheckCPUSync: */ - /* If Vdiv/Mdiv is evenly divisible then set the CPU semi-sync. */ - /* CPU is always greater or equal. */ - if (!((((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_MDIV_SHIFT) & 0x07) + 2) % - (((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_VDIV_SHIFT) & 0x0F) + 2))) - { - SyncBits |= RSTPPL_LOWER_CPU_SEMI_SYNC_SET; - } - } - - /* SetSync: */ - msrGlcpSysRstpll.lo &= ~(RSTPPL_LOWER_PCI_SEMI_SYNC_SET | RSTPPL_LOWER_CPU_SEMI_SYNC_SET); - msrGlcpSysRstpll.lo |= SyncBits; - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - /* CheckSemiSync endp */ - - /* now we do the reset */ - /* Set hold count to 99 (063h) */ - msrGlcpSysRstpll.lo &= ~(0x0FF << RSTPPL_LOWER_HOLD_COUNT_SHIFT); - msrGlcpSysRstpll.lo |= (0x0DE << RSTPPL_LOWER_HOLD_COUNT_SHIFT); - msrGlcpSysRstpll.lo |= PLLCHECK_COMPLETED; // Say we are done - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - /* Don't want to use LOCKWAIT */ - msrGlcpSysRstpll.lo |= (RSTPPL_LOWER_PLL_RESET_SET + RSTPPL_LOWER_PD_SET); - msrGlcpSysRstpll.lo |= RSTPPL_LOWER_CHIP_RESET_SET; - wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); - - /* You should never get here..... The chip has reset. */ - post_code(POST_PLL_RESET_FAIL); - die("CONFIGURING PLL FAILURE\n"); - - } /* we haven't configured the PLL; do it now */ - -} - -static unsigned int GeodeLinkSpeed(void) -{ - unsigned geodelinkspeed; - geodelinkspeed = ((CONFIG_GX2_PROCESSOR_MHZ * DEFAULT_VDIV) / DEFAULT_MDIV); - return (geodelinkspeed); -} diff --git a/src/northbridge/amd/gx2/raminit.c b/src/northbridge/amd/gx2/raminit.c deleted file mode 100644 index 6e66d7dcf5..0000000000 --- a/src/northbridge/amd/gx2/raminit.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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/amd/gx2def.h> -#include <spd.h> -#include <stddef.h> - -static const unsigned char NumColAddr[] = { - 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -}; - -static void __attribute__((noreturn)) hcf(void) -{ - printk(BIOS_EMERG, "DIE\n"); - /* this guarantees we flush the UART fifos (if any) and also - * ensures that things, in general, keep going so no debug output - * is lost - */ - while (1) - printk(BIOS_EMERG, (0)); -} - -static void auto_size_dimm(unsigned int dimm) -{ - uint32_t dimm_setting; - uint16_t dimm_size; - uint8_t spd_byte; - msr_t msr; - - dimm_setting = 0; - - printk(BIOS_DEBUG, "Check present\n"); - /* Check that we have a dimm */ - if (spd_read_byte(dimm, SPD_MEMORY_TYPE) == 0xFF) { - return; - } - - printk(BIOS_DEBUG, "MODBANKS\n"); - /* Field: Module Banks per DIMM */ - /* EEPROM byte usage: (5) Number of DIMM Banks */ - spd_byte = spd_read_byte(dimm, SPD_NUM_DIMM_BANKS); - if ((MIN_MOD_BANKS > spd_byte) || (spd_byte > MAX_MOD_BANKS)) { - printk(BIOS_EMERG, "Number of module banks not compatible\n"); - post_code(ERROR_BANK_SET); - hcf(); - } - dimm_setting |= (spd_byte >> 1) << CF07_UPPER_D0_MB_SHIFT; - - printk(BIOS_DEBUG, "FIELDBANKS\n"); - /* Field: Banks per SDRAM device */ - /* EEPROM byte usage: (17) Number of Banks on SDRAM Device */ - spd_byte = spd_read_byte(dimm, SPD_NUM_BANKS_PER_SDRAM); - if ((MIN_DEV_BANKS > spd_byte) || (spd_byte > MAX_DEV_BANKS)) { - printk(BIOS_EMERG, "Number of device banks not compatible\n"); - post_code(ERROR_BANK_SET); - hcf(); - } - dimm_setting |= (spd_byte >> 2) << CF07_UPPER_D0_CB_SHIFT; - - printk(BIOS_DEBUG, "SPDNUMROWS\n"); - /* Field: DIMM size - * EEPROM byte usage: - * (3) Number of Row Addresses - * (4) Number of Column Addresses - * (5) Number of DIMM Banks - * (31) Module Bank Density - * Size = Module Density * Module Banks - */ - if ((spd_read_byte(dimm, SPD_NUM_ROWS) & 0xF0) - || (spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF0)) { - printk(BIOS_EMERG, "Asymmetric DIMM not compatible\n"); - post_code(ERROR_UNSUPPORTED_DIMM); - hcf(); - } - - printk(BIOS_DEBUG, "SPDBANKDENSITY\n"); - dimm_size = spd_read_byte(dimm, SPD_BANK_DENSITY); - printk(BIOS_DEBUG, "DIMMSIZE\n"); - dimm_size |= (dimm_size << 8); /* align so 1GB(bit0) is bit 8, this is a little weird to get gcc to not optimize this out */ - dimm_size &= 0x01FC; /* and off 2GB DIMM size : not supported and the 1GB size we just moved up to bit 8 as well as all the extra on top */ - - /* Module Density * Module Banks */ - dimm_size <<= (dimm_setting >> CF07_UPPER_D0_MB_SHIFT) & 1; /* shift to multiply by # DIMM banks */ - printk(BIOS_DEBUG, "BEFORT CTZ\n"); - dimm_size = __builtin_ctz(dimm_size); - printk(BIOS_DEBUG, "TEST DIMM SIZE > 7\n"); - if (dimm_size > 7) { /* 7 is 512MB only support 512MB per DIMM */ - printk(BIOS_EMERG, "Only support up to 512MB per DIMM\n"); - post_code(ERROR_DENSITY_DIMM); - hcf(); - } - dimm_setting |= dimm_size << CF07_UPPER_D0_SZ_SHIFT; - printk(BIOS_DEBUG, "PAGESIZE\n"); - -/* - * Field: PAGE size - * EEPROM byte usage: (4) Number of Column Addresses - * PageSize = 2^# Column Addresses * Data width in bytes - * (should be 8bytes for a normal DIMM) - * - * But this really works by magic. - * If ma[11:0] is the memory address pins, and pa[13:0] is the physical column - * address that MC generates, here is how the MC assigns the pa onto the - * ma pins: - * - * ma 11 10 09 08 07 06 05 04 03 02 01 00 - * --------------------------------------- - * pa 09 08 07 06 05 04 03 (7 col addr bits = 1K page size) - * pa 10 09 08 07 06 05 04 03 (8 col addr bits = 2K page size) - * pa 11 10 09 08 07 06 05 04 03 (9 col addr bits = 4K page size) - * pa 12 11 10 09 08 07 06 05 04 03 (10 col addr bits = 8K page size) - * pa 13 AP 12 11 10 09 08 07 06 05 04 03 (11 col addr bits = 16K page size) - * - * (AP = autoprecharge bit) - * - * Remember that pa[2:0] are zeroed out since it's a 64-bit data bus (8 bytes), - * so lower 3 address bits are dont_cares. So from the table above, - * it's easier to see what the old code is doing: if for example, - * #col_addr_bits = 7(06h), it adds 3 to get 10, then does 2^10 = 1K. - */ - - spd_byte = NumColAddr[spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF]; - printk(BIOS_DEBUG, "MAXCOLADDR\n"); - if (spd_byte > MAX_COL_ADDR) { - printk(BIOS_EMERG, "DIMM page size not compatible\n"); - post_code(ERROR_SET_PAGE); - hcf(); - } - printk(BIOS_DEBUG, ">11address test\n"); - spd_byte -= 7; - if (spd_byte > 4) { /* if the value is above 4 it means > 11 col address lines */ - spd_byte = 7; /* which means > 16k so set to disabled */ - } - dimm_setting |= spd_byte << CF07_UPPER_D0_PSZ_SHIFT; /* 0 = 1k, 1 = 2k, 2 = 4k, etc */ - - printk(BIOS_DEBUG, "RDMSR CF07\n"); - msr = rdmsr(MC_CF07_DATA); - printk(BIOS_DEBUG, "WRMSR CF07\n"); - if (dimm == DIMM0) { - msr.hi &= 0xFFFF0000; - msr.hi |= dimm_setting; - } else { - msr.hi &= 0x0000FFFF; - msr.hi |= dimm_setting << 16; - } - wrmsr(MC_CF07_DATA, msr); - printk(BIOS_DEBUG, "ALL DONE\n"); -} - -static void checkDDRMax(void) -{ - uint8_t spd_byte0, spd_byte1; - uint16_t speed; - - /* PC133 identifier */ - spd_byte0 = spd_read_byte(DIMM0, SPD_MIN_CYCLE_TIME_AT_CAS_MAX); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_MIN_CYCLE_TIME_AT_CAS_MAX); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - - /* Use the slowest DIMM */ - if (spd_byte0 < spd_byte1) { - spd_byte0 = spd_byte1; - } - - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ - speed = 20000 / (((spd_byte0 >> 4) * 10) + (spd_byte0 & 0x0F)); - - /* current speed > max speed? */ - if (GeodeLinkSpeed() > speed) { - printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink Speed\n"); - post_code(POST_PLL_MEM_FAIL); - hcf(); - } -} - -const uint16_t REF_RATE[] = { 15, 3, 7, 31, 62, 125 }; /* ns */ - -static void set_refresh_rate(void) -{ - uint8_t spd_byte0, spd_byte1; - uint16_t rate0, rate1; - msr_t msr; - - spd_byte0 = spd_read_byte(DIMM0, SPD_REFRESH); - spd_byte0 &= 0xF; - if (spd_byte0 > 5) { - spd_byte0 = 5; - } - rate0 = REF_RATE[spd_byte0]; - - spd_byte1 = spd_read_byte(DIMM1, SPD_REFRESH); - spd_byte1 &= 0xF; - if (spd_byte1 > 5) { - spd_byte1 = 5; - } - rate1 = REF_RATE[spd_byte1]; - - /* Use the faster rate (lowest number) */ - if (rate0 > rate1) { - rate0 = rate1; - } - - msr = rdmsr(MC_CF07_DATA); - msr.lo |= ((rate0 * (GeodeLinkSpeed() / 2)) / 16) - << CF07_LOWER_REF_INT_SHIFT; - wrmsr(MC_CF07_DATA, msr); -} - -const uint8_t CASDDR[] = { 5, 5, 2, 6, 0 }; /* 1(1.5), 1.5, 2, 2.5, 0 */ - -static u8 getcasmap(u32 dimm, u16 glspeed) -{ - u16 dimm_speed; - u8 spd_byte, casmap, casmap_shift = 0; - - /************************** DIMM0 **********************************/ - casmap = spd_read_byte(dimm, SPD_ACCEPTABLE_CAS_LATENCIES); - if (casmap != 0xFF) { - /* IF -.5 timing is supported, check -.5 timing > GeodeLink */ - spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_2ND); - if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ - dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F)); - if (dimm_speed >= glspeed) { - casmap_shift = 1; /* -.5 is a shift of 1 */ - /* IF -1 timing is supported, check -1 timing > GeodeLink */ - spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_3RD); - if (spd_byte != 0) { - /* Turn SPD ns time into MHZ. Check what the asm does to this math. */ - dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F)); - if (dimm_speed >= glspeed) { - casmap_shift = 2; /* -1 is a shift of 2 */ - } - } /* SPD_SDRAM_CYCLE_TIME_3RD (-1) !=0 */ - } else { - casmap_shift = 0; - } - } /* SPD_SDRAM_CYCLE_TIME_2ND (-.5) !=0 */ - /* set the casmap based on the shift to limit possible CAS settings */ - spd_byte = 31 - __builtin_clz((uint32_t) casmap); - /* just want bits in the lower byte since we have to cast to a 32 */ - casmap &= 0xFF << (spd_byte - casmap_shift); - } else { /* No DIMM */ - casmap = 0; - } - return casmap; -} - -static void setCAS(void) -{ -/* - * setCAS - * EEPROM byte usage: (18) SDRAM device attributes - CAS latency - * EEPROM byte usage: (23) SDRAM Minimum Clock Cycle Time @ CLX -.5 - * EEPROM byte usage: (25) SDRAM Minimum Clock Cycle Time @ CLX -1 - * - * The CAS setting is based on the information provided in each DIMMs SPD. - * The speed at which a DIMM can run is described relative to the slowest - * CAS the DIMM supports. Each speed for the relative CAS settings is - * checked that it is within the GeodeLink speed. If it isn't within the GeodeLink - * speed, the CAS setting is removed from the list of good settings for - * the DIMM. This is done for both DIMMs and the lists are compared to - * find the lowest common CAS latency setting. If there are no CAS settings - * in common we out a ERROR_DIFF_DIMMS (78h) to port 80h and halt. - * - * Entry: - * Exit: Set fastest CAS Latency based on GeodeLink speed and SPD information. - * Destroys: We really use everything ! - */ - uint16_t glspeed; - uint8_t spd_byte, casmap0, casmap1; - msr_t msr; - - glspeed = GeodeLinkSpeed(); - - casmap0 = getcasmap(DIMM0, glspeed); - casmap1 = getcasmap(DIMM1, glspeed); - - /* CAS_LAT MAP COMPARE */ - if (casmap0 == 0) { - spd_byte = CASDDR[__builtin_ctz(casmap1)]; - } else if (casmap1 == 0) { - spd_byte = CASDDR[__builtin_ctz(casmap0)]; - } else if ((casmap0 &= casmap1)) { - spd_byte = CASDDR[__builtin_ctz(casmap0)]; - } else { - printk(BIOS_EMERG, "DIMM CAS Latencies not compatible\n"); - post_code(ERROR_DIFF_DIMMS); - hcf(); - } - - msr = rdmsr(MC_CF8F_DATA); - msr.lo &= ~(7 << CF8F_LOWER_CAS_LAT_SHIFT); - msr.lo |= spd_byte << CF8F_LOWER_CAS_LAT_SHIFT; - wrmsr(MC_CF8F_DATA, msr); -} - -static void set_latencies(void) -{ - uint32_t memspeed, dimm_setting; - uint8_t spd_byte0, spd_byte1; - msr_t msr; - - memspeed = GeodeLinkSpeed() / 2; - dimm_setting = 0; - - /* MC_CF8F setup */ - /* tRAS */ - spd_byte0 = spd_read_byte(DIMM0, SPD_tRAS); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_tRAS); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { - spd_byte0 = spd_byte1; - } - /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ - spd_byte1 = (spd_byte0 * memspeed) / 1000; - if (((spd_byte0 * memspeed) % 1000)) { - ++spd_byte1; - } - if (spd_byte1 > 6) { - --spd_byte1; - } - dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2PRE_SHIFT; - - /* tRP */ - spd_byte0 = spd_read_byte(DIMM0, SPD_tRP); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_tRP); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { - spd_byte0 = spd_byte1; - } - /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ - spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; - if ((((spd_byte0 >> 2) * memspeed) % 1000)) { - ++spd_byte1; - } - dimm_setting |= spd_byte1 << CF8F_LOWER_PRE2ACT_SHIFT; - - /* tRCD */ - spd_byte0 = spd_read_byte(DIMM0, SPD_tRCD); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_tRCD); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { - spd_byte0 = spd_byte1; - } - /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ - spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; - if ((((spd_byte0 >> 2) * memspeed) % 1000)) { - ++spd_byte1; - } - dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2CMD_SHIFT; - - /* tRRD */ - spd_byte0 = spd_read_byte(DIMM0, SPD_tRRD); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_tRRD); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - if (spd_byte0 < spd_byte1) { - spd_byte0 = spd_byte1; - } - /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */ - spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000; - if ((((spd_byte0 >> 2) * memspeed) % 1000)) { - ++spd_byte1; - } - dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2ACT_SHIFT; - - /* tRC = tRP + tRAS */ - dimm_setting |= (((dimm_setting >> CF8F_LOWER_ACT2PRE_SHIFT) & 0x0F) + - ((dimm_setting >> CF8F_LOWER_PRE2ACT_SHIFT) & 0x07)) - << CF8F_LOWER_REF2ACT_SHIFT; - - msr = rdmsr(MC_CF8F_DATA); - msr.lo &= 0xF00000FF; - msr.lo |= dimm_setting; - msr.hi |= CF8F_UPPER_REORDER_DIS_SET; - wrmsr(MC_CF8F_DATA, msr); - printk(BIOS_DEBUG, "MSR MC_CF8F_DATA (%08x) value is %08x:%08x\n", - MC_CF8F_DATA, msr.hi, msr.lo); -} - -static void set_extended_mode_registers(void) -{ - uint8_t spd_byte0, spd_byte1; - msr_t msr; - spd_byte0 = spd_read_byte(DIMM0, SPD_DEVICE_ATTRIBUTES_GENERAL); - if (spd_byte0 == 0xFF) { - spd_byte0 = 0; - } - spd_byte1 = spd_read_byte(DIMM1, SPD_DEVICE_ATTRIBUTES_GENERAL); - if (spd_byte1 == 0xFF) { - spd_byte1 = 0; - } - spd_byte1 &= spd_byte0; - - msr = rdmsr(MC_CF07_DATA); - if (spd_byte1 & 1) { /* Drive Strength Control */ - msr.lo |= CF07_LOWER_EMR_DRV_SET; - } - if (spd_byte1 & 2) { /* FET Control */ - msr.lo |= CF07_LOWER_EMR_QFC_SET; - } - wrmsr(MC_CF07_DATA, msr); -} - -static void sdram_set_registers(const struct mem_controller *ctrl) -{ - msr_t msr; - uint32_t msrnum; - - /* Set Refresh Staggering */ - msrnum = MC_CF07_DATA; - msr = rdmsr(msrnum); - msr.lo &= ~0xC0; - msr.lo |= 0x0; /* set refresh to 4SDRAM clocks */ - wrmsr(msrnum, msr); -} - -static void sdram_set_spd_registers(const struct mem_controller *ctrl) -{ - uint8_t spd_byte; - - printk(BIOS_DEBUG, "sdram_set_spd_register\n"); - post_code(POST_MEM_SETUP); /* post_70h */ - - spd_byte = spd_read_byte(DIMM0, SPD_MODULE_ATTRIBUTES); - printk(BIOS_DEBUG, "Check DIMM 0\n"); - /* Check DIMM is not Register and not Buffered DIMMs. */ - if ((spd_byte != 0xFF) && (spd_byte & 3)) { - printk(BIOS_EMERG, "DIMM0 NOT COMPATIBLE\n"); - post_code(ERROR_UNSUPPORTED_DIMM); - hcf(); - } - printk(BIOS_DEBUG, "Check DIMM 1\n"); - spd_byte = spd_read_byte(DIMM1, SPD_MODULE_ATTRIBUTES); - if ((spd_byte != 0xFF) && (spd_byte & 3)) { - printk(BIOS_EMERG, "DIMM1 NOT COMPATIBLE\n"); - post_code(ERROR_UNSUPPORTED_DIMM); - hcf(); - } - - post_code(POST_MEM_SETUP2); /* post_72h */ - printk(BIOS_DEBUG, "Check DDR MAX\n"); - - /* Check that the memory is not overclocked. */ - checkDDRMax(); - - /* Size the DIMMS */ - post_code(POST_MEM_SETUP3); /* post_73h */ - printk(BIOS_DEBUG, "AUTOSIZE DIMM 0\n"); - auto_size_dimm(DIMM0); - post_code(POST_MEM_SETUP4); /* post_74h */ - printk(BIOS_DEBUG, "AUTOSIZE DIMM 1\n"); - auto_size_dimm(DIMM1); - - /* Set CAS latency */ - printk(BIOS_DEBUG, "set cas latency\n"); - post_code(POST_MEM_SETUP5); /* post_75h */ - setCAS(); - - /* Set all the other latencies here (tRAS, tRP....) */ - printk(BIOS_DEBUG, "set all latency\n"); - set_latencies(); - - /* Set Extended Mode Registers */ - printk(BIOS_DEBUG, "set emrs\n"); - set_extended_mode_registers(); - - printk(BIOS_DEBUG, "set ref rate\n"); - /* Set Memory Refresh Rate */ - set_refresh_rate(); -} - -/* Section 6.1.3, LX processor databooks, BIOS Initialization Sequence - * Section 4.1.4, GX/CS5535 GeodeROM Porting guide */ -static void sdram_enable(int controllers, const struct mem_controller *ctrl) -{ - int i; - msr_t msr; - - /* 2. clock gating for PMode */ - msr = rdmsr(MC_GLD_MSR_PM); - msr.lo &= ~0x04; - msr.lo |= 0x01; - wrmsr(MC_GLD_MSR_PM, msr); - /* undocmented bits in GX, in LX there are - * 8 bits in PM1_UP_DLY */ - msr = rdmsr(MC_CF1017_DATA); - msr.lo = 0x0101; - wrmsr(MC_CF1017_DATA, msr); - printk(BIOS_DEBUG, "sdram_enable step 2\n"); - - /* 3. release CKE mask to enable CKE */ - msr = rdmsr(MC_CFCLK_DBUG); - msr.lo &= ~(0x03 << 8); - wrmsr(MC_CFCLK_DBUG, msr); - printk(BIOS_DEBUG, "sdram_enable step 3\n"); - - /* 4. set and clear REF_TST 16 times, more shouldn't hurt - * why this is before EMRS and MRS ? */ - for (i = 0; i < 19; i++) { - msr = rdmsr(MC_CF07_DATA); - msr.lo |= (0x01 << 3); - wrmsr(MC_CF07_DATA, msr); - msr.lo &= ~(0x01 << 3); - wrmsr(MC_CF07_DATA, msr); - } - printk(BIOS_DEBUG, "sdram_enable step 4\n"); - - /* 6. enable DLL, load Extended Mode Register by set and clear PROG_DRAM */ - msr = rdmsr(MC_CF07_DATA); - msr.lo |= ((0x01 << 28) | 0x01); - wrmsr(MC_CF07_DATA, msr); - msr.lo &= ~((0x01 << 28) | 0x01); - wrmsr(MC_CF07_DATA, msr); - printk(BIOS_DEBUG, "sdram_enable step 6\n"); - - /* 7. Reset DLL, Bit 27 is undocumented in GX datasheet, - * it is documented in LX datasheet */ - /* load Mode Register by set and clear PROG_DRAM */ - msr = rdmsr(MC_CF07_DATA); - msr.lo |= ((0x01 << 27) | 0x01); - wrmsr(MC_CF07_DATA, msr); - msr.lo &= ~((0x01 << 27) | 0x01); - wrmsr(MC_CF07_DATA, msr); - printk(BIOS_DEBUG, "sdram_enable step 7\n"); - - /* 8. load Mode Register by set and clear PROG_DRAM */ - msr = rdmsr(MC_CF07_DATA); - msr.lo |= 0x01; - wrmsr(MC_CF07_DATA, msr); - msr.lo &= ~0x01; - wrmsr(MC_CF07_DATA, msr); - printk(BIOS_DEBUG, "sdram_enable step 8\n"); - - /* wait 200 SDCLKs */ - for (i = 0; i < 200; i++) - outb(0xaa, 0x80); - - /* load RDSYNC */ - msr = rdmsr(MC_CF_RDSYNC); - msr.hi = 0x000ff310; - /* the above setting is supposed to be good for "slow" ram. We have found that for - * some dram, at some clock rates, e.g. hynix at 366/244, this will actually - * cause errors. The fix is to just set it to 0x310. Tested on 3 boards - * with 3 different type of dram -- Hynix, PSC, infineon. - * I am leaving this comment here so that at some future time nobody is tempted - * to mess with this setting -- RGM, 9/2006 - */ - msr.hi = 0x00000310; - msr.lo = 0x00000000; - wrmsr(MC_CF_RDSYNC, msr); - - /* set delay control */ - msr = rdmsr(GLCP_DELAY_CONTROLS); - msr.hi = 0x830d415a; - msr.lo = 0x8ea0ad6a; - wrmsr(GLCP_DELAY_CONTROLS, msr); - - /* The RAM dll needs a write to lock on so generate a few dummy writes */ - /* Note: The descriptor needs to be enabled to point at memory */ - for (i = 0; i < 5; i++) { - write32(zeroptr + i, i); - } - - printk(BIOS_INFO, "RAM DLL lock\n"); - -} diff --git a/src/northbridge/amd/gx2/raminit.h b/src/northbridge/amd/gx2/raminit.h deleted file mode 100644 index a49bf20886..0000000000 --- a/src/northbridge/amd/gx2/raminit.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef RAMINIT_H -#define RAMINIT_H - -#define DIMM_SOCKETS 2 - -struct mem_controller { - uint16_t channel0[DIMM_SOCKETS]; -}; - -void sdram_initialize(int controllers, const struct mem_controller *ctrl); - -#endif /* RAMINIT_H */ |