stm32h7: refactor and simplify clock helper functions
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 386be9dfcc72a0c2b3786a7e1ee8ce55676c93bc Author: Aidan MacDonald <[email protected]> Date: Fri Jan 16 14:17:02 2026 +0000 stm32h7: refactor and simplify clock helper functions The clock helpers are only used for leaf clocks of single peripherals, which don't benefit from reference counting. Change-Id: Ica5685e7bc0fce621ae46f758f0ad0b1dcfb2789 diff --git a/firmware/SOURCES b/firmware/SOURCES index 6be052de85..9279307af5 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -2024,7 +2024,6 @@ target/arm/rk27xx/ihifi2/audio-ihifi800.c target/arm/stm32/crt0-stm32h7.S target/arm/stm32/vectors-stm32h7.S target/arm/stm32/adc-stm32h7.c -target/arm/stm32/clock-stm32h7.c target/arm/stm32/debug-stm32h7.c target/arm/stm32/gpio-stm32h7.c target/arm/stm32/i2c-stm32h7.c diff --git a/firmware/target/arm/stm32/clock-stm32h7.c b/firmware/target/arm/stm32/clock-stm32h7.c deleted file mode 100644 index ec1ff106b2..0000000000 --- a/firmware/target/arm/stm32/clock-stm32h7.c +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2025 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "clock-stm32h7.h" -#include "mutex.h" -#include "panic.h" -#include <stdint.h> - -struct stm_clock_state -{ - struct mutex mutex; - uint8_t refcount[STM_NUM_CLOCKS]; -}; - -static struct stm_clock_state stm_clocks; - -void stm_clock_init(void) -{ - mutex_init(&stm_clocks.mutex); - - stm_target_clock_init(); -} - -void stm_clock_enable(enum stm_clock clock) -{ - mutex_lock(&stm_clocks.mutex); - - if (stm_clocks.refcount[clock] == UINT8_MAX) - panicf("%s: clock %d overflow", __func__, (int)clock); - - if (stm_clocks.refcount[clock]++ == 0) - stm_target_clock_enable(clock, true); - - mutex_unlock(&stm_clocks.mutex); -} - -void stm_clock_disable(enum stm_clock clock) -{ - mutex_lock(&stm_clocks.mutex); - - if (stm_clocks.refcount[clock] == 0) - panicf("%s: clock %d underflow", __func__, (int)clock); - - if (--stm_clocks.refcount[clock] == 0) - stm_target_clock_enable(clock, false); - - mutex_unlock(&stm_clocks.mutex); -} diff --git a/firmware/target/arm/stm32/clock-stm32h7.h b/firmware/target/arm/stm32/clock-stm32h7.h index 7e78d30ecf..e6dbd44c53 100644 --- a/firmware/target/arm/stm32/clock-stm32h7.h +++ b/firmware/target/arm/stm32/clock-stm32h7.h @@ -25,18 +25,15 @@ #include <stdbool.h> #include <stddef.h> -enum stm_clock +struct stm32_clock { - STM_CLOCK_SPI1_KER, - STM_CLOCK_SPI2_KER, - STM_CLOCK_SPI3_KER, - STM_CLOCK_SPI4_KER, - STM_CLOCK_SPI5_KER, - STM_CLOCK_SPI6_KER, - STM_CLOCK_LTDC_KER, - STM_CLOCK_SDMMC1_KER, - STM_CLOCK_SDMMC2_KER, - STM_NUM_CLOCKS, + uint32_t frequency; + + uint32_t en_reg; + uint32_t en_bit; + + uint32_t lpen_reg; + uint32_t lpen_bit; }; /* @@ -47,43 +44,43 @@ enum stm_clock void stm_target_clock_init(void) INIT_ATTR; /* - * Callback to be implemented by the target when the hardware - * clock needs to be turned on or off. Clocks are internally - * reference counted so only the first / last user will change - * the hardware state. - * - * Only clocks that are actually used need to be implemented, - * and unless otherwise noted it is allowed for enable/disable - * to be a no-op if the clock is always enabled. + * Called by system_init() to setup target clocks. */ -void stm_target_clock_enable(enum stm_clock clock, bool enable); +static inline void stm_clock_init(void) +{ + stm_target_clock_init(); +} /* - * Callback to return a specific clock's frequency. For most - * peripherals the frequency must be known at initialization - * and not change afterwards; see peripheral drivers for the - * details, as their exact requirements may vary. + * Enables a clock by setting its enable bits in the RCC. */ -size_t stm_target_clock_get_frequency(enum stm_clock clock); +static inline void stm32_clock_enable(const struct stm32_clock *clk) +{ + if (clk->en_reg) + *(volatile uint32_t *)clk->en_reg |= clk->en_bit; -/* - * Called from system_init(). Sets up internal book-keeping - * and then calls stm_target_clock_init(). - */ -void stm_clock_init(void) INIT_ATTR; + if (clk->lpen_reg) + *(volatile uint32_t *)clk->lpen_reg |= clk->lpen_bit; +} /* - * Enable or disable a clock. Not safe to call from an IRQ handler. + * Disables a clock in the RCC. */ -void stm_clock_enable(enum stm_clock clock); -void stm_clock_disable(enum stm_clock clock); +static inline void stm32_clock_disable(const struct stm32_clock *clk) +{ + if (clk->en_reg) + *(volatile uint32_t *)clk->en_reg &= ~clk->en_bit; + + if (clk->lpen_reg) + *(volatile uint32_t *)clk->lpen_reg &= ~clk->lpen_bit; +} /* * Get a clock's frequency in Hz. */ -static inline size_t stm_clock_get_frequency(enum stm_clock clock) +static inline uint32_t stm32_clock_get_frequency(const struct stm32_clock *clk) { - return stm_target_clock_get_frequency(clock); + return clk->frequency; } #endif /* __CLOCK_STM32H7_H__ */ diff --git a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c index fcf26ae3dc..2ff829bfd8 100644 --- a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c @@ -180,43 +180,26 @@ void stm_target_clock_init(void) init_periph_clock(); } -void stm_target_clock_enable(enum stm_clock clock, bool enable) -{ - switch (clock) - { - case STM_CLOCK_SPI5_KER: - reg_writef(RCC_APB2ENR, SPI5EN(enable)); - reg_writef(RCC_APB2LPENR, SPI5EN(enable)); - break; - - case STM_CLOCK_LTDC_KER: - reg_writef(RCC_APB3ENR, LTDCEN(enable)); - reg_writef(RCC_APB3LPENR, LTDCEN(enable)); - break; - - case STM_CLOCK_SDMMC1_KER: - reg_writef(RCC_AHB3ENR, SDMMC1EN(enable)); - reg_writef(RCC_AHB3LPENR, SDMMC1EN(enable)); - break; - - default: - panicf("%s: unsupported clock %d", __func__, (int)clock); - break; - } -} - -size_t stm_target_clock_get_frequency(enum stm_clock clock) -{ - switch (clock) - { - case STM_CLOCK_SPI5_KER: - return STM32_HSE_FREQ; - - case STM_CLOCK_SDMMC1_KER: - return PLL1Q_FREQ; - - default: - panicf("%s: unsupported clock %d", __func__, (int)clock); - return 0; - } -} +const struct stm32_clock sdmmc1_ker_clock = { + .frequency = PLL1Q_FREQ, + .en_reg = ITA_RCC_AHB3ENR, + .en_bit = BM_RCC_AHB3ENR_SDMMC1EN, + .lpen_reg = ITA_RCC_AHB3LPENR, + .lpen_bit = BM_RCC_AHB3LPENR_SDMMC1EN, +}; + +const struct stm32_clock ltdc_ker_clock = { + .frequency = LCD_DOTCLOCK_FREQ, + .en_reg = ITA_RCC_APB3ENR, + .en_bit = BM_RCC_APB3ENR_LTDCEN, + .lpen_reg = ITA_RCC_APB3LPENR, + .lpen_bit = BM_RCC_APB3ENR_LTDCEN, +}; + +const struct stm32_clock spi5_ker_clock = { + .frequency = STM32_HSE_FREQ, + .en_reg = ITA_RCC_APB2ENR, + .en_bit = BM_RCC_APB2ENR_SPI5EN, + .lpen_reg = ITA_RCC_APB2LPENR, + .lpen_bit = BM_RCC_APB2ENR_SPI5EN, +}; diff --git a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h new file mode 100644 index 0000000000..cea54441c0 --- /dev/null +++ b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2026 Aidan MacDonald + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __CLOCK_ECHOPLAYER_H__ +#define __CLOCK_ECHOPLAYER_H__ + +#include "clock-stm32h7.h" + +extern struct stm32_clock sdmmc1_ker_clock; +extern struct stm32_clock ltdc_ker_clock; +extern struct stm32_clock spi5_ker_clock; + +#endif /* __CLOCK_ECHOPLAYER_H__ */ diff --git a/firmware/target/arm/stm32/echoplayer/lcd-echoplayer.c b/firmware/target/arm/stm32/echoplayer/lcd-echoplayer.c index ea2febeff6..947342b1fb 100644 --- a/firmware/target/arm/stm32/echoplayer/lcd-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/lcd-echoplayer.c @@ -22,6 +22,7 @@ #include "kernel.h" #include "lcd.h" #include "lcd-echoplayer.h" +#include "clock-echoplayer.h" #include "nvic-arm.h" #include "spi-stm32h7.h" #include "gpio-stm32h7.h" @@ -40,7 +41,7 @@ struct stm_spi_config spi_cfg = { .instance = ITA_SPI5, - .clock = STM_CLOCK_SPI5_KER, + .clock = &spi5_ker_clock, .freq = LCD_SPI_FREQ, .mode = STM_SPIMODE_HALF_DUPLEX, .proto = STM_SPIPROTO_MOTOROLA, @@ -61,7 +62,7 @@ struct stm_spi spi; static void init_ltdc(void) { /* Enable LTDC clock */ - stm_clock_enable(STM_CLOCK_LTDC_KER); + stm32_clock_enable(<dc_ker_clock); /* Set timing parameters */ const uint32_t hsw = LCD_HSW - 1; diff --git a/firmware/target/arm/stm32/echoplayer/sdmmc-echoplayer.c b/firmware/target/arm/stm32/echoplayer/sdmmc-echoplayer.c index 5120cca473..7a192bc914 100644 --- a/firmware/target/arm/stm32/echoplayer/sdmmc-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/sdmmc-echoplayer.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include "sdmmc_host.h" +#include "clock-echoplayer.h" #include "sdmmc-stm32h7.h" #include "gpio-stm32h7.h" #include "nvic-arm.h" @@ -95,7 +96,7 @@ static struct sdmmc_poll sdcard_poll; void sdmmc_host_target_init(void) { /* Initialize controller */ - stm32h7_sdmmc_init(&sdmmc1_ctl, ITA_SDMMC1, STM_CLOCK_SDMMC1_KER, + stm32h7_sdmmc_init(&sdmmc1_ctl, ITA_SDMMC1, &sdmmc1_ker_clock, stm32h7_reset_sdmmc1, NULL); nvic_enable_irq(NVIC_IRQN_SDMMC1); diff --git a/firmware/target/arm/stm32/sdmmc-stm32h7.c b/firmware/target/arm/stm32/sdmmc-stm32h7.c index 4147c0a95a..0fdad1156a 100644 --- a/firmware/target/arm/stm32/sdmmc-stm32h7.c +++ b/firmware/target/arm/stm32/sdmmc-stm32h7.c @@ -80,7 +80,7 @@ void stm32h7_reset_sdmmc1(void) void stm32h7_sdmmc_init(struct stm32h7_sdmmc_controller *ctl, uint32_t instance, - enum stm_clock clock, + const struct stm32_clock *clock, void (*reset_sdmmc)(void), void (*vcc_enable)(bool)) { @@ -109,7 +109,7 @@ void stm32h7_sdmmc_set_power_enabled(void *controller, bool enabled) sleep(1); /* Bus clock is now needed, so enable kernel clock */ - stm_clock_enable(ctl->clock); + stm32_clock_enable(ctl->clock); /* Configure bus parameters */ stm32h7_sdmmc_set_bus_width(ctl, SDMMC_BUS_WIDTH_1BIT); @@ -136,7 +136,7 @@ void stm32h7_sdmmc_set_power_enabled(void *controller, bool enabled) * and the bus is powered down; some quick testing shows this * seems to be true. */ - stm_clock_disable(ctl->clock); + stm32_clock_disable(ctl->clock); /* Disable VCC */ if (ctl->vcc_enable) @@ -174,7 +174,7 @@ void stm32h7_sdmmc_set_bus_clock(void *controller, uint32_t clock) if (stm32h7_sdmmc_is_powered_off(ctl)) return; - size_t ker_freq = stm_clock_get_frequency(ctl->clock); + size_t ker_freq = stm32_clock_get_frequency(ctl->clock); size_t bus_freq = get_sdmmc_bus_freq(clock); if (!bus_freq) panicf("%s", __func__); diff --git a/firmware/target/arm/stm32/sdmmc-stm32h7.h b/firmware/target/arm/stm32/sdmmc-stm32h7.h index 95f3ab0cbc..7aeed251e2 100644 --- a/firmware/target/arm/stm32/sdmmc-stm32h7.h +++ b/firmware/target/arm/stm32/sdmmc-stm32h7.h @@ -31,7 +31,7 @@ struct stm32h7_sdmmc_controller uint32_t regs; /* SDMMC kernel clock */ - enum stm_clock clock; + const struct stm32_clock *clock; /* Callback to reset SDMMC instance in RCC */ void (*reset_sdmmc)(void); @@ -59,7 +59,7 @@ void stm32h7_reset_sdmmc1(void); void stm32h7_sdmmc_init(struct stm32h7_sdmmc_controller *controller, uint32_t instance, - enum stm_clock clock, + const struct stm32_clock *clock, void (*reset_sdmmc)(void), void (*vcc_enable)(bool)); diff --git a/firmware/target/arm/stm32/spi-stm32h7.c b/firmware/target/arm/stm32/spi-stm32h7.c index 941310f90d..fc4d87eafc 100644 --- a/firmware/target/arm/stm32/spi-stm32h7.c +++ b/firmware/target/arm/stm32/spi-stm32h7.c @@ -37,7 +37,7 @@ static void stm_spi_enable(struct stm_spi *spi, bool hd_tx, size_t size) if (tsize > TSIZE_MAX) panicf("%s: tsize > TSIZE_MAX", __func__); - stm_clock_enable(spi->clock); + stm32_clock_enable(spi->clock); if (spi->set_cs) spi->set_cs(spi, true); @@ -59,7 +59,7 @@ static void stm_spi_disable(struct stm_spi *spi) if (spi->set_cs) spi->set_cs(spi, false); - stm_clock_disable(spi->clock); + stm32_clock_disable(spi->clock); } static uint32_t stm_spi_pack(const void **bufp, size_t *sizep) @@ -110,7 +110,7 @@ static void stm_spi_unpack(void **bufp, size_t *sizep, uint32_t data) static uint32_t stm_spi_calc_mbr(const struct stm_spi_config *config) { - size_t ker_freq = stm_clock_get_frequency(config->clock); + size_t ker_freq = stm32_clock_get_frequency(config->clock); for (uint32_t mbr = 0; mbr <= 7; mbr++) { if (ker_freq / (2 << mbr) <= config->freq) @@ -162,7 +162,7 @@ void stm_spi_init(struct stm_spi *spi, ftlevel *= 2; } - stm_clock_enable(spi->clock); + stm32_clock_enable(spi->clock); /* TODO: allow setting MBR here */ reg_writelf(spi->regs, SPI_CFG1, @@ -191,7 +191,7 @@ void stm_spi_init(struct stm_spi *spi, MIDI(0), MSSI(0)); - stm_clock_disable(spi->clock); + stm32_clock_disable(spi->clock); } int stm_spi_xfer(struct stm_spi *spi, size_t size, diff --git a/firmware/target/arm/stm32/spi-stm32h7.h b/firmware/target/arm/stm32/spi-stm32h7.h index dbc6a2fdaa..a6b0ef11d0 100644 --- a/firmware/target/arm/stm32/spi-stm32h7.h +++ b/firmware/target/arm/stm32/spi-stm32h7.h @@ -58,7 +58,7 @@ struct stm_spi_config * such the kernel clock should not be changed after * the SPI peripheral is initialized. */ - enum stm_clock clock; + const struct stm32_clock *clock; size_t freq; enum stm_spi_mode mode; @@ -77,7 +77,7 @@ struct stm_spi_config struct stm_spi { uint32_t regs; - enum stm_clock clock; + const struct stm32_clock *clock; enum stm_spi_mode mode; stm_spi_set_cs_t set_cs; uint32_t frame_size; -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs