From fd228e979c37b66111ba1405875b08182c8d993d Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 16 Mar 2018 12:55:58 -0600 Subject: soc/intel/apollolake: handle different memory profiles for apl and glk glk has different memory profile values than apl. Therefore, a translation is required to correctly set the proper profile value depending on what SoC (and therefore FSP) is being used. Based on SOC_INTEL_GLK Kconfig value use different profiles. BUG=b:74932341 Change-Id: I6ea84d3339caf666aea5034ab8f0287bd1915e06 Signed-off-by: Aaron Durbin Reviewed-on: https://review.coreboot.org/25249 Reviewed-by: Justin TerAvest Reviewed-by: Furquan Shaikh Reviewed-by: Sumeet R Pawnikar Tested-by: build bot (Jenkins) --- src/soc/intel/apollolake/meminit.c | 89 ++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 18 deletions(-) (limited to 'src/soc/intel/apollolake') diff --git a/src/soc/intel/apollolake/meminit.c b/src/soc/intel/apollolake/meminit.c index dd8b591a72..ca9d742ae5 100644 --- a/src/soc/intel/apollolake/meminit.c +++ b/src/soc/intel/apollolake/meminit.c @@ -79,29 +79,82 @@ static void set_lpddr4_defaults(FSP_M_CONFIG *cfg) cfg->Ch3_OdtConfig = ODT_A_B_HIGH_HIGH; } -void meminit_lpddr4(FSP_M_CONFIG *cfg, int speed) +struct speed_mapping { + int logical; + int fsp_value; +}; + +struct fsp_speed_profiles { + const struct speed_mapping *mappings; + size_t num_mappings; +}; + +static const struct speed_mapping apl_mappings[] = { + { .logical = LP4_SPEED_1600, .fsp_value = 0x9 }, + { .logical = LP4_SPEED_2133, .fsp_value = 0xa }, + { .logical = LP4_SPEED_2400, .fsp_value = 0xb }, +}; + +static const struct fsp_speed_profiles apl_profile = { + .mappings = apl_mappings, + .num_mappings = ARRAY_SIZE(apl_mappings), +}; + +static const struct speed_mapping glk_mappings[] = { + { .logical = LP4_SPEED_1600, .fsp_value = 0x4 }, + { .logical = LP4_SPEED_2133, .fsp_value = 0x6 }, + { .logical = LP4_SPEED_2400, .fsp_value = 0x7 }, +}; + +static const struct fsp_speed_profiles glk_profile = { + .mappings = glk_mappings, + .num_mappings = ARRAY_SIZE(glk_mappings), +}; + +static const struct fsp_speed_profiles *get_fsp_profile(void) { - uint8_t profile; + if (IS_ENABLED(CONFIG_SOC_INTEL_GLK)) + return &glk_profile; + else + return &apl_profile; +} - switch (speed) { - case LP4_SPEED_1600: - profile = 0x9; - break; - case LP4_SPEED_2133: - profile = 0xa; - break; - case LP4_SPEED_2400: - profile = 0xb; - break; - default: - printk(BIOS_WARNING, "Invalid LPDDR4 speed: %d\n", speed); - /* Set defaults. */ - speed = LP4_SPEED_1600; - profile = 0x9; +static int validate_speed(int speed) +{ + const struct fsp_speed_profiles *fsp_profile = get_fsp_profile(); + size_t i; + + for (i = 0; i < fsp_profile->num_mappings; i++) { + /* Mapping exists. */ + if (fsp_profile->mappings[i].logical == speed) + return speed; + } + + printk(BIOS_WARNING, "Invalid LPDDR4 speed: %d\n", speed); + /* Default to slowest speed */ + return LP4_SPEED_1600; +} + +static int fsp_memory_profile(int speed) +{ + const struct fsp_speed_profiles *fsp_profile = get_fsp_profile(); + size_t i; + + for (i = 0; i < fsp_profile->num_mappings; i++) { + if (fsp_profile->mappings[i].logical == speed) + return fsp_profile->mappings[i].fsp_value; } + /* should never happen. */ + return -1; +} + +void meminit_lpddr4(FSP_M_CONFIG *cfg, int speed) +{ + speed = validate_speed(speed); + printk(BIOS_INFO, "LP4DDR speed is %dMHz\n", speed); - cfg->Profile = profile; + cfg->Profile = fsp_memory_profile(speed); set_lpddr4_defaults(cfg); } -- cgit v1.2.3