From: Sumit Gupta <sumitg@nvidia.com> To: <rjw@rjwysocki.net>, <viresh.kumar@linaro.org>, <sudeep.holla@arm.com>, <thierry.reding@gmail.com>, <jonathanh@nvidia.com>, <linux-pm@vger.kernel.org>, <linux-tegra@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org> Cc: <sumitg@nvidia.com>, <bbasu@nvidia.com>, <ksitaraman@nvidia.com> Subject: [PATCH v3] cpufreq: tegra194: get consistent cpuinfo_cur_freq Date: Wed, 14 Oct 2020 15:06:11 +0530 [thread overview] Message-ID: <1602668171-30104-1-git-send-email-sumitg@nvidia.com> (raw) Frequency returned by 'cpuinfo_cur_freq' using counters is not fixed and keeps changing slightly. This change returns a consistent value from freq_table. If the reconstructed frequency has acceptable delta from the last written value, then return the frequency corresponding to the last written ndiv value from freq_table. Otherwise, print a warning and return the reconstructed freq. Signed-off-by: Sumit Gupta <sumitg@nvidia.com> --- Sending only this patch as other patch not required after the change to convert 'pr_warn' to 'pr_info' in cpufreq core for unlisted freq. Changelog v1[2] -> v3: - Removed unwanted checks for cpu_online and max cluster number - Used WARN_ON_ONCE to avoid print flooding. v1[1] -> v2: - Minor changes to improve comments and reduce debug prints. - Get freq table from cluster specific data instead of policy. [2] https://marc.info/?l=linux-tegra&m=160216218511280&w=2 [1] https://marc.info/?l=linux-arm-kernel&m=160028821117535&w=2 drivers/cpufreq/tegra194-cpufreq.c | 62 ++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index e1d931c..7901587 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -180,9 +180,61 @@ static unsigned int tegra194_get_speed_common(u32 cpu, u32 delay) return (rate_mhz * KHZ); /* in KHz */ } +static void get_cpu_ndiv(void *ndiv) +{ + u64 ndiv_val; + + asm volatile("mrs %0, s3_0_c15_c0_4" : "=r" (ndiv_val) : ); + + *(u64 *)ndiv = ndiv_val; +} + +static void set_cpu_ndiv(void *data) +{ + struct cpufreq_frequency_table *tbl = data; + u64 ndiv_val = (u64)tbl->driver_data; + + asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); +} + static unsigned int tegra194_get_speed(u32 cpu) { - return tegra194_get_speed_common(cpu, US_DELAY); + struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); + struct cpufreq_frequency_table *pos; + unsigned int rate; + u64 ndiv; + int ret; + u32 cl; + + smp_call_function_single(cpu, get_cpu_cluster, &cl, true); + + /* reconstruct actual cpu freq using counters */ + rate = tegra194_get_speed_common(cpu, US_DELAY); + + /* get last written ndiv value */ + ret = smp_call_function_single(cpu, get_cpu_ndiv, &ndiv, true); + if (WARN_ON_ONCE(ret)) + return rate; + + /* + * If the reconstructed frequency has acceptable delta from + * the last written value, then return freq corresponding + * to the last written ndiv value from freq_table. This is + * done to return consistent value. + */ + cpufreq_for_each_valid_entry(pos, data->tables[cl]) { + if (pos->driver_data != ndiv) + continue; + + if (abs(pos->frequency - rate) > 115200) { + pr_warn("cpufreq: cpu%d,cur:%u,set:%u,set ndiv:%llu\n", + cpu, rate, pos->frequency, ndiv); + } else { + rate = pos->frequency; + } + break; + } + return rate; } static int tegra194_cpufreq_init(struct cpufreq_policy *policy) @@ -209,14 +261,6 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy) return 0; } -static void set_cpu_ndiv(void *data) -{ - struct cpufreq_frequency_table *tbl = data; - u64 ndiv_val = (u64)tbl->driver_data; - - asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); -} - static int tegra194_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Sumit Gupta <sumitg@nvidia.com> To: <rjw@rjwysocki.net>, <viresh.kumar@linaro.org>, <sudeep.holla@arm.com>, <thierry.reding@gmail.com>, <jonathanh@nvidia.com>, <linux-pm@vger.kernel.org>, <linux-tegra@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org> Cc: ksitaraman@nvidia.com, sumitg@nvidia.com, bbasu@nvidia.com Subject: [PATCH v3] cpufreq: tegra194: get consistent cpuinfo_cur_freq Date: Wed, 14 Oct 2020 15:06:11 +0530 [thread overview] Message-ID: <1602668171-30104-1-git-send-email-sumitg@nvidia.com> (raw) Frequency returned by 'cpuinfo_cur_freq' using counters is not fixed and keeps changing slightly. This change returns a consistent value from freq_table. If the reconstructed frequency has acceptable delta from the last written value, then return the frequency corresponding to the last written ndiv value from freq_table. Otherwise, print a warning and return the reconstructed freq. Signed-off-by: Sumit Gupta <sumitg@nvidia.com> --- Sending only this patch as other patch not required after the change to convert 'pr_warn' to 'pr_info' in cpufreq core for unlisted freq. Changelog v1[2] -> v3: - Removed unwanted checks for cpu_online and max cluster number - Used WARN_ON_ONCE to avoid print flooding. v1[1] -> v2: - Minor changes to improve comments and reduce debug prints. - Get freq table from cluster specific data instead of policy. [2] https://marc.info/?l=linux-tegra&m=160216218511280&w=2 [1] https://marc.info/?l=linux-arm-kernel&m=160028821117535&w=2 drivers/cpufreq/tegra194-cpufreq.c | 62 ++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index e1d931c..7901587 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -180,9 +180,61 @@ static unsigned int tegra194_get_speed_common(u32 cpu, u32 delay) return (rate_mhz * KHZ); /* in KHz */ } +static void get_cpu_ndiv(void *ndiv) +{ + u64 ndiv_val; + + asm volatile("mrs %0, s3_0_c15_c0_4" : "=r" (ndiv_val) : ); + + *(u64 *)ndiv = ndiv_val; +} + +static void set_cpu_ndiv(void *data) +{ + struct cpufreq_frequency_table *tbl = data; + u64 ndiv_val = (u64)tbl->driver_data; + + asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); +} + static unsigned int tegra194_get_speed(u32 cpu) { - return tegra194_get_speed_common(cpu, US_DELAY); + struct tegra194_cpufreq_data *data = cpufreq_get_driver_data(); + struct cpufreq_frequency_table *pos; + unsigned int rate; + u64 ndiv; + int ret; + u32 cl; + + smp_call_function_single(cpu, get_cpu_cluster, &cl, true); + + /* reconstruct actual cpu freq using counters */ + rate = tegra194_get_speed_common(cpu, US_DELAY); + + /* get last written ndiv value */ + ret = smp_call_function_single(cpu, get_cpu_ndiv, &ndiv, true); + if (WARN_ON_ONCE(ret)) + return rate; + + /* + * If the reconstructed frequency has acceptable delta from + * the last written value, then return freq corresponding + * to the last written ndiv value from freq_table. This is + * done to return consistent value. + */ + cpufreq_for_each_valid_entry(pos, data->tables[cl]) { + if (pos->driver_data != ndiv) + continue; + + if (abs(pos->frequency - rate) > 115200) { + pr_warn("cpufreq: cpu%d,cur:%u,set:%u,set ndiv:%llu\n", + cpu, rate, pos->frequency, ndiv); + } else { + rate = pos->frequency; + } + break; + } + return rate; } static int tegra194_cpufreq_init(struct cpufreq_policy *policy) @@ -209,14 +261,6 @@ static int tegra194_cpufreq_init(struct cpufreq_policy *policy) return 0; } -static void set_cpu_ndiv(void *data) -{ - struct cpufreq_frequency_table *tbl = data; - u64 ndiv_val = (u64)tbl->driver_data; - - asm volatile("msr s3_0_c15_c0_4, %0" : : "r" (ndiv_val)); -} - static int tegra194_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next reply other threads:[~2020-10-14 9:36 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-14 9:36 Sumit Gupta [this message] 2020-10-14 9:36 ` [PATCH v3] cpufreq: tegra194: get consistent cpuinfo_cur_freq Sumit Gupta 2020-10-27 6:16 ` Sumit Gupta 2020-10-27 6:16 ` Sumit Gupta 2020-10-27 6:58 ` Viresh Kumar 2020-10-27 6:58 ` Viresh Kumar 2020-10-27 7:05 ` Sumit Gupta 2020-10-27 7:05 ` Sumit Gupta 2020-10-28 6:10 ` Viresh Kumar 2020-10-28 6:10 ` Viresh Kumar
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1602668171-30104-1-git-send-email-sumitg@nvidia.com \ --to=sumitg@nvidia.com \ --cc=bbasu@nvidia.com \ --cc=jonathanh@nvidia.com \ --cc=ksitaraman@nvidia.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pm@vger.kernel.org \ --cc=linux-tegra@vger.kernel.org \ --cc=rjw@rjwysocki.net \ --cc=sudeep.holla@arm.com \ --cc=thierry.reding@gmail.com \ --cc=viresh.kumar@linaro.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.