[PATCH 0/4] clk-imx8mm: Reduce SPL binary size

Reduce the SPL binary size by building some clocks only for the non-SPL case, such as Ethernet and PWM and by also building ECSPI and QSPI when their respective drivers are enabled.
On a imx8mm_evk_defconfig the following SPL binary reduction was observed.
Prior to this series:
$ aarch64-linux-gnu-readelf -s spl/u-boot-spl | sort -nk 3 | grep imx8mm_clk_probe 766: 00000000007f34c8 4100 FUNC LOCAL DEFAULT 1 imx8mm_clk_probe
After this series:
$ aarch64-linux-gnu-readelf -s spl/u-boot-spl | sort -nk 3 | grep imx8mm_clk_probe 766: 00000000007f34c8 3316 FUNC LOCAL DEFAULT 1 imx8mm_clk_probe
Total reduction: 4100 - 3316 = 784 bytes.
Fabio Estevam (4): clk-imx8mm: Only build PWM clocks in non-SPL code clk-imx8mm: Move CLK_ENET_AXI to the non-SPL section clk-imx8mm: Only build ecspi clocks when CONFIG_DM_SPI=y clk-imx8mm: Only build QSPI clocks when CONFIG_NXP_FSPI=y
drivers/clk/imx/clk-imx8mm.c | 86 ++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 37 deletions(-)

PWM is not used inside SPL, so do not define the PWM clocks inside SPL to reduce the final SPL binary size.
Signed-off-by: Fabio Estevam festevam@denx.de --- drivers/clk/imx/clk-imx8mm.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 542aa31f7a..0d7891f11a 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -66,6 +66,7 @@ static const char *imx8mm_i2c3_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_ static const char *imx8mm_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+#ifndef CONFIG_SPL_BUILD static const char *imx8mm_pwm1_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
@@ -77,6 +78,7 @@ static const char *imx8mm_pwm3_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_
static const char *imx8mm_pwm4_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", }; +#endif
static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", }; @@ -267,14 +269,6 @@ 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_PWM1, - imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380)); - clk_dm(IMX8MM_CLK_PWM2, - imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400)); - clk_dm(IMX8MM_CLK_PWM3, - imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480)); - clk_dm(IMX8MM_CLK_PWM4, - imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500)); clk_dm(IMX8MM_CLK_WDOG, imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900)); clk_dm(IMX8MM_CLK_USDHC3, @@ -309,14 +303,6 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0)); clk_dm(IMX8MM_CLK_OCOTP_ROOT, imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0)); - clk_dm(IMX8MM_CLK_PWM1_ROOT, - imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0)); - clk_dm(IMX8MM_CLK_PWM2_ROOT, - imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0)); - clk_dm(IMX8MM_CLK_PWM3_ROOT, - imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0)); - clk_dm(IMX8MM_CLK_PWM4_ROOT, - imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); clk_dm(IMX8MM_CLK_USDHC1_ROOT, imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0)); clk_dm(IMX8MM_CLK_USDHC2_ROOT, @@ -348,6 +334,22 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0)); + clk_dm(IMX8MM_CLK_PWM1, + imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380)); + clk_dm(IMX8MM_CLK_PWM2, + imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400)); + clk_dm(IMX8MM_CLK_PWM3, + imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480)); + clk_dm(IMX8MM_CLK_PWM4, + imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500)); + clk_dm(IMX8MM_CLK_PWM1_ROOT, + imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0)); + clk_dm(IMX8MM_CLK_PWM2_ROOT, + imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0)); + clk_dm(IMX8MM_CLK_PWM3_ROOT, + imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0)); + clk_dm(IMX8MM_CLK_PWM4_ROOT, + imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); #endif
return 0;

PWM is not used inside SPL, so do not define the PWM clocks inside SPL to reduce the final SPL binary size. Signed-off-by: Fabio Estevam festevam@denx.de
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Ethernet is not used inside SPL, so move the IMX8MM_CLK_ENET_AXI clock inside the non-SPL block to reduce the final SPL binary size.
Signed-off-by: Fabio Estevam festevam@denx.de --- drivers/clk/imx/clk-imx8mm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 0d7891f11a..286915982c 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -28,10 +28,10 @@ static const char *imx8mm_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll static const char *imx8mm_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+#ifndef CONFIG_SPL_BUILD static const char *imx8mm_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
-#ifndef CONFIG_SPL_BUILD static const char *imx8mm_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
@@ -244,9 +244,6 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_IPG_ROOT, imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
- clk_dm(IMX8MM_CLK_ENET_AXI, - imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, - base + 0x8880)); clk_dm(IMX8MM_CLK_NAND_USDHC_BUS, imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, @@ -322,6 +319,9 @@ static int imx8mm_clk_probe(struct udevice *dev)
/* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD + clk_dm(IMX8MM_CLK_ENET_AXI, + imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, + base + 0x8880)); clk_dm(IMX8MM_CLK_ENET_REF, imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980));

Ethernet is not used inside SPL, so move the IMX8MM_CLK_ENET_AXI clock inside the non-SPL block to reduce the final SPL binary size. Signed-off-by: Fabio Estevam festevam@denx.de
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

The ecspi clocks are only used when CONFIG_DM_SPI=y, so only build the ecspi clocks in this case to reduce the final SPL binary size.
Signed-off-by: Fabio Estevam festevam@denx.de --- drivers/clk/imx/clk-imx8mm.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 286915982c..b6a289b01d 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -95,6 +95,7 @@ static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", " static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+#if CONFIG_IS_ENABLED(DM_SPI) static const char *imx8mm_ecspi1_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
@@ -103,6 +104,7 @@ static const char *imx8mm_ecspi2_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sy
static const char *imx8mm_ecspi3_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; +#endif
static int imx8mm_clk_probe(struct udevice *dev) { @@ -277,19 +279,6 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); clk_dm(IMX8MM_CLK_USB_PHY_REF, imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180)); - clk_dm(IMX8MM_CLK_ECSPI1, - imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280)); - clk_dm(IMX8MM_CLK_ECSPI2, - imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300)); - clk_dm(IMX8MM_CLK_ECSPI3, - imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180)); - - clk_dm(IMX8MM_CLK_ECSPI1_ROOT, - imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); - clk_dm(IMX8MM_CLK_ECSPI2_ROOT, - imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); - clk_dm(IMX8MM_CLK_ECSPI3_ROOT, - imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); clk_dm(IMX8MM_CLK_I2C2_ROOT, @@ -352,6 +341,22 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); #endif
+#if CONFIG_IS_ENABLED(DM_SPI) + clk_dm(IMX8MM_CLK_ECSPI1, + imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280)); + clk_dm(IMX8MM_CLK_ECSPI2, + imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300)); + clk_dm(IMX8MM_CLK_ECSPI3, + imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180)); + + clk_dm(IMX8MM_CLK_ECSPI1_ROOT, + imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); + clk_dm(IMX8MM_CLK_ECSPI2_ROOT, + imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); + clk_dm(IMX8MM_CLK_ECSPI3_ROOT, + imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); +#endif + return 0; }

The ecspi clocks are only used when CONFIG_DM_SPI=y, so only build the ecspi clocks in this case to reduce the final SPL binary size. Signed-off-by: Fabio Estevam festevam@denx.de
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

The QSPI clocks are only used when CONFIG_NXP_FSPI=y, so only build the QSPI clocks in this case to reduce the final SPL binary size.
Signed-off-by: Fabio Estevam festevam@denx.de --- drivers/clk/imx/clk-imx8mm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index b6a289b01d..b5c253e496 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -86,8 +86,10 @@ static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+#if CONFIG_IS_ENABLED(NXP_FSPI) static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; +#endif
static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; @@ -273,8 +275,6 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80)); - clk_dm(IMX8MM_CLK_QSPI, - imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); clk_dm(IMX8MM_CLK_USB_CORE_REF, imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); clk_dm(IMX8MM_CLK_USB_PHY_REF, @@ -301,8 +301,6 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); - clk_dm(IMX8MM_CLK_QSPI_ROOT, - imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); clk_dm(IMX8MM_CLK_USB1_CTRL_ROOT, imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
@@ -357,6 +355,13 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); #endif
+#if CONFIG_IS_ENABLED(NXP_FSPI) + clk_dm(IMX8MM_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); + clk_dm(IMX8MM_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); +#endif + return 0; }

The QSPI clocks are only used when CONFIG_NXP_FSPI=y, so only build the QSPI clocks in this case to reduce the final SPL binary size. Signed-off-by: Fabio Estevam festevam@denx.de
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Hi Fabio
On Mon, Sep 26, 2022 at 6:40 PM Fabio Estevam festevam@denx.de wrote:
Reduce the SPL binary size by building some clocks only for the non-SPL case, such as Ethernet and PWM and by also building ECSPI and QSPI when their respective drivers are enabled.
On a imx8mm_evk_defconfig the following SPL binary reduction was observed.
Prior to this series:
$ aarch64-linux-gnu-readelf -s spl/u-boot-spl | sort -nk 3 | grep imx8mm_clk_probe 766: 00000000007f34c8 4100 FUNC LOCAL DEFAULT 1 imx8mm_clk_probe
After this series:
$ aarch64-linux-gnu-readelf -s spl/u-boot-spl | sort -nk 3 | grep imx8mm_clk_probe 766: 00000000007f34c8 3316 FUNC LOCAL DEFAULT 1 imx8mm_clk_probe
Total reduction: 4100 - 3316 = 784 bytes.
Fabio Estevam (4): clk-imx8mm: Only build PWM clocks in non-SPL code clk-imx8mm: Move CLK_ENET_AXI to the non-SPL section
I'm not really convinced of those two. I mean with should maybe think about some different approach of clock framework to reduce the size
Michael
clk-imx8mm: Only build ecspi clocks when CONFIG_DM_SPI=y clk-imx8mm: Only build QSPI clocks when CONFIG_NXP_FSPI=y
drivers/clk/imx/clk-imx8mm.c | 86 ++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 37 deletions(-)
-- 2.25.1

Hi Michael,
On 27/09/2022 09:24, Michael Nazzareno Trimarchi wrote:
Fabio Estevam (4): clk-imx8mm: Only build PWM clocks in non-SPL code clk-imx8mm: Move CLK_ENET_AXI to the non-SPL section
I'm not really convinced of those two. I mean with should maybe think about some different approach of clock framework to reduce the size
What is your proposal then?

Hi Fabio
On Tue, Sep 27, 2022 at 2:29 PM Fabio Estevam festevam@denx.de wrote:
Hi Michael,
On 27/09/2022 09:24, Michael Nazzareno Trimarchi wrote:
Fabio Estevam (4): clk-imx8mm: Only build PWM clocks in non-SPL code clk-imx8mm: Move CLK_ENET_AXI to the non-SPL section
I'm not really convinced of those two. I mean with should maybe think about some different approach of clock framework to reduce the size
What is your proposal then?
When Dario wrote the Ti clock, he was using the dtsi. One idea can be understand if this approch cost less in term of space in the SPL
Michael

Hi Michael,
On Tue, Sep 27, 2022 at 10:38 AM Michael Nazzareno Trimarchi michael@amarulasolutions.com wrote:
When Dario wrote the Ti clock, he was using the dtsi. One idea can be understand if this approch cost less in term of space in the SPL
Care to submit a patch series with your proposal?

Hi Fabio
On Tue, Sep 27, 2022 at 3:44 PM Fabio Estevam festevam@gmail.com wrote:
Hi Michael,
On Tue, Sep 27, 2022 at 10:38 AM Michael Nazzareno Trimarchi michael@amarulasolutions.com wrote:
When Dario wrote the Ti clock, he was using the dtsi. One idea can be understand if this approch cost less in term of space in the SPL
Care to submit a patch series with your proposal?
Our plan can be this one. We are soon sending some patches for imx Nand subsystems that introduce new clocks there. We use then this series to create a PoC where we move those clocks in dtsi format as in omap and then send it later
Michael
participants (4)
-
Fabio Estevam
-
Fabio Estevam
-
Michael Nazzareno Trimarchi
-
sbabic@denx.de