aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/mvebu
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@bootlin.com>2018-02-28 09:07:51 -0500
committerStephen Boyd <sboyd@kernel.org>2018-03-19 16:10:50 -0400
commitc7e92def1ef4dad7a45f0fcca283da1afd003966 (patch)
tree9c6c0846dd7299b1e59e9b2d53932aa70869e4b3 /drivers/clk/mvebu
parent7928b2cbe55b2a410a0f5c1f154610059c57b1b2 (diff)
clk: mvebu: cp110: Fix clock tree representation
Thanks to new documentation, we have a better view of the clock tree. There were few mistakes in the first version of this driver, the main one being the parental link between the clocks. Actually the tree is more flat that we though. Most of the IP blocks require two clocks: one for the IP itself and one for accessing the registers, and unlike what we wrote there is no link between these two clocks. The other mistakes were about the name of the clocks: the root clock is not the Audio PLL but the PLL0, and what we called the EIP clock is named the x2 Core clock and is used by other IP block than the EIP ones. Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/mvebu')
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c94
1 files changed, 39 insertions, 55 deletions
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index ca9a0a536174..75bf7b8f282f 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -13,18 +13,17 @@
13/* 13/*
14 * CP110 has 6 core clocks: 14 * CP110 has 6 core clocks:
15 * 15 *
16 * - APLL (1 Ghz) 16 * - PLL0 (1 Ghz)
17 * - PPv2 core (1/3 APLL) 17 * - PPv2 core (1/3 PLL0)
18 * - EIP (1/2 APLL) 18 * - x2 Core (1/2 PLL0)
19 * - Core (1/2 EIP) 19 * - Core (1/2 x2 Core)
20 * - SDIO (2/5 APLL) 20 * - SDIO (2/5 PLL0)
21 * 21 *
22 * - NAND clock, which is either: 22 * - NAND clock, which is either:
23 * - Equal to SDIO clock 23 * - Equal to SDIO clock
24 * - 2/5 APLL 24 * - 2/5 PLL0
25 * 25 *
26 * CP110 has 32 gatable clocks, for the various peripherals in the 26 * CP110 has 32 gatable clocks, for the various peripherals in the IP.
27 * IP. They have fairly complicated parent/child relationships.
28 */ 27 */
29 28
30#define pr_fmt(fmt) "cp110-system-controller: " fmt 29#define pr_fmt(fmt) "cp110-system-controller: " fmt
@@ -53,9 +52,9 @@ enum {
53#define CP110_CLK_NUM \ 52#define CP110_CLK_NUM \
54 (CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS) 53 (CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS)
55 54
56#define CP110_CORE_APLL 0 55#define CP110_CORE_PLL0 0
57#define CP110_CORE_PPV2 1 56#define CP110_CORE_PPV2 1
58#define CP110_CORE_EIP 2 57#define CP110_CORE_X2CORE 2
59#define CP110_CORE_CORE 3 58#define CP110_CORE_CORE 3
60#define CP110_CORE_NAND 4 59#define CP110_CORE_NAND 4
61#define CP110_CORE_SDIO 5 60#define CP110_CORE_SDIO 5
@@ -237,7 +236,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
237 struct regmap *regmap; 236 struct regmap *regmap;
238 struct device *dev = &pdev->dev; 237 struct device *dev = &pdev->dev;
239 struct device_node *np = dev->of_node; 238 struct device_node *np = dev->of_node;
240 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name, 239 const char *ppv2_name, *pll0_name, *core_name, *x2core_name, *nand_name,
241 *sdio_name; 240 *sdio_name;
242 struct clk_hw_onecell_data *cp110_clk_data; 241 struct clk_hw_onecell_data *cp110_clk_data;
243 struct clk_hw *hw, **cp110_clks; 242 struct clk_hw *hw, **cp110_clks;
@@ -263,20 +262,20 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
263 cp110_clks = cp110_clk_data->hws; 262 cp110_clks = cp110_clk_data->hws;
264 cp110_clk_data->num = CP110_CLK_NUM; 263 cp110_clk_data->num = CP110_CLK_NUM;
265 264
266 /* Register the APLL which is the root of the hw tree */ 265 /* Register the PLL0 which is the root of the hw tree */
267 apll_name = cp110_unique_name(dev, syscon_node, "apll"); 266 pll0_name = cp110_unique_name(dev, syscon_node, "pll0");
268 hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0, 267 hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0,
269 1000 * 1000 * 1000); 268 1000 * 1000 * 1000);
270 if (IS_ERR(hw)) { 269 if (IS_ERR(hw)) {
271 ret = PTR_ERR(hw); 270 ret = PTR_ERR(hw);
272 goto fail_apll; 271 goto fail_pll0;
273 } 272 }
274 273
275 cp110_clks[CP110_CORE_APLL] = hw; 274 cp110_clks[CP110_CORE_PLL0] = hw;
276 275
277 /* PPv2 is APLL/3 */ 276 /* PPv2 is PLL0/3 */
278 ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core"); 277 ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
279 hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3); 278 hw = clk_hw_register_fixed_factor(NULL, ppv2_name, pll0_name, 0, 1, 3);
280 if (IS_ERR(hw)) { 279 if (IS_ERR(hw)) {
281 ret = PTR_ERR(hw); 280 ret = PTR_ERR(hw);
282 goto fail_ppv2; 281 goto fail_ppv2;
@@ -284,30 +283,32 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
284 283
285 cp110_clks[CP110_CORE_PPV2] = hw; 284 cp110_clks[CP110_CORE_PPV2] = hw;
286 285
287 /* EIP clock is APLL/2 */ 286 /* X2CORE clock is PLL0/2 */
288 eip_name = cp110_unique_name(dev, syscon_node, "eip"); 287 x2core_name = cp110_unique_name(dev, syscon_node, "x2core");
289 hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2); 288 hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name,
289 0, 1, 2);
290 if (IS_ERR(hw)) { 290 if (IS_ERR(hw)) {
291 ret = PTR_ERR(hw); 291 ret = PTR_ERR(hw);
292 goto fail_eip; 292 goto fail_eip;
293 } 293 }
294 294
295 cp110_clks[CP110_CORE_EIP] = hw; 295 cp110_clks[CP110_CORE_X2CORE] = hw;
296 296
297 /* Core clock is EIP/2 */ 297 /* Core clock is X2CORE/2 */
298 core_name = cp110_unique_name(dev, syscon_node, "core"); 298 core_name = cp110_unique_name(dev, syscon_node, "core");
299 hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2); 299 hw = clk_hw_register_fixed_factor(NULL, core_name, x2core_name,
300 0, 1, 2);
300 if (IS_ERR(hw)) { 301 if (IS_ERR(hw)) {
301 ret = PTR_ERR(hw); 302 ret = PTR_ERR(hw);
302 goto fail_core; 303 goto fail_core;
303 } 304 }
304 305
305 cp110_clks[CP110_CORE_CORE] = hw; 306 cp110_clks[CP110_CORE_CORE] = hw;
306 /* NAND can be either APLL/2.5 or core clock */ 307 /* NAND can be either PLL0/2.5 or core clock */
307 nand_name = cp110_unique_name(dev, syscon_node, "nand-core"); 308 nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
308 if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK) 309 if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
309 hw = clk_hw_register_fixed_factor(NULL, nand_name, 310 hw = clk_hw_register_fixed_factor(NULL, nand_name,
310 apll_name, 0, 2, 5); 311 pll0_name, 0, 2, 5);
311 else 312 else
312 hw = clk_hw_register_fixed_factor(NULL, nand_name, 313 hw = clk_hw_register_fixed_factor(NULL, nand_name,
313 core_name, 0, 1, 1); 314 core_name, 0, 1, 1);
@@ -318,10 +319,10 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
318 319
319 cp110_clks[CP110_CORE_NAND] = hw; 320 cp110_clks[CP110_CORE_NAND] = hw;
320 321
321 /* SDIO clock is APLL/2.5 */ 322 /* SDIO clock is PLL0/2.5 */
322 sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core"); 323 sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
323 hw = clk_hw_register_fixed_factor(NULL, sdio_name, 324 hw = clk_hw_register_fixed_factor(NULL, sdio_name,
324 apll_name, 0, 2, 5); 325 pll0_name, 0, 2, 5);
325 if (IS_ERR(hw)) { 326 if (IS_ERR(hw)) {
326 ret = PTR_ERR(hw); 327 ret = PTR_ERR(hw);
327 goto fail_sdio; 328 goto fail_sdio;
@@ -341,40 +342,23 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
341 continue; 342 continue;
342 343
343 switch (i) { 344 switch (i) {
344 case CP110_GATE_AUDIO:
345 case CP110_GATE_COMM_UNIT:
346 case CP110_GATE_EIP150:
347 case CP110_GATE_EIP197:
348 case CP110_GATE_SLOW_IO:
349 parent = gate_name[CP110_GATE_MAIN];
350 break;
351 case CP110_GATE_MG:
352 parent = gate_name[CP110_GATE_MG_CORE];
353 break;
354 case CP110_GATE_NAND: 345 case CP110_GATE_NAND:
355 parent = nand_name; 346 parent = nand_name;
356 break; 347 break;
348 case CP110_GATE_MG:
349 case CP110_GATE_GOP_DP:
357 case CP110_GATE_PPV2: 350 case CP110_GATE_PPV2:
358 parent = ppv2_name; 351 parent = ppv2_name;
359 break; 352 break;
360 case CP110_GATE_SDIO: 353 case CP110_GATE_SDIO:
361 parent = sdio_name; 354 parent = sdio_name;
362 break; 355 break;
363 case CP110_GATE_GOP_DP: 356 case CP110_GATE_MAIN:
364 parent = gate_name[CP110_GATE_SDMMC_GOP]; 357 case CP110_GATE_PCIE_XOR:
365 break;
366 case CP110_GATE_XOR1:
367 case CP110_GATE_XOR0:
368 case CP110_GATE_PCIE_X1_0:
369 case CP110_GATE_PCIE_X1_1:
370 case CP110_GATE_PCIE_X4: 358 case CP110_GATE_PCIE_X4:
371 parent = gate_name[CP110_GATE_PCIE_XOR]; 359 case CP110_GATE_EIP150:
372 break; 360 case CP110_GATE_EIP197:
373 case CP110_GATE_SATA: 361 parent = x2core_name;
374 case CP110_GATE_USB3H0:
375 case CP110_GATE_USB3H1:
376 case CP110_GATE_USB3DEV:
377 parent = gate_name[CP110_GATE_SATA_USB];
378 break; 362 break;
379 default: 363 default:
380 parent = core_name; 364 parent = core_name;
@@ -413,12 +397,12 @@ fail_sdio:
413fail_nand: 397fail_nand:
414 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]); 398 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
415fail_core: 399fail_core:
416 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]); 400 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_X2CORE]);
417fail_eip: 401fail_eip:
418 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]); 402 clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
419fail_ppv2: 403fail_ppv2:
420 clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]); 404 clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_PLL0]);
421fail_apll: 405fail_pll0:
422 return ret; 406 return ret;
423} 407}
424 408