blob: 5a5b9a5f06a9fb8812195572bdbaa05ff7652781 [file] [log] [blame]
sah016ec01e82021-06-06 14:38:01 +05301/*
Tamas Ban307b3d82023-05-08 13:51:27 +02002 * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
sah016ec01e82021-06-06 14:38:01 +05303 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
8#include <drivers/arm/css/sds.h>
9#include <lib/mmio.h>
10#include <lib/utils.h>
11
12#include "n1sdp_def.h"
13#include <plat/arm/common/plat_arm.h>
Tamas Ban307b3d82023-05-08 13:51:27 +020014#include <platform_def.h>
sah016ec01e82021-06-06 14:38:01 +053015
16struct n1sdp_plat_info {
17 bool multichip_mode;
18 uint8_t secondary_count;
19 uint8_t local_ddr_size;
20 uint8_t remote_ddr_size;
21} __packed;
22
23/*
24 * N1SDP platform supports RDIMMs with ECC capability. To use the ECC
25 * capability, the entire DDR memory space has to be zeroed out before
26 * enabling the ECC bits in DMC620. Zeroing out several gigabytes of
27 * memory from SCP is quite time consuming so the following function
28 * is added to zero out the DDR memory from application processor which is
29 * much faster compared to SCP.
30 */
31
32void dmc_ecc_setup(uint8_t ddr_size_gb)
33{
34 uint64_t dram2_size;
35
36 dram2_size = (ddr_size_gb * 1024UL * 1024UL * 1024UL) -
37 ARM_DRAM1_SIZE;
38
39 INFO("Zeroing DDR memories\n");
40 zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
41 flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
42 zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
43 flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
44
45 INFO("Enabling ECC on DMCs\n");
46 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
47 mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
48 mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
49
50 /* Enable ECC in DMCs */
51 mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
52 mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
53
54 /* Set DMCs to READY state */
55 mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
56 mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
57}
58
59void bl2_platform_setup(void)
60{
61 int ret;
62 struct n1sdp_plat_info plat_info;
63
Tamas Ban307b3d82023-05-08 13:51:27 +020064 ret = sds_init(SDS_SCP_AP_REGION_ID);
sah016ec01e82021-06-06 14:38:01 +053065 if (ret != SDS_OK) {
66 ERROR("SDS initialization failed\n");
67 panic();
68 }
69
Tamas Ban307b3d82023-05-08 13:51:27 +020070 ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
71 N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
sah016ec01e82021-06-06 14:38:01 +053072 N1SDP_SDS_PLATFORM_INFO_OFFSET,
73 &plat_info,
74 N1SDP_SDS_PLATFORM_INFO_SIZE,
75 SDS_ACCESS_MODE_NON_CACHED);
76 if (ret != SDS_OK) {
77 ERROR("Error getting platform info from SDS\n");
78 panic();
79 }
80 /* Validate plat_info SDS */
81 if ((plat_info.local_ddr_size == 0)
82 || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
83 || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
84 || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
85 ERROR("platform info SDS is corrupted\n");
86 panic();
87 }
88
89 dmc_ecc_setup(plat_info.local_ddr_size);
90 arm_bl2_platform_setup();
91}