aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h')
-rw-r--r--platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h503
1 files changed, 503 insertions, 0 deletions
diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h
new file mode 100644
index 0000000000..e84786d23c
--- /dev/null
+++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2019 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file syscounter_armv8-m_cntrl_drv.h
+ *
+ * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase
+ * Frame
+ *
+ * This System Counter is a 64-bit up-counter, generating the physical
+ * count for System Timer.
+ *
+ * Main features:
+ * - Enable/disable and Set/Get the 64-bit upcounter
+ * - 2 scaling registers for the 2 clock sources
+ * - These registers are used to pre-program the scaling values so
+ * that when hardware based clock switching is implemented there is no
+ * need to program the scaling increment value each time when clock is
+ * switched.
+ * - When counter scaling is enabled, ScaleVal is the value added to the
+ * Counter Count Value for every period of the counter as determined
+ * by 1/Frequency from the current operating frequency of the system
+ * counter (the “counter tick”).
+ * - ScaleVal is expressed as an unsigned fixed-point number with
+ * a 8 bit integer value and a 24-bit fractional value
+ * - Interrupt for error detection
+ * There are 2 possible reasons for error notification generation from
+ * the Counter:
+ * 1. Security attribute mismatch between register access and security
+ * attribute of the CONTROL frame
+ * 2. Address decode error within a given frame
+ *
+ */
+
+#ifndef __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__
+#define __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH 32u
+ /*!< Armv8-M System Counter Control registers bit width */
+
+#define SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL 0u
+ /*!< Armv8-M System Counter Control default counter init value */
+
+/**
+ * \brief Armv8-M System Counter Control scaling value
+ */
+struct syscounter_armv8_m_cntrl_scale_val_t {
+ uint32_t integer; /* 8 bit */
+ uint32_t fixed_point_fraction; /* 24 bit */
+};
+
+/**
+ * \brief Armv8-M System Counter Control scaling value macros *
+ * 8 bit integer and 24 bit fixed point fractional value
+ */
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX UINT8_MAX
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF 24u
+#define SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX \
+ ((1u << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF) - 1u)
+
+/**
+ * \brief Armv8-M System Counter Control device configuration structure
+ */
+struct syscounter_armv8_m_cntrl_dev_cfg_t {
+ const uint32_t base;
+ /*!< Armv8-M System Counter Control device base address */
+ struct syscounter_armv8_m_cntrl_scale_val_t scale0;
+ /*!< Default clock scaling value for Clock source 0 */
+ struct syscounter_armv8_m_cntrl_scale_val_t scale1;
+ /*!< Default clock scaling value for Clock source 1 */
+};
+
+/**
+ * \brief Armv8-M System Counter Control device data structure
+ */
+struct syscounter_armv8_m_cntrl_dev_data_t {
+ bool is_initialized;
+};
+
+/**
+ * \brief Armv8-M System Counter Control device structure
+ */
+struct syscounter_armv8_m_cntrl_dev_t {
+ const struct syscounter_armv8_m_cntrl_dev_cfg_t* const cfg;
+ /*!< Armv8-M System Counter Control configuration structure */
+ struct syscounter_armv8_m_cntrl_dev_data_t* const data;
+ /*!< Armv8-M System Counter Control data structure */
+};
+
+/**
+ * \brief Armv8-M System Counter Control error enumeration types
+ */
+enum syscounter_armv8_m_cntrl_error_t {
+ SYSCOUNTER_ARMV8_M_ERR_NONE = 0u,
+ SYSCOUNTER_ARMV8_M_ERR_INVALID = 1u,
+ SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG = 2u
+};
+
+/**
+ * \brief Armv8-M System Counter Control scaling number for each clock sources
+ */
+enum syscounter_armv8_m_cntrl_scale_nr_t {
+ SYSCOUNTER_ARMV8_M_SCALE_NR_0 = 0u,
+ /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK0 */
+ SYSCOUNTER_ARMV8_M_SCALE_NR_1 = 1u
+ /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK1 */
+};
+
+/**
+ * \brief Clock select values
+ */
+enum syscounter_armv8_m_cntrl_selclk_t {
+ SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID0 = 0u,
+ /*!< Clock select invalid value */
+ SYSCOUNTER_ARMV8_M_SELCLK_CLK0 = 1u,
+ /*!< Clock select clock source 0 */
+ SYSCOUNTER_ARMV8_M_SELCLK_CLK1 = 2u,
+ /*!< Clock select clock source 1 */
+ SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID1 = 3u
+ /*!< Clock select invalid value */
+};
+
+/**
+ * \brief Override counter enable condition for writing to CNTSCR registers
+ *
+ */
+enum syscounter_armv8_m_cntrl_cntscr_ovr_t {
+ SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED = 0u,
+ /*!< Scaling registers can be written only when counter is disabled */
+ SYSCOUNTER_ARMV8_M_CNTSCR_ALWAYS = 1u
+ /*!< CNTSCR can be written regardless of counter enabled or disabled */
+};
+
+/**
+ * \brief Initializes counter to a known default state, which is:
+ * - counter is enabled, so starts counting
+ * - interrupt is disabled
+ * - counter reset to default reset value
+ * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL
+ * - scaling is disabled
+ * - scaling registers are set to the set values:
+ * \ref struct syscounter_armv8_m_cntrl_dev_cfg_t
+ * Init should be called prior to any other process and
+ * it's the caller's responsibility to follow proper call order.
+ * More than one call results fall through.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Uninitializes counter to a known default state, which is:
+ * - counter is disabled, so stops counting
+ * - interrupt is disabled
+ * - counter reset to default reset value
+ * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL
+ * - scaling is disabled
+ * Init should be called prior to any other process and
+ * it's the caller's responsibility to follow proper call order.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_uninit(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables the counter, so counter starts counting
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_counter(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables the counter, so counter stops counting
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_counter(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls counter enable status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_enabled(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables Halt-On-Debug feature
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_halt_on_debug(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables Halt-On-Debug feature
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_halt_on_debug(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls Halt-On-Debug enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables scaling
+ * The used scaling register is depending on the used HW clock source.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_scale(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables scaling
+ * Counter count will be incremented by default 1 for each ticks.
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_scale(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls scaling enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_scale_enabled(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables interrupt
+ *
+ * There are 2 possible reasons for error notification generation from
+ * the Counter:
+ * 1. Security attribute mismatch between register access and security
+ * attribute of the CONTROL frame
+ * 2. Address decode error within a given frame
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_interrupt(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables interrupt
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_interrupt(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls interrupt enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_interrupt_enabled(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Enables PSLVERR output
+ *
+ * PSLVERR output signal on APB bus dynamically generated for the
+ * following error:
+ * For security attribute mismatch between register access and security
+ * attribute of the CONTROL frame
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_enable_pslverr(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Disables PSLVERR output
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_disable_pslverr(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls PSLVERR output enablement status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_pslverr_enabled(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Clears interrupt pending flag
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_clear_interrupt(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls Halt-On-Debug status
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if counter is halted, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Read counter value
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return 64 bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t syscounter_armv8_m_cntrl_get_counter_value(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Writes counter value
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] value 64 bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void syscounter_armv8_m_cntrl_set_counter_value(
+ struct syscounter_armv8_m_cntrl_dev_t* dev,
+ uint64_t value);
+
+/**
+ * \brief Polls whether scaling is implemented
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Polls whether HW based clock switching is implemented
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool syscounter_armv8_m_cntrl_is_clock_switching_implemented(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads which clock source is being used
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Clock source \ref enum syscounter_armv8_m_cntrl_selclk_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_selclk_t
+ syscounter_armv8_m_cntrl_get_clock_source(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads scaling register can be overriden anytime
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ *
+ * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+ syscounter_armv8_m_cntrl_get_override_cntscr(
+ struct syscounter_armv8_m_cntrl_dev_t* dev);
+
+/**
+ * \brief Reads scaling register
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] nr Index of scaling register to read
+ * \ref enum syscounter_armv8_m_cntrl_scale_nr_t
+ * \param[out] nr Pointer to structure to read the scale value
+ * \ref struct syscounter_armv8_m_cntrl_scale_val_t
+ *
+ * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_get_counter_scale_value(
+ struct syscounter_armv8_m_cntrl_dev_t* dev,
+ enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+ struct syscounter_armv8_m_cntrl_scale_val_t *val);
+
+/**
+ * \brief Writes scaling register
+ *
+ * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t
+ * \param[in] nr Index of scaling register to write
+ * \ref enum syscounter_armv8_m_cntrl_scale_nr_t
+ * \param[in] Scale value structure
+ * \ref struct syscounter_armv8_m_cntrl_scale_val_t
+ *
+ * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum syscounter_armv8_m_cntrl_error_t
+syscounter_armv8_m_cntrl_set_counter_scale_value(
+ struct syscounter_armv8_m_cntrl_dev_t* dev,
+ enum syscounter_armv8_m_cntrl_scale_nr_t nr,
+ struct syscounter_armv8_m_cntrl_scale_val_t val);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ */