2 * Driver for AT91/AT32 MULTI LAYER LCD Controller
4 * Copyright (C) 2012 Atmel Corporation
6 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/gpio.h>
12 #include <asm/arch/clk.h>
19 #include <atmel_hlcdc.h>
21 #if defined(CONFIG_LCD_LOGO)
25 DECLARE_GLOBAL_DATA_PTR;
27 #ifndef CONFIG_DM_VIDEO
29 /* configurable parameters */
30 #define ATMEL_LCDC_CVAL_DEFAULT 0xc8
31 #define ATMEL_LCDC_DMA_BURST_LEN 8
32 #ifndef ATMEL_LCDC_GUARD_TIME
33 #define ATMEL_LCDC_GUARD_TIME 1
36 #define ATMEL_LCDC_FIFO_SIZE 512
39 * the CLUT register map as following
40 * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0)
42 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
44 writel(panel_info.mmio + ATMEL_LCDC_LUT(regno),
45 ((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk)
46 | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk)
47 | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk));
50 ushort *configuration_get_cmap(void)
52 #if defined(CONFIG_LCD_LOGO)
53 return bmp_logo_palette;
59 void lcd_ctrl_init(void *lcdbase)
62 struct lcd_dma_desc *desc;
63 struct atmel_hlcd_regs *regs;
69 regs = (struct atmel_hlcd_regs *)panel_info.mmio;
71 /* Disable DISP signal */
72 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
73 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
76 printf("%s: %d: Timeout!\n", __func__, __LINE__);
77 /* Disable synchronization */
78 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
79 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
82 printf("%s: %d: Timeout!\n", __func__, __LINE__);
83 /* Disable pixel clock */
84 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
85 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
88 printf("%s: %d: Timeout!\n", __func__, __LINE__);
90 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
91 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
94 printf("%s: %d: Timeout!\n", __func__, __LINE__);
97 value = get_lcdc_clk_rate(0) / panel_info.vl_clk;
98 if (get_lcdc_clk_rate(0) % panel_info.vl_clk)
102 /* Using system clock as pixel clock */
103 writel(LCDC_LCDCFG0_CLKDIV(0)
104 | LCDC_LCDCFG0_CGDISHCR
105 | LCDC_LCDCFG0_CGDISHEO
106 | LCDC_LCDCFG0_CGDISOVR1
107 | LCDC_LCDCFG0_CGDISBASE
108 | panel_info.vl_clk_pol
109 | LCDC_LCDCFG0_CLKSEL,
110 ®s->lcdc_lcdcfg0);
113 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
114 | LCDC_LCDCFG0_CGDISHCR
115 | LCDC_LCDCFG0_CGDISHEO
116 | LCDC_LCDCFG0_CGDISOVR1
117 | LCDC_LCDCFG0_CGDISBASE
118 | panel_info.vl_clk_pol,
119 ®s->lcdc_lcdcfg0);
122 /* Initialize control register 5 */
125 value |= panel_info.vl_sync;
127 #ifndef LCD_OUTPUT_BPP
128 /* Output is 24bpp */
129 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
131 switch (LCD_OUTPUT_BPP) {
133 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
136 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
139 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
142 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
150 value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME);
151 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
152 writel(value, ®s->lcdc_lcdcfg5);
154 /* Vertical & Horizontal Timing */
155 value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1);
156 value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1);
157 writel(value, ®s->lcdc_lcdcfg1);
159 value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin);
160 value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1);
161 writel(value, ®s->lcdc_lcdcfg2);
163 value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1);
164 value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1);
165 writel(value, ®s->lcdc_lcdcfg3);
168 value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1);
169 value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1);
170 writel(value, ®s->lcdc_lcdcfg4);
172 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
173 ®s->lcdc_basecfg0);
175 switch (NBITS(panel_info.vl_bpix)) {
177 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
178 ®s->lcdc_basecfg1);
181 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
182 ®s->lcdc_basecfg1);
189 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2);
190 writel(0, ®s->lcdc_basecfg3);
191 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4);
193 /* Disable all interrupts */
194 writel(~0UL, ®s->lcdc_lcdidr);
195 writel(~0UL, ®s->lcdc_baseidr);
197 /* Setup the DMA descriptor, this descriptor will loop to itself */
198 desc = (struct lcd_dma_desc *)(lcdbase - 16);
200 desc->address = (u32)lcdbase;
201 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
202 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
203 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
204 desc->next = (u32)desc;
206 /* Flush the DMA descriptor if we enabled dcache */
207 flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
209 writel(desc->address, ®s->lcdc_baseaddr);
210 writel(desc->control, ®s->lcdc_basectrl);
211 writel(desc->next, ®s->lcdc_basenext);
212 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
213 ®s->lcdc_basecher);
216 value = readl(®s->lcdc_lcden);
217 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
218 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
221 printf("%s: %d: Timeout!\n", __func__, __LINE__);
222 value = readl(®s->lcdc_lcden);
223 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
224 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
227 printf("%s: %d: Timeout!\n", __func__, __LINE__);
228 value = readl(®s->lcdc_lcden);
229 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
230 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
233 printf("%s: %d: Timeout!\n", __func__, __LINE__);
234 value = readl(®s->lcdc_lcden);
235 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
236 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
239 printf("%s: %d: Timeout!\n", __func__, __LINE__);
241 /* Enable flushing if we enabled dcache */
242 lcd_set_flush_dcache(1);
248 LCD_MAX_WIDTH = 1024,
249 LCD_MAX_HEIGHT = 768,
250 LCD_MAX_LOG2_BPP = VIDEO_BPP16,
253 struct atmel_hlcdc_priv {
254 struct atmel_hlcd_regs *regs;
255 struct display_timing timing;
256 unsigned int vl_bpix;
257 unsigned int output_mode;
258 unsigned int guard_time;
262 static int at91_hlcdc_enable_clk(struct udevice *dev)
264 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
269 ret = clk_get_by_index(dev, 0, &clk);
273 ret = clk_enable(&clk);
277 clk_rate = clk_get_rate(&clk);
283 priv->clk_rate = clk_rate;
290 static void atmel_hlcdc_init(struct udevice *dev)
292 struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
293 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
294 struct atmel_hlcd_regs *regs = priv->regs;
295 struct display_timing *timing = &priv->timing;
296 struct lcd_dma_desc *desc;
297 unsigned long value, vl_clk_pol;
300 /* Disable DISP signal */
301 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
302 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
305 printf("%s: %d: Timeout!\n", __func__, __LINE__);
306 /* Disable synchronization */
307 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
308 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
311 printf("%s: %d: Timeout!\n", __func__, __LINE__);
312 /* Disable pixel clock */
313 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
314 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
317 printf("%s: %d: Timeout!\n", __func__, __LINE__);
319 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
320 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
323 printf("%s: %d: Timeout!\n", __func__, __LINE__);
325 /* Set pixel clock */
326 value = priv->clk_rate / timing->pixelclock.typ;
327 if (priv->clk_rate % timing->pixelclock.typ)
331 if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
332 vl_clk_pol = LCDC_LCDCFG0_CLKPOL;
335 /* Using system clock as pixel clock */
336 writel(LCDC_LCDCFG0_CLKDIV(0)
337 | LCDC_LCDCFG0_CGDISHCR
338 | LCDC_LCDCFG0_CGDISHEO
339 | LCDC_LCDCFG0_CGDISOVR1
340 | LCDC_LCDCFG0_CGDISBASE
342 | LCDC_LCDCFG0_CLKSEL,
343 ®s->lcdc_lcdcfg0);
346 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
347 | LCDC_LCDCFG0_CGDISHCR
348 | LCDC_LCDCFG0_CGDISHEO
349 | LCDC_LCDCFG0_CGDISOVR1
350 | LCDC_LCDCFG0_CGDISBASE
352 ®s->lcdc_lcdcfg0);
355 /* Initialize control register 5 */
358 if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH))
359 value |= LCDC_LCDCFG5_HSPOL;
360 if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH))
361 value |= LCDC_LCDCFG5_VSPOL;
363 switch (priv->output_mode) {
365 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
368 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
371 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
374 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
381 value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time);
382 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
383 writel(value, ®s->lcdc_lcdcfg5);
385 /* Vertical & Horizontal Timing */
386 value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1);
387 value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1);
388 writel(value, ®s->lcdc_lcdcfg1);
390 value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ);
391 value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1);
392 writel(value, ®s->lcdc_lcdcfg2);
394 value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1);
395 value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1);
396 writel(value, ®s->lcdc_lcdcfg3);
399 value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1);
400 value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1);
401 writel(value, ®s->lcdc_lcdcfg4);
403 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
404 ®s->lcdc_basecfg0);
406 switch (VNBITS(priv->vl_bpix)) {
408 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
409 ®s->lcdc_basecfg1);
412 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
413 ®s->lcdc_basecfg1);
420 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2);
421 writel(0, ®s->lcdc_basecfg3);
422 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4);
424 /* Disable all interrupts */
425 writel(~0UL, ®s->lcdc_lcdidr);
426 writel(~0UL, ®s->lcdc_baseidr);
428 /* Setup the DMA descriptor, this descriptor will loop to itself */
429 desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
433 desc->address = (u32)uc_plat->base;
435 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
436 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
437 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
438 desc->next = (u32)desc;
440 /* Flush the DMA descriptor if we enabled dcache */
441 flush_dcache_range((u32)desc,
442 ALIGN(((u32)desc + sizeof(*desc)),
443 CONFIG_SYS_CACHELINE_SIZE));
445 writel(desc->address, ®s->lcdc_baseaddr);
446 writel(desc->control, ®s->lcdc_basectrl);
447 writel(desc->next, ®s->lcdc_basenext);
448 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
449 ®s->lcdc_basecher);
452 value = readl(®s->lcdc_lcden);
453 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
454 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
457 printf("%s: %d: Timeout!\n", __func__, __LINE__);
458 value = readl(®s->lcdc_lcden);
459 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
460 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
463 printf("%s: %d: Timeout!\n", __func__, __LINE__);
464 value = readl(®s->lcdc_lcden);
465 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
466 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
469 printf("%s: %d: Timeout!\n", __func__, __LINE__);
470 value = readl(®s->lcdc_lcden);
471 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
472 ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
475 printf("%s: %d: Timeout!\n", __func__, __LINE__);
478 static int atmel_hlcdc_probe(struct udevice *dev)
480 struct video_priv *uc_priv = dev_get_uclass_priv(dev);
481 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
484 ret = at91_hlcdc_enable_clk(dev);
488 atmel_hlcdc_init(dev);
490 uc_priv->xsize = priv->timing.hactive.typ;
491 uc_priv->ysize = priv->timing.vactive.typ;
492 uc_priv->bpix = priv->vl_bpix;
494 /* Enable flushing if we enabled dcache */
495 video_set_flush_dcache(dev, true);
500 static int atmel_hlcdc_ofdata_to_platdata(struct udevice *dev)
502 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
503 const void *blob = gd->fdt_blob;
504 int node = dev_of_offset(dev);
506 priv->regs = (struct atmel_hlcd_regs *)devfdt_get_addr(dev);
508 debug("%s: No display controller address\n", __func__);
512 if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
514 debug("%s: Failed to decode display timing\n", __func__);
518 if (priv->timing.hactive.typ > LCD_MAX_WIDTH)
519 priv->timing.hactive.typ = LCD_MAX_WIDTH;
521 if (priv->timing.vactive.typ > LCD_MAX_HEIGHT)
522 priv->timing.vactive.typ = LCD_MAX_HEIGHT;
524 priv->vl_bpix = fdtdec_get_int(blob, node, "atmel,vl-bpix", 0);
525 if (!priv->vl_bpix) {
526 debug("%s: Failed to get bits per pixel\n", __func__);
530 priv->output_mode = fdtdec_get_int(blob, node, "atmel,output-mode", 24);
531 priv->guard_time = fdtdec_get_int(blob, node, "atmel,guard-time", 1);
536 static int atmel_hlcdc_bind(struct udevice *dev)
538 struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
540 uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
541 (1 << LCD_MAX_LOG2_BPP) / 8;
543 debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
548 static const struct udevice_id atmel_hlcdc_ids[] = {
549 { .compatible = "atmel,sama5d2-hlcdc" },
550 { .compatible = "atmel,at91sam9x5-hlcdc" },
554 U_BOOT_DRIVER(atmel_hlcdfb) = {
555 .name = "atmel_hlcdfb",
557 .of_match = atmel_hlcdc_ids,
558 .bind = atmel_hlcdc_bind,
559 .probe = atmel_hlcdc_probe,
560 .ofdata_to_platdata = atmel_hlcdc_ofdata_to_platdata,
561 .priv_auto_alloc_size = sizeof(struct atmel_hlcdc_priv),