1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Amlogic Meson Video Processing Unit driver 4 * 5 * Copyright (c) 2018 BayLibre, SAS. 6 * Author: Neil Armstrong <narmstrong@baylibre.com> 7 */ 8 9 #include <edid.h> 10 #include "meson_vpu.h" 11 12 enum { 13 MESON_VENC_MODE_NONE = 0, 14 MESON_VENC_MODE_CVBS_PAL, 15 MESON_VENC_MODE_CVBS_NTSC, 16 MESON_VENC_MODE_HDMI, 17 }; 18 19 enum meson_venc_source { 20 MESON_VENC_SOURCE_NONE = 0, 21 MESON_VENC_SOURCE_ENCI = 1, 22 MESON_VENC_SOURCE_ENCP = 2, 23 }; 24 25 #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ 26 #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ 27 28 struct meson_cvbs_enci_mode { 29 unsigned int mode_tag; 30 unsigned int hso_begin; /* HSO begin position */ 31 unsigned int hso_end; /* HSO end position */ 32 unsigned int vso_even; /* VSO even line */ 33 unsigned int vso_odd; /* VSO odd line */ 34 unsigned int macv_max_amp; /* Macrovision max amplitude */ 35 unsigned int video_prog_mode; 36 unsigned int video_mode; 37 unsigned int sch_adjust; 38 unsigned int yc_delay; 39 unsigned int pixel_start; 40 unsigned int pixel_end; 41 unsigned int top_field_line_start; 42 unsigned int top_field_line_end; 43 unsigned int bottom_field_line_start; 44 unsigned int bottom_field_line_end; 45 unsigned int video_saturation; 46 unsigned int video_contrast; 47 unsigned int video_brightness; 48 unsigned int video_hue; 49 unsigned int analog_sync_adj; 50 }; 51 52 struct meson_cvbs_enci_mode meson_cvbs_enci_pal = { 53 .mode_tag = MESON_VENC_MODE_CVBS_PAL, 54 .hso_begin = 3, 55 .hso_end = 129, 56 .vso_even = 3, 57 .vso_odd = 260, 58 .macv_max_amp = 7, 59 .video_prog_mode = 0xff, 60 .video_mode = 0x13, 61 .sch_adjust = 0x28, 62 .yc_delay = 0x343, 63 .pixel_start = 251, 64 .pixel_end = 1691, 65 .top_field_line_start = 22, 66 .top_field_line_end = 310, 67 .bottom_field_line_start = 23, 68 .bottom_field_line_end = 311, 69 .video_saturation = 9, 70 .video_contrast = 0, 71 .video_brightness = 0, 72 .video_hue = 0, 73 .analog_sync_adj = 0x8080, 74 }; 75 76 struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = { 77 .mode_tag = MESON_VENC_MODE_CVBS_NTSC, 78 .hso_begin = 5, 79 .hso_end = 129, 80 .vso_even = 3, 81 .vso_odd = 260, 82 .macv_max_amp = 0xb, 83 .video_prog_mode = 0xf0, 84 .video_mode = 0x8, 85 .sch_adjust = 0x20, 86 .yc_delay = 0x333, 87 .pixel_start = 227, 88 .pixel_end = 1667, 89 .top_field_line_start = 18, 90 .top_field_line_end = 258, 91 .bottom_field_line_start = 19, 92 .bottom_field_line_end = 259, 93 .video_saturation = 18, 94 .video_contrast = 3, 95 .video_brightness = 0, 96 .video_hue = 0, 97 .analog_sync_adj = 0x9c00, 98 }; 99 100 union meson_hdmi_venc_mode { 101 struct { 102 unsigned int mode_tag; 103 unsigned int hso_begin; 104 unsigned int hso_end; 105 unsigned int vso_even; 106 unsigned int vso_odd; 107 unsigned int macv_max_amp; 108 unsigned int video_prog_mode; 109 unsigned int video_mode; 110 unsigned int sch_adjust; 111 unsigned int yc_delay; 112 unsigned int pixel_start; 113 unsigned int pixel_end; 114 unsigned int top_field_line_start; 115 unsigned int top_field_line_end; 116 unsigned int bottom_field_line_start; 117 unsigned int bottom_field_line_end; 118 } enci; 119 struct { 120 unsigned int dvi_settings; 121 unsigned int video_mode; 122 unsigned int video_mode_adv; 123 unsigned int video_prog_mode; 124 bool video_prog_mode_present; 125 unsigned int video_sync_mode; 126 bool video_sync_mode_present; 127 unsigned int video_yc_dly; 128 bool video_yc_dly_present; 129 unsigned int video_rgb_ctrl; 130 bool video_rgb_ctrl_present; 131 unsigned int video_filt_ctrl; 132 bool video_filt_ctrl_present; 133 unsigned int video_ofld_voav_ofst; 134 bool video_ofld_voav_ofst_present; 135 unsigned int yfp1_htime; 136 unsigned int yfp2_htime; 137 unsigned int max_pxcnt; 138 unsigned int hspuls_begin; 139 unsigned int hspuls_end; 140 unsigned int hspuls_switch; 141 unsigned int vspuls_begin; 142 unsigned int vspuls_end; 143 unsigned int vspuls_bline; 144 unsigned int vspuls_eline; 145 unsigned int eqpuls_begin; 146 bool eqpuls_begin_present; 147 unsigned int eqpuls_end; 148 bool eqpuls_end_present; 149 unsigned int eqpuls_bline; 150 bool eqpuls_bline_present; 151 unsigned int eqpuls_eline; 152 bool eqpuls_eline_present; 153 unsigned int havon_begin; 154 unsigned int havon_end; 155 unsigned int vavon_bline; 156 unsigned int vavon_eline; 157 unsigned int hso_begin; 158 unsigned int hso_end; 159 unsigned int vso_begin; 160 unsigned int vso_end; 161 unsigned int vso_bline; 162 unsigned int vso_eline; 163 bool vso_eline_present; 164 unsigned int sy_val; 165 bool sy_val_present; 166 unsigned int sy2_val; 167 bool sy2_val_present; 168 unsigned int max_lncnt; 169 } encp; 170 }; 171 172 union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = { 173 .enci = { 174 .hso_begin = 5, 175 .hso_end = 129, 176 .vso_even = 3, 177 .vso_odd = 260, 178 .macv_max_amp = 0x810b, 179 .video_prog_mode = 0xf0, 180 .video_mode = 0x8, 181 .sch_adjust = 0x20, 182 .yc_delay = 0, 183 .pixel_start = 227, 184 .pixel_end = 1667, 185 .top_field_line_start = 18, 186 .top_field_line_end = 258, 187 .bottom_field_line_start = 19, 188 .bottom_field_line_end = 259, 189 }, 190 }; 191 192 union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = { 193 .enci = { 194 .hso_begin = 3, 195 .hso_end = 129, 196 .vso_even = 3, 197 .vso_odd = 260, 198 .macv_max_amp = 8107, 199 .video_prog_mode = 0xff, 200 .video_mode = 0x13, 201 .sch_adjust = 0x28, 202 .yc_delay = 0x333, 203 .pixel_start = 251, 204 .pixel_end = 1691, 205 .top_field_line_start = 22, 206 .top_field_line_end = 310, 207 .bottom_field_line_start = 23, 208 .bottom_field_line_end = 311, 209 }, 210 }; 211 212 union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = { 213 .encp = { 214 .dvi_settings = 0x21, 215 .video_mode = 0x4000, 216 .video_mode_adv = 0x9, 217 .video_prog_mode = 0, 218 .video_prog_mode_present = true, 219 .video_sync_mode = 7, 220 .video_sync_mode_present = true, 221 /* video_yc_dly */ 222 /* video_rgb_ctrl */ 223 .video_filt_ctrl = 0x2052, 224 .video_filt_ctrl_present = true, 225 /* video_ofld_voav_ofst */ 226 .yfp1_htime = 244, 227 .yfp2_htime = 1630, 228 .max_pxcnt = 1715, 229 .hspuls_begin = 0x22, 230 .hspuls_end = 0xa0, 231 .hspuls_switch = 88, 232 .vspuls_begin = 0, 233 .vspuls_end = 1589, 234 .vspuls_bline = 0, 235 .vspuls_eline = 5, 236 .havon_begin = 249, 237 .havon_end = 1689, 238 .vavon_bline = 42, 239 .vavon_eline = 521, 240 /* eqpuls_begin */ 241 /* eqpuls_end */ 242 /* eqpuls_bline */ 243 /* eqpuls_eline */ 244 .hso_begin = 3, 245 .hso_end = 5, 246 .vso_begin = 3, 247 .vso_end = 5, 248 .vso_bline = 0, 249 /* vso_eline */ 250 .sy_val = 8, 251 .sy_val_present = true, 252 .sy2_val = 0x1d8, 253 .sy2_val_present = true, 254 .max_lncnt = 524, 255 }, 256 }; 257 258 union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = { 259 .encp = { 260 .dvi_settings = 0x21, 261 .video_mode = 0x4000, 262 .video_mode_adv = 0x9, 263 .video_prog_mode = 0, 264 .video_prog_mode_present = true, 265 .video_sync_mode = 7, 266 .video_sync_mode_present = true, 267 /* video_yc_dly */ 268 /* video_rgb_ctrl */ 269 .video_filt_ctrl = 0x52, 270 .video_filt_ctrl_present = true, 271 /* video_ofld_voav_ofst */ 272 .yfp1_htime = 235, 273 .yfp2_htime = 1674, 274 .max_pxcnt = 1727, 275 .hspuls_begin = 0, 276 .hspuls_end = 0x80, 277 .hspuls_switch = 88, 278 .vspuls_begin = 0, 279 .vspuls_end = 1599, 280 .vspuls_bline = 0, 281 .vspuls_eline = 4, 282 .havon_begin = 235, 283 .havon_end = 1674, 284 .vavon_bline = 44, 285 .vavon_eline = 619, 286 /* eqpuls_begin */ 287 /* eqpuls_end */ 288 /* eqpuls_bline */ 289 /* eqpuls_eline */ 290 .hso_begin = 0x80, 291 .hso_end = 0, 292 .vso_begin = 0, 293 .vso_end = 5, 294 .vso_bline = 0, 295 /* vso_eline */ 296 .sy_val = 8, 297 .sy_val_present = true, 298 .sy2_val = 0x1d8, 299 .sy2_val_present = true, 300 .max_lncnt = 624, 301 }, 302 }; 303 304 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = { 305 .encp = { 306 .dvi_settings = 0x2029, 307 .video_mode = 0x4040, 308 .video_mode_adv = 0x19, 309 /* video_prog_mode */ 310 /* video_sync_mode */ 311 /* video_yc_dly */ 312 /* video_rgb_ctrl */ 313 /* video_filt_ctrl */ 314 /* video_ofld_voav_ofst */ 315 .yfp1_htime = 648, 316 .yfp2_htime = 3207, 317 .max_pxcnt = 3299, 318 .hspuls_begin = 80, 319 .hspuls_end = 240, 320 .hspuls_switch = 80, 321 .vspuls_begin = 688, 322 .vspuls_end = 3248, 323 .vspuls_bline = 4, 324 .vspuls_eline = 8, 325 .havon_begin = 648, 326 .havon_end = 3207, 327 .vavon_bline = 29, 328 .vavon_eline = 748, 329 /* eqpuls_begin */ 330 /* eqpuls_end */ 331 /* eqpuls_bline */ 332 /* eqpuls_eline */ 333 .hso_begin = 256, 334 .hso_end = 168, 335 .vso_begin = 168, 336 .vso_end = 256, 337 .vso_bline = 0, 338 .vso_eline = 5, 339 .vso_eline_present = true, 340 /* sy_val */ 341 /* sy2_val */ 342 .max_lncnt = 749, 343 }, 344 }; 345 346 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = { 347 .encp = { 348 .dvi_settings = 0x202d, 349 .video_mode = 0x4040, 350 .video_mode_adv = 0x19, 351 .video_prog_mode = 0x100, 352 .video_prog_mode_present = true, 353 .video_sync_mode = 0x407, 354 .video_sync_mode_present = true, 355 .video_yc_dly = 0, 356 .video_yc_dly_present = true, 357 /* video_rgb_ctrl */ 358 /* video_filt_ctrl */ 359 /* video_ofld_voav_ofst */ 360 .yfp1_htime = 648, 361 .yfp2_htime = 3207, 362 .max_pxcnt = 3959, 363 .hspuls_begin = 80, 364 .hspuls_end = 240, 365 .hspuls_switch = 80, 366 .vspuls_begin = 688, 367 .vspuls_end = 3248, 368 .vspuls_bline = 4, 369 .vspuls_eline = 8, 370 .havon_begin = 648, 371 .havon_end = 3207, 372 .vavon_bline = 29, 373 .vavon_eline = 748, 374 /* eqpuls_begin */ 375 /* eqpuls_end */ 376 /* eqpuls_bline */ 377 /* eqpuls_eline */ 378 .hso_begin = 128, 379 .hso_end = 208, 380 .vso_begin = 128, 381 .vso_end = 128, 382 .vso_bline = 0, 383 .vso_eline = 5, 384 .vso_eline_present = true, 385 /* sy_val */ 386 /* sy2_val */ 387 .max_lncnt = 749, 388 }, 389 }; 390 391 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = { 392 .encp = { 393 .dvi_settings = 0x2029, 394 .video_mode = 0x5ffc, 395 .video_mode_adv = 0x19, 396 .video_prog_mode = 0x100, 397 .video_prog_mode_present = true, 398 .video_sync_mode = 0x207, 399 .video_sync_mode_present = true, 400 /* video_yc_dly */ 401 /* video_rgb_ctrl */ 402 /* video_filt_ctrl */ 403 .video_ofld_voav_ofst = 0x11, 404 .video_ofld_voav_ofst_present = true, 405 .yfp1_htime = 516, 406 .yfp2_htime = 4355, 407 .max_pxcnt = 4399, 408 .hspuls_begin = 88, 409 .hspuls_end = 264, 410 .hspuls_switch = 88, 411 .vspuls_begin = 440, 412 .vspuls_end = 2200, 413 .vspuls_bline = 0, 414 .vspuls_eline = 4, 415 .havon_begin = 516, 416 .havon_end = 4355, 417 .vavon_bline = 20, 418 .vavon_eline = 559, 419 .eqpuls_begin = 2288, 420 .eqpuls_begin_present = true, 421 .eqpuls_end = 2464, 422 .eqpuls_end_present = true, 423 .eqpuls_bline = 0, 424 .eqpuls_bline_present = true, 425 .eqpuls_eline = 4, 426 .eqpuls_eline_present = true, 427 .hso_begin = 264, 428 .hso_end = 176, 429 .vso_begin = 88, 430 .vso_end = 88, 431 .vso_bline = 0, 432 .vso_eline = 5, 433 .vso_eline_present = true, 434 /* sy_val */ 435 /* sy2_val */ 436 .max_lncnt = 1124, 437 }, 438 }; 439 440 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = { 441 .encp = { 442 .dvi_settings = 0x202d, 443 .video_mode = 0x5ffc, 444 .video_mode_adv = 0x19, 445 .video_prog_mode = 0x100, 446 .video_prog_mode_present = true, 447 .video_sync_mode = 0x7, 448 .video_sync_mode_present = true, 449 /* video_yc_dly */ 450 /* video_rgb_ctrl */ 451 /* video_filt_ctrl */ 452 .video_ofld_voav_ofst = 0x11, 453 .video_ofld_voav_ofst_present = true, 454 .yfp1_htime = 526, 455 .yfp2_htime = 4365, 456 .max_pxcnt = 5279, 457 .hspuls_begin = 88, 458 .hspuls_end = 264, 459 .hspuls_switch = 88, 460 .vspuls_begin = 440, 461 .vspuls_end = 2200, 462 .vspuls_bline = 0, 463 .vspuls_eline = 4, 464 .havon_begin = 526, 465 .havon_end = 4365, 466 .vavon_bline = 20, 467 .vavon_eline = 559, 468 .eqpuls_begin = 2288, 469 .eqpuls_begin_present = true, 470 .eqpuls_end = 2464, 471 .eqpuls_end_present = true, 472 .eqpuls_bline = 0, 473 .eqpuls_bline_present = true, 474 .eqpuls_eline = 4, 475 .eqpuls_eline_present = true, 476 .hso_begin = 142, 477 .hso_end = 230, 478 .vso_begin = 142, 479 .vso_end = 142, 480 .vso_bline = 0, 481 .vso_eline = 5, 482 .vso_eline_present = true, 483 /* sy_val */ 484 /* sy2_val */ 485 .max_lncnt = 1124, 486 }, 487 }; 488 489 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = { 490 .encp = { 491 .dvi_settings = 0xd, 492 .video_mode = 0x4040, 493 .video_mode_adv = 0x18, 494 .video_prog_mode = 0x100, 495 .video_prog_mode_present = true, 496 .video_sync_mode = 0x7, 497 .video_sync_mode_present = true, 498 .video_yc_dly = 0, 499 .video_yc_dly_present = true, 500 .video_rgb_ctrl = 2, 501 .video_rgb_ctrl_present = true, 502 .video_filt_ctrl = 0x1052, 503 .video_filt_ctrl_present = true, 504 /* video_ofld_voav_ofst */ 505 .yfp1_htime = 271, 506 .yfp2_htime = 2190, 507 .max_pxcnt = 2749, 508 .hspuls_begin = 44, 509 .hspuls_end = 132, 510 .hspuls_switch = 44, 511 .vspuls_begin = 220, 512 .vspuls_end = 2140, 513 .vspuls_bline = 0, 514 .vspuls_eline = 4, 515 .havon_begin = 271, 516 .havon_end = 2190, 517 .vavon_bline = 41, 518 .vavon_eline = 1120, 519 /* eqpuls_begin */ 520 /* eqpuls_end */ 521 .eqpuls_bline = 0, 522 .eqpuls_bline_present = true, 523 .eqpuls_eline = 4, 524 .eqpuls_eline_present = true, 525 .hso_begin = 79, 526 .hso_end = 123, 527 .vso_begin = 79, 528 .vso_end = 79, 529 .vso_bline = 0, 530 .vso_eline = 5, 531 .vso_eline_present = true, 532 /* sy_val */ 533 /* sy2_val */ 534 .max_lncnt = 1124, 535 }, 536 }; 537 538 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = { 539 .encp = { 540 .dvi_settings = 0x1, 541 .video_mode = 0x4040, 542 .video_mode_adv = 0x18, 543 .video_prog_mode = 0x100, 544 .video_prog_mode_present = true, 545 /* video_sync_mode */ 546 /* video_yc_dly */ 547 /* video_rgb_ctrl */ 548 .video_filt_ctrl = 0x1052, 549 .video_filt_ctrl_present = true, 550 /* video_ofld_voav_ofst */ 551 .yfp1_htime = 140, 552 .yfp2_htime = 2060, 553 .max_pxcnt = 2199, 554 .hspuls_begin = 2156, 555 .hspuls_end = 44, 556 .hspuls_switch = 44, 557 .vspuls_begin = 140, 558 .vspuls_end = 2059, 559 .vspuls_bline = 0, 560 .vspuls_eline = 4, 561 .havon_begin = 148, 562 .havon_end = 2067, 563 .vavon_bline = 41, 564 .vavon_eline = 1120, 565 /* eqpuls_begin */ 566 /* eqpuls_end */ 567 /* eqpuls_bline */ 568 /* eqpuls_eline */ 569 .hso_begin = 44, 570 .hso_end = 2156, 571 .vso_begin = 2100, 572 .vso_end = 2164, 573 .vso_bline = 0, 574 .vso_eline = 5, 575 .vso_eline_present = true, 576 /* sy_val */ 577 /* sy2_val */ 578 .max_lncnt = 1124, 579 }, 580 }; 581 582 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = { 583 .encp = { 584 .dvi_settings = 0xd, 585 .video_mode = 0x4040, 586 .video_mode_adv = 0x18, 587 .video_prog_mode = 0x100, 588 .video_prog_mode_present = true, 589 .video_sync_mode = 0x7, 590 .video_sync_mode_present = true, 591 .video_yc_dly = 0, 592 .video_yc_dly_present = true, 593 .video_rgb_ctrl = 2, 594 .video_rgb_ctrl_present = true, 595 /* video_filt_ctrl */ 596 /* video_ofld_voav_ofst */ 597 .yfp1_htime = 271, 598 .yfp2_htime = 2190, 599 .max_pxcnt = 2639, 600 .hspuls_begin = 44, 601 .hspuls_end = 132, 602 .hspuls_switch = 44, 603 .vspuls_begin = 220, 604 .vspuls_end = 2140, 605 .vspuls_bline = 0, 606 .vspuls_eline = 4, 607 .havon_begin = 271, 608 .havon_end = 2190, 609 .vavon_bline = 41, 610 .vavon_eline = 1120, 611 /* eqpuls_begin */ 612 /* eqpuls_end */ 613 .eqpuls_bline = 0, 614 .eqpuls_bline_present = true, 615 .eqpuls_eline = 4, 616 .eqpuls_eline_present = true, 617 .hso_begin = 79, 618 .hso_end = 123, 619 .vso_begin = 79, 620 .vso_end = 79, 621 .vso_bline = 0, 622 .vso_eline = 5, 623 .vso_eline_present = true, 624 /* sy_val */ 625 /* sy2_val */ 626 .max_lncnt = 1124, 627 }, 628 }; 629 630 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { 631 .encp = { 632 .dvi_settings = 0x1, 633 .video_mode = 0x4040, 634 .video_mode_adv = 0x18, 635 .video_prog_mode = 0x100, 636 .video_prog_mode_present = true, 637 /* video_sync_mode */ 638 /* video_yc_dly */ 639 /* video_rgb_ctrl */ 640 .video_filt_ctrl = 0x1052, 641 .video_filt_ctrl_present = true, 642 /* video_ofld_voav_ofst */ 643 .yfp1_htime = 140, 644 .yfp2_htime = 2060, 645 .max_pxcnt = 2199, 646 .hspuls_begin = 2156, 647 .hspuls_end = 44, 648 .hspuls_switch = 44, 649 .vspuls_begin = 140, 650 .vspuls_end = 2059, 651 .vspuls_bline = 0, 652 .vspuls_eline = 4, 653 .havon_begin = 148, 654 .havon_end = 2067, 655 .vavon_bline = 41, 656 .vavon_eline = 1120, 657 /* eqpuls_begin */ 658 /* eqpuls_end */ 659 /* eqpuls_bline */ 660 /* eqpuls_eline */ 661 .hso_begin = 44, 662 .hso_end = 2156, 663 .vso_begin = 2100, 664 .vso_end = 2164, 665 .vso_bline = 0, 666 .vso_eline = 5, 667 .vso_eline_present = true, 668 /* sy_val */ 669 /* sy2_val */ 670 .max_lncnt = 1124, 671 }, 672 }; 673 674 static signed int to_signed(unsigned int a) 675 { 676 if (a <= 7) 677 return a; 678 else 679 return a - 16; 680 } 681 682 static unsigned long modulo(unsigned long a, unsigned long b) 683 { 684 if (a >= b) 685 return a - b; 686 else 687 return a; 688 } 689 690 bool meson_venc_hdmi_supported_mode(const struct display_timing *mode) 691 { 692 if (mode->flags & ~(DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_HSYNC_HIGH | 693 DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH)) 694 return false; 695 696 if (mode->hactive.typ < 640 || mode->hactive.typ > 1920) 697 return false; 698 699 if (mode->vactive.typ < 480 || mode->vactive.typ > 1200) 700 return false; 701 702 return true; 703 } 704 705 static void meson_venc_hdmi_get_dmt_vmode(const struct display_timing *mode, 706 union meson_hdmi_venc_mode *dmt_mode) 707 { 708 memset(dmt_mode, 0, sizeof(*dmt_mode)); 709 710 dmt_mode->encp.dvi_settings = 0x21; 711 dmt_mode->encp.video_mode = 0x4040; 712 dmt_mode->encp.video_mode_adv = 0x18; 713 714 dmt_mode->encp.max_pxcnt = mode->hactive.typ + 715 mode->hfront_porch.typ + 716 mode->hback_porch.typ + 717 mode->hsync_len.typ - 1; 718 719 dmt_mode->encp.havon_begin = mode->hback_porch.typ + 720 mode->hsync_len.typ; 721 722 dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin + 723 mode->hactive.typ - 1; 724 725 dmt_mode->encp.vavon_bline = mode->vback_porch.typ + 726 mode->vsync_len.typ; 727 dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline + 728 mode->vactive.typ - 1; 729 730 /* to investigate */ 731 dmt_mode->encp.hso_begin = 0; 732 dmt_mode->encp.hso_end = mode->hsync_len.typ; 733 dmt_mode->encp.vso_begin = 30; 734 dmt_mode->encp.vso_end = 50; 735 736 dmt_mode->encp.vso_bline = 0; 737 dmt_mode->encp.vso_eline = mode->vsync_len.typ; 738 dmt_mode->encp.vso_eline_present = true; 739 740 dmt_mode->encp.max_lncnt = mode->vactive.typ + 741 mode->vfront_porch.typ + 742 mode->vback_porch.typ + 743 mode->vsync_len.typ - 1; 744 } 745 746 static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv, 747 const struct display_timing *mode) 748 { 749 union meson_hdmi_venc_mode *vmode = NULL; 750 union meson_hdmi_venc_mode vmode_dmt; 751 bool use_enci = false; 752 bool venc_repeat = false; 753 bool hdmi_repeat = false; 754 unsigned int venc_hdmi_latency = 2; 755 unsigned long total_pixels_venc = 0; 756 unsigned long active_pixels_venc = 0; 757 unsigned long front_porch_venc = 0; 758 unsigned long hsync_pixels_venc = 0; 759 unsigned long de_h_begin = 0; 760 unsigned long de_h_end = 0; 761 unsigned long de_v_begin_even = 0; 762 unsigned long de_v_end_even = 0; 763 unsigned long de_v_begin_odd = 0; 764 unsigned long de_v_end_odd = 0; 765 unsigned long hs_begin = 0; 766 unsigned long hs_end = 0; 767 unsigned long vs_adjust = 0; 768 unsigned long vs_bline_evn = 0; 769 unsigned long vs_eline_evn = 0; 770 unsigned long vs_bline_odd = 0; 771 unsigned long vs_eline_odd = 0; 772 unsigned long vso_begin_evn = 0; 773 unsigned long vso_begin_odd = 0; 774 unsigned int eof_lines; 775 unsigned int sof_lines; 776 unsigned int vsync_lines; 777 778 /* Use VENCI for 480i and 576i and double HDMI pixels */ 779 if (mode->flags & DISPLAY_FLAGS_DOUBLECLK) { 780 venc_hdmi_latency = 1; 781 hdmi_repeat = true; 782 use_enci = true; 783 } 784 785 meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); 786 vmode = &vmode_dmt; 787 use_enci = false; 788 789 debug(" max_pxcnt %04d, max_lncnt %04d\n" 790 " havon_begin %04d, havon_end %04d\n" 791 " vavon_bline %04d, vavon_eline %04d\n" 792 " hso_begin %04d, hso_end %04d\n" 793 " vso_begin %04d, vso_end %04d\n" 794 " vso_bline %04d, vso_eline %04d\n", 795 vmode->encp.max_pxcnt, vmode->encp.max_lncnt, 796 vmode->encp.havon_begin, vmode->encp.havon_end, 797 vmode->encp.vavon_bline, vmode->encp.vavon_eline, 798 vmode->encp.hso_begin, vmode->encp.hso_end, 799 vmode->encp.vso_begin, vmode->encp.vso_end, 800 vmode->encp.vso_bline, vmode->encp.vso_eline); 801 802 eof_lines = mode->vfront_porch.typ; 803 if (mode->flags & DISPLAY_FLAGS_INTERLACED) 804 eof_lines /= 2; 805 806 sof_lines = mode->vback_porch.typ; 807 if (mode->flags & DISPLAY_FLAGS_INTERLACED) 808 sof_lines /= 2; 809 810 vsync_lines = mode->vsync_len.typ; 811 if (mode->flags & DISPLAY_FLAGS_INTERLACED) 812 vsync_lines /= 2; 813 814 total_pixels_venc = mode->hback_porch.typ + mode->hactive.typ + 815 mode->hfront_porch.typ + mode->hsync_len.typ; 816 if (hdmi_repeat) 817 total_pixels_venc /= 2; 818 if (venc_repeat) 819 total_pixels_venc *= 2; 820 821 active_pixels_venc = mode->hactive.typ; 822 if (hdmi_repeat) 823 active_pixels_venc /= 2; 824 if (venc_repeat) 825 active_pixels_venc *= 2; 826 827 front_porch_venc = mode->hfront_porch.typ; 828 if (hdmi_repeat) 829 front_porch_venc /= 2; 830 if (venc_repeat) 831 front_porch_venc *= 2; 832 833 hsync_pixels_venc = mode->hsync_len.typ; 834 if (hdmi_repeat) 835 hsync_pixels_venc /= 2; 836 if (venc_repeat) 837 hsync_pixels_venc *= 2; 838 839 /* Disable VDACs */ 840 writel_bits(0xff, 0xff, 841 priv->io_base + _REG(VENC_VDAC_SETTING)); 842 843 writel(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 844 writel(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 845 846 debug("use_enci: %d, hdmi_repeat: %d\n", use_enci, hdmi_repeat); 847 848 if (use_enci) { 849 unsigned int lines_f0; 850 unsigned int lines_f1; 851 852 /* CVBS Filter settings */ 853 writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); 854 writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); 855 856 /* Digital Video Select : Interlace, clk27 clk, external */ 857 writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); 858 859 /* Reset Video Mode */ 860 writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); 861 writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 862 863 /* Horizontal sync signal output */ 864 writel(vmode->enci.hso_begin, 865 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); 866 writel(vmode->enci.hso_end, 867 priv->io_base + _REG(ENCI_SYNC_HSO_END)); 868 869 /* Vertical Sync lines */ 870 writel(vmode->enci.vso_even, 871 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); 872 writel(vmode->enci.vso_odd, 873 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); 874 875 /* Macrovision max amplitude change */ 876 writel(vmode->enci.macv_max_amp, 877 priv->io_base + _REG(ENCI_MACV_MAX_AMP)); 878 879 /* Video mode */ 880 writel(vmode->enci.video_prog_mode, 881 priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 882 writel(vmode->enci.video_mode, 883 priv->io_base + _REG(ENCI_VIDEO_MODE)); 884 885 /* Advanced Video Mode : 886 * Demux shifting 0x2 887 * Blank line end at line17/22 888 * High bandwidth Luma Filter 889 * Low bandwidth Chroma Filter 890 * Bypass luma low pass filter 891 * No macrovision on CSYNC 892 */ 893 writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 894 895 writel(vmode->enci.sch_adjust, 896 priv->io_base + _REG(ENCI_VIDEO_SCH)); 897 898 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ 899 writel(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); 900 901 if (vmode->enci.yc_delay) 902 writel(vmode->enci.yc_delay, 903 priv->io_base + _REG(ENCI_YC_DELAY)); 904 905 /* UNreset Interlaced TV Encoder */ 906 writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); 907 908 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ 909 writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); 910 911 /* Timings */ 912 writel(vmode->enci.pixel_start, 913 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); 914 writel(vmode->enci.pixel_end, 915 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); 916 917 writel(vmode->enci.top_field_line_start, 918 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 919 writel(vmode->enci.top_field_line_end, 920 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); 921 922 writel(vmode->enci.bottom_field_line_start, 923 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 924 writel(vmode->enci.bottom_field_line_end, 925 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); 926 927 /* Select ENCI for VIU */ 928 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); 929 930 /* Interlace video enable */ 931 writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 932 933 lines_f0 = mode->vback_porch.typ + mode->vactive.typ + 934 mode->vback_porch.typ + mode->vsync_len.typ; 935 lines_f0 = lines_f0 >> 1; 936 lines_f1 = lines_f0 + 1; 937 938 de_h_begin = modulo(readl(priv->io_base + 939 _REG(ENCI_VFIFO2VD_PIXEL_START)) 940 + venc_hdmi_latency, 941 total_pixels_venc); 942 de_h_end = modulo(de_h_begin + active_pixels_venc, 943 total_pixels_venc); 944 945 writel(de_h_begin, 946 priv->io_base + _REG(ENCI_DE_H_BEGIN)); 947 writel(de_h_end, 948 priv->io_base + _REG(ENCI_DE_H_END)); 949 950 de_v_begin_even = readl(priv->io_base + 951 _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 952 de_v_end_even = de_v_begin_even + mode->vactive.typ; 953 de_v_begin_odd = readl(priv->io_base + 954 _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 955 de_v_end_odd = de_v_begin_odd + mode->vactive.typ; 956 957 writel(de_v_begin_even, 958 priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN)); 959 writel(de_v_end_even, 960 priv->io_base + _REG(ENCI_DE_V_END_EVEN)); 961 writel(de_v_begin_odd, 962 priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD)); 963 writel(de_v_end_odd, 964 priv->io_base + _REG(ENCI_DE_V_END_ODD)); 965 966 /* Program Hsync timing */ 967 hs_begin = de_h_end + front_porch_venc; 968 if (de_h_end + front_porch_venc >= total_pixels_venc) { 969 hs_begin -= total_pixels_venc; 970 vs_adjust = 1; 971 } else { 972 hs_begin = de_h_end + front_porch_venc; 973 vs_adjust = 0; 974 } 975 976 hs_end = modulo(hs_begin + hsync_pixels_venc, 977 total_pixels_venc); 978 writel(hs_begin, 979 priv->io_base + _REG(ENCI_DVI_HSO_BEGIN)); 980 writel(hs_end, 981 priv->io_base + _REG(ENCI_DVI_HSO_END)); 982 983 /* Program Vsync timing for even field */ 984 if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) { 985 vs_bline_evn = (de_v_end_odd - 1) 986 + eof_lines 987 + vs_adjust 988 - lines_f1; 989 vs_eline_evn = vs_bline_evn + vsync_lines; 990 991 writel(vs_bline_evn, 992 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); 993 994 writel(vs_eline_evn, 995 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN)); 996 997 writel(hs_begin, 998 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN)); 999 writel(hs_begin, 1000 priv->io_base + _REG(ENCI_DVI_VSO_END_EVN)); 1001 } else { 1002 vs_bline_odd = (de_v_end_odd - 1) 1003 + eof_lines 1004 + vs_adjust; 1005 1006 writel(vs_bline_odd, 1007 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); 1008 1009 writel(hs_begin, 1010 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); 1011 1012 if ((vs_bline_odd + vsync_lines) >= lines_f1) { 1013 vs_eline_evn = vs_bline_odd 1014 + vsync_lines 1015 - lines_f1; 1016 1017 writel(vs_eline_evn, priv->io_base 1018 + _REG(ENCI_DVI_VSO_ELINE_EVN)); 1019 1020 writel(hs_begin, priv->io_base 1021 + _REG(ENCI_DVI_VSO_END_EVN)); 1022 } else { 1023 vs_eline_odd = vs_bline_odd 1024 + vsync_lines; 1025 1026 writel(vs_eline_odd, priv->io_base 1027 + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1028 1029 writel(hs_begin, priv->io_base 1030 + _REG(ENCI_DVI_VSO_END_ODD)); 1031 } 1032 } 1033 1034 /* Program Vsync timing for odd field */ 1035 if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) { 1036 vs_bline_odd = (de_v_end_even - 1) 1037 + (eof_lines + 1) 1038 - lines_f0; 1039 vs_eline_odd = vs_bline_odd + vsync_lines; 1040 1041 writel(vs_bline_odd, 1042 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); 1043 1044 writel(vs_eline_odd, 1045 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1046 1047 vso_begin_odd = modulo(hs_begin 1048 + (total_pixels_venc >> 1), 1049 total_pixels_venc); 1050 1051 writel(vso_begin_odd, 1052 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); 1053 writel(vso_begin_odd, 1054 priv->io_base + _REG(ENCI_DVI_VSO_END_ODD)); 1055 } else { 1056 vs_bline_evn = (de_v_end_even - 1) 1057 + (eof_lines + 1); 1058 1059 writel(vs_bline_evn, 1060 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); 1061 1062 vso_begin_evn = modulo(hs_begin 1063 + (total_pixels_venc >> 1), 1064 total_pixels_venc); 1065 1066 writel(vso_begin_evn, priv->io_base 1067 + _REG(ENCI_DVI_VSO_BEGIN_EVN)); 1068 1069 if (vs_bline_evn + vsync_lines >= lines_f0) { 1070 vs_eline_odd = vs_bline_evn 1071 + vsync_lines 1072 - lines_f0; 1073 1074 writel(vs_eline_odd, priv->io_base 1075 + _REG(ENCI_DVI_VSO_ELINE_ODD)); 1076 1077 writel(vso_begin_evn, priv->io_base 1078 + _REG(ENCI_DVI_VSO_END_ODD)); 1079 } else { 1080 vs_eline_evn = vs_bline_evn + vsync_lines; 1081 1082 writel(vs_eline_evn, priv->io_base 1083 + _REG(ENCI_DVI_VSO_ELINE_EVN)); 1084 1085 writel(vso_begin_evn, priv->io_base 1086 + _REG(ENCI_DVI_VSO_END_EVN)); 1087 } 1088 } 1089 } else { 1090 writel(vmode->encp.dvi_settings, 1091 priv->io_base + _REG(VENC_DVI_SETTING)); 1092 writel(vmode->encp.video_mode, 1093 priv->io_base + _REG(ENCP_VIDEO_MODE)); 1094 writel(vmode->encp.video_mode_adv, 1095 priv->io_base + _REG(ENCP_VIDEO_MODE_ADV)); 1096 if (vmode->encp.video_prog_mode_present) 1097 writel(vmode->encp.video_prog_mode, 1098 priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 1099 if (vmode->encp.video_sync_mode_present) 1100 writel(vmode->encp.video_sync_mode, 1101 priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE)); 1102 if (vmode->encp.video_yc_dly_present) 1103 writel(vmode->encp.video_yc_dly, 1104 priv->io_base + _REG(ENCP_VIDEO_YC_DLY)); 1105 if (vmode->encp.video_rgb_ctrl_present) 1106 writel(vmode->encp.video_rgb_ctrl, 1107 priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL)); 1108 if (vmode->encp.video_filt_ctrl_present) 1109 writel(vmode->encp.video_filt_ctrl, 1110 priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL)); 1111 if (vmode->encp.video_ofld_voav_ofst_present) 1112 writel(vmode->encp.video_ofld_voav_ofst, 1113 priv->io_base 1114 + _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); 1115 writel(vmode->encp.yfp1_htime, 1116 priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME)); 1117 writel(vmode->encp.yfp2_htime, 1118 priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME)); 1119 writel(vmode->encp.max_pxcnt, 1120 priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT)); 1121 writel(vmode->encp.hspuls_begin, 1122 priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN)); 1123 writel(vmode->encp.hspuls_end, 1124 priv->io_base + _REG(ENCP_VIDEO_HSPULS_END)); 1125 writel(vmode->encp.hspuls_switch, 1126 priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH)); 1127 writel(vmode->encp.vspuls_begin, 1128 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN)); 1129 writel(vmode->encp.vspuls_end, 1130 priv->io_base + _REG(ENCP_VIDEO_VSPULS_END)); 1131 writel(vmode->encp.vspuls_bline, 1132 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE)); 1133 writel(vmode->encp.vspuls_eline, 1134 priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE)); 1135 if (vmode->encp.eqpuls_begin_present) 1136 writel(vmode->encp.eqpuls_begin, 1137 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN)); 1138 if (vmode->encp.eqpuls_end_present) 1139 writel(vmode->encp.eqpuls_end, 1140 priv->io_base + _REG(ENCP_VIDEO_EQPULS_END)); 1141 if (vmode->encp.eqpuls_bline_present) 1142 writel(vmode->encp.eqpuls_bline, 1143 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE)); 1144 if (vmode->encp.eqpuls_eline_present) 1145 writel(vmode->encp.eqpuls_eline, 1146 priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE)); 1147 writel(vmode->encp.havon_begin, 1148 priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN)); 1149 writel(vmode->encp.havon_end, 1150 priv->io_base + _REG(ENCP_VIDEO_HAVON_END)); 1151 writel(vmode->encp.vavon_bline, 1152 priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE)); 1153 writel(vmode->encp.vavon_eline, 1154 priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE)); 1155 writel(vmode->encp.hso_begin, 1156 priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN)); 1157 writel(vmode->encp.hso_end, 1158 priv->io_base + _REG(ENCP_VIDEO_HSO_END)); 1159 writel(vmode->encp.vso_begin, 1160 priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN)); 1161 writel(vmode->encp.vso_end, 1162 priv->io_base + _REG(ENCP_VIDEO_VSO_END)); 1163 writel(vmode->encp.vso_bline, 1164 priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE)); 1165 if (vmode->encp.vso_eline_present) 1166 writel(vmode->encp.vso_eline, 1167 priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE)); 1168 if (vmode->encp.sy_val_present) 1169 writel(vmode->encp.sy_val, 1170 priv->io_base + _REG(ENCP_VIDEO_SY_VAL)); 1171 if (vmode->encp.sy2_val_present) 1172 writel(vmode->encp.sy2_val, 1173 priv->io_base + _REG(ENCP_VIDEO_SY2_VAL)); 1174 writel(vmode->encp.max_lncnt, 1175 priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT)); 1176 1177 writel(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 1178 1179 /* Set DE signal's polarity is active high */ 1180 writel_bits(BIT(14), BIT(14), 1181 priv->io_base + _REG(ENCP_VIDEO_MODE)); 1182 1183 /* Program DE timing */ 1184 de_h_begin = modulo(readl(priv->io_base + 1185 _REG(ENCP_VIDEO_HAVON_BEGIN)) 1186 + venc_hdmi_latency, 1187 total_pixels_venc); 1188 de_h_end = modulo(de_h_begin + active_pixels_venc, 1189 total_pixels_venc); 1190 1191 writel(de_h_begin, 1192 priv->io_base + _REG(ENCP_DE_H_BEGIN)); 1193 writel(de_h_end, 1194 priv->io_base + _REG(ENCP_DE_H_END)); 1195 1196 /* Program DE timing for even field */ 1197 de_v_begin_even = readl(priv->io_base 1198 + _REG(ENCP_VIDEO_VAVON_BLINE)); 1199 if (mode->flags & DISPLAY_FLAGS_INTERLACED) 1200 de_v_end_even = de_v_begin_even + 1201 (mode->vactive.typ / 2); 1202 else 1203 de_v_end_even = de_v_begin_even + mode->vactive.typ; 1204 1205 writel(de_v_begin_even, 1206 priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN)); 1207 writel(de_v_end_even, 1208 priv->io_base + _REG(ENCP_DE_V_END_EVEN)); 1209 1210 /* Program DE timing for odd field if needed */ 1211 if (mode->flags & DISPLAY_FLAGS_INTERLACED) { 1212 unsigned int ofld_voav_ofst = 1213 readl(priv->io_base + 1214 _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); 1215 de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4) 1216 + de_v_begin_even 1217 + ((mode->vfront_porch.typ + 1218 mode->vactive.typ + 1219 mode->vsync_len.typ - 1) / 2); 1220 de_v_end_odd = de_v_begin_odd + (mode->vactive.typ / 2); 1221 1222 writel(de_v_begin_odd, 1223 priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD)); 1224 writel(de_v_end_odd, 1225 priv->io_base + _REG(ENCP_DE_V_END_ODD)); 1226 } 1227 1228 /* Program Hsync timing */ 1229 if ((de_h_end + front_porch_venc) >= total_pixels_venc) { 1230 hs_begin = de_h_end 1231 + front_porch_venc 1232 - total_pixels_venc; 1233 vs_adjust = 1; 1234 } else { 1235 hs_begin = de_h_end 1236 + front_porch_venc; 1237 vs_adjust = 0; 1238 } 1239 1240 hs_end = modulo(hs_begin + hsync_pixels_venc, 1241 total_pixels_venc); 1242 1243 writel(hs_begin, 1244 priv->io_base + _REG(ENCP_DVI_HSO_BEGIN)); 1245 writel(hs_end, 1246 priv->io_base + _REG(ENCP_DVI_HSO_END)); 1247 1248 /* Program Vsync timing for even field */ 1249 if (de_v_begin_even >= 1250 (sof_lines + vsync_lines + (1 - vs_adjust))) 1251 vs_bline_evn = de_v_begin_even 1252 - sof_lines 1253 - vsync_lines 1254 - (1 - vs_adjust); 1255 else 1256 vs_bline_evn = (mode->vfront_porch.typ + 1257 mode->vactive.typ + 1258 mode->vsync_len.typ) + 1259 + de_v_begin_even 1260 - sof_lines 1261 - vsync_lines 1262 - (1 - vs_adjust); 1263 1264 vs_eline_evn = modulo(vs_bline_evn + vsync_lines, 1265 mode->hfront_porch.typ + 1266 mode->hactive.typ + 1267 mode->hsync_len.typ); 1268 1269 writel(vs_bline_evn, 1270 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN)); 1271 writel(vs_eline_evn, 1272 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN)); 1273 1274 vso_begin_evn = hs_begin; 1275 writel(vso_begin_evn, 1276 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN)); 1277 writel(vso_begin_evn, 1278 priv->io_base + _REG(ENCP_DVI_VSO_END_EVN)); 1279 1280 /* Program Vsync timing for odd field if needed */ 1281 if (mode->flags & DISPLAY_FLAGS_INTERLACED) { 1282 vs_bline_odd = (de_v_begin_odd - 1) 1283 - sof_lines 1284 - vsync_lines; 1285 vs_eline_odd = (de_v_begin_odd - 1) 1286 - vsync_lines; 1287 vso_begin_odd = modulo(hs_begin 1288 + (total_pixels_venc >> 1), 1289 total_pixels_venc); 1290 1291 writel(vs_bline_odd, 1292 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD)); 1293 writel(vs_eline_odd, 1294 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD)); 1295 writel(vso_begin_odd, 1296 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD)); 1297 writel(vso_begin_odd, 1298 priv->io_base + _REG(ENCP_DVI_VSO_END_ODD)); 1299 } 1300 1301 /* Select ENCP for VIU */ 1302 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP); 1303 } 1304 1305 writel((use_enci ? 1 : 2) | 1306 (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH ? 1 << 2 : 0) | 1307 (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH ? 1 << 3 : 0) | 1308 4 << 5 | 1309 (venc_repeat ? 1 << 8 : 0) | 1310 (hdmi_repeat ? 1 << 12 : 0), 1311 priv->io_base + _REG(VPU_HDMI_SETTING)); 1312 } 1313 1314 static void meson_venci_cvbs_mode_set(struct meson_vpu_priv *priv, 1315 struct meson_cvbs_enci_mode *mode) 1316 { 1317 /* CVBS Filter settings */ 1318 writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); 1319 writel(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); 1320 1321 /* Digital Video Select : Interlace, clk27 clk, external */ 1322 writel(0, priv->io_base + _REG(VENC_DVI_SETTING)); 1323 1324 /* Reset Video Mode */ 1325 writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); 1326 writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 1327 1328 /* Horizontal sync signal output */ 1329 writel(mode->hso_begin, 1330 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); 1331 writel(mode->hso_end, 1332 priv->io_base + _REG(ENCI_SYNC_HSO_END)); 1333 1334 /* Vertical Sync lines */ 1335 writel(mode->vso_even, 1336 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); 1337 writel(mode->vso_odd, 1338 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); 1339 1340 /* Macrovision max amplitude change */ 1341 writel(0x8100 + mode->macv_max_amp, 1342 priv->io_base + _REG(ENCI_MACV_MAX_AMP)); 1343 1344 /* Video mode */ 1345 writel(mode->video_prog_mode, 1346 priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); 1347 writel(mode->video_mode, 1348 priv->io_base + _REG(ENCI_VIDEO_MODE)); 1349 1350 /* Advanced Video Mode : 1351 * Demux shifting 0x2 1352 * Blank line end at line17/22 1353 * High bandwidth Luma Filter 1354 * Low bandwidth Chroma Filter 1355 * Bypass luma low pass filter 1356 * No macrovision on CSYNC 1357 */ 1358 writel(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); 1359 1360 writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH)); 1361 1362 /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ 1363 writel(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); 1364 1365 /* 0x3 Y, C, and Component Y delay */ 1366 writel(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY)); 1367 1368 /* Timings */ 1369 writel(mode->pixel_start, 1370 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); 1371 writel(mode->pixel_end, 1372 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); 1373 1374 writel(mode->top_field_line_start, 1375 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); 1376 writel(mode->top_field_line_end, 1377 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); 1378 1379 writel(mode->bottom_field_line_start, 1380 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); 1381 writel(mode->bottom_field_line_end, 1382 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); 1383 1384 /* Internal Venc, Internal VIU Sync, Internal Vencoder */ 1385 writel(0, priv->io_base + _REG(VENC_SYNC_ROUTE)); 1386 1387 /* UNreset Interlaced TV Encoder */ 1388 writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); 1389 1390 /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ 1391 writel(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); 1392 1393 /* Power UP Dacs */ 1394 writel(0, priv->io_base + _REG(VENC_VDAC_SETTING)); 1395 1396 /* Video Upsampling */ 1397 writel(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0)); 1398 writel(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1)); 1399 writel(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2)); 1400 1401 /* Select Interlace Y DACs */ 1402 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); 1403 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL1)); 1404 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL2)); 1405 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL3)); 1406 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL4)); 1407 writel(0, priv->io_base + _REG(VENC_VDAC_DACSEL5)); 1408 1409 /* Select ENCI for VIU */ 1410 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); 1411 1412 /* Enable ENCI FIFO */ 1413 writel(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL)); 1414 1415 /* Select ENCI DACs 0, 1, 4, and 5 */ 1416 writel(0x11, priv->io_base + _REG(ENCI_DACSEL_0)); 1417 writel(0x11, priv->io_base + _REG(ENCI_DACSEL_1)); 1418 1419 /* Interlace video enable */ 1420 writel(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 1421 1422 /* Configure Video Saturation / Contrast / Brightness / Hue */ 1423 writel(mode->video_saturation, 1424 priv->io_base + _REG(ENCI_VIDEO_SAT)); 1425 writel(mode->video_contrast, 1426 priv->io_base + _REG(ENCI_VIDEO_CONT)); 1427 writel(mode->video_brightness, 1428 priv->io_base + _REG(ENCI_VIDEO_BRIGHT)); 1429 writel(mode->video_hue, 1430 priv->io_base + _REG(ENCI_VIDEO_HUE)); 1431 1432 /* Enable DAC0 Filter */ 1433 writel(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0)); 1434 writel(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1)); 1435 1436 /* 0 in Macrovision register 0 */ 1437 writel(0, priv->io_base + _REG(ENCI_MACV_N0)); 1438 1439 /* Analog Synchronization and color burst value adjust */ 1440 writel(mode->analog_sync_adj, 1441 priv->io_base + _REG(ENCI_SYNC_ADJ)); 1442 1443 /* enable VDAC */ 1444 writel_bits(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); 1445 1446 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) 1447 hhi_write(HHI_VDAC_CNTL0, 1); 1448 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) || 1449 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) 1450 hhi_write(HHI_VDAC_CNTL0, 0xf0001); 1451 1452 hhi_write(HHI_VDAC_CNTL1, 0); 1453 } 1454 1455 void meson_vpu_setup_venc(struct udevice *dev, 1456 const struct display_timing *mode, bool is_cvbs) 1457 { 1458 struct meson_vpu_priv *priv = dev_get_priv(dev); 1459 1460 if (is_cvbs) 1461 return meson_venci_cvbs_mode_set(priv, &meson_cvbs_enci_pal); 1462 1463 meson_venc_hdmi_mode_set(priv, mode); 1464 } 1465