diff options
author | Chon Ming Lee <chon.ming.lee@intel.com> | 2014-05-02 07:27:47 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-05-12 13:50:14 -0400 |
commit | 9d556c99ed48ae9aa6e41cb5542f1735bc70c16e (patch) | |
tree | 307d8aa8782b751f63cd9c08b0e0a3fef5ac4965 | |
parent | ef9348c8605264342513f78d6256262886b63eab (diff) |
drm/i915/chv: Add update and enable pll for Cherryview
Added programming PLL for CHV based on "Application note for 1273 CHV
Display phy".
v2: -Break the common lane reset into another patch.
-Break the clock calculation into another patch.
-The changes are based on Ville review.
-Rework based on DPIO register define naming convention change.
-Break the dpio write into few lines to improve readability.
-Correct the udelay during chv_enable_pll.
-clean up some magic numbers with some new define.
-program the afc recal bit which was missed.
v3: Based on Ville review
- minor correction of the bit defination
- add deassert/propagate data lane reset
v4: Corrected the udelay between dclkp enable and pll enable.
Minor comment and better way to clear the TX lane reset.
v5: Squash in fixup from Rafael Barbalho.
[vsyrjala: v6: Polish the defines (Imre)]
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Chon Ming Lee <chon.ming.lee@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 134 |
2 files changed, 202 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 921b48fbf571..816470ea5736 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -681,6 +681,12 @@ enum punit_power_well { | |||
681 | #define _VLV_PCS_DW9_CH1 0x8424 | 681 | #define _VLV_PCS_DW9_CH1 0x8424 |
682 | #define VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1) | 682 | #define VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1) |
683 | 683 | ||
684 | #define _CHV_PCS_DW10_CH0 0x8228 | ||
685 | #define _CHV_PCS_DW10_CH1 0x8428 | ||
686 | #define DPIO_PCS_SWING_CALC_TX0_TX2 (1<<30) | ||
687 | #define DPIO_PCS_SWING_CALC_TX1_TX3 (1<<31) | ||
688 | #define CHV_PCS_DW10(ch) _PORT(ch, _CHV_PCS_DW10_CH0, _CHV_PCS_DW10_CH1) | ||
689 | |||
684 | #define _VLV_PCS_DW11_CH0 0x822c | 690 | #define _VLV_PCS_DW11_CH0 0x822c |
685 | #define _VLV_PCS_DW11_CH1 0x842c | 691 | #define _VLV_PCS_DW11_CH1 0x842c |
686 | #define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1) | 692 | #define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1) |
@@ -699,14 +705,21 @@ enum punit_power_well { | |||
699 | 705 | ||
700 | #define _VLV_TX_DW2_CH0 0x8288 | 706 | #define _VLV_TX_DW2_CH0 0x8288 |
701 | #define _VLV_TX_DW2_CH1 0x8488 | 707 | #define _VLV_TX_DW2_CH1 0x8488 |
708 | #define DPIO_SWING_MARGIN_SHIFT 16 | ||
709 | #define DPIO_SWING_MARGIN_MASK (0xff << DPIO_SWING_MARGIN_SHIFT) | ||
710 | #define DPIO_UNIQ_TRANS_SCALE_SHIFT 8 | ||
702 | #define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1) | 711 | #define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1) |
703 | 712 | ||
704 | #define _VLV_TX_DW3_CH0 0x828c | 713 | #define _VLV_TX_DW3_CH0 0x828c |
705 | #define _VLV_TX_DW3_CH1 0x848c | 714 | #define _VLV_TX_DW3_CH1 0x848c |
715 | /* The following bit for CHV phy */ | ||
716 | #define DPIO_TX_UNIQ_TRANS_SCALE_EN (1<<27) | ||
706 | #define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1) | 717 | #define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1) |
707 | 718 | ||
708 | #define _VLV_TX_DW4_CH0 0x8290 | 719 | #define _VLV_TX_DW4_CH0 0x8290 |
709 | #define _VLV_TX_DW4_CH1 0x8490 | 720 | #define _VLV_TX_DW4_CH1 0x8490 |
721 | #define DPIO_SWING_DEEMPH9P5_SHIFT 24 | ||
722 | #define DPIO_SWING_DEEMPH9P5_MASK (0xff << DPIO_SWING_DEEMPH9P5_SHIFT) | ||
710 | #define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1) | 723 | #define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1) |
711 | 724 | ||
712 | #define _VLV_TX3_DW4_CH0 0x690 | 725 | #define _VLV_TX3_DW4_CH0 0x690 |
@@ -726,6 +739,62 @@ enum punit_power_well { | |||
726 | #define _VLV_TX_DW14_CH1 0x84b8 | 739 | #define _VLV_TX_DW14_CH1 0x84b8 |
727 | #define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1) | 740 | #define VLV_TX_DW14(ch) _PORT(ch, _VLV_TX_DW14_CH0, _VLV_TX_DW14_CH1) |
728 | 741 | ||
742 | /* CHV dpPhy registers */ | ||
743 | #define _CHV_PLL_DW0_CH0 0x8000 | ||
744 | #define _CHV_PLL_DW0_CH1 0x8180 | ||
745 | #define CHV_PLL_DW0(ch) _PIPE(ch, _CHV_PLL_DW0_CH0, _CHV_PLL_DW0_CH1) | ||
746 | |||
747 | #define _CHV_PLL_DW1_CH0 0x8004 | ||
748 | #define _CHV_PLL_DW1_CH1 0x8184 | ||
749 | #define DPIO_CHV_N_DIV_SHIFT 8 | ||
750 | #define DPIO_CHV_M1_DIV_BY_2 (0 << 0) | ||
751 | #define CHV_PLL_DW1(ch) _PIPE(ch, _CHV_PLL_DW1_CH0, _CHV_PLL_DW1_CH1) | ||
752 | |||
753 | #define _CHV_PLL_DW2_CH0 0x8008 | ||
754 | #define _CHV_PLL_DW2_CH1 0x8188 | ||
755 | #define CHV_PLL_DW2(ch) _PIPE(ch, _CHV_PLL_DW2_CH0, _CHV_PLL_DW2_CH1) | ||
756 | |||
757 | #define _CHV_PLL_DW3_CH0 0x800c | ||
758 | #define _CHV_PLL_DW3_CH1 0x818c | ||
759 | #define DPIO_CHV_FRAC_DIV_EN (1 << 16) | ||
760 | #define DPIO_CHV_FIRST_MOD (0 << 8) | ||
761 | #define DPIO_CHV_SECOND_MOD (1 << 8) | ||
762 | #define DPIO_CHV_FEEDFWD_GAIN_SHIFT 0 | ||
763 | #define CHV_PLL_DW3(ch) _PIPE(ch, _CHV_PLL_DW3_CH0, _CHV_PLL_DW3_CH1) | ||
764 | |||
765 | #define _CHV_PLL_DW6_CH0 0x8018 | ||
766 | #define _CHV_PLL_DW6_CH1 0x8198 | ||
767 | #define DPIO_CHV_GAIN_CTRL_SHIFT 16 | ||
768 | #define DPIO_CHV_INT_COEFF_SHIFT 8 | ||
769 | #define DPIO_CHV_PROP_COEFF_SHIFT 0 | ||
770 | #define CHV_PLL_DW6(ch) _PIPE(ch, _CHV_PLL_DW6_CH0, _CHV_PLL_DW6_CH1) | ||
771 | |||
772 | #define _CHV_CMN_DW13_CH0 0x8134 | ||
773 | #define _CHV_CMN_DW0_CH1 0x8080 | ||
774 | #define DPIO_CHV_S1_DIV_SHIFT 21 | ||
775 | #define DPIO_CHV_P1_DIV_SHIFT 13 /* 3 bits */ | ||
776 | #define DPIO_CHV_P2_DIV_SHIFT 8 /* 5 bits */ | ||
777 | #define DPIO_CHV_K_DIV_SHIFT 4 | ||
778 | #define DPIO_PLL_FREQLOCK (1 << 1) | ||
779 | #define DPIO_PLL_LOCK (1 << 0) | ||
780 | #define CHV_CMN_DW13(ch) _PIPE(ch, _CHV_CMN_DW13_CH0, _CHV_CMN_DW0_CH1) | ||
781 | |||
782 | #define _CHV_CMN_DW14_CH0 0x8138 | ||
783 | #define _CHV_CMN_DW1_CH1 0x8084 | ||
784 | #define DPIO_AFC_RECAL (1 << 14) | ||
785 | #define DPIO_DCLKP_EN (1 << 13) | ||
786 | #define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1) | ||
787 | |||
788 | #define CHV_CMN_DW30 0x8178 | ||
789 | #define DPIO_LRC_BYPASS (1 << 3) | ||
790 | |||
791 | #define _TXLANE(ch, lane, offset) ((ch ? 0x2400 : 0) + \ | ||
792 | (lane) * 0x200 + (offset)) | ||
793 | |||
794 | #define CHV_TX_DW11(ch, lane) _TXLANE(ch, lane, 0xac) | ||
795 | #define DPIO_FRC_LATENCY_SHFIT 8 | ||
796 | #define CHV_TX_DW14(ch, lane) _TXLANE(ch, lane, 0xb8) | ||
797 | #define DPIO_UPAR_SHIFT 30 | ||
729 | /* | 798 | /* |
730 | * Fence registers | 799 | * Fence registers |
731 | */ | 800 | */ |
@@ -1415,6 +1484,7 @@ enum punit_power_well { | |||
1415 | #define DPLL_LOCK_VLV (1<<15) | 1484 | #define DPLL_LOCK_VLV (1<<15) |
1416 | #define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) | 1485 | #define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) |
1417 | #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) | 1486 | #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) |
1487 | #define DPLL_SSC_REF_CLOCK_CHV (1<<13) | ||
1418 | #define DPLL_PORTC_READY_MASK (0xf << 4) | 1488 | #define DPLL_PORTC_READY_MASK (0xf << 4) |
1419 | #define DPLL_PORTB_READY_MASK (0xf) | 1489 | #define DPLL_PORTB_READY_MASK (0xf) |
1420 | 1490 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 13330fd7b21c..9bfc271c751f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1555,6 +1555,49 @@ static void vlv_enable_pll(struct intel_crtc *crtc) | |||
1555 | udelay(150); /* wait for warmup */ | 1555 | udelay(150); /* wait for warmup */ |
1556 | } | 1556 | } |
1557 | 1557 | ||
1558 | static void chv_enable_pll(struct intel_crtc *crtc) | ||
1559 | { | ||
1560 | struct drm_device *dev = crtc->base.dev; | ||
1561 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1562 | int pipe = crtc->pipe; | ||
1563 | enum dpio_channel port = vlv_pipe_to_channel(pipe); | ||
1564 | int dpll = DPLL(crtc->pipe); | ||
1565 | u32 tmp; | ||
1566 | |||
1567 | assert_pipe_disabled(dev_priv, crtc->pipe); | ||
1568 | |||
1569 | BUG_ON(!IS_CHERRYVIEW(dev_priv->dev)); | ||
1570 | |||
1571 | mutex_lock(&dev_priv->dpio_lock); | ||
1572 | |||
1573 | /* Enable back the 10bit clock to display controller */ | ||
1574 | tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)); | ||
1575 | tmp |= DPIO_DCLKP_EN; | ||
1576 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp); | ||
1577 | |||
1578 | /* | ||
1579 | * Need to wait > 100ns between dclkp clock enable bit and PLL enable. | ||
1580 | */ | ||
1581 | udelay(1); | ||
1582 | |||
1583 | /* Enable PLL */ | ||
1584 | tmp = I915_READ(dpll); | ||
1585 | tmp |= DPLL_VCO_ENABLE; | ||
1586 | I915_WRITE(dpll, tmp); | ||
1587 | |||
1588 | /* Check PLL is locked */ | ||
1589 | if (wait_for(((I915_READ(dpll) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) | ||
1590 | DRM_ERROR("PLL %d failed to lock\n", pipe); | ||
1591 | |||
1592 | /* Deassert soft data lane reset*/ | ||
1593 | tmp = vlv_dpio_read(dev_priv, pipe, VLV_PCS_DW0(port)); | ||
1594 | tmp |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); | ||
1595 | vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), tmp); | ||
1596 | |||
1597 | |||
1598 | mutex_unlock(&dev_priv->dpio_lock); | ||
1599 | } | ||
1600 | |||
1558 | static void i9xx_enable_pll(struct intel_crtc *crtc) | 1601 | static void i9xx_enable_pll(struct intel_crtc *crtc) |
1559 | { | 1602 | { |
1560 | struct drm_device *dev = crtc->base.dev; | 1603 | struct drm_device *dev = crtc->base.dev; |
@@ -4470,8 +4513,12 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) | |||
4470 | 4513 | ||
4471 | is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); | 4514 | is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); |
4472 | 4515 | ||
4473 | if (!is_dsi) | 4516 | if (!is_dsi) { |
4474 | vlv_enable_pll(intel_crtc); | 4517 | if (IS_CHERRYVIEW(dev)) |
4518 | chv_enable_pll(intel_crtc); | ||
4519 | else | ||
4520 | vlv_enable_pll(intel_crtc); | ||
4521 | } | ||
4475 | 4522 | ||
4476 | for_each_encoder_on_crtc(dev, crtc, encoder) | 4523 | for_each_encoder_on_crtc(dev, crtc, encoder) |
4477 | if (encoder->pre_enable) | 4524 | if (encoder->pre_enable) |
@@ -5326,6 +5373,87 @@ static void vlv_update_pll(struct intel_crtc *crtc) | |||
5326 | mutex_unlock(&dev_priv->dpio_lock); | 5373 | mutex_unlock(&dev_priv->dpio_lock); |
5327 | } | 5374 | } |
5328 | 5375 | ||
5376 | static void chv_update_pll(struct intel_crtc *crtc) | ||
5377 | { | ||
5378 | struct drm_device *dev = crtc->base.dev; | ||
5379 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5380 | int pipe = crtc->pipe; | ||
5381 | int dpll_reg = DPLL(crtc->pipe); | ||
5382 | enum dpio_channel port = vlv_pipe_to_channel(pipe); | ||
5383 | u32 val, loopfilter, intcoeff; | ||
5384 | u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac; | ||
5385 | int refclk; | ||
5386 | |||
5387 | mutex_lock(&dev_priv->dpio_lock); | ||
5388 | |||
5389 | bestn = crtc->config.dpll.n; | ||
5390 | bestm2_frac = crtc->config.dpll.m2 & 0x3fffff; | ||
5391 | bestm1 = crtc->config.dpll.m1; | ||
5392 | bestm2 = crtc->config.dpll.m2 >> 22; | ||
5393 | bestp1 = crtc->config.dpll.p1; | ||
5394 | bestp2 = crtc->config.dpll.p2; | ||
5395 | |||
5396 | /* | ||
5397 | * Enable Refclk and SSC | ||
5398 | */ | ||
5399 | val = I915_READ(dpll_reg); | ||
5400 | val |= (DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV); | ||
5401 | I915_WRITE(dpll_reg, val); | ||
5402 | |||
5403 | /* Propagate soft reset to data lane reset */ | ||
5404 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS_DW0(port)); | ||
5405 | val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); | ||
5406 | vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), val); | ||
5407 | |||
5408 | /* Disable 10bit clock to display controller */ | ||
5409 | val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)); | ||
5410 | val &= ~DPIO_DCLKP_EN; | ||
5411 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val); | ||
5412 | |||
5413 | /* p1 and p2 divider */ | ||
5414 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port), | ||
5415 | 5 << DPIO_CHV_S1_DIV_SHIFT | | ||
5416 | bestp1 << DPIO_CHV_P1_DIV_SHIFT | | ||
5417 | bestp2 << DPIO_CHV_P2_DIV_SHIFT | | ||
5418 | 1 << DPIO_CHV_K_DIV_SHIFT); | ||
5419 | |||
5420 | /* Feedback post-divider - m2 */ | ||
5421 | vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2); | ||
5422 | |||
5423 | /* Feedback refclk divider - n and m1 */ | ||
5424 | vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port), | ||
5425 | DPIO_CHV_M1_DIV_BY_2 | | ||
5426 | 1 << DPIO_CHV_N_DIV_SHIFT); | ||
5427 | |||
5428 | /* M2 fraction division */ | ||
5429 | vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac); | ||
5430 | |||
5431 | /* M2 fraction division enable */ | ||
5432 | vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), | ||
5433 | DPIO_CHV_FRAC_DIV_EN | | ||
5434 | (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT)); | ||
5435 | |||
5436 | /* Loop filter */ | ||
5437 | refclk = i9xx_get_refclk(&crtc->base, 0); | ||
5438 | loopfilter = 5 << DPIO_CHV_PROP_COEFF_SHIFT | | ||
5439 | 2 << DPIO_CHV_GAIN_CTRL_SHIFT; | ||
5440 | if (refclk == 100000) | ||
5441 | intcoeff = 11; | ||
5442 | else if (refclk == 38400) | ||
5443 | intcoeff = 10; | ||
5444 | else | ||
5445 | intcoeff = 9; | ||
5446 | loopfilter |= intcoeff << DPIO_CHV_INT_COEFF_SHIFT; | ||
5447 | vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter); | ||
5448 | |||
5449 | /* AFC Recal */ | ||
5450 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), | ||
5451 | vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) | | ||
5452 | DPIO_AFC_RECAL); | ||
5453 | |||
5454 | mutex_unlock(&dev_priv->dpio_lock); | ||
5455 | } | ||
5456 | |||
5329 | static void i9xx_update_pll(struct intel_crtc *crtc, | 5457 | static void i9xx_update_pll(struct intel_crtc *crtc, |
5330 | intel_clock_t *reduced_clock, | 5458 | intel_clock_t *reduced_clock, |
5331 | int num_connectors) | 5459 | int num_connectors) |
@@ -5709,6 +5837,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5709 | i8xx_update_pll(intel_crtc, | 5837 | i8xx_update_pll(intel_crtc, |
5710 | has_reduced_clock ? &reduced_clock : NULL, | 5838 | has_reduced_clock ? &reduced_clock : NULL, |
5711 | num_connectors); | 5839 | num_connectors); |
5840 | } else if (IS_CHERRYVIEW(dev)) { | ||
5841 | chv_update_pll(intel_crtc); | ||
5712 | } else if (IS_VALLEYVIEW(dev)) { | 5842 | } else if (IS_VALLEYVIEW(dev)) { |
5713 | vlv_update_pll(intel_crtc); | 5843 | vlv_update_pll(intel_crtc); |
5714 | } else { | 5844 | } else { |