mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-30 07:39:24 +00:00

Update SDS driver calls to align with recent changes [1] of the SDS driver. - The driver now requires us to explicitly pass the SDS region id to act on. - Implement plat_sds_get_regions() platform function which is used by the driver to get SDS region information per platform. [1]: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/24609/ Change-Id: I942599edb4d9734c0455f67c6b5673aace62e444 Signed-off-by: Tamas Ban <tamas.ban@arm.com> Signed-off-by: David Vincze <david.vincze@arm.com>
193 lines
5.7 KiB
C
193 lines
5.7 KiB
C
/*
|
|
* 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();
|
|
}
|