2016-03-08 17:46:19 +02:00
/*
* 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_
2016-03-08 17:46:23 +02:00
/*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 ) ; } )
2016-03-08 17:46:19 +02:00
struct drm_i915_private ;
2016-03-08 17:46:20 +02:00
struct intel_crtc ;
struct intel_crtc_state ;
2016-03-08 17:46:23 +02:00
struct intel_encoder ;
2016-03-08 17:46:19 +02:00
2016-03-08 17:46:23 +02:00
struct intel_shared_dpll ;
2016-03-08 17:46:22 +02:00
struct intel_dpll_mgr ;
2016-12-29 17:22:11 +02:00
/**
* enum intel_dpll_id - possible DPLL ids
*
* Enumeration of possible IDs for a DPLL . Real shared dpll ids must be > = 0.
*/
2016-03-08 17:46:19 +02:00
enum intel_dpll_id {
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_PRIVATE : non - shared dpll in use
*/
DPLL_ID_PRIVATE = - 1 ,
/**
* @ DPLL_ID_PCH_PLL_A : DPLL A in ILK , SNB and IVB
*/
2016-03-08 17:46:19 +02:00
DPLL_ID_PCH_PLL_A = 0 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_PCH_PLL_B : DPLL B in ILK , SNB and IVB
*/
2016-03-08 17:46:19 +02:00
DPLL_ID_PCH_PLL_B = 1 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_WRPLL1 : HSW and BDW WRPLL1
*/
2016-03-08 17:46:19 +02:00
DPLL_ID_WRPLL1 = 0 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_WRPLL2 : HSW and BDW WRPLL2
*/
2016-03-08 17:46:19 +02:00
DPLL_ID_WRPLL2 = 1 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_SPLL : HSW and BDW SPLL
*/
2016-03-08 17:46:19 +02:00
DPLL_ID_SPLL = 2 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_LCPLL_810 : HSW and BDW 0.81 GHz LCPLL
*/
2016-03-08 17:46:26 +02:00
DPLL_ID_LCPLL_810 = 3 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_LCPLL_1350 : HSW and BDW 1.35 GHz LCPLL
*/
2016-03-08 17:46:26 +02:00
DPLL_ID_LCPLL_1350 = 4 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_LCPLL_2700 : HSW and BDW 2.7 GHz LCPLL
*/
2016-03-08 17:46:26 +02:00
DPLL_ID_LCPLL_2700 = 5 ,
2016-03-08 17:46:19 +02:00
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_SKL_DPLL0 : SKL and later DPLL0
*/
2016-03-08 17:46:27 +02:00
DPLL_ID_SKL_DPLL0 = 0 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_SKL_DPLL1 : SKL and later DPLL1
*/
2016-03-08 17:46:27 +02:00
DPLL_ID_SKL_DPLL1 = 1 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_SKL_DPLL2 : SKL and later DPLL2
*/
2016-03-08 17:46:27 +02:00
DPLL_ID_SKL_DPLL2 = 2 ,
2016-12-29 17:22:11 +02:00
/**
* @ DPLL_ID_SKL_DPLL3 : SKL and later DPLL3
*/
2016-03-08 17:46:27 +02:00
DPLL_ID_SKL_DPLL3 = 3 ,
2016-03-08 17:46:19 +02:00
} ;
2016-03-08 17:46:26 +02:00
# define I915_NUM_PLLS 6
2016-03-08 17:46:19 +02:00
struct intel_dpll_hw_state {
/* i9xx, pch plls */
uint32_t dpll ;
uint32_t dpll_md ;
uint32_t fp0 ;
uint32_t fp1 ;
/* hsw, bdw */
uint32_t wrpll ;
uint32_t 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 .
*/
uint32_t ctrl1 ;
/* HDMI only, 0 when used for DP */
uint32_t cfgcr1 , cfgcr2 ;
/* bxt */
uint32_t ebb0 , ebb4 , pll0 , pll1 , pll2 , pll3 , pll6 , pll8 , pll9 , pll10 ,
pcsdw12 ;
} ;
2016-12-29 17:22:11 +02:00
/**
* 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 ) .
*
* See also intel_get_shared_dpll ( ) and intel_release_shared_dpll ( ) .
*/
2016-12-29 17:22:09 +02:00
struct intel_shared_dpll_state {
2016-12-29 17:22:11 +02:00
/**
* @ crtc_mask : mask of CRTC using this DPLL , active or not
*/
unsigned crtc_mask ;
/**
* @ hw_state : hardware configuration for the DPLL stored in
* struct & intel_dpll_hw_state .
*/
2016-03-08 17:46:19 +02:00
struct intel_dpll_hw_state hw_state ;
} ;
2016-12-29 17:22:11 +02:00
/**
* struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs
*/
2016-03-08 17:46:21 +02:00
struct intel_shared_dpll_funcs {
2016-12-29 17:22:11 +02:00
/**
* @ prepare :
*
* Optional hook to perform operations prior to enabling the PLL .
* Called from intel_prepare_shared_dpll ( ) function unless the PLL
* is already enabled .
*/
2016-12-29 17:22:10 +02:00
void ( * prepare ) ( struct drm_i915_private * dev_priv ,
struct intel_shared_dpll * pll ) ;
2016-12-29 17:22:11 +02:00
/**
* @ enable :
*
* Hook for enabling the pll , called from intel_enable_shared_dpll ( )
* if the pll is not already enabled .
*/
2016-03-08 17:46:19 +02:00
void ( * enable ) ( struct drm_i915_private * dev_priv ,
struct intel_shared_dpll * pll ) ;
2016-12-29 17:22:11 +02:00
/**
* @ 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 .
*/
2016-03-08 17:46:19 +02:00
void ( * disable ) ( struct drm_i915_private * dev_priv ,
struct intel_shared_dpll * pll ) ;
2016-12-29 17:22:11 +02:00
/**
* @ 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 .
*/
2016-03-08 17:46:19 +02:00
bool ( * get_hw_state ) ( struct drm_i915_private * dev_priv ,
struct intel_shared_dpll * pll ,
struct intel_dpll_hw_state * hw_state ) ;
} ;
2016-12-29 17:22:11 +02:00
/**
* struct intel_shared_dpll - display PLL with tracked state and users
*/
2016-03-08 17:46:21 +02:00
struct intel_shared_dpll {
2016-12-29 17:22:11 +02:00
/**
* @ state :
*
* Store the state for the pll , including the its hw state
* and CRTCs using it .
*/
2016-12-29 17:22:09 +02:00
struct intel_shared_dpll_state state ;
2016-03-08 17:46:21 +02:00
2016-12-29 17:22:11 +02:00
/**
* @ active_mask : mask of active CRTCs ( i . e . DPMS on ) using this DPLL
*/
unsigned active_mask ;
/**
* @ on : is the PLL actually active ? Disabled during modeset
*/
bool on ;
/**
* @ name : DPLL name ; used for logging
*/
2016-03-08 17:46:21 +02:00
const char * name ;
2016-12-29 17:22:11 +02:00
/**
* @ id : unique indentifier for this DPLL ; should match the index in the
* dev_priv - > shared_dplls array
*/
2016-03-08 17:46:21 +02:00
enum intel_dpll_id id ;
2016-12-29 17:22:11 +02:00
/**
* @ funcs : platform specific hooks
*/
2016-03-08 17:46:21 +02:00
struct intel_shared_dpll_funcs funcs ;
2016-03-08 17:46:26 +02:00
2016-12-29 17:22:11 +02:00
# 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 .
*/
2016-03-08 17:46:26 +02:00
uint32_t flags ;
2016-03-08 17:46:21 +02:00
} ;
2016-03-08 17:46:19 +02:00
# define SKL_DPLL0 0
# define SKL_DPLL1 1
# define SKL_DPLL2 2
# define SKL_DPLL3 3
2016-03-08 17:46:20 +02:00
/* 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)
struct intel_shared_dpll * intel_get_shared_dpll ( struct intel_crtc * crtc ,
2016-03-08 17:46:23 +02:00
struct intel_crtc_state * state ,
struct intel_encoder * encoder ) ;
2016-12-29 17:22:07 +02:00
void intel_release_shared_dpll ( struct intel_shared_dpll * dpll ,
struct intel_crtc * crtc ,
struct drm_atomic_state * state ) ;
2016-03-08 17:46:20 +02:00
void intel_prepare_shared_dpll ( struct intel_crtc * crtc ) ;
void intel_enable_shared_dpll ( struct intel_crtc * crtc ) ;
void intel_disable_shared_dpll ( struct intel_crtc * crtc ) ;
2016-12-29 17:22:08 +02:00
void intel_shared_dpll_swap_state ( struct drm_atomic_state * state ) ;
2016-03-08 17:46:20 +02:00
void intel_shared_dpll_init ( struct drm_device * dev ) ;
2016-12-29 17:22:12 +02:00
void intel_dpll_dump_hw_state ( struct drm_i915_private * dev_priv ,
struct intel_dpll_hw_state * hw_state ) ;
2016-03-08 17:46:19 +02:00
# endif /* _INTEL_DPLL_MGR_H_ */