brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0351-clk-bcm2835-Skip-PLLC-clocks-when-deciding-on-a-new-.patch
1 From 4ef6b916c3004783aeeabfcd9889bca046d944bf Mon Sep 17 00:00:00 2001
2 From: Eric Anholt <eric@anholt.net>
3 Date: Tue, 26 Apr 2016 12:39:45 -0700
4 Subject: [PATCH 351/381] clk: bcm2835: Skip PLLC clocks when deciding on a new
5 clock parent
6
7 If the firmware had set up a clock to source from PLLC, go along with
8 it. But if we're looking for a new parent, we don't want to switch it
9 to PLLC because the firmware will force PLLC (and thus the AXI bus
10 clock) to different frequencies during over-temp/under-voltage,
11 without notification to Linux.
12
13 On my system, this moves the Linux-enabled HDMI state machine and DSI1
14 escape clock over to plld_per from pllc_per. EMMC still ends up on
15 pllc_per, because the firmware had set it up to use that.
16
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
19 ---
20 drivers/clk/bcm/clk-bcm2835.c | 23 +++++++++++++++++++++++
21 1 file changed, 23 insertions(+)
22
23 --- a/drivers/clk/bcm/clk-bcm2835.c
24 +++ b/drivers/clk/bcm/clk-bcm2835.c
25 @@ -1020,16 +1020,28 @@ static int bcm2835_clock_set_rate(struct
26 return 0;
27 }
28
29 +static bool
30 +bcm2835_clk_is_pllc(struct clk_hw *hw)
31 +{
32 + if (!hw)
33 + return false;
34 +
35 + return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
36 +}
37 +
38 static int bcm2835_clock_determine_rate(struct clk_hw *hw,
39 struct clk_rate_request *req)
40 {
41 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
42 struct clk_hw *parent, *best_parent = NULL;
43 + bool current_parent_is_pllc;
44 unsigned long rate, best_rate = 0;
45 unsigned long prate, best_prate = 0;
46 size_t i;
47 u32 div;
48
49 + current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
50 +
51 /*
52 * Select parent clock that results in the closest but lower rate
53 */
54 @@ -1037,6 +1049,17 @@ static int bcm2835_clock_determine_rate(
55 parent = clk_hw_get_parent_by_index(hw, i);
56 if (!parent)
57 continue;
58 +
59 + /*
60 + * Don't choose a PLLC-derived clock as our parent
61 + * unless it had been manually set that way. PLLC's
62 + * frequency gets adjusted by the firmware due to
63 + * over-temp or under-voltage conditions, without
64 + * prior notification to our clock consumer.
65 + */
66 + if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
67 + continue;
68 +
69 prate = clk_hw_get_rate(parent);
70 div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
71 rate = bcm2835_clock_rate_from_divisor(clock, prate, div);