1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause 2 /* 3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 4 * Copyright (C) 2021 Microchip 5 */ 6 7 #include <io.h> 8 #include <kernel/delay.h> 9 #include <kernel/panic.h> 10 #include <mm/core_memprot.h> 11 #include <types_ext.h> 12 13 #include "at91_clk.h" 14 15 #define SLOW_CLOCK_FREQ 32768 16 #define MAINF_DIV 16 17 #define USEC_PER_SEC 1000000L 18 #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ) 19 20 #define OSC_READY_TIMEOUT_US 1000 21 22 #define MOR_KEY_MASK (0xFF << 16) 23 24 #define CLK_MAIN_PARENT_SELECT(s) (((s) & \ 25 (AT91_PMC_MOSCEN | \ 26 AT91_PMC_OSCBYPASS)) ? 1 : 0) 27 28 /* 29 * Main RC Oscillator 30 */ 31 32 struct main_rc_osc { 33 unsigned long freq; 34 vaddr_t base; 35 }; 36 37 static bool pmc_main_rc_osc_ready(struct main_rc_osc *osc) 38 { 39 uint32_t status = io_read32(osc->base + AT91_PMC_SR); 40 41 return status & AT91_PMC_MOSCRCS; 42 } 43 44 static TEE_Result pmc_main_rc_osc_enable(struct clk *clk) 45 { 46 struct main_rc_osc *osc = clk->priv; 47 uint32_t mor = io_read32(osc->base + AT91_CKGR_MOR); 48 49 /* Enable the oscillator if not */ 50 if (!(mor & AT91_PMC_MOSCRCEN)) { 51 io_clrsetbits32(osc->base + AT91_CKGR_MOR, 52 MOR_KEY_MASK | AT91_PMC_MOSCRCEN, 53 AT91_PMC_MOSCRCEN | AT91_PMC_KEY); 54 } 55 56 while (!pmc_main_rc_osc_ready(osc)) 57 ; 58 59 return TEE_SUCCESS; 60 } 61 62 static void pmc_main_rc_osc_disable(struct clk *clk) 63 { 64 struct main_rc_osc *osc = clk->priv; 65 uint32_t mor = io_read32(osc->base + AT91_CKGR_MOR); 66 67 if (!(mor & AT91_PMC_MOSCRCEN)) 68 return; 69 70 io_clrsetbits32(osc->base + AT91_CKGR_MOR, 71 MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY); 72 } 73 74 static unsigned long 75 pmc_main_rc_osc_get_rate(struct clk *clk, unsigned long parent_rate __unused) 76 { 77 struct main_rc_osc *osc = clk->priv; 78 79 return osc->freq; 80 } 81 82 static const struct clk_ops pmc_main_rc_osc_clk_ops = { 83 .enable = pmc_main_rc_osc_enable, 84 .disable = pmc_main_rc_osc_disable, 85 .get_rate = pmc_main_rc_osc_get_rate, 86 }; 87 88 struct clk *pmc_register_main_rc_osc(struct pmc_data *pmc, const char *name, 89 unsigned long freq) 90 { 91 struct clk *clk = NULL; 92 struct main_rc_osc *osc = NULL; 93 94 clk = clk_alloc(name, &pmc_main_rc_osc_clk_ops, NULL, 0); 95 if (!clk) 96 return NULL; 97 98 osc = calloc(1, sizeof(*osc)); 99 if (!osc) { 100 clk_free(clk); 101 return NULL; 102 } 103 104 osc->freq = freq; 105 osc->base = pmc->base; 106 107 clk->priv = osc; 108 109 if (clk_register(clk)) { 110 free(osc); 111 clk_free(clk); 112 return NULL; 113 } 114 115 return clk; 116 } 117 118 /* 119 * Main Oscillator 120 */ 121 static bool pmc_main_osc_ready(struct pmc_data *pmc) 122 { 123 uint32_t status = io_read32(pmc->base + AT91_PMC_SR); 124 125 return status & AT91_PMC_MOSCS; 126 } 127 128 static TEE_Result pmc_main_osc_enable(struct clk *clk) 129 { 130 struct pmc_data *pmc = clk->priv; 131 uint32_t mor = io_read32(pmc->base + AT91_CKGR_MOR); 132 133 mor &= ~MOR_KEY_MASK; 134 135 if (mor & AT91_PMC_OSCBYPASS) 136 return TEE_SUCCESS; 137 138 if (!(mor & AT91_PMC_MOSCEN)) { 139 mor |= AT91_PMC_MOSCEN | AT91_PMC_KEY; 140 io_write32(pmc->base + AT91_CKGR_MOR, mor); 141 } 142 143 while (!pmc_main_osc_ready(pmc)) 144 ; 145 146 return TEE_SUCCESS; 147 } 148 149 static void pmc_main_osc_disable(struct clk *clk) 150 { 151 struct pmc_data *pmc = clk->priv; 152 uint32_t mor = io_read32(pmc->base + AT91_CKGR_MOR); 153 154 if (mor & AT91_PMC_OSCBYPASS) 155 return; 156 157 if (!(mor & AT91_PMC_MOSCEN)) 158 return; 159 160 mor &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); 161 io_write32(pmc->base + AT91_CKGR_MOR, mor | AT91_PMC_KEY); 162 } 163 164 static const struct clk_ops pmc_main_osc_clk_ops = { 165 .enable = pmc_main_osc_enable, 166 .disable = pmc_main_osc_disable, 167 }; 168 169 struct clk *pmc_register_main_osc(struct pmc_data *pmc, const char *name, 170 struct clk *parent, bool bypass) 171 { 172 struct clk *clk = NULL; 173 174 clk = clk_alloc(name, &pmc_main_osc_clk_ops, &parent, 1); 175 if (!clk) 176 panic(); 177 178 clk->priv = pmc; 179 180 if (bypass) 181 io_clrsetbits32(pmc->base + AT91_CKGR_MOR, 182 MOR_KEY_MASK | AT91_PMC_OSCBYPASS, 183 AT91_PMC_OSCBYPASS | AT91_PMC_KEY); 184 185 if (clk_register(clk)) { 186 clk_free(clk); 187 return NULL; 188 } 189 190 return clk; 191 } 192 193 /* 194 * Main Clock 195 */ 196 static TEE_Result clk_main_probe_frequency(vaddr_t base) 197 { 198 while (!(io_read32(base + AT91_CKGR_MCFR) & AT91_PMC_MAINRDY)) 199 ; 200 201 return TEE_SUCCESS; 202 } 203 204 static unsigned long clk_main_get_rate(vaddr_t base, 205 unsigned long parent_rate) 206 { 207 uint32_t mcfr = 0; 208 209 if (parent_rate) 210 return parent_rate; 211 212 IMSG("Main crystal frequency not set, using approximate value"); 213 mcfr = io_read32(base + AT91_CKGR_MCFR); 214 if (!(mcfr & AT91_PMC_MAINRDY)) 215 return 0; 216 217 return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; 218 } 219 220 static bool clk_sam9x5_main_ready(vaddr_t base) 221 { 222 uint32_t status = io_read32(base + AT91_PMC_SR); 223 224 return status & AT91_PMC_MOSCSELS; 225 } 226 227 static TEE_Result clk_sam9x5_main_enable(struct clk *clk) 228 { 229 struct pmc_data *pmc = clk->priv; 230 231 while (!clk_sam9x5_main_ready(pmc->base)) 232 ; 233 234 return clk_main_probe_frequency(pmc->base); 235 } 236 237 static unsigned long clk_sam9x5_main_get_rate(struct clk *clk, 238 unsigned long parent_rate) 239 { 240 struct pmc_data *pmc = clk->priv; 241 242 return clk_main_get_rate(pmc->base, parent_rate); 243 } 244 245 static TEE_Result clk_sam9x5_main_set_parent(struct clk *clk, size_t index) 246 { 247 struct pmc_data *pmc = clk->priv; 248 uint32_t tmp = 0; 249 250 if (index > 1) 251 return TEE_ERROR_BAD_PARAMETERS; 252 253 tmp = io_read32(pmc->base + AT91_CKGR_MOR); 254 255 if (index && !(tmp & AT91_PMC_MOSCSEL)) 256 tmp = AT91_PMC_MOSCSEL; 257 else if (!index && (tmp & AT91_PMC_MOSCSEL)) 258 tmp = 0; 259 else 260 return TEE_SUCCESS; 261 262 io_clrsetbits32(pmc->base + AT91_CKGR_MOR, 263 AT91_PMC_MOSCSEL | MOR_KEY_MASK, 264 tmp | AT91_PMC_KEY); 265 266 while (!clk_sam9x5_main_ready(pmc->base)) 267 ; 268 269 return TEE_SUCCESS; 270 } 271 272 static size_t clk_sam9x5_main_get_parent(struct clk *clk) 273 { 274 struct pmc_data *pmc = clk->priv; 275 uint32_t status = io_read32(pmc->base + AT91_CKGR_MOR); 276 277 return CLK_MAIN_PARENT_SELECT(status); 278 } 279 280 static const struct clk_ops sam9x5_main_ops = { 281 .enable = clk_sam9x5_main_enable, 282 .get_rate = clk_sam9x5_main_get_rate, 283 .set_parent = clk_sam9x5_main_set_parent, 284 .get_parent = clk_sam9x5_main_get_parent, 285 }; 286 287 struct clk * 288 at91_clk_register_sam9x5_main(struct pmc_data *pmc, 289 const char *name, 290 struct clk **parent_clocks, 291 unsigned int num_parents) 292 { 293 struct clk *clk = NULL; 294 295 if (!name) 296 return NULL; 297 298 if (!parent_clocks || !num_parents) 299 return NULL; 300 301 clk = clk_alloc(name, &sam9x5_main_ops, parent_clocks, num_parents); 302 if (!clk) 303 return NULL; 304 305 clk->flags = CLK_SET_PARENT_GATE; 306 clk->priv = pmc; 307 308 if (clk_register(clk)) { 309 clk_free(clk); 310 return NULL; 311 } 312 313 return clk; 314 } 315