From: eric@anholt.net (Eric Anholt)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent
Date: Tue, 26 Apr 2016 12:39:45 -0700 [thread overview]
Message-ID: <1461699585-6649-2-git-send-email-eric@anholt.net> (raw)
In-Reply-To: <1461699585-6649-1-git-send-email-eric@anholt.net>
If the firmware had set up a clock to source from PLLC, go along with
it. But if we're looking for a new parent, we don't want to switch it
to PLLC because the firmware will force PLLC (and thus the AXI bus
clock) to different frequencies during over-temp/under-voltage,
without notification to Linux.
On my system, this moves the Linux-enabled HDMI state machine and DSI1
escape clock over to plld_per from pllc_per. EMMC still ends up on
pllc_per, because the firmware had set it up to use that.
Signed-off-by: Eric Anholt <eric@anholt.net>
Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
---
drivers/clk/bcm/clk-bcm2835.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 14f3066194ac..870c5745d649 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1035,16 +1035,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
return 0;
}
+static bool
+bcm2835_clk_is_pllc(struct clk_hw *hw)
+{
+ if (!hw)
+ return false;
+
+ return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
+}
+
static int bcm2835_clock_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
struct clk_hw *parent, *best_parent = NULL;
+ bool current_parent_is_pllc;
unsigned long rate, best_rate = 0;
unsigned long prate, best_prate = 0;
size_t i;
u32 div;
+ current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
+
/*
* Select parent clock that results in the closest but lower rate
*/
@@ -1052,6 +1064,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
parent = clk_hw_get_parent_by_index(hw, i);
if (!parent)
continue;
+
+ /*
+ * Don't choose a PLLC-derived clock as our parent
+ * unless it had been manually set that way. PLLC's
+ * frequency gets adjusted by the firmware due to
+ * over-temp or under-voltage conditions, without
+ * prior notification to our clock consumer.
+ */
+ if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
+ continue;
+
prate = clk_hw_get_rate(parent);
div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
--
2.8.0.rc3
WARNING: multiple messages have this Message-ID (diff)
From: Eric Anholt <eric@anholt.net>
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@codeaurora.org>
Cc: linux-rpi-kernel@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
Stephen Warren <swarren@wwwdotorg.org>,
Lee Jones <lee@kernel.org>,
Martin Sperl <kernel@martin.sperl.org>,
Eric Anholt <eric@anholt.net>
Subject: [PATCH 2/2] clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent
Date: Tue, 26 Apr 2016 12:39:45 -0700 [thread overview]
Message-ID: <1461699585-6649-2-git-send-email-eric@anholt.net> (raw)
In-Reply-To: <1461699585-6649-1-git-send-email-eric@anholt.net>
If the firmware had set up a clock to source from PLLC, go along with
it. But if we're looking for a new parent, we don't want to switch it
to PLLC because the firmware will force PLLC (and thus the AXI bus
clock) to different frequencies during over-temp/under-voltage,
without notification to Linux.
On my system, this moves the Linux-enabled HDMI state machine and DSI1
escape clock over to plld_per from pllc_per. EMMC still ends up on
pllc_per, because the firmware had set it up to use that.
Signed-off-by: Eric Anholt <eric@anholt.net>
Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
---
drivers/clk/bcm/clk-bcm2835.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 14f3066194ac..870c5745d649 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1035,16 +1035,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
return 0;
}
+static bool
+bcm2835_clk_is_pllc(struct clk_hw *hw)
+{
+ if (!hw)
+ return false;
+
+ return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
+}
+
static int bcm2835_clock_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
struct clk_hw *parent, *best_parent = NULL;
+ bool current_parent_is_pllc;
unsigned long rate, best_rate = 0;
unsigned long prate, best_prate = 0;
size_t i;
u32 div;
+ current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
+
/*
* Select parent clock that results in the closest but lower rate
*/
@@ -1052,6 +1064,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
parent = clk_hw_get_parent_by_index(hw, i);
if (!parent)
continue;
+
+ /*
+ * Don't choose a PLLC-derived clock as our parent
+ * unless it had been manually set that way. PLLC's
+ * frequency gets adjusted by the firmware due to
+ * over-temp or under-voltage conditions, without
+ * prior notification to our clock consumer.
+ */
+ if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
+ continue;
+
prate = clk_hw_get_rate(parent);
div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
--
2.8.0.rc3
next prev parent reply other threads:[~2016-04-26 19:39 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-26 19:39 [PATCH 1/2] clk: bcm2835: Mark the VPU clock as critical Eric Anholt
2016-04-26 19:39 ` Eric Anholt
2016-04-26 19:39 ` Eric Anholt [this message]
2016-04-26 19:39 ` [PATCH 2/2] clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent Eric Anholt
2016-04-30 9:28 ` Martin Sperl
2016-04-30 9:28 ` Martin Sperl
2016-05-02 8:54 ` Martin Sperl
2016-05-02 8:54 ` Martin Sperl
2016-05-02 15:29 ` Eric Anholt
2016-05-02 15:29 ` Eric Anholt
2016-05-02 16:36 ` Martin Sperl
2016-05-02 16:36 ` Martin Sperl
2016-05-03 1:09 ` Eric Anholt
2016-05-03 1:09 ` Eric Anholt
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=1461699585-6649-2-git-send-email-eric@anholt.net \
--to=eric@anholt.net \
--cc=linux-arm-kernel@lists.infradead.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.