Hello,
attached is the patch which implements the mem speed table,
mainboards describe it's mem speed ability in mem_controller structure
as the following example:
static const struct mem_controller cpu[] = {
{
.node_id = 0,
.f0 = PCI_DEV(0, 0x18, 0),
.f1 = PCI_DEV(0, 0x18, 1),
.f2 = PCI_DEV(0, 0x18, 2),
.f3 = PCI_DEV(0, 0x18, 3),
.channel0 = { (0xa<<3)|0, (0xa<<3)|2, (0xa<<3)|4,
(0xa<<3)|6 },
.channel1 = { (0xa<<3)|1, (0xa<<3)|3, (0xa<<3)|5,
(0xa<<3)|7 },
.memclk_conf = {
{4, 4, 2, 0, 0, 200}, /* 200M for: 4x1rank,
2x1rank + 2x2rank, etc */
{4, 4, 0, 2, 0, 200},
{4, 4, 0, 0, 2, 200},
{8, 8, 8, 8, 8, 166}, /* 166M for other case
*/
{0, 0, 0, 0, 0, 0}, /* the end */
}
},
};
Tao
diff -pNur freebios2-orig/src/northbridge/amd/amdk8/raminit.c freebios2/src/northbridge/amd/amdk8/raminit.c
--- freebios2-orig/src/northbridge/amd/amdk8/raminit.c 2005-04-30 16:04:13.000000000 +0800
+++ freebios2/src/northbridge/amd/amdk8/raminit.c 2005-05-11 15:48:24.000000000 +0800
@@ -1219,6 +1219,70 @@ static const struct mem_param *get_mem_p
return param;
}
+static int read_memclk_conf(const struct mem_controller *ctrl, long dimm_mask)
+{
+ unsigned char cur_dimms, cur_1rank, cur_2rank, cur_3rank, cur_4rank, cur_speed;
+ struct memclk_conf *memclk_conf;
+ int i, ranks;
+
+ cur_dimms = cur_1rank = cur_2rank = cur_3rank = cur_4rank = 0;
+ cur_speed = 100;
+
+ for (i = 0; i < (DIMM_SOCKETS << 1); i++) {
+ if (!(dimm_mask & (1 << i)))
+ continue;
+ cur_dimms++;
+ if (i < DIMM_SOCKETS)
+ ranks = spd_read_byte(ctrl->channel0[i], 5);
+ else
+ ranks = spd_read_byte(ctrl->channel1[i - DIMM_SOCKETS], 5);
+ switch (ranks) {
+ case 1:
+ cur_1rank++;
+ break;
+ case 2:
+ cur_2rank++;
+ break;
+ case 3:
+ cur_3rank++;
+ break;
+ case 4:
+ cur_4rank++;
+ break;
+ }
+ }
+
+ if (!is_dual_channel(ctrl)) {
+ cur_dimms <<= 1;
+ cur_1rank <<= 1;
+ cur_2rank <<= 1;
+ cur_3rank <<= 1;
+ cur_4rank <<= 1;
+ }
+
+ memclk_conf = ctrl->memclk_conf;
+ while (memclk_conf->max_dimms) {
+ if (cur_speed < memclk_conf->max_speed &&
+ cur_dimms <= memclk_conf->max_dimms &&
+ cur_1rank <= memclk_conf->max_1rank &&
+ cur_2rank <= memclk_conf->max_2rank &&
+ cur_3rank <= memclk_conf->max_3rank &&
+ cur_4rank <= memclk_conf->max_4rank) {
+ cur_speed = memclk_conf->max_speed;
+ }
+ memclk_conf++;
+ }
+
+ if (cur_speed < 133)
+ return NBCAP_MEMCLK_100MHZ;
+ else if (cur_speed < 166)
+ return NBCAP_MEMCLK_133MHZ;
+ else if (cur_speed < 200)
+ return NBCAP_MEMCLK_166MHZ;
+ else
+ return NBCAP_MEMCLK_200MHZ;
+}
+
struct spd_set_memclk_result {
const struct mem_param *param;
long dimm_mask;
@@ -1227,7 +1291,7 @@ static struct spd_set_memclk_result spd_
{
/* Compute the minimum cycle time for these dimms */
struct spd_set_memclk_result result;
- unsigned min_cycle_time, min_latency, bios_cycle_time;
+ unsigned min_cycle_time, min_latency, board_cycle_time, bios_cycle_time;
int i;
uint32_t value;
@@ -1242,6 +1306,10 @@ static struct spd_set_memclk_result spd_
value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
+ board_cycle_time = min_cycle_times[read_memclk_conf(ctrl, dimm_mask)];
+ if (board_cycle_time > min_cycle_time) {
+ min_cycle_time = board_cycle_time;
+ }
bios_cycle_time = min_cycle_times[
read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 0)];
if (bios_cycle_time > min_cycle_time) {
diff -pNur freebios2-orig/src/northbridge/amd/amdk8/raminit.h freebios2/src/northbridge/amd/amdk8/raminit.h
--- freebios2-orig/src/northbridge/amd/amdk8/raminit.h 2005-04-30 16:04:13.000000000 +0800
+++ freebios2/src/northbridge/amd/amdk8/raminit.h 2005-05-11 15:48:22.000000000 +0800
@@ -1,12 +1,22 @@
#ifndef RAMINIT_H
#define RAMINIT_H
+struct memclk_conf {
+ unsigned char max_dimms;
+ unsigned char max_1rank;
+ unsigned char max_2rank;
+ unsigned char max_3rank;
+ unsigned char max_4rank;
+ unsigned char max_speed;
+};
+
#define DIMM_SOCKETS 4
struct mem_controller {
unsigned node_id;
device_t f0, f1, f2, f3;
uint16_t channel0[DIMM_SOCKETS];
uint16_t channel1[DIMM_SOCKETS];
+ struct memclk_conf memclk_conf[8];
};
_______________________________________________
LinuxBIOS mailing list
[email protected]
http://www.openbios.org/mailman/listinfo/linuxbios