summaryrefslogtreecommitdiff
path: root/mali_kbase/arbiter
diff options
context:
space:
mode:
authorSidath Senanayake <sidaths@google.com>2021-06-17 17:58:22 +0100
committerSidath Senanayake <sidaths@google.com>2021-06-17 17:58:22 +0100
commit2bfaaa5f53c45ab7b4f6daba20e92ef6d16ab53b (patch)
tree8cd2a6a47f2a590ed7bed11afdcb9e52f7232c4f /mali_kbase/arbiter
parentfca8613cfcf585bf9113dca96a05daea9fd89794 (diff)
downloadgpu-2bfaaa5f53c45ab7b4f6daba20e92ef6d16ab53b.tar.gz
Mali Valhall DDK r32p1 BETA KMD
Provenance: 59f633569 (collaborate/google/android/v_r32p1-00bet0) VX504X08X-BU-00000-r32p1-00bet0 - Valhall Android DDK VX504X08X-BU-60000-r32p1-00bet0 - Valhall Android Document Bundle VX504X08X-DC-11001-r32p1-00bet0 - Valhall Android DDK Software Errata VX504X08X-SW-99006-r32p1-00bet0 - Valhall Android Renderscript AOSP parts Signed-off-by: Sidath Senanayake <sidaths@google.com> Change-Id: I6c9fc6e1e9f2e58bc804eb79582ad7afaafdef1b
Diffstat (limited to 'mali_kbase/arbiter')
-rw-r--r--mali_kbase/arbiter/Kbuild6
-rw-r--r--mali_kbase/arbiter/mali_kbase_arbif.c14
-rw-r--r--mali_kbase/arbiter/mali_kbase_arbif.h7
-rw-r--r--mali_kbase/arbiter/mali_kbase_arbiter_interface.h5
-rw-r--r--mali_kbase/arbiter/mali_kbase_arbiter_pm.c100
-rw-r--r--mali_kbase/arbiter/mali_kbase_arbiter_pm.h18
6 files changed, 128 insertions, 22 deletions
diff --git a/mali_kbase/arbiter/Kbuild b/mali_kbase/arbiter/Kbuild
index f81aa75..4491fc6 100644
--- a/mali_kbase/arbiter/Kbuild
+++ b/mali_kbase/arbiter/Kbuild
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
#
-# (C) COPYRIGHT 2019-2020 ARM Limited. All rights reserved.
+# (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the
# GNU General Public License version 2 as published by the Free Software
@@ -19,5 +19,5 @@
#
mali_kbase-y += \
- arbiter/mali_kbase_arbif.o \
- arbiter/mali_kbase_arbiter_pm.o
+ arbiter/mali_kbase_arbif.o \
+ arbiter/mali_kbase_arbiter_pm.o
diff --git a/mali_kbase/arbiter/mali_kbase_arbif.c b/mali_kbase/arbiter/mali_kbase_arbif.c
index 7d6ab0c..bd78c66 100644
--- a/mali_kbase/arbiter/mali_kbase_arbif.c
+++ b/mali_kbase/arbiter/mali_kbase_arbif.c
@@ -170,11 +170,15 @@ static void on_gpu_lost(struct device *dev)
*
* Initialise Kbase Arbiter interface and assign callback functions.
*
- * Return: 0 on success else a Linux error code
+ * Return:
+ * * 0 - the interface was initialized or was not specified
+ * * in the device tree.
+ * * -EFAULT - the interface was specified but failed to initialize.
+ * * -EPROBE_DEFER - module dependencies are not yet available.
*/
int kbase_arbif_init(struct kbase_device *kbdev)
{
-#ifdef CONFIG_OF
+#if IS_ENABLED(CONFIG_OF)
struct arbiter_if_arb_vm_ops ops;
struct arbiter_if_dev *arb_if;
struct device_node *arbiter_if_node;
@@ -218,8 +222,8 @@ int kbase_arbif_init(struct kbase_device *kbdev)
ops.arb_vm_max_config = on_max_config;
ops.arb_vm_update_freq = on_update_freq;
-
kbdev->arb.arb_freq.arb_freq = 0;
+ kbdev->arb.arb_freq.freq_updated = false;
mutex_init(&kbdev->arb.arb_freq.arb_freq_lock);
/* register kbase arbiter_if callbacks */
@@ -229,6 +233,8 @@ int kbase_arbif_init(struct kbase_device *kbdev)
if (err) {
dev_err(&pdev->dev, "Failed to register with arbiter\n");
module_put(pdev->dev.driver->owner);
+ if (err != -EPROBE_DEFER)
+ err = -EFAULT;
return err;
}
}
@@ -307,6 +313,8 @@ void kbase_arbif_gpu_stopped(struct kbase_device *kbdev, u8 gpu_required)
if (arb_if && arb_if->vm_ops.vm_arb_gpu_stopped) {
dev_dbg(kbdev->dev, "%s\n", __func__);
KBASE_TLSTREAM_TL_ARBITER_STOPPED(kbdev, kbdev);
+ if (gpu_required)
+ KBASE_TLSTREAM_TL_ARBITER_REQUESTED(kbdev, kbdev);
arb_if->vm_ops.vm_arb_gpu_stopped(arb_if, gpu_required);
}
}
diff --git a/mali_kbase/arbiter/mali_kbase_arbif.h b/mali_kbase/arbiter/mali_kbase_arbif.h
index 710559c..531c910 100644
--- a/mali_kbase/arbiter/mali_kbase_arbif.h
+++ b/mali_kbase/arbiter/mali_kbase_arbif.h
@@ -57,8 +57,11 @@ enum kbase_arbif_evt {
* Initialize the arbiter interface and also determines
* if Arbiter functionality is required.
*
- * Return: 0 if the Arbiter interface was successfully initialized or the
- * Arbiter was not required.
+ * Return:
+ * * 0 - the interface was initialized or was not specified
+ * * in the device tree.
+ * * -EFAULT - the interface was specified but failed to initialize.
+ * * -EPROBE_DEFER - module dependencies are not yet available.
*/
int kbase_arbif_init(struct kbase_device *kbdev);
diff --git a/mali_kbase/arbiter/mali_kbase_arbiter_interface.h b/mali_kbase/arbiter/mali_kbase_arbiter_interface.h
index 84389e8..1b4365e 100644
--- a/mali_kbase/arbiter/mali_kbase_arbiter_interface.h
+++ b/mali_kbase/arbiter/mali_kbase_arbiter_interface.h
@@ -132,6 +132,11 @@ struct arbiter_if_vm_arb_ops {
* @dev: The device structure to supply in the callbacks.
* @ops: The callbacks that the device driver supports
* (none are optional).
+ *
+ * Return:
+ * * 0 - successful.
+ * * -EINVAL - invalid argument.
+ * * -EPROBE_DEFER - module dependencies are not yet available.
*/
int (*vm_arb_register_dev)(struct arbiter_if_dev *arbif_dev,
struct device *dev, struct arbiter_if_arb_vm_ops *ops);
diff --git a/mali_kbase/arbiter/mali_kbase_arbiter_pm.c b/mali_kbase/arbiter/mali_kbase_arbiter_pm.c
index 456cc70..a5deded 100644
--- a/mali_kbase/arbiter/mali_kbase_arbiter_pm.c
+++ b/mali_kbase/arbiter/mali_kbase_arbiter_pm.c
@@ -27,9 +27,9 @@
#include <mali_kbase.h>
#include <mali_kbase_pm.h>
#include <mali_kbase_hwaccess_jm.h>
-#include <mali_kbase_irq_internal.h>
+#include <backend/gpu/mali_kbase_irq_internal.h>
#include <mali_kbase_hwcnt_context.h>
-#include <mali_kbase_pm_internal.h>
+#include <backend/gpu/mali_kbase_pm_internal.h>
#include <tl/mali_kbase_tracepoints.h>
#include <mali_kbase_gpuprops.h>
@@ -37,6 +37,7 @@
* after the following time (in milliseconds) has ellapsed.
*/
#define GPU_REQUEST_TIMEOUT 1000
+#define KHZ_TO_HZ 1000
#define MAX_L2_SLICES_MASK 0xFF
@@ -528,8 +529,16 @@ int kbase_arbiter_pm_gpu_assigned(struct kbase_device *kbdev)
static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
{
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
+ bool freq_updated = false;
lockdep_assert_held(&arb_vm_state->vm_state_lock);
+ mutex_lock(&kbdev->arb.arb_freq.arb_freq_lock);
+ if (kbdev->arb.arb_freq.freq_updated) {
+ kbdev->arb.arb_freq.freq_updated = false;
+ freq_updated = true;
+ }
+ mutex_unlock(&kbdev->arb.arb_freq.arb_freq_lock);
+
cancel_request_timer(kbdev);
switch (arb_vm_state->vm_state) {
case KBASE_VM_STATE_INITIALIZING:
@@ -555,9 +564,16 @@ static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_SUSPENDED);
break;
default:
- dev_warn(kbdev->dev,
- "GPU_GRANTED when not expected - state %s\n",
- kbase_arbiter_pm_vm_state_str(arb_vm_state->vm_state));
+ /*
+ * GPU_GRANTED can be received when there is a frequency update
+ * Only show a warning if received in an unexpected state
+ * without a frequency update
+ */
+ if (!freq_updated)
+ dev_warn(kbdev->dev,
+ "GPU_GRANTED when not expected - state %s\n",
+ kbase_arbiter_pm_vm_state_str(
+ arb_vm_state->vm_state));
break;
}
}
@@ -1005,13 +1021,25 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
* kbase_arbiter_pm_update_gpu_freq() - Updates GPU clock frequency received
* from arbiter.
* @arb_freq - Pointer to struchture holding GPU clock frequenecy data
- * @freq - New frequency value
+ * @freq - New frequency value in KHz
*/
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
- uint32_t freq)
+ uint32_t freq)
{
+ struct kbase_gpu_clk_notifier_data ndata;
+
mutex_lock(&arb_freq->arb_freq_lock);
- arb_freq->arb_freq = freq;
+ if (arb_freq->arb_freq != freq) {
+ ndata.new_rate = freq * KHZ_TO_HZ;
+ ndata.old_rate = arb_freq->arb_freq * KHZ_TO_HZ;
+ ndata.gpu_clk_handle = arb_freq;
+ arb_freq->arb_freq = freq;
+ arb_freq->freq_updated = true;
+ if (arb_freq->nb)
+ arb_freq->nb->notifier_call(arb_freq->nb,
+ POST_RATE_CHANGE, &ndata);
+ }
+
mutex_unlock(&arb_freq->arb_freq_lock);
}
@@ -1046,14 +1074,64 @@ static unsigned long get_arb_gpu_clk_rate(struct kbase_device *kbdev,
(struct kbase_arbiter_freq *) gpu_clk_handle;
mutex_lock(&arb_dev_freq->arb_freq_lock);
- freq = arb_dev_freq->arb_freq;
+ /* Convert from KHz to Hz */
+ freq = arb_dev_freq->arb_freq * KHZ_TO_HZ;
mutex_unlock(&arb_dev_freq->arb_freq_lock);
return freq;
}
+/**
+ * arb_gpu_clk_notifier_register() - Register a clock rate change notifier.
+ * @kbdev - kbase_device pointer
+ * @gpu_clk_handle - Handle unique to the enumerated GPU clock
+ * @nb - notifier block containing the callback function pointer
+ *
+ * Returns 0 on success, negative error code otherwise.
+ *
+ * This function registers a callback function that is invoked whenever the
+ * frequency of the clock corresponding to @gpu_clk_handle changes.
+ */
+static int arb_gpu_clk_notifier_register(struct kbase_device *kbdev,
+ void *gpu_clk_handle, struct notifier_block *nb)
+{
+ int ret = 0;
+ struct kbase_arbiter_freq *arb_dev_freq =
+ (struct kbase_arbiter_freq *)gpu_clk_handle;
+
+ if (!arb_dev_freq->nb)
+ arb_dev_freq->nb = nb;
+ else
+ ret = -EBUSY;
+
+ return ret;
+}
+
+/**
+ * gpu_clk_notifier_unregister() - Unregister clock rate change notifier
+ * @kbdev - kbase_device pointer
+ * @gpu_clk_handle - Handle unique to the enumerated GPU clock
+ * @nb - notifier block containing the callback function pointer
+ *
+ * This function pointer is used to unregister a callback function that
+ * was previously registered to get notified of a frequency change of the
+ * clock corresponding to @gpu_clk_handle.
+ */
+static void arb_gpu_clk_notifier_unregister(struct kbase_device *kbdev,
+ void *gpu_clk_handle, struct notifier_block *nb)
+{
+ struct kbase_arbiter_freq *arb_dev_freq =
+ (struct kbase_arbiter_freq *)gpu_clk_handle;
+ if (arb_dev_freq->nb == nb) {
+ arb_dev_freq->nb = NULL;
+ } else {
+ dev_err(kbdev->dev, "%s - notifier did not match\n",
+ __func__);
+ }
+}
+
struct kbase_clk_rate_trace_op_conf arb_clk_rate_trace_ops = {
.get_gpu_clk_rate = get_arb_gpu_clk_rate,
.enumerate_gpu_clk = enumerate_arb_gpu_clk,
- .gpu_clk_notifier_register = NULL,
- .gpu_clk_notifier_unregister = NULL
+ .gpu_clk_notifier_register = arb_gpu_clk_notifier_register,
+ .gpu_clk_notifier_unregister = arb_gpu_clk_notifier_unregister
};
diff --git a/mali_kbase/arbiter/mali_kbase_arbiter_pm.h b/mali_kbase/arbiter/mali_kbase_arbiter_pm.h
index 0f74b63..b35d1b7 100644
--- a/mali_kbase/arbiter/mali_kbase_arbiter_pm.h
+++ b/mali_kbase/arbiter/mali_kbase_arbiter_pm.h
@@ -168,15 +168,27 @@ extern struct kbase_clk_rate_trace_op_conf arb_clk_rate_trace_ops;
/**
* struct kbase_arbiter_freq - Holding the GPU clock frequency data retrieved
* from arbiter
- * @arb_freq: GPU clock frequency value
- * @arb_freq_lock: Mutex protecting access to arbfreq value
+ * @arb_freq: GPU clock frequency value
+ * @arb_freq_lock: Mutex protecting access to arbfreq value
+ * @nb: Notifier block to receive rate change callbacks
+ * @freq_updated: Flag to indicate whether a frequency changed has just been
+ * communicated to avoid "GPU_GRANTED when not expected" warning
*/
struct kbase_arbiter_freq {
uint32_t arb_freq;
struct mutex arb_freq_lock;
+ struct notifier_block *nb;
+ bool freq_updated;
};
+/**
+ * kbase_arbiter_pm_update_gpu_freq() - Update GPU frequency
+ * @arb_freq: Pointer to GPU clock frequency data
+ * @freq: The new frequency
+ *
+ * Updates the GPU frequency and triggers any notifications
+ */
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
- uint32_t freq);
+ uint32_t freq);
#endif /*_MALI_KBASE_ARBITER_PM_H_ */