diff --git a/src/hal/drivers/mesa-hostmot2/hm2_spix.c b/src/hal/drivers/mesa-hostmot2/hm2_spix.c index 67d522690f1..d5d2dd7c4ac 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_spix.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_spix.c @@ -632,8 +632,17 @@ static int spix_setup(void) if(!(spi_probe & (1 << i))) // Only probe if enabled continue; - sa.clkw = spiclk_rate[j] * 1000; - sa.clkr = spiclk_rate_rd[j] * 1000; + // The clock is increased by 1 kHz to compensate for the truncation of + // the listed values. The clock divider calculations will always be + // rounded down, making it consistent between hardware drivers and + // kernel's spidev driver. + // For example: On the RPi5, a clock of 33333 kHz would become 25000 + // kHz without compensation because of recurring 3 behind the comma in + // 33333 kHz, which got truncated. With compensation we use 33334 kHz + // as the rate and that gets rounded down to 33333 kHz in the + // calculation. + sa.clkw = (spiclk_rate[j] + 1) * 1000; + sa.clkr = (spiclk_rate_rd[j] + 1) * 1000; sa.spidev = spidev_path[j]; if(NULL == (port = hwdriver->open(i, &sa))) { LL_INFO("Failed to open hardware port index %d\n", i); diff --git a/src/hal/drivers/mesa-hostmot2/spix_rpi3.c b/src/hal/drivers/mesa-hostmot2/spix_rpi3.c index 2a71b6f76f5..ccb3c8dc10f 100644 --- a/src/hal/drivers/mesa-hostmot2/spix_rpi3.c +++ b/src/hal/drivers/mesa-hostmot2/spix_rpi3.c @@ -176,7 +176,7 @@ HWREGACCESS_ALWAYS_INLINE static inline void gpio_debug_pin(bool set_reset) */ static int32_t spi0_clkdiv_calc(uint32_t base, uint32_t rate) { - uint32_t clkdiv = base / rate; + uint32_t clkdiv = (base + rate - 1) / rate; // Use only even divider values // This is what the documentation (probably) states if(clkdiv > 65534) @@ -274,7 +274,7 @@ static int32_t spi1_clkdiv_calc(uint32_t base, uint32_t rate) uint32_t clkdiv; if(rate >= base / 2) return 0; - clkdiv = base / (rate * 2) - 1; + clkdiv = (base + rate*2 - 1) / (rate * 2) - 1; if(clkdiv > 4095) clkdiv = 4095; // Slowest possible return clkdiv; diff --git a/src/hal/drivers/mesa-hostmot2/spix_rpi5.c b/src/hal/drivers/mesa-hostmot2/spix_rpi5.c index f90b1c68a94..cc905261236 100644 --- a/src/hal/drivers/mesa-hostmot2/spix_rpi5.c +++ b/src/hal/drivers/mesa-hostmot2/spix_rpi5.c @@ -171,7 +171,7 @@ HWREGACCESS_ALWAYS_INLINE static inline void gpio_debug_pin(bool set_reset) */ static inline int32_t clkdiv_calc(uint32_t rate) { - uint32_t clkdiv = RP1_SPI_CLK / rate; + uint32_t clkdiv = (RP1_SPI_CLK + rate - 1) / rate; // The documentation states: bit 0 is always zero, therefore, only even // divider values supported. Divider value 0 disables the SCLK output. if(clkdiv > 65534)