Support for vt8237r/s stage2 for v3, untested due to other issues. Also nuke a PCI ID that isn't actually part of the vt8237 at all. WIP. Signed-off-by: Corey Osgood Index: southbridge/via/vt8237/lpc.c =================================================================== --- southbridge/via/vt8237/lpc.c (revision 0) +++ southbridge/via/vt8237/lpc.c (revision 0) @@ -0,0 +1,470 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * Copyright (C) 2007, 2008 Rudolf Marek + * + * 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 + */ + +/* Inspiration from other VIA SB code. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vt8237.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) + +static 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(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + u32 value_low, value_high, val; + volatile u32 *l; + int i; + + /* All delivered to CPU0. */ + ioapic_table[0].value_high = (lapicid()) << (56 - 32); + l = (void *)sb->apic_base; + + /* Set APIC to FSB message bus. */ + l[0] = 0x3; + val = l[4]; + l[4] = (val & 0xFFFFFE) | 1; + + /* Set APIC ADDR - this will be VT8237_APIC_ID. */ + l[0] = 0; + val = l[4]; + l[4] = (val & 0xF0FFFF) | (sb->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(BIOS_WARNING, "IO APIC not responding.\n"); + return; + } + } +} + +/** Set up PCI IRQ routing, route everything through APIC. */ +static void pci_routing_fixup(struct device *dev) +{ + /* PCI PNP Interrupt Routing INTE/F - disable */ + pci_write_config8(dev, 0x44, 0x00); + + /* PCI PNP Interrupt Routing INTG/H - disable */ + pci_write_config8(dev, 0x45, 0x00); + + /* Route INTE-INTH through registers above, no map to INTA-INTD. */ + pci_write_config8(dev, 0x46, 0x10); + + /* PCI Interrupt Polarity */ + pci_write_config8(dev, 0x54, 0x00); + + /* PCI INTA# Routing */ + pci_write_config8(dev, 0x55, 0x00); + + /* PCI INTB#/C# Routing */ + pci_write_config8(dev, 0x56, 0x00); + + /* PCI INTD# Routing */ + pci_write_config8(dev, 0x57, 0x00); +} + +/** + * Set up the power management capabilities directly into ACPI mode. + * This avoids having to handle any System Management Interrupts (SMIs). + */ +static void setup_pm(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + /* Debounce LID and PWRBTN# Inputs for 16ms. */ + pci_write_config8(dev, 0x80, 0x20); + + /* Set ACPI base address to I/O sb->acpi_io_base. */ + pci_write_config16(dev, 0x88, sb->acpi_io_base | 0x1); + + /* Set ACPI to 9, must set IRQ 9 override to level! Set PSON gating. */ + pci_write_config8(dev, 0x82, 0x40 | sb->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 = Internal 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 + * 4 = PWRGOOD reset on VT8237A/S + * 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 ACPI accessm RTC signal gated with PSON. */ + pci_write_config8(dev, 0x81, 0x84); + + /* Clear status events. */ + outw(0xffff, sb->acpi_io_base + 0x00); + outw(0xffff, sb->acpi_io_base + 0x20); + outw(0xffff, sb->acpi_io_base + 0x28); + outl(0xffffffff, sb->acpi_io_base + 0x30); + + /* Disable SCI on GPIO. */ + outw(0x0, sb->acpi_io_base + 0x22); + + /* Disable SMI on GPIO. */ + outw(0x0, sb->acpi_io_base + 0x24); + + /* Disable all global enable SMIs. */ + outw(0x0, sb->acpi_io_base + 0x2a); + + /* All SMI off, both IDE buses ON, PSON rising edge. */ + outw(0x0, sb->acpi_io_base + 0x2c); + + /* Primary activity SMI disable. */ + outl(0x0, sb->acpi_io_base + 0x34); + + /* GP timer reload on none. */ + outl(0x0, sb->acpi_io_base + 0x38); + + /* Disable extended IO traps. */ + outb(0x0, sb->acpi_io_base + 0x42); + + /* SCI is generated for RTC/pwrBtn/slpBtn. */ + outw(0x001, sb->acpi_io_base + 0x04); +} + +static void vt8237_common_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); + + /* + * ROM decode + * bit range + * 7 000E0000h-000EFFFFh + * 6 FFF00000h-FFF7FFFFh + * 5 FFE80000h-FFEFFFFFh + * 4 FFE00000h-FFE7FFFFh + * 3 FFD80000h-FFDFFFFFh + * 2 FFD00000h-FFD7FFFFh + * 1 FFC80000h-FFCFFFFFh + * 0 FFC00000h-FFC7FFFFh + * So 0x7f here sets ROM decode to FFC00000-FFFFFFFF or 4Mbyte. + */ + pci_write_config8(dev, 0x41, 0x7f); + + /* + * Set bit 6 of 0x40 (I/O 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); + + /* I/O recovery time, default IDE routing */ + pci_write_config8(dev, 0x4c, 0x44); + + /* ROM memory cycles go to LPC. */ + pci_write_config8(dev, 0x59, 0x80); + + /* + * Bit | Meaning + * ------------- + * 3 | Bypass APIC De-Assert Message (1=Enable) + * 1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI" + * | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch + * 0 | Dynamic Clock Gating Main Switch (1=Enable) + */ + pci_write_config8(dev, 0x5b, 0xb); + + /* Set 0x58 to 0x43 APIC and RTC. */ + pci_write_config8(dev, 0x58, 0x43); + + /* Enable serial IRQ, 6PCI clocks. */ + pci_write_config8(dev, 0x52, 0x9); + + /* Power management setup */ + setup_pm(dev); + + /* Enable the RTC. */ + enables = pci_read_config8(dev, 0x51); + enables |= (1 << 3); + pci_write_config8(dev, 0x51, enables); + + /* Start the RTC. */ + rtc_init(0); +} + +static void vt8237_read_resources(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + struct resource *res; + + pci_dev_read_resources(dev); + /* Fixed APIC resource */ + res = new_resource(dev, 0x44); + /* Possible breakage */ + res->base = sb->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 VT8237 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. + */ +static void vt8237_enable_resources(struct device *dev) +{ + pci_dev_enable_resources(dev); + enable_childrens_resources(dev); +} + +static void init_keyboard(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + u8 regval; + + if (sb->enable_keyboard) + { + /* Enable PS/2 mouse, Keyboard, and KBC Config */ + regval = pci_read_config8(dev, 0x51); + regval |= (1 << 2)|(1 << 1)|1; + pci_write_config8(dev, 0x51, regval); + + init_pc_keyboard(0x60, 0x64, 0); + } +} + +static void southbridge_init_common(struct device *dev) +{ + vt8237_common_init(dev); + pci_routing_fixup(dev); + setup_ioapic(dev); + setup_i8259(); + init_keyboard(dev); +} + +static void vt8237r_init(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + u8 enables; + + /* + * 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); + + /* Set bit 3 of 0x4f (use INIT# as CPU reset). */ + enables = pci_read_config8(dev, 0x4f); + enables |= 0x08; + pci_write_config8(dev, 0x4f, enables); + + /* + * Set Read Pass Write Control Enable + * (force A2 from APIC FSB to low). + */ + pci_write_config8(dev, 0x48, 0x8c); + + southbridge_init_common(dev); + + /* FIXME: Intel needs more bit set for C2/C3. */ + + /* + * Allow SLP# signal to assert LDTSTOP_L. + * Will work for C3 and for FID/VID change. + */ + outb(0x1, sb->acpi_io_base + 0x11); +} + +static void vt8237s_init(struct device *dev) +{ + struct southbridge_via_vt8237_lpc_config *sb = + (struct southbridge_via_vt8237_lpc_config *)dev->device_configuration; + + u32 tmp; + + /* Put SPI base VT8237S_SPI_MEM_BASE. */ + tmp = pci_read_config32(dev, 0xbc); + pci_write_config32(dev, 0xbc, (sb->spi_mem_base >> 8) | (tmp & 0xFF000000)); + + /* Enable SATA LED, VR timer = 100us, VR timer should be fixed. */ + pci_write_config8(dev, 0xe5, 0x69); + + /* + * REQ5 as PCI request input - should be together with INTE-INTH. + * Fast VR timer disable - need for LDTSTOP_L signal. + */ + pci_write_config8(dev, 0xe4, 0xa5); + + /* Reduce further the STPCLK/LDTSTP signal to 5us. */ + pci_write_config8(dev, 0xec, 0x4); + + /* Host Bus Power Management Control, maybe not needed */ + pci_write_config8(dev, 0x8c, 0x5); + + /* Enable HPET at hpet_addr (from dts), does not work correctly on R. */ + pci_write_config32(dev, 0x68, (sb->hpet_addr | 0x80)); + + southbridge_init_common(dev); + + /* FIXME: Intel needs more bit set for C2/C3. */ + + /* + * Allow SLP# signal to assert LDTSTOP_L. + * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2. + */ + + outb(0xff, sb->acpi_io_base + 0x50); +} + +struct device_operations vt8237r_lpc = { + .id = {.type = DEVICE_ID_PCI, + {.pci = {.vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237R_LPC}}}, + .constructor = default_device_constructor, + .phase2_fixup = vt8237_enable, + .phase3_scan = scan_static_bus, + .phase4_read_resources = vt8237_read_resources, + .phase4_set_resources = pci_dev_set_resources, + .phase5_enable_resources = vt8237_enable_resources, + .phase6_init = vt8237r_init, +}; + +struct device_operations vt8237s_lpc = { + .id = {.type = DEVICE_ID_PCI, + {.pci = {.vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237S_LPC}}}, + .constructor = default_device_constructor, + .phase2_fixup = vt8237_enable, + .phase3_scan = scan_static_bus, + .phase4_read_resources = vt8237_read_resources, + .phase4_set_resources = pci_dev_set_resources, + .phase5_enable_resources = vt8237_enable_resources, + .phase6_init = vt8237s_init, +}; Index: southbridge/via/vt8237/sata.dts =================================================================== --- southbridge/via/vt8237/sata.dts (revision 0) +++ southbridge/via/vt8237/sata.dts (revision 0) @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +{ + device_operations = "vt8237r_sata"; + /* configuration variables go here */ +}; + +{ + device_operations = "vt8237s_sata"; +}; Index: southbridge/via/vt8237/ide.c =================================================================== --- southbridge/via/vt8237/ide.c (revision 0) +++ southbridge/via/vt8237/ide.c (revision 0) @@ -0,0 +1,105 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * 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 + */ + +/* Based on other VIA SB code. */ +#include +#include +#include +#include +#include +#include "vt8237.h" + +/** + * No native mode. Interrupts from unconnected HDDs might occur if + * IRQ14/15 is used for PCI. Therefore no native mode support. + */ +static void ide_init(struct device *dev) +{ + struct southbridge_via_vt8237_ide_config *sb = + (struct southbridge_via_vt8237_ide_config *)dev->device_configuration; + + u8 enables; + u32 cablesel; + + printk(BIOS_INFO, "%s IDE interface %s\n", "Primary", + sb->ide0_enable ? "enabled" : "disabled"); + printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary", + sb->ide1_enable ? "enabled" : "disabled"); + enables = pci_read_config8(dev, IDE_CS) & ~0x3; + enables |= (sb->ide0_enable << 1) | sb->ide1_enable; + pci_write_config8(dev, IDE_CS, enables); + enables = pci_read_config8(dev, IDE_CS); + printk(BIOS_DEBUG, "Enables in reg 0x40 read back as 0x%x\n", enables); + + /* Enable only compatibility mode. */ + enables = pci_read_config8(dev, IDE_CONF_II); + enables &= ~0xc0; + pci_write_config8(dev, IDE_CONF_II, enables); + enables = pci_read_config8(dev, IDE_CONF_II); + printk(BIOS_DEBUG, "Enables in reg 0x42 read back as 0x%x\n", enables); + + /* Enable prefetch buffers. */ + enables = pci_read_config8(dev, IDE_CONF_I); + enables |= 0xf0; + pci_write_config8(dev, IDE_CONF_I, enables); + + /* Flush FIFOs at half. */ + enables = pci_read_config8(dev, IDE_CONF_FIFO); + enables &= 0xf0; + enables |= (1 << 2) | (1 << 0); + pci_write_config8(dev, IDE_CONF_FIFO, enables); + + /* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */ + enables = pci_read_config8(dev, IDE_MISC_I); + enables &= 0xe2; + enables |= (1 << 4) | (1 << 3); + pci_write_config8(dev, IDE_MISC_I, enables); + + /* Use memory read multiple, Memory-Write-and-Invalidate. */ + enables = pci_read_config8(dev, IDE_MISC_II); + enables |= (1 << 2) | (1 << 3); + pci_write_config8(dev, IDE_MISC_II, enables); + + /* Force interrupts to use compat mode. */ + pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0); + pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff); + + /* Cable guy... */ + cablesel = pci_read_config32(dev, IDE_UDMA); + cablesel &= ~((1 << 28) | (1 << 20) | (1 << 12) | (1 << 4)); + cablesel |= (sb->ide0_80pin_cable << 28) | + (sb->ide0_80pin_cable << 20) | + (sb->ide1_80pin_cable << 12) | + (sb->ide1_80pin_cable << 4); + pci_write_config32(dev, IDE_UDMA, cablesel); +} + +struct device_operations vt8237_ide = { + .id = {.type = DEVICE_ID_PCI, + {.pci = {.vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237_PATA}}}, + .constructor = default_device_constructor, + .phase2_fixup = vt8237_enable, + .phase3_scan = 0, + //.phase4_enable_disable = vt8237_enable, + //.phase4_read_resources = pci_dev_read_resources, + //.phase4_set_resources = pci_dev_set_resources, + //.phase5_enable_resources = pci_dev_enable_resources, + .phase6_init = ide_init, +}; Index: southbridge/via/vt8237/vt8237.h =================================================================== --- southbridge/via/vt8237/vt8237.h (revision 961) +++ southbridge/via/vt8237/vt8237.h (working copy) @@ -22,16 +22,6 @@ #include -/* Static resources for the VT8237R southbridge */ - -#define VT8237R_APIC_ID 0x2 -#define VT8237R_ACPI_IO_BASE 0x500 -/* 0x0 disabled, 0x2 reserved, 0xf = IRQ15 */ -#define VT8237R_ACPI_IRQ 0x9 -#define VT8237S_SPI_MEM_BASE 0xfed02000ULL -#define VT8237R_HPET_ADDR 0xfed00000ULL -#define VT8237R_APIC_BASE 0xfec00000ULL - /* IDE */ #define IDE_CS 0x40 #define IDE_CONF_I 0x41 @@ -41,10 +31,12 @@ #define IDE_MISC_II 0x45 #define IDE_UDMA 0x50 +#define SATA_MISC_CTRL 0x45 + /* SMBus */ -#define VT8237R_POWER_WELL 0x94 -#define VT8237R_SMBUS_IO_BASE_REG 0xd0 -#define VT8237R_SMBUS_HOST_CONF 0xd2 +#define VT8237_POWER_WELL 0x94 +#define VT8237_SMBUS_IO_BASE_REG 0xd0 +#define VT8237_SMBUS_HOST_CONF 0xd2 #define SMBHSTSTAT 0x0 #define SMBSLVSTAT 0x1 @@ -86,5 +78,6 @@ void enable_smbus(u16); u8 smbus_read_byte(u16, u8, u16); +void vt8237_enable(struct device *); #endif Index: southbridge/via/vt8237/stage1.c =================================================================== --- southbridge/via/vt8237/stage1.c (revision 961) +++ southbridge/via/vt8237/stage1.c (working copy) @@ -170,14 +170,14 @@ /* 7 = SMBus Clock from RTC 32.768KHz * 5 = Internal PLL reset from susp */ - pci_conf1_write_config8(dev, VT8237R_POWER_WELL, 0xa0); + pci_conf1_write_config8(dev, VT8237_POWER_WELL, 0xa0); /* Enable SMBus. */ - pci_conf1_write_config16(dev, VT8237R_SMBUS_IO_BASE_REG, + pci_conf1_write_config16(dev, VT8237_SMBUS_IO_BASE_REG, smbus_io_base | 0x1); /* SMBus Host Configuration, enable. */ - pci_conf1_write_config8(dev, VT8237R_SMBUS_HOST_CONF, 0x01); + pci_conf1_write_config8(dev, VT8237_SMBUS_HOST_CONF, 0x01); /* Make it work for I/O. */ pci_conf1_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO); Index: southbridge/via/vt8237/lpc.dts =================================================================== --- southbridge/via/vt8237/lpc.dts (revision 0) +++ southbridge/via/vt8237/lpc.dts (revision 0) @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +{ + device_operations = "vt8237r_lpc"; + enable_keyboard = "1"; + acpi_io_base = "0x500"; + acpi_irq = "0x9"; + apic_id = "0x2"; + apic_base = "0xfec00000ULL"; + + /* These are unused by vt8237r, but necessary to use + * the same driver for vt8237s */ + spi_mem_base = "0"; + hpet_addr = "0"; +}; + +{ + device_operations = "vt8237s_lpc"; + enable_keyboard = "1"; + acpi_io_base = "0x500"; + acpi_irq = "0x9"; + apic_id = "0x2"; + apic_base = "0xfec00000ULL"; + spi_mem_base = "0xfed02000ULL"; + hpet_addr = "0xfed00000ULL"; +}; Index: southbridge/via/vt8237/sata.c =================================================================== --- southbridge/via/vt8237/sata.c (revision 0) +++ southbridge/via/vt8237/sata.c (revision 0) @@ -0,0 +1,123 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007, 2008 Rudolf Marek + * + * 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 +#include +#include +#include "vt8237.h" + +/* TODO: use phase2_fixup to disable SATA */ +static void sata_i_init(struct device *dev) +{ + u8 reg; + + printk(BIOS_DEBUG, "Configuring VIA SATA controller\n"); + + /* Class IDE Disk */ + reg = pci_read_config8(dev, SATA_MISC_CTRL); + reg &= 0x7f; /* Sub Class Write Protect off */ + pci_write_config8(dev, SATA_MISC_CTRL, reg); + + /* Change the device class to SATA from RAID. */ + pci_write_config8(dev, PCI_CLASS_DEVICE, 0x1); + reg |= 0x80; /* Sub Class Write Protect on */ + pci_write_config8(dev, SATA_MISC_CTRL, reg); +} + +/* VT8237R is SATA, VT8237S is SATAII */ +static void sata_ii_init(struct device *dev) +{ + u8 reg; + + sata_i_init(dev); + + /* + * Analog black magic, you may or may not need to adjust 0x60-0x6f, + * depends on PCB. + */ + + /* + * Analog PHY - gen1 + * CDR bandwidth [6:5] = 3 + * Squelch Window Select [4:3] = 1 + * CDR Charge Pump [2:0] = 1 + */ + + /* TODO: Move to DTS */ + + pci_write_config8(dev, 0x64, 0x49); + + /* Adjust driver current source value to 9. */ + reg = pci_read_config8(dev, 0x65); + reg &= 0xf0; + reg |= 0x9; + pci_write_config8(dev, 0x65, reg); + + /* Set all manual termination 50ohm bits [2:0] and enable [4]. */ + reg = pci_read_config8(dev, 0x6a); + reg |= 0xf; + pci_write_config8(dev, 0x6a, reg); + + /* + * Analog PHY - gen2 + * CDR bandwidth [5:4] = 2 + * Pre / De-emphasis Level [7:6] controls bits [3:2], rest in 0x6e + * CDR Charge Pump [2:0] = 1 + */ + + reg = pci_read_config8(dev, 0x6f); + reg &= 0x08; + reg |= 0x61; + pci_write_config8(dev, 0x6f, reg); + + /* Check if staggered spinup is supported. */ + reg = pci_read_config8(dev, 0x83); + if ((reg & 0x8) == 0) { + /* Start OOB sequence on both drives. */ + reg |= 0x30; + pci_write_config8(dev, 0x83, reg); + } +} + +struct device_operations vt8237r_sata = { + .id = {.type = DEVICE_ID_PCI, + {.pci = {.vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237R_SATA}}}, + .constructor = default_device_constructor, + .phase3_scan = 0, + //.phase4_enable_disable = vt8237_enable, + //.phase4_read_resources = pci_dev_read_resources, + //.phase4_set_resources = pci_dev_set_resources, + //.phase5_enable_resources = pci_dev_enable_resources, + .phase6_init = sata_i_init, +}; + +struct device_operations vt8237s_sata = { + .id = {.type = DEVICE_ID_PCI, + {.pci = {.vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237S_SATA}}}, + .constructor = default_device_constructor, + .phase2_fixup = 0, + .phase3_scan = 0, + //.phase4_enable_disable = vt8237_enable, + //.phase4_read_resources = pci_dev_read_resources, + //.phase4_set_resources = pci_dev_set_resources, + //.phase5_enable_resources = pci_dev_enable_resources, + .phase6_init = sata_ii_init, +}; Index: southbridge/via/vt8237/ide.dts =================================================================== --- southbridge/via/vt8237/ide.dts (revision 0) +++ southbridge/via/vt8237/ide.dts (revision 0) @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +{ + device_operations = "vt8237_ide"; + ide0_enable = "1"; + ide1_enable = "1"; + ide0_80pin_cable = "0"; + ide1_80pin_cable = "0"; +}; Index: southbridge/via/vt8237/Makefile =================================================================== --- southbridge/via/vt8237/Makefile (revision 961) +++ southbridge/via/vt8237/Makefile (working copy) @@ -20,6 +20,9 @@ ifeq ($(CONFIG_SOUTHBRIDGE_VIA_VT8237),y) -STAGE2_CHIPSET_SRC += +STAGE2_CHIPSET_SRC += $(src)/southbridge/via/vt8237/vt8237.c \ + $(src)/southbridge/via/vt8237/lpc.c \ + $(src)/southbridge/via/vt8237/ide.c \ + $(src)/southbridge/via/vt8237/sata.c endif Index: southbridge/via/vt8237/vt8237.c =================================================================== --- southbridge/via/vt8237/vt8237.c (revision 0) +++ southbridge/via/vt8237/vt8237.c (revision 0) @@ -0,0 +1,84 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * + * 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 +#include +#include +#include +#include +#include +#include "vt8237.h" + +/* + * Datasheet: http://www.via.com.tw/en/downloads/datasheets/chipsets/ + * VT8237R_SouthBridge_Revision2.06_Lead-Free.zip + */ + +void vt8237_enable(struct device *dev) +{ + struct device *lpc_dev; + u16 sb_fn_ctrl; + + const u8 func = dev->path.pci.devfn & 0x7; + const u8 device = dev->path.pci.devfn >> 3; + const int d16_index[6] = {12, 13, 10, 8, 9, 7}; + + + printk(BIOS_DEBUG, "Enabling/Disabling device 0x%x function 0x%x.\n", + device, func); + + if(dev->id.pci.vendor != PCI_VENDOR_ID_VIA) + return; + + lpc_dev = dev_find_slot(0, PCI_BDF(0, 17, 0)); + sb_fn_ctrl = pci_read_config8(lpc_dev, 0x50) << 8; + sb_fn_ctrl |= pci_read_config8(lpc_dev, 0x51); + + if (device == 16) + { + /* If any port is enabled, the first port needs to be enabled */ + if (dev->enabled) + { + sb_fn_ctrl &= ~(1 << d16_index[0]); + sb_fn_ctrl &= ~(1 << d16_index[func]); + } + else + { + sb_fn_ctrl |= (1 << d16_index[func]); + } + } + else if (device == 17) + { + if (func == 5) + { + sb_fn_ctrl &= ~(dev->enabled << 14); + sb_fn_ctrl |= (!dev->enabled << 14); + } + else if (func == 6) + { + sb_fn_ctrl &= ~(dev->enabled << 15); + sb_fn_ctrl |= (!dev->enabled << 15); + } + } + + pci_write_config8(dev, 0x50, (sb_fn_ctrl >> 8) & 0xff); + pci_write_config8(dev, 0x51, sb_fn_ctrl & 0xff); + + /* TODO: If SATA is disabled, move IDE to fn0 to conform PCI specs. */ +} Index: include/device/pci_ids.h =================================================================== --- include/device/pci_ids.h (revision 961) +++ include/device/pci_ids.h (working copy) @@ -272,7 +280,5 @@ #define PCI_DEVICE_ID_VIA_VT8237R_SATA 0x3149 #define PCI_DEVICE_ID_VIA_VT8237S_SATA 0x5372 #define PCI_DEVICE_ID_VIA_VT8237_UHCI 0x3038 -#define PCI_DEVICE_ID_VIA_VT8237_VLINK 0x287e - #endif /* DEVICE_PCI_IDS_H */