18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Amlogic Meson-AXG Clock Controller Driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2016 Baylibre SAS.
68c2ecf20Sopenharmony_ci * Author: Michael Turquette <mturquette@baylibre.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Copyright (c) 2019 Baylibre SAS.
98c2ecf20Sopenharmony_ci * Author: Neil Armstrong <narmstrong@baylibre.com>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
128c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
138c2ecf20Sopenharmony_ci#include <linux/reset-controller.h>
148c2ecf20Sopenharmony_ci#include <linux/mfd/syscon.h>
158c2ecf20Sopenharmony_ci#include "meson-aoclk.h"
168c2ecf20Sopenharmony_ci#include "g12a-aoclk.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "clk-regmap.h"
198c2ecf20Sopenharmony_ci#include "clk-dualdiv.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * AO Configuration Clock registers offsets
238c2ecf20Sopenharmony_ci * Register offsets from the data sheet must be multiplied by 4.
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci#define AO_RTI_STATUS_REG3	0x0C
268c2ecf20Sopenharmony_ci#define AO_RTI_PWR_CNTL_REG0	0x10
278c2ecf20Sopenharmony_ci#define AO_RTI_GEN_CNTL_REG0	0x40
288c2ecf20Sopenharmony_ci#define AO_CLK_GATE0		0x4c
298c2ecf20Sopenharmony_ci#define AO_CLK_GATE0_SP		0x50
308c2ecf20Sopenharmony_ci#define AO_OSCIN_CNTL		0x58
318c2ecf20Sopenharmony_ci#define AO_CEC_CLK_CNTL_REG0	0x74
328c2ecf20Sopenharmony_ci#define AO_CEC_CLK_CNTL_REG1	0x78
338c2ecf20Sopenharmony_ci#define AO_SAR_CLK		0x90
348c2ecf20Sopenharmony_ci#define AO_RTC_ALT_CLK_CNTL0	0x94
358c2ecf20Sopenharmony_ci#define AO_RTC_ALT_CLK_CNTL1	0x98
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * Like every other peripheral clock gate in Amlogic Clock drivers,
398c2ecf20Sopenharmony_ci * we are using CLK_IGNORE_UNUSED here, so we keep the state of the
408c2ecf20Sopenharmony_ci * bootloader. The goal is to remove this flag at some point.
418c2ecf20Sopenharmony_ci * Actually removing it will require some extensive test to be done safely.
428c2ecf20Sopenharmony_ci */
438c2ecf20Sopenharmony_ci#define AXG_AO_GATE(_name, _reg, _bit)					\
448c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_##_name = {				\
458c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data) {			\
468c2ecf20Sopenharmony_ci		.offset = (_reg),					\
478c2ecf20Sopenharmony_ci		.bit_idx = (_bit),					\
488c2ecf20Sopenharmony_ci	},								\
498c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data) {				\
508c2ecf20Sopenharmony_ci		.name =  "g12a_ao_" #_name,				\
518c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,				\
528c2ecf20Sopenharmony_ci		.parent_data = &(const struct clk_parent_data) {	\
538c2ecf20Sopenharmony_ci			.fw_name = "mpeg-clk",				\
548c2ecf20Sopenharmony_ci		},							\
558c2ecf20Sopenharmony_ci		.num_parents = 1,					\
568c2ecf20Sopenharmony_ci		.flags = CLK_IGNORE_UNUSED,				\
578c2ecf20Sopenharmony_ci	},								\
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciAXG_AO_GATE(ahb, AO_CLK_GATE0, 0);
618c2ecf20Sopenharmony_ciAXG_AO_GATE(ir_in, AO_CLK_GATE0, 1);
628c2ecf20Sopenharmony_ciAXG_AO_GATE(i2c_m0, AO_CLK_GATE0, 2);
638c2ecf20Sopenharmony_ciAXG_AO_GATE(i2c_s0, AO_CLK_GATE0, 3);
648c2ecf20Sopenharmony_ciAXG_AO_GATE(uart, AO_CLK_GATE0, 4);
658c2ecf20Sopenharmony_ciAXG_AO_GATE(prod_i2c, AO_CLK_GATE0, 5);
668c2ecf20Sopenharmony_ciAXG_AO_GATE(uart2, AO_CLK_GATE0, 6);
678c2ecf20Sopenharmony_ciAXG_AO_GATE(ir_out, AO_CLK_GATE0, 7);
688c2ecf20Sopenharmony_ciAXG_AO_GATE(saradc, AO_CLK_GATE0, 8);
698c2ecf20Sopenharmony_ciAXG_AO_GATE(mailbox, AO_CLK_GATE0_SP, 0);
708c2ecf20Sopenharmony_ciAXG_AO_GATE(m3, AO_CLK_GATE0_SP, 1);
718c2ecf20Sopenharmony_ciAXG_AO_GATE(ahb_sram, AO_CLK_GATE0_SP, 2);
728c2ecf20Sopenharmony_ciAXG_AO_GATE(rti, AO_CLK_GATE0_SP, 3);
738c2ecf20Sopenharmony_ciAXG_AO_GATE(m4_fclk, AO_CLK_GATE0_SP, 4);
748c2ecf20Sopenharmony_ciAXG_AO_GATE(m4_hclk, AO_CLK_GATE0_SP, 5);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cts_oscin = {
778c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data){
788c2ecf20Sopenharmony_ci		.offset = AO_RTI_PWR_CNTL_REG0,
798c2ecf20Sopenharmony_ci		.bit_idx = 14,
808c2ecf20Sopenharmony_ci	},
818c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
828c2ecf20Sopenharmony_ci		.name = "cts_oscin",
838c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ro_ops,
848c2ecf20Sopenharmony_ci		.parent_data = &(const struct clk_parent_data) {
858c2ecf20Sopenharmony_ci			.fw_name = "xtal",
868c2ecf20Sopenharmony_ci		},
878c2ecf20Sopenharmony_ci		.num_parents = 1,
888c2ecf20Sopenharmony_ci	},
898c2ecf20Sopenharmony_ci};
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic const struct meson_clk_dualdiv_param g12a_32k_div_table[] = {
928c2ecf20Sopenharmony_ci	{
938c2ecf20Sopenharmony_ci		.dual	= 1,
948c2ecf20Sopenharmony_ci		.n1	= 733,
958c2ecf20Sopenharmony_ci		.m1	= 8,
968c2ecf20Sopenharmony_ci		.n2	= 732,
978c2ecf20Sopenharmony_ci		.m2	= 11,
988c2ecf20Sopenharmony_ci	}, {}
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci/* 32k_by_oscin clock */
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_32k_by_oscin_pre = {
1048c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data){
1058c2ecf20Sopenharmony_ci		.offset = AO_RTC_ALT_CLK_CNTL0,
1068c2ecf20Sopenharmony_ci		.bit_idx = 31,
1078c2ecf20Sopenharmony_ci	},
1088c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
1098c2ecf20Sopenharmony_ci		.name = "g12a_ao_32k_by_oscin_pre",
1108c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,
1118c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
1128c2ecf20Sopenharmony_ci			&g12a_aoclk_cts_oscin.hw
1138c2ecf20Sopenharmony_ci		},
1148c2ecf20Sopenharmony_ci		.num_parents = 1,
1158c2ecf20Sopenharmony_ci	},
1168c2ecf20Sopenharmony_ci};
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_32k_by_oscin_div = {
1198c2ecf20Sopenharmony_ci	.data = &(struct meson_clk_dualdiv_data){
1208c2ecf20Sopenharmony_ci		.n1 = {
1218c2ecf20Sopenharmony_ci			.reg_off = AO_RTC_ALT_CLK_CNTL0,
1228c2ecf20Sopenharmony_ci			.shift   = 0,
1238c2ecf20Sopenharmony_ci			.width   = 12,
1248c2ecf20Sopenharmony_ci		},
1258c2ecf20Sopenharmony_ci		.n2 = {
1268c2ecf20Sopenharmony_ci			.reg_off = AO_RTC_ALT_CLK_CNTL0,
1278c2ecf20Sopenharmony_ci			.shift   = 12,
1288c2ecf20Sopenharmony_ci			.width   = 12,
1298c2ecf20Sopenharmony_ci		},
1308c2ecf20Sopenharmony_ci		.m1 = {
1318c2ecf20Sopenharmony_ci			.reg_off = AO_RTC_ALT_CLK_CNTL1,
1328c2ecf20Sopenharmony_ci			.shift   = 0,
1338c2ecf20Sopenharmony_ci			.width   = 12,
1348c2ecf20Sopenharmony_ci		},
1358c2ecf20Sopenharmony_ci		.m2 = {
1368c2ecf20Sopenharmony_ci			.reg_off = AO_RTC_ALT_CLK_CNTL1,
1378c2ecf20Sopenharmony_ci			.shift   = 12,
1388c2ecf20Sopenharmony_ci			.width   = 12,
1398c2ecf20Sopenharmony_ci		},
1408c2ecf20Sopenharmony_ci		.dual = {
1418c2ecf20Sopenharmony_ci			.reg_off = AO_RTC_ALT_CLK_CNTL0,
1428c2ecf20Sopenharmony_ci			.shift   = 28,
1438c2ecf20Sopenharmony_ci			.width   = 1,
1448c2ecf20Sopenharmony_ci		},
1458c2ecf20Sopenharmony_ci		.table = g12a_32k_div_table,
1468c2ecf20Sopenharmony_ci	},
1478c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
1488c2ecf20Sopenharmony_ci		.name = "g12a_ao_32k_by_oscin_div",
1498c2ecf20Sopenharmony_ci		.ops = &meson_clk_dualdiv_ops,
1508c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
1518c2ecf20Sopenharmony_ci			&g12a_aoclk_32k_by_oscin_pre.hw
1528c2ecf20Sopenharmony_ci		},
1538c2ecf20Sopenharmony_ci		.num_parents = 1,
1548c2ecf20Sopenharmony_ci	},
1558c2ecf20Sopenharmony_ci};
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_32k_by_oscin_sel = {
1588c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_mux_data) {
1598c2ecf20Sopenharmony_ci		.offset = AO_RTC_ALT_CLK_CNTL1,
1608c2ecf20Sopenharmony_ci		.mask = 0x1,
1618c2ecf20Sopenharmony_ci		.shift = 24,
1628c2ecf20Sopenharmony_ci		.flags = CLK_MUX_ROUND_CLOSEST,
1638c2ecf20Sopenharmony_ci	},
1648c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
1658c2ecf20Sopenharmony_ci		.name = "g12a_ao_32k_by_oscin_sel",
1668c2ecf20Sopenharmony_ci		.ops = &clk_regmap_mux_ops,
1678c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
1688c2ecf20Sopenharmony_ci			&g12a_aoclk_32k_by_oscin_div.hw,
1698c2ecf20Sopenharmony_ci			&g12a_aoclk_32k_by_oscin_pre.hw,
1708c2ecf20Sopenharmony_ci		},
1718c2ecf20Sopenharmony_ci		.num_parents = 2,
1728c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
1738c2ecf20Sopenharmony_ci	},
1748c2ecf20Sopenharmony_ci};
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_32k_by_oscin = {
1778c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data){
1788c2ecf20Sopenharmony_ci		.offset = AO_RTC_ALT_CLK_CNTL0,
1798c2ecf20Sopenharmony_ci		.bit_idx = 30,
1808c2ecf20Sopenharmony_ci	},
1818c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
1828c2ecf20Sopenharmony_ci		.name = "g12a_ao_32k_by_oscin",
1838c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,
1848c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
1858c2ecf20Sopenharmony_ci			&g12a_aoclk_32k_by_oscin_sel.hw
1868c2ecf20Sopenharmony_ci		},
1878c2ecf20Sopenharmony_ci		.num_parents = 1,
1888c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
1898c2ecf20Sopenharmony_ci	},
1908c2ecf20Sopenharmony_ci};
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci/* cec clock */
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cec_pre = {
1958c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data){
1968c2ecf20Sopenharmony_ci		.offset = AO_CEC_CLK_CNTL_REG0,
1978c2ecf20Sopenharmony_ci		.bit_idx = 31,
1988c2ecf20Sopenharmony_ci	},
1998c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
2008c2ecf20Sopenharmony_ci		.name = "g12a_ao_cec_pre",
2018c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,
2028c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
2038c2ecf20Sopenharmony_ci			&g12a_aoclk_cts_oscin.hw
2048c2ecf20Sopenharmony_ci		},
2058c2ecf20Sopenharmony_ci		.num_parents = 1,
2068c2ecf20Sopenharmony_ci	},
2078c2ecf20Sopenharmony_ci};
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cec_div = {
2108c2ecf20Sopenharmony_ci	.data = &(struct meson_clk_dualdiv_data){
2118c2ecf20Sopenharmony_ci		.n1 = {
2128c2ecf20Sopenharmony_ci			.reg_off = AO_CEC_CLK_CNTL_REG0,
2138c2ecf20Sopenharmony_ci			.shift   = 0,
2148c2ecf20Sopenharmony_ci			.width   = 12,
2158c2ecf20Sopenharmony_ci		},
2168c2ecf20Sopenharmony_ci		.n2 = {
2178c2ecf20Sopenharmony_ci			.reg_off = AO_CEC_CLK_CNTL_REG0,
2188c2ecf20Sopenharmony_ci			.shift   = 12,
2198c2ecf20Sopenharmony_ci			.width   = 12,
2208c2ecf20Sopenharmony_ci		},
2218c2ecf20Sopenharmony_ci		.m1 = {
2228c2ecf20Sopenharmony_ci			.reg_off = AO_CEC_CLK_CNTL_REG1,
2238c2ecf20Sopenharmony_ci			.shift   = 0,
2248c2ecf20Sopenharmony_ci			.width   = 12,
2258c2ecf20Sopenharmony_ci		},
2268c2ecf20Sopenharmony_ci		.m2 = {
2278c2ecf20Sopenharmony_ci			.reg_off = AO_CEC_CLK_CNTL_REG1,
2288c2ecf20Sopenharmony_ci			.shift   = 12,
2298c2ecf20Sopenharmony_ci			.width   = 12,
2308c2ecf20Sopenharmony_ci		},
2318c2ecf20Sopenharmony_ci		.dual = {
2328c2ecf20Sopenharmony_ci			.reg_off = AO_CEC_CLK_CNTL_REG0,
2338c2ecf20Sopenharmony_ci			.shift   = 28,
2348c2ecf20Sopenharmony_ci			.width   = 1,
2358c2ecf20Sopenharmony_ci		},
2368c2ecf20Sopenharmony_ci		.table = g12a_32k_div_table,
2378c2ecf20Sopenharmony_ci	},
2388c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
2398c2ecf20Sopenharmony_ci		.name = "g12a_ao_cec_div",
2408c2ecf20Sopenharmony_ci		.ops = &meson_clk_dualdiv_ops,
2418c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
2428c2ecf20Sopenharmony_ci			&g12a_aoclk_cec_pre.hw
2438c2ecf20Sopenharmony_ci		},
2448c2ecf20Sopenharmony_ci		.num_parents = 1,
2458c2ecf20Sopenharmony_ci	},
2468c2ecf20Sopenharmony_ci};
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cec_sel = {
2498c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_mux_data) {
2508c2ecf20Sopenharmony_ci		.offset = AO_CEC_CLK_CNTL_REG1,
2518c2ecf20Sopenharmony_ci		.mask = 0x1,
2528c2ecf20Sopenharmony_ci		.shift = 24,
2538c2ecf20Sopenharmony_ci		.flags = CLK_MUX_ROUND_CLOSEST,
2548c2ecf20Sopenharmony_ci	},
2558c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
2568c2ecf20Sopenharmony_ci		.name = "g12a_ao_cec_sel",
2578c2ecf20Sopenharmony_ci		.ops = &clk_regmap_mux_ops,
2588c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
2598c2ecf20Sopenharmony_ci			&g12a_aoclk_cec_div.hw,
2608c2ecf20Sopenharmony_ci			&g12a_aoclk_cec_pre.hw,
2618c2ecf20Sopenharmony_ci		},
2628c2ecf20Sopenharmony_ci		.num_parents = 2,
2638c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
2648c2ecf20Sopenharmony_ci	},
2658c2ecf20Sopenharmony_ci};
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cec = {
2688c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data){
2698c2ecf20Sopenharmony_ci		.offset = AO_CEC_CLK_CNTL_REG0,
2708c2ecf20Sopenharmony_ci		.bit_idx = 30,
2718c2ecf20Sopenharmony_ci	},
2728c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
2738c2ecf20Sopenharmony_ci		.name = "g12a_ao_cec",
2748c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,
2758c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
2768c2ecf20Sopenharmony_ci			&g12a_aoclk_cec_sel.hw
2778c2ecf20Sopenharmony_ci		},
2788c2ecf20Sopenharmony_ci		.num_parents = 1,
2798c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
2808c2ecf20Sopenharmony_ci	},
2818c2ecf20Sopenharmony_ci};
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_cts_rtc_oscin = {
2848c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_mux_data) {
2858c2ecf20Sopenharmony_ci		.offset = AO_RTI_PWR_CNTL_REG0,
2868c2ecf20Sopenharmony_ci		.mask = 0x1,
2878c2ecf20Sopenharmony_ci		.shift = 10,
2888c2ecf20Sopenharmony_ci		.flags = CLK_MUX_ROUND_CLOSEST,
2898c2ecf20Sopenharmony_ci	},
2908c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
2918c2ecf20Sopenharmony_ci		.name = "g12a_ao_cts_rtc_oscin",
2928c2ecf20Sopenharmony_ci		.ops = &clk_regmap_mux_ops,
2938c2ecf20Sopenharmony_ci		.parent_data = (const struct clk_parent_data []) {
2948c2ecf20Sopenharmony_ci			{ .hw = &g12a_aoclk_32k_by_oscin.hw },
2958c2ecf20Sopenharmony_ci			{ .fw_name = "ext-32k-0", },
2968c2ecf20Sopenharmony_ci		},
2978c2ecf20Sopenharmony_ci		.num_parents = 2,
2988c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
2998c2ecf20Sopenharmony_ci	},
3008c2ecf20Sopenharmony_ci};
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_clk81 = {
3038c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_mux_data) {
3048c2ecf20Sopenharmony_ci		.offset = AO_RTI_PWR_CNTL_REG0,
3058c2ecf20Sopenharmony_ci		.mask = 0x1,
3068c2ecf20Sopenharmony_ci		.shift = 8,
3078c2ecf20Sopenharmony_ci		.flags = CLK_MUX_ROUND_CLOSEST,
3088c2ecf20Sopenharmony_ci	},
3098c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
3108c2ecf20Sopenharmony_ci		.name = "g12a_ao_clk81",
3118c2ecf20Sopenharmony_ci		.ops = &clk_regmap_mux_ro_ops,
3128c2ecf20Sopenharmony_ci		.parent_data = (const struct clk_parent_data []) {
3138c2ecf20Sopenharmony_ci			{ .fw_name = "mpeg-clk", },
3148c2ecf20Sopenharmony_ci			{ .hw = &g12a_aoclk_cts_rtc_oscin.hw },
3158c2ecf20Sopenharmony_ci		},
3168c2ecf20Sopenharmony_ci		.num_parents = 2,
3178c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
3188c2ecf20Sopenharmony_ci	},
3198c2ecf20Sopenharmony_ci};
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_saradc_mux = {
3228c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_mux_data) {
3238c2ecf20Sopenharmony_ci		.offset = AO_SAR_CLK,
3248c2ecf20Sopenharmony_ci		.mask = 0x3,
3258c2ecf20Sopenharmony_ci		.shift = 9,
3268c2ecf20Sopenharmony_ci	},
3278c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
3288c2ecf20Sopenharmony_ci		.name = "g12a_ao_saradc_mux",
3298c2ecf20Sopenharmony_ci		.ops = &clk_regmap_mux_ops,
3308c2ecf20Sopenharmony_ci		.parent_data = (const struct clk_parent_data []) {
3318c2ecf20Sopenharmony_ci			{ .fw_name = "xtal", },
3328c2ecf20Sopenharmony_ci			{ .hw = &g12a_aoclk_clk81.hw },
3338c2ecf20Sopenharmony_ci		},
3348c2ecf20Sopenharmony_ci		.num_parents = 2,
3358c2ecf20Sopenharmony_ci	},
3368c2ecf20Sopenharmony_ci};
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_saradc_div = {
3398c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_div_data) {
3408c2ecf20Sopenharmony_ci		.offset = AO_SAR_CLK,
3418c2ecf20Sopenharmony_ci		.shift = 0,
3428c2ecf20Sopenharmony_ci		.width = 8,
3438c2ecf20Sopenharmony_ci	},
3448c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
3458c2ecf20Sopenharmony_ci		.name = "g12a_ao_saradc_div",
3468c2ecf20Sopenharmony_ci		.ops = &clk_regmap_divider_ops,
3478c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
3488c2ecf20Sopenharmony_ci			&g12a_aoclk_saradc_mux.hw
3498c2ecf20Sopenharmony_ci		},
3508c2ecf20Sopenharmony_ci		.num_parents = 1,
3518c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
3528c2ecf20Sopenharmony_ci	},
3538c2ecf20Sopenharmony_ci};
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic struct clk_regmap g12a_aoclk_saradc_gate = {
3568c2ecf20Sopenharmony_ci	.data = &(struct clk_regmap_gate_data) {
3578c2ecf20Sopenharmony_ci		.offset = AO_SAR_CLK,
3588c2ecf20Sopenharmony_ci		.bit_idx = 8,
3598c2ecf20Sopenharmony_ci	},
3608c2ecf20Sopenharmony_ci	.hw.init = &(struct clk_init_data){
3618c2ecf20Sopenharmony_ci		.name = "g12a_ao_saradc_gate",
3628c2ecf20Sopenharmony_ci		.ops = &clk_regmap_gate_ops,
3638c2ecf20Sopenharmony_ci		.parent_hws = (const struct clk_hw *[]) {
3648c2ecf20Sopenharmony_ci			&g12a_aoclk_saradc_div.hw
3658c2ecf20Sopenharmony_ci		},
3668c2ecf20Sopenharmony_ci		.num_parents = 1,
3678c2ecf20Sopenharmony_ci		.flags = CLK_SET_RATE_PARENT,
3688c2ecf20Sopenharmony_ci	},
3698c2ecf20Sopenharmony_ci};
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic const unsigned int g12a_aoclk_reset[] = {
3728c2ecf20Sopenharmony_ci	[RESET_AO_IR_IN]	= 16,
3738c2ecf20Sopenharmony_ci	[RESET_AO_UART]		= 17,
3748c2ecf20Sopenharmony_ci	[RESET_AO_I2C_M]	= 18,
3758c2ecf20Sopenharmony_ci	[RESET_AO_I2C_S]	= 19,
3768c2ecf20Sopenharmony_ci	[RESET_AO_SAR_ADC]	= 20,
3778c2ecf20Sopenharmony_ci	[RESET_AO_UART2]	= 22,
3788c2ecf20Sopenharmony_ci	[RESET_AO_IR_OUT]	= 23,
3798c2ecf20Sopenharmony_ci};
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_cistatic struct clk_regmap *g12a_aoclk_regmap[] = {
3828c2ecf20Sopenharmony_ci	&g12a_aoclk_ahb,
3838c2ecf20Sopenharmony_ci	&g12a_aoclk_ir_in,
3848c2ecf20Sopenharmony_ci	&g12a_aoclk_i2c_m0,
3858c2ecf20Sopenharmony_ci	&g12a_aoclk_i2c_s0,
3868c2ecf20Sopenharmony_ci	&g12a_aoclk_uart,
3878c2ecf20Sopenharmony_ci	&g12a_aoclk_prod_i2c,
3888c2ecf20Sopenharmony_ci	&g12a_aoclk_uart2,
3898c2ecf20Sopenharmony_ci	&g12a_aoclk_ir_out,
3908c2ecf20Sopenharmony_ci	&g12a_aoclk_saradc,
3918c2ecf20Sopenharmony_ci	&g12a_aoclk_mailbox,
3928c2ecf20Sopenharmony_ci	&g12a_aoclk_m3,
3938c2ecf20Sopenharmony_ci	&g12a_aoclk_ahb_sram,
3948c2ecf20Sopenharmony_ci	&g12a_aoclk_rti,
3958c2ecf20Sopenharmony_ci	&g12a_aoclk_m4_fclk,
3968c2ecf20Sopenharmony_ci	&g12a_aoclk_m4_hclk,
3978c2ecf20Sopenharmony_ci	&g12a_aoclk_cts_oscin,
3988c2ecf20Sopenharmony_ci	&g12a_aoclk_32k_by_oscin_pre,
3998c2ecf20Sopenharmony_ci	&g12a_aoclk_32k_by_oscin_div,
4008c2ecf20Sopenharmony_ci	&g12a_aoclk_32k_by_oscin_sel,
4018c2ecf20Sopenharmony_ci	&g12a_aoclk_32k_by_oscin,
4028c2ecf20Sopenharmony_ci	&g12a_aoclk_cec_pre,
4038c2ecf20Sopenharmony_ci	&g12a_aoclk_cec_div,
4048c2ecf20Sopenharmony_ci	&g12a_aoclk_cec_sel,
4058c2ecf20Sopenharmony_ci	&g12a_aoclk_cec,
4068c2ecf20Sopenharmony_ci	&g12a_aoclk_cts_rtc_oscin,
4078c2ecf20Sopenharmony_ci	&g12a_aoclk_clk81,
4088c2ecf20Sopenharmony_ci	&g12a_aoclk_saradc_mux,
4098c2ecf20Sopenharmony_ci	&g12a_aoclk_saradc_div,
4108c2ecf20Sopenharmony_ci	&g12a_aoclk_saradc_gate,
4118c2ecf20Sopenharmony_ci};
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_cistatic const struct clk_hw_onecell_data g12a_aoclk_onecell_data = {
4148c2ecf20Sopenharmony_ci	.hws = {
4158c2ecf20Sopenharmony_ci		[CLKID_AO_AHB]		= &g12a_aoclk_ahb.hw,
4168c2ecf20Sopenharmony_ci		[CLKID_AO_IR_IN]	= &g12a_aoclk_ir_in.hw,
4178c2ecf20Sopenharmony_ci		[CLKID_AO_I2C_M0]	= &g12a_aoclk_i2c_m0.hw,
4188c2ecf20Sopenharmony_ci		[CLKID_AO_I2C_S0]	= &g12a_aoclk_i2c_s0.hw,
4198c2ecf20Sopenharmony_ci		[CLKID_AO_UART]		= &g12a_aoclk_uart.hw,
4208c2ecf20Sopenharmony_ci		[CLKID_AO_PROD_I2C]	= &g12a_aoclk_prod_i2c.hw,
4218c2ecf20Sopenharmony_ci		[CLKID_AO_UART2]	= &g12a_aoclk_uart2.hw,
4228c2ecf20Sopenharmony_ci		[CLKID_AO_IR_OUT]	= &g12a_aoclk_ir_out.hw,
4238c2ecf20Sopenharmony_ci		[CLKID_AO_SAR_ADC]	= &g12a_aoclk_saradc.hw,
4248c2ecf20Sopenharmony_ci		[CLKID_AO_MAILBOX]	= &g12a_aoclk_mailbox.hw,
4258c2ecf20Sopenharmony_ci		[CLKID_AO_M3]		= &g12a_aoclk_m3.hw,
4268c2ecf20Sopenharmony_ci		[CLKID_AO_AHB_SRAM]	= &g12a_aoclk_ahb_sram.hw,
4278c2ecf20Sopenharmony_ci		[CLKID_AO_RTI]		= &g12a_aoclk_rti.hw,
4288c2ecf20Sopenharmony_ci		[CLKID_AO_M4_FCLK]	= &g12a_aoclk_m4_fclk.hw,
4298c2ecf20Sopenharmony_ci		[CLKID_AO_M4_HCLK]	= &g12a_aoclk_m4_hclk.hw,
4308c2ecf20Sopenharmony_ci		[CLKID_AO_CLK81]	= &g12a_aoclk_clk81.hw,
4318c2ecf20Sopenharmony_ci		[CLKID_AO_SAR_ADC_SEL]	= &g12a_aoclk_saradc_mux.hw,
4328c2ecf20Sopenharmony_ci		[CLKID_AO_SAR_ADC_DIV]	= &g12a_aoclk_saradc_div.hw,
4338c2ecf20Sopenharmony_ci		[CLKID_AO_SAR_ADC_CLK]	= &g12a_aoclk_saradc_gate.hw,
4348c2ecf20Sopenharmony_ci		[CLKID_AO_CTS_OSCIN]	= &g12a_aoclk_cts_oscin.hw,
4358c2ecf20Sopenharmony_ci		[CLKID_AO_32K_PRE]	= &g12a_aoclk_32k_by_oscin_pre.hw,
4368c2ecf20Sopenharmony_ci		[CLKID_AO_32K_DIV]	= &g12a_aoclk_32k_by_oscin_div.hw,
4378c2ecf20Sopenharmony_ci		[CLKID_AO_32K_SEL]	= &g12a_aoclk_32k_by_oscin_sel.hw,
4388c2ecf20Sopenharmony_ci		[CLKID_AO_32K]		= &g12a_aoclk_32k_by_oscin.hw,
4398c2ecf20Sopenharmony_ci		[CLKID_AO_CEC_PRE]	= &g12a_aoclk_cec_pre.hw,
4408c2ecf20Sopenharmony_ci		[CLKID_AO_CEC_DIV]	= &g12a_aoclk_cec_div.hw,
4418c2ecf20Sopenharmony_ci		[CLKID_AO_CEC_SEL]	= &g12a_aoclk_cec_sel.hw,
4428c2ecf20Sopenharmony_ci		[CLKID_AO_CEC]		= &g12a_aoclk_cec.hw,
4438c2ecf20Sopenharmony_ci		[CLKID_AO_CTS_RTC_OSCIN] = &g12a_aoclk_cts_rtc_oscin.hw,
4448c2ecf20Sopenharmony_ci	},
4458c2ecf20Sopenharmony_ci	.num = NR_CLKS,
4468c2ecf20Sopenharmony_ci};
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_cistatic const struct meson_aoclk_data g12a_aoclkc_data = {
4498c2ecf20Sopenharmony_ci	.reset_reg	= AO_RTI_GEN_CNTL_REG0,
4508c2ecf20Sopenharmony_ci	.num_reset	= ARRAY_SIZE(g12a_aoclk_reset),
4518c2ecf20Sopenharmony_ci	.reset		= g12a_aoclk_reset,
4528c2ecf20Sopenharmony_ci	.num_clks	= ARRAY_SIZE(g12a_aoclk_regmap),
4538c2ecf20Sopenharmony_ci	.clks		= g12a_aoclk_regmap,
4548c2ecf20Sopenharmony_ci	.hw_data	= &g12a_aoclk_onecell_data,
4558c2ecf20Sopenharmony_ci};
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_cistatic const struct of_device_id g12a_aoclkc_match_table[] = {
4588c2ecf20Sopenharmony_ci	{
4598c2ecf20Sopenharmony_ci		.compatible	= "amlogic,meson-g12a-aoclkc",
4608c2ecf20Sopenharmony_ci		.data		= &g12a_aoclkc_data,
4618c2ecf20Sopenharmony_ci	},
4628c2ecf20Sopenharmony_ci	{ }
4638c2ecf20Sopenharmony_ci};
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_cistatic struct platform_driver g12a_aoclkc_driver = {
4668c2ecf20Sopenharmony_ci	.probe		= meson_aoclkc_probe,
4678c2ecf20Sopenharmony_ci	.driver		= {
4688c2ecf20Sopenharmony_ci		.name	= "g12a-aoclkc",
4698c2ecf20Sopenharmony_ci		.of_match_table = g12a_aoclkc_match_table,
4708c2ecf20Sopenharmony_ci	},
4718c2ecf20Sopenharmony_ci};
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_cibuiltin_platform_driver(g12a_aoclkc_driver);
474