Add support for DMP Vortex86EX PCI northbridge.
Change-Id: I60675a357f9db430ebb59b17be6d8c92a9cadf43 Signed-off-by: Andrew Wu <arw@dmp.com.tw> Reviewed-on: http://review.coreboot.org/3511 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
378d04640d
commit
0651072597
|
@ -1,4 +1,5 @@
|
||||||
source src/northbridge/amd/Kconfig
|
source src/northbridge/amd/Kconfig
|
||||||
|
source src/northbridge/dmp/Kconfig
|
||||||
source src/northbridge/intel/Kconfig
|
source src/northbridge/intel/Kconfig
|
||||||
source src/northbridge/rdc/Kconfig
|
source src/northbridge/rdc/Kconfig
|
||||||
source src/northbridge/via/Kconfig
|
source src/northbridge/via/Kconfig
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
subdirs-y += amd
|
subdirs-y += amd
|
||||||
|
subdirs-y += dmp
|
||||||
subdirs-y += intel
|
subdirs-y += intel
|
||||||
subdirs-y += rdc
|
subdirs-y += rdc
|
||||||
subdirs-y += via
|
subdirs-y += via
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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,
|
||||||
|
};
|
|
@ -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 */
|
|
@ -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
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue