diff options
author | Nicola Mazzucato <nicola.mazzucato@arm.com> | 2019-02-05 17:12:36 +0000 |
---|---|---|
committer | ronald-cron-arm <39518861+ronald-cron-arm@users.noreply.github.com> | 2019-02-26 18:45:43 +0100 |
commit | 218f46aac85859ec7b0c747f9211b8c1c9b20278 (patch) | |
tree | a0b6d806044ae5bcad6bd405311f29a4d2eb14b6 | |
parent | cb6bc5d9d5edd6b686c80971af9deda36ff4a684 (diff) |
sgm775/module: Add DMC-500 module
This patch adds a platform-specific DMC500 module derived
from the generic DMC500 module, providing memory-cost saving
and simplified configuration.
Change-Id: Ib242d9261a4fd67b10bc9c09f5bd4280d4796212
Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
3 files changed, 858 insertions, 0 deletions
diff --git a/product/sgm775/module/sgm775_dmc500/include/mod_sgm775_dmc500.h b/product/sgm775/module/sgm775_dmc500/include/mod_sgm775_dmc500.h new file mode 100644 index 00000000..4ef0be56 --- /dev/null +++ b/product/sgm775/module/sgm775_dmc500/include/mod_sgm775_dmc500.h @@ -0,0 +1,471 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SGM775 DMC-500 module. + */ + +#ifndef MOD_SGM775_DMC500_H +#define MOD_SGM775_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 GroupSGM775_DMC DMC-500 Driver + * @{ + */ + +/*! + * \brief DMC-500 register definitions + */ +struct mod_sgm775_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; + uint8_t RESERVED2[0x254 - 0x250]; + 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; + uint8_t RESERVED4[0x414 - 0x410]; + 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; + uint8_t RESERVED6[0x470 - 0x46C]; + FWK_R uint32_t ERR_RAMECC_FR; + uint8_t RESERVED7[0x478 - 0x474]; + FWK_RW uint32_t ERR_RAMECC_CTLR; + uint8_t RESERVED8[0x480 - 0x47C]; + FWK_RW uint32_t ERR_RAMECC_STATUS; + uint8_t RESERVED9[0x488 - 0x484]; + FWK_RW uint32_t ERR_RAMECC_ADDR; + FWK_RW uint32_t ERR_RAMECC_ADDR2; + FWK_RW uint32_t ERR_RAMECC_MISC0; + uint8_t RESERVED10[0x4A0 - 0x494]; + FWK_W uint32_t ERR_RAMECC_INJECT; + uint8_t RESERVED11[0x500 - 0x4A4]; + FWK_R uint32_t QUEUE_STATUS; + uint8_t RESERVED12[0x508 - 0x504]; + 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; + uint8_t RESERVED13[0x548 - 0x544]; + 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; + uint8_t RESERVED15[0x628 - 0x624]; + FWK_R uint32_t PMU_MI_INT_INFO; + uint8_t RESERVED16[0x630 - 0x62C]; + 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; + uint8_t RESERVED17[0x684 - 0x680]; + FWK_RW uint32_t ODT_RD_CONTROL_31_00; + uint8_t RESERVED18[0x68C - 0x688]; + FWK_RW uint32_t PHY_WRDATA_CS_CONTROL_31_00; + uint8_t RESERVED19[0x694 - 0x690]; + FWK_RW uint32_t PHY_RDDATA_CS_CONTROL_31_00; + uint8_t RESERVED20[0x69C - 0x698]; + FWK_RW uint32_t PHYUPD_INIT; + FWK_RW uint32_t PHY_POWER_CONTROL; + uint8_t RESERVED21[0x6A8 - 0x6A4]; + 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; + uint8_t RESERVED22[0x704 - 0x700]; + 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; + uint8_t RESERVED23[0x720 - 0x71C]; + FWK_RW uint32_t ERR_PHY_CTLR; + uint8_t RESERVED24[0x728 - 0x724]; + FWK_RW uint32_t ERR_PHY_STATUS; + uint8_t RESERVED25[0x730 - 0x72C]; + 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; + uint8_t RESERVED28[0xF10 - 0xF04]; + 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; + uint8_t RESERVED30[0xF38 - 0xF34]; + 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; + uint8_t RESERVED32[0xFD0 - 0xFC8]; + FWK_R uint32_t PERIPH_ID_4; + uint8_t RESERVED33[0xFE0 - 0xFD4]; + 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_STATUS mask used to confirm that request stalling is active. + */ +#define MOD_DMC500_SI_STATUS_STALL_ACK (1 << 0) + +/*! + * \brief QUEUE_STATUS mask used to confirm that request stalling is active. + */ +#define MOD_DMC500_QUEUE_STATUS_STALL_ACK (1 << 0) + +/*! + * \brief MI_STATUS mask used to read the idle bit. + */ +#define MOD_DMC500_MI_STATUS_IDLE (1 << 0) + +/*! + * \brief Element configuration. + */ +struct mod_sgm775_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 associated to the DMC. + */ +struct mod_sgm775_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 standard framework error codes. + */ + int (*configure)(fwk_id_t element_id); +}; + +/*! + * \brief SGM775 DMC-500 module configuration. + */ +struct mod_sgm775_dmc500_module_config { + /*! + * Element identifier of the timer used for delays when programming the + * DMC-500. + */ + fwk_id_t timer_id; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_SGM775_DMC500_H */ diff --git a/product/sgm775/module/sgm775_dmc500/src/Makefile b/product/sgm775/module/sgm775_dmc500/src/Makefile new file mode 100644 index 00000000..f2b407b3 --- /dev/null +++ b/product/sgm775/module/sgm775_dmc500/src/Makefile @@ -0,0 +1,11 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BS_LIB_NAME := SGM775 DMC-500 +BS_LIB_SOURCES += mod_sgm775_dmc500.c + +include $(BS_DIR)/lib.mk diff --git a/product/sgm775/module/sgm775_dmc500/src/mod_sgm775_dmc500.c b/product/sgm775/module/sgm775_dmc500/src/mod_sgm775_dmc500.c new file mode 100644 index 00000000..6d88ebcc --- /dev/null +++ b/product/sgm775/module/sgm775_dmc500/src/mod_sgm775_dmc500.c @@ -0,0 +1,376 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SGM775 DMC-500 module. + */ + +#include <fwk_assert.h> +#include <fwk_errno.h> +#include <fwk_mm.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> +#include <mod_sgm775_dmc500.h> + +#define COL_BITS 1 +#define BANK_BITS 0 +#define RANK_BITS 1 +#define BANK_GROUP 0 +#define ROW_BITS 4 +#define MEM_TYPE 3 +#define MEM_BURST 2 +#define DEVICE_WIDTH 2 +#define ADDR_SHUTTER 2 + +/* Timeout in us */ +#define TIMEOUT_DMC_INIT_US (1000 * 1000) + +static struct mod_log_api *log_api; +static struct mod_timer_api *timer_api; +static struct mod_sgm775_dmc_ddr_phy_api *ddr_phy_api; + +/* Forward declaration */ +static int sgm775_dmc500_config(struct mod_sgm775_dmc500_reg *dmc, + fwk_id_t ddr_phy_id); + +/* + * Framework APIs + */ + +static int mod_sgm775_dmc500_init(fwk_id_t module_id, + unsigned int element_count, const void *data) +{ + return FWK_SUCCESS; +} + +static int mod_sgm775_dmc500_element_init(fwk_id_t element_id, + unsigned int unused, const void *data) +{ + fwk_assert(data != NULL); + + return FWK_SUCCESS; +} + +static int mod_sgm775_dmc500_bind(fwk_id_t id, unsigned int round) +{ + int status; + const struct mod_sgm775_dmc500_module_config *module_config; + + /* Nothing to do in the second round of calls. */ + if (round == 1) + return FWK_SUCCESS; + + if (fwk_module_is_valid_module_id(id)) { + + module_config = fwk_module_get_data(fwk_module_id_sgm775_dmc500); + fwk_assert(module_config != NULL); + + /* Bind to the log module */ + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + MOD_LOG_API_ID, &log_api); + if (status != FWK_SUCCESS) + return status; + + /* Bind to the timer */ + status = fwk_module_bind(module_config->timer_id, + FWK_ID_API(FWK_MODULE_IDX_TIMER, 0), &timer_api); + if (status != FWK_SUCCESS) + return status; + + /* Bind to the DDR-PHY specific module */ + status = + fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_SGM775_DDR_PHY500), + FWK_ID_API(FWK_MODULE_IDX_SGM775_DDR_PHY500, 0), &ddr_phy_api); + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + +static int mod_sgm775_dmc500_start(fwk_id_t id) +{ + const struct mod_sgm775_dmc500_element_config *element_config; + struct mod_sgm775_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_sgm775_dmc500_reg *)element_config->dmc; + + return sgm775_dmc500_config(dmc, element_config->ddr_phy_id); +} + +const struct fwk_module module_sgm775_dmc500 = { + .name = "SGM775_DMC500", + .type = FWK_MODULE_TYPE_DRIVER, + .init = mod_sgm775_dmc500_init, + .element_init = mod_sgm775_dmc500_element_init, + .bind = mod_sgm775_dmc500_bind, + .start = mod_sgm775_dmc500_start, + .api_count = 0, + .event_count = 0, +}; + +static int sgm775_dmc500_config(struct mod_sgm775_dmc500_reg *dmc, + fwk_id_t ddr_phy_id) +{ + int status; + uint64_t timeout; + uint64_t remaining_ticks; + uint64_t counter; + const struct mod_sgm775_dmc500_module_config *module_config; + + module_config = fwk_module_get_data(fwk_module_id_sgm775_dmc500); + + log_api->log(MOD_LOG_GROUP_DEBUG, + "[DDR] Initialising DMC500 at 0x%x\n", (uintptr_t)dmc); + + dmc->ADDRESS_CONTROL = ((RANK_BITS << 24) | + (BANK_BITS << 16) | + (ROW_BITS << 8) | + COL_BITS); + dmc->RANK_REMAP_CONTROL = 0x00000000; + dmc->MEMORY_TYPE = ((BANK_GROUP << 16) | + (DEVICE_WIDTH << 8) | + MEM_TYPE); + dmc->FORMAT_CONTROL = (MEM_BURST << 8); + dmc->DECODE_CONTROL = 0x00000011; + dmc->FEATURE_CONTROL = 0x00000000; + dmc->ODT_WR_CONTROL_31_00 = 0x00000000; + dmc->ODT_RD_CONTROL_31_00 = 0x00000000; + dmc->ODT_TIMING = 0x10001000; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Setting timing settings\n"); + + dmc->T_REFI = 0x0000030B; + dmc->T_RFC = 0x000340D0; + dmc->T_RDPDEN = 0x0000002E; + dmc->T_RCD = 0x0000001D; + dmc->T_RAS = 0x80000044; + dmc->T_RP = 0x0000221D; + dmc->T_RRD = 0x00001010; + dmc->T_ACT_WINDOW = 0x00000040; + dmc->T_RTR = 0x000C0808; + dmc->T_RTW = 0x001F1F1F; + dmc->T_RTP = 0x0000000C; + dmc->T_WR = 0x00000035; + dmc->T_WTR = 0x00082929; + dmc->T_WTW = 0x000B0808; + dmc->T_XTMW = 0x00000020; + dmc->T_CLOCK_CONTROL = 0x1119030D; + dmc->T_EP = 0x0000000C; + dmc->T_XP = 0x000C000C; + dmc->T_ESR = 0x00000019; + dmc->T_XSR = 0x00E100E1; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Setting address map\n"); + + dmc->ADDRESS_MAP = ((1 << 8) | (ADDR_SHUTTER)); + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Setting PMU settings\n"); + + dmc->SI0_SI_INTERRUPT_CONTROL = 0x00000000; + dmc->SI0_PMU_REQ_CONTROL = 0x00000B1A; + dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_0 = 0xB0562AA1; + dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_0 = 0xD0FB6716; + dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_1 = 0x7FC24C15; + dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_1 = 0xF7A9B2AC; + dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_2 = 0xDD35FA69; + dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_2 = 0x3555A8F5; + dmc->SI0_PMU_REQ_ATTRIBUTE_MASK_3 = 0xDE382B10; + dmc->SI0_PMU_REQ_ATTRIBUTE_MATCH_3 = 0x3484B32C; + dmc->SI0_THRESHOLD_CONTROL = 0x80000801; + dmc->SI1_SI_INTERRUPT_CONTROL = 0x00000000; + dmc->SI1_PMU_REQ_CONTROL = 0x00000B1A; + dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_0 = 0xB0562AA1; + dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_0 = 0xD0FB6716; + dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_1 = 0x7FC24C15; + dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_1 = 0xF7A9B2AC; + dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_2 = 0xDD35FA69; + dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_2 = 0x3555A8F5; + dmc->SI1_PMU_REQ_ATTRIBUTE_MASK_3 = 0xDE382B10; + dmc->SI1_PMU_REQ_ATTRIBUTE_MATCH_3 = 0x3484B32C; + dmc->SI1_THRESHOLD_CONTROL = 0x80000801; + dmc->QUEUE_THRESHOLD_CONTROL_31_00 = 0xDEF8D550; + dmc->QUEUE_THRESHOLD_CONTROL_63_32 = 0xB038362F; + dmc->DCB_INTERRUPT_CONTROL = 0x00000000; + dmc->PMU_DCB_CONTROL = 0x00000800; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_0 = 0xFD98CF7D; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_0 = 0x9F276EB5; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_1 = 0x40B1FC24; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_1 = 0x04BBF4FA; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MASK_2 = 0x8089B0AF; + dmc->PMU_DATA_CONTROL_BLOCK_ATTRIBUTE_MATCH_2 = 0x7D26E0BE; + dmc->PMU_TAG_ENTRIES_ATTRIBUTE_MASK = 0x000000CE; + dmc->PMU_TAG_ENTRIES_ATTRIBUTE_MATCH = 0x00000056; + dmc->QE_INTERRUPT_CONTROL = 0x00000000; + dmc->RANK_TURNAROUND_CONTROL = 0x8909020F; + dmc->HIT_TURNAROUND_CONTROL = 0x37B8222C; + dmc->QOS_CLASS_CONTROL = 0x00000D50; + dmc->ESCALATION_CONTROL = 0x000D0C00; + dmc->QV_CONTROL_31_00 = 0xED2626B0; + dmc->QV_CONTROL_63_32 = 0x4159BE97; + dmc->RT_CONTROL_31_00 = 0xE8DC790A; + dmc->RT_CONTROL_63_32 = 0x9441A291; + dmc->TIMEOUT_CONTROL = 0x00000003; + dmc->WRITE_PRIORITY_CONTROL_31_00 = 0x81268C40; + dmc->WRITE_PRIORITY_CONTROL_63_32 = 0x15F20D15; + dmc->DIR_TURNAROUND_CONTROL = 0x06060403; + dmc->HIT_PREDICTION_CONTROL = 0x00020705; + dmc->REFRESH_PRIORITY = 0x00000204; + dmc->MC_UPDATE_CONTROL = 0x0000FF00; + dmc->PHY_UPDATE_CONTROL = 0x15A3925F; + dmc->PHY_MASTER_CONTROL = 0x6875AF9A; + dmc->LOW_POWER_CONTROL = 0x000E0801; + dmc->PMU_QE_CONTROL = 0x00000C0D; + dmc->PMU_QE_MUX = 0x05670023; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_0 = 0x000000F1; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_0 = 0x00000662; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_1 = 0x000000DD; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_1 = 0x00000097; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MASK_2 = 0x0000001A; + dmc->PMU_QOS_ENGINE_ATTRIBUTE_MATCH_2 = 0x00000755; + dmc->PMU_QUEUED_ENTRIES_ATTRIBUTE_MASK = 0xAD625ED5; + dmc->PMU_QUEUED_ENTRIES_ATTRIBUTE_MATCH = 0x853C65BB; + dmc->MI_INTERRUPT_CONTROL = 0x00000000; + dmc->POWER_DOWN_CONTROL = 0x00000005; + dmc->REFRESH_CONTROL = 0x00000000; + dmc->PMU_MI_CONTROL = 0x00000100; + dmc->PMU_MEMORY_IF_ATTRIBUTE_MASK_0 = 0x0032BB0E; + dmc->PMU_MEMORY_IF_ATTRIBUTE_MATCH_0 = 0x0033F5AB; + dmc->PMU_MEMORY_IF_ATTRIBUTE_MASK_1 = 0x00296B28; + dmc->PMU_MEMORY_IF_ATTRIBUTE_MATCH_1 = 0x002C67BF; + dmc->PMU_BANK_STATES_ATTRIBUTE_MASK = 0x00000005; + dmc->PMU_BANK_STATES_ATTRIBUTE_MATCH = 0x00000019; + dmc->PMU_RANK_STATES_ATTRIBUTE_MASK = 0x0000001B; + dmc->PMU_RANK_STATES_ATTRIBUTE_MATCH = 0x00000020; + dmc->CFG_INTERRUPT_CONTROL = 0x00000000; + dmc->T_RDDATA_EN = 0x00000001; + dmc->T_PHYRDLAT = 0x0000003F; + dmc->T_PHYWRLAT = 0x010F170E; + dmc->ERR_RAMECC_CTLR = 0x00000000; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Setting PHY-related settings\n"); + + dmc->PHY_POWER_CONTROL = 0x0000012A; + dmc->T_PHY_TRAIN = 0x00F8000A; + dmc->PHYUPD_INIT = 0x00000000; + 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; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Doing direct DDR commands\n"); + + 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; + dmc->REFRESH_ENABLE = 0x00000001; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Setting dmc in READY mode\n"); + + status = timer_api->time_to_timestamp(module_config->timer_id, + TIMEOUT_DMC_INIT_US, &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 = 0x00000000; + dmc->QUEUE_STATE_CONTROL = 0x00000000; + dmc->SI0_SI_STATE_CONTROL = 0x00000000; + dmc->SI1_SI_STATE_CONTROL = 0x00000000; + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Waiting for Queue stall = 0...\n"); + + 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; + } + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Waiting for SI0 stall = 0...\n"); + + 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; + } + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] Waiting for SI1 stall = 0...\n"); + + 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; + } + + log_api->log(MOD_LOG_GROUP_DEBUG, "[DDR] DMC init done.\n"); + + return FWK_SUCCESS; + +timeout: + log_api->log(MOD_LOG_GROUP_ERROR, "[DDR] Timed out in DMC500 init.\n"); + + return FWK_E_TIMEOUT; +} |