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