diff --git a/src/mainboard/supermicro/p4dc6/cacheramtest.c b/src/mainboard/supermicro/p4dc6/cacheramtest.c index 704da3e275..26592b2945 100644 --- a/src/mainboard/supermicro/p4dc6/cacheramtest.c +++ b/src/mainboard/supermicro/p4dc6/cacheramtest.c @@ -9,10 +9,11 @@ #include #include #include - - -#define SMBUS_BUS 0 -#define SMBUS_DEVFN ((0x1f << 3) + 3) +#include +#include +#include +#include +#include #define LPC_BUS 0 #define LPC_DEVFN ((0x1f << 3) + 0) @@ -31,245 +32,24 @@ #define SMBUS_MEM_DEVICE_0 (0xa << 3) -static struct smbus_info{ - u32 base; -} smbus; - - -#define SMBHSTSTAT 0x0 -#define SMBHSTCTL 0x2 -#define SMBHSTCMD 0x3 -#define SMBXMITADD 0x4 -#define SMBHSTDAT0 0x5 -#define SMBHSTDAT1 0x6 -#define SMBBLKDAT 0x7 -#define SMBTRNSADD 0x9 -#define SMBSLVDATA 0xa -#define SMLINK_PIN_CTL 0xe -#define SMBUS_PIN_CTL 0xf - - -void smbus_setup(void) -{ - u8 smbus_enable; - u16 smbus_func_enable; - - pcibios_write_config_dword(SMBUS_BUS, SMBUS_DEVFN, 0x20, 0x1000 | 1); - pcibios_write_config_byte(SMBUS_BUS, SMBUS_DEVFN, 0x40, 1); - pcibios_write_config_word(SMBUS_BUS, SMBUS_DEVFN, 0x4, 1); - - pcibios_read_config_dword(SMBUS_BUS, SMBUS_DEVFN, 0x20, &smbus.base); - pcibios_read_config_byte(SMBUS_BUS, SMBUS_DEVFN, 0x40, &smbus_enable); - pcibios_read_config_word(SMBUS_BUS, SMBUS_DEVFN, 0x4, &smbus_func_enable); - - printk_debug("smbus.base = %08x\n", smbus.base); - printk_debug("smbus.enable = %02x\n", smbus_enable); - printk_debug("smbus.func_enable = %04x\n", smbus_func_enable); - - smbus.base &= ~1; - printk_debug("\n"); - printk_debug("smbus.base = %08x\n", smbus.base); - printk_debug("smbus.enable = %02x\n", smbus_enable); - printk_debug("smbus.func_enable = %04x\n", smbus_func_enable); - - /* Disable interrupt generation */ - outb(0, smbus.base + SMBHSTCTL); -} - -static void smbus_wait_until_ready(void) -{ - while((inb(smbus.base + SMBHSTSTAT) & 1) == 1) { - /* nop */ - } -} - -static void smbus_wait_until_done(void) -{ - unsigned char byte; - do { - byte = inb(smbus.base + SMBHSTSTAT); - } - while((byte &1) == 1); - while( (byte & ~(1|(1<<6))) == 0) { - byte = inb(smbus.base + SMBHSTSTAT); - } -} - - -#if 0 -static void smbus_print_error(unsigned char host_status_register) -{ - - printk_debug("smbus_error: 0x%02x\n", host_status_register); - if (host_status_register & (1 << 7)) { - printk_debug("Byte Done Status\n"); - } - if (host_status_register & (1 << 6)) { - printk_debug("In Use Status\n"); - } - if (host_status_register & (1 << 5)) { - printk_debug("SMBus Alert Status\n"); - } - if (host_status_register & (1 << 4)) { - printk_debug("Interrup/SMI# was Failed Bus Transaction\n"); - } - if (host_status_register & (1 << 3)) { - printk_debug("Bus Error\n"); - } - if (host_status_register & (1 << 2)) { - printk_debug("Device Error\n"); - } - if (host_status_register & (1 << 1)) { - printk_debug("Interrupt/SMI# was Successful Completion\n"); - } - if (host_status_register & (1 << 0)) { - printk_debug("Host Busy\n"); - } -} -#endif - -static int smbus_read_byte(unsigned device, unsigned address, unsigned char *result) -{ - unsigned char host_status_register; - unsigned char byte; - - smbus_wait_until_ready(); - - /* setup transaction */ - /* disable interrupts */ - outb(inb(smbus.base + SMBHSTCTL) & (~1), smbus.base + SMBHSTCTL); - /* set the device I'm talking too */ - outb(((device & 0x7f) << 1) | 1, smbus.base + SMBXMITADD); - /* set the command/address... */ - outb(address & 0xFF, smbus.base + SMBHSTCMD); - /* set up for a byte data read */ - outb((inb(smbus.base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus.base + SMBHSTCTL); - - /* clear any lingering errors, so the transaction will run */ - outb(inb(smbus.base + SMBHSTSTAT), smbus.base + SMBHSTSTAT); - - /* clear the data byte...*/ - outb(0, smbus.base + SMBHSTDAT0); - - /* start the command */ - outb((inb(smbus.base + SMBHSTCTL) | 0x40), smbus.base + SMBHSTCTL); - - /* poll for transaction completion */ - smbus_wait_until_done(); - - host_status_register = inb(smbus.base + SMBHSTSTAT); -#if 1 - /* Ignore the In Use Status... */ - host_status_register &= ~(1 << 6); -#endif - - /* read results of transaction */ - byte = inb(smbus.base + SMBHSTDAT0); - -#if 0 - if (host_status_register != 0x02) { - smbus_print_error(host_status_register); - } -#endif - - *result = byte; - return host_status_register != 0x02; -} - -#define FLOPPY_DEVICE 0 -#define PARALLEL_DEVICE 1 -#define COM1_DEVICE 2 -#define COM2_DEVICE 3 -#define KBC_DEVICE 5 -#define CIR_DEVICE 6 -#define GAME_PORT_DEVICE 7 -#define GPIO_PORT2_DEVICE 8 -#define GPIO_PORT3_DEVICE 9 -#define ACPI_DEVICE 0xa -#define HW_MONITOR_DEVICE 0xb - -#define SIO_PORT 0x2e - -static void enter_pnp(void) -{ - outb(0x87, SIO_PORT); - outb(0x87, SIO_PORT); -} - -static void exit_pnp(void) -{ - outb(0xaa, SIO_PORT); -} - -static void write_config(unsigned char value, unsigned char reg) -{ - outb(reg, SIO_PORT); - outb(value, SIO_PORT +1); -} - -static unsigned char read_config(unsigned char reg) -{ - outb(reg, SIO_PORT); - return inb(SIO_PORT +1); -} -static void set_logical_device(int device) -{ - write_config(device, 0x07); -} - -static void set_enable(int enable) -{ - write_config(enable?0x1:0x0, 0x30); -#if 0 - if (enable) { - printk_debug("enabled superio device: %d\n", - read_config(0x07)); - } -#endif -} - -#if 0 -static void set_iobase0(unsigned iobase) -{ - write_config((iobase >> 8) & 0xff, 0x60); - write_config(iobase & 0xff, 0x61); -} - -static void set_iobase1(unsigned iobase) -{ - write_config((iobase >> 8) & 0xff, 0x62); - write_config(iobase & 0xff, 0x63); -} - -static void set_irq0(unsigned irq) -{ - write_config(irq, 0x70); -} - -static void set_irq1(unsigned irq) -{ - write_config(irq, 0x72); -} - -static void set_drq(unsigned drq) -{ - write_config(drq & 0xff, 0x74); -} -#endif +#define TSCYCLE_SLOW 1000 /* ns */ +#define TSCYCLE_FAST 10 /* ns */ +static void ndelay(unsigned long); +static void ram_zap(unsigned long, unsigned long); static void select_rdram_i2c(void) { unsigned char byte; - enter_pnp(); - byte = read_config(0x2b); + w83627hf_enter_pnp(SIO_BASE); + byte = pnp_read_config(SIO_BASE, 0x2b); byte |= 0x30; - write_config(byte, 0x2b); - set_logical_device(GPIO_PORT2_DEVICE); - set_enable(1); - byte = read_config(0xf0); + pnp_write_config(SIO_BASE, byte, 0x2b); + pnp_set_logical_device(SIO_BASE, GPIO_PORT2_DEVICE); + pnp_set_enable(SIO_BASE, 1); + byte = pnp_read_config(SIO_BASE, 0xf0); byte &= ~(1 << 3); - write_config(byte, 0xf0); - exit_pnp(); + pnp_write_config(SIO_BASE, byte, 0xf0); + w83627hf_exit_pnp(SIO_BASE); } #define I860_MCH_BUS 0 @@ -407,6 +187,7 @@ static void rdram_wait_until_ready(void) do { pcibios_read_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, &ricm); } while(ricm & RICM_BUSY); + ndelay(1000); /* delay after ready because the documentation says to */ } struct rdram_reg_values { @@ -414,15 +195,49 @@ struct rdram_reg_values { u16 channel_b; }; -u16 tparm[5]={0x3a,0x3a,0x3a,0x4a,0x5a}; -u16 tcdly1[5]={0,1,2,2,2}; +/* rdram timing tables */ +static u16 tparm[5]={0x3a,0x3a,0x3a,0x4a,0x5a}; +static u16 tcdly1[5]={0,1,2,2,2}; -u8 spd_devices[4]={0,0,0,0}; -u8 spd_row_col[4]={0,0,0,0}; -u8 spd_banks[4]={0,0,0,0}; -u8 spd_size[2]={0,0}; +/* serial presence detect needed variables */ +/* Byte 99 number of devices for each stick */ +static u8 spd_devices[4]={0,0,0,0}; +/* Byte 4 # of row address bits, # of column address bits */ +static u8 spd_row_col[4]={0,0,0,0}; +/* Byte 5 # of bank bits lower nibble */ +static u8 spd_banks[4]={0,0,0,0}; +/* Byte 9 Misc. Device configuration S28, and S3 bits are used */ +static u8 spd_misc_conf[4]={0,0,0,0}; +/* Byte 31 power down exit max time phase A (tPDNXA,max) */ +static u8 spd_pdnxa_max[4]={0,0,0,0}; +/* Byte 32 power down exit max time phase B (tPDNXB,max) */ +static u8 spd_pdnxb_max[4]={0,0,0,0}; +/* Byte 33 Map exit max time phase A (tNAPXA,max) */ +static u8 spd_napxa_max[4]={0,0,0,0}; +/* Byte 34 Nap exit max time phase B (tNAPXB,max) */ +static u8 spd_napxb_max[4]={0,0,0,0}; +/* Byte 12 Min ras to cas cycles */ +static u8 spd_rcd_min[4]={0,0,0,0}; +/* Byte 100 Module data width */ +static u8 spd_data_width[4]={0,0,0,0}; +/* Byte 35 bits 0-3<<8 + byte 37 give the rdram max mhz rate */ +static u16 spd_mhz_max[4]={0,0,0,0}; +/* Byte 35 bits 4-7<<4 + byte 36 give the rdram min mhz rate */ +static u16 spd_mhz_min[4]={0,0,0,0}; +/* The size of each device in mega bytes. */ +static u8 spd_size[2]={0,0}; -int rdram_chips=0; +static int rdram_chips=0; /* number of ram chips on the rimms */ +static u32 total_rdram; /* Total rdram found */ + +/* register index tables */ +static u8 mch_gar[16] ={MCH_GAR0,MCH_GAR1,MCH_GAR2,MCH_GAR3,MCH_GAR4,MCH_GAR5, + MCH_GAR6,MCH_GAR7,MCH_GAR8,MCH_GAR9,MCH_GAR10,MCH_GAR11, + MCH_GAR12,MCH_GAR13,MCH_GAR14,MCH_GAR15}; + +static u8 mch_gba[16] ={MCH_GBA0,MCH_GBA1,MCH_GBA2,MCH_GBA3,MCH_GBA4,MCH_GBA5, + MCH_GBA6,MCH_GBA7,MCH_GBA8,MCH_GBA9,MCH_GBA10,MCH_GBA11, + MCH_GBA12,MCH_GBA13,MCH_GBA14,MCH_GBA15}; static void __rdram_run_command(u8 channel, u16 sdevice_id, u16 reg, u16 command) { @@ -454,7 +269,6 @@ static void __rdram_run_command(u8 channel, u16 sdevice_id, u16 reg, u16 command /* Wait until the command completes */ rdram_wait_until_ready(); - } static void rdram_run_command(u8 channel, u16 sdevice_id, u16 command) @@ -602,7 +416,8 @@ static void rdram_read_domain_initialization(int rdram_devices) u8 adj_a[32],adj_b[32]; u8 l=20; - /* Set all the rdram devices to the slowest clock cycles */ + total_rdram=0; + /* Set all the rdram devices to the fastest clock cycles */ rdram_write_reg(0, BCAST, REG_TCDLY1, 0, 0 ); rdram_write_reg(0, BCAST, REG_TPARM, 0x3a, 0x3a); @@ -622,7 +437,7 @@ static void rdram_read_domain_initialization(int rdram_devices) adj_b[j]=(mem[4]&0x0ff)-1; if(adj_a[j](16*TSCYCLE_SLOW)) + ndelay(delay); + else + ndelay(16*TSCYCLE_SLOW); rdram_run_command(0, BCAST, CMD_RDRAM_CLEAR_RESET); rdram_write_reg(0, BCAST, REG_TEST34, 0, 0); rdram_write_reg(0, BCAST, REG_TEST78, 0, 0); @@ -708,6 +531,11 @@ static void rdram_set_clear_reset(void) */ static void rdram_init(int rdram_devices) { + u16 tcycle; + u16 pdnxa,pdnxb,pdnx,napx,napxa,napxb; + u16 tfrm; + int i; + /* 3.1/3.2 RDRAM SIO reset */ rdram_run_command(0, 0, CMD_RDRAM_SIO_RESET); @@ -715,8 +543,13 @@ static void rdram_init(int rdram_devices) rdram_write_reg(0, BCAST, REG_TEST77, 0, 0); /* 3.4 Write Tcycle */ - /* FIXME Hard coded as 400Mhz for now */ - rdram_write_reg(0, BCAST, REG_TCYCLE, 0x27, 0x27); + /* Calculate the Tcycle */ + for(tcycle=spd_mhz_max[0],i=1;i<4;i++) + if(spd_mhz_max[i]&&(tcycle>spd_mhz_max[i])) + tcycle=spd_mhz_max[i]; + tcycle = 15625 / tcycle; + rdram_write_reg(0, BCAST, REG_TCYCLE, tcycle, tcycle); + printk_debug("Tcycle = %x\n",tcycle); /* 3.5 Set SDEVID */ set_sdevid(rdram_devices); @@ -725,29 +558,61 @@ static void rdram_init(int rdram_devices) set_devid(rdram_devices); /* 3.7 Write PDNX, PDNXA Registers */ - /* FIXME don't hard code these timings... */ - rdram_write_reg(0, BCAST, REG_PDNXA, 0x7, 0x7); - rdram_write_reg(0, BCAST, REG_PDNX, 0x5, 0x5); + /* tscycle=10ns or <= 100MHz MCH datasheet pg 156 */ + for(pdnxa=(u16)spd_pdnxa_max[0],i=1;i<4;i++) + if(pdnxa 10) + tfrm-=4; + } + else { + tfrm = 9; + } + rdram_write_reg(0, BCAST, REG_TFRM, tfrm, tfrm); /* 3.12 SETR/CLRR */ rdram_set_clear_reset(); @@ -756,13 +621,13 @@ static void rdram_init(int rdram_devices) /* Program all Current controll registers with * an initial approximation. 1/2 their maximum is recommended. */ - /* FIXME figure out voltage assymetry */ rdram_write_reg(0, BCAST, REG_CCA, 0x40, 0x40); rdram_write_reg(0, BCAST, REG_CCB, 0x40, 0x40); /* 3.14 Powerdown Exit */ - /* FIXME not all RDRAMS models need this */ - rdram_run_command(0, BCAST, CMD_RDRAM_POWERDOWN_EXIT); + /* test is S28IECO is set, if yes power up ram from PDN state */ + if(spd_misc_conf[0]&4) + rdram_run_command(0, BCAST, CMD_RDRAM_POWERDOWN_EXIT); /* 3.15 SETF */ rdram_run_command(0, BCAST, CMD_SET_FAST_CLK); @@ -772,60 +637,64 @@ void mch_init(void) { u8 byte; u16 word; - u32 dword; - u16 word2; +// u32 dword; + u16 top; int bits1,bits2; + int reg,reg_last,dev; + /* Program Group Attribute Registers */ /* Calculate the GAR value */ bits1=(spd_row_col[0]>>4)+(spd_row_col[0]&0x0f)+spd_banks[0]; byte=0x80; if(bits1==21) { - byte=0xc4; + byte=0x84; spd_size[0]=32; } else if(bits1==20) { byte=0x82; spd_size[0]=16; } - if(byte!=0x80) + if(byte!=0x80) { if(spd_banks[0]==5) byte|=0x10; - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR0, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR1, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR2, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR3, byte); + if((spd_row_col[0]&0x0f)==7) byte|=0x40; + } + for(reg=dev=0;dev>4)+(spd_row_col[1]&0x0f)+spd_banks[1]; byte=0x80; if(bits2==21) { - byte=0xd4; + byte=0x84; spd_size[1]=32; } else if(bits2==20) { - byte=0x92; + byte=0x82; spd_size[1]=16; } - if(byte!=0x80) - if(spd_banks[2]==5) byte|=0x10; - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR4, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR5, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR6, byte); - pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_GAR7, byte); + if(byte!=0x80) { + if(spd_banks[1]==5) byte|=0x10; + if((spd_row_col[1]&0x0f)==7) byte|=0x40; + } + for(dev=0;dev= 8) - return; - - // it is recommended that we disable and enable cache when we - // do this. - /* Disable cache */ - /* Write back the cache and flush TLB */ - asm volatile ( - "movl %%cr0, %0\n\t" - "orl $0x40000000, %0\n\t" - "movl %0, %%cr0\n\t" - :"=r" (tmp) - ::"memory"); - - if (size == 0) { - /* The invalid bit is kept in the mask, so we simply clear the - relevant mask register to disable a range. */ - wrmsr (MTRRphysMask_MSR (reg), 0, 0); - } else { - /* Bit 32-35 of MTRRphysMask should be set to 1 */ - wrmsr (MTRRphysBase_MSR (reg), base | type, 0); - wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0x0F); - } - - // turn cache back on. - asm volatile ("movl %%cr0, %0\n\t" - "andl $0x9fffffff, %0\n\t" - "movl %0, %%cr0\n\t":"=r" (tmp)::"memory"); + printk_debug("%08lx\nDRAM filled\n", addr); } @@ -1140,6 +971,7 @@ void cache_ram_start(void) pci_set_method(); printk_info("Setting up smbus controller\n"); smbus_setup(); + ich2_rtc_init(); printk_info("Selecting rdram i2c bus\n"); select_rdram_i2c(); @@ -1162,21 +994,12 @@ void cache_ram_start(void) if ((i &0x0f) == 0x0f) { printk_debug("\n"); } - if(i==99) spd_devices[j-SMBUS_MEM_DEVICE_0]=byte; - if(i==4) spd_row_col[j-SMBUS_MEM_DEVICE_0]=byte; - if(i==5) spd_banks[j-SMBUS_MEM_DEVICE_0]=byte&0x0f; } } printk_debug("\n"); #endif + load_spd_vars(); init_memory(); - printk_debug("set_var_mtrr\n"); -#if 0 - set_var_mtrr(0, 0, 512*1024*1024, MTRR_TYPE_WRBACK); -#else - set_var_mtrr(0, 0, 512*1024*1024, MTRR_TYPE_WRCOMB); -#endif - printk_debug("set_var_mtrr done\n"); #if 0 error |= ramcheck(0x000f0000, 0x000f1000, 20); #endif @@ -1200,15 +1023,6 @@ void cache_ram_start(void) ram_verify(addr, addr + 0x400, 1); } } -#endif -#if 0 - error |= ramcheck( 0x00000000, 0x00000400, 128); - error |= ramcheck2(0x00000000, 0x00000400, 128); - error |= ramcheck( 0x14000000, 0x14000400, 128); - error |= ramcheck2(0x14000000, 0x14000400, 128); -#endif -#if 0 - error |= ramcheck2(0x00100000, 0x00180000, 128); #endif error |= ramcheck(0x00000000, 0x00080000, 20); error |= ramcheck(0x02000000, 0x02080000, 20); @@ -1230,7 +1044,7 @@ void cache_ram_start(void) #if 0 error |= ramcheck(0x00000000, 0x00080000, 20); #endif -#if 0 +#if 1 for(i = 0; i < rdram_chips; i++) { for(j = 0; j < sizeof(rdram_regs)/sizeof(rdram_regs[0]); j++) { struct rdram_reg_values values; @@ -1253,5 +1067,11 @@ void cache_ram_start(void) printk_debug("\n"); } #endif - if (error) while(1); + if (error) { + printk_err("Something isn't working!!!\n"); + while(1); + } else { + printk_info("Leaving cacheram...\n"); + } + }