[PATCH 0/5] Fix i.MXRT1050 hang on lcdif init and improve DT for mxsfb

This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
Giulio Benetti (5): video: mxsfb: add enabling of "axi" clock other than "per" clock video: mxsfb: add enabling of "disp_axi" clock clk: imx: clk-imxrt1050: introduce LCDIF_PIX and rename LCDIF to LCDIF_APB ARM: dts: imxrt1050: move lcdif assigned clock to dtsi ARM: dts: imxrt1050: set lcdif clocks according to mxsfb driver
arch/arm/dts/imxrt1050-evk.dts | 3 -- arch/arm/dts/imxrt1050.dtsi | 7 ++-- drivers/clk/imx/clk-imxrt1050.c | 6 ++-- drivers/video/mxsfb.c | 36 +++++++++++++++++---- include/dt-bindings/clock/imxrt1050-clock.h | 5 +-- 5 files changed, 41 insertions(+), 16 deletions(-)

On some SoC mxsfb needs more than one clock gate(actual "per" clock). So let's introduce "axi" clock that can be provided but it's not mandatory. This is inspired from linux mxsfb driver. Also let's rename "per" clock to "pix" clock for compatibility with already existing .dts lcdif nodes implementation.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/video/mxsfb.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index e1fd36a62d..147bd668fe 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -67,26 +67,37 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, uint32_t vdctrl0;
#if CONFIG_IS_ENABLED(CLK) - struct clk per_clk; + struct clk clk; int ret;
- ret = clk_get_by_name(dev, "per", &per_clk); + ret = clk_get_by_name(dev, "pix", &clk); if (ret) { - dev_err(dev, "Failed to get mxs clk: %d\n", ret); + dev_err(dev, "Failed to get mxs pix clk: %d\n", ret); return; }
- ret = clk_set_rate(&per_clk, timings->pixelclock.typ); + ret = clk_set_rate(&clk, timings->pixelclock.typ); if (ret < 0) { - dev_err(dev, "Failed to set mxs clk: %d\n", ret); + dev_err(dev, "Failed to set mxs pix clk: %d\n", ret); return; }
- ret = clk_enable(&per_clk); + ret = clk_enable(&clk); if (ret < 0) { - dev_err(dev, "Failed to enable mxs clk: %d\n", ret); + dev_err(dev, "Failed to enable mxs pix clk: %d\n", ret); return; } + + ret = clk_get_by_name(dev, "axi", &clk); + if (!ret) { + debug("%s: Failed to get mxs axi clk: %d\n", __func__, ret); + } else { + ret = clk_enable(&clk); + if (ret < 0) { + dev_err(dev, "Failed to enable mxs axi clk: %d\n", ret); + return; + } + } #else /* Kick in the LCDIF clock */ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);

Some SoC needs "disp_axi" clock to be enabled, so let's try to retrieve it and enabling. If it fails it gives only a debug(), but this clock as well as "axi" clock is not mandatory.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/video/mxsfb.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 147bd668fe..523d8a8d98 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -98,6 +98,17 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, return; } } + + ret = clk_get_by_name(dev, "disp_axi", &clk); + if (!ret) { + debug("%s: Failed to get mxs disp_axi clk: %d\n", __func__, ret); + } else { + ret = clk_enable(&clk); + if (ret < 0) { + dev_err(dev, "Failed to enable mxs disp_axi clk: %d\n", ret); + return; + } + } #else /* Kick in the LCDIF clock */ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);

Lcd peripheral needs 2 different gates to be enable to work, so let's introduce the missing one(LCDIF_PIX) and rename the existing one (LCDIF_APB).
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/clk/imx/clk-imxrt1050.c | 6 ++++-- include/dt-bindings/clock/imxrt1050-clock.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c index 594093ee5f..eb6847f865 100644 --- a/drivers/clk/imx/clk-imxrt1050.c +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -255,8 +255,10 @@ static int imxrt1050_clk_probe(struct udevice *dev) imx_clk_gate2("lpuart1", "lpuart_podf", base + 0x7c, 24)); clk_dm(IMXRT1050_CLK_SEMC, imx_clk_gate2("semc", "semc_podf", base + 0x74, 4)); - clk_dm(IMXRT1050_CLK_LCDIF, - imx_clk_gate2("lcdif", "lcdif_podf", base + 0x74, 10)); + clk_dm(IMXRT1050_CLK_LCDIF_APB, + imx_clk_gate2("lcdif", "lcdif_podf", base + 0x70, 28)); + clk_dm(IMXRT1050_CLK_LCDIF_PIX, + imx_clk_gate2("lcdif_pix", "lcdif", base + 0x74, 10));
struct clk *clk, *clk1;
diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h index c174f90c1a..09b65e5df2 100644 --- a/include/dt-bindings/clock/imxrt1050-clock.h +++ b/include/dt-bindings/clock/imxrt1050-clock.h @@ -52,7 +52,7 @@ #define IMXRT1050_CLK_USDHC2 43 #define IMXRT1050_CLK_LPUART1 44 #define IMXRT1050_CLK_SEMC 45 -#define IMXRT1050_CLK_LCDIF 46 +#define IMXRT1050_CLK_LCDIF_APB 46 #define IMXRT1050_CLK_PLL1_ARM 47 #define IMXRT1050_CLK_PLL2_SYS 48 #define IMXRT1050_CLK_PLL3_USB_OTG 49 @@ -60,6 +60,7 @@ #define IMXRT1050_CLK_PLL5_VIDEO 51 #define IMXRT1050_CLK_PLL6_ENET 52 #define IMXRT1050_CLK_PLL7_USB_HOST 53 -#define IMXRT1050_CLK_END 54 +#define IMXRT1050_CLK_LCDIF_PIX 54 +#define IMXRT1050_CLK_END 55
#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */

Since we assume pll5 is the default lcdif clock source let's move assigned-clocks(-parents) properties to .dtsi file.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 3 --- arch/arm/dts/imxrt1050.dtsi | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index 2052d4eb4e..dc66fc9c37 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -238,9 +238,6 @@ display = <&display0>; status = "okay";
- assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; - assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; - display0: display0 { bits-per-pixel = <16>; bus-width = <16>; diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index 6f9da3fe8a..eb5e09e971 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -152,6 +152,8 @@ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMXRT1050_CLK_LCDIF>; clock-names = "per"; + assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; + assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; status = "disabled"; };

Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index eb5e09e971..ec1eb88e45 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -150,8 +150,9 @@ compatible = "fsl,imxrt-lcdif"; reg = <0x402b8000 0x4000>; interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMXRT1050_CLK_LCDIF>; - clock-names = "per"; + clocks = <&clks IMXRT1050_CLK_LCDIF_PIX>, + <&clks IMXRT1050_CLK_LCDIF_APB>; + clock-names = "pix", "axi"; assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; status = "disabled";

On 4/13/21 1:03 AM, Giulio Benetti wrote:
This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
I've forgotten to specify that this patchset depends on this patchset: https://patchwork.ozlabs.org/project/uboot/list/?series=237909
Best regards

On 4/13/21 1:05 AM, Giulio Benetti wrote:
On 4/13/21 1:03 AM, Giulio Benetti wrote:
This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
I've forgotten to specify that this patchset depends on this patchset: https://patchwork.ozlabs.org/project/uboot/list/?series=237909
This ^^^ series is superseeded by v2: https://patchwork.ozlabs.org/project/uboot/list/?series=241701
Best regards

Hi Stefano,
On 5/2/21 1:44 AM, Giulio Benetti wrote:
On 4/13/21 1:05 AM, Giulio Benetti wrote:
On 4/13/21 1:03 AM, Giulio Benetti wrote:
This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
I've forgotten to specify that this patchset depends on this patchset: https://patchwork.ozlabs.org/project/uboot/list/?series=237909
This ^^^ series is superseeded by v2: https://patchwork.ozlabs.org/project/uboot/list/?series=241701
Current patchset is not superseeded, only the one which depends to is superseeded by v2. Do you prefer me to send a unique patchset with all patches of both patchsets?
Kind regards

Hi Giulio,
On 13.05.21 00:12, Giulio Benetti wrote:
Hi Stefano,
On 5/2/21 1:44 AM, Giulio Benetti wrote:
On 4/13/21 1:05 AM, Giulio Benetti wrote:
On 4/13/21 1:03 AM, Giulio Benetti wrote:
This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
I've forgotten to specify that this patchset depends on this patchset: https://patchwork.ozlabs.org/project/uboot/list/?series=237909
This ^^^ series is superseeded by v2: https://patchwork.ozlabs.org/project/uboot/list/?series=241701
Current patchset is not superseeded, only the one which depends to is superseeded by v2. Do you prefer me to send a unique patchset with all patches of both patchsets?
Yes, or in patchset becomes a mess. Please send a complete series, thanks !
Best regards, Stefano

This patchset adds imx-gpt-timer driver that is supported by i.MXRT and also a lot of other i.MX* SoCs. This driver is needed for i.MXRT SoC family that is lacking at the moment the timer at all and that makes u-boot to fail running on i.MXRT. There are also some fixes in imxrt10*0-evk.dts and other minor fixed and improvements and specifically on imxrt1050 has been fixed lcdif init hang.
--- V1->V2: * fixed 32 to 64 bit conversion on timer as suggested by Sean Anderson V2->V3: * merge with patchset with https://patchwork.ozlabs.org/project/uboot/list/?series=238842&state=* that fixes lcdif init hang * improve some commit log ---
Giulio Benetti (22): arm: imxrt: soc: make mpu regions generic timer: imx-gpt: Add timer support for i.MX SoCs family ARM: dts: imxrt1020: add node label to osc ARM: dts: imxrt1020: add gpt1 node ARM: dts: imxrt1020-evk: enable gpt1 timer ARM: dts: imxrt1020-evk: set gpt1 as tick-timer for u-boot ARM: dts: imxrt1020-evk-u-boot: make gpt1 present for SPL ARM: dts: imxrt1020-evk: add device_type = "memory" to memory node configs: imxrt1020-evk: enable imx gpt timer as tick-timer ARM: dts: imxrt1050: add node label to osc ARM: dts: imxrt1050: add gpt1 node ARM: dts: imxrt1050-evk: enable gpt1 timer ARM: dts: imxrt1050-evk: set gpt1 as tick-timer for u-boot ARM: dts: imxrt1050-evk-u-boot: make gpt1 present for SPL ARM: dts: imxrt1050-evk: add device_type = "memory" to memory node configs: imxrt1050-evk: enable imx gpt timer as tick-timer video: mxsfb: add enabling of "axi" clock other than "per" clock video: mxsfb: add enabling of "disp_axi" clock clk: imx: clk-imxrt1050: introduce LCDIF_PIX and rename LCDIF to LCDIF_APB ARM: dts: imxrt1050: move lcdif assigned clock to dtsi ARM: dts: imxrt1050: set lcdif clocks according to mxsfb driver ARM: dts: imxrt1050-evk: remove u-boot,dm-spl
arch/arm/dts/imxrt1020-evk-u-boot.dtsi | 4 + arch/arm/dts/imxrt1020-evk.dts | 6 + arch/arm/dts/imxrt1020.dtsi | 10 +- arch/arm/dts/imxrt1050-evk-u-boot.dtsi | 4 + arch/arm/dts/imxrt1050-evk.dts | 10 +- arch/arm/dts/imxrt1050.dtsi | 17 +- arch/arm/mach-imx/imxrt/soc.c | 6 +- configs/imxrt1020-evk_defconfig | 1 + configs/imxrt1050-evk_defconfig | 1 + drivers/clk/imx/clk-imxrt1050.c | 6 +- drivers/timer/Kconfig | 7 + drivers/timer/Makefile | 1 + drivers/timer/imx-gpt-timer.c | 162 ++++++++++++++++++++ drivers/video/mxsfb.c | 36 ++++- include/dt-bindings/clock/imxrt1050-clock.h | 5 +- 15 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 drivers/timer/imx-gpt-timer.c

This patchset adds imx-gpt-timer driver that is supported by i.MXRT and also a lot of other i.MX* SoCs. This driver is needed for i.MXRT SoC family that is lacking at the moment the timer at all and that makes u-boot to fail running on i.MXRT. There are also some fixes in imxrt10*0-evk.dts and other minor fixed and improvements and specifically on imxrt1050 has been fixed lcdif init hang.
--- V1->V2: * fixed 32 to 64 bit conversion on timer as suggested by Sean Anderson V2->V3: * merge with patchset with https://patchwork.ozlabs.org/project/uboot/list/?series=238842&state=* that fixes lcdif init hang * improve some commit log ---
Giulio Benetti (22): arm: imxrt: soc: make mpu regions generic timer: imx-gpt: Add timer support for i.MX SoCs family ARM: dts: imxrt1020: add node label to osc ARM: dts: imxrt1020: add gpt1 node ARM: dts: imxrt1020-evk: enable gpt1 timer ARM: dts: imxrt1020-evk: set gpt1 as tick-timer for u-boot ARM: dts: imxrt1020-evk-u-boot: make gpt1 present for SPL ARM: dts: imxrt1020-evk: add device_type = "memory" to memory node configs: imxrt1020-evk: enable imx gpt timer as tick-timer ARM: dts: imxrt1050: add node label to osc ARM: dts: imxrt1050: add gpt1 node ARM: dts: imxrt1050-evk: enable gpt1 timer ARM: dts: imxrt1050-evk: set gpt1 as tick-timer for u-boot ARM: dts: imxrt1050-evk-u-boot: make gpt1 present for SPL ARM: dts: imxrt1050-evk: add device_type = "memory" to memory node configs: imxrt1050-evk: enable imx gpt timer as tick-timer video: mxsfb: add enabling of "axi" clock other than "per" clock video: mxsfb: add enabling of "disp_axi" clock clk: imx: clk-imxrt1050: introduce LCDIF_PIX and rename LCDIF to LCDIF_APB ARM: dts: imxrt1050: move lcdif assigned clock to dtsi ARM: dts: imxrt1050: set lcdif clocks according to mxsfb driver ARM: dts: imxrt1050-evk: remove u-boot,dm-spl
arch/arm/dts/imxrt1020-evk-u-boot.dtsi | 4 + arch/arm/dts/imxrt1020-evk.dts | 6 + arch/arm/dts/imxrt1020.dtsi | 10 +- arch/arm/dts/imxrt1050-evk-u-boot.dtsi | 4 + arch/arm/dts/imxrt1050-evk.dts | 10 +- arch/arm/dts/imxrt1050.dtsi | 17 +- arch/arm/mach-imx/imxrt/soc.c | 6 +- configs/imxrt1020-evk_defconfig | 1 + configs/imxrt1050-evk_defconfig | 1 + drivers/clk/imx/clk-imxrt1050.c | 6 +- drivers/timer/Kconfig | 7 + drivers/timer/Makefile | 1 + drivers/timer/imx-gpt-timer.c | 162 ++++++++++++++++++++ drivers/video/mxsfb.c | 36 ++++- include/dt-bindings/clock/imxrt1050-clock.h | 5 +- 15 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 drivers/timer/imx-gpt-timer.c

This mpu handling works for every i.MXRT SoC that we have, so let's generalize imxrt1050_region_config to imxrt_region_config.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/mach-imx/imxrt/soc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-imx/imxrt/soc.c b/arch/arm/mach-imx/imxrt/soc.c index 8e7d15160d..c533f3554a 100644 --- a/arch/arm/mach-imx/imxrt/soc.c +++ b/arch/arm/mach-imx/imxrt/soc.c @@ -14,7 +14,7 @@ int arch_cpu_init(void) { int i;
- struct mpu_region_config imxrt1050_region_config[] = { + struct mpu_region_config imxrt_region_config[] = { { 0x00000000, REGION_0, XN_DIS, PRIV_RW_USR_RW, STRONG_ORDER, REGION_4GB }, { PHYS_SDRAM, REGION_1, XN_DIS, PRIV_RW_USR_RW, @@ -29,8 +29,8 @@ int arch_cpu_init(void) * the whole 4GB address space. */ disable_mpu(); - for (i = 0; i < ARRAY_SIZE(imxrt1050_region_config); i++) - mpu_config(&imxrt1050_region_config[i]); + for (i = 0; i < ARRAY_SIZE(imxrt_region_config); i++) + mpu_config(&imxrt_region_config[i]); enable_mpu();
return 0;

This mpu handling works for every i.MXRT SoC that we have, so let's generalize imxrt1050_region_config to imxrt_region_config. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

This timer driver uses GPT Timer (General Purpose Timer) available on a lot of i.MX SoCs family. This driver deals with both 24Mhz oscillator as well as peripheral clock.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com [Giulio: added the driver's stub and handled peripheral clock prescaler setting making driver to work correctly] Signed-off-by: Jesse Taube mr.bossman075@gmail.com [Jesse: added init, setting prescaler for 24Mhz support and enabling timer] --- drivers/timer/Kconfig | 7 ++ drivers/timer/Makefile | 1 + drivers/timer/imx-gpt-timer.c | 162 ++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 drivers/timer/imx-gpt-timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 80743a2551..ee81dfa776 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -227,4 +227,11 @@ config MCHP_PIT64B_TIMER Select this to enable support for Microchip 64-bit periodic interval timer.
+config IMX_GPT_TIMER + bool "NXP i.MX GPT timer support" + depends on TIMER + help + Select this to enable support for the timer found on + NXP i.MX devices. + endmenu diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index eb5c48cc6c..e214ba7268 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_STM32_TIMER) += stm32_timer.o obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_MTK_TIMER) += mtk_timer.o obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o +obj-$(CONFIG_IMX_GPT_TIMER) += imx-gpt-timer.o diff --git a/drivers/timer/imx-gpt-timer.c b/drivers/timer/imx-gpt-timer.c new file mode 100644 index 0000000000..72be297754 --- /dev/null +++ b/drivers/timer/imx-gpt-timer.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 + * Author(s): Giulio Benetti giulio.benetti@benettiengineering.com + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <fdtdec.h> +#include <timer.h> +#include <dm/device_compat.h> + +#include <asm/io.h> + +#define GPT_CR_EN BIT(0) +#define GPT_CR_FRR BIT(9) +#define GPT_CR_EN_24M BIT(10) +#define GPT_CR_SWR BIT(15) + +#define GPT_PR_PRESCALER24M_MASK 0x0000F000 +#define GPT_PR_PRESCALER24M_SHIFT 12 +#define GPT_PR_PRESCALER24M_MAX (GPT_PR_PRESCALER24M_MASK >> GPT_PR_PRESCALER24M_SHIFT) +#define GPT_PR_PRESCALER_MASK 0x00000FFF +#define GPT_PR_PRESCALER_SHIFT 0 +#define GPT_PR_PRESCALER_MAX (GPT_PR_PRESCALER_MASK >> GPT_PR_PRESCALER_SHIFT) + +#define GPT_CLKSRC_IPG_CLK (1 << 6) +#define GPT_CLKSRC_IPG_CLK_24M (5 << 6) + +/* If CONFIG_SYS_HZ_CLOCK not specified et's default to 3Mhz */ +#ifndef CONFIG_SYS_HZ_CLOCK +#define CONFIG_SYS_HZ_CLOCK 3000000 +#endif + +struct imx_gpt_timer_regs { + u32 cr; + u32 pr; + u32 sr; + u32 ir; + u32 ocr1; + u32 ocr2; + u32 ocr3; + u32 icr1; + u32 icr2; + u32 cnt; +}; + +struct imx_gpt_timer_priv { + struct imx_gpt_timer_regs *base; +}; + +static u64 imx_gpt_timer_get_count(struct udevice *dev) +{ + struct imx_gpt_timer_priv *priv = dev_get_priv(dev); + struct imx_gpt_timer_regs *regs = priv->base; + + return timer_conv_64(readl(®s->cnt)); +} + +static int imx_gpt_setup(struct imx_gpt_timer_regs *regs, u32 rate) +{ + u32 prescaler = (rate / CONFIG_SYS_HZ_CLOCK) - 1; + + /* Reset the timer */ + setbits_le32(®s->cr, GPT_CR_SWR); + + /* Wait for timer to finish reset */ + while (readl(®s->cr) & GPT_CR_SWR) + ; + + if (rate == 24000000UL) { + /* Set timer frequency if using 24M clock source */ + if (prescaler > GPT_PR_PRESCALER24M_MAX) + return -EINVAL; + + /* Set 24M prescaler */ + writel((prescaler << GPT_PR_PRESCALER24M_SHIFT), ®s->pr); + /* Set Oscillator as clock source, enable 24M input and set gpt + * in free-running mode + */ + writel(GPT_CLKSRC_IPG_CLK_24M | GPT_CR_EN_24M | GPT_CR_FRR, ®s->cr); + } else { + if (prescaler > GPT_PR_PRESCALER_MAX) + return -EINVAL; + + /* Set prescaler */ + writel((prescaler << GPT_PR_PRESCALER_SHIFT), ®s->pr); + /* Set Peripheral as clock source and set gpt in free-running + * mode + */ + writel(GPT_CLKSRC_IPG_CLK | GPT_CR_FRR, ®s->cr); + } + + /* Start timer */ + setbits_le32(®s->cr, GPT_CR_EN); + + return 0; +} + +static int imx_gpt_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct imx_gpt_timer_priv *priv = dev_get_priv(dev); + struct imx_gpt_timer_regs *regs; + struct clk clk; + fdt_addr_t addr; + u32 clk_rate; + int ret; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = (struct imx_gpt_timer_regs *)addr; + regs = priv->base; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + if (ret) { + dev_err(dev, "Failed to enable clock\n"); + return ret; + } + + /* Get timer clock rate */ + clk_rate = clk_get_rate(&clk); + if (clk_rate <= 0) { + dev_err(dev, "Could not get clock rate...\n"); + return -EINVAL; + } + + ret = imx_gpt_setup(regs, clk_rate); + if (ret) { + dev_err(dev, "Could not setup timer\n"); + return ret; + } + + uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK; + + return 0; +} + +static const struct timer_ops imx_gpt_timer_ops = { + .get_count = imx_gpt_timer_get_count, +}; + +static const struct udevice_id imx_gpt_timer_ids[] = { + { .compatible = "fsl,imxrt-gpt" }, + {} +}; + +U_BOOT_DRIVER(imx_gpt_timer) = { + .name = "imx_gpt_timer", + .id = UCLASS_TIMER, + .of_match = imx_gpt_timer_ids, + .priv_auto = sizeof(struct imx_gpt_timer_priv), + .probe = imx_gpt_timer_probe, + .ops = &imx_gpt_timer_ops, +};

This timer driver uses GPT Timer (General Purpose Timer) available on a lot of i.MX SoCs family. This driver deals with both 24Mhz oscillator as well as peripheral clock. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com [Giulio: added the driver's stub and handled peripheral clock prescaler setting making driver to work correctly] Signed-off-by: Jesse Taube mr.bossman075@gmail.com [Jesse: added init, setting prescaler for 24Mhz support and enabling timer]
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's add node label to osc to be used as clock source for other nodes.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/imxrt1020.dtsi b/arch/arm/dts/imxrt1020.dtsi index 97f3cec9f3..0a3a3b451a 100644 --- a/arch/arm/dts/imxrt1020.dtsi +++ b/arch/arm/dts/imxrt1020.dtsi @@ -36,7 +36,7 @@ clock-frequency = <0>; };
- osc { + osc: osc { u-boot,dm-spl; compatible = "fsl,imx-osc", "fixed-clock"; #clock-cells = <0>;

Let's add node label to osc to be used as clock source for other nodes. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Add gpt1 node for using it as timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/imxrt1020.dtsi b/arch/arm/dts/imxrt1020.dtsi index 0a3a3b451a..cab608c644 100644 --- a/arch/arm/dts/imxrt1020.dtsi +++ b/arch/arm/dts/imxrt1020.dtsi @@ -129,5 +129,13 @@ interrupt-controller; #interrupt-cells = <2>; }; + + gpt1: gpt1@401ec000 { + compatible = "fsl,imxrt-gpt"; + reg = <0x401ec000 0x4000>; + interrupts = <100>; + clocks = <&osc>; + status = "disabled"; + }; }; };

Add gpt1 node for using it as timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Enable gpt1 timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020-evk.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/imxrt1020-evk.dts b/arch/arm/dts/imxrt1020-evk.dts index ece13601bd..a471ff3838 100644 --- a/arch/arm/dts/imxrt1020-evk.dts +++ b/arch/arm/dts/imxrt1020-evk.dts @@ -186,6 +186,10 @@ }; };
+&gpt1 { + status = "okay"; +}; + &usdhc1 { pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; pinctrl-0 = <&pinctrl_usdhc0>;

Enable gpt1 timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's set gpt1 as u-boot timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020-evk.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/imxrt1020-evk.dts b/arch/arm/dts/imxrt1020-evk.dts index a471ff3838..b527206fcf 100644 --- a/arch/arm/dts/imxrt1020-evk.dts +++ b/arch/arm/dts/imxrt1020-evk.dts @@ -16,6 +16,7 @@ chosen { bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; + tick-timer = &gpt1; };
memory {

Let's set gpt1 as u-boot timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Timer needs to be already enabled in spl, so let's add its node to spl dtb.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020-evk-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/imxrt1020-evk-u-boot.dtsi b/arch/arm/dts/imxrt1020-evk-u-boot.dtsi index d32c98de9c..34d19e06c5 100644 --- a/arch/arm/dts/imxrt1020-evk-u-boot.dtsi +++ b/arch/arm/dts/imxrt1020-evk-u-boot.dtsi @@ -10,6 +10,10 @@ }; };
+&gpt1 { + u-boot,dm-spl; +}; + &lpuart1 { /* console */ u-boot,dm-spl; };

Timer needs to be already enabled in spl, so let's add its node to spl dtb. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Now device_type = "memory" is mandatory to allow u-boot to read memory node, so let's add it to memory node.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1020-evk.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/imxrt1020-evk.dts b/arch/arm/dts/imxrt1020-evk.dts index b527206fcf..2da79e5c20 100644 --- a/arch/arm/dts/imxrt1020-evk.dts +++ b/arch/arm/dts/imxrt1020-evk.dts @@ -20,6 +20,7 @@ };
memory { + device_type = "memory"; reg = <0x80000000 0x2000000>; }; };

Now device_type = "memory" is mandatory to allow u-boot to read memory node, so let's add it to memory node. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's enable imx-gpt-timer in imx1020-evk defconfig.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- configs/imxrt1020-evk_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/imxrt1020-evk_defconfig b/configs/imxrt1020-evk_defconfig index ad408ebef8..f0b05b7165 100644 --- a/configs/imxrt1020-evk_defconfig +++ b/configs/imxrt1020-evk_defconfig @@ -61,6 +61,7 @@ CONFIG_IMXRT_SDRAM=y CONFIG_FSL_LPUART=y CONFIG_TIMER=y CONFIG_SPL_TIMER=y +CONFIG_IMX_GPT_TIMER=y CONFIG_SHA1=y CONFIG_SHA256=y CONFIG_HEXDUMP=y

Let's enable imx-gpt-timer in imx1020-evk defconfig. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's add node label to osc to be used as clock source for other nodes.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index a9281001e5..b7cc3fbc2a 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -28,7 +28,7 @@ clocks { u-boot,dm-spl;
- osc { + osc: osc { u-boot,dm-spl; compatible = "fsl,imx-osc", "fixed-clock"; #clock-cells = <0>;

Let's add node label to osc to be used as clock source for other nodes. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Add gpt1 node for using it as timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index b7cc3fbc2a..6f9da3fe8a 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -154,5 +154,13 @@ clock-names = "per"; status = "disabled"; }; + + gpt1: gpt1@401ec000 { + compatible = "fsl,imxrt-gpt"; + reg = <0x401ec000 0x4000>; + interrupts = <100>; + clocks = <&osc>; + status = "disabled"; + }; }; };

Add gpt1 node for using it as timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Enable gpt1 timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index b5e781275e..e592330332 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -215,6 +215,10 @@ }; };
+&gpt1 { + status = "okay"; +}; + &usdhc1 { pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; pinctrl-0 = <&pinctrl_usdhc0>;

Enable gpt1 timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's set gpt1 as u-boot timer.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index e592330332..6d21f2b738 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -16,6 +16,7 @@ chosen { bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; + tick-timer = &gpt1; };
memory {

Let's set gpt1 as u-boot timer. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Timer needs to be already enabled in spl, so let's add its node to spl dtb.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/dts/imxrt1050-evk-u-boot.dtsi b/arch/arm/dts/imxrt1050-evk-u-boot.dtsi index fb4f7f6f9d..a4b50f0bb2 100644 --- a/arch/arm/dts/imxrt1050-evk-u-boot.dtsi +++ b/arch/arm/dts/imxrt1050-evk-u-boot.dtsi @@ -10,6 +10,10 @@ }; };
+&gpt1 { + u-boot,dm-spl; +}; + &lpuart1 { /* console */ u-boot,dm-spl; };

Timer needs to be already enabled in spl, so let's add its node to spl dtb. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Now device_type = "memory" is mandatory to allow u-boot to read memory node, so let's add it to memory node.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index 6d21f2b738..2052d4eb4e 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -20,6 +20,7 @@ };
memory { + device_type = "memory"; reg = <0x80000000 0x2000000>; }; };

Now device_type = "memory" is mandatory to allow u-boot to read memory node, so let's add it to memory node. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Let's enable imx-gpt-timer in imx1050-evk defconfig.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- configs/imxrt1050-evk_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/imxrt1050-evk_defconfig b/configs/imxrt1050-evk_defconfig index d03572e7db..9c8bdb07dc 100644 --- a/configs/imxrt1050-evk_defconfig +++ b/configs/imxrt1050-evk_defconfig @@ -64,6 +64,7 @@ CONFIG_IMXRT_SDRAM=y CONFIG_FSL_LPUART=y CONFIG_TIMER=y CONFIG_SPL_TIMER=y +CONFIG_IMX_GPT_TIMER=y CONFIG_DM_VIDEO=y CONFIG_BACKLIGHT_GPIO=y CONFIG_SYS_WHITE_ON_BLACK=y

Let's enable imx-gpt-timer in imx1050-evk defconfig. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

On some SoC mxsfb needs more than one clock gate(actual "per" clock). So let's introduce "axi" clock that can be provided but it's not mandatory. This is inspired from linux mxsfb driver. Also let's rename "per" clock to "pix" clock for compatibility with already existing .dts lcdif nodes implementation.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/video/mxsfb.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index e1fd36a62d..147bd668fe 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -67,26 +67,37 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, uint32_t vdctrl0;
#if CONFIG_IS_ENABLED(CLK) - struct clk per_clk; + struct clk clk; int ret;
- ret = clk_get_by_name(dev, "per", &per_clk); + ret = clk_get_by_name(dev, "pix", &clk); if (ret) { - dev_err(dev, "Failed to get mxs clk: %d\n", ret); + dev_err(dev, "Failed to get mxs pix clk: %d\n", ret); return; }
- ret = clk_set_rate(&per_clk, timings->pixelclock.typ); + ret = clk_set_rate(&clk, timings->pixelclock.typ); if (ret < 0) { - dev_err(dev, "Failed to set mxs clk: %d\n", ret); + dev_err(dev, "Failed to set mxs pix clk: %d\n", ret); return; }
- ret = clk_enable(&per_clk); + ret = clk_enable(&clk); if (ret < 0) { - dev_err(dev, "Failed to enable mxs clk: %d\n", ret); + dev_err(dev, "Failed to enable mxs pix clk: %d\n", ret); return; } + + ret = clk_get_by_name(dev, "axi", &clk); + if (!ret) { + debug("%s: Failed to get mxs axi clk: %d\n", __func__, ret); + } else { + ret = clk_enable(&clk); + if (ret < 0) { + dev_err(dev, "Failed to enable mxs axi clk: %d\n", ret); + return; + } + } #else /* Kick in the LCDIF clock */ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);

On some SoC mxsfb needs more than one clock gate(actual "per" clock). So let's introduce "axi" clock that can be provided but it's not mandatory. This is inspired from linux mxsfb driver. Also let's rename "per" clock to "pix" clock for compatibility with already existing .dts lcdif nodes implementation. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Some SoC needs "disp_axi" clock to be enabled, so let's try to retrieve it and enabling. If it fails it gives only a debug(), but this clock as well as "axi" clock is not mandatory.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/video/mxsfb.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 147bd668fe..523d8a8d98 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -98,6 +98,17 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, return; } } + + ret = clk_get_by_name(dev, "disp_axi", &clk); + if (!ret) { + debug("%s: Failed to get mxs disp_axi clk: %d\n", __func__, ret); + } else { + ret = clk_enable(&clk); + if (ret < 0) { + dev_err(dev, "Failed to enable mxs disp_axi clk: %d\n", ret); + return; + } + } #else /* Kick in the LCDIF clock */ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);

Some SoC needs "disp_axi" clock to be enabled, so let's try to retrieve it and enabling. If it fails it gives only a debug(), but this clock as well as "axi" clock is not mandatory. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Some SoC needs "disp_axi" clock to be enabled, so let's try to retrieve it and enabling. If it fails it gives only a debug(), but this clock as well as "axi" clock is not mandatory.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/video/mxsfb.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 147bd668fe..523d8a8d98 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -98,6 +98,17 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, return; } } + + ret = clk_get_by_name(dev, "disp_axi", &clk); + if (!ret) { + debug("%s: Failed to get mxs disp_axi clk: %d\n", __func__, ret); + } else { + ret = clk_enable(&clk); + if (ret < 0) { + dev_err(dev, "Failed to enable mxs disp_axi clk: %d\n", ret); + return; + } + } #else /* Kick in the LCDIF clock */ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);

Lcd peripheral needs 2 different gates to be enable to work, so let's introduce the missing one(LCDIF_PIX) and rename the existing one (LCDIF_APB).
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/clk/imx/clk-imxrt1050.c | 6 ++++-- include/dt-bindings/clock/imxrt1050-clock.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c index 594093ee5f..eb6847f865 100644 --- a/drivers/clk/imx/clk-imxrt1050.c +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -255,8 +255,10 @@ static int imxrt1050_clk_probe(struct udevice *dev) imx_clk_gate2("lpuart1", "lpuart_podf", base + 0x7c, 24)); clk_dm(IMXRT1050_CLK_SEMC, imx_clk_gate2("semc", "semc_podf", base + 0x74, 4)); - clk_dm(IMXRT1050_CLK_LCDIF, - imx_clk_gate2("lcdif", "lcdif_podf", base + 0x74, 10)); + clk_dm(IMXRT1050_CLK_LCDIF_APB, + imx_clk_gate2("lcdif", "lcdif_podf", base + 0x70, 28)); + clk_dm(IMXRT1050_CLK_LCDIF_PIX, + imx_clk_gate2("lcdif_pix", "lcdif", base + 0x74, 10));
struct clk *clk, *clk1;
diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h index c174f90c1a..09b65e5df2 100644 --- a/include/dt-bindings/clock/imxrt1050-clock.h +++ b/include/dt-bindings/clock/imxrt1050-clock.h @@ -52,7 +52,7 @@ #define IMXRT1050_CLK_USDHC2 43 #define IMXRT1050_CLK_LPUART1 44 #define IMXRT1050_CLK_SEMC 45 -#define IMXRT1050_CLK_LCDIF 46 +#define IMXRT1050_CLK_LCDIF_APB 46 #define IMXRT1050_CLK_PLL1_ARM 47 #define IMXRT1050_CLK_PLL2_SYS 48 #define IMXRT1050_CLK_PLL3_USB_OTG 49 @@ -60,6 +60,7 @@ #define IMXRT1050_CLK_PLL5_VIDEO 51 #define IMXRT1050_CLK_PLL6_ENET 52 #define IMXRT1050_CLK_PLL7_USB_HOST 53 -#define IMXRT1050_CLK_END 54 +#define IMXRT1050_CLK_LCDIF_PIX 54 +#define IMXRT1050_CLK_END 55
#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */

Lcd peripheral needs 2 different gates to be enable to work, so let's introduce the missing one(LCDIF_PIX) and rename the existing one (LCDIF_APB). Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Since we assume pll5 is the default lcdif clock source let's move assigned-clocks(-parents) properties to .dtsi file.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 3 --- arch/arm/dts/imxrt1050.dtsi | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index 2052d4eb4e..dc66fc9c37 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -238,9 +238,6 @@ display = <&display0>; status = "okay";
- assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; - assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; - display0: display0 { bits-per-pixel = <16>; bus-width = <16>; diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index 6f9da3fe8a..eb5e09e971 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -152,6 +152,8 @@ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMXRT1050_CLK_LCDIF>; clock-names = "per"; + assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; + assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; status = "disabled"; };

Since we assume pll5 is the default lcdif clock source let's move assigned-clocks(-parents) properties to .dtsi file. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Lcdif needs both "pix" and "axi" clocks to be enabled so let's add them to lcdif node.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index eb5e09e971..ec1eb88e45 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -150,8 +150,9 @@ compatible = "fsl,imxrt-lcdif"; reg = <0x402b8000 0x4000>; interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMXRT1050_CLK_LCDIF>; - clock-names = "per"; + clocks = <&clks IMXRT1050_CLK_LCDIF_PIX>, + <&clks IMXRT1050_CLK_LCDIF_APB>; + clock-names = "pix", "axi"; assigned-clocks = <&clks IMXRT1050_CLK_LCDIF_SEL>; assigned-clock-parents = <&clks IMXRT1050_CLK_PLL5_VIDEO>; status = "disabled";

Lcdif needs both "pix" and "axi" clocks to be enabled so let's add them to lcdif node. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

We don't need lcdif to be enable in SPL, so let's remove u-boot,dm-spl.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index dc66fc9c37..81db1a446d 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -189,7 +189,6 @@ };
pinctrl_lcdif: lcdifgrp { - u-boot,dm-spl; fsl,pins = < MXRT1050_IOMUXC_GPIO_B0_00_LCD_CLK 0x1b0b1 MXRT1050_IOMUXC_GPIO_B0_01_LCD_ENABLE 0x1b0b1

We don't need lcdif to be enable in SPL, so let's remove u-boot,dm-spl. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Sorry for this patch sent twice. My e-mail provider doesn't let me send more than 18 e-mail at a time, so I need to send it in 2 times and I've left this.
Best regards

Hi Stefano,
On 5/13/21 10:14 AM, Stefano Babic wrote:
Hi Giulio,
On 13.05.21 00:12, Giulio Benetti wrote:
Hi Stefano,
On 5/2/21 1:44 AM, Giulio Benetti wrote:
On 4/13/21 1:05 AM, Giulio Benetti wrote:
On 4/13/21 1:03 AM, Giulio Benetti wrote:
This patchset fixes u-boot hang on i.MXRT1050 while setting lcdif in mxsfb driver. There are 2 gates to be enabled to initialize mxsfb so let's introduce the missing gate as a clock and rename "per" clock to "pix" clock since in the other .dts files using *-lcdif "pix" is used.
This patchset add also "disp_axi" clock enabling in mxsfb that should make able to every i.MX SoC with lcdif using DT. I didn't test it other than i.MXRT1050 since I don't have the boards. If someone can test it it would be great. Note that i.MX23/28 should fail using DT instead because they don't specify any clock-names in their dts.
I've forgotten to specify that this patchset depends on this patchset: https://patchwork.ozlabs.org/project/uboot/list/?series=237909
This ^^^ series is superseeded by v2: https://patchwork.ozlabs.org/project/uboot/list/?series=241701
Current patchset is not superseeded, only the one which depends to is superseeded by v2. Do you prefer me to send a unique patchset with all patches of both patchsets?
Yes, or in patchset becomes a mess. Please send a complete series, thanks !
Well I've merged in a unique patchset both patchsets[1], sorry for my e-mail mess.
[1]: https://patchwork.ozlabs.org/project/uboot/list/?series=243591
Best regards
participants (3)
-
Giulio Benetti
-
sbabic@denx.de
-
Stefano Babic