kernel: update kernel 4.9 to version 4.9.91
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.9 / 950-0156-clk-bcm2835-Register-the-DSI0-DSI1-pixel-clocks.patch
1 From 876f8ef32ec09fb566cc6ecdf4c96a8348f135b6 Mon Sep 17 00:00:00 2001
2 From: Eric Anholt <eric@anholt.net>
3 Date: Wed, 18 Jan 2017 07:31:56 +1100
4 Subject: [PATCH] clk: bcm2835: Register the DSI0/DSI1 pixel clocks.
5
6 The DSI pixel clocks are muxed from clocks generated in the analog phy
7 by the DSI driver. In order to set them as parents, we need to do the
8 same name lookup dance on them as we do for our root oscillator.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
12 (cherry picked from commit 8a39e9fa578229fd4604266c6ebb1a3a77d7994c)
13 ---
14 .../bindings/clock/brcm,bcm2835-cprman.txt | 15 ++-
15 drivers/clk/bcm/clk-bcm2835.c | 121 +++++++++++++++++++--
16 include/dt-bindings/clock/bcm2835.h | 2 +
17 3 files changed, 125 insertions(+), 13 deletions(-)
18
19 --- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
20 +++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
21 @@ -16,7 +16,20 @@ Required properties:
22 - #clock-cells: Should be <1>. The permitted clock-specifier values can be
23 found in include/dt-bindings/clock/bcm2835.h
24 - reg: Specifies base physical address and size of the registers
25 -- clocks: The external oscillator clock phandle
26 +- clocks: phandles to the parent clocks used as input to the module, in
27 + the following order:
28 +
29 + - External oscillator
30 + - DSI0 byte clock
31 + - DSI0 DDR2 clock
32 + - DSI0 DDR clock
33 + - DSI1 byte clock
34 + - DSI1 DDR2 clock
35 + - DSI1 DDR clock
36 +
37 + Only external oscillator is required. The DSI clocks may
38 + not be present, in which case their children will be
39 + unusable.
40
41 Example:
42
43 --- a/drivers/clk/bcm/clk-bcm2835.c
44 +++ b/drivers/clk/bcm/clk-bcm2835.c
45 @@ -297,11 +297,32 @@
46 #define LOCK_TIMEOUT_NS 100000000
47 #define BCM2835_MAX_FB_RATE 1750000000u
48
49 +/*
50 + * Names of clocks used within the driver that need to be replaced
51 + * with an external parent's name. This array is in the order that
52 + * the clocks node in the DT references external clocks.
53 + */
54 +static const char *const cprman_parent_names[] = {
55 + "xosc",
56 + "dsi0_byte",
57 + "dsi0_ddr2",
58 + "dsi0_ddr",
59 + "dsi1_byte",
60 + "dsi1_ddr2",
61 + "dsi1_ddr",
62 +};
63 +
64 struct bcm2835_cprman {
65 struct device *dev;
66 void __iomem *regs;
67 spinlock_t regs_lock; /* spinlock for all clocks */
68 - const char *osc_name;
69 +
70 + /*
71 + * Real names of cprman clock parents looked up through
72 + * of_clk_get_parent_name(), which will be used in the
73 + * parent_names[] arrays for clock registration.
74 + */
75 + const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)];
76
77 /* Must be last */
78 struct clk_hw_onecell_data onecell;
79 @@ -911,6 +932,9 @@ static long bcm2835_clock_rate_from_divi
80 const struct bcm2835_clock_data *data = clock->data;
81 u64 temp;
82
83 + if (data->int_bits == 0 && data->frac_bits == 0)
84 + return parent_rate;
85 +
86 /*
87 * The divisor is a 12.12 fixed point field, but only some of
88 * the bits are populated in any given clock.
89 @@ -934,7 +958,12 @@ static unsigned long bcm2835_clock_get_r
90 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
91 struct bcm2835_cprman *cprman = clock->cprman;
92 const struct bcm2835_clock_data *data = clock->data;
93 - u32 div = cprman_read(cprman, data->div_reg);
94 + u32 div;
95 +
96 + if (data->int_bits == 0 && data->frac_bits == 0)
97 + return parent_rate;
98 +
99 + div = cprman_read(cprman, data->div_reg);
100
101 return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
102 }
103 @@ -1213,7 +1242,7 @@ static struct clk_hw *bcm2835_register_p
104 memset(&init, 0, sizeof(init));
105
106 /* All of the PLLs derive from the external oscillator. */
107 - init.parent_names = &cprman->osc_name;
108 + init.parent_names = &cprman->real_parent_names[0];
109 init.num_parents = 1;
110 init.name = data->name;
111 init.ops = &bcm2835_pll_clk_ops;
112 @@ -1299,18 +1328,22 @@ static struct clk_hw *bcm2835_register_c
113 struct bcm2835_clock *clock;
114 struct clk_init_data init;
115 const char *parents[1 << CM_SRC_BITS];
116 - size_t i;
117 + size_t i, j;
118 int ret;
119
120 /*
121 - * Replace our "xosc" references with the oscillator's
122 - * actual name.
123 + * Replace our strings referencing parent clocks with the
124 + * actual clock-output-name of the parent.
125 */
126 for (i = 0; i < data->num_mux_parents; i++) {
127 - if (strcmp(data->parents[i], "xosc") == 0)
128 - parents[i] = cprman->osc_name;
129 - else
130 - parents[i] = data->parents[i];
131 + parents[i] = data->parents[i];
132 +
133 + for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
134 + if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
135 + parents[i] = cprman->real_parent_names[j];
136 + break;
137 + }
138 + }
139 }
140
141 memset(&init, 0, sizeof(init));
142 @@ -1446,6 +1479,47 @@ static const char *const bcm2835_clock_v
143 __VA_ARGS__)
144
145 /*
146 + * DSI parent clocks. The DSI byte/DDR/DDR2 clocks come from the DSI
147 + * analog PHY. The _inv variants are generated internally to cprman,
148 + * but we don't use them so they aren't hooked up.
149 + */
150 +static const char *const bcm2835_clock_dsi0_parents[] = {
151 + "gnd",
152 + "xosc",
153 + "testdebug0",
154 + "testdebug1",
155 + "dsi0_ddr",
156 + "dsi0_ddr_inv",
157 + "dsi0_ddr2",
158 + "dsi0_ddr2_inv",
159 + "dsi0_byte",
160 + "dsi0_byte_inv",
161 +};
162 +
163 +static const char *const bcm2835_clock_dsi1_parents[] = {
164 + "gnd",
165 + "xosc",
166 + "testdebug0",
167 + "testdebug1",
168 + "dsi1_ddr",
169 + "dsi1_ddr_inv",
170 + "dsi1_ddr2",
171 + "dsi1_ddr2_inv",
172 + "dsi1_byte",
173 + "dsi1_byte_inv",
174 +};
175 +
176 +#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \
177 + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \
178 + .parents = bcm2835_clock_dsi0_parents, \
179 + __VA_ARGS__)
180 +
181 +#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \
182 + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \
183 + .parents = bcm2835_clock_dsi1_parents, \
184 + __VA_ARGS__)
185 +
186 +/*
187 * the real definition of all the pll, pll_dividers and clocks
188 * these make use of the above REGISTER_* macros
189 */
190 @@ -1908,6 +1982,18 @@ static const struct bcm2835_clk_desc clk
191 .div_reg = CM_DSI1EDIV,
192 .int_bits = 4,
193 .frac_bits = 8),
194 + [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
195 + .name = "dsi0p",
196 + .ctl_reg = CM_DSI0PCTL,
197 + .div_reg = CM_DSI0PDIV,
198 + .int_bits = 0,
199 + .frac_bits = 0),
200 + [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
201 + .name = "dsi1p",
202 + .ctl_reg = CM_DSI1PCTL,
203 + .div_reg = CM_DSI1PDIV,
204 + .int_bits = 0,
205 + .frac_bits = 0),
206
207 /* the gates */
208
209 @@ -1966,8 +2052,19 @@ static int bcm2835_clk_probe(struct plat
210 if (IS_ERR(cprman->regs))
211 return PTR_ERR(cprman->regs);
212
213 - cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0);
214 - if (!cprman->osc_name)
215 + memcpy(cprman->real_parent_names, cprman_parent_names,
216 + sizeof(cprman_parent_names));
217 + of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
218 + ARRAY_SIZE(cprman_parent_names));
219 +
220 + /*
221 + * Make sure the external oscillator has been registered.
222 + *
223 + * The other (DSI) clocks are not present on older device
224 + * trees, which we still need to support for backwards
225 + * compatibility.
226 + */
227 + if (!cprman->real_parent_names[0])
228 return -ENODEV;
229
230 platform_set_drvdata(pdev, cprman);
231 --- a/include/dt-bindings/clock/bcm2835.h
232 +++ b/include/dt-bindings/clock/bcm2835.h
233 @@ -64,3 +64,5 @@
234 #define BCM2835_CLOCK_CAM1 46
235 #define BCM2835_CLOCK_DSI0E 47
236 #define BCM2835_CLOCK_DSI1E 48
237 +#define BCM2835_CLOCK_DSI0P 49
238 +#define BCM2835_CLOCK_DSI1P 50