123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <common/debug.h>
- #include <drivers/arm/css/sds.h>
- #include <lib/mmio.h>
- #include <lib/utils.h>
- #include <plat/arm/common/plat_arm.h>
- #include "morello_def.h"
- #include <platform_def.h>
- #ifdef TARGET_PLATFORM_SOC
- /*
- * Morello platform supports RDIMMs with ECC capability. To use the ECC
- * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
- * memory from SCP is quite time consuming so the following function
- * is added to zero out the DDR memory from application processor which is
- * much faster compared to SCP.
- */
- static void dmc_ecc_setup(struct morello_plat_info *plat_info)
- {
- uint64_t dram2_size;
- uint32_t val;
- uint64_t tag_mem_base;
- uint64_t usable_mem_size;
- INFO("Total DIMM size: %uGB\n",
- (uint32_t)(plat_info->local_ddr_size / 0x40000000));
- assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
- dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
- INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
- zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
- flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
- INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
- ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
- zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
- flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
- /* Clear previous ECC errors while zeroing out the memory */
- val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
- val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
- /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
- /* Configure Bing client/server mode based on SCC configuration */
- if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
- INFO("Configuring DMC Bing in client mode\n");
- usable_mem_size = plat_info->local_ddr_size -
- (plat_info->local_ddr_size / 128ULL);
- /* Linear DDR address */
- tag_mem_base = usable_mem_size;
- tag_mem_base = tag_mem_base / 4;
- /* Reverse translation */
- if (tag_mem_base < ARM_DRAM1_BASE) {
- tag_mem_base += ARM_DRAM1_BASE;
- } else {
- tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
- ARM_DRAM2_BASE;
- }
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
- mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
- if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
- INFO("C1 Tag Cache Enabled\n");
- }
- if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
- INFO("C2 Tag Cache Enabled\n");
- }
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
- mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
- mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
- INFO("Tag base set to 0x%lx\n", tag_mem_base);
- plat_info->local_ddr_size = usable_mem_size;
- } else {
- INFO("Configuring DMC Bing in server mode\n");
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
- }
- INFO("Enabling ECC on DMCs\n");
- /* Enable ECC in DMCs */
- mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
- mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
- /* Set DMCs to READY state */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
- }
- #endif
- void bl2_platform_setup(void)
- {
- int ret;
- struct morello_plat_info plat_info;
- ret = sds_init(SDS_SCP_AP_REGION_ID);
- if (ret != SDS_OK) {
- ERROR("SDS initialization failed. ret:%d\n", ret);
- panic();
- }
- ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
- MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
- MORELLO_SDS_PLATFORM_INFO_OFFSET,
- &plat_info,
- MORELLO_SDS_PLATFORM_INFO_SIZE,
- SDS_ACCESS_MODE_NON_CACHED);
- if (ret != SDS_OK) {
- ERROR("Error getting platform info from SDS. ret:%d\n", ret);
- panic();
- }
- /* Validate plat_info SDS */
- #ifdef TARGET_PLATFORM_FVP
- if (plat_info.local_ddr_size == 0U) {
- #else
- if ((plat_info.local_ddr_size == 0U)
- || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
- ) {
- #endif
- ERROR("platform info SDS is corrupted\n");
- panic();
- }
- #ifdef TARGET_PLATFORM_SOC
- dmc_ecc_setup(&plat_info);
- #endif
- arm_bl2_platform_setup();
- }
|