mirror of
https://github.com/CTCaer/hekate.git
synced 2024-11-26 11:42:09 +00:00
sdram: Add MR read request
This commit is contained in:
parent
8c762c52e2
commit
ecb616e411
6 changed files with 158 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
||||||
* arch/arm/mach-tegra/tegra21_emc.h
|
* arch/arm/mach-tegra/tegra21_emc.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
* Copyright (c) 2019-2020, CTCaer.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -664,4 +665,28 @@
|
||||||
#define EMC_PMC_SCRATCH2 0x444
|
#define EMC_PMC_SCRATCH2 0x444
|
||||||
#define EMC_PMC_SCRATCH3 0x448
|
#define EMC_PMC_SCRATCH3 0x448
|
||||||
|
|
||||||
|
#define EMC_STATUS_UPDATE_TIMEOUT 1000
|
||||||
|
|
||||||
|
typedef enum _emc_mr_t
|
||||||
|
{
|
||||||
|
MR5_MAN_ID = 5,
|
||||||
|
MR6_REV_ID1 = 6,
|
||||||
|
MR7_REV_ID2 = 7,
|
||||||
|
MR8_DENSITY = 8,
|
||||||
|
} emc_mr_t;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
EMC_CHAN0 = 0,
|
||||||
|
EMC_CHAN1 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _emc_mr_data_t
|
||||||
|
{
|
||||||
|
u8 dev0_ch0;
|
||||||
|
u8 dev0_ch1;
|
||||||
|
u8 dev1_ch0;
|
||||||
|
u8 dev1_ch1;
|
||||||
|
} emc_mr_data_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,56 @@ static u32 _get_sdram_id()
|
||||||
return sdram_id;
|
return sdram_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)
|
||||||
|
{
|
||||||
|
bool err = true;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)
|
||||||
|
{
|
||||||
|
if (emc_channel)
|
||||||
|
{
|
||||||
|
if (emc_channel != 1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)
|
||||||
|
{
|
||||||
|
err = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (((EMC(reg_offset) & bit_mask) != 0) == updated_state)
|
||||||
|
{
|
||||||
|
err = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _sdram_req_mrr_data(u32 data, bool dual_channel)
|
||||||
|
{
|
||||||
|
EMC(EMC_MRR) = data;
|
||||||
|
_sdram_wait_emc_status(EMC_EMC_STATUS, EMC_STATUS_MRR_DIVLD, true, EMC_CHAN0);
|
||||||
|
if (dual_channel)
|
||||||
|
_sdram_wait_emc_status(EMC_EMC_STATUS, EMC_STATUS_MRR_DIVLD, true, EMC_CHAN1);
|
||||||
|
}
|
||||||
|
|
||||||
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
||||||
|
{
|
||||||
|
emc_mr_data_t data;
|
||||||
|
_sdram_req_mrr_data((1 << 31) | (mrx << 16), EMC_CHAN0);
|
||||||
|
data.dev0_ch0 = EMC(EMC_MRR) & 0xFF;
|
||||||
|
data.dev0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
||||||
|
_sdram_req_mrr_data((1 << 30) | (mrx << 16), EMC_CHAN1);
|
||||||
|
data.dev1_ch0 = EMC(EMC_MRR) & 0xFF;
|
||||||
|
data.dev1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
static void _sdram_config(const sdram_params_t *params)
|
static void _sdram_config(const sdram_params_t *params)
|
||||||
{
|
{
|
||||||
// Program DPD3/DPD4 regs (coldboot path).
|
// Program DPD3/DPD4 regs (coldboot path).
|
||||||
|
@ -91,7 +141,7 @@ break_nosleep:
|
||||||
if (params->emc_clock_source_dll)
|
if (params->emc_clock_source_dll)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
||||||
if (params->clear_clock2_mc1)
|
if (params->clear_clock2_mc1)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
|
||||||
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
||||||
|
|
|
@ -17,11 +17,13 @@
|
||||||
#ifndef _SDRAM_H_
|
#ifndef _SDRAM_H_
|
||||||
#define _SDRAM_H_
|
#define _SDRAM_H_
|
||||||
|
|
||||||
|
#include "emc.h"
|
||||||
#include "sdram_param_t210.h"
|
#include "sdram_param_t210.h"
|
||||||
|
|
||||||
void sdram_init();
|
void sdram_init();
|
||||||
sdram_params_t *sdram_get_params();
|
sdram_params_t *sdram_get_params();
|
||||||
sdram_params_t *sdram_get_params_patched();
|
sdram_params_t *sdram_get_params_patched();
|
||||||
void sdram_lp0_save_params(const void *params);
|
void sdram_lp0_save_params(const void *params);
|
||||||
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* arch/arm/mach-tegra/tegra21_emc.h
|
* arch/arm/mach-tegra/tegra21_emc.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
* Copyright (c) 2019-2020, CTCaer.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -231,6 +232,7 @@
|
||||||
#define EMC_COMP_PAD_SW_CTRL 0x57c
|
#define EMC_COMP_PAD_SW_CTRL 0x57c
|
||||||
#define EMC_REQ_CTRL 0x2b0
|
#define EMC_REQ_CTRL 0x2b0
|
||||||
#define EMC_EMC_STATUS 0x2b4
|
#define EMC_EMC_STATUS 0x2b4
|
||||||
|
#define EMC_STATUS_MRR_DIVLD (1 << 20)
|
||||||
#define EMC_CFG_2 0x2b8
|
#define EMC_CFG_2 0x2b8
|
||||||
#define EMC_CFG_DIG_DLL 0x2bc
|
#define EMC_CFG_DIG_DLL 0x2bc
|
||||||
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
||||||
|
@ -664,4 +666,28 @@
|
||||||
#define EMC_PMC_SCRATCH2 0x444
|
#define EMC_PMC_SCRATCH2 0x444
|
||||||
#define EMC_PMC_SCRATCH3 0x448
|
#define EMC_PMC_SCRATCH3 0x448
|
||||||
|
|
||||||
|
#define EMC_STATUS_UPDATE_TIMEOUT 1000
|
||||||
|
|
||||||
|
typedef enum _emc_mr_t
|
||||||
|
{
|
||||||
|
MR5_MAN_ID = 5,
|
||||||
|
MR6_REV_ID1 = 6,
|
||||||
|
MR7_REV_ID2 = 7,
|
||||||
|
MR8_DENSITY = 8,
|
||||||
|
} emc_mr_t;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
EMC_CHAN0 = 0,
|
||||||
|
EMC_CHAN1 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _emc_mr_data_t
|
||||||
|
{
|
||||||
|
u8 dev0_ch0;
|
||||||
|
u8 dev0_ch1;
|
||||||
|
u8 dev1_ch0;
|
||||||
|
u8 dev1_ch1;
|
||||||
|
} emc_mr_data_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,7 +40,57 @@
|
||||||
|
|
||||||
static u32 _get_sdram_id()
|
static u32 _get_sdram_id()
|
||||||
{
|
{
|
||||||
return (fuse_read_odm(4) & 0x38) >> 3;
|
return ((fuse_read_odm(4) & 0x38) >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)
|
||||||
|
{
|
||||||
|
bool err = true;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)
|
||||||
|
{
|
||||||
|
if (emc_channel)
|
||||||
|
{
|
||||||
|
if (emc_channel != 1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)
|
||||||
|
{
|
||||||
|
err = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (((EMC(reg_offset) & bit_mask) != 0) == updated_state)
|
||||||
|
{
|
||||||
|
err = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _sdram_req_mrr_data(u32 data, bool dual_channel)
|
||||||
|
{
|
||||||
|
EMC(EMC_MRR) = data;
|
||||||
|
_sdram_wait_emc_status(EMC_EMC_STATUS, EMC_STATUS_MRR_DIVLD, true, EMC_CHAN0);
|
||||||
|
if (dual_channel)
|
||||||
|
_sdram_wait_emc_status(EMC_EMC_STATUS, EMC_STATUS_MRR_DIVLD, true, EMC_CHAN1);
|
||||||
|
}
|
||||||
|
|
||||||
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
||||||
|
{
|
||||||
|
emc_mr_data_t data;
|
||||||
|
_sdram_req_mrr_data((1 << 31) | (mrx << 16), EMC_CHAN0);
|
||||||
|
data.dev0_ch0 = EMC(EMC_MRR) & 0xFF;
|
||||||
|
data.dev0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
||||||
|
_sdram_req_mrr_data((1 << 30) | (mrx << 16), EMC_CHAN1);
|
||||||
|
data.dev1_ch0 = EMC(EMC_MRR) & 0xFF;
|
||||||
|
data.dev1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sdram_config(const sdram_params_t *params)
|
static void _sdram_config(const sdram_params_t *params)
|
||||||
|
@ -85,7 +135,7 @@ break_nosleep:
|
||||||
if (params->emc_clock_source_dll)
|
if (params->emc_clock_source_dll)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
||||||
if (params->clear_clock2_mc1)
|
if (params->clear_clock2_mc1)
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
|
||||||
|
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
||||||
|
|
|
@ -17,11 +17,13 @@
|
||||||
#ifndef _SDRAM_H_
|
#ifndef _SDRAM_H_
|
||||||
#define _SDRAM_H_
|
#define _SDRAM_H_
|
||||||
|
|
||||||
|
#include "emc.h"
|
||||||
#include "sdram_param_t210.h"
|
#include "sdram_param_t210.h"
|
||||||
|
|
||||||
void sdram_init();
|
void sdram_init();
|
||||||
sdram_params_t *sdram_get_params();
|
sdram_params_t *sdram_get_params();
|
||||||
sdram_params_t *sdram_get_params_patched();
|
sdram_params_t *sdram_get_params_patched();
|
||||||
void sdram_lp0_save_params(const void *params);
|
void sdram_lp0_save_params(const void *params);
|
||||||
|
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue