okay, i've cleaned up all the evil typos (many..duh!), split the column address type detection and the size detection into separate functions, rewrote the size detection and made the functions a bit safer (where did my const go?). gcc still doesn't like my way of calling functions..i'll go figure out how to fix that. as soon as i can get my hands on a mainboard with the northbridge chip i'm going to test it. if you've questions: feel free to ask. in the meantime i'll write some more raminits for slot1/s370/socket7 chipsets. any particular wishes? Holger
/* * This file is part of the LinuxBIOS project. * * Copyright (C) * * 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 */
#include <spd.h> #include <sdram_mode.h> #include <delay.h> //#include <../arch/i386/include/stdint.h> #include <device/device.h> #include "raminit.h" #include "m1621.h"
/*----------------------------------------------------------------------------- Macros and definitions. -----------------------------------------------------------------------------*/
/* Uncomment this to enable debugging output. */ #define DEBUG_RAM_SETUP 1
#define REFRESH_66 0x0411 #define REFRESH_75 0x0493; #define REFRESH_83 0x0516; #define REFRESH_100 0x0618;
/* Debugging macros. */ #if defined(DEBUG_RAM_SETUP) #define PRINT_DEBUG(x) print_debug(x) #define PRINT_DEBUG_HEX8(x) print_debug_hex8(x) #define PRINT_DEBUG_HEX16(x) print_debug_hex16(x) #define PRINT_DEBUG_HEX32(x) print_debug_hex32(x) #define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0)) #else #define PRINT_DEBUG_(x) #define PRINT_DEBUG_HEX8(x) #define PRINT_DEBUG_HEX16(x) #define PRINT_DEBUG_HEX32(x) #define DUMPNORTH() #endif
/*----------------------------------------------------------------------------- EDO/FP/SDRAM configuration functions. -----------------------------------------------------------------------------*/
/** * Routine for the RAM detection */ static void ram_detection(const struct mem_controller* ctrl) { uint8_t u8_fsb100 = 0; uint8_t u8_row = 0; uint16_t u16_reg; uint32_t u32_reg; uint32_t au32_dram_row[DIMM_SOCKETS * DIMM_ROWS];
/* Detect Host Clock Bus Frequency */ u32_reg = pci_read_config(ctrl->d0, CR_MRNG); u8_fsb100 = (uint8_t)(u32_reg >> 30);
/* Turn off cache (L1 & L2) */ //TODO
/* Disable DRAM ECC function */ u32_reg = pci_read_config32(ctrl->d0, CR_MCMD); u32_reg &= ~((uint32_t)e_MEMORY_PROTECTION);
/* Enable DRAM refresh and set the refresh cycle counter */ u32_reg &= ((uint32_t)e_DRAM_REFRESH_ENABLE); u32_reg &= ~((uint32_t)e_DRAM_REFRESH_CYCLE); if(u8_fsb100) { u32_reg |= (uint32_t)REFRESH_100; } else { /* TODO determine the real fsb by cpu core speed / multiplier */ u32_reg |= (uint32_t)REFRESH_66; }
pci_write_config32(ctrl->d0, CR_MCMD, u32_reg);
/* Disable remapping & shadow */ // TODO
/* Set CAS layout topology as cross-bar */ u16_reg = pci_read_config16(ctrl->d0, CR_HCFG); u16_reg |= 0x80000000; pci_write_config(ctrl->d0, CR_HCFG, u16_reg);
/* Detect RAM presence and type RAM in all rows */ for(u8_row = 0; u8_row < DIMM_SOCKETS*DIMM_ROWS; u8_row++) {
/* Start of DRAM type detection */ /* Initialize the current row */ initialize_row(ctrl, au32_dram_row, u8_row);
/* Detect type of ram in the current row */ detect_type(ctrl, au32_dram_row, u8_row);
/* Check if types of the two rows of a bank match */ if((u8_row & 0x01) && (au32_dram_row[u8_row] & e_2ND_ROW) != 0) { /* Scratch the type detection results if they don't match */ if((au32_dram_row[u8_row] & e_DRAM_TYPE) != (au32_dram_row[u8_row - 1] & e_DRAM_TYPE)) { au32_dram_row[u8_row] & ~(e_2ND_ROW); continue; } }
/* Detect column address type of the current row */ detect_ca(ctrl, au32_dram_row, u8_row);
/* Detect size of the current row */ detect_size(ctrl, au32_dram_row, u8_row); } }
/** * Initializes a row before it can be checked for DRAM */ static void initialize_row(const struct mem_controller* ctrl, uint32_t* u32_dram_row, const uint8_t u8_row) { uint8_t u8_bank = u8_row >> 1;
u32_dram_row[u8_row] = pci_read_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank));
/* Initialize the current bank to ... */ /* ... EDO ... */ u32_dram_row[u8_row] &= ~((uint32_t)e_DRAM_TYPE); u32_dram_row[u8_row] |= ((uint32_t)e_EDO);
if(u8_row & 0x01) { /* ... 2nd Row present ... */ u32_dram_row[u8_row] &= (uint32_t)e_2ND_ROW; } else { /* ... 1st Row present ... */ u32_dram_row[u8_row] &= (uint32_t)e_1ST_ROW; } /* ... row size 256MB ... */ u32_dram_row[u8_row] &= ~((uint32_t)e_ROW_SIZE); u32_dram_row[u8_row] |= ((uint32_t)e_256MB);
/* and column address 12bit */ u32_dram_row[u8_row] &= ~((uint32_t)e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= ((uint32_t)e_12BIT);
pci_write_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank), u32_dram_row[u8_row]); }
/** * Detects type of RAM */ static void detect_type(const struct mem_controller* ctrl, uint32_t* u32_dram_row, const uint8_t u8_row) { uint32_t u32_reg = 0; uint8_t u8_type_detected = 0; uint8_t u8_bank = u8_row >> 1; uint32_t u32_AA0 = 0x0; uint32_t u32_AA8 = 0x8; uint64_t u64_DD1 = 0x5555555555555555ULL; uint64_t u64_DD2 = 0xAAAAAAAAAAAAAAAAULL; uint64_t u64_DD3 = 0; uint64_t u64_DD4 = 0;
for(;;) { switch(u32_dram_row[u8_row]) {
case e_EDO: { /* Write some data */ dimm_write64(u32_AA0, u64_DD1); dimm_write64(u32_AA8, u64_DD2);
/* Enable EDO detection mode */ u32_reg = pci_read_config32(ctrl->d0, CR_MCMD); u32_reg &= ((uint32_t)e_EDO_DETECT_MODE); pci_write_config32(ctrl->d0, CR_MCMD, u32_reg);
/* Read the data back */ dimm_read64(u32_AA0, u64_DD3); dimm_read64(u32_AA8, u64_DD4);
/* Disable EDO detection mode */ u32_reg = pci_read_config32(ctrl->d0, CR_MCMD); u32_reg &= ~((uint32_t)e_EDO_DETECT_MODE); pci_write_config32(ctrl->d0, CR_MCMD, u32_reg);
if(u64_DD3 != u64_DD1 || u64_DD4 != u64_DD2) { /* No EDO RAM. Test FPM next */ u32_dram_row[u8_row] &= ~(e_DRAM_TYPE); u32_dram_row[u8_row] = e_FPM; /* Set the current bank to FPM */ pci_write_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank), u32_dram_row[u8_row]); } else { /* EDO found */ u8_type_detected = 1; } break; }
case e_FPM: { /* Write some data */ dimm_write64(u32_AA0, u64_DD1); dimm_write64(u32_AA8, u64_DD2);
/* Read the data back */ dimm_read64(u32_AA0, u64_DD3); dimm_read64(u32_AA8, u64_DD4);
if(u64_DD3 != u64_DD1 || u64_DD4 != u64_DD2) { /* No FPM RAM. Test SDR next */ u32_dram_row[u8_row] &= ~(e_DRAM_TYPE); u32_dram_row[u8_row] = e_SDR; /* Set the current bank to SDR */ pci_write_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank), u32_dram_row[u8_row]); } else { /* FPM found */ u8_type_detected = 1; }
break; }
case e_SDR: { /* Disable DRAM refresh */ u32_reg = pci_read_config32(ctrl->d0, CR_MCMD); u32_reg &= ~((uint32_t)e_DRAM_REFRESH_ENABLE); pci_write_config32(ctrl->d0, CR_MCMD, u32_reg);
/* Wait for 5µS */ udelay(5);
/* Enable DRAM refresh */ u32_reg = pci_read_config32(ctrl->d0, CR_MCMD); u32_reg &= ((uint32_t)e_DRAM_REFRESH_ENABLE); pci_write_config32(ctrl->d0, CR_MCMD, u32_reg);
/* Write some data */ dimm_write64(u32_AA0, u64_DD1); dimm_write64(u32_AA8, u64_DD2);
/* Read the data back */ dimm_read64(u32_AA0, u64_DD3); dimm_read64(u32_AA8, u64_DD4);
if(u64_DD3 != u64_DD1 || u64_DD4 != u64_DD2) { /* No SDR RAM. No RAM at all found! */ u32_dram_row[u8_row] &= ~(e_DRAM_TYPE); /* Clear the row presence status */ if(u8_row & 0x01) { u32_dram_row[u8_row] &= ~(e_2ND_ROW); } else { u32_dram_row[u8_row] &= ~(e_1ST_ROW); } } else { /* SDR found */ u8_type_detected = 1; }
break; }
default : { break; } }
/* Quit type detection if detection was successful or the row is empty */ if((u8_type_detected != 0) || ((u32_dram_row[u8_row] & ~(e_1ST_ROW) == 0) && (u32_dram_row[u8_row] & ~(e_2ND_ROW) == 0))) { break; } } } /** * Detects column address type */ static void detect_ca(const struct mem_controller* ctrl, uint32_t* u32_dram_row, const uint8_t u8_row) { uint8_t u8_ca_detected = 0; uint8_t u8_error_detecting_ca = 0; uint8_t u8_bank = u8_row >> 1; uint32_t u32_AA0 = 0x0; uint32_t u32_AA8 = 0; uint64_t u64_DD1 = 0x5555555555555555ULL; uint64_t u64_DD2 = 0xAAAAAAAAAAAAAAAAULL; uint64_t u64_DD3 = 0;
u32_dram_row[u8_row] = pci_read_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank));
/* Set 10bit column address for SDR */ if((u32_dram_row[u8_row] & e_DRAM_TYPE) == e_SDR) { u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_10BIT; pci_write_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank), u32_dram_row[u8_row]); }
for(;;) { /* Write some data */ dimm_write64(u32_AA0, u64_DD1);
switch(u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) { case e_8BIT : { u32_AA8 = 0x00000200;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 8bit column address ram found */ u8_ca_detected = 1; /* Set the maximum row size to 64MB */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_64MB; } else { /* User defined column address detection next */ u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_USER_DEFINED; }
break; }
case e_9BIT : { u32_AA8 = 0x00000800;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 9bit column address ram found */ u8_ca_detected = 1; /* Set the maximum row size to 128MB */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_128MB;
} else if (u64_DD3 == u64_DD2) { /* 8bit column address detection next */ u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_8BIT; } else { /* Error detecting column address mode */ u8_error_detecting_ca = 1; }
break; }
case e_10BIT : { u32_AA8 = 0x00001000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 10bit column address ram found */ u8_ca_detected = 1; } else if (u64_DD3 == u64_DD2) { /* 9bit column address detection next */ u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_9BIT; } else { /* Error detecting column address mode */ u8_error_detecting_ca = 1; }
break; }
case e_11BIT : { u32_AA8 = 0x00002000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 11bit column address ram found */ u8_ca_detected = 1; } else if (u64_DD3 == u64_DD2) { /* 10bit column address detection next */ u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_10BIT; } else { /* Error detecting column address mode */ u8_error_detecting_ca = 1; }
break; }
case e_12BIT : { u32_AA8 = 0x04000000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 12bit column address ram found */ u8_ca_detected = 1; } else if (u64_DD3 == u64_DD2) { /* 11bit column address detection next */ u32_dram_row[u8_row] &= ~(e_COLUMN_ADDRESS_TYPE); u32_dram_row[u8_row] |= e_11BIT; } else { /* Error detecting column address mode */ u8_error_detecting_ca = 1; }
break; }
case e_USER_DEFINED : { u32_AA8 = 0x00002000;
if((u32_dram_row[u8_row] & e_DRAM_TYPE) != e_SDR) { /* Error detecting column address mode */ u8_error_detecting_ca = 1; } else { // TODO : ADJUST REGISTERS F0-FCh
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* User defined column address ram found */ u8_ca_detected = 1; } else { /* SDRAM type not supported */ u8_error_detecting_ca = 1; } }
break; }
default : { /* Undefined column address type */ u8_error_detecting_ca = 1;
break; } }
/* Quit column address type detection if a column address was found or an error occured */ if(u8_error_detecting_ca != 0 || u8_ca_detected != 0) { break; } }
/* Set the detected column address type */ if(u8_ca_detected != 0) { pci_write_config32(ctrl->d0, ((uint8_t)CR_MROW + u8_bank), u32_dram_row[u8_row]); } }
/** * Detects DRAM row size */ static void detect_size(const struct mem_controller* ctrl, uint32_t* u32_dram_row, const uint8_t u8_row) { uint8_t u8_size_detected = 0; uint8_t u8_error_detecting_size = 0; uint8_t u8_bank = u8_row >> 1; uint32_t u32_AA0 = 0x0; uint32_t u32_AA8 = 0; uint64_t u64_DD1 = 0x5555555555555555ULL; uint64_t u64_DD2 = 0xAAAAAAAAAAAAAAAAULL; uint64_t u64_DD3 = 0;
for(;;) { switch (u32_dram_row[u8_row] & e_ROW_SIZE) { case e_4MB : { u32_AA8 = 0x00200000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 4MB found */ u8_size_detected = 1; } else { /* Error detecting size */ u8_error_detecting_size = 1; }
break; }
case e_8MB : { /* 10bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_10BIT) { u32_AA8 = 0x00200000; } /* 8bit and 9bit column address detection scheme */ else { u32_AA8 = 0x00400000; }
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
/* 10bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_10BIT) { if(u64_DD3 == u64_DD1) { /* 8MB found */ u8_size_detected = 1; } else { /* Error detecting size */ u8_error_detecting_size = 1; } } /* 8bit and 9bit column address detection scheme */ else{ if(u64_DD3 == u64_DD1) { /* 8MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 4MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_4MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; } }
break; }
case e_16MB : { u32_AA8 = 0x00800000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 16MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 8MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_8MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; }
break; }
case e_32MB : { /* 11bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_11BIT) { u32_AA8 = 0x00800000; } /* 8bit, 9bit and 10bit column address detection scheme */ else { u32_AA8 = 0x01000000; }
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
/* 11bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_11BIT) { if(u64_DD3 == u64_DD1) { /* 32MB found */ u8_size_detected = 1; } else { /* Error detecting size */ u8_error_detecting_size = 1; } } /* 8bit, 9bit and 10bit column address detection scheme */ else{ if(u64_DD3 == u64_DD1) { /* 32MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 16MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_16MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; } }
break; }
case e_64MB : { u32_AA8 = 0x02000000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 64MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 32MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_32MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; }
break; }
case e_128MB : { /* 12bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_12BIT) { u32_AA8 = 0x02000000; } /* 10bit and 11bit column address detection scheme */ else { u32_AA8 = 0x04000000; }
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
/* 12bit column address detection scheme */ if((u32_dram_row[u8_row] & e_COLUMN_ADDRESS_TYPE) == e_12BIT) { if(u64_DD3 == u64_DD1) { /* 128MB found */ u8_size_detected = 1; } else { /* Error detecting size */ u8_error_detecting_size = 1; } } /* 10bit and 11bit column address detection scheme */ else{ if(u64_DD3 == u64_DD1) { /* 128MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 64MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_64MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; } }
break; }
case e_256MB : { u32_AA8 = 0x08000000;
/* Write some more data */ dimm_write64(u32_AA8, u64_DD2);
/* Read data back */ dimm_read64(u32_AA0, u64_DD3);
if(u64_DD3 == u64_DD1) { /* 256MB found */ u8_size_detected = 1; } else if(u64_DD3 == u64_DD2) { /* 128MB detection next */ u32_dram_row[u8_row] &= ~(e_ROW_SIZE); u32_dram_row[u8_row] |= e_128MB; } else { /* Error detecting size */ u8_error_detecting_size = 1; }
break; }
default : { /* Unknown DRAM size */ u8_error_detecting_size = 1; break; } }
/* Quit if the size of the current row was detected or an error occured */ if((u8_size_detected != 0) || (u8_error_detecting_size != 0)){ break; } } /* Clear the row presence status if an error occured */ if(u8_error_detecting_size != 0){ if(u8_row & 0x01) { u32_dram_row[u8_row] &= ~(e_2ND_ROW); } else { u32_dram_row[u8_row] &= ~(e_1ST_ROW); } } }
/* * This file is part of the LinuxBIOS project. * * Copyright (C) * * 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 */
#ifndef RAMINIT_H #define RAMINIT_H
/* The ALi Aladdin-Pro II supports up to four DIMMs with 2 rows each. */ #define DIMM_SOCKETS 4 #define DIMM_ROWS 2
enum E_CR_MROW_MASKS { e_MA_ASSERTATION = 0x80000000, e_PAGE_HIT_WAIT_STATE = 0x40000000, e_EDO_SR_SDR_CL = 0x20000000, e_DRAM_TYPE = 0x18000000, e_1ST_ROW = 0x06000000, e_2ND_ROW = 0x01800000, e_ROW_SIZE = 0x00700000, e_COLUMN_ADDRESS_TYPE = 0x000F0000, e_EDO_ASR_SDR_CSQ = 0x00008000, e_EDO_RAH_SDR_BANK = 0x00006000, e_EDO_ASC_SDR_BANK = 0x00001800, e_EDO_RCAS = 0x00000600, e_EDO_WCAS = 0x00000180, e_EDO_CP_SDR_REG = 0x00000040, e_EDO_CSH_SDR_RCD_RP = 0x00000030, e_EDO_RAS_SDR_BANK = 0x0000000C, e_EDO_RP_SDR_BANK = 0x00000003 };
enum E_CR_MCMD_MASKS { e_MEMORY_PROTECTION = 0xC0000000, e_MWB_ALLOCATION = 0x30000000, e_REF_QUEUE_DEPTH = 0x08000000, e_REF_START_CONTROL = 0x07000000, e_AF_START_CONTROL = 0x00C00000, e_DRAM_REFRESH_ENV = 0x00200000, e_EDO_DETECT_MODE = 0x00100000, e_DRAM_REFRESH_ENABLE = 0x00080000, e_DRAM_REF_CASL_RASL = 0x00040000, e_DRAM_REF_RAS = 0x00030000, e_DRAM_REF_RP = 0x0000C000, e_DRAM_REFRESH_CYCLE = 0x00003FFF, };
enum E_DRAM_TYPE { e_FPM = 0x00000000, e_EDO = 0x08000000, e_SDR = 0x10000000, };
enum E_DRAM_ROW_SIZE { e_4MB = 0x00000000, e_8MB = 0x00100000, e_16MB = 0x00200000, e_32MB = 0x00300000, e_64MB = 0x00400000, e_128MB = 0x00500000, e_256MB = 0x00600000 };
enum E_DRAM_CA { e_8BIT = 0x00000000, e_9BIT = 0x00010000, e_10BIT = 0x00020000, e_11BIT = 0x00030000, e_12BIT = 0x00040000, e_USER_DEFINED = 0x000F0000 };
uint32_t au32_DRAM[DIMM_SOCKETS];
/* The ALi Aladdin-Pro II memory controller has one channel only. */ struct mem_controller { device_t d0; uint16_t channel0[DIMM_SOCKETS]; };
#endif /* RAMINIT_H */
/* * This file is part of the LinuxBIOS project. * * Copyright (C) * * 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 */
/* * Datasheet: * - Name: Acer Laboratories Inc. - Aladdin-Pro II M1621 North Bridge */
/* * Host-to-PCI Bridge Registers. * The values in parenthesis are the default values as per datasheet. * Any addresses between 0x00 and 0xff not listed below are reserved. */ #define CR_VID 0x00 /* Vendor Identification (0x10B9). */ #define CR_DID 0x02 /* Device Identification (0x1621). */ #define CR_CMD 0x04 /* PCI Command Register (0x006). */ #define CR_STAS 0x06 /* PCI Status Register (0x0410). */ #define CR_RID 0x08 /* Revision Identification (0x01). */ #define CR_SRLP 0x09 /* Specific Register-level Programming Register (0x00). */ #define CR_SCC 0x0A /* Sub-Class Code (0x00). */ #define CR_BCC 0x0B /* Base Class Code (0x06). */ #define CR_BAR 0x10 /* Base Address Register (0x00000008). */ #define CR_CPR 0x34 /* Capabilities Pointer Register (0xB0) */ #define CR_FC3PCI 0x40 /* Flushing Counter for USWC Posted Write to 33PCI (0x0C) */ #define CR_FC6PCI 0x41 /* Flushing Counter for USWC Posted Write to 66PCI (0x0C) */ #define CR_PIOW1 0x42 /* First I/O Address for Posted I/O Write (0x0000) */ #define CR_PIOW2 0x44 /* Second I/O Address for Posted I/O Write (0x0000) */ #define CR_PIOW3 0x46 /* Third I/O Address for Posted I/O Write (0x0000) */ #define CR_PIOW4 0x48 /* Fourth I/O Address for Posted I/O Write (0x0000) */ #define CR_IOPWCNT 0x4A /* Control Register for I/O Posted Write Cycles (0x00) */ #define CR_CRSPCNF 0x4B /* Control Register for Special & Configuration Cycles (0x00) */ #define CR_CFDT3P 0x4C /* Counter for 33 PCI Delay Transaction (0x04) */ #define CR_CFDT6P 0x4D /* Counter for 66 PCI Delay Transaction (0x04) */ #define CR_PPM1 0x4E /* Power Management for 33 and 66 PCI Block (0x7F) */ #define CR_PPM2 0x4F /* Power Management for Host Block (0x7F) */ #define CR_HWGEN 0x50 /* Host to AGP Memory-Write Enhancement Register (0x0C) */ #define CR_GPMFW 0x51 /* 66 PCI Master Device Pre-Fetch & Post-Write Control Register (0x00) */ #define CR_GPCMD 0x52 /* 66 PCI Bridge Command Register (0x00) */ #define CR_GPBRC 0x53 /* 66 PCI Bridge Retry Counter Register (0x02) */ #define CR_GPBECR 0x54 /* 66 PCI Bridge Error Command Register (0x0000) */ #define CR_GPBESR 0x56 /* 66 PCI Bridge Error Status Register (0x00) */ #define CR_GPBER 0x57 /* AGP Arbiter Control Register (0x00) */ #define CR_GPMDMT 0x58 /* 66 PCI Master Device Multiple Transaction Timer (0x00) */ #define CR_GPBMT 0x59 /* 66 PCI Bridge Multiple Transaction Timer (0x00) */ #define CR_P2PRPC 0x5A /* P2P Bridge Retry Counter Register (0x02) */ #define CR_PCLKRUN 0x5C /* PCI CLKRUN Control Register (0x00) */ #define CR_HWEN 0x60 /* Host to PCI Memory-Write Enhancement Register (0x00) */ #define CR_PMFW 0x61 /* PCI Master Device Pre-Fetch & Post-Write Control Register (0x00) */ #define CR_PCMD 0x62 /* PCI Bridge Command Register (0x00) */ #define CR_PBRC 0x63 /* PCI Bridge Retry Counter Register (0x02) */ #define CR_PBECR 0x64 /* PCI Bridge Error Command Register (0x0000) */ #define CR_PBESR 0x66 /* PCI Bridge Error Status Register (0x00) */ #define CR_PACR 0x67 /* PCI Arbiter Control Register (0x00) */ #define CR_PMDMT 0x68 /* PCI Master Device Multiple Transaction Timer (0x00) */ #define CR_PBMT 0x69 /* PCI Master Device Multiple Transaction Timer (0x00) */ #define CR_MROW 0x6C /* Memory Bank 0 Register (0xE600FFFF) */ //#define CR_MROW1 0x70 /* Memory Bank 1 Register (0xE000FFFF) */ //#define CR_MROW2 0x74 /* Memory Bank 2 Register (0xE000FFFF) */ //#define CR_MROW3 0x78 /* Memory Bank 3 Register (0xE000FFFF) */ #define CR_MCMD 0x7C /* Memory Command Register (0x00C7C411) */ #define CR_HCFG 0x80 /* Host Interface Configuration Register (0x0C01) */ #define CR_PDEC 0x82 /* PCI Decode Mode Register (0x00) */ #define CR_MSMM 0x83 /* A/B Page and SMM Range Register (0x08) */ #define CR_MPAM 0x84 /* Memory Attribute Register (0x00000000) */ #define CR_MRNG 0x88 /* Memory Gap Range Register (0x00000000) */ #define CR_USWC 0x8C /* USWC Gap Range Register (0x00010000) */ #define CR_ECCST 0x90 /* Memory ECC Error Status Register (0x0000) */ #define CR_SPR1 0x94 /* Spare Register #1 (0x00000000) */ #define CR_SPR2 0x98 /* Spare Register #2 (0x00000000) */ #define CR_SPR3 0x9C /* Spare Register #3 (0x00000000) */ #define CR_PMC2 0xA0 /* Power Management Control Block #2 (0x00000020) */ #define CR_AGPCI 0xB0 /* AGP Capability Identifier Register (0x00800002) */ #define CR_AGPSTA 0xB4 /* AGP Status Register (0x20000203) */ #define CR_AGPCMD 0xB8 /* AGP Command Register (0x80000101) */ #define CR_NLVMCTL 0xBC /* AGP NLVM Control Register (0x00000000) */ #define CR_TGCLR 0xC0 /* AGP TAG Clear Register (0x00000080) */ #define CR_AGPCR1 0xC4 /* AGP Control Register One (0x00000000) */ #define CR_AGPCR2 0xC8 /* AGP Control Register Two (0x00002400) */ #define CR_AGPCR3 0xCC /* AGP Control Register Three (0x00000000) */ #define CR_AGPCR4 0xD0 /* AGP Control Register Four (0x00000000) */ #define CR_AGPCR5 0xD4 /* AGP Control Register Five (0x00000000) */ #define CR_RCA0 0xF0 /* User-Defined Row/Column Address Mapping Register 0 (0x43214320) */ #define CR_RCA1 0xF4 /* User-Defined Row/Column Address Mapping Register 0 (0x43214320) */ #define CR_RCA2 0xF8 /* User-Defined Row/Column Address Mapping Register 0 (0x43214320) */ #define CR_RCA3 0xFC /* User-Defined Row/Column Address Mapping Register 0 (0x43214320) */
* popkonserve popkonserve@gmx.de [070804 19:51]:
okay, i've cleaned up all the evil typos (many..duh!), split the column address type detection and the size detection into separate functions, rewrote the size detection and made the functions a bit safer (where did my const go?). gcc still doesn't like my way of calling functions..i'll go figure out how to fix that. as soon as i can get my hands on a mainboard with the northbridge chip i'm going to test it. if you've questions: feel free to ask. in the meantime i'll write some more raminits for slot1/s370/socket7 chipsets. any particular wishes? Holger
Do you have a complete patch including support for a mainboard, too?
Other than that, please read our documentation (it exists! ;) on how to contribute and sign the code off so we can check it in.
http://www.linuxbios.org/Development_Guidelines#How_to_contribute
Stefan