summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/boot/acpi.c67
-rw-r--r--src/arch/i386/boot/tables.c9
-rw-r--r--src/arch/i386/include/arch/acpi.h75
-rw-r--r--src/arch/i386/lib/c_start.S2
-rw-r--r--src/config/Options.lb6
-rw-r--r--src/cpu/p6/mtrr.c29
-rw-r--r--src/devices/pci_device.c10
-rw-r--r--src/include/cpu/p6/mtrr.h1
-rw-r--r--src/mainboard/via/epia-m/Config.lb14
-rw-r--r--src/mainboard/via/epia-m/auto.c13
-rw-r--r--src/mainboard/via/epia-m/fadt.c155
-rw-r--r--src/mainboard/via/epia-m/irq_tables.c40
-rw-r--r--src/mainboard/via/epia-m/mainboard.c54
-rw-r--r--src/northbridge/via/vt8623/northbridge.c84
-rw-r--r--src/northbridge/via/vt8623/raminit.c295
-rw-r--r--src/pc80/Config.lb2
-rw-r--r--src/pc80/keyboard.c2
-rw-r--r--src/pc80/vgabios.c258
-rw-r--r--src/southbridge/ricoh/rl5c476/Config.lb2
-rw-r--r--src/southbridge/ricoh/rl5c476/chip.h10
-rw-r--r--src/southbridge/ricoh/rl5c476/rl5c476.c255
-rw-r--r--src/southbridge/ricoh/rl5c476/rl5c476.h97
-rw-r--r--src/southbridge/via/vt8235/vt8235.c346
-rw-r--r--src/southbridge/via/vt8235/vt8235_early_smbus.c46
-rw-r--r--src/superio/via/vt1211/Config.lb2
-rw-r--r--src/superio/via/vt1211/chip.h19
-rw-r--r--src/superio/via/vt1211/vt1211.c149
-rw-r--r--src/superio/via/vt1211/vt1211.h22
28 files changed, 1669 insertions, 395 deletions
diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c
index ca9b66f744..6c837d0c8a 100644
--- a/src/arch/i386/boot/acpi.c
+++ b/src/arch/i386/boot/acpi.c
@@ -3,6 +3,10 @@
* written by Stefan Reinauer <stepan@openbios.org>
* (C) 2004 SUSE LINUX AG
*/
+/* ACPI FADT, FACS, and DSDT table support added by
+ * Nick Barker <nick.barker9@btinternet.com>, and those portions
+ * (C) Copyright 2004 Nick Barker
+ */
#include <console/console.h>
#include <string.h>
@@ -22,7 +26,15 @@
#define OEM_ID "LXBIOS"
#define ASLC "NONE"
-static u8 acpi_checksum(u8 *table, u32 length)
+
+// FIX ME - define needs declaring / setting in Config files
+#define HAVE_ACPI_FADT
+
+#ifdef HAVE_ACPI_FADT
+extern unsigned char AmlCode[];
+#endif
+
+u8 acpi_checksum(u8 *table, u32 length)
{
u8 ret=0;
while (length--) {
@@ -43,13 +55,15 @@ static void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
for (i=0; i<8; i++) {
if(rsdt->entry[i]==0) {
rsdt->entry[i]=(u32)table;
+ /* fix length to stop kernel winging about invalid entries */
+ rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1));
/* fix checksum */
/* hope this won't get optimized away */
rsdt->header.checksum=0;
rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
rsdt->header.length);
- printk_debug("ACPI: added table %d/8\n",i+1);
+ printk_debug("ACPI: added table %d/8 Length now %d\n",i+1,rsdt->header.length);
return;
}
}
@@ -181,6 +195,22 @@ static void acpi_create_hpet(acpi_hpet_t *hpet)
header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
}
+static void acpi_create_facs(acpi_facs_t *facs)
+{
+
+ memset( (void *)facs,0, sizeof(acpi_facs_t));
+
+ memcpy(facs->signature,"FACS",4);
+ facs->length = sizeof(acpi_facs_t);
+ facs->hardware_signature = 0;
+ facs->firmware_waking_vector = 0;
+ facs->global_lock = 0;
+ facs->flags = 0;
+ facs->x_firmware_waking_vector_l = 0;
+ facs->x_firmware_waking_vector_h = 0;
+ facs->version = 1;
+
+}
static void acpi_write_rsdt(acpi_rsdt_t *rsdt)
{
acpi_header_t *header=&(rsdt->header);
@@ -222,6 +252,9 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_rsdt_t *rsdt;
acpi_hpet_t *hpet;
acpi_madt_t *madt;
+ acpi_fadt_t *fadt;
+ acpi_facs_t *facs;
+ acpi_header_t *dsdt;
/* Align ACPI tables to 16byte */
start = ( start + 0x0f ) & -0x10;
@@ -244,7 +277,6 @@ unsigned long write_acpi_tables(unsigned long start)
/*
* We explicitly add these tables later on:
*/
-#define HAVE_ACPI_HPET
#ifdef HAVE_ACPI_HPET
printk_debug("ACPI: * HPET\n");
@@ -263,6 +295,35 @@ unsigned long write_acpi_tables(unsigned long start)
#endif
+
+#ifdef HAVE_ACPI_FADT
+
+
+ printk_debug("ACPI: * FACS\n");
+ facs = (acpi_facs_t *) current;
+ current += sizeof(acpi_facs_t);
+ acpi_create_facs(facs);
+
+
+ dsdt = (acpi_header_t *)current;
+ current += ((acpi_header_t *)AmlCode)->length;
+ memcpy((void *)dsdt,(void *)AmlCode, ((acpi_header_t *)AmlCode)->length);
+ dsdt->checksum = 0; // don't trust intel iasl compiler to get this right
+ dsdt->checksum = acpi_checksum(dsdt,dsdt->length);
+ printk_debug("ACPI: * DSDT @ %08x Length %x\n",dsdt,dsdt->length);
+ printk_debug("ACPI: * FADT\n");
+
+ fadt = (acpi_fadt_t *) current;
+ current += sizeof(acpi_fadt_t);
+
+ acpi_create_fadt(fadt,facs,dsdt);
+ acpi_add_table(rsdt,fadt);
+
+
+#endif
+
+
+
printk_info("ACPI: done.\n");
return current;
}
diff --git a/src/arch/i386/boot/tables.c b/src/arch/i386/boot/tables.c
index 08bb7a3401..18e271db8c 100644
--- a/src/arch/i386/boot/tables.c
+++ b/src/arch/i386/boot/tables.c
@@ -60,8 +60,13 @@ struct lb_memory *write_tables(struct mem_range *mem, unsigned long *processor_m
low_table_end = write_smp_table(low_table_end, processor_map);
/* Write ACPI tables */
- low_table_end = write_acpi_tables(low_table_end);
-
+ /* write them in the rom area because DSDT can be large (8K on epia-m) which
+ * pushes linuxbios table out of first 4K if set up in low table area
+ */
+
+ rom_table_end = write_acpi_tables(rom_table_end);
+ rom_table_end = (rom_table_end+1023) & ~1023;
+
/* Don't write anything in the traditional x86 BIOS data segment */
if (low_table_end < 0x500) {
low_table_end = 0x500;
diff --git a/src/arch/i386/include/arch/acpi.h b/src/arch/i386/include/arch/acpi.h
index e840d42195..9c89e90ba6 100644
--- a/src/arch/i386/include/arch/acpi.h
+++ b/src/arch/i386/include/arch/acpi.h
@@ -7,6 +7,9 @@
* The ACPI table structs are based on the Linux kernel sources.
*
*/
+/* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
+ * those parts (C) 2004 Nick Barker
+ */
#ifndef __ASM_ACPI_H
@@ -134,7 +137,77 @@ typedef struct acpi_madt_irqoverride {
} __attribute__ ((packed)) acpi_madt_irqoverride_t;
-
+typedef struct acpi_fadt {
+ struct acpi_table_header header;
+ u32 firmware_ctrl;
+ u32 dsdt;
+ u8 res1;
+ u8 preferred_pm_profile;
+ u16 sci_int;
+ u32 smi_cmd;
+ u8 acpi_enable;
+ u8 acpi_disable;
+ u8 s4bios_req;
+ u8 pstate_cnt;
+ u32 pm1a_evt_blk;
+ u32 pm1b_evt_blk;
+ u32 pm1a_cnt_blk;
+ u32 pm1b_cnt_blk;
+ u32 pm2_cnt_blk;
+ u32 pm_tmr_blk;
+ u32 gpe0_blk;
+ u32 gpe1_blk;
+ u8 pm1_evt_len;
+ u8 pm1_cnt_len;
+ u8 pm2_cnt_len;
+ u8 pm_tmr_len;
+ u8 gpe0_blk_len;
+ u8 gpe1_blk_len;
+ u8 gpe1_base;
+ u8 cst_cnt;
+ u16 p_lvl2_lat;
+ u16 p_lvl3_lat;
+ u16 flush_size;
+ u16 flush_stride;
+ u8 duty_offset;
+ u8 duty_width;
+ u8 day_alrm;
+ u8 mon_alrm;
+ u8 century;
+ u16 iapc_boot_arch;
+ u8 res2;
+ u32 flags;
+ struct acpi_gen_regaddr reset_reg;
+ u8 reset_value;
+ u8 res3;
+ u8 res4;
+ u8 res5;
+ u32 x_firmware_ctl_l;
+ u32 x_firmware_ctl_h;
+ u32 x_dsdt_l;
+ u32 x_dsdt_h;
+ struct acpi_gen_regaddr x_pm1a_evt_blk;
+ struct acpi_gen_regaddr x_pm1b_evt_blk;
+ struct acpi_gen_regaddr x_pm1a_cnt_blk;
+ struct acpi_gen_regaddr x_pm1b_cnt_blk;
+ struct acpi_gen_regaddr x_pm2_cnt_blk;
+ struct acpi_gen_regaddr x_pm_tmr_blk;
+ struct acpi_gen_regaddr x_gpe0_blk;
+ struct acpi_gen_regaddr x_gpe1_blk;
+} __attribute__ ((packed)) acpi_fadt_t;
+
+typedef struct acpi_facs {
+ char signature[4];
+ u32 length;
+ u32 hardware_signature;
+ u32 firmware_waking_vector;
+ u32 global_lock;
+ u32 flags;
+ u32 x_firmware_waking_vector_l;
+ u32 x_firmware_waking_vector_h;
+ u8 version;
+ u8 resv[33];
+} __attribute__ ((packed)) acpi_facs_t;
unsigned long write_acpi_tables(unsigned long addr);
diff --git a/src/arch/i386/lib/c_start.S b/src/arch/i386/lib/c_start.S
index 602fc51cbd..47fb64588c 100644
--- a/src/arch/i386/lib/c_start.S
+++ b/src/arch/i386/lib/c_start.S
@@ -116,7 +116,7 @@ gdt:
.word 0x0000, 0x0000 /* dummy */
.byte 0x00, 0x00, 0x00, 0x00
-#if defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
+#if defined(CONFIG_LEGACY_VGABIOS) && (CONFIG_LEGACY_VGABIOS == 1)
// from monty:
/* 0x00009a00,0000ffffULL, 20h: 16-bit 64k code at 0x00000000 */
/* 0x00009200,0000ffffULL 28h: 16-bit 64k data at 0x00000000 */
diff --git a/src/config/Options.lb b/src/config/Options.lb
index 343abda2bf..db00c51b84 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -481,7 +481,11 @@ define CONFIG_LEGACY_VGABIOS
export used
comment "Support for legacy VGA BIOS"
end
-
+define VGABIOS_START
+ default 0
+ export used
+ comment "Base of Legacy VGA in Rom"
+end
###############################################
# SMP options
###############################################
diff --git a/src/cpu/p6/mtrr.c b/src/cpu/p6/mtrr.c
index 36286608e8..f8b33a6f3d 100644
--- a/src/cpu/p6/mtrr.c
+++ b/src/cpu/p6/mtrr.c
@@ -45,6 +45,7 @@ static unsigned int mtrr_msr[] = {
MTRRfix4K_E0000_MSR, MTRRfix4K_E8000_MSR, MTRRfix4K_F0000_MSR, MTRRfix4K_F8000_MSR,
};
+static int mtrr_count = 0;
static void intel_enable_fixed_mtrr(void)
{
@@ -79,6 +80,12 @@ static inline void disable_cache(void)
::"memory");
}
+static inline void wbinvd(void)
+{
+ asm volatile (
+ "wbinvd\n\t");
+}
+
static inline void enable_cache(void)
{
unsigned int tmp;
@@ -92,15 +99,19 @@ static inline void enable_cache(void)
}
/* setting variable mtrr, comes from linux kernel source */
+/* funtion nows saves and restores state of deftype regs so that extra mtrr's can be set-up
+ * after the initial main memory mtrr's
+ */
static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
{
- msr_t base, mask;
+ msr_t base, mask, def,defsave;
base.hi = basek >> 22;
base.lo = basek << 10;
//printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
+ printk_debug("Adding mtrr #%d at %08x size %x\n",reg,base.lo,sizek<<10);
if (sizek < 4*1024*1024) {
mask.hi = ADDRESS_MASK_HIGH;
mask.lo = ~((sizek << 10) -1);
@@ -116,6 +127,10 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
// it is recommended that we disable and enable cache when we
// do this.
disable_cache();
+ def = defsave = rdmsr(MTRRdefType_MSR);
+ def.lo &= 0xf300;
+ wrmsr(MTRRdefType_MSR,def);
+
if (sizek == 0) {
msr_t zero;
zero.lo = zero.hi = 0;
@@ -129,6 +144,8 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
wrmsr (MTRRphysBase_MSR(reg), base);
wrmsr (MTRRphysMask_MSR(reg), mask);
}
+ wbinvd();
+ wrmsr(MTRRdefType_MSR,defsave);
enable_cache();
}
@@ -262,7 +279,16 @@ static unsigned fixed_mtrr_index(unsigned long addrk)
}
return index;
}
+// Externally visible function to add extra non system memory based mtrr's such
+// as AGP mtrr's - needs to be called after setup_mtrrs
+
+void add_var_mtrr(unsigned long range_startk, unsigned long range_sizek,
+ unsigned char type)
+{
+ intel_set_var_mtrr(mtrr_count++,range_startk,range_sizek,type);
+}
+
static unsigned int range_to_mtrr(unsigned int reg,
unsigned long range_startk, unsigned long range_sizek,
unsigned long next_range_startk)
@@ -382,6 +408,7 @@ void setup_mtrrs(struct mem_range *mem)
}
/* Write the last range */
reg = range_to_mtrr(reg, range_startk, range_sizek, 0);
+ mtrr_count = reg;
printk_debug("DONE variable MTRRs\n");
printk_debug("Clear out the extra MTRR's\n");
/* Clear out the extra MTRR's */
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 785bf33515..f87a590d0e 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -679,6 +679,10 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn,
/* if a child provides scan_bus(), for example a bridge, scan
* buses behind that child */
for (child = bus->children; child; child = child->sibling) {
+ // make sure that we have an ops structure
+ if (!child->ops) {
+ continue;
+ }
if (!child->ops->scan_bus) {
continue;
}
@@ -767,17 +771,17 @@ static void pci_level_irq(unsigned char intNum)
{
unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
- printk_spew("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
+ printk_debug("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
intBits |= (1 << intNum);
- printk_spew("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
+ printk_debug("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
// Write new values
outb((unsigned char) intBits, 0x4d0);
outb((unsigned char) (intBits >> 8), 0x4d1);
/* this seems like an error but is not ... */
-#if 0
+#if 1
if (inb(0x4d0) != (intBits & 0xf)) {
printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
__FUNCTION__, intBits &0xf, inb(0x4d0));
diff --git a/src/include/cpu/p6/mtrr.h b/src/include/cpu/p6/mtrr.h
index 92bf62e5c2..b14f7104bd 100644
--- a/src/include/cpu/p6/mtrr.h
+++ b/src/include/cpu/p6/mtrr.h
@@ -34,6 +34,7 @@
#if !defined(ASSEMBLY)
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
+void add_var_mtrr(unsigned long basek, unsigned long sizek, unsigned char type);
#if defined(INTEL_PPRO_MTRR)
struct mem_range;
void setup_mtrrs(struct mem_range *mem);
diff --git a/src/mainboard/via/epia-m/Config.lb b/src/mainboard/via/epia-m/Config.lb
index ed43611162..8438fcf23b 100644
--- a/src/mainboard/via/epia-m/Config.lb
+++ b/src/mainboard/via/epia-m/Config.lb
@@ -23,6 +23,7 @@ uses _ROMBASE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses HAVE_MP_TABLE
+uses HAVE_ACPI_TABLES
## ROM_SIZE is the size of boot ROM that this board will use.
default ROM_SIZE = 256*1024
@@ -130,6 +131,11 @@ arch i386 end
driver mainboard.o
#object reset.o
+if HAVE_ACPI_TABLES
+ object fadt.o
+ object dsdt.o
+end
+
##
## Romcc output
##
@@ -218,6 +224,14 @@ northbridge via/vt8623 "vt8623"
register "enable_keyboard" = "0"
register "enable_nvram" = "1"
end
+ southbridge ricoh/rl5c476 "rl5c476"
+ end
+ superio via/vt1211 "vt1211"
+ register "enable_com_ports" = "1"
+ register "enable_hwmon" = "1"
+ register "enable_lpt" = "1"
+ register "enable_fdc" = "1"
+ end
end
cpu p6 "cpu0"
diff --git a/src/mainboard/via/epia-m/auto.c b/src/mainboard/via/epia-m/auto.c
index 88523ed9e9..6fbc8306a4 100644
--- a/src/mainboard/via/epia-m/auto.c
+++ b/src/mainboard/via/epia-m/auto.c
@@ -49,7 +49,7 @@ static inline int spd_read_byte(unsigned device, unsigned address)
-#include "northbridge/via/vt8601/raminit.c"
+#include "northbridge/via/vt8623/raminit.c"
/*
#include "sdram/generic_sdram.c"
*/
@@ -64,8 +64,9 @@ static void enable_mainboard_devices(void)
if (dev == PCI_DEV_INVALID) {
die("Southbridge not found!!!\n");
}
- pci_write_config8(dev, 0x50, 7);
- pci_write_config8(dev, 0x51, 0xff);
+ pci_write_config8(dev, 0x50, 0);
+ pci_write_config8(dev, 0x51, 0xfd);
+ pci_write_config8(dev, 0x94, 0xb2);
#if 0
// This early setup switches IDE into compatibility mode before PCI gets
// // a chance to assign I/Os
@@ -97,9 +98,15 @@ static void enable_shadow_ram(void)
static void main(void)
{
unsigned long x;
+ device_t dev;
/* init_timer();*/
outb(5, 0x80);
+
+ pci_write_config8( 0xd*8,0x15,0x1c);
+ pci_write_config8( 0 , 0xe1, 0xdd);
+
+ outb(5, 0x80);
enable_smbus();
enable_vt8235_serial();
diff --git a/src/mainboard/via/epia-m/fadt.c b/src/mainboard/via/epia-m/fadt.c
new file mode 100644
index 0000000000..702d556988
--- /dev/null
+++ b/src/mainboard/via/epia-m/fadt.c
@@ -0,0 +1,155 @@
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <string.h>
+#include <arch/acpi.h>
+
+void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs,void *dsdt){
+ acpi_header_t *header=&(fadt->header);
+
+ memset((void *)fadt,0,sizeof(acpi_fadt_t));
+ memcpy(header->signature,"FACP",4);
+ header->length = 244;
+ header->revision = 1;
+ memcpy(header->oem_id,"LXBIOS",6);
+ memcpy(header->oem_table_id,"LXBACPI ",8);
+ memcpy(header->asl_compiler_id,"LXB",8);
+ header->asl_compiler_revision=0;
+
+ fadt->firmware_ctrl=facs;
+ fadt->dsdt= dsdt;
+ fadt->preferred_pm_profile=0;
+ fadt->sci_int=5;
+ fadt->smi_cmd = 0;
+ fadt->acpi_enable = 0;
+ fadt->acpi_disable = 0;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0x0;
+
+ fadt->pm1a_evt_blk = 0x400;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = 0x404;
+ fadt->pm1b_cnt_blk = 0x0;
+ fadt->pm2_cnt_blk = 0x0;
+ fadt->pm_tmr_blk = 0x408;
+ fadt->gpe0_blk = 0x420;
+ fadt->gpe1_blk = 0x0;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 0;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 4;
+ fadt->gpe1_blk_len = 0;
+ fadt->gpe1_base = 0;
+ fadt->cst_cnt = 0;
+ fadt->p_lvl2_lat = 90;
+ fadt->p_lvl3_lat = 900;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 0;
+ fadt->duty_width = 1;
+ fadt->day_alrm = 125;
+ fadt->mon_alrm = 126;
+ fadt->century = 50;
+ fadt->iapc_boot_arch = 0x1;
+ fadt->flags = 0x4a5;
+
+ fadt->reset_reg.space_id = 0;
+ fadt->reset_reg.bit_width = 0;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0x0;
+ fadt->reset_reg.addrh = 0x0;
+
+ fadt->reset_value = 0;
+ fadt->x_firmware_ctl_l = facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = 4;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = 0x400;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = 4;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = 0x0;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = 2;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = 0x404;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = 2;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = 0x0;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = 0;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = 0x0;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = 4;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = 0x408;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = 0;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = 0x420;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = 0;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = 0x0;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
+
+}
diff --git a/src/mainboard/via/epia-m/irq_tables.c b/src/mainboard/via/epia-m/irq_tables.c
index 894c27dec5..8e8aadcbf4 100644
--- a/src/mainboard/via/epia-m/irq_tables.c
+++ b/src/mainboard/via/epia-m/irq_tables.c
@@ -1,32 +1,30 @@
/* This file was generated by getpir.c, do not modify!
(but if you do, please run checkpir on it to verify)
- Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
-
- Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
+ * Contains the IRQ Routing Table dumped directly from your memory, which BIOS sets up
+ *
+ * Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
*/
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
- PIRQ_SIGNATURE, /* u32 signature */
- PIRQ_VERSION, /* u16 version */
- 32+16*5, /* there can be total 5 devices on the bus */
- 0, /* Where the interrupt router lies (bus) */
- 0x88, /* Where the interrupt router lies (dev) */
- 0x1c20, /* IRQs devoted exclusively to PCI usage */
- 0x1106, /* Vendor */
- 0x8231, /* Device */
- 0, /* Crap (miniport) */
+ PIRQ_SIGNATURE, /* u32 signature */
+ PIRQ_VERSION, /* u16 version */
+ 32+16*5, /* there can be total 5 devices on the bus */
+ 0x00, /* Where the interrupt router lies (bus) */
+ (0x00<<3)|0x0, /* Where the interrupt router lies (dev) */
+ 0xc20, /* IRQs devoted exclusively to PCI usage */
+ 0, /* Vendor */
+ 0, /* Device */
+ 0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
- 0x5e, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
+ 0x68, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
- /* 8231 ethernet */
- {0,0x90, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0x1, 0},
- /* 8231 internal */
- {0,0x88, {{0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}}, 0x2, 0},
- /* PCI slot */
- {0,0xa0, {{0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}, {0x2, 0xdeb8}}, 0, 0},
- {0,0x50, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x3, 0},
- {0,0x98, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x4, 0},
+ /* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
+ {0x00,(0x14<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x1, 0x0},
+ {0x00,(0x13<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x2, 0x0},
+ {0x00,(0x0a<<3)|0x0, {{0x04, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0x0deb8}}, 0x3, 0x0},
+ {0x00,(0x0d<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x4, 0x0},
+ {0x00,(0x01<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x0, 0x0},
}
};
diff --git a/src/mainboard/via/epia-m/mainboard.c b/src/mainboard/via/epia-m/mainboard.c
index 747eb3eb7f..9597392593 100644
--- a/src/mainboard/via/epia-m/mainboard.c
+++ b/src/mainboard/via/epia-m/mainboard.c
@@ -9,6 +9,9 @@
#include <device/chip.h>
#include "chip.h"
+void vga_enable_console();
+
+
static int
mainboard_scan_bus(device_t root, int maxbus)
{
@@ -19,6 +22,56 @@ mainboard_scan_bus(device_t root, int maxbus)
return maxbus;
}
+void vga_fixup(void) {
+ // we do this right here because:
+ // - all the hardware is working, and some VGA bioses seem to need
+ // that
+ // - we need page 0 below for linuxbios tables.
+
+ printk_debug("INSTALL REAL-MODE IDT\n");
+ setup_realmode_idt();
+ printk_debug("DO THE VGA BIOS\n");
+ do_vgabios();
+ post_code(0x93);
+ vga_enable_console();
+
+
+}
+
+void write_protect_vgabios(void)
+{
+ device_t dev;
+
+ printk_info("write_protect_vgabios\n");
+ dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3123, 0);
+ if(dev)
+ pci_write_config8(dev, 0x61, 0xaa);
+
+}
+
+static void
+enable(struct chip *chip, enum chip_pass pass)
+{
+
+ struct mainboard_tyan_s4882_config *conf =
+ (struct mainboard_tyan_s4882_config *)chip->chip_info;
+
+ switch (pass) {
+ default: break;
+// case CONF_PASS_PRE_CONSOLE:
+// case CONF_PASS_PRE_PCI:
+ case CONF_PASS_POST_PCI:
+// case CONF_PASS_PRE_BOOT:
+// if (conf->fixup_scsi)
+// onboard_scsi_fixup();
+// if (conf->fixup_vga)
+// vga_fixup();
+ printk_debug("mainboard fixup pass %d done\r\n",
+ pass);
+ break;
+ }
+
+}
static struct device_operations mainboard_operations = {
.read_resources = root_dev_read_resources,
.set_resources = root_dev_set_resources,
@@ -41,5 +94,6 @@ static void enumerate(struct chip *chip)
struct chip_control mainboard_via_epia_m_control = {
.enumerate = enumerate,
.name = "VIA EPIA-M mainboard ",
+ .enable = enable
};
diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c
index db5d831d74..cba7278066 100644
--- a/src/northbridge/via/vt8623/northbridge.c
+++ b/src/northbridge/via/vt8623/northbridge.c
@@ -6,15 +6,16 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/hypertransport.h>
+#include <device/pci_ids.h>
#include <device/chip.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
+#include <cpu/p6/mtrr.h>
#include "chip.h"
#include "northbridge.h"
-static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x56, 0x57};
+static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
struct mem_range *sizeram(void)
{
@@ -30,8 +31,9 @@ struct mem_range *sizeram(void)
return 0;
}
mem[0].basek = 0;
- mem[0].sizek = 65536;
- idx = 1;
+ mem[0].sizek = 0xa0000 >>10; // first 640k
+ mem[1].basek = 0xc0000 >>10; // leave a hole for vga
+ idx = 2;
while(idx < sizeof(mem)/sizeof(mem[0])) {
mem[idx].basek = 0;
mem[idx].sizek = 0;
@@ -53,8 +55,8 @@ struct mem_range *sizeram(void)
ramregs[i]);
}
- printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
- mem[0].sizek = rambits*8*1024;
+ printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
+ mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10);
#if 1
for(i = 0; i < idx; i++) {
printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
@@ -78,18 +80,65 @@ static void enumerate(struct chip *chip)
* Apparently these registers govern some sort of bus master behavior.
*/
static void random_fixup() {
- device_t pcidev = dev_find_slot(0, 0);
+ device_t pcidev0 = dev_find_slot(0, 0);
+ device_t pcidev1,pcidev2;
+ unsigned long fb;
+ unsigned char c;
- printk_spew("VT8623 random fixup ...\n");
- if (pcidev) {
- pci_write_config8(pcidev, 0x70, 0xc0);
- pci_write_config8(pcidev, 0x71, 0x88);
- pci_write_config8(pcidev, 0x72, 0xec);
- pci_write_config8(pcidev, 0x73, 0x0c);
- pci_write_config8(pcidev, 0x74, 0x0e);
- pci_write_config8(pcidev, 0x75, 0x81);
- pci_write_config8(pcidev, 0x76, 0x52);
+ printk_debug("VT8623 random fixup ...\n");
+ if (pcidev0) {
+ pci_write_config8(pcidev0, 0x0d, 0x08);
+ pci_write_config8(pcidev0, 0x70, 0x82);
+ pci_write_config8(pcidev0, 0x71, 0xc8);
+ pci_write_config8(pcidev0, 0x72, 0x0);
+ pci_write_config8(pcidev0, 0x73, 0x01);
+ pci_write_config8(pcidev0, 0x74, 0x01);
+ pci_write_config8(pcidev0, 0x75, 0x08);
+ pci_write_config8(pcidev0, 0x76, 0x52);
+ pci_write_config8(pcidev0, 0x13, 0xd0);
+ pci_write_config8(pcidev0, 0x84, 0x80);
+ pci_write_config16(pcidev0,0x80, 0x610f);
+ pci_write_config32(pcidev0,0x88, 0x02);
}
+ printk_debug("VT8623 AGP random fixup ...\n");
+ pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0);
+ if( pcidev1) {
+ pci_write_config8(pcidev1,0x3e,0x0c);
+ pci_write_config8(pcidev1,0x40,0x83);
+ pci_write_config8(pcidev1,0x41,0xc5);
+ pci_write_config8(pcidev1,0x43,0x44);
+ pci_write_config8(pcidev1,0x44,0x34);
+ pci_write_config8(pcidev1,0x83,0x02);
+ }
+ printk_debug("VGA random fixup ...\n");
+ pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
+ if( pcidev2 ){
+ pci_write_config8(pcidev2,0x04,0x07);
+ pci_write_config8(pcidev2,0x0d,0x20);
+ }
+ // fixup GART and framebuffer addresses properly
+ // first set up frame buffer properly
+ fb = pci_read_config32(pcidev2,0x10); // base address of framebuffer
+ printk_debug("Frame buffer at %8x\n",fb);
+ c = pci_read_config8(pcidev0,0xe1) & 0xf0; // size of vga
+ c |= fb>>28; // upper nibble of frame buffer address
+ pci_write_config8(pcidev0,0xe1,c);
+ c = (fb>>20) | 1; // enable framebuffer
+ pci_write_config8(pcidev0,0xe0,c);
+ pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does
+
+
+}
+static void set_vga_mtrrs(void)
+{
+ device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
+ unsigned long fb;
+
+ add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
+ fb = pci_read_config32(pcidev,0x10); // get the fb address
+ add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB);
+
+
}
static void northbridge_init(struct chip *chip, enum chip_pass pass)
@@ -103,10 +152,11 @@ static void northbridge_init(struct chip *chip, enum chip_pass pass)
break;
case CONF_PASS_POST_PCI:
+ random_fixup();
break;
case CONF_PASS_PRE_BOOT:
- random_fixup();
+ set_vga_mtrrs();
break;
default:
diff --git a/src/northbridge/via/vt8623/raminit.c b/src/northbridge/via/vt8623/raminit.c
index f7c0a10fb0..10086a02fd 100644
--- a/src/northbridge/via/vt8623/raminit.c
+++ b/src/northbridge/via/vt8623/raminit.c
@@ -47,16 +47,17 @@ it with the version available from LANL.
#define DIMM_CL2 0
#endif
-void dimms_read(unsigned long x)
+
+
+
+
+void dimm_read(unsigned long x)
{
- uint8_t c;
unsigned long eax;
volatile unsigned long y;
eax = x;
- for(c = 0; c < 6; c++) {
- y = * (volatile unsigned long *) eax;
- eax += 0x10000000;
- }
+ y = * (volatile unsigned long *) eax;
+
}
void dimms_write(int x)
@@ -88,7 +89,7 @@ void setnorthb(device_t north, uint8_t reg, uint8_t val)
void
dumpnorth(device_t north)
{
- uint8_t r, c;
+ uint16_t r, c;
for(r = 0; r < 256; r += 16) {
print_debug_hex8(r);
print_debug(":");
@@ -106,7 +107,7 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
uint8_t c, r;
print_err("vt8623 init starting\r\n");
- north = pci_locate_device(PCI_ID(0x1106, 0x8623), 0);
+ north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0);
north = 0;
print_debug_hex32(north);
print_debug(" is the north\n");
@@ -118,66 +119,57 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
/* All we are doing now is setting initial known-good values that will
* be revised later as we read SPD
*/
- // memory clk enable. We are not using ECC
- pci_write_config8(north,0x78, 0x01);
- print_debug_hex8(pci_read_config8(north, 0x78));
- // dram control, see the book.
-#if DIMM_PC133
- pci_write_config8(north,0x68, 0x52);
-#else
- pci_write_config8(north,0x68, 0x42);
-#endif
- // dram control, see the book.
- pci_write_config8(north,0x6B, 0x0c);
- // Initial setting, 256MB in each bank, will be rewritten later.
- pci_write_config8(north,0x5A, 0x20);
- print_debug_hex8(pci_read_config8(north, 0x5a));
- pci_write_config8(north,0x5B, 0x40);
- pci_write_config8(north,0x5C, 0x60);
- pci_write_config8(north,0x5D, 0x80);
- pci_write_config8(north,0x5E, 0xA0);
- pci_write_config8(north,0x5F, 0xC0);
- // It seems we have to take care of these 2 registers as if
- // they are bank 6 and 7.
- pci_write_config8(north,0x56, 0xC0);
- pci_write_config8(north,0x57, 0xC0);
-
- // SDRAM in all banks
- pci_write_config8(north,0x60, 0x3F);
- // DRAM timing. I'm suspicious of this
- // This is for all banks, 64 is 0,1. 65 is 2,3. 66 is 4,5.
- // ras precharge 4T, RAS pulse 5T
- // cas2 is 0xd6, cas3 is 0xe6
- // we're also backing off write pulse width to 2T, so result is 0xee
-#if DIMM_CL2
- pci_write_config8(north,0x64, 0xd4);
- pci_write_config8(north,0x65, 0xd4);
- pci_write_config8(north,0x66, 0xd4);
-#else // CL=3
- pci_write_config8(north,0x64, 0xe4);
- pci_write_config8(north,0x65, 0xe4);
- pci_write_config8(north,0x66, 0xe4);
-#endif
- // dram frequency select.
- // enable 4K pages for 64M dram.
-#if DIMM_PC133
- pci_write_config8(north,0x69, 0x3c);
-#else
- pci_write_config8(north,0x69, 0xac);
-#endif
+ pci_write_config8(north,0x75,0x08);
+
+ /* since we only support epia-m at the moment, only ddr is supported */
+ /* setup cpu */
+ pci_write_config8(north,0x50,0xc8);
+ pci_write_config8(north,0x51,0xde);
+ pci_write_config8(north,0x52,0xcf);
+ pci_write_config8(north,0x53,0x88);
+ pci_write_config8(north,0x55,0x07);
+
+ /* DRAM MA Map Type */
+ pci_write_config8(north,0x58,0xe0);
- /* IMPORTANT -- disable refresh counter */
- // refresh counter, disabled.
- pci_write_config8(north,0x6A, 0x00);
+ /* DRAM bank 0 - 3 size = 512M */
+ pci_write_config8(north,0x5a,0x10);
+ pci_write_config8(north,0x5b,0x10);
+ pci_write_config8(north,0x5c,0x10);
+ pci_write_config8(north,0x5d,0x10);
+
+ /* set DRAM timing for all banks */
+ pci_write_config8(north,0x64,0xe6);
+
+ /* set DRAM type to DDR */
+ pci_write_config8(north,0x60,0x02);
+
+
+ /* DRAM arbitration timer */
+ pci_write_config8(north,0x65,0x32);
+ pci_write_config8(north,0x66,0x01);
+ pci_write_config8(north,0x68,0x59);
+
+
+ /* DRAM Frequency */
+ pci_write_config8(north,0x54,0xe0);
+ pci_write_config8(north,0x69,0x2d);
+
+ /* Enable CKE */
+ pci_write_config8(north,0x6b,0x10);
+ /* Disable DRAM refresh */
+ pci_write_config8(north,0x6a,0x0);
+
+ /* set heavy drive */
+ pci_write_config8(north,0x6d,0x44);
+
+
+ pci_write_config8(north,0x61,0xff);
+
+
- // clkenable configuration. kevinh FIXME - add precharge
- pci_write_config8(north,0x6C, 0x00);
- // dram read latch delay of 1 ns, MD drive 8 mA,
- // high drive strength on MA[2: 13], we#, cas#, ras#
- // As per Cindy Lee, set to 0x37, not 0x57
- pci_write_config8(north,0x6D, 0x7f);
}
/* slot is the dram slot. Return size of side0 in lower 16-bit,
@@ -291,104 +283,87 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
};
device_t north = 0;
uint32_t size, base, slot, ma;
- /* begin to initialize*/
- // I forget why we need this, but we do
- dimms_write(0xa55a5aa5);
-
- /* set NOP*/
- pci_write_config8(north,0x6C, 0x01);
- print_debug("NOP\r\n");
- /* wait 200us*/
- // You need to do the memory reference. That causes the nop cycle.
- dimms_read(0);
- udelay(400);
- print_debug("PRECHARGE\r\n");
- /* set precharge */
- pci_write_config8(north,0x6C, 0x02);
- print_debug("DUMMY READS\r\n");
- /* dummy reads*/
- dimms_read(0);
- udelay(200);
- print_debug("CBR\r\n");
- /* set CBR*/
- pci_write_config8(north,0x6C, 0x04);
-
- /* do 8 reads and wait >100us between each - from via*/
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- dimms_read(0);
- udelay(200);
- print_debug("MRS\r\n");
- /* set MRS*/
- pci_write_config8(north,0x6c, 0x03);
-#if DIMM_CL2
- dimms_read(0x150);
-#else // CL=3
- dimms_read(0x1d0);
-#endif
- udelay(200);
- print_debug("NORMAL\r\n");
- /* set to normal mode */
- pci_write_config8(north,0x6C, 0x08);
- dimms_write(0x55aa55aa);
- dimms_read(0);
+
+ /* NOP command enable */
+ pci_write_config8(north,0x6b,0x01);
+
+ /* read a double word from any addree of the dimm */
+ dimm_read(0x1f000);
udelay(200);
- print_debug("set ref. rate\r\n");
- // Set the refresh rate.
-#if DIMM_PC133
- pci_write_config8(north,0x6A, 0x86);
-#else
- pci_write_config8(north,0x6A, 0x65);
-#endif
- print_debug("enable multi-page open\r\n");
- // enable multi-page open
- pci_write_config8(north,0x6B, 0x0d);
+
+ /* All bank precharge Command Enable */
+ pci_write_config8(north,0x6b,0x02);
+ dimm_read(0x1f000);
+
+ /* MSR Enable */
+ pci_write_config8(north,0x6b,0x03);
+ dimm_read(0x2000);
+
+ dimm_read(0x800);
+
+ /* All banks precharge Command Enable */
+ pci_write_config8(north,0x6b,0x02);
+ dimm_read(0x1f200);
+
+ /* CBR Cycle Enable */
+ pci_write_config8(north,0x6b,0x04);
+
+ /* Read 8 times */
+ dimm_read(0x1f300);
+ udelay(100);
+ dimm_read(0x1f400);
+ udelay(100);
+ dimm_read(0x1f500);
+ udelay(100);
+ dimm_read(0x1f600);
+ udelay(100);
+ dimm_read(0x1f700);
+ udelay(100);
+ dimm_read(0x1f800);
+ udelay(100);
+ dimm_read(0x1f900);
+ udelay(100);
+ dimm_read(0x1fa00);
+ udelay(100);
+
+ /* MSR Enable */
+ pci_write_config8(north,0x6b,0x03);
+
+ /* 0x150 if CAS Latency 2 or 0x350 CAS Latency 2.5 */
+ dimm_read(0x350);
+
+ /* Normal SDRAM Mode */
+ pci_write_config8(north,0x6b,0x58 );
+
+
+ /* Set the refresh rate */
+ pci_write_config8(north,0x6a,0x43);
+ pci_write_config8(north,0x67,0x22);
+
+ /* pci */
+ pci_write_config8(north,0x70,0x82);
+ pci_write_config8(north,0x73,0x01);
+ pci_write_config8(north,0x76,0x50);
+
+
+ pci_write_config8(north,0x71,0xc8);
- base = 0;
- for(slot = 0; slot < 4; slot++) {
- size = spd_module_size(slot);
- /* side 0 */
- base += size & 0xffff;
- pci_write_config8(north, ramregs[2*slot], base);
- /* side 1 */
- base += size >> 16;
- if (base > 0xff)
- base = 0xff;
- pci_write_config8(north, ramregs[2*slot + 1], base);
-
- if (!size)
- continue;
-
- /* Calculate the value of MA mapping type register,
- * based on size of SDRAM chips. */
- size = (size & 0xffff) << (3 + 3);
- /* convert module size to be in Mbits */
- size /= spd_num_chips(slot);
- print_debug_hex16(size);
- print_debug(" is the chip size\r\n");
- if (size < 64)
- ma = 0;
- if (size < 256)
- ma = 8;
- else
- ma = 0xe;
- print_debug_hex16(ma);
- print_debug(" is the MA type\r\n");
- set_ma_mapping(north, slot, ma);
- }
- print_err("vt8623 done\r\n");
+
+ /* graphics aperture base */
+ pci_write_config8(north,0x13,0xd0);
+
+ //pci_write_config8(north,0x56,0x10);
+ //pci_write_config8(north,0x57,0x10);
+
+ pci_write_config8(north,0xe0,0x80);
+ pci_write_config8(north,0xe1,0xdf);
+ pci_write_config8(north,0xe2,0x42);
+
+ pci_write_config8(north,0xa8,0x04);
+ pci_write_config8(north,0xac,0x2f);
+ pci_write_config8(north,0xae,0x04);
+
+ print_err("vt8623 done\r\n");
dumpnorth(north);
}
diff --git a/src/pc80/Config.lb b/src/pc80/Config.lb
index 1261abf3f8..fb00418249 100644
--- a/src/pc80/Config.lb
+++ b/src/pc80/Config.lb
@@ -3,7 +3,7 @@ uses CONFIG_LEGACY_VGABIOS
object mc146818rtc.o
object isa-dma.o
-#object i8259.o CONFIG_I8259
+object i8259.o
#object udelay_timer2.o CONFIG_UDELAY_TIMER2
#object beep.o CONFIG_BEEP
#object vga_load_regs.o VIDEO_CONSOLE
diff --git a/src/pc80/keyboard.c b/src/pc80/keyboard.c
index d293f714de..331f5ab345 100644
--- a/src/pc80/keyboard.c
+++ b/src/pc80/keyboard.c
@@ -5,7 +5,7 @@
/* much better keyboard init courtesy ollie@sis.com.tw
TODO: Typematic Setting, the keyboard is too slow for me */
-static void pc_keyboard_init(struct pc_keyboard *keyboard)
+void pc_keyboard_init(struct pc_keyboard *keyboard)
{
volatile unsigned char regval;
diff --git a/src/pc80/vgabios.c b/src/pc80/vgabios.c
index c83498e985..a6806d3947 100644
--- a/src/pc80/vgabios.c
+++ b/src/pc80/vgabios.c
@@ -1,8 +1,10 @@
-#include <pci.h>
-#include <pci_ids.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
#undef __KERNEL__
#include <arch/io.h>
-#include <printk.h>
+//#include <printk.h>
#include <string.h>
#include "vgachip.h"
@@ -121,6 +123,8 @@ static void real_mode_switch_call_vga(unsigned long devfn)
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
+ " mov $0x40, %ax \n"
+ " mov %ax, %ds \n"
" mov %cx, %ax \n"
" .byte 0x9a, 0x03, 0, 0, 0xc0 \n"
" movb $0x55, %al\noutb %al, $0x80\n"
@@ -151,10 +155,99 @@ static void real_mode_switch_call_vga(unsigned long devfn)
__asm__ (".text\n""real_mode_switch_end:\n");
extern char real_mode_switch_end[];
+/* call vga bios int 10 function 0x4f14 to enable main console
+ epia-m does not always autosence the main console so forcing it on is good !! */
+
+void vga_enable_console()
+{
+ __asm__ __volatile__ (
+ // paranoia -- does ecx get saved? not sure. This is
+ // the easiest safe thing to do.
+ " pushal\n"
+ /* save the stack */
+ " mov %esp, __stack\n"
+
+ /* This configures CS properly for real mode. */
+ " ljmp $0x28, $__vga_ec_16bit\n"
+ "__vga_ec_16bit: \n"
+ ".code16 \n"
+ /* 16 bit code from here on... */
+
+ /* Load the segment registers w/ properly configured segment
+ * descriptors. They will retain these configurations (limits,
+ * writability, etc.) once protected mode is turned off. */
+ " mov $0x30, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+
+ /* Turn off protection (bit 0 in CR0) */
+ " movl %cr0, %eax \n"
+ " andl $0xFFFFFFFE, %eax \n"
+ " movl %eax, %cr0 \n"
+
+ /* Now really going into real mode */
+ " ljmp $0, $__vga_ec_real \n"
+ "__vga_ec_real: \n"
+
+ // put the stack at the end of page zero.
+ // that way we can easily share it between real and protected,
+ // since the 16-bit ESP at segment 0 will work for any case.
+ /* Setup a stack */
+ " mov $0x0, %ax \n"
+ " mov %ax, %ss \n"
+ " movl $0x1000, %eax \n"
+ " movl %eax, %esp \n"
+ /* debugging for RGM */
+ " mov $0x11, %al \n"
+ " outb %al, $0x80\n"
+
+ /* Dump zeros in the other segregs */
+ " xor %ax, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ /* ask bios to enable main console */
+ /* set up for int 10 call - values found from X server bios call routines */
+ " movw $0x4f14,%ax \n"
+ " movw $0x8003,%bx \n"
+ " movw $1, %cx \n"
+ " movw $0, %dx \n"
+ " movw $0, %di \n"
+ " .byte 0xcd, 0x10 \n"
+ " movb $0x55, %al\noutb %al, $0x80\n"
+ /* if we got here, just about done.
+ * Need to get back to protected mode */
+ "movl %cr0, %eax\n"
+ // "andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
+ // "orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
+ "orl $0x0000001, %eax\n" /* PE = 1 */
+ "movl %eax, %cr0\n"
+ /* Now that we are in protected mode jump to a 32 bit code segment. */
+ "data32 ljmp $0x10, $vga_ec_restart\n"
+ "vga_ec_restart:\n"
+ ".code32\n"
+ " movw $0x18, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+ ".globl vga__ec_exit\n"
+ "vga_ec_exit:\n"
+ " mov __stack, %esp\n"
+ " popal\n"
+ );
+}
+
+
void
do_vgabios(void)
{
- struct pci_dev *dev;
+ device_t dev;
unsigned long busdevfn;
unsigned int rom = 0;
unsigned char *buf;
@@ -162,17 +255,17 @@ do_vgabios(void)
int i;
for (i=0x400; i<0x500; i++) {
- printk_debug("%02x%c", *(unsigned char *)i,
- i%16==15 ? '\n' : ' ');
+ //printk_debug("%02x%c", *(unsigned char *)i,
+ // i%16==15 ? '\n' : ' ');
*(unsigned char *) i = 0;
}
- for (i=0x400; i<0x500; i++) {
+/* for (i=0x400; i<0x500; i++) {
printk_debug("%02x%c", *(unsigned char *)i,
i%16==15 ? '\n' : ' ');
}
-
- dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
+*/
+ dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0);
if (! dev) {
printk_debug("NO VGA FOUND\n");
@@ -184,7 +277,7 @@ do_vgabios(void)
// Use VGA BIOS blob at specified address
rom = VGABIOS_START;
#else
- pci_read_config32(dev, PCI_ROM_ADDRESS, &rom);
+ rom = pci_read_config32(dev, PCI_ROM_ADDRESS);
// paranoia
rom = 0xf0000000;
pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
@@ -193,12 +286,28 @@ do_vgabios(void)
buf = (unsigned char *) rom;
if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
memcpy((void *) 0xc0000, buf, size);
+
+#define VGABIOS_WRITE_PROTECT 1
+#ifdef VGABIOS_WRITE_PROTECT
+ write_protect_vgabios();
+#endif
+
+ for(i = 0; i < 16; i++)
+ printk_debug("0x%x ", buf[i]);
+ // check signature again
+ buf = (unsigned char *) 0xc0000;
+ if (buf[0]==0x55 && buf[1]==0xAA) {
+ busdevfn = (dev->bus->secondary << 8) | dev->path.u.pci.devfn;
+ printk_debug("bus/devfn = %#x\n", busdevfn);
+
+ real_mode_switch_call_vga(busdevfn);
+ //for( i = 0 ; i < 0x500; i++){
+ // printk_debug("%02x%c",*(unsigned char *)i,
+ // i%16 == 15 ? '\n':' ');
+ //}
+ } else
+ printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
- for(i = 0; i < 16; i++)
- printk_debug("0x%x ", buf[i]);
- // check signature here later!
- busdevfn = (dev->bus->secondary << 8) | dev->devfn;
- real_mode_switch_call_vga(busdevfn);
} else
printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
#ifndef VGABIOS_START
@@ -253,6 +362,10 @@ void callbiosint(void) {
__asm__ __volatile__ (
".code16\n"
"callbiosint16:\n"
+ " push %ds \n"
+ " push %es \n"
+ " push %fs \n"
+ " push %gs \n"
// clean up the int #. To save space we put it in the lower
// byte. But the top 24 bits are junk.
"andl $0xff, %eax\n"
@@ -277,8 +390,8 @@ void callbiosint(void) {
" mov %ax, %ss \n"
" call biosint \n"
// back to real mode ...
- " ljmp $0x28, $__rms_16bit\n"
- "__rms_16bit: \n"
+ " ljmp $0x28, $__rms_16bit2\n"
+ "__rms_16bit2: \n"
".code16 \n" /* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
@@ -297,8 +410,8 @@ void callbiosint(void) {
" movl %eax, %cr0 \n"
/* Now really going into real mode */
- " ljmp $0, $__rms_real \n"
- "__rms_real: \n"
+ " ljmp $0, $__rms_real2 \n"
+ "__rms_real2: \n"
/* Setup a stack */
" mov $0x0, %ax \n"
@@ -311,10 +424,16 @@ void callbiosint(void) {
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
+ " mov $0x40, %ax \n"
+ " mov %ax, %ds \n"
// pop the INT # that you pushed earlier
" popl %eax\n"
- " popal\n"
- " iret\n"
+ " pop %gs \n"
+ " pop %fs \n"
+ " pop %es \n"
+ " pop %ds \n"
+ " popal\n"
+ " iret\n"
".code32\n"
);
}
@@ -336,12 +455,26 @@ pcibios(
unsigned long *peax,
unsigned long *pflags
);
+int
+handleint21(
+ unsigned long *pedi,
+ unsigned long *pesi,
+ unsigned long *pebp,
+ unsigned long *pesp,
+ unsigned long *pebx,
+ unsigned long *pedx,
+ unsigned long *pecx,
+ unsigned long *peax,
+ unsigned long *pflags
+ );
extern void vga_exit(void);
int
biosint(
unsigned long intnumber,
+ unsigned long gsfs,
+ unsigned long dses,
unsigned long edi,
unsigned long esi,
unsigned long ebp,
@@ -393,8 +526,12 @@ biosint(
eax = 64 * 1024;
ret = 0;
break;
+ case 0x15:
+ ret=handleint21( &edi, &esi, &ebp, &esp,
+ &ebx, &edx, &ecx, &eax, &flags);
+ break;
default:
- printk_info(__FUNCTION__ ": Unsupport int #0x%x\n",
+ printk_info("BIOSINT: Unsupport int #0x%x\n",
intnumber);
break;
}
@@ -491,7 +628,7 @@ pcibios(
unsigned short devid, vendorid, devfn;
short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
unsigned char bus;
- struct pci_dev *dev;
+ device_t dev;
switch(func) {
case CHECK:
@@ -505,7 +642,7 @@ pcibios(
vendorid = *pedx;
devindex = *pesi;
dev = 0;
- while ((dev = pci_find_device(vendorid, devid, dev))) {
+ while ((dev = dev_find_device(vendorid, devid, dev))) {
if (devindex <= 0)
break;
devindex--;
@@ -516,7 +653,7 @@ pcibios(
// busnum is an unsigned char;
// devfn is an int, so we mask it off.
busdevfn = (dev->bus->secondary << 8)
- | (dev->devfn & 0xff);
+ | (dev->path.u.pci.devfn & 0xff);
printk_debug("0x%x: return 0x%x\n", func, busdevfn);
*pebx = busdevfn;
retval = 0;
@@ -541,7 +678,7 @@ pcibios(
devfn = *pebx & 0xff;
bus = *pebx >> 8;
reg = *pedi;
- dev = pci_find_slot(bus, devfn);
+ dev = dev_find_slot(bus, devfn);
if (! dev) {
printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
@@ -563,15 +700,15 @@ pcibios(
break;
case WRITECONFBYTE:
byte = *pecx;
- write_config8(dev, reg, byte);
+ pci_write_config8(dev, reg, byte);
break;
case WRITECONFWORD:
word = *pecx;
- write_config16(dev, reg, word);
+ pci_write_config16(dev, reg, word);
break;
case WRITECONFDWORD:
- word = *pecx;
- write_config32(dev, reg, dword);
+ dword = *pecx;
+ pci_write_config32(dev, reg, dword);
break;
}
@@ -590,31 +727,46 @@ pcibios(
return retval;
}
-static void vga_init(struct chip *chip, enum chip_pass pass)
-{
- struct pc80_vgabios_config *conf =
- (struct pc80_vgabios_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_BOOT:
-
+
+int handleint21( unsigned long *edi, unsigned long *esi, unsigned long *ebp,
+ unsigned long *esp, unsigned long *ebx, unsigned long *edx,
+ unsigned long *ecx, unsigned long *eax, unsigned long *flags)
+{
+int res=-1;
+ switch(*eax&0xffff)
+ {
+ case 0x5f19:
break;
-
- default:
- /* nothing yet */
+ case 0x5f18:
+ *eax=0x5f;
+ *ebx=0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
+ // *ebx = 0x515; // MCLK = 133, 32M frame buffer, 128 M main memory
+ *ecx=0x060;
+ res=0;
+ break;
+ case 0x5f00:
+ *eax = 0x8600;
+ break;
+ case 0x5f01:
+ *eax = 0x5f;
+ *ecx = (*ecx & 0xffffff00 ) | 2; // panel type = 2 = 1024 * 768
+ res = 0;
+ break;
+ case 0x5f02:
+ *eax=0x5f;
+ *ebx= (*ebx & 0xffff0000) | 2;
+ *ecx= (*ecx & 0xffff0000) | 0x401; // PAL + crt only
+ *edx= (*edx & 0xffff0000) | 0; // TV Layout - default
+ res=0;
+ break;
+ case 0x5f0f:
+ *eax=0x860f;
+ //*ebx=0;
+ //*ecx=0;
+ //*edx=0;
+ //res=0;
break;
}
+ return res;
}
-
-static void enumerate(struct chip *chip)
-{
- /* don't really need to do anything */
-
-}
-
-struct chip_control southbridge_via_vt8231_control = {
- .enumerate = enumerate,
- .enable = vga_init,
- .name = "Legacy VGA bios"
-};
diff --git a/src/southbridge/ricoh/rl5c476/Config.lb b/src/southbridge/ricoh/rl5c476/Config.lb
new file mode 100644
index 0000000000..05c7739f5c
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object rl5c476.o
diff --git a/src/southbridge/ricoh/rl5c476/chip.h b/src/southbridge/ricoh/rl5c476/chip.h
new file mode 100644
index 0000000000..d951a8aec1
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/chip.h
@@ -0,0 +1,10 @@
+#ifndef _SOUTHBRIDGE_RICOH_RL5C476
+#define _SOUTHBRIDGE_RICOH_RL5C476
+
+extern struct chip_control southbridge_ricoh_rl5c476_control;
+
+struct southbridge_ricoh_rl5c476_config {
+ int num;
+};
+
+#endif /* _SOUTHBRIDGE_RL5C476 */
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.c b/src/southbridge/ricoh/rl5c476/rl5c476.c
new file mode 100644
index 0000000000..c6cb55cba3
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include <console/console.h>
+#include "rl5c476.h"
+#include "chip.h"
+
+static void udelay(int i){
+ for(; i > 0 ; i--)
+ inb(0x80);
+
+}
+
+static void
+dump_south(void)
+{
+ device_t dev0;
+ dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
+ dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev0);
+ int i,j;
+
+ for(i = 0; i < 256; i += 16) {
+ printk_debug("0x%x: ", i);
+ for(j = 0; j < 16; j++) {
+ printk_debug("%02x ", pci_read_config8(dev0, i+j));
+ }
+ printk_debug("\n");
+ }
+ printk_debug("Card32\n");
+ for(i = 0 ; i < 256 ; i+=16){
+ printk_debug("0x%x: ",i);
+ for(j = 0 ; j < 16 ; j++){
+ printk_debug(" %02x",*(unsigned char *)(0x80000000+i+j));
+ }
+ printk_debug("\n");
+ }
+ printk_debug("Card16\n");
+ for(i = 0; i < 256; i += 16) {
+ printk_debug("0x%x: ", i);
+ for(j = 0; j < 16; j++) {
+ printk_debug("%02x ", *(unsigned char *)(0x80000800+ i+j));
+ }
+ printk_debug("\n");
+ }
+ printk_debug("CF Config\n");
+ for(i = 0 ; i < 256 ; i+=16){
+ printk_debug("0x%x: ",i);
+ for(j=0 ; j < 16 ; j++){
+ printk_debug("%02x ",*(unsigned char *)(0x81000200 + i + j));
+ }
+ printk_debug("\n");
+ }
+}
+
+
+static void rl5c476_init(struct southbridge_rl5c476_config *conf)
+{
+ //unsigned char enables;
+ device_t dev;
+ pc16reg_t *pc16;
+ int i;
+
+ printk_debug("rl5c476 init\n");
+ /* cardbus controller function 1 for CF Socket */
+ dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
+
+ if (!dev ){
+ // probably an epia-m rather than mii
+ printk_debug("No rl5c476 found\n");
+ return;
+ }
+
+ /* setup pci header manually because 'pci_device.c' doesn't know how to handle
+ * pci to cardbus bridges - (header type 2 I think)
+ */
+
+
+ /* initialize function zero - pcmcia socket so it behaves itself */
+ /* FIXME - statically put control memory at 0xe0000000 for now
+ * one day the pci_device allocator might do this */
+ pci_write_config32(dev,0x10,0xe0000000);
+ pci_write_config8(dev,0x0d,0x20);
+ pci_write_config8(dev,0x19,0x02);
+ pci_write_config8(dev,0x1a,0x02);
+ pci_write_config8(dev,0x1b,0x20);
+ //pci_write_config8(dev,0x3c,0);
+ pci_write_config8(dev,0x82,0x00a0);
+ pci_write_config16(dev,0x04,0x07);
+
+
+ /* get second function - i.e. compact flash socket */
+ dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev);
+
+
+ /* FIXME - control structure statically declared at 0xe0008000 for now */
+ pci_write_config32(dev,0x10,0xe0008000);
+ pci_write_config8(dev,0x0d,0x20);
+ pci_write_config8(dev,0x19,0x03);
+ pci_write_config8(dev,0x1a,0x03);
+ pci_write_config8(dev,0x1b,0x20);
+
+ //pci_write_config8(dev,0x3c,0x0);
+ pci_write_config16(dev,0x3e,0x0780);
+ pci_write_config16(dev,0x82,0x00a0);
+
+ pci_write_config16(dev,0x04,0x07);
+
+
+ /* pick up where 16 bit card control structure is */
+ pc16 = (pc16reg_t *)(0xe0008800);
+
+ /* disable memory and io windows and turn off socket power */
+ pc16->pwctrl = 0;
+
+ /* disable irq lines */
+ pc16->igctrl = 0;
+
+ /* disable memory and I/O windows */
+ pc16->awinen = 0;
+
+ /* reset card, configure for I/O and set IRQ line */
+ pc16->igctrl = 0x69;
+
+
+ // set io window 0 for 1e8 - 1ef
+ pc16->iostl0 = 0xe8;
+ pc16->iosth0 = 1;
+
+ pc16->iospl0 = 0xef;
+ pc16->iosph0 = 1;
+
+ // add io offset of 8 so that CF card will decode 0x1e8 as 0x1f0 i.e. the first byte of
+ // a 16 byte aligned, 16 byte window etc
+ pc16->ioffl0 = 0x8;
+ pc16->ioffh0 = 0;
+
+ // set io window 1 for 3ed - 3ee
+ pc16->iostl1 = 0xed;
+ pc16->iosth1 = 3;
+
+ pc16->iospl1 = 0xee;
+ pc16->iosph1 = 3;
+
+ pc16->ioffl1 = 0x0;
+ pc16->ioffh1 = 0;
+
+
+ // FIXME statically declare CF config window at 0xe1000000
+ pc16->smstl0 = 0;
+ pc16->smsth0 = 0;
+ pc16->smspl0 = 0;
+ pc16->smsph0 = 0x80;
+ pc16->moffl0 = 0;
+ pc16->moffh0 = 0x40;
+ pc16->smpga0 = 0xe1;
+
+ // set I/O width for Auto Data width
+ pc16->ioctrl = 0x22;
+
+
+ // enable I/O window 0 and 1
+ pc16->awinen = 0xc1;
+
+
+ pc16->miscc1 = 1;
+
+ // apply power and enable outputs
+ pc16->pwctrl = 0xb0;
+
+
+ // delay could be optimised, but this works
+ udelay(100000);
+
+ pc16->igctrl = 0x69;
+
+ unsigned char *cptr;
+ cptr = (unsigned char *)(0xe1000200);
+ printk_debug("CF Config = %x\n",*cptr);
+
+ // FIX Me 16 bit CF always have first config byte at 0x200 into Config structure,
+ // but CF+ May Not according to spec - should locate through reading tuple data,
+ // but this will do for now !!!
+
+
+ // set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
+ // windows of the bridge set up above to map those bytes into the
+ // addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
+ *cptr = 0x41;
+
+
+}
+
+static void southbridge_init(struct chip *chip, enum chip_pass pass)
+{
+
+ struct southbridge_rl5c476_config *conf =
+ (struct southbridge_rl5c476_config *)chip->chip_info;
+
+ switch (pass) {
+ case CONF_PASS_PRE_PCI:
+ //rl5c476_pci_enable(conf);
+ break;
+
+ case CONF_PASS_POST_PCI:
+ rl5c476_init(conf);
+
+ break;
+
+ case CONF_PASS_PRE_BOOT:
+ //dump_south();
+ break;
+
+ default:
+ /* nothing yet */
+ break;
+ }
+}
+
+static void enumerate(struct chip *chip)
+{
+ extern struct device_operations default_pci_ops_bus;
+ chip_enumerate(chip);
+ chip->dev->ops = &default_pci_ops_bus;
+}
+
+struct chip_control southbridge_ricoh_rl5c476_control = {
+ .enumerate = enumerate,
+ .enable = southbridge_init,
+ .name = "RICOH RL5C476"
+};
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.h b/src/southbridge/ricoh/rl5c476/rl5c476.h
new file mode 100644
index 0000000000..c2da0de17f
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.h
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* rl5c476 routines and defines*/
+
+
+typedef unsigned char u8;
+
+
+/* the 16 bit control structure for ricoh cardbus bridge */
+typedef struct pc16reg {
+ u8 idrevs;
+ u8 ifstat;
+ u8 pwctrl;
+ u8 igctrl;
+ u8 cschg;
+ u8 cscint;
+ u8 awinen;
+ u8 ioctrl;
+ u8 iostl0;
+ u8 iosth0;
+ u8 iospl0;
+ u8 iosph0;
+ u8 iostl1;
+ u8 iosth1;
+ u8 iospl1;
+ u8 iosph1;
+ u8 smstl0;
+ u8 smsth0;
+ u8 smspl0;
+ u8 smsph0;
+ u8 moffl0;
+ u8 moffh0;
+ u8 cdgenc;
+ u8 resv1;
+ u8 smstl1;
+ u8 smsth1;
+ u8 smspl1;
+ u8 smsph1;
+ u8 moffl1;
+ u8 moffh1;
+ u8 glctrl;
+ u8 atctrl;
+ u8 smstl2;
+ u8 smsth2;
+ u8 smspl2;
+ u8 smsph2;
+ u8 moffl2;
+ u8 moffh2;
+ u8 resv2;
+ u8 resv3;
+ u8 smstl3;
+ u8 smsth3;
+ u8 smspl3;
+ u8 smsph3;
+ u8 moffl3;
+ u8 moffh3;
+ u8 resv4;
+ u8 miscc1;
+ u8 smstl4;
+ u8 smsth4;
+ u8 smspl4;
+ u8 smsph4;
+ u8 moffl4;
+ u8 moffh4;
+ u8 ioffl0;
+ u8 ioffh0;
+ u8 ioffl1;
+ u8 ioffh1;
+ u8 gpio;
+ u8 resv5;
+ u8 resv6;
+ u8 resv7;
+ u8 resv8;
+ u8 resv9;
+ u8 smpga0;
+} __attribute__ ((packed)) pc16reg_t;
+
+
+
diff --git a/src/southbridge/via/vt8235/vt8235.c b/src/southbridge/via/vt8235/vt8235.c
index ca5ab32ac3..fc4c6a6186 100644
--- a/src/southbridge/via/vt8235/vt8235.c
+++ b/src/southbridge/via/vt8235/vt8235.c
@@ -9,6 +9,8 @@
#include "vt8235.h"
#include "chip.h"
+void rtc_init(int i);
+
void pc_keyboard_init(void);
void hard_reset(void)
@@ -23,67 +25,78 @@ static void usb_on(int enable)
/* Base 8235 controller */
device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
/* USB controller 1 */
- device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
+ device_t dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
/* USB controller 2 */
- device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
-
- /* enable USB1 */
- if(dev2) {
- if (enable) {
- pci_write_config8(dev2, 0x3c, 0x05);
- pci_write_config8(dev2, 0x04, 0x07);
- } else {
- pci_write_config8(dev2, 0x3c, 0x00);
- pci_write_config8(dev2, 0x04, 0x00);
+ device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev1);
+ /* USB controller 2 */
+ device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C586_2, dev2);
+
+ if(enable){
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ regval &= ~(0x36);
+ pci_write_config8(dev0, 0x50, regval);
}
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x10);
- else
- regval |= 0x10;
- pci_write_config8(dev0, 0x50, regval);
- }
-
- /* enable USB2 */
- if(dev3) {
- if (enable) {
- pci_write_config8(dev3, 0x3c, 0x05);
- pci_write_config8(dev3, 0x04, 0x07);
- } else {
- pci_write_config8(dev3, 0x3c, 0x00);
- pci_write_config8(dev3, 0x04, 0x00);
+
+ /* enable USB1 */
+ if(dev1) {
+ pci_write_config8(dev1, 0x04, 0x07);
+ }
+
+ /* enable USB2 */
+ if(dev2) {
+ pci_write_config8(dev2, 0x04, 0x07);
+ }
+
+ /* enable USB3 */
+ if(dev3) {
+ pci_write_config8(dev3, 0x04, 0x07);
+ }
+
+ }else{
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ regval |= 0x36;
+ pci_write_config8(dev0, 0x50, regval);
+ }
+
+ /* disable USB1 */
+ if(dev1) {
+ pci_write_config8(dev1, 0x3c, 0x00);
+ pci_write_config8(dev1, 0x04, 0x00);
+ }
+
+ /* disable USB2 */
+ if(dev2) {
+ pci_write_config8(dev2, 0x3c, 0x00);
+ pci_write_config8(dev2, 0x04, 0x00);
+ }
+
+ /* disable USB3 */
+ if(dev3) {
+ pci_write_config8(dev3, 0x3c, 0x00);
+ pci_write_config8(dev3, 0x04, 0x00);
}
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x20);
- else
- regval |= 0x20;
- pci_write_config8(dev0, 0x50, regval);
}
}
static void keyboard_on(void)
{
unsigned char regval;
-
+
/* Base 8235 controller */
- device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
-
- /* kevinh/Ispiri - update entire function to use
- new pci_write_config8 */
+ device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
+ PCI_DEVICE_ID_VIA_8235, 0);
if (dev0) {
regval = pci_read_config8(dev0, 0x51);
- regval |= 0x0f;
+// regval |= 0x0f;
+ /* !!!FIX let's try this */
+ regval |= 0x1d;
pci_write_config8(dev0, 0x51, regval);
}
- init_pc_keyboard(0x60, 0x64, 0);
+ pc_keyboard_init();
}
static void nvram_on(void)
@@ -152,16 +165,43 @@ static void vt8235_pci_enable(struct southbridge_via_vt8235_config *conf)
*/
void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]);
+/* taken some liberties - changed irq structures to pins numbers so that it is easier to
+ * change PCI irq assignments without having to change each PCI function individually
+ */
-static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
-
+/* pciIrqs contains the irqs assigned for PCI pins A-D */
+/* setting will depend on motherboard as irqs can be quite scarce */
+/* e.g on EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia socket */
+/* may want another - for now only claim 3 interupts for PCI, leaving at least one spare */
+/* for CF. */
+/* On EPIA-M one could allocated all four irqs to different numbers since there are no cardbus */
+/* devices */
+
+
+static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 10 };
+
+static const unsigned char usbPins[4] = { 'A','B','C','D'};
+static const unsigned char enetPins[4] = { 'A','B','C','D'};
+static const unsigned char slotPins[4] = { 'B','C','D','A'};
+static const unsigned char firewirePins[4] = { 'B','C','D','A'};
+static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
+static const unsigned char vgaPins[4] = { 'A','B','C','D'};
+static const unsigned char cbPins[4] = { 'A','B','C','D'};
+static const unsigned char riserPins[4] = { 'A','B','C','D'};
/*
Our IDSEL mappings are as follows
PCI slot is AD31 (device 15) (00:14.0)
Southbridge is AD28 (device 12) (00:11.0)
*/
+static unsigned char *pin_to_irq(const unsigned char *pin)
+{
+ static unsigned char Irqs[4];
+ int i;
+ for (i = 0 ; i < 4 ; i++)
+ Irqs[i] = pciIrqs[ pin[i] - 'A' ];
+
+ return Irqs;
+}
static void pci_routing_fixup(void)
{
device_t dev;
@@ -177,23 +217,47 @@ static void pci_routing_fixup(void)
PINTC = IRQ10
PINTD = IRQ12
*/
- pci_write_config8(dev, 0x55, 0xb0);
- pci_write_config8(dev, 0x56, 0xa5);
- pci_write_config8(dev, 0x57, 0xc0);
+ pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+ pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+ pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
}
- // Standard southbridge components
- printk_info("setting southbridge\n");
- pci_assign_irqs(0, 0x11, southbridgeIrqs);
+
+
+ // firewire built into southbridge
+ printk_info("setting firewire\n");
+ pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins) );
+
+ // Standard usb components
+ printk_info("setting usb\n");
+ pci_assign_irqs(0, 0x10, pin_to_irq(usbPins) );
+
+ // VT8235 + sound hardware
+ printk_info("setting vt8235\n");
+ pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins) );
// Ethernet built into southbridge
printk_info("setting ethernet\n");
- pci_assign_irqs(0, 0x12, enetIrqs);
+ pci_assign_irqs(0, 0x12, pin_to_irq(enetPins) );
+
+ // VGA
+ printk_info("setting vga\n");
+ pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins) );
// PCI slot
printk_info("setting pci slot\n");
- pci_assign_irqs(0, 0x14, slotIrqs);
- printk_info("%s: DONE\n", __FUNCTION__);
+ pci_assign_irqs(0, 0x14, pin_to_irq(slotPins) );
+
+ // Cardbus slot
+ printk_info("setting cardbus slot\n");
+ pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins) );
+
+ // Via 2 slot riser card 2nd slot
+ printk_info("setting riser slot\n");
+ pci_assign_irqs(0, 0x13, pin_to_irq(riserPins) );
+
+
}
@@ -213,13 +277,76 @@ dump_south(void)
}
}
+void set_led(void)
+{
+
+ // set power led to steady now that lxbios has virtually done its job
+ device_t dev0;
+ dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,0);
+
+ pci_write_config8(dev0,0x94,0xb0);
+
+}
+
+/* set up the power management capabilities directly into ACPI mode */
+/* this avoids having to handle any System Management Interrupts (SMI's) which I can't */
+/* figure out how to do !!!! */
+
+void setup_pm(device_t dev0)
+{
+
+ // Set gen config 0
+ pci_write_config8(dev0,0x80,0x20);
+
+ // Set ACPI base address to IO 0x4000
+ pci_write_config16(dev0, 0x88, 0x0401);
+
+ // set ACPI irq to 5
+ pci_write_config8(dev0,0x82,0x55);
+
+ // primary interupt channel
+ pci_write_config16(dev0,0x84,0x30f2);
+
+ // throttle / stop clock control
+ pci_write_config8(dev0,0x8d,0x18);
+
+ pci_write_config8(dev0,0x93,0x88);
+ //pci_write_config8(dev0,0x94,0xb0);
+ pci_write_config8(dev0,0x95,0xc0);
+ pci_write_config8(dev0,0x98,0);
+ pci_write_config8(dev0,0x99,0xea);
+ pci_write_config8(dev0,0xe4,0x14);
+ pci_write_config8(dev0,0xe5,0x08);
+
+
+ // Enable ACPI access (and setup like award)
+ pci_write_config8(dev0, 0x81, 0x84);
+
+ outw(0xffff,0x400);
+ outw(0xffff,0x420);
+ outw(0xffff,0x428);
+ outl(0xffffffff,0x430);
+
+ outw(0x0,0x424);
+ outw(0x0,0x42a);
+ outw(0x1,0x42c);
+ outl(0x0,0x434);
+ outl(0x01,0x438);
+ outb(0x0,0x442);
+ outl(0xffff7fff,0x448);
+ outw(0x001,0x404);
+
+
+}
+
static void vt8235_init(struct southbridge_via_vt8235_config *conf)
{
unsigned char enables;
device_t dev0;
device_t dev1;
- device_t devpwr;
-
+ //device_t devpwr;
+ //int i;
+
// to do: use the pcibios_find function here, instead of
// hard coding the devfn.
// done - kevinh/Ispiri
@@ -243,6 +370,7 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
// interrupts can be properly marked as level triggered.
enables = pci_read_config8(dev0, 0x40);
+ enables |= 0x45;
pci_write_config8(dev0, 0x40, enables);
// Set 0x42 to 0xf0 to match Award bios
@@ -250,6 +378,17 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
enables |= 0xf0;
pci_write_config8(dev0, 0x42, enables);
+
+ /* Set 0x58 to 0x03 to match Award */
+ pci_write_config8(dev0, 0x58, 0x03);
+
+ /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
+ enables = pci_read_config8(dev0, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev0, 0x4f, enables);
+
+
+
// Set bit 3 of 0x4a, to match award (dummy pci request)
enables = pci_read_config8(dev0, 0x4a);
enables |= 0x08;
@@ -271,68 +410,24 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
}
- // enable com1 and com2.
- if (conf->enable_com_ports) {
- enables = pci_read_config8(dev0, 0x6e);
-
- /* 0x80 is enable com port b, 0x10 is to make it com2, 0x8
- * is enable com port a as com1 kevinh/Ispiri - Old code
- * thought 0x01 would make it com1, that was wrong enables =
- * 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e,
- * enables); // note: this is also a redo of some port of
- * assembly, but we want everything up.
- */
-
- /* set com1 to 115 kbaud not clear how to do this yet.
- * forget it; done in assembly.
- */
+ /* enable serial irq */
+ pci_write_config8(dev0,0x52,0x9);
+
+ /* dma */
+ pci_write_config8(dev0, 0x53, 0x00);
+
+ /* Use compatability mode - per award bios */
+ pci_write_config32(dev1, 0x10, 0x0);
+ pci_write_config32(dev1, 0x14, 0x0);
+ pci_write_config32(dev1, 0x18, 0x0);
+ pci_write_config32(dev1, 0x1c, 0x0);
+
- }
- // enable IDE, since Linux won't do it.
- // First do some more things to devfn (17,0)
- // note: this should already be cleared, according to the book.
- enables = pci_read_config8(dev0, 0x50);
- printk_debug("IDE enable in reg. 50 is 0x%x\n", enables);
- enables &= ~8; // need manifest constant here!
- printk_debug("set IDE reg. 50 to 0x%x\n", enables);
- pci_write_config8(dev0, 0x50, enables);
-
- // set default interrupt values (IDE)
- enables = pci_read_config8(dev0, 0x4c);
- printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf);
- // clear out whatever was there.
- enables &= ~0xf;
- enables |= 4;
- printk_debug("setting reg. 4c to 0x%x\n", enables);
- pci_write_config8(dev0, 0x4c, enables);
-
- // set up the serial port interrupts.
- // com2 to 3, com1 to 4
- pci_write_config8(dev0, 0x46, 0x04);
- pci_write_config8(dev0, 0x47, 0x03);
- pci_write_config8(dev0, 0x6e, 0x98);
- //
// Power management setup
- //
- // Set ACPI base address to IO 0x4000
- //pci_write_config32(devpwr, 0x48, 0x4001);
-
- // Enable ACPI access (and setup like award)
- //pci_write_config8(devpwr, 0x41, 0x84);
-
- // Set hardware monitor base address to IO 0x6000
- //pci_write_config32(devpwr, 0x70, 0x6001);
-
- // Enable hardware monitor (and setup like award)
- //pci_write_config8(devpwr, 0x74, 0x01);
-
- // set IO base address to 0x5000
- //pci_write_config32(devpwr, 0x90, 0x5001);
-
- // Enable SMBus
- //pci_write_config8(devpwr, 0xd2, 0x01);
+ setup_pm(dev0);
//
+ //
// IDE setup
//
if (! conf->enable_native_ide) {
@@ -422,6 +517,8 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
// Start the rtc
rtc_init(0);
+
+
}
static void southbridge_init(struct chip *chip, enum chip_pass pass)
@@ -436,12 +533,23 @@ static void southbridge_init(struct chip *chip, enum chip_pass pass)
break;
case CONF_PASS_POST_PCI:
+ /* initialise the PIC - particularly so that VGA bios init code
+ doesn't get nasty unknown interupt vectors when it tries to establish
+ its interrupts. */
+ setup_i8259();
vt8235_init(conf);
pci_routing_fixup();
+ usb_on(1);
+ keyboard_on();
+ vga_fixup();
+
+
+
break;
case CONF_PASS_PRE_BOOT:
dump_south();
+ set_led();
break;
default:
diff --git a/src/southbridge/via/vt8235/vt8235_early_smbus.c b/src/southbridge/via/vt8235/vt8235_early_smbus.c
index 79b73df01e..26beea933b 100644
--- a/src/southbridge/via/vt8235/vt8235_early_smbus.c
+++ b/src/southbridge/via/vt8235/vt8235_early_smbus.c
@@ -29,35 +29,64 @@ static void enable_smbus(void)
{
device_t dev;
unsigned char c;
+ int i;
/* Power management controller */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
if (dev == PCI_DEV_INVALID) {
die("SMBUS controller not found\r\n");
- }
-
+ }
+ pci_write_config8(dev, 0xd2, (0x4 << 1 ));
+
// set IO base address to SMBUS_IO_BASE
- pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
+ pci_write_config16(dev, 0xd0, SMBUS_IO_BASE);
// Enable SMBus
pci_write_config8(dev, 0xd2, (0x4 << 1)|1);
+ // Enable RTC
+ pci_write_config8(dev,0x51,0x04);
+
/* make it work for I/O ...
*/
- pci_write_config8(dev, 4, 1);
+ pci_write_config16(dev, 4, 1);
+
+
+ /* tell the world we're alive - make power led flash during bios execution */
+ pci_write_config8(dev,0x94,0xb2);
+
+
+ /* FIX for half baud rate problem */
+ /* let clocks and the like settle */
+ /* as yet arbitrary count - 1000 is too little 5000 works */
+ for(i = 0 ; i < 5000 ; i++)
+ outb(0x80,0x80);
+
+ /* southbridge doesn't seem to like to do much untill after this delay, so set up
+ * the flashing power LED again */
+ pci_write_config8(dev,0x94,0xb2);
/* The VT1211 serial port needs 48 mhz clock, on power up it is getting
only 24 mhz, there is some mysterious device on the smbus that can
fix this...this code below does it. */
outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+ outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+ outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+ outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+ for( ;;) {
+ c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
+ if ((c & 1) == 0)
+ break;
+ }
outb(0x7f, SMBUS_IO_BASE+SMBHSTDAT0);
outb(0x83, SMBUS_IO_BASE+SMBHSTCMD);
- outb(CLOCK_SLAVE_ADDRESS<<1, SMBUS_IO_BASE+SMBXMITADD);
+ outb(CLOCK_SLAVE_ADDRESS<<1 , SMBUS_IO_BASE+SMBXMITADD);
outb(8 | I2C_TRANS_CMD, SMBUS_IO_BASE+SMBHSTCTL);
+
for (;;) {
c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
- if (c & 1 == 0)
+ if ((c & 1) == 0)
break;
}
}
@@ -173,8 +202,9 @@ static unsigned char smbus_read_byte(unsigned char devAdr,
/* SMBUS Wait Ready */
for ( i = 0; i < 0xFFFF; i++ )
- if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
+ if ( ((sts = (inb(SMBUS_IO_BASE) & 0x1f)) & 0x01) == 0 )
break;
+
if ((sts & ~3) != 0) {
smbus_print_error(sts);
return 0;
diff --git a/src/superio/via/vt1211/Config.lb b/src/superio/via/vt1211/Config.lb
new file mode 100644
index 0000000000..a1dfde020e
--- /dev/null
+++ b/src/superio/via/vt1211/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object vt1211.o
diff --git a/src/superio/via/vt1211/chip.h b/src/superio/via/vt1211/chip.h
new file mode 100644
index 0000000000..76a5a5babd
--- /dev/null
+++ b/src/superio/via/vt1211/chip.h
@@ -0,0 +1,19 @@
+#ifndef _SUPERIO_VIA_VT1211
+#define _SUPERIO_VIA_VT1211
+
+extern struct chip_control superio_via_vt1211_control;
+
+struct superio_via_vt1211_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!
+ */
+ /* enables of functions of devices */
+ int enable_com_ports;
+ int enable_fdc;
+ int enable_lpt;
+ int enable_hwmon;
+};
+
+#endif /* _SUPERIO_VIA_VT1211 */
diff --git a/src/superio/via/vt1211/vt1211.c b/src/superio/via/vt1211/vt1211.c
new file mode 100644
index 0000000000..26d9356a61
--- /dev/null
+++ b/src/superio/via/vt1211/vt1211.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* vt1211 routines and defines*/
+
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include <console/console.h>
+#include "vt1211.h"
+#include "chip.h"
+
+
+static unsigned char vt1211hwmonitorinits[]={
+ 0x10,0x3, 0x11,0x10, 0x12,0xd, 0x13,0x7f,
+ 0x14,0x21, 0x15,0x81, 0x16,0xbd, 0x17,0x8a,
+ 0x18,0x0, 0x19,0x0, 0x1a,0x0, 0x1b,0x0,
+ 0x1d,0xff, 0x1e,0x0, 0x1f,0x73, 0x20,0x67,
+ 0x21,0xc1, 0x22,0xca, 0x23,0x74, 0x24,0xc2,
+ 0x25,0xc7, 0x26,0xc9, 0x27,0x7f, 0x29,0x0,
+ 0x2a,0x0, 0x2b,0xff, 0x2c,0x0, 0x2d,0xff,
+ 0x2e,0x0, 0x2f,0xff, 0x30,0x0, 0x31,0xff,
+ 0x32,0x0, 0x33,0xff, 0x34,0x0, 0x39,0xff,
+ 0x3a,0x0, 0x3b,0xff, 0x3c,0xff, 0x3d,0xff,
+ 0x3e,0x0, 0x3f,0xb0, 0x43,0xff, 0x44,0xff,
+ 0x46,0xff, 0x47,0x50, 0x4a,0x3, 0x4b,0xc0,
+ 0x4c,0x0, 0x4d,0x0, 0x4e,0xf, 0x5d,0x77,
+ 0x5c,0x0, 0x5f,0x33, 0x40,0x1};
+
+static void start_conf_pnp(int dev)
+{
+ outb(0x87,0x2e);
+ outb(0x87,0x2e);
+ outb(7,0x2e);
+ outb(dev,0x2f);
+}
+static void write_pnp(int reg, int val)
+{
+ outb(reg,0x2e);
+ outb(val,0x2f);
+}
+static void end_conf_pnp()
+{
+ outb(0xaa,0x2e);
+}
+
+static void vt1211_init(struct superio_via_vt1211_config *conf)
+{
+
+ int i;
+ // Activate the vt1211 hardware monitor
+ if(conf->enable_hwmon){
+ start_conf_pnp(0x0b);
+ write_pnp(0x60,0xec);
+ write_pnp(0x30,1);
+ end_conf_pnp();
+
+ // initialize vt1211 hardware monitor registers, which are at 0xECXX
+ for(i=0;i<sizeof(vt1211hwmonitorinits);i+=2)
+ outb(vt1211hwmonitorinits[i+1],0xec00+vt1211hwmonitorinits[i]);
+ }
+ if( conf->enable_fdc){
+ // activate FDC
+ start_conf_pnp(0); // fdc is device 0
+ write_pnp(0x60,0xfc); // io address
+ write_pnp(0x70,0x06); // interupt
+ write_pnp(0x74,0x02); // dma
+ write_pnp(0x30,0x01); // activate it
+ end_conf_pnp();
+ }
+
+ if( conf->enable_com_ports ){
+ // activate com2
+ start_conf_pnp(3);
+ write_pnp(0x60,0xbe);
+ write_pnp(0x70,0x3);
+ write_pnp(0xf0,0x02);
+ write_pnp(0x30,0x01);
+ end_conf_pnp();
+ }
+
+ if( conf->enable_lpt ){
+ // activate lpt
+ start_conf_pnp(1);
+ write_pnp(0x60,0xde);
+ write_pnp(0x70,0x07);
+ write_pnp(0x74,0x3);
+ write_pnp(0x30,0x01);
+ end_conf_pnp();
+ }
+
+}
+
+static void superio_init(struct chip *chip, enum chip_pass pass)
+{
+
+ struct superio_via_vt1211_config *conf =
+ (struct superio_via_vt1211_config *)chip->chip_info;
+
+ switch (pass) {
+ case CONF_PASS_PRE_PCI:
+ break;
+
+ case CONF_PASS_POST_PCI:
+ vt1211_init(conf);
+ break;
+
+ case CONF_PASS_PRE_BOOT:
+ break;
+
+ default:
+ /* nothing yet */
+ break;
+ }
+}
+
+static void enumerate(struct chip *chip)
+{
+ extern struct device_operations default_pci_ops_bus;
+ chip_enumerate(chip);
+ chip->dev->ops = &default_pci_ops_bus;
+}
+
+struct chip_control superio_via_vt1211_control = {
+ .enumerate = enumerate,
+ .enable = superio_init,
+ .name = "VIA vt1211"
+};
diff --git a/src/superio/via/vt1211/vt1211.h b/src/superio/via/vt1211/vt1211.h
new file mode 100644
index 0000000000..0d3d620df2
--- /dev/null
+++ b/src/superio/via/vt1211/vt1211.h
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* vt1211 routines and defines*/
+