aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Moberg <anton.moberg@arm.com>2021-03-24 14:08:22 +0100
committerAnton Moberg <anton.moberg@arm.com>2021-04-12 10:01:52 +0200
commit0a6142904a712a1f1c9ce16bb364c3e9d2434dd2 (patch)
tree19a72b883f5c765528d853bb515fecb514c75d50
parentdfed5fd24699246811300a05ebc421a978e52149 (diff)
downloadethos-u-core-driver-0a6142904a712a1f1c9ce16bb364c3e9d2434dd2.tar.gz
Clock request disabled when PMU enabled
Currently clock request is enabled, which means NPU will only request clock when working. When NPU is going into idle it will no longer request clock and thus PMU won't be clocked either, and thus affect the cycle counter. Added: enum for request clients (PMU or INFERENCE). Added: clock_request added to driver struct (bit 0: PMU, bit 1: INFERENCE) which keeps track of which client requests clock. Added: power_request added to driver struct (bit 0: PMU, bit 1: INFERENCE) which keeps track of which client requests power. Added set_clock_and_power_request(...) updates clock_request and power_request depending on which client calls it. Sets clock and power if both PMU and INFERENCE requests it. Added: Call set_clock_and_power_request(...) from PMU. Changed: replace ethosu_set_clock_and_power(...) with set_clock_and_power_request(...) in ethosu_init and ethosu_invoke Change-Id: Ie7d8aee639d4abbf879b05e9a82035d7c0d40d40
-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);
}