summaryrefslogtreecommitdiff
path: root/src/southbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge')
-rw-r--r--src/southbridge/via/k8t890/k8t890_early_car.c74
1 files changed, 55 insertions, 19 deletions
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;
}