Skip to content

Commit

Permalink
Use same clock divider calculation round-up as the kernel's spidev dr…
Browse files Browse the repository at this point in the history
…iver.

Compensate truncated input values by adding one kHz to the rate settings.
  • Loading branch information
BsAtHome committed Dec 7, 2024
1 parent feabf54 commit a4f249d
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
13 changes: 11 additions & 2 deletions src/hal/drivers/mesa-hostmot2/hm2_spix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/hal/drivers/mesa-hostmot2/spix_rpi3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/hal/drivers/mesa-hostmot2/spix_rpi5.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit a4f249d

Please sign in to comment.