diff options
-rw-r--r-- | include/ethosu_driver.h | 16 | ||||
-rw-r--r-- | src/ethosu_driver.c | 43 | ||||
-rw-r--r-- | src/ethosu_pmu.c | 2 |
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); } |