diff options
author | Aaron Durbin <adurbin@chromium.org> | 2018-03-16 12:55:58 -0600 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2018-03-17 02:06:08 +0000 |
commit | fd228e979c37b66111ba1405875b08182c8d993d (patch) | |
tree | a1e8e19c55e1325fceba4b47c1c522e091a80ee3 /src/soc | |
parent | a9f49366c09f8902a13221185449a1d0870af1c6 (diff) |
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 <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/25249
Reviewed-by: Justin TerAvest <teravest@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Sumeet R Pawnikar <sumeet.r.pawnikar@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/apollolake/meminit.c | 89 |
1 files changed, 71 insertions, 18 deletions
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); } |