@@ -2020,13 +2020,12 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
20202020 return NULL ;
20212021}
20222022
2023- static void intel_cx0pll_update_ssc (struct intel_crtc_state * crtc_state ,
2024- struct intel_encoder * encoder )
2023+ static void intel_cx0pll_update_ssc (struct intel_encoder * encoder ,
2024+ struct intel_cx0pll_state * pll_state , bool is_dp )
20252025{
20262026 struct intel_display * display = to_intel_display (encoder );
2027- struct intel_cx0pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll ;
20282027
2029- if (intel_crtc_has_dp_encoder ( crtc_state ) ) {
2028+ if (is_dp ) {
20302029 if (intel_panel_use_ssc (display )) {
20312030 struct intel_dp * intel_dp = enc_to_intel_dp (encoder );
20322031 pll_state -> ssc_enabled =
@@ -2035,11 +2034,10 @@ static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
20352034 }
20362035}
20372036
2038- static void intel_c10pll_update_pll (struct intel_crtc_state * crtc_state ,
2039- struct intel_encoder * encoder )
2037+ static void intel_c10pll_update_pll (struct intel_encoder * encoder ,
2038+ struct intel_cx0pll_state * pll_state )
20402039{
20412040 struct intel_display * display = to_intel_display (encoder );
2042- struct intel_cx0pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll ;
20432041 int i ;
20442042
20452043 if (pll_state -> ssc_enabled )
@@ -2050,38 +2048,53 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
20502048 pll_state -> c10 .pll [i ] = 0 ;
20512049}
20522050
2051+ static int intel_c10pll_calc_state_from_table (struct intel_encoder * encoder ,
2052+ const struct intel_c10pll_state * const * tables ,
2053+ bool is_dp , int port_clock ,
2054+ struct intel_cx0pll_state * pll_state )
2055+ {
2056+ int i ;
2057+
2058+ for (i = 0 ; tables [i ]; i ++ ) {
2059+ if (port_clock == tables [i ]-> clock ) {
2060+ pll_state -> c10 = * tables [i ];
2061+ intel_cx0pll_update_ssc (encoder , pll_state , is_dp );
2062+ intel_c10pll_update_pll (encoder , pll_state );
2063+ pll_state -> use_c10 = true;
2064+
2065+ return 0 ;
2066+ }
2067+ }
2068+
2069+ return - EINVAL ;
2070+ }
2071+
20532072static int intel_c10pll_calc_state (struct intel_crtc_state * crtc_state ,
20542073 struct intel_encoder * encoder )
20552074{
20562075 const struct intel_c10pll_state * const * tables ;
2057- int i ;
2076+ int err ;
20582077
20592078 tables = intel_c10pll_tables_get (crtc_state , encoder );
20602079 if (!tables )
20612080 return - EINVAL ;
20622081
2063- for (i = 0 ; tables [i ]; i ++ ) {
2064- if (crtc_state -> port_clock == tables [i ]-> clock ) {
2065- crtc_state -> dpll_hw_state .cx0pll .c10 = * tables [i ];
2066- intel_cx0pll_update_ssc (crtc_state , encoder );
2067- intel_c10pll_update_pll (crtc_state , encoder );
2068- crtc_state -> dpll_hw_state .cx0pll .use_c10 = true;
2082+ err = intel_c10pll_calc_state_from_table (encoder , tables ,
2083+ intel_crtc_has_dp_encoder (crtc_state ),
2084+ crtc_state -> port_clock ,
2085+ & crtc_state -> dpll_hw_state .cx0pll );
20692086
2070- return 0 ;
2071- }
2072- }
2087+ if (err == 0 || !intel_crtc_has_type (crtc_state , INTEL_OUTPUT_HDMI ))
2088+ return err ;
20732089
20742090 /* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */
2075- if (intel_crtc_has_type (crtc_state , INTEL_OUTPUT_HDMI )) {
2076- intel_snps_hdmi_pll_compute_c10pll (& crtc_state -> dpll_hw_state .cx0pll .c10 ,
2077- crtc_state -> port_clock );
2078- intel_c10pll_update_pll (crtc_state , encoder );
2079- crtc_state -> dpll_hw_state .cx0pll .use_c10 = true;
2080-
2081- return 0 ;
2082- }
2091+ intel_snps_hdmi_pll_compute_c10pll (& crtc_state -> dpll_hw_state .cx0pll .c10 ,
2092+ crtc_state -> port_clock );
2093+ intel_c10pll_update_pll (encoder ,
2094+ & crtc_state -> dpll_hw_state .cx0pll );
2095+ crtc_state -> dpll_hw_state .cx0pll .use_c10 = true;
20832096
2084- return - EINVAL ;
2097+ return 0 ;
20852098}
20862099
20872100static void intel_c10pll_readout_hw_state (struct intel_encoder * encoder ,
@@ -2111,10 +2124,9 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
21112124}
21122125
21132126static void intel_c10_pll_program (struct intel_display * display ,
2114- const struct intel_crtc_state * crtc_state ,
2115- struct intel_encoder * encoder )
2127+ struct intel_encoder * encoder ,
2128+ const struct intel_c10pll_state * pll_state )
21162129{
2117- const struct intel_c10pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll .c10 ;
21182130 int i ;
21192131
21202132 intel_cx0_rmw (encoder , INTEL_CX0_BOTH_LANES , PHY_C10_VDR_CONTROL (1 ),
@@ -2333,7 +2345,9 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
23332345 for (i = 0 ; tables [i ]; i ++ ) {
23342346 if (crtc_state -> port_clock == tables [i ]-> clock ) {
23352347 crtc_state -> dpll_hw_state .cx0pll .c20 = * tables [i ];
2336- intel_cx0pll_update_ssc (crtc_state , encoder );
2348+ intel_cx0pll_update_ssc (encoder ,
2349+ & crtc_state -> dpll_hw_state .cx0pll ,
2350+ intel_crtc_has_dp_encoder (crtc_state ));
23372351 crtc_state -> dpll_hw_state .cx0pll .use_c10 = false;
23382352 return 0 ;
23392353 }
@@ -2599,19 +2613,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp)
25992613}
26002614
26012615static void intel_c20_pll_program (struct intel_display * display ,
2602- const struct intel_crtc_state * crtc_state ,
2603- struct intel_encoder * encoder )
2616+ struct intel_encoder * encoder ,
2617+ const struct intel_c20pll_state * pll_state ,
2618+ bool is_dp , int port_clock )
26042619{
2605- const struct intel_c20pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll .c20 ;
2606- bool dp = false;
26072620 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask (encoder );
2608- u32 clock = crtc_state -> port_clock ;
26092621 bool cntx ;
26102622 int i ;
26112623
2612- if (intel_crtc_has_dp_encoder (crtc_state ))
2613- dp = true;
2614-
26152624 /* 1. Read current context selection */
26162625 cntx = intel_cx0_read (encoder , INTEL_CX0_LANE0 , PHY_C20_VDR_CUSTOM_SERDES_RATE ) & BIT (0 );
26172626
@@ -2679,23 +2688,23 @@ static void intel_c20_pll_program(struct intel_display *display,
26792688 /* 4. Program custom width to match the link protocol */
26802689 intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_WIDTH ,
26812690 PHY_C20_CUSTOM_WIDTH_MASK ,
2682- PHY_C20_CUSTOM_WIDTH (intel_get_c20_custom_width (clock , dp )),
2691+ PHY_C20_CUSTOM_WIDTH (intel_get_c20_custom_width (port_clock , is_dp )),
26832692 MB_WRITE_COMMITTED );
26842693
26852694 /* 5. For DP or 6. For HDMI */
2686- if (dp ) {
2695+ if (is_dp ) {
26872696 intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_SERDES_RATE ,
26882697 BIT (6 ) | PHY_C20_CUSTOM_SERDES_MASK ,
2689- BIT (6 ) | PHY_C20_CUSTOM_SERDES (intel_c20_get_dp_rate (clock )),
2698+ BIT (6 ) | PHY_C20_CUSTOM_SERDES (intel_c20_get_dp_rate (port_clock )),
26902699 MB_WRITE_COMMITTED );
26912700 } else {
26922701 intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_SERDES_RATE ,
26932702 BIT (7 ) | PHY_C20_CUSTOM_SERDES_MASK ,
2694- is_hdmi_frl (clock ) ? BIT (7 ) : 0 ,
2703+ is_hdmi_frl (port_clock ) ? BIT (7 ) : 0 ,
26952704 MB_WRITE_COMMITTED );
26962705
26972706 intel_cx0_write (encoder , INTEL_CX0_BOTH_LANES , PHY_C20_VDR_HDMI_RATE ,
2698- intel_c20_get_hdmi_rate (clock ),
2707+ intel_c20_get_hdmi_rate (port_clock ),
26992708 MB_WRITE_COMMITTED );
27002709 }
27012710
@@ -2735,7 +2744,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
27352744}
27362745
27372746static void intel_program_port_clock_ctl (struct intel_encoder * encoder ,
2738- const struct intel_crtc_state * crtc_state ,
2747+ const struct intel_cx0pll_state * pll_state ,
2748+ bool is_dp , int port_clock ,
27392749 bool lane_reversal )
27402750{
27412751 struct intel_display * display = to_intel_display (encoder );
@@ -2750,18 +2760,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
27502760
27512761 val |= XELPDP_FORWARD_CLOCK_UNGATE ;
27522762
2753- if (intel_crtc_has_type (crtc_state , INTEL_OUTPUT_HDMI ) &&
2754- is_hdmi_frl (crtc_state -> port_clock ))
2763+ if (!is_dp && is_hdmi_frl (port_clock ))
27552764 val |= XELPDP_DDI_CLOCK_SELECT (XELPDP_DDI_CLOCK_SELECT_DIV18CLK );
27562765 else
27572766 val |= XELPDP_DDI_CLOCK_SELECT (XELPDP_DDI_CLOCK_SELECT_MAXPCLK );
27582767
27592768 /* TODO: HDMI FRL */
27602769 /* DP2.0 10G and 20G rates enable MPLLA*/
2761- if (crtc_state -> port_clock == 1000000 || crtc_state -> port_clock == 2000000 )
2762- val |= crtc_state -> dpll_hw_state . cx0pll . ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0 ;
2770+ if (port_clock == 1000000 || port_clock == 2000000 )
2771+ val |= pll_state -> ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0 ;
27632772 else
2764- val |= crtc_state -> dpll_hw_state . cx0pll . ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0 ;
2773+ val |= pll_state -> ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0 ;
27652774
27662775 intel_de_rmw (display , XELPDP_PORT_CLOCK_CTL (display , encoder -> port ),
27672776 XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
@@ -2991,8 +3000,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
29913000 return val ;
29923001}
29933002
2994- static void intel_cx0pll_enable (struct intel_encoder * encoder ,
2995- const struct intel_crtc_state * crtc_state )
3003+ static void __intel_cx0pll_enable (struct intel_encoder * encoder ,
3004+ const struct intel_cx0pll_state * pll_state ,
3005+ bool is_dp , int port_clock , int lane_count )
29963006{
29973007 struct intel_display * display = to_intel_display (encoder );
29983008 enum phy phy = intel_encoder_to_phy (encoder );
@@ -3006,7 +3016,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30063016 * 1. Program PORT_CLOCK_CTL REGISTER to configure
30073017 * clock muxes, gating and SSC
30083018 */
3009- intel_program_port_clock_ctl (encoder , crtc_state , lane_reversal );
3019+ intel_program_port_clock_ctl (encoder , pll_state , is_dp , port_clock , lane_reversal );
30103020
30113021 /* 2. Bring PHY out of reset. */
30123022 intel_cx0_phy_lane_reset (encoder , lane_reversal );
@@ -3026,15 +3036,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30263036
30273037 /* 5. Program PHY internal PLL internal registers. */
30283038 if (intel_encoder_is_c10phy (encoder ))
3029- intel_c10_pll_program (display , crtc_state , encoder );
3039+ intel_c10_pll_program (display , encoder , & pll_state -> c10 );
30303040 else
3031- intel_c20_pll_program (display , crtc_state , encoder );
3041+ intel_c20_pll_program (display , encoder , & pll_state -> c20 , is_dp , port_clock );
30323042
30333043 /*
30343044 * 6. Program the enabled and disabled owned PHY lane
30353045 * transmitters over message bus
30363046 */
3037- intel_cx0_program_phy_lane (encoder , crtc_state -> lane_count , lane_reversal );
3047+ intel_cx0_program_phy_lane (encoder , lane_count , lane_reversal );
30383048
30393049 /*
30403050 * 7. Follow the Display Voltage Frequency Switching - Sequence
@@ -3045,8 +3055,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30453055 * 8. Program DDI_CLK_VALFREQ to match intended DDI
30463056 * clock frequency.
30473057 */
3048- intel_de_write (display , DDI_CLK_VALFREQ (encoder -> port ),
3049- crtc_state -> port_clock );
3058+ intel_de_write (display , DDI_CLK_VALFREQ (encoder -> port ), port_clock );
30503059
30513060 /*
30523061 * 9. Set PORT_CLOCK_CTL register PCLK PLL Request
@@ -3073,6 +3082,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30733082 intel_cx0_phy_transaction_end (encoder , wakeref );
30743083}
30753084
3085+ static void intel_cx0pll_enable (struct intel_encoder * encoder ,
3086+ const struct intel_crtc_state * crtc_state )
3087+ {
3088+ __intel_cx0pll_enable (encoder , & crtc_state -> dpll_hw_state .cx0pll ,
3089+ intel_crtc_has_dp_encoder (crtc_state ),
3090+ crtc_state -> port_clock , crtc_state -> lane_count );
3091+ }
3092+
30763093int intel_mtl_tbt_calc_port_clock (struct intel_encoder * encoder )
30773094{
30783095 struct intel_display * display = to_intel_display (encoder );
0 commit comments