737ecfe0142be82ce0d47fa1a71c75191251ed76
[platform/kernel/linux-starfive.git] / drivers / clk / starfive / clk-starfive-jh7110-aon.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * StarFive JH7110 aon Clock Generator Driver
4  *
5  * Copyright (C) 2022 Xingyu Wu <xingyu.wu@starfivetech.com>
6  */
7
8 #include <linux/clk.h>
9 #include <linux/clk-provider.h>
10 #include <linux/init.h>
11 #include <linux/platform_device.h>
12
13 #include <dt-bindings/clock/starfive-jh7110-clkgen.h>
14 #include "clk-starfive-jh7110.h"
15
16 static const struct jh7110_clk_data jh7110_clk_aon_data[] __initconst = {
17         //source
18         JH7110__DIV(JH7110_OSC_DIV4, "osc_div4", 4, JH7110_OSC),
19         JH7110__MUX(JH7110_AON_APB_FUNC, "aon_apb_func", PARENT_NUMS_2,
20                         JH7110_OSC_DIV4,
21                         JH7110_OSC),
22         //gmac5
23         JH7110_GATE(JH7110_U0_GMAC5_CLK_AHB, 
24                         "u0_dw_gmac5_axi64_clk_ahb",
25                         GATE_FLAG_NORMAL, JH7110_AON_AHB),
26         JH7110_GATE(JH7110_U0_GMAC5_CLK_AXI,
27                         "u0_dw_gmac5_axi64_clk_axi",
28                         GATE_FLAG_NORMAL, JH7110_AON_AHB),
29         JH7110__DIV(JH7110_GMAC0_RMII_RTX,
30                         "gmac0_rmii_rtx", 30, JH7110_GMAC0_RMII_REFIN),
31         JH7110_GMUX(JH7110_U0_GMAC5_CLK_TX,
32                         "u0_dw_gmac5_axi64_clk_tx",
33                         GATE_FLAG_NORMAL, PARENT_NUMS_2,
34                         JH7110_GMAC0_GTXCLK,
35                         JH7110_GMAC0_RMII_RTX),
36         JH7110__INV(JH7110_U0_GMAC5_CLK_TX_INV,
37                         "u0_dw_gmac5_axi64_clk_tx_inv",
38                         JH7110_U0_GMAC5_CLK_TX),
39         JH7110__MUX(JH7110_U0_GMAC5_CLK_RX,
40                         "u0_dw_gmac5_axi64_clk_rx", PARENT_NUMS_2,
41                         JH7110_GMAC0_RGMII_RXIN,
42                         JH7110_GMAC0_RMII_RTX),
43         JH7110__INV(JH7110_U0_GMAC5_CLK_RX_INV,
44                         "u0_dw_gmac5_axi64_clk_rx_inv",
45                         JH7110_U0_GMAC5_CLK_RX),
46         //otpc
47         JH7110_GATE(JH7110_OTPC_CLK_APB,
48                         "u0_otpc_clk_apb",
49                         CLK_IGNORE_UNUSED, JH7110_AON_APB),
50         //rtc
51         JH7110_GATE(JH7110_RTC_HMS_CLK_APB,
52                         "u0_rtc_hms_clk_apb",
53                         CLK_IGNORE_UNUSED, JH7110_AON_APB),
54         JH7110__DIV(JH7110_RTC_INTERNAL,
55                         "rtc_internal", 1022, JH7110_OSC),
56         JH7110__MUX(JH7110_RTC_HMS_CLK_OSC32K,
57                         "u0_rtc_hms_clk_osc32k", PARENT_NUMS_2,
58                         JH7110_CLK_RTC,
59                         JH7110_RTC_INTERNAL),
60         JH7110_GATE(JH7110_RTC_HMS_CLK_CAL,
61                         "u0_rtc_hms_clk_cal",
62                         GATE_FLAG_NORMAL, JH7110_OSC),
63 };
64
65 int __init clk_starfive_jh7110_aon_init(struct platform_device *pdev,
66                                                 struct jh7110_clk_priv *priv)
67 {
68         unsigned int idx;
69         int ret = 0;
70
71         priv->aon_base = devm_platform_ioremap_resource_byname(pdev, "aon");
72         if (IS_ERR(priv->aon_base))
73                 return PTR_ERR(priv->aon_base);
74
75         priv->pll[PLL_OF(JH7110_U0_GMAC5_CLK_PTP)] =
76                         devm_clk_hw_register_fixed_factor(priv->dev,
77                         "u0_dw_gmac5_axi64_clk_ptp", "gmac0_ptp", 0, 1, 1);
78         priv->pll[PLL_OF(JH7110_U0_GMAC5_CLK_RMII)] =
79                         devm_clk_hw_register_fixed_factor(priv->dev,
80                         "u0_dw_gmac5_axi64_clk_rmii",
81                         "gmac0_rmii_refin", 0, 1, 1);
82         priv->pll[PLL_OF(JH7110_AON_SYSCON_PCLK)] =
83                         devm_clk_hw_register_fixed_factor(priv->dev,
84                         "u0_aon_syscon_pclk", "aon_apb", 0, 1, 1);
85         priv->pll[PLL_OF(JH7110_AON_IOMUX_PCLK)] =
86                         devm_clk_hw_register_fixed_factor(priv->dev,
87                         "u0_aon_iomux_pclk", "aon_apb", 0, 1, 1);
88         priv->pll[PLL_OF(JH7110_AON_CRG_PCLK)] =
89                         devm_clk_hw_register_fixed_factor(priv->dev,
90                         "u0_aon_crg_pclk", "aon_apb", 0, 1, 1);
91         priv->pll[PLL_OF(JH7110_PMU_CLK_APB)] =
92                         devm_clk_hw_register_fixed_factor(priv->dev,
93                         "u0_pmu_clk_apb", "aon_apb", 0, 1, 1);
94         priv->pll[PLL_OF(JH7110_PMU_CLK_WKUP)] =
95                         devm_clk_hw_register_fixed_factor(priv->dev,
96                         "u0_pmu_clk_wkup", "aon_apb", 0, 1, 1);
97         priv->pll[PLL_OF(JH7110_RTC_HMS_CLK_OSC32K_G)] =
98                         devm_clk_hw_register_fixed_factor(priv->dev,
99                         "u0_rtc_hms_clk_osc32k_g",
100                         "u0_rtc_hms_clk_osc32k", 0, 1, 1);
101         priv->pll[PLL_OF(JH7110_32K_OUT)] =
102                         devm_clk_hw_register_fixed_factor(priv->dev,
103                         "32k_out", "clk_rtc", 0, 1, 1);
104         priv->pll[PLL_OF(JH7110_RESET0_CTRL_CLK_SRC)] =
105                         devm_clk_hw_register_fixed_factor(priv->dev,
106                         "u0_reset_ctrl_clk_src", "osc", 0, 1, 1);
107         priv->pll[PLL_OF(JH7110_PCLK_MUX_FUNC_PCLK)] =
108                         devm_clk_hw_register_fixed_factor(priv->dev,
109                         "u1_pclk_mux_func_pclk", "aon_apb_func", 0, 1, 1);
110         priv->pll[PLL_OF(JH7110_PCLK_MUX_BIST_PCLK)] =
111                         devm_clk_hw_register_fixed_factor(priv->dev,
112                         "u1_pclk_mux_bist_pclk", "bist_apb", 0, 1, 1);
113
114         for (idx = JH7110_CLK_STG_REG_END; idx < JH7110_CLK_REG_END; idx++) {
115                 u32 max = jh7110_clk_aon_data[idx].max;
116                 struct clk_parent_data parents[4] = {};
117                 struct clk_init_data init = {
118                         .name = jh7110_clk_aon_data[idx].name,
119                         .ops = starfive_jh7110_clk_ops(max),
120                         .parent_data = parents,
121                         .num_parents = ((max & JH7110_CLK_MUX_MASK) \
122                                         >> JH7110_CLK_MUX_SHIFT) + 1,
123                         .flags = jh7110_clk_aon_data[idx].flags,
124                 };
125                 struct jh7110_clk *clk = &priv->reg[idx];
126                 unsigned int i;
127
128                 for (i = 0; i < init.num_parents; i++) {
129                         unsigned int pidx = jh7110_clk_aon_data[idx].parents[i];
130
131                         if (pidx < JH7110_CLK_REG_END)
132                                 parents[i].hw = &priv->reg[pidx].hw;
133                         else if ((pidx < JH7110_CLK_END) && \
134                                 (pidx > JH7110_RTC_HMS_CLK_CAL))
135                                 parents[i].hw = priv->pll[PLL_OF(pidx)];
136                         else if (pidx == JH7110_GMAC0_RMII_REFIN)
137                                 parents[i].fw_name = "gmac0_rmii_refin";
138                         else if (pidx == JH7110_GMAC0_RGMII_RXIN)
139                                 parents[i].fw_name = "gmac0_rgmii_rxin";
140                         else if (pidx == JH7110_CLK_RTC)
141                                 parents[i].fw_name = "clk_rtc";
142                 }
143
144                 clk->hw.init = &init;
145                 clk->idx = idx;
146                 clk->max_div = max & JH7110_CLK_DIV_MASK;
147                 clk->reg_flags = JH7110_CLK_AON_FLAG;
148
149                 ret = devm_clk_hw_register(priv->dev, &clk->hw);
150                 if (ret)
151                         return ret;
152         }
153
154         dev_dbg(&pdev->dev,"starfive JH7110 clk_aon init successfully.");
155         return 0;
156 }