summaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake/meminit.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2018-04-18 23:07:44 -0600
committerAaron Durbin <adurbin@chromium.org>2018-04-25 19:56:22 +0000
commita695a736b4b8a9549e3384b4ec66b148f547d16c (patch)
tree91e0b87b11f981bdbf3191b32e30708a919cf165 /src/soc/intel/apollolake/meminit.c
parentf8744425537f09738a153c8368364070be559f20 (diff)
downloadcoreboot-a695a736b4b8a9549e3384b4ec66b148f547d16c.tar.xz
soc/intel/apollake: add support for tracking memory details
It's going to be necessary to know the i/o hole size as well the amount of memory configured in the sytsem. Therefore, add two helper functions: memory_in_system_in_mib() iohole_in_mib() Both return values in units of MiB. BUG=b:72728953 Change-Id: I481ba517c37f769e76d9e12b3631f5f99b5427a9 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/25738 Reviewed-by: Lijian Zhao <lijian.zhao@intel.com> Reviewed-by: Hannah Williams <hannah.williams@intel.com> Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/intel/apollolake/meminit.c')
-rw-r--r--src/soc/intel/apollolake/meminit.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/soc/intel/apollolake/meminit.c b/src/soc/intel/apollolake/meminit.c
index ca9d742ae5..b0a5f4a534 100644
--- a/src/soc/intel/apollolake/meminit.c
+++ b/src/soc/intel/apollolake/meminit.c
@@ -12,6 +12,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+#include <arch/early_variables.h>
#include <console/console.h>
#include <fsp/util.h>
#include <memory_info.h>
@@ -20,6 +21,54 @@
#include <fsp/soc_binding.h>
#include <string.h>
+static size_t memory_size_mib CAR_GLOBAL;
+
+size_t memory_in_system_in_mib(void)
+{
+ return car_get_var(memory_size_mib);
+}
+
+static void accumulate_channel_memory(int density, int dual_rank)
+{
+ /* For this platform LPDDR4 memory is 4 DRAM parts that are x32. 2 of
+ the parts are composed into a x64 memory channel. Thus there are 2
+ channels composed of 2 DRAMs. */
+ size_t sz;
+
+ /* Per rank density in Gb */
+ switch (density) {
+ case LP4_8Gb_DENSITY:
+ sz = 8;
+ break;
+ case LP4_12Gb_DENSITY:
+ sz = 12;
+ break;
+ case LP4_16Gb_DENSITY:
+ sz = 16;
+ break;
+ default:
+ printk(BIOS_ERR, "Invalid DRAM density: %d\n", density);
+ sz = 0;
+ break;
+ }
+
+ /* Two DRAMs per channel. */
+ sz *= 2;
+
+ /* Two ranks per channel. */
+ if (dual_rank)
+ sz *= 2;
+
+ sz *= GiB / MiB;
+
+ car_set_var(memory_size_mib, car_get_var(memory_size_mib) + sz);
+}
+
+size_t iohole_in_mib(void)
+{
+ return 2 * (GiB / MiB);
+}
+
static void set_lpddr4_defaults(FSP_M_CONFIG *cfg)
{
/* Enable memory down BGA since it's the only LPDDR4 packaging. */
@@ -35,8 +84,8 @@ static void set_lpddr4_defaults(FSP_M_CONFIG *cfg)
cfg->DualRankSupportEnable = 1;
/* Don't enforce a memory size limit. */
cfg->MemorySizeLimit = 0;
- /* Use a 2GiB I/O hole -- field is in MiB units. */
- cfg->LowMemoryMaxValue = 2 * (GiB/MiB);
+ /* Field is in MiB units. */
+ cfg->LowMemoryMaxValue = iohole_in_mib();
/* No restrictions on memory above 4GiB */
cfg->HighMemoryMaxValue = 0;
@@ -268,8 +317,9 @@ void meminit_lpddr4_enable_channel(FSP_M_CONFIG *cfg, int logical_chan,
break;
default:
printk(BIOS_ERR, "Invalid logical channel: %d\n", logical_chan);
- break;
+ return;
}
+ accumulate_channel_memory(rank_density, dual_rank);
}
void meminit_lpddr4_by_sku(FSP_M_CONFIG *cfg,