15
15
16
16
#include "clk-aspeed.h"
17
17
18
- #define ASPEED_G6_NUM_CLKS 71
18
+ /*
19
+ * This includes the gates (configured from aspeed_g6_gates), plus the
20
+ * explicitly-configured clocks (ASPEED_CLK_HPLL and up).
21
+ */
22
+ #define ASPEED_G6_NUM_CLKS 72
19
23
20
24
#define ASPEED_G6_SILICON_REV 0x014
21
25
#define CHIP_REVISION_ID GENMASK(23, 16)
32
36
#define ASPEED_G6_CLK_SELECTION1 0x300
33
37
#define ASPEED_G6_CLK_SELECTION2 0x304
34
38
#define ASPEED_G6_CLK_SELECTION4 0x310
39
+ #define ASPEED_G6_CLK_SELECTION5 0x314
40
+ #define I3C_CLK_SELECTION_SHIFT 31
41
+ #define I3C_CLK_SELECTION BIT(31)
42
+ #define I3C_CLK_SELECT_HCLK (0 << I3C_CLK_SELECTION_SHIFT)
43
+ #define I3C_CLK_SELECT_APLL_DIV (1 << I3C_CLK_SELECTION_SHIFT)
44
+ #define APLL_DIV_SELECTION_SHIFT 28
45
+ #define APLL_DIV_SELECTION GENMASK(30, 28)
46
+ #define APLL_DIV_2 (0b001 << APLL_DIV_SELECTION_SHIFT)
47
+ #define APLL_DIV_3 (0b010 << APLL_DIV_SELECTION_SHIFT)
48
+ #define APLL_DIV_4 (0b011 << APLL_DIV_SELECTION_SHIFT)
49
+ #define APLL_DIV_5 (0b100 << APLL_DIV_SELECTION_SHIFT)
50
+ #define APLL_DIV_6 (0b101 << APLL_DIV_SELECTION_SHIFT)
51
+ #define APLL_DIV_7 (0b110 << APLL_DIV_SELECTION_SHIFT)
52
+ #define APLL_DIV_8 (0b111 << APLL_DIV_SELECTION_SHIFT)
35
53
36
54
#define ASPEED_HPLL_PARAM 0x200
37
55
#define ASPEED_APLL_PARAM 0x210
@@ -55,6 +73,27 @@ static void __iomem *scu_g6_base;
55
73
static u8 soc_rev ;
56
74
57
75
/*
76
+ * The majority of the clocks in the system are gates paired with a reset
77
+ * controller that holds the IP in reset; this is represented by the @reset_idx
78
+ * member of entries here.
79
+ *
80
+ * This borrows from clk_hw_register_gate, but registers two 'gates', one
81
+ * to control the clock enable register and the other to control the reset
82
+ * IP. This allows us to enforce the ordering:
83
+ *
84
+ * 1. Place IP in reset
85
+ * 2. Enable clock
86
+ * 3. Delay
87
+ * 4. Release reset
88
+ *
89
+ * Consequently, if reset_idx is set, reset control is implicit: the clock
90
+ * consumer does not need its own reset handling, as enabling the clock will
91
+ * also deassert reset.
92
+ *
93
+ * There are some gates that do not have an associated reset; these are
94
+ * handled by using -1 as the index for the reset, and the consumer must
95
+ * explictly assert/deassert reset lines as required.
96
+ *
58
97
* Clocks marked with CLK_IS_CRITICAL:
59
98
*
60
99
* ref0 and ref1 are essential for the SoC to operate
@@ -97,14 +136,13 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = {
97
136
[ASPEED_CLK_GATE_LHCCLK ] = { 37 , -1 , "lhclk-gate" , "lhclk" , 0 }, /* LPC master/LPC+ */
98
137
/* Reserved 38 RSA: no longer used */
99
138
/* Reserved 39 */
100
- [ASPEED_CLK_GATE_I3C0CLK ] = { 40 , 40 , "i3c0clk-gate" , NULL , 0 }, /* I3C0 */
101
- [ASPEED_CLK_GATE_I3C1CLK ] = { 41 , 41 , "i3c1clk-gate" , NULL , 0 }, /* I3C1 */
102
- [ASPEED_CLK_GATE_I3C2CLK ] = { 42 , 42 , "i3c2clk-gate" , NULL , 0 }, /* I3C2 */
103
- [ASPEED_CLK_GATE_I3C3CLK ] = { 43 , 43 , "i3c3clk-gate" , NULL , 0 }, /* I3C3 */
104
- [ASPEED_CLK_GATE_I3C4CLK ] = { 44 , 44 , "i3c4clk-gate" , NULL , 0 }, /* I3C4 */
105
- [ASPEED_CLK_GATE_I3C5CLK ] = { 45 , 45 , "i3c5clk-gate" , NULL , 0 }, /* I3C5 */
106
- [ASPEED_CLK_GATE_I3C6CLK ] = { 46 , 46 , "i3c6clk-gate" , NULL , 0 }, /* I3C6 */
107
- [ASPEED_CLK_GATE_I3C7CLK ] = { 47 , 47 , "i3c7clk-gate" , NULL , 0 }, /* I3C7 */
139
+ [ASPEED_CLK_GATE_I3C0CLK ] = { 40 , 40 , "i3c0clk-gate" , "i3cclk" , 0 }, /* I3C0 */
140
+ [ASPEED_CLK_GATE_I3C1CLK ] = { 41 , 41 , "i3c1clk-gate" , "i3cclk" , 0 }, /* I3C1 */
141
+ [ASPEED_CLK_GATE_I3C2CLK ] = { 42 , 42 , "i3c2clk-gate" , "i3cclk" , 0 }, /* I3C2 */
142
+ [ASPEED_CLK_GATE_I3C3CLK ] = { 43 , 43 , "i3c3clk-gate" , "i3cclk" , 0 }, /* I3C3 */
143
+ [ASPEED_CLK_GATE_I3C4CLK ] = { 44 , 44 , "i3c4clk-gate" , "i3cclk" , 0 }, /* I3C4 */
144
+ [ASPEED_CLK_GATE_I3C5CLK ] = { 45 , 45 , "i3c5clk-gate" , "i3cclk" , 0 }, /* I3C5 */
145
+ /* Reserved: 46 & 47 */
108
146
[ASPEED_CLK_GATE_UART1CLK ] = { 48 , -1 , "uart1clk-gate" , "uart" , 0 }, /* UART1 */
109
147
[ASPEED_CLK_GATE_UART2CLK ] = { 49 , -1 , "uart2clk-gate" , "uart" , 0 }, /* UART2 */
110
148
[ASPEED_CLK_GATE_UART3CLK ] = { 50 , -1 , "uart3clk-gate" , "uart" , 0 }, /* UART3 */
@@ -652,6 +690,9 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
652
690
const struct aspeed_gate_data * gd = & aspeed_g6_gates [i ];
653
691
u32 gate_flags ;
654
692
693
+ if (!gd -> name )
694
+ continue ;
695
+
655
696
/*
656
697
* Special case: the USB port 1 clock (bit 14) is always
657
698
* working the opposite way from the other ones.
@@ -772,6 +813,14 @@ static void __init aspeed_g6_cc(struct regmap *map)
772
813
/* USB 2.0 port1 phy 40MHz clock */
773
814
hw = clk_hw_register_fixed_rate (NULL , "usb-phy-40m" , NULL , 0 , 40000000 );
774
815
aspeed_g6_clk_data -> hws [ASPEED_CLK_USBPHY_40M ] = hw ;
816
+
817
+ /* i3c clock: source from apll, divide by 8 */
818
+ regmap_update_bits (map , ASPEED_G6_CLK_SELECTION5 ,
819
+ I3C_CLK_SELECTION | APLL_DIV_SELECTION ,
820
+ I3C_CLK_SELECT_APLL_DIV | APLL_DIV_8 );
821
+
822
+ hw = clk_hw_register_fixed_factor (NULL , "i3cclk" , "apll" , 0 , 1 , 8 );
823
+ aspeed_g6_clk_data -> hws [ASPEED_CLK_I3C ] = hw ;
775
824
};
776
825
777
826
static void __init aspeed_g6_cc_init (struct device_node * np )
0 commit comments