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