diff options
author | Zuma copybara merger <zuma-automerger@google.com> | 2023-02-07 15:53:05 +0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-02-07 04:38:55 -0800 |
commit | 526c22e2691cc7d25e2eb33396ae53feac6c0ae2 (patch) | |
tree | 55c38f9d7af623fe38f2d43b9298a2a4b2d0ee51 | |
parent | f2524ddbaaf0908b03820fac7071989832ad91ea (diff) | |
download | rio-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.c | 15 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-kci.h | 8 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-mobile-platform.c | 4 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-thermal.h | 1 | ||||
-rw-r--r-- | drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c | 6 | ||||
-rw-r--r-- | drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-dma-fence.h | 7 | ||||
-rw-r--r-- | drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-image-config.h | 16 | ||||
-rw-r--r-- | drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h | 12 | ||||
-rw-r--r-- | drivers/edgetpu/mobile-firmware.c | 6 | ||||
-rw-r--r-- | drivers/edgetpu/mobile-pm.c | 19 | ||||
-rw-r--r-- | drivers/edgetpu/mobile-thermal.c | 79 | ||||
-rw-r--r-- | drivers/edgetpu/rio/config.h | 13 |
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 |