blob: 38e2e6a228ce248000ea1c19a2802c255c0e1b6c [file] [log] [blame]
Manoj Kumar58876122021-01-10 16:12:24 +00001/*
Tamas Banf728b612023-05-08 13:50:37 +02002 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
Manoj Kumar58876122021-01-10 16:12:24 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
Manoj Kumar91162752022-06-23 12:30:37 +01008#include <drivers/arm/css/sds.h>
9#include <lib/mmio.h>
Manoj Kumar58876122021-01-10 16:12:24 +000010#include <lib/utils.h>
11#include <plat/arm/common/plat_arm.h>
12
Manoj Kumar91162752022-06-23 12:30:37 +010013#include "morello_def.h"
14#include <platform_def.h>
15
Manoj Kumar58876122021-01-10 16:12:24 +000016#ifdef TARGET_PLATFORM_SOC
Manoj Kumar91162752022-06-23 12:30:37 +010017/*
18 * Morello platform supports RDIMMs with ECC capability. To use the ECC
19 * capability, the entire DDR memory space has to be zeroed out before
20 * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
21 * memory from SCP is quite time consuming so the following function
22 * is added to zero out the DDR memory from application processor which is
23 * much faster compared to SCP.
24 */
25
26static void dmc_ecc_setup(struct morello_plat_info *plat_info)
27{
28 uint64_t dram2_size;
29 uint32_t val;
30 uint64_t tag_mem_base;
31 uint64_t usable_mem_size;
32
33 INFO("Total DIMM size: %uGB\n",
34 (uint32_t)(plat_info->local_ddr_size / 0x40000000));
35
36 assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
37 dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
38
Manoj Kumar58876122021-01-10 16:12:24 +000039 INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
40 zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
41 flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
Manoj Kumar91162752022-06-23 12:30:37 +010042
43 INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
44 ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
45 zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
46 flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
47
48 /* Clear previous ECC errors while zeroing out the memory */
49 val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
50 mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
51
52 val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
53 mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
54
55 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
56 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
57 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
58
59 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
60 MORELLO_DMC_MEMC_STATUS_MASK) !=
61 MORELLO_DMC_MEMC_CMD_CONFIG) {
62 continue;
63 }
64
65 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
66 MORELLO_DMC_MEMC_STATUS_MASK) !=
67 MORELLO_DMC_MEMC_CMD_CONFIG) {
68 continue;
69 }
70
71 /* Configure Bing client/server mode based on SCC configuration */
72 if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
73 INFO("Configuring DMC Bing in client mode\n");
74 usable_mem_size = plat_info->local_ddr_size -
75 (plat_info->local_ddr_size / 128ULL);
76
77 /* Linear DDR address */
78 tag_mem_base = usable_mem_size;
79 tag_mem_base = tag_mem_base / 4;
80
81 /* Reverse translation */
82 if (tag_mem_base < ARM_DRAM1_BASE) {
83 tag_mem_base += ARM_DRAM1_BASE;
84 } else {
85 tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
86 ARM_DRAM2_BASE;
87 }
88
89 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
90 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
91 mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
92 mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
93
94 if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
95 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
96 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
97 INFO("C1 Tag Cache Enabled\n");
98 }
99
100 if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
101 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
102 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
103 INFO("C2 Tag Cache Enabled\n");
104 }
105
106 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
107 (uint32_t)tag_mem_base);
108 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
109 (uint32_t)tag_mem_base);
110 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
111 (uint32_t)(tag_mem_base >> 32));
112 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
113 (uint32_t)(tag_mem_base >> 32));
114
115 mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
116 MORELLO_DMC_MEM_ACCESS_DIS);
117 mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
118 MORELLO_DMC_MEM_ACCESS_DIS);
119
120 INFO("Tag base set to 0x%lx\n", tag_mem_base);
121 plat_info->local_ddr_size = usable_mem_size;
122 } else {
123 INFO("Configuring DMC Bing in server mode\n");
124 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
125 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
126 }
127
128 INFO("Enabling ECC on DMCs\n");
129 /* Enable ECC in DMCs */
130 mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
131 MORELLO_DMC_ERR0CTLR0_ECC_EN);
132 mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
133 MORELLO_DMC_ERR0CTLR0_ECC_EN);
134
135 /* Set DMCs to READY state */
136 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
137 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
138
139 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
140 MORELLO_DMC_MEMC_STATUS_MASK) !=
141 MORELLO_DMC_MEMC_CMD_READY) {
142 continue;
143 }
144
145 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
146 MORELLO_DMC_MEMC_STATUS_MASK) !=
147 MORELLO_DMC_MEMC_CMD_READY) {
148 continue;
149 }
150}
151#endif
152
153void bl2_platform_setup(void)
154{
155 int ret;
156 struct morello_plat_info plat_info;
157
Tamas Banf728b612023-05-08 13:50:37 +0200158 ret = sds_init(SDS_SCP_AP_REGION_ID);
Manoj Kumar91162752022-06-23 12:30:37 +0100159 if (ret != SDS_OK) {
160 ERROR("SDS initialization failed. ret:%d\n", ret);
161 panic();
162 }
163
Tamas Banf728b612023-05-08 13:50:37 +0200164 ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
165 MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
Manoj Kumar91162752022-06-23 12:30:37 +0100166 MORELLO_SDS_PLATFORM_INFO_OFFSET,
167 &plat_info,
168 MORELLO_SDS_PLATFORM_INFO_SIZE,
169 SDS_ACCESS_MODE_NON_CACHED);
170 if (ret != SDS_OK) {
171 ERROR("Error getting platform info from SDS. ret:%d\n", ret);
172 panic();
173 }
174
175 /* Validate plat_info SDS */
176#ifdef TARGET_PLATFORM_FVP
177 if (plat_info.local_ddr_size == 0U) {
178#else
179 if ((plat_info.local_ddr_size == 0U)
180 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
181 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
182 || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
183 ) {
184#endif
185 ERROR("platform info SDS is corrupted\n");
186 panic();
187 }
188
189#ifdef TARGET_PLATFORM_SOC
190 dmc_ecc_setup(&plat_info);
Manoj Kumar58876122021-01-10 16:12:24 +0000191#endif
192 arm_bl2_platform_setup();
193}