14af53977SManoj Kumar /*
2*48d42ed5STamas Ban * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
34af53977SManoj Kumar *
44af53977SManoj Kumar * SPDX-License-Identifier: BSD-3-Clause
54af53977SManoj Kumar */
64af53977SManoj Kumar
74af53977SManoj Kumar #include <common/debug.h>
805330a49SManoj Kumar #include <drivers/arm/css/sds.h>
905330a49SManoj Kumar #include <lib/mmio.h>
104af53977SManoj Kumar #include <lib/utils.h>
114af53977SManoj Kumar #include <plat/arm/common/plat_arm.h>
124af53977SManoj Kumar
1305330a49SManoj Kumar #include "morello_def.h"
1405330a49SManoj Kumar #include <platform_def.h>
1505330a49SManoj Kumar
164af53977SManoj Kumar #ifdef TARGET_PLATFORM_SOC
174af53977SManoj Kumar /*
184af53977SManoj Kumar * Morello platform supports RDIMMs with ECC capability. To use the ECC
194af53977SManoj Kumar * capability, the entire DDR memory space has to be zeroed out before
2005330a49SManoj Kumar * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
2105330a49SManoj Kumar * memory from SCP is quite time consuming so the following function
2205330a49SManoj Kumar * is added to zero out the DDR memory from application processor which is
2305330a49SManoj Kumar * much faster compared to SCP.
244af53977SManoj Kumar */
2505330a49SManoj Kumar
dmc_ecc_setup(struct morello_plat_info * plat_info)2605330a49SManoj Kumar static void dmc_ecc_setup(struct morello_plat_info *plat_info)
2705330a49SManoj Kumar {
2805330a49SManoj Kumar uint64_t dram2_size;
2905330a49SManoj Kumar uint32_t val;
3005330a49SManoj Kumar uint64_t tag_mem_base;
3105330a49SManoj Kumar uint64_t usable_mem_size;
3205330a49SManoj Kumar
3305330a49SManoj Kumar INFO("Total DIMM size: %uGB\n",
3405330a49SManoj Kumar (uint32_t)(plat_info->local_ddr_size / 0x40000000));
3505330a49SManoj Kumar
3605330a49SManoj Kumar assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
3705330a49SManoj Kumar dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
3805330a49SManoj Kumar
394af53977SManoj Kumar INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
404af53977SManoj Kumar zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
414af53977SManoj Kumar flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
4205330a49SManoj Kumar
4305330a49SManoj Kumar INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
4405330a49SManoj Kumar ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
4505330a49SManoj Kumar zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
4605330a49SManoj Kumar flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
4705330a49SManoj Kumar
4805330a49SManoj Kumar /* Clear previous ECC errors while zeroing out the memory */
4905330a49SManoj Kumar val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
5005330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
5105330a49SManoj Kumar
5205330a49SManoj Kumar val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
5305330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
5405330a49SManoj Kumar
5505330a49SManoj Kumar /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
5605330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
5705330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
5805330a49SManoj Kumar
5905330a49SManoj Kumar while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
6005330a49SManoj Kumar MORELLO_DMC_MEMC_STATUS_MASK) !=
6105330a49SManoj Kumar MORELLO_DMC_MEMC_CMD_CONFIG) {
6205330a49SManoj Kumar continue;
6305330a49SManoj Kumar }
6405330a49SManoj Kumar
6505330a49SManoj Kumar while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
6605330a49SManoj Kumar MORELLO_DMC_MEMC_STATUS_MASK) !=
6705330a49SManoj Kumar MORELLO_DMC_MEMC_CMD_CONFIG) {
6805330a49SManoj Kumar continue;
6905330a49SManoj Kumar }
7005330a49SManoj Kumar
7105330a49SManoj Kumar /* Configure Bing client/server mode based on SCC configuration */
7205330a49SManoj Kumar if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
7305330a49SManoj Kumar INFO("Configuring DMC Bing in client mode\n");
7405330a49SManoj Kumar usable_mem_size = plat_info->local_ddr_size -
7505330a49SManoj Kumar (plat_info->local_ddr_size / 128ULL);
7605330a49SManoj Kumar
7705330a49SManoj Kumar /* Linear DDR address */
7805330a49SManoj Kumar tag_mem_base = usable_mem_size;
7905330a49SManoj Kumar tag_mem_base = tag_mem_base / 4;
8005330a49SManoj Kumar
8105330a49SManoj Kumar /* Reverse translation */
8205330a49SManoj Kumar if (tag_mem_base < ARM_DRAM1_BASE) {
8305330a49SManoj Kumar tag_mem_base += ARM_DRAM1_BASE;
8405330a49SManoj Kumar } else {
8505330a49SManoj Kumar tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
8605330a49SManoj Kumar ARM_DRAM2_BASE;
8705330a49SManoj Kumar }
8805330a49SManoj Kumar
8905330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
9005330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
9105330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
9205330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
9305330a49SManoj Kumar
9405330a49SManoj Kumar if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
9505330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
9605330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
9705330a49SManoj Kumar INFO("C1 Tag Cache Enabled\n");
9805330a49SManoj Kumar }
9905330a49SManoj Kumar
10005330a49SManoj Kumar if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
10105330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
10205330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
10305330a49SManoj Kumar INFO("C2 Tag Cache Enabled\n");
10405330a49SManoj Kumar }
10505330a49SManoj Kumar
10605330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
10705330a49SManoj Kumar (uint32_t)tag_mem_base);
10805330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
10905330a49SManoj Kumar (uint32_t)tag_mem_base);
11005330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
11105330a49SManoj Kumar (uint32_t)(tag_mem_base >> 32));
11205330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
11305330a49SManoj Kumar (uint32_t)(tag_mem_base >> 32));
11405330a49SManoj Kumar
11505330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
11605330a49SManoj Kumar MORELLO_DMC_MEM_ACCESS_DIS);
11705330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
11805330a49SManoj Kumar MORELLO_DMC_MEM_ACCESS_DIS);
11905330a49SManoj Kumar
12005330a49SManoj Kumar INFO("Tag base set to 0x%lx\n", tag_mem_base);
12105330a49SManoj Kumar plat_info->local_ddr_size = usable_mem_size;
12205330a49SManoj Kumar } else {
12305330a49SManoj Kumar INFO("Configuring DMC Bing in server mode\n");
12405330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
12505330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
12605330a49SManoj Kumar }
12705330a49SManoj Kumar
12805330a49SManoj Kumar INFO("Enabling ECC on DMCs\n");
12905330a49SManoj Kumar /* Enable ECC in DMCs */
13005330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
13105330a49SManoj Kumar MORELLO_DMC_ERR0CTLR0_ECC_EN);
13205330a49SManoj Kumar mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
13305330a49SManoj Kumar MORELLO_DMC_ERR0CTLR0_ECC_EN);
13405330a49SManoj Kumar
13505330a49SManoj Kumar /* Set DMCs to READY state */
13605330a49SManoj Kumar mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
13705330a49SManoj Kumar mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
13805330a49SManoj Kumar
13905330a49SManoj Kumar while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
14005330a49SManoj Kumar MORELLO_DMC_MEMC_STATUS_MASK) !=
14105330a49SManoj Kumar MORELLO_DMC_MEMC_CMD_READY) {
14205330a49SManoj Kumar continue;
14305330a49SManoj Kumar }
14405330a49SManoj Kumar
14505330a49SManoj Kumar while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
14605330a49SManoj Kumar MORELLO_DMC_MEMC_STATUS_MASK) !=
14705330a49SManoj Kumar MORELLO_DMC_MEMC_CMD_READY) {
14805330a49SManoj Kumar continue;
14905330a49SManoj Kumar }
15005330a49SManoj Kumar }
15105330a49SManoj Kumar #endif
15205330a49SManoj Kumar
bl2_platform_setup(void)15305330a49SManoj Kumar void bl2_platform_setup(void)
15405330a49SManoj Kumar {
15505330a49SManoj Kumar int ret;
15605330a49SManoj Kumar struct morello_plat_info plat_info;
15705330a49SManoj Kumar
158*48d42ed5STamas Ban ret = sds_init(SDS_SCP_AP_REGION_ID);
15905330a49SManoj Kumar if (ret != SDS_OK) {
16005330a49SManoj Kumar ERROR("SDS initialization failed. ret:%d\n", ret);
16105330a49SManoj Kumar panic();
16205330a49SManoj Kumar }
16305330a49SManoj Kumar
164*48d42ed5STamas Ban ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
165*48d42ed5STamas Ban MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
16605330a49SManoj Kumar MORELLO_SDS_PLATFORM_INFO_OFFSET,
16705330a49SManoj Kumar &plat_info,
16805330a49SManoj Kumar MORELLO_SDS_PLATFORM_INFO_SIZE,
16905330a49SManoj Kumar SDS_ACCESS_MODE_NON_CACHED);
17005330a49SManoj Kumar if (ret != SDS_OK) {
17105330a49SManoj Kumar ERROR("Error getting platform info from SDS. ret:%d\n", ret);
17205330a49SManoj Kumar panic();
17305330a49SManoj Kumar }
17405330a49SManoj Kumar
17505330a49SManoj Kumar /* Validate plat_info SDS */
17605330a49SManoj Kumar #ifdef TARGET_PLATFORM_FVP
17705330a49SManoj Kumar if (plat_info.local_ddr_size == 0U) {
17805330a49SManoj Kumar #else
17905330a49SManoj Kumar if ((plat_info.local_ddr_size == 0U)
18005330a49SManoj Kumar || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
18105330a49SManoj Kumar || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
18205330a49SManoj Kumar || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
18305330a49SManoj Kumar ) {
18405330a49SManoj Kumar #endif
18505330a49SManoj Kumar ERROR("platform info SDS is corrupted\n");
18605330a49SManoj Kumar panic();
18705330a49SManoj Kumar }
18805330a49SManoj Kumar
18905330a49SManoj Kumar #ifdef TARGET_PLATFORM_SOC
19005330a49SManoj Kumar dmc_ecc_setup(&plat_info);
1914af53977SManoj Kumar #endif
1924af53977SManoj Kumar arm_bl2_platform_setup();
1934af53977SManoj Kumar }
194