summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRudolf Marek <r.marek@assembler.cz>2008-03-19 20:24:33 +0000
committerRudolf Marek <r.marek@assembler.cz>2008-03-19 20:24:33 +0000
commitc221349746299537de9e01a0bcfb28485b15ef84 (patch)
treef0702245bbcc225216a883589e7b8ae0febb7db9
parentcfcc9ca59047a19dd01953c1d906947e2c78ca6a (diff)
downloadcoreboot-c221349746299537de9e01a0bcfb28485b15ef84.tar.xz
Following patch will setup KT890 HT automatically. It will find the
max width of the link and also it will take the frequency of K8 HT already done coreboot (and checks if t can run on it). Signed-off-by: Rudolf Marek <r.marek@assembler.cz> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3169 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-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;
}