1/* 2 * Copyright (C) 2014 Broadcom Corporation 3 * Copyright 2014 Linaro Limited 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation version 2. 8 * 9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 10 * kind, whether express or implied; without even the implied warranty 11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15#include "clk-kona.h" 16#include "dt-bindings/clock/bcm21664.h" 17 18#define BCM21664_CCU_COMMON(_name, _capname) \ 19 KONA_CCU_COMMON(BCM21664, _name, _capname) 20 21/* Root CCU */ 22 23static struct peri_clk_data frac_1m_data = { 24 .gate = HW_SW_GATE(0x214, 16, 0, 1), 25 .clocks = CLOCKS("ref_crystal"), 26}; 27 28static struct ccu_data root_ccu_data = { 29 BCM21664_CCU_COMMON(root, ROOT), 30 /* no policy control */ 31 .kona_clks = { 32 [BCM21664_ROOT_CCU_FRAC_1M] = 33 KONA_CLK(root, frac_1m, peri), 34 [BCM21664_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 35 }, 36}; 37 38/* AON CCU */ 39 40static struct peri_clk_data hub_timer_data = { 41 .gate = HW_SW_GATE(0x0414, 16, 0, 1), 42 .hyst = HYST(0x0414, 8, 9), 43 .clocks = CLOCKS("bbl_32k", 44 "frac_1m", 45 "dft_19_5m"), 46 .sel = SELECTOR(0x0a10, 0, 2), 47 .trig = TRIGGER(0x0a40, 4), 48}; 49 50static struct ccu_data aon_ccu_data = { 51 BCM21664_CCU_COMMON(aon, AON), 52 .policy = { 53 .enable = CCU_LVM_EN(0x0034, 0), 54 .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 55 }, 56 .kona_clks = { 57 [BCM21664_AON_CCU_HUB_TIMER] = 58 KONA_CLK(aon, hub_timer, peri), 59 [BCM21664_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 60 }, 61}; 62 63/* Master CCU */ 64 65static struct peri_clk_data sdio1_data = { 66 .gate = HW_SW_GATE(0x0358, 18, 2, 3), 67 .clocks = CLOCKS("ref_crystal", 68 "var_52m", 69 "ref_52m", 70 "var_96m", 71 "ref_96m"), 72 .sel = SELECTOR(0x0a28, 0, 3), 73 .div = DIVIDER(0x0a28, 4, 14), 74 .trig = TRIGGER(0x0afc, 9), 75}; 76 77static struct peri_clk_data sdio2_data = { 78 .gate = HW_SW_GATE(0x035c, 18, 2, 3), 79 .clocks = CLOCKS("ref_crystal", 80 "var_52m", 81 "ref_52m", 82 "var_96m", 83 "ref_96m"), 84 .sel = SELECTOR(0x0a2c, 0, 3), 85 .div = DIVIDER(0x0a2c, 4, 14), 86 .trig = TRIGGER(0x0afc, 10), 87}; 88 89static struct peri_clk_data sdio3_data = { 90 .gate = HW_SW_GATE(0x0364, 18, 2, 3), 91 .clocks = CLOCKS("ref_crystal", 92 "var_52m", 93 "ref_52m", 94 "var_96m", 95 "ref_96m"), 96 .sel = SELECTOR(0x0a34, 0, 3), 97 .div = DIVIDER(0x0a34, 4, 14), 98 .trig = TRIGGER(0x0afc, 12), 99}; 100 101static struct peri_clk_data sdio4_data = { 102 .gate = HW_SW_GATE(0x0360, 18, 2, 3), 103 .clocks = CLOCKS("ref_crystal", 104 "var_52m", 105 "ref_52m", 106 "var_96m", 107 "ref_96m"), 108 .sel = SELECTOR(0x0a30, 0, 3), 109 .div = DIVIDER(0x0a30, 4, 14), 110 .trig = TRIGGER(0x0afc, 11), 111}; 112 113static struct peri_clk_data sdio1_sleep_data = { 114 .clocks = CLOCKS("ref_32k"), /* Verify */ 115 .gate = HW_SW_GATE(0x0358, 18, 2, 3), 116}; 117 118static struct peri_clk_data sdio2_sleep_data = { 119 .clocks = CLOCKS("ref_32k"), /* Verify */ 120 .gate = HW_SW_GATE(0x035c, 18, 2, 3), 121}; 122 123static struct peri_clk_data sdio3_sleep_data = { 124 .clocks = CLOCKS("ref_32k"), /* Verify */ 125 .gate = HW_SW_GATE(0x0364, 18, 2, 3), 126}; 127 128static struct peri_clk_data sdio4_sleep_data = { 129 .clocks = CLOCKS("ref_32k"), /* Verify */ 130 .gate = HW_SW_GATE(0x0360, 18, 2, 3), 131}; 132 133static struct ccu_data master_ccu_data = { 134 BCM21664_CCU_COMMON(master, MASTER), 135 .policy = { 136 .enable = CCU_LVM_EN(0x0034, 0), 137 .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 138 }, 139 .kona_clks = { 140 [BCM21664_MASTER_CCU_SDIO1] = 141 KONA_CLK(master, sdio1, peri), 142 [BCM21664_MASTER_CCU_SDIO2] = 143 KONA_CLK(master, sdio2, peri), 144 [BCM21664_MASTER_CCU_SDIO3] = 145 KONA_CLK(master, sdio3, peri), 146 [BCM21664_MASTER_CCU_SDIO4] = 147 KONA_CLK(master, sdio4, peri), 148 [BCM21664_MASTER_CCU_SDIO1_SLEEP] = 149 KONA_CLK(master, sdio1_sleep, peri), 150 [BCM21664_MASTER_CCU_SDIO2_SLEEP] = 151 KONA_CLK(master, sdio2_sleep, peri), 152 [BCM21664_MASTER_CCU_SDIO3_SLEEP] = 153 KONA_CLK(master, sdio3_sleep, peri), 154 [BCM21664_MASTER_CCU_SDIO4_SLEEP] = 155 KONA_CLK(master, sdio4_sleep, peri), 156 [BCM21664_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 157 }, 158}; 159 160/* Slave CCU */ 161 162static struct peri_clk_data uartb_data = { 163 .gate = HW_SW_GATE(0x0400, 18, 2, 3), 164 .clocks = CLOCKS("ref_crystal", 165 "var_156m", 166 "ref_156m"), 167 .sel = SELECTOR(0x0a10, 0, 2), 168 .div = FRAC_DIVIDER(0x0a10, 4, 12, 8), 169 .trig = TRIGGER(0x0afc, 2), 170}; 171 172static struct peri_clk_data uartb2_data = { 173 .gate = HW_SW_GATE(0x0404, 18, 2, 3), 174 .clocks = CLOCKS("ref_crystal", 175 "var_156m", 176 "ref_156m"), 177 .sel = SELECTOR(0x0a14, 0, 2), 178 .div = FRAC_DIVIDER(0x0a14, 4, 12, 8), 179 .trig = TRIGGER(0x0afc, 3), 180}; 181 182static struct peri_clk_data uartb3_data = { 183 .gate = HW_SW_GATE(0x0408, 18, 2, 3), 184 .clocks = CLOCKS("ref_crystal", 185 "var_156m", 186 "ref_156m"), 187 .sel = SELECTOR(0x0a18, 0, 2), 188 .div = FRAC_DIVIDER(0x0a18, 4, 12, 8), 189 .trig = TRIGGER(0x0afc, 4), 190}; 191 192static struct peri_clk_data bsc1_data = { 193 .gate = HW_SW_GATE(0x0458, 18, 2, 3), 194 .clocks = CLOCKS("ref_crystal", 195 "var_104m", 196 "ref_104m", 197 "var_13m", 198 "ref_13m"), 199 .sel = SELECTOR(0x0a64, 0, 3), 200 .trig = TRIGGER(0x0afc, 23), 201}; 202 203static struct peri_clk_data bsc2_data = { 204 .gate = HW_SW_GATE(0x045c, 18, 2, 3), 205 .clocks = CLOCKS("ref_crystal", 206 "var_104m", 207 "ref_104m", 208 "var_13m", 209 "ref_13m"), 210 .sel = SELECTOR(0x0a68, 0, 3), 211 .trig = TRIGGER(0x0afc, 24), 212}; 213 214static struct peri_clk_data bsc3_data = { 215 .gate = HW_SW_GATE(0x0470, 18, 2, 3), 216 .clocks = CLOCKS("ref_crystal", 217 "var_104m", 218 "ref_104m", 219 "var_13m", 220 "ref_13m"), 221 .sel = SELECTOR(0x0a7c, 0, 3), 222 .trig = TRIGGER(0x0afc, 18), 223}; 224 225static struct peri_clk_data bsc4_data = { 226 .gate = HW_SW_GATE(0x0474, 18, 2, 3), 227 .clocks = CLOCKS("ref_crystal", 228 "var_104m", 229 "ref_104m", 230 "var_13m", 231 "ref_13m"), 232 .sel = SELECTOR(0x0a80, 0, 3), 233 .trig = TRIGGER(0x0afc, 19), 234}; 235 236static struct ccu_data slave_ccu_data = { 237 BCM21664_CCU_COMMON(slave, SLAVE), 238 .policy = { 239 .enable = CCU_LVM_EN(0x0034, 0), 240 .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), 241 }, 242 .kona_clks = { 243 [BCM21664_SLAVE_CCU_UARTB] = 244 KONA_CLK(slave, uartb, peri), 245 [BCM21664_SLAVE_CCU_UARTB2] = 246 KONA_CLK(slave, uartb2, peri), 247 [BCM21664_SLAVE_CCU_UARTB3] = 248 KONA_CLK(slave, uartb3, peri), 249 [BCM21664_SLAVE_CCU_BSC1] = 250 KONA_CLK(slave, bsc1, peri), 251 [BCM21664_SLAVE_CCU_BSC2] = 252 KONA_CLK(slave, bsc2, peri), 253 [BCM21664_SLAVE_CCU_BSC3] = 254 KONA_CLK(slave, bsc3, peri), 255 [BCM21664_SLAVE_CCU_BSC4] = 256 KONA_CLK(slave, bsc4, peri), 257 [BCM21664_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, 258 }, 259}; 260 261/* Device tree match table callback functions */ 262 263static void __init kona_dt_root_ccu_setup(struct device_node *node) 264{ 265 kona_dt_ccu_setup(&root_ccu_data, node); 266} 267 268static void __init kona_dt_aon_ccu_setup(struct device_node *node) 269{ 270 kona_dt_ccu_setup(&aon_ccu_data, node); 271} 272 273static void __init kona_dt_master_ccu_setup(struct device_node *node) 274{ 275 kona_dt_ccu_setup(&master_ccu_data, node); 276} 277 278static void __init kona_dt_slave_ccu_setup(struct device_node *node) 279{ 280 kona_dt_ccu_setup(&slave_ccu_data, node); 281} 282 283CLK_OF_DECLARE(bcm21664_root_ccu, BCM21664_DT_ROOT_CCU_COMPAT, 284 kona_dt_root_ccu_setup); 285CLK_OF_DECLARE(bcm21664_aon_ccu, BCM21664_DT_AON_CCU_COMPAT, 286 kona_dt_aon_ccu_setup); 287CLK_OF_DECLARE(bcm21664_master_ccu, BCM21664_DT_MASTER_CCU_COMPAT, 288 kona_dt_master_ccu_setup); 289CLK_OF_DECLARE(bcm21664_slave_ccu, BCM21664_DT_SLAVE_CCU_COMPAT, 290 kona_dt_slave_ccu_setup); 291