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