diff options
Diffstat (limited to 'resources/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch')
-rw-r--r-- | resources/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch | 249 |
1 files changed, 0 insertions, 249 deletions
diff --git a/resources/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch b/resources/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch deleted file mode 100644 index e38f8e57..00000000 --- a/resources/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch +++ /dev/null @@ -1,249 +0,0 @@ -From faabed9ca8974b2e7192c55b59a9d28d75e72df6 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sat, 7 May 2022 16:29:55 +0200 -Subject: [PATCH 12/26] haswell NRI: Post-process selected timings - -Once the MPLL has been initialised, convert the timings from the SPD to -be in DCLKs, which is what the hardware expects. In addition, calculate -the values for tREFI and tXP. - -Change-Id: Id02caf858f75b9e08016762b3aefda282b274386 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../intel/haswell/native_raminit/Makefile.inc | 1 + - .../haswell/native_raminit/lookup_timings.c | 62 +++++++++++ - .../haswell/native_raminit/raminit_main.c | 1 + - .../haswell/native_raminit/raminit_native.h | 8 ++ - .../haswell/native_raminit/spd_bitmunching.c | 100 ++++++++++++++++++ - 5 files changed, 172 insertions(+) - create mode 100644 src/northbridge/intel/haswell/native_raminit/lookup_timings.c - -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -index c125d84f0b..2769e0bbb4 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -@@ -1,5 +1,6 @@ - ## SPDX-License-Identifier: GPL-2.0-or-later - -+romstage-y += lookup_timings.c - romstage-y += init_mpll.c - romstage-y += io_comp_control.c - romstage-y += raminit_main.c -diff --git a/src/northbridge/intel/haswell/native_raminit/lookup_timings.c b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c -new file mode 100644 -index 0000000000..038686c844 ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <commonlib/clamp.h> -+#include <types.h> -+ -+#include "raminit_native.h" -+ -+struct timing_lookup { -+ uint32_t clock; -+ uint32_t value; -+}; -+ -+static uint32_t lookup_timing( -+ const uint32_t mem_clock_mhz, -+ const struct timing_lookup *const lookup, -+ const size_t length) -+{ -+ /* Fall back to the last index */ -+ size_t i; -+ for (i = 0; i < length - 1; i++) { -+ /* Account for imprecise frequency values */ -+ if ((mem_clock_mhz - 5) <= lookup[i].clock) -+ break; -+ } -+ return lookup[i].value; -+} -+ -+static const uint32_t fmax = UINT32_MAX; -+ -+uint8_t get_tCWL(const uint32_t mem_clock_mhz) -+{ -+ const struct timing_lookup lut[] = { -+ { 400, 5 }, -+ { 533, 6 }, -+ { 666, 7 }, -+ { 800, 8 }, -+ { 933, 9 }, -+ { 1066, 10 }, -+ { 1200, 11 }, -+ { fmax, 12 }, -+ }; -+ return lookup_timing(mem_clock_mhz, lut, ARRAY_SIZE(lut)); -+} -+ -+/* tREFI = 7800 ns * DDR MHz */ -+uint32_t get_tREFI(const uint32_t mem_clock_mhz) -+{ -+ return (mem_clock_mhz * 7800) / 1000; -+} -+ -+uint32_t get_tXP(const uint32_t mem_clock_mhz) -+{ -+ const struct timing_lookup lut[] = { -+ { 400, 3 }, -+ { 666, 4 }, -+ { 800, 5 }, -+ { 933, 6 }, -+ { 1066, 7 }, -+ { fmax, 8 }, -+ }; -+ return lookup_timing(mem_clock_mhz, lut, ARRAY_SIZE(lut)); -+} -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 09545422c0..5f2be980d4 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -22,6 +22,7 @@ struct task_entry { - static const struct task_entry cold_boot[] = { - { collect_spd_info, true, "PROCSPD", }, - { initialise_mpll, true, "INITMPLL", }, -+ { convert_timings, true, "CONVTIM", }, - }; - - /* Return a generic stepping value to make stepping checks simpler */ -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index a54581abc7..01e5ed1bd6 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -@@ -78,6 +78,9 @@ struct sysinfo { - uint32_t tCWL; - uint32_t tCMD; - -+ uint32_t tREFI; -+ uint32_t tXP; -+ - uint8_t lanes; /* 8 or 9 */ - uint8_t chanmap; - uint8_t dpc[NUM_CHANNELS]; /* DIMMs per channel */ -@@ -96,7 +99,12 @@ void raminit_main(enum raminit_boot_mode bootmode); - - enum raminit_status collect_spd_info(struct sysinfo *ctrl); - enum raminit_status initialise_mpll(struct sysinfo *ctrl); -+enum raminit_status convert_timings(struct sysinfo *ctrl); - - enum raminit_status wait_for_first_rcomp(void); - -+uint8_t get_tCWL(uint32_t mem_clock_mhz); -+uint32_t get_tREFI(uint32_t mem_clock_mhz); -+uint32_t get_tXP(uint32_t mem_clock_mhz); -+ - #endif -diff --git a/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -index dbe02c72d0..becbea0725 100644 ---- a/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -+++ b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -@@ -204,3 +204,103 @@ enum raminit_status collect_spd_info(struct sysinfo *ctrl) - get_spd_data(ctrl); - return find_common_spd_parameters(ctrl); - } -+ -+#define MIN_CWL 5 -+#define MAX_CWL 12 -+ -+/* Except for tCK, hardware expects all timing values in DCLKs, not nanoseconds */ -+enum raminit_status convert_timings(struct sysinfo *ctrl) -+{ -+ /* -+ * Obtain all required timing values, in DCLKs. -+ */ -+ -+ /* Convert primary timings from nanoseconds to DCLKs */ -+ ctrl->tAA = DIV_ROUND_UP(ctrl->tAA, ctrl->tCK); -+ ctrl->tWR = DIV_ROUND_UP(ctrl->tWR, ctrl->tCK); -+ ctrl->tRCD = DIV_ROUND_UP(ctrl->tRCD, ctrl->tCK); -+ ctrl->tRRD = DIV_ROUND_UP(ctrl->tRRD, ctrl->tCK); -+ ctrl->tRP = DIV_ROUND_UP(ctrl->tRP, ctrl->tCK); -+ ctrl->tRAS = DIV_ROUND_UP(ctrl->tRAS, ctrl->tCK); -+ ctrl->tRC = DIV_ROUND_UP(ctrl->tRC, ctrl->tCK); -+ ctrl->tRFC = DIV_ROUND_UP(ctrl->tRFC, ctrl->tCK); -+ ctrl->tWTR = DIV_ROUND_UP(ctrl->tWTR, ctrl->tCK); -+ ctrl->tRTP = DIV_ROUND_UP(ctrl->tRTP, ctrl->tCK); -+ ctrl->tFAW = DIV_ROUND_UP(ctrl->tFAW, ctrl->tCK); -+ ctrl->tCWL = DIV_ROUND_UP(ctrl->tCWL, ctrl->tCK); -+ ctrl->tCMD = DIV_ROUND_UP(ctrl->tCMD, ctrl->tCK); -+ -+ /* Constrain primary timings to hardware limits */ -+ /** TODO: complain when clamping? **/ -+ ctrl->tAA = clamp_u32(4, ctrl->tAA, 24); -+ ctrl->tWR = clamp_u32(5, ctrl->tWR, 16); -+ ctrl->tRCD = clamp_u32(4, ctrl->tRCD, 20); -+ ctrl->tRRD = clamp_u32(4, ctrl->tRRD, 65535); -+ ctrl->tRP = clamp_u32(4, ctrl->tRP, 15); -+ ctrl->tRAS = clamp_u32(10, ctrl->tRAS, 40); -+ ctrl->tRC = clamp_u32(1, ctrl->tRC, 4095); -+ ctrl->tRFC = clamp_u32(1, ctrl->tRFC, 511); -+ ctrl->tWTR = clamp_u32(4, ctrl->tWTR, 10); -+ ctrl->tRTP = clamp_u32(4, ctrl->tRTP, 15); -+ ctrl->tFAW = clamp_u32(10, ctrl->tFAW, 54); -+ -+ /** TODO: Honor tREFI from XMP **/ -+ ctrl->tREFI = get_tREFI(ctrl->mem_clock_mhz); -+ ctrl->tXP = get_tXP(ctrl->mem_clock_mhz); -+ -+ /* -+ * Check some values, and adjust them if necessary. -+ */ -+ -+ /* If tWR cannot be written into DDR3 MR0, adjust it */ -+ switch (ctrl->tWR) { -+ case 9: -+ case 11: -+ case 13: -+ case 15: -+ ctrl->tWR++; -+ } -+ -+ /* If tCWL is not supported or unspecified, look up a reasonable default */ -+ if (ctrl->tCWL < MIN_CWL || ctrl->tCWL > MAX_CWL) -+ ctrl->tCWL = get_tCWL(ctrl->mem_clock_mhz); -+ -+ /* This is needed to support ODT properly on 2DPC */ -+ if (ctrl->tAA - ctrl->tCWL > 4) -+ ctrl->tCWL = ctrl->tAA - 4; -+ -+ /* If tCMD is invalid, use a guesstimate default */ -+ if (!ctrl->tCMD) { -+ ctrl->tCMD = MAX(ctrl->dpc[0], ctrl->dpc[1]); -+ printk(RAM_DEBUG, "tCMD was zero, picking a guesstimate value\n"); -+ } -+ ctrl->tCMD = clamp_u32(1, ctrl->tCMD, 3); -+ -+ /* -+ * Print final timings. -+ */ -+ -+ /* tCK is special */ -+ printk(BIOS_DEBUG, "Selected tCK : %u ns\n", ctrl->tCK / 256); -+ -+ /* Primary timings */ -+ printk(BIOS_DEBUG, "Selected tAA : %uT\n", ctrl->tAA); -+ printk(BIOS_DEBUG, "Selected tWR : %uT\n", ctrl->tWR); -+ printk(BIOS_DEBUG, "Selected tRCD : %uT\n", ctrl->tRCD); -+ printk(BIOS_DEBUG, "Selected tRRD : %uT\n", ctrl->tRRD); -+ printk(BIOS_DEBUG, "Selected tRP : %uT\n", ctrl->tRP); -+ printk(BIOS_DEBUG, "Selected tRAS : %uT\n", ctrl->tRAS); -+ printk(BIOS_DEBUG, "Selected tRC : %uT\n", ctrl->tRC); -+ printk(BIOS_DEBUG, "Selected tRFC : %uT\n", ctrl->tRFC); -+ printk(BIOS_DEBUG, "Selected tWTR : %uT\n", ctrl->tWTR); -+ printk(BIOS_DEBUG, "Selected tRTP : %uT\n", ctrl->tRTP); -+ printk(BIOS_DEBUG, "Selected tFAW : %uT\n", ctrl->tFAW); -+ printk(BIOS_DEBUG, "Selected tCWL : %uT\n", ctrl->tCWL); -+ printk(BIOS_DEBUG, "Selected tCMD : %uT\n", ctrl->tCMD); -+ -+ /* Derived timings */ -+ printk(BIOS_DEBUG, "Selected tREFI : %uT\n", ctrl->tREFI); -+ printk(BIOS_DEBUG, "Selected tXP : %uT\n", ctrl->tXP); -+ -+ return RAMINIT_STATUS_SUCCESS; -+} --- -2.39.2 - |