summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/stdlib.h3
-rw-r--r--src/mainboard/asus/a8v-e_se/cache_as_ram_auto.c11
-rw-r--r--src/southbridge/via/k8t890/k8t890_early_car.c74
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;
}