Changeset 3765 for trunk/coreboot-v2

Show
Ignore:
Timestamp:
11/21/08 18:14:40 (7 weeks ago)
Author:
uwe
Message:

i810: Add support for multiple DIMMs, both single-sided and double-sided,
as well as most (all?) combinations thereof.

Drop some unused code, the unused row_offset variable, and obsolete comments.
Also, fix a typo (thanks to Stefan Reinauer for noticing).

This is tested on the MSI MS-6178 with a number of different DIMM
combinations and so far all of them worked fine.

Signed-off-by: Elia Yehuda <z4ziggy@…>
Signed-off-by: Uwe Hermann <uwe@…>
Acked-by: Peter Stuge <peter@…>

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/coreboot-v2/src/northbridge/intel/i82810/raminit.c

    r3764 r3765  
    22 * This file is part of the coreboot project. 
    33 * 
    4  * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de> 
     4 * Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de> 
    55 * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com> 
     6 * Copyright (C) 2008 Elia Yehuda <z4ziggy@gmail.com> 
    67 * 
    78 * This program is free software; you can redistribute it and/or modify 
     
    5657#define RAM_COMMAND_CBR          0x7 /* CBR */ 
    5758 
     59/* 
     60 * Table which returns the RAM size in MB when fed the DRP[7:4] or [3:0] value. 
     61 * Note that 2 is a value which the DRP should never be programmed to. 
     62 * Some size values appear twice, due to single-sided vs dual-sided banks. 
     63 */ 
     64static const u16 translate_i82810_to_mb[] = { 
     65/* DRP  0  1 (2) 3   4   5   6   7   8   9   A   B   C    D    E    F */ 
     66/* MB */0, 8, 0, 16, 16, 24, 32, 32, 48, 64, 64, 96, 128, 128, 192, 256, 
     67}; 
     68 
     69/* Size of bank#0 for dual-sided DIMMs */ 
     70static const u8 translate_i82810_to_bank[] = { 
     71/* DRP  0  1 (2) 3  4  5   6   7  8   9   A  B   C   D  E    F */ 
     72/* MB */0, 0, 0, 8, 0, 16, 16, 0, 32, 32, 0, 64, 64, 0, 128, 128, 
     73}; 
     74 
    5875/*----------------------------------------------------------------------------- 
    5976SDRAM configuration functions. 
     
    6380 * Send the specified RAM command to all DIMMs. 
    6481 * 
    65  * @param TODO 
    66  * @param TODO 
    67  */ 
    68 static void do_ram_command(uint32_t command, uint32_t addr_offset, 
    69                            uint32_t row_offset) 
    70 { 
    71         uint8_t reg; 
    72  
    73         /* TODO: Support for multiple DIMMs. */ 
     82 * @param The RAM command to send to the DIMM(s). 
     83 */ 
     84static void do_ram_command(u8 command) 
     85{ 
     86        u32 addr, addr_offset; 
     87        u16 dimm_size, dimm_start, dimm_bank; 
     88        u8 reg8, drp; 
     89        int i, caslatency; 
    7490 
    7591        /* Configure the RAM command. */ 
    76         reg = pci_read_config8(PCI_DEV(0, 0, 0), DRAMT); 
    77         reg &= 0x1f;            /* Clear bits 7-5. */ 
    78         reg |= command << 5; 
    79         pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, reg); 
    80  
    81         /* RAM_COMMAND_NORMAL affects only the memory controller and 
    82            doesn't need to be "sent" to the DIMMs. */ 
    83         /* if (command == RAM_COMMAND_NORMAL) return; */ 
    84  
    85         PRINT_DEBUG("    Sending RAM command 0x"); 
    86         PRINT_DEBUG_HEX8(reg); 
    87         PRINT_DEBUG(" to 0x"); 
    88         PRINT_DEBUG_HEX32(0 + addr_offset);     // FIXME 
    89         PRINT_DEBUG("\r\n"); 
    90  
    91         /* Read from (DIMM start address + addr_offset). */ 
    92         read32(0 + addr_offset);        //first offset is always 0 
    93         read32(row_offset + addr_offset); 
     92        reg8 = pci_read_config8(PCI_DEV(0, 0, 0), DRAMT); 
     93        reg8 &= 0x1f;           /* Clear bits 7-5. */ 
     94        reg8 |= command << 5; 
     95        pci_write_config8(PCI_DEV(0, 0, 0), DRAMT, reg8); 
     96 
     97        /* 
     98         * RAM_COMMAND_NORMAL affects only the memory controller and 
     99         * doesn't need to be "sent" to the DIMMs. 
     100         */ 
     101        if (command == RAM_COMMAND_NORMAL) 
     102                return; 
     103 
     104        dimm_start = 0; 
     105        for (i = 0; i < DIMM_SOCKETS; i++) { 
     106                /* 
     107                 * Calculate the address offset where we need to "send" the 
     108                 * DIMM command to. For most commands the offset is 0, only 
     109                 * RAM_COMMAND_MRS needs special values, see below. 
     110                 * The final address offset bits depend on three things: 
     111                 * 
     112                 *  (1) Some hardcoded values specified in the datasheet. 
     113                 *  (2) Which CAS latency we will use/set. This is the SMAA[4] 
     114                 *      bit, which is 1 for CL3, and 0 for CL2. The bitstring 
     115                 *      so far has the form '00000001X1010', X being SMAA[4]. 
     116                 *  (3) The DIMM to which we want to send the command. For 
     117                 *      DIMM0 no special handling is needed, but for DIMM1 we 
     118                 *      must invert the four bits SMAA[7:4] (see datasheet). 
     119                 * 
     120                 * Finally, the bitstring has to be shifted 3 bits to the left. 
     121                 * See i810 datasheet pages 43, 85, and 86 for details. 
     122                 */ 
     123                addr_offset = 0; 
     124                caslatency = 3; /* TODO: Dynamically get CAS latency later. */ 
     125                if (i == 0 && command == RAM_COMMAND_MRS && caslatency == 3) 
     126                        addr_offset = 0x1d0; /* DIMM0, CL3, 0000111010000 */ 
     127                if (i == 1 && command == RAM_COMMAND_MRS && caslatency == 3) 
     128                        addr_offset = 0x650; /* DIMM1, CL3, 0011001010000 */ 
     129                if (i == 0 && command == RAM_COMMAND_MRS && caslatency == 2) 
     130                        addr_offset = 0x150; /* DIMM0, CL2, 0000101010000 */ 
     131                if (i == 1 && command == RAM_COMMAND_MRS && caslatency == 2) 
     132                        addr_offset = 0x1a0; /* DIMM1, CL2, 0000110100000 */ 
     133 
     134                drp = pci_read_config8(PCI_DEV(0, 0, 0), DRP); 
     135                drp = (drp >> (i * 4)) & 0x0f; 
     136 
     137                dimm_size = translate_i82810_to_mb[drp]; 
     138                addr = (dimm_start * 1024 * 1024) + addr_offset; 
     139                if (dimm_size) { 
     140                        PRINT_DEBUG("    Sending RAM command 0x"); 
     141                        PRINT_DEBUG_HEX8(reg8); 
     142                        PRINT_DEBUG(" to 0x"); 
     143                        PRINT_DEBUG_HEX32(addr); 
     144                        PRINT_DEBUG("\r\n"); 
     145 
     146                        read32(addr); 
     147                } 
     148 
     149                dimm_bank = translate_i82810_to_bank[drp]; 
     150                addr = ((dimm_start + dimm_bank) * 1024 * 1024) + addr_offset; 
     151                if (dimm_bank) { 
     152                        PRINT_DEBUG("    Sending RAM command 0x"); 
     153                        PRINT_DEBUG_HEX8(reg8); 
     154                        PRINT_DEBUG(" to 0x"); 
     155                        PRINT_DEBUG_HEX32(addr); 
     156                        PRINT_DEBUG("\r\n"); 
     157 
     158                        read32(addr); 
     159                } 
     160 
     161                dimm_start += dimm_size; 
     162        } 
    94163} 
    95164 
     
    101170 * Set DRP - DRAM Row Population Register (Device 0). 
    102171 */ 
    103 static void spd_set_dram_size(uint32_t row_offset) 
     172static void spd_set_dram_size(void) 
    104173{ 
    105174        /* The variables drp and dimm_size have to be ints since all the 
     
    138207                        } 
    139208 
    140                         /* Set the row offset, in KBytes (should this be 
    141                          * Kbits?). Note that this offset is the start of the 
    142                          * next row. 
    143                          */ 
    144                         row_offset = (dimm_size * 4 * 1024); 
    145  
    146                         /* This is the way I was doing this, it's provided 
    147                          * mainly as an alternative to the "new" way. 
    148                          */ 
    149  
    150 #if 0 
    151                         /* 8MB */ 
    152                         if (dimm_size == 0x2) 
    153                                 dimm_size = 0x1; 
    154                         /* 16MB */ 
    155                         else if (dimm_size == 0x4) 
    156                                 dimm_size = 0x4; 
    157                         /* 32MB */ 
    158                         else if (dimm_size == 0x8) 
    159                                 dimm_size = 0x7; 
    160                         /* 64 MB */ 
    161                         else if (dimm_size == 0x10) 
    162                                 dimm_size = 0xa; 
    163                         /* 128 MB */ 
    164                         else if (dimm_size == 0x20) 
    165                                 dimm_size = 0xd; 
    166                         else 
    167                                 print_debug("Ram Size not supported\r\n"); 
    168 #endif 
    169  
    170209                        /* This array is provided in raminit.h, because it got 
    171210                         * extremely messy. The above way is cleaner, but 
     
    213252/* 
    214253 * TODO: BUFF_SC needs to be set according to the DRAM tech (x8, x16, 
    215  * or x32), but the datasheet doesn't list all the detaisl. Currently, it 
     254 * or x32), but the datasheet doesn't list all the details. Currently, it 
    216255 * needs to be pulled from the output of 'lspci -xxx Rx92'. 
    217256 * 
     
    247286-----------------------------------------------------------------------------*/ 
    248287 
    249 /** 
    250  * TODO. 
    251  */ 
    252288static void sdram_set_registers(void) 
    253289{ 
     
    293329} 
    294330 
    295 /** 
    296  * TODO. 
    297  */ 
    298331static void sdram_set_spd_registers(void) 
    299332{ 
    300         /* spd_set_dram_size() moved into sdram_enable() to prevent having 
    301          * to pass a variable between here and there. 
    302          */ 
     333        spd_set_dram_size(); 
    303334        set_dram_buffer_strength(); 
    304  
    305335        set_dram_timing(); 
    306336} 
     
    313343        int i; 
    314344 
    315         /* Todo: this will currently work with either one dual sided or two 
    316          * single sided DIMMs. Needs to work with 2 dual sided DIMMs in the 
    317          * long run. 
    318          */ 
    319         uint32_t row_offset; 
    320  
    321         spd_set_dram_size(row_offset); 
    322  
    323345        /* 1. Apply NOP. */ 
    324346        PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n"); 
    325         do_ram_command(RAM_COMMAND_NOP, 0, row_offset); 
     347        do_ram_command(RAM_COMMAND_NOP); 
    326348        udelay(200); 
    327349 
    328350        /* 2. Precharge all. Wait tRP. */ 
    329351        PRINT_DEBUG("RAM Enable 2: Precharge all\r\n"); 
    330         do_ram_command(RAM_COMMAND_PRECHARGE, 0, row_offset); 
     352        do_ram_command(RAM_COMMAND_PRECHARGE); 
    331353        udelay(1); 
    332354 
    333355        /* 3. Perform 8 refresh cycles. Wait tRC each time. */ 
    334356        PRINT_DEBUG("RAM Enable 3: CBR\r\n"); 
    335         do_ram_command(RAM_COMMAND_CBR, 0, row_offset); 
    336357        for (i = 0; i < 8; i++) { 
    337                 read32(0); 
    338                 read32(row_offset); 
     358                do_ram_command(RAM_COMMAND_CBR); 
    339359                udelay(1); 
    340360        } 
     
    342362        /* 4. Mode register set. Wait two memory cycles. */ 
    343363        PRINT_DEBUG("RAM Enable 4: Mode register set\r\n"); 
    344         do_ram_command(RAM_COMMAND_MRS, 0x1d0, row_offset); 
     364        do_ram_command(RAM_COMMAND_MRS); 
    345365        udelay(2); 
    346366 
    347367        /* 5. Normal operation (enables refresh) */ 
    348368        PRINT_DEBUG("RAM Enable 5: Normal operation\r\n"); 
    349         do_ram_command(RAM_COMMAND_NORMAL, 0, row_offset); 
     369        do_ram_command(RAM_COMMAND_NORMAL); 
    350370        udelay(1); 
    351371