summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ding <aaronding@google.com>2021-08-18 23:48:12 +0800
committerAaron Ding <aaronding@google.com>2021-08-18 23:48:28 +0800
commit09df8e441354ec8c57a67c74f6ea770e61d16d58 (patch)
tree1504828d55610c1550bce2913a3f8abc3ba061e5
parent22bce3194998638e9df4bc051386f66554bf7865 (diff)
parentb202780572588790b5c001093d2916ab4ddfe62c (diff)
downloadjaneiro-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.c24
-rw-r--r--drivers/edgetpu/edgetpu-device-group.c13
-rw-r--r--drivers/edgetpu/edgetpu-fs.c84
-rw-r--r--drivers/edgetpu/edgetpu-internal.h45
-rw-r--r--drivers/edgetpu/edgetpu-shared-fw.c2
-rw-r--r--drivers/edgetpu/edgetpu-thermal.h13
-rw-r--r--drivers/edgetpu/janeiro-device.c10
-rw-r--r--drivers/edgetpu/janeiro-platform.c9
-rw-r--r--drivers/edgetpu/janeiro-pm.c15
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, &regs);
+ ret = edgetpu_device_add(&edgetpu_pdev->edgetpu_dev, &regs, 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);