From: Dmitry Osipenko <digetx@gmail.com>
To: Sumit Gupta <sumitg@nvidia.com>,
rjw@rjwysocki.net, viresh.kumar@linaro.org,
catalin.marinas@arm.com, will@kernel.org,
thierry.reding@gmail.com, jonathanh@nvidia.com, talho@nvidia.com,
linux-pm@vger.kernel.org, linux-tegra@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: bbasu@nvidia.com, mperttunen@nvidia.com
Subject: Re: [TEGRA194_CPUFREQ Patch v2 2/3] cpufreq: Add Tegra194 cpufreq driver
Date: Sun, 5 Apr 2020 17:05:14 +0300 [thread overview]
Message-ID: <67f9feb1-ba51-f1ac-b6eb-4587924d0748@gmail.com> (raw)
In-Reply-To: <1586028547-14993-3-git-send-email-sumitg@nvidia.com>
04.04.2020 22:29, Sumit Gupta пишет:
...
> +static void tegra_read_counters(struct work_struct *work)
> +{
> + struct read_counters_work *read_counters_work;
> + struct tegra_cpu_ctr *c;
> + u64 val;
> +
> + /*
> + * ref_clk_counter(32 bit counter) runs on constant clk,
> + * pll_p(408MHz).
> + * It will take = 2 ^ 32 / 408 MHz to overflow ref clk counter
> + * = 10526880 usec = 10.527 sec to overflow
> + *
> + * Like wise core_clk_counter(32 bit counter) runs on core clock.
> + * It's synchronized to crab_clk (cpu_crab_clk) which runs at
> + * freq of cluster. Assuming max cluster clock ~2000MHz,
> + * It will take = 2 ^ 32 / 2000 MHz to overflow core clk counter
> + * = ~2.147 sec to overflow
> + */
> + read_counters_work = container_of(work, struct read_counters_work,
> + work);
> + c = &read_counters_work->c;
> +
> + val = read_freq_feedback();
> + c->last_refclk_cnt = lower_32_bits(val);
> + c->last_coreclk_cnt = upper_32_bits(val);
> + udelay(c->delay);
> + val = read_freq_feedback();
> + c->refclk_cnt = lower_32_bits(val);
> + c->coreclk_cnt = upper_32_bits(val);
> +}
> +
> +/*
> + * Return instantaneous cpu speed
> + * Instantaneous freq is calculated as -
> + * -Takes sample on every query of getting the freq.
> + * - Read core and ref clock counters;
> + * - Delay for X us
> + * - Read above cycle counters again
> + * - Calculates freq by subtracting current and previous counters
> + * divided by the delay time or eqv. of ref_clk_counter in delta time
> + * - Return Kcycles/second, freq in KHz
> + *
> + * delta time period = x sec
> + * = delta ref_clk_counter / (408 * 10^6) sec
> + * freq in Hz = cycles/sec
> + * = (delta cycles / x sec
> + * = (delta cycles * 408 * 10^6) / delta ref_clk_counter
> + * in KHz = (delta cycles * 408 * 10^3) / delta ref_clk_counter
> + *
> + * @cpu - logical cpu whose freq to be updated
> + * Returns freq in KHz on success, 0 if cpu is offline
I don't see any checks in the code about whether CPU is offline.
Googling for "queue_work_on offline cpu" suggests that this function
should hang.
> + */
> +static unsigned int tegra194_get_speed_common(u32 cpu, u32 delay)
> +{
> + struct read_counters_work read_counters_work;
> + struct tegra_cpu_ctr c;
> + u32 delta_refcnt;
> + u32 delta_ccnt;
> + u32 rate_mhz;
> +
> + read_counters_work.c.cpu = cpu;
> + read_counters_work.c.delay = delay;
> + INIT_WORK_ONSTACK(&read_counters_work.work, tegra_read_counters);
> + queue_work_on(cpu, read_counters_wq, &read_counters_work.work);
> + flush_work(&read_counters_work.work);
> + c = read_counters_work.c;
> +
> + if (c.coreclk_cnt < c.last_coreclk_cnt)
> + delta_ccnt = c.coreclk_cnt + (MAX_CNT - c.last_coreclk_cnt);
> + else
> + delta_ccnt = c.coreclk_cnt - c.last_coreclk_cnt;
> + if (!delta_ccnt)
> + return 0;
> +
> + /* ref clock is 32 bits */
> + if (c.refclk_cnt < c.last_refclk_cnt)
> + delta_refcnt = c.refclk_cnt + (MAX_CNT - c.last_refclk_cnt);
> + else
> + delta_refcnt = c.refclk_cnt - c.last_refclk_cnt;
> + if (!delta_refcnt) {
> + pr_debug("cpufreq: %d is idle, delta_refcnt: 0\n", cpu);
> + return 0;
> + }
> + rate_mhz = ((unsigned long)(delta_ccnt * REF_CLK_MHZ)) / delta_refcnt;
> +
> + return (rate_mhz * KHZ); /* in KHz */
> +}
next prev parent reply other threads:[~2020-04-05 14:05 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-04 19:29 [TEGRA194_CPUFREQ Patch v2 0/3] Add cpufreq driver for Tegra194 Sumit Gupta
2020-04-04 19:29 ` [TEGRA194_CPUFREQ Patch v2 1/3] firmware: tegra: adding function to get BPMP data Sumit Gupta
2020-04-04 19:29 ` [TEGRA194_CPUFREQ Patch v2 2/3] cpufreq: Add Tegra194 cpufreq driver Sumit Gupta
2020-04-05 14:05 ` Dmitry Osipenko [this message]
2020-04-07 18:55 ` sumitg
2020-04-07 19:12 ` Dmitry Osipenko
2020-04-05 14:11 ` Dmitry Osipenko
2020-04-07 18:56 ` sumitg
2020-04-04 19:29 ` [TEGRA194_CPUFREQ Patch v2 3/3] arm64: defconfig: Enable CONFIG_ARM_TEGRA194_CPUFREQ Sumit Gupta
2020-04-06 2:47 ` [TEGRA194_CPUFREQ Patch v2 0/3] Add cpufreq driver for Tegra194 Viresh Kumar
2020-04-06 6:06 ` sumitg
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=67f9feb1-ba51-f1ac-b6eb-4587924d0748@gmail.com \
--to=digetx@gmail.com \
--cc=bbasu@nvidia.com \
--cc=catalin.marinas@arm.com \
--cc=jonathanh@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=mperttunen@nvidia.com \
--cc=rjw@rjwysocki.net \
--cc=sumitg@nvidia.com \
--cc=talho@nvidia.com \
--cc=thierry.reding@gmail.com \
--cc=viresh.kumar@linaro.org \
--cc=will@kernel.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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).