1515
1616#include "clk-aspeed.h"
1717
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
1923
2024#define ASPEED_G6_SILICON_REV 0x014
2125#define CHIP_REVISION_ID GENMASK(23, 16)
3236#define ASPEED_G6_CLK_SELECTION1 0x300
3337#define ASPEED_G6_CLK_SELECTION2 0x304
3438#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)
3553
3654#define ASPEED_HPLL_PARAM 0x200
3755#define ASPEED_APLL_PARAM 0x210
@@ -55,6 +73,27 @@ static void __iomem *scu_g6_base;
5573static u8 soc_rev ;
5674
5775/*
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+ *
5897 * Clocks marked with CLK_IS_CRITICAL:
5998 *
6099 * ref0 and ref1 are essential for the SoC to operate
@@ -97,14 +136,13 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = {
97136 [ASPEED_CLK_GATE_LHCCLK ] = { 37 , -1 , "lhclk-gate" , "lhclk" , 0 }, /* LPC master/LPC+ */
98137 /* Reserved 38 RSA: no longer used */
99138 /* 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 */
108146 [ASPEED_CLK_GATE_UART1CLK ] = { 48 , -1 , "uart1clk-gate" , "uart" , 0 }, /* UART1 */
109147 [ASPEED_CLK_GATE_UART2CLK ] = { 49 , -1 , "uart2clk-gate" , "uart" , 0 }, /* UART2 */
110148 [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)
652690 const struct aspeed_gate_data * gd = & aspeed_g6_gates [i ];
653691 u32 gate_flags ;
654692
693+ if (!gd -> name )
694+ continue ;
695+
655696 /*
656697 * Special case: the USB port 1 clock (bit 14) is always
657698 * working the opposite way from the other ones.
@@ -772,6 +813,14 @@ static void __init aspeed_g6_cc(struct regmap *map)
772813 /* USB 2.0 port1 phy 40MHz clock */
773814 hw = clk_hw_register_fixed_rate (NULL , "usb-phy-40m" , NULL , 0 , 40000000 );
774815 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 ;
775824};
776825
777826static void __init aspeed_g6_cc_init (struct device_node * np )
0 commit comments