18621f407SFrançois Tigeot /* 28621f407SFrançois Tigeot * Copyright © 2012-2016 Intel Corporation 38621f407SFrançois Tigeot * 48621f407SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 58621f407SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 68621f407SFrançois Tigeot * to deal in the Software without restriction, including without limitation 78621f407SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88621f407SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 98621f407SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 108621f407SFrançois Tigeot * 118621f407SFrançois Tigeot * The above copyright notice and this permission notice (including the next 128621f407SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 138621f407SFrançois Tigeot * Software. 148621f407SFrançois Tigeot * 158621f407SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168621f407SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178621f407SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 188621f407SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 198621f407SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 208621f407SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 218621f407SFrançois Tigeot * IN THE SOFTWARE. 228621f407SFrançois Tigeot * 238621f407SFrançois Tigeot */ 248621f407SFrançois Tigeot 258621f407SFrançois Tigeot #ifndef _INTEL_DPLL_MGR_H_ 268621f407SFrançois Tigeot #define _INTEL_DPLL_MGR_H_ 278621f407SFrançois Tigeot 288621f407SFrançois Tigeot /*FIXME: Move this to a more appropriate place. */ 298621f407SFrançois Tigeot #define abs_diff(a, b) ({ \ 308621f407SFrançois Tigeot typeof(a) __a = (a); \ 318621f407SFrançois Tigeot typeof(b) __b = (b); \ 328621f407SFrançois Tigeot (void) (&__a == &__b); \ 338621f407SFrançois Tigeot __a > __b ? (__a - __b) : (__b - __a); }) 348621f407SFrançois Tigeot 358621f407SFrançois Tigeot struct drm_i915_private; 368621f407SFrançois Tigeot struct intel_crtc; 378621f407SFrançois Tigeot struct intel_crtc_state; 388621f407SFrançois Tigeot struct intel_encoder; 398621f407SFrançois Tigeot 408621f407SFrançois Tigeot struct intel_shared_dpll; 418621f407SFrançois Tigeot struct intel_dpll_mgr; 428621f407SFrançois Tigeot 43a85cb24fSFrançois Tigeot /** 44a85cb24fSFrançois Tigeot * enum intel_dpll_id - possible DPLL ids 45a85cb24fSFrançois Tigeot * 46a85cb24fSFrançois Tigeot * Enumeration of possible IDs for a DPLL. Real shared dpll ids must be >= 0. 47a85cb24fSFrançois Tigeot */ 488621f407SFrançois Tigeot enum intel_dpll_id { 49a85cb24fSFrançois Tigeot /** 50a85cb24fSFrançois Tigeot * @DPLL_ID_PRIVATE: non-shared dpll in use 51a85cb24fSFrançois Tigeot */ 52a85cb24fSFrançois Tigeot DPLL_ID_PRIVATE = -1, 53a85cb24fSFrançois Tigeot 54a85cb24fSFrançois Tigeot /** 55a85cb24fSFrançois Tigeot * @DPLL_ID_PCH_PLL_A: DPLL A in ILK, SNB and IVB 56a85cb24fSFrançois Tigeot */ 578621f407SFrançois Tigeot DPLL_ID_PCH_PLL_A = 0, 58a85cb24fSFrançois Tigeot /** 59a85cb24fSFrançois Tigeot * @DPLL_ID_PCH_PLL_B: DPLL B in ILK, SNB and IVB 60a85cb24fSFrançois Tigeot */ 618621f407SFrançois Tigeot DPLL_ID_PCH_PLL_B = 1, 62a85cb24fSFrançois Tigeot 63a85cb24fSFrançois Tigeot 64a85cb24fSFrançois Tigeot /** 65a85cb24fSFrançois Tigeot * @DPLL_ID_WRPLL1: HSW and BDW WRPLL1 66a85cb24fSFrançois Tigeot */ 678621f407SFrançois Tigeot DPLL_ID_WRPLL1 = 0, 68a85cb24fSFrançois Tigeot /** 69a85cb24fSFrançois Tigeot * @DPLL_ID_WRPLL2: HSW and BDW WRPLL2 70a85cb24fSFrançois Tigeot */ 718621f407SFrançois Tigeot DPLL_ID_WRPLL2 = 1, 72a85cb24fSFrançois Tigeot /** 73a85cb24fSFrançois Tigeot * @DPLL_ID_SPLL: HSW and BDW SPLL 74a85cb24fSFrançois Tigeot */ 758621f407SFrançois Tigeot DPLL_ID_SPLL = 2, 76a85cb24fSFrançois Tigeot /** 77a85cb24fSFrançois Tigeot * @DPLL_ID_LCPLL_810: HSW and BDW 0.81 GHz LCPLL 78a85cb24fSFrançois Tigeot */ 798621f407SFrançois Tigeot DPLL_ID_LCPLL_810 = 3, 80a85cb24fSFrançois Tigeot /** 81a85cb24fSFrançois Tigeot * @DPLL_ID_LCPLL_1350: HSW and BDW 1.35 GHz LCPLL 82a85cb24fSFrançois Tigeot */ 838621f407SFrançois Tigeot DPLL_ID_LCPLL_1350 = 4, 84a85cb24fSFrançois Tigeot /** 85a85cb24fSFrançois Tigeot * @DPLL_ID_LCPLL_2700: HSW and BDW 2.7 GHz LCPLL 86a85cb24fSFrançois Tigeot */ 878621f407SFrançois Tigeot DPLL_ID_LCPLL_2700 = 5, 888621f407SFrançois Tigeot 89a85cb24fSFrançois Tigeot 90a85cb24fSFrançois Tigeot /** 91a85cb24fSFrançois Tigeot * @DPLL_ID_SKL_DPLL0: SKL and later DPLL0 92a85cb24fSFrançois Tigeot */ 938621f407SFrançois Tigeot DPLL_ID_SKL_DPLL0 = 0, 94a85cb24fSFrançois Tigeot /** 95a85cb24fSFrançois Tigeot * @DPLL_ID_SKL_DPLL1: SKL and later DPLL1 96a85cb24fSFrançois Tigeot */ 978621f407SFrançois Tigeot DPLL_ID_SKL_DPLL1 = 1, 98a85cb24fSFrançois Tigeot /** 99a85cb24fSFrançois Tigeot * @DPLL_ID_SKL_DPLL2: SKL and later DPLL2 100a85cb24fSFrançois Tigeot */ 1018621f407SFrançois Tigeot DPLL_ID_SKL_DPLL2 = 2, 102a85cb24fSFrançois Tigeot /** 103a85cb24fSFrançois Tigeot * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3 104a85cb24fSFrançois Tigeot */ 1058621f407SFrançois Tigeot DPLL_ID_SKL_DPLL3 = 3, 1068621f407SFrançois Tigeot }; 1078621f407SFrançois Tigeot #define I915_NUM_PLLS 6 1088621f407SFrançois Tigeot 1098621f407SFrançois Tigeot struct intel_dpll_hw_state { 1108621f407SFrançois Tigeot /* i9xx, pch plls */ 1118621f407SFrançois Tigeot uint32_t dpll; 1128621f407SFrançois Tigeot uint32_t dpll_md; 1138621f407SFrançois Tigeot uint32_t fp0; 1148621f407SFrançois Tigeot uint32_t fp1; 1158621f407SFrançois Tigeot 1168621f407SFrançois Tigeot /* hsw, bdw */ 1178621f407SFrançois Tigeot uint32_t wrpll; 1188621f407SFrançois Tigeot uint32_t spll; 1198621f407SFrançois Tigeot 1208621f407SFrançois Tigeot /* skl */ 1218621f407SFrançois Tigeot /* 1228621f407SFrançois Tigeot * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in 1238621f407SFrançois Tigeot * lower part of ctrl1 and they get shifted into position when writing 1248621f407SFrançois Tigeot * the register. This allows us to easily compare the state to share 1258621f407SFrançois Tigeot * the DPLL. 1268621f407SFrançois Tigeot */ 1278621f407SFrançois Tigeot uint32_t ctrl1; 1288621f407SFrançois Tigeot /* HDMI only, 0 when used for DP */ 1298621f407SFrançois Tigeot uint32_t cfgcr1, cfgcr2; 1308621f407SFrançois Tigeot 131*3f2dd94aSFrançois Tigeot /* cnl */ 132*3f2dd94aSFrançois Tigeot uint32_t cfgcr0; 133*3f2dd94aSFrançois Tigeot /* CNL also uses cfgcr1 */ 134*3f2dd94aSFrançois Tigeot 1358621f407SFrançois Tigeot /* bxt */ 1368621f407SFrançois Tigeot uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, 1378621f407SFrançois Tigeot pcsdw12; 1388621f407SFrançois Tigeot }; 1398621f407SFrançois Tigeot 140a85cb24fSFrançois Tigeot /** 141a85cb24fSFrançois Tigeot * struct intel_shared_dpll_state - hold the DPLL atomic state 142a85cb24fSFrançois Tigeot * 143a85cb24fSFrançois Tigeot * This structure holds an atomic state for the DPLL, that can represent 144a85cb24fSFrançois Tigeot * either its current state (in struct &intel_shared_dpll) or a desired 145a85cb24fSFrançois Tigeot * future state which would be applied by an atomic mode set (stored in 146a85cb24fSFrançois Tigeot * a struct &intel_atomic_state). 147a85cb24fSFrançois Tigeot * 148a85cb24fSFrançois Tigeot * See also intel_get_shared_dpll() and intel_release_shared_dpll(). 149a85cb24fSFrançois Tigeot */ 150a85cb24fSFrançois Tigeot struct intel_shared_dpll_state { 151a85cb24fSFrançois Tigeot /** 152a85cb24fSFrançois Tigeot * @crtc_mask: mask of CRTC using this DPLL, active or not 153a85cb24fSFrançois Tigeot */ 154a85cb24fSFrançois Tigeot unsigned crtc_mask; 155a85cb24fSFrançois Tigeot 156a85cb24fSFrançois Tigeot /** 157a85cb24fSFrançois Tigeot * @hw_state: hardware configuration for the DPLL stored in 158a85cb24fSFrançois Tigeot * struct &intel_dpll_hw_state. 159a85cb24fSFrançois Tigeot */ 1608621f407SFrançois Tigeot struct intel_dpll_hw_state hw_state; 1618621f407SFrançois Tigeot }; 1628621f407SFrançois Tigeot 163a85cb24fSFrançois Tigeot /** 164a85cb24fSFrançois Tigeot * struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs 165a85cb24fSFrançois Tigeot */ 1668621f407SFrançois Tigeot struct intel_shared_dpll_funcs { 167a85cb24fSFrançois Tigeot /** 168a85cb24fSFrançois Tigeot * @prepare: 169a85cb24fSFrançois Tigeot * 170a85cb24fSFrançois Tigeot * Optional hook to perform operations prior to enabling the PLL. 171a85cb24fSFrançois Tigeot * Called from intel_prepare_shared_dpll() function unless the PLL 172a85cb24fSFrançois Tigeot * is already enabled. 173a85cb24fSFrançois Tigeot */ 174a85cb24fSFrançois Tigeot void (*prepare)(struct drm_i915_private *dev_priv, 1758621f407SFrançois Tigeot struct intel_shared_dpll *pll); 176a85cb24fSFrançois Tigeot 177a85cb24fSFrançois Tigeot /** 178a85cb24fSFrançois Tigeot * @enable: 179a85cb24fSFrançois Tigeot * 180a85cb24fSFrançois Tigeot * Hook for enabling the pll, called from intel_enable_shared_dpll() 181a85cb24fSFrançois Tigeot * if the pll is not already enabled. 182a85cb24fSFrançois Tigeot */ 1838621f407SFrançois Tigeot void (*enable)(struct drm_i915_private *dev_priv, 1848621f407SFrançois Tigeot struct intel_shared_dpll *pll); 185a85cb24fSFrançois Tigeot 186a85cb24fSFrançois Tigeot /** 187a85cb24fSFrançois Tigeot * @disable: 188a85cb24fSFrançois Tigeot * 189a85cb24fSFrançois Tigeot * Hook for disabling the pll, called from intel_disable_shared_dpll() 190a85cb24fSFrançois Tigeot * only when it is safe to disable the pll, i.e., there are no more 191a85cb24fSFrançois Tigeot * tracked users for it. 192a85cb24fSFrançois Tigeot */ 1938621f407SFrançois Tigeot void (*disable)(struct drm_i915_private *dev_priv, 1948621f407SFrançois Tigeot struct intel_shared_dpll *pll); 195a85cb24fSFrançois Tigeot 196a85cb24fSFrançois Tigeot /** 197a85cb24fSFrançois Tigeot * @get_hw_state: 198a85cb24fSFrançois Tigeot * 199a85cb24fSFrançois Tigeot * Hook for reading the values currently programmed to the DPLL 200a85cb24fSFrançois Tigeot * registers. This is used for initial hw state readout and state 201a85cb24fSFrançois Tigeot * verification after a mode set. 202a85cb24fSFrançois Tigeot */ 2038621f407SFrançois Tigeot bool (*get_hw_state)(struct drm_i915_private *dev_priv, 2048621f407SFrançois Tigeot struct intel_shared_dpll *pll, 2058621f407SFrançois Tigeot struct intel_dpll_hw_state *hw_state); 2068621f407SFrançois Tigeot }; 2078621f407SFrançois Tigeot 208a85cb24fSFrançois Tigeot /** 209a85cb24fSFrançois Tigeot * struct intel_shared_dpll - display PLL with tracked state and users 210a85cb24fSFrançois Tigeot */ 2118621f407SFrançois Tigeot struct intel_shared_dpll { 212a85cb24fSFrançois Tigeot /** 213a85cb24fSFrançois Tigeot * @state: 214a85cb24fSFrançois Tigeot * 215a85cb24fSFrançois Tigeot * Store the state for the pll, including the its hw state 216a85cb24fSFrançois Tigeot * and CRTCs using it. 217a85cb24fSFrançois Tigeot */ 218a85cb24fSFrançois Tigeot struct intel_shared_dpll_state state; 2198621f407SFrançois Tigeot 220a85cb24fSFrançois Tigeot /** 221a85cb24fSFrançois Tigeot * @active_mask: mask of active CRTCs (i.e. DPMS on) using this DPLL 222a85cb24fSFrançois Tigeot */ 223a85cb24fSFrançois Tigeot unsigned active_mask; 224a85cb24fSFrançois Tigeot 225a85cb24fSFrançois Tigeot /** 226a85cb24fSFrançois Tigeot * @on: is the PLL actually active? Disabled during modeset 227a85cb24fSFrançois Tigeot */ 228a85cb24fSFrançois Tigeot bool on; 229a85cb24fSFrançois Tigeot 230a85cb24fSFrançois Tigeot /** 231a85cb24fSFrançois Tigeot * @name: DPLL name; used for logging 232a85cb24fSFrançois Tigeot */ 2338621f407SFrançois Tigeot const char *name; 234a85cb24fSFrançois Tigeot 235a85cb24fSFrançois Tigeot /** 236a85cb24fSFrançois Tigeot * @id: unique indentifier for this DPLL; should match the index in the 237a85cb24fSFrançois Tigeot * dev_priv->shared_dplls array 238a85cb24fSFrançois Tigeot */ 2398621f407SFrançois Tigeot enum intel_dpll_id id; 2408621f407SFrançois Tigeot 241a85cb24fSFrançois Tigeot /** 242a85cb24fSFrançois Tigeot * @funcs: platform specific hooks 243a85cb24fSFrançois Tigeot */ 2448621f407SFrançois Tigeot struct intel_shared_dpll_funcs funcs; 2458621f407SFrançois Tigeot 246a85cb24fSFrançois Tigeot #define INTEL_DPLL_ALWAYS_ON (1 << 0) 247a85cb24fSFrançois Tigeot /** 248a85cb24fSFrançois Tigeot * @flags: 249a85cb24fSFrançois Tigeot * 250a85cb24fSFrançois Tigeot * INTEL_DPLL_ALWAYS_ON 251a85cb24fSFrançois Tigeot * Inform the state checker that the DPLL is kept enabled even if 252a85cb24fSFrançois Tigeot * not in use by any CRTC. 253a85cb24fSFrançois Tigeot */ 2548621f407SFrançois Tigeot uint32_t flags; 2558621f407SFrançois Tigeot }; 2568621f407SFrançois Tigeot 2578621f407SFrançois Tigeot #define SKL_DPLL0 0 2588621f407SFrançois Tigeot #define SKL_DPLL1 1 2598621f407SFrançois Tigeot #define SKL_DPLL2 2 2608621f407SFrançois Tigeot #define SKL_DPLL3 3 2618621f407SFrançois Tigeot 2628621f407SFrançois Tigeot /* shared dpll functions */ 2638621f407SFrançois Tigeot struct intel_shared_dpll * 2648621f407SFrançois Tigeot intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, 2658621f407SFrançois Tigeot enum intel_dpll_id id); 2668621f407SFrançois Tigeot enum intel_dpll_id 2678621f407SFrançois Tigeot intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, 2688621f407SFrançois Tigeot struct intel_shared_dpll *pll); 2698621f407SFrançois Tigeot void assert_shared_dpll(struct drm_i915_private *dev_priv, 2708621f407SFrançois Tigeot struct intel_shared_dpll *pll, 2718621f407SFrançois Tigeot bool state); 2728621f407SFrançois Tigeot #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) 2738621f407SFrançois Tigeot #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) 2748621f407SFrançois Tigeot struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, 2758621f407SFrançois Tigeot struct intel_crtc_state *state, 2768621f407SFrançois Tigeot struct intel_encoder *encoder); 277a85cb24fSFrançois Tigeot void intel_release_shared_dpll(struct intel_shared_dpll *dpll, 278a85cb24fSFrançois Tigeot struct intel_crtc *crtc, 279a85cb24fSFrançois Tigeot struct drm_atomic_state *state); 2808621f407SFrançois Tigeot void intel_prepare_shared_dpll(struct intel_crtc *crtc); 2818621f407SFrançois Tigeot void intel_enable_shared_dpll(struct intel_crtc *crtc); 2828621f407SFrançois Tigeot void intel_disable_shared_dpll(struct intel_crtc *crtc); 283a85cb24fSFrançois Tigeot void intel_shared_dpll_swap_state(struct drm_atomic_state *state); 2848621f407SFrançois Tigeot void intel_shared_dpll_init(struct drm_device *dev); 2858621f407SFrançois Tigeot 286a85cb24fSFrançois Tigeot void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv, 287a85cb24fSFrançois Tigeot struct intel_dpll_hw_state *hw_state); 2888621f407SFrançois Tigeot 2898621f407SFrançois Tigeot #endif /* _INTEL_DPLL_MGR_H_ */ 290