summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch')
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch980
1 files changed, 980 insertions, 0 deletions
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch
new file mode 100644
index 0000000..5d50aae
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch
@@ -0,0 +1,980 @@
+From 864c5d310f3a833e1317053c1d9886ac6e95a56e Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:47 -0600
+Subject: [PATCH 09/45] northbridge/amd/amdmct: Add termination and timing
+ values for C32 sockets
+
+The existing MCT initialization code was largely missing C32 socket-
+specific configuration data. Add C32 socket-specific timing and ODT
+values as specified in the BKDG.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 543 ++++++++++++++++++++++++++-
+ src/northbridge/amd/amdmct/mct_ddr3/mctrci.c | 58 +++
+ src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 254 +++++++++++++
+ 3 files changed, 851 insertions(+), 4 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index cb83fe1..ac5220e 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -1092,6 +1092,152 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++
++ if (rank_count_dimm0 == 4) {
++ calibration_code &= ~(0xff << 16);
++ calibration_code |= 0x22 << 16;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++
++ if ((rank_count_dimm0 == 4) || (rank_count_dimm1 == 4)) {
++ calibration_code &= ~(0xff << 16);
++ calibration_code |= 0x22 << 16;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x10222222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x20222222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x30222222;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* TODO
++ * LRDIMM support unimplemented
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
++ if (MaxDimmsInstallable == 1) {
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x10222222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x20222222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ calibration_code = 0x30222222;
++ else
++ calibration_code = 0x30112222;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1116,11 +1262,165 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
+ uint8_t rank_count_dimm0;
+ uint8_t rank_count_dimm1;
+
+- if (package_type == PT_GR) {
+- /* Socket G34 */
++ if (package_type == PT_GR) {
++ /* Socket G34 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */
++ if (MaxDimmsInstallable == 1) {
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003c3c3c;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x003a3a3a;
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ calibration_code = 0x00393939;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00393c39;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00373a37;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x00363936;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003a3c3a;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00383a38;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x00353935;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* TODO
++ * LRDIMM support unimplemented
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00383837;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00363635;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00353533;
++ else
++ calibration_code = 0x00003533;
++ } else if (MemClkFreq == 0x16) {
++ /* DDR3-1866 */
++ calibration_code = 0x00333330;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00383837;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00363635;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00353533;
++ else
++ calibration_code = 0x00003533;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00390039;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x00390039;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003a3a3a;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00003939;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ calibration_code = 0x00003738;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
+ if (pDCTstat->Status & (1 << SB_Registered)) {
+ /* RDIMM */
+- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
+ if (MaxDimmsInstallable == 1) {
+ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
+ /* DDR3-667 - DDR3-800 */
+@@ -1179,7 +1479,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
+ */
+ } else {
+ /* UDIMM */
+- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
+ if (MaxDimmsInstallable == 1) {
+ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
+
+@@ -1357,6 +1657,69 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
++ slow_access = 0;
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 78 */
++ slow_access = 0;
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ slow_access = 0;
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ if (rank_count_dimm0 == 1)
++ slow_access = 0;
++ else
++ slow_access = 1;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ slow_access = 0;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ slow_access = 0;
++ else
++ slow_access = 1;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa)) {
++ /* DDR3-667 - DDR3-1066 */
++ slow_access = 0;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ slow_access = 1;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1466,6 +1829,92 @@ static uint8_t fam15h_odt_tristate_enable_code(struct DCTStatStruc *pDCTstat, ui
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xe;
++ else
++ odt_tristate_code = 0xa;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm1 == 1)
++ odt_tristate_code = 0xd;
++ else
++ odt_tristate_code = 0x5;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0xc;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2))
++ odt_tristate_code = 0x4;
++ else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0x8;
++ else
++ odt_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++
++ /* TODO
++ * Implement LRDIMM support
++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xe;
++ else
++ odt_tristate_code = 0xa;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xd;
++ else
++ odt_tristate_code = 0x5;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0xc;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2))
++ odt_tristate_code = 0x4;
++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0x8;
++ else
++ odt_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1575,6 +2024,92 @@ static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uin
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 < 4)
++ cs_tristate_code = 0xfc;
++ else
++ cs_tristate_code = 0xcc;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm1 < 4)
++ cs_tristate_code = 0xf3;
++ else
++ cs_tristate_code = 0x33;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ cs_tristate_code = 0xf0;
++ else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4))
++ cs_tristate_code = 0x30;
++ else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4))
++ cs_tristate_code = 0xc0;
++ else
++ cs_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++
++ /* TODO
++ * Implement LRDIMM support
++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ cs_tristate_code = 0xfe;
++ else
++ cs_tristate_code = 0xfc;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ cs_tristate_code = 0xfb;
++ else
++ cs_tristate_code = 0xf3;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ cs_tristate_code = 0xfa;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2))
++ cs_tristate_code = 0xf2;
++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1))
++ cs_tristate_code = 0xf8;
++ else
++ cs_tristate_code = 0xf0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
+index 4455391..f5d488a 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
+@@ -77,6 +77,51 @@ static uint8_t fam15h_rdimm_rc2_ibt_code(struct DCTStatStruc *pDCTstat, uint8_t
+ * 3 DIMM/channel support unimplemented
+ */
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.7.1.2.1 Table 86 */
++ if (MaxDimmsInstallable == 1) {
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ control_code = 0x1;
++ } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) {
++ /* DDR3-1066 - DDR3-1333 */
++ if (num_registers == 1) {
++ control_code = 0x0;
++ } else {
++ control_code = 0x1;
++ }
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ control_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ control_code = 0x1;
++ } else if ((MemClkFreq >= 0xa) && (MemClkFreq <= 0x12)) {
++ /* DDR3-1066 - DDR3-1600 */
++ if (num_registers == 1) {
++ control_code = 0x0;
++ } else {
++ control_code = 0x1;
++ }
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ if (num_registers == 1) {
++ control_code = 0x1;
++ } else {
++ control_code = 0x8;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -166,6 +211,13 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
+ val = 0x4;
+ }
+ }
++ else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (MaxDimmsInstallable == 2) {
++ if (Dimms > 1)
++ val = 0x4;
++ }
++ }
+ }
+ } else if (CtrlWordNum == 3) {
+ val = (pDCTstat->CtrlWrd3 >> (DimmNum << 2)) & 0xff;
+@@ -183,6 +235,12 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
+ val = 0x0;
+ }
+ }
++ else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (MaxDimmsInstallable == 2) {
++ val = 0x0;
++ }
++ }
+ }
+ } else if (CtrlWordNum == 9) {
+ val = 0xd; /* DBA1, DBA0, DA3 = 0 */
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+index 143290f..822d813 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+@@ -117,6 +117,67 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
+ term = 0x2;
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */
++ if (MaxDimmsInstallable == 1) {
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)
++ || (frequency_index == 0xa) || (frequency_index == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ if (rank_count < 3)
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ /* DDR3-1600 */
++ term = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4)
++ && (rank_count_dimm1 < 4)))
++ term = 0x0;
++ else
++ term = 0x2;
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ term = 0x1;
++ }
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ term = 0x2;
++ } else {
++ /* DDR3-1600 */
++ if (number_of_dimms == 1)
++ term = 0x0;
++ else
++ term = 0x1;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct];
++
++ if ((frequency_index == 0xa) || (frequency_index == 0xe)) {
++ /* DDR3-1066 - DDR3-1333 */
++ if (rank_count_dimm2 < 4)
++ term = 0x1;
++ else
++ term = 0x2;
++ } else if (frequency_index == 0x12) {
++ /* DDR3-1600 */
++ term = 0x1;
++ } else {
++ term = 0x2;
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+@@ -151,6 +212,33 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
+ term = 0x2;
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 59 */
++ if (MaxDimmsInstallable == 1) {
++ term = 0x0;
++ } else if (MaxDimmsInstallable == 2) {
++ if ((number_of_dimms == 2) && (frequency_index == 0x12)) {
++ term = 0x1;
++ } else if (number_of_dimms == 1) {
++ term = 0x0;
++ } else {
++ term = 0x2;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ if (number_of_dimms == 1) {
++ if (frequency_index <= 0xa) {
++ term = 0x2;
++ } else {
++ if (rank_count < 3) {
++ term = 0x1;
++ } else {
++ term = 0x2;
++ }
++ }
++ } else if (number_of_dimms == 2) {
++ term = 0x2;
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+@@ -302,6 +390,125 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t
+ * 3 DIMM/channel support unimplemented
+ */
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if (rank_count_dimm0 < 4) {
++ term = 0x2;
++ } else {
++ if (!rank)
++ term = 0x2;
++ else
++ term = 0x0;
++ }
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ term = 0x1;
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ if (rank_count_dimm0 < 4) {
++ term = 0x1;
++ } else {
++ if (!rank)
++ term = 0x3;
++ else
++ term = 0x0;
++ }
++ } else {
++ term = 0x3;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x2;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
++ term = 0x3;
++ } else {
++ if (rank_count_dimm0 == 4) {
++ if (rank_count_dimm1 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ } else if (rank_count_dimm1 == 4) {
++ if (rank_count_dimm0 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ }
++ if (rank)
++ term = 0x0;
++ }
++ }
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x1;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x1;
++ } else {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
++ term = 0x3;
++ } else {
++ if (rank_count_dimm0 == 4) {
++ if (rank_count_dimm1 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ } else if (rank_count_dimm1 == 4) {
++ if (rank_count_dimm0 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ }
++ if (rank)
++ term = 0x0;
++ }
++ }
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x1;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x3;
++ } else {
++ term = 0x5;
++ }
++ } else {
++ /* DDR3-1600 */
++ if (number_of_dimms == 1)
++ term = 0x3;
++ else
++ term = 0x4;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else {
++ /* TODO
++ * Other sockets unimplemented
++ */
+ }
+ } else {
+ /* UDIMM */
+@@ -352,6 +559,53 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t
+ }
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 62 */
++ if (MaxDimmsInstallable == 1) {
++ if ((frequency_index == 0x4) || (frequency_index == 0x6))
++ term = 0x2;
++ else if ((frequency_index == 0xa) || (frequency_index == 0xe))
++ term = 0x1;
++ else
++ term = 0x3;
++ }
++ if (MaxDimmsInstallable == 2) {
++ if (number_of_dimms == 1) {
++ if (frequency_index <= 0x6) {
++ term = 0x2;
++ } else if (frequency_index <= 0xe) {
++ term = 0x1;
++ } else {
++ term = 0x3;
++ }
++ } else {
++ if (frequency_index <= 0xa) {
++ term = 0x3;
++ } else if (frequency_index <= 0xe) {
++ term = 0x5;
++ } else {
++ term = 0x4;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ if (number_of_dimms == 1) {
++ term = 0x0;
++ } else if (number_of_dimms == 2) {
++ if (frequency_index <= 0xa) {
++ if (rank == 1) {
++ term = 0x0;
++ } else {
++ term = 0x3;
++ }
++ } else if (frequency_index <= 0xe) {
++ if (rank == 1) {
++ term = 0x0;
++ } else {
++ term = 0x5;
++ }
++ }
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+--
+2.1.4
+