0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/export.h>
0009
0010 #include <drm/drm_modes.h>
0011
0012 #include "meson_drv.h"
0013 #include "meson_registers.h"
0014 #include "meson_venc.h"
0015 #include "meson_vpp.h"
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 #define HHI_GCLK_MPEG2 0x148
0063 #define HHI_VDAC_CNTL0 0x2F4
0064 #define HHI_VDAC_CNTL0_G12A 0x2EC
0065 #define HHI_VDAC_CNTL1 0x2F8
0066 #define HHI_VDAC_CNTL1_G12A 0x2F0
0067 #define HHI_HDMI_PHY_CNTL0 0x3a0
0068
0069 struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
0070 .mode_tag = MESON_VENC_MODE_CVBS_PAL,
0071 .hso_begin = 3,
0072 .hso_end = 129,
0073 .vso_even = 3,
0074 .vso_odd = 260,
0075 .macv_max_amp = 7,
0076 .video_prog_mode = 0xff,
0077 .video_mode = 0x13,
0078 .sch_adjust = 0x28,
0079 .yc_delay = 0x343,
0080 .pixel_start = 251,
0081 .pixel_end = 1691,
0082 .top_field_line_start = 22,
0083 .top_field_line_end = 310,
0084 .bottom_field_line_start = 23,
0085 .bottom_field_line_end = 311,
0086 .video_saturation = 9,
0087 .video_contrast = 0,
0088 .video_brightness = 0,
0089 .video_hue = 0,
0090 .analog_sync_adj = 0x8080,
0091 };
0092
0093 struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
0094 .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
0095 .hso_begin = 5,
0096 .hso_end = 129,
0097 .vso_even = 3,
0098 .vso_odd = 260,
0099 .macv_max_amp = 0xb,
0100 .video_prog_mode = 0xf0,
0101 .video_mode = 0x8,
0102 .sch_adjust = 0x20,
0103 .yc_delay = 0x333,
0104 .pixel_start = 227,
0105 .pixel_end = 1667,
0106 .top_field_line_start = 18,
0107 .top_field_line_end = 258,
0108 .bottom_field_line_start = 19,
0109 .bottom_field_line_end = 259,
0110 .video_saturation = 18,
0111 .video_contrast = 3,
0112 .video_brightness = 0,
0113 .video_hue = 0,
0114 .analog_sync_adj = 0x9c00,
0115 };
0116
0117 union meson_hdmi_venc_mode {
0118 struct {
0119 unsigned int mode_tag;
0120 unsigned int hso_begin;
0121 unsigned int hso_end;
0122 unsigned int vso_even;
0123 unsigned int vso_odd;
0124 unsigned int macv_max_amp;
0125 unsigned int video_prog_mode;
0126 unsigned int video_mode;
0127 unsigned int sch_adjust;
0128 unsigned int yc_delay;
0129 unsigned int pixel_start;
0130 unsigned int pixel_end;
0131 unsigned int top_field_line_start;
0132 unsigned int top_field_line_end;
0133 unsigned int bottom_field_line_start;
0134 unsigned int bottom_field_line_end;
0135 } enci;
0136 struct {
0137 unsigned int dvi_settings;
0138 unsigned int video_mode;
0139 unsigned int video_mode_adv;
0140 unsigned int video_prog_mode;
0141 bool video_prog_mode_present;
0142 unsigned int video_sync_mode;
0143 bool video_sync_mode_present;
0144 unsigned int video_yc_dly;
0145 bool video_yc_dly_present;
0146 unsigned int video_rgb_ctrl;
0147 bool video_rgb_ctrl_present;
0148 unsigned int video_filt_ctrl;
0149 bool video_filt_ctrl_present;
0150 unsigned int video_ofld_voav_ofst;
0151 bool video_ofld_voav_ofst_present;
0152 unsigned int yfp1_htime;
0153 unsigned int yfp2_htime;
0154 unsigned int max_pxcnt;
0155 unsigned int hspuls_begin;
0156 unsigned int hspuls_end;
0157 unsigned int hspuls_switch;
0158 unsigned int vspuls_begin;
0159 unsigned int vspuls_end;
0160 unsigned int vspuls_bline;
0161 unsigned int vspuls_eline;
0162 unsigned int eqpuls_begin;
0163 bool eqpuls_begin_present;
0164 unsigned int eqpuls_end;
0165 bool eqpuls_end_present;
0166 unsigned int eqpuls_bline;
0167 bool eqpuls_bline_present;
0168 unsigned int eqpuls_eline;
0169 bool eqpuls_eline_present;
0170 unsigned int havon_begin;
0171 unsigned int havon_end;
0172 unsigned int vavon_bline;
0173 unsigned int vavon_eline;
0174 unsigned int hso_begin;
0175 unsigned int hso_end;
0176 unsigned int vso_begin;
0177 unsigned int vso_end;
0178 unsigned int vso_bline;
0179 unsigned int vso_eline;
0180 bool vso_eline_present;
0181 unsigned int sy_val;
0182 bool sy_val_present;
0183 unsigned int sy2_val;
0184 bool sy2_val_present;
0185 unsigned int max_lncnt;
0186 } encp;
0187 };
0188
0189 union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
0190 .enci = {
0191 .hso_begin = 5,
0192 .hso_end = 129,
0193 .vso_even = 3,
0194 .vso_odd = 260,
0195 .macv_max_amp = 0xb,
0196 .video_prog_mode = 0xf0,
0197 .video_mode = 0x8,
0198 .sch_adjust = 0x20,
0199 .yc_delay = 0,
0200 .pixel_start = 227,
0201 .pixel_end = 1667,
0202 .top_field_line_start = 18,
0203 .top_field_line_end = 258,
0204 .bottom_field_line_start = 19,
0205 .bottom_field_line_end = 259,
0206 },
0207 };
0208
0209 union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
0210 .enci = {
0211 .hso_begin = 3,
0212 .hso_end = 129,
0213 .vso_even = 3,
0214 .vso_odd = 260,
0215 .macv_max_amp = 0x7,
0216 .video_prog_mode = 0xff,
0217 .video_mode = 0x13,
0218 .sch_adjust = 0x28,
0219 .yc_delay = 0x333,
0220 .pixel_start = 251,
0221 .pixel_end = 1691,
0222 .top_field_line_start = 22,
0223 .top_field_line_end = 310,
0224 .bottom_field_line_start = 23,
0225 .bottom_field_line_end = 311,
0226 },
0227 };
0228
0229 union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
0230 .encp = {
0231 .dvi_settings = 0x21,
0232 .video_mode = 0x4000,
0233 .video_mode_adv = 0x9,
0234 .video_prog_mode = 0,
0235 .video_prog_mode_present = true,
0236 .video_sync_mode = 7,
0237 .video_sync_mode_present = true,
0238
0239
0240 .video_filt_ctrl = 0x2052,
0241 .video_filt_ctrl_present = true,
0242
0243 .yfp1_htime = 244,
0244 .yfp2_htime = 1630,
0245 .max_pxcnt = 1715,
0246 .hspuls_begin = 0x22,
0247 .hspuls_end = 0xa0,
0248 .hspuls_switch = 88,
0249 .vspuls_begin = 0,
0250 .vspuls_end = 1589,
0251 .vspuls_bline = 0,
0252 .vspuls_eline = 5,
0253 .havon_begin = 249,
0254 .havon_end = 1689,
0255 .vavon_bline = 42,
0256 .vavon_eline = 521,
0257
0258
0259
0260
0261 .hso_begin = 3,
0262 .hso_end = 5,
0263 .vso_begin = 3,
0264 .vso_end = 5,
0265 .vso_bline = 0,
0266
0267 .sy_val = 8,
0268 .sy_val_present = true,
0269 .sy2_val = 0x1d8,
0270 .sy2_val_present = true,
0271 .max_lncnt = 524,
0272 },
0273 };
0274
0275 union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
0276 .encp = {
0277 .dvi_settings = 0x21,
0278 .video_mode = 0x4000,
0279 .video_mode_adv = 0x9,
0280 .video_prog_mode = 0,
0281 .video_prog_mode_present = true,
0282 .video_sync_mode = 7,
0283 .video_sync_mode_present = true,
0284
0285
0286 .video_filt_ctrl = 0x52,
0287 .video_filt_ctrl_present = true,
0288
0289 .yfp1_htime = 235,
0290 .yfp2_htime = 1674,
0291 .max_pxcnt = 1727,
0292 .hspuls_begin = 0,
0293 .hspuls_end = 0x80,
0294 .hspuls_switch = 88,
0295 .vspuls_begin = 0,
0296 .vspuls_end = 1599,
0297 .vspuls_bline = 0,
0298 .vspuls_eline = 4,
0299 .havon_begin = 235,
0300 .havon_end = 1674,
0301 .vavon_bline = 44,
0302 .vavon_eline = 619,
0303
0304
0305
0306
0307 .hso_begin = 0x80,
0308 .hso_end = 0,
0309 .vso_begin = 0,
0310 .vso_end = 5,
0311 .vso_bline = 0,
0312
0313 .sy_val = 8,
0314 .sy_val_present = true,
0315 .sy2_val = 0x1d8,
0316 .sy2_val_present = true,
0317 .max_lncnt = 624,
0318 },
0319 };
0320
0321 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
0322 .encp = {
0323 .dvi_settings = 0x2029,
0324 .video_mode = 0x4040,
0325 .video_mode_adv = 0x19,
0326
0327
0328
0329
0330
0331
0332 .yfp1_htime = 648,
0333 .yfp2_htime = 3207,
0334 .max_pxcnt = 3299,
0335 .hspuls_begin = 80,
0336 .hspuls_end = 240,
0337 .hspuls_switch = 80,
0338 .vspuls_begin = 688,
0339 .vspuls_end = 3248,
0340 .vspuls_bline = 4,
0341 .vspuls_eline = 8,
0342 .havon_begin = 648,
0343 .havon_end = 3207,
0344 .vavon_bline = 29,
0345 .vavon_eline = 748,
0346
0347
0348
0349
0350 .hso_begin = 256,
0351 .hso_end = 168,
0352 .vso_begin = 168,
0353 .vso_end = 256,
0354 .vso_bline = 0,
0355 .vso_eline = 5,
0356 .vso_eline_present = true,
0357
0358
0359 .max_lncnt = 749,
0360 },
0361 };
0362
0363 union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
0364 .encp = {
0365 .dvi_settings = 0x202d,
0366 .video_mode = 0x4040,
0367 .video_mode_adv = 0x19,
0368 .video_prog_mode = 0x100,
0369 .video_prog_mode_present = true,
0370 .video_sync_mode = 0x407,
0371 .video_sync_mode_present = true,
0372 .video_yc_dly = 0,
0373 .video_yc_dly_present = true,
0374
0375
0376
0377 .yfp1_htime = 648,
0378 .yfp2_htime = 3207,
0379 .max_pxcnt = 3959,
0380 .hspuls_begin = 80,
0381 .hspuls_end = 240,
0382 .hspuls_switch = 80,
0383 .vspuls_begin = 688,
0384 .vspuls_end = 3248,
0385 .vspuls_bline = 4,
0386 .vspuls_eline = 8,
0387 .havon_begin = 648,
0388 .havon_end = 3207,
0389 .vavon_bline = 29,
0390 .vavon_eline = 748,
0391
0392
0393
0394
0395 .hso_begin = 128,
0396 .hso_end = 208,
0397 .vso_begin = 128,
0398 .vso_end = 128,
0399 .vso_bline = 0,
0400 .vso_eline = 5,
0401 .vso_eline_present = true,
0402
0403
0404 .max_lncnt = 749,
0405 },
0406 };
0407
0408 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
0409 .encp = {
0410 .dvi_settings = 0x2029,
0411 .video_mode = 0x5ffc,
0412 .video_mode_adv = 0x19,
0413 .video_prog_mode = 0x100,
0414 .video_prog_mode_present = true,
0415 .video_sync_mode = 0x207,
0416 .video_sync_mode_present = true,
0417
0418
0419
0420 .video_ofld_voav_ofst = 0x11,
0421 .video_ofld_voav_ofst_present = true,
0422 .yfp1_htime = 516,
0423 .yfp2_htime = 4355,
0424 .max_pxcnt = 4399,
0425 .hspuls_begin = 88,
0426 .hspuls_end = 264,
0427 .hspuls_switch = 88,
0428 .vspuls_begin = 440,
0429 .vspuls_end = 2200,
0430 .vspuls_bline = 0,
0431 .vspuls_eline = 4,
0432 .havon_begin = 516,
0433 .havon_end = 4355,
0434 .vavon_bline = 20,
0435 .vavon_eline = 559,
0436 .eqpuls_begin = 2288,
0437 .eqpuls_begin_present = true,
0438 .eqpuls_end = 2464,
0439 .eqpuls_end_present = true,
0440 .eqpuls_bline = 0,
0441 .eqpuls_bline_present = true,
0442 .eqpuls_eline = 4,
0443 .eqpuls_eline_present = true,
0444 .hso_begin = 264,
0445 .hso_end = 176,
0446 .vso_begin = 88,
0447 .vso_end = 88,
0448 .vso_bline = 0,
0449 .vso_eline = 5,
0450 .vso_eline_present = true,
0451
0452
0453 .max_lncnt = 1124,
0454 },
0455 };
0456
0457 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
0458 .encp = {
0459 .dvi_settings = 0x202d,
0460 .video_mode = 0x5ffc,
0461 .video_mode_adv = 0x19,
0462 .video_prog_mode = 0x100,
0463 .video_prog_mode_present = true,
0464 .video_sync_mode = 0x7,
0465 .video_sync_mode_present = true,
0466
0467
0468
0469 .video_ofld_voav_ofst = 0x11,
0470 .video_ofld_voav_ofst_present = true,
0471 .yfp1_htime = 526,
0472 .yfp2_htime = 4365,
0473 .max_pxcnt = 5279,
0474 .hspuls_begin = 88,
0475 .hspuls_end = 264,
0476 .hspuls_switch = 88,
0477 .vspuls_begin = 440,
0478 .vspuls_end = 2200,
0479 .vspuls_bline = 0,
0480 .vspuls_eline = 4,
0481 .havon_begin = 526,
0482 .havon_end = 4365,
0483 .vavon_bline = 20,
0484 .vavon_eline = 559,
0485 .eqpuls_begin = 2288,
0486 .eqpuls_begin_present = true,
0487 .eqpuls_end = 2464,
0488 .eqpuls_end_present = true,
0489 .eqpuls_bline = 0,
0490 .eqpuls_bline_present = true,
0491 .eqpuls_eline = 4,
0492 .eqpuls_eline_present = true,
0493 .hso_begin = 142,
0494 .hso_end = 230,
0495 .vso_begin = 142,
0496 .vso_end = 142,
0497 .vso_bline = 0,
0498 .vso_eline = 5,
0499 .vso_eline_present = true,
0500
0501
0502 .max_lncnt = 1124,
0503 },
0504 };
0505
0506 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
0507 .encp = {
0508 .dvi_settings = 0xd,
0509 .video_mode = 0x4040,
0510 .video_mode_adv = 0x18,
0511 .video_prog_mode = 0x100,
0512 .video_prog_mode_present = true,
0513 .video_sync_mode = 0x7,
0514 .video_sync_mode_present = true,
0515 .video_yc_dly = 0,
0516 .video_yc_dly_present = true,
0517 .video_rgb_ctrl = 2,
0518 .video_rgb_ctrl_present = true,
0519 .video_filt_ctrl = 0x1052,
0520 .video_filt_ctrl_present = true,
0521
0522 .yfp1_htime = 271,
0523 .yfp2_htime = 2190,
0524 .max_pxcnt = 2749,
0525 .hspuls_begin = 44,
0526 .hspuls_end = 132,
0527 .hspuls_switch = 44,
0528 .vspuls_begin = 220,
0529 .vspuls_end = 2140,
0530 .vspuls_bline = 0,
0531 .vspuls_eline = 4,
0532 .havon_begin = 271,
0533 .havon_end = 2190,
0534 .vavon_bline = 41,
0535 .vavon_eline = 1120,
0536
0537
0538 .eqpuls_bline = 0,
0539 .eqpuls_bline_present = true,
0540 .eqpuls_eline = 4,
0541 .eqpuls_eline_present = true,
0542 .hso_begin = 79,
0543 .hso_end = 123,
0544 .vso_begin = 79,
0545 .vso_end = 79,
0546 .vso_bline = 0,
0547 .vso_eline = 5,
0548 .vso_eline_present = true,
0549
0550
0551 .max_lncnt = 1124,
0552 },
0553 };
0554
0555 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
0556 .encp = {
0557 .dvi_settings = 0x1,
0558 .video_mode = 0x4040,
0559 .video_mode_adv = 0x18,
0560 .video_prog_mode = 0x100,
0561 .video_prog_mode_present = true,
0562
0563
0564
0565 .video_filt_ctrl = 0x1052,
0566 .video_filt_ctrl_present = true,
0567
0568 .yfp1_htime = 140,
0569 .yfp2_htime = 2060,
0570 .max_pxcnt = 2199,
0571 .hspuls_begin = 2156,
0572 .hspuls_end = 44,
0573 .hspuls_switch = 44,
0574 .vspuls_begin = 140,
0575 .vspuls_end = 2059,
0576 .vspuls_bline = 0,
0577 .vspuls_eline = 4,
0578 .havon_begin = 148,
0579 .havon_end = 2067,
0580 .vavon_bline = 41,
0581 .vavon_eline = 1120,
0582
0583
0584
0585
0586 .hso_begin = 44,
0587 .hso_end = 2156,
0588 .vso_begin = 2100,
0589 .vso_end = 2164,
0590 .vso_bline = 0,
0591 .vso_eline = 5,
0592 .vso_eline_present = true,
0593
0594
0595 .max_lncnt = 1124,
0596 },
0597 };
0598
0599 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
0600 .encp = {
0601 .dvi_settings = 0xd,
0602 .video_mode = 0x4040,
0603 .video_mode_adv = 0x18,
0604 .video_prog_mode = 0x100,
0605 .video_prog_mode_present = true,
0606 .video_sync_mode = 0x7,
0607 .video_sync_mode_present = true,
0608 .video_yc_dly = 0,
0609 .video_yc_dly_present = true,
0610 .video_rgb_ctrl = 2,
0611 .video_rgb_ctrl_present = true,
0612
0613
0614 .yfp1_htime = 271,
0615 .yfp2_htime = 2190,
0616 .max_pxcnt = 2639,
0617 .hspuls_begin = 44,
0618 .hspuls_end = 132,
0619 .hspuls_switch = 44,
0620 .vspuls_begin = 220,
0621 .vspuls_end = 2140,
0622 .vspuls_bline = 0,
0623 .vspuls_eline = 4,
0624 .havon_begin = 271,
0625 .havon_end = 2190,
0626 .vavon_bline = 41,
0627 .vavon_eline = 1120,
0628
0629
0630 .eqpuls_bline = 0,
0631 .eqpuls_bline_present = true,
0632 .eqpuls_eline = 4,
0633 .eqpuls_eline_present = true,
0634 .hso_begin = 79,
0635 .hso_end = 123,
0636 .vso_begin = 79,
0637 .vso_end = 79,
0638 .vso_bline = 0,
0639 .vso_eline = 5,
0640 .vso_eline_present = true,
0641
0642
0643 .max_lncnt = 1124,
0644 },
0645 };
0646
0647 union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
0648 .encp = {
0649 .dvi_settings = 0x1,
0650 .video_mode = 0x4040,
0651 .video_mode_adv = 0x18,
0652 .video_prog_mode = 0x100,
0653 .video_prog_mode_present = true,
0654
0655
0656
0657 .video_filt_ctrl = 0x1052,
0658 .video_filt_ctrl_present = true,
0659
0660 .yfp1_htime = 140,
0661 .yfp2_htime = 2060,
0662 .max_pxcnt = 2199,
0663 .hspuls_begin = 2156,
0664 .hspuls_end = 44,
0665 .hspuls_switch = 44,
0666 .vspuls_begin = 140,
0667 .vspuls_end = 2059,
0668 .vspuls_bline = 0,
0669 .vspuls_eline = 4,
0670 .havon_begin = 148,
0671 .havon_end = 2067,
0672 .vavon_bline = 41,
0673 .vavon_eline = 1120,
0674
0675
0676
0677
0678 .hso_begin = 44,
0679 .hso_end = 2156,
0680 .vso_begin = 2100,
0681 .vso_end = 2164,
0682 .vso_bline = 0,
0683 .vso_eline = 5,
0684 .vso_eline_present = true,
0685
0686
0687 .max_lncnt = 1124,
0688 },
0689 };
0690
0691 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
0692 .encp = {
0693 .dvi_settings = 0x1,
0694 .video_mode = 0x4040,
0695 .video_mode_adv = 0x8,
0696
0697
0698
0699 .video_filt_ctrl = 0x1000,
0700 .video_filt_ctrl_present = true,
0701
0702 .yfp1_htime = 140,
0703 .yfp2_htime = 140+3840,
0704 .max_pxcnt = 3840+1660-1,
0705 .hspuls_begin = 2156+1920,
0706 .hspuls_end = 44,
0707 .hspuls_switch = 44,
0708 .vspuls_begin = 140,
0709 .vspuls_end = 2059+1920,
0710 .vspuls_bline = 0,
0711 .vspuls_eline = 4,
0712 .havon_begin = 148,
0713 .havon_end = 3987,
0714 .vavon_bline = 89,
0715 .vavon_eline = 2248,
0716
0717
0718
0719
0720 .hso_begin = 44,
0721 .hso_end = 2156+1920,
0722 .vso_begin = 2100+1920,
0723 .vso_end = 2164+1920,
0724 .vso_bline = 51,
0725 .vso_eline = 53,
0726 .vso_eline_present = true,
0727
0728
0729 .max_lncnt = 2249,
0730 },
0731 };
0732
0733 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
0734 .encp = {
0735 .dvi_settings = 0x1,
0736 .video_mode = 0x4040,
0737 .video_mode_adv = 0x8,
0738
0739
0740
0741 .video_filt_ctrl = 0x1000,
0742 .video_filt_ctrl_present = true,
0743
0744 .yfp1_htime = 140,
0745 .yfp2_htime = 140+3840,
0746 .max_pxcnt = 3840+1440-1,
0747 .hspuls_begin = 2156+1920,
0748 .hspuls_end = 44,
0749 .hspuls_switch = 44,
0750 .vspuls_begin = 140,
0751 .vspuls_end = 2059+1920,
0752 .vspuls_bline = 0,
0753 .vspuls_eline = 4,
0754 .havon_begin = 148,
0755 .havon_end = 3987,
0756 .vavon_bline = 89,
0757 .vavon_eline = 2248,
0758
0759
0760
0761
0762 .hso_begin = 44,
0763 .hso_end = 2156+1920,
0764 .vso_begin = 2100+1920,
0765 .vso_end = 2164+1920,
0766 .vso_bline = 51,
0767 .vso_eline = 53,
0768 .vso_eline_present = true,
0769
0770
0771 .max_lncnt = 2249,
0772 },
0773 };
0774
0775 union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
0776 .encp = {
0777 .dvi_settings = 0x1,
0778 .video_mode = 0x4040,
0779 .video_mode_adv = 0x8,
0780
0781
0782
0783 .video_filt_ctrl = 0x1000,
0784 .video_filt_ctrl_present = true,
0785
0786 .yfp1_htime = 140,
0787 .yfp2_htime = 140+3840,
0788 .max_pxcnt = 3840+560-1,
0789 .hspuls_begin = 2156+1920,
0790 .hspuls_end = 44,
0791 .hspuls_switch = 44,
0792 .vspuls_begin = 140,
0793 .vspuls_end = 2059+1920,
0794 .vspuls_bline = 0,
0795 .vspuls_eline = 4,
0796 .havon_begin = 148,
0797 .havon_end = 3987,
0798 .vavon_bline = 89,
0799 .vavon_eline = 2248,
0800
0801
0802
0803
0804 .hso_begin = 44,
0805 .hso_end = 2156+1920,
0806 .vso_begin = 2100+1920,
0807 .vso_end = 2164+1920,
0808 .vso_bline = 51,
0809 .vso_eline = 53,
0810 .vso_eline_present = true,
0811
0812
0813 .max_lncnt = 2249,
0814 },
0815 };
0816
0817 struct meson_hdmi_venc_vic_mode {
0818 unsigned int vic;
0819 union meson_hdmi_venc_mode *mode;
0820 } meson_hdmi_venc_vic_modes[] = {
0821 { 6, &meson_hdmi_enci_mode_480i },
0822 { 7, &meson_hdmi_enci_mode_480i },
0823 { 21, &meson_hdmi_enci_mode_576i },
0824 { 22, &meson_hdmi_enci_mode_576i },
0825 { 2, &meson_hdmi_encp_mode_480p },
0826 { 3, &meson_hdmi_encp_mode_480p },
0827 { 17, &meson_hdmi_encp_mode_576p },
0828 { 18, &meson_hdmi_encp_mode_576p },
0829 { 4, &meson_hdmi_encp_mode_720p60 },
0830 { 19, &meson_hdmi_encp_mode_720p50 },
0831 { 5, &meson_hdmi_encp_mode_1080i60 },
0832 { 20, &meson_hdmi_encp_mode_1080i50 },
0833 { 32, &meson_hdmi_encp_mode_1080p24 },
0834 { 33, &meson_hdmi_encp_mode_1080p50 },
0835 { 34, &meson_hdmi_encp_mode_1080p30 },
0836 { 31, &meson_hdmi_encp_mode_1080p50 },
0837 { 16, &meson_hdmi_encp_mode_1080p60 },
0838 { 93, &meson_hdmi_encp_mode_2160p24 },
0839 { 94, &meson_hdmi_encp_mode_2160p25 },
0840 { 95, &meson_hdmi_encp_mode_2160p30 },
0841 { 96, &meson_hdmi_encp_mode_2160p25 },
0842 { 97, &meson_hdmi_encp_mode_2160p30 },
0843 { 0, NULL},
0844 };
0845
0846 static signed int to_signed(unsigned int a)
0847 {
0848 if (a <= 7)
0849 return a;
0850 else
0851 return a - 16;
0852 }
0853
0854 static unsigned long modulo(unsigned long a, unsigned long b)
0855 {
0856 if (a >= b)
0857 return a - b;
0858 else
0859 return a;
0860 }
0861
0862 enum drm_mode_status
0863 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
0864 {
0865 if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
0866 DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
0867 return MODE_BAD;
0868
0869 if (mode->hdisplay < 640 || mode->hdisplay > 1920)
0870 return MODE_BAD_HVALUE;
0871
0872 if (mode->vdisplay < 480 || mode->vdisplay > 1200)
0873 return MODE_BAD_VVALUE;
0874
0875 return MODE_OK;
0876 }
0877 EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
0878
0879 bool meson_venc_hdmi_supported_vic(int vic)
0880 {
0881 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
0882
0883 while (vmode->vic && vmode->mode) {
0884 if (vmode->vic == vic)
0885 return true;
0886 vmode++;
0887 }
0888
0889 return false;
0890 }
0891 EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
0892
0893 static void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
0894 union meson_hdmi_venc_mode *dmt_mode)
0895 {
0896 memset(dmt_mode, 0, sizeof(*dmt_mode));
0897
0898 dmt_mode->encp.dvi_settings = 0x21;
0899 dmt_mode->encp.video_mode = 0x4040;
0900 dmt_mode->encp.video_mode_adv = 0x18;
0901 dmt_mode->encp.max_pxcnt = mode->htotal - 1;
0902 dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start;
0903 dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin +
0904 mode->hdisplay - 1;
0905 dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start;
0906 dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline +
0907 mode->vdisplay - 1;
0908 dmt_mode->encp.hso_begin = 0;
0909 dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start;
0910 dmt_mode->encp.vso_begin = 30;
0911 dmt_mode->encp.vso_end = 50;
0912 dmt_mode->encp.vso_bline = 0;
0913 dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start;
0914 dmt_mode->encp.vso_eline_present = true;
0915 dmt_mode->encp.max_lncnt = mode->vtotal - 1;
0916 }
0917
0918 static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
0919 {
0920 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
0921
0922 while (vmode->vic && vmode->mode) {
0923 if (vmode->vic == vic)
0924 return vmode->mode;
0925 vmode++;
0926 }
0927
0928 return NULL;
0929 }
0930
0931 bool meson_venc_hdmi_venc_repeat(int vic)
0932 {
0933
0934 if (vic == 6 || vic == 7 ||
0935 vic == 21 || vic == 22 ||
0936 vic == 17 || vic == 18 ||
0937 vic == 2 || vic == 3 ||
0938 vic == 4 ||
0939 vic == 19 ||
0940 vic == 5 ||
0941 vic == 20)
0942 return true;
0943
0944 return false;
0945 }
0946 EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
0947
0948 void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
0949 unsigned int ycrcb_map,
0950 bool yuv420_mode,
0951 const struct drm_display_mode *mode)
0952 {
0953 union meson_hdmi_venc_mode *vmode = NULL;
0954 union meson_hdmi_venc_mode vmode_dmt;
0955 bool use_enci = false;
0956 bool venc_repeat = false;
0957 bool hdmi_repeat = false;
0958 unsigned int venc_hdmi_latency = 2;
0959 unsigned long total_pixels_venc = 0;
0960 unsigned long active_pixels_venc = 0;
0961 unsigned long front_porch_venc = 0;
0962 unsigned long hsync_pixels_venc = 0;
0963 unsigned long de_h_begin = 0;
0964 unsigned long de_h_end = 0;
0965 unsigned long de_v_begin_even = 0;
0966 unsigned long de_v_end_even = 0;
0967 unsigned long de_v_begin_odd = 0;
0968 unsigned long de_v_end_odd = 0;
0969 unsigned long hs_begin = 0;
0970 unsigned long hs_end = 0;
0971 unsigned long vs_adjust = 0;
0972 unsigned long vs_bline_evn = 0;
0973 unsigned long vs_eline_evn = 0;
0974 unsigned long vs_bline_odd = 0;
0975 unsigned long vs_eline_odd = 0;
0976 unsigned long vso_begin_evn = 0;
0977 unsigned long vso_begin_odd = 0;
0978 unsigned int eof_lines;
0979 unsigned int sof_lines;
0980 unsigned int vsync_lines;
0981 u32 reg;
0982
0983
0984 if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
0985 hdmi_repeat = true;
0986 use_enci = true;
0987 venc_hdmi_latency = 1;
0988 }
0989
0990 if (meson_venc_hdmi_supported_vic(vic)) {
0991 vmode = meson_venc_hdmi_get_vic_vmode(vic);
0992 if (!vmode) {
0993 dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
0994 DRM_MODE_FMT "\n", __func__,
0995 DRM_MODE_ARG(mode));
0996 return;
0997 }
0998 } else {
0999 meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
1000 vmode = &vmode_dmt;
1001 use_enci = false;
1002 }
1003
1004
1005 if (meson_venc_hdmi_venc_repeat(vic))
1006 venc_repeat = true;
1007
1008 eof_lines = mode->vsync_start - mode->vdisplay;
1009 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1010 eof_lines /= 2;
1011 sof_lines = mode->vtotal - mode->vsync_end;
1012 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1013 sof_lines /= 2;
1014 vsync_lines = mode->vsync_end - mode->vsync_start;
1015 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1016 vsync_lines /= 2;
1017
1018 total_pixels_venc = mode->htotal;
1019 if (hdmi_repeat)
1020 total_pixels_venc /= 2;
1021 if (venc_repeat)
1022 total_pixels_venc *= 2;
1023
1024 active_pixels_venc = mode->hdisplay;
1025 if (hdmi_repeat)
1026 active_pixels_venc /= 2;
1027 if (venc_repeat)
1028 active_pixels_venc *= 2;
1029
1030 front_porch_venc = (mode->hsync_start - mode->hdisplay);
1031 if (hdmi_repeat)
1032 front_porch_venc /= 2;
1033 if (venc_repeat)
1034 front_porch_venc *= 2;
1035
1036 hsync_pixels_venc = (mode->hsync_end - mode->hsync_start);
1037 if (hdmi_repeat)
1038 hsync_pixels_venc /= 2;
1039 if (venc_repeat)
1040 hsync_pixels_venc *= 2;
1041
1042
1043 writel_bits_relaxed(0xff, 0xff,
1044 priv->io_base + _REG(VENC_VDAC_SETTING));
1045
1046 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1047 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1048
1049 if (use_enci) {
1050 unsigned int lines_f0;
1051 unsigned int lines_f1;
1052
1053
1054 writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
1055 priv->io_base + _REG(ENCI_CFILT_CTRL));
1056 writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
1057 ENCI_CFILT_CMPT_CB_DLY(1),
1058 priv->io_base + _REG(ENCI_CFILT_CTRL2));
1059
1060
1061 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1062
1063
1064 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1065 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1066
1067
1068 writel_relaxed(vmode->enci.hso_begin,
1069 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1070 writel_relaxed(vmode->enci.hso_end,
1071 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1072
1073
1074 writel_relaxed(vmode->enci.vso_even,
1075 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1076 writel_relaxed(vmode->enci.vso_odd,
1077 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1078
1079
1080 writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
1081 ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp),
1082 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1083
1084
1085 writel_relaxed(vmode->enci.video_prog_mode,
1086 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1087 writel_relaxed(vmode->enci.video_mode,
1088 priv->io_base + _REG(ENCI_VIDEO_MODE));
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
1100 ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
1101 ENCI_VIDEO_MODE_ADV_YBW_HIGH,
1102 priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1103
1104 writel(vmode->enci.sch_adjust,
1105 priv->io_base + _REG(ENCI_VIDEO_SCH));
1106
1107
1108 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1109
1110 if (vmode->enci.yc_delay)
1111 writel_relaxed(vmode->enci.yc_delay,
1112 priv->io_base + _REG(ENCI_YC_DELAY));
1113
1114
1115
1116 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126 writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
1127 ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
1128 priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1129
1130
1131 writel_relaxed(vmode->enci.pixel_start,
1132 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1133 writel_relaxed(vmode->enci.pixel_end,
1134 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1135
1136 writel_relaxed(vmode->enci.top_field_line_start,
1137 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1138 writel_relaxed(vmode->enci.top_field_line_end,
1139 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1140
1141 writel_relaxed(vmode->enci.bottom_field_line_start,
1142 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1143 writel_relaxed(vmode->enci.bottom_field_line_end,
1144 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1145
1146
1147 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1148
1149
1150 writel_relaxed(ENCI_VIDEO_EN_ENABLE,
1151 priv->io_base + _REG(ENCI_VIDEO_EN));
1152
1153 lines_f0 = mode->vtotal >> 1;
1154 lines_f1 = lines_f0 + 1;
1155
1156 de_h_begin = modulo(readl_relaxed(priv->io_base +
1157 _REG(ENCI_VFIFO2VD_PIXEL_START))
1158 + venc_hdmi_latency,
1159 total_pixels_venc);
1160 de_h_end = modulo(de_h_begin + active_pixels_venc,
1161 total_pixels_venc);
1162
1163 writel_relaxed(de_h_begin,
1164 priv->io_base + _REG(ENCI_DE_H_BEGIN));
1165 writel_relaxed(de_h_end,
1166 priv->io_base + _REG(ENCI_DE_H_END));
1167
1168 de_v_begin_even = readl_relaxed(priv->io_base +
1169 _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1170 de_v_end_even = de_v_begin_even + mode->vdisplay;
1171 de_v_begin_odd = readl_relaxed(priv->io_base +
1172 _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1173 de_v_end_odd = de_v_begin_odd + mode->vdisplay;
1174
1175 writel_relaxed(de_v_begin_even,
1176 priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN));
1177 writel_relaxed(de_v_end_even,
1178 priv->io_base + _REG(ENCI_DE_V_END_EVEN));
1179 writel_relaxed(de_v_begin_odd,
1180 priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD));
1181 writel_relaxed(de_v_end_odd,
1182 priv->io_base + _REG(ENCI_DE_V_END_ODD));
1183
1184
1185 hs_begin = de_h_end + front_porch_venc;
1186 if (de_h_end + front_porch_venc >= total_pixels_venc) {
1187 hs_begin -= total_pixels_venc;
1188 vs_adjust = 1;
1189 } else {
1190 hs_begin = de_h_end + front_porch_venc;
1191 vs_adjust = 0;
1192 }
1193
1194 hs_end = modulo(hs_begin + hsync_pixels_venc,
1195 total_pixels_venc);
1196 writel_relaxed(hs_begin,
1197 priv->io_base + _REG(ENCI_DVI_HSO_BEGIN));
1198 writel_relaxed(hs_end,
1199 priv->io_base + _REG(ENCI_DVI_HSO_END));
1200
1201
1202 if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) {
1203 vs_bline_evn = (de_v_end_odd - 1)
1204 + eof_lines
1205 + vs_adjust
1206 - lines_f1;
1207 vs_eline_evn = vs_bline_evn + vsync_lines;
1208
1209 writel_relaxed(vs_bline_evn,
1210 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1211
1212 writel_relaxed(vs_eline_evn,
1213 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN));
1214
1215 writel_relaxed(hs_begin,
1216 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1217 writel_relaxed(hs_begin,
1218 priv->io_base + _REG(ENCI_DVI_VSO_END_EVN));
1219 } else {
1220 vs_bline_odd = (de_v_end_odd - 1)
1221 + eof_lines
1222 + vs_adjust;
1223
1224 writel_relaxed(vs_bline_odd,
1225 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1226
1227 writel_relaxed(hs_begin,
1228 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1229
1230 if ((vs_bline_odd + vsync_lines) >= lines_f1) {
1231 vs_eline_evn = vs_bline_odd
1232 + vsync_lines
1233 - lines_f1;
1234
1235 writel_relaxed(vs_eline_evn, priv->io_base
1236 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1237
1238 writel_relaxed(hs_begin, priv->io_base
1239 + _REG(ENCI_DVI_VSO_END_EVN));
1240 } else {
1241 vs_eline_odd = vs_bline_odd
1242 + vsync_lines;
1243
1244 writel_relaxed(vs_eline_odd, priv->io_base
1245 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1246
1247 writel_relaxed(hs_begin, priv->io_base
1248 + _REG(ENCI_DVI_VSO_END_ODD));
1249 }
1250 }
1251
1252
1253 if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) {
1254 vs_bline_odd = (de_v_end_even - 1)
1255 + (eof_lines + 1)
1256 - lines_f0;
1257 vs_eline_odd = vs_bline_odd + vsync_lines;
1258
1259 writel_relaxed(vs_bline_odd,
1260 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
1261
1262 writel_relaxed(vs_eline_odd,
1263 priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD));
1264
1265 vso_begin_odd = modulo(hs_begin
1266 + (total_pixels_venc >> 1),
1267 total_pixels_venc);
1268
1269 writel_relaxed(vso_begin_odd,
1270 priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
1271 writel_relaxed(vso_begin_odd,
1272 priv->io_base + _REG(ENCI_DVI_VSO_END_ODD));
1273 } else {
1274 vs_bline_evn = (de_v_end_even - 1)
1275 + (eof_lines + 1);
1276
1277 writel_relaxed(vs_bline_evn,
1278 priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
1279
1280 vso_begin_evn = modulo(hs_begin
1281 + (total_pixels_venc >> 1),
1282 total_pixels_venc);
1283
1284 writel_relaxed(vso_begin_evn, priv->io_base
1285 + _REG(ENCI_DVI_VSO_BEGIN_EVN));
1286
1287 if (vs_bline_evn + vsync_lines >= lines_f0) {
1288 vs_eline_odd = vs_bline_evn
1289 + vsync_lines
1290 - lines_f0;
1291
1292 writel_relaxed(vs_eline_odd, priv->io_base
1293 + _REG(ENCI_DVI_VSO_ELINE_ODD));
1294
1295 writel_relaxed(vso_begin_evn, priv->io_base
1296 + _REG(ENCI_DVI_VSO_END_ODD));
1297 } else {
1298 vs_eline_evn = vs_bline_evn + vsync_lines;
1299
1300 writel_relaxed(vs_eline_evn, priv->io_base
1301 + _REG(ENCI_DVI_VSO_ELINE_EVN));
1302
1303 writel_relaxed(vso_begin_evn, priv->io_base
1304 + _REG(ENCI_DVI_VSO_END_EVN));
1305 }
1306 }
1307 } else {
1308 writel_relaxed(vmode->encp.dvi_settings,
1309 priv->io_base + _REG(VENC_DVI_SETTING));
1310 writel_relaxed(vmode->encp.video_mode,
1311 priv->io_base + _REG(ENCP_VIDEO_MODE));
1312 writel_relaxed(vmode->encp.video_mode_adv,
1313 priv->io_base + _REG(ENCP_VIDEO_MODE_ADV));
1314 if (vmode->encp.video_prog_mode_present)
1315 writel_relaxed(vmode->encp.video_prog_mode,
1316 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1317 if (vmode->encp.video_sync_mode_present)
1318 writel_relaxed(vmode->encp.video_sync_mode,
1319 priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE));
1320 if (vmode->encp.video_yc_dly_present)
1321 writel_relaxed(vmode->encp.video_yc_dly,
1322 priv->io_base + _REG(ENCP_VIDEO_YC_DLY));
1323 if (vmode->encp.video_rgb_ctrl_present)
1324 writel_relaxed(vmode->encp.video_rgb_ctrl,
1325 priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL));
1326 if (vmode->encp.video_filt_ctrl_present)
1327 writel_relaxed(vmode->encp.video_filt_ctrl,
1328 priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL));
1329 if (vmode->encp.video_ofld_voav_ofst_present)
1330 writel_relaxed(vmode->encp.video_ofld_voav_ofst,
1331 priv->io_base
1332 + _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1333 writel_relaxed(vmode->encp.yfp1_htime,
1334 priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME));
1335 writel_relaxed(vmode->encp.yfp2_htime,
1336 priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME));
1337 writel_relaxed(vmode->encp.max_pxcnt,
1338 priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT));
1339 writel_relaxed(vmode->encp.hspuls_begin,
1340 priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN));
1341 writel_relaxed(vmode->encp.hspuls_end,
1342 priv->io_base + _REG(ENCP_VIDEO_HSPULS_END));
1343 writel_relaxed(vmode->encp.hspuls_switch,
1344 priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH));
1345 writel_relaxed(vmode->encp.vspuls_begin,
1346 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN));
1347 writel_relaxed(vmode->encp.vspuls_end,
1348 priv->io_base + _REG(ENCP_VIDEO_VSPULS_END));
1349 writel_relaxed(vmode->encp.vspuls_bline,
1350 priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE));
1351 writel_relaxed(vmode->encp.vspuls_eline,
1352 priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE));
1353 if (vmode->encp.eqpuls_begin_present)
1354 writel_relaxed(vmode->encp.eqpuls_begin,
1355 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN));
1356 if (vmode->encp.eqpuls_end_present)
1357 writel_relaxed(vmode->encp.eqpuls_end,
1358 priv->io_base + _REG(ENCP_VIDEO_EQPULS_END));
1359 if (vmode->encp.eqpuls_bline_present)
1360 writel_relaxed(vmode->encp.eqpuls_bline,
1361 priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE));
1362 if (vmode->encp.eqpuls_eline_present)
1363 writel_relaxed(vmode->encp.eqpuls_eline,
1364 priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE));
1365 writel_relaxed(vmode->encp.havon_begin,
1366 priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN));
1367 writel_relaxed(vmode->encp.havon_end,
1368 priv->io_base + _REG(ENCP_VIDEO_HAVON_END));
1369 writel_relaxed(vmode->encp.vavon_bline,
1370 priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE));
1371 writel_relaxed(vmode->encp.vavon_eline,
1372 priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE));
1373 writel_relaxed(vmode->encp.hso_begin,
1374 priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN));
1375 writel_relaxed(vmode->encp.hso_end,
1376 priv->io_base + _REG(ENCP_VIDEO_HSO_END));
1377 writel_relaxed(vmode->encp.vso_begin,
1378 priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN));
1379 writel_relaxed(vmode->encp.vso_end,
1380 priv->io_base + _REG(ENCP_VIDEO_VSO_END));
1381 writel_relaxed(vmode->encp.vso_bline,
1382 priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE));
1383 if (vmode->encp.vso_eline_present)
1384 writel_relaxed(vmode->encp.vso_eline,
1385 priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE));
1386 if (vmode->encp.sy_val_present)
1387 writel_relaxed(vmode->encp.sy_val,
1388 priv->io_base + _REG(ENCP_VIDEO_SY_VAL));
1389 if (vmode->encp.sy2_val_present)
1390 writel_relaxed(vmode->encp.sy2_val,
1391 priv->io_base + _REG(ENCP_VIDEO_SY2_VAL));
1392 writel_relaxed(vmode->encp.max_lncnt,
1393 priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT));
1394
1395 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
1396
1397
1398 writel_bits_relaxed(ENCP_VIDEO_MODE_DE_V_HIGH,
1399 ENCP_VIDEO_MODE_DE_V_HIGH,
1400 priv->io_base + _REG(ENCP_VIDEO_MODE));
1401
1402
1403 de_h_begin = modulo(readl_relaxed(priv->io_base +
1404 _REG(ENCP_VIDEO_HAVON_BEGIN))
1405 + venc_hdmi_latency,
1406 total_pixels_venc);
1407 de_h_end = modulo(de_h_begin + active_pixels_venc,
1408 total_pixels_venc);
1409
1410 writel_relaxed(de_h_begin,
1411 priv->io_base + _REG(ENCP_DE_H_BEGIN));
1412 writel_relaxed(de_h_end,
1413 priv->io_base + _REG(ENCP_DE_H_END));
1414
1415
1416 de_v_begin_even = readl_relaxed(priv->io_base
1417 + _REG(ENCP_VIDEO_VAVON_BLINE));
1418 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1419 de_v_end_even = de_v_begin_even +
1420 (mode->vdisplay / 2);
1421 else
1422 de_v_end_even = de_v_begin_even + mode->vdisplay;
1423
1424 writel_relaxed(de_v_begin_even,
1425 priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN));
1426 writel_relaxed(de_v_end_even,
1427 priv->io_base + _REG(ENCP_DE_V_END_EVEN));
1428
1429
1430 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1431 unsigned int ofld_voav_ofst =
1432 readl_relaxed(priv->io_base +
1433 _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
1434 de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4)
1435 + de_v_begin_even
1436 + ((mode->vtotal - 1) / 2);
1437 de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2);
1438
1439 writel_relaxed(de_v_begin_odd,
1440 priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD));
1441 writel_relaxed(de_v_end_odd,
1442 priv->io_base + _REG(ENCP_DE_V_END_ODD));
1443 }
1444
1445
1446 if ((de_h_end + front_porch_venc) >= total_pixels_venc) {
1447 hs_begin = de_h_end
1448 + front_porch_venc
1449 - total_pixels_venc;
1450 vs_adjust = 1;
1451 } else {
1452 hs_begin = de_h_end
1453 + front_porch_venc;
1454 vs_adjust = 0;
1455 }
1456
1457 hs_end = modulo(hs_begin + hsync_pixels_venc,
1458 total_pixels_venc);
1459
1460 writel_relaxed(hs_begin,
1461 priv->io_base + _REG(ENCP_DVI_HSO_BEGIN));
1462 writel_relaxed(hs_end,
1463 priv->io_base + _REG(ENCP_DVI_HSO_END));
1464
1465
1466 if (de_v_begin_even >=
1467 (sof_lines + vsync_lines + (1 - vs_adjust)))
1468 vs_bline_evn = de_v_begin_even
1469 - sof_lines
1470 - vsync_lines
1471 - (1 - vs_adjust);
1472 else
1473 vs_bline_evn = mode->vtotal
1474 + de_v_begin_even
1475 - sof_lines
1476 - vsync_lines
1477 - (1 - vs_adjust);
1478
1479 vs_eline_evn = modulo(vs_bline_evn + vsync_lines,
1480 mode->vtotal);
1481
1482 writel_relaxed(vs_bline_evn,
1483 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN));
1484 writel_relaxed(vs_eline_evn,
1485 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN));
1486
1487 vso_begin_evn = hs_begin;
1488 writel_relaxed(vso_begin_evn,
1489 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN));
1490 writel_relaxed(vso_begin_evn,
1491 priv->io_base + _REG(ENCP_DVI_VSO_END_EVN));
1492
1493
1494 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1495 vs_bline_odd = (de_v_begin_odd - 1)
1496 - sof_lines
1497 - vsync_lines;
1498 vs_eline_odd = (de_v_begin_odd - 1)
1499 - vsync_lines;
1500 vso_begin_odd = modulo(hs_begin
1501 + (total_pixels_venc >> 1),
1502 total_pixels_venc);
1503
1504 writel_relaxed(vs_bline_odd,
1505 priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD));
1506 writel_relaxed(vs_eline_odd,
1507 priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD));
1508 writel_relaxed(vso_begin_odd,
1509 priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD));
1510 writel_relaxed(vso_begin_odd,
1511 priv->io_base + _REG(ENCP_DVI_VSO_END_ODD));
1512 }
1513
1514
1515 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
1516 }
1517
1518
1519
1520 if (use_enci)
1521 reg = VPU_HDMI_ENCI_DATA_TO_HDMI;
1522 else
1523 reg = VPU_HDMI_ENCP_DATA_TO_HDMI;
1524
1525
1526 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1527 reg |= VPU_HDMI_INV_HSYNC;
1528
1529
1530 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1531 reg |= VPU_HDMI_INV_VSYNC;
1532
1533
1534 reg |= ycrcb_map;
1535
1536
1537
1538
1539
1540 if (venc_repeat || yuv420_mode)
1541 reg |= VPU_HDMI_WR_RATE(2);
1542
1543
1544
1545
1546
1547 if (hdmi_repeat)
1548 reg |= VPU_HDMI_RD_RATE(2);
1549
1550 writel_relaxed(reg, priv->io_base + _REG(VPU_HDMI_SETTING));
1551
1552 priv->venc.hdmi_repeat = hdmi_repeat;
1553 priv->venc.venc_repeat = venc_repeat;
1554 priv->venc.hdmi_use_enci = use_enci;
1555
1556 priv->venc.current_mode = MESON_VENC_MODE_HDMI;
1557 }
1558 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
1559
1560 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
1561 struct meson_cvbs_enci_mode *mode)
1562 {
1563 u32 reg;
1564
1565 if (mode->mode_tag == priv->venc.current_mode)
1566 return;
1567
1568
1569 writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
1570 priv->io_base + _REG(ENCI_CFILT_CTRL));
1571 writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
1572 ENCI_CFILT_CMPT_CB_DLY(1),
1573 priv->io_base + _REG(ENCI_CFILT_CTRL2));
1574
1575
1576 writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
1577
1578
1579 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
1580 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1581
1582
1583 writel_relaxed(mode->hso_begin,
1584 priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
1585 writel_relaxed(mode->hso_end,
1586 priv->io_base + _REG(ENCI_SYNC_HSO_END));
1587
1588
1589 writel_relaxed(mode->vso_even,
1590 priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
1591 writel_relaxed(mode->vso_odd,
1592 priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
1593
1594
1595 writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
1596 ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp),
1597 priv->io_base + _REG(ENCI_MACV_MAX_AMP));
1598
1599
1600 writel_relaxed(mode->video_prog_mode,
1601 priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
1602 writel_relaxed(mode->video_mode,
1603 priv->io_base + _REG(ENCI_VIDEO_MODE));
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614 writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
1615 ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
1616 ENCI_VIDEO_MODE_ADV_YBW_HIGH,
1617 priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
1618
1619 writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
1620
1621
1622 writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
1623
1624
1625 writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
1626
1627
1628 writel_relaxed(mode->pixel_start,
1629 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
1630 writel_relaxed(mode->pixel_end,
1631 priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
1632
1633 writel_relaxed(mode->top_field_line_start,
1634 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
1635 writel_relaxed(mode->top_field_line_end,
1636 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
1637
1638 writel_relaxed(mode->bottom_field_line_start,
1639 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
1640 writel_relaxed(mode->bottom_field_line_end,
1641 priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
1642
1643
1644 writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
1645
1646
1647 writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657 writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
1658 ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
1659 priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
1660
1661
1662 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
1663
1664
1665
1666
1667
1668
1669
1670 reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN |
1671 VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN;
1672
1673
1674
1675
1676
1677 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg,
1678 priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
1679
1680
1681
1682
1683
1684 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg,
1685 priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
1686
1687
1688
1689
1690
1691 writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg,
1692 priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
1693
1694
1695 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
1696 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
1697 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
1698 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
1699 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
1700 writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
1701
1702
1703 meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
1704
1705
1706 writel_relaxed(VENC_VDAC_FIFO_EN_ENCI_ENABLE,
1707 priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
1708
1709
1710 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
1711 writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
1712
1713
1714 writel_relaxed(ENCI_VIDEO_EN_ENABLE,
1715 priv->io_base + _REG(ENCI_VIDEO_EN));
1716
1717
1718 writel_relaxed(mode->video_saturation,
1719 priv->io_base + _REG(ENCI_VIDEO_SAT));
1720 writel_relaxed(mode->video_contrast,
1721 priv->io_base + _REG(ENCI_VIDEO_CONT));
1722 writel_relaxed(mode->video_brightness,
1723 priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
1724 writel_relaxed(mode->video_hue,
1725 priv->io_base + _REG(ENCI_VIDEO_HUE));
1726
1727
1728 writel_relaxed(VENC_VDAC_DAC0_FILT_CTRL0_EN,
1729 priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
1730 writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
1731
1732
1733 writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
1734
1735
1736 writel_relaxed(mode->analog_sync_adj,
1737 priv->io_base + _REG(ENCI_SYNC_ADJ));
1738
1739 priv->venc.current_mode = mode->mode_tag;
1740 }
1741
1742
1743 unsigned int meson_venci_get_field(struct meson_drm *priv)
1744 {
1745 return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
1746 }
1747
1748 void meson_venc_enable_vsync(struct meson_drm *priv)
1749 {
1750 writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
1751 priv->io_base + _REG(VENC_INTCTRL));
1752 regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
1753 }
1754
1755 void meson_venc_disable_vsync(struct meson_drm *priv)
1756 {
1757 regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
1758 writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
1759 }
1760
1761 void meson_venc_init(struct meson_drm *priv)
1762 {
1763
1764 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
1765 regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0);
1766 regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8);
1767 } else {
1768 regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
1769 regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
1770 }
1771
1772
1773 writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
1774
1775
1776 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
1777
1778
1779 writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI |
1780 VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
1781 priv->io_base + _REG(VPU_HDMI_SETTING));
1782
1783
1784 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
1785 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
1786 writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
1787
1788
1789 meson_venc_disable_vsync(priv);
1790
1791 priv->venc.current_mode = MESON_VENC_MODE_NONE;
1792 }