msm: kgsl: Add support for clk_set_options() to enable NAP feature

Add support for clk_set_options() to have memory retention for core
clock during NAP.

Change-Id: I0eee48472b1ad4b9dc6eee13334c6cf0b29d8461
Signed-off-by: Hareesh Gundu <hareeshg@codeaurora.org>
This commit is contained in:
Hareesh Gundu 2020-07-06 17:00:53 +05:30
commit 4189ea98b8
4 changed files with 71 additions and 9 deletions

View file

@ -3,6 +3,7 @@
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/clk/qcom.h>
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/of_device.h>
@ -1366,11 +1367,30 @@ static void a3xx_microcode_load(struct adreno_device *adreno_dev)
adreno_dev->fw[ADRENO_FW_PFP].fwvirt[i]);
}
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
static void a3xx_clk_set_options(struct adreno_device *adreno_dev,
const char *name, struct clk *clk, bool on)
{
WARN(adreno_is_a306a(adreno_dev), "clk_set_flags() not supported\n");
if (!adreno_is_a306a(adreno_dev))
return;
/* Handle clock settings for GFX PSCBCs */
if (on) {
if (!strcmp(name, "mem_iface_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
} else if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_MEM);
}
} else {
if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
}
}
}
#endif
static u64 a3xx_read_alwayson(struct adreno_device *adreno_dev)
{
@ -1438,7 +1458,9 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a3xx_coresight},
#endif
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
.clk_set_options = a3xx_clk_set_options,
#endif
.read_alwayson = a3xx_read_alwayson,
.hw_isidle = a3xx_hw_isidle,
.power_ops = &adreno_power_operations,

View file

@ -3,6 +3,7 @@
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/clk/qcom.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/of.h>
@ -1141,13 +1142,31 @@ static void a5xx_pwrlevel_change_settings(struct adreno_device *adreno_dev,
}
}
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
static void a5xx_clk_set_options(struct adreno_device *adreno_dev,
const char *name, struct clk *clk, bool on)
{
WARN(adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev) ||
adreno_is_a508(adreno_dev),
"clk_set_flags() is not supported\n");
if (!adreno_is_a540(adreno_dev) && !adreno_is_a512(adreno_dev) &&
!adreno_is_a508(adreno_dev))
return;
/* Handle clock settings for GFX PSCBCs */
if (on) {
if (!strcmp(name, "mem_iface_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
} else if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_MEM);
}
} else {
if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
}
}
}
#endif
static void a5xx_count_throttles(struct adreno_device *adreno_dev,
uint64_t adj)
@ -3015,7 +3034,9 @@ struct adreno_gpudev adreno_a5xx_gpudev = {
a5xx_preemption_post_ibsubmit,
.preemption_init = a5xx_preemption_init,
.preemption_schedule = a5xx_preemption_schedule,
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
.clk_set_options = a5xx_clk_set_options,
#endif
.read_alwayson = a5xx_read_alwayson,
.hw_isidle = a5xx_hw_isidle,
.power_ops = &adreno_power_operations,

View file

@ -3,6 +3,7 @@
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/clk/qcom.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
@ -2631,12 +2632,27 @@ update:
return 0;
}
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
static void a6xx_clk_set_options(struct adreno_device *adreno_dev,
const char *name, struct clk *clk, bool on)
{
WARN(adreno_is_a610(adreno_dev),
"clk_set_flags() is not supported\n");
/* Handle clock settings for GFX PSCBCs */
if (on) {
if (!strcmp(name, "mem_iface_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
} else if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_RETAIN_MEM);
}
} else {
if (!strcmp(name, "core_clk")) {
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
qcom_clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
}
}
}
#endif
u64 a6xx_read_alwayson(struct adreno_device *adreno_dev)
{
@ -2694,7 +2710,9 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
#endif
#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM)
.clk_set_options = a6xx_clk_set_options,
#endif
.read_alwayson = a6xx_read_alwayson,
.power_ops = &adreno_power_operations,
};
@ -2729,7 +2747,6 @@ struct adreno_gpudev adreno_a6xx_gmu_gpudev = {
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
#endif
.clk_set_options = a6xx_clk_set_options,
.read_alwayson = a6xx_read_alwayson,
.power_ops = &a6xx_gmu_power_ops,
};
@ -2764,7 +2781,6 @@ struct adreno_gpudev adreno_a6xx_rgmu_gpudev = {
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
#endif
.clk_set_options = a6xx_clk_set_options,
.read_alwayson = a6xx_read_alwayson,
.power_ops = &a6xx_rgmu_power_ops,
};
@ -2799,7 +2815,6 @@ struct adreno_gpudev adreno_a630_gpudev = {
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
.coresight = {&a6xx_coresight, &a6xx_coresight_cx},
#endif
.clk_set_options = a6xx_clk_set_options,
.read_alwayson = a6xx_read_alwayson,
.power_ops = &a630_gmu_power_ops,
};

View file

@ -1476,6 +1476,10 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
if (of_property_read_bool(pdev->dev.of_node, "qcom,no-nap"))
device->pwrctrl.ctrl_flags |= BIT(KGSL_PWRFLAGS_NAP_OFF);
else if (!IS_ENABLED(CONFIG_COMMON_CLK_QCOM)) {
dev_warn(device->dev, "KGSL nap state is not supported\n");
device->pwrctrl.ctrl_flags |= BIT(KGSL_PWRFLAGS_NAP_OFF);
}
if (pwr->num_pwrlevels == 0) {
dev_err(device->dev, "No power levels are defined\n");