aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2020-11-24 09:20:14 +0100
committerKristofer Jonsson <kristofer.jonsson@arm.com>2020-11-24 16:11:56 +0100
commitc6e7a1f7d75342b11093b058e0cf47e7a636f852 (patch)
tree724897623afd9d1d89283da6236fb6f15f560a0a
parent849cf69b01a6d226238882e28281c4285f0ddfbb (diff)
downloadethos-u-core-driver-c6e7a1f7d75342b11093b058e0cf47e7a636f852.tar.gz
Update handling of soft reset20.11
Change-Id: Ia22b2934b4c85e3c480931c8b92608365351a877
-rw-r--r--include/ethosu_device.h2
-rw-r--r--src/ethosu_device.c35
-rw-r--r--src/ethosu_driver.c16
3 files changed, 37 insertions, 16 deletions
diff --git a/include/ethosu_device.h b/include/ethosu_device.h
index dd34201..eff9054 100644
--- a/include/ethosu_device.h
+++ b/include/ethosu_device.h
@@ -55,7 +55,7 @@ enum ethosu_error_codes
struct ethosu_device
{
volatile uint32_t *base_address;
- uint32_t reset;
+ uint32_t proto;
uint32_t pmcr;
uint32_t pmccntr[2];
uint32_t pmcnten;
diff --git a/src/ethosu_device.c b/src/ethosu_device.c
index adfdbb1..f8250bc 100644
--- a/src/ethosu_device.c
+++ b/src/ethosu_device.c
@@ -170,6 +170,7 @@ enum ethosu_error_codes ethosu_clear_irq_status(struct ethosu_device *dev)
cmd.clock_q_enable = oldcmd.clock_q_enable;
cmd.power_q_enable = oldcmd.power_q_enable;
ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+ LOG_DEBUG("CMD=0x%08x\n", cmd.word);
#else
UNUSED(dev);
#endif
@@ -187,23 +188,29 @@ enum ethosu_error_codes ethosu_soft_reset(struct ethosu_device *dev)
reset.pending_CPL = dev->privileged ? PRIVILEGE_LEVEL_PRIVILEGED : PRIVILEGE_LEVEL_USER;
reset.pending_CSL = dev->secure ? SECURITY_LEVEL_SECURE : SECURITY_LEVEL_NON_SECURE;
- prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
-
- if (prot.active_CPL < reset.pending_CPL && prot.active_CSL > reset.pending_CSL)
- {
- LOG_ERR("Failed to reset NPU\n");
- // Register access not permitted
- return ETHOSU_GENERIC_FAILURE;
- }
-
// Reset and set security level
+ LOG_INFO("Soft reset NPU\n");
ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
// Wait for reset to complete
return_code = ethosu_wait_for_reset(dev);
+ if (return_code != ETHOSU_SUCCESS)
+ {
+ LOG_ERR("Soft reset timed out\n");
+ return return_code;
+ }
+
+ // Verify that NPU has switched security state and privilege level
+ prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
+ if (prot.active_CPL != reset.pending_CPL || prot.active_CSL != reset.pending_CSL)
+ {
+ LOG_ERR("Failed to switch security state and privilege level\n");
+ // Register access not permitted
+ return ETHOSU_GENERIC_FAILURE;
+ }
// Save the prot register
- dev->reset = ethosu_read_reg(dev, NPU_REG_PROT);
+ dev->proto = ethosu_read_reg(dev, NPU_REG_PROT);
// Soft reset will clear the PMU configuration and counters. The shadow PMU counters
// are cleared by saving the PMU counters to ram, which will read back zeros.
@@ -277,6 +284,7 @@ enum ethosu_error_codes ethosu_set_qconfig(struct ethosu_device *dev, enum ethos
}
#if !defined(ARM_NPU_STUB)
ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
+ LOG_DEBUG("QCONFIG=0x%08x\n", memory_type);
#else
// NPU stubbed
UNUSED(dev);
@@ -324,6 +332,7 @@ enum ethosu_error_codes ethosu_set_axi_limit0(struct ethosu_device *dev,
axi_limit0.max_outstanding_write_m1 = max_writes - 1;
ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
+ LOG_DEBUG("AXI_LIMIT0=0x%08x\n", axi_limit0.word);
#else
// NPU stubbed
UNUSED(dev);
@@ -351,6 +360,7 @@ enum ethosu_error_codes ethosu_set_axi_limit1(struct ethosu_device *dev,
axi_limit1.max_outstanding_write_m1 = max_writes - 1;
ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
+ LOG_DEBUG("AXI_LIMIT1=0x%08x\n", axi_limit1.word);
#else
// NPU stubbed
UNUSED(dev);
@@ -378,6 +388,7 @@ enum ethosu_error_codes ethosu_set_axi_limit2(struct ethosu_device *dev,
axi_limit2.max_outstanding_write_m1 = max_writes - 1;
ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
+ LOG_DEBUG("AXI_LIMIT2=0x%08x\n", axi_limit2.word);
#else
// NPU stubbed
UNUSED(dev);
@@ -405,6 +416,7 @@ enum ethosu_error_codes ethosu_set_axi_limit3(struct ethosu_device *dev,
axi_limit3.max_outstanding_write_m1 = max_writes - 1;
ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
+ LOG_DEBUG("AXI_LIMIT3=0x%08x\n", axi_limit3.word);
#else
// NPU stubbed
UNUSED(dev);
@@ -479,6 +491,7 @@ enum ethosu_error_codes ethosu_clear_irq_history_mask(struct ethosu_device *dev,
cmd.power_q_enable = oldcmd.power_q_enable;
cmd.clear_irq_history = irq_history_clear_mask;
ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+ LOG_DEBUG("CMD=0x%08x\n", cmd.word);
#else
UNUSED(dev);
UNUSED(irq_history_clear_mask);
@@ -498,6 +511,7 @@ enum ethosu_error_codes ethosu_set_command_run(struct ethosu_device *dev)
cmd.clock_q_enable = oldcmd.clock_q_enable;
cmd.power_q_enable = oldcmd.power_q_enable;
ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+ LOG_DEBUG("CMD=0x%08x\n", cmd.word);
#else
UNUSED(dev);
#endif
@@ -537,6 +551,7 @@ enum ethosu_error_codes ethosu_set_clock_and_power(struct ethosu_device *dev,
cmd.clock_q_enable = clock_q;
cmd.power_q_enable = power_q;
ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+ LOG_DEBUG("CMD=0x%08x\n", cmd.word);
#else
UNUSED(dev);
UNUSED(clock_q);
diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c
index 3c9c55b..3b6ebcf 100644
--- a/src/ethosu_driver.c
+++ b/src/ethosu_driver.c
@@ -149,7 +149,7 @@ struct opt_cfg_s
******************************************************************************/
struct ethosu_driver ethosu_drv = {
- .dev = {.base_address = NULL, .reset = 0, .pmccntr = {0}, .pmu_evcntr = {0, 0, 0, 0}, .pmu_evtypr = {0, 0, 0, 0}},
+ .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};
@@ -356,13 +356,15 @@ int ethosu_invoke_v2(const void *custom_data_ptr,
*fast_memory = ethosu_drv.fast_memory;
}
- if (ethosu_drv.dev.reset != ethosu_read_reg(&ethosu_drv.dev, NPU_REG_PROT))
+ // 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_SUCCESS != ethosu_soft_reset(&ethosu_drv.dev))
{
return -1;
}
}
+
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);
@@ -575,8 +577,10 @@ static int handle_command_stream(struct ethosu_driver *drv,
const size_t *base_addr_size,
const int num_base_addr)
{
- uint32_t qread = 0;
- uint32_t cms_bytes = cms_length * BYTES_IN_32_BITS;
+ uint32_t qread = 0;
+ uint32_t cms_bytes = cms_length * BYTES_IN_32_BITS;
+ ptrdiff_t cmd_stream_ptr = (ptrdiff_t)cmd_stream;
+
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))
@@ -594,10 +598,12 @@ static int handle_command_stream(struct ethosu_driver *drv,
base_addr_invalid = true;
}
}
+
if (base_addr_invalid)
{
return -1;
}
+
npu_axi_init(drv);
/* Flush the cache if available on our CPU.
@@ -608,7 +614,7 @@ static int handle_command_stream(struct ethosu_driver *drv,
if (base_addr_size != NULL)
{
- ethosu_flush_dcache((uint32_t *)cmd_stream, cms_bytes);
+ ethosu_flush_dcache((uint32_t *)cmd_stream_ptr, cms_bytes);
for (int i = 0; i < num_base_addr; i++)
{
ethosu_flush_dcache((uint32_t *)base_addr[i], base_addr_size[i]);