[LinuxBIOS] [PATCH] VIA VT8237R support

Corey Osgood corey.osgood at gmail.com
Sun Oct 28 02:22:04 CEST 2007


Rudolf Marek wrote:
> Hi all,
>
> Attaching fixed version. I left the dump_south and writeback there,
> I have in plan to remove the "writeback" function in near future,
> and for the dump_south I'm not sure how to handle the case when the
> debugging is
> switched off. I hope it is OK to accept it as it is right now, since
> my primary goal is to make it available.
>
> Signed-off-by: Rudolf Marek <r.marek at assembler.cz>
>
> Rudolf

Sorry I haven't gotten to this yet, been very busy lately. I'll
hopefully be back at work on the cn700 tomorrow, trying to get it ready
to go in the tree, so I'd like to see this in as well. Just a few little
things:

> Index: src/southbridge/via/vt8237r/vt8237r.c
> ===================================================================
> --- src/southbridge/via/vt8237r/vt8237r.c	(revision 0)
> +++ src/southbridge/via/vt8237r/vt8237r.c	(revision 0)
> @@ -0,0 +1,82 @@
> +/*
> + * This file is part of the LinuxBIOS project.
> + *
> + * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License v2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +#include <console/console.h>
> +#include <device/device.h>
> +#include <device/pci.h>
> +#include <device/pci_ops.h>
> +#include <device/pci_ids.h>
> +#include <pc80/keyboard.h>
> +#include "chip.h"
> +
> +/* 
> + * Datasheets: http://www.via.com.tw/en/downloads/datasheets/chipsets/
> + *		VT8237R_SouthBridge_Revision2.06_Lead-Free.zip
> +*/
> +
> +void hard_reset(void)
> +{
> +	printk_err("NO HARD RESET ON VT8237R! FIX ME!\n");
> +}
> +
> +void writeback(struct device *dev, u16 where, u8 what)
> +{
> +	u8 regval;
> +
> +	pci_write_config8(dev, where, what);
> +	regval = pci_read_config8(dev, where);
> +	if (regval != what) {
> +		print_debug("Writeback to ");
> +		print_debug_hex8(where);
> +		print_debug("failed ");
> +		print_debug_hex8(regval);
> +		print_debug("\n ");
> +	}
> +}
>   

Perhaps something like

#if DEFAULT_CONSOLE_LOGLEVEL < 8 //8 = debug level
inline void writeback(...)
{
    pci_write_config8(...);
}
#else
(original function)
#endif

writeback() seems like it could be a very useful bit of debugging code.
Renaming to writeback8 (for clarity's sake) would also be good too. The
biggest problem with the above is that it won't turn on/off if the
console log level is changed by, say, lxbios or uwe's boot menu. Only a
suggestion though

> +static void vt8237r_enable(struct device *dev)
> +{
> +	struct southbridge_via_vt8237r_config *sb =
> +	(struct southbridge_via_vt8237r_config *) dev->chip_info;
> +
> +	pci_write_config8(dev, 0x50, sb->fn_ctrl_lo);
> +	pci_write_config8(dev, 0x51, sb->fn_ctrl_hi);
> +
> +	/* TODO: if SATA is disabled, move IDE to fn0 to conform PCI specs */
>   

I have a little piece of code to do this, I've just got to figure out
where/how to do it. Leave it as is and I'll take care of later.

> +}
> +
> +struct chip_operations southbridge_via_vt8237r_ops = {
> +	CHIP_NAME("VIA VT8237R Southbridge")
> +	    .enable_dev = vt8237r_enable,
> +};
>   

> Index: src/southbridge/via/vt8237r/vt8237r_lpc.c
> ===================================================================
> --- src/southbridge/via/vt8237r/vt8237r_lpc.c	(revision 0)
> +++ src/southbridge/via/vt8237r/vt8237r_lpc.c	(revision 0)
> @@ -0,0 +1,305 @@
> +/*
> + * This file is part of the LinuxBIOS project.
> + * Inspiration from other VIA SB code.
> + * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License v2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +#include <arch/io.h>
> +#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 <cpu/x86/lapic.h>
> +#include <stdlib.h>
> +
> +#include "vt8237r.h"
> +#include "chip.h"
> +
> +#define ALL		(0xff << 24)
> +#define NONE		(0)
> +#define DISABLED	(1 << 16)
> +#define ENABLED		(0 << 16)
> +#define TRIGGER_EDGE	(0 << 15)
> +#define TRIGGER_LEVEL	(1 << 15)
> +#define POLARITY_HIGH	(0 << 13)
> +#define POLARITY_LOW	(1 << 13)
> +#define PHYSICAL_DEST	(0 << 11)
> +#define LOGICAL_DEST	(1 << 11)
> +#define ExtINT		(7 << 8)
> +#define NMI		(4 << 8)
> +#define SMI		(2 << 8)
> +#define INT		(1 << 8)
> +
> +extern void dump_south(device_t dev);
> +
> +struct ioapicreg {
> +	u32 reg;
> +	u32 value_low;
> +	u32 value_high;
> +} ioapic_table[] = {
> +	/* IO-APIC virtual wire mode configuration */
> +	/* mask, trigger, polarity, destination, delivery, vector */
> +	{0,
> +	 ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT,
> +	 NONE},
> +	{1, DISABLED, NONE},
> +	{2, DISABLED, NONE},
> +	{3, DISABLED, NONE},
> +	{4, DISABLED, NONE},
> +	{5, DISABLED, NONE},
> +	{6, DISABLED, NONE},
> +	{7, DISABLED, NONE},
> +	{8, DISABLED, NONE},
> +	{9, DISABLED, NONE},
> +	{10, DISABLED, NONE},
> +	{11, DISABLED, NONE},
> +	{12, DISABLED, NONE},
> +	{13, DISABLED, NONE},
> +	{14, DISABLED, NONE},
> +	{15, DISABLED, NONE},
> +	{16, DISABLED, NONE},
> +	{17, DISABLED, NONE},
> +	{18, DISABLED, NONE},
> +	{19, DISABLED, NONE},
> +	{20, DISABLED, NONE},
> +	{21, DISABLED, NONE},
> +	{22, DISABLED, NONE},
> +	{23, DISABLED, NONE},
> +};
> +
> +static void setup_ioapic(u32 ioapic_base)
> +{
> +	u32 value_low, value_high, val;
> +	volatile u32 *l;
> +	int i;
> +
> +	/* all delivered to CPU0 */
> +	ioapic_table[0].value_high = (lapicid()) << (56 - 32);
> +	l = (unsigned long *) ioapic_base;
> +	/* set APIC to FSB message bus */
> +	l[0] = 0x3;
> +	val = l[4];
> +	l[4] = (val & 0xFFFFFE) | 1;
> +	/* set APIC ADDR - this will be VT8237R_APIC_ID */
> +	l[0] = 0;
> +	val = l[4];
> +	l[4] = (val & 0xF0FFFF) | (VT8237R_APIC_ID << 24);
> +
> +	for (i = 0; i < ARRAY_SIZE(ioapic_table); i++) {
> +		l[0] = (ioapic_table[i].reg * 2) + 0x10;
> +		l[4] = ioapic_table[i].value_low;
> +		value_low = l[4];
> +		l[0] = (ioapic_table[i].reg * 2) + 0x11;
> +		l[4] = ioapic_table[i].value_high;
> +		value_high = l[4];
> +		if ((i == 0) && (value_low == 0xffffffff)) {
> +			printk_warning("IO APIC not responding.\n");
> +			return;
> +		}
> +	}
> +}
> +
> +static void pci_routing_fixup(struct device *dev)
> +{
> +	/* set up PCI IRQ routing, route everything through APIC */
> +	pci_write_config8(dev, 0x44, 0x00);	/* PCI PNP Interrupt Routing INTE/F - disable */
> +	pci_write_config8(dev, 0x45, 0x00);	/* PCI PNP Interrupt Routing INTG/H - disable */
> +	pci_write_config8(dev, 0x46, 0x10);	/* Route INTE-INTH through registers above, no map to INTA-INTD */
> +	pci_write_config8(dev, 0x54, 0x00);	/* PCI Interrupt Polarity */
> +	pci_write_config8(dev, 0x55, 0x00);	/* PCI INTA# Routing */
> +	pci_write_config8(dev, 0x56, 0x00);	/* PCI INTB#/C# Routing */
> +	pci_write_config8(dev, 0x57, 0x00);	/* PCI INTD# Routing */
> +}
> +
> +/* 
> + * Set up the power management capabilities directly into ACPI mode.  This
> + * avoids having to handle any System Management Interrupts (SMI's)
> + */
> +
> +void setup_pm(device_t dev)
> +{
> +	/* Debounce LID and PWRBTN# Inputs for 16ms */
> +	pci_write_config8(dev, 0x80, 0x20);
> +	/* Set ACPI base address to IO VT8237R_ACPI_IO_BASE */
> +	pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
> +	/* set ACPI to 9, need to set IRQ 9 override to level!
> +	   set PSON gating */
> +	pci_write_config8(dev, 0x82, 0x40 | VT8237R_ACPI_IRQ);
> +	/* primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en */
> +	pci_write_config16(dev, 0x84, 0x30b2);
> +	/* SMI output level to low, 7.5us throttle clock */
> +	pci_write_config8(dev, 0x8d, 0x18);
> +	/* GP Timer Control 1s */
> +	pci_write_config8(dev, 0x93, 0x88);
> +	/* 7=SMBus Clock from RTC 32.768KHz
> +	 * 5=Internall PLL reset from susp
> +	 * 2= GPO2 is GPIO
> +	 */
> +	pci_write_config8(dev, 0x94, 0xa4);
> +	/* 7=stp to sust delay 1msec, 
> +	 * 6=SUSST# Deasserted Before PWRGD for STD
> +	 * 3=GPO26/GPO27 is GPO 
> +	 * 2=Disable Alert on Lan
> +	 */
> +	pci_write_config8(dev, 0x95, 0xcc);
> +	/* Disable GP3 timer */
> +	pci_write_config8(dev, 0x98, 0);
> +	/* enable SATA LED, disable special CPU Frequency Change -
> +	   GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs */
> +	pci_write_config8(dev, 0xe5, 0x9);
> +	/* REQ5 as PCI request input - should be together with  INTE-INTH */
> +	pci_write_config8(dev, 0xe4, 0x4);
> +	/* Enable ACPI accessm RTC signal gated with PSON */
> +	pci_write_config8(dev, 0x81, 0x84);
> +	/* clear status events */
> +	outw(0xffff, VT8237R_ACPI_IO_BASE + 0x00);
> +	outw(0xffff, VT8237R_ACPI_IO_BASE + 0x20);
> +	outw(0xffff, VT8237R_ACPI_IO_BASE + 0x28);
> +	outl(0xffffffff, VT8237R_ACPI_IO_BASE + 0x30);
> +	/* disable SCI on GPIO */
> +	outw(0x0, VT8237R_ACPI_IO_BASE + 0x22);
> +	/* disable SMI on GPIO */
> +	outw(0x0, VT8237R_ACPI_IO_BASE + 0x24);
> +	/* disable all global enable SMIs */
> +	outw(0x0, VT8237R_ACPI_IO_BASE + 0x2a);
> +	/* all SMI off, both IDE buses ON, PSON rising edge */
> +	outw(0x0, VT8237R_ACPI_IO_BASE + 0x2c);
> +	/* primary activity SMI disable */
> +	outl(0x0, VT8237R_ACPI_IO_BASE + 0x34);
> +	/* GP timer reload on none */
> +	outl(0x0, VT8237R_ACPI_IO_BASE + 0x38);
> +	/* disable extended IO traps */
> +	outb(0x0, VT8237R_ACPI_IO_BASE + 0x42);
> +	/* SCI is generated for RTC/pwrBtn/slpBtn */
> +	outw(0x001, VT8237R_ACPI_IO_BASE + 0x04);
> +}
> +
> +static void vt8237r_init(struct device *dev)
> +{
> +	u8 enables, byte;
> +
> +	/* enable addr/data stepping */
> +	byte = pci_read_config8(dev, PCI_COMMAND);
> +	byte |= PCI_COMMAND_WAIT;
> +	pci_write_config8(dev, PCI_COMMAND, byte);
> +
> +	/* enable the internal I/O decode */
> +	enables = pci_read_config8(dev, 0x6C);
> +	enables |= 0x80;
> +	pci_write_config8(dev, 0x6C, enables);
> +
> +	/* FIXME Map 4MB of FLASH into the address space,
> +	   this should be in CAR call */
> +	/* pci_write_config8(dev, 0x41, 0x7f); */
> +
> +	/* Set bit 6 of 0x40, (IO recovery time)
> +	   IMPORTANT FIX - EISA = ECLR reg at 0x4d0! Decoding must be on so that PCI 
> +	   interrupts can be properly marked as level triggered. */
> +	enables = pci_read_config8(dev, 0x40);
> +	enables |= 0x44;
> +	pci_write_config8(dev, 0x40, enables);
> +
> +	/* Line buffer control */
> +	enables = pci_read_config8(dev, 0x42);
> +	enables |= 0xf8;
> +	pci_write_config8(dev, 0x42, enables);
> +
> +	/* Delay Transaction Control */
> +	pci_write_config8(dev, 0x43, 0xb);
> +	/* IO Recovery time */
> +	pci_write_config8(dev, 0x4c, 0x44);
> +	/* ROM Memory Cycles Go To LPC */
> +	pci_write_config8(dev, 0x59, 0x80);
> +	/* bypass Bypass APIC De-Assert Message,  INTE#, INTF#, INTG#, INTH# as PCI  */
> +	pci_write_config8(dev, 0x5B, 0xb);
> +	/* set  Read Pass Write Control  Enable (force A2 from APIC FSB to low) */
> +	pci_write_config8(dev, 0x48, 0x8c);
> +	/* Set 0x58 to 0x43 APIC and RTC */
> +	pci_write_config8(dev, 0x58, 0x43);
> +	/* Set bit 3 of 0x4f (use INIT# as cpu reset) */
> +	enables = pci_read_config8(dev, 0x4f);
> +	enables |= 0x08;
> +	pci_write_config8(dev, 0x4f, enables);
> +
> +	/* enable serial irq, 6PCI clocks */
> +	pci_write_config8(dev, 0x52, 0x9);
> +	/* enable HPET at: */
> +	pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
> +	/* Power management setup */
> +	setup_pm(dev);
> +	/* Start the rtc */
> +	rtc_init(0);
> +}
> +
> +void vt8237r_read_resources(device_t dev)
> +{
> +	struct resource *res;
> +
> +	pci_dev_read_resources(dev);
> +	/* fixed APIC resource */
> +	res = new_resource(dev, 0x44);
> +	res->base = VT8237R_APIC_BASE;
> +	res->size = 256;
> +	res->limit = res->base + res->size - 1;
> +	res->align = 8;
> +	res->gran = 8;
> +	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
> +	    IORESOURCE_STORED | IORESOURCE_ASSIGNED;
> +}
> +
> +/**
> + * The VT8237R is not a PCI bridge and has no resources of its own (other
> + * than standard PC I/O addresses), however it does control the ISA bus
> + * and so we need to manually call enable childrens resources on that bus.
> + */
> +void vt8237r_enable_resources(device_t dev)
> +{
> +	pci_dev_enable_resources(dev);
> +	enable_childrens_resources(dev);
> +}
> +
> +static void init_keyboard(struct device *dev)
> +{
> +	u8 regval;
> +	regval = pci_read_config8(dev, 0x51);
> +	if (regval & 0x1)
> +		init_pc_keyboard(0x60, 0x64, 0);
> +}
> +
> +static void southbridge_init(struct device *dev)
> +{
> +	vt8237r_init(dev);
> +	pci_routing_fixup(dev);
> +	setup_ioapic(VT8237R_APIC_BASE);
> +	setup_i8259();
> +	init_keyboard(dev);
> +}
> +
> +static struct device_operations vt8237r_lpc_ops = {
> +	.read_resources = vt8237r_read_resources,
> +	.set_resources = pci_dev_set_resources,
> +	.enable_resources = vt8237r_enable_resources,
> +	.init = &southbridge_init,
> +	.scan_bus = scan_static_bus,
> +};
> +
> +static struct pci_driver lpc_driver __pci_driver = {
> +	.ops = &vt8237r_lpc_ops,
> +	.vendor = PCI_VENDOR_ID_VIA,
> +	.device = PCI_DEVICE_ID_VIA_VT8237R_ISA,
>   

PCI_DEVICE_ID_VIA_VT8237R_LPC please. Datasheet refers to it as lpc, as
does the file name.

> +};
> Index: src/include/device/pci_ids.h
> ===================================================================
> --- src/include/device/pci_ids.h	(revision 2901)
> +++ src/include/device/pci_ids.h	(working copy)
> @@ -1138,6 +1138,21 @@
>  #define PCI_DEVICE_ID_VIA_8505_1	0x8605
>  #define PCI_DEVICE_ID_VIA_8633_1	0xB091
>  #define PCI_DEVICE_ID_VIA_8367_1	0xB099
> +#define PCI_DEVICE_ID_VIA_K8T890CE_0	0x0238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_1	0x1238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_2	0x2238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_3	0x3238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_4	0x4238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_5	0x5238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_7	0x7238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_PEG	0xa238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_PEX0	0xc238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_PEX1	0xd238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_PEX2	0xe238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_PEX3	0xf238
> +#define PCI_DEVICE_ID_VIA_K8T890CE_BR	0xb188
> +#define PCI_DEVICE_ID_VIA_VT6420_SATA	0x3149
> +#define PCI_DEVICE_ID_VIA_VT8237R_ISA	0x3227

Same here. With that one nitpick:

Acked-by: Corey Osgood <corey.osgood at gmail.com>

-Corey




More information about the coreboot mailing list