ARM: dts: imx6qdl-sr-som: Sync with kernel 5.8-rc1
[oweals/u-boot.git] / drivers / video / atmel_hlcdfb.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for AT91/AT32 MULTI LAYER LCD Controller
4  *
5  * Copyright (C) 2012 Atmel Corporation
6  */
7
8 #include <common.h>
9 #include <cpu_func.h>
10 #include <log.h>
11 #include <malloc.h>
12 #include <part.h>
13 #include <asm/io.h>
14 #include <asm/arch/gpio.h>
15 #include <asm/arch/clk.h>
16 #include <clk.h>
17 #include <dm.h>
18 #include <fdtdec.h>
19 #include <lcd.h>
20 #include <video.h>
21 #include <wait_bit.h>
22 #include <atmel_hlcdc.h>
23 #include <linux/bug.h>
24
25 #if defined(CONFIG_LCD_LOGO)
26 #include <bmp_logo.h>
27 #endif
28
29 DECLARE_GLOBAL_DATA_PTR;
30
31 #ifndef CONFIG_DM_VIDEO
32
33 /* configurable parameters */
34 #define ATMEL_LCDC_CVAL_DEFAULT         0xc8
35 #define ATMEL_LCDC_DMA_BURST_LEN        8
36 #ifndef ATMEL_LCDC_GUARD_TIME
37 #define ATMEL_LCDC_GUARD_TIME           1
38 #endif
39
40 #define ATMEL_LCDC_FIFO_SIZE            512
41
42 /*
43  * the CLUT register map as following
44  * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0)
45  */
46 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
47 {
48         writel(panel_info.mmio + ATMEL_LCDC_LUT(regno),
49                ((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk)
50                | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk)
51                | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk));
52 }
53
54 ushort *configuration_get_cmap(void)
55 {
56 #if defined(CONFIG_LCD_LOGO)
57         return bmp_logo_palette;
58 #else
59         return NULL;
60 #endif
61 }
62
63 void lcd_ctrl_init(void *lcdbase)
64 {
65         unsigned long value;
66         struct lcd_dma_desc *desc;
67         struct atmel_hlcd_regs *regs;
68         int ret;
69
70         if (!has_lcdc())
71                 return;     /* No lcdc */
72
73         regs = (struct atmel_hlcd_regs *)panel_info.mmio;
74
75         /* Disable DISP signal */
76         writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
77         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
78                                 false, 1000, false);
79         if (ret)
80                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
81         /* Disable synchronization */
82         writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
83         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
84                                 false, 1000, false);
85         if (ret)
86                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
87         /* Disable pixel clock */
88         writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
89         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
90                                 false, 1000, false);
91         if (ret)
92                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
93         /* Disable PWM */
94         writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
95         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
96                                 false, 1000, false);
97         if (ret)
98                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
99
100         /* Set pixel clock */
101         value = get_lcdc_clk_rate(0) / panel_info.vl_clk;
102         if (get_lcdc_clk_rate(0) % panel_info.vl_clk)
103                 value++;
104
105         if (value < 1) {
106                 /* Using system clock as pixel clock */
107                 writel(LCDC_LCDCFG0_CLKDIV(0)
108                         | LCDC_LCDCFG0_CGDISHCR
109                         | LCDC_LCDCFG0_CGDISHEO
110                         | LCDC_LCDCFG0_CGDISOVR1
111                         | LCDC_LCDCFG0_CGDISBASE
112                         | panel_info.vl_clk_pol
113                         | LCDC_LCDCFG0_CLKSEL,
114                         &regs->lcdc_lcdcfg0);
115
116         } else {
117                 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
118                         | LCDC_LCDCFG0_CGDISHCR
119                         | LCDC_LCDCFG0_CGDISHEO
120                         | LCDC_LCDCFG0_CGDISOVR1
121                         | LCDC_LCDCFG0_CGDISBASE
122                         | panel_info.vl_clk_pol,
123                         &regs->lcdc_lcdcfg0);
124         }
125
126         /* Initialize control register 5 */
127         value = 0;
128
129         value |= panel_info.vl_sync;
130
131 #ifndef LCD_OUTPUT_BPP
132         /* Output is 24bpp */
133         value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
134 #else
135         switch (LCD_OUTPUT_BPP) {
136         case 12:
137                 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
138                 break;
139         case 16:
140                 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
141                 break;
142         case 18:
143                 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
144                 break;
145         case 24:
146                 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
147                 break;
148         default:
149                 BUG();
150                 break;
151         }
152 #endif
153
154         value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME);
155         value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
156         writel(value, &regs->lcdc_lcdcfg5);
157
158         /* Vertical & Horizontal Timing */
159         value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1);
160         value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1);
161         writel(value, &regs->lcdc_lcdcfg1);
162
163         value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin);
164         value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1);
165         writel(value, &regs->lcdc_lcdcfg2);
166
167         value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1);
168         value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1);
169         writel(value, &regs->lcdc_lcdcfg3);
170
171         /* Display size */
172         value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1);
173         value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1);
174         writel(value, &regs->lcdc_lcdcfg4);
175
176         writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
177                &regs->lcdc_basecfg0);
178
179         switch (NBITS(panel_info.vl_bpix)) {
180         case 16:
181                 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
182                        &regs->lcdc_basecfg1);
183                 break;
184         case 32:
185                 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
186                        &regs->lcdc_basecfg1);
187                 break;
188         default:
189                 BUG();
190                 break;
191         }
192
193         writel(LCDC_BASECFG2_XSTRIDE(0), &regs->lcdc_basecfg2);
194         writel(0, &regs->lcdc_basecfg3);
195         writel(LCDC_BASECFG4_DMA, &regs->lcdc_basecfg4);
196
197         /* Disable all interrupts */
198         writel(~0UL, &regs->lcdc_lcdidr);
199         writel(~0UL, &regs->lcdc_baseidr);
200
201         /* Setup the DMA descriptor, this descriptor will loop to itself */
202         desc = (struct lcd_dma_desc *)(lcdbase - 16);
203
204         desc->address = (u32)lcdbase;
205         /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
206         desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
207                         | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
208         desc->next = (u32)desc;
209
210         /* Flush the DMA descriptor if we enabled dcache */
211         flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
212
213         writel(desc->address, &regs->lcdc_baseaddr);
214         writel(desc->control, &regs->lcdc_basectrl);
215         writel(desc->next, &regs->lcdc_basenext);
216         writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
217                &regs->lcdc_basecher);
218
219         /* Enable LCD */
220         value = readl(&regs->lcdc_lcden);
221         writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
222         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
223                                 true, 1000, false);
224         if (ret)
225                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
226         value = readl(&regs->lcdc_lcden);
227         writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
228         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
229                                 true, 1000, false);
230         if (ret)
231                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
232         value = readl(&regs->lcdc_lcden);
233         writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
234         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
235                                 true, 1000, false);
236         if (ret)
237                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
238         value = readl(&regs->lcdc_lcden);
239         writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
240         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
241                                 true, 1000, false);
242         if (ret)
243                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
244
245         /* Enable flushing if we enabled dcache */
246         lcd_set_flush_dcache(1);
247 }
248
249 #else
250
251 enum {
252         LCD_MAX_WIDTH           = 1024,
253         LCD_MAX_HEIGHT          = 768,
254         LCD_MAX_LOG2_BPP        = VIDEO_BPP16,
255 };
256
257 struct atmel_hlcdc_priv {
258         struct atmel_hlcd_regs *regs;
259         struct display_timing timing;
260         unsigned int vl_bpix;
261         unsigned int output_mode;
262         unsigned int guard_time;
263         ulong clk_rate;
264 };
265
266 static int at91_hlcdc_enable_clk(struct udevice *dev)
267 {
268         struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
269         struct clk clk;
270         ulong clk_rate;
271         int ret;
272
273         ret = clk_get_by_index(dev, 0, &clk);
274         if (ret)
275                 return -EINVAL;
276
277         ret = clk_enable(&clk);
278         if (ret)
279                 return ret;
280
281         clk_rate = clk_get_rate(&clk);
282         if (!clk_rate) {
283                 clk_disable(&clk);
284                 return -ENODEV;
285         }
286
287         priv->clk_rate = clk_rate;
288
289         clk_free(&clk);
290
291         return 0;
292 }
293
294 static void atmel_hlcdc_init(struct udevice *dev)
295 {
296         struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
297         struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
298         struct atmel_hlcd_regs *regs = priv->regs;
299         struct display_timing *timing = &priv->timing;
300         struct lcd_dma_desc *desc;
301         unsigned long value, vl_clk_pol;
302         int ret;
303
304         /* Disable DISP signal */
305         writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
306         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
307                                 false, 1000, false);
308         if (ret)
309                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
310         /* Disable synchronization */
311         writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
312         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
313                                 false, 1000, false);
314         if (ret)
315                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
316         /* Disable pixel clock */
317         writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
318         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
319                                 false, 1000, false);
320         if (ret)
321                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
322         /* Disable PWM */
323         writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
324         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
325                                 false, 1000, false);
326         if (ret)
327                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
328
329         /* Set pixel clock */
330         value = priv->clk_rate / timing->pixelclock.typ;
331         if (priv->clk_rate % timing->pixelclock.typ)
332                 value++;
333
334         vl_clk_pol = 0;
335         if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
336                 vl_clk_pol = LCDC_LCDCFG0_CLKPOL;
337
338         if (value < 1) {
339                 /* Using system clock as pixel clock */
340                 writel(LCDC_LCDCFG0_CLKDIV(0)
341                         | LCDC_LCDCFG0_CGDISHCR
342                         | LCDC_LCDCFG0_CGDISHEO
343                         | LCDC_LCDCFG0_CGDISOVR1
344                         | LCDC_LCDCFG0_CGDISBASE
345                         | vl_clk_pol
346                         | LCDC_LCDCFG0_CLKSEL,
347                         &regs->lcdc_lcdcfg0);
348
349         } else {
350                 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
351                         | LCDC_LCDCFG0_CGDISHCR
352                         | LCDC_LCDCFG0_CGDISHEO
353                         | LCDC_LCDCFG0_CGDISOVR1
354                         | LCDC_LCDCFG0_CGDISBASE
355                         | vl_clk_pol,
356                         &regs->lcdc_lcdcfg0);
357         }
358
359         /* Initialize control register 5 */
360         value = 0;
361
362         if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH))
363                 value |= LCDC_LCDCFG5_HSPOL;
364         if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH))
365                 value |= LCDC_LCDCFG5_VSPOL;
366
367         switch (priv->output_mode) {
368         case 12:
369                 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
370                 break;
371         case 16:
372                 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
373                 break;
374         case 18:
375                 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
376                 break;
377         case 24:
378                 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
379                 break;
380         default:
381                 BUG();
382                 break;
383         }
384
385         value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time);
386         value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
387         writel(value, &regs->lcdc_lcdcfg5);
388
389         /* Vertical & Horizontal Timing */
390         value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1);
391         value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1);
392         writel(value, &regs->lcdc_lcdcfg1);
393
394         value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ);
395         value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1);
396         writel(value, &regs->lcdc_lcdcfg2);
397
398         value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1);
399         value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1);
400         writel(value, &regs->lcdc_lcdcfg3);
401
402         /* Display size */
403         value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1);
404         value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1);
405         writel(value, &regs->lcdc_lcdcfg4);
406
407         writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
408                &regs->lcdc_basecfg0);
409
410         switch (VNBITS(priv->vl_bpix)) {
411         case 16:
412                 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
413                        &regs->lcdc_basecfg1);
414                 break;
415         case 32:
416                 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
417                        &regs->lcdc_basecfg1);
418                 break;
419         default:
420                 BUG();
421                 break;
422         }
423
424         writel(LCDC_BASECFG2_XSTRIDE(0), &regs->lcdc_basecfg2);
425         writel(0, &regs->lcdc_basecfg3);
426         writel(LCDC_BASECFG4_DMA, &regs->lcdc_basecfg4);
427
428         /* Disable all interrupts */
429         writel(~0UL, &regs->lcdc_lcdidr);
430         writel(~0UL, &regs->lcdc_baseidr);
431
432         /* Setup the DMA descriptor, this descriptor will loop to itself */
433         desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
434         if (!desc)
435                 return;
436
437         desc->address = (u32)uc_plat->base;
438
439         /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
440         desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
441                         | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
442         desc->next = (u32)desc;
443
444         /* Flush the DMA descriptor if we enabled dcache */
445         flush_dcache_range((u32)desc,
446                            ALIGN(((u32)desc + sizeof(*desc)),
447                            CONFIG_SYS_CACHELINE_SIZE));
448
449         writel(desc->address, &regs->lcdc_baseaddr);
450         writel(desc->control, &regs->lcdc_basectrl);
451         writel(desc->next, &regs->lcdc_basenext);
452         writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
453                &regs->lcdc_basecher);
454
455         /* Enable LCD */
456         value = readl(&regs->lcdc_lcden);
457         writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
458         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
459                                 true, 1000, false);
460         if (ret)
461                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
462         value = readl(&regs->lcdc_lcden);
463         writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
464         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
465                                 true, 1000, false);
466         if (ret)
467                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
468         value = readl(&regs->lcdc_lcden);
469         writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
470         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
471                                 true, 1000, false);
472         if (ret)
473                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
474         value = readl(&regs->lcdc_lcden);
475         writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
476         ret = wait_for_bit_le32(&regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
477                                 true, 1000, false);
478         if (ret)
479                 printf("%s: %d: Timeout!\n", __func__, __LINE__);
480 }
481
482 static int atmel_hlcdc_probe(struct udevice *dev)
483 {
484         struct video_priv *uc_priv = dev_get_uclass_priv(dev);
485         struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
486         int ret;
487
488         ret = at91_hlcdc_enable_clk(dev);
489         if (ret)
490                 return ret;
491
492         atmel_hlcdc_init(dev);
493
494         uc_priv->xsize = priv->timing.hactive.typ;
495         uc_priv->ysize = priv->timing.vactive.typ;
496         uc_priv->bpix = priv->vl_bpix;
497
498         /* Enable flushing if we enabled dcache */
499         video_set_flush_dcache(dev, true);
500
501         return 0;
502 }
503
504 static int atmel_hlcdc_ofdata_to_platdata(struct udevice *dev)
505 {
506         struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
507         const void *blob = gd->fdt_blob;
508         int node = dev_of_offset(dev);
509
510         priv->regs = (struct atmel_hlcd_regs *)devfdt_get_addr(dev);
511         if (!priv->regs) {
512                 debug("%s: No display controller address\n", __func__);
513                 return -EINVAL;
514         }
515
516         if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
517                                          0, &priv->timing)) {
518                 debug("%s: Failed to decode display timing\n", __func__);
519                 return -EINVAL;
520         }
521
522         if (priv->timing.hactive.typ > LCD_MAX_WIDTH)
523                 priv->timing.hactive.typ = LCD_MAX_WIDTH;
524
525         if (priv->timing.vactive.typ > LCD_MAX_HEIGHT)
526                 priv->timing.vactive.typ = LCD_MAX_HEIGHT;
527
528         priv->vl_bpix = fdtdec_get_int(blob, node, "atmel,vl-bpix", 0);
529         if (!priv->vl_bpix) {
530                 debug("%s: Failed to get bits per pixel\n", __func__);
531                 return -EINVAL;
532         }
533
534         priv->output_mode = fdtdec_get_int(blob, node, "atmel,output-mode", 24);
535         priv->guard_time = fdtdec_get_int(blob, node, "atmel,guard-time", 1);
536
537         return 0;
538 }
539
540 static int atmel_hlcdc_bind(struct udevice *dev)
541 {
542         struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
543
544         uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
545                                 (1 << LCD_MAX_LOG2_BPP) / 8;
546
547         debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
548
549         return 0;
550 }
551
552 static const struct udevice_id atmel_hlcdc_ids[] = {
553         { .compatible = "atmel,sama5d2-hlcdc" },
554         { .compatible = "atmel,at91sam9x5-hlcdc" },
555         { }
556 };
557
558 U_BOOT_DRIVER(atmel_hlcdfb) = {
559         .name   = "atmel_hlcdfb",
560         .id     = UCLASS_VIDEO,
561         .of_match = atmel_hlcdc_ids,
562         .bind   = atmel_hlcdc_bind,
563         .probe  = atmel_hlcdc_probe,
564         .ofdata_to_platdata = atmel_hlcdc_ofdata_to_platdata,
565         .priv_auto_alloc_size = sizeof(struct atmel_hlcdc_priv),
566 };
567
568 #endif