From d5038a15438aba67f4a6e61acf53e6e70fa8e6e4 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Tue, 21 Apr 2020 11:51:39 +0100 Subject: [PATCH 01/31] module: add support for CMN Booker interconnect Add initial support for CMN Booker interconnect. This include configuring SAM tables, programming the nodes and sufficient support for single chip operation. When compared to other CMN such as CMN Rhodes and CMN600, CMN Booker has support for MTSX node type and enables coherent read/writes through HND node. Change-Id: I3ac4736601d9d79c11ee202e0a35146ba16d1596 Signed-off-by: Usama Arif --- .../include/internal/cmn_booker_ctx.h | 50 ++ module/cmn_booker/include/mod_cmn_booker.h | 141 +++++ module/cmn_booker/src/Makefile | 13 + module/cmn_booker/src/cmn_booker.c | 227 +++++++ module/cmn_booker/src/cmn_booker.h | 428 +++++++++++++ module/cmn_booker/src/mod_cmn_booker.c | 589 ++++++++++++++++++ 6 files changed, 1448 insertions(+) create mode 100644 module/cmn_booker/include/internal/cmn_booker_ctx.h create mode 100644 module/cmn_booker/include/mod_cmn_booker.h create mode 100644 module/cmn_booker/src/Makefile create mode 100644 module/cmn_booker/src/cmn_booker.c create mode 100644 module/cmn_booker/src/cmn_booker.h create mode 100644 module/cmn_booker/src/mod_cmn_booker.c diff --git a/module/cmn_booker/include/internal/cmn_booker_ctx.h b/module/cmn_booker/include/internal/cmn_booker_ctx.h new file mode 100644 index 000000000..18ba5a912 --- /dev/null +++ b/module/cmn_booker/include/internal/cmn_booker_ctx.h @@ -0,0 +1,50 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * CMN_BOOKER Context structure Interface + */ + +#ifndef INTERNAL_CMN_BOOKER_CTX_H +#define INTERNAL_CMN_BOOKER_CTX_H + +#include + +#include + +#include +#include + +static struct cmn_booker_ctx { + const struct mod_cmn_booker_config *config; + + struct cmn_booker_cfgm_reg *root; + + /* Number of HN-F (system cache) nodes in the system */ + unsigned int hnf_count; + uint64_t *hnf_cache_group; + uint64_t *sn_nodeid_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 cmn_booker_rnsam_reg **internal_rnsam_table; + + bool initialized; +} *ctx; + + +#endif /* INTERNAL_CMN600_CTX_H */ diff --git a/module/cmn_booker/include/mod_cmn_booker.h b/module/cmn_booker/include/mod_cmn_booker.h new file mode 100644 index 000000000..7ca0d7915 --- /dev/null +++ b/module/cmn_booker/include/mod_cmn_booker.h @@ -0,0 +1,141 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_CMN_BOOKER_H +#define MOD_CMN_BOOKER_H + +#include + +#include +#include +#include + +/*! + * \addtogroup GroupModules Modules + * @{ + */ + +/*! + * \defgroup GroupModuleCMN_BOOKER CMN_BOOKER + * + * \brief Arm Coherent Mesh Network (CMN) BOOKER module + * + * \details This module adds support for the CMN_BOOKER interconnect + * @{ + */ + +/*! + * \brief Module API indices + */ +enum mod_cmn_booker_api_idx { + /*! Index of the PPU_V1 power state observer API */ + MOD_CMN_BOOKER_API_IDX_PPU_OBSERVER, + + /*! Number of APIs */ + MOD_CMN_BOOKER_API_COUNT +}; + +/*! + * \brief Memory region configuration type + */ +enum mod_cmn_booker_mem_region_type { + /*! Input/Output region (serviced by dedicated HN-I and HN-D nodes) */ + MOD_CMN_BOOKER_MEM_REGION_TYPE_IO, + + /*! + * Region backed by the system cache (serviced by all HN-F nodes in the + * system) + */ + MOD_CMN_BOOKER_MEM_REGION_TYPE_SYSCACHE, + + /*! + * Sub region of the system cache for non-hashed access (serviced by + * dedicated SN-F nodes). + */ + MOD_CMN_BOOKER_REGION_TYPE_SYSCACHE_SUB, +}; + +/*! + * \brief Memory region map descriptor + */ +struct mod_cmn_booker_mem_region_map { + /*! Base address */ + uint64_t base; + + /*! Region size in bytes */ + uint64_t size; + + /*! Region configuration type */ + enum mod_cmn_booker_mem_region_type type; + + /*! + * \brief Target node identifier + * + * \note Not used for \ref + * mod_cmn_booker_mem_region_type. + * MOD_CMN_BOOKER_MEM_REGION_TYPE_SYSCACHE + * memory regions as it uses the pool of HN-F nodes available in the + * system + */ + unsigned int node_id; +}; + +/*! + * \brief CMN_BOOKER configuration data + */ +struct mod_cmn_booker_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_cmn_booker_mem_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; + + /*! + * \brief HN-F with CAL support flag + * \details When set to true, enables HN-F with CAL support. This flag will + * be used only if HN-F is found to be connected to CAL (When connected to + * a CAL port, node id of HN-F will be a odd number). + */ + bool hnf_cal_mode; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_CMN_BOOKER_H */ diff --git a/module/cmn_booker/src/Makefile b/module/cmn_booker/src/Makefile new file mode 100644 index 000000000..2de018a83 --- /dev/null +++ b/module/cmn_booker/src/Makefile @@ -0,0 +1,13 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := CMN_BOOKER + +BS_LIB_SOURCES = mod_cmn_booker.c +BS_LIB_SOURCES += cmn_booker.c + +include $(BS_DIR)/lib.mk diff --git a/module/cmn_booker/src/cmn_booker.c b/module/cmn_booker/src/cmn_booker.c new file mode 100644 index 000000000..2d759ab11 --- /dev/null +++ b/module/cmn_booker/src/cmn_booker.c @@ -0,0 +1,227 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/* + * Encoding bits size of the X and Y position in the Node info value. + * If X and Y dimension are less than 4, encoding bits size will be 2. + * If X and Y dimension are between 5 and 8, encoding bits size will be 3. + */ +static unsigned int encoding_bits; +static unsigned int mask_bits; + +unsigned int get_node_child_count(void *node_base) +{ + struct node_header *node = node_base; + return node->CHILD_INFO & CMN_BOOKER_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 & CMN_BOOKER_NODE_INFO_TYPE); +} + +unsigned int get_node_id(void *node_base) +{ + struct node_header *node = node_base; + return (node->NODE_INFO & CMN_BOOKER_NODE_INFO_ID) >> + CMN_BOOKER_NODE_INFO_ID_POS; +} + +unsigned int get_node_logical_id(void *node_base) +{ + struct node_header *node = node_base; + return (node->NODE_INFO & CMN_BOOKER_NODE_INFO_LOGICAL_ID) >> + CMN_BOOKER_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 & CMN_BOOKER_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 node_id; + + node_pointer = (node->CHILD_POINTER[child_index] & + CMN_BOOKER_CHILD_POINTER_EXT_NODE_POINTER) >> + CMN_BOOKER_CHILD_POINTER_EXT_NODE_POINTER_POS; + + /* + * For mesh widths using 2 bits each for X,Y encoding: + * NodeID[1:0] = DeviceID[3:2] + * NodeID[2] = DeviceID[0] + * NodeID[4:3] = NODE POINTER[7:6] + * NodeID[6:5] = NODE POINTER[9:8] + * + * For mesh widths using 3 bits each for X,Y encoding: + * NodeID[1:0] = DeviceID[3:2] + * NodeID[2] = DeviceID[0] + * NodeID[5:3] = NODE POINTER[8:6] + * NodeID[8:6] = NODE POINTER[11:9] + */ + node_id = (((node_pointer >> 6) & 0xff) << 3) | + ((node_pointer & 0x1) << 2) | + ((node_pointer >> 2) & 0x3); + + return node_id; +} + +bool is_child_external(void *node_base, unsigned int child_index) +{ + struct node_header *node = node_base; + return !!(node->CHILD_POINTER[child_index] & (1U << 31)); +} + +bool get_port_number(unsigned int child_node_id) +{ + return (child_node_id >> CMN_BOOKER_NODE_ID_PORT_POS) & + CMN_BOOKER_NODE_ID_PORT_MASK; +} + +unsigned int get_device_type(void *mxp_base, bool port) +{ + struct cmn_booker_mxp_reg *mxp = mxp_base; + return mxp->PORT_CONNECT_INFO[port] & + CMN_BOOKER_MXP_PORT_CONNECT_INFO_DEVICE_TYPE_MASK; +} + +uint64_t sam_encode_region_size(uint64_t size) +{ + uint64_t blocks; + uint64_t result; + + /* Size must be a multiple of SAM_GRANULARITY */ + fwk_assert((size % SAM_GRANULARITY) == 0); + + /* Size also must be a power of two */ + fwk_assert((size & (size - 1)) == 0); + + blocks = size / SAM_GRANULARITY; + result = fwk_math_log2(blocks); + + return result; +} + +void configure_region(volatile uint64_t *reg, uint64_t base, uint64_t size, + enum sam_node_type node_type) +{ + uint64_t value; + + fwk_assert(reg); + fwk_assert((base % size) == 0); + + value = CMN_BOOKER_RNSAM_REGION_ENTRY_VALID; + value |= node_type << CMN_BOOKER_RNSAM_REGION_ENTRY_TYPE_POS; + value |= sam_encode_region_size(size) << + CMN_BOOKER_RNSAM_REGION_ENTRY_SIZE_POS; + value |= (base / SAM_GRANULARITY) << CMN_BOOKER_RNSAM_REGION_ENTRY_BASE_POS; + + *reg = value; +} + +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_MPAM_S] = "MPAM-S", + [NODE_TYPE_MPAM_NS] = "MPAM-NS", + [NODE_TYPE_RN_I] = "RN-I", + [NODE_TYPE_RN_D] = "RN-D", + [NODE_TYPE_RN_SAM] = "RN-SAM", + [NODE_TYPE_MTU] = "MTU", +}; + +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_MTU) + 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 (get_node_id(node) >> (CMN_BOOKER_NODE_ID_Y_POS + encoding_bits)) & + mask_bits; +} + +unsigned int get_node_pos_y(void *node_base) +{ + struct node_header *node = node_base; + return (get_node_id(node) >> CMN_BOOKER_NODE_ID_Y_POS) & mask_bits; +} + +struct cmn_booker_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 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 CMN_BOOKER 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 >> CMN_BOOKER_NODE_ID_Y_POS) & mask_bits; + node_pos_x = (hnd_node_id >> (CMN_BOOKER_NODE_ID_Y_POS + encoding_bits)) & + mask_bits; + node_port = (hnd_node_id >> CMN_BOOKER_NODE_ID_PORT_POS) & + CMN_BOOKER_NODE_ID_PORT_MASK; + + /* Calculate node address offset */ + offset = (node_pos_y << CMN_BOOKER_ROOT_NODE_OFFSET_Y_POS) | + (node_pos_x << (CMN_BOOKER_ROOT_NODE_OFFSET_Y_POS + + encoding_bits)) | + (node_port << CMN_BOOKER_ROOT_NODE_OFFSET_PORT_POS); + + return (struct cmn_booker_cfgm_reg *)(base + offset); +} diff --git a/module/cmn_booker/src/cmn_booker.h b/module/cmn_booker/src/cmn_booker.h new file mode 100644 index 000000000..03dc288f0 --- /dev/null +++ b/module/cmn_booker/src/cmn_booker.h @@ -0,0 +1,428 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions and utility functions for the CMN BOOKER module. + */ + +#ifndef CMN_BOOKER_H +#define CMN_BOOKER_H + +#include + +#include +#include + +/* Max Node Counts */ +#define MAX_HNF_COUNT 64 +#define MAX_RND_COUNT 32 +#define MAX_RNI_COUNT 32 +#define MAX_RNF_COUNT 64 + +/* Maximum System Cache Group regions supported by CMN-BOOKER */ +#define MAX_SCG_COUNT 4 + +/* SAM Granularity of RN-SAM and HN-F SAM */ +#define SAM_GRANULARITY (64 * FWK_MIB) + +/* Macros to split 64 bit value two 32 bit values */ +#define HIGH_WORD(x) ((unsigned int)((((x) & 0xFFFFFFFF00000000ULL) >> 32))) +#define LOW_WORD(x) ((unsigned int)((x) & 0xFFFFFFFF)) + +/* External nodes that require RN-SAM mapping during run-time */ +struct external_rnsam_tuple { + unsigned int node_id; + struct cmn_booker_rnsam_reg *node; +}; + +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_MPAM_S = 0x8, + NODE_TYPE_MPAM_NS = 0x9, + NODE_TYPE_RN_I = 0xA, + NODE_TYPE_RN_D = 0xD, + NODE_TYPE_RN_SAM = 0xF, + NODE_TYPE_MTU = 0x10, + /* Coherent Multichip Link (CML) node types */ + NODE_TYPE_CML_BASE = 0x100, + NODE_TYPE_CXRA = 0x100, + NODE_TYPE_CXHA = 0x101, + NODE_TYPE_CXLA = 0x102, +}; + +enum device_type { + DEVICE_TYPE_CXHA = 0x11, // 0b10001 + DEVICE_TYPE_CXRA = 0x12, // 0b10010 + DEVICE_TYPE_CXRH = 0x13, // 0b10011 +}; + +/* 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]; +}; + +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 cmn_booker_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[0xC00 - 0x908]; + FWK_RW uint64_t NON_HASH_MEM_REGION[20]; + uint8_t RESERVED3[0xD80 - 0xCA0]; + FWK_RW uint64_t NON_HASH_TGT_NODEID[5]; + uint8_t RESERVED4[0xE00 - 0xDA8]; + FWK_RW uint64_t SYS_CACHE_GRP_REGION[4]; + uint8_t RESERVED5[0xEA0 - 0xE20]; + FWK_RW uint64_t SYS_CACHE_GRP_HN_COUNT; + uint8_t RESERVED6[0xF00 - 0xEA8]; + FWK_RW uint64_t SYS_CACHE_GRP_HN_NODEID[16]; + uint8_t RESERVED7[0x1000 - 0xF80]; + FWK_RW uint64_t SYS_CACHE_GRP_SN_NODEID[16]; + uint8_t RESERVED8[0x1100 - 0x1080]; + FWK_RW uint64_t STATUS; + uint8_t RESERVED9[0x1120 - 0x1108]; + FWK_RW uint64_t SYS_CACHE_GRP_CAL_MODE; +}; + +/* + * Fully Coherent Home Node (HN-F) registers + */ +struct cmn_booker_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[0xD00 - 0x908]; + FWK_RW uint64_t SAM_CONTROL; + FWK_RW uint64_t SAM_MEMREGION[2]; + uint8_t RESERVED8[0x1C00 - 0xD18]; + FWK_RW uint64_t PPU_PWPR; +}; + +/* + * Configuration slave registers + */ +struct cmn_booker_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; +}; + +/* + * Crosspoint (XP) registers + */ +struct cmn_booker_mxp_reg { + FWK_R uint64_t NODE_INFO; + FWK_R uint64_t PORT_CONNECT_INFO[2]; + uint8_t RESERVED0[0x80 - 0x18]; + FWK_R uint64_t CHILD_INFO; + uint8_t RESERVED1[0x100 - 0x88]; + FWK_R uint64_t CHILD_POINTER[16]; +}; + +/* + * Home Node I/O (HN-I) registers + */ +struct cmn_booker_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 CMN_BOOKER_NODE_INFO_TYPE UINT64_C(0x000000000000FFFF) +#define CMN_BOOKER_NODE_INFO_ID UINT64_C(0x00000000FFFF0000) +#define CMN_BOOKER_NODE_INFO_ID_POS 16 +#define CMN_BOOKER_NODE_INFO_LOGICAL_ID UINT64_C(0x0000FFFF00000000) +#define CMN_BOOKER_NODE_INFO_LOGICAL_ID_POS 32 + +#define CMN_BOOKER_CHILD_INFO_COUNT UINT64_C(0x000000000000FFFF) + +#define CMN_BOOKER_CHILD_POINTER_OFFSET UINT64_C(0x000000000FFFFFFF) +#define CMN_BOOKER_CHILD_POINTER_EXT UINT64_C(0x0000000080000000) + +/* External child node */ +#define CMN_BOOKER_CHILD_POINTER_EXT_REGISTER_OFFSET UINT64_C(0x00003FFF) +#define CMN_BOOKER_CHILD_POINTER_EXT_NODE_POINTER UINT64_C(0x0FFFC000) +#define CMN_BOOKER_CHILD_POINTER_EXT_NODE_POINTER_POS 14 + +/* Used by NON_HASH_MEM_REGIONx and SYS_CACHE_GRP_REGIONx group registers */ +#define CMN_BOOKER_RNSAM_REGION_ENTRY_TYPE_POS 2 +#define CMN_BOOKER_RNSAM_REGION_ENTRY_SIZE_POS 56 +#define CMN_BOOKER_RNSAM_REGION_ENTRY_BASE_POS 26 +#define CMN_BOOKER_RNSAM_REGION_ENTRY_BITS_WIDTH 64 +#define CMN_BOOKER_RNSAM_REGION_ENTRY_VALID UINT64_C(0x0000000000000001) +#define CMN_BOOKER_RNSAM_REGION_ENTRIES_PER_GROUP 1 +#define CMN_BOOKER_RNSAM_SYS_CACHE_GRP_SN_NODEID_ENTRIES_PER_GROUP 4 +#define CMN_BOOKER_RNSAM_SCG_HNF_CAL_MODE_EN UINT64_C(0x01) +#define CMN_BOOKER_RNSAM_SCG_HNF_CAL_MODE_SHIFT 16 + +#define CMN_BOOKER_RNSAM_STATUS_UNSTALL UINT64_C(0x0000000000000002) +#define CMN_BOOKER_RNSAM_STATUS_DEFAULT_NODEID_POS 48 + +#define CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRY_BITS_WIDTH 12 +#define CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK UINT64_C(0xFFF) +#define CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP 4 + +#define CMN_BOOKER_HNF_SAM_MEMREGION_SIZE_POS 12 +#define CMN_BOOKER_HNF_SAM_MEMREGION_BASE_POS 26 +#define CMN_BOOKER_HNF_SAM_MEMREGION_VALID UINT64_C(0x8000000000000000) + +#define CMN_BOOKER_HNF_CACHE_GROUP_ENTRIES_MAX 64 +#define CMN_BOOKER_HNF_CACHE_GROUP_ENTRIES_PER_GROUP 4 +#define CMN_BOOKER_HNF_CACHE_GROUP_ENTRY_BITS_WIDTH 12 + +#define CMN_BOOKER_PPU_PWPR_POLICY_OFF UINT64_C(0x0000000000000000) +#define CMN_BOOKER_PPU_PWPR_POLICY_MEM_RET UINT64_C(0x0000000000000002) +#define CMN_BOOKER_PPU_PWPR_POLICY_FUNC_RET UINT64_C(0x000000000000007) +#define CMN_BOOKER_PPU_PWPR_POLICY_ON UINT64_C(0x0000000000000008) +#define CMN_BOOKER_PPU_PWPR_OPMODE_NOSFSLC UINT64_C(0x0000000000000000) +#define CMN_BOOKER_PPU_PWPR_OPMODE_SFONLY UINT64_C(0x0000000000000010) +#define CMN_BOOKER_PPU_PWPR_OPMODE_HAM UINT64_C(0x0000000000000020) +#define CMN_BOOKER_PPU_PWPR_OPMODE_FAM UINT64_C(0x0000000000000030) +#define CMN_BOOKER_PPU_PWPR_DYN_EN UINT64_C(0x0000000000000100) + +/* Mesh and Node ID mapping */ +#define CMN_BOOKER_MESH_X_MAX 8 +#define CMN_BOOKER_MESH_Y_MAX 8 + +#define CMN_BOOKER_NODE_ID_PORT_POS 1 +#define CMN_BOOKER_NODE_ID_PORT_MASK 0x3 +#define CMN_BOOKER_NODE_ID_Y_POS 3 + +#define CMN_BOOKER_MXP_PORT_CONNECT_INFO_DEVICE_TYPE_MASK UINT64_C(0x1F) + +#define CMN_BOOKER_ROOT_NODE_OFFSET_PORT_POS 16 +#define CMN_BOOKER_ROOT_NODE_OFFSET_Y_POS 22 + +/* + * 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 CMN BOOKER 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); + +/* + * Returns the port number from the child node id. + * + * \param child_node_id Child node id calculated from the child pointer. + * + * \retval port number (either 0 or 1). + */ +bool get_port_number(unsigned int child_node_id); + +/* + * Returns the device type from the MXP's port connect info register. + * + * \param mxp_base Pointer to the cross point node descriptor + * \pre The cross point node pointer must be valid + * \param port Port number + * \pre The port number should be either 0 or 1. + * + * \retval device type (por_mxp_por_mxp_device_port_connect_info_p[port] & 0x1F) + */ +unsigned int get_device_type(void *mxp_base, bool port); + +/* + * Convert a memory region size into a size format used by the CMN BOOKER + * registers. The format is the binary logarithm of the memory region size + * represented as blocks multiple of the CMN BOOKER'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 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, 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 CMN BOOKER 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 cmn_booker_cfgm_reg *get_root_node(uintptr_t base, + unsigned int hnd_node_id, unsigned int mesh_size_x, + unsigned int mesh_size_y); + +#endif /* CMN_BOOKER_H */ diff --git a/module/cmn_booker/src/mod_cmn_booker.c b/module/cmn_booker/src/mod_cmn_booker.c new file mode 100644 index 000000000..942986081 --- /dev/null +++ b/module/cmn_booker/src/mod_cmn_booker.c @@ -0,0 +1,589 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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 + +#define MOD_NAME "[CMN_BOOKER] " + +static struct cmn_booker_ctx *ctx; + +static void process_node_hnf(struct cmn_booker_hnf_reg *hnf) +{ + unsigned int bit_pos; + unsigned int group; + unsigned int logical_id; + unsigned int node_id; + unsigned int region_idx; + unsigned int region_sub_count = 0; + static unsigned int cal_mode_factor = 1; + const struct mod_cmn_booker_mem_region_map *region; + const struct mod_cmn_booker_config *config = ctx->config; + + logical_id = get_node_logical_id(hnf); + node_id = get_node_id(hnf); + + /* + * If CAL mode is set, only even numbered hnf node should be added to the + * sys_cache_grp_hn_nodeid registers. + */ + if (config->hnf_cal_mode == true && (node_id % 2 == 1)) { + /* Factor to manipulate the group and bit_pos */ + cal_mode_factor = 2; + } + + assert(logical_id < config->snf_count); + + group = logical_id / + (CMN_BOOKER_HNF_CACHE_GROUP_ENTRIES_PER_GROUP * cal_mode_factor); + bit_pos = (CMN_BOOKER_HNF_CACHE_GROUP_ENTRY_BITS_WIDTH / cal_mode_factor) * + ((logical_id % + (CMN_BOOKER_HNF_CACHE_GROUP_ENTRIES_PER_GROUP * + cal_mode_factor))); + + /* + * If CAL mode is set, add only even numbered hnd node to + * sys_cache_grp_hn_nodeid registers + */ + if (config->hnf_cal_mode == true) { + if (node_id % 2 == 0) { + ctx->hnf_cache_group[group] += ((uint64_t)get_node_id(hnf)) << + bit_pos; + ctx->sn_nodeid_group[group] += + ((uint64_t)config->snf_table[logical_id]) << bit_pos; + } + } else { + ctx->hnf_cache_group[group] += ((uint64_t)get_node_id(hnf)) << bit_pos; + ctx->sn_nodeid_group[group] += + ((uint64_t)config->snf_table[logical_id]) << 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_CMN_BOOKER_REGION_TYPE_SYSCACHE_SUB) + continue; + + /* Configure sub-region entry */ + hnf->SAM_MEMREGION[region_sub_count] = region->node_id | + (sam_encode_region_size(region->size) << + CMN_BOOKER_HNF_SAM_MEMREGION_SIZE_POS) | + ((region->base / SAM_GRANULARITY) << + CMN_BOOKER_HNF_SAM_MEMREGION_BASE_POS) | + CMN_BOOKER_HNF_SAM_MEMREGION_VALID; + + region_sub_count++; + } + + /* Configure the system cache RAM PPU */ + hnf->PPU_PWPR = CMN_BOOKER_PPU_PWPR_POLICY_ON | + CMN_BOOKER_PPU_PWPR_OPMODE_FAM | + CMN_BOOKER_PPU_PWPR_DYN_EN; +} + +/* + * Discover the topology of the interconnect and identify the number of: + * - External RN-SAM nodes + * - Internal RN-SAM nodes + * - HN-F nodes (cache) + */ +static int cmn_booker_discovery(void) +{ + unsigned int xp_count; + unsigned int xp_idx; + unsigned int node_count; + unsigned int node_idx; + bool xp_port; + struct cmn_booker_mxp_reg *xp; + struct node_header *node; + const struct mod_cmn_booker_config *config = ctx->config; + + FWK_LOG_INFO(MOD_NAME "Starting discovery..."); + + 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); + + FWK_LOG_INFO( + MOD_NAME "XP (%d, %d) ID:%d, LID:%d", + 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); + if (is_child_external(xp, node_idx)) { /* External nodes */ + xp_port = get_port_number(get_child_node_id(xp, node_idx)); + + /* + * If the device type is CXRH, CXHA, or CXRA, then the external + * child node is CXLA as every CXRH, CXHA, or CXRA node has a + * corresponding external CXLA node. + */ + if ((get_device_type(xp, xp_port) == DEVICE_TYPE_CXRH) || + (get_device_type(xp, xp_port) == DEVICE_TYPE_CXHA) || + (get_device_type(xp, xp_port) == DEVICE_TYPE_CXRA)) { + FWK_LOG_INFO( + MOD_NAME " Found CXLA at node ID: %d", + get_child_node_id(xp, node_idx)); + } else { /* External RN-SAM Node */ + ctx->external_rnsam_count++; + FWK_LOG_INFO( + MOD_NAME " Found external node ID: %d", + get_child_node_id(xp, node_idx)); + } + } else { /* Internal nodes */ + switch (get_node_type(node)) { + case NODE_TYPE_HN_F: + if (ctx->hnf_count >= MAX_HNF_COUNT) { + FWK_LOG_INFO( + MOD_NAME " hnf count %d >= max limit (%d)", + ctx->hnf_count, + MAX_HNF_COUNT); + return FWK_E_DATA; + } + ctx->hnf_count++; + break; + + case NODE_TYPE_RN_SAM: + ctx->internal_rnsam_count++; + break; + + default: + /* Nothing to be done for other node types */ + break; + } + + FWK_LOG_INFO( + MOD_NAME " %s ID:%d, LID:%d", + get_node_type_name(get_node_type(node)), + get_node_id(node), + get_node_logical_id(node)); + } + } + } + + /* When CAL is present, the number of HN-Fs must be even. */ + if ((ctx->hnf_count % 2 != 0) && (config->hnf_cal_mode == true)) { + FWK_LOG_ERR( + MOD_NAME "hnf count: %d should be even when CAL mode is set", + ctx->hnf_count); + return FWK_E_DATA; + } + + FWK_LOG_INFO(MOD_NAME + "Total internal RN-SAM nodes: %d", ctx->internal_rnsam_count); + FWK_LOG_INFO(MOD_NAME + "Total external RN-SAM nodes: %d", ctx->external_rnsam_count); + FWK_LOG_INFO(MOD_NAME + "Total HN-F nodes: %d", ctx->hnf_count); + + return FWK_SUCCESS; +} + +static void cmn_booker_configure(void) +{ + unsigned int node_count; + unsigned int node_idx; + unsigned int xp_count; + unsigned int xp_idx; + unsigned int xrnsam_entry; + unsigned int irnsam_entry; + bool xp_port; + void *node; + struct cmn_booker_mxp_reg *xp; + const struct mod_cmn_booker_config *config = ctx->config; + + assert(get_node_type(ctx->root) == NODE_TYPE_CFG); + + xrnsam_entry = 0; + irnsam_entry = 0; + + /* 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)) { + unsigned int node_id = get_child_node_id(xp, node_idx); + xp_port = get_port_number(get_child_node_id(xp, node_idx)); + + /* Skip if the device type is CXG */ + if ((get_device_type(xp, xp_port) == DEVICE_TYPE_CXRH) || + (get_device_type(xp, xp_port) == DEVICE_TYPE_CXHA) || + (get_device_type(xp, xp_port) == DEVICE_TYPE_CXRA)) + continue; + + fwk_assert(xrnsam_entry < ctx->external_rnsam_count); + + ctx->external_rnsam_table[xrnsam_entry].node_id = node_id; + ctx->external_rnsam_table[xrnsam_entry].node = node; + + xrnsam_entry++; + } else { + enum node_type node_type = get_node_type(node); + + if (node_type == NODE_TYPE_RN_SAM) { + fwk_assert(irnsam_entry < ctx->internal_rnsam_count); + + ctx->internal_rnsam_table[irnsam_entry] = node; + + irnsam_entry++; + } else if (node_type == NODE_TYPE_HN_F) { + process_node_hnf(node); + } else if (node_type == NODE_TYPE_HN_I) { + /* + Disable sending of NDE response error to RN and logging of + error information forthe following requests: + 1. Coherent Read + 2. CleanUnique/MakeUnique + 3. Coherent/CopyBack Write + This enables coherent access through HNI. + */ + struct cmn_booker_hni_reg* hni_node = + (struct cmn_booker_hni_reg*) node; + hni_node->CFG_CTL &= ~1; + } + } + } + } +} + +static const char * const mmap_type_name[] = { + [MOD_CMN_BOOKER_MEM_REGION_TYPE_IO] = "I/O", + [MOD_CMN_BOOKER_MEM_REGION_TYPE_SYSCACHE] = "System Cache", + [MOD_CMN_BOOKER_REGION_TYPE_SYSCACHE_SUB] = "Sub-System Cache", +}; + +static int cmn_booker_setup_sam(struct cmn_booker_rnsam_reg *rnsam) +{ + unsigned int bit_pos; + unsigned int group; + unsigned int group_count; + unsigned int hnf_count; + unsigned int region_idx; + unsigned int region_io_count = 0; + unsigned int region_sys_count = 0; + unsigned int scg_regions_enabled[MAX_SCG_COUNT] = {0, 0, 0, 0}; + const struct mod_cmn_booker_mem_region_map *region; + const struct mod_cmn_booker_config *config = ctx->config; + + FWK_LOG_INFO(MOD_NAME "Configuring SAM for node %d", get_node_id(rnsam)); + + for (region_idx = 0; region_idx < config->mmap_count; region_idx++) { + region = &config->mmap_table[region_idx]; + + FWK_LOG_INFO( + MOD_NAME " [0x%x%x - 0x%x%x] %s", + HIGH_WORD(region->base), LOW_WORD(region->base), + HIGH_WORD(region->base + region->size - 1), + LOW_WORD(region->base + region->size - 1), + mmap_type_name[region->type]); + + switch (region->type) { + case MOD_CMN_BOOKER_MEM_REGION_TYPE_IO: + /* + * Configure memory region + */ + configure_region(&rnsam->NON_HASH_MEM_REGION[region_io_count], + region->base, + region->size, + SAM_NODE_TYPE_HN_I); + + /* + * Configure target node + */ + group = region_io_count / + CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP; + bit_pos = CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRY_BITS_WIDTH * + (region_io_count % + CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRIES_PER_GROUP); + + rnsam->NON_HASH_TGT_NODEID[group] &= + ~(CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK << bit_pos); + rnsam->NON_HASH_TGT_NODEID[group] |= + (region->node_id & + CMN_BOOKER_RNSAM_NON_HASH_TGT_NODEID_ENTRY_MASK) << bit_pos; + + region_io_count++; + break; + + case MOD_CMN_BOOKER_MEM_REGION_TYPE_SYSCACHE: + /* + * Configure memory region + */ + configure_region(&rnsam->SYS_CACHE_GRP_REGION[region_sys_count], + region->base, + region->size, + SAM_NODE_TYPE_HN_F); + + /* Mark corresponding region as enabled */ + fwk_assert(region_sys_count < MAX_SCG_COUNT); + scg_regions_enabled[region_sys_count] = 1; + + region_sys_count++; + break; + + case MOD_CMN_BOOKER_REGION_TYPE_SYSCACHE_SUB: + /* Do nothing. System cache sub-regions are handled by HN-Fs */ + break; + + default: + assert(false); + return FWK_E_DATA; + } + } + + /* + * If CAL mode is enabled, then only the even numbered HN-F nodes are + * programmed to the SYS_CACHE registers. Hence reduce the HN-F count by + * half if CAL mode is enabled. + */ + if (config->hnf_cal_mode) + hnf_count = ctx->hnf_count/2; + else + hnf_count = ctx->hnf_count; + + group_count = hnf_count / CMN_BOOKER_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 = hnf_count; + + /* + * If CAL mode is enabled by the configuration program the SCG CAL Mode + * enable register. + */ + if (config->hnf_cal_mode) + for (region_idx = 0; region_idx < MAX_SCG_COUNT; region_idx++) + rnsam->SYS_CACHE_GRP_CAL_MODE |= scg_regions_enabled[region_idx] * + (CMN_BOOKER_RNSAM_SCG_HNF_CAL_MODE_EN << + (region_idx * CMN_BOOKER_RNSAM_SCG_HNF_CAL_MODE_SHIFT)); + + /* Program the SYS_CACHE_GRP_SN_NODEID register for PrefetchTgt */ + if (config->hnf_cal_mode) + group_count = config->snf_count/ + (CMN_BOOKER_RNSAM_SYS_CACHE_GRP_SN_NODEID_ENTRIES_PER_GROUP * 2); + else + group_count = config->snf_count/ + CMN_BOOKER_RNSAM_SYS_CACHE_GRP_SN_NODEID_ENTRIES_PER_GROUP; + + for (group = 0; group <= group_count; group++) + rnsam->SYS_CACHE_GRP_SN_NODEID[group] = ctx->sn_nodeid_group[group]; + + /* Enable RNSAM */ + rnsam->STATUS = ((uint64_t)config->hnd_node_id << + CMN_BOOKER_RNSAM_STATUS_DEFAULT_NODEID_POS) | + CMN_BOOKER_RNSAM_STATUS_UNSTALL; + __sync_synchronize(); + + return FWK_SUCCESS; +} + +static int cmn_booker_setup(void) +{ + unsigned int rnsam_idx; + int status = FWK_SUCCESS; + + if (!ctx->initialized) { + status = cmn_booker_discovery(); + if (status != FWK_SUCCESS) + return FWK_SUCCESS; + + /* + * 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)); + } + + /* 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)); + } + + /* 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 / CMN_BOOKER_HNF_CACHE_GROUP_ENTRIES_PER_GROUP, + sizeof(*ctx->hnf_cache_group)); + ctx->sn_nodeid_group = fwk_mm_calloc( + ctx->hnf_count / + CMN_BOOKER_RNSAM_SYS_CACHE_GRP_SN_NODEID_ENTRIES_PER_GROUP, + sizeof(*ctx->sn_nodeid_group)); + } + } + + cmn_booker_configure(); + + /* Setup internal RN-SAM nodes */ + for (rnsam_idx = 0; rnsam_idx < ctx->internal_rnsam_count; rnsam_idx++) + cmn_booker_setup_sam(ctx->internal_rnsam_table[rnsam_idx]); + + FWK_LOG_INFO(MOD_NAME "Done"); + + ctx->initialized = true; + + return FWK_SUCCESS; +} + +static int cmn_booker_setup_rnsam(unsigned int node_id) +{ + unsigned int node_idx; + + for (node_idx = 0; node_idx < ctx->external_rnsam_count; node_idx++) { + if (ctx->external_rnsam_table[node_idx].node_id == node_id) { + cmn_booker_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); + cmn_booker_setup_rnsam(*(unsigned int *)data); +} + +static const struct mod_ppu_v1_power_state_observer_api +cmn_booker_observer_api = { + .post_ppu_on = post_ppu_on, +}; + +/* + * Framework handlers + */ + +static int cmn_booker_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + const struct mod_cmn_booker_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 (config->base == 0) + return FWK_E_DATA; + + if ((config->mesh_size_x == 0) || + (config->mesh_size_x > CMN_BOOKER_MESH_X_MAX)) + return FWK_E_DATA; + + if ((config->mesh_size_y == 0) || + (config->mesh_size_y > CMN_BOOKER_MESH_Y_MAX)) + return FWK_E_DATA; + + if (config->snf_count > CMN_BOOKER_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 cmn_booker_process_bind_request(fwk_id_t requester_id, + fwk_id_t target_id, fwk_id_t api_id, const void **api) +{ + *api = &cmn_booker_observer_api; + return FWK_SUCCESS; +} + +int cmn_booker_start(fwk_id_t id) +{ + if (fwk_id_is_equal(ctx->config->clock_id, FWK_ID_NONE)) { + cmn_booker_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 cmn_booker_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) + cmn_booker_setup(); + + return FWK_SUCCESS; +} + +const struct fwk_module module_cmn_booker = { + .name = "CMN_BOOKER", + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = MOD_CMN_BOOKER_API_COUNT, + .init = cmn_booker_init, + .start = cmn_booker_start, + .process_bind_request = cmn_booker_process_bind_request, + .process_notification = cmn_booker_process_notification, +}; -- GitLab From b6b03ceefd51d0568961fef42f19ad10d5f4c08e Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 15:56:53 +0100 Subject: [PATCH 02/31] product/tc0: add configuration data for pl011 UART module pl011 controller is used as a console port for debug and log messages. Add configuration data of this controller including base address and input clock frequency for the pl011 module to use. Change-Id: Ifa777deaaa6661a3ac706d07de5751fc98d7c017 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 15 ++++++++++++ product/tc0/include/scp_mmap.h | 13 ++++++++++ product/tc0/src/config_pl011.c | 38 ++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 product/tc0/include/scp_css_mmap.h create mode 100644 product/tc0/include/scp_mmap.h create mode 100644 product/tc0/src/config_pl011.c diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h new file mode 100644 index 000000000..3fc6fd060 --- /dev/null +++ b/product/tc0/include/scp_css_mmap.h @@ -0,0 +1,15 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_CSS_MMAP_H +#define SCP_CSS_MMAP_H + +#include "scp_mmap.h" + +#define SCP_UART_BASE (SCP_PERIPHERAL_BASE + 0x2000) + +#endif /* SCP_CSS_MMAP_H */ diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h new file mode 100644 index 000000000..9795ed49d --- /dev/null +++ b/product/tc0/include/scp_mmap.h @@ -0,0 +1,13 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_MMAP_H +#define SCP_MMAP_H + +#define SCP_PERIPHERAL_BASE 0x44000000 + +#endif /* SCP_MMAP_H */ diff --git a/product/tc0/src/config_pl011.c b/product/tc0/src/config_pl011.c new file mode 100644 index 000000000..07192a92c --- /dev/null +++ b/product/tc0/src/config_pl011.c @@ -0,0 +1,38 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_css_mmap.h" + +#include + +#include +#include +#include +#include + +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, + .pd_id = FWK_ID_NONE_INIT, + }), + }, + [1] = { 0 }, +}; + +static const struct fwk_element *get_pl011_table(fwk_id_t id) +{ + return pl011_element_desc_table; +} + +const struct fwk_module_config config_pl011 = { + .get_element_table = get_pl011_table, +}; -- GitLab From b30737bc473acb516acfe1e220bfb595163712fd Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 15:59:53 +0100 Subject: [PATCH 03/31] product/tc0: add configuration data for log module Provide the configuration data for the log module that includes the details of the console to use to display the log messages and the type of log messages that are allowed to be displayed. Change-Id: Ie39203c0ab07558770ed58deed52120028887c42 Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/config_log.c | 25 +++++++++++++++++++++++++ product/tc0/scp_romfw/config_log.c | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_log.c create mode 100644 product/tc0/scp_romfw/config_log.c diff --git a/product/tc0/scp_ramfw/config_log.c b/product/tc0/scp_ramfw/config_log.c new file mode 100644 index 000000000..9f5ce961a --- /dev/null +++ b/product/tc0/scp_ramfw/config_log.c @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +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), + .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/tc0/scp_romfw/config_log.c b/product/tc0/scp_romfw/config_log.c new file mode 100644 index 000000000..ebb6acb0e --- /dev/null +++ b/product/tc0/scp_romfw/config_log.c @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +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), + .banner = FWK_BANNER_SCP + FWK_BANNER_ROM_FIRMWARE + BUILD_VERSION_DESCRIBE_STRING "\n", +}; + +struct fwk_module_config config_log = { + .data = &log_data, +}; -- GitLab From 08629aad3b6045096edb15c0ceb61ff819dd5ea7 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:11:47 +0100 Subject: [PATCH 04/31] product/tc0: add helper functions to obtain platform topology Functions to obtain the platform topology information such as core count, cluster count help in adding configuration data dynamically and can be used by modules to add the configuration data dynamically. Change-Id: I1bf9e83bb0fc04ac0cca19d8934bf2d873fb0a45 Signed-off-by: Usama Arif --- product/tc0/include/tc0_core.h | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 product/tc0/include/tc0_core.h diff --git a/product/tc0/include/tc0_core.h b/product/tc0/include/tc0_core.h new file mode 100644 index 000000000..508e38834 --- /dev/null +++ b/product/tc0/include/tc0_core.h @@ -0,0 +1,37 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TC0_CORE_H +#define TC0_CORE_H + +#include + +#define TC0_CORE_PER_CLUSTER_MAX 4 + +#define CORES_PER_CLUSTER 4 +#define NUMBER_OF_CLUSTERS 1 + +static inline unsigned int tc0_core_get_cluster_count(void) +{ + return NUMBER_OF_CLUSTERS; +} + +static inline unsigned int tc0_core_get_core_per_cluster_count( + unsigned int cluster) +{ + fwk_assert(cluster < tc0_core_get_cluster_count()); + + return CORES_PER_CLUSTER; +} + +static inline unsigned int tc0_core_get_core_count(void) +{ + return tc0_core_get_core_per_cluster_count(0) * + tc0_core_get_cluster_count(); +} + +#endif /* TC0_CORE_H */ -- GitLab From 0c4405a77b3d9fa546339401c83cbd2e1706958d Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:20:47 +0100 Subject: [PATCH 05/31] product/tc0: add SCP PIK register space declaration SCP PIK includes registers for various system configuration and status. SCP PIK is first one to come out of reset and it generates all the reset conrols for SCP. Add the register space declaration for SCP PIK and the subsequent base address from element management peripheral space. Change-Id: I5a33ea0d7d5f5b2409bc1dd1251e8706658df951 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 1 + product/tc0/include/scp_mmap.h | 1 + product/tc0/include/scp_pik.h | 106 +++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 product/tc0/include/scp_pik.h diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index 3fc6fd060..530ce1916 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -11,5 +11,6 @@ #include "scp_mmap.h" #define SCP_UART_BASE (SCP_PERIPHERAL_BASE + 0x2000) +#define SCP_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) #endif /* SCP_CSS_MMAP_H */ diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 9795ed49d..29ed6b62d 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -9,5 +9,6 @@ #define SCP_MMAP_H #define SCP_PERIPHERAL_BASE 0x44000000 +#define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 #endif /* SCP_MMAP_H */ diff --git a/product/tc0/include/scp_pik.h b/product/tc0/include/scp_pik.h new file mode 100644 index 000000000..9ce9d6f8a --- /dev/null +++ b/product/tc0/include/scp_pik.h @@ -0,0 +1,106 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP PIK registers + */ + +#ifndef SCP_PIK_H +#define SCP_PIK_H + +#include "scp_css_mmap.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[0x830 - 0x828]; + FWK_RW uint32_t GTSYNCCLK_CTRL; + FWK_RW uint32_t GTSYNCCLK_DIV1; + uint8_t RESERVED8[0xA10 - 0x838]; + FWK_R uint32_t PLL_STATUS[17]; + uint8_t RESERVED9[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 RESERVED10[0xB00 - 0xA78]; + FWK_R uint32_t MHU_NS_INT_STATUS; + FWK_R uint32_t MHU_S_INT_STATUS; + uint8_t RESERVED11[0xB20 - 0xB08]; + FWK_R uint32_t CPU_PPU_INT_STATUS[8]; + FWK_R uint32_t CLUS_PPU_INT_STATUS; + uint8_t RESERVED12[0xB60 - 0xB44]; + FWK_R uint32_t TIMER_INT_STATUS[8]; + FWK_R uint32_t CPU_PLL_LOCK_STATUS[8]; + uint8_t RESERVED13[0xBC0 - 0xBA0]; + FWK_R uint32_t CPU_PLL_UNLOCK_STATUS[8]; + uint8_t RESERVED14[0xBF0 - 0xBE0]; + FWK_R uint32_t CLUSTER_PLL_LOCK_STATUS; + FWK_R uint32_t CLUSTER_PLL_UNLOCK_STATUS; + uint8_t RESERVED15[0xC00 - 0xBF8]; + FWK_R uint32_t CLUS_FAULT_INT_STATUS; + uint8_t RESERVED16[0xC30 - 0xC04]; + FWK_R uint32_t CLUSTER_ECCERR_INT_STATUS; + uint8_t RESERVED17[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 RESERVED18[0xFC0 - 0xD10]; + FWK_R uint32_t PCL_CFG; + uint8_t RESERVED19[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))) + +/* Pointer to SCP PIK */ +#define SCP_PIK_PTR ((struct pik_scp_reg *) SCP_PIK_SCP_BASE) + +#endif /* SCP_PIK_H */ -- GitLab From e2aba6076aa9c232b7cdc9687722cdb296acfcfa Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:23:25 +0100 Subject: [PATCH 06/31] product/tc0: add CPU PIK register space declaration CPU PIK includes registers for configuration and clock control for AP cores. Add the register space declaration and the base address macro for the CPU PIK. Change-Id: I756be250c98258d98227d9c0c99dfa440ffb7ff8 Signed-off-by: Usama Arif --- product/tc0/include/cpu_pik.h | 91 ++++++++++++++++++++++++++++++ product/tc0/include/scp_css_mmap.h | 3 + 2 files changed, 94 insertions(+) create mode 100644 product/tc0/include/cpu_pik.h diff --git a/product/tc0/include/cpu_pik.h b/product/tc0/include/cpu_pik.h new file mode 100644 index 000000000..5ec664569 --- /dev/null +++ b/product/tc0/include/cpu_pik.h @@ -0,0 +1,91 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CPU_PIK_H +#define CPU_PIK_H + +#include "scp_css_mmap.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 CLUSTER_PIK_PTR(IDX) ((struct pik_cpu_reg *) SCP_PIK_CLUSTER_BASE(IDX)) + +#endif /* CPU_PIK_H */ diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index 530ce1916..2d47db79d 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -11,6 +11,9 @@ #include "scp_mmap.h" #define SCP_UART_BASE (SCP_PERIPHERAL_BASE + 0x2000) + #define SCP_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) +#define SCP_PIK_CLUSTER_BASE(n) ((SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + + 0x60000) + ((n) * 0x20000)) #endif /* SCP_CSS_MMAP_H */ -- GitLab From 755e2ce37c5140e66594e675a00dd091e465539e Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:30:42 +0100 Subject: [PATCH 07/31] product/tc0: add System PIK register space declaration System PIK includes registers for clock control of System PPU and CMN Booker Interconnect. Add the register space declaration and base address from element management peripheral space. Change-Id: If99fe77240e04c4064dd26cae3802ca90c609f35 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 2 + product/tc0/include/system_pik.h | 79 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 product/tc0/include/system_pik.h diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index 2d47db79d..c736cf3dc 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -15,5 +15,7 @@ #define SCP_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) #define SCP_PIK_CLUSTER_BASE(n) ((SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + 0x60000) + ((n) * 0x20000)) +#define SCP_PIK_SYSTEM_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + + 0x40000) #endif /* SCP_CSS_MMAP_H */ diff --git a/product/tc0/include/system_pik.h b/product/tc0/include/system_pik.h new file mode 100644 index 000000000..d83bd1de7 --- /dev/null +++ b/product/tc0/include/system_pik.h @@ -0,0 +1,79 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SYSTEM_PIK_H +#define SYSTEM_PIK_H + +#include "scp_css_mmap.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; +}; + +#define SYSTEM_PIK_PTR ((struct pik_system_reg *) SCP_PIK_SYSTEM_BASE) + +#endif /* SYSTEM_PIK_H */ -- GitLab From 69479e557653afeaa81cf87cf2ab2c122202c867 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:50:42 +0100 Subject: [PATCH 08/31] product/tc0: add configuration data for system PLL driver Add the base address of the control registers and the initial rates for the PLL hardware in Total Compute. Change-Id: I48bf5b171b7445ce523c662172fc6feb334b76cf Signed-off-by: Usama Arif --- product/tc0/include/clock_soc.h | 23 ++++++++ product/tc0/include/scp_mmap.h | 1 + product/tc0/include/scp_soc_mmap.h | 23 ++++++++ product/tc0/scp_ramfw/config_system_pll.c | 67 +++++++++++++++++++++++ product/tc0/scp_romfw/config_system_pll.c | 67 +++++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 product/tc0/include/clock_soc.h create mode 100644 product/tc0/include/scp_soc_mmap.h create mode 100644 product/tc0/scp_ramfw/config_system_pll.c create mode 100644 product/tc0/scp_romfw/config_system_pll.c diff --git a/product/tc0/include/clock_soc.h b/product/tc0/include/clock_soc.h new file mode 100644 index 000000000..d0c9150fa --- /dev/null +++ b/product/tc0/include/clock_soc.h @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CLOCK_SOC_H +#define CLOCK_SOC_H + +#include + +/* + * PLL clock indexes. + */ +enum clock_pll_idx { + CLOCK_PLL_IDX_CPU0, + CLOCK_PLL_IDX_SYS, + CLOCK_PLL_IDX_INTERCONNECT, + CLOCK_PLL_IDX_COUNT +}; + +#endif /* CLOCK_SOC_H */ diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 29ed6b62d..03d7b6829 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -8,6 +8,7 @@ #ifndef SCP_MMAP_H #define SCP_MMAP_H +#define SCP_SOC_EXPANSION3_BASE 0x40000000 #define SCP_PERIPHERAL_BASE 0x44000000 #define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 diff --git a/product/tc0/include/scp_soc_mmap.h b/product/tc0/include/scp_soc_mmap.h new file mode 100644 index 000000000..9cf53d538 --- /dev/null +++ b/product/tc0/include/scp_soc_mmap.h @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SOC_MMAP_H +#define SCP_SOC_MMAP_H + +#include "scp_mmap.h" + +#define SCP_PLL_BASE (SCP_SOC_EXPANSION3_BASE + 0x03000000) + +#define SCP_PLL_SYSPLL (SCP_PLL_BASE + 0x00000000) +#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) + +#endif /* SCP_SOC_MMAP_H */ diff --git a/product/tc0/scp_ramfw/config_system_pll.c b/product/tc0/scp_ramfw/config_system_pll.c new file mode 100644 index 000000000..c9a8408f2 --- /dev/null +++ b/product/tc0/scp_ramfw/config_system_pll.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "scp_pik.h" +#include "scp_soc_mmap.h" + +#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 *)&SCP_PIK_PTR->PLL_STATUS[1], + .lock_flag_mask = PLL_STATUS_CPUPLLLOCK(0), + .initial_rate = 1750 * 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 *)&SCP_PIK_PTR->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_INTERCONNECT] = { + .name = "INT_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_INTERCONNECT, + .status_reg = (void *)&SCP_PIK_PTR->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/tc0/scp_romfw/config_system_pll.c b/product/tc0/scp_romfw/config_system_pll.c new file mode 100644 index 000000000..c9a8408f2 --- /dev/null +++ b/product/tc0/scp_romfw/config_system_pll.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "scp_pik.h" +#include "scp_soc_mmap.h" + +#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 *)&SCP_PIK_PTR->PLL_STATUS[1], + .lock_flag_mask = PLL_STATUS_CPUPLLLOCK(0), + .initial_rate = 1750 * 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 *)&SCP_PIK_PTR->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_INTERCONNECT] = { + .name = "INT_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_INTERCONNECT, + .status_reg = (void *)&SCP_PIK_PTR->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, +}; -- GitLab From afca7f058429b3d8999a37039dd91f28b8fff1bd Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 16:57:32 +0100 Subject: [PATCH 09/31] product/tc0: add configuration data for PIK clock driver The configuration data for PIK clock devices includes the base address of control registers and the rate table with initial rate. Change-Id: I6327930005af491dbcd765fc1a403a5e7c0265fa Signed-off-by: Usama Arif --- product/tc0/include/clock_soc.h | 16 ++ product/tc0/scp_ramfw/config_pik_clock.c | 183 +++++++++++++++++++++++ product/tc0/scp_romfw/config_pik_clock.c | 182 ++++++++++++++++++++++ 3 files changed, 381 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_pik_clock.c create mode 100644 product/tc0/scp_romfw/config_pik_clock.c diff --git a/product/tc0/include/clock_soc.h b/product/tc0/include/clock_soc.h index d0c9150fa..7de493c6e 100644 --- a/product/tc0/include/clock_soc.h +++ b/product/tc0/include/clock_soc.h @@ -10,6 +10,8 @@ #include +#define CLOCK_RATE_SYSPLLCLK (2000UL * FWK_MHZ) + /* * PLL clock indexes. */ @@ -20,4 +22,18 @@ enum clock_pll_idx { CLOCK_PLL_IDX_COUNT }; +/* + * PIK clock indexes. + */ +enum clock_pik_idx { + CLOCK_PIK_IDX_CLUS0_CPU0, + 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 +}; + #endif /* CLOCK_SOC_H */ diff --git a/product/tc0/scp_ramfw/config_pik_clock.c b/product/tc0/scp_ramfw/config_pik_clock.c new file mode 100644 index 000000000..70ec66aa3 --- /dev/null +++ b/product/tc0/scp_ramfw/config_pik_clock.c @@ -0,0 +1,183 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "cpu_pik.h" +#include "scp_pik.h" +#include "system_pik.h" + +#include + +#include +#include +#include +#include + +/* + * Rate lookup tables + */ +static struct mod_pik_clock_rate rate_table_cpu_group[] = { + { + .rate = 1750 * 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 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_scp[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_gicclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_pclkscp[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_sysperclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_uartclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct fwk_element pik_clock_element_table[] = { + + [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 = &CLUSTER_PIK_PTR(0)->CORECLK[0].CTRL, + .divext_reg = &CLUSTER_PIK_PTR(0)->CORECLK[0].DIV, + .modulator_reg = &CLUSTER_PIK_PTR(0)->CORECLK[0].MOD, + .rate_table = rate_table_cpu_group, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group), + }), + }, + [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 = &SYSTEM_PIK_PTR->INTCLK_CTRL, + .divext_reg = &SYSTEM_PIK_PTR->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 = &SCP_PIK_PTR->CORECLK_CTRL, + .divsys_reg = &SCP_PIK_PTR->CORECLK_DIV1, + .rate_table = rate_table_scp, + .rate_count = FWK_ARRAY_SIZE(rate_table_scp), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->GICCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->GICCLK_DIV1, + .rate_table = rate_table_gicclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_gicclk), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->PCLKSCP_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->PCLKSCP_DIV1, + .rate_table = rate_table_pclkscp, + .rate_count = FWK_ARRAY_SIZE(rate_table_pclkscp), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->SYSPERCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->SYSPERCLK_DIV1, + .rate_table = rate_table_sysperclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sysperclk), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->UARTCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->UARTCLK_DIV1, + .rate_table = rate_table_uartclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_uartclk), + .initial_rate = 2000 * 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/tc0/scp_romfw/config_pik_clock.c b/product/tc0/scp_romfw/config_pik_clock.c new file mode 100644 index 000000000..184d4d350 --- /dev/null +++ b/product/tc0/scp_romfw/config_pik_clock.c @@ -0,0 +1,182 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "cpu_pik.h" +#include "scp_pik.h" +#include "system_pik.h" + +#include + +#include +#include +#include +#include +/* + * Rate lookup tables + */ +static struct mod_pik_clock_rate rate_table_cpu_group[] = { + { + .rate = 1750 * 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 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_scp[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_gicclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_pclkscp[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_sysperclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct mod_pik_clock_rate rate_table_uartclk[] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (2000 * FWK_MHZ), + }, +}; + +static const struct fwk_element pik_clock_element_table[] = { + + [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 = &CLUSTER_PIK_PTR(0)->CORECLK[0].CTRL, + .divext_reg = &CLUSTER_PIK_PTR(0)->CORECLK[0].DIV, + .modulator_reg = &CLUSTER_PIK_PTR(0)->CORECLK[0].MOD, + .rate_table = rate_table_cpu_group, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group), + }), + }, + [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 = &SYSTEM_PIK_PTR->INTCLK_CTRL, + .divext_reg = &SYSTEM_PIK_PTR->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 = &SCP_PIK_PTR->CORECLK_CTRL, + .divsys_reg = &SCP_PIK_PTR->CORECLK_DIV1, + .rate_table = rate_table_scp, + .rate_count = FWK_ARRAY_SIZE(rate_table_scp), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->GICCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->GICCLK_DIV1, + .rate_table = rate_table_gicclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_gicclk), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->PCLKSCP_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->PCLKSCP_DIV1, + .rate_table = rate_table_pclkscp, + .rate_count = FWK_ARRAY_SIZE(rate_table_pclkscp), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->SYSPERCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->SYSPERCLK_DIV1, + .rate_table = rate_table_sysperclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sysperclk), + .initial_rate = 2000 * 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 = &SYSTEM_PIK_PTR->UARTCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->UARTCLK_DIV1, + .rate_table = rate_table_uartclk, + .rate_count = FWK_ARRAY_SIZE(rate_table_uartclk), + .initial_rate = 2000 * 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, +}; -- GitLab From 51176e83192d4cbe85625ade552b7d4420bf980e Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 17:00:16 +0100 Subject: [PATCH 10/31] product/tc0: add configuration data for subsytem clock driver Provide setup data i.e source PLL, member table and rate table for css clocks. Change-Id: I3a881e9c9b272be6d36bff703a2fcebc12339f79 Signed-off-by: Usama Arif --- product/tc0/include/clock_soc.h | 9 ++ product/tc0/scp_ramfw/config_css_clock.c | 108 +++++++++++++++++++++++ product/tc0/scp_romfw/config_css_clock.c | 108 +++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_css_clock.c create mode 100644 product/tc0/scp_romfw/config_css_clock.c diff --git a/product/tc0/include/clock_soc.h b/product/tc0/include/clock_soc.h index 7de493c6e..aafae9c99 100644 --- a/product/tc0/include/clock_soc.h +++ b/product/tc0/include/clock_soc.h @@ -10,6 +10,7 @@ #include +#define CLOCK_RATE_REFCLK (100UL * FWK_MHZ) #define CLOCK_RATE_SYSPLLCLK (2000UL * FWK_MHZ) /* @@ -36,4 +37,12 @@ enum clock_pik_idx { CLOCK_PIK_IDX_COUNT }; +/* + * CSS clock indexes. + */ +enum clock_css_idx { + CLOCK_CSS_IDX_CPU_GROUP0, + CLOCK_CSS_IDX_COUNT +}; + #endif /* CLOCK_SOC_H */ diff --git a/product/tc0/scp_ramfw/config_css_clock.c b/product/tc0/scp_ramfw/config_css_clock.c new file mode 100644 index 000000000..964ae1647 --- /dev/null +++ b/product/tc0/scp_ramfw/config_css_clock.c @@ -0,0 +1,108 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +static const struct mod_css_clock_rate rate_table_cpu_group[] = { + { + /* Super Underdrive */ + .rate = 946 * FWK_MHZ, + .pll_rate = 946 * 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 = 1419 * FWK_MHZ, + .pll_rate = 1419 * 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 = 1893 * FWK_MHZ, + .pll_rate = 1893 * 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 = 2271 * FWK_MHZ, + .pll_rate = 2271 * 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 = 2650 * FWK_MHZ, + .pll_rate = 2650 * 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 fwk_id_t member_table_cpu_group_0[] = { + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0), +}; + +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, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group), + .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 = 2271 * 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/tc0/scp_romfw/config_css_clock.c b/product/tc0/scp_romfw/config_css_clock.c new file mode 100644 index 000000000..964ae1647 --- /dev/null +++ b/product/tc0/scp_romfw/config_css_clock.c @@ -0,0 +1,108 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +static const struct mod_css_clock_rate rate_table_cpu_group[] = { + { + /* Super Underdrive */ + .rate = 946 * FWK_MHZ, + .pll_rate = 946 * 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 = 1419 * FWK_MHZ, + .pll_rate = 1419 * 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 = 1893 * FWK_MHZ, + .pll_rate = 1893 * 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 = 2271 * FWK_MHZ, + .pll_rate = 2271 * 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 = 2650 * FWK_MHZ, + .pll_rate = 2650 * 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 fwk_id_t member_table_cpu_group_0[] = { + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0), +}; + +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, + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group), + .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 = 2271 * 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, +}; -- GitLab From 01b9264bdcf89e3f20ae92b2eebc66b6d060ab8f Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 17:09:44 +0100 Subject: [PATCH 11/31] product/tc0: add configuration data for power domain and PPU modules Provide the config data such as PPU base addresses and irq map for the PPU driver and config data for power domain HAL to construct the power domain tree. Only a single core (core 0) needs to be provided for PPU config in ROM as AP firmware only uses primary core but all the cores need to be provided in PPU RAM firmware which is used when the kernel switches ON secondary cores. Change-Id: I1da7fc3ca0e8bf8ce3132e8a84d564c64ed0de2a Signed-off-by: Usama Arif --- product/tc0/include/config_power_domain.h | 25 +++ product/tc0/include/scp_css_mmap.h | 8 + product/tc0/include/tc0_power_domain.h | 25 +++ product/tc0/scp_ramfw/config_power_domain.c | 171 ++++++++++++++++++++ product/tc0/scp_ramfw/config_ppu_v1.c | 155 ++++++++++++++++++ product/tc0/scp_romfw/config_ppu_v1.c | 141 ++++++++++++++++ 6 files changed, 525 insertions(+) create mode 100644 product/tc0/include/config_power_domain.h create mode 100644 product/tc0/include/tc0_power_domain.h create mode 100644 product/tc0/scp_ramfw/config_power_domain.c create mode 100644 product/tc0/scp_ramfw/config_ppu_v1.c create mode 100644 product/tc0/scp_romfw/config_ppu_v1.c diff --git a/product/tc0/include/config_power_domain.h b/product/tc0/include/config_power_domain.h new file mode 100644 index 000000000..a85ea581f --- /dev/null +++ b/product/tc0/include/config_power_domain.h @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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 tc0_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_SYSTOP, + PD_STATIC_DEV_IDX_COUNT +}; + +#endif /* CONFIG_POWER_DOMAIN_H */ diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index c736cf3dc..a66f4a8ed 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -18,4 +18,12 @@ #define SCP_PIK_SYSTEM_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + 0x40000) +#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) + +#define SCP_PPU_SYS0_BASE (SCP_PIK_SYSTEM_BASE + 0x1000) +#define SCP_PPU_SYS1_BASE (SCP_PIK_SYSTEM_BASE + 0x5000) + +#define SCP_PPU_BASE(n) (SCP_PIK_CLUSTER_BASE(n) + 0x2000) #endif /* SCP_CSS_MMAP_H */ diff --git a/product/tc0/include/tc0_power_domain.h b/product/tc0/include/tc0_power_domain.h new file mode 100644 index 000000000..f7ef23636 --- /dev/null +++ b/product/tc0/include/tc0_power_domain.h @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TC0_POWER_DOMAIN_H +#define TC0_POWER_DOMAIN_H + +#include + +/*! Mask for the cluster valid power states */ +#define TC0_CLUSTER_VALID_STATE_MASK ( \ + MOD_PD_STATE_OFF_MASK | \ + MOD_PD_STATE_ON_MASK \ + ) + +/*! Mask for the core valid power states */ +#define TC0_CORE_VALID_STATE_MASK ( \ + MOD_PD_STATE_OFF_MASK | \ + MOD_PD_STATE_ON_MASK \ + ) + +#endif /* TC0_POWER_DOMAIN_H */ diff --git a/product/tc0/scp_ramfw/config_power_domain.c b/product/tc0/scp_ramfw/config_power_domain.c new file mode 100644 index 000000000..7d948cd45 --- /dev/null +++ b/product/tc0/scp_ramfw/config_power_domain.c @@ -0,0 +1,171 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "tc0_core.h" +#include "tc0_power_domain.h" + +#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_ON_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_ON] = TC0_CLUSTER_VALID_STATE_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] = TC0_CORE_VALID_STATE_MASK, +}; + +/* Power module specific configuration data (none) */ +static const struct mod_power_domain_config + tc0_power_domain_config = { 0 }; + +static struct fwk_element tc0_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_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 *tc0_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 = tc0_core_get_core_count(); + cluster_count = tc0_core_get_cluster_count(); + + element_table = fwk_mm_calloc( + core_count + + FWK_ARRAY_SIZE(tc0_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 < tc0_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 *) + tc0_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, + tc0_power_domain_static_element_table, + sizeof(tc0_power_domain_static_element_table)); + + return element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_power_domain = { + .get_element_table = tc0_power_domain_get_element_table, + .data = &tc0_power_domain_config, +}; diff --git a/product/tc0/scp_ramfw/config_ppu_v1.c b/product/tc0/scp_ramfw/config_ppu_v1.c new file mode 100644 index 000000000..2932c5130 --- /dev/null +++ b/product/tc0/scp_ramfw/config_ppu_v1.c @@ -0,0 +1,155 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "tc0_core.h" +#include "scp_css_mmap.h" + +#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 + +/* 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 = tc0_core_get_core_count(); + cluster_count = tc0_core_get_cluster_count(); + + /* + * 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 < tc0_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_ID_NONE; + } + + 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/tc0/scp_romfw/config_ppu_v1.c b/product/tc0/scp_romfw/config_ppu_v1.c new file mode 100644 index 000000000..3a83aaf25 --- /dev/null +++ b/product/tc0/scp_romfw/config_ppu_v1.c @@ -0,0 +1,141 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "tc0_core.h" +#include "scp_css_mmap.h" + +#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 indicies into CMN_BOOKER node IDs */ +static const unsigned int cluster_idx_to_node_id[] = {68}; + +static struct fwk_element ppu_v1_system_element_table[] = { + { + .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, + .default_power_on = true, + }), + }, + { + .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, + .default_power_on = true, + }), + }, + { 0 }, /* Termination entry */ +}; + +static const struct fwk_element *tc0_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; + + /* + * Allocate element descriptors based on: + * Core0 + * + Cluster0 + * + Number of system power domain descriptors + * + 1 terminator descriptor + */ + element_table = fwk_mm_calloc(2 + + 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(2, sizeof(struct mod_ppu_v1_pd_config)); + if (pd_config_table == NULL) + return NULL; + + // pd_config for core0 + element = &element_table[0]; + pd_config = &pd_config_table[0]; + + element->name = fwk_mm_alloc(PPU_CORE_NAME_SIZE, 1); + if (element->name == NULL) + return NULL; + + snprintf((char *)element->name, PPU_CORE_NAME_SIZE, "CLUS0CORE0"); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CORE; + pd_config->ppu.reg_base = SCP_PPU_CORE_BASE(0, 0); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->cluster_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, 1); + pd_config->observer_id = FWK_ID_NONE; + + //pd_config for cluster0 + element = &element_table[1]; + pd_config = &pd_config_table[1]; + + element->name = fwk_mm_alloc(PPU_CLUS_NAME_SIZE, 1); + if (element->name == NULL) + return NULL; + + snprintf((char *)element->name, PPU_CLUS_NAME_SIZE, "CLUS0"); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CLUSTER; + pd_config->ppu.reg_base = SCP_PPU_CLUSTER_BASE(0); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + + pd_config->observer_id = fwk_module_id_cmn_booker; + pd_config->observer_api = FWK_ID_API(FWK_MODULE_IDX_CMN_BOOKER, + MOD_CMN_BOOKER_API_IDX_PPU_OBSERVER); + pd_config->post_ppu_on_param = + (void *)&cluster_idx_to_node_id[0]; + + memcpy(&element_table[2], + ppu_v1_system_element_table, + sizeof(ppu_v1_system_element_table)); + + return element_table; +} + +/* + * Power module configuration data + */ +struct fwk_module_config config_ppu_v1 = { + .get_element_table = tc0_ppu_v1_get_element_table, + .data = &(struct mod_ppu_v1_config) { + .pd_notification_id = FWK_ID_NOTIFICATION_INIT(FWK_MODULE_IDX_MSYS_ROM, + MOD_MSYS_ROM_NOTIFICATION_IDX_POWER_SYSTOP), + .pd_source_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MSYS_ROM), + }, +}; -- GitLab From 9835e102c9556d3516094d23d55cefd0204f1cbf Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 22 Apr 2020 17:18:09 +0100 Subject: [PATCH 12/31] product/tc0: add configuration data for Clock HAL Provide the configuration data for clock HAL which includes the clock driver id, api id and the power domain source. Change-Id: I6e9daa5582795e64e792e0967504ba49abdabe73 Signed-off-by: Usama Arif --- product/tc0/include/clock_soc.h | 9 ++++ product/tc0/scp_ramfw/config_clock.c | 71 ++++++++++++++++++++++++++++ product/tc0/scp_romfw/config_clock.c | 61 ++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_clock.c create mode 100644 product/tc0/scp_romfw/config_clock.c diff --git a/product/tc0/include/clock_soc.h b/product/tc0/include/clock_soc.h index aafae9c99..2ae6f7de6 100644 --- a/product/tc0/include/clock_soc.h +++ b/product/tc0/include/clock_soc.h @@ -45,4 +45,13 @@ enum clock_css_idx { CLOCK_CSS_IDX_COUNT }; +/* + * Clock indexes. + */ +enum clock_idx { + CLOCK_IDX_INTERCONNECT, + CLOCK_IDX_CPU_GROUP0, + CLOCK_IDX_COUNT +}; + #endif /* CLOCK_SOC_H */ diff --git a/product/tc0/scp_ramfw/config_clock.c b/product/tc0/scp_ramfw/config_clock.c new file mode 100644 index 000000000..0b6c5d64c --- /dev/null +++ b/product/tc0/scp_ramfw/config_clock.c @@ -0,0 +1,71 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "config_power_domain.h" +#include "tc0_core.h" + +#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), + }), + }, + { 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, + tc0_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/tc0/scp_romfw/config_clock.c b/product/tc0/scp_romfw/config_clock.c new file mode 100644 index 000000000..3b49a0a58 --- /dev/null +++ b/product/tc0/scp_romfw/config_clock.c @@ -0,0 +1,61 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "config_power_domain.h" +#include "tc0_core.h" + +#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), + .pd_source_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MSYS_ROM), + + }), + }, + [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), + .pd_source_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MSYS_ROM), + }), + }, + { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id) +{ + 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_MSYS_ROM, + MOD_MSYS_ROM_NOTIFICATION_IDX_POWER_SYSTOP), + .pd_pre_transition_notification_id = FWK_ID_NONE_INIT, + }), +}; -- GitLab From 9ae90c4d16ed85d73d712a540d23c4bae8fbe1ca Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 12:01:57 +0100 Subject: [PATCH 13/31] product/tc0: add configuration data for CMN Booker driver CMN Booker is the interconnect used in Total Compute platform. Add configuration data such as base address, memory region map, SNF table and mesh sizes. Change-Id: I9ebba14c1efbb2d629285e2323f2d87430e603c6 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 2 + product/tc0/include/scp_mmap.h | 1 + product/tc0/scp_romfw/config_cmn_booker.c | 111 ++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 product/tc0/scp_romfw/config_cmn_booker.c diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index a66f4a8ed..d3d47b3f0 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -10,6 +10,8 @@ #include "scp_mmap.h" +#define SCP_CMN_BOOKER_BASE (SCP_SYSTEM_ACCESS_PORT0_BASE + 0x10000000) + #define SCP_UART_BASE (SCP_PERIPHERAL_BASE + 0x2000) #define SCP_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 03d7b6829..9af488f47 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -11,5 +11,6 @@ #define SCP_SOC_EXPANSION3_BASE 0x40000000 #define SCP_PERIPHERAL_BASE 0x44000000 #define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 +#define SCP_SYSTEM_ACCESS_PORT0_BASE 0x60000000 #endif /* SCP_MMAP_H */ diff --git a/product/tc0/scp_romfw/config_cmn_booker.c b/product/tc0/scp_romfw/config_cmn_booker.c new file mode 100644 index 000000000..2365ec78a --- /dev/null +++ b/product/tc0/scp_romfw/config_cmn_booker.c @@ -0,0 +1,111 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "scp_css_mmap.h" + +#include + +#include +#include +#include +#include + +/* + * CMN_BOOKER nodes + */ +#define MEM_CNTRL0_ID 2 +#define MEM_CNTRL1_ID 14 +#define MEM_CNTRL2_ID 38 +#define MEM_CNTRL3_ID 46 +#define NODE_ID_HND 4 + +static const unsigned int snf_table[] = { + MEM_CNTRL0_ID, /* Maps to HN-F logical node 0 */ + MEM_CNTRL1_ID, /* Maps to HN-F logical node 1 */ + MEM_CNTRL2_ID, /* Maps to HN-F logical node 2 */ + MEM_CNTRL3_ID, /* Maps to HN-F logical node 3 */ +}; + +static const struct mod_cmn_booker_mem_region_map mmap[] = { + { + /* + * System cache backed region + * Map: 0x0000_0000_0000 - 0x003FF_FFFF_FFFF (4 TB) + */ + .base = UINT64_C(0x000000000000), + .size = UINT64_C(4) * FWK_TIB, + .type = MOD_CMN_BOOKER_MEM_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_CMN_BOOKER_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals + * Map: 0x00_0800_0000 - 0x00_0FFF_FFFF (128 MB) + */ + .base = UINT64_C(0x0008000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_BOOKER_MEM_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_CMN_BOOKER_MEM_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_CMN_BOOKER_MEM_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_CMN_BOOKER_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, +}; + +const struct fwk_module_config config_cmn_booker = { + .get_element_table = NULL, + .data = &((struct mod_cmn_booker_config) { + .base = SCP_CMN_BOOKER_BASE, + .mesh_size_x = 2, + .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), + .hnf_cal_mode = false, + }), +}; -- GitLab From f91cea43500b58b7794d370007e1662e7774f3a0 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 12:06:55 +0100 Subject: [PATCH 14/31] product/tc0: add configuration data for generic timer driver The configuration data for generic timer driver includes the base adresses of timer register, counter register and control register along with the initial frequency and the id of clock device on which the timer depends. Change-Id: Ie9ef746c380b1eef924bc894fb242eb1f39bc928 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 3 ++ product/tc0/scp_ramfw/config_gtimer.c | 43 +++++++++++++++++++++++++++ product/tc0/scp_romfw/config_gtimer.c | 43 +++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_gtimer.c create mode 100644 product/tc0/scp_romfw/config_gtimer.c diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index d3d47b3f0..71fd2b823 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -12,6 +12,9 @@ #define SCP_CMN_BOOKER_BASE (SCP_SYSTEM_ACCESS_PORT0_BASE + 0x10000000) +#define SCP_REFCLK_CNTCONTROL_BASE (SCP_SYSTEM_ACCESS_PORT1_BASE + 0x2A430000) +#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_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) diff --git a/product/tc0/scp_ramfw/config_gtimer.c b/product/tc0/scp_ramfw/config_gtimer.c new file mode 100644 index 000000000..79d94478e --- /dev/null +++ b/product/tc0/scp_ramfw/config_gtimer.c @@ -0,0 +1,43 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "scp_css_mmap.h" + +#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, +}; diff --git a/product/tc0/scp_romfw/config_gtimer.c b/product/tc0/scp_romfw/config_gtimer.c new file mode 100644 index 000000000..e3325a171 --- /dev/null +++ b/product/tc0/scp_romfw/config_gtimer.c @@ -0,0 +1,43 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "scp_css_mmap.h" + +#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, +}; -- GitLab From d42b216be7033316349441a9e32678704976850f Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 12:11:23 +0100 Subject: [PATCH 15/31] product/tc0: add configuration data for timer HAL Provide the configuration data for timer HAL which includes the id for the timer element and the IRQ number. Change-Id: I9b9d60a131d110ae362b88f97de88060a11f743a Signed-off-by: Usama Arif --- product/tc0/include/scp_tc0_irq.h | 17 ++++++++++++ product/tc0/include/tc0_timer.h | 16 +++++++++++ product/tc0/scp_ramfw/config_timer.c | 41 ++++++++++++++++++++++++++++ product/tc0/scp_romfw/config_timer.c | 39 ++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 product/tc0/include/scp_tc0_irq.h create mode 100644 product/tc0/include/tc0_timer.h create mode 100644 product/tc0/scp_ramfw/config_timer.c create mode 100644 product/tc0/scp_romfw/config_timer.c diff --git a/product/tc0/include/scp_tc0_irq.h b/product/tc0/include/scp_tc0_irq.h new file mode 100644 index 000000000..0369cc9ae --- /dev/null +++ b/product/tc0/include/scp_tc0_irq.h @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_TC0_IRQ_H +#define SCP_TC0_IRQ_H + +#include + +enum scp_tc0_interrupt { + TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ +}; + +#endif /* SCP_TC0_IRQ_H */ diff --git a/product/tc0/include/tc0_timer.h b/product/tc0/include/tc0_timer.h new file mode 100644 index 000000000..2ca478f4a --- /dev/null +++ b/product/tc0/include/tc0_timer.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_TIMER_H +#define CONFIG_TIMER_H + +enum config_timer_refclk_sub_element_idx { + CONFIG_TIMER_DVFS_CPU, + CONFIG_TIMER_SUB_ELEMENT_IDX_COUNT, +}; + +#endif /* CONFIG_TIMER_H */ diff --git a/product/tc0/scp_ramfw/config_timer.c b/product/tc0/scp_ramfw/config_timer.c new file mode 100644 index 000000000..396b61c08 --- /dev/null +++ b/product/tc0/scp_ramfw/config_timer.c @@ -0,0 +1,41 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_tc0_irq.h" +#include "tc0_timer.h" + +#include + +#include +#include +#include +#include + +/* + * 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, + }), + /* Number of alarms */ + .sub_element_count = CONFIG_TIMER_SUB_ELEMENT_IDX_COUNT, + }, + [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/tc0/scp_romfw/config_timer.c b/product/tc0/scp_romfw/config_timer.c new file mode 100644 index 000000000..599d9c3c1 --- /dev/null +++ b/product/tc0/scp_romfw/config_timer.c @@ -0,0 +1,39 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_tc0_irq.h" + +#include + +#include +#include +#include +#include + +/* + * 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, +}; -- GitLab From 8fc0cba8d118fef0bd20af33298f061296e8d84b Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 12:18:15 +0100 Subject: [PATCH 16/31] product/tc0: add configuration data for SDS service module SDS module is used to pass runtime data from SCP firmware to the firmware on AP core using shared memory. Provide the base address and size for the same and also the payloads to be passed. CPU info and feature availability SDS identifiers are used by both ROM and RAM, but bootloader SDS is used by ROM only as it used to copy copy SCP RAM firmware from AP secure RAM to SCP RAM. Change-Id: I6ef9a112b158530bbdf9e1fc311bf002ad444cea Signed-off-by: Usama Arif --- product/tc0/include/scp_mmap.h | 1 + product/tc0/include/scp_software_mmap.h | 29 ++++++++ product/tc0/include/tc0_sds.h | 62 ++++++++++++++++ product/tc0/scp_ramfw/config_sds.c | 85 ++++++++++++++++++++++ product/tc0/scp_romfw/config_sds.c | 95 +++++++++++++++++++++++++ 5 files changed, 272 insertions(+) create mode 100644 product/tc0/include/scp_software_mmap.h create mode 100644 product/tc0/include/tc0_sds.h create mode 100644 product/tc0/scp_ramfw/config_sds.c create mode 100644 product/tc0/scp_romfw/config_sds.c diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 9af488f47..1147843f5 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -12,5 +12,6 @@ #define SCP_PERIPHERAL_BASE 0x44000000 #define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 #define SCP_SYSTEM_ACCESS_PORT0_BASE 0x60000000 +#define SCP_SYSTEM_ACCESS_PORT1_BASE 0xA0000000 #endif /* SCP_MMAP_H */ diff --git a/product/tc0/include/scp_software_mmap.h b/product/tc0/include/scp_software_mmap.h new file mode 100644 index 000000000..0ba401c64 --- /dev/null +++ b/product/tc0/include/scp_software_mmap.h @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCP_SOFTWARE_MMAP_H +#define SCP_SOFTWARE_MMAP_H + + +#include "scp_soc_mmap.h" + +#include + +/* SCP trusted and non-trusted RAM base address */ +#define SCP_TRUSTED_RAM_BASE (SCP_SYSTEM_ACCESS_PORT1_BASE + \ + 0x04000000) + +/* Secure Shared memory between AP and SCP */ +#define SCP_AP_SHARED_SECURE_BASE (SCP_TRUSTED_RAM_BASE) +#define SCP_AP_SHARED_SECURE_SIZE (4 * FWK_KIB) + + +/* SDS Memory Region */ +#define SCP_SDS_MEM_BASE (SCP_AP_SHARED_SECURE_BASE) +#define SCP_SDS_MEM_SIZE (3520) + +#endif /* SCP_SOFTWARE_MMAP_H */ diff --git a/product/tc0/include/tc0_sds.h b/product/tc0/include/tc0_sds.h new file mode 100644 index 000000000..e8d9ae25a --- /dev/null +++ b/product/tc0/include/tc0_sds.h @@ -0,0 +1,62 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TC0_SDS_H +#define TC0_SDS_H + +#include + +/* + * Structure identifiers. + */ +enum tc0_sds_struct_id { + TC0_SDS_CPU_INFO = 1 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + TC0_SDS_FEATURE_AVAILABILITY = 6 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), + TC0_SDS_BOOTLOADER = 9 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS), +}; + +enum tc0_sds_region_idx { + TC0_SDS_REGION_SECURE, + TC0_SDS_REGION_COUNT +}; + +/* + * Structure sizes. + */ +#define TC0_SDS_CPU_INFO_SIZE 4 +#define TC0_SDS_FEATURE_AVAILABILITY_SIZE 4 +#define TC0_SDS_BOOTLOADER_SIZE 12 + +/* + * Field masks and offsets for TC0_SDS_AP_CPU_INFO structure. + */ +#define TC0_SDS_CPU_INFO_PRIMARY_MASK 0xFFFFFFFF +#define TC0_SDS_CPU_INFO_PRIMARY_POS 0 + +/* + * Field masks and offsets for TC0_SDS_FEATURE_AVAILABILITY structure. + */ +#define TC0_SDS_FEATURE_FIRMWARE_MASK 0x1 +#define TC0_SDS_FEATURE_DMC_MASK 0x2 +#define TC0_SDS_FEATURE_MESSAGING_MASK 0x4 + +#define TC0_SDS_FEATURE_FIRMWARE_POS 0 +#define TC0_SDS_FEATURE_DMC_POS 1 +#define TC0_SDS_FEATURE_MESSAGING_POS 2 + +/* + * Field masks and offsets for the TC0_SDS_BOOTLOADER structure. + */ +#define TC0_SDS_BOOTLOADER_VALID_MASK 0x1 +#define TC0_SDS_BOOTLOADER_OFFSET_MASK 0xFFFFFFFF +#define TC0_SDS_BOOTLOADER_SIZE_MASK 0xFFFFFFFF + +#define TC0_SDS_BOOTLOADER_VALID_POS 0 +#define TC0_SDS_BOOTLOADER_OFFSET_POS 0 +#define TC0_SDS_BOOTLOADER_SIZE_POS 0 + +#endif /* TC0_SDS_H */ diff --git a/product/tc0/scp_ramfw/config_sds.c b/product/tc0/scp_ramfw/config_sds.c new file mode 100644 index 000000000..328db8483 --- /dev/null +++ b/product/tc0/scp_ramfw/config_sds.c @@ -0,0 +1,85 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "tc0_sds.h" +#include "scp_pik.h" +#include "scp_software_mmap.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +static const uint32_t feature_flags = TC0_SDS_FEATURE_FIRMWARE_MASK; + +static const struct mod_sds_region_desc sds_module_regions[] = { + [TC0_SDS_REGION_SECURE] = { + .base = (void*)SCP_SDS_MEM_BASE, + .size = SCP_SDS_MEM_SIZE, + }, +}; + +static_assert(FWK_ARRAY_SIZE(sds_module_regions) == TC0_SDS_REGION_COUNT, + "Mismatch between number of SDS regions and number of regions " + "provided by the SDS configuration."); + +const struct mod_sds_config sds_module_config = { + .regions = sds_module_regions, + .region_count = TC0_SDS_REGION_COUNT, + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT) +}; + +static struct fwk_element sds_element_table[] = { + { + .name = "CPU Info", + .data = &((struct mod_sds_structure_desc) { + .id = TC0_SDS_CPU_INFO, + .size = TC0_SDS_CPU_INFO_SIZE, + .region_id = TC0_SDS_REGION_SECURE, + .finalize = true, + }), + }, + { + .name = "Feature Availability", + .data = &((struct mod_sds_structure_desc) { + .id = TC0_SDS_FEATURE_AVAILABILITY, + .size = TC0_SDS_FEATURE_AVAILABILITY_SIZE, + .payload = &feature_flags, + .region_id = TC0_SDS_REGION_SECURE, + .finalize = true, + }), + }, + { 0 }, /* Termination description. */ +}; + +static_assert(SCP_SDS_MEM_SIZE > + TC0_SDS_CPU_INFO_SIZE + + TC0_SDS_FEATURE_AVAILABILITY_SIZE, + "SDS structures too large for SDS SRAM.\n"); + +static const struct fwk_element *sds_get_element_table(fwk_id_t module_id) +{ + 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"); + + 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/tc0/scp_romfw/config_sds.c b/product/tc0/scp_romfw/config_sds.c new file mode 100644 index 000000000..3c0a3ec8f --- /dev/null +++ b/product/tc0/scp_romfw/config_sds.c @@ -0,0 +1,95 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "tc0_sds.h" +#include "scp_pik.h" +#include "scp_software_mmap.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +static const uint32_t feature_flags = 0x00000000; + +static const struct mod_sds_region_desc sds_module_regions[] = { + [TC0_SDS_REGION_SECURE] = { + .base = (void*)SCP_SDS_MEM_BASE, + .size = SCP_SDS_MEM_SIZE, + }, +}; + +static_assert(FWK_ARRAY_SIZE(sds_module_regions) == TC0_SDS_REGION_COUNT, + "Mismatch between number of SDS regions and number of regions " + "provided by the SDS configuration."); + +const struct mod_sds_config sds_module_config = { + .regions = sds_module_regions, + .region_count = TC0_SDS_REGION_COUNT, + .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, + CLOCK_IDX_INTERCONNECT) +}; + +static struct fwk_element sds_element_table[] = { + { + .name = "CPU Info", + .data = &((struct mod_sds_structure_desc) { + .id = TC0_SDS_CPU_INFO, + .size = TC0_SDS_CPU_INFO_SIZE, + .region_id = TC0_SDS_REGION_SECURE, + .finalize = true, + }), + }, + { + .name = "Feature Availability", + .data = &((struct mod_sds_structure_desc) { + .id = TC0_SDS_FEATURE_AVAILABILITY, + .size = TC0_SDS_FEATURE_AVAILABILITY_SIZE, + .payload = &feature_flags, + .region_id = TC0_SDS_REGION_SECURE, + .finalize = true, + }), + }, + { + .name = "Bootloader", + .data = &((struct mod_sds_structure_desc) { + .id = TC0_SDS_BOOTLOADER, + .size = TC0_SDS_BOOTLOADER_SIZE, + .region_id = TC0_SDS_REGION_SECURE, + .finalize = true, + }), + }, + { 0 }, /* Termination description. */ +}; + +static_assert(SCP_SDS_MEM_SIZE > + TC0_SDS_CPU_INFO_SIZE + + TC0_SDS_FEATURE_AVAILABILITY_SIZE + + TC0_SDS_BOOTLOADER_SIZE, + "SDS structures too large for SDS SRAM.\n"); + +static const struct fwk_element *sds_get_element_table(fwk_id_t module_id) +{ + 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"); + + return sds_element_table; +} + +struct fwk_module_config config_sds = { + .get_element_table = sds_get_element_table, + .data = &sds_module_config, +}; -- GitLab From db3708aad4ab87a65af28a25a4dab485a82c7ec5 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 13:24:18 +0100 Subject: [PATCH 17/31] product/tc0: add configuration data for bootloader and msys ROM These modules are used initiate the boot of the primary AP core, copy the SCP RAM firmware from AP Secure RAM to SCP RAM, and then jump to the SCP RAM firmware. Change-Id: I6b6dd39fa3456e7dac1fd8a7c033ded161c3befa Signed-off-by: Usama Arif --- product/tc0/include/scp_mmap.h | 1 + product/tc0/include/scp_software_mmap.h | 7 +++++++ product/tc0/scp_romfw/config_bootloader.c | 25 +++++++++++++++++++++++ product/tc0/scp_romfw/config_msys_rom.c | 23 +++++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 product/tc0/scp_romfw/config_bootloader.c create mode 100644 product/tc0/scp_romfw/config_msys_rom.c diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 1147843f5..37c6c77f5 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -8,6 +8,7 @@ #ifndef SCP_MMAP_H #define SCP_MMAP_H +#define SCP_ITC_RAM_BASE 0x00800000 #define SCP_SOC_EXPANSION3_BASE 0x40000000 #define SCP_PERIPHERAL_BASE 0x44000000 #define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 diff --git a/product/tc0/include/scp_software_mmap.h b/product/tc0/include/scp_software_mmap.h index 0ba401c64..66b110f45 100644 --- a/product/tc0/include/scp_software_mmap.h +++ b/product/tc0/include/scp_software_mmap.h @@ -13,6 +13,8 @@ #include +#define SCP_ITC_RAM_SIZE (256 * 1024) + /* SCP trusted and non-trusted RAM base address */ #define SCP_TRUSTED_RAM_BASE (SCP_SYSTEM_ACCESS_PORT1_BASE + \ 0x04000000) @@ -21,6 +23,11 @@ #define SCP_AP_SHARED_SECURE_BASE (SCP_TRUSTED_RAM_BASE) #define SCP_AP_SHARED_SECURE_SIZE (4 * FWK_KIB) +/* 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) /* SDS Memory Region */ #define SCP_SDS_MEM_BASE (SCP_AP_SHARED_SECURE_BASE) diff --git a/product/tc0/scp_romfw/config_bootloader.c b/product/tc0/scp_romfw/config_bootloader.c new file mode 100644 index 000000000..bac10ecaf --- /dev/null +++ b/product/tc0/scp_romfw/config_bootloader.c @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_software_mmap.h" +#include "tc0_sds.h" + +#include + +#include + +static const struct mod_bootloader_config bootloader_module_config = { + .source_base = SCP_TRUSTED_RAM_BASE, + .source_size = 512 * 1024, + .destination_base = SCP_ITC_RAM_BASE, + .destination_size = SCP_ITC_RAM_SIZE, + .sds_struct_id = TC0_SDS_BOOTLOADER, +}; + +struct fwk_module_config config_bootloader = { + .data = &bootloader_module_config, +}; diff --git a/product/tc0/scp_romfw/config_msys_rom.c b/product/tc0/scp_romfw/config_msys_rom.c new file mode 100644 index 000000000..6b0ef6b97 --- /dev/null +++ b/product/tc0/scp_romfw/config_msys_rom.c @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_software_mmap.h" + +#include + +#include +#include +#include + +const struct fwk_module_config config_msys_rom = { + .data = &((struct msys_rom_config) { + .ap_context_base = SCP_AP_CONTEXT_BASE, + .ap_context_size = SCP_AP_CONTEXT_SIZE, + .id_primary_cluster = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 1), + .id_primary_core = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 0), + }) +}; -- GitLab From a7a961d5e6c9fe4ab2768280b907323fbac458a7 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 15:48:24 +0100 Subject: [PATCH 18/31] product/tc0: add build support for SCP ROM firmware Add the linker script and makefile to support the build of the SCP ROM firmware. Change-Id: I854c182dbf0477c5a168fbe31651d0a248d09361 Signed-off-by: Usama Arif --- product/tc0/include/scp_mmap.h | 2 ++ product/tc0/include/scp_software_mmap.h | 3 ++ product/tc0/scp_romfw/firmware.mk | 47 +++++++++++++++++++++++++ product/tc0/scp_romfw/fmw_memory.h | 31 ++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 product/tc0/scp_romfw/firmware.mk create mode 100644 product/tc0/scp_romfw/fmw_memory.h diff --git a/product/tc0/include/scp_mmap.h b/product/tc0/include/scp_mmap.h index 37c6c77f5..e048ce7a1 100644 --- a/product/tc0/include/scp_mmap.h +++ b/product/tc0/include/scp_mmap.h @@ -8,7 +8,9 @@ #ifndef SCP_MMAP_H #define SCP_MMAP_H +#define SCP_BOOT_ROM_BASE 0x00000000 #define SCP_ITC_RAM_BASE 0x00800000 +#define SCP_DTC_RAM_BASE 0x20000000 #define SCP_SOC_EXPANSION3_BASE 0x40000000 #define SCP_PERIPHERAL_BASE 0x44000000 #define SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE 0x50000000 diff --git a/product/tc0/include/scp_software_mmap.h b/product/tc0/include/scp_software_mmap.h index 66b110f45..7c2327396 100644 --- a/product/tc0/include/scp_software_mmap.h +++ b/product/tc0/include/scp_software_mmap.h @@ -13,6 +13,9 @@ #include +/* SCP ROM and RAM firmware size loaded on main memory */ +#define SCP_BOOT_ROM_SIZE (64 * 1024) +#define SCP_DTC_RAM_SIZE (256 * 1024) #define SCP_ITC_RAM_SIZE (256 * 1024) /* SCP trusted and non-trusted RAM base address */ diff --git a/product/tc0/scp_romfw/firmware.mk b/product/tc0/scp_romfw/firmware.mk new file mode 100644 index 000000000..c3c3a43ae --- /dev/null +++ b/product/tc0/scp_romfw/firmware.mk @@ -0,0 +1,47 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, 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 \ + log \ + ppu_v1 \ + msys_rom \ + sds \ + bootloader \ + system_pll \ + pik_clock \ + css_clock \ + clock \ + gtimer \ + timer \ + cmn_booker + +BS_FIRMWARE_SOURCES := \ + config_log.c \ + config_pl011.c \ + config_ppu_v1.c \ + config_sds.c \ + config_cmn_booker.c \ + config_system_pll.c \ + config_pik_clock.c \ + config_css_clock.c \ + config_clock.c \ + config_gtimer.c \ + config_timer.c \ + config_msys_rom.c \ + config_bootloader.c + + + +include $(BS_DIR)/firmware.mk diff --git a/product/tc0/scp_romfw/fmw_memory.h b/product/tc0/scp_romfw/fmw_memory.h new file mode 100644 index 000000000..78978aba9 --- /dev/null +++ b/product/tc0/scp_romfw/fmw_memory.h @@ -0,0 +1,31 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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_H +#define FMW_MEMORY_H + +#include "scp_mmap.h" +#include "scp_software_mmap.h" + +#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * ROM memory + */ +#define FIRMWARE_MEM0_SIZE SCP_BOOT_ROM_SIZE +#define FIRMWARE_MEM0_BASE SCP_BOOT_ROM_BASE + +/* + * RAM memory + */ +#define FIRMWARE_MEM1_SIZE SCP_DTC_RAM_SIZE +#define FIRMWARE_MEM1_BASE SCP_DTC_RAM_BASE + +#endif /* FMW_MEMORY_H */ -- GitLab From 22966bfc54004e1373c6ce3632e703056770f052 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 16:38:28 +0100 Subject: [PATCH 19/31] product/tc0: add configuration data for MPU module Add configuration data for MPU module. The SCP RAMs, trusted RAM and non-trusted memory regions are specified. Change-Id: I5f768c7294dc1df1d84686508bfb4d56d5802c08 Signed-off-by: Usama Arif --- product/tc0/include/fmw_cmsis.h | 34 +++++++++++++++ product/tc0/include/scp_software_mmap.h | 2 + product/tc0/scp_ramfw/config_armv7m_mpu.c | 51 +++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 product/tc0/include/fmw_cmsis.h create mode 100644 product/tc0/scp_ramfw/config_armv7m_mpu.c diff --git a/product/tc0/include/fmw_cmsis.h b/product/tc0/include/fmw_cmsis.h new file mode 100644 index 000000000..89e48f5d8 --- /dev/null +++ b/product/tc0/include/fmw_cmsis.h @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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/tc0/include/scp_software_mmap.h b/product/tc0/include/scp_software_mmap.h index 7c2327396..58fbff940 100644 --- a/product/tc0/include/scp_software_mmap.h +++ b/product/tc0/include/scp_software_mmap.h @@ -21,6 +21,8 @@ /* SCP trusted and non-trusted RAM base address */ #define SCP_TRUSTED_RAM_BASE (SCP_SYSTEM_ACCESS_PORT1_BASE + \ 0x04000000) +#define SCP_NONTRUSTED_RAM_BASE (SCP_SYSTEM_ACCESS_PORT1_BASE + \ + 0x06000000) /* Secure Shared memory between AP and SCP */ #define SCP_AP_SHARED_SECURE_BASE (SCP_TRUSTED_RAM_BASE) diff --git a/product/tc0/scp_ramfw/config_armv7m_mpu.c b/product/tc0/scp_ramfw/config_armv7m_mpu.c new file mode 100644 index 000000000..cdeeac7a1 --- /dev/null +++ b/product/tc0/scp_ramfw/config_armv7m_mpu.c @@ -0,0 +1,51 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_mmap.h" +#include "scp_software_mmap.h" + +#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_ITC_RAM_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_DTC_RAM_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, + }), +}; -- GitLab From 193992f1b3e438407353988975eb29c8443b8cd3 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 16:43:38 +0100 Subject: [PATCH 20/31] product/tc0: add platform specific definitions for RTX Add platform specific definitions for callback functions for CMSIS RTX. Change-Id: If3d158f22eea2f9e6061cfe56811aaf26e068554 Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/RTX_Config.h | 56 ++++++++++++++++++++++++++++++ product/tc0/scp_ramfw/rtx_config.c | 38 ++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 product/tc0/scp_ramfw/RTX_Config.h create mode 100644 product/tc0/scp_ramfw/rtx_config.c diff --git a/product/tc0/scp_ramfw/RTX_Config.h b/product/tc0/scp_ramfw/RTX_Config.h new file mode 100644 index 000000000..35ce37d14 --- /dev/null +++ b/product/tc0/scp_ramfw/RTX_Config.h @@ -0,0 +1,56 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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 the an RTX + * file in order to create a 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/tc0/scp_ramfw/rtx_config.c b/product/tc0/scp_ramfw/rtx_config.c new file mode 100644 index 000000000..3f0acbaaa --- /dev/null +++ b/product/tc0/scp_ramfw/rtx_config.c @@ -0,0 +1,38 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" + +#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); +} -- GitLab From 2fd14a95f582fa7ed90f8ab4ae737c5c4441358e Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 17:17:55 +0100 Subject: [PATCH 21/31] product/tc0: add configuration data for MHUv2 driver Provide the details of the MHUv2 channels used for messaging from the application cores to the SCP. Change-Id: I3645670dbe57b50b90f7237aa19f0444454ab937 Signed-off-by: Usama Arif --- product/tc0/include/scp_css_mmap.h | 7 +++++ product/tc0/include/scp_tc0_irq.h | 2 ++ product/tc0/include/scp_tc0_mhu.h | 20 ++++++++++++ product/tc0/scp_ramfw/config_mhu2.c | 49 +++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 product/tc0/include/scp_tc0_mhu.h create mode 100644 product/tc0/scp_ramfw/config_mhu2.c diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index 71fd2b823..9f78f67b7 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -16,6 +16,7 @@ #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_MHU_AP_BASE (SCP_PERIPHERAL_BASE + 0x1000000) #define SCP_PIK_SCP_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE) #define SCP_PIK_CLUSTER_BASE(n) ((SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ @@ -31,4 +32,10 @@ #define SCP_PPU_SYS1_BASE (SCP_PIK_SYSTEM_BASE + 0x5000) #define SCP_PPU_BASE(n) (SCP_PIK_CLUSTER_BASE(n) + 0x2000) + +#define SCP_MHU_SCP_AP_SND_NS_CLUS0 (SCP_MHU_AP_BASE + 0x00000) +#define SCP_MHU_SCP_AP_RCV_NS_CLUS0 (SCP_MHU_AP_BASE + 0x10000) +#define SCP_MHU_SCP_AP_SND_S_CLUS0 (SCP_MHU_AP_BASE + 0x400000) +#define SCP_MHU_SCP_AP_RCV_S_CLUS0 (SCP_MHU_AP_BASE + 0x410000) + #endif /* SCP_CSS_MMAP_H */ diff --git a/product/tc0/include/scp_tc0_irq.h b/product/tc0/include/scp_tc0_irq.h index 0369cc9ae..549bcb759 100644 --- a/product/tc0/include/scp_tc0_irq.h +++ b/product/tc0/include/scp_tc0_irq.h @@ -12,6 +12,8 @@ enum scp_tc0_interrupt { TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ + 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 */ }; #endif /* SCP_TC0_IRQ_H */ diff --git a/product/tc0/include/scp_tc0_mhu.h b/product/tc0/include/scp_tc0_mhu.h new file mode 100644 index 000000000..24dfe4a56 --- /dev/null +++ b/product/tc0/include/scp_tc0_mhu.h @@ -0,0 +1,20 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * MHU module device indexes. + */ + +#ifndef SCP_TC0_MHU_H +#define SCP_TC0_MHU_H + +enum scp_tc0_mhu_device_idx { + SCP_TC0_MHU_DEVICE_IDX_SCP_AP_S_CLUS0, + SCP_TC0_MHU_DEVICE_IDX_SCP_AP_NS_CLUS0, + SCP_TC0_MHU_DEVICE_IDX_COUNT +}; + +#endif /* SCP_TC0_MHU_H */ diff --git a/product/tc0/scp_ramfw/config_mhu2.c b/product/tc0/scp_ramfw/config_mhu2.c new file mode 100644 index 000000000..029c80844 --- /dev/null +++ b/product/tc0/scp_ramfw/config_mhu2.c @@ -0,0 +1,49 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "scp_tc0_irq.h" +#include "scp_css_mmap.h" +#include "scp_tc0_mhu.h" + +#include + +#include +#include +#include + +static const struct fwk_element mhu_element_table[] = { + [SCP_TC0_MHU_DEVICE_IDX_SCP_AP_S_CLUS0] = { + .name = "MHU_SCP_AP_S", + .sub_element_count = 1, + .data = &((struct mod_mhu2_channel_config) { + .irq = MHU_AP_SEC_IRQ, + .recv = SCP_MHU_SCP_AP_RCV_S_CLUS0, + .send = SCP_MHU_SCP_AP_SND_S_CLUS0, + .channel = 0, + }) + }, + [SCP_TC0_MHU_DEVICE_IDX_SCP_AP_NS_CLUS0] = { + .name = "MHU_SCP_AP_NS", + .sub_element_count = 1, + .data = &((struct mod_mhu2_channel_config) { + .irq = MHU_AP_NONSEC_IRQ, + .recv = SCP_MHU_SCP_AP_RCV_NS_CLUS0, + .send = SCP_MHU_SCP_AP_SND_NS_CLUS0, + .channel = 0, + }) + }, + [SCP_TC0_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_mhu2 = { + .get_element_table = mhu_get_element_table, +}; -- GitLab From d8730512c57f17613d89ab9c47fb089d9f5ff399 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Thu, 23 Apr 2020 18:10:21 +0100 Subject: [PATCH 22/31] product/tc0: add configuration data for SCMI and SMT services Provide configuration data to enable support request for SCMI using PSCI and OSPM. Change-Id: I14f0ca12224e1838ae1ef541b5ee814f6bcdb044 Signed-off-by: Usama Arif --- product/tc0/include/scp_software_mmap.h | 17 ++++++ product/tc0/include/tc0_scmi.h | 29 +++++++++ product/tc0/scp_ramfw/config_scmi.c | 80 +++++++++++++++++++++++++ product/tc0/scp_ramfw/config_smt.c | 67 +++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 product/tc0/include/tc0_scmi.h create mode 100644 product/tc0/scp_ramfw/config_scmi.c create mode 100644 product/tc0/scp_ramfw/config_smt.c diff --git a/product/tc0/include/scp_software_mmap.h b/product/tc0/include/scp_software_mmap.h index 58fbff940..12d754063 100644 --- a/product/tc0/include/scp_software_mmap.h +++ b/product/tc0/include/scp_software_mmap.h @@ -28,6 +28,10 @@ #define SCP_AP_SHARED_SECURE_BASE (SCP_TRUSTED_RAM_BASE) #define SCP_AP_SHARED_SECURE_SIZE (4 * FWK_KIB) +/* Non-secure Shared memory between AP and SCP */ +#define SCP_AP_SHARED_NONSECURE_BASE (SCP_NONTRUSTED_RAM_BASE) +#define SCP_AP_SHARED_NONSECURE_SIZE (4 * FWK_KIB) + /* AP Context Area */ #define SCP_AP_CONTEXT_BASE (SCP_AP_SHARED_SECURE_BASE + \ SCP_AP_SHARED_SECURE_SIZE - \ @@ -38,4 +42,17 @@ #define SCP_SDS_MEM_BASE (SCP_AP_SHARED_SECURE_BASE) #define SCP_SDS_MEM_SIZE (3520) +/* 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/tc0/include/tc0_scmi.h b/product/tc0/include/tc0_scmi.h new file mode 100644 index 000000000..fc09eb131 --- /dev/null +++ b/product/tc0/include/tc0_scmi.h @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for SCMI and SMT module configurations. + */ + +#ifndef SCP_TC0_SCMI_H +#define SCP_TC0_SCMI_H + +/* SCMI agent identifiers */ +enum scp_tc0_scmi_agent_id { + /* 0 is reserved for the platform */ + SCP_SCMI_AGENT_ID_OSPM = 1, + SCP_SCMI_AGENT_ID_PSCI, + SCP_SCMI_AGENT_ID_COUNT +}; + +/* SCMI service indexes */ +enum scp_tc0_scmi_service_idx { + SCP_TC0_SCMI_SERVICE_IDX_PSCI, + SCP_TC0_SCMI_SERVICE_IDX_OSPM, + SCP_TC0_SCMI_SERVICE_IDX_COUNT, +}; + +#endif /* SCP_TC0_SCMI_H */ diff --git a/product/tc0/scp_ramfw/config_scmi.c b/product/tc0/scp_ramfw/config_scmi.c new file mode 100644 index 000000000..f1d137719 --- /dev/null +++ b/product/tc0/scp_ramfw/config_scmi.c @@ -0,0 +1,80 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "tc0_scmi.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +static const struct fwk_element service_table[] = { + [SCP_TC0_SCMI_SERVICE_IDX_PSCI] = { + .name = "PSCI", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SMT, + SCP_TC0_SCMI_SERVICE_IDX_PSCI), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), + .scmi_agent_id = SCP_SCMI_AGENT_ID_PSCI, + }), + }, + [SCP_TC0_SCMI_SERVICE_IDX_OSPM] = { + .name = "OSPM", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SMT, + SCP_TC0_SCMI_SERVICE_IDX_OSPM), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_API_IDX_SCMI_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SMT, + MOD_SMT_NOTIFICATION_IDX_INITIALIZED), + .scmi_agent_id = SCP_SCMI_AGENT_ID_OSPM, + }), + }, + [SCP_TC0_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), + .agent_table = agent_table, + .vendor_identifier = "arm", + .sub_vendor_identifier = "arm", + }), +}; diff --git a/product/tc0/scp_ramfw/config_smt.c b/product/tc0/scp_ramfw/config_smt.c new file mode 100644 index 000000000..59b499731 --- /dev/null +++ b/product/tc0/scp_ramfw/config_smt.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "tc0_core.h" +#include "tc0_scmi.h" +#include "scp_tc0_mhu.h" +#include "scp_software_mmap.h" + +#include + +#include +#include +#include +#include + +#include + +static const struct fwk_element smt_element_table[] = { + [SCP_TC0_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_MHU2, + SCP_TC0_MHU_DEVICE_IDX_SCP_AP_S_CLUS0, 0), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU2, 0), + }) + }, + [SCP_TC0_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_MHU2, + SCP_TC0_MHU_DEVICE_IDX_SCP_AP_NS_CLUS0, 0), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU2, 0), + }) + }, + [SCP_TC0_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_TC0_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, + tc0_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, +}; -- GitLab From 72a701d05ab76e41acb1942ea97b6b27dc372f03 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 10:09:45 +0100 Subject: [PATCH 23/31] product/tc0: add configuration data for SCMI power domain There is no specific configuration data to be supplied to the SCMI power domain module. Change-Id: Id90190e9a47c21fb6dbe55f07249f7ae694123d5 Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/config_scmi_power_domain.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_scmi_power_domain.c diff --git a/product/tc0/scp_ramfw/config_scmi_power_domain.c b/product/tc0/scp_ramfw/config_scmi_power_domain.c new file mode 100644 index 000000000..2d344b267 --- /dev/null +++ b/product/tc0/scp_ramfw/config_scmi_power_domain.c @@ -0,0 +1,11 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* No elements, no module configuration data */ +struct fwk_module_config config_scmi_power_domain = { 0 }; -- GitLab From 90026ae9e8b5106701bc2397befe443f02ae20b2 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 10:11:02 +0100 Subject: [PATCH 24/31] product/tc0: add configuration data for SCMI system power Provide the configuration data for SCMI system power module to manage system states. Change-Id: I1c1845f53775a83e3df184d7bbad243de5ccef34 Signed-off-by: Usama Arif --- .../tc0/scp_ramfw/config_scmi_system_power.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_scmi_system_power.c diff --git a/product/tc0/scp_ramfw/config_scmi_system_power.c b/product/tc0/scp_ramfw/config_scmi_system_power.c new file mode 100644 index 000000000..20b225820 --- /dev/null +++ b/product/tc0/scp_ramfw/config_scmi_system_power.c @@ -0,0 +1,18 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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 + }), +}; -- GitLab From 8dff1952d9ba24616504a15e46cff66337385483 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 11:07:25 +0100 Subject: [PATCH 25/31] product/tc0: add configuration data for system power driver The system power driver manages the SYSTOP power domain. Provide the details such as the base adresses of System PPU's and the SOC IRQ's for the same. Change-Id: I0c5880776ae47ab4236edcca608bf967b7d5404e Signed-off-by: Usama Arif --- product/tc0/include/scp_tc0_irq.h | 1 + product/tc0/scp_ramfw/config_system_power.c | 93 +++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_system_power.c diff --git a/product/tc0/include/scp_tc0_irq.h b/product/tc0/include/scp_tc0_irq.h index 549bcb759..3ce18c6fa 100644 --- a/product/tc0/include/scp_tc0_irq.h +++ b/product/tc0/include/scp_tc0_irq.h @@ -11,6 +11,7 @@ #include enum scp_tc0_interrupt { + SOC_WAKEUP0_IRQ = 16, /* SoC Expansion Wakeup */ TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ 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 */ diff --git a/product/tc0/scp_ramfw/config_system_power.c b/product/tc0/scp_ramfw/config_system_power.c new file mode 100644 index 000000000..6ec4d6bc1 --- /dev/null +++ b/product/tc0/scp_ramfw/config_system_power.c @@ -0,0 +1,93 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "tc0_core.h" +#include "scp_tc0_irq.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static const uint8_t system_power_to_sys_ppu0_state[] = { + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_OFF, + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, +}; + +static const uint8_t system_power_to_sys_ppu1_state[] = { + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_ON, + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, +}; + +static struct fwk_element system_power_element_table[] = { + [0] = { + .name = "SYS-PPU-0", + .data = &((struct mod_system_power_dev_config) { + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .sys_state_table = system_power_to_sys_ppu0_state, + }), + }, + + [1] = { + .name = "SYS-PPU-1", + .data = &((struct mod_system_power_dev_config) { + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .sys_state_table = system_power_to_sys_ppu1_state, + }), + }, + + [2] = { 0 }, /* Termination description */ +}; + +static struct mod_system_power_config system_power_config = { + .soc_wakeup_irq = SOC_WAKEUP0_IRQ, + + /* System driver */ + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_TC0_SYSTEM), + .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_TC0_SYSTEM, + MOD_TC0_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + + /* Initial system state */ + .initial_system_power_state = MOD_PD_STATE_OFF, +}; + +static const struct fwk_element *tc0_system_get_element_table( + fwk_id_t unused) +{ + struct mod_system_power_dev_config *dev_config_table; + unsigned int i; + + /* The system PPUs are placed after the core and cluster PPUs */ + unsigned int ppu_idx_base = tc0_core_get_core_count() + + tc0_core_get_cluster_count(); + + for (i = 0; i < (FWK_ARRAY_SIZE(system_power_element_table) - 1); i++) { + dev_config_table = (struct mod_system_power_dev_config *) + system_power_element_table[i].data; + dev_config_table->sys_ppu_id = + fwk_id_build_element_id(fwk_module_id_ppu_v1, ppu_idx_base + i); + } + + return system_power_element_table; +} + +const struct fwk_module_config config_system_power = { + .get_element_table = tc0_system_get_element_table, + .data = &system_power_config, +}; -- GitLab From 0550a00707f1d9422cc6a3f08a26c10f83abf8e4 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 15:56:06 +0100 Subject: [PATCH 26/31] product/tc0: add configuration files for enabling DVFS Provide configuration data for DVFS, PSU and scmi_perf for changing voltage and frequency. DVFS uses a mock psu to set the voltage levels. Change-Id: I0aebb658f2d20225958057ef3f603dcd322209ba Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/config_dvfs.c | 69 ++++++++++++++++++++++++ product/tc0/scp_ramfw/config_mock_psu.c | 38 +++++++++++++ product/tc0/scp_ramfw/config_psu.c | 34 ++++++++++++ product/tc0/scp_ramfw/config_scmi_perf.c | 32 +++++++++++ 4 files changed, 173 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_dvfs.c create mode 100644 product/tc0/scp_ramfw/config_mock_psu.c create mode 100644 product/tc0/scp_ramfw/config_psu.c create mode 100644 product/tc0/scp_ramfw/config_scmi_perf.c diff --git a/product/tc0/scp_ramfw/config_dvfs.c b/product/tc0/scp_ramfw/config_dvfs.c new file mode 100644 index 000000000..94ddabf50 --- /dev/null +++ b/product/tc0/scp_ramfw/config_dvfs.c @@ -0,0 +1,69 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "tc0_timer.h" + +#include + +#include +#include +#include +#include + +static struct mod_dvfs_opp opps[] = { + { + .frequency = 946 * FWK_MHZ, + .voltage = 550, + }, + { + .frequency = 1419 * FWK_MHZ, + .voltage = 650, + }, + { + .frequency = 1893 * FWK_MHZ, + .voltage = 750, + }, + { + .frequency = 2271 * FWK_MHZ, + .voltage = 850, + }, + { + .frequency = 2650 * FWK_MHZ, + .voltage = 950, + }, + { 0 } +}; + +static const struct mod_dvfs_domain_config cpu_group = { + .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), + .alarm_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0, + CONFIG_TIMER_DVFS_CPU), + .notification_id = FWK_ID_NONE_INIT, + .retry_ms = 1, + .latency = 1200, + .sustained_idx = 2, + .opps = opps, +}; + +static const struct fwk_element element_table[] = { + [0] = { + .name = "CPU_GROUP", + .data = &cpu_group, + }, + { 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/tc0/scp_ramfw/config_mock_psu.c b/product/tc0/scp_ramfw/config_mock_psu.c new file mode 100644 index 000000000..f6c8d2653 --- /dev/null +++ b/product/tc0/scp_ramfw/config_mock_psu.c @@ -0,0 +1,38 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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_element_cfg){ + .async_alarm_id = FWK_ID_NONE_INIT, + .async_alarm_api_id = FWK_ID_NONE_INIT, + + .async_response_id = FWK_ID_NONE_INIT, + .async_response_api_id = FWK_ID_NONE_INIT, + + .default_enabled = true, + .default_voltage = 550, + }, + }, + { 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/tc0/scp_ramfw/config_psu.c b/product/tc0/scp_ramfw/config_psu.c new file mode 100644 index 000000000..a10c13fb4 --- /dev/null +++ b/product/tc0/scp_ramfw/config_psu.c @@ -0,0 +1,34 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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_element_cfg) { + .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_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/tc0/scp_ramfw/config_scmi_perf.c b/product/tc0/scp_ramfw/config_scmi_perf.c new file mode 100644 index 000000000..9005ff85e --- /dev/null +++ b/product/tc0/scp_ramfw/config_scmi_perf.c @@ -0,0 +1,32 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "tc0_scmi.h" + +#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, + } + }, +}; + +const struct fwk_module_config config_scmi_perf = { + .get_element_table = NULL, + .data = &((struct mod_scmi_perf_config) { + .domains = &domains, + .fast_channels_alarm_id = FWK_ID_NONE_INIT, + }), +}; -- GitLab From 176eae3789b80d6dafefa12e8726f1d35e17b908 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Tue, 28 Apr 2020 17:24:35 +0100 Subject: [PATCH 27/31] product/tc0: add clock entries for DPU This involves defining the css, pik and system_pll clock entries for DPU, PIXEL_0 and PIXEL_1 as well as DPU pik register definitions used by those clocks. Change-Id: Id836c5e25eaf9816ed27d10eb51cff9d9580bb15 Signed-off-by: Usama Arif --- product/tc0/include/clock_soc.h | 8 ++++ product/tc0/include/dpu_pik.h | 48 +++++++++++++++++++++++ product/tc0/include/scp_css_mmap.h | 3 ++ product/tc0/include/scp_pik.h | 10 +++-- product/tc0/include/scp_soc_mmap.h | 3 ++ product/tc0/scp_ramfw/config_clock.c | 28 +++++++++++++ product/tc0/scp_ramfw/config_css_clock.c | 22 +++++++++++ product/tc0/scp_ramfw/config_pik_clock.c | 24 ++++++++++++ product/tc0/scp_ramfw/config_system_pll.c | 37 +++++++++++++++++ 9 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 product/tc0/include/dpu_pik.h diff --git a/product/tc0/include/clock_soc.h b/product/tc0/include/clock_soc.h index 2ae6f7de6..d129c872b 100644 --- a/product/tc0/include/clock_soc.h +++ b/product/tc0/include/clock_soc.h @@ -20,6 +20,9 @@ enum clock_pll_idx { CLOCK_PLL_IDX_CPU0, CLOCK_PLL_IDX_SYS, CLOCK_PLL_IDX_INTERCONNECT, + CLOCK_PLL_IDX_DPU, + CLOCK_PLL_IDX_PIX0, + CLOCK_PLL_IDX_PIX1, CLOCK_PLL_IDX_COUNT }; @@ -34,6 +37,7 @@ enum clock_pik_idx { CLOCK_PIK_IDX_PCLKSCP, CLOCK_PIK_IDX_SYSPERCLK, CLOCK_PIK_IDX_UARTCLK, + CLOCK_PIK_IDX_DPU, CLOCK_PIK_IDX_COUNT }; @@ -42,6 +46,7 @@ enum clock_pik_idx { */ enum clock_css_idx { CLOCK_CSS_IDX_CPU_GROUP0, + CLOCK_CSS_IDX_DPU, CLOCK_CSS_IDX_COUNT }; @@ -51,6 +56,9 @@ enum clock_css_idx { enum clock_idx { CLOCK_IDX_INTERCONNECT, CLOCK_IDX_CPU_GROUP0, + CLOCK_IDX_DPU, + CLOCK_IDX_PIXEL_0, + CLOCK_IDX_PIXEL_1, CLOCK_IDX_COUNT }; diff --git a/product/tc0/include/dpu_pik.h b/product/tc0/include/dpu_pik.h new file mode 100644 index 000000000..bce45dbb8 --- /dev/null +++ b/product/tc0/include/dpu_pik.h @@ -0,0 +1,48 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DPU_PIK_H +#define DPU_PIK_H + +#include "scp_css_mmap.h" + +#include + +#include + +/*! + * \brief DPU PIK register definitions + */ +struct pik_dpu_reg { + FWK_R uint8_t RESERVED0[0x830]; + FWK_RW uint32_t ACLKDP_CTRL; + FWK_RW uint32_t ACLKDP_DIV1; + FWK_RW uint32_t ACLKDP_DIV2; + uint8_t RESERVED3[0xA00 - 0x83C]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLR; + uint8_t RESERVED4[0xFC0 - 0xA0C]; + FWK_RW 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; +}; + +#define DPU_PIK_PTR ((struct pik_dpu_reg *) SCP_PIK_DPU_BASE) + +#endif /* DPU_PIK_H */ diff --git a/product/tc0/include/scp_css_mmap.h b/product/tc0/include/scp_css_mmap.h index 9f78f67b7..f9f7975b9 100644 --- a/product/tc0/include/scp_css_mmap.h +++ b/product/tc0/include/scp_css_mmap.h @@ -24,6 +24,9 @@ #define SCP_PIK_SYSTEM_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + 0x40000) +#define SCP_PIK_DPU_BASE (SCP_ELEMENT_MANAGEMENT_PERIPHERAL_BASE \ + + 0x860000) + #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) diff --git a/product/tc0/include/scp_pik.h b/product/tc0/include/scp_pik.h index 9ce9d6f8a..a90efda9d 100644 --- a/product/tc0/include/scp_pik.h +++ b/product/tc0/include/scp_pik.h @@ -93,10 +93,12 @@ struct pik_scp_reg { 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_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_0_DISPLAYPLLLOCK UINT32_C(0x00000040) + #define PLL_STATUS_CPUPLLLOCK(CPU) ((uint32_t)(1 << (CPU % 32))) diff --git a/product/tc0/include/scp_soc_mmap.h b/product/tc0/include/scp_soc_mmap.h index 9cf53d538..e59924c3f 100644 --- a/product/tc0/include/scp_soc_mmap.h +++ b/product/tc0/include/scp_soc_mmap.h @@ -13,6 +13,9 @@ #define SCP_PLL_BASE (SCP_SOC_EXPANSION3_BASE + 0x03000000) #define SCP_PLL_SYSPLL (SCP_PLL_BASE + 0x00000000) +#define SCP_PLL_DISPLAY (SCP_PLL_BASE + 0x00000014) +#define SCP_PLL_PIX0 (SCP_PLL_BASE + 0x00000018) +#define SCP_PLL_PIX1 (SCP_PLL_BASE + 0x0000001C) #define SCP_PLL_INTERCONNECT (SCP_PLL_BASE + 0x00000020) #define SCP_PLL_CPU0 (SCP_PLL_BASE + 0x00000100) diff --git a/product/tc0/scp_ramfw/config_clock.c b/product/tc0/scp_ramfw/config_clock.c index 0b6c5d64c..e219e8d6c 100644 --- a/product/tc0/scp_ramfw/config_clock.c +++ b/product/tc0/scp_ramfw/config_clock.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,33 @@ static const struct fwk_element clock_dev_desc_table[] = { MOD_CSS_CLOCK_API_TYPE_CLOCK), }), }, + [CLOCK_IDX_DPU] = { + .name = "DPU", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, + CLOCK_CSS_IDX_DPU), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK, + MOD_CSS_CLOCK_API_TYPE_CLOCK), + }), + }, + [CLOCK_IDX_PIXEL_0] = { + .name = "PIXEL_0", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + CLOCK_PLL_IDX_PIX0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + MOD_SYSTEM_PLL_API_TYPE_DEFAULT), + }), + }, + [CLOCK_IDX_PIXEL_1] = { + .name = "PIXEL_1", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + CLOCK_PLL_IDX_PIX1), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + MOD_SYSTEM_PLL_API_TYPE_DEFAULT), + }), + }, { 0 }, /* Termination description. */ }; diff --git a/product/tc0/scp_ramfw/config_css_clock.c b/product/tc0/scp_ramfw/config_css_clock.c index 964ae1647..96e25c44b 100644 --- a/product/tc0/scp_ramfw/config_css_clock.c +++ b/product/tc0/scp_ramfw/config_css_clock.c @@ -74,6 +74,10 @@ static const fwk_id_t member_table_cpu_group_0[] = { FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0), }; +static const fwk_id_t member_table_dpu[] = { + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_DPU), +}; + static const struct fwk_element css_clock_element_table[] = { [CLOCK_CSS_IDX_CPU_GROUP0] = { .name = "CPU_GROUP_0", @@ -94,6 +98,24 @@ static const struct fwk_element css_clock_element_table[] = { .modulation_supported = true, }), }, + [CLOCK_CSS_IDX_DPU] = { + .name = "DPU", + .data = &((struct mod_css_clock_dev_config) { + .clock_type = MOD_CSS_CLOCK_TYPE_NON_INDEXED, + .clock_default_source = MOD_PIK_CLOCK_ACLKDPU_SOURCE_DISPLAYPLLCLK, + .clock_switching_source = MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSREFCLK, + .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + CLOCK_PLL_IDX_DPU), + .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL, + MOD_SYSTEM_PLL_API_TYPE_DEFAULT), + .member_table = member_table_dpu, + .member_count = FWK_ARRAY_SIZE(member_table_dpu), + .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK, + MOD_PIK_CLOCK_API_TYPE_CSS), + .initial_rate = 600 * FWK_MHZ, + .modulation_supported = false, + }), + }, [CLOCK_CSS_IDX_COUNT] = { 0 }, /* Termination description. */ }; diff --git a/product/tc0/scp_ramfw/config_pik_clock.c b/product/tc0/scp_ramfw/config_pik_clock.c index 70ec66aa3..f937c5a71 100644 --- a/product/tc0/scp_ramfw/config_pik_clock.c +++ b/product/tc0/scp_ramfw/config_pik_clock.c @@ -7,6 +7,7 @@ #include "clock_soc.h" #include "cpu_pik.h" +#include "dpu_pik.h" #include "scp_pik.h" #include "system_pik.h" @@ -83,6 +84,15 @@ static const struct mod_pik_clock_rate rate_table_uartclk[] = { }, }; +static struct mod_pik_clock_rate rate_table_dpu[] = { + { + .rate = 600 * FWK_MHZ, + .source = MOD_PIK_CLOCK_ACLKDPU_SOURCE_DISPLAYPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, /* Rate adjusted via display PLL */ + }, +}; + static const struct fwk_element pik_clock_element_table[] = { [CLOCK_PIK_IDX_CLUS0_CPU0] = { @@ -169,6 +179,20 @@ static const struct fwk_element pik_clock_element_table[] = { .initial_rate = 2000 * FWK_MHZ, }), }, + [CLOCK_PIK_IDX_DPU] = { + .name = "DPU", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = true, + .control_reg = &DPU_PIK_PTR->ACLKDP_CTRL, + .divsys_reg = &DPU_PIK_PTR->ACLKDP_DIV1, + .divext_reg = &DPU_PIK_PTR->ACLKDP_DIV2, + .rate_table = rate_table_dpu, + .rate_count = FWK_ARRAY_SIZE(rate_table_dpu), + .initial_rate = 600 * FWK_MHZ, + .defer_initialization = true, + }), + }, [CLOCK_PIK_IDX_COUNT] = { 0 }, /* Termination description. */ }; diff --git a/product/tc0/scp_ramfw/config_system_pll.c b/product/tc0/scp_ramfw/config_system_pll.c index c9a8408f2..15232c683 100644 --- a/product/tc0/scp_ramfw/config_system_pll.c +++ b/product/tc0/scp_ramfw/config_system_pll.c @@ -53,6 +53,43 @@ static const struct fwk_element system_pll_element_table[] = { .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, }), }, + [CLOCK_PLL_IDX_DPU] = { + .name = "DPU_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_DISPLAY, + .status_reg = (void *)&SCP_PIK_PTR->PLL_STATUS[0], + .lock_flag_mask = PLL_STATUS_0_DISPLAYPLLLOCK, + .initial_rate = 600 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + .defer_initialization = false, + }), + }, + [CLOCK_PLL_IDX_PIX0] = { + .name = "PIX0_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_PIX0, + .status_reg = NULL, + .initial_rate = 594 * FWK_MHZ, + .min_rate = 12500 * FWK_KHZ, + .max_rate = 594 * FWK_MHZ, + .min_step = 25 * FWK_KHZ, + .defer_initialization = false, + }), + }, + [CLOCK_PLL_IDX_PIX1] = { + .name = "PIX1_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_PIX1, + .status_reg = NULL, + .initial_rate = 594 * FWK_MHZ, + .min_rate = 12500 * FWK_KHZ, + .max_rate = 594 * FWK_MHZ, + .min_step = 25 * FWK_KHZ, + .defer_initialization = false, + }), + }, [CLOCK_PLL_IDX_COUNT] = { 0 }, /* Termination description. */ }; -- GitLab From 010778e5ef9c9b34044e5c756d453e86a6dda1a2 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 29 Apr 2020 10:03:49 +0100 Subject: [PATCH 28/31] product/tc0: add configuration data for scmi_clk for DPU This provides the DPU, PIXEL_0 and PIXEL_1 clock. Change-Id: I19ba4bfbdb406a28ed34a221f80b13152b6116f5 Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/config_scmi_clock.c | 65 +++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 product/tc0/scp_ramfw/config_scmi_clock.c diff --git a/product/tc0/scp_ramfw/config_scmi_clock.c b/product/tc0/scp_ramfw/config_scmi_clock.c new file mode 100644 index 000000000..a2b4a4b7f --- /dev/null +++ b/product/tc0/scp_ramfw/config_scmi_clock.c @@ -0,0 +1,65 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "clock_soc.h" +#include "tc0_scmi.h" + +#include + +#include +#include +#include +#include + +static const struct mod_scmi_clock_device agent_device_table_ospm[] = { + { + /* DPU */ + .element_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_DPU), + .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | + MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | + MOD_SCMI_CLOCK_PERM_GET_RATE | + MOD_SCMI_CLOCK_PERM_SET_RATE | + MOD_SCMI_CLOCK_PERM_SET_CONFIG, + }, + { + /* PIXEL_0 */ + .element_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_PIXEL_0), + .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | + MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | + MOD_SCMI_CLOCK_PERM_GET_RATE | + MOD_SCMI_CLOCK_PERM_SET_RATE | + MOD_SCMI_CLOCK_PERM_SET_CONFIG, + }, + { + /* PIXEL_1 */ + .element_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_IDX_PIXEL_1), + .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES | + MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES | + MOD_SCMI_CLOCK_PERM_GET_RATE | + MOD_SCMI_CLOCK_PERM_SET_RATE, + }, +}; + +static const struct mod_scmi_clock_agent + agent_table[SCP_SCMI_AGENT_ID_COUNT] = { + [SCP_SCMI_AGENT_ID_PSCI] = { 0 /* No access */ }, + [SCP_SCMI_AGENT_ID_OSPM] = { + .device_table = agent_device_table_ospm, + .device_count = FWK_ARRAY_SIZE(agent_device_table_ospm), + }, +}; + +const struct fwk_module_config config_scmi_clock = { + .data = &((struct mod_scmi_clock_config) { + .max_pending_transactions = 0, + .agent_table = agent_table, + .agent_count = FWK_ARRAY_SIZE(agent_table), + }), +}; -- GitLab From 95793e6add5e694b2003a5a6fcf956abdf1c3eb6 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 18:45:47 +0100 Subject: [PATCH 29/31] product/tc0: add TC0 system module The system module sets up the SCMI services and SDS messaging stack. Change-Id: Ia01cec8583c67dafcc0847ec827d2d55dd8a3499 Signed-off-by: Usama Arif --- product/tc0/include/scp_tc0_irq.h | 9 + .../tc0_system/include/mod_tc0_system.h | 64 ++++ product/tc0/module/tc0_system/src/Makefile | 11 + .../module/tc0_system/src/mod_tc0_system.c | 330 ++++++++++++++++++ 4 files changed, 414 insertions(+) create mode 100644 product/tc0/module/tc0_system/include/mod_tc0_system.h create mode 100644 product/tc0/module/tc0_system/src/Makefile create mode 100644 product/tc0/module/tc0_system/src/mod_tc0_system.c diff --git a/product/tc0/include/scp_tc0_irq.h b/product/tc0/include/scp_tc0_irq.h index 3ce18c6fa..1555e887e 100644 --- a/product/tc0/include/scp_tc0_irq.h +++ b/product/tc0/include/scp_tc0_irq.h @@ -15,6 +15,15 @@ enum scp_tc0_interrupt { TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */ 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 */ + 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 */ }; #endif /* SCP_TC0_IRQ_H */ diff --git a/product/tc0/module/tc0_system/include/mod_tc0_system.h b/product/tc0/module/tc0_system/include/mod_tc0_system.h new file mode 100644 index 000000000..53a2bb926 --- /dev/null +++ b/product/tc0/module/tc0_system/include/mod_tc0_system.h @@ -0,0 +1,64 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * TC0 System Support + */ + +#ifndef MOD_TC0_SYSTEM_H +#define MOD_TC0_SYSTEM_H + +#include + +/*! + * \addtogroup GroupTC0Module TC0 Product Modules + * @{ + */ + +/*! + * \defgroup GroupTC0System TC0 System Support + * @{ + */ + +/*! + * \brief Additional TC0 system power states. + */ +enum mod_tc0_system_power_states { + MOD_TC0_SYSTEM_POWER_STATE_SLEEP0 = MOD_PD_STATE_COUNT, + MOD_TC0_SYSTEM_POWER_STATE_SLEEP1, + MOD_TC0_SYSTEM_POWER_STATE_COUNT +}; + +/*! + * \brief System power state masks. + */ +enum mod_tc0_system_power_state_masks { + MOD_TC0_SYSTEM_POWER_STATE_SLEEP0_MASK = + (1 << MOD_TC0_SYSTEM_POWER_STATE_SLEEP0), + MOD_TC0_SYSTEM_POWER_STATE_SLEEP1_MASK = + (1 << MOD_TC0_SYSTEM_POWER_STATE_SLEEP1), +}; + +/*! + * \brief Indices of the interfaces exposed by the module. + */ +enum mod_tc0_system_api_idx { + /*! API index for the driver interface of the SYSTEM POWER module */ + MOD_TC0_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER, + + /*! Number of exposed interfaces */ + MOD_TC0_SYSTEM_API_COUNT +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_TC0_SYSTEM_H */ diff --git a/product/tc0/module/tc0_system/src/Makefile b/product/tc0/module/tc0_system/src/Makefile new file mode 100644 index 000000000..52f7cc4a9 --- /dev/null +++ b/product/tc0/module/tc0_system/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := TC0 SYSTEM +BS_LIB_SOURCES = mod_tc0_system.c + +include $(BS_DIR)/lib.mk diff --git a/product/tc0/module/tc0_system/src/mod_tc0_system.c b/product/tc0/module/tc0_system/src/mod_tc0_system.c new file mode 100644 index 000000000..f646f3478 --- /dev/null +++ b/product/tc0/module/tc0_system/src/mod_tc0_system.c @@ -0,0 +1,330 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * TC0 System Support. + */ + +#include "clock_soc.h" +#include "tc0_core.h" +#include "tc0_sds.h" +#include "tc0_scmi.h" +#include "scp_tc0_irq.h" +#include "scp_pik.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + + +/* SCMI services required to enable the messaging stack */ +static unsigned int scmi_notification_table[] = { + SCP_TC0_SCMI_SERVICE_IDX_PSCI, +}; + +/* Module context */ +struct tc0_system_ctx { + /* Pointer to the SCP PIK registers */ + struct pik_scp_reg *pik_scp_reg; + + /* 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; + + /* SDS API pointer */ + const struct mod_sds_api *sds_api; +}; + +struct tc0_system_isr { + unsigned int interrupt; + void (*handler)(void); +}; + +static struct tc0_system_ctx tc0_system_ctx; +const struct fwk_module_config config_tc0_system = { 0 }; + +static const uint32_t feature_flags = (TC0_SDS_FEATURE_FIRMWARE_MASK | + TC0_SDS_FEATURE_DMC_MASK | + TC0_SDS_FEATURE_MESSAGING_MASK); + +static fwk_id_t sds_feature_availability_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SDS, 1); + +/* + * SCMI Messaging stack + */ + +static int messaging_stack_ready(void) +{ + const struct mod_sds_structure_desc *sds_structure_desc = + fwk_module_get_data(sds_feature_availability_id); + + /* + * Write SDS Feature Availability to signal the completion of the messaging + * stack + */ + return tc0_system_ctx.sds_api->struct_write( + sds_structure_desc->id, + 0, + (void *)(&feature_flags), + sds_structure_desc->size); +} + +/* + * 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) >= tc0_core_get_core_count()) + continue; + + tc0_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, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[0]); + ppu_cores_isr(128, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[4]); +} + +static void ppu_cores_isr_1(void) +{ + ppu_cores_isr(32, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[1]); + ppu_cores_isr(160, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[5]); +} + +static void ppu_cores_isr_2(void) +{ + ppu_cores_isr(64, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[2]); + ppu_cores_isr(192, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[6]); +} + +static void ppu_cores_isr_3(void) +{ + ppu_cores_isr(96, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[3]); + ppu_cores_isr(224, + tc0_system_ctx.pik_scp_reg->CPU_PPU_INT_STATUS[7]); +} + +static void ppu_clusters_isr(void) +{ + uint32_t status = tc0_system_ctx.pik_scp_reg->CLUS_PPU_INT_STATUS; + unsigned int cluster_idx; + + while (status != 0) { + cluster_idx = __builtin_ctz(status); + + tc0_system_ctx.ppu_v1_isr_api->ppu_interrupt_handler( + FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, + tc0_core_get_core_count() + cluster_idx)); + + status &= ~(1 << cluster_idx); + } +} + +/* + * PPU Interrupt Service Routine table + */ + +static struct tc0_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's driver API + */ + +static int tc0_system_shutdown( + enum mod_pd_system_shutdown system_shutdown) +{ + NVIC_SystemReset(); + + return FWK_E_DEVICE; +} + +static const struct mod_system_power_driver_api + tc0_system_system_power_driver_api = { + .system_shutdown = tc0_system_shutdown, +}; + +/* + * Functions fulfilling the framework's module interface + */ + +static int tc0_system_mod_init(fwk_id_t module_id, + unsigned int unused, + const void *unused2) +{ + int status; + unsigned int idx; + struct tc0_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; + } + + tc0_system_ctx.pik_scp_reg = + (struct pik_scp_reg *)SCP_PIK_SCP_BASE; + + return FWK_SUCCESS; +} + +static int tc0_system_bind(fwk_id_t id, unsigned int round) +{ + int status; + + if (round > 0) + return FWK_SUCCESS; + + 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), + &tc0_system_ctx.mod_pd_restricted_api); + if (status != FWK_SUCCESS) + return status; + + status = 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), + &tc0_system_ctx.ppu_v1_isr_api); + if (status != FWK_SUCCESS) + return status; + + return fwk_module_bind(fwk_module_id_sds, + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &tc0_system_ctx.sds_api); +} + +static int tc0_system_process_bind_request(fwk_id_t requester_id, + fwk_id_t pd_id, fwk_id_t api_id, const void **api) +{ + *api = &tc0_system_system_power_driver_api; + return FWK_SUCCESS; +} + +static int tc0_system_start(fwk_id_t id) +{ + int status; + unsigned int i; + + /* + * Subscribe to these SCMI channels in order to know when they have all + * initialized. + * At that point we can consider the SCMI stack to be initialized from + * the point of view of the PSCI agent. + */ + for (i = 0; i < FWK_ARRAY_SIZE(scmi_notification_table); i++) { + status = fwk_notification_subscribe( + mod_scmi_notification_id_initialized, + fwk_id_build_element_id(fwk_module_id_scmi, + scmi_notification_table[i]), + id); + if (status != FWK_SUCCESS) + return status; + } + + /* + * Subscribe to the SDS initialized notification so we can correctly let the + * PSCI agent know that the SCMI stack is initialized. + */ + status = fwk_notification_subscribe( + mod_sds_notification_id_initialized, + fwk_module_id_sds, + id); + if (status != FWK_SUCCESS) + return status; + + return + tc0_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 tc0_system_process_notification(const struct fwk_event *event, + struct fwk_event *resp_event) +{ + static unsigned int scmi_notification_count = 0; + static bool sds_notification_received = false; + + assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); + + if (fwk_id_is_equal(event->id, + mod_scmi_notification_id_initialized)) { + scmi_notification_count++; + } else if (fwk_id_is_equal(event->id, + mod_sds_notification_id_initialized)) { + sds_notification_received = true; + } else + return FWK_E_PARAM; + + if ((scmi_notification_count == FWK_ARRAY_SIZE(scmi_notification_table)) && + sds_notification_received) { + messaging_stack_ready(); + + scmi_notification_count = 0; + sds_notification_received = false; + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_tc0_system = { + .name = "TC0_SYSTEM", + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = MOD_TC0_SYSTEM_API_COUNT, + .init = tc0_system_mod_init, + .bind = tc0_system_bind, + .process_bind_request = tc0_system_process_bind_request, + .process_notification = tc0_system_process_notification, + .start = tc0_system_start, +}; -- GitLab From b5616318f28a13aeada02e9578488b2914abd08f Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 18:49:28 +0100 Subject: [PATCH 30/31] product/tc0: add build support for SCP RAM firmware Add the makefile to build the RAM firmware and the corresponding linker script. Change-Id: Ie990e07905900dc66af50832858b03510e3208aa Signed-off-by: Usama Arif --- product/tc0/scp_ramfw/firmware.mk | 65 ++++++++++++++++++++++++++++++ product/tc0/scp_ramfw/fmw_memory.h | 31 ++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 product/tc0/scp_ramfw/firmware.mk create mode 100644 product/tc0/scp_ramfw/fmw_memory.h diff --git a/product/tc0/scp_ramfw/firmware.mk b/product/tc0/scp_ramfw/firmware.mk new file mode 100644 index 000000000..a7a9dd96f --- /dev/null +++ b/product/tc0/scp_ramfw/firmware.mk @@ -0,0 +1,65 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, 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_NOTIFICATION_COUNT := 128 + +BS_FIRMWARE_MODULES := \ + armv7m_mpu \ + pl011 \ + log \ + ppu_v1 \ + system_power \ + mhu2 \ + smt \ + scmi \ + sds \ + system_pll \ + pik_clock \ + css_clock \ + clock \ + power_domain \ + scmi_power_domain \ + scmi_system_power \ + dvfs \ + scmi_clock \ + scmi_perf \ + gtimer \ + timer \ + mock_psu \ + psu \ + tc0_system + +BS_FIRMWARE_SOURCES := \ + config_system_power.c \ + rtx_config.c \ + config_armv7m_mpu.c \ + config_pl011.c \ + config_log.c \ + config_power_domain.c \ + config_ppu_v1.c \ + config_mhu2.c \ + config_smt.c \ + config_scmi.c \ + config_sds.c \ + config_scmi_system_power.c \ + config_scmi_clock.c \ + config_scmi_perf.c \ + config_gtimer.c \ + config_timer.c \ + config_dvfs.c \ + config_psu.c \ + config_mock_psu.c \ + config_system_pll.c \ + config_pik_clock.c \ + config_css_clock.c \ + config_clock.c \ + config_scmi_power_domain.c + +include $(BS_DIR)/firmware.mk diff --git a/product/tc0/scp_ramfw/fmw_memory.h b/product/tc0/scp_ramfw/fmw_memory.h new file mode 100644 index 000000000..01ff8e4f2 --- /dev/null +++ b/product/tc0/scp_ramfw/fmw_memory.h @@ -0,0 +1,31 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, 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_H +#define FMW_MEMORY_H + +#include "scp_mmap.h" +#include "scp_software_mmap.h" + +#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * RAM instruction memory + */ +#define FIRMWARE_MEM0_SIZE SCP_ITC_RAM_SIZE +#define FIRMWARE_MEM0_BASE SCP_ITC_RAM_BASE + +/* + * RAM data memory + */ +#define FIRMWARE_MEM1_SIZE SCP_DTC_RAM_SIZE +#define FIRMWARE_MEM1_BASE SCP_DTC_RAM_BASE + +#endif /* FMW_MEMORY_H */ -- GitLab From 5a87c21eb46e72f404441a15de9b61e3327479ab Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 24 Apr 2020 18:50:10 +0100 Subject: [PATCH 31/31] product/tc0: add the product.mk file for Total Compute (TC0) platform Add the product.mk file for Total Compute (TC0) platform and make it available to the scp build system as a product. Change-Id: Id3368c24a8a98f696c88dc46ac4536761360bb9e Signed-off-by: Usama Arif --- product/tc0/product.mk | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 product/tc0/product.mk diff --git a/product/tc0/product.mk b/product/tc0/product.mk new file mode 100644 index 000000000..35170cd45 --- /dev/null +++ b/product/tc0/product.mk @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_PRODUCT_NAME := tc0 +BS_FIRMWARE_LIST := scp_romfw \ + scp_ramfw \ No newline at end of file -- GitLab