/* * Copyright (c) 2023, NXP * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include uint32_t flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate) { uint8_t divider; uint32_t root_rate; FLEXSPI_Type *flexspi; clock_div_t div_sel; clock_ip_name_t clk_name; switch (clock_name) { case IMX_CCM_FLEXSPI_CLK: /* Get clock root frequency */ root_rate = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot) * (CLOCK_GetDiv(kCLOCK_FlexspiDiv) + 1); flexspi = (FLEXSPI_Type *)DT_REG_ADDR(DT_NODELABEL(flexspi)); div_sel = kCLOCK_FlexspiDiv; clk_name = kCLOCK_FlexSpi; break; #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexspi2)) case IMX_CCM_FLEXSPI2_CLK: /* Get clock root frequency */ root_rate = CLOCK_GetClockRootFreq(kCLOCK_Flexspi2ClkRoot) * (CLOCK_GetDiv(kCLOCK_Flexspi2Div) + 1); flexspi = (FLEXSPI_Type *)DT_REG_ADDR(DT_NODELABEL(flexspi2)); div_sel = kCLOCK_Flexspi2Div; clk_name = kCLOCK_FlexSpi2; break; #endif default: return -ENOTSUP; } /* 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, kCLOCK_FlexspiDivBy8); while (FLEXSPI_GetBusIdleStatus(flexspi) == false) { /* Spin */ } FLEXSPI_Enable(flexspi, false); CLOCK_DisableClock(clk_name); CLOCK_SetDiv(div_sel, divider); CLOCK_EnableClock(clk_name); FLEXSPI_Enable(flexspi, true); FLEXSPI_SoftwareReset(flexspi); return 0; }