zephyr/soc/nxp/rw/flexspi_clock_setup.c
Daniel DeGrasse 53ceae5f58 soc: nxp: rw: use correct mask for FLEXSPI clock setup divider
Mask for FLEXSPI clock divider was being used when setting the FLEXSPI
clock selector value. Correct this to use the mask for the selector
instead of the divider.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
2024-05-14 18:21:57 -04:00

68 lines
1.8 KiB
C

/*
* Copyright 2022-2023 NXP
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/devicetree.h>
#include "flexspi_clock_setup.h"
#ifdef CONFIG_MEMC
#include <fsl_flexspi.h>
#include <fsl_clock.h>
#endif
#ifdef CONFIG_MEMC
/**
* @brief Set flexspi clock to given frequency
*
* This function differs from the above function in that it will not configure
* the FlexSPI with a new MUX source, only change the divider. This function
* is used by the clock control framework to set the clock frequency of
* the FlexSPI
*/
int __ramfunc flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate)
{
uint32_t root_rate;
uint32_t divider;
(void)clock_name; /* Not used by this function */
/* Get the root clock rate: FlexSPI clock * divisor */
root_rate = ((CLKCTL0->FLEXSPIFCLKDIV & CLKCTL0_FLEXSPIFCLKDIV_DIV_MASK) + 1) *
CLOCK_GetFlexspiClkFreq();
/* Select a divider based on root frequency.
* if we can't get an exact divider, round down
*/
divider = ((root_rate + (rate - 1)) / rate) - 1;
/* Cap divider to max value */
divider = MIN(divider, CLKCTL0_FLEXSPIFCLKDIV_DIV_MASK);
while (FLEXSPI_GetBusIdleStatus(FLEXSPI) == false) {
/* Spin */
}
FLEXSPI_Enable(FLEXSPI, false);
set_flexspi_clock(FLEXSPI, (CLKCTL0->FLEXSPIFCLKSEL &
CLKCTL0_FLEXSPIFCLKSEL_SEL_MASK), (divider + 1));
FLEXSPI_Enable(FLEXSPI, true);
FLEXSPI_SoftwareReset(FLEXSPI);
return 0;
}
#endif
/**
* @brief Set flexspi clock
*/
void __ramfunc set_flexspi_clock(FLEXSPI_Type *base, uint32_t src, uint32_t divider)
{
CLKCTL0->FLEXSPIFCLKSEL = CLKCTL0_FLEXSPIFCLKSEL_SEL(src);
CLKCTL0->FLEXSPIFCLKDIV |=
CLKCTL0_FLEXSPIFCLKDIV_RESET_MASK; /* Reset the divider counter */
CLKCTL0->FLEXSPIFCLKDIV = CLKCTL0_FLEXSPIFCLKDIV_DIV(divider - 1);
while ((CLKCTL0->FLEXSPIFCLKDIV) & CLKCTL0_FLEXSPIFCLKDIV_REQFLAG_MASK) {
}
}