Following patch adds K8M890 support. It initializes the AGP and graphics UMA.

The V-link setup and HT bridge is redone, because VT8237A has it in another
device. So far following combination of chipsets should now work:

K8T890CE + VT8237R
K8M890(CE) + VT8237R

VIA PC1 brige moved to NB code (vt8237r_bridge.c -> k8t890_bridge.c) and
notes about K8M890 support were added.

Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3183 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Rudolf Marek 2008-03-20 21:19:50 +00:00
parent 14a3feb068
commit 316e07fb04
12 changed files with 338 additions and 88 deletions

View File

@ -1145,6 +1145,13 @@
#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_K8M890CE_0 0x0336
#define PCI_DEVICE_ID_VIA_K8M890CE_1 0x1336
#define PCI_DEVICE_ID_VIA_K8M890CE_2 0x2336
#define PCI_DEVICE_ID_VIA_K8M890CE_3 0x3336
#define PCI_DEVICE_ID_VIA_K8M890CE_4 0x4336
#define PCI_DEVICE_ID_VIA_K8M890CE_5 0x5336
#define PCI_DEVICE_ID_VIA_K8M890CE_7 0x7336
#define PCI_DEVICE_ID_VIA_K8T890CE_PEG 0xa238
#define PCI_DEVICE_ID_VIA_K8T890CE_PEX0 0xc238
#define PCI_DEVICE_ID_VIA_K8T890CE_PEX1 0xd238

View File

@ -19,6 +19,7 @@
driver k8t890_ctrl.o
driver k8t890_dram.o
driver k8t890_bridge.o
driver k8t890_host.o
driver k8t890_host_ctrl.o
driver k8t890_pcie.o

View File

@ -32,4 +32,7 @@
#define K8T890_MMCONFIG_MBAR 0x61
#define K8T890_MULTIPLE_FN_EN 0x4f
/* the FB size in MB (min is 8MB max is 512MB) */
#define K8M890_FBSIZEMB 64
#endif

View File

@ -27,15 +27,22 @@ static void bridge_enable(struct device *dev)
print_debug("B188 device dump\n");
/* VIA recommends this, sorry no known info. */
writeback(dev, 0x40, 0x91);
writeback(dev, 0x41, 0x40);
writeback(dev, 0x43, 0x44);
writeback(dev, 0x44, 0x31);
writeback(dev, 0x44, 0x31); /* K8M890 should have 0x35 datasheet
* says it is reserved
*/
writeback(dev, 0x45, 0x3a);
writeback(dev, 0x46, 0x88); /* PCI ID lo */
writeback(dev, 0x47, 0xb1); /* PCI ID hi */
writeback(dev, 0x3e, 0x16); /* Bridge control */
/* Bridge control, K8M890 bit 3 should be set to enable VGA on AGP
* (Forward VGA compatible memory and I/O cycles )
*/
writeback(dev, 0x3e, 0x16);
dump_south(dev);
}

View File

@ -23,75 +23,23 @@
#include <device/pci_ids.h>
#include <console/console.h>
/**
* Setup the V-Link for VT8237R, 8X mode.
*
* For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
*
* REG DEF AW VIA-8X VIA-4X
* -----------------------------
* NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
* NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
* NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
* NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
* SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
* SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
* SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
* SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
* V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
* V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
/* We support here K8M890/K8T890 and VT8237R PCI1/Vlink which setup is not in separate
* PCI device 0:11.7, but it is mapped to PCI 0:0.7 (0x70-0x7c for PCI1)
*/
static void ctrl_init_vt8237r(struct device *dev)
{
u8 reg;
/*
* This init code is valid only for the VT8237R! For different
* sounthbridges (e.g. VT8237A, VT8237S, VT8237 (without plus R)
* and VT8251) a different init code is required.
*/
device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
if (!devsb)
return;
pci_write_config8(dev, 0xb5, 0x88);
pci_write_config8(dev, 0xb6, 0x88);
pci_write_config8(dev, 0xb7, 0x61);
reg = pci_read_config8(dev, 0xb4);
reg |= 0x11;
pci_write_config8(dev, 0xb4, reg);
pci_write_config8(dev, 0xb9, 0x98);
pci_write_config8(dev, 0xba, 0x77);
pci_write_config8(dev, 0xbb, 0x11);
reg = pci_read_config8(dev, 0xb8);
reg |= 0x1;
pci_write_config8(dev, 0xb8, reg);
pci_write_config8(dev, 0xb0, 0x06);
pci_write_config8(dev, 0xb1, 0x01);
/* Program V-link 8X 16bit full duplex, parity enabled. */
pci_write_config8(dev, 0x48, 0xa3);
}
static void ctrl_enable(struct device *dev)
static void vt8237r_cfg(struct device *dev, struct device *devsb)
{
u8 regm, regm2, regm3;
device_t devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
device_t devfun3;
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
/* TODO: Fix some ordering issue fo V-link set Rx77[6] and PCI1_Rx4F[0]
should to 1 */
if (!devfun3)
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
/* C2P Read ACK Return Priority */
/* PCI CFG Address bits[27:24] are used as extended register address
bit[11:8] */
pci_write_config8(dev, 0x47, 0x30);
/* Magic init. This is not well documented :/ */
pci_write_config8(dev, 0x70, 0xc2);
/* PCI Control */
@ -137,17 +85,98 @@ static void ctrl_enable(struct device *dev)
pci_write_config8(dev, 0x63, regm3 | (regm & 0x3F));
}
/**
* Setup the V-Link for VT8237R, 8X mode.
*
* For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
*
* REG DEF AW VIA-8X VIA-4X
* -----------------------------
* NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
* NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
* NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
* NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
* SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
* SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
* SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
* SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
* V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
* V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
*/
static void vt8237r_vlink_init(struct device *dev)
{
u8 reg;
/*
* This init code is valid only for the VT8237R! For different
* sounthbridges (e.g. VT8237A, VT8237S, VT8237 (without plus R)
* and VT8251) a different init code is required.
*/
pci_write_config8(dev, 0xb5, 0x88);
pci_write_config8(dev, 0xb6, 0x88);
pci_write_config8(dev, 0xb7, 0x61);
reg = pci_read_config8(dev, 0xb4);
reg |= 0x11;
pci_write_config8(dev, 0xb4, reg);
pci_write_config8(dev, 0xb9, 0x98);
pci_write_config8(dev, 0xba, 0x77);
pci_write_config8(dev, 0xbb, 0x11);
reg = pci_read_config8(dev, 0xb8);
reg |= 0x1;
pci_write_config8(dev, 0xb8, reg);
pci_write_config8(dev, 0xb0, 0x06);
pci_write_config8(dev, 0xb1, 0x01);
/* Program V-link 8X 16bit full duplex, parity enabled. */
pci_write_config8(dev, 0x48, 0xa3);
}
static void ctrl_init(struct device *dev) {
/* TODO: Fix some ordering issue fo V-link set Rx77[6] and PCI1_Rx4F[0]
should to 1 */
/* C2P Read ACK Return Priority */
/* PCI CFG Address bits[27:24] are used as extended register address
bit[11:8] */
pci_write_config8(dev, 0x47, 0x30);
/* VT8237R specific configuration other SB are done in their own directories */
device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
if (devsb) {
vt8237r_vlink_init(dev);
vt8237r_cfg(dev, devsb);
}
}
static const struct device_operations ctrl_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = ctrl_enable,
.init = ctrl_init_vt8237r,
.init = ctrl_init,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &ctrl_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_7,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &ctrl_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_7,
};

View File

@ -23,6 +23,8 @@
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h>
#include <bitops.h>
#include "k8t890.h"
static void dram_enable(struct device *dev)
{
@ -59,10 +61,75 @@ static void dram_enable(struct device *dev)
reg = pci_read_config16(dev, 0x88);
reg &= 0xf800;
/* The Address Next to the Last Valid DRAM Address */
pci_write_config16(dev, 0x88, (msr.lo >> 24) | reg);
}
static const struct device_operations dram_ops = {
static struct resource *resmax;
static void get_memres(void *gp, struct device *dev, struct resource *res)
{
unsigned int *fbsize = (unsigned int *) gp;
uint64_t proposed_base = res->base + res->size - *fbsize;
printk_debug("get_memres: res->base=%llx res->size=%llx %d %d %d\n",
res->base, res->size, (res->size > *fbsize),
(!(proposed_base & (*fbsize - 1))),
(proposed_base < ((uint64_t) 0xffffffff)));
/* if we fit and also align OK, and must be below 4GB */
if ((res->size > *fbsize) && (!(proposed_base & (*fbsize - 1))) &&
(proposed_base < ((uint64_t) 0xffffffff) )) {
resmax = res;
}
}
static void dram_init_fb(struct device *dev)
{
/* Important bits:
* Enable the internal GFX bit 7 of reg 0xa1 plus in same reg:
* bits 6:4 X fbuffer size will be 2^(X+2) or 100 = 64MB, 101 = 128MB
* bits 3:0 BASE [31:28]
* reg 0xa0 bits 7:1 BASE [27:21] bit0 enable CPU access
*/
u8 tmp;
uint64_t proposed_base;
unsigned int fbsize = (K8M890_FBSIZEMB * 1024 * 1024);
resmax = NULL;
search_global_resources(
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
get_memres, (void *) &fbsize);
/* no space for FB */
if (!resmax) {
printk_err("VIA FB: no space for framebuffer in RAM\n");
return;
}
proposed_base = resmax->base + resmax->size - fbsize;
resmax->size -= fbsize;
printk_debug("VIA FB proposed base: %llx\n", proposed_base);
/* enable UMA but no FB */
pci_write_config8(dev, 0xa1, 0x80);
/* 27:21 goes to 7:1, 0 is enable CPU access */
tmp = (proposed_base >> 20) | 0x1;
pci_write_config8(dev, 0xa0, tmp);
/* 31:28 goes to 3:0 */
tmp = ((proposed_base >> 28) & 0xf);
tmp = ((log2(K8M890_FBSIZEMB) - 2) << 4);
tmp |= 0x80;
pci_write_config8(dev, 0xa1, tmp);
/* TODO K8 needs some UMA fine tuning too maybe call some generic routine here? */
}
static const struct device_operations dram_ops_t = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
@ -70,8 +137,23 @@ static const struct device_operations dram_ops = {
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
.ops = &dram_ops,
static const struct device_operations dram_ops_m = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = dram_enable,
.init = dram_init_fb,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &dram_ops_t,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_3,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &dram_ops_m,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_3,
};

View File

@ -30,6 +30,8 @@ static void error_enable(struct device *dev)
* bit7 - Parity Error/SERR# Report Through NMI
*/
pci_write_config8(dev, 0x58, 0x81);
/* TODO: enable AGP errors reporting on K8M890 */
}
static const struct device_operations error_ops = {
@ -40,8 +42,14 @@ static const struct device_operations error_ops = {
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &error_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_1,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &error_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_1,
};

View File

@ -28,9 +28,32 @@ static void host_enable(struct device *dev)
{
/* Multiple function control */
pci_write_config8(dev, K8T890_MULTIPLE_FN_EN, 0x01);
}
static const struct device_operations host_ops = {
static void host_init(struct device *dev)
{
u8 reg;
/* AGP Capability Header Control */
reg = pci_read_config8(dev, 0x4d);
reg |= 0x20; /* GART access enabled by either D0F0 Rx90[8] or D1F0 Rx90[8] */
pci_write_config8(dev, 0x4d, reg);
/* GD Output Stagger Delay */
reg = pci_read_config8(dev, 0x42);
reg |= 0x10; /* AD[31:16] with 1ns */
pci_write_config8(dev, 0x42, reg);
/* AGP Control */
reg = pci_read_config8(dev, 0xbc);
reg |= 0x20; /* AGP Read Snoop DRAM Post-Write Buffer */
pci_write_config8(dev, 0xbc, reg);
}
static const struct device_operations host_ops_t = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
@ -38,8 +61,23 @@ static const struct device_operations host_ops = {
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
.ops = &host_ops,
static const struct device_operations host_ops_m = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = host_enable,
.init = host_init,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &host_ops_t,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_0,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &host_ops_m,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_0,
};

View File

@ -23,8 +23,10 @@
#include <device/pci_ids.h>
#include <console/console.h>
/* this may be later merged */
/* This fine tunes the HT link settings, which were loaded by ROM strap. */
static void host_ctrl_enable(struct device *dev)
static void host_ctrl_enable_k8t890(struct device *dev)
{
dump_south(dev);
@ -48,6 +50,11 @@ static void host_ctrl_enable(struct device *dev)
/* Arbitration control 2 */
pci_write_config8(dev, 0xa6, 0x80);
/* this will be possibly removed, when I figure out
* if the ROM SIP is good, second reason is that the
* unknown bits are AGP related, which are dummy on K8T890
*/
writeback(dev, 0xa0, 0x13); /* Bit4 is reserved! */
writeback(dev, 0xa1, 0x8e); /* Some bits are reserved. */
writeback(dev, 0xa2, 0x0e); /* I/O NVRAM base 0xe00-0xeff disabled. */
@ -78,16 +85,55 @@ static void host_ctrl_enable(struct device *dev)
dump_south(dev);
}
static const struct device_operations host_ctrl_ops = {
/* This fine tunes the HT link settings, which were loaded by ROM strap. */
static void host_ctrl_enable_k8m890(struct device *dev) {
/*
* Set PCI to HT outstanding requests to 03.
* Bit 4 32 AGP ADS Read Outstanding Request Number
*/
pci_write_config8(dev, 0xa0, 0x13);
/* Disable NVRAM and enable non-posted PCI writes. */
pci_write_config8(dev, 0xa1, 0x8e);
/*
* NVRAM I/O base 0xe00-0xeff, but it is disabled.
*/
pci_write_config8(dev, 0xa2, 0x0e);
/* Arbitration control */
pci_write_config8(dev, 0xa5, 0x3c);
/* Arbitration control 2 */
pci_write_config8(dev, 0xa6, 0x82);
}
static const struct device_operations host_ctrl_ops_t = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = host_ctrl_enable,
.enable = host_ctrl_enable_k8t890,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
.ops = &host_ctrl_ops,
static const struct device_operations host_ctrl_ops_m = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = host_ctrl_enable_k8m890,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &host_ctrl_ops_t,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_2,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &host_ctrl_ops_m,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_2,
};

View File

@ -68,15 +68,15 @@ static void apic_mmconfig_read_resources(device_t dev)
res->flags = IORESOURCE_MEM;
}
static void traf_ctrl_enable(struct device *dev)
static void traf_ctrl_enable_generic(struct device *dev)
{
volatile u32 *apic;
u32 data;
/* Enable D3F1-D3F3, no device2 redirect, enable just one device behind
/* no device2 redirect, enable just one device behind
* bridge device 2 and device 3).
*/
pci_write_config8(dev, 0x60, 0x88);
pci_write_config8(dev, 0x60, 0x08);
/* Will enable MMCONFIG later. */
pci_write_config8(dev, 0x64, 0x23);
@ -104,16 +104,46 @@ static void traf_ctrl_enable(struct device *dev)
apic[4] = (data & 0xF0FFFF) | (K8T890_APIC_ID << 24);
}
static const struct device_operations traf_ctrl_ops = {
static void traf_ctrl_enable_k8m890(struct device *dev)
{
traf_ctrl_enable_generic(dev);
}
static void traf_ctrl_enable_k8t890(struct device *dev)
{
u8 reg;
traf_ctrl_enable_generic(dev);
/* Enable D3F1-D3F3 */
reg = pci_read_config8(dev, 0x60);
pci_write_config8(dev, 0x60, 0x80 | reg);
}
static const struct device_operations traf_ctrl_ops_m = {
.read_resources = apic_mmconfig_read_resources,
.set_resources = mmconfig_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = traf_ctrl_enable,
.enable = traf_ctrl_enable_k8m890,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver __pci_driver = {
.ops = &traf_ctrl_ops,
static const struct device_operations traf_ctrl_ops_t = {
.read_resources = apic_mmconfig_read_resources,
.set_resources = mmconfig_set_resources,
.enable_resources = pci_dev_enable_resources,
.enable = traf_ctrl_enable_k8t890,
.ops_pci = 0,
};
static const struct pci_driver northbridge_driver_t __pci_driver = {
.ops = &traf_ctrl_ops_t,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T890CE_5,
};
static const struct pci_driver northbridge_driver_m __pci_driver = {
.ops = &traf_ctrl_ops_m,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8M890CE_5,
};

View File

@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* This file constructs the ROM strap table for K8T890. */
/* This file constructs the ROM strap table for K8T890 and K8M890 */
.section ".romstrap", "a", @progbits

View File

@ -23,4 +23,3 @@ driver vt8237r.o
driver vt8237r_ide.o
driver vt8237r_lpc.o
driver vt8237r_sata.o
driver vt8237r_bridge.o