From: Jerome Brunet <jbrunet@baylibre.com>
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@codeaurora.org>
Cc: Jerome Brunet <jbrunet@baylibre.com>,
linux-clk@vger.kernel.org, Kevin Hilman <khilman@baylibre.com>,
Neil Armstrong <narmstrong@baylibre.com>
Subject: [RFC 0/2] CLK_SET_RATE_GATE and protection against changes
Date: Thu, 2 Mar 2017 18:38:33 +0100 [thread overview]
Message-ID: <20170302173835.18313-1-jbrunet@baylibre.com> (raw)
Hi,
I have been playing with CLK_SET_RATE_GATE, with the goal of protecting a
parent clock against rate change if the clock is already used. I did not
get the expected result. Before explaining more my use case, I'd like to
point out that the patches attached to this RFC are just here to illustrate
what I understand of the problem and start a discussion. By no means I
expect them to be merged as it is.
I'm working on the audio support on Amlogic's meson platforms [0]. In CCF,
I have an i2s master clock and spdif clock. Both can take any of 3 PLLs as
parent. These 3 PLLs have the capabilities, and I have set the
"CLK_SET_RATE_GATE" on each of them.
After boot, here is what we have:
name | en_cnt | prepare_cnt | rate |
===============================================================
fixed_pll 2 2 2000000000
mpll2 0 0 0
mpll1 0 0 346956926
mpll0 0 0 274510132
Here the audio clocks don't appear because of an undocumented boot value of
the mux in front of them Please ignore this.
Starting i2s playback:
fixed_pll 3 3 2000000000
mpll2 0 0 0
mpll1 0 0 346956926
mpll0 1 1 491495425
cts_amclk_sel 1 1 491495425
cts_amclk_div 1 1 12287386
cts_amclk 1 1 12287386
Here the i2s master is attached to the mpll0 and pll is set to (roughly)
500Mhz. So far so good.
Now starting the spdif playback, I expected the mpll0 to be protected and
.round_rate/.determine_rate to return the current rate of mpll0. By going
through the possible parents, I expected CCF not to select mpll0 as the
best parent. Well, guess what happened ;)
Starting spdif playback
fixed_pll 3 3 2000000000
mpll2 0 0 0
mpll1 0 0 346956926
mpll0 2 2 36863870
cts_mclk_i958_sel 1 1 36863870
cts_mclk_i958_div 1 1 6143979
cts_mclk_i958 1 1 6143979
cts_amclk_sel 1 1 36863870
cts_amclk_div 1 1 921597
cts_amclk 1 1 921597
mpll0 got selected anyway, the rate changed and the i2s master clock
wrecked.
I tried to understand what happened but my understanding of CCF is limited,
if the following is complete nonsense, feel free to (gently) mock me.
CLK_SET_RATE_GATE only prevent rate change when the clock is busy and we
through clk_core_set_rate_nolock. So if we call clk_set_rate directly on
clock with CLK_SET_RATE_GATE, while another clock uses it, it shall
fail. However if we reach this clock by walking up the clock tree,
everything seems to be as if this flag did not exist. I think this explains
why mpll0 was selected has best parent and updated.
In patch 1, I try in intercept the calls to .round_rate and .determine_rate
and just return the current rate of the clock when it is busy. The way the
clock remains usable with the consumer can deal with the current but the
rate won't change for the consumer already using the clock. Because of
this change, mpll0 is no longer the best parent out there.
fixed_pll 3 3 2000000000
mpll2 0 0 0
mpll1 0 0 36863870
cts_mclk_i958_sel 0 0 36863870
cts_mclk_i958_div 0 0 6143979
cts_mclk_i958 0 0 6143979
mpll0 1 1 491495425
cts_amclk_sel 1 1 491495425
cts_amclk_div 1 1 12287386
cts_amclk 1 1 12287386
This is the result I expected :) However, the situation is still not ideal
as I think using CLK_SET_RATE_GATE to protect against rate changes in such
case is subject to race condition.
Suppose that I start both playbacks at the same time, i2s sets its rate but
get descheduled before enabling the clock. Then spdif get scheduled, set
the rate on the same pll (it can as the prepare/enable count is still 0)
and enables the clock. Finally, i2s gets scheduled again, enables its
clock but the rate of the selected parent has changed behind our back. I
don't really know how to solve this one. I was thinking of another counter
(like owner_count) but we already have 2 of those, there must be something
smarter we can do about it... I guess.
If you read that far, thanks a lot !
Does any of what I just wrote make sense ? Do you have any suggestion ?
Patch 2 is merely a suggestion. As explained in the patch, I think the
wording is bit confusing.
[0] : https://github.com/jeromebrunet/linux/commits/amlogic/wip/audio
Jerome Brunet (2):
clk: fix CLK_SET_RATE_GATE on parent clocks
clk: use enable_count to check if clk is busy
drivers/clk/clk.c | 56 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 20 deletions(-)
--
2.9.3
next reply other threads:[~2017-03-02 17:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-02 17:38 Jerome Brunet [this message]
2017-03-02 17:38 ` [RFC 1/2] clk: fix CLK_SET_RATE_GATE on parent clocks Jerome Brunet
2017-03-02 17:38 ` [RFC 2/2] clk: use enable_count to check if clk is busy Jerome Brunet
2017-03-07 14:38 ` [RFC 0/2] CLK_SET_RATE_GATE and protection against changes Stephen Boyd
2017-03-07 16:00 ` Jerome Brunet
2017-03-09 22:23 ` Michael Turquette
2017-03-11 18:18 ` Jerome Brunet
2017-03-13 16:57 ` Michael Turquette
2017-03-14 1:19 ` Stephen Boyd
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=20170302173835.18313-1-jbrunet@baylibre.com \
--to=jbrunet@baylibre.com \
--cc=khilman@baylibre.com \
--cc=linux-clk@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=narmstrong@baylibre.com \
--cc=sboyd@codeaurora.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 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.