~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 27eb3ac17357d731f8a958180b13810f7489ccd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) Marvell International Ltd. and its affiliates
 */

#include "ddr3_init.h"
#include "mv_ddr_common.h"

#if defined(CONFIG_DDR4)
static char *ddr_type = "DDR4";
#else /* CONFIG_DDR4 */
static char *ddr_type = "DDR3";
#endif /* CONFIG_DDR4 */

/*
 * generic_init_controller controls D-unit configuration:
 * '1' - dynamic D-unit configuration,
 */
u8 generic_init_controller = 1;

static int mv_ddr_training_params_set(u8 dev_num);

/*
 * Name:     ddr3_init - Main DDR3 Init function
 * Desc:     This routine initialize the DDR3 MC and runs HW training.
 * Args:     None.
 * Notes:
 * Returns:  None.
 */
int ddr3_init(void)
{
	int status;
	int is_manual_cal_done;

	/* Print mv_ddr version */
	mv_ddr_ver_print();

	mv_ddr_pre_training_fixup();

	/* SoC/Board special initializations */
	mv_ddr_pre_training_soc_config(ddr_type);

	/* Set log level for training library */
	mv_ddr_user_log_level_set(DEBUG_BLOCK_ALL);

	mv_ddr_early_init();

	if (mv_ddr_topology_map_update()) {
		printf("mv_ddr: failed to update topology\n");
		return MV_FAIL;
	}

	if (mv_ddr_early_init2() != MV_OK)
		return MV_FAIL;

	/* Set training algorithm's parameters */
	status = mv_ddr_training_params_set(0);
	if (MV_OK != status)
		return status;

	mv_ddr_mc_config();

	is_manual_cal_done = mv_ddr_manual_cal_do();

	mv_ddr_mc_init();

	if (!is_manual_cal_done) {
#if defined(CONFIG_DDR4)
		status = mv_ddr4_calibration_adjust(0, 1, 0);
		if (status != MV_OK) {
			printf("%s: failed (0x%x)\n", __func__, status);
			return status;
		}
#endif
	}


	status = ddr3_silicon_post_init();
	if (MV_OK != status) {
		printf("DDR3 Post Init - FAILED 0x%x\n", status);
		return status;
	}

	/* PHY initialization (Training) */
	status = hws_ddr3_tip_run_alg(0, ALGO_TYPE_DYNAMIC);
	if (MV_OK != status) {
		printf("%s Training Sequence - FAILED\n", ddr_type);
		return status;
	}


	/* Post MC/PHY initializations */
	mv_ddr_post_training_soc_config(ddr_type);

	mv_ddr_post_training_fixup();

	if (mv_ddr_is_ecc_ena())
		mv_ddr_mem_scrubbing();

	printf("mv_ddr: completed successfully\n");

	return MV_OK;
}

/*
 * Name:	mv_ddr_training_params_set
 * Desc:
 * Args:
 * Notes:	sets internal training params
 * Returns:
 */
static int mv_ddr_training_params_set(u8 dev_num)
{
	struct tune_train_params params;
	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
	int status;
	u32 cs_num;
	int ck_delay;

	cs_num = mv_ddr_cs_num_get();
	ck_delay = mv_ddr_ck_delay_get();

	/* NOTE: do not remove any field initilization */
	params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY;
	params.phy_reg3_val = TUNE_TRAINING_PARAMS_PHYREG3VAL;
	params.g_zpri_data = TUNE_TRAINING_PARAMS_PRI_DATA;
	params.g_znri_data = TUNE_TRAINING_PARAMS_NRI_DATA;
	params.g_zpri_ctrl = TUNE_TRAINING_PARAMS_PRI_CTRL;
	params.g_znri_ctrl = TUNE_TRAINING_PARAMS_NRI_CTRL;
	params.g_znodt_data = TUNE_TRAINING_PARAMS_N_ODT_DATA;
	params.g_zpodt_ctrl = TUNE_TRAINING_PARAMS_P_ODT_CTRL;
	params.g_znodt_ctrl = TUNE_TRAINING_PARAMS_N_ODT_CTRL;

#if defined(CONFIG_DDR4)
	params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA_DDR4;
	params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_DDR4;
	params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM_DDR4;
	params.g_dic = TUNE_TRAINING_PARAMS_DIC_DDR4;
	if (cs_num == 1) {
		params.g_rtt_wr =  TUNE_TRAINING_PARAMS_RTT_WR_1CS;
		params.g_rtt_park = TUNE_TRAINING_PARAMS_RTT_PARK_1CS;
	} else {
		params.g_rtt_wr =  TUNE_TRAINING_PARAMS_RTT_WR_2CS;
		params.g_rtt_park = TUNE_TRAINING_PARAMS_RTT_PARK_2CS;
	}
#else /* CONFIG_DDR4 */
	params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA;
	params.g_dic = TUNE_TRAINING_PARAMS_DIC;
	params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM;
	if (cs_num == 1) {
		params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_1CS;
		params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS;
	} else {
		params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_2CS;
		params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS;
	}
#endif /* CONFIG_DDR4 */

	if (ck_delay > 0)
		params.ck_delay = ck_delay;

	/* Use platform specific override ODT value */
	if (tm->odt_config)
		params.g_odt_config = tm->odt_config;

	status = ddr3_tip_tune_training_params(dev_num, &params);
	if (MV_OK != status) {
		printf("%s Training Sequence - FAILED\n", ddr_type);
		return status;
	}

	return MV_OK;
}