Author: mjones
Date: 2007-11-03 00:27:12 +0100 (Sat, 03 Nov 2007)
New Revision: 2935

Modified:
   trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/amdk8.h
   trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/raminit.c
Log:
This patch changes the "if else" style of parameter matching to table and also 
changes the rdpreamble parameter, which will cause that more then one DIMM will 
work for 939 motherboard.


Signed-off-by: Rudolf Marek <[EMAIL PROTECTED]>
Acked-by: Jordan Crouse <[EMAIL PROTECTED]>



Modified: trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/amdk8.h
===================================================================
--- trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/amdk8.h 2007-11-02 23:17:57 UTC 
(rev 2934)
+++ trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/amdk8.h 2007-11-02 23:27:12 UTC 
(rev 2935)
@@ -134,7 +134,9 @@
 #define         DCL_D_DRV         (1<<1)
 #define         DCL_QFC_EN        (1<<2)
 #define         DCL_DisDqsHys     (1<<3)
+#define         DCL_Burst2Opt     (1<<5)
 #define         DCL_DramInit      (1<<8)
+#define         DCL_DualDIMMen    (1<<9)
 #define         DCL_DramEnable    (1<<10)
 #define         DCL_MemClrStatus  (1<<11)
 #define         DCL_ESR           (1<<12)
@@ -147,7 +149,8 @@
 #define         DCL_DisInRcvrs    (1<<24)
 #define         DCL_BypMax_SHIFT  25
 #define         DCL_En2T          (1<<28)
-
+#define         DCL_UpperCSMap    (1<<29)
+       
 #define DRAM_CONFIG_HIGH   0x94
 #define         DCH_ASYNC_LAT_SHIFT  0
 #define         DCH_ASYNC_LAT_MASK   0xf

Modified: trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/raminit.c
===================================================================
--- trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/raminit.c       2007-11-02 
23:17:57 UTC (rev 2934)
+++ trunk/LinuxBIOSv2/src/northbridge/amd/amdk8/raminit.c       2007-11-02 
23:27:12 UTC (rev 2935)
@@ -1177,6 +1177,7 @@
        int i;
        int registered;
        int unbuffered;
+       int has_dualch = is_opteron(ctrl);
        uint32_t dcl;
        unbuffered = 0;
        registered = 0;
@@ -1201,17 +1202,22 @@
        if (unbuffered && registered) {
                die("Mixed buffered and registered dimms not supported");
        }
-#if 1
-       // yhlu debug: Athlon64 939 can do dual channel, but it uses unbuffered 
DIMMs
-       if (unbuffered && is_opteron(ctrl)) {
-               die("Unbuffered Dimms not supported on Opteron");
-       }
-#endif
 
        dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
        dcl &= ~DCL_UnBufDimm;
        if (unbuffered) {
-               dcl |= DCL_UnBufDimm;
+               if ((has_dualch) && (!is_cpu_pre_d0())) {
+                       dcl |= DCL_UnBufDimm; /* set DCL_DualDIMMen too? */
+                       
+                       /* set DCL_En2T if you have non-equal DDR mem types! */
+                       
+                       if ((cpuid_eax(1) & 0x30) == 0x30) {
+                               /* CS[7:4] is copy of CS[3:0], should be set 
for 939 socket */
+                               dcl |= DCL_UpperCSMap;
+                       }
+               } else {
+                       dcl |= DCL_UnBufDimm;
+               }
        }
        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
 #if 0
@@ -1333,6 +1339,9 @@
        uint32_t dch_memclk;
        uint16_t dch_tref4k, dch_tref8k;
        uint8_t  dtl_twr;
+       uint8_t  dtl_twtr;
+       uint8_t  dtl_trwt[3][3]; /* first index is CAS_LAT 2/2.5/3 and 
128/registered64/64 */
+       uint8_t  rdpreamble[4]; /* 0 is for registered, 1 for 1-2 DIMMS, 2 and 
3 for 3 or 4 unreg dimm slots */
        char name[9];
 };
 
@@ -1349,6 +1358,9 @@
                        .dch_tref4k = DTH_TREF_100MHZ_4K,
                        .dch_tref8k = DTH_TREF_100MHZ_8K,
                        .dtl_twr    = 2,
+                       .dtl_twtr   = 1,
+                       .dtl_trwt   = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
+                       .rdpreamble = { ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 
1) + 0), ((9 << 1) + 0) }
                },
                {
                        .name       = "133Mhz\r\n",
@@ -1360,6 +1372,9 @@
                        .dch_tref4k = DTH_TREF_133MHZ_4K,
                        .dch_tref8k = DTH_TREF_133MHZ_8K,
                        .dtl_twr    = 2,
+                       .dtl_twtr   = 1,
+                       .dtl_trwt   = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
+                       .rdpreamble = { ((8 << 1) + 0), ((7 << 1) + 0), ((7 << 
1) + 1), ((7 << 1) + 0) }
                },
                {
                        .name       = "166Mhz\r\n",
@@ -1371,6 +1386,9 @@
                        .dch_tref4k = DTH_TREF_166MHZ_4K,
                        .dch_tref8k = DTH_TREF_166MHZ_8K,
                        .dtl_twr    = 3,
+                       .dtl_twtr   = 1,
+                       .dtl_trwt   = { { 3, 2, 3 }, { 3, 3, 4 }, { 4, 3, 4 }},
+                       .rdpreamble = { ((7 << 1) + 1), ((6 << 1) + 0), ((6 << 
1) + 1), ((6 << 1) + 0) }
                },
                {
                        .name       = "200Mhz\r\n",
@@ -1382,6 +1400,9 @@
                        .dch_tref4k = DTH_TREF_200MHZ_4K,
                        .dch_tref8k = DTH_TREF_200MHZ_8K,
                        .dtl_twr    = 3,
+                       .dtl_twtr   = 2,
+                       .dtl_trwt   = { { 0, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
+                       .rdpreamble = { ((7 << 1) + 0), ((5 << 1) + 0), ((5 << 
1) + 1), ((5 << 1) + 1) }
                },
                {
                        .cycle_time = 0x00,
@@ -1423,8 +1444,8 @@
                [NBCAP_MEMCLK_100MHZ] = 0xa0, /* 10ns */
        };
 
-
        value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
+
        min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & 
NBCAP_MEMCLK_MASK];
        bios_cycle_time = min_cycle_times[
                read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 
0)];
@@ -1877,75 +1898,47 @@
 static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param 
*param)
 {
        uint32_t dth;
-       unsigned clocks;
-       clocks = 1; /* AMD says hard code this */
+
        dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
        dth &= ~(DTH_TWTR_MASK << DTH_TWTR_SHIFT);
-       dth |= ((clocks - DTH_TWTR_BASE) << DTH_TWTR_SHIFT);
+       dth |= ((param->dtl_twtr - DTH_TWTR_BASE) << DTH_TWTR_SHIFT);
        pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
 }
 
 static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param 
*param)
 {
        uint32_t dth, dtl;
-       unsigned divisor;
        unsigned latency;
        unsigned clocks;
+       int lat, mtype;
 
        clocks = 0;
        dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
        latency = (dtl >> DTL_TCL_SHIFT) & DTL_TCL_MASK;
-       divisor = param->divisor;
 
        if (is_opteron(ctrl)) {
-               if (latency == DTL_CL_2) {
-                       if (divisor == ((6 << 0) + 0)) {
-                               /* 166Mhz */
-                               clocks = 3;
-                       }
-                       else if (divisor > ((6 << 0)+0)) {
-                               /* 100Mhz && 133Mhz */
-                               clocks = 2;
-                       }
-               }
-               else if (latency == DTL_CL_2_5) {
-                       clocks = 3;
-               }
-               else if (latency == DTL_CL_3) {
-                       if (divisor == ((6 << 0)+0)) {
-                               /* 166Mhz */
-                               clocks = 4;
-                       }
-                       else if (divisor > ((6 << 0)+0)) {
-                               /* 100Mhz && 133Mhz */
-                               clocks = 3;
-                       }
-               }
+               mtype = 0; /* dual channel */
+       } else if (is_registered(ctrl)) {
+               mtype = 1; /* registered 64bit interface */
+       } else {
+               mtype = 2; /* unbuffered 64bit interface */
        }
-       else /* Athlon64 */ {
-               if (is_registered(ctrl)) {
-                       if (latency == DTL_CL_2) {
-                               clocks = 2;
-                       }
-                       else if (latency == DTL_CL_2_5) {
-                               clocks = 3;
-                       }
-                       else if (latency == DTL_CL_3) {
-                               clocks = 3;
-                       }
-               }
-               else /* Unbuffered */{
-                       if (latency == DTL_CL_2) {
-                               clocks = 3;
-                       }
-                       else if (latency == DTL_CL_2_5) {
-                               clocks = 4;
-                       }
-                       else if (latency == DTL_CL_3) {
-                               clocks = 4;
-                       }
-               }
+
+       switch (latency) {
+               case DTL_CL_2:
+                       lat = 0;
+                       break;
+               case DTL_CL_2_5:
+                       lat = 1;
+                       break;
+               case DTL_CL_3:
+                       lat = 2;
+                       break;
+               default:
+                       die("Unknown LAT for Trwt");
        }
+
+       clocks = param->dtl_trwt[lat][mtype];
        if ((clocks < DTH_TRWT_MIN) || (clocks > DTH_TRWT_MAX)) {
                die("Unknown Trwt\r\n");
        }
@@ -1977,83 +1970,38 @@
 static void set_read_preamble(const struct mem_controller *ctrl, const struct 
mem_param *param)
 {
        uint32_t dch;
-       unsigned divisor;
        unsigned rdpreamble;
-       divisor = param->divisor;
-       dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-       dch &= ~(DCH_RDPREAMBLE_MASK << DCH_RDPREAMBLE_SHIFT);
-       rdpreamble = 0;
-       if (is_registered(ctrl)) {
-               if (divisor == ((10 << 1)+0)) {
-                       /* 100Mhz, 9ns */
-                       rdpreamble = ((9 << 1)+ 0);
+       int slots, i;
+
+       slots = 0;
+
+       for(i = 0; i < 4; i++) {
+               if (ctrl->channel0[i]) {
+                       slots += 1;
                }
-               else if (divisor == ((7 << 1)+1)) {
-                       /* 133Mhz, 8ns */
-                       rdpreamble = ((8 << 1)+0);
-               }
-               else if (divisor == ((6 << 1)+0)) {
-                       /* 166Mhz, 7.5ns */
-                       rdpreamble = ((7 << 1)+1);
-               }
-               else if (divisor == ((5 << 1)+0)) {
-                       /* 200Mhz,  7ns */
-                       rdpreamble = ((7 << 1)+0);
-               }
        }
-       else {
-               int slots;
-               int i;
-               slots = 0;
-               for(i = 0; i < 4; i++) {
-                       if (ctrl->channel0[i]) {
-                               slots += 1;
-                       }
-               }
-               if (divisor == ((10 << 1)+0)) {
-                       /* 100Mhz */
-                       if (slots <= 2) {
-                               /* 9ns */
-                               rdpreamble = ((9 << 1)+0);
-                       } else {
-                               /* 14ns */
-                               rdpreamble = ((14 << 1)+0);
-                       }
-               }
-               else if (divisor == ((7 << 1)+1)) {
-                       /* 133Mhz */
-                       if (slots <= 2) {
-                               /* 7ns */
-                               rdpreamble = ((7 << 1)+0);
-                       } else {
-                               /* 11 ns */
-                               rdpreamble = ((11 << 1)+0);
-                       }
-               }
-               else if (divisor == ((6 << 1)+0)) {
-                       /* 166Mhz */
-                       if (slots <= 2) {
-                               /* 6ns */
-                               rdpreamble = ((7 << 1)+0);
-                       } else {
-                               /* 9ns */
-                               rdpreamble = ((9 << 1)+0);
-                       }
-               }
-               else if (divisor == ((5 << 1)+0)) {
-                       /* 200Mhz */
-                       if (slots <= 2) {
-                               /* 5ns */
-                               rdpreamble = ((5 << 1)+0);
-                       } else {
-                               /* 7ns */
-                               rdpreamble = ((7 << 1)+0);
-                       }
-               }
+
+       /* map to index to param.rdpreamble array */
+       if (is_registered(ctrl)) {
+               i = 0;
+       } else if (slots < 3) {
+               i = 1;
+       } else if (slots == 3) {
+               i = 2;
+       } else if (slots == 4) {
+               i = 3;
+       } else {
+               die("Unknown rdpreamble for this nr of slots");
        }
+
+       dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+       dch &= ~(DCH_RDPREAMBLE_MASK << DCH_RDPREAMBLE_SHIFT);
+       rdpreamble = param->rdpreamble[i];
+
        if ((rdpreamble < DCH_RDPREAMBLE_MIN) || (rdpreamble > 
DCH_RDPREAMBLE_MAX)) {
                die("Unknown rdpreamble");
        }
+
        dch |= (rdpreamble - DCH_RDPREAMBLE_BASE) << DCH_RDPREAMBLE_SHIFT;
        pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
 }


-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to