diff options
-rw-r--r-- | src/include/stdlib.h | 3 | ||||
-rw-r--r-- | src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c | 11 | ||||
-rw-r--r-- | src/southbridge/via/k8t890/k8t890_early_car.c | 74 |
3 files changed, 63 insertions, 25 deletions
diff --git a/src/include/stdlib.h b/src/include/stdlib.h index 1fa8e24d18..e2b37e6fe9 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -5,6 +5,9 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + #ifndef __ROMCC__ extern void *malloc(size_t size); void free(void *ptr); diff --git a/src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c b/src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c index 58dce4dd05..b0f7e6903f 100644 --- a/src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c +++ b/src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c @@ -284,20 +284,19 @@ void real_main(unsigned long bist, unsigned long cpu_init_detectedx) init_timer(); ht_setup_chains_x(sysinfo); /* Init sblnk and sbbusn, nodes, sbdn. */ - enable_fid_change(); - init_fidvid_bsp(bsp_apicid); - needs_reset = optimize_link_coherent_ht(); needs_reset |= optimize_link_incoherent_ht(sysinfo); - - /* FIXME: Assumes that 1000MHz LDT is selected. */ - needs_reset |= k8t890_early_setup_car(16, 0x6); + needs_reset |= k8t890_early_setup_ht(); if (needs_reset) { print_debug("ht reset -\r\n"); soft_reset(); } + /* the HT settings needs to be OK, because link freq chnage may cause HT disconnect */ + enable_fid_change(); + init_fidvid_bsp(bsp_apicid); + /* Stop the APs so we can start them later in init. */ allow_all_aps_stop(bsp_apicid); diff --git a/src/southbridge/via/k8t890/k8t890_early_car.c b/src/southbridge/via/k8t890/k8t890_early_car.c index 6faeabbd0b..a14e2a2715 100644 --- a/src/southbridge/via/k8t890/k8t890_early_car.c +++ b/src/southbridge/via/k8t890/k8t890_early_car.c @@ -22,35 +22,71 @@ * generate PCI reset or LDTSTOP to apply. */ -u8 k8t890_early_setup_car(u8 width, u8 speed) -{ - u8 awidth, aspeed; +#include <stdlib.h> - print_debug("LDT width and speed for K8T890 was"); - awidth = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x67); - print_debug_hex8(awidth); +/* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */ +static ldtreg[3] = {0x86, 0xa6, 0xc6}; - aspeed = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x6d); - print_debug_hex8(aspeed); +/* This functions sets KT890 link frequency and width to same values as + * it has been setup on K8 side, by AMD NB init. + */ - if ((aspeed == speed) && (((width == 16) && (awidth == 0x11)) || - ((width == 8) && (awidth == 0x00)))) - return 0; +u8 k8t890_early_setup_ht(void) +{ + u8 awidth, afreq, cldtfreq; + u8 cldtwidth_in, cldtwidth_out, vldtwidth_in, vldtwidth_out, ldtnr, width; + u16 vldtcaps; + + /* check if connected non coherent, initcomplete (find the SB on K8 side) */ + if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0x98)) { + ldtnr = 0; + } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xb8)) { + ldtnr = 1; + } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xd8)) { + ldtnr = 2; + } + + print_debug("K8T890 found at LDT "); + print_debug_hex8(ldtnr); - /* Update the desired HT LNK capabilities in NB too. */ - pci_write_config8(PCI_DEV(0, 0x0, 0), 0x67, - (width == 16) ? 0x11 : 0x00); - pci_write_config8(PCI_DEV(0, 0x0, 0), 0x6d, speed); + /* get the maximum widths for both sides */ + cldtwidth_in = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) & 0x7; + cldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) >> 4) & 0x7; + vldtwidth_in = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) & 0x7; + vldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) >> 4) & 0x7; - print_debug(" and will after HT reset: "); + width = MIN(MIN(MIN(cldtwidth_out, cldtwidth_in), vldtwidth_out), vldtwidth_in); + print_debug(" Agreed on width: "); + print_debug_hex8(width); awidth = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x67); - print_debug_hex8(awidth); - aspeed = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x6d); - print_debug_hex8(aspeed); + /* Update the desired HT LNK to match AMD NB max from VIA NB is 0x1 */ + width = (width == 0x01) ? 0x11 : 0x00; + pci_write_config8(PCI_DEV(0, 0x0, 0), 0x67, width); + + /* Get programmed HT freq at base 0x89 */ + cldtfreq = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr] + 3) & 0xf; + print_debug(" CPU programmed to HT freq: "); + print_debug_hex8(cldtfreq); + + print_debug(" VIA HT caps: "); + vldtcaps = pci_read_config16(PCI_DEV(0, 0, 0), 0x6e); + print_debug_hex16(vldtcaps); + + if (!(vldtcaps & (1 << cldtfreq ))) { + die("Chipset does not support desired HT frequency\n"); + } + + afreq = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x6d); + pci_write_config8(PCI_DEV(0, 0x0, 0), 0x6d, cldtfreq); print_debug("\n"); + /* no reset needed */ + if ((width == awidth) && (afreq == cldtfreq)) { + return 0; + } + return 1; } |