freescale/t104xrdb/ddr.c
#include <common.h>
#include <i2c.h>
#include <hwconfig.h>
#include <asm/mmu.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr_dimm_params.h>
#include <asm/fsl_law.h>
#include <asm/mpc85xx_gpio.h>
#include "ddr.h"
DECLARE_GLOBAL_DATA_PTR;
void fsl_ddr_board_options(memctl_options_t *popts,
dimm_params_t *pdimm,
unsigned int ctrl_num)
{
const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
ulong ddr_freq;
if (ctrl_num > 1) {
printf("Not supported controller number %d\n", ctrl_num);
return;
}
if (!pdimm->n_ranks)
return;
pbsp = udimms[0];
/* Get clk_adjust according to the board ddr
* freqency and n_banks specified in board_specific_parameters table.
*/
ddr_freq = get_ddr_freq(0) / 1000000;
while (pbsp->datarate_mhz_high) {
if (pbsp->n_ranks == pdimm->n_ranks &&
(pdimm->rank_density >> 30) >= pbsp->rank_gb) {
if (ddr_freq <= pbsp->datarate_mhz_high) {
popts->clk_adjust = pbsp->clk_adjust;
popts->wrlvl_start = pbsp->wrlvl_start;
popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
goto found;
}
pbsp_highest = pbsp;
}
pbsp++;
}
if (pbsp_highest) {
printf("Error: board specific timing not found\n");
printf("for data rate %lu MT/s\n", ddr_freq);
printf("Trying to use the highest speed (%u) parameters\n",
pbsp_highest->datarate_mhz_high);
popts->clk_adjust = pbsp_highest->clk_adjust;
popts->wrlvl_start = pbsp_highest->wrlvl_start;
popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
} else {
panic("DIMM is not supported by this board");
}
found:
debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
"\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, "
"wrlvl_ctrl_3 0x%x\n",
pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
pbsp->wrlvl_ctl_3);
/*
* Factors to consider for half-strength driver enable:
* - number of DIMMs installed
*/
#ifdef CONFIG_SYS_FSL_DDR4
popts->half_strength_driver_enable = 1;
/* optimize cpo for erratum A-009942 */
popts->cpo_sample = 0x59;
#else
popts->half_strength_driver_enable = 0;
#endif
/*
* Write leveling override
*/
popts->wrlvl_override = 1;
popts->wrlvl_sample = 0xf;
/*
* rtt and rtt_wr override
*/
popts->rtt_override = 0;
/* Enable ZQ calibration */
popts->zq_en = 1;
/* DHC_EN =1, ODT = 75 Ohm */
#ifdef CONFIG_SYS_FSL_DDR4
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_120OHM);
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_120OHM) |
DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
#else
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
#endif
}
#define DATARATE_300MHZ 300000000
#define DATARATE_400MHZ 400000000
#define DATARATE_500MHZ 500000000
#define DATARATE_600MHZ 600000000
#define DATARATE_700MHZ 700000000
#define DATARATE_800MHZ 800000000
#define DATARATE_900MHZ 900000000
#define DATARATE_1000MHZ 1000000000
#define DATARATE_1200MHZ 1200000000
#define DATARATE_1300MHZ 1300000000
#define DATARATE_1400MHZ 1400000000
#define DATARATE_1500MHZ 1500000000
#define DATARATE_1600MHZ 1600000000
#define DATARATE_1700MHZ 1700000000
#define DATARATE_1800MHZ 1800000000
#define DATARATE_1900MHZ 1900000000
#define DATARATE_2000MHZ 2000000000
#define DATARATE_2100MHZ 2100000000
#define DATARATE_2200MHZ 2200000000
#define DATARATE_2300MHZ 2300000000
#define DATARATE_2400MHZ 2400000000
#define SDRAM_CFG_MEM_EN_MASK 0x80000000
/* DDR Controller 1 register values */
#define DDRmc1_CS0_BNDS 0xFF
#define DDRmc1_CS1_BNDS 0x0200023F
#define DDRmc1_CS0_CONFIG 0x80010412
#define DDRmc1_CS1_CONFIG 0x0202
#define DDRmc1_CS0_CONFIG_2 0x00
#define DDRmc1_CS1_CONFIG_2 0x00
#define DDRmc1_CS2_BNDS 0x0240027F
#define DDRmc1_CS3_BNDS 0x028002BF
#define DDRmc1_CS2_CONFIG 0x0202
#define DDRmc1_CS3_CONFIG 0x00010202
#define DDRmc1_CS2_CONFIG_2 0x00
#define DDRmc1_CS3_CONFIG_2 0x00
#define DDRmc1_TIMING_CFG_3 0x01111000
#define DDRmc1_TIMING_CFG_0 0x4055000C
#define DDRmc1_TIMING_CFG_1 0xCCC60E54
#define DDRmc1_TIMING_CFG_2 0x0049111C
#define DDRmc1_SDRAM_CFG 0x05008000
#define DDRmc1_SDRAM_CFG2 0x00401050
#define DDRmc1_MODE_1 0x01010215
#define DDRmc1_MODE_2 0x00
#define DDRmc1_MODE_3 0x00
#define DDRmc1_MODE_4 0x00
#define DDRmc1_MODE_5 0x00
#define DDRmc1_MODE_6 0x00
#define DDRmc1_MODE_7 0x00
#define DDRmc1_MODE_8 0x00
#define DDRmc1_MODE_CONTROL 0x00
#define DDRmc1_INTERVAL 0x18600618
#define DDRmc1_MEM_INIT_VALUE 0xDEADBEEF
#define DDRmc1_CLK_CTRL 0x02800000
#define DDRmc1_INIT_ADDR 0x00
#define DDRmc1_INIT_EXT_ADDR 0x00
#define DDRmc1_TIMING_CFG_4 0x00220001
#define DDRmc1_TIMING_CFG_5 0x05401400
#define DDRmc1_ZQ_CNTL 0x8A090705
#define DDRmc1_WRLVL_CNTL 0x8675F609
#define DDRmc1_WRLVL_CNTL_2 0x00
#define DDRmc1_WRLVL_CNTL_3 0x00
#define DDRmc1_RCW_1 0x00
#define DDRmc1_RCW_2 0x00
#define DDRmc1_CDR_1 0x80040000
#define DDRmc1_CDR_2 0x80040000
#define DDRmc1_SDRAM_CFG_3 0x00
#define DDRmc1_TIMING_CFG_6 0x00
#define DDRmc1_TIMING_CFG_7 0x00
#define DDRmc1_TIMING_CFG_8 0x03115800
#define DDRmc1_DESKEW_CNTL 0x80000000
#define DDRmc1_DQ_MAP0 0x5B65B658
#define DDRmc1_DQ_MAP1 0xD96D96D8
#define DDRmc1_DQ_MAP2 0x5B65B658
#define DDRmc1_DQ_MAP3 0xD8000000
#define DDRmc1_RCW_3 0x00
#define DDRmc1_RCW_4 0x00
#define DDRmc1_RCW_5 0x00
#define DDRmc1_RCW_6 0x00
#define DDRmc1_MODE_9 0x0500
#define DDRmc1_MODE_10 0x04000000
#define DDRmc1_MODE_11 0x00
#define DDRmc1_MODE_12 0x00
#define DDRmc1_MODE_13 0x00
#define DDRmc1_MODE_14 0x00
#define DDRmc1_MODE_15 0x00
#define DDRmc1_MODE_16 0x00
#define DDRmc1_ERR_DISABLE 0x00
#define DDRmc1_ERR_INT_EN 0x00
#define DDRmc1_ERR_SBE 0x00010000
#ifndef CONFIG_SYS_DDR_RAW_TIMING
fsl_ddr_cfg_regs_t ddr_cfg_regs_1600 = {
.cs[0].bnds = 0x7F,
.cs[1].bnds = 0x008000BF,
.cs[2].bnds = 0x0100013F,
.cs[3].bnds = 0x0140017F,
.cs[0].config = 0x80010422,
.cs[0].config_2 = 0,
.cs[1].config = 0x0202,
.cs[1].config_2 = 0,
.cs[2].config = 0x0202,
.cs[2].config_2 = 0,
.cs[3].config = 0x00010202,
.cs[3].config_2 = 0,
.timing_cfg_3 = 0x02111000,
.timing_cfg_0 = 0x6055000C,
.timing_cfg_1 = 0xB3B40F56,
.timing_cfg_2 = 0x0048D118,
.ddr_sdram_cfg = 0x05008000,
.ddr_sdram_cfg_2 = 0x00401052,
.ddr_sdram_cfg_3 = 0,
.ddr_sdram_mode = 0x01010411,
.ddr_sdram_mode_2 = 0,
.ddr_sdram_mode_3 = 0,
.ddr_sdram_mode_4 = 0,
.ddr_sdram_mode_5 = 0,
.ddr_sdram_mode_6 = 0,
.ddr_sdram_mode_7 = 0,
.ddr_sdram_mode_8 = 0,
.ddr_sdram_mode_9 = 0x0500,
.ddr_sdram_mode_10 = 0x04000000,
.ddr_sdram_mode_11 = 0,
.ddr_sdram_mode_12 = 0,
.ddr_sdram_mode_13 = 0,
.ddr_sdram_mode_14 = 0,
.ddr_sdram_mode_15 = 0,
.ddr_sdram_mode_16 = 0,
.ddr_sdram_interval = 0x18600618,
.ddr_data_init = 0xDEADBEEF,
.ddr_sdram_clk_cntl = 0x02800000,
.ddr_init_addr = 0,
.ddr_init_ext_addr = 0,
.timing_cfg_4 = 0x00220001,
.timing_cfg_5 = 0x05401400,
.timing_cfg_6 = 0,
.timing_cfg_7 = 0x20000000,
.timing_cfg_8 = 0x03114400,
.timing_cfg_9 = 0,
.ddr_zq_cntl = 0x8A090705,
.ddr_wrlvl_cntl = 0x8675F609,
.ddr_wrlvl_cntl_2 = 0x00,
.ddr_wrlvl_cntl_3 = 0x00,
.ddr_sr_cntr = 0x80000000,
.ddr_sdram_rcw_1 = 0,
.ddr_sdram_rcw_2 = 0,
.ddr_cdr1 = 0x80040000,
.ddr_cdr2 = 0x80040000,
.dq_map_0 = 0x00,
.dq_map_1 = 0x00,
.dq_map_2 = 0x00,
.dq_map_3 = 0x00,
//.debug[28] = 0x00700046,
// .cs[0].bnds = DDRmc1_CS0_BNDS,
// .cs[1].bnds = DDRmc1_CS1_BNDS,
// .cs[0].config = DDRmc1_CS0_CONFIG,
// .cs[1].config = DDRmc1_CS1_CONFIG,
// .cs[0].config_2 = DDRmc1_CS0_CONFIG_2,
// .cs[1].config_2 = DDRmc1_CS1_CONFIG_2,
// .cs[2].bnds = DDRmc1_CS2_BNDS,
// .cs[3].bnds = DDRmc1_CS3_BNDS,
// .cs[2].config = DDRmc1_CS2_CONFIG,
// .cs[3].config = DDRmc1_CS3_CONFIG,
// .cs[2].config_2 = DDRmc1_CS2_CONFIG_2,
// .cs[3].config_2 = DDRmc1_CS3_CONFIG_2,
// .timing_cfg_0 = DDRmc1_TIMING_CFG_0,
// .timing_cfg_1 = DDRmc1_TIMING_CFG_1,
// .timing_cfg_2 = DDRmc1_TIMING_CFG_2,
// .timing_cfg_3 = DDRmc1_TIMING_CFG_3,
// .timing_cfg_4 = DDRmc1_TIMING_CFG_4,
// .timing_cfg_5 = DDRmc1_TIMING_CFG_5,
// .timing_cfg_6 = DDRmc1_TIMING_CFG_6,
// .timing_cfg_7 = DDRmc1_TIMING_CFG_7,
// .timing_cfg_8 = DDRmc1_TIMING_CFG_8,
// .sdram_cfg = DDRmc1_SDRAM_CFG,
// .sdram_cfg_2 = DDRmc1_SDRAM_CFG2,
// .sdram_cfg_3 = DDRmc1_SDRAM_CFG_3,// DDRmc1_SDRAM_CFG3
// .sdram_mode = DDRmc1_MODE_1,
// .sdram_mode_2 = DDRmc1_MODE_2,
// .sdram_mode_3 = DDRmc1_MODE_3,
// .sdram_mode_4 = DDRmc1_MODE_4,
// .sdram_mode_5 = DDRmc1_MODE_5,
// .sdram_mode_6 = DDRmc1_MODE_6,
// .sdram_mode_7 = DDRmc1_MODE_7,
// .sdram_mode_8 = DDRmc1_MODE_8,
// .sdram_mode_9 = DDRmc1_MODE_9,
// .sdram_mode_10 = DDRmc1_MODE_10,
// .sdram_mode_11 = DDRmc1_MODE_11,
// .sdram_mode_12 = DDRmc1_MODE_12,
// .sdram_mode_13 = DDRmc1_MODE_13,
// .sdram_mode_14 = DDRmc1_MODE_14,
// .sdram_mode_15 = DDRmc1_MODE_15,
// .sdram_mode_16 = DDRmc1_MODE_16,
// .sdram_md_cntl = DDRmc1_MODE_CONTROL,
// .sdram_interval = DDRmc1_INTERVAL,
// .sdram_data_init = DDRmc1_MEM_INIT_VALUE,
// .sdram_clk_cntl = DDRmc1_CLK_CTRL,
// .init_addr = DDRmc1_INIT_ADDR,
// .init_ext_addr = DDRmc1_INIT_EXT_ADDR,
// .ddr_zq_cntl = DDRmc1_ZQ_CNTL,
// .ddr_wrlvl_cntl = DDRmc1_WRLVL_CNTL,
// .ddr_wrlvl_cntl_2 = DDRmc1_WRLVL_CNTL_2,
// .ddr_wrlvl_cntl_3 = DDRmc1_WRLVL_CNTL_3,
// .ddr_sdram_rcw_1 = DDRmc1_RCW_1,
// .ddr_sdram_rcw_2 = DDRmc1_RCW_2,
// .ddr_sdram_rcw_3 = DDRmc1_RCW_3,
// .ddr_sdram_rcw_4 = DDRmc1_RCW_4,
// .ddr_sdram_rcw_5 = DDRmc1_RCW_5,
// .ddr_sdram_rcw_6 = DDRmc1_RCW_6,
// .deskew_cntl = DDRmc1_DESKEW_CNTL,
// .ddr_cdr1 = DDRmc1_CDR_1,
// .ddr_cdr1 = DDRmc1_CDR_2,
// .err_disable = DDRmc1_ERR_DISABLE,
// .err_int_en = DDRmc1_ERR_INT_EN,
// .err_sbe = DDRmc1_ERR_SBE
};
fixed_ddr_parm_t fixed_ddr_parm_0[] = {
{1550, 1650, &ddr_cfg_regs_1600},
{0, 0, NULL}
};
#endif
/* DDR model number: MT40A512M8HX-093E */
#ifdef CONFIG_SYS_DDR_RAW_TIMING
dimm_params_t ddr_raw_timing = {
.n_ranks = 1,
.rank_density = 2147483648u,
.capacity = 2147483648u,
.primary_sdram_width = 32,
.ec_sdram_width = 0,
.registered_dimm = 0,
.mirrored_dimm = 0,
.n_row_addr = 15,
.n_col_addr = 10,
.bank_addr_bits = 2,
.bank_group_bits = 2,
.edc_config = 0,
.burst_lengths_bitmask = 0x0c,
.tckmin_x_ps = 938,
.tckmax_ps = 1500,
.caslat_x = 0x000DFA00,
.taa_ps = 13500,
.trcd_ps = 13500,
.trp_ps = 13500,
.tras_ps = 33000,
.trc_ps = 46500,
.trfc1_ps = 260000,
.trfc2_ps = 160000,
.trfc4_ps = 110000,
.tfaw_ps = 21000,
.trrds_ps = 3700,
.trrdl_ps = 5300,
.tccdl_ps = 5355,
.refresh_rate_ps = 7800000,
.dq_mapping[0] = 0x0,
.dq_mapping[1] = 0x0,
.dq_mapping[2] = 0x0,
.dq_mapping[3] = 0x0,
.dq_mapping[4] = 0x0,
.dq_mapping[5] = 0x0,
.dq_mapping[6] = 0x0,
.dq_mapping[7] = 0x0,
.dq_mapping[8] = 0x0,
.dq_mapping[9] = 0x0,
.dq_mapping[10] = 0x0,
.dq_mapping[11] = 0x0,
.dq_mapping[12] = 0x0,
.dq_mapping[13] = 0x0,
.dq_mapping[14] = 0x0,
.dq_mapping[15] = 0x0,
.dq_mapping[16] = 0x0,
.dq_mapping[17] = 0x0,
.dq_mapping_ors = 0,
};
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
unsigned int controller_number,
unsigned int dimm_number)
{
static const char dimm_model[] = "Fixed DDR on board";
if (((controller_number == 0) && (dimm_number == 0)) ||
((controller_number == 1) && (dimm_number == 0))) {
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
}
return 0;
}
#else
phys_size_t fixed_sdram(void)
{
int i;
char buf[32];
fsl_ddr_cfg_regs_t ddr_cfg_regs;
phys_size_t ddr_size;
ulong ddr_freq, ddr_freq_mhz;
ddr_freq = get_ddr_freq(0);
ddr_freq_mhz = ddr_freq / 1000000;
printf("Configuring DDR for %s MT/s data rate\n",
strmhz(buf, ddr_freq));
for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) {
if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) &&
(ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) {
memcpy(&ddr_cfg_regs,
fixed_ddr_parm_0[i].ddr_settings,
sizeof(ddr_cfg_regs));
break;
}
}
if (fixed_ddr_parm_0[i].max_freq == 0)
panic("Unsupported DDR data rate %s MT/s data rate\n",
strmhz(buf, ddr_freq));
ddr_size = (phys_size_t)2048 * 1024 * 1024;
fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0, 0);
return ddr_size;
}
#endif
#if defined(CONFIG_DEEP_SLEEP)
void board_mem_sleep_setup(void)
{
void __iomem *cpld_base = (void *)CONFIG_SYS_CPLD_BASE;
/* does not provide HW signals for power management */
clrbits_8(cpld_base + 0x17, 0x40);
/* Disable MCKE isolation */
gpio_set_value(2, 0);
udelay(1);
}
#endif
phys_size_t initdram(int board_type)
{
phys_size_t dram_size;
puts("swh ddr4 init!\r\n");
dram_size = fixed_sdram();
#if 0
#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
puts("Initializing....using SPD\n");
dram_size = fsl_ddr_sdram();
#else
dram_size = fsl_ddr_sdram_size();
#endif
#endif
dram_size = setup_ddr_tlbs(dram_size / 0x100000);
dram_size *= 0x100000;
#if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
fsl_dp_resume();
#endif
return dram_size;
}