summaryrefslogtreecommitdiff
path: root/gxp-vd.c
diff options
context:
space:
mode:
authorNeela Chithirala <chithiralan@google.com>2022-01-17 04:41:54 +0000
committerNeela Chithirala <chithiralan@google.com>2022-02-03 06:27:20 +0000
commit3ccb2479717de3089dbbcb894ddd045b2ddc256c (patch)
treea577f284ff42d11b1fcfb7c338a7f0b59b10672a /gxp-vd.c
parente14069f1739b05c7a7f60ae73c8ce14b91ef12e0 (diff)
downloadgs201-3ccb2479717de3089dbbcb894ddd045b2ddc256c.tar.gz
Merge branch 'gs201-release' to android13-gs-pixel-5.10
* gs201-release: gxp: Fix multicore VDs not shutting down clean Bug: 215303765 gxp: Rework VD locking and remove mailbox locking Bug: 189018271 gxp: initial commit for thermal driver Bug: 177217526 gxp: Add wakelock interface and make debugfs wakelock aware Bug: 215192870 gxp: Hook-up pm ops for driver suspend/resume Bug: 204924965 gxp: Dynamically power BLK_AUR on and off Bug: 204924965 gxp: support GXP_PLATFORM=GEM5 Bug: 204942713 gxp: Remove delay waiting for FW mailbox init Bug: 207037428 gxp: Fix infrequent crash during mailbox release gxp: Release FW file on firmware loading errors gxp: return GXP_RESP_CANCELLED if timeout occurs Bug: 207432733 gxp: Remove initial 10ms delay when disabling telemetry gxp: Cast telemetry buffer IOVAs to u32s before use gxp: check sscoredump by CONFIG_SUBSYSTEM_COREDUMP gxp: Fix double-lock hang in gxp_telemetry_vma_close gxp: Log driver git commit hash on probe Bug: 206744969 gxp: Add ioctl for reading the TOP global counter gxp: Implement eventfd signalling for telemetry gxp: Notify running cores of telemetry state changes gxp: Add notification interface Signed-off-by: Neela Chithirala <chithiralan@google.com> Change-Id: Ic7cd7b81ee643371c600ac208ae33d6344ed7f1b
Diffstat (limited to 'gxp-vd.c')
-rw-r--r--gxp-vd.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/gxp-vd.c b/gxp-vd.c
index fcb99ea..bc5a6e3 100644
--- a/gxp-vd.c
+++ b/gxp-vd.c
@@ -21,33 +21,43 @@ int gxp_vd_init(struct gxp_dev *gxp)
uint core;
int ret;
- mutex_init(&gxp->vd_lock);
- mutex_lock(&gxp->vd_lock);
+ init_rwsem(&gxp->vd_semaphore);
- /* Mark all cores as free */
+ /* All cores start as free */
for (core = 0; core < GXP_NUM_CORES; core++)
gxp->core_to_client[core] = NULL;
ret = gxp_fw_init(gxp);
- mutex_unlock(&gxp->vd_lock);
+
return ret;
}
void gxp_vd_destroy(struct gxp_dev *gxp)
{
- mutex_lock(&gxp->vd_lock);
+ down_write(&gxp->vd_semaphore);
gxp_fw_destroy(gxp);
- mutex_unlock(&gxp->vd_lock);
+ up_write(&gxp->vd_semaphore);
}
-/* Caller must hold gxp->vd_lock */
+/* Caller must hold gxp->vd_semaphore for writing */
static void gxp_vd_release(struct gxp_client *client)
{
uint core;
struct gxp_dev *gxp = client->gxp;
+ /*
+ * Put all cores in the VD into reset so they can not wake each other up
+ */
+ for (core = 0; core < GXP_NUM_CORES; core++) {
+ if (gxp->core_to_client[core] == client) {
+ gxp_write_32_core(
+ gxp, core, GXP_REG_ETM_PWRCTL,
+ 1 << GXP_REG_ETM_PWRCTL_CORE_RESET_SHIFT);
+ }
+ }
+
for (core = 0; core < GXP_NUM_CORES; core++) {
if (gxp->core_to_client[core] == client) {
gxp->core_to_client[core] = NULL;
@@ -60,7 +70,7 @@ static void gxp_vd_release(struct gxp_client *client)
}
}
-/* Caller must hold gxp->vd_lock */
+/* Caller must hold gxp->vd_semaphore for writing */
int gxp_vd_allocate(struct gxp_client *client, u16 requested_cores)
{
struct gxp_dev *gxp = client->gxp;
@@ -133,10 +143,10 @@ int gxp_vd_virt_core_to_phys_core(struct gxp_client *client, u16 virt_core)
uint phys_core;
uint virt_core_index = 0;
- mutex_lock(&gxp->vd_lock);
+ down_read(&gxp->vd_semaphore);
if (!client->vd_allocated) {
- mutex_unlock(&gxp->vd_lock);
+ up_read(&gxp->vd_semaphore);
dev_dbg(gxp->dev, "Client has not allocated a virtual device\n");
return -EINVAL;
}
@@ -145,7 +155,7 @@ int gxp_vd_virt_core_to_phys_core(struct gxp_client *client, u16 virt_core)
if (gxp->core_to_client[phys_core] == client) {
if (virt_core_index == virt_core) {
/* Found virtual core */
- mutex_unlock(&gxp->vd_lock);
+ up_read(&gxp->vd_semaphore);
return phys_core;
}
@@ -153,7 +163,7 @@ int gxp_vd_virt_core_to_phys_core(struct gxp_client *client, u16 virt_core)
}
}
- mutex_unlock(&gxp->vd_lock);
+ up_read(&gxp->vd_semaphore);
dev_dbg(gxp->dev, "No mapping for virtual core %u\n", virt_core);
return -EINVAL;
}
@@ -207,18 +217,18 @@ void gxp_client_destroy(struct gxp_client *client)
{
struct gxp_dev *gxp = client->gxp;
- mutex_lock(&gxp->vd_lock);
+ down_write(&gxp->vd_semaphore);
-#ifdef CONFIG_ANDROID
+#if IS_ENABLED(CONFIG_ANDROID) && !IS_ENABLED(CONFIG_GXP_GEM5)
/*
* Unmap TPU buffers, if the mapping is already removed, this
* is a no-op.
*/
gxp_dma_unmap_tpu_buffer(gxp, client->mbx_desc);
-#endif // CONFIG_ANDROID
+#endif // CONFIG_ANDROID && !CONFIG_GXP_GEM5
gxp_vd_release(client);
- mutex_unlock(&gxp->vd_lock);
+ up_write(&gxp->vd_semaphore);
kfree(client);
}