diff options
author | Sidath Senanayake <sidaths@google.com> | 2021-06-17 17:58:22 +0100 |
---|---|---|
committer | Sidath Senanayake <sidaths@google.com> | 2021-06-17 17:58:22 +0100 |
commit | 2bfaaa5f53c45ab7b4f6daba20e92ef6d16ab53b (patch) | |
tree | 8cd2a6a47f2a590ed7bed11afdcb9e52f7232c4f /mali_kbase/arbiter | |
parent | fca8613cfcf585bf9113dca96a05daea9fd89794 (diff) | |
download | gpu-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/Kbuild | 6 | ||||
-rw-r--r-- | mali_kbase/arbiter/mali_kbase_arbif.c | 14 | ||||
-rw-r--r-- | mali_kbase/arbiter/mali_kbase_arbif.h | 7 | ||||
-rw-r--r-- | mali_kbase/arbiter/mali_kbase_arbiter_interface.h | 5 | ||||
-rw-r--r-- | mali_kbase/arbiter/mali_kbase_arbiter_pm.c | 100 | ||||
-rw-r--r-- | mali_kbase/arbiter/mali_kbase_arbiter_pm.h | 18 |
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_ */ |