Newer
Older
/*
* Copyright Altera Corporation (C) 2012-2015
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/sdram.h>
#include "sequencer.h"
#include "sequencer_auto.h"
#include "sequencer_auto_ac_init.h"
#include "sequencer_auto_inst_init.h"
#include "sequencer_defines.h"
static void scc_mgr_load_dqs_for_write_group(uint32_t write_group);
static struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
(struct socfpga_sdr_rw_load_manager *)(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0x800);
static struct socfpga_sdr_rw_load_jump_manager *sdr_rw_load_jump_mgr_regs =
(struct socfpga_sdr_rw_load_jump_manager *)(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0xC00);
static struct socfpga_sdr_reg_file *sdr_reg_file =
(struct socfpga_sdr_reg_file *)SDR_PHYGRP_REGFILEGRP_ADDRESS;
static struct socfpga_sdr_scc_mgr *sdr_scc_mgr =
(struct socfpga_sdr_scc_mgr *)(SDR_PHYGRP_SCCGRP_ADDRESS | 0xe00);
static struct socfpga_phy_mgr_cmd *phy_mgr_cmd =
(struct socfpga_phy_mgr_cmd *)SDR_PHYGRP_PHYMGRGRP_ADDRESS;
static struct socfpga_phy_mgr_cfg *phy_mgr_cfg =
(struct socfpga_phy_mgr_cfg *)(SDR_PHYGRP_PHYMGRGRP_ADDRESS | 0x40);
static struct socfpga_data_mgr *data_mgr =
(struct socfpga_data_mgr *)SDR_PHYGRP_DATAMGRGRP_ADDRESS;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define DELTA_D 1
/*
* In order to reduce ROM size, most of the selectable calibration steps are
* decided at compile time based on the user's calibration mode selection,
* as captured by the STATIC_CALIB_STEPS selection below.
*
* However, to support simulation-time selection of fast simulation mode, where
* we skip everything except the bare minimum, we need a few of the steps to
* be dynamic. In those cases, we either use the DYNAMIC_CALIB_STEPS for the
* check, which is based on the rtl-supplied value, or we dynamically compute
* the value to use based on the dynamically-chosen calibration mode
*/
#define DLEVEL 0
#define STATIC_IN_RTL_SIM 0
#define STATIC_SKIP_DELAY_LOOPS 0
#define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | \
STATIC_SKIP_DELAY_LOOPS)
/* calibration steps requested by the rtl */
uint16_t dyn_calib_steps;
/*
* To make CALIB_SKIP_DELAY_LOOPS a dynamic conditional option
* instead of static, we use boolean logic to select between
* non-skip and skip values
*
* The mask is set to include all bits when not-skipping, but is
* zero when skipping
*/
uint16_t skip_delay_mask; /* mask off bits when skipping/not-skipping */
#define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
((non_skip_value) & skip_delay_mask)
struct gbl_type *gbl;
struct param_type *param;
uint32_t curr_shadow_reg;
static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
uint32_t write_group, uint32_t use_dm,
uint32_t all_correct, uint32_t *bit_chk, uint32_t all_ranks);
static void set_failing_group_stage(uint32_t group, uint32_t stage,
uint32_t substage)
{
/*
* Only set the global stage if there was not been any other
* failing group
*/
if (gbl->error_stage == CAL_STAGE_NIL) {
gbl->error_substage = substage;
gbl->error_stage = stage;
gbl->error_group = group;
}
}
static void reg_file_set_group(uint32_t set_group)
{
u32 addr = (u32)&sdr_reg_file->cur_stage;
/* Read the current group and stage */
uint32_t cur_stage_group = readl(SOCFPGA_SDR_ADDRESS + addr);
/* Clear the group */
cur_stage_group &= 0x0000FFFF;
/* Set the group */
cur_stage_group |= (set_group << 16);
/* Write the data back */
writel(cur_stage_group, SOCFPGA_SDR_ADDRESS + addr);
}
static void reg_file_set_stage(uint32_t set_stage)
{
u32 addr = (u32)&sdr_reg_file->cur_stage;
/* Read the current group and stage */
uint32_t cur_stage_group = readl(SOCFPGA_SDR_ADDRESS + addr);
/* Clear the stage and substage */
cur_stage_group &= 0xFFFF0000;
/* Set the stage */
cur_stage_group |= (set_stage & 0x000000FF);
/* Write the data back */
writel(cur_stage_group, SOCFPGA_SDR_ADDRESS + addr);
}
static void reg_file_set_sub_stage(uint32_t set_sub_stage)
{
u32 addr = (u32)&sdr_reg_file->cur_stage;
/* Read the current group and stage */
uint32_t cur_stage_group = readl(SOCFPGA_SDR_ADDRESS + addr);
/* Clear the substage */
cur_stage_group &= 0xFFFF00FF;
/* Set the sub stage */
cur_stage_group |= ((set_sub_stage << 8) & 0x0000FF00);
/* Write the data back */
writel(cur_stage_group, SOCFPGA_SDR_ADDRESS + addr);
}
static void initialize(void)
{
u32 addr = (u32)&phy_mgr_cfg->mux_sel;
debug("%s:%d\n", __func__, __LINE__);
/* USER calibration has control over path to memory */
/*
* In Hard PHY this is a 2-bit control:
* 0: AFI Mux Select
* 1: DDIO Mux Select
*/
writel(0x3, SOCFPGA_SDR_ADDRESS + addr);
/* USER memory clock is not stable we begin initialization */
addr = (u32)&phy_mgr_cfg->reset_mem_stbl;
writel(0, SOCFPGA_SDR_ADDRESS + addr);
/* USER calibration status all set to zero */
addr = (u32)&phy_mgr_cfg->cal_status;
writel(0, SOCFPGA_SDR_ADDRESS + addr);
addr = (u32)&phy_mgr_cfg->cal_debug_info;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
writel(0, SOCFPGA_SDR_ADDRESS + addr);
if ((dyn_calib_steps & CALIB_SKIP_ALL) != CALIB_SKIP_ALL) {
param->read_correct_mask_vg = ((uint32_t)1 <<
(RW_MGR_MEM_DQ_PER_READ_DQS /
RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS)) - 1;
param->write_correct_mask_vg = ((uint32_t)1 <<
(RW_MGR_MEM_DQ_PER_READ_DQS /
RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS)) - 1;
param->read_correct_mask = ((uint32_t)1 <<
RW_MGR_MEM_DQ_PER_READ_DQS) - 1;
param->write_correct_mask = ((uint32_t)1 <<
RW_MGR_MEM_DQ_PER_WRITE_DQS) - 1;
param->dm_correct_mask = ((uint32_t)1 <<
(RW_MGR_MEM_DATA_WIDTH / RW_MGR_MEM_DATA_MASK_WIDTH))
- 1;
}
}
static void set_rank_and_odt_mask(uint32_t rank, uint32_t odt_mode)
{
uint32_t odt_mask_0 = 0;
uint32_t odt_mask_1 = 0;
uint32_t cs_and_odt_mask;
uint32_t addr;
if (odt_mode == RW_MGR_ODT_MODE_READ_WRITE) {
if (RW_MGR_MEM_NUMBER_OF_RANKS == 1) {
/*
Loading
Loading full blame...