summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/via/vt8623/northbridge.c84
-rw-r--r--src/northbridge/via/vt8623/raminit.c295
2 files changed, 202 insertions, 177 deletions
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);
}