Commit 9dc89a053d29deea73c39ef49c9f1c6cb4c38820

Authored by Simon Glass
Committed by Andreas Bießmann
1 parent d63ec26a49

at91: video: Support driver-model for the LCD driver

Add driver-model support to this driver. Most features can be controlled
from the device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Andreas Bießmann <andreas@biessmann.org>

Showing 2 changed files with 100 additions and 0 deletions Side-by-side Diff

drivers/video/atmel_lcdfb.c
... ... @@ -7,7 +7,10 @@
7 7 */
8 8  
9 9 #include <common.h>
  10 +#include <atmel_lcd.h>
  11 +#include <dm.h>
10 12 #include <fdtdec.h>
  13 +#include <video.h>
11 14 #include <asm/io.h>
12 15 #include <asm/arch/gpio.h>
13 16 #include <asm/arch/clk.h>
... ... @@ -15,6 +18,21 @@
15 18 #include <bmp_layout.h>
16 19 #include <atmel_lcdc.h>
17 20  
  21 +DECLARE_GLOBAL_DATA_PTR;
  22 +
  23 +#ifdef CONFIG_DM_VIDEO
  24 +enum {
  25 + /* Maximum LCD size we support */
  26 + LCD_MAX_WIDTH = 1366,
  27 + LCD_MAX_HEIGHT = 768,
  28 + LCD_MAX_LOG2_BPP = VIDEO_BPP16,
  29 +};
  30 +#endif
  31 +
  32 +struct atmel_fb_priv {
  33 + struct display_timing timing;
  34 +};
  35 +
18 36 /* configurable parameters */
19 37 #define ATMEL_LCDC_CVAL_DEFAULT 0xc8
20 38 #define ATMEL_LCDC_DMA_BURST_LEN 8
... ... @@ -31,6 +49,7 @@
31 49 #define lcdc_readl(mmio, reg) __raw_readl((mmio)+(reg))
32 50 #define lcdc_writel(mmio, reg, val) __raw_writel((val), (mmio)+(reg))
33 51  
  52 +#ifndef CONFIG_DM_VIDEO
34 53 ushort *configuration_get_cmap(void)
35 54 {
36 55 return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
... ... @@ -91,6 +110,7 @@
91 110 lcd_setcolreg(i, cte.red, cte.green, cte.blue);
92 111 }
93 112 }
  113 +#endif
94 114  
95 115 static void atmel_fb_init(ulong addr, struct display_timing *timing, int bpix,
96 116 bool tft, bool cont_pol_low, ulong lcdbase)
... ... @@ -190,6 +210,7 @@
190 210 (ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
191 211 }
192 212  
  213 +#ifndef CONFIG_DM_VIDEO
193 214 void lcd_ctrl_init(void *lcdbase)
194 215 {
195 216 struct display_timing timing;
... ... @@ -221,4 +242,74 @@
221 242 return ((panel_info.vl_col * panel_info.vl_row *
222 243 NBITS(panel_info.vl_bpix)) / 8) + PAGE_SIZE;
223 244 }
  245 +#endif
  246 +
  247 +#ifdef CONFIG_DM_VIDEO
  248 +static int atmel_fb_lcd_probe(struct udevice *dev)
  249 +{
  250 + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
  251 + struct video_priv *uc_priv = dev_get_uclass_priv(dev);
  252 + struct atmel_fb_priv *priv = dev_get_priv(dev);
  253 + struct display_timing *timing = &priv->timing;
  254 +
  255 + /*
  256 + * For now some values are hard-coded. We could use the device tree
  257 + * bindings in simple-framebuffer.txt to specify the format/bpp and
  258 + * some Atmel-specific binding for tft and cont_pol_low.
  259 + */
  260 + atmel_fb_init(ATMEL_BASE_LCDC, timing, VIDEO_BPP16, true, false,
  261 + uc_plat->base);
  262 + uc_priv->xsize = timing->hactive.typ;
  263 + uc_priv->ysize = timing->vactive.typ;
  264 + uc_priv->bpix = VIDEO_BPP16;
  265 + video_set_flush_dcache(dev, true);
  266 + debug("LCD frame buffer at %lx, size %x, %dx%d pixels\n", uc_plat->base,
  267 + uc_plat->size, uc_priv->xsize, uc_priv->ysize);
  268 +
  269 + return 0;
  270 +}
  271 +
  272 +static int atmel_fb_ofdata_to_platdata(struct udevice *dev)
  273 +{
  274 + struct atmel_lcd_platdata *plat = dev_get_platdata(dev);
  275 + struct atmel_fb_priv *priv = dev_get_priv(dev);
  276 + struct display_timing *timing = &priv->timing;
  277 + const void *blob = gd->fdt_blob;
  278 +
  279 + if (fdtdec_decode_display_timing(blob, dev->of_offset,
  280 + plat->timing_index, timing)) {
  281 + debug("%s: Failed to decode display timing\n", __func__);
  282 + return -EINVAL;
  283 + }
  284 +
  285 + return 0;
  286 +}
  287 +
  288 +static int atmel_fb_lcd_bind(struct udevice *dev)
  289 +{
  290 + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
  291 +
  292 + uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
  293 + (1 << VIDEO_BPP16) / 8;
  294 + debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
  295 +
  296 + return 0;
  297 +}
  298 +
  299 +static const struct udevice_id atmel_fb_lcd_ids[] = {
  300 + { .compatible = "atmel,at91sam9g45-lcdc" },
  301 + { }
  302 +};
  303 +
  304 +U_BOOT_DRIVER(atmel_fb) = {
  305 + .name = "atmel_fb",
  306 + .id = UCLASS_VIDEO,
  307 + .of_match = atmel_fb_lcd_ids,
  308 + .bind = atmel_fb_lcd_bind,
  309 + .ofdata_to_platdata = atmel_fb_ofdata_to_platdata,
  310 + .probe = atmel_fb_lcd_probe,
  311 + .platdata_auto_alloc_size = sizeof(struct atmel_lcd_platdata),
  312 + .priv_auto_alloc_size = sizeof(struct atmel_fb_priv),
  313 +};
  314 +#endif
... ... @@ -10,6 +10,15 @@
10 10 #ifndef _ATMEL_LCD_H_
11 11 #define _ATMEL_LCD_H_
12 12  
  13 +/**
  14 + * struct atmel_lcd_platdata - platform data for Atmel LCDs with driver model
  15 + *
  16 + * @timing_index: Index of LCD timing to use in device tree node
  17 + */
  18 +struct atmel_lcd_platdata {
  19 + int timing_index;
  20 +};
  21 +
13 22 typedef struct vidinfo {
14 23 ushort vl_col; /* Number of columns (i.e. 640) */
15 24 ushort vl_row; /* Number of rows (i.e. 480) */