mem_chip_info: Update to new format

The original version of the mem_chip_info structure does not record rank
information and does not allow precise modeling of certain DDR
configurations, so it falls short on its purpose to compile all
available memory information. This patch updates the format to a new
layout that remedies these issues. Since the structure was introduced so
recently that no firmware using it has been finalized and shipped yet,
we should be able to get away with this without accounting for backwards
compatibility.

BRANCH=corsola

Cq-Depend: chromium:3980175
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: If34e6857439b6f6ab225344e5b4dd0ff11d8d42a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68871
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Reviewed-by: Xixi Chen <xixi.chen@mediatek.corp-partner.google.com>
diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c
index e420722..0a8f58f 100644
--- a/src/soc/mediatek/common/memory.c
+++ b/src/soc/mediatek/common/memory.c
@@ -112,20 +112,26 @@
 
 static void fill_dram_info(struct mem_chip_info *mc, const struct ddr_base_info *ddr)
 {
-	unsigned int i;
-	size_t size;
+	unsigned int c, r;
 
-	mc->type = MEM_CHIP_LPDDR4X;
-	mc->num_channels = CHANNEL_MAX;
-	size = mtk_dram_size();
-	assert(size);
+	mc->num_entries = CHANNEL_MAX * ddr->mrr_info.rank_nums;
+	mc->struct_version = MEM_CHIP_STRUCT_VERSION;
 
-	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;
+	struct mem_chip_entry *entry = mc->entries;
+	for (c = 0; c < CHANNEL_MAX; c++) {
+		for (r = 0; r < ddr->mrr_info.rank_nums; r++) {
+			entry->channel = c;
+			entry->rank = r;
+			entry->type = MEM_CHIP_LPDDR4X;
+			entry->channel_io_width = DQ_DATA_WIDTH_LP4;
+			entry->density_mbits = ddr->mrr_info.mr8_density[r] / CHANNEL_MAX /
+					       (MiB / 8);
+			entry->io_width = DQ_DATA_WIDTH_LP4;
+			entry->manufacturer_id = ddr->mrr_info.mr5_vendor_id;
+			entry->revision_id[0] = ddr->mrr_info.mr6_revision_id;
+			entry->revision_id[1] = ddr->mrr_info.mr7_revision_id;
+			entry++;
+		}
 	}
 }
 
@@ -140,9 +146,10 @@
 		return;
 	}
 
-	size = sizeof(*mc) + sizeof(struct mem_chip_channel) * CHANNEL_MAX;
+	size = mem_chip_info_size(CHANNEL_MAX * curr_ddr_info->mrr_info.rank_nums);
 	mc = cbmem_add(CBMEM_ID_MEM_CHIP_INFO, size);
 	assert(mc);
+	memset(mc, 0, size);
 
 	fill_dram_info(mc, curr_ddr_info);
 }