1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Amlogic Meson-AXG Clock Controller Driver 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (c) 2016 Baylibre SAS. 6*4882a593Smuzhiyun * Author: Michael Turquette <mturquette@baylibre.com> 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (c) 2019 Baylibre SAS. 9*4882a593Smuzhiyun * Author: Neil Armstrong <narmstrong@baylibre.com> 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun #include <linux/clk-provider.h> 12*4882a593Smuzhiyun #include <linux/platform_device.h> 13*4882a593Smuzhiyun #include <linux/reset-controller.h> 14*4882a593Smuzhiyun #include <linux/mfd/syscon.h> 15*4882a593Smuzhiyun #include <linux/module.h> 16*4882a593Smuzhiyun #include "meson-aoclk.h" 17*4882a593Smuzhiyun #include "g12a-aoclk.h" 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #include "clk-regmap.h" 20*4882a593Smuzhiyun #include "clk-dualdiv.h" 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /* 23*4882a593Smuzhiyun * AO Configuration Clock registers offsets 24*4882a593Smuzhiyun * Register offsets from the data sheet must be multiplied by 4. 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun #define AO_RTI_STATUS_REG3 0x0C 27*4882a593Smuzhiyun #define AO_RTI_PWR_CNTL_REG0 0x10 28*4882a593Smuzhiyun #define AO_RTI_GEN_CNTL_REG0 0x40 29*4882a593Smuzhiyun #define AO_CLK_GATE0 0x4c 30*4882a593Smuzhiyun #define AO_CLK_GATE0_SP 0x50 31*4882a593Smuzhiyun #define AO_OSCIN_CNTL 0x58 32*4882a593Smuzhiyun #define AO_CEC_CLK_CNTL_REG0 0x74 33*4882a593Smuzhiyun #define AO_CEC_CLK_CNTL_REG1 0x78 34*4882a593Smuzhiyun #define AO_SAR_CLK 0x90 35*4882a593Smuzhiyun #define AO_RTC_ALT_CLK_CNTL0 0x94 36*4882a593Smuzhiyun #define AO_RTC_ALT_CLK_CNTL1 0x98 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* 39*4882a593Smuzhiyun * Like every other peripheral clock gate in Amlogic Clock drivers, 40*4882a593Smuzhiyun * we are using CLK_IGNORE_UNUSED here, so we keep the state of the 41*4882a593Smuzhiyun * bootloader. The goal is to remove this flag at some point. 42*4882a593Smuzhiyun * Actually removing it will require some extensive test to be done safely. 43*4882a593Smuzhiyun */ 44*4882a593Smuzhiyun #define AXG_AO_GATE(_name, _reg, _bit) \ 45*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_##_name = { \ 46*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data) { \ 47*4882a593Smuzhiyun .offset = (_reg), \ 48*4882a593Smuzhiyun .bit_idx = (_bit), \ 49*4882a593Smuzhiyun }, \ 50*4882a593Smuzhiyun .hw.init = &(struct clk_init_data) { \ 51*4882a593Smuzhiyun .name = "g12a_ao_" #_name, \ 52*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, \ 53*4882a593Smuzhiyun .parent_data = &(const struct clk_parent_data) { \ 54*4882a593Smuzhiyun .fw_name = "mpeg-clk", \ 55*4882a593Smuzhiyun }, \ 56*4882a593Smuzhiyun .num_parents = 1, \ 57*4882a593Smuzhiyun .flags = CLK_IGNORE_UNUSED, \ 58*4882a593Smuzhiyun }, \ 59*4882a593Smuzhiyun } 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun AXG_AO_GATE(ahb, AO_CLK_GATE0, 0); 62*4882a593Smuzhiyun AXG_AO_GATE(ir_in, AO_CLK_GATE0, 1); 63*4882a593Smuzhiyun AXG_AO_GATE(i2c_m0, AO_CLK_GATE0, 2); 64*4882a593Smuzhiyun AXG_AO_GATE(i2c_s0, AO_CLK_GATE0, 3); 65*4882a593Smuzhiyun AXG_AO_GATE(uart, AO_CLK_GATE0, 4); 66*4882a593Smuzhiyun AXG_AO_GATE(prod_i2c, AO_CLK_GATE0, 5); 67*4882a593Smuzhiyun AXG_AO_GATE(uart2, AO_CLK_GATE0, 6); 68*4882a593Smuzhiyun AXG_AO_GATE(ir_out, AO_CLK_GATE0, 7); 69*4882a593Smuzhiyun AXG_AO_GATE(saradc, AO_CLK_GATE0, 8); 70*4882a593Smuzhiyun AXG_AO_GATE(mailbox, AO_CLK_GATE0_SP, 0); 71*4882a593Smuzhiyun AXG_AO_GATE(m3, AO_CLK_GATE0_SP, 1); 72*4882a593Smuzhiyun AXG_AO_GATE(ahb_sram, AO_CLK_GATE0_SP, 2); 73*4882a593Smuzhiyun AXG_AO_GATE(rti, AO_CLK_GATE0_SP, 3); 74*4882a593Smuzhiyun AXG_AO_GATE(m4_fclk, AO_CLK_GATE0_SP, 4); 75*4882a593Smuzhiyun AXG_AO_GATE(m4_hclk, AO_CLK_GATE0_SP, 5); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cts_oscin = { 78*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data){ 79*4882a593Smuzhiyun .offset = AO_RTI_PWR_CNTL_REG0, 80*4882a593Smuzhiyun .bit_idx = 14, 81*4882a593Smuzhiyun }, 82*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 83*4882a593Smuzhiyun .name = "cts_oscin", 84*4882a593Smuzhiyun .ops = &clk_regmap_gate_ro_ops, 85*4882a593Smuzhiyun .parent_data = &(const struct clk_parent_data) { 86*4882a593Smuzhiyun .fw_name = "xtal", 87*4882a593Smuzhiyun }, 88*4882a593Smuzhiyun .num_parents = 1, 89*4882a593Smuzhiyun }, 90*4882a593Smuzhiyun }; 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun static const struct meson_clk_dualdiv_param g12a_32k_div_table[] = { 93*4882a593Smuzhiyun { 94*4882a593Smuzhiyun .dual = 1, 95*4882a593Smuzhiyun .n1 = 733, 96*4882a593Smuzhiyun .m1 = 8, 97*4882a593Smuzhiyun .n2 = 732, 98*4882a593Smuzhiyun .m2 = 11, 99*4882a593Smuzhiyun }, {} 100*4882a593Smuzhiyun }; 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* 32k_by_oscin clock */ 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = { 105*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data){ 106*4882a593Smuzhiyun .offset = AO_RTC_ALT_CLK_CNTL0, 107*4882a593Smuzhiyun .bit_idx = 31, 108*4882a593Smuzhiyun }, 109*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 110*4882a593Smuzhiyun .name = "g12a_ao_32k_by_oscin_pre", 111*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, 112*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 113*4882a593Smuzhiyun &g12a_aoclk_cts_oscin.hw 114*4882a593Smuzhiyun }, 115*4882a593Smuzhiyun .num_parents = 1, 116*4882a593Smuzhiyun }, 117*4882a593Smuzhiyun }; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { 120*4882a593Smuzhiyun .data = &(struct meson_clk_dualdiv_data){ 121*4882a593Smuzhiyun .n1 = { 122*4882a593Smuzhiyun .reg_off = AO_RTC_ALT_CLK_CNTL0, 123*4882a593Smuzhiyun .shift = 0, 124*4882a593Smuzhiyun .width = 12, 125*4882a593Smuzhiyun }, 126*4882a593Smuzhiyun .n2 = { 127*4882a593Smuzhiyun .reg_off = AO_RTC_ALT_CLK_CNTL0, 128*4882a593Smuzhiyun .shift = 12, 129*4882a593Smuzhiyun .width = 12, 130*4882a593Smuzhiyun }, 131*4882a593Smuzhiyun .m1 = { 132*4882a593Smuzhiyun .reg_off = AO_RTC_ALT_CLK_CNTL1, 133*4882a593Smuzhiyun .shift = 0, 134*4882a593Smuzhiyun .width = 12, 135*4882a593Smuzhiyun }, 136*4882a593Smuzhiyun .m2 = { 137*4882a593Smuzhiyun .reg_off = AO_RTC_ALT_CLK_CNTL1, 138*4882a593Smuzhiyun .shift = 12, 139*4882a593Smuzhiyun .width = 12, 140*4882a593Smuzhiyun }, 141*4882a593Smuzhiyun .dual = { 142*4882a593Smuzhiyun .reg_off = AO_RTC_ALT_CLK_CNTL0, 143*4882a593Smuzhiyun .shift = 28, 144*4882a593Smuzhiyun .width = 1, 145*4882a593Smuzhiyun }, 146*4882a593Smuzhiyun .table = g12a_32k_div_table, 147*4882a593Smuzhiyun }, 148*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 149*4882a593Smuzhiyun .name = "g12a_ao_32k_by_oscin_div", 150*4882a593Smuzhiyun .ops = &meson_clk_dualdiv_ops, 151*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 152*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_pre.hw 153*4882a593Smuzhiyun }, 154*4882a593Smuzhiyun .num_parents = 1, 155*4882a593Smuzhiyun }, 156*4882a593Smuzhiyun }; 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { 159*4882a593Smuzhiyun .data = &(struct clk_regmap_mux_data) { 160*4882a593Smuzhiyun .offset = AO_RTC_ALT_CLK_CNTL1, 161*4882a593Smuzhiyun .mask = 0x1, 162*4882a593Smuzhiyun .shift = 24, 163*4882a593Smuzhiyun .flags = CLK_MUX_ROUND_CLOSEST, 164*4882a593Smuzhiyun }, 165*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 166*4882a593Smuzhiyun .name = "g12a_ao_32k_by_oscin_sel", 167*4882a593Smuzhiyun .ops = &clk_regmap_mux_ops, 168*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 169*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_div.hw, 170*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_pre.hw, 171*4882a593Smuzhiyun }, 172*4882a593Smuzhiyun .num_parents = 2, 173*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 174*4882a593Smuzhiyun }, 175*4882a593Smuzhiyun }; 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_32k_by_oscin = { 178*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data){ 179*4882a593Smuzhiyun .offset = AO_RTC_ALT_CLK_CNTL0, 180*4882a593Smuzhiyun .bit_idx = 30, 181*4882a593Smuzhiyun }, 182*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 183*4882a593Smuzhiyun .name = "g12a_ao_32k_by_oscin", 184*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, 185*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 186*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_sel.hw 187*4882a593Smuzhiyun }, 188*4882a593Smuzhiyun .num_parents = 1, 189*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 190*4882a593Smuzhiyun }, 191*4882a593Smuzhiyun }; 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun /* cec clock */ 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cec_pre = { 196*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data){ 197*4882a593Smuzhiyun .offset = AO_CEC_CLK_CNTL_REG0, 198*4882a593Smuzhiyun .bit_idx = 31, 199*4882a593Smuzhiyun }, 200*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 201*4882a593Smuzhiyun .name = "g12a_ao_cec_pre", 202*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, 203*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 204*4882a593Smuzhiyun &g12a_aoclk_cts_oscin.hw 205*4882a593Smuzhiyun }, 206*4882a593Smuzhiyun .num_parents = 1, 207*4882a593Smuzhiyun }, 208*4882a593Smuzhiyun }; 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cec_div = { 211*4882a593Smuzhiyun .data = &(struct meson_clk_dualdiv_data){ 212*4882a593Smuzhiyun .n1 = { 213*4882a593Smuzhiyun .reg_off = AO_CEC_CLK_CNTL_REG0, 214*4882a593Smuzhiyun .shift = 0, 215*4882a593Smuzhiyun .width = 12, 216*4882a593Smuzhiyun }, 217*4882a593Smuzhiyun .n2 = { 218*4882a593Smuzhiyun .reg_off = AO_CEC_CLK_CNTL_REG0, 219*4882a593Smuzhiyun .shift = 12, 220*4882a593Smuzhiyun .width = 12, 221*4882a593Smuzhiyun }, 222*4882a593Smuzhiyun .m1 = { 223*4882a593Smuzhiyun .reg_off = AO_CEC_CLK_CNTL_REG1, 224*4882a593Smuzhiyun .shift = 0, 225*4882a593Smuzhiyun .width = 12, 226*4882a593Smuzhiyun }, 227*4882a593Smuzhiyun .m2 = { 228*4882a593Smuzhiyun .reg_off = AO_CEC_CLK_CNTL_REG1, 229*4882a593Smuzhiyun .shift = 12, 230*4882a593Smuzhiyun .width = 12, 231*4882a593Smuzhiyun }, 232*4882a593Smuzhiyun .dual = { 233*4882a593Smuzhiyun .reg_off = AO_CEC_CLK_CNTL_REG0, 234*4882a593Smuzhiyun .shift = 28, 235*4882a593Smuzhiyun .width = 1, 236*4882a593Smuzhiyun }, 237*4882a593Smuzhiyun .table = g12a_32k_div_table, 238*4882a593Smuzhiyun }, 239*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 240*4882a593Smuzhiyun .name = "g12a_ao_cec_div", 241*4882a593Smuzhiyun .ops = &meson_clk_dualdiv_ops, 242*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 243*4882a593Smuzhiyun &g12a_aoclk_cec_pre.hw 244*4882a593Smuzhiyun }, 245*4882a593Smuzhiyun .num_parents = 1, 246*4882a593Smuzhiyun }, 247*4882a593Smuzhiyun }; 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cec_sel = { 250*4882a593Smuzhiyun .data = &(struct clk_regmap_mux_data) { 251*4882a593Smuzhiyun .offset = AO_CEC_CLK_CNTL_REG1, 252*4882a593Smuzhiyun .mask = 0x1, 253*4882a593Smuzhiyun .shift = 24, 254*4882a593Smuzhiyun .flags = CLK_MUX_ROUND_CLOSEST, 255*4882a593Smuzhiyun }, 256*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 257*4882a593Smuzhiyun .name = "g12a_ao_cec_sel", 258*4882a593Smuzhiyun .ops = &clk_regmap_mux_ops, 259*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 260*4882a593Smuzhiyun &g12a_aoclk_cec_div.hw, 261*4882a593Smuzhiyun &g12a_aoclk_cec_pre.hw, 262*4882a593Smuzhiyun }, 263*4882a593Smuzhiyun .num_parents = 2, 264*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 265*4882a593Smuzhiyun }, 266*4882a593Smuzhiyun }; 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cec = { 269*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data){ 270*4882a593Smuzhiyun .offset = AO_CEC_CLK_CNTL_REG0, 271*4882a593Smuzhiyun .bit_idx = 30, 272*4882a593Smuzhiyun }, 273*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 274*4882a593Smuzhiyun .name = "g12a_ao_cec", 275*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, 276*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 277*4882a593Smuzhiyun &g12a_aoclk_cec_sel.hw 278*4882a593Smuzhiyun }, 279*4882a593Smuzhiyun .num_parents = 1, 280*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 281*4882a593Smuzhiyun }, 282*4882a593Smuzhiyun }; 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { 285*4882a593Smuzhiyun .data = &(struct clk_regmap_mux_data) { 286*4882a593Smuzhiyun .offset = AO_RTI_PWR_CNTL_REG0, 287*4882a593Smuzhiyun .mask = 0x1, 288*4882a593Smuzhiyun .shift = 10, 289*4882a593Smuzhiyun .flags = CLK_MUX_ROUND_CLOSEST, 290*4882a593Smuzhiyun }, 291*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 292*4882a593Smuzhiyun .name = "g12a_ao_cts_rtc_oscin", 293*4882a593Smuzhiyun .ops = &clk_regmap_mux_ops, 294*4882a593Smuzhiyun .parent_data = (const struct clk_parent_data []) { 295*4882a593Smuzhiyun { .hw = &g12a_aoclk_32k_by_oscin.hw }, 296*4882a593Smuzhiyun { .fw_name = "ext-32k-0", }, 297*4882a593Smuzhiyun }, 298*4882a593Smuzhiyun .num_parents = 2, 299*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 300*4882a593Smuzhiyun }, 301*4882a593Smuzhiyun }; 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_clk81 = { 304*4882a593Smuzhiyun .data = &(struct clk_regmap_mux_data) { 305*4882a593Smuzhiyun .offset = AO_RTI_PWR_CNTL_REG0, 306*4882a593Smuzhiyun .mask = 0x1, 307*4882a593Smuzhiyun .shift = 8, 308*4882a593Smuzhiyun .flags = CLK_MUX_ROUND_CLOSEST, 309*4882a593Smuzhiyun }, 310*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 311*4882a593Smuzhiyun .name = "g12a_ao_clk81", 312*4882a593Smuzhiyun .ops = &clk_regmap_mux_ro_ops, 313*4882a593Smuzhiyun .parent_data = (const struct clk_parent_data []) { 314*4882a593Smuzhiyun { .fw_name = "mpeg-clk", }, 315*4882a593Smuzhiyun { .hw = &g12a_aoclk_cts_rtc_oscin.hw }, 316*4882a593Smuzhiyun }, 317*4882a593Smuzhiyun .num_parents = 2, 318*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 319*4882a593Smuzhiyun }, 320*4882a593Smuzhiyun }; 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_saradc_mux = { 323*4882a593Smuzhiyun .data = &(struct clk_regmap_mux_data) { 324*4882a593Smuzhiyun .offset = AO_SAR_CLK, 325*4882a593Smuzhiyun .mask = 0x3, 326*4882a593Smuzhiyun .shift = 9, 327*4882a593Smuzhiyun }, 328*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 329*4882a593Smuzhiyun .name = "g12a_ao_saradc_mux", 330*4882a593Smuzhiyun .ops = &clk_regmap_mux_ops, 331*4882a593Smuzhiyun .parent_data = (const struct clk_parent_data []) { 332*4882a593Smuzhiyun { .fw_name = "xtal", }, 333*4882a593Smuzhiyun { .hw = &g12a_aoclk_clk81.hw }, 334*4882a593Smuzhiyun }, 335*4882a593Smuzhiyun .num_parents = 2, 336*4882a593Smuzhiyun }, 337*4882a593Smuzhiyun }; 338*4882a593Smuzhiyun 339*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_saradc_div = { 340*4882a593Smuzhiyun .data = &(struct clk_regmap_div_data) { 341*4882a593Smuzhiyun .offset = AO_SAR_CLK, 342*4882a593Smuzhiyun .shift = 0, 343*4882a593Smuzhiyun .width = 8, 344*4882a593Smuzhiyun }, 345*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 346*4882a593Smuzhiyun .name = "g12a_ao_saradc_div", 347*4882a593Smuzhiyun .ops = &clk_regmap_divider_ops, 348*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 349*4882a593Smuzhiyun &g12a_aoclk_saradc_mux.hw 350*4882a593Smuzhiyun }, 351*4882a593Smuzhiyun .num_parents = 1, 352*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 353*4882a593Smuzhiyun }, 354*4882a593Smuzhiyun }; 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun static struct clk_regmap g12a_aoclk_saradc_gate = { 357*4882a593Smuzhiyun .data = &(struct clk_regmap_gate_data) { 358*4882a593Smuzhiyun .offset = AO_SAR_CLK, 359*4882a593Smuzhiyun .bit_idx = 8, 360*4882a593Smuzhiyun }, 361*4882a593Smuzhiyun .hw.init = &(struct clk_init_data){ 362*4882a593Smuzhiyun .name = "g12a_ao_saradc_gate", 363*4882a593Smuzhiyun .ops = &clk_regmap_gate_ops, 364*4882a593Smuzhiyun .parent_hws = (const struct clk_hw *[]) { 365*4882a593Smuzhiyun &g12a_aoclk_saradc_div.hw 366*4882a593Smuzhiyun }, 367*4882a593Smuzhiyun .num_parents = 1, 368*4882a593Smuzhiyun .flags = CLK_SET_RATE_PARENT, 369*4882a593Smuzhiyun }, 370*4882a593Smuzhiyun }; 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun static const unsigned int g12a_aoclk_reset[] = { 373*4882a593Smuzhiyun [RESET_AO_IR_IN] = 16, 374*4882a593Smuzhiyun [RESET_AO_UART] = 17, 375*4882a593Smuzhiyun [RESET_AO_I2C_M] = 18, 376*4882a593Smuzhiyun [RESET_AO_I2C_S] = 19, 377*4882a593Smuzhiyun [RESET_AO_SAR_ADC] = 20, 378*4882a593Smuzhiyun [RESET_AO_UART2] = 22, 379*4882a593Smuzhiyun [RESET_AO_IR_OUT] = 23, 380*4882a593Smuzhiyun }; 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun static struct clk_regmap *g12a_aoclk_regmap[] = { 383*4882a593Smuzhiyun &g12a_aoclk_ahb, 384*4882a593Smuzhiyun &g12a_aoclk_ir_in, 385*4882a593Smuzhiyun &g12a_aoclk_i2c_m0, 386*4882a593Smuzhiyun &g12a_aoclk_i2c_s0, 387*4882a593Smuzhiyun &g12a_aoclk_uart, 388*4882a593Smuzhiyun &g12a_aoclk_prod_i2c, 389*4882a593Smuzhiyun &g12a_aoclk_uart2, 390*4882a593Smuzhiyun &g12a_aoclk_ir_out, 391*4882a593Smuzhiyun &g12a_aoclk_saradc, 392*4882a593Smuzhiyun &g12a_aoclk_mailbox, 393*4882a593Smuzhiyun &g12a_aoclk_m3, 394*4882a593Smuzhiyun &g12a_aoclk_ahb_sram, 395*4882a593Smuzhiyun &g12a_aoclk_rti, 396*4882a593Smuzhiyun &g12a_aoclk_m4_fclk, 397*4882a593Smuzhiyun &g12a_aoclk_m4_hclk, 398*4882a593Smuzhiyun &g12a_aoclk_cts_oscin, 399*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_pre, 400*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_div, 401*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin_sel, 402*4882a593Smuzhiyun &g12a_aoclk_32k_by_oscin, 403*4882a593Smuzhiyun &g12a_aoclk_cec_pre, 404*4882a593Smuzhiyun &g12a_aoclk_cec_div, 405*4882a593Smuzhiyun &g12a_aoclk_cec_sel, 406*4882a593Smuzhiyun &g12a_aoclk_cec, 407*4882a593Smuzhiyun &g12a_aoclk_cts_rtc_oscin, 408*4882a593Smuzhiyun &g12a_aoclk_clk81, 409*4882a593Smuzhiyun &g12a_aoclk_saradc_mux, 410*4882a593Smuzhiyun &g12a_aoclk_saradc_div, 411*4882a593Smuzhiyun &g12a_aoclk_saradc_gate, 412*4882a593Smuzhiyun }; 413*4882a593Smuzhiyun 414*4882a593Smuzhiyun static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = { 415*4882a593Smuzhiyun .hws = { 416*4882a593Smuzhiyun [CLKID_AO_AHB] = &g12a_aoclk_ahb.hw, 417*4882a593Smuzhiyun [CLKID_AO_IR_IN] = &g12a_aoclk_ir_in.hw, 418*4882a593Smuzhiyun [CLKID_AO_I2C_M0] = &g12a_aoclk_i2c_m0.hw, 419*4882a593Smuzhiyun [CLKID_AO_I2C_S0] = &g12a_aoclk_i2c_s0.hw, 420*4882a593Smuzhiyun [CLKID_AO_UART] = &g12a_aoclk_uart.hw, 421*4882a593Smuzhiyun [CLKID_AO_PROD_I2C] = &g12a_aoclk_prod_i2c.hw, 422*4882a593Smuzhiyun [CLKID_AO_UART2] = &g12a_aoclk_uart2.hw, 423*4882a593Smuzhiyun [CLKID_AO_IR_OUT] = &g12a_aoclk_ir_out.hw, 424*4882a593Smuzhiyun [CLKID_AO_SAR_ADC] = &g12a_aoclk_saradc.hw, 425*4882a593Smuzhiyun [CLKID_AO_MAILBOX] = &g12a_aoclk_mailbox.hw, 426*4882a593Smuzhiyun [CLKID_AO_M3] = &g12a_aoclk_m3.hw, 427*4882a593Smuzhiyun [CLKID_AO_AHB_SRAM] = &g12a_aoclk_ahb_sram.hw, 428*4882a593Smuzhiyun [CLKID_AO_RTI] = &g12a_aoclk_rti.hw, 429*4882a593Smuzhiyun [CLKID_AO_M4_FCLK] = &g12a_aoclk_m4_fclk.hw, 430*4882a593Smuzhiyun [CLKID_AO_M4_HCLK] = &g12a_aoclk_m4_hclk.hw, 431*4882a593Smuzhiyun [CLKID_AO_CLK81] = &g12a_aoclk_clk81.hw, 432*4882a593Smuzhiyun [CLKID_AO_SAR_ADC_SEL] = &g12a_aoclk_saradc_mux.hw, 433*4882a593Smuzhiyun [CLKID_AO_SAR_ADC_DIV] = &g12a_aoclk_saradc_div.hw, 434*4882a593Smuzhiyun [CLKID_AO_SAR_ADC_CLK] = &g12a_aoclk_saradc_gate.hw, 435*4882a593Smuzhiyun [CLKID_AO_CTS_OSCIN] = &g12a_aoclk_cts_oscin.hw, 436*4882a593Smuzhiyun [CLKID_AO_32K_PRE] = &g12a_aoclk_32k_by_oscin_pre.hw, 437*4882a593Smuzhiyun [CLKID_AO_32K_DIV] = &g12a_aoclk_32k_by_oscin_div.hw, 438*4882a593Smuzhiyun [CLKID_AO_32K_SEL] = &g12a_aoclk_32k_by_oscin_sel.hw, 439*4882a593Smuzhiyun [CLKID_AO_32K] = &g12a_aoclk_32k_by_oscin.hw, 440*4882a593Smuzhiyun [CLKID_AO_CEC_PRE] = &g12a_aoclk_cec_pre.hw, 441*4882a593Smuzhiyun [CLKID_AO_CEC_DIV] = &g12a_aoclk_cec_div.hw, 442*4882a593Smuzhiyun [CLKID_AO_CEC_SEL] = &g12a_aoclk_cec_sel.hw, 443*4882a593Smuzhiyun [CLKID_AO_CEC] = &g12a_aoclk_cec.hw, 444*4882a593Smuzhiyun [CLKID_AO_CTS_RTC_OSCIN] = &g12a_aoclk_cts_rtc_oscin.hw, 445*4882a593Smuzhiyun }, 446*4882a593Smuzhiyun .num = NR_CLKS, 447*4882a593Smuzhiyun }; 448*4882a593Smuzhiyun 449*4882a593Smuzhiyun static const struct meson_aoclk_data g12a_aoclkc_data = { 450*4882a593Smuzhiyun .reset_reg = AO_RTI_GEN_CNTL_REG0, 451*4882a593Smuzhiyun .num_reset = ARRAY_SIZE(g12a_aoclk_reset), 452*4882a593Smuzhiyun .reset = g12a_aoclk_reset, 453*4882a593Smuzhiyun .num_clks = ARRAY_SIZE(g12a_aoclk_regmap), 454*4882a593Smuzhiyun .clks = g12a_aoclk_regmap, 455*4882a593Smuzhiyun .hw_data = &g12a_aoclk_onecell_data, 456*4882a593Smuzhiyun }; 457*4882a593Smuzhiyun 458*4882a593Smuzhiyun static const struct of_device_id g12a_aoclkc_match_table[] = { 459*4882a593Smuzhiyun { 460*4882a593Smuzhiyun .compatible = "amlogic,meson-g12a-aoclkc", 461*4882a593Smuzhiyun .data = &g12a_aoclkc_data, 462*4882a593Smuzhiyun }, 463*4882a593Smuzhiyun { } 464*4882a593Smuzhiyun }; 465*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, g12a_aoclkc_match_table); 466*4882a593Smuzhiyun 467*4882a593Smuzhiyun static struct platform_driver g12a_aoclkc_driver = { 468*4882a593Smuzhiyun .probe = meson_aoclkc_probe, 469*4882a593Smuzhiyun .driver = { 470*4882a593Smuzhiyun .name = "g12a-aoclkc", 471*4882a593Smuzhiyun .of_match_table = g12a_aoclkc_match_table, 472*4882a593Smuzhiyun }, 473*4882a593Smuzhiyun }; 474*4882a593Smuzhiyun 475*4882a593Smuzhiyun module_platform_driver(g12a_aoclkc_driver); 476*4882a593Smuzhiyun MODULE_LICENSE("GPL v2"); 477