1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for AT91/AT32 MULTI LAYER LCD Controller
5 * Copyright (C) 2012 Atmel Corporation
13 #include <asm/global_data.h>
15 #include <asm/arch/gpio.h>
16 #include <asm/arch/clk.h>
23 #include <atmel_hlcdc.h>
24 #include <linux/bug.h>
26 DECLARE_GLOBAL_DATA_PTR;
28 #ifndef CONFIG_DM_VIDEO
30 /* configurable parameters */
31 #define ATMEL_LCDC_CVAL_DEFAULT 0xc8
32 #define ATMEL_LCDC_DMA_BURST_LEN 8
33 #ifndef ATMEL_LCDC_GUARD_TIME
34 #define ATMEL_LCDC_GUARD_TIME 1
37 #define ATMEL_LCDC_FIFO_SIZE 512
40 * the CLUT register map as following
41 * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0)
43 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
45 writel(panel_info.mmio + ATMEL_LCDC_LUT(regno),
46 ((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk)
47 | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk)
48 | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk));
51 void lcd_ctrl_init(void *lcdbase)
54 struct lcd_dma_desc *desc;
55 struct atmel_hlcd_regs *regs;
61 regs = (struct atmel_hlcd_regs *)panel_info.mmio;
63 /* Disable DISP signal */
64 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
65 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
68 printf("%s: %d: Timeout!\n", __func__, __LINE__);
69 /* Disable synchronization */
70 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
71 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
74 printf("%s: %d: Timeout!\n", __func__, __LINE__);
75 /* Disable pixel clock */
76 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
77 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
80 printf("%s: %d: Timeout!\n", __func__, __LINE__);
82 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
83 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
86 printf("%s: %d: Timeout!\n", __func__, __LINE__);
89 value = get_lcdc_clk_rate(0) / panel_info.vl_clk;
90 if (get_lcdc_clk_rate(0) % panel_info.vl_clk)
94 /* Using system clock as pixel clock */
95 writel(LCDC_LCDCFG0_CLKDIV(0)
96 | LCDC_LCDCFG0_CGDISHCR
97 | LCDC_LCDCFG0_CGDISHEO
98 | LCDC_LCDCFG0_CGDISOVR1
99 | LCDC_LCDCFG0_CGDISBASE
100 | panel_info.vl_clk_pol
101 | LCDC_LCDCFG0_CLKSEL,
102 ®s->lcdc_lcdcfg0);
105 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
106 | LCDC_LCDCFG0_CGDISHCR
107 | LCDC_LCDCFG0_CGDISHEO
108 | LCDC_LCDCFG0_CGDISOVR1
109 | LCDC_LCDCFG0_CGDISBASE
110 | panel_info.vl_clk_pol,
111 ®s->lcdc_lcdcfg0);
114 /* Initialize control register 5 */
117 value |= panel_info.vl_sync;
119 #ifndef LCD_OUTPUT_BPP
120 /* Output is 24bpp */
121 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
123 switch (LCD_OUTPUT_BPP) {
125 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
128 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
131 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
134 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
142 value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME);
143 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
144 writel(value, ®s->lcdc_lcdcfg5);
146 /* Vertical & Horizontal Timing */
147 value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1);
148 value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1);
149 writel(value, ®s->lcdc_lcdcfg1);
151 value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin);
152 value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1);
153 writel(value, ®s->lcdc_lcdcfg2);
155 value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1);
156 value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1);
157 writel(value, ®s->lcdc_lcdcfg3);
160 value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1);
161 value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1);
162 writel(value, ®s->lcdc_lcdcfg4);
164 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
165 ®s->lcdc_basecfg0);
167 switch (NBITS(panel_info.vl_bpix)) {
169 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
170 ®s->lcdc_basecfg1);
173 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
174 ®s->lcdc_basecfg1);
181 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2);
182 writel(0, ®s->lcdc_basecfg3);
183 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4);
185 /* Disable all interrupts */
186 writel(~0UL, ®s->lcdc_lcdidr);
187 writel(~0UL, ®s->lcdc_baseidr);
189 /* Setup the DMA descriptor, this descriptor will loop to itself */
190 desc = (struct lcd_dma_desc *)(lcdbase - 16);
192 desc->address = (u32)lcdbase;
193 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
194 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
195 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
196 desc->next = (u32)desc;
198 /* Flush the DMA descriptor if we enabled dcache */
199 flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
201 writel(desc->address, ®s->lcdc_baseaddr);
202 writel(desc->control, ®s->lcdc_basectrl);
203 writel(desc->next, ®s->lcdc_basenext);
204 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
205 ®s->lcdc_basecher);
208 value = readl(®s->lcdc_lcden);
209 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
210 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
213 printf("%s: %d: Timeout!\n", __func__, __LINE__);
214 value = readl(®s->lcdc_lcden);
215 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
216 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
219 printf("%s: %d: Timeout!\n", __func__, __LINE__);
220 value = readl(®s->lcdc_lcden);
221 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
222 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
225 printf("%s: %d: Timeout!\n", __func__, __LINE__);
226 value = readl(®s->lcdc_lcden);
227 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
228 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
231 printf("%s: %d: Timeout!\n", __func__, __LINE__);
233 /* Enable flushing if we enabled dcache */
234 lcd_set_flush_dcache(1);
240 LCD_MAX_WIDTH = 1024,
241 LCD_MAX_HEIGHT = 768,
242 LCD_MAX_LOG2_BPP = VIDEO_BPP16,
245 struct atmel_hlcdc_priv {
246 struct atmel_hlcd_regs *regs;
247 struct display_timing timing;
248 unsigned int vl_bpix;
249 unsigned int output_mode;
250 unsigned int guard_time;
254 static int at91_hlcdc_enable_clk(struct udevice *dev)
256 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
261 ret = clk_get_by_index(dev, 0, &clk);
265 ret = clk_enable(&clk);
269 clk_rate = clk_get_rate(&clk);
275 priv->clk_rate = clk_rate;
282 static void atmel_hlcdc_init(struct udevice *dev)
284 struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
285 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
286 struct atmel_hlcd_regs *regs = priv->regs;
287 struct display_timing *timing = &priv->timing;
288 struct lcd_dma_desc *desc;
289 unsigned long value, vl_clk_pol;
292 /* Disable DISP signal */
293 writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis);
294 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
297 printf("%s: %d: Timeout!\n", __func__, __LINE__);
298 /* Disable synchronization */
299 writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis);
300 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
303 printf("%s: %d: Timeout!\n", __func__, __LINE__);
304 /* Disable pixel clock */
305 writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis);
306 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
309 printf("%s: %d: Timeout!\n", __func__, __LINE__);
311 writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis);
312 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
315 printf("%s: %d: Timeout!\n", __func__, __LINE__);
317 /* Set pixel clock */
318 value = priv->clk_rate / timing->pixelclock.typ;
319 if (priv->clk_rate % timing->pixelclock.typ)
323 if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
324 vl_clk_pol = LCDC_LCDCFG0_CLKPOL;
327 /* Using system clock as pixel clock */
328 writel(LCDC_LCDCFG0_CLKDIV(0)
329 | LCDC_LCDCFG0_CGDISHCR
330 | LCDC_LCDCFG0_CGDISHEO
331 | LCDC_LCDCFG0_CGDISOVR1
332 | LCDC_LCDCFG0_CGDISBASE
334 | LCDC_LCDCFG0_CLKSEL,
335 ®s->lcdc_lcdcfg0);
338 writel(LCDC_LCDCFG0_CLKDIV(value - 2)
339 | LCDC_LCDCFG0_CGDISHCR
340 | LCDC_LCDCFG0_CGDISHEO
341 | LCDC_LCDCFG0_CGDISOVR1
342 | LCDC_LCDCFG0_CGDISBASE
344 ®s->lcdc_lcdcfg0);
347 /* Initialize control register 5 */
350 if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH))
351 value |= LCDC_LCDCFG5_HSPOL;
352 if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH))
353 value |= LCDC_LCDCFG5_VSPOL;
355 switch (priv->output_mode) {
357 value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
360 value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
363 value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
366 value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
373 value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time);
374 value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
375 writel(value, ®s->lcdc_lcdcfg5);
377 /* Vertical & Horizontal Timing */
378 value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1);
379 value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1);
380 writel(value, ®s->lcdc_lcdcfg1);
382 value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ);
383 value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1);
384 writel(value, ®s->lcdc_lcdcfg2);
386 value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1);
387 value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1);
388 writel(value, ®s->lcdc_lcdcfg3);
391 value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1);
392 value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1);
393 writel(value, ®s->lcdc_lcdcfg4);
395 writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
396 ®s->lcdc_basecfg0);
398 switch (VNBITS(priv->vl_bpix)) {
400 writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
401 ®s->lcdc_basecfg1);
404 writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
405 ®s->lcdc_basecfg1);
412 writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2);
413 writel(0, ®s->lcdc_basecfg3);
414 writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4);
416 /* Disable all interrupts */
417 writel(~0UL, ®s->lcdc_lcdidr);
418 writel(~0UL, ®s->lcdc_baseidr);
420 /* Setup the DMA descriptor, this descriptor will loop to itself */
421 desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
425 desc->address = (u32)uc_plat->base;
427 /* Disable DMA transfer interrupt & descriptor loaded interrupt. */
428 desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
429 | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
430 desc->next = (u32)desc;
432 /* Flush the DMA descriptor if we enabled dcache */
433 flush_dcache_range((u32)desc,
434 ALIGN(((u32)desc + sizeof(*desc)),
435 CONFIG_SYS_CACHELINE_SIZE));
437 writel(desc->address, ®s->lcdc_baseaddr);
438 writel(desc->control, ®s->lcdc_basectrl);
439 writel(desc->next, ®s->lcdc_basenext);
440 writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
441 ®s->lcdc_basecher);
444 value = readl(®s->lcdc_lcden);
445 writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden);
446 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
449 printf("%s: %d: Timeout!\n", __func__, __LINE__);
450 value = readl(®s->lcdc_lcden);
451 writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden);
452 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
455 printf("%s: %d: Timeout!\n", __func__, __LINE__);
456 value = readl(®s->lcdc_lcden);
457 writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden);
458 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
461 printf("%s: %d: Timeout!\n", __func__, __LINE__);
462 value = readl(®s->lcdc_lcden);
463 writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden);
464 ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
467 printf("%s: %d: Timeout!\n", __func__, __LINE__);
470 static int atmel_hlcdc_probe(struct udevice *dev)
472 struct video_priv *uc_priv = dev_get_uclass_priv(dev);
473 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
476 ret = at91_hlcdc_enable_clk(dev);
480 atmel_hlcdc_init(dev);
482 uc_priv->xsize = priv->timing.hactive.typ;
483 uc_priv->ysize = priv->timing.vactive.typ;
484 uc_priv->bpix = priv->vl_bpix;
486 /* Enable flushing if we enabled dcache */
487 video_set_flush_dcache(dev, true);
492 static int atmel_hlcdc_of_to_plat(struct udevice *dev)
494 struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
495 const void *blob = gd->fdt_blob;
496 int node = dev_of_offset(dev);
498 priv->regs = dev_read_addr_ptr(dev);
500 debug("%s: No display controller address\n", __func__);
504 if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
506 debug("%s: Failed to decode display timing\n", __func__);
510 if (priv->timing.hactive.typ > LCD_MAX_WIDTH)
511 priv->timing.hactive.typ = LCD_MAX_WIDTH;
513 if (priv->timing.vactive.typ > LCD_MAX_HEIGHT)
514 priv->timing.vactive.typ = LCD_MAX_HEIGHT;
516 priv->vl_bpix = fdtdec_get_int(blob, node, "atmel,vl-bpix", 0);
517 if (!priv->vl_bpix) {
518 debug("%s: Failed to get bits per pixel\n", __func__);
522 priv->output_mode = fdtdec_get_int(blob, node, "atmel,output-mode", 24);
523 priv->guard_time = fdtdec_get_int(blob, node, "atmel,guard-time", 1);
528 static int atmel_hlcdc_bind(struct udevice *dev)
530 struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
532 uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
533 (1 << LCD_MAX_LOG2_BPP) / 8;
535 debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
540 static const struct udevice_id atmel_hlcdc_ids[] = {
541 { .compatible = "atmel,sama5d2-hlcdc" },
542 { .compatible = "atmel,at91sam9x5-hlcdc" },
546 U_BOOT_DRIVER(atmel_hlcdfb) = {
547 .name = "atmel_hlcdfb",
549 .of_match = atmel_hlcdc_ids,
550 .bind = atmel_hlcdc_bind,
551 .probe = atmel_hlcdc_probe,
552 .of_to_plat = atmel_hlcdc_of_to_plat,
553 .priv_auto = sizeof(struct atmel_hlcdc_priv),