diff --git a/module/apcontext/include/mod_apcontext.h b/module/apcontext/include/mod_apcontext.h new file mode 100644 index 0000000000000000000000000000000000000000..ba6dc0756c99b78513da42470e79e5c1cc88bef9 --- /dev/null +++ b/module/apcontext/include/mod_apcontext.h @@ -0,0 +1,43 @@ + +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_APCONTEXT_H +#define MOD_APCONTEXT_H + +#include +#include + +/*! + * \ingroup GroupModules Modules + * \defgroup GroupModuleAPContext AP Context + * + * \brief Application Processor (AP) context module. + * + * \details This module implements the AP context zero-initialization. + * \{ + */ + +/*! + * \brief AP context configuration data + */ +struct mod_apcontext_config { + /*! Base address of the AP context */ + uintptr_t base; + + /*! Size of the AP context */ + size_t size; + + /*! Identifier of the clock this module depends on */ + fwk_id_t clock_id; +}; + +/*! + * \} + */ + +#endif /* MOD_APCONTEXT_H */ diff --git a/module/apcontext/src/Makefile b/module/apcontext/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f7598edf01d2587c1822f2bdde20f30ee4fb48f9 --- /dev/null +++ b/module/apcontext/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := "APContext" +BS_LIB_SOURCES = mod_apcontext.c + +include $(BS_DIR)/lib.mk diff --git a/module/apcontext/src/mod_apcontext.c b/module/apcontext/src/mod_apcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..4d0217bf296b11946709c3d8b36b53751a1c67e3 --- /dev/null +++ b/module/apcontext/src/mod_apcontext.c @@ -0,0 +1,124 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "[APContext]" + +static const struct mod_log_api *log; + +static void apcontext_zero(void) +{ + const struct mod_apcontext_config *config; + + config = fwk_module_get_data(fwk_module_id_apcontext); + + log->log(MOD_LOG_GROUP_DEBUG, MODULE_NAME + " Zeroing AP context area [0x%08x - 0x%08x]\n", + config->base, + config->base + config->size); + + memset((void *)config->base, 0, config->size); +} + +/* + * Framework handlers + */ + +static int apcontext_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + const struct mod_apcontext_config *config = data; + + /* This module does not support elements */ + if (element_count != 0) + return FWK_E_PARAM; + + if (config->base == 0) + return FWK_E_DATA; + + if (config->size == 0) + return FWK_E_DATA; + + return FWK_SUCCESS; +} + +static int apcontext_bind(fwk_id_t id, unsigned int round) +{ + int status; + + /* Skip second round */ + if (round > 0) + return FWK_SUCCESS; + + status = fwk_module_bind(fwk_module_id_log, MOD_LOG_API_ID, &log); + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + + return FWK_SUCCESS; +} + +static int apcontext_start(fwk_id_t id) +{ + const struct mod_apcontext_config *config = + fwk_module_get_data(fwk_module_id_apcontext); + + if (fwk_id_is_equal(config->clock_id, FWK_ID_NONE)) { + apcontext_zero(); + return FWK_SUCCESS; + } + + /* Register the module for clock state notifications */ + return fwk_notification_subscribe( + mod_clock_notification_id_state_changed, + config->clock_id, + id); +} + +static int apcontext_process_notification(const struct fwk_event *event, + struct fwk_event *resp_event) +{ + struct clock_notification_params *params; + + assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); + assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); + + params = (struct clock_notification_params *)event->params; + + /* + * Zero AP context area when the system is initialized for the first time + * only + */ + if (params->new_state == MOD_CLOCK_STATE_RUNNING) { + apcontext_zero(); + + /* Unsubscribe to the notification */ + return fwk_notification_unsubscribe(event->id, event->source_id, + event->target_id); + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_apcontext = { + .name = "APContext", + .type = FWK_MODULE_TYPE_SERVICE, + .init = apcontext_init, + .bind = apcontext_bind, + .start = apcontext_start, + .process_notification = apcontext_process_notification, +}; diff --git a/module/cmn600/include/mod_cmn600.h b/module/cmn600/include/mod_cmn600.h new file mode 100644 index 0000000000000000000000000000000000000000..18ded12166bdef31760dd33db04af7ca9aa696c0 --- /dev/null +++ b/module/cmn600/include/mod_cmn600.h @@ -0,0 +1,129 @@ + +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_CMN600_H +#define MOD_CMN600_H + +#include + +/*! + * \addtogroup GroupModules Modules + * @{ + */ + +/*! + * \defgroup GroupModuleCMN600 CMN600 + * + * \brief Arm Coherent Mesh Network (CMN) 600 module + * + * \details This module adds support for the CMN600 interconnect + * @{ + */ + +/*! + * \brief Module API indices + */ +enum mod_cmn600_api_idx { + /*! Index of the PPU_V1 power state observer API */ + MOD_CMN600_API_IDX_PPU_OBSERVER, + + /*! Number of APIs */ + MOD_CMN600_API_COUNT +}; + +/*! + * \brief Memory region configuration type + */ +enum mod_cmn600_memory_region_type { + /*! Input/Output region (serviced by dedicated HN-I and HN-D nodes) */ + MOD_CMN600_MEMORY_REGION_TYPE_IO, + + /*! + * Region backed by the system cache (serviced by all HN-F nodes in the + * system) + */ + MOD_CMN600_MEMORY_REGION_TYPE_SYSCACHE, + + /*! + * Sub region of the system cache for non-hashed access (serviced by + * dedicated SN-F nodes). + */ + MOD_CMN600_REGION_TYPE_SYSCACHE_SUB, +}; + +/*! + * \brief Memory region map descriptor + */ +struct mod_cmn600_memory_region_map { + /*! Base address */ + uint64_t base; + + /*! Region size in bytes */ + uint64_t size; + + /*! Region configuration type */ + enum mod_cmn600_memory_region_type type; + + /*! + * \brief Target node identifier + * + * \note Not used for \ref + * mod_cmn600_memory_region_type.MOD_CMN600_MEMORY_REGION_TYPE_SYSCACHE + * memory regions as it uses the pool of HN-F nodes available in the + * system + */ + unsigned int node_id; +}; + +/*! + * \brief CMN600 configuration data + */ +struct mod_cmn600_config { + /*! Peripheral base address. */ + uintptr_t base; + + /*! Size along x-axis of the interconnect mesh */ + unsigned int mesh_size_x; + + /*! Size along y-axis of the interconnect mesh */ + unsigned int mesh_size_y; + + /*! Default HN-D node identifier containing the global configuration */ + unsigned int hnd_node_id; + + /*! + * \brief Table of SN-Fs used as targets for the HN-F nodes + * + * \details Each entry of this table corresponds to a HN-F node in the + * system. The HN-F's logical identifiers are used as indices in this + * table + */ + const unsigned int *snf_table; + + /*! Number of entries in the \ref snf_table */ + size_t snf_count; + + /*! Table of region memory map entries */ + const struct mod_cmn600_memory_region_map *mmap_table; + + /*! Number of entries in the \ref mmap_table */ + size_t mmap_count; + + /*! Identifier of the clock that this device depends on */ + fwk_id_t clock_id; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_CMN600_H */ diff --git a/module/cmn600/src/Makefile b/module/cmn600/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..08c5fb064429d9b8c190fa5ddf6bb6e8c18defe7 --- /dev/null +++ b/module/cmn600/src/Makefile @@ -0,0 +1,13 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := CMN600 + +BS_LIB_SOURCES = mod_cmn600.c +BS_LIB_SOURCES += cmn600.c + +include $(BS_DIR)/lib.mk diff --git a/module/cmn600/src/cmn600.c b/module/cmn600/src/cmn600.c new file mode 100644 index 0000000000000000000000000000000000000000..32da64b250e8c9e8e907a8511fd930fa2156eaf7 --- /dev/null +++ b/module/cmn600/src/cmn600.c @@ -0,0 +1,185 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +unsigned int get_node_child_count(void *node_base) +{ + struct node_header *node = node_base; + return node->CHILD_INFO & CMN600_CHILD_INFO_COUNT; +} + +enum node_type get_node_type(void *node_base) +{ + struct node_header *node = node_base; + return (enum node_type)(node->NODE_INFO & CMN600_NODE_INFO_TYPE); +} + +unsigned int get_node_id(void *node_base) +{ + struct node_header *node = node_base; + return (node->NODE_INFO & CMN600_NODE_INFO_ID) >> CMN600_NODE_INFO_ID_POS; +} + +unsigned int get_node_logical_id(void *node_base) +{ + struct node_header *node = node_base; + return (node->NODE_INFO & CMN600_NODE_INFO_LOGICAL_ID) >> + CMN600_NODE_INFO_LOGICAL_ID_POS; +} + +void *get_child_node(uintptr_t base, void *node_base, unsigned int child_index) +{ + struct node_header *node = node_base; + uint32_t child_pointer; + unsigned int offset; + void *child_node; + + child_pointer = node->CHILD_POINTER[child_index]; + offset = child_pointer & CMN600_CHILD_POINTER_OFFSET; + + child_node = (void *)(base + offset); + return child_node; +} + +unsigned int get_child_node_id(void *node_base, + unsigned int child_index) +{ + struct node_header *node = node_base; + uint32_t node_pointer; + unsigned int device_id; + + node_pointer = (node->CHILD_POINTER[child_index] & + CMN600_CHILD_POINTER_EXT_NODE_POINTER) >> + CMN600_CHILD_POINTER_EXT_NODE_POINTER_POS; + + device_id = (((node_pointer >> 6) & 0xff) << 3) | + ((node_pointer & 0x1) << 2) | + ((node_pointer >> 2) & 0x3); + + return device_id; +} + +bool is_child_external(void *node_base, unsigned int child_index) +{ + struct node_header *node = node_base; + return !!(node->CHILD_POINTER[child_index] & (1 << 31)); +} + +uint64_t sam_encode_region_size(uint64_t size) +{ + uint64_t blocks; + uint64_t result; + + /* Size must be a multiple of SAM_GRANULARITY */ + assert((size % SAM_GRANULARITY) == 0); + + blocks = size / SAM_GRANULARITY; + result = fwk_math_log2(blocks); + + return result; +} + +void configure_region(volatile uint64_t *reg, unsigned int bit_offset, + uint64_t base, uint64_t size, enum sam_node_type node_type) +{ + uint64_t value; + + assert(reg); + assert((base % size) == 0); + + value = CMN600_RNSAM_REGION_ENTRY_VALID; + value |= node_type << CMN600_RNSAM_REGION_ENTRY_TYPE_POS; + value |= sam_encode_region_size(size) << CMN600_RNSAM_REGION_ENTRY_SIZE_POS; + value |= (base / SAM_GRANULARITY) << CMN600_RNSAM_REGION_ENTRY_BASE_POS; + + *reg &= ~(CMN600_RNSAM_REGION_ENTRY_MASK << bit_offset); + *reg |= value << bit_offset; +} + +static const char * const type_to_name[] = { + [NODE_TYPE_INVALID] = "", + [NODE_TYPE_DVM] = "DVM", + [NODE_TYPE_CFG] = "CFG", + [NODE_TYPE_DTC] = "DTC", + [NODE_TYPE_HN_I] = "HN-I", + [NODE_TYPE_HN_F] = "HN-F", + [NODE_TYPE_XP] = "XP", + [NODE_TYPE_SBSX] = "SBSX", + [NODE_TYPE_RN_I] = "RN-I", + [NODE_TYPE_RN_D] = "RN-D", + [NODE_TYPE_RN_SAM] = "RN-SAM", +}; + +static const char * const type_to_name_cml[] = { + [NODE_TYPE_CXRA - NODE_TYPE_CML_BASE] = "CXRA", + [NODE_TYPE_CXHA - NODE_TYPE_CML_BASE] = "CXHA", + [NODE_TYPE_CXLA - NODE_TYPE_CML_BASE] = "CXLA", + +}; + +const char *get_node_type_name(enum node_type node_type) +{ + /* Base node IDs */ + if (node_type <= NODE_TYPE_RN_SAM) + return type_to_name[node_type]; + + /* CML node IDs */ + if ((node_type >= NODE_TYPE_CML_BASE) && + (node_type <= NODE_TYPE_CXLA)) + return type_to_name_cml[node_type - NODE_TYPE_CML_BASE]; + + /* Invalid node IDs */ + return type_to_name[NODE_TYPE_INVALID]; +} + +unsigned int get_node_pos_x(void *node_base) +{ + struct node_header *node = node_base; + return (unsigned int)((node->NODE_INFO >> 21) & 0x3); +} + +unsigned int get_node_pos_y(void *node_base) +{ + struct node_header *node = node_base; + return (unsigned int)((node->NODE_INFO >> 19) & 0x3); +} + +struct cmn600_cfgm_reg *get_root_node(uintptr_t base, unsigned int hnd_node_id, + unsigned int mesh_size_x, unsigned int mesh_size_y) +{ + unsigned int encoding_bits; + unsigned int mask_bits; + unsigned int node_pos_x; + unsigned int node_pos_y; + unsigned int node_port; + uintptr_t offset; + + /* + * Determine the number of bits used to represent each node coordinate based + * on the mesh size as per CMN600 specification. + */ + encoding_bits = ((mesh_size_x > 4) || (mesh_size_y > 4)) ? 3 : 2; + + /* Extract node coordinates from the node identifier */ + mask_bits = (1 << encoding_bits) - 1; + node_pos_y = (hnd_node_id >> CMN600_NODE_ID_Y_POS) & mask_bits; + node_pos_x = (hnd_node_id >> (CMN600_NODE_ID_Y_POS + encoding_bits)) & + mask_bits; + node_port = (hnd_node_id >> CMN600_NODE_ID_PORT_POS) & + CMN600_NODE_ID_PORT_MASK; + + /* Calculate node address offset */ + offset = (node_pos_y << CMN600_ROOT_NODE_OFFSET_Y_POS) | + (node_pos_x << (CMN600_ROOT_NODE_OFFSET_Y_POS + encoding_bits)) | + (node_port << CMN600_ROOT_NODE_OFFSET_PORT_POS); + + return (struct cmn600_cfgm_reg *)(base + offset); +} diff --git a/module/cmn600/src/cmn600.h b/module/cmn600/src/cmn600.h new file mode 100644 index 0000000000000000000000000000000000000000..0705cbb47fa1b315f4ccd2e8b2dbb1847a9fc3ec --- /dev/null +++ b/module/cmn600/src/cmn600.h @@ -0,0 +1,696 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions and utility functions for the CMN600 module. + */ + +#ifndef CMN600_H +#define CMN600_H + +#include +#include +#include + +#define CMN600_MAX_NUM_RNF 32 +#define CMN600_MAX_NUM_HNF 32 + +#define SAM_GRANULARITY (64 * FWK_MIB) + +enum node_id_size { + NODE_ID_SIZE_7BITS, + NODE_ID_SIZE_9BITS, +}; + +enum node_type { + NODE_TYPE_INVALID = 0x0, + NODE_TYPE_DVM = 0x1, + NODE_TYPE_CFG = 0x2, + NODE_TYPE_DTC = 0x3, + NODE_TYPE_HN_I = 0x4, + NODE_TYPE_HN_F = 0x5, + NODE_TYPE_XP = 0x6, + NODE_TYPE_SBSX = 0x7, + NODE_TYPE_RN_I = 0xA, + NODE_TYPE_RN_D = 0xD, + NODE_TYPE_RN_SAM = 0xF, + /* Coherent Multichip Link (CML) node types */ + NODE_TYPE_CML_BASE = 0x100, + NODE_TYPE_CXRA = 0x100, + NODE_TYPE_CXHA = 0x101, + NODE_TYPE_CXLA = 0x102, +}; + +/* Common node header */ +struct node_header { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x100 - 0x88]; + FWK_R uint64_t CHILD_POINTER[256]; +}; + +struct cluster_mapping { + unsigned int node_id; + struct node_header *node; +}; + +enum sam_node_type { + SAM_NODE_TYPE_HN_F = 0, + SAM_NODE_TYPE_HN_I = 1, + SAM_NODE_TYPE_CXRA = 2, + SAM_NODE_TYPE_COUNT +}; + +/* + * Request Node System Address Map (RN-SAM) registers + */ +struct cmn600_rnsam_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xC00 - 0x988]; + FWK_RW uint64_t STATUS; + FWK_RW uint64_t NON_HASH_MEM_REGION[5]; + FWK_RW uint64_t NON_HASH_TGT_NODEID[3]; + FWK_RW uint64_t SYS_CACHE_GRP_REGION[2]; + FWK_RW uint64_t SYS_CACHE_GRP_HN_NODEID[8]; + FWK_RW uint64_t SYS_CACHE_GRP_NOHASH_NODEID; + uint8_t RESERVED4[0xD00 - 0xCA0]; + FWK_RW uint64_t SYS_CACHE_GRP_HN_COUNT; + FWK_RW uint64_t SYS_CACHE_GRP_SN_NODEID[8]; + FWK_RW uint64_t SYS_CACHE_GRP_SN_SAM_CFG[2]; +}; + +/* + * Debug and Trace registers + */ +struct cmn600_dt_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x980 - 0x88]; + FWK_RW uint64_t SECURE_ACCESS; + uint8_t RESERVED2[0xA00 - 0x988]; + FWK_RW uint64_t DTC_CTL; + uint8_t RESERVED3[0xA10 - 0xA08]; + FWK_R uint64_t TRIGGER_STATUS; + uint8_t RESERVED4[0xA20 - 0xA18]; + FWK_W uint64_t TRIGGER_STATUS_CLR; + uint8_t RESERVED5[0xA30 - 0xA28]; + FWK_RW uint64_t TRACE_CONTROL; + uint8_t RESERVED6[0xA40 - 0xA38]; + FWK_R uint64_t DBG_ID; + FWK_RW uint64_t TRACE_ID; + uint8_t RESERVED7[0x2000 - 0xA50]; + FWK_RW uint64_t PMEVCNT[8]; + FWK_RW uint64_t PMCCNTR; + uint8_t RESERVED8[0x2050 - 0x2048]; + FWK_RW uint64_t PMEVCNTSR[8]; + FWK_RW uint64_t PMCCNTRSR; + uint8_t RESERVED9[0x2100 - 0x2098]; + FWK_RW uint64_t PMCR; + FWK_RW uint64_t PMEVCNT_LOCALNUM; + uint8_t RESERVED10[0x2118 - 0x2110]; + FWK_R uint64_t PMOVSR; + FWK_W uint64_t PMOVSR_CLR; + FWK_R uint64_t PMSR; + FWK_W uint64_t PMSR_REQ; + FWK_W uint64_t PMSR_CLR; + uint8_t RESERVED11[0x2DA0 - 0x2140]; + FWK_RW uint64_t CLAIM; + FWK_R uint64_t DEVAFF; + FWK_R uint64_t LSR; + FWK_R uint64_t AUTHSTATUS_DEVARCH; + FWK_R uint64_t DEVID; + FWK_R uint64_t DEVTYPE; + FWK_R uint64_t PIDR45; + FWK_R uint64_t PIDR67; + FWK_R uint64_t PIDR01; + FWK_R uint64_t PIDR23; + FWK_R uint64_t CIDR01; + FWK_R uint64_t CIDR23; +}; + +/* + * Device Node registers + */ +struct cmn600_dn_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t BUILD_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xA00 - 0x988]; + FWK_RW uint64_t AUX_CTL; + uint8_t RESERVED4[0xC00 - 0xA08]; + FWK_RW uint64_t VMF0_CTRL; + FWK_RW uint64_t VMF0_RNF[4]; + uint8_t RESERVED5[0xC40 - 0xC28]; + FWK_RW uint64_t VMF0_RND; + uint8_t RESERVED6[0xC60 - 0xC48]; + FWK_RW uint64_t VMF0_RNC; + uint8_t RESERVED7[0xC80 - 0xC68]; + FWK_RW uint64_t VMF1_CTRL; + FWK_RW uint64_t VMF1_RNF[4]; + uint8_t RESERVED8[0xCC0 - 0xCA8]; + FWK_RW uint64_t VMF1_RND; + uint8_t RESERVED9[0xCE0 - 0xCC8]; + FWK_RW uint64_t VMF1_RNC; + uint8_t RESERVED10[0xD00 - 0xCE8]; + FWK_RW uint64_t VMF2_CTRL; + FWK_RW uint64_t VMF2_RNF[4]; + uint8_t RESERVED11[0xD40 - 0xD28]; + FWK_RW uint64_t VMF2_RND; + uint8_t RESERVED12[0xD60 - 0xD48]; + FWK_RW uint64_t VMF2_RNC; + uint8_t RESERVED13[0xD80 - 0xD68]; + FWK_RW uint64_t VMF3_CTRL; + FWK_RW uint64_t VMF3_RNF[4]; + uint8_t RESERVED14[0xDC0 - 0xDA8]; + FWK_RW uint64_t VMF3_RND; + uint8_t RESERVED15[0xDE0 - 0xDC8]; + FWK_RW uint64_t VMF3_RNC; + uint8_t RESERVED16[0x2000 - 0xDE8]; + FWK_RW uint64_t PMU_EVEN_SEL; +}; + + +/* + * Quality of Service (QoS) registers + */ +struct cmn600_qos_reg { + FWK_RW uint64_t QOS_CONTROL; + FWK_RW uint64_t QOS_LAST_TGT; + FWK_RW uint64_t QOS_LAST_SCALE; + FWK_RW uint64_t QOS_LAST_RANGE; +}; + +/* + * Request Node Device (RN-D) registers + */ +struct cmn600_rnd_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xA00 - 0x988]; + FWK_RW uint64_t CFG_CTL; + FWK_RW uint64_t AUX_CTL; + FWK_RW uint64_t S_PORT_CONTROL[3]; + uint8_t RESERVED4[0xA80 - 0xA28]; + struct cmn600_qos_reg S_QOS[3]; + uint8_t RESERVED5[0x1000 - 0xAE0]; + FWK_RW uint64_t SYSCOREQ_CTL; + FWK_R uint64_t SYSCOACK_STATUS; + uint8_t RESERVED6[0x2000 - 0x1010]; + FWK_RW uint64_t PMU_EVENT_SEL; +}; + +/* + * Fully Coherent Home Node (HN-F) registers + */ +struct cmn600_hnf_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xA00 - 0x988]; + FWK_RW uint64_t CFG_CTL; + FWK_RW uint64_t AUX_CTL; + uint8_t RESERVED4[0xA80 - 0xA10]; + FWK_R uint64_t QOS_BAND; + FWK_RW uint64_t QOS_RESERVATION; + FWK_RW uint64_t RN_STARVATION; + uint8_t RESERVED5[0xB80 - 0xA98]; + FWK_W uint64_t CFG_L3SF_DBGRD; + FWK_R uint64_t L3_CACHE_ACCESS_L3_TAG; + FWK_R uint64_t L3_CACHE_ACCESS_L3_DATA; + FWK_R uint64_t L3_CACHE_ACCESS_SF_DATA; + uint8_t RESERVED6[0xC00 - 0xBA0]; + FWK_RW uint64_t L3_LOCK_WAYS; + FWK_RW uint64_t L3_LOCK_BASE[4]; + uint8_t RESERVED7[0xC30 - 0xC28]; + FWK_RW uint64_t RNID_REGION_VEC; + FWK_RW uint64_t RNF_REGION_VEC; + uint8_t RESERVED8[0xD00 - 0xC40]; + FWK_RW uint64_t SAM_CONTROL; + FWK_RW uint64_t SAM_MEMREGION[2]; + FWK_RW uint64_t SAM_SN_PROPERTIES; + FWK_RW uint64_t SAM_6SN_NODEID; + uint8_t RESERVED9[0x1000 - 0xD28]; + FWK_RW uint64_t PPU_PWPR; + FWK_RW uint64_t PPU_PWSR; + uint8_t RESERVED10[0x1014 - 0x1010]; + FWK_R uint32_t PPU_MISR; + uint8_t RESERVED11[0x1100 - 0x1018]; + FWK_RW uint64_t PPU_DYN_RET_THRESHOLD; + uint8_t RESERVED12[0x1FB0 - 0x1108]; + FWK_R uint32_t PPU_IDR[2]; + uint8_t RESERVED13[0x1FC8 - 0x1FB8]; + FWK_R uint32_t PPU_IIDR; + FWK_R uint32_t PPU_AIDR; + uint8_t RESERVED14[0x2000 - 0x1FD0]; + FWK_RW uint64_t PMU_EVENT_SEL; + uint8_t RESERVED15[0x3000 - 0x2008]; + FWK_R uint64_t ERRFR; + FWK_RW uint64_t ERRCTLR; + FWK_RW uint64_t ERRSTATUS; + FWK_RW uint64_t ERRADDR; + FWK_RW uint64_t ERRMISC; + uint8_t RESERVED16[0x3030 - 0x3028]; + FWK_RW uint64_t RN_ERR_INJ; + FWK_RW uint64_t RN_BYTE_PAR_ERR_INJ; + uint8_t RESERVED17[0x3100 - 0x3040]; + FWK_R uint64_t ERRFR_NS; + FWK_RW uint64_t ERRCTLR_NS; + FWK_RW uint64_t ERRSTATUS_NS; + FWK_RW uint64_t ERRADDR_NS; + FWK_RW uint64_t ERRMISC_NS; +}; + +/* + * AMBA 5 CHI to AXI bridge registers + */ +struct cmn600_sbsx_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0xA00 - 0x908]; + FWK_RW uint64_t AUX_CTL; + uint8_t RESERVED3[0x2000 - 0xA08]; + FWK_RW uint64_t PMU_EVENT_SEL; + uint8_t RESERVED4[0x3000 - 0x2008]; + FWK_R uint64_t ERRFR; + FWK_RW uint64_t ERRCTL; + FWK_RW uint64_t ERRSTATUS; + FWK_RW uint64_t ERRADDR; + FWK_RW uint64_t ERRMISC; + uint8_t RESERVED5[0x3100 - 0x3028]; + FWK_R uint64_t ERRFR_NS; + FWK_RW uint64_t ERRCTL_NS; + FWK_RW uint64_t ERRSTATUS_NS; + FWK_RW uint64_t ERRADDR_NS; + FWK_RW uint64_t ERRMISC_NS; +}; + +/* + * Configuration slave registers + */ +struct cmn600_cfgm_reg { + FWK_R uint64_t NODE_INFO; + FWK_RW uint64_t PERIPH_ID[4]; + FWK_RW uint64_t COMPONENT_ID[2]; + uint8_t RESERVED0[0x80 - 0x38]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x100 - 0x88]; + FWK_R uint64_t CHILD_POINTER[256]; + FWK_R uint64_t INFO_GLOBAL; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_ACCESS; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0x1000 - 0x990]; + FWK_RW uint64_t PPU_INT_MASK; + FWK_RW uint64_t PPU_INT_STATUS; + uint8_t RESERVED4[0x3000 - 0x1010]; + FWK_R uint64_t ERRGSR[8]; + uint8_t RESERVED5[0x3100 - 0x3040]; + FWK_R uint64_t ERRGSR_NS[8]; + uint8_t RESERVED6[0x3FA8 - 0x3140]; + FWK_R uint64_t ERRDEVAFF; + uint8_t RESERVED7[0x3FB8 - 0x3FB0]; + FWK_R uint64_t ERRDEVARCH; + uint8_t RESERVED8[0x3FC8 - 0x3FC0]; + FWK_R uint64_t ERRIDR; + FWK_R uint64_t ERRPIDR45; + FWK_R uint64_t ERRPIDR67; + FWK_R uint64_t ERRPIDR01; + FWK_R uint64_t ERRPIDR23; + FWK_R uint64_t ERRCIDR01; + FWK_R uint64_t ERRCIDR23; +}; + +/* + * Crosspoint (XP) registers + */ +struct cmn600_mxp_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x100 - 0x88]; + FWK_R uint64_t CHILD_POINTER[16]; + uint8_t RESERVED2[0x900 - 0x180]; + FWK_R uint64_t P0_INFO; + FWK_R uint64_t P1_INFO; + uint8_t RESERVED3[0x980 - 0x910]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED4[0xA00 - 0x988]; + FWK_RW uint64_t AUX_CTL; + uint8_t RESERVED5[0xA80 - 0xA08]; + struct cmn600_qos_reg P_QOS[2]; + uint8_t RESERVED6[0x1000 - 0xAC0]; + FWK_RW uint64_t P_SYSCOREQ_CTL[2]; + FWK_R uint64_t P_SYSCOACK_STATUS[2]; + uint8_t RESERVED7[0x2000 - 0x1020]; + FWK_RW uint64_t PMU_EVENT_SEL; + uint8_t RESERVED8[0x2100 - 0x2008]; + FWK_RW uint64_t DTM_CONTROL; + uint8_t RESERVED9[0x2118 - 0x2108]; + FWK_R uint64_t DTM_FIFO_ENTRY_READY; + FWK_R uint64_t DTM_FIFO_ENTRY0[3]; + FWK_R uint64_t DTM_FIFO_ENTRY1[3]; + FWK_R uint64_t DTM_FIFO_ENTRY2[3]; + FWK_R uint64_t DTM_FIFO_ENTRY3[3]; + uint8_t RESERVED10[0x21A0 - 0x2180]; + FWK_RW uint64_t DTM_WP0_CONFIG; + FWK_RW uint64_t DTM_WP0_VAL; + FWK_RW uint64_t DTM_WP0_MASK; + FWK_RW uint64_t DTM_WP1_CONFIG; + FWK_RW uint64_t DTM_WP1_VAL; + FWK_RW uint64_t DTM_WP1_MASK; + FWK_RW uint64_t DTM_WP2_CONFIG; + FWK_RW uint64_t DTM_WP2_VAL; + FWK_RW uint64_t DTM_WP2_MASK; + FWK_RW uint64_t DTM_WP3_CONFIG; + FWK_RW uint64_t DTM_WP3_VAL; + FWK_RW uint64_t DTM_WP3_MASK; + FWK_RW uint64_t PMSICR; + FWK_RW uint64_t PMSIRR; + FWK_RW uint64_t DTM_PMU_CONFIG; + uint8_t RESERVED11[0x2220 - 0x2218]; + FWK_RW uint64_t PMEVCNT[4]; + FWK_RW uint64_t PMEVCNTSR[4]; + uint8_t RESERVED12[0x3000 - 0x2260]; + FWK_R uint64_t ERRFR; + FWK_RW uint64_t ERRCTL; + FWK_RW uint64_t ERRSTATUS; + uint8_t RESERVED13[0x3028 - 0x3018]; + FWK_RW uint64_t ERRMISC; + FWK_W uint64_t P_BYTE_PAR_ERR_INJ[2]; + uint8_t RESERVED14[0x3100 - 0x3040]; + FWK_R uint64_t ERRFR_NS; + FWK_RW uint64_t ERRCTL_NS; + FWK_RW uint64_t ERRSTATUS_NS; + uint8_t RESERVED15[0x3128 - 0x3118]; + FWK_RW uint64_t ERRMISC_NS; +}; + +/* + * Request Node I/O (RN-I)registers + */ +struct cmn600_rni_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xA00 - 0x988]; + FWK_RW uint64_t CFG_CTL; + FWK_RW uint64_t AUX_CTL; + FWK_RW uint64_t S0_PORT_CONTRL; + FWK_RW uint64_t S1_PORT_CONTRL; + FWK_RW uint64_t S2_PORT_CONTRL; + uint8_t RESERVED4[0xA80 - 0xA28]; + struct cmn600_qos_reg S_QOS[3]; + uint8_t RESERVED5[0x2000 - 0xAE0]; + FWK_RW uint64_t PMU_EVENT_SEL; +}; + +/* + * Home Node I/O (HN-I) registers + */ +struct cmn600_hni_reg { + FWK_R uint64_t NODE_INFO; + uint8_t RESERVED0[0x80 - 0x8]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x900 - 0x88]; + FWK_R uint64_t UNIT_INFO; + uint8_t RESERVED2[0x980 - 0x908]; + FWK_RW uint64_t SECURE_REGISTER_GROUPS_OVERRIDE; + uint8_t RESERVED3[0xA00 - 0x988]; + FWK_RW uint64_t CFG_CTL; + FWK_RW uint64_t AUX_CTL; + uint8_t RESERVED4[0xC00 - 0xA10]; + FWK_RW uint64_t SAM_ADDRREGION_CFG[4]; + uint8_t RESERVED5[0x2000 - 0xC20]; + FWK_RW uint64_t PMU_EVENT_SEL; + uint8_t RESERVED6[0x3000 - 0x2008]; + FWK_R uint64_t ERRFR; + FWK_RW uint64_t ERRCTL; + FWK_RW uint64_t ERRSTATUS; + FWK_RW uint64_t ERRADDR; + FWK_RW uint64_t ERRMISC; + uint8_t RESERVED7[0x3100 - 0x3028]; + FWK_R uint64_t ERRFR_NS; + FWK_RW uint64_t ERRCTL_NS; + FWK_RW uint64_t ERRSTATUS_NS; + FWK_RW uint64_t ERRADDR_NS; + FWK_RW uint64_t ERRMISC_NS; +}; + +#define CMN600_NODE_INFO_TYPE UINT64_C(0x000000000000FFFF) +#define CMN600_NODE_INFO_ID UINT64_C(0x00000000FFFF0000) +#define CMN600_NODE_INFO_ID_POS 16 +#define CMN600_NODE_INFO_LOGICAL_ID UINT64_C(0x0000FFFF00000000) +#define CMN600_NODE_INFO_LOGICAL_ID_POS 32 + +#define CMN600_CHILD_INFO_COUNT UINT64_C(0x000000000000FFFF) + +#define CMN600_CHILD_POINTER UINT64_C(0x00000000FFFFFFFF) +#define CMN600_CHILD_POINTER_OFFSET UINT64_C(0x000000000FFFFFFF) +#define CMN600_CHILD_POINTER_EXT UINT64_C(0x0000000080000000) + +/* External child node */ +#define CMN600_CHILD_POINTER_EXT_REGISTER_OFFSET UINT64_C(0x0000000000003FFF) +#define CMN600_CHILD_POINTER_EXT_NODE_POINTER UINT64_C(0x000000000FFFC000) +#define CMN600_CHILD_POINTER_EXT_NODE_POINTER_POS 14 + +/* Used by NON_HASH_MEM_REGIONx and SYS_CACHE_GRP_REGIONx group registers */ +#define CMN600_RNSAM_REGION_ENTRY_VALID_POS 0 +#define CMN600_RNSAM_REGION_ENTRY_EN_POS 1 /* Not available for all regions */ +#define CMN600_RNSAM_REGION_ENTRY_TYPE_POS 2 +#define CMN600_RNSAM_REGION_ENTRY_SIZE_POS 4 +#define CMN600_RNSAM_REGION_ENTRY_BASE_POS 9 +#define CMN600_RNSAM_REGION_ENTRY_BITS_WIDTH 32 +#define CMN600_RNSAM_REGION_ENTRY_VALID UINT64_C(0x0000000000000001) +#define CMN600_RNSAM_REGION_ENTRY_MASK UINT64_C(0xFFFFFFFF) +#define CMN600_RNSAM_REGION_ENTRIES_PER_GROUP 2 + +#define CMN600_RNSAM_STATUS_UNSTALL UINT64_C(0x0000000000000002) + +#define CMN600_HNF_SAM_MEMREGION_SIZE_POS 12 +#define CMN600_HNF_SAM_MEMREGION_BASE_POS 26 +#define CMN600_HNF_SAM_MEMREGION_VALID UINT64_C(0x8000000000000000) + +#define CMN600_HNF_CACHE_GROUP_ENTRIES_MAX 32 +#define CMN600_HNF_CACHE_GROUP_ENTRIES_PER_GROUP 4 +#define CMN600_HNF_CACHE_GROUP_ENTRY_BITS_WIDTH 12 + +#define CMN600_HNI_SAM_REGION_CFG_SER_DEVNE_WR UINT64_C(0x1000000000000000) + +#define CMN600_RND_CFG_CTL_PCIE_MSTR_PRESENT UINT64_C(0x0000000000000020) + +#define CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRY_BITS_WIDTH 12 +#define CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK UINT64_C(0xFFF) +#define CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP 4 + +#define CMN600_PPU_PWPR_POLICY_OFF UINT64_C(0x0000000000000000) +#define CMN600_PPU_PWPR_POLICY_MEM_RET UINT64_C(0x0000000000000002) +#define CMN600_PPU_PWPR_POLICY_FUNC_RET UINT64_C(0x000000000000007) +#define CMN600_PPU_PWPR_POLICY_ON UINT64_C(0x0000000000000008) +#define CMN600_PPU_PWPR_OPMODE_NOSFSLC UINT64_C(0x0000000000000000) +#define CMN600_PPU_PWPR_OPMODE_SFONLY UINT64_C(0x0000000000000010) +#define CMN600_PPU_PWPR_OPMODE_HAM UINT64_C(0x0000000000000020) +#define CMN600_PPU_PWPR_OPMODE_FAM UINT64_C(0x0000000000000030) +#define CMN600_PPU_PWPR_DYN_EN UINT64_C(0x0000000000000100) + +/* Mesh and Node ID mapping */ +#define CMN600_MESH_X_MAX 8 +#define CMN600_MESH_Y_MAX 8 + +#define CMN600_NODE_ID_PORT_POS 2 +#define CMN600_NODE_ID_PORT_MASK 0x1 +#define CMN600_NODE_ID_Y_POS 3 + +#define CMN600_ROOT_NODE_OFFSET_PORT_POS 14 +#define CMN600_ROOT_NODE_OFFSET_Y_POS 20 + +/* + * Retrieve the number of child nodes of a given node + * + * \param node_base Pointer to the node descriptor + * \pre The node pointer must be valid + * + * \return Number of child nodes + */ +unsigned int get_node_child_count(void *node_base); + +/* + * Retrieve node type identifier + * + * \param node_base Pointer to the node descriptor + * \pre The node pointer must be valid + * + * \return Node's type identifier + */ +enum node_type get_node_type(void *node_base); + +/* + * Retrieve the physical identifier of a node from its hardware node descriptor. + * This identifier encodes the node's position in the mesh. + * + * Note: Multiple node descriptors can share the same identifier if they are + * related to the same device node in the mesh. + * + * \param node_base Pointer to the node descriptor + * \pre The node pointer must be valid + * + * \return Node's physical identifier + */ +unsigned int get_node_id(void *node_base); + +/* + * Retrieve the logical identifier of a node from its hardware node descriptor. + * This is an unique identifier (index) among nodes of the same type in the + * system. + * + * \param node_base Pointer to the node base address + * \pre The node pointer must be valid + * + * \return An integer representing the node's logical identifier + */ +unsigned int get_node_logical_id(void *node_base); + +/* + * Retrieve a child node given a node and child index + * + * \param node_base Pointer to the node descriptor + * \pre The node pointer must be valid + * \param child_index Child index + * \pre The child index must be valid + * + * \return Pointer to the child's node descriptor + */ +void *get_child_node(uintptr_t base, void *node_base, unsigned int child_index); + +/* + * Retrieve the physical identifier of a node using its child pointer in the + * parent's node hardware descriptor + * + * This function is used to extract a node's identifier without accessing the + * node descriptor. This is specially useful for external nodes that are in an + * unavailable power or clock domain. + * + * \param node_base Pointer to the parent node descriptor + * \pre The node pointer must be valid + * \param child_index Child index + * \pre The child index must be valid + * + * \return Physical child node identifier + */ +unsigned int get_child_node_id(void *node_base, unsigned int child_index); + +/* + * Verify if a child node (given a parent node base and child index) is an + * external node from the CMN600 instance point of view. + * + * \param node_base Pointer to the parent node descriptor + * \pre The node pointer must be valid + * \param child_index Child index + * \pre The child index must be valid + * + * \retval true if the node is external + * \retval false if the node is internal + */ +bool is_child_external(void *node_base, unsigned int child_index); + +/* + * Convert a memory region size into a size format used by the CMN600 registers + * The format is the binary logarithm of the memory region size represented as + * blocks multiple of the CMN600's granularity: + * n = log2(size / SAM_GRANULARITY) + * + * \param size Memory region size to be converted + * \pre size must be a multiple of SAM_GRANULARITY + * + * \return log2(size / SAM_GRANULARITY) + */ +uint64_t sam_encode_region_size(uint64_t size); + +/* + * Configure a memory region + * + * \param reg Pointer to the region group descriptor to be configured + * \pre Must be a valid pointer + * \param region Region entry in the region group descriptor + * \param bit_offset Bit offset of the memory region in the group descriptor + * \param base Region base address + * \param size Region size + * \param node_type Type of the target node + * + * \return None + */ +void configure_region(volatile uint64_t *reg, unsigned int bit_offset, + uint64_t base, uint64_t size, enum sam_node_type node_type); + +/* + * Retrieve the node type name + * + * \param node_type Node type + * + * \return Pointer to the node type name string + */ +const char *get_node_type_name(enum node_type node_type); + +/* + * Retrieve the node's position in the mesh along the X-axis + * + * \param node_base Pointer to the node descriptor + * + * \return Zero-indexed position along the X-axis + */ +unsigned int get_node_pos_x(void *node_base); + +/* + * Retrieve the node's position in the mesh along the Y-axis + * + * \param node_base Pointer to the node descriptor + * + * \return Zero-indexed position along the Y-axis + */ +unsigned int get_node_pos_y(void *node_base); + +/* + * Get the root node descriptor based on the peripheral base, HN-D node + * identifier and mesh size. + * + * \param base CMN600 peripheral base address + * \param hnd_node_id HN-D node identifier containing the global configuration + * \param mesh_size_x Size of the mesh along the x-axis + * \param mesh_size_y Size of the mesh along the x-axis + * + * \return Pointer to the root node descriptor + */ +struct cmn600_cfgm_reg *get_root_node(uintptr_t base, unsigned int hnd_node_id, + unsigned int mesh_size_x, unsigned int mesh_size_y); + +#endif /* CMN600_H */ diff --git a/module/cmn600/src/mod_cmn600.c b/module/cmn600/src/mod_cmn600.c new file mode 100644 index 0000000000000000000000000000000000000000..d96a08130097ecedfb6fc7e74252ee4d9ade5f86 --- /dev/null +++ b/module/cmn600/src/mod_cmn600.c @@ -0,0 +1,540 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOD_NAME "[CMN600] " + +/* External nodes that require RN-SAM mapping during run-time */ +struct external_rnsam_tuple { + unsigned int node_id; + struct cmn600_rnsam_reg *node; +}; + +struct cmn600_ctx { + const struct mod_cmn600_config *config; + + struct cmn600_cfgm_reg *root; + + /* Number of HN-F (system cache) nodes in the system */ + unsigned int hnf_count; + uint64_t *hnf_cache_group; + + /* + * External RN-SAMs. The driver keeps a list of tuples (node identifier and + * node pointers). The configuration of these nodes is via the SAM API. + */ + unsigned int external_rnsam_count; + struct external_rnsam_tuple *external_rnsam_table; + + /* + * Internal RN-SAMs. The driver keeps a list of RN-SAM pointers to + * configure them once the system has been fully discovered and all + * parameters are known + */ + unsigned int internal_rnsam_count; + struct cmn600_rnsam_reg **internal_rnsam_table; + + struct mod_log_api *log_api; +} *ctx; + +static void process_external_node(unsigned int node_id, void *node) +{ + static unsigned int entry = 0; + + assert(entry < ctx->external_rnsam_count); + + ctx->external_rnsam_table[entry].node_id = node_id; + ctx->external_rnsam_table[entry].node = node; + + entry++; +} + +static void process_node_hnf(struct cmn600_hnf_reg *hnf) +{ + unsigned int logical_id; + unsigned int group; + unsigned int bit_pos; + unsigned int region_idx; + unsigned int region_sub_count = 0; + const struct mod_cmn600_memory_region_map *region; + const struct mod_cmn600_config *config = ctx->config; + + logical_id = get_node_logical_id(hnf); + + assert(logical_id < config->snf_count); + + group = logical_id / CMN600_HNF_CACHE_GROUP_ENTRIES_PER_GROUP; + bit_pos = CMN600_HNF_CACHE_GROUP_ENTRY_BITS_WIDTH * + (logical_id % CMN600_HNF_CACHE_GROUP_ENTRIES_PER_GROUP); + + ctx->hnf_cache_group[group] += ((uint64_t)get_node_id(hnf)) << bit_pos; + + /* Set target node */ + hnf->SAM_CONTROL = config->snf_table[logical_id]; + + /* + * Map sub-regions to this HN-F node + */ + for (region_idx = 0; region_idx < config->mmap_count; region_idx++) { + region = &config->mmap_table[region_idx]; + + /* Skip non sub-regions */ + if (region->type != MOD_CMN600_REGION_TYPE_SYSCACHE_SUB) + continue; + + /* Configure sub-region entry */ + hnf->SAM_MEMREGION[region_sub_count] = region->node_id | + (sam_encode_region_size(region->size) << + CMN600_HNF_SAM_MEMREGION_SIZE_POS) | + ((region->base / SAM_GRANULARITY) << + CMN600_HNF_SAM_MEMREGION_BASE_POS) | + CMN600_HNF_SAM_MEMREGION_VALID; + + region_sub_count++; + } + + /* Configure the system cache RAM PPU */ + hnf->PPU_PWPR = CMN600_PPU_PWPR_POLICY_ON | + CMN600_PPU_PWPR_OPMODE_FAM | + CMN600_PPU_PWPR_DYN_EN; +} + +static void process_internal_node(void *node) +{ + static unsigned int rnsam_entry = 0; + enum node_type node_type; + + node_type = get_node_type(node); + + switch (node_type) { + case NODE_TYPE_HN_F: + process_node_hnf(node); + break; + + case NODE_TYPE_RN_SAM: + assert(rnsam_entry < ctx->internal_rnsam_count); + ctx->internal_rnsam_table[rnsam_entry++] = node; + break; + + default: + /* Nothing to be done for other node types */ + break; + } +} + +/* + * Scan the CMN600 to find out: + * - Number of external RN-SAM nodes + * - Number of internal RN-SAM nodes + * - Number of HN-F nodes (cache) + */ +static void cmn600_discovery(void) +{ + unsigned int xp_count; + unsigned int xp_idx; + unsigned int node_count; + unsigned int node_idx; + struct cmn600_mxp_reg *xp; + struct node_header *node; + const struct mod_cmn600_config *config = ctx->config; + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, MOD_NAME "Starting discovery...\n"); + + assert(get_node_type(ctx->root) == NODE_TYPE_CFG); + + /* Traverse cross points (XP) */ + xp_count = get_node_child_count(ctx->root); + for (xp_idx = 0; xp_idx < xp_count; xp_idx++) { + + xp = get_child_node(config->base, ctx->root, xp_idx); + assert(get_node_type(xp) == NODE_TYPE_XP); + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, MOD_NAME "\n"); + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME "XP (%d, %d) ID:%d, LID:%d\n", + get_node_pos_x(xp), + get_node_pos_y(xp), + get_node_id(xp), + get_node_logical_id(xp)); + + /* Traverse nodes */ + node_count = get_node_child_count(xp); + for (node_idx = 0; node_idx < node_count; node_idx++) { + + node = get_child_node(config->base, xp, node_idx); + + /* External nodes */ + if (is_child_external(xp, node_idx)) { + ctx->external_rnsam_count++; + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME " Found external node ID:%d\n", + get_child_node_id(xp, node_idx)); + + /* Internal nodes */ + } else { + switch (get_node_type(node)) { + case NODE_TYPE_HN_F: + ctx->hnf_count++; + break; + + case NODE_TYPE_RN_SAM: + ctx->internal_rnsam_count++; + break; + + default: + /* Nothing to be done for other node types */ + break; + } + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME " %s ID:%d, LID:%d\n", + get_node_type_name(get_node_type(node)), + get_node_id(node), + get_node_logical_id(node)); + } + } + } + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME "Total internal RN-SAM nodes: %d\n" + MOD_NAME "Total external RN-SAM nodes: %d\n" + MOD_NAME "Total HN-F nodes: %d\n", + ctx->internal_rnsam_count, + ctx->external_rnsam_count, + ctx->hnf_count); +} + +static void cmn600_configure(void) +{ + unsigned int xp_count; + unsigned int xp_idx; + unsigned int node_count; + unsigned int node_idx; + struct cmn600_mxp_reg *xp; + struct node_header *node; + const struct mod_cmn600_config *config = ctx->config; + + assert(get_node_type(ctx->root) == NODE_TYPE_CFG); + + /* Traverse cross points (XP) */ + xp_count = get_node_child_count(ctx->root); + for (xp_idx = 0; xp_idx < xp_count; xp_idx++) { + + xp = get_child_node(config->base, ctx->root, xp_idx); + assert(get_node_type(xp) == NODE_TYPE_XP); + + /* Traverse nodes */ + node_count = get_node_child_count(xp); + for (node_idx = 0; node_idx < node_count; node_idx++) { + + node = get_child_node(config->base, xp, node_idx); + + if (is_child_external(xp, node_idx)) + process_external_node(get_child_node_id(xp, node_idx), node); + else + process_internal_node(node); + } + } +} + +static const char * const mmap_type_name[] = { + [MOD_CMN600_MEMORY_REGION_TYPE_IO] = "I/O", + [MOD_CMN600_MEMORY_REGION_TYPE_SYSCACHE] = "System Cache", + [MOD_CMN600_REGION_TYPE_SYSCACHE_SUB] = "Sub-System Cache", +}; + +static int cmn600_setup_sam(struct cmn600_rnsam_reg *rnsam) +{ + unsigned int region_idx; + unsigned int region_io_count = 0; + const struct mod_cmn600_memory_region_map *region; + const struct mod_cmn600_config *config = ctx->config; + unsigned int bit_pos; + unsigned int group; + unsigned int group_count; + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME "Configuring SAM for node %d\n", + get_node_id(rnsam)); + + for (region_idx = 0; region_idx < config->mmap_count; region_idx++) { + region = &config->mmap_table[region_idx]; + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, + MOD_NAME " [0x%lx - 0x%lx] %s\n", + region->base, + region->base + region->size - 1, + mmap_type_name[region->type]); + + group = region_io_count / CMN600_RNSAM_REGION_ENTRIES_PER_GROUP; + bit_pos = (region_io_count % CMN600_RNSAM_REGION_ENTRIES_PER_GROUP) * + CMN600_RNSAM_REGION_ENTRY_BITS_WIDTH; + + switch (region->type) { + case MOD_CMN600_MEMORY_REGION_TYPE_IO: + /* + * Configure memory region + */ + configure_region(&rnsam->NON_HASH_MEM_REGION[group], + bit_pos, + region->base, + region->size, + SAM_NODE_TYPE_HN_I); + + /* + * Configure target node + */ + group = region_io_count / + CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP; + bit_pos = CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRY_BITS_WIDTH * + (region_io_count % + CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP); + + rnsam->NON_HASH_TGT_NODEID[group] &= + ~(CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK << bit_pos); + rnsam->NON_HASH_TGT_NODEID[group] |= (region->node_id & + CMN600_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK) << bit_pos; + + region_io_count++; + break; + + case MOD_CMN600_MEMORY_REGION_TYPE_SYSCACHE: + /* + * Configure memory region + */ + configure_region(&rnsam->SYS_CACHE_GRP_REGION[group], + bit_pos, + region->base, + region->size, + SAM_NODE_TYPE_HN_F); + break; + + case MOD_CMN600_REGION_TYPE_SYSCACHE_SUB: + /* Do nothing. System cache sub-regions are handled by HN-Fs */ + break; + + default: + assert(false); + return FWK_E_DATA; + } + } + + group_count = ctx->hnf_count / CMN600_HNF_CACHE_GROUP_ENTRIES_PER_GROUP; + for (group = 0; group < group_count; group++) + rnsam->SYS_CACHE_GRP_HN_NODEID[group] = ctx->hnf_cache_group[group]; + + /* Program the number of HNFs */ + rnsam->SYS_CACHE_GRP_HN_COUNT = ctx->hnf_count; + + /* Enable RNSAM */ + rnsam->STATUS = CMN600_RNSAM_STATUS_UNSTALL; + __sync_synchronize(); + + return FWK_SUCCESS; +} + +static int cmn600_setup(void) +{ + unsigned int rnsam_idx; + + cmn600_discovery(); + + /* + * Allocate resources based on the discovery + */ + + /* Pointers for the internal RN-SAM nodes */ + if (ctx->internal_rnsam_count != 0) { + ctx->internal_rnsam_table = fwk_mm_calloc(ctx->internal_rnsam_count, + sizeof(*ctx->internal_rnsam_table)); + if (ctx->internal_rnsam_table == NULL) + return FWK_E_NOMEM; + } + + /* Tuples for the external RN-RAM nodes (including their node IDs) */ + if (ctx->external_rnsam_count != 0) { + ctx->external_rnsam_table = fwk_mm_calloc(ctx->external_rnsam_count, + sizeof(*ctx->external_rnsam_table)); + if (ctx->external_rnsam_table == NULL) + return FWK_E_NOMEM; + } + + /* Cache groups */ + if (ctx->hnf_count != 0) { + /* + * Allocate enough group descriptors to accommodate all expected HN-F + * nodes in the system + */ + ctx->hnf_cache_group = fwk_mm_calloc(ctx->hnf_count / + CMN600_HNF_CACHE_GROUP_ENTRIES_PER_GROUP, + sizeof(*ctx->hnf_cache_group)); + if (ctx->hnf_cache_group == NULL) + return FWK_E_NOMEM; + } + + cmn600_configure(); + + /* Setup internal RN-SAM nodes */ + for (rnsam_idx = 0; rnsam_idx < ctx->internal_rnsam_count; rnsam_idx++) + cmn600_setup_sam(ctx->internal_rnsam_table[rnsam_idx]); + + ctx->log_api->log(MOD_LOG_GROUP_DEBUG, MOD_NAME "Done\n"); + + return FWK_SUCCESS; +} + +static int cmn600_setup_rnsam(unsigned int node_id) +{ + int status; + unsigned int node_idx; + + status = fwk_module_check_call(FWK_ID_MODULE(FWK_MODULE_IDX_CMN600)); + if (status != FWK_SUCCESS) + return status; + + for (node_idx = 0; node_idx < ctx->external_rnsam_count; node_idx++) { + if (ctx->external_rnsam_table[node_idx].node_id == node_id) { + cmn600_setup_sam(ctx->external_rnsam_table[node_idx].node); + return FWK_SUCCESS; + } + } + + return FWK_E_PARAM; +} + +/* + * PPUv1 State Observer API + */ + +static void post_ppu_on(void *data) +{ + assert(data != NULL); + cmn600_setup_rnsam(*(unsigned int *)data); +} + +static const struct mod_ppu_v1_power_state_observer_api cmn600_observer_api = { + .post_ppu_on = post_ppu_on, +}; + +/* + * Framework handlers + */ + +static int cmn600_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + const struct mod_cmn600_config *config = data; + + /* No elements support */ + if (element_count > 0) + return FWK_E_DATA; + + /* Allocate space for the context */ + ctx = fwk_mm_calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return FWK_E_NOMEM; + + if (config->base == 0) + return FWK_E_DATA; + + if ((config->mesh_size_x == 0) || (config->mesh_size_x > CMN600_MESH_X_MAX)) + return FWK_E_DATA; + + if ((config->mesh_size_y == 0) || (config->mesh_size_y > CMN600_MESH_Y_MAX)) + return FWK_E_DATA; + + if (config->snf_count > CMN600_HNF_CACHE_GROUP_ENTRIES_MAX) + return FWK_E_DATA; + + ctx->root = get_root_node(config->base, config->hnd_node_id, + config->mesh_size_x, config->mesh_size_y); + + ctx->config = config; + + return FWK_SUCCESS; +} + +static int cmn600_bind(fwk_id_t id, unsigned int round) +{ + int status; + + /* Use second round only (round numbering is zero-indexed) */ + if (round == 1) { + + /* Bind to the log component */ + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), + &ctx->log_api); + + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + } + + return FWK_SUCCESS; +} + +static int cmn600_process_bind_request(fwk_id_t requester_id, + fwk_id_t target_id, fwk_id_t api_id, const void **api) +{ + *api = &cmn600_observer_api; + return FWK_SUCCESS; +} + +int cmn600_start(fwk_id_t id) +{ + if (fwk_id_is_equal(ctx->config->clock_id, FWK_ID_NONE)) { + cmn600_setup(); + return FWK_SUCCESS; + } + + /* Register the module for clock state notifications */ + return fwk_notification_subscribe( + mod_clock_notification_id_state_changed, + ctx->config->clock_id, + id); +} + +static int cmn600_process_notification( + const struct fwk_event *event, + struct fwk_event *resp_event) +{ + struct clock_notification_params *params; + + assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); + assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); + + params = (struct clock_notification_params *)event->params; + + if (params->new_state == MOD_CLOCK_STATE_RUNNING) + cmn600_setup(); + + return FWK_SUCCESS; +} + +const struct fwk_module module_cmn600 = { + .name = "CMN600", + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = MOD_CMN600_API_COUNT, + .init = cmn600_init, + .bind = cmn600_bind, + .start = cmn600_start, + .process_bind_request = cmn600_process_bind_request, + .process_notification = cmn600_process_notification, +}; diff --git a/module/ddr_phy500/include/mod_ddr_phy500.h b/module/ddr_phy500/include/mod_ddr_phy500.h index 1bf5e5451555af8d3deec4425befd6fc409478c7..4bb8bc58a878daa9b78843c23e186b6e0b3e4bf0 100644 --- a/module/ddr_phy500/include/mod_ddr_phy500.h +++ b/module/ddr_phy500/include/mod_ddr_phy500.h @@ -10,6 +10,7 @@ #ifndef MOD_DDR_PHY500_H #define MOD_DDR_PHY500_H +#include #include #include #include @@ -43,20 +44,20 @@ struct mod_ddr_phy500_reg { FWK_RW uint32_t T_WRLAT; FWK_RW uint32_t T_RDDATA_EN; FWK_RW uint32_t T_RDLAT; - FWK_RW uint32_t RESERVED1; - FWK_R uint32_t RESERVED2; - FWK_R uint32_t LP_REQ; - FWK_RW uint32_t LP_ACK; - FWK_RW uint32_t RDLVL_REQ; - FWK_R uint32_t RDLVL_EN; - FWK_RW uint32_t WRLVL_REQ; - FWK_RW uint32_t WRLVL_EN; - FWK_RW uint32_t MSTR_REQ; - FWK_RW uint32_t MSTR_ACK; + FWK_RW uint32_t DFI_PHYUPD_REQ; + FWK_R uint32_t DFI_PHYUPD_ACK; + FWK_R uint32_t DFI_LP_REQ; + FWK_RW uint32_t DFI_LP_ACK; + FWK_RW uint32_t DFI_RDLVL_REQ; + FWK_R uint32_t DFI_RDLVL_EN; + FWK_RW uint32_t DFI_WRLVL_REQ; + FWK_R uint32_t DFI_WRLVL_EN; + FWK_RW uint32_t DFI_PHYMSTR_REQ; + FWK_RW uint32_t DFI_PHYMSTR_ACK; FWK_RW uint32_t DFI_WR_PREMBL; - FWK_R uint8_t RESERVED3[0x820 - 0x50]; + uint8_t RESERVED[0x820 - 0x50]; FWK_RW uint32_t DELAY_SEL; - FWK_R uint32_t RESERVED4; + FWK_RW uint32_t REF_EN; FWK_RW uint32_t T_CTRL_UPD_MIN; /*! * \endcond @@ -82,6 +83,18 @@ struct mod_ddr_phy500_module_config { * represented by elements in the module's element table. */ const struct mod_ddr_phy500_reg *ddr_reg_val; + + /*! + * Indicate whether the \c INIT_COMPLETE register of the peripheral needs to + * be initialized. + */ + bool initialize_init_complete; + + /*! + * Indicate whether the \c REF_EN register of the peripheral needs to be + * initialized. + */ + bool initialize_ref_en; }; /*! diff --git a/module/ddr_phy500/src/mod_ddr_phy500.c b/module/ddr_phy500/src/mod_ddr_phy500.c index 7f43285369d212845c2e6bacf90e63f772398fe2..9971464f283f40cae9c8dbc0accad6a1ae1c4c38 100644 --- a/module/ddr_phy500/src/mod_ddr_phy500.c +++ b/module/ddr_phy500/src/mod_ddr_phy500.c @@ -15,7 +15,14 @@ #include #include #include -#include + +#ifdef BUILD_HAS_MOD_DMC500 + #include +#endif + +#ifdef BUILD_HAS_MOD_DMC620 + #include +#endif static struct mod_log_api *log_api; @@ -44,6 +51,9 @@ static int ddr_phy500_config(fwk_id_t element_id) if (status != FWK_SUCCESS) return status; + if (module_config->initialize_init_complete) + ddr->INIT_COMPLETE = module_config->ddr_reg_val->INIT_COMPLETE; + ddr->T_CTRL_DELAY = module_config->ddr_reg_val->T_CTRL_DELAY; ddr->READ_DELAY = module_config->ddr_reg_val->READ_DELAY; ddr->T_CTRL_UPD_MIN = module_config->ddr_reg_val->T_CTRL_UPD_MIN; @@ -55,12 +65,15 @@ static int ddr_phy500_config(fwk_id_t element_id) ddr->T_WRLAT = module_config->ddr_reg_val->T_WRLAT; ddr->DFI_WR_PREMBL = module_config->ddr_reg_val->DFI_WR_PREMBL; - ddr->LP_ACK = module_config->ddr_reg_val->LP_ACK; + ddr->DFI_LP_ACK = module_config->ddr_reg_val->DFI_LP_ACK; + + if (module_config->initialize_ref_en) + ddr->REF_EN = module_config->ddr_reg_val->REF_EN; return FWK_SUCCESS; } -static struct mod_dmc500_ddr_phy_api ddr_phy500_api = { +static struct mod_dmc_ddr_phy_api ddr_phy500_api = { .configure = ddr_phy500_config, }; diff --git a/module/dmc500/include/mod_dmc500.h b/module/dmc500/include/mod_dmc500.h index 7f42436365fa2daddf410bdb992568b6857665d8..8bd686004122fba09b368d7cc5c2bce89c21550d 100644 --- a/module/dmc500/include/mod_dmc500.h +++ b/module/dmc500/include/mod_dmc500.h @@ -521,11 +521,11 @@ struct mod_dmc500_element_config { }; /*! - * \brief API of the DDR PHY associate to the DMC + * \brief API of the DDR PHY associated to the DMC */ -struct mod_dmc500_ddr_phy_api { +struct mod_dmc_ddr_phy_api { /*! - * \brief Configure a DDR PHY500 device + * \brief Configure a DDR physical device * * \param element_id Element identifier corresponding to the device to * configure. diff --git a/module/dmc500/src/mod_dmc500.c b/module/dmc500/src/mod_dmc500.c index bbbec13f788fab4b2af1f9afcb26f314dd9d414b..664faf6935c754195ffe2ff70e7b9f2e302d705b 100644 --- a/module/dmc500/src/mod_dmc500.c +++ b/module/dmc500/src/mod_dmc500.c @@ -16,7 +16,7 @@ #include static struct mod_log_api *log_api; -static struct mod_dmc500_ddr_phy_api *ddr_phy_api; +static struct mod_dmc_ddr_phy_api *ddr_phy_api; static struct mod_timer_api *timer_api; static int dmc500_config(struct mod_dmc500_reg *dmc, fwk_id_t ddr_phy_id); diff --git a/module/dmc620/include/mod_dmc620.h b/module/dmc620/include/mod_dmc620.h new file mode 100644 index 0000000000000000000000000000000000000000..9b93c66714990d94fc0386f7e532854bdf3c466a --- /dev/null +++ b/module/dmc620/include/mod_dmc620.h @@ -0,0 +1,670 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * DMC-620 module. + */ + +#ifndef MOD_DMC620_H +#define MOD_DMC620_H + +#include +#include +#include + +/*! + * \addtogroup GroupModules Modules + * @{ + */ + +/*! + * \addtogroup GroupDMC620 DMC-620 Driver + * + * \details Please consult the Arm CoreLink DMC-620 Dynamic Memory Controller + * Technical Reference Manual for details on the specific registers that + * are programmed here. + * + * \sa https://developer.arm.com/docs/100568/latest/programmers-model/register-summary + * @{ + */ + +/*! + * \brief Number of access addresses + */ +#define MOD_DMC620_ACCESS_ADDRESS_COUNT 8 + +/*! + * \brief Access address next registers + */ +struct mod_dmc620_access_address_next { + /*! + * \cond + * @{ + */ + FWK_RW uint32_t MIN_31_00; + FWK_RW uint32_t MIN_43_32; + FWK_RW uint32_t MAX_31_00; + FWK_RW uint32_t MAX_43_32; + /*! + * \endcond + * @} + */ +}; + +/*! + * \brief Access address next registers + */ +struct mod_dmc620_access_address_now { + /*! + * \cond + * @{ + */ + FWK_R uint32_t MIN_31_00; + FWK_R uint32_t MIN_43_32; + FWK_R uint32_t MAX_31_00; + FWK_R uint32_t MAX_43_32; + /*! + * \endcond + * @} + */ +}; + +/*! + * \brief PMU payload information operation register + */ +struct mod_dmc620_pmu_counter { + /*! + * \cond + * @{ + */ + FWK_RW uint32_t MASK_31_00; + FWK_RW uint32_t MASK_63_32; + FWK_RW uint32_t MATCH_31_00; + FWK_RW uint32_t MATCH_63_32; + FWK_RW uint32_t CONTROL; + uint32_t RESERVED0; + FWK_R uint32_t SNAPSHOT_VALUE_31_00; + uint32_t RESERVED1; + FWK_RW uint32_t VALUE_31_00; + uint32_t RESERVED2; + /*! + * \endcond + * @} + */ +}; + +/*! + * \brief DMC-620 register definitions + */ +struct mod_dmc620_reg { + /*! + * \cond + * @{ + */ + FWK_R uint32_t MEMC_STATUS; + FWK_R uint32_t MEMC_CONFIG; + FWK_W uint32_t MEMC_CMD; + uint32_t RESERVED1; + FWK_RW uint32_t ADDRESS_CONTROL_NEXT; + FWK_RW uint32_t DECODE_CONTROL_NEXT; + FWK_RW uint32_t FORMAT_CONTROL; + FWK_RW uint32_t ADDRESS_MAP_NEXT; + FWK_RW uint32_t LOW_POWER_CONTROL_NEXT; + uint32_t RESERVED2; + FWK_RW uint32_t TURNAROUND_CONTROL_NEXT; + FWK_RW uint32_t HIT_TURNAROUND_CONTROL_NEXT; + FWK_RW uint32_t QOS_CLASS_CONTROL_NEXT; + FWK_RW uint32_t ESCALATION_CONTROL_NEXT; + FWK_RW uint32_t QV_CONTROL_31_00_NEXT; + FWK_RW uint32_t QV_CONTROL_63_32_NEXT; + FWK_RW uint32_t RT_CONTROL_31_00_NEXT; + FWK_RW uint32_t RT_CONTROL_63_32_NEXT; + FWK_RW uint32_t TIMEOUT_CONTROL_NEXT; + FWK_RW uint32_t CREDIT_CONTROL_NEXT; + FWK_RW uint32_t WRITE_PRIORITY_CONTROL_31_00_NEXT; + FWK_RW uint32_t WRITE_PRIORITY_CONTROL_63_32_NEXT; + FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_31_00_NEXT; + FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_63_32_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_31_00_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_63_32_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_95_64_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_127_96_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_159_128_NEXT; + FWK_RW uint32_t ADDRESS_SHUTTER_191_160_NEXT; + FWK_RW uint32_t MEMORY_ADDRESS_MAX_31_00_NEXT; + FWK_RW uint32_t MEMORY_ADDRESS_MAX_43_32_NEXT; + struct mod_dmc620_access_address_next ACCESS_ADDRESS_NEXT + [MOD_DMC620_ACCESS_ADDRESS_COUNT]; + FWK_R uint32_t CHANNEL_STATUS; + FWK_R uint32_t CHANNEL_STATUS_63_32; + FWK_RW uint32_t DIRECT_ADDR; + FWK_W uint32_t DIRECT_CMD; + FWK_RW uint32_t DCI_REPLAY_TYPE_NEXT; + FWK_RW uint32_t DIRECT_CONTROL_NEXT; + FWK_RW uint32_t DCI_STRB; + FWK_RW uint32_t DCI_DATA; + FWK_RW uint32_t REFRESH_CONTROL_NEXT; + uint32_t RESERVED3; + FWK_RW uint32_t MEMORY_TYPE_NEXT; + uint32_t RESERVED4; + FWK_RW uint32_t FEATURE_CONFIG; + uint32_t RESERVED5; + FWK_RW uint32_t NIBBLE_FAILED_031_000; + FWK_RW uint32_t NIBBLE_FAILED_063_032; + FWK_RW uint32_t NIBBLE_FAILED_095_064; + FWK_RW uint32_t NIBBLE_FAILED_127_096; + FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_031_000; + FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_063_032; + FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_095_064; + FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_127_096; + uint8_t RESERVED6[0x16C - 0x158]; + FWK_RW uint32_t LINK_ERR_COUNT; + FWK_RW uint32_t SCRUB_CONTROL0_NEXT; + FWK_RW uint32_t SCRUB_ADDRESS_MIN0_NEXT; + FWK_RW uint32_t SCRUB_ADDRESS_MAX0_NEXT; + FWK_R uint32_t SCRUB_ADDRESS_CURRENT0; + FWK_RW uint32_t SCRUB_CONTROL1_NEXT; + FWK_RW uint32_t SCRUB_ADDRESS_MIN1_NEXT; + FWK_RW uint32_t SCRUB_ADDRESS_MAX1_NEXT; + FWK_R uint32_t SCRUB_ADDRESS_CURRENT1; + uint8_t RESERVED7[0x1A0 - 0x190]; + FWK_RW uint32_t CS_REMAP_CONTROL_31_00_NEXT; + FWK_RW uint32_t CS_REMAP_CONTROL_63_32_NEXT; + FWK_RW uint32_t CS_REMAP_CONTROL_95_64_NEXT; + FWK_RW uint32_t CS_REMAP_CONTROL_127_96_NEXT; + FWK_RW uint32_t CID_REMAP_CONTROL_31_00_NEXT; + FWK_RW uint32_t CID_REMAP_CONTROL_63_32_NEXT; + uint8_t RESERVED8[0x1C0 - 0x1B8]; + FWK_RW uint32_t CKE_REMAP_CONTROL_NEXT; + FWK_RW uint32_t RST_REMAP_CONTROL_NEXT; + FWK_RW uint32_t CK_REMAP_CONTROL_NEXT; + uint32_t RESERVED9; + FWK_RW uint32_t POWER_GROUP_CONTROL_31_00_NEXT; + FWK_RW uint32_t POWER_GROUP_CONTROL_63_32_NEXT; + FWK_RW uint32_t POWER_GROUP_CONTROL_95_64_NEXT; + FWK_RW uint32_t POWER_GROUP_CONTROL_127_96_NEXT; + FWK_RW uint32_t PHY_RDWRDATA_CS_MASK_31_00; + FWK_RW uint32_t PHY_RDWRDATA_CS_MASK_63_32; + FWK_RW uint32_t PHY_REQUEST_CS_REMAP; + uint32_t RESERVED10; + FWK_RW uint32_t FEATURE_CONTROL_NEXT; + FWK_RW uint32_t MUX_CONTROL_NEXT; + FWK_RW uint32_t RANK_REMAP_CONTROL_NEXT; + uint32_t RESERVED11; + FWK_RW uint32_t T_REFI_NEXT; + FWK_RW uint32_t T_RFC_NEXT; + FWK_RW uint32_t T_MRR_NEXT; + FWK_RW uint32_t T_MRW_NEXT; + uint8_t RESERVED12[0x218 - 0x210]; + FWK_RW uint32_t T_RCD_NEXT; + FWK_RW uint32_t T_RAS_NEXT; + FWK_RW uint32_t T_RP_NEXT; + FWK_RW uint32_t T_RPALL_NEXT; + FWK_RW uint32_t T_RRD_NEXT; + FWK_RW uint32_t T_ACT_WINDOW_NEXT; + uint32_t RESERVED13; + FWK_RW uint32_t T_RTR_NEXT; + FWK_RW uint32_t T_RTW_NEXT; + FWK_RW uint32_t T_RTP_NEXT; + uint32_t RESERVED14; + FWK_RW uint32_t T_WR_NEXT; + FWK_RW uint32_t T_WTR_NEXT; + FWK_RW uint32_t T_WTW_NEXT; + uint32_t RESERVED15; + FWK_RW uint32_t T_XMPD_NEXT; + FWK_RW uint32_t T_EP_NEXT; + FWK_RW uint32_t T_XP_NEXT; + FWK_RW uint32_t T_ESR_NEXT; + FWK_RW uint32_t T_XSR_NEXT; + FWK_RW uint32_t T_ESRCK_NEXT; + FWK_RW uint32_t T_CKXSR_NEXT; + FWK_RW uint32_t T_CMD_NEXT; + FWK_RW uint32_t T_PARITY_NEXT; + FWK_RW uint32_t T_ZQCS_NEXT; + FWK_RW uint32_t T_RW_ODT_CLR_NEXT; + uint8_t RESERVED16[0x300 - 0x280]; + FWK_RW uint32_t T_RDDATA_EN_NEXT; + FWK_RW uint32_t T_PHYRDLAT_NEXT; + FWK_RW uint32_t T_PHYWRLAT_NEXT; + uint32_t RESERVED17; + FWK_RW uint32_t RDLVL_CONTROL_NEXT; + FWK_RW uint32_t RDLVL_MRS_NEXT; + FWK_RW uint32_t T_RDLVL_EN_NEXT; + FWK_RW uint32_t T_RDLVL_RR_NEXT; + FWK_RW uint32_t WRLVL_CONTROL_NEXT; + FWK_RW uint32_t WRLVL_MRS_NEXT; + FWK_RW uint32_t T_WRLVL_EN_NEXT; + FWK_RW uint32_t T_WRLVL_WW_NEXT; + uint32_t RESERVED18; + FWK_R uint32_t TRAINING_WRLVL_SLICE_STATUS; + FWK_R uint32_t TRAINING_RDLVL_SLICE_STATUS; + FWK_R uint32_t TRAINING_RDLVL_GATE_SLICE_STATUS; + FWK_R uint32_t TRAINING_WDQLVL_SLICE_STATUS; + FWK_R uint32_t TRAINING_WDQLVL_SLICE_RESULT; + FWK_RW uint32_t PHY_POWER_CONTROL_NEXT; + FWK_RW uint32_t T_LPRESP_NEXT; + FWK_RW uint32_t PHY_UPDATE_CONTROL_NEXT; + FWK_RW uint32_t T_ODTH_NEXT; + FWK_RW uint32_t ODT_TIMING_NEXT; + uint32_t RESERVED19; + FWK_RW uint32_t ODT_WR_CONTROL_31_00_NEXT; + FWK_RW uint32_t ODT_WR_CONTROL_63_32_NEXT; + FWK_RW uint32_t ODT_RD_CONTROL_31_00_NEXT; + FWK_RW uint32_t ODT_RD_CONTROL_63_32_NEXT; + FWK_R uint32_t TEMPERATURE_READOUT; + uint32_t RESERVED20; + FWK_R uint32_t TRAINING_STATUS; + FWK_R uint32_t TRAINING_STATUS_63_32; + FWK_RW uint32_t DQ_MAP_CONTROL_15_00_NEXT; + FWK_RW uint32_t DQ_MAP_CONTROL_31_16_NEXT; + FWK_RW uint32_t DQ_MAP_CONTROL_47_32_NEXT; + FWK_RW uint32_t DQ_MAP_CONTROL_63_48_NEXT; + FWK_RW uint32_t DQ_MAP_CONTROL_71_64_NEXT; + uint32_t RESERVED21; + FWK_R uint32_t RANK_STATUS; + FWK_R uint32_t MODE_CHANGE_STATUS; + uint8_t RESERVED22[0x3B0 - 0x3A0]; + FWK_RW uint32_t ODT_CP_CONTROL_31_00_NEXT; + FWK_RW uint32_t ODT_CP_CONTROL_63_32_NEXT; + uint8_t RESERVED23[0x400 - 0x3B8]; + FWK_R uint32_t USER_STATUS; + uint32_t RESERVED24; + FWK_RW uint32_t USER_CONFIG0_NEXT; + FWK_RW uint32_t USER_CONFIG1_NEXT; + FWK_RW uint32_t USER_CONFIG2; + FWK_RW uint32_t USER_CONFIG3; + uint8_t RESERVED25[0x500 - 0x418]; + FWK_RW uint32_t INTERRUPT_CONTROL; + uint32_t RESERVED26; + FWK_W uint32_t INTERRUPT_CLR; + uint32_t RESERVED27; + FWK_R uint32_t INTERRUPT_STATUS; + uint8_t RESERVED28[0x538 - 0x514]; + FWK_R uint32_t FAILED_ACCESS_INT_INFO_31_00; + FWK_R uint32_t FAILED_ACCESS_INT_INFO_63_32; + FWK_R uint32_t FAILED_PROG_INT_INFO_31_00; + FWK_R uint32_t FAILED_PROG_INT_INFO_63_32; + FWK_R uint32_t LINK_ERR_INT_INFO_31_00; + FWK_R uint32_t LINK_ERR_INT_INFO_63_32; + FWK_R uint32_t ARCH_FSM_INT_INFO_31_00; + FWK_R uint32_t ARCH_FSM_INT_INFO_63_32; + uint8_t RESERVED29[0x610 - 0x558]; + FWK_RW uint32_t T_DB_TRAIN_RESP_NEXT; + FWK_RW uint32_t T_LVL_DISCONNECT_NEXT; + uint8_t RESERVED30[0x620 - 0x618]; + FWK_RW uint32_t WDQLVL_CONTROL_NEXT; + FWK_RW uint32_t WDQLVL_VREFDQ_TRAIN_MRS_NEXT; + FWK_RW uint32_t WDQLVL_ADDRESS_31_00_NEXT; + FWK_RW uint32_t WDQLVL_ADDRESS_63_32_NEXT; + FWK_RW uint32_t T_WDQLVL_EN_NEXT; + FWK_RW uint32_t T_WDQLVL_WW_NEXT; + FWK_RW uint32_t T_WDQLVL_RW_NEXT; + FWK_R uint32_t TRAINING_WDQLVL_SLICE_RESP; + FWK_R uint32_t TRAINING_RDLVL_SLICE_RESP; + uint8_t RESERVED31[0x654 - 0x644]; + FWK_RW uint32_t PHYMSTR_CONTROL_NEXT; + uint8_t RESERVED32[0x700 - 0x658]; + FWK_R uint32_t ERR0FR; + uint32_t RESERVED33; + FWK_RW uint32_t ERR0CTLR0; + FWK_RW uint32_t ERR0CTLR1; + FWK_R uint32_t ERR0STATUS; + uint8_t RESERVED34[0x740 - 0x714]; + FWK_R uint32_t ERR1FR; + uint32_t RESERVED35; + FWK_R uint32_t ERR1CTLR; + uint32_t RESERVED36; + FWK_R uint32_t ERR1STATUS; + uint32_t RESERVED37; + FWK_RW uint32_t ERR1ADDR0; + FWK_RW uint32_t ERR1ADDR1; + FWK_RW uint32_t ERR1MISC0; + FWK_RW uint32_t ERR1MISC1; + FWK_RW uint32_t ERR1MISC2; + FWK_RW uint32_t ERR1MISC3; + FWK_RW uint32_t ERR1MISC4; + FWK_RW uint32_t ERR1MISC5; + uint8_t RESERVED38[0x780 - 0x778]; + FWK_R uint32_t ERR2FR; + uint32_t RESERVED39; + FWK_R uint32_t ERR2CTLR; + uint32_t RESERVED40; + FWK_R uint32_t ERR2STATUS; + uint32_t RESERVED41; + FWK_RW uint32_t ERR2ADDR0; + FWK_RW uint32_t ERR2ADDR1; + FWK_RW uint32_t ERR2MISC0; + FWK_RW uint32_t ERR2MISC1; + FWK_RW uint32_t ERR2MISC2; + FWK_RW uint32_t ERR2MISC3; + FWK_RW uint32_t ERR2MISC4; + FWK_RW uint32_t ERR2MISC5; + uint8_t RESERVED42[0x7C0 - 0x7B8]; + FWK_R uint32_t ERR3FR; + uint32_t RESERVED43; + FWK_R uint32_t ERR3CTLR; + uint32_t RESERVED44; + FWK_R uint32_t ERR3STATUS; + uint32_t RESERVED45; + FWK_RW uint32_t ERR3ADDR0; + FWK_RW uint32_t ERR3ADDR1; + uint8_t RESERVED46[0x800 - 0x7E0]; + FWK_R uint32_t ERR4FR; + uint32_t RESERVED47; + FWK_R uint32_t ERR4CTLR; + uint32_t RESERVED48; + FWK_R uint32_t ERR4STATUS; + uint32_t RESERVED49; + FWK_RW uint32_t ERR4ADDR0; + FWK_RW uint32_t ERR4ADDR1; + FWK_RW uint32_t ERR4MISC0; + FWK_RW uint32_t ERR4MISC1; + FWK_RW uint32_t ERR4MISC2; + uint8_t RESERVED50[0x840 - 0x82C]; + FWK_R uint32_t ERR5FR; + uint32_t RESERVED51; + FWK_R uint32_t ERR5CTLR; + uint32_t RESERVED52; + FWK_R uint32_t ERR5STATUS; + uint32_t RESERVED53; + FWK_RW uint32_t ERR5ADDR0; + FWK_RW uint32_t ERR5ADDR1; + FWK_RW uint32_t ERR5MISC0; + FWK_RW uint32_t ERR5MISC1; + FWK_RW uint32_t ERR5MISC2; + uint8_t RESERVED54[0x880 - 0x86C]; + FWK_R uint32_t ERR6FR; + uint32_t RESERVED55; + FWK_R uint32_t ERR6CTLR; + uint32_t RESERVED56; + FWK_R uint32_t ERR6STATUS; + uint32_t RESERVED57; + FWK_RW uint32_t ERR6ADDR0; + FWK_RW uint32_t ERR6ADDR1; + FWK_RW uint32_t ERR6MISC0; + FWK_RW uint32_t ERR6MISC1; + uint8_t RESERVED58[0x920 - 0x8A8]; + FWK_RW uint32_t ERRGSR; + uint8_t RESERVED59[0xA00 - 0x924]; + FWK_W uint32_t PMU_SNAPSHOT_REQ; + FWK_R uint32_t PMU_SNAPSHOT_ACK; + FWK_RW uint32_t PMU_OVERFLOW_STATUS_CLKDIV2; + FWK_RW uint32_t PMU_OVERFLOW_STATUS_CLK; + struct mod_dmc620_pmu_counter PMC_CLKDIV2_COUNT[8]; + struct mod_dmc620_pmu_counter PMC_CLK_COUNT[2]; + uint8_t RESERVED60[0xE00 - 0xBA0]; + FWK_RW uint32_t INTEG_CFG; + uint32_t RESERVED61; + FWK_W uint32_t INTEG_OUTPUTS; + uint8_t RESERVED62[0x1010 - 0xE0C]; + FWK_R uint32_t ADDRESS_CONTROL_NOW; + FWK_R uint32_t DECODE_CONTROL_NOW; + uint32_t RESERVED63; + FWK_R uint32_t ADDRESS_MAP_NOW; + FWK_R uint32_t LOW_POWER_CONTROL_NOW; + uint32_t RESERVED64; + FWK_R uint32_t TURNAROUND_CONTROL_NOW; + FWK_R uint32_t HIT_TURNAROUND_CONTROL_NOW; + FWK_R uint32_t QOS_CLASS_CONTROL_NOW; + FWK_R uint32_t ESCALATION_CONTROL_NOW; + FWK_R uint32_t QV_CONTROL_31_00_NOW; + FWK_R uint32_t QV_CONTROL_63_32_NOW; + FWK_R uint32_t RT_CONTROL_31_00_NOW; + FWK_R uint32_t RT_CONTROL_63_32_NOW; + FWK_R uint32_t TIMEOUT_CONTROL_NOW; + FWK_R uint32_t CREDIT_CONTROL_NOW; + FWK_R uint32_t WRITE_PRIORITY_CONTROL_31_00_NOW; + FWK_R uint32_t WRITE_PRIORITY_CONTROL_63_32_NOW; + FWK_R uint32_t QUEUE_THRESHOLD_CONTROL_31_00_NOW; + FWK_R uint32_t QUEUE_THRESHOLD_CONTROL_63_32_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_31_00_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_63_32_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_95_64_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_127_96_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_159_128_NOW; + FWK_R uint32_t ADDRESS_SHUTTER_191_160_NOW; + FWK_R uint32_t MEMORY_ADDRESS_MAX_31_00_NOW; + FWK_R uint32_t MEMORY_ADDRESS_MAX_43_32_NOW; + struct mod_dmc620_access_address_now ACCESS_ADDRESS_NOW + [MOD_DMC620_ACCESS_ADDRESS_COUNT]; + uint8_t RESERVED65[0x1110 - 0x1100]; + FWK_R uint32_t DCI_REPLAY_TYPE_NOW; + FWK_R uint32_t DIRECT_CONTROL_NOW; + uint8_t RESERVED66[0x1120 - 0x1118]; + FWK_R uint32_t REFRESH_CONTROL_NOW; + uint32_t RESERVED67; + FWK_R uint32_t MEMORY_TYPE_NOW; + uint8_t RESERVED68[0x1170 - 0x112C]; + FWK_R uint32_t SCRUB_CONTROL0_NOW; + FWK_R uint32_t SCRUB_ADDRESS_MIN0_NOW; + FWK_R uint32_t SCRUB_ADDRESS_MAX0_NOW; + uint32_t RESERVED69; + FWK_R uint32_t SCRUB_CONTROL1_NOW; + FWK_R uint32_t SCRUB_ADDRESS_MIN1_NOW; + FWK_R uint32_t SCRUB_ADDRESS_MAX1_NOW; + uint8_t RESERVED70[0x11A0 - 0x118C]; + FWK_R uint32_t CS_REMAP_CONTROL_31_00_NOW; + FWK_R uint32_t CS_REMAP_CONTROL_63_32_NOW; + FWK_R uint32_t CS_REMAP_CONTROL_95_64_NOW; + FWK_R uint32_t CS_REMAP_CONTROL_127_96_NOW; + FWK_R uint32_t CID_REMAP_CONTROL_31_00_NOW; + FWK_R uint32_t CID_REMAP_CONTROL_63_32_NOW; + uint8_t RESERVED71[0x11C0 - 0x11B8]; + FWK_R uint32_t CKE_REMAP_CONTROL_31_00_NOW; + FWK_R uint32_t RST_REMAP_CONTROL_31_00_NOW; + FWK_R uint32_t CK_REMAP_CONTROL_31_00_NOW; + FWK_R uint32_t POWER_GROUP_CONTROL_31_00_NOW; + FWK_R uint32_t POWER_GROUP_CONTROL_63_32_NOW; + FWK_R uint32_t POWER_GROUP_CONTROL_95_64_NOW; + FWK_R uint32_t POWER_GROUP_CONTROL_127_96_NOW; + uint8_t RESERVED72[0x11F0 - 0x11E0]; + FWK_R uint32_t FEATURE_CONTROL_NOW; + FWK_R uint32_t MUX_CONTROL_NOW; + FWK_R uint32_t RANK_REMAP_CONTROL_NOW; + uint32_t RESERVED73; + FWK_R uint32_t T_REFI_NOW; + FWK_R uint32_t T_RFC_NOW; + FWK_R uint32_t T_MRR_NOW; + FWK_R uint32_t T_MRW_NOW; + uint8_t RESERVED74[0x1218 - 0x1210]; + FWK_R uint32_t T_RCD_NOW; + FWK_R uint32_t T_RAS_NOW; + FWK_R uint32_t T_RP_NOW; + FWK_R uint32_t T_RPALL_NOW; + FWK_R uint32_t T_RRD_NOW; + FWK_R uint32_t T_ACT_WINDOW_NOW; + uint32_t RESERVED75; + FWK_R uint32_t T_RTR_NOW; + FWK_R uint32_t T_RTW_NOW; + FWK_R uint32_t T_RTP_NOW; + uint32_t RESERVED76; + FWK_R uint32_t T_WR_NOW; + FWK_R uint32_t T_WTR_NOW; + FWK_R uint32_t T_WTW_NOW; + uint32_t RESERVED77; + FWK_R uint32_t T_XMPD_NOW; + FWK_R uint32_t T_EP_NOW; + FWK_R uint32_t T_XP_NOW; + FWK_R uint32_t T_ESR_NOW; + FWK_R uint32_t T_XSR_NOW; + FWK_R uint32_t T_ESRCK_NOW; + FWK_R uint32_t T_CKXSR_NOW; + FWK_R uint32_t T_CMD_NOW; + FWK_R uint32_t T_PARITY_NOW; + FWK_R uint32_t T_ZQCS_NOW; + FWK_R uint32_t T_RW_ODT_CLR_NOW; + uint8_t RESERVED78[0x1300 - 0x1280]; + FWK_R uint32_t T_RDDATA_EN_NOW; + FWK_R uint32_t T_PHYRDLAT_NOW; + FWK_R uint32_t T_PHYWRLAT_NOW; + uint32_t RESERVED79; + FWK_R uint32_t RDLVL_CONTROL_NOW; + FWK_R uint32_t RDLVL_MRS_NOW; + FWK_R uint32_t T_RDLVL_EN_NOW; + FWK_R uint32_t T_RDLVL_RR_NOW; + FWK_R uint32_t WRLVL_CONTROL_NOW; + FWK_R uint32_t WRLVL_MRS_NOW; + FWK_R uint32_t T_WRLVL_EN_NOW; + FWK_R uint32_t T_WRLVL_WW_NOW; + uint8_t RESERVED80[0x1348 - 0x1330]; + FWK_R uint32_t PHY_POWER_CONTROL_NOW; + FWK_R uint32_t T_LPRESP_NOW; + FWK_R uint32_t PHY_UPDATE_CONTROL_NOW; + FWK_R uint32_t T_ODTH_NOW; + FWK_R uint32_t ODT_TIMING_NOW; + uint32_t RESERVED81; + FWK_R uint32_t ODT_WR_CONTROL_31_00_NOW; + FWK_R uint32_t ODT_WR_CONTROL_63_32_NOW; + FWK_R uint32_t ODT_RD_CONTROL_31_00_NOW; + FWK_R uint32_t ODT_RD_CONTROL_63_32_NOW; + uint8_t RESERVED82[0x1380 - 0x1370]; + FWK_R uint32_t DQ_MAP_CONTROL_15_00_NOW; + FWK_R uint32_t DQ_MAP_CONTROL_31_16_NOW; + FWK_R uint32_t DQ_MAP_CONTROL_47_32_NOW; + FWK_R uint32_t DQ_MAP_CONTROL_63_48_NOW; + FWK_R uint32_t DQ_MAP_CONTROL_71_64_NOW; + uint8_t RESERVED83[0x13B0 - 0x1394]; + FWK_R uint32_t ODT_CP_CONTROL_31_00_NOW; + FWK_R uint32_t ODT_CP_CONTROL_63_32_NOW; + uint8_t RESERVED84[0x1408 - 0x13B8]; + FWK_R uint32_t USER_CONFIG0_NOW; + FWK_R uint32_t USER_CONFIG1_NOW; + uint8_t RESERVED85[0x1610 - 0x1410]; + FWK_R uint32_t T_DB_TRAIN_RESP_NOW; + FWK_R uint32_t T_LVL_DISCONNECT_NOW; + uint8_t RESERVED86[0x1620 - 0x1618]; + FWK_R uint32_t WDQLVL_CONTROL_NOW; + FWK_R uint32_t WDQLVL_VREFDQ_TRAIN_MRS_NOW; + FWK_R uint32_t WDQLVL_ADDRESS_31_00_NOW; + FWK_R uint32_t WDQLVL_ADDRESS_63_32_NOW; + FWK_R uint32_t T_WDQLVL_EN_NOW; + FWK_R uint32_t T_WDQLVL_WW_NOW; + FWK_R uint32_t T_WDQLVL_RW_NOW; + uint8_t RESERVED87[0x1654 - 0x163C]; + FWK_R uint32_t PHYMSTR_CONTROL_NOW; + uint8_t RESERVED88[0x1FD0 - 0x1658]; + FWK_R uint32_t PERIPH_ID_4; + uint8_t RESERVED89[0x1FE0 - 0x1FD4]; + FWK_R uint32_t PERIPH_ID_0; + FWK_R uint32_t PERIPH_ID_1; + FWK_R uint32_t PERIPH_ID_2; + FWK_R uint32_t PERIPH_ID_3; + FWK_R uint32_t COMPONENT_ID_0; + FWK_R uint32_t COMPONENT_ID_1; + FWK_R uint32_t COMPONENT_ID_2; + FWK_R uint32_t COMPONENT_ID_3; + /*! + * \endcond + * @} + */ +}; + +/*! + * \brief Mask to get the memc_cmd bitfield + */ +#define MOD_DMC620_MEMC_CMD UINT32_C(0x00000007) + +/*! + * \brief Command to enter into the CONFIG architectural state + */ +#define MOD_DMC620_MEMC_CMD_CONFIG UINT32_C(0x00000000) + +/*! + * \brief Command to enter the SLEEP architectural state + */ +#define MOD_DMC620_MEMC_CMD_SLEEP UINT32_C(0x00000001) + +/*! + * \brief Command to enter the READY architectural state + */ +#define MOD_DMC620_MEMC_CMD_GO UINT32_C(0x00000003) + +/*! + * \brief Command to perform any direct_cmd operations + */ +#define MOD_DMC620_MEMC_CMD_EXECUTE UINT32_C(0x00000004) + +/*! + * \brief Enable ECC detection on reads + */ +#define DMC_ERR0CTRL0_ED_ENABLE UINT32_C(0x00000001) + +/*! + * \brief Enable defer on reads + */ +#define DMC_ERR0CTRL0_DE_ENABLE UINT32_C(0x00000002) + +/*! + * \brief Enable uncorrectable error recovery interrupt + */ +#define DMC_ERR0CTRL0_UI_ENABLE UINT32_C(0x00000004) + +/*! + * \brief Enable ECC FHI interrupt + */ +#define DMC_ERR0CTRL0_FI_ENABLE UINT32_C(0x00000008) + +/*! + * \brief Enable CFI interrupt + */ +#define DMC_ERR0CTRL0_CFI_ENABLE UINT32_C(0x00000100) + +/*! + * \brief Element configuration. + */ +struct mod_dmc620_element_config { + /*! Base address of the DMC-620 device's registers */ + uintptr_t dmc; + /*! Element identifier of the associated DDR PHY-500 device */ + fwk_id_t ddr_id; + /*! Identifier of the clock that this element depends on */ + fwk_id_t clock_id; +}; + +/*! + * \brief API of the DDR PHY associated to the DMC + */ +struct mod_dmc_ddr_phy_api { + /*! + * \brief Configure a DDR physical device + * + * \param element_id Element identifier corresponding to the device to + * configure. + * + * \retval FWK_SUCCESS if the operation succeed. + * \return one of the error code otherwise. + */ + int (*configure)(fwk_id_t element_id); +}; + +/*! + * \brief DMC-620 module configuration. + */ +struct mod_dmc620_module_config { + /*! DDR PHY module ID*/ + fwk_id_t ddr_module_id; + /*! DDR PHY API ID*/ + fwk_id_t ddr_api_id; + /*! Default value for the dmc register */ + struct mod_dmc620_reg *dmc_val; + /*! Pointer to a product-specific function that issues direct commands */ + void (*direct_ddr_cmd)(struct mod_dmc620_reg *dmc); +}; + +/*! + * \brief DMC-620 module description. + */ +extern const struct fwk_module module_dmc620; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_DMC620_H */ diff --git a/module/dmc620/src/Makefile b/module/dmc620/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9530b95dd5af76f70387d50c5ed981cfaa591ece --- /dev/null +++ b/module/dmc620/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := mod_dmc620 +BS_LIB_SOURCES += mod_dmc620.c + +include $(BS_DIR)/lib.mk \ No newline at end of file diff --git a/module/dmc620/src/mod_dmc620.c b/module/dmc620/src/mod_dmc620.c new file mode 100644 index 0000000000000000000000000000000000000000..2b547a10a2d74b39d7beddd30b417c3431e060e5 --- /dev/null +++ b/module/dmc620/src/mod_dmc620.c @@ -0,0 +1,301 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * DMC-620 driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mod_log_api *log_api; +static struct mod_dmc_ddr_phy_api *ddr_phy_api; + +static int dmc620_config(struct mod_dmc620_reg *dmc, fwk_id_t ddr_id); + +/* Framework API */ +static int mod_dmc620_init(fwk_id_t module_id, unsigned int element_count, + const void *config) +{ + return FWK_SUCCESS; +} + +static int mod_dmc620_element_init(fwk_id_t element_id, unsigned int unused, + const void *data) +{ + assert(data != NULL); + + return FWK_SUCCESS; +} + +static int mod_dmc620_bind(fwk_id_t id, unsigned int round) +{ + int status; + const struct mod_dmc620_module_config *module_config; + + /* Nothing to do in the second round of calls. */ + if (round == 1) + return FWK_SUCCESS; + + /* Nothing to do in case of elements. */ + if (fwk_module_is_valid_element_id(id)) + return FWK_SUCCESS; + + module_config = fwk_module_get_data(fwk_module_id_dmc620); + assert(module_config != NULL); + + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + MOD_LOG_API_ID, &log_api); + if (status != FWK_SUCCESS) + return status; + + status = fwk_module_bind(module_config->ddr_module_id, + module_config->ddr_api_id, &ddr_phy_api); + if (status != FWK_SUCCESS) + return status; + + return FWK_SUCCESS; +} + +static int mod_dmc620_start(fwk_id_t id) +{ + const struct mod_dmc620_element_config *element_config; + + if (!fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT)) + return FWK_SUCCESS; + + element_config = fwk_module_get_data(id); + + /* Register elements for clock state notifications */ + return fwk_notification_subscribe( + mod_clock_notification_id_state_changed, + element_config->clock_id, + id); +} + +static int dmc620_notify_system_state_transition_resume(fwk_id_t id) +{ + struct mod_dmc620_reg *dmc; + const struct mod_dmc620_element_config *element_config; + + element_config = fwk_module_get_data(id); + dmc = (struct mod_dmc620_reg *)element_config->dmc; + + return dmc620_config(dmc, element_config->ddr_id); +} + +static int mod_dmc620_process_notification( + const struct fwk_event *event, + struct fwk_event *resp_event) +{ + struct clock_notification_params *params; + + assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); + assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_ELEMENT)); + + params = (struct clock_notification_params *)event->params; + + if (params->new_state == MOD_CLOCK_STATE_RUNNING) + return dmc620_notify_system_state_transition_resume(event->target_id); + + return FWK_SUCCESS; +} + +const struct fwk_module module_dmc620 = { + .name = "DMC620", + .type = FWK_MODULE_TYPE_DRIVER, + .init = mod_dmc620_init, + .element_init = mod_dmc620_element_init, + .bind = mod_dmc620_bind, + .start = mod_dmc620_start, + .process_notification = mod_dmc620_process_notification, + .api_count = 0, + .event_count = 0, +}; + +static int dmc620_config(struct mod_dmc620_reg *dmc, fwk_id_t ddr_id) +{ + int i; + int status; + struct mod_dmc620_reg *reg_val; + const struct mod_dmc620_module_config *module_config; + + module_config = fwk_module_get_data(fwk_module_id_dmc620); + reg_val = module_config->dmc_val; + + status = log_api->log(MOD_LOG_GROUP_INFO, + "[DDR] Initialising DMC620 at 0x%x\n", (uintptr_t) dmc); + if (status != FWK_SUCCESS) + return status; + + status = log_api->log(MOD_LOG_GROUP_INFO, + "[DDR] Writing functional settings\n"); + if (status != FWK_SUCCESS) + return status; + + dmc->ADDRESS_CONTROL_NEXT = reg_val->ADDRESS_CONTROL_NEXT; + + dmc->DECODE_CONTROL_NEXT = reg_val->DECODE_CONTROL_NEXT; + dmc->FORMAT_CONTROL = reg_val->FORMAT_CONTROL; + + dmc->ADDRESS_MAP_NEXT = reg_val->ADDRESS_MAP_NEXT; + + dmc->LOW_POWER_CONTROL_NEXT = reg_val->LOW_POWER_CONTROL_NEXT; + dmc->TURNAROUND_CONTROL_NEXT = reg_val->TURNAROUND_CONTROL_NEXT; + dmc->HIT_TURNAROUND_CONTROL_NEXT = reg_val->HIT_TURNAROUND_CONTROL_NEXT; + dmc->QOS_CLASS_CONTROL_NEXT = reg_val->QOS_CLASS_CONTROL_NEXT; + dmc->ESCALATION_CONTROL_NEXT = reg_val->ESCALATION_CONTROL_NEXT; + dmc->QV_CONTROL_31_00_NEXT = reg_val->QV_CONTROL_31_00_NEXT; + dmc->QV_CONTROL_63_32_NEXT = reg_val->QV_CONTROL_63_32_NEXT; + dmc->RT_CONTROL_31_00_NEXT = reg_val->RT_CONTROL_31_00_NEXT; + dmc->RT_CONTROL_63_32_NEXT = reg_val->RT_CONTROL_63_32_NEXT; + dmc->TIMEOUT_CONTROL_NEXT = reg_val->TIMEOUT_CONTROL_NEXT; + dmc->CREDIT_CONTROL_NEXT = reg_val->CREDIT_CONTROL_NEXT; + dmc->WRITE_PRIORITY_CONTROL_31_00_NEXT = + reg_val->WRITE_PRIORITY_CONTROL_31_00_NEXT; + dmc->WRITE_PRIORITY_CONTROL_63_32_NEXT = + reg_val->WRITE_PRIORITY_CONTROL_63_32_NEXT; + dmc->QUEUE_THRESHOLD_CONTROL_31_00_NEXT = + reg_val->QUEUE_THRESHOLD_CONTROL_31_00_NEXT; + dmc->QUEUE_THRESHOLD_CONTROL_63_32_NEXT = + reg_val->QUEUE_THRESHOLD_CONTROL_63_32_NEXT; + dmc->ADDRESS_SHUTTER_31_00_NEXT = reg_val->ADDRESS_SHUTTER_31_00_NEXT; + dmc->ADDRESS_SHUTTER_63_32_NEXT = reg_val->ADDRESS_SHUTTER_63_32_NEXT; + dmc->ADDRESS_SHUTTER_95_64_NEXT = reg_val->ADDRESS_SHUTTER_95_64_NEXT; + dmc->ADDRESS_SHUTTER_127_96_NEXT = reg_val->ADDRESS_SHUTTER_127_96_NEXT; + dmc->ADDRESS_SHUTTER_159_128_NEXT = reg_val->ADDRESS_SHUTTER_159_128_NEXT; + dmc->ADDRESS_SHUTTER_191_160_NEXT = reg_val->ADDRESS_SHUTTER_191_160_NEXT; + dmc->MEMORY_ADDRESS_MAX_31_00_NEXT = reg_val->MEMORY_ADDRESS_MAX_31_00_NEXT; + dmc->MEMORY_ADDRESS_MAX_43_32_NEXT = reg_val->MEMORY_ADDRESS_MAX_43_32_NEXT; + dmc->ACCESS_ADDRESS_NEXT[0].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[0].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[0].MIN_43_32 = + reg_val->ACCESS_ADDRESS_NEXT[0].MIN_43_32; + dmc->ACCESS_ADDRESS_NEXT[1].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[1].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[1].MIN_43_32 = + reg_val->ACCESS_ADDRESS_NEXT[1].MIN_43_32; + dmc->ACCESS_ADDRESS_NEXT[2].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[2].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[3].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[3].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[4].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[4].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[5].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[5].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[6].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[6].MIN_31_00; + dmc->ACCESS_ADDRESS_NEXT[7].MIN_31_00 = + reg_val->ACCESS_ADDRESS_NEXT[7].MIN_31_00; + + dmc->DCI_REPLAY_TYPE_NEXT = reg_val->DCI_REPLAY_TYPE_NEXT; + dmc->DCI_STRB = reg_val->DCI_STRB; + dmc->DCI_DATA = reg_val->DCI_DATA; + dmc->REFRESH_CONTROL_NEXT = reg_val->REFRESH_CONTROL_NEXT; + dmc->MEMORY_TYPE_NEXT = reg_val->MEMORY_TYPE_NEXT; + dmc->FEATURE_CONFIG = reg_val->FEATURE_CONFIG; + dmc->FEATURE_CONTROL_NEXT = reg_val->FEATURE_CONTROL_NEXT; + dmc->MUX_CONTROL_NEXT = reg_val->MUX_CONTROL_NEXT; + + /* Timing Configuration */ + status = log_api->log(MOD_LOG_GROUP_INFO, + "[DDR] Writing timing settings\n"); + if (status != FWK_SUCCESS) + return status; + + dmc->T_REFI_NEXT = reg_val->T_REFI_NEXT; + dmc->T_RFC_NEXT = reg_val->T_RFC_NEXT; + dmc->T_MRR_NEXT = reg_val->T_MRR_NEXT; + dmc->T_MRW_NEXT = reg_val->T_MRW_NEXT; + dmc->T_RCD_NEXT = reg_val->T_RCD_NEXT; + dmc->T_RAS_NEXT = reg_val->T_RAS_NEXT; + dmc->T_RP_NEXT = reg_val->T_RP_NEXT; + dmc->T_RPALL_NEXT = reg_val->T_RPALL_NEXT; + dmc->T_RRD_NEXT = reg_val->T_RRD_NEXT; + dmc->T_ACT_WINDOW_NEXT = reg_val->T_ACT_WINDOW_NEXT; + dmc->T_RTR_NEXT = reg_val->T_RTR_NEXT; + dmc->T_RTW_NEXT = reg_val->T_RTW_NEXT; + dmc->T_RTP_NEXT = reg_val->T_RTP_NEXT; + dmc->T_WR_NEXT = reg_val->T_WR_NEXT; + dmc->T_WTR_NEXT = reg_val->T_WTR_NEXT; + dmc->T_WTW_NEXT = reg_val->T_WTW_NEXT; + dmc->T_XMPD_NEXT = reg_val->T_XMPD_NEXT; + dmc->T_EP_NEXT = reg_val->T_EP_NEXT; + dmc->T_XP_NEXT = reg_val->T_XP_NEXT; + dmc->T_ESR_NEXT = reg_val->T_ESR_NEXT; + dmc->T_XSR_NEXT = reg_val->T_XSR_NEXT; + dmc->T_ESRCK_NEXT = reg_val->T_ESRCK_NEXT; + dmc->T_CKXSR_NEXT = reg_val->T_CKXSR_NEXT; + dmc->T_CMD_NEXT = reg_val->T_CMD_NEXT; + dmc->T_PARITY_NEXT = reg_val->T_PARITY_NEXT; + dmc->T_ZQCS_NEXT = reg_val->T_ZQCS_NEXT; + dmc->T_RW_ODT_CLR_NEXT = reg_val->T_RW_ODT_CLR_NEXT; + dmc->T_RDDATA_EN_NEXT = reg_val->T_RDDATA_EN_NEXT; + dmc->T_PHYWRLAT_NEXT = reg_val->T_PHYWRLAT_NEXT; + dmc->T_PHYRDLAT_NEXT = reg_val->T_PHYRDLAT_NEXT; + dmc->RDLVL_CONTROL_NEXT = reg_val->RDLVL_CONTROL_NEXT; + dmc->RDLVL_MRS_NEXT = reg_val->RDLVL_MRS_NEXT; + dmc->T_RDLVL_EN_NEXT = reg_val->T_RDLVL_EN_NEXT; + dmc->T_RDLVL_RR_NEXT = reg_val->T_RDLVL_RR_NEXT; + dmc->WRLVL_CONTROL_NEXT = reg_val->WRLVL_CONTROL_NEXT; + dmc->WRLVL_MRS_NEXT = reg_val->WRLVL_MRS_NEXT; + dmc->T_WRLVL_EN_NEXT = reg_val->T_WRLVL_EN_NEXT; + dmc->T_WRLVL_WW_NEXT = reg_val->T_WRLVL_WW_NEXT; + dmc->PHY_POWER_CONTROL_NEXT = reg_val->PHY_POWER_CONTROL_NEXT; + dmc->T_LPRESP_NEXT = reg_val->T_LPRESP_NEXT; + dmc->PHY_UPDATE_CONTROL_NEXT = reg_val->PHY_UPDATE_CONTROL_NEXT; + dmc->T_ODTH_NEXT = reg_val->T_ODTH_NEXT; + + dmc->ODT_TIMING_NEXT = reg_val->ODT_TIMING_NEXT; + dmc->ODT_WR_CONTROL_31_00_NEXT = reg_val->ODT_WR_CONTROL_31_00_NEXT; + dmc->ODT_WR_CONTROL_63_32_NEXT = reg_val->ODT_WR_CONTROL_63_32_NEXT; + dmc->ODT_RD_CONTROL_31_00_NEXT = reg_val->ODT_RD_CONTROL_31_00_NEXT; + dmc->ODT_RD_CONTROL_63_32_NEXT = reg_val->ODT_RD_CONTROL_63_32_NEXT; + + /* Enable RAS interrupts and error detection */ + dmc->ERR0CTLR0 = reg_val->ERR0CTLR0; + + ddr_phy_api->configure(ddr_id); + + for (i = 0; i < 3; i++) /* ~200ns */ + __NOP(); + + status = log_api->log(MOD_LOG_GROUP_INFO, + "[DDR] Sending direct DDR commands\n"); + if (status != FWK_SUCCESS) + return status; + + module_config->direct_ddr_cmd(dmc); + + for (i = 0; i < 5; i++) /* ~400ns */ + __NOP(); + + /* Switch to READY */ + status = log_api->log(MOD_LOG_GROUP_INFO, + "[DDR] Setting DMC to READY mode\n"); + if (status != FWK_SUCCESS) + return status; + + dmc->MEMC_CMD = MOD_DMC620_MEMC_CMD_GO; + dmc->MEMC_CMD = MOD_DMC620_MEMC_CMD_EXECUTE; + + while ((dmc->MEMC_STATUS & MOD_DMC620_MEMC_CMD) != MOD_DMC620_MEMC_CMD_GO) + continue; + + status = log_api->log(MOD_LOG_GROUP_INFO, "[DDR] DMC init done.\n"); + if (status != FWK_SUCCESS) + return status; + + return FWK_SUCCESS; +} diff --git a/product/sgi575/include/fmw_cmsis.h b/product/sgi575/include/fmw_cmsis.h new file mode 100644 index 0000000000000000000000000000000000000000..c5a80626e4304a0ab4241e6ed3baad66cefa883f --- /dev/null +++ b/product/sgi575/include/fmw_cmsis.h @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_CMSIS_H +#define FMW_CMSIS_H + +#define __CHECK_DEVICE_DEFINES +#define __CM7_REV 0x0000U +#define __FPU_PRESENT 0U +#define __MPU_PRESENT 1U +#define __ICACHE_PRESENT 0U +#define __DCACHE_PRESENT 0U +#define __DTCM_PRESENT 0U +#define __NVIC_PRIO_BITS 3U +#define __Vendor_SysTickConfig 0U + +typedef enum IRQn { + NonMaskableInt_IRQn = -14, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, +} IRQn_Type; + +#include + +#endif /* FMW_CMSIS_H */ diff --git a/product/sgi575/include/mcp_sgi575_irq.h b/product/sgi575/include/mcp_sgi575_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..492b25e23f9b5031a7a8de38be8e00d35d5914f3 --- /dev/null +++ b/product/sgi575/include/mcp_sgi575_irq.h @@ -0,0 +1,266 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCP_SGI575_IRQ_H +#define MCP_SGI575_IRQ_H + +#include + +#define MCP_WDOG_IRQ FWK_INTERRUPT_NMI /* MCP Watchdog (SP805) */ + +enum mcp_sgi575_interrupt { + RESERVED0_IRQ = 0, /* Reserved */ + CDBG_PWR_UP_REQ_IRQ = 1, /* Coresight Debug Power Request */ + CSYS_PWR_UP_REQ_IRQ = 2, /* Coresight System Power Request */ + CDBG_RST_REQ_IRQ = 3, /* Coresight Debug Reset Request */ + GIC_EXT_WAKEUP_IRQ = 4, /* External GIC Wakeup Request */ + RESERVED5_IRQ = 5, /* Reserved */ + RESERVED6_IRQ = 6, /* Reserved */ + RESERVED7_IRQ = 7, /* Reserved */ + RESERVED8_IRQ = 8, /* Reserved */ + RESERVED9_IRQ = 9, /* Reserved */ + RESERVED10_IRQ = 10, /* Reserved */ + RESERVED11_IRQ = 11, /* Reserved */ + RESERVED12_IRQ = 12, /* Reserved */ + RESERVED13_IRQ = 13, /* Reserved */ + RESERVED14_IRQ = 14, /* Reserved */ + RESERVED15_IRQ = 15, /* Reserved */ + SOC_WAKEUP0_IRQ = 16, /* SoC Expansion Wakeup */ + SOC_WAKEUP1_IRQ = 17, /* SoC Expansion Wakeup */ + SOC_WAKEUP2_IRQ = 18, /* SoC Expansion Wakeup */ + SOC_WAKEUP3_IRQ = 19, /* SoC Expansion Wakeup */ + SOC_WAKEUP4_IRQ = 20, /* SoC Expansion Wakeup */ + SOC_WAKEUP5_IRQ = 21, /* SoC Expansion Wakeup */ + SOC_WAKEUP6_IRQ = 22, /* SoC Expansion Wakeup */ + SOC_WAKEUP7_IRQ = 23, /* SoC Expansion Wakeup */ + SOC_WAKEUP8_IRQ = 24, /* SoC Expansion Wakeup */ + SOC_WAKEUP9_IRQ = 25, /* SoC Expansion Wakeup */ + SOC_WAKEUP10_IRQ = 26, /* SoC Expansion Wakeup */ + SOC_WAKEUP11_IRQ = 27, /* SoC Expansion Wakeup */ + SOC_WAKEUP12_IRQ = 28, /* SoC Expansion Wakeup */ + SOC_WAKEUP13_IRQ = 29, /* SoC Expansion Wakeup */ + SOC_WAKEUP14_IRQ = 30, /* SoC Expansion Wakeup */ + SOC_WAKEUP15_IRQ = 31, /* SoC Expansion Wakeup */ + RESERVED32_IRQ = 32, /* Reserved */ + TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ + MHU_AP_NONSEC_IRQ = 34, /* MHU Non-Secure IRQ between MCP and AP */ + RESERVED35_IRQ = 35, /* Reserved */ + MHU_AP_SEC_IRQ = 36, /* MHU Secure IRQ between MCP and AP */ + CTI_TRIGGER0_IRQ = 37, /* MCP CTI Trigger */ + CTI_TRIGGER1_IRQ = 38, /* MCP CTI Trigger */ + RESERVED39_IRQ = 39, /* Reserved */ + RESERVED40_IRQ = 40, /* Reserved */ + RESERVED41_IRQ = 41, /* Reserved */ + MCP_UART0_INT_IRQ = 42, /* Always-on UART interrupt */ + MCP_UART1_INT_IRQ = 43, /* Always-on UART interrupt */ + RESERVED44_IRQ = 44, /* Reserved */ + RESERVED45_IRQ = 45, /* Reserved */ + RESERVED46_IRQ = 46, /* Reserved */ + RESERVED47_IRQ = 47, /* Reserved */ + RESERVED48_IRQ = 48, /* Reserved */ + RESERVED49_IRQ = 49, /* Reserved */ + RESERVED50_IRQ = 50, /* Reserved */ + RESERVED51_IRQ = 51, /* Reserved */ + RESERVED52_IRQ = 52, /* Reserved */ + RESERVED53_IRQ = 53, /* Reserved */ + RESERVED54_IRQ = 54, /* Reserved */ + RESERVED55_IRQ = 55, /* Reserved */ + RESERVED56_IRQ = 56, /* Reserved */ + RESERVED57_IRQ = 57, /* Reserved */ + RESERVED58_IRQ = 58, /* Reserved */ + RESERVED59_IRQ = 59, /* Reserved */ + RESERVED60_IRQ = 60, /* Reserved */ + RESERVED61_IRQ = 61, /* Reserved */ + RESERVED62_IRQ = 62, /* Reserved */ + RESERVED63_IRQ = 63, /* Reserved */ + RESERVED64_IRQ = 64, /* Reserved */ + RESERVED65_IRQ = 65, /* Reserved */ + RESERVED66_IRQ = 66, /* Reserved */ + RESERVED67_IRQ = 67, /* Reserved */ + RESERVED68_IRQ = 68, /* Reserved */ + RESERVED69_IRQ = 69, /* Reserved */ + RESERVED70_IRQ = 70, /* Reserved */ + RESERVED71_IRQ = 71, /* Reserved */ + RESERVED72_IRQ = 72, /* Reserved */ + RESERVED73_IRQ = 73, /* Reserved */ + RESERVED74_IRQ = 74, /* Reserved */ + RESERVED75_IRQ = 75, /* Reserved */ + RESERVED76_IRQ = 76, /* Reserved */ + RESERVED77_IRQ = 77, /* Reserved */ + RESERVED78_IRQ = 78, /* Reserved */ + RESERVED79_IRQ = 79, /* Reserved */ + RESERVED80_IRQ = 80, /* Reserved */ + RESERVED81_IRQ = 81, /* Reserved */ + RESERVED82_IRQ = 82, /* Reserved */ + RESERVED83_IRQ = 83, /* Reserved */ + MHU_SCP_NONSEC_IRQ = 84, /* MHU Non-Sec IRQ between SCP and MCP */ + MHU_SCP_SEC_IRQ = 85, /* MHU Secure IRQ between SCP and MCP */ + RESERVED86_IRQ = 86, /* Reserved */ + RESERVED87_IRQ = 87, /* Reserved */ + RESERVED88_IRQ = 88, /* Reserved */ + RESERVED89_IRQ = 89, /* Reserved */ + RESERVED90_IRQ = 90, /* Reserved */ + RESERVED91_IRQ = 91, /* Reserved */ + RESERVED92_IRQ = 92, /* Reserved */ + RESERVED93_IRQ = 93, /* Reserved */ + MMU_TCU_RASIRPT_IRQ = 94, /* Consolidated MMU RAS */ + MMU_TBU_RASIRPT_IRQ = 95, /* Consolidated TBU RAS */ + INT_PPU_IRQ = 96, /* PPU interrupt from Interconnect PPU */ + INT_ERRNS_IRQ = 97, /* Non-Sec error interrupt from + Interconnect PPU */ + INT_ERRS_IRQ = 98, /* Secure error interrupt from + Interconnect PPU */ + INT_FAULTS_IRQ = 99, /* Secure fault interrupt from + Interconnect PPU */ + INT_FAULTNS_IRQ = 100, /* Non-Sec fault interrupt from + Interconnect PPU */ + INT_PMU_IRQ = 101, /* PMU count overflow interrupt */ + RESERVED102_IRQ = 102, /* Reserved */ + RESERVED103_IRQ = 103, /* Reserved */ + RESERVED104_IRQ = 104, /* Reserved */ + RESERVED105_IRQ = 105, /* Reserved */ + RESERVED106_IRQ = 106, /* Reserved */ + RESERVED107_IRQ = 107, /* Reserved */ + RESERVED108_IRQ = 108, /* Reserved */ + RESERVED109_IRQ = 109, /* Reserved */ + RESERVED110_IRQ = 110, /* Reserved */ + RESERVED111_IRQ = 111, /* Reserved */ + RESERVED112_IRQ = 112, /* Reserved */ + RESERVED113_IRQ = 113, /* Reserved */ + RESERVED114_IRQ = 114, /* Reserved */ + RESERVED115_IRQ = 115, /* Reserved */ + RESERVED116_IRQ = 116, /* Reserved */ + RESERVED117_IRQ = 117, /* Reserved */ + RESERVED118_IRQ = 118, /* Reserved */ + RESERVED119_IRQ = 119, /* Reserved */ + RESERVED120_IRQ = 120, /* Reserved */ + RESERVED121_IRQ = 121, /* Reserved */ + RESERVED122_IRQ = 122, /* Reserved */ + RESERVED123_IRQ = 123, /* Reserved */ + RESERVED124_IRQ = 124, /* Reserved */ + RESERVED125_IRQ = 125, /* Reserved */ + RESERVED126_IRQ = 126, /* Reserved */ + RESERVED127_IRQ = 127, /* Reserved */ + RESERVED128_IRQ = 128, /* Reserved */ + RESERVED129_IRQ = 129, /* Reserved */ + RESERVED130_IRQ = 130, /* Reserved */ + RESERVED131_IRQ = 131, /* Reserved */ + RESERVED132_IRQ = 132, /* Reserved */ + RESERVED133_IRQ = 133, /* Reserved */ + RESERVED134_IRQ = 134, /* Reserved */ + RESERVED135_IRQ = 135, /* Reserved */ + RESERVED136_IRQ = 136, /* Reserved */ + RESERVED137_IRQ = 137, /* Reserved */ + RESERVED138_IRQ = 138, /* Reserved */ + MCP_WD_WS1_IRQ = 139, /* MCP watchdog reset */ + RESERVED140_IRQ = 140, /* Reserved */ + RESERVED141_IRQ = 141, /* Reserved */ + RESERVED142_IRQ = 142, /* Reserved */ + RESERVED143_IRQ = 143, /* Reserved */ + RESERVED144_IRQ = 144, /* Reserved */ + RESERVED145_IRQ = 145, /* Reserved */ + RESERVED146_IRQ = 146, /* Reserved */ + RESERVED147_IRQ = 147, /* Reserved */ + RESERVED148_IRQ = 148, /* Reserved */ + RESERVED149_IRQ = 149, /* Reserved */ + RESERVED150_IRQ = 150, /* Reserved */ + RESERVED151_IRQ = 151, /* Reserved */ + RESERVED152_IRQ = 152, /* Reserved */ + RESERVED153_IRQ = 153, /* Reserved */ + RESERVED154_IRQ = 154, /* Reserved */ + RESERVED155_IRQ = 155, /* Reserved */ + RESERVED156_IRQ = 156, /* Reserved */ + RESERVED157_IRQ = 157, /* Reserved */ + RESERVED158_IRQ = 158, /* Reserved */ + RESERVED159_IRQ = 159, /* Reserved */ + RESERVED160_IRQ = 160, /* Reserved */ + RESERVED161_IRQ = 161, /* Reserved */ + RESERVED162_IRQ = 162, /* Reserved */ + RESERVED163_IRQ = 163, /* Reserved */ + RESERVED164_IRQ = 164, /* Reserved */ + RESERVED165_IRQ = 165, /* Reserved */ + RESERVED166_IRQ = 166, /* Reserved */ + RESERVED167_IRQ = 167, /* Reserved */ + RESERVED168_IRQ = 168, /* Reserved */ + RESERVED169_IRQ = 169, /* Reserved */ + RESERVED170_IRQ = 170, /* Reserved */ + RESERVED171_IRQ = 171, /* Reserved */ + RESERVED172_IRQ = 172, /* Reserved */ + RESERVED173_IRQ = 173, /* Reserved */ + RESERVED174_IRQ = 174, /* Reserved */ + RESERVED175_IRQ = 175, /* Reserved */ + RESERVED176_IRQ = 176, /* Reserved */ + RESERVED177_IRQ = 177, /* Reserved */ + RESERVED178_IRQ = 178, /* Reserved */ + RESERVED179_IRQ = 179, /* Reserved */ + DMCS0_MISC_OFLOW_IRQ = 180, /* DMC 0/4 Combined Error Overflow */ + DMCS0_ERR_OFLOW_IRQ = 181, /* DMC 0/4 Error Overflow */ + DMCS0_ECC_ERR_INT_IRQ = 182, /* DMC 0/4 ECC Error Int */ + DMCS0_MISC_ACCESS_INT_IRQ = 183, /* DMC 0/4 Combined Miscellaneous + access int */ + DMCS0_TEMPERATURE_EVENT_INT_IRQ = 184, /* DMC 0/4 Temperature event int */ + DMCS0_FAILED_ACCESS_INT_IRQ = 185, /* DMC 0/4 Failed access int */ + DMCS0_MGR_INT_IRQ = 186, /* DMC 0/4 combined manager int */ + DMCS1_MISC_OFLOW_IRQ = 187, /* DMC 1/5 Combined Error Overflow */ + DMCS1_ERR_OFLOW_IRQ = 188, /* DMC 1/5 Error Overflow */ + DMCS1_ECC_ERR_INT_IRQ = 189, /* DMC 1/5 ECC Error Int */ + DMCS1_MISC_ACCESS_INT_IRQ = 190, /* DMC 1/5 Combined Miscellaneous + access int */ + DMCS1_TEMPERATURE_EVENT_INT_IRQ = 191, /* DMC 1/5 Temperature event int */ + DMCS1_FAILED_ACCESS_INT_IRQ = 192, /* DMC 1/5 Failed access int */ + DMCS1_MGR_INT_IRQ = 193, /* DMC 1/5 combined manager int */ + DMCS2_MISC_OFLOW_IRQ = 194, /* DMC 2/6 Combined Error Overflow */ + DMCS2_ERR_OFLOW_IRQ = 195, /* DMC 2/6 Error Overflow */ + DMCS2_ECC_ERR_INT_IRQ = 196, /* DMC 2/6 ECC Error Int */ + DMCS2_MISC_ACCESS_INT_IRQ = 197, /* DMC 2/6 Combined Miscellaneous + access int */ + DMCS2_TEMPERATURE_EVENT_INT_IRQ = 198, /* DMC 2/6 Temperature event int */ + DMCS2_FAILED_ACCESS_INT_IRQ = 199, /* DMC 2/6 Failed access int */ + DMCS2_MGR_INT_IRQ = 200, /* DMC 2/6 combined manager int */ + DMCS3_MISC_OFLOW_IRQ = 201, /* DMC 3/7 Combined Error Overflow */ + DMCS3_ERR_OFLOW_IRQ = 202, /* DMC 3/7 Error Overflow */ + DMCS3_ECC_ERR_INT_IRQ = 203, /* DMC 3/7 ECC Error Int */ + DMCS3_MISC_ACCESS_INT_IRQ = 204, /* DMC 3/7 Combined Miscellaneous + access int */ + DMCS3_TEMPERATURE_EVENT_INT_IRQ = 205, /* DMC 3/7 Temperature event int */ + DMCS3_FAILED_ACCESS_INT_IRQ = 206, /* DMC 3/7 Failed access int */ + DMCS3_MGR_INT_IRQ = 207, /* DMC 3/7 combined manager int */ + MCP_EXT_INTR0_IRQ = 208, /* MCP Customer Extension */ + MCP_EXT_INTR1_IRQ = 209, /* MCP Customer Extension */ + MCP_EXT_INTR2_IRQ = 210, /* MCP Customer Extension */ + MCP_EXT_INTR3_IRQ = 211, /* MCP Customer Extension */ + MCP_EXT_INTR4_IRQ = 212, /* MCP Customer Extension */ + MCP_EXT_INTR5_IRQ = 213, /* MCP Customer Extension */ + MCP_EXT_INTR6_IRQ = 214, /* MCP Customer Extension */ + MCP_EXT_INTR7_IRQ = 215, /* MCP Customer Extension */ + MCP_EXT_INTR8_IRQ = 216, /* MCP Customer Extension */ + MCP_EXT_INTR9_IRQ = 217, /* MCP Customer Extension */ + MCP_EXT_INTR10_IRQ = 218, /* MCP Customer Extension */ + MCP_EXT_INTR11_IRQ = 219, /* MCP Customer Extension */ + MCP_EXT_INTR12_IRQ = 220, /* MCP Customer Extension */ + MCP_EXT_INTR13_IRQ = 221, /* MCP Customer Extension */ + MCP_EXT_INTR14_IRQ = 222, /* MCP Customer Extension */ + MCP_EXT_INTR15_IRQ = 223, /* MCP Customer Extension */ + MCP_EXT_INTR16_IRQ = 224, /* MCP Customer Extension */ + MCP_EXT_INTR17_IRQ = 225, /* MCP Customer Extension */ + MCP_EXT_INTR18_IRQ = 226, /* MCP Customer Extension */ + MCP_EXT_INTR19_IRQ = 227, /* MCP Customer Extension */ + MCP_EXT_INTR20_IRQ = 228, /* MCP Customer Extension */ + MCP_EXT_INTR21_IRQ = 229, /* MCP Customer Extension */ + MCP_EXT_INTR22_IRQ = 230, /* MCP Customer Extension */ + MCP_EXT_INTR23_IRQ = 231, /* MCP Customer Extension */ + MCP_EXT_INTR24_IRQ = 232, /* MCP Customer Extension */ + MCP_EXT_INTR25_IRQ = 233, /* MCP Customer Extension */ + MCP_EXT_INTR26_IRQ = 234, /* MCP Customer Extension */ + MCP_EXT_INTR27_IRQ = 235, /* MCP Customer Extension */ + MCP_EXT_INTR28_IRQ = 236, /* MCP Customer Extension */ + MCP_EXT_INTR29_IRQ = 237, /* MCP Customer Extension */ + MCP_EXT_INTR30_IRQ = 238, /* MCP Customer Extension */ + MCP_EXT_INTR31_IRQ = 239 /* MCP Customer Extension */ +}; + +#endif /* MCP_SGI575_IRQ_H */ diff --git a/product/sgi575/include/mcp_sgi575_mmap.h b/product/sgi575/include/mcp_sgi575_mmap.h new file mode 100644 index 0000000000000000000000000000000000000000..deef5112f6e10881f5603becfc5f16d9031fe041 --- /dev/null +++ b/product/sgi575/include/mcp_sgi575_mmap.h @@ -0,0 +1,52 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCP_SGI575_MMAP_H +#define MCP_SGI575_MMAP_H + +#include + +/* + * Top-level base addresses + */ +#define MCP_SOC_EXPANSION1_BASE UINT32_C(0x01000000) +#define MCP_SOC_EXPANSION2_BASE UINT32_C(0x21000000) +#define MCP_SOC_EXPANSION3_BASE UINT32_C(0x40000000) +#define MCP_MHU_SCP_BASE UINT32_C(0x45600000) +#define MCP_SOC_EXPANSION4_BASE UINT32_C(0x48000000) +#define MCP_PERIPH_BASE UINT32_C(0x4C000000) +#define MCP_MEMORY_CONTROLLER UINT32_C(0x4E000000) +#define MCP_POWER_PERIPH_BASE UINT32_C(0x50000000) +#define MCP_SYS0_BASE UINT32_C(0x60000000) +#define MCP_SYS1_BASE UINT32_C(0xA0000000) +#define MCP_PPB_BASE_INTERNAL UINT32_C(0xE0000000) +#define MCP_PPB_BASE_EXTERNAL UINT32_C(0xE0040000) + +/* + * Peripherals + */ +#define MCP_REFCLK_CNTCTL_BASE (MCP_PERIPH_BASE) +#define MCP_REFCLK_CNTBASE0_BASE (MCP_PERIPH_BASE + 0x1000) +#define MCP_UART0_BASE (MCP_PERIPH_BASE + 0x2000) +#define MCP_UART1_BASE (MCP_PERIPH_BASE + 0x3000) +#define MCP_WDOG_BASE (MCP_PERIPH_BASE + 0x6000) +#define MCP_MHU_AP_BASE (MCP_PERIPH_BASE + 0x400000) + +/* + * Power control peripherals + */ +#define MCP_PIK_BASE (MCP_POWER_PERIPH_BASE) + +/* + * Base addresses of MHU devices + */ +#define MCP_MHU_SCP_MCP_NS (MCP_MHU_SCP_BASE + 0x020) +#define MCP_MHU_MCP_SCP_NS (MCP_MHU_SCP_BASE + 0x120) +#define MCP_MHU_SCP_MCP_S (MCP_MHU_SCP_BASE + 0x200) +#define MCP_MHU_MCP_SCP_S (MCP_MHU_SCP_BASE + 0x300) + +#endif /* MCP_SGI575_MMAP_H */ diff --git a/product/sgi575/include/mcp_sgi575_mmap_mcp.h b/product/sgi575/include/mcp_sgi575_mmap_mcp.h new file mode 100644 index 0000000000000000000000000000000000000000..cab90ffa361222d2b58c3fd69bd598ef29b25716 --- /dev/null +++ b/product/sgi575/include/mcp_sgi575_mmap_mcp.h @@ -0,0 +1,15 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCP_SGI575_MMAP_MCP_H +#define MCP_SGI575_MMAP_MCP_H + +#define MCP_ROM_BASE 0x00000000 +#define MCP_RAM0_BASE 0x00800000 +#define MCP_RAM1_BASE 0x20000000 + +#endif /* MCP_SGI575_MMAP_MCP_H */ diff --git a/product/sgi575/include/mcp_system_mmap_mcp.h b/product/sgi575/include/mcp_system_mmap_mcp.h new file mode 100644 index 0000000000000000000000000000000000000000..628aaa2679fa68077c2111034d05165c16f6c27b --- /dev/null +++ b/product/sgi575/include/mcp_system_mmap_mcp.h @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCP_SYSTEM_MMAP_MCP_H +#define MCP_SYSTEM_MMAP_MCP_H + +#include + +#define MCP_ROM_SIZE (64 * 1024) +#define MCP_RAM0_SIZE (64 * 1024) +#define MCP_RAM1_SIZE (64 * 1024) + +#endif /* MCP_SYSTEM_MMAP_MCP_H */ diff --git a/product/sgi575/include/scp_sgi575_irq.h b/product/sgi575/include/scp_sgi575_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..27ebd69b87670576ec7420e514762c2c7233273c --- /dev/null +++ b/product/sgi575/include/scp_sgi575_irq.h @@ -0,0 +1,280 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SGI575_IRQ_H +#define SCP_SGI575_IRQ_H + +#include + +#define SCP_WDOG_IRQ FWK_INTERRUPT_NMI /* SCP Watchdog (SP805) */ + +enum scp_sgi575_interrupt { + RESERVED0_IRQ = 0, /* Reserved */ + CDBG_PWR_UP_REQ_IRQ = 1, /* Coresight Debug Power Request */ + CSYS_PWR_UP_REQ_IRQ = 2, /* Coresight System Power Request */ + CDBG_RST_REQ_IRQ = 3, /* Coresight Debug Reset Request */ + GIC_EXT_WAKEUP_IRQ = 4, /* External GIC Wakeup Request */ + RESERVED5_IRQ = 5, /* Reserved */ + RESERVED6_IRQ = 6, /* Reserved */ + RESERVED7_IRQ = 7, /* Reserved */ + RESERVED8_IRQ = 8, /* Reserved */ + RESERVED9_IRQ = 9, /* Reserved */ + RESERVED10_IRQ = 10, /* Reserved */ + RESERVED11_IRQ = 11, /* Reserved */ + RESERVED12_IRQ = 12, /* Reserved */ + RESERVED13_IRQ = 13, /* Reserved */ + RESERVED14_IRQ = 14, /* Reserved */ + RESERVED15_IRQ = 15, /* Reserved */ + SOC_WAKEUP0_IRQ = 16, /* SoC Expansion Wakeup */ + SOC_WAKEUP1_IRQ = 17, /* SoC Expansion Wakeup */ + SOC_WAKEUP2_IRQ = 18, /* SoC Expansion Wakeup */ + SOC_WAKEUP3_IRQ = 19, /* SoC Expansion Wakeup */ + SOC_WAKEUP4_IRQ = 20, /* SoC Expansion Wakeup */ + SOC_WAKEUP5_IRQ = 21, /* SoC Expansion Wakeup */ + SOC_WAKEUP6_IRQ = 22, /* SoC Expansion Wakeup */ + SOC_WAKEUP7_IRQ = 23, /* SoC Expansion Wakeup */ + SOC_WAKEUP8_IRQ = 24, /* SoC Expansion Wakeup */ + SOC_WAKEUP9_IRQ = 25, /* SoC Expansion Wakeup */ + SOC_WAKEUP10_IRQ = 26, /* SoC Expansion Wakeup */ + SOC_WAKEUP11_IRQ = 27, /* SoC Expansion Wakeup */ + SOC_WAKEUP12_IRQ = 28, /* SoC Expansion Wakeup */ + SOC_WAKEUP13_IRQ = 29, /* SoC Expansion Wakeup */ + SOC_WAKEUP14_IRQ = 30, /* SoC Expansion Wakeup */ + SOC_WAKEUP15_IRQ = 31, /* SoC Expansion Wakeup */ + RESERVED32_IRQ = 32, /* Reserved */ + TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ + RESERVED34_IRQ = 34, /* Reserved */ + RESERVED35_IRQ = 35, /* Reserved */ + RESERVED36_IRQ = 36, /* Reserved */ + CTI_TRIGGER0_IRQ = 37, /* SCP CTI Trigger */ + CTI_TRIGGER1_IRQ = 38, /* SCP CTI Trigger */ + GIC_ERROR_ECC_IRQ = 39, /* GIC Error (ECC Fatal) */ + GIC_ERROR_AXIM_IRQ = 40, /* GIC Error (AXIM) */ + RESERVED41_IRQ = 41, /* Reserved */ + AON_UART_IRQ = 42, /* Always on UART */ + RESERVED43_IRQ = 43, /* Reserved */ + GEN_WD_WS0_IRQ = 44, /* Generic Watchdog timer WS0 */ + GEN_WD_WS1_IRQ = 45, /* Generic Watchdog timer WS1 */ + TRUSTED_WD_WS0_IRQ = 46, /* Trusted Watchdog timer WS0 */ + TRUSTED_WD_WS1_IRQ = 47, /* Trusted Watchdog timer WS1 */ + APPS_UART_IRQ = 48, /* Application UART */ + RESERVED49_IRQ = 49, /* Reserved */ + PPU_CORES0_IRQ = 50, /* Consolidated PPU Interrupt for cores + 1-32, 129-160 */ + PPU_CORES1_IRQ = 51, /* Consolidated PPU Interrupt for cores + 33-64, 161-192 */ + PPU_CORES2_IRQ = 52, /* Consolidated PPU Interrupt for cores + 65-96, 193-224 */ + PPU_CORES3_IRQ = 53, /* Consolidated PPU Interrupt for cores + 97-128, 225-256 */ + PPU_CLUSTERS_IRQ = 54, /* Consolidated clusters PPU */ + PLL_CORES0_LOCK_IRQ = 55, /* Consolidated PLL lock for PLLs + 1-32, 65-96, 129-160, 193-224 */ + PLL_CORES1_LOCK_IRQ = 56, /* Consolidated PLL lock for PLLs + 33-64, 97-128, 161-192, 225-256 */ + PLL_CORES0_UNLOCK_IRQ = 57, /* Consolidated PLL unlock for PLLs + 1-32, 65-96, 129-160, 193-224 */ + PLL_CORES1_UNLOCK_IRQ = 58, /* Consolidated PLL unlock for PLLs + 33-64, 97-128, 161-192, 225-256 */ + CLUSTER_FAULT_IRQ = 59, /* Consolidated fault IRQ for all + clusters */ + RESERVED60_IRQ = 60, /* Reserved */ + RESERVED61_IRQ = 61, /* Reserved */ + RESERVED62_IRQ = 62, /* Reserved */ + RESERVED63_IRQ = 63, /* Reserved */ + ECC_CLUSTERS_ERROR_IRQ = 64, /* Consolidated clusters ECC ERROR */ + RESERVED65_IRQ = 65, /* Reserved */ + RESERVED66_IRQ = 66, /* Reserved */ + RESERVED67_IRQ = 67, /* Reserved */ + RESERVED68_IRQ = 68, /* Reserved */ + PLL_CLUSTERS_LOCK_IRQ = 69, /* Consolidated clusters PLL Lock */ + PLL_CLUSTERS_UNLOCK_IRQ = 70, /* Consolidated clusters PLL Unlock*/ + RESERVED71_IRQ = 71, /* Reserved */ + RESERVED72_IRQ = 72, /* Reserved */ + RESERVED73_IRQ = 73, /* Reserved */ + RESERVED74_IRQ = 74, /* Reserved */ + RESERVED75_IRQ = 75, /* Reserved */ + RESERVED76_IRQ = 76, /* Reserved */ + RESERVED77_IRQ = 77, /* Reserved */ + RESERVED78_IRQ = 78, /* Reserved */ + RESERVED79_IRQ = 79, /* Reserved */ + RESERVED80_IRQ = 80, /* Reserved */ + RESERVED81_IRQ = 81, /* Reserved */ + MHU_AP_NONSEC_IRQ = 82, /* MHU non-secure irq bewteen SCP and AP */ + MHU_AP_SEC_IRQ = 83, /* MHU secure irq bewteen SCP and AP */ + MHU_MCP_NONSEC_IRQ = 84, /* MHU non-secure irq between SCP and + MCP */ + MHU_MCP_SEC_IRQ = 85, /* MHU secure irq bewteen SCP and MCP */ + RESERVED86_IRQ = 86, /* Reserved */ + RESERVED87_IRQ = 87, /* Reserved */ + RESERVED88_IRQ = 88, /* Reserved */ + RESERVED89_IRQ = 89, /* Reserved */ + TIMER_CLUSTERS_IRQ = 90, /* Consolidated clusters timer interrupt */ + RESERVED91_IRQ = 91, /* Reserved */ + RESERVED92_IRQ = 92, /* Reserved */ + RESERVED93_IRQ = 93, /* Reserved */ + MMU_TCU_RASIRPT_IRQ = 94, /* Consolidated MMU RAS */ + MMU_TBU_RASIRPT_IRQ = 95, /* Consolidated TBU RAS */ + INT_PPU_IRQ = 96, /* PPU interrupt from Interconnect PPU */ + INT_ERRNS_IRQ = 97, /* Non-Sec error interrupt from + Interconnect PPU */ + INT_ERRS_IRQ = 98, /* Secure error interrupt from + Interconnect PPU */ + INT_FAULTS_IRQ = 99, /* Secure fault interrupt from + Interconnect PPU */ + INT_FAULTNS_IRQ = 100, /* Non-Sec fault interrupt from + Interconnect PPU */ + INT_PMU_DTC0_IRQ = 101, /* PMU count overflow interrupt if + DTC > 0 */ + INT_PMU_DTC1_IRQ = 102, /* PMU count overflow interrupt if + DTC > 1 */ + INT_PMU_DTC2_IRQ = 103, /* PMU count overflow interrupt if + DTC > 2 */ + INT_PMU_DTC3_IRQ = 104, /* PMU count overflow interrupt if + DTC > 3 */ + RESERVED105_IRQ = 105, /* Reserved */ + RESERVED106_IRQ = 106, /* Reserved */ + RESERVED107_IRQ = 107, /* Reserved */ + RESERVED108_IRQ = 108, /* Reserved */ + RESERVED109_IRQ = 109, /* Reserved */ + RESERVED110_IRQ = 110, /* Reserved */ + RESERVED111_IRQ = 111, /* Reserved */ + RESERVED112_IRQ = 112, /* Reserved */ + RESERVED113_IRQ = 113, /* Reserved */ + RESERVED114_IRQ = 114, /* Reserved */ + RESERVED115_IRQ = 115, /* Reserved */ + RESERVED116_IRQ = 116, /* Reserved */ + RESERVED117_IRQ = 117, /* Reserved */ + RESERVED118_IRQ = 118, /* Reserved */ + RESERVED119_IRQ = 119, /* Reserved */ + RESERVED120_IRQ = 120, /* Reserved */ + RESERVED121_IRQ = 121, /* Reserved */ + RESERVED122_IRQ = 122, /* Reserved */ + RESERVED123_IRQ = 123, /* Reserved */ + RESERVED124_IRQ = 124, /* Reserved */ + RESERVED125_IRQ = 125, /* Reserved */ + RESERVED126_IRQ = 126, /* Reserved */ + RESERVED127_IRQ = 127, /* Reserved */ + RESERVED128_IRQ = 128, /* Reserved */ + RESERVED129_IRQ = 129, /* Reserved */ + DEBUG_PIK_IRQ = 130, /* DEBUG PIK */ + PPU_LOGIC_IRQ = 131, /* PPU LOGIC */ + RESERVED132_IRQ = 132, /* Reserved */ + RESERVED133_IRQ = 133, /* Reserved */ + RESERVED134_IRQ = 134, /* Reserved */ + PPU_SRAM_IRQ = 135, /* PPU SRAM */ + RESERVED136_IRQ = 136, /* Reserved */ + RESERVED137_IRQ = 137, /* Reserved */ + RESERVED138_IRQ = 138, /* Reserved */ + MCP_WD_WS1_IRQ = 139, /* MCP watchdog reset */ + PLL_SYS_LOCK_IRQ = 140, /* System PLL Lock */ + PLL_SYS_UNLOCK_IRQ = 141, /* System PLL Unlock */ + PLL_INT_LOCK_IRQ = 142, /* Interconnect PLL Lock */ + PLL_INT_UNLOCK_IRQ = 143, /* Interconnect PLL Unlock */ + RESERVED144_IRQ = 144, /* Reserved */ + RESERVED145_IRQ = 145, /* Reserved */ + RESERVED146_IRQ = 146, /* Reserved */ + RESERVED147_IRQ = 147, /* Reserved */ + RESERVED148_IRQ = 148, /* Reserved */ + RESERVED149_IRQ = 149, /* Reserved */ + RESERVED150_IRQ = 150, /* Reserved */ + RESERVED151_IRQ = 151, /* Reserved */ + RESERVED152_IRQ = 152, /* Reserved */ + RESERVED153_IRQ = 153, /* Reserved */ + RESERVED154_IRQ = 154, /* Reserved */ + RESERVED155_IRQ = 155, /* Reserved */ + RESERVED156_IRQ = 156, /* Reserved */ + RESERVED157_IRQ = 157, /* Reserved */ + RESERVED158_IRQ = 158, /* Reserved */ + RESERVED159_IRQ = 159, /* Reserved */ + RESERVED160_IRQ = 160, /* Reserved */ + RESERVED161_IRQ = 161, /* Reserved */ + RESERVED162_IRQ = 162, /* Reserved */ + RESERVED163_IRQ = 163, /* Reserved */ + RESERVED164_IRQ = 164, /* Reserved */ + RESERVED165_IRQ = 165, /* Reserved */ + RESERVED166_IRQ = 166, /* Reserved */ + RESERVED167_IRQ = 167, /* Reserved */ + RESERVED168_IRQ = 168, /* Reserved */ + RESERVED169_IRQ = 169, /* Reserved */ + RESERVED170_IRQ = 170, /* Reserved */ + RESERVED171_IRQ = 171, /* Reserved */ + RESERVED172_IRQ = 172, /* Reserved */ + RESERVED173_IRQ = 173, /* Reserved */ + PLL_DMC_LOCK_IRQ = 174, /* DMC PLL LOCK */ + PLL_DMC_UNLOCK_IRQ = 175, /* DMC PLL LOCK */ + RESERVED176_IRQ = 176, /* Reserved */ + RESERVED177_IRQ = 177, /* Reserved */ + RESERVED178_IRQ = 178, /* Reserved */ + RESERVED179_IRQ = 179, /* Reserved */ + DMCS0_MISC_OFLOW_IRQ = 180, /* DMC 0/4 Combined Error Overflow */ + DMCS0_ERR_OFLOW_IRQ = 181, /* DMC 0/4 Error Overflow */ + DMCS0_ECC_ERR_INT_IRQ = 182, /* DMC 0/4 ECC Error Int */ + DMCS0_MISC_ACCESS_INT_IRQ = 183, /* DMC 0/4 Combined Miscellaneous + access int */ + DMCS0_TEMPERATURE_EVENT_INT_IRQ = 184, /* DMC 0/4 Temperature event int */ + DMCS0_FAILED_ACCESS_INT_IRQ = 185, /* DMC 0/4 Failed access int */ + DMCS0_MGR_INT_IRQ = 186, /* DMC 0/4 combined manager int */ + DMCS1_MISC_OFLOW_IRQ = 187, /* DMC 1/5 Combined Error Overflow */ + DMCS1_ERR_OFLOW_IRQ = 188, /* DMC 1/5 Error Overflow */ + DMCS1_ECC_ERR_INT_IRQ = 189, /* DMC 1/5 ECC Error Int */ + DMCS1_MISC_ACCESS_INT_IRQ = 190, /* DMC 1/5 Combined Miscellaneous + access int */ + DMCS1_TEMPERATURE_EVENT_INT_IRQ = 191, /* DMC 1/5 Temperature event int */ + DMCS1_FAILED_ACCESS_INT_IRQ = 192, /* DMC 1/5 Failed access int */ + DMCS1_MGR_INT_IRQ = 193, /* DMC 1/5 combined manager int */ + DMCS2_MISC_OFLOW_IRQ = 194, /* DMC 2/6 Combined Error Overflow */ + DMCS2_ERR_OFLOW_IRQ = 195, /* DMC 2/6 Error Overflow */ + DMCS2_ECC_ERR_INT_IRQ = 196, /* DMC 2/6 ECC Error Int */ + DMCS2_MISC_ACCESS_INT_IRQ = 197, /* DMC 2/6 Combined Miscellaneous + access int */ + DMCS2_TEMPERATURE_EVENT_INT_IRQ = 198, /* DMC 2/6 Temperature event int */ + DMCS2_FAILED_ACCESS_INT_IRQ = 199, /* DMC 2/6 Failed access int */ + DMCS2_MGR_INT_IRQ = 200, /* DMC 2/6 combined manager int */ + DMCS3_MISC_OFLOW_IRQ = 201, /* DMC 3/7 Combined Error Overflow */ + DMCS3_ERR_OFLOW_IRQ = 202, /* DMC 3/7 Error Overflow */ + DMCS3_ECC_ERR_INT_IRQ = 203, /* DMC 3/7 ECC Error Int */ + DMCS3_MISC_ACCESS_INT_IRQ = 204, /* DMC 3/7 Combined Miscellaneous + access int */ + DMCS3_TEMPERATURE_EVENT_INT_IRQ = 205, /* DMC 3/7 Temperature event int */ + DMCS3_FAILED_ACCESS_INT_IRQ = 206, /* DMC 3/7 Failed access int */ + DMCS3_MGR_INT_IRQ = 207, /* DMC 3/7 combined manager int */ + SCP_EXT_INTR0_IRQ = 208, /* SCP Customer Extension */ + SCP_EXT_INTR1_IRQ = 209, /* SCP Customer Extension */ + SCP_EXT_INTR2_IRQ = 210, /* SCP Customer Extension */ + SCP_EXT_INTR3_IRQ = 211, /* SCP Customer Extension */ + SCP_EXT_INTR4_IRQ = 212, /* SCP Customer Extension */ + SCP_EXT_INTR5_IRQ = 213, /* SCP Customer Extension */ + SCP_EXT_INTR6_IRQ = 214, /* SCP Customer Extension */ + SCP_EXT_INTR7_IRQ = 215, /* SCP Customer Extension */ + SCP_EXT_INTR8_IRQ = 216, /* SCP Customer Extension */ + SCP_EXT_INTR9_IRQ = 217, /* SCP Customer Extension */ + SCP_EXT_INTR10_IRQ = 218, /* SCP Customer Extension */ + SCP_EXT_INTR11_IRQ = 219, /* SCP Customer Extension */ + SCP_EXT_INTR12_IRQ = 220, /* SCP Customer Extension */ + SCP_EXT_INTR13_IRQ = 221, /* SCP Customer Extension */ + SCP_EXT_INTR14_IRQ = 222, /* SCP Customer Extension */ + SCP_EXT_INTR15_IRQ = 223, /* SCP Customer Extension */ + SCP_EXT_INTR16_IRQ = 224, /* SCP Customer Extension */ + SCP_EXT_INTR17_IRQ = 225, /* SCP Customer Extension */ + SCP_EXT_INTR18_IRQ = 226, /* SCP Customer Extension */ + SCP_EXT_INTR19_IRQ = 227, /* SCP Customer Extension */ + SCP_EXT_INTR20_IRQ = 228, /* SCP Customer Extension */ + SCP_EXT_INTR21_IRQ = 229, /* SCP Customer Extension */ + SCP_EXT_INTR22_IRQ = 230, /* SCP Customer Extension */ + SCP_EXT_INTR23_IRQ = 231, /* SCP Customer Extension */ + SCP_EXT_INTR24_IRQ = 232, /* SCP Customer Extension */ + SCP_EXT_INTR25_IRQ = 233, /* SCP Customer Extension */ + SCP_EXT_INTR26_IRQ = 234, /* SCP Customer Extension */ + SCP_EXT_INTR27_IRQ = 235, /* SCP Customer Extension */ + SCP_EXT_INTR28_IRQ = 236, /* SCP Customer Extension */ + SCP_EXT_INTR29_IRQ = 237, /* SCP Customer Extension */ + SCP_EXT_INTR30_IRQ = 238, /* SCP Customer Extension */ + SCP_EXT_INTR31_IRQ = 239 /* SCP Customer Extension */ +}; + +#endif /* SCP_SGI575_IRQ_H */ diff --git a/product/sgi575/include/scp_sgi575_mhu.h b/product/sgi575/include/scp_sgi575_mhu.h new file mode 100644 index 0000000000000000000000000000000000000000..dd48684ee739724973d365ccfc5a2cb6cd854d9c --- /dev/null +++ b/product/sgi575/include/scp_sgi575_mhu.h @@ -0,0 +1,20 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * MHU module device indexes. + */ + +#ifndef SCP_SGI575_MHU_H +#define SCP_SGI575_MHU_H + +enum scp_sgi575_mhu_device_idx { + SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_S, + SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_NS, + SCP_SGI575_MHU_DEVICE_IDX_COUNT +}; + +#endif /* SCP_SGI575_MHU_H */ diff --git a/product/sgi575/include/scp_sgi575_mmap.h b/product/sgi575/include/scp_sgi575_mmap.h new file mode 100644 index 0000000000000000000000000000000000000000..b908c1c18ea85adfb10b413b1077da7817280945 --- /dev/null +++ b/product/sgi575/include/scp_sgi575_mmap.h @@ -0,0 +1,92 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SGI575_MMAP_H +#define SCP_SGI575_MMAP_H + +#include + +/* + * Top-level base addresses + */ +#define SCP_EXPANSION1_BASE UINT32_C(0x01000000) +#define SCP_EXPANSION2_BASE UINT32_C(0x21000000) +#define SCP_EXPANSION3_BASE UINT32_C(0x40000000) +#define SCP_PERIPHERAL_BASE UINT32_C(0x44000000) +#define SCP_MEMORY_CONTROLLER UINT32_C(0x4E000000) +#define SCP_POWER_PERIPHERAL_BASE UINT32_C(0x50000000) +#define SCP_SYS0_BASE UINT32_C(0x60000000) +#define SCP_SYS1_BASE UINT32_C(0xA0000000) +#define SCP_PPB_BASE_INTERNAL UINT32_C(0xE0000000) +#define SCP_PPB_BASE_EXTERNAL UINT32_C(0xE0040000) + +/* + * Peripherals + */ +#define SCP_REFCLK_CNTCTL_BASE (SCP_PERIPHERAL_BASE + 0x0000) +#define SCP_REFCLK_CNTBASE0_BASE (SCP_PERIPHERAL_BASE + 0x1000) +#define SCP_UART_BASE (SCP_PERIPHERAL_BASE + 0x2000) +#define SCP_WDOG_BASE (SCP_PERIPHERAL_BASE + 0x6000) +#define SCP_CS_CNTCONTROL_BASE (SCP_PERIPHERAL_BASE + 0xA000) +#define SCP_MHU_AP_BASE (SCP_PERIPHERAL_BASE + 0x1000000) +#define SCP_MHU_MCP_BASE (SCP_PERIPHERAL_BASE + 0x1600000) + +/* + * Power control peripherals + */ +#define SCP_PIK_SCP_BASE (SCP_POWER_PERIPHERAL_BASE + 0x00000) +#define SCP_PIK_DEBUG_BASE (SCP_POWER_PERIPHERAL_BASE + 0x20000) +#define SCP_SCP_SENSOR_DEBUG_BASE (SCP_POWER_PERIPHERAL_BASE + 0x30000) +#define SCP_PIK_SYSTEM_BASE (SCP_POWER_PERIPHERAL_BASE + 0x40000) +#define SCP_SENSOR_SYSTEM_BASE (SCP_POWER_PERIPHERAL_BASE + 0x50000) +#define SCP_SENSOR_CLUS0_BASE (SCP_POWER_PERIPHERAL_BASE + 0x70000) +#define SCP_SENSOR_CLUS1_BASE (SCP_POWER_PERIPHERAL_BASE + 0x90000) +#define SCP_PIK_CLUSTER_BASE(n) ((SCP_POWER_PERIPHERAL_BASE + 0x60000) + \ + ((n) * 0x20000)) + +/* + * PPU base address + */ +#define SCP_PPU_SCP_BASE (SCP_PIK_SCP_BASE + 0x1000) +#define SCP_PPU_SYS0_BASE (SCP_PIK_SYSTEM_BASE + 0x1000) +#define SCP_PPU_SYS1_BASE (SCP_PIK_SYSTEM_BASE + 0x5000) +#define SCP_PPU_DEBUG_BASE (SCP_PIK_DEBUG_BASE + 0x1000) +#define SCP_PPU_CLUSTER_BASE(n) (SCP_PIK_CLUSTER_BASE((n)) + 0x1000) +#define SCP_PPU_CORE_BASE(n, m) (SCP_PPU_CLUSTER_BASE((n)) + \ + ((m) + 1) * 0x1000) + +/* + * System access port 0 + */ +#define SCP_CMN600_BASE (SCP_SYS0_BASE + 0x10000000) + +/* + * System access port 1 + */ +#define SCP_TRUSTED_RAM_BASE (SCP_SYS1_BASE + 0x04000000) +#define SCP_NONTRUSTED_RAM_BASE (SCP_SYS1_BASE + 0x06000000) +#define SSC_BASE (SCP_SYS1_BASE + 0x2A420000) +#define SCP_REFCLK_CNTCONTROL_BASE (SCP_SYS1_BASE + 0x2A430000) + +/* + * Base addresses of MHU devices + */ +#define SCP_MHU_SCP_AP_NS(cluster) (SCP_MHU_AP_BASE + \ + (0x10000 * cluster) + 0x020) +#define SCP_MHU_AP_SCP_NS(cluster) (SCP_MHU_AP_BASE + \ + (0x10000 * cluster) + 0x120) +#define SCP_MHU_SCP_AP_S(cluster) (SCP_MHU_AP_BASE + \ + (0x10000 * cluster) + 0x200) +#define SCP_MHU_AP_SCP_S(cluster) (SCP_MHU_AP_BASE + \ + (0x10000 * cluster) + 0x300) + +#define SCP_MHU_SCP_MCP_NS (SCP_MHU_MCP_BASE + 0x020) +#define SCP_MHU_MCP_SCP_NS (SCP_MHU_MCP_BASE + 0x120) +#define SCP_MHU_SCP_MCP_S (SCP_MHU_MCP_BASE + 0x200) +#define SCP_MHU_MCP_SCP_S (SCP_MHU_MCP_BASE + 0x300) + +#endif /* SCP_SGI575_MMAP_H */ diff --git a/product/sgi575/include/scp_sgi575_mmap_scp.h b/product/sgi575/include/scp_sgi575_mmap_scp.h new file mode 100644 index 0000000000000000000000000000000000000000..3da4e644a94e22309de98e1d703f200ffbb29c98 --- /dev/null +++ b/product/sgi575/include/scp_sgi575_mmap_scp.h @@ -0,0 +1,15 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SGI575_MMAP_SCP_H +#define SCP_SGI575_MMAP_SCP_H + +#define SCP_ROM_BASE 0x00000000 +#define SCP_RAM0_BASE 0x00800000 +#define SCP_RAM1_BASE 0x20000000 + +#endif /* SCP_SGI575_MMAP_SCP_H */ diff --git a/product/sgi575/include/scp_sgi575_pik.h b/product/sgi575/include/scp_sgi575_pik.h new file mode 100644 index 0000000000000000000000000000000000000000..2abd1f78c614b8c197fd7594fcc3ed480df36792 --- /dev/null +++ b/product/sgi575/include/scp_sgi575_pik.h @@ -0,0 +1,20 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SGI575_PIK_H +#define SCP_SGI575_PIK_H + +#include +#include +#include +#include + +#define PIK_CLUSTER(IDX) ((struct pik_cpu_reg *) SCP_PIK_CLUSTER_BASE(IDX)) +#define PIK_SCP ((struct pik_scp_reg *) SCP_PIK_SCP_BASE) +#define PIK_SYSTEM ((struct pik_system_reg *) SCP_PIK_SYSTEM_BASE) + +#endif /* SCP_SGI575_PIK_H */ diff --git a/product/sgi575/include/scp_sgi575_scmi.h b/product/sgi575/include/scp_sgi575_scmi.h new file mode 100644 index 0000000000000000000000000000000000000000..5324729b25e687f027e994f2a17b6452bff90aa4 --- /dev/null +++ b/product/sgi575/include/scp_sgi575_scmi.h @@ -0,0 +1,28 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for SCMI and SMT module configurations. + */ + +#ifndef SCP_SGI575_SCMI_H +#define SCP_SGI575_SCMI_H + +/* SCMI agent identifiers */ +enum scp_sgi575_scmi_agent_id { + /* 0 is reserved for the platform */ + SCP_SCMI_AGENT_ID_OSPM = 1, + SCP_SCMI_AGENT_ID_PSCI, +}; + +/* SCMI service indexes */ +enum scp_sgi575_scmi_service_idx { + SCP_SGI575_SCMI_SERVICE_IDX_PSCI, + SCP_SGI575_SCMI_SERVICE_IDX_OSPM, + SCP_SGI575_SCMI_SERVICE_IDX_COUNT, +}; + +#endif /* SCP_SGI575_SCMI_H */ diff --git a/product/sgi575/include/scp_software_mmap.h b/product/sgi575/include/scp_software_mmap.h new file mode 100644 index 0000000000000000000000000000000000000000..d9340a1b73518b85150f0a5a2f87bb33f6320991 --- /dev/null +++ b/product/sgi575/include/scp_software_mmap.h @@ -0,0 +1,50 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Software defined memory map shared between SCP and AP cores. + */ + +#ifndef SCP_SOFTWARE_MMAP_H +#define SCP_SOFTWARE_MMAP_H + +#include +#include + +#define SCP_NOR_FLASH_BASE 0x08000000 +#define SCP_NOR_BASE (SCP_NOR_FLASH_BASE + 0x03D80000) +#define SCP_IMAGE_SIZE (256 * FWK_KIB) + +#define SCP_AP_SHARED_SECURE_BASE (SCP_TRUSTED_RAM_BASE) +#define SCP_AP_SHARED_SECURE_SIZE (4 * FWK_KIB) + +/* Non-secure shared memory at the base of Non-trusted SRAM */ +#define SCP_AP_SHARED_NONSECURE_BASE (SCP_NONTRUSTED_RAM_BASE) +#define SCP_AP_SHARED_NONSECURE_SIZE (4 * FWK_KIB) + +/* SDS Memory Region */ +#define SCP_SDS_MEM_BASE (SCP_AP_SHARED_SECURE_BASE) +#define SCP_SDS_MEM_SIZE (3520) + +/* AP Context Area */ +#define SCP_AP_CONTEXT_BASE (SCP_AP_SHARED_SECURE_BASE + \ + SCP_AP_SHARED_SECURE_SIZE - \ + SCP_AP_CONTEXT_SIZE) +#define SCP_AP_CONTEXT_SIZE (64) + +/* SCMI Secure Payload Areas */ +#define SCP_SCMI_PAYLOAD_SIZE (128) +#define SCP_SCMI_PAYLOAD_S_A2P_BASE (SCP_SDS_MEM_BASE + \ + SCP_SDS_MEM_SIZE) +#define SCP_SCMI_PAYLOAD_S_P2A_BASE (SCP_SCMI_PAYLOAD_S_A2P_BASE + \ + SCP_SCMI_PAYLOAD_SIZE) + +/* SCMI Non-Secure Payload Areas */ +#define SCP_SCMI_PAYLOAD_NS_A2P_BASE (SCP_AP_SHARED_NONSECURE_BASE) +#define SCP_SCMI_PAYLOAD_NS_P2A_BASE (SCP_SCMI_PAYLOAD_NS_A2P_BASE + \ + SCP_SCMI_PAYLOAD_SIZE) + +#endif /* SCP_SOFTWARE_MMAP_H */ diff --git a/product/sgi575/include/scp_system_mmap.h b/product/sgi575/include/scp_system_mmap.h new file mode 100644 index 0000000000000000000000000000000000000000..9f16bce9c1de397505ea90bf64c37e1741f6d396 --- /dev/null +++ b/product/sgi575/include/scp_system_mmap.h @@ -0,0 +1,41 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SYSTEM_MMAP_H +#define SCP_SYSTEM_MMAP_H + +#include + +#define SCP_PLAT_BASE (SCP_SYS0_BASE + 0x3FFE0000) + +#define SCP_PLL_BASE (SCP_EXPANSION2_BASE + 0x01000000) + +#define SCP_PLL_SYSPLL (SCP_PLL_BASE) +#define SCP_PLL_CLUS0 (SCP_PLL_BASE + 0x00000004) +#define SCP_PLL_CLUS1 (SCP_PLL_BASE + 0x00000008) +#define SCP_PLL_DMC (SCP_PLL_BASE + 0x00000010) +#define SCP_PLL_INTERCONNECT (SCP_PLL_BASE + 0x00000020) + +#define SCP_PLL_CPU0 (SCP_PLL_BASE + 0x00000100) +#define SCP_PLL_CPU1 (SCP_PLL_BASE + 0x00000104) +#define SCP_PLL_CPU2 (SCP_PLL_BASE + 0x00000108) +#define SCP_PLL_CPU3 (SCP_PLL_BASE + 0x0000010C) +#define SCP_PLL_CPU4 (SCP_PLL_BASE + 0x00000110) +#define SCP_PLL_CPU5 (SCP_PLL_BASE + 0x00000114) +#define SCP_PLL_CPU6 (SCP_PLL_BASE + 0x00000118) +#define SCP_PLL_CPU7 (SCP_PLL_BASE + 0x0000011C) + +#define SCP_DDR_PHY0 (SCP_SYS0_BASE + 0x3FB60000) +#define SCP_DDR_PHY1 (SCP_SYS0_BASE + 0x3FB70000) + +#define SCP_DMC0 (SCP_MEMORY_CONTROLLER + 0x00000000) +#define SCP_DMC1 (SCP_MEMORY_CONTROLLER + 0x00100000) + +#define SCP_SENSOR_SOC_TEMP (SCP_PLAT_BASE + 0x00000080) +#define SCP_PLATFORM_ID (SCP_PLAT_BASE + 0x000000E0) + +#endif /* SCP_SYSTEM_MMAP_H*/ diff --git a/product/sgi575/include/scp_system_mmap_scp.h b/product/sgi575/include/scp_system_mmap_scp.h new file mode 100644 index 0000000000000000000000000000000000000000..b22b4195855be9f1ac9fc874c1e531d407a4d262 --- /dev/null +++ b/product/sgi575/include/scp_system_mmap_scp.h @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SYSTEM_MMAP_SCP_H +#define SCP_SYSTEM_MMAP_SCP_H + +#include + +#define SCP_ROM_SIZE (64 * 1024) +#define SCP_RAM0_SIZE (256 * 1024) +#define SCP_RAM1_SIZE (256 * 1024) + +#endif /* SCP_SYSTEM_MMAP_SCP_H */ diff --git a/product/sgi575/include/sgi575_core.h b/product/sgi575/include/sgi575_core.h new file mode 100644 index 0000000000000000000000000000000000000000..2a61dcf927409fb9bc1252cbfc1cc074b4e33009 --- /dev/null +++ b/product/sgi575/include/sgi575_core.h @@ -0,0 +1,18 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_CORE_H +#define SGI575_CORE_H + +#define SGI575_CORE_PER_CLUSTER0_MAX 4 +#define SGI575_CORE_PER_CLUSTER1_MAX 4 + +unsigned int sgi575_core_get_core_per_cluster_count(unsigned int cluster); +unsigned int sgi575_core_get_core_count(void); +unsigned int sgi575_core_get_cluster_count(void); + +#endif /* SGI575_CORE_H */ diff --git a/product/sgi575/include/sgi575_pik_cpu.h b/product/sgi575/include/sgi575_pik_cpu.h new file mode 100644 index 0000000000000000000000000000000000000000..7e2330e7fdb6ec9d1cc8927660045538527ed18b --- /dev/null +++ b/product/sgi575/include/sgi575_pik_cpu.h @@ -0,0 +1,92 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_PIK_CPU_H +#define SGI575_PIK_CPU_H + +#include +#include + +/*! + * \brief PE Static Configuration register definitions + */ +struct static_config_reg { + FWK_RW uint32_t STATIC_CONFIG; + FWK_RW uint32_t RVBARADDR_LW; + FWK_RW uint32_t RVBARADDR_UP; + uint32_t RESERVED; +}; + +/*! + * \brief AP cores clock control register definitions + */ +struct coreclk_reg { + FWK_RW uint32_t CTRL; + FWK_RW uint32_t DIV; + uint32_t RESERVED; + FWK_RW uint32_t MOD; +}; + +/*! + * \brief CPU (V8.2) PIK register definitions + */ +struct pik_cpu_reg { + FWK_RW uint32_t CLUSTER_CONFIG; + uint8_t RESERVED0[0x10 - 0x4]; + struct static_config_reg STATIC_CONFIG[16]; + uint8_t RESERVED1[0x800 - 0x110]; + FWK_RW uint32_t PPUCLK_CTRL; + FWK_RW uint32_t PPUCLK_DIV1; + uint8_t RESERVED2[0x810 - 0x808]; + FWK_RW uint32_t PCLK_CTRL; + uint8_t RESERVED3[0x820 - 0x814]; + FWK_RW uint32_t DBGCLK_CTRL; + FWK_RW uint32_t DBGCLK_DIV1; + uint8_t RESERVED4[0x830 - 0x828]; + FWK_RW uint32_t GICCLK_CTRL; + uint8_t RESERVED5[0x840 - 0x834]; + FWK_RW uint32_t AMBACLK_CTRL; + uint8_t RESERVED6[0x850 - 0x844]; + FWK_RW uint32_t CLUSCLK_CTRL; + FWK_RW uint32_t CLUSCLK_DIV1; + uint8_t RESERVED7[0x860 - 0x858]; + struct coreclk_reg CORECLK[8]; + uint8_t RESERVED8[0xA00 - 0x8E0]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLR; + uint8_t RESERVED9[0xB00 - 0xA0C]; + FWK_R uint32_t NERRIQ_INT_STATUS; + FWK_R uint32_t NFAULTIQ_INT_STATUS; + uint8_t RESERVED10[0xFB4 - 0xB08]; + FWK_R uint32_t CAP3; + FWK_R uint32_t CAP2; + FWK_R uint32_t CAP; + FWK_R uint32_t PCL_CONFIG; + uint8_t RESERVED11[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; + +#define PIK_CPU_CAP_CLUSSYNC UINT32_C(0x00000001) +#define PIK_CPU_CAP_CORESYNC(CORE) ((uint32_t)(1 << ((CORE) + 1))) +#define PIK_CPU_CAP_PE_MASK UINT32_C(0xF0000000) +#define PIK_CPU_CAP_PE_POS 28 + +#define PIK_CPU_PCL_CONFIG_NO_OF_PPU UINT32_C(0x0000000F) + +#endif /* SGI575_PIK_CPU_H */ diff --git a/product/sgi575/include/sgi575_pik_debug.h b/product/sgi575/include/sgi575_pik_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..a8f667e23cb403fade334d02949c17614f80075d --- /dev/null +++ b/product/sgi575/include/sgi575_pik_debug.h @@ -0,0 +1,50 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_PIK_DEBUG_H +#define SGI575_PIK_DEBUG_H + +#include +#include + +/*! + * \brief Debug register definitions + */ +struct pik_debug_reg { + FWK_RW uint32_t DEBUG_CTRL; + FWK_R uint32_t DEBUG_STATUS; + FWK_RW uint32_t DEBUG_CONFIG; + uint8_t RESERVED0[0x10 - 0xC]; + FWK_R uint32_t APP_DAP_TARGET_ID; + FWK_R uint32_t SCP_DAP_TARGET_ID; + FWK_R uint32_t DAP_INSTANCE_ID; + uint8_t RESERVED1[0x810 - 0x1C]; + FWK_RW uint32_t TRACECLK_CTRL; + FWK_RW uint32_t TRACECLK_DIV1; + uint8_t RESERVED2[0x820 - 0x818]; + FWK_RW uint32_t PCLKDBG_CTRL; + uint8_t RESERVED3[0x830 - 0x824]; + FWK_RW uint32_t ATCLKDBG_CTRL; + FWK_RW uint32_t ATCLKDBG_DIV1; + FWK_R uint8_t RESERVED4[0xFC0 - 0x838]; + FWK_R uint32_t PCL_CONFIG; + uint8_t RESERVED5[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; + +#endif /* SGI575_PIK_DEBUG_H */ diff --git a/product/sgi575/include/sgi575_pik_scp.h b/product/sgi575/include/sgi575_pik_scp.h new file mode 100644 index 0000000000000000000000000000000000000000..14e42910211fd8bcffad3f863afaab4691dc90a2 --- /dev/null +++ b/product/sgi575/include/sgi575_pik_scp.h @@ -0,0 +1,97 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP PIK registers + */ + +#ifndef SGI575_PIK_SCP_H +#define SGI575_PIK_SCP_H + +#include +#include + +/*! + * \brief SCP PIK register definitions + */ +struct pik_scp_reg { + uint8_t RESERVED0[0x10 - 0x0]; + FWK_RW uint32_t RESET_SYNDROME; + uint8_t RESERVED1[0x20 - 0x14]; + FWK_RW uint32_t SURVIVAL_RESET_STATUS; + uint8_t RESERVED2[0x34 - 0x24]; + FWK_RW uint32_t ADDR_TRANS; + FWK_RW uint32_t DBG_ADDR_TRANS; + uint8_t RESERVED3[0x40 - 0x3C]; + FWK_RW uint32_t WS1_TIMER_MATCH; + FWK_RW uint32_t WS1_TIMER_EN; + uint8_t RESERVED4[0x200 - 0x48]; + FWK_R uint32_t SS_RESET_STATUS; + FWK_W uint32_t SS_RESET_SET; + FWK_W uint32_t SS_RESET_CLR; + uint8_t RESERVED5[0x810 - 0x20C]; + FWK_RW uint32_t CORECLK_CTRL; + FWK_RW uint32_t CORECLK_DIV1; + uint8_t RESERVED6[0x820 - 0x818]; + FWK_RW uint32_t ACLK_CTRL; + FWK_RW uint32_t ACLK_DIV1; + uint8_t RESERVED7[0xA10 - 0x828]; + FWK_R uint32_t PLL_STATUS[17]; + uint8_t RESERVED8[0xA60 - 0xA54]; + FWK_R uint32_t CONS_MMUTCU_INT_STATUS; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS0; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS1; + FWK_W uint32_t CONS_MMUTCU_INT_CLR; + FWK_W uint32_t CONS_MMUTBU_INT_CLR0; + FWK_W uint32_t CONS_MMUTBU_INT_CLR1; + uint8_t RESERVED9[0xB00 - 0xA78]; + FWK_R uint32_t MHU_NS_INT_STATUS; + FWK_R uint32_t MHU_S_INT_STATUS; + uint8_t RESERVED10[0xB20 - 0xB08]; + FWK_R uint32_t CPU_PPU_INT_STATUS[8]; + FWK_R uint32_t CLUS_PPU_INT_STATUS; + uint8_t RESERVED11[0xB60 - 0xB44]; + FWK_R uint32_t TIMER_INT_STATUS[8]; + FWK_RW uint32_t CPU_PLL_LOCK_STATUS[8]; + uint8_t RESERVED12[0xBC0 - 0xBA0]; + FWK_RW uint32_t CPU_PLL_UNLOCK_STATUS[8]; + uint8_t RESERVED13[0xBF0 - 0xBE0]; + FWK_RW uint32_t CLUSTER_PLL_LOCK_STATUS; + FWK_RW uint32_t CLUSTER_PLL_UNLOCK_STATUS; + uint8_t RESERVED14[0xC00 - 0xBF8]; + FWK_R uint32_t CLUS_FAULT_INT_STATUS; + uint8_t RESERVED15[0xC30 - 0xC04]; + FWK_R uint32_t CLUSTER_ECCERR_INT_STATUS; + uint8_t RESERVED16[0xD00 - 0xC34]; + FWK_R uint32_t DMC0_4_INT_STATUS; + FWK_R uint32_t DMC1_5_INT_STATUS; + FWK_R uint32_t DMC2_6_INT_STATUS; + FWK_R uint32_t DMC3_7_INT_STATUS; + uint8_t RESERVED17[0xFC0 - 0xD10]; + FWK_R uint32_t PCL_CFG; + uint8_t RESERVED18[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; + +#define PLL_STATUS_0_REFCLK UINT32_C(0x00000001) +#define PLL_STATUS_0_SYSPLLLOCK UINT32_C(0x00000002) +#define PLL_STATUS_0_DDRPLLLOCK UINT32_C(0x00000004) +#define PLL_STATUS_0_INTPLLLOCK UINT32_C(0x00000008) + +#define PLL_STATUS_CPUPLLLOCK(CPU) ((uint32_t)(1 << (CPU % 32))) + +#endif /* SGI575_PIK_SCP_H */ diff --git a/product/sgi575/include/sgi575_pik_system.h b/product/sgi575/include/sgi575_pik_system.h new file mode 100644 index 0000000000000000000000000000000000000000..47f2254820e5968603e1df4316d5fe0188384c45 --- /dev/null +++ b/product/sgi575/include/sgi575_pik_system.h @@ -0,0 +1,74 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_PIK_SYSTEM_H +#define SGI575_PIK_SYSTEM_H + +#include +#include + +/*! + * \brief TCU clock register definitions + */ +struct tcuclk_ctrl_reg { + FWK_RW uint32_t TCUCLK_CTRL; + FWK_RW uint32_t TCUCLK_DIV1; +}; + +/*! + * \brief System PIK register definitions + */ +struct pik_system_reg { + uint8_t RESERVED0[0x800 - 0x0]; + FWK_RW uint32_t PPUCLK_CTRL; + FWK_RW uint32_t PPUCLK_DIV1; + uint8_t RESERVED1[0x820 - 0x808]; + FWK_RW uint32_t INTCLK_CTRL; + FWK_RW uint32_t INTCLK_DIV1; + uint8_t RESERVED2[0x830 - 0x828]; + struct tcuclk_ctrl_reg TCUCLK[4]; + FWK_RW uint32_t GICCLK_CTRL; + FWK_RW uint32_t GICCLK_DIV1; + uint8_t RESERVED3[0x860 - 0x858]; + FWK_RW uint32_t PCLKSCP_CTRL; + FWK_RW uint32_t PCLKSCP_DIV1; + uint8_t RESERVED4[0x870 - 0x868]; + FWK_RW uint32_t SYSPERCLK_CTRL; + FWK_RW uint32_t SYSPERCLK_DIV1; + uint8_t RESERVED5[0x880 - 0x878]; + FWK_RW uint32_t DMCCLK_CTRL; + FWK_RW uint32_t DMCCLK_DIV1; + uint8_t RESERVED6[0x890 - 0x888]; + FWK_RW uint32_t SYSPCLKDBG_CTRL; + FWK_RW uint32_t SYSPCLKDBG_DIV1; + uint8_t RESERVED7[0x8A0 - 0x898]; + FWK_RW uint32_t UARTCLK_CTRL; + FWK_RW uint32_t UARTCLK_DIV1; + uint8_t RESERVED8[0xA00 - 0x8A8]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLR; + uint8_t RESERVED9[0xB0C - 0xA0C]; + FWK_RW uint32_t SYSTOP_RST_DLY; + uint8_t RESERVED10[0xFC0 - 0xB10]; + FWK_R uint32_t PCL_CONFIG; + uint8_t RESERVED11[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; + +#endif /* SGI575_PIK_SYSTEM_H */ diff --git a/product/sgi575/include/sgi575_power_domain.h b/product/sgi575/include/sgi575_power_domain.h new file mode 100644 index 0000000000000000000000000000000000000000..f0d0c2116ccffec13180165bf7087bede3d218d1 --- /dev/null +++ b/product/sgi575/include/sgi575_power_domain.h @@ -0,0 +1,51 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SGI575 System Support + */ + +#ifndef SGI575_POWER_DOMAIN_H +#define SGI575_POWER_DOMAIN_H + +#include + +/*! Additional SGI575 power domain states */ +enum sgi575_power_domain_states { + SGI575_POWER_DOMAIN_STATE_FUNC_RET = MOD_PD_STATE_COUNT, + SGI575_POWER_DOMAIN_STATE_FULL_RET, + SGI575_POWER_DOMAIN_STATE_MEM_RET, + SGI575_POWER_DOMAIN_STATE_COUNT +}; + +/*! Power domain state masks */ +enum sgi575_power_domain_state_masks { + SGI575_POWER_DOMAIN_STATE_FUNC_RET_MASK = + (1 << SGI575_POWER_DOMAIN_STATE_FUNC_RET), + SGI575_POWER_DOMAIN_STATE_FULL_RET_MASK = + (1 << SGI575_POWER_DOMAIN_STATE_FULL_RET), + SGI575_POWER_DOMAIN_STATE_MEM_RET_MASK = + (1 << SGI575_POWER_DOMAIN_STATE_MEM_RET), +}; + +/*! Mask for the cluster valid power states */ +#define SGI575_CLUSTER_VALID_STATE_MASK ( \ + MOD_PD_STATE_OFF_MASK | \ + MOD_PD_STATE_ON_MASK | \ + MOD_PD_STATE_SLEEP_MASK | \ + SGI575_POWER_DOMAIN_STATE_MEM_RET_MASK | \ + SGI575_POWER_DOMAIN_STATE_FUNC_RET_MASK \ + ) + +/*! Mask for the core valid power states */ +#define SGI575_CORE_VALID_STATE_MASK ( \ + MOD_PD_STATE_OFF_MASK | \ + MOD_PD_STATE_ON_MASK | \ + MOD_PD_STATE_SLEEP_MASK | \ + SGI575_POWER_DOMAIN_STATE_FULL_RET_MASK \ + ) + +#endif /* SGI575_POWER_DOMAIN_H */ diff --git a/product/sgi575/include/sgi575_sds.h b/product/sgi575/include/sgi575_sds.h new file mode 100644 index 0000000000000000000000000000000000000000..098814141926f07e4932fbb34960922d0e10da3f --- /dev/null +++ b/product/sgi575/include/sgi575_sds.h @@ -0,0 +1,82 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_SDS_H +#define SGI575_SDS_H + +#include + +/* + * Structure identifiers. + */ +enum sgi575_sds_struct_id { + SGI575_SDS_CPU_INFO = 1 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_FIRMWARE_VERSION = 2 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_PLATFORM_ID = 3 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_RESET_SYNDROME = 4 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_FEATURE_AVAILABILITY = + 5 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_CPU_BOOTCTR = 6 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + SGI575_SDS_CPU_FLAGS = 7 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), +}; + +/* + * Structure sizes. + */ +#define SGI575_SDS_CPU_INFO_SIZE 4 +#define SGI575_SDS_FIRMWARE_VERSION_SIZE 4 +#define SGI575_SDS_PLATFORM_ID_SIZE 8 +#define SGI575_SDS_RESET_SYNDROME_SIZE 4 +#define SGI575_SDS_FEATURE_AVAILABILITY_SIZE 4 +#define SGI575_SDS_CPU_BOOTCTR_SIZE 256 +#define SGI575_SDS_CPU_FLAGS_SIZE 256 + +/* + * Field masks and offsets for the SGI575_SDS_AP_CPU_INFO structure. + */ +#define SGI575_SDS_CPU_INFO_PRIMARY_MASK 0xFFFFFFFF +#define SGI575_SDS_CPU_INFO_PRIMARY_POS 0 + +/* + * Platform information: + * Structure, field masks and offsets for the SGI575_SDS_PLATFORM_ID + * structure. + */ +struct sgi575_sds_platid { + /* Subsystem part number */ + uint32_t platform_identifier; + /* Platform type information */ + uint32_t platform_type_identifier; +}; + +#define SGI575_SDS_PLATID_PARTNO_MASK 0xFFF +#define SGI575_SDS_PLATID_DESIGNER_MASK 0xFF000 +#define SGI575_SDS_PLATID_REV_MINOR_MASK 0xF00000 +#define SGI575_SDS_PLATID_REV_MAJOR_MASK 0xF000000 +#define SGI575_SDS_PLATID_CONFIG_MASK 0xF0000000 +#define SGI575_SDS_PLATID_TYPE_MASK 0xF + +#define SGI575_SDS_PLATID_PARTNO_POS 0 +#define SGI575_SDS_PLATID_DESIGNER_POS 12 +#define SGI575_SDS_PLATID_REV_MINOR_POS 20 +#define SGI575_SDS_PLATID_REV_MAJOR_POS 24 +#define SGI575_SDS_PLATID_CONFIG_POS 28 + +#define SGI575_SDS_PLATID_TYPE_POS 0 + +/* + * Field masks and offsets for the SGI575_SDS_FEATURE_AVAILABILITY structure. + */ +#define SGI575_SDS_FEATURE_FIRMWARE_MASK 0x1 +#define SGI575_SDS_FEATURE_DMC_MASK 0x2 +#define SGI575_SDS_FEATURE_MESSAGING_MASK 0x4 + +#define SGI575_SDS_FEATURE_FIRMWARE_POS 0 +#define SGI575_SDS_FEATURE_DMC_POS 1 +#define SGI575_SDS_FEATURE_MESSAGING_POS 2 + +#endif /* SGI575_SDS_H */ diff --git a/product/sgi575/include/sgi575_ssc.h b/product/sgi575/include/sgi575_ssc.h new file mode 100644 index 0000000000000000000000000000000000000000..683428ba3744caa779a1b4ebb2128baba98bc94e --- /dev/null +++ b/product/sgi575/include/sgi575_ssc.h @@ -0,0 +1,41 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SGI575_SSC_H +#define SGI575_SSC_H + +#include +#include + +/*! + * \brief System Security Control (SSC) register definitions + */ +struct ssc_reg { + uint8_t RESERVED1[0x10 - 0x0]; + FWK_R uint32_t SSC_DBGCFG_STAT; + FWK_W uint32_t SSC_DBGCFG_SET; + FWK_W uint32_t SSC_DBGCFG_CLR; + uint8_t RESERVED2[0x28 - 0x1C]; + FWK_RW uint32_t SSC_AUXDBGCFG; + uint8_t RESERVED3[0x30 - 0x2C]; + FWK_RW uint32_t SSC_GPRETN; + uint8_t RESERVED4[0x40 - 0x34]; + FWK_R uint32_t SSC_VERSION; + uint8_t RESERVED5[0xFD0 - 0x44]; + FWK_R uint32_t PID4; + uint8_t RESERVED6[0xFE0 - 0xFD4]; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t COMPID0; + FWK_R uint32_t COMPID1; + FWK_R uint32_t COMPID2; + FWK_R uint32_t COMPID3; +}; + +#endif /* SGI575_SSC_H */ diff --git a/product/sgi575/include/system_clock.h b/product/sgi575/include/system_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..73c66ba8a60316aeeece20b40e41ca49ab21091e --- /dev/null +++ b/product/sgi575/include/system_clock.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SYSTEM_CLOCK_H +#define SYSTEM_CLOCK_H + +#include + +#define CLOCK_RATE_REFCLK (100UL * FWK_MHZ) +#define CLOCK_RATE_SYSPLLCLK (2000UL * FWK_MHZ) + +#endif /* SYSTEM_CLOCK_H */ diff --git a/product/sgi575/mcp_romfw/config_clock.c b/product/sgi575/mcp_romfw/config_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..6e8e3309851d89958b070bd4fe4132f4f670febe --- /dev/null +++ b/product/sgi575/mcp_romfw/config_clock.c @@ -0,0 +1,10 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +const struct fwk_module_config config_clock = { 0 }; diff --git a/product/sgi575/mcp_romfw/config_log.c b/product/sgi575/mcp_romfw/config_log.c new file mode 100644 index 0000000000000000000000000000000000000000..f33e364a31151173ae59e5f970764e82c696077e --- /dev/null +++ b/product/sgi575/mcp_romfw/config_log.c @@ -0,0 +1,58 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * PL011 module + */ +static const struct fwk_element pl011_element_desc_table[] = { + [0] = { + .name = "uart0", + .data = &((struct mod_pl011_device_config) { + .reg_base = MCP_UART0_BASE, + .baud_rate_bps = 115200, + .clock_rate_hz = 24 * FWK_MHZ, + .clock_id = FWK_ID_NONE_INIT, + }), + }, + [1] = { 0 }, +}; + +static const struct fwk_element *get_pl011_table(fwk_id_t module_id) +{ + return pl011_element_desc_table; +} + +struct fwk_module_config config_pl011 = { + .get_element_table = get_pl011_table, +}; + +/* + * Log module + */ +static const struct mod_log_config log_data = { + .device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PL011, 0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PL011, 0), + .log_groups = MOD_LOG_GROUP_ERROR | + MOD_LOG_GROUP_INFO | + MOD_LOG_GROUP_WARNING | + MOD_LOG_GROUP_DEBUG, + .banner = FWK_BANNER_MCP + FWK_BANNER_ROM_FIRMWARE + BUILD_VERSION_DESCRIBE_STRING "\n", +}; + +struct fwk_module_config config_log = { + .data = &log_data, +}; diff --git a/product/sgi575/mcp_romfw/config_sgi575_rom.c b/product/sgi575/mcp_romfw/config_sgi575_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..7666bc7a73fd82be509ea9d304842b08fab71c63 --- /dev/null +++ b/product/sgi575/mcp_romfw/config_sgi575_rom.c @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +const struct fwk_module_config config_sgi575_rom = { + .data = &((struct sgi575_rom_config) { + .ramfw_base = MCP_RAM0_BASE, + .load_ram_size = 0, + }) +}; diff --git a/product/sgi575/mcp_romfw/firmware.mk b/product/sgi575/mcp_romfw/firmware.mk new file mode 100644 index 0000000000000000000000000000000000000000..618d0b3d6cc9b8d8bf5ba1f335f366233e6f394e --- /dev/null +++ b/product/sgi575/mcp_romfw/firmware.mk @@ -0,0 +1,25 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_FIRMWARE_CPU := cortex-m7 +BS_FIRMWARE_HAS_MULTITHREADING := no +BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_MODULE_HEADERS_ONLY := \ + power_domain + +BS_FIRMWARE_MODULES := \ + pl011 \ + log \ + clock \ + sgi575_rom + +BS_FIRMWARE_SOURCES := \ + config_log.c \ + config_clock.c \ + config_sgi575_rom.c + +include $(BS_DIR)/firmware.mk diff --git a/product/sgi575/mcp_romfw/fmw_memory.ld.S b/product/sgi575/mcp_romfw/fmw_memory.ld.S new file mode 100644 index 0000000000000000000000000000000000000000..1f6d4c29efc7b36014f3ad4582d5c826d80fb742 --- /dev/null +++ b/product/sgi575/mcp_romfw/fmw_memory.ld.S @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * ROM firmware memory layout for the linker script. + */ + +#ifndef FMW_MEMORY_LD_S +#define FMW_MEMORY_LD_S + +#include + +#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * ROM memory + */ +#define FIRMWARE_MEM0_SIZE MCP_ROM_SIZE +#define FIRMWARE_MEM0_BASE MCP_ROM_BASE + +/* + * RAM memory + */ +#define FIRMWARE_MEM1_SIZE MCP_RAM1_SIZE +#define FIRMWARE_MEM1_BASE MCP_RAM1_BASE + +#define FIRMWARE_STACK_SIZE (1 * 1024) + +#endif /* FMW_MEMORY_LD_S */ diff --git a/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h b/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..cd4a0661cf5380788a697905a3e5254d416a7a90 --- /dev/null +++ b/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h @@ -0,0 +1,45 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_SGI575_ROM_H +#define MOD_SGI575_ROM_H + +#include + +/*! + * \addtogroup GroupSGI575Module SGI575 Product Modules + * @{ + */ + +/*! + * \defgroup GroupSGI575 ROM Support + * @{ + */ + +/*! + * \brief Module configuration data. + */ +struct sgi575_rom_config { + /*! Base address of the RAM firmware image */ + const uintptr_t ramfw_base; + + /*! Base address of the NOR flash memory */ + const uintptr_t nor_base; + + /*! The RAM size to load */ + const unsigned int load_ram_size; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_SGI575_ROM_H */ diff --git a/product/sgi575/module/sgi575_rom/src/Makefile b/product/sgi575/module/sgi575_rom/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4e1226e49931629cda79d1dcb897ce5c63fbe01c --- /dev/null +++ b/product/sgi575/module/sgi575_rom/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := sgi575 ROM +BS_LIB_SOURCES := mod_sgi575_rom.c + +include $(BS_DIR)/lib.mk diff --git a/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c b/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..8375b9c4984bc570ac25479574f85f24e271609f --- /dev/null +++ b/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c @@ -0,0 +1,118 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct sgi575_rom_config *rom_config; +static struct mod_log_api *log_api; + +enum rom_event { + ROM_EVENT_RUN, + ROM_EVENT_COUNT +}; + +/* + * This function assumes that the RAM firmware image is located at the beginning + * of the SCP SRAM. The reset handler will be at offset 0x4 (the second entry of + * the vector table). + */ +static void jump_to_ramfw(void) +{ + uintptr_t const *reset_base = (uintptr_t *)(rom_config->ramfw_base + 0x4); + void (*ramfw_reset_handler)(void); + + /* + * Disable interrupts for the duration of the ROM firmware to RAM firmware + * transition. + */ + fwk_interrupt_global_disable(); + + ramfw_reset_handler = (void (*)(void))*reset_base; + + /* + * Execute the RAM firmware's reset handler to pass control from ROM + * firmware to the RAM firmware. + */ + ramfw_reset_handler(); +} + +/* + * Framework API + */ +static int sgi575_rom_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + rom_config = data; + + return FWK_SUCCESS; +} + +static int sgi575_rom_bind(fwk_id_t id, unsigned int round) +{ + int status; + + /* Use second round only (round numbering is zero-indexed) */ + if (round == 1) { + /* Bind to the log component */ + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), + &log_api); + + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + } + + return FWK_SUCCESS; +} + +static int sgi575_rom_start(fwk_id_t id) +{ + int status; + struct fwk_event event = { + .source_id = FWK_ID_MODULE(FWK_MODULE_IDX_SGI575_ROM), + .target_id = FWK_ID_MODULE(FWK_MODULE_IDX_SGI575_ROM), + .id = FWK_ID_EVENT(FWK_MODULE_IDX_SGI575_ROM, ROM_EVENT_RUN), + }; + + status = fwk_thread_put_event(&event); + + return status; +} + +static int sgi575_rom_process_event(const struct fwk_event *event, + struct fwk_event *resp) +{ + log_api->log(MOD_LOG_GROUP_INFO, "[ROM] Launch RAM\n"); + + if (rom_config->load_ram_size != 0) { + memcpy((void *)rom_config->ramfw_base, + (uint8_t *)rom_config->nor_base, rom_config->load_ram_size); + } + + jump_to_ramfw(); + + return FWK_SUCCESS; +} + +/* Module descriptor */ +const struct fwk_module module_sgi575_rom = { + .name = "SGI575_ROM", + .type = FWK_MODULE_TYPE_SERVICE, + .event_count = ROM_EVENT_COUNT, + .init = sgi575_rom_init, + .bind = sgi575_rom_bind, + .start = sgi575_rom_start, + .process_event = sgi575_rom_process_event, +}; diff --git a/product/sgi575/module/sgi575_system/include/mod_sgi575_system.h b/product/sgi575/module/sgi575_system/include/mod_sgi575_system.h new file mode 100644 index 0000000000000000000000000000000000000000..a5cb374f790b3a2c3e09915f65470b2d8e1cd59d --- /dev/null +++ b/product/sgi575/module/sgi575_system/include/mod_sgi575_system.h @@ -0,0 +1,64 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SGI575 System Support + */ + +#ifndef MOD_SGI575_SYSTEM_H +#define MOD_SGI575_SYSTEM_H + +#include + +/*! + * \addtogroup GroupSGI575Module SGI575 Product Modules + * @{ + */ + +/*! + * \defgroup GroupSGI575System SGI575 System Support + * @{ + */ + +/*! + * \brief Additional SGI575 system power states. + */ +enum mod_sgi575_system_power_states { + MOD_SGI575_SYSTEM_POWER_STATE_SLEEP0 = MOD_PD_STATE_COUNT, + MOD_SGI575_SYSTEM_POWER_STATE_SLEEP1, + MOD_SGI575_SYSTEM_POWER_STATE_COUNT +}; + +/*! + * \brief System power state masks. + */ +enum mod_sgi575_system_power_state_masks { + MOD_SGI575_SYSTEM_POWER_STATE_SLEEP0_MASK = + (1 << MOD_SGI575_SYSTEM_POWER_STATE_SLEEP0), + MOD_SGI575_SYSTEM_POWER_STATE_SLEEP1_MASK = + (1 << MOD_SGI575_SYSTEM_POWER_STATE_SLEEP1), +}; + +/*! + * \brief Indices of the interfaces exposed by the module. + */ +enum mod_sgi575_system_api_idx { + /*! API index for the driver interface of the SYSTEM POWER module */ + MOD_SGI575_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER, + + /*! Number of exposed interfaces */ + MOD_SGI575_SYSTEM_API_COUNT +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_SGI575_SYSTEM_H */ diff --git a/product/sgi575/module/sgi575_system/src/Makefile b/product/sgi575/module/sgi575_system/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f2769a6c000ba5364c0bfbf618345bb5350c7aab --- /dev/null +++ b/product/sgi575/module/sgi575_system/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := SGI575 SYSTEM +BS_LIB_SOURCES = mod_sgi575_system.c + +include $(BS_DIR)/lib.mk diff --git a/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c b/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c new file mode 100644 index 0000000000000000000000000000000000000000..ddb77e363be49d6d448286da936dd07fe8df85b6 --- /dev/null +++ b/product/sgi575/module/sgi575_system/src/mod_sgi575_system.c @@ -0,0 +1,269 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SGI575 System Support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Module context */ +struct sgi575_system_ctx { + /* Pointer to the SCP PIK registers */ + struct pik_scp_reg *pik_scp_reg; + + /* Log API pointer */ + const struct mod_log_api *log_api; + + /* Pointer to the Interrupt Service Routine API of the PPU_V1 module */ + const struct ppu_v1_isr_api *ppu_v1_isr_api; + + /* Power domain module restricted API pointer */ + struct mod_pd_restricted_api *mod_pd_restricted_api; +}; + +struct sgi575_system_isr { + unsigned int interrupt; + void (*handler)(void); +}; + +static struct sgi575_system_ctx sgi575_system_ctx; +const struct fwk_module_config config_sgi575_system = { 0 }; + +/* + * PPU Interrupt Service Routines for cluster and core power domains + */ + +static void ppu_cores_isr(unsigned int first, uint32_t status) +{ + unsigned int core_idx; + + while (status != 0) { + core_idx = __builtin_ctz(status); + status &= ~(1 << core_idx); + + if ((first + core_idx) >= sgi575_core_get_core_count()) + continue; + + sgi575_system_ctx.ppu_v1_isr_api->ppu_interrupt_handler( + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, first + core_idx)); + } +} + +static void ppu_cores_isr_0(void) +{ + ppu_cores_isr(0, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[0]); + ppu_cores_isr(128, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[4]); +} + +static void ppu_cores_isr_1(void) +{ + ppu_cores_isr(32, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[1]); + ppu_cores_isr(160, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[5]); +} + +static void ppu_cores_isr_2(void) +{ + ppu_cores_isr(64, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[2]); + ppu_cores_isr(192, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[6]); +} + +static void ppu_cores_isr_3(void) +{ + ppu_cores_isr(96, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[3]); + ppu_cores_isr(224, sgi575_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[7]); +} + +static void ppu_clusters_isr(void) +{ + uint32_t status = sgi575_system_ctx.pik_scp_reg->CLUS_PPU_INT_STATUS; + unsigned int cluster_idx; + + while (status != 0) { + cluster_idx = __builtin_ctz(status); + + sgi575_system_ctx.ppu_v1_isr_api->ppu_interrupt_handler( + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, + sgi575_core_get_core_count() + cluster_idx)); + + status &= ~(1 << cluster_idx); + } +} + +/* + * PPU Interrupt Service Routine table + */ + +static struct sgi575_system_isr isrs[] = { + [0] = { .interrupt = PPU_CORES0_IRQ, + .handler = ppu_cores_isr_0 }, + [1] = { .interrupt = PPU_CORES1_IRQ, + .handler = ppu_cores_isr_1 }, + [2] = { .interrupt = PPU_CORES2_IRQ, + .handler = ppu_cores_isr_2 }, + [3] = { .interrupt = PPU_CORES3_IRQ, + .handler = ppu_cores_isr_3 }, + [4] = { .interrupt = PPU_CLUSTERS_IRQ, + .handler = ppu_clusters_isr }, +}; + +/* + * SYSTEM POWER driver API + */ + +static int sgi575_system_shutdown( + enum mod_pd_system_shutdown system_shutdown) +{ + NVIC_SystemReset(); + + return FWK_E_DEVICE; +} + +static const struct mod_system_power_driver_api + sgi575_system_system_power_driver_api = { + .system_shutdown = sgi575_system_shutdown, +}; + +/* + * Functions fulfilling the framework's module interface + */ + +static int sgi575_system_mod_init(fwk_id_t module_id, unsigned int unused, + const void *unused2) +{ + int status; + unsigned int idx; + struct sgi575_system_isr *isr; + + for (idx = 0; idx < FWK_ARRAY_SIZE(isrs); idx++) { + isr = &isrs[idx]; + status = fwk_interrupt_set_isr(isr->interrupt, isr->handler); + if (status != FWK_SUCCESS) + return status; + } + + sgi575_system_ctx.pik_scp_reg = (struct pik_scp_reg *)SCP_PIK_SCP_BASE; + + return FWK_SUCCESS; +} + +static int sgi575_system_bind(fwk_id_t id, unsigned int round) +{ + int status; + + if (round == 0) { + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &sgi575_system_ctx.log_api); + if (status != FWK_SUCCESS) + return status; + } + + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_POWER_DOMAIN), + FWK_ID_API(FWK_MODULE_IDX_POWER_DOMAIN, MOD_PD_API_IDX_RESTRICTED), + &sgi575_system_ctx.mod_pd_restricted_api); + if (status != FWK_SUCCESS) + return status; + + return fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_PPU_V1), + FWK_ID_API(FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_ISR), + &sgi575_system_ctx.ppu_v1_isr_api); +} + +static int sgi575_system_process_bind_request(fwk_id_t requester_id, + fwk_id_t pd_id, fwk_id_t api_id, const void **api) +{ + *api = &sgi575_system_system_power_driver_api; + return FWK_SUCCESS; +} + +static int sgi575_system_start(fwk_id_t id) +{ + int status; + + status = fwk_notification_subscribe( + mod_clock_notification_id_state_changed, + FWK_ID_ELEMENT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_INTERCONNECT), + id); + if (status != FWK_SUCCESS) + return status; + + sgi575_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, + "[SGI575 SYSTEM] Requesting SYSTOP initialization...\n"); + + return + sgi575_system_ctx.mod_pd_restricted_api->set_composite_state_async( + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), false, + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, + MOD_PD_STATE_OFF, MOD_PD_STATE_OFF)); +} + +int sgi575_system_process_notification(const struct fwk_event *event, + struct fwk_event *resp_event) +{ + int status; + struct clock_notification_params *params; + struct mod_pd_restricted_api *mod_pd_restricted_api; + + assert(fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed)); + assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); + + params = (struct clock_notification_params *)event->params; + + /* + * Initialize primary core when the system is initialized for the first time + * only + */ + if (params->new_state == MOD_CLOCK_STATE_RUNNING) { + sgi575_system_ctx.log_api->log(MOD_LOG_GROUP_DEBUG, + "[SGI575 SYSTEM] Initializing the primary core...\n"); + + mod_pd_restricted_api = sgi575_system_ctx.mod_pd_restricted_api; + + status = mod_pd_restricted_api->set_composite_state_async( + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0), + false, + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, + MOD_PD_STATE_ON, MOD_PD_STATE_ON)); + if (status != FWK_SUCCESS) + return status; + + /* Unsubscribe to the notification */ + return fwk_notification_unsubscribe(event->id, event->source_id, + event->target_id); + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_sgi575_system = { + .name = "SGI575_SYSTEM", + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = MOD_SGI575_SYSTEM_API_COUNT, + .init = sgi575_system_mod_init, + .bind = sgi575_system_bind, + .process_bind_request = sgi575_system_process_bind_request, + .process_notification = sgi575_system_process_notification, + .start = sgi575_system_start, +}; diff --git a/product/sgi575/product.mk b/product/sgi575/product.mk new file mode 100644 index 0000000000000000000000000000000000000000..c734f1803d82a617c9cc3d5288efd12257929ed3 --- /dev/null +++ b/product/sgi575/product.mk @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_PRODUCT_NAME := sgi575 +BS_FIRMWARE_LIST := scp_romfw \ + scp_ramfw \ + mcp_romfw diff --git a/product/sgi575/scp_ramfw/RTX_Config.h b/product/sgi575/scp_ramfw/RTX_Config.h new file mode 100644 index 0000000000000000000000000000000000000000..fa9dbda806b2c6594cb42b8ec0c8520a58328965 --- /dev/null +++ b/product/sgi575/scp_ramfw/RTX_Config.h @@ -0,0 +1,56 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * RTX2 v5 configuration file. + * The file must be called RTX_Config.h as it is included by a RTX file + * in order to create an object file containing the configuration. + */ + +#ifndef RTX_CONFIG_H_ +#define RTX_CONFIG_H_ + +/* System */ +#define OS_DYNAMIC_MEM_SIZE 0 +#define OS_TICK_FREQ 1000 /* Hz */ +#define OS_ROBIN_ENABLE 0 +#define OS_ROBIN_TIMEOUT 0 +#define OS_ISR_FIFO_QUEUE 16 + +/* Thread */ +#define OS_THREAD_OBJ_MEM 0 +#define OS_THREAD_NUM 1 +#define OS_THREAD_DEF_STACK_NUM 0 +#define OS_THREAD_USER_STACK_SIZE 0 +#define OS_STACK_SIZE 200 +#define OS_IDLE_THREAD_STACK_SIZE 200 +#define OS_STACK_CHECK 1 +#define OS_STACK_WATERMARK 0 +#define OS_PRIVILEGE_MODE 1 + +/* Timer */ +#define OS_TIMER_OBJ_MEM 0 +#define OS_TIMER_NUM 1 +#define OS_TIMER_THREAD_PRIO 40 +#define OS_TIMER_THREAD_STACK_SIZE 200 +#define OS_TIMER_CB_QUEUE 4 + +/* Event flags */ +#define OS_EVFLAGS_OBJ_MEM 0 +#define OS_EVFLAGS_NUM 1 + +#define OS_MUTEX_OBJ_MEM 0 +#define OS_MUTEX_NUM 1 +#define OS_SEMAPHORE_OBJ_MEM 0 +#define OS_SEMAPHORE_NUM 1 +#define OS_MEMPOOL_OBJ_MEM 0 +#define OS_MEMPOOL_NUM 1 +#define OS_MEMPOOL_DATA_SIZE 0 +#define OS_MSGQUEUE_OBJ_MEM 0 +#define OS_MSGQUEUE_NUM 1 +#define OS_MSGQUEUE_DATA_SIZE 0 + +#endif /* RTX_CONFIG_H_ */ diff --git a/product/sgi575/scp_ramfw/config_apcontext.c b/product/sgi575/scp_ramfw/config_apcontext.c new file mode 100644 index 0000000000000000000000000000000000000000..12818b9d4b20044f88ff30311cdf8ed418ce061d --- /dev/null +++ b/product/sgi575/scp_ramfw/config_apcontext.c @@ -0,0 +1,26 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* + * AP Context module configuration + */ +static const struct mod_apcontext_config apcontext_data = { + .base = SCP_AP_CONTEXT_BASE, + .size = SCP_AP_CONTEXT_SIZE, + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT), +}; + +struct fwk_module_config config_apcontext = { + .data = &apcontext_data, +}; diff --git a/product/sgi575/scp_ramfw/config_armv7m_mpu.c b/product/sgi575/scp_ramfw/config_armv7m_mpu.c new file mode 100644 index 0000000000000000000000000000000000000000..515cce4f2c57234c1e30b65121951076970087dd --- /dev/null +++ b/product/sgi575/scp_ramfw/config_armv7m_mpu.c @@ -0,0 +1,47 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static const ARM_MPU_Region_t regions[] = { + { /* 0x0000_0000 - 0xFFFF_FFFF */ + .RBAR = ARM_MPU_RBAR(0, 0x00000000), + .RASR = ARM_MPU_RASR( + 1, ARM_MPU_AP_PRIV, 0, 1, 0, 1, 0, ARM_MPU_REGION_SIZE_4GB), + }, + { /* 0x0080_0000 - 0x00FF_FFFF */ + .RBAR = ARM_MPU_RBAR(1, SCP_RAM0_BASE), + .RASR = ARM_MPU_RASR( + 0, ARM_MPU_AP_PRO, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_256KB), + }, + { /* 0x2000_0000 - 0x20FF_FFFF */ + .RBAR = ARM_MPU_RBAR(2, SCP_RAM1_BASE), + .RASR = ARM_MPU_RASR( + 1, ARM_MPU_AP_PRIV, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB), + }, + { /* 0xA400_0000 - 0xA400_7FFF*/ + .RBAR = ARM_MPU_RBAR(3, SCP_TRUSTED_RAM_BASE), + .RASR = ARM_MPU_RASR( + 1, ARM_MPU_AP_PRIV, 0, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_4KB), + }, + { /* 0xA600_0000 - 0xA600_7FFF */ + .RBAR = ARM_MPU_RBAR(4, SCP_NONTRUSTED_RAM_BASE), + .RASR = ARM_MPU_RASR( + 1, ARM_MPU_AP_PRIV, 0, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_256B), + }, +}; + +const struct fwk_module_config config_armv7m_mpu = { + .data = &((struct mod_armv7m_mpu_config){ + .region_count = FWK_ARRAY_SIZE(regions), + .regions = regions, + }), +}; diff --git a/product/sgi575/scp_ramfw/config_clock.c b/product/sgi575/scp_ramfw/config_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..b719c1104515d6b26bd70c3d972b38a593145b34 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_clock.c @@ -0,0 +1,78 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct fwk_element clock_dev_desc_table[] = { + [CLOCK_IDX_INTERCONNECT] = { + .name = "Interconnect", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, + CLOCK_PIK_IDX_INTERCONNECT), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK, + MOD_PIK_CLOCK_API_TYPE_CLOCK), + }), + }, + [CLOCK_IDX_CPU_GROUP0] = { + .name = "CPU_GROUP0", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, + CLOCK_CSS_IDX_CPU_GROUP0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK, + MOD_CSS_CLOCK_API_TYPE_CLOCK), + }), + }, + [CLOCK_IDX_CPU_GROUP1] = { + .name = "CPU_GROUP1", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, + CLOCK_CSS_IDX_CPU_GROUP1), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK, + MOD_CSS_CLOCK_API_TYPE_CLOCK), + }), + }, + { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id) +{ + unsigned int i; + struct mod_clock_dev_config *dev_config; + + for (i = 0; i < CLOCK_IDX_COUNT; i++) { + dev_config = + (struct mod_clock_dev_config *)clock_dev_desc_table[i].data; + dev_config->pd_source_id = fwk_id_build_element_id( + fwk_module_id_power_domain, + sgi575_core_get_core_count() + PD_STATIC_DEV_IDX_SYSTOP); + } + + return clock_dev_desc_table; +} + +const struct fwk_module_config config_clock = { + .get_element_table = clock_get_dev_desc_table, + .data = &((struct mod_clock_config) { + .pd_transition_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION), + .pd_pre_transition_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_PRE_TRANSITION), + }), + +}; diff --git a/product/sgi575/scp_ramfw/config_clock.h b/product/sgi575/scp_ramfw/config_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..2f65ff55e927fb8e66c56e19a2d9196d294b81fe --- /dev/null +++ b/product/sgi575/scp_ramfw/config_clock.h @@ -0,0 +1,64 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_CLOCK_H +#define CONFIG_CLOCK_H + +/* + * Clock indexes. + */ +enum clock_idx { + CLOCK_IDX_INTERCONNECT, + CLOCK_IDX_CPU_GROUP0, + CLOCK_IDX_CPU_GROUP1, + CLOCK_IDX_COUNT +}; + +/* + * PIK clock indexes. + */ +enum clock_pik_idx { + CLOCK_PIK_IDX_CLUS0_CPU0, + CLOCK_PIK_IDX_CLUS0_CPU1, + CLOCK_PIK_IDX_CLUS0_CPU2, + CLOCK_PIK_IDX_CLUS0_CPU3, + CLOCK_PIK_IDX_CLUS1_CPU0, + CLOCK_PIK_IDX_CLUS1_CPU1, + CLOCK_PIK_IDX_CLUS1_CPU2, + CLOCK_PIK_IDX_CLUS1_CPU3, + CLOCK_PIK_IDX_DMC, + CLOCK_PIK_IDX_INTERCONNECT, + CLOCK_PIK_IDX_SCP, + CLOCK_PIK_IDX_GIC, + CLOCK_PIK_IDX_PCLKSCP, + CLOCK_PIK_IDX_SYSPERCLK, + CLOCK_PIK_IDX_UARTCLK, + CLOCK_PIK_IDX_COUNT +}; + +/* + * CSS clock indexes. + */ +enum clock_css_idx { + CLOCK_CSS_IDX_CPU_GROUP0, + CLOCK_CSS_IDX_CPU_GROUP1, + CLOCK_CSS_IDX_COUNT +}; + +/* + * PLL clock indexes. + */ +enum clock_pll_idx { + CLOCK_PLL_IDX_CPU0, + CLOCK_PLL_IDX_CPU1, + CLOCK_PLL_IDX_SYS, + CLOCK_PLL_IDX_DMC, + CLOCK_PLL_IDX_INTERCONNECT, + CLOCK_PLL_IDX_COUNT +}; + +#endif /* CONFIG_CLOCK_H */ diff --git a/product/sgi575/scp_ramfw/config_cmn600.c b/product/sgi575/scp_ramfw/config_cmn600.c new file mode 100644 index 0000000000000000000000000000000000000000..56c6f0d1dad7244586d2883f611148de31d1f083 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_cmn600.c @@ -0,0 +1,106 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* + * CMN600 nodes + */ +#define DMC0_ID 0x20 +#define DMC1_ID 0x4c +#define NODE_ID_HND 0xc +#define NODE_ID_SBSX 0x60 + +static const unsigned int snf_table[] = { + DMC0_ID, /* Maps to HN-F logical node 0 */ + DMC0_ID, /* Maps to HN-F logical node 1 */ + DMC1_ID, /* Maps to HN-F logical node 2 */ + DMC1_ID, /* Maps to HN-F logical node 3 */ +}; + +static const struct mod_cmn600_memory_region_map mmap[] = { + { + /* + * System cache backed region + * Map: 0x0000_0000_0000 - 0xFFFF_FFFF_FFFF (256 TB) + */ + .base = UINT64_C(0x000000000000), + .size = UINT64_C(256) * FWK_TIB, + .type = MOD_CMN600_MEMORY_REGION_TYPE_SYSCACHE, + }, + { + /* + * Boot region + * Map: 0x0000_0000_0000 - 0x0000_07FF_FFFF (128 MB) + */ + .base = UINT64_C(0x000000000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN600_REGION_TYPE_SYSCACHE_SUB, + .node_id = NODE_ID_SBSX, + }, + { + /* + * Peripherals + * Map: 0x00_0800_0000 - 0x00_0FFF_FFFF (128 MB) + */ + .base = UINT64_C(0x0008000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN600_MEMORY_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals + * Map: 0x00_1000_0000 - 0x00_1FFF_FFFF (256 MB) + */ + .base = UINT64_C(0x0010000000), + .size = UINT64_C(256) * FWK_MIB, + .type = MOD_CMN600_MEMORY_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals + * Map: 0x00_2000_0000 - 0x00_3FFF_FFFF (512 MB) + */ + .base = UINT64_C(0x0020000000), + .size = UINT64_C(512) * FWK_MIB, + .type = MOD_CMN600_MEMORY_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals + * Map: 0x00_4000_0000 - 0x00_7FFF_FFFF (1 GB) + */ + .base = UINT64_C(0x0040000000), + .size = UINT64_C(1) * FWK_GIB, + .type = MOD_CMN600_MEMORY_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, +}; + +const struct fwk_module_config config_cmn600 = { + .get_element_table = NULL, + .data = &((struct mod_cmn600_config) { + .base = SCP_CMN600_BASE, + .mesh_size_x = 4, + .mesh_size_y = 2, + .hnd_node_id = NODE_ID_HND, + .snf_table = snf_table, + .snf_count = FWK_ARRAY_SIZE(snf_table), + .mmap_table = mmap, + .mmap_count = FWK_ARRAY_SIZE(mmap), + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT), + }), +}; diff --git a/product/sgi575/scp_ramfw/config_css_clock.c b/product/sgi575/scp_ramfw/config_css_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..e895fbcdb431c654ede83609cd91162d81336ee5 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_css_clock.c @@ -0,0 +1,189 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct mod_css_clock_rate rate_table_cpu_group_0[] = { + { + /* Super Underdrive */ + .rate = 1313 * FWK_MHZ, + .pll_rate = 1313 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Underdrive */ + .rate = 1531 * FWK_MHZ, + .pll_rate = 1531 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Nominal */ + .rate = 1750 * FWK_MHZ, + .pll_rate = 1750 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Overdrive */ + .rate = 2100 * FWK_MHZ, + .pll_rate = 2100 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Super Overdrive */ + .rate = 2600 * FWK_MHZ, + .pll_rate = 2600 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, +}; + +static const struct mod_css_clock_rate rate_table_cpu_group_1[] = { + { + /* Super Underdrive */ + .rate = 1313 * FWK_MHZ, + .pll_rate = 1313 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Underdrive */ + .rate = 1531 * FWK_MHZ, + .pll_rate = 1531 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Nominal */ + .rate = 1750 * FWK_MHZ, + .pll_rate = 1750 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Overdrive */ + .rate = 2100 * FWK_MHZ, + .pll_rate = 2100 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, + { + /* Super Overdrive */ + .rate = 2600 * FWK_MHZ, + .pll_rate = 2600 * FWK_MHZ, + .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .clock_div = 1, + .clock_mod_numerator = 1, + .clock_mod_denominator = 1, + }, +}; + +static const fwk_id_t member_table_cpu_group_0[] = { + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU1), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU2), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU3), +}; + +static const fwk_id_t member_table_cpu_group_1[] = { + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS1_CPU0), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS1_CPU1), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS1_CPU2), + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS1_CPU3), +}; + +static const struct fwk_element css_clock_element_table[] = { + [CLOCK_CSS_IDX_CPU_GROUP0] = { + .name = "CPU_GROUP_0", + .data = &((struct mod_css_clock_dev_config) { + .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED, + .rate_table = rate_table_cpu_group_0, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_0), + .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK, + .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + CLOCK_PLL_IDX_CPU0), + .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + MOD_SYSTEM_PLL_API_TYPE_DEFAULT), + .member_table = member_table_cpu_group_0, + .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_0), + .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK, + MOD_PIK_CLOCK_API_TYPE_CSS), + .initial_rate = 2600 * FWK_MHZ, + .modulation_supported = true, + }), + }, + [CLOCK_CSS_IDX_CPU_GROUP1] = { + .name = "CPU_GROUP_1", + .data = &((struct mod_css_clock_dev_config) { + .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED, + .rate_table = rate_table_cpu_group_1, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_1), + .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK, + .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + CLOCK_PLL_IDX_CPU1), + .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + MOD_SYSTEM_PLL_API_TYPE_DEFAULT), + .member_table = member_table_cpu_group_1, + .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_1), + .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK, + MOD_PIK_CLOCK_API_TYPE_CSS), + .initial_rate = 2600 * FWK_MHZ, + .modulation_supported = true, + }), + }, + [CLOCK_CSS_IDX_COUNT] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *css_clock_get_element_table + (fwk_id_t module_id) +{ + return css_clock_element_table; +} + +const struct fwk_module_config config_css_clock = { + .get_element_table = css_clock_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_ddr_phy500.c b/product/sgi575/scp_ramfw/config_ddr_phy500.c new file mode 100644 index 0000000000000000000000000000000000000000..3ea38caa73b07868167b5f8eb84e75a381f87ee7 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_ddr_phy500.c @@ -0,0 +1,59 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* Default configuration values for DDR PHY500 devices. */ +static const struct mod_ddr_phy500_reg ddr_reg_val = { + .INIT_COMPLETE = 0x00000001, + .READ_DELAY = 0x00000001, + .CAPTURE_MASK = 0x00000002, + .T_CTRL_DELAY = 0x0C000000, + .T_WRLAT = 0x00000001, + .T_RDDATA_EN = 0x00001600, + .T_RDLAT = 0x00000011, + .DFI_LP_ACK = 0x00030000, + .DFI_WR_PREMBL = 0x00000001, + .DELAY_SEL = 0x0000000D, + .REF_EN = 0x00000000, + .T_CTRL_UPD_MIN = 0x00000000, +}; + +/* Table of DDR PHY500 element descriptions. */ +static struct fwk_element ddr_phy500_element_table[] = { + [0] = { .name = "DDR_PHY500-0", + .data = &((struct mod_ddr_phy500_element_config) { + .ddr = SCP_DDR_PHY0, + }), + }, + [1] = { .name = "DDR_PHY500-1", + .data = &((struct mod_ddr_phy500_element_config) { + .ddr = SCP_DDR_PHY1, + }), + }, + [2] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *ddr_phy500_get_element_table + (fwk_id_t module_id) +{ + return ddr_phy500_element_table; +} + +/* Configuration of the DDR PHY500 module. */ +struct fwk_module_config config_ddr_phy500 = { + .get_element_table = ddr_phy500_get_element_table, + .data = &((struct mod_ddr_phy500_module_config) { + .ddr_reg_val = &ddr_reg_val, + .initialize_init_complete = true, + .initialize_ref_en = true, + }), +}; diff --git a/product/sgi575/scp_ramfw/config_dmc620.c b/product/sgi575/scp_ramfw/config_dmc620.c new file mode 100644 index 0000000000000000000000000000000000000000..b10c5373eb2defae2c4d35713e56adb03f572b88 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_dmc620.c @@ -0,0 +1,218 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#define COL_BITS 2 +#define BANK_BITS 4 +#define RANK_BITS 1 +#define ROW_BITS 5 +#define BANK_HASH_ENABLE 1 +#define MEM_TYPE 2 +#define ADDR_DEC 0x68C +#define STRIPE_DEC 1 +#define MEM_DEVICE_WIDTH 0 +#define BANK_GROUP 3 +#define MEM_CHANNEL 2 +#define ADDRESS_CONTROL_NEXT_VAL ((BANK_HASH_ENABLE << 28) | \ + (RANK_BITS << 24) | (BANK_BITS << 16) | \ + (ROW_BITS << 8) | (COL_BITS)) +#define DECODE_CONTROL_NEXT_VAL ((ADDR_DEC << 10) | (STRIPE_DEC << 4)) +#define MEMORY_TYPE_NEXT_VAL ((BANK_GROUP << 16) | (MEM_DEVICE_WIDTH << 8) | \ + (MEM_TYPE)) + +struct mod_dmc620_reg dmc_val = { + .ADDRESS_CONTROL_NEXT = ADDRESS_CONTROL_NEXT_VAL, + .DECODE_CONTROL_NEXT = DECODE_CONTROL_NEXT_VAL, + .FORMAT_CONTROL = 0x00000003, + .ADDRESS_MAP_NEXT = 0x00000002, + .LOW_POWER_CONTROL_NEXT = 0x00000010, + .TURNAROUND_CONTROL_NEXT = 0x1F0F0F0F, + .HIT_TURNAROUND_CONTROL_NEXT = 0x08909FBF, + .QOS_CLASS_CONTROL_NEXT = 0x00000FC8, + .ESCALATION_CONTROL_NEXT = 0x00080F00, + .QV_CONTROL_31_00_NEXT = 0x76543210, + .QV_CONTROL_63_32_NEXT = 0xFEDCBA98, + .RT_CONTROL_31_00_NEXT = 0x00000000, + .RT_CONTROL_63_32_NEXT = 0x00000000, + .TIMEOUT_CONTROL_NEXT = 0x00000001, + .CREDIT_CONTROL_NEXT = 0x00000F03, + .WRITE_PRIORITY_CONTROL_31_00_NEXT = 0x00000000, + .WRITE_PRIORITY_CONTROL_63_32_NEXT = 0xECA86421, + .QUEUE_THRESHOLD_CONTROL_31_00_NEXT = 0x00000008, + .QUEUE_THRESHOLD_CONTROL_63_32_NEXT = 0x00000000, + .ADDRESS_SHUTTER_31_00_NEXT = 0x11111110, + .ADDRESS_SHUTTER_63_32_NEXT = 0x11111111, + .ADDRESS_SHUTTER_95_64_NEXT = 0x11111111, + .ADDRESS_SHUTTER_127_96_NEXT = 0x11111111, + .ADDRESS_SHUTTER_159_128_NEXT = 0x11111111, + .ADDRESS_SHUTTER_191_160_NEXT = 0x11111111, + .MEMORY_ADDRESS_MAX_31_00_NEXT = 0xFFFF001F, + .MEMORY_ADDRESS_MAX_43_32_NEXT = 0x00000FFF, + .ACCESS_ADDRESS_NEXT = { + [0] = {.MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000}, + [1] = {.MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000}, + [2] = {.MIN_31_00 = 0x0000000F}, + [3] = {.MIN_31_00 = 0x0000000F}, + [4] = {.MIN_31_00 = 0x0000000F}, + [5] = {.MIN_31_00 = 0x0000000F}, + [6] = {.MIN_31_00 = 0x0000000F}, + [7] = {.MIN_31_00 = 0x0000000F}, + }, + .DCI_REPLAY_TYPE_NEXT = 0x00000000, + .DCI_STRB = 0x00000007, + .DCI_DATA = 0x00000000, + .REFRESH_CONTROL_NEXT = 0x00000000, + .MEMORY_TYPE_NEXT = MEMORY_TYPE_NEXT_VAL, + .FEATURE_CONFIG = 0x00001800, + .FEATURE_CONTROL_NEXT = 0x00000000, + .MUX_CONTROL_NEXT = 0x00000000, + .T_REFI_NEXT = 0x90000618, + .T_RFC_NEXT = 0x06A8C230, + .T_MRR_NEXT = 0x00000001, + .T_MRW_NEXT = 0x00010018, + .T_RCD_NEXT = 0x00000014, + .T_RAS_NEXT = 0x00000034, + .T_RP_NEXT = 0x00000014, + .T_RPALL_NEXT = 0x00000014, + .T_RRD_NEXT = 0x04000805, + .T_ACT_WINDOW_NEXT = 0x00001010, + .T_RTR_NEXT = 0x14060804, + .T_RTW_NEXT = 0x000A0A0A, + .T_RTP_NEXT = 0x0000000C, + .T_WR_NEXT = 0x0000002C, + .T_WTR_NEXT = 0x00022019, + .T_WTW_NEXT = 0x14060804, + .T_XMPD_NEXT = 0x00000510, + .T_EP_NEXT = 0x00000008, + .T_XP_NEXT = 0x0014000A, + .T_ESR_NEXT = 0x00000009, + .T_XSR_NEXT = 0x04000110, + .T_ESRCK_NEXT = 0x00000010, + .T_CKXSR_NEXT = 0x00000010, + .T_CMD_NEXT = 0x00000000, + .T_PARITY_NEXT = 0x00001600, + .T_ZQCS_NEXT = 0x00000090, + .T_RW_ODT_CLR_NEXT = 0x0000005E, + .T_RDDATA_EN_NEXT = 0x00000000, + .T_PHYWRLAT_NEXT = 0x001F000E, + .T_PHYRDLAT_NEXT = 0x0000002E, + .RDLVL_CONTROL_NEXT = 0x00000000, + .RDLVL_MRS_NEXT = 0x00000424, + .T_RDLVL_EN_NEXT = 0x00000001, + .T_RDLVL_RR_NEXT = 0x0000001A, + .WRLVL_CONTROL_NEXT = 0x00100000, + .WRLVL_MRS_NEXT = 0x00000181, + .T_WRLVL_EN_NEXT = 0x00000018, + .T_WRLVL_WW_NEXT = 0x00000001, + .PHY_POWER_CONTROL_NEXT = 0x00000000, + .T_LPRESP_NEXT = 0x00000000, + .PHY_UPDATE_CONTROL_NEXT = 0x00000000, + .T_ODTH_NEXT = 0x00000006, + .ODT_TIMING_NEXT = 0x07003900, + .ODT_WR_CONTROL_31_00_NEXT = 0x08040201, + .ODT_WR_CONTROL_63_32_NEXT = 0x80402010, + .ODT_RD_CONTROL_31_00_NEXT = 0x00000000, + .ODT_RD_CONTROL_63_32_NEXT = 0x00000000, + .ERR0CTLR0 = DMC_ERR0CTRL0_ED_ENABLE | + DMC_ERR0CTRL0_DE_ENABLE | + DMC_ERR0CTRL0_UI_ENABLE | + DMC_ERR0CTRL0_FI_ENABLE | + DMC_ERR0CTRL0_CFI_ENABLE, +}; + +/* Table of DMC620 elements descriptions. */ +static struct fwk_element dmc620_element_table[] = { + [0] = { .name = "DMC620-0", + .data = &((struct mod_dmc620_element_config) { + .dmc = SCP_DMC0, + .ddr_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_DDR_PHY500, 0), + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT), + }), + }, + [1] = { .name = "DMC620-1", + .data = &((struct mod_dmc620_element_config) { + .dmc = SCP_DMC1, + .ddr_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_DDR_PHY500, 1), + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT), + }), + }, + [2] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *dmc620_get_element_table(fwk_id_t module_id) +{ + return dmc620_element_table; +} + +static void direct_ddr_cmd(struct mod_dmc620_reg *dmc) +{ + dmc->DIRECT_ADDR = 0x00000004; + dmc->DIRECT_CMD = 0x0001000A; + dmc->DIRECT_ADDR = 0x00000006; + dmc->DIRECT_CMD = 0x00030004; + dmc->DIRECT_ADDR = 0x00000000; + dmc->DIRECT_CMD = 0x0001000B; + dmc->DIRECT_ADDR = 0x00000001; + dmc->DIRECT_CMD = 0x0003000B; + dmc->DIRECT_ADDR = 0x000003E8; + dmc->DIRECT_CMD = 0x0001000D; + dmc->DIRECT_ADDR = 0x00000258; + dmc->DIRECT_CMD = 0x0001000D; + dmc->DIRECT_ADDR = 0x00010001; + dmc->DIRECT_CMD = 0x0003000B; + dmc->DIRECT_ADDR = 0x0000003C; + dmc->DIRECT_CMD = 0x0001000D; + dmc->DIRECT_ADDR = 0x00000000; + dmc->DIRECT_CMD = 0x00030000; + dmc->DIRECT_ADDR = 0x0000003C; + dmc->DIRECT_ADDR = 0x00000420; + dmc->DIRECT_CMD = 0x00030301; + dmc->DIRECT_ADDR = 0x00001000; + dmc->DIRECT_CMD = 0x00030601; + dmc->DIRECT_ADDR = 0x00000600; + dmc->DIRECT_CMD = 0x00030501; + dmc->DIRECT_ADDR = 0x00000000; + dmc->DIRECT_CMD = 0x30030401; + dmc->DIRECT_ADDR = 0x00000028; + dmc->DIRECT_CMD = 0x00030201; + dmc->DIRECT_ADDR = 0x00000001; + dmc->DIRECT_CMD = 0x00030101; + dmc->DIRECT_ADDR = 0x00000D50; + dmc->DIRECT_CMD = 0x00030001; + dmc->DIRECT_ADDR = 0x000003F6; + dmc->DIRECT_CMD = 0x0001000D; + dmc->DIRECT_ADDR = 0x0000000A; + dmc->DIRECT_CMD = 0x0001000D; + dmc->DIRECT_ADDR = 0x00000400; + dmc->DIRECT_CMD = 0x00030005; + dmc->DIRECT_ADDR = 0x000003FF; + dmc->DIRECT_CMD = 0x0001000D; + +} + +/* Configuration of the DMC500 module. */ +const struct fwk_module_config config_dmc620 = { + .get_element_table = dmc620_get_element_table, + .data = &((struct mod_dmc620_module_config) { + .dmc_val = &dmc_val, + .ddr_module_id = FWK_ID_MODULE_INIT( + FWK_MODULE_IDX_DDR_PHY500), + .ddr_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_DDR_PHY500, + 0), + .direct_ddr_cmd = direct_ddr_cmd, + }), +}; diff --git a/product/sgi575/scp_ramfw/config_dvfs.c b/product/sgi575/scp_ramfw/config_dvfs.c new file mode 100644 index 0000000000000000000000000000000000000000..a4f20070aa0a6559dfeb8a514a20efe73a5a568c --- /dev/null +++ b/product/sgi575/scp_ramfw/config_dvfs.c @@ -0,0 +1,74 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static struct mod_dvfs_opp opps[] = { + { + .frequency = 1313 * FWK_MHZ, + .voltage = 100, + }, + { + .frequency = 1531 * FWK_MHZ, + .voltage = 200, + }, + { + .frequency = 1750 * FWK_MHZ, + .voltage = 300, + }, + { + .frequency = 2100 * FWK_MHZ, + .voltage = 400, + }, + { + .frequency = 2600 * FWK_MHZ, + .voltage = 500, + }, + { 0 } +}; + +static const struct mod_dvfs_domain_config cpu_group0 = { + .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0), + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP0), + .latency = 1200, + .sustained_idx = 2, + .opps = opps, +}; + +static const struct mod_dvfs_domain_config cpu_group1 = { + .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 1), + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_CPU_GROUP1), + .latency = 1200, + .sustained_idx = 2, + .opps = opps, +}; + +static const struct fwk_element element_table[] = { + [0] = { + .name = "GROUP0", + .data = &cpu_group0, + }, + [1] = { + .name = "GROUP1", + .data = &cpu_group1, + }, + { 0 } +}; + +static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id) +{ + return element_table; +} + +const struct fwk_module_config config_dvfs = { + .get_element_table = dvfs_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_log.c b/product/sgi575/scp_ramfw/config_log.c new file mode 100644 index 0000000000000000000000000000000000000000..a989beaef3b13ae364d2da07efd43ca2a7566d90 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_log.c @@ -0,0 +1,58 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * PL011 module + */ +static const struct fwk_element pl011_element_desc_table[] = { + [0] = { + .name = "scp-uart1", + .data = &((struct mod_pl011_device_config) { + .reg_base = SCP_UART_BASE, + .baud_rate_bps = 115200, + .clock_rate_hz = 24 * FWK_MHZ, + .clock_id = FWK_ID_NONE_INIT, + }), + }, + [1] = { 0 }, +}; + +static const struct fwk_element *get_pl011_table(fwk_id_t module_id) +{ + return pl011_element_desc_table; +} + +struct fwk_module_config config_pl011 = { + .get_element_table = get_pl011_table, +}; + +/* + * Log module + */ +static const struct mod_log_config log_data = { + .device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PL011, 0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PL011, 0), + .log_groups = MOD_LOG_GROUP_ERROR | + MOD_LOG_GROUP_INFO | + MOD_LOG_GROUP_WARNING | + MOD_LOG_GROUP_DEBUG, + .banner = FWK_BANNER_SCP + FWK_BANNER_RAM_FIRMWARE + BUILD_VERSION_DESCRIBE_STRING "\n", +}; + +struct fwk_module_config config_log = { + .data = &log_data, +}; diff --git a/product/sgi575/scp_ramfw/config_mhu.c b/product/sgi575/scp_ramfw/config_mhu.c new file mode 100644 index 0000000000000000000000000000000000000000..4ac8b53371eeaacdd3fc0b8386101cbb04832252 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_mhu.c @@ -0,0 +1,46 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct fwk_element mhu_element_table[] = { + [SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_S] = { + .name = "MHU_SCP_AP_S", + .sub_element_count = 1, + .data = &((struct mod_mhu_device_config) { + .irq = MHU_AP_SEC_IRQ, + .in = SCP_MHU_AP_SCP_S(0), + .out = SCP_MHU_SCP_AP_S(0), + }) + }, + [SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_NS] = { + .name = "MHU_SCP_AP_NS", + .sub_element_count = 1, + .data = &((struct mod_mhu_device_config) { + .irq = MHU_AP_NONSEC_IRQ, + .in = SCP_MHU_AP_SCP_NS(0), + .out = SCP_MHU_SCP_AP_NS(0), + }) + }, + [SCP_SGI575_MHU_DEVICE_IDX_COUNT] = { 0 }, +}; + + +static const struct fwk_element *mhu_get_element_table(fwk_id_t module_id) +{ + return mhu_element_table; +} + +const struct fwk_module_config config_mhu = { + .get_element_table = mhu_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_mock_psu.c b/product/sgi575/scp_ramfw/config_mock_psu.c new file mode 100644 index 0000000000000000000000000000000000000000..453f6273a69cb7548bb44d21800764108f56a40f --- /dev/null +++ b/product/sgi575/scp_ramfw/config_mock_psu.c @@ -0,0 +1,39 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +static const struct fwk_element element_table[] = { + { + .name = "DVFS_GROUP0", + .data = + &(const struct mod_mock_psu_device_config){ + .default_enabled = true, + .default_voltage = 100, + }, + }, + { + .name = "DVFS_GROUP1", + .data = + &(const struct mod_mock_psu_device_config){ + .default_enabled = true, + .default_voltage = 100, + }, + }, + { 0 } +}; + +static const struct fwk_element *get_element_table(fwk_id_t module_id) +{ + return element_table; +} + +const struct fwk_module_config config_mock_psu = { + .get_element_table = get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_pik_clock.c b/product/sgi575/scp_ramfw/config_pik_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..d4447edeabce3afd915fa888f8d02f8523c65aa9 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_pik_clock.c @@ -0,0 +1,298 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Rate lookup tables + */ + +static struct mod_pik_clock_rate rate_table_cpu_group_0[] = { + { + .rate = 2600 * FWK_MHZ, + .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, /* Rate adjusted via CPU PLL */ + }, +}; + +static struct mod_pik_clock_rate rate_table_cpu_group_1[] = { + { + .rate = 2600 * FWK_MHZ, + .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, /* Rate adjusted via CPU PLL */ + }, +}; + +static const struct mod_pik_clock_rate rate_table_sys_intclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_INTCLK_SOURCE_INTPLL, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, + }, +}; + +static const struct mod_pik_clock_rate rate_table_sys_dmcclk[] = { + { + .rate = 1600 * FWK_MHZ, + .source = MOD_PIK_CLOCK_DMCCLK_SOURCE_DDRPLL, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, + }, +}; + +static const struct mod_pik_clock_rate rate_table_scp[] = { + { + .rate = 250 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (250 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_gicclk[] = { + { + .rate = 1000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (1000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_pclkscp[] = { + { + .rate = 400 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (400 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_sysperclk[] = { + { + .rate = 500 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (500 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_uartclk[] = { + { + .rate = 250 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (250 * FWK_MHZ), + }, +}; + +static const struct fwk_element pik_clock_element_table[] = { + /* + * Cluster 0 CPUS + */ + [CLOCK_PIK_IDX_CLUS0_CPU0] = { + .name = "CLUS0_CPU0", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(0)->CORECLK[0].CTRL, + .divext_reg = &PIK_CLUSTER(0)->CORECLK[0].DIV, + .modulator_reg = &PIK_CLUSTER(0)->CORECLK[0].MOD, + .rate_table = rate_table_cpu_group_0, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_0), + }), + }, + [CLOCK_PIK_IDX_CLUS0_CPU1] = { + .name = "CLUS0_CPU1", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(0)->CORECLK[1].CTRL, + .divext_reg = &PIK_CLUSTER(0)->CORECLK[1].DIV, + .modulator_reg = &PIK_CLUSTER(0)->CORECLK[1].MOD, + .rate_table = rate_table_cpu_group_0, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_0), + }), + }, + [CLOCK_PIK_IDX_CLUS0_CPU2] = { + .name = "CLUS0_CPU2", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(0)->CORECLK[2].CTRL, + .divext_reg = &PIK_CLUSTER(0)->CORECLK[2].DIV, + .modulator_reg = &PIK_CLUSTER(0)->CORECLK[2].MOD, + .rate_table = rate_table_cpu_group_0, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_0), + }), + }, + [CLOCK_PIK_IDX_CLUS0_CPU3] = { + .name = "CLUS0_CPU3", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(0)->CORECLK[3].CTRL, + .divext_reg = &PIK_CLUSTER(0)->CORECLK[3].DIV, + .modulator_reg = &PIK_CLUSTER(0)->CORECLK[3].MOD, + .rate_table = rate_table_cpu_group_0, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_0), + }), + }, + [CLOCK_PIK_IDX_CLUS1_CPU0] = { + .name = "CLUS1_CPU0", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(1)->CORECLK[0].CTRL, + .divext_reg = &PIK_CLUSTER(1)->CORECLK[0].DIV, + .modulator_reg = &PIK_CLUSTER(1)->CORECLK[0].MOD, + .rate_table = rate_table_cpu_group_1, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_1), + }), + }, + [CLOCK_PIK_IDX_CLUS1_CPU1] = { + .name = "CLUS1_CPU1", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(1)->CORECLK[1].CTRL, + .divext_reg = &PIK_CLUSTER(1)->CORECLK[1].DIV, + .modulator_reg = &PIK_CLUSTER(1)->CORECLK[1].MOD, + .rate_table = rate_table_cpu_group_1, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_1), + }), + }, + [CLOCK_PIK_IDX_CLUS1_CPU2] = { + .name = "CLUS1_CPU2", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(1)->CORECLK[2].CTRL, + .divext_reg = &PIK_CLUSTER(1)->CORECLK[2].DIV, + .modulator_reg = &PIK_CLUSTER(1)->CORECLK[2].MOD, + .rate_table = rate_table_cpu_group_1, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_1), + }), + }, + [CLOCK_PIK_IDX_CLUS1_CPU3] = { + .name = "CLUS1_CPU3", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_CLUSTER, + .is_group_member = true, + .control_reg = &PIK_CLUSTER(1)->CORECLK[3].CTRL, + .divext_reg = &PIK_CLUSTER(1)->CORECLK[3].DIV, + .modulator_reg = &PIK_CLUSTER(1)->CORECLK[3].MOD, + .rate_table = rate_table_cpu_group_1, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_1), + }), + }, + [CLOCK_PIK_IDX_DMC] = { + .name = "DMC", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->DMCCLK_CTRL, + .divext_reg = &PIK_SYSTEM->DMCCLK_DIV1, + .rate_table = rate_table_sys_dmcclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sys_dmcclk), + .initial_rate = 1600 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_INTERCONNECT] = { + .name = "INTERCONNECT", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->INTCLK_CTRL, + .divext_reg = &PIK_SYSTEM->INTCLK_DIV1, + .rate_table = rate_table_sys_intclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sys_intclk), + .initial_rate = 2000 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_SCP] = { + .name = "SCP", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SCP->CORECLK_CTRL, + .divsys_reg = &PIK_SCP->CORECLK_DIV1, + .rate_table = rate_table_scp, + .rate_count = FWK_ARRAY_SIZE(rate_table_scp), + .initial_rate = 250 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_GIC] = { + .name = "GIC", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->GICCLK_CTRL, + .divsys_reg = &PIK_SYSTEM->GICCLK_DIV1, + .rate_table = rate_table_gicclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_gicclk), + .initial_rate = 1000 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_PCLKSCP] = { + .name = "PCLKSCP", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->PCLKSCP_CTRL, + .divsys_reg = &PIK_SYSTEM->PCLKSCP_DIV1, + .rate_table = rate_table_pclkscp, + .rate_count = FWK_ARRAY_SIZE(rate_table_pclkscp), + .initial_rate = 400 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_SYSPERCLK] = { + .name = "SYSPERCLK", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->SYSPERCLK_CTRL, + .divsys_reg = &PIK_SYSTEM->SYSPERCLK_DIV1, + .rate_table = rate_table_sysperclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sysperclk), + .initial_rate = 500 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_UARTCLK] = { + .name = "UARTCLK", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &PIK_SYSTEM->UARTCLK_CTRL, + .divsys_reg = &PIK_SYSTEM->UARTCLK_DIV1, + .rate_table = rate_table_uartclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_uartclk), + .initial_rate = 250 * FWK_MHZ, + }), + }, + [CLOCK_PIK_IDX_COUNT] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *pik_clock_get_element_table + (fwk_id_t module_id) +{ + return pik_clock_element_table; +} + +const struct fwk_module_config config_pik_clock = { + .get_element_table = pik_clock_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_power_domain.c b/product/sgi575/scp_ramfw/config_power_domain.c new file mode 100644 index 0000000000000000000000000000000000000000..d2d448297e0d047f4958520d64ed88c47a118d71 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_power_domain.c @@ -0,0 +1,212 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Maximum power domain name size including the null terminator */ +#define PD_NAME_SIZE 12 + +/* Mask of the allowed states for the systop power domain */ +static const uint32_t systop_allowed_state_mask_table[] = { + [0] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK | + (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP0) | + (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP1) +}; + +/* + * Mask of the allowed states for the top level power domains + * (but the cluster power domains) depending on the system states. + */ +static const uint32_t toplevel_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK, + [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK +}; + +/* + * Mask of the allowed states for the cluster power domain depending on the + * system states. + */ +static const uint32_t cluster_pd_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = SGI575_CLUSTER_VALID_STATE_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK +}; + +/* Mask of the allowed states for a core depending on the cluster states. */ +static const uint32_t core_pd_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = SGI575_CORE_VALID_STATE_MASK, + [MOD_PD_STATE_SLEEP] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [SGI575_POWER_DOMAIN_STATE_FUNC_RET] = SGI575_CORE_VALID_STATE_MASK, + [SGI575_POWER_DOMAIN_STATE_MEM_RET] = MOD_PD_STATE_OFF_MASK +}; + +/* Power module specific configuration data (none) */ +static const struct mod_power_domain_config sgi575_power_domain_config = { 0 }; + +static struct fwk_element sgi575_power_domain_static_element_table[] = { + [PD_STATIC_DEV_IDX_CLUSTER0] = { + .name = "CLUS0", + .data = &((struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_CLUSTER, + .tree_pos = MOD_PD_TREE_POS( + MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_CLUSTER0, 0), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = cluster_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table) + }), + }, + [PD_STATIC_DEV_IDX_CLUSTER1] = { + .name = "CLUS1", + .data = &((struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_CLUSTER, + .tree_pos = MOD_PD_TREE_POS( + MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_CLUSTER1, 0), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = cluster_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table) + }), + }, + [PD_STATIC_DEV_IDX_DBGTOP] = { + .name = "DBGTOP", + .data = &((struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG, + .tree_pos = MOD_PD_TREE_POS( + MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_DBGTOP, 0), + .driver_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_PPU_V0, PPU_V0_ELEMENT_IDX_DBGTOP), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), + .allowed_state_mask_table = toplevel_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table) + }), + }, + [PD_STATIC_DEV_IDX_SYSTOP] = { + .name = "SYSTOP", + .data = &((struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_SYSTEM, + .tree_pos = MOD_PD_TREE_POS( + MOD_PD_LEVEL_2, 0, 0, 0, 0), + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SYSTEM_POWER, + MOD_SYSTEM_POWER_API_IDX_PD_DRIVER), + .allowed_state_mask_table = systop_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(systop_allowed_state_mask_table) + }), + }, +}; + +/* + * Function definitions with internal linkage + */ +static const struct fwk_element *sgi575_power_domain_get_element_table + (fwk_id_t module_id) +{ + struct fwk_element *element_table, *element; + struct mod_power_domain_element_config *pd_config_table, *pd_config; + unsigned int core_idx; + unsigned int cluster_idx; + unsigned int core_count; + unsigned int cluster_count; + unsigned int core_element_count = 0; + + core_count = sgi575_core_get_core_count(); + cluster_count = sgi575_core_get_cluster_count(); + + element_table = fwk_mm_calloc( + core_count + + FWK_ARRAY_SIZE(sgi575_power_domain_static_element_table) + + 1, /* Terminator */ + sizeof(struct fwk_element)); + if (element_table == NULL) + return NULL; + + pd_config_table = fwk_mm_calloc(core_count, + sizeof(struct mod_power_domain_element_config)); + if (pd_config_table == NULL) + return NULL; + + for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { + for (core_idx = 0; + core_idx < sgi575_core_get_core_per_cluster_count(cluster_idx); + core_idx++) { + + element = &element_table[core_element_count]; + pd_config = &pd_config_table[core_element_count]; + + element->name = fwk_mm_alloc(PD_NAME_SIZE, 1); + if (element->name == NULL) + return NULL; + + snprintf((char *)element->name, PD_NAME_SIZE, "CLUS%uCORE%u", + cluster_idx, core_idx); + + element->data = pd_config; + + pd_config->attributes.pd_type = MOD_PD_TYPE_CORE; + pd_config->tree_pos = MOD_PD_TREE_POS( + MOD_PD_LEVEL_0, 0, 0, cluster_idx, core_idx); + pd_config->driver_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, + core_element_count); + pd_config->api_id = FWK_ID_API( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER); + pd_config->allowed_state_mask_table = + core_pd_allowed_state_mask_table; + pd_config->allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table); + core_element_count++; + } + + /* Define the driver id for the cluster */ + pd_config = (struct mod_power_domain_element_config *) + sgi575_power_domain_static_element_table[cluster_idx].data; + pd_config->driver_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, + (core_count + cluster_idx)); + } + + memcpy(element_table + core_count, + sgi575_power_domain_static_element_table, + sizeof(sgi575_power_domain_static_element_table)); + + return element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_power_domain = { + .get_element_table = sgi575_power_domain_get_element_table, + .data = &sgi575_power_domain_config, +}; diff --git a/product/sgi575/scp_ramfw/config_power_domain.h b/product/sgi575/scp_ramfw/config_power_domain.h new file mode 100644 index 0000000000000000000000000000000000000000..b428c14883a3d0ce8404384df96ac817428c3841 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_power_domain.h @@ -0,0 +1,27 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_POWER_DOMAIN_H +#define CONFIG_POWER_DOMAIN_H + +/* + * Power domain indices for the statically defined domains used for: + * - Indexing the domains in the sgi575_power_domain_static_element_table + * - Indexing the SYSTOP children in the power domain tree + * + * When calculating a power domain element index, use the formula: + * core_count + pd_static_dev_idx + */ +enum pd_static_dev_idx { + PD_STATIC_DEV_IDX_CLUSTER0, + PD_STATIC_DEV_IDX_CLUSTER1, + PD_STATIC_DEV_IDX_DBGTOP, + PD_STATIC_DEV_IDX_SYSTOP, + PD_STATIC_DEV_IDX_COUNT +}; + +#endif /* CONFIG_POWER_DOMAIN_H */ diff --git a/product/sgi575/scp_ramfw/config_ppu_v0.c b/product/sgi575/scp_ramfw/config_ppu_v0.c new file mode 100644 index 0000000000000000000000000000000000000000..1acf54bb45846f670f9cb30c833fe14264a5071d --- /dev/null +++ b/product/sgi575/scp_ramfw/config_ppu_v0.c @@ -0,0 +1,37 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static struct fwk_element ppu_v0_element_table[] = { + [PPU_V0_ELEMENT_IDX_DBGTOP] = { + .name = "DBGTOP", + .data = &((struct mod_ppu_v0_pd_config) { + .pd_type = MOD_PD_TYPE_DEVICE_DEBUG, + .ppu.reg_base = SCP_PPU_DEBUG_BASE, + }), + }, + [PPU_V0_ELEMENT_IDX_COUNT] = { 0 }, /* Termination entry */ +}; + + +static const struct fwk_element *ppu_v0_get_element_table(fwk_id_t module_id) +{ + return ppu_v0_element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_ppu_v0 = { + .get_element_table = ppu_v0_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_ppu_v0.h b/product/sgi575/scp_ramfw/config_ppu_v0.h new file mode 100644 index 0000000000000000000000000000000000000000..ec0c88df6ae5e36f99189e882976ac37b8006ce5 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_ppu_v0.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_PPU_V0_H +#define CONFIG_PPU_V0_H + +enum ppu_v0_element_idx { + PPU_V0_ELEMENT_IDX_DBGTOP, + PPU_V0_ELEMENT_IDX_COUNT +}; + +#endif /* CONFIG_PPU_V0_H */ diff --git a/product/sgi575/scp_ramfw/config_ppu_v1.c b/product/sgi575/scp_ramfw/config_ppu_v1.c new file mode 100644 index 0000000000000000000000000000000000000000..b32c87cf1bc6ca685aeefe101caf898720fc9409 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_ppu_v1.c @@ -0,0 +1,161 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Maximum PPU core name size including the null terminator */ +#define PPU_CORE_NAME_SIZE 12 + +/* Maximum PPU cluster name size including the null terminator */ +#define PPU_CLUS_NAME_SIZE 6 + +/* Lookup table for translating cluster indexes into CMN600 node IDs */ +static const unsigned int cluster_idx_to_node_id[] = {44, 64}; + +/* Module configuration data */ +static struct mod_ppu_v1_config ppu_v1_config_data = { + .pd_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION), +}; + +static struct fwk_element ppu_v1_system_element_table[] = { + [0] = { + .name = "SYS0", + .data = &((struct mod_ppu_v1_pd_config) { + .pd_type = MOD_PD_TYPE_SYSTEM, + .ppu.reg_base = SCP_PPU_SYS0_BASE, + .observer_id = FWK_ID_NONE_INIT, + }), + }, + [1] = { + .name = "SYS1", + .data = &((struct mod_ppu_v1_pd_config) { + .pd_type = MOD_PD_TYPE_SYSTEM, + .ppu.reg_base = SCP_PPU_SYS1_BASE, + .observer_id = FWK_ID_NONE_INIT, + }), + }, +}; + +static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) +{ + struct fwk_element *element_table, *element; + struct mod_ppu_v1_pd_config *pd_config_table, *pd_config; + unsigned int core_idx; + unsigned int cluster_idx; + unsigned int core_count; + unsigned int cluster_count; + unsigned int core_element_count = 0; + + core_count = sgi575_core_get_core_count(); + cluster_count = sgi575_core_get_cluster_count(); + + assert(cluster_count == FWK_ARRAY_SIZE(cluster_idx_to_node_id)); + + /* + * Allocate element descriptors based on: + * Number of cores + * + Number of cluster descriptors + * + Number of system power domain descriptors + * + 1 terminator descriptor + */ + element_table = fwk_mm_calloc(core_count + cluster_count + + FWK_ARRAY_SIZE(ppu_v1_system_element_table) + 1, + sizeof(struct fwk_element)); + if (element_table == NULL) + return NULL; + + pd_config_table = fwk_mm_calloc(core_count + cluster_count, + sizeof(struct mod_ppu_v1_pd_config)); + if (pd_config_table == NULL) + return NULL; + + for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { + for (core_idx = 0; + core_idx < sgi575_core_get_core_per_cluster_count(cluster_idx); + core_idx++) { + element = &element_table[core_element_count]; + pd_config = &pd_config_table[core_element_count]; + + element->name = fwk_mm_alloc(PPU_CORE_NAME_SIZE, 1); + if (element->name == NULL) + return NULL; + + snprintf((char *)element->name, PPU_CORE_NAME_SIZE, "CLUS%uCORE%u", + cluster_idx, core_idx); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CORE; + pd_config->ppu.reg_base = SCP_PPU_CORE_BASE(cluster_idx, core_idx); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->cluster_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, + (core_count + cluster_idx)); + pd_config->observer_id = FWK_ID_NONE; + core_element_count++; + } + + element = &element_table[core_count + cluster_idx]; + pd_config = &pd_config_table[core_count + cluster_idx]; + + element->name = fwk_mm_alloc(PPU_CLUS_NAME_SIZE, 1); + if (element->name == NULL) + return NULL; + + snprintf((char *)element->name, PPU_CLUS_NAME_SIZE, "CLUS%u", + cluster_idx); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CLUSTER; + pd_config->ppu.reg_base = SCP_PPU_CLUSTER_BASE(cluster_idx); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->observer_id = fwk_module_id_cmn600; + pd_config->observer_api = FWK_ID_API(FWK_MODULE_IDX_CMN600, + MOD_CMN600_API_IDX_PPU_OBSERVER); + pd_config->post_ppu_on_param = + (void *)&cluster_idx_to_node_id[cluster_idx]; + } + + memcpy(&element_table[core_count + cluster_count], + ppu_v1_system_element_table, + sizeof(ppu_v1_system_element_table)); + + /* + * Configure pd_source_id with the SYSTOP identifier from the power domain + * module which is dynamically defined based on the number of cores. + */ + ppu_v1_config_data.pd_source_id = fwk_id_build_element_id( + fwk_module_id_power_domain, + core_count + PD_STATIC_DEV_IDX_SYSTOP); + + return element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_ppu_v1 = { + .get_element_table = ppu_v1_get_element_table, + .data = &ppu_v1_config_data, +}; diff --git a/product/sgi575/scp_ramfw/config_psu.c b/product/sgi575/scp_ramfw/config_psu.c new file mode 100644 index 0000000000000000000000000000000000000000..5a8654a91b01d9cf8b2b9d0e7dc475b6942ed191 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_psu.c @@ -0,0 +1,41 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static const struct fwk_element element_table[] = { + { + .name = "DVFS_GROUP0", + .data = &(const struct mod_psu_device_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MOCK_PSU, 0), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MOCK_PSU, + MOD_MOCK_PSU_API_IDX_PSU_DRIVER) + }, + }, + { + .name = "DVFS_GROUP1", + .data = &(const struct mod_psu_device_config){ + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MOCK_PSU, 1), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MOCK_PSU, + MOD_MOCK_PSU_API_IDX_PSU_DRIVER) + }, + }, + { 0 } +}; + +static const struct fwk_element *psu_get_element_table(fwk_id_t module_id) +{ + return element_table; +} + +const struct fwk_module_config config_psu = { + .get_element_table = psu_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_scmi.c b/product/sgi575/scp_ramfw/config_scmi.c new file mode 100644 index 0000000000000000000000000000000000000000..35311ec6f4a1c619e7d5b9e7512c03eff971bca0 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_scmi.c @@ -0,0 +1,71 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct fwk_element service_table[] = { + [SCP_SGI575_SCMI_SERVICE_IDX_PSCI] = { + .name = "SERVICE0", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SMT, + SCP_SGI575_SCMI_SERVICE_IDX_PSCI), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_API_IDX_SCMI_TRANSPORT), + .scmi_agent_id = SCP_SCMI_AGENT_ID_PSCI, + }), + }, + [SCP_SGI575_SCMI_SERVICE_IDX_OSPM] = { + .name = "SERVICE1", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SMT, + SCP_SGI575_SCMI_SERVICE_IDX_OSPM), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_API_IDX_SCMI_TRANSPORT), + .scmi_agent_id = SCP_SCMI_AGENT_ID_OSPM, + }), + }, + [SCP_SGI575_SCMI_SERVICE_IDX_COUNT] = { 0 } +}; + +static const struct fwk_element *get_service_table(fwk_id_t module_id) +{ + return service_table; +} + +static struct mod_scmi_agent agent_table[] = { + [SCP_SCMI_AGENT_ID_OSPM] = { + .type = SCMI_AGENT_TYPE_OSPM, + .name = "OSPM", + }, + [SCP_SCMI_AGENT_ID_PSCI] = { + .type = SCMI_AGENT_TYPE_PSCI, + .name = "PSCI", + }, +}; + +const struct fwk_module_config config_scmi = { + .get_element_table = get_service_table, + .data = &((struct mod_scmi_config) { + .protocol_count_max = 9, + .agent_count = FWK_ARRAY_SIZE(agent_table) - 1, + .agent_table = agent_table, + .vendor_identifier = "arm", + .sub_vendor_identifier = "arm", + }), +}; diff --git a/product/sgi575/scp_ramfw/config_scmi_apcore.c b/product/sgi575/scp_ramfw/config_scmi_apcore.c new file mode 100644 index 0000000000000000000000000000000000000000..62883dfdf2422da223505b5dbf13d0174814cdc3 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_scmi_apcore.c @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static const struct mod_scmi_apcore_reset_register_group + reset_reg_group_table[] = { + { + .base_register = + (uintptr_t)&PIK_CLUSTER(0)->STATIC_CONFIG[0].RVBARADDR_LW, + .register_count = + (SGI575_CORE_PER_CLUSTER0_MAX + SGI575_CORE_PER_CLUSTER1_MAX), + }, + }; + +const struct fwk_module_config config_scmi_apcore = { + .data = &((struct mod_scmi_apcore_config){ + .reset_register_width = MOD_SCMI_APCORE_REG_WIDTH_64, + .reset_register_group_count = + FWK_ARRAY_SIZE(reset_reg_group_table), + .reset_register_group_table = &reset_reg_group_table[0], + }), +}; diff --git a/product/sgi575/scp_ramfw/config_scmi_perf.c b/product/sgi575/scp_ramfw/config_scmi_perf.c new file mode 100644 index 0000000000000000000000000000000000000000..e5d25f2f3002f825ad5642f7d3f6d735117930a5 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_scmi_perf.c @@ -0,0 +1,36 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static const struct mod_scmi_perf_domain_config domains[] = { + [0] = { + .permissions = &(const uint32_t[]) { + [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | + MOD_SCMI_PERF_PERMS_SET_LIMITS, + [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, + } + }, + [1] = { + .permissions = &(const uint32_t[]) { + [SCP_SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL | + MOD_SCMI_PERF_PERMS_SET_LIMITS, + [SCP_SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE, + } + }, +}; + +const struct fwk_module_config config_scmi_perf = { + .get_element_table = NULL, + .data = &((struct mod_scmi_perf_config) { + .domains = &domains, + }), +}; diff --git a/product/sgi575/scp_ramfw/config_scmi_system_power.c b/product/sgi575/scp_ramfw/config_scmi_system_power.c new file mode 100644 index 0000000000000000000000000000000000000000..30408ae78d2a529379581c62bc4c2ac2517719b9 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_scmi_system_power.c @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +const struct fwk_module_config config_scmi_system_power = { + .data = &((struct mod_scmi_system_power_config) { + .system_view = MOD_SCMI_SYSTEM_VIEW_FULL, + .system_suspend_state = MOD_SYSTEM_POWER_POWER_STATE_SLEEP0 + }), +}; diff --git a/product/sgi575/scp_ramfw/config_sds.c b/product/sgi575/scp_ramfw/config_sds.c new file mode 100644 index 0000000000000000000000000000000000000000..84c63a479bf8d8bd64d0401eb1f18c2a26d6ff58 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_sds.c @@ -0,0 +1,121 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint32_t version_packed = FWK_BUILD_VERSION; +static const uint32_t feature_flags = (SGI575_SDS_FEATURE_FIRMWARE_MASK | + SGI575_SDS_FEATURE_DMC_MASK | + SGI575_SDS_FEATURE_MESSAGING_MASK); + +const struct mod_sds_config sds_module_config = { + .region_base_address = SCP_SDS_MEM_BASE, + .region_size = SCP_SDS_MEM_SIZE, + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT) +}; + +static struct sgi575_sds_platid platid; + +static struct fwk_element sds_element_table[] = { + { + .name = "CPU Info", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_CPU_INFO, + .size = SGI575_SDS_CPU_INFO_SIZE, + .finalize = true, + }), + }, + { + .name = "Firmware version", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_FIRMWARE_VERSION, + .size = SGI575_SDS_FIRMWARE_VERSION_SIZE, + .payload = &version_packed, + .finalize = true, + }), + }, + { + .name = "Platform ID", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_PLATFORM_ID, + .size = SGI575_SDS_PLATFORM_ID_SIZE, + .payload = &platid, + .finalize = true, + }), + }, + { + .name = "Reset Syndrome", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_RESET_SYNDROME, + .size = SGI575_SDS_RESET_SYNDROME_SIZE, + .payload = (void *)(&PIK_SCP->RESET_SYNDROME), + .finalize = true, + }), + }, + { + .name = "Feature Availability", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_FEATURE_AVAILABILITY, + .size = SGI575_SDS_FEATURE_AVAILABILITY_SIZE, + .payload = &feature_flags, + .finalize = true, + }), + }, +#ifdef MODE_DEBUG + { + .name = "Boot Counters", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_CPU_BOOTCTR, + .size = SGI575_SDS_CPU_BOOTCTR_SIZE, + .finalize = true, + }), + }, + { + .name = "CPU Flags", + .data = &((struct mod_sds_structure_desc) { + .id = SGI575_SDS_CPU_FLAGS, + .size = SGI575_SDS_CPU_FLAGS_SIZE, + .finalize = true, + }), + }, +#endif + { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *sds_get_element_table(fwk_id_t module_id) +{ + struct ssc_reg *ssc_regs = ((struct ssc_reg *)(SSC_BASE)); + + static_assert(BUILD_VERSION_MAJOR < UINT8_MAX, "Invalid version size"); + static_assert(BUILD_VERSION_MINOR < UINT8_MAX, "Invalid version size"); + static_assert(BUILD_VERSION_PATCH < UINT16_MAX, "Invalid version size"); + + platid.platform_identifier = ssc_regs->SSC_VERSION; + platid.platform_type_identifier = platid.platform_identifier & + SGI575_SDS_PLATID_PARTNO_MASK; + + return sds_element_table; +} + +struct fwk_module_config config_sds = { + .get_element_table = sds_get_element_table, + .data = &sds_module_config, +}; diff --git a/product/sgi575/scp_ramfw/config_sensor.c b/product/sgi575/scp_ramfw/config_sensor.c new file mode 100644 index 0000000000000000000000000000000000000000..c3af128417276be8431714fbaa8a5da1b84ebcfe --- /dev/null +++ b/product/sgi575/scp_ramfw/config_sensor.c @@ -0,0 +1,72 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +enum REG_SENSOR_DEVICES { + REG_SENSOR_DEV_SOC_TEMP, + REG_SENSOR_DEV_COUNT, +}; + +/* + * Register Sensor driver config + */ +static const struct fwk_element reg_sensor_element_table[] = { + [REG_SENSOR_DEV_SOC_TEMP] = { + .name = "Soc Temperature", + .data = &((struct mod_reg_sensor_dev_config) { + .reg = (uintptr_t)(SCP_SENSOR_SOC_TEMP), + }), + }, + [REG_SENSOR_DEV_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_reg_sensor_element_table(fwk_id_t id) +{ + return reg_sensor_element_table; +} + +struct fwk_module_config config_reg_sensor = { + .get_element_table = get_reg_sensor_element_table, +}; + + +/* + * Sensor module config + */ +static const struct mod_sensor_dev_config soctemp_config = { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_REG_SENSOR, + REG_SENSOR_DEV_SOC_TEMP), + .info = &((struct mod_sensor_info) { + .type = MOD_SENSOR_TYPE_DEGREES_C, + .update_interval = 0, + .update_interval_multiplier = 0, + .unit_multiplier = 0, + }), +}; + +static const struct fwk_element sensor_element_table[] = { + [0] = { + .name = "Soc Temperature", + .data = &soctemp_config, + }, + [1] = { 0 }, +}; + +static const struct fwk_element *get_sensor_element_table(fwk_id_t module_id) +{ + return sensor_element_table; +} + +const struct fwk_module_config config_sensor = { + .get_element_table = get_sensor_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_smt.c b/product/sgi575/scp_ramfw/config_smt.c new file mode 100644 index 0000000000000000000000000000000000000000..4127418fdb65654701f99538d35d5aee300f39a3 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_smt.c @@ -0,0 +1,64 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct fwk_element smt_element_table[] = { + [SCP_SGI575_SCMI_SERVICE_IDX_PSCI] = { + .name = "PSCI", + .data = &((struct mod_smt_channel_config) { + .type = MOD_SMT_CHANNEL_TYPE_SLAVE, + .policies = MOD_SMT_POLICY_INIT_MAILBOX | MOD_SMT_POLICY_SECURE, + .mailbox_address = (uintptr_t)SCP_SCMI_PAYLOAD_S_A2P_BASE, + .mailbox_size = SCP_SCMI_PAYLOAD_SIZE, + .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_MHU, + SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_S, 0), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU, 0), + }) + }, + [SCP_SGI575_SCMI_SERVICE_IDX_OSPM] = { + .name = "OSPM", + .data = &((struct mod_smt_channel_config) { + .type = MOD_SMT_CHANNEL_TYPE_SLAVE, + .policies = MOD_SMT_POLICY_INIT_MAILBOX, + .mailbox_address = (uintptr_t)SCP_SCMI_PAYLOAD_NS_A2P_BASE, + .mailbox_size = SCP_SCMI_PAYLOAD_SIZE, + .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_MHU, + SCP_SGI575_MHU_DEVICE_IDX_SCP_AP_NS, 0), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU, 0), + }) + }, + [SCP_SGI575_SCMI_SERVICE_IDX_COUNT] = { 0 }, +}; + +static const struct fwk_element *smt_get_element_table(fwk_id_t module_id) +{ + unsigned int idx; + struct mod_smt_channel_config *config; + + for (idx = 0; idx < SCP_SGI575_SCMI_SERVICE_IDX_COUNT; idx++) { + config = (struct mod_smt_channel_config *)(smt_element_table[idx].data); + config->pd_source_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, + sgi575_core_get_core_count() + PD_STATIC_DEV_IDX_SYSTOP); + } + + return smt_element_table; +} + +const struct fwk_module_config config_smt = { + .get_element_table = smt_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_system_pll.c b/product/sgi575/scp_ramfw/config_system_pll.c new file mode 100644 index 0000000000000000000000000000000000000000..fbec538e75ef341428fd8ab3cadd8ef5d03be27a --- /dev/null +++ b/product/sgi575/scp_ramfw/config_system_pll.c @@ -0,0 +1,90 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct fwk_element system_pll_element_table[] = { + [CLOCK_PLL_IDX_CPU0] = { + .name = "CPU_PLL_0", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_CPU0, + .status_reg = (void *)&PIK_SCP->PLL_STATUS[1], + .lock_flag_mask = PLL_STATUS_CPUPLLLOCK(0), + .initial_rate = 2600 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CLOCK_PLL_IDX_CPU1] = { + .name = "CPU_PLL_1", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_CPU1, + .status_reg = (void *)&PIK_SCP->PLL_STATUS[1], + .lock_flag_mask = PLL_STATUS_CPUPLLLOCK(1), + .initial_rate = 2600 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CLOCK_PLL_IDX_SYS] = { + .name = "SYS_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_SYSPLL, + .status_reg = (void *)&PIK_SCP->PLL_STATUS[0], + .lock_flag_mask = PLL_STATUS_0_SYSPLLLOCK, + .initial_rate = 2000 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CLOCK_PLL_IDX_DMC] = { + .name = "DMC_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_DMC, + .status_reg = (void *)&PIK_SCP->PLL_STATUS[0], + .lock_flag_mask = PLL_STATUS_0_DDRPLLLOCK, + .initial_rate = 1600 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CLOCK_PLL_IDX_INTERCONNECT] = { + .name = "INT_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_INTERCONNECT, + .status_reg = (void *)&PIK_SCP->PLL_STATUS[0], + .lock_flag_mask = PLL_STATUS_0_INTPLLLOCK, + .initial_rate = 2000 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CLOCK_PLL_IDX_COUNT] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *system_pll_get_element_table + (fwk_id_t module_id) +{ + return system_pll_element_table; +} + +const struct fwk_module_config config_system_pll = { + .get_element_table = system_pll_get_element_table, +}; diff --git a/product/sgi575/scp_ramfw/config_system_power.c b/product/sgi575/scp_ramfw/config_system_power.c new file mode 100644 index 0000000000000000000000000000000000000000..173ad0e2719188a00e64ae4323e4caa4d12783e1 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_system_power.c @@ -0,0 +1,58 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Table with only a terminator */ +static const struct fwk_element sgi575_system_element_table = { 0 }; + +static struct mod_system_power_config system_power_config = { + .soc_wakeup_irq = SOC_WAKEUP0_IRQ, + + /* PPU settings */ + .ppu_sys_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + + /* System driver */ + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SGI575_SYSTEM), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SGI575_SYSTEM, + MOD_SGI575_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), +}; + +static const struct fwk_element *sgi575_system_get_element_table( + fwk_id_t unused) +{ + /* The system PPUs are placed after the core and cluster PPUs */ + unsigned int ppu_idx_base = sgi575_core_get_core_count() + + sgi575_core_get_cluster_count(); + + /* Set the system PPU elements */ + system_power_config.ppu_sys0_id = fwk_id_build_element_id( + fwk_module_id_ppu_v1, ppu_idx_base); + system_power_config.ppu_sys1_id = fwk_id_build_element_id( + fwk_module_id_ppu_v1, ppu_idx_base + 1); + + /* + * Return table with only a terminator as this function is only used to + * setup the dynamic module data. + */ + return &sgi575_system_element_table; +} + +const struct fwk_module_config config_system_power = { + .get_element_table = sgi575_system_get_element_table, + .data = &system_power_config, +}; diff --git a/product/sgi575/scp_ramfw/config_timer.c b/product/sgi575/scp_ramfw/config_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..64c6bd1cff8c8e3481fd3dadc3609741395d44b0 --- /dev/null +++ b/product/sgi575/scp_ramfw/config_timer.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Generic timer driver config + */ +static const struct fwk_element gtimer_dev_table[] = { + [0] = { + .name = "REFCLK", + .data = &((struct mod_gtimer_dev_config) { + .hw_timer = SCP_REFCLK_CNTBASE0_BASE, + .hw_counter = SCP_REFCLK_CNTCTL_BASE, + .control = SCP_REFCLK_CNTCONTROL_BASE, + .frequency = CLOCK_RATE_REFCLK, + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT) + }) + }, + [1] = { 0 }, +}; + +static const struct fwk_element *gtimer_get_dev_table(fwk_id_t module_id) +{ + return gtimer_dev_table; +} + +const struct fwk_module_config config_gtimer = { + .get_element_table = gtimer_get_dev_table, +}; + +/* + * Timer HAL config + */ +static const struct fwk_element timer_dev_table[] = { + [0] = { + .name = "REFCLK", + .data = &((struct mod_timer_dev_config) { + .id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_GTIMER, 0), + .timer_irq = TIMREFCLK_IRQ, + }), + .sub_element_count = 8, /* Number of alarms */ + }, + [1] = { 0 }, +}; + +static const struct fwk_element *timer_get_dev_table(fwk_id_t module_id) +{ + return timer_dev_table; +} + +const struct fwk_module_config config_timer = { + .get_element_table = timer_get_dev_table, +}; diff --git a/product/sgi575/scp_ramfw/firmware.mk b/product/sgi575/scp_ramfw/firmware.mk new file mode 100644 index 0000000000000000000000000000000000000000..a094b90a9333978612cd29fd396745d2561561d5 --- /dev/null +++ b/product/sgi575/scp_ramfw/firmware.mk @@ -0,0 +1,77 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_FIRMWARE_CPU := cortex-m7 +BS_FIRMWARE_HAS_MULTITHREADING := yes +BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_MODULE_HEADERS_ONLY := + +BS_FIRMWARE_MODULES := \ + armv7m_mpu \ + pl011 \ + log \ + cmn600 \ + apcontext \ + power_domain \ + clock \ + dmc620 \ + ddr_phy500 \ + ppu_v0 \ + ppu_v1 \ + system_power \ + sgi575_system \ + mhu \ + smt \ + scmi \ + sds \ + system_pll \ + pik_clock \ + css_clock \ + gtimer \ + timer \ + sensor \ + reg_sensor \ + scmi_sensor \ + mock_psu \ + psu \ + dvfs \ + scmi_perf \ + scmi_power_domain \ + scmi_system_power \ + scmi_apcore + +BS_FIRMWARE_SOURCES := \ + rtx_config.c \ + sgi575_core.c \ + config_armv7m_mpu.c \ + config_log.c \ + config_cmn600.c \ + config_power_domain.c \ + config_clock.c \ + config_dmc620.c \ + config_ddr_phy500.c \ + config_ppu_v0.c \ + config_ppu_v1.c \ + config_system_power.c \ + config_mhu.c \ + config_smt.c \ + config_scmi.c \ + config_sds.c \ + config_system_pll.c \ + config_pik_clock.c \ + config_css_clock.c \ + config_timer.c \ + config_sensor.c \ + config_mock_psu.c \ + config_psu.c \ + config_dvfs.c \ + config_scmi_perf.c \ + config_scmi_system_power.c \ + config_scmi_apcore.c \ + config_apcontext.c + +include $(BS_DIR)/firmware.mk diff --git a/product/sgi575/scp_ramfw/fmw_memory.ld.S b/product/sgi575/scp_ramfw/fmw_memory.ld.S new file mode 100644 index 0000000000000000000000000000000000000000..c87a448f82a91174e2f4986a62af14706aa19353 --- /dev/null +++ b/product/sgi575/scp_ramfw/fmw_memory.ld.S @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * RAM firmware memory layout for the linker script. + */ + +#ifndef FMW_MEMORY_LD_S +#define FMW_MEMORY_LD_S + +#include + +#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * RAM instruction memory + */ +#define FIRMWARE_MEM0_SIZE SCP_RAM0_SIZE +#define FIRMWARE_MEM0_BASE SCP_RAM0_BASE + +/* + * RAM data memory + */ +#define FIRMWARE_MEM1_SIZE SCP_RAM1_SIZE +#define FIRMWARE_MEM1_BASE SCP_RAM1_BASE + +#define FIRMWARE_STACK_SIZE (1 * 1024) + +#endif /* FMW_MEMORY_LD_S */ diff --git a/product/sgi575/scp_ramfw/rtx_config.c b/product/sgi575/scp_ramfw/rtx_config.c new file mode 100644 index 0000000000000000000000000000000000000000..bce3ba4bbadc52a261a82a24b8f44dcf2512473c --- /dev/null +++ b/product/sgi575/scp_ramfw/rtx_config.c @@ -0,0 +1,35 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* + * Required by RTX to configure the SysTick timer. + */ +uint32_t SystemCoreClock = CLOCK_RATE_REFCLK; + +/* + * Idle thread + */ +__NO_RETURN void osRtxIdleThread(void *argument) +{ + while (true) + __WFI(); +} + +/* + * OS error handler + */ +uint32_t osRtxErrorNotify(uint32_t code, void *object_id) +{ + osRtxIdleThread(object_id); +} diff --git a/product/sgi575/scp_romfw/config_clock.c b/product/sgi575/scp_romfw/config_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..6e8e3309851d89958b070bd4fe4132f4f670febe --- /dev/null +++ b/product/sgi575/scp_romfw/config_clock.c @@ -0,0 +1,10 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +const struct fwk_module_config config_clock = { 0 }; diff --git a/product/sgi575/scp_romfw/config_gtimer.c b/product/sgi575/scp_romfw/config_gtimer.c new file mode 100644 index 0000000000000000000000000000000000000000..bd1eca4afee9c3e8f5d34b7831ad79499c0c1ff0 --- /dev/null +++ b/product/sgi575/scp_romfw/config_gtimer.c @@ -0,0 +1,38 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* + * Generic timer driver config + */ +static const struct fwk_element gtimer_dev_table[] = { + [0] = { + .name = "REFCLK", + .data = &((struct mod_gtimer_dev_config) { + .hw_timer = SCP_REFCLK_CNTBASE0_BASE, + .hw_counter = SCP_REFCLK_CNTCTL_BASE, + .control = SCP_REFCLK_CNTCONTROL_BASE, + .frequency = CLOCK_RATE_REFCLK, + .clock_id = FWK_ID_NONE_INIT, + }) + }, + [1] = { 0 }, +}; + +static const struct fwk_element *gtimer_get_dev_table(fwk_id_t module_id) +{ + return gtimer_dev_table; +} + +const struct fwk_module_config config_gtimer = { + .get_element_table = gtimer_get_dev_table, +}; diff --git a/product/sgi575/scp_romfw/config_log.c b/product/sgi575/scp_romfw/config_log.c new file mode 100644 index 0000000000000000000000000000000000000000..b0dee0cfbb9a1d3a8e737ae3f265eb07bfcb109c --- /dev/null +++ b/product/sgi575/scp_romfw/config_log.c @@ -0,0 +1,58 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * PL011 module + */ +static const struct fwk_element pl011_element_desc_table[] = { + [0] = { + .name = "uart", + .data = &((struct mod_pl011_device_config) { + .reg_base = SCP_UART_BASE, + .baud_rate_bps = 115200, + .clock_rate_hz = 24 * FWK_MHZ, + .clock_id = FWK_ID_NONE_INIT, + }), + }, + [1] = { 0 }, +}; + +static const struct fwk_element *get_pl011_table(fwk_id_t module_id) +{ + return pl011_element_desc_table; +} + +struct fwk_module_config config_pl011 = { + .get_element_table = get_pl011_table, +}; + +/* + * Log module + */ +static const struct mod_log_config log_data = { + .device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PL011, 0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PL011, 0), + .log_groups = MOD_LOG_GROUP_ERROR | + MOD_LOG_GROUP_INFO | + MOD_LOG_GROUP_WARNING | + MOD_LOG_GROUP_DEBUG, + .banner = FWK_BANNER_SCP + FWK_BANNER_ROM_FIRMWARE + BUILD_VERSION_DESCRIBE_STRING "\n", +}; + +struct fwk_module_config config_log = { + .data = &log_data, +}; diff --git a/product/sgi575/scp_romfw/config_sgi575_rom.c b/product/sgi575/scp_romfw/config_sgi575_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..411560ffd16375cf844e3e58a4d0b6bbd64906a9 --- /dev/null +++ b/product/sgi575/scp_romfw/config_sgi575_rom.c @@ -0,0 +1,19 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +const struct fwk_module_config config_sgi575_rom = { + .data = &((struct sgi575_rom_config) { + .ramfw_base = SCP_RAM0_BASE, + .nor_base = SCP_NOR_BASE, + .load_ram_size = SCP_IMAGE_SIZE, + }) +}; diff --git a/product/sgi575/scp_romfw/firmware.mk b/product/sgi575/scp_romfw/firmware.mk new file mode 100644 index 0000000000000000000000000000000000000000..4d8359ce13cbc59c5b5a71646266077899412d24 --- /dev/null +++ b/product/sgi575/scp_romfw/firmware.mk @@ -0,0 +1,28 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_FIRMWARE_CPU := cortex-m7 +BS_FIRMWARE_HAS_MULTITHREADING := no +BS_FIRMWARE_HAS_NOTIFICATION := yes +BS_FIRMWARE_MODULE_HEADERS_ONLY := \ + power_domain \ + timer + +BS_FIRMWARE_MODULES := \ + pl011 \ + clock \ + log \ + sgi575_rom \ + gtimer + +BS_FIRMWARE_SOURCES := \ + config_log.c \ + config_clock.c \ + config_sgi575_rom.c \ + config_gtimer.c + +include $(BS_DIR)/firmware.mk diff --git a/product/sgi575/scp_romfw/fmw_memory.ld.S b/product/sgi575/scp_romfw/fmw_memory.ld.S new file mode 100644 index 0000000000000000000000000000000000000000..fd0bc98829d01ad3f1a3972b2744baf341537253 --- /dev/null +++ b/product/sgi575/scp_romfw/fmw_memory.ld.S @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * ROM firmware memory layout for the linker script. + */ + +#ifndef FMW_MEMORY_LD_S +#define FMW_MEMORY_LD_S + +#include + +#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * ROM memory + */ +#define FIRMWARE_MEM0_SIZE SCP_ROM_SIZE +#define FIRMWARE_MEM0_BASE SCP_ROM_BASE + +/* + * RAM memory + */ +#define FIRMWARE_MEM1_SIZE SCP_RAM1_SIZE +#define FIRMWARE_MEM1_BASE SCP_RAM1_BASE + +#define FIRMWARE_STACK_SIZE (1 * 1024) + +#endif /* FMW_MEMORY_LD_S */ diff --git a/product/sgi575/src/sgi575_core.c b/product/sgi575/src/sgi575_core.c new file mode 100644 index 0000000000000000000000000000000000000000..c1760923fed9f548cc6b68a6310983c584dded5f --- /dev/null +++ b/product/sgi575/src/sgi575_core.c @@ -0,0 +1,31 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* SGI575 only has one configuration, hence the constant values */ + +#define CORES_PER_CLUSTER 4 +#define NUMBER_OF_CLUSTERS 2 + +unsigned int sgi575_core_get_core_per_cluster_count(unsigned int cluster) +{ + assert(cluster < sgi575_core_get_cluster_count()); + + return CORES_PER_CLUSTER; +} + +unsigned int sgi575_core_get_core_count(void) +{ + return NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER; +} + +unsigned int sgi575_core_get_cluster_count(void) +{ + return NUMBER_OF_CLUSTERS; +} diff --git a/product/sgm775/scp_ramfw/config_ddr_phy500.c b/product/sgm775/scp_ramfw/config_ddr_phy500.c index e6d2d7b305ba2d66b6536d680c2b86a508b137fa..a6ad948dee87707df9596c3fbd42e77c4c78340e 100644 --- a/product/sgm775/scp_ramfw/config_ddr_phy500.c +++ b/product/sgm775/scp_ramfw/config_ddr_phy500.c @@ -4,6 +4,8 @@ * * SPDX-License-Identifier: BSD-3-Clause */ + +#include #include #include #include @@ -20,7 +22,7 @@ static const struct mod_ddr_phy500_reg ddr_reg_val = { .T_RDLAT = 0x00000016, .T_WRLAT = 0x01000000, .DFI_WR_PREMBL = 0x00000002, - .LP_ACK = 0x00641300, + .DFI_LP_ACK = 0x00641300, }; /* Table of DDR PHY500 element descriptions. */ @@ -59,5 +61,7 @@ struct fwk_module_config config_ddr_phy500 = { .get_element_table = ddr_phy500_get_element_table, .data = &((struct mod_ddr_phy500_module_config) { .ddr_reg_val = &ddr_reg_val, + .initialize_init_complete = false, + .initialize_ref_en = false, }), }; diff --git a/tools/ci.py b/tools/ci.py index b31a5d3f73321e675ee2477fce1f6dd28dbd06c7..f4381ef392dc704f84bdd1dd14193c9849a7b1a5 100755 --- a/tools/ci.py +++ b/tools/ci.py @@ -87,6 +87,15 @@ def main(): result = subprocess.call(cmd, shell=True) results.append(('Product sgm775 build (GCC)', result)) + banner('Test building sgi575 product') + + cmd = \ + 'CC=arm-none-eabi-gcc CROSS_COMPILE=arm-none-eabi- ' \ + 'PRODUCT=sgi575 ' \ + 'make clean all' + result = subprocess.call(cmd, shell=True) + results.append(('Product sgi575 build (GCC)', result)) + banner('Tests summary') total_success = 0