A collection of other clock fixes in -next for the RPi
This commit is contained in:
parent
bb4f705986
commit
08645910f6
|
@ -682,3 +682,266 @@ index b68bf57..8c7763f 100644
|
|||
--
|
||||
cgit v0.12
|
||||
|
||||
From e69fdcca836f0b81a2260b69429c8622a80ea891 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Anholt <eric@anholt.net>
|
||||
Date: Wed, 1 Jun 2016 12:05:33 -0700
|
||||
Subject: clk: bcm2835: Mark the VPU clock as critical
|
||||
|
||||
The VPU clock is also the clock for our AXI bus, so we really can't
|
||||
disable it. This might have happened during boot if, for example,
|
||||
uart1 (aux_uart clock) probed and was then disabled before the other
|
||||
consumers of the VPU clock had probed.
|
||||
|
||||
Signed-off-by: Eric Anholt <eric@anholt.net>
|
||||
Acked-by: Martin Sperl <kernel@martin.sperl.org>
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
---
|
||||
drivers/clk/bcm/clk-bcm2835.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
|
||||
index 7a79708..d9db03c 100644
|
||||
--- a/drivers/clk/bcm/clk-bcm2835.c
|
||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
|
||||
@@ -443,6 +443,8 @@ struct bcm2835_clock_data {
|
||||
/* Number of fractional bits in the divider */
|
||||
u32 frac_bits;
|
||||
|
||||
+ u32 flags;
|
||||
+
|
||||
bool is_vpu_clock;
|
||||
bool is_mash_clock;
|
||||
};
|
||||
@@ -1230,7 +1232,7 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
|
||||
init.parent_names = parents;
|
||||
init.num_parents = data->num_mux_parents;
|
||||
init.name = data->name;
|
||||
- init.flags = CLK_IGNORE_UNUSED;
|
||||
+ init.flags = data->flags | CLK_IGNORE_UNUSED;
|
||||
|
||||
if (data->is_vpu_clock) {
|
||||
init.ops = &bcm2835_vpu_clock_clk_ops;
|
||||
@@ -1649,6 +1651,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
|
||||
.div_reg = CM_VPUDIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 8,
|
||||
+ .flags = CLK_IS_CRITICAL,
|
||||
.is_vpu_clock = true),
|
||||
|
||||
/* clocks with per parent mux */
|
||||
--
|
||||
cgit v0.12
|
||||
|
||||
From eddcbe8398fc7103fccd22aa6df6917caf0123bf Mon Sep 17 00:00:00 2001
|
||||
From: Eric Anholt <eric@anholt.net>
|
||||
Date: Wed, 1 Jun 2016 12:05:34 -0700
|
||||
Subject: clk: bcm2835: Mark GPIO clocks enabled at boot as critical
|
||||
|
||||
These divide off of PLLD_PER and are used for the ethernet and wifi
|
||||
PHYs source PLLs. Neither of them is currently represented by a phy
|
||||
device that would grab the clock for us.
|
||||
|
||||
This keeps other drivers from killing the networking PHYs when they
|
||||
disable their own clocks and trigger PLLD_PER's refcount going to 0.
|
||||
|
||||
Signed-off-by: Eric Anholt <eric@anholt.net>
|
||||
Acked-by: Martin Sperl <kernel@martin.sperl.org>
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
---
|
||||
drivers/clk/bcm/clk-bcm2835.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
|
||||
index d9db03c..400615b 100644
|
||||
--- a/drivers/clk/bcm/clk-bcm2835.c
|
||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
|
||||
@@ -1239,6 +1239,12 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
|
||||
} else {
|
||||
init.ops = &bcm2835_clock_clk_ops;
|
||||
init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
|
||||
+
|
||||
+ /* If the clock wasn't actually enabled at boot, it's not
|
||||
+ * critical.
|
||||
+ */
|
||||
+ if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
|
||||
+ init.flags &= ~CLK_IS_CRITICAL;
|
||||
}
|
||||
|
||||
clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
|
||||
@@ -1708,13 +1714,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
|
||||
.div_reg = CM_GP1DIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 12,
|
||||
+ .flags = CLK_IS_CRITICAL,
|
||||
.is_mash_clock = true),
|
||||
[BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
|
||||
.name = "gp2",
|
||||
.ctl_reg = CM_GP2CTL,
|
||||
.div_reg = CM_GP2DIV,
|
||||
.int_bits = 12,
|
||||
- .frac_bits = 12),
|
||||
+ .frac_bits = 12,
|
||||
+ .flags = CLK_IS_CRITICAL),
|
||||
|
||||
/* HDMI state machine */
|
||||
[BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
|
||||
--
|
||||
cgit v0.12
|
||||
|
||||
From 9e400c5cc5c105e35216ac59a346f20cdd7613be Mon Sep 17 00:00:00 2001
|
||||
From: Eric Anholt <eric@anholt.net>
|
||||
Date: Wed, 1 Jun 2016 12:05:35 -0700
|
||||
Subject: clk: bcm2835: Mark the CM SDRAM clock's parent as critical
|
||||
|
||||
While the SDRAM is being driven by its dedicated PLL most of the time,
|
||||
there is a little loop running in the firmware that periodically turns
|
||||
on the CM SDRAM clock (using its pre-initialized parent) and switches
|
||||
SDRAM to using the CM clock to do PVT recalibration.
|
||||
|
||||
This avoids system hangs if we choose SDRAM's parent for some other
|
||||
clock, then disable that clock.
|
||||
|
||||
Signed-off-by: Eric Anholt <eric@anholt.net>
|
||||
Acked-by: Martin Sperl <kernel@martin.sperl.org>
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
---
|
||||
drivers/clk/bcm/clk-bcm2835.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
|
||||
index 400615b..c6420b3 100644
|
||||
--- a/drivers/clk/bcm/clk-bcm2835.c
|
||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
+#include <linux/clk.h>
|
||||
#include <linux/clk/bcm2835.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
@@ -1801,6 +1802,25 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
|
||||
.ctl_reg = CM_PERIICTL),
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Permanently take a reference on the parent of the SDRAM clock.
|
||||
+ *
|
||||
+ * While the SDRAM is being driven by its dedicated PLL most of the
|
||||
+ * time, there is a little loop running in the firmware that
|
||||
+ * periodically switches the SDRAM to using our CM clock to do PVT
|
||||
+ * recalibration, with the assumption that the previously configured
|
||||
+ * SDRAM parent is still enabled and running.
|
||||
+ */
|
||||
+static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
|
||||
+{
|
||||
+ struct clk *parent = clk_get_parent(sdc);
|
||||
+
|
||||
+ if (IS_ERR(parent))
|
||||
+ return PTR_ERR(parent);
|
||||
+
|
||||
+ return clk_prepare_enable(parent);
|
||||
+}
|
||||
+
|
||||
static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -1810,6 +1830,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||
const struct bcm2835_clk_desc *desc;
|
||||
const size_t asize = ARRAY_SIZE(clk_desc_array);
|
||||
size_t i;
|
||||
+ int ret;
|
||||
|
||||
cprman = devm_kzalloc(dev,
|
||||
sizeof(*cprman) + asize * sizeof(*clks),
|
||||
@@ -1840,6 +1861,10 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||
clks[i] = desc->clk_register(cprman, desc->data);
|
||||
}
|
||||
|
||||
+ ret = bcm2835_mark_sdc_parent_critical(clks[BCM2835_CLOCK_SDRAM]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
|
||||
&cprman->onecell);
|
||||
}
|
||||
--
|
||||
cgit v0.12
|
||||
|
||||
From 67615c588a059b731df9d019edc3c561d8006ec9 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Anholt <eric@anholt.net>
|
||||
Date: Wed, 1 Jun 2016 12:05:36 -0700
|
||||
Subject: clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent
|
||||
|
||||
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")
|
||||
Acked-by: Martin Sperl <kernel@martin.sperl.org>
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
---
|
||||
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 c6420b3..e8a9646a 100644
|
||||
--- a/drivers/clk/bcm/clk-bcm2835.c
|
||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
|
||||
@@ -1009,16 +1009,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
|
||||
*/
|
||||
@@ -1026,6 +1038,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);
|
||||
--
|
||||
cgit v0.12
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Summary: The Linux kernel
|
|||
# For non-released -rc kernels, this will be appended after the rcX and
|
||||
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
|
||||
#
|
||||
%global baserelease 300
|
||||
%global baserelease 301
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
|
@ -2161,8 +2161,9 @@ fi
|
|||
#
|
||||
#
|
||||
%changelog
|
||||
* Mon Oct 24 2016 Peter Robinson <pbrobinson@fedoraproject.org>
|
||||
* Mon Oct 24 2016 Peter Robinson <pbrobinson@fedoraproject.org> 4.8.4-301
|
||||
- Upstream fix for Raspberry Pi to fix setting low-resolution video modes on HDMI
|
||||
- A collection of other clock fixes in -next for the RPi
|
||||
|
||||
* Mon Oct 24 2016 Justin M. Forbes <jforbes@fedoraproject.org> - 4.8.4-300
|
||||
- Linux v4.8.4
|
||||
|
|
Loading…
Reference in New Issue