linux-stable/drivers/gpu/drm/i915/display/intel_dpll_mgr.h

367 lines
9.1 KiB
C
Raw Normal View History

/*
* Copyright © 2012-2016 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
#ifndef _INTEL_DPLL_MGR_H_
#define _INTEL_DPLL_MGR_H_
#include <linux/types.h>
drm/i915/ehl: Add support for DPLL4 (v10) This patch adds support for DPLL4 on EHL that include the following restrictions: - DPLL4 cannot be used with DDIA (combo port A internal eDP usage). DPLL4 can be used with other DDIs, including DDID (combo port A external usage). - DPLL4 cannot be enabled when DC5 or DC6 are enabled. - The DPLL4 enable, lock, power enabled, and power state are connected to the MGPLL1_ENABLE register. v2: (suggestions from Bob Paauwe) - Rework ehl_get_dpll() function to call intel_find_shared_dpll() and iterate twice: once for Combo plls and once for MG plls. - Use MG pll funcs for DPLL4 instead of creating new ones and modify mg_pll_enable to include the restrictions for EHL. v3: Fix compilation error v4: (suggestions from Lucas and Ville) - Treat DPLL4 as a combo phy PLL and not as MG PLL - Disable DC states when this DPLL is being enabled - Reuse icl_get_dpll instead of creating a separate one for EHL v5: (suggestion from Ville) - Refcount the DC OFF power domains during the enabling and disabling of this DPLL. v6: rebase v7: (suggestion from Imre) - Add a new power domain instead of iterating over the domains assoicated with DC OFF power well. v8: (Ville and Imre) - Rename POWER_DOMAIN_DPLL4 TO POWER_DOMAIN_DPLL_DC_OFF - Grab a reference in intel_modeset_setup_hw_state() if this DPLL was already enabled perhaps by BIOS. - Check for the port type instead of the encoder v9: (Ville) - Move the block of code that grabs a reference to the power domain POWER_DOMAIN_DPLL_DC_OFF to intel_modeset_readout_hw_state() to ensure that there is a reference present before this DPLL might get disabled. v10: rebase Cc: José Roberto de Souza <jose.souza@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Reviewed-by: José Roberto de Souza <jose.souza@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190703230353.24059-1-vivek.kasireddy@intel.com
2019-07-03 23:03:53 +00:00
#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); })
enum tc_port;
struct drm_device;
struct drm_i915_private;
drm/i915: Sanitize the shared DPLL reserve/release interface For consistency s/intel_get_shared_dpll()/intel_reserve_shared_dplls()/ to better match intel_release_shared_dplls(). Also, pass to the reserve/release and get_dplls/put_dplls hooks the intel_atomic_state and CRTC object, that way these functions can look up the old or new state as needed. Also release the PLLs from the atomic state via a new put_dplls->intel_unreference_shared_dpll() call chain for better symmetry with the reservation via the get_dplls->intel_reference_shared_dpll() call chain. Since nothing uses the PLL returned by intel_reserve_shared_dplls(), make it return only a bool. While at it also clarify the reserve/release function docbook headers making it clear that multiple DPLLs will be reserved/released and whether the new or old atomic CRTC state is affected. This refactoring is also a preparation for a follow-up change that needs to reserve multiple DPLLs. Kudos to Ville for the idea to pass intel_atomic_state around, to make things clearer locally where an object's old/new atomic state is required. No functional changes. v2: - Fix checkpatch issue: typo in code comment. v3: - Rebase on drm-tip. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-17-imre.deak@intel.com
2019-06-28 14:36:28 +00:00
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_encoder;
struct intel_shared_dpll;
struct intel_shared_dpll_funcs;
/**
* enum intel_dpll_id - possible DPLL ids
*
* Enumeration of possible IDs for a DPLL. Real shared dpll ids must be >= 0.
*/
enum intel_dpll_id {
/**
* @DPLL_ID_PRIVATE: non-shared dpll in use
*/
DPLL_ID_PRIVATE = -1,
/**
* @DPLL_ID_PCH_PLL_A: DPLL A in ILK, SNB and IVB
*/
DPLL_ID_PCH_PLL_A = 0,
/**
* @DPLL_ID_PCH_PLL_B: DPLL B in ILK, SNB and IVB
*/
DPLL_ID_PCH_PLL_B = 1,
/**
* @DPLL_ID_WRPLL1: HSW and BDW WRPLL1
*/
DPLL_ID_WRPLL1 = 0,
/**
* @DPLL_ID_WRPLL2: HSW and BDW WRPLL2
*/
DPLL_ID_WRPLL2 = 1,
/**
* @DPLL_ID_SPLL: HSW and BDW SPLL
*/
DPLL_ID_SPLL = 2,
/**
* @DPLL_ID_LCPLL_810: HSW and BDW 0.81 GHz LCPLL
*/
DPLL_ID_LCPLL_810 = 3,
/**
* @DPLL_ID_LCPLL_1350: HSW and BDW 1.35 GHz LCPLL
*/
DPLL_ID_LCPLL_1350 = 4,
/**
* @DPLL_ID_LCPLL_2700: HSW and BDW 2.7 GHz LCPLL
*/
DPLL_ID_LCPLL_2700 = 5,
/**
* @DPLL_ID_SKL_DPLL0: SKL and later DPLL0
*/
DPLL_ID_SKL_DPLL0 = 0,
/**
* @DPLL_ID_SKL_DPLL1: SKL and later DPLL1
*/
DPLL_ID_SKL_DPLL1 = 1,
/**
* @DPLL_ID_SKL_DPLL2: SKL and later DPLL2
*/
DPLL_ID_SKL_DPLL2 = 2,
/**
* @DPLL_ID_SKL_DPLL3: SKL and later DPLL3
*/
DPLL_ID_SKL_DPLL3 = 3,
/**
* @DPLL_ID_ICL_DPLL0: ICL/TGL combo PHY DPLL0
*/
DPLL_ID_ICL_DPLL0 = 0,
/**
* @DPLL_ID_ICL_DPLL1: ICL/TGL combo PHY DPLL1
*/
DPLL_ID_ICL_DPLL1 = 1,
drm/i915/ehl: Add support for DPLL4 (v10) This patch adds support for DPLL4 on EHL that include the following restrictions: - DPLL4 cannot be used with DDIA (combo port A internal eDP usage). DPLL4 can be used with other DDIs, including DDID (combo port A external usage). - DPLL4 cannot be enabled when DC5 or DC6 are enabled. - The DPLL4 enable, lock, power enabled, and power state are connected to the MGPLL1_ENABLE register. v2: (suggestions from Bob Paauwe) - Rework ehl_get_dpll() function to call intel_find_shared_dpll() and iterate twice: once for Combo plls and once for MG plls. - Use MG pll funcs for DPLL4 instead of creating new ones and modify mg_pll_enable to include the restrictions for EHL. v3: Fix compilation error v4: (suggestions from Lucas and Ville) - Treat DPLL4 as a combo phy PLL and not as MG PLL - Disable DC states when this DPLL is being enabled - Reuse icl_get_dpll instead of creating a separate one for EHL v5: (suggestion from Ville) - Refcount the DC OFF power domains during the enabling and disabling of this DPLL. v6: rebase v7: (suggestion from Imre) - Add a new power domain instead of iterating over the domains assoicated with DC OFF power well. v8: (Ville and Imre) - Rename POWER_DOMAIN_DPLL4 TO POWER_DOMAIN_DPLL_DC_OFF - Grab a reference in intel_modeset_setup_hw_state() if this DPLL was already enabled perhaps by BIOS. - Check for the port type instead of the encoder v9: (Ville) - Move the block of code that grabs a reference to the power domain POWER_DOMAIN_DPLL_DC_OFF to intel_modeset_readout_hw_state() to ensure that there is a reference present before this DPLL might get disabled. v10: rebase Cc: José Roberto de Souza <jose.souza@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Reviewed-by: José Roberto de Souza <jose.souza@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190703230353.24059-1-vivek.kasireddy@intel.com
2019-07-03 23:03:53 +00:00
/**
* @DPLL_ID_EHL_DPLL4: EHL combo PHY DPLL4
*/
DPLL_ID_EHL_DPLL4 = 2,
/**
* @DPLL_ID_ICL_TBTPLL: ICL/TGL TBT PLL
*/
DPLL_ID_ICL_TBTPLL = 2,
/**
* @DPLL_ID_ICL_MGPLL1: ICL MG PLL 1 port 1 (C),
* TGL TC PLL 1 port 1 (TC1)
*/
DPLL_ID_ICL_MGPLL1 = 3,
/**
* @DPLL_ID_ICL_MGPLL2: ICL MG PLL 1 port 2 (D)
* TGL TC PLL 1 port 2 (TC2)
*/
DPLL_ID_ICL_MGPLL2 = 4,
/**
* @DPLL_ID_ICL_MGPLL3: ICL MG PLL 1 port 3 (E)
* TGL TC PLL 1 port 3 (TC3)
*/
DPLL_ID_ICL_MGPLL3 = 5,
/**
* @DPLL_ID_ICL_MGPLL4: ICL MG PLL 1 port 4 (F)
* TGL TC PLL 1 port 4 (TC4)
*/
DPLL_ID_ICL_MGPLL4 = 6,
/**
* @DPLL_ID_TGL_MGPLL5: TGL TC PLL port 5 (TC5)
*/
DPLL_ID_TGL_MGPLL5 = 7,
/**
* @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
drm/i915/icl: Reserve all required PLLs for TypeC ports When enabling a TypeC port we need to reserve all the required PLLs for it, the TBT PLL for TBT-alt and the MG PHY PLL for DP-alt/legacy sinks. We can select the proper PLL for the current port mode from the reserved PLLs only once we selected and locked down the port mode for the whole duration of the port's active state. Resetting and locking down the port mode can in turn happen only during the modeset commit phase once we disabled the given port and the PLL it used. To support the above reserve-and-select PLL semantic we store the reserved PLLs along with their HW state in the CRTC state and provide a way to select the active PLL from these. The selected PLL along with its HW state will be pointed at by crtc_state->shared_dpll/dpll_hw_state as in the case of other port types. Besides reserving all required PLLs no functional changes. v2: - Fix releasing the ICL PLLs, not clearing the PLLs from the old crtc_state. - Init port_dpll to ICL_PORT_DPLL_DEFAULT closer to where port_dpll is used for symmetry with the corresponding ICL_PORT_DPLL_MG_PHY init. (Ville) v3: - Add FIXME: for clearing the ICL port PLLs from the new crtc state. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-20-imre.deak@intel.com
2019-06-28 14:36:31 +00:00
enum icl_port_dpll_id {
ICL_PORT_DPLL_DEFAULT,
ICL_PORT_DPLL_MG_PHY,
ICL_PORT_DPLL_COUNT,
};
struct intel_dpll_hw_state {
/* i9xx, pch plls */
u32 dpll;
u32 dpll_md;
u32 fp0;
u32 fp1;
/* hsw, bdw */
u32 wrpll;
u32 spll;
/* skl */
/*
* 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
* the register. This allows us to easily compare the state to share
* the DPLL.
*/
u32 ctrl1;
/* HDMI only, 0 when used for DP */
u32 cfgcr1, cfgcr2;
/* icl */
u32 cfgcr0;
/* bxt */
u32 ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, pcsdw12;
/*
* ICL uses the following, already defined:
* u32 cfgcr0, cfgcr1;
*/
u32 mg_refclkin_ctl;
u32 mg_clktop2_coreclkctl1;
u32 mg_clktop2_hsclkctl;
u32 mg_pll_div0;
u32 mg_pll_div1;
u32 mg_pll_lf;
u32 mg_pll_frac_lock;
u32 mg_pll_ssc;
u32 mg_pll_bias;
u32 mg_pll_tdc_coldst_bias;
u32 mg_pll_bias_mask;
u32 mg_pll_tdc_coldst_bias_mask;
};
/**
* struct intel_shared_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
* future state which would be applied by an atomic mode set (stored in
* a struct &intel_atomic_state).
*
drm/i915: Sanitize the shared DPLL reserve/release interface For consistency s/intel_get_shared_dpll()/intel_reserve_shared_dplls()/ to better match intel_release_shared_dplls(). Also, pass to the reserve/release and get_dplls/put_dplls hooks the intel_atomic_state and CRTC object, that way these functions can look up the old or new state as needed. Also release the PLLs from the atomic state via a new put_dplls->intel_unreference_shared_dpll() call chain for better symmetry with the reservation via the get_dplls->intel_reference_shared_dpll() call chain. Since nothing uses the PLL returned by intel_reserve_shared_dplls(), make it return only a bool. While at it also clarify the reserve/release function docbook headers making it clear that multiple DPLLs will be reserved/released and whether the new or old atomic CRTC state is affected. This refactoring is also a preparation for a follow-up change that needs to reserve multiple DPLLs. Kudos to Ville for the idea to pass intel_atomic_state around, to make things clearer locally where an object's old/new atomic state is required. No functional changes. v2: - Fix checkpatch issue: typo in code comment. v3: - Rebase on drm-tip. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-17-imre.deak@intel.com
2019-06-28 14:36:28 +00:00
* See also intel_reserve_shared_dplls() and intel_release_shared_dplls().
*/
struct intel_shared_dpll_state {
/**
* @pipe_mask: mask of pipes using this DPLL, active or not
*/
u8 pipe_mask;
/**
* @hw_state: hardware configuration for the DPLL stored in
* struct &intel_dpll_hw_state.
*/
struct intel_dpll_hw_state hw_state;
};
/**
* struct dpll_info - display PLL platform specific info
*/
struct dpll_info {
/**
* @name: DPLL name; used for logging
*/
const char *name;
/**
* @funcs: platform specific hooks
*/
const struct intel_shared_dpll_funcs *funcs;
/**
* @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:
*
* INTEL_DPLL_ALWAYS_ON
* Inform the state checker that the DPLL is kept enabled even if
* not in use by any CRTC.
*/
u32 flags;
};
/**
* struct intel_shared_dpll - display PLL with tracked state and users
*/
struct intel_shared_dpll {
/**
* @state:
*
* Store the state for the pll, including its hw state
* and CRTCs using it.
*/
struct intel_shared_dpll_state state;
/**
* @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
*/
bool on;
/**
* @info: platform specific info
*/
const struct dpll_info *info;
/**
* @wakeref: In some platforms a device-level runtime pm reference may
* need to be grabbed to disable DC states while this DPLL is enabled
*/
drm/i915/ehl: Add support for DPLL4 (v10) This patch adds support for DPLL4 on EHL that include the following restrictions: - DPLL4 cannot be used with DDIA (combo port A internal eDP usage). DPLL4 can be used with other DDIs, including DDID (combo port A external usage). - DPLL4 cannot be enabled when DC5 or DC6 are enabled. - The DPLL4 enable, lock, power enabled, and power state are connected to the MGPLL1_ENABLE register. v2: (suggestions from Bob Paauwe) - Rework ehl_get_dpll() function to call intel_find_shared_dpll() and iterate twice: once for Combo plls and once for MG plls. - Use MG pll funcs for DPLL4 instead of creating new ones and modify mg_pll_enable to include the restrictions for EHL. v3: Fix compilation error v4: (suggestions from Lucas and Ville) - Treat DPLL4 as a combo phy PLL and not as MG PLL - Disable DC states when this DPLL is being enabled - Reuse icl_get_dpll instead of creating a separate one for EHL v5: (suggestion from Ville) - Refcount the DC OFF power domains during the enabling and disabling of this DPLL. v6: rebase v7: (suggestion from Imre) - Add a new power domain instead of iterating over the domains assoicated with DC OFF power well. v8: (Ville and Imre) - Rename POWER_DOMAIN_DPLL4 TO POWER_DOMAIN_DPLL_DC_OFF - Grab a reference in intel_modeset_setup_hw_state() if this DPLL was already enabled perhaps by BIOS. - Check for the port type instead of the encoder v9: (Ville) - Move the block of code that grabs a reference to the power domain POWER_DOMAIN_DPLL_DC_OFF to intel_modeset_readout_hw_state() to ensure that there is a reference present before this DPLL might get disabled. v10: rebase Cc: José Roberto de Souza <jose.souza@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Reviewed-by: José Roberto de Souza <jose.souza@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190703230353.24059-1-vivek.kasireddy@intel.com
2019-07-03 23:03:53 +00:00
intel_wakeref_t wakeref;
};
#define SKL_DPLL0 0
#define SKL_DPLL1 1
#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)
drm/i915: Sanitize the shared DPLL reserve/release interface For consistency s/intel_get_shared_dpll()/intel_reserve_shared_dplls()/ to better match intel_release_shared_dplls(). Also, pass to the reserve/release and get_dplls/put_dplls hooks the intel_atomic_state and CRTC object, that way these functions can look up the old or new state as needed. Also release the PLLs from the atomic state via a new put_dplls->intel_unreference_shared_dpll() call chain for better symmetry with the reservation via the get_dplls->intel_reference_shared_dpll() call chain. Since nothing uses the PLL returned by intel_reserve_shared_dplls(), make it return only a bool. While at it also clarify the reserve/release function docbook headers making it clear that multiple DPLLs will be reserved/released and whether the new or old atomic CRTC state is affected. This refactoring is also a preparation for a follow-up change that needs to reserve multiple DPLLs. Kudos to Ville for the idea to pass intel_atomic_state around, to make things clearer locally where an object's old/new atomic state is required. No functional changes. v2: - Fix checkpatch issue: typo in code comment. v3: - Rebase on drm-tip. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-17-imre.deak@intel.com
2019-06-28 14:36:28 +00:00
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);
drm/i915/icl: Reserve all required PLLs for TypeC ports When enabling a TypeC port we need to reserve all the required PLLs for it, the TBT PLL for TBT-alt and the MG PHY PLL for DP-alt/legacy sinks. We can select the proper PLL for the current port mode from the reserved PLLs only once we selected and locked down the port mode for the whole duration of the port's active state. Resetting and locking down the port mode can in turn happen only during the modeset commit phase once we disabled the given port and the PLL it used. To support the above reserve-and-select PLL semantic we store the reserved PLLs along with their HW state in the CRTC state and provide a way to select the active PLL from these. The selected PLL along with its HW state will be pointed at by crtc_state->shared_dpll/dpll_hw_state as in the case of other port types. Besides reserving all required PLLs no functional changes. v2: - Fix releasing the ICL PLLs, not clearing the PLLs from the old crtc_state. - Init port_dpll to ICL_PORT_DPLL_DEFAULT closer to where port_dpll is used for symmetry with the corresponding ICL_PORT_DPLL_MG_PHY init. (Ville) v3: - Add FIXME: for clearing the ICL port PLLs from the new crtc state. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-20-imre.deak@intel.com
2019-06-28 14:36:31 +00:00
void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
enum icl_port_dpll_id port_dpll_id);
drm/i915: Keep the TypeC port mode fixed when the port is active The TypeC port mode needs to stay fixed whenever the port is active. Do that by introducing a tc_link_refcount to account for active ports, avoiding changing the port mode if a reference is held. During the modeset commit phase we also have to reset the port mode and update the active PLL reflecting the new port mode. We can do this only once the port and its old PLL has been already disabled. Add the new encoder update_prepare/complete hooks that are called around the whole enabling sequence. The TypeC specific hooks of these will reset the port mode, update the active PLL if the port will be active and ensure that the port mode will stay fixed for the duration of the whole enabling sequence by holding a tc_link_refcount. During the port enabling, the pre_pll_enable/post_pll_disable hooks will take/release a tc_link_refcount to ensure the port mode stays fixed while the port is active. Changing the port mode should also be avoided during connector detection and AUX transfers if the port is active, we'll do that by checking the port's tc_link_refcount. When resetting the port mode we also have to take into account the maximum lanes provided by the FIA. It's guaranteed to be 4 in TBT-alt and legacy modes, but there may be less lanes available in DP-alt mode, in which case we have to fall back to TBT-alt mode. While at it also update icl_tc_phy_connect()'s code comment, reflecting the current way of switching the port mode. v2: - Add the update_prepare/complete hooks to the encoder instead of the connector. (Ville) - Simplify intel_connector_needs_modeset() by removing redundant if. (Ville) v3: - Fix sparse warning, marking static functions as such. v4: - Rebase on drm-tip. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190628143635.22066-21-imre.deak@intel.com
2019-06-28 14:36:32 +00:00
void intel_update_active_dpll(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,
const struct intel_dpll_hw_state *pll_state);
bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
struct intel_dpll_hw_state *hw_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_update_ref_clks(struct drm_i915_private *dev_priv);
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);
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);
#endif /* _INTEL_DPLL_MGR_H_ */