soc/mediatek: Save dram info to cbmem
Store dram info in cbmem for ramstage or payloads to use.
BUG=b:206014043
TEST=Build pass on Kingler
Signed-off-by: Xi Chen <xixi.chen@mediatek.corp-partner.google.com>
Change-Id: I195187c0c757a43bb6d2c57c8f303249f2a7995a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/61334
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
diff --git a/src/soc/mediatek/common/include/soc/emi.h b/src/soc/mediatek/common/include/soc/emi.h
index 60206d8..0070ec1 100644
--- a/src/soc/mediatek/common/include/soc/emi.h
+++ b/src/soc/mediatek/common/include/soc/emi.h
@@ -6,6 +6,7 @@
#include <soc/dramc_param.h>
size_t sdram_size(void);
+size_t mtk_dram_size(void);
void mt_set_emi(struct dramc_param *dparam);
void mt_mem_init(struct dramc_param *dparam);
void mtk_dram_init(void);
diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c
index 3ca3611..2e460ae 100644
--- a/src/soc/mediatek/common/memory.c
+++ b/src/soc/mediatek/common/memory.c
@@ -3,6 +3,8 @@
#include <assert.h>
#include <bootmode.h>
#include <cbfs.h>
+#include <cbmem.h>
+#include <commonlib/bsd/mem_chip_info.h>
#include <console/console.h>
#include <soc/dramc_common.h>
#include <ip_checksum.h>
@@ -23,6 +25,8 @@
const char *get_dram_geometry_str(u32 ddr_geometry);
const char *get_dram_type_str(u32 ddr_type);
+static const struct ddr_base_info *curr_ddr_info;
+
static int mt_mem_test(const struct dramc_data *dparam)
{
if (CONFIG(MEMORY_TEST)) {
@@ -96,6 +100,49 @@
return s;
}
+size_t mtk_dram_size(void)
+{
+ size_t size = 0;
+
+ if (!curr_ddr_info)
+ return 0;
+ for (unsigned int i = 0; i < RANK_MAX; ++i)
+ size += curr_ddr_info->mrr_info.mr8_density[i];
+ return size;
+}
+
+static void fill_dram_info(struct mem_chip_info *mc, const struct ddr_base_info *ddr)
+{
+ unsigned int i;
+ size_t size;
+
+ mc->type = MEM_CHIP_LPDDR4X;
+ mc->num_channels = CHANNEL_MAX;
+ size = mtk_dram_size();
+ assert(size);
+
+ for (i = 0; i < mc->num_channels; ++i) {
+ mc->channel[i].density = size / mc->num_channels;
+ mc->channel[i].io_width = DQ_DATA_WIDTH_LP4;
+ mc->channel[i].manufacturer_id = ddr->mrr_info.mr5_vendor_id;
+ mc->channel[i].revision_id[0] = ddr->mrr_info.mr6_revision_id;
+ mc->channel[i].revision_id[1] = ddr->mrr_info.mr7_revision_id;
+ }
+}
+
+static void add_mem_chip_info(int unused)
+{
+ struct mem_chip_info *mc;
+ size_t size;
+
+ size = sizeof(*mc) + sizeof(struct mem_chip_channel) * CHANNEL_MAX;
+ mc = cbmem_add(CBMEM_ID_MEM_CHIP_INFO, size);
+ assert(mc);
+
+ fill_dram_info(mc, curr_ddr_info);
+}
+ROMSTAGE_CBMEM_INIT_HOOK(add_mem_chip_info);
+
static int run_dram_blob(struct dramc_param *dparam)
{
/* Load and run the provided blob for full-calibration if available */
@@ -261,5 +308,6 @@
/* dramc_param is too large to fit in stack. */
static struct dramc_param dramc_parameter;
mt_mem_init(&dramc_parameter);
+ curr_ddr_info = &dramc_parameter.dramc_datas.ddr_info;
mtk_mmu_after_dram();
}