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