@@ -2020,13 +2020,12 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
2020
2020
return NULL ;
2021
2021
}
2022
2022
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 )
2025
2025
{
2026
2026
struct intel_display * display = to_intel_display (encoder );
2027
- struct intel_cx0pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll ;
2028
2027
2029
- if (intel_crtc_has_dp_encoder ( crtc_state ) ) {
2028
+ if (is_dp ) {
2030
2029
if (intel_panel_use_ssc (display )) {
2031
2030
struct intel_dp * intel_dp = enc_to_intel_dp (encoder );
2032
2031
pll_state -> ssc_enabled =
@@ -2035,11 +2034,10 @@ static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
2035
2034
}
2036
2035
}
2037
2036
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 )
2040
2039
{
2041
2040
struct intel_display * display = to_intel_display (encoder );
2042
- struct intel_cx0pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll ;
2043
2041
int i ;
2044
2042
2045
2043
if (pll_state -> ssc_enabled )
@@ -2050,38 +2048,53 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
2050
2048
pll_state -> c10 .pll [i ] = 0 ;
2051
2049
}
2052
2050
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
+
2053
2072
static int intel_c10pll_calc_state (struct intel_crtc_state * crtc_state ,
2054
2073
struct intel_encoder * encoder )
2055
2074
{
2056
2075
const struct intel_c10pll_state * const * tables ;
2057
- int i ;
2076
+ int err ;
2058
2077
2059
2078
tables = intel_c10pll_tables_get (crtc_state , encoder );
2060
2079
if (!tables )
2061
2080
return - EINVAL ;
2062
2081
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 );
2069
2086
2070
- return 0 ;
2071
- }
2072
- }
2087
+ if (err == 0 || !intel_crtc_has_type (crtc_state , INTEL_OUTPUT_HDMI ))
2088
+ return err ;
2073
2089
2074
2090
/* 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;
2083
2096
2084
- return - EINVAL ;
2097
+ return 0 ;
2085
2098
}
2086
2099
2087
2100
static 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,
2111
2124
}
2112
2125
2113
2126
static 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 )
2116
2129
{
2117
- const struct intel_c10pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll .c10 ;
2118
2130
int i ;
2119
2131
2120
2132
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,
2333
2345
for (i = 0 ; tables [i ]; i ++ ) {
2334
2346
if (crtc_state -> port_clock == tables [i ]-> clock ) {
2335
2347
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 ));
2337
2351
crtc_state -> dpll_hw_state .cx0pll .use_c10 = false;
2338
2352
return 0 ;
2339
2353
}
@@ -2599,19 +2613,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp)
2599
2613
}
2600
2614
2601
2615
static 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 )
2604
2619
{
2605
- const struct intel_c20pll_state * pll_state = & crtc_state -> dpll_hw_state .cx0pll .c20 ;
2606
- bool dp = false;
2607
2620
u8 owned_lane_mask = intel_cx0_get_owned_lane_mask (encoder );
2608
- u32 clock = crtc_state -> port_clock ;
2609
2621
bool cntx ;
2610
2622
int i ;
2611
2623
2612
- if (intel_crtc_has_dp_encoder (crtc_state ))
2613
- dp = true;
2614
-
2615
2624
/* 1. Read current context selection */
2616
2625
cntx = intel_cx0_read (encoder , INTEL_CX0_LANE0 , PHY_C20_VDR_CUSTOM_SERDES_RATE ) & BIT (0 );
2617
2626
@@ -2679,23 +2688,23 @@ static void intel_c20_pll_program(struct intel_display *display,
2679
2688
/* 4. Program custom width to match the link protocol */
2680
2689
intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_WIDTH ,
2681
2690
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 )),
2683
2692
MB_WRITE_COMMITTED );
2684
2693
2685
2694
/* 5. For DP or 6. For HDMI */
2686
- if (dp ) {
2695
+ if (is_dp ) {
2687
2696
intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_SERDES_RATE ,
2688
2697
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 )),
2690
2699
MB_WRITE_COMMITTED );
2691
2700
} else {
2692
2701
intel_cx0_rmw (encoder , owned_lane_mask , PHY_C20_VDR_CUSTOM_SERDES_RATE ,
2693
2702
BIT (7 ) | PHY_C20_CUSTOM_SERDES_MASK ,
2694
- is_hdmi_frl (clock ) ? BIT (7 ) : 0 ,
2703
+ is_hdmi_frl (port_clock ) ? BIT (7 ) : 0 ,
2695
2704
MB_WRITE_COMMITTED );
2696
2705
2697
2706
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 ),
2699
2708
MB_WRITE_COMMITTED );
2700
2709
}
2701
2710
@@ -2735,7 +2744,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
2735
2744
}
2736
2745
2737
2746
static 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 ,
2739
2749
bool lane_reversal )
2740
2750
{
2741
2751
struct intel_display * display = to_intel_display (encoder );
@@ -2750,18 +2760,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
2750
2760
2751
2761
val |= XELPDP_FORWARD_CLOCK_UNGATE ;
2752
2762
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 ))
2755
2764
val |= XELPDP_DDI_CLOCK_SELECT (XELPDP_DDI_CLOCK_SELECT_DIV18CLK );
2756
2765
else
2757
2766
val |= XELPDP_DDI_CLOCK_SELECT (XELPDP_DDI_CLOCK_SELECT_MAXPCLK );
2758
2767
2759
2768
/* TODO: HDMI FRL */
2760
2769
/* 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 ;
2763
2772
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 ;
2765
2774
2766
2775
intel_de_rmw (display , XELPDP_PORT_CLOCK_CTL (display , encoder -> port ),
2767
2776
XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
@@ -2991,8 +3000,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
2991
3000
return val ;
2992
3001
}
2993
3002
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 )
2996
3006
{
2997
3007
struct intel_display * display = to_intel_display (encoder );
2998
3008
enum phy phy = intel_encoder_to_phy (encoder );
@@ -3006,7 +3016,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
3006
3016
* 1. Program PORT_CLOCK_CTL REGISTER to configure
3007
3017
* clock muxes, gating and SSC
3008
3018
*/
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 );
3010
3020
3011
3021
/* 2. Bring PHY out of reset. */
3012
3022
intel_cx0_phy_lane_reset (encoder , lane_reversal );
@@ -3026,15 +3036,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
3026
3036
3027
3037
/* 5. Program PHY internal PLL internal registers. */
3028
3038
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 );
3030
3040
else
3031
- intel_c20_pll_program (display , crtc_state , encoder );
3041
+ intel_c20_pll_program (display , encoder , & pll_state -> c20 , is_dp , port_clock );
3032
3042
3033
3043
/*
3034
3044
* 6. Program the enabled and disabled owned PHY lane
3035
3045
* transmitters over message bus
3036
3046
*/
3037
- intel_cx0_program_phy_lane (encoder , crtc_state -> lane_count , lane_reversal );
3047
+ intel_cx0_program_phy_lane (encoder , lane_count , lane_reversal );
3038
3048
3039
3049
/*
3040
3050
* 7. Follow the Display Voltage Frequency Switching - Sequence
@@ -3045,8 +3055,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
3045
3055
* 8. Program DDI_CLK_VALFREQ to match intended DDI
3046
3056
* clock frequency.
3047
3057
*/
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 );
3050
3059
3051
3060
/*
3052
3061
* 9. Set PORT_CLOCK_CTL register PCLK PLL Request
@@ -3073,6 +3082,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
3073
3082
intel_cx0_phy_transaction_end (encoder , wakeref );
3074
3083
}
3075
3084
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
+
3076
3093
int intel_mtl_tbt_calc_port_clock (struct intel_encoder * encoder )
3077
3094
{
3078
3095
struct intel_display * display = to_intel_display (encoder );
0 commit comments