Last week Peter commented that the delay control setting code should be made clearer. Here is what I came up with. I think that it makes more sense now.

Marc

--
Marc Jones
Senior Software Engineer
(970) 226-9684 Office
mailto:[EMAIL PROTECTED]
http://www.amd.com/embeddedprocessors
Rework the Geode delay control setup to table driven and much more readable.

Signed-off-by: Marc Jones <[EMAIL PROTECTED]>


Index: LinuxBIOSv3/arch/x86/geodelx/geodelx.c
===================================================================
--- LinuxBIOSv3.orig/arch/x86/geodelx/geodelx.c 2007-07-03 18:20:19.000000000 
-0600
+++ LinuxBIOSv3/arch/x86/geodelx/geodelx.c      2007-07-03 17:40:27.000000000 
-0600
@@ -247,6 +247,54 @@
        }
 }
 
+
+/**
+ * Delay Control Settings Table from AMD (MCP 0x4C00000F)
+ * DIMMs       devices   Slow (<=333MHz)         Fast (>334MHz)
+ * -----       -------  ----------------------  ----------------------
+ *  1          4                0x83*100FF 0x56960004   0x82*100FF 0x56960004
+ *  1          8                0x83*100AA 0x56960004   0x82*100AA 0x56960004
+ *  1          16               0x83*100AA 0x56960004   0x82*10055 0x56960004
+ *
+ *  2          8                0x837100A5 0x56960004   0x82710000 0x56960004
+ *  2          16               0x937100A5 0x56960004   0xC27100A5 0x56960004
+ *  2          20               0xB37100A5 0x56960004   0xB27100A5 0x56960004
+ *  2          24               0xB37100A5 0x56960004   0xB27100A5 0x56960004
+ *  2          32               0xB37100A5 0x56960004   0xB2710000 0x56960004
+ *
+ * =========================================================================
+ * - Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM
+ *     in slot 0, but it should be clear for all 2 DIMM settings and if a
+ *     single DIMM is in slot 1. Bits 54:52 should always be set to '111'.
+ *
+ * Settings for single DIMM and no VTT termination (Like db800 platform)
+ *   0xF2F100FF 0x56960004
+ * -------------------------------------
+ * ADDR/CTL have 22 ohm series R
+ * DQ/DQM/DQS have 33 ohm series R
+*/
+
+struct delay_controls {
+       u8 dimms;
+       u8 devices;
+       u32 slow_hi;
+       u32 slow_low;
+       u32 fast_hi;
+       u32 fast_low;
+};
+
+const struct delay_controls delay_control_table [] = {
+/* DIMMs       devices Slow (<=333MHz)                         Fast (>334MHz)*/
+{      1,              4,              0x0837100FF, 0x056960004,       
0x0827100FF, 0x056960004},
+{      1,              8,              0x0837100AA, 0x056960004,       
0x0827100AA, 0x056960004},
+{      1,              16,             0x0837100AA, 0x056960004,       
0x082710055, 0x056960004},
+{      2,              8,              0x0837100A5, 0x056960004,       
0x082710000, 0x056960004},
+{      2,              16,             0x0937100A5, 0x056960004,       
0x0C27100A5, 0x056960004},
+{      2,              20,             0x0B37100A5, 0x056960004,       
0x0B27100A5, 0x056960004},
+{      2,              24,             0x0B37100A5, 0x056960004,       
0x0B27100A5, 0x056960004},
+{      2,              32,             0x0B37100A5, 0x056960004,       
0x0B2710000, 0x056960004}
+};
+
 /**
  * set_delay_control. This is Black Magic DRAM timing
  * juju(http://www.thefreedictionary.com/juju) Dram delay depends on
@@ -263,12 +311,10 @@
  * @param dimm1 DIMM 1 SMBus address
  * @param sram_width Data width of the SDRAM
  */
-
 void set_delay_control(u8 dimm0, u8 dimm1)
 {
        u32 msrnum, glspeed;
-       u8 spdbyte0, spdbyte1;
-       int numdimms = 0;
+       u8 spdbyte0, spdbyte1, dimms, i;
        struct msr  msr;
 
        glspeed = geode_link_speed();
@@ -317,7 +363,7 @@
         */
        spdbyte0 = smbus_read_byte(dimm0, SPD_PRIMARY_SDRAM_WIDTH);
        if (spdbyte0 != 0xFF) {
-               numdimms++;
+               dimms++;
                spdbyte0 = (unsigned char)64 / spdbyte0 *
                    (unsigned char)(smbus_read_byte(dimm0, SPD_NUM_DIMM_BANKS));
        } else {
@@ -326,134 +372,32 @@
 
        spdbyte1 = smbus_read_byte(dimm1, SPD_PRIMARY_SDRAM_WIDTH);
        if (spdbyte1 != 0xFF) {
-               numdimms++;
+               dimms++;
                spdbyte1 = (unsigned char)64 / spdbyte1 *
                    (unsigned char)(smbus_read_byte(dimm1, SPD_NUM_DIMM_BANKS));
        } else {
                spdbyte1 = 0;
        }
 
-/* The current thinking. Subject to change...
-
-;                                                                 "FUTURE 
ROBUSTNESS" PROPOSAL
-;                                                                 
----------------------------
-;              DIMM     Max MBUS                                          MC 
0x2000001A bits 26:24
-;DIMMs devices  Frequency       MCP 0x4C00000F Setting          vvv
-;----- -------  ---------       ----------------------  ----------
-;1              4               400MHz          0x82*100FF 0x56960004          
  4
-;1              8               400MHz          0x82*100AA 0x56960004          
  4
-;1              16              400MHz          0x82*10055 0x56960004          
  4
-;
-;2              4,4     400MHz          0x82710000 0x56960004            4
-;2              8,8     400MHz          0xC27100A5 0x56960004            4     
*** OUT OF PUBLISHED ENVELOPE ***
-;
-;2             16,4     >333            0xB27100A5 0x56960004            4     
*** OUT OF PUBLISHED ENVELOPE ***
-;2             16,8     >333            0xB27100A5 0x56960004            4     
*** OUT OF PUBLISHED ENVELOPE ***
-;2             16,16    >333            0xB2710000 0x56960004            4     
*** OUT OF PUBLISHED ENVELOPE ***
-;
-;1              4               <=333MHz        0x83*100FF 0x56960004          
  3
-;1              8               <=333MHz        0x83*100AA 0x56960004          
  3
-;1              16              <=333MHz        0x83*100AA 0x56960004          
  3
-;
-;2              4,4     <=333MHz        0x837100A5 0x56960004            3
-;2              8,8     <=333MHz        0x937100A5 0x56960004            3
-;
-;2             16,4     <=333MHz        0xB37100A5 0x56960004            3     
*** OUT OF PUBLISHED ENVELOPE ***
-;2             16,8     <=333MHz        0xB37100A5 0x56960004            3     
*** OUT OF PUBLISHED ENVELOPE ***
-;2             16,16    <=333MHz        0xB37100A5 0x56960004            3     
*** OUT OF PUBLISHED ENVELOPE ***
-;=========================================================================
-;* - Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM in 
slot 0,
-;       but it should be clear for all 2 DIMM settings and if a single DIMM is 
in slot 1.
-;       Bits 54:52 should always be set to '111'.
-
-;No VTT termination
-;-------------------------------------
-;ADDR/CTL have 22 ohm series R
-;DQ/DQM/DQS have 33 ohm series R
-;
-;              DIMM     Max MBUS
-;DIMMs devices  Frequency       MCP 0x4C00000F Setting
-;----- -------  ---------       ----------------------
-;1              4               400MHz          0xF2F100FF 0x56960004          
  4                     The MC changes improve Salsa.
-;1              8               400MHz          0xF2F100FF 0x56960004          
  4                     Delay controls no real change,
-;1              4               <=333MHz        0xF2F100FF 0x56960004          
  3                     just fixing typo in left side.
-;1              8               <=333MHz        0xF2F100FF 0x56960004          
  3
-;1              16              <=333MHz        0xF2F100FF 0x56960004          
  3
-*/
+       /* zero GLCP_DELAY_CONTROLS MSR */
        msr.hi = msr.lo = 0;
 
-       if (spdbyte0 == 0 || spdbyte1 == 0) {
-               /* one dimm solution */
-               if (spdbyte1 == 0) {
-                       msr.hi |= 0x000800000;
-               }
-               spdbyte0 += spdbyte1;
-               if (spdbyte0 > 8) {
-                       /* large dimm */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0837100AA;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x082710055;
-                               msr.lo |= 0x056960004;
-                       }
-               } else if (spdbyte0 > 4) {
-                       /* medium dimm */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0837100AA;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x0827100AA;
-                               msr.lo |= 0x056960004;
-                       }
-               } else {
-                       /* small dimm */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0837100FF;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x0827100FF;
-                               msr.lo |= 0x056960004;
-                       }
-               }
-       } else {
-               /* two dimm solution */
-               spdbyte0 += spdbyte1;
-               if (spdbyte0 > 24) {
-                       /* huge dimms */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0B37100A5;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x0B2710000;
-                               msr.lo |= 0x056960004;
-                       }
-               } else if (spdbyte0 > 16) {
-                       /* large dimms */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0B37100A5;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x0B27100A5;
-                               msr.lo |= 0x056960004;
-                       }
-               } else if (spdbyte0 >= 8) {
-                       /* medium dimms */
-                       if (glspeed < 334) {
-                               msr.hi |= 0x0937100A5;
-                               msr.lo |= 0x056960004;
-                       } else {
-                               msr.hi |= 0x0C27100A5;
-                               msr.lo |= 0x056960004;
-                       }
-               } else {
-                       /* small dimms */
+       /* save some power, disable clock to second DIMM if it is empty */
+       if (spdbyte1 == 0) {
+               msr.hi |= 0x000800000;
+       }
+
+       spdbyte0 += spdbyte1;
+
+       for(i = 0; i < ARRAY_SIZE(delay_control_table); i++){
+               if((dimms == delay_control_table[i].dimms) &&
+                               (spdbyte0 <= delay_control_table[i].devices)) {
                        if (glspeed < 334) {
-                               msr.hi |= 0x0837100A5;
-                               msr.lo |= 0x056960004;
+                               msr.hi |= delay_control_table[i].slow_hi;
+                               msr.lo |= delay_control_table[i].slow_low;
                        } else {
-                               msr.hi |= 0x082710000;
-                               msr.lo |= 0x056960004;
+                               msr.hi |= delay_control_table[i].fast_hi;
+                               msr.lo |= delay_control_table[i].fast_low;
                        }
                }
        }
-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to