hc
2024-09-20 a36159eec6ca17402b0e146b86efaf76568dc353
kernel/drivers/clk/clk-aspeed.c
....@@ -1,20 +1,20 @@
11 // SPDX-License-Identifier: GPL-2.0+
2
+// Copyright IBM Corp
23
34 #define pr_fmt(fmt) "clk-aspeed: " fmt
45
5
-#include <linux/clk-provider.h>
66 #include <linux/mfd/syscon.h>
77 #include <linux/of_address.h>
88 #include <linux/of_device.h>
99 #include <linux/platform_device.h>
1010 #include <linux/regmap.h>
11
-#include <linux/reset-controller.h>
1211 #include <linux/slab.h>
13
-#include <linux/spinlock.h>
1412
1513 #include <dt-bindings/clock/aspeed-clock.h>
1614
17
-#define ASPEED_NUM_CLKS 36
15
+#include "clk-aspeed.h"
16
+
17
+#define ASPEED_NUM_CLKS 38
1818
1919 #define ASPEED_RESET2_OFFSET 32
2020
....@@ -28,6 +28,7 @@
2828 #define AST2400_HPLL_BYPASS_EN BIT(17)
2929 #define ASPEED_MISC_CTRL 0x2c
3030 #define UART_DIV13_EN BIT(12)
31
+#define ASPEED_MAC_CLK_DLY 0x48
3132 #define ASPEED_STRAP 0x70
3233 #define CLKIN_25MHZ_EN BIT(23)
3334 #define AST2400_CLK_SOURCE_SEL BIT(18)
....@@ -42,55 +43,13 @@
4243
4344 static void __iomem *scu_base;
4445
45
-/**
46
- * struct aspeed_gate_data - Aspeed gated clocks
47
- * @clock_idx: bit used to gate this clock in the clock register
48
- * @reset_idx: bit used to reset this IP in the reset register. -1 if no
49
- * reset is required when enabling the clock
50
- * @name: the clock name
51
- * @parent_name: the name of the parent clock
52
- * @flags: standard clock framework flags
53
- */
54
-struct aspeed_gate_data {
55
- u8 clock_idx;
56
- s8 reset_idx;
57
- const char *name;
58
- const char *parent_name;
59
- unsigned long flags;
60
-};
61
-
62
-/**
63
- * struct aspeed_clk_gate - Aspeed specific clk_gate structure
64
- * @hw: handle between common and hardware-specific interfaces
65
- * @reg: register controlling gate
66
- * @clock_idx: bit used to gate this clock in the clock register
67
- * @reset_idx: bit used to reset this IP in the reset register. -1 if no
68
- * reset is required when enabling the clock
69
- * @flags: hardware-specific flags
70
- * @lock: register lock
71
- *
72
- * Some of the clocks in the Aspeed SoC must be put in reset before enabling.
73
- * This modified version of clk_gate allows an optional reset bit to be
74
- * specified.
75
- */
76
-struct aspeed_clk_gate {
77
- struct clk_hw hw;
78
- struct regmap *map;
79
- u8 clock_idx;
80
- s8 reset_idx;
81
- u8 flags;
82
- spinlock_t *lock;
83
-};
84
-
85
-#define to_aspeed_clk_gate(_hw) container_of(_hw, struct aspeed_clk_gate, hw)
86
-
8746 /* TODO: ask Aspeed about the actual parent data */
8847 static const struct aspeed_gate_data aspeed_gates[] = {
8948 /* clk rst name parent flags */
90
- [ASPEED_CLK_GATE_ECLK] = { 0, -1, "eclk-gate", "eclk", 0 }, /* Video Engine */
49
+ [ASPEED_CLK_GATE_ECLK] = { 0, 6, "eclk-gate", "eclk", 0 }, /* Video Engine */
9150 [ASPEED_CLK_GATE_GCLK] = { 1, 7, "gclk-gate", NULL, 0 }, /* 2D engine */
9251 [ASPEED_CLK_GATE_MCLK] = { 2, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */
93
- [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */
52
+ [ASPEED_CLK_GATE_VCLK] = { 3, -1, "vclk-gate", NULL, 0 }, /* Video Capture */
9453 [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", CLK_IS_CRITICAL }, /* PCIe/PCI */
9554 [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */
9655 [ASPEED_CLK_GATE_REFCLK] = { 6, -1, "refclk-gate", "clkin", CLK_IS_CRITICAL },
....@@ -111,6 +70,24 @@
11170 [ASPEED_CLK_GATE_UART4CLK] = { 26, -1, "uart4clk-gate", "uart", 0 }, /* UART4 */
11271 [ASPEED_CLK_GATE_SDCLK] = { 27, 16, "sdclk-gate", NULL, 0 }, /* SDIO/SD */
11372 [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */
73
+};
74
+
75
+static const char * const eclk_parent_names[] = {
76
+ "mpll",
77
+ "hpll",
78
+ "dpll",
79
+};
80
+
81
+static const struct clk_div_table ast2500_eclk_div_table[] = {
82
+ { 0x0, 2 },
83
+ { 0x1, 2 },
84
+ { 0x2, 3 },
85
+ { 0x3, 4 },
86
+ { 0x4, 5 },
87
+ { 0x5, 6 },
88
+ { 0x6, 7 },
89
+ { 0x7, 8 },
90
+ { 0 }
11491 };
11592
11693 static const struct clk_div_table ast2500_mac_div_table[] = {
....@@ -190,20 +167,16 @@
190167 mult, div);
191168 }
192169
193
-struct aspeed_clk_soc_data {
194
- const struct clk_div_table *div_table;
195
- const struct clk_div_table *mac_div_table;
196
- struct clk_hw *(*calc_pll)(const char *name, u32 val);
197
-};
198
-
199170 static const struct aspeed_clk_soc_data ast2500_data = {
200171 .div_table = ast2500_div_table,
172
+ .eclk_div_table = ast2500_eclk_div_table,
201173 .mac_div_table = ast2500_mac_div_table,
202174 .calc_pll = aspeed_ast2500_calc_pll,
203175 };
204176
205177 static const struct aspeed_clk_soc_data ast2400_data = {
206178 .div_table = ast2400_div_table,
179
+ .eclk_div_table = ast2400_div_table,
207180 .mac_div_table = ast2400_div_table,
208181 .calc_pll = aspeed_ast2400_calc_pll,
209182 };
....@@ -294,18 +267,6 @@
294267 .is_enabled = aspeed_clk_is_enabled,
295268 };
296269
297
-/**
298
- * struct aspeed_reset - Aspeed reset controller
299
- * @map: regmap to access the containing system controller
300
- * @rcdev: reset controller device
301
- */
302
-struct aspeed_reset {
303
- struct regmap *map;
304
- struct reset_controller_dev rcdev;
305
-};
306
-
307
-#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev)
308
-
309270 static const u8 aspeed_resets[] = {
310271 /* SCU04 resets */
311272 [ASPEED_RESET_XDMA] = 25,
....@@ -387,7 +348,7 @@
387348 u8 clk_gate_flags, spinlock_t *lock)
388349 {
389350 struct aspeed_clk_gate *gate;
390
- struct clk_init_data init = {};
351
+ struct clk_init_data init;
391352 struct clk_hw *hw;
392353 int ret;
393354
....@@ -479,9 +440,14 @@
479440 return PTR_ERR(hw);
480441 aspeed_clk_data->hws[ASPEED_CLK_MPLL] = hw;
481442
482
- /* SD/SDIO clock divider (TODO: There's a gate too) */
483
- hw = clk_hw_register_divider_table(dev, "sdio", "hpll", 0,
484
- scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
443
+ /* SD/SDIO clock divider and gate */
444
+ hw = clk_hw_register_gate(dev, "sd_extclk_gate", "hpll", 0,
445
+ scu_base + ASPEED_CLK_SELECTION, 15, 0,
446
+ &aspeed_clk_lock);
447
+ if (IS_ERR(hw))
448
+ return PTR_ERR(hw);
449
+ hw = clk_hw_register_divider_table(dev, "sd_extclk", "sd_extclk_gate",
450
+ 0, scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
485451 soc_data->div_table,
486452 &aspeed_clk_lock);
487453 if (IS_ERR(hw))
....@@ -496,6 +462,30 @@
496462 if (IS_ERR(hw))
497463 return PTR_ERR(hw);
498464 aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw;
465
+
466
+ if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) {
467
+ /* RMII 50MHz RCLK */
468
+ hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0,
469
+ 50000000);
470
+ if (IS_ERR(hw))
471
+ return PTR_ERR(hw);
472
+
473
+ /* RMII1 50MHz (RCLK) output enable */
474
+ hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0,
475
+ scu_base + ASPEED_MAC_CLK_DLY, 29, 0,
476
+ &aspeed_clk_lock);
477
+ if (IS_ERR(hw))
478
+ return PTR_ERR(hw);
479
+ aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw;
480
+
481
+ /* RMII2 50MHz (RCLK) output enable */
482
+ hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0,
483
+ scu_base + ASPEED_MAC_CLK_DLY, 30, 0,
484
+ &aspeed_clk_lock);
485
+ if (IS_ERR(hw))
486
+ return PTR_ERR(hw);
487
+ aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw;
488
+ }
499489
500490 /* LPC Host (LHCLK) clock divider */
501491 hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
....@@ -522,6 +512,22 @@
522512 return PTR_ERR(hw);
523513 aspeed_clk_data->hws[ASPEED_CLK_24M] = hw;
524514
515
+ hw = clk_hw_register_mux(dev, "eclk-mux", eclk_parent_names,
516
+ ARRAY_SIZE(eclk_parent_names), 0,
517
+ scu_base + ASPEED_CLK_SELECTION, 2, 0x3, 0,
518
+ &aspeed_clk_lock);
519
+ if (IS_ERR(hw))
520
+ return PTR_ERR(hw);
521
+ aspeed_clk_data->hws[ASPEED_CLK_ECLK_MUX] = hw;
522
+
523
+ hw = clk_hw_register_divider_table(dev, "eclk", "eclk-mux", 0,
524
+ scu_base + ASPEED_CLK_SELECTION, 28,
525
+ 3, 0, soc_data->eclk_div_table,
526
+ &aspeed_clk_lock);
527
+ if (IS_ERR(hw))
528
+ return PTR_ERR(hw);
529
+ aspeed_clk_data->hws[ASPEED_CLK_ECLK] = hw;
530
+
525531 /*
526532 * TODO: There are a number of clocks that not included in this driver
527533 * as more information is required:
....@@ -531,7 +537,6 @@
531537 * RGMII
532538 * RMII
533539 * UART[1..5] clock source mux
534
- * Video Engine (ECLK) mux and clock divider
535540 */
536541
537542 for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {