diff options
author | Jon Harrison <bothlyn@blueyonder.co.uk> | 2009-08-17 17:09:46 +0000 |
---|---|---|
committer | Myles Watson <mylesgw@gmail.com> | 2009-08-17 17:09:46 +0000 |
commit | 1825be291f49f892fa8c048974239aa0daa4de56 (patch) | |
tree | 0451175aed9b7d9f8d5a1cffc0a69ade799c36aa /src/northbridge | |
parent | b5f4e77bff5247dc155873f668a0ccf35400cd11 (diff) |
Get the Via EPIA-N(L)/CN400 to a reasonable level of maturity::
Tested on Via EPIA-NL8000EG with FILO payload booting FC9 (2.6.25
kernel) from SATA HDD.
ACPI is working for PCI interrupt routing, some memory stuff and
Soft-Off.
USB/SATA Working
VGA Console Working
X Working via Onboard AGP
Removed dsdt.c, fixed some whitespace.
Signed-off-by: Jon Harrison <bothlyn@blueyonder.co.uk>
Acked-by: Myles Watson <mylesgw@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4549 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/via/cn400/Config.lb | 2 | ||||
-rw-r--r-- | src/northbridge/via/cn400/agp.c | 128 | ||||
-rw-r--r-- | src/northbridge/via/cn400/cn400.h | 2 | ||||
-rw-r--r-- | src/northbridge/via/cn400/northbridge.c | 115 | ||||
-rw-r--r-- | src/northbridge/via/cn400/raminit.c | 117 | ||||
-rw-r--r-- | src/northbridge/via/cn400/vga.c | 22 |
6 files changed, 266 insertions, 120 deletions
diff --git a/src/northbridge/via/cn400/Config.lb b/src/northbridge/via/cn400/Config.lb index e79e0e02e1..b0704b9c89 100644 --- a/src/northbridge/via/cn400/Config.lb +++ b/src/northbridge/via/cn400/Config.lb @@ -19,6 +19,7 @@ ## uses CONFIG_HAVE_HIGH_TABLES +uses CONFIG_IOAPIC config chip.h @@ -27,5 +28,6 @@ object vgabios.o driver northbridge.o driver agp.o driver vga.o +driver vlink.o default CONFIG_HAVE_HIGH_TABLES=1 diff --git a/src/northbridge/via/cn400/agp.c b/src/northbridge/via/cn400/agp.c index 509dac7f66..c9cca61759 100644 --- a/src/northbridge/via/cn400/agp.c +++ b/src/northbridge/via/cn400/agp.c @@ -32,21 +32,26 @@ static void agp_init(device_t dev) { u32 reg32; + u8 reg8; + int i, j; /* Some of this may not be necessary (should be handled by the OS). */ printk_debug("Enabling AGP.\n"); /* Allow R/W access to AGP registers. */ - pci_write_config8(dev, 0x4d, 0x15); + pci_write_config8(dev, 0x4d, 0x05); /* Setup PCI latency timer. */ pci_write_config8(dev, 0xd, 0x8); + /* Write Secondary Vendor Ids */ + pci_write_config32(dev, 0x2C, 0xAA071106); + /* * Set to AGP 3.0 Mode, which should theoretically render the rest of * the registers set here pointless. */ - pci_write_config8(dev, 0x84, 0xb); + pci_write_config8(dev, 0x84, 0x1b); /* AGP Request Queue Size */ pci_write_config8(dev, 0x4a, 0x1f); @@ -67,41 +72,60 @@ static void agp_init(device_t dev) /* Enable AGP Backdoor */ pci_write_config8(dev, 0xb5, 0x03); - /* Set aperture to 32 MB. */ + /* Set aperture to 128 MB. */ /* TODO: Use config option, explain how it works. */ - pci_write_config32(dev, 0x94, 0x00010f38); + pci_write_config32(dev, 0x94, 0x00010f20); /* Set GART Table Base Address (31:12). */ - pci_write_config32(dev, 0x98, (0x1558 << 12)); + pci_write_config32(dev, 0x98, (0x37b20 << 12)); /* Set AGP Aperture Base. */ - pci_write_config32(dev, 0x10, 0xf8000008); + pci_write_config32(dev, 0x10, 0xe8000008); + + /* NMI/AGPBUSY# Function Select */ + pci_write_config8(dev, 0xbe, 0x80); + + /* AGP Misc Control 1 */ + pci_write_config8(dev, 0xc2, 0x40); - /* Enable CPU/PMSTR GART Access. */ + /* Enable CPU/PMSTR GART Access and DBI function. */ reg32 = pci_read_config8(dev, 0xbf); - reg32 |= 0x80; + reg32 |= 0x8c; pci_write_config8(dev, 0xbf, reg32); /* Enable AGP Aperture. */ - reg32 = pci_read_config32(dev, 0x94); - reg32 |= (3 << 7); - pci_write_config32(dev, 0x90, reg32); + pci_write_config32(dev, 0x90, 0x0180); /* AGP Control */ - pci_write_config8(dev, 0xbc, 0x21); + pci_write_config8(dev, 0xbc, 0x25); pci_write_config8(dev, 0xbd, 0xd2); /* * AGP Pad, driving strength, and delay control. All this should be * constant, seeing as the VGA controller is onboard. */ - pci_write_config8(dev, 0x40, 0xc7); - pci_write_config8(dev, 0x41, 0xdb); - pci_write_config8(dev, 0x42, 0x10); - pci_write_config8(dev, 0x43, 0xdb); - pci_write_config8(dev, 0x44, 0x24); + pci_write_config8(dev, 0x40, 0xda); + pci_write_config8(dev, 0x41, 0xca); + pci_write_config8(dev, 0x42, 0x01); + pci_write_config8(dev, 0x43, 0xca); + pci_write_config8(dev, 0x44, 0x04); /* AGPC CKG Control */ - pci_write_config8(dev, 0xc0, 0x02); + pci_write_config8(dev, 0xc0, 0x04); pci_write_config8(dev, 0xc1, 0x02); + +#ifdef DEBUG_CN400 + printk_spew("%s PCI Header Regs::\n", dev_path(dev)); + + for (i = 0 ; i < 16; i++) + { + printk_spew("%02X: ", i*16); + for (j = 0; j < 16; j++) + { + reg8 = pci_read_config8(dev, j+(i*16)); + printk_spew("%02X ", reg8); + } + printk_spew("\n"); + } +#endif } static const struct device_operations agp_operations = { @@ -118,47 +142,89 @@ static const struct pci_driver agp_driver __pci_driver = { .device = PCI_DEVICE_ID_VIA_CN400_AGP, }; +static void agp_bridge_read_resources (device_t dev) +{ + struct resource *res; + + res = new_resource(dev, 1); + res->base = 0xF0000000ULL; + res->size = 0x06000000ULL; + res->limit = 0xffffffffULL; + res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_ASSIGNED; + + res = new_resource(dev, 2); + res->base = 0xB000UL; + res->size = 4096; + res->limit = 0xffffUL; + res->flags = IORESOURCE_IO | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_ASSIGNED; + +} /* * This is the AGP 3.0 "bridge" @Bus 0 Device 1 Func 0. When using AGP 3.0, the * config in this device takes presidence. We configure both just to be safe. */ static void agp_bridge_init(device_t dev) { - printk_debug("Setting up AGP bridge device\n"); + u8 reg8; + int i, j; - pci_write_config16(dev, 0x4, 0x0007); + printk_debug("Entering %s\n", __func__); + + pci_write_config16(dev, 0x4, 0x0107); /* Secondary Bus Number */ pci_write_config8(dev, 0x19, 0x01); /* Subordinate Bus Number */ pci_write_config8(dev, 0x1a, 0x01); + /* I/O Base */ - pci_write_config8(dev, 0x1c, 0xd0); + pci_write_config8(dev, 0x1c, 0xf0); + /* I/O Limit */ - pci_write_config8(dev, 0x1d, 0xd0); + pci_write_config8(dev, 0x1d, 0x00); /* Memory Base */ - pci_write_config16(dev, 0x20, 0xfb00); + pci_write_config16(dev, 0x20, 0xf400); + /* Memory Limit */ - pci_write_config16(dev, 0x22, 0xfcf0); + pci_write_config16(dev, 0x22, 0xf5f0); + /* Prefetchable Memory Base */ - pci_write_config16(dev, 0x24, 0xf400); + pci_write_config16(dev, 0x24, 0xf000); + /* Prefetchable Memory Limit */ - pci_write_config16(dev, 0x26, 0xf7f0); + pci_write_config16(dev, 0x26, 0xf3f0); + /* Enable VGA Compatible Memory/IO Range */ - pci_write_config8(dev, 0x3e, 0x08); + pci_write_config8(dev, 0x3e, 0x0e); - /* Second PCI Bus Control (see datasheet) */ + /* AGP Bus Control */ pci_write_config8(dev, 0x40, 0x83); - pci_write_config8(dev, 0x41, 0x43); - pci_write_config8(dev, 0x42, 0xe2); + pci_write_config8(dev, 0x41, 0xC7); + pci_write_config8(dev, 0x42, 0x02); pci_write_config8(dev, 0x43, 0x44); pci_write_config8(dev, 0x44, 0x34); pci_write_config8(dev, 0x45, 0x72); + + printk_spew("%s PCI Header Regs::\n", dev_path(dev)); + + for (i = 0 ; i < 16; i++) + { + printk_spew("%02X: ", i*16); + for (j = 0; j < 16; j++) + { + reg8 = pci_read_config8(dev, j+(i*16)); + printk_spew("%02X ", reg8); + } + printk_spew("\n"); + } + } static const struct device_operations agp_bridge_operations = { - .read_resources = cn400_noop, + .read_resources = agp_bridge_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, .init = agp_bridge_init, diff --git a/src/northbridge/via/cn400/cn400.h b/src/northbridge/via/cn400/cn400.h index 79b2f2f708..bbb6ff112f 100644 --- a/src/northbridge/via/cn400/cn400.h +++ b/src/northbridge/via/cn400/cn400.h @@ -24,6 +24,8 @@ static void cn400_noop() } #endif +#define DEBUG_CN400 + /* VGA stuff */ #define SR_INDEX 0x3c4 #define SR_DATA 0x3c5 diff --git a/src/northbridge/via/cn400/northbridge.c b/src/northbridge/via/cn400/northbridge.c index c4998a8599..9594182864 100644 --- a/src/northbridge/via/cn400/northbridge.c +++ b/src/northbridge/via/cn400/northbridge.c @@ -38,16 +38,28 @@ static void memctrl_init(device_t dev) { device_t vlink_dev; u16 reg16; - u8 ranks, pagec, paged, pagee, pagef, shadowreg; + u8 ranks, pagec, paged, pagee, pagef, shadowreg, reg8; + int i, j; printk_spew("Entering cn400 memctrl_init.\n"); + /* vlink mirror */ + vlink_dev = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_CN400_VLINK, 0); - /* Set up the VGA framebuffer size. */ - reg16 = (log2(CONFIG_VIDEO_MB) << 12) | (1 << 15); + /* Setup Low Memory Top */ + /* 0x47 == HA(32:25) */ + /* 0x84/85 == HA(31:20) << 4 | DRAM Granularity */ + ranks = pci_read_config8(dev, 0x47); + reg16 = (((u16)(ranks - 1) << 9) & 0xFFF0) | 0x01F0; + + pci_write_config16(dev, 0x84, reg16); + printk_spew("Low Top Address = 0x%04X\n", reg16); + + /* Set up the VGA framebuffer size and Base Address */ + /* Note dependencies between agp.c and vga.c and here */ + reg16 = (log2(CONFIG_VIDEO_MB) << 12) | (1 << 15) | 0xF00; pci_write_config16(dev, 0xa0, reg16); - /* Set up VGA timers. */ - pci_write_config8(dev, 0xa2, 0x44); for (ranks = 0x4b; ranks >= 0x48; ranks--) { if (pci_read_config8(dev, ranks)) { @@ -64,6 +76,15 @@ static void memctrl_init(device_t dev) /* AGPCINT Misc. */ pci_write_config8(dev, 0xb8, 0x08); + /* Arbritation Counters */ + pci_write_config8(dev, 0xb2, 0xaa); + + /* Write FIFO Setup */ + pci_write_config8(dev, 0xb3, 0x5a); + + /* Graphics control optimisation */ + pci_write_config8(dev, 0xb4, 0x0f); + /* Shadow RAM */ pagec = 0xff, paged = 0xff, pagee = 0xff, pagef = 0x30; /* PAGE C, D, E are all read write enable */ @@ -74,10 +95,6 @@ static void memctrl_init(device_t dev) shadowreg = pci_read_config8(dev, 0x82); shadowreg |= pagef; pci_write_config8(dev, 0x82, shadowreg); - /* vlink mirror */ - vlink_dev = dev_find_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_CN400_VLINK, 0); - if (vlink_dev) { pci_write_config8(vlink_dev, 0x61, pagec); pci_write_config8(vlink_dev, 0x62, paged); pci_write_config8(vlink_dev, 0x64, pagee); @@ -85,14 +102,36 @@ static void memctrl_init(device_t dev) shadowreg = pci_read_config8(vlink_dev, 0x63); shadowreg |= pagef; pci_write_config8(vlink_dev, 0x63, shadowreg); - } + + /* Activate VGA Frame Buffer */ - printk_spew("Leaving cn400 memctrl_init.\n"); + reg8 = pci_read_config8(dev, 0xA0); + reg8 |= 0x01; + pci_write_config8(dev, 0xA0, reg8); + +#ifdef DEBUG_CN400 + printk_spew("%s PCI Header Regs::\n", dev_path(dev)); + + for (i = 0 ; i < 16; i++) + { + printk_spew("%02X: ", i*16); + for (j = 0; j < 16; j++) + { + reg8 = pci_read_config8(dev, j+(i*16)); + printk_spew("%02X ", reg8); + } + printk_spew("\n"); + } +#endif + printk_spew("Leaving cn400 %s.\n", __func__); } static const struct device_operations memctrl_operations = { .read_resources = cn400_noop, + .set_resources = cn400_noop, + .enable_resources = cn400_noop, .init = memctrl_init, + .ops_pci = 0, }; static const struct pci_driver memctrl_driver __pci_driver = { @@ -129,14 +168,27 @@ static void ram_resource(device_t dev, unsigned long index, if (!sizek) return; - resource = new_resource(dev, index); - resource->base = ((resource_t) basek) << 10; - resource->size = ((resource_t) sizek) << 10; + resource->base = (resource_t) (basek << 10); + resource->size = (resource_t) (sizek << 10); resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; } +static void ram_reservation(device_t dev, unsigned long index, + unsigned long base, unsigned long size) +{ + struct resource *res; + + printk_spew("Configuring Via C3 LAPIC Fixed Resource\n"); + /* Fixed LAPIC resource */ + res = new_resource(dev, 1); + res->base = (resource_t) base; + res->size = size; + res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + static void tolm_test(void *gp, struct device *dev, struct resource *new) { struct resource **best_p = gp; @@ -150,24 +202,23 @@ static void tolm_test(void *gp, struct device *dev, struct resource *new) static u32 find_pci_tolm(struct bus *bus) { - struct resource *min; + struct resource *min = NULL; u32 tolm; - print_debug("Entering CN400 find_pci_tolm\n"); + printk_spew("Entering CN400 find_pci_tolm\n"); - min = 0; search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min); tolm = 0xffffffffUL; if (min && tolm > min->base) tolm = min->base; - print_debug("Leaving find_pci_tolm\n"); + printk_spew("Leaving CN400 find_pci_tolm\n"); return tolm; } -#if HAVE_HIGH_TABLES==1 +#if CONFIG_HAVE_HIGH_TABLES==1 /* maximum size of high tables in KB */ #define HIGH_TABLES_SIZE 64 extern uint64_t high_tables_base, high_tables_size; @@ -175,8 +226,6 @@ extern uint64_t high_tables_base, high_tables_size; static void cn400_domain_set_resources(device_t dev) { - /* The order is important to find the correct RAM size. */ - static const u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 }; device_t mc_dev; u32 pci_tolm; @@ -191,29 +240,21 @@ static void cn400_domain_set_resources(device_t dev) unsigned char rambits; int i, idx; - /* - * Once the register value is not zero, the RAM size is - * this register's value multiply 64 * 1024 * 1024. - */ - for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) { - rambits = pci_read_config8(mc_dev, ramregs[i]); - if (rambits != 0) - break; - } - - tomk = rambits * 64 * 1024; - printk_spew("tomk is 0x%x\n", tomk); + rambits = pci_read_config8(mc_dev, 0x47); + tomk = rambits * 32 * 1024; /* Compute the Top Of Low Memory (TOLM), in Kb. */ tolmk = pci_tolm >> 10; + printk_spew("tomk is 0x%x, tolmk is 0x%08X\n", tomk, tolmk); if (tolmk >= tomk) { /* The PCI hole does does not overlap the memory. */ tolmk = tomk; } -#if HAVE_HIGH_TABLES == 1 - high_tables_base = (tolmk - HIGH_TABLES_SIZE) * 1024; - high_tables_size = HIGH_TABLES_SIZE* 1024; - printk_debug("tom: %lx, high_tables_base: %llx, high_tables_size: %llx\n", tomk*1024, high_tables_base, high_tables_size); +#if CONFIG_HAVE_HIGH_TABLES == 1 + /* Locate the High Tables at the Top of Low Memory below the Video RAM */ + high_tables_base = (uint64_t) (tolmk - (CONFIG_VIDEO_MB *1024) - HIGH_TABLES_SIZE) * 1024; + high_tables_size = (uint64_t) HIGH_TABLES_SIZE* 1024; + printk_spew("tom: %lx, high_tables_base: %llx, high_tables_size: %llx\n", tomk*1024, high_tables_base, high_tables_size); #endif /* Report the memory regions. */ diff --git a/src/northbridge/via/cn400/raminit.c b/src/northbridge/via/cn400/raminit.c index f4db867bed..a44196fd90 100644 --- a/src/northbridge/via/cn400/raminit.c +++ b/src/northbridge/via/cn400/raminit.c @@ -1,5 +1,6 @@ /* * (C) Copyright 2005 Nick Barker <nick.barker9@btinternet.com> + * (C) Copyright 2009 Jon Harrison <bothlyn@blueyonder.co.uk * * * This program is free software; you can redistribute it and/or @@ -19,16 +20,13 @@ */ /* - Automatically detect and set up ddr dram on the CLE266 chipset. - Assumes DDR memory, though chipset also supports SDRAM - Assumes at least 266Mhz memory as no attempt is made to clock + Automatically detect and set up ddr dram on the CN400 chipset. + Assumes DDR400 memory as no attempt is made to clock the chipset down if slower memory is installed. So far tested on: - 256 Mb 266Mhz 1 Bank (i.e. single sided) - 256 Mb 266Mhz 2 Bank (i.e. double sided) - 512 Mb 266Mhz 2 Bank (i.e. double sided) + 512 Mb DDR400 4 Bank / 2 Rank (1GB) (i.e. double sided) */ -/* ported and enhanced from assembler level code in coreboot v1 */ +/* ported from Via VT8263 Code*/ #include <spd.h> #include <sdram_mode.h> @@ -68,6 +66,7 @@ static void c3_cpu_setup(device_t dev) { /* Host bus interface registers (D0F2 0x50-0x67) */ /* Taken from CN700 and updated from running CN400 */ + uint8_t reg8; /* Host Bus I/O Circuit (see datasheet) */ /* Host Address Pullup/down Driving */ @@ -87,6 +86,7 @@ static void c3_cpu_setup(device_t dev) /* AGTL+ Auto Compensation Offest */ pci_write_config8(dev, 0x77, 0x00); + pci_write_config8(dev, 0x78, 0x94); /* Request phase control */ pci_write_config8(dev, 0x50, 0xA8); @@ -135,7 +135,13 @@ static void c3_cpu_setup(device_t dev) /* CPU Miscellaneous Control */ pci_write_config8(dev, 0x55, 0x28); + pci_write_config8(dev, 0x57, 0x69); + /* CPU Host Bus Final Setup */ + reg8 = pci_read_config8(dev, 0x54); + reg8 |= 0x08; + pci_write_config8(dev, 0x54, reg8); + } static void ddr_ram_setup(void) @@ -177,7 +183,7 @@ static void ddr_ram_setup(void) /* Read SPD byte 3, Number of row addresses. */ - c = 0; + c = 0x01; bank = 0x40; b = smbus_read_byte(0x50, SPD_NUM_ROWS); //print_val("\r\nNumber of Rows ", b); @@ -195,7 +201,7 @@ static void ddr_ram_setup(void) b = smbus_read_byte(0x50, SPD_PRIMARY_SDRAM_WIDTH); //print_val("\r\nPrimary DRAM width", b); if( b != 4 ) // not 64/128Mb (x4) - c = 0x80; // 256Mb + c = 0x81; // 256Mb } /* @@ -211,6 +217,10 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3, 0x50, c); } + + /* Disable Upper Banks */ + pci_write_config8(ctrl.d0f3, 0x51, 0x00); + /* else { die("DRAM module size is not supported by CN400\r\n"); @@ -265,8 +275,6 @@ static void ddr_ram_setup(void) else if( b & 0x08) c = 0x01; // 32MB else c = 0x01; // Error, use default - //print_val("\r\nBank 0 (*32 Mb) ",c); - // set bank zero size pci_write_config8(ctrl.d0f3, 0x40, c); @@ -278,7 +286,6 @@ static void ddr_ram_setup(void) { c <<=1; bank |= 0x80; - //print_val("\r\nTotal Memory (*32 Mb) ",c); } /* else { @@ -294,6 +301,10 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3, 0x46,c); pci_write_config8(ctrl.d0f3, 0x47,c); + /* Top Rank Address Mirrored to the South Bridge */ + /* over the VLink */ + pci_write_config8(ctrl.d0f7, 0x57, (c << 1)); + ma = bank; /* Read SPD byte 18 CAS Latency */ @@ -313,13 +324,11 @@ static void ddr_ram_setup(void) c = smbus_read_byte(0x50, SPD_SDRAM_CYCLE_TIME_3RD); print_val("\r\nCycle time at CL X-1 (nS)", c); */ + /* Scaling of Cycle Time SPD data */ + /* 7 4 3 0 */ + /* ns x0.1ns */ bank = smbus_read_byte(0x50, SPD_MIN_CYCLE_TIME_AT_CAS_MAX); - /* Setup DRAM Cycle Time */ - if ( bank <= 0x50 ) bank = 0x14; - else if (bank <= 0x60) bank = 0x18; - else bank = 0x1E; - if( b & 0x10 ){ // DDR offering optional CAS 3 //print_debug("\r\nStarting at CAS 3"); c = 0x30; @@ -347,6 +356,13 @@ static void ddr_ram_setup(void) } } + /* Scale DRAM Cycle Time to tRP/tRCD */ + /* 7 2 1 0 */ + /* ns x0.25ns */ + if ( bank <= 0x50 ) bank = 0x14; + else if (bank <= 0x60) bank = 0x18; + else bank = 0x1E; + /* DRAM Timing Device 0 Fn 3 Offset 56 @@ -401,8 +417,12 @@ static void ddr_ram_setup(void) Read SPD byte 30, device min active to pre-charge time. */ + /* tRAS is in whole ns */ + bank = bank >> 2; + b = smbus_read_byte(0x50, SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY); //print_val("\r\ntRAS ",b); + //print_val("\r\nBank ", bank); if ( b >= (9 * bank)) c |= 0xC0; // set tRAS = 9T else if ( b >= (8 * bank)) c |= 0x80; // set tRAS = 8T else if ( b >= (7 * bank)) c |= 0x40; // set tRAS = 7T @@ -457,15 +477,20 @@ static void ddr_ram_setup(void) /* 4-Way Interleave With Multi-Paging (From Running System)*/ pci_write_config8(ctrl.d0f3, 0x69, c); + /*DRAM Controller Internal Options */ + pci_write_config8(ctrl.d0f3, 0x54, 0x01); + /* DRAM Arbitration Control */ pci_write_config8(ctrl.d0f3, 0x66, 0x82); /* DRAM Control */ - pci_write_config8(ctrl.d0f3, 0x6e, 0x00); + pci_write_config8(ctrl.d0f3, 0x6e, 0x80); /* Disable refresh for now */ pci_write_config8(ctrl.d0f3, 0x6a, 0x00); + /* DDR Clock Gen Duty Cycle Control */ + pci_write_config8(ctrl.d0f3, 0xEE, 0x01); /* DRAM Clock Control */ @@ -484,8 +509,9 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3, 0xe4, 0x99); /* DRAM signal timing control */ - pci_write_config8(ctrl.d0f3, 0x74, 0x99); + pci_write_config8(ctrl.d0f3, 0x74, 0x99); pci_write_config8(ctrl.d0f3, 0x76, 0x09); + pci_write_config8(ctrl.d0f3, 0x77, 0x12); pci_write_config8(ctrl.d0f3, 0xe0, 0xAA); pci_write_config8(ctrl.d0f3, 0xe1, 0x00); @@ -500,6 +526,9 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3, 0xb0, c); + /* Set RAM Decode method */ + pci_write_config8(ctrl.d0f3, 0x55, 0x0a); + /* Enable DIMM Ranks */ pci_write_config8(ctrl.d0f3, 0x48, ma); udelay(200); @@ -528,7 +557,7 @@ static void ddr_ram_setup(void) i = 0x008; // Used later to set SDRAM MSR } - + for( bank = 0 , bank_address=0; bank <= b ; bank++) { /* DDR init described in Via VT8623 BIOS Porting Guide. Pg 28 (4.2.3.1) @@ -641,6 +670,9 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3, 0x7A, 0xA1); pci_write_config8(ctrl.d0f3, 0x7B, 0x62); + /* DQS Duty Cycle Control */ + pci_write_config8(ctrl.d0f3, 0xED, 0x11); + /* SPD byte 5 # of physical banks */ b = smbus_read_byte(0x50, SPD_NUM_DIMM_BANKS) -1; @@ -650,7 +682,7 @@ static void ddr_ram_setup(void) else bank_address = 0; - for(i = 0x40 ; i < 0x0ff; i++){ + for(i = 0x30 ; i < 0x0ff; i++){ pci_write_config8(ctrl.d0f3,0x70,i); // clear *(volatile unsigned long*)(0x4000) = 0; @@ -741,13 +773,15 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f3,0x70,0x67); } - /* Set DQS ChB Output to the default */ - pci_write_config8(ctrl.d0f3, 0x71, 0x6c); + /* Set DQS ChA Data Output Delay to the default */ + pci_write_config8(ctrl.d0f3, 0x71, 0x65); - /* Set DQS Input Delays */ - pci_write_config8(ctrl.d0f3, 0x72, 0x29); - pci_write_config8(ctrl.d0f3, 0x73, 0x99); + /* Set Ch B DQS Output Delays */ + pci_write_config8(ctrl.d0f3, 0x72, 0x2a); + pci_write_config8(ctrl.d0f3, 0x73, 0x29); + pci_write_config8(ctrl.d0f3, 0x78, 0x03); + /* Mystery Value */ pci_write_config8(ctrl.d0f3, 0x67, 0x50); @@ -765,14 +799,14 @@ static void ddr_ram_setup(void) //b = smbus_read_byte(0x50, SPD_REFRESH); //print_val("SPD_REFRESH = ", b); - pci_write_config8(ctrl.d0f3,0x6a,0x6C); + pci_write_config8(ctrl.d0f3,0x6a,0x65); + /* SMM and APIC decoding, we do not use SMM */ + b = 0x29; + pci_write_config8(ctrl.d0f3, 0x86, b); + /* SMM and APIC decoding mirror */ + pci_write_config8(ctrl.d0f7, 0xe6, b); - /* Enable TLB Auto refresh */ - b = pci_read_config8(ctrl.d0f3, 0x69); - b |= 0x10; - pci_write_config8(ctrl.d0f3, 0x69, b); - /* Open Up the Rest of the Shadow RAM */ pci_write_config8(ctrl.d0f3,0x80,0xff); pci_write_config8(ctrl.d0f3,0x81,0xff); @@ -784,26 +818,9 @@ static void ddr_ram_setup(void) pci_write_config8(ctrl.d0f7,0x71,0xc8); - print_debug("CN400 Init done\r\n"); /* VGA device. */ pci_write_config16(ctrl.d0f3, 0xa0, (1 << 15)); pci_write_config16(ctrl.d0f3, 0xa4, 0x0010); - - /* Graphics Control Basic Init. */ - //pci_write_config8(ctrl.d0f3, 0xb0, 0xFf); - //pci_write_config8(ctrl.d0f3, 0xb1, 0xAA); - //pci_write_config8(ctrl.d0f3, 0xb2, 0xAA); - //pci_write_config8(ctrl.d0f3, 0xb3, 0x5A); - //pci_write_config8(ctrl.d0f3, 0xb4, 0x0f); - - /* AGP Controller Interface Basic Init */ - //pci_write_config8(ctrl.d0f3, 0xc0, 0x3b); - - /* VGA device, Basic frame Buffer Init. */ - //pci_write_config8(ctrl.d0f3, 0xa0, 0x01); - /* Bit 7 = Enable VGA When Set to 1 */ - //pci_write_config8(ctrl.d0f3, 0xa1, 0xef); - //pci_write_config8(ctrl.d0f3, 0xa4, 0x00); - + print_debug("CN400 raminit.c done\r\n"); } diff --git a/src/northbridge/via/cn400/vga.c b/src/northbridge/via/cn400/vga.c index 0624ba1e3f..6c61f3de5d 100644 --- a/src/northbridge/via/cn400/vga.c +++ b/src/northbridge/via/cn400/vga.c @@ -47,6 +47,9 @@ static void vga_init(device_t dev) { u8 reg8; u32 temp; +#ifdef DEBUG_CN400 + int i, j; +#endif temp = (0xffffffff - CONFIG_FALLBACK_SIZE - 0xffff); printk_debug("Copying BOCHS BIOS from 0x%08X to 0xf000\n", temp); @@ -73,8 +76,8 @@ static void vga_init(device_t dev) pci_write_config8(dev, 0x04, 0x07); pci_write_config8(dev, 0x0d, 0x20); - pci_write_config32(dev, 0x10, 0xf4000008); - pci_write_config32(dev, 0x14, 0xfb000000); + pci_write_config32(dev, 0x10, 0xf0000008); + pci_write_config32(dev, 0x14, 0xf4000000); printk_debug("INSTALL REAL-MODE IDT\n"); setup_realmode_idt(); @@ -101,6 +104,21 @@ static void vga_init(device_t dev) /* Clear the BOCHS BIOS out of memory, so it doesn't confuse Linux. */ memset(0xf0000, 0, 0x10000); + +#ifdef DEBUG_CN400 + printk_spew("%s PCI Header Regs::\n", dev_path(dev)); + + for (i = 0 ; i < 16; i++) + { + printk_spew("%02X: ", i*16); + for (j = 0; j < 16; j++) + { + reg8 = pci_read_config8(dev, j+(i*16)); + printk_spew("%02X ", reg8); + } + printk_spew("\n"); + } +#endif } static void vga_read_resources(device_t dev) |