1 /* SPDX-License-Identifier: GPL-2.0-only */
6 #include <console/console.h>
7 #include <ip_checksum.h>
9 #include <soc/dramc_param.h>
11 #include <soc/mmu_operations.h>
15 /* This must be defined in chromeos.fmd in same name and size. */
16 #define CALIBRATION_REGION "RW_MRC_CACHE"
17 #define CALIBRATION_REGION_SIZE 0x2000
19 _Static_assert(sizeof(struct dramc_param
) <= CALIBRATION_REGION_SIZE
,
20 "sizeof(struct dramc_param) exceeds " CALIBRATION_REGION
);
22 const char *get_dram_geometry_str(u32 ddr_geometry
);
23 const char *get_dram_type_str(u32 ddr_type
);
25 static int mt_mem_test(const struct dramc_data
*dparam
)
27 if (CONFIG(MEMORY_TEST
)) {
29 const struct ddr_base_info
*ddr_info
= &dparam
->ddr_info
;
31 for (u8 rank
= RANK_0
; rank
< ddr_info
->support_ranks
; rank
++) {
32 int result
= complex_mem_test(addr
, 0x2000);
36 "[MEM] complex R/W mem test failed: %d\n", result
);
39 printk(BIOS_DEBUG
, "[MEM] rank %u complex R/W mem test passed\n", rank
);
41 addr
+= ddr_info
->rank_size
[rank
];
48 const char *get_dram_geometry_str(u32 ddr_geometry
)
52 switch (ddr_geometry
) {
53 case DDR_TYPE_2CH_2RK_4GB_2_2
:
54 s
= "2CH_2RK_4GB_2_2";
56 case DDR_TYPE_2CH_2RK_6GB_3_3
:
57 s
= "2CH_2RK_6GB_3_3";
59 case DDR_TYPE_2CH_2RK_8GB_4_4
:
60 s
= "2CH_2RK_8GB_4_4";
62 case DDR_TYPE_2CH_2RK_8GB_4_4_BYTE
:
63 s
= "2CH_2RK_8GB_4_4_BYTE";
65 case DDR_TYPE_2CH_1RK_4GB_4_0
:
66 s
= "2CH_1RK_4GB_4_0";
68 case DDR_TYPE_2CH_2RK_6GB_2_4
:
69 s
= "2CH_2RK_6GB_2_4";
79 const char *get_dram_type_str(u32 ddr_type
)
84 case DDR_TYPE_DISCRETE
:
98 static int dram_run_fast_calibration(struct dramc_param
*dparam
)
100 const u16 config
= CONFIG(MEDIATEK_DRAM_DVFS
) ? DRAMC_ENABLE_DVFS
: DRAMC_DISABLE_DVFS
;
101 if (dparam
->dramc_datas
.ddr_info
.config_dvfs
!= config
) {
103 "DRAM-K: Incompatible config for calibration data from flash "
104 "(expected: %#x, saved: %#x)\n",
105 config
, dparam
->dramc_datas
.ddr_info
.config_dvfs
);
109 printk(BIOS_INFO
, "DRAM-K: DRAM calibration data valid pass\n");
110 init_dram_by_params(dparam
);
111 if (mt_mem_test(&dparam
->dramc_datas
) == 0)
114 return DRAMC_ERR_FAST_CALIBRATION
;
117 static int dram_run_full_calibration(struct dramc_param
*dparam
)
119 /* Load and run the provided blob for full-calibration if available */
120 struct prog dram
= PROG_INIT(PROG_REFCODE
, CONFIG_CBFS_PREFIX
"/dram");
122 initialize_dramc_param(dparam
);
123 dump_param_header(dparam
);
125 if (cbfs_prog_stage_load(&dram
)) {
126 printk(BIOS_ERR
, "DRAM-K: CBFS load program failed\n");
130 dparam
->do_putc
= do_putchar
;
132 prog_set_entry(&dram
, prog_entry(&dram
), dparam
);
134 if (dparam
->header
.status
!= DRAMC_SUCCESS
) {
135 printk(BIOS_ERR
, "DRAM-K: Full calibration failed: status = %d\n",
136 dparam
->header
.status
);
140 if (!(dparam
->header
.flags
& DRAMC_FLAG_HAS_SAVED_DATA
)) {
142 "DRAM-K: Full calibration executed without saving parameters. "
143 "Please ensure the blob is built properly.\n");
150 static void mem_init_set_default_config(struct dramc_param
*dparam
,
151 const struct sdram_info
*dram_info
)
154 memset(dparam
, 0, sizeof(*dparam
));
156 type
= dram_info
->ddr_type
;
157 geometry
= dram_info
->ddr_geometry
;
159 dparam
->dramc_datas
.ddr_info
.sdram
.ddr_type
= type
;
161 if (CONFIG(MEDIATEK_DRAM_DVFS
))
162 dparam
->dramc_datas
.ddr_info
.config_dvfs
= DRAMC_ENABLE_DVFS
;
164 dparam
->dramc_datas
.ddr_info
.sdram
.ddr_geometry
= geometry
;
166 printk(BIOS_INFO
, "DRAM-K: ddr_type: %s, config_dvfs: %d, ddr_geometry: %s\n",
167 get_dram_type_str(type
),
168 dparam
->dramc_datas
.ddr_info
.config_dvfs
,
169 get_dram_geometry_str(geometry
));
172 static void mt_mem_init_run(struct dramc_param
*dparam
,
173 const struct sdram_info
*dram_info
)
175 const ssize_t mrc_cache_size
= sizeof(dparam
->dramc_datas
);
180 /* Load calibration params from flash and run fast calibration */
181 mem_init_set_default_config(dparam
, dram_info
);
182 data_size
= mrc_cache_load_current(MRC_TRAINING_DATA
,
183 DRAMC_PARAM_HEADER_VERSION
,
184 &dparam
->dramc_datas
,
186 if (data_size
== mrc_cache_size
) {
187 printk(BIOS_INFO
, "DRAM-K: Running fast calibration\n");
190 ret
= dram_run_fast_calibration(dparam
);
192 printk(BIOS_ERR
, "DRAM-K: Failed to run fast calibration "
193 "in %ld msecs, error: %d\n",
194 stopwatch_duration_msecs(&sw
), ret
);
196 /* Erase flash data after fast calibration failed */
197 memset(&dparam
->dramc_datas
, 0xa5, mrc_cache_size
);
198 if (mrc_cache_stash_data(MRC_TRAINING_DATA
,
199 DRAMC_PARAM_HEADER_VERSION
,
200 &dparam
->dramc_datas
, mrc_cache_size
))
201 printk(BIOS_ERR
, "DRAM-K: Failed to erase "
202 "calibration data\n");
204 printk(BIOS_INFO
, "DRAM-K: Fast calibration passed in %ld msecs\n",
205 stopwatch_duration_msecs(&sw
));
209 printk(BIOS_WARNING
, "DRAM-K: Invalid data in flash (size: %#zx, expected: %#zx)\n",
210 data_size
, mrc_cache_size
);
213 /* Run full calibration */
214 printk(BIOS_INFO
, "DRAM-K: Running full calibration\n");
215 mem_init_set_default_config(dparam
, dram_info
);
218 int err
= dram_run_full_calibration(dparam
);
220 printk(BIOS_INFO
, "DRAM-K: Full calibration passed in %ld msecs\n",
221 stopwatch_duration_msecs(&sw
));
223 if (mrc_cache_stash_data(MRC_TRAINING_DATA
,
224 DRAMC_PARAM_HEADER_VERSION
,
225 &dparam
->dramc_datas
, mrc_cache_size
) == 0)
226 printk(BIOS_DEBUG
, "DRAM-K: Calibration params saved "
227 "to flash: version=%#x, size=%#zx\n",
228 DRAMC_PARAM_HEADER_VERSION
, sizeof(*dparam
));
230 printk(BIOS_ERR
, "DRAM-K: Failed to save calibration "
233 printk(BIOS_ERR
, "DRAM-K: Full calibration failed in %ld msecs\n",
234 stopwatch_duration_msecs(&sw
));
238 void mt_mem_init(struct dramc_param
*dparam
)
240 const struct sdram_info
*sdram_param
= get_sdram_config();
242 mt_mem_init_run(dparam
, sdram_param
);
245 void mtk_dram_init(void)
247 /* dramc_param is too large to fit in stack. */
248 static struct dramc_param dramc_parameter
;
249 mt_mem_init(&dramc_parameter
);
250 mtk_mmu_after_dram();