summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Peng <robinpeng@google.com>2022-12-13 08:51:02 +0000
committerRobin Peng <robinpeng@google.com>2022-12-13 08:51:02 +0000
commit148b24704f5d989cda60e4aec224996493f61500 (patch)
tree44acbb57e6402788ac02a20b8f60aa180c488753
parent4be679923581b9083035ec594ff480fbd77045ab (diff)
parente3f1d5b556891535c7b79933b15c18d42ab4d666 (diff)
downloadrio-148b24704f5d989cda60e4aec224996493f61500.tar.gz
Merge android13-gs-pixel-5.15 into android14-gs-pixel-5.15
Bug: 260174400 Change-Id: If7b1e790bfc9339c958a3a0b9ea09194f98717e0 Signed-off-by: Robin Peng <robinpeng@google.com>
-rw-r--r--drivers/edgetpu/Kbuild2
-rw-r--r--drivers/edgetpu/Makefile3
-rw-r--r--drivers/edgetpu/edgetpu-domain-pool.c102
-rw-r--r--drivers/edgetpu/edgetpu-domain-pool.h53
-rw-r--r--drivers/edgetpu/edgetpu-google-iommu.c27
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/drivers/gcip/Makefile4
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-domain-pool.c101
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-domain-pool.h49
-rw-r--r--drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h9
9 files changed, 175 insertions, 175 deletions
diff --git a/drivers/edgetpu/Kbuild b/drivers/edgetpu/Kbuild
index 913899b..6bd52cf 100644
--- a/drivers/edgetpu/Kbuild
+++ b/drivers/edgetpu/Kbuild
@@ -13,7 +13,7 @@ endif
GCIP_DIR=gcip-kernel-driver/drivers/gcip
-edgetpu-objs := edgetpu-mailbox.o edgetpu-kci.o edgetpu-telemetry.o edgetpu-mapping.o edgetpu-dmabuf.o edgetpu-async.o edgetpu-iremap-pool.o edgetpu-sw-watchdog.o edgetpu-firmware.o edgetpu-firmware-util.o edgetpu-domain-pool.o $(GCIP_DIR)/gcip.o
+edgetpu-objs := edgetpu-mailbox.o edgetpu-kci.o edgetpu-telemetry.o edgetpu-mapping.o edgetpu-dmabuf.o edgetpu-async.o edgetpu-iremap-pool.o edgetpu-sw-watchdog.o edgetpu-firmware.o edgetpu-firmware-util.o $(GCIP_DIR)/gcip.o
rio-y := rio-device.o rio-device-group.o rio-fs.o rio-core.o rio-platform.o rio-firmware.o rio-thermal.o rio-pm.o rio-debug-dump.o rio-usage-stats.o rio-iommu.o rio-wakelock.o rio-external.o rio-soc.o $(edgetpu-objs)
diff --git a/drivers/edgetpu/Makefile b/drivers/edgetpu/Makefile
index 40416ca..177bbb5 100644
--- a/drivers/edgetpu/Makefile
+++ b/drivers/edgetpu/Makefile
@@ -19,8 +19,7 @@ endif
edgetpu-objs := edgetpu-async.o edgetpu-dmabuf.o edgetpu-iremap-pool.o \
edgetpu-kci.o edgetpu-mailbox.o edgetpu-mapping.o \
edgetpu-sw-watchdog.o edgetpu-telemetry.o \
- edgetpu-firmware-util.o edgetpu-firmware.o \
- edgetpu-domain-pool.o
+ edgetpu-firmware-util.o edgetpu-firmware.o
rio-objs := rio-core.o rio-debug-dump.o rio-device-group.o rio-device.o \
rio-firmware.o rio-fs.o rio-iommu.o rio-platform.o rio-pm.o \
diff --git a/drivers/edgetpu/edgetpu-domain-pool.c b/drivers/edgetpu/edgetpu-domain-pool.c
deleted file mode 100644
index 2989254..0000000
--- a/drivers/edgetpu/edgetpu-domain-pool.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * EdgeTPU IOMMU domain allocator.
- *
- * Copyright (C) 2022 Google, LLC.
- */
-
-#include <linux/idr.h>
-#include <linux/iommu.h>
-#include <linux/slab.h>
-
-#include "edgetpu-domain-pool.h"
-#include "edgetpu-internal.h"
-
-int edgetpu_domain_pool_init(struct edgetpu_dev *etdev, struct edgetpu_domain_pool *pool,
- unsigned int size)
-{
- unsigned int i;
- struct iommu_domain *domain;
-
- pool->size = size;
- pool->etdev = etdev;
-
- if (!size)
- return 0;
-
- etdev_dbg(pool->etdev, "Initializing domain pool with %u domains\n", size);
-
- ida_init(&pool->idp);
- pool->array = vzalloc(sizeof(*pool->array) * size);
- if (!pool->array) {
- etdev_err(etdev, "Failed to allocate memory for domain pool array\n");
- return -ENOMEM;
- }
- for (i = 0; i < size; i++) {
- domain = iommu_domain_alloc(pool->etdev->dev->bus);
- if (!domain) {
- etdev_err(pool->etdev, "Failed to allocate iommu domain %d of %u\n", i + 1,
- size);
- edgetpu_domain_pool_destroy(pool);
- return -ENOMEM;
- }
- pool->array[i] = domain;
- }
- return 0;
-}
-
-struct iommu_domain *edgetpu_domain_pool_alloc(struct edgetpu_domain_pool *pool)
-{
- int id;
-
- if (!pool->size)
- return iommu_domain_alloc(pool->etdev->dev->bus);
-
- id = ida_alloc_max(&pool->idp, pool->size - 1, GFP_KERNEL);
-
- if (id < 0) {
- etdev_err(pool->etdev, "No more domains available from pool of size %u\n",
- pool->size);
- return NULL;
- }
-
- etdev_dbg(pool->etdev, "Allocated domain from pool with id = %d\n", id);
-
- return pool->array[id];
-}
-
-void edgetpu_domain_pool_free(struct edgetpu_domain_pool *pool, struct iommu_domain *domain)
-{
- int id;
-
- if (!pool->size) {
- iommu_domain_free(domain);
- return;
- }
- for (id = 0; id < pool->size; id++) {
- if (pool->array[id] == domain) {
- etdev_dbg(pool->etdev, "Released domain from pool with id = %d\n", id);
- ida_free(&pool->idp, id);
- return;
- }
- }
- etdev_err(pool->etdev, "%s: domain not found in pool", __func__);
-}
-
-void edgetpu_domain_pool_destroy(struct edgetpu_domain_pool *pool)
-{
- int i;
-
- if (!pool->size)
- return;
-
- etdev_dbg(pool->etdev, "Destroying domain pool with %u domains\n", pool->size);
-
- for (i = 0; i < pool->size; i++) {
- if (pool->array[i])
- iommu_domain_free(pool->array[i]);
- }
-
- ida_destroy(&pool->idp);
- vfree(pool->array);
-}
diff --git a/drivers/edgetpu/edgetpu-domain-pool.h b/drivers/edgetpu/edgetpu-domain-pool.h
deleted file mode 100644
index 3dd19d3..0000000
--- a/drivers/edgetpu/edgetpu-domain-pool.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * IOMMU domain allocator for edgetpu
- *
- * Copyright (C) 2022 Google LLC
- */
-
-#ifndef __EDGETPU_DOMAIN_POOL_H__
-#define __EDGETPU_DOMAIN_POOL_H__
-
-#include <linux/idr.h>
-#include <linux/iommu.h>
-
-#include "edgetpu-internal.h"
-
-struct edgetpu_domain_pool {
- struct ida idp; /* ID allocator to keep track of used domains. */
- /*
- * Size of the pool. Can be set to 0, in which case the implementation will fall back to
- * dynamic domain allocation using the IOMMU API directly.
- */
- unsigned int size;
- struct iommu_domain **array; /* Array holding the pointers to pre-allocated domains. */
- struct edgetpu_dev *etdev; /* The edgetpu device used for logging warnings/errors. */
-};
-
-
-/*
- * Initializes a domain pool.
- *
- * @etdev: pointer to edgeptu device.
- * @pool: caller-allocated pool structure.
- * @size: size of the pre-allocated domains pool.
- * Set to zero to fall back to dynamically allocated domains.
- *
- * returns 0 on success or negative error value.
- */
-int edgetpu_domain_pool_init(struct edgetpu_dev *etdev, struct edgetpu_domain_pool *pool,
- unsigned int size);
-
-/*
- * Allocates a domain from the pool
- * returns NULL on error.
- */
-struct iommu_domain *edgetpu_domain_pool_alloc(struct edgetpu_domain_pool *pool);
-
-/* Releases a domain from the pool. */
-void edgetpu_domain_pool_free(struct edgetpu_domain_pool *pool, struct iommu_domain *domain);
-
-/* Cleans up all resources used by the domain pool. */
-void edgetpu_domain_pool_destroy(struct edgetpu_domain_pool *pool);
-
-#endif /* __EDGETPU_DOMAIN_POOL_H__ */
diff --git a/drivers/edgetpu/edgetpu-google-iommu.c b/drivers/edgetpu/edgetpu-google-iommu.c
index 97ec1b9..1aee8df 100644
--- a/drivers/edgetpu/edgetpu-google-iommu.c
+++ b/drivers/edgetpu/edgetpu-google-iommu.c
@@ -13,8 +13,9 @@
#include <linux/slab.h>
#include <linux/types.h>
+#include <gcip/gcip-domain-pool.h>
+
#include "edgetpu-config.h"
-#include "edgetpu-domain-pool.h"
#include "edgetpu-internal.h"
#include "edgetpu-mapping.h"
#include "edgetpu-mmu.h"
@@ -43,7 +44,7 @@ struct edgetpu_iommu {
* required.
* The implementation will fall back to dynamically allocated domains otherwise.
*/
- struct edgetpu_domain_pool domain_pool;
+ struct gcip_domain_pool domain_pool;
};
@@ -145,7 +146,7 @@ static int edgetpu_idr_free_domain_callback(int id, void *p, void *data)
struct iommu_domain *domain = p;
struct edgetpu_iommu *etiommu = data;
- edgetpu_domain_pool_free(&etiommu->domain_pool, domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, domain);
return 0;
}
@@ -194,7 +195,7 @@ static int check_default_domain(struct edgetpu_dev *etdev,
if (!etiommu->aux_enabled)
return -EINVAL;
- domain = edgetpu_domain_pool_alloc(&etiommu->domain_pool);
+ domain = gcip_domain_pool_alloc(&etiommu->domain_pool);
if (!domain) {
etdev_warn(etdev, "iommu domain alloc failed");
return -EINVAL;
@@ -202,7 +203,7 @@ static int check_default_domain(struct edgetpu_dev *etdev,
ret = iommu_aux_attach_device(domain, etdev->dev);
if (ret) {
etdev_warn(etdev, "Attach IOMMU aux failed: %d", ret);
- edgetpu_domain_pool_free(&etiommu->domain_pool, domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, domain);
return ret;
}
pasid = iommu_aux_get_pasid(domain, etdev->dev);
@@ -211,7 +212,7 @@ static int check_default_domain(struct edgetpu_dev *etdev,
etdev_warn(etdev, "Invalid PASID %d returned from iommu\n",
pasid);
iommu_aux_detach_device(domain, etdev->dev);
- edgetpu_domain_pool_free(&etiommu->domain_pool, domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, domain);
return -EINVAL;
}
out:
@@ -228,7 +229,7 @@ int edgetpu_mmu_attach(struct edgetpu_dev *etdev, void *mmu_info)
etiommu = kzalloc(sizeof(*etiommu), GFP_KERNEL);
if (!etiommu)
return -ENOMEM;
- ret = edgetpu_domain_pool_init(etdev, &etiommu->domain_pool,
+ ret = gcip_domain_pool_init(etdev->dev, &etiommu->domain_pool,
EDGETPU_NUM_PREALLOCATED_DOMAINS);
idr_init(&etiommu->domain_id_pool);
mutex_init(&etiommu->pool_lock);
@@ -286,12 +287,12 @@ void edgetpu_mmu_detach(struct edgetpu_dev *etdev)
/* free the domain if the context 0 domain is not default */
if (!etiommu->context_0_default && etiommu->domains[0])
- edgetpu_domain_pool_free(&etiommu->domain_pool, etiommu->domains[0]);
+ gcip_domain_pool_free(&etiommu->domain_pool, etiommu->domains[0]);
idr_for_each(&etiommu->domain_id_pool, edgetpu_idr_free_domain_callback,
etiommu);
idr_destroy(&etiommu->domain_id_pool);
- edgetpu_domain_pool_destroy(&etiommu->domain_pool);
+ gcip_domain_pool_destroy(&etiommu->domain_pool);
kfree(etiommu);
etdev->mmu_cookie = NULL;
}
@@ -605,7 +606,7 @@ struct edgetpu_iommu_domain *edgetpu_mmu_alloc_domain(struct edgetpu_dev *etdev)
if (!etiommu->aux_enabled)
return &invalid_etdomain;
- domain = edgetpu_domain_pool_alloc(&etiommu->domain_pool);
+ domain = gcip_domain_pool_alloc(&etiommu->domain_pool);
if (!domain) {
etdev_warn(etdev, "iommu domain allocation failed");
return NULL;
@@ -613,7 +614,7 @@ struct edgetpu_iommu_domain *edgetpu_mmu_alloc_domain(struct edgetpu_dev *etdev)
etdomain = kzalloc(sizeof(*etdomain), GFP_KERNEL);
if (!etdomain) {
- edgetpu_domain_pool_free(&etiommu->domain_pool, domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, domain);
return NULL;
}
@@ -624,7 +625,7 @@ struct edgetpu_iommu_domain *edgetpu_mmu_alloc_domain(struct edgetpu_dev *etdev)
if (token < 0) {
etdev_warn(etdev, "alloc iommu domain token failed: %d", token);
kfree(etdomain);
- edgetpu_domain_pool_free(&etiommu->domain_pool, domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, domain);
return NULL;
}
@@ -646,7 +647,7 @@ void edgetpu_mmu_free_domain(struct edgetpu_dev *etdev,
mutex_lock(&etiommu->pool_lock);
idr_remove(&etiommu->domain_id_pool, etdomain->token);
mutex_unlock(&etiommu->pool_lock);
- edgetpu_domain_pool_free(&etiommu->domain_pool, etdomain->iommu_domain);
+ gcip_domain_pool_free(&etiommu->domain_pool, etdomain->iommu_domain);
kfree(etdomain);
}
diff --git a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/Makefile b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/Makefile
index 7f6d2f0..2f34448 100644
--- a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/Makefile
+++ b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/Makefile
@@ -6,8 +6,8 @@
CONFIG_GCIP ?= m
obj-$(CONFIG_GCIP) += gcip.o
-gcip-objs := gcip-firmware.o gcip-image-config.o gcip-kci.o gcip-mailbox.o \
- gcip-mem-pool.o gcip-telemetry.o
+gcip-objs := gcip-domain-pool.o gcip-firmware.o gcip-image-config.o gcip-kci.o \
+ gcip-mailbox.o gcip-mem-pool.o gcip-telemetry.o
CURRENT_DIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
diff --git a/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-domain-pool.c b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-domain-pool.c
new file mode 100644
index 0000000..2341b52
--- /dev/null
+++ b/drivers/edgetpu/gcip-kernel-driver/drivers/gcip/gcip-domain-pool.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GCIP IOMMU domain allocator.
+ *
+ * Copyright (C) 2022 Google LLC
+ */
+
+#include <linux/device.h>
+#include <linux/idr.h>
+#include <linux/iommu.h>
+#include <linux/vmalloc.h>
+
+#include <gcip/gcip-domain-pool.h>
+
+int gcip_domain_pool_init(struct device *dev, struct gcip_domain_pool *pool, unsigned int size)
+{
+ unsigned int i;
+ struct iommu_domain *domain;
+
+ pool->size = size;
+ pool->dev = dev;
+
+ if (!size)
+ return 0;
+
+ dev_dbg(pool->dev, "Initializing domain pool with %u domains\n", size);
+
+ ida_init(&pool->idp);
+ pool->array = vzalloc(sizeof(*pool->array) * size);
+ if (!pool->array) {
+ ida_destroy(&pool->idp);
+ return -ENOMEM;
+ }
+ for (i = 0; i < size; i++) {
+ domain = iommu_domain_alloc(dev->bus);
+ if (!domain) {
+ dev_err(pool->dev, "Failed to allocate iommu domain %d of %u\n", i + 1,
+ size);
+ gcip_domain_pool_destroy(pool);
+ return -ENOMEM;
+ }
+
+ pool->array[i] = domain;
+ }
+ return 0;
+}
+
+struct iommu_domain *gcip_domain_pool_alloc(struct gcip_domain_pool *pool)
+{
+ int id;
+
+ if (!pool->size)
+ return iommu_domain_alloc(pool->dev->bus);
+
+ id = ida_alloc_max(&pool->idp, pool->size - 1, GFP_KERNEL);
+
+ if (id < 0) {
+ dev_err(pool->dev, "No more domains available from pool of size %u\n", pool->size);
+ return NULL;
+ }
+
+ dev_dbg(pool->dev, "Allocated domain from pool with id = %d\n", id);
+
+ return pool->array[id];
+}
+
+void gcip_domain_pool_free(struct gcip_domain_pool *pool, struct iommu_domain *domain)
+{
+ int id;
+
+ if (!pool->size) {
+ iommu_domain_free(domain);
+ return;
+ }
+ for (id = 0; id < pool->size; id++) {
+ if (pool->array[id] == domain) {
+ dev_dbg(pool->dev, "Released domain from pool with id = %d\n", id);
+ ida_free(&pool->idp, id);
+ return;
+ }
+ }
+ dev_err(pool->dev, "Domain not found in pool\n");
+}
+
+void gcip_domain_pool_destroy(struct gcip_domain_pool *pool)
+{
+ int i;
+
+ if (!pool->size)
+ return;
+
+ dev_dbg(pool->dev, "Destroying domain pool with %u domains\n", pool->size);
+
+ for (i = 0; i < pool->size; i++) {
+ if (pool->array[i])
+ iommu_domain_free(pool->array[i]);
+ }
+
+ ida_destroy(&pool->idp);
+ vfree(pool->array);
+}
diff --git a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-domain-pool.h b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-domain-pool.h
new file mode 100644
index 0000000..b740bf9
--- /dev/null
+++ b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-domain-pool.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * GCIP IOMMU domain allocator.
+ *
+ * Copyright (C) 2022 Google LLC
+ */
+
+#ifndef __GCIP_DOMAIN_POOL_H__
+#define __GCIP_DOMAIN_POOL_H__
+
+#include <linux/idr.h>
+#include <linux/iommu.h>
+
+struct gcip_domain_pool {
+ struct ida idp; /* ID allocator to keep track of used domains. */
+ /*
+ * Size of the pool. Can be set to 0, in which case the implementation will fall back to
+ * dynamic domain allocation using the IOMMU API directly.
+ */
+ unsigned int size;
+ struct iommu_domain **array; /* Array holding the pointers to pre-allocated domains. */
+ struct device *dev; /* The device used for logging warnings/errors. */
+};
+
+/*
+ * Initializes a domain pool.
+ *
+ * @dev: pointer to device structure.
+ * @pool: caller-allocated pool structure.
+ * @size: size of the pre-allocated domains pool.
+ * Set to zero to fall back to dynamically allocated domains.
+ *
+ * returns 0 on success or negative error value.
+ */
+int gcip_domain_pool_init(struct device *dev, struct gcip_domain_pool *pool, unsigned int size);
+
+/*
+ * Allocates a domain from the pool
+ * returns NULL on error.
+ */
+struct iommu_domain *gcip_domain_pool_alloc(struct gcip_domain_pool *pool);
+
+/* Releases a domain from the pool. */
+void gcip_domain_pool_free(struct gcip_domain_pool *pool, struct iommu_domain *domain);
+
+/* Cleans up all resources used by the domain pool. */
+void gcip_domain_pool_destroy(struct gcip_domain_pool *pool);
+
+#endif /* __GCIP_DOMAIN_POOL_H__ */
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 74e44ae..bda1b40 100644
--- a/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h
+++ b/drivers/edgetpu/gcip-kernel-driver/include/gcip/gcip-kci.h
@@ -93,10 +93,10 @@ enum gcip_kci_code {
GCIP_KCI_CODE_GET_USAGE = 12,
GCIP_KCI_CODE_NOTIFY_THROTTLING = 13,
GCIP_KCI_CODE_BLOCK_BUS_SPEED_CONTROL = 14,
- /* TODO(b/237955391): Update this code after decided. */
GCIP_KCI_CODE_ALLOCATE_VMBOX = 15,
- /* TODO(b/237955391): Update this code after decided. */
GCIP_KCI_CODE_RELEASE_VMBOX = 16,
+ GCIP_KCI_CODE_LINK_OFFLOAD_VMBOX = 17,
+ GCIP_KCI_CODE_UNLINK_OFFLOAD_VMBOX = 18,
GCIP_KCI_CODE_RKCI_ACK = 256,
};
@@ -140,6 +140,11 @@ enum gcip_kci_error {
GCIP_KCI_ERROR_UNAUTHENTICATED = 16,
};
+/* Type of the chip of the offload vmbox to be linked. */
+enum gcip_kci_offload_chip_type {
+ GCIP_KCI_OFFLOAD_CHIP_TYPE_TPU = 0,
+};
+
/*
* Reason for triggering the CMD doorbell.
* The CMD doorbell is triggered either when a CMD is pushed or the RESP that might blocks the FW is