1
0
Fork 0
mirror of https://github.com/CTCaer/hekate.git synced 2024-11-26 11:42:09 +00:00

sdram: acquire per chip mrr info

This commit is contained in:
CTCaer 2024-02-12 04:08:39 +02:00
parent e9d2bdb124
commit 4576ed81ef
2 changed files with 40 additions and 13 deletions

View file

@ -712,7 +712,7 @@ enum
EMC_CHAN1 = 1 EMC_CHAN1 = 1
}; };
typedef struct _emc_mr_data_t typedef struct _emc_mr_chip_data_t
{ {
// Device 0. // Device 0.
u8 rank0_ch0; u8 rank0_ch0;
@ -721,6 +721,12 @@ typedef struct _emc_mr_data_t
// Device 1. // Device 1.
u8 rank1_ch0; u8 rank1_ch0;
u8 rank1_ch1; 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; } emc_mr_data_t;
#endif #endif

View file

@ -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 sdram_read_mrx(emc_mr_t mrx)
{ {
emc_mr_data_t data; 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. // Clear left overs.
for (u32 i = 0; i < 32; i++) for (u32 i = 0; i < 16; i++)
{ {
(void)EMC(EMC_MRR); (void)EMC(EMC_MRR);
usleep(1); 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. * 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. * 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). // Get Device 0 (Rank 0) info from both dram chips (channels).
_sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel); _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 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). // Get Device 1 (Rank 1) info from both dram chips (channels).
_sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel); _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); // Ram module 0 info.
} mrr = EMC_CH0(EMC_MRR);
else data.chip0.rank1_ch0 = mrr & 0xFF;
data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
// Ram module 1 info.
if (dual_channel)
{ {
data.rank1_ch0 = 0xFF; mrr = EMC_CH1(EMC_MRR);
data.rank1_ch1 = 0xFF; data.chip1.rank1_ch0 = mrr & 0xFF;
data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
}
} }
return data; return data;