39
39
#include "i915_drv.h"
40
40
#include "gvt.h"
41
41
#include "i915_pvinfo.h"
42
+ #include "display/intel_display_types.h"
42
43
43
44
/* XXX FIXME i915 has changed PP_XXX definition */
44
45
#define PCH_PP_STATUS _MMIO(0xc7200)
@@ -443,6 +444,254 @@ static int dpy_reg_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
443
444
return 0 ;
444
445
}
445
446
447
+ /*
448
+ * Only PIPE_A is enabled in current vGPU display and PIPE_A is tied to
449
+ * TRANSCODER_A in HW. DDI/PORT could be PORT_x depends on
450
+ * setup_virtual_dp_monitor().
451
+ * emulate_monitor_status_change() set up PLL for PORT_x as the initial enabled
452
+ * DPLL. Later guest driver may setup a different DPLLx when setting mode.
453
+ * So the correct sequence to find DP stream clock is:
454
+ * Check TRANS_DDI_FUNC_CTL on TRANSCODER_A to get PORT_x.
455
+ * Check correct PLLx for PORT_x to get PLL frequency and DP bitrate.
456
+ * Then Refresh rate then can be calculated based on follow equations:
457
+ * Pixel clock = h_total * v_total * refresh_rate
458
+ * stream clock = Pixel clock
459
+ * ls_clk = DP bitrate
460
+ * Link M/N = strm_clk / ls_clk
461
+ */
462
+
463
+ static u32 bdw_vgpu_get_dp_bitrate (struct intel_vgpu * vgpu , enum port port )
464
+ {
465
+ u32 dp_br = 0 ;
466
+ u32 ddi_pll_sel = vgpu_vreg_t (vgpu , PORT_CLK_SEL (port ));
467
+
468
+ switch (ddi_pll_sel ) {
469
+ case PORT_CLK_SEL_LCPLL_2700 :
470
+ dp_br = 270000 * 2 ;
471
+ break ;
472
+ case PORT_CLK_SEL_LCPLL_1350 :
473
+ dp_br = 135000 * 2 ;
474
+ break ;
475
+ case PORT_CLK_SEL_LCPLL_810 :
476
+ dp_br = 81000 * 2 ;
477
+ break ;
478
+ case PORT_CLK_SEL_SPLL :
479
+ {
480
+ switch (vgpu_vreg_t (vgpu , SPLL_CTL ) & SPLL_FREQ_MASK ) {
481
+ case SPLL_FREQ_810MHz :
482
+ dp_br = 81000 * 2 ;
483
+ break ;
484
+ case SPLL_FREQ_1350MHz :
485
+ dp_br = 135000 * 2 ;
486
+ break ;
487
+ case SPLL_FREQ_2700MHz :
488
+ dp_br = 270000 * 2 ;
489
+ break ;
490
+ default :
491
+ gvt_dbg_dpy ("vgpu-%d PORT_%c can't get freq from SPLL 0x%08x\n" ,
492
+ vgpu -> id , port_name (port ), vgpu_vreg_t (vgpu , SPLL_CTL ));
493
+ break ;
494
+ }
495
+ break ;
496
+ }
497
+ case PORT_CLK_SEL_WRPLL1 :
498
+ case PORT_CLK_SEL_WRPLL2 :
499
+ {
500
+ u32 wrpll_ctl ;
501
+ int refclk , n , p , r ;
502
+
503
+ if (ddi_pll_sel == PORT_CLK_SEL_WRPLL1 )
504
+ wrpll_ctl = vgpu_vreg_t (vgpu , WRPLL_CTL (DPLL_ID_WRPLL1 ));
505
+ else
506
+ wrpll_ctl = vgpu_vreg_t (vgpu , WRPLL_CTL (DPLL_ID_WRPLL2 ));
507
+
508
+ switch (wrpll_ctl & WRPLL_REF_MASK ) {
509
+ case WRPLL_REF_PCH_SSC :
510
+ refclk = vgpu -> gvt -> gt -> i915 -> dpll .ref_clks .ssc ;
511
+ break ;
512
+ case WRPLL_REF_LCPLL :
513
+ refclk = 2700000 ;
514
+ break ;
515
+ default :
516
+ gvt_dbg_dpy ("vgpu-%d PORT_%c WRPLL can't get refclk 0x%08x\n" ,
517
+ vgpu -> id , port_name (port ), wrpll_ctl );
518
+ goto out ;
519
+ }
520
+
521
+ r = wrpll_ctl & WRPLL_DIVIDER_REF_MASK ;
522
+ p = (wrpll_ctl & WRPLL_DIVIDER_POST_MASK ) >> WRPLL_DIVIDER_POST_SHIFT ;
523
+ n = (wrpll_ctl & WRPLL_DIVIDER_FB_MASK ) >> WRPLL_DIVIDER_FB_SHIFT ;
524
+
525
+ dp_br = (refclk * n / 10 ) / (p * r ) * 2 ;
526
+ break ;
527
+ }
528
+ default :
529
+ gvt_dbg_dpy ("vgpu-%d PORT_%c has invalid clock select 0x%08x\n" ,
530
+ vgpu -> id , port_name (port ), vgpu_vreg_t (vgpu , PORT_CLK_SEL (port )));
531
+ break ;
532
+ }
533
+
534
+ out :
535
+ return dp_br ;
536
+ }
537
+
538
+ static u32 bxt_vgpu_get_dp_bitrate (struct intel_vgpu * vgpu , enum port port )
539
+ {
540
+ u32 dp_br = 0 ;
541
+ int refclk = vgpu -> gvt -> gt -> i915 -> dpll .ref_clks .nssc ;
542
+ enum dpio_phy phy = DPIO_PHY0 ;
543
+ enum dpio_channel ch = DPIO_CH0 ;
544
+ struct dpll clock = {0 };
545
+ u32 temp ;
546
+
547
+ /* Port to PHY mapping is fixed, see bxt_ddi_phy_info{} */
548
+ switch (port ) {
549
+ case PORT_A :
550
+ phy = DPIO_PHY1 ;
551
+ ch = DPIO_CH0 ;
552
+ break ;
553
+ case PORT_B :
554
+ phy = DPIO_PHY0 ;
555
+ ch = DPIO_CH0 ;
556
+ break ;
557
+ case PORT_C :
558
+ phy = DPIO_PHY0 ;
559
+ ch = DPIO_CH1 ;
560
+ break ;
561
+ default :
562
+ gvt_dbg_dpy ("vgpu-%d no PHY for PORT_%c\n" , vgpu -> id , port_name (port ));
563
+ goto out ;
564
+ }
565
+
566
+ temp = vgpu_vreg_t (vgpu , BXT_PORT_PLL_ENABLE (port ));
567
+ if (!(temp & PORT_PLL_ENABLE ) || !(temp & PORT_PLL_LOCK )) {
568
+ gvt_dbg_dpy ("vgpu-%d PORT_%c PLL_ENABLE 0x%08x isn't enabled or locked\n" ,
569
+ vgpu -> id , port_name (port ), temp );
570
+ goto out ;
571
+ }
572
+
573
+ clock .m1 = 2 ;
574
+ clock .m2 = (vgpu_vreg_t (vgpu , BXT_PORT_PLL (phy , ch , 0 )) & PORT_PLL_M2_MASK ) << 22 ;
575
+ if (vgpu_vreg_t (vgpu , BXT_PORT_PLL (phy , ch , 3 )) & PORT_PLL_M2_FRAC_ENABLE )
576
+ clock .m2 |= vgpu_vreg_t (vgpu , BXT_PORT_PLL (phy , ch , 2 )) & PORT_PLL_M2_FRAC_MASK ;
577
+ clock .n = (vgpu_vreg_t (vgpu , BXT_PORT_PLL (phy , ch , 1 )) & PORT_PLL_N_MASK ) >> PORT_PLL_N_SHIFT ;
578
+ clock .p1 = (vgpu_vreg_t (vgpu , BXT_PORT_PLL_EBB_0 (phy , ch )) & PORT_PLL_P1_MASK ) >> PORT_PLL_P1_SHIFT ;
579
+ clock .p2 = (vgpu_vreg_t (vgpu , BXT_PORT_PLL_EBB_0 (phy , ch )) & PORT_PLL_P2_MASK ) >> PORT_PLL_P2_SHIFT ;
580
+ clock .m = clock .m1 * clock .m2 ;
581
+ clock .p = clock .p1 * clock .p2 ;
582
+
583
+ if (clock .n == 0 || clock .p == 0 ) {
584
+ gvt_dbg_dpy ("vgpu-%d PORT_%c PLL has invalid divider\n" , vgpu -> id , port_name (port ));
585
+ goto out ;
586
+ }
587
+
588
+ clock .vco = DIV_ROUND_CLOSEST_ULL (mul_u32_u32 (refclk , clock .m ), clock .n << 22 );
589
+ clock .dot = DIV_ROUND_CLOSEST (clock .vco , clock .p );
590
+
591
+ dp_br = clock .dot / 5 ;
592
+
593
+ out :
594
+ return dp_br ;
595
+ }
596
+
597
+ static u32 skl_vgpu_get_dp_bitrate (struct intel_vgpu * vgpu , enum port port )
598
+ {
599
+ u32 dp_br = 0 ;
600
+ enum intel_dpll_id dpll_id = DPLL_ID_SKL_DPLL0 ;
601
+
602
+ /* Find the enabled DPLL for the DDI/PORT */
603
+ if (!(vgpu_vreg_t (vgpu , DPLL_CTRL2 ) & DPLL_CTRL2_DDI_CLK_OFF (port )) &&
604
+ (vgpu_vreg_t (vgpu , DPLL_CTRL2 ) & DPLL_CTRL2_DDI_SEL_OVERRIDE (port ))) {
605
+ dpll_id += (vgpu_vreg_t (vgpu , DPLL_CTRL2 ) &
606
+ DPLL_CTRL2_DDI_CLK_SEL_MASK (port )) >>
607
+ DPLL_CTRL2_DDI_CLK_SEL_SHIFT (port );
608
+ } else {
609
+ gvt_dbg_dpy ("vgpu-%d DPLL for PORT_%c isn't turned on\n" ,
610
+ vgpu -> id , port_name (port ));
611
+ return dp_br ;
612
+ }
613
+
614
+ /* Find PLL output frequency from correct DPLL, and get bir rate */
615
+ switch ((vgpu_vreg_t (vgpu , DPLL_CTRL1 ) &
616
+ DPLL_CTRL1_LINK_RATE_MASK (dpll_id )) >>
617
+ DPLL_CTRL1_LINK_RATE_SHIFT (dpll_id )) {
618
+ case DPLL_CTRL1_LINK_RATE_810 :
619
+ dp_br = 81000 * 2 ;
620
+ break ;
621
+ case DPLL_CTRL1_LINK_RATE_1080 :
622
+ dp_br = 108000 * 2 ;
623
+ break ;
624
+ case DPLL_CTRL1_LINK_RATE_1350 :
625
+ dp_br = 135000 * 2 ;
626
+ break ;
627
+ case DPLL_CTRL1_LINK_RATE_1620 :
628
+ dp_br = 162000 * 2 ;
629
+ break ;
630
+ case DPLL_CTRL1_LINK_RATE_2160 :
631
+ dp_br = 216000 * 2 ;
632
+ break ;
633
+ case DPLL_CTRL1_LINK_RATE_2700 :
634
+ dp_br = 270000 * 2 ;
635
+ break ;
636
+ default :
637
+ dp_br = 0 ;
638
+ gvt_dbg_dpy ("vgpu-%d PORT_%c fail to get DPLL-%d freq\n" ,
639
+ vgpu -> id , port_name (port ), dpll_id );
640
+ }
641
+
642
+ return dp_br ;
643
+ }
644
+
645
+ static void vgpu_update_refresh_rate (struct intel_vgpu * vgpu )
646
+ {
647
+ struct drm_i915_private * dev_priv = vgpu -> gvt -> gt -> i915 ;
648
+ enum port port ;
649
+ u32 dp_br , link_m , link_n , htotal , vtotal ;
650
+
651
+ /* Find DDI/PORT assigned to TRANSCODER_A, expect B or D */
652
+ port = (vgpu_vreg_t (vgpu , TRANS_DDI_FUNC_CTL (TRANSCODER_A )) &
653
+ TRANS_DDI_PORT_MASK ) >> TRANS_DDI_PORT_SHIFT ;
654
+ if (port != PORT_B && port != PORT_D ) {
655
+ gvt_dbg_dpy ("vgpu-%d unsupported PORT_%c\n" , vgpu -> id , port_name (port ));
656
+ return ;
657
+ }
658
+
659
+ /* Calculate DP bitrate from PLL */
660
+ if (IS_BROADWELL (dev_priv ))
661
+ dp_br = bdw_vgpu_get_dp_bitrate (vgpu , port );
662
+ else if (IS_BROXTON (dev_priv ))
663
+ dp_br = bxt_vgpu_get_dp_bitrate (vgpu , port );
664
+ else
665
+ dp_br = skl_vgpu_get_dp_bitrate (vgpu , port );
666
+
667
+ /* Get DP link symbol clock M/N */
668
+ link_m = vgpu_vreg_t (vgpu , PIPE_LINK_M1 (TRANSCODER_A ));
669
+ link_n = vgpu_vreg_t (vgpu , PIPE_LINK_N1 (TRANSCODER_A ));
670
+
671
+ /* Get H/V total from transcoder timing */
672
+ htotal = (vgpu_vreg_t (vgpu , HTOTAL (TRANSCODER_A )) >> TRANS_HTOTAL_SHIFT ) + 1 ;
673
+ vtotal = (vgpu_vreg_t (vgpu , VTOTAL (TRANSCODER_A )) >> TRANS_VTOTAL_SHIFT ) + 1 ;
674
+
675
+ if (dp_br && link_n && htotal && vtotal ) {
676
+ u64 pixel_clk = 0 ;
677
+ u32 new_rate = 0 ;
678
+ u32 * old_rate = & (intel_vgpu_port (vgpu , vgpu -> display .port_num )-> vrefresh_k );
679
+
680
+ /* Calcuate pixel clock by (ls_clk * M / N) */
681
+ pixel_clk = div_u64 (mul_u32_u32 (link_m , dp_br ), link_n );
682
+ pixel_clk *= MSEC_PER_SEC ;
683
+
684
+ /* Calcuate refresh rate by (pixel_clk / (h_total * v_total)) */
685
+ new_rate = DIV64_U64_ROUND_CLOSEST (pixel_clk , div64_u64 (mul_u32_u32 (htotal , vtotal ), MSEC_PER_SEC ));
686
+
687
+ if (* old_rate != new_rate )
688
+ * old_rate = new_rate ;
689
+
690
+ gvt_dbg_dpy ("vgpu-%d PIPE_%c refresh rate updated to %d\n" ,
691
+ vgpu -> id , pipe_name (PIPE_A ), new_rate );
692
+ }
693
+ }
694
+
446
695
static int pipeconf_mmio_write (struct intel_vgpu * vgpu , unsigned int offset ,
447
696
void * p_data , unsigned int bytes )
448
697
{
@@ -451,10 +700,13 @@ static int pipeconf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
451
700
write_vreg (vgpu , offset , p_data , bytes );
452
701
data = vgpu_vreg (vgpu , offset );
453
702
454
- if (data & PIPECONF_ENABLE )
703
+ if (data & PIPECONF_ENABLE ) {
455
704
vgpu_vreg (vgpu , offset ) |= I965_PIPECONF_ACTIVE ;
456
- else
705
+ vgpu_update_refresh_rate (vgpu );
706
+
707
+ } else {
457
708
vgpu_vreg (vgpu , offset ) &= ~I965_PIPECONF_ACTIVE ;
709
+ }
458
710
/* vgpu_lock already hold by emulate mmio r/w */
459
711
mutex_unlock (& vgpu -> vgpu_lock );
460
712
intel_gvt_check_vblank_emulation (vgpu -> gvt );
0 commit comments