How to enable pwm in u-boot's spl.c?

Jan 2025 - Hello, my SoM is Toradex imx8m mini and I have added the following codes in function board_init(void) which is in board/toradex/verdin-imx8mm/verdin-imx8mm.c and I can enable the pwm successfully. But pwm is enabled within nearly one second after pressing the power button, we want it to be faster.
Then we try to move these codes in function board_init_f() which is in board/toradex/verdin-imx8mm/spl.c where the pwm can be loaded faster, but when building the u-boot, it says:

debian/build/verdin-imx8mm/spl/../board/toradex/verdin-imx8mm/spl.c:142: undefined reference to `pwm_set_config'
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: /tmp/ccl4iKdI.ltrans0.ltrans.o:debian/build/verdin-imx8mm/spl/../board/toradex/verdin-imx8mm/spl.c:148: undefined reference to `pwm_set_enable'

So, maybe need to use other function to enable pwm here?

I have enable these configs in configs/verdin-imx8mm_defconfig
+CONFIG_CMD_PWM=y
+CONFIG_PWM=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_IMX=y

The following is my patch.

board/toradex/verdin-imx8mm/spl.c | 50 +++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)

diff --git a/board/toradex/verdin-imx8mm/spl.c b/board/toradex/verdin-imx8mm/spl.c
index 210665b…17de2b5 100644
— a/board/toradex/verdin-imx8mm/spl.c
+++ b/board/toradex/verdin-imx8mm/spl.c
@@ -26,11 +26,24 @@
#include <power/pca9450.h>
#include <power/pmic.h>
#include <spl.h>
+#include <dm.h>
+#include <pwm.h>

DECLARE_GLOBAL_DATA_PTR;

#define I2C_PMIC_BUS_ID 1

+#define IOMUXC_BASE_ADDR 0x30330000
+
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO01 0x3033002c
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO01 0x30330294
+
+#define IOMUXC_SW_MUX_CTL_PAD_SAI3_MCLK 0x303301e4
+#define IOMUXC_SW_PAD_CTL_PAD_SAI3_MCLK 0x3033044c
+
+#define MUX_MODE_ALT1 0x1
+#define PAD_CTL_DSE2 0x6
+
int spl_board_boot_device(enum boot_device boot_dev_spl)
{
switch (boot_dev_spl) {
@@ -103,6 +116,41 @@ int power_init_board(void)
return 0;
}

+void setup_iomux_pwm1(void)
+{

  • // config ALT1(PWM function)
  • writel(MUX_MODE_ALT1, IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO01);
  • // set PAD control, such as drive strength…
  • writel(PAD_CTL_DSE2, IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO01);
    +}

+void enable_status_light(void)
+{

  • struct udevice *pwm_dev1;
  • int ret;
  • // config IO MUX red-pwm1, green-pwm4
  • setup_iomux_pwm1();
  • // get pwm device
  • ret = uclass_get_device(UCLASS_PWM, 0, &pwm_dev1);
  • if (ret) {
  •    printf("Failed to get PWM1 device: %d\n", ret);
    
  • }
  • // config PWM1:period 1ms,duty cycle 25(0-255)
  • ret = pwm_set_config(pwm_dev1, 0, 1000000, 98039);
  • if (ret) {
  •    printf("Failed to configure PWM1: %d\n", ret);
    
  • }
  • // enable PWM
  • ret = pwm_set_enable(pwm_dev1, 0, true);
  • if (ret) {
  •    printf("Failed to enable PWM1: %d\n", ret);
    
  • }
    +}

void board_init_f(ulong dummy)
{
struct udevice *dev;
@@ -137,6 +185,8 @@ void board_init_f(ulong dummy)

power_init_board();
  • enable_status_light();
  • /* DDR initialization */
    spl_dram_init();

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

Thank you for reaching out with your question about enabling PWM in the U-Boot SPL for the Toradex iMX8M Mini. The undefined reference errors you’re encountering with pwm_set_config and pwm_set_enable are likely due to the limited functionality available in the SPL environment, which is a minimal bootloader context.

Here are some steps you can take to address this issue:

  1. SPL Configuration: Ensure that your SPL configuration includes all necessary components for PWM support. The SPL environment is stripped down, so not all U-Boot features are available. You may need to modify the SPL configuration to include the PWM driver code.

  2. Include Necessary Drivers: Verify that the PWM driver code is included in the SPL build. This might involve modifying the U-Boot source to ensure that the PWM driver is compiled and linked in the SPL context. You may need to add specific source files or adjust the Makefile to include the PWM driver.

  3. Alternative Methods: If direct function calls like pwm_set_config and pwm_set_enable are not available, consider alternative methods to configure PWM in SPL. This might involve writing lower-level register manipulation code to set up the PWM hardware directly, bypassing the higher-level driver functions.

  4. Debugging: Use debugging techniques to trace the build process and identify where the PWM functions are expected but not found. This can help you determine if there are missing dependencies or incorrect configurations.

By following these steps, you should be able to resolve the undefined reference errors and enable PWM functionality in the SPL context more effectively. If you continue to encounter issues, consider reviewing the U-Boot source code and configuration options related to PWM support in SPL.

Best regards,
Toradex AI Assistant.

Please, also check if these links can help you solve your problem:

Issue enabling PWM1 or Backlight on IMX8MM.

Currently, I can light the LED with GPIO enabled in spl.c as follows, but don’t konw which interface to use to select MUX mode of this pin to be pwm4_out and set frequency and periods. Could you give some support?

diff --git a/board/toradex/verdin-imx8mm/spl.c b/board/toradex/verdin-imx8mm/spl.c
index 210665b…6f60467 100644
— a/board/toradex/verdin-imx8mm/spl.c
+++ b/board/toradex/verdin-imx8mm/spl.c
@@ -26,6 +26,8 @@
#include <power/pca9450.h>
#include <power/pmic.h>
#include <spl.h>
+#include <asm/mach-imx/gpio.h>
+

DECLARE_GLOBAL_DATA_PTR;

@@ -137,8 +139,32 @@ void board_init_f(ulong dummy)

power_init_board();
  • enable_status_light();

  • /* DDR initialization */
    spl_dram_init();

    board_init_r(NULL, 0);
    }

+#define LED_PWM1 IMX_GPIO_NR(1,1)
+#define LED_PWM4 IMX_GPIO_NR(5,2)
+
+#define PWM_PAD_CTRL PAD_CTL_DSE6
+
+static iomux_v3_cfg_t const pwm_pads = {

  • IMX8MM_PAD_GPIO1_IO01_GPIO1_IO1 | MUX_PAD_CTRL(PWM_PAD_CTRL),
  • IMX8MM_PAD_SAI3_MCLK_GPIO5_IO2 | MUX_PAD_CTRL(PWM_PAD_CTRL)
    +};

+void enable_status_light(void)
+{

  • /* activate LED controller OE */
  • imx_iomux_v3_setup_multiple_pads(pwm_pads, ARRAY_SIZE(pwm_pads));
  • gpio_request(LED_PWM4, “PWM4”);
  • gpio_direction_output(LED_PWM4, 1);
  • //gpio_request(LED_PWM1, “PWM1”);
  • //gpio_direction_output(LED_PWM1, 1);
    +}

This patch for upstream U-boot 2024.07 pulls up Verdin iMX8MP’s SODIMM 19 in SPL.
gpio_pull_high_spl.patch (5.6 KB)

SPL uses a compact device tree to initialize necessary devices. Any node with bootph-pre-ram; will be retained during U-boot building.

However, the same config for SODIMM 91 doesn’t work. I will look into it.