Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

stm32h7: refactor clock init to target-specific callback

Given the myriad of clocking options the STM32H7 family
provides, it is easiest to let targets simply implement
what they need.

Change-Id: I9cceed40a2d638998e8b583651f73557d2ffbd46

authored by

Aidan MacDonald and committed by
Solomon Peachy
23448a13 37b90baa

+180 -121
+1
firmware/SOURCES
··· 2034 2034 target/arm/stm32/echoplayer/audiohw-echoplayer.c 2035 2035 target/arm/stm32/echoplayer/backlight-echoplayer.c 2036 2036 target/arm/stm32/echoplayer/button-echoplayer.c 2037 + target/arm/stm32/echoplayer/clock-echoplayer.c 2037 2038 target/arm/stm32/echoplayer/lcd-echoplayer.c 2038 2039 target/arm/stm32/echoplayer/power-echoplayer.c 2039 2040 target/arm/stm32/echoplayer/system-echoplayer.c
+33
firmware/target/arm/stm32/clock-stm32h7.h
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2025 Aidan MacDonald 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + #ifndef __CLOCK_STM32H7_H__ 22 + #define __CLOCK_STM32H7_H__ 23 + 24 + #include "system.h" 25 + 26 + /* 27 + * Implemented by the target to initialize all oscillators, 28 + * system, CPU, and bus clocks that need to be enabled from 29 + * early boot. 30 + */ 31 + void stm_target_clock_init(void) INIT_ATTR; 32 + 33 + #endif /* __CLOCK_STM32H7_H__ */
+143
firmware/target/arm/stm32/echoplayer/clock-echoplayer.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2025 Aidan MacDonald 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + #include "clock-stm32h7.h" 22 + #include "panic.h" 23 + #include "regs/stm32h743/flash.h" 24 + #include "regs/stm32h743/fmc.h" 25 + #include "regs/stm32h743/pwr.h" 26 + #include "regs/stm32h743/rcc.h" 27 + #include "regs/stm32h743/syscfg.h" 28 + 29 + /* Flag to use VOS0 */ 30 + #define STM32H743_USE_VOS0 (CPU_FREQ > 400000000) 31 + 32 + static void init_hse(void) 33 + { 34 + reg_writef(RCC_CR, HSEON(1)); 35 + 36 + while (!reg_readf(RCC_CR, HSERDY)); 37 + } 38 + 39 + static void init_pll(void) 40 + { 41 + /* Select HSE/4 input for PLL1 (6 MHz) */ 42 + reg_writef(RCC_PLLCKSELR, 43 + PLLSRC_V(HSE), 44 + DIVM1(4), 45 + DIVM2(0), 46 + DIVM3(0)); 47 + 48 + /* Enable PLL1P and PLL1Q */ 49 + reg_writef(RCC_PLLCFGR, 50 + DIVP1EN(1), 51 + DIVQ1EN(1), 52 + DIVR1EN(0), 53 + DIVP2EN(0), 54 + DIVQ2EN(0), 55 + DIVR2EN(0), 56 + DIVP3EN(0), 57 + DIVQ3EN(0), 58 + DIVR3EN(0), 59 + PLL1RGE_V(4_8MHZ), 60 + PLL1VCOSEL_V(WIDE)); 61 + 62 + reg_writef(RCC_PLL1DIVR, 63 + DIVN(80 - 1), /* 6 * 80 = 480 MHz */ 64 + DIVP(1 - 1), /* 480 / 1 = 480 MHz */ 65 + DIVQ(8 - 1), /* 480 / 8 = 60 MHz */ 66 + DIVR(1 - 1)); 67 + 68 + reg_writef(RCC_CR, PLL1ON(1)); 69 + while (!reg_readf(RCC_CR, PLL1RDY)); 70 + } 71 + 72 + static void init_vos(void) 73 + { 74 + reg_writef(PWR_D3CR, VOS_V(VOS1)); 75 + while (!reg_readf(PWR_D3CR, VOSRDY)); 76 + 77 + if (STM32H743_USE_VOS0) 78 + { 79 + reg_writef(RCC_APB4ENR, SYSCFGEN(1)); 80 + 81 + /* Set ODEN bit to enter VOS0 */ 82 + reg_writef(SYSCFG_PWRCFG, ODEN(1)); 83 + while (!reg_readf(PWR_D3CR, VOSRDY)); 84 + 85 + reg_writef(RCC_APB4ENR, SYSCFGEN(0)); 86 + } 87 + } 88 + 89 + static void init_system_clock(void) 90 + { 91 + /* Enable HCLK /2 divider (CPU is at 480 MHz, HCLK limit is 240 MHz) */ 92 + reg_writef(RCC_D1CFGR, HPRE(8)); 93 + while (reg_readf(RCC_D1CFGR, HPRE) != 8); 94 + 95 + /* Enable ABP /2 dividers (HCLK/2, APB limit is 120 MHz) */ 96 + reg_writef(RCC_D1CFGR, D1PPRE(4)); 97 + reg_writef(RCC_D2CFGR, D2PPRE1(4), D2PPRE2(4)); 98 + reg_writef(RCC_D3CFGR, D3PPRE(4)); 99 + 100 + /* Switch to PLL1P system clock source */ 101 + reg_writef(RCC_CFGR, SW_V(PLL1P)); 102 + while (reg_readf(RCC_CFGR, SWS) != BV_RCC_CFGR_SWS_PLL1P); 103 + 104 + /* Reduce flash access latency */ 105 + reg_writef(FLASH_ACR, LATENCY(4), WRHIGHFREQ(2)); 106 + while (reg_readf(FLASH_ACR, LATENCY) != 4); 107 + } 108 + 109 + static void init_lse(void) 110 + { 111 + /* 112 + * Skip if LSE and RTC are already enabled. 113 + */ 114 + if (reg_readf(RCC_BDCR, LSERDY) && 115 + reg_readf(RCC_BDCR, RTCEN)) 116 + return; 117 + 118 + /* 119 + * Enable LSE and set it as RTC clock source, 120 + * then re-enable backup domain write protection. 121 + */ 122 + 123 + reg_writef(PWR_CR1, DBP(1)); 124 + 125 + /* Reset backup domain */ 126 + reg_writef(RCC_BDCR, BDRST(1)); 127 + reg_writef(RCC_BDCR, BDRST(0)); 128 + 129 + reg_writef(RCC_BDCR, LSEON(1), LSEDRV(3)); 130 + while (!reg_readf(RCC_BDCR, LSERDY)); 131 + 132 + reg_writef(RCC_BDCR, RTCEN(1), RTCSEL_V(LSE)); 133 + reg_writef(PWR_CR1, DBP(0)); 134 + } 135 + 136 + void stm_target_clock_init(void) 137 + { 138 + init_hse(); 139 + init_pll(); 140 + init_vos(); 141 + init_system_clock(); 142 + init_lse(); 143 + }
+3 -121
firmware/target/arm/stm32/system-stm32h7.c
··· 20 20 ****************************************************************************/ 21 21 #include "system.h" 22 22 #include "tick.h" 23 + #include "clock-stm32h7.h" 23 24 #include "gpio-stm32h7.h" 24 25 #include "regs/cortex-m/cm_scb.h" 25 26 #include "regs/cortex-m/cm_systick.h" 26 - #include "regs/stm32h743/rcc.h" 27 - #include "regs/stm32h743/pwr.h" 28 - #include "regs/stm32h743/syscfg.h" 29 - #include "regs/stm32h743/flash.h" 30 27 #include "regs/stm32h743/dbgmcu.h" 31 28 32 29 /* EXT timer is 1/8th of CPU clock */ ··· 37 34 /* Max delay is limited by kernel tick interval + safety margin */ 38 35 #define SYSTICK_DELAY_MAX_US (1000000 / HZ / 2) 39 36 #define SYSTICK_DELAY_MAX_MS (SYSTICK_DELAY_MAX_US / 1000) 40 - 41 - /* Flag to use VOS0 */ 42 - #define STM32H743_USE_VOS0 (CPU_FREQ > 400000000) 43 37 44 38 /* Base address of vector table */ 45 39 extern char __vectors_arm[]; ··· 61 55 arm_isb(); 62 56 } 63 57 64 - static void stm_init_hse(void) 65 - { 66 - reg_writef(RCC_CR, HSEON(1)); 67 - 68 - while (!reg_readf(RCC_CR, HSERDY)); 69 - } 70 - 71 - static void stm_init_pll(void) 72 - { 73 - /* TODO - this should be determined by the target in some way. */ 74 - 75 - /* Select HSE/4 input for PLL1 (6 MHz) */ 76 - reg_writef(RCC_PLLCKSELR, 77 - PLLSRC_V(HSE), 78 - DIVM1(4), 79 - DIVM2(0), 80 - DIVM3(0)); 81 - 82 - /* Enable PLL1P and PLL1Q */ 83 - reg_writef(RCC_PLLCFGR, 84 - DIVP1EN(1), 85 - DIVQ1EN(1), 86 - DIVR1EN(0), 87 - DIVP2EN(0), 88 - DIVQ2EN(0), 89 - DIVR2EN(0), 90 - DIVP3EN(0), 91 - DIVQ3EN(0), 92 - DIVR3EN(0), 93 - PLL1RGE_V(4_8MHZ), 94 - PLL1VCOSEL_V(WIDE)); 95 - 96 - reg_writef(RCC_PLL1DIVR, 97 - DIVN(80 - 1), /* 6 * 80 = 480 MHz */ 98 - DIVP(1 - 1), /* 480 / 1 = 480 MHz */ 99 - DIVQ(8 - 1), /* 480 / 8 = 60 MHz */ 100 - DIVR(1 - 1)); 101 - 102 - reg_writef(RCC_CR, PLL1ON(1)); 103 - while (!reg_readf(RCC_CR, PLL1RDY)); 104 - } 105 - 106 - static void stm_init_vos(void) 107 - { 108 - reg_writef(PWR_D3CR, VOS_V(VOS1)); 109 - while (!reg_readf(PWR_D3CR, VOSRDY)); 110 - 111 - if (STM32H743_USE_VOS0) 112 - { 113 - reg_writef(RCC_APB4ENR, SYSCFGEN(1)); 114 - 115 - /* Set ODEN bit to enter VOS0 */ 116 - reg_writef(SYSCFG_PWRCFG, ODEN(1)); 117 - while (!reg_readf(PWR_D3CR, VOSRDY)); 118 - 119 - reg_writef(RCC_APB4ENR, SYSCFGEN(0)); 120 - } 121 - } 122 - 123 - static void stm_init_system_clock(void) 124 - { 125 - /* Enable HCLK /2 divider (CPU is at 480 MHz, HCLK limit is 240 MHz) */ 126 - reg_writef(RCC_D1CFGR, HPRE(8)); 127 - while (reg_readf(RCC_D1CFGR, HPRE) != 8); 128 - 129 - /* Enable ABP /2 dividers (HCLK/2, APB limit is 120 MHz) */ 130 - reg_writef(RCC_D1CFGR, D1PPRE(4)); 131 - reg_writef(RCC_D2CFGR, D2PPRE1(4), D2PPRE2(4)); 132 - reg_writef(RCC_D3CFGR, D3PPRE(4)); 133 - 134 - /* Switch to PLL1P system clock source */ 135 - reg_writef(RCC_CFGR, SW_V(PLL1P)); 136 - while (reg_readf(RCC_CFGR, SWS) != BV_RCC_CFGR_SWS_PLL1P); 137 - 138 - /* Reduce flash access latency */ 139 - reg_writef(FLASH_ACR, LATENCY(4), WRHIGHFREQ(2)); 140 - while (reg_readf(FLASH_ACR, LATENCY) != 4); 141 - } 142 - 143 - static void stm_init_lse(void) 144 - { 145 - /* 146 - * Skip if LSE and RTC are already enabled. 147 - */ 148 - if (reg_readf(RCC_BDCR, LSERDY) && 149 - reg_readf(RCC_BDCR, RTCEN)) 150 - return; 151 - 152 - /* 153 - * Enable LSE and set it as RTC clock source, 154 - * then re-enable backup domain write protection. 155 - */ 156 - 157 - reg_writef(PWR_CR1, DBP(1)); 158 - 159 - /* Reset backup domain */ 160 - reg_writef(RCC_BDCR, BDRST(1)); 161 - reg_writef(RCC_BDCR, BDRST(0)); 162 - 163 - reg_writef(RCC_BDCR, LSEON(1), LSEDRV(3)); 164 - while (!reg_readf(RCC_BDCR, LSERDY)); 165 - 166 - reg_writef(RCC_BDCR, RTCEN(1), RTCSEL_V(LSE)); 167 - reg_writef(PWR_CR1, DBP(0)); 168 - } 169 - 170 58 void system_init(void) 171 59 { 172 60 #if defined(DEBUG) ··· 180 68 /* Enable CPU caches */ 181 69 stm_enable_caches(); 182 70 183 - /* Start up clocks and get running at max CPU frequency */ 184 - stm_init_hse(); 185 - stm_init_pll(); 186 - stm_init_vos(); 187 - stm_init_system_clock(); 188 - 189 - /* Start up LSE and RTC if necessary so backup domain works */ 190 - stm_init_lse(); 71 + /* Initialize system clocks */ 72 + stm_target_clock_init(); 191 73 192 74 /* TODO: move this */ 193 75 systick_init(1000/HZ);