aboutsummaryrefslogtreecommitdiff
path: root/product/morello
diff options
context:
space:
mode:
authorAnurag Koul <anurag.koul@arm.com>2020-06-08 03:12:32 +0100
committerjimqui01 <54316584+jimqui01@users.noreply.github.com>2020-09-15 17:03:53 +0100
commit11b0e16e19ff2d9ae54530cd3c868d922ab5a9f3 (patch)
tree116b1a02ae55b6d5363973ab8709714bbad2e66a /product/morello
parentee56f02cadf70726b2f2e869485a7b1bd2cec48e (diff)
morello/module: add dmc_bing module and config data
Add DMC Bing module for Morello DDR memory controller. There generally is no DDR PHY modelled in FVP environments, and as such, ramfw for Morello FVP lacks any config data/file for DDR PHY. Change-Id: I8723505c20b2d75831ade517a276b50b473b4393 Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Diffstat (limited to 'product/morello')
-rw-r--r--product/morello/module/dmc_bing/include/mod_dmc_bing.h673
-rw-r--r--product/morello/module/dmc_bing/src/Makefile11
-rw-r--r--product/morello/module/dmc_bing/src/mod_dmc_bing.c290
-rw-r--r--product/morello/scp_ramfw_fvp/config_dmc_bing.c223
4 files changed, 1197 insertions, 0 deletions
diff --git a/product/morello/module/dmc_bing/include/mod_dmc_bing.h b/product/morello/module/dmc_bing/include/mod_dmc_bing.h
new file mode 100644
index 00000000..58888063
--- /dev/null
+++ b/product/morello/module/dmc_bing/include/mod_dmc_bing.h
@@ -0,0 +1,673 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * DMC-BING module.
+ */
+
+#ifndef MOD_DMC_BING_H
+#define MOD_DMC_BING_H
+
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+
+#include <stdint.h>
+
+/*!
+ * \addtogroup GroupModules Modules
+ * @{
+ */
+
+/*!
+ * \addtogroup GroupDMC_BING DMC-BING Driver
+ *
+ * \details Please consult the Arm CoreLink DMC-BING Dynamic Memory Controller
+ * Technical Reference Manual for details on the specific registers that
+ * are programmed here.
+ *
+ * \sa
+ * https://developer.arm.com/docs/100568/latest/programmers-model/register-summary
+ * @{
+ */
+
+/*!
+ * \brief Number of access addresses
+ */
+#define MOD_DMC_BING_ACCESS_ADDRESS_COUNT 8
+
+/*!
+ * \brief Access address next registers
+ */
+struct mod_dmc_bing_access_address_next {
+ /*!
+ * \cond
+ * @{
+ */
+ FWK_RW uint32_t MIN_31_00;
+ FWK_RW uint32_t MIN_43_32;
+ FWK_RW uint32_t MAX_31_00;
+ FWK_RW uint32_t MAX_43_32;
+ /*!
+ * \endcond
+ * @}
+ */
+};
+
+/*!
+ * \brief Access address next registers
+ */
+struct mod_dmc_bing_access_address_now {
+ /*!
+ * \cond
+ * @{
+ */
+ FWK_R uint32_t MIN_31_00;
+ FWK_R uint32_t MIN_43_32;
+ FWK_R uint32_t MAX_31_00;
+ FWK_R uint32_t MAX_43_32;
+ /*!
+ * \endcond
+ * @}
+ */
+};
+
+/*!
+ * \brief PMU payload information operation register
+ */
+struct mod_dmc_bing_pmu_counter {
+ /*!
+ * \cond
+ * @{
+ */
+ FWK_RW uint32_t MASK_31_00;
+ FWK_RW uint32_t MASK_63_32;
+ FWK_RW uint32_t MATCH_31_00;
+ FWK_RW uint32_t MATCH_63_32;
+ FWK_RW uint32_t CONTROL;
+ uint32_t RESERVED0;
+ FWK_R uint32_t SNAPSHOT_VALUE_31_00;
+ uint32_t RESERVED1;
+ FWK_RW uint32_t VALUE_31_00;
+ uint32_t RESERVED2;
+ /*!
+ * \endcond
+ * @}
+ */
+};
+
+/*!
+ * \brief DMC-BING register definitions
+ */
+struct mod_dmc_bing_reg {
+ /*!
+ * \cond
+ * @{
+ */
+ FWK_R uint32_t MEMC_STATUS;
+ FWK_R uint32_t MEMC_CONFIG;
+ FWK_W uint32_t MEMC_CMD;
+ uint32_t RESERVED1;
+ FWK_RW uint32_t ADDRESS_CONTROL_NEXT;
+ FWK_RW uint32_t DECODE_CONTROL_NEXT;
+ FWK_RW uint32_t FORMAT_CONTROL;
+ FWK_RW uint32_t ADDRESS_MAP_NEXT;
+ FWK_RW uint32_t LOW_POWER_CONTROL_NEXT;
+ uint32_t RESERVED2;
+ FWK_RW uint32_t TURNAROUND_CONTROL_NEXT;
+ FWK_RW uint32_t HIT_TURNAROUND_CONTROL_NEXT;
+ FWK_RW uint32_t QOS_CLASS_CONTROL_NEXT;
+ FWK_RW uint32_t ESCALATION_CONTROL_NEXT;
+ FWK_RW uint32_t QV_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t QV_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t RT_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t RT_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t TIMEOUT_CONTROL_NEXT;
+ FWK_RW uint32_t CREDIT_CONTROL_NEXT;
+ FWK_RW uint32_t WRITE_PRIORITY_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t WRITE_PRIORITY_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t QUEUE_THRESHOLD_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_31_00_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_63_32_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_95_64_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_127_96_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_159_128_NEXT;
+ FWK_RW uint32_t ADDRESS_SHUTTER_191_160_NEXT;
+ FWK_RW uint32_t MEMORY_ADDRESS_MAX_31_00_NEXT;
+ FWK_RW uint32_t MEMORY_ADDRESS_MAX_43_32_NEXT;
+ struct mod_dmc_bing_access_address_next
+ ACCESS_ADDRESS_NEXT[MOD_DMC_BING_ACCESS_ADDRESS_COUNT];
+ FWK_R uint32_t CHANNEL_STATUS;
+ FWK_R uint32_t CHANNEL_STATUS_63_32;
+ FWK_RW uint32_t DIRECT_ADDR;
+ FWK_W uint32_t DIRECT_CMD;
+ FWK_RW uint32_t DCI_REPLAY_TYPE_NEXT;
+ FWK_RW uint32_t DIRECT_CONTROL_NEXT;
+ FWK_RW uint32_t DCI_STRB;
+ FWK_RW uint32_t DCI_DATA;
+ FWK_RW uint32_t REFRESH_CONTROL_NEXT;
+ uint32_t RESERVED3;
+ FWK_RW uint32_t MEMORY_TYPE_NEXT;
+ uint32_t RESERVED4;
+ FWK_RW uint32_t FEATURE_CONFIG;
+ uint32_t RESERVED5;
+ FWK_RW uint32_t NIBBLE_FAILED_031_000;
+ FWK_RW uint32_t NIBBLE_FAILED_063_032;
+ FWK_RW uint32_t NIBBLE_FAILED_095_064;
+ FWK_RW uint32_t NIBBLE_FAILED_127_096;
+ FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_031_000;
+ FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_063_032;
+ FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_095_064;
+ FWK_RW uint32_t QUEUE_ALLOCATE_CONTROL_127_096;
+ uint8_t RESERVED6[0x16C - 0x158];
+ FWK_RW uint32_t LINK_ERR_COUNT;
+ FWK_RW uint32_t SCRUB_CONTROL0_NEXT;
+ FWK_RW uint32_t SCRUB_ADDRESS_MIN0_NEXT;
+ FWK_RW uint32_t SCRUB_ADDRESS_MAX0_NEXT;
+ FWK_R uint32_t SCRUB_ADDRESS_CURRENT0;
+ FWK_RW uint32_t SCRUB_CONTROL1_NEXT;
+ FWK_RW uint32_t SCRUB_ADDRESS_MIN1_NEXT;
+ FWK_RW uint32_t SCRUB_ADDRESS_MAX1_NEXT;
+ FWK_R uint32_t SCRUB_ADDRESS_CURRENT1;
+ uint8_t RESERVED7[0x1A0 - 0x190];
+ FWK_RW uint32_t CS_REMAP_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t CS_REMAP_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t CS_REMAP_CONTROL_95_64_NEXT;
+ FWK_RW uint32_t CS_REMAP_CONTROL_127_96_NEXT;
+ FWK_RW uint32_t CID_REMAP_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t CID_REMAP_CONTROL_63_32_NEXT;
+ uint8_t RESERVED8[0x1C0 - 0x1B8];
+ FWK_RW uint32_t CKE_REMAP_CONTROL_NEXT;
+ FWK_RW uint32_t RST_REMAP_CONTROL_NEXT;
+ FWK_RW uint32_t CK_REMAP_CONTROL_NEXT;
+ uint32_t RESERVED9;
+ FWK_RW uint32_t POWER_GROUP_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t POWER_GROUP_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t POWER_GROUP_CONTROL_95_64_NEXT;
+ FWK_RW uint32_t POWER_GROUP_CONTROL_127_96_NEXT;
+ FWK_RW uint32_t PHY_RDWRDATA_CS_MASK_31_00;
+ FWK_RW uint32_t PHY_RDWRDATA_CS_MASK_63_32;
+ FWK_RW uint32_t PHY_REQUEST_CS_REMAP;
+ uint32_t RESERVED10;
+ FWK_RW uint32_t FEATURE_CONTROL_NEXT;
+ FWK_RW uint32_t MUX_CONTROL_NEXT;
+ FWK_RW uint32_t RANK_REMAP_CONTROL_NEXT;
+ uint32_t RESERVED11;
+ FWK_RW uint32_t T_REFI_NEXT;
+ FWK_RW uint32_t T_RFC_NEXT;
+ FWK_RW uint32_t T_MRR_NEXT;
+ FWK_RW uint32_t T_MRW_NEXT;
+ uint8_t RESERVED12[0x218 - 0x210];
+ FWK_RW uint32_t T_RCD_NEXT;
+ FWK_RW uint32_t T_RAS_NEXT;
+ FWK_RW uint32_t T_RP_NEXT;
+ FWK_RW uint32_t T_RPALL_NEXT;
+ FWK_RW uint32_t T_RRD_NEXT;
+ FWK_RW uint32_t T_ACT_WINDOW_NEXT;
+ uint32_t RESERVED13;
+ FWK_RW uint32_t T_RTR_NEXT;
+ FWK_RW uint32_t T_RTW_NEXT;
+ FWK_RW uint32_t T_RTP_NEXT;
+ uint32_t RESERVED14;
+ FWK_RW uint32_t T_WR_NEXT;
+ FWK_RW uint32_t T_WTR_NEXT;
+ FWK_RW uint32_t T_WTW_NEXT;
+ uint32_t RESERVED15;
+ FWK_RW uint32_t T_XMPD_NEXT;
+ FWK_RW uint32_t T_EP_NEXT;
+ FWK_RW uint32_t T_XP_NEXT;
+ FWK_RW uint32_t T_ESR_NEXT;
+ FWK_RW uint32_t T_XSR_NEXT;
+ FWK_RW uint32_t T_ESRCK_NEXT;
+ FWK_RW uint32_t T_CKXSR_NEXT;
+ FWK_RW uint32_t T_CMD_NEXT;
+ FWK_RW uint32_t T_PARITY_NEXT;
+ FWK_RW uint32_t T_ZQCS_NEXT;
+ FWK_RW uint32_t T_RW_ODT_CLR_NEXT;
+ uint8_t RESERVED16[0x300 - 0x280];
+ FWK_RW uint32_t T_RDDATA_EN_NEXT;
+ FWK_RW uint32_t T_PHYRDLAT_NEXT;
+ FWK_RW uint32_t T_PHYWRLAT_NEXT;
+ uint32_t RESERVED17;
+ FWK_RW uint32_t RDLVL_CONTROL_NEXT;
+ FWK_RW uint32_t RDLVL_MRS_NEXT;
+ FWK_RW uint32_t T_RDLVL_EN_NEXT;
+ FWK_RW uint32_t T_RDLVL_RR_NEXT;
+ FWK_RW uint32_t WRLVL_CONTROL_NEXT;
+ FWK_RW uint32_t WRLVL_MRS_NEXT;
+ FWK_RW uint32_t T_WRLVL_EN_NEXT;
+ FWK_RW uint32_t T_WRLVL_WW_NEXT;
+ uint32_t RESERVED18;
+ FWK_R uint32_t TRAINING_WRLVL_SLICE_STATUS;
+ FWK_R uint32_t TRAINING_RDLVL_SLICE_STATUS;
+ FWK_R uint32_t TRAINING_RDLVL_GATE_SLICE_STATUS;
+ FWK_R uint32_t TRAINING_WDQLVL_SLICE_STATUS;
+ FWK_R uint32_t TRAINING_WDQLVL_SLICE_RESULT;
+ FWK_RW uint32_t PHY_POWER_CONTROL_NEXT;
+ FWK_RW uint32_t T_LPRESP_NEXT;
+ FWK_RW uint32_t PHY_UPDATE_CONTROL_NEXT;
+ FWK_RW uint32_t T_ODTH_NEXT;
+ FWK_RW uint32_t ODT_TIMING_NEXT;
+ uint32_t RESERVED19;
+ FWK_RW uint32_t ODT_WR_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t ODT_WR_CONTROL_63_32_NEXT;
+ FWK_RW uint32_t ODT_RD_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t ODT_RD_CONTROL_63_32_NEXT;
+ FWK_R uint32_t TEMPERATURE_READOUT;
+ uint32_t RESERVED20;
+ FWK_R uint32_t TRAINING_STATUS;
+ FWK_R uint32_t TRAINING_STATUS_63_32;
+ FWK_RW uint32_t DQ_MAP_CONTROL_15_00_NEXT;
+ FWK_RW uint32_t DQ_MAP_CONTROL_31_16_NEXT;
+ FWK_RW uint32_t DQ_MAP_CONTROL_47_32_NEXT;
+ FWK_RW uint32_t DQ_MAP_CONTROL_63_48_NEXT;
+ FWK_RW uint32_t DQ_MAP_CONTROL_71_64_NEXT;
+ uint32_t RESERVED21;
+ FWK_R uint32_t RANK_STATUS;
+ FWK_R uint32_t MODE_CHANGE_STATUS;
+ uint8_t RESERVED22[0x3B0 - 0x3A0];
+ FWK_RW uint32_t ODT_CP_CONTROL_31_00_NEXT;
+ FWK_RW uint32_t ODT_CP_CONTROL_63_32_NEXT;
+ uint8_t RESERVED23[0x400 - 0x3B8];
+ FWK_R uint32_t USER_STATUS;
+ uint32_t RESERVED24;
+ FWK_RW uint32_t USER_CONFIG0_NEXT;
+ FWK_RW uint32_t USER_CONFIG1_NEXT;
+ FWK_RW uint32_t USER_CONFIG2;
+ FWK_RW uint32_t USER_CONFIG3;
+ uint8_t RESERVED25[0x500 - 0x418];
+ FWK_RW uint32_t INTERRUPT_CONTROL;
+ uint32_t RESERVED26;
+ FWK_W uint32_t INTERRUPT_CLR;
+ uint32_t RESERVED27;
+ FWK_R uint32_t INTERRUPT_STATUS;
+ uint8_t RESERVED28[0x538 - 0x514];
+ FWK_R uint32_t FAILED_ACCESS_INT_INFO_31_00;
+ FWK_R uint32_t FAILED_ACCESS_INT_INFO_63_32;
+ FWK_R uint32_t FAILED_PROG_INT_INFO_31_00;
+ FWK_R uint32_t FAILED_PROG_INT_INFO_63_32;
+ FWK_R uint32_t LINK_ERR_INT_INFO_31_00;
+ FWK_R uint32_t LINK_ERR_INT_INFO_63_32;
+ FWK_R uint32_t ARCH_FSM_INT_INFO_31_00;
+ FWK_R uint32_t ARCH_FSM_INT_INFO_63_32;
+ uint8_t RESERVED29[0x610 - 0x558];
+ FWK_RW uint32_t T_DB_TRAIN_RESP_NEXT;
+ FWK_RW uint32_t T_LVL_DISCONNECT_NEXT;
+ uint8_t RESERVED30[0x620 - 0x618];
+ FWK_RW uint32_t WDQLVL_CONTROL_NEXT;
+ FWK_RW uint32_t WDQLVL_VREFDQ_TRAIN_MRS_NEXT;
+ FWK_RW uint32_t WDQLVL_ADDRESS_31_00_NEXT;
+ FWK_RW uint32_t WDQLVL_ADDRESS_63_32_NEXT;
+ FWK_RW uint32_t T_WDQLVL_EN_NEXT;
+ FWK_RW uint32_t T_WDQLVL_WW_NEXT;
+ FWK_RW uint32_t T_WDQLVL_RW_NEXT;
+ FWK_R uint32_t TRAINING_WDQLVL_SLICE_RESP;
+ FWK_R uint32_t TRAINING_RDLVL_SLICE_RESP;
+ uint8_t RESERVED31[0x654 - 0x644];
+ FWK_RW uint32_t PHYMSTR_CONTROL_NEXT;
+ uint8_t RESERVED32[0x700 - 0x658];
+ FWK_R uint32_t ERR0FR;
+ uint32_t RESERVED33;
+ FWK_RW uint32_t ERR0CTLR0;
+ FWK_RW uint32_t ERR0CTLR1;
+ FWK_R uint32_t ERR0STATUS;
+ uint8_t RESERVED34[0x740 - 0x714];
+ FWK_R uint32_t ERR1FR;
+ uint32_t RESERVED35;
+ FWK_R uint32_t ERR1CTLR;
+ uint32_t RESERVED36;
+ FWK_R uint32_t ERR1STATUS;
+ uint32_t RESERVED37;
+ FWK_RW uint32_t ERR1ADDR0;
+ FWK_RW uint32_t ERR1ADDR1;
+ FWK_RW uint32_t ERR1MISC0;
+ FWK_RW uint32_t ERR1MISC1;
+ FWK_RW uint32_t ERR1MISC2;
+ FWK_RW uint32_t ERR1MISC3;
+ FWK_RW uint32_t ERR1MISC4;
+ FWK_RW uint32_t ERR1MISC5;
+ uint8_t RESERVED38[0x780 - 0x778];
+ FWK_R uint32_t ERR2FR;
+ uint32_t RESERVED39;
+ FWK_R uint32_t ERR2CTLR;
+ uint32_t RESERVED40;
+ FWK_R uint32_t ERR2STATUS;
+ uint32_t RESERVED41;
+ FWK_RW uint32_t ERR2ADDR0;
+ FWK_RW uint32_t ERR2ADDR1;
+ FWK_RW uint32_t ERR2MISC0;
+ FWK_RW uint32_t ERR2MISC1;
+ FWK_RW uint32_t ERR2MISC2;
+ FWK_RW uint32_t ERR2MISC3;
+ FWK_RW uint32_t ERR2MISC4;
+ FWK_RW uint32_t ERR2MISC5;
+ uint8_t RESERVED42[0x7C0 - 0x7B8];
+ FWK_R uint32_t ERR3FR;
+ uint32_t RESERVED43;
+ FWK_R uint32_t ERR3CTLR;
+ uint32_t RESERVED44;
+ FWK_R uint32_t ERR3STATUS;
+ uint32_t RESERVED45;
+ FWK_RW uint32_t ERR3ADDR0;
+ FWK_RW uint32_t ERR3ADDR1;
+ uint8_t RESERVED46[0x800 - 0x7E0];
+ FWK_R uint32_t ERR4FR;
+ uint32_t RESERVED47;
+ FWK_R uint32_t ERR4CTLR;
+ uint32_t RESERVED48;
+ FWK_R uint32_t ERR4STATUS;
+ uint32_t RESERVED49;
+ FWK_RW uint32_t ERR4ADDR0;
+ FWK_RW uint32_t ERR4ADDR1;
+ FWK_RW uint32_t ERR4MISC0;
+ FWK_RW uint32_t ERR4MISC1;
+ FWK_RW uint32_t ERR4MISC2;
+ uint8_t RESERVED50[0x840 - 0x82C];
+ FWK_R uint32_t ERR5FR;
+ uint32_t RESERVED51;
+ FWK_R uint32_t ERR5CTLR;
+ uint32_t RESERVED52;
+ FWK_R uint32_t ERR5STATUS;
+ uint32_t RESERVED53;
+ FWK_RW uint32_t ERR5ADDR0;
+ FWK_RW uint32_t ERR5ADDR1;
+ FWK_RW uint32_t ERR5MISC0;
+ FWK_RW uint32_t ERR5MISC1;
+ FWK_RW uint32_t ERR5MISC2;
+ uint8_t RESERVED54[0x880 - 0x86C];
+ FWK_R uint32_t ERR6FR;
+ uint32_t RESERVED55;
+ FWK_R uint32_t ERR6CTLR;
+ uint32_t RESERVED56;
+ FWK_R uint32_t ERR6STATUS;
+ uint32_t RESERVED57;
+ FWK_RW uint32_t ERR6ADDR0;
+ FWK_RW uint32_t ERR6ADDR1;
+ FWK_RW uint32_t ERR6MISC0;
+ FWK_RW uint32_t ERR6MISC1;
+ uint8_t RESERVED58[0x920 - 0x8A8];
+ FWK_RW uint32_t ERRGSR;
+ uint8_t RESERVED59[0xA00 - 0x924];
+ FWK_W uint32_t PMU_SNAPSHOT_REQ;
+ FWK_R uint32_t PMU_SNAPSHOT_ACK;
+ FWK_RW uint32_t PMU_OVERFLOW_STATUS_CLKDIV2;
+ FWK_RW uint32_t PMU_OVERFLOW_STATUS_CLK;
+ struct mod_dmc_bing_pmu_counter PMC_CLKDIV2_COUNT[8];
+ struct mod_dmc_bing_pmu_counter PMC_CLK_COUNT[2];
+ uint8_t RESERVED60[0xE00 - 0xBA0];
+ FWK_RW uint32_t INTEG_CFG;
+ uint32_t RESERVED61;
+ FWK_W uint32_t INTEG_OUTPUTS;
+ uint8_t RESERVED62[0x1010 - 0xE0C];
+ FWK_R uint32_t ADDRESS_CONTROL_NOW;
+ FWK_R uint32_t DECODE_CONTROL_NOW;
+ uint32_t RESERVED63;
+ FWK_R uint32_t ADDRESS_MAP_NOW;
+ FWK_R uint32_t LOW_POWER_CONTROL_NOW;
+ uint32_t RESERVED64;
+ FWK_R uint32_t TURNAROUND_CONTROL_NOW;
+ FWK_R uint32_t HIT_TURNAROUND_CONTROL_NOW;
+ FWK_R uint32_t QOS_CLASS_CONTROL_NOW;
+ FWK_R uint32_t ESCALATION_CONTROL_NOW;
+ FWK_R uint32_t QV_CONTROL_31_00_NOW;
+ FWK_R uint32_t QV_CONTROL_63_32_NOW;
+ FWK_R uint32_t RT_CONTROL_31_00_NOW;
+ FWK_R uint32_t RT_CONTROL_63_32_NOW;
+ FWK_R uint32_t TIMEOUT_CONTROL_NOW;
+ FWK_R uint32_t CREDIT_CONTROL_NOW;
+ FWK_R uint32_t WRITE_PRIORITY_CONTROL_31_00_NOW;
+ FWK_R uint32_t WRITE_PRIORITY_CONTROL_63_32_NOW;
+ FWK_R uint32_t QUEUE_THRESHOLD_CONTROL_31_00_NOW;
+ FWK_R uint32_t QUEUE_THRESHOLD_CONTROL_63_32_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_31_00_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_63_32_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_95_64_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_127_96_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_159_128_NOW;
+ FWK_R uint32_t ADDRESS_SHUTTER_191_160_NOW;
+ FWK_R uint32_t MEMORY_ADDRESS_MAX_31_00_NOW;
+ FWK_R uint32_t MEMORY_ADDRESS_MAX_43_32_NOW;
+ struct mod_dmc_bing_access_address_now
+ ACCESS_ADDRESS_NOW[MOD_DMC_BING_ACCESS_ADDRESS_COUNT];
+ uint8_t RESERVED65[0x1110 - 0x1100];
+ FWK_R uint32_t DCI_REPLAY_TYPE_NOW;
+ FWK_R uint32_t DIRECT_CONTROL_NOW;
+ uint8_t RESERVED66[0x1120 - 0x1118];
+ FWK_R uint32_t REFRESH_CONTROL_NOW;
+ uint32_t RESERVED67;
+ FWK_R uint32_t MEMORY_TYPE_NOW;
+ uint8_t RESERVED68[0x1170 - 0x112C];
+ FWK_R uint32_t SCRUB_CONTROL0_NOW;
+ FWK_R uint32_t SCRUB_ADDRESS_MIN0_NOW;
+ FWK_R uint32_t SCRUB_ADDRESS_MAX0_NOW;
+ uint32_t RESERVED69;
+ FWK_R uint32_t SCRUB_CONTROL1_NOW;
+ FWK_R uint32_t SCRUB_ADDRESS_MIN1_NOW;
+ FWK_R uint32_t SCRUB_ADDRESS_MAX1_NOW;
+ uint8_t RESERVED70[0x11A0 - 0x118C];
+ FWK_R uint32_t CS_REMAP_CONTROL_31_00_NOW;
+ FWK_R uint32_t CS_REMAP_CONTROL_63_32_NOW;
+ FWK_R uint32_t CS_REMAP_CONTROL_95_64_NOW;
+ FWK_R uint32_t CS_REMAP_CONTROL_127_96_NOW;
+ FWK_R uint32_t CID_REMAP_CONTROL_31_00_NOW;
+ FWK_R uint32_t CID_REMAP_CONTROL_63_32_NOW;
+ uint8_t RESERVED71[0x11C0 - 0x11B8];
+ FWK_R uint32_t CKE_REMAP_CONTROL_31_00_NOW;
+ FWK_R uint32_t RST_REMAP_CONTROL_31_00_NOW;
+ FWK_R uint32_t CK_REMAP_CONTROL_31_00_NOW;
+ FWK_R uint32_t POWER_GROUP_CONTROL_31_00_NOW;
+ FWK_R uint32_t POWER_GROUP_CONTROL_63_32_NOW;
+ FWK_R uint32_t POWER_GROUP_CONTROL_95_64_NOW;
+ FWK_R uint32_t POWER_GROUP_CONTROL_127_96_NOW;
+ uint8_t RESERVED72[0x11F0 - 0x11E0];
+ FWK_R uint32_t FEATURE_CONTROL_NOW;
+ FWK_R uint32_t MUX_CONTROL_NOW;
+ FWK_R uint32_t RANK_REMAP_CONTROL_NOW;
+ uint32_t RESERVED73;
+ FWK_R uint32_t T_REFI_NOW;
+ FWK_R uint32_t T_RFC_NOW;
+ FWK_R uint32_t T_MRR_NOW;
+ FWK_R uint32_t T_MRW_NOW;
+ uint8_t RESERVED74[0x1218 - 0x1210];
+ FWK_R uint32_t T_RCD_NOW;
+ FWK_R uint32_t T_RAS_NOW;
+ FWK_R uint32_t T_RP_NOW;
+ FWK_R uint32_t T_RPALL_NOW;
+ FWK_R uint32_t T_RRD_NOW;
+ FWK_R uint32_t T_ACT_WINDOW_NOW;
+ uint32_t RESERVED75;
+ FWK_R uint32_t T_RTR_NOW;
+ FWK_R uint32_t T_RTW_NOW;
+ FWK_R uint32_t T_RTP_NOW;
+ uint32_t RESERVED76;
+ FWK_R uint32_t T_WR_NOW;
+ FWK_R uint32_t T_WTR_NOW;
+ FWK_R uint32_t T_WTW_NOW;
+ uint32_t RESERVED77;
+ FWK_R uint32_t T_XMPD_NOW;
+ FWK_R uint32_t T_EP_NOW;
+ FWK_R uint32_t T_XP_NOW;
+ FWK_R uint32_t T_ESR_NOW;
+ FWK_R uint32_t T_XSR_NOW;
+ FWK_R uint32_t T_ESRCK_NOW;
+ FWK_R uint32_t T_CKXSR_NOW;
+ FWK_R uint32_t T_CMD_NOW;
+ FWK_R uint32_t T_PARITY_NOW;
+ FWK_R uint32_t T_ZQCS_NOW;
+ FWK_R uint32_t T_RW_ODT_CLR_NOW;
+ uint8_t RESERVED78[0x1300 - 0x1280];
+ FWK_R uint32_t T_RDDATA_EN_NOW;
+ FWK_R uint32_t T_PHYRDLAT_NOW;
+ FWK_R uint32_t T_PHYWRLAT_NOW;
+ uint32_t RESERVED79;
+ FWK_R uint32_t RDLVL_CONTROL_NOW;
+ FWK_R uint32_t RDLVL_MRS_NOW;
+ FWK_R uint32_t T_RDLVL_EN_NOW;
+ FWK_R uint32_t T_RDLVL_RR_NOW;
+ FWK_R uint32_t WRLVL_CONTROL_NOW;
+ FWK_R uint32_t WRLVL_MRS_NOW;
+ FWK_R uint32_t T_WRLVL_EN_NOW;
+ FWK_R uint32_t T_WRLVL_WW_NOW;
+ uint8_t RESERVED80[0x1348 - 0x1330];
+ FWK_R uint32_t PHY_POWER_CONTROL_NOW;
+ FWK_R uint32_t T_LPRESP_NOW;
+ FWK_R uint32_t PHY_UPDATE_CONTROL_NOW;
+ FWK_R uint32_t T_ODTH_NOW;
+ FWK_R uint32_t ODT_TIMING_NOW;
+ uint32_t RESERVED81;
+ FWK_R uint32_t ODT_WR_CONTROL_31_00_NOW;
+ FWK_R uint32_t ODT_WR_CONTROL_63_32_NOW;
+ FWK_R uint32_t ODT_RD_CONTROL_31_00_NOW;
+ FWK_R uint32_t ODT_RD_CONTROL_63_32_NOW;
+ uint8_t RESERVED82[0x1380 - 0x1370];
+ FWK_R uint32_t DQ_MAP_CONTROL_15_00_NOW;
+ FWK_R uint32_t DQ_MAP_CONTROL_31_16_NOW;
+ FWK_R uint32_t DQ_MAP_CONTROL_47_32_NOW;
+ FWK_R uint32_t DQ_MAP_CONTROL_63_48_NOW;
+ FWK_R uint32_t DQ_MAP_CONTROL_71_64_NOW;
+ uint8_t RESERVED83[0x13B0 - 0x1394];
+ FWK_R uint32_t ODT_CP_CONTROL_31_00_NOW;
+ FWK_R uint32_t ODT_CP_CONTROL_63_32_NOW;
+ uint8_t RESERVED84[0x1408 - 0x13B8];
+ FWK_R uint32_t USER_CONFIG0_NOW;
+ FWK_R uint32_t USER_CONFIG1_NOW;
+ uint8_t RESERVED85[0x1610 - 0x1410];
+ FWK_R uint32_t T_DB_TRAIN_RESP_NOW;
+ FWK_R uint32_t T_LVL_DISCONNECT_NOW;
+ uint8_t RESERVED86[0x1620 - 0x1618];
+ FWK_R uint32_t WDQLVL_CONTROL_NOW;
+ FWK_R uint32_t WDQLVL_VREFDQ_TRAIN_MRS_NOW;
+ FWK_R uint32_t WDQLVL_ADDRESS_31_00_NOW;
+ FWK_R uint32_t WDQLVL_ADDRESS_63_32_NOW;
+ FWK_R uint32_t T_WDQLVL_EN_NOW;
+ FWK_R uint32_t T_WDQLVL_WW_NOW;
+ FWK_R uint32_t T_WDQLVL_RW_NOW;
+ uint8_t RESERVED87[0x1654 - 0x163C];
+ FWK_R uint32_t PHYMSTR_CONTROL_NOW;
+ uint8_t RESERVED88[0x1FD0 - 0x1658];
+ FWK_R uint32_t PERIPH_ID_4;
+ uint8_t RESERVED89[0x1FE0 - 0x1FD4];
+ FWK_R uint32_t PERIPH_ID_0;
+ FWK_R uint32_t PERIPH_ID_1;
+ FWK_R uint32_t PERIPH_ID_2;
+ FWK_R uint32_t PERIPH_ID_3;
+ FWK_R uint32_t COMPONENT_ID_0;
+ FWK_R uint32_t COMPONENT_ID_1;
+ FWK_R uint32_t COMPONENT_ID_2;
+ FWK_R uint32_t COMPONENT_ID_3;
+ /*!
+ * \endcond
+ * @}
+ */
+};
+
+/*!
+ * \brief Mask to get the memc_cmd bitfield
+ */
+#define MOD_DMC_BING_MEMC_CMD UINT32_C(0x00000007)
+
+/*!
+ * \brief Command to enter into the CONFIG architectural state
+ */
+#define MOD_DMC_BING_MEMC_CMD_CONFIG UINT32_C(0x00000000)
+
+/*!
+ * \brief Command to enter the SLEEP architectural state
+ */
+#define MOD_DMC_BING_MEMC_CMD_SLEEP UINT32_C(0x00000001)
+
+/*!
+ * \brief Command to enter the READY architectural state
+ */
+#define MOD_DMC_BING_MEMC_CMD_GO UINT32_C(0x00000003)
+
+/*!
+ * \brief Command to perform any direct_cmd operations
+ */
+#define MOD_DMC_BING_MEMC_CMD_EXECUTE UINT32_C(0x00000004)
+
+/*!
+ * \brief Enable ECC detection on reads
+ */
+#define DMC_ERR0CTRL0_ED_ENABLE UINT32_C(0x00000001)
+
+/*!
+ * \brief Enable defer on reads
+ */
+#define DMC_ERR0CTRL0_DE_ENABLE UINT32_C(0x00000002)
+
+/*!
+ * \brief Enable uncorrectable error recovery interrupt
+ */
+#define DMC_ERR0CTRL0_UI_ENABLE UINT32_C(0x00000004)
+
+/*!
+ * \brief Enable ECC FHI interrupt
+ */
+#define DMC_ERR0CTRL0_FI_ENABLE UINT32_C(0x00000008)
+
+/*!
+ * \brief Enable CFI interrupt
+ */
+#define DMC_ERR0CTRL0_CFI_ENABLE UINT32_C(0x00000100)
+
+/*!
+ * \brief Element configuration.
+ */
+struct mod_dmc_bing_element_config {
+ /*! Base address of the DMC-BING device's registers */
+ uintptr_t dmc;
+ /*! Element identifier of the associated DDR PHY-500 device */
+ fwk_id_t ddr_id;
+ /*! Identifier of the clock that this element depends on */
+ fwk_id_t clock_id;
+};
+
+/*!
+ * \brief API of the DDR PHY associated to the DMC
+ */
+struct mod_dmc_ddr_phy_api {
+ /*!
+ * \brief Configure a DDR physical device
+ *
+ * \param element_id Element identifier corresponding to the device to
+ * configure.
+ *
+ * \retval FWK_SUCCESS if the operation succeed.
+ * \return one of the error code otherwise.
+ */
+ int (*configure)(fwk_id_t element_id);
+};
+
+/*!
+ * \brief DMC-BING module configuration.
+ */
+struct mod_dmc_bing_module_config {
+ /*! DDR PHY module ID*/
+ fwk_id_t ddr_module_id;
+ /*! DDR PHY API ID*/
+ fwk_id_t ddr_api_id;
+ /*! Default value for the dmc register */
+ struct mod_dmc_bing_reg *dmc_val;
+ /*! Pointer to a product-specific function that issues direct commands */
+ void (*direct_ddr_cmd)(struct mod_dmc_bing_reg *dmc);
+};
+
+/*!
+ * \brief DMC-BING module description.
+ */
+extern const struct fwk_module module_dmc_bing;
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#endif /* MOD_DMC_BING_H */
diff --git a/product/morello/module/dmc_bing/src/Makefile b/product/morello/module/dmc_bing/src/Makefile
new file mode 100644
index 00000000..16026bd9
--- /dev/null
+++ b/product/morello/module/dmc_bing/src/Makefile
@@ -0,0 +1,11 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := mod_dmc_bing
+BS_LIB_SOURCES += mod_dmc_bing.c
+
+include $(BS_DIR)/lib.mk
diff --git a/product/morello/module/dmc_bing/src/mod_dmc_bing.c b/product/morello/module/dmc_bing/src/mod_dmc_bing.c
new file mode 100644
index 00000000..daa1f205
--- /dev/null
+++ b/product/morello/module/dmc_bing/src/mod_dmc_bing.c
@@ -0,0 +1,290 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * DMC-BING driver
+ */
+
+#include <mod_clock.h>
+#include <mod_dmc_bing.h>
+
+#include <fwk_assert.h>
+#include <fwk_event.h>
+#include <fwk_log.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <fwk_notification.h>
+#include <fwk_status.h>
+
+#include <fmw_cmsis.h>
+
+#include <stddef.h>
+
+static struct mod_dmc_ddr_phy_api *ddr_phy_api;
+
+static int dmc_bing_config(struct mod_dmc_bing_reg *dmc, fwk_id_t ddr_id);
+
+/* Framework API */
+static int mod_dmc_bing_init(
+ fwk_id_t module_id,
+ unsigned int element_count,
+ const void *config)
+{
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc_bing_element_init(
+ fwk_id_t element_id,
+ unsigned int unused,
+ const void *data)
+{
+ fwk_assert(data != NULL);
+
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc_bing_bind(fwk_id_t id, unsigned int round)
+{
+ int status;
+ const struct mod_dmc_bing_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_dmc_bing);
+ fwk_assert(module_config != NULL);
+
+ if (!(fwk_id_is_equal(module_config->ddr_module_id, FWK_ID_NONE))) {
+ status = fwk_module_bind(
+ module_config->ddr_module_id,
+ module_config->ddr_api_id,
+ &ddr_phy_api);
+ if (status != FWK_SUCCESS)
+ return status;
+ }
+
+ return FWK_SUCCESS;
+}
+
+static int mod_dmc_bing_start(fwk_id_t id)
+{
+ const struct mod_dmc_bing_element_config *element_config;
+
+ if (!fwk_id_is_type(id, FWK_ID_TYPE_ELEMENT))
+ return FWK_SUCCESS;
+
+ element_config = fwk_module_get_data(id);
+
+ /* Register elements for clock state notifications */
+ return fwk_notification_subscribe(
+ mod_clock_notification_id_state_changed, element_config->clock_id, id);
+}
+
+static int dmc_bing_notify_system_state_transition_resume(fwk_id_t id)
+{
+ struct mod_dmc_bing_reg *dmc;
+ const struct mod_dmc_bing_element_config *element_config;
+
+ element_config = fwk_module_get_data(id);
+ dmc = (struct mod_dmc_bing_reg *)element_config->dmc;
+
+ return dmc_bing_config(dmc, element_config->ddr_id);
+}
+
+static int mod_dmc_bing_process_notification(
+ const struct fwk_event *event,
+ struct fwk_event *resp_event)
+{
+ struct clock_notification_params *params;
+
+ fwk_assert(
+ fwk_id_is_equal(event->id, mod_clock_notification_id_state_changed));
+ fwk_assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_ELEMENT));
+
+ params = (struct clock_notification_params *)event->params;
+
+ if (params->new_state == MOD_CLOCK_STATE_RUNNING)
+ return dmc_bing_notify_system_state_transition_resume(event->target_id);
+
+ return FWK_SUCCESS;
+}
+
+const struct fwk_module module_dmc_bing = {
+ .name = "DMC BING",
+ .type = FWK_MODULE_TYPE_DRIVER,
+ .init = mod_dmc_bing_init,
+ .element_init = mod_dmc_bing_element_init,
+ .bind = mod_dmc_bing_bind,
+ .start = mod_dmc_bing_start,
+ .process_notification = mod_dmc_bing_process_notification,
+ .api_count = 0,
+ .event_count = 0,
+};
+
+static int dmc_bing_config(struct mod_dmc_bing_reg *dmc, fwk_id_t ddr_id)
+{
+ int i;
+ struct mod_dmc_bing_reg *reg_val;
+ const struct mod_dmc_bing_module_config *module_config;
+
+ module_config = fwk_module_get_data(fwk_module_id_dmc_bing);
+ reg_val = module_config->dmc_val;
+
+ FWK_LOG_INFO("[DDR] Initialising DMC_BING at 0x%x", (uintptr_t)dmc);
+
+ FWK_LOG_INFO("[DDR] Writing functional settings");
+
+ dmc->ADDRESS_CONTROL_NEXT = reg_val->ADDRESS_CONTROL_NEXT;
+
+ dmc->DECODE_CONTROL_NEXT = reg_val->DECODE_CONTROL_NEXT;
+ dmc->FORMAT_CONTROL = reg_val->FORMAT_CONTROL;
+
+ dmc->ADDRESS_MAP_NEXT = reg_val->ADDRESS_MAP_NEXT;
+
+ dmc->LOW_POWER_CONTROL_NEXT = reg_val->LOW_POWER_CONTROL_NEXT;
+ dmc->TURNAROUND_CONTROL_NEXT = reg_val->TURNAROUND_CONTROL_NEXT;
+ dmc->HIT_TURNAROUND_CONTROL_NEXT = reg_val->HIT_TURNAROUND_CONTROL_NEXT;
+ dmc->QOS_CLASS_CONTROL_NEXT = reg_val->QOS_CLASS_CONTROL_NEXT;
+ dmc->ESCALATION_CONTROL_NEXT = reg_val->ESCALATION_CONTROL_NEXT;
+ dmc->QV_CONTROL_31_00_NEXT = reg_val->QV_CONTROL_31_00_NEXT;
+ dmc->QV_CONTROL_63_32_NEXT = reg_val->QV_CONTROL_63_32_NEXT;
+ dmc->RT_CONTROL_31_00_NEXT = reg_val->RT_CONTROL_31_00_NEXT;
+ dmc->RT_CONTROL_63_32_NEXT = reg_val->RT_CONTROL_63_32_NEXT;
+ dmc->TIMEOUT_CONTROL_NEXT = reg_val->TIMEOUT_CONTROL_NEXT;
+ dmc->CREDIT_CONTROL_NEXT = reg_val->CREDIT_CONTROL_NEXT;
+ dmc->WRITE_PRIORITY_CONTROL_31_00_NEXT =
+ reg_val->WRITE_PRIORITY_CONTROL_31_00_NEXT;
+ dmc->WRITE_PRIORITY_CONTROL_63_32_NEXT =
+ reg_val->WRITE_PRIORITY_CONTROL_63_32_NEXT;
+ dmc->QUEUE_THRESHOLD_CONTROL_31_00_NEXT =
+ reg_val->QUEUE_THRESHOLD_CONTROL_31_00_NEXT;
+ dmc->QUEUE_THRESHOLD_CONTROL_63_32_NEXT =
+ reg_val->QUEUE_THRESHOLD_CONTROL_63_32_NEXT;
+ dmc->ADDRESS_SHUTTER_31_00_NEXT = reg_val->ADDRESS_SHUTTER_31_00_NEXT;
+ dmc->ADDRESS_SHUTTER_63_32_NEXT = reg_val->ADDRESS_SHUTTER_63_32_NEXT;
+ dmc->ADDRESS_SHUTTER_95_64_NEXT = reg_val->ADDRESS_SHUTTER_95_64_NEXT;
+ dmc->ADDRESS_SHUTTER_127_96_NEXT = reg_val->ADDRESS_SHUTTER_127_96_NEXT;
+ dmc->ADDRESS_SHUTTER_159_128_NEXT = reg_val->ADDRESS_SHUTTER_159_128_NEXT;
+ dmc->ADDRESS_SHUTTER_191_160_NEXT = reg_val->ADDRESS_SHUTTER_191_160_NEXT;
+ dmc->MEMORY_ADDRESS_MAX_31_00_NEXT = reg_val->MEMORY_ADDRESS_MAX_31_00_NEXT;
+ dmc->MEMORY_ADDRESS_MAX_43_32_NEXT = reg_val->MEMORY_ADDRESS_MAX_43_32_NEXT;
+ dmc->ACCESS_ADDRESS_NEXT[0].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[0].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[0].MIN_43_32 =
+ reg_val->ACCESS_ADDRESS_NEXT[0].MIN_43_32;
+ dmc->ACCESS_ADDRESS_NEXT[1].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[1].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[1].MIN_43_32 =
+ reg_val->ACCESS_ADDRESS_NEXT[1].MIN_43_32;
+ dmc->ACCESS_ADDRESS_NEXT[2].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[2].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[3].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[3].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[4].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[4].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[5].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[5].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[6].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[6].MIN_31_00;
+ dmc->ACCESS_ADDRESS_NEXT[7].MIN_31_00 =
+ reg_val->ACCESS_ADDRESS_NEXT[7].MIN_31_00;
+
+ dmc->DCI_REPLAY_TYPE_NEXT = reg_val->DCI_REPLAY_TYPE_NEXT;
+ dmc->DCI_STRB = reg_val->DCI_STRB;
+ dmc->DCI_DATA = reg_val->DCI_DATA;
+ dmc->REFRESH_CONTROL_NEXT = reg_val->REFRESH_CONTROL_NEXT;
+ dmc->MEMORY_TYPE_NEXT = reg_val->MEMORY_TYPE_NEXT;
+ dmc->FEATURE_CONFIG = reg_val->FEATURE_CONFIG;
+ dmc->FEATURE_CONTROL_NEXT = reg_val->FEATURE_CONTROL_NEXT;
+ dmc->MUX_CONTROL_NEXT = reg_val->MUX_CONTROL_NEXT;
+
+ /* Timing Configuration */
+ FWK_LOG_INFO("[DDR] Writing timing settings");
+
+ dmc->T_REFI_NEXT = reg_val->T_REFI_NEXT;
+ dmc->T_RFC_NEXT = reg_val->T_RFC_NEXT;
+ dmc->T_MRR_NEXT = reg_val->T_MRR_NEXT;
+ dmc->T_MRW_NEXT = reg_val->T_MRW_NEXT;
+ dmc->T_RCD_NEXT = reg_val->T_RCD_NEXT;
+ dmc->T_RAS_NEXT = reg_val->T_RAS_NEXT;
+ dmc->T_RP_NEXT = reg_val->T_RP_NEXT;
+ dmc->T_RPALL_NEXT = reg_val->T_RPALL_NEXT;
+ dmc->T_RRD_NEXT = reg_val->T_RRD_NEXT;
+ dmc->T_ACT_WINDOW_NEXT = reg_val->T_ACT_WINDOW_NEXT;
+ dmc->T_RTR_NEXT = reg_val->T_RTR_NEXT;
+ dmc->T_RTW_NEXT = reg_val->T_RTW_NEXT;
+ dmc->T_RTP_NEXT = reg_val->T_RTP_NEXT;
+ dmc->T_WR_NEXT = reg_val->T_WR_NEXT;
+ dmc->T_WTR_NEXT = reg_val->T_WTR_NEXT;
+ dmc->T_WTW_NEXT = reg_val->T_WTW_NEXT;
+ dmc->T_XMPD_NEXT = reg_val->T_XMPD_NEXT;
+ dmc->T_EP_NEXT = reg_val->T_EP_NEXT;
+ dmc->T_XP_NEXT = reg_val->T_XP_NEXT;
+ dmc->T_ESR_NEXT = reg_val->T_ESR_NEXT;
+ dmc->T_XSR_NEXT = reg_val->T_XSR_NEXT;
+ dmc->T_ESRCK_NEXT = reg_val->T_ESRCK_NEXT;
+ dmc->T_CKXSR_NEXT = reg_val->T_CKXSR_NEXT;
+ dmc->T_CMD_NEXT = reg_val->T_CMD_NEXT;
+ dmc->T_PARITY_NEXT = reg_val->T_PARITY_NEXT;
+ dmc->T_ZQCS_NEXT = reg_val->T_ZQCS_NEXT;
+ dmc->T_RW_ODT_CLR_NEXT = reg_val->T_RW_ODT_CLR_NEXT;
+ dmc->T_RDDATA_EN_NEXT = reg_val->T_RDDATA_EN_NEXT;
+ dmc->T_PHYWRLAT_NEXT = reg_val->T_PHYWRLAT_NEXT;
+ dmc->T_PHYRDLAT_NEXT = reg_val->T_PHYRDLAT_NEXT;
+ dmc->RDLVL_CONTROL_NEXT = reg_val->RDLVL_CONTROL_NEXT;
+ dmc->RDLVL_MRS_NEXT = reg_val->RDLVL_MRS_NEXT;
+ dmc->T_RDLVL_EN_NEXT = reg_val->T_RDLVL_EN_NEXT;
+ dmc->T_RDLVL_RR_NEXT = reg_val->T_RDLVL_RR_NEXT;
+ dmc->WRLVL_CONTROL_NEXT = reg_val->WRLVL_CONTROL_NEXT;
+ dmc->WRLVL_MRS_NEXT = reg_val->WRLVL_MRS_NEXT;
+ dmc->T_WRLVL_EN_NEXT = reg_val->T_WRLVL_EN_NEXT;
+ dmc->T_WRLVL_WW_NEXT = reg_val->T_WRLVL_WW_NEXT;
+ dmc->PHY_POWER_CONTROL_NEXT = reg_val->PHY_POWER_CONTROL_NEXT;
+ dmc->T_LPRESP_NEXT = reg_val->T_LPRESP_NEXT;
+ dmc->PHY_UPDATE_CONTROL_NEXT = reg_val->PHY_UPDATE_CONTROL_NEXT;
+ dmc->T_ODTH_NEXT = reg_val->T_ODTH_NEXT;
+
+ dmc->ODT_TIMING_NEXT = reg_val->ODT_TIMING_NEXT;
+ dmc->ODT_WR_CONTROL_31_00_NEXT = reg_val->ODT_WR_CONTROL_31_00_NEXT;
+ dmc->ODT_WR_CONTROL_63_32_NEXT = reg_val->ODT_WR_CONTROL_63_32_NEXT;
+ dmc->ODT_RD_CONTROL_31_00_NEXT = reg_val->ODT_RD_CONTROL_31_00_NEXT;
+ dmc->ODT_RD_CONTROL_63_32_NEXT = reg_val->ODT_RD_CONTROL_63_32_NEXT;
+
+ /* Enable RAS interrupts and error detection */
+ dmc->ERR0CTLR0 = reg_val->ERR0CTLR0;
+
+ if (!(fwk_id_is_equal(module_config->ddr_module_id, FWK_ID_NONE)))
+ ddr_phy_api->configure(ddr_id);
+
+ for (i = 0; i < 3; i++) /* ~200ns */
+ __NOP();
+
+ FWK_LOG_INFO("[DDR] Sending direct DDR commands");
+
+ module_config->direct_ddr_cmd(dmc);
+
+ for (i = 0; i < 5; i++) /* ~400ns */
+ __NOP();
+
+ /* Switch to READY */
+ FWK_LOG_INFO("[DDR] Setting DMC to READY mode");
+
+ dmc->MEMC_CMD = MOD_DMC_BING_MEMC_CMD_GO;
+ dmc->MEMC_CMD = MOD_DMC_BING_MEMC_CMD_EXECUTE;
+
+ while ((dmc->MEMC_STATUS & MOD_DMC_BING_MEMC_CMD) !=
+ MOD_DMC_BING_MEMC_CMD_GO)
+ continue;
+
+ FWK_LOG_INFO("[DDR] DMC init done.");
+
+ return FWK_SUCCESS;
+}
diff --git a/product/morello/scp_ramfw_fvp/config_dmc_bing.c b/product/morello/scp_ramfw_fvp/config_dmc_bing.c
new file mode 100644
index 00000000..dc527592
--- /dev/null
+++ b/product/morello/scp_ramfw_fvp/config_dmc_bing.c
@@ -0,0 +1,223 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "config_clock.h"
+#include "morello_scp_mmap.h"
+
+#include <mod_dmc_bing.h>
+
+#include <fwk_element.h>
+#include <fwk_id.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+
+#define COL_BITS 2
+#define BANK_BITS 4
+#define RANK_BITS 1
+#define ROW_BITS 5
+#define BANK_HASH_ENABLE 1
+#define MEM_TYPE 2
+#define ADDR_DEC 0x68C
+#define STRIPE_DEC 1
+#define MEM_DEVICE_WIDTH 0
+#define BANK_GROUP 3
+#define MEM_CHANNEL 2
+#define ADDRESS_CONTROL_NEXT_VAL \
+ ((BANK_HASH_ENABLE << 28) | (RANK_BITS << 24) | (BANK_BITS << 16) | \
+ (ROW_BITS << 8) | (COL_BITS))
+#define DECODE_CONTROL_NEXT_VAL ((ADDR_DEC << 10) | (STRIPE_DEC << 4))
+#define MEMORY_TYPE_NEXT_VAL \
+ ((BANK_GROUP << 16) | (MEM_DEVICE_WIDTH << 8) | (MEM_TYPE))
+
+struct mod_dmc_bing_reg dmc_val = {
+ .ADDRESS_CONTROL_NEXT = ADDRESS_CONTROL_NEXT_VAL,
+ .DECODE_CONTROL_NEXT = DECODE_CONTROL_NEXT_VAL,
+ .FORMAT_CONTROL = 0x00000003,
+ .ADDRESS_MAP_NEXT = 0x00000002,
+ .LOW_POWER_CONTROL_NEXT = 0x00000010,
+ .TURNAROUND_CONTROL_NEXT = 0x1F0F0F0F,
+ .HIT_TURNAROUND_CONTROL_NEXT = 0x08909FBF,
+ .QOS_CLASS_CONTROL_NEXT = 0x00000FC8,
+ .ESCALATION_CONTROL_NEXT = 0x00080F00,
+ .QV_CONTROL_31_00_NEXT = 0x76543210,
+ .QV_CONTROL_63_32_NEXT = 0xFEDCBA98,
+ .RT_CONTROL_31_00_NEXT = 0x00000000,
+ .RT_CONTROL_63_32_NEXT = 0x00000000,
+ .TIMEOUT_CONTROL_NEXT = 0x00000001,
+ .CREDIT_CONTROL_NEXT = 0x00000F03,
+ .WRITE_PRIORITY_CONTROL_31_00_NEXT = 0x00000000,
+ .WRITE_PRIORITY_CONTROL_63_32_NEXT = 0xECA86421,
+ .QUEUE_THRESHOLD_CONTROL_31_00_NEXT = 0x00000008,
+ .QUEUE_THRESHOLD_CONTROL_63_32_NEXT = 0x00000000,
+ .ADDRESS_SHUTTER_31_00_NEXT = 0x11111110,
+ .ADDRESS_SHUTTER_63_32_NEXT = 0x11111111,
+ .ADDRESS_SHUTTER_95_64_NEXT = 0x11111111,
+ .ADDRESS_SHUTTER_127_96_NEXT = 0x11111111,
+ .ADDRESS_SHUTTER_159_128_NEXT = 0x11111111,
+ .ADDRESS_SHUTTER_191_160_NEXT = 0x11111111,
+ .MEMORY_ADDRESS_MAX_31_00_NEXT = 0xFFFF001F,
+ .MEMORY_ADDRESS_MAX_43_32_NEXT = 0x00000FFF,
+ .ACCESS_ADDRESS_NEXT =
+ {
+ [0] = { .MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000 },
+ [1] = { .MIN_31_00 = 0x0000000F, .MIN_43_32 = 0x00000000 },
+ [2] = { .MIN_31_00 = 0x0000000F },
+ [3] = { .MIN_31_00 = 0x0000000F },
+ [4] = { .MIN_31_00 = 0x0000000F },
+ [5] = { .MIN_31_00 = 0x0000000F },
+ [6] = { .MIN_31_00 = 0x0000000F },
+ [7] = { .MIN_31_00 = 0x0000000F },
+ },
+ .DCI_REPLAY_TYPE_NEXT = 0x00000000,
+ .DCI_STRB = 0x00000007,
+ .DCI_DATA = 0x00000000,
+ .REFRESH_CONTROL_NEXT = 0x00000000,
+ .MEMORY_TYPE_NEXT = MEMORY_TYPE_NEXT_VAL,
+ .FEATURE_CONFIG = 0x00001800,
+ .FEATURE_CONTROL_NEXT = 0x00000000,
+ .MUX_CONTROL_NEXT = 0x00000000,
+ .T_REFI_NEXT = 0x90000618,
+ .T_RFC_NEXT = 0x06A8C230,
+ .T_MRR_NEXT = 0x00000001,
+ .T_MRW_NEXT = 0x00010018,
+ .T_RCD_NEXT = 0x00000014,
+ .T_RAS_NEXT = 0x00000034,
+ .T_RP_NEXT = 0x00000014,
+ .T_RPALL_NEXT = 0x00000014,
+ .T_RRD_NEXT = 0x04000805,
+ .T_ACT_WINDOW_NEXT = 0x00001010,
+ .T_RTR_NEXT = 0x14060804,
+ .T_RTW_NEXT = 0x000A0A0A,
+ .T_RTP_NEXT = 0x0000000C,
+ .T_WR_NEXT = 0x0000002C,
+ .T_WTR_NEXT = 0x00022019,
+ .T_WTW_NEXT = 0x14060804,
+ .T_XMPD_NEXT = 0x00000510,
+ .T_EP_NEXT = 0x00000008,
+ .T_XP_NEXT = 0x0014000A,
+ .T_ESR_NEXT = 0x00000009,
+ .T_XSR_NEXT = 0x04000110,
+ .T_ESRCK_NEXT = 0x00000010,
+ .T_CKXSR_NEXT = 0x00000010,
+ .T_CMD_NEXT = 0x00000000,
+ .T_PARITY_NEXT = 0x00001600,
+ .T_ZQCS_NEXT = 0x00000090,
+ .T_RW_ODT_CLR_NEXT = 0x0000005E,
+ .T_RDDATA_EN_NEXT = 0x00000000,
+ .T_PHYWRLAT_NEXT = 0x001F000E,
+ .T_PHYRDLAT_NEXT = 0x0000002E,
+ .RDLVL_CONTROL_NEXT = 0x00000000,
+ .RDLVL_MRS_NEXT = 0x00000424,
+ .T_RDLVL_EN_NEXT = 0x00000001,
+ .T_RDLVL_RR_NEXT = 0x0000001A,
+ .WRLVL_CONTROL_NEXT = 0x00100000,
+ .WRLVL_MRS_NEXT = 0x00000181,
+ .T_WRLVL_EN_NEXT = 0x00000018,
+ .T_WRLVL_WW_NEXT = 0x00000001,
+ .PHY_POWER_CONTROL_NEXT = 0x00000000,
+ .T_LPRESP_NEXT = 0x00000000,
+ .PHY_UPDATE_CONTROL_NEXT = 0x00000000,
+ .T_ODTH_NEXT = 0x00000006,
+ .ODT_TIMING_NEXT = 0x07003900,
+ .ODT_WR_CONTROL_31_00_NEXT = 0x08040201,
+ .ODT_WR_CONTROL_63_32_NEXT = 0x80402010,
+ .ODT_RD_CONTROL_31_00_NEXT = 0x00000000,
+ .ODT_RD_CONTROL_63_32_NEXT = 0x00000000,
+ .ERR0CTLR0 = DMC_ERR0CTRL0_ED_ENABLE | DMC_ERR0CTRL0_DE_ENABLE |
+ DMC_ERR0CTRL0_UI_ENABLE | DMC_ERR0CTRL0_FI_ENABLE |
+ DMC_ERR0CTRL0_CFI_ENABLE,
+};
+
+/* Table of DMC_BING elements descriptions. */
+static struct fwk_element dmc_bing_element_table[] = {
+ [0] =
+ {
+ .name = "DMC_BING-0",
+ .data = &((struct mod_dmc_bing_element_config){
+ .dmc = SCP_DMC0,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_IDX_INTERCONNECT),
+ }),
+ },
+ [1] =
+ {
+ .name = "DMC_BING-1",
+ .data = &((struct mod_dmc_bing_element_config){
+ .dmc = SCP_DMC1,
+ .clock_id = FWK_ID_ELEMENT_INIT(
+ FWK_MODULE_IDX_CLOCK,
+ CLOCK_IDX_INTERCONNECT),
+ }),
+ },
+ [2] = { 0 }, /* Termination description. */
+};
+
+static const struct fwk_element *dmc_bing_get_element_table(fwk_id_t module_id)
+{
+ return dmc_bing_element_table;
+}
+
+static void direct_ddr_cmd(struct mod_dmc_bing_reg *dmc)
+{
+ dmc->DIRECT_ADDR = 0x00000004;
+ dmc->DIRECT_CMD = 0x0001000A;
+ dmc->DIRECT_ADDR = 0x00000006;
+ dmc->DIRECT_CMD = 0x00030004;
+ dmc->DIRECT_ADDR = 0x00000000;
+ dmc->DIRECT_CMD = 0x0001000B;
+ dmc->DIRECT_ADDR = 0x00000001;
+ dmc->DIRECT_CMD = 0x0003000B;
+ dmc->DIRECT_ADDR = 0x000003E8;
+ dmc->DIRECT_CMD = 0x0001000D;
+ dmc->DIRECT_ADDR = 0x00000258;
+ dmc->DIRECT_CMD = 0x0001000D;
+ dmc->DIRECT_ADDR = 0x00010001;
+ dmc->DIRECT_CMD = 0x0003000B;
+ dmc->DIRECT_ADDR = 0x0000003C;
+ dmc->DIRECT_CMD = 0x0001000D;
+ dmc->DIRECT_ADDR = 0x00000000;
+ dmc->DIRECT_CMD = 0x00030000;
+ dmc->DIRECT_ADDR = 0x0000003C;
+ dmc->DIRECT_ADDR = 0x00000420;
+ dmc->DIRECT_CMD = 0x00030301;
+ dmc->DIRECT_ADDR = 0x00001000;
+ dmc->DIRECT_CMD = 0x00030601;
+ dmc->DIRECT_ADDR = 0x00000600;
+ dmc->DIRECT_CMD = 0x00030501;
+ dmc->DIRECT_ADDR = 0x00000000;
+ dmc->DIRECT_CMD = 0x30030401;
+ dmc->DIRECT_ADDR = 0x00000028;
+ dmc->DIRECT_CMD = 0x00030201;
+ dmc->DIRECT_ADDR = 0x00000001;
+ dmc->DIRECT_CMD = 0x00030101;
+ dmc->DIRECT_ADDR = 0x00000D50;
+ dmc->DIRECT_CMD = 0x00030001;
+ dmc->DIRECT_ADDR = 0x000003F6;
+ dmc->DIRECT_CMD = 0x0001000D;
+ dmc->DIRECT_ADDR = 0x0000000A;
+ dmc->DIRECT_CMD = 0x0001000D;
+ dmc->DIRECT_ADDR = 0x00000400;
+ dmc->DIRECT_CMD = 0x00030005;
+ dmc->DIRECT_ADDR = 0x000003FF;
+ dmc->DIRECT_CMD = 0x0001000D;
+}
+
+/* Configuration of the DMC_BING module.
+ *
+ * Skip initializing ddr_module_id and ddr_api_id in order to
+ * bypass invocation of DDR PHY initialization/configuration
+ * during DMC_BING module init.
+ */
+const struct fwk_module_config config_dmc_bing = {
+ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dmc_bing_get_element_table),
+ .data = &((struct mod_dmc_bing_module_config){
+ .dmc_val = &dmc_val,
+ .ddr_module_id = FWK_ID_NONE_INIT,
+ .direct_ddr_cmd = direct_ddr_cmd,
+ }),
+};