2 * Display driver for Allwinner SoCs.
4 * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
5 * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
7 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/arch/clock.h>
13 #include <asm/arch/display.h>
14 #include <asm/arch/gpio.h>
15 #include <asm/global_data.h>
20 #include <fdt_support.h>
23 #include "videomodes.h"
24 #include "hitachi_tx18d42vm_lcd.h"
27 #ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW
35 DECLARE_GLOBAL_DATA_PTR;
43 sunxi_monitor_composite_pal,
44 sunxi_monitor_composite_ntsc,
45 sunxi_monitor_composite_pal_m,
46 sunxi_monitor_composite_pal_nc,
48 #define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
50 struct sunxi_display {
51 GraphicDevice graphic_device;
52 enum sunxi_monitor monitor;
57 const struct ctfb_res_modes composite_video_modes[2] = {
58 /* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */
59 { 720, 576, 50, 37037, 27000, 137, 5, 20, 27, 2, 2, 0, FB_VMODE_INTERLACED },
60 { 720, 480, 60, 37037, 27000, 116, 20, 16, 27, 2, 2, 0, FB_VMODE_INTERLACED },
63 #ifdef CONFIG_VIDEO_HDMI
66 * Wait up to 200ms for value to be set in given part of reg.
68 static int await_completion(u32 *reg, u32 mask, u32 val)
70 unsigned long tmo = timer_get_us() + 200000;
72 while ((readl(reg) & mask) != val) {
73 if (timer_get_us() > tmo) {
74 printf("DDC: timeout reading EDID\n");
81 static int sunxi_hdmi_hpd_detect(int hpd_delay)
83 struct sunxi_ccm_reg * const ccm =
84 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
85 struct sunxi_hdmi_reg * const hdmi =
86 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
87 unsigned long tmo = timer_get_us() + hpd_delay * 1000;
89 /* Set pll3 to 300MHz */
90 clock_set_pll3(300000000);
92 /* Set hdmi parent to pll3 */
93 clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK,
96 /* Set ahb gating to pass */
97 #ifdef CONFIG_SUNXI_GEN_SUN6I
98 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
100 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
103 setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
105 writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl);
106 writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0);
108 while (timer_get_us() < tmo) {
109 if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT)
116 static void sunxi_hdmi_shutdown(void)
118 struct sunxi_ccm_reg * const ccm =
119 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
120 struct sunxi_hdmi_reg * const hdmi =
121 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
123 clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE);
124 clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
125 clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
126 #ifdef CONFIG_SUNXI_GEN_SUN6I
127 clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
132 static int sunxi_hdmi_ddc_do_command(u32 cmnd, int offset, int n)
134 struct sunxi_hdmi_reg * const hdmi =
135 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
137 setbits_le32(&hdmi->ddc_fifo_ctrl, SUNXI_HDMI_DDC_FIFO_CTRL_CLEAR);
138 writel(SUNXI_HMDI_DDC_ADDR_EDDC_SEGMENT(offset >> 8) |
139 SUNXI_HMDI_DDC_ADDR_EDDC_ADDR |
140 SUNXI_HMDI_DDC_ADDR_OFFSET(offset) |
141 SUNXI_HMDI_DDC_ADDR_SLAVE_ADDR, &hdmi->ddc_addr);
142 #ifndef CONFIG_MACH_SUN6I
143 writel(n, &hdmi->ddc_byte_count);
144 writel(cmnd, &hdmi->ddc_cmnd);
146 writel(n << 16 | cmnd, &hdmi->ddc_cmnd);
148 setbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START);
150 return await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START, 0);
153 static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count)
155 struct sunxi_hdmi_reg * const hdmi =
156 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
165 if (sunxi_hdmi_ddc_do_command(
166 SUNXI_HDMI_DDC_CMND_EXPLICIT_EDDC_READ,
170 for (i = 0; i < n; i++)
171 *buf++ = readb(&hdmi->ddc_fifo_data);
180 static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
185 r = sunxi_hdmi_ddc_read(block * 128, buf, 128);
188 r = edid_check_checksum(buf);
190 printf("EDID block %d: checksum error%s\n",
191 block, retries ? ", retrying" : "");
193 } while (r && retries--);
198 static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
200 struct edid1_info edid1;
201 struct edid_cea861_info cea681[4];
202 struct edid_detailed_timing *t =
203 (struct edid_detailed_timing *)edid1.monitor_details.timing;
204 struct sunxi_hdmi_reg * const hdmi =
205 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
206 struct sunxi_ccm_reg * const ccm =
207 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
208 int i, r, ext_blocks = 0;
210 /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */
211 writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE,
213 writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15),
215 writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
217 /* Reset i2c controller */
218 setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
219 writel(SUNXI_HMDI_DDC_CTRL_ENABLE |
220 SUNXI_HMDI_DDC_CTRL_SDA_ENABLE |
221 SUNXI_HMDI_DDC_CTRL_SCL_ENABLE |
222 SUNXI_HMDI_DDC_CTRL_RESET, &hdmi->ddc_ctrl);
223 if (await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_RESET, 0))
226 writel(SUNXI_HDMI_DDC_CLOCK, &hdmi->ddc_clock);
227 #ifndef CONFIG_MACH_SUN6I
228 writel(SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE |
229 SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, &hdmi->ddc_line_ctrl);
232 r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1);
234 r = edid_check_info(&edid1);
236 printf("EDID: invalid EDID data\n");
241 ext_blocks = edid1.extension_flag;
244 for (i = 0; i < ext_blocks; i++) {
245 if (sunxi_hdmi_edid_get_block(1 + i,
246 (u8 *)&cea681[i]) != 0) {
253 /* Disable DDC engine, no longer needed */
254 clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE);
255 clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
260 /* We want version 1.3 or 1.2 with detailed timing info */
261 if (edid1.version != 1 || (edid1.revision < 3 &&
262 !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) {
263 printf("EDID: unsupported version %d.%d\n",
264 edid1.version, edid1.revision);
268 /* Take the first usable detailed timing */
269 for (i = 0; i < 4; i++, t++) {
270 r = video_edid_dtd_to_ctfb_res_modes(t, mode);
275 printf("EDID: no usable detailed timing found\n");
279 /* Check for basic audio support, if found enable hdmi output */
280 sunxi_display.monitor = sunxi_monitor_dvi;
281 for (i = 0; i < ext_blocks; i++) {
282 if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
283 cea681[i].revision < 2)
286 if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
287 sunxi_display.monitor = sunxi_monitor_hdmi;
293 #endif /* CONFIG_VIDEO_HDMI */
295 #ifdef CONFIG_MACH_SUN4I
297 * Testing has shown that on sun4i the display backend engine does not have
298 * deep enough fifo-s causing flickering / tearing in full-hd mode due to
299 * fifo underruns. So on sun4i we use the display frontend engine to do the
300 * dma from memory, as the frontend does have deep enough fifo-s.
303 static const u32 sun4i_vert_coef[32] = {
304 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd,
305 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb,
306 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb,
307 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
308 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
309 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff,
310 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff,
311 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100,
314 static const u32 sun4i_horz_coef[64] = {
315 0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03,
316 0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06,
317 0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09,
318 0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f,
319 0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12,
320 0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18,
321 0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e,
322 0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23,
323 0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29,
324 0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e,
325 0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33,
326 0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37,
327 0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b,
328 0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e,
329 0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40,
330 0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42,
333 static void sunxi_frontend_init(void)
335 struct sunxi_ccm_reg * const ccm =
336 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
337 struct sunxi_de_fe_reg * const de_fe =
338 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
342 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0);
343 setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0);
344 clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000);
346 setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN);
348 for (i = 0; i < 32; i++) {
349 writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]);
350 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]);
351 writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]);
352 writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]);
353 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]);
354 writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]);
357 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY);
360 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
361 unsigned int address)
363 struct sunxi_de_fe_reg * const de_fe =
364 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
366 setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS);
367 writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr);
368 writel(mode->xres * 4, &de_fe->ch0_stride);
369 writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt);
370 writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt);
372 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
374 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
375 &de_fe->ch0_outsize);
376 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact);
377 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact);
379 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
381 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
382 &de_fe->ch1_outsize);
383 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact);
384 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact);
386 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY);
389 static void sunxi_frontend_enable(void)
391 struct sunxi_de_fe_reg * const de_fe =
392 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
394 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START);
397 static void sunxi_frontend_init(void) {}
398 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
399 unsigned int address) {}
400 static void sunxi_frontend_enable(void) {}
403 static bool sunxi_is_composite(void)
405 switch (sunxi_display.monitor) {
406 case sunxi_monitor_none:
407 case sunxi_monitor_dvi:
408 case sunxi_monitor_hdmi:
409 case sunxi_monitor_lcd:
410 case sunxi_monitor_vga:
412 case sunxi_monitor_composite_pal:
413 case sunxi_monitor_composite_ntsc:
414 case sunxi_monitor_composite_pal_m:
415 case sunxi_monitor_composite_pal_nc:
419 return false; /* Never reached */
423 * This is the entity that mixes and matches the different layers and inputs.
424 * Allwinner calls it the back-end, but i like composer better.
426 static void sunxi_composer_init(void)
428 struct sunxi_ccm_reg * const ccm =
429 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
430 struct sunxi_de_be_reg * const de_be =
431 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
434 sunxi_frontend_init();
436 #ifdef CONFIG_SUNXI_GEN_SUN6I
438 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
442 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0);
443 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
444 setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0);
446 clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000);
448 /* Engine bug, clear registers after reset */
449 for (i = 0x0800; i < 0x1000; i += 4)
450 writel(0, SUNXI_DE_BE0_BASE + i);
452 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
455 static u32 sunxi_rgb2yuv_coef[12] = {
456 0x00000107, 0x00000204, 0x00000064, 0x00000108,
457 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
458 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
461 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
462 unsigned int address)
464 struct sunxi_de_be_reg * const de_be =
465 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
468 sunxi_frontend_mode_set(mode, address);
470 writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
472 writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
473 &de_be->layer0_size);
474 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
475 writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride);
476 writel(address << 3, &de_be->layer0_addr_low32b);
477 writel(address >> 29, &de_be->layer0_addr_high4b);
479 writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl);
481 writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
483 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
484 if (mode->vmode == FB_VMODE_INTERLACED)
485 setbits_le32(&de_be->mode,
486 SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
487 SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
489 if (sunxi_is_composite()) {
490 writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
491 &de_be->output_color_ctrl);
492 for (i = 0; i < 12; i++)
493 writel(sunxi_rgb2yuv_coef[i],
494 &de_be->output_color_coef[i]);
498 static void sunxi_composer_enable(void)
500 struct sunxi_de_be_reg * const de_be =
501 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
503 sunxi_frontend_enable();
505 setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
506 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
510 * LCDC, what allwinner calls a CRTC, so timing controller and serializer.
512 static void sunxi_lcdc_pll_set(int tcon, int dotclock,
513 int *clk_div, int *clk_double)
515 struct sunxi_ccm_reg * const ccm =
516 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
517 int value, n, m, min_m, max_m, diff;
518 int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
522 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
526 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
535 * Find the lowest divider resulting in a matching clock, if there
536 * is no match, pick the closest lower clock, as monitors tend to
537 * not sync to higher frequencies.
539 for (m = min_m; m <= max_m; m++) {
540 n = (m * dotclock) / 3000;
542 if ((n >= 9) && (n <= 127)) {
543 value = (3000 * n) / m;
544 diff = dotclock - value;
545 if (diff < best_diff) {
553 /* These are just duplicates */
557 n = (m * dotclock) / 6000;
558 if ((n >= 9) && (n <= 127)) {
559 value = (6000 * n) / m;
560 diff = dotclock - value;
561 if (diff < best_diff) {
570 debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n",
571 dotclock, (best_double + 1) * 3000 * best_n / best_m,
572 best_double + 1, best_n, best_m);
574 clock_set_pll3(best_n * 3000000);
577 writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST |
578 (best_double ? CCM_LCD_CH0_CTRL_PLL3_2X :
579 CCM_LCD_CH0_CTRL_PLL3),
580 &ccm->lcd0_ch0_clk_cfg);
582 writel(CCM_LCD_CH1_CTRL_GATE |
583 (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
584 CCM_LCD_CH1_CTRL_PLL3) |
585 CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
586 if (sunxi_is_composite())
587 setbits_le32(&ccm->lcd0_ch1_clk_cfg,
588 CCM_LCD_CH1_CTRL_HALF_SCLK1);
592 *clk_double = best_double;
595 static void sunxi_lcdc_init(void)
597 struct sunxi_ccm_reg * const ccm =
598 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
599 struct sunxi_lcdc_reg * const lcdc =
600 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
603 #ifdef CONFIG_SUNXI_GEN_SUN6I
604 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
606 setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST);
610 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
611 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
612 #ifdef CONFIG_SUNXI_GEN_SUN6I
613 setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS);
615 setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
620 writel(0, &lcdc->ctrl); /* Disable tcon */
621 writel(0, &lcdc->int0); /* Disable all interrupts */
623 /* Disable tcon0 dot clock */
624 clrbits_le32(&lcdc->tcon0_dclk, SUNXI_LCDC_TCON0_DCLK_ENABLE);
626 /* Set all io lines to tristate */
627 writel(0xffffffff, &lcdc->tcon0_io_tristate);
628 writel(0xffffffff, &lcdc->tcon1_io_tristate);
631 static void sunxi_lcdc_enable(void)
633 struct sunxi_lcdc_reg * const lcdc =
634 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
636 setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
637 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
638 setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE);
639 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0);
640 #ifdef CONFIG_SUNXI_GEN_SUN6I
641 udelay(2); /* delay at least 1200 ns */
642 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB);
643 udelay(2); /* delay at least 1200 ns */
644 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC);
645 if (sunxi_display.depth == 18)
646 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7));
648 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf));
650 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
651 udelay(2); /* delay at least 1200 ns */
652 setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1);
653 udelay(1); /* delay at least 120 ns */
654 setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2);
655 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
660 static void sunxi_lcdc_panel_enable(void)
665 * Start with backlight disabled to avoid the screen flashing to
666 * white while the lcd inits.
668 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
670 gpio_request(pin, "lcd_backlight_enable");
671 gpio_direction_output(pin, 0);
674 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
676 gpio_request(pin, "lcd_backlight_pwm");
677 gpio_direction_output(pin, PWM_OFF);
680 reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET);
681 if (reset_pin >= 0) {
682 gpio_request(reset_pin, "lcd_reset");
683 gpio_direction_output(reset_pin, 0); /* Assert reset */
686 /* Give the backlight some time to turn off and power up the panel. */
688 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
690 gpio_request(pin, "lcd_power");
691 gpio_direction_output(pin, 1);
695 gpio_direction_output(reset_pin, 1); /* De-assert reset */
698 static void sunxi_lcdc_backlight_enable(void)
703 * We want to have scanned out at least one frame before enabling the
704 * backlight to avoid the screen flashing to white when we enable it.
708 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
710 gpio_direction_output(pin, 1);
712 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
714 gpio_direction_output(pin, PWM_ON);
717 static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)
721 delay = mode->lower_margin + mode->vsync_len + mode->upper_margin;
722 if (mode->vmode == FB_VMODE_INTERLACED)
727 return (delay > 30) ? 30 : delay;
730 static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
731 bool for_ext_vga_dac)
733 struct sunxi_lcdc_reg * const lcdc =
734 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
735 int bp, clk_delay, clk_div, clk_double, pin, total, val;
737 for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
738 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
739 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
741 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
742 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
745 sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
748 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
749 SUNXI_LCDC_CTRL_IO_MAP_TCON0);
751 clk_delay = sunxi_lcdc_get_clk_delay(mode, 0);
752 writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
753 SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
755 writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
756 SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
758 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
759 &lcdc->tcon0_timing_active);
761 bp = mode->hsync_len + mode->left_margin;
762 total = mode->xres + mode->right_margin + bp;
763 writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
764 SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
766 bp = mode->vsync_len + mode->upper_margin;
767 total = mode->yres + mode->lower_margin + bp;
768 writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
769 SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
771 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
772 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
773 &lcdc->tcon0_timing_sync);
775 writel(0, &lcdc->tcon0_hv_intf);
776 writel(0, &lcdc->tcon0_cpu_intf);
778 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
779 val = (sunxi_display.depth == 18) ? 1 : 0;
780 writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
781 SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
784 if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {
785 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
786 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]);
787 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]);
788 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]);
789 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]);
790 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]);
791 writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]);
792 writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]);
793 writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]);
794 writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]);
795 writel(((sunxi_display.depth == 18) ?
796 SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 :
797 SUNXI_LCDC_TCON0_FRM_CTRL_RGB565),
798 &lcdc->tcon0_frm_ctrl);
801 val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(CONFIG_VIDEO_LCD_DCLK_PHASE);
802 if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
803 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
804 if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
805 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
807 #ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
811 writel(val, &lcdc->tcon0_io_polarity);
813 writel(0, &lcdc->tcon0_io_tristate);
816 #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
817 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
818 int *clk_div, int *clk_double,
819 bool use_portd_hvsync)
821 struct sunxi_lcdc_reg * const lcdc =
822 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
823 int bp, clk_delay, total, val, yres;
826 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
827 SUNXI_LCDC_CTRL_IO_MAP_TCON1);
829 clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
830 writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
831 ((mode->vmode == FB_VMODE_INTERLACED) ?
832 SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
833 SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
836 if (mode->vmode == FB_VMODE_INTERLACED)
838 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
839 &lcdc->tcon1_timing_source);
840 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
841 &lcdc->tcon1_timing_scale);
842 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
843 &lcdc->tcon1_timing_out);
845 bp = mode->hsync_len + mode->left_margin;
846 total = mode->xres + mode->right_margin + bp;
847 writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) |
848 SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h);
850 bp = mode->vsync_len + mode->upper_margin;
851 total = mode->yres + mode->lower_margin + bp;
852 if (mode->vmode == FB_VMODE_NONINTERLACED)
854 writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
855 SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
857 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
858 &lcdc->tcon1_timing_sync);
860 if (use_portd_hvsync) {
861 sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
862 sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0);
865 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
866 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
867 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
868 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
869 writel(val, &lcdc->tcon1_io_polarity);
871 clrbits_le32(&lcdc->tcon1_io_tristate,
872 SUNXI_LCDC_TCON_VSYNC_MASK |
873 SUNXI_LCDC_TCON_HSYNC_MASK);
875 sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
877 #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
879 #ifdef CONFIG_VIDEO_HDMI
881 static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
883 struct sunxi_hdmi_reg * const hdmi =
884 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
886 u8 avi_info_frame[17] = {
887 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00,
888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
891 u8 vendor_info_frame[19] = {
892 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40,
893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
898 if (mode->pixclock_khz <= 27000)
899 avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */
901 avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */
903 if (mode->xres * 100 / mode->yres < 156)
904 avi_info_frame[5] |= 0x18; /* 4 : 3 */
906 avi_info_frame[5] |= 0x28; /* 16 : 9 */
908 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
909 checksum += avi_info_frame[i];
911 avi_info_frame[3] = 0x100 - checksum;
913 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
914 writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]);
916 writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0);
917 writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1);
919 for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++)
920 writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]);
922 writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0);
923 writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1);
925 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI);
928 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
929 int clk_div, int clk_double)
931 struct sunxi_hdmi_reg * const hdmi =
932 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
935 /* Write clear interrupt status bits */
936 writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
938 if (sunxi_display.monitor == sunxi_monitor_hdmi)
939 sunxi_hdmi_setup_info_frames(mode);
941 /* Set input sync enable */
942 writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown);
944 /* Init various registers, select pll3 as clock source */
945 writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity);
946 writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0);
947 writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1);
948 writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl);
949 writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
951 /* Setup clk div and doubler */
952 clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK,
953 SUNXI_HDMI_PLL_CTRL_DIV(clk_div));
955 setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE);
957 /* Setup timing registers */
958 writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres),
961 x = mode->hsync_len + mode->left_margin;
962 y = mode->vsync_len + mode->upper_margin;
963 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp);
965 x = mode->right_margin;
966 y = mode->lower_margin;
967 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp);
971 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw);
973 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
974 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR);
976 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
977 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER);
980 static void sunxi_hdmi_enable(void)
982 struct sunxi_hdmi_reg * const hdmi =
983 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
986 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
989 #endif /* CONFIG_VIDEO_HDMI */
991 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
993 static void sunxi_tvencoder_mode_set(void)
995 struct sunxi_ccm_reg * const ccm =
996 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
997 struct sunxi_tve_reg * const tve =
998 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1001 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
1003 switch (sunxi_display.monitor) {
1004 case sunxi_monitor_vga:
1005 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1006 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1007 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
1008 writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
1009 writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
1010 writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
1012 case sunxi_monitor_composite_pal_nc:
1013 writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
1015 case sunxi_monitor_composite_pal:
1016 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1017 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1018 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1019 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1020 writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
1021 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1022 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1023 writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
1024 writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
1025 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
1026 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1027 writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
1028 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1029 writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
1030 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1031 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1032 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1033 writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
1034 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1036 case sunxi_monitor_composite_pal_m:
1037 writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
1038 writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
1040 case sunxi_monitor_composite_ntsc:
1041 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1042 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1043 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1044 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1045 writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
1046 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1047 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1048 writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
1049 writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
1050 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
1051 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1052 writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
1053 writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
1054 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1055 writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
1056 writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
1057 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1058 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1059 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1060 writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
1061 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1063 case sunxi_monitor_none:
1064 case sunxi_monitor_dvi:
1065 case sunxi_monitor_hdmi:
1066 case sunxi_monitor_lcd:
1071 static void sunxi_tvencoder_enable(void)
1073 struct sunxi_tve_reg * const tve =
1074 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1076 setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
1079 #endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
1081 static void sunxi_drc_init(void)
1083 #ifdef CONFIG_SUNXI_GEN_SUN6I
1084 struct sunxi_ccm_reg * const ccm =
1085 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1087 /* On sun6i the drc must be clocked even when in pass-through mode */
1088 #ifdef CONFIG_MACH_SUN8I_A33
1089 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT);
1091 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0);
1092 clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000);
1096 #ifdef CONFIG_VIDEO_VGA_VIA_LCD
1097 static void sunxi_vga_external_dac_enable(void)
1101 pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN);
1103 gpio_request(pin, "vga_enable");
1104 gpio_direction_output(pin, 1);
1107 #endif /* CONFIG_VIDEO_VGA_VIA_LCD */
1109 #ifdef CONFIG_VIDEO_LCD_SSD2828
1110 static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
1112 struct ssd2828_config cfg = {
1113 .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS),
1114 .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK),
1115 .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI),
1116 .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO),
1117 .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET),
1118 .ssd2828_tx_clk_khz = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000,
1119 .ssd2828_color_depth = 24,
1120 #ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
1121 .mipi_dsi_number_of_data_lanes = 4,
1122 .mipi_dsi_bitrate_per_data_lane_mbps = 513,
1123 .mipi_dsi_delay_after_exit_sleep_mode_ms = 100,
1124 .mipi_dsi_delay_after_set_display_on_ms = 200
1126 #error MIPI LCD panel needs configuration parameters
1130 if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) {
1131 printf("SSD2828: SPI pins are not properly configured\n");
1134 if (cfg.reset_pin == -1) {
1135 printf("SSD2828: Reset pin is not properly configured\n");
1139 return ssd2828_init(&cfg, mode);
1141 #endif /* CONFIG_VIDEO_LCD_SSD2828 */
1143 static void sunxi_engines_init(void)
1145 sunxi_composer_init();
1150 static void sunxi_mode_set(const struct ctfb_res_modes *mode,
1151 unsigned int address)
1153 int __maybe_unused clk_div, clk_double;
1155 switch (sunxi_display.monitor) {
1156 case sunxi_monitor_none:
1158 case sunxi_monitor_dvi:
1159 case sunxi_monitor_hdmi:
1160 #ifdef CONFIG_VIDEO_HDMI
1161 sunxi_composer_mode_set(mode, address);
1162 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1163 sunxi_hdmi_mode_set(mode, clk_div, clk_double);
1164 sunxi_composer_enable();
1165 sunxi_lcdc_enable();
1166 sunxi_hdmi_enable();
1169 case sunxi_monitor_lcd:
1170 sunxi_lcdc_panel_enable();
1171 if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
1172 mdelay(50); /* Wait for lcd controller power on */
1173 hitachi_tx18d42vm_init();
1175 if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
1176 unsigned int orig_i2c_bus = i2c_get_bus_num();
1177 i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
1178 i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
1179 i2c_set_bus_num(orig_i2c_bus);
1181 sunxi_composer_mode_set(mode, address);
1182 sunxi_lcdc_tcon0_mode_set(mode, false);
1183 sunxi_composer_enable();
1184 sunxi_lcdc_enable();
1185 #ifdef CONFIG_VIDEO_LCD_SSD2828
1186 sunxi_ssd2828_init(mode);
1188 sunxi_lcdc_backlight_enable();
1190 case sunxi_monitor_vga:
1191 #ifdef CONFIG_VIDEO_VGA
1192 sunxi_composer_mode_set(mode, address);
1193 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
1194 sunxi_tvencoder_mode_set();
1195 sunxi_composer_enable();
1196 sunxi_lcdc_enable();
1197 sunxi_tvencoder_enable();
1198 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1199 sunxi_composer_mode_set(mode, address);
1200 sunxi_lcdc_tcon0_mode_set(mode, true);
1201 sunxi_composer_enable();
1202 sunxi_lcdc_enable();
1203 sunxi_vga_external_dac_enable();
1206 case sunxi_monitor_composite_pal:
1207 case sunxi_monitor_composite_ntsc:
1208 case sunxi_monitor_composite_pal_m:
1209 case sunxi_monitor_composite_pal_nc:
1210 #ifdef CONFIG_VIDEO_COMPOSITE
1211 sunxi_composer_mode_set(mode, address);
1212 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1213 sunxi_tvencoder_mode_set();
1214 sunxi_composer_enable();
1215 sunxi_lcdc_enable();
1216 sunxi_tvencoder_enable();
1222 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
1225 case sunxi_monitor_none: return "none";
1226 case sunxi_monitor_dvi: return "dvi";
1227 case sunxi_monitor_hdmi: return "hdmi";
1228 case sunxi_monitor_lcd: return "lcd";
1229 case sunxi_monitor_vga: return "vga";
1230 case sunxi_monitor_composite_pal: return "composite-pal";
1231 case sunxi_monitor_composite_ntsc: return "composite-ntsc";
1232 case sunxi_monitor_composite_pal_m: return "composite-pal-m";
1233 case sunxi_monitor_composite_pal_nc: return "composite-pal-nc";
1235 return NULL; /* never reached */
1238 ulong board_get_usable_ram_top(ulong total_size)
1240 return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
1243 static bool sunxi_has_hdmi(void)
1245 #ifdef CONFIG_VIDEO_HDMI
1252 static bool sunxi_has_lcd(void)
1254 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1256 return lcd_mode[0] != 0;
1259 static bool sunxi_has_vga(void)
1261 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
1268 static bool sunxi_has_composite(void)
1270 #ifdef CONFIG_VIDEO_COMPOSITE
1277 static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
1279 if (allow_hdmi && sunxi_has_hdmi())
1280 return sunxi_monitor_dvi;
1281 else if (sunxi_has_lcd())
1282 return sunxi_monitor_lcd;
1283 else if (sunxi_has_vga())
1284 return sunxi_monitor_vga;
1285 else if (sunxi_has_composite())
1286 return sunxi_monitor_composite_pal;
1288 return sunxi_monitor_none;
1291 void *video_hw_init(void)
1293 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1294 const struct ctfb_res_modes *mode;
1295 struct ctfb_res_modes custom;
1296 const char *options;
1297 #ifdef CONFIG_VIDEO_HDMI
1298 int ret, hpd, hpd_delay, edid;
1301 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1304 memset(&sunxi_display, 0, sizeof(struct sunxi_display));
1306 video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
1307 &sunxi_display.depth, &options);
1308 #ifdef CONFIG_VIDEO_HDMI
1309 hpd = video_get_option_int(options, "hpd", 1);
1310 hpd_delay = video_get_option_int(options, "hpd_delay", 500);
1311 edid = video_get_option_int(options, "edid", 1);
1313 sunxi_display.monitor = sunxi_get_default_mon(true);
1314 video_get_option_string(options, "monitor", mon, sizeof(mon),
1315 sunxi_get_mon_desc(sunxi_display.monitor));
1316 for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
1317 if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
1318 sunxi_display.monitor = i;
1322 if (i > SUNXI_MONITOR_LAST)
1323 printf("Unknown monitor: '%s', falling back to '%s'\n",
1324 mon, sunxi_get_mon_desc(sunxi_display.monitor));
1326 #ifdef CONFIG_VIDEO_HDMI
1327 /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
1328 if (sunxi_display.monitor == sunxi_monitor_dvi ||
1329 sunxi_display.monitor == sunxi_monitor_hdmi) {
1330 /* Always call hdp_detect, as it also enables clocks, etc. */
1331 ret = sunxi_hdmi_hpd_detect(hpd_delay);
1333 printf("HDMI connected: ");
1334 if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
1337 sunxi_hdmi_shutdown();
1338 sunxi_display.monitor = sunxi_get_default_mon(false);
1339 } /* else continue with hdmi/dvi without a cable connected */
1343 switch (sunxi_display.monitor) {
1344 case sunxi_monitor_none:
1346 case sunxi_monitor_dvi:
1347 case sunxi_monitor_hdmi:
1348 if (!sunxi_has_hdmi()) {
1349 printf("HDMI/DVI not supported on this board\n");
1350 sunxi_display.monitor = sunxi_monitor_none;
1354 case sunxi_monitor_lcd:
1355 if (!sunxi_has_lcd()) {
1356 printf("LCD not supported on this board\n");
1357 sunxi_display.monitor = sunxi_monitor_none;
1360 sunxi_display.depth = video_get_params(&custom, lcd_mode);
1363 case sunxi_monitor_vga:
1364 if (!sunxi_has_vga()) {
1365 printf("VGA not supported on this board\n");
1366 sunxi_display.monitor = sunxi_monitor_none;
1369 sunxi_display.depth = 18;
1371 case sunxi_monitor_composite_pal:
1372 case sunxi_monitor_composite_ntsc:
1373 case sunxi_monitor_composite_pal_m:
1374 case sunxi_monitor_composite_pal_nc:
1375 if (!sunxi_has_composite()) {
1376 printf("Composite video not supported on this board\n");
1377 sunxi_display.monitor = sunxi_monitor_none;
1380 if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
1381 sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
1382 mode = &composite_video_modes[0];
1384 mode = &composite_video_modes[1];
1385 sunxi_display.depth = 24;
1389 sunxi_display.fb_size =
1390 (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
1391 if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
1392 printf("Error need %dkB for fb, but only %dkB is reserved\n",
1393 sunxi_display.fb_size >> 10,
1394 CONFIG_SUNXI_MAX_FB_SIZE >> 10);
1398 printf("Setting up a %dx%d%s %s console\n", mode->xres, mode->yres,
1399 (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
1400 sunxi_get_mon_desc(sunxi_display.monitor));
1402 gd->fb_base = gd->bd->bi_dram[0].start +
1403 gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1404 sunxi_engines_init();
1405 sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE);
1408 * These are the only members of this structure that are used. All the
1409 * others are driver specific. There is nothing to decribe pitch or
1410 * stride, but we are lucky with our hw.
1412 graphic_device->frameAdrs = gd->fb_base;
1413 graphic_device->gdfIndex = GDF_32BIT_X888RGB;
1414 graphic_device->gdfBytesPP = 4;
1415 graphic_device->winSizeX = mode->xres;
1416 graphic_device->winSizeY = mode->yres;
1418 return graphic_device;
1424 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
1425 int sunxi_simplefb_setup(void *blob)
1427 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1430 const char *pipeline = NULL;
1432 #ifdef CONFIG_MACH_SUN4I
1433 #define PIPELINE_PREFIX "de_fe0-"
1435 #define PIPELINE_PREFIX
1438 switch (sunxi_display.monitor) {
1439 case sunxi_monitor_none:
1441 case sunxi_monitor_dvi:
1442 case sunxi_monitor_hdmi:
1443 pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi";
1445 case sunxi_monitor_lcd:
1446 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1448 case sunxi_monitor_vga:
1449 #ifdef CONFIG_VIDEO_VGA
1450 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1451 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1452 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1455 case sunxi_monitor_composite_pal:
1456 case sunxi_monitor_composite_ntsc:
1457 case sunxi_monitor_composite_pal_m:
1458 case sunxi_monitor_composite_pal_nc:
1459 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1463 /* Find a prefilled simpefb node, matching out pipeline config */
1464 offset = fdt_node_offset_by_compatible(blob, -1,
1465 "allwinner,simple-framebuffer");
1466 while (offset >= 0) {
1467 ret = fdt_find_string(blob, offset, "allwinner,pipeline",
1471 offset = fdt_node_offset_by_compatible(blob, offset,
1472 "allwinner,simple-framebuffer");
1475 eprintf("Cannot setup simplefb: node not found\n");
1476 return 0; /* Keep older kernels working */
1480 * Do not report the framebuffer as free RAM to the OS, note we cannot
1481 * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
1482 * and e.g. Linux refuses to iomap RAM on ARM, see:
1483 * linux/arch/arm/mm/ioremap.c around line 301.
1485 start = gd->bd->bi_dram[0].start;
1486 size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1487 ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
1489 eprintf("Cannot setup simplefb: Error reserving memory\n");
1493 ret = fdt_setup_simplefb_node(blob, offset, gd->fb_base,
1494 graphic_device->winSizeX, graphic_device->winSizeY,
1495 graphic_device->winSizeX * graphic_device->gdfBytesPP,
1498 eprintf("Cannot setup simplefb: Error setting properties\n");
1502 #endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */