summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuma copybara merger <zuma-automerger@google.com>2023-02-07 15:53:05 +0800
committerCopybara-Service <copybara-worker@google.com>2023-02-07 04:38:55 -0800
commit526c22e2691cc7d25e2eb33396ae53feac6c0ae2 (patch)
tree55c38f9d7af623fe38f2d43b9298a2a4b2d0ee51
parentf2524ddbaaf0908b03820fac7071989832ad91ea (diff)
downloadrio-526c22e2691cc7d25e2eb33396ae53feac6c0ae2.tar.gz
[Copybara Auto Merge] Merge branch zuma into android14-gs-pixel-5.15
edgetpu: Add a debugfs node for thermal control Bug: 266837631 edgetpu: Add missing pm error handling gcip: use v*alloc without node gcip: Add a new KCI code for thermal control Bug: 266837631 (repeat) gcip: Add a new KCI code for fw tracing level request Bug: 262916889 gcip: fix up DMA fence macros gcip: fix code style/formatting issues edgetpu: fix firmware size check Bug: 267206706 gcip: conditionally zero the non-contiguous region Signed-off-by: Zuma copybara merger <zuma-automerger@google.com> GitOrigin-RevId: 5bf0de6e2161bdd772fa8207f9a79ecbde14c54f Change-Id: I433bbaae480764936f1ac5ba2230902d5f28321f
-rw-r--r--drivers/edgetpu/edgetpu-kci.c15
-rw-r--r--drivers/edgetpu/edgetpu-kci.h8
-rw-r--r--drivers/edgetpu/edgetpu-mobile-platform.c4
-rw-r--r--drivers/edgetpu/edgetpu-thermal.h1
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c6
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h7
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h16
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h12
-rw-r--r--drivers/edgetpu/mobile-firmware.c6
-rw-r--r--drivers/edgetpu/mobile-pm.c19
-rw-r--r--drivers/edgetpu/mobile-thermal.c79
-rw-r--r--drivers/edgetpu/rio/config.h13
12 files changed, 150 insertions, 36 deletions
diff --git a/drivers/edgetpu/edgetpu-kci.c b/drivers/edgetpu/edgetpu-kci.c
index 194c9fb..ed9b9e2 100644
--- a/drivers/edgetpu/edgetpu-kci.c
+++ b/drivers/edgetpu/edgetpu-kci.c
@@ -636,6 +636,21 @@ int edgetpu_kci_block_bus_speed_control(struct edgetpu_dev *etdev, bool block)
return gcip_kci_send_cmd(etdev->etkci->kci, &cmd);
}
+int edgetpu_kci_thermal_control(struct edgetpu_dev *etdev, bool enable)
+{
+ struct gcip_kci_command_element cmd = {
+ .code = GCIP_KCI_CODE_THERMAL_CONTROL,
+ .dma = {
+ .flags = (u32)enable,
+ },
+ };
+
+ if (!etdev->etkci)
+ return -ENODEV;
+
+ return gcip_kci_send_cmd(etdev->etkci->kci, &cmd);
+}
+
int edgetpu_kci_resp_rkci_ack(struct edgetpu_dev *etdev, struct gcip_kci_response_element *rkci_cmd)
{
struct gcip_kci_command_element cmd = {
diff --git a/drivers/edgetpu/edgetpu-kci.h b/drivers/edgetpu/edgetpu-kci.h
index 0368be6..6b75306 100644
--- a/drivers/edgetpu/edgetpu-kci.h
+++ b/drivers/edgetpu/edgetpu-kci.h
@@ -197,6 +197,14 @@ int edgetpu_kci_notify_throttling(struct edgetpu_dev *etdev, u32 level);
int edgetpu_kci_block_bus_speed_control(struct edgetpu_dev *etdev, bool block);
/*
+ * Request the firmware to enable or disable the thermal throttling.
+ *
+ * Returns KCI response code on success or < 0 on error (typically -ETIMEDOUT).
+ */
+
+int edgetpu_kci_thermal_control(struct edgetpu_dev *etdev, bool enable);
+
+/*
* Send an ack to the FW after handling a reverse KCI request.
*
* The FW may wait for a response from the kernel for an RKCI request so a
diff --git a/drivers/edgetpu/edgetpu-mobile-platform.c b/drivers/edgetpu/edgetpu-mobile-platform.c
index 3c7e302..1af3bde 100644
--- a/drivers/edgetpu/edgetpu-mobile-platform.c
+++ b/drivers/edgetpu/edgetpu-mobile-platform.c
@@ -56,7 +56,7 @@ static int edgetpu_platform_setup_fw_region(struct edgetpu_mobile_platform_dev *
struct resource r;
struct device_node *np;
int err;
- size_t region_map_size = EDGETPU_DEFAULT_FW_SIZE_MAX + EDGETPU_DEFAULT_REMAPPED_DATA_SIZE;
+ size_t region_map_size = EDGETPU_MAX_FW_LIMIT;
np = of_parse_phandle(dev->of_node, "memory-region", 0);
if (!np) {
@@ -93,7 +93,7 @@ static int edgetpu_platform_setup_fw_region(struct edgetpu_mobile_platform_dev *
}
etmdev->fw_region_paddr = r.start;
- etmdev->fw_region_size = EDGETPU_DEFAULT_FW_SIZE_MAX;
+ etmdev->fw_region_size = EDGETPU_DEFAULT_FW_LIMIT;
etmdev->remapped_data_addr = EDGETPU_INSTRUCTION_REMAP_BASE + etmdev->fw_region_size;
etmdev->remapped_data_size = EDGETPU_DEFAULT_REMAPPED_DATA_SIZE;
diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h
index b96d961..98bc4df 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 */
+ bool enabled;
};
struct edgetpu_state_pwr {
diff --git a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c
index 33c95e2..85af8e5 100644
--- a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c
+++ b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c
@@ -7,6 +7,7 @@
#include <asm/page.h>
#include <linux/device.h>
+#include <linux/gfp.h>
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
@@ -47,7 +48,10 @@ struct sg_table *gcip_alloc_noncontiguous(struct device *dev, size_t size, gfp_t
size = PAGE_ALIGN(size);
count = size >> PAGE_SHIFT;
- mem = vzalloc_node(size, dev_to_node(dev));
+ if (gfp & __GFP_ZERO)
+ mem = vzalloc(size);
+ else
+ mem = vmalloc(size);
if (!mem) {
dev_err(dev, "GCIP noncontiguous alloc size=%#zx failed", size);
goto err_free_sh;
diff --git a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h
index c0a7d68..1d4030a 100644
--- a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h
+++ b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h
@@ -17,8 +17,9 @@
#define GCIP_FENCE_TIMELINE_NAME_LEN 128
/* Used before accessing the list headed by mgr->fence_list_head. */
-#define GCIP_DMA_FENCE_LIST_LOCK(mgr, flags) spin_lock_irqsave(&mgr->fence_list_lock, flags)
-#define GCIP_DMA_FENCE_LIST_UNLOCK(mgr, flags) spin_unlock_irqrestore(&mgr->fence_list_lock, flags)
+#define GCIP_DMA_FENCE_LIST_LOCK(mgr, flags) spin_lock_irqsave(&(mgr)->fence_list_lock, flags)
+#define GCIP_DMA_FENCE_LIST_UNLOCK(mgr, flags) \
+ spin_unlock_irqrestore(&(mgr)->fence_list_lock, flags)
/*
* A macro to loop through all fences under a gcip_dma_fence_manager.
@@ -28,7 +29,7 @@
* This macro must be wrapped by GCIP_DMA_FENCE_LIST_(UN)LOCK.
*/
#define gcip_for_each_fence(mgr, gfence) \
- list_for_each_entry(gfence, &mgr->fence_list_head, fence_list)
+ list_for_each_entry(gfence, &(mgr)->fence_list_head, fence_list)
#define to_gcip_fence(fence) container_of(fence, struct gcip_dma_fence, fence)
diff --git a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h
index 1d00ef9..bcc506f 100644
--- a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h
+++ b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h
@@ -92,27 +92,19 @@ struct gcip_image_config_parser {
/* For decoding the size of ns_iommu_mappings. */
static inline u32 gcip_ns_config_to_size(u32 cfg)
{
- u32 size;
-
if (cfg & GCIP_IMG_CFG_SIZE_MODE_BIT)
- size = (cfg & GCIP_IMG_CFG_NS_SIZE_MASK) << PAGE_SHIFT;
- else
- size = (cfg & GCIP_IMG_CFG_NS_SIZE_MASK) << GCIP_IMG_CFG_MB_SHIFT;
+ return (cfg & GCIP_IMG_CFG_NS_SIZE_MASK) << PAGE_SHIFT;
- return size;
+ return (cfg & GCIP_IMG_CFG_NS_SIZE_MASK) << GCIP_IMG_CFG_MB_SHIFT;
}
/* For decoding the size of iommu_mappings. */
static inline u32 gcip_config_to_size(u32 cfg)
{
- u32 page_size;
-
if (cfg & GCIP_IMG_CFG_SIZE_MODE_BIT)
- page_size = cfg & GCIP_IMG_CFG_SECURE_SIZE_MASK;
- else
- page_size = BIT(cfg & GCIP_IMG_CFG_SECURE_SIZE_MASK);
+ return (cfg & GCIP_IMG_CFG_SECURE_SIZE_MASK) << PAGE_SHIFT;
- return page_size << PAGE_SHIFT;
+ return BIT(cfg & GCIP_IMG_CFG_SECURE_SIZE_MASK) << PAGE_SHIFT;
}
/*
diff --git a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h
index 3649779..03cc078 100644
--- a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h
+++ b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h
@@ -97,6 +97,8 @@ enum gcip_kci_code {
GCIP_KCI_CODE_RELEASE_VMBOX = 16,
GCIP_KCI_CODE_LINK_OFFLOAD_VMBOX = 17,
GCIP_KCI_CODE_UNLINK_OFFLOAD_VMBOX = 18,
+ GCIP_KCI_CODE_FIRMWARE_TRACING_LEVEL = 19,
+ GCIP_KCI_CODE_THERMAL_CONTROL = 20,
GCIP_KCI_CODE_RKCI_ACK = 256,
};
@@ -109,11 +111,11 @@ enum gcip_kci_code {
*/
enum gcip_reverse_kci_code {
GCIP_RKCI_CHIP_CODE_FIRST = 0,
- GCIP_RKCI_PM_QOS_REQUEST = GCIP_RKCI_CHIP_CODE_FIRST + 1,
- GCIP_RKCI_CHANGE_BTS_SCENARIO = GCIP_RKCI_CHIP_CODE_FIRST + 2,
- GCIP_RKCI_PM_QOS_BTS_REQUEST = GCIP_RKCI_CHIP_CODE_FIRST + 3,
- GCIP_RKCI_DSP_CORE_TELEMETRY_TRY_READ = GCIP_RKCI_CHIP_CODE_FIRST + 4,
- GCIP_RKCI_CLIENT_FATAL_ERROR_NOTIFY = GCIP_RKCI_CHIP_CODE_FIRST + 5,
+ GCIP_RKCI_PM_QOS_REQUEST,
+ GCIP_RKCI_CHANGE_BTS_SCENARIO,
+ GCIP_RKCI_PM_QOS_BTS_REQUEST,
+ GCIP_RKCI_DSP_CORE_TELEMETRY_TRY_READ,
+ GCIP_RKCI_CLIENT_FATAL_ERROR_NOTIFY,
GCIP_RKCI_CHIP_CODE_LAST = 0x7FFF,
GCIP_RKCI_GENERIC_CODE_FIRST = 0x8000,
GCIP_RKCI_FIRMWARE_CRASH = GCIP_RKCI_GENERIC_CODE_FIRST + 0,
diff --git a/drivers/edgetpu/mobile-firmware.c b/drivers/edgetpu/mobile-firmware.c
index de6b4cd..e8f156f 100644
--- a/drivers/edgetpu/mobile-firmware.c
+++ b/drivers/edgetpu/mobile-firmware.c
@@ -99,11 +99,9 @@ static int mobile_firmware_alloc_buffer(
struct edgetpu_firmware_buffer *fw_buf)
{
struct edgetpu_dev *etdev = et_fw->etdev;
- struct edgetpu_mobile_platform_dev *etmdev = to_mobile_dev(etdev);
/* Allocate extra space the image header */
- size_t buffer_size =
- etmdev->fw_region_size + MOBILE_FW_HEADER_SIZE;
+ size_t buffer_size = EDGETPU_MAX_FW_LIMIT + MOBILE_FW_HEADER_SIZE;
fw_buf->vaddr = vmalloc(buffer_size);
if (!fw_buf->vaddr) {
@@ -351,7 +349,7 @@ static int mobile_firmware_setup_buffer(struct edgetpu_firmware *et_fw,
etmdev->fw_region_size =
image_config->remapped_data_start ?
image_config->remapped_data_start - image_config->firmware_base :
- EDGETPU_DEFAULT_FW_SIZE_MAX;
+ EDGETPU_DEFAULT_FW_LIMIT;
image_vaddr = memremap(etmdev->fw_region_paddr, etmdev->fw_region_size, MEMREMAP_WC);
if (!image_vaddr) {
diff --git a/drivers/edgetpu/mobile-pm.c b/drivers/edgetpu/mobile-pm.c
index aaf6a2f..6ab65bf 100644
--- a/drivers/edgetpu/mobile-pm.c
+++ b/drivers/edgetpu/mobile-pm.c
@@ -354,9 +354,8 @@ static int mobile_pm_after_create(struct edgetpu_pm *etpm)
ret = pm_runtime_get_sync(dev);
if (ret) {
- pm_runtime_put_noidle(dev);
dev_err(dev, "pm_runtime_get_sync returned %d\n", ret);
- return ret;
+ goto err_pm_runtime_put;
}
mutex_init(&platform_pwr->policy_lock);
@@ -374,7 +373,21 @@ static int mobile_pm_after_create(struct edgetpu_pm *etpm)
debugfs_create_file("policy", 0660, platform_pwr->debugfs_dir, etdev,
&fops_tpu_pwr_policy);
}
- return edgetpu_soc_pm_init(etdev);
+
+ ret = edgetpu_soc_pm_init(etdev);
+ if (ret)
+ goto err_debugfs_remove;
+
+ return 0;
+
+err_debugfs_remove:
+ debugfs_remove_recursive(platform_pwr->debugfs_dir);
+
+err_pm_runtime_put:
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+
+ return ret;
}
static void mobile_pm_before_destroy(struct edgetpu_pm *etpm)
diff --git a/drivers/edgetpu/mobile-thermal.c b/drivers/edgetpu/mobile-thermal.c
index 4794053..a1bbda5 100644
--- a/drivers/edgetpu/mobile-thermal.c
+++ b/drivers/edgetpu/mobile-thermal.c
@@ -292,6 +292,70 @@ static ssize_t user_vote_store(struct device *dev, struct device_attribute *attr
static DEVICE_ATTR_RW(user_vote);
+static int edgetpu_thermal_control_kci(struct edgetpu_dev *etdev, bool enable)
+{
+ int ret;
+
+ ret = edgetpu_kci_thermal_control(etdev, enable);
+ if (ret)
+ etdev_err_ratelimited(etdev, "Failed to %s the thermal, error:%d",
+ enable ? "enable" : "disable", ret);
+
+ return ret;
+}
+
+static int edgetpu_thermal_control_kci_if_powered(struct edgetpu_dev *etdev, bool enable)
+{
+ int ret;
+
+ /* Use trylock since this function might be called during power up. */
+ if (!edgetpu_pm_get_if_powered(etdev->pm, true))
+ return -EAGAIN;
+
+ ret = edgetpu_thermal_control_kci(etdev, enable);
+
+ edgetpu_pm_put(etdev->pm);
+
+ return ret;
+}
+
+static int thermal_enable_get(void *data, u64 *val)
+{
+ struct edgetpu_thermal *thermal = (struct edgetpu_thermal *)data;
+
+ edgetpu_thermal_lock(thermal);
+ *val = thermal->enabled;
+ edgetpu_thermal_unlock(thermal);
+
+ return 0;
+}
+
+static int thermal_enable_set(void *data, u64 val)
+{
+ struct edgetpu_thermal *thermal = (struct edgetpu_thermal *)data;
+ int ret = 0;
+
+ edgetpu_thermal_lock(thermal);
+
+ if (thermal->enabled != (bool)val) {
+ ret = edgetpu_thermal_control_kci_if_powered(thermal->etdev, val);
+ /*
+ * -EAGAIN means the fw is not powered and the value will be restored by
+ * edgetpu_thermal_restore in next fw boot.
+ */
+ if (!ret || ret == -EAGAIN) {
+ ret = 0;
+ thermal->enabled = val;
+ }
+ }
+
+ edgetpu_thermal_unlock(thermal);
+
+ return ret;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_thermal_enable, thermal_enable_get, thermal_enable_set, "%llu\n");
+
static int tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
{
struct device_node *cooling_node = NULL;
@@ -324,11 +388,18 @@ static int tpu_thermal_init(struct edgetpu_thermal *thermal, struct device *dev)
struct dentry *d;
thermal->dev = dev;
+ thermal->enabled = true;
+
d = debugfs_create_dir("cooling", edgetpu_fs_debugfs_dir());
/* don't let debugfs creation failure abort the init procedure */
- if (IS_ERR_OR_NULL(d))
+ if (IS_ERR_OR_NULL(d)) {
dev_warn(dev, "failed to create debug fs for cooling");
- thermal->cooling_root = d;
+ thermal->cooling_root = NULL;
+ } else {
+ thermal->cooling_root = d;
+ debugfs_create_file("enable", 0660, thermal->cooling_root, thermal,
+ &fops_thermal_enable);
+ }
err = tpu_thermal_cooling_register(thermal, EDGETPU_COOLING_NAME);
if (err) {
@@ -446,7 +517,9 @@ int edgetpu_thermal_restore(struct edgetpu_dev *etdev)
edgetpu_thermal_lock(thermal);
- if (edgetpu_thermal_is_suspended(thermal))
+ if (!thermal->enabled)
+ ret = edgetpu_thermal_control_kci(etdev, thermal->enabled);
+ else if (edgetpu_thermal_is_suspended(thermal))
ret = edgetpu_thermal_kci(etdev, TPU_OFF);
else if (thermal->cooling_state)
ret = edgetpu_thermal_kci(etdev, state_pwr_map[thermal->cooling_state].state);
diff --git a/drivers/edgetpu/rio/config.h b/drivers/edgetpu/rio/config.h
index 5b4f0f2..4434a2e 100644
--- a/drivers/edgetpu/rio/config.h
+++ b/drivers/edgetpu/rio/config.h
@@ -29,13 +29,20 @@
/* Placeholder value */
#define EDGETPU_TZ_MAILBOX_ID 31
-/* Default size of the area in remapped DRAM reserved for firmware code and internal data. */
-#define EDGETPU_DEFAULT_FW_SIZE_MAX 0x100000
+/* Default size limit of the area in remapped DRAM reserved for firmware code and internal data. */
+#define EDGETPU_DEFAULT_FW_LIMIT 0x100000
/* Default size of remapped DRAM data region. */
#define EDGETPU_DEFAULT_REMAPPED_DATA_SIZE 0x100000
/*
+ * Maximum size limit of the area in remapped DRAM reserved for firmware code and internal data.
+ * The firmware image config may modify the split between code and data, but the total size of both
+ * must be respected.
+ */
+#define EDGETPU_MAX_FW_LIMIT (EDGETPU_DEFAULT_FW_LIMIT + EDGETPU_DEFAULT_REMAPPED_DATA_SIZE)
+
+/*
* Instruction remap registers make carveout memory appear at address
* 0x10000000 from the TPU CPU perspective
*/
@@ -46,7 +53,7 @@
* Data in remapped DRAM starts after firmware code and internal data.
*/
#define EDGETPU_DEFAULT_REMAPPED_DATA_ADDR \
- (EDGETPU_INSTRUCTION_REMAP_BASE + EDGETPU_DEFAULT_FW_SIZE_MAX)
+ (EDGETPU_INSTRUCTION_REMAP_BASE + EDGETPU_DEFAULT_FW_LIMIT)
/*
* Size of memory for FW accessible debug dump segments