-
-
Save openedev/bbfc245cd9727de53bec3005c1fb540f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static int sdram_init(struct dram_info *dram, | |
struct rk3399_sdram_params *sdram_params) | |
{ | |
unsigned char dramtype = sdram_params->base.dramtype; | |
unsigned int ddr_freq = sdram_params->base.ddr_freq; | |
u32 training_flag = PI_READ_GATE_TRAINING; | |
int channel, ch; | |
u32 rank; | |
int ret; | |
debug("Starting SDRAM initialization...\n"); | |
if ((dramtype == DDR3 && ddr_freq > 933) || | |
(dramtype == LPDDR3 && ddr_freq > 933) || | |
(dramtype == LPDDR4 && ddr_freq > 800)) { | |
debug("SDRAM frequency is to high!"); | |
return -E2BIG; | |
} | |
for (ch = 0; ch < 2; ch++) { | |
sdram_params->ch[ch].cap_info.rank = 2; | |
for (rank = 2; rank != 0; rank--) { | |
for (channel = 0; channel < 2; channel++) { | |
const struct chan_info *chan = | |
&dram->chan[channel]; | |
struct rk3399_cru *cru = dram->cru; | |
struct rk3399_ddr_publ_regs *publ = chan->publ; | |
phy_pctrl_reset(cru, channel); | |
phy_dll_bypass_set(publ, ddr_freq); | |
ret = pctl_cfg(dram, chan, channel, | |
sdram_params); | |
if (ret < 0) { | |
printf("%s: Fail to configure pctl\n", | |
__func__); | |
return ret; | |
} | |
/* start to trigger initialization */ | |
pctl_start(dram, sdram_params, channel); | |
printf("\nLOOP0. rank %d, channel %d\n", rank, channel); | |
} | |
/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ | |
if (dramtype == LPDDR3) | |
udelay(10); | |
dram_set_cs(&dram->chan[ch], ((rank == 2) ? 3 : 1), | |
sdram_params->base.dramtype); | |
sdram_params->ch[ch].cap_info.rank = rank; | |
/* | |
* LPDDR3 CA training msut be trigger before | |
* other training. | |
* DDR3 is not have CA training. | |
*/ | |
if (sdram_params->base.dramtype == LPDDR3) | |
training_flag |= PI_CA_TRAINING; | |
printf("\nLOOP1. rank %d, ch %d\n", rank, ch); | |
if (!(data_training(&dram->chan[ch], ch, sdram_params, | |
training_flag))) { | |
printf("Channel %d\n", ch); | |
break; | |
} | |
} | |
sdram_params->ch[ch].cap_info.rank = rank; | |
} | |
sdram_params->base.num_channels = 0; | |
for (channel = 0; channel < 2; channel++) { | |
const struct chan_info *chan = &dram->chan[channel]; | |
struct sdram_cap_info *cap_info = | |
&sdram_params->ch[channel].cap_info; | |
printf("\nLOOP2. rank %d, channel %d\n", cap_info->rank, channel); | |
if (cap_info->rank == 0) { | |
clear_channel_params(sdram_params, 1); | |
continue; | |
} else { | |
sdram_params->base.num_channels++; | |
} | |
printf("Channel "); | |
printf(channel ? "1: " : "0: "); | |
if (channel == 0) | |
set_ddr_stride(dram->pmusgrf, 0x17); | |
else | |
set_ddr_stride(dram->pmusgrf, 0x18); | |
if (dram_detect_cap(dram, sdram_params, channel)) { | |
printf("%s: failed to detect capabilities\n", __func__); | |
continue; | |
} | |
sdram_print_ddr_info(cap_info, &sdram_params->base, 0); | |
set_memory_map(chan, channel, sdram_params); | |
cap_info->ddrconfig = calculate_ddrconfig(sdram_params, | |
channel); | |
if (cap_info->ddrconfig < 0) { | |
printf("%s: ddrconfig not find\n", __func__); | |
continue; | |
} | |
set_ddrconfig(chan, sdram_params, channel, cap_info->ddrconfig); | |
set_cap_relate_config(chan, sdram_params, channel); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment