bsps/imxrt: Get clock for IMXRT11xx in drivers

The mcux_sdk has a different interface for getting the clock for
IMXRT11xx than for getting it in IMXRT10xx. Adapt simple drivers to
support that interface.
This commit is contained in:
Christian Mauderer
2023-04-12 17:24:14 +02:00
parent f3df09352c
commit 5e78c76c79
4 changed files with 73 additions and 6 deletions

View File

@@ -53,6 +53,7 @@ typedef struct {
volatile LPUART_Type *regs; volatile LPUART_Type *regs;
rtems_vector_number irq; rtems_vector_number irq;
const char *path; const char *path;
clock_ip_name_t clock_ip;
uint32_t src_clock_hz; uint32_t src_clock_hz;
lpuart_config_t config; lpuart_config_t config;
} imxrt_lpuart_context; } imxrt_lpuart_context;
@@ -174,12 +175,15 @@ static bool imxrt_lpuart_set_attributes(
return true; return true;
} }
static uint32_t imxrt_lpuart_get_src_freq(void) static uint32_t imxrt_lpuart_get_src_freq(clock_ip_name_t clock_ip)
{ {
uint32_t freq; uint32_t freq;
#if IMXRT_IS_MIMXRT10xx
uint32_t mux; uint32_t mux;
uint32_t divider; uint32_t divider;
(void) clock_ip; /* Not necessary for i.MXRT1050 */
mux = CLOCK_GetMux(kCLOCK_UartMux); mux = CLOCK_GetMux(kCLOCK_UartMux);
divider = 1; divider = 1;
@@ -197,10 +201,36 @@ static uint32_t imxrt_lpuart_get_src_freq(void)
divider *= CLOCK_GetDiv(kCLOCK_UartDiv) + 1U; divider *= CLOCK_GetDiv(kCLOCK_UartDiv) + 1U;
freq /= divider; freq /= divider;
#elif IMXRT_IS_MIMXRT11xx
/*
* FIXME: A future version of the mcux_sdk might provide a better method to
* get the clock instead of this hack.
*/
clock_root_t clock_root = clock_ip + kCLOCK_Root_Lpuart1 - kCLOCK_Lpuart1;
freq = CLOCK_GetRootClockFreq(clock_root);
#else
#error Getting UART clock frequency is not implemented for this chip
#endif
return freq; return freq;
} }
static clock_ip_name_t imxrt_lpuart_clock_ip(volatile LPUART_Type *regs)
{
LPUART_Type *const base_addresses[] = LPUART_BASE_PTRS;
static const clock_ip_name_t lpuart_clocks[] = LPUART_CLOCKS;
size_t i;
for (i = 0; i < RTEMS_ARRAY_SIZE(base_addresses); ++i) {
if (base_addresses[i] == regs) {
return lpuart_clocks[i];
}
}
return kCLOCK_IpInvalid;
}
static void imxrt_lpuart_init_hardware(imxrt_lpuart_context *ctx) static void imxrt_lpuart_init_hardware(imxrt_lpuart_context *ctx)
{ {
(void) LPUART_Init((LPUART_Type *)ctx->regs, &ctx->config, (void) LPUART_Init((LPUART_Type *)ctx->regs, &ctx->config,
@@ -378,7 +408,8 @@ static void imxrt_lpuart_init_context_from_fdt(
bsp_fatal(IMXRT_FATAL_LPI2C_INVALID_FDT); bsp_fatal(IMXRT_FATAL_LPI2C_INVALID_FDT);
} }
ctx->src_clock_hz = imxrt_lpuart_get_src_freq(); ctx->clock_ip = imxrt_lpuart_clock_ip(ctx->regs);
ctx->src_clock_hz = imxrt_lpuart_get_src_freq(ctx->clock_ip);
LPUART_GetDefaultConfig(&ctx->config); LPUART_GetDefaultConfig(&ctx->config);
ctx->config.enableTx = true; ctx->config.enableTx = true;

View File

@@ -373,12 +373,15 @@ static int imxrt_lpi2c_hw_init(struct imxrt_lpi2c_bus *bus)
return 0; return 0;
} }
static uint32_t imxrt_lpi2c_get_src_freq(void) static uint32_t imxrt_lpi2c_get_src_freq(clock_ip_name_t clock_ip)
{ {
uint32_t freq; uint32_t freq;
#if IMXRT_IS_MIMXRT10xx
uint32_t mux; uint32_t mux;
uint32_t divider; uint32_t divider;
(void) clock_ip; /* Not necessary for i.MXRT1050 */
mux = CLOCK_GetMux(kCLOCK_Lpi2cMux); mux = CLOCK_GetMux(kCLOCK_Lpi2cMux);
divider = 1; divider = 1;
@@ -396,6 +399,17 @@ static uint32_t imxrt_lpi2c_get_src_freq(void)
divider *= CLOCK_GetDiv(kCLOCK_Lpi2cDiv) + 1; divider *= CLOCK_GetDiv(kCLOCK_Lpi2cDiv) + 1;
freq /= divider; freq /= divider;
#elif IMXRT_IS_MIMXRT11xx
/*
* FIXME: A future version of the mcux_sdk might provide a better method to
* get the clock instead of this hack.
*/
clock_root_t clock_root = clock_ip + kCLOCK_Root_Lpi2c1 - kCLOCK_Lpi2c1;
freq = CLOCK_GetRootClockFreq(clock_root);
#else
#error Getting I2C frequency is not implemented for this chip.
#endif
return freq; return freq;
} }
@@ -457,7 +471,7 @@ void imxrt_lpi2c_init(void)
} }
bus->clock_ip = imxrt_lpi2c_clock_ip(bus->regs); bus->clock_ip = imxrt_lpi2c_clock_ip(bus->regs);
bus->src_clock_hz = imxrt_lpi2c_get_src_freq(); bus->src_clock_hz = imxrt_lpi2c_get_src_freq(bus->clock_ip);
eno = imxrt_lpi2c_hw_init(bus); eno = imxrt_lpi2c_hw_init(bus);
if (eno != 0) { if (eno != 0) {

View File

@@ -92,9 +92,17 @@ rtems_vector_number QTMR_get_IRQ_from_fdt(const void *fdt, int node)
uint32_t QTMR_get_src_clk(TMR_Type *base) uint32_t QTMR_get_src_clk(TMR_Type *base)
{ {
#if IMXRT_IS_MIMXRT10xx
(void) base; (void) base;
return CLOCK_GetFreq(kCLOCK_IpgClk); return CLOCK_GetFreq(kCLOCK_IpgClk);
#elif IMXRT_IS_MIMXRT11xx
(void) base;
return CLOCK_GetRootClockMux(kCLOCK_Root_Bus);
#else
#error Getting Timer clock frequency is not implemented for this chip
#endif
} }
#endif /* __rtems__ */ #endif /* __rtems__ */

View File

@@ -477,12 +477,15 @@ static int imxrt_lpspi_setup(spi_bus *base)
return rv; return rv;
} }
static uint32_t imxrt_lpspi_get_src_freq(void) static uint32_t imxrt_lpspi_get_src_freq(clock_ip_name_t clock_ip)
{ {
uint32_t freq; uint32_t freq;
#if IMXRT_IS_MIMXRT10xx
uint32_t mux; uint32_t mux;
uint32_t divider; uint32_t divider;
(void) clock_ip; /* Not necessary for i.MXRT1050 */
mux = CLOCK_GetMux(kCLOCK_LpspiMux); mux = CLOCK_GetMux(kCLOCK_LpspiMux);
switch (mux) { switch (mux) {
@@ -504,6 +507,17 @@ static uint32_t imxrt_lpspi_get_src_freq(void)
divider = CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1; divider = CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1;
freq /= divider; freq /= divider;
#elif IMXRT_IS_MIMXRT11xx
/*
* FIXME: A future version of the mcux_sdk might provide a better method to
* get the clock instead of this hack.
*/
clock_root_t clock_root = clock_ip + kCLOCK_Root_Lpspi1 - kCLOCK_Lpspi1;
freq = CLOCK_GetRootClockFreq(clock_root);
#else
#error Getting SPI frequency is not implemented for this chip.
#endif
return freq; return freq;
} }
@@ -580,7 +594,7 @@ void imxrt_lpspi_init(void)
} }
bus->clock_ip = imxrt_lpspi_clock_ip(bus->regs); bus->clock_ip = imxrt_lpspi_clock_ip(bus->regs);
bus->src_clock_hz = imxrt_lpspi_get_src_freq(); bus->src_clock_hz = imxrt_lpspi_get_src_freq(bus->clock_ip);
/* Absolut maximum is 30MHz according to electrical characteristics */ /* Absolut maximum is 30MHz according to electrical characteristics */
bus->base.max_speed_hz = MIN(bus->src_clock_hz / 2, 30000000); bus->base.max_speed_hz = MIN(bus->src_clock_hz / 2, 30000000);
bus->base.delay_usecs = 0; bus->base.delay_usecs = 0;