diff options
author | Zuma copybara merger <zuma-automerger@google.com> | 2023-02-08 15:32:13 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-02-17 18:53:36 -0800 |
commit | c01d777cb9feb30c3ccec179bf5098484294d0eb (patch) | |
tree | 0f04e439ce79777370f71afbc1057d899994e397 | |
parent | 1d82648e250e367df17f452cff31dd320e7396ec (diff) | |
download | rio-c01d777cb9feb30c3ccec179bf5098484294d0eb.tar.gz |
[Copybara Auto Merge] Merge branch zuma into android14-gs-pixel-5.15
edgetpu: Add PMQoS support
Bug: 254703840
Signed-off-by: Zuma copybara merger <zuma-automerger@google.com>
GitOrigin-RevId: 0ec4320afeb754d057a1e5d2cade155bb56ef677
Change-Id: Ia0250e3a427013552845e8521a3ba6f6d4c2cc7a
-rw-r--r-- | drivers/edgetpu/edgetpu-internal.h | 2 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-thermal.h | 17 | ||||
-rw-r--r-- | drivers/edgetpu/mobile-thermal.c | 36 | ||||
-rw-r--r-- | drivers/edgetpu/rio-pm.c | 26 |
4 files changed, 74 insertions, 7 deletions
diff --git a/drivers/edgetpu/edgetpu-internal.h b/drivers/edgetpu/edgetpu-internal.h index 798d2d5..fe72da6 100644 --- a/drivers/edgetpu/edgetpu-internal.h +++ b/drivers/edgetpu/edgetpu-internal.h @@ -25,6 +25,7 @@ #include <linux/irqreturn.h> #include <linux/mm_types.h> #include <linux/mutex.h> +#include <linux/notifier.h> #include <linux/refcount.h> #include <linux/scatterlist.h> #include <linux/types.h> @@ -221,6 +222,7 @@ struct edgetpu_dev { struct work_struct debug_dump_work; struct mutex freq_lock; /* protects below freq_* variables */ + struct notifier_block pmqos_nb; /* PMQoS notifier struct */ uint32_t *freq_table; /* Array to record reported frequencies by f/w */ uint32_t freq_count; /* Number of entries in freq_table */ }; diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h index 4efe0fe..f1280a0 100644 --- a/drivers/edgetpu/edgetpu-thermal.h +++ b/drivers/edgetpu/edgetpu-thermal.h @@ -27,6 +27,7 @@ struct edgetpu_thermal { unsigned int tpu_num_states; struct edgetpu_dev *etdev; bool thermal_suspended; /* TPU thermal suspended state */ + unsigned long thermal_vote[2]; /* Thermal vote array, idx0: Tskin; idx1: BCL */ bool enabled; }; @@ -74,6 +75,22 @@ int edgetpu_thermal_kci_if_powered(struct edgetpu_dev *etdev, u32 state); int edgetpu_thermal_restore(struct edgetpu_dev *etdev); /* + * Callback for BCL vote for throttling + * + * This goes through the same path as regular Tskin throttling + * + * Returns 0 if successful, otherwise negative error. + */ +int edgetpu_set_cur_state_bcl(struct thermal_cooling_device *cdev, unsigned long state_original); + +/* + * API to map frequency to cooling state + * + * Returns state if successful. On an invalid input it returns lowest state. + */ +int edgetpu_state_to_cooling(struct edgetpu_dev *etdev, unsigned long state); + +/* * Holds thermal->lock. * * Does nothing if the thermal management is not supported. diff --git a/drivers/edgetpu/mobile-thermal.c b/drivers/edgetpu/mobile-thermal.c index d78dc44..34813e9 100644 --- a/drivers/edgetpu/mobile-thermal.c +++ b/drivers/edgetpu/mobile-thermal.c @@ -42,10 +42,8 @@ static int edgetpu_get_max_state(struct thermal_cooling_device *cdev, unsigned l return 0; } -/* - * Set cooling state. - */ -static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state_original) +static int __edgetpu_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state_original, int voter_id) { int ret; struct edgetpu_thermal *thermal = cdev->devdata; @@ -57,9 +55,12 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned l return -EINVAL; } + edgetpu_thermal_lock(thermal); + thermal->thermal_vote[voter_id] = state_original; + + state_original = max(thermal->thermal_vote[0], thermal->thermal_vote[1]); state_original = max(thermal->sysfs_req, state_original); - edgetpu_thermal_lock(thermal); pwr_state = state_pwr_map[state_original].state; if (state_original == thermal->cooling_state) { ret = -EALREADY; @@ -89,6 +90,19 @@ out: return ret; } +/* + * Set cooling state. + */ +static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state_original) +{ + return __edgetpu_set_cur_state(cdev, state_original, 0); +} + +int edgetpu_set_cur_state_bcl(struct thermal_cooling_device *cdev, unsigned long state_original) +{ + return __edgetpu_set_cur_state(cdev, state_original, 1); +} + static int edgetpu_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { int ret = 0; @@ -527,3 +541,15 @@ int edgetpu_thermal_restore(struct edgetpu_dev *etdev) return ret; } + +int edgetpu_state_to_cooling(struct edgetpu_dev *etdev, unsigned long state) +{ + struct edgetpu_thermal *thermal = etdev->thermal; + int i = 0; + + for (i = 0; i < thermal->tpu_num_states; i++) { + if (state_pwr_map[i].state <= state) + return i; + } + return thermal->tpu_num_states - 1; +} diff --git a/drivers/edgetpu/rio-pm.c b/drivers/edgetpu/rio-pm.c index c013583..81eb133 100644 --- a/drivers/edgetpu/rio-pm.c +++ b/drivers/edgetpu/rio-pm.c @@ -7,7 +7,9 @@ #include <linux/delay.h> #include <linux/iopoll.h> +#include <linux/notifier.h> #include <soc/google/bcl.h> +#include <soc/google/exynos_pm_qos.h> #include "edgetpu-config.h" #include "edgetpu-internal.h" @@ -142,6 +144,22 @@ static int rio_lpm_up(struct edgetpu_dev *etdev) return 0; } +static int rio_pmqos_notifier(struct notifier_block *nb, unsigned long state_freq, + void *nb_data) +{ + struct edgetpu_dev *etdev; + int state_cooling; + int ret; + + etdev = container_of(nb, struct edgetpu_dev, pmqos_nb); + state_cooling = edgetpu_state_to_cooling(etdev, state_freq); + etdev_dbg(etdev, "pmqos req original: %ld, cooling: %d\n", state_freq, state_cooling); + ret = edgetpu_set_cur_state_bcl(etdev->thermal->cdev, state_cooling); + if (ret) + etdev_err_ratelimited(etdev, "Error in BCL throttling %d\n", ret); + return NOTIFY_OK; +} + static bool rio_is_block_down(struct edgetpu_dev *etdev) { struct edgetpu_mobile_platform_dev *etmdev = to_mobile_dev(etdev); @@ -162,8 +180,6 @@ static bool rio_is_block_down(struct edgetpu_dev *etdev) static void rio_post_fw_start(struct edgetpu_dev *etdev) { - if (!etdev->soc_data->bcl_dev) - etdev->soc_data->bcl_dev = google_retrieve_bcl_handle(); if (etdev->soc_data->bcl_dev) google_init_tpu_ratio(etdev->soc_data->bcl_dev); } @@ -179,5 +195,11 @@ int edgetpu_chip_pm_create(struct edgetpu_dev *etdev) platform_pwr->is_block_down = rio_is_block_down; platform_pwr->post_fw_start = rio_post_fw_start; + etdev->soc_data->bcl_dev = google_retrieve_bcl_handle(); + if (etdev->soc_data->bcl_dev) { + etdev->pmqos_nb.notifier_call = rio_pmqos_notifier; + exynos_pm_qos_add_notifier(PM_QOS_TPU_FREQ_MAX, &etdev->pmqos_nb); + } + return edgetpu_mobile_pm_create(etdev); } |