Andrew Wu (arw@dmp.com.tw) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3511
-gerrit
commit ea3858e608772ecd92c964c7a94d80f562b46405 Author: Andrew Wu arw@dmp.com.tw Date: Fri Jun 21 21:37:05 2013 +0800
Add support for DMP Vortex86EX PCI northbridge.
Change-Id: I60675a357f9db430ebb59b17be6d8c92a9cadf43 Signed-off-by: Andrew Wu arw@dmp.com.tw --- src/northbridge/Kconfig | 1 + src/northbridge/Makefile.inc | 1 + src/northbridge/dmp/Kconfig | 20 ++ src/northbridge/dmp/Makefile.inc | 20 ++ src/northbridge/dmp/vortex86ex/Kconfig | 21 ++ src/northbridge/dmp/vortex86ex/Makefile.inc | 21 ++ src/northbridge/dmp/vortex86ex/chip.h | 26 +++ src/northbridge/dmp/vortex86ex/northbridge.c | 146 ++++++++++++ src/northbridge/dmp/vortex86ex/northbridge.h | 69 ++++++ src/northbridge/dmp/vortex86ex/raminit.c | 325 +++++++++++++++++++++++++++ src/northbridge/dmp/vortex86ex/xgi_oprom.c | 35 +++ 11 files changed, 685 insertions(+)
diff --git a/src/northbridge/Kconfig b/src/northbridge/Kconfig index b2b8abe..0ac09a6 100644 --- a/src/northbridge/Kconfig +++ b/src/northbridge/Kconfig @@ -1,4 +1,5 @@ source src/northbridge/amd/Kconfig +source src/northbridge/dmp/Kconfig source src/northbridge/intel/Kconfig source src/northbridge/rdc/Kconfig source src/northbridge/via/Kconfig diff --git a/src/northbridge/Makefile.inc b/src/northbridge/Makefile.inc index 283ba4e..1a5b1c8 100644 --- a/src/northbridge/Makefile.inc +++ b/src/northbridge/Makefile.inc @@ -1,4 +1,5 @@ subdirs-y += amd +subdirs-y += dmp subdirs-y += intel subdirs-y += rdc subdirs-y += via diff --git a/src/northbridge/dmp/Kconfig b/src/northbridge/dmp/Kconfig new file mode 100644 index 0000000..a69d1d9 --- /dev/null +++ b/src/northbridge/dmp/Kconfig @@ -0,0 +1,20 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 DMP Electronics Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +source src/northbridge/dmp/vortex86ex/Kconfig diff --git a/src/northbridge/dmp/Makefile.inc b/src/northbridge/dmp/Makefile.inc new file mode 100644 index 0000000..3cfcc48 --- /dev/null +++ b/src/northbridge/dmp/Makefile.inc @@ -0,0 +1,20 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 DMP Electronics Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +subdirs-$(CONFIG_NORTHBRIDGE_DMP_VORTEX86EX) += vortex86ex diff --git a/src/northbridge/dmp/vortex86ex/Kconfig b/src/northbridge/dmp/vortex86ex/Kconfig new file mode 100644 index 0000000..7bf5235 --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/Kconfig @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 DMP Electronics Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config NORTHBRIDGE_DMP_VORTEX86EX + bool diff --git a/src/northbridge/dmp/vortex86ex/Makefile.inc b/src/northbridge/dmp/vortex86ex/Makefile.inc new file mode 100644 index 0000000..82b07fd --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/Makefile.inc @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 DMP Electronics Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +ramstage-y += northbridge.c +ramstage-y += xgi_oprom.c diff --git a/src/northbridge/dmp/vortex86ex/chip.h b/src/northbridge/dmp/vortex86ex/chip.h new file mode 100644 index 0000000..93384c4 --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/chip.h @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 DMP Electronics Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _NORTHBRIDGE_DMP_VORTEX86EX +#define _NORTHBRIDGE_DMP_VORTEX86EX + +struct northbridge_dmp_vortex86ex_config { +}; + +#endif /* _NORTHBRIDGE_DMP_VORTEX86EX */ diff --git a/src/northbridge/dmp/vortex86ex/northbridge.c b/src/northbridge/dmp/vortex86ex/northbridge.c new file mode 100644 index 0000000..e3be6c3 --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/northbridge.c @@ -0,0 +1,146 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 DMP Electronics Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <arch/io.h> +#include <stdint.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <cbmem.h> +#include <pc80/mc146818rtc.h> +#include "chip.h" +#include "northbridge.h" + +#define SPI_BASE 0xfc00 + +static void northbridge_init(device_t dev) +{ + printk(BIOS_DEBUG, "Vortex86EX northbridge early init ...\n"); + // enable F0A/ECA/E8A/E4A/E0A/C4A/C0A shadow read/writable. + pci_write_config32(dev, NB_REG_MAR, 0x3ff000f0); + // enable C0000h - C3FFFh/C4000h - C7FFF can be in L1 cache selection. + pci_write_config32(dev, NB_REG_HOST_CTL, (1 << 18) | (1 << 19)); + // Set SPI register base. + pci_write_config16(dev, NB_REG_SPI_BASE, SPI_BASE | 1); +} + +static struct device_operations northbridge_operations = { + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = northbridge_init +}; + +static const struct pci_driver northbridge_driver_6021 __pci_driver = { + .ops = &northbridge_operations, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x6021, /* DX CPU N/B ID */ +}; + +static const struct pci_driver northbridge_driver_6025 __pci_driver = { + .ops = &northbridge_operations, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x6025, /* EX CPU N/B ID */ +}; + +/* Set CMOS register 15h/16h/17h/18h for base/extended + * memory size. */ +static void set_cmos_memory_size(unsigned long sizek) +{ + unsigned long ext_mem_size; + u8 ext_mem_size_hb, ext_mem_size_lb; + /* calculate memory size between 1M - 65M. */ + ext_mem_size = sizek - 1024; + if (ext_mem_size > 65535) + ext_mem_size = 65535; + ext_mem_size_hb = (u8) (ext_mem_size >> 8); + ext_mem_size_lb = (u8) (ext_mem_size & 0xff); + /* Base memory is always 640K. */ + cmos_write(0x80, 0x15); + cmos_write(0x02, 0x16); + /* Write extended memory size. */ + cmos_write(ext_mem_size_lb, 0x17); + cmos_write(ext_mem_size_hb, 0x18); + /* register 0x30(48) is RTC_BOOT_BYTE for coreboot, + * don't touch it. */ +} + +static void pci_domain_set_resources(device_t dev) +{ + device_t mc_dev; + uint32_t pci_tolm; + + printk(BIOS_SPEW, "Entering vortex86ex pci_domain_set_resources.\n"); + + pci_tolm = find_pci_tolm(dev->link_list); + mc_dev = dev->link_list->children; + if (mc_dev) { + unsigned long tomk, tolmk; + int idx; + int ss; + /* Get DDRII size setting from northbridge register. */ + /* SS = 0 for 2MB, 1 for 4MB, 2 for 8MB, 3 for 16MB ... */ + ss = pci_read_config16(mc_dev, 0x6c); + ss = ((ss >> 8) & 0xf); + tomk = (2 * 1024) << ss; + printk(BIOS_DEBUG, "I would set ram size to %ld Mbytes\n", (tomk >> 10)); + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) + /* The PCI hole does does not overlap the memory. + */ + tolmk = tomk; + + high_tables_base = (tolmk * 1024) - HIGH_MEMORY_SIZE; + high_tables_size = HIGH_MEMORY_SIZE; + printk(BIOS_DEBUG, "tom: %lx, high_tables_base: %llx, high_tables_size: %llx\n", + tomk * 1024, high_tables_base, high_tables_size); + + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 640); /* first 640k */ + ram_resource(dev, idx++, 768, tolmk - 768); /* leave a hole for vga */ + set_cmos_memory_size(tolmk); + } + assign_resources(dev->link_list); +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = NULL, + .init = NULL, + .scan_bus = pci_domain_scan_bus, +}; + +static void enable_dev(struct device *dev) +{ + printk(BIOS_SPEW, "In vortex86ex enable_dev for device %s.\n", dev_path(dev)); + + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_DOMAIN) { + dev->ops = &pci_domain_ops; + pci_set_method(dev); + } +} + +struct chip_operations northbridge_dmp_vortex86ex_ops = { + CHIP_NAME("DMP Vortex86EX Northbridge") + .enable_dev = enable_dev, +}; diff --git a/src/northbridge/dmp/vortex86ex/northbridge.h b/src/northbridge/dmp/vortex86ex/northbridge.h new file mode 100644 index 0000000..e6f21cd --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/northbridge.h @@ -0,0 +1,69 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 DMP Electronics Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NORTHBRIDGE_H +#define NORTHBRIDGE_H + +#define NB PCI_DEV(0, 0, 0) +#define NB_REG_SPI_BASE 0x40 +#define NB_REG_CLK_OUT_CTL 0x48 +#define NB_REG_PCI_CLK_CTL 0x4b +#define NB_REG_STRAP 0x60 +#define NB_REG_STRAP2 0x64 +#define NB_REG_MBR 0x6c +#define NB_REG_DDR3_CFG 0x74 +#define NB_REG_DDR3_MTR1 0x78 +#define NB_REG_DDR3_MTR2 0x7c +#define NB_REG_SMM 0x83 +#define NB_REG_MAR 0x84 +#define NB_REG_CID 0x90 +#define NB_REG_S1R 0x94 +#define NB_REG_S2R 0x98 +#define NB_REG_S3R 0x9c +#define NB_REG_HOST_CTL 0xa0 +#define NB_REG_CPU_MBCR 0xc4 +#define NB_REG_CDR 0xd0 +#define NB_REG_PACR 0xf0 +#define NB_REG_PMCR 0xf4 +#define NB_REG_PCI_TARGET 0xf8 +#define NB_REG_PCSCR 0xfc + +/* Additional "virtual" device, just extension of NB */ +#define NB1 PCI_DEV(0, 0, 1) +#define NB1_REG_FJZ_PHY_CTL1 0x80 +#define NB1_REG_FJZ_PHY_CTL2 0x84 +#define NB1_REG_FJZ_PHY_CTL3 0x88 +#define NB1_REG_FJZ_DRAM_CTL1 0x90 +#define NB1_REG_FJZ_DRAM_CTL2 0x94 +#define NB1_REG_FJZ_DRAM_CTL3 0x98 +#define NB1_REG_FJZ_DRAM_CTL4 0x9c +#define NB1_REG_PLL_TEST_CTL 0xa8 +#define NB1_REG_DDR3_PWR_SAV 0xbc +#define NB1_REG_DDR3_CTL_OPT1 0xc0 +#define NB1_REG_DDR3_CTL_OPT3 0xc8 +#define NB1_REG_DDR3_CTL_OPT4 0xcc +#define NB1_REG_DDR3_CTL_OPT5 0xce +#define NB1_REG_PLL_TEST_MODE 0xd0 +#define NB1_REG_L2_CACHE_CTL 0xe8 +#define NB1_REG_SSCR 0xec +#define NB1_REG_NB_CTL_OPT1 0xf4 +#define NB1_REG_UPDATE_PHY_IO 0xf8 +#define NB1_REG_RESET_DRAMC_PHY 0xfa + +#endif /* NORTHBRIDGE_H */ diff --git a/src/northbridge/dmp/vortex86ex/raminit.c b/src/northbridge/dmp/vortex86ex/raminit.c new file mode 100644 index 0000000..2382fe2 --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/raminit.c @@ -0,0 +1,325 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 DMP Electronics Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static u16 get_mask(u16 bit_width, u16 bit_offset) +{ + u16 mask = (((1 << bit_width) - 1) << bit_offset); + return mask; +} + +static u16 set_bitfield(u16 val, u16 bits, u16 bit_width, u16 bit_offset) +{ + u16 mask = get_mask(bit_width, bit_offset); + val = (val & ~mask) | (bits << bit_offset); + return val; +} + +static u16 get_bitfield(u16 val, u16 bit_width, u16 bit_offset) +{ + u16 mask = get_mask(bit_width, bit_offset); + return (val & mask) >> bit_offset; +} + +static u8 check_address_bit(int addr_bit) +{ + u16 dummy; + *(volatile u16 *)(0) = 0; + dummy = *(volatile u16 *)(0); // read push write + *(volatile u16 *)(1 << addr_bit) = 0x5a5a; + dummy = *(volatile u16 *)(1 << addr_bit); // read push write + if ((*(volatile u16 *)(0)) != 0) + return 0; // address bit wrapped. + return 1; // address bit not wrapped. +} + +static u8 check_dram_side(int addr_bit) +{ + *(volatile u16 *)(1 << addr_bit) = 0x5a5a; + *(volatile u16 *)(0) = 0; + if ((*(volatile u16 *)(1 << addr_bit)) != 0x5a5a) + return 0; // DRAM only one side. + return 1; // two sides. +} + +// DDRIII memory bank register control: +// bit : +// 2 - 0 : DRAMC_COLSIZE : DDRIII Column Address Type : 0 0 0 = 10bit +// : 0 0 1 = 11bit +// 7 - 5 : DRAMC_ROWSIZE : DDRIII Row Address Type : 0 0 0 = 13bit +// : 0 0 1 = 14bit +// : 0 1 0 = 15bit +// : 0 1 1 = 16bit +// 11 - 8 : DRAM_SIZE : DDRIII Size : 0 1 0 1 = 64M +// : 0 1 1 0 = 128M +// : 0 1 1 1 = 256M +// : 1 0 0 0 = 512M +// : 1 0 0 1 = 1GB +// : 1 0 1 0 = 2GB +// 13 : DRAMC_CSMASK : DDRIII CS#[1] Mask : 1 = Mask CS1 enable + +#define DDR3_COL_10BIT 0 +#define DDR3_COL_11BIT 1 +#define DDR3_ROW_13BIT 0 +#define DDR3_ROW_14BIT 1 +#define DDR3_ROW_15BIT 2 +#define DDR3_ROW_16BIT 3 +#define DDR3_SIZE_64M 5 +#define DDR3_SIZE_128M 6 +#define DDR3_SIZE_256M 7 +#define DDR3_SIZE_512M 8 +#define DDR3_SIZE_1GB 9 +#define DDR3_SIZE_2GB 10 +#define DDR3_C1M_ACTIVE 0 +#define DDR3_C1M_MASK 1 + +static u16 set_ddr3_mem_reg_col(u16 reg, u16 col) +{ + return set_bitfield(reg, col, 3, 0); +} + +static u16 get_ddr3_mem_reg_col(u16 reg) +{ + return get_bitfield(reg, 3, 0); +} + +static u16 set_ddr3_mem_reg_row(u16 reg, u16 row) +{ + return set_bitfield(reg, row, 3, 5); +} + +static u16 get_ddr3_mem_reg_row(u16 reg) +{ + return get_bitfield(reg, 3, 5); +} + +static u16 set_ddr3_mem_reg_size(u16 reg, u16 size) +{ + return set_bitfield(reg, size, 4, 8); +} + +static u16 get_ddr3_mem_reg_size(u16 reg) +{ + return get_bitfield(reg, 4, 8); +} + +static u16 set_ddr3_mem_reg_c1m(u16 reg, u16 c1m) +{ + return set_bitfield(reg, c1m, 1, 13); +} + +static u16 get_ddr3_mem_reg_c1m(u16 reg) +{ + return get_bitfield(reg, 1, 13); +} + +static u16 auto_set_ddr3_mem_reg_size(u16 reg) +{ + u8 ss = 0; + // If reg is the minimum DRAM size, + // SS is also the minimum size 128M. + // If size in reg is bigger, SS is also bigger. + ss += get_ddr3_mem_reg_col(reg); + ss += get_ddr3_mem_reg_row(reg); + ss += (1 - get_ddr3_mem_reg_c1m(reg)); + ss += DDR3_SIZE_128M; + return set_ddr3_mem_reg_size(reg, ss); +} + +static u16 get_ddr3_mem_reg(u16 col, u16 row, u16 c1m) +{ + u16 reg; + reg = 0; + reg = set_ddr3_mem_reg_col(reg, col); + reg = set_ddr3_mem_reg_row(reg, row); + reg = set_ddr3_mem_reg_c1m(reg, c1m); + reg = auto_set_ddr3_mem_reg_size(reg); + return reg; +} + +static void ddr3_phy_reset(void) +{ + // PCI N/B reg FAh bit 6 = RST_DRAM_PHY. + pci_write_config8(NB1, NB1_REG_RESET_DRAMC_PHY, 0x40); + while ((pci_read_config8(NB1, NB1_REG_RESET_DRAMC_PHY) & 0x40) == 0x40) { + } + // reload mode. + u32 ddr3_cfg = pci_read_config32(NB, NB_REG_DDR3_CFG); + pci_write_config32(NB, NB_REG_DDR3_CFG, ddr3_cfg); +} + +static u8 detect_ddr3_dram_cs(u16 reg, u8 base_addr_bit) +{ + reg = set_ddr3_mem_reg_c1m(reg, DDR3_C1M_ACTIVE); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_dram_side(base_addr_bit + 1)) { + base_addr_bit += 1; + return 0; + } + + reg = set_ddr3_mem_reg_c1m(reg, DDR3_C1M_MASK); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + // no need to check CS = 0. + // Need to reset DDR3 PHY. + ddr3_phy_reset(); + return 0; +} + +static u8 detect_ddr3_dram_row(u16 reg, u8 base_addr_bit) +{ + reg = set_ddr3_mem_reg_row(reg, DDR3_ROW_16BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 16)) { + base_addr_bit += 16; + return detect_ddr3_dram_cs(reg, base_addr_bit); + } + + reg = set_ddr3_mem_reg_row(reg, DDR3_ROW_15BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 15)) { + base_addr_bit += 15; + return detect_ddr3_dram_cs(reg, base_addr_bit); + } + + reg = set_ddr3_mem_reg_row(reg, DDR3_ROW_14BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 14)) { + base_addr_bit += 14; + return detect_ddr3_dram_cs(reg, base_addr_bit); + } + + reg = set_ddr3_mem_reg_row(reg, DDR3_ROW_13BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 13)) { + base_addr_bit += 13; + return detect_ddr3_dram_cs(reg, base_addr_bit); + } + // row test error. + return 1; +} + +static u8 detect_ddr3_dram_bank(u16 reg, u8 base_addr_bit) +{ + /* DDR3 is always 3 bank bits */ + base_addr_bit += 3; + return detect_ddr3_dram_row(reg, base_addr_bit); +} + +static u8 detect_ddr3_dram_col(u16 reg, u8 base_addr_bit) +{ + reg = set_ddr3_mem_reg_col(reg, DDR3_COL_11BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 11)) { + base_addr_bit += 11; + return detect_ddr3_dram_bank(reg, base_addr_bit); + } + + reg = set_ddr3_mem_reg_col(reg, DDR3_COL_10BIT); + reg = auto_set_ddr3_mem_reg_size(reg); + pci_write_config16(NB, NB_REG_MBR, reg); + if (check_address_bit(base_addr_bit + 10)) { + base_addr_bit += 10; + return detect_ddr3_dram_bank(reg, base_addr_bit); + } + // col test error. + return 1; +} + +static u8 detect_ddr3_dram_size(void) +{ + u16 reg; + u8 base_addr_bit = 0; + reg = get_ddr3_mem_reg(DDR3_COL_10BIT, DDR3_ROW_13BIT, DDR3_C1M_MASK); + return detect_ddr3_dram_col(reg, base_addr_bit); +} + +static void print_ddr3_memory_setup(void) +{ +#if CONFIG_DEBUG_RAM_SETUP + print_debug("DDR3 Timing Reg 0-3:\n"); + print_debug("NB 6e : "); + print_debug_hex16(pci_read_config16(NB, 0x6e)); + print_debug("\nNB 74 : "); + print_debug_hex32(pci_read_config32(NB, 0x74)); + print_debug("\nNB 78 : "); + print_debug_hex32(pci_read_config32(NB, 0x78)); + print_debug("\nNB 7c : "); + print_debug_hex32(pci_read_config32(NB, 0x7c)); + u16 mbr = pci_read_config16(NB, 0x6c); + print_debug("\nNB 6c(MBR) : "); + print_debug_hex16(mbr); + const char *s; + u8 col = get_ddr3_mem_reg_col(mbr); + if (col == DDR3_COL_10BIT) + s = " (COL=10"; + else + s = " (COL=11"; + print_debug(s); + u8 row = get_ddr3_mem_reg_row(mbr); + switch (row) { + case DDR3_ROW_13BIT: + s = ", ROW = 13"; + break; + case DDR3_ROW_14BIT: + s = ", ROW = 14"; + break; + case DDR3_ROW_15BIT: + s = ", ROW = 15"; + break; + default: + s = ", ROW = 16"; + break; + } + print_debug(s); + u8 size = get_ddr3_mem_reg_size(mbr); + switch (size) { + case DDR3_SIZE_64M: + s = ", 64M"; + break; + case DDR3_SIZE_128M: + s = ", 128M"; + break; + case DDR3_SIZE_256M: + s = ", 256M"; + break; + case DDR3_SIZE_512M: + s = ", 512M"; + break; + case DDR3_SIZE_1GB: + s = ", 1GB"; + break; + case DDR3_SIZE_2GB: + s = ", 2GB"; + break; + } + print_debug(s); + u8 mask = get_ddr3_mem_reg_c1m(mbr); + if (mask == DDR3_C1M_ACTIVE) + s = ", CS MASK Enable)\n"; + else + s = ", CS Mask Disable)\n"; + print_debug(s); +#endif +} diff --git a/src/northbridge/dmp/vortex86ex/xgi_oprom.c b/src/northbridge/dmp/vortex86ex/xgi_oprom.c new file mode 100644 index 0000000..dc814c2 --- /dev/null +++ b/src/northbridge/dmp/vortex86ex/xgi_oprom.c @@ -0,0 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 DMP Electronics Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/******************************************************************** + * Change the vendor / device IDs to match the XGI Z9S VBIOS header. + ********************************************************************/ +#include <device/pci.h> +u32 map_oprom_vendev(u32 vendev) +{ + u32 new_vendev = vendev; + + switch (vendev) { + case 0x18ca0020: + new_vendev = 0x18ca0021; + break; + } + + return new_vendev; +}