diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 22:40:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 22:40:34 -0400 |
commit | 20a2078ce7705a6e0722ef5184336eb8657a58d8 (patch) | |
tree | 5b927c96516380aa0ecd68d8a609f7cd72120ad5 /drivers/gpu/drm/i915/intel_pm.c | |
parent | 0279b3c0ada1d78882f24acf94ac4595bd657a89 (diff) | |
parent | 307b9c022720f9de90d58e51743e01e9a42aec59 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"This is the main drm pull request for 3.10.
Wierd bits:
- OMAP drm changes required OMAP dss changes, in drivers/video, so I
took them in here.
- one more fbcon fix for font handover
- VT switch avoidance in pm code
- scatterlist helpers for gpu drivers - have acks from akpm
Highlights:
- qxl kms driver - driver for the spice qxl virtual GPU
Nouveau:
- fermi/kepler VRAM compression
- GK110/nvf0 modesetting support.
Tegra:
- host1x core merged with 2D engine support
i915:
- vt switchless resume
- more valleyview support
- vblank fixes
- modesetting pipe config rework
radeon:
- UVD engine support
- SI chip tiling support
- GPU registers initialisation from golden values.
exynos:
- device tree changes
- fimc block support
Otherwise:
- bunches of fixes all over the place."
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (513 commits)
qxl: update to new idr interfaces.
drm/nouveau: fix build with nv50->nvc0
drm/radeon: fix handling of v6 power tables
drm/radeon: clarify family checks in pm table parsing
drm/radeon: consolidate UVD clock programming
drm/radeon: fix UPLL_REF_DIV_MASK definition
radeon: add bo tracking debugfs
drm/radeon: add new richland pci ids
drm/radeon: add some new SI PCI ids
drm/radeon: fix scratch reg handling for UVD fence
drm/radeon: allocate SA bo in the requested domain
drm/radeon: fix possible segfault when parsing pm tables
drm/radeon: fix endian bugs in atom_allocate_fb_scratch()
OMAPDSS: TFP410: return EPROBE_DEFER if the i2c adapter not found
OMAPDSS: VENC: Add error handling for venc_probe_pdata
OMAPDSS: HDMI: Add error handling for hdmi_probe_pdata
OMAPDSS: RFBI: Add error handling for rfbi_probe_pdata
OMAPDSS: DSI: Add error handling for dsi_probe_pdata
OMAPDSS: SDI: Add error handling for sdi_probe_pdata
OMAPDSS: DPI: Add error handling for dpi_probe_pdata
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 245 |
1 files changed, 177 insertions, 68 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index adca00783e61..de3b0dc5658b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2460,10 +2460,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val) | |||
2460 | if (val == dev_priv->rps.cur_delay) | 2460 | if (val == dev_priv->rps.cur_delay) |
2461 | return; | 2461 | return; |
2462 | 2462 | ||
2463 | I915_WRITE(GEN6_RPNSWREQ, | 2463 | if (IS_HASWELL(dev)) |
2464 | GEN6_FREQUENCY(val) | | 2464 | I915_WRITE(GEN6_RPNSWREQ, |
2465 | GEN6_OFFSET(0) | | 2465 | HSW_FREQUENCY(val)); |
2466 | GEN6_AGGRESSIVE_TURBO); | 2466 | else |
2467 | I915_WRITE(GEN6_RPNSWREQ, | ||
2468 | GEN6_FREQUENCY(val) | | ||
2469 | GEN6_OFFSET(0) | | ||
2470 | GEN6_AGGRESSIVE_TURBO); | ||
2467 | 2471 | ||
2468 | /* Make sure we continue to get interrupts | 2472 | /* Make sure we continue to get interrupts |
2469 | * until we hit the minimum or maximum frequencies. | 2473 | * until we hit the minimum or maximum frequencies. |
@@ -2554,8 +2558,8 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
2554 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | 2558 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
2555 | gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | 2559 | gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); |
2556 | 2560 | ||
2557 | /* In units of 100MHz */ | 2561 | /* In units of 50MHz */ |
2558 | dev_priv->rps.max_delay = rp_state_cap & 0xff; | 2562 | dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff; |
2559 | dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16; | 2563 | dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16; |
2560 | dev_priv->rps.cur_delay = 0; | 2564 | dev_priv->rps.cur_delay = 0; |
2561 | 2565 | ||
@@ -2601,12 +2605,19 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
2601 | GEN6_RC_CTL_EI_MODE(1) | | 2605 | GEN6_RC_CTL_EI_MODE(1) | |
2602 | GEN6_RC_CTL_HW_ENABLE); | 2606 | GEN6_RC_CTL_HW_ENABLE); |
2603 | 2607 | ||
2604 | I915_WRITE(GEN6_RPNSWREQ, | 2608 | if (IS_HASWELL(dev)) { |
2605 | GEN6_FREQUENCY(10) | | 2609 | I915_WRITE(GEN6_RPNSWREQ, |
2606 | GEN6_OFFSET(0) | | 2610 | HSW_FREQUENCY(10)); |
2607 | GEN6_AGGRESSIVE_TURBO); | 2611 | I915_WRITE(GEN6_RC_VIDEO_FREQ, |
2608 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | 2612 | HSW_FREQUENCY(12)); |
2609 | GEN6_FREQUENCY(12)); | 2613 | } else { |
2614 | I915_WRITE(GEN6_RPNSWREQ, | ||
2615 | GEN6_FREQUENCY(10) | | ||
2616 | GEN6_OFFSET(0) | | ||
2617 | GEN6_AGGRESSIVE_TURBO); | ||
2618 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | ||
2619 | GEN6_FREQUENCY(12)); | ||
2620 | } | ||
2610 | 2621 | ||
2611 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); | 2622 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
2612 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | 2623 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, |
@@ -2631,9 +2642,11 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
2631 | if (!ret) { | 2642 | if (!ret) { |
2632 | pcu_mbox = 0; | 2643 | pcu_mbox = 0; |
2633 | ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &pcu_mbox); | 2644 | ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &pcu_mbox); |
2634 | if (ret && pcu_mbox & (1<<31)) { /* OC supported */ | 2645 | if (!ret && (pcu_mbox & (1<<31))) { /* OC supported */ |
2635 | dev_priv->rps.max_delay = pcu_mbox & 0xff; | 2646 | DRM_DEBUG_DRIVER("Overclocking supported. Max: %dMHz, Overclock max: %dMHz\n", |
2636 | DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); | 2647 | (dev_priv->rps.max_delay & 0xff) * 50, |
2648 | (pcu_mbox & 0xff) * 50); | ||
2649 | dev_priv->rps.hw_max = pcu_mbox & 0xff; | ||
2637 | } | 2650 | } |
2638 | } else { | 2651 | } else { |
2639 | DRM_DEBUG_DRIVER("Failed to set the min frequency\n"); | 2652 | DRM_DEBUG_DRIVER("Failed to set the min frequency\n"); |
@@ -2671,8 +2684,8 @@ static void gen6_update_ring_freq(struct drm_device *dev) | |||
2671 | { | 2684 | { |
2672 | struct drm_i915_private *dev_priv = dev->dev_private; | 2685 | struct drm_i915_private *dev_priv = dev->dev_private; |
2673 | int min_freq = 15; | 2686 | int min_freq = 15; |
2674 | int gpu_freq; | 2687 | unsigned int gpu_freq; |
2675 | unsigned int ia_freq, max_ia_freq; | 2688 | unsigned int max_ia_freq, min_ring_freq; |
2676 | int scaling_factor = 180; | 2689 | int scaling_factor = 180; |
2677 | 2690 | ||
2678 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 2691 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
@@ -2688,6 +2701,10 @@ static void gen6_update_ring_freq(struct drm_device *dev) | |||
2688 | /* Convert from kHz to MHz */ | 2701 | /* Convert from kHz to MHz */ |
2689 | max_ia_freq /= 1000; | 2702 | max_ia_freq /= 1000; |
2690 | 2703 | ||
2704 | min_ring_freq = I915_READ(MCHBAR_MIRROR_BASE_SNB + DCLK); | ||
2705 | /* convert DDR frequency from units of 133.3MHz to bandwidth */ | ||
2706 | min_ring_freq = (2 * 4 * min_ring_freq + 2) / 3; | ||
2707 | |||
2691 | /* | 2708 | /* |
2692 | * For each potential GPU frequency, load a ring frequency we'd like | 2709 | * For each potential GPU frequency, load a ring frequency we'd like |
2693 | * to use for memory access. We do this by specifying the IA frequency | 2710 | * to use for memory access. We do this by specifying the IA frequency |
@@ -2696,21 +2713,32 @@ static void gen6_update_ring_freq(struct drm_device *dev) | |||
2696 | for (gpu_freq = dev_priv->rps.max_delay; gpu_freq >= dev_priv->rps.min_delay; | 2713 | for (gpu_freq = dev_priv->rps.max_delay; gpu_freq >= dev_priv->rps.min_delay; |
2697 | gpu_freq--) { | 2714 | gpu_freq--) { |
2698 | int diff = dev_priv->rps.max_delay - gpu_freq; | 2715 | int diff = dev_priv->rps.max_delay - gpu_freq; |
2699 | 2716 | unsigned int ia_freq = 0, ring_freq = 0; | |
2700 | /* | 2717 | |
2701 | * For GPU frequencies less than 750MHz, just use the lowest | 2718 | if (IS_HASWELL(dev)) { |
2702 | * ring freq. | 2719 | ring_freq = (gpu_freq * 5 + 3) / 4; |
2703 | */ | 2720 | ring_freq = max(min_ring_freq, ring_freq); |
2704 | if (gpu_freq < min_freq) | 2721 | /* leave ia_freq as the default, chosen by cpufreq */ |
2705 | ia_freq = 800; | 2722 | } else { |
2706 | else | 2723 | /* On older processors, there is no separate ring |
2707 | ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); | 2724 | * clock domain, so in order to boost the bandwidth |
2708 | ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); | 2725 | * of the ring, we need to upclock the CPU (ia_freq). |
2709 | ia_freq <<= GEN6_PCODE_FREQ_IA_RATIO_SHIFT; | 2726 | * |
2727 | * For GPU frequencies less than 750MHz, | ||
2728 | * just use the lowest ring freq. | ||
2729 | */ | ||
2730 | if (gpu_freq < min_freq) | ||
2731 | ia_freq = 800; | ||
2732 | else | ||
2733 | ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); | ||
2734 | ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); | ||
2735 | } | ||
2710 | 2736 | ||
2711 | sandybridge_pcode_write(dev_priv, | 2737 | sandybridge_pcode_write(dev_priv, |
2712 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE, | 2738 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE, |
2713 | ia_freq | gpu_freq); | 2739 | ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT | |
2740 | ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT | | ||
2741 | gpu_freq); | ||
2714 | } | 2742 | } |
2715 | } | 2743 | } |
2716 | 2744 | ||
@@ -2821,7 +2849,7 @@ static void ironlake_enable_rc6(struct drm_device *dev) | |||
2821 | ret = intel_ring_idle(ring); | 2849 | ret = intel_ring_idle(ring); |
2822 | dev_priv->mm.interruptible = was_interruptible; | 2850 | dev_priv->mm.interruptible = was_interruptible; |
2823 | if (ret) { | 2851 | if (ret) { |
2824 | DRM_ERROR("failed to enable ironlake power power savings\n"); | 2852 | DRM_ERROR("failed to enable ironlake power savings\n"); |
2825 | ironlake_teardown_rc6(dev); | 2853 | ironlake_teardown_rc6(dev); |
2826 | return; | 2854 | return; |
2827 | } | 2855 | } |
@@ -3562,6 +3590,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) | |||
3562 | { | 3590 | { |
3563 | struct drm_i915_private *dev_priv = dev->dev_private; | 3591 | struct drm_i915_private *dev_priv = dev->dev_private; |
3564 | int pipe; | 3592 | int pipe; |
3593 | uint32_t val; | ||
3565 | 3594 | ||
3566 | /* | 3595 | /* |
3567 | * On Ibex Peak and Cougar Point, we need to disable clock | 3596 | * On Ibex Peak and Cougar Point, we need to disable clock |
@@ -3574,8 +3603,17 @@ static void cpt_init_clock_gating(struct drm_device *dev) | |||
3574 | /* The below fixes the weird display corruption, a few pixels shifted | 3603 | /* The below fixes the weird display corruption, a few pixels shifted |
3575 | * downward, on (only) LVDS of some HP laptops with IVY. | 3604 | * downward, on (only) LVDS of some HP laptops with IVY. |
3576 | */ | 3605 | */ |
3577 | for_each_pipe(pipe) | 3606 | for_each_pipe(pipe) { |
3578 | I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE); | 3607 | val = I915_READ(TRANS_CHICKEN2(pipe)); |
3608 | val |= TRANS_CHICKEN2_TIMING_OVERRIDE; | ||
3609 | val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; | ||
3610 | if (dev_priv->fdi_rx_polarity_inverted) | ||
3611 | val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; | ||
3612 | val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; | ||
3613 | val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; | ||
3614 | val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; | ||
3615 | I915_WRITE(TRANS_CHICKEN2(pipe), val); | ||
3616 | } | ||
3579 | /* WADP0ClockGatingDisable */ | 3617 | /* WADP0ClockGatingDisable */ |
3580 | for_each_pipe(pipe) { | 3618 | for_each_pipe(pipe) { |
3581 | I915_WRITE(TRANS_CHICKEN1(pipe), | 3619 | I915_WRITE(TRANS_CHICKEN1(pipe), |
@@ -3768,6 +3806,9 @@ static void haswell_init_clock_gating(struct drm_device *dev) | |||
3768 | I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | | 3806 | I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | |
3769 | GEN6_MBCTL_ENABLE_BOOT_FETCH); | 3807 | GEN6_MBCTL_ENABLE_BOOT_FETCH); |
3770 | 3808 | ||
3809 | /* WaSwitchSolVfFArbitrationPriority */ | ||
3810 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); | ||
3811 | |||
3771 | /* XXX: This is a workaround for early silicon revisions and should be | 3812 | /* XXX: This is a workaround for early silicon revisions and should be |
3772 | * removed later. | 3813 | * removed later. |
3773 | */ | 3814 | */ |
@@ -3874,7 +3915,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
3874 | snpcr |= GEN6_MBC_SNPCR_MED; | 3915 | snpcr |= GEN6_MBC_SNPCR_MED; |
3875 | I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); | 3916 | I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); |
3876 | 3917 | ||
3877 | cpt_init_clock_gating(dev); | 3918 | if (!HAS_PCH_NOP(dev)) |
3919 | cpt_init_clock_gating(dev); | ||
3878 | 3920 | ||
3879 | gen6_check_mch_setup(dev); | 3921 | gen6_check_mch_setup(dev); |
3880 | } | 3922 | } |
@@ -3899,8 +3941,10 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
3899 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | 3941 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
3900 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | 3942 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
3901 | 3943 | ||
3944 | /* WaDisablePSDDualDispatchEnable */ | ||
3902 | I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, | 3945 | I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, |
3903 | _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); | 3946 | _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | |
3947 | GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); | ||
3904 | 3948 | ||
3905 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | 3949 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ |
3906 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | 3950 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, |
@@ -3968,24 +4012,20 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
3968 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | 4012 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
3969 | 4013 | ||
3970 | /* | 4014 | /* |
3971 | * On ValleyView, the GUnit needs to signal the GT | ||
3972 | * when flip and other events complete. So enable | ||
3973 | * all the GUnit->GT interrupts here | ||
3974 | */ | ||
3975 | I915_WRITE(VLV_DPFLIPSTAT, PIPEB_LINE_COMPARE_INT_EN | | ||
3976 | PIPEB_HLINE_INT_EN | PIPEB_VBLANK_INT_EN | | ||
3977 | SPRITED_FLIPDONE_INT_EN | SPRITEC_FLIPDONE_INT_EN | | ||
3978 | PLANEB_FLIPDONE_INT_EN | PIPEA_LINE_COMPARE_INT_EN | | ||
3979 | PIPEA_HLINE_INT_EN | PIPEA_VBLANK_INT_EN | | ||
3980 | SPRITEB_FLIPDONE_INT_EN | SPRITEA_FLIPDONE_INT_EN | | ||
3981 | PLANEA_FLIPDONE_INT_EN); | ||
3982 | |||
3983 | /* | ||
3984 | * WaDisableVLVClockGating_VBIIssue | 4015 | * WaDisableVLVClockGating_VBIIssue |
3985 | * Disable clock gating on th GCFG unit to prevent a delay | 4016 | * Disable clock gating on th GCFG unit to prevent a delay |
3986 | * in the reporting of vblank events. | 4017 | * in the reporting of vblank events. |
3987 | */ | 4018 | */ |
3988 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS); | 4019 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, 0xffffffff); |
4020 | |||
4021 | /* Conservative clock gating settings for now */ | ||
4022 | I915_WRITE(0x9400, 0xffffffff); | ||
4023 | I915_WRITE(0x9404, 0xffffffff); | ||
4024 | I915_WRITE(0x9408, 0xffffffff); | ||
4025 | I915_WRITE(0x940c, 0xffffffff); | ||
4026 | I915_WRITE(0x9410, 0xffffffff); | ||
4027 | I915_WRITE(0x9414, 0xffffffff); | ||
4028 | I915_WRITE(0x9418, 0xffffffff); | ||
3989 | } | 4029 | } |
3990 | 4030 | ||
3991 | static void g4x_init_clock_gating(struct drm_device *dev) | 4031 | static void g4x_init_clock_gating(struct drm_device *dev) |
@@ -4070,13 +4110,29 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4070 | dev_priv->display.init_clock_gating(dev); | 4110 | dev_priv->display.init_clock_gating(dev); |
4071 | } | 4111 | } |
4072 | 4112 | ||
4113 | /** | ||
4114 | * We should only use the power well if we explicitly asked the hardware to | ||
4115 | * enable it, so check if it's enabled and also check if we've requested it to | ||
4116 | * be enabled. | ||
4117 | */ | ||
4118 | bool intel_using_power_well(struct drm_device *dev) | ||
4119 | { | ||
4120 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4121 | |||
4122 | if (IS_HASWELL(dev)) | ||
4123 | return I915_READ(HSW_PWR_WELL_DRIVER) == | ||
4124 | (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE); | ||
4125 | else | ||
4126 | return true; | ||
4127 | } | ||
4128 | |||
4073 | void intel_set_power_well(struct drm_device *dev, bool enable) | 4129 | void intel_set_power_well(struct drm_device *dev, bool enable) |
4074 | { | 4130 | { |
4075 | struct drm_i915_private *dev_priv = dev->dev_private; | 4131 | struct drm_i915_private *dev_priv = dev->dev_private; |
4076 | bool is_enabled, enable_requested; | 4132 | bool is_enabled, enable_requested; |
4077 | uint32_t tmp; | 4133 | uint32_t tmp; |
4078 | 4134 | ||
4079 | if (!IS_HASWELL(dev)) | 4135 | if (!HAS_POWER_WELL(dev)) |
4080 | return; | 4136 | return; |
4081 | 4137 | ||
4082 | if (!i915_disable_power_well && !enable) | 4138 | if (!i915_disable_power_well && !enable) |
@@ -4114,7 +4170,7 @@ void intel_init_power_well(struct drm_device *dev) | |||
4114 | { | 4170 | { |
4115 | struct drm_i915_private *dev_priv = dev->dev_private; | 4171 | struct drm_i915_private *dev_priv = dev->dev_private; |
4116 | 4172 | ||
4117 | if (!IS_HASWELL(dev)) | 4173 | if (!HAS_POWER_WELL(dev)) |
4118 | return; | 4174 | return; |
4119 | 4175 | ||
4120 | /* For now, we need the power well to be always enabled. */ | 4176 | /* For now, we need the power well to be always enabled. */ |
@@ -4176,7 +4232,6 @@ void intel_init_pm(struct drm_device *dev) | |||
4176 | } | 4232 | } |
4177 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; | 4233 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; |
4178 | } else if (IS_IVYBRIDGE(dev)) { | 4234 | } else if (IS_IVYBRIDGE(dev)) { |
4179 | /* FIXME: detect B0+ stepping and use auto training */ | ||
4180 | if (SNB_READ_WM0_LATENCY()) { | 4235 | if (SNB_READ_WM0_LATENCY()) { |
4181 | dev_priv->display.update_wm = ivybridge_update_wm; | 4236 | dev_priv->display.update_wm = ivybridge_update_wm; |
4182 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | 4237 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; |
@@ -4274,21 +4329,14 @@ static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) | |||
4274 | 4329 | ||
4275 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 4330 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
4276 | { | 4331 | { |
4277 | u32 forcewake_ack; | 4332 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, |
4278 | |||
4279 | if (IS_HASWELL(dev_priv->dev)) | ||
4280 | forcewake_ack = FORCEWAKE_ACK_HSW; | ||
4281 | else | ||
4282 | forcewake_ack = FORCEWAKE_ACK; | ||
4283 | |||
4284 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, | ||
4285 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4333 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4286 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); | 4334 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
4287 | 4335 | ||
4288 | I915_WRITE_NOTRACE(FORCEWAKE, FORCEWAKE_KERNEL); | 4336 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
4289 | POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ | 4337 | POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ |
4290 | 4338 | ||
4291 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1), | 4339 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), |
4292 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4340 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4293 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); | 4341 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
4294 | 4342 | ||
@@ -4311,7 +4359,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
4311 | else | 4359 | else |
4312 | forcewake_ack = FORCEWAKE_MT_ACK; | 4360 | forcewake_ack = FORCEWAKE_MT_ACK; |
4313 | 4361 | ||
4314 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, | 4362 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL) == 0, |
4315 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4363 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4316 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); | 4364 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
4317 | 4365 | ||
@@ -4319,7 +4367,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
4319 | /* something from same cacheline, but !FORCEWAKE_MT */ | 4367 | /* something from same cacheline, but !FORCEWAKE_MT */ |
4320 | POSTING_READ(ECOBUS); | 4368 | POSTING_READ(ECOBUS); |
4321 | 4369 | ||
4322 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1), | 4370 | if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL), |
4323 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4371 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4324 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); | 4372 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
4325 | 4373 | ||
@@ -4409,15 +4457,22 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) | |||
4409 | 4457 | ||
4410 | static void vlv_force_wake_get(struct drm_i915_private *dev_priv) | 4458 | static void vlv_force_wake_get(struct drm_i915_private *dev_priv) |
4411 | { | 4459 | { |
4412 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0, | 4460 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, |
4413 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4461 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4414 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); | 4462 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
4415 | 4463 | ||
4416 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); | 4464 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
4465 | I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, | ||
4466 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); | ||
4417 | 4467 | ||
4418 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), | 4468 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), |
4419 | FORCEWAKE_ACK_TIMEOUT_MS)) | 4469 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4420 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); | 4470 | DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n"); |
4471 | |||
4472 | if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_MEDIA_VLV) & | ||
4473 | FORCEWAKE_KERNEL), | ||
4474 | FORCEWAKE_ACK_TIMEOUT_MS)) | ||
4475 | DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); | ||
4421 | 4476 | ||
4422 | __gen6_gt_wait_for_thread_c0(dev_priv); | 4477 | __gen6_gt_wait_for_thread_c0(dev_priv); |
4423 | } | 4478 | } |
@@ -4425,8 +4480,9 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv) | |||
4425 | static void vlv_force_wake_put(struct drm_i915_private *dev_priv) | 4480 | static void vlv_force_wake_put(struct drm_i915_private *dev_priv) |
4426 | { | 4481 | { |
4427 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); | 4482 | I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
4428 | /* something from same cacheline, but !FORCEWAKE_VLV */ | 4483 | I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, |
4429 | POSTING_READ(FORCEWAKE_ACK_VLV); | 4484 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
4485 | /* The below doubles as a POSTING_READ */ | ||
4430 | gen6_gt_check_fifodbg(dev_priv); | 4486 | gen6_gt_check_fifodbg(dev_priv); |
4431 | } | 4487 | } |
4432 | 4488 | ||
@@ -4511,3 +4567,56 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) | |||
4511 | 4567 | ||
4512 | return 0; | 4568 | return 0; |
4513 | } | 4569 | } |
4570 | |||
4571 | static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode, | ||
4572 | u8 addr, u32 *val) | ||
4573 | { | ||
4574 | u32 cmd, devfn, port, be, bar; | ||
4575 | |||
4576 | bar = 0; | ||
4577 | be = 0xf; | ||
4578 | port = IOSF_PORT_PUNIT; | ||
4579 | devfn = PCI_DEVFN(2, 0); | ||
4580 | |||
4581 | cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | | ||
4582 | (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | | ||
4583 | (bar << IOSF_BAR_SHIFT); | ||
4584 | |||
4585 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | ||
4586 | |||
4587 | if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) { | ||
4588 | DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n", | ||
4589 | opcode == PUNIT_OPCODE_REG_READ ? | ||
4590 | "read" : "write"); | ||
4591 | return -EAGAIN; | ||
4592 | } | ||
4593 | |||
4594 | I915_WRITE(VLV_IOSF_ADDR, addr); | ||
4595 | if (opcode == PUNIT_OPCODE_REG_WRITE) | ||
4596 | I915_WRITE(VLV_IOSF_DATA, *val); | ||
4597 | I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); | ||
4598 | |||
4599 | if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, | ||
4600 | 500)) { | ||
4601 | DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", | ||
4602 | opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", | ||
4603 | addr); | ||
4604 | return -ETIMEDOUT; | ||
4605 | } | ||
4606 | |||
4607 | if (opcode == PUNIT_OPCODE_REG_READ) | ||
4608 | *val = I915_READ(VLV_IOSF_DATA); | ||
4609 | I915_WRITE(VLV_IOSF_DATA, 0); | ||
4610 | |||
4611 | return 0; | ||
4612 | } | ||
4613 | |||
4614 | int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) | ||
4615 | { | ||
4616 | return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_READ, addr, val); | ||
4617 | } | ||
4618 | |||
4619 | int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) | ||
4620 | { | ||
4621 | return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val); | ||
4622 | } | ||