[U-Boot] [PATCH v2 16/18] at91: video: Support driver-model for the LCD driver
Andreas Bießmann
andreas at biessmann.org
Sat Jun 4 22:11:29 CEST 2016
On 05.05.16 15:28, Simon Glass wrote:
> Add driver-model support to this driver. Most features can be controlled
> from the device tree.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
Reviewed-by: Andreas Bießmann <andreas at biessmann.org>
> ---
>
> Changes in v2: None
>
> drivers/video/atmel_lcdfb.c | 91 +++++++++++++++++++++++++++++++++++++++++++++
> include/atmel_lcd.h | 9 +++++
> 2 files changed, 100 insertions(+)
>
> diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
> index 37838a8..39cd7ca 100644
> --- a/drivers/video/atmel_lcdfb.c
> +++ b/drivers/video/atmel_lcdfb.c
> @@ -7,7 +7,10 @@
> */
>
> #include <common.h>
> +#include <atmel_lcd.h>
> +#include <dm.h>
> #include <fdtdec.h>
> +#include <video.h>
> #include <asm/io.h>
> #include <asm/arch/gpio.h>
> #include <asm/arch/clk.h>
> @@ -15,6 +18,21 @@
> #include <bmp_layout.h>
> #include <atmel_lcdc.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#ifdef CONFIG_DM_VIDEO
> +enum {
> + /* Maximum LCD size we support */
> + LCD_MAX_WIDTH = 1366,
> + LCD_MAX_HEIGHT = 768,
> + LCD_MAX_LOG2_BPP = VIDEO_BPP16,
> +};
> +#endif
> +
> +struct atmel_fb_priv {
> + struct display_timing timing;
> +};
> +
> /* configurable parameters */
> #define ATMEL_LCDC_CVAL_DEFAULT 0xc8
> #define ATMEL_LCDC_DMA_BURST_LEN 8
> @@ -31,6 +49,7 @@
> #define lcdc_readl(mmio, reg) __raw_readl((mmio)+(reg))
> #define lcdc_writel(mmio, reg, val) __raw_writel((val), (mmio)+(reg))
>
> +#ifndef CONFIG_DM_VIDEO
> ushort *configuration_get_cmap(void)
> {
> return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
> @@ -91,6 +110,7 @@ void lcd_set_cmap(struct bmp_image *bmp, unsigned colors)
> lcd_setcolreg(i, cte.red, cte.green, cte.blue);
> }
> }
> +#endif
>
> static void atmel_fb_init(ulong addr, struct display_timing *timing, int bpix,
> bool tft, bool cont_pol_low, ulong lcdbase)
> @@ -190,6 +210,7 @@ static void atmel_fb_init(ulong addr, struct display_timing *timing, int bpix,
> (ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
> }
>
> +#ifndef CONFIG_DM_VIDEO
> void lcd_ctrl_init(void *lcdbase)
> {
> struct display_timing timing;
> @@ -221,3 +242,73 @@ ulong calc_fbsize(void)
> return ((panel_info.vl_col * panel_info.vl_row *
> NBITS(panel_info.vl_bpix)) / 8) + PAGE_SIZE;
> }
> +#endif
> +
> +#ifdef CONFIG_DM_VIDEO
> +static int atmel_fb_lcd_probe(struct udevice *dev)
> +{
> + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
> + struct video_priv *uc_priv = dev_get_uclass_priv(dev);
> + struct atmel_fb_priv *priv = dev_get_priv(dev);
> + struct display_timing *timing = &priv->timing;
> +
> + /*
> + * For now some values are hard-coded. We could use the device tree
> + * bindings in simple-framebuffer.txt to specify the format/bpp and
> + * some Atmel-specific binding for tft and cont_pol_low.
> + */
> + atmel_fb_init(ATMEL_BASE_LCDC, timing, VIDEO_BPP16, true, false,
> + uc_plat->base);
> + uc_priv->xsize = timing->hactive.typ;
> + uc_priv->ysize = timing->vactive.typ;
> + uc_priv->bpix = VIDEO_BPP16;
> + video_set_flush_dcache(dev, true);
> + debug("LCD frame buffer at %lx, size %x, %dx%d pixels\n", uc_plat->base,
> + uc_plat->size, uc_priv->xsize, uc_priv->ysize);
> +
> + return 0;
> +}
> +
> +static int atmel_fb_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct atmel_lcd_platdata *plat = dev_get_platdata(dev);
> + struct atmel_fb_priv *priv = dev_get_priv(dev);
> + struct display_timing *timing = &priv->timing;
> + const void *blob = gd->fdt_blob;
> +
> + if (fdtdec_decode_display_timing(blob, dev->of_offset,
> + plat->timing_index, timing)) {
> + debug("%s: Failed to decode display timing\n", __func__);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int atmel_fb_lcd_bind(struct udevice *dev)
> +{
> + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
> +
> + uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
> + (1 << VIDEO_BPP16) / 8;
> + debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
> +
> + return 0;
> +}
> +
> +static const struct udevice_id atmel_fb_lcd_ids[] = {
> + { .compatible = "atmel,at91sam9g45-lcdc" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(atmel_fb) = {
> + .name = "atmel_fb",
> + .id = UCLASS_VIDEO,
> + .of_match = atmel_fb_lcd_ids,
> + .bind = atmel_fb_lcd_bind,
> + .ofdata_to_platdata = atmel_fb_ofdata_to_platdata,
> + .probe = atmel_fb_lcd_probe,
> + .platdata_auto_alloc_size = sizeof(struct atmel_lcd_platdata),
> + .priv_auto_alloc_size = sizeof(struct atmel_fb_priv),
> +};
> +#endif
> diff --git a/include/atmel_lcd.h b/include/atmel_lcd.h
> index 6993128..8a2f46f 100644
> --- a/include/atmel_lcd.h
> +++ b/include/atmel_lcd.h
> @@ -10,6 +10,15 @@
> #ifndef _ATMEL_LCD_H_
> #define _ATMEL_LCD_H_
>
> +/**
> + * struct atmel_lcd_platdata - platform data for Atmel LCDs with driver model
> + *
> + * @timing_index: Index of LCD timing to use in device tree node
> + */
> +struct atmel_lcd_platdata {
> + int timing_index;
> +};
> +
> typedef struct vidinfo {
> ushort vl_col; /* Number of columns (i.e. 640) */
> ushort vl_row; /* Number of rows (i.e. 480) */
>
More information about the U-Boot
mailing list