1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "low_level_access.h"
9 #include "mmu500.h"
10 #include "synquacer_config.h"
11 #include "synquacer_ddr.h"
12 #include "synquacer_common.h"
13 #include "synquacer_mmap.h"
14 
15 #include <ddr_init.h>
16 #include <sysdef_option.h>
17 
18 #include <internal/i2c_depend.h>
19 #include <internal/i2c_driver.h>
20 #include <internal/reg_DMA330.h>
21 
22 #include <mod_f_i2c.h>
23 #include <mod_synquacer_memc.h>
24 #include <mod_synquacer_system.h>
25 
26 #include <fwk_assert.h>
27 #include <fwk_log.h>
28 #include <fwk_status.h>
29 
30 #include <inttypes.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <string.h>
34 
35 extern const struct mod_f_i2c_api *f_i2c_api;
36 
37 #define CONFIG_DDR_ERROR_FORCE_STOP
38 
39 #if FWK_LOG_LEVEL <= FWK_LOG_LEVEL_INFO
40 static char *dimm_module_type[] = { "Extended DIMM", "RDIMM",    "UDIMM",
41                                     "SO-DIMM",       "LRDIMM",   "Mini-RDIMM",
42                                     "Mini-UDIMM",    "Reserved", "72b-SO-RDIMM",
43                                     "72b-SO-UDIMM" };
44 #endif
45 
46 typedef struct spd_ddr_info_s {
47     uint8_t base_module_type;
48     uint8_t ddr_memory_type;
49     uint8_t slot_bitmap;
50     uint8_t ddr_memory_used_ch;
51     bool ecc_available;
52     uint8_t rank_address_bits;
53     uint8_t row_address_bits;
54     uint8_t column_address_bits;
55     uint32_t set_memory_type_next;
56     uint32_t dmc_address_control;
57     uint32_t sdram_slot_total[DIMM_SLOT_NUM];
58     uint32_t per_slot_dimm_size;
59     uint32_t dq_map_control[5];
60 } spd_ddr_info_t;
61 
62 static spd_ddr_info_t spd_ddr_info = { 0 };
63 static uint8_t buf[SPD_READ_BYTE_NUM];
64 
65 void sysoc_set_reset(uint32_t sysoc_addr, uint32_t value);
66 int sysoc_wait_status_change(
67     uint32_t sysoc_addr,
68     bool reset_set_flag,
69     uint32_t set_bit);
70 int ddr_ch0_init_mp(void);
71 int ddr_ch1_init_mp(void);
72 static void dram_init_for_ecc(void);
73 
74 typedef enum {
75     SPD_READ_SLOT_AVAILABLE = 0,
76     SPD_READ_SLOT_NONE,
77     SPD_READ_ERROR,
78     SPD_READ_INVALID_PARAM,
79     SPD_READ_SET_PAGE_ADDR_ERROR
80 } spd_read_err_code_t;
81 
82 static uint32_t get_i2c_target_addr_set_page(uint32_t target_page);
83 static spd_read_err_code_t read_spd(
84     uint32_t slot,
85     uint8_t *dst,
86     int32_t total_len);
87 static void store_spd_to_nssram(void);
88 
89 static uint32_t config_ddr4_sdram_total_size;
90 
91 enum ddr_freq_e {
92     DDR_FREQ_1333 = 0,
93     DDR_FREQ_1600,
94     DDR_FREQ_1800,
95     DDR_FREQ_1866,
96     DDR_FREQ_2133,
97     DDR_FREQ_MAX,
98 };
99 
100 typedef enum ddr_freq_e ddr_freq_t;
101 
102 static void fw_ddr_change_freq(ddr_freq_t freq);
103 
fw_ddr_init(void)104 void fw_ddr_init(void)
105 {
106     int result = 0;
107 
108     fw_ddr_change_freq(CONFIG_SCB_DDR_FREQ);
109 
110     if (spd_ddr_info.ddr_memory_used_ch == DDR_USE_CH0)
111         result = ddr_ch0_init_mp();
112     else if (spd_ddr_info.ddr_memory_used_ch == DDR_USE_CH1)
113         result = ddr_ch1_init_mp();
114     else
115         result = ddr_dual_ch_init_mp();
116 
117     if (result != 0) {
118         /* Tentative workaround. Need to implement retrying. */
119         do {
120             FWK_LOG_ERR("DDR Initialize Failed.(0x%x)", result);
121             synquacer_memc_timer_api->delay(
122                 FWK_ID_ELEMENT(FWK_MODULE_IDX_TIMER, 0),
123                 MSEC_TO_USEC(10000));
124         } while (1);
125     }
126 
127     if (fw_get_ddr4_sdram_ecc_available() && dram_ecc_is_enabled()) {
128         FWK_LOG_INFO("[DDR] DRAM ECC enabled");
129         dram_init_for_ecc();
130     } else {
131         FWK_LOG_INFO("[DDR] DRAM ECC disabled");
132     }
133 
134     /*
135      * save SPD information to non-secure SRAM
136      * will be used for system information such as SMBIOS.
137      */
138     store_spd_to_nssram();
139 }
140 
fw_ddr_change_freq(ddr_freq_t freq)141 static void fw_ddr_change_freq(ddr_freq_t freq)
142 {
143     uint32_t value = 0;
144     if (freq >= DDR_FREQ_MAX)
145         return;
146 
147     switch (freq) {
148     case DDR_FREQ_1333:
149         FWK_LOG_INFO("[DDR] 1333MHz");
150         value = 0x00000027U; /* 1333MHz */
151         break;
152     case DDR_FREQ_1600:
153         FWK_LOG_INFO("[DDR] 1600MHz");
154         value = 0x0000002FU; /* 1600MHz */
155         break;
156     case DDR_FREQ_1800:
157         FWK_LOG_INFO("[DDR] 1800MHz");
158         value = 0x00000035U; /* 1800MHz */
159         break;
160     case DDR_FREQ_1866:
161         FWK_LOG_INFO("[DDR] 1866MHz");
162         value = 0x00000037U; /* 1866MHz */
163         break;
164     case DDR_FREQ_2133:
165         FWK_LOG_INFO("[DDR] 2133MHz");
166         value = 0x0000003FU; /* 2133MHz */
167         break;
168     default:
169         FWK_LOG_INFO("[DDR] Invalid DDR frequency");
170         fwk_unexpected();
171     }
172 
173     /* set value */
174     writel(0x48370000, value);
175 
176     /* change freq value kick */
177     writel(0x48370080, 0x00000004);
178 
179     /* wait for change freq done */
180     while (readl(0x48370080) != 0x00000000)
181         ;
182 
183     /* set value */
184     writel(0x48378000, value);
185 
186     /* change freq value kick */
187     writel(0x48378080, 0x00000004);
188 
189     /* wait for change freq done */
190     while (readl(0x48378080) != 0x00000000)
191         ;
192 }
193 
get_i2c_target_addr_set_page(uint32_t target_page)194 static uint32_t get_i2c_target_addr_set_page(uint32_t target_page)
195 {
196     if (target_page == 0)
197         return SPD_DTIC_SPA0;
198     else
199         return SPD_DTIC_SPA1;
200 }
201 
read_spd(uint32_t slot,uint8_t * dst,int32_t total_len)202 static spd_read_err_code_t read_spd(
203     uint32_t slot,
204     uint8_t *dst,
205     int32_t total_len)
206 {
207     I2C_ERR_t i2c_err;
208     uint8_t dummy = 0;
209     int32_t read_len;
210     uint32_t spd_page;
211     uint32_t i2c_target_addr_read_spd;
212     uint32_t i2c_target_addr_set_page;
213 
214     /*
215      * SPD for DDR4 consists of 512 bytes information and it is divided into
216      * two 256 bytes pages.
217      * Setting page address to 0 selects the lower 256 bytes,
218      * Setting it to 1 selects upper 256 bytes.
219      * To set the page address, dummy write to the SPA0/SPA1.
220      */
221 
222     if (total_len > (SPD_PAGE_SIZE * SPD_NUM_OF_PAGE))
223         return SPD_READ_INVALID_PARAM;
224 
225     i2c_target_addr_read_spd = slot + sysdef_option_get_i2c_for_spd_read_addr();
226 
227     for (spd_page = 0; spd_page < SPD_NUM_OF_PAGE; spd_page++) {
228         /* dummy write to switch the spd page */
229         i2c_target_addr_set_page = get_i2c_target_addr_set_page(spd_page);
230         i2c_err = f_i2c_api->send_data(
231             I2C_EN_CH0, i2c_target_addr_set_page, 0, &dummy, sizeof(dummy));
232         if (i2c_err != I2C_ERR_OK)
233             return SPD_READ_SET_PAGE_ADDR_ERROR;
234 
235         read_len = (total_len > SPD_PAGE_SIZE) ? SPD_PAGE_SIZE : total_len;
236 
237         i2c_err = f_i2c_api->recv_data(
238             I2C_EN_CH0, i2c_target_addr_read_spd, 0, dst, read_len);
239         if (i2c_err == I2C_ERR_UNAVAILABLE) {
240             FWK_LOG_INFO("[SYSTEM] slot DIMM%" PRIu32 ": not detected", slot);
241             return SPD_READ_SLOT_NONE;
242         }
243         if (i2c_err != I2C_ERR_OK) {
244             FWK_LOG_INFO(
245                 "[SYSTEM] Error detected while reading the first byte of SPD. "
246                 "target_addr:0x%02" PRIx32 ", errror code = %d",
247                 i2c_target_addr_read_spd,
248                 i2c_err);
249             return SPD_READ_ERROR;
250         }
251 
252         total_len -= read_len;
253         if (total_len <= 0)
254             break;
255 
256         dst += SPD_PAGE_SIZE;
257     }
258 
259     return SPD_READ_SLOT_AVAILABLE;
260 }
261 
fw_spd_ddr_info_get(spd_ddr_info_t * spd_ddr_info_p)262 bool fw_spd_ddr_info_get(spd_ddr_info_t *spd_ddr_info_p)
263 {
264     int i;
265     spd_read_err_code_t i2c_err_check;
266     int check_dimm_slot;
267     bool error_flag = false;
268 
269     spd_ddr_info_p->slot_bitmap = 0;
270     spd_ddr_info_p->base_module_type = 0;
271 
272     for (check_dimm_slot = 0; check_dimm_slot < DIMM_SLOT_NUM;
273          check_dimm_slot++) {
274         /* SPD parameter */
275         uint32_t sdram_capacity, logical_ranks_per_dimm, primary_bus_width,
276             sdram_width, bank_group_bits;
277 
278         /* spd parameter initialize */
279         memset(buf, 0, SPD_READ_BYTE_NUM);
280 
281         i2c_err_check = read_spd(check_dimm_slot, buf, SPD_READ_BYTE_NUM);
282 
283         if (i2c_err_check == SPD_READ_SLOT_NONE)
284             continue;
285 
286         if (i2c_err_check != SPD_READ_SLOT_AVAILABLE) {
287             error_flag = true;
288             return error_flag;
289         }
290 
291         /* check base module type */
292         if ((spd_ddr_info_p->base_module_type != 0) &&
293             (spd_ddr_info_p->base_module_type != (buf[3] & 0x0F))) {
294             /* error! mixed base module memory */
295             FWK_LOG_ERR("[ERROR] use same sdram type!");
296             error_flag = true;
297             return error_flag;
298         } else {
299             spd_ddr_info_p->base_module_type = buf[3] & 0x0F;
300         }
301 
302         /* Bank Group Bits */
303         bank_group_bits = (buf[4] & 0xC0) >> 6;
304         if (bank_group_bits == 0x02)
305             bank_group_bits = 0x03;
306 
307         /* SDRAM capacity */
308         sdram_capacity = buf[4] & 0x0F; /* SPD original data */
309 
310         /* Row Address Bits */
311         spd_ddr_info_p->row_address_bits = ((buf[5] & 0x38) >> 3) + 1;
312 
313         /* Column Address Bits */
314         spd_ddr_info_p->column_address_bits = (buf[5] & 0x07) + 1;
315 
316         /* bus width */
317         sdram_width = buf[12] & 0x03;
318 
319         /* make memory_type_next */
320         spd_ddr_info_p->set_memory_type_next =
321             (bank_group_bits << 16) | (sdram_width << 8) | DRAM_DDR4;
322 
323         logical_ranks_per_dimm = ((buf[12] & 0x38) >> 3) + 1;
324 
325         /* DDR4 package Type check */
326         if ((buf[6] & 0x3) == 0x02 || (buf[6] & 0x3) == 0x03) {
327             FWK_LOG_ERR("[ERROR] not support sdram type!");
328             error_flag = true;
329             return error_flag;
330         }
331         /* Number of Package Ranks per DIMM */
332         spd_ddr_info_p->rank_address_bits = logical_ranks_per_dimm - 1;
333 
334         spd_ddr_info_p->ecc_available = (buf[13] & 0x08) != 0;
335         primary_bus_width = 8 * (1 << (buf[13] & 0x07));
336 
337         /*
338          * Total[MB] = SDRAM Capacity[GB] / 8 * Primary Bus Width /
339          *             SDRAM Width * Logical Ranks per DIMM * 1024[GB->MB]
340          */
341         spd_ddr_info.sdram_slot_total[check_dimm_slot] =
342             (((1 << sdram_capacity) >> 3) * primary_bus_width /
343              (4 * (1 << sdram_width)) * logical_ranks_per_dimm)
344             << 8;
345         spd_ddr_info_p->slot_bitmap |= (1 << check_dimm_slot);
346 
347 #if FWK_LOG_LEVEL <= FWK_LOG_LEVEL_INFO
348         FWK_LOG_INFO(
349             "[SYSTEM] slot DIMM%d: %" PRIu32 "MB %s %s",
350             check_dimm_slot,
351             spd_ddr_info_p->sdram_slot_total[check_dimm_slot],
352             dimm_module_type[spd_ddr_info_p->base_module_type],
353             ((spd_ddr_info_p->ecc_available) ? "ECC" : "non-ECC"));
354 #endif
355 
356         /* dq_map_control data make */
357         for (i = 0; i < 5; i++) {
358             spd_ddr_info_p->dq_map_control[i] = buf[60 + i * 4];
359             spd_ddr_info_p->dq_map_control[i] |= (uint32_t)buf[61 + i * 4] << 8;
360             spd_ddr_info_p->dq_map_control[i] |= (uint32_t)buf[62 + i * 4]
361                 << 16;
362             spd_ddr_info_p->dq_map_control[i] |= (uint32_t)buf[63 + i * 4]
363                 << 24;
364         }
365     }
366     return error_flag;
367 }
368 
fw_spd_rdimm_support_check(spd_ddr_info_t * spd_ddr_info_p)369 bool fw_spd_rdimm_support_check(spd_ddr_info_t *spd_ddr_info_p)
370 {
371     bool error_flag = false;
372 
373     fwk_assert(spd_ddr_info_p->per_slot_dimm_size == FW_MODULE_CAPACITY_16GB);
374 
375     /* !ERROR CHECK! and memory kinds select */
376     /* 16GB module RDIMM */
377     switch (spd_ddr_info_p->slot_bitmap) {
378     /* 4slot */
379     case 0x0FU:
380         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_DUAL_CH;
381         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_2SLOTPERCH;
382         spd_ddr_info_p->rank_address_bits *= 2;
383         break;
384 
385     /* 2slot one side ch1 */
386     case 0x0CU:
387         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH1;
388         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_2SLOTPERCH;
389         spd_ddr_info_p->rank_address_bits *= 2;
390         break;
391 
392     /* 2slot one side ch0 */
393     case 0x03U:
394         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH0;
395         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_2SLOTPERCH;
396         spd_ddr_info_p->rank_address_bits *= 2;
397         break;
398 
399     /* 2slot far side dual ch*/
400     case 0x0AU:
401         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_DUAL_CH;
402         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_1SLOTPERCH;
403         break;
404 
405     /* 1slot ch0 far side */
406     case 0x02U:
407         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH0;
408         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_1SLOTPERCH;
409         break;
410 
411     /* 1slot ch1 far side */
412     case 0x08U:
413         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH1;
414         spd_ddr_info_p->ddr_memory_type = RDIMM_16GBPERSLOT_1SLOTPERCH;
415         break;
416 
417     /* non support dimm slot layout! */
418     default:
419         FWK_LOG_ERR("[ERROR] read spd at sdram non support dimm slot layout!");
420         error_flag = true;
421         return error_flag;
422     }
423 
424     return error_flag;
425 }
426 
fw_spd_udimm_support_check(spd_ddr_info_t * spd_ddr_info_p)427 bool fw_spd_udimm_support_check(spd_ddr_info_t *spd_ddr_info_p)
428 {
429     bool error_flag = false;
430 
431     switch (spd_ddr_info_p->per_slot_dimm_size) {
432     case FW_MODULE_CAPACITY_8GB:
433         spd_ddr_info_p->ddr_memory_type = UDIMM_8GBPERSLOT_1SLOTPERCH;
434         break;
435 
436     case FW_MODULE_CAPACITY_4GB:
437         spd_ddr_info_p->ddr_memory_type = UDIMM_4GBPERSLOT_1SLOTPERCH;
438         break;
439 
440     default:
441         FWK_LOG_ERR("[ERROR] non support capability dimm!");
442         error_flag = true;
443         return error_flag;
444     }
445 
446     switch (spd_ddr_info_p->slot_bitmap) {
447     /* 2slot far side */
448     case 0x0AU:
449         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_DUAL_CH;
450         break;
451 
452     /* 1slot ch0 far side */
453     case 0x02U:
454         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH0;
455         break;
456 
457     /* 1slot ch1 far side */
458     case 0x08U:
459         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH1;
460         break;
461 
462     /* non support dimm slot layout! */
463     default:
464         FWK_LOG_ERR("[ERROR] read spd at sdram non support dimm slot layout!");
465         error_flag = true;
466         return error_flag;
467     }
468     return error_flag;
469 }
470 
fw_spd_72bitsoudimm_support_check(spd_ddr_info_t * spd_ddr_info_p)471 bool fw_spd_72bitsoudimm_support_check(spd_ddr_info_t *spd_ddr_info_p)
472 {
473     bool error_flag = false;
474 
475     switch (spd_ddr_info_p->per_slot_dimm_size) {
476     case FW_MODULE_CAPACITY_16GB:
477         spd_ddr_info_p->ddr_memory_type = SOUDIMM_72BIT_16GBPERSLOT_1SLOTPERCH;
478         break;
479 
480     case FW_MODULE_CAPACITY_8GB:
481         spd_ddr_info_p->ddr_memory_type = SOUDIMM_72BIT_8GBPERSLOT_1SLOTPERCH;
482         break;
483 
484     default:
485         FWK_LOG_ERR("[ERROR] non support capability dimm!");
486         error_flag = true;
487         return error_flag;
488     }
489 
490     switch (spd_ddr_info_p->slot_bitmap) {
491     /* 2slot */
492     case 0x03U:
493         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_DUAL_CH;
494         break;
495 
496     /* 1slot ch1 */
497     case 0x02U:
498         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH1;
499         break;
500 
501     /* 1slot ch0 */
502     case 0x01U:
503         spd_ddr_info_p->ddr_memory_used_ch = DDR_USE_CH0;
504         break;
505 
506     /* non support dimm slot layout! */
507     default:
508         error_flag = true;
509         FWK_LOG_ERR("[ERROR] read spd at sdram non support dimm slot layout!");
510     }
511 
512     return error_flag;
513 }
514 
fw_spd_read_dimm_capacity_check(spd_ddr_info_t * spd_ddr_info_p)515 bool fw_spd_read_dimm_capacity_check(spd_ddr_info_t *spd_ddr_info_p)
516 {
517     int i;
518     bool error_flag = false;
519 
520     spd_ddr_info_p->per_slot_dimm_size = 0;
521     config_ddr4_sdram_total_size = 0;
522 
523     for (i = 0; i < DIMM_SLOT_NUM; i++) {
524         if (spd_ddr_info_p->slot_bitmap & (1 << i)) {
525             if ((spd_ddr_info_p->per_slot_dimm_size != 0) &&
526                 (spd_ddr_info_p->per_slot_dimm_size !=
527                  spd_ddr_info_p->sdram_slot_total[i])) {
528                 FWK_LOG_ERR("[ERROR] Please use same capacity DDR memory!");
529                 error_flag = true;
530                 return error_flag;
531             }
532             spd_ddr_info_p->per_slot_dimm_size =
533                 spd_ddr_info_p->sdram_slot_total[i];
534             config_ddr4_sdram_total_size += spd_ddr_info_p->sdram_slot_total[i];
535         }
536     }
537     return error_flag;
538 }
539 
fw_spd_read_dimm_kinds_check(spd_ddr_info_t * spd_ddr_info_p)540 bool fw_spd_read_dimm_kinds_check(spd_ddr_info_t *spd_ddr_info_p)
541 {
542     bool error_flag = false;
543 
544     /* !ERROR CHECK! and memory kinds select */
545     switch (spd_ddr_info_p->base_module_type) {
546     /* RDIMM */
547     case MODULE_TYPE_RDIMM:
548         error_flag = fw_spd_rdimm_support_check(spd_ddr_info_p);
549         break;
550 
551     /* UDIMM */
552     case MODULE_TYPE_UDIMM:
553         error_flag = fw_spd_udimm_support_check(spd_ddr_info_p);
554         break;
555 
556     /* SODIMM */
557     case MODULE_TYPE_72BITSOUDIMM:
558         error_flag = fw_spd_72bitsoudimm_support_check(spd_ddr_info_p);
559         break;
560 
561     /* other type memory module */
562     default:
563         FWK_LOG_ERR("[ERROR] sdram other type memory module");
564         error_flag = true;
565         return error_flag;
566     }
567 
568     spd_ddr_info_p->dmc_address_control =
569         (uint32_t)(spd_ddr_info_p->rank_address_bits << 24) | BANK_BIT_NEXT |
570         (uint32_t)(spd_ddr_info_p->row_address_bits << 8) |
571         (uint32_t)(spd_ddr_info_p->column_address_bits);
572 
573     return error_flag;
574 }
575 
fw_ddr_spd_param_check(void)576 int fw_ddr_spd_param_check(void)
577 {
578     FWK_LOG_INFO("[SYSTEM] Starting check DRAM");
579 
580     if (fw_spd_ddr_info_get(&spd_ddr_info))
581         return FWK_E_SUPPORT;
582 
583     if (fw_spd_read_dimm_capacity_check(&spd_ddr_info))
584         return FWK_E_SUPPORT;
585 
586     if (fw_spd_read_dimm_kinds_check(&spd_ddr_info))
587         return FWK_E_SUPPORT;
588 
589     FWK_LOG_INFO(
590         "[SYSTEM] Finished check DRAM memory total %" PRIu32 "GB",
591         (config_ddr4_sdram_total_size / 1024));
592 
593     return FWK_SUCCESS;
594 }
595 
fw_get_ddr4_sdram_ecc_available(void)596 bool fw_get_ddr4_sdram_ecc_available(void)
597 {
598     return spd_ddr_info.ecc_available;
599 }
600 
fw_get_used_memory_ch(void)601 uint8_t fw_get_used_memory_ch(void)
602 {
603     return spd_ddr_info.ddr_memory_used_ch;
604 }
605 
fw_get_memory_type_next(void)606 uint32_t fw_get_memory_type_next(void)
607 {
608     return spd_ddr_info.set_memory_type_next;
609 }
610 
fw_get_address_control_next(void)611 uint32_t fw_get_address_control_next(void)
612 {
613     return spd_ddr_info.dmc_address_control;
614 }
615 
fw_get_ddr4_sdram_dq_map_control(uint8_t i)616 uint32_t fw_get_ddr4_sdram_dq_map_control(uint8_t i)
617 {
618     return spd_ddr_info.dq_map_control[i];
619 }
620 
fw_get_ddr4_sdram_total_size(void)621 uint32_t fw_get_ddr4_sdram_total_size(void)
622 {
623     return config_ddr4_sdram_total_size;
624 }
625 
fw_get_memory_type(void)626 uint32_t fw_get_memory_type(void)
627 {
628     return spd_ddr_info.ddr_memory_type;
629 }
630 
631 #define CM3_TO_AP_ADDR(addr) ((addr)-EXTERNAL_DEV_BASE)
632 
633 /* 16MB zero clear*/
dma330_zero_clear(uint32_t inst_start_addr,uint32_t clear_start_addr)634 static void dma330_zero_clear(
635     uint32_t inst_start_addr,
636     uint32_t clear_start_addr)
637 {
638     volatile REG_ST_DMA330_S_t *REG_DMA330_S;
639 
640     REG_DMA330_S = (volatile REG_ST_DMA330_S_t *)CONFIG_SOC_DMA330_REG_BASE;
641 
642     /**
643      * Instruction for DMA330
644      * DMAMOV CCR SB1 SS8 SP3 SC0 DB16 DS128 DP3 DC1
645      *  DMAMOV DAR 0x80000000
646      *  DMALP 256
647      *    DMALP 256
648      *       DMASTZ
649      *    DMALPEND
650      *  DMALPEND
651      *  DMAWMB
652      *  DMASEV 0
653      *  DMAEND
654      */
655     writel(inst_start_addr + 0x000U, 0x430101bcU);
656     writel(inst_start_addr + 0x004U, 0x02bc02feU);
657     writel(inst_start_addr + 0x008U, clear_start_addr);
658     /**
659      * DMA330 0 clear size setting
660      * DMALP(1) 256(1), in loop DMAL 256(0)
661      * 16 * 128bit * 256 * 256 = 16MBytes
662      */
663     writel(inst_start_addr + 0x00cU, 0xff22ff20U);
664     writel(inst_start_addr + 0x010U, 0x38013c0cU);
665     writel(inst_start_addr + 0x014U, 0x00341305U);
666     writel(inst_start_addr + 0x018U, 0xffffff00U);
667     writel(inst_start_addr + 0x01cU, 0xffffffffU);
668 
669     REG_DMA330_S->INTEN = 0xffffffffU;
670 
671     while (REG_DMA330_S->DBGSTATUS != 0) {
672         FWK_LOG_INFO("[SYSTEM] Wait DMA330 busy.");
673         synquacer_memc_timer_api->delay(
674             FWK_ID_ELEMENT(FWK_MODULE_IDX_TIMER, 0),
675             MSEC_TO_USEC(10));
676     }
677 
678     REG_DMA330_S->DBGINST[0] = 0xa2U << 16;
679     REG_DMA330_S->DBGINST[1] = CM3_TO_AP_ADDR(inst_start_addr);
680     REG_DMA330_S->DBGCMD = 0;
681 
682     /* Wait for DMA done */
683     while (REG_DMA330_S->INTMIS == 0) {
684         synquacer_memc_timer_api->delay(
685             FWK_ID_ELEMENT(FWK_MODULE_IDX_TIMER, 0),
686             MSEC_TO_USEC(1));
687     }
688 
689     REG_DMA330_S->INTCLR = 0xffffffffU;
690 }
691 
692 #define REG_DMAB_REG_dma330_boot_manager \
693     (CONFIG_SOC_DMAB_WRAPPER_REG + 0x00000010)
694 #define REG_DMAB_REG_mmu500_wsb_ns_zero_0_s \
695     (CONFIG_SOC_DMAB_WRAPPER_REG + 0x00000118)
696 #define REG_DMAB_REG_mmu500_rsb_ns_zero_0_s \
697     (CONFIG_SOC_DMAB_WRAPPER_REG + 0x00000128)
698 #define REG_DMAB_REG_mmu500_awdomain_zero_s \
699     (CONFIG_SOC_DMAB_WRAPPER_REG + 0x00000110)
700 #define REG_DMAB_REG_mmu500_ardomain_zero_s \
701     (CONFIG_SOC_DMAB_WRAPPER_REG + 0x00000120)
702 
dmab_mmu500_init(uint64_t output_addr)703 static void dmab_mmu500_init(uint64_t output_addr)
704 {
705     uint32_t i;
706     uint32_t page_table_top_ap_addr;
707     uint32_t page_table_top_addr;
708     uint32_t upper_addr;
709     uint32_t lower_addr;
710     MMU500_ContextInfo_t context_info;
711     MMU500_Type_t *p_mmu_dmab;
712     p_mmu_dmab = (MMU500_Type_t *)CONFIG_SOC_DMAB_SMMU_REG_BASE;
713 
714     page_table_top_addr = TRUSTED_RAM_BASE;
715     page_table_top_ap_addr = CM3_TO_AP_ADDR(page_table_top_addr);
716 
717     /* lv1 Excel(TTBR Descriptor address, Level2 Table address) */
718     writel(
719         page_table_top_addr + 0x00000000 + 0x0,
720         3 | (page_table_top_ap_addr + 0x00010000));
721     writel(page_table_top_addr + 0x00000000 + 0x4, 0);
722 
723     /* Input  Address = 0x2e000000 */
724     /* lv2 Excel(Level1 Descriptor address, Level3 Table address) */
725     writel(
726         page_table_top_addr + 0x00010008 + 0x0,
727         3 | (page_table_top_ap_addr + 0x00020000));
728     writel(page_table_top_addr + 0x00010008 + 0x4, 0);
729 
730     /* Input  Address = 0x80000000 */
731     /* lv2 Excel(Level1 Descriptor address, Level3 Table address) */
732     writel(
733         page_table_top_addr + 0x00010020 + 0x0,
734         3 | (page_table_top_ap_addr + 0x00030000));
735     writel(page_table_top_addr + 0x00010020 + 0x4, 0);
736 
737     /* Input  Address = 0x2e000000 */
738     /* Output Address = 0x2e000000 */
739     /* lv3  Excel(Level2 Descriptor address) */
740     upper_addr = 0x00000000;
741     lower_addr = 0x2e000000;
742 
743     /* 0x0000 - 0x0001 ( 64KB *     1 = 64KB : 0x00010000 ) */
744     for (i = 0; i < 0x0001; i++) {
745         writel(
746             page_table_top_addr + 0x00027000 + 0x0 + (i * 0x8),
747             3 | (lower_addr) | (1 << 10) | (1 << 7) | (1 << 6) | (0 << 5) |
748                 (0 << 4) | (0 << 3) | (0 << 2));
749 
750         writel(page_table_top_addr + 0x00027000 + 0x4 + (i * 0x8), upper_addr);
751         lower_addr = (lower_addr + 0x10000);
752     }
753 
754     /* Input  Address = 0x80000000 */
755     /* Output Address = output_addr */
756     /* lv3 Excel(Level2 Descriptor address) */
757     /*    0x00000 - 0x02000 ( 64KB *   8192 = 512MB : 0x200000000     */
758     for (i = 0; i < 0x02000; i++, output_addr += 0x10000) {
759         upper_addr = output_addr >> 32;
760         lower_addr = output_addr;
761 
762         writel(
763             page_table_top_addr + 0x00030000 + 0x0 + (i * 0x8),
764             3 | (lower_addr) | (1 << 10) | (0 << 7) | (1 << 6) | (0 << 5) |
765                 (0 << 4) | (0 << 3) | (1 << 2));
766 
767         writel(page_table_top_addr + 0x00030000 + 0x4 + (i * 0x8), upper_addr);
768     }
769 
770     context_info.stream_match_mask = 0x7c00U;
771     context_info.stream_match_id = 0;
772     context_info.base_addr = (uint64_t)page_table_top_ap_addr;
773 
774     SMMU_s_init(
775         (MMU500_Type_t *)p_mmu_dmab,
776         1,
777         (const MMU500_ContextInfo_t *)&context_info,
778         MMU500_GRANULE_64KB);
779 }
780 
781 #define addr_trans(addr_39_20, size, write) (0)
782 
783 #define DMA330_ERASE_BLOCK_SIZE UINT32_C(0x1000000)
784 
dma330_wrapper_init(void)785 static void dma330_wrapper_init(void)
786 {
787     uint32_t value;
788 
789     /* Change to Non Secure bit0 : 0=Secure */
790     value = readl(REG_DMAB_REG_dma330_boot_manager);
791     writel(REG_DMAB_REG_dma330_boot_manager, value & 0xFFFFFFFE);
792 
793     /* Change to Non Secure bit0 = 0 : mmu500_wsb_ns_zero_0_s */
794     value = readl(REG_DMAB_REG_mmu500_wsb_ns_zero_0_s);
795     writel(REG_DMAB_REG_mmu500_wsb_ns_zero_0_s, value & 0xFFFFFFFE);
796 
797     /* Change to Non Secure bit0 = 0 : mmu500_rsb_ns_zero_0_s */
798     value = readl(REG_DMAB_REG_mmu500_rsb_ns_zero_0_s);
799     writel(REG_DMAB_REG_mmu500_rsb_ns_zero_0_s, value & 0xFFFFFFFE);
800 
801     /* REG_DMAB_REG_mmu500_awdomain_zero_s &= 0xFFFFFFFC; */
802     /* bit1:0 = 2'b00(Non shareable) */
803     value = readl(REG_DMAB_REG_mmu500_awdomain_zero_s);
804     writel(REG_DMAB_REG_mmu500_awdomain_zero_s, value | 0x00000003);
805 
806     /* bit1:0 = 2'b11 : System */
807     value = readl(REG_DMAB_REG_mmu500_ardomain_zero_s);
808     writel(REG_DMAB_REG_mmu500_ardomain_zero_s, value | 0x00000003);
809 }
810 
811 #define TEST_SIZE (1024 * 1024)
dram_init_for_ecc(void)812 static void dram_init_for_ecc(void)
813 {
814     uint64_t dst_ddr_addr, dram_size;
815     uint32_t dma_dst_addr;
816 
817     SMMU_s_disable((MMU500_Type_t *)CONFIG_SOC_DMAB_SMMU_REG_BASE, 1);
818 
819     (void)addr_trans(0x00800U, TEST_SIZE, true);
820     (void)addr_trans(0x008ffU, TEST_SIZE, true);
821     (void)addr_trans(0x00fffU, TEST_SIZE, true);
822     (void)addr_trans(0x08800U, TEST_SIZE, true);
823     (void)addr_trans(0x088ffU, TEST_SIZE, true);
824     (void)addr_trans(0x0ff00U, TEST_SIZE, true);
825     (void)addr_trans(0x0ffffU, TEST_SIZE, true);
826 
827     dram_size = (uint64_t)config_ddr4_sdram_total_size * 1024 * 1024;
828 
829     FWK_LOG_INFO("[DDR] Initializing DRAM for ECC\nNow Initializing[");
830 
831     dma330_wrapper_init();
832 
833     /* 0x00_8000_0000 - 0x00_ffff_ffff */
834     for (dst_ddr_addr = DRAM_AREA_1_START_ADDR, dma_dst_addr = 0x80000000U;
835          (dst_ddr_addr < DRAM_AREA_1_END_ADDR) && (dram_size != 0);
836          dma_dst_addr += DMA330_ERASE_BLOCK_SIZE) {
837         if ((dst_ddr_addr & 0x3fffffffULL) == 0) {
838             FWK_LOG_INFO("[DDR] +");
839         }
840 
841         dma330_zero_clear(0xce000000U, dma_dst_addr);
842         dst_ddr_addr += DMA330_ERASE_BLOCK_SIZE;
843         dram_size -= DMA330_ERASE_BLOCK_SIZE;
844     }
845 
846     /* 0x08_8000_0000 - 0x0f_ffff_ffff */
847     for (dst_ddr_addr = DRAM_AREA_2_START_ADDR, dma_dst_addr = 0x80000000U;
848          (dst_ddr_addr < DRAM_AREA_2_END_ADDR) && (dram_size != 0);
849          dma_dst_addr += DMA330_ERASE_BLOCK_SIZE) {
850         if ((dst_ddr_addr & 0x3fffffffULL) == 0) {
851             FWK_LOG_INFO("[DDR] -");
852         }
853 
854         if ((dst_ddr_addr & 0x1fffffffULL) == 0) {
855             dmab_mmu500_init(dst_ddr_addr);
856             dma_dst_addr = 0x80000000U;
857         }
858 
859         dma330_zero_clear(0xce000000U, dma_dst_addr);
860         dst_ddr_addr += DMA330_ERASE_BLOCK_SIZE;
861         dram_size -= DMA330_ERASE_BLOCK_SIZE;
862     }
863 
864     /* 0x88_0000_0000 - 0x8f_ffff_ffff */
865     for (dst_ddr_addr = DRAM_AREA_3_START_ADDR, dma_dst_addr = 0x80000000U;
866          (dst_ddr_addr < DRAM_AREA_3_END_ADDR) && (dram_size != 0);
867          dma_dst_addr += DMA330_ERASE_BLOCK_SIZE) {
868         if ((dst_ddr_addr & 0x3fffffffULL) == 0) {
869             FWK_LOG_INFO("[DDR] x");
870         }
871 
872         if ((dst_ddr_addr & 0x1fffffffULL) == 0) {
873             dmab_mmu500_init(dst_ddr_addr);
874             dma_dst_addr = 0x80000000U;
875         }
876 
877         dma330_zero_clear(0xce000000U, dma_dst_addr);
878         dst_ddr_addr += DMA330_ERASE_BLOCK_SIZE;
879         dram_size -= DMA330_ERASE_BLOCK_SIZE;
880     }
881 
882     FWK_LOG_INFO("[DDR] Finished initializing DRAM for ECC");
883 
884     (void)addr_trans(0x00800U, TEST_SIZE, false);
885     (void)addr_trans(0x008ffU, TEST_SIZE, false);
886     (void)addr_trans(0x00fffU, TEST_SIZE, false);
887     (void)addr_trans(0x08800U, TEST_SIZE, false);
888     (void)addr_trans(0x088ffU, TEST_SIZE, false);
889     (void)addr_trans(0x0ff00U, TEST_SIZE, false);
890     (void)addr_trans(0x0ffffU, TEST_SIZE, false);
891 
892     SMMU_s_disable((MMU500_Type_t *)CONFIG_SOC_DMAB_SMMU_REG_BASE, 1);
893 
894     /* Clear Secure SRAM */
895     memset((void *)TRUSTED_RAM_BASE, 0, 256 * 1024);
896 }
897 
store_spd_to_nssram(void)898 static void store_spd_to_nssram(void)
899 {
900     uint32_t slot;
901     uint8_t *dst = (uint8_t *)SPD_STORE_ADDR;
902     spd_read_err_code_t ret;
903 
904     memset(dst, 0, SPD_STORE_AREA_SIZE);
905 
906     for (slot = 0; slot < DIMM_SLOT_NUM; slot++) {
907         ret = read_spd(slot, dst, (SPD_PAGE_SIZE * SPD_NUM_OF_PAGE));
908         if (ret != SPD_READ_SLOT_AVAILABLE) {
909             /* clear invalid data */
910             memset(dst, 0, (SPD_PAGE_SIZE * SPD_NUM_OF_PAGE));
911         }
912         dst += (SPD_PAGE_SIZE * SPD_NUM_OF_PAGE);
913     }
914 }
915