Message ID | 20230903205703.662080-5-dario.binacchi@amarulasolutions.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
On 9/3/23 22:57, Dario Binacchi wrote: > Add support to Orise Tech OTM8009A display on stm32f469-disco board. > > It was necessary to retrieve the framebuffer address from the device tree > because the address returned by the video-uclass driver pointed to a memory > area that was not usable. > > Furthermore, unlike Linux, the DSI driver requires the LTDC clock to be > properly probed. Hence, the changes made to the DSI node in > stm32f469-disco-u-boot.dtsi. > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> > --- > > arch/arm/dts/stm32f469-disco-u-boot.dtsi | 4 +++ > configs/stm32f469-discovery_defconfig | 13 +++++++++ > drivers/video/stm32/stm32_ltdc.c | 37 +++++++++++++++++++++++- > 3 files changed, 53 insertions(+), 1 deletion(-) > > diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi > index 8e781c5a7b23..47ba9fa4a783 100644 > --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi > +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi > @@ -92,7 +92,9 @@ > > &dsi { > clocks = <&rcc 0 STM32F4_APB2_CLOCK(DSI)>, > + <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>, > <&clk_hse>; > + clock-names = "pclk", "px_clk", "ref"; > }; > > &gpioa { > @@ -140,6 +142,8 @@ > }; > > <dc { > + bootph-all; > + > clocks = <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>; > }; > > diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig > index 35d18d58be6f..9796b8f2d9a5 100644 > --- a/configs/stm32f469-discovery_defconfig > +++ b/configs/stm32f469-discovery_defconfig > @@ -21,6 +21,7 @@ CONFIG_CMD_GPT=y > # CONFIG_RANDOM_UUID is not set > CONFIG_CMD_MMC=y > # CONFIG_CMD_SETEXPR is not set > +CONFIG_CMD_BMP=y > CONFIG_CMD_CACHE=y > CONFIG_CMD_TIMER=y > # CONFIG_ISO_PARTITION is not set > @@ -40,3 +41,15 @@ CONFIG_SPI_FLASH_STMICRO=y > CONFIG_SPI=y > CONFIG_DM_SPI=y > CONFIG_STM32_QSPI=y > +CONFIG_VIDEO=y > +CONFIG_BACKLIGHT_GPIO=y > +CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y > +CONFIG_VIDEO_STM32=y > +CONFIG_VIDEO_STM32_DSI=y > +CONFIG_VIDEO_STM32_MAX_XRES=480 > +CONFIG_VIDEO_STM32_MAX_YRES=800 > +CONFIG_BMP_16BPP=y > +CONFIG_BMP_24BPP=y > +CONFIG_BMP_32BPP=y > +CONFIG_DM_REGULATOR=y > +CONFIG_DM_REGULATOR_FIXED=y > diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c > index f48badc517a8..428b0addc43c 100644 > --- a/drivers/video/stm32/stm32_ltdc.c > +++ b/drivers/video/stm32/stm32_ltdc.c > @@ -494,6 +494,34 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) > setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN); > } > > +#if IS_ENABLED(CONFIG_TARGET_STM32F469_DISCOVERY) We want to avoid this kind of #define specific to a particular target > +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, > + uint align) > +{ > + phys_addr_t cpu; > + dma_addr_t bus; > + u64 dma_size; > + int ret; > + > + ret = dev_get_dma_range(dev, &cpu, &bus, &dma_size); > + if (ret) { > + dev_err(dev, "failed to get dma address\n"); > + return ret; > + } > + > + *base = bus + 0x1000000 - ALIGN(size, align); Why adding 0x1000000 ? avoid to insert const whithout any description and use a #define instead. > + return 0; > +} > +#else > +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, > + uint align) > +{ > + /* Delegate framebuffer allocation to video-uclass */ > + *base = 0; > + return 0; > +} > +#endif > + > static int stm32_ltdc_probe(struct udevice *dev) > { > struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); > @@ -504,7 +532,7 @@ static int stm32_ltdc_probe(struct udevice *dev) > struct display_timing timings; > struct clk pclk; > struct reset_ctl rst; > - ulong rate; > + ulong rate, fb_base; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > @@ -604,6 +632,13 @@ static int stm32_ltdc_probe(struct udevice *dev) > priv->crop_h = timings.vactive.typ; > priv->alpha = 0xFF; > > + ret = stm32_ltdc_get_fb_addr(dev, &fb_base, uc_plat->size, > + uc_plat->align); > + if (ret) > + return ret; > + > + uc_plat->base = fb_base; > + It breaks display on stm32f746-disco and also on stm32f769-disco. Thanks Patrice > dev_dbg(dev, "%dx%d %dbpp frame buffer at 0x%lx\n", > timings.hactive.typ, timings.vactive.typ, > VNBITS(priv->l2bpp), uc_plat->base);
Hello Patrice, On Wed, Sep 27, 2023 at 8:19 AM Patrice CHOTARD <patrice.chotard@foss.st.com> wrote: > > > > On 9/3/23 22:57, Dario Binacchi wrote: > > Add support to Orise Tech OTM8009A display on stm32f469-disco board. > > > > It was necessary to retrieve the framebuffer address from the device tree > > because the address returned by the video-uclass driver pointed to a memory > > area that was not usable. > > > > Furthermore, unlike Linux, the DSI driver requires the LTDC clock to be > > properly probed. Hence, the changes made to the DSI node in > > stm32f469-disco-u-boot.dtsi. > > > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> > > --- > > > > arch/arm/dts/stm32f469-disco-u-boot.dtsi | 4 +++ > > configs/stm32f469-discovery_defconfig | 13 +++++++++ > > drivers/video/stm32/stm32_ltdc.c | 37 +++++++++++++++++++++++- > > 3 files changed, 53 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi > > index 8e781c5a7b23..47ba9fa4a783 100644 > > --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi > > +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi > > @@ -92,7 +92,9 @@ > > > > &dsi { > > clocks = <&rcc 0 STM32F4_APB2_CLOCK(DSI)>, > > + <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>, > > <&clk_hse>; > > + clock-names = "pclk", "px_clk", "ref"; > > }; > > > > &gpioa { > > @@ -140,6 +142,8 @@ > > }; > > > > <dc { > > + bootph-all; > > + > > clocks = <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>; > > }; > > > > diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig > > index 35d18d58be6f..9796b8f2d9a5 100644 > > --- a/configs/stm32f469-discovery_defconfig > > +++ b/configs/stm32f469-discovery_defconfig > > @@ -21,6 +21,7 @@ CONFIG_CMD_GPT=y > > # CONFIG_RANDOM_UUID is not set > > CONFIG_CMD_MMC=y > > # CONFIG_CMD_SETEXPR is not set > > +CONFIG_CMD_BMP=y > > CONFIG_CMD_CACHE=y > > CONFIG_CMD_TIMER=y > > # CONFIG_ISO_PARTITION is not set > > @@ -40,3 +41,15 @@ CONFIG_SPI_FLASH_STMICRO=y > > CONFIG_SPI=y > > CONFIG_DM_SPI=y > > CONFIG_STM32_QSPI=y > > +CONFIG_VIDEO=y > > +CONFIG_BACKLIGHT_GPIO=y > > +CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y > > +CONFIG_VIDEO_STM32=y > > +CONFIG_VIDEO_STM32_DSI=y > > +CONFIG_VIDEO_STM32_MAX_XRES=480 > > +CONFIG_VIDEO_STM32_MAX_YRES=800 > > +CONFIG_BMP_16BPP=y > > +CONFIG_BMP_24BPP=y > > +CONFIG_BMP_32BPP=y > > +CONFIG_DM_REGULATOR=y > > +CONFIG_DM_REGULATOR_FIXED=y > > diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c > > index f48badc517a8..428b0addc43c 100644 > > --- a/drivers/video/stm32/stm32_ltdc.c > > +++ b/drivers/video/stm32/stm32_ltdc.c > > @@ -494,6 +494,34 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) > > setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN); > > } > > > > +#if IS_ENABLED(CONFIG_TARGET_STM32F469_DISCOVERY) > > We want to avoid this kind of #define specific to a particular target If the framebuffer is allocated by the video-uclass module, it is mapped to the address 0xe00000, which does not appear to be a correct memory zone. Therefore, for the stm32f469-disco board, a different method for framebuffer allocation is required, and this seemed to me the most suitable way. I have submitted the series as an RFC, and this is one of the points for which I did it. So, I am open to considering any suggestions you may have. Output in case of applied patch: stm32_display display-controller@40016800: 480x800 16bpp frame buffer at 0xc0e00000 Otherwise: stm32_display display-controller@40016800: 480x800 16bpp frame buffer at 0xe00000 > > > +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, > > + uint align) > > +{ > > + phys_addr_t cpu; > > + dma_addr_t bus; > > + u64 dma_size; > > + int ret; > > + > > + ret = dev_get_dma_range(dev, &cpu, &bus, &dma_size); > > + if (ret) { > > + dev_err(dev, "failed to get dma address\n"); > > + return ret; > > + } > > + > > + *base = bus + 0x1000000 - ALIGN(size, align); > > Why adding 0x1000000 ? avoid to insert const whithout any description and use a #define instead. Right, I will add it in version 2. > > > + return 0; > > +} > > +#else > > +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, > > + uint align) > > +{ > > + /* Delegate framebuffer allocation to video-uclass */ > > + *base = 0; > > + return 0; > > +} > > +#endif > > + > > static int stm32_ltdc_probe(struct udevice *dev) > > { > > struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); > > @@ -504,7 +532,7 @@ static int stm32_ltdc_probe(struct udevice *dev) > > struct display_timing timings; > > struct clk pclk; > > struct reset_ctl rst; > > - ulong rate; > > + ulong rate, fb_base; > > int ret; > > > > priv->regs = dev_read_addr_ptr(dev); > > @@ -604,6 +632,13 @@ static int stm32_ltdc_probe(struct udevice *dev) > > priv->crop_h = timings.vactive.typ; > > priv->alpha = 0xFF; > > > > + ret = stm32_ltdc_get_fb_addr(dev, &fb_base, uc_plat->size, > > + uc_plat->align); > > + if (ret) > > + return ret; > > + > > + uc_plat->base = fb_base; > > + > > It breaks display on stm32f746-disco and also on stm32f769-disco. You are right, I will fix it in version 2. Thanks and regards, Dario > > Thanks > Patrice > > > dev_dbg(dev, "%dx%d %dbpp frame buffer at 0x%lx\n", > > timings.hactive.typ, timings.vactive.typ, > > VNBITS(priv->l2bpp), uc_plat->base);
diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi index 8e781c5a7b23..47ba9fa4a783 100644 --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi @@ -92,7 +92,9 @@ &dsi { clocks = <&rcc 0 STM32F4_APB2_CLOCK(DSI)>, + <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>, <&clk_hse>; + clock-names = "pclk", "px_clk", "ref"; }; &gpioa { @@ -140,6 +142,8 @@ }; <dc { + bootph-all; + clocks = <&rcc 0 STM32F4_APB2_CLOCK(LTDC)>; }; diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig index 35d18d58be6f..9796b8f2d9a5 100644 --- a/configs/stm32f469-discovery_defconfig +++ b/configs/stm32f469-discovery_defconfig @@ -21,6 +21,7 @@ CONFIG_CMD_GPT=y # CONFIG_RANDOM_UUID is not set CONFIG_CMD_MMC=y # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_BMP=y CONFIG_CMD_CACHE=y CONFIG_CMD_TIMER=y # CONFIG_ISO_PARTITION is not set @@ -40,3 +41,15 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_STM32_QSPI=y +CONFIG_VIDEO=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y +CONFIG_VIDEO_STM32=y +CONFIG_VIDEO_STM32_DSI=y +CONFIG_VIDEO_STM32_MAX_XRES=480 +CONFIG_VIDEO_STM32_MAX_YRES=800 +CONFIG_BMP_16BPP=y +CONFIG_BMP_24BPP=y +CONFIG_BMP_32BPP=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c index f48badc517a8..428b0addc43c 100644 --- a/drivers/video/stm32/stm32_ltdc.c +++ b/drivers/video/stm32/stm32_ltdc.c @@ -494,6 +494,34 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN); } +#if IS_ENABLED(CONFIG_TARGET_STM32F469_DISCOVERY) +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, + uint align) +{ + phys_addr_t cpu; + dma_addr_t bus; + u64 dma_size; + int ret; + + ret = dev_get_dma_range(dev, &cpu, &bus, &dma_size); + if (ret) { + dev_err(dev, "failed to get dma address\n"); + return ret; + } + + *base = bus + 0x1000000 - ALIGN(size, align); + return 0; +} +#else +static int stm32_ltdc_get_fb_addr(struct udevice *dev, ulong *base, uint size, + uint align) +{ + /* Delegate framebuffer allocation to video-uclass */ + *base = 0; + return 0; +} +#endif + static int stm32_ltdc_probe(struct udevice *dev) { struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); @@ -504,7 +532,7 @@ static int stm32_ltdc_probe(struct udevice *dev) struct display_timing timings; struct clk pclk; struct reset_ctl rst; - ulong rate; + ulong rate, fb_base; int ret; priv->regs = dev_read_addr_ptr(dev); @@ -604,6 +632,13 @@ static int stm32_ltdc_probe(struct udevice *dev) priv->crop_h = timings.vactive.typ; priv->alpha = 0xFF; + ret = stm32_ltdc_get_fb_addr(dev, &fb_base, uc_plat->size, + uc_plat->align); + if (ret) + return ret; + + uc_plat->base = fb_base; + dev_dbg(dev, "%dx%d %dbpp frame buffer at 0x%lx\n", timings.hactive.typ, timings.vactive.typ, VNBITS(priv->l2bpp), uc_plat->base);
Add support to Orise Tech OTM8009A display on stm32f469-disco board. It was necessary to retrieve the framebuffer address from the device tree because the address returned by the video-uclass driver pointed to a memory area that was not usable. Furthermore, unlike Linux, the DSI driver requires the LTDC clock to be properly probed. Hence, the changes made to the DSI node in stm32f469-disco-u-boot.dtsi. Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> --- arch/arm/dts/stm32f469-disco-u-boot.dtsi | 4 +++ configs/stm32f469-discovery_defconfig | 13 +++++++++ drivers/video/stm32/stm32_ltdc.c | 37 +++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-)