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