summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWhi copybara merger <whitechapel-automerger@google.com>2022-05-02 15:20:48 +0530
committerCopybara-Service <copybara-worker@google.com>2022-05-10 17:46:31 -0700
commit92144428553ca6654e4e6f4e963f116244ecbb2a (patch)
tree8c67db4395ad075de6967f955351fc703b150340
parentaf622a86fc1cec1d75575c92d49b502d2be1cf21 (diff)
downloadjaneiro-92144428553ca6654e4e6f4e963f116244ecbb2a.tar.gz
[Copybara Auto Merge] Merge branch 'pro' into android13-gs-pixel-5.10
edgetpu: add support for all dvfs frequencies Bug: 230582743 edgetpu: fetch hw ctx region from device tree Bug: 230236668 GitOrigin-RevId: e60acf09440d62f96d1a047d2f70b76e0dbd6863 Change-Id: Id187c2635cc2de627bedf168c0fefb2f4a9411c2
-rw-r--r--drivers/edgetpu/edgetpu-core.c2
-rw-r--r--drivers/edgetpu/edgetpu-internal.h4
-rw-r--r--drivers/edgetpu/edgetpu-mobile-platform.c32
-rw-r--r--drivers/edgetpu/edgetpu-usage-stats.c87
-rw-r--r--drivers/edgetpu/edgetpu-usage-stats.h2
-rw-r--r--drivers/edgetpu/janeiro-platform.c28
6 files changed, 121 insertions, 34 deletions
diff --git a/drivers/edgetpu/edgetpu-core.c b/drivers/edgetpu/edgetpu-core.c
index b84d626..81c54a6 100644
--- a/drivers/edgetpu/edgetpu-core.c
+++ b/drivers/edgetpu/edgetpu-core.c
@@ -434,6 +434,8 @@ int edgetpu_device_add(struct edgetpu_dev *etdev,
etdev->vcid_pool = (1u << EDGETPU_NUM_VCIDS) - 1;
mutex_init(&etdev->state_lock);
etdev->state = ETDEV_STATE_NOFW;
+ etdev->freq_count = 0;
+ mutex_init(&etdev->freq_lock);
ret = edgetpu_fs_add(etdev, iface_params, num_ifaces);
if (ret) {
diff --git a/drivers/edgetpu/edgetpu-internal.h b/drivers/edgetpu/edgetpu-internal.h
index 122a3e7..37ea27f 100644
--- a/drivers/edgetpu/edgetpu-internal.h
+++ b/drivers/edgetpu/edgetpu-internal.h
@@ -226,6 +226,10 @@ struct edgetpu_dev {
/* debug dump handlers */
edgetpu_debug_dump_handlers *debug_dump_handlers;
struct work_struct debug_dump_work;
+
+ struct mutex freq_lock; /* protects below freq_* variables */
+ uint32_t *freq_table; /* Array to record reported frequencies by f/w */
+ uint32_t freq_count; /* Number of entries in freq_table */
};
struct edgetpu_dev_iface {
diff --git a/drivers/edgetpu/edgetpu-mobile-platform.c b/drivers/edgetpu/edgetpu-mobile-platform.c
index 4e9cac0..af6bcb7 100644
--- a/drivers/edgetpu/edgetpu-mobile-platform.c
+++ b/drivers/edgetpu/edgetpu-mobile-platform.c
@@ -279,6 +279,38 @@ static void edgetpu_platform_remove_irq(struct edgetpu_mobile_platform_dev *etmd
edgetpu_unregister_irq(etdev, etmdev->irq[i]);
}
+/*
+ * Fetch and set the firmware context region from device tree.
+ *
+ * Maybe be unused since not all chips need this.
+ */
+static int __maybe_unused
+edgetpu_mobile_platform_set_fw_ctx_memory(struct edgetpu_mobile_platform_dev *etmdev)
+{
+ struct edgetpu_dev *etdev = &etmdev->edgetpu_dev;
+ struct device *dev = etdev->dev;
+ struct resource r;
+ struct device_node *np;
+ int ret;
+
+ np = of_parse_phandle(dev->of_node, "memory-region", 1);
+ if (!np) {
+ etdev_warn(etdev, "No memory for firmware contexts");
+ return -ENODEV;
+ }
+
+ ret = of_address_to_resource(np, 0, &r);
+ of_node_put(np);
+ if (ret) {
+ etdev_warn(etdev, "No memory address for firmware contexts");
+ return ret;
+ }
+
+ etmdev->fw_ctx_paddr = r.start;
+ etmdev->fw_ctx_size = resource_size(&r);
+ return 0;
+}
+
static int edgetpu_mobile_platform_probe(struct platform_device *pdev,
struct edgetpu_mobile_platform_dev *etmdev)
{
diff --git a/drivers/edgetpu/edgetpu-usage-stats.c b/drivers/edgetpu/edgetpu-usage-stats.c
index 41d149d..ba93d49 100644
--- a/drivers/edgetpu/edgetpu-usage-stats.c
+++ b/drivers/edgetpu/edgetpu-usage-stats.c
@@ -13,16 +13,36 @@
#include "edgetpu-kci.h"
#include "edgetpu-usage-stats.h"
+/* Max number of frequencies to support */
+#define EDGETPU_MAX_STATES 10
+
struct uid_entry {
int32_t uid;
- uint64_t time_in_state[EDGETPU_NUM_STATES];
+ uint64_t time_in_state[EDGETPU_MAX_STATES];
struct hlist_node node;
};
-static int tpu_state_map(uint32_t state)
+static int tpu_state_map(struct edgetpu_dev *etdev, uint32_t state)
{
- int i;
+ int i, idx = 0;
+
+ mutex_lock(&etdev->freq_lock);
+ /* Use frequency table if f/w already reported via usage_stats */
+ if (etdev->freq_table) {
+ for (i = etdev->freq_count - 1; i >= 0; i--) {
+ if (state == etdev->freq_table[i])
+ idx = i;
+ }
+ mutex_unlock(&etdev->freq_lock);
+ return idx;
+ }
+
+ mutex_unlock(&etdev->freq_lock);
+ /*
+ * use predefined state table in case of no f/w reported supported
+ * frequencies.
+ */
for (i = (EDGETPU_NUM_STATES - 1); i >= 0; i--) {
if (state >= edgetpu_active_states[i])
return i;
@@ -49,7 +69,7 @@ int edgetpu_usage_add(struct edgetpu_dev *etdev, struct tpu_usage *tpu_usage)
{
struct edgetpu_usage_stats *ustats = etdev->usage_stats;
struct uid_entry *uid_entry;
- int state = tpu_state_map(tpu_usage->power_state);
+ int state = tpu_state_map(etdev, tpu_usage->power_state);
if (!ustats)
return 0;
@@ -186,6 +206,39 @@ static void edgetpu_thread_stats_update(
mutex_unlock(&ustats->usage_stats_lock);
}
+/* Record new supported frequencies if reported by firmware */
+static void edgetpu_dvfs_frequency_update(struct edgetpu_dev *etdev, uint32_t frequency)
+{
+ uint32_t *freq_table, i;
+
+ mutex_lock(&etdev->freq_lock);
+ if (!etdev->freq_table) {
+ freq_table = kvmalloc(EDGETPU_MAX_STATES * sizeof(uint32_t), GFP_KERNEL);
+ if (!freq_table) {
+ etdev_warn(etdev, "Unable to create supported frequencies table");
+ goto out;
+ }
+ etdev->freq_count = 0;
+ etdev->freq_table = freq_table;
+ }
+
+ freq_table = etdev->freq_table;
+
+ for (i = 0; i < etdev->freq_count; i++) {
+ if (freq_table[i] == frequency)
+ goto out;
+ }
+
+ if (etdev->freq_count >= EDGETPU_MAX_STATES) {
+ etdev_warn(etdev, "Unable to record supported frequencies");
+ goto out;
+ }
+
+ freq_table[etdev->freq_count++] = frequency;
+out:
+ mutex_unlock(&etdev->freq_lock);
+}
+
void edgetpu_usage_stats_process_buffer(struct edgetpu_dev *etdev, void *buf)
{
struct edgetpu_usage_header *header = buf;
@@ -221,6 +274,10 @@ void edgetpu_usage_stats_process_buffer(struct edgetpu_dev *etdev, void *buf)
edgetpu_thread_stats_update(
etdev, &metric->thread_stats);
break;
+ case EDGETPU_METRIC_TYPE_DVFS_FREQUENCY_INFO:
+ edgetpu_dvfs_frequency_update(
+ etdev, metric->dvfs_frequency_info);
+ break;
default:
etdev_dbg(etdev, "%s: %d: skip unknown type=%u",
__func__, i, metric->type);
@@ -294,9 +351,18 @@ static ssize_t tpu_usage_show(struct device *dev,
/* uid: state0speed state1speed ... */
ret += scnprintf(buf, PAGE_SIZE, "uid:");
- for (i = 0; i < EDGETPU_NUM_STATES; i++)
- ret += scnprintf(buf + ret, PAGE_SIZE - ret, " %d",
- edgetpu_states_display[i]);
+ mutex_lock(&etdev->freq_lock);
+ if (!etdev->freq_table) {
+ mutex_unlock(&etdev->freq_lock);
+ for (i = 0; i < EDGETPU_NUM_STATES; i++)
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, " %d",
+ edgetpu_states_display[i]);
+ } else {
+ for (i = 0; i < etdev->freq_count; i++)
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, " %d",
+ etdev->freq_table[i]);
+ mutex_unlock(&etdev->freq_lock);
+ }
ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
@@ -877,6 +943,13 @@ void edgetpu_usage_stats_exit(struct edgetpu_dev *etdev)
if (ustats) {
usage_stats_remove_uids(ustats);
device_remove_group(etdev->dev, &usage_stats_attr_group);
+ /* free the frequency table if allocated */
+ mutex_lock(&etdev->freq_lock);
+ if (etdev->freq_table)
+ kvfree(etdev->freq_table);
+ etdev->freq_table = NULL;
+ etdev->freq_count = 0;
+ mutex_unlock(&etdev->freq_lock);
}
etdev_dbg(etdev, "%s exit\n", __func__);
diff --git a/drivers/edgetpu/edgetpu-usage-stats.h b/drivers/edgetpu/edgetpu-usage-stats.h
index 6b5d612..a60b107 100644
--- a/drivers/edgetpu/edgetpu-usage-stats.h
+++ b/drivers/edgetpu/edgetpu-usage-stats.h
@@ -150,6 +150,7 @@ enum edgetpu_usage_metric_type {
EDGETPU_METRIC_TYPE_COUNTER = 3,
EDGETPU_METRIC_TYPE_THREAD_STATS = 4,
EDGETPU_METRIC_TYPE_MAX_WATERMARK = 5,
+ EDGETPU_METRIC_TYPE_DVFS_FREQUENCY_INFO = 6,
};
/*
@@ -165,6 +166,7 @@ struct edgetpu_usage_metric {
struct edgetpu_usage_counter counter;
struct edgetpu_thread_stats thread_stats;
struct edgetpu_usage_max_watermark max_watermark;
+ uint32_t dvfs_frequency_info;
};
};
diff --git a/drivers/edgetpu/janeiro-platform.c b/drivers/edgetpu/janeiro-platform.c
index d17aa9c..a618a18 100644
--- a/drivers/edgetpu/janeiro-platform.c
+++ b/drivers/edgetpu/janeiro-platform.c
@@ -47,32 +47,6 @@ static int janeiro_mmu_set_shareability(struct device *dev, u32 reg_base)
return 0;
}
-static int janeiro_set_fw_ctx_memory(struct edgetpu_mobile_platform_dev *etmdev)
-{
- struct edgetpu_dev *etdev = &etmdev->edgetpu_dev;
- struct device *dev = etdev->dev;
- struct resource r;
- struct device_node *np;
- int ret;
-
- np = of_parse_phandle(dev->of_node, "memory-region", 1);
- if (!np) {
- etdev_warn(etdev, "No memory for firmware contexts");
- return -ENODEV;
- }
-
- ret = of_address_to_resource(np, 0, &r);
- of_node_put(np);
- if (ret) {
- etdev_warn(etdev, "No memory address for firmware contexts");
- return ret;
- }
-
- etmdev->fw_ctx_paddr = r.start;
- etmdev->fw_ctx_size = resource_size(&r);
- return 0;
-}
-
static int janeiro_parse_set_dt_property(struct edgetpu_mobile_platform_dev *etmdev)
{
int ret;
@@ -80,7 +54,7 @@ static int janeiro_parse_set_dt_property(struct edgetpu_mobile_platform_dev *etm
struct edgetpu_dev *etdev = &etmdev->edgetpu_dev;
struct device *dev = etdev->dev;
- ret = janeiro_set_fw_ctx_memory(etmdev);
+ ret = edgetpu_mobile_platform_set_fw_ctx_memory(etmdev);
if (ret) {
etdev_err(etdev, "Failed to initialize fw context memory: %d", ret);
return ret;