blob: 29e088542387177360c211d9256d4641a8540395 [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001// 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) \
20static 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
34AXG_AO_GATE(remote, 0);
35AXG_AO_GATE(i2c_master, 1);
36AXG_AO_GATE(i2c_slave, 2);
37AXG_AO_GATE(uart1, 3);
38AXG_AO_GATE(uart2, 5);
39AXG_AO_GATE(ir_blaster, 6);
40AXG_AO_GATE(saradc, 7);
41
42static 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
56static 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
70static 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
85static 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
99static 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
108static 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
122static 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
139static 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
148static 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
156static 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
164builtin_platform_driver(axg_aoclkc_driver);