diff options
author | Damien Lespiau <damien.lespiau@intel.com> | 2014-01-21 08:35:39 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-01-24 11:22:56 -0500 |
commit | ec5b01dd8f127f5e61ba25efabb98f0ff68f4c86 (patch) | |
tree | 43bce3b88ac5f5c8f00c81be2ec9ce7626e23d38 /drivers/gpu/drm/i915/intel_dp.c | |
parent | 0f540c3a7cfb91c9d7a19eb0c95c24c5de1197d5 (diff) |
drm/i915: Turn get_aux_clock_divider() into per-platform vfuncs
A tiny clean-up to allow better code separation between platforms.
v2: Fix comment placement (put in in i9xx_get_aux_clock_divider()) and
nuke the outdated PCH eDP comment (Jani Nikula)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 45ec1a85451b..9c938f8bffa9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -358,31 +358,46 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) | |||
358 | return status; | 358 | return status; |
359 | } | 359 | } |
360 | 360 | ||
361 | static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp, | 361 | static uint32_t i9xx_get_aux_clock_divider(struct intel_dp *intel_dp, int index) |
362 | int index) | ||
363 | { | 362 | { |
364 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 363 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
365 | struct drm_device *dev = intel_dig_port->base.base.dev; | 364 | struct drm_device *dev = intel_dig_port->base.base.dev; |
366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
367 | 365 | ||
368 | /* The clock divider is based off the hrawclk, | 366 | /* |
369 | * and would like to run at 2MHz. So, take the | 367 | * The clock divider is based off the hrawclk, and would like to run at |
370 | * hrawclk value and divide by 2 and use that | 368 | * 2MHz. So, take the hrawclk value and divide by 2 and use that |
371 | * | ||
372 | * Note that PCH attached eDP panels should use a 125MHz input | ||
373 | * clock divider. | ||
374 | */ | 369 | */ |
375 | if (IS_VALLEYVIEW(dev)) { | 370 | return index ? 0 : intel_hrawclk(dev) / 2; |
376 | return index ? 0 : 100; | 371 | } |
377 | } else if (intel_dig_port->port == PORT_A) { | 372 | |
378 | if (index) | 373 | static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) |
379 | return 0; | 374 | { |
380 | if (HAS_DDI(dev)) | 375 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
381 | return DIV_ROUND_CLOSEST(intel_ddi_get_cdclk_freq(dev_priv), 2000); | 376 | struct drm_device *dev = intel_dig_port->base.base.dev; |
382 | else if (IS_GEN6(dev) || IS_GEN7(dev)) | 377 | |
378 | if (index) | ||
379 | return 0; | ||
380 | |||
381 | if (intel_dig_port->port == PORT_A) { | ||
382 | if (IS_GEN6(dev) || IS_GEN7(dev)) | ||
383 | return 200; /* SNB & IVB eDP input clock at 400Mhz */ | 383 | return 200; /* SNB & IVB eDP input clock at 400Mhz */ |
384 | else | 384 | else |
385 | return 225; /* eDP input clock at 450Mhz */ | 385 | return 225; /* eDP input clock at 450Mhz */ |
386 | } else { | ||
387 | return DIV_ROUND_UP(intel_pch_rawclk(dev), 2); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) | ||
392 | { | ||
393 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
394 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
395 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
396 | |||
397 | if (intel_dig_port->port == PORT_A) { | ||
398 | if (index) | ||
399 | return 0; | ||
400 | return DIV_ROUND_CLOSEST(intel_ddi_get_cdclk_freq(dev_priv), 2000); | ||
386 | } else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { | 401 | } else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { |
387 | /* Workaround for non-ULT HSW */ | 402 | /* Workaround for non-ULT HSW */ |
388 | switch (index) { | 403 | switch (index) { |
@@ -390,13 +405,16 @@ static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp, | |||
390 | case 1: return 72; | 405 | case 1: return 72; |
391 | default: return 0; | 406 | default: return 0; |
392 | } | 407 | } |
393 | } else if (HAS_PCH_SPLIT(dev)) { | 408 | } else { |
394 | return index ? 0 : DIV_ROUND_UP(intel_pch_rawclk(dev), 2); | 409 | return index ? 0 : DIV_ROUND_UP(intel_pch_rawclk(dev), 2); |
395 | } else { | ||
396 | return index ? 0 :intel_hrawclk(dev) / 2; | ||
397 | } | 410 | } |
398 | } | 411 | } |
399 | 412 | ||
413 | static uint32_t vlv_get_aux_clock_divider(struct intel_dp *intel_dp, int index) | ||
414 | { | ||
415 | return index ? 0 : 100; | ||
416 | } | ||
417 | |||
400 | static int | 418 | static int |
401 | intel_dp_aux_ch(struct intel_dp *intel_dp, | 419 | intel_dp_aux_ch(struct intel_dp *intel_dp, |
402 | uint8_t *send, int send_bytes, | 420 | uint8_t *send, int send_bytes, |
@@ -455,7 +473,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
455 | goto out; | 473 | goto out; |
456 | } | 474 | } |
457 | 475 | ||
458 | while ((aux_clock_divider = get_aux_clock_divider(intel_dp, clock++))) { | 476 | while ((aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, clock++))) { |
459 | /* Must try at least 3 times according to DP spec */ | 477 | /* Must try at least 3 times according to DP spec */ |
460 | for (try = 0; try < 5; try++) { | 478 | for (try = 0; try < 5; try++) { |
461 | /* Load the send data into the aux channel data registers */ | 479 | /* Load the send data into the aux channel data registers */ |
@@ -1619,10 +1637,12 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) | |||
1619 | { | 1637 | { |
1620 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1638 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1621 | struct drm_i915_private *dev_priv = dev->dev_private; | 1639 | struct drm_i915_private *dev_priv = dev->dev_private; |
1622 | uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp, 0); | 1640 | uint32_t aux_clock_divider; |
1623 | int precharge = 0x3; | 1641 | int precharge = 0x3; |
1624 | int msg_size = 5; /* Header(4) + Message(1) */ | 1642 | int msg_size = 5; /* Header(4) + Message(1) */ |
1625 | 1643 | ||
1644 | aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); | ||
1645 | |||
1626 | /* Enable PSR in sink */ | 1646 | /* Enable PSR in sink */ |
1627 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) | 1647 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) |
1628 | intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, | 1648 | intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, |
@@ -3679,6 +3699,16 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
3679 | const char *name = NULL; | 3699 | const char *name = NULL; |
3680 | int type, error; | 3700 | int type, error; |
3681 | 3701 | ||
3702 | /* intel_dp vfuncs */ | ||
3703 | if (IS_VALLEYVIEW(dev)) | ||
3704 | intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider; | ||
3705 | else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) | ||
3706 | intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider; | ||
3707 | else if (HAS_PCH_SPLIT(dev)) | ||
3708 | intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider; | ||
3709 | else | ||
3710 | intel_dp->get_aux_clock_divider = i9xx_get_aux_clock_divider; | ||
3711 | |||
3682 | /* Preserve the current hw state. */ | 3712 | /* Preserve the current hw state. */ |
3683 | intel_dp->DP = I915_READ(intel_dp->output_reg); | 3713 | intel_dp->DP = I915_READ(intel_dp->output_reg); |
3684 | intel_dp->attached_connector = intel_connector; | 3714 | intel_dp->attached_connector = intel_connector; |