mmc: atmel_sdhci: Enable the quirk SDHCI_QUIRK_WAIT_SEND_CMD
[platform/kernel/u-boot.git] / drivers / video / sunxi / sunxi_display.c
1 /*
2  * Display driver for Allwinner SoCs.
3  *
4  * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
5  * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <common.h>
11
12 #include <asm/arch/clock.h>
13 #include <asm/arch/display.h>
14 #include <asm/arch/gpio.h>
15 #include <asm/arch/lcdc.h>
16 #include <asm/arch/pwm.h>
17 #include <asm/global_data.h>
18 #include <asm/gpio.h>
19 #include <asm/io.h>
20 #include <axp_pmic.h>
21 #include <errno.h>
22 #include <fdtdec.h>
23 #include <fdt_support.h>
24 #include <i2c.h>
25 #include <malloc.h>
26 #include <video_fb.h>
27 #include "../videomodes.h"
28 #include "../anx9804.h"
29 #include "../hitachi_tx18d42vm_lcd.h"
30 #include "../ssd2828.h"
31
32 #ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW
33 #define PWM_ON 0
34 #define PWM_OFF 1
35 #else
36 #define PWM_ON 1
37 #define PWM_OFF 0
38 #endif
39
40 DECLARE_GLOBAL_DATA_PTR;
41
42 enum sunxi_monitor {
43         sunxi_monitor_none,
44         sunxi_monitor_dvi,
45         sunxi_monitor_hdmi,
46         sunxi_monitor_lcd,
47         sunxi_monitor_vga,
48         sunxi_monitor_composite_pal,
49         sunxi_monitor_composite_ntsc,
50         sunxi_monitor_composite_pal_m,
51         sunxi_monitor_composite_pal_nc,
52 };
53 #define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
54
55 struct sunxi_display {
56         GraphicDevice graphic_device;
57         enum sunxi_monitor monitor;
58         unsigned int depth;
59         unsigned int fb_addr;
60         unsigned int fb_size;
61 } sunxi_display;
62
63 const struct ctfb_res_modes composite_video_modes[2] = {
64         /*  x     y  hz  pixclk ps/kHz   le   ri  up  lo   hs vs  s  vmode */
65         { 720,  576, 50, 37037,  27000, 137,   5, 20, 27,   2, 2, 0, FB_VMODE_INTERLACED },
66         { 720,  480, 60, 37037,  27000, 116,  20, 16, 27,   2, 2, 0, FB_VMODE_INTERLACED },
67 };
68
69 #ifdef CONFIG_VIDEO_HDMI
70
71 /*
72  * Wait up to 200ms for value to be set in given part of reg.
73  */
74 static int await_completion(u32 *reg, u32 mask, u32 val)
75 {
76         unsigned long tmo = timer_get_us() + 200000;
77
78         while ((readl(reg) & mask) != val) {
79                 if (timer_get_us() > tmo) {
80                         printf("DDC: timeout reading EDID\n");
81                         return -ETIME;
82                 }
83         }
84         return 0;
85 }
86
87 static int sunxi_hdmi_hpd_detect(int hpd_delay)
88 {
89         struct sunxi_ccm_reg * const ccm =
90                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
91         struct sunxi_hdmi_reg * const hdmi =
92                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
93         unsigned long tmo = timer_get_us() + hpd_delay * 1000;
94
95         /* Set pll3 to 300MHz */
96         clock_set_pll3(300000000);
97
98         /* Set hdmi parent to pll3 */
99         clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK,
100                         CCM_HDMI_CTRL_PLL3);
101
102         /* Set ahb gating to pass */
103 #ifdef CONFIG_SUNXI_GEN_SUN6I
104         setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
105 #endif
106         setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
107
108         /* Clock on */
109         setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
110
111         writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl);
112         writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0);
113
114         while (timer_get_us() < tmo) {
115                 if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT)
116                         return 1;
117         }
118
119         return 0;
120 }
121
122 static void sunxi_hdmi_shutdown(void)
123 {
124         struct sunxi_ccm_reg * const ccm =
125                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
126         struct sunxi_hdmi_reg * const hdmi =
127                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
128
129         clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE);
130         clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE);
131         clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI);
132 #ifdef CONFIG_SUNXI_GEN_SUN6I
133         clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI);
134 #endif
135         clock_set_pll3(0);
136 }
137
138 static int sunxi_hdmi_ddc_do_command(u32 cmnd, int offset, int n)
139 {
140         struct sunxi_hdmi_reg * const hdmi =
141                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
142
143         setbits_le32(&hdmi->ddc_fifo_ctrl, SUNXI_HDMI_DDC_FIFO_CTRL_CLEAR);
144         writel(SUNXI_HMDI_DDC_ADDR_EDDC_SEGMENT(offset >> 8) |
145                SUNXI_HMDI_DDC_ADDR_EDDC_ADDR |
146                SUNXI_HMDI_DDC_ADDR_OFFSET(offset) |
147                SUNXI_HMDI_DDC_ADDR_SLAVE_ADDR, &hdmi->ddc_addr);
148 #ifndef CONFIG_MACH_SUN6I
149         writel(n, &hdmi->ddc_byte_count);
150         writel(cmnd, &hdmi->ddc_cmnd);
151 #else
152         writel(n << 16 | cmnd, &hdmi->ddc_cmnd);
153 #endif
154         setbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START);
155
156         return await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START, 0);
157 }
158
159 static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count)
160 {
161         struct sunxi_hdmi_reg * const hdmi =
162                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
163         int i, n;
164
165         while (count > 0) {
166                 if (count > 16)
167                         n = 16;
168                 else
169                         n = count;
170
171                 if (sunxi_hdmi_ddc_do_command(
172                                 SUNXI_HDMI_DDC_CMND_EXPLICIT_EDDC_READ,
173                                 offset, n))
174                         return -ETIME;
175
176                 for (i = 0; i < n; i++)
177                         *buf++ = readb(&hdmi->ddc_fifo_data);
178
179                 offset += n;
180                 count -= n;
181         }
182
183         return 0;
184 }
185
186 static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
187 {
188         int r, retries = 2;
189
190         do {
191                 r = sunxi_hdmi_ddc_read(block * 128, buf, 128);
192                 if (r)
193                         continue;
194                 r = edid_check_checksum(buf);
195                 if (r) {
196                         printf("EDID block %d: checksum error%s\n",
197                                block, retries ? ", retrying" : "");
198                 }
199         } while (r && retries--);
200
201         return r;
202 }
203
204 static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
205 {
206         struct edid1_info edid1;
207         struct edid_cea861_info cea681[4];
208         struct edid_detailed_timing *t =
209                 (struct edid_detailed_timing *)edid1.monitor_details.timing;
210         struct sunxi_hdmi_reg * const hdmi =
211                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
212         struct sunxi_ccm_reg * const ccm =
213                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
214         int i, r, ext_blocks = 0;
215
216         /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */
217         writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE,
218                &hdmi->pad_ctrl1);
219         writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15),
220                &hdmi->pll_ctrl);
221         writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
222
223         /* Reset i2c controller */
224         setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
225         writel(SUNXI_HMDI_DDC_CTRL_ENABLE |
226                SUNXI_HMDI_DDC_CTRL_SDA_ENABLE |
227                SUNXI_HMDI_DDC_CTRL_SCL_ENABLE |
228                SUNXI_HMDI_DDC_CTRL_RESET, &hdmi->ddc_ctrl);
229         if (await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_RESET, 0))
230                 return -EIO;
231
232         writel(SUNXI_HDMI_DDC_CLOCK, &hdmi->ddc_clock);
233 #ifndef CONFIG_MACH_SUN6I
234         writel(SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE |
235                SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, &hdmi->ddc_line_ctrl);
236 #endif
237
238         r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1);
239         if (r == 0) {
240                 r = edid_check_info(&edid1);
241                 if (r) {
242                         printf("EDID: invalid EDID data\n");
243                         r = -EINVAL;
244                 }
245         }
246         if (r == 0) {
247                 ext_blocks = edid1.extension_flag;
248                 if (ext_blocks > 4)
249                         ext_blocks = 4;
250                 for (i = 0; i < ext_blocks; i++) {
251                         if (sunxi_hdmi_edid_get_block(1 + i,
252                                                 (u8 *)&cea681[i]) != 0) {
253                                 ext_blocks = i;
254                                 break;
255                         }
256                 }
257         }
258
259         /* Disable DDC engine, no longer needed */
260         clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE);
261         clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
262
263         if (r)
264                 return r;
265
266         /* We want version 1.3 or 1.2 with detailed timing info */
267         if (edid1.version != 1 || (edid1.revision < 3 &&
268                         !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) {
269                 printf("EDID: unsupported version %d.%d\n",
270                        edid1.version, edid1.revision);
271                 return -EINVAL;
272         }
273
274         /* Take the first usable detailed timing */
275         for (i = 0; i < 4; i++, t++) {
276                 r = video_edid_dtd_to_ctfb_res_modes(t, mode);
277                 if (r == 0)
278                         break;
279         }
280         if (i == 4) {
281                 printf("EDID: no usable detailed timing found\n");
282                 return -ENOENT;
283         }
284
285         /* Check for basic audio support, if found enable hdmi output */
286         sunxi_display.monitor = sunxi_monitor_dvi;
287         for (i = 0; i < ext_blocks; i++) {
288                 if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
289                     cea681[i].revision < 2)
290                         continue;
291
292                 if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
293                         sunxi_display.monitor = sunxi_monitor_hdmi;
294         }
295
296         return 0;
297 }
298
299 #endif /* CONFIG_VIDEO_HDMI */
300
301 #ifdef CONFIG_MACH_SUN4I
302 /*
303  * Testing has shown that on sun4i the display backend engine does not have
304  * deep enough fifo-s causing flickering / tearing in full-hd mode due to
305  * fifo underruns. So on sun4i we use the display frontend engine to do the
306  * dma from memory, as the frontend does have deep enough fifo-s.
307  */
308
309 static const u32 sun4i_vert_coef[32] = {
310         0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd,
311         0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb,
312         0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb,
313         0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
314         0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
315         0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff,
316         0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff,
317         0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100,
318 };
319
320 static const u32 sun4i_horz_coef[64] = {
321         0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03,
322         0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06,
323         0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09,
324         0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f,
325         0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12,
326         0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18,
327         0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e,
328         0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23,
329         0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29,
330         0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e,
331         0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33,
332         0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37,
333         0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b,
334         0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e,
335         0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40,
336         0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42,
337 };
338
339 static void sunxi_frontend_init(void)
340 {
341         struct sunxi_ccm_reg * const ccm =
342                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
343         struct sunxi_de_fe_reg * const de_fe =
344                 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
345         int i;
346
347         /* Clocks on */
348         setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0);
349         setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0);
350         clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000);
351
352         setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN);
353
354         for (i = 0; i < 32; i++) {
355                 writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]);
356                 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]);
357                 writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]);
358                 writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]);
359                 writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]);
360                 writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]);
361         }
362
363         setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY);
364 }
365
366 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
367                                     unsigned int address)
368 {
369         struct sunxi_de_fe_reg * const de_fe =
370                 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
371
372         setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS);
373         writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr);
374         writel(mode->xres * 4, &de_fe->ch0_stride);
375         writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt);
376         writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt);
377
378         writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
379                &de_fe->ch0_insize);
380         writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
381                &de_fe->ch0_outsize);
382         writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact);
383         writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact);
384
385         writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
386                &de_fe->ch1_insize);
387         writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres),
388                &de_fe->ch1_outsize);
389         writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact);
390         writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact);
391
392         setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY);
393 }
394
395 static void sunxi_frontend_enable(void)
396 {
397         struct sunxi_de_fe_reg * const de_fe =
398                 (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE;
399
400         setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START);
401 }
402 #else
403 static void sunxi_frontend_init(void) {}
404 static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
405                                     unsigned int address) {}
406 static void sunxi_frontend_enable(void) {}
407 #endif
408
409 static bool sunxi_is_composite(void)
410 {
411         switch (sunxi_display.monitor) {
412         case sunxi_monitor_none:
413         case sunxi_monitor_dvi:
414         case sunxi_monitor_hdmi:
415         case sunxi_monitor_lcd:
416         case sunxi_monitor_vga:
417                 return false;
418         case sunxi_monitor_composite_pal:
419         case sunxi_monitor_composite_ntsc:
420         case sunxi_monitor_composite_pal_m:
421         case sunxi_monitor_composite_pal_nc:
422                 return true;
423         }
424
425         return false; /* Never reached */
426 }
427
428 /*
429  * This is the entity that mixes and matches the different layers and inputs.
430  * Allwinner calls it the back-end, but i like composer better.
431  */
432 static void sunxi_composer_init(void)
433 {
434         struct sunxi_ccm_reg * const ccm =
435                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
436         struct sunxi_de_be_reg * const de_be =
437                 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
438         int i;
439
440         sunxi_frontend_init();
441
442 #ifdef CONFIG_SUNXI_GEN_SUN6I
443         /* Reset off */
444         setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0);
445 #endif
446
447         /* Clocks on */
448         setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0);
449 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
450         setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0);
451 #endif
452         clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000);
453
454         /* Engine bug, clear registers after reset */
455         for (i = 0x0800; i < 0x1000; i += 4)
456                 writel(0, SUNXI_DE_BE0_BASE + i);
457
458         setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE);
459 }
460
461 static u32 sunxi_rgb2yuv_coef[12] = {
462         0x00000107, 0x00000204, 0x00000064, 0x00000108,
463         0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
464         0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
465 };
466
467 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
468                                     unsigned int address)
469 {
470         struct sunxi_de_be_reg * const de_be =
471                 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
472         int i;
473
474         sunxi_frontend_mode_set(mode, address);
475
476         writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
477                &de_be->disp_size);
478         writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres),
479                &de_be->layer0_size);
480 #ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */
481         writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride);
482         writel(address << 3, &de_be->layer0_addr_low32b);
483         writel(address >> 29, &de_be->layer0_addr_high4b);
484 #else
485         writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl);
486 #endif
487         writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl);
488
489         setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE);
490         if (mode->vmode == FB_VMODE_INTERLACED)
491                 setbits_le32(&de_be->mode,
492 #ifndef CONFIG_MACH_SUN5I
493                              SUNXI_DE_BE_MODE_DEFLICKER_ENABLE |
494 #endif
495                              SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
496
497         if (sunxi_is_composite()) {
498                 writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
499                        &de_be->output_color_ctrl);
500                 for (i = 0; i < 12; i++)
501                         writel(sunxi_rgb2yuv_coef[i],
502                                &de_be->output_color_coef[i]);
503         }
504 }
505
506 static void sunxi_composer_enable(void)
507 {
508         struct sunxi_de_be_reg * const de_be =
509                 (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
510
511         sunxi_frontend_enable();
512
513         setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS);
514         setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START);
515 }
516
517 /*
518  * LCDC, what allwinner calls a CRTC, so timing controller and serializer.
519  */
520 static void sunxi_lcdc_pll_set(int tcon, int dotclock,
521                                int *clk_div, int *clk_double)
522 {
523         struct sunxi_ccm_reg * const ccm =
524                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
525         int value, n, m, min_m, max_m, diff;
526         int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF;
527         int best_double = 0;
528         bool use_mipi_pll = false;
529
530         if (tcon == 0) {
531 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
532                 min_m = 6;
533                 max_m = 127;
534 #endif
535 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
536                 min_m = max_m = 7;
537 #endif
538         } else {
539                 min_m = 1;
540                 max_m = 15;
541         }
542
543         /*
544          * Find the lowest divider resulting in a matching clock, if there
545          * is no match, pick the closest lower clock, as monitors tend to
546          * not sync to higher frequencies.
547          */
548         for (m = min_m; m <= max_m; m++) {
549                 n = (m * dotclock) / 3000;
550
551                 if ((n >= 9) && (n <= 127)) {
552                         value = (3000 * n) / m;
553                         diff = dotclock - value;
554                         if (diff < best_diff) {
555                                 best_diff = diff;
556                                 best_m = m;
557                                 best_n = n;
558                                 best_double = 0;
559                         }
560                 }
561
562                 /* These are just duplicates */
563                 if (!(m & 1))
564                         continue;
565
566                 n = (m * dotclock) / 6000;
567                 if ((n >= 9) && (n <= 127)) {
568                         value = (6000 * n) / m;
569                         diff = dotclock - value;
570                         if (diff < best_diff) {
571                                 best_diff = diff;
572                                 best_m = m;
573                                 best_n = n;
574                                 best_double = 1;
575                         }
576                 }
577         }
578
579 #ifdef CONFIG_MACH_SUN6I
580         /*
581          * Use the MIPI pll if we've been unable to find any matching setting
582          * for PLL3, this happens with high dotclocks because of min_m = 6.
583          */
584         if (tcon == 0 && best_n == 0) {
585                 use_mipi_pll = true;
586                 best_m = 6;  /* Minimum m for tcon0 */
587         }
588
589         if (use_mipi_pll) {
590                 clock_set_pll3(297000000); /* Fix the video pll at 297 MHz */
591                 clock_set_mipi_pll(best_m * dotclock * 1000);
592                 debug("dotclock: %dkHz = %dkHz via mipi pll\n",
593                       dotclock, clock_get_mipi_pll() / best_m / 1000);
594         } else
595 #endif
596         {
597                 clock_set_pll3(best_n * 3000000);
598                 debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n",
599                       dotclock,
600                       (best_double + 1) * clock_get_pll3() / best_m / 1000,
601                       best_double + 1, best_n, best_m);
602         }
603
604         if (tcon == 0) {
605                 u32 pll;
606
607                 if (use_mipi_pll)
608                         pll = CCM_LCD_CH0_CTRL_MIPI_PLL;
609                 else if (best_double)
610                         pll = CCM_LCD_CH0_CTRL_PLL3_2X;
611                 else
612                         pll = CCM_LCD_CH0_CTRL_PLL3;
613
614                 writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST | pll,
615                        &ccm->lcd0_ch0_clk_cfg);
616         } else {
617                 writel(CCM_LCD_CH1_CTRL_GATE |
618                        (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X :
619                                       CCM_LCD_CH1_CTRL_PLL3) |
620                        CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg);
621                 if (sunxi_is_composite())
622                         setbits_le32(&ccm->lcd0_ch1_clk_cfg,
623                                      CCM_LCD_CH1_CTRL_HALF_SCLK1);
624         }
625
626         *clk_div = best_m;
627         *clk_double = best_double;
628 }
629
630 static void sunxi_lcdc_init(void)
631 {
632         struct sunxi_ccm_reg * const ccm =
633                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
634         struct sunxi_lcdc_reg * const lcdc =
635                 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
636
637         /* Reset off */
638 #ifdef CONFIG_SUNXI_GEN_SUN6I
639         setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
640 #else
641         setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST);
642 #endif
643
644         /* Clock on */
645         setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
646 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
647 #ifdef CONFIG_SUNXI_GEN_SUN6I
648         setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS);
649 #else
650         setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
651 #endif
652 #endif
653
654         lcdc_init(lcdc);
655 }
656
657 static void sunxi_lcdc_panel_enable(void)
658 {
659         int pin, reset_pin;
660
661         /*
662          * Start with backlight disabled to avoid the screen flashing to
663          * white while the lcd inits.
664          */
665         pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
666         if (pin >= 0) {
667                 gpio_request(pin, "lcd_backlight_enable");
668                 gpio_direction_output(pin, 0);
669         }
670
671         pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
672         if (pin >= 0) {
673                 gpio_request(pin, "lcd_backlight_pwm");
674                 gpio_direction_output(pin, PWM_OFF);
675         }
676
677         reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET);
678         if (reset_pin >= 0) {
679                 gpio_request(reset_pin, "lcd_reset");
680                 gpio_direction_output(reset_pin, 0); /* Assert reset */
681         }
682
683         /* Give the backlight some time to turn off and power up the panel. */
684         mdelay(40);
685         pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
686         if (pin >= 0) {
687                 gpio_request(pin, "lcd_power");
688                 gpio_direction_output(pin, 1);
689         }
690
691         if (reset_pin >= 0)
692                 gpio_direction_output(reset_pin, 1); /* De-assert reset */
693 }
694
695 static void sunxi_lcdc_backlight_enable(void)
696 {
697         int pin;
698
699         /*
700          * We want to have scanned out at least one frame before enabling the
701          * backlight to avoid the screen flashing to white when we enable it.
702          */
703         mdelay(40);
704
705         pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN);
706         if (pin >= 0)
707                 gpio_direction_output(pin, 1);
708
709         pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
710 #ifdef SUNXI_PWM_PIN0
711         if (pin == SUNXI_PWM_PIN0) {
712                 writel(SUNXI_PWM_CTRL_POLARITY0(PWM_ON) |
713                        SUNXI_PWM_CTRL_ENABLE0 |
714                        SUNXI_PWM_CTRL_PRESCALE0(0xf), SUNXI_PWM_CTRL_REG);
715                 writel(SUNXI_PWM_PERIOD_80PCT, SUNXI_PWM_CH0_PERIOD);
716                 sunxi_gpio_set_cfgpin(pin, SUNXI_PWM_MUX);
717                 return;
718         }
719 #endif
720         if (pin >= 0)
721                 gpio_direction_output(pin, PWM_ON);
722 }
723
724 static void sunxi_ctfb_mode_to_display_timing(const struct ctfb_res_modes *mode,
725                                               struct display_timing *timing)
726 {
727         timing->pixelclock.typ = mode->pixclock_khz * 1000;
728
729         timing->hactive.typ = mode->xres;
730         timing->hfront_porch.typ = mode->right_margin;
731         timing->hback_porch.typ = mode->left_margin;
732         timing->hsync_len.typ = mode->hsync_len;
733
734         timing->vactive.typ = mode->yres;
735         timing->vfront_porch.typ = mode->lower_margin;
736         timing->vback_porch.typ = mode->upper_margin;
737         timing->vsync_len.typ = mode->vsync_len;
738
739         if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
740                 timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
741         else
742                 timing->flags |= DISPLAY_FLAGS_HSYNC_LOW;
743         if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
744                 timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
745         else
746                 timing->flags |= DISPLAY_FLAGS_VSYNC_LOW;
747         if (mode->vmode == FB_VMODE_INTERLACED)
748                 timing->flags |= DISPLAY_FLAGS_INTERLACED;
749 }
750
751 static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
752                                       bool for_ext_vga_dac)
753 {
754         struct sunxi_lcdc_reg * const lcdc =
755                 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
756         int clk_div, clk_double, pin;
757         struct display_timing timing;
758
759 #if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS
760         for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) {
761 #else
762         for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
763 #endif
764 #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
765                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
766 #endif
767 #ifdef CONFIG_VIDEO_LCD_IF_LVDS
768                 sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
769 #endif
770 #ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
771                 sunxi_gpio_set_drv(pin, 3);
772 #endif
773         }
774
775         sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
776
777         sunxi_ctfb_mode_to_display_timing(mode, &timing);
778         lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
779                             sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
780 }
781
782 #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
783 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
784                                       int *clk_div, int *clk_double,
785                                       bool use_portd_hvsync)
786 {
787         struct sunxi_lcdc_reg * const lcdc =
788                 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
789         struct display_timing timing;
790
791         sunxi_ctfb_mode_to_display_timing(mode, &timing);
792         lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync,
793                             sunxi_is_composite());
794
795         if (use_portd_hvsync) {
796                 sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
797                 sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0);
798         }
799
800         sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double);
801 }
802 #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
803
804 #ifdef CONFIG_VIDEO_HDMI
805
806 static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
807 {
808         struct sunxi_hdmi_reg * const hdmi =
809                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
810         u8 checksum = 0;
811         u8 avi_info_frame[17] = {
812                 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00,
813                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814                 0x00
815         };
816         u8 vendor_info_frame[19] = {
817                 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40,
818                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819                 0x00, 0x00, 0x00
820         };
821         int i;
822
823         if (mode->pixclock_khz <= 27000)
824                 avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */
825         else
826                 avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */
827
828         if (mode->xres * 100 / mode->yres < 156)
829                 avi_info_frame[5] |= 0x18; /* 4 : 3 */
830         else
831                 avi_info_frame[5] |= 0x28; /* 16 : 9 */
832
833         for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
834                 checksum += avi_info_frame[i];
835
836         avi_info_frame[3] = 0x100 - checksum;
837
838         for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++)
839                 writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]);
840
841         writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0);
842         writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1);
843
844         for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++)
845                 writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]);
846
847         writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0);
848         writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1);
849
850         setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI);
851 }
852
853 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
854                                 int clk_div, int clk_double)
855 {
856         struct sunxi_hdmi_reg * const hdmi =
857                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
858         int x, y;
859
860         /* Write clear interrupt status bits */
861         writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
862
863         if (sunxi_display.monitor == sunxi_monitor_hdmi)
864                 sunxi_hdmi_setup_info_frames(mode);
865
866         /* Set input sync enable */
867         writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown);
868
869         /* Init various registers, select pll3 as clock source */
870         writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity);
871         writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0);
872         writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1);
873         writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl);
874         writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
875
876         /* Setup clk div and doubler */
877         clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK,
878                         SUNXI_HDMI_PLL_CTRL_DIV(clk_div));
879         if (!clk_double)
880                 setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE);
881
882         /* Setup timing registers */
883         writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres),
884                &hdmi->video_size);
885
886         x = mode->hsync_len + mode->left_margin;
887         y = mode->vsync_len + mode->upper_margin;
888         writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp);
889
890         x = mode->right_margin;
891         y = mode->lower_margin;
892         writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp);
893
894         x = mode->hsync_len;
895         y = mode->vsync_len;
896         writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw);
897
898         if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
899                 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR);
900
901         if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
902                 setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER);
903 }
904
905 static void sunxi_hdmi_enable(void)
906 {
907         struct sunxi_hdmi_reg * const hdmi =
908                 (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
909
910         udelay(100);
911         setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE);
912 }
913
914 #endif /* CONFIG_VIDEO_HDMI */
915
916 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
917
918 static void sunxi_tvencoder_mode_set(void)
919 {
920         struct sunxi_ccm_reg * const ccm =
921                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
922         struct sunxi_tve_reg * const tve =
923                 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
924
925         /* Reset off */
926         setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_TVE_RST);
927         /* Clock on */
928         setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
929
930         switch (sunxi_display.monitor) {
931         case sunxi_monitor_vga:
932                 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
933                        SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
934                        SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl);
935                 writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0);
936                 writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0);
937                 writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
938                 break;
939         case sunxi_monitor_composite_pal_nc:
940                 writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
941                 /* Fall through */
942         case sunxi_monitor_composite_pal:
943                 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
944                        SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
945                        SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
946                        SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
947                 writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
948                 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
949                 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
950                 writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
951                 writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
952                 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level);
953                 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
954                 writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level);
955                 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
956                 writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2);
957                 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
958                 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
959                 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
960                 writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num);
961                 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
962                 break;
963         case sunxi_monitor_composite_pal_m:
964                 writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq);
965                 writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst);
966                 /* Fall through */
967         case sunxi_monitor_composite_ntsc:
968                 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
969                        SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
970                        SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) |
971                        SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl);
972                 writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0);
973                 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
974                 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
975                 writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num);
976                 writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num);
977                 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level);
978                 writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1);
979                 writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level);
980                 writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase);
981                 writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width);
982                 writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2);
983                 writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level);
984                 writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num);
985                 writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain);
986                 writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width);
987                 writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num);
988                 writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para);
989                 break;
990         case sunxi_monitor_none:
991         case sunxi_monitor_dvi:
992         case sunxi_monitor_hdmi:
993         case sunxi_monitor_lcd:
994                 break;
995         }
996 }
997
998 static void sunxi_tvencoder_enable(void)
999 {
1000         struct sunxi_tve_reg * const tve =
1001                 (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
1002
1003         setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE);
1004 }
1005
1006 #endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */
1007
1008 static void sunxi_drc_init(void)
1009 {
1010 #ifdef CONFIG_SUNXI_GEN_SUN6I
1011         struct sunxi_ccm_reg * const ccm =
1012                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
1013
1014         /* On sun6i the drc must be clocked even when in pass-through mode */
1015 #ifdef CONFIG_MACH_SUN8I_A33
1016         setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT);
1017 #endif
1018         setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0);
1019         clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000);
1020 #endif
1021 }
1022
1023 #ifdef CONFIG_VIDEO_VGA_VIA_LCD
1024 static void sunxi_vga_external_dac_enable(void)
1025 {
1026         int pin;
1027
1028         pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN);
1029         if (pin >= 0) {
1030                 gpio_request(pin, "vga_enable");
1031                 gpio_direction_output(pin, 1);
1032         }
1033 }
1034 #endif /* CONFIG_VIDEO_VGA_VIA_LCD */
1035
1036 #ifdef CONFIG_VIDEO_LCD_SSD2828
1037 static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
1038 {
1039         struct ssd2828_config cfg = {
1040                 .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS),
1041                 .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK),
1042                 .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI),
1043                 .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO),
1044                 .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET),
1045                 .ssd2828_tx_clk_khz  = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000,
1046                 .ssd2828_color_depth = 24,
1047 #ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828
1048                 .mipi_dsi_number_of_data_lanes           = 4,
1049                 .mipi_dsi_bitrate_per_data_lane_mbps     = 513,
1050                 .mipi_dsi_delay_after_exit_sleep_mode_ms = 100,
1051                 .mipi_dsi_delay_after_set_display_on_ms  = 200
1052 #else
1053 #error MIPI LCD panel needs configuration parameters
1054 #endif
1055         };
1056
1057         if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) {
1058                 printf("SSD2828: SPI pins are not properly configured\n");
1059                 return 1;
1060         }
1061         if (cfg.reset_pin == -1) {
1062                 printf("SSD2828: Reset pin is not properly configured\n");
1063                 return 1;
1064         }
1065
1066         return ssd2828_init(&cfg, mode);
1067 }
1068 #endif /* CONFIG_VIDEO_LCD_SSD2828 */
1069
1070 static void sunxi_engines_init(void)
1071 {
1072         sunxi_composer_init();
1073         sunxi_lcdc_init();
1074         sunxi_drc_init();
1075 }
1076
1077 static void sunxi_mode_set(const struct ctfb_res_modes *mode,
1078                            unsigned int address)
1079 {
1080         int __maybe_unused clk_div, clk_double;
1081         struct sunxi_lcdc_reg * const lcdc =
1082                 (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
1083
1084         switch (sunxi_display.monitor) {
1085         case sunxi_monitor_none:
1086                 break;
1087         case sunxi_monitor_dvi:
1088         case sunxi_monitor_hdmi:
1089 #ifdef CONFIG_VIDEO_HDMI
1090                 sunxi_composer_mode_set(mode, address);
1091                 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1092                 sunxi_hdmi_mode_set(mode, clk_div, clk_double);
1093                 sunxi_composer_enable();
1094                 lcdc_enable(lcdc, sunxi_display.depth);
1095                 sunxi_hdmi_enable();
1096 #endif
1097                 break;
1098         case sunxi_monitor_lcd:
1099                 sunxi_lcdc_panel_enable();
1100                 if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
1101                         /*
1102                          * The anx9804 needs 1.8V from eldo3, we do this here
1103                          * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
1104                          * to avoid turning this on when using hdmi output.
1105                          */
1106                         axp_set_eldo(3, 1800);
1107                         anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
1108                                      ANX9804_DATA_RATE_1620M,
1109                                      sunxi_display.depth);
1110                 }
1111                 if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
1112                         mdelay(50); /* Wait for lcd controller power on */
1113                         hitachi_tx18d42vm_init();
1114                 }
1115                 if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
1116                         unsigned int orig_i2c_bus = i2c_get_bus_num();
1117                         i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
1118                         i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
1119                         i2c_set_bus_num(orig_i2c_bus);
1120                 }
1121                 sunxi_composer_mode_set(mode, address);
1122                 sunxi_lcdc_tcon0_mode_set(mode, false);
1123                 sunxi_composer_enable();
1124                 lcdc_enable(lcdc, sunxi_display.depth);
1125 #ifdef CONFIG_VIDEO_LCD_SSD2828
1126                 sunxi_ssd2828_init(mode);
1127 #endif
1128                 sunxi_lcdc_backlight_enable();
1129                 break;
1130         case sunxi_monitor_vga:
1131 #ifdef CONFIG_VIDEO_VGA
1132                 sunxi_composer_mode_set(mode, address);
1133                 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
1134                 sunxi_tvencoder_mode_set();
1135                 sunxi_composer_enable();
1136                 lcdc_enable(lcdc, sunxi_display.depth);
1137                 sunxi_tvencoder_enable();
1138 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1139                 sunxi_composer_mode_set(mode, address);
1140                 sunxi_lcdc_tcon0_mode_set(mode, true);
1141                 sunxi_composer_enable();
1142                 lcdc_enable(lcdc, sunxi_display.depth);
1143                 sunxi_vga_external_dac_enable();
1144 #endif
1145                 break;
1146         case sunxi_monitor_composite_pal:
1147         case sunxi_monitor_composite_ntsc:
1148         case sunxi_monitor_composite_pal_m:
1149         case sunxi_monitor_composite_pal_nc:
1150 #ifdef CONFIG_VIDEO_COMPOSITE
1151                 sunxi_composer_mode_set(mode, address);
1152                 sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
1153                 sunxi_tvencoder_mode_set();
1154                 sunxi_composer_enable();
1155                 lcdc_enable(lcdc, sunxi_display.depth);
1156                 sunxi_tvencoder_enable();
1157 #endif
1158                 break;
1159         }
1160 }
1161
1162 static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
1163 {
1164         switch (monitor) {
1165         case sunxi_monitor_none:                return "none";
1166         case sunxi_monitor_dvi:                 return "dvi";
1167         case sunxi_monitor_hdmi:                return "hdmi";
1168         case sunxi_monitor_lcd:                 return "lcd";
1169         case sunxi_monitor_vga:                 return "vga";
1170         case sunxi_monitor_composite_pal:       return "composite-pal";
1171         case sunxi_monitor_composite_ntsc:      return "composite-ntsc";
1172         case sunxi_monitor_composite_pal_m:     return "composite-pal-m";
1173         case sunxi_monitor_composite_pal_nc:    return "composite-pal-nc";
1174         }
1175         return NULL; /* never reached */
1176 }
1177
1178 ulong board_get_usable_ram_top(ulong total_size)
1179 {
1180         return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
1181 }
1182
1183 static bool sunxi_has_hdmi(void)
1184 {
1185 #ifdef CONFIG_VIDEO_HDMI
1186         return true;
1187 #else
1188         return false;
1189 #endif
1190 }
1191
1192 static bool sunxi_has_lcd(void)
1193 {
1194         char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1195
1196         return lcd_mode[0] != 0;
1197 }
1198
1199 static bool sunxi_has_vga(void)
1200 {
1201 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD
1202         return true;
1203 #else
1204         return false;
1205 #endif
1206 }
1207
1208 static bool sunxi_has_composite(void)
1209 {
1210 #ifdef CONFIG_VIDEO_COMPOSITE
1211         return true;
1212 #else
1213         return false;
1214 #endif
1215 }
1216
1217 static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
1218 {
1219         if (allow_hdmi && sunxi_has_hdmi())
1220                 return sunxi_monitor_dvi;
1221         else if (sunxi_has_lcd())
1222                 return sunxi_monitor_lcd;
1223         else if (sunxi_has_vga())
1224                 return sunxi_monitor_vga;
1225         else if (sunxi_has_composite())
1226                 return sunxi_monitor_composite_pal;
1227         else
1228                 return sunxi_monitor_none;
1229 }
1230
1231 void *video_hw_init(void)
1232 {
1233         static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1234         const struct ctfb_res_modes *mode;
1235         struct ctfb_res_modes custom;
1236         const char *options;
1237 #ifdef CONFIG_VIDEO_HDMI
1238         int ret, hpd, hpd_delay, edid;
1239 #endif
1240         int i, overscan_offset, overscan_x, overscan_y;
1241         unsigned int fb_dma_addr;
1242         char mon[16];
1243         char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
1244
1245         memset(&sunxi_display, 0, sizeof(struct sunxi_display));
1246
1247         video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
1248                                  &sunxi_display.depth, &options);
1249 #ifdef CONFIG_VIDEO_HDMI
1250         hpd = video_get_option_int(options, "hpd", 1);
1251         hpd_delay = video_get_option_int(options, "hpd_delay", 500);
1252         edid = video_get_option_int(options, "edid", 1);
1253 #endif
1254         overscan_x = video_get_option_int(options, "overscan_x", -1);
1255         overscan_y = video_get_option_int(options, "overscan_y", -1);
1256         sunxi_display.monitor = sunxi_get_default_mon(true);
1257         video_get_option_string(options, "monitor", mon, sizeof(mon),
1258                                 sunxi_get_mon_desc(sunxi_display.monitor));
1259         for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
1260                 if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
1261                         sunxi_display.monitor = i;
1262                         break;
1263                 }
1264         }
1265         if (i > SUNXI_MONITOR_LAST)
1266                 printf("Unknown monitor: '%s', falling back to '%s'\n",
1267                        mon, sunxi_get_mon_desc(sunxi_display.monitor));
1268
1269 #ifdef CONFIG_VIDEO_HDMI
1270         /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
1271         if (sunxi_display.monitor == sunxi_monitor_dvi ||
1272             sunxi_display.monitor == sunxi_monitor_hdmi) {
1273                 /* Always call hdp_detect, as it also enables clocks, etc. */
1274                 ret = sunxi_hdmi_hpd_detect(hpd_delay);
1275                 if (ret) {
1276                         printf("HDMI connected: ");
1277                         if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
1278                                 mode = &custom;
1279                 } else if (hpd) {
1280                         sunxi_hdmi_shutdown();
1281                         sunxi_display.monitor = sunxi_get_default_mon(false);
1282                 } /* else continue with hdmi/dvi without a cable connected */
1283         }
1284 #endif
1285
1286         switch (sunxi_display.monitor) {
1287         case sunxi_monitor_none:
1288                 return NULL;
1289         case sunxi_monitor_dvi:
1290         case sunxi_monitor_hdmi:
1291                 if (!sunxi_has_hdmi()) {
1292                         printf("HDMI/DVI not supported on this board\n");
1293                         sunxi_display.monitor = sunxi_monitor_none;
1294                         return NULL;
1295                 }
1296                 break;
1297         case sunxi_monitor_lcd:
1298                 if (!sunxi_has_lcd()) {
1299                         printf("LCD not supported on this board\n");
1300                         sunxi_display.monitor = sunxi_monitor_none;
1301                         return NULL;
1302                 }
1303                 sunxi_display.depth = video_get_params(&custom, lcd_mode);
1304                 mode = &custom;
1305                 break;
1306         case sunxi_monitor_vga:
1307                 if (!sunxi_has_vga()) {
1308                         printf("VGA not supported on this board\n");
1309                         sunxi_display.monitor = sunxi_monitor_none;
1310                         return NULL;
1311                 }
1312                 sunxi_display.depth = 18;
1313                 break;
1314         case sunxi_monitor_composite_pal:
1315         case sunxi_monitor_composite_ntsc:
1316         case sunxi_monitor_composite_pal_m:
1317         case sunxi_monitor_composite_pal_nc:
1318                 if (!sunxi_has_composite()) {
1319                         printf("Composite video not supported on this board\n");
1320                         sunxi_display.monitor = sunxi_monitor_none;
1321                         return NULL;
1322                 }
1323                 if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
1324                     sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
1325                         mode = &composite_video_modes[0];
1326                 else
1327                         mode = &composite_video_modes[1];
1328                 sunxi_display.depth = 24;
1329                 break;
1330         }
1331
1332         /* Yes these defaults are quite high, overscan on composite sucks... */
1333         if (overscan_x == -1)
1334                 overscan_x = sunxi_is_composite() ? 32 : 0;
1335         if (overscan_y == -1)
1336                 overscan_y = sunxi_is_composite() ? 20 : 0;
1337
1338         sunxi_display.fb_size =
1339                 (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
1340         overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
1341         /* We want to keep the fb_base for simplefb page aligned, where as
1342          * the sunxi dma engines will happily accept an unaligned address. */
1343         if (overscan_offset)
1344                 sunxi_display.fb_size += 0x1000;
1345
1346         if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
1347                 printf("Error need %dkB for fb, but only %dkB is reserved\n",
1348                        sunxi_display.fb_size >> 10,
1349                        CONFIG_SUNXI_MAX_FB_SIZE >> 10);
1350                 return NULL;
1351         }
1352
1353         printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
1354                mode->xres, mode->yres,
1355                (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
1356                sunxi_get_mon_desc(sunxi_display.monitor),
1357                overscan_x, overscan_y);
1358
1359         gd->fb_base = gd->bd->bi_dram[0].start +
1360                       gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1361         sunxi_engines_init();
1362
1363         fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
1364         sunxi_display.fb_addr = gd->fb_base;
1365         if (overscan_offset) {
1366                 fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
1367                 sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
1368                 memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
1369                 flush_cache(gd->fb_base, sunxi_display.fb_size);
1370         }
1371         sunxi_mode_set(mode, fb_dma_addr);
1372
1373         /*
1374          * These are the only members of this structure that are used. All the
1375          * others are driver specific. The pitch is stored in plnSizeX.
1376          */
1377         graphic_device->frameAdrs = sunxi_display.fb_addr;
1378         graphic_device->gdfIndex = GDF_32BIT_X888RGB;
1379         graphic_device->gdfBytesPP = 4;
1380         graphic_device->winSizeX = mode->xres - 2 * overscan_x;
1381         graphic_device->winSizeY = mode->yres - 2 * overscan_y;
1382         graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
1383
1384         return graphic_device;
1385 }
1386
1387 /*
1388  * Simplefb support.
1389  */
1390 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
1391 int sunxi_simplefb_setup(void *blob)
1392 {
1393         static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
1394         int offset, ret;
1395         u64 start, size;
1396         const char *pipeline = NULL;
1397
1398 #ifdef CONFIG_MACH_SUN4I
1399 #define PIPELINE_PREFIX "de_fe0-"
1400 #else
1401 #define PIPELINE_PREFIX
1402 #endif
1403
1404         switch (sunxi_display.monitor) {
1405         case sunxi_monitor_none:
1406                 return 0;
1407         case sunxi_monitor_dvi:
1408         case sunxi_monitor_hdmi:
1409                 pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi";
1410                 break;
1411         case sunxi_monitor_lcd:
1412                 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1413                 break;
1414         case sunxi_monitor_vga:
1415 #ifdef CONFIG_VIDEO_VGA
1416                 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1417 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
1418                 pipeline = PIPELINE_PREFIX "de_be0-lcd0";
1419 #endif
1420                 break;
1421         case sunxi_monitor_composite_pal:
1422         case sunxi_monitor_composite_ntsc:
1423         case sunxi_monitor_composite_pal_m:
1424         case sunxi_monitor_composite_pal_nc:
1425                 pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0";
1426                 break;
1427         }
1428
1429         /* Find a prefilled simpefb node, matching out pipeline config */
1430         offset = fdt_node_offset_by_compatible(blob, -1,
1431                                                "allwinner,simple-framebuffer");
1432         while (offset >= 0) {
1433                 ret = fdt_stringlist_search(blob, offset, "allwinner,pipeline",
1434                                             pipeline);
1435                 if (ret == 0)
1436                         break;
1437                 offset = fdt_node_offset_by_compatible(blob, offset,
1438                                                "allwinner,simple-framebuffer");
1439         }
1440         if (offset < 0) {
1441                 eprintf("Cannot setup simplefb: node not found\n");
1442                 return 0; /* Keep older kernels working */
1443         }
1444
1445         /*
1446          * Do not report the framebuffer as free RAM to the OS, note we cannot
1447          * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
1448          * and e.g. Linux refuses to iomap RAM on ARM, see:
1449          * linux/arch/arm/mm/ioremap.c around line 301.
1450          */
1451         start = gd->bd->bi_dram[0].start;
1452         size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
1453         ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
1454         if (ret) {
1455                 eprintf("Cannot setup simplefb: Error reserving memory\n");
1456                 return ret;
1457         }
1458
1459         ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr,
1460                         graphic_device->winSizeX, graphic_device->winSizeY,
1461                         graphic_device->plnSizeX, "x8r8g8b8");
1462         if (ret)
1463                 eprintf("Cannot setup simplefb: Error setting properties\n");
1464
1465         return ret;
1466 }
1467 #endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */