aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2020-08-20 16:52:23 +0200
committerKristofer Jonsson <kristofer.jonsson@arm.com>2020-08-24 11:29:32 +0200
commit125429a1c089775b05d4d13739ee7fc72285079f (patch)
treee24a0310ef37ac93ebd624d2eb31afb0e6f1cab0 /src
parente2e70241aa9bb11093222d07b83176ebafeddae1 (diff)
downloadethos-u-core-driver-125429a1c089775b05d4d13739ee7fc72285079f.tar.gz
Base pointer offset and soft reset
Allow user to define a base pointer offset, if the CPU and the NPU have address spaces offseted from each other. Soft reset NPU before every inference. Added log prints. Change-Id: I98a746d20dc780fefa23ad68816f5ba2ba2e6c6e
Diffstat (limited to 'src')
-rw-r--r--src/ethosu_config.h8
-rw-r--r--src/ethosu_device.c34
-rw-r--r--src/ethosu_driver.c14
3 files changed, 38 insertions, 18 deletions
diff --git a/src/ethosu_config.h b/src/ethosu_config.h
index 07eb824..91fe660 100644
--- a/src/ethosu_config.h
+++ b/src/ethosu_config.h
@@ -108,6 +108,14 @@
#define AXI_LIMIT3_MAX_OUTSTANDING_WRITES 16
#endif
+/*
+ * Address offset between the CPU and the NPU. The offset is
+ * applied to the QBASE and BASEP registers.
+ */
+#ifndef BASE_POINTER_OFFSET
+#define BASE_POINTER_OFFSET 0
+#endif
+
#ifdef PMU_AUTOINIT
/*
* Register control
diff --git a/src/ethosu_device.c b/src/ethosu_device.c
index 60fc243..404a0e7 100644
--- a/src/ethosu_device.c
+++ b/src/ethosu_device.c
@@ -17,6 +17,7 @@
*/
#include "ethosu_device.h"
#include "ethosu_common.h"
+#include "ethosu_config.h"
#include <assert.h>
#include <stddef.h>
@@ -26,6 +27,9 @@
#define REG_OFFSET 4
#define BYTES_1KB 1024
+#define ADDRESS_BITS 48
+#define ADDRESS_MASK ((1ull << ADDRESS_BITS) - 1)
+
#if defined(ARM_NPU_STUB)
static uint32_t stream_length = 0;
#endif
@@ -93,29 +97,24 @@ enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev,
enum ethosu_error_codes ret_code = ETHOSU_SUCCESS;
#if !defined(ARM_NPU_STUB)
- uint32_t qbase0;
- uint32_t qbase1;
- uint32_t qsize;
- uint32_t *reg_basep;
- int num_base_reg;
-
ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES);
- qbase0 = ((uint64_t)cmd_stream_ptr) & MASK_0_31_BITS;
- qbase1 = (((uint64_t)cmd_stream_ptr) & MASK_32_47_BITS) >> 32;
- qsize = cms_length;
- num_base_reg = num_base_addr * 2;
- reg_basep = (uint32_t *)base_addr;
+ uint64_t qbase = (uint64_t)cmd_stream_ptr + BASE_POINTER_OFFSET;
+ ASSERT(qbase <= ADDRESS_MASK);
+ LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET);
+ ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff);
+ ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32);
+ ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length);
- for (int i = 0; i < num_base_reg; i++)
+ for (int i = 0; i < num_base_addr; i++)
{
- ethosu_write_reg(dev, NPU_REG_BASEP0 + (i * BASEP_OFFSET), reg_basep[i]);
+ uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET;
+ ASSERT(addr <= ADDRESS_MASK);
+ LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr);
+ ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff);
+ ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32);
}
- ethosu_write_reg(dev, NPU_REG_QBASE0, qbase0);
- ethosu_write_reg(dev, NPU_REG_QBASE1, qbase1);
- ethosu_write_reg(dev, NPU_REG_QSIZE, qsize);
-
ret_code = ethosu_set_command_run(dev);
#else
// NPU stubbed
@@ -282,6 +281,7 @@ enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev,
regioncfg.word &= ~(0x3 << (2 * region));
regioncfg.word |= (memory_type & 0x3) << (2 * region);
ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word);
+ LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word);
#else
// NPU stubbed
UNUSED(dev);
diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c
index 9d74980..f47d3f2 100644
--- a/src/ethosu_driver.c
+++ b/src/ethosu_driver.c
@@ -43,10 +43,20 @@ static volatile bool irq_triggered = false;
void ethosu_irq_handler(void)
{
uint8_t irq_raised = 0;
+
+ LOG_DEBUG("Interrupt. status=0x%08x, qread=%d\n",
+ ethosu_read_reg(&ethosu_drv.dev, NPU_REG_STATUS),
+ ethosu_read_reg(&ethosu_drv.dev, NPU_REG_QREAD));
+
+ // Verify that interrupt has been raised
(void)ethosu_is_irq_raised(&ethosu_drv.dev, &irq_raised);
ASSERT(irq_raised == 1);
irq_triggered = true;
+
+ // Clear interrupt
(void)ethosu_clear_irq_status(&ethosu_drv.dev);
+
+ // Verify that interrupt has been successfully cleard
(void)ethosu_is_irq_raised(&ethosu_drv.dev, &irq_raised);
ASSERT(irq_raised == 0);
}
@@ -280,8 +290,10 @@ int ethosu_invoke(const void *custom_data_ptr,
}
int custom_data_32bit_size = (custom_data_size / BYTES_IN_32_BITS - CUSTOM_OPTION_LENGTH_32_BIT_WORD);
+ ethosu_soft_reset(&ethosu_drv.dev);
ethosu_set_clock_and_power(&ethosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
ethosu_restore_pmu_config(&ethosu_drv.dev);
+
while (data_ptr < (data_start_ptr + custom_data_32bit_size))
{
int ret = 0;
@@ -464,7 +476,7 @@ static int handle_command_stream(struct ethosu_driver *drv,
{
uint32_t qread = 0;
uint32_t cms_bytes = cms_length * BYTES_IN_32_BITS;
- LOG_INFO("handle_command_stream cms_length %d\n", cms_length);
+ LOG_INFO("handle_command_stream: cmd_stream=%p, cms_length %d\n", cmd_stream, cms_length);
if (0 != ((ptrdiff_t)cmd_stream & MASK_16_BYTE_ALIGN))
{