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>
21 #include <fdt_support.h>
25 #include "videomodes.h"
27 #include "hitachi_tx18d42vm_lcd.h"
30 #ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW
38 DECLARE_GLOBAL_DATA_PTR;
46 sunxi_monitor_composite_pal,
47 sunxi_monitor_composite_ntsc,
48 sunxi_monitor_composite_pal_m,
49 sunxi_monitor_composite_pal_nc,
51 #define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
53 struct sunxi_display {
54 GraphicDevice graphic_device;
55 enum sunxi_monitor monitor;
61 const struct ctfb_res_modes composite_video_modes[2] = {
62 /* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */
63 { 720, 576, 50, 37037, 27000, 137, 5, 20, 27, 2, 2, 0, FB_VMODE_INTERLACED },
64 { 720, 480, 60, 37037, 27000, 116, 20, 16, 27, 2, 2, 0, FB_VMODE_INTERLACED },
67 #ifdef CONFIG_VIDEO_HDMI
70 * Wait up to 200ms for value to be set in given part of reg.
72 static int await_completion(u32 *reg, u32 mask, u32 val)
74 unsigned long tmo = timer_get_us() + 200000;
76 while ((readl(reg) & mask) != val) {
77 if (timer_get_us() > tmo) {
78 printf("DDC: timeout reading EDID\n");
85 static int sunxi_hdmi_hpd_detect(int hpd_delay)
87 struct sunxi_ccm_reg * const ccm =
88 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
89 struct sunxi_hdmi_reg * const hdmi =
90 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
91 unsigned long tmo = timer_get_us() + hpd_delay * 1000;
93 /* Set pll3 to 300MHz */
94 clock_set_pll3(300000000);
96 /* Set hdmi parent to pll3 */
97 clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK,
100 /* Set ahb gating to pass */
101 #ifdef CONFIG_SUNXI_GEN_SUN6I
102 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
104 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
107 setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
109 writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl);
110 writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0);
112 while (timer_get_us() < tmo) {
113 if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT)
120 static void sunxi_hdmi_shutdown(void)
122 struct sunxi_ccm_reg * const ccm =
123 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
124 struct sunxi_hdmi_reg * const hdmi =
125 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
127 clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE);
128 clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
129 clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
130 #ifdef CONFIG_SUNXI_GEN_SUN6I
131 clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
136 static int sunxi_hdmi_ddc_do_command(u32 cmnd, int offset, int n)
138 struct sunxi_hdmi_reg * const hdmi =
139 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
141 setbits_le32(&hdmi->ddc_fifo_ctrl, SUNXI_HDMI_DDC_FIFO_CTRL_CLEAR);
142 writel(SUNXI_HMDI_DDC_ADDR_EDDC_SEGMENT(offset >> 8) |
143 SUNXI_HMDI_DDC_ADDR_EDDC_ADDR |
144 SUNXI_HMDI_DDC_ADDR_OFFSET(offset) |
145 SUNXI_HMDI_DDC_ADDR_SLAVE_ADDR, &hdmi->ddc_addr);
146 #ifndef CONFIG_MACH_SUN6I
147 writel(n, &hdmi->ddc_byte_count);
148 writel(cmnd, &hdmi->ddc_cmnd);
150 writel(n << 16 | cmnd, &hdmi->ddc_cmnd);
152 setbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START);
154 return await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START, 0);
157 static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count)
159 struct sunxi_hdmi_reg * const hdmi =
160 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
169 if (sunxi_hdmi_ddc_do_command(
170 SUNXI_HDMI_DDC_CMND_EXPLICIT_EDDC_READ,
174 for (i = 0; i < n; i++)
175 *buf++ = readb(&hdmi->ddc_fifo_data);
184 static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
189 r = sunxi_hdmi_ddc_read(block * 128, buf, 128);
192 r = edid_check_checksum(buf);
194 printf("EDID block %d: checksum error%s\n",
195 block, retries ? ", retrying" : "");
197 } while (r && retries--);
202 static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
204 struct edid1_info edid1;
205 struct edid_cea861_info cea681[4];
206 struct edid_detailed_timing *t =
207 (struct edid_detailed_timing *)edid1.monitor_details.timing;
208 struct sunxi_hdmi_reg * const hdmi =
209 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
210 struct sunxi_ccm_reg * const ccm =
211 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
212 int i, r, ext_blocks = 0;
214 /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */
215 writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE,
217 writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15),
219 writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
221 /* Reset i2c controller */
222 setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
223 writel(SUNXI_HMDI_DDC_CTRL_ENABLE |
224 SUNXI_HMDI_DDC_CTRL_SDA_ENABLE |
225 SUNXI_HMDI_DDC_CTRL_SCL_ENABLE |
226 SUNXI_HMDI_DDC_CTRL_RESET, &hdmi->ddc_ctrl);
227 if (await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_RESET, 0))
230 writel(SUNXI_HDMI_DDC_CLOCK, &hdmi->ddc_clock);
231 #ifndef CONFIG_MACH_SUN6I
232 writel(SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE |
233 SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, &hdmi->ddc_line_ctrl);
236 r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1);
238 r = edid_check_info(&edid1);
240 printf("EDID: invalid EDID data\n");
245 ext_blocks = edid1.extension_flag;
248 for (i = 0; i < ext_blocks; i++) {
249 if (sunxi_hdmi_edid_get_block(1 + i,
250 (u8 *)&cea681[i]) != 0) {
257 /* Disable DDC engine, no longer needed */
258 clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE);
259 clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
264 /* We want version 1.3 or 1.2 with detailed timing info */
265 if (edid1.version != 1 || (edid1.revision < 3 &&
266 !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) {
267 printf("EDID: unsupported version %d.%d\n",
268 edid1.version, edid1.revision);
272 /* Take the first usable detailed timing */
273 for (i = 0; i < 4; i++, t++) {
274 r = video_edid_dtd_to_ctfb_res_modes(t, mode);
279 printf("EDID: no usable detailed timing found\n");
283 /* Check for basic audio support, if found enable hdmi output */
284 sunxi_display.monitor = sunxi_monitor_dvi;
285 for (i = 0; i < ext_blocks; i++) {
286 if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
287 cea681[i].revision < 2)
290 if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
291 sunxi_display.monitor = sunxi_monitor_hdmi;
297 #endif /* CONFIG_VIDEO_HDMI */
299 #ifdef CONFIG_MACH_SUN4I
301 * Testing has shown that on sun4i the display backend engine does not have
302 * deep enough fifo-s causing flickering / tearing in full-hd mode due to
303 * fifo underruns. So on sun4i we use the display frontend engine to do the
304 * dma from memory, as the frontend does have deep enough fifo-s.
307 static const u32 sun4i_vert_coef[32] = {
308 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd,
309 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb,
310 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb,
311 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
312 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
313 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff,
314 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff,
315 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100,
318 static const u32 sun4i_horz_coef[64] = {
319 0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03,
320 0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06,
321 0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09,
322 0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f,
323 0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12,
324 0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18,
325 0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e,
326 0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23,
327 0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29,
328 0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e,
329 0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33,
330 0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37,
331 0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b,
332 0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e,
333 0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40,
334 0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42,
337 static void sunxi_frontend_init(void)
339 struct sunxi_ccm_reg * const ccm =
340 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
341 struct sunxi_de_fe_reg * const de_fe =
342 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
346 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0);
347 setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0);
348 clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000);
350 setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN);
352 for (i = 0; i < 32; i++) {
353 writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]);
354 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]);
355 writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]);
356 writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]);
357 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]);
358 writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]);
361 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY);
364 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
365 unsigned int address)
367 struct sunxi_de_fe_reg * const de_fe =
368 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
370 setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS);
371 writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr);
372 writel(mode->xres * 4, &de_fe->ch0_stride);
373 writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt);
374 writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt);
376 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
378 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
379 &de_fe->ch0_outsize);
380 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact);
381 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact);
383 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
385 writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
386 &de_fe->ch1_outsize);
387 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact);
388 writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact);
390 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY);
393 static void sunxi_frontend_enable(void)
395 struct sunxi_de_fe_reg * const de_fe =
396 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
398 setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START);
401 static void sunxi_frontend_init(void) {}
402 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
403 unsigned int address) {}
404 static void sunxi_frontend_enable(void) {}
407 static bool sunxi_is_composite(void)
409 switch (sunxi_display.monitor) {
410 case sunxi_monitor_none:
411 case sunxi_monitor_dvi:
412 case sunxi_monitor_hdmi:
413 case sunxi_monitor_lcd:
414 case sunxi_monitor_vga:
416 case sunxi_monitor_composite_pal:
417 case sunxi_monitor_composite_ntsc:
418 case sunxi_monitor_composite_pal_m:
419 case sunxi_monitor_composite_pal_nc:
423 return false; /* Never reached */
427 * This is the entity that mixes and matches the different layers and inputs.
428 * Allwinner calls it the back-end, but i like composer better.
430 static void sunxi_composer_init(void)
432 struct sunxi_ccm_reg * const ccm =
433 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
434 struct sunxi_de_be_reg * const de_be =
435 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
438 sunxi_frontend_init();
440 #ifdef CONFIG_SUNXI_GEN_SUN6I
442 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
446 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0);
447 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
448 setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0);
450 clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000);
452 /* Engine bug, clear registers after reset */
453 for (i = 0x0800; i < 0x1000; i += 4)
454 writel(0, SUNXI_DE_BE0_BASE + i);
456 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
459 static u32 sunxi_rgb2yuv_coef[12] = {
460 0x00000107, 0x00000204, 0x00000064, 0x00000108,
461 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
462 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
465 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
466 unsigned int address)
468 struct sunxi_de_be_reg * const de_be =
469 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
472 sunxi_frontend_mode_set(mode, address);
474 writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
476 writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
477 &de_be->layer0_size);
478 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
479 writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride);
480 writel(address << 3, &de_be->layer0_addr_low32b);
481 writel(address >> 29, &de_be->layer0_addr_high4b);
483 writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl);
485 writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
487 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
488 if (mode->vmode == FB_VMODE_INTERLACED)
489 setbits_le32(&de_be->mode,
490 #ifndef CONFIG_MACH_SUN5I
491 SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
493 SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
495 if (sunxi_is_composite()) {
496 writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
497 &de_be->output_color_ctrl);
498 for (i = 0; i < 12; i++)
499 writel(sunxi_rgb2yuv_coef[i],
500 &de_be->output_color_coef[i]);
504 static void sunxi_composer_enable(void)
506 struct sunxi_de_be_reg * const de_be =
507 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
509 sunxi_frontend_enable();
511 setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
512 setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
516 * LCDC, what allwinner calls a CRTC, so timing controller and serializer.
518 static void sunxi_lcdc_pll_set(int tcon, int dotclock,
519 int *clk_div, int *clk_double)
521 struct sunxi_ccm_reg * const ccm =
522 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
523 int value, n, m, min_m, max_m, diff;
524 int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
526 bool use_mipi_pll = false;
529 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
533 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
542 * Find the lowest divider resulting in a matching clock, if there
543 * is no match, pick the closest lower clock, as monitors tend to
544 * not sync to higher frequencies.
546 for (m = min_m; m <= max_m; m++) {
547 n = (m * dotclock) / 3000;
549 if ((n >= 9) && (n <= 127)) {
550 value = (3000 * n) / m;
551 diff = dotclock - value;
552 if (diff < best_diff) {
560 /* These are just duplicates */
564 n = (m * dotclock) / 6000;
565 if ((n >= 9) && (n <= 127)) {
566 value = (6000 * n) / m;
567 diff = dotclock - value;
568 if (diff < best_diff) {
577 #ifdef CONFIG_MACH_SUN6I
579 * Use the MIPI pll if we've been unable to find any matching setting
580 * for PLL3, this happens with high dotclocks because of min_m = 6.
582 if (tcon == 0 && best_n == 0) {
584 best_m = 6; /* Minimum m for tcon0 */
588 clock_set_pll3(297000000); /* Fix the video pll at 297 MHz */
589 clock_set_mipi_pll(best_m * dotclock * 1000);
590 debug("dotclock: %dkHz = %dkHz via mipi pll\n",
591 dotclock, clock_get_mipi_pll() / best_m / 1000);
595 clock_set_pll3(best_n * 3000000);
596 debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n",
598 (best_double + 1) * clock_get_pll3() / best_m / 1000,
599 best_double + 1, best_n, best_m);
606 pll = CCM_LCD_CH0_CTRL_MIPI_PLL;
607 else if (best_double)
608 pll = CCM_LCD_CH0_CTRL_PLL3_2X;
610 pll = CCM_LCD_CH0_CTRL_PLL3;
612 writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST | pll,
613 &ccm->lcd0_ch0_clk_cfg);
615 writel(CCM_LCD_CH1_CTRL_GATE |
616 (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
617 CCM_LCD_CH1_CTRL_PLL3) |
618 CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
619 if (sunxi_is_composite())
620 setbits_le32(&ccm->lcd0_ch1_clk_cfg,
621 CCM_LCD_CH1_CTRL_HALF_SCLK1);
625 *clk_double = best_double;
628 static void sunxi_lcdc_init(void)
630 struct sunxi_ccm_reg * const ccm =
631 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
632 struct sunxi_lcdc_reg * const lcdc =
633 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
636 #ifdef CONFIG_SUNXI_GEN_SUN6I
637 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
639 setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST);
643 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
644 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
645 #ifdef CONFIG_SUNXI_GEN_SUN6I
646 setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS);
648 setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
653 writel(0, &lcdc->ctrl); /* Disable tcon */
654 writel(0, &lcdc->int0); /* Disable all interrupts */
656 /* Disable tcon0 dot clock */
657 clrbits_le32(&lcdc->tcon0_dclk, SUNXI_LCDC_TCON0_DCLK_ENABLE);
659 /* Set all io lines to tristate */
660 writel(0xffffffff, &lcdc->tcon0_io_tristate);
661 writel(0xffffffff, &lcdc->tcon1_io_tristate);
664 static void sunxi_lcdc_enable(void)
666 struct sunxi_lcdc_reg * const lcdc =
667 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
669 setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
670 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
671 setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE);
672 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0);
673 #ifdef CONFIG_SUNXI_GEN_SUN6I
674 udelay(2); /* delay at least 1200 ns */
675 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB);
676 udelay(2); /* delay at least 1200 ns */
677 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC);
678 if (sunxi_display.depth == 18)
679 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7));
681 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf));
683 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
684 udelay(2); /* delay at least 1200 ns */
685 setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1);
686 udelay(1); /* delay at least 120 ns */
687 setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2);
688 setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
693 static void sunxi_lcdc_panel_enable(void)
698 * Start with backlight disabled to avoid the screen flashing to
699 * white while the lcd inits.
701 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
703 gpio_request(pin, "lcd_backlight_enable");
704 gpio_direction_output(pin, 0);
707 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
709 gpio_request(pin, "lcd_backlight_pwm");
710 gpio_direction_output(pin, PWM_OFF);
713 reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET);
714 if (reset_pin >= 0) {
715 gpio_request(reset_pin, "lcd_reset");
716 gpio_direction_output(reset_pin, 0); /* Assert reset */
719 /* Give the backlight some time to turn off and power up the panel. */
721 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
723 gpio_request(pin, "lcd_power");
724 gpio_direction_output(pin, 1);
728 gpio_direction_output(reset_pin, 1); /* De-assert reset */
731 static void sunxi_lcdc_backlight_enable(void)
736 * We want to have scanned out at least one frame before enabling the
737 * backlight to avoid the screen flashing to white when we enable it.
741 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
743 gpio_direction_output(pin, 1);
745 pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
747 gpio_direction_output(pin, PWM_ON);
750 static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon)
754 delay = mode->lower_margin + mode->vsync_len + mode->upper_margin;
755 if (mode->vmode == FB_VMODE_INTERLACED)
760 return (delay > 30) ? 30 : delay;
763 static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
764 bool for_ext_vga_dac)
766 struct sunxi_lcdc_reg * const lcdc =
767 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
768 int bp, clk_delay, clk_div, clk_double, pin, total, val;
770 for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
771 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
772 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
774 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
775 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
777 #ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
778 sunxi_gpio_set_drv(pin, 3);
782 sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
785 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
786 SUNXI_LCDC_CTRL_IO_MAP_TCON0);
788 clk_delay = sunxi_lcdc_get_clk_delay(mode, 0);
789 writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
790 SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
792 writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
793 SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
795 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
796 &lcdc->tcon0_timing_active);
798 bp = mode->hsync_len + mode->left_margin;
799 total = mode->xres + mode->right_margin + bp;
800 writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
801 SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
803 bp = mode->vsync_len + mode->upper_margin;
804 total = mode->yres + mode->lower_margin + bp;
805 writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
806 SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
808 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
809 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
810 &lcdc->tcon0_timing_sync);
812 writel(0, &lcdc->tcon0_hv_intf);
813 writel(0, &lcdc->tcon0_cpu_intf);
815 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
816 val = (sunxi_display.depth == 18) ? 1 : 0;
817 writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
818 SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
821 if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {
822 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
823 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]);
824 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]);
825 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]);
826 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]);
827 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]);
828 writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]);
829 writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]);
830 writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]);
831 writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]);
832 writel(((sunxi_display.depth == 18) ?
833 SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 :
834 SUNXI_LCDC_TCON0_FRM_CTRL_RGB565),
835 &lcdc->tcon0_frm_ctrl);
838 val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(CONFIG_VIDEO_LCD_DCLK_PHASE);
839 if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
840 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
841 if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
842 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
844 #ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
848 writel(val, &lcdc->tcon0_io_polarity);
850 writel(0, &lcdc->tcon0_io_tristate);
853 #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
854 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
855 int *clk_div, int *clk_double,
856 bool use_portd_hvsync)
858 struct sunxi_lcdc_reg * const lcdc =
859 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
860 int bp, clk_delay, total, val, yres;
863 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
864 SUNXI_LCDC_CTRL_IO_MAP_TCON1);
866 clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
867 writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
868 ((mode->vmode == FB_VMODE_INTERLACED) ?
869 SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
870 SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
873 if (mode->vmode == FB_VMODE_INTERLACED)
875 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
876 &lcdc->tcon1_timing_source);
877 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
878 &lcdc->tcon1_timing_scale);
879 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
880 &lcdc->tcon1_timing_out);
882 bp = mode->hsync_len + mode->left_margin;
883 total = mode->xres + mode->right_margin + bp;
884 writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) |
885 SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h);
887 bp = mode->vsync_len + mode->upper_margin;
888 total = mode->yres + mode->lower_margin + bp;
889 if (mode->vmode == FB_VMODE_NONINTERLACED)
891 writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
892 SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
894 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
895 &lcdc->tcon1_timing_sync);
897 if (use_portd_hvsync) {
898 sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
899 sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0);
902 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
903 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
904 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
905 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
906 writel(val, &lcdc->tcon1_io_polarity);
908 clrbits_le32(&lcdc->tcon1_io_tristate,
909 SUNXI_LCDC_TCON_VSYNC_MASK |
910 SUNXI_LCDC_TCON_HSYNC_MASK);
913 #ifdef CONFIG_MACH_SUN5I
914 if (sunxi_is_composite())
915 clrsetbits_le32(&lcdc->mux_ctrl, SUNXI_LCDC_MUX_CTRL_SRC0_MASK,
916 SUNXI_LCDC_MUX_CTRL_SRC0(1));
919 sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
921 #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
923 #ifdef CONFIG_VIDEO_HDMI
925 static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
927 struct sunxi_hdmi_reg * const hdmi =
928 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
930 u8 avi_info_frame[17] = {
931 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00,
932 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
935 u8 vendor_info_frame[19] = {
936 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40,
937 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942 if (mode->pixclock_khz <= 27000)
943 avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */
945 avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */
947 if (mode->xres * 100 / mode->yres < 156)
948 avi_info_frame[5] |= 0x18; /* 4 : 3 */
950 avi_info_frame[5] |= 0x28; /* 16 : 9 */
952 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
953 checksum += avi_info_frame[i];
955 avi_info_frame[3] = 0x100 - checksum;
957 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
958 writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]);
960 writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0);
961 writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1);
963 for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++)
964 writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]);
966 writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0);
967 writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1);
969 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI);
972 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
973 int clk_div, int clk_double)
975 struct sunxi_hdmi_reg * const hdmi =
976 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
979 /* Write clear interrupt status bits */
980 writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
982 if (sunxi_display.monitor == sunxi_monitor_hdmi)
983 sunxi_hdmi_setup_info_frames(mode);
985 /* Set input sync enable */
986 writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown);
988 /* Init various registers, select pll3 as clock source */
989 writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity);
990 writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0);
991 writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1);
992 writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl);
993 writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
995 /* Setup clk div and doubler */
996 clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK,
997 SUNXI_HDMI_PLL_CTRL_DIV(clk_div));
999 setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE);
1001 /* Setup timing registers */
1002 writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres),
1005 x = mode->hsync_len + mode->left_margin;
1006 y = mode->vsync_len + mode->upper_margin;
1007 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp);
1009 x = mode->right_margin;
1010 y = mode->lower_margin;
1011 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp);
1013 x = mode->hsync_len;
1014 y = mode->vsync_len;
1015 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw);
1017 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
1018 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR);
1020 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
1021 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER);
1024 static void sunxi_hdmi_enable(void)
1026 struct sunxi_hdmi_reg * const hdmi =
1027 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
1030 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
1033 #endif /* CONFIG_VIDEO_HDMI */
1035 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
1037 static void sunxi_tvencoder_mode_set(void)
1039 struct sunxi_ccm_reg * const ccm =
1040 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1041 struct sunxi_tve_reg * const tve =
1042 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1045 setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_TVE_RST);
1047 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
1049 switch (sunxi_display.monitor) {
1050 case sunxi_monitor_vga:
1051 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1052 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1053 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
1054 writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
1055 writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
1056 writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
1058 case sunxi_monitor_composite_pal_nc:
1059 writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
1061 case sunxi_monitor_composite_pal:
1062 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1063 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1064 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1065 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1066 writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
1067 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1068 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1069 writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
1070 writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
1071 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
1072 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1073 writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
1074 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1075 writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
1076 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1077 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1078 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1079 writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
1080 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1082 case sunxi_monitor_composite_pal_m:
1083 writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
1084 writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
1086 case sunxi_monitor_composite_ntsc:
1087 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1088 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1089 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1090 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1091 writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
1092 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1093 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1094 writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
1095 writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
1096 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
1097 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1098 writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
1099 writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
1100 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1101 writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
1102 writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
1103 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1104 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1105 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1106 writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
1107 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1109 case sunxi_monitor_none:
1110 case sunxi_monitor_dvi:
1111 case sunxi_monitor_hdmi:
1112 case sunxi_monitor_lcd:
1117 static void sunxi_tvencoder_enable(void)
1119 struct sunxi_tve_reg * const tve =
1120 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1122 setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
1125 #endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
1127 static void sunxi_drc_init(void)
1129 #ifdef CONFIG_SUNXI_GEN_SUN6I
1130 struct sunxi_ccm_reg * const ccm =
1131 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1133 /* On sun6i the drc must be clocked even when in pass-through mode */
1134 #ifdef CONFIG_MACH_SUN8I_A33
1135 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT);
1137 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0);
1138 clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000);
1142 #ifdef CONFIG_VIDEO_VGA_VIA_LCD
1143 static void sunxi_vga_external_dac_enable(void)
1147 pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN);
1149 gpio_request(pin, "vga_enable");
1150 gpio_direction_output(pin, 1);
1153 #endif /* CONFIG_VIDEO_VGA_VIA_LCD */
1155 #ifdef CONFIG_VIDEO_LCD_SSD2828
1156 static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
1158 struct ssd2828_config cfg = {
1159 .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS),
1160 .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK),
1161 .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI),
1162 .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO),
1163 .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET),
1164 .ssd2828_tx_clk_khz = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000,
1165 .ssd2828_color_depth = 24,
1166 #ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
1167 .mipi_dsi_number_of_data_lanes = 4,
1168 .mipi_dsi_bitrate_per_data_lane_mbps = 513,
1169 .mipi_dsi_delay_after_exit_sleep_mode_ms = 100,
1170 .mipi_dsi_delay_after_set_display_on_ms = 200
1172 #error MIPI LCD panel needs configuration parameters
1176 if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) {
1177 printf("SSD2828: SPI pins are not properly configured\n");
1180 if (cfg.reset_pin == -1) {
1181 printf("SSD2828: Reset pin is not properly configured\n");
1185 return ssd2828_init(&cfg, mode);
1187 #endif /* CONFIG_VIDEO_LCD_SSD2828 */
1189 static void sunxi_engines_init(void)
1191 sunxi_composer_init();
1196 static void sunxi_mode_set(const struct ctfb_res_modes *mode,
1197 unsigned int address)
1199 int __maybe_unused clk_div, clk_double;
1201 switch (sunxi_display.monitor) {
1202 case sunxi_monitor_none:
1204 case sunxi_monitor_dvi:
1205 case sunxi_monitor_hdmi:
1206 #ifdef CONFIG_VIDEO_HDMI
1207 sunxi_composer_mode_set(mode, address);
1208 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1209 sunxi_hdmi_mode_set(mode, clk_div, clk_double);
1210 sunxi_composer_enable();
1211 sunxi_lcdc_enable();
1212 sunxi_hdmi_enable();
1215 case sunxi_monitor_lcd:
1216 sunxi_lcdc_panel_enable();
1217 if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
1219 * The anx9804 needs 1.8V from eldo3, we do this here
1220 * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
1221 * to avoid turning this on when using hdmi output.
1223 axp_set_eldo(3, 1800);
1224 anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
1225 ANX9804_DATA_RATE_1620M,
1226 sunxi_display.depth);
1228 if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
1229 mdelay(50); /* Wait for lcd controller power on */
1230 hitachi_tx18d42vm_init();
1232 if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
1233 unsigned int orig_i2c_bus = i2c_get_bus_num();
1234 i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
1235 i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
1236 i2c_set_bus_num(orig_i2c_bus);
1238 sunxi_composer_mode_set(mode, address);
1239 sunxi_lcdc_tcon0_mode_set(mode, false);
1240 sunxi_composer_enable();
1241 sunxi_lcdc_enable();
1242 #ifdef CONFIG_VIDEO_LCD_SSD2828
1243 sunxi_ssd2828_init(mode);
1245 sunxi_lcdc_backlight_enable();
1247 case sunxi_monitor_vga:
1248 #ifdef CONFIG_VIDEO_VGA
1249 sunxi_composer_mode_set(mode, address);
1250 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
1251 sunxi_tvencoder_mode_set();
1252 sunxi_composer_enable();
1253 sunxi_lcdc_enable();
1254 sunxi_tvencoder_enable();
1255 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1256 sunxi_composer_mode_set(mode, address);
1257 sunxi_lcdc_tcon0_mode_set(mode, true);
1258 sunxi_composer_enable();
1259 sunxi_lcdc_enable();
1260 sunxi_vga_external_dac_enable();
1263 case sunxi_monitor_composite_pal:
1264 case sunxi_monitor_composite_ntsc:
1265 case sunxi_monitor_composite_pal_m:
1266 case sunxi_monitor_composite_pal_nc:
1267 #ifdef CONFIG_VIDEO_COMPOSITE
1268 sunxi_composer_mode_set(mode, address);
1269 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1270 sunxi_tvencoder_mode_set();
1271 sunxi_composer_enable();
1272 sunxi_lcdc_enable();
1273 sunxi_tvencoder_enable();
1279 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
1282 case sunxi_monitor_none: return "none";
1283 case sunxi_monitor_dvi: return "dvi";
1284 case sunxi_monitor_hdmi: return "hdmi";
1285 case sunxi_monitor_lcd: return "lcd";
1286 case sunxi_monitor_vga: return "vga";
1287 case sunxi_monitor_composite_pal: return "composite-pal";
1288 case sunxi_monitor_composite_ntsc: return "composite-ntsc";
1289 case sunxi_monitor_composite_pal_m: return "composite-pal-m";
1290 case sunxi_monitor_composite_pal_nc: return "composite-pal-nc";
1292 return NULL; /* never reached */
1295 ulong board_get_usable_ram_top(ulong total_size)
1297 return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
1300 static bool sunxi_has_hdmi(void)
1302 #ifdef CONFIG_VIDEO_HDMI
1309 static bool sunxi_has_lcd(void)
1311 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1313 return lcd_mode[0] != 0;
1316 static bool sunxi_has_vga(void)
1318 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
1325 static bool sunxi_has_composite(void)
1327 #ifdef CONFIG_VIDEO_COMPOSITE
1334 static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
1336 if (allow_hdmi && sunxi_has_hdmi())
1337 return sunxi_monitor_dvi;
1338 else if (sunxi_has_lcd())
1339 return sunxi_monitor_lcd;
1340 else if (sunxi_has_vga())
1341 return sunxi_monitor_vga;
1342 else if (sunxi_has_composite())
1343 return sunxi_monitor_composite_pal;
1345 return sunxi_monitor_none;
1348 void *video_hw_init(void)
1350 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1351 const struct ctfb_res_modes *mode;
1352 struct ctfb_res_modes custom;
1353 const char *options;
1354 #ifdef CONFIG_VIDEO_HDMI
1355 int ret, hpd, hpd_delay, edid;
1357 int i, overscan_offset, overscan_x, overscan_y;
1358 unsigned int fb_dma_addr;
1360 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1362 memset(&sunxi_display, 0, sizeof(struct sunxi_display));
1364 video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
1365 &sunxi_display.depth, &options);
1366 #ifdef CONFIG_VIDEO_HDMI
1367 hpd = video_get_option_int(options, "hpd", 1);
1368 hpd_delay = video_get_option_int(options, "hpd_delay", 500);
1369 edid = video_get_option_int(options, "edid", 1);
1371 overscan_x = video_get_option_int(options, "overscan_x", -1);
1372 overscan_y = video_get_option_int(options, "overscan_y", -1);
1373 sunxi_display.monitor = sunxi_get_default_mon(true);
1374 video_get_option_string(options, "monitor", mon, sizeof(mon),
1375 sunxi_get_mon_desc(sunxi_display.monitor));
1376 for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
1377 if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
1378 sunxi_display.monitor = i;
1382 if (i > SUNXI_MONITOR_LAST)
1383 printf("Unknown monitor: '%s', falling back to '%s'\n",
1384 mon, sunxi_get_mon_desc(sunxi_display.monitor));
1386 #ifdef CONFIG_VIDEO_HDMI
1387 /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
1388 if (sunxi_display.monitor == sunxi_monitor_dvi ||
1389 sunxi_display.monitor == sunxi_monitor_hdmi) {
1390 /* Always call hdp_detect, as it also enables clocks, etc. */
1391 ret = sunxi_hdmi_hpd_detect(hpd_delay);
1393 printf("HDMI connected: ");
1394 if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
1397 sunxi_hdmi_shutdown();
1398 sunxi_display.monitor = sunxi_get_default_mon(false);
1399 } /* else continue with hdmi/dvi without a cable connected */
1403 switch (sunxi_display.monitor) {
1404 case sunxi_monitor_none:
1406 case sunxi_monitor_dvi:
1407 case sunxi_monitor_hdmi:
1408 if (!sunxi_has_hdmi()) {
1409 printf("HDMI/DVI not supported on this board\n");
1410 sunxi_display.monitor = sunxi_monitor_none;
1414 case sunxi_monitor_lcd:
1415 if (!sunxi_has_lcd()) {
1416 printf("LCD not supported on this board\n");
1417 sunxi_display.monitor = sunxi_monitor_none;
1420 sunxi_display.depth = video_get_params(&custom, lcd_mode);
1423 case sunxi_monitor_vga:
1424 if (!sunxi_has_vga()) {
1425 printf("VGA not supported on this board\n");
1426 sunxi_display.monitor = sunxi_monitor_none;
1429 sunxi_display.depth = 18;
1431 case sunxi_monitor_composite_pal:
1432 case sunxi_monitor_composite_ntsc:
1433 case sunxi_monitor_composite_pal_m:
1434 case sunxi_monitor_composite_pal_nc:
1435 if (!sunxi_has_composite()) {
1436 printf("Composite video not supported on this board\n");
1437 sunxi_display.monitor = sunxi_monitor_none;
1440 if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
1441 sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
1442 mode = &composite_video_modes[0];
1444 mode = &composite_video_modes[1];
1445 sunxi_display.depth = 24;
1449 /* Yes these defaults are quite high, overscan on composite sucks... */
1450 if (overscan_x == -1)
1451 overscan_x = sunxi_is_composite() ? 32 : 0;
1452 if (overscan_y == -1)
1453 overscan_y = sunxi_is_composite() ? 20 : 0;
1455 sunxi_display.fb_size =
1456 (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
1457 overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
1458 /* We want to keep the fb_base for simplefb page aligned, where as
1459 * the sunxi dma engines will happily accept an unaligned address. */
1460 if (overscan_offset)
1461 sunxi_display.fb_size += 0x1000;
1463 if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
1464 printf("Error need %dkB for fb, but only %dkB is reserved\n",
1465 sunxi_display.fb_size >> 10,
1466 CONFIG_SUNXI_MAX_FB_SIZE >> 10);
1470 printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
1471 mode->xres, mode->yres,
1472 (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
1473 sunxi_get_mon_desc(sunxi_display.monitor),
1474 overscan_x, overscan_y);
1476 gd->fb_base = gd->bd->bi_dram[0].start +
1477 gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1478 sunxi_engines_init();
1480 fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
1481 sunxi_display.fb_addr = gd->fb_base;
1482 if (overscan_offset) {
1483 fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
1484 sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
1485 memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
1486 flush_cache(gd->fb_base, sunxi_display.fb_size);
1488 sunxi_mode_set(mode, fb_dma_addr);
1491 * These are the only members of this structure that are used. All the
1492 * others are driver specific. The pitch is stored in plnSizeX.
1494 graphic_device->frameAdrs = sunxi_display.fb_addr;
1495 graphic_device->gdfIndex = GDF_32BIT_X888RGB;
1496 graphic_device->gdfBytesPP = 4;
1497 graphic_device->winSizeX = mode->xres - 2 * overscan_x;
1498 graphic_device->winSizeY = mode->yres - 2 * overscan_y;
1499 graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
1501 return graphic_device;
1507 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
1508 int sunxi_simplefb_setup(void *blob)
1510 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1513 const char *pipeline = NULL;
1515 #ifdef CONFIG_MACH_SUN4I
1516 #define PIPELINE_PREFIX "de_fe0-"
1518 #define PIPELINE_PREFIX
1521 switch (sunxi_display.monitor) {
1522 case sunxi_monitor_none:
1524 case sunxi_monitor_dvi:
1525 case sunxi_monitor_hdmi:
1526 pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi";
1528 case sunxi_monitor_lcd:
1529 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1531 case sunxi_monitor_vga:
1532 #ifdef CONFIG_VIDEO_VGA
1533 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1534 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1535 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1538 case sunxi_monitor_composite_pal:
1539 case sunxi_monitor_composite_ntsc:
1540 case sunxi_monitor_composite_pal_m:
1541 case sunxi_monitor_composite_pal_nc:
1542 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1546 /* Find a prefilled simpefb node, matching out pipeline config */
1547 offset = fdt_node_offset_by_compatible(blob, -1,
1548 "allwinner,simple-framebuffer");
1549 while (offset >= 0) {
1550 ret = fdt_find_string(blob, offset, "allwinner,pipeline",
1554 offset = fdt_node_offset_by_compatible(blob, offset,
1555 "allwinner,simple-framebuffer");
1558 eprintf("Cannot setup simplefb: node not found\n");
1559 return 0; /* Keep older kernels working */
1563 * Do not report the framebuffer as free RAM to the OS, note we cannot
1564 * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
1565 * and e.g. Linux refuses to iomap RAM on ARM, see:
1566 * linux/arch/arm/mm/ioremap.c around line 301.
1568 start = gd->bd->bi_dram[0].start;
1569 size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1570 ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
1572 eprintf("Cannot setup simplefb: Error reserving memory\n");
1576 ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr,
1577 graphic_device->winSizeX, graphic_device->winSizeY,
1578 graphic_device->plnSizeX, "x8r8g8b8");
1580 eprintf("Cannot setup simplefb: Error setting properties\n");
1584 #endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */