Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/dp: Add a standalone function to obtain shared dpll for HSW/BDW/SKL/BXT

Add the PLL selection code for HSW/BDW/BXT/SKL into a stand-alone function
in order to allow for the implementation of a platform neutral upfront
link training function.

v4:
* Removed dereferencing NULL pointer in case of failure (Dhinakaran Pandiyan)
v3:
* Add Hooks for all DDI platforms into this standalone function

v2:
* Change the macro to use dev_priv instead of dev (David Weinehall)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Jim Bride and committed by
Rodrigo Vivi
f169660e fbb30a5c

+81 -1
+39
drivers/gpu/drm/i915/intel_ddi.c
··· 2393 2393 return connector; 2394 2394 } 2395 2395 2396 + struct intel_shared_dpll * 2397 + intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock) 2398 + { 2399 + struct intel_connector *connector = intel_dp->attached_connector; 2400 + struct intel_encoder *encoder = connector->encoder; 2401 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2402 + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 2403 + struct intel_shared_dpll *pll = NULL; 2404 + struct intel_shared_dpll_config tmp_pll_config; 2405 + enum intel_dpll_id dpll_id; 2406 + 2407 + if (IS_BROXTON(dev_priv)) { 2408 + dpll_id = (enum intel_dpll_id)dig_port->port; 2409 + /* 2410 + * Select the required PLL. This works for platforms where 2411 + * there is no shared DPLL. 2412 + */ 2413 + pll = &dev_priv->shared_dplls[dpll_id]; 2414 + if (WARN_ON(pll->active_mask)) { 2415 + 2416 + DRM_ERROR("Shared DPLL in use. active_mask:%x\n", 2417 + pll->active_mask); 2418 + return NULL; 2419 + } 2420 + tmp_pll_config = pll->config; 2421 + if (!bxt_ddi_dp_set_dpll_hw_state(clock, 2422 + &pll->config.hw_state)) { 2423 + DRM_ERROR("Could not setup DPLL\n"); 2424 + pll->config = tmp_pll_config; 2425 + return NULL; 2426 + } 2427 + } else if (IS_SKYLAKE(dev_priv)) { 2428 + pll = skl_find_link_pll(dev_priv, clock); 2429 + } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 2430 + pll = hsw_ddi_dp_get_dpll(encoder, clock); 2431 + } 2432 + return pll; 2433 + } 2434 + 2396 2435 void intel_ddi_init(struct drm_device *dev, enum port port) 2397 2436 { 2398 2437 struct drm_i915_private *dev_priv = to_i915(dev);
+38
drivers/gpu/drm/i915/intel_dpll_mgr.c
··· 24 24 #include "intel_drv.h" 25 25 26 26 struct intel_shared_dpll * 27 + skl_find_link_pll(struct drm_i915_private *dev_priv, int clock) 28 + { 29 + struct intel_shared_dpll *pll = NULL; 30 + struct intel_dpll_hw_state dpll_hw_state; 31 + enum intel_dpll_id i; 32 + bool found = false; 33 + 34 + if (!skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state)) 35 + return pll; 36 + 37 + for (i = DPLL_ID_SKL_DPLL1; i <= DPLL_ID_SKL_DPLL3; i++) { 38 + pll = &dev_priv->shared_dplls[i]; 39 + 40 + /* Only want to check enabled timings first */ 41 + if (pll->config.crtc_mask == 0) 42 + continue; 43 + 44 + if (memcmp(&dpll_hw_state, &pll->config.hw_state, 45 + sizeof(pll->config.hw_state)) == 0) { 46 + found = true; 47 + break; 48 + } 49 + } 50 + 51 + /* Ok no matching timings, maybe there's a free one? */ 52 + for (i = DPLL_ID_SKL_DPLL1; 53 + ((found == false) && (i <= DPLL_ID_SKL_DPLL3)); i++) { 54 + pll = &dev_priv->shared_dplls[i]; 55 + if (pll->config.crtc_mask == 0) { 56 + pll->config.hw_state = dpll_hw_state; 57 + break; 58 + } 59 + } 60 + 61 + return pll; 62 + } 63 + 64 + struct intel_shared_dpll * 27 65 intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, 28 66 enum intel_dpll_id id) 29 67 {
+2
drivers/gpu/drm/i915/intel_dpll_mgr.h
··· 168 168 /* SKL dpll related functions */ 169 169 bool skl_ddi_dp_set_dpll_hw_state(int clock, 170 170 struct intel_dpll_hw_state *dpll_hw_state); 171 + struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv, 172 + int clock); 171 173 172 174 173 175 /* HSW dpll related functions */
+2 -1
drivers/gpu/drm/i915/intel_drv.h
··· 1159 1159 struct intel_crtc_state *pipe_config); 1160 1160 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state); 1161 1161 uint32_t ddi_signal_levels(struct intel_dp *intel_dp); 1162 - 1162 + struct intel_shared_dpll *intel_ddi_get_link_dpll(struct intel_dp *intel_dp, 1163 + int clock); 1163 1164 unsigned int intel_fb_align_height(struct drm_device *dev, 1164 1165 unsigned int height, 1165 1166 uint32_t pixel_format,