mediatek/mt8183: Add DDR driver of runtime config part
BUG=b:80501386 BRANCH=none TEST=Boots correctly on Kukui, and inits DRAM successfully with related patches. Change-Id: Id1e8862ff6feb9628d37fe5300780ff56865a563 Signed-off-by: Huayang Duan <huayang.duan@mediatek.com> Reviewed-on: https://review.coreboot.org/c/28844 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org>
This commit is contained in:
parent
6202d1b51a
commit
7b78a805da
|
@ -16,6 +16,7 @@
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <soc/emi.h>
|
#include <soc/emi.h>
|
||||||
|
#include <soc/spm.h>
|
||||||
#include <soc/dramc_register.h>
|
#include <soc/dramc_register.h>
|
||||||
#include <soc/dramc_pi_api.h>
|
#include <soc/dramc_pi_api.h>
|
||||||
|
|
||||||
|
@ -109,3 +110,199 @@ void dramc_sw_impedance(const struct sdram_params *params)
|
||||||
|
|
||||||
clrsetbits_le32(&ch[0].phy.shu[0].ca_dll[1], 0x1f << 16, 0x9 << 16);
|
clrsetbits_le32(&ch[0].phy.shu[0].ca_dll[1], 0x1f << 16, 0x9 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void transfer_pll_to_spm_control(void)
|
||||||
|
{
|
||||||
|
u8 shu_lev = (read32(&ch[0].ao.shustatus) & 0x00000006) >> 1;
|
||||||
|
|
||||||
|
clrsetbits_le32(&mtk_spm->poweron_config_set,
|
||||||
|
(0xffff << 16) | (0x1 << 0),
|
||||||
|
(0xb16 << 16) | (0x1 << 0));
|
||||||
|
|
||||||
|
/* Set SPM pinmux */
|
||||||
|
clrbits_le32(&mtk_spm->pcm_pwr_io_en, (0xff << 0) | (0xff << 16));
|
||||||
|
setbits_le32(&mtk_spm->dramc_dpy_clk_sw_con_sel, 0xffffffff);
|
||||||
|
setbits_le32(&mtk_spm->dramc_dpy_clk_sw_con_sel2, 0xffffffff);
|
||||||
|
|
||||||
|
setbits_le32(&mtk_spm->spm_power_on_val0, (0x1 << 8) | (0xf << 12));
|
||||||
|
setbits_le32(&mtk_spm->spm_s1_mode_ch, 0x3 << 0);
|
||||||
|
|
||||||
|
shu_lev = (shu_lev == 1) ? 2 : 1;
|
||||||
|
clrsetbits_le32(&mtk_spm->spm_power_on_val0, 0x3 << 28, shu_lev << 28);
|
||||||
|
clrsetbits_le32(&mtk_spm->dramc_dpy_clk_sw_con2,
|
||||||
|
0x3 << 2, shu_lev << 2);
|
||||||
|
|
||||||
|
udelay(1);
|
||||||
|
for (size_t chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) {
|
||||||
|
clrbits_le32(&ch[chn].phy.pll1, 0x1 << 31);
|
||||||
|
clrbits_le32(&ch[chn].phy.pll2, 0x1 << 31);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dramc_rx_input_delay_tracking(u8 chn)
|
||||||
|
{
|
||||||
|
/* Enable RX_FIFO macro DIV4 clock CG */
|
||||||
|
write32(&ch[chn].phy.misc_cg_ctrl1, 0xffffffff);
|
||||||
|
|
||||||
|
/* DVS mode to RG mode */
|
||||||
|
for (size_t r = 0; r < 2; r++)
|
||||||
|
for (size_t b = 0; b < 2; b++)
|
||||||
|
clrbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[2], 3 << 30);
|
||||||
|
|
||||||
|
clrsetbits_le32(&ch[chn].phy.b0_rxdvs[0], 0x1 << 19, 0x1 << 9);
|
||||||
|
clrsetbits_le32(&ch[chn].phy.b1_rxdvs[0], 0x1 << 19, 0x1 << 9);
|
||||||
|
|
||||||
|
for (size_t r = 0; r < 2; r++)
|
||||||
|
for (size_t b = 0; b < 2; b++) {
|
||||||
|
/* Track rising and update rising/falling together */
|
||||||
|
clrbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[2],
|
||||||
|
0x1 << 29);
|
||||||
|
clrsetbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[7],
|
||||||
|
(0x3f << 0) | (0x3f << 8) |
|
||||||
|
(0x7f << 16) | (0x7f << 24),
|
||||||
|
(0x0 << 0) | (0x3f << 8) |
|
||||||
|
(0x0 << 16) | (0x7f << 24));
|
||||||
|
clrsetbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[1],
|
||||||
|
(0xffff << 16) | (0xffff << 0),
|
||||||
|
(0x2 << 16) | (0x2 << 0));
|
||||||
|
|
||||||
|
/* DQ/DQS Rx DLY adjustment for tracking mode */
|
||||||
|
clrbits_le32(&ch[chn].phy.r[r].b[b].rxdvs[2],
|
||||||
|
(0x3 << 26) | (0x3 << 24) |
|
||||||
|
(0x3 << 18) | (0x3 << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
clrbits_le32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
|
||||||
|
|
||||||
|
/* Rx DLY tracking setting (Static) */
|
||||||
|
clrsetbits_le32(&ch[chn].phy.b0_rxdvs[0],
|
||||||
|
(0x1 << 29) | (0xf << 4) | (0x1 << 0),
|
||||||
|
(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
|
||||||
|
clrsetbits_le32(&ch[chn].phy.b1_rxdvs[0],
|
||||||
|
(0x1 << 29) | (0xf << 4) | (0x1 << 0),
|
||||||
|
(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
|
||||||
|
|
||||||
|
for (u8 b = 0; b < 2; b++) {
|
||||||
|
clrsetbits_le32(&ch[chn].phy.b[b].dq[9],
|
||||||
|
(0x7 << 28) | (0x7 << 24),
|
||||||
|
(0x1 << 28) | (0x0 << 24));
|
||||||
|
setbits_le32(&ch[chn].phy.b[b].dq[5], 0x1 << 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
setbits_le32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 28) | (0x1 << 31));
|
||||||
|
setbits_le32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31));
|
||||||
|
for (u8 rank = RANK_0; rank < RANK_MAX; rank++)
|
||||||
|
for (u8 b = 0; b < 2; b++)
|
||||||
|
clrsetbits_le32(&ch[chn].phy.r[rank].b[b].rxdvs[2],
|
||||||
|
(0x3 << 30) | (0x1 << 28) | (0x1 << 23),
|
||||||
|
(0x2 << 30) | (0x1 << 28) | (0x1 << 23));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dramc_hw_dqs_gating_tracking(u8 chn)
|
||||||
|
{
|
||||||
|
setbits_le32(&ch[chn].ao.stbcal, (0x3 << 26) | (0x1 << 0));
|
||||||
|
clrsetbits_le32(&ch[chn].ao.stbcal1,
|
||||||
|
(0xffff << 16) | (0x1 << 8) | (0x1 << 6),
|
||||||
|
(0x1 << 16) | (0x1 << 8) | (0x0 << 6));
|
||||||
|
|
||||||
|
clrsetbits_le32(&ch[chn].phy.misc_ctrl0,
|
||||||
|
(0x1 << 24) | (0x1f << 11) | (0xf << 0),
|
||||||
|
(0x1 << 24) | (0x0 << 11) | (0x0 << 0));
|
||||||
|
|
||||||
|
clrbits_le32(&ch[chn].phy.b[0].dq[6], 0x1 << 31);
|
||||||
|
clrbits_le32(&ch[chn].phy.b[1].dq[6], 0x1 << 31);
|
||||||
|
clrbits_le32(&ch[chn].phy.ca_cmd[6], 0x1 << 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dramc_hw_gating_init(void)
|
||||||
|
{
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||||
|
clrbits_le32(&ch[chn].ao.stbcal,
|
||||||
|
(0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
|
||||||
|
setbits_le32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
|
||||||
|
setbits_le32(&ch[chn].phy.misc_ctrl1, 0x1 << 24);
|
||||||
|
|
||||||
|
dramc_hw_dqs_gating_tracking(chn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dramc_impedance_tracking_enable(void)
|
||||||
|
{
|
||||||
|
setbits_le32(&ch[0].phy.misc_ctrl0, 0x1 << 10);
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||||
|
setbits_le32(&ch[chn].ao.impcal, (0x1 << 31) | (0x1 << 29) |
|
||||||
|
(0x1 << 26) | (0x1 << 17) | (0x7 << 11));
|
||||||
|
clrbits_le32(&ch[chn].ao.impcal, 0x1 << 30);
|
||||||
|
setbits_le32(&ch[chn].phy.misc_ctrl0, 0x1 << 18);
|
||||||
|
setbits_le32(&ch[chn].ao.impcal, 0x1 << 19);
|
||||||
|
}
|
||||||
|
setbits_le32(&ch[0].ao.impcal, 0x1 << 14);
|
||||||
|
setbits_le32(&ch[1].ao.refctrl0, 0x1 << 2);
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
|
||||||
|
setbits_le32(&ch[chn].ao.refctrl0, 0x1 << 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dramc_phy_low_power_enable(void)
|
||||||
|
{
|
||||||
|
u32 broadcast_bak = dramc_get_broadcast();
|
||||||
|
dramc_set_broadcast(DRAMC_BROADCAST_OFF);
|
||||||
|
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||||
|
for (size_t b = 0; b < 2; b++) {
|
||||||
|
clrbits_le32(&ch[chn].phy.b[b].dll_fine_tune[2],
|
||||||
|
0x3fffff << 10);
|
||||||
|
write32(&ch[chn].phy.b[b].dll_fine_tune[3], 0x2e800);
|
||||||
|
}
|
||||||
|
clrsetbits_le32(&ch[chn].phy.ca_dll_fine_tune[2],
|
||||||
|
0x3fffff << 10, 0x2 << 10);
|
||||||
|
}
|
||||||
|
write32(&ch[0].phy.ca_dll_fine_tune[3], 0xba000);
|
||||||
|
write32(&ch[1].phy.ca_dll_fine_tune[3], 0x3a000);
|
||||||
|
|
||||||
|
dramc_set_broadcast(broadcast_bak);
|
||||||
|
}
|
||||||
|
void dramc_runtime_config(void)
|
||||||
|
{
|
||||||
|
clrbits_le32(&ch[0].ao.refctrl0, 0x1 << 29);
|
||||||
|
clrbits_le32(&ch[1].ao.refctrl0, 0x1 << 29);
|
||||||
|
|
||||||
|
transfer_pll_to_spm_control();
|
||||||
|
setbits_le32(&mtk_spm->spm_power_on_val0, 0x3 << 25);
|
||||||
|
|
||||||
|
for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
|
||||||
|
dramc_rx_input_delay_tracking(chn);
|
||||||
|
|
||||||
|
dramc_hw_gating_init();
|
||||||
|
dramc_hw_gating_onoff(CHANNEL_A, true);
|
||||||
|
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
|
||||||
|
clrbits_le32(&ch[chn].ao.stbcal2,
|
||||||
|
(0x3 << 4) | (0x3 << 8) | (0x1 << 28));
|
||||||
|
|
||||||
|
clrbits_le32(&ch[0].ao.spcmdctrl, 0x1 << 30);
|
||||||
|
clrbits_le32(&ch[1].ao.spcmdctrl, 0x1 << 30);
|
||||||
|
|
||||||
|
dramc_phy_low_power_enable();
|
||||||
|
dramc_enable_phy_dcm(true);
|
||||||
|
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
|
||||||
|
for (size_t shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
|
||||||
|
clrbits_le32(&ch[chn].ao.shu[shu].dqsg_retry,
|
||||||
|
(0x1 << 1) | (0x3 << 13));
|
||||||
|
|
||||||
|
write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);
|
||||||
|
write32(&ch[1].phy.misc_spm_ctrl0, 0xfbffefff);
|
||||||
|
write32(&ch[0].phy.misc_spm_ctrl2, 0xffffffef);
|
||||||
|
write32(&ch[1].phy.misc_spm_ctrl2, 0x7fffffef);
|
||||||
|
|
||||||
|
dramc_impedance_tracking_enable();
|
||||||
|
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||||
|
clrbits_le32(&ch[chn].ao.spcmdctrl, 0x3 << 28);
|
||||||
|
setbits_le32(&ch[chn].ao.hw_mrr_fun, (0x1 << 0) | (0x1 << 11));
|
||||||
|
clrbits_le32(&ch[0].ao.refctrl0, 0x1 << 18);
|
||||||
|
setbits_le32(&ch[chn].phy.dvfs_emi_clk, 0x1 << 24);
|
||||||
|
setbits_le32(&ch[chn].ao.dvfsdll, 0x1 << 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -190,22 +190,24 @@ static void dramc_write_dbi_onoff(bool on)
|
||||||
(on ? 1 : 0) << SHU1_WODT_DBIWR_SHIFT);
|
(on ? 1 : 0) << SHU1_WODT_DBIWR_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dramc_phy_dcm_disable(u8 chn)
|
static void dramc_phy_dcm_2_channel(u8 chn, bool en)
|
||||||
{
|
{
|
||||||
clrsetbits_le32(&ch[chn].phy.misc_cg_ctrl0,
|
clrsetbits_le32(&ch[chn].phy.misc_cg_ctrl0, (0x3 << 19) | (0x3ff << 8),
|
||||||
(0x1 << 20) | (0x1 << 19) | 0x3ff << 8,
|
((en ? 0 : 0x1) << 19) | ((en ? 0 : 0x1ff) << 9) | (1 << 8));
|
||||||
(0x0 << 20) | (0x1 << 19) | 0x3ff << 8);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
|
for (size_t i = 0; i < DRAM_DFS_SHUFFLE_MAX; i++) {
|
||||||
struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
|
struct ddrphy_ao_shu *shu = &ch[chn].phy.shu[i];
|
||||||
setbits_le32(&shu->b[0].dq[8], 0x1fff << 19);
|
for (size_t b = 0; b < 2; b++)
|
||||||
setbits_le32(&shu->b[1].dq[8], 0x1fff << 19);
|
clrsetbits_le32(&shu->b[b].dq[8], 0x1fff << 19,
|
||||||
|
((en ? 0 : 0x7ff) << 22) | (0x1 << 21) |
|
||||||
|
((en ? 0 : 0x3) << 19));
|
||||||
clrbits_le32(&shu->ca_cmd[8], 0x1fff << 19);
|
clrbits_le32(&shu->ca_cmd[8], 0x1fff << 19);
|
||||||
}
|
}
|
||||||
clrbits_le32(&ch[chn].phy.misc_cg_ctrl5, (0x7 << 16) | (0x7 << 20));
|
clrsetbits_le32(&ch[chn].phy.misc_cg_ctrl5, (0x7 << 16) | (0x7 << 20),
|
||||||
|
((en ? 0x7 : 0) << 16) | ((en ? 0x7 : 0) << 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dramc_enable_phy_dcm(bool en)
|
void dramc_enable_phy_dcm(bool en)
|
||||||
{
|
{
|
||||||
u32 broadcast_bak = dramc_get_broadcast();
|
u32 broadcast_bak = dramc_get_broadcast();
|
||||||
dramc_set_broadcast(DRAMC_BROADCAST_OFF);
|
dramc_set_broadcast(DRAMC_BROADCAST_OFF);
|
||||||
|
@ -250,8 +252,7 @@ static void dramc_enable_phy_dcm(bool en)
|
||||||
clrsetbits_le32(&shu->ca_cmd[7], mask, value);
|
clrsetbits_le32(&shu->ca_cmd[7], mask, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!en)
|
dramc_phy_dcm_2_channel(chn, en);
|
||||||
dramc_phy_dcm_disable(chn);
|
|
||||||
}
|
}
|
||||||
dramc_set_broadcast(broadcast_bak);
|
dramc_set_broadcast(broadcast_bak);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +271,7 @@ static void reset_delay_chain_before_calibration(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dramc_hw_gating_onoff(u8 chn, bool on)
|
void dramc_hw_gating_onoff(u8 chn, bool on)
|
||||||
{
|
{
|
||||||
clrsetbits_le32(&ch[chn].ao.shuctrl2, 0x3 << 14,
|
clrsetbits_le32(&ch[chn].ao.shuctrl2, 0x3 << 14,
|
||||||
(on ? 0x3 : 0) << 14);
|
(on ? 0x3 : 0) << 14);
|
||||||
|
|
|
@ -121,12 +121,9 @@ size_t sdram_size(void)
|
||||||
|
|
||||||
static void set_rank_info_to_conf(const struct sdram_params *params)
|
static void set_rank_info_to_conf(const struct sdram_params *params)
|
||||||
{
|
{
|
||||||
u8 u4value = 0;
|
bool is_dual_rank = (params->emi_cona_val & (0x1 << 17)) != 0;
|
||||||
|
clrsetbits_le32(&ch[0].ao.rstmask, 0x1 << 12,
|
||||||
/* CONA 17th bit 0: Disable dual rank mode
|
(is_dual_rank ? 0 : 1) << 12);
|
||||||
1: Enable dual rank mode */
|
|
||||||
u4value = ((params->emi_cona_val & (0x1 << 17)) >> 17) ? 0 : 1;
|
|
||||||
clrsetbits_le32(&ch[0].ao.arbctl, 0x1 << 12, u4value << 12);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_MRR_pinmux_mapping(void)
|
static void set_MRR_pinmux_mapping(void)
|
||||||
|
@ -271,6 +268,17 @@ static void dramc_init_pre_settings(void)
|
||||||
setbits_le32(&ch[0].phy.misc_ctrl1, 0x1 << 31);
|
setbits_le32(&ch[0].phy.misc_ctrl1, 0x1 << 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dramc_ac_timing_optimize(void)
|
||||||
|
{
|
||||||
|
for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
|
||||||
|
clrsetbits_le32(&ch[chn].ao.shu[0].actim[3],
|
||||||
|
0xff << 16, 0x64 << 16);
|
||||||
|
clrbits_le32(&ch[chn].ao.shu[0].ac_time_05t, 0x1 << 2);
|
||||||
|
clrsetbits_le32(&ch[chn].ao.shu[0].actim[4],
|
||||||
|
0x3ff << 0, 0x77 << 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void init_dram(const struct sdram_params *params)
|
static void init_dram(const struct sdram_params *params)
|
||||||
{
|
{
|
||||||
global_option_init(params);
|
global_option_init(params);
|
||||||
|
@ -288,6 +296,8 @@ static void do_calib(const struct sdram_params *params)
|
||||||
{
|
{
|
||||||
dramc_apply_pre_calibration_config();
|
dramc_apply_pre_calibration_config();
|
||||||
dramc_calibrate_all_channels(params);
|
dramc_calibrate_all_channels(params);
|
||||||
|
dramc_ac_timing_optimize();
|
||||||
|
dramc_runtime_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mt_set_emi(const struct sdram_params *params)
|
void mt_set_emi(const struct sdram_params *params)
|
||||||
|
|
|
@ -118,10 +118,13 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
void dramc_get_rank_size(u64 *dram_rank_size);
|
void dramc_get_rank_size(u64 *dram_rank_size);
|
||||||
|
void dramc_runtime_config(void);
|
||||||
void dramc_set_broadcast(u32 onoff);
|
void dramc_set_broadcast(u32 onoff);
|
||||||
u32 dramc_get_broadcast(void);
|
u32 dramc_get_broadcast(void);
|
||||||
void dramc_init(void);
|
void dramc_init(void);
|
||||||
void dramc_sw_impedance(const struct sdram_params *params);
|
void dramc_sw_impedance(const struct sdram_params *params);
|
||||||
void dramc_apply_pre_calibration_config(void);
|
void dramc_apply_pre_calibration_config(void);
|
||||||
void dramc_calibrate_all_channels(const struct sdram_params *params);
|
void dramc_calibrate_all_channels(const struct sdram_params *params);
|
||||||
|
void dramc_hw_gating_onoff(u8 chn, bool onoff);
|
||||||
|
void dramc_enable_phy_dcm(bool bEn);
|
||||||
#endif /* _DRAMC_PI_API_MT8183_H */
|
#endif /* _DRAMC_PI_API_MT8183_H */
|
||||||
|
|
Loading…
Reference in New Issue