summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2019-11-19 15:42:02 +0100
committerKyösti Mälkki <kyosti.malkki@gmail.com>2019-11-20 18:32:42 +0000
commit0fd398a5a151fec4b3e5f257322b21a84ca48e87 (patch)
tree55253ac38064705b8e9509eb06938ac7249e814e /src/northbridge
parent4c38ed3c38ac5ef0136bf5d5c893d8b71d82b531 (diff)
downloadcoreboot-0fd398a5a151fec4b3e5f257322b21a84ca48e87.tar.xz
nb/via/vx900: Drop support
Relocatable ramstage, postcar stage and C_ENVIRONMENT_BOOTBLOCK are now mandatory features, which this platform lacks. Change-Id: Ie971893da06fd3b1ac41dda398b1caeec3ee32db Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/36951 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr> Reviewed-by: Nico Huber <nico.h@gmx.de>
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/via/vx900/Kconfig48
-rw-r--r--src/northbridge/via/vx900/Makefile.inc50
-rw-r--r--src/northbridge/via/vx900/bootblock.c46
-rw-r--r--src/northbridge/via/vx900/chip.h54
-rw-r--r--src/northbridge/via/vx900/chrome9hd.c277
-rw-r--r--src/northbridge/via/vx900/early_host_bus_ctl.c68
-rw-r--r--src/northbridge/via/vx900/early_smbus.c193
-rw-r--r--src/northbridge/via/vx900/early_vx900.c130
-rw-r--r--src/northbridge/via/vx900/early_vx900.h74
-rw-r--r--src/northbridge/via/vx900/lpc.c266
-rw-r--r--src/northbridge/via/vx900/memmap.c135
-rw-r--r--src/northbridge/via/vx900/northbridge.c345
-rw-r--r--src/northbridge/via/vx900/pci_util.c39
-rw-r--r--src/northbridge/via/vx900/pcie.c120
-rw-r--r--src/northbridge/via/vx900/raminit.h98
-rw-r--r--src/northbridge/via/vx900/raminit_ddr3.c1671
-rw-r--r--src/northbridge/via/vx900/romstrap.S56
-rw-r--r--src/northbridge/via/vx900/romstrap.ld24
-rw-r--r--src/northbridge/via/vx900/sata.c275
-rw-r--r--src/northbridge/via/vx900/traf_ctrl.c142
-rw-r--r--src/northbridge/via/vx900/vx900.h44
21 files changed, 0 insertions, 4155 deletions
diff --git a/src/northbridge/via/vx900/Kconfig b/src/northbridge/via/vx900/Kconfig
deleted file mode 100644
index 8d95942866..0000000000
--- a/src/northbridge/via/vx900/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me@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, 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.
-##
-
-config NORTHBRIDGE_VIA_VX900
- bool
- select IOAPIC
- select DRIVERS_GENERIC_IOAPIC
- select HAVE_DEBUG_RAM_SETUP
- select HAVE_DEBUG_SMBUS
- select HAVE_CF9_RESET
- select NO_RELOCATABLE_RAMSTAGE
-
-if NORTHBRIDGE_VIA_VX900
-
-config MAX_PIRQ_LINKS
- int
- default 8
-
-config MMCONF_BASE_ADDRESS
- hex
- default 0xe0000000
-
-config MMCONF_BUS_NUMBER
- int
- default 256
-
-config VGA_BIOS_ID
- string
- default "1106,7122"
-
-config BOOTBLOCK_NORTHBRIDGE_INIT
- string
- default "northbridge/via/vx900/bootblock.c"
-
-endif
diff --git a/src/northbridge/via/vx900/Makefile.inc b/src/northbridge/via/vx900/Makefile.inc
deleted file mode 100644
index 247cc249bf..0000000000
--- a/src/northbridge/via/vx900/Makefile.inc
+++ /dev/null
@@ -1,50 +0,0 @@
-##
-## This file is part of the coreboot project.
-##
-## Copyright (C) 2011-2013 Alexandru Gagniuc <mr.nuke.me@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, 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.
-##
-
-ifeq ($(CONFIG_NORTHBRIDGE_VIA_VX900),y)
-
-romstage-y += pci_util.c
-romstage-y += early_smbus.c
-romstage-y += early_vx900.c
-romstage-y += early_host_bus_ctl.c
-romstage-y += raminit_ddr3.c
-romstage-y += memmap.c
-romstage-y += ./../../../device/dram/ddr3.c
-romstage-y += ./../../../southbridge/via/common/early_smbus_delay.c
-romstage-y += ./../../../southbridge/via/common/early_smbus_is_busy.c
-romstage-y += ./../../../southbridge/via/common/early_smbus_print_error.c
-romstage-y += ./../../../southbridge/via/common/early_smbus_reset.c
-romstage-y += ./../../../southbridge/via/common/early_smbus_wait_until_ready.c
-
-ramstage-y += pci_util.c
-ramstage-y += pcie.c
-ramstage-y += northbridge.c
-ramstage-y += chrome9hd.c
-ramstage-y += traf_ctrl.c
-ramstage-y += sata.c
-ramstage-y += lpc.c
-ramstage-y += memmap.c
-
-# The buildsystem only includes this file if CONFIG_VGA is selected.
-# We need to do some VGA I/O before the VGA can be initialized. We can make good
-# use of some of the functions there, so include them unconditionally
-ramstage-y += ./../../../drivers/pc80/vga/vga_io.c
-
-
-bootblock-y += romstrap.ld
-bootblock-y += romstrap.S
-
-endif
diff --git a/src/northbridge/via/vx900/bootblock.c b/src/northbridge/via/vx900/bootblock.c
deleted file mode 100644
index 6679cdb31b..0000000000
--- a/src/northbridge/via/vx900/bootblock.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2017 Lubomir Rintel <lkundrak@v3.sk>
- *
- * 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.
- */
-
-#include <device/pci_ops.h>
-
-#if CONFIG_ROM_SIZE == 0x80000
-# define ROM_DECODE_MAP 0x00
-#elif CONFIG_ROM_SIZE == 0x100000
-# define ROM_DECODE_MAP 0x40
-#elif CONFIG_ROM_SIZE == 0x180000
-# define ROM_DECODE_MAP 0x60
-#elif CONFIG_ROM_SIZE == 0x200000
-# define ROM_DECODE_MAP 0x70
-#elif CONFIG_ROM_SIZE == 0x280000
-# define ROM_DECODE_MAP 0x78
-#elif CONFIG_ROM_SIZE == 0x300000
-# define ROM_DECODE_MAP 0x7c
-#elif CONFIG_ROM_SIZE == 0x380000
-# define ROM_DECODE_MAP 0x7e
-#elif CONFIG_ROM_SIZE == 0x400000
-# define ROM_DECODE_MAP 0x7f
-#else
-# error "Bad CONFIG_ROM_SIZE"
-#endif
-
-static void bootblock_northbridge_init(void)
-{
- u8 reg;
-
- pci_io_read_config8(PCI_DEV(0, 0x11, 0), 0x41);
- reg |= ROM_DECODE_MAP;
- pci_io_write_config8(PCI_DEV(0, 0x11, 0), 0x41, reg);
-}
diff --git a/src/northbridge/via/vx900/chip.h b/src/northbridge/via/vx900/chip.h
deleted file mode 100644
index 91a7a3d119..0000000000
--- a/src/northbridge/via/vx900/chip.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#ifndef __VIA_VX900_CHIP_H__
-#define __VIA_VX900_CHIP_H__
-
-struct northbridge_via_vx900_config {
- /**
- * \brief PCIe Lane[3:0] Function Select
- *
- * PCIe Lane3~Lane0 (PEXTX[3:0]P/VCC) can be used by the integrated
- * graphic controller to output its display data. The PCIe lanes will
- * be used to output DisplayPort data.
- */
- u8 assign_pex_to_dp;
-
- /**
- * \brief Lane Width for Root Port 1
- *
- * Two PCIe lanes are used for Root port 1. Root port 2 is disabled.
- */
- u8 pcie_port1_2_lane_wide;
-
- /**
- * \brief PIRQ line to which to route the external interrupt
- *
- * The VX900 features an external interrupt which can be routed to any
- * of the PIRQA->PIRQH lines. Usually, on-board devices are connected
- * to the external interrupt. In some vendor BIOS's pirq table, this
- * appears as link 9.
- *
- * Setting this line only affects the behavior of the integrated PIC. It
- * has no effect on the IOAPIC.
- *
- * The value of this register must be a literal upper-case character
- * from 'A' to 'H'.
- */
- char ext_int_route_to_pirq;
-};
-
-#endif
diff --git a/src/northbridge/via/vx900/chrome9hd.c b/src/northbridge/via/vx900/chrome9hd.c
deleted file mode 100644
index fef53502f8..0000000000
--- a/src/northbridge/via/vx900/chrome9hd.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci_ops.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/vga_io.h>
-#include <stdlib.h>
-
-#include "vx900.h"
-
-/**
- * @file chrome9hd.c
- *
- * \brief Initialization for Chrome9HD integrated graphics adapters
- *
- * This takes care of the initialization we need to do before calling the VGA
- * BIOS. The device is not documented in the VX900 datasheet.
- *
- * The device is documented in:
- * Open Graphics Programming Manual
- * Chrome9GraphicsHD Processor
- * VX900 Series System Processor
- * Part I: Graphics Core / 2D
- *
- * This document was released by VIA to the Xorg project, and is available at:
- * <http://www.x.org/docs/via/OGPM_Chrome9%20HD%20DX9%20_R100_PartI_Core_2D.pdf>
- *
- * STATUS:
- * We do the minimal initialization described in VIA documents. Running the VGA
- * option ROM does not get us a usable display. We configure the framebuffer and
- * the IGP is able to use it. GRUB2 and linux are capable of getting a usable
- * text console, which uses the monitor's native resolution (even 1920x1080).
- * The graphical console (linux) does not work properly.
- * @todo
- * 1. Figure out what sequence we need to do to get the VGA BIOS running
- * properly. Use the code provided by VIA and compare their sequence to ours,
- * fill in any missing steps, etc.
- * 2. Make BAR2 and the framebuffer use the same memory space. This is a feature
- * called "Direct framebuffer access" which allows us to save memory space by
- * setting BAR2 of the VGA to the location in memory of the framebuffer. This
- * reduces the amount of PCI MMIO space we need below 4G, and is especially
- * useful considering we only have 8GB (33 bits) of memory-mapped space.
- */
-
-/**
- * vx900_int15
- *
- * \brief INT15 helpers for Chrome9HD IGP
- *
- * The following are helpers for INT15 handlers for the VGA BIOS. The full set
- * of INT15 callbacks is described in
- *
- * VIA/S3Graphics
- * Video BIOS External Interface Specification for Chrome9 Series IGP
- * VX900 Series
- *
- * This document is only available under NDA, however, the callbacks are very
- * similar to other VIA/Intel IGP callbacks.
- *
- * Callback 0x5f18 is the most important one. It informs the VGA BIOS of the
- * RAM speed and framebuffer size. The other callbacks seem to be optional.
- * @{
- */
-
-/**
- * \brief Get X86_BL value for VGA INT15 function 5f18
- *
- * Int15 5f18 lets the VGA BIOS know the framebuffer size and the memory speed.
- * This handler is very important. If it is not implemented, the VGA BIOS will
- * not work correctly.
- *
- * To use, just call this from the 15f18 handler, and place the return value in
- * X86_BL
- *
- * @code{.c}
- * case 0x5f18:
- * X86_BX = vx900_int15_get_5f18_bl();
- * res = 0;
- * break;
- * @endcode
- *
- */
-u8 vx900_int15_get_5f18_bl(void)
-{
- u8 reg8, ret;
- struct device *dev;
- /*
- * BL Bit[7:4]
- * Memory Data Rate (not to be confused with fCLK)
- * 0000: 66MHz
- * 0001: 100MHz
- * 0010: 133MHz
- * 0011: 200MHz (DDR200)
- * 0100: 266MHz (DDR266)
- * 0101: 333MHz (DDR333)
- * 0110: 400MHz (DDR400)
- * 0111: 533MHz (DDR I/II 533)
- * 1000: 667MHz (DDR I/II 667)
- * 1001: 800MHz (DDR3 800)
- * 1010: 1066MHz (DDR3 1066)
- * 1011: 1333MHz (DDR3 1333)
- * Bit[3:0]
- * N: Frame Buffer Size 2^N MB
- */
- dev = pcidev_on_root(0, 3);
- reg8 = pci_read_config8(dev, 0xa1);
- ret = (u32) ((reg8 & 0x70) >> 4) + 2;
- reg8 = pci_read_config8(dev, 0x90);
- reg8 = ((reg8 & 0x07) + 3) << 4;
- ret |= (u32) reg8;
-
- return ret;
-}
-
-/** @} */
-
-static void chrome9hd_set_sid_vid(u16 vendor, u16 device)
-{
- vga_sr_write(0x36, vendor >> 8); /* SVID high byte */
- vga_sr_write(0x35, vendor & 0xff); /* SVID low byte */
- vga_sr_write(0x38, device >> 8); /* SID high byte */
- vga_sr_write(0x37, device & 0xff); /* SID low byte */
-}
-
-static void chrome9hd_handle_uma(struct device *dev)
-{
- u8 fb_pow = vx900_get_chrome9hd_fb_pow();
-
- if (fb_pow == 0)
- return;
-
- /* Step 7 - Let GFX know the framebuffer size (through PCI and IOCTL)
- * The size we set here affects the behavior of BAR2, and the amount of
- * MMIO space it requests. The default is 512MB, so if we don't set this
- * before reading the resources, we could waste space below 4G */
- pci_write_config8(dev, 0xb2, ((0xff << (fb_pow - 2)) & ~(1 << 7)));
- vga_sr_write(0x68, (0xff << (fb_pow - 1)));
- /* And also that the framebuffer is in the system, RAM */
- pci_or_config8(dev, 0xb0, 1 << 0);
-}
-
-/**
- * \brief Initialization sequence before running the VGA BIOS
- *
- * This is the initialization sequence described in:
- *
- * BIOS Porting Guide
- * VX900 Series
- * All-in-One System Processor
- *
- * This document is only available under NDA.
- */
-static void chrome9hd_biosguide_init_seq(struct device *dev)
-{
- struct device *mcu = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_MEMCTRL, 0);
- struct device *host = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_HOST_BR, 0);
-
- /* Step 1 - Enable VGA controller */
- /* FIXME: This is the VGA hole @ 640k-768k, and the vga port io
- * We need the port IO, but can we disable the memory hole? */
- pci_or_config8(mcu, 0xa4, (1 << 7)); /* VGA memory hole */
-
- /* Step 2 - Forward MDA cycles to GFX */
- pci_or_config8(host, 0x4e, (1 << 1));
-
- /* Step 3 - Enable GFX I/O space */
- pci_or_config8(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Step 4 - Enable video subsystem */
- vga_enable_mask((1 << 0), (1 << 0));
-
- /* FIXME: VGA IO Address Select. 3B5 or 3D5? */
- vga_misc_mask((1 << 0), (1 << 0));
-
- /* Step 5 - Unlock accessing of IO space */
- vga_sr_write(0x10, 0x01);
-
- chrome9hd_handle_uma(dev);
-
- uint64_t gfx_base = get_uma_memory_base();
- if (gfx_base == 0)
- die("uma_memory_base not set. Abandon ship!\n");
-
- /* Step 8 - Enable memory base register on the GFX */
- vga_sr_write(0x6d, (gfx_base >> 21) & 0xff); /* base 28:21 */
- vga_sr_write(0x6e, (gfx_base >> 29) & 0xff); /* base 36:29 */
- vga_sr_write(0x6f, 0x00); /* base 43:37 */
-
- /* Step 9 - Set SID/VID */
- chrome9hd_set_sid_vid(0x1106, 0x7122);
-
-}
-
-static void chrome9hd_init(struct device *dev)
-{
- printk(BIOS_DEBUG, "======================================================\n");
- printk(BIOS_DEBUG, "== Chrome9 HD INIT\n");
- printk(BIOS_DEBUG, "======================================================\n");
-
- chrome9hd_biosguide_init_seq(dev);
-
- /* Prime PLL FIXME: bad comment */
- vga_sr_mask(0x3c, 1 << 2, 1 << 2);
-
- /* FIXME: recheck; VGA IO Address Select. 3B5 or 3D5? */
- vga_misc_mask(1 << 0, 1 << 0);
-
- /* FIXME: recheck; Enable Base VGA 16 Bits Decode */
-
- u32 fb_address = pci_read_config32(dev, PCI_BASE_ADDRESS_2);
- fb_address &= ~0x0F;
- if (!fb_address) {
- printk(BIOS_WARNING, "Chrome9HD: No FB BAR assigned!\n");
- return;
- }
-
- printk(BIOS_INFO, "Chrome: Using %dMB Framebuffer at 0x%08X.\n",
- 256, fb_address);
-
- printk(BIOS_DEBUG, "Initializing VGA...\n");
-
- pci_dev_init(dev);
-
- printk(BIOS_DEBUG, "Enable VGA console\n");
-
- dump_pci_device(PCI_BDF(dev));
-}
-
-static void chrome9hd_enable(struct device *dev)
-{
- struct device *mcu = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_MEMCTRL, 0);
- /* FIXME: here? -=- ACLK 250MHz */
- pci_or_config8(mcu, 0xbb, 0x01);
-}
-
-static void chrome9hd_disable(struct device *dev)
-{
- struct device *mcu = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_MEMCTRL, 0);
- /* Disable GFX - This step effectively renders the GFX inert
- * It won't even show up as a PCI device during enumeration */
- pci_update_config8(mcu, 0xa1, (u8)~(1 << 7), 0);
-}
-
-static struct device_operations chrome9hd_operations = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = chrome9hd_init,
- .disable = chrome9hd_disable,
- .enable = chrome9hd_enable,
- .ops_pci = 0,
-};
-
-static const struct pci_driver chrome9hd_driver __pci_driver = {
- .ops = &chrome9hd_operations,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VX900_VGA,
-};
diff --git a/src/northbridge/via/vx900/early_host_bus_ctl.c b/src/northbridge/via/vx900/early_host_bus_ctl.c
deleted file mode 100644
index 1ef29449fd..0000000000
--- a/src/northbridge/via/vx900/early_host_bus_ctl.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci_ops.h>
-
-#include "early_vx900.h"
-
-static void vx900_cpu_bus_preram_setup(void)
-{
- /* Faster CPU to DRAM Cycle */
- pci_update_config8(HOST_BUS, 0x50, ~0x0f, 0x08);
- /* CPU Interface Control - Basic Options */
- pci_or_config8(HOST_BUS, 0x51, 0x6c);
- /*CPU Interface Control - Advanced Options */
- pci_write_config8(HOST_BUS, 0x52, 0xc7);
- /* Enable 8QW burst and 4QW request merging [4] and [2]
- * and special mode for read cycles bit[3] */
- pci_or_config8(HOST_BUS, 0x54, (1 << 4) | (1 << 2) | (1 << 3));
- /* High priority upstream requests on V4 bus */
- pci_write_config8(HOST_BUS, 0x56, 0x03);
- /* CPU to DRAM extra 1T access control */
- pci_or_config8(HOST_BUS, 0x59, (1 << 2));
- /* Queue reordering */
- pci_or_config8(HOST_BUS, 0x5f, (1 << 6));
- /* Only Write cycle of CPU->GFXCTL will flush the CPU->Memory FIFO */
- pci_or_config8(HOST_BUS, 0x98, 0x60);
- /* 1T delay for data on CPU bus */
- pci_write_config8(HOST_BUS, 0x9e, 0x0e);
- /* Arbitrate ownership of DRAM controller a few cycles earlier */
- pci_or_config8(HOST_BUS, 0x9f, (1 << 7));
- /* Write retire policy */
- pci_write_config8(HOST_BUS, 0x5d, 0xa2);
- /* Occupancy timer */
- pci_write_config8(HOST_BUS, 0x53, 0x44);
- /* Medium Threshold for Write Retire Policy - 6 requests */
- pci_or_config8(HOST_BUS, 0x56, 0x60);
- /* Bandwidth timer */
- pci_write_config8(HOST_BUS, 0x5e, 0x44);
-}
-
-/**
- * \brief Configure the CPU to northbridge bus (formerly, FSB)
- *
- * Configure the CPU <-> host interface. This interface is complex and needs to
- * be set up to operate properly. Configured parameters include bandwidth
- * arbitration. This function does not, however, change the physical interface
- * parameters, such as drive strength and signal timing. Instead, it assumes
- * that those parameters were already configured correctly from the ROMSTRAP.
- */
-void vx900_cpu_bus_interface_setup(void)
-{
- vx900_cpu_bus_preram_setup();
-
- dump_pci_device(HOST_BUS);
-}
diff --git a/src/northbridge/via/vx900/early_smbus.c b/src/northbridge/via/vx900/early_smbus.c
deleted file mode 100644
index 5816926f59..0000000000
--- a/src/northbridge/via/vx900/early_smbus.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci_ids.h>
-#include "early_vx900.h"
-#include <device/early_smbus.h>
-
-#include <arch/io.h>
-#include <device/pci_ops.h>
-#include <console/console.h>
-
-/**
- * \brief SMBUS IO ports in relation to the base IO port
- */
-#define SMBHSTSTAT(base) (u16)(u32)base + 0x0
-#define SMBSLVSTAT(base) (u16)(u32)base + 0x1
-#define SMBHSTCTL(base) (u16)(u32)base + 0x2
-#define SMBHSTCMD(base) (u16)(u32)base + 0x3
-#define SMBXMITADD(base) (u16)(u32)base + 0x4
-#define SMBHSTDAT0(base) (u16)(u32)base + 0x5
-#define SMBHSTDAT1(base) (u16)(u32)base + 0x6
-#define SMBBLKDAT(base) (u16)(u32)base + 0x7
-#define SMBSLVCTL(base) (u16)(u32)base + 0x8
-#define SMBTRNSADD(base) (u16)(u32)base + 0x9
-#define SMBSLVDATA (base) (u16)(u32)base + 0xa
-
-static void smbus_delays(int delays)
-{
- while (delays--)
- smbus_delay();
-}
-
-/**
- * Read a byte from the SMBus.
- *
- * @param smbus_dev The PCI address of the SMBus device .
- * @param addr The address location of the DIMM on the SMBus.
- * @param offset The offset the data is located at.
- */
-u8 smbus_read_byte(u32 smbus_dev, u8 addr, u8 offset)
-{
- u8 val;
-
- /* Initialize SMBUS sequence */
- smbus_reset(smbus_dev);
- /* Clear host data port. */
- outb(0x00, SMBHSTDAT0(smbus_dev));
-
- smbus_wait_until_ready(smbus_dev);
- smbus_delays(50);
-
- /* Actual addr to reg format. */
- addr = (addr << 1);
- addr |= 1; /* read command */
- outb(addr, SMBXMITADD(smbus_dev));
- outb(offset, SMBHSTCMD(smbus_dev));
- /* Start transaction, byte data read. */
- outb(0x48, SMBHSTCTL(smbus_dev));
- smbus_wait_until_ready(smbus_dev);
-
- val = inb(SMBHSTDAT0(smbus_dev));
- return val;
-}
-
-void enable_smbus(void)
-{
- pci_devfn_t dev;
- u8 reg8;
- u32 smbus_dev = (u32) SMBUS_IO_BASE;
-
- /* Locate the Power Management control */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_LPC), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("Power Management Controller not found\n");
- }
-
- /*
- * To use SMBus to manage devices on the system board, it is a must to
- * enable SMBus function by setting
- * PMU_RXD2[0] (SMBus Controller Enable) to 1.
- * And set PMU_RXD0 and PMU_RXD1 (SMBus I/O Base) to an appropriate
- * I/O port address, so that all registers in SMBus I/O port can be
- * accessed.
- */
-
- reg8 = pci_read_config8(dev, 0xd2);
- /* Enable SMBus controller */
- reg8 |= 1;
- /* Set SMBUS clock from 128k source */
- reg8 |= 1 << 2;
- pci_write_config8(dev, 0xd2, reg8);
-
- reg8 = pci_read_config8(dev, 0x94);
- /* SMBUS clock from divider of 14.318 MHz */
- reg8 &= ~(1 << 7);
- pci_write_config8(dev, 0x94, reg8);
-
- /* Set SMBus IO base */
- pci_write_config16(dev, 0xd0, SMBUS_IO_BASE);
-
- /*
- * Initialize the SMBus sequence:
- */
- /* Clear SMBus host status register */
- smbus_reset(smbus_dev);
- /* Clear SMBus host data 0 register */
- outb(0x00, SMBHSTDAT0(smbus_dev));
-
- /* Wait for SMBUS */
- smbus_wait_until_ready(smbus_dev);
-
-}
-
-static int spd_get_length(u8 spd_byte0)
-{
- spd_byte0 &= 0xf;
-
- switch (spd_byte0) {
- case 0x3:
- return 256;
- case 0x2:
- return 176;
- case 0x1:
- return 128;
- default:
- break;
- }
- return 0;
-}
-
-void spd_read(u8 addr, spd_raw_data spd)
-{
- u8 reg;
- int i, regs;
- u32 smbus_dev = SMBUS_IO_BASE;
-
- reg = smbus_read_byte(smbus_dev, addr, 2);
- if (reg != 0x0b) {
- printk(BIOS_DEBUG, "SMBUS device %x not a DDR3 module\n", addr);
- spd[2] = 0;
- return;
- }
-
- reg = smbus_read_byte(smbus_dev, addr, 0);
- if ((regs = spd_get_length(reg)) == 0) {
- printk(BIOS_INFO, "No DIMM present at %x\n", addr);
- spd[2] = 0;
- return;
- }
-
- for (i = 0; i < regs; i++)
- spd[i] = smbus_read_byte(smbus_dev, addr, i);
-}
-
-void dump_spd_data(spd_raw_data spd)
-{
- int len, i;
- u8 reg;
-
- if ((len = spd_get_length(spd[0])) == 0) {
- printk(BIOS_DEBUG, "Invalid SPD\n");
- return;
- }
-
- /*
- * I originally saw this way to present SPD data in code from VIA. I
- * really liked the idea, so here it goes.
- */
- printk(BIOS_DEBUG, " 00 01 02 03 04 05 06 07 07 09 0A 0B 0C 0D 0E 0F\n");
- printk(BIOS_DEBUG, "---+------------------------------------------------");
- for (i = 0; i < len; i++) {
- reg = spd[i];
- if ((i & 0x0f) == 0)
- printk(BIOS_DEBUG, "\n%.2x |", i);
- printk(BIOS_DEBUG, " %.2x", reg);
- }
- printk(BIOS_DEBUG, "\n");
-}
diff --git a/src/northbridge/via/vx900/early_vx900.c b/src/northbridge/via/vx900/early_vx900.c
deleted file mode 100644
index e50b96812d..0000000000
--- a/src/northbridge/via/vx900/early_vx900.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include "early_vx900.h"
-#include <device/pci_ops.h>
-#include <console/console.h>
-
-/**
- * \brief Enable accessing of PCI configuration space for all devices.
- *
- * Enable accessing of D0F1 through D0F7, which would otherwise not be
- * accessible. If MMCONF is enabled, configure it here. This is the first
- * function that should be called in romstage.
- */
-void vx900_enable_pci_config_space(void)
-{
- /* MMCONF is not yet enabled, so we'll need to specify we want to do
- * pci_io. We don't want to do pci_mmio until we enable it */
- /* Enable multifunction bit for northbridge.
- * This enables the PCI configuration spaces of D0F1 to D0F7 to be
- * accessed */
- pci_io_write_config8(HOST_CTR, 0x4f, 0x01);
-
- /* COOL, now enable MMCONF */
- u8 reg8 = pci_io_read_config8(TRAF_CTR, 0x60);
- reg8 |= 3;
- pci_io_write_config8(TRAF_CTR, 0x60, reg8);
-
- reg8 = CONFIG_MMCONF_BASE_ADDRESS >> 28;
- pci_io_write_config8(TRAF_CTR, 0x61, reg8);
-}
-
-/**
- *\brief Prints information regarding the hardware strapping on VX900
- *
- * Certain features on the VX900 are controlled by strapping pins which are
- * hardwired on the mainboard. These values determine whether the ROM is on the
- * SPI or LPC bus, or whether auto-reset is enabled.
- * \n
- * Having a feel for these values is important when trying to fix obscure
- * problems found when porting a mainboard based on the VX900.
- * \n
- * These values are decoded and printed to the terminal.
- */
-void vx900_print_strapping_info(void)
-{
- u8 strap = pci_read_config8(SNMIC, 0x56);
-
- printk(BIOS_DEBUG, "VX900 strapping pins indicate that:\n");
- printk(BIOS_DEBUG, " ROM is on %s bus\n",
- (strap & (1 << 0)) ? "SPI" : "LPC");
- printk(BIOS_DEBUG, " Auto reset is %s\n",
- (strap & (1 << 1)) ? "disabled" : "enabled");
- printk(BIOS_DEBUG, " LPC FWH command is %s\n",
- (strap & (1 << 2)) ? "enabled" : "disabled");
- printk(BIOS_DEBUG, " Debug link is is %s\n",
- (strap & (1 << 4)) ? "enabled" : "disabled");
- printk(BIOS_DEBUG, " PCI master mode is %s\n",
- (strap & (1 << 5)) ? "enabled" : "disabled");
-}
-
-/**
- *\brief Disables the auto-reboot mechanism on VX900
- *
- * The VX900 has an auto-reboot mechanism that can be enabled by a hardware
- * strap. This mechanism can make development annoying, since we don't know if
- * the reset was caused by a bug in coreboot, or by this mechanism.
- */
-void vx900_disable_auto_reboot(void)
-{
- if (pci_read_config8(SNMIC, 0x56) & (1 << 1)) {
- printk(BIOS_DEBUG, "Auto-reboot is disabled in hardware\n");
- return;
- }
- /* Disable the GP3 timer, which is the root of all evil */
- pci_write_config8(LPC, 0x98, 0);
- /* Yep, that's all it takes */
- printk(BIOS_DEBUG, "GP3 timer disabled."
- " Auto-reboot should not give you any more trouble.\n");
-}
-
-/**
- * \brief Disables 'shadowing' of system ROM
- *
- * Disable unnecessary shadowing of the ROM in the first 1MB of address space.
- * coreboot runs in 32-bit mode from the start. Shadowing only gets in the way.
- * This function frees the entire 640k-1M range for DRAM. VGA may still use
- * the 640k-768k range, if enabled later.
- */
-void vx900_disable_legacy_rom_shadow(void)
-{
- pci_write_config8(MCU, 0x80, 0xff); /* LPC ROM 768k - 832k */
- pci_write_config8(MCU, 0x81, 0xff); /* LPC ROM 832k - 896k */
- pci_write_config8(MCU, 0x82, 0xff); /* LPC ROM 896k - 960k */
- /* LPC ROM 960k - 1M * SMRAM: 640k - 768k */
- pci_write_config8(MCU, 0x83, 0x31);
-
- /* Bits 6:0 are the ROM shadow on top of 4G, so leave those untouched */
- pci_update_config8(LPC, 0x41, (u8)~(1 << 7), 0); /* LPC ROM 896k - 960k */
-
- pci_write_config8(SNMIC, 0x61, 0); /* 768k - 832k */
- pci_write_config8(SNMIC, 0x62, 0); /* 832k - 896k */
- pci_write_config8(SNMIC, 0x63, 0); /* 896k - 1M */
- pci_write_config8(SNMIC, 0x64, 0); /* 896k - 960k */
-}
-
-/**
- * \brief Disables the VX900 integrated graphics controller
- *
- * Disable the graphics controller entirely. It will no longer be visible as a
- * PCI device.
- */
-void vx900_disable_gfx(void)
-{
- /* Disable GFX */
- pci_update_config8(MCU, 0xa1, (u8)~(1 << 7), 0);
-}
diff --git a/src/northbridge/via/vx900/early_vx900.h b/src/northbridge/via/vx900/early_vx900.h
deleted file mode 100644
index c1a823beaa..0000000000
--- a/src/northbridge/via/vx900/early_vx900.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011-2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#ifndef EARLY_VX900_H
-#define EARLY_VX900_H
-
-#include "raminit.h"
-#include "vx900.h"
-
-#include <stdint.h>
-
-/* North Module devices */
-#define HOST_CTR PCI_DEV(0, 0, 0)
-#define ERR_REP PCI_DEV(0, 0, 1)
-#define HOST_BUS PCI_DEV(0, 0, 2)
-#define MCU PCI_DEV(0, 0, 3)
-#define POWERMAN PCI_DEV(0, 0, 4)
-#define TRAF_CTR PCI_DEV(0, 0, 5)
-#define NSBIC PCI_DEV(0, 0, 7)
-
-#define GFX PCI_DEV(0, 1, 0)
-#define HDMI PCI_DEV(0, 1, 0)
-
-#define PEXx PCI_DEV(0, 3, x)
-#define PEX_CTR PCI_DEV(0, 3, 4)
-
-/* South Module devices */
-#define UARTx PCI_DEV(0, 0x0a, x)
-#define USB_MASS PCI_DEV(0, 0x0b, 0)
-#define SDIO PCI_DEV(0, 0x0c, 0)
-#define CARD_RD PCI_DEV(0, 0x0d, 0)
-#define SATA PCI_DEV(0, 0x0d, 0)
-#define USBx PCI_DEV(0, 0x10, x)
-#define USB_EHCI PCI_DEV(0, 0x10, 4)
-#define LPC PCI_DEV(0, 0x11, 0)
-#define PMU LPC
-#define SNMIC PCI_DEV(0, 0x11, 7)
-#define P2P PCI_DEV(0, 0x13, 0)
-#define HDAC PCI_DEV(0, 0x14, 0)
-
-/* These control the behavior of raminit */
-#define RAMINIT_USE_HW_RXCR_CALIB 0
-#define RAMINIT_USE_HW_MRS_SEQ 0
-
-
-void enable_smbus(void);
-void dump_spd_data(spd_raw_data spd);
-void spd_read(u8 addr, spd_raw_data spd);
-
-void vx900_enable_pci_config_space(void);
-void vx900_disable_legacy_rom_shadow(void);
-
-void vx900_print_strapping_info(void);
-void vx900_disable_auto_reboot(void);
-
-void vx900_cpu_bus_interface_setup(void);
-
-void vx900_dram_set_gfx_resources(void);
-void vx900_disable_gfx(void);
-
-#endif /* EARLY_VX900_H */
diff --git a/src/northbridge/via/vx900/lpc.c b/src/northbridge/via/vx900/lpc.c
deleted file mode 100644
index fd4d5ad2a2..0000000000
--- a/src/northbridge/via/vx900/lpc.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012-2013 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci_ops.h>
-#include <arch/pirq_routing.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/i8259.h>
-#include <drivers/generic/ioapic/chip.h>
-
-#include "vx900.h"
-#include "chip.h"
-
-/**
- * @file vx900/lpc.c
- *
- * STATUS:
- * We do a fair bit of setup, and most of it seems to work fairly well. There
- * are still a few FIXME items here and there, but overall, this code hasn't
- * been touched much from its initial 2012 version to 2013, when it was revived.
- *
- * We do the IOAPIC setup with the assumption that it is declared in the
- * mainboard's devicetree.cb. We cannot use the IOAPIC however. The interrupts
- * do not make it to the CPU. This issue is still under investigation.
- *
- * We also route PIRQs with CONFIG_PIRQ_ROUTE. This is currently the only way to
- * get interrupts working.
- *
- * On the VX900, the keyboard can be connected directly to the chipset
- * (referenced as "internal keyboard" in the documents). As long as that is the
- * case (not connected to the superIO), and we disable the superIO keyboard LDN,
- * it will work, but perhaps this should be more configurable.
- */
-
-static void vx900_lpc_misc_stuff(struct device *dev)
-{
- char extint;
- u8 val;
- struct northbridge_via_vx900_config *nb = (void *)dev->chip_info;
-
- /* GPIO 11,10 to SATALED [1,0] */
- pci_or_config8(dev, 0xe4, 1 << 0);
-
- /* Route the external interrupt line */
- extint = nb->ext_int_route_to_pirq;
- if (extint < 'A' || extint > 'H') {
- printk(BIOS_WARNING, "Invalid PIRQ%c for external interrupt\n",
- extint);
- } else {
- printk(BIOS_INFO, "Routing external interrupt to PIRQ%c\n",
- extint);
- val = extint - 'A';
- val |= (1 << 3); /* bit3 enables the external int */
- pci_update_config8(dev, 0x55, ~0xf, val);
-
- }
-}
-
-static void vx900_lpc_dma_setup(struct device *dev)
-{
- /* These are the steps recommended by VIA in order to get DMA running */
-
- /* Enable Positive South Module PCI Cycle Decoding */
- /* FIXME: Setting this seems to hang our system */
-
- /* Positive decoding for ROM + APIC + On-board IO ports */
- pci_or_config8(dev, 0x6c, (1 << 2) | (1 << 3) | (1 << 7));
- /* Enable DMA channels. BIOS guide recommends DMA channel 2 off */
- pci_write_config8(dev, 0x53, 0xfb);
- /* Disable PCI/DMA Memory Cycles Output to PCI Bus */
- pci_update_config8(dev, 0x5b, ~(1 << 5), 0);
- /* DMA bandwidth control - Improved bandwidth */
- pci_write_config8(dev, 0x53, 0xff);
- /* ISA Positive Decoding control */
- pci_write_config8(dev, 0x6d, 0xdf);
- pci_write_config8(dev, 0x6e, 0x98);
- pci_write_config8(dev, 0x6f, 0x30);
-}
-
-/**
- *\brief VX900: Set up the south module IOAPIC (for the ISA/LPC bus)
- *
- * Enable the IOAPIC in the south module, and properly set it up.
- * \n
- * This is the hardware specific initialization for the IOAPIC, and complements
- * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work
- * properly, it _must_ be declared in devicetree.cb .
- * \n
- * We are assuming this is called before the drivers/generic/ioapic code,
- * which should be the case if devicetree.cb is set up properly.
- */
-static void vx900_lpc_ioapic_setup(struct device *dev)
-{
- /* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb
- * If it's not, then the generic ioapic driver will not set it up
- * correctly, and the MP table will not be correctly generated */
- struct device *ioapic;
- for (ioapic = dev->next; ioapic; ioapic = ioapic->next) {
- if (ioapic->path.type == DEVICE_PATH_IOAPIC)
- break;
- }
-
- /* You did put an IOAPIC in devicetree.cb, didn't you? */
- if (ioapic == 0) {
- /* We don't have enough info to set up the IOAPIC */
- printk(BIOS_ERR, "ERROR: South module IOAPIC not found. "
- "Check your devicetree.cb\n");
- return;
- }
-
- /* Found an IOAPIC, now we need to make sure it's the right one */
- ioapic_config_t *config = (ioapic_config_t *) ioapic->chip_info;
- if (!config->have_isa_interrupts) {
- /* Umh, is this the right IOAPIC ? */
- printk(BIOS_ERR, "ERROR: South module IOAPIC not carrying ISA "
- "interrupts. Check your devicetree.cb\n");
- printk(BIOS_ERR, "Will not initialize this IOAPIC.\n");
- return;
- }
-
- /* The base address of this IOAPIC _must_ be at 0xfec00000.
- * Don't move this value to a #define, as people might think it's
- * configurable. It is not. */
- const void *base = config->base;
- if (base != (void *)0xfec00000) {
- printk(BIOS_ERR, "ERROR: South module IOAPIC base should be at "
- "0xfec00000\n but we found it at %p\n", base);
- return;
- }
-
- printk(BIOS_DEBUG, "VX900 LPC: Setting up the south module IOAPIC.\n");
- /* Enable IOAPIC
- * So much work for one line of code. Talk about bloat :)
- * The 8259 PIC should still work even if the IOAPIC is enabled, so
- * there's no crime in enabling the IOAPIC here. */
- pci_or_config8(dev, 0x58, 1 << 6);
-}
-
-static void vx900_lpc_interrupt_stuff(struct device *dev)
-{
- /* Enable setting trigger mode through 0x4d0, and 0x4d1 ports
- * And enable I/O recovery time */
- pci_or_config8(dev, 0x40, (1 << 2) | (1 << 6));
- /* Set serial IRQ frame width to 6 PCI cycles (recommended by VIA)
- * And enable serial IRQ */
- pci_update_config8(dev, 0x52, ~(3 << 0), (1 << 3) | (1 << 0));
-
- /* Disable IRQ12 storm FIXME: bad comment */
- pci_update_config8(dev, 0x51, ~(1 << 2), 0);
-
- pci_write_config8(dev, 0x4c, (1 << 6));
-
- /* FIXME: Do we really need this? SeaBIOS/linux runs fine without it.
- * Is this something the payload/OS should do, or is it safe for us to
- * do it? */
- /* Get the IRQs up and running */
- setup_i8259();
-
- vx900_lpc_dma_setup(dev);
-
- /* The IOAPIC is special, and we treat it separately */
- vx900_lpc_ioapic_setup(dev);
-}
-
-static void vx900_lpc_init(struct device *dev)
-{
- vx900_lpc_interrupt_stuff(dev);
- vx900_lpc_misc_stuff(dev);
- dump_pci_device(PCI_BDF(dev));
-}
-
-static void vx900_lpc_read_resources(struct device *dev)
-{
- struct resource *res;
- pci_dev_read_resources(dev);
-
- /* MMIO space */
- res = new_resource(dev, VX900_MMCONFIG_MBAR);
- res->size = 0x1000;
- res->align = 12;
- res->gran = 12;
- res->limit = 0xffffffff;
- res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE;
-
- /* SPI controller */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->size = 0x8;
- res->align = 12;
- res->gran = 12;
- res->limit = 0xffffffff;
- res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE;
-}
-
-static void vx900_lpc_set_resources(struct device *dev)
-{
- struct resource *mmio, *spi;
- u32 reg;
-
- mmio = find_resource(dev, VX900_MMCONFIG_MBAR);
- if (mmio) {
- report_resource_stored(dev, mmio, "<mmconfig>");
- mmio->flags |= IORESOURCE_STORED;
- reg = pci_read_config32(dev, VX900_MMCONFIG_MBAR);
- reg &= 0xff000000;
- reg |= mmio->base >> 8;
- pci_write_config32(dev, VX900_MMCONFIG_MBAR, reg);
-
- spi = find_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- if (spi) {
- report_resource_stored(dev, spi, "<spi>");
- spi->flags |= IORESOURCE_STORED;
- /* Set base and the enable bit. */
- ((u32*)(uintptr_t)mmio->base)[0] = (spi->base | 0x01);
- }
- }
- pci_dev_set_resources(dev);
-}
-
-static struct device_operations vx900_lpc_ops = {
- .read_resources = vx900_lpc_read_resources,
- .set_resources = vx900_lpc_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vx900_lpc_init,
- .scan_bus = scan_static_bus,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &vx900_lpc_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VX900_LPC,
-};
-
-#if CONFIG(PIRQ_ROUTE)
-void pirq_assign_irqs(const u8 *pirq)
-{
- struct device *lpc;
-
- lpc = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_LPC, 0);
-
- /* Take care of INTA -> INTD */
- pci_update_config8(lpc, 0x55, (u8)~(0xf << 4), pirq[0] << 4);
- pci_write_config8(lpc, 0x56, pirq[1] | (pirq[2] << 4));
- pci_write_config8(lpc, 0x57, pirq[3] << 4);
-
- /* Enable INTE -> INTH to be on separate IRQs */
- pci_or_config8(lpc, 0x46, 1 << 4);
- /* Now do INTE -> INTH */
- pci_write_config8(lpc, 0x44, pirq[4] | (pirq[5] << 4));
- pci_write_config8(lpc, 0x45, pirq[6] | (pirq[7] << 4));
-}
-#endif
diff --git a/src/northbridge/via/vx900/memmap.c b/src/northbridge/via/vx900/memmap.c
deleted file mode 100644
index 3121d7406e..0000000000
--- a/src/northbridge/via/vx900/memmap.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
- * Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>
- *
- * 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.
- */
-
-#define __SIMPLE_DEVICE__
-
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <lib.h>
-
-#include "vx900.h"
-
-#define MCU PCI_DEV(0, 0, 3)
-
-#define CHROME_9_HD_MIN_FB_SIZE 8
-#define CHROME_9_HD_MAX_FB_SIZE 512
-
-/* Helper to determine the framebuffer size */
-void vx900_set_chrome9hd_fb_size(u32 size_mb)
-{
- u8 reg8, ranksize;
- u32 tom_mb, max_size_mb;
- int i;
-
- /* The minimum framebuffer size is 8MB. */
- size_mb = MAX(size_mb, CHROME_9_HD_MIN_FB_SIZE);
-
- /*
- * We have two limitations on the maximum framebuffer size:
- * 1) (Sanity) No more that 1/4 of system RAM
- * 2) (Hardware limitation) No larger than DRAM in last rank
- * Check both of these limitations and apply them to our framebuffer */
- tom_mb = (pci_read_config16(MCU, 0x88) & 0x07ff) << (24 - 20);
- max_size_mb = tom_mb >> 2;
- if (size_mb > max_size_mb) {
- printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
- " than 1/4 of available memory.\n"
- " Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
- size_mb = max_size_mb;
- }
-
- /* Now handle limitation #2
- * Look at the ending address of the memory ranks, from last to first,
- * until we find one that is not zero. That is our last rank, and its
- * size is the limit of our framebuffer. */
- /* FIXME: This has a bug. If we remap memory above 4G, we consider the
- * memory hole as part of our RAM. Thus if we install 3G, with a TOLM of
- * 2.5G, our TOM will be at 5G and we'll assume we have 5G RAM instead
- * of the actual 3.5G */
- for (i = VX900_MAX_MEM_RANKS - 1; i > -1; i--) {
- reg8 = pci_read_config8(MCU, 0x40 + i);
- if (reg8 == 0)
- continue;
- /* We've reached the last populated rank */
- ranksize = reg8 - pci_read_config8(MCU, 0x48 + i);
- max_size_mb = ranksize << 6;
- /* That's it. We got what we needed. */
- break;
- }
- if (size_mb > max_size_mb) {
- printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
- " than size of the last DRAM rank.\n"
- " Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
- size_mb = max_size_mb;
- }
-
- /* Now round down the framebuffer size to the closest power of 2 */
- if (size_mb == 0)
- die("Framebuffer size is 0\n");
-
- int fb_pow = log2(size_mb);
-
- size_mb = 1U << fb_pow;
-
- if (size_mb < CHROME_9_HD_MIN_FB_SIZE || size_mb > CHROME_9_HD_MAX_FB_SIZE)
- die("Framebuffer size %u is out of range\n", size_mb);
-
- pci_update_config8(MCU, 0xa1, ~(7 << 4), (fb_pow - 2) << 4);
-}
-
-/* Gets the configured framebuffer size as a power of 2 */
-u8 vx900_get_chrome9hd_fb_pow(void)
-{
- u8 fb_pow = (pci_read_config8(MCU, 0xa1) >> 4) & 7;
-
- if (fb_pow > 0)
- fb_pow += 2;
-
- return fb_pow;
-}
-
-/* Gets the configured framebuffer size in MB */
-u32 vx900_get_chrome9hd_fb_size(void)
-{
- u8 size = vx900_get_chrome9hd_fb_pow();
-
- if (size == 0)
- return 0;
-
- return 1 << size;
-}
-
-u32 vx900_get_tolm(void)
-{
- return (pci_read_config16(MCU, 0x84) & 0xfff0) >> 4;
-}
-
-void *cbmem_top_chipset(void)
-{
- uintptr_t tolm;
- uintptr_t fb_size;
-
- tolm = vx900_get_tolm ();
- fb_size = vx900_get_chrome9hd_fb_size ();
-
- if (tolm > 0xfc0 || tolm <= 0x3ff || fb_size == 0x0)
- return NULL;
-
- return (void *)((tolm - fb_size) << 20);
-}
diff --git a/src/northbridge/via/vx900/northbridge.c b/src/northbridge/via/vx900/northbridge.c
deleted file mode 100644
index 260bd3de05..0000000000
--- a/src/northbridge/via/vx900/northbridge.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include "vx900.h"
-#include "chip.h"
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <cpu/cpu.h>
-#include <cf9_reset.h>
-#include <reset.h>
-
-#define RAM_4GB (((u64)1) << 32)
-
-static uint64_t uma_memory_base = 0;
-static uint64_t uma_memory_size = 0;
-
-/**
- * @file vx900/northbridge.c
- *
- * STATUS: Pretty good
- * One thing that needs to be thoroughly tested is the remap above 4G logic.
- * Unfortunately, while we cannot initialize odd ranks, our testing
- * possibilities are somewhat limited. A point of failure that is not covered is
- * when the amount of RAM and PCI config space added up exceeds 8GB. The
- * remapping mechanism will overflow, the effects of which are unknown.
- */
-
-void do_board_reset(void)
-{
- system_reset();
-}
-
-uint64_t get_uma_memory_base(void)
-{
- printk(BIOS_DEBUG, "UMA base 0x%.8llx (%lluMB)\n", uma_memory_base,
- uma_memory_base >> 20);
- printk(BIOS_DEBUG, "UMA size 0x%.8llx (%lluMB)\n", uma_memory_size,
- uma_memory_size >> 20);
- return uma_memory_base;
-}
-
-static u64 vx900_get_top_of_ram(struct device *mcu)
-{
- u16 reg16;
- /* The last valid DRAM address is computed by the MCU
- * One issue might be if we have a hole in the rank mappings, so that
- * virtual ranks are not mapped successively in the linear address space
- * (Ex: rank 0 mapped 0-1G, rank 1 mapped 2G-3G)
- * We don't do this awkward mapping in RAM init, so we don't worry about
- * it here, but it is something to keep in mind if having RAM issues */
- reg16 = pci_read_config16(mcu, 0x88) & 0x07ff;
- return (u64) reg16 << 24;
-}
-
-/*
- * This guy is meant to go away, but for now, leave it in so that we can see
- * if the logic to remap RAM above 4G has errors.
- */
-static void killme_debug_4g_remap_reg(u32 reg32)
-{
- if (reg32 & (1 << 0))
- printk(BIOS_DEBUG, "Mem remapping enabled\n");
- u64 remapstart = (reg32 >> 2) & 0x3ff;
- u64 remapend = (reg32 >> 14) & 0x3ff;
- remapstart <<= 26;
- remapend <<= 26;
- printk(BIOS_DEBUG, "Remapstart %lld(MB)\n", remapstart >> 20);
- printk(BIOS_DEBUG, "Remapend %lld(MB)\n", remapend >> 20);
-}
-
-/**
- * \brief Remap low memory colliding with PCI MMIO space, above 4G
- *
- * @param mcu The memory controller
- * @param tolm Top of low memory.
- *
- * @return The new top of memory.
- */
-static u64 vx900_remap_above_4g(struct device *mcu, u32 tolm)
-{
- size_t i;
- u8 reg8, start8, end8, start, end;
- u16 reg16;
- u32 reg32;
- u64 tor, newtor, chunk;
-
- /*
- * The remapping mechanism works like this:
- *
- * - Choose the top of low memory.
- * This becomes the "remap from"
- * - Choose a chunk above 4G where to remap.
- * This becomes "remap to"
- * - Choose a chunk above 4G where to end the remapping.
- * This becomes "remap until"
- *
- * This remaps a "chunk" of memory where we want to.
- * sizeof(chunk) = until - to;
- *
- * Therefore the memory region from "from" to " from + sizeof(chunk)"
- * becomes accessible at "to" to "until"
- */
- if (tolm >= vx900_get_top_of_ram(mcu)) {
- printk(BIOS_DEBUG, "Nothing to remap\n");
- return 0;
- }
-
- /* This is how the Vendor BIOS. Keep it for comparison for now */
- killme_debug_4g_remap_reg(0x00180141);
- /* We can remap with a granularity of 64MB, so align tolm */
- tolm &= ~((64 * MiB) - 1);
-
- /* The "start remapping from where ?" register */
- reg16 = ((tolm >> 20) & 0xfff) << 4;
- pci_update_config16(mcu, 0x84, (u16)~0xfff0, reg16);
-
- /* Find the chunk size */
- tor = vx900_get_top_of_ram(mcu);
- printk(BIOS_DEBUG, "Top of RAM %lldMB\n", tor >> 20);
-
- if (tor < RAM_4GB) {
- chunk = tor - tolm;
- newtor = RAM_4GB + chunk;
- } else {
- chunk = (RAM_4GB - tolm);
- newtor = tor + chunk;
- }
- printk(BIOS_DEBUG, "New top of RAM %lldMB\n", newtor >> 20);
-
- reg8 = tolm >> 26;
- /* Which rank does the PCI TOLM fall on? */
- for (i = 0; i < VX900_MAX_MEM_RANKS; i++) {
- end8 = pci_read_config8(mcu, 0x40 + i);
- if (reg8 > end8)
- continue;
- start8 = pci_read_config8(mcu, 0x48 + i);
- if (reg8 <= start8)
- continue;
- printk(BIOS_DEBUG, "Address %x falls on rank %zu\n", tolm, i);
- break;
- }
-
- for (; i < VX900_MAX_MEM_RANKS; i++) {
- start = pci_read_config8(mcu, 0x48 + i);
- end = pci_read_config8(mcu, 0x40 + i);
-
- if (end == 0) {
- printk(BIOS_DEBUG, "Huh? rank %zu empty?\n", i);
- continue;
- }
-
- if (end < (tolm >> 26)) {
- printk(BIOS_DEBUG, "Huh? rank %zu don't need remap?\n",
- i);
- continue;
- }
-
- printk(BIOS_DEBUG, "Physical rank %u is mapped to\n"
- " Start address: 0x%.10llx (%dMB)\n"
- " End address: 0x%.10llx (%dMB)\n",
- (int)i,
- ((u64) start << 26), (start << (26 - 20)),
- ((u64) end << 26), (end << (26 - 20)));
-
- if (end < (RAM_4GB >> 26))
- end = (RAM_4GB >> 26);
-
- if (end >= (tolm >> 26))
- end += chunk >> 26;
-
- if (start > (tolm >> 26))
- start += chunk >> 26;
-
- pci_write_config8(mcu, 0x48 + i, start);
- pci_write_config8(mcu, 0x40 + i, end);
-
- printk(BIOS_DEBUG, "ReMapped Physical rank %u, to\n"
- " Start address: 0x%.10llx (%dMB)\n"
- " End address: 0x%.10llx (%dMB)\n",
- (int)i,
- ((u64) start << 26), (start << (26 - 20)),
- ((u64) end << 26), (end << (26 - 20)));
- }
-
- /* The "remap to where?" register */
- reg32 = ((MAX(tor, RAM_4GB) >> 26) & 0x3ff) << 2;
- /* The "remap until where?" register */
- reg32 |= ((newtor >> 26) & 0x3ff) << 14;
- /* Now enable the goodies */
- reg32 |= (1 << 0);
- pci_write_config32(mcu, 0xf8, reg32);
- printk(BIOS_DEBUG, "Wrote remap map %x\n", reg32);
- killme_debug_4g_remap_reg(reg32);
-
- printk(BIOS_DEBUG, "New top of memory is at %lldMB\n", newtor >> 20);
- return newtor;
-}
-
-static void vx900_set_resources(struct device *dev)
-{
- u32 pci_tolm, tomk, vx900_tolm, full_tolmk, fbufk, tolmk;
-
- printk(BIOS_DEBUG, "========================================"
- "========================================\n");
- printk(BIOS_DEBUG, "============= VX900 memory sizing & Co. "
- "========================================\n");
- printk(BIOS_DEBUG, "========================================"
- "========================================\n");
-
- int idx = 10;
- struct device *const mcu = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_MEMCTRL,
- 0);
- if (!mcu) {
- die("Something is terribly wrong.\n"
- " We tried locating the MCU on the PCI bus, "
- "but couldn't find it. Halting.\n");
- }
-
- /* How much low adrress space do we have? */
- pci_tolm = find_pci_tolm(dev->link_list);
- printk(BIOS_SPEW, "Found PCI tolm at %.8x\n", pci_tolm);
- printk(BIOS_SPEW, "Found PCI tolm at %dMB\n", pci_tolm >> 20);
-
- /* Figure out the total amount of RAM */
- tomk = vx900_get_top_of_ram(mcu) >> 10;
- printk(BIOS_SPEW, "Found top of memory at %dMB\n", tomk >> 10);
-
- /* Do the same for top of low RAM */
- vx900_tolm = vx900_get_tolm();
- full_tolmk = vx900_tolm << (20 - 10);
- /* Remap above 4G if needed */
- full_tolmk = MIN(full_tolmk, pci_tolm >> 10);
- printk(BIOS_SPEW, "Found top of low memory at %dMB\n",
- full_tolmk >> 10);
-
- /* What about the framebuffer for the integrated GPU? */
- fbufk = vx900_get_chrome9hd_fb_size() << (20 - 10);
- printk(BIOS_SPEW, "Integrated graphics buffer: %dMB\n", fbufk >> 10);
-
- /* Can't use the framebuffer as system RAM, sorry */
- tolmk = MIN(full_tolmk, tomk);
- tolmk -= fbufk;
- ram_resource(dev, idx++, 0, 640);
- printk(BIOS_SPEW, "System RAM left: %dMB\n", tolmk >> 10);
- /* FIXME: how can we avoid leaving this hole?
- * Leave a hole for VGA, 0xa0000 - 0xc0000 ?? */
- /* TODO: VGA Memory hole can be disabled in SNMIC. Upper 64k of ROM seem
- * to be always mapped to the top of 1M, but this can be overcome with
- * some smart positive/subtractive resource decoding */
- ram_resource(dev, idx++, 768, (tolmk - 768));
-
- uma_memory_size = (uint64_t)fbufk << 10;
- uma_memory_base = (uint64_t)tolmk << 10;
-
- if (uma_memory_size > UINT32_MAX)
- die("uma_memory_size %llu exceeds 32-bit address range\n", uma_memory_size);
-
- if (uma_memory_base > UINT32_MAX)
- die("uma_memory_base %llu exceeds 32-bit address range\n", uma_memory_base);
-
- //uma_resource(dev, idx++, uma_memory_base>>10, uma_memory_size>>10);
-
- printk(BIOS_DEBUG, "UMA @ %lldMB + %lldMB\n", uma_memory_base >> 20,
- uma_memory_size >> 20);
- /* FIXME: How do we handle remapping above 4G? */
- u64 tor = vx900_remap_above_4g(mcu, pci_tolm);
- if (tor)
- ram_resource(dev, idx++, RAM_4GB >> 10, (tor - RAM_4GB) >> 10);
-
- printk(BIOS_DEBUG, "======================================================\n");
- assign_resources(dev->link_list);
-}
-
-static void vx900_read_resources(struct device *dev)
-{
- /* Our fixed resources start at 0 */
- int idx = 0;
- /* Reserve our ROM mapped space */
- struct resource *res;
- res = new_resource(dev, idx++);
- res->size = CONFIG_ROM_SIZE;
- res->base = 0xffffffff - (res->size - 1);
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- /* Now do the same for our MMCONF
- * We always run with MMCONF enabled. We need to access the extended
- * config space when configuring PCI-Express links */
- mmconf_resource(dev, idx++);
-
- pci_domain_read_resources(dev);
-}
-
-static struct device_operations pci_domain_ops = {
- .read_resources = vx900_read_resources,
- .set_resources = vx900_set_resources,
- .enable_resources = NULL,
- .init = NULL,
- .scan_bus = pci_domain_scan_bus,
-};
-
-static void cpu_bus_init(struct device *dev)
-{
- 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)
-{
- /* 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_via_vx900_ops = {
- CHIP_NAME("VIA VX900 Chipset")
- .enable_dev = enable_dev,
-};
diff --git a/src/northbridge/via/vx900/pci_util.c b/src/northbridge/via/vx900/pci_util.c
deleted file mode 100644
index 57b08e7586..0000000000
--- a/src/northbridge/via/vx900/pci_util.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <console/console.h>
-#include <device/pci_ops.h>
-
-#include "vx900.h"
-
-void dump_pci_device(pci_devfn_t dev)
-{
- int i;
- for (i = 0; i <= 0xff; i++) {
- unsigned char val;
- if ((i & 0x0f) == 0)
- printk(BIOS_DEBUG, "%.2x:", i);
-
- if ((i & 0x0f) == 0x08)
- printk(BIOS_DEBUG, " |");
-
- val = pci_s_read_config8(dev, i);
- printk(BIOS_DEBUG, " %.2x", val);
-
- if ((i & 0x0f) == 0x0f)
- printk(BIOS_DEBUG, "\n");
- }
-}
diff --git a/src/northbridge/via/vx900/pcie.c b/src/northbridge/via/vx900/pcie.c
deleted file mode 100644
index ef157d8a02..0000000000
--- a/src/northbridge/via/vx900/pcie.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci_ops.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pciexp.h>
-#include <device/pci_ids.h>
-
-#include "vx900.h"
-
-/**
- * @file vx900/pcie.c
- *
- * STATUS:
- * We do part of the sequence to initialize the PCIE link. The problem is that
- * the reset signal for each slot is connected to a GPO pin, but We don't know
- * which GPO pin. We need to figure out which GPIO pin is hooked to which slot,
- * and have a mechanism to specify this per-mainboard (devicetree.cb).
- *
- * There is currently no timeout detection mechanism for when a link comes up.
- * If the link never comes up, we hang.
- */
-
-static void vx900_pcie_link_init(struct device *dev)
-{
- u8 reg8;
- u32 reg32;
-
- u8 fn = dev->path.pci.devfn & 0x07;
-
- /* Step 1 : Check for presence of PCIE device */
- reg8 = pci_read_config8(dev, 0x5a);
-
- if (reg8 & (1 << 6))
- printk(BIOS_DEBUG, "Card detected in PEX%i\n", fn);
- else
- return;
-
- /* Step 2: Wait for device to enter L0 state */
- /* FIXME: implement timeout detection */
- while (0x8a != pci_read_config8(dev, 0x1c3));
-
- /* Step 3: Clear PCIe error status, then check for failures */
- pci_write_config32(dev, 0x104, 0xffffffff);
- reg32 = pci_read_config32(dev, 0x104);
- if (0 != reg32) {
- printk(BIOS_DEBUG, "PEX init error. flags 0x%.8x\n", reg32);
- return;
- }
-
- pci_write_config32(dev, 0x110, 0xffffffff);
- reg32 = pci_read_config32(dev, 0x110);
- if (0 != reg32)
- printk(BIOS_DEBUG, "PEX errors. flags 0x%.8x\n", reg32);
-
- pci_write_config8(dev, 0xa4, 0xff);
- if (pci_read_config8(dev, 0x4a) & (1 << 3))
- printk(BIOS_DEBUG, "Unsupported request detected.\n");
-
- pci_write_config8(dev, 0x15a, 0xff);
- if (pci_read_config8(dev, 0x15a) & (1 << 1))
- printk(BIOS_DEBUG, "Negotiation pending.\n");
-
- /* Step 4: Read vendor ID */
- /* FIXME: Do we want to run through the whole sequence and delay boot
- * by several seconds if the device does not respond properly the first
- * time? */
-}
-
-static void vx900_pex_dev_set_resources(struct device *dev)
-{
- assign_resources(dev->link_list);
-}
-
-static void vx900_pex_init(struct device *dev)
-{
- /* FIXME: For some reason, PEX0 hangs on init. Find issue, fix it. */
- if ((dev->path.pci.devfn & 0x7) == 0)
- return;
-
- vx900_pcie_link_init(dev);
-}
-
-static struct device_operations vx900_pex_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = vx900_pex_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = vx900_pex_init,
- .scan_bus = pciexp_scan_bridge,
- .reset_bus = pci_bus_reset,
-};
-
-static const unsigned short pci_device_ids[] = {
- PCI_DEVICE_ID_VIA_VX900_PEX1,
- PCI_DEVICE_ID_VIA_VX900_PEX2,
- PCI_DEVICE_ID_VIA_VX900_PEX3,
- PCI_DEVICE_ID_VIA_VX900_PEX4,
- 0,
-};
-
-static const struct pci_driver pex_driver __pci_driver = {
- .ops = &vx900_pex_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .devices = pci_device_ids,
-
-};
diff --git a/src/northbridge/via/vx900/raminit.h b/src/northbridge/via/vx900/raminit.h
deleted file mode 100644
index 4c53d52d8c..0000000000
--- a/src/northbridge/via/vx900/raminit.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#ifndef RAMINIT_VX900_H
-#define RAMINIT_VX900_H
-
-#include <device/dram/ddr3.h>
-#include "vx900.h"
-
-#define SPD_END_LIST 0xff
-
-typedef struct dimm_layout_st
-{
- /* The address of the DIMM on the SMBUS *
- * 0xFF to terminate the array*/
- u8 spd_addr[VX900_MAX_DIMM_SLOTS + 1];
-} dimm_layout;
-
-typedef struct dimm_info_st
-{
- dimm_attr dimm[VX900_MAX_DIMM_SLOTS];
-} dimm_info;
-
-typedef struct mem_rank_st {
- u16 start_addr;
- u16 end_addr;
-} mem_rank;
-
-typedef struct rank_layout_st {
- u32 phys_rank_size_mb[VX900_MAX_MEM_RANKS];
- mem_rank virt[VX900_MAX_MEM_RANKS];
- dimm_flags_t flags[VX900_MAX_MEM_RANKS];
-} rank_layout;
-
-typedef struct pci_reg8_st {
- u8 addr;
- u8 val;
-} pci_reg8;
-
-typedef u8 timing_dly[8];
-
-typedef struct delay_range_st {
- timing_dly low;
- timing_dly avg;
- timing_dly high;
-} delay_range;
-
-typedef struct vx900_delay_calib_st {
- delay_range rx_dq_cr;
- delay_range rx_dqs;
- /* Transmit delays are calibrated for each dimm */
- delay_range tx_dq[VX900_MAX_DIMM_SLOTS];
- delay_range tx_dqs[VX900_MAX_DIMM_SLOTS];
-} vx900_delay_calib;
-
-typedef struct ramctr_timing_st {
- enum spd_memory_type dram_type;
- enum spd_dimm_type dimm_type;
- u16 cas_supported;
- /* tLatencies are in units of ns, scaled by x256 */
- u32 tCK;
- u32 tAA;
- u32 tWR;
- u32 tRCD;
- u32 tRRD;
- u32 tRP;
- u32 tRAS;
- u32 tRC;
- u32 tRFC;
- u32 tWTR;
- u32 tRTP;
- u32 tFAW;
- /* Latencies in terms of clock cycles
- * They are saved separately as they are needed for DRAM MRS commands*/
- u8 CAS; /* CAS read latency */
- u8 CWL; /* CAS write latency */
- u8 WR; /* write recovery time */
- /* Number of dimms currently connected */
- u8 n_dimms;
-
-} ramctr_timing;
-
-void vx900_init_dram_ddr3(const dimm_layout *dimms);
-
-#endif /* RAMINIT_VX900_H */
diff --git a/src/northbridge/via/vx900/raminit_ddr3.c b/src/northbridge/via/vx900/raminit_ddr3.c
deleted file mode 100644
index 4f79ed35b0..0000000000
--- a/src/northbridge/via/vx900/raminit_ddr3.c
+++ /dev/null
@@ -1,1671 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011-2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include "early_vx900.h"
-#include "raminit.h"
-#include <arch/io.h>
-#include <device/pci_ops.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <delay.h>
-#include <lib.h>
-#include <string.h>
-
-/**
- * @file raminit_ddr3.c
- *
- * \brief DDR3 initialization for VIA VX900 chipset
- *
- * Rather than explain the DDR3 init algorithm, it is better to focus on what
- * works and what doesn't. Familiarity with the DDR3 spec does not hurt.
- *
- * 1 DIMMs and 2 DIMMs with one rank each works.
- * 1 rank DIMM with 2 rank DIMM works, but the odd ranks are disabled.
- * (2) 2-rank DIMMs will not work.
- *
- * It is not yet clear if odd ranks do not work because of faulty timing
- * calibration, or a misconfiguration of the MCU. I have seen this with DIMMS
- * which mirror pins on the odd rank. That could also be the issue.
- *
- * The capture window is not calibrated, but preset. Whether that preset is
- * universal or frequency dependent, and whether it is board-specific or not is
- * not yet clear. @see vx900_dram_calibrate_receive_delays().
- *
- * 4GBit and 8GBit modules may not work. This is untested. Modules with 11
- * column address bits are not tested. @see vx900_dram_map_row_col_bank()
- *
- * Everything else should be in a more or less usable state. FIXME s are placed
- * all over as a reminder that either something really needs fixing, or as a
- * reminder to double-check.
- */
-
-/* Map BA0 <-> A17, BA1 <-> A18 */
-/* Map BA2 <-> A19, RA0/RA1 must not overlap BA[0:2] */
-#define VX900_MRS_MA_MAP 0x4b33 /* MA Pin Mapping for MRS commands */
-#define VX900_CALIB_MA_MAP 0x5911 /* MA Pin mapping for calibrations */
-
-/*
- * Registers 0x78 -> 0x7f contain the calibration settings for DRAM IO timing
- * The dataset in these registers is selected from 0x70.
- * Once the correct dataset is selected the delays can be altered.
- * delay_type refers to TxDQS, TxDQ, RxDQS, or RxCR
- * bound refers to either manual, average, upper bound, or lower bound
- */
-#define CALIB_TxDQS 0
-#define CALIB_TxDQ 1
-#define CALIB_RxDQS 2
-#define CALIB_RxDQ_CR 3
-
-#define CALIB_AVERAGE 0
-#define CALIB_LOWER 1
-#define CALIB_UPPER 2
-#define CALIB_MANUAL 4 /* We want this & 3 to overflow to 0 */
-
-static void vx900_delay_calib_mode_select(u8 delay_type, u8 bound)
-{
- /* Which calibration setting */
- u8 reg8 = (delay_type & 0x03) << 2;
- /* Upper, lower, average, or manual setting */
- reg8 |= (bound & 0x03);
- pci_write_config8(MCU, 0x70, reg8);
-}
-
-/*
- * The vendor BIOS does something similar to vx900_delay_calib_mode_select(),
- * then reads or write a byte, and repeats the process for all 8 bytes. This is
- * annoyingly inefficient, and we can achieve the same result in a much more
- * elegant manner.
- */
-static void vx900_read_0x78_0x7f(timing_dly dly)
-{
- *((u32 *) (&(dly[0]))) = pci_read_config32(MCU, 0x78);
- *((u32 *) (&(dly[4]))) = pci_read_config32(MCU, 0x7c);
-}
-
-static void vx900_write_0x78_0x7f(const timing_dly dly)
-{
- pci_write_config32(MCU, 0x78, *((u32 *) (&(dly[0]))));
- pci_write_config32(MCU, 0x7c, *((u32 *) (&(dly[4]))));
-}
-
-static void vx900_read_delay_range(delay_range * d_range, u8 mode)
-{
- vx900_delay_calib_mode_select(mode, CALIB_LOWER);
- vx900_read_0x78_0x7f(d_range->low);
- vx900_delay_calib_mode_select(mode, CALIB_AVERAGE);
- vx900_read_0x78_0x7f(d_range->avg);
- vx900_delay_calib_mode_select(mode, CALIB_UPPER);
- vx900_read_0x78_0x7f(d_range->high);
-}
-
-static void dump_delay(const timing_dly dly)
-{
- u8 i;
- for (i = 0; i < 8; i++) {
- printram(" %.2x", dly[i]);
- }
- printram("\n");
-}
-
-static void dump_delay_range(const delay_range d_range)
-{
- printram("Lower limit: ");
- dump_delay(d_range.low);
- printram("Average: ");
- dump_delay(d_range.avg);
- printram("Upper limit: ");
- dump_delay(d_range.high);
-}
-
-/*
- * These are some "safe" values that can be used for memory initialization.
- * Some will stay untouched, and others will be overwritten later on
- */
-static pci_reg8 mcu_init_config[] = {
- {0x40, 0x01}, /* Virtual rank 0 ending address = 64M - 1 */
- {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00}, /* Virtual Ranks ending */
- {0x48, 0x00}, /* Virtual rank 0 starting address = 0 */
- {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00}, /* Virtual Ranks beginning */
- {0x50, 0xd8}, /* Set ranks 0-3 to 11 col bits, 16 row bits */
- /* Disable all virtual ranks */
- {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00},
- /* Disable rank interleaving in ranks 0-3 */
- {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00},
- {0x6c, 0xA0}, /* Memory type: DDR3, VDIMM: 1.5V, 64-bit DRAM */
- {0xc4, 0x80}, /* Enable 8 memory banks */
- {0xc6, 0x80}, /* Minimum latency from self-refresh. Bit [7] must be 1 */
- /* FIXME: do it here or in Final config? */
- {0xc8, 0x80}, /* Enable automatic triggering of short ZQ calibration */
- {0x99, 0xf0}, /* Power Management and Bypass Reorder Queue */
- /* Enable differential DQS; MODT assertion values suggested in DS */
- {0x9e, 0xa1}, {0x9f, 0x51},
- /* DQ/DQM Duty Control - Do not put any extra delays */
- {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00}, {0xec, 0x00},
- {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00},
- {0xfc, 0x00}, {0xfd, 0x00}, {0xfe, 0x00}, {0xff, 0x00},
- /* The following parameters we may or may not change */
- {0x61, 0x2e}, /* DRAMC Pipeline Control */
- {0x77, 0x10}, /* MDQS Output Control */
-
- /* The following are parameters we'll most likely never change again */
- {0x60, 0xf4}, /* DRAM Pipeline Turn-Around Setting */
- {0x65, 0x49}, /* DRAM Arbitration Bandwidth Timer - I */
- {0x66, 0x80}, /* DRAM Queue / Arbitration */
- {0x69, 0xc6}, /* Bank Control: 8 banks, high priority refresh */
- {0x6a, 0xfc}, /* DRAMC Request Reorder Control */
- {0x6e, 0x38}, /* Burst length: 8, burst-chop: enable */
- {0x73, 0x04}, /* Close All Pages Threshold */
-
- /* The following need to be dynamically asserted */
- /* See: check_special_registers.c */
- {0x74, 0xa0}, /* Yes, same 0x74; add one more T */
- {0x76, 0x60}, /* Write Data Phase Control */
-
-};
-
-/*
- * This table keeps the driving strength control setting that we can safely use
- * during initialization. This settings come in part from SerialICE, and in part
- * from code provided by VIA.
- */
-static pci_reg8 mcu_drv_ctrl_config[] = {
- {0xd3, 0x03}, /* Enable auto-compensation circuit for ODT strength */
- {0xd4, 0x80}, /* Set internal ODT to dynamically turn on or off */
- {0xd6, 0x20}, /* Enable strong driving for MA and DRAM commands */
- {0xd0, 0x88}, /* (ODT) Strength ?has effect? */
- {0xe0, 0x88}, /* DRAM Driving - Group DQS (MDQS) */
- {0xe1, 0x00}, /* Disable offset mode for driving strength control */
- {0xe2, 0x88}, /* DRAM Driving - Group DQ (MD, MDQM) */
- {0xe4, 0xcc}, /* DRAM Driving - Group CSA (MCS, MCKE, MODT) */
- {0xe8, 0x88}, /* DRAM Driving - Group MA (MA, MBA, MSRAS, MSCAS, MSWE) */
- {0xe6, 0xff}, /* DRAM Driving - Group DCLK0 (DCLK[2:0] for DIMM0) */
- {0xe7, 0xff}, /* DRAM Driving - Group DCLK1 (DCLK[5:3] for DIMM1) */
- {0xe4, 0xcc}, /* DRAM Driving - Group CSA (MCS, MCKE, MODT) */
- {0x91, 0x08}, /* MCLKO Output Phase Delay - I */
- {0x92, 0x08}, /* MCLKO Output Phase Delay - II */
- {0x93, 0x16}, /* CS/CKE Output Phase Delay */
- {0x95, 0x16}, /* SCMD/MA Output Phase Delay */
- {0x9b, 0x3f}, /* Memory Clock Output Enable */
-};
-
-static void vx900_dram_set_ma_pin_map(u16 map)
-{
- pci_write_config16(MCU, 0x52, map);
-}
-
-/*
- * FIXME: This function is a complete waste of space. All we really need is a
- * MA MAP table based on either row address bits or column address bits.
- * The problem is, I do not know if this mapping is applied during the column
- * access or during the row access. At least the religiously verbose output
- * makes pretty console output.
- */
-static void vx900_dram_map_pins(u8 ba0, u8 ba1, u8 ba2, u8 ra0, u8 ra1)
-{
- u16 map = 0;
-
- printram("Mapping address pins to DRAM pins:\n");
- printram(" BA0 -> A%u\n", ba0);
- printram(" BA1 -> A%u\n", ba1);
- printram(" BA2 -> A%u\n", ba2);
- printram(" RA0 -> A%u\n", ra0);
- printram(" RA1 -> A%u\n", ra1);
- /* Make sure BA2 is enabled */
- map |= (1 << 11);
-
- /*
- * Find RA1 (15:14)
- * 00: A14
- * 01: A16
- * 10: A18
- * 11: A20
- */
- if ((ra1 & 0x01) || (ra1 < 14) || (ra1 > 20)) {
- printram("Illegal mapping RA1 -> A%u\n", ra1);
- return;
- }
- map |= (((ra1 - 14) >> 1) & 0x03) << 14;
-
- /*
- * Find RA0 (13:12)
- * 00: A15
- * 01: A17
- * 10: A19
- * 11: A21
- */
- if ((!(ra0 & 0x01)) || (ra0 < 15) || (ra0 > 21)) {
- printram("Illegal mapping RA0 -> A%u\n", ra0);
- return;
- }
- map |= (((ra0 - 15) >> 1) & 0x03) << 12;
-
- /*
- * Find BA2 (10:8)
- * x00: A14
- * x01: A15
- * x10: A18
- * x11: A19
- */
- switch (ba2) {
- case 14:
- map |= (0 << 8);
- break;
- case 15:
- map |= (1 << 8);
- break;
- case 18:
- map |= (2 << 8);
- break;
- case 19:
- map |= (3 << 8);
- break;
- default:
- printram("Illegal mapping BA2 -> A%u\n", ba2);
- break;
- }
-
- /*
- * Find BA1 (6:4)
- * 000: A12
- * 001: A14
- * 010: A16
- * 011: A18
- * 1xx: A20
- */
- if (((ba1 & 0x01)) || (ba1 < 12) || (ba1 > 20)) {
- printram("Illegal mapping BA1 -> A%u\n", ba1);
- return;
- }
- map |= (((ba1 - 12) >> 1) & 0x07) << 4;
-
- /*
- * Find BA0 (2:0)
- * 000: A11
- * 001: A13
- * 010: A15
- * 011: A17
- * 1xx: A19
- */
- if ((!(ba0 & 0x01)) || (ba0 < 11) || (ba0 > 19)) {
- printram("Illegal mapping BA0 -> A%u\n", ba0);
- return;
- }
- map |= (((ba0 - 11) >> 1) & 0x07) << 0;
-
- printram("Setting map mask (rx52) to %.4x\n", map);
- vx900_dram_set_ma_pin_map(map);
-}
-
-static void vx900_dram_write_init_config(void)
-{
- /* Keep our RAM space free of legacy stuff */
- vx900_disable_legacy_rom_shadow();
-
- /* Now worry about the real RAM init */
- size_t i;
- for (i = 0; i < (sizeof(mcu_init_config) / sizeof(pci_reg8)); i++) {
- pci_write_config8(MCU, mcu_init_config[i].addr,
- mcu_init_config[i].val);
- }
- vx900_dram_set_ma_pin_map(VX900_CALIB_MA_MAP);
-
- /* FIXME: Slowing stuff down. Does this really help? */
-
- /* Fast cycle control for CPU-to-DRAM Read Cycle 0:Disabled.
- * This CPU bus controller will wait for all data */
-
- /* Memory to CPU bus Controller Conversion Mode 1: Synchronous mode */
-}
-
-static void dram_find_spds_ddr3(const dimm_layout * addr, dimm_info * dimm)
-{
- size_t i = 0;
- int dimms = 0;
- do {
- spd_raw_data spd;
- spd_read(addr->spd_addr[i], spd);
- spd_decode_ddr3(&dimm->dimm[i], spd);
- if (dimm->dimm[i].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
- continue;
- dimms++;
- dram_print_spd_ddr3(&dimm->dimm[i]);
- } while (addr->spd_addr[++i] != SPD_END_LIST
- && i < VX900_MAX_DIMM_SLOTS);
-
- if (!dimms)
- die("No DIMMs were found");
-}
-
-static void dram_find_common_params(const dimm_info * dimms,
- ramctr_timing * ctrl)
-{
- size_t i, valid_dimms;
- memset(ctrl, 0, sizeof(ramctr_timing));
- ctrl->cas_supported = 0xff;
- valid_dimms = 0;
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i++) {
- const dimm_attr *dimm = &dimms->dimm[i];
- if (dimm->dram_type == SPD_MEMORY_TYPE_UNDEFINED)
- continue;
- valid_dimms++;
-
- if (valid_dimms == 1) {
- /* First DIMM defines the type of DIMM */
- ctrl->dram_type = dimm->dram_type;
- ctrl->dimm_type = dimm->dimm_type;
- } else {
- /* Check if we have mismatched DIMMs */
- if (ctrl->dram_type != dimm->dram_type
- || ctrl->dimm_type != dimm->dimm_type)
- die("Mismatched DIMM Types");
- }
- /* Find all possible CAS combinations */
- ctrl->cas_supported &= dimm->cas_supported;
-
- /* Find the smallest common latencies supported by all DIMMs */
- ctrl->tCK = MAX(ctrl->tCK, dimm->tCK);
- ctrl->tAA = MAX(ctrl->tAA, dimm->tAA);
- ctrl->tWR = MAX(ctrl->tWR, dimm->tWR);
- ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
- ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
- ctrl->tRP = MAX(ctrl->tRP, dimm->tRP);
- ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
- ctrl->tRC = MAX(ctrl->tRC, dimm->tRC);
- ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
- ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
- ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
- ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
-
- }
-
- ctrl->n_dimms = valid_dimms;
- if (!ctrl->cas_supported)
- die("Unsupported DIMM combination. "
- "DIMMS do not support common CAS latency");
- if (!valid_dimms)
- die("No valid DIMMs found");
-}
-
-static void vx900_dram_phys_bank_range(const dimm_info * dimms,
- rank_layout * ranks)
-{
- size_t i;
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i++) {
- if (dimms->dimm[i].dram_type == SPD_MEMORY_TYPE_UNDEFINED)
- continue;
- u8 nranks = dimms->dimm[i].ranks;
- /* Make sure we save the flags */
- ranks->flags[i * 2 + 1] = ranks->flags[i * 2] =
- dimms->dimm[i].flags;
- /* Only Rank1 has a mirrored pin mapping */
- ranks->flags[i * 2].pins_mirrored = 0;
- if (nranks > 2)
- die("Found DIMM with more than two ranks, which is not "
- "supported by this chipset");
- u32 size = dimms->dimm[i].size_mb;
- if (nranks == 2) {
- /* Each rank holds half the capacity of the DIMM */
- size >>= 1;
- ranks->phys_rank_size_mb[i << 1] = size;
- ranks->phys_rank_size_mb[(i << 1) | 1] = size;
- } else {
- /* Otherwise, everything is held in the first bank */
- ranks->phys_rank_size_mb[i << 1] = size;
- ranks->phys_rank_size_mb[(i << 1) | 1] = 0;
- }
- }
-}
-
-#define ODT_R0 0
-#define ODT_R1 1
-#define ODT_R2 2
-#define ODT_R3 3
-/*
- * This is the table that tells us which MODT pin to map to which rank.
- *
- * This table is taken from code provided by VIA, but no explanation was
- * provided as to why it is done this way. It may be possible that this table is
- * not suitable for the way we map ranks later on.
- */
-static const u8 odt_lookup_table[][2] = {
- /* RankMAP Rank 3 Rank 2 Rank 1 Rank 0 */
- {0x01, (ODT_R3 << 6) | (ODT_R2 << 4) | (ODT_R1 << 2) | (ODT_R0 << 0)},
- {0x03, (ODT_R3 << 6) | (ODT_R2 << 4) | (ODT_R0 << 2) | (ODT_R1 << 0)},
- {0x04, (ODT_R3 << 6) | (ODT_R2 << 4) | (ODT_R1 << 2) | (ODT_R0 << 0)},
- {0x05, (ODT_R3 << 6) | (ODT_R0 << 4) | (ODT_R1 << 2) | (ODT_R2 << 0)},
- {0x07, (ODT_R3 << 6) | (ODT_R0 << 4) | (ODT_R2 << 2) | (ODT_R2 << 0)},
- {0x0c, (ODT_R2 << 6) | (ODT_R3 << 4) | (ODT_R1 << 2) | (ODT_R0 << 0)},
- {0x0d, (ODT_R0 << 6) | (ODT_R0 << 4) | (ODT_R1 << 2) | (ODT_R2 << 0)},
- {0x0f, (ODT_R0 << 6) | (ODT_R0 << 4) | (ODT_R2 << 2) | (ODT_R2 << 0)},
- {0, 0},
-};
-
-static void vx900_dram_driving_ctrl(const dimm_info * dimm)
-{
- size_t i, ndimms;
- u8 reg8, regxd5, rank_mask;
-
- rank_mask = 0;
- /* For ODT range selection, datasheet recommends
- * when 1 DIMM present: 60 Ohm
- * when 2 DIMMs present: 120 Ohm */
- ndimms = 0;
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i++) {
- if (dimm->dimm[i].dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
- continue;
- ndimms++;
- rank_mask |= (1 << (i * 2));
- if (dimm->dimm[i].ranks > 1)
- rank_mask |= (2 << (i * 2));
- }
- /* ODT strength and MD/MDQM/MDQS driving strength */
- if (ndimms > 1) {
- /* Enable 1 ODT block (120 Ohm ODT) */
- regxd5 = 0 << 2;
- /* Enable strong driving for MD/MDQM/MDQS */
- regxd5 |= (1 << 7);
- } else {
- /* Enable 2 ODT blocks (60 Ohm ODT) */
- regxd5 = 1 << 2;
- /* Leave MD/MDQM/MDQS driving weak */
- }
- pci_write_config8(MCU, 0xd5, regxd5);
-
- /* Enable strong CLK driving for DIMMs with more than one rank */
- if (dimm->dimm[0].ranks > 1)
- pci_or_config8(MCU, 0xd6, (1 << 7));
- if (dimm->dimm[1].ranks > 1)
- pci_or_config8(MCU, 0xd6, (1 << 6));
-
- /* DRAM ODT Lookup Table */
- for (i = 0;; i++) {
- if (odt_lookup_table[i][0] == 0) {
- printram("No ODT entry for rank mask %x\n", rank_mask);
- die("Aborting");
- }
- if (odt_lookup_table[i][0] != rank_mask)
- continue;
-
- reg8 = odt_lookup_table[i][1];
- break;
- }
-
- printram("Mapping rank mask %x to ODT entry %.2x\n", rank_mask, reg8);
- pci_write_config8(MCU, 0x9c, reg8);
-
- for (i = 0; i < (sizeof(mcu_drv_ctrl_config) / sizeof(pci_reg8)); i++) {
- pci_write_config8(MCU, mcu_drv_ctrl_config[i].addr,
- mcu_drv_ctrl_config[i].val);
- }
-}
-
-static void vx900_pr_map_all_vr3(void)
-{
- /* Enable all ranks and set them to VR3 */
- pci_write_config16(MCU, 0x54, 0xbbbb);
-}
-
-/* Map physical rank pr to virtual rank vr */
-static void vx900_map_pr_vr(u8 pr, u8 vr)
-{
- u16 val;
-
- pr &= 0x3;
- vr &= 0x3;
- /* Enable rank (bit [3], and set the VR number bits [1:0] */
- val = 0x8 | vr;
- /* Now move the value to the appropriate PR */
- val <<= (pr * 4);
- pci_update_config16(MCU, 0x54, ~(0xf << (pr * 4)), val);
- printram("Mapping PR %u to VR %u\n", pr, vr);
-}
-
-static u8 vx900_get_CWL(u8 CAS)
-{
- /* Get CWL based on CAS using the following rule:
- * _________________________________________
- * CAS: | 4T | 5T | 6T | 7T | 8T | 9T | 10T | 11T |
- * CWL: | 5T | 5T | 5T | 6T | 6T | 7T | 7T | 8T |
- */
- static const u8 cas_cwl_map[] = { 5, 5, 5, 6, 6, 7, 7, 8 };
- if (CAS > 11)
- return 8;
- return cas_cwl_map[CAS - 4];
-}
-
-/*
- * Here we are calculating latencies, and writing them to the appropriate
- * registers. Note that some registers do not take latencies from 0 = 0T,
- * 1 = 1T, so each register gets its own math formula.
- */
-static void vx900_dram_timing(ramctr_timing * ctrl)
-{
- u8 reg8, val, tFAW, tRRD;
-
- /* Maximum supported DDR3 frequency is 533MHz (DDR3 1066) so make sure
- * we cap it if we have faster DIMMs.
- * Then, align it to the closest JEDEC standard frequency */
- if (ctrl->tCK <= TCK_533MHZ) {
- ctrl->tCK = TCK_533MHZ;
- } else if (ctrl->tCK <= TCK_400MHZ) {
- ctrl->tCK = TCK_400MHZ;
- } else if (ctrl->tCK <= TCK_333MHZ) {
- ctrl->tCK = TCK_333MHZ;
- } else {
- ctrl->tCK = TCK_266MHZ;
- }
-
- printram("Selected DRAM frequency: %u MHz\n", (1000 << 8) / ctrl->tCK);
-
- /* Find CAS and CWL latencies */
- val = DIV_ROUND_UP(ctrl->tAA, ctrl->tCK);
- printram("Minimum CAS latency : %uT\n", val);
- /* Find lowest supported CAS latency that satisfies the minimum value */
- while (!((ctrl->cas_supported >> (val - 4)) & 1)
- && (ctrl->cas_supported >> (val - 4))) {
- val++;
- }
- /* Is CAS supported */
- if (!(ctrl->cas_supported & (1 << (val - 4))))
- printram("CAS not supported\n");
- printram("Selected CAS latency : %uT\n", val);
- ctrl->CAS = val;
- ctrl->CWL = vx900_get_CWL(ctrl->CAS);
- printram("Selected CWL latency : %uT\n", ctrl->CWL);
- /* Write CAS and CWL */
- reg8 = (((ctrl->CWL - 4) & 0x07) << 4) | ((ctrl->CAS - 4) & 0x07);
- pci_write_config8(MCU, 0xc0, reg8);
-
- /* Find tRCD */
- val = DIV_ROUND_UP(ctrl->tRCD, ctrl->tCK);
- printram("Selected tRCD : %uT\n", val);
- reg8 = ((val - 4) & 0x7) << 4;
- /* Find tRP */
- val = DIV_ROUND_UP(ctrl->tRP, ctrl->tCK);
- printram("Selected tRP : %uT\n", val);
- reg8 |= ((val - 4) & 0x7);
- pci_write_config8(MCU, 0xc1, reg8);
-
- /* Find tRAS */
- val = DIV_ROUND_UP(ctrl->tRAS, ctrl->tCK);
- printram("Selected tRAS : %uT\n", val);
- reg8 = ((val - 15) & 0x7) << 4;
- /* Find tWR */
- ctrl->WR = DIV_ROUND_UP(ctrl->tWR, ctrl->tCK);
- printram("Selected tWR : %uT\n", ctrl->WR);
- reg8 |= ((ctrl->WR - 4) & 0x7);
- pci_write_config8(MCU, 0xc2, reg8);
-
- /* Find tFAW */
- tFAW = DIV_ROUND_UP(ctrl->tFAW, ctrl->tCK);
- printram("Selected tFAW : %uT\n", tFAW);
- /* Find tRRD */
- tRRD = DIV_ROUND_UP(ctrl->tRRD, ctrl->tCK);
- printram("Selected tRRD : %uT\n", tRRD);
- val = tFAW - 4 * tRRD; /* number of cycles above 4*tRRD */
- reg8 = ((val - 0) & 0x7) << 4;
- reg8 |= ((tRRD - 2) & 0x7);
- pci_write_config8(MCU, 0xc3, reg8);
-
- /* Find tRTP */
- val = DIV_ROUND_UP(ctrl->tRTP, ctrl->tCK);
- printram("Selected tRTP : %uT\n", val);
- reg8 = ((val & 0x3) << 4);
- /* Find tWTR */
- val = DIV_ROUND_UP(ctrl->tWTR, ctrl->tCK);
- printram("Selected tWTR : %uT\n", val);
- reg8 |= ((val - 2) & 0x7);
- pci_update_config8(MCU, 0xc4, ~0x3f, reg8);
-
- /* DRAM Timing for All Ranks - VI
- * [7:6] CKE Assertion Minimum Pulse Width
- * We probably don't want to mess with this just yet.
- * [5:0] Refresh-to-Active or Refresh-to-Refresh (tRFC)
- * tRFC = (30 + 2 * [5:0])T
- * Since we previously set RxC4[7]
- */
- reg8 = pci_read_config8(MCU, 0xc5);
- val = DIV_ROUND_UP(ctrl->tRFC, ctrl->tCK);
- printram("Minimum tRFC : %uT\n", val);
- if (val < 30) {
- val = 0;
- } else {
- val = (val - 30 + 1) / 2;
- }
- ;
- printram("Selected tRFC : %uT\n", 30 + 2 * val);
- reg8 |= (val & 0x3f);
- pci_write_config8(MCU, 0xc5, reg8);
-
- /* Where does this go??? */
- val = DIV_ROUND_UP(ctrl->tRC, ctrl->tCK);
- printram("Required tRC : %uT\n", val);
-}
-
-/* Program the DRAM frequency */
-static void vx900_dram_freq(ramctr_timing * ctrl)
-{
- u8 val;
-
- /* Step 1 - Reset the PLL */
- pci_or_config8(MCU, 0x90, 0x0f);
- /* Wait at least 10 ns; VIA code delays by 640us */
- udelay(640);
-
- /* Step 2 - Set target frequency */
- if (ctrl->tCK <= TCK_533MHZ) {
- val = 0x07;
- ctrl->tCK = TCK_533MHZ;
- } else if (ctrl->tCK <= TCK_400MHZ) {
- val = 0x06;
- ctrl->tCK = TCK_400MHZ;
- } else if (ctrl->tCK <= TCK_333MHZ) {
- val = 0x05;
- ctrl->tCK = TCK_333MHZ;
- } else { /*ctrl->tCK <= TCK_266MHZ */
- val = 0x04;
- ctrl->tCK = TCK_266MHZ;
- }
- /* Restart the PLL with the desired frequency */
- pci_update_config8(MCU, 0x90, ~0x0f, val);
-
- /* Step 3 - Wait for PLL to stabilize */
- udelay(2000);
-
- /* Step 4 - Reset the DLL - Clear [7,4] */
- pci_update_config8(MCU, 0x6b, (u8)~0x90, 0x00);
- udelay(2000);
-
- /* Step 5 - Enable the DLL - Set bits [7,4] to 01b */
- pci_or_config8(MCU, 0x6b, 0x10);
- udelay(2000);
-
- /* Step 6 - Start DLL Calibration - Set bit [7] */
- pci_or_config8(MCU, 0x6b, 0x80);
- udelay(5);
-
- /* Step 7 - Finish DLL Calibration - Clear bit [7] */
- pci_update_config8(MCU, 0x6b, (u8)~0x80, 0x00);
-
- /* Step 8 - If we have registered DIMMs, we need to set bit[0] */
- if (spd_dimm_is_registered_ddr3(ctrl->dimm_type)) {
- printram("Enabling RDIMM support in memory controller\n");
- pci_or_config8(MCU, 0x6c, 0x01);
- }
-}
-
-/*
- * The VX900 can send the MRS commands directly through hardware
- * It does the MR2->MR3->MR1->MR0->LongZQ JEDEC dance
- * The parameters that we don't worry about are extracted from the timing
- * registers we have programmed earlier.
- */
-static void vx900_dram_ddr3_do_hw_mrs(u8 ma_swap, u8 rtt_nom,
- u8 ods, u8 rtt_wr, u8 srt, u8 asr)
-{
- u16 reg16 = 0;
-
- printram("Using Hardware method for DRAM MRS commands.\n");
-
- reg16 |= ((rtt_wr & 0x03) << 12);
- if (srt)
- reg16 |= (1 << 9);
- if (asr)
- reg16 |= (1 << 8);
- reg16 |= ((rtt_nom & 0x7) << 4);
- reg16 |= ((ods & 0x03) << 2);
- if (ma_swap)
- reg16 |= (1 << 1);
- reg16 |= (1 << 14);
- reg16 |= (1 << 0); /* This is the trigger bit */
- printram("Hw MRS set is 0x%4x\n", reg16);
- pci_write_config16(MCU, 0xcc, reg16);
- /* Wait for MRS commands to be sent */
- while (pci_read_config8(MCU, 0xcc) & 1);
-}
-
-/*
- * Translate the MRS command into an address on the CPU bus
- *
- * Take an MRS command (mrs_cmd_t) and translate it to a read address on the CPU
- * bus. Thus, reading from the returned address, will issue the correct MRS
- * command, assuming we are in MRS mode, of course.
- *
- * A read from the returned address will produce the correct MRS command
- * provided the following conditions are met:
- * - The MA pin mapping is set to VX900_MRS_MA_MAP
- * - The memory controller's Fun3_RX6B[2:0] is set to 011b (MSR Enable)
- */
-static u32 vx900_get_mrs_addr(mrs_cmd_t cmd)
-{
- u32 addr = 0;
- u8 mrs_type = (cmd >> 16) & 0x07;
- /* MA[9:0] <-> A[12:3] */
- addr |= ((cmd & 0x3ff) << 3);
- /* MA10 <-> A20 */
- addr |= (((cmd >> 10) & 0x1) << 20);
- /* MA[12:11] <-> A[14:13] */
- addr |= (((cmd >> 11) & 0x3) << 13);
- /* BA[2:0] <-> A[19:17] */
- addr |= mrs_type << 17;
- return addr;
-}
-
-/*
- * Here, we do the MR2->MR3->MR1->MR0->LongZQ JEDEC dance manually
- *
- * Why would we do this in software, when the VX900 can do it in hardware? The
- * problem is the hardware sequence seems to be buggy on ranks with mirrored
- * pins. Is this a hardware bug or a misconfigured MCU? No idea.
- *
- * To maintain API compatibility with the function that implements the hardware
- * sequence, we don't ask for all parameters. To keep an overall cleaner code
- * structure, we don't try to pass down all that information. Instead, we
- * extract the extra parameters from the timing registers we have programmed
- * earlier.
- */
-static void vx900_dram_ddr3_do_sw_mrs(u8 ma_swap, enum ddr3_mr1_rtt_nom rtt_nom,
- enum ddr3_mr1_ods ods,
- enum ddr3_mr2_rttwr rtt_wr,
- enum ddr3_mr2_srt_range srt,
- enum ddr3_mr2_asr asr)
-{
- mrs_cmd_t mrs;
- u8 reg8, cas, cwl, twr;
-
- printram("Using Software method for DRAM MRS commands.\n");
-
- /* Get CAS, CWL, and tWR that we programmed earlier */
- reg8 = pci_read_config8(MCU, 0xc0);
- cas = (reg8 & 0x07) + 4;
- cwl = ((reg8 >> 4) & 0x07) + 4;
- reg8 = pci_read_config8(MCU, 0xc2);
- twr = (reg8 & 0x07) + 4;
-
- /* Step 06 - Set Fun3_RX6B[2:0] to 001b (NOP Command Enable). */
- /* Was already done for us before calling us */
-
- /* Step 07 - Read a double word from any address of the DIMM. */
- /* Was already done for us before calling us */
-
- /* Step 08 - Set Fun3_RX6B[2:0] to 011b (MSR Enable). */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x03); /* MSR Enable */
-
- /* Step 09 - Issue MR2 cycle. Read a double word from the address
- * depended on DRAM's Rtt_WR and CWL settings. */
- mrs = ddr3_get_mr2(rtt_wr, srt, asr, cwl);
- if (ma_swap)
- mrs = ddr3_mrs_mirror_pins(mrs);
- volatile_read(vx900_get_mrs_addr(mrs));
- printram("MR2: %.5x\n", mrs);
- udelay(1000);
-
- /* Step 10 - Issue MR3 cycle. Read a double word from the address 60000h
- * to set DRAM to normal operation mode. */
- mrs = ddr3_get_mr3(0);
- if (ma_swap)
- mrs = ddr3_mrs_mirror_pins(mrs);
- volatile_read(vx900_get_mrs_addr(mrs));
- printram("MR3: %.5x\n", mrs);
- udelay(1000);
-
- /* Step 11 -Issue MR1 cycle. Read a double word from the address
- * depended on DRAM's output driver impedance and Rtt_Nom settings.
- * The DLL enable field, TDQS field, write leveling enable field,
- * additive latency field and Qoff field should be set to 0. */
- mrs = ddr3_get_mr1(DDR3_MR1_QOFF_ENABLE, DDR3_MR1_TQDS_DISABLE, rtt_nom,
- DDR3_MR1_WRLVL_DISABLE, ods, DDR3_MR1_AL_DISABLE,
- DDR3_MR1_DLL_ENABLE);
- if (ma_swap)
- mrs = ddr3_mrs_mirror_pins(mrs);
- volatile_read(vx900_get_mrs_addr(mrs));
- printram("MR1: %.5x\n", mrs);
- udelay(1000);
-
- /* Step 12 - Issue MR0 cycle. Read a double word from the address
- * depended on DRAM's burst length, CAS latency and write recovery time
- * settings.
- * The read burst type field should be set to interleave.
- * The mode field should be set to normal mode.
- * The DLL reset field should be set to No.
- * The DLL control for precharge PD field should be set to Fast exit.
- */
- mrs = ddr3_get_mr0(DDR3_MR0_PRECHARGE_FAST, twr,
- DDR3_MR0_DLL_RESET_NO, DDR3_MR0_MODE_NORMAL, cas,
- DDR3_MR0_BURST_TYPE_INTERLEAVED,
- DDR3_MR0_BURST_LENGTH_CHOP);
- volatile_read(vx900_get_mrs_addr(mrs));
- printram("MR0: %.5x\n", mrs);
- udelay(1000);
-
- /* Step 13 - Set Fun3_RX6B[2:0] to 110b (Long ZQ calibration cmd) */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x06); /* Long ZQ */
- /* Step 14 - Read a double word from any address of the DIMM. */
- volatile_read(0);
- udelay(1000);
-}
-
-/*
- * This is where we take the DIMMs out of reset and do the JEDEC dance for each
- * individual physical rank.
- */
-static void vx900_dram_ddr3_dimm_init(const ramctr_timing * ctrl,
- const rank_layout * ranks)
-{
- size_t i;
- u8 rtt_nom, rtt_wr, ods, pinswap;
-
- /* Set BA[0/1/2] to [A17/18/19] */
- vx900_dram_set_ma_pin_map(VX900_MRS_MA_MAP);
-
- /* Step 01 - Set Fun3_Rx6E[5] to 1b to support burst length. */
- pci_or_config8(MCU, 0x6e, 1 << 5);
- /* Step 02 - Set Fun3_RX69[0] to 0b (Disable Multiple Page Mode). */
- pci_update_config8(MCU, 0x69, ~(1 << 0), 0x00);
- /* And set [7:6] to 10b ? */
- pci_write_config8(MCU, 0x69, 0x87);
-
- /* Step 03 - Set the target physical rank to virtual rank0 and other
- * ranks to virtual rank3. */
- vx900_pr_map_all_vr3();
-
- /* Step 04 - Set Fun3_Rx50 to D8h. */
- pci_write_config8(MCU, 0x50, 0xd8);
- /* Step 05 - Set Fun3_RX6B[5] to 1b to de-assert RESET# and wait for at
- * least 500 us. */
- pci_or_config8(MCU, 0x6b, (1 << 5));
- udelay(500);
-
- /* Step 6 -> 15 - Set the target physical rank to virtual rank 0 and
- * other ranks to virtual rank 3.
- * Repeat Step 6 to 14 for every rank present, then jump to Step 16. */
- for (i = 0; i < VX900_MAX_MEM_RANKS; i++) {
- if (ranks->phys_rank_size_mb[i] == 0)
- continue;
- printram("Initializing rank %zu\n", i);
-
- /* Set target physical rank to virtual rank 0
- * other ranks to virtual rank 3*/
- vx900_map_pr_vr(i, 0);
-
- /* FIXME: Is this needed on HW init? */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x01); /* Enable NOP */
- volatile_read(0x0); /* Do NOP */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x03); /* MSR Enable */
-
- /* See init_dram_by_rank.c and get_basic_information.c
- * in the VIA provided code */
- if (ctrl->n_dimms == 1) {
- rtt_nom = DDR3_MR1_RTT_NOM_RZQ2;
- rtt_wr = DDR3_MR2_RTTWR_OFF;
- } else {
- rtt_nom = DDR3_MR1_RTT_NOM_RZQ8;
- rtt_wr = DDR3_MR2_RTTWR_RZQ2;
- }
- ods = ranks->flags[i].rzq7_supported ?
- DDR3_MR1_ODS_RZQ7 : DDR3_MR1_ODS_RZQ6;
-
- pinswap = (ranks->flags[i].pins_mirrored);
- if (pinswap)
- printram("Pins mirrored\n");
- printram(" Swap : %x\n", pinswap);
- printram(" rtt_nom : %x\n", rtt_nom);
- printram(" ods : %x\n", ods);
- printram(" rtt_wr : %x\n", rtt_wr);
- if (RAMINIT_USE_HW_MRS_SEQ)
- vx900_dram_ddr3_do_hw_mrs(pinswap, rtt_nom, ods, rtt_wr,
- 0, 0);
- else
- vx900_dram_ddr3_do_sw_mrs(pinswap, rtt_nom, ods, rtt_wr,
- 0, 0);
-
- /* Normal SDRAM Mode */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x00);
-
- /* Step 15, set the rank to virtual rank 3 */
- vx900_map_pr_vr(i, 3);
- }
-
- /* Step 16 - Set Fun3_Rx6B[2:0] to 000b (Normal SDRAM Mode). */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x00);
-
- /* Set BA[0/1/2] to [A13/14/15] */
- vx900_dram_set_ma_pin_map(VX900_CALIB_MA_MAP);
-
- /* Step 17 - Set Fun3_Rx69[0] to 1b (Enable Multiple Page Mode). */
- pci_or_config8(MCU, 0x69, (1 << 0));
-
- printram("DIMM initialization sequence complete\n");
-}
-
-/*
- * This a small utility to send a single MRS command, but where we don't want to
- * have to worry about changing the MCU mode. It gives the MCU back to us in
- * normal operating mode.
- */
-static void vx900_dram_send_soft_mrs(mrs_cmd_t cmd, u8 pin_swap)
-{
- u32 addr;
- /* Set Fun3_RX6B[2:0] to 011b (MSR Enable). */
- pci_update_config8(MCU, 0x6b, ~0x07, (3 << 0));
- /* Is this a funky rank with Address pins swapped? */
- if (pin_swap)
- cmd = ddr3_mrs_mirror_pins(cmd);
- /* Find the address corresponding to the MRS */
- addr = vx900_get_mrs_addr(cmd);
- /* Execute the MRS */
- volatile_read(addr);
- /* Set Fun3_Rx6B[2:0] to 000b (Normal SDRAM Mode). */
- pci_update_config8(MCU, 0x6b, ~0x07, 0x00);
-}
-
-static void vx900_dram_enter_read_leveling(u8 pinswap)
-{
- /* Precharge all before issuing read leveling MRS to DRAM */
- pci_update_config8(MCU, 0x06b, ~0x07, 0x02);
- volatile_read(0x0);
- udelay(1000);
-
- /* Enable read leveling: Set D0F3Rx71[7]=1 */
- pci_or_config8(MCU, 0x71, (1 << 7));
-
- /* Put DRAM in read leveling mode */
- mrs_cmd_t cmd = ddr3_get_mr3(1);
- vx900_dram_send_soft_mrs(cmd, pinswap);
-}
-
-static void vx900_dram_exit_read_leveling(u8 pinswap)
-{
- /* Disable read leveling, and put dram in normal operation mode */
- mrs_cmd_t cmd = ddr3_get_mr3(0);
- vx900_dram_send_soft_mrs(cmd, pinswap);
-
- /* Disable read leveling: Set D0F3Rx71[7]=0 */
- pci_update_config8(MCU, 0x71, (u8)~(1 << 7), 0);
-}
-
-/*
- * We need to see if the delay window (difference between minimum and maximum)
- * is large enough so that we actually have a valid window. The signal should be
- * valid for at least 1/2T in general. If the window is significantly smaller,
- * then chances are our window does not latch at the correct time, and the
- * calibration will not work.
- */
-#define DQSI_THRESHOLD 0x10
-#define DQO_THRESHOLD 0x09
-#define DQSO_THRESHOLD 0x12
-#define DELAY_RANGE_GOOD 0
-#define DELAY_RANGE_BAD -1
-static u8 vx900_dram_check_calib_range(const delay_range * dly, u8 window)
-{
- size_t i;
- for (i = 0; i < 8; i++) {
- if (dly->high[i] - dly->low[i] < window)
- return DELAY_RANGE_BAD;
- /* When our maximum value is lower than our min, both values
- * have overshot, and the window is definitely invalid */
- if (dly->high[i] < dly->low[i])
- return DELAY_RANGE_BAD;
- }
- return DELAY_RANGE_GOOD;
-}
-
-static void vx900_dram_find_avg_delays(vx900_delay_calib * delays)
-{
- size_t i;
- u16 dq_low, dq_high, dqs_low, dqs_high, dq_final, dqs_final;
- /*
- * At this point, we have transmit delays for both DIMMA and DIMMB, each
- * with a slightly different window We want to find the intersection of
- * those windows, so that we have a constrained window which both
- * DIMMA and DIMMB can use. The center of our constrained window will
- * also be the safest setting for the transmit delays
- *
- * DIMMA window t:|xxxxxxxxxxxxxx---------------xxxxxxxxxxxxxxxxxxxxxxx|
- * DIMMB window t:|xxxxxxxxxxxxxxxxxxx---------------xxxxxxxxxxxxxxxxxx|
- * Safe window t:|xxxxxxxxxxxxxxxxxxx----------xxxxxxxxxxxxxxxxxxxxxxx|
- */
- delay_range *tx_dq_a = &(delays->tx_dq[0]);
- delay_range *tx_dq_b = &(delays->tx_dq[1]);
- delay_range *tx_dqs_a = &(delays->tx_dqs[0]);
- delay_range *tx_dqs_b = &(delays->tx_dqs[1]);
-
- for (i = 0; i < 8; i++) {
- dq_low = MAX(tx_dq_a->low[i], tx_dq_b->low[i]);
- dq_high = MIN(tx_dq_a->high[i], tx_dq_b->high[i]);
- dqs_low = MAX(tx_dqs_a->low[i], tx_dqs_b->low[i]);
- dqs_high = MIN(tx_dqs_a->high[i], tx_dqs_b->high[i]);
-
- /* Find the average */
- dq_final = ((dq_low + dq_high) / 2);
- dqs_final = ((dqs_low + dqs_high) / 2);
-
- /*
- * These adjustments are done in code provided by VIA.
- * There is no explanation as to why this is done.
- *
- * We can get away without doing the DQS adjustment, but doing
- * it, brings the values closer to what the vendor BIOS
- * calibrates to.
- */
- if ((dqs_final & 0x1f) >= 0x1c)
- dqs_final -= 0x1c;
- else
- dqs_final += 0x04;
- /*
- * The DQ adjustment is more critical. If we don't do this
- * adjustment our MCU won't be configured properly, and
- * ram_check() will fail.
- */
- if ((dq_final & 0x1f) >= 0x14)
- dq_final -= 0x14;
- else
- dq_final += 0x0c;
-
- /* Store our values in the first delay */
- delays->tx_dq[0].avg[i] = dq_final;
- delays->tx_dqs[0].avg[i] = dqs_final;
-
- }
-}
-
-/*
- * First calibration: When to receive data from the DRAM
- * (MD and MDQS input delay)
- *
- * This calibration unfortunately does not seem to work. Whether this is due to
- * a misconfigured MCU or hardware bug is unknown.
- */
-static void vx900_rx_capture_range_calib(u8 pinswap)
-{
- u8 reg8;
- const u32 cal_addr = 0x20;
-
- /* Set IO calibration address */
- pci_update_config16(MCU, 0x8c, (u16)~0xfff0, cal_addr & (0xfff0));
- /* Data pattern must be 0x00 for this calibration
- * See paragraph describing Rx8e */
- pci_write_config8(MCU, 0x8e, 0x00);
-
- /* Need to put DRAM and MCU in read leveling */
- vx900_dram_enter_read_leveling(pinswap);
-
- /* Data pattern must be 0x00 for this calibration
- * See paragraph describing Rx8e */
- pci_write_config8(MCU, 0x8e, 0x00);
- /* Trigger calibration */
- reg8 = 0xa0;
- pci_write_config8(MCU, 0x71, reg8);
-
- /* Wait for it */
- while (pci_read_config8(MCU, 0x71) & 0x10);
- vx900_dram_exit_read_leveling(pinswap);
-}
-
-/*
- * Second calibration: How much to delay DQS signal by
- * (MDQS input delay)
- */
-static void vx900_rx_dqs_delay_calib(u8 pinswap)
-{
- const u32 cal_addr = 0x30;
-
- /* We need to disable refresh commands so that they don't interfere */
- const u8 ref_cnt = pci_read_config8(MCU, 0xc7);
- pci_write_config8(MCU, 0xc7, 0);
- /* Set IO calibration address */
- pci_update_config16(MCU, 0x8c, (u16)~0xfff0, cal_addr & (0xfff0));
- /* Data pattern must be 0x00 for this calibration
- * See paragraph describing Rx8e */
- pci_write_config8(MCU, 0x8e, 0x00);
-
- /* Need to put DRAM and MCU in read leveling */
- vx900_dram_enter_read_leveling(pinswap);
-
- /* From VIA code; Undocumented
- * In theory this enables MODT[3:0] to be asserted */
- pci_or_config8(MCU, 0x9e, 0x80);
-
- /* Trigger calibration: Set D0F3Rx71[1:0]=10b */
- pci_update_config8(MCU, 0x71, ~0x03, 0x02);
-
- /* Wait for calibration to complete */
- while (pci_read_config8(MCU, 0x71) & 0x02);
- vx900_dram_exit_read_leveling(pinswap);
-
- /* Restore the refresh counter */
- pci_write_config8(MCU, 0xc7, ref_cnt);
-
- /* FIXME: should we save it before, or should we just set it as is */
- vx900_dram_set_ma_pin_map(VX900_CALIB_MA_MAP);
-}
-
-static void vx900_tx_dqs_trigger_calib(u8 pattern)
-{
- /* Data pattern for calibration */
- pci_write_config8(MCU, 0x8e, pattern);
- /* Trigger calibration */
- pci_or_config8(MCU, 0x75, 0x20);
- /* Wait for calibration */
- while (pci_read_config8(MCU, 0x75) & 0x20);
-}
-
-/*
- * Third calibration: How much to wait before asserting DQS
- */
-static void vx900_tx_dqs_delay_calib(void)
-{
- const u32 cal_addr = 0x00;
- /* Set IO calibration address */
- pci_update_config16(MCU, 0x8c, (u16)~0xfff0, cal_addr & (0xfff0));
- /* Set circuit to use calibration results - Clear Rx75[0] */
- pci_update_config8(MCU, 0x75, ~0x01, 0);
- /* Run calibration with first data pattern */
- vx900_tx_dqs_trigger_calib(0x5a);
- /* Run again with different pattern */
- vx900_tx_dqs_trigger_calib(0xa5);
-}
-
-/*
- * Fourt calibration: How much to wait before putting data on DQ lines
- */
-static void vx900_tx_dq_delay_calib(void)
-{
- /* Data pattern for calibration */
- pci_write_config8(MCU, 0x8e, 0x5a);
- /* Trigger calibration */
- pci_or_config8(MCU, 0x75, 0x02);
- /* Wait for calibration */
- while (pci_read_config8(MCU, 0x75) & 0x02);
-}
-
-static void vx900_rxdqs_adjust(delay_range * dly)
-{
- /* Adjust Rx DQS delay after calibration has been run. This is
- * recommended by VIA, but no explanation was provided as to why */
- size_t i;
- for (i = 0; i < 8; i++) {
- if (dly->low[i] < 3) {
- if (i == 2 || i == 4)
- dly->avg[i] += 4;
- else
- dly->avg[i] += 3;
-
- }
-
- if (dly->high[i] > 0x38)
- dly->avg[i] -= 6;
- else if (dly->high[i] > 0x30)
- dly->avg[i] -= 4;
-
- if (dly->avg[i] > 0x20)
- dly->avg[i] = 0x20;
- }
-
- /* Put Rx DQS delay into manual mode (Set Rx[2,0] to 01) */
- pci_update_config8(MCU, 0x71, ~0x05, 0x01);
- /* Now write the new settings */
- vx900_delay_calib_mode_select(CALIB_RxDQS, CALIB_MANUAL);
- vx900_write_0x78_0x7f(dly->avg);
-}
-
-static void vx900_dram_calibrate_receive_delays(vx900_delay_calib * delays,
- u8 pinswap)
-{
- size_t n_tries = 0;
- delay_range *rx_dq_cr = &(delays->rx_dq_cr);
- delay_range *rx_dqs = &(delays->rx_dqs);
- /* We really should be able to finish this in a single pass, but it may
- * in very rare circumstances not work the first time. We define a limit
- * on the number of tries so that we have a way of warning the user */
- const size_t max_tries = 100;
- for (;;) {
- if (n_tries++ >= max_tries) {
- die("Could not calibrate receive delays. Giving up");
- }
- u8 result;
- /* Run calibrations */
- if (RAMINIT_USE_HW_RXCR_CALIB) {
- vx900_rx_capture_range_calib(pinswap);
- vx900_read_delay_range(rx_dq_cr, CALIB_RxDQ_CR);
- dump_delay_range(*rx_dq_cr);
-
- } else {
- /*FIXME: Cheating with Rx CR setting\
- * We need to either use Rx CR calibration
- * or set up a table for the calibration */
- u8 *override = &(rx_dq_cr->avg[0]);
- override[0] = 0x28;
- override[1] = 0x1c;
- override[2] = 0x28;
- override[3] = 0x28;
- override[4] = 0x2c;
- override[5] = 0x30;
- override[6] = 0x30;
- override[7] = 0x34;
- printram("Bypassing RxCR 78-7f calibration with:\n");
- dump_delay(rx_dq_cr->avg);
- }
- /* We need to put the setting on manual mode */
- pci_or_config8(MCU, 0x71, 1 << 4);
- vx900_delay_calib_mode_select(CALIB_RxDQ_CR, CALIB_MANUAL);
- vx900_write_0x78_0x7f(rx_dq_cr->avg);
-
- /************* RxDQS *************/
- vx900_rx_dqs_delay_calib(pinswap);
- vx900_read_delay_range(rx_dqs, CALIB_RxDQS);
- vx900_rxdqs_adjust(rx_dqs);
-
- result = vx900_dram_check_calib_range(rx_dqs, DQSI_THRESHOLD);
- if (result != DELAY_RANGE_GOOD)
- continue;
-
- /* We're good to go. Switch to manual and write the manual
- * setting */
- pci_or_config8(MCU, 0x71, 1 << 0);
- vx900_delay_calib_mode_select(CALIB_RxDQS, CALIB_MANUAL);
- vx900_write_0x78_0x7f(rx_dqs->avg);
- break;
- }
- if (n_tries > 1)
- printram("Hmm, we had to try %zu times before our calibration "
- "was good.\n", n_tries);
-}
-
-static void vx900_dram_calibrate_transmit_delays(delay_range * tx_dq,
- delay_range * tx_dqs)
-{
- /* Same timeout reasoning as in receive delays */
- size_t n_tries = 0;
- int dq_tries = 0, dqs_tries = 0;
- const size_t max_tries = 100;
- for (;;) {
- if (n_tries++ >= max_tries) {
- printram("Tried DQS %i times and DQ %i times\n",
- dqs_tries, dq_tries);
- printram("Tx DQS calibration results\n");
- dump_delay_range(*tx_dqs);
- printram("TX DQ delay calibration results:\n");
- dump_delay_range(*tx_dq);
- die("Could not calibrate transmit delays. Giving up");
- }
- u8 result;
- /************* TxDQS *************/
- dqs_tries++;
- vx900_tx_dqs_delay_calib();
- vx900_read_delay_range(tx_dqs, CALIB_TxDQS);
-
- result = vx900_dram_check_calib_range(tx_dqs, DQSO_THRESHOLD);
- if (result != DELAY_RANGE_GOOD)
- continue;
-
- /************* TxDQ *************/
- /* FIXME: not sure if multiple page mode should be enabled here
- * Vendor BIOS does it */
- pci_or_config8(MCU, 0x69, 0x01);
-
- dq_tries++;
- vx900_tx_dq_delay_calib();
- vx900_read_delay_range(tx_dq, CALIB_TxDQ);
-
- result = vx900_dram_check_calib_range(tx_dq, DQO_THRESHOLD);
- if (result != DELAY_RANGE_GOOD)
- continue;
-
- /* At this point, our RAM should give correct read-backs for
- * addresses under 64 MB. If it doesn't, it won't work */
- if (ram_check_noprint_nodie(1 << 20, 1 << 20)) {
- /* No, our RAM is not working, try again */
- /* FIXME: Except that we have not yet told the MCU what
- * the geometry of the DIMM is, hence we don't trust
- * this test for now */
- }
- /* Good. We should be able to use this DIMM */
- /* That's it. We're done */
- break;
- }
- if (n_tries > 1)
- printram("Hmm, we had to try %zu times before our calibration "
- "was good.\n", n_tries);
-}
-
-/*
- * The meat and potatoes of getting our MCU to operate the DIMMs properly.
- *
- * Thank you JEDEC for making us need configurable delays for each set of MD
- * signals.
- */
-static void vx900_dram_calibrate_delays(const ramctr_timing * ctrl,
- const rank_layout * ranks)
-{
- size_t i;
- u8 val;
- u8 dimm;
- vx900_delay_calib delay_cal;
- memset(&delay_cal, 0, sizeof(delay_cal));
- printram("Starting delay calibration\n");
-
- /**** Read delay control ****/
- /* MD Input Data Push Timing Control;
- * use values recommended in datasheet
- * Setting this too low causes the Rx window to move below the range we
- * need it so we can capture it with Rx_78_7f
- * This causes Rx calibrations to be too close to 0, and Tx
- * calibrations will fail.
- * Setting this too high causes the window to move above the range.
- */
- if (ctrl->tCK <= TCK_533MHZ)
- val = 2;
- else if (ctrl->tCK <= TCK_333MHZ)
- val = 1;
- else
- val = 0;
- val++; /* FIXME: vendor BIOS sets this to 3 */
- pci_update_config8(MCU, 0x74, ~(0x03 << 1), ((val & 0x03) << 1));
-
- /* FIXME: The vendor BIOS increases the MD input delay - WHY ? */
- pci_update_config8(MCU, 0xef, ~(3 << 4), 3 << 4);
-
- /**** Write delay control ****/
- /* FIXME: The vendor BIOS does this, but WHY?
- * See check_special_registers in VIA provided code. This value seems
- * to depend on the DRAM frequency.
- */
- /* Early DQ/DQS for write cycles */
- pci_update_config8(MCU, 0x76, ~(3 << 2), 2 << 2);
- /* FIXME: The vendor BIOS does this - Output preamble ? */
- pci_write_config8(MCU, 0x77, 0x10);
-
- /* Set BA[0/1/2] to [A17/18/19] */
- vx900_dram_set_ma_pin_map(VX900_MRS_MA_MAP);
- /* Disable Multiple Page Mode - Set Rx69[0] to 0 */
- pci_update_config8(MCU, 0x69, ~(1 << 0), 0x00);
-
- /* It's very important that we keep all ranks which are not calibrated
- * mapped to VR3. Even if we disable them, if they are mapped to VR0
- * (the rank we use for calibrations), the calibrations may fail in
- * unexpected ways. */
- vx900_pr_map_all_vr3();
-
- /* We only really need to run the receive calibrations once. They are
- * meant to account for signal travel differences in the internal paths
- * of the MCU, so it doesn't really matter which rank we use for this.
- * Differences between ranks will be accounted for in the transmit
- * calibration. */
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i += 2) {
- /* Do we have a valid DIMM? */
- if (ranks->phys_rank_size_mb[i] +
- ranks->phys_rank_size_mb[i + 1] == 0)
- continue;
- /* Map the first rank of the DIMM to VR0 */
- vx900_map_pr_vr(2 * i, 0);
- /* Only run on first rank, remember? */
- break;
- }
- vx900_dram_calibrate_receive_delays(&delay_cal,
- ranks->flags[i].pins_mirrored);
- printram("RX DQS calibration results\n");
- dump_delay_range(delay_cal.rx_dqs);
-
- /* Enable multiple page mode for when calibrating transmit delays */
- pci_or_config8(MCU, 0x69, 1 << 1);
-
- /*
- * Unlike the receive delays, we need to run the transmit calibration
- * for each DIMM (not rank). We run the calibration on the even rank.
- * The odd rank may have memory pins swapped, and this, it seems,
- * confuses the calibration circuit.
- */
- dimm = 0;
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i++) {
- /* Do we have a valid DIMM? */
- u32 dimm_size_mb = ranks->phys_rank_size_mb[2 * i]
- + ranks->phys_rank_size_mb[2 * i + 1];
- if (dimm_size_mb == 0)
- continue;
- /* Map the first rank of the DIMM to VR0 */
- vx900_map_pr_vr(2 * i, 0);
- vx900_dram_calibrate_transmit_delays(&(delay_cal.tx_dq[dimm]),
- &(delay_cal.tx_dqs[dimm]));
- /* We run this more than once, so dump delays for each DIMM */
- printram("Tx DQS calibration results\n");
- dump_delay_range(delay_cal.tx_dqs[dimm]);
- printram("TX DQ delay calibration results:\n");
- dump_delay_range(delay_cal.tx_dq[dimm]);
- /* Now move the DIMM back to VR3 */
- vx900_map_pr_vr(2 * i, 3);
- /* We use dimm as a counter so that we fill tx_dq[] and tx_dqs[]
- * results in order from 0, and do not leave any gaps */
- dimm++;
- }
-
- /* When we have more dimms, we need to find a tx window with which all
- * dimms can safely work */
- if (dimm > 1) {
- vx900_dram_find_avg_delays(&delay_cal);
- printram("Final delay values\n");
- printram("Tx DQS: ");
- dump_delay(delay_cal.tx_dqs[0].avg);
- printram("Tx DQ: ");
- dump_delay(delay_cal.tx_dq[0].avg);
- }
- /* Write manual settings */
- pci_or_config8(MCU, 0x75, 0x01);
- vx900_delay_calib_mode_select(CALIB_TxDQS, CALIB_MANUAL);
- vx900_write_0x78_0x7f(delay_cal.tx_dqs[0].avg);
- vx900_delay_calib_mode_select(CALIB_TxDQ, CALIB_MANUAL);
- vx900_write_0x78_0x7f(delay_cal.tx_dq[0].avg);
-}
-
-static void vx900_dram_set_refresh_counter(ramctr_timing * ctrl)
-{
- u8 reg8;
- /* Set DRAM refresh counter
- * Based on a refresh counter of 0x61 at 400MHz */
- reg8 = (TCK_400MHZ * 0x61) / ctrl->tCK;
- pci_write_config8(MCU, 0xc7, reg8);
-}
-
-/*
- * Here, we map each rank somewhere in our address space. We don't really care
- * at this point if this will overlap the PCI config space. If needed, remapping
- * is done in ramstage, where we actually know how much PCI space we actually
- * need.
- */
-static void vx900_dram_range(ramctr_timing * ctrl, rank_layout * ranks)
-{
- size_t i, vrank = 0;
- u8 reg8;
- u32 ramsize_mb = 0, tolm_mb;
- const u32 TOLM_3_5G = (7 << 29);
- /* All unused physical ranks go to VR3. Otherwise, the MCU might be
- * trying to read or write from unused ranks, or even worse, write some
- * bits to the rank we want, and some to the unused ranks, even though
- * they are disabled. Since VR3 is the last virtual rank to be used, we
- * eliminate any ambiguities that the MCU may face. */
- vx900_pr_map_all_vr3();
- for (i = 0; i < VX900_MAX_MEM_RANKS; i++) {
- u32 rank_size_mb = ranks->phys_rank_size_mb[i];
- if (!rank_size_mb)
- continue;
-
- /* vvvvvvvvvv FIXME: Fix odd rank init vvvvvvvvvv */
- if ((i & 1)) {
- printk(BIOS_EMERG, "I cannot initialize rank %zu\n", i);
- printk(BIOS_EMERG, "I have to disable it\n");
- continue;
- }
- /* ^^^^^^^^^^ FIXME: Fix odd rank init ^^^^^^^^^^ */
-
- ranks->virt[vrank].start_addr = ramsize_mb;
- ramsize_mb += rank_size_mb;
- ranks->virt[vrank].end_addr = ramsize_mb;
-
- /* Rank memory range */
- reg8 = (ranks->virt[vrank].start_addr >> 6);
- pci_write_config8(MCU, 0x48 + vrank, reg8);
- reg8 = (ranks->virt[vrank].end_addr >> 6);
- pci_write_config8(MCU, 0x40 + vrank, reg8);
-
- vx900_map_pr_vr(i, vrank);
-
- printram("Mapped Physical rank %u, to virtual rank %u\n"
- " Start address: 0x%.10llx\n"
- " End address: 0x%.10llx\n",
- (int)i, (int)vrank,
- (u64) ranks->virt[vrank].start_addr << 20,
- (u64) ranks->virt[vrank].end_addr << 20);
- /* Move on to next virtual rank */
- vrank++;
- }
-
- /* Limit the Top of Low memory at 3.5G
- * Not to worry, we'll set tolm in ramstage, once we have initialized
- * all devices and know pci_tolm. */
- tolm_mb = MIN(ramsize_mb, TOLM_3_5G >> 20);
- u16 reg_tolm = (tolm_mb << 4) & 0xfff0;
- pci_update_config16(MCU, 0x84, (u16)~0xfff0, reg_tolm);
-
- printram("Initialized %u virtual ranks, with a total size of %u MB\n",
- (int)vrank, ramsize_mb);
-}
-
-/*
- * Here, we tell the memory controller how to treat a DIMM. This is an extremely
- * important step. It tells the MCU how many address bits we have in each DIMM,
- * and how to use them. This information is essential for the controller to
- * understand the DIMM addressing, and write and read data in the correct place.
- */
-static void vx900_dram_map_row_col_bank(dimm_info * dimms)
-{
- u8 reg8, rcb_val, col_bits, max_row_bits;
- size_t i;
- /* Do we have 4Gbit chips? */
- /* FIXME: Implement this */
-
- /* Do we have 8Gbit chips? */
- /* FIXME: Implement this */
-
- max_row_bits = rcb_val = reg8 = 0;
- for (i = 0; i < VX900_MAX_DIMM_SLOTS; i++) {
- if (dimms->dimm[i].dram_type == SPD_MEMORY_TYPE_UNDEFINED)
- continue;
-
- col_bits = dimms->dimm[i].col_bits;
-
- /*
- * DDR3 always uses 3 bank address bits, and MA type 111b cannot
- * be used due to chipset limitation. We are left with only two
- * options, which we can choose based solely on the number of
- * column address bits.
- */
- if ((col_bits < 10) || (col_bits > 11)) {
- printram("DIMM %zd has %d column address bits.\n",
- i, col_bits);
- die("Unsupported DIMM. Try booting without this DIMM");
- }
-
- rcb_val = col_bits - 5;
- reg8 |= (rcb_val << ((i * 3) + 2));
-
- /* */
- max_row_bits = MAX(max_row_bits, dimms->dimm[i].row_bits);
- }
-
- printram("RCBA map (rx50) <- %.2x\n", reg8);
- pci_write_config8(MCU, 0x50, reg8);
-
- printram("Houston, we have %d row address bits\n", max_row_bits);
- /* FIXME: Do this properly */
- vx900_dram_map_pins(13, 14, 15, 17, 16);
-
-}
-
-/*
- * Here, we set some final configuration bits, which should improve the
- * performance of the memory slightly (arbitration, expiration counters, etc.)
- *
- * FIXME: We don't really do much else than the minimum to get the MCU properly
- * configured. We don't yet do set the "performance-enhancing" bits referenced
- * in the comment above.
- */
-static void vx900_dram_write_final_config(ramctr_timing * ctrl)
-{
- /* FIXME: These are quick cheats */
-
- /* FIXME: Why are we doing this? */
- /* Tri-state MCSi# when rank is in self-refresh */
- pci_or_config8(MCU, 0x99, 0x0f);
-
- /* Enable paging mode and 8 page registers */
- pci_or_config8(MCU, 0x69, 0xe5);
-
- /* Enable automatic triggering of short ZQ calibration */
- pci_write_config8(MCU, 0xc8, 0x80);
-
- /* And last but not least, Enable A20 line */
- outb(inb(0x92) | (1 << 1), 0x92);
-}
-
-void vx900_init_dram_ddr3(const dimm_layout * dimm_addr)
-{
- dimm_info dimm_prop;
- ramctr_timing ctrl_prop;
- rank_layout ranks;
- pci_devfn_t mcu;
-
- if (!ram_check_noprint_nodie(1 << 20, 1 << 20)) {
- printram("RAM is already initialized. Skipping init\n");
- return;
- }
- /* Locate the Memory controller */
- mcu = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VX900_MEMCTRL), 0);
-
- if (mcu == PCI_DEV_INVALID) {
- die("Memory Controller not found\n");
- }
- memset(&dimm_prop, 0, sizeof(dimm_prop));
- memset(&ctrl_prop, 0, sizeof(ctrl_prop));
- memset(&ranks, 0, sizeof(ranks));
- /* 1) Write some initial "safe" parameters */
- vx900_dram_write_init_config();
- /* 2) Get timing information from SPDs */
- dram_find_spds_ddr3(dimm_addr, &dimm_prop);
- /* 3) Find lowest common denominator for all modules */
- dram_find_common_params(&dimm_prop, &ctrl_prop);
- /* 4) Find the size of each memory rank */
- vx900_dram_phys_bank_range(&dimm_prop, &ranks);
- /* 5) Set DRAM driving strength */
- vx900_dram_driving_ctrl(&dimm_prop);
- /* 6) Set DRAM frequency and latencies */
- vx900_dram_timing(&ctrl_prop);
- vx900_dram_freq(&ctrl_prop);
- /* 7) Initialize the modules themselves */
- vx900_dram_ddr3_dimm_init(&ctrl_prop, &ranks);
- /* 8) Set refresh counter based on DRAM frequency */
- vx900_dram_set_refresh_counter(&ctrl_prop);
- /* 9) Calibrate receive and transmit delays */
- vx900_dram_calibrate_delays(&ctrl_prop, &ranks);
- /* 10) Enable Physical to Virtual Rank mapping */
- vx900_dram_range(&ctrl_prop, &ranks);
- /* 11) Map address bits to DRAM pins */
- vx900_dram_map_row_col_bank(&dimm_prop);
- /* 99) Some final adjustments */
- vx900_dram_write_final_config(&ctrl_prop);
- /* Take a dump */
- dump_pci_device(mcu);
-}
diff --git a/src/northbridge/via/vx900/romstrap.S b/src/northbridge/via/vx900/romstrap.S
deleted file mode 100644
index 26c1ee694a..0000000000
--- a/src/northbridge/via/vx900/romstrap.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer)
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- * Copyright (C) 2009 One Laptop per Child, Association, Inc.
- * Copyright (C) 2011-2012 Alexandru Gagniuc <mr.nuke.me@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.
- */
-
-/* As extracted from the manufacturer's ROM, the romstrap table looks like:
- * .long 0x77886047 .long 0x00777777
- * .long 0x00000000 .long 0x00000000
- * .long 0x00888888 .long 0x00AA1111
- * .long 0x00000000 .long 0x00000000
- *
- * The vendor BIOS then adjusts some of these settings very early on. Instead of
- * adjusting those settings in code, we work them in the romstrap table.
- *
- */
-/* This file constructs the ROM strap table for VX900 */
-
- .section ".romstrap", "a", @progbits
-
- .globl __romstrap_start
-__romstrap_start:
-tblpointer:
- .long 0x77886047
- .long 0x00777777
- .long 0x00000000
- .long 0x00000000
- .long 0x00888888
- .long 0x00AA1111
- .long 0x00000000
- .long 0x00000000
-
-/*
- * The pointer to above table should be at 0xffffffd0,
- * the table itself MUST be aligned to 128B it seems!
- */
-rspointers:
- .long tblpointer // It will be 0xffffffd0
-
- .globl __romstrap_end
-
-__romstrap_end:
-.previous
diff --git a/src/northbridge/via/vx900/romstrap.ld b/src/northbridge/via/vx900/romstrap.ld
deleted file mode 100644
index 0217f41b87..0000000000
--- a/src/northbridge/via/vx900/romstrap.ld
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 AMD
- * (Written by Yinghai Lu <yinghai.lu@amd.com> for AMD)
- * Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-SECTIONS {
- . = (0x100000000 - 0x2c) - (__romstrap_end - __romstrap_start);
- .romstrap (.): {
- KEEP(*(.romstrap))
- }
-}
diff --git a/src/northbridge/via/vx900/sata.c b/src/northbridge/via/vx900/sata.c
deleted file mode 100644
index 791133142f..0000000000
--- a/src/northbridge/via/vx900/sata.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-#include "vx900.h"
-
-/**
- * @file vx900/sata.c
- *
- * STATUS: Pretty good
- * The only issue is the SATA EPHY configuration. We do not know if it is board
- * specific or not. Otherwise, the SATA controller works without issues.
- */
-
-static void vx900_print_sata_errors(u32 flags)
-{
- /* Status flags */
- printk(BIOS_DEBUG, "\tPhyRdy %s\n",
- (flags & (1 << 16)) ? "changed" : "not changed");
- printk(BIOS_DEBUG, "\tCOMWAKE %s\n",
- (flags & (1 << 16)) ? "detected" : "not detected");
- printk(BIOS_DEBUG, "\tExchange as determined by COMINIT %s\n",
- (flags & (1 << 26)) ? "occurred" : "not occurred");
- printk(BIOS_DEBUG, "\tPort selector presence %s\n",
- (flags & (1 << 27)) ? "detected" : "not detected");
- /* Errors */
- if (flags & (1 << 0))
- printk(BIOS_DEBUG, "\tRecovered data integrity ERROR\n");
- if (flags & (1 << 1))
- printk(BIOS_DEBUG, "\tRecovered data communication ERROR\n");
- if (flags & (1 << 8))
- printk(BIOS_DEBUG, "\tNon-recovered Transient Data Integrity ERROR\n");
- if (flags & (1 << 9))
- printk(BIOS_DEBUG, "\tNon-recovered Persistent Communication or"
- "\tData Integrity ERROR\n");
- if (flags & (1 << 10))
- printk(BIOS_DEBUG, "\tProtocol ERROR\n");
- if (flags & (1 << 11))
- printk(BIOS_DEBUG, "\tInternal ERROR\n");
- if (flags & (1 << 17))
- printk(BIOS_DEBUG, "\tPHY Internal ERROR\n");
- if (flags & (1 << 19))
- printk(BIOS_DEBUG, "\t10B to 8B Decode ERROR\n");
- if (flags & (1 << 20))
- printk(BIOS_DEBUG, "\tDisparity ERROR\n");
- if (flags & (1 << 21))
- printk(BIOS_DEBUG, "\tCRC ERROR\n");
- if (flags & (1 << 22))
- printk(BIOS_DEBUG, "\tHandshake ERROR\n");
- if (flags & (1 << 23))
- printk(BIOS_DEBUG, "\tLink Sequence ERROR\n");
- if (flags & (1 << 24))
- printk(BIOS_DEBUG, "\tTransport State Transition ERROR\n");
- if (flags & (1 << 25))
- printk(BIOS_DEBUG, "\tUNRECOGNIZED FIS type\n");
-}
-
-static void vx900_dbg_sata_errors(struct device *dev)
-{
- /* Port 0 */
- if (pci_read_config8(dev, 0xa0) & (1 << 0)) {
- printk(BIOS_DEBUG, "Device detected in SATA port 0.\n");
- u32 flags = pci_read_config32(dev, 0xa8);
- vx900_print_sata_errors(flags);
- };
- /* Port 1 */
- if (pci_read_config8(dev, 0xa1) & (1 << 0)) {
- printk(BIOS_DEBUG, "Device detected in SATA port 1.\n");
- u32 flags = pci_read_config32(dev, 0xac);
- vx900_print_sata_errors(flags);
- };
-}
-
-typedef u8 sata_phy_config[64];
-
-static sata_phy_config reference_ephy = {
- 0x80, 0xb8, 0xf0, 0xfe, 0x40, 0x7e, 0xf6, 0xdd,
- 0x1a, 0x22, 0xa0, 0x10, 0x02, 0xa9, 0x7c, 0x7e,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x84, 0x8c,
- 0x75, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x40, 0xd0, 0x41, 0x40, 0x00, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x40, 0x50, 0x41, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static u32 sata_phy_read32(struct device *dev, u8 index)
-{
- /* The SATA PHY control registers are accessed by a funny index/value
- * scheme. Each byte (0,1,2,3) has its own 4-bit index */
- index = (index >> 2) & 0xf;
- u16 i16 = index | (index << 4) | (index << 8) | (index << 12);
- /* The index */
- pci_write_config16(dev, 0x68, i16);
- /* The value */
- return pci_read_config32(dev, 0x64);
-}
-
-static void sata_phy_write32(struct device *dev, u8 index, u32 val)
-{
- /* The SATA PHY control registers are accessed by a funny index/value
- * scheme. Each byte (0,1,2,3) has its own 4-bit index */
- index = (index >> 2) & 0xf;
- u16 i16 = index | (index << 4) | (index << 8) | (index << 12);
- /* The index */
- pci_write_config16(dev, 0x68, i16);
- /* The value */
- pci_write_config32(dev, 0x64, val);
-}
-
-static void vx900_sata_read_phy_config(struct device *dev, sata_phy_config cfg)
-{
- size_t i;
- u32 *data = (u32 *) cfg;
- for (i = 0; i < (sizeof(sata_phy_config)) >> 2; i++) {
- data[i] = sata_phy_read32(dev, i << 2);
- }
-}
-
-static void vx900_sata_write_phy_config(struct device *dev, sata_phy_config cfg)
-{
- size_t i;
- u32 *data = (u32 *) cfg;
- for (i = 0; i < (sizeof(sata_phy_config)) >> 2; i++) {
- sata_phy_write32(dev, i << 2, data[i]);
- }
-}
-
-static void vx900_sata_dump_phy_config(sata_phy_config cfg)
-{
- printk(BIOS_DEBUG, "SATA PHY config:\n");
- int i;
- for (i = 0; i < sizeof(sata_phy_config); i++) {
- unsigned char val;
- if ((i & 0x0f) == 0)
- printk(BIOS_DEBUG, "%02x:", i);
- val = cfg[i];
- if ((i & 7) == 0)
- printk(BIOS_DEBUG, " |");
- printk(BIOS_DEBUG, " %02x", val);
- if ((i & 0x0f) == 0x0f) {
- printk(BIOS_DEBUG, "\n");
- }
- }
-}
-
-/**
- * \brief VX900: Place the onboard SATA controller in Native IDE mode
- *
- * AHCI mode requires a sub-class of 0x06, and Interface of 0x0
- * SATA mode requires a sub-class of 0x06, and Interface of 0x00
- * Unfortunately, setting the class to SATA, will prevent us from modyfing the
- * interface register to an AHCI/SATA compliant value. Thus, payloads or OS may
- * not properly identify this as a SATA controller.
- * We could set the class code to 0x04, which would cause the interface register
- * to become 0x00, which represents a RAID controller. Unfortunately, when we do
- * this, SeaBIOS will skip this as a storage device, and we will not be able to
- * boot.
- * Our only option is to operate in IDE mode. We choose native IDE so that we
- * can freely assign an IRQ, and are not forced to use IRQ14
- */
-static void vx900_native_ide_mode(struct device *dev)
-{
- /* Disable subclass write protect */
- pci_update_config8(dev, 0x45, (u8)~(1 << 7), 0);
- /* Change the device class to IDE */
- pci_write_config16(dev, PCI_CLASS_DEVICE, PCI_CLASS_STORAGE_IDE);
- /* Re-enable subclass write protect */
- pci_or_config8(dev, 0x45, 1 << 7);
- /* Put it in native IDE mode */
- pci_write_config8(dev, PCI_CLASS_PROG, 0x8f);
-}
-
-static void vx900_sata_init(struct device *dev)
-{
- /* Enable SATA primary channel IO access */
- pci_or_config8(dev, 0x40, 1 << 1);
- /* Just SATA, so it makes sense to be in native SATA mode */
- vx900_native_ide_mode(dev);
-
- /* TP Layer Idle at least 20us before the Following Command */
- pci_or_config8(dev, 0x53, 1 << 7);
- /* Resend COMRESET When Recovering SATA Gen2 Device Error */
- pci_update_config8(dev, 0x62, ~(1 << 1), 1 << 7);
-
- /* Fix "PMP Device Can't Detect HDD Normally" (VIA Porting Guide)
- * SATA device detection will not work unless we clear these bits.
- * Without doing this, SeaBIOS (and potentially other payloads) will
- * timeout when detecting SATA devices */
- pci_update_config8(dev, 0x89, ~(1 << 3) | (1 << 6), 0);
-
- /* 12.7 Two Software Resets May Affect the System
- * When the software does the second reset before the first reset
- * finishes, it may cause the system hang. It would do one software
- * reset and check the BSY bit of one port only, and the BSY bit of
- * other port would be 1, then it does another software reset
- * immediately and causes the system hang.
- * This is because the first software reset doesn't finish, and the
- * state machine of the host controller conflicts, it can't finish the
- * second one anymore. The BSY bit of slave port would be always 1 after
- * the second software reset issues. BIOS should set the following
- * bit to avoid this issue. */
- pci_or_config8(dev, 0x80, 1 << 6);
-
- /* We need to set the EPHY values before doing anything with the link */
- sata_phy_config ephy;
- vx900_sata_read_phy_config(dev, ephy);
- if (1) {
- vx900_sata_dump_phy_config(ephy);
- vx900_sata_write_phy_config(dev, reference_ephy);
- } else {
- /* Enable TX and RX driving resistance */
- /* TX - 50 Ohm */
- ephy[1] &= ~(0x1f << 3);
- ephy[1] |= (1 << 7) | (8 << 3);
- /* RX - 50 Ohm */
- ephy[2] &= ~(0x1f << 3);
- ephy[2] |= (1 << 7) | (8 << 3);
- vx900_sata_write_phy_config(dev, ephy);
- }
-
- vx900_sata_read_phy_config(dev, ephy);
- vx900_sata_dump_phy_config(ephy);
-
- /* Clear error flags */
- pci_write_config32(dev, 0xa8, 0xffffffff);
- pci_write_config32(dev, 0xac, 0xffffffff);
-
- /* Start OOB link negotiation sequence */
- pci_or_config8(dev, 0xb9, 3 << 4);
-
- /* FIXME: From now on, we are just doing DEBUG stuff
- * Wait until PHY communication is enabled */
- u32 wloops = 0;
- while (!(pci_read_config8(dev, 0xa0) & (1 << 1)))
- wloops++;
- printk(BIOS_SPEW, "SATA wait loops: %u\n", wloops);
-
- vx900_dbg_sata_errors(dev);
-}
-
-static void vx900_sata_read_resources(struct device *dev)
-{
- pci_dev_read_resources(dev);
-}
-
-static struct device_operations vga_operations = {
- .read_resources = vx900_sata_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vx900_sata_init,
-};
-
-static const struct pci_driver chrome9hd_driver __pci_driver = {
- .ops = &vga_operations,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VX900_SATA,
-};
diff --git a/src/northbridge/via/vx900/traf_ctrl.c b/src/northbridge/via/vx900/traf_ctrl.c
deleted file mode 100644
index 2ef542afb8..0000000000
--- a/src/northbridge/via/vx900/traf_ctrl.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <drivers/generic/ioapic/chip.h>
-
-#include "vx900.h"
-#include "chip.h"
-
-/**
- * @file vx900/traf_ctrl.c
- *
- * STATUS:
- * The same issues with the IOAPIC pointe in lpc.c also apply here.
- *
- * We need to check if the current PCIE lane configuration mechanism is sane.
- */
-
-/**
- * \brief VX900: Set up the north module IOAPIC (for PCIE and VGA)
- *
- * Enable the IOAPIC in the south module, and properly set it up.
- * \n
- * This is the hardware specific initialization for the IOAPIC, and complements
- * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work
- * properly, it _must_ be declared in devicetree.cb .
- * \n
- * We are assuming this is called before the drivers/generic/ioapic code,
- * which should be the case if devicetree.cb is set up properly.
- */
-static void vx900_north_ioapic_setup(struct device *dev)
-{
- u8 base_val;
- struct device *ioapic;
- ioapic_config_t *config;
- /* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb
- * If it's not, then the generic ioapic driver will not set it up
- * correctly, and the MP table will not be correctly generated */
- for (ioapic = dev->next; ioapic; ioapic = ioapic->next) {
- if (ioapic->path.type == DEVICE_PATH_IOAPIC)
- break;
- }
- /* You did put an IOAPIC in devicetree.cb, didn't you? */
- if (ioapic == 0) {
- /* We don't have enough info to set up the IOAPIC */
- printk(BIOS_ERR, "ERROR: North module IOAPIC not found. "
- "Check your devicetree.cb\n");
- return;
- }
- /* Found our IOAPIC, and it should not carry ISA interrupts */
- config = (ioapic_config_t *) ioapic->chip_info;
- if (config->have_isa_interrupts) {
- /* Umh, is this the right IOAPIC ? */
- printk(BIOS_ERR, "ERROR: North module IOAPIC should not carry "
- "ISA interrupts.\n" "Check your devicetree.cb\n");
- printk(BIOS_ERR, "Will not initialize this IOAPIC.\n");
- return;
- }
- /* The base address of this IOAPIC _must_
- * be between 0xfec00000 and 0xfecfff00
- * be 256-byte aligned
- */
- if ((config->base < (void *)0xfec0000 || config->base > (void *)0xfecfff00)
- || (((uintptr_t)config->base & 0xff) != 0)) {
- printk(BIOS_ERR, "ERROR: North module IOAPIC base should be "
- "between 0xfec00000 and 0xfecfff00\n"
- "and must be aligned to a 256-byte boundary, "
- "but we found it at 0x%p\n", config->base);
- return;
- }
-
- printk(BIOS_DEBUG, "VX900 TRAF_CTR: Setting up the north module IOAPIC "
- "at %p\n", config->base);
-
- /* First register of the IOAPIC base */
- base_val = (((uintptr_t)config->base) >> 8) & 0xff;
- pci_write_config8(dev, 0x41, base_val);
- /* Second register of the base.
- * Bit[7] also enables the IOAPIC and bit[5] enables MSI cycles */
- base_val = (((uintptr_t)config->base) >> 16) & 0xf;
- pci_or_config8(dev, 0x40, base_val | (1 << 7) | (1 << 5));
-}
-
-/*
- * Configures the PCI-express ports
- *
- * FIXME: triple-quadruple-check this
- */
-static void vx900_pex_link_setup(struct device *dev)
-{
- u8 reg8;
- struct northbridge_via_vx900_config *nb = (void *)dev->chip_info;
-
- reg8 = pci_read_config8(dev, 0xb0);
- reg8 &= ~((1 << 7) | (1 << 3));
-
- if (nb->assign_pex_to_dp)
- reg8 |= (1 << 7);
-
- if (!nb->pcie_port1_2_lane_wide)
- reg8 |= (1 << 3);
-
- pci_write_config8(dev, 0xb0, reg8);
-}
-
-static void vx900_traf_ctr_init(struct device *dev)
-{
- vx900_north_ioapic_setup(dev);
- vx900_pex_link_setup(dev);
-}
-
-static struct device_operations traf_ctrl_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vx900_traf_ctr_init,
- /* Need this here, or the IOAPIC driver won't be called.
- * FIXME: Technically not a LPC bus. */
- .scan_bus = scan_static_bus,
-};
-
-static const struct pci_driver traf_ctrl_driver __pci_driver = {
- .ops = &traf_ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VX900_TRAF,
-};
diff --git a/src/northbridge/via/vx900/vx900.h b/src/northbridge/via/vx900/vx900.h
deleted file mode 100644
index 1f611535aa..0000000000
--- a/src/northbridge/via/vx900/vx900.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me@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, 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.
- */
-#ifndef __VX900_H
-#define __VX900_H
-
-#define VX900_ACPI_IO_BASE 0x0400
-
-#define SMBUS_IO_BASE 0x500
-
-#define VX900_MMCONFIG_MBAR 0xbc
-
-/* The maximum number of DIMM slots that the VX900 supports */
-#define VX900_MAX_DIMM_SLOTS 2
-#define VX900_MAX_MEM_RANKS 4
-
-#include <device/pci_ops.h>
-#include <device/pci.h>
-
-u32 vx900_get_tolm(void);
-void vx900_set_chrome9hd_fb_size(u32 size_mb);
-u8 vx900_get_chrome9hd_fb_pow(void);
-u32 vx900_get_chrome9hd_fb_size(void);
-u8 vx900_int15_get_5f18_bl(void);
-uint64_t get_uma_memory_base(void);
-
-/* We use these throughout the code. They really belong in a generic part of
- * coreboot, but until bureaucracy gets them there, we still need them */
-
-void dump_pci_device(pci_devfn_t dev);
-
-#endif /* __VX900_H */