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