Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Add a warning about false negatives in the DIMM dual channel compatibility check. This needs to be implemented correctly.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c =================================================================== --- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Revision 3850) +++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Arbeitskopie) @@ -34,34 +34,20 @@ #define QRANK_DIMM_SUPPORT 0 #endif
-static inline void print_raminit(const char *strval, uint32_t val) -{ #if CONFIG_USE_PRINTK_IN_CAR - printk_debug("%s%08x\r\n", strval, val); #else - print_debug(strval); print_debug_hex32(val); print_debug("\r\n"); +#error This file needs CONFIG_USE_PRINTK_IN_CAR #endif -}
-#define RAM_TIMING_DEBUG 0 +#define RAM_TIMING_DEBUG 1
-static inline void print_tx(const char *strval, uint32_t val) -{ #if RAM_TIMING_DEBUG == 1 - print_raminit(strval, val); +#define printk_raminit printk_debug +#else +#define printk_raminit(fmt, arg...) do {} while(0) #endif -}
-static inline void print_t(const char *strval) -{ -#if RAM_TIMING_DEBUG == 1 - print_debug(strval); -#endif -} - - - #if (CONFIG_LB_MEM_TOPK & (CONFIG_LB_MEM_TOPK -1)) != 0 # error "CONFIG_LB_MEM_TOPK must be a power of 2" #endif @@ -713,9 +699,7 @@ } sysinfo->ctrl_present[ctrl->node_id] = 1;
- print_spew("setting up CPU"); - print_spew_hex8(ctrl->node_id); - print_spew(" northbridge registers\r\n"); + printk_spew("setting up CPU %02x northbridge registers\n", ctrl->node_id); max = ARRAY_SIZE(register_values); for (i = 0; i < max; i += 3) { device_t dev; @@ -729,7 +713,7 @@ pci_write_config32(dev, where, reg); }
- print_spew("done.\r\n"); + printk_spew("done.\n"); }
@@ -829,14 +813,14 @@ if (value <=4 ) value += 8; // add back to 1G to high value += (27-5); // make 128MB to the real lines if ( value != (sz->per_rank)) { - print_err("Bad RANK Size --\r\n"); + printk_err("Bad RANK Size --\n"); goto val_err; }
goto out;
val_err: - die("Bad SPD value\r\n"); + die("Bad SPD value\n"); /* If an hw_error occurs report that I have no memory */ hw_err: sz->per_rank = 0; @@ -1070,9 +1054,7 @@ }
/* Report the amount of memory. */ - print_debug("RAM: 0x"); - print_debug_hex32(tom_k); - print_debug(" KB\r\n"); + printk_debug("RAM: 0x%08x kB\n", tom_k);
msr_t msr; if (tom_k > (4*1024*1024)) { @@ -1202,7 +1184,7 @@ csbase += csbase_inc; }
- print_debug("Interleaved\r\n"); + printk_debug("Interleaved\n");
/* Return the memory size in K */ return common_size << ((27-10) + bits); @@ -1306,7 +1288,7 @@ CMOS_VLEN_interleave_chip_selects, 1) != 0) { tom_k = interleave_chip_selects(ctrl, meminfo->is_Width128); } else { - print_debug("Interleaving disabled\r\n"); + printk_debug("Interleaving disabled\n"); tom_k = 0; } @@ -1325,9 +1307,7 @@ static long disable_dimm(const struct mem_controller *ctrl, unsigned index, struct mem_info *meminfo) { - print_debug("disabling dimm"); - print_debug_hex8(index); - print_debug("\r\n"); + printk_debug("disabling dimm %02x\n", index); if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */ pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), 0); pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), 0); @@ -1402,9 +1382,9 @@
#if 1 if (meminfo->is_registered) { - print_debug("Registered\r\n"); + printk_debug("Registered\n"); } else { - print_debug("Unbuffered\r\n"); + printk_debug("Unbuffered\n"); } #endif return meminfo->dimm_mask; @@ -1448,15 +1428,11 @@ 4, /* *Column addresses */ 5, /* *Number of DIMM Ranks */ 6, /* *Module Data Width*/ - 9, /* *Cycle time at highest CAS Latency CL=X */ 11, /* *DIMM Conf Type */ 13, /* *Pri SDRAM Width */ 17, /* *Logical Banks */ - 18, /* *Supported CAS Latencies */ 20, /* *DIMM Type Info */ 21, /* *SDRAM Module Attributes */ - 23, /* *Cycle time at CAS Latnecy (CLX - 1) */ - 26, /* *Cycle time at CAS Latnecy (CLX - 2) */ 27, /* *tRP Row precharge time */ 28, /* *Minimum Row Active to Row Active Delay (tRRD) */ 29, /* *tRCD RAS to CAS */ @@ -1464,11 +1440,18 @@ 36, /* *Write recovery time (tWR) */ 37, /* *Internal write to read command delay (tRDP) */ 38, /* *Internal read to precharge commanfd delay (tRTP) */ +#warning Why is SPD address 41 checked twice? 41, /* *Extension of Byte 41 tRC and Byte 42 tRFC */ 41, /* *Minimum Active to Active/Auto Refresh Time(Trc) */ 42, /* *Minimum Auto Refresh Command Time(Trfc) */ +#warning The SPD addresses below need special treatment like in spd_set_memclk. Right now they cause many false negatives. + 18, /* *Supported CAS Latencies */ + 9, /* *Cycle time at highest CAS Latency CL=X */ + 23, /* *Cycle time at CAS Latency (CLX - 1) */ + 26, /* *Cycle time at CAS Latency (CLX - 2) */ }; u32 dcl, dcm; + u8 common_cl;
/* S1G1 and AM2 sockets are Mod64BitMux capable. */ #if CPU_SOCKET_TYPE == 0x11 || CPU_SOCKET_TYPE == 0x12 @@ -1497,6 +1480,14 @@ } device0 = ctrl->channel0[i]; device1 = ctrl->channel1[i]; + /* Abort if the chips don't support a common CAS latency. */ + common_cl = spd_read_byte(device0, 18) & spd_read_byte(device1, 18); + if (!common_cl) { + printk_debug("No common CAS latency supported\n"); + goto single_channel; + } else { + printk_raminit("Common CAS latency bitfield: 0x%02x\n", common_cl); + } for (j = 0; j < ARRAY_SIZE(addresses); j++) { unsigned addr; addr = addresses[j]; @@ -1509,11 +1500,12 @@ return -1; } if (value0 != value1) { + printk_raminit("SPD values differ between channel 0/1 for byte %i\n", addr); goto single_channel; } } } - print_spew("Enabling dual channel memory\r\n"); + printk_spew("Enabling dual channel memory\n"); dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW); dcl &= ~DCL_BurstLength32; /* 32byte mode may be preferred in platforms that include graphics controllers that generate a lot of 32-bytes system memory accesses 32byte mode is not supported when the DRAM interface is 128 bits wides, even 32byte mode is set, system still use 64 byte mode */ @@ -1566,7 +1558,7 @@
static const struct mem_param speed[] = { { - .name = "200Mhz\r\n", + .name = "200Mhz\n", .cycle_time = 0x500, .divisor = 200, // how many 1/40ns per clock .dch_memclk = DCH_MemClkFreq_200MHz, //0 @@ -1578,7 +1570,7 @@
}, { - .name = "266Mhz\r\n", + .name = "266Mhz\n", .cycle_time = 0x375, .divisor = 150, //???? .dch_memclk = DCH_MemClkFreq_266MHz, //1 @@ -1589,7 +1581,7 @@ .DcqByPassMax = 4, }, { - .name = "333Mhz\r\n", + .name = "333Mhz\n", .cycle_time = 0x300, .divisor = 120, .dch_memclk = DCH_MemClkFreq_333MHz, //2 @@ -1601,7 +1593,7 @@
}, { - .name = "400Mhz\r\n", + .name = "400Mhz\n", .cycle_time = 0x250, .divisor = 100, .dch_memclk = DCH_MemClkFreq_400MHz,//3 @@ -1628,9 +1620,10 @@ if (!param->cycle_time) { die("min_cycle_time to low"); } - print_spew(param->name); #ifdef DRAM_MIN_CYCLE_TIME - print_debug(param->name); + printk_debug(param->name); +#else + printk_spew(param->name); #endif return param; } @@ -1722,7 +1715,7 @@ } min_latency = 3;
- print_tx("1 min_cycle_time:", min_cycle_time); + printk_raminit("1 min_cycle_time: %08x\n", min_cycle_time);
/* Compute the least latency with the fastest clock supported * by both the memory controller and the dimms. @@ -1734,7 +1727,7 @@ int latency; u32 spd_device = ctrl->channel0[i];
- print_tx("1.1 dimm_mask:", meminfo->dimm_mask); + printk_raminit("1.1 dimm_mask: %08x\n", meminfo->dimm_mask); if (!(meminfo->dimm_mask & (1 << i))) { if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */ spd_device = ctrl->channel1[i]; @@ -1756,8 +1749,8 @@ latencies = spd_read_byte(spd_device, SPD_CAS_LAT); if (latencies <= 0) continue;
- print_tx("i:",i); - print_tx("\tlatencies:", latencies); + printk_raminit("i: %08x\n",i); + printk_raminit("\tlatencies: %08x\n", latencies); /* Compute the lowest cas latency supported */ latency = log2(latencies) - 2;
@@ -1773,15 +1766,15 @@ goto hw_error; }
- print_tx("\tindex:", index); - print_tx("\t\tlatency:", latency); - print_tx("\t\tvalue1:", value); + printk_raminit("\tindex: %08x\n", index); + printk_raminit("\t\tlatency: %08x\n", latency); + printk_raminit("\t\tvalue1: %08x\n", value);
value = convert_to_linear(value);
- print_tx("\t\tvalue2:", value); + printk_raminit("\t\tvalue2: %08x\n", value);
- /* Only increase the latency if we decreas the clock */ + /* Only increase the latency if we decrease the clock */ if (value >= min_cycle_time ) { if (value < new_cycle_time) { new_cycle_time = value; @@ -1792,8 +1785,8 @@ } } } - print_tx("\t\tnew_cycle_time:", new_cycle_time); - print_tx("\t\tnew_latency:", new_latency); + printk_raminit("\t\tnew_cycle_time: %08x\n", new_cycle_time); + printk_raminit("\t\tnew_latency: %08x\n", new_latency);
}
@@ -1811,15 +1804,15 @@ min_latency = new_latency; }
- print_tx("2 min_cycle_time:", min_cycle_time); - print_tx("2 min_latency:", min_latency); + printk_raminit("2 min_cycle_time: %08x\n", min_cycle_time); + printk_raminit("2 min_latency: %08x\n", min_latency); } /* Make a second pass through the dimms and disable * any that cannot support the selected memclk and cas latency. */
- print_tx("3 min_cycle_time:", min_cycle_time); - print_tx("3 min_latency:", min_latency); + printk_raminit("3 min_cycle_time: %08x\n", min_cycle_time); + printk_raminit("3 min_latency: %08x\n", min_latency);
for (i = 0; (i < DIMM_SOCKETS); i++) { int latencies; @@ -1874,7 +1867,7 @@ meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo); }
- print_tx("4 min_cycle_time:", min_cycle_time); + printk_raminit("4 min_cycle_time: %08x\n", min_cycle_time);
/* Now that I know the minimum cycle time lookup the memory parameters */ result.param = get_mem_param(min_cycle_time); @@ -1886,7 +1879,7 @@ value |= result.param->dch_memclk << DCH_MemClkFreq_SHIFT; pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
- print_debug(result.param->name); + printk_debug(result.param->name);
/* Update DRAM Timing Low with our selected cas latency */ value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW); @@ -2054,16 +2047,16 @@
value = spd_read_byte(spd_device, SPD_TRAS); //in 1 ns if (value < 0) return -1; - print_tx("update_dimm_Tras: 0 value=", value); + printk_raminit("update_dimm_Tras: 0 value= %08x\n", value);
value <<= 2; //convert it to in 1/4ns
value *= 10; - print_tx("update_dimm_Tras: 1 value=", value); + printk_raminit("update_dimm_Tras: 1 value= %08x\n", value);
clocks = (value + param->divisor - 1)/param->divisor; - print_tx("update_dimm_Tras: divisor=", param->divisor); - print_tx("update_dimm_Tras: clocks=", clocks); + printk_raminit("update_dimm_Tras: divisor= %08x\n", param->divisor); + printk_raminit("update_dimm_Tras: clocks= %08x\n", clocks); if (clocks < DTL_TRAS_MIN) { clocks = DTL_TRAS_MIN; } @@ -2366,8 +2359,8 @@ uint32_t reg;
if ((val < TT_MIN) || (val > TT_MAX)) { - print_err(str); - die(" Unknown\r\n"); + printk_err(str); + die(" Unknown\n"); }
reg = pci_read_config32(ctrl->f2, TT_REG); @@ -2610,12 +2603,12 @@ break; }
- print_raminit("\tdimm_mask = ", meminfo->dimm_mask); - print_raminit("\tx4_mask = ", meminfo->x4_mask); - print_raminit("\tx16_mask = ", meminfo->x16_mask); - print_raminit("\tsingle_rank_mask = ", meminfo->single_rank_mask); - print_raminit("\tODC = ", dword); - print_raminit("\tAddr Timing= ", dwordx); + printk_raminit("\tdimm_mask = %08x\n", meminfo->dimm_mask); + printk_raminit("\tx4_mask = %08x\n", meminfo->x4_mask); + printk_raminit("\tx16_mask = %08x\n", meminfo->x16_mask); + printk_raminit("\tsingle_rank_mask = %08x\n", meminfo->single_rank_mask); + printk_raminit("\tODC = %08x\n", dword); + printk_raminit("\tAddr Timing= %08x\n", dwordx); #endif
#if (DIMM_SUPPORT & 0x0100)==0x0000 /* 2T mode only used for unbuffered DIMM */ @@ -2697,37 +2690,37 @@ !(meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) ) { continue; } - print_tx("spd_set_dram_timing dimm socket: ", i); + printk_raminit("spd_set_dram_timing dimm socket: %08x\n", i); /* DRAM Timing Low Register */ - print_t("\ttrc\r\n"); + printk_raminit("\ttrc\n"); if ((rc = update_dimm_Trc (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrcd\r\n"); + printk_raminit("\ttrcd\n"); if ((rc = update_dimm_Trcd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrrd\r\n"); + printk_raminit("\ttrrd\n"); if ((rc = update_dimm_Trrd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttras\r\n"); + printk_raminit("\ttras\n"); if ((rc = update_dimm_Tras(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrp\r\n"); + printk_raminit("\ttrp\n"); if ((rc = update_dimm_Trp (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrtp\r\n"); + printk_raminit("\ttrtp\n"); if ((rc = update_dimm_Trtp(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
- print_t("\ttwr\r\n"); + printk_raminit("\ttwr\n"); if ((rc = update_dimm_Twr (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
/* DRAM Timing High Register */ - print_t("\ttref\r\n"); + printk_raminit("\ttref\n"); if ((rc = update_dimm_Tref(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttwtr\r\n"); + printk_raminit("\ttwtr\n"); if ((rc = update_dimm_Twtr(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrfc\r\n"); + printk_raminit("\ttrfc\n"); if ((rc = update_dimm_Trfc(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
/* DRAM Config Low */ @@ -2784,37 +2777,37 @@ #endif meminfo = &sysinfo->meminfo[ctrl->node_id];
- print_debug_addr("sdram_set_spd_registers: paramx :", ¶mx); + printk_debug("sdram_set_spd_registers: paramx :%p\n", ¶mx);
activate_spd_rom(ctrl); meminfo->dimm_mask = spd_detect_dimms(ctrl);
- print_tx("sdram_set_spd_registers: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("sdram_set_spd_registers: dimm_mask=0x%x\n", meminfo->dimm_mask);
if (!(meminfo->dimm_mask & ((1 << 2*DIMM_SOCKETS) - 1))) { - print_debug("No memory for this cpu\r\n"); + printk_debug("No memory for this cpu\n"); return; } meminfo->dimm_mask = spd_enable_2channels(ctrl, meminfo); - print_tx("spd_enable_2channels: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_enable_2channels: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
meminfo->dimm_mask = spd_set_ram_size(ctrl, meminfo); - print_tx("spd_set_ram_size: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_ram_size: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
meminfo->dimm_mask = spd_handle_unbuffered_dimms(ctrl, meminfo); - print_tx("spd_handle_unbuffered_dimms: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_handle_unbuffered_dimms: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
result = spd_set_memclk(ctrl, meminfo); param = result.param; meminfo->dimm_mask = result.dimm_mask; - print_tx("spd_set_memclk: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_memclk: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
@@ -2826,7 +2819,7 @@ paramx.divisor = get_exact_divisor(param->dch_memclk, paramx.divisor);
meminfo->dimm_mask = spd_set_dram_timing(ctrl, ¶mx, meminfo); - print_tx("spd_set_dram_timing: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_dram_timing: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
@@ -2961,13 +2954,13 @@ /* FIXME: How about 32 node machine later? */ tsc_t tsc, tsc0[8];
- print_debug_addr("sdram_enable: tsc0[8]: ", &tsc0[0]); + printk_debug("sdram_enable: tsc0[8]: %p", &tsc0[0]); #endif uint32_t dword;
/* Error if I don't have memory */ if (memory_end_k(ctrl, controllers) == 0) { - die("No memory\r\n"); + die("No memory\n"); }
/* Before enabling memory start the memory clocks */ @@ -2993,12 +2986,12 @@ /* We need to wait a mimmium of 20 MEMCLKS to enable the InitDram */ memreset(controllers, ctrl); #if 0 - print_debug("prepare to InitDram:"); + printk_debug("prepare to InitDram:"); for (i=0; i<10; i++) { - print_debug_hex32(i); + printk_debug("%08x", i); print_debug("\b\b\b\b\b\b\b\b"); } - print_debug("\r\n"); + printk_debug("\n"); #endif
for (i = 0; i < controllers; i++) { @@ -3015,7 +3008,7 @@ dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW); if (dcl & DCL_DimmEccEn) { uint32_t mnc; - print_spew("ECC enabled\r\n"); + printk_spew("ECC enabled\n"); mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG); mnc |= MNC_ECC_EN; if (dcl & DCL_Width128) { @@ -3057,17 +3050,17 @@ /* Skip everything if I don't have any memory on this controller */ if (sysinfo->meminfo[i].dimm_mask==0x00) continue;
- print_debug("Initializing memory: "); + printk_debug("Initializing memory: "); int loops = 0; do { dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW); loops++; if ((loops & 1023) == 0) { - print_debug("."); + printk_debug("."); } } while(((dcl & DCL_InitDram) != 0) && (loops < TIMEOUT_LOOPS)); if (loops >= TIMEOUT_LOOPS) { - print_debug(" failed\r\n"); + printk_debug(" failed\n"); continue; }
@@ -3080,7 +3073,7 @@ if (cpu_f0_f1[i]) { tsc= rdtsc();
- print_debug_dqs_tsc("\r\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2); + print_debug_dqs_tsc("\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2); print_debug_dqs_tsc("end tsc ", i, tsc.hi, tsc.lo, 2);
if (tsc.lo<tsc0[i].lo) { @@ -3095,7 +3088,7 @@ print_debug_dqs_tsc(" dtsc0", i, tsc0[i].hi, tsc0[i].lo, 2); } #endif - print_debug(" done\r\n"); + printk_debug(" done\n"); }
#if HW_MEM_HOLE_SIZEK != 0 Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f_dqs.c =================================================================== --- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f_dqs.c (Revision 3850) +++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f_dqs.c (Arbeitskopie) @@ -21,15 +21,16 @@ //0: mean no debug info #define DQS_TRAIN_DEBUG 0
+#if CONFIG_USE_PRINTK_IN_CAR +#else +#error This file needs CONFIG_USE_PRINTK_IN_CAR +#endif + static inline void print_debug_dqs(const char *str, unsigned val, unsigned level) { #if DQS_TRAIN_DEBUG > 0 if(DQS_TRAIN_DEBUG > level) { - #if CONFIG_USE_PRINTK_IN_CAR printk_debug("%s%x\r\n", str, val); - #else - print_debug(str); print_debug_hex32(val); print_debug("\r\n"); - #endif } #endif } @@ -38,11 +39,7 @@ { #if DQS_TRAIN_DEBUG > 0 if(DQS_TRAIN_DEBUG > level) { - #if CONFIG_USE_PRINTK_IN_CAR printk_debug("%s%08x%s%08x\r\n", str, val, str2, val2); - #else - print_debug(str); print_debug_hex32(val); print_debug(str2); print_debug_hex32(val2); print_debug("\r\n"); - #endif } #endif } @@ -51,22 +48,14 @@ { #if DQS_TRAIN_DEBUG > 0 if(DQS_TRAIN_DEBUG > level) { - #if CONFIG_USE_PRINTK_IN_CAR printk_debug("%s[%02x]=%08x%08x\r\n", str, i, val, val2); - #else - print_debug(str); print_debug("["); print_debug_hex8(i); print_debug("]="); print_debug_hex32(val); print_debug_hex32(val2); print_debug("\r\n"); - #endif } #endif }
static inline void print_debug_dqs_tsc_x(const char *str, unsigned i, unsigned val, unsigned val2) { - #if CONFIG_USE_PRINTK_IN_CAR printk_debug("%s[%02x]=%08x%08x\r\n", str, i, val, val2); - #else - print_debug(str); print_debug("["); print_debug_hex8(i); print_debug("]="); print_debug_hex32(val); print_debug_hex32(val2); print_debug("\r\n"); - #endif
}
@@ -855,11 +844,7 @@
#if MEM_TRAIN_SEQ != 1 /* We need tidy output for type 1 */ - #if CONFIG_USE_PRINTK_IN_CAR - printk_debug(" CTLRMaxDelay=%02x", CTLRMaxDelay); - #else - print_debug(" CTLRMaxDelay="); print_debug_hex8(CTLRMaxDelay); - #endif + printk_debug(" CTLRMaxDelay=%02x\n", CTLRMaxDelay); #endif
return (CTLRMaxDelay==0xae)?1:0; @@ -1135,7 +1120,7 @@
print_debug_dqs("\t\t\tTrainDQSPos begin ", 0, 3);
- print_debug_addr("TrainDQSPos: MutualCSPassW[48] :", MutualCSPassW); + printk_debug("TrainDQSPos: MutualCSPassW[48] :%p\n", MutualCSPassW);
for(DQSDelay=0; DQSDelay<48; DQSDelay++) { MutualCSPassW[DQSDelay] = 0xff; // Bitmapped status per delay setting, 0xff=All positions passing (1= PASS) @@ -1408,7 +1393,7 @@
print_debug_dqs("\r\nTrainDQSRdWrPos: 0 ctrl ", ctrl->node_id, 0);
- print_debug_addr("TrainDQSRdWrPos: buf_a:", buf_a); + printk_debug("TrainDQSRdWrPos: buf_a:%p\n", buf_a);
Errors = 0; channel = 0; @@ -1542,7 +1527,7 @@ { print_debug_dqs("\r\ntrain_DqsPos: begin ctrl ", ctrl->node_id, 0); if(TrainDQSRdWrPos(ctrl, sysinfo) != 0) { - print_err("\r\nDQS Training Rd Wr failed ctrl"); print_err_hex8(ctrl->node_id); print_err("\r\n"); + printk_err("\r\nDQS Training Rd Wr failed ctrl%02x\r\n", ctrl->node_id); return 1; } else { @@ -1705,19 +1690,11 @@ } sizek = 1 << align; #if MEM_TRAIN_SEQ != 1 - #if CONFIG_USE_PRINTK_IN_CAR printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type %s\r\n", reg, range_startk >>10, sizek >> 10, (type==MTRR_TYPE_UNCACHEABLE)?"UC": ((type==MTRR_TYPE_WRBACK)?"WB":"Other") ); - #else - print_debug("Setting variable MTRR "); print_debug_hex8(reg); print_debug(", base: "); print_debug_hex16(range_startk>>10); - print_debug("MB, range: "); print_debug_hex16(sizek >> 10); print_debug("MB, type "); - print_debug( (type==MTRR_TYPE_UNCACHEABLE)?"UC\r\n": - ((type==MTRR_TYPE_WRBACK)?"WB\r\n":"Other\r\n") - ); - #endif #endif set_var_mtrr_dqs(reg++, range_startk, sizek, type, address_bits); range_startk += sizek; @@ -1866,10 +1843,9 @@ /* Skip everything if I don't have any memory on this controller */ if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
- print_debug("DQS Training:RcvrEn:Pass1: "); - print_debug_hex8(i); + printk_debug("DQS Training:RcvrEn:Pass1: %02x\n", i); if(train_DqsRcvrEn(ctrl+i, 1, sysinfo)) goto out; - print_debug(" done\r\n"); + printk_debug(" done\r\n"); }
tsc[1] = rdtsc(); @@ -1885,10 +1861,9 @@ /* Skip everything if I don't have any memory on this controller */ if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
- print_debug("DQS Training:DQSPos: "); - print_debug_hex8(i); + printk_debug("DQS Training:DQSPos: %02x\n", i); if(train_DqsPos(ctrl+i, sysinfo)) goto out; - print_debug(" done\r\n"); + printk_debug(" done\r\n"); }
tsc[3] = rdtsc(); @@ -1899,10 +1874,9 @@ /* Skip everything if I don't have any memory on this controller */ if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
- print_debug("DQS Training:RcvrEn:Pass2: "); - print_debug_hex8(i); + printk_debug("DQS Training:RcvrEn:Pass2: %02x\n", i); if(train_DqsRcvrEn(ctrl+i, 2, sysinfo)) goto out; - print_debug(" done\r\n"); + printk_debug(" done\r\n"); sysinfo->mem_trained[i]=1; }
@@ -1943,8 +1917,7 @@ if(v) { tsc[0] = rdtsc();
- print_debug("set DQS timing:RcvrEn:Pass1: "); - print_debug_hex8(i); + printk_debug("set DQS timing:RcvrEn:Pass1: %02x\n", i); } if(train_DqsRcvrEn(ctrl, 1, sysinfo)) { sysinfo->mem_trained[i]=0x81; // @@ -1952,10 +1925,9 @@ }
if(v) { - print_debug(" done\r\n"); + printk_debug(" done\r\n"); tsc[1] = rdtsc(); - print_debug("set DQS timing:DQSPos: "); - print_debug_hex8(i); + printk_debug("set DQS timing:DQSPos: %02x\n", i); }
if(train_DqsPos(ctrl, sysinfo)) { @@ -1964,11 +1936,10 @@ }
if(v) { - print_debug(" done\r\n"); + printk_debug(" done\r\n"); tsc[2] = rdtsc();
- print_debug("set DQS timing:RcvrEn:Pass2: "); - print_debug_hex8(i); + printk_debug("set DQS timing:RcvrEn:Pass2: %02x\n", i); } if(train_DqsRcvrEn(ctrl, 2, sysinfo)){ sysinfo->mem_trained[i]=0x83; // @@ -1976,7 +1947,7 @@ }
if(v) { - print_debug(" done\r\n"); + printk_debug(" done\r\n");
tsc[3] = rdtsc(); } @@ -2027,7 +1998,7 @@ #endif set_top_mem_ap(sysinfo->tom_k, sysinfo->tom2_k); // keep the ap's tom consistent with bsp's #if CONFIG_AP_CODE_IN_CAR == 0 - print_debug("CODE IN ROM AND RUN ON NODE:"); print_debug_hex8(nodeid); print_debug("\r\n"); + printk_debug("CODE IN ROM AND RUN ON NODE: %02x\n", nodeid); train_ram(nodeid, sysinfo, sysinfox); #else /* Can copy dqs_timing to ap cache and run from cache?
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Carl-Daniel Hailfinger Sent: Wednesday, January 14, 2009 11:32 PM To: Coreboot Subject: [coreboot] [PATCH] Convert print_* to printk_* in K8 RAM init
Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Add a warning about false negatives in the DIMM dual channel compatibility check. This needs to be implemented correctly.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c
--- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Revision 3850) +++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Arbeitskopie) @@ -34,34 +34,20 @@ #define QRANK_DIMM_SUPPORT 0 #endif
-static inline void print_raminit(const char *strval, uint32_t val) -{ #if CONFIG_USE_PRINTK_IN_CAR
- printk_debug("%s%08x\r\n", strval, val);
#else
- print_debug(strval); print_debug_hex32(val); print_debug("\r\n");
+#error This file needs CONFIG_USE_PRINTK_IN_CAR #endif -}
-#define RAM_TIMING_DEBUG 0 +#define RAM_TIMING_DEBUG 1
Do we really want to always debug RAM timing?
-static inline void print_tx(const char *strval, uint32_t val) -{ #if RAM_TIMING_DEBUG == 1
- print_raminit(strval, val);
+#define printk_raminit printk_debug +#else +#define printk_raminit(fmt, arg...) do {} while(0)
Why is the do{} while (0) needed here?
4, /* *Column addresses */ 5, /* *Number of DIMM Ranks */ 6, /* *Module Data Width*/
11, /* *DIMM Conf Type */ 13, /* *Pri SDRAM Width */ 17, /* *Logical Banks */9, /* *Cycle time at highest CAS Latency CL=X */
20, /* *DIMM Type Info */ 21, /* *SDRAM Module Attributes */18, /* *Supported CAS Latencies */
23, /* *Cycle time at CAS Latnecy (CLX - 1) */
27, /* *tRP Row precharge time */ 28, /* *Minimum Row Active to Row Active Delay (tRRD) */ 29, /* *tRCD RAS to CAS */26, /* *Cycle time at CAS Latnecy (CLX - 2) */
@@ -1464,11 +1440,18 @@ 36, /* *Write recovery time (tWR) */ 37, /* *Internal write to read command delay (tRDP) */ 38, /* *Internal read to precharge commanfd delay (tRTP)
*/
+#warning Why is SPD address 41 checked twice? 41, /* *Extension of Byte 41 tRC and Byte 42 tRFC */ 41, /* *Minimum Active to Active/Auto Refresh Time(Trc)
*/
42, /* *Minimum Auto Refresh Command Time(Trfc) */
+#warning The SPD addresses below need special treatment like in spd_set_memclk. Right now they cause many false negatives.
18, /* *Supported CAS Latencies */
9, /* *Cycle time at highest CAS Latency CL=X */
23, /* *Cycle time at CAS Latency (CLX - 1) */
26, /* *Cycle time at CAS Latency (CLX - 2) */
I guess I'd rather leave them in order and add their numbers to the warning message.
}; u32 dcl, dcm;
- u8 common_cl;
/* S1G1 and AM2 sockets are Mod64BitMux capable. */ #if CPU_SOCKET_TYPE == 0x11 || CPU_SOCKET_TYPE == 0x12 @@ -1497,6 +1480,14 @@ } device0 = ctrl->channel0[i]; device1 = ctrl->channel1[i];
/* Abort if the chips don't support a common CAS latency. */
common_cl = spd_read_byte(device0, 18) &
spd_read_byte(device1, 18);
if (!common_cl) {
printk_debug("No common CAS latency supported\n");
goto single_channel;
} else {
printk_raminit("Common CAS latency bitfield:
0x%02x\n",
common_cl);
}
I didn't see this part in the summary of the patch.
if (!param->cycle_time) { die("min_cycle_time to low"); }
- print_spew(param->name);
#ifdef DRAM_MIN_CYCLE_TIME
- print_debug(param->name);
- printk_debug(param->name);
It seems like you could get rid of this ifdef and just make it printk_debug or printk_raminit.
Thanks, Myles
On 15.01.2009 15:22, Myles Watson wrote:
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Carl-Daniel Hailfinger Sent: Wednesday, January 14, 2009 11:32 PM To: Coreboot Subject: [coreboot] [PATCH] Convert print_* to printk_* in K8 RAM init
Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Add a warning about false negatives in the DIMM dual channel compatibility check. This needs to be implemented correctly.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c
--- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Revision 3850) +++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Arbeitskopie) @@ -34,34 +34,20 @@ #define QRANK_DIMM_SUPPORT 0 #endif
-static inline void print_raminit(const char *strval, uint32_t val) -{ #if CONFIG_USE_PRINTK_IN_CAR
- printk_debug("%s%08x\r\n", strval, val);
#else
- print_debug(strval); print_debug_hex32(val); print_debug("\r\n");
+#error This file needs CONFIG_USE_PRINTK_IN_CAR #endif -}
-#define RAM_TIMING_DEBUG 0 +#define RAM_TIMING_DEBUG 1
Do we really want to always debug RAM timing?
No. This is a local change that crept in. Thanks for noticing. I'll drop it.
-static inline void print_tx(const char *strval, uint32_t val) -{ #if RAM_TIMING_DEBUG == 1
- print_raminit(strval, val);
+#define printk_raminit printk_debug +#else +#define printk_raminit(fmt, arg...) do {} while(0)
Why is the do{} while (0) needed here?
I was going to point to http://kernelnewbies.org/FAQ/DoWhile0 but that does not apply to empty statements. I blame having coded this at 4am. Will drop.
4, /* *Column addresses */ 5, /* *Number of DIMM Ranks */ 6, /* *Module Data Width*/
11, /* *DIMM Conf Type */ 13, /* *Pri SDRAM Width */ 17, /* *Logical Banks */9, /* *Cycle time at highest CAS Latency CL=X */
20, /* *DIMM Type Info */ 21, /* *SDRAM Module Attributes */18, /* *Supported CAS Latencies */
23, /* *Cycle time at CAS Latnecy (CLX - 1) */
27, /* *tRP Row precharge time */ 28, /* *Minimum Row Active to Row Active Delay (tRRD) */ 29, /* *tRCD RAS to CAS */26, /* *Cycle time at CAS Latnecy (CLX - 2) */
@@ -1464,11 +1440,18 @@ 36, /* *Write recovery time (tWR) */ 37, /* *Internal write to read command delay (tRDP) */ 38, /* *Internal read to precharge commanfd delay (tRTP) */ +#warning Why is SPD address 41 checked twice? 41, /* *Extension of Byte 41 tRC and Byte 42 tRFC */ 41, /* *Minimum Active to Active/Auto Refresh Time(Trc) */ 42, /* *Minimum Auto Refresh Command Time(Trfc) */ +#warning The SPD addresses below need special treatment like in spd_set_memclk. Right now they cause many false negatives.
18, /* *Supported CAS Latencies */
9, /* *Cycle time at highest CAS Latency CL=X */
23, /* *Cycle time at CAS Latency (CLX - 1) */
26, /* *Cycle time at CAS Latency (CLX - 2) */
I guess I'd rather leave them in order and add their numbers to the warning message.
I want to remove them altogether because they can't be treated specially in that array. That reordering is there to make sure that we know if any other mismatches are present in the DIMM. So in a way the new order helps debugging with the old code. I'm not feeling strongly about this, though.
}; u32 dcl, dcm;
- u8 common_cl;
/* S1G1 and AM2 sockets are Mod64BitMux capable. */ #if CPU_SOCKET_TYPE == 0x11 || CPU_SOCKET_TYPE == 0x12 @@ -1497,6 +1480,14 @@ } device0 = ctrl->channel0[i]; device1 = ctrl->channel1[i];
/* Abort if the chips don't support a common CAS latency. */
common_cl = spd_read_byte(device0, 18) &
spd_read_byte(device1, 18);
if (!common_cl) {
printk_debug("No common CAS latency supported\n");
goto single_channel;
} else {
printk_raminit("Common CAS latency bitfield:
0x%02x\n",
common_cl);
}
I didn't see this part in the summary of the patch.
I'll add the following sentence to the summary: "Check for dual channel CAS latency compatibility."
if (!param->cycle_time) { die("min_cycle_time to low"); }
- print_spew(param->name);
#ifdef DRAM_MIN_CYCLE_TIME
- print_debug(param->name);
- printk_debug(param->name);
It seems like you could get rid of this ifdef and just make it printk_debug or printk_raminit.
I'll probably make it printk_debug.
Thanks for the review. Any other comments before I repost?
Regards, Carl-Daniel
Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Reorder the SPD equality checks in the dual channel DIMM compatibility checking code. This is to make sure that we know if any other mismatches are present in the DIMM. The new order eases debugging with the old code. Add a comment about false negatives in that code. This needs to be implemented correctly, but that is hard to do in an efficient way. Check if the DIMMS in a dual channel setup have any compatible CAS latencies.
Add better comments to explain why wrong-at-first-glance SPD CL walking code is actually correct.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c =================================================================== --- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Revision 3850) +++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Arbeitskopie) @@ -34,34 +34,20 @@ #define QRANK_DIMM_SUPPORT 0 #endif
-static inline void print_raminit(const char *strval, uint32_t val) -{ #if CONFIG_USE_PRINTK_IN_CAR - printk_debug("%s%08x\r\n", strval, val); #else - print_debug(strval); print_debug_hex32(val); print_debug("\r\n"); +#error This file needs CONFIG_USE_PRINTK_IN_CAR #endif -}
#define RAM_TIMING_DEBUG 0
-static inline void print_tx(const char *strval, uint32_t val) -{ #if RAM_TIMING_DEBUG == 1 - print_raminit(strval, val); +#define printk_raminit printk_debug +#else +#define printk_raminit(fmt, arg...) #endif -}
-static inline void print_t(const char *strval) -{ -#if RAM_TIMING_DEBUG == 1 - print_debug(strval); -#endif -} - - - #if (CONFIG_LB_MEM_TOPK & (CONFIG_LB_MEM_TOPK -1)) != 0 # error "CONFIG_LB_MEM_TOPK must be a power of 2" #endif @@ -713,9 +699,7 @@ } sysinfo->ctrl_present[ctrl->node_id] = 1;
- print_spew("setting up CPU"); - print_spew_hex8(ctrl->node_id); - print_spew(" northbridge registers\r\n"); + printk_spew("setting up CPU %02x northbridge registers\n", ctrl->node_id); max = ARRAY_SIZE(register_values); for (i = 0; i < max; i += 3) { device_t dev; @@ -729,7 +713,7 @@ pci_write_config32(dev, where, reg); }
- print_spew("done.\r\n"); + printk_spew("done.\n"); }
@@ -829,14 +813,14 @@ if (value <=4 ) value += 8; // add back to 1G to high value += (27-5); // make 128MB to the real lines if ( value != (sz->per_rank)) { - print_err("Bad RANK Size --\r\n"); + printk_err("Bad RANK Size --\n"); goto val_err; }
goto out;
val_err: - die("Bad SPD value\r\n"); + die("Bad SPD value\n"); /* If an hw_error occurs report that I have no memory */ hw_err: sz->per_rank = 0; @@ -1070,9 +1054,7 @@ }
/* Report the amount of memory. */ - print_debug("RAM: 0x"); - print_debug_hex32(tom_k); - print_debug(" KB\r\n"); + printk_debug("RAM: 0x%08x kB\n", tom_k);
msr_t msr; if (tom_k > (4*1024*1024)) { @@ -1202,7 +1184,7 @@ csbase += csbase_inc; }
- print_debug("Interleaved\r\n"); + printk_debug("Interleaved\n");
/* Return the memory size in K */ return common_size << ((27-10) + bits); @@ -1306,7 +1288,7 @@ CMOS_VLEN_interleave_chip_selects, 1) != 0) { tom_k = interleave_chip_selects(ctrl, meminfo->is_Width128); } else { - print_debug("Interleaving disabled\r\n"); + printk_debug("Interleaving disabled\n"); tom_k = 0; } @@ -1325,9 +1307,7 @@ static long disable_dimm(const struct mem_controller *ctrl, unsigned index, struct mem_info *meminfo) { - print_debug("disabling dimm"); - print_debug_hex8(index); - print_debug("\r\n"); + printk_debug("disabling dimm %02x\n", index); if (!(meminfo->dimm_mask & 0x0F) && (meminfo->dimm_mask & 0xF0)) { /* channelB only? */ pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 4) << 2), 0); pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1) + 5) << 2), 0); @@ -1402,9 +1382,9 @@
#if 1 if (meminfo->is_registered) { - print_debug("Registered\r\n"); + printk_debug("Registered\n"); } else { - print_debug("Unbuffered\r\n"); + printk_debug("Unbuffered\n"); } #endif return meminfo->dimm_mask; @@ -1420,6 +1400,7 @@ int byte; unsigned device; device = ctrl->channel0[i]; + printk_raminit("DIMM socket %i, channel 0 SPD device is 0x%02x\n", i, device); if (device) { byte = spd_read_byte(ctrl->channel0[i], SPD_MEM_TYPE); /* Type */ if (byte == SPD_MEM_TYPE_SDRAM_DDR2) { @@ -1427,6 +1408,7 @@ } } device = ctrl->channel1[i]; + printk_raminit("DIMM socket %i, channel 1 SPD device is 0x%02x\n", i, device); if (device) { byte = spd_read_byte(ctrl->channel1[i], SPD_MEM_TYPE); if (byte == SPD_MEM_TYPE_SDRAM_DDR2) { @@ -1448,27 +1430,32 @@ 4, /* *Column addresses */ 5, /* *Number of DIMM Ranks */ 6, /* *Module Data Width*/ - 9, /* *Cycle time at highest CAS Latency CL=X */ 11, /* *DIMM Conf Type */ 13, /* *Pri SDRAM Width */ 17, /* *Logical Banks */ - 18, /* *Supported CAS Latencies */ 20, /* *DIMM Type Info */ 21, /* *SDRAM Module Attributes */ - 23, /* *Cycle time at CAS Latnecy (CLX - 1) */ - 26, /* *Cycle time at CAS Latnecy (CLX - 2) */ 27, /* *tRP Row precharge time */ 28, /* *Minimum Row Active to Row Active Delay (tRRD) */ 29, /* *tRCD RAS to CAS */ 30, /* *tRAS Activate to Precharge */ 36, /* *Write recovery time (tWR) */ 37, /* *Internal write to read command delay (tRDP) */ - 38, /* *Internal read to precharge commanfd delay (tRTP) */ - 41, /* *Extension of Byte 41 tRC and Byte 42 tRFC */ + 38, /* *Internal read to precharge command delay (tRTP) */ + 40, /* *Extension of Byte 41 tRC and Byte 42 tRFC */ 41, /* *Minimum Active to Active/Auto Refresh Time(Trc) */ 42, /* *Minimum Auto Refresh Command Time(Trfc) */ + /* The SPD addresses 18, 9, 23, 26 need special treatment like + * in spd_set_memclk. Right now they cause many false negatives. + * Keep them at the end to see other mismatches (if any). + */ + 18, /* *Supported CAS Latencies */ + 9, /* *Cycle time at highest CAS Latency CL=X */ + 23, /* *Cycle time at CAS Latency (CLX - 1) */ + 26, /* *Cycle time at CAS Latency (CLX - 2) */ }; u32 dcl, dcm; + u8 common_cl;
/* S1G1 and AM2 sockets are Mod64BitMux capable. */ #if CPU_SOCKET_TYPE == 0x11 || CPU_SOCKET_TYPE == 0x12 @@ -1497,6 +1484,14 @@ } device0 = ctrl->channel0[i]; device1 = ctrl->channel1[i]; + /* Abort if the chips don't support a common CAS latency. */ + common_cl = spd_read_byte(device0, 18) & spd_read_byte(device1, 18); + if (!common_cl) { + printk_debug("No common CAS latency supported\n"); + goto single_channel; + } else { + printk_raminit("Common CAS latency bitfield: 0x%02x\n", common_cl); + } for (j = 0; j < ARRAY_SIZE(addresses); j++) { unsigned addr; addr = addresses[j]; @@ -1509,11 +1504,12 @@ return -1; } if (value0 != value1) { + printk_raminit("SPD values differ between channel 0/1 for byte %i\n", addr); goto single_channel; } } } - print_spew("Enabling dual channel memory\r\n"); + printk_spew("Enabling dual channel memory\n"); dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW); dcl &= ~DCL_BurstLength32; /* 32byte mode may be preferred in platforms that include graphics controllers that generate a lot of 32-bytes system memory accesses 32byte mode is not supported when the DRAM interface is 128 bits wides, even 32byte mode is set, system still use 64 byte mode */ @@ -1566,7 +1562,7 @@
static const struct mem_param speed[] = { { - .name = "200Mhz\r\n", + .name = "200MHz", .cycle_time = 0x500, .divisor = 200, // how many 1/40ns per clock .dch_memclk = DCH_MemClkFreq_200MHz, //0 @@ -1578,7 +1574,7 @@
}, { - .name = "266Mhz\r\n", + .name = "266MHz", .cycle_time = 0x375, .divisor = 150, //???? .dch_memclk = DCH_MemClkFreq_266MHz, //1 @@ -1589,7 +1585,7 @@ .DcqByPassMax = 4, }, { - .name = "333Mhz\r\n", + .name = "333MHz", .cycle_time = 0x300, .divisor = 120, .dch_memclk = DCH_MemClkFreq_333MHz, //2 @@ -1601,7 +1597,7 @@
}, { - .name = "400Mhz\r\n", + .name = "400MHz", .cycle_time = 0x250, .divisor = 100, .dch_memclk = DCH_MemClkFreq_400MHz,//3 @@ -1628,10 +1624,7 @@ if (!param->cycle_time) { die("min_cycle_time to low"); } - print_spew(param->name); -#ifdef DRAM_MIN_CYCLE_TIME - print_debug(param->name); -#endif + printk_debug("%s\n", param->name); return param; }
@@ -1722,7 +1715,7 @@ } min_latency = 3;
- print_tx("1 min_cycle_time:", min_cycle_time); + printk_raminit("1 min_cycle_time: %08x\n", min_cycle_time);
/* Compute the least latency with the fastest clock supported * by both the memory controller and the dimms. @@ -1734,7 +1727,7 @@ int latency; u32 spd_device = ctrl->channel0[i];
- print_tx("1.1 dimm_mask:", meminfo->dimm_mask); + printk_raminit("1.1 dimm_mask: %08x\n", meminfo->dimm_mask); if (!(meminfo->dimm_mask & (1 << i))) { if (meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) { /* channelB only? */ spd_device = ctrl->channel1[i]; @@ -1756,9 +1749,16 @@ latencies = spd_read_byte(spd_device, SPD_CAS_LAT); if (latencies <= 0) continue;
- print_tx("i:",i); - print_tx("\tlatencies:", latencies); - /* Compute the lowest cas latency supported */ + printk_raminit("i: %08x\n",i); + printk_raminit("\tlatencies: %08x\n", latencies); + /* Compute the lowest cas latency which can be expressed in this + * particular SPD EEPROM. You can store at most settings for 3 + * contiguous CAS latencies, so by taking the highest CAS + * latency maked as supported in the SPD and subtracting 2 you + * get the lowest expressable CAS latency. That latency is not + * necessarily supported, but a (maybe invalid) entry exists + * for it. + */ latency = log2(latencies) - 2;
/* Loop through and find a fast clock with a low latency */ @@ -1773,15 +1773,15 @@ goto hw_error; }
- print_tx("\tindex:", index); - print_tx("\t\tlatency:", latency); - print_tx("\t\tvalue1:", value); + printk_raminit("\tindex: %08x\n", index); + printk_raminit("\t\tlatency: %08x\n", latency); + printk_raminit("\t\tvalue1: %08x\n", value);
value = convert_to_linear(value);
- print_tx("\t\tvalue2:", value); + printk_raminit("\t\tvalue2: %08x\n", value);
- /* Only increase the latency if we decreas the clock */ + /* Only increase the latency if we decrease the clock */ if (value >= min_cycle_time ) { if (value < new_cycle_time) { new_cycle_time = value; @@ -1792,8 +1792,8 @@ } } } - print_tx("\t\tnew_cycle_time:", new_cycle_time); - print_tx("\t\tnew_latency:", new_latency); + printk_raminit("\t\tnew_cycle_time: %08x\n", new_cycle_time); + printk_raminit("\t\tnew_latency: %08x\n", new_latency);
}
@@ -1811,15 +1811,15 @@ min_latency = new_latency; }
- print_tx("2 min_cycle_time:", min_cycle_time); - print_tx("2 min_latency:", min_latency); + printk_raminit("2 min_cycle_time: %08x\n", min_cycle_time); + printk_raminit("2 min_latency: %08x\n", min_latency); } /* Make a second pass through the dimms and disable * any that cannot support the selected memclk and cas latency. */
- print_tx("3 min_cycle_time:", min_cycle_time); - print_tx("3 min_latency:", min_latency); + printk_raminit("3 min_cycle_time: %08x\n", min_cycle_time); + printk_raminit("3 min_latency: %08x\n", min_latency);
for (i = 0; (i < DIMM_SOCKETS); i++) { int latencies; @@ -1874,7 +1874,7 @@ meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo); }
- print_tx("4 min_cycle_time:", min_cycle_time); + printk_raminit("4 min_cycle_time: %08x\n", min_cycle_time);
/* Now that I know the minimum cycle time lookup the memory parameters */ result.param = get_mem_param(min_cycle_time); @@ -1886,7 +1886,7 @@ value |= result.param->dch_memclk << DCH_MemClkFreq_SHIFT; pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
- print_debug(result.param->name); + printk_debug("%s\n", result.param->name);
/* Update DRAM Timing Low with our selected cas latency */ value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW); @@ -2054,16 +2054,16 @@
value = spd_read_byte(spd_device, SPD_TRAS); //in 1 ns if (value < 0) return -1; - print_tx("update_dimm_Tras: 0 value=", value); + printk_raminit("update_dimm_Tras: 0 value= %08x\n", value);
value <<= 2; //convert it to in 1/4ns
value *= 10; - print_tx("update_dimm_Tras: 1 value=", value); + printk_raminit("update_dimm_Tras: 1 value= %08x\n", value);
clocks = (value + param->divisor - 1)/param->divisor; - print_tx("update_dimm_Tras: divisor=", param->divisor); - print_tx("update_dimm_Tras: clocks=", clocks); + printk_raminit("update_dimm_Tras: divisor= %08x\n", param->divisor); + printk_raminit("update_dimm_Tras: clocks= %08x\n", clocks); if (clocks < DTL_TRAS_MIN) { clocks = DTL_TRAS_MIN; } @@ -2366,8 +2366,8 @@ uint32_t reg;
if ((val < TT_MIN) || (val > TT_MAX)) { - print_err(str); - die(" Unknown\r\n"); + printk_err(str); + die(" Unknown\n"); }
reg = pci_read_config32(ctrl->f2, TT_REG); @@ -2610,12 +2610,12 @@ break; }
- print_raminit("\tdimm_mask = ", meminfo->dimm_mask); - print_raminit("\tx4_mask = ", meminfo->x4_mask); - print_raminit("\tx16_mask = ", meminfo->x16_mask); - print_raminit("\tsingle_rank_mask = ", meminfo->single_rank_mask); - print_raminit("\tODC = ", dword); - print_raminit("\tAddr Timing= ", dwordx); + printk_raminit("\tdimm_mask = %08x\n", meminfo->dimm_mask); + printk_raminit("\tx4_mask = %08x\n", meminfo->x4_mask); + printk_raminit("\tx16_mask = %08x\n", meminfo->x16_mask); + printk_raminit("\tsingle_rank_mask = %08x\n", meminfo->single_rank_mask); + printk_raminit("\tODC = %08x\n", dword); + printk_raminit("\tAddr Timing= %08x\n", dwordx); #endif
#if (DIMM_SUPPORT & 0x0100)==0x0000 /* 2T mode only used for unbuffered DIMM */ @@ -2697,37 +2697,37 @@ !(meminfo->dimm_mask & (1 << (DIMM_SOCKETS + i))) ) { continue; } - print_tx("spd_set_dram_timing dimm socket: ", i); + printk_raminit("spd_set_dram_timing dimm socket: %08x\n", i); /* DRAM Timing Low Register */ - print_t("\ttrc\r\n"); + printk_raminit("\ttrc\n"); if ((rc = update_dimm_Trc (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrcd\r\n"); + printk_raminit("\ttrcd\n"); if ((rc = update_dimm_Trcd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrrd\r\n"); + printk_raminit("\ttrrd\n"); if ((rc = update_dimm_Trrd(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttras\r\n"); + printk_raminit("\ttras\n"); if ((rc = update_dimm_Tras(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrp\r\n"); + printk_raminit("\ttrp\n"); if ((rc = update_dimm_Trp (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrtp\r\n"); + printk_raminit("\ttrtp\n"); if ((rc = update_dimm_Trtp(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
- print_t("\ttwr\r\n"); + printk_raminit("\ttwr\n"); if ((rc = update_dimm_Twr (ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
/* DRAM Timing High Register */ - print_t("\ttref\r\n"); + printk_raminit("\ttref\n"); if ((rc = update_dimm_Tref(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttwtr\r\n"); + printk_raminit("\ttwtr\n"); if ((rc = update_dimm_Twtr(ctrl, param, i, meminfo->dimm_mask)) <= 0) goto dimm_err;
- print_t("\ttrfc\r\n"); + printk_raminit("\ttrfc\n"); if ((rc = update_dimm_Trfc(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
/* DRAM Config Low */ @@ -2784,37 +2784,37 @@ #endif meminfo = &sysinfo->meminfo[ctrl->node_id];
- print_debug_addr("sdram_set_spd_registers: paramx :", ¶mx); + printk_debug("sdram_set_spd_registers: paramx :%p\n", ¶mx);
activate_spd_rom(ctrl); meminfo->dimm_mask = spd_detect_dimms(ctrl);
- print_tx("sdram_set_spd_registers: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("sdram_set_spd_registers: dimm_mask=0x%x\n", meminfo->dimm_mask);
if (!(meminfo->dimm_mask & ((1 << 2*DIMM_SOCKETS) - 1))) { - print_debug("No memory for this cpu\r\n"); + printk_debug("No memory for this cpu\n"); return; } meminfo->dimm_mask = spd_enable_2channels(ctrl, meminfo); - print_tx("spd_enable_2channels: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_enable_2channels: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
meminfo->dimm_mask = spd_set_ram_size(ctrl, meminfo); - print_tx("spd_set_ram_size: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_ram_size: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
meminfo->dimm_mask = spd_handle_unbuffered_dimms(ctrl, meminfo); - print_tx("spd_handle_unbuffered_dimms: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_handle_unbuffered_dimms: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
result = spd_set_memclk(ctrl, meminfo); param = result.param; meminfo->dimm_mask = result.dimm_mask; - print_tx("spd_set_memclk: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_memclk: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
@@ -2826,7 +2826,7 @@ paramx.divisor = get_exact_divisor(param->dch_memclk, paramx.divisor);
meminfo->dimm_mask = spd_set_dram_timing(ctrl, ¶mx, meminfo); - print_tx("spd_set_dram_timing: dimm_mask=0x%x\n", meminfo->dimm_mask); + printk_raminit("spd_set_dram_timing: dimm_mask=0x%x\n", meminfo->dimm_mask); if (meminfo->dimm_mask == -1) goto hw_spd_err;
@@ -2961,13 +2961,13 @@ /* FIXME: How about 32 node machine later? */ tsc_t tsc, tsc0[8];
- print_debug_addr("sdram_enable: tsc0[8]: ", &tsc0[0]); + printk_debug("sdram_enable: tsc0[8]: %p", &tsc0[0]); #endif uint32_t dword;
/* Error if I don't have memory */ if (memory_end_k(ctrl, controllers) == 0) { - die("No memory\r\n"); + die("No memory\n"); }
/* Before enabling memory start the memory clocks */ @@ -2990,15 +2990,15 @@ } }
- /* We need to wait a mimmium of 20 MEMCLKS to enable the InitDram */ + /* We need to wait a minimum of 20 MEMCLKS to enable the InitDram */ memreset(controllers, ctrl); #if 0 - print_debug("prepare to InitDram:"); + printk_debug("prepare to InitDram:"); for (i=0; i<10; i++) { - print_debug_hex32(i); + printk_debug("%08x", i); print_debug("\b\b\b\b\b\b\b\b"); } - print_debug("\r\n"); + printk_debug("\n"); #endif
for (i = 0; i < controllers; i++) { @@ -3015,7 +3015,7 @@ dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW); if (dcl & DCL_DimmEccEn) { uint32_t mnc; - print_spew("ECC enabled\r\n"); + printk_spew("ECC enabled\n"); mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG); mnc |= MNC_ECC_EN; if (dcl & DCL_Width128) { @@ -3057,17 +3057,17 @@ /* Skip everything if I don't have any memory on this controller */ if (sysinfo->meminfo[i].dimm_mask==0x00) continue;
- print_debug("Initializing memory: "); + printk_debug("Initializing memory: "); int loops = 0; do { dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW); loops++; if ((loops & 1023) == 0) { - print_debug("."); + printk_debug("."); } } while(((dcl & DCL_InitDram) != 0) && (loops < TIMEOUT_LOOPS)); if (loops >= TIMEOUT_LOOPS) { - print_debug(" failed\r\n"); + printk_debug(" failed\n"); continue; }
@@ -3080,7 +3080,7 @@ if (cpu_f0_f1[i]) { tsc= rdtsc();
- print_debug_dqs_tsc("\r\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2); + print_debug_dqs_tsc("\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2); print_debug_dqs_tsc("end tsc ", i, tsc.hi, tsc.lo, 2);
if (tsc.lo<tsc0[i].lo) { @@ -3095,7 +3095,7 @@ print_debug_dqs_tsc(" dtsc0", i, tsc0[i].hi, tsc0[i].lo, 2); } #endif - print_debug(" done\r\n"); + printk_debug(" done\n"); }
#if HW_MEM_HOLE_SIZEK != 0
On Thu, Jan 15, 2009 at 4:46 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Reorder the SPD equality checks in the dual channel DIMM compatibility checking code. This is to make sure that we know if any other mismatches are present in the DIMM. The new order eases debugging with the old code. Add a comment about false negatives in that code. This needs to be implemented correctly, but that is hard to do in an efficient way. Check if the DIMMS in a dual channel setup have any compatible CAS latencies.
Add better comments to explain why wrong-at-first-glance SPD CL walking code is actually correct.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Marc Jones marcj303@gmail.com
On 16.01.2009 00:58, Marc Jones wrote:
On Thu, Jan 15, 2009 at 4:46 PM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Since all K8 targets now have CONFIG_USE_PRINTK_IN_CAR enabled, using print_* in K8 RAM init does not make sense anymore. Convert almost all print_* to printk_*. This improves readability a lot and makes the code shorter.
Reorder the SPD equality checks in the dual channel DIMM compatibility checking code. This is to make sure that we know if any other mismatches are present in the DIMM. The new order eases debugging with the old code. Add a comment about false negatives in that code. This needs to be implemented correctly, but that is hard to do in an efficient way. Check if the DIMMS in a dual channel setup have any compatible CAS latencies.
Add better comments to explain why wrong-at-first-glance SPD CL walking code is actually correct.
Fix a few typos.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Marc Jones marcj303@gmail.com
Thanks, r3865.
Regards, Carl-Daniel