aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Moberg <anton.moberg@arm.com>2020-12-21 09:37:18 +0100
committerAnton Moberg <anton.moberg@arm.com>2021-01-18 09:06:30 +0100
commit8d65b6f7a4a291d90e20c44bf8d81a37b865cbd2 (patch)
tree9392a1ec5f461aa16d30e037b7ed5d3b50aa20e1
parent033bb1bcbecd89734c64a84ccda4f12d6cedb8c0 (diff)
downloadethos-u-core-driver-8d65b6f7a4a291d90e20c44bf8d81a37b865cbd2.tar.gz
Added simplified driver setup
If NPU power is guaranteed always on parts of driver setup can be omitted to reduce the number of cycles required to setup the NPU drivers. By enabling dev_power_always_on, the setup cycles are reduced by approx. ~50%. (4462->2238 in prologue, 1167->642 in epilogue) Change-Id: I56d380c2571fedbc8888fb7c00fce0e4320f7fb7
-rw-r--r--include/ethosu_driver.h6
-rw-r--r--src/ethosu_driver.c54
2 files changed, 48 insertions, 12 deletions
diff --git a/include/ethosu_driver.h b/include/ethosu_driver.h
index 46f777a..d47b676 100644
--- a/include/ethosu_driver.h
+++ b/include/ethosu_driver.h
@@ -44,6 +44,7 @@ struct ethosu_driver
uint64_t fast_memory;
size_t fast_memory_size;
bool status_error;
+ bool dev_power_always_on;
};
struct ethosu_version_id
@@ -126,6 +127,11 @@ void ethosu_abort(void);
*/
void ethosu_irq_handler(void);
+/**
+ * Set Ethos-U power mode.
+ */
+void ethosu_set_power_mode(bool);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c
index 8bc927c..15326e3 100644
--- a/src/ethosu_driver.c
+++ b/src/ethosu_driver.c
@@ -150,11 +150,13 @@ struct opt_cfg_s
struct ethosu_driver ethosu_drv = {
.dev = {.base_address = NULL, .proto = 0, .pmccntr = {0}, .pmu_evcntr = {0, 0, 0, 0}, .pmu_evtypr = {0, 0, 0, 0}},
- .abort_inference = false,
- .status_error = false};
+ .abort_inference = false,
+ .status_error = false,
+ .dev_power_always_on = false};
// IRQ
static volatile bool irq_triggered = false;
+static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv);
void ethosu_irq_handler(void)
{
uint8_t irq_raised = 0;
@@ -177,7 +179,7 @@ void ethosu_irq_handler(void)
if (ethosu_status_has_error(&ethosu_drv.dev))
{
- (void)ethosu_soft_reset(&ethosu_drv.dev);
+ ethosu_soft_reset_and_restore(&ethosu_drv);
ethosu_drv.status_error = true;
}
}
@@ -253,6 +255,7 @@ int ethosu_init_v3(const void *base_address,
LOG_ERR("Failed reset of Ethos-U\n");
return -1;
}
+
ethosu_drv.status_error = false;
return return_code;
@@ -335,18 +338,21 @@ int ethosu_invoke_v2(const void *custom_data_ptr,
*fast_memory = ethosu_drv.fast_memory;
}
- // Only soft reset if securty state or privilege level needs changing
- if (ethosu_drv.dev.proto != ethosu_read_reg(&ethosu_drv.dev, NPU_REG_PROT))
+ if (!ethosu_drv.dev_power_always_on)
{
- if (ETHOSU_SUCCESS != ethosu_soft_reset(&ethosu_drv.dev))
+ if (ethosu_drv.dev.proto != ethosu_read_reg(&ethosu_drv.dev, NPU_REG_PROT))
{
- return -1;
+ if (ETHOSU_SUCCESS != ethosu_soft_reset(&ethosu_drv.dev))
+ {
+ return -1;
+ }
}
+ ethosu_set_clock_and_power(&ethosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
+ ethosu_restore_pmu_config(&ethosu_drv.dev);
+ npu_axi_init(&ethosu_drv);
}
ethosu_drv.status_error = false;
- 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_end)
{
@@ -411,7 +417,7 @@ int ethosu_invoke_v2(const void *custom_data_ptr,
}
}
- if (!ethosu_drv.status_error)
+ if (!ethosu_drv.status_error && !ethosu_drv.dev_power_always_on)
{
ethosu_save_pmu_counters(&ethosu_drv.dev);
ethosu_set_clock_and_power(&ethosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
@@ -425,6 +431,32 @@ void ethosu_abort(void)
ethosu_drv.abort_inference = true;
}
+void ethosu_set_power_mode(bool always_on)
+{
+ ethosu_drv.dev_power_always_on = always_on;
+
+ if (always_on)
+ {
+ npu_axi_init(&ethosu_drv);
+ }
+}
+
+static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv)
+{
+
+ if (ETHOSU_SUCCESS != ethosu_soft_reset(&drv->dev))
+ {
+ return -1;
+ }
+
+ ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
+
+ npu_axi_init(drv);
+ ethosu_restore_pmu_config(&drv->dev);
+
+ return 0;
+}
+
static int handle_optimizer_config(struct ethosu_driver *drv, struct opt_cfg_s *opt_cfg_p)
{
struct ethosu_config cfg;
@@ -583,8 +615,6 @@ static int handle_command_stream(struct ethosu_driver *drv,
return -1;
}
- npu_axi_init(drv);
-
/* Flush the cache if available on our CPU.
* The upcasting to uin32_t* is ok since the pointer never is dereferenced.
* The base_addr_size is null if invoking from prior to invoke_V2, in that case