blob: db7215f438e8d472b4c76cb15ce078d2b7552722 [file] [log] [blame]
Deepak Pandey9cbacf62018-08-08 10:32:51 +05301/*
Werner Lewisf32d2ad2023-02-21 14:40:12 +00002 * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
Deepak Pandey9cbacf62018-08-08 10:32:51 +05303 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Max Shvetsov0ac39412019-11-19 11:01:26 +00007#include <common/debug.h>
Antonio Nino Diaz1b0c6f12019-01-23 21:08:43 +00008#include <drivers/arm/css/css_mhu_doorbell.h>
Antonio Nino Diazc30db5b2019-01-23 20:37:32 +00009#include <drivers/arm/css/scmi.h>
Manoj Kumar69bebd82019-06-21 17:07:13 +010010#include <drivers/arm/css/sds.h>
Manish Pandey2c44a442019-10-14 17:37:38 +010011#include <drivers/arm/gic600_multichip.h>
Manoj Kumar69bebd82019-06-21 17:07:13 +010012#include <lib/mmio.h>
13#include <lib/utils.h>
Antonio Nino Diazbd7b7402019-01-25 14:30:04 +000014#include <plat/arm/common/plat_arm.h>
15
Manoj Kumar69bebd82019-06-21 17:07:13 +010016#include "n1sdp_def.h"
Werner Lewisf32d2ad2023-02-21 14:40:12 +000017#include "n1sdp_private.h"
sah016ec01e82021-06-06 14:38:01 +053018#include <platform_def.h>
Manoj Kumar69bebd82019-06-21 17:07:13 +010019
20/*
Manish Pandey2f3203f2019-10-07 17:47:46 +010021 * Platform information structure stored in SDS.
22 * This structure holds information about platform's DDR
23 * size which will be used to zero out the memory before
24 * enabling the ECC capability as well as information
25 * about multichip setup
26 * - multichip mode
sah016ec01e82021-06-06 14:38:01 +053027 * - secondary_count
Manish Pandey2f3203f2019-10-07 17:47:46 +010028 * - Local DDR size in GB, DDR memory in master board
sah016ec01e82021-06-06 14:38:01 +053029 * - Remote DDR size in GB, DDR memory in secondary board
Manoj Kumar69bebd82019-06-21 17:07:13 +010030 */
Manish Pandey2f3203f2019-10-07 17:47:46 +010031struct n1sdp_plat_info {
32 bool multichip_mode;
sah016ec01e82021-06-06 14:38:01 +053033 uint8_t secondary_count;
Manish Pandey2f3203f2019-10-07 17:47:46 +010034 uint8_t local_ddr_size;
35 uint8_t remote_ddr_size;
36} __packed;
Manoj Kumar69bebd82019-06-21 17:07:13 +010037
Deepak Pandey9cbacf62018-08-08 10:32:51 +053038static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
Manish Pandey2f3203f2019-10-07 17:47:46 +010039 .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
40 .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
41 .db_preserve_mask = 0xfffffffe,
42 .db_modify_mask = 0x1,
43 .ring_doorbell = &mhu_ring_doorbell
Deepak Pandey9cbacf62018-08-08 10:32:51 +053044};
45
Manish Pandey2c44a442019-10-14 17:37:38 +010046static struct gic600_multichip_data n1sdp_multichip_data __init = {
47 .rt_owner_base = PLAT_ARM_GICD_BASE,
48 .rt_owner = 0,
49 .chip_count = 1,
50 .chip_addrs = {
51 PLAT_ARM_GICD_BASE >> 16,
52 PLAT_ARM_GICD_BASE >> 16
53 },
54 .spi_ids = {
Varun Wadekar61286d22023-03-08 16:47:38 +000055 {PLAT_ARM_GICD_BASE, 32, 479},
56 {PLAT_ARM_GICD_BASE, 512, 959}
Manish Pandey2c44a442019-10-14 17:37:38 +010057 }
58};
59
60static uintptr_t n1sdp_multichip_gicr_frames[3] = {
61 PLAT_ARM_GICR_BASE,
62 PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET,
63 0
64};
65
Tony K Nadackal1b116a82022-12-07 20:44:05 +000066scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
Deepak Pandey9cbacf62018-08-08 10:32:51 +053067{
68 return &n1sdp_scmi_plat_info;
69}
Chandni Cherukurie4bf6a02018-11-14 13:43:59 +053070
71const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
72{
Werner Lewisf32d2ad2023-02-21 14:40:12 +000073 ops->pwr_domain_off = n1sdp_pwr_domain_off;
74 ops->pwr_domain_suspend = n1sdp_pwr_domain_suspend;
Chandni Cherukurie4bf6a02018-11-14 13:43:59 +053075 return css_scmi_override_pm_ops(ops);
76}
Manoj Kumar69bebd82019-06-21 17:07:13 +010077
78/*
79 * N1SDP platform supports RDIMMs with ECC capability. To use the ECC
80 * capability, the entire DDR memory space has to be zeroed out before
81 * enabling the ECC bits in DMC620. Zeroing out several gigabytes of
82 * memory from SCP is quite time consuming so the following function
83 * is added to zero out the DDR memory from application processor which is
sah016ec01e82021-06-06 14:38:01 +053084 * much faster compared to SCP. Local DDR memory is zeroed out during BL2
85 * stage. If remote chip is connected, it's DDR memory is zeroed out here.
Manoj Kumar69bebd82019-06-21 17:07:13 +010086 */
87
Manish Pandeyb68e2862019-09-11 17:07:40 +010088void remote_dmc_ecc_setup(uint8_t remote_ddr_size)
89{
90 uint64_t remote_dram2_size;
91
92 remote_dram2_size = (remote_ddr_size * 1024UL * 1024UL * 1024UL) -
93 N1SDP_REMOTE_DRAM1_SIZE;
94 /* multichip setup */
95 INFO("Zeroing remote DDR memories\n");
96 zero_normalmem((void *)N1SDP_REMOTE_DRAM1_BASE,
97 N1SDP_REMOTE_DRAM1_SIZE);
98 flush_dcache_range(N1SDP_REMOTE_DRAM1_BASE, N1SDP_REMOTE_DRAM1_SIZE);
99 zero_normalmem((void *)N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
100 flush_dcache_range(N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
101
102 INFO("Enabling ECC on remote DMCs\n");
103 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
104 mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG,
105 N1SDP_DMC_MEMC_CMD_CONFIG);
106 mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG,
107 N1SDP_DMC_MEMC_CMD_CONFIG);
108
109 /* Enable ECC in DMCs */
110 mmio_setbits_32(N1SDP_REMOTE_DMC0_ERR0CTLR0_REG,
111 N1SDP_DMC_ERR0CTLR0_ECC_EN);
112 mmio_setbits_32(N1SDP_REMOTE_DMC1_ERR0CTLR0_REG,
113 N1SDP_DMC_ERR0CTLR0_ECC_EN);
114
115 /* Set DMCs to READY state */
116 mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
117 mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
118}
119
Manish Pandey2c44a442019-10-14 17:37:38 +0100120void n1sdp_bl31_multichip_setup(void)
121{
122 plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
123 gic600_multichip_init(&n1sdp_multichip_data);
124}
125
Manoj Kumar69bebd82019-06-21 17:07:13 +0100126void bl31_platform_setup(void)
127{
128 int ret;
Manish Pandey2f3203f2019-10-07 17:47:46 +0100129 struct n1sdp_plat_info plat_info;
Manoj Kumar69bebd82019-06-21 17:07:13 +0100130
Manoj Kumar69bebd82019-06-21 17:07:13 +0100131 ret = sds_init();
132 if (ret != SDS_OK) {
133 ERROR("SDS initialization failed\n");
134 panic();
135 }
136
Manish Pandey2f3203f2019-10-07 17:47:46 +0100137 ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
138 N1SDP_SDS_PLATFORM_INFO_OFFSET,
139 &plat_info,
140 N1SDP_SDS_PLATFORM_INFO_SIZE,
Manoj Kumar69bebd82019-06-21 17:07:13 +0100141 SDS_ACCESS_MODE_NON_CACHED);
142 if (ret != SDS_OK) {
Manish Pandey2f3203f2019-10-07 17:47:46 +0100143 ERROR("Error getting platform info from SDS\n");
144 panic();
145 }
146 /* Validate plat_info SDS */
147 if ((plat_info.local_ddr_size == 0)
148 || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
149 || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
sah016ec01e82021-06-06 14:38:01 +0530150 || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
Manish Pandey2f3203f2019-10-07 17:47:46 +0100151 ERROR("platform info SDS is corrupted\n");
Manoj Kumar69bebd82019-06-21 17:07:13 +0100152 panic();
153 }
Manish Pandey2f3203f2019-10-07 17:47:46 +0100154
Manish Pandey2c44a442019-10-14 17:37:38 +0100155 if (plat_info.multichip_mode) {
sah016ec01e82021-06-06 14:38:01 +0530156 n1sdp_multichip_data.chip_count = plat_info.secondary_count + 1;
Manish Pandey2c44a442019-10-14 17:37:38 +0100157 n1sdp_bl31_multichip_setup();
158 }
159 arm_bl31_platform_setup();
160
Manish Pandeyb68e2862019-09-11 17:07:40 +0100161 /* Check if remote memory is present */
162 if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
163 remote_dmc_ecc_setup(plat_info.remote_ddr_size);
Manoj Kumar69bebd82019-06-21 17:07:13 +0100164}
Madhukar Pappireddy042043b2023-03-02 16:33:25 -0600165
Govindraj Raja436ea5e2023-05-10 14:50:36 -0500166#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
Madhukar Pappireddy042043b2023-03-02 16:33:25 -0600167/*
168 * A dummy implementation of the platform handler for Group0 secure interrupt.
169 */
170int plat_spmd_handle_group0_interrupt(uint32_t intid)
171{
172 (void)intid;
173 return -1;
174}
Govindraj Raja436ea5e2023-05-10 14:50:36 -0500175#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/