summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/mediatek/common/include/soc/emi.h1
-rw-r--r--src/soc/mediatek/common/memory.c48
2 files changed, 49 insertions, 0 deletions
diff --git a/src/soc/mediatek/common/include/soc/emi.h b/src/soc/mediatek/common/include/soc/emi.h
index 60206d8ae7..0070ec1bcd 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 3ca36117e9..2e460ae1bb 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 @@ _Static_assert(sizeof(struct dramc_param) <= CALIBRATION_REGION_SIZE,
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 @@ const char *get_dram_type_str(u32 ddr_type)
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 @@ void mtk_dram_init(void)
/* 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();
}