aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Quigley <jim.quigley@arm.com>2020-02-17 15:47:51 +0000
committerChris Kay <chris@cjkay.com>2020-02-24 19:56:00 +0000
commit3970a6f995d1909b29b83ff9542a7433ce8d6946 (patch)
tree1206b509bb6c2735212b8b46da3cf6f822e21769
parent358c8140980c6c09237cf657d29eb4b641bf4b34 (diff)
sgm776: Add sgm776 platform
This patch adds support for the sgm776 platform. Change-Id: I62db113e37b1e688957a982c13f13c58cf995a4c Signed-off-by: Jim Quigley <jim.quigley@arm.com>
-rw-r--r--module/dmc500/include/mod_dmc500.h568
-rw-r--r--module/dmc500/src/Makefile11
-rw-r--r--module/dmc500/src/mod_dmc500.c390
-rw-r--r--product/sgm776/include/fmw_cmsis.h30
-rw-r--r--product/sgm776/include/sgm776_core.h15
-rw-r--r--product/sgm776/include/sgm776_irq.h210
-rw-r--r--product/sgm776/include/sgm776_mhu.h21
-rw-r--r--product/sgm776/include/sgm776_mmap.h96
-rw-r--r--product/sgm776/include/sgm776_mmap_scp.h19
-rw-r--r--product/sgm776/include/sgm776_pik.h29
-rw-r--r--product/sgm776/include/sgm776_pik_cpu.h94
-rw-r--r--product/sgm776/include/sgm776_pik_debug.h65
-rw-r--r--product/sgm776/include/sgm776_pik_dpu.h43
-rw-r--r--product/sgm776/include/sgm776_pik_gpu.h45
-rw-r--r--product/sgm776/include/sgm776_pik_scp.h61
-rw-r--r--product/sgm776/include/sgm776_pik_system.h69
-rw-r--r--product/sgm776/include/sgm776_pik_vpu.h43
-rw-r--r--product/sgm776/include/sgm776_scmi.h29
-rw-r--r--product/sgm776/include/sgm776_sds.h149
-rw-r--r--product/sgm776/include/sgm776_sid.h16
-rw-r--r--product/sgm776/include/software_mmap.h128
-rw-r--r--product/sgm776/include/system_clock.h16
-rw-r--r--product/sgm776/include/system_mmap.h61
-rw-r--r--product/sgm776/include/system_mmap_scp.h21
-rw-r--r--product/sgm776/module/sgm776_system/include/mod_sgm776_system.h44
-rw-r--r--product/sgm776/module/sgm776_system/src/Makefile11
-rw-r--r--product/sgm776/module/sgm776_system/src/mod_sgm776_system.c59
-rw-r--r--product/sgm776/product.mk14
-rw-r--r--product/sgm776/scp_ramfw/RTX_Config.h56
-rw-r--r--product/sgm776/scp_ramfw/clock_devices.h26
-rw-r--r--product/sgm776/scp_ramfw/config_clock.c118
-rw-r--r--product/sgm776/scp_ramfw/config_css_clock.c354
-rw-r--r--product/sgm776/scp_ramfw/config_ddr_phy500.c63
-rw-r--r--product/sgm776/scp_ramfw/config_dmc500.c221
-rw-r--r--product/sgm776/scp_ramfw/config_dvfs.c128
-rw-r--r--product/sgm776/scp_ramfw/config_dvfs.h18
-rw-r--r--product/sgm776/scp_ramfw/config_log.c63
-rw-r--r--product/sgm776/scp_ramfw/config_mhu.c57
-rw-r--r--product/sgm776/scp_ramfw/config_mock_psu.c75
-rw-r--r--product/sgm776/scp_ramfw/config_pik_clock.c305
-rw-r--r--product/sgm776/scp_ramfw/config_power_domain.c250
-rw-r--r--product/sgm776/scp_ramfw/config_power_domain.h20
-rw-r--r--product/sgm776/scp_ramfw/config_ppu_v1.c174
-rw-r--r--product/sgm776/scp_ramfw/config_ppu_v1.h21
-rw-r--r--product/sgm776/scp_ramfw/config_psu.c57
-rw-r--r--product/sgm776/scp_ramfw/config_scmi.c86
-rw-r--r--product/sgm776/scp_ramfw/config_scmi_apcore.c31
-rw-r--r--product/sgm776/scp_ramfw/config_scmi_clock.c70
-rw-r--r--product/sgm776/scp_ramfw/config_scmi_perf.c43
-rw-r--r--product/sgm776/scp_ramfw/config_scmi_system_power.c19
-rw-r--r--product/sgm776/scp_ramfw/config_sds.c60
-rw-r--r--product/sgm776/scp_ramfw/config_sensor.c75
-rw-r--r--product/sgm776/scp_ramfw/config_smt.c82
-rw-r--r--product/sgm776/scp_ramfw/config_system_pll.c117
-rw-r--r--product/sgm776/scp_ramfw/config_system_power.c99
-rw-r--r--product/sgm776/scp_ramfw/config_timer.c71
-rw-r--r--product/sgm776/scp_ramfw/firmware.mk73
-rw-r--r--product/sgm776/scp_ramfw/fmw_memory.ld.S21
-rw-r--r--product/sgm776/scp_ramfw/rtx_config.c79
-rw-r--r--product/sgm776/scp_romfw/clock_devices.h28
-rw-r--r--product/sgm776/scp_romfw/config_bootloader.c26
-rw-r--r--product/sgm776/scp_romfw/config_clock.c117
-rw-r--r--product/sgm776/scp_romfw/config_css_clock.c186
-rw-r--r--product/sgm776/scp_romfw/config_log.c62
-rw-r--r--product/sgm776/scp_romfw/config_msys_rom.c23
-rw-r--r--product/sgm776/scp_romfw/config_pik_clock.c341
-rw-r--r--product/sgm776/scp_romfw/config_ppu_v1.c77
-rw-r--r--product/sgm776/scp_romfw/config_sds.c126
-rw-r--r--product/sgm776/scp_romfw/config_system_pll.c79
-rw-r--r--product/sgm776/scp_romfw/config_timer.c68
-rw-r--r--product/sgm776/scp_romfw/firmware.mk45
-rw-r--r--product/sgm776/scp_romfw/fmw_memory.ld.S36
-rw-r--r--product/sgm776/src/config_sid.c50
-rw-r--r--product/sgm776/src/sgm776_core.c14
-rwxr-xr-xtools/ci.py34
75 files changed, 6601 insertions, 0 deletions
diff --git a/module/dmc500/include/mod_dmc500.h b/module/dmc500/include/mod_dmc500.h
new file mode 100644
index 00000000..d611af83
--- /dev/null
+++ b/module/dmc500/include/mod_dmc500.h
@@ -0,0 +1,568 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * DMC-500 module.
+ */
+
+#ifndef MOD_DMC500_H
+#define MOD_DMC500_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_log.h>
+#include <mod_timer.h>
+
+/*!
+ * \addtogroup GroupModules Modules
+ * @{
+ */
+
+/*!
+ * \addtogroup GroupDMC DMC-500 Driver
+ *
+ * \details Please consult the Arm CoreLink DMC-500 Dynamic Memory Controller
+ * Technical Reference Manual for details on the specific registers that
+ * are programmed here.
+ * @{
+ */
+
+/*!
+ * \brief DMC-500 register definitions
+ */
+struct mod_dmc500_reg {
+ /*!
+ * \cond
+ * @{
+ */
+ FWK_R uint32_t SI0_SI_STATUS;
+ FWK_R uint32_t SI0_SI_INTERRUPT_STATUS;
+ FWK_R uint32_t SI0_TZ_FAIL_ADDRESS_LOW;
+ FWK_R uint32_t SI0_TZ_FAIL_ADDRESS_HIGH;
+ FWK_R uint32_t SI0_TZ_FAIL_CONTROL;
+ FWK_R uint32_t SI0_TZ_FAIL_ID;
+ FWK_R uint32_t SI0_PMU_REQ_INT_INFO;
+ FWK_RW uint32_t SI0_PMU_REQ_COUNT0;
+ FWK_RW uint32_t SI0_PMU_REQ_COUNT1;
+ FWK_RW uint32_t SI0_PMU_REQ_COUNT2;
+ FWK_RW uint32_t SI0_PMU_REQ_COUNT3;
+ FWK_RW uint32_t SI0_PMU_SCLK_COUNT_COUNT;
+ FWK_RW uint32_t SI0_SI_STATE_CONTROL;
+ FWK_W uint32_t SI0_SI_FLUSH_CONTROL;
+ FWK_RW uint32_t ADDRESS_CONTROL;
+ FWK_RW uint32_t DECODE_CONTROL;
+ FWK_RW uint32_t ADDRESS_MAP;
+ FWK_RW uint32_t RANK_REMAP_CONTROL;
+ FWK_RW uint32_t SI0_SI_INTERRUPT_CONTROL;
+ FWK_W uint32_t SI0_SI_INTERRUPT_CLR;
+ FWK_RW uint32_t TZ_ACTION;
+ FWK_R uint32_t SI0_TZ_REGION_BASE_LOW_0;
+ FWK_R uint32_t SI0_TZ_REGION_BASE_HIGH_0;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_0;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_0;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_0;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_0;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_1;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_1;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_1;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_1;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_1;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_1;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_2;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_2;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_2;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_2;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_2;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_2;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_3;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_3;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_3;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_3;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_3;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_3;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_4;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_4;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_4;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_4;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_4;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_4;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_5;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_5;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_5;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_5;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_5;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_5;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_6;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_6;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_6;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_6;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_6;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_6;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_7;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_7;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_7;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_7;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_7;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_7;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_LOW_8;
+ FWK_RW uint32_t SI0_TZ_REGION_BASE_HIGH_8;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_LOW_8;
+ FWK_RW uint32_t SI0_TZ_REGION_TOP_HIGH_8;
+ FWK_RW uint32_t SI0_TZ_REGION_ATTRIBUTES_8;
+ FWK_RW uint32_t SI0_TZ_REGION_ID_ACCESS_8;
+ FWK_RW uint32_t SI0_PMU_REQ_CONTROL;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MASK_0;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MATCH_0;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MASK_1;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MATCH_1;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MASK_2;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MATCH_2;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MASK_3;
+ FWK_RW uint32_t SI0_PMU_REQ_ATTRIBUTE_MATCH_3;
+ FWK_RW uint32_t SI0_THRESHOLD_CONTROL;
+ uint8_t RESERVED0[0x200 - 0x154];
+ FWK_R uint32_t SI1_SI_STATUS;
+ FWK_R uint32_t SI1_SI_INTERRUPT_STATUS;
+ FWK_R uint32_t SI1_TZ_FAIL_ADDRESS_LOW;
+ FWK_R uint32_t SI1_TZ_FAIL_ADDRESS_HIGH;
+ FWK_R uint32_t SI1_TZ_FAIL_CONTROL;
+ FWK_R uint32_t SI1_TZ_FAIL_ID;
+ FWK_R uint32_t SI1_PMU_REQ_INT_INFO;
+ FWK_RW uint32_t SI1_PMU_REQ_COUNT0;
+ FWK_RW uint32_t SI1_PMU_REQ_COUNT1;
+ FWK_RW uint32_t SI1_PMU_REQ_COUNT2;
+ FWK_RW uint32_t SI1_PMU_REQ_COUNT3;
+ FWK_RW uint32_t SI1_PMU_SCLK_COUNT_COUNT;
+ FWK_RW uint32_t SI1_SI_STATE_CONTROL;
+ FWK_W uint32_t SI1_SI_FLUSH_CONTROL;
+ uint8_t RESERVED1[0x248 - 0x238];
+ FWK_RW uint32_t SI1_SI_INTERRUPT_CONTROL;
+ FWK_W uint32_t SI1_SI_INTERRUPT_CLR;
+ uint32_t RESERVED2;
+ FWK_R uint32_t SI1_TZ_REGION_BASE_LOW_0;
+ FWK_R uint32_t SI1_TZ_REGION_BASE_HIGH_0;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_0;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_0;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_0;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_0;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_1;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_1;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_1;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_1;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_1;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_1;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_2;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_2;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_2;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_2;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_2;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_2;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_3;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_3;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_3;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_3;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_3;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_3;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_4;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_4;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_4;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_4;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_4;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_4;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_5;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_5;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_5;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_5;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_5;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_5;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_6;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_6;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_6;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_6;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_6;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_6;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_7;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_7;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_7;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_7;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_7;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_7;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_LOW_8;
+ FWK_RW uint32_t SI1_TZ_REGION_BASE_HIGH_8;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_LOW_8;
+ FWK_RW uint32_t SI1_TZ_REGION_TOP_HIGH_8;
+ FWK_RW uint32_t SI1_TZ_REGION_ATTRIBUTES_8;
+ FWK_RW uint32_t SI1_TZ_REGION_ID_ACCESS_8;
+ FWK_RW uint32_t SI1_PMU_REQ_CONTROL;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MASK_0;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MATCH_0;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MASK_1;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MATCH_1;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MASK_2;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MATCH_2;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MASK_3;
+ FWK_RW uint32_t SI1_PMU_REQ_ATTRIBUTE_MATCH_3;
+ FWK_RW uint32_t SI1_THRESHOLD_CONTROL;
+ uint8_t RESERVED3[0x400 - 0x354];
+ FWK_R uint32_t DCB_STATUS;
+ FWK_R uint32_t M_INTERRUPT_STATUS;
+ FWK_R uint32_t PMU_DCB_INT_INFO;
+ FWK_W uint32_t DCB_STATE_CONTROL;
+ uint32_t RESERVED4;
+ FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_31_00;
+ FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_63_32;
+ uint8_t RESERVED5[0x42C - 0x41C];
+ FWK_RW uint32_t DCB_INTERRUPT_CONTROL;
+ FWK_W uint32_t DCB_INTERRUPT_CLR;
+ FWK_RW uint32_t PMU_DCB_CONTROL;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_0;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_0;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_COUNT_0;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_1;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_1;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_COUNT_1;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_2;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_2;
+ FWK_RW uint32_t PMU_DATA_CONTROL_BLOCK_COUNT_2;
+ FWK_RW uint32_t PMU_TAG_ENTRIES_ATTRIBUTE_MASK;
+ FWK_RW uint32_t PMU_TAG_ENTRIES_ATTRIBUTE_MATCH;
+ FWK_RW uint32_t PMU_TAG_ENTRIES_COUNT;
+ FWK_RW uint32_t PMU_MCLK_COUNT_COUNT;
+ uint32_t RESERVED6;
+ FWK_R uint32_t ERR_RAMECC_FR;
+ uint32_t RESERVED7;
+ FWK_RW uint32_t ERR_RAMECC_CTLR;
+ uint32_t RESERVED8;
+ FWK_RW uint32_t ERR_RAMECC_STATUS;
+ uint32_t RESERVED9;
+ FWK_RW uint32_t ERR_RAMECC_ADDR;
+ FWK_RW uint32_t ERR_RAMECC_ADDR2;
+ FWK_RW uint32_t ERR_RAMECC_MISC0;
+ uint32_t RESERVED10[3];
+ FWK_W uint32_t ERR_RAMECC_INJECT;
+ uint8_t RESERVED11[0x500 - 0x4A4];
+ FWK_R uint32_t QUEUE_STATUS;
+ uint32_t RESERVED12;
+ FWK_R uint32_t PMU_QE_INT_INFO;
+ FWK_RW uint32_t QUEUE_STATE_CONTROL;
+ FWK_RW uint32_t QE_INTERRUPT_CONTROL;
+ FWK_W uint32_t QE_INTERRUPT_CLR;
+ FWK_RW uint32_t RANK_TURNAROUND_CONTROL;
+ FWK_RW uint32_t HIT_TURNAROUND_CONTROL;
+ FWK_RW uint32_t QOS_CLASS_CONTROL;
+ FWK_RW uint32_t ESCALATION_CONTROL;
+ FWK_RW uint32_t QV_CONTROL_31_00;
+ FWK_RW uint32_t QV_CONTROL_63_32;
+ FWK_RW uint32_t RT_CONTROL_31_00;
+ FWK_RW uint32_t RT_CONTROL_63_32;
+ FWK_RW uint32_t TIMEOUT_CONTROL;
+ FWK_RW uint32_t WRITE_PRIORITY_CONTROL_31_00;
+ FWK_RW uint32_t WRITE_PRIORITY_CONTROL_63_32;
+ uint32_t RESERVED13;
+ FWK_RW uint32_t DIR_TURNAROUND_CONTROL;
+ FWK_RW uint32_t HIT_PREDICTION_CONTROL;
+ FWK_RW uint32_t REFRESH_ENABLE;
+ FWK_R uint32_t REFRESH_STATUS;
+ FWK_R uint32_t REFRESH_STATUS_FG;
+ FWK_RW uint32_t REFRESH_PRIORITY;
+ FWK_RW uint32_t MC_UPDATE_CONTROL;
+ FWK_RW uint32_t PHY_UPDATE_CONTROL;
+ FWK_RW uint32_t PHY_MASTER_CONTROL;
+ FWK_RW uint32_t LOW_POWER_CONTROL;
+ FWK_RW uint32_t PMU_QE_CONTROL;
+ FWK_RW uint32_t PMU_QE_MUX;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MASK_0;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MATCH_0;
+ FWK_RW uint32_t PMU_QOS_ENGINE_COUNT_0;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MASK_1;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MATCH_1;
+ FWK_RW uint32_t PMU_QOS_ENGINE_COUNT_1;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MASK_2;
+ FWK_RW uint32_t PMU_QOS_ENGINE_ATTRIBUTE_MATCH_2;
+ FWK_RW uint32_t PMU_QOS_ENGINE_COUNT_2;
+ FWK_RW uint32_t PMU_QUEUED_ENTRIES_ATTRIBUTE_MASK;
+ FWK_RW uint32_t PMU_QUEUED_ENTRIES_ATTRIBUTE_MATCH;
+ FWK_RW uint32_t PMU_QUEUED_ENTRIES_COUNT;
+ uint8_t RESERVED14[0x600 - 0x5A8];
+ FWK_R uint32_t MI_STATUS;
+ FWK_R uint32_t RANKS_READY;
+ FWK_R uint32_t RANKS_RESET;
+ FWK_R uint32_t RANKS_DEEP_POWER_DOWN;
+ FWK_R uint32_t RANKS_SELF_REFRESH;
+ FWK_R uint32_t RANKS_POWERED_DOWN;
+ FWK_R uint32_t RANKS_CLOCK_DISABLED;
+ FWK_R uint32_t PHY_STATUS0;
+ FWK_R uint32_t PHY_STATUS1;
+ uint32_t RESERVED15;
+ FWK_R uint32_t PMU_MI_INT_INFO;
+ uint32_t RESERVED16;
+ FWK_RW uint32_t MI_STATE_CONTROL;
+ FWK_RW uint32_t PHY_CONFIG;
+ FWK_RW uint32_t DIRECT_CMD_SETTINGS;
+ FWK_RW uint32_t DIRECT_CMD;
+ FWK_RW uint32_t DIRECT_CLK_DISABLE;
+ FWK_RW uint32_t DIRECT_ODT;
+ FWK_RW uint32_t DCI_STRB;
+ FWK_RW uint32_t DCI_DATA;
+ FWK_W uint32_t DCI_DATA_CLR;
+ FWK_W uint32_t RANK_STATUS_OVERRIDE;
+ FWK_W uint32_t CLK_STATUS_OVERRIDE;
+ FWK_W uint32_t BANK_STATUS_OVERRIDE;
+ FWK_RW uint32_t MI_INTERRUPT_CONTROL;
+ FWK_W uint32_t MI_INTERRUPT_CLR;
+ FWK_RW uint32_t MEMORY_TYPE;
+ FWK_RW uint32_t FORMAT_CONTROL;
+ FWK_RW uint32_t FEATURE_CONTROL;
+ FWK_RW uint32_t POWER_DOWN_CONTROL;
+ FWK_RW uint32_t REFRESH_CONTROL;
+ FWK_RW uint32_t ODT_WR_CONTROL_31_00;
+ uint32_t RESERVED17;
+ FWK_RW uint32_t ODT_RD_CONTROL_31_00;
+ uint32_t RESERVED18;
+ FWK_RW uint32_t PHY_WRDATA_CS_CONTROL_31_00;
+ uint32_t RESERVED19;
+ FWK_RW uint32_t PHY_RDDATA_CS_CONTROL_31_00;
+ uint32_t RESERVED20;
+ FWK_RW uint32_t PHYUPD_INIT;
+ FWK_RW uint32_t PHY_POWER_CONTROL;
+ uint32_t RESERVED21;
+ FWK_RW uint32_t ODT_TIMING;
+ FWK_RW uint32_t T_REFI;
+ FWK_RW uint32_t T_RFC;
+ FWK_RW uint32_t T_RCD;
+ FWK_RW uint32_t T_RAS;
+ FWK_RW uint32_t T_RP;
+ FWK_RW uint32_t T_RRD;
+ FWK_RW uint32_t T_ACT_WINDOW;
+ FWK_RW uint32_t T_RTR;
+ FWK_RW uint32_t T_RTW;
+ FWK_RW uint32_t T_RTP;
+ FWK_RW uint32_t T_RDPDEN;
+ FWK_RW uint32_t T_WR;
+ FWK_RW uint32_t T_WTR;
+ FWK_RW uint32_t T_WTW;
+ FWK_RW uint32_t T_XTMW;
+ FWK_RW uint32_t T_WRPDEN;
+ FWK_RW uint32_t T_CLOCK_CONTROL;
+ FWK_RW uint32_t T_EP;
+ FWK_RW uint32_t T_XP;
+ FWK_RW uint32_t T_ESR;
+ FWK_RW uint32_t T_XSR;
+ uint32_t RESERVED22;
+ FWK_RW uint32_t T_COMPLETION_CHECKS;
+ FWK_RW uint32_t T_RDDATA_EN;
+ FWK_RW uint32_t T_PHYRDLAT;
+ FWK_RW uint32_t T_PHYWRLAT;
+ FWK_RW uint32_t T_PHY_TRAIN;
+ FWK_R uint32_t ERR_PHY_FR;
+ uint32_t RESERVED23;
+ FWK_RW uint32_t ERR_PHY_CTLR;
+ uint32_t RESERVED24;
+ FWK_RW uint32_t ERR_PHY_STATUS;
+ uint32_t RESERVED25;
+ FWK_RW uint32_t ERR_PHY_ADDR;
+ FWK_RW uint32_t ERR_PHY_ADDR2;
+ FWK_RW uint32_t ERR_PHY_MISC0;
+ uint8_t RESERVED26[0x74C - 0x73C];
+ FWK_W uint32_t ERR_PHY_INJECT;
+ FWK_RW uint32_t PMU_MI_CONTROL;
+ FWK_RW uint32_t PMU_MEMORY_IF_ATTRIBUTE_MASK_0;
+ FWK_RW uint32_t PMU_MEMORY_IF_ATTRIBUTE_MATCH_0;
+ FWK_RW uint32_t PMU_MEMORY_IF_COUNT_0;
+ FWK_RW uint32_t PMU_MEMORY_IF_ATTRIBUTE_MASK_1;
+ FWK_RW uint32_t PMU_MEMORY_IF_ATTRIBUTE_MATCH_1;
+ FWK_RW uint32_t PMU_MEMORY_IF_COUNT_1;
+ FWK_RW uint32_t PMU_BANK_STATES_ATTRIBUTE_MASK;
+ FWK_RW uint32_t PMU_BANK_STATES_ATTRIBUTE_MATCH;
+ FWK_RW uint32_t PMU_BANK_STATES_COUNT;
+ FWK_RW uint32_t PMU_RANK_STATES_ATTRIBUTE_MASK;
+ FWK_RW uint32_t PMU_RANK_STATES_ATTRIBUTE_MATCH;
+ FWK_RW uint32_t PMU_RANK_STATES_COUNT;
+ uint8_t RESERVED27[0xF00 - 0x784];
+ FWK_R uint32_t MEMC_CONFIG;
+ uint32_t RESERVED28[3];
+ FWK_R uint32_t CFG_INTERRUPT_STATUS;
+ FWK_R uint32_t CFG_FAILED_ACCESS_INT_INFO;
+ uint8_t RESERVED29[0xF30 - 0xF18];
+ FWK_RW uint32_t CFG_INTERRUPT_CONTROL;
+ uint32_t RESERVED30;
+ FWK_W uint32_t CFG_INTERRUPT_CLR;
+ uint8_t RESERVED31[0xFC0 - 0xF3C];
+ FWK_RW uint32_t INTEGRATION_TEST_CONTROL;
+ FWK_RW uint32_t INTEGRATION_TEST_OUTPUT;
+ uint32_t RESERVED32[2];
+ FWK_R uint32_t PERIPH_ID_4;
+ uint32_t RESERVED33[3];
+ FWK_R uint32_t PERIPH_ID_0;
+ FWK_R uint32_t PERIPH_ID_1;
+ FWK_R uint32_t PERIPH_ID_2;
+ FWK_R uint32_t PERIPH_ID_3;
+ FWK_R uint32_t COMPONENT_ID_0;
+ FWK_R uint32_t COMPONENT_ID_1;
+ FWK_R uint32_t COMPONENT_ID_2;
+ FWK_R uint32_t COMPONENT_ID_3;
+ /*!
+ * \endcond
+ * @}
+ */
+};
+
+/*!
+ * \brief SI_STATE_CONTROL mask used to prevent request stalling.
+ */
+#define MOD_DMC500_SI_STATE_CONTROL_GO 0
+
+/*!
+ * \brief SI_STATE_CONTROL mask used to enable request stalling.
+ */
+#define MOD_DMC500_SI_STATE_CONTROL_STALL_REQ (1 << 0)
+
+/*!
+ * \brief SI_STATUS mask used to confirm that request stalling is active.
+ */
+#define MOD_DMC500_SI_STATUS_STALL_ACK (1 << 0)
+
+/*!
+ * \brief SI_STATUS mask used to read the empty bit.
+ */
+#define MOD_DMC500_SI_STATUS_EMPTY (1 << 1)
+
+/*!
+ * \brief QUEUE_STATE_CONTROL mask used to prevent request stalling.
+ */
+#define MOD_DMC500_QUEUE_STATE_CONTROL_GO 0
+
+/*!
+ * \brief QUEUE_STATE_CONTROL mask used to enable request stalling.
+ */
+#define MOD_DMC500_QUEUE_STATE_CONTROL_STALL_REQ (1 << 0)
+
+/*!
+ * \brief QUEUE_STATUS mask used to confirm that request stalling is active.
+ */
+#define MOD_DMC500_QUEUE_STATUS_STALL_ACK (1 << 0)
+
+/*!
+ * \brief QUEUE_STATUS mask used to read the empty bit.
+ */
+#define MOD_DMC500_QUEUE_STATUS_EMPTY (1 << 1)
+
+/*!
+ * \brief MI_STATUS mask used to read the idle bit.
+ */
+#define MOD_DMC500_MI_STATUS_IDLE (1 << 0)
+
+/*!
+ * \brief MI_STATUS mask used to read the empty bit.
+ */
+#define MOD_DMC500_MI_STATUS_EMPTY (1 << 1)
+
+/*!
+ * \brief Create the ADDRESS_MAP value.
+ *
+ * \param SHUTTER The address shutter.
+ *
+ * \return The ADDRESS_MAP value.
+ */
+#define ADDRESS_MAP_VAL(SHUTTER) ((1 << 8) | (SHUTTER))
+
+/*!
+ * \brief Create the ADDRESS_CONTROL value.
+ *
+ * \param RANK Number of bits for the rank.
+ * \param BANK Number of bits for the bank.
+ * \param ROW Number of bits for the row.
+ * \param COL Number of bits for the column.
+ *
+ * \return The ADDRESS_CONTROL value.
+ */
+#define ADDRESS_CONTROL_VAL(RANK, BANK, ROW, COL) (((RANK) << 24) | \
+ ((BANK) << 16) | \
+ ((ROW) << 8) | \
+ (COL))
+
+/*!
+ * \brief Create the MEMORY_TYPE value
+ *
+ * \param BANK_GROUP Bank group.
+ * \param WIDTH Memory device width.
+ * \param TYPE Memory type.
+ *
+ * \return The MEMORY_TYPE value.
+ */
+#define MEMORY_TYPE_VAL(BANK_GROUP, WIDTH, TYPE) (((BANK_GROUP) << 16) | \
+ ((WIDTH) << 8) | \
+ (TYPE))
+
+/*!
+ * \brief Create the FORMAT_CONTROL value.
+ *
+ * \param BURST Memory burst.
+ *
+ * \return The FORMAT_CONTROL value.
+ */
+#define FORMAT_CONTROL_VAL(BURST) ((BURST) << 8)
+
+/*!
+ * \brief Element configuration.
+ */
+struct mod_dmc500_element_config {
+ /*! Base address of the DMC-500 device's registers */
+ uintptr_t dmc;
+ /*! Element identifier of the associated DDR PHY-500 device */
+ fwk_id_t ddr_phy_id;
+};
+
+/*!
+ * \brief API of the DDR PHY associate to the DMC
+ */
+struct mod_dmc_ddr_phy_api {
+ /*!
+ * \brief Configure a DDR PHY500 device
+ *
+ * \param element_id Element identifier corresponding to the device to
+ * configure.
+ *
+ * \retval FWK_SUCCESS if the operation succeed.
+ * \return one of the error code otherwise.
+ */
+ int (*configure)(fwk_id_t element_id);
+};
+
+/*!
+ * \brief DMC-500 module configuration.
+ */
+struct mod_dmc500_module_config {
+ /*!
+ * Element identifier of the timer used for delays when programming the
+ * DMC-500
+ */
+ fwk_id_t timer_id;
+ /*! DDR PHY module ID */
+ fwk_id_t ddr_phy_module_id;
+ /*! DDR PHY API ID */
+ fwk_id_t ddr_phy_api_id;
+ /*! Initial value for the dmc registers */
+ const struct mod_dmc500_reg *reg_val;
+ /*! Pointer to a product-specific function that issues direct commands */
+ void (*direct_ddr_cmd)(struct mod_dmc500_reg *dmc);
+};
+
+/*!
+ * \brief DMC-500 module description.
+ */
+extern const struct fwk_module module_dmc500;
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#endif /* MOD_DMC500_H */
diff --git a/module/dmc500/src/Makefile b/module/dmc500/src/Makefile
new file mode 100644
index 00000000..ae4f2159
--- /dev/null
+++ b/module/dmc500/src/Makefile
@@ -0,0 +1,11 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := mod_dmc500
+BS_LIB_SOURCES += mod_dmc500.c
+
+include $(BS_DIR)/lib.mk
diff --git a/module/dmc500/src/mod_dmc500.c b/module/dmc500/src/mod_dmc500.c
new file mode 100644
index 00000000..5e5e3d73
--- /dev/null
+++ b/module/dmc500/src/mod_dmc500.c
@@ -0,0 +1,390 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * DMC-500 driver
+ */
+
+#include <assert.h>
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <fwk_status.h>
+#include <mod_dmc500.h>
+
+static struct mod_log_api *log_api;
+static struct mod_dmc_ddr_phy_api *ddr_phy_api;
+static struct mod_timer_api *timer_api;
+
+static int dmc500_config(struct mod_dmc500_reg *dmc, fwk_id_t ddr_phy_id);
+
+/* Framework API */
+static int mod_dmc500_init(fwk_id_t module_id, unsigned int element_count,
+ const void *data)
+{
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc500_element_init(fwk_id_t element_id, unsigned int unused,
+ const void *data)
+{
+ assert(data != NULL);
+
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc500_bind(fwk_id_t id, unsigned int round)
+{
+ int status;
+ const struct mod_dmc500_module_config *module_config;
+
+ /* Nothing to do in the second round of calls. */
+ if (round == 1)
+ return FWK_SUCCESS;
+
+ /* Nothing to do in case of elements. */
+ if (fwk_module_is_valid_element_id(id))
+ return FWK_SUCCESS;
+
+ module_config = fwk_module_get_data(fwk_module_id_dmc500);
+ assert(module_config != NULL);
+
+ status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG),
+ MOD_LOG_API_ID, &log_api);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = fwk_module_bind(module_config->ddr_phy_module_id,
+ module_config->ddr_phy_api_id, &ddr_phy_api);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = fwk_module_bind(module_config->timer_id,
+ FWK_ID_API(FWK_MODULE_IDX_TIMER, 0), &timer_api);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc500_start(fwk_id_t id)
+{
+ const struct mod_dmc500_element_config *element_config;
+ struct mod_dmc500_reg *dmc;
+
+ /* Nothing to start for the module */
+ if (fwk_module_is_valid_module_id(id))
+ return FWK_SUCCESS;
+
+ element_config = fwk_module_get_data(id);
+ dmc = (struct mod_dmc500_reg *)element_config->dmc;
+
+ return dmc500_config(dmc, element_config->ddr_phy_id);
+}
+
+const struct fwk_module module_dmc500 = {
+ .name = "DMC500",
+ .type = FWK_MODULE_TYPE_DRIVER,
+ .init = mod_dmc500_init,
+ .element_init = mod_dmc500_element_init,
+ .bind = mod_dmc500_bind,
+ .start = mod_dmc500_start,
+ .api_count = 0,
+ .event_count = 0,
+};
+
+
+static int dmc500_config(struct mod_dmc500_reg *dmc, fwk_id_t ddr_phy_id)
+{
+ int status;
+ uint64_t timeout;
+ uint64_t remaining_ticks;
+ uint64_t counter;
+ const struct mod_dmc500_reg *reg_val;
+ const struct mod_dmc500_module_config *module_config;
+
+ module_config = fwk_module_get_data(fwk_module_id_dmc500);
+ reg_val = module_config->reg_val;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Initialising DMC500 at 0x%x\n", (uintptr_t)dmc);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->ADDRESS_CONTROL = reg_val->ADDRESS_CONTROL;
+ dmc->RANK_REMAP_CONTROL = reg_val->RANK_REMAP_CONTROL;
+ dmc->MEMORY_TYPE = reg_val->MEMORY_TYPE;
+ dmc->FORMAT_CONTROL = reg_val->FORMAT_CONTROL;
+ dmc->DECODE_CONTROL = reg_val->DECODE_CONTROL;
+ dmc->FEATURE_CONTROL = reg_val->FEATURE_CONTROL;
+ dmc->ODT_WR_CONTROL_31_00 = reg_val->ODT_WR_CONTROL_31_00;
+ dmc->ODT_RD_CONTROL_31_00 = reg_val->ODT_RD_CONTROL_31_00;
+ dmc->ODT_TIMING = reg_val->ODT_TIMING;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Setting timing settings\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->T_REFI = reg_val->T_REFI;
+ dmc->T_RFC = reg_val->T_RFC;
+ dmc->T_RDPDEN = reg_val->T_RDPDEN;
+ dmc->T_RCD = reg_val->T_RCD;
+ dmc->T_RAS = reg_val->T_RAS;
+ dmc->T_RP = reg_val->T_RP;
+ dmc->T_RRD = reg_val->T_RRD;
+ dmc->T_ACT_WINDOW = reg_val->T_ACT_WINDOW;
+ dmc->T_RTR = reg_val->T_RTR;
+ dmc->T_RTW = reg_val->T_RTW;
+ dmc->T_RTP = reg_val->T_RTP;
+ dmc->T_WR = reg_val->T_WR;
+ dmc->T_WTR = reg_val->T_WTR;
+ dmc->T_WTW = reg_val->T_WTW;
+ dmc->T_XTMW = reg_val->T_XTMW;
+ dmc->T_CLOCK_CONTROL = reg_val->T_CLOCK_CONTROL;
+ dmc->T_EP = reg_val->T_EP;
+ dmc->T_XP = reg_val->T_XP;
+ dmc->T_ESR = reg_val->T_ESR;
+ dmc->T_XSR = reg_val->T_XSR;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Setting address map\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->ADDRESS_MAP = reg_val->ADDRESS_MAP;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Setting PMU settings\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->SI0_SI_INTERRUPT_CONTROL = reg_val->SI0_SI_INTERRUPT_CONTROL;
+ dmc->SI0_PMU_REQ_CONTROL = reg_val->SI0_PMU_REQ_CONTROL;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_0 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MASK_0;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_0 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MATCH_0;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_1 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MASK_1;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_1 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MATCH_1;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_2 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MASK_2;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_2 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MATCH_2;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_3 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MASK_3;
+ dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_3 = reg_val->SI0_PMU_REQ_ATTRIBUTE_MATCH_3;
+ dmc->SI0_THRESHOLD_CONTROL = reg_val->SI0_THRESHOLD_CONTROL;
+ dmc->SI1_SI_INTERRUPT_CONTROL = reg_val->SI1_SI_INTERRUPT_CONTROL;
+ dmc->SI1_PMU_REQ_CONTROL = reg_val->SI1_PMU_REQ_CONTROL;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_0 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MASK_0;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_0 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MATCH_0;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_1 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MASK_1;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_1 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MATCH_1;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_2 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MASK_2;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_2 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MATCH_2;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_3 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MASK_3;
+ dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_3 = reg_val->SI1_PMU_REQ_ATTRIBUTE_MATCH_3;
+ dmc->SI1_THRESHOLD_CONTROL = reg_val->SI1_THRESHOLD_CONTROL;
+ dmc->QUEUE_THRESHOLD_CONTROL_31_00 = reg_val->QUEUE_THRESHOLD_CONTROL_31_00;
+ dmc->QUEUE_THRESHOLD_CONTROL_63_32 = reg_val->QUEUE_THRESHOLD_CONTROL_63_32;
+ dmc->DCB_INTERRUPT_CONTROL = reg_val->DCB_INTERRUPT_CONTROL;
+ dmc->PMU_DCB_CONTROL = reg_val->PMU_DCB_CONTROL;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_0 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_0;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_0 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_0;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_1 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_1;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_1 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_1;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_2 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_2;
+ dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_2 =
+ reg_val->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_2;
+ dmc->PMU_TAG_ENTRIES_ATTRIBUTE_MASK =
+ reg_val->PMU_TAG_ENTRIES_ATTRIBUTE_MASK;
+ dmc->PMU_TAG_ENTRIES_ATTRIBUTE_MATCH =
+ reg_val->PMU_TAG_ENTRIES_ATTRIBUTE_MATCH;
+ dmc->QE_INTERRUPT_CONTROL = reg_val->QE_INTERRUPT_CONTROL;
+ dmc->RANK_TURNAROUND_CONTROL = reg_val->RANK_TURNAROUND_CONTROL;
+ dmc->HIT_TURNAROUND_CONTROL = reg_val->HIT_TURNAROUND_CONTROL;
+ dmc->QOS_CLASS_CONTROL = reg_val->QOS_CLASS_CONTROL;
+ dmc->ESCALATION_CONTROL = reg_val->ESCALATION_CONTROL;
+ dmc->QV_CONTROL_31_00 = reg_val->QV_CONTROL_31_00;
+ dmc->QV_CONTROL_63_32 = reg_val->QV_CONTROL_63_32;
+ dmc->RT_CONTROL_31_00 = reg_val->RT_CONTROL_31_00;
+ dmc->RT_CONTROL_63_32 = reg_val->RT_CONTROL_63_32;
+ dmc->TIMEOUT_CONTROL = reg_val->TIMEOUT_CONTROL;
+ dmc->WRITE_PRIORITY_CONTROL_31_00 = reg_val->WRITE_PRIORITY_CONTROL_31_00;
+ dmc->WRITE_PRIORITY_CONTROL_63_32 = reg_val->WRITE_PRIORITY_CONTROL_63_32;
+ dmc->DIR_TURNAROUND_CONTROL = reg_val->DIR_TURNAROUND_CONTROL;
+ dmc->HIT_PREDICTION_CONTROL = reg_val->HIT_PREDICTION_CONTROL;
+ dmc->REFRESH_PRIORITY = reg_val->REFRESH_PRIORITY;
+ dmc->MC_UPDATE_CONTROL = reg_val->MC_UPDATE_CONTROL;
+ dmc->PHY_UPDATE_CONTROL = reg_val->PHY_UPDATE_CONTROL;
+ dmc->PHY_MASTER_CONTROL = reg_val->PHY_MASTER_CONTROL;
+ dmc->LOW_POWER_CONTROL = reg_val->LOW_POWER_CONTROL;
+ dmc->PMU_QE_CONTROL = reg_val->PMU_QE_CONTROL;
+ dmc->PMU_QE_MUX = reg_val->PMU_QE_MUX;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_0 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MASK_0;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_0 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_0;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_1 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MASK_1;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_1 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_1;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_2 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MASK_2;
+ dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_2 =
+ reg_val->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_2;
+ dmc->PMU_QUEUED_ENTRIES_ATTRIBUTE_MASK =
+ reg_val->PMU_QUEUED_ENTRIES_ATTRIBUTE_MASK;
+ dmc->PMU_QUEUED_ENTRIES_ATTRIBUTE_MATCH =
+ reg_val->PMU_QUEUED_ENTRIES_ATTRIBUTE_MATCH;
+ dmc->MI_INTERRUPT_CONTROL = reg_val->MI_INTERRUPT_CONTROL;
+ dmc->POWER_DOWN_CONTROL = reg_val->POWER_DOWN_CONTROL;
+ dmc->REFRESH_CONTROL = reg_val->REFRESH_CONTROL;
+ dmc->PMU_MI_CONTROL = reg_val->PMU_MI_CONTROL;
+ dmc->PMU_MEMORY_IF_ATTRIBUTE_MASK_0 =
+ reg_val->PMU_MEMORY_IF_ATTRIBUTE_MASK_0;
+ dmc->PMU_MEMORY_IF_ATTRIBUTE_MATCH_0 =
+ reg_val->PMU_MEMORY_IF_ATTRIBUTE_MATCH_0;
+ dmc->PMU_MEMORY_IF_ATTRIBUTE_MASK_1 =
+ reg_val->PMU_MEMORY_IF_ATTRIBUTE_MASK_1;
+ dmc->PMU_MEMORY_IF_ATTRIBUTE_MATCH_1 =
+ reg_val->PMU_MEMORY_IF_ATTRIBUTE_MATCH_1;
+ dmc->PMU_BANK_STATES_ATTRIBUTE_MASK =
+ reg_val->PMU_BANK_STATES_ATTRIBUTE_MASK;
+ dmc->PMU_BANK_STATES_ATTRIBUTE_MATCH =
+ reg_val->PMU_BANK_STATES_ATTRIBUTE_MATCH;
+ dmc->PMU_RANK_STATES_ATTRIBUTE_MASK =
+ reg_val->PMU_RANK_STATES_ATTRIBUTE_MASK;
+ dmc->PMU_RANK_STATES_ATTRIBUTE_MATCH =
+ reg_val->PMU_RANK_STATES_ATTRIBUTE_MATCH;
+ dmc->CFG_INTERRUPT_CONTROL = reg_val->CFG_INTERRUPT_CONTROL;
+ dmc->T_RDDATA_EN = reg_val->T_RDDATA_EN;
+ dmc->T_PHYRDLAT = reg_val->T_PHYRDLAT;
+ dmc->T_PHYWRLAT = reg_val->T_PHYWRLAT;
+
+ dmc->ERR_RAMECC_CTLR = reg_val->ERR_RAMECC_CTLR;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Setting PHY-related settings\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->PHY_POWER_CONTROL = reg_val->PHY_POWER_CONTROL;
+ dmc->T_PHY_TRAIN = reg_val->T_PHY_TRAIN;
+ dmc->PHYUPD_INIT = reg_val->PHYUPD_INIT;
+
+ dmc->PHY_CONFIG = 0x03000000;
+ dmc->PHY_CONFIG = 0x0600000A;
+ dmc->PHY_CONFIG = 0x01000001;
+
+ status = ddr_phy_api->configure(ddr_phy_id);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ dmc->PHY_CONFIG = 0x01000001;
+ dmc->PHY_CONFIG = 0x01000000;
+ dmc->PHY_CONFIG = 0x00000003;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Doing direct DDR commands\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ module_config->direct_ddr_cmd(dmc);
+
+ dmc->REFRESH_ENABLE = reg_val->REFRESH_ENABLE;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Setting dmc in READY mode\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = timer_api->time_to_timestamp(module_config->timer_id,
+ 1000 * 1000, &timeout);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = timer_api->get_counter(module_config->timer_id, &counter);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ timeout += counter;
+
+ while ((dmc->MI_STATUS & MOD_DMC500_MI_STATUS_IDLE) !=
+ MOD_DMC500_MI_STATUS_IDLE) {
+ status = timer_api->remaining(module_config->timer_id, timeout,
+ &remaining_ticks);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ if (remaining_ticks == 0)
+ goto timeout;
+ }
+
+ dmc->MI_STATE_CONTROL = reg_val->MI_STATE_CONTROL;
+ dmc->QUEUE_STATE_CONTROL = reg_val->QUEUE_STATE_CONTROL;
+ dmc->SI0_SI_STATE_CONTROL = reg_val->SI0_SI_STATE_CONTROL;
+ dmc->SI1_SI_STATE_CONTROL = reg_val->SI1_SI_STATE_CONTROL;
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Waiting for Queue stall = 0...\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ while ((dmc->QUEUE_STATUS & MOD_DMC500_QUEUE_STATUS_STALL_ACK) != 0) {
+ status = timer_api->remaining(module_config->timer_id, timeout,
+ &remaining_ticks);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ if (remaining_ticks == 0)
+ goto timeout;
+ }
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Waiting for SI0 stall = 0...\n");
+ if (status != FWK_SUCCESS)
+ return FWK_SUCCESS;
+
+ while ((dmc->SI0_SI_STATUS & MOD_DMC500_SI_STATUS_STALL_ACK) != 0) {
+ status = timer_api->remaining(module_config->timer_id, timeout,
+ &remaining_ticks);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ if (remaining_ticks == 0)
+ goto timeout;
+ }
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG,
+ "[DDR] Waiting for SI1 stall = 0...\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ while ((dmc->SI1_SI_STATUS & MOD_DMC500_SI_STATUS_STALL_ACK) != 0) {
+ status = timer_api->remaining(module_config->timer_id, timeout,
+ &remaining_ticks);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ if (remaining_ticks == 0)
+ goto timeout;
+ }
+
+ status = log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] DMC init done.\n");
+ if (status != FWK_SUCCESS)
+ return status;
+
+ return FWK_SUCCESS;
+
+timeout:
+ status = log_api->log(MOD_LOG_GROUP_ERROR,
+ "[DDR] Timed out in DMC500 init.\n");
+ if (status != FWK_SUCCESS)
+ return status;
+ return FWK_E_TIMEOUT;
+}
diff --git a/product/sgm776/include/fmw_cmsis.h b/product/sgm776/include/fmw_cmsis.h
new file mode 100644
index 00000000..ece8426c
--- /dev/null
+++ b/product/sgm776/include/fmw_cmsis.h
@@ -0,0 +1,30 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-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 __CM3_REV 0x0201
+#define __MPU_PRESENT 1
+#define __NVIC_PRIO_BITS 3
+#define __Vendor_SysTickConfig 0
+
+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 <core_cm3.h>
+
+#endif /* FMW_CMSIS_H */
diff --git a/product/sgm776/include/sgm776_core.h b/product/sgm776/include/sgm776_core.h
new file mode 100644
index 00000000..ef0ccac0
--- /dev/null
+++ b/product/sgm776/include/sgm776_core.h
@@ -0,0 +1,15 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_CORE_H
+#define SGM776_CORE_H
+
+#define SGM776_CORE_PER_CLUSTER_MAX 8
+
+unsigned int sgm776_core_get_count(void);
+
+#endif /* SGM776_CORE_H */
diff --git a/product/sgm776/include/sgm776_irq.h b/product/sgm776/include/sgm776_irq.h
new file mode 100644
index 00000000..b664a005
--- /dev/null
+++ b/product/sgm776/include/sgm776_irq.h
@@ -0,0 +1,210 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_IRQ_H
+#define SGM776_IRQ_H
+
+#include <fwk_interrupt.h>
+
+#define WDOG_IRQ FWK_INTERRUPT_NMI /* SCP Watchdog (SP805) */
+
+enum sgm776_irq {
+ TIM32KHZ_IRQ = 0, /* 32KHz Physical Timer */
+ CDBG_PWR_UP_REQ_IRQ = 1, /* Coresight Debug Power Request */
+ CSYS_PWR_UP_REQ_IRQ = 2, /* Coresight System Power Request */
+ CDBG_RST_REQ_IRQ = 3, /* Coresight Debug Reset Request */
+ RESERVED4_IRQ = 4, /* Reserved */
+ RESERVED5_IRQ = 5, /* Reserved */
+ RESERVED6_IRQ = 6, /* Reserved */
+ RESERVED7_IRQ = 7, /* Reserved */
+ RESERVED8_IRQ = 8, /* Reserved */
+ RESERVED9_IRQ = 9, /* Reserved */
+ RESERVED10_IRQ = 10, /* Reserved */
+ RESERVED11_IRQ = 11, /* Reserved */
+ RESERVED12_IRQ = 12, /* Reserved */
+ RESERVED13_IRQ = 13, /* Reserved */
+ RESERVED14_IRQ = 14, /* Reserved */
+ RESERVED15_IRQ = 15, /* Reserved */
+ SOC_WAKEUP0_IRQ = 16, /* SoC Expansion Wakeup */
+ SOC_WAKEUP1_IRQ = 17, /* SoC Expansion Wakeup */
+ SOC_WAKEUP2_IRQ = 18, /* SoC Expansion Wakeup */
+ SOC_WAKEUP3_IRQ = 19, /* SoC Expansion Wakeup */
+ SOC_WAKEUP4_IRQ = 20, /* SoC Expansion Wakeup */
+ SOC_WAKEUP5_IRQ = 21, /* SoC Expansion Wakeup */
+ SOC_WAKEUP6_IRQ = 22, /* SoC Expansion Wakeup */
+ SOC_WAKEUP7_IRQ = 23, /* SoC Expansion Wakeup */
+ SOC_WAKEUP8_IRQ = 24, /* SoC Expansion Wakeup */
+ SOC_WAKEUP9_IRQ = 25, /* SoC Expansion Wakeup */
+ SOC_WAKEUP10_IRQ = 26, /* SoC Expansion Wakeup */
+ SOC_WAKEUP11_IRQ = 27, /* SoC Expansion Wakeup */
+ SOC_WAKEUP12_IRQ = 28, /* SoC Expansion Wakeup */
+ SOC_WAKEUP13_IRQ = 29, /* SoC Expansion Wakeup */
+ SOC_WAKEUP14_IRQ = 30, /* SoC Expansion Wakeup */
+ SOC_WAKEUP15_IRQ = 31, /* SoC Expansion Wakeup */
+ PPU_SCP_IRQ = 32, /* SCP Power Policy Unit */
+ TIMREFCLK_IRQ = 33, /* REFCLK Physical Timer */
+ MHU_HIGH_PRIO_IRQ = 34, /* MHU High Priority */
+ MHU_LOW_PRIO_IRQ = 35, /* MHU Low Priority */
+ MHU_SECURE_IRQ = 36, /* MHU Secure */
+ CTI_TRIGGER0_IRQ = 37, /* SCP CTI Trigger */
+ CTI_TRIGGER1_IRQ = 38, /* SCP CTI Trigger */
+ GIC_ERROR_ECC_IRQ = 39, /* GIC Error (ECC Fatal) */
+ GIC_ERROR_AXIM_IRQ = 40, /* GIC Error (AXIM) */
+ DMC_RESERVED0_IRQ = 41, /* DMC, Reserved */
+ DMC_0_ERROR_ECC_IRQ = 42, /* DMC0 Combined ECC Error */
+ DMC_0_ERROR_ACCESS_IRQ = 43, /* DMC0 Combined Misc Access Error */
+ DMC_RESERVED1_IRQ = 44, /* DMC, Reserved */
+ DMC_RESERVED2_IRQ = 45, /* DMC, Reserved */
+ DMC_1_ERROR_ECC_IRQ = 46, /* DMC1 Combined ECC Error */
+ DMC_1_ERROR_ACCESS_IRQ = 47, /* DMC1 Combined Misc Access Error */
+ DMC_RESERVED3_IRQ = 48, /* DMC, Reserved */
+ DMC_RESERVED4_IRQ = 49, /* DMC, Reserved */
+ DMC_2_ERROR_ECC_IRQ = 50, /* DMC2 Combined ECC Error */
+ DMC_2_ERROR_ACCESS_IRQ = 51, /* DMC2 Combined Misc Access Error */
+ DMC_RESERVED5_IRQ = 52, /* DMC, Reserved */
+ DMC_RESERVED6_IRQ = 53, /* DMC, Reserved */
+ DMC_3_ERROR_ECC_IRQ = 54, /* DMC3 Combined ECC Error */
+ DMC_3_ERROR_ACCESS_IRQ = 55, /* DMC3 Combined Misc Access Error */
+ DMC_RESERVED7_IRQ = 56, /* DMC, Reserved */
+ RESERVED57_IRQ = 57, /* Reserved */
+ RESERVED58_IRQ = 58, /* Reserved */
+ RESERVED59_IRQ = 59, /* Reserved */
+ RESERVED60_IRQ = 60, /* Reserved */
+ RESERVED61_IRQ = 61, /* Reserved */
+ RESERVED62_IRQ = 62, /* Reserved */
+ RESERVED63_IRQ = 63, /* Reserved */
+ PPU_CLUS0CORE0_IRQ = 64, /* Cluster 0 Core 0 Power Policy Unit */
+ PPU_CLUS0CORE1_IRQ = 65, /* Cluster 0 Core 1 Power Policy Unit */
+ PPU_CLUS0CORE2_IRQ = 66, /* Cluster 0 Core 2 Power Policy Unit */
+ PPU_CLUS0CORE3_IRQ = 67, /* Cluster 0 Core 3 Power Policy Unit */
+ PPU_CLUS0_IRQ = 68, /* Cluster 0 Power Policy Unit */
+ PPU_CLUS1CORE0_IRQ = 69, /* Cluster 1 Core 0 Power Policy Unit */
+ PPU_CLUS1CORE1_IRQ = 70, /* Cluster 1 Core 1 Power Policy Unit */
+ PPU_CLUS1CORE2_IRQ = 71, /* Cluster 1 Core 2 Power Policy Unit */
+ PPU_CLUS1CORE3_IRQ = 72, /* Cluster 1 Core 3 Power Policy Unit */
+ PPU_CLUS1_IRQ = 73, /* Cluster 1 Power Policy Unit */
+ PPU_SYS0_IRQ = 74, /* System Power Policy Unit 0 */
+ PPU_SYS1_IRQ = 75, /* System Power Policy Unit 1 */
+ PPU_GPU_IRQ = 76, /* GPU Power Policy Unit */
+ PPU_VPU_IRQ = 77, /* Video Power Policy Unit */
+ PPU_DPU_IRQ = 78, /* Display Power Policy Unit 0 */
+ RESERVED79_IRQ = 79, /* Reserved */
+ RESERVED80_IRQ = 80, /* Reserved */
+ PPU_DEBUG_IRQ = 81, /* DBGSYS Power Policy Unit */
+ PPU_DEBUG_CHAIN_IRQ = 82, /* Debug chain Power Policy Unit */
+ RESERVED83_IRQ = 83, /* Reserved */
+ RESERVED84_IRQ = 84, /* Reserved */
+ RESERVED85_IRQ = 85, /* Reserved */
+ RESERVED86_IRQ = 86, /* Reserved */
+ RESERVED87_IRQ = 87, /* Reserved */
+ RESERVED88_IRQ = 88, /* Reserved */
+ RESERVED89_IRQ = 89, /* Reserved */
+ PPU_CLUS0CORE4_IRQ = 90, /* Cluster 0 Core 4 Power Policy Unit */
+ PPU_CLUS0CORE5_IRQ = 91, /* Cluster 0 Core 5 Power Policy Unit */
+ PPU_CLUS0CORE6_IRQ = 92, /* Cluster 0 Core 6 Power Policy Unit */
+ PPU_CLUS0CORE7_IRQ = 93, /* Cluster 0 Core 7 Power Policy Unit */
+ PPU_CLUS1CORE4_IRQ = 94, /* Cluster 1 Core 4 Power Policy Unit */
+ PPU_CLUS1CORE5_IRQ = 95, /* Cluster 1 Core 5 Power Policy Unit */
+ PPU_CLUS1CORE6_IRQ = 96, /* Cluster 1 Core 6 Power Policy Unit */
+ PPU_CLUS1CORE7_IRQ = 97, /* Cluster 1 Core 7 Power Policy Unit */
+ PLL_CLUS0_LOCK_IRQ = 98, /* Cluster 0 CPU PLL Lock */
+ PLL_CLUS1_LOCK_IRQ = 99, /* Cluster 1 CPU PLL Lock */
+ PLL_GPU_LOCK_IRQ = 100, /* GPU PLL Lock */
+ PLL_VPU_LOCK_IRQ = 101, /* Video PLL Lock */
+ PLL_SYS_LOCK_IRQ = 102, /* System PLL Lock */
+ PLL_DPU_LOCK_IRQ = 103, /* Display PLL Lock */
+ PLL_CLUS0CORE0_IRQ = 104, /* Cluster 0 PLL0 Lock */
+ PLL_CLUS0CORE1_IRQ = 105, /* Cluster 0 PLL1 Lock */
+ PLL_CLUS0CORE2_IRQ = 106, /* Cluster 0 PLL2 Lock */
+ PLL_CLUS0CORE3_IRQ = 107, /* Cluster 0 PLL3 Lock */
+ PLL_CLUS0CORE4_IRQ = 108, /* Cluster 0 PLL4 Lock */
+ PLL_CLUS0CORE5_IRQ = 109, /* Cluster 0 PLL5 Lock */
+ PLL_CLUS0CORE6_IRQ = 110, /* Cluster 0 PLL6 Lock */
+ PLL_CLUS0CORE7_IRQ = 111, /* Cluster 0 PLL7 Lock */
+ PLL_CLUS1CORE0_IRQ = 112, /* Cluster 1 PLL0 Lock */
+ PLL_CLUS1CORE1_IRQ = 113, /* Cluster 1 PLL1 Lock */
+ PLL_CLUS1CORE2_IRQ = 114, /* Cluster 1 PLL2 Lock */
+ PLL_CLUS1CORE3_IRQ = 115, /* Cluster 1 PLL3 Lock */
+ PLL_CLUS1CORE4_IRQ = 116, /* Cluster 1 PLL4 Lock */
+ PLL_CLUS1CORE5_IRQ = 117, /* Cluster 1 PLL5 Lock */
+ PLL_CLUS1CORE6_IRQ = 118, /* Cluster 1 PLL6 Lock */
+ PLL_CLUS1CORE7_IRQ = 119, /* Cluster 1 PLL7 Lock */
+ DBG_PWR_REQ0_IRQ = 120, /* Debug power request 0 */
+ DBG_PWR_REQ1_IRQ = 121, /* Debug power request 1 */
+ DBG_PWR_REQ2_IRQ = 122, /* Debug power request 2 */
+ DBG_PWR_REQ3_IRQ = 123, /* Debug power request 3 */
+ DBG_RST_REQ_IRQ = 124, /* Debug reset request */
+ SYS_PWR_REQ0_IRQ = 125, /* System power request 0 */
+ SYS_PWR_REQ1_IRQ = 126, /* System power request 1 */
+ SYS_PWR_REQ2_IRQ = 127, /* System power request 2 */
+ SYS_PWR_REQ3_IRQ = 128, /* System power request 3 */
+ SYS_RST_REQ_IRQ = 129, /* System reset request */
+ DBG_CHN_PWRUP_IRQ = 130, /* Debug chain power up */
+ RESERVED131_IRQ = 131, /* Reserved */
+ RESERVED132_IRQ = 132, /* Reserved */
+ RESERVED133_IRQ = 133, /* Reserved */
+ RESERVED134_IRQ = 134, /* Reserved */
+ RESERVED135_IRQ = 135, /* Reserved */
+ RESERVED136_IRQ = 136, /* Reserved */
+ RESERVED137_IRQ = 137, /* Reserved */
+ RESERVED138_IRQ = 138, /* Reserved */
+ RESERVED139_IRQ = 139, /* Reserved */
+ RESERVED140_IRQ = 140, /* Reserved */
+ RESERVED141_IRQ = 141, /* Reserved */
+ RESERVED142_IRQ = 142, /* Reserved */
+ RESERVED143_IRQ = 143, /* Reserved */
+ RESERVED144_IRQ = 144, /* Reserved */
+ RESERVED145_IRQ = 145, /* Reserved */
+ RESERVED146_IRQ = 146, /* Reserved */
+ RESERVED147_IRQ = 147, /* Reserved */
+ RESERVED148_IRQ = 148, /* Reserved */
+ RESERVED149_IRQ = 149, /* Reserved */
+ RESERVED150_IRQ = 150, /* Reserved */
+ RESERVED151_IRQ = 151, /* Reserved */
+ RESERVED152_IRQ = 152, /* Reserved */
+ RESERVED153_IRQ = 153, /* Reserved */
+ RESERVED154_IRQ = 154, /* Reserved */
+ RESERVED155_IRQ = 155, /* Reserved */
+ RESERVED156_IRQ = 156, /* Reserved */
+ RESERVED157_IRQ = 157, /* Reserved */
+ RESERVED158_IRQ = 158, /* Reserved */
+ RESERVED159_IRQ = 159, /* Reserved */
+ SCP_EXT_INTR0_IRQ = 160, /* SCP Customer Extension */
+ SCP_EXT_INTR1_IRQ = 161, /* SCP Customer Extension */
+ SCP_EXT_INTR2_IRQ = 162, /* SCP Customer Extension */
+ SCP_EXT_INTR3_IRQ = 163, /* SCP Customer Extension */
+ SCP_EXT_INTR4_IRQ = 164, /* SCP Customer Extension */
+ SCP_EXT_INTR5_IRQ = 165, /* SCP Customer Extension */
+ SCP_EXT_INTR6_IRQ = 166, /* SCP Customer Extension */
+ SCP_EXT_INTR7_IRQ = 167, /* SCP Customer Extension */
+ SCP_EXT_INTR8_IRQ = 168, /* SCP Customer Extension */
+ SCP_EXT_INTR9_IRQ = 169, /* SCP Customer Extension */
+ SCP_EXT_INTR10_IRQ = 170, /* SCP Customer Extension */
+ SCP_EXT_INTR11_IRQ = 171, /* SCP Customer Extension */
+ SCP_EXT_INTR12_IRQ = 172, /* SCP Customer Extension */
+ SCP_EXT_INTR13_IRQ = 173, /* SCP Customer Extension */
+ SCP_EXT_INTR14_IRQ = 174, /* SCP Customer Extension */
+ SCP_EXT_INTR15_IRQ = 175, /* SCP Customer Extension */
+ SCP_EXT_INTR16_IRQ = 176, /* SCP Customer Extension */
+ SCP_EXT_INTR17_IRQ = 177, /* SCP Customer Extension */
+ SCP_EXT_INTR18_IRQ = 178, /* SCP Customer Extension */
+ SCP_EXT_INTR19_IRQ = 179, /* SCP Customer Extension */
+ SCP_EXT_INTR20_IRQ = 180, /* SCP Customer Extension */
+ SCP_EXT_INTR21_IRQ = 181, /* SCP Customer Extension */
+ SCP_EXT_INTR22_IRQ = 182, /* SCP Customer Extension */
+ SCP_EXT_INTR23_IRQ = 183, /* SCP Customer Extension */
+ SCP_EXT_INTR24_IRQ = 184, /* SCP Customer Extension */
+ SCP_EXT_INTR25_IRQ = 185, /* SCP Customer Extension */
+ SCP_EXT_INTR26_IRQ = 186, /* SCP Customer Extension */
+ SCP_EXT_INTR27_IRQ = 187, /* SCP Customer Extension */
+ SCP_EXT_INTR28_IRQ = 188, /* SCP Customer Extension */
+ SCP_EXT_INTR29_IRQ = 189, /* SCP Customer Extension */
+ SCP_EXT_INTR30_IRQ = 190, /* SCP Customer Extension */
+ SCP_EXT_INTR31_IRQ = 191, /* SCP Customer Extension */
+};
+
+#endif /* SGM776_IRQ_H */
diff --git a/product/sgm776/include/sgm776_mhu.h b/product/sgm776/include/sgm776_mhu.h
new file mode 100644
index 00000000..6ec8101a
--- /dev/null
+++ b/product/sgm776/include/sgm776_mhu.h
@@ -0,0 +1,21 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * MHU module device indexes.
+ */
+
+#ifndef SGM776_MHU_H
+#define SGM776_MHU_H
+
+enum sgm776_mhu_device_idx {
+ SGM776_MHU_DEVICE_IDX_S,
+ SGM776_MHU_DEVICE_IDX_NS_H,
+ SGM776_MHU_DEVICE_IDX_NS_L,
+ SGM776_MHU_DEVICE_IDX_COUNT
+};
+
+#endif /* SGM776_MHU_H */
diff --git a/product/sgm776/include/sgm776_mmap.h b/product/sgm776/include/sgm776_mmap.h
new file mode 100644
index 00000000..9ae9f58a
--- /dev/null
+++ b/product/sgm776/include/sgm776_mmap.h
@@ -0,0 +1,96 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_MMAP_H
+#define SGM776_MMAP_H
+
+#include <stdint.h>
+
+/*
+ * Top-level base addresses
+ */
+#define EXPANSION0_BASE UINT32_C(0x40000000)
+#define PERIPHERAL_BASE UINT32_C(0x44000000)
+#define POWER_PERIPHERAL_BASE UINT32_C(0x50000000)
+#define SYS0_BASE UINT32_C(0x60000000)
+#define SYS1_BASE UINT32_C(0xA0000000)
+#define PPB_INTERNAL_BASE UINT32_C(0xE0000000)
+#define PPB_EXTERNAL_BASE UINT32_C(0xE0040000)
+#define EXPANSION1_BASE UINT32_C(0xE0100000)
+
+/*
+ * Peripherals
+ */
+#define REFCLK_CNTCTL_BASE (PERIPHERAL_BASE + 0x0000)
+#define REFCLK_CNTBASE0_BASE (PERIPHERAL_BASE + 0x1000)
+#define MHU_RECV_NS_BASE (PERIPHERAL_BASE + 0x2000)
+#define MHU_SEND_NS_BASE (PERIPHERAL_BASE + 0x3000)
+#define MHU_RECV_S_BASE (PERIPHERAL_BASE + 0x4000)
+#define MHU_SEND_S_BASE (PERIPHERAL_BASE + 0x5000)
+#define WDOG_BASE (PERIPHERAL_BASE + 0x6000)
+#define S32K_CNTCONTROL_BASE (PERIPHERAL_BASE + 0x7000)
+#define S32K_CNTCTL_BASE (PERIPHERAL_BASE + 0x8000)
+#define S32K_CNTBASE0_BASE (PERIPHERAL_BASE + 0x9000)
+#define CS_CNTCONTROL_BASE (PERIPHERAL_BASE + 0xA000)
+
+/*
+ * Power control peripherals
+ */
+#define PIK_SCP_BASE (POWER_PERIPHERAL_BASE + 0x000000)
+#define PIK_DEBUG_BASE (POWER_PERIPHERAL_BASE + 0x020000)
+#define SENSOR_DEBUG_BASE (POWER_PERIPHERAL_BASE + 0x030000)
+#define PIK_SYSTEM_BASE (POWER_PERIPHERAL_BASE + 0x040000)
+#define SENSOR_SYSTEM_BASE (POWER_PERIPHERAL_BASE + 0x050000)
+#define PIK_CLUS0_BASE (POWER_PERIPHERAL_BASE + 0x060000)
+#define SENSOR_CLUS0_BASE (POWER_PERIPHERAL_BASE + 0x070000)
+#define PIK_CLUS1_BASE (POWER_PERIPHERAL_BASE + 0x080000)
+#define SENSOR_CLUS1_BASE (POWER_PERIPHERAL_BASE + 0x090000)
+#define PIK_GPU_BASE (POWER_PERIPHERAL_BASE + 0x0A0000)
+#define SENSOR_GPU_BASE (POWER_PERIPHERAL_BASE + 0x0B0000)
+#define PIK_VPU_BASE (POWER_PERIPHERAL_BASE + 0x0C0000)
+#define SENSOR_VPU_BASE (POWER_PERIPHERAL_BASE + 0x0D0000)
+#define PIK_DPU_BASE (POWER_PERIPHERAL_BASE + 0x0E0000)
+#define SENSOR_DPU_BASE (POWER_PERIPHERAL_BASE + 0x0F0000)
+#define PIK_DEBUG_CHAIN_BASE (POWER_PERIPHERAL_BASE + 0x100000)
+
+/*
+ * PPU base address
+ */
+#define PPU_SCP_BASE (PIK_SCP_BASE + 0x1000)
+#define PPU_SYS0_BASE (PIK_SYSTEM_BASE + 0x1000)
+#define PPU_SYS1_BASE (PIK_SYSTEM_BASE + 0x2000)
+#define PPU_DEBUG_BASE (PIK_DEBUG_BASE + 0x1000)
+#define PPU_CLUS0CORE0_BASE (PIK_CLUS0_BASE + 0x2000)
+#define PPU_CLUS0CORE1_BASE (PIK_CLUS0_BASE + 0x3000)
+#define PPU_CLUS0CORE2_BASE (PIK_CLUS0_BASE + 0x4000)
+#define PPU_CLUS0CORE3_BASE (PIK_CLUS0_BASE + 0x5000)
+#define PPU_CLUS0CORE4_BASE (PIK_CLUS0_BASE + 0x6000)
+#define PPU_CLUS0CORE5_BASE (PIK_CLUS0_BASE + 0x7000)
+#define PPU_CLUS0CORE6_BASE (PIK_CLUS0_BASE + 0x8000)
+#define PPU_CLUS0CORE7_BASE (PIK_CLUS0_BASE + 0x9000)
+#define PPU_CLUS0_BASE (PIK_CLUS0_BASE + 0x1000)
+#define PPU_CLUS1CORE0_BASE (PIK_CLUS1_BASE + 0x2000)
+#define PPU_CLUS1CORE1_BASE (PIK_CLUS1_BASE + 0x3000)
+#define PPU_CLUS1CORE2_BASE (PIK_CLUS1_BASE + 0x4000)
+#define PPU_CLUS1CORE3_BASE (PIK_CLUS1_BASE + 0x5000)
+#define PPU_CLUS1_BASE (PIK_CLUS1_BASE + 0x1000)
+#define PPU_GPU_BASE (PIK_GPU_BASE + 0x1000)
+#define PPU_VPU_BASE (PIK_VPU_BASE + 0x1000)
+#define PPU_DPU_BASE (PIK_DPU_BASE + 0x1000)
+
+/*
+ * System access port 1
+ */
+#define TRUSTED_RAM_BASE (SYS1_BASE + 0x04000000)
+#define NONTRUSTED_RAM_BASE (SYS1_BASE + 0x06000000)
+#define CCI_BASE (SYS1_BASE + 0x2A000000)
+#define ARACHNE_BASE (SYS1_BASE + 0x2A100000)
+#define SID_BASE (SYS1_BASE + 0x2A420000)
+#define REFCLK_CNTCONTROL_BASE (SYS1_BASE + 0x2A430000)
+#define DMC_BASE (SYS1_BASE + 0x2A500000)
+
+#endif /* SGM776_MMAP_H */
diff --git a/product/sgm776/include/sgm776_mmap_scp.h b/product/sgm776/include/sgm776_mmap_scp.h
new file mode 100644
index 00000000..147b1f16
--- /dev/null
+++ b/product/sgm776/include/sgm776_mmap_scp.h
@@ -0,0 +1,19 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * SCP ROM and RAM memory bases. These definitions are kept isolated without
+ * the UINT32_C() or UL decorators allowing them to be used in the linker
+ * script.
+ */
+
+#ifndef SGM776_MMAP_SCP_H
+#define SGM776_MMAP_SCP_H
+
+#define SCP_ROM_BASE 0x00000000
+#define SCP_RAM_BASE 0x10000000
+
+#endif /* SGM776_MMAP_SCP_H */
diff --git a/product/sgm776/include/sgm776_pik.h b/product/sgm776/include/sgm776_pik.h
new file mode 100644
index 00000000..bdb57c11
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik.h
@@ -0,0 +1,29 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_H
+#define SGM776_PIK_H
+
+#include <sgm776_mmap.h>
+#include <sgm776_pik_cpu.h>
+#include <sgm776_pik_debug.h>
+#include <sgm776_pik_dpu.h>
+#include <sgm776_pik_scp.h>
+#include <sgm776_pik_gpu.h>
+#include <sgm776_pik_system.h>
+#include <sgm776_pik_vpu.h>
+
+#define PIK_CLUS0 ((struct pik_cpu_reg *) PIK_CLUS0_BASE)
+#define PIK_CLUS1 ((struct pik_cpu_reg *) PIK_CLUS1_BASE)
+#define PIK_DEBUG ((struct pik_debug_reg *) PIK_DEBUG_BASE)
+#define PIK_DPU ((struct pik_dpu_reg *) PIK_DPU_BASE)
+#define PIK_GPU ((struct pik_gpu_reg *) PIK_GPU_BASE)
+#define PIK_SCP ((struct pik_scp_reg *) PIK_SCP_BASE)
+#define PIK_SYSTEM ((struct pik_system_reg *) PIK_SYSTEM_BASE)
+#define PIK_VPU ((struct pik_vpu_reg *) PIK_VPU_BASE)
+
+#endif /* SGM776_PIK_H */
diff --git a/product/sgm776/include/sgm776_pik_cpu.h b/product/sgm776/include/sgm776_pik_cpu.h
new file mode 100644
index 00000000..34cdd146
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_cpu.h
@@ -0,0 +1,94 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_CPU_H
+#define SGM776_PIK_CPU_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+#define PE_COUNT_MAX 16
+
+/*!
+ * \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[PE_COUNT_MAX];
+ 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[PE_COUNT_MAX];
+ uint8_t RESERVED8[0xA00 - 0x960];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_RW uint32_t CLKFORCE_SET;
+ FWK_RW uint32_t CLKFORCE_CLR;
+ uint8_t RESERVED9[0xB00 - 0xA0C];
+ FWK_R uint32_t NERRIQ_INT_STATUS;
+ FWK_R uint32_t NFAULTIQ_INT_STATUS;
+ uint8_t RESERVED10[0xFB4 - 0xB08];
+ FWK_R uint32_t CAP3;
+ FWK_R uint32_t CAP2;
+ FWK_R uint32_t CAP;
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED11[0xFD0 - 0xFC4];
+ FWK_R uint32_t PID4;
+ FWK_R uint32_t PID5;
+ FWK_R uint32_t PID6;
+ FWK_R uint32_t PID7;
+ FWK_R uint32_t PID0;
+ FWK_R uint32_t PID1;
+ FWK_R uint32_t PID2;
+ FWK_R uint32_t PID3;
+ FWK_R uint32_t ID0;
+ FWK_R uint32_t ID1;
+ FWK_R uint32_t ID2;
+ FWK_R uint32_t ID3;
+};
+
+#define PIK_CPU_CAP_CLUSSYNC UINT32_C(0x00000001)
+#define PIK_CPU_CAP_CORESYNC(CORE) ((uint32_t)(1 << ((CORE) + 1)))
+#define PIK_CPU_CAP_PE_MASK UINT32_C(0xF0000000)
+#define PIK_CPU_CAP_PE_POS 28
+
+#define PIK_CPU_PCL_CONFIG_NO_OF_PPU UINT32_C(0x0000000F)
+
+#endif /* SGM776_PIK_CPU_H */
diff --git a/product/sgm776/include/sgm776_pik_debug.h b/product/sgm776/include/sgm776_pik_debug.h
new file mode 100644
index 00000000..5421fae9
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_debug.h
@@ -0,0 +1,65 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_DEBUG_H
+#define SGM776_PIK_DEBUG_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \brief Debug register definitions
+ */
+struct pik_debug_reg {
+ FWK_R uint32_t DBG_PWR_REQ_ST[4];
+ FWK_R uint32_t DBG_PWR_REQ_ACK[4];
+ FWK_R uint32_t DBG_RST_REQ_ST;
+ FWK_R uint32_t DBG_RST_ACK;
+ uint8_t RESERVED0[0x30 - 0x28];
+ FWK_R uint32_t SYS_PWR_REQ_ST[4];
+ FWK_R uint32_t SYS_PWR_REQ_ACK[4];
+ FWK_R uint32_t SYS_RST_REQ_ST;
+ uint8_t RESERVED1[0x60 - 0x54];
+ FWK_RW uint32_t DEBUG_CONFIG;
+ uint8_t RESERVED2[0x810 - 0x64];
+ FWK_RW uint32_t TRACECLK_CTRL;
+ FWK_RW uint32_t TRACECLK_DIV1;
+ uint8_t RESERVED3[0x820 - 0x818];
+ FWK_RW uint32_t PCLKDBG_CTRL;
+ FWK_RW uint32_t PCLKDBG_DIV1;
+ uint8_t RESERVED4[0x830 - 0x828];
+ FWK_RW uint32_t DBGCLK_CTRL;
+ FWK_RW uint32_t DBGCLK_DIV1;
+ uint8_t RESERVED5[0xA00 - 0x838];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_RW uint32_t CLKFORCE_SET;
+ FWK_RW uint32_t CLKFORCE_CLR;
+ uint8_t RESERVED6[0xB00 - 0xA0C];
+ FWK_R uint32_t DBG_PWR_REQ_INT_ST[4];
+ FWK_R uint32_t DBG_RST_REQ_INT_ST;
+ uint8_t RESERVED7[0xB20 - 0xB14];
+ FWK_R uint32_t SYS_PWR_REQ_INT_ST[4];
+ FWK_R uint32_t SYS_RST_REQ_INT_ST;
+ uint8_t RESERVED8[0xFBC - 0xB34];
+ FWK_R uint32_t CAP;
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED9[0xFD0 - 0xFC4];
+ FWK_R uint32_t PID4;
+ FWK_R uint32_t PID5;
+ FWK_R uint32_t PID6;
+ FWK_R uint32_t PID7;
+ FWK_R uint32_t PID0;
+ FWK_R uint32_t PID1;
+ FWK_R uint32_t PID2;
+ FWK_R uint32_t PID3;
+ FWK_R uint32_t ID0;
+ FWK_R uint32_t ID1;
+ FWK_R uint32_t ID2;
+ FWK_R uint32_t ID3;
+};
+
+#endif /* SGM776_PIK_DEBUG_H */
diff --git a/product/sgm776/include/sgm776_pik_dpu.h b/product/sgm776/include/sgm776_pik_dpu.h
new file mode 100644
index 00000000..fd3ebdce
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_dpu.h
@@ -0,0 +1,43 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_DPU_H
+#define SGM776_PIK_DPU_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \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;
+};
+
+#endif /* SGM776_PIK_DPU_H */
diff --git a/product/sgm776/include/sgm776_pik_gpu.h b/product/sgm776/include/sgm776_pik_gpu.h
new file mode 100644
index 00000000..f10af96b
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_gpu.h
@@ -0,0 +1,45 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_GPU_H
+#define SGM776_PIK_GPU_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \brief GPU PIK register definitions
+ */
+struct pik_gpu_reg {
+ uint8_t RESERVED0[0x810];
+ FWK_RW uint32_t GPUCLK_CTRL;
+ FWK_RW uint32_t GPUCLK_DIV1;
+ FWK_RW uint32_t GPUCLK_DIV2;
+ uint8_t RESERVED1[0x820 - 0x81C];
+ FWK_RW uint32_t ACLKGPU_CTRL;
+ uint8_t RESERVED2[0xA00 - 0x824];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_W uint32_t CLKFORCE_SET;
+ FWK_W uint32_t CLKFORCE_CLR;
+ uint8_t RESERVED3[0xFBC - 0xA0C];
+ FWK_R uint32_t CAP;
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED4[0xFD0 - 0xFC4];
+ FWK_R uint32_t PID4;
+ FWK_R uint32_t PID5;
+ FWK_R uint32_t PID6;
+ FWK_R uint32_t PID7;
+ FWK_R uint32_t PID0;
+ FWK_R uint32_t PID1;
+ FWK_R uint32_t PID2;
+ FWK_R uint32_t PID3;
+ FWK_R uint32_t ID0;
+ FWK_R uint32_t ID1;
+ FWK_R uint32_t ID2;
+ FWK_R uint32_t ID3;
+};
+#endif /* SGM776_PIK_GPU_H */
diff --git a/product/sgm776/include/sgm776_pik_scp.h b/product/sgm776/include/sgm776_pik_scp.h
new file mode 100644
index 00000000..ae2258db
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_scp.h
@@ -0,0 +1,61 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_SCP_H
+#define SGM776_PIK_SCP_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \brief SCP PIK register definitions
+ */
+struct pik_scp_reg {
+ uint8_t RESERVED0[0x10];
+ FWK_RW uint32_t RESET_SYNDROME;
+ FWK_RW uint32_t WIC_CTRL;
+ FWK_R uint32_t WIC_STATUS;
+ uint8_t RESERVED1[0xA00 - 0x1C];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_RW uint32_t CLKFORCE_SET;
+ FWK_RW uint32_t CLKFORCE_CLR;
+ uint32_t RESERVED2;
+ FWK_R uint32_t PLL_STATUS0;
+ FWK_R uint32_t PLL_STATUS1;
+ uint8_t RESERVED3[0xFC0 - 0xA18];
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED4[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_STATUS0_REFCLK UINT32_C(0x00000001)
+#define PLL_STATUS0_GPUPLLLOCK UINT32_C(0x00000008)
+#define PLL_STATUS0_VIDEOPLLLOCK UINT32_C(0x00000010)
+#define PLL_STATUS0_SYSPLLLOCK UINT32_C(0x00000020)
+#define PLL_STATUS0_DISPLAYPLLLOCK UINT32_C(0x00000040)
+
+#define PLL_STATUS1_CPUPLLLOCK(CORE, PLL) \
+ ((uint32_t)((1 << (PLL)) << ((CORE) * 8)))
+
+#define RESET_SYNDROME_PORESET UINT32_C(0x01)
+#define RESET_SYNDROME_WDOGRESET_SCP UINT32_C(0x02)
+#define RESET_SYNDROME_WDOGRESET_SYS UINT32_C(0x04)
+#define RESET_SYNDROME_SYSRESETREQ UINT32_C(0x08)
+#define RESET_SYNDROME_SCPM3LOCKUP UINT32_C(0x10)
+
+#endif /* SGM776_PIK_SCP_H */
diff --git a/product/sgm776/include/sgm776_pik_system.h b/product/sgm776/include/sgm776_pik_system.h
new file mode 100644
index 00000000..3099713b
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_system.h
@@ -0,0 +1,69 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_SYSTEM_H
+#define SGM776_PIK_SYSTEM_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \brief System PIK register definitions
+ */
+struct pik_system_reg {
+ uint8_t RESERVED0[0x800];
+ FWK_RW uint32_t PPUCLK_CTRL;
+ FWK_RW uint32_t PPUCLK_DIV1;
+ uint8_t RESERVED1[0x810 - 0x808];
+ FWK_RW uint32_t NOCMEMCLK_CTRL;
+ FWK_RW uint32_t NOCMEMCLK_DIV1;
+ uint8_t RESERVED2[0x820 - 0x818];
+ FWK_RW uint32_t ACLKCCI_CTRL;
+ FWK_RW uint32_t ACLKCCI_DIV1;
+ uint8_t RESERVED3[0x840 - 0x828];
+ FWK_RW uint32_t TCUCLK_CTRL;
+ FWK_RW uint32_t TCUCLK_DIV1;
+ uint8_t RESERVED4[0x850 - 0x848];
+ FWK_RW uint32_t GICCLK_CTRL;
+ FWK_RW uint32_t GICCLK_DIV1;
+ uint8_t RESERVED5[0x860 - 0x858];
+ FWK_RW uint32_t PCLKSCP_CTRL;
+ FWK_RW uint32_t PCLKSCP_DIV1;
+ uint8_t RESERVED6[0x870 - 0x868];
+ FWK_RW uint32_t SYSPERCLK_CTRL;
+ FWK_RW uint32_t SYSPERCLK_DIV1;
+ uint8_t RESERVED7[0x880 - 0x878];
+ FWK_RW uint32_t FCMCLK_CTRL;
+ FWK_RW uint32_t FCMCLK_DIV1;
+ uint8_t RESERVED8[0xA00 - 0x888];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_RW uint32_t CLKFORCE_SET;
+ FWK_RW uint32_t CLKFORCE_CLR;
+ uint8_t RESERVED9[0xFBC - 0xA0C];
+ FWK_R uint32_t CAP;
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED10[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 CAP_GICCLK_GATING_SUPPORT UINT32_C(0x00000001)
+#define CAP_TCUCLK_SUPPORT UINT32_C(0x00000002)
+#define CAP_ELA_SUPPORT UINT32_C(0x00000004)
+#define CAP_FCMCLK_SUPPORT UINT32_C(0x00000008)
+
+#endif /* SGM776_PIK_SYSTEM_H */
diff --git a/product/sgm776/include/sgm776_pik_vpu.h b/product/sgm776/include/sgm776_pik_vpu.h
new file mode 100644
index 00000000..66269146
--- /dev/null
+++ b/product/sgm776/include/sgm776_pik_vpu.h
@@ -0,0 +1,43 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_PIK_VPU_H
+#define SGM776_PIK_VPU_H
+
+#include <stdint.h>
+#include <fwk_macros.h>
+
+/*!
+ * \brief VPU PIK register definitions
+ */
+struct pik_vpu_reg {
+ uint8_t RESERVED0[0x810];
+ FWK_RW uint32_t VIDEOCLK_CTRL;
+ FWK_RW uint32_t VIDEOCLK_DIV1;
+ FWK_RW uint32_t VIDEOCLK_DIV2;
+ uint8_t RESERVED1[0xA00 - 0x81C];
+ FWK_R uint32_t CLKFORCE_STATUS;
+ FWK_W uint32_t CLKFORCE_SET;
+ FWK_W uint32_t CLKFORCE_CLR;
+ uint8_t RESERVED2[0xFC0 - 0xA0C];
+ FWK_R uint32_t PCL_CONFIG;
+ uint8_t RESERVED3[0xFD0 - 0xFC4];
+ FWK_R uint32_t PID4;
+ FWK_R uint32_t PID5;
+ FWK_R uint32_t PID6;
+ FWK_R uint32_t PID7;
+ FWK_R uint32_t PID0;
+ FWK_R uint32_t PID1;
+ FWK_R uint32_t PID2;
+ FWK_R uint32_t PID3;
+ FWK_R uint32_t ID0;
+ FWK_R uint32_t ID1;
+ FWK_R uint32_t ID2;
+ FWK_R uint32_t ID3;
+};
+
+#endif /* SGM776_PIK_VPU_H */
diff --git a/product/sgm776/include/sgm776_scmi.h b/product/sgm776/include/sgm776_scmi.h
new file mode 100644
index 00000000..b06607f1
--- /dev/null
+++ b/product/sgm776/include/sgm776_scmi.h
@@ -0,0 +1,29 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * Definitions for SCMI and SMT module configurations.
+ */
+
+#ifndef SGM776_SCMI_H
+#define SGM776_SCMI_H
+
+/* SCMI agent identifiers */
+enum sgm776_scmi_agent_id {
+ /* 0 is reserved for the platform */
+ SCMI_AGENT_ID_OSPM = 1,
+ SCMI_AGENT_ID_PSCI,
+ SCMI_AGENT_ID_COUNT
+};
+
+/* SCMI service indexes */
+enum sgm776_scmi_service_idx {
+ SGM776_SCMI_SERVICE_IDX_PSCI,
+ SGM776_SCMI_SERVICE_IDX_OSPM_0,
+ SGM776_SCMI_SERVICE_IDX_OSPM_1,
+ SGM776_SCMI_SERVICE_IDX_COUNT,
+};
+#endif /* SGM776_SCMI_H */
diff --git a/product/sgm776/include/sgm776_sds.h b/product/sgm776/include/sgm776_sds.h
new file mode 100644
index 00000000..b3da4fe7
--- /dev/null
+++ b/product/sgm776/include/sgm776_sds.h
@@ -0,0 +1,149 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_SDS_H
+#define SGM776_SDS_H
+
+#include <mod_sds.h>
+
+/*
+ * Structure identifiers.
+ */
+enum sgm776_sds_struct_id {
+ SGM776_SDS_CPU_INFO = 1 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_ROM_VERSION = 2 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_RAM_VERSION = 3 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_PLATFORM_ID = 4 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_RESET_SYNDROME = 5 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_FEATURE_AVAILABILITY = 6 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_CPU_BOOTCTR = 7 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_CPU_FLAGS = 8 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+ SGM776_SDS_BOOTLOADER = 9 | (1 << MOD_SDS_ID_VERSION_MAJOR_POS),
+};
+
+/*
+ * Structure sizes.
+ */
+#define SGM776_SDS_CPU_INFO_SIZE 4
+#define SGM776_SDS_ROM_VERSION_SIZE 4
+#define SGM776_SDS_RAM_VERSION_SIZE 4
+#define SGM776_SDS_PLATFORM_ID_SIZE 8
+#define SGM776_SDS_RESET_SYNDROME_SIZE 4
+#define SGM776_SDS_FEATURE_AVAILABILITY_SIZE 4
+#define SGM776_SDS_CPU_BOOTCTR_SIZE 8
+#define SGM776_SDS_CPU_FLAGS_SIZE 8
+#define SGM776_SDS_BOOTLOADER_SIZE 12
+
+/*
+ * Field masks and offsets for the SGM776_SDS_AP_CPU_INFO structure.
+ */
+#define SGM776_SDS_CPU_INFO_PRIMARY_MASK 0xFFFFFFFF
+#define SGM776_SDS_CPU_INFO_PRIMARY_POS 0
+
+/*
+ * Structure, field masks and offsets for the SGM776_SDS_PLATFORM_ID structure.
+ */
+
+struct sgm776_sds_platid {
+ uint32_t platform_identifier;
+ uint32_t platform_type_identifier;
+};
+
+#define SGM776_SDS_PLATID_PARTNO_MASK 0xFFF
+#define SGM776_SDS_PLATID_DESIGNER_MASK 0xFF000
+#define SGM776_SDS_PLATID_REV_MINOR_MASK 0xF00000
+#define SGM776_SDS_PLATID_REV_MAJOR_MASK 0xF000000
+#define SGM776_SDS_PLATID_CONFIG_MASK 0xF0000000
+#define SGM776_SDS_PLATID_TYPE_MASK 0xF
+
+#define SGM776_SDS_PLATID_PARTNO_POS 0
+#define SGM776_SDS_PLATID_DESIGNER_POS 12
+#define SGM776_SDS_PLATID_REV_MINOR_POS 20
+#define SGM776_SDS_PLATID_REV_MAJOR_POS 24
+#define SGM776_SDS_PLATID_CONFIG_POS 28
+
+#define SGM776_SDS_PLATID_TYPE_POS 0
+/*
+ * Field masks and offsets for the SGM776_SDS_RESET_SYNDROME structure.
+ */
+#define SGM776_SDS_RESET_SYNDROME_POR_MASK 0x1
+#define SGM776_SDS_RESET_SYNDROME_WDOGSCP_MASK 0x2
+#define SGM776_SDS_RESET_SYNDROME_WDOGAP_MASK 0x4
+#define SGM776_SDS_RESET_SYNDROME_SYSRESET_MASK 0x8
+#define SGM776_SDS_RESET_SYNDROME_M3LOCKUP_MASK 0x10
+
+#define SGM776_SDS_RESET_SYNDROME_POR_POS 0
+#define SGM776_SDS_RESET_SYNDROME_WDOGSCP_POS 1
+#define SGM776_SDS_RESET_SYNDROME_WDOGAP_POS 2
+#define SGM776_SDS_RESET_SYNDROME_SYSRESET_POS 3
+#define SGM776_SDS_RESET_SYNDROME_M3LOCKUP_POS 4
+
+/*
+ * Field masks and offsets for the SGM776_SDS_FEATURE_AVAILABILITY structure.
+ */
+#define SGM776_SDS_FEATURE_FIRMWARE_MASK 0x1
+#define SGM776_SDS_FEATURE_DMC_MASK 0x2
+#define SGM776_SDS_FEATURE_MESSAGING_MASK 0x4
+
+#define SGM776_SDS_FEATURE_FIRMWARE_POS 0
+#define SGM776_SDS_FEATURE_DMC_POS 1
+#define SGM776_SDS_FEATURE_MESSAGING_POS 2
+
+/*
+ * Field masks and offsets for the SGM776_SDS_CPU_BOOTCTR structure.
+ */
+#define SGM776_SDS_CPU_BOOTCTR_CPU0_MASK 0xFF
+#define SGM776_SDS_CPU_BOOTCTR_CPU1_MASK 0xFF00
+#define SGM776_SDS_CPU_BOOTCTR_CPU2_MASK 0xFF0000
+#define SGM776_SDS_CPU_BOOTCTR_CPU3_MASK 0xFF000000
+#define SGM776_SDS_CPU_BOOTCTR_CPU4_MASK 0xFF
+#define SGM776_SDS_CPU_BOOTCTR_CPU5_MASK 0xFF00
+#define SGM776_SDS_CPU_BOOTCTR_CPU6_MASK 0xFF0000
+#define SGM776_SDS_CPU_BOOTCTR_CPU7_MASK 0xFF000000
+
+
+#define SGM776_SDS_CPU_BOOTCTR_CPU0_POS 0
+#define SGM776_SDS_CPU_BOOTCTR_CPU1_POS 8
+#define SGM776_SDS_CPU_BOOTCTR_CPU2_POS 16
+#define SGM776_SDS_CPU_BOOTCTR_CPU3_POS 24
+#define SGM776_SDS_CPU_BOOTCTR_CPU4_POS 0
+#define SGM776_SDS_CPU_BOOTCTR_CPU5_POS 8
+#define SGM776_SDS_CPU_BOOTCTR_CPU6_POS 16
+#define SGM776_SDS_CPU_BOOTCTR_CPU7_POS 24
+
+/*
+ * Field masks and offsets for the SGM776_SDS_CPU_FLAGS structure.
+ */
+#define SGM776_SDS_CPU_FLAGS_CPU0_WFI_MASK 0x1
+#define SGM776_SDS_CPU_FLAGS_CPU1_WFI_MASK 0x100
+#define SGM776_SDS_CPU_FLAGS_CPU2_WFI_MASK 0x10000
+#define SGM776_SDS_CPU_FLAGS_CPU3_WFI_MASK 0x1000000
+#define SGM776_SDS_CPU_FLAGS_CPU4_WFI_MASK 0x1
+#define SGM776_SDS_CPU_FLAGS_CPU5_WFI_MASK 0x100
+#define SGM776_SDS_CPU_FLAGS_CPU6_WFI_MASK 0x10000
+#define SGM776_SDS_CPU_FLAGS_CPU7_WFI_MASK 0x1000000
+
+#define SGM776_SDS_CPU_FLAGS_CPU0_WFI_POS 0
+#define SGM776_SDS_CPU_FLAGS_CPU1_WFI_POS 8
+#define SGM776_SDS_CPU_FLAGS_CPU2_WFI_POS 16
+#define SGM776_SDS_CPU_FLAGS_CPU3_WFI_POS 24
+#define SGM776_SDS_CPU_FLAGS_CPU4_WFI_POS 0
+#define SGM776_SDS_CPU_FLAGS_CPU5_WFI_POS 8
+#define SGM776_SDS_CPU_FLAGS_CPU6_WFI_POS 16
+#define SGM776_SDS_CPU_FLAGS_CPU7_WFI_POS 24
+/*
+ * Field masks and offsets for the SGM776_SDS_BOOTLOADER structure.
+ */
+#define SGM776_SDS_BOOTLOADER_VALID_MASK 0x1
+#define SGM776_SDS_BOOTLOADER_OFFSET_MASK 0xFFFFFFFF
+#define SGM776_SDS_BOOTLOADER_SIZE_MASK 0xFFFFFFFF
+
+#define SGM776_SDS_BOOTLOADER_VALID_POS 0
+#define SGM776_SDS_BOOTLOADER_OFFSET_POS 0
+#define SGM776_SDS_BOOTLOADER_SIZE_POS 0
+
+#endif /* SGM776_SDS_H */
diff --git a/product/sgm776/include/sgm776_sid.h b/product/sgm776/include/sgm776_sid.h
new file mode 100644
index 00000000..bcbb4fe9
--- /dev/null
+++ b/product/sgm776/include/sgm776_sid.h
@@ -0,0 +1,16 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGM776_SID_H
+#define SGM776_SID_H
+
+enum sgm776_sid_part {
+ SGM776_SID_PART_DUKE = 0x791,
+ SGM776_SID_PART_DAVIS = 0x792,
+};
+
+#endif /* SGM776_SID_H */
diff --git a/product/sgm776/include/software_mmap.h b/product/sgm776/include/software_mmap.h
new file mode 100644
index 00000000..081a54a6
--- /dev/null
+++ b/product/sgm776/include/software_mmap.h
@@ -0,0 +1,128 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * Software defined memory map shared between SCP and AP cores.
+ */
+
+#ifndef SOFTWARE_MMAP_H
+#define SOFTWARE_MMAP_H
+
+#include <fwk_macros.h>
+#include <system_mmap.h>
+
+/*
+ * The 4KiB AP/SCP Shared memory at the base of Trusted SRAM is used for several
+ * purposes. These are: the Shared Data Storage (SDS) Memory Region, the SCMI
+ * secure payload areas, and the context area for Application Processor
+ * firmware.
+ *
+ * Shared Data Storage (SDS) Memory Region: Used for structured storage of data
+ * that is shared between SCP Firmware and Application Processor firmware. The
+ * SDS Memory Region occupies the area between the context region base and
+ * the SCMI Secure Payload base.
+ *
+ * SCMI Secure Payload Areas: Storage for SCMI message contents in both the
+ * Agent->Platform and Platform->Agent directions.
+ *
+ * Application Processor Context Area: The usage of this area is defined by the
+ * firmware running on the Application Processors. The SCP Firmware must zero
+ * this memory before releasing any Application Processors. This area must
+ * always be located in the top 64 bytes of the 4KiB reserved region.
+ *
+ * +-----------------------+ 4096
+ * | |
+ * 64B | AP Context Area |
+ * | |
+ * +-----------------------+
+ * | |
+ * 256B | Unused |
+ * | |
+ * +-----------------------+
+ * | |
+ * | SCMI Sec. Payload |
+ * 128B | Platform to Agent |
+ * | |
+ * +-----------------------+
+ * | |
+ * 128B | SCMI Sec. Payload |
+ * | Agent to Platform |
+ * | |
+ * +-----------------------+
+ * | |
+ * 3520B | SDS Memory Region |
+ * | |
+ * +-----------------------+ 0
+ */
+
+/* Secure shared memory at the base of Trusted SRAM */
+#define SHARED_SECURE_BASE (TRUSTED_RAM_BASE)
+#define SHARED_SECURE_SIZE (4 * FWK_KIB)
+
+/* SDS Memory Region */
+#define SDS_MEM_BASE (SHARED_SECURE_BASE)
+#define SDS_MEM_SIZE (3520)
+
+/* AP Context Area */
+#define AP_CONTEXT_BASE (SHARED_SECURE_BASE + SHARED_SECURE_SIZE - \
+ AP_CONTEXT_SIZE)
+#define AP_CONTEXT_SIZE (64)
+
+/* SCMI Secure Payload Areas */
+#define SCMI_PAYLOAD_SIZE (128)
+#define SCMI_PAYLOAD_S_A2P_BASE (SDS_MEM_BASE + SDS_MEM_SIZE)
+#define SCMI_PAYLOAD_S_P2A_BASE (SCMI_PAYLOAD_S_A2P_BASE + SCMI_PAYLOAD_SIZE)
+
+/*
+ * The 4KiB AP/SCP Shared memory at the base of Non-trusted SRAM is used for the
+ * SCMI non-secure payload areas.
+ *
+ * Two SCMI non-Secure Payload Areas: Storage for SCMI message contents in both
+ * the Agent->Platform and Platform->Agent directions.
+ *
+ * +-----------------------+ 4096
+ * 3584B | Unused |
+ * +-----------------------+
+ * | |
+ * | Non-Sec. Channel 1 |
+ * | SCMI non-Sec. Payload |
+ * 128B | Platform to Agent |
+ * | |
+ * +-----------------------+
+ * | |
+ * | Non-Sec. Channel 1 |
+ * 128B | SCMI non-Sec. Payload |
+ * | Agent to Platform |
+ * | |
+ * +-----------------------+
+ * | |
+ * | Non-Sec. Channel 0 |
+ * | SCMI non-Sec. Payload |
+ * 128B | Platform to Agent |
+ * | |
+ * +-----------------------+
+ * | |
+ * | Non-Sec. Channel 0 |
+ * 128B | SCMI non-Sec. Payload |
+ * | Agent to Platform |
+ * | |
+ * +-----------------------+ 0
+ */
+
+/* Non-secure shared memory at the base of Non-trusted SRAM */
+#define SHARED_NONSECURE_BASE (NONTRUSTED_RAM_BASE)
+#define SHARED_NONSECURE_SIZE (4 * FWK_KIB)
+
+/* SCMI Non-Secure Payload Areas */
+#define SCMI_PAYLOAD0_NS_A2P_BASE (SHARED_NONSECURE_BASE)
+#define SCMI_PAYLOAD0_NS_P2A_BASE (SCMI_PAYLOAD0_NS_A2P_BASE + \
+ SCMI_PAYLOAD_SIZE)
+#define SCMI_PAYLOAD1_NS_A2P_BASE (SCMI_PAYLOAD0_NS_P2A_BASE + \
+ SCMI_PAYLOAD_SIZE)
+#define SCMI_PAYLOAD1_NS_P2A_BASE (SCMI_PAYLOAD1_NS_A2P_BASE + \
+ SCMI_PAYLOAD_SIZE)
+
+#endif /* SOFTWARE_MMAP_H */
diff --git a/product/sgm776/include/system_clock.h b/product/sgm776/include/system_clock.h
new file mode 100644
index 00000000..923e3d34
--- /dev/null
+++ b/product/sgm776/include/system_clock.h
@@ -0,0 +1,16 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYSTEM_CLOCK_H
+#define SYSTEM_CLOCK_H
+
+#include <fwk_macros.h>
+
+#define CLOCK_RATE_REFCLK (50UL * FWK_MHZ)
+#define CLOCK_RATE_SYSPLLCLK (3600UL * FWK_MHZ)
+
+#endif /* SYSTEM_CLOCK_H */
diff --git a/product/sgm776/include/system_mmap.h b/product/sgm776/include/system_mmap.h
new file mode 100644
index 00000000..92594402
--- /dev/null
+++ b/product/sgm776/include/system_mmap.h
@@ -0,0 +1,61 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYSTEM_MMAP_H
+#define SYSTEM_MMAP_H
+
+#include <sgm776_mmap.h>
+
+#define DMC_EXTERNAL0 (SYS0_BASE + 0x3FBE0000)
+#define DMC_EXTERNAL1 (SYS0_BASE + 0x3FBF0000)
+#define DMC_EXTERNAL2 (SYS0_BASE + 0x3FC00000)
+#define DMC_EXTERNAL3 (SYS0_BASE + 0x3FC10000)
+
+#define BOARD_UART1_BASE (SYS0_BASE + 0x3FF70000)
+#define PLAT_BASE (SYS0_BASE + 0x3FFE0000)
+
+#define PLL_GPU (PLAT_BASE + 0x00000008)
+#define PLL_SYSTEM (PLAT_BASE + 0x0000000C)
+#define PLL_VIDEO (PLAT_BASE + 0x00000010)
+#define PLL_DISPLAY (PLAT_BASE + 0x00000014)
+
+#define PIX0_CONTROL (PLAT_BASE + 0x00000018)
+#define PIX1_CONTROL (PLAT_BASE + 0x0000001C)
+
+#define SWCLKTCK_CONTROL (PLAT_BASE + 0x00000020)
+#define SENSOR_SOC_TEMP (PLAT_BASE + 0x00000080)
+#define PLATFORM_ID (PLAT_BASE + 0x000000E0)
+
+#define PLL_CLUS0_0 (PLAT_BASE + 0x00000100)
+#define PLL_CLUS0_1 (PLAT_BASE + 0x00000104)
+#define PLL_CLUS0_2 (PLAT_BASE + 0x00000108)
+#define PLL_CLUS0_3 (PLAT_BASE + 0x0000010C)
+#define PLL_CLUS0_4 (PLAT_BASE + 0x00000110)
+#define PLL_CLUS0_5 (PLAT_BASE + 0x00000114)
+#define PLL_CLUS0_6 (PLAT_BASE + 0x00000118)
+#define PLL_CLUS0_7 (PLAT_BASE + 0x0000011C)
+
+#define DDR_PHY0 (SYS0_BASE + 0x3FB60000)
+#define DDR_PHY1 (SYS0_BASE + 0x3FB70000)
+#define DDR_PHY2 (SYS0_BASE + 0x3FB80000)
+#define DDR_PHY3 (SYS0_BASE + 0x3FB90000)
+
+#define GPV_CCI_GPU1 (SYS1_BASE + 0x2A004000)
+#define GPV_CCI_GPU0 (SYS1_BASE + 0x2A005000)
+#define GPV_CCI_LITTLE (SYS1_BASE + 0x2A006000)
+#define GPV_CCI_BIG (SYS1_BASE + 0x2A007000)
+#define GPV_VPU (SYS1_BASE + 0x2A243000)
+#define GPV_DPU0 (SYS1_BASE + 0x2A244000)
+#define GPV_DPU1 (SYS1_BASE + 0x2A245000)
+
+#define DMC_INTERNAL0 (SYS1_BASE + 0x2A500000)
+#define DMC_INTERNAL1 (SYS1_BASE + 0x2A540000)
+#define DMC_INTERNAL2 (SYS1_BASE + 0x2A580000)
+#define DMC_INTERNAL3 (SYS1_BASE + 0x2A5C0000)
+
+
+#endif /* SYSTEM_MMAP_H */
diff --git a/product/sgm776/include/system_mmap_scp.h b/product/sgm776/include/system_mmap_scp.h
new file mode 100644
index 00000000..4cb4d053
--- /dev/null
+++ b/product/sgm776/include/system_mmap_scp.h
@@ -0,0 +1,21 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * SCP ROM and RAM memory sizes. These definitions are kept isolated without
+ * the UINT32_C() or UL decorators allowing them to be used in the linker
+ * script.
+ */
+
+#ifndef SYSTEM_MMAP_SCP_H
+#define SYSTEM_MMAP_SCP_H
+
+#include <sgm776_mmap_scp.h>
+
+#define SCP_ROM_SIZE (64 * 1024)
+#define SCP_RAM_SIZE (128 * 1024)
+
+#endif /* SYSTEM_MMAP_SCP_H */
diff --git a/product/sgm776/module/sgm776_system/include/mod_sgm776_system.h b/product/sgm776/module/sgm776_system/include/mod_sgm776_system.h
new file mode 100644
index 00000000..851a05ec
--- /dev/null
+++ b/product/sgm776/module/sgm776_system/include/mod_sgm776_system.h
@@ -0,0 +1,44 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * SGM776 System Support
+ */
+
+#ifndef MOD_SGM776_SYSTEM_H
+#define MOD_SGM776_SYSTEM_H
+
+/*!
+ * \addtogroup GroupSGM776Module SGM776 Product Modules
+ * @{
+ */
+
+/*!
+ * \defgroup GroupSGM776System SGM776 System Support
+ *
+ * @{
+ */
+
+/*!
+ * \brief API indices.
+ */
+enum mod_sgm776_system_api_idx {
+ /*! API index for the driver interface of the SYSTEM POWER module */
+ MOD_SGM776_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER,
+
+ /*! Number of defined APIs */
+ MOD_SGM776_SYSTEM_API_COUNT
+};
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#endif /* MOD_SGM776_SYSTEM_H */
diff --git a/product/sgm776/module/sgm776_system/src/Makefile b/product/sgm776/module/sgm776_system/src/Makefile
new file mode 100644
index 00000000..b2408fcc
--- /dev/null
+++ b/product/sgm776/module/sgm776_system/src/Makefile
@@ -0,0 +1,11 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := SGM776 SYSTEM
+BS_LIB_SOURCES = mod_sgm776_system.c
+
+include $(BS_DIR)/lib.mk
diff --git a/product/sgm776/module/sgm776_system/src/mod_sgm776_system.c b/product/sgm776/module/sgm776_system/src/mod_sgm776_system.c
new file mode 100644
index 00000000..cfbba969
--- /dev/null
+++ b/product/sgm776/module/sgm776_system/src/mod_sgm776_system.c
@@ -0,0 +1,59 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * sgm776 System Support.
+ */
+
+#include <fmw_cmsis.h>
+#include <fwk_module.h>
+#include <mod_system_power.h>
+#include <mod_sgm776_system.h>
+
+/*
+ * Functions fulfilling the framework's module interface
+ */
+
+static int sgm776_system_shutdown(enum mod_pd_system_shutdown system_shutdown)
+{
+ NVIC_SystemReset();
+
+ return FWK_E_DEVICE;
+}
+
+static const struct mod_system_power_driver_api
+ sgm776_system_system_power_driver_api = {
+ .system_shutdown = sgm776_system_shutdown
+};
+
+/*
+ * Functions fulfilling the framework's module interface
+ */
+
+static int sgm776_system_init(fwk_id_t module_id, unsigned int unused,
+ const void *unused2)
+{
+ return FWK_SUCCESS;
+}
+
+static int sgm776_system_process_bind_request(fwk_id_t source_id,
+ fwk_id_t target_id, fwk_id_t api_id, const void **api)
+{
+ *api = &sgm776_system_system_power_driver_api;
+
+ return FWK_SUCCESS;
+}
+
+const struct fwk_module module_sgm776_system = {
+ .name = "sgm776_SYSTEM",
+ .api_count = MOD_SGM776_SYSTEM_API_COUNT,
+ .type = FWK_MODULE_TYPE_DRIVER,
+ .init = sgm776_system_init,
+ .process_bind_request = sgm776_system_process_bind_request,
+};
+
+/* No elements, no module configuration data */
+struct fwk_module_config config_sgm776_system = { 0 };
diff --git a/product/sgm776/product.mk b/product/sgm776/product.mk
new file mode 100644
index 00000000..9333cd50
--- /dev/null
+++ b/product/sgm776/product.mk
@@ -0,0 +1,14 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platforms supported by the sgm776 product: Duke.
+#
+
+BS_PRODUCT_NAME := sgm776
+
+BS_FIRMWARE_LIST := \
+ scp_romfw \
+ scp_ramfw
diff --git a/product/sgm776/scp_ramfw/RTX_Config.h b/product/sgm776/scp_ramfw/RTX_Config.h
new file mode 100644
index 00000000..eaa90d80
--- /dev/null
+++ b/product/sgm776/scp_ramfw/RTX_Config.h
@@ -0,0 +1,56 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-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 an RTX file
+ * in order to create an object file containing the configuration.
+ */
+
+#ifndef RTX_CONFIG_H_
+#define RTX_CONFIG_H_
+
+/* System */
+#define OS_DYNAMIC_MEM_SIZE 0
+#define OS_TICK_FREQ 1000 /* Hz */
+#define OS_ROBIN_ENABLE 0
+#define OS_ROBIN_TIMEOUT 0
+#define OS_ISR_FIFO_QUEUE 16
+
+/* Thread */
+#define OS_THREAD_OBJ_MEM 0
+#define OS_THREAD_NUM 1
+#define OS_THREAD_DEF_STACK_NUM 0
+#define OS_THREAD_USER_STACK_SIZE 0
+#define OS_STACK_SIZE 200
+#define OS_IDLE_THREAD_STACK_SIZE 200
+#define OS_STACK_CHECK 1
+#define OS_STACK_WATERMARK 0
+#define OS_PRIVILEGE_MODE 1
+
+/* Timer */
+#define OS_TIMER_OBJ_MEM 0
+#define OS_TIMER_NUM 1
+#define OS_TIMER_THREAD_PRIO 40
+#define OS_TIMER_THREAD_STACK_SIZE 200
+#define OS_TIMER_CB_QUEUE 4
+
+/* Event flags */
+#define OS_EVFLAGS_OBJ_MEM 0
+#define OS_EVFLAGS_NUM 1
+
+#define OS_MUTEX_OBJ_MEM 0
+#define OS_MUTEX_NUM 1
+#define OS_SEMAPHORE_OBJ_MEM 0
+#define OS_SEMAPHORE_NUM 1
+#define OS_MEMPOOL_OBJ_MEM 0
+#define OS_MEMPOOL_NUM 1
+#define OS_MEMPOOL_DATA_SIZE 0
+#define OS_MSGQUEUE_OBJ_MEM 0
+#define OS_MSGQUEUE_NUM 1
+#define OS_MSGQUEUE_DATA_SIZE 0
+
+#endif /* RTX_CONFIG_H_ */
diff --git a/product/sgm776/scp_ramfw/clock_devices.h b/product/sgm776/scp_ramfw/clock_devices.h
new file mode 100644
index 00000000..495c8c6f
--- /dev/null
+++ b/product/sgm776/scp_ramfw/clock_devices.h
@@ -0,0 +1,26 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCK_DEVICES_H
+#define CLOCK_DEVICES_H
+
+/*!
+ * \brief Clock device indexes.
+ */
+enum clock_dev_idx {
+ CLOCK_DEV_IDX_BIG,
+ CLOCK_DEV_IDX_LITTLE,
+ CLOCK_DEV_IDX_GPU,
+ CLOCK_DEV_IDX_VPU,
+ CLOCK_DEV_IDX_DPU,
+ CLOCK_DEV_IDX_PIXEL_0,
+ CLOCK_DEV_IDX_PIXEL_1,
+ CLOCK_DEV_IDX_INTERCONNECT,
+ CLOCK_DEV_IDX_COUNT
+};
+
+#endif /* CLOCK_DEVICES_H */
diff --git a/product/sgm776/scp_ramfw/config_clock.c b/product/sgm776/scp_ramfw/config_clock.c
new file mode 100644
index 00000000..2994ffd0
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_clock.c
@@ -0,0 +1,118 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_css_clock.h>
+#include <mod_system_pll.h>
+#include <mod_pik_clock.h>
+#include <mod_power_domain.h>
+#include <config_power_domain.h>
+#include <clock_devices.h>
+#include <sgm776_core.h>
+
+static const struct fwk_element clock_dev_desc_table[] = {
+ [CLOCK_DEV_IDX_BIG] = {
+ .name = "CPU_GROUP_BIG",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 0),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
+ MOD_CSS_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_LITTLE] = {
+ .name = "CPU_GROUP_LITTLE",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 1),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
+ MOD_CSS_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_GPU] = {
+ .name = "GPU",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 2),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
+ MOD_CSS_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_VPU] = {
+ .name = "VPU",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 3),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
+ MOD_CSS_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_DPU] = {
+ .name = "DPU",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 4),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_CSS_CLOCK,
+ MOD_CSS_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_PIXEL_0] = {
+ .name = "PIXEL_0",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 5),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ }),
+ },
+ [CLOCK_DEV_IDX_PIXEL_1] = {
+ .name = "PIXEL_1",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 6),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ }),
+ },
+ [CLOCK_DEV_IDX_INTERCONNECT] = {
+ .name = "INTERCONNECT",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 11),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CLOCK),
+ }),
+ },
+ [CLOCK_DEV_IDX_COUNT] = { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id)
+{
+ unsigned int i;
+ unsigned int core_count;
+ struct mod_clock_dev_config *dev_config;
+
+ core_count = sgm776_core_get_count();
+
+ /* Configure all clocks to respond to changes in SYSTOP power state */
+ for (i = 0; i < CLOCK_DEV_IDX_COUNT; i++) {
+ dev_config =
+ (struct mod_clock_dev_config *)clock_dev_desc_table[i].data;
+ dev_config->pd_source_id = FWK_ID_ELEMENT(
+ FWK_MODULE_IDX_POWER_DOMAIN,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_COUNT + core_count);
+ }
+
+ return clock_dev_desc_table;
+}
+
+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/sgm776/scp_ramfw/config_css_clock.c b/product/sgm776/scp_ramfw/config_css_clock.c
new file mode 100644
index 00000000..183d9334
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_css_clock.c
@@ -0,0 +1,354 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_assert.h>
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_css_clock.h>
+#include <mod_system_pll.h>
+#include <mod_pik_clock.h>
+#include <mod_sid.h>
+#include <sgm776_pik.h>
+
+static const struct mod_css_clock_rate rate_table_cpu_group_big[] = {
+ {
+ /* Super Underdrive */
+ .rate = 1313 * FWK_MHZ,
+ .pll_rate = 1313 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+ {
+ /* Underdrive */
+ .rate = 1531 * FWK_MHZ,
+ .pll_rate = 1531 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+ {
+ /* Nominal */
+ .rate = 1750 * FWK_MHZ,
+ .pll_rate = 1750 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+ {
+ /* Overdrive */
+ .rate = 2100 * FWK_MHZ,
+ .pll_rate = 2100 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+ {
+ /* Super Overdrive */
+ .rate = 2700 * FWK_MHZ,
+ .pll_rate = 2700 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+};
+
+static const struct mod_css_clock_rate rate_table_cpu_group_little[] = {
+ {
+ /* Super Underdrive */
+ .rate = 665 * FWK_MHZ,
+ .pll_rate = 665 * 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 = 998 * FWK_MHZ,
+ .pll_rate = 998 * 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 = 1330 * FWK_MHZ,
+ .pll_rate = 1330 * 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 = 1463 * FWK_MHZ,
+ .pll_rate = 1463 * 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 = 2200 * FWK_MHZ,
+ .pll_rate = 2200 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+};
+
+static const struct mod_css_clock_rate rate_table_gpu[] = {
+ {
+ .rate = 450 * FWK_MHZ,
+ .pll_rate = 450 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+ {
+ .rate = 487500 * FWK_KHZ,
+ .pll_rate = 487500 * FWK_KHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+ {
+ .rate = 525 * FWK_MHZ,
+ .pll_rate = 525 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+ {
+ .rate = 562500 * FWK_KHZ,
+ .pll_rate = 562500 * FWK_KHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+ {
+ /* Nominal */
+ .rate = 800 * FWK_MHZ,
+ .pll_rate = 800 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+};
+
+static const struct mod_css_clock_rate rate_table_vpu[] = {
+ {
+ /* Nominal */
+ .rate = 650 * FWK_MHZ,
+ .pll_rate = 650 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+};
+
+static const fwk_id_t member_table_cpu_big_cfg_a[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 6),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 7),
+};
+
+static const fwk_id_t member_table_cpu_little_cfg_a[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 0),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 1),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 2),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 3),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 4),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 5),
+};
+
+static const fwk_id_t member_table_cpu_big_cfg_b[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 4),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 5),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 6),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 7),
+};
+
+static const fwk_id_t member_table_cpu_little_cfg_b[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 0),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 1),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 2),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 3),
+};
+
+static const fwk_id_t member_table_gpu[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 8),
+};
+
+static const fwk_id_t member_table_vpu[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 9),
+};
+
+static const fwk_id_t member_table_dpu[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 10),
+};
+
+static const struct fwk_element css_clock_element_table[] = {
+ {
+ .name = "CPU_GROUP_BIG",
+ .data = &((struct mod_css_clock_dev_config) {
+ .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
+ .rate_table = rate_table_cpu_group_big,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_big),
+ .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 1),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 2700 * FWK_MHZ,
+ .modulation_supported = true,
+ }),
+ },
+ {
+ .name = "CPU_GROUP_LITTLE",
+ .data = &((struct mod_css_clock_dev_config) {
+ .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
+ .rate_table = rate_table_cpu_group_little,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_little),
+ .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 0),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 2200 * FWK_MHZ,
+ .modulation_supported = true,
+ }),
+ },
+ {
+ .name = "GPU",
+ .data = &((struct mod_css_clock_dev_config) {
+ .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
+ .rate_table = rate_table_gpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_gpu),
+ .clock_switching_source = MOD_PIK_CLOCK_GPUCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 2),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_table = member_table_gpu,
+ .member_count = FWK_ARRAY_SIZE(member_table_gpu),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 800 * FWK_MHZ,
+ .modulation_supported = false,
+ }),
+ },
+ {
+ .name = "VPU",
+ .data = &((struct mod_css_clock_dev_config) {
+ .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
+ .rate_table = rate_table_vpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_vpu),
+ .clock_switching_source = MOD_PIK_CLOCK_VPUCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 4),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_table = member_table_vpu,
+ .member_count = FWK_ARRAY_SIZE(member_table_vpu),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 650 * FWK_MHZ,
+ .modulation_supported = false,
+ }),
+ },
+ {
+ .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, 3),
+ .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,
+ }),
+ },
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *css_clock_get_element_table
+ (fwk_id_t module_id)
+{
+ int status;
+ struct mod_css_clock_dev_config *config_big;
+ struct mod_css_clock_dev_config *config_little;
+ const struct mod_sid_info *system_info;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ config_big =
+ (struct mod_css_clock_dev_config *) css_clock_element_table[0].data;
+ config_little =
+ (struct mod_css_clock_dev_config *) css_clock_element_table[1].data;
+
+ switch (system_info->config_number) {
+ case 1:
+ case 5:
+ case 7:
+ case 8:
+ config_big->member_table = member_table_cpu_big_cfg_a;
+ config_big->member_count = FWK_ARRAY_SIZE(member_table_cpu_big_cfg_a);
+
+ config_little->member_table = member_table_cpu_little_cfg_a;
+ config_little->member_count =
+ FWK_ARRAY_SIZE(member_table_cpu_little_cfg_a);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ config_big->member_table = member_table_cpu_big_cfg_b;
+ config_big->member_count =
+ FWK_ARRAY_SIZE(member_table_cpu_big_cfg_b);
+
+ config_little->member_table = member_table_cpu_little_cfg_b;
+ config_little->member_count =
+ FWK_ARRAY_SIZE(member_table_cpu_little_cfg_b);
+ break;
+ default:
+ return NULL;
+ }
+
+ 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/sgm776/scp_ramfw/config_ddr_phy500.c b/product/sgm776/scp_ramfw/config_ddr_phy500.c
new file mode 100644
index 00000000..61ddcebb
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_ddr_phy500.c
@@ -0,0 +1,63 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <mod_ddr_phy500.h>
+#include <system_mmap.h>
+
+/* Default configuration values for DDR PHY500 devices. */
+static const struct mod_ddr_phy500_reg ddr_reg_val = {
+ .T_CTRL_DELAY = 0x00000000,
+ .READ_DELAY = 0x00000003,
+ .T_CTRL_UPD_MIN = 0x00000000,
+ .DELAY_SEL = 0x0000000A,
+ .CAPTURE_MASK = 0x0000001f,
+ .T_RDDATA_EN = 0x00001C00,
+ .T_RDLAT = 0x00000016,
+ .T_WRLAT = 0x01000000,
+ .DFI_WR_PREMBL = 0x00000002,
+ .DFI_LP_ACK = 0x00641300,
+};
+
+/* Table of DDR PHY500 element descriptions. */
+static struct fwk_element ddr_phy500_element_table[] = {
+ [0] = { .name = "DDR_PHY500-0",
+ .data = &((struct mod_ddr_phy500_element_config) {
+ .ddr = DDR_PHY0,
+ }),
+ },
+ [1] = { .name = "DDR_PHY500-1",
+ .data = &((struct mod_ddr_phy500_element_config) {
+ .ddr = DDR_PHY1,
+ }),
+ },
+ [2] = { .name = "DDR_PHY500-2",
+ .data = &((struct mod_ddr_phy500_element_config) {
+ .ddr = DDR_PHY2,
+ }),
+ },
+ [3] = { .name = "DDR_PHY500-3",
+ .data = &((struct mod_ddr_phy500_element_config) {
+ .ddr = DDR_PHY3,
+ }),
+ },
+ [4] = { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *ddr_phy500_get_element_table(
+ fwk_id_t module_id)
+{
+ return ddr_phy500_element_table;
+}
+
+/* Configuration of the DDR PHY500 module. */
+const struct fwk_module_config config_ddr_phy500 = {
+ .get_element_table = ddr_phy500_get_element_table,
+ .data = &((struct mod_ddr_phy500_module_config) {
+ .ddr_reg_val = &ddr_reg_val,
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_dmc500.c b/product/sgm776/scp_ramfw/config_dmc500.c
new file mode 100644
index 00000000..97380a8f
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_dmc500.c
@@ -0,0 +1,221 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_dmc500.h>
+#include <system_mmap.h>
+
+#define COL_BITS 1
+#define BANK_BITS 0
+#define RANK_BITS 1
+#define BANK_GROUP 0
+#define ROW_BITS 5
+#define MEM_TYPE 3
+#define MEM_BURST 2
+#define DEVICE_WIDTH 2
+#define ADDR_SHUTTER 2
+
+static const struct mod_dmc500_reg reg_val = {
+ .ADDRESS_CONTROL = ADDRESS_CONTROL_VAL(RANK_BITS,
+ BANK_BITS,
+ ROW_BITS,
+ COL_BITS),
+ .RANK_REMAP_CONTROL = 0x00000000,
+ .MEMORY_TYPE = MEMORY_TYPE_VAL(BANK_GROUP,
+ DEVICE_WIDTH,
+ MEM_TYPE),
+ .FORMAT_CONTROL = FORMAT_CONTROL_VAL(MEM_BURST),
+ .DECODE_CONTROL = 0x00000011,
+ .FEATURE_CONTROL = 0x00000000,
+ .ODT_WR_CONTROL_31_00 = 0x00000000,
+ .ODT_RD_CONTROL_31_00 = 0x00000000,
+ .ODT_TIMING = 0x10001000,
+ .T_REFI = 0x0000030b,
+ .T_RFC = 0x000340d0,
+ .T_RDPDEN = 0x0000002e,
+ .T_RCD = 0x0000001d,
+ .T_RAS = 0x80000044,
+ .T_RP = 0x0000221d,
+ .T_RRD = 0x00001010,
+ .T_ACT_WINDOW = 0x00000040,
+ .T_RTR = 0x000c0808,
+ .T_RTW = 0x001f1f1f,
+ .T_RTP = 0x0000000C,
+ .T_WR = 0x00000035,
+ .T_WTR = 0x00082929,
+ .T_WTW = 0x000b0808,
+ .T_XTMW = 0x00000020,
+ .T_CLOCK_CONTROL = 0x1119030d,
+ .T_EP = 0x0000000C,
+ .T_XP = 0x000c000c,
+ .T_ESR = 0x00000019,
+ .T_XSR = 0x00e100e1,
+ .ADDRESS_MAP = ADDRESS_MAP_VAL(ADDR_SHUTTER),
+ .SI0_SI_INTERRUPT_CONTROL = 0x00000000,
+ .SI0_PMU_REQ_CONTROL = 0x00000B1A,
+ .SI0_PMU_REQ_ATTRIBUTE_MASK_0 = 0xB0562AA1,
+ .SI0_PMU_REQ_ATTRIBUTE_MATCH_0 = 0xD0FB6716,
+ .SI0_PMU_REQ_ATTRIBUTE_MASK_1 = 0x7FC24C15,
+ .SI0_PMU_REQ_ATTRIBUTE_MATCH_1 = 0xF7A9B2AC,
+ .SI0_PMU_REQ_ATTRIBUTE_MASK_2 = 0xDD35FA69,
+ .SI0_PMU_REQ_ATTRIBUTE_MATCH_2 = 0x3555A8F5,
+ .SI0_PMU_REQ_ATTRIBUTE_MASK_3 = 0xDE382B10,
+ .SI0_PMU_REQ_ATTRIBUTE_MATCH_3 = 0x3484B32C,
+ .SI0_THRESHOLD_CONTROL = 0x00000000,
+ .SI1_SI_INTERRUPT_CONTROL = 0x00000000,
+ .SI1_PMU_REQ_CONTROL = 0x00000B1A,
+ .SI1_PMU_REQ_ATTRIBUTE_MASK_0 = 0xB0562AA1,
+ .SI1_PMU_REQ_ATTRIBUTE_MATCH_0 = 0xD0FB6716,
+ .SI1_PMU_REQ_ATTRIBUTE_MASK_1 = 0x7FC24C15,
+ .SI1_PMU_REQ_ATTRIBUTE_MATCH_1 = 0xF7A9B2AC,
+ .SI1_PMU_REQ_ATTRIBUTE_MASK_2 = 0xDD35FA69,
+ .SI1_PMU_REQ_ATTRIBUTE_MATCH_2 = 0x3555A8F5,
+ .SI1_PMU_REQ_ATTRIBUTE_MASK_3 = 0xDE382B10,
+ .SI1_PMU_REQ_ATTRIBUTE_MATCH_3 = 0x3484B32C,
+ .SI1_THRESHOLD_CONTROL = 0x00000000,
+ .QUEUE_THRESHOLD_CONTROL_31_00 = 0x00000000,
+ .QUEUE_THRESHOLD_CONTROL_63_32 = 0x99887700,
+ .DCB_INTERRUPT_CONTROL = 0x00000000,
+ .PMU_DCB_CONTROL = 0x00000800,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_0 = 0xFD98CF7D,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_0 = 0x9F276EB5,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_1 = 0x40B1FC24,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_1 = 0x04BBF4FA,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_2 = 0x8089B0AF,
+ .PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_2 = 0x7D26E0BE,
+ .PMU_TAG_ENTRIES_ATTRIBUTE_MASK = 0x000000CE,
+ .PMU_TAG_ENTRIES_ATTRIBUTE_MATCH = 0x00000056,
+ .QE_INTERRUPT_CONTROL = 0x00000000,
+ .RANK_TURNAROUND_CONTROL = 0x0F0F0F0F,
+ .HIT_TURNAROUND_CONTROL = 0x8290BF8F,
+ .QOS_CLASS_CONTROL = 0x00000D50,
+ .ESCALATION_CONTROL = 0x00000F03,
+ .QV_CONTROL_31_00 = 0xE6543210,
+ .QV_CONTROL_63_32 = 0xFEDCBA98,
+ .RT_CONTROL_31_00 = 0x00000000,
+ .RT_CONTROL_63_32 = 0x00008800,
+ .TIMEOUT_CONTROL = 0x00000001,
+ .WRITE_PRIORITY_CONTROL_31_00 = 0x00000000,
+ .WRITE_PRIORITY_CONTROL_63_32 = 0xEC840000,
+ .DIR_TURNAROUND_CONTROL = 0x05050F00,
+ .HIT_PREDICTION_CONTROL = 0x00020705,
+ .REFRESH_PRIORITY = 0x00000204,
+ .MC_UPDATE_CONTROL = 0x0000ff00,
+ .PHY_UPDATE_CONTROL = 0x15A3925F,
+ .PHY_MASTER_CONTROL = 0x6875AF9A,
+ .LOW_POWER_CONTROL = 0x000E0801,
+ .PMU_QE_CONTROL = 0x00000C0D,
+ .PMU_QE_MUX = 0x05670023,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MASK_0 = 0x000000F1,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MATCH_0 = 0x00000662,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MASK_1 = 0x000000DD,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MATCH_1 = 0x00000097,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MASK_2 = 0x0000001A,
+ .PMU_QOS_ENGINE_ATTRIBUTE_MATCH_2 = 0x00000755,
+ .PMU_QUEUED_ENTRIES_ATTRIBUTE_MASK = 0xAD625ED5,
+ .PMU_QUEUED_ENTRIES_ATTRIBUTE_MATCH = 0x853C65BB,
+ .MI_INTERRUPT_CONTROL = 0x00000000,
+ .POWER_DOWN_CONTROL = 0x00000005,
+ .REFRESH_CONTROL = 0x00000000,
+ .PMU_MI_CONTROL = 0x00000100,
+ .PMU_MEMORY_IF_ATTRIBUTE_MASK_0 = 0x0032BB0E,
+ .PMU_MEMORY_IF_ATTRIBUTE_MATCH_0 = 0x0033F5AB,
+ .PMU_MEMORY_IF_ATTRIBUTE_MASK_1 = 0x00296B28,
+ .PMU_MEMORY_IF_ATTRIBUTE_MATCH_1 = 0x002C67BF,
+ .PMU_BANK_STATES_ATTRIBUTE_MASK = 0x00000005,
+ .PMU_BANK_STATES_ATTRIBUTE_MATCH = 0x00000019,
+ .PMU_RANK_STATES_ATTRIBUTE_MASK = 0x0000001B,
+ .PMU_RANK_STATES_ATTRIBUTE_MATCH = 0x00000020,
+ .CFG_INTERRUPT_CONTROL = 0x00000000,
+ .T_RDDATA_EN = 0x00000001,
+ .T_PHYRDLAT = 0x0000003f,
+ .T_PHYWRLAT = 0x010f170e,
+ .ERR_RAMECC_CTLR = 0x00000000,
+ .PHY_POWER_CONTROL = 0x0000012a,
+ .T_PHY_TRAIN = 0x00f8000a,
+ .PHYUPD_INIT = 0x00000000,
+ .REFRESH_ENABLE = 0x00000001,
+ .MI_STATE_CONTROL = 0,
+ .QUEUE_STATE_CONTROL = 0,
+ .SI0_SI_STATE_CONTROL = 0,
+ .SI1_SI_STATE_CONTROL = 0,
+};
+
+/* Table of DMC500 elements descriptions. */
+static const struct fwk_element dmc500_element_table[] = {
+ [0] = { .name = "DMC500-0",
+ .data = &((struct mod_dmc500_element_config) {
+ .dmc = DMC_INTERNAL0,
+ .ddr_phy_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_DDR_PHY500, 0),
+ }),
+ },
+ [1] = { .name = "DMC500-1",
+ .data = &((struct mod_dmc500_element_config) {
+ .dmc = DMC_INTERNAL1,
+ .ddr_phy_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_DDR_PHY500, 1),
+ }),
+ },
+ [2] = { .name = "DMC500-2",
+ .data = &((struct mod_dmc500_element_config) {
+ .dmc = DMC_INTERNAL2,
+ .ddr_phy_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_DDR_PHY500, 2),
+ }),
+ },
+ [3] = { .name = "DMC500-3",
+ .data = &((struct mod_dmc500_element_config) {
+ .dmc = DMC_INTERNAL3,
+ .ddr_phy_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_DDR_PHY500, 3),
+ }),
+ },
+ [4] = { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *dmc500_get_element_table(fwk_id_t module_id)
+{
+ return dmc500_element_table;
+}
+
+static void direct_ddr_cmd(struct mod_dmc500_reg *dmc)
+{
+ dmc->DIRECT_CMD_SETTINGS = 0x00C80000;
+ dmc->DIRECT_CMD = 0x00000000;
+ dmc->DIRECT_CLK_DISABLE = 0x00280003;
+ dmc->CLK_STATUS_OVERRIDE = 0x00000003;
+ dmc->DIRECT_CMD_SETTINGS = 0x01F40003;
+ dmc->DIRECT_CMD = 0x00800080;
+ dmc->RANK_STATUS_OVERRIDE = 0x30000003;
+ dmc->DIRECT_CMD_SETTINGS = 0x04b00003;
+ dmc->DIRECT_CMD = 0x00800FE0;
+ dmc->DIRECT_CMD_SETTINGS = 0x00500003;
+ dmc->DIRECT_CMD = 0x008011E0;
+ dmc->DIRECT_CMD_SETTINGS = 0x00140003;
+ dmc->DIRECT_CMD = 0x06d601c6;
+ dmc->DIRECT_CMD_SETTINGS = 0x01000003;
+ dmc->DIRECT_CMD = 0x00f60dc6;
+ dmc->DIRECT_CMD_SETTINGS = 0x00140003;
+ dmc->DIRECT_CMD = 0x31d603c6;
+ dmc->DIRECT_CMD_SETTINGS = 0x00140003;
+ dmc->DIRECT_CMD = 0x16f601c6;
+ dmc->DIRECT_CMD_SETTINGS = 0x00140003;
+ dmc->DIRECT_CMD = 0x2dd602c6;
+ dmc->DIRECT_CMD_SETTINGS = 0x02000003;
+ dmc->DIRECT_CMD = 0x00d60de6;
+}
+
+/* Configuration of the DMC500 module. */
+const struct fwk_module_config config_dmc500 = {
+ .get_element_table = dmc500_get_element_table,
+ .data = &((struct mod_dmc500_module_config) {
+ .timer_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0),
+ .ddr_phy_module_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_DDR_PHY500),
+ .ddr_phy_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_DDR_PHY500, 0),
+ .reg_val = &reg_val,
+ .direct_ddr_cmd = direct_ddr_cmd,
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_dvfs.c b/product/sgm776/scp_ramfw/config_dvfs.c
new file mode 100644
index 00000000..e48d5aea
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_dvfs.c
@@ -0,0 +1,128 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <config_dvfs.h>
+#include <mod_dvfs.h>
+
+static const struct mod_dvfs_domain_config cpu_group_little = {
+ .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0),
+ .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 1),
+ .latency = 1200,
+ .sustained_idx = 2,
+ .opps = (struct mod_dvfs_opp[]) {
+ {
+ .frequency = 665 * FWK_MHZ,
+ .voltage = 100,
+ },
+ {
+ .frequency = 998 * FWK_MHZ,
+ .voltage = 200,
+ },
+ {
+ .frequency = 1330 * FWK_MHZ,
+ .voltage = 300,
+ },
+ {
+ .frequency = 1463 * FWK_MHZ,
+ .voltage = 400,
+ },
+ {
+ .frequency = 2200 * FWK_MHZ,
+ .voltage = 500,
+ },
+ { 0 }
+ }
+};
+
+static const struct mod_dvfs_domain_config cpu_group_big = {
+ .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 1),
+ .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 0),
+ .latency = 1200,
+ .sustained_idx = 2,
+ .opps = (struct mod_dvfs_opp[]) {
+ {
+ .frequency = 1313 * FWK_MHZ,
+ .voltage = 100,
+ },
+ {
+ .frequency = 1531 * FWK_MHZ,
+ .voltage = 200,
+ },
+ {
+ .frequency = 1750 * FWK_MHZ,
+ .voltage = 300,
+ },
+ {
+ .frequency = 2100 * FWK_MHZ,
+ .voltage = 400,
+ },
+ {
+ .frequency = 2700 * FWK_MHZ,
+ .voltage = 500,
+ },
+ { 0 }
+ }
+};
+
+static const struct mod_dvfs_domain_config gpu = {
+ .psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 2),
+ .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, 2),
+ .latency = 1200,
+ .sustained_idx = 4,
+ .opps = (struct mod_dvfs_opp[]) {
+ {
+ .frequency = 450 * FWK_MHZ,
+ .voltage = 100,
+ },
+ {
+ .frequency = 487500 * FWK_KHZ,
+ .voltage = 200,
+ },
+ {
+ .frequency = 525 * FWK_MHZ,
+ .voltage = 300,
+ },
+ {
+ .frequency = 562500 * FWK_KHZ,
+ .voltage = 400,
+ },
+ {
+ .frequency = 800 * FWK_MHZ,
+ .voltage = 500,
+ },
+ { 0 }
+ }
+};
+
+static const struct fwk_element element_table[] = {
+ [DVFS_ELEMENT_IDX_LITTLE] = {
+ .name = "CPU_GROUP_LITTLE",
+ .data = &cpu_group_little,
+ },
+ [DVFS_ELEMENT_IDX_BIG] = {
+ .name = "CPU_GROUP_BIG",
+ .data = &cpu_group_big,
+ },
+ [DVFS_ELEMENT_IDX_GPU] = {
+ .name = "GPU",
+ .data = &gpu,
+ },
+ { 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/sgm776/scp_ramfw/config_dvfs.h b/product/sgm776/scp_ramfw/config_dvfs.h
new file mode 100644
index 00000000..f5ec5ee3
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_dvfs.h
@@ -0,0 +1,18 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONFIG_DVFS_H
+#define CONFIG_DVFS_H
+
+enum dvfs_element_idx {
+ DVFS_ELEMENT_IDX_LITTLE,
+ DVFS_ELEMENT_IDX_BIG,
+ DVFS_ELEMENT_IDX_GPU,
+ DVFS_ELEMENT_IDX_COUNT
+};
+
+#endif /* CONFIG_DVFS_H */
diff --git a/product/sgm776/scp_ramfw/config_log.c b/product/sgm776/scp_ramfw/config_log.c
new file mode 100644
index 00000000..c418ef46
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_log.c
@@ -0,0 +1,63 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_banner.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_log.h>
+#include <mod_pl011.h>
+#include <system_mmap.h>
+#include <clock_devices.h>
+
+/*
+ * PL011 module
+ */
+static const struct fwk_element pl011_element_table[] = {
+ [0] = {
+ .name = "board-uart1",
+ .data = &((struct mod_pl011_device_config) {
+ .reg_base = BOARD_UART1_BASE,
+ .baud_rate_bps = 115200,
+ .clock_rate_hz = 24 * FWK_MHZ,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_INTERCONNECT),
+ }),
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *get_pl011_table(fwk_id_t module_id)
+{
+ return pl011_element_table;
+}
+
+const struct fwk_module_config config_pl011 = {
+ .get_element_table = get_pl011_table,
+};
+
+/*
+ * Log module
+ */
+static const struct mod_log_config log_data = {
+ .device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PL011, 0),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PL011, 0),
+ .log_groups = MOD_LOG_GROUP_ERROR |
+ MOD_LOG_GROUP_INFO |
+ MOD_LOG_GROUP_WARNING |
+ MOD_LOG_GROUP_DEBUG,
+ .banner = FWK_BANNER_SCP
+ FWK_BANNER_RAM_FIRMWARE
+ BUILD_VERSION_DESCRIBE_STRING "\n",
+};
+
+const struct fwk_module_config config_log = {
+ .get_element_table = NULL,
+ .data = &log_data,
+};
diff --git a/product/sgm776/scp_ramfw/config_mhu.c b/product/sgm776/scp_ramfw/config_mhu.c
new file mode 100644
index 00000000..9ba401fe
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_mhu.c
@@ -0,0 +1,57 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <mod_mhu2.h>
+#include <sgm776_irq.h>
+#include <sgm776_mhu.h>
+#include <sgm776_mmap.h>
+
+static const struct fwk_element mhu_element_table[] = {
+ [SGM776_MHU_DEVICE_IDX_S] = {
+ .name = "MHU_S",
+ .sub_element_count = 1,
+ .data = &((struct mod_mhu2_channel_config) {
+ .irq = MHU_SECURE_IRQ,
+ .recv = MHU_RECV_S_BASE,
+ .send = MHU_SEND_S_BASE,
+ .channel = 0,
+ })
+ },
+ [SGM776_MHU_DEVICE_IDX_NS_H] = {
+ .name = "MHU_NS_HIGH",
+ .sub_element_count = 1,
+ .data = &((struct mod_mhu2_channel_config) {
+ .irq = MHU_HIGH_PRIO_IRQ,
+ .recv = MHU_RECV_NS_BASE,
+ .send = MHU_SEND_NS_BASE,
+ .channel = 0,
+ })
+ },
+ [SGM776_MHU_DEVICE_IDX_NS_L] = {
+ .name = "MHU_NS_LOW",
+ .sub_element_count = 1,
+ .data = &((struct mod_mhu2_channel_config) {
+ .irq = MHU_LOW_PRIO_IRQ,
+ .recv = MHU_RECV_NS_BASE,
+ .send = MHU_SEND_NS_BASE,
+ .channel = 1,
+ })
+ },
+ [SGM776_MHU_DEVICE_IDX_COUNT] = { 0 },
+};
+
+static const struct fwk_element *mhu_get_element_table(fwk_id_t module_id)
+{
+ return mhu_element_table;
+}
+
+struct fwk_module_config config_mhu2 = {
+ .get_element_table = mhu_get_element_table,
+};
diff --git a/product/sgm776/scp_ramfw/config_mock_psu.c b/product/sgm776/scp_ramfw/config_mock_psu.c
new file mode 100644
index 00000000..0bfc203e
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_mock_psu.c
@@ -0,0 +1,75 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <mod_mock_psu.h>
+
+static const struct fwk_element element_table[] = {
+ {
+ .name = "CPU_GROUP_LITTLE",
+ .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 = 100,
+ },
+ },
+ {
+ .name = "CPU_GROUP_BIG",
+ .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 = 100,
+ },
+ },
+ {
+ .name = "GPU",
+ .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 = 100,
+ },
+ },
+ {
+ .name = "VPU",
+ .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 = 100,
+ },
+ },
+ { 0 }
+};
+
+static const struct fwk_element *get_element_table(fwk_id_t module_id)
+{
+ return element_table;
+}
+
+const struct fwk_module_config config_mock_psu = {
+ .get_element_table = get_element_table,
+};
diff --git a/product/sgm776/scp_ramfw/config_pik_clock.c b/product/sgm776/scp_ramfw/config_pik_clock.c
new file mode 100644
index 00000000..d09b5f2c
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_pik_clock.c
@@ -0,0 +1,305 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_assert.h>
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_pik_clock.h>
+#include <mod_sid.h>
+#include <sgm776_pik.h>
+#include <system_clock.h>
+
+/*
+ * Rate lookup tables
+ */
+
+static struct mod_pik_clock_rate rate_table_cpu_a55[] = {
+ {
+ .rate = 2200 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via CPU PLL */
+ },
+};
+
+static struct mod_pik_clock_rate rate_table_cpu_a75[] = {
+ {
+ .rate = 2700 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via CPU PLL */
+ },
+};
+
+static struct mod_pik_clock_rate rate_table_gpu[] = {
+ {
+ .rate = 800 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via GPU PLL */
+ },
+};
+
+static struct mod_pik_clock_rate rate_table_vpu[] = {
+ {
+ .rate = 650 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_VPUCLK_SOURCE_VIDEOPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via VPU PLL */
+ },
+};
+
+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 mod_pik_clock_rate rate_table_sys_nocmemclk[] = {
+ {
+ .rate = 720 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (720 * FWK_MHZ),
+ },
+};
+
+static const struct fwk_element pik_clock_element_table[] = {
+ /*
+ * Cluster 0 CPUS
+ */
+ {
+ .name = "CLUS0_CPU0",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[0].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[0].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[0].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU1",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[1].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[1].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[1].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU2",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[2].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[2].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[2].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU3",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[3].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[3].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[3].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU4",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[4].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[4].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[4].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU5",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[5].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[5].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[5].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU6",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[6].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[6].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[6].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU7",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[7].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[7].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[7].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * GPU
+ */
+ {
+ .name = "GPU",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = true,
+ .control_reg = &PIK_GPU->GPUCLK_CTRL,
+ .divsys_reg = &PIK_GPU->GPUCLK_DIV1,
+ .divext_reg = &PIK_GPU->GPUCLK_DIV2,
+ .rate_table = rate_table_gpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_gpu),
+ .initial_rate = 800 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * VPU
+ */
+ {
+ .name = "VPU",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = true,
+ .control_reg = &PIK_VPU->VIDEOCLK_CTRL,
+ .divsys_reg = &PIK_VPU->VIDEOCLK_DIV1,
+ .divext_reg = &PIK_VPU->VIDEOCLK_DIV2,
+ .rate_table = rate_table_vpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_vpu),
+ .initial_rate = 650 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * DPU
+ */
+ {
+ .name = "DPU",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = true,
+ .control_reg = &PIK_DPU->ACLKDP_CTRL,
+ .divsys_reg = &PIK_DPU->ACLKDP_DIV1,
+ .divext_reg = &PIK_DPU->ACLKDP_DIV2,
+ .rate_table = rate_table_dpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_dpu),
+ .initial_rate = 600 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * Arachne NOC
+ */
+ {
+ .name = "INTERCONNECT",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->NOCMEMCLK_CTRL,
+ .divsys_reg = &PIK_SYSTEM->NOCMEMCLK_DIV1,
+ .rate_table = rate_table_sys_nocmemclk,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_nocmemclk),
+ .initial_rate = 720 * FWK_MHZ,
+ .defer_initialization = false,
+ }),
+ },
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *pik_clock_get_element_table
+ (fwk_id_t module_id)
+{
+ int status;
+ int element_idx;
+ struct mod_pik_clock_dev_config *config;
+ const struct mod_sid_info *system_info;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ switch (system_info->config_number) {
+ case 1:
+ case 5:
+ case 7:
+ case 8:
+ /* CPUs 0-5: Little */
+ for (element_idx = 0; element_idx < 6; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a55;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a55);
+ }
+ /* CPUs 6-7: Big */
+ for (element_idx = 6; element_idx < 8; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a75;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a75);
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ /* CPUs 0-3: Little */
+ for (element_idx = 0; element_idx < 4; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a55;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a55);
+ }
+ /* CPUs 4-7: Big */
+ for (element_idx = 4; element_idx < 8; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a75;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a75);
+ }
+ break;
+ default:
+ return NULL;
+ }
+
+ 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/sgm776/scp_ramfw/config_power_domain.c b/product/sgm776/scp_ramfw/config_power_domain.c
new file mode 100644
index 00000000..79c73d30
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_power_domain.c
@@ -0,0 +1,250 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <config_power_domain.h>
+#include <config_ppu_v1.h>
+#include <mod_system_power.h>
+#include <mod_ppu_v1.h>
+#include <mod_power_domain.h>
+#include <sgm776_core.h>
+
+static const char *core_pd_name_table[SGM776_CORE_PER_CLUSTER_MAX] = {
+ "CLUS0CORE0", "CLUS0CORE1", "CLUS0CORE2", "CLUS0CORE3",
+ "CLUS0CORE4", "CLUS0CORE5", "CLUS0CORE6", "CLUS0CORE7",
+};
+
+/* Mask of the allowed states for the systop power domain */
+static const uint32_t systop_allowed_state_mask_table[] = {
+ [0] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK |
+ (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP0) |
+ (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP1)
+};
+
+/*
+ * Mask of the allowed states for the top level power domains
+ * (but the cluster power domains) depending on the system states.
+ */
+static const uint32_t toplevel_allowed_state_mask_table[] = {
+ [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
+ [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK,
+ [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK,
+ [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK
+};
+
+/*
+ * Mask of the allowed states for the cluster power domain depending on the
+ * system states.
+ */
+static const uint32_t cluster_pd_allowed_state_mask_table[] = {
+ [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
+ [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK |
+ MOD_PD_STATE_SLEEP_MASK,
+ [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK,
+ [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK
+};
+
+/* Mask of the allowed states for a core depending on the cluster states. */
+static const uint32_t core_pd_allowed_state_mask_table[] = {
+ [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
+ [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK |
+ MOD_PD_STATE_SLEEP_MASK,
+ [MOD_PD_STATE_SLEEP] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK,
+};
+
+/* Power module specific configuration data (none) */
+static const struct mod_power_domain_config sgm776_power_domain_config = { 0 };
+
+static struct fwk_element sgm776_power_domain_static_element_table[] = {
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_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,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_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)
+ }),
+ },
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DBGTOP] = {
+ .name = "DBGTOP",
+ .data = &((struct mod_power_domain_element_config) {
+ .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
+ .tree_pos = MOD_PD_TREE_POS(
+ MOD_PD_LEVEL_1,
+ 0,
+ 0,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DBGTOP,
+ 0),
+ .driver_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_DBGTOP),
+ .api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ .allowed_state_mask_table = toplevel_allowed_state_mask_table,
+ .allowed_state_mask_table_size =
+ FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
+ }),
+ },
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DPUTOP] = {
+ .name = "DPUTOP",
+ .data = &((struct mod_power_domain_element_config) {
+ .attributes.pd_type = MOD_PD_TYPE_DEVICE,
+ .tree_pos = MOD_PD_TREE_POS(
+ MOD_PD_LEVEL_1,
+ 0,
+ 0,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DPUTOP,
+ 0),
+ .driver_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_DPUTOP),
+ .api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ .allowed_state_mask_table = toplevel_allowed_state_mask_table,
+ .allowed_state_mask_table_size =
+ FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
+ }),
+ },
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_GPUTOP] = {
+ .name = "GPUTOP",
+ .data = &((struct mod_power_domain_element_config) {
+ .attributes.pd_type = MOD_PD_TYPE_DEVICE,
+ .tree_pos = MOD_PD_TREE_POS(
+ MOD_PD_LEVEL_1,
+ 0,
+ 0,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_GPUTOP,
+ 0),
+ .driver_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_GPUTOP),
+ .api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ .allowed_state_mask_table = toplevel_allowed_state_mask_table,
+ .allowed_state_mask_table_size =
+ FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
+ }),
+ },
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_VPUTOP] = {
+ .name = "VPUTOP",
+ .data = &((struct mod_power_domain_element_config) {
+ .attributes.pd_type = MOD_PD_TYPE_DEVICE,
+ .tree_pos = MOD_PD_TREE_POS(
+ MOD_PD_LEVEL_1,
+ 0,
+ 0,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_VPUTOP,
+ 0),
+ .driver_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_VPUTOP),
+ .api_id = FWK_ID_API_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ .allowed_state_mask_table = toplevel_allowed_state_mask_table,
+ .allowed_state_mask_table_size =
+ FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
+ }),
+ },
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_COUNT] = {
+ .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 *sgm776_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;
+
+ element_table = fwk_mm_calloc(
+ sgm776_core_get_count()
+ + FWK_ARRAY_SIZE(sgm776_power_domain_static_element_table)
+ + 1, /* Terminator */
+ sizeof(struct fwk_element));
+ if (element_table == NULL)
+ return NULL;
+
+ pd_config_table = fwk_mm_calloc(sgm776_core_get_count(),
+ sizeof(struct mod_power_domain_element_config));
+ if (pd_config_table == NULL)
+ return NULL;
+
+ for (core_idx = 0; core_idx < sgm776_core_get_count(); core_idx++) {
+ element = &element_table[core_idx];
+ pd_config = &pd_config_table[core_idx];
+
+ element->name = core_pd_name_table[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,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_CLUSTER0,
+ core_idx),
+ pd_config->driver_id = FWK_ID_ELEMENT(
+ FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_COUNT + core_idx),
+ 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);
+ }
+
+ pd_config = (struct mod_power_domain_element_config *)
+ sgm776_power_domain_static_element_table
+ [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_CLUSTER0]
+ .data;
+ pd_config->driver_id =
+ FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_COUNT + sgm776_core_get_count());
+
+ memcpy(element_table + sgm776_core_get_count(),
+ sgm776_power_domain_static_element_table,
+ sizeof(sgm776_power_domain_static_element_table));
+
+ return element_table;
+}
+
+/*
+ * Power module configuration data
+ */
+struct fwk_module_config config_power_domain = {
+ .get_element_table = sgm776_power_domain_get_element_table,
+ .data = &sgm776_power_domain_config,
+};
diff --git a/product/sgm776/scp_ramfw/config_power_domain.h b/product/sgm776/scp_ramfw/config_power_domain.h
new file mode 100644
index 00000000..a510220b
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_power_domain.h
@@ -0,0 +1,20 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONFIG_POWER_DOMAIN_H
+#define CONFIG_POWER_DOMAIN_H
+
+enum systop_child_index {
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_CLUSTER0,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DBGTOP,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DPUTOP,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_GPUTOP,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_VPUTOP,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_COUNT
+};
+
+#endif /* CONFIG_POWER_DOMAIN_H */
diff --git a/product/sgm776/scp_ramfw/config_ppu_v1.c b/product/sgm776/scp_ramfw/config_ppu_v1.c
new file mode 100644
index 00000000..57f3fe31
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_ppu_v1.c
@@ -0,0 +1,174 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_power_domain.h>
+#include <mod_ppu_v1.h>
+#include <sgm776_core.h>
+#include <sgm776_irq.h>
+#include <sgm776_mmap.h>
+#include <config_power_domain.h>
+#include <config_ppu_v1.h>
+
+static const char *core_pd_name_table[SGM776_CORE_PER_CLUSTER_MAX] = {
+ "CLUS0CORE0", "CLUS0CORE1", "CLUS0CORE2", "CLUS0CORE3",
+ "CLUS0CORE4", "CLUS0CORE5", "CLUS0CORE6", "CLUS0CORE7",
+};
+
+static uintptr_t core_pd_ppu_base_table[] = {
+ PPU_CLUS0CORE0_BASE, PPU_CLUS0CORE1_BASE, PPU_CLUS0CORE2_BASE,
+ PPU_CLUS0CORE3_BASE, PPU_CLUS0CORE4_BASE, PPU_CLUS0CORE5_BASE,
+ PPU_CLUS0CORE6_BASE, PPU_CLUS0CORE7_BASE
+};
+
+static unsigned int core_pd_ppu_irq_table[] = {
+ PPU_CLUS0CORE0_IRQ, PPU_CLUS0CORE1_IRQ, PPU_CLUS0CORE2_IRQ,
+ PPU_CLUS0CORE3_IRQ, PPU_CLUS0CORE4_IRQ, PPU_CLUS0CORE5_IRQ,
+ PPU_CLUS0CORE6_IRQ, PPU_CLUS0CORE7_IRQ
+};
+
+struct mod_ppu_v1_config sgm776_ppu_v1_notification_config = {
+ .pd_notification_id = FWK_ID_NOTIFICATION_INIT(
+ FWK_MODULE_IDX_POWER_DOMAIN,
+ MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION),
+};
+
+static const struct fwk_element static_ppu_table[] = {
+ [PPU_V1_ELEMENT_IDX_DBGTOP] = {
+ .name = "DBGTOP",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
+ .ppu.reg_base = PPU_DEBUG_BASE,
+ .ppu.irq = PPU_DEBUG_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ [PPU_V1_ELEMENT_IDX_DPUTOP] = {
+ .name = "DPU0TOP",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_DEVICE,
+ .ppu.reg_base = PPU_DPU_BASE,
+ .ppu.irq = PPU_DPU_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ .default_power_on = true,
+ }),
+ },
+ [PPU_V1_ELEMENT_IDX_GPUTOP] = {
+ .name = "GPUTOP",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_DEVICE,
+ .ppu.reg_base = PPU_GPU_BASE,
+ .ppu.irq = PPU_GPU_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ .default_power_on = true,
+ }),
+ },
+ [PPU_V1_ELEMENT_IDX_VPUTOP] = {
+ .name = "VPUTOP",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_DEVICE,
+ .ppu.reg_base = PPU_VPU_BASE,
+ .ppu.irq = PPU_VPU_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ .default_power_on = true,
+ }),
+ },
+ [PPU_V1_ELEMENT_IDX_SYS0] = {
+ .name = "SYS0",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_SYSTEM,
+ .ppu.reg_base = PPU_SYS0_BASE,
+ .ppu.irq = PPU_SYS0_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ [PPU_V1_ELEMENT_IDX_SYS1] = {
+ .name = "SYS1",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_SYSTEM,
+ .ppu.reg_base = PPU_SYS1_BASE,
+ .ppu.irq = PPU_SYS1_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+};
+
+static const struct fwk_element *sgm776_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, table_size;
+
+ /*
+ * Allocate element descriptors based on:
+ * Size of static ppu table
+ * + Number of cores
+ * +1 cluster descriptor
+ * +1 terminator descriptor
+ */
+ table_size = FWK_ARRAY_SIZE(static_ppu_table) + sgm776_core_get_count() + 2;
+ element_table = fwk_mm_calloc(table_size, sizeof(struct fwk_element));
+ if (element_table == NULL)
+ return NULL;
+
+ /* Table to hold configs for all cores and the cluster */
+ pd_config_table = fwk_mm_calloc(sgm776_core_get_count() + 1,
+ sizeof(struct mod_ppu_v1_pd_config));
+ if (pd_config_table == NULL)
+ return NULL;
+
+ /* Cores */
+ for (core_idx = 0; core_idx < sgm776_core_get_count(); core_idx++) {
+ element = &element_table[PPU_V1_ELEMENT_IDX_COUNT + core_idx];
+ pd_config = &pd_config_table[core_idx];
+
+ element->name = core_pd_name_table[core_idx];
+ element->data = pd_config;
+
+ pd_config->pd_type = MOD_PD_TYPE_CORE;
+ pd_config->ppu.reg_base = core_pd_ppu_base_table[core_idx];
+ pd_config->ppu.irq = core_pd_ppu_irq_table[core_idx];
+ pd_config->cluster_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1,
+ table_size - 2);
+ pd_config->observer_id = FWK_ID_NONE;
+ }
+
+ element = &element_table[table_size - 2];
+ pd_config = &pd_config_table[sgm776_core_get_count()];
+
+ element->name = "CLUS0";
+ element->data = pd_config;
+
+ pd_config->pd_type = MOD_PD_TYPE_CLUSTER;
+ pd_config->ppu.reg_base = PPU_CLUS0_BASE;
+ pd_config->ppu.irq = PPU_CLUS0_IRQ;
+ pd_config->observer_id = FWK_ID_NONE;
+
+ /* Copy static table to the beginning of the dynamic table */
+ memcpy(element_table, static_ppu_table, sizeof(static_ppu_table));
+
+ sgm776_ppu_v1_notification_config.pd_source_id = FWK_ID_ELEMENT(
+ FWK_MODULE_IDX_POWER_DOMAIN,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_COUNT + sgm776_core_get_count());
+
+ return element_table;
+}
+
+/*
+ * Power module configuration data
+ */
+struct fwk_module_config config_ppu_v1 = {
+ .get_element_table = sgm776_ppu_v1_get_element_table,
+ .data = &sgm776_ppu_v1_notification_config,
+};
diff --git a/product/sgm776/scp_ramfw/config_ppu_v1.h b/product/sgm776/scp_ramfw/config_ppu_v1.h
new file mode 100644
index 00000000..2cf9c766
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_ppu_v1.h
@@ -0,0 +1,21 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONFIG_PPU_V1_H
+#define CONFIG_PPU_V1_H
+
+enum ppu_v1_static_element_idx {
+ PPU_V1_ELEMENT_IDX_DBGTOP,
+ PPU_V1_ELEMENT_IDX_SYS0,
+ PPU_V1_ELEMENT_IDX_SYS1,
+ PPU_V1_ELEMENT_IDX_DPUTOP,
+ PPU_V1_ELEMENT_IDX_GPUTOP,
+ PPU_V1_ELEMENT_IDX_VPUTOP,
+ PPU_V1_ELEMENT_IDX_COUNT,
+};
+
+#endif /* CONFIG_PPU_V1_H */
diff --git a/product/sgm776/scp_ramfw/config_psu.c b/product/sgm776/scp_ramfw/config_psu.c
new file mode 100644
index 00000000..e9ebbdc0
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_psu.c
@@ -0,0 +1,57 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_mock_psu.h>
+#include <mod_psu.h>
+
+static const struct fwk_element element_table[] = {
+ {
+ .name = "CPU_GROUP_LITTLE",
+ .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)
+ },
+ },
+ {
+ .name = "CPU_GROUP_BIG",
+ .data = &(const struct mod_psu_element_cfg) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MOCK_PSU, 1),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MOCK_PSU,
+ MOD_MOCK_PSU_API_IDX_DRIVER)
+ },
+ },
+ {
+ .name = "GPU",
+ .data = &(const struct mod_psu_element_cfg) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MOCK_PSU, 2),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MOCK_PSU,
+ MOD_MOCK_PSU_API_IDX_DRIVER)
+ },
+ },
+ {
+ .name = "VPU",
+ .data = &(const struct mod_psu_element_cfg) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MOCK_PSU, 3),
+ .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/sgm776/scp_ramfw/config_scmi.c b/product/sgm776/scp_ramfw/config_scmi.c
new file mode 100644
index 00000000..fc128fca
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_scmi.c
@@ -0,0 +1,86 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <sgm776_scmi.h>
+#include <mod_scmi.h>
+#include <internal/scmi.h>
+#include <mod_smt.h>
+
+static const struct fwk_element service_table[] = {
+ [SGM776_SCMI_SERVICE_IDX_PSCI] = {
+ .name = "SERVICE0",
+ .data = &((struct mod_scmi_service_config) {
+ .transport_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SMT,
+ SGM776_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 = SCMI_AGENT_ID_PSCI,
+ }),
+ },
+ [SGM776_SCMI_SERVICE_IDX_OSPM_0] = {
+ .name = "SERVICE1",
+ .data = &((struct mod_scmi_service_config) {
+ .transport_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SMT,
+ SGM776_SCMI_SERVICE_IDX_OSPM_0),
+ .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 = SCMI_AGENT_ID_OSPM,
+ }),
+ },
+ [SGM776_SCMI_SERVICE_IDX_OSPM_1] = {
+ .name = "SERVICE2",
+ .data = &((struct mod_scmi_service_config) {
+ .transport_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SMT,
+ SGM776_SCMI_SERVICE_IDX_OSPM_1),
+ .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 = SCMI_AGENT_ID_OSPM,
+ }),
+ },
+ [SGM776_SCMI_SERVICE_IDX_COUNT] = { 0 }
+};
+
+static const struct fwk_element *get_service_table(fwk_id_t module_id)
+{
+ return service_table;
+}
+
+static const struct mod_scmi_agent agent_table[] = {
+ [SCMI_AGENT_ID_OSPM] = {
+ .type = SCMI_AGENT_TYPE_OSPM,
+ .name = "OSPM",
+ },
+ [SCMI_AGENT_ID_PSCI] = {
+ .type = SCMI_AGENT_TYPE_PSCI,
+ .name = "PSCI",
+ },
+};
+
+struct fwk_module_config config_scmi = {
+ .get_element_table = get_service_table,
+ .data = &((struct mod_scmi_config) {
+ .protocol_count_max = 9,
+ .agent_count = FWK_ARRAY_SIZE(agent_table) - 1,
+ .agent_table = agent_table,
+ .vendor_identifier = "arm",
+ .sub_vendor_identifier = "arm",
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_scmi_apcore.c b/product/sgm776/scp_ramfw/config_scmi_apcore.c
new file mode 100644
index 00000000..cfdfe5a2
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_scmi_apcore.c
@@ -0,0 +1,31 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_scmi_apcore.h>
+#include <sgm776_core.h>
+#include <sgm776_pik.h>
+
+static const struct mod_scmi_apcore_reset_register_group
+ reset_reg_group_table[] = {
+ {
+ .base_register =
+ (uintptr_t)&PIK_CLUS0->STATIC_CONFIG[0].RVBARADDR_LW,
+ .register_count = SGM776_CORE_PER_CLUSTER_MAX,
+ },
+ };
+
+const struct fwk_module_config config_scmi_apcore = {
+ .data = &((struct mod_scmi_apcore_config){
+ .reset_register_width = MOD_SCMI_APCORE_REG_WIDTH_64,
+ .reset_register_group_count =
+ FWK_ARRAY_SIZE(reset_reg_group_table),
+ .reset_register_group_table = &reset_reg_group_table[0],
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_scmi_clock.c b/product/sgm776/scp_ramfw/config_scmi_clock.c
new file mode 100644
index 00000000..27368930
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_scmi_clock.c
@@ -0,0 +1,70 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_scmi_clock.h>
+#include <sgm776_scmi.h>
+#include <clock_devices.h>
+
+static const struct mod_scmi_clock_device agent_device_table_ospm[] = {
+ {
+ /* VPU */
+ .element_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_IDX_VPU),
+ .permissions = MOD_SCMI_CLOCK_PERM_ATTRIBUTES |
+ MOD_SCMI_CLOCK_PERM_DESCRIBE_RATES |
+ MOD_SCMI_CLOCK_PERM_GET_RATE |
+ MOD_SCMI_CLOCK_PERM_SET_RATE,
+ },
+ {
+ /* DPU */
+ .element_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_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,
+ },
+ {
+ /* PIXEL_0 */
+ .element_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_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,
+ },
+ {
+ /* PIXEL_1 */
+ .element_id =
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_DEV_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[SCMI_AGENT_ID_COUNT] = {
+ [SCMI_AGENT_ID_PSCI] = { 0 /* No access */ },
+ [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),
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_scmi_perf.c b/product/sgm776/scp_ramfw/config_scmi_perf.c
new file mode 100644
index 00000000..e1dd43dc
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_scmi_perf.c
@@ -0,0 +1,43 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <config_dvfs.h>
+#include <sgm776_scmi.h>
+#include <mod_scmi_perf.h>
+
+static const struct mod_scmi_perf_domain_config domains[] = {
+ [DVFS_ELEMENT_IDX_LITTLE] = {
+ .permissions = &(const uint32_t[]) {
+ [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL |
+ MOD_SCMI_PERF_PERMS_SET_LIMITS,
+ [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE,
+ }
+ },
+ [DVFS_ELEMENT_IDX_BIG] = {
+ .permissions = &(const uint32_t[]) {
+ [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL |
+ MOD_SCMI_PERF_PERMS_SET_LIMITS,
+ [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE,
+ }
+ },
+ [DVFS_ELEMENT_IDX_GPU] = {
+ .permissions = &(const uint32_t[]) {
+ [SCMI_AGENT_ID_OSPM] = MOD_SCMI_PERF_PERMS_SET_LEVEL |
+ MOD_SCMI_PERF_PERMS_SET_LIMITS,
+ [SCMI_AGENT_ID_PSCI] = MOD_SCMI_PERF_PERMS_NONE,
+ }
+ },
+};
+
+const struct fwk_module_config config_scmi_perf = {
+ .data = &((struct mod_scmi_perf_config) {
+ .domains = &domains,
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_scmi_system_power.c b/product/sgm776/scp_ramfw/config_scmi_system_power.c
new file mode 100644
index 00000000..3302ccba
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_scmi_system_power.c
@@ -0,0 +1,19 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <fwk_module.h>
+#include <mod_scmi_system_power.h>
+#include <mod_system_power.h>
+
+struct fwk_module_config config_scmi_system_power = {
+ .get_element_table = NULL,
+ .data = &((struct mod_scmi_system_power_config) {
+ .system_view = MOD_SCMI_SYSTEM_VIEW_FULL,
+ .system_suspend_state = MOD_SYSTEM_POWER_POWER_STATE_SLEEP0
+ }),
+};
diff --git a/product/sgm776/scp_ramfw/config_sds.c b/product/sgm776/scp_ramfw/config_sds.c
new file mode 100644
index 00000000..95d68157
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_sds.c
@@ -0,0 +1,60 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_sds.h>
+#include <sgm776_mmap.h>
+#include <sgm776_sds.h>
+#include <clock_devices.h>
+
+static const uint32_t feature_flags = SGM776_SDS_FEATURE_FIRMWARE_MASK;
+static const uint32_t version_packed = FWK_BUILD_VERSION;
+
+const struct mod_sds_config sds_module_config = {
+ .region_base_address = TRUSTED_RAM_BASE,
+ .region_size = 3520,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_INTERCONNECT),
+};
+
+static const struct fwk_element sds_element_table[] = {
+ {
+ .name = "RAM Version",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_RAM_VERSION,
+ .size = SGM776_SDS_RAM_VERSION_SIZE,
+ .payload = &version_packed,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "Feature Availability",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_FEATURE_AVAILABILITY,
+ .size = sizeof(feature_flags),
+ .payload = &feature_flags,
+ .finalize = true,
+ }),
+ },
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *sds_get_element_table(fwk_id_t module_id)
+{
+ return sds_element_table;
+}
+
+const struct fwk_module_config config_sds = {
+ .get_element_table = sds_get_element_table,
+ .data = &sds_module_config,
+};
diff --git a/product/sgm776/scp_ramfw/config_sensor.c b/product/sgm776/scp_ramfw/config_sensor.c
new file mode 100644
index 00000000..75c77a59
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_sensor.c
@@ -0,0 +1,75 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_reg_sensor.h>
+#include <mod_sensor.h>
+#include <system_mmap.h>
+
+enum REG_SENSOR_DEVICES {
+ REG_SENSOR_DEV_SOC_TEMP,
+ REG_SENSOR_DEV_COUNT,
+};
+
+/*
+ * Register Sensor driver config
+ */
+
+static struct mod_sensor_info info_soc_temperature = {
+ .type = MOD_SENSOR_TYPE_DEGREES_C,
+ .update_interval = 0,
+ .update_interval_multiplier = 0,
+ .unit_multiplier = 0,
+};
+
+static const struct fwk_element reg_sensor_element_table[] = {
+ [REG_SENSOR_DEV_SOC_TEMP] = {
+ .name = "Soc Temperature",
+ .data = &((struct mod_reg_sensor_dev_config) {
+ .reg = (uintptr_t)(SENSOR_SOC_TEMP),
+ .info = &info_soc_temperature,
+ }),
+ },
+ [REG_SENSOR_DEV_COUNT] = { 0 },
+};
+
+static const struct fwk_element *get_reg_sensor_element_table(fwk_id_t id)
+{
+ return reg_sensor_element_table;
+}
+
+struct fwk_module_config config_reg_sensor = {
+ .get_element_table = get_reg_sensor_element_table,
+};
+
+/*
+ * Sensor module config
+ */
+static const struct fwk_element sensor_element_table[] = {
+ [0] = {
+ .name = "Soc Temperature",
+ .data = &((const struct mod_sensor_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_REG_SENSOR,
+ REG_SENSOR_DEV_SOC_TEMP),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_REG_SENSOR, 0),
+ }),
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *get_sensor_element_table(fwk_id_t module_id)
+{
+ return sensor_element_table;
+}
+
+const struct fwk_module_config config_sensor = {
+ .get_element_table = get_sensor_element_table,
+ .data = NULL,
+};
diff --git a/product/sgm776/scp_ramfw/config_smt.c b/product/sgm776/scp_ramfw/config_smt.c
new file mode 100644
index 00000000..ee9fb7a4
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_smt.c
@@ -0,0 +1,82 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_mhu2.h>
+#include <mod_smt.h>
+#include <sgm776_core.h>
+#include <sgm776_mhu.h>
+#include <sgm776_scmi.h>
+#include <config_power_domain.h>
+#include <clock_devices.h>
+#include <software_mmap.h>
+
+static const struct fwk_element smt_element_table[] = {
+ [SGM776_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)SCMI_PAYLOAD_S_A2P_BASE,
+ .mailbox_size = SCMI_PAYLOAD_SIZE,
+ .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_MHU2,
+ SGM776_MHU_DEVICE_IDX_S, 0),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU2,
+ MOD_MHU2_API_IDX_SMT_DRIVER),
+ })
+ },
+ [SGM776_SCMI_SERVICE_IDX_OSPM_0] = {
+ .name = "OSPM0",
+ .data = &((struct mod_smt_channel_config) {
+ .type = MOD_SMT_CHANNEL_TYPE_SLAVE,
+ .policies = MOD_SMT_POLICY_INIT_MAILBOX,
+ .mailbox_address = (uintptr_t)SCMI_PAYLOAD0_NS_A2P_BASE,
+ .mailbox_size = SCMI_PAYLOAD_SIZE,
+ .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_MHU2,
+ SGM776_MHU_DEVICE_IDX_NS_L, 0),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU2,
+ MOD_MHU2_API_IDX_SMT_DRIVER),
+ })
+ },
+ [SGM776_SCMI_SERVICE_IDX_OSPM_1] = {
+ .name = "OSPM1",
+ .data = &((struct mod_smt_channel_config) {
+ .type = MOD_SMT_CHANNEL_TYPE_SLAVE,
+ .policies = MOD_SMT_POLICY_INIT_MAILBOX,
+ .mailbox_address = (uintptr_t)SCMI_PAYLOAD1_NS_A2P_BASE,
+ .mailbox_size = SCMI_PAYLOAD_SIZE,
+ .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_MHU2,
+ SGM776_MHU_DEVICE_IDX_NS_H, 0),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_MHU2,
+ MOD_MHU2_API_IDX_SMT_DRIVER),
+ })
+ },
+ [SGM776_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 < SGM776_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,
+ CONFIG_POWER_DOMAIN_SYSTOP_CHILD_COUNT + sgm776_core_get_count());
+ }
+
+ return smt_element_table;
+}
+
+struct fwk_module_config config_smt = {
+ .get_element_table = smt_get_element_table,
+};
diff --git a/product/sgm776/scp_ramfw/config_system_pll.c b/product/sgm776/scp_ramfw/config_system_pll.c
new file mode 100644
index 00000000..829ed8f3
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_system_pll.c
@@ -0,0 +1,117 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_system_pll.h>
+#include <sgm776_pik.h>
+#include <system_mmap.h>
+
+static const struct fwk_element system_pll_element_table[] = {
+ {
+ .name = "CPU_PLL_0",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_CLUS0_0,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS1,
+ .lock_flag_mask = PLL_STATUS1_CPUPLLLOCK(0, 0),
+ .initial_rate = 2200 * 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,
+ }),
+ },
+ {
+ .name = "CPU_PLL_1",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_CLUS0_1,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS1,
+ .lock_flag_mask = PLL_STATUS1_CPUPLLLOCK(0, 1),
+ .initial_rate = 2700 * 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,
+ }),
+ },
+ {
+ .name = "GPU_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_GPU,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS0,
+ .lock_flag_mask = PLL_STATUS0_GPUPLLLOCK,
+ .initial_rate = 800 * 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,
+ }),
+ },
+ {
+ .name = "DPU_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_DISPLAY,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS0,
+ .lock_flag_mask = PLL_STATUS0_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,
+ }),
+ },
+ {
+ .name = "VPU_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_VIDEO,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS0,
+ .lock_flag_mask = PLL_STATUS0_VIDEOPLLLOCK,
+ .initial_rate = 650 * 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,
+ }),
+ },
+ {
+ .name = "PIX0_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PIX0_CONTROL,
+ .status_reg = NULL,
+ .initial_rate = 594 * FWK_MHZ,
+ .min_rate = 12500 * FWK_KHZ,
+ .max_rate = 594 * FWK_MHZ,
+ .min_step = 250 * FWK_KHZ,
+ .defer_initialization = false,
+ }),
+ },
+ {
+ .name = "PIX1_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PIX1_CONTROL,
+ .status_reg = NULL,
+ .initial_rate = 594 * FWK_MHZ,
+ .min_rate = 12500 * FWK_KHZ,
+ .max_rate = 594 * FWK_MHZ,
+ .min_step = 250 * FWK_KHZ,
+ .defer_initialization = false,
+ }),
+ },
+ { 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/sgm776/scp_ramfw/config_system_power.c b/product/sgm776/scp_ramfw/config_system_power.c
new file mode 100644
index 00000000..9edfbe3f
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_system_power.c
@@ -0,0 +1,99 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <sgm776_irq.h>
+#include <config_ppu_v1.h>
+#include <mod_ppu_v1.h>
+#include <mod_system_power.h>
+#include <mod_sgm776_system.h>
+
+/*
+ * The DPU/GPU/VPU PPUs in this list are there as a temporary workaround, until
+ * Linux supports handling these domains on its own.
+ */
+static const struct mod_system_power_ext_ppu_config ext_ppus[] = {
+ {
+ .ppu_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_DPUTOP),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ },
+ {
+ .ppu_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_GPUTOP),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ },
+ {
+ .ppu_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_VPUTOP),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1,
+ MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
+ },
+};
+
+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 const struct fwk_element system_power_element_table[] = {
+ [0] = {
+ .name = "SYS-PPU-0",
+ .data = &((struct mod_system_power_dev_config) {
+ .sys_ppu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_SYS0),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1, 0),
+ .sys_state_table = system_power_to_sys_ppu0_state,
+ }),
+ },
+
+ [1] = {
+ .name = "SYS-PPU-1",
+ .data = &((struct mod_system_power_dev_config) {
+ .sys_ppu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1,
+ PPU_V1_ELEMENT_IDX_SYS1),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1, 0),
+ .sys_state_table = system_power_to_sys_ppu1_state,
+ }),
+ },
+
+ [2] = { 0 }, /* Termination description */
+};
+
+static const struct fwk_element *system_power_get_element_table(
+ fwk_id_t module_id)
+{
+ return system_power_element_table;
+}
+
+const struct fwk_module_config config_system_power = {
+ .data = &((struct mod_system_power_config) {
+ .soc_wakeup_irq = SOC_WAKEUP0_IRQ,
+ .ext_ppus = ext_ppus,
+ .ext_ppus_count = FWK_ARRAY_SIZE(ext_ppus),
+ .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SGM776_SYSTEM),
+ .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SGM776_SYSTEM,
+ MOD_SGM776_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER),
+ .initial_system_power_state = MOD_PD_STATE_ON,
+ }),
+ .get_element_table = system_power_get_element_table,
+};
diff --git a/product/sgm776/scp_ramfw/config_timer.c b/product/sgm776/scp_ramfw/config_timer.c
new file mode 100644
index 00000000..69c5720e
--- /dev/null
+++ b/product/sgm776/scp_ramfw/config_timer.c
@@ -0,0 +1,71 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_gtimer.h>
+#include <mod_timer.h>
+#include <sgm776_mmap.h>
+#include <sgm776_irq.h>
+#include <clock_devices.h>
+#include <system_clock.h>
+
+/*
+ * Generic timer driver config
+ */
+static const struct fwk_element gtimer_dev_table[] = {
+ [0] = {
+ .name = "REFCLK",
+ .data = &((struct mod_gtimer_dev_config) {
+ .hw_timer = REFCLK_CNTBASE0_BASE,
+ .hw_counter = REFCLK_CNTCTL_BASE,
+ .control = REFCLK_CNTCONTROL_BASE,
+ .frequency = CLOCK_RATE_REFCLK,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_INTERCONNECT),
+ })
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *gtimer_get_dev_table(fwk_id_t module_id)
+{
+ return gtimer_dev_table;
+}
+
+const struct fwk_module_config config_gtimer = {
+ .get_element_table = gtimer_get_dev_table,
+};
+
+/*
+ * Timer HAL config
+ */
+static const struct mod_timer_dev_config refclk_config = {
+ .id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_GTIMER, 0),
+ .timer_irq = TIMREFCLK_IRQ,
+};
+
+static const struct fwk_element timer_dev_table[] = {
+ [0] = {
+ .name = "REFCLK",
+ .data = &refclk_config,
+ .sub_element_count = 8, /* Number of alarms */
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *timer_get_dev_table(fwk_id_t module_id)
+{
+ return timer_dev_table;
+}
+
+const struct fwk_module_config config_timer = {
+ .get_element_table = timer_get_dev_table,
+};
diff --git a/product/sgm776/scp_ramfw/firmware.mk b/product/sgm776/scp_ramfw/firmware.mk
new file mode 100644
index 00000000..26aca7bf
--- /dev/null
+++ b/product/sgm776/scp_ramfw/firmware.mk
@@ -0,0 +1,73 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_FIRMWARE_CPU := cortex-m3
+BS_FIRMWARE_HAS_MULTITHREADING := yes
+BS_FIRMWARE_HAS_NOTIFICATION := yes
+
+BS_FIRMWARE_MODULES := \
+ sid \
+ pcid \
+ pl011 \
+ log \
+ gtimer \
+ timer \
+ ddr_phy500 \
+ dmc500 \
+ reg_sensor \
+ sensor \
+ ppu_v1 \
+ system_power \
+ sgm776_system \
+ power_domain \
+ psu \
+ mock_psu \
+ mhu2 \
+ smt \
+ system_pll \
+ pik_clock \
+ css_clock \
+ clock \
+ dvfs \
+ scmi \
+ scmi_power_domain \
+ scmi_system_power \
+ scmi_clock \
+ scmi_perf \
+ scmi_sensor \
+ scmi_apcore \
+ sds
+
+BS_FIRMWARE_SOURCES := \
+ rtx_config.c \
+ config_log.c \
+ config_timer.c \
+ config_ddr_phy500.c \
+ config_dmc500.c \
+ config_sensor.c \
+ config_ppu_v1.c \
+ config_system_power.c \
+ config_power_domain.c \
+ sgm776_core.c \
+ config_sds.c \
+ config_mhu.c \
+ config_smt.c \
+ config_scmi.c \
+ config_scmi_system_power.c \
+ config_scmi_clock.c \
+ config_scmi_perf.c \
+ config_scmi_apcore.c \
+ config_system_pll.c \
+ config_pik_clock.c \
+ config_css_clock.c \
+ config_clock.c \
+ config_psu.c \
+ config_mock_psu.c \
+ config_dvfs.c \
+ config_sid.c
+
+include $(BS_DIR)/firmware.mk
diff --git a/product/sgm776/scp_ramfw/fmw_memory.ld.S b/product/sgm776/scp_ramfw/fmw_memory.ld.S
new file mode 100644
index 00000000..4f062809
--- /dev/null
+++ b/product/sgm776/scp_ramfw/fmw_memory.ld.S
@@ -0,0 +1,21 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FMW_MEMORY_LD_S
+#define FMW_MEMORY_LD_S
+
+#include <system_mmap_scp.h>
+
+#define FIRMWARE_MEM_MODE FWK_MEM_MODE_SINGLE_REGION
+
+/* RAM */
+#define FIRMWARE_MEM0_BASE SCP_RAM_BASE
+#define FIRMWARE_MEM0_SIZE SCP_RAM_SIZE
+
+#define FIRMWARE_STACK_SIZE (1 * 1024)
+
+#endif /* FMW_MEMORY_LD_S */
diff --git a/product/sgm776/scp_ramfw/rtx_config.c b/product/sgm776/scp_ramfw/rtx_config.c
new file mode 100644
index 00000000..12842cd8
--- /dev/null
+++ b/product/sgm776/scp_ramfw/rtx_config.c
@@ -0,0 +1,79 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <cmsis_compiler.h>
+#include <rtx_os.h>
+#include <system_clock.h>
+
+#include <rtx_lib.c>
+
+/*
+ * Required by RTX to configure the SysTick timer.
+ */
+uint32_t SystemCoreClock = CLOCK_RATE_REFCLK;
+
+/*
+ * Idle thread
+ */
+__NO_RETURN void osRtxIdleThread(void *argument)
+{
+ (void)argument;
+
+ while (true)
+ __WFI();
+}
+
+/*
+ * OS error handler
+ */
+uint32_t osRtxErrorNotify(uint32_t code, void *object_id)
+{
+ (void)object_id;
+
+ switch (code) {
+ case osRtxErrorStackUnderflow:
+ /*
+ * Stack underflow detected for thread
+ * thread_id=object_id
+ */
+ break;
+
+ case osRtxErrorISRQueueOverflow:
+ /*
+ * ISR Queue overflow detected when inserting object
+ * object_id
+ */
+ break;
+
+ case osRtxErrorTimerQueueOverflow:
+ /*
+ * User Timer Callback Queue overflow detected for timer
+ * timer_id=object_id
+ */
+ break;
+
+ case osRtxErrorClibSpace:
+ /*
+ * Standard C/C++ library libspace not available:
+ * increase OS_THREAD_LIBSPACE_NUM
+ */
+ break;
+
+ case osRtxErrorClibMutex:
+ /*
+ * Standard C/C++ library mutex initialization failed
+ */
+ break;
+
+ default:
+ break;
+ }
+
+ osRtxIdleThread(object_id);
+}
diff --git a/product/sgm776/scp_romfw/clock_devices.h b/product/sgm776/scp_romfw/clock_devices.h
new file mode 100644
index 00000000..be2f007a
--- /dev/null
+++ b/product/sgm776/scp_romfw/clock_devices.h
@@ -0,0 +1,28 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCK_DEVICES_H
+#define CLOCK_DEVICES_H
+
+/*!
+ * \brief Clock device indexes.
+ */
+enum clock_dev_idx {
+ CLOCK_DEV_IDX_BIG,
+ CLOCK_DEV_IDX_LITTLE,
+ CLOCK_DEV_IDX_GPU,
+ CLOCK_DEV_IDX_SYS_NOCMEMCLK,
+ CLOCK_DEV_IDX_SYS_FCMCLK,
+ CLOCK_DEV_IDX_SYS_GICCLK,
+ CLOCK_DEV_IDX_SYS_PCLKSCP,
+ CLOCK_DEV_IDX_SYS_SYSPERCLK,
+ CLOCK_DEV_IDX_PLL_SWTCLKTCK,
+ CLOCK_DEV_IDX_PLL_SYSTEM,
+ CLOCK_DEV_IDX_COUNT
+};
+
+#endif /* CLOCK_DEVICES_H */
diff --git a/product/sgm776/scp_romfw/config_bootloader.c b/product/sgm776/scp_romfw/config_bootloader.c
new file mode 100644
index 00000000..f9177984
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_bootloader.c
@@ -0,0 +1,26 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_bootloader.h>
+#include <system_mmap.h>
+#include <system_mmap_scp.h>
+#include <sgm776_sds.h>
+
+static const struct mod_bootloader_config bootloader_module_config = {
+ .source_base = TRUSTED_RAM_BASE,
+ .source_size = 256 * 1024,
+ .destination_base = SCP_RAM_BASE,
+ .destination_size = SCP_RAM_SIZE,
+ .sds_struct_id = SGM776_SDS_BOOTLOADER,
+};
+
+struct fwk_module_config config_bootloader = {
+ .data = &bootloader_module_config,
+};
diff --git a/product/sgm776/scp_romfw/config_clock.c b/product/sgm776/scp_romfw/config_clock.c
new file mode 100644
index 00000000..0f796d0c
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_clock.c
@@ -0,0 +1,117 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_css_clock.h>
+#include <mod_system_pll.h>
+#include <mod_msys_rom.h>
+#include <mod_pik_clock.h>
+#include <clock_devices.h>
+
+static const struct fwk_element clock_dev_desc_table[] = {
+ [CLOCK_DEV_IDX_BIG] = {
+ .name = "CPU_GROUP_BIG",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 0),
+ .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),
+ }),
+ },
+ [CLOCK_DEV_IDX_LITTLE] = {
+ .name = "CPU_GROUP_LITTLE",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 1),
+ .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),
+ }),
+ },
+ [CLOCK_DEV_IDX_GPU] = {
+ .name = "GPU",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CSS_CLOCK, 2),
+ .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),
+ }),
+ },
+ [CLOCK_DEV_IDX_SYS_NOCMEMCLK] = {
+ .name = "SYS_NOCMEMCLK",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 0),
+ .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_DEV_IDX_SYS_FCMCLK] = {
+ .name = "SYS_FCMCLK",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 1),
+ .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_DEV_IDX_SYS_GICCLK] = {
+ .name = "SYS_GICCLK",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 2),
+ .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_DEV_IDX_SYS_PCLKSCP] = {
+ .name = "SYS_PCLKSCP",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 3),
+ .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_DEV_IDX_SYS_SYSPERCLK] = {
+ .name = "SYS_SYSPERCLK",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 4),
+ .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_DEV_IDX_PLL_SYSTEM] = {
+ .name = "PLL_SYSTEM",
+ .data = &((struct mod_clock_dev_config) {
+ .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 3),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .pd_source_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MSYS_ROM),
+ }),
+ },
+ [CLOCK_DEV_IDX_COUNT] = { 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,
+ }),
+};
diff --git a/product/sgm776/scp_romfw/config_css_clock.c b/product/sgm776/scp_romfw/config_css_clock.c
new file mode 100644
index 00000000..69b50e20
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_css_clock.c
@@ -0,0 +1,186 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_assert.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_css_clock.h>
+#include <mod_system_pll.h>
+#include <mod_pik_clock.h>
+#include <mod_sid.h>
+
+static const struct mod_css_clock_rate rate_table_cpu_group_big[] = {
+ {
+ .rate = 2700 * FWK_MHZ,
+ .pll_rate = 2700 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+};
+
+static const struct mod_css_clock_rate rate_table_cpu_group_little[] = {
+ {
+ .rate = 2200 * FWK_MHZ,
+ .pll_rate = 2200 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ .clock_mod_numerator = 1,
+ .clock_mod_denominator = 1,
+ },
+};
+
+static const struct mod_css_clock_rate rate_table_gpu[] = {
+ {
+ .rate = 800 * FWK_MHZ,
+ .pll_rate = 800 * FWK_MHZ,
+ .clock_source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .clock_div = 1,
+ },
+};
+
+static const fwk_id_t member_table_cpu_big_cfg_a[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 11),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 12),
+};
+
+static const fwk_id_t member_table_cpu_little_cfg_a[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 5),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 6),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 7),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 8),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 9),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 10),
+};
+
+static const fwk_id_t member_table_cpu_big_cfg_b[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 9),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 10),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 11),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 12),
+};
+
+static const fwk_id_t member_table_cpu_little_cfg_b[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 5),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 6),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 7),
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 8),
+};
+
+static const fwk_id_t member_table_gpu[] = {
+ FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, 13),
+};
+
+static const struct fwk_element css_clock_element_table[] = {
+ {
+ .name = "CPU_GROUP_BIG",
+ .data = &((struct mod_css_clock_dev_config) {
+ .rate_table = rate_table_cpu_group_big,
+ .rate_count = sizeof(rate_table_cpu_group_big) /
+ sizeof(struct mod_css_clock_rate),
+ .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 1),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 2700 * FWK_MHZ,
+ .modulation_supported = true,
+ }),
+ },
+ {
+ .name = "CPU_GROUP_LITTLE",
+ .data = &((struct mod_css_clock_dev_config) {
+ .rate_table = rate_table_cpu_group_little,
+ .rate_count = sizeof(rate_table_cpu_group_little) /
+ sizeof(struct mod_css_clock_rate),
+ .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 0),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 2200 * FWK_MHZ,
+ .modulation_supported = true,
+ }),
+ },
+ {
+ .name = "GPU",
+ .data = &((struct mod_css_clock_dev_config) {
+ .rate_table = rate_table_gpu,
+ .rate_count = sizeof(rate_table_gpu) /
+ sizeof(struct mod_css_clock_rate),
+ .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK,
+ .pll_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SYSTEM_PLL, 2),
+ .pll_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SYSTEM_PLL,
+ MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
+ .member_table = member_table_gpu,
+ .member_count = FWK_ARRAY_SIZE(member_table_gpu),
+ .member_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK,
+ MOD_PIK_CLOCK_API_TYPE_CSS),
+ .initial_rate = 800 * FWK_MHZ,
+ .modulation_supported = false,
+ }),
+ },
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *css_clock_get_element_table
+ (fwk_id_t module_id)
+{
+ int status;
+ struct mod_css_clock_dev_config *config_big;
+ struct mod_css_clock_dev_config *config_little;
+ const struct mod_sid_info *system_info;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ config_big =
+ (struct mod_css_clock_dev_config *) css_clock_element_table[0].data;
+ config_little =
+ (struct mod_css_clock_dev_config *) css_clock_element_table[1].data;
+
+ switch (system_info->config_number) {
+ case 1:
+ case 5:
+ case 7:
+ case 8:
+ config_big->member_table = member_table_cpu_big_cfg_a;
+ config_big->member_count = FWK_ARRAY_SIZE(member_table_cpu_big_cfg_a);
+
+ config_little->member_table = member_table_cpu_little_cfg_a;
+ config_little->member_count =
+ FWK_ARRAY_SIZE(member_table_cpu_little_cfg_a);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ config_big->member_table = member_table_cpu_big_cfg_b;
+ config_big->member_count = FWK_ARRAY_SIZE(member_table_cpu_big_cfg_b);
+
+ config_little->member_table = member_table_cpu_little_cfg_b;
+ config_little->member_count =
+ FWK_ARRAY_SIZE(member_table_cpu_little_cfg_b);
+ break;
+ default:
+ return NULL;
+ }
+
+ 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/sgm776/scp_romfw/config_log.c b/product/sgm776/scp_romfw/config_log.c
new file mode 100644
index 00000000..29fdf358
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_log.c
@@ -0,0 +1,62 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_banner.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_log.h>
+#include <mod_pl011.h>
+#include <system_mmap.h>
+#include <clock_devices.h>
+
+/*
+ * PL011 module
+ */
+static const struct fwk_element pl011_element_desc_table[] = {
+ [0] = {
+ .name = "board-uart1",
+ .data = &((struct mod_pl011_device_config) {
+ .reg_base = BOARD_UART1_BASE,
+ .baud_rate_bps = 115200,
+ .clock_rate_hz = 24 * FWK_MHZ,
+ .clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_SYS_NOCMEMCLK),
+ }),
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *get_pl011_table(fwk_id_t module_id)
+{
+ return pl011_element_desc_table;
+}
+
+struct fwk_module_config config_pl011 = {
+ .get_element_table = get_pl011_table,
+};
+
+/*
+ * Log module
+ */
+static const struct mod_log_config log_data = {
+ .device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PL011, 0),
+ .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PL011, 0),
+ .log_groups = MOD_LOG_GROUP_ERROR |
+ MOD_LOG_GROUP_INFO |
+ MOD_LOG_GROUP_WARNING |
+ MOD_LOG_GROUP_DEBUG,
+ .banner = FWK_BANNER_SCP
+ FWK_BANNER_ROM_FIRMWARE
+ BUILD_VERSION_DESCRIBE_STRING "\n",
+};
+
+struct fwk_module_config config_log = {
+ .get_element_table = NULL,
+ .data = &log_data,
+};
diff --git a/product/sgm776/scp_romfw/config_msys_rom.c b/product/sgm776/scp_romfw/config_msys_rom.c
new file mode 100644
index 00000000..1e38f1b1
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_msys_rom.c
@@ -0,0 +1,23 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_msys_rom.h>
+#include <sgm776_mmap_scp.h>
+#include <software_mmap.h>
+
+const struct fwk_module_config config_msys_rom = {
+ .data = &((struct msys_rom_config) {
+ .ap_context_base = AP_CONTEXT_BASE,
+ .ap_context_size = AP_CONTEXT_SIZE,
+ .ramfw_base = SCP_RAM_BASE,
+ .id_primary_cluster = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 2),
+ .id_primary_core = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 3),
+ })
+};
diff --git a/product/sgm776/scp_romfw/config_pik_clock.c b/product/sgm776/scp_romfw/config_pik_clock.c
new file mode 100644
index 00000000..f42d2d1b
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_pik_clock.c
@@ -0,0 +1,341 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_assert.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_pik_clock.h>
+#include <mod_sid.h>
+#include <sgm776_pik.h>
+#include <system_clock.h>
+
+/*
+ * Rate lookup tables.
+ */
+
+static const struct mod_pik_clock_rate rate_table_sys_nocmemclk[] = {
+ {
+ .rate = 720 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (720 * FWK_MHZ),
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_sys_fcmclk[] = {
+ {
+ .rate = 1800 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (1800 * FWK_MHZ),
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_sys_gicclk[] = {
+ {
+ .rate = 600 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (600 * FWK_MHZ),
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_sys_pclkscp[] = {
+ {
+ .rate = 225 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (225 * FWK_MHZ),
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_sys_sysperclk[] = {
+ {
+ .rate = 225 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
+ .divider = CLOCK_RATE_SYSPLLCLK / (225 * FWK_MHZ),
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_cpu_a55[] = {
+ {
+ .rate = 2200 * 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_cpu_a75[] = {
+ {
+ .rate = 2700 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via CPU PLL */
+ },
+};
+
+static const struct mod_pik_clock_rate rate_table_gpu[] = {
+ {
+ .rate = 800 * FWK_MHZ,
+ .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK,
+ .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
+ .divider = 1, /* Rate adjusted via GPU PLL */
+ },
+};
+
+static const struct fwk_element pik_clock_element_table[] = {
+ /*
+ * System Clocks
+ */
+ {
+ .name = "SYS_NOCMEMCLK",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->NOCMEMCLK_CTRL,
+ .divsys_reg = &PIK_SYSTEM->NOCMEMCLK_DIV1,
+ .rate_table = rate_table_sys_nocmemclk,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_nocmemclk),
+ .initial_rate = 720 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "SYS_FCMCLK",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->FCMCLK_CTRL,
+ .divsys_reg = &PIK_SYSTEM->FCMCLK_DIV1,
+ .rate_table = rate_table_sys_fcmclk,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_fcmclk),
+ .initial_rate = 1800 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "SYS_GICCLK",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->GICCLK_CTRL,
+ .divsys_reg = &PIK_SYSTEM->GICCLK_DIV1,
+ .rate_table = rate_table_sys_gicclk,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_gicclk),
+ .initial_rate = 600 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "SYS_PCLKSCP",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->PCLKSCP_CTRL,
+ .divsys_reg = &PIK_SYSTEM->PCLKSCP_DIV1,
+ .rate_table = rate_table_sys_pclkscp,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_pclkscp),
+ .initial_rate = 225 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "SYS_SYSPERCLK",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = false,
+ .control_reg = &PIK_SYSTEM->SYSPERCLK_CTRL,
+ .divsys_reg = &PIK_SYSTEM->SYSPERCLK_DIV1,
+ .rate_table = rate_table_sys_sysperclk,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_sys_sysperclk),
+ .initial_rate = 225 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * Cluster 0 CPUs
+ */
+ {
+ .name = "CLUS0_CPU0",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[0].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[0].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[0].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU1",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[1].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[1].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[1].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU2",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[2].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[2].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[2].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU3",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[3].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[3].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[3].MOD,
+ .initial_rate = 2200 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU4",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[4].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[4].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[4].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU5",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[5].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[5].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[5].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU6",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[6].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[6].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[6].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ {
+ .name = "CLUS0_CPU7",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_CLUSTER,
+ .is_group_member = true,
+ .control_reg = &PIK_CLUS0->CORECLK[7].CTRL,
+ .divext_reg = &PIK_CLUS0->CORECLK[7].DIV,
+ .modulator_reg = &PIK_CLUS0->CORECLK[7].MOD,
+ .initial_rate = 2700 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ /*
+ * GPU
+ */
+ {
+ .name = "GPU",
+ .data = &((struct mod_pik_clock_dev_config) {
+ .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
+ .is_group_member = true,
+ .control_reg = &PIK_GPU->GPUCLK_CTRL,
+ .divsys_reg = &PIK_GPU->GPUCLK_DIV1,
+ .divext_reg = &PIK_GPU->GPUCLK_DIV2,
+ .rate_table = rate_table_gpu,
+ .rate_count = FWK_ARRAY_SIZE(rate_table_gpu),
+ .initial_rate = 800 * FWK_MHZ,
+ .defer_initialization = true,
+ }),
+ },
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *pik_clock_get_element_table
+ (fwk_id_t module_id)
+{
+ int status;
+ int element_idx;
+ struct mod_pik_clock_dev_config *config;
+ const struct mod_sid_info *system_info;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ switch (system_info->config_number) {
+ case 1:
+ case 5:
+ case 7:
+ case 8:
+ /* CPUs 0-5: Little */
+ for (element_idx = 5; element_idx < 11; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a55;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a55);
+ }
+ /* CPUs 6-7: Big */
+ for (element_idx = 11; element_idx < 13; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a75;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a75);
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ /* CPUs 0-3: Little */
+ for (element_idx = 5; element_idx < 9; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a55;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a55);
+ }
+ /* CPUs 4-7: Big */
+ for (element_idx = 9; element_idx < 13; element_idx++) {
+ config = (struct mod_pik_clock_dev_config *)
+ pik_clock_element_table[element_idx].data;
+ config->rate_table = rate_table_cpu_a75;
+ config->rate_count = FWK_ARRAY_SIZE(rate_table_cpu_a75);
+ }
+ break;
+ default:
+ return NULL;
+ }
+
+ 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/sgm776/scp_romfw/config_ppu_v1.c b/product/sgm776/scp_romfw/config_ppu_v1.c
new file mode 100644
index 00000000..3d12d9cc
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_ppu_v1.c
@@ -0,0 +1,77 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <fwk_element.h>
+#include <fwk_mm.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_msys_rom.h>
+#include <mod_ppu_v1.h>
+#include <sgm776_irq.h>
+#include <sgm776_mmap.h>
+
+static struct fwk_element sgm776_ppu_v1_element_table[] = {
+ {
+ .name = "SYS0",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_SYSTEM,
+ .ppu.reg_base = PPU_SYS0_BASE,
+ .ppu.irq = PPU_SYS0_IRQ,
+ .default_power_on = true,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ {
+ .name = "SYS1",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_SYSTEM,
+ .ppu.reg_base = PPU_SYS1_BASE,
+ .ppu.irq = PPU_SYS1_IRQ,
+ .default_power_on = true,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ {
+ .name = "CLUS0",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_CLUSTER,
+ .ppu.reg_base = PPU_CLUS0_BASE,
+ .ppu.irq = PPU_CLUS0_IRQ,
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ {
+ .name = "CORE0",
+ .data = &((struct mod_ppu_v1_pd_config) {
+ .pd_type = MOD_PD_TYPE_CORE,
+ .ppu.reg_base = PPU_CLUS0CORE0_BASE,
+ .ppu.irq = PPU_CLUS0CORE0_IRQ,
+ .cluster_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 2),
+ .observer_id = FWK_ID_NONE_INIT,
+ }),
+ },
+ { 0 }, /* Termination entry */
+};
+
+static const struct fwk_element *sgm776_ppu_v1_get_element_table(
+ fwk_id_t module_id)
+{
+ return sgm776_ppu_v1_element_table;
+}
+
+/*
+ * Power module configuration data
+ */
+struct fwk_module_config config_ppu_v1 = {
+ .get_element_table = sgm776_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),
+ },
+};
diff --git a/product/sgm776/scp_romfw/config_sds.c b/product/sgm776/scp_romfw/config_sds.c
new file mode 100644
index 00000000..ffae2b24
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_sds.c
@@ -0,0 +1,126 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_assert.h>
+#include <stdint.h>
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_sds.h>
+#include <mod_sid.h>
+#include <sgm776_mmap.h>
+#include <sgm776_sds.h>
+#include <sgm776_pik.h>
+#include <system_mmap.h>
+#include <clock_devices.h>
+
+static const uint32_t version_packed = FWK_BUILD_VERSION;
+static struct sgm776_sds_platid platid;
+
+static const struct mod_sds_config sds_module_config = {
+ .region_base_address = TRUSTED_RAM_BASE,
+ .region_size = 3520,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_SYS_NOCMEMCLK),
+};
+
+static const struct fwk_element sds_element_table[] = {
+ {
+ .name = "CPU Info",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_CPU_INFO,
+ .size = SGM776_SDS_CPU_INFO_SIZE,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "ROM Version",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_ROM_VERSION,
+ .size = SGM776_SDS_ROM_VERSION_SIZE,
+ .payload = &version_packed,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "Platform ID",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_PLATFORM_ID,
+ .size = SGM776_SDS_PLATFORM_ID_SIZE,
+ .payload = &platid,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "Reset Syndrome",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_RESET_SYNDROME,
+ .size = SGM776_SDS_RESET_SYNDROME_SIZE,
+ .payload = (const void *)&PIK_SCP->RESET_SYNDROME,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "Bootloader",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_BOOTLOADER,
+ .size = SGM776_SDS_BOOTLOADER_SIZE,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "Features",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_FEATURE_AVAILABILITY,
+ .size = SGM776_SDS_FEATURE_AVAILABILITY_SIZE,
+ .finalize = true,
+ }),
+ },
+#ifdef MODE_DEBUG
+ {
+ .name = "Boot Counters",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_CPU_BOOTCTR,
+ .size = SGM776_SDS_CPU_BOOTCTR_SIZE,
+ .finalize = true,
+ }),
+ },
+ {
+ .name = "CPU Flags",
+ .data = &((struct mod_sds_structure_desc) {
+ .id = SGM776_SDS_CPU_FLAGS,
+ .size = SGM776_SDS_CPU_FLAGS_SIZE,
+ .finalize = true,
+ }),
+ },
+#endif
+ { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *sds_get_element_table(fwk_id_t module_id)
+{
+ int status;
+ const struct mod_sid_info *system_info;
+
+ 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");
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+ platid.platform_identifier = system_info->system_part_number;
+ platid.platform_type_identifier = *((uint32_t*)PLATFORM_ID);
+
+ 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/sgm776/scp_romfw/config_system_pll.c b/product/sgm776/scp_romfw/config_system_pll.c
new file mode 100644
index 00000000..01beaf6c
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_system_pll.c
@@ -0,0 +1,79 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <mod_system_pll.h>
+#include <sgm776_pik.h>
+#include <system_mmap.h>
+
+static const struct fwk_element system_pll_element_table[] = {
+ {
+ .name = "CPU_PLL_0",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_CLUS0_0,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS1,
+ .lock_flag_mask = PLL_STATUS1_CPUPLLLOCK(0, 0),
+ .initial_rate = 2700 * 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,
+ }),
+ },
+ {
+ .name = "CPU_PLL_1",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_CLUS0_1,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS1,
+ .lock_flag_mask = PLL_STATUS1_CPUPLLLOCK(0, 1),
+ .initial_rate = 2200 * 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,
+ }),
+ },
+ {
+ .name = "GPU_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_GPU,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS0,
+ .lock_flag_mask = PLL_STATUS0_GPUPLLLOCK,
+ .initial_rate = 800 * 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,
+ }),
+ },
+ {
+ .name = "SYS_PLL",
+ .data = &((struct mod_system_pll_dev_config) {
+ .control_reg = (void *)PLL_SYSTEM,
+ .status_reg = (void *)&PIK_SCP->PLL_STATUS0,
+ .lock_flag_mask = PLL_STATUS0_SYSPLLLOCK,
+ .initial_rate = 3600 * 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,
+ }),
+ },
+ { 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/sgm776/scp_romfw/config_timer.c b/product/sgm776/scp_romfw/config_timer.c
new file mode 100644
index 00000000..62d2d523
--- /dev/null
+++ b/product/sgm776/scp_romfw/config_timer.c
@@ -0,0 +1,68 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <mod_clock.h>
+#include <mod_gtimer.h>
+#include <mod_timer.h>
+#include <sgm776_mmap.h>
+#include <clock_devices.h>
+#include <system_clock.h>
+
+/*
+ * Generic timer driver config
+ */
+static const struct fwk_element gtimer_dev_table[] = {
+ [0] = {
+ .name = "REFCLK",
+ .data = &((struct mod_gtimer_dev_config) {
+ .hw_timer = REFCLK_CNTBASE0_BASE,
+ .hw_counter = REFCLK_CNTCTL_BASE,
+ .control = REFCLK_CNTCONTROL_BASE,
+ .frequency = CLOCK_RATE_REFCLK,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_DEV_IDX_SYS_NOCMEMCLK),
+ })
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *gtimer_get_dev_table(fwk_id_t module_id)
+{
+ return gtimer_dev_table;
+}
+
+struct fwk_module_config config_gtimer = {
+ .get_element_table = gtimer_get_dev_table,
+};
+
+/*
+ * Timer HAL config
+ */
+static const struct mod_timer_dev_config refclk_config = {
+ .id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_GTIMER, 0),
+};
+
+static const struct fwk_element timer_dev_table[] = {
+ [0] = {
+ .name = "REFCLK",
+ .data = &refclk_config,
+ },
+ [1] = { 0 },
+};
+
+static const struct fwk_element *timer_get_dev_table(fwk_id_t module_id)
+{
+ return timer_dev_table;
+}
+
+struct fwk_module_config config_timer = {
+ .get_element_table = timer_get_dev_table,
+};
diff --git a/product/sgm776/scp_romfw/firmware.mk b/product/sgm776/scp_romfw/firmware.mk
new file mode 100644
index 00000000..8ab120c7
--- /dev/null
+++ b/product/sgm776/scp_romfw/firmware.mk
@@ -0,0 +1,45 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_FIRMWARE_CPU := cortex-m3
+BS_FIRMWARE_HAS_MULTITHREADING := no
+BS_FIRMWARE_HAS_NOTIFICATION := yes
+
+BS_FIRMWARE_MODULE_HEADERS_ONLY := \
+ power_domain \
+ timer
+
+BS_FIRMWARE_MODULES := \
+ sid \
+ pcid \
+ ppu_v1 \
+ pl011 \
+ log \
+ gtimer \
+ msys_rom \
+ sds \
+ bootloader \
+ system_pll \
+ pik_clock \
+ css_clock \
+ clock
+
+BS_FIRMWARE_SOURCES := \
+ sgm776_core.c \
+ config_log.c \
+ config_timer.c \
+ config_msys_rom.c \
+ config_sds.c \
+ config_bootloader.c \
+ config_ppu_v1.c \
+ config_system_pll.c \
+ config_pik_clock.c \
+ config_css_clock.c \
+ config_clock.c \
+ config_sid.c
+
+include $(BS_DIR)/firmware.mk
diff --git a/product/sgm776/scp_romfw/fmw_memory.ld.S b/product/sgm776/scp_romfw/fmw_memory.ld.S
new file mode 100644
index 00000000..07b5ffe8
--- /dev/null
+++ b/product/sgm776/scp_romfw/fmw_memory.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-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_LD_S
+#define FMW_MEMORY_LD_S
+
+#include <system_mmap_scp.h>
+
+#define FIRMWARE_MEM_MODE FWK_MEM_MODE_DUAL_REGION_RELOCATION
+
+/*
+ * ROM memory
+ */
+#define FIRMWARE_MEM0_SIZE SCP_ROM_SIZE
+#define FIRMWARE_MEM0_BASE SCP_ROM_BASE
+
+/*
+ * RAM memory (16 KiB block at the top of the RAM)
+ *
+ * Note: The sections that must go into the RAM memory (i.e. stack, heap, bss
+ * and data) are placed at the end of the RAM memory to avoid being overwritten
+ * by the bootloader when loading the RAM firmware image.
+ */
+#define FIRMWARE_MEM1_SIZE (16 * 1024)
+#define FIRMWARE_MEM1_BASE (SCP_RAM_BASE + SCP_RAM_SIZE - FIRMWARE_MEM1_SIZE)
+
+#define FIRMWARE_STACK_SIZE (1 * 1024)
+
+#endif /* FMW_MEMORY_LD_S */
diff --git a/product/sgm776/src/config_sid.c b/product/sgm776/src/config_sid.c
new file mode 100644
index 00000000..8cd12d71
--- /dev/null
+++ b/product/sgm776/src/config_sid.c
@@ -0,0 +1,50 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_element.h>
+#include <fwk_module.h>
+#include <mod_sid.h>
+#include <sgm776_mmap.h>
+#include <sgm776_sid.h>
+
+static const struct fwk_element subsystem_table[] = {
+ {
+ .name = "Duke",
+ .data = &(struct mod_sid_subsystem_config) {
+ .part_number = SGM776_SID_PART_DUKE,
+ }
+ },
+ {
+ .name = "Davis",
+ .data = &(struct mod_sid_subsystem_config) {
+ .part_number = SGM776_SID_PART_DAVIS,
+ }
+ },
+ { 0 },
+};
+
+static const struct fwk_element *get_subsystem_table(fwk_id_t id)
+{
+ return subsystem_table;
+}
+
+struct fwk_module_config config_sid = {
+ .get_element_table = get_subsystem_table,
+ .data = &(struct mod_sid_config) {
+ .sid_base = SID_BASE,
+ .pcid_expected = {
+ .PID0 = 0xB9,
+ .PID1 = 0xB0,
+ .PID2 = 0x0B,
+ .PID4 = 0x04,
+ .CID0 = 0x0D,
+ .CID1 = 0xF0,
+ .CID2 = 0x05,
+ .CID3 = 0xB1,
+ },
+ },
+};
diff --git a/product/sgm776/src/sgm776_core.c b/product/sgm776/src/sgm776_core.c
new file mode 100644
index 00000000..d78df954
--- /dev/null
+++ b/product/sgm776/src/sgm776_core.c
@@ -0,0 +1,14 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sgm776_pik.h>
+#include <sgm776_core.h>
+
+unsigned int sgm776_core_get_count(void)
+{
+ return (PIK_CLUS0->PCL_CONFIG & PIK_CPU_PCL_CONFIG_NO_OF_PPU) - 1;
+}
diff --git a/tools/ci.py b/tools/ci.py
index b61e80c6..ed359da6 100755
--- a/tools/ci.py
+++ b/tools/ci.py
@@ -297,6 +297,40 @@ def main():
result = subprocess.call(cmd, shell=True)
results.append(('Product synquacer debug build (ARM)', result))
+ banner('Test building sgm776 product')
+
+ cmd = \
+ 'CC=arm-none-eabi-gcc ' \
+ 'PRODUCT=sgm776 ' \
+ 'MODE=release ' \
+ 'make clean all'
+ result = subprocess.call(cmd, shell=True)
+ results.append(('Product sgm776 release build (GCC)', result))
+
+ cmd = \
+ 'CC=armclang ' \
+ 'PRODUCT=sgm776 ' \
+ 'MODE=release ' \
+ 'make clean all'
+ result = subprocess.call(cmd, shell=True)
+ results.append(('Product sgm776 release build (ARM)', result))
+
+ cmd = \
+ 'CC=arm-none-eabi-gcc ' \
+ 'PRODUCT=sgm776 ' \
+ 'MODE=debug ' \
+ 'make clean all'
+ result = subprocess.call(cmd, shell=True)
+ results.append(('Product sgm776 debug build (GCC)', result))
+
+ cmd = \
+ 'CC=armclang ' \
+ 'PRODUCT=sgm776 ' \
+ 'MODE=debug ' \
+ 'make clean all'
+ result = subprocess.call(cmd, shell=True)
+ results.append(('Product sgm776 debug build (ARM)', result))
+
banner('Tests summary')
total_success = 0