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