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 #if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS
771 for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) {
773 for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
775 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
776 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
778 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
779 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
781 #ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
782 sunxi_gpio_set_drv(pin, 3);
786 sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
789 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
790 SUNXI_LCDC_CTRL_IO_MAP_TCON0);
792 clk_delay = sunxi_lcdc_get_clk_delay(mode, 0);
793 writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
794 SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
796 writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
797 SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
799 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres),
800 &lcdc->tcon0_timing_active);
802 bp = mode->hsync_len + mode->left_margin;
803 total = mode->xres + mode->right_margin + bp;
804 writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
805 SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
807 bp = mode->vsync_len + mode->upper_margin;
808 total = mode->yres + mode->lower_margin + bp;
809 writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
810 SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
812 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
813 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
814 &lcdc->tcon0_timing_sync);
816 writel(0, &lcdc->tcon0_hv_intf);
817 writel(0, &lcdc->tcon0_cpu_intf);
819 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
820 val = (sunxi_display.depth == 18) ? 1 : 0;
821 writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
822 SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
825 if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {
826 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
827 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]);
828 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]);
829 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]);
830 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]);
831 writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]);
832 writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]);
833 writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]);
834 writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]);
835 writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]);
836 writel(((sunxi_display.depth == 18) ?
837 SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 :
838 SUNXI_LCDC_TCON0_FRM_CTRL_RGB565),
839 &lcdc->tcon0_frm_ctrl);
842 val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(CONFIG_VIDEO_LCD_DCLK_PHASE);
843 if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
844 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
845 if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
846 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
848 #ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
852 writel(val, &lcdc->tcon0_io_polarity);
854 writel(0, &lcdc->tcon0_io_tristate);
857 #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
858 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
859 int *clk_div, int *clk_double,
860 bool use_portd_hvsync)
862 struct sunxi_lcdc_reg * const lcdc =
863 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
864 int bp, clk_delay, total, val, yres;
867 clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
868 SUNXI_LCDC_CTRL_IO_MAP_TCON1);
870 clk_delay = sunxi_lcdc_get_clk_delay(mode, 1);
871 writel(SUNXI_LCDC_TCON1_CTRL_ENABLE |
872 ((mode->vmode == FB_VMODE_INTERLACED) ?
873 SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) |
874 SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl);
877 if (mode->vmode == FB_VMODE_INTERLACED)
879 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
880 &lcdc->tcon1_timing_source);
881 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
882 &lcdc->tcon1_timing_scale);
883 writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres),
884 &lcdc->tcon1_timing_out);
886 bp = mode->hsync_len + mode->left_margin;
887 total = mode->xres + mode->right_margin + bp;
888 writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) |
889 SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h);
891 bp = mode->vsync_len + mode->upper_margin;
892 total = mode->yres + mode->lower_margin + bp;
893 if (mode->vmode == FB_VMODE_NONINTERLACED)
895 writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) |
896 SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v);
898 writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
899 &lcdc->tcon1_timing_sync);
901 if (use_portd_hvsync) {
902 sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
903 sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0);
906 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
907 val |= SUNXI_LCDC_TCON_HSYNC_MASK;
908 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
909 val |= SUNXI_LCDC_TCON_VSYNC_MASK;
910 writel(val, &lcdc->tcon1_io_polarity);
912 clrbits_le32(&lcdc->tcon1_io_tristate,
913 SUNXI_LCDC_TCON_VSYNC_MASK |
914 SUNXI_LCDC_TCON_HSYNC_MASK);
917 #ifdef CONFIG_MACH_SUN5I
918 if (sunxi_is_composite())
919 clrsetbits_le32(&lcdc->mux_ctrl, SUNXI_LCDC_MUX_CTRL_SRC0_MASK,
920 SUNXI_LCDC_MUX_CTRL_SRC0(1));
923 sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
925 #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
927 #ifdef CONFIG_VIDEO_HDMI
929 static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
931 struct sunxi_hdmi_reg * const hdmi =
932 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
934 u8 avi_info_frame[17] = {
935 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00,
936 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
939 u8 vendor_info_frame[19] = {
940 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40,
941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
946 if (mode->pixclock_khz <= 27000)
947 avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */
949 avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */
951 if (mode->xres * 100 / mode->yres < 156)
952 avi_info_frame[5] |= 0x18; /* 4 : 3 */
954 avi_info_frame[5] |= 0x28; /* 16 : 9 */
956 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
957 checksum += avi_info_frame[i];
959 avi_info_frame[3] = 0x100 - checksum;
961 for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
962 writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]);
964 writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0);
965 writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1);
967 for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++)
968 writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]);
970 writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0);
971 writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1);
973 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI);
976 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
977 int clk_div, int clk_double)
979 struct sunxi_hdmi_reg * const hdmi =
980 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
983 /* Write clear interrupt status bits */
984 writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
986 if (sunxi_display.monitor == sunxi_monitor_hdmi)
987 sunxi_hdmi_setup_info_frames(mode);
989 /* Set input sync enable */
990 writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown);
992 /* Init various registers, select pll3 as clock source */
993 writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity);
994 writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0);
995 writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1);
996 writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl);
997 writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
999 /* Setup clk div and doubler */
1000 clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK,
1001 SUNXI_HDMI_PLL_CTRL_DIV(clk_div));
1003 setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE);
1005 /* Setup timing registers */
1006 writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres),
1009 x = mode->hsync_len + mode->left_margin;
1010 y = mode->vsync_len + mode->upper_margin;
1011 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp);
1013 x = mode->right_margin;
1014 y = mode->lower_margin;
1015 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp);
1017 x = mode->hsync_len;
1018 y = mode->vsync_len;
1019 writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw);
1021 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
1022 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR);
1024 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
1025 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER);
1028 static void sunxi_hdmi_enable(void)
1030 struct sunxi_hdmi_reg * const hdmi =
1031 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
1034 setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
1037 #endif /* CONFIG_VIDEO_HDMI */
1039 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
1041 static void sunxi_tvencoder_mode_set(void)
1043 struct sunxi_ccm_reg * const ccm =
1044 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1045 struct sunxi_tve_reg * const tve =
1046 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1049 setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_TVE_RST);
1051 setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
1053 switch (sunxi_display.monitor) {
1054 case sunxi_monitor_vga:
1055 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1056 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1057 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
1058 writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
1059 writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
1060 writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
1062 case sunxi_monitor_composite_pal_nc:
1063 writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
1065 case sunxi_monitor_composite_pal:
1066 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1067 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1068 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1069 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1070 writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
1071 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1072 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1073 writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
1074 writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
1075 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
1076 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1077 writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
1078 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1079 writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
1080 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1081 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1082 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1083 writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
1084 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1086 case sunxi_monitor_composite_pal_m:
1087 writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
1088 writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
1090 case sunxi_monitor_composite_ntsc:
1091 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
1092 SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
1093 SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
1094 SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
1095 writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
1096 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
1097 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
1098 writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
1099 writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
1100 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
1101 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
1102 writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
1103 writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
1104 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
1105 writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
1106 writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
1107 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
1108 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
1109 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
1110 writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
1111 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
1113 case sunxi_monitor_none:
1114 case sunxi_monitor_dvi:
1115 case sunxi_monitor_hdmi:
1116 case sunxi_monitor_lcd:
1121 static void sunxi_tvencoder_enable(void)
1123 struct sunxi_tve_reg * const tve =
1124 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1126 setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
1129 #endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
1131 static void sunxi_drc_init(void)
1133 #ifdef CONFIG_SUNXI_GEN_SUN6I
1134 struct sunxi_ccm_reg * const ccm =
1135 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1137 /* On sun6i the drc must be clocked even when in pass-through mode */
1138 #ifdef CONFIG_MACH_SUN8I_A33
1139 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT);
1141 setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0);
1142 clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000);
1146 #ifdef CONFIG_VIDEO_VGA_VIA_LCD
1147 static void sunxi_vga_external_dac_enable(void)
1151 pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN);
1153 gpio_request(pin, "vga_enable");
1154 gpio_direction_output(pin, 1);
1157 #endif /* CONFIG_VIDEO_VGA_VIA_LCD */
1159 #ifdef CONFIG_VIDEO_LCD_SSD2828
1160 static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
1162 struct ssd2828_config cfg = {
1163 .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS),
1164 .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK),
1165 .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI),
1166 .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO),
1167 .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET),
1168 .ssd2828_tx_clk_khz = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000,
1169 .ssd2828_color_depth = 24,
1170 #ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
1171 .mipi_dsi_number_of_data_lanes = 4,
1172 .mipi_dsi_bitrate_per_data_lane_mbps = 513,
1173 .mipi_dsi_delay_after_exit_sleep_mode_ms = 100,
1174 .mipi_dsi_delay_after_set_display_on_ms = 200
1176 #error MIPI LCD panel needs configuration parameters
1180 if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) {
1181 printf("SSD2828: SPI pins are not properly configured\n");
1184 if (cfg.reset_pin == -1) {
1185 printf("SSD2828: Reset pin is not properly configured\n");
1189 return ssd2828_init(&cfg, mode);
1191 #endif /* CONFIG_VIDEO_LCD_SSD2828 */
1193 static void sunxi_engines_init(void)
1195 sunxi_composer_init();
1200 static void sunxi_mode_set(const struct ctfb_res_modes *mode,
1201 unsigned int address)
1203 int __maybe_unused clk_div, clk_double;
1205 switch (sunxi_display.monitor) {
1206 case sunxi_monitor_none:
1208 case sunxi_monitor_dvi:
1209 case sunxi_monitor_hdmi:
1210 #ifdef CONFIG_VIDEO_HDMI
1211 sunxi_composer_mode_set(mode, address);
1212 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1213 sunxi_hdmi_mode_set(mode, clk_div, clk_double);
1214 sunxi_composer_enable();
1215 sunxi_lcdc_enable();
1216 sunxi_hdmi_enable();
1219 case sunxi_monitor_lcd:
1220 sunxi_lcdc_panel_enable();
1221 if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
1223 * The anx9804 needs 1.8V from eldo3, we do this here
1224 * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
1225 * to avoid turning this on when using hdmi output.
1227 axp_set_eldo(3, 1800);
1228 anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
1229 ANX9804_DATA_RATE_1620M,
1230 sunxi_display.depth);
1232 if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
1233 mdelay(50); /* Wait for lcd controller power on */
1234 hitachi_tx18d42vm_init();
1236 if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
1237 unsigned int orig_i2c_bus = i2c_get_bus_num();
1238 i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
1239 i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
1240 i2c_set_bus_num(orig_i2c_bus);
1242 sunxi_composer_mode_set(mode, address);
1243 sunxi_lcdc_tcon0_mode_set(mode, false);
1244 sunxi_composer_enable();
1245 sunxi_lcdc_enable();
1246 #ifdef CONFIG_VIDEO_LCD_SSD2828
1247 sunxi_ssd2828_init(mode);
1249 sunxi_lcdc_backlight_enable();
1251 case sunxi_monitor_vga:
1252 #ifdef CONFIG_VIDEO_VGA
1253 sunxi_composer_mode_set(mode, address);
1254 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
1255 sunxi_tvencoder_mode_set();
1256 sunxi_composer_enable();
1257 sunxi_lcdc_enable();
1258 sunxi_tvencoder_enable();
1259 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1260 sunxi_composer_mode_set(mode, address);
1261 sunxi_lcdc_tcon0_mode_set(mode, true);
1262 sunxi_composer_enable();
1263 sunxi_lcdc_enable();
1264 sunxi_vga_external_dac_enable();
1267 case sunxi_monitor_composite_pal:
1268 case sunxi_monitor_composite_ntsc:
1269 case sunxi_monitor_composite_pal_m:
1270 case sunxi_monitor_composite_pal_nc:
1271 #ifdef CONFIG_VIDEO_COMPOSITE
1272 sunxi_composer_mode_set(mode, address);
1273 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1274 sunxi_tvencoder_mode_set();
1275 sunxi_composer_enable();
1276 sunxi_lcdc_enable();
1277 sunxi_tvencoder_enable();
1283 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
1286 case sunxi_monitor_none: return "none";
1287 case sunxi_monitor_dvi: return "dvi";
1288 case sunxi_monitor_hdmi: return "hdmi";
1289 case sunxi_monitor_lcd: return "lcd";
1290 case sunxi_monitor_vga: return "vga";
1291 case sunxi_monitor_composite_pal: return "composite-pal";
1292 case sunxi_monitor_composite_ntsc: return "composite-ntsc";
1293 case sunxi_monitor_composite_pal_m: return "composite-pal-m";
1294 case sunxi_monitor_composite_pal_nc: return "composite-pal-nc";
1296 return NULL; /* never reached */
1299 ulong board_get_usable_ram_top(ulong total_size)
1301 return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
1304 static bool sunxi_has_hdmi(void)
1306 #ifdef CONFIG_VIDEO_HDMI
1313 static bool sunxi_has_lcd(void)
1315 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1317 return lcd_mode[0] != 0;
1320 static bool sunxi_has_vga(void)
1322 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
1329 static bool sunxi_has_composite(void)
1331 #ifdef CONFIG_VIDEO_COMPOSITE
1338 static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
1340 if (allow_hdmi && sunxi_has_hdmi())
1341 return sunxi_monitor_dvi;
1342 else if (sunxi_has_lcd())
1343 return sunxi_monitor_lcd;
1344 else if (sunxi_has_vga())
1345 return sunxi_monitor_vga;
1346 else if (sunxi_has_composite())
1347 return sunxi_monitor_composite_pal;
1349 return sunxi_monitor_none;
1352 void *video_hw_init(void)
1354 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1355 const struct ctfb_res_modes *mode;
1356 struct ctfb_res_modes custom;
1357 const char *options;
1358 #ifdef CONFIG_VIDEO_HDMI
1359 int ret, hpd, hpd_delay, edid;
1361 int i, overscan_offset, overscan_x, overscan_y;
1362 unsigned int fb_dma_addr;
1364 char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1366 memset(&sunxi_display, 0, sizeof(struct sunxi_display));
1368 video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
1369 &sunxi_display.depth, &options);
1370 #ifdef CONFIG_VIDEO_HDMI
1371 hpd = video_get_option_int(options, "hpd", 1);
1372 hpd_delay = video_get_option_int(options, "hpd_delay", 500);
1373 edid = video_get_option_int(options, "edid", 1);
1375 overscan_x = video_get_option_int(options, "overscan_x", -1);
1376 overscan_y = video_get_option_int(options, "overscan_y", -1);
1377 sunxi_display.monitor = sunxi_get_default_mon(true);
1378 video_get_option_string(options, "monitor", mon, sizeof(mon),
1379 sunxi_get_mon_desc(sunxi_display.monitor));
1380 for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
1381 if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
1382 sunxi_display.monitor = i;
1386 if (i > SUNXI_MONITOR_LAST)
1387 printf("Unknown monitor: '%s', falling back to '%s'\n",
1388 mon, sunxi_get_mon_desc(sunxi_display.monitor));
1390 #ifdef CONFIG_VIDEO_HDMI
1391 /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
1392 if (sunxi_display.monitor == sunxi_monitor_dvi ||
1393 sunxi_display.monitor == sunxi_monitor_hdmi) {
1394 /* Always call hdp_detect, as it also enables clocks, etc. */
1395 ret = sunxi_hdmi_hpd_detect(hpd_delay);
1397 printf("HDMI connected: ");
1398 if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
1401 sunxi_hdmi_shutdown();
1402 sunxi_display.monitor = sunxi_get_default_mon(false);
1403 } /* else continue with hdmi/dvi without a cable connected */
1407 switch (sunxi_display.monitor) {
1408 case sunxi_monitor_none:
1410 case sunxi_monitor_dvi:
1411 case sunxi_monitor_hdmi:
1412 if (!sunxi_has_hdmi()) {
1413 printf("HDMI/DVI not supported on this board\n");
1414 sunxi_display.monitor = sunxi_monitor_none;
1418 case sunxi_monitor_lcd:
1419 if (!sunxi_has_lcd()) {
1420 printf("LCD not supported on this board\n");
1421 sunxi_display.monitor = sunxi_monitor_none;
1424 sunxi_display.depth = video_get_params(&custom, lcd_mode);
1427 case sunxi_monitor_vga:
1428 if (!sunxi_has_vga()) {
1429 printf("VGA not supported on this board\n");
1430 sunxi_display.monitor = sunxi_monitor_none;
1433 sunxi_display.depth = 18;
1435 case sunxi_monitor_composite_pal:
1436 case sunxi_monitor_composite_ntsc:
1437 case sunxi_monitor_composite_pal_m:
1438 case sunxi_monitor_composite_pal_nc:
1439 if (!sunxi_has_composite()) {
1440 printf("Composite video not supported on this board\n");
1441 sunxi_display.monitor = sunxi_monitor_none;
1444 if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
1445 sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
1446 mode = &composite_video_modes[0];
1448 mode = &composite_video_modes[1];
1449 sunxi_display.depth = 24;
1453 /* Yes these defaults are quite high, overscan on composite sucks... */
1454 if (overscan_x == -1)
1455 overscan_x = sunxi_is_composite() ? 32 : 0;
1456 if (overscan_y == -1)
1457 overscan_y = sunxi_is_composite() ? 20 : 0;
1459 sunxi_display.fb_size =
1460 (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
1461 overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
1462 /* We want to keep the fb_base for simplefb page aligned, where as
1463 * the sunxi dma engines will happily accept an unaligned address. */
1464 if (overscan_offset)
1465 sunxi_display.fb_size += 0x1000;
1467 if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
1468 printf("Error need %dkB for fb, but only %dkB is reserved\n",
1469 sunxi_display.fb_size >> 10,
1470 CONFIG_SUNXI_MAX_FB_SIZE >> 10);
1474 printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
1475 mode->xres, mode->yres,
1476 (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
1477 sunxi_get_mon_desc(sunxi_display.monitor),
1478 overscan_x, overscan_y);
1480 gd->fb_base = gd->bd->bi_dram[0].start +
1481 gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1482 sunxi_engines_init();
1484 fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
1485 sunxi_display.fb_addr = gd->fb_base;
1486 if (overscan_offset) {
1487 fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
1488 sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
1489 memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
1490 flush_cache(gd->fb_base, sunxi_display.fb_size);
1492 sunxi_mode_set(mode, fb_dma_addr);
1495 * These are the only members of this structure that are used. All the
1496 * others are driver specific. The pitch is stored in plnSizeX.
1498 graphic_device->frameAdrs = sunxi_display.fb_addr;
1499 graphic_device->gdfIndex = GDF_32BIT_X888RGB;
1500 graphic_device->gdfBytesPP = 4;
1501 graphic_device->winSizeX = mode->xres - 2 * overscan_x;
1502 graphic_device->winSizeY = mode->yres - 2 * overscan_y;
1503 graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
1505 return graphic_device;
1511 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
1512 int sunxi_simplefb_setup(void *blob)
1514 static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1517 const char *pipeline = NULL;
1519 #ifdef CONFIG_MACH_SUN4I
1520 #define PIPELINE_PREFIX "de_fe0-"
1522 #define PIPELINE_PREFIX
1525 switch (sunxi_display.monitor) {
1526 case sunxi_monitor_none:
1528 case sunxi_monitor_dvi:
1529 case sunxi_monitor_hdmi:
1530 pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi";
1532 case sunxi_monitor_lcd:
1533 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1535 case sunxi_monitor_vga:
1536 #ifdef CONFIG_VIDEO_VGA
1537 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1538 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1539 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1542 case sunxi_monitor_composite_pal:
1543 case sunxi_monitor_composite_ntsc:
1544 case sunxi_monitor_composite_pal_m:
1545 case sunxi_monitor_composite_pal_nc:
1546 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1550 /* Find a prefilled simpefb node, matching out pipeline config */
1551 offset = fdt_node_offset_by_compatible(blob, -1,
1552 "allwinner,simple-framebuffer");
1553 while (offset >= 0) {
1554 ret = fdt_find_string(blob, offset, "allwinner,pipeline",
1558 offset = fdt_node_offset_by_compatible(blob, offset,
1559 "allwinner,simple-framebuffer");
1562 eprintf("Cannot setup simplefb: node not found\n");
1563 return 0; /* Keep older kernels working */
1567 * Do not report the framebuffer as free RAM to the OS, note we cannot
1568 * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
1569 * and e.g. Linux refuses to iomap RAM on ARM, see:
1570 * linux/arch/arm/mm/ioremap.c around line 301.
1572 start = gd->bd->bi_dram[0].start;
1573 size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1574 ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
1576 eprintf("Cannot setup simplefb: Error reserving memory\n");
1580 ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr,
1581 graphic_device->winSizeX, graphic_device->winSizeY,
1582 graphic_device->plnSizeX, "x8r8g8b8");
1584 eprintf("Cannot setup simplefb: Error setting properties\n");
1588 #endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */