Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14600
-gerrit
commit c55ce4da1ef304235d1d80b0271897e205b09815 Author: Stefan Reinauer stefan.reinauer@coreboot.org Date: Tue May 3 16:26:05 2016 -0700
dmp/vortex86ex: Merge northbridge and southbridge into soc
Change-Id: I16c04452d2d6c3205aea29fe8aa8fad8fc485a46 Signed-off-by: Stefan Reinauer stefan.reinauer@coreboot.org --- src/mainboard/dmp/vortex86ex/Kconfig | 3 +- src/mainboard/dmp/vortex86ex/devicetree.cb | 18 +- src/mainboard/dmp/vortex86ex/romstage.c | 6 +- src/northbridge/dmp/vortex86ex/Kconfig | 18 - src/northbridge/dmp/vortex86ex/Makefile.inc | 21 - src/northbridge/dmp/vortex86ex/chip.h | 22 - src/northbridge/dmp/vortex86ex/northbridge.c | 133 ------ src/northbridge/dmp/vortex86ex/northbridge.h | 65 --- src/northbridge/dmp/vortex86ex/raminit.c | 321 -------------- src/northbridge/dmp/vortex86ex/xgi_oprom.c | 31 -- src/soc/dmp/vortex86ex/Kconfig | 20 + src/soc/dmp/vortex86ex/Makefile.inc | 26 ++ src/soc/dmp/vortex86ex/audio.c | 25 ++ src/soc/dmp/vortex86ex/chip.h | 34 ++ src/soc/dmp/vortex86ex/hard_reset.c | 21 + src/soc/dmp/vortex86ex/ide_sd_sata.c | 167 +++++++ src/soc/dmp/vortex86ex/northbridge.c | 133 ++++++ src/soc/dmp/vortex86ex/northbridge.h | 65 +++ src/soc/dmp/vortex86ex/raminit.c | 321 ++++++++++++++ src/soc/dmp/vortex86ex/southbridge.c | 632 +++++++++++++++++++++++++++ src/soc/dmp/vortex86ex/southbridge.h | 42 ++ src/soc/dmp/vortex86ex/xgi_oprom.c | 31 ++ src/southbridge/dmp/vortex86ex/Kconfig | 19 - src/southbridge/dmp/vortex86ex/Makefile.inc | 23 - src/southbridge/dmp/vortex86ex/audio.c | 25 -- src/southbridge/dmp/vortex86ex/chip.h | 34 -- src/southbridge/dmp/vortex86ex/hard_reset.c | 21 - src/southbridge/dmp/vortex86ex/ide_sd_sata.c | 167 ------- src/southbridge/dmp/vortex86ex/southbridge.c | 632 --------------------------- src/southbridge/dmp/vortex86ex/southbridge.h | 42 -- 30 files changed, 1529 insertions(+), 1589 deletions(-)
diff --git a/src/mainboard/dmp/vortex86ex/Kconfig b/src/mainboard/dmp/vortex86ex/Kconfig index f6e5d0c..9c4c178 100644 --- a/src/mainboard/dmp/vortex86ex/Kconfig +++ b/src/mainboard/dmp/vortex86ex/Kconfig @@ -18,8 +18,7 @@ if BOARD_DMP_EX config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select CPU_DMP_VORTEX86EX - select NORTHBRIDGE_DMP_VORTEX86EX - select SOUTHBRIDGE_DMP_VORTEX86EX + select SOC_DMP_VORTEX86EX select HAVE_PIRQ_TABLE select BOARD_ROMSIZE_KB_256 select ROMCC diff --git a/src/mainboard/dmp/vortex86ex/devicetree.cb b/src/mainboard/dmp/vortex86ex/devicetree.cb index 46dd243..4106bed 100644 --- a/src/mainboard/dmp/vortex86ex/devicetree.cb +++ b/src/mainboard/dmp/vortex86ex/devicetree.cb @@ -13,18 +13,16 @@ ## GNU General Public License for more details. ##
-chip northbridge/dmp/vortex86ex # North Bridge +chip soc/dmp/vortex86ex # North Bridge device domain 0 on device pci 0.0 on end # Host Bridge - chip southbridge/dmp/vortex86ex # South Bridge - device pci 7.0 on end # ISA Bridge - device pci 8.0 on end # Ethernet - device pci a.0 on end # USB 1.1 - device pci a.1 on end # USB 2.0 - device pci b.0 on end # USB 1.1 - device pci b.1 on end # USB 2.0 - device pci c.0 on end # IDE - end + device pci 7.0 on end # ISA Bridge + device pci 8.0 on end # Ethernet + device pci a.0 on end # USB 1.1 + device pci a.1 on end # USB 2.0 + device pci b.0 on end # USB 1.1 + device pci b.1 on end # USB 2.0 + device pci c.0 on end # IDE end # pci domain 0 chip cpu/dmp/vortex86ex end # CPU end diff --git a/src/mainboard/dmp/vortex86ex/romstage.c b/src/mainboard/dmp/vortex86ex/romstage.c index a6aa59b..0b02373 100644 --- a/src/mainboard/dmp/vortex86ex/romstage.c +++ b/src/mainboard/dmp/vortex86ex/romstage.c @@ -22,9 +22,9 @@ #include <cpu/x86/cache.h> #include <halt.h> #include "drivers/pc80/pc/i8254.c" -#include <northbridge/dmp/vortex86ex/northbridge.h> -#include <southbridge/dmp/vortex86ex/southbridge.h> -#include "northbridge/dmp/vortex86ex/raminit.c" +#include <soc/dmp/vortex86ex/northbridge.h> +#include <soc/dmp/vortex86ex/southbridge.h> +#include "soc/dmp/vortex86ex/raminit.c" #include <cpu/dmp/dmp_post_code.h>
#define DMP_CPUID_SX 0x31504d44 diff --git a/src/northbridge/dmp/vortex86ex/Kconfig b/src/northbridge/dmp/vortex86ex/Kconfig deleted file mode 100644 index 7daf10c..0000000 --- a/src/northbridge/dmp/vortex86ex/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -## -## 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. -## - -config NORTHBRIDGE_DMP_VORTEX86EX - bool - select LATE_CBMEM_INIT diff --git a/src/northbridge/dmp/vortex86ex/Makefile.inc b/src/northbridge/dmp/vortex86ex/Makefile.inc deleted file mode 100644 index bfc81ca..0000000 --- a/src/northbridge/dmp/vortex86ex/Makefile.inc +++ /dev/null @@ -1,21 +0,0 @@ -## -## 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. -## - -ifeq ($(CONFIG_NORTHBRIDGE_DMP_VORTEX86EX),y) - -ramstage-y += northbridge.c -ramstage-y += xgi_oprom.c - -endif diff --git a/src/northbridge/dmp/vortex86ex/chip.h b/src/northbridge/dmp/vortex86ex/chip.h deleted file mode 100644 index d7b4b93..0000000 --- a/src/northbridge/dmp/vortex86ex/chip.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -#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 deleted file mode 100644 index 62c68e0..0000000 --- a/src/northbridge/dmp/vortex86ex/northbridge.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - */ - -#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_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; - - set_top_of_ram(tolmk * 1024); - - /* 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, - .ops_pci_bus = pci_bus_default_ops, -}; - -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; - } -} - -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 deleted file mode 100644 index d5bb6f1..0000000 --- a/src/northbridge/dmp/vortex86ex/northbridge.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -#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 deleted file mode 100644 index 1ccdb27..0000000 --- a/src/northbridge/dmp/vortex86ex/raminit.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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. - */ - -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 - printk(BIOS_DEBUG, "DDR3 Timing Reg 0-3:\n"); - printk(BIOS_DEBUG, "NB 6e : "); - print_debug_hex16(pci_read_config16(NB, 0x6e)); - printk(BIOS_DEBUG, "\nNB 74 : "); - print_debug_hex32(pci_read_config32(NB, 0x74)); - printk(BIOS_DEBUG, "\nNB 78 : "); - print_debug_hex32(pci_read_config32(NB, 0x78)); - printk(BIOS_DEBUG, "\nNB 7c : "); - print_debug_hex32(pci_read_config32(NB, 0x7c)); - u16 mbr = pci_read_config16(NB, 0x6c); - printk(BIOS_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 deleted file mode 100644 index b72157d..0000000 --- a/src/northbridge/dmp/vortex86ex/xgi_oprom.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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. - */ - -/******************************************************************** - * 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; -} diff --git a/src/soc/dmp/vortex86ex/Kconfig b/src/soc/dmp/vortex86ex/Kconfig new file mode 100644 index 0000000..7c616d6 --- /dev/null +++ b/src/soc/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. +## + +config SOC_DMP_VORTEX86EX + bool + select LATE_CBMEM_INIT + select AZALIA_PLUGIN_SUPPORT + select HAVE_HARD_RESET diff --git a/src/soc/dmp/vortex86ex/Makefile.inc b/src/soc/dmp/vortex86ex/Makefile.inc new file mode 100644 index 0000000..a896fcd --- /dev/null +++ b/src/soc/dmp/vortex86ex/Makefile.inc @@ -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. +## + +ifeq ($(CONFIG_SOC_DMP_VORTEX86EX),y) + +ramstage-y += northbridge.c +ramstage-y += xgi_oprom.c + +ramstage-y += southbridge.c +ramstage-y += hard_reset.c +ramstage-y += ide_sd_sata.c +ramstage-y += audio.c + +endif diff --git a/src/soc/dmp/vortex86ex/audio.c b/src/soc/dmp/vortex86ex/audio.c new file mode 100644 index 0000000..05a0d8c --- /dev/null +++ b/src/soc/dmp/vortex86ex/audio.c @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#include <device/azalia_device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +/* RDC HD audio controller */ +static const struct pci_driver rdc_audio __pci_driver = { + .ops = &default_azalia_audio_ops, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x3010, +}; diff --git a/src/soc/dmp/vortex86ex/chip.h b/src/soc/dmp/vortex86ex/chip.h new file mode 100644 index 0000000..d67b801 --- /dev/null +++ b/src/soc/dmp/vortex86ex/chip.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#ifndef _SOC_DMP_VORTEX86EX +#define _SOC_DMP_VORTEX86EX + +struct soc_dmp_vortex86ex_config { + /* PCI function enables */ + /* i.e. so that pci scan bus will find them. */ + /* I am putting in IDE as an example but obviously this needs + * to be more complete! + */ + int enable_ide; + /* enables of functions of devices */ + int enable_usb; + int enable_native_ide; + int enable_com_ports; + int enable_keyboard; + int enable_nvram; +}; + +#endif /* _SOC_DMP_VORTEX86EX */ diff --git a/src/soc/dmp/vortex86ex/hard_reset.c b/src/soc/dmp/vortex86ex/hard_reset.c new file mode 100644 index 0000000..9b9c426 --- /dev/null +++ b/src/soc/dmp/vortex86ex/hard_reset.c @@ -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. + */ + +#include <arch/io.h> +#include <reset.h> + +void hard_reset(void) +{ +} diff --git a/src/soc/dmp/vortex86ex/ide_sd_sata.c b/src/soc/dmp/vortex86ex/ide_sd_sata.c new file mode 100644 index 0000000..936505e --- /dev/null +++ b/src/soc/dmp/vortex86ex/ide_sd_sata.c @@ -0,0 +1,167 @@ +/* + * 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. + */ + +#include <delay.h> +#include <stdlib.h> +#include <string.h> +#include <arch/io.h> + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +/* Vortex86EX IDE to SD/STAT controller need to enable ATA decoder and + * setup timing. */ + +/* + * Primary ATA Timing Register (PATR) - Offset 40-41h + * Secondary ATA Timing Register (PATR) - Offset 42-43h + * + * Bit R/W Default Description + * 15 R/W 0h ATA Decode Enable. Decode the I/O addressing ranges assigned to this controller. + * 1: Enabled. + * 0: Disabled. + * 14 R/W 0b Device 1 ATA Timing Register Enable + * 1: Enable the device 1 ATA timing. + * 0: Disable the device 1 ATA timing + * 13-12 R/W 0h IORDY Sample Mode. Sets the setup time before IORDY are sampled. + * 00: PIO-0 + * 10: PIO-2, SW-2 + * 10: PIO-3, PIO-4, MW-1, MW-2 + * 11: Reserved + * 11-10 RO 0h Reserved + * 9-8 R/W 0h Recovery Mode. Sets the hold time after IORDY are sampled. + * 00: PIO-0, PIO-2, SW-2 + * 10: PIO-3, MW-1 + * 10: Reserved + * 11: PIO-4, MW-2 + * 7 R/W 0b DMA Timing Enable Only Select 1 + * 1: Enable the device timings for DMA operation for device 1 + * 0: Disable the device timings for DMA operation for device 1 + * 6 R/W 0b ATA/ATAPI Device Indicator 1 + * 1: Indicate presence od an ATA device + * 0: Indicate presence od an ATAPI device + * 5 R/W 0b IORDY Sample Point Enabled Select 1 + * 1: Enable IORDY sample for PIO transfers for device 1 + * 0: Disable IORDY sample for PIO transfers for device 1 + * 4 R/W 0b Fast Drive Timing Select 1 + * 1: Enable faster than PIO-0 timing modes for device 1 + * 0: Disable faster than PIO-0 timing modes for device 1 + * 3 R/W 0b DMA Timing Enable Only Select 0 + * 1: Enable the device timings for DMA operation for device 0 + * 0: Disable the device timings for DMA operation for device 0 + * 2 R/W 0b ATA/ATAPI Device Indicator 0 + * 1: Indicate presence od an ATA device + * 0: Indicate presence od an ATAPI device + * 1 R/W 0b IORDY Sample Point Enabled Select 0 + * 1: Enable IORDY sample for PIO transfers for device 0 + * 0: Disable IORDY sample for PIO transfers for device 0 + * 0 R/W 0b Fast Drive Timing Select 0 + * 1: Enable faster than PIO-0 timing modes for device 0 + * 0: Disable faster than PIO-0 timing modes for device 0 + * */ + +static void init_ide_ata_timing(struct device *dev) +{ + u16 ata_timing_pri, ata_timing_sec; + u32 ata_timing_reg32; + /* Primary channel is SD. */ +#if CONFIG_IDE1_ENABLE + ata_timing_pri = 0x8000; +#else + ata_timing_pri = 0x0000; // Disable this channel. +#endif + /* Secondary channel is SATA. */ +#if CONFIG_IDE2_ENABLE + ata_timing_sec = 0xa30f; // This setting value works well. +#else + ata_timing_sec = 0x0000; // Disable this channel. +#endif + ata_timing_reg32 = (ata_timing_sec << 16) | ata_timing_pri; + pci_write_config32(dev, 0x40, ata_timing_reg32); +#if CONFIG_IDE_NATIVE_MODE + /* Set both IDE channels to native mode. */ + u8 prog_if; + prog_if = pci_read_config8(dev, 0x09); + prog_if |= 5; + pci_write_config8(dev, 0x09, prog_if); +#endif + /* MMC function enable. */ + u32 sd_ctrl_reg; + sd_ctrl_reg = pci_read_config32(dev, 0x94); + sd_ctrl_reg |= 0x0200; + pci_write_config32(dev, 0x94, sd_ctrl_reg); + printk(BIOS_INFO, "Vortex86EX IDE controller ATA TIMING reg = %08x\n", ata_timing_reg32); +} + +static void setup_std_ide_compatible(struct device *dev) +{ +#if CONFIG_IDE_STANDARD_COMPATIBLE + // Misc Control Register (MCR) Offset 90h + // bit 0 = Vendor ID Access, bit 1 = Device ID Access. + u8 mcr; + u16 vendor = (u16) (CONFIG_IDE_COMPATIBLE_SELECTION >> 16); + u16 device = (u16) (CONFIG_IDE_COMPATIBLE_SELECTION & 0xffff); + // unlock vendor/device ID access bits. + mcr = pci_read_config8(dev, 0x90); + pci_write_config8(dev, 0x90, mcr | 3); + pci_write_config16(dev, 0x00, vendor); + pci_write_config16(dev, 0x02, device); + // restore lock bits. + pci_write_config8(dev, 0x90, mcr); +#endif +} + +static void vortex_ide_init(struct device *dev) +{ + if (dev->device == 0x1010) { + // This is SX/old DX IDE controller. + // Set IOCFG bit 15/13 : IDE Decoder Enable for Primary/Secondary channel. + u16 iocfg = 0xa000; + pci_write_config16(dev, 0x40, iocfg); + } else if (dev->device == 0x1011 || dev->device == 0x1012) { + // This is new DX/MX/MX+/DX2 IDE controller. + init_ide_ata_timing(dev); + setup_std_ide_compatible(dev); + } +} + +static struct device_operations vortex_ide_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = vortex_ide_init, + .scan_bus = 0, +}; + +static const struct pci_driver vortex_ide_driver_1010 __pci_driver = { + .ops = &vortex_ide_ops, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x1010, +}; + +static const struct pci_driver vortex_ide_driver_1011 __pci_driver = { + .ops = &vortex_ide_ops, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x1011, +}; + +static const struct pci_driver vortex_ide_driver_1012 __pci_driver = { + .ops = &vortex_ide_ops, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x1012, +}; diff --git a/src/soc/dmp/vortex86ex/northbridge.c b/src/soc/dmp/vortex86ex/northbridge.c new file mode 100644 index 0000000..62c68e0 --- /dev/null +++ b/src/soc/dmp/vortex86ex/northbridge.c @@ -0,0 +1,133 @@ +/* + * 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. + */ + +#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_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; + + set_top_of_ram(tolmk * 1024); + + /* 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, + .ops_pci_bus = pci_bus_default_ops, +}; + +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; + } +} + +struct chip_operations northbridge_dmp_vortex86ex_ops = { + CHIP_NAME("DMP Vortex86EX Northbridge") + .enable_dev = enable_dev, +}; diff --git a/src/soc/dmp/vortex86ex/northbridge.h b/src/soc/dmp/vortex86ex/northbridge.h new file mode 100644 index 0000000..d5bb6f1 --- /dev/null +++ b/src/soc/dmp/vortex86ex/northbridge.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#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/soc/dmp/vortex86ex/raminit.c b/src/soc/dmp/vortex86ex/raminit.c new file mode 100644 index 0000000..1ccdb27 --- /dev/null +++ b/src/soc/dmp/vortex86ex/raminit.c @@ -0,0 +1,321 @@ +/* + * 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. + */ + +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 + printk(BIOS_DEBUG, "DDR3 Timing Reg 0-3:\n"); + printk(BIOS_DEBUG, "NB 6e : "); + print_debug_hex16(pci_read_config16(NB, 0x6e)); + printk(BIOS_DEBUG, "\nNB 74 : "); + print_debug_hex32(pci_read_config32(NB, 0x74)); + printk(BIOS_DEBUG, "\nNB 78 : "); + print_debug_hex32(pci_read_config32(NB, 0x78)); + printk(BIOS_DEBUG, "\nNB 7c : "); + print_debug_hex32(pci_read_config32(NB, 0x7c)); + u16 mbr = pci_read_config16(NB, 0x6c); + printk(BIOS_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/soc/dmp/vortex86ex/southbridge.c b/src/soc/dmp/vortex86ex/southbridge.c new file mode 100644 index 0000000..05702d1 --- /dev/null +++ b/src/soc/dmp/vortex86ex/southbridge.c @@ -0,0 +1,632 @@ +/* + * 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. + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ops.h> +#include <device/pci_ids.h> +#include <pc80/mc146818rtc.h> +#include <pc80/keyboard.h> +#include <string.h> +#include <delay.h> +#include "arch/io.h" +#include "chip.h" +#include "southbridge.h" +#include "cpu/dmp/dmp_post_code.h" + +/* IRQ number to S/B PCI Interrupt routing table reg(0x58/0xb4) mapping table. */ +static const unsigned char irq_to_int_routing[16] = { + 0x0, 0x0, 0x0, 0x2, // IRQ0-2 is unmappable, IRQ3 = 2. + 0x4, 0x5, 0x7, 0x6, // IRQ4-7 = 4, 5, 7, 6. + 0x0, 0x1, 0x3, 0x9, // IRQ8 is unmappable, IRQ9-11 = 1, 3, 9. + 0xb, 0x0, 0xd, 0xf // IRQ12 = b, IRQ13 is unmappable, IRQ14-15 = d, f. +}; + +/* S/B PCI Interrupt routing table reg(0x58) field bit shift. */ +#define EHCIH_IRQ_SHIFT 28 +#define OHCII_IRQ_SHIFT 24 +#define MAC_IRQ_SHIFT 16 +#define RT3_IRQ_SHIFT 12 +#define RT2_IRQ_SHIFT 8 +#define RT1_IRQ_SHIFT 4 +#define RT0_IRQ_SHIFT 0 + +/* S/B Extend PCI Interrupt routing table reg(0xb4) field bit shift. */ +#define CAN_IRQ_SHIFT 28 +#define HDA_IRQ_SHIFT 20 +#define USBD_IRQ_SHIFT 16 +#define SIDE_IRQ_SHIFT 12 +#define PIDE_IRQ_SHIFT 8 + +/* S/B function 1 Extend PCI Interrupt routing table reg 2(0xb4) + * field bit shift. + */ +#define SPI1_IRQ_SHIFT 8 +#define MOTOR_IRQ_SHIFT 0 + +/* in-chip PCI device IRQs(0 for disabled). */ +#define EHCII_IRQ 5 +#define OHCII_IRQ 5 +#define MAC_IRQ 6 + +#define CAN_IRQ 10 +#define HDA_IRQ 7 +#define USBD_IRQ 6 +#define PIDE_IRQ 5 + +#define SPI1_IRQ 10 +#define I2C0_IRQ 10 +#define MOTOR_IRQ 11 + +/* RT0-3 IRQs. */ +#define RT3_IRQ 3 +#define RT2_IRQ 4 +#define RT1_IRQ 5 +#define RT0_IRQ 6 + +/* IDE legacy mode IRQs. */ +#define IDE1_LEGACY_IRQ 14 +#define IDE2_LEGACY_IRQ 15 + +/* Internal parallel port */ +#define LPT_INT_C 0 +#define LPT_INT_ACK_SET 0 +#define LPT_UE 1 +#define LPT_PDMAS 0 +#define LPT_DREQS 0 + +/* keyboard controller system flag timeout : 400 ms */ +#define KBC_TIMEOUT_SYS_FLAG 400 + +static u8 get_pci_dev_func(device_t dev) +{ + return PCI_FUNC(dev->path.pci.devfn); +} + +static void verify_dmp_keyboard_error(void) +{ + post_code(POST_DMP_KBD_FW_VERIFY_ERR); + die("Internal keyboard firmware verify error!\n"); +} + +static void upload_dmp_keyboard_firmware(struct device *dev) +{ + u32 reg_sb_c0; + u32 fwptr; + + // enable firmware uploading function by set bit 10. + post_code(POST_DMP_KBD_FW_UPLOAD); + reg_sb_c0 = pci_read_config32(dev, SB_REG_IPFCR); + pci_write_config32(dev, SB_REG_IPFCR, reg_sb_c0 | 0x400); + + outw(0, 0x62); // reset upload address to 0. + // upload 4096 bytes from 0xFFFFE000. + outsb(0x66, (u8 *) 0xffffe000, 4096); + // upload 4096 bytes from 0xFFFFC000. + outsb(0x66, (u8 *) 0xffffc000, 4096); + + outw(0, 0x62); // reset upload address to 0. + // verify 4096 bytes from 0xFFFFE000. + for (fwptr = 0xffffe000; fwptr < 0xfffff000; fwptr++) { + if (inb(0x66) != *(u8 *) fwptr) { + verify_dmp_keyboard_error(); + } + } + // verify 4096 bytes from 0xFFFFC000. + for (fwptr = 0xffffc000; fwptr < 0xffffd000; fwptr++) { + if (inb(0x66) != *(u8 *) fwptr) { + verify_dmp_keyboard_error(); + } + } + + // disable firmware uploading. + pci_write_config32(dev, SB_REG_IPFCR, reg_sb_c0 & ~0x400L); +} + +static int kbc_wait_system_flag(void) +{ + /* wait keyboard controller ready by checking system flag + * (status port bit 2). + */ + post_code(POST_DMP_KBD_CHK_READY); + u32 timeout; + for (timeout = KBC_TIMEOUT_SYS_FLAG; + timeout && ((inb(0x64) & 0x4) == 0); timeout--) + mdelay(1); + + if (!timeout) { + printk(BIOS_WARNING, "Keyboard controller system flag timeout\n"); + } + return !!timeout; +} + +static void pci_routing_fixup(struct device *dev) +{ + const unsigned slot[3] = { 0 }; + const unsigned char slot_irqs[1][4] = { + {RT0_IRQ, RT1_IRQ, RT2_IRQ, RT3_IRQ}, + }; + const int slot_num = 1; + int i; + u32 int_routing = 0; + u32 ext_int_routing = 0; + + /* assign PCI-e bridge (bus#0, dev#1, fn#0) IRQ to RT0. */ + pci_assign_irqs(0, 1, slot_irqs[0]); + + /* RT0 is enabled. */ + int_routing |= irq_to_int_routing[RT0_IRQ] << RT0_IRQ_SHIFT; + + /* assign PCI slot IRQs. */ + for (i = 0; i < slot_num; i++) { + pci_assign_irqs(1, slot[i], slot_irqs[i]); + } + + /* Read PCI slot IRQs to see if RT1-3 is used, and enables it */ + for (i = 0; i < slot_num; i++) { + unsigned int funct; + device_t pdev; + u8 irq; + + /* Each slot may contain up to eight functions. */ + for (funct = 0; funct < 8; funct++) { + pdev = dev_find_slot(1, (slot[i] << 3) + funct); + if (!pdev) + continue; + irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE); + if (irq == RT1_IRQ) { + int_routing |= irq_to_int_routing[RT1_IRQ] << RT1_IRQ_SHIFT; + } else if (irq == RT2_IRQ) { + int_routing |= irq_to_int_routing[RT2_IRQ] << RT2_IRQ_SHIFT; + } else if (irq == RT3_IRQ) { + int_routing |= irq_to_int_routing[RT3_IRQ] << RT3_IRQ_SHIFT; + } + } + } + + /* Setup S/B PCI Interrupt routing table reg(0x58). */ + int_routing |= irq_to_int_routing[EHCII_IRQ] << EHCIH_IRQ_SHIFT; + int_routing |= irq_to_int_routing[OHCII_IRQ] << OHCII_IRQ_SHIFT; + int_routing |= irq_to_int_routing[MAC_IRQ] << MAC_IRQ_SHIFT; + pci_write_config32(dev, SB_REG_PIRQ_ROUTE, int_routing); + + /* Setup S/B PCI Extend Interrupt routing table reg(0xb4). */ + ext_int_routing |= irq_to_int_routing[CAN_IRQ] << CAN_IRQ_SHIFT; + ext_int_routing |= irq_to_int_routing[HDA_IRQ] << HDA_IRQ_SHIFT; + ext_int_routing |= irq_to_int_routing[USBD_IRQ] << USBD_IRQ_SHIFT; +#if CONFIG_IDE_NATIVE_MODE + /* IDE in native mode, only uses one IRQ. */ + ext_int_routing |= irq_to_int_routing[0] << SIDE_IRQ_SHIFT; + ext_int_routing |= irq_to_int_routing[PIDE_IRQ] << PIDE_IRQ_SHIFT; +#else + /* IDE in legacy mode, use IRQ 14, 15. */ + ext_int_routing |= irq_to_int_routing[IDE2_LEGACY_IRQ] << SIDE_IRQ_SHIFT; + ext_int_routing |= irq_to_int_routing[IDE1_LEGACY_IRQ] << PIDE_IRQ_SHIFT; +#endif + pci_write_config32(dev, SB_REG_EXT_PIRQ_ROUTE, ext_int_routing); + + /* Assign in-chip PCI device IRQs. */ + if (MAC_IRQ) { + unsigned char irqs[4] = { MAC_IRQ, 0, 0, 0 }; + pci_assign_irqs(0, 0x8, irqs); + } + if ((OHCII_IRQ != 0) && (EHCII_IRQ != 0)) { + unsigned char irqs[4] = { OHCII_IRQ, EHCII_IRQ, 0, 0 }; + pci_assign_irqs(0, 0xa, irqs); + } + if ((CONFIG_IDE_NATIVE_MODE != 0) && (PIDE_IRQ != 0)) { + /* IDE in native mode, setup PCI IRQ. */ + unsigned char irqs[4] = { PIDE_IRQ, 0, 0, 0 }; + pci_assign_irqs(0, 0xc, irqs); + } + if (CAN_IRQ) { + unsigned char irqs[4] = { CAN_IRQ, 0, 0, 0 }; + pci_assign_irqs(0, 0x11, irqs); + } + if (HDA_IRQ) { + unsigned char irqs[4] = { HDA_IRQ, 0, 0, 0 }; + pci_assign_irqs(0, 0xe, irqs); + } + if (USBD_IRQ) { + unsigned char irqs[4] = { USBD_IRQ, 0, 0, 0 }; + pci_assign_irqs(0, 0xf, irqs); + } +} + +static void vortex_sb_init(struct device *dev) +{ + u32 lpt_reg = 0; + +#if CONFIG_LPT_ENABLE + int ppmod = 0; +#if CONFIG_LPT_MODE_BPP + ppmod = 0; +#elif CONFIG_LPT_MODE_EPP_19_AND_SPP + ppmod = 1; +#elif CONFIG_LPT_MODE_ECP + ppmod = 2; +#elif CONFIG_LPT_MODE_ECP_AND_EPP_19 + ppmod = 3; +#elif CONFIG_LPT_MODE_SPP + ppmod = 4; +#elif CONFIG_LPT_MODE_EPP_17_AND_SPP + ppmod = 5; +#elif CONFIG_LPT_MODE_ECP_AND_EPP_17 + ppmod = 7; +#else +#error CONFIG_LPT_MODE error. +#endif + + /* Setup internal parallel port */ + lpt_reg |= (LPT_INT_C << 28); + lpt_reg |= (LPT_INT_ACK_SET << 27); + lpt_reg |= (ppmod << 24); + lpt_reg |= (LPT_UE << 23); + lpt_reg |= (LPT_PDMAS << 22); + lpt_reg |= (LPT_DREQS << 20); + lpt_reg |= (irq_to_int_routing[CONFIG_LPT_IRQ] << 16); + lpt_reg |= (CONFIG_LPT_IO << 0); +#endif // CONFIG_LPT_ENABLE + pci_write_config32(dev, SB_REG_IPPCR, lpt_reg); +} + +#define SETUP_GPIO_ADDR(n) \ + u32 cfg##n = (CONFIG_GPIO_P##n##_DIR_ADDR << 16) | (CONFIG_GPIO_P##n##_DATA_ADDR);\ + outl(cfg##n, base + 4 + (n * 4));\ + gpio_enable_mask |= (1 << n); + +#define INIT_GPIO(n) \ + outb(CONFIG_GPIO_P##n##_INIT_DIR, CONFIG_GPIO_P##n##_DIR_ADDR);\ + outb(CONFIG_GPIO_P##n##_INIT_DATA, CONFIG_GPIO_P##n##_DATA_ADDR); + +static void ex_sb_gpio_init(struct device *dev) +{ + const int base = 0xb00; + u32 gpio_enable_mask = 0; + /* S/B register 63h - 62h : GPIO Port Config IO Base Address */ + pci_write_config16(dev, SB_REG_GPIO_CFG_IO_BASE, base | 1); + /* Set GPIO port 0~9 base address. + * Config Base + 04h, 08h, 0ch... : GPIO port 0~9 data/dir decode addr. + * Bit 31-16 : DBA, GPIO direction base address. + * Bit 15-0 : DPBA, GPIO data port base address. + * */ +#if CONFIG_GPIO_P0_ENABLE + SETUP_GPIO_ADDR(0) +#endif +#if CONFIG_GPIO_P1_ENABLE + SETUP_GPIO_ADDR(1) +#endif +#if CONFIG_GPIO_P2_ENABLE + SETUP_GPIO_ADDR(2) +#endif +#if CONFIG_GPIO_P3_ENABLE + SETUP_GPIO_ADDR(3) +#endif +#if CONFIG_GPIO_P4_ENABLE + SETUP_GPIO_ADDR(4) +#endif +#if CONFIG_GPIO_P5_ENABLE + SETUP_GPIO_ADDR(5) +#endif +#if CONFIG_GPIO_P6_ENABLE + SETUP_GPIO_ADDR(6) +#endif +#if CONFIG_GPIO_P7_ENABLE + SETUP_GPIO_ADDR(7) +#endif +#if CONFIG_GPIO_P8_ENABLE + SETUP_GPIO_ADDR(8) +#endif +#if CONFIG_GPIO_P9_ENABLE + SETUP_GPIO_ADDR(9) +#endif + /* Enable GPIO port 0~9. */ + outl(gpio_enable_mask, base); + /* Set GPIO port 0-9 initial dir and data. */ +#if CONFIG_GPIO_P0_ENABLE + INIT_GPIO(0) +#endif +#if CONFIG_GPIO_P1_ENABLE + INIT_GPIO(1) +#endif +#if CONFIG_GPIO_P2_ENABLE + INIT_GPIO(2) +#endif +#if CONFIG_GPIO_P3_ENABLE + INIT_GPIO(3) +#endif +#if CONFIG_GPIO_P4_ENABLE + INIT_GPIO(4) +#endif +#if CONFIG_GPIO_P5_ENABLE + INIT_GPIO(5) +#endif +#if CONFIG_GPIO_P6_ENABLE + INIT_GPIO(6) +#endif +#if CONFIG_GPIO_P7_ENABLE + INIT_GPIO(7) +#endif +#if CONFIG_GPIO_P8_ENABLE + INIT_GPIO(8) +#endif +#if CONFIG_GPIO_P9_ENABLE + INIT_GPIO(9) +#endif + /* Disable GPIO Port Config IO Base Address. */ + pci_write_config16(dev, SB_REG_GPIO_CFG_IO_BASE, 0x0); +} + +static u32 make_uart_config(u16 base, u8 irq) +{ + u8 mapped_irq = irq_to_int_routing[irq]; + u32 cfg = 0; + cfg |= 1 << 23; // UE = enabled. + cfg |= (mapped_irq << 16); // UIRT. + cfg |= base; // UIOA. + return cfg; +} + +#define SETUP_UART(n) \ + uart_cfg = make_uart_config(CONFIG_UART##n##_IO, CONFIG_UART##n##_IRQ);\ + outl(uart_cfg, base + (n - 1) * 4); + +static void ex_sb_uart_init(struct device *dev) +{ + const int base = 0xc00; + u32 uart_cfg = 0; + /* S/B register 61h - 60h : UART Config IO Base Address */ + pci_write_config16(dev, SB_REG_UART_CFG_IO_BASE, base | 1); + /* setup UART */ +#if CONFIG_UART1_ENABLE + SETUP_UART(1) +#endif +#if CONFIG_UART2_ENABLE + SETUP_UART(2) +#endif +#if CONFIG_UART3_ENABLE + SETUP_UART(3) +#endif +#if CONFIG_UART4_ENABLE + SETUP_UART(4) +#endif +#if CONFIG_UART5_ENABLE + SETUP_UART(5) +#endif +#if CONFIG_UART6_ENABLE + SETUP_UART(6) +#endif +#if CONFIG_UART7_ENABLE + SETUP_UART(7) +#endif +#if CONFIG_UART8_ENABLE + SETUP_UART(8) +#endif +#if CONFIG_UART9_ENABLE + SETUP_UART(9) +#endif +#if CONFIG_UART10_ENABLE + SETUP_UART(10) +#endif + /* Keep UART Config I/O base address */ + //pci_write_config16(SB, SB_REG_UART_CFG_IO_BASE, 0x0); +} + +static void i2c_init(struct device *dev) +{ + u8 mapped_irq = irq_to_int_routing[I2C0_IRQ]; + u32 cfg = 0; + cfg |= 1 << 31; // UE = enabled. + cfg |= (mapped_irq << 16); // IIRT0. + cfg |= CONFIG_I2C_BASE; // UIOA. + pci_write_config32(dev, SB_REG_II2CCR, cfg); +} + +static int get_rtc_update_in_progress(void) +{ + if (cmos_read(RTC_REG_A) & RTC_UIP) + return 1; + return 0; +} + +static void unsafe_read_cmos_rtc(u8 rtc[7]) +{ + rtc[0] = cmos_read(RTC_CLK_ALTCENTURY); + rtc[1] = cmos_read(RTC_CLK_YEAR); + rtc[2] = cmos_read(RTC_CLK_MONTH); + rtc[3] = cmos_read(RTC_CLK_DAYOFMONTH); + rtc[4] = cmos_read(RTC_CLK_HOUR); + rtc[5] = cmos_read(RTC_CLK_MINUTE); + rtc[6] = cmos_read(RTC_CLK_SECOND); +} + +static void read_cmos_rtc(u8 rtc[7]) +{ + /* Read RTC twice and check update-in-progress flag, to make + * sure RTC is correct */ + u8 rtc_old[7], rtc_new[7]; + while (get_rtc_update_in_progress()) ; + unsafe_read_cmos_rtc(rtc_new); + do { + memcpy(rtc_old, rtc_new, 7); + while (get_rtc_update_in_progress()) ; + unsafe_read_cmos_rtc(rtc_new); + } while (memcmp(rtc_new, rtc_old, 7) != 0); +} + +/* + * Convert a number in decimal format into the BCD format. + * Return 255 if not a valid BCD value. + */ +static u8 bcd2dec(u8 bcd) +{ + u8 h, l; + h = bcd >> 4; + l = bcd & 0xf; + if (h > 9 || l > 9) + return 255; + return h * 10 + l; +} + +static void fix_cmos_rtc_time(void) +{ + /* Read RTC data. */ + u8 rtc[7]; + read_cmos_rtc(rtc); + + /* Convert RTC from BCD format to binary. */ + u8 bin_rtc[7]; + int i; + for (i = 0; i < 7; i++) { + bin_rtc[i] = bcd2dec(rtc[i]); + } + + /* If RTC date is invalid, fix it. */ + if (bin_rtc[0] > 99 || bin_rtc[1] > 99 || bin_rtc[2] > 12 || bin_rtc[3] > 31) { + /* Set PC compatible timing mode. */ + cmos_write(0x26, RTC_REG_A); + cmos_write(0x02, RTC_REG_B); + /* Now setup a default date 2008/08/08 08:08:08. */ + cmos_write(0x8, RTC_CLK_SECOND); + cmos_write(0x8, RTC_CLK_MINUTE); + cmos_write(0x8, RTC_CLK_HOUR); + cmos_write(0x6, RTC_CLK_DAYOFWEEK); /* Friday */ + cmos_write(0x8, RTC_CLK_DAYOFMONTH); + cmos_write(0x8, RTC_CLK_MONTH); + cmos_write(0x8, RTC_CLK_YEAR); + cmos_write(0x20, RTC_CLK_ALTCENTURY); + } +} + +static void vortex86_sb_set_io_resv(device_t dev, unsigned index, u32 base, u32 size) +{ + struct resource *res; + res = new_resource(dev, index); + res->base = base; + res->size = size; + res->limit = 0xffffUL; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void vortex86_sb_set_spi_flash_size(device_t dev, unsigned index, u32 flash_size) +{ + /* SPI flash is in topmost of 4G memory space */ + struct resource *res; + res = new_resource(dev, index); + res->base = 0x100000000LL - flash_size; + res->size = flash_size; + res->limit = 0xffffffffUL; + res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void vortex86_sb_read_resources(device_t dev) +{ + u32 flash_size = 8 * 1024 * 1024; + + pci_dev_read_resources(dev); + + if (dev->device == 0x6011) { + /* It is EX CPU southbridge */ + if (get_pci_dev_func(dev) != 0) { + /* only for function 0, skip function 1 */ + return; + } + /* default SPI flash ROM is 64MB */ + flash_size = 64 * 1024 * 1024; + } + + /* Reserve space for legacy I/O */ + vortex86_sb_set_io_resv(dev, 1, 0, 0x1000UL); + + /* Reserve space for flash */ + vortex86_sb_set_spi_flash_size(dev, 2, flash_size); + + /* Reserve space for I2C */ + vortex86_sb_set_io_resv(dev, 3, CONFIG_I2C_BASE, 8); +} + +static void southbridge_init_func1(struct device *dev) +{ + /* Handle S/B function 1 PCI IRQ routing. (SPI1/MOTOR) */ + u32 ext_int_routing2 = 0; + /* Setup S/B function 1 PCI Extend Interrupt routing table reg 2(0xb4). */ + ext_int_routing2 |= irq_to_int_routing[SPI1_IRQ] << SPI1_IRQ_SHIFT; + ext_int_routing2 |= irq_to_int_routing[MOTOR_IRQ] << MOTOR_IRQ_SHIFT; + pci_write_config32(dev, SB1_REG_EXT_PIRQ_ROUTE2, ext_int_routing2); + + /* Assign in-chip PCI device IRQs. */ + if ((SPI1_IRQ != 0) || (MOTOR_IRQ != 0)) { + unsigned char irqs[4] = { MOTOR_IRQ, SPI1_IRQ, 0, 0 }; + pci_assign_irqs(0, 0x10, irqs); + } +} + +static void southbridge_init(struct device *dev) +{ + /* Check it is function 0 or 1. (Same Vendor/Device ID) */ + if (get_pci_dev_func(dev) != 0) { + southbridge_init_func1(dev); + return; + } + upload_dmp_keyboard_firmware(dev); + vortex_sb_init(dev); + if (dev->device == 0x6011) { + ex_sb_gpio_init(dev); + ex_sb_uart_init(dev); + i2c_init(dev); + } + pci_routing_fixup(dev); + + fix_cmos_rtc_time(); + cmos_init(0); + /* Check keyboard controller ready. If timeout, reload firmware code + * and try again. + */ + u32 retries = 10; + while (!kbc_wait_system_flag()) { + if (!retries) { + post_code(POST_DMP_KBD_IS_BAD); + die("The keyboard timeout occurred too often. " + "Your CPU is probably defect. " + "Contact your dealer to replace it\n"); + } + upload_dmp_keyboard_firmware(dev); + retries--; + } + post_code(POST_DMP_KBD_IS_READY); + pc_keyboard_init(NO_AUX_DEVICE); +} + +static struct device_operations vortex_sb_ops = { + .read_resources = vortex86_sb_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = &southbridge_init, + .scan_bus = scan_lpc_bus, + .enable = 0, + .ops_pci = 0, +}; + +static const struct pci_driver pci_driver_6011 __pci_driver = { + .ops = &vortex_sb_ops, + .vendor = PCI_VENDOR_ID_RDC, + .device = 0x6011, /* EX CPU S/B ID */ +}; + +struct chip_operations southbridge_dmp_vortex86ex_ops = { + CHIP_NAME("DMP Vortex86EX Southbridge") + .enable_dev = 0 +}; diff --git a/src/soc/dmp/vortex86ex/southbridge.h b/src/soc/dmp/vortex86ex/southbridge.h new file mode 100644 index 0000000..c2b9102 --- /dev/null +++ b/src/soc/dmp/vortex86ex/southbridge.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +#ifndef SOUTHBRIDGE_H +#define SOUTHBRIDGE_H + +#define SB PCI_DEV(0, 7, 0) +#define SB_REG_LPCCR 0x41 +#define SB_REG_FRCSCR 0x42 +#define SB_REG_PIRQ_ROUTE 0x58 +#define SB_REG_UART_CFG_IO_BASE 0x60 +#define SB_REG_GPIO_CFG_IO_BASE 0x62 +#define SB_REG_CS_BASE0 0x90 +#define SB_REG_CS_BASE_MASK0 0x94 +#define SB_REG_CS_BASE1 0x98 +#define SB_REG_CS_BASE_MASK1 0x9c +#define SB_REG_IPPCR 0xb0 +#define SB_REG_EXT_PIRQ_ROUTE 0xb4 +#define SB_REG_OCDCR 0xbc +#define SB_REG_IPFCR 0xc0 +#define SB_REG_FRWPR 0xc4 +#define SB_REG_STRAP 0xce +#define SB_REG_II2CCR 0xd4 + +#define SB1 PCI_DEV(0, 7, 1) +#define SB1_REG_EXT_PIRQ_ROUTE2 0xb4 + +#define SYSTEM_CTL_PORT 0x92 + +#endif /* SOUTHBRIDGE_H */ diff --git a/src/soc/dmp/vortex86ex/xgi_oprom.c b/src/soc/dmp/vortex86ex/xgi_oprom.c new file mode 100644 index 0000000..b72157d --- /dev/null +++ b/src/soc/dmp/vortex86ex/xgi_oprom.c @@ -0,0 +1,31 @@ +/* + * 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. + */ + +/******************************************************************** + * 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; +} diff --git a/src/southbridge/dmp/vortex86ex/Kconfig b/src/southbridge/dmp/vortex86ex/Kconfig deleted file mode 100644 index 37bd7c8..0000000 --- a/src/southbridge/dmp/vortex86ex/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -## -## 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. -## - -config SOUTHBRIDGE_DMP_VORTEX86EX - bool - select AZALIA_PLUGIN_SUPPORT - select HAVE_HARD_RESET diff --git a/src/southbridge/dmp/vortex86ex/Makefile.inc b/src/southbridge/dmp/vortex86ex/Makefile.inc deleted file mode 100644 index 7232a63..0000000 --- a/src/southbridge/dmp/vortex86ex/Makefile.inc +++ /dev/null @@ -1,23 +0,0 @@ -## -## 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. -## - -ifeq ($(CONFIG_SOUTHBRIDGE_DMP_VORTEX86EX),y) - -ramstage-y += southbridge.c -ramstage-y += hard_reset.c -ramstage-y += ide_sd_sata.c -ramstage-y += audio.c - -endif diff --git a/src/southbridge/dmp/vortex86ex/audio.c b/src/southbridge/dmp/vortex86ex/audio.c deleted file mode 100644 index 05a0d8c..0000000 --- a/src/southbridge/dmp/vortex86ex/audio.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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. - */ - -#include <device/azalia_device.h> -#include <device/pci.h> -#include <device/pci_ids.h> - -/* RDC HD audio controller */ -static const struct pci_driver rdc_audio __pci_driver = { - .ops = &default_azalia_audio_ops, - .vendor = PCI_VENDOR_ID_RDC, - .device = 0x3010, -}; diff --git a/src/southbridge/dmp/vortex86ex/chip.h b/src/southbridge/dmp/vortex86ex/chip.h deleted file mode 100644 index 11bf3cc..0000000 --- a/src/southbridge/dmp/vortex86ex/chip.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - */ - -#ifndef _SOUTHBRIDGE_DMP_VORTEX86EX -#define _SOUTHBRIDGE_DMP_VORTEX86EX - -struct southbridge_dmp_vortex86ex_config { - /* PCI function enables */ - /* i.e. so that pci scan bus will find them. */ - /* I am putting in IDE as an example but obviously this needs - * to be more complete! - */ - int enable_ide; - /* enables of functions of devices */ - int enable_usb; - int enable_native_ide; - int enable_com_ports; - int enable_keyboard; - int enable_nvram; -}; - -#endif /* _SOUTHBRIDGE_DMP_VORTEX86EX */ diff --git a/src/southbridge/dmp/vortex86ex/hard_reset.c b/src/southbridge/dmp/vortex86ex/hard_reset.c deleted file mode 100644 index 9b9c426..0000000 --- a/src/southbridge/dmp/vortex86ex/hard_reset.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -#include <arch/io.h> -#include <reset.h> - -void hard_reset(void) -{ -} diff --git a/src/southbridge/dmp/vortex86ex/ide_sd_sata.c b/src/southbridge/dmp/vortex86ex/ide_sd_sata.c deleted file mode 100644 index 936505e..0000000 --- a/src/southbridge/dmp/vortex86ex/ide_sd_sata.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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. - */ - -#include <delay.h> -#include <stdlib.h> -#include <string.h> -#include <arch/io.h> - -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> - -/* Vortex86EX IDE to SD/STAT controller need to enable ATA decoder and - * setup timing. */ - -/* - * Primary ATA Timing Register (PATR) - Offset 40-41h - * Secondary ATA Timing Register (PATR) - Offset 42-43h - * - * Bit R/W Default Description - * 15 R/W 0h ATA Decode Enable. Decode the I/O addressing ranges assigned to this controller. - * 1: Enabled. - * 0: Disabled. - * 14 R/W 0b Device 1 ATA Timing Register Enable - * 1: Enable the device 1 ATA timing. - * 0: Disable the device 1 ATA timing - * 13-12 R/W 0h IORDY Sample Mode. Sets the setup time before IORDY are sampled. - * 00: PIO-0 - * 10: PIO-2, SW-2 - * 10: PIO-3, PIO-4, MW-1, MW-2 - * 11: Reserved - * 11-10 RO 0h Reserved - * 9-8 R/W 0h Recovery Mode. Sets the hold time after IORDY are sampled. - * 00: PIO-0, PIO-2, SW-2 - * 10: PIO-3, MW-1 - * 10: Reserved - * 11: PIO-4, MW-2 - * 7 R/W 0b DMA Timing Enable Only Select 1 - * 1: Enable the device timings for DMA operation for device 1 - * 0: Disable the device timings for DMA operation for device 1 - * 6 R/W 0b ATA/ATAPI Device Indicator 1 - * 1: Indicate presence od an ATA device - * 0: Indicate presence od an ATAPI device - * 5 R/W 0b IORDY Sample Point Enabled Select 1 - * 1: Enable IORDY sample for PIO transfers for device 1 - * 0: Disable IORDY sample for PIO transfers for device 1 - * 4 R/W 0b Fast Drive Timing Select 1 - * 1: Enable faster than PIO-0 timing modes for device 1 - * 0: Disable faster than PIO-0 timing modes for device 1 - * 3 R/W 0b DMA Timing Enable Only Select 0 - * 1: Enable the device timings for DMA operation for device 0 - * 0: Disable the device timings for DMA operation for device 0 - * 2 R/W 0b ATA/ATAPI Device Indicator 0 - * 1: Indicate presence od an ATA device - * 0: Indicate presence od an ATAPI device - * 1 R/W 0b IORDY Sample Point Enabled Select 0 - * 1: Enable IORDY sample for PIO transfers for device 0 - * 0: Disable IORDY sample for PIO transfers for device 0 - * 0 R/W 0b Fast Drive Timing Select 0 - * 1: Enable faster than PIO-0 timing modes for device 0 - * 0: Disable faster than PIO-0 timing modes for device 0 - * */ - -static void init_ide_ata_timing(struct device *dev) -{ - u16 ata_timing_pri, ata_timing_sec; - u32 ata_timing_reg32; - /* Primary channel is SD. */ -#if CONFIG_IDE1_ENABLE - ata_timing_pri = 0x8000; -#else - ata_timing_pri = 0x0000; // Disable this channel. -#endif - /* Secondary channel is SATA. */ -#if CONFIG_IDE2_ENABLE - ata_timing_sec = 0xa30f; // This setting value works well. -#else - ata_timing_sec = 0x0000; // Disable this channel. -#endif - ata_timing_reg32 = (ata_timing_sec << 16) | ata_timing_pri; - pci_write_config32(dev, 0x40, ata_timing_reg32); -#if CONFIG_IDE_NATIVE_MODE - /* Set both IDE channels to native mode. */ - u8 prog_if; - prog_if = pci_read_config8(dev, 0x09); - prog_if |= 5; - pci_write_config8(dev, 0x09, prog_if); -#endif - /* MMC function enable. */ - u32 sd_ctrl_reg; - sd_ctrl_reg = pci_read_config32(dev, 0x94); - sd_ctrl_reg |= 0x0200; - pci_write_config32(dev, 0x94, sd_ctrl_reg); - printk(BIOS_INFO, "Vortex86EX IDE controller ATA TIMING reg = %08x\n", ata_timing_reg32); -} - -static void setup_std_ide_compatible(struct device *dev) -{ -#if CONFIG_IDE_STANDARD_COMPATIBLE - // Misc Control Register (MCR) Offset 90h - // bit 0 = Vendor ID Access, bit 1 = Device ID Access. - u8 mcr; - u16 vendor = (u16) (CONFIG_IDE_COMPATIBLE_SELECTION >> 16); - u16 device = (u16) (CONFIG_IDE_COMPATIBLE_SELECTION & 0xffff); - // unlock vendor/device ID access bits. - mcr = pci_read_config8(dev, 0x90); - pci_write_config8(dev, 0x90, mcr | 3); - pci_write_config16(dev, 0x00, vendor); - pci_write_config16(dev, 0x02, device); - // restore lock bits. - pci_write_config8(dev, 0x90, mcr); -#endif -} - -static void vortex_ide_init(struct device *dev) -{ - if (dev->device == 0x1010) { - // This is SX/old DX IDE controller. - // Set IOCFG bit 15/13 : IDE Decoder Enable for Primary/Secondary channel. - u16 iocfg = 0xa000; - pci_write_config16(dev, 0x40, iocfg); - } else if (dev->device == 0x1011 || dev->device == 0x1012) { - // This is new DX/MX/MX+/DX2 IDE controller. - init_ide_ata_timing(dev); - setup_std_ide_compatible(dev); - } -} - -static struct device_operations vortex_ide_ops = { - .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = vortex_ide_init, - .scan_bus = 0, -}; - -static const struct pci_driver vortex_ide_driver_1010 __pci_driver = { - .ops = &vortex_ide_ops, - .vendor = PCI_VENDOR_ID_RDC, - .device = 0x1010, -}; - -static const struct pci_driver vortex_ide_driver_1011 __pci_driver = { - .ops = &vortex_ide_ops, - .vendor = PCI_VENDOR_ID_RDC, - .device = 0x1011, -}; - -static const struct pci_driver vortex_ide_driver_1012 __pci_driver = { - .ops = &vortex_ide_ops, - .vendor = PCI_VENDOR_ID_RDC, - .device = 0x1012, -}; diff --git a/src/southbridge/dmp/vortex86ex/southbridge.c b/src/southbridge/dmp/vortex86ex/southbridge.c deleted file mode 100644 index 05702d1..0000000 --- a/src/southbridge/dmp/vortex86ex/southbridge.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 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. - */ - -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ops.h> -#include <device/pci_ids.h> -#include <pc80/mc146818rtc.h> -#include <pc80/keyboard.h> -#include <string.h> -#include <delay.h> -#include "arch/io.h" -#include "chip.h" -#include "southbridge.h" -#include "cpu/dmp/dmp_post_code.h" - -/* IRQ number to S/B PCI Interrupt routing table reg(0x58/0xb4) mapping table. */ -static const unsigned char irq_to_int_routing[16] = { - 0x0, 0x0, 0x0, 0x2, // IRQ0-2 is unmappable, IRQ3 = 2. - 0x4, 0x5, 0x7, 0x6, // IRQ4-7 = 4, 5, 7, 6. - 0x0, 0x1, 0x3, 0x9, // IRQ8 is unmappable, IRQ9-11 = 1, 3, 9. - 0xb, 0x0, 0xd, 0xf // IRQ12 = b, IRQ13 is unmappable, IRQ14-15 = d, f. -}; - -/* S/B PCI Interrupt routing table reg(0x58) field bit shift. */ -#define EHCIH_IRQ_SHIFT 28 -#define OHCII_IRQ_SHIFT 24 -#define MAC_IRQ_SHIFT 16 -#define RT3_IRQ_SHIFT 12 -#define RT2_IRQ_SHIFT 8 -#define RT1_IRQ_SHIFT 4 -#define RT0_IRQ_SHIFT 0 - -/* S/B Extend PCI Interrupt routing table reg(0xb4) field bit shift. */ -#define CAN_IRQ_SHIFT 28 -#define HDA_IRQ_SHIFT 20 -#define USBD_IRQ_SHIFT 16 -#define SIDE_IRQ_SHIFT 12 -#define PIDE_IRQ_SHIFT 8 - -/* S/B function 1 Extend PCI Interrupt routing table reg 2(0xb4) - * field bit shift. - */ -#define SPI1_IRQ_SHIFT 8 -#define MOTOR_IRQ_SHIFT 0 - -/* in-chip PCI device IRQs(0 for disabled). */ -#define EHCII_IRQ 5 -#define OHCII_IRQ 5 -#define MAC_IRQ 6 - -#define CAN_IRQ 10 -#define HDA_IRQ 7 -#define USBD_IRQ 6 -#define PIDE_IRQ 5 - -#define SPI1_IRQ 10 -#define I2C0_IRQ 10 -#define MOTOR_IRQ 11 - -/* RT0-3 IRQs. */ -#define RT3_IRQ 3 -#define RT2_IRQ 4 -#define RT1_IRQ 5 -#define RT0_IRQ 6 - -/* IDE legacy mode IRQs. */ -#define IDE1_LEGACY_IRQ 14 -#define IDE2_LEGACY_IRQ 15 - -/* Internal parallel port */ -#define LPT_INT_C 0 -#define LPT_INT_ACK_SET 0 -#define LPT_UE 1 -#define LPT_PDMAS 0 -#define LPT_DREQS 0 - -/* keyboard controller system flag timeout : 400 ms */ -#define KBC_TIMEOUT_SYS_FLAG 400 - -static u8 get_pci_dev_func(device_t dev) -{ - return PCI_FUNC(dev->path.pci.devfn); -} - -static void verify_dmp_keyboard_error(void) -{ - post_code(POST_DMP_KBD_FW_VERIFY_ERR); - die("Internal keyboard firmware verify error!\n"); -} - -static void upload_dmp_keyboard_firmware(struct device *dev) -{ - u32 reg_sb_c0; - u32 fwptr; - - // enable firmware uploading function by set bit 10. - post_code(POST_DMP_KBD_FW_UPLOAD); - reg_sb_c0 = pci_read_config32(dev, SB_REG_IPFCR); - pci_write_config32(dev, SB_REG_IPFCR, reg_sb_c0 | 0x400); - - outw(0, 0x62); // reset upload address to 0. - // upload 4096 bytes from 0xFFFFE000. - outsb(0x66, (u8 *) 0xffffe000, 4096); - // upload 4096 bytes from 0xFFFFC000. - outsb(0x66, (u8 *) 0xffffc000, 4096); - - outw(0, 0x62); // reset upload address to 0. - // verify 4096 bytes from 0xFFFFE000. - for (fwptr = 0xffffe000; fwptr < 0xfffff000; fwptr++) { - if (inb(0x66) != *(u8 *) fwptr) { - verify_dmp_keyboard_error(); - } - } - // verify 4096 bytes from 0xFFFFC000. - for (fwptr = 0xffffc000; fwptr < 0xffffd000; fwptr++) { - if (inb(0x66) != *(u8 *) fwptr) { - verify_dmp_keyboard_error(); - } - } - - // disable firmware uploading. - pci_write_config32(dev, SB_REG_IPFCR, reg_sb_c0 & ~0x400L); -} - -static int kbc_wait_system_flag(void) -{ - /* wait keyboard controller ready by checking system flag - * (status port bit 2). - */ - post_code(POST_DMP_KBD_CHK_READY); - u32 timeout; - for (timeout = KBC_TIMEOUT_SYS_FLAG; - timeout && ((inb(0x64) & 0x4) == 0); timeout--) - mdelay(1); - - if (!timeout) { - printk(BIOS_WARNING, "Keyboard controller system flag timeout\n"); - } - return !!timeout; -} - -static void pci_routing_fixup(struct device *dev) -{ - const unsigned slot[3] = { 0 }; - const unsigned char slot_irqs[1][4] = { - {RT0_IRQ, RT1_IRQ, RT2_IRQ, RT3_IRQ}, - }; - const int slot_num = 1; - int i; - u32 int_routing = 0; - u32 ext_int_routing = 0; - - /* assign PCI-e bridge (bus#0, dev#1, fn#0) IRQ to RT0. */ - pci_assign_irqs(0, 1, slot_irqs[0]); - - /* RT0 is enabled. */ - int_routing |= irq_to_int_routing[RT0_IRQ] << RT0_IRQ_SHIFT; - - /* assign PCI slot IRQs. */ - for (i = 0; i < slot_num; i++) { - pci_assign_irqs(1, slot[i], slot_irqs[i]); - } - - /* Read PCI slot IRQs to see if RT1-3 is used, and enables it */ - for (i = 0; i < slot_num; i++) { - unsigned int funct; - device_t pdev; - u8 irq; - - /* Each slot may contain up to eight functions. */ - for (funct = 0; funct < 8; funct++) { - pdev = dev_find_slot(1, (slot[i] << 3) + funct); - if (!pdev) - continue; - irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE); - if (irq == RT1_IRQ) { - int_routing |= irq_to_int_routing[RT1_IRQ] << RT1_IRQ_SHIFT; - } else if (irq == RT2_IRQ) { - int_routing |= irq_to_int_routing[RT2_IRQ] << RT2_IRQ_SHIFT; - } else if (irq == RT3_IRQ) { - int_routing |= irq_to_int_routing[RT3_IRQ] << RT3_IRQ_SHIFT; - } - } - } - - /* Setup S/B PCI Interrupt routing table reg(0x58). */ - int_routing |= irq_to_int_routing[EHCII_IRQ] << EHCIH_IRQ_SHIFT; - int_routing |= irq_to_int_routing[OHCII_IRQ] << OHCII_IRQ_SHIFT; - int_routing |= irq_to_int_routing[MAC_IRQ] << MAC_IRQ_SHIFT; - pci_write_config32(dev, SB_REG_PIRQ_ROUTE, int_routing); - - /* Setup S/B PCI Extend Interrupt routing table reg(0xb4). */ - ext_int_routing |= irq_to_int_routing[CAN_IRQ] << CAN_IRQ_SHIFT; - ext_int_routing |= irq_to_int_routing[HDA_IRQ] << HDA_IRQ_SHIFT; - ext_int_routing |= irq_to_int_routing[USBD_IRQ] << USBD_IRQ_SHIFT; -#if CONFIG_IDE_NATIVE_MODE - /* IDE in native mode, only uses one IRQ. */ - ext_int_routing |= irq_to_int_routing[0] << SIDE_IRQ_SHIFT; - ext_int_routing |= irq_to_int_routing[PIDE_IRQ] << PIDE_IRQ_SHIFT; -#else - /* IDE in legacy mode, use IRQ 14, 15. */ - ext_int_routing |= irq_to_int_routing[IDE2_LEGACY_IRQ] << SIDE_IRQ_SHIFT; - ext_int_routing |= irq_to_int_routing[IDE1_LEGACY_IRQ] << PIDE_IRQ_SHIFT; -#endif - pci_write_config32(dev, SB_REG_EXT_PIRQ_ROUTE, ext_int_routing); - - /* Assign in-chip PCI device IRQs. */ - if (MAC_IRQ) { - unsigned char irqs[4] = { MAC_IRQ, 0, 0, 0 }; - pci_assign_irqs(0, 0x8, irqs); - } - if ((OHCII_IRQ != 0) && (EHCII_IRQ != 0)) { - unsigned char irqs[4] = { OHCII_IRQ, EHCII_IRQ, 0, 0 }; - pci_assign_irqs(0, 0xa, irqs); - } - if ((CONFIG_IDE_NATIVE_MODE != 0) && (PIDE_IRQ != 0)) { - /* IDE in native mode, setup PCI IRQ. */ - unsigned char irqs[4] = { PIDE_IRQ, 0, 0, 0 }; - pci_assign_irqs(0, 0xc, irqs); - } - if (CAN_IRQ) { - unsigned char irqs[4] = { CAN_IRQ, 0, 0, 0 }; - pci_assign_irqs(0, 0x11, irqs); - } - if (HDA_IRQ) { - unsigned char irqs[4] = { HDA_IRQ, 0, 0, 0 }; - pci_assign_irqs(0, 0xe, irqs); - } - if (USBD_IRQ) { - unsigned char irqs[4] = { USBD_IRQ, 0, 0, 0 }; - pci_assign_irqs(0, 0xf, irqs); - } -} - -static void vortex_sb_init(struct device *dev) -{ - u32 lpt_reg = 0; - -#if CONFIG_LPT_ENABLE - int ppmod = 0; -#if CONFIG_LPT_MODE_BPP - ppmod = 0; -#elif CONFIG_LPT_MODE_EPP_19_AND_SPP - ppmod = 1; -#elif CONFIG_LPT_MODE_ECP - ppmod = 2; -#elif CONFIG_LPT_MODE_ECP_AND_EPP_19 - ppmod = 3; -#elif CONFIG_LPT_MODE_SPP - ppmod = 4; -#elif CONFIG_LPT_MODE_EPP_17_AND_SPP - ppmod = 5; -#elif CONFIG_LPT_MODE_ECP_AND_EPP_17 - ppmod = 7; -#else -#error CONFIG_LPT_MODE error. -#endif - - /* Setup internal parallel port */ - lpt_reg |= (LPT_INT_C << 28); - lpt_reg |= (LPT_INT_ACK_SET << 27); - lpt_reg |= (ppmod << 24); - lpt_reg |= (LPT_UE << 23); - lpt_reg |= (LPT_PDMAS << 22); - lpt_reg |= (LPT_DREQS << 20); - lpt_reg |= (irq_to_int_routing[CONFIG_LPT_IRQ] << 16); - lpt_reg |= (CONFIG_LPT_IO << 0); -#endif // CONFIG_LPT_ENABLE - pci_write_config32(dev, SB_REG_IPPCR, lpt_reg); -} - -#define SETUP_GPIO_ADDR(n) \ - u32 cfg##n = (CONFIG_GPIO_P##n##_DIR_ADDR << 16) | (CONFIG_GPIO_P##n##_DATA_ADDR);\ - outl(cfg##n, base + 4 + (n * 4));\ - gpio_enable_mask |= (1 << n); - -#define INIT_GPIO(n) \ - outb(CONFIG_GPIO_P##n##_INIT_DIR, CONFIG_GPIO_P##n##_DIR_ADDR);\ - outb(CONFIG_GPIO_P##n##_INIT_DATA, CONFIG_GPIO_P##n##_DATA_ADDR); - -static void ex_sb_gpio_init(struct device *dev) -{ - const int base = 0xb00; - u32 gpio_enable_mask = 0; - /* S/B register 63h - 62h : GPIO Port Config IO Base Address */ - pci_write_config16(dev, SB_REG_GPIO_CFG_IO_BASE, base | 1); - /* Set GPIO port 0~9 base address. - * Config Base + 04h, 08h, 0ch... : GPIO port 0~9 data/dir decode addr. - * Bit 31-16 : DBA, GPIO direction base address. - * Bit 15-0 : DPBA, GPIO data port base address. - * */ -#if CONFIG_GPIO_P0_ENABLE - SETUP_GPIO_ADDR(0) -#endif -#if CONFIG_GPIO_P1_ENABLE - SETUP_GPIO_ADDR(1) -#endif -#if CONFIG_GPIO_P2_ENABLE - SETUP_GPIO_ADDR(2) -#endif -#if CONFIG_GPIO_P3_ENABLE - SETUP_GPIO_ADDR(3) -#endif -#if CONFIG_GPIO_P4_ENABLE - SETUP_GPIO_ADDR(4) -#endif -#if CONFIG_GPIO_P5_ENABLE - SETUP_GPIO_ADDR(5) -#endif -#if CONFIG_GPIO_P6_ENABLE - SETUP_GPIO_ADDR(6) -#endif -#if CONFIG_GPIO_P7_ENABLE - SETUP_GPIO_ADDR(7) -#endif -#if CONFIG_GPIO_P8_ENABLE - SETUP_GPIO_ADDR(8) -#endif -#if CONFIG_GPIO_P9_ENABLE - SETUP_GPIO_ADDR(9) -#endif - /* Enable GPIO port 0~9. */ - outl(gpio_enable_mask, base); - /* Set GPIO port 0-9 initial dir and data. */ -#if CONFIG_GPIO_P0_ENABLE - INIT_GPIO(0) -#endif -#if CONFIG_GPIO_P1_ENABLE - INIT_GPIO(1) -#endif -#if CONFIG_GPIO_P2_ENABLE - INIT_GPIO(2) -#endif -#if CONFIG_GPIO_P3_ENABLE - INIT_GPIO(3) -#endif -#if CONFIG_GPIO_P4_ENABLE - INIT_GPIO(4) -#endif -#if CONFIG_GPIO_P5_ENABLE - INIT_GPIO(5) -#endif -#if CONFIG_GPIO_P6_ENABLE - INIT_GPIO(6) -#endif -#if CONFIG_GPIO_P7_ENABLE - INIT_GPIO(7) -#endif -#if CONFIG_GPIO_P8_ENABLE - INIT_GPIO(8) -#endif -#if CONFIG_GPIO_P9_ENABLE - INIT_GPIO(9) -#endif - /* Disable GPIO Port Config IO Base Address. */ - pci_write_config16(dev, SB_REG_GPIO_CFG_IO_BASE, 0x0); -} - -static u32 make_uart_config(u16 base, u8 irq) -{ - u8 mapped_irq = irq_to_int_routing[irq]; - u32 cfg = 0; - cfg |= 1 << 23; // UE = enabled. - cfg |= (mapped_irq << 16); // UIRT. - cfg |= base; // UIOA. - return cfg; -} - -#define SETUP_UART(n) \ - uart_cfg = make_uart_config(CONFIG_UART##n##_IO, CONFIG_UART##n##_IRQ);\ - outl(uart_cfg, base + (n - 1) * 4); - -static void ex_sb_uart_init(struct device *dev) -{ - const int base = 0xc00; - u32 uart_cfg = 0; - /* S/B register 61h - 60h : UART Config IO Base Address */ - pci_write_config16(dev, SB_REG_UART_CFG_IO_BASE, base | 1); - /* setup UART */ -#if CONFIG_UART1_ENABLE - SETUP_UART(1) -#endif -#if CONFIG_UART2_ENABLE - SETUP_UART(2) -#endif -#if CONFIG_UART3_ENABLE - SETUP_UART(3) -#endif -#if CONFIG_UART4_ENABLE - SETUP_UART(4) -#endif -#if CONFIG_UART5_ENABLE - SETUP_UART(5) -#endif -#if CONFIG_UART6_ENABLE - SETUP_UART(6) -#endif -#if CONFIG_UART7_ENABLE - SETUP_UART(7) -#endif -#if CONFIG_UART8_ENABLE - SETUP_UART(8) -#endif -#if CONFIG_UART9_ENABLE - SETUP_UART(9) -#endif -#if CONFIG_UART10_ENABLE - SETUP_UART(10) -#endif - /* Keep UART Config I/O base address */ - //pci_write_config16(SB, SB_REG_UART_CFG_IO_BASE, 0x0); -} - -static void i2c_init(struct device *dev) -{ - u8 mapped_irq = irq_to_int_routing[I2C0_IRQ]; - u32 cfg = 0; - cfg |= 1 << 31; // UE = enabled. - cfg |= (mapped_irq << 16); // IIRT0. - cfg |= CONFIG_I2C_BASE; // UIOA. - pci_write_config32(dev, SB_REG_II2CCR, cfg); -} - -static int get_rtc_update_in_progress(void) -{ - if (cmos_read(RTC_REG_A) & RTC_UIP) - return 1; - return 0; -} - -static void unsafe_read_cmos_rtc(u8 rtc[7]) -{ - rtc[0] = cmos_read(RTC_CLK_ALTCENTURY); - rtc[1] = cmos_read(RTC_CLK_YEAR); - rtc[2] = cmos_read(RTC_CLK_MONTH); - rtc[3] = cmos_read(RTC_CLK_DAYOFMONTH); - rtc[4] = cmos_read(RTC_CLK_HOUR); - rtc[5] = cmos_read(RTC_CLK_MINUTE); - rtc[6] = cmos_read(RTC_CLK_SECOND); -} - -static void read_cmos_rtc(u8 rtc[7]) -{ - /* Read RTC twice and check update-in-progress flag, to make - * sure RTC is correct */ - u8 rtc_old[7], rtc_new[7]; - while (get_rtc_update_in_progress()) ; - unsafe_read_cmos_rtc(rtc_new); - do { - memcpy(rtc_old, rtc_new, 7); - while (get_rtc_update_in_progress()) ; - unsafe_read_cmos_rtc(rtc_new); - } while (memcmp(rtc_new, rtc_old, 7) != 0); -} - -/* - * Convert a number in decimal format into the BCD format. - * Return 255 if not a valid BCD value. - */ -static u8 bcd2dec(u8 bcd) -{ - u8 h, l; - h = bcd >> 4; - l = bcd & 0xf; - if (h > 9 || l > 9) - return 255; - return h * 10 + l; -} - -static void fix_cmos_rtc_time(void) -{ - /* Read RTC data. */ - u8 rtc[7]; - read_cmos_rtc(rtc); - - /* Convert RTC from BCD format to binary. */ - u8 bin_rtc[7]; - int i; - for (i = 0; i < 7; i++) { - bin_rtc[i] = bcd2dec(rtc[i]); - } - - /* If RTC date is invalid, fix it. */ - if (bin_rtc[0] > 99 || bin_rtc[1] > 99 || bin_rtc[2] > 12 || bin_rtc[3] > 31) { - /* Set PC compatible timing mode. */ - cmos_write(0x26, RTC_REG_A); - cmos_write(0x02, RTC_REG_B); - /* Now setup a default date 2008/08/08 08:08:08. */ - cmos_write(0x8, RTC_CLK_SECOND); - cmos_write(0x8, RTC_CLK_MINUTE); - cmos_write(0x8, RTC_CLK_HOUR); - cmos_write(0x6, RTC_CLK_DAYOFWEEK); /* Friday */ - cmos_write(0x8, RTC_CLK_DAYOFMONTH); - cmos_write(0x8, RTC_CLK_MONTH); - cmos_write(0x8, RTC_CLK_YEAR); - cmos_write(0x20, RTC_CLK_ALTCENTURY); - } -} - -static void vortex86_sb_set_io_resv(device_t dev, unsigned index, u32 base, u32 size) -{ - struct resource *res; - res = new_resource(dev, index); - res->base = base; - res->size = size; - res->limit = 0xffffUL; - res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; -} - -static void vortex86_sb_set_spi_flash_size(device_t dev, unsigned index, u32 flash_size) -{ - /* SPI flash is in topmost of 4G memory space */ - struct resource *res; - res = new_resource(dev, index); - res->base = 0x100000000LL - flash_size; - res->size = flash_size; - res->limit = 0xffffffffUL; - res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; -} - -static void vortex86_sb_read_resources(device_t dev) -{ - u32 flash_size = 8 * 1024 * 1024; - - pci_dev_read_resources(dev); - - if (dev->device == 0x6011) { - /* It is EX CPU southbridge */ - if (get_pci_dev_func(dev) != 0) { - /* only for function 0, skip function 1 */ - return; - } - /* default SPI flash ROM is 64MB */ - flash_size = 64 * 1024 * 1024; - } - - /* Reserve space for legacy I/O */ - vortex86_sb_set_io_resv(dev, 1, 0, 0x1000UL); - - /* Reserve space for flash */ - vortex86_sb_set_spi_flash_size(dev, 2, flash_size); - - /* Reserve space for I2C */ - vortex86_sb_set_io_resv(dev, 3, CONFIG_I2C_BASE, 8); -} - -static void southbridge_init_func1(struct device *dev) -{ - /* Handle S/B function 1 PCI IRQ routing. (SPI1/MOTOR) */ - u32 ext_int_routing2 = 0; - /* Setup S/B function 1 PCI Extend Interrupt routing table reg 2(0xb4). */ - ext_int_routing2 |= irq_to_int_routing[SPI1_IRQ] << SPI1_IRQ_SHIFT; - ext_int_routing2 |= irq_to_int_routing[MOTOR_IRQ] << MOTOR_IRQ_SHIFT; - pci_write_config32(dev, SB1_REG_EXT_PIRQ_ROUTE2, ext_int_routing2); - - /* Assign in-chip PCI device IRQs. */ - if ((SPI1_IRQ != 0) || (MOTOR_IRQ != 0)) { - unsigned char irqs[4] = { MOTOR_IRQ, SPI1_IRQ, 0, 0 }; - pci_assign_irqs(0, 0x10, irqs); - } -} - -static void southbridge_init(struct device *dev) -{ - /* Check it is function 0 or 1. (Same Vendor/Device ID) */ - if (get_pci_dev_func(dev) != 0) { - southbridge_init_func1(dev); - return; - } - upload_dmp_keyboard_firmware(dev); - vortex_sb_init(dev); - if (dev->device == 0x6011) { - ex_sb_gpio_init(dev); - ex_sb_uart_init(dev); - i2c_init(dev); - } - pci_routing_fixup(dev); - - fix_cmos_rtc_time(); - cmos_init(0); - /* Check keyboard controller ready. If timeout, reload firmware code - * and try again. - */ - u32 retries = 10; - while (!kbc_wait_system_flag()) { - if (!retries) { - post_code(POST_DMP_KBD_IS_BAD); - die("The keyboard timeout occurred too often. " - "Your CPU is probably defect. " - "Contact your dealer to replace it\n"); - } - upload_dmp_keyboard_firmware(dev); - retries--; - } - post_code(POST_DMP_KBD_IS_READY); - pc_keyboard_init(NO_AUX_DEVICE); -} - -static struct device_operations vortex_sb_ops = { - .read_resources = vortex86_sb_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = &southbridge_init, - .scan_bus = scan_lpc_bus, - .enable = 0, - .ops_pci = 0, -}; - -static const struct pci_driver pci_driver_6011 __pci_driver = { - .ops = &vortex_sb_ops, - .vendor = PCI_VENDOR_ID_RDC, - .device = 0x6011, /* EX CPU S/B ID */ -}; - -struct chip_operations southbridge_dmp_vortex86ex_ops = { - CHIP_NAME("DMP Vortex86EX Southbridge") - .enable_dev = 0 -}; diff --git a/src/southbridge/dmp/vortex86ex/southbridge.h b/src/southbridge/dmp/vortex86ex/southbridge.h deleted file mode 100644 index c2b9102..0000000 --- a/src/southbridge/dmp/vortex86ex/southbridge.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -#ifndef SOUTHBRIDGE_H -#define SOUTHBRIDGE_H - -#define SB PCI_DEV(0, 7, 0) -#define SB_REG_LPCCR 0x41 -#define SB_REG_FRCSCR 0x42 -#define SB_REG_PIRQ_ROUTE 0x58 -#define SB_REG_UART_CFG_IO_BASE 0x60 -#define SB_REG_GPIO_CFG_IO_BASE 0x62 -#define SB_REG_CS_BASE0 0x90 -#define SB_REG_CS_BASE_MASK0 0x94 -#define SB_REG_CS_BASE1 0x98 -#define SB_REG_CS_BASE_MASK1 0x9c -#define SB_REG_IPPCR 0xb0 -#define SB_REG_EXT_PIRQ_ROUTE 0xb4 -#define SB_REG_OCDCR 0xbc -#define SB_REG_IPFCR 0xc0 -#define SB_REG_FRWPR 0xc4 -#define SB_REG_STRAP 0xce -#define SB_REG_II2CCR 0xd4 - -#define SB1 PCI_DEV(0, 7, 1) -#define SB1_REG_EXT_PIRQ_ROUTE2 0xb4 - -#define SYSTEM_CTL_PORT 0x92 - -#endif /* SOUTHBRIDGE_H */