blob: 35f79248fca71ddad7465405d4e9c64d9ad953e6 [file] [log] [blame]
/*
* Copyright (c) 2019-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#ifndef ETHOSU_DEVICE_H
#define ETHOSU_DEVICE_H
/******************************************************************************
* Includes
******************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* Defines
******************************************************************************/
#define ETHOSU_DRIVER_VERSION_MAJOR 0 ///< Driver major version
#define ETHOSU_DRIVER_VERSION_MINOR 16 ///< Driver minor version
#define ETHOSU_DRIVER_VERSION_PATCH 0 ///< Driver patch version
#define ETHOSU_DRIVER_BASEP_INDEXES 8 ///< Number of base pointer indexes
#ifndef ETHOSU_PMU_NCOUNTERS
#define ETHOSU_PMU_NCOUNTERS 4
#endif
/******************************************************************************
* Types
******************************************************************************/
enum ethosu_error_codes
{
ETHOSU_SUCCESS = 0, ///< Success
ETHOSU_GENERIC_FAILURE = -1, ///< Generic failure
ETHOSU_INVALID_PARAM = -2 ///< Invalid parameter
};
struct ethosu_device
{
volatile uint32_t *base_address;
uint32_t proto;
uint32_t pmcr;
uint32_t pmccntr[2];
uint32_t pmcnten;
uint32_t pmint;
uint32_t pmccntr_cfg;
uint32_t pmu_evcntr[ETHOSU_PMU_NCOUNTERS];
uint32_t pmu_evtypr[ETHOSU_PMU_NCOUNTERS];
uint32_t secure;
uint32_t privileged;
};
struct ethosu_id
{
uint32_t version_status; ///< Version status
uint32_t version_minor; ///< Version minor
uint32_t version_major; ///< Version major
uint32_t product_major; ///< Product major
uint32_t arch_patch_rev; ///< Architecture version patch
uint32_t arch_minor_rev; ///< Architecture version minor
uint32_t arch_major_rev; ///< Architecture version major
};
struct ethosu_config
{
struct
{
uint32_t macs_per_cc; ///< MACs per clock cycle
uint32_t cmd_stream_version; ///< NPU command stream version
uint32_t shram_size; ///< SHRAM size
uint32_t custom_dma; ///< Custom DMA enabled
};
};
/**
* Memory type parameter for set_regioncfg_reg:
* Counter{0,1}: Outstanding transactions for
* AXI port 0 for memory type/region a=0,b=1
* Counter{2,3}: Outstanding transactions for
* AXI port 1 for memory type/region a=2,b=3
*/
enum ethosu_memory_type
{
ETHOSU_AXI0_OUTSTANDING_COUNTER0 = 0, ///< NPU axi0_outstanding_counter0
ETHOSU_AXI0_OUTSTANDING_COUNTER1 = 1, ///< NPU axi0_outstanding_counter1
ETHOSU_AXI1_OUTSTANDING_COUNTER2 = 2, ///< NPU axi1_outstanding_counter2
ETHOSU_AXI1_OUTSTANDING_COUNTER3 = 3 ///< NPU axi1_outstanding_counter3
};
enum ethosu_axi_limit_beats
{
ETHOSU_AXI_LIMIT_64_BYTES = 0, ///< NPU AXI limit 64 byte burst split alignment.
ETHOSU_AXI_LIMIT_128_BYTES = 1, ///< NPU AXI limit 128 byte burst split alignment.
ETHOSU_AXI_LIMIT_256_BYTES = 2 ///< NPU AXI limit 256 byte burst split alignment.
};
enum ethosu_axi_limit_mem_type
{
ETHOSU_MEM_TYPE_DEVICE_NON_BUFFERABLE = 0,
ETHOSU_MEM_TYPE_DEVICE_BUFFERABLE = 1,
ETHOSU_MEM_TYPE_NORMAL_NON_CACHEABLE_NON_BUFFERABLE = 2,
ETHOSU_MEM_TYPE_NORMAL_NON_CACHEABLE_BUFFERABLE = 3,
ETHOSU_MEM_TYPE_WRITE_THROUGH_NO_ALLOCATE = 4,
ETHOSU_MEM_TYPE_WRITE_THROUGH_READ_ALLOCATE = 5,
ETHOSU_MEM_TYPE_WRITE_THROUGH_WRITE_ALLOCATE = 6,
ETHOSU_MEM_TYPE_WRITE_THROUGH_READ_AND_WRITE_ALLOCATE = 7,
ETHOSU_MEM_TYPE_WRITE_BACK_NO_ALLOCATE = 8,
ETHOSU_MEM_TYPE_WRITE_BACK_READ_ALLOCATE = 9,
ETHOSU_MEM_TYPE_WRITE_BACK_WRITE_ALLOCATE = 10,
ETHOSU_MEM_TYPE_WRITE_BACK_READ_AND_WRITE_ALLOCATE = 11
};
enum ethosu_clock_q_request
{
ETHOSU_CLOCK_Q_DISABLE = 0, ///< Disble NPU signal ready for clock off.
ETHOSU_CLOCK_Q_ENABLE = 1 ///< Enable NPU signal ready for clock off when stop+idle state reached.
};
enum ethosu_power_q_request
{
ETHOSU_POWER_Q_DISABLE = 0, ///< Disble NPU signal ready for power off.
ETHOSU_POWER_Q_ENABLE = 1 ///< Enable NPU signal ready for power off when stop+idle state reached.
};
/******************************************************************************
* Prototypes
******************************************************************************/
/**
* Initialize the device.
*/
enum ethosu_error_codes ethosu_dev_init(struct ethosu_device *dev,
const void *base_address,
uint32_t secure_enable,
uint32_t privilege_enable);
/**
* Get device id.
*/
enum ethosu_error_codes ethosu_get_id(struct ethosu_device *dev, struct ethosu_id *id);
/**
* Get device configuration.
*/
enum ethosu_error_codes ethosu_get_config(struct ethosu_device *dev, struct ethosu_config *config);
/**
* Execute a given command stream on NPU.
* \param[in] cmd_stream_ptr Pointer to the command stream
* \param[in] cms_length Command stream length
* \param[in] base_addr Pointer to array of base addresses
* - 0: weight tensor
* - 1: scratch tensor
* - All input tensors
* - All output tensors
* \param[in] num_base_addr Number of base addresses.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
const uint8_t *cmd_stream_ptr,
uint32_t cms_length,
const uint64_t *base_addr,
int num_base_addr);
/**
* Check if IRQ is raised.
* \param[out] irq_status Pointer to IRQ status
* - 0 IRQ not raised
* - 1 IRQ raised
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_is_irq_raised(struct ethosu_device *dev, uint8_t *irq_status);
/**
* Clear IRQ status.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev);
/**
* Get the 16 bit status mask.
* \param[out] irq_status_mask Pointer to the status mask.
* The lower 16 bits of status reg are returned.
* bit0: state
* bit1: irq_raised
* bit2: bus_status
* bit3: reset_status
* bit4: cmd_parse_error
* bit5: cmd_end_reached
* bit6: pmu_irq_raised
* bit7-15: reserved
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_get_status_mask(struct ethosu_device *dev, uint16_t *status_mask);
/**
* Get the 16 bit IRQ history mask.
* \param[out] irq_history_mask Pointer to the IRQ history mask.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_get_irq_history_mask(struct ethosu_device *dev, uint16_t *irq_history_mask);
/**
* Clear the given bits in the
* IRQ history mask.
* \param[in] irq_history_clear_mask 16 bit mask indicating which bits to
* clear in the IRQ history mask.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_clear_irq_history_mask(struct ethosu_device *dev, uint16_t irq_history_clear_mask);
/**
* Perform a NPU soft reset.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev);
/**
* Wait for reset ready.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_wait_for_reset(struct ethosu_device *dev);
/**
* Read and return the content of a given NPU APB
* register range.
* \param[in] start_address Start address.
* \param[in] num_reg Number of registers to read.
* \param[out] reg_p Pointer to a output area, allocated by the
* caller, where the register content shall be
* written.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_read_apb_reg(struct ethosu_device *dev,
uint32_t start_address,
uint16_t num_reg,
uint32_t *reg_p);
/**
* Set qconfig register. I.e.
* AXI configuration for the command stream.
* \param[in] memory_type Memory_type to use for command stream:
* enum ethosu_memory_type.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethosu_memory_type memory_type);
/**
* Set register REGIONCFG.
* Base pointer configuration.
* Bits[2*k+1:2*k] give the memory type for BASEP[k].
* \param[in] region Region field to set: 0 - 7.
* \param[in] memory_type Memory_type to use for region: enum ethosu_memory_type.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
uint8_t region,
enum ethosu_memory_type memory_type);
/**
* Set AXI limit parameters for port 0 counter 0.
* \param[in] max_beats Burst split alignment, \ref ethosu_axi_limit_beats.
* \param[in] memtype Cache policy \ref ethosu_axi_limit_mem_type
* \param[in] max_reads Maximum number of outstanding reads.
* \param[in] max_writes Maximum number of outstanding writes.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_axi_limit0(struct ethosu_device *dev,
enum ethosu_axi_limit_beats max_beats,
enum ethosu_axi_limit_mem_type memtype,
uint8_t max_reads,
uint8_t max_writes);
/**
* Set AXI limit parameters for port 0 counter 1.
* \param[in] max_beats Burst split alignment, \ref ethosu_axi_limit_beats.
* \param[in] memtype Cache policy \ref ethosu_axi_limit_mem_type
* \param[in] max_reads Maximum number of outstanding reads.
* \param[in] max_writes Maximum number of outstanding writes.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
enum ethosu_axi_limit_beats max_beats,
enum ethosu_axi_limit_mem_type memtype,
uint8_t max_reads,
uint8_t max_writes);
/**
* Set AXI limit parameters for port 1 counter 2.
* \param[in] max_beats Burst split alignment, \ref ethosu_axi_limit_beats.
* \param[in] memtype Cache policy \ref ethosu_axi_limit_mem_type
* \param[in] max_reads Maximum number of outstanding reads.
* \param[in] max_writes Maximum number of outstanding writes.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
enum ethosu_axi_limit_beats max_beats,
enum ethosu_axi_limit_mem_type memtype,
uint8_t max_reads,
uint8_t max_writes);
/**
* Set AXI limit parameters for port 1 counter 3.
* \param[in] max_beats Burst split alignment, \ref ethosu_axi_limit_beats.
* \param[in] memtype Cache policy \ref ethosu_axi_limit_mem_type
* \param[in] max_reads Maximum number of outstanding reads.
* \param[in] max_writes Maximum number of outstanding writes.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
enum ethosu_axi_limit_beats max_beats,
enum ethosu_axi_limit_mem_type memtype,
uint8_t max_reads,
uint8_t max_writes);
/**
* Get current command stream queue read position.
* \param[out] qread Pointer to queue read.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_get_qread(struct ethosu_device *dev, uint32_t *qread);
/**
* Get revision of NPU
* \param[out] revision Pointer to revision read.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_get_revision(struct ethosu_device *dev, uint32_t *revision);
/**
* Issue run command for the currently programmed
* command stream, starting at current queue read
* position.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev);
/**
* Dump a 1KB section of SHRAM.
* \param[in] section Section offset to 1KB section in SHRAM.
* \param[out] shram_p Pointer to a output area, allocated by the
* caller, where the SHRAM content shall be
* written.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_get_shram_data(struct ethosu_device *dev, int section, uint32_t *shram_p);
/**
* Set clock and power q request enable bits.
* \param[in] clock_q Clock q ENABLE/DISABLE \ref clock_q_request.
* \param[in] power_q Power q ENABLE/DISABLE \ref power_q_request.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
enum ethosu_clock_q_request clock_q,
enum ethosu_power_q_request power_q);
/**
* Read register.
* \param[in] address Address to read.
* \return Register value.
*/
uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address);
/**
* Write register.
* \param[in] address Address to read.
* \param[in] value Value to be written.
*/
void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value);
/**
* Write register with shadow variable.
* \param[in] address Address to read.
* \param[in] value Value to be written.
*/
void ethosu_write_reg_shadow(struct ethosu_device *dev, uint32_t address, uint32_t value, uint32_t *shadow);
/**
* Save the PMU configuration to ethosu_device struct.
* \param[in] dev Ethos-U device where the PMU configuration is
* saved.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev);
/**
* Restore the PMU configuration from a ethosu_device struct.
* \param[in] dev Ethos-U device where the PMU configuration is
* stored.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev);
/**
* Save PMU counters to shadow variables in memory.
* \param[in] dev Ethos-U device where the PMU configuration is
* stored.
* \return \ref ethosu_error_codes
*/
enum ethosu_error_codes ethosu_save_pmu_counters(struct ethosu_device *dev);
/**
* Check if the STATUS register has any error bits set or not.
* \param[in] dev Ethos-U device to check.
* \return true if any error bits set,
* false otherwise.
*/
bool ethosu_status_has_error(struct ethosu_device *dev);
#ifdef __cplusplus
}
#endif
#endif // ETHOSU_DEVICE_H