Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 366583ea authored by Sultan Alsawaf's avatar Sultan Alsawaf Committed by Harshit Jain
Browse files

clk: qcom: clk-cpu-osm: Use CLK_GET_RATE_NOCACHE



After a CPU comes online, clk_set_rate silently refuses to change said CPU's
frequency to the frequency it was running at before going offline (since it
thinks that we are setting the same frequency redundantly). By default, each CPU
runs at its minimum frequency when coming online, so if the governor decides to
keep a CPU running at the frequency it used before going offline, then
clk_set_rate will ignore the frequency change request and the CPU will stay
stuck running at its minimum frequency for a potentially long period of time
(i.e., until the governor decides to change the frequency to something
different). This can cause severe lag when a device is woken up from deep sleep.

In order to prevent a CPU from being stuck at its default frequency for a
potentially long period of time, set the CLK_GET_RATE_NOCACHE flag so that the
governor's frequency change requests will always be honored. Do this for the L3
clock as well.

Signed-off-by: default avatarSultan Alsawaf <sultan@kerneltoast.com>
Signed-off-by: default avatarAdam W. Willis <return.of.octobot@gmail.com>
Signed-off-by: default avatarYaroslav Furman <yaro330@gmail.com>
parent f920d24e
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -282,24 +282,28 @@ static struct clk_init_data osm_clks_init[] = {
		.name = "l3_clk",
		.parent_names = (const char *[]){ "bi_tcxo_ao" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_l3_osm,
	},
	[1] = {
		.name = "pwrcl_clk",
		.parent_names = (const char *[]){ "bi_tcxo_ao" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_cpu_osm,
	},
	[2] = {
		.name = "perfcl_clk",
		.parent_names = (const char *[]){ "bi_tcxo_ao" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_cpu_osm,
	},
	[3] = {
		.name = "perfpcl_clk",
		.parent_names = (const char *[]){ "bi_tcxo_ao" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_cpu_osm,
	},
};
@@ -310,9 +314,9 @@ static struct clk_osm l3_clk = {
	.hw.init = &osm_clks_init[0],
};

static DEFINE_CLK_VOTER(l3_cluster0_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER(l3_cluster1_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER(l3_cluster2_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER_NOCACHE(l3_cluster0_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER_NOCACHE(l3_cluster1_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER_NOCACHE(l3_cluster2_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER(l3_misc_vote_clk, l3_clk, 0);
static DEFINE_CLK_VOTER(l3_gpu_vote_clk, l3_clk, 0);

@@ -330,6 +334,7 @@ static struct clk_osm cpu0_pwrcl_clk = {
		.name = "cpu0_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -342,6 +347,7 @@ static struct clk_osm cpu1_pwrcl_clk = {
		.name = "cpu1_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -354,6 +360,7 @@ static struct clk_osm cpu2_pwrcl_clk = {
		.name = "cpu2_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -366,6 +373,7 @@ static struct clk_osm cpu3_pwrcl_clk = {
		.name = "cpu3_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -378,6 +386,7 @@ static struct clk_osm cpu4_pwrcl_clk = {
		.name = "cpu4_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -390,6 +399,7 @@ static struct clk_osm cpu5_pwrcl_clk = {
		.name = "cpu5_pwrcl_clk",
		.parent_names = (const char *[]){ "pwrcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -408,6 +418,7 @@ static struct clk_osm cpu4_perfcl_clk = {
		.name = "cpu4_perfcl_clk",
		.parent_names = (const char *[]){ "perfcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -420,6 +431,7 @@ static struct clk_osm cpu5_perfcl_clk = {
		.name = "cpu5_perfcl_clk",
		.parent_names = (const char *[]){ "perfcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -432,6 +444,7 @@ static struct clk_osm cpu6_perfcl_clk = {
		.name = "cpu6_perfcl_clk",
		.parent_names = (const char *[]){ "perfcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -444,6 +457,7 @@ static struct clk_osm cpu7_perfcl_clk = {
		.name = "cpu7_perfcl_clk",
		.parent_names = (const char *[]){ "perfcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
@@ -462,6 +476,7 @@ static struct clk_osm cpu7_perfpcl_clk = {
		.name = "cpu7_perfpcl_clk",
		.parent_names = (const char *[]){ "perfpcl_clk" },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
		.ops = &clk_ops_core,
	},
};
+7 −3
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ extern const struct clk_ops clk_ops_voter;

#define to_clk_voter(_hw) container_of(_hw, struct clk_voter, hw)

#define __DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate, _is_branch) \
#define __DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate, _is_branch, _flags) \
	struct clk_voter clk_name = {					 \
		.is_branch = (_is_branch),				  \
		.rate = _default_rate,					   \
@@ -39,14 +39,18 @@ extern const struct clk_ops clk_ops_voter;
			.flags = CLK_ENABLE_HAND_OFF,			   \
			.parent_names = (const char *[]){ #_parent_name }, \
			.num_parents = 1,				   \
			.flags = _flags,					\
		},							   \
	}

#define DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate) \
	 __DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate, 0)
	 __DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate, 0, 0)

#define DEFINE_CLK_VOTER_NOCACHE(clk_name, _parent_name, _default_rate) \
	 __DEFINE_CLK_VOTER(clk_name, _parent_name, _default_rate, 0, CLK_GET_RATE_NOCACHE)

#define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent_name) \
	 __DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1)
	__DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1, 0)

int voter_clk_handoff(struct clk_hw *hw);