From 4576ed81ef3068379e6f6ba17d8413a9a1f2f47e Mon Sep 17 00:00:00 2001 From: CTCaer Date: Mon, 12 Feb 2024 04:08:39 +0200 Subject: [PATCH] sdram: acquire per chip mrr info --- bdk/mem/emc.h | 8 +++++++- bdk/mem/sdram.c | 45 +++++++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/bdk/mem/emc.h b/bdk/mem/emc.h index e4ff626..24266e2 100644 --- a/bdk/mem/emc.h +++ b/bdk/mem/emc.h @@ -712,7 +712,7 @@ enum EMC_CHAN1 = 1 }; -typedef struct _emc_mr_data_t +typedef struct _emc_mr_chip_data_t { // Device 0. u8 rank0_ch0; @@ -721,6 +721,12 @@ typedef struct _emc_mr_data_t // Device 1. u8 rank1_ch0; u8 rank1_ch1; +} emc_mr_chip_data_t; + +typedef struct _emc_mr_data_t +{ + emc_mr_chip_data_t chip0; + emc_mr_chip_data_t chip1; } emc_mr_data_t; #endif diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index f383aed..868387a 100644 --- a/bdk/mem/sdram.c +++ b/bdk/mem/sdram.c @@ -127,15 +127,19 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel) emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) { emc_mr_data_t data; - u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; + u32 mrr; + bool dual_rank = EMC(EMC_ADR_CFG) & 1; + bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; // Each EMC channel is a RAM chip module. // Clear left overs. - for (u32 i = 0; i < 32; i++) + for (u32 i = 0; i < 16; i++) { (void)EMC(EMC_MRR); usleep(1); } + memset(&data, 0xFF, sizeof(emc_mr_data_t)); + /* * When a dram chip has only one rank, then the info from the 2 ranks differs. * Info not matching is only allowed on different channels. @@ -143,21 +147,38 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) // Get Device 0 (Rank 0) info from both dram chips (channels). _sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel); - data.rank0_ch0 = EMC(EMC_MRR) & 0xFF; - data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); + + // Ram module 0 info. + mrr = EMC_CH0(EMC_MRR); + data.chip0.rank0_ch0 = mrr & 0xFF; + data.chip0.rank0_ch1 = (mrr & 0xFF00 >> 8); + + // Ram module 1 info. + if (dual_channel) + { + mrr = EMC_CH1(EMC_MRR); + data.chip1.rank0_ch0 = mrr & 0xFF; + data.chip1.rank0_ch1 = (mrr & 0xFF00 >> 8); + } // If Rank 1 exists, get info. - if (EMC(EMC_ADR_CFG) & 1) + if (dual_rank) { // Get Device 1 (Rank 1) info from both dram chips (channels). _sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel); - data.rank1_ch0 = EMC(EMC_MRR) & 0xFF; - data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); - } - else - { - data.rank1_ch0 = 0xFF; - data.rank1_ch1 = 0xFF; + + // Ram module 0 info. + mrr = EMC_CH0(EMC_MRR); + data.chip0.rank1_ch0 = mrr & 0xFF; + data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8); + + // Ram module 1 info. + if (dual_channel) + { + mrr = EMC_CH1(EMC_MRR); + data.chip1.rank1_ch0 = mrr & 0xFF; + data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8); + } } return data;