1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu #include <assert.h> 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <common/debug.h> 9*91f16700Schasinglulu #include <common/fdt_wrappers.h> 10*91f16700Schasinglulu #include <libfdt.h> 11*91f16700Schasinglulu #include <plat/arm/common/fconf_sdei_getter.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu #define PRIVATE_EVENT_NUM(i) private_events[3 * (i)] 14*91f16700Schasinglulu #define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1] 15*91f16700Schasinglulu #define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2] 16*91f16700Schasinglulu 17*91f16700Schasinglulu #define SHARED_EVENT_NUM(i) shared_events[3 * (i)] 18*91f16700Schasinglulu #define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1] 19*91f16700Schasinglulu #define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2] 20*91f16700Schasinglulu 21*91f16700Schasinglulu struct sdei_dyn_config_t sdei_dyn_config; 22*91f16700Schasinglulu 23*91f16700Schasinglulu int fconf_populate_sdei_dyn_config(uintptr_t config) 24*91f16700Schasinglulu { 25*91f16700Schasinglulu uint32_t i; 26*91f16700Schasinglulu int node, err; 27*91f16700Schasinglulu uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3]; 28*91f16700Schasinglulu uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3]; 29*91f16700Schasinglulu 30*91f16700Schasinglulu const void *dtb = (void *)config; 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* Check that the node offset points to compatible property */ 33*91f16700Schasinglulu node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0"); 34*91f16700Schasinglulu if (node < 0) { 35*91f16700Schasinglulu ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n"); 36*91f16700Schasinglulu return node; 37*91f16700Schasinglulu } 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* Read number of private mappings */ 40*91f16700Schasinglulu err = fdt_read_uint32(dtb, node, "private_event_count", 41*91f16700Schasinglulu &sdei_dyn_config.private_ev_cnt); 42*91f16700Schasinglulu if (err < 0) { 43*91f16700Schasinglulu ERROR("FCONF: Read cell failed for 'private_event_count': %u\n", 44*91f16700Schasinglulu sdei_dyn_config.private_ev_cnt); 45*91f16700Schasinglulu return err; 46*91f16700Schasinglulu } 47*91f16700Schasinglulu 48*91f16700Schasinglulu /* Check if the value is in range */ 49*91f16700Schasinglulu if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) { 50*91f16700Schasinglulu ERROR("FCONF: Invalid value for 'private_event_count': %u\n", 51*91f16700Schasinglulu sdei_dyn_config.private_ev_cnt); 52*91f16700Schasinglulu return -1; 53*91f16700Schasinglulu } 54*91f16700Schasinglulu 55*91f16700Schasinglulu /* Read private mappings */ 56*91f16700Schasinglulu err = fdt_read_uint32_array(dtb, node, "private_events", 57*91f16700Schasinglulu sdei_dyn_config.private_ev_cnt * 3, private_events); 58*91f16700Schasinglulu if (err < 0) { 59*91f16700Schasinglulu ERROR("FCONF: Read cell failed for 'private_events': %d\n", err); 60*91f16700Schasinglulu return err; 61*91f16700Schasinglulu } 62*91f16700Schasinglulu 63*91f16700Schasinglulu /* Move data to fconf struct */ 64*91f16700Schasinglulu for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) { 65*91f16700Schasinglulu sdei_dyn_config.private_ev_nums[i] = PRIVATE_EVENT_NUM(i); 66*91f16700Schasinglulu sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i); 67*91f16700Schasinglulu sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i); 68*91f16700Schasinglulu } 69*91f16700Schasinglulu 70*91f16700Schasinglulu /* Read number of shared mappings */ 71*91f16700Schasinglulu err = fdt_read_uint32(dtb, node, "shared_event_count", 72*91f16700Schasinglulu &sdei_dyn_config.shared_ev_cnt); 73*91f16700Schasinglulu if (err < 0) { 74*91f16700Schasinglulu ERROR("FCONF: Read cell failed for 'shared_event_count'\n"); 75*91f16700Schasinglulu return err; 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu /* Check if the value is in range */ 79*91f16700Schasinglulu if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) { 80*91f16700Schasinglulu ERROR("FCONF: Invalid value for 'shared_event_count': %u\n", 81*91f16700Schasinglulu sdei_dyn_config.shared_ev_cnt); 82*91f16700Schasinglulu return -1; 83*91f16700Schasinglulu } 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* Read shared mappings */ 86*91f16700Schasinglulu err = fdt_read_uint32_array(dtb, node, "shared_events", 87*91f16700Schasinglulu sdei_dyn_config.shared_ev_cnt * 3, shared_events); 88*91f16700Schasinglulu if (err < 0) { 89*91f16700Schasinglulu ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err); 90*91f16700Schasinglulu return err; 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu /* Move data to fconf struct */ 94*91f16700Schasinglulu for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) { 95*91f16700Schasinglulu sdei_dyn_config.shared_ev_nums[i] = SHARED_EVENT_NUM(i); 96*91f16700Schasinglulu sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i); 97*91f16700Schasinglulu sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i); 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu return 0; 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config); 104