GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / clk / meson / axg-aoclk.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Amlogic Meson-AXG Clock Controller Driver
4  *
5  * Copyright (c) 2016 Baylibre SAS.
6  * Author: Michael Turquette <mturquette@baylibre.com>
7  *
8  * Copyright (c) 2018 Amlogic, inc.
9  * Author: Qiufang Dai <qiufang.dai@amlogic.com>
10  */
11 #include <linux/clk-provider.h>
12 #include <linux/platform_device.h>
13 #include <linux/reset-controller.h>
14 #include <linux/mfd/syscon.h>
15 #include "clk-regmap.h"
16 #include "meson-aoclk.h"
17 #include "axg-aoclk.h"
18
19 #define AXG_AO_GATE(_name, _bit)                                        \
20 static struct clk_regmap axg_aoclk_##_name = {                          \
21         .data = &(struct clk_regmap_gate_data) {                        \
22                 .offset = (AO_RTI_GEN_CNTL_REG0),                       \
23                 .bit_idx = (_bit),                                      \
24         },                                                              \
25         .hw.init = &(struct clk_init_data) {                            \
26                 .name =  "axg_ao_" #_name,                              \
27                 .ops = &clk_regmap_gate_ops,                            \
28                 .parent_names = (const char *[]){ "clk81" },            \
29                 .num_parents = 1,                                       \
30                 .flags = CLK_IGNORE_UNUSED,                             \
31         },                                                              \
32 }
33
34 AXG_AO_GATE(remote, 0);
35 AXG_AO_GATE(i2c_master, 1);
36 AXG_AO_GATE(i2c_slave, 2);
37 AXG_AO_GATE(uart1, 3);
38 AXG_AO_GATE(uart2, 5);
39 AXG_AO_GATE(ir_blaster, 6);
40 AXG_AO_GATE(saradc, 7);
41
42 static struct clk_regmap axg_aoclk_clk81 = {
43         .data = &(struct clk_regmap_mux_data) {
44                 .offset = AO_RTI_PWR_CNTL_REG0,
45                 .mask = 0x1,
46                 .shift = 8,
47         },
48         .hw.init = &(struct clk_init_data){
49                 .name = "axg_ao_clk81",
50                 .ops = &clk_regmap_mux_ro_ops,
51                 .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"},
52                 .num_parents = 2,
53         },
54 };
55
56 static struct clk_regmap axg_aoclk_saradc_mux = {
57         .data = &(struct clk_regmap_mux_data) {
58                 .offset = AO_SAR_CLK,
59                 .mask = 0x3,
60                 .shift = 9,
61         },
62         .hw.init = &(struct clk_init_data){
63                 .name = "axg_ao_saradc_mux",
64                 .ops = &clk_regmap_mux_ops,
65                 .parent_names = (const char *[]){ "xtal", "axg_ao_clk81" },
66                 .num_parents = 2,
67         },
68 };
69
70 static struct clk_regmap axg_aoclk_saradc_div = {
71         .data = &(struct clk_regmap_div_data) {
72                 .offset = AO_SAR_CLK,
73                 .shift = 0,
74                 .width = 8,
75         },
76         .hw.init = &(struct clk_init_data){
77                 .name = "axg_ao_saradc_div",
78                 .ops = &clk_regmap_divider_ops,
79                 .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
80                 .num_parents = 1,
81                 .flags = CLK_SET_RATE_PARENT,
82         },
83 };
84
85 static struct clk_regmap axg_aoclk_saradc_gate = {
86         .data = &(struct clk_regmap_gate_data) {
87                 .offset = AO_SAR_CLK,
88                 .bit_idx = 8,
89         },
90         .hw.init = &(struct clk_init_data){
91                 .name = "axg_ao_saradc_gate",
92                 .ops = &clk_regmap_gate_ops,
93                 .parent_names = (const char *[]){ "axg_ao_saradc_div" },
94                 .num_parents = 1,
95                 .flags = CLK_SET_RATE_PARENT,
96         },
97 };
98
99 static const unsigned int axg_aoclk_reset[] = {
100         [RESET_AO_REMOTE]       = 16,
101         [RESET_AO_I2C_MASTER]   = 18,
102         [RESET_AO_I2C_SLAVE]    = 19,
103         [RESET_AO_UART1]        = 17,
104         [RESET_AO_UART2]        = 22,
105         [RESET_AO_IR_BLASTER]   = 23,
106 };
107
108 static struct clk_regmap *axg_aoclk_regmap[] = {
109         [CLKID_AO_REMOTE]       = &axg_aoclk_remote,
110         [CLKID_AO_I2C_MASTER]   = &axg_aoclk_i2c_master,
111         [CLKID_AO_I2C_SLAVE]    = &axg_aoclk_i2c_slave,
112         [CLKID_AO_UART1]        = &axg_aoclk_uart1,
113         [CLKID_AO_UART2]        = &axg_aoclk_uart2,
114         [CLKID_AO_IR_BLASTER]   = &axg_aoclk_ir_blaster,
115         [CLKID_AO_SAR_ADC]      = &axg_aoclk_saradc,
116         [CLKID_AO_CLK81]        = &axg_aoclk_clk81,
117         [CLKID_AO_SAR_ADC_SEL]  = &axg_aoclk_saradc_mux,
118         [CLKID_AO_SAR_ADC_DIV]  = &axg_aoclk_saradc_div,
119         [CLKID_AO_SAR_ADC_CLK]  = &axg_aoclk_saradc_gate,
120 };
121
122 static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
123         .hws = {
124                 [CLKID_AO_REMOTE]       = &axg_aoclk_remote.hw,
125                 [CLKID_AO_I2C_MASTER]   = &axg_aoclk_i2c_master.hw,
126                 [CLKID_AO_I2C_SLAVE]    = &axg_aoclk_i2c_slave.hw,
127                 [CLKID_AO_UART1]        = &axg_aoclk_uart1.hw,
128                 [CLKID_AO_UART2]        = &axg_aoclk_uart2.hw,
129                 [CLKID_AO_IR_BLASTER]   = &axg_aoclk_ir_blaster.hw,
130                 [CLKID_AO_SAR_ADC]      = &axg_aoclk_saradc.hw,
131                 [CLKID_AO_CLK81]        = &axg_aoclk_clk81.hw,
132                 [CLKID_AO_SAR_ADC_SEL]  = &axg_aoclk_saradc_mux.hw,
133                 [CLKID_AO_SAR_ADC_DIV]  = &axg_aoclk_saradc_div.hw,
134                 [CLKID_AO_SAR_ADC_CLK]  = &axg_aoclk_saradc_gate.hw,
135         },
136         .num = NR_CLKS,
137 };
138
139 static const struct meson_aoclk_data axg_aoclkc_data = {
140         .reset_reg      = AO_RTI_GEN_CNTL_REG0,
141         .num_reset      = ARRAY_SIZE(axg_aoclk_reset),
142         .reset          = axg_aoclk_reset,
143         .num_clks       = ARRAY_SIZE(axg_aoclk_regmap),
144         .clks           = axg_aoclk_regmap,
145         .hw_data        = &axg_aoclk_onecell_data,
146 };
147
148 static const struct of_device_id axg_aoclkc_match_table[] = {
149         {
150                 .compatible     = "amlogic,meson-axg-aoclkc",
151                 .data           = &axg_aoclkc_data,
152         },
153         { }
154 };
155
156 static struct platform_driver axg_aoclkc_driver = {
157         .probe          = meson_aoclkc_probe,
158         .driver         = {
159                 .name   = "axg-aoclkc",
160                 .of_match_table = axg_aoclkc_match_table,
161         },
162 };
163
164 builtin_platform_driver(axg_aoclkc_driver);