From 5e78c76c79a7d6b46f774e5ba4af665d0b471324 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Wed, 12 Apr 2023 17:24:14 +0200 Subject: 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. --- bsps/arm/imxrt/console/console.c | 35 +++++++++++++++++++++-- bsps/arm/imxrt/i2c/imxrt-lpi2c.c | 18 ++++++++++-- bsps/arm/imxrt/mcux-sdk/drivers/qtmr_1/fsl_qtmr.c | 8 ++++++ bsps/arm/imxrt/spi/imxrt-lpspi.c | 18 ++++++++++-- 4 files changed, 73 insertions(+), 6 deletions(-) (limited to 'bsps') diff --git a/bsps/arm/imxrt/console/console.c b/bsps/arm/imxrt/console/console.c index 1389058e90..0ad6a8ada2 100644 --- a/bsps/arm/imxrt/console/console.c +++ b/bsps/arm/imxrt/console/console.c @@ -53,6 +53,7 @@ typedef struct { volatile LPUART_Type *regs; rtems_vector_number irq; const char *path; + clock_ip_name_t clock_ip; uint32_t src_clock_hz; lpuart_config_t config; } imxrt_lpuart_context; @@ -174,12 +175,15 @@ static bool imxrt_lpuart_set_attributes( 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; +#if IMXRT_IS_MIMXRT10xx uint32_t mux; uint32_t divider; + (void) clock_ip; /* Not necessary for i.MXRT1050 */ + mux = CLOCK_GetMux(kCLOCK_UartMux); divider = 1; @@ -197,10 +201,36 @@ static uint32_t imxrt_lpuart_get_src_freq(void) divider *= CLOCK_GetDiv(kCLOCK_UartDiv) + 1U; 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; } +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) { (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); } - 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); ctx->config.enableTx = true; diff --git a/bsps/arm/imxrt/i2c/imxrt-lpi2c.c b/bsps/arm/imxrt/i2c/imxrt-lpi2c.c index ac3d35b356..9b983f24af 100644 --- a/bsps/arm/imxrt/i2c/imxrt-lpi2c.c +++ b/bsps/arm/imxrt/i2c/imxrt-lpi2c.c @@ -373,12 +373,15 @@ static int imxrt_lpi2c_hw_init(struct imxrt_lpi2c_bus *bus) 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; +#if IMXRT_IS_MIMXRT10xx uint32_t mux; uint32_t divider; + (void) clock_ip; /* Not necessary for i.MXRT1050 */ + mux = CLOCK_GetMux(kCLOCK_Lpi2cMux); divider = 1; @@ -396,6 +399,17 @@ static uint32_t imxrt_lpi2c_get_src_freq(void) divider *= CLOCK_GetDiv(kCLOCK_Lpi2cDiv) + 1; 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; } @@ -457,7 +471,7 @@ void imxrt_lpi2c_init(void) } 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); if (eno != 0) { diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/qtmr_1/fsl_qtmr.c b/bsps/arm/imxrt/mcux-sdk/drivers/qtmr_1/fsl_qtmr.c index a4e393896b..4c8bd71be5 100644 --- a/bsps/arm/imxrt/mcux-sdk/drivers/qtmr_1/fsl_qtmr.c +++ b/bsps/arm/imxrt/mcux-sdk/drivers/qtmr_1/fsl_qtmr.c @@ -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) { +#if IMXRT_IS_MIMXRT10xx (void) base; 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__ */ diff --git a/bsps/arm/imxrt/spi/imxrt-lpspi.c b/bsps/arm/imxrt/spi/imxrt-lpspi.c index 7e812d9894..aed4f07f88 100644 --- a/bsps/arm/imxrt/spi/imxrt-lpspi.c +++ b/bsps/arm/imxrt/spi/imxrt-lpspi.c @@ -477,12 +477,15 @@ static int imxrt_lpspi_setup(spi_bus *base) 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; +#if IMXRT_IS_MIMXRT10xx uint32_t mux; uint32_t divider; + (void) clock_ip; /* Not necessary for i.MXRT1050 */ + mux = CLOCK_GetMux(kCLOCK_LpspiMux); switch (mux) { @@ -504,6 +507,17 @@ static uint32_t imxrt_lpspi_get_src_freq(void) divider = CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1; 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; } @@ -580,7 +594,7 @@ void imxrt_lpspi_init(void) } 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 */ bus->base.max_speed_hz = MIN(bus->src_clock_hz / 2, 30000000); bus->base.delay_usecs = 0; -- cgit v1.2.3