aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h')
-rw-r--r--platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h411
1 files changed, 411 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h
new file mode 100644
index 0000000000..d14d2f79e2
--- /dev/null
+++ b/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h
@@ -0,0 +1,411 @@
+/*
+ * 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 systimer_armv8-m_drv.h
+ *
+ * \brief Driver for Armv8-M System Timer
+ *
+ * This System Timer is based on the 64-bit Armv8-M System Counter,
+ * generating the physical count for System Timer.
+ *
+ * Main features:
+ * - Disabling the timer doesn't stop counting, but it disables timer output
+ * signal, what might be a power saving option.
+ * - 1 interrupt signal, can be triggered by the 2 modes below
+ * Modes:
+ * 1. Normal mode
+ * For clearing the interrupt generated by normal mode, the Timer
+ * should be disabled.
+ * Views
+ * 1.1. 64-bit up-counting Compare view
+ * As soon as the physical up-counter reaches the set
+ * compare value, the interrupt status will be asserted.
+ * \ref systimer_armv8_m_set_compare_value
+ * \ref systimer_armv8_m_get_compare_value
+
+ * 1.2. 32-bit down-counting Timer view
+ * As soon as the down-counter timer reaches zero,
+ * the interrupt status will be asserted.
+ * Setting the down-counter timer value, sets the compare
+ * register by
+ * compare register = current counter + timer value
+ * \ref systimer_armv8_m_set_timer_value
+ * \ref systimer_armv8_m_get_timer_value
+ *
+ * 2. Auto-Increment mode
+ * - The auto-increment feature allows generation of Timer
+ * interrupt at regular intervals without the need for
+ * reprogramming the Timer after each interrupt and re-enabling
+ * the timer logic.
+ * - Auto-increment is working as a 64-bit up-counter, which is set
+ * by the 32-bit reload register.
+ * - If auto-increment mode is enabled, none of the normal modes'
+ * views can assert interrupt. *
+ * \ref systimer_armv8_m_get_autoinc_value
+ * \ref systimer_armv8_m_set_autoinc_reload
+ * \ref systimer_armv8_m_enable_autoinc
+ * \ref systimer_armv8_m_disable_autoinc
+ * \ref systimer_armv8_m_is_autoinc_enabled
+ * \ref systimer_armv8_m_clear_autoinc_interrupt
+ * \ref systimer_armv8_m_is_autoinc_implemented
+ *
+ */
+
+#ifndef __SYSTIMER_ARMV8_M_DRV_H__
+#define __SYSTIMER_ARMV8_M_DRV_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH 32u
+ /*!< Armv8-M System Timer registers bit width */
+
+/**
+ * \brief Armv8-M System Timer device configuration structure
+ */
+struct systimer_armv8_m_dev_cfg_t {
+ const uint32_t base;
+ /*!< Armv8-M System Timer device base address */
+ uint32_t default_freq_hz;
+ /*!< Default reported frequency in Hz */
+};
+
+/**
+ * \brief Armv8-M System Timer device data structure
+ */
+struct systimer_armv8_m_dev_data_t {
+ bool is_initialized;
+};
+
+/**
+ * \brief Armv8-M System Timer device structure
+ */
+struct systimer_armv8_m_dev_t {
+ const struct systimer_armv8_m_dev_cfg_t* const cfg;
+ /*!< Armv8-M System Timer configuration structure */
+ struct systimer_armv8_m_dev_data_t* const data;
+ /*!< Armv8-M System Timer data structure */
+};
+
+/**
+ * \brief Initializes timer to a known default state, which is:
+ * - timer is enabled
+ * - interrupt is disabled
+ * - auto-increment is disabled
+ * - reported timer frequency is set to default
+ * 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 Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Uninitializes timer to a known default state, which is:
+ * - timer is disabled
+ * - interrupt is disabled
+ * - auto-increment is disabled
+ * 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 Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Reads 64-bit physical counter value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit counter value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_counter_value(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 64-bit compare value
+ * As soon as the physical up-counter reaches this value, the interrupt
+ * condition will be asserted \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 64-bit compare value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_compare_value(
+ struct systimer_armv8_m_dev_t* dev,
+ uint64_t value);
+
+/**
+ * \brief Reads 64-bit compare value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit compare value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_compare_value(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets frequency register in Hz
+ * Hardware does not interpret the value of the register, so it's only
+ * for software can discover the frequency of the system counter.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value frequency in Hz
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_counter_freq(
+ struct systimer_armv8_m_dev_t* dev,
+ uint32_t value);
+
+/**
+ * \brief Reads frequency register in Hz
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return frequency in Hz
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_counter_freq(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 32-bit down-counter timer value
+ * 'Down-counter timer set' automatically sets the compare register by
+ * compare register = current counter + this timer value
+ *
+ * As soon as the timer value reaches zero, the interrupt condition will
+ * be asserted \ref systimer_armv8_m_is_interrupt_asserted.
+ * Reaching zero doesn't stop the timer.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 32-bit timer value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev,
+ uint32_t value);
+
+/**
+ * \brief Reads down-counter timer value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 32-bit timer value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_timer_value(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables timer
+ * Enables timer output signal and interrupt status assertion
+ * \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables timer
+ * Disables timer output signal. Interrupt status will be unknown
+ * \ref systimer_armv8_m_is_interrupt_asserted
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_timer_enabled(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables timer interrupt
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_interrupt(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables timer interrupt
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_interrupt(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer interrupt enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_interrupt_enabled(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls timer interrupt status
+ * It's asserted if
+ * 1. Auto-Inc is disabled and counter reaches compare value
+ * OR
+ * 2. Auto-Inc is enabled and counter reaches auto-inc value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if asserted, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_interrupt_asserted(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Reads auto-increment value
+ * This value is automatically calculated by
+ * auto-inc = current counter + auto-inc reload
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 64-bit auto-increment value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint64_t systimer_armv8_m_get_autoinc_value(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Sets 32-bit auto-increment reload value
+ * Auto-Inc value is automatically calculated by adding this reload value
+ * to the current counter.
+ * If the counter reaches auto-inc value, interrupt status is asserted
+ * and auto-inc value is automatically set by current reload.
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ * \param[in] value 32-bit reload value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_set_autoinc_reload(
+ struct systimer_armv8_m_dev_t* dev,
+ uint32_t value);
+
+/**
+ * \brief Reads auto-increment reload value
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return 32-bit auto-increment reload value
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t systimer_armv8_m_get_autoinc_reload(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Enables auto-increment mode
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Disables auto-increment mode
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls auto-increment enable status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if enabled, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_autoinc_enabled(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Clears auto-increment mode interrupt flag
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void systimer_armv8_m_clear_autoinc_interrupt(
+ struct systimer_armv8_m_dev_t* dev);
+
+/**
+ * \brief Polls auto-increment implementation status
+ *
+ * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t
+ *
+ * \return true if implemented, false otherwise
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+bool systimer_armv8_m_is_autoinc_implemented(
+ struct systimer_armv8_m_dev_t* dev);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SYSTIMER_ARMV8_M_DRV_H__ */