diff options
Diffstat (limited to 'src/northbridge/via/vt8623/raminit.c')
-rw-r--r-- | src/northbridge/via/vt8623/raminit.c | 628 |
1 files changed, 0 insertions, 628 deletions
diff --git a/src/northbridge/via/vt8623/raminit.c b/src/northbridge/via/vt8623/raminit.c deleted file mode 100644 index f281ce096c..0000000000 --- a/src/northbridge/via/vt8623/raminit.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Nick Barker <nick.barker9@btinternet.com> - * - * 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 - */ - -/* - 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 - 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) -*/ -/* ported and enhanced from assembler level code in coreboot v1 */ - -#include <spd.h> -#include <cpu/x86/mtrr.h> -#include "raminit.h" - - - -void dimm_read(unsigned long bank,unsigned long x) -{ - //unsigned long eax; - volatile unsigned long y; - //eax = x; - y = * (volatile unsigned long *) (x+ bank) ; - -} - - -void -dumpnorth(device_t north) -{ - uint16_t r, c; - for(r = 0; r < 256; r += 16) { - print_debug_hex8(r); - print_debug(":"); - for(c = 0; c < 16; c++) { - print_debug_hex8(pci_read_config8(north, r+c)); - print_debug(" "); - } - print_debug("\n"); - } -} -void print_val(char *str, int val) -{ - print_debug(str); - print_debug_hex8(val); -} - -static void ddr_ram_setup(const struct mem_controller *ctrl) -{ - device_t north = (device_t) 0; - uint8_t b, c, bank; - uint16_t i; - unsigned long bank_address; - - print_debug("vt8623 init starting\n"); - north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0); - north = 0; - - - pci_write_config8(north,0x75,0x08); - - /* 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,0x04); - -/* - DRAM MA Map Type Device 0 Offset 58 - - Determine memory addressing based on the module's memory technology and - arrangement. See Table 4-9 of Intel's 82443GX datasheet for details. - - Bank 1/0 MA map type 58[7-5] - Bank 1/0 command rate 58[4] - Bank 3/2 MA map type 58[3-1] - Bank 3/2 command rate 58[0] - - - Read SPD byte 17, Number of banks on SDRAM device. -*/ - c = 0; - b = smbus_read_byte(DIMM0,17); - print_val("Detecting Memory\nNumber of Banks ",b); - - if( b != 2 ){ // not 16 Mb type - -/* - Read SPD byte 3, Number of row addresses. -*/ - b = smbus_read_byte(DIMM0,3); - print_val("\nNumber of Rows ",b); - if( b >= 0x0d ){ // not 64/128Mb (rows <=12) - -/* - Read SPD byte 13, Primary DRAM width. -*/ - b = smbus_read_byte(DIMM0,13); - print_val("\nPriamry DRAM width",b); - if( b != 4 ) // mot 64/128Mb (x4) - c = 0x80; // 256Mb - } - -/* - 64/128Mb chip - - Read SPD byte 4, Number of column addresses. -*/ - b = smbus_read_byte(DIMM0,4); - print_val("\nNo Columns ",b); - if( b == 10 || b == 11 ) c |= 0x60; // 10/11 bit col addr - if( b == 9 ) c |= 0x40; // 9 bit col addr - if( b == 8 ) c |= 0x20; // 8 bit col addr - - } - print_val("\nMA type ",c); - pci_write_config8(north,0x58,c); - -/* - DRAM bank size. See 4.3.1 pg 35 - - 5a->5d set to end address for each bank. 1 bit == 16MB - 5a = bank 0 - 5b = bank 0 + b1 - 5c = bank 0 + b1 + b2 - 5d = bank 0 + b1 + b2 + b3 -*/ - -// Read SPD byte 31 Module bank density - c = 0; - b = smbus_read_byte(DIMM0,31); - if( b & 0x02 ) c = 0x80; // 2GB - else if( b & 0x01) c = 0x40; // 1GB - else if( b & 0x80) c = 0x20; // 512Mb - else if( b & 0x40) c = 0x10; // 256Mb - else if( b & 0x20) c = 0x08; // 128Mb - else if( b & 0x10) c = 0x04; // 64Mb - else if( b & 0x08) c = 0x02; // 32Mb - else if( b & 0x04) c = 0x01; // 16Mb / 4Gb - else c = 0x01; // Error, use default - - - print_val("\nBank 0 (*16 Mb) ",c); - - // set bank zero size - pci_write_config8(north,0x5a,c); - // SPD byte 5 # of physical banks - b = smbus_read_byte(DIMM0,5); - - print_val("\nNo Physical Banks ",b); - if( b == 2) - c <<=1; - - print_val("\nTotal Memory (*16 Mb) ",c); - // set banks 1,2,3 - pci_write_config8(north,0x5b,c); - pci_write_config8(north,0x5c,c); - pci_write_config8(north,0x5d,c); - - - /* Read SPD byte 18 CAS Latency */ - b = smbus_read_byte(DIMM0,18); - print_debug("\nCAS Supported "); - if(b & 0x04) - print_debug("2 "); - if(b & 0x08) - print_debug("2.5 "); - if(b & 0x10) - print_debug("3"); - print_val("\nCycle time at CL X (nS)",smbus_read_byte(DIMM0,9)); - print_val("\nCycle time at CL X-0.5 (nS)",smbus_read_byte(DIMM0,23)); - print_val("\nCycle time at CL X-1 (nS)",smbus_read_byte(DIMM0,25)); - - - if( b & 0x10 ){ // DDR offering optional CAS 3 - print_debug("\nStarting at CAS 3"); - c = 0x30; - /* see if we can better it */ - if( b & 0x08 ){ // DDR mandatory CAS 2.5 - if( smbus_read_byte(DIMM0,23) <= 0x75 ){ // we can manage 133MHz at CAS 2.5 - print_debug("\nWe can do CAS 2.5"); - c = 0x20; - } - } - if( b & 0x04 ){ // DDR mandatory CAS 2 - if( smbus_read_byte(DIMM0,25) <= 0x75 ){ // we can manage 133MHz at CAS 2 - print_debug("\nWe can do CAS 2"); - c = 0x10; - } - } - }else{ // no optional CAS values just 2 & 2.5 - print_debug("\nStarting at CAS 2.5"); - c = 0x20; // assume CAS 2.5 - if( b & 0x04){ // Should always happen - if( smbus_read_byte(DIMM0,23) <= 0x75){ // we can manage 133MHz at CAS 2 - print_debug("\nWe can do CAS 2"); - c = 0x10; - } - } - } - - - -/* - DRAM Timing Device 0 Offset 64 - - Row pre-charge 64[7] - RAS Pulse width 64[6] - CAS Latency 64[5,4] - - SDR DDR - 00 1T - - 01 2T 2T - 10 3T 2.5T - 11 - 3T - - RAS/CAS delay 64[2] - Bank Interleave 64[1,0] - - - Determine row pre-charge time (tRP) - - T nS SPD*4 SPD - 1T 7.5 0x1e - 2T 15 0x3c - 3T 22.5 0x5a - 4T 30 0x1e - 5T 37.5 0x25 .5? - 6T 45 0x2d - - - Read SPD byte 27, min row pre-charge time. -*/ - - b = smbus_read_byte(DIMM0,27); - print_val("\ntRP ",b); - if( b > 0x3c ) // set tRP = 3T - c |= 0x80; - - -/* - Determine RAS to CAS delay (tRCD) - - Read SPD byte 29, min row pre-charge time. -*/ - - b = smbus_read_byte(DIMM0,29); - print_val("\ntRCD ",b); - if( b > 0x3c ) // set tRCD = 3T - c |= 0x04; - -/* - Determine RAS pulse width (tRAS) - - - Read SPD byte 30, device min active to pre-charge time. -*/ - - b = smbus_read_byte(DIMM0,30); - print_val("\ntRAS ",b); - if( b > 0x25 ) // set tRAS = 6T - c |= 0x40; - - -/* - Determine bank interleave - - Read SPD byte 17, Number of banks on SDRAM device. -*/ - b = smbus_read_byte(DIMM0,17); - if( b == 4) c |= 0x02; - else if (b == 2) c |= 0x01; - - - /* set DRAM timing for all banks */ - pci_write_config8(north,0x64,c); - - /* set DRAM type to DDR */ - pci_write_config8(north,0x60,0x02); - - - /* DRAM arbitration timer */ - pci_write_config8(north,0x65,0x32); - - -/* - CPU Frequency Device 0 Offset 54 - - CPU Frequency 54[7,6] bootstraps at 0xc0 (133MHz) - DRAM burst length = 8 54[5] -*/ - pci_write_config8(north,0x54,0xe0); - - -/* - DRAM Clock Device 0 Offset 69 - - DRAM/CPU speed 69[7,6] (leave at default 00 == CPU) - Controller que > 2 69[5] - Controller que != 4 69[4] - DRAM 8k page size 69[3] - DRAM 4k page size 69[2] - Multiple page mode 69[0] -*/ - - pci_write_config8(north,0x69,0x2d); - - /* Delay >= 100ns after DRAM Frequency adjust, See 4.1.1.3 pg 15 */ - udelay(200); - - - /* Enable CKE */ - pci_write_config8(north,0x6b,0x10); - udelay(200); - - /* Disable DRAM refresh */ - pci_write_config8(north,0x6a,0x0); - - - /* Set drive for 1 bank DDR (Table 4.4.2, pg 40) */ - pci_write_config8(north,0x6d,0x044); - pci_write_config8(north,0x67,0x3a); - - b = smbus_read_byte(DIMM0,5); // SPD byte 5 # of physical banks - if( b > 1) { - // Increase drive control when there is more than 1 physical bank - pci_write_config8(north,0x6c,0x84); // Drive control: MA, DQS, MD/CKE - pci_write_config8(north,0x6d,0x55); // DC: Early clock select, DQM, CS#, MD - } - /* place frame buffer on last bank */ - if( !b) b++; // make sure at least 1 bank reported - pci_write_config8(north,0xe3,b-1); - - for( bank = 0 , bank_address=0; bank < b ; bank++){ -/* - DDR init described in Via BIOS Porting Guide. Pg 28 (4.2.3.1) -*/ - - - /* NOP command enable */ - pci_write_config8(north,0x6b,0x11); - - /* read a double word from any address of the dimm */ - dimm_read(bank_address,0x1f000); - //udelay(200); - - /* All bank precharge Command Enable */ - pci_write_config8(north,0x6b,0x12); - dimm_read(bank_address,0x1f000); - - - /* MSR Enable */ - pci_write_config8(north,0x6b,0x13); - dimm_read(bank_address,0x2000); - udelay(1); - dimm_read(bank_address,0x800); - udelay(1); - - /* All banks precharge Command Enable */ - pci_write_config8(north,0x6b,0x12); - dimm_read(bank_address,0x1f200); - - /* CBR Cycle Enable */ - pci_write_config8(north,0x6b,0x14); - - /* Read 8 times */ - dimm_read(bank_address,0x1f300); - udelay(100); - dimm_read(bank_address,0x1f400); - udelay(100); - dimm_read(bank_address,0x1f500); - udelay(100); - dimm_read(bank_address,0x1f600); - udelay(100); - dimm_read(bank_address,0x1f700); - udelay(100); - dimm_read(bank_address,0x1f800); - udelay(100); - dimm_read(bank_address,0x1f900); - udelay(100); - dimm_read(bank_address,0x1fa00); - udelay(100); - - /* MSR Enable */ - pci_write_config8(north,0x6b,0x13); - -/* - Mode Register Definition - with adjustement so that address calculation is correct - 64 bit technology, therefore - a0-a2 refer to byte within a 64 bit long word, and a3 is the first address line presented - to DIMM as a row or column address. - - MR[9-7] CAS Latency - MR[6] Burst Type 0 = sequential, 1 = interleaved - MR[5-3] burst length 001 = 2, 010 = 4, 011 = 8, others reserved - MR[0-2] dont care - - CAS Latency - 000 reserved - 001 reserved - 010 2 - 011 3 - 100 reserved - 101 1.5 - 110 2.5 - 111 reserved - - CAS 2 0101011000 = 0x158 - CAS 2.5 1101011000 = 0x358 - CAS 3 0111011000 = 0x1d8 - -*/ - c = pci_read_config8(north,0x64); - if( (c & 0x30) == 0x10 ) - dimm_read(bank_address,0x150); - else if((c & 0x30) == 0x20 ) - dimm_read(bank_address,0x350); - else - dimm_read(bank_address,0x1d0); - - //dimm_read(bank_address,0x350); - - /* Normal SDRAM Mode */ - pci_write_config8(north,0x6b,0x58 ); - - - bank_address = pci_read_config8(north,0x5a+bank) * 0x1000000; - } // end of for each bank - - /* Adjust DQS (data strobe output delay). See 4.2.3.2 pg 29 */ - pci_write_config8(north,0x66,0x41); - - /* determine low bond */ - if( b == 2) - bank_address = pci_read_config8(north,0x5a) * 0x1000000; - else - bank_address = 0; - - for(i = 0 ; i < 0x0ff; i++){ - c = i ^ (i>>1); // convert to gray code - pci_write_config8(north,0x68,c); - // clear - *(volatile unsigned long*)(0x4000) = 0; - *(volatile unsigned long*)(0x4100+bank_address) = 0; - *(volatile unsigned long*)(0x4200) = 0; - *(volatile unsigned long*)(0x4300+bank_address) = 0; - *(volatile unsigned long*)(0x4400) = 0; - *(volatile unsigned long*)(0x4500+bank_address) = 0; - - - // fill - *(volatile unsigned long*)(0x4000) = 0x12345678; - *(volatile unsigned long*)(0x4100+bank_address) = 0x81234567; - *(volatile unsigned long*)(0x4200) = 0x78123456; - *(volatile unsigned long*)(0x4300+bank_address) = 0x67812345; - *(volatile unsigned long*)(0x4400) = 0x56781234; - *(volatile unsigned long*)(0x4500+bank_address) = 0x45678123; - - // verify - if( *(volatile unsigned long*)(0x4000) != 0x12345678) - continue; - - if( *(volatile unsigned long*)(0x4100+bank_address) != 0x81234567) - continue; - - if( *(volatile unsigned long*)(0x4200) != 0x78123456) - continue; - - if( *(volatile unsigned long*)(0x4300+bank_address) != 0x67812345) - continue; - - if( *(volatile unsigned long*)(0x4400) != 0x56781234) - continue; - - if( *(volatile unsigned long*)(0x4500+bank_address) != 0x45678123) - continue; - - // if everything verified then found low bond - break; - - } - print_val("\nLow Bond ",i); - if( i < 0xff ){ - c = i++; - for( ; i <0xff ; i++){ - pci_write_config8(north,0x68,i ^ (i>>1) ); - - // clear - *(volatile unsigned long*)(0x8000) = 0; - *(volatile unsigned long*)(0x8100+bank_address) = 0; - *(volatile unsigned long*)(0x8200) = 0x0; - *(volatile unsigned long*)(0x8300+bank_address) = 0; - *(volatile unsigned long*)(0x8400) = 0x0; - *(volatile unsigned long*)(0x8500+bank_address) = 0; - - // fill - *(volatile unsigned long*)(0x8000) = 0x12345678; - *(volatile unsigned long*)(0x8100+bank_address) = 0x81234567; - *(volatile unsigned long*)(0x8200) = 0x78123456; - *(volatile unsigned long*)(0x8300+bank_address) = 0x67812345; - *(volatile unsigned long*)(0x8400) = 0x56781234; - *(volatile unsigned long*)(0x8500+bank_address) = 0x45678123; - - // verify - if( *(volatile unsigned long*)(0x8000) != 0x12345678) - break; - - if( *(volatile unsigned long*)(0x8100+bank_address) != 0x81234567) - break; - - if( *(volatile unsigned long*)(0x8200) != 0x78123456) - break; - - if( *(volatile unsigned long*)(0x8300+bank_address) != 0x67812345) - break; - - if( *(volatile unsigned long*)(0x8400) != 0x56781234) - break; - - if( *(volatile unsigned long*)(0x8500+bank_address) != 0x45678123) - break; - - } - print_val(" High Bond",i); - c = ((i - c)<<1)/3 +c; - print_val(" Setting DQS delay",c); - c = c ^ (c>>1); // convert to gray code - pci_write_config8(north,0x68,c); - pci_write_config8(north,0x68,0x42); - }else{ - print_debug("Unable to determine low bond - Setting default\n"); - pci_write_config8(north,0x68,0x59); - } - - - pci_write_config8(north,0x66,0x01); - pci_write_config8(north,0x55,0x07); - - - -/* - DRAM refresh rate Device 0 Offset 6a - - Units of 16 DRAM clock cycles. (See 4.4.1 pg 39) - - Rx69 (DRAM freq) Rx58 (chip tech) Rx6a - - 133MHz 64/128Mb 0x86 - 133MHz 256/512Mb 0x43 - 100MHz 64/128Mb 0x65 - 100MHz 256/512Mb 0x32 -*/ - - b = pci_read_config8(north,0x58); - if( b < 0x80 ) // 256 tech - pci_write_config8(north,0x6a,0x86); - else - pci_write_config8(north,0x6a,0x43); - - pci_write_config8(north,0x61,0xff); - //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); - - - /* graphics aperture base */ - - pci_write_config8(north,0x13,0xd0); - - //pci_write_config8(north,0xe1,0xdf); - //pci_write_config8(north,0xe2,0x42); - pci_write_config8(north,0xe0,0x00); - - pci_write_config8(north,0x84,0x80); - pci_write_config16(north,0x80,0x610f); - pci_write_config32(north,0x88,0x00000002); - - - - pci_write_config8(north,0xa8,0x04); - pci_write_config8(north,0xac,0x2f); - pci_write_config8(north,0xae,0x04); - - print_debug("vt8623 done\n"); - dumpnorth(north); - - print_debug("AGP\n"); - north = pci_locate_device(PCI_ID(0x1106, 0xb091), 0); - pci_write_config32(north,0x20,0xddf0dc00); - pci_write_config32(north,0x24,0xdbf0d800); - pci_write_config8(north,0x3e,0x0c); - //dumpnorth(north); - - //print_err("VGA\n"); - //north = pci_locate_device(PCI_ID(0x1106, 0x3122), 0); - //pci_write_config32(north,0x10,0xd8000008); - //pci_write_config32(north,0x14,0xdc000000); - //dumpnorth(north); - -} |