github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/soc/sifive/fu540/clock.go (about) 1 // SiFive FU540 clock control 2 // https://github.com/usbarmory/tamago 3 // 4 // Copyright (c) WithSecure Corporation 5 // https://foundry.withsecure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 package fu540 11 12 import ( 13 "github.com/usbarmory/tamago/bits" 14 "github.com/usbarmory/tamago/internal/reg" 15 ) 16 17 // Clock registers 18 const ( 19 PRCI_BASE = 0x10000000 20 21 PRCI_COREPLLCFG = PRCI_BASE + 0x4 22 COREPLL_DIVR = 0 23 COREPLL_DIVF = 6 24 COREPLL_DIVQ = 15 25 26 PRCI_CORECLKSEL = PRCI_BASE + 0x24 27 ) 28 29 // Oscillator frequencies 30 const ( 31 // p43, 7.1 Clocking, FU540C00RM 32 RTCCLK = 1000000 33 COREPLL = 33330000 34 ) 35 36 func init() { 37 c := reg.Read(PRCI_COREPLLCFG) 38 39 // set COREPLL for 1 GHz operation 40 bits.Clear(&c, COREPLL_DIVR) 41 bits.SetN(&c, COREPLL_DIVF, 0x1ff, 59) 42 bits.SetN(&c, COREPLL_DIVQ, 0b111, 2) 43 44 reg.Write(PRCI_COREPLLCFG, c) 45 reg.Clear(PRCI_CORECLKSEL, 0) 46 } 47 48 // Freq returns the RISC-V core frequency. 49 func Freq() (hz uint32) { 50 if reg.Get(PRCI_CORECLKSEL, 0, 1) == 1 { 51 return COREPLL 52 } 53 54 // p47, 7.4.2 Setting coreclk frequency, FU540C00RM 55 56 c := reg.Read(PRCI_COREPLLCFG) 57 58 divr := bits.Get(&c, COREPLL_DIVR, 0x3f) 59 divf := bits.Get(&c, COREPLL_DIVF, 0x1ff) 60 divq := bits.Get(&c, COREPLL_DIVQ, 0b111) 61 62 return (COREPLL * 2 * (divf + 1)) / ((divr + 1) * 1 << divq) 63 }