diff options
author | Aaron Ding <aaronding@google.com> | 2021-08-18 23:48:12 +0800 |
---|---|---|
committer | Aaron Ding <aaronding@google.com> | 2021-08-18 23:48:28 +0800 |
commit | 09df8e441354ec8c57a67c74f6ea770e61d16d58 (patch) | |
tree | 1504828d55610c1550bce2913a3f8abc3ba061e5 | |
parent | 22bce3194998638e9df4bc051386f66554bf7865 (diff) | |
parent | b202780572588790b5c001093d2916ab4ddfe62c (diff) | |
download | janeiro-09df8e441354ec8c57a67c74f6ea770e61d16d58.tar.gz |
Merge android-gs-cloudripper-5.10 into android13-gs-pixel-5.10
Change-Id: I1e4de8679434bcfcec7a83d4d8d977f984af0c14
Signed-off-by: Aaron Ding <aaronding@google.com>
-rw-r--r-- | drivers/edgetpu/edgetpu-core.c | 24 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-device-group.c | 13 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-fs.c | 84 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-internal.h | 45 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-shared-fw.c | 2 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-thermal.h | 13 | ||||
-rw-r--r-- | drivers/edgetpu/janeiro-device.c | 10 | ||||
-rw-r--r-- | drivers/edgetpu/janeiro-platform.c | 9 | ||||
-rw-r--r-- | drivers/edgetpu/janeiro-pm.c | 15 |
9 files changed, 160 insertions, 55 deletions
diff --git a/drivers/edgetpu/edgetpu-core.c b/drivers/edgetpu/edgetpu-core.c index e7dbaf2..3115f17 100644 --- a/drivers/edgetpu/edgetpu-core.c +++ b/drivers/edgetpu/edgetpu-core.c @@ -345,12 +345,23 @@ int edgetpu_get_state_errno_locked(struct edgetpu_dev *etdev) } int edgetpu_device_add(struct edgetpu_dev *etdev, - const struct edgetpu_mapped_resource *regs) + const struct edgetpu_mapped_resource *regs, + const struct edgetpu_iface_params *iface_params, + uint num_ifaces) { int ret; etdev->regs = *regs; + etdev->etiface = devm_kzalloc( + etdev->dev, sizeof(*etdev->etiface) * num_ifaces, GFP_KERNEL); + + if (!etdev->etiface) { + dev_err(etdev->dev, + "Failed to allocate memory for interfaces\n"); + return -ENOMEM; + } + /* mcp_id and mcp_die_index fields set by caller */ if (etdev->mcp_id < 0) { uint ordinal_id = atomic_add_return(1, &single_dev_count); @@ -377,11 +388,10 @@ int edgetpu_device_add(struct edgetpu_dev *etdev, mutex_init(&etdev->state_lock); etdev->state = ETDEV_STATE_NOFW; - ret = edgetpu_fs_add(etdev); + ret = edgetpu_fs_add(etdev, iface_params, num_ifaces); if (ret) { - dev_err(etdev->dev, "%s: edgetpu_fs_add returns %d\n", - etdev->dev_name, ret); - return ret; + dev_err(etdev->dev, "%s: edgetpu_fs_add returns %d\n", etdev->dev_name, ret); + goto remove_dev; } etdev->mailbox_manager = @@ -456,10 +466,11 @@ void edgetpu_device_remove(struct edgetpu_dev *etdev) edgetpu_fs_remove(etdev); } -struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev) +struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev_iface *etiface) { struct edgetpu_client *client; struct edgetpu_list_device_client *l = kmalloc(sizeof(*l), GFP_KERNEL); + struct edgetpu_dev *etdev = etiface->etdev; if (!l) return ERR_PTR(-ENOMEM); @@ -478,6 +489,7 @@ struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev) client->pid = current->pid; client->tgid = current->tgid; client->etdev = etdev; + client->etiface = etiface; mutex_init(&client->group_lock); /* equivalent to edgetpu_client_get() */ refcount_set(&client->count, 1); diff --git a/drivers/edgetpu/edgetpu-device-group.c b/drivers/edgetpu/edgetpu-device-group.c index f51119c..d1c0832 100644 --- a/drivers/edgetpu/edgetpu-device-group.c +++ b/drivers/edgetpu/edgetpu-device-group.c @@ -1156,9 +1156,12 @@ static struct page **edgetpu_pin_user_pages(struct edgetpu_device_group *group, * "num_pages" is decided from user-space arguments, don't show warnings * when facing malicious input. */ - pages = kcalloc(num_pages, sizeof(*pages), GFP_KERNEL | __GFP_NOWARN); - if (!pages) + pages = kvmalloc((num_pages * sizeof(*pages)), GFP_KERNEL | __GFP_NOWARN); + if (!pages) { + etdev_dbg(etdev, "%s: kvmalloc failed (%lu bytes)\n", __func__, + (num_pages * sizeof(*pages))); return ERR_PTR(-ENOMEM); + } /* * The host pages might be read-only and could fail if we attempt to pin @@ -1199,7 +1202,7 @@ static struct page **edgetpu_pin_user_pages(struct edgetpu_device_group *group, error: for (i = 0; i < num_pages; i++) unpin_user_page(pages[i]); - kfree(pages); + kvfree(pages); return ERR_PTR(ret); } @@ -1463,7 +1466,7 @@ int edgetpu_device_group_map(struct edgetpu_device_group *group, mutex_unlock(&group->lock); arg->device_address = map->device_address; - kfree(pages); + kvfree(pages); return 0; error: @@ -1478,7 +1481,7 @@ error: unpin_user_page(pages[i]); } mutex_unlock(&group->lock); - kfree(pages); + kvfree(pages); return ret; } diff --git a/drivers/edgetpu/edgetpu-fs.c b/drivers/edgetpu/edgetpu-fs.c index c16c964..0dcad64 100644 --- a/drivers/edgetpu/edgetpu-fs.c +++ b/drivers/edgetpu/edgetpu-fs.c @@ -73,13 +73,13 @@ static bool is_edgetpu_file(struct file *file) return file->f_op == &edgetpu_fops; } -int edgetpu_open(struct edgetpu_dev *etdev, struct file *file) +int edgetpu_open(struct edgetpu_dev_iface *etiface, struct file *file) { struct edgetpu_client *client; /* Set client pointer to NULL if error creating client. */ file->private_data = NULL; - client = edgetpu_client_add(etdev); + client = edgetpu_client_add(etiface); if (IS_ERR(client)) return PTR_ERR(client); file->private_data = client; @@ -88,10 +88,10 @@ int edgetpu_open(struct edgetpu_dev *etdev, struct file *file) static int edgetpu_fs_open(struct inode *inode, struct file *file) { - struct edgetpu_dev *etdev = - container_of(inode->i_cdev, struct edgetpu_dev, cdev); + struct edgetpu_dev_iface *etiface = + container_of(inode->i_cdev, struct edgetpu_dev_iface, cdev); - return edgetpu_open(etdev, file); + return edgetpu_open(etiface, file); } static int edgetpu_fs_release(struct inode *inode, struct file *file) @@ -800,6 +800,7 @@ static int edgetpu_fs_mmap(struct file *file, struct vm_area_struct *vma) return edgetpu_mmap(client, vma); } +#ifndef EDGETPU_FEATURE_MOBILE static struct edgetpu_dumpregs_range common_statusregs_ranges[] = { { .firstreg = EDGETPU_REG_AON_RESET, @@ -939,6 +940,7 @@ static const struct file_operations statusregs_ops = { .owner = THIS_MODULE, .release = single_release, }; +#endif /* EDGETPU_FEATURE_MOBILE */ static int mappings_show(struct seq_file *s, void *data) { @@ -979,8 +981,10 @@ static void edgetpu_fs_setup_debugfs(struct edgetpu_dev *etdev) } debugfs_create_file("mappings", 0440, etdev->d_entry, etdev, &mappings_ops); +#ifndef EDGETPU_FEATURE_MOBILE debugfs_create_file("statusregs", 0440, etdev->d_entry, etdev, &statusregs_ops); +#endif } static ssize_t firmware_crash_count_show( @@ -1045,46 +1049,78 @@ const struct file_operations edgetpu_fops = { .unlocked_ioctl = edgetpu_fs_ioctl, }; -/* Called from edgetpu core to add a new edgetpu device. */ -int edgetpu_fs_add(struct edgetpu_dev *etdev) +static int edgeptu_fs_add_interface(struct edgetpu_dev *etdev, struct edgetpu_dev_iface *etiface, + const struct edgetpu_iface_params *etiparams) { + char dev_name[EDGETPU_DEVICE_NAME_MAX]; int ret; - etdev->devno = MKDEV(MAJOR(edgetpu_basedev), + etiface->name = etiparams->name ? etiparams->name : etdev->dev_name; + snprintf(dev_name, EDGETPU_DEVICE_NAME_MAX, "%s", + etiface->name); + + dev_dbg(etdev->dev, "adding interface: %s", dev_name); + + etiface->devno = MKDEV(MAJOR(edgetpu_basedev), atomic_add_return(1, &char_minor)); - cdev_init(&etdev->cdev, &edgetpu_fops); - ret = cdev_add(&etdev->cdev, etdev->devno, 1); + cdev_init(&etiface->cdev, &edgetpu_fops); + ret = cdev_add(&etiface->cdev, etiface->devno, 1); if (ret) { - dev_err(etdev->dev, - "%s: error %d adding cdev for dev %d:%d\n", - etdev->dev_name, ret, - MAJOR(etdev->devno), MINOR(etdev->devno)); + dev_err(etdev->dev, "%s: error %d adding cdev for dev %d:%d\n", + etdev->dev_name, ret, MAJOR(etiface->devno), + MINOR(etiface->devno)); return ret; } - etdev->etcdev = device_create(edgetpu_class, etdev->dev, etdev->devno, - etdev, "%s", etdev->dev_name); - if (IS_ERR(etdev->etcdev)) { - ret = PTR_ERR(etdev->etcdev); + etiface->etcdev = device_create(edgetpu_class, etdev->dev, etiface->devno, + etdev, "%s", dev_name); + if (IS_ERR(etiface->etcdev)) { + ret = PTR_ERR(etiface->etcdev); dev_err(etdev->dev, "%s: failed to create char device: %d\n", - etdev->dev_name, ret); - cdev_del(&etdev->cdev); + dev_name, ret); + cdev_del(&etiface->cdev); return ret; } + return 0; +} + +/* Called from edgetpu core to add new edgetpu device files. */ +int edgetpu_fs_add(struct edgetpu_dev *etdev, const struct edgetpu_iface_params *etiparams, + int num_ifaces) +{ + int ret; + int i; + + etdev->num_ifaces = 0; + dev_dbg(etdev->dev, "%s: adding %u interfaces\n", __func__, num_ifaces); + + for (i = 0; i < num_ifaces; i++) { + etdev->etiface[i].etdev = etdev; + ret = edgeptu_fs_add_interface(etdev, &etdev->etiface[i], &etiparams[i]); + if (ret) + return ret; + etdev->num_ifaces++; + } + ret = device_add_group(etdev->dev, &edgetpu_attr_group); + edgetpu_fs_setup_debugfs(etdev); if (ret) etdev_warn(etdev, "edgetpu attr group create failed: %d", ret); - edgetpu_fs_setup_debugfs(etdev); return 0; } void edgetpu_fs_remove(struct edgetpu_dev *etdev) { + int i; device_remove_group(etdev->dev, &edgetpu_attr_group); - device_destroy(edgetpu_class, etdev->devno); - etdev->etcdev = NULL; - cdev_del(&etdev->cdev); + for (i = 0; i < etdev->num_ifaces; i++) { + struct edgetpu_dev_iface *etiface = &etdev->etiface[i]; + + device_destroy(edgetpu_class, etiface->devno); + etiface->etcdev = NULL; + cdev_del(&etiface->cdev); + } debugfs_remove_recursive(etdev->d_entry); } diff --git a/drivers/edgetpu/edgetpu-internal.h b/drivers/edgetpu/edgetpu-internal.h index d352fe1..b492eab 100644 --- a/drivers/edgetpu/edgetpu-internal.h +++ b/drivers/edgetpu/edgetpu-internal.h @@ -35,7 +35,8 @@ #include "edgetpu-thermal.h" #include "edgetpu-usage-stats.h" -#define get_dev_for_logging(etdev) ((etdev)->etcdev ? (etdev)->etcdev : (etdev)->dev) +#define get_dev_for_logging(etdev) \ + ((etdev)->etiface->etcdev ? (etdev)->etiface->etcdev : (etdev)->dev) #define etdev_err(etdev, fmt, ...) dev_err(get_dev_for_logging(etdev), fmt, ##__VA_ARGS__) #define etdev_warn(etdev, fmt, ...) \ @@ -93,6 +94,7 @@ struct edgetpu_device_group; struct edgetpu_p2p_csr_map; struct edgetpu_remote_dram_map; struct edgetpu_wakelock; +struct edgetpu_dev_iface; #define EDGETPU_NUM_PERDIE_EVENTS 2 #define perdie_event_id_to_num(event_id) \ @@ -117,6 +119,8 @@ struct edgetpu_client { uint idx; /* the device opened by this client */ struct edgetpu_dev *etdev; + /* the interface from which this client was opened */ + struct edgetpu_dev_iface *etiface; /* Peer CSR dma addrs for this client, if in a group with P2P */ dma_addr_t *p2p_csrs_dma_addrs; /* Peer DRAM dma addrs for this client, if has on-device DRAM */ @@ -127,6 +131,15 @@ struct edgetpu_client { u64 perdie_events; }; +/* Configurable parameters for an edgetpu interface */ +struct edgetpu_iface_params { + /* + * Interface-specific name. + * May be NULL for the default interface (etdev->dev_name will be used) + */ + const char *name; +}; + /* edgetpu_dev#clients list entry. */ struct edgetpu_list_device_client { struct list_head list; @@ -167,9 +180,12 @@ enum edgetpu_dev_state { struct edgetpu_dev { struct device *dev; /* platform/pci bus device */ - struct device *etcdev; /* edgetpu class char device */ - struct cdev cdev; /* cdev char device structure */ - dev_t devno; /* char device dev_t */ + uint num_ifaces; /* Number of device interfaces */ + /* + * Array of device interfaces + * First element is the default interface + */ + struct edgetpu_dev_iface *etiface; char dev_name[EDGETPU_DEVICE_NAME_MAX]; struct edgetpu_mapped_resource regs; /* ioremapped CSRs */ struct dentry *d_entry; /* debugfs dir for this device */ @@ -219,6 +235,14 @@ struct edgetpu_dev { bool on_exit; }; +struct edgetpu_dev_iface { + struct cdev cdev; /* cdev char device structure */ + struct device *etcdev; /* edgetpu class char device */ + struct edgetpu_dev *etdev; /* Pointer to core device struct */ + dev_t devno; /* char device dev_t */ + const char *name; /* interface specific device name */ +}; + /* Firmware crash_type codes */ enum edgetpu_fw_crash_type { EDGETPU_FW_CRASH_ASSERT = 0, @@ -335,7 +359,7 @@ void edgetpu_free_coherent(struct edgetpu_dev *etdev, /* External drivers can hook up to edgetpu driver using these calls. */ -int edgetpu_open(struct edgetpu_dev *etdev, struct file *file); +int edgetpu_open(struct edgetpu_dev_iface *etiface, struct file *file); long edgetpu_ioctl(struct file *file, uint cmd, ulong arg); #if IS_ENABLED(CONFIG_EDGETPU_EXTERNAL_WRAPPER_CLASS) @@ -359,7 +383,9 @@ void edgetpu_handle_job_lockup(struct edgetpu_dev *etdev, u16 vcid); int __init edgetpu_init(void); void __exit edgetpu_exit(void); int edgetpu_device_add(struct edgetpu_dev *etdev, - const struct edgetpu_mapped_resource *regs); + const struct edgetpu_mapped_resource *regs, + const struct edgetpu_iface_params *iface_params, + uint num_ifaces); void edgetpu_device_remove(struct edgetpu_dev *etdev); int edgetpu_register_irq(struct edgetpu_dev *etdev, int irq); void edgetpu_unregister_irq(struct edgetpu_dev *etdev, int irq); @@ -368,7 +394,9 @@ void edgetpu_unregister_irq(struct edgetpu_dev *etdev, int irq); int __init edgetpu_fs_init(void); void __exit edgetpu_fs_exit(void); -int edgetpu_fs_add(struct edgetpu_dev *etdev); +int edgetpu_fs_add(struct edgetpu_dev *etdev, const struct edgetpu_iface_params *etiparams, + int num_ifaces); + void edgetpu_fs_remove(struct edgetpu_dev *dev); /* Get the top-level debugfs directory for the device class */ struct dentry *edgetpu_fs_debugfs_dir(void); @@ -409,7 +437,8 @@ void edgetpu_chip_handle_reverse_kci(struct edgetpu_dev *etdev, /* Device -> Core API */ /* Add current thread as new TPU client */ -struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev); +struct edgetpu_client * +edgetpu_client_add(struct edgetpu_dev_iface *etiface); /* Remove TPU client */ void edgetpu_client_remove(struct edgetpu_client *client); diff --git a/drivers/edgetpu/edgetpu-shared-fw.c b/drivers/edgetpu/edgetpu-shared-fw.c index c3c4e48..c41215e 100644 --- a/drivers/edgetpu/edgetpu-shared-fw.c +++ b/drivers/edgetpu/edgetpu-shared-fw.c @@ -167,7 +167,7 @@ edgetpu_shared_fw_load_locked(const char *name, struct edgetpu_dev *etdev) pr_debug("%s: shared fw image %s not found, requesting\n", __func__, name); - ret = request_firmware(&fw, name, etdev ? etdev->etcdev : NULL); + ret = request_firmware(&fw, name, etdev ? etdev->etiface->etcdev : NULL); if (ret) goto out; diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h index 2b4dd09..8d4b23f 100644 --- a/drivers/edgetpu/edgetpu-thermal.h +++ b/drivers/edgetpu/edgetpu-thermal.h @@ -42,6 +42,19 @@ struct edgetpu_thermal *devm_tpu_thermal_create(struct device *dev, struct edgetpu_dev *etdev); /* + * Marks the TPU is suspended and informs TPU device if it's powered. + * + * Returns 0 on success. + */ +int edgetpu_thermal_suspend(struct device *dev); +/* + * Resumes the TPU from the suspend state and informs TPU CPU if it's powered. + * + * Returns 0 on success. + */ +int edgetpu_thermal_resume(struct device *dev); + +/* * Holds thermal->lock. * * Does nothing if the thermal management is not supported. diff --git a/drivers/edgetpu/janeiro-device.c b/drivers/edgetpu/janeiro-device.c index 265d5e8..7b1aa6d 100644 --- a/drivers/edgetpu/janeiro-device.c +++ b/drivers/edgetpu/janeiro-device.c @@ -75,16 +75,6 @@ void edgetpu_mark_probe_fail(struct edgetpu_dev *etdev) { } -struct edgetpu_dumpregs_range edgetpu_chip_statusregs_ranges[] = { -}; -int edgetpu_chip_statusregs_nranges = - ARRAY_SIZE(edgetpu_chip_statusregs_ranges); - -struct edgetpu_dumpregs_range edgetpu_chip_tile_statusregs_ranges[] = { -}; -int edgetpu_chip_tile_statusregs_nranges = - ARRAY_SIZE(edgetpu_chip_tile_statusregs_ranges); - void edgetpu_chip_handle_reverse_kci(struct edgetpu_dev *etdev, struct edgetpu_kci_response_element *resp) { diff --git a/drivers/edgetpu/janeiro-platform.c b/drivers/edgetpu/janeiro-platform.c index 6f956c1..73c6119 100644 --- a/drivers/edgetpu/janeiro-platform.c +++ b/drivers/edgetpu/janeiro-platform.c @@ -164,6 +164,12 @@ static int edgetpu_platform_probe(struct platform_device *pdev) struct resource *r; struct edgetpu_mapped_resource regs; int ret, i; + struct edgetpu_iface_params iface_params[] = { + /* Default interface */ + { .name = NULL }, + /* Common name for SoC embedded devices */ + { .name = "edgetpu-soc" }, + }; edgetpu_pdev = devm_kzalloc(dev, sizeof(*edgetpu_pdev), GFP_KERNEL); if (!edgetpu_pdev) @@ -233,7 +239,8 @@ static int edgetpu_platform_probe(struct platform_device *pdev) dev_warn(dev, "%s failed to enable shareability: %d\n", DRIVER_NAME, ret); - ret = edgetpu_device_add(&edgetpu_pdev->edgetpu_dev, ®s); + ret = edgetpu_device_add(&edgetpu_pdev->edgetpu_dev, ®s, iface_params, + ARRAY_SIZE(iface_params)); if (ret) { dev_err(dev, "%s edgetpu setup failed: %d\n", DRIVER_NAME, ret); diff --git a/drivers/edgetpu/janeiro-pm.c b/drivers/edgetpu/janeiro-pm.c index 569858d..e69f774 100644 --- a/drivers/edgetpu/janeiro-pm.c +++ b/drivers/edgetpu/janeiro-pm.c @@ -25,6 +25,8 @@ #define SHUTDOWN_DELAY_US_MIN 20 #define SHUTDOWN_DELAY_US_MAX 20 +#define BOOTUP_DELAY_US_MIN 100 +#define BOOTUP_DELAY_US_MAX 150 #define SHUTDOWN_MAX_DELAY_COUNT 20 /* Default power state */ @@ -73,6 +75,7 @@ static int janeiro_pwr_state_set_locked(void *data, u64 val) { int ret; int curr_state; + int timeout_cnt = 0; struct edgetpu_dev *etdev = (typeof(etdev))data; struct device *dev = etdev->dev; @@ -106,6 +109,16 @@ static int janeiro_pwr_state_set_locked(void *data, u64 val) __func__, ret); return ret; } + do { + /* Delay 20us per retry till blk shutdown finished */ + usleep_range(SHUTDOWN_DELAY_US_MIN, SHUTDOWN_DELAY_US_MAX); + curr_state = exynos_acpm_get_rate(TPU_ACPM_DOMAIN, 0); + if (!curr_state) + break; + timeout_cnt++; + } while (timeout_cnt < SHUTDOWN_MAX_DELAY_COUNT); + if (timeout_cnt == SHUTDOWN_MAX_DELAY_COUNT) + dev_warn(dev, "%s: blk_shutdown timeout\n", __func__); } return ret; @@ -259,6 +272,8 @@ static int janeiro_power_up(struct edgetpu_pm *etpm) if (ret) return ret; + /* Delay 100us to make sure LPM is accessible */ + usleep_range(BOOTUP_DELAY_US_MIN, BOOTUP_DELAY_US_MAX); janeiro_set_lpm(etdev); edgetpu_chip_init(etdev); |