aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ethosu_driver.h16
-rw-r--r--src/ethosu_driver.c43
-rw-r--r--src/ethosu_pmu.c2
3 files changed, 57 insertions, 4 deletions
diff --git a/include/ethosu_driver.h b/include/ethosu_driver.h
index 16f0a25..4089932 100644
--- a/include/ethosu_driver.h
+++ b/include/ethosu_driver.h
@@ -49,6 +49,8 @@ struct ethosu_driver
bool reserved;
volatile bool irq_triggered;
void *semaphore;
+ uint8_t clock_request;
+ uint8_t power_request;
};
struct ethosu_version_id
@@ -81,6 +83,12 @@ struct ethosu_version
struct ethosu_version_config cfg;
};
+enum ethosu_request_clients
+{
+ ETHOSU_PMU_REQUEST = 0,
+ ETHOSU_INFERENCE_REQUEST = 1,
+};
+
/******************************************************************************
* Variables
******************************************************************************/
@@ -169,6 +177,14 @@ struct ethosu_driver *ethosu_reserve_driver(void);
void ethosu_release_driver(struct ethosu_driver *drv);
/**
+ * Set clock and power request bits
+ */
+enum ethosu_error_codes set_clock_and_power_request(struct ethosu_driver *drv,
+ enum ethosu_request_clients client,
+ enum ethosu_clock_q_request clock_request,
+ enum ethosu_power_q_request power_request);
+
+/**
* Static inline for backwards-compatibility
*/
static inline int ethosu_invoke_v2(const void *custom_data_ptr,
diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c
index 442ea43..7b2a8ef 100644
--- a/src/ethosu_driver.c
+++ b/src/ethosu_driver.c
@@ -305,7 +305,8 @@ int ethosu_init_v4(struct ethosu_driver *drv,
return -1;
}
- if (ETHOSU_SUCCESS != ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE))
+ if (ETHOSU_SUCCESS !=
+ set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE))
{
LOG_ERR("Failed to disable clock-q & power-q for Ethos-U\n");
return -1;
@@ -417,7 +418,7 @@ int ethosu_invoke_v3(struct ethosu_driver *drv,
}
drv->status_error = false;
- ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
+ set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
ethosu_restore_pmu_config(&drv->dev);
npu_axi_init(drv);
}
@@ -489,7 +490,7 @@ int ethosu_invoke_v3(struct ethosu_driver *drv,
if (!drv->status_error && !drv->dev_power_always_on)
{
ethosu_save_pmu_counters(&drv->dev);
- ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
+ set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
}
return return_code;
@@ -620,7 +621,7 @@ static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv)
return -1;
}
- ethosu_set_clock_and_power(&drv->dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
+ set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
npu_axi_init(drv);
ethosu_restore_pmu_config(&drv->dev);
@@ -628,6 +629,40 @@ static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv)
return 0;
}
+enum ethosu_error_codes set_clock_and_power_request(struct ethosu_driver *drv,
+ enum ethosu_request_clients client,
+ enum ethosu_clock_q_request clock_request,
+ enum ethosu_power_q_request power_request)
+{
+ // Set clock request bit for client
+ if (clock_request == ETHOSU_CLOCK_Q_DISABLE)
+ {
+ drv->clock_request |= (1 << client);
+ }
+ else
+ {
+ drv->clock_request &= ~(1 << client);
+ }
+ // Get current clock request (ENABLE if both PMU and INFERENCE asks for clock request, else DISABLE)
+ clock_request = drv->clock_request == 0 ? ETHOSU_CLOCK_Q_ENABLE : ETHOSU_CLOCK_Q_DISABLE;
+
+ // Set power request bit for client
+ if (power_request == ETHOSU_CLOCK_Q_DISABLE)
+ {
+ drv->power_request |= (1 << client);
+ }
+ else
+ {
+ drv->power_request &= ~(1 << client);
+ }
+ // Get current power request (ENABLE if both PMU and INFERENCE asks for power request, else DISABLE)
+ power_request = drv->power_request == 0 ? ETHOSU_POWER_Q_ENABLE : ETHOSU_POWER_Q_DISABLE;
+ // Set clock and power
+ enum ethosu_error_codes ret = ethosu_set_clock_and_power(&drv->dev, clock_request, power_request);
+
+ return ret;
+}
+
static int handle_optimizer_config(struct ethosu_driver *drv, struct opt_cfg_s *opt_cfg_p)
{
struct ethosu_config cfg;
diff --git a/src/ethosu_pmu.c b/src/ethosu_pmu.c
index aef3255..a5143e2 100644
--- a/src/ethosu_pmu.c
+++ b/src/ethosu_pmu.c
@@ -90,6 +90,7 @@ void ETHOSU_PMU_Enable_v2(struct ethosu_driver *drv)
struct pmcr_r pmcr;
pmcr.word = drv->dev.pmcr;
pmcr.cnt_en = 1;
+ set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE);
ethosu_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr);
}
@@ -99,6 +100,7 @@ void ETHOSU_PMU_Disable_v2(struct ethosu_driver *drv)
struct pmcr_r pmcr;
pmcr.word = drv->dev.pmcr;
pmcr.cnt_en = 0;
+ set_clock_and_power_request(drv, ETHOSU_PMU_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
ethosu_write_reg_shadow(&drv->dev, NPU_REG_PMCR, pmcr.word, &drv->dev.pmcr);
}