stm32h7: support setting bus frequency in SPI driver

Change-Id: I71edf28fdc24d8a00d27aa727815f99e788b675a
This commit is contained in:
Aidan MacDonald 2025-12-26 21:48:12 +00:00 committed by Solomon Peachy
parent a4b0af2a44
commit 5137ef49e3
4 changed files with 41 additions and 1 deletions

View file

@ -162,3 +162,16 @@ void stm_target_clock_enable(enum stm_clock clock, bool enable)
break;
}
}
size_t stm_target_clock_get_frequency(enum stm_clock clock)
{
switch (clock)
{
case STM_CLOCK_SPI5_KER:
return STM32_HSE_FREQ;
default:
panicf("%s: unsupported clock %d", __func__, (int)clock);
return 0;
}
}

View file

@ -28,9 +28,13 @@
#include "regs/stm32h743/rcc.h"
#include "regs/stm32h743/spi.h"
/* ILI9342C specifies 10 MHz max */
#define LCD_SPI_FREQ 10000000
struct stm_spi_config spi_cfg = {
.instance = ITA_SPI5,
.clock = STM_CLOCK_SPI5_KER,
.freq = LCD_SPI_FREQ,
.mode = STM_SPIMODE_HALF_DUPLEX,
.proto = STM_SPIPROTO_MOTOROLA,
.frame_bits = 9,

View file

@ -108,10 +108,23 @@ static void stm_spi_unpack(void **bufp, size_t *sizep, uint32_t data)
*sizep = 0;
}
static uint32_t stm_spi_calc_mbr(const struct stm_spi_config *config)
{
size_t ker_freq = stm_clock_get_frequency(config->clock);
for (uint32_t mbr = 0; mbr <= 7; mbr++)
{
if (ker_freq / (2 << mbr) <= config->freq)
return mbr;
}
panicf("%s: impossible frequency", __func__);
}
void stm_spi_init(struct stm_spi *spi,
const struct stm_spi_config *config)
{
uint32_t ftlevel;
uint32_t mbr = stm_spi_calc_mbr(config);
spi->regs = config->instance;
spi->clock = config->clock;
@ -153,7 +166,7 @@ void stm_spi_init(struct stm_spi *spi,
/* TODO: allow setting MBR here */
reg_writelf(spi->regs, SPI_CFG1,
MBR(0),
MBR(mbr),
CRCEN(0),
CRCSIZE(7),
TXDMAEN(0),

View file

@ -50,7 +50,17 @@ struct stm_spi_config
{
/* Peripheral instance base address; one of ITA_SPIx */
uint32_t instance;
/*
* SPI kernel clock and requested SPI bus frequency.
* The frequency is used to set the SPI master baud
* rate setting based on the kernel clock input, as
* such the kernel clock should not be changed after
* the SPI peripheral is initialized.
*/
enum stm_clock clock;
size_t freq;
enum stm_spi_mode mode;
enum stm_spi_protocol proto;
stm_spi_set_cs_t set_cs;