From b013fe9059682c1a82da6a1bc59504c24d8ec297 Mon Sep 17 00:00:00 2001 From: Jiyu Yang Date: Tue, 21 Jun 2016 21:20:06 +0800 Subject: [PATCH] PD#126286 fix soft reset on midgard The driver will ensure that the GPU is idle before requesting power down. The power down request will be made only when all jobs on all slots have completed (all jobs flush and invalidate on completion meaning the L2 cache will be empty). The power down requests of the shader cores, the tiler and the L2 cache are deferred to the system code that will disable the clock(TODO) and power-off the whole GPU. By bypassing the shader cores and core group power down sequences, and power off the whole GPU instead, allows to this workaround to avoid the beginning of any spurious transaction. ter suspend Change-Id: I048370dc83cb92762217f61b21a0ef3db2da457e --- .../backend/gpu/mali_kbase_pm_driver.c | 29 ++----------- .../backend/gpu/mali_kbase_pm_internal.h | 43 +++++++++++++++++++ .../backend/gpu/mali_kbase_pm_policy.c | 29 +++++++++++++ .../gpu/arm/midgard/mali_kbase_hwaccess_pm.h | 1 + .../devicetree/mali_kbase_runtime_pm.c | 18 ++++++-- 5 files changed, 92 insertions(+), 28 deletions(-) diff --git a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c index 7675c91..d0fa253 100755 --- a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c +++ b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c @@ -49,29 +49,6 @@ /* Special value to indicate that the JM_CONFIG reg isn't currently used. */ #define KBASE_JM_CONFIG_UNUSED (1<<31) -/** - * enum kbasep_pm_action - Actions that can be performed on a core. - * - * This enumeration is private to the file. Its values are set to allow - * core_type_to_reg() function, which decodes this enumeration, to be simpler - * and more efficient. - * - * @ACTION_PRESENT: The cores that are present - * @ACTION_READY: The cores that are ready - * @ACTION_PWRON: Power on the cores specified - * @ACTION_PWROFF: Power off the cores specified - * @ACTION_PWRTRANS: The cores that are transitioning - * @ACTION_PWRACTIVE: The cores that are active - */ -enum kbasep_pm_action { - ACTION_PRESENT = 0, - ACTION_READY = (SHADER_READY_LO - SHADER_PRESENT_LO), - ACTION_PWRON = (SHADER_PWRON_LO - SHADER_PRESENT_LO), - ACTION_PWROFF = (SHADER_PWROFF_LO - SHADER_PRESENT_LO), - ACTION_PWRTRANS = (SHADER_PWRTRANS_LO - SHADER_PRESENT_LO), - ACTION_PWRACTIVE = (SHADER_PWRACTIVE_LO - SHADER_PRESENT_LO) -}; - static u64 kbase_pm_get_state( struct kbase_device *kbdev, enum kbase_pm_core_type core_type, @@ -143,7 +120,7 @@ static void mali_cci_flush_l2(struct kbase_device *kbdev) * @cores: A bit mask of cores to perform the action on (low 32 bits) * @action: The action to perform on the cores */ -static void kbase_pm_invoke(struct kbase_device *kbdev, +void kbase_pm_invoke(struct kbase_device *kbdev, enum kbase_pm_core_type core_type, u64 cores, enum kbasep_pm_action action) @@ -223,6 +200,8 @@ static void kbase_pm_invoke(struct kbase_device *kbdev, kbase_reg_write(kbdev, GPU_CONTROL_REG(reg + 4), hi, NULL); } +KBASE_EXPORT_TEST_API(kbase_pm_invoke); + /** * kbase_pm_get_state - Get information about a core set * @@ -485,7 +464,7 @@ static bool kbase_pm_transition_core_type(struct kbase_device *kbdev, /* Perform transitions if any */ kbase_pm_invoke(kbdev, type, powerup, ACTION_PWRON); - kbase_pm_invoke(kbdev, type, powerdown, ACTION_PWROFF); + //kbase_pm_invoke(kbdev, type, powerdown, ACTION_PWROFF); /* Recalculate cores transitioning on, and re-evaluate our state */ powering_on_trans |= powerup; diff --git a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h index aa51b8c..477bea7 100755 --- a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h +++ b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h @@ -30,6 +30,31 @@ #include "mali_kbase_pm_policy.h" +/** + * enum kbasep_pm_action - Actions that can be performed on a core. + * + * This enumeration is private to the file. Its values are set to allow + * core_type_to_reg() function, which decodes this enumeration, to be simpler + * and more efficient. + * + * @ACTION_PRESENT: The cores that are present + * @ACTION_READY: The cores that are ready + * @ACTION_PWRON: Power on the cores specified + * @ACTION_PWROFF: Power off the cores specified + * @ACTION_PWRTRANS: The cores that are transitioning + * @ACTION_PWRACTIVE: The cores that are active + */ +enum kbasep_pm_action { + ACTION_PRESENT = 0, + ACTION_READY = (SHADER_READY_LO - SHADER_PRESENT_LO), + ACTION_PWRON = (SHADER_PWRON_LO - SHADER_PRESENT_LO), + ACTION_PWROFF = (SHADER_PWROFF_LO - SHADER_PRESENT_LO), + ACTION_PWRTRANS = (SHADER_PWRTRANS_LO - SHADER_PRESENT_LO), + ACTION_PWRACTIVE = (SHADER_PWRACTIVE_LO - SHADER_PRESENT_LO) +}; + + + /** * kbase_pm_dev_idle - The GPU is idle. * @@ -277,6 +302,24 @@ void kbase_pm_update_cores_state(struct kbase_device *kbdev); */ void kbase_pm_cancel_deferred_poweroff(struct kbase_device *kbdev); +/** + * kbase_pm_invoke - Invokes an action on a core set + * + * This function performs the action given by @action on a set of cores of a + * type given by @core_type. It is a static function used by + * kbase_pm_transition_core_type() + * + * @kbdev: The kbase device structure of the device + * @core_type: The type of core that the action should be performed on + * @cores: A bit mask of cores to perform the action on (low 32 bits) + * @action: The action to perform on the cores + */ + +void kbase_pm_invoke(struct kbase_device *kbdev, + enum kbase_pm_core_type core_type, + u64 cores, + enum kbasep_pm_action action); + /** * kbasep_pm_read_present_cores - Read the bitmasks of present cores. * diff --git a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c index 343436f..90648c7 100755 --- a/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c +++ b/t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c @@ -554,6 +554,35 @@ const struct kbase_pm_policy *kbase_pm_get_policy(struct kbase_device *kbdev) KBASE_EXPORT_TEST_API(kbase_pm_get_policy); +int set_policy_by_name(struct kbase_device *kbdev, const char *name) +{ + const struct kbase_pm_policy *new_policy = NULL; + const struct kbase_pm_policy *const *policy_list; + int policy_count; + int i; + + policy_count = kbase_pm_list_policies(&policy_list); + + for (i = 0; i < policy_count; i++) { + if (sysfs_streq(policy_list[i]->name, name)) { + new_policy = policy_list[i]; + break; + } + } + + if (!new_policy) { + printk("power_policy: policy not found\n"); + return -EINVAL; + } + trace_printk("policy name=%s\n", name); + + kbase_pm_set_policy(kbdev, new_policy); + + return 0; +} + +KBASE_EXPORT_TEST_API(set_policy_by_name); + void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_policy *new_policy) { diff --git a/t83x/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h b/t83x/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h index 71c7d49..bae7c0d 100755 --- a/t83x/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h +++ b/t83x/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h @@ -183,6 +183,7 @@ kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy * const **policies); * @return The current policy */ const struct kbase_pm_policy *kbase_pm_get_policy(struct kbase_device *kbdev); +int set_policy_by_name(struct kbase_device *kbdev, const char *name); /** * Change the policy to the one specified. diff --git a/t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c b/t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c index 62f974c..3b3f095 100755 --- a/t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c +++ b/t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c @@ -17,17 +17,17 @@ #include #include +#include +#include #include #include #include #include -#include void *reg_base_hiubus = NULL; u32 override_value_aml = 0; static int first = 1; -extern u64 kbase_pm_get_ready_cores(struct kbase_device *kbdev, enum kbase_pm_core_type type); static void Mali_pwr_on_with_kdev ( struct kbase_device *kbdev, uint32_t mask) { uint32_t part1_done; @@ -163,12 +163,24 @@ ret: static void pm_callback_power_off(struct kbase_device *kbdev) { - dev_dbg(kbdev->dev, "pm_callback_power_off\n"); //printk("%s, %d\n", __FILE__, __LINE__); #if 0 iounmap(reg_base_hiubus); reg_base_hiubus = NULL; #endif + u64 core_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER); + u64 l2_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_L2); + u64 tiler_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_TILER); + + dev_dbg(kbdev->dev, "pm_callback_power_off\n"); + if (core_ready) + kbase_pm_invoke(kbdev, KBASE_PM_CORE_SHADER, core_ready, ACTION_PWROFF); + + if (l2_ready) + kbase_pm_invoke(kbdev, KBASE_PM_CORE_L2, l2_ready, ACTION_PWROFF); + + if (tiler_ready) + kbase_pm_invoke(kbdev, KBASE_PM_CORE_TILER, tiler_ready, ACTION_PWROFF); pm_runtime_put_autosuspend(kbdev->dev); } -- 2.20.1