From e1a9ff95304957a774642ff1bef2b1851a4ae96a Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 12 Mar 2025 17:04:07 +0800 Subject: [PATCH 01/16] imx93_evk: Fix wrong VDDQ voltage setting for LPDDR4x The default PCA9451 BUCK2 volt is 0.6 V for LPDDR4x VDDQ. The codes are actually used for reworking to LPDDR4 which needs VDDQ at 1.1 V. So remove it to avoid LPDDR4x issue. Signed-off-by: Ye Li Acked-by: Peng Fan --- board/freescale/imx93_evk/spl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/board/freescale/imx93_evk/spl.c b/board/freescale/imx93_evk/spl.c index a214c04ddad..67a10bbb05b 100644 --- a/board/freescale/imx93_evk/spl.c +++ b/board/freescale/imx93_evk/spl.c @@ -110,11 +110,6 @@ int power_init_board(void) pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, buck_val + 0x4); } - if (IS_ENABLED(CONFIG_IMX93_EVK_LPDDR4X)) { - /* Set VDDQ to 1.1V from buck2 */ - pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x28); - } - /* set standby voltage to 0.65v */ if (val & PCA9450_REG_PWRCTRL_TOFF_DEB) pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x0); From 27e0160320c13168ab5d703c5ec4bec87a6d2700 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 29 Dec 2024 14:46:05 +0000 Subject: [PATCH 02/16] rpi: Add identifiers for the new RPi 5 series The Raspberry Pi foundation have released the Raspberry Pi 500, CM5 an CM5 lite devices so add the assoicated revision identifers so we can detect them. Signed-off-by: Peter Robinson Acked-by: Matthias Brugger --- board/raspberrypi/rpi/rpi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index aa39afa338a..4d546892842 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -193,6 +193,21 @@ static const struct rpi_model rpi_models_new_scheme[] = { DTB_DIR "bcm2712-rpi-5-b.dtb", true, }, + [0x18] = { + "Compute Module 5", + DTB_DIR "bcm2712-rpi-cm5-cm5io.dtb", + true, + }, + [0x19] = { + "500", + DTB_DIR "bcm2712-rpi-500.dtb", + true, + }, + [0x1A] = { + "Compute Module 5 Lite", + DTB_DIR "bcm2712-rpi-cm5l-cm5io.dtb", + true, + }, }; static const struct rpi_model rpi_models_old_scheme[] = { From 2d75c46be99c15fa186436c149b87ee97e0b8f44 Mon Sep 17 00:00:00 2001 From: Martin Stolpe Date: Wed, 23 Oct 2024 15:09:20 +0200 Subject: [PATCH 03/16] rpi: Only add frame buffer node if CONFIG_FDT_SIMPLEFB is set The functions fdt_simplefb_add_node and fdt_simplefb_enable_and_mem_rsv are only available if CONFIG_FDT_SIMPLEFB is enabled. Signed-off-by: Martin Stolpe Acked-by: Matthias Brugger Signed-off-by: Peter Robinson --- board/raspberrypi/rpi/rpi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 4d546892842..fe6153b388b 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -604,11 +604,13 @@ int ft_board_setup(void *blob, struct bd_info *bd) update_fdt_from_fw(blob, (void *)fw_dtb_pointer); - node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); - if (node < 0) - fdt_simplefb_add_node(blob); - else - fdt_simplefb_enable_and_mem_rsv(blob); + if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) { + node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); + if (node < 0) + fdt_simplefb_add_node(blob); + else + fdt_simplefb_enable_and_mem_rsv(blob); + } #ifdef CONFIG_EFI_LOADER /* Reserve the spin table */ From fc7a3110184a3ca4c227675b20d3a4887210e36c Mon Sep 17 00:00:00 2001 From: Fiona Klute Date: Wed, 12 Feb 2025 12:39:01 +0100 Subject: [PATCH 04/16] Raspberry Pi: Keep warnings from firmware in DT, if any The /chosen/user-warnings property is created by the RPi firmware if there are warnings to report, keep it to make debugging easier. For example, if the firmware config.txt contains "dtoverlay=error-example" and that example references an undefined symbol "&nosuchdev" the warning can be read after boot: $ cat /proc/device-tree/chosen/user-warnings dterror: can't find symbol 'nosuchdev' Failed to resolve overlay 'error-example' Signed-off-by: Fiona Klute Reviewed-by: Matthias Brugger Signed-off-by: Peter Robinson --- board/raspberrypi/rpi/rpi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index fe6153b388b..43efb0dbc1d 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -594,6 +594,9 @@ void update_fdt_from_fw(void *fdt, void *fw_fdt) /* kernel address randomisation seed as provided by the firmware */ copy_property(fdt, fw_fdt, "/chosen", "kaslr-seed"); + /* warnings from the firmware (if any) */ + copy_property(fdt, fw_fdt, "/chosen", "user-warnings"); + /* address of the PHY device as provided by the firmware */ copy_property(fdt, fw_fdt, "ethernet0/mdio@e14/ethernet-phy@1", "reg"); } From e042d7593a0b7544259fd2d22240e78d18912746 Mon Sep 17 00:00:00 2001 From: Fiona Klute Date: Wed, 12 Feb 2025 12:39:02 +0100 Subject: [PATCH 05/16] Raspberry Pi: Copy Bluetooth device address in DT The firmware sets local-bd-address, copy it when loading a new DT. Signed-off-by: Fiona Klute Signed-off-by: Peter Robinson --- board/raspberrypi/rpi/rpi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 43efb0dbc1d..70d3c35499b 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -599,6 +599,9 @@ void update_fdt_from_fw(void *fdt, void *fw_fdt) /* address of the PHY device as provided by the firmware */ copy_property(fdt, fw_fdt, "ethernet0/mdio@e14/ethernet-phy@1", "reg"); + + /* Bluetooth device address as provided by the firmware */ + copy_property(fdt, fw_fdt, "/soc/serial@7e201000/bluetooth", "local-bd-address"); } int ft_board_setup(void *blob, struct bd_info *bd) From 15d6518c942f0da13f9a7ceeadbd925c3317ec8d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 11 Mar 2025 02:34:18 +0100 Subject: [PATCH 06/16] ARM: dts: imx: Drop bogus regulator extras on DH i.MX6 DHCOM DRC02 The regulator extras should be placed in the USB H1 regulator node, the /regulator-usb-h1-vbus. They are already present there in the upstream DT, so delete this bogus node entirely. Signed-off-by: Marek Vasut --- arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi index 740a24d96ec..300e355c8ef 100644 --- a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi @@ -27,11 +27,6 @@ }; }; -®_usb_otg_vbus { - gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>; - enable-active-high; -}; - &wdog1 { bootph-pre-ram; }; From 2b08beb3b35ac2a1d613efe5fc1e64a3ba793253 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:21 -0500 Subject: [PATCH 07/16] clk: imx6q: Properly handle imx6qp ECSPI clk_sels The ECSPI clock has the ability to select between pll3_60m and osc on the imx6qp, where it's fixed on other variants. Fix this by adding using a helper function to determine SoC variant and register the clock accordingly. Signed-off-by: Adam Ford Reviewed-by: Michael Trimarchi Reviewed-by: Peng Fan --- drivers/clk/imx/clk-imx6q.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index df9f0285e1e..15ad0c9ac06 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -35,6 +35,7 @@ static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *const periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *const periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; +static const char *const ecspi_sels[] = { "pll3_60m", "osc", }; static int imx6q_clk_probe(struct udevice *dev) { @@ -78,6 +79,11 @@ static int imx6q_clk_probe(struct udevice *dev) imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels))); + if (of_machine_is_compatible("fsl,imx6qp") + clk_dm(IMX6QDL_CLK_ECSPI_SEL, + imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, + ARRAY_SIZE(ecspi_sels))); + clk_dm(IMX6QDL_CLK_USDHC1_PODF, imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3)); @@ -91,8 +97,12 @@ static int imx6q_clk_probe(struct udevice *dev) imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3)); - clk_dm(IMX6QDL_CLK_ECSPI_ROOT, - imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6)); + if (of_machine_is_compatible("fsl,imx6qp") + clk_dm(IMX6QDL_CLK_ECSPI_ROOT, + imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6)); + else + clk_dm(IMX6QDL_CLK_ECSPI_ROOT, + imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6)); clk_dm(IMX6QDL_CLK_ECSPI1, imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0)); From a3b726e416da9effe1506800286284b4c792c913 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:22 -0500 Subject: [PATCH 08/16] clk: imx6q: Register UART clocks In order to use the driver model and clock system to enable UART clocks from the serial driver, it's necessary to register the UART clocks. With the helper function to check for imx6qp vs other variants, the UART can register for both scenarios. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- drivers/clk/imx/clk-imx6q.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index 15ad0c9ac06..a4295614016 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -35,6 +35,7 @@ static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *const periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *const periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; +static const char *const uart_sels[] = { "pll3_80m", "osc", }; static const char *const ecspi_sels[] = { "pll3_60m", "osc", }; static int imx6q_clk_probe(struct udevice *dev) @@ -79,10 +80,14 @@ static int imx6q_clk_probe(struct udevice *dev) imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels))); - if (of_machine_is_compatible("fsl,imx6qp") + if (of_machine_is_compatible("fsl,imx6qp") { + clk_dm(IMX6QDL_CLK_UART_SEL, + imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, + ARRAY_SIZE(uart_sels))); clk_dm(IMX6QDL_CLK_ECSPI_SEL, imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels))); + } clk_dm(IMX6QDL_CLK_USDHC1_PODF, imx_clk_divider("usdhc1_podf", "usdhc1_sel", @@ -97,12 +102,17 @@ static int imx6q_clk_probe(struct udevice *dev) imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3)); - if (of_machine_is_compatible("fsl,imx6qp") + if (of_machine_is_compatible("fsl,imx6qp") { + clk_dm(IMX6QDL_CLK_UART_SERIAL_PODF, + imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6)); clk_dm(IMX6QDL_CLK_ECSPI_ROOT, imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6)); - else + } else { + clk_dm(IMX6QDL_CLK_UART_SERIAL_PODF, + imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6)); clk_dm(IMX6QDL_CLK_ECSPI_ROOT, imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6)); + } clk_dm(IMX6QDL_CLK_ECSPI1, imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0)); @@ -112,6 +122,10 @@ static int imx6q_clk_probe(struct udevice *dev) imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4)); clk_dm(IMX6QDL_CLK_ECSPI4, imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6)); + clk_dm(IMX6QDL_CLK_UART_IPG, + imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24)); + clk_dm(IMX6QDL_CLK_UART_SERIAL, + imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26)); clk_dm(IMX6QDL_CLK_USDHC1, imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2)); clk_dm(IMX6QDL_CLK_USDHC2, From 6f87ad540f3ec282227b3e092b89df1d283d292b Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:23 -0500 Subject: [PATCH 09/16] clk: imx8mm: register UART clocks In order to let the serial driver enable the clocks, the UART clocks must be registered first. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- drivers/clk/imx/clk-imx8mm.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index bb6958f0ec2..378c07caba3 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -81,6 +81,22 @@ static const char * const imx8mm_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m" "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; +static const char * const imx8mm_uart1_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", + "audio_pll2_out", }; + +static const char * const imx8mm_uart2_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", + "audio_pll2_out", }; + +static const char * const imx8mm_uart3_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", + "audio_pll2_out", }; + +static const char * const imx8mm_uart4_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", + "audio_pll2_out", }; + #if CONFIG_IS_ENABLED(PCIE_DW_IMX) static const char * const imx8mm_pcie1_ctrl_sels[] = {"clock-osc-24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m", @@ -322,6 +338,24 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00)); clk_dm(IMX8MM_CLK_I2C4, imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80)); + + clk_dm(IMX8MM_CLK_UART1, + imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00)); + clk_dm(IMX8MM_CLK_UART2, + imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80)); + clk_dm(IMX8MM_CLK_UART3, + imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000)); + clk_dm(IMX8MM_CLK_UART4, + imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080)); + clk_dm(IMX8MM_CLK_UART1_ROOT, + imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0)); + clk_dm(IMX8MM_CLK_UART2_ROOT, + imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0)); + clk_dm(IMX8MM_CLK_UART3_ROOT, + imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0)); + clk_dm(IMX8MM_CLK_UART4_ROOT, + imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0)); + clk_dm(IMX8MM_CLK_WDOG, imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900)); clk_dm(IMX8MM_CLK_USDHC3, From 1a14a71cc2c29d69277aaa033f45b048cfc1ab73 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:24 -0500 Subject: [PATCH 10/16] clk: imx8mn: register UART clocks In order to let the serial driver enable the clocks, the UART clocks must be registered first. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- drivers/clk/imx/clk-imx8mn.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index be15ebd0e25..54ae887817a 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -97,6 +97,22 @@ static const char * const imx8mn_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m" "sys_pll3_out", "audio_pll1_out", "video_pll_out", "audio_pll2_out", "sys_pll1_133m", }; +static const char * const imx8mn_uart1_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + +static const char * const imx8mn_uart2_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mn_uart3_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + +static const char * const imx8mn_uart4_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + #ifndef CONFIG_XPL_BUILD static const char * const imx8mn_pwm1_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", "sys_pll3_out", "clk_ext1", @@ -311,6 +327,14 @@ static int imx8mn_clk_probe(struct udevice *dev) imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00)); clk_dm(IMX8MN_CLK_I2C4, imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80)); + clk_dm(IMX8MN_CLK_UART1, + imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00)); + clk_dm(IMX8MN_CLK_UART2, + imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80)); + clk_dm(IMX8MN_CLK_UART3, + imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000)); + clk_dm(IMX8MN_CLK_UART4, + imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080)); clk_dm(IMX8MN_CLK_WDOG, imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900)); clk_dm(IMX8MN_CLK_USDHC3, @@ -355,6 +379,14 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand)); + clk_dm(IMX8MN_CLK_UART1_ROOT, + imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0)); + clk_dm(IMX8MN_CLK_UART2_ROOT, + imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0)); + clk_dm(IMX8MN_CLK_UART3_ROOT, + imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0)); + clk_dm(IMX8MN_CLK_UART4_ROOT, + imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0)); clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT, imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); From 5f7694e7eff56d1ef1ef7de55b4d7d8575860dbc Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:25 -0500 Subject: [PATCH 11/16] serial: mxc: Support bulk enabling clocks Depending on the platform, there may be multiple clock sources required to enable a UART. Use the bulk functions to get and enable the clocks when the UART probes. This can facilitate the removal of functions to manually enable the clock. This is made dependent on CLK_CCF which is used on imx6q, imx8m[mnqp], several imxrt, imx9. If/when the UART clock registration is done for older boards, this limitation could be updated. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- drivers/serial/serial_mxc.c | 11 +++++++++++ include/dm/platform_data/serial_mxc.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index c5fd740be4d..28f4435d01d 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -3,6 +3,7 @@ * (c) 2007 Sascha Hauer */ +#include #include #include #include @@ -312,7 +313,17 @@ int mxc_serial_setbrg(struct udevice *dev, int baudrate) static int mxc_serial_probe(struct udevice *dev) { struct mxc_serial_plat *plat = dev_get_plat(dev); +#if CONFIG_IS_ENABLED(CLK_CCF) + int ret; + ret = clk_get_bulk(dev, &plat->clks); + if (ret) + return ret; + + ret = clk_enable_bulk(&plat->clks); + if (ret) + return ret; +#endif _mxc_serial_init(plat->reg, plat->use_dte); return 0; diff --git a/include/dm/platform_data/serial_mxc.h b/include/dm/platform_data/serial_mxc.h index cc59eeb1dd1..52657aa3deb 100644 --- a/include/dm/platform_data/serial_mxc.h +++ b/include/dm/platform_data/serial_mxc.h @@ -9,6 +9,9 @@ /* Information about a serial port */ struct mxc_serial_plat { struct mxc_uart *reg; /* address of registers in physical memory */ +#if CONFIG_IS_ENABLED(CLK_CCF) + struct clk_bulk clks; +#endif bool use_dte; }; From 664d3192d8a0e49e472b2a7ba9c9c81ec615b903 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:26 -0500 Subject: [PATCH 12/16] board: beacon: imx8mm: Let clock system enable UART clock Now that the UART driver can enable the required clocks, remove the hard-coded clock enable. This requires a small re-order of a couple functions. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- board/beacon/imx8mm/spl.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/board/beacon/imx8mm/spl.c b/board/beacon/imx8mm/spl.c index 12013aa5a4d..93ee5b7ee0c 100644 --- a/board/beacon/imx8mm/spl.c +++ b/board/beacon/imx8mm/spl.c @@ -100,9 +100,6 @@ void board_init_f(ulong dummy) int ret; arch_cpu_init(); - - init_uart_clk(1); - timer_init(); /* Clear the BSS. */ @@ -114,8 +111,6 @@ void board_init_f(ulong dummy) hang(); } - preloader_console_init(); - ret = uclass_get_device_by_name(UCLASS_CLK, "clock-controller@30380000", &dev); @@ -124,6 +119,7 @@ void board_init_f(ulong dummy) hang(); } + preloader_console_init(); enable_tzc380(); power_init_board(); From 03fe27b22a5705efabaaa6febe37f6aed2c08cca Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:27 -0500 Subject: [PATCH 13/16] board: beacon: imx8mn: Let clock system enable UART clock Now that the UART driver can enable the required clocks, remove the hard-coded clock enable. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- board/beacon/imx8mn/spl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/board/beacon/imx8mn/spl.c b/board/beacon/imx8mn/spl.c index f03841e5a01..e91d3fdcf5e 100644 --- a/board/beacon/imx8mn/spl.c +++ b/board/beacon/imx8mn/spl.c @@ -111,8 +111,6 @@ int board_early_init_f(void) /* Claiming pwm pins prevents LCD flicker during startup*/ imx_iomux_v3_setup_multiple_pads(pwm_pads, ARRAY_SIZE(pwm_pads)); - init_uart_clk(1); - return 0; } From 9b4bc717fff6ed98d2feb770f49246bf4e1a9f84 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:28 -0500 Subject: [PATCH 14/16] clk: imx: select SPL_CLK_COMPOSITE_CCF when SPL_CLK_IMX8MP If SPL_CLK_IMX8MP is selected alone, it causes a build error. The clock composite is required when using the clock framework, so select it when SPL_CLK_IMX8MP is enabled. This is already being done outside of SPL. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- drivers/clk/imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 56d893e0579..d17a54fb9b3 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -60,6 +60,7 @@ config SPL_CLK_IMX8MP depends on ARCH_IMX8M && SPL select SPL_CLK select SPL_CLK_CCF + select SPL_CLK_COMPOSITE_CCF help This enables SPL DM/DTS support for clock driver in i.MX8MP From 11c09096ee02e54d049855d7f85e00f5b43c3b53 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:29 -0500 Subject: [PATCH 15/16] configs: imx8mp_beacon: Select SPL_CLK_IMX8MP In preparation to remove manual references for enabling some clocks, enable SPL_CLK_IMX8MP which automatically enables SPL_CCF and SPL_CLK_COMPOSITE_CCF which permit various drivers to activate their respective clocks automatically. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- configs/imx8mp_beacon_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/imx8mp_beacon_defconfig b/configs/imx8mp_beacon_defconfig index f39e4f5dd28..9709f628f9c 100644 --- a/configs/imx8mp_beacon_defconfig +++ b/configs/imx8mp_beacon_defconfig @@ -86,6 +86,7 @@ CONFIG_USE_ETHPRIME=y CONFIG_ETHPRIME="eth1" CONFIG_SPL_DM=y CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_IMX8MP=y CONFIG_CLK_IMX8MP=y CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x42800000 From ef609b86c24f8da0f3745aa232041c9a4e90cd3c Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 11 Mar 2025 19:30:30 -0500 Subject: [PATCH 16/16] board: beacon: imx8mp: Let clock system enable UART clock Now that the UART driver can enable the required clocks, remove the hard-coded clock enable. Signed-off-by: Adam Ford Reviewed-by: Peng Fan --- board/beacon/imx8mp/spl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/board/beacon/imx8mp/spl.c b/board/beacon/imx8mp/spl.c index 30d577f7e0e..6b357d90a3f 100644 --- a/board/beacon/imx8mp/spl.c +++ b/board/beacon/imx8mp/spl.c @@ -112,8 +112,6 @@ void board_init_f(ulong dummy) arch_cpu_init(); - init_uart_clk(1); - ret = spl_early_init(); if (ret) { debug("spl_init() failed: %d\n", ret);