diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dpll_mgr.h')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 300 |
1 files changed, 177 insertions, 123 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 5d9a2bc371e7..6183da90b28d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -27,21 +27,19 @@ #include <linux/types.h> -#include "intel_display.h" +#include "intel_display_power.h" #include "intel_wakeref.h" -/*FIXME: Move this to a more appropriate place. */ -#define abs_diff(a, b) ({ \ - typeof(a) __a = (a); \ - typeof(b) __b = (b); \ - (void) (&__a == &__b); \ - __a > __b ? (__a - __b) : (__b - __a); }) +#define for_each_dpll(__display, __pll, __i) \ + for ((__i) = 0; (__i) < (__display)->dpll.num_dpll && \ + ((__pll) = &(__display)->dpll.dplls[(__i)]) ; (__i)++) -struct drm_device; -struct drm_i915_private; +enum tc_port; +struct drm_printer; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_dpll_funcs; struct intel_encoder; struct intel_shared_dpll; @@ -154,6 +152,23 @@ enum intel_dpll_id { * @DPLL_ID_TGL_MGPLL6: TGL TC PLL port 6 (TC6) */ DPLL_ID_TGL_MGPLL6 = 8, + + /** + * @DPLL_ID_DG1_DPLL0: DG1 combo PHY DPLL0 + */ + DPLL_ID_DG1_DPLL0 = 0, + /** + * @DPLL_ID_DG1_DPLL1: DG1 combo PHY DPLL1 + */ + DPLL_ID_DG1_DPLL1 = 1, + /** + * @DPLL_ID_DG1_DPLL2: DG1 combo PHY DPLL2 + */ + DPLL_ID_DG1_DPLL2 = 2, + /** + * @DPLL_ID_DG1_DPLL3: DG1 combo PHY DPLL3 + */ + DPLL_ID_DG1_DPLL3 = 3, }; #define I915_NUM_PLLS 9 @@ -165,18 +180,19 @@ enum icl_port_dpll_id { ICL_PORT_DPLL_COUNT, }; -struct intel_dpll_hw_state { - /* i9xx, pch plls */ +struct i9xx_dpll_hw_state { u32 dpll; u32 dpll_md; u32 fp0; u32 fp1; +}; - /* hsw, bdw */ +struct hsw_dpll_hw_state { u32 wrpll; u32 spll; +}; - /* skl */ +struct skl_dpll_hw_state { /* * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in * lower part of ctrl1 and they get shifted into position when writing @@ -186,18 +202,18 @@ struct intel_dpll_hw_state { u32 ctrl1; /* HDMI only, 0 when used for DP */ u32 cfgcr1, cfgcr2; +}; - /* cnl */ - u32 cfgcr0; - /* CNL also uses cfgcr1 */ - - /* bxt */ +struct bxt_dpll_hw_state { u32 ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, pcsdw12; +}; + +struct icl_dpll_hw_state { + u32 cfgcr0, cfgcr1; + + /* tgl */ + u32 div0; - /* - * ICL uses the following, already defined: - * u32 cfgcr0, cfgcr1; - */ u32 mg_refclkin_ctl; u32 mg_clktop2_coreclkctl1; u32 mg_clktop2_hsclkctl; @@ -212,8 +228,70 @@ struct intel_dpll_hw_state { u32 mg_pll_tdc_coldst_bias_mask; }; +struct intel_mpllb_state { + u32 clock; /* in KHz */ + u32 ref_control; + u32 mpllb_cp; + u32 mpllb_div; + u32 mpllb_div2; + u32 mpllb_fracn1; + u32 mpllb_fracn2; + u32 mpllb_sscen; + u32 mpllb_sscstep; +}; + +struct intel_c10pll_state { + u32 clock; /* in KHz */ + u8 tx; + u8 cmn; + u8 pll[20]; +}; + +struct intel_c20pll_state { + u32 clock; /* in kHz */ + u16 tx[3]; + u16 cmn[4]; + union { + u16 mplla[10]; + u16 mpllb[11]; + }; +}; + +struct intel_cx0pll_state { + union { + struct intel_c10pll_state c10; + struct intel_c20pll_state c20; + }; + bool ssc_enabled; + bool use_c10; + bool tbt_mode; +}; + +struct intel_lt_phy_pll_state { + u32 clock; /* in kHz */ + u8 addr_msb[13]; + u8 addr_lsb[13]; + u8 data[13][4]; + u8 config[3]; + bool ssc_enabled; + bool tbt_mode; +}; + +struct intel_dpll_hw_state { + union { + struct i9xx_dpll_hw_state i9xx; + struct hsw_dpll_hw_state hsw; + struct skl_dpll_hw_state skl; + struct bxt_dpll_hw_state bxt; + struct icl_dpll_hw_state icl; + struct intel_mpllb_state mpllb; + struct intel_cx0pll_state cx0pll; + struct intel_lt_phy_pll_state ltpll; + }; +}; + /** - * struct intel_shared_dpll_state - hold the DPLL atomic state + * struct intel_dpll_state - hold the DPLL atomic state * * This structure holds an atomic state for the DPLL, that can represent * either its current state (in struct &intel_shared_dpll) or a desired @@ -222,11 +300,11 @@ struct intel_dpll_hw_state { * * See also intel_reserve_shared_dplls() and intel_release_shared_dplls(). */ -struct intel_shared_dpll_state { +struct intel_dpll_state { /** - * @crtc_mask: mask of CRTC using this DPLL, active or not + * @pipe_mask: mask of pipes using this DPLL, active or not */ - unsigned crtc_mask; + u8 pipe_mask; /** * @hw_state: hardware configuration for the DPLL stored in @@ -236,106 +314,67 @@ struct intel_shared_dpll_state { }; /** - * struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs + * struct dpll_info - display PLL platform specific info */ -struct intel_shared_dpll_funcs { +struct dpll_info { /** - * @prepare: - * - * Optional hook to perform operations prior to enabling the PLL. - * Called from intel_prepare_shared_dpll() function unless the PLL - * is already enabled. + * @name: DPLL name; used for logging */ - void (*prepare)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); + const char *name; /** - * @enable: - * - * Hook for enabling the pll, called from intel_enable_shared_dpll() - * if the pll is not already enabled. + * @funcs: platform specific hooks */ - void (*enable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); + const struct intel_dpll_funcs *funcs; /** - * @disable: - * - * Hook for disabling the pll, called from intel_disable_shared_dpll() - * only when it is safe to disable the pll, i.e., there are no more - * tracked users for it. + * @id: unique identifier for this DPLL */ - void (*disable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); + enum intel_dpll_id id; /** - * @get_hw_state: - * - * Hook for reading the values currently programmed to the DPLL - * registers. This is used for initial hw state readout and state - * verification after a mode set. + * @power_domain: extra power domain required by the DPLL */ - bool (*get_hw_state)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state); + enum intel_display_power_domain power_domain; /** - * @get_freq: + * @always_on: * - * Hook for calculating the pll's output frequency based on its - * current state. - */ - int (*get_freq)(struct drm_i915_private *i915, - const struct intel_shared_dpll *pll); -}; - -/** - * struct dpll_info - display PLL platform specific info - */ -struct dpll_info { - /** - * @name: DPLL name; used for logging - */ - const char *name; - - /** - * @funcs: platform specific hooks + * Inform the state checker that the DPLL is kept enabled even if + * not in use by any CRTC. */ - const struct intel_shared_dpll_funcs *funcs; + bool always_on; /** - * @id: unique indentifier for this DPLL; should match the index in the - * dev_priv->shared_dplls array - */ - enum intel_dpll_id id; - -#define INTEL_DPLL_ALWAYS_ON (1 << 0) - /** - * @flags: + * @is_alt_port_dpll: * - * INTEL_DPLL_ALWAYS_ON - * Inform the state checker that the DPLL is kept enabled even if - * not in use by any CRTC. + * Inform the state checker that the DPLL can be used as a fallback + * (for TC->TBT fallback). */ - u32 flags; + bool is_alt_port_dpll; }; /** - * struct intel_shared_dpll - display PLL with tracked state and users + * struct intel_dpll - display PLL with tracked state and users */ -struct intel_shared_dpll { +struct intel_dpll { /** * @state: * * Store the state for the pll, including its hw state * and CRTCs using it. */ - struct intel_shared_dpll_state state; + struct intel_dpll_state state; /** - * @active_mask: mask of active CRTCs (i.e. DPMS on) using this DPLL + * @index: index for atomic state */ - unsigned active_mask; + u8 index; + + /** + * @active_mask: mask of active pipes (i.e. DPMS on) using this DPLL + */ + u8 active_mask; /** * @on: is the PLL actually active? Disabled during modeset @@ -359,41 +398,56 @@ struct intel_shared_dpll { #define SKL_DPLL2 2 #define SKL_DPLL3 3 -/* shared dpll functions */ -struct intel_shared_dpll * -intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, - enum intel_dpll_id id); -enum intel_dpll_id -intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); -void assert_shared_dpll(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - bool state); -#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) -#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) -bool intel_reserve_shared_dplls(struct intel_atomic_state *state, - struct intel_crtc *crtc, - struct intel_encoder *encoder); -void intel_release_shared_dplls(struct intel_atomic_state *state, - struct intel_crtc *crtc); +/* dpll functions */ +struct intel_dpll * +intel_get_dpll_by_id(struct intel_display *display, + enum intel_dpll_id id); +void assert_dpll(struct intel_display *display, + struct intel_dpll *pll, + bool state); +#define assert_dpll_enabled(d, p) assert_dpll(d, p, true) +#define assert_dpll_disabled(d, p) assert_dpll(d, p, false) +int intel_dpll_compute(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_encoder *encoder); +int intel_dpll_reserve(struct intel_atomic_state *state, + struct intel_crtc *crtc, + struct intel_encoder *encoder); +void intel_dpll_release(struct intel_atomic_state *state, + struct intel_crtc *crtc); +void intel_dpll_crtc_put(const struct intel_crtc *crtc, + const struct intel_dpll *pll, + struct intel_dpll_state *shared_dpll_state); void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state, enum icl_port_dpll_id port_dpll_id); -void intel_update_active_dpll(struct intel_atomic_state *state, +void intel_dpll_update_active(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder); -int intel_dpll_get_freq(struct drm_i915_private *i915, - const struct intel_shared_dpll *pll); -void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state); -void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state); -void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state); -void intel_shared_dpll_swap_state(struct intel_atomic_state *state); -void intel_shared_dpll_init(struct drm_device *dev); -void intel_dpll_readout_hw_state(struct drm_i915_private *dev_priv); -void intel_dpll_sanitize_state(struct drm_i915_private *dev_priv); - -void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv, - const struct intel_dpll_hw_state *hw_state); +int intel_dpll_get_freq(struct intel_display *display, + const struct intel_dpll *pll, + const struct intel_dpll_hw_state *dpll_hw_state); +bool intel_dpll_get_hw_state(struct intel_display *display, + struct intel_dpll *pll, + struct intel_dpll_hw_state *dpll_hw_state); +void intel_dpll_enable(const struct intel_crtc_state *crtc_state); +void intel_dpll_disable(const struct intel_crtc_state *crtc_state); +void intel_dpll_swap_state(struct intel_atomic_state *state); +void intel_dpll_init(struct intel_display *display); +void intel_dpll_update_ref_clks(struct intel_display *display); +void intel_dpll_readout_hw_state(struct intel_display *display); +void intel_dpll_sanitize_state(struct intel_display *display); + +void intel_dpll_dump_hw_state(struct intel_display *display, + struct drm_printer *p, + const struct intel_dpll_hw_state *dpll_hw_state); +bool intel_dpll_compare_hw_state(struct intel_display *display, + const struct intel_dpll_hw_state *a, + const struct intel_dpll_hw_state *b); enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port); bool intel_dpll_is_combophy(enum intel_dpll_id id); +void intel_dpll_state_verify(struct intel_atomic_state *state, + struct intel_crtc *crtc); +void intel_dpll_verify_disabled(struct intel_atomic_state *state); + #endif /* _INTEL_DPLL_MGR_H_ */ |
