diff options
author | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:14:34 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:14:44 -0400 |
commit | d3638ac429ff0e8af81c1bc551cbd8da5c09e3d2 (patch) | |
tree | 061df5c180b5b01d32618ba4542e173764867f22 | |
parent | 4eebf60b7452fbd551fd7dece855ba7825a49cbc (diff) | |
parent | 75067ddecf21271631bc018d2fb23ddd09b66aae (diff) |
Merge tag 'drm-intel-next-fixes-2015-08-16' of git://anongit.freedesktop.org/drm-intel into drm-next
Bunch more fixes for 4.3, most of it skl fallout. It's not quite all yet,
there's still a few more patches pending to enable DDI-E correctly on skl.
Also included the dpms atomic work from Maarten since atomic is just a
pain and not including would cause piles of conflicts right from the
start.
* tag 'drm-intel-next-fixes-2015-08-16' of git://anongit.freedesktop.org/drm-intel: (67 commits)
drm/i915: Per-DDI I_boost override
drm/i915/skl: WaIgnoreDDIAStrap is forever, always init DDI A
drm/i915: fix checksum write for automated test reply
drm/i915: Contain the WA_REG macro
drm/i915: Remove the failed context from the fpriv->context_idr
drm/i915: Report IOMMU enabled status for GPU hangs
drm/i915: Check idle to active before processing CSQ
drm/i915: Set alternate aux for DDI-E
drm/i915: Set power domain for DDI-E
drm/i915: fix stolen bios_reserved checks
drm/i915: Use masked write for Context Status Buffer Pointer
drm/i915/skl WaDisableSbeCacheDispatchPortSharing
drm/i915: Spam less on dp aux send/receive problems
drm/i915: Handle return value in intel_pin_and_fence_fb_obj, v2.
drm/i915: Only update mode related state if a modeset happened.
drm/i915: Remove connectors_active.
drm/i915: Remove connectors_active from intel_dp.c, v2.
drm/i915: Remove connectors_active from sanitization, v2.
drm/i915: Get rid of dpms handling.
drm/i915: Make crtc checking use the atomic state, v2.
...
43 files changed, 2023 insertions, 1436 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 30b3651d642b..9ddf8c6cb887 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
@@ -3982,7 +3982,6 @@ int num_ioctls;</synopsis> | |||
3982 | <title>Interrupt Handling</title> | 3982 | <title>Interrupt Handling</title> |
3983 | !Pdrivers/gpu/drm/i915/i915_irq.c interrupt handling | 3983 | !Pdrivers/gpu/drm/i915/i915_irq.c interrupt handling |
3984 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_init intel_irq_init_hw intel_hpd_init | 3984 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_init intel_irq_init_hw intel_hpd_init |
3985 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_fini | ||
3986 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts | 3985 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts |
3987 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts | 3986 | !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts |
3988 | </sect2> | 3987 | </sect2> |
@@ -4199,6 +4198,23 @@ int num_ioctls;</synopsis> | |||
4199 | !Idrivers/gpu/drm/i915/i915_gem_gtt.c | 4198 | !Idrivers/gpu/drm/i915/i915_gem_gtt.c |
4200 | </sect2> | 4199 | </sect2> |
4201 | <sect2> | 4200 | <sect2> |
4201 | <title>GTT Fences and Swizzling</title> | ||
4202 | !Idrivers/gpu/drm/i915/i915_gem_fence.c | ||
4203 | <sect3> | ||
4204 | <title>Global GTT Fence Handling</title> | ||
4205 | !Pdrivers/gpu/drm/i915/i915_gem_fence.c fence register handling | ||
4206 | </sect3> | ||
4207 | <sect3> | ||
4208 | <title>Hardware Tiling and Swizzling Details</title> | ||
4209 | !Pdrivers/gpu/drm/i915/i915_gem_fence.c tiling swizzling details | ||
4210 | </sect3> | ||
4211 | </sect2> | ||
4212 | <sect2> | ||
4213 | <title>Object Tiling IOCTLs</title> | ||
4214 | !Idrivers/gpu/drm/i915/i915_gem_tiling.c | ||
4215 | !Pdrivers/gpu/drm/i915/i915_gem_tiling.c buffer object tiling | ||
4216 | </sect2> | ||
4217 | <sect2> | ||
4202 | <title>Buffer Object Eviction</title> | 4218 | <title>Buffer Object Eviction</title> |
4203 | <para> | 4219 | <para> |
4204 | This section documents the interface functions for evicting buffer | 4220 | This section documents the interface functions for evicting buffer |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b3d9992f0210..998b4643109f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -6,12 +6,13 @@ | |||
6 | 6 | ||
7 | # core driver code | 7 | # core driver code |
8 | i915-y := i915_drv.o \ | 8 | i915-y := i915_drv.o \ |
9 | i915_irq.o \ | ||
9 | i915_params.o \ | 10 | i915_params.o \ |
10 | i915_suspend.o \ | 11 | i915_suspend.o \ |
11 | i915_sysfs.o \ | 12 | i915_sysfs.o \ |
13 | intel_csr.o \ | ||
12 | intel_pm.o \ | 14 | intel_pm.o \ |
13 | intel_runtime_pm.o \ | 15 | intel_runtime_pm.o |
14 | intel_csr.o | ||
15 | 16 | ||
16 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 17 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
17 | i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o | 18 | i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o |
@@ -20,21 +21,20 @@ i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o | |||
20 | i915-y += i915_cmd_parser.o \ | 21 | i915-y += i915_cmd_parser.o \ |
21 | i915_gem_batch_pool.o \ | 22 | i915_gem_batch_pool.o \ |
22 | i915_gem_context.o \ | 23 | i915_gem_context.o \ |
23 | i915_gem_render_state.o \ | ||
24 | i915_gem_debug.o \ | 24 | i915_gem_debug.o \ |
25 | i915_gem_dmabuf.o \ | 25 | i915_gem_dmabuf.o \ |
26 | i915_gem_evict.o \ | 26 | i915_gem_evict.o \ |
27 | i915_gem_execbuffer.o \ | 27 | i915_gem_execbuffer.o \ |
28 | i915_gem_fence.o \ | ||
28 | i915_gem_gtt.o \ | 29 | i915_gem_gtt.o \ |
29 | i915_gem.o \ | 30 | i915_gem.o \ |
31 | i915_gem_render_state.o \ | ||
30 | i915_gem_shrinker.o \ | 32 | i915_gem_shrinker.o \ |
31 | i915_gem_stolen.o \ | 33 | i915_gem_stolen.o \ |
32 | i915_gem_tiling.o \ | 34 | i915_gem_tiling.o \ |
33 | i915_gem_userptr.o \ | 35 | i915_gem_userptr.o \ |
34 | i915_gpu_error.o \ | 36 | i915_gpu_error.o \ |
35 | i915_irq.o \ | ||
36 | i915_trace_points.o \ | 37 | i915_trace_points.o \ |
37 | intel_hotplug.o \ | ||
38 | intel_lrc.o \ | 38 | intel_lrc.o \ |
39 | intel_mocs.o \ | 39 | intel_mocs.o \ |
40 | intel_ringbuffer.o \ | 40 | intel_ringbuffer.o \ |
@@ -48,11 +48,14 @@ i915-y += intel_renderstate_gen6.o \ | |||
48 | 48 | ||
49 | # modesetting core code | 49 | # modesetting core code |
50 | i915-y += intel_audio.o \ | 50 | i915-y += intel_audio.o \ |
51 | intel_atomic.o \ | ||
52 | intel_atomic_plane.o \ | ||
51 | intel_bios.o \ | 53 | intel_bios.o \ |
52 | intel_display.o \ | 54 | intel_display.o \ |
53 | intel_fbc.o \ | 55 | intel_fbc.o \ |
54 | intel_fifo_underrun.o \ | 56 | intel_fifo_underrun.o \ |
55 | intel_frontbuffer.o \ | 57 | intel_frontbuffer.o \ |
58 | intel_hotplug.o \ | ||
56 | intel_modes.o \ | 59 | intel_modes.o \ |
57 | intel_overlay.o \ | 60 | intel_overlay.o \ |
58 | intel_psr.o \ | 61 | intel_psr.o \ |
@@ -68,15 +71,13 @@ i915-y += dvo_ch7017.o \ | |||
68 | dvo_ns2501.o \ | 71 | dvo_ns2501.o \ |
69 | dvo_sil164.o \ | 72 | dvo_sil164.o \ |
70 | dvo_tfp410.o \ | 73 | dvo_tfp410.o \ |
71 | intel_atomic.o \ | ||
72 | intel_atomic_plane.o \ | ||
73 | intel_crt.o \ | 74 | intel_crt.o \ |
74 | intel_ddi.o \ | 75 | intel_ddi.o \ |
75 | intel_dp.o \ | ||
76 | intel_dp_mst.o \ | 76 | intel_dp_mst.o \ |
77 | intel_dp.o \ | ||
77 | intel_dsi.o \ | 78 | intel_dsi.o \ |
78 | intel_dsi_pll.o \ | ||
79 | intel_dsi_panel_vbt.o \ | 79 | intel_dsi_panel_vbt.o \ |
80 | intel_dsi_pll.o \ | ||
80 | intel_dvo.o \ | 81 | intel_dvo.o \ |
81 | intel_hdmi.o \ | 82 | intel_hdmi.o \ |
82 | intel_i2c.o \ | 83 | intel_i2c.o \ |
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 430571b977db..237ff6884a22 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -151,8 +151,8 @@ static const struct drm_i915_cmd_descriptor render_cmds[] = { | |||
151 | CMD( MI_ARB_ON_OFF, SMI, F, 1, R ), | 151 | CMD( MI_ARB_ON_OFF, SMI, F, 1, R ), |
152 | CMD( MI_PREDICATE, SMI, F, 1, S ), | 152 | CMD( MI_PREDICATE, SMI, F, 1, S ), |
153 | CMD( MI_TOPOLOGY_FILTER, SMI, F, 1, S ), | 153 | CMD( MI_TOPOLOGY_FILTER, SMI, F, 1, S ), |
154 | CMD( MI_DISPLAY_FLIP, SMI, !F, 0xFF, R ), | ||
155 | CMD( MI_SET_APPID, SMI, F, 1, S ), | 154 | CMD( MI_SET_APPID, SMI, F, 1, S ), |
155 | CMD( MI_DISPLAY_FLIP, SMI, !F, 0xFF, R ), | ||
156 | CMD( MI_SET_CONTEXT, SMI, !F, 0xFF, R ), | 156 | CMD( MI_SET_CONTEXT, SMI, !F, 0xFF, R ), |
157 | CMD( MI_URB_CLEAR, SMI, !F, 0xFF, S ), | 157 | CMD( MI_URB_CLEAR, SMI, !F, 0xFF, S ), |
158 | CMD( MI_STORE_DWORD_IMM, SMI, !F, 0x3F, B, | 158 | CMD( MI_STORE_DWORD_IMM, SMI, !F, 0x3F, B, |
@@ -564,7 +564,7 @@ static bool validate_cmds_sorted(struct intel_engine_cs *ring, | |||
564 | 564 | ||
565 | for (j = 0; j < table->count; j++) { | 565 | for (j = 0; j < table->count; j++) { |
566 | const struct drm_i915_cmd_descriptor *desc = | 566 | const struct drm_i915_cmd_descriptor *desc = |
567 | &table->table[i]; | 567 | &table->table[j]; |
568 | u32 curr = desc->cmd.value & desc->cmd.mask; | 568 | u32 curr = desc->cmd.value & desc->cmd.mask; |
569 | 569 | ||
570 | if (curr < previous) { | 570 | if (curr < previous) { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 36fe31875737..33aabc79813b 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -3645,74 +3645,40 @@ static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, | |||
3645 | return 0; | 3645 | return 0; |
3646 | } | 3646 | } |
3647 | 3647 | ||
3648 | static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev) | 3648 | static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev, bool enable) |
3649 | { | 3649 | { |
3650 | struct drm_i915_private *dev_priv = dev->dev_private; | 3650 | struct drm_i915_private *dev_priv = dev->dev_private; |
3651 | struct intel_crtc *crtc = | 3651 | struct intel_crtc *crtc = |
3652 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]); | 3652 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]); |
3653 | struct intel_crtc_state *pipe_config; | 3653 | struct intel_crtc_state *pipe_config; |
3654 | struct drm_atomic_state *state; | ||
3655 | int ret = 0; | ||
3654 | 3656 | ||
3655 | drm_modeset_lock_all(dev); | 3657 | drm_modeset_lock_all(dev); |
3656 | pipe_config = to_intel_crtc_state(crtc->base.state); | 3658 | state = drm_atomic_state_alloc(dev); |
3657 | 3659 | if (!state) { | |
3658 | /* | 3660 | ret = -ENOMEM; |
3659 | * If we use the eDP transcoder we need to make sure that we don't | 3661 | goto out; |
3660 | * bypass the pfit, since otherwise the pipe CRC source won't work. Only | ||
3661 | * relevant on hsw with pipe A when using the always-on power well | ||
3662 | * routing. | ||
3663 | */ | ||
3664 | if (pipe_config->cpu_transcoder == TRANSCODER_EDP && | ||
3665 | !pipe_config->pch_pfit.enabled) { | ||
3666 | bool active = pipe_config->base.active; | ||
3667 | |||
3668 | if (active) { | ||
3669 | intel_crtc_control(&crtc->base, false); | ||
3670 | pipe_config = to_intel_crtc_state(crtc->base.state); | ||
3671 | } | ||
3672 | |||
3673 | pipe_config->pch_pfit.force_thru = true; | ||
3674 | |||
3675 | intel_display_power_get(dev_priv, | ||
3676 | POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A)); | ||
3677 | |||
3678 | if (active) | ||
3679 | intel_crtc_control(&crtc->base, true); | ||
3680 | } | 3662 | } |
3681 | drm_modeset_unlock_all(dev); | ||
3682 | } | ||
3683 | |||
3684 | static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev) | ||
3685 | { | ||
3686 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3687 | struct intel_crtc *crtc = | ||
3688 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]); | ||
3689 | struct intel_crtc_state *pipe_config; | ||
3690 | |||
3691 | drm_modeset_lock_all(dev); | ||
3692 | /* | ||
3693 | * If we use the eDP transcoder we need to make sure that we don't | ||
3694 | * bypass the pfit, since otherwise the pipe CRC source won't work. Only | ||
3695 | * relevant on hsw with pipe A when using the always-on power well | ||
3696 | * routing. | ||
3697 | */ | ||
3698 | pipe_config = to_intel_crtc_state(crtc->base.state); | ||
3699 | if (pipe_config->pch_pfit.force_thru) { | ||
3700 | bool active = pipe_config->base.active; | ||
3701 | |||
3702 | if (active) { | ||
3703 | intel_crtc_control(&crtc->base, false); | ||
3704 | pipe_config = to_intel_crtc_state(crtc->base.state); | ||
3705 | } | ||
3706 | 3663 | ||
3707 | pipe_config->pch_pfit.force_thru = false; | 3664 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(&crtc->base); |
3665 | pipe_config = intel_atomic_get_crtc_state(state, crtc); | ||
3666 | if (IS_ERR(pipe_config)) { | ||
3667 | ret = PTR_ERR(pipe_config); | ||
3668 | goto out; | ||
3669 | } | ||
3708 | 3670 | ||
3709 | intel_display_power_put(dev_priv, | 3671 | pipe_config->pch_pfit.force_thru = enable; |
3710 | POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A)); | 3672 | if (pipe_config->cpu_transcoder == TRANSCODER_EDP && |
3673 | pipe_config->pch_pfit.enabled != enable) | ||
3674 | pipe_config->base.connectors_changed = true; | ||
3711 | 3675 | ||
3712 | if (active) | 3676 | ret = drm_atomic_commit(state); |
3713 | intel_crtc_control(&crtc->base, true); | 3677 | out: |
3714 | } | ||
3715 | drm_modeset_unlock_all(dev); | 3678 | drm_modeset_unlock_all(dev); |
3679 | WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret); | ||
3680 | if (ret) | ||
3681 | drm_atomic_state_free(state); | ||
3716 | } | 3682 | } |
3717 | 3683 | ||
3718 | static int ivb_pipe_crc_ctl_reg(struct drm_device *dev, | 3684 | static int ivb_pipe_crc_ctl_reg(struct drm_device *dev, |
@@ -3732,7 +3698,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_device *dev, | |||
3732 | break; | 3698 | break; |
3733 | case INTEL_PIPE_CRC_SOURCE_PF: | 3699 | case INTEL_PIPE_CRC_SOURCE_PF: |
3734 | if (IS_HASWELL(dev) && pipe == PIPE_A) | 3700 | if (IS_HASWELL(dev) && pipe == PIPE_A) |
3735 | hsw_trans_edp_pipe_A_crc_wa(dev); | 3701 | hsw_trans_edp_pipe_A_crc_wa(dev, true); |
3736 | 3702 | ||
3737 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB; | 3703 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB; |
3738 | break; | 3704 | break; |
@@ -3844,7 +3810,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, | |||
3844 | else if (IS_VALLEYVIEW(dev)) | 3810 | else if (IS_VALLEYVIEW(dev)) |
3845 | vlv_undo_pipe_scramble_reset(dev, pipe); | 3811 | vlv_undo_pipe_scramble_reset(dev, pipe); |
3846 | else if (IS_HASWELL(dev) && pipe == PIPE_A) | 3812 | else if (IS_HASWELL(dev) && pipe == PIPE_A) |
3847 | hsw_undo_trans_edp_pipe_A_crc_wa(dev); | 3813 | hsw_trans_edp_pipe_A_crc_wa(dev, false); |
3848 | 3814 | ||
3849 | hsw_enable_ips(crtc); | 3815 | hsw_enable_ips(crtc); |
3850 | } | 3816 | } |
@@ -4030,24 +3996,14 @@ static ssize_t i915_displayport_test_active_write(struct file *file, | |||
4030 | { | 3996 | { |
4031 | char *input_buffer; | 3997 | char *input_buffer; |
4032 | int status = 0; | 3998 | int status = 0; |
4033 | struct seq_file *m; | ||
4034 | struct drm_device *dev; | 3999 | struct drm_device *dev; |
4035 | struct drm_connector *connector; | 4000 | struct drm_connector *connector; |
4036 | struct list_head *connector_list; | 4001 | struct list_head *connector_list; |
4037 | struct intel_dp *intel_dp; | 4002 | struct intel_dp *intel_dp; |
4038 | int val = 0; | 4003 | int val = 0; |
4039 | 4004 | ||
4040 | m = file->private_data; | 4005 | dev = ((struct seq_file *)file->private_data)->private; |
4041 | if (!m) { | ||
4042 | status = -ENODEV; | ||
4043 | return status; | ||
4044 | } | ||
4045 | dev = m->private; | ||
4046 | 4006 | ||
4047 | if (!dev) { | ||
4048 | status = -ENODEV; | ||
4049 | return status; | ||
4050 | } | ||
4051 | connector_list = &dev->mode_config.connector_list; | 4007 | connector_list = &dev->mode_config.connector_list; |
4052 | 4008 | ||
4053 | if (len == 0) | 4009 | if (len == 0) |
@@ -4071,9 +4027,7 @@ static ssize_t i915_displayport_test_active_write(struct file *file, | |||
4071 | DRM_MODE_CONNECTOR_DisplayPort) | 4027 | DRM_MODE_CONNECTOR_DisplayPort) |
4072 | continue; | 4028 | continue; |
4073 | 4029 | ||
4074 | if (connector->connector_type == | 4030 | if (connector->status == connector_status_connected && |
4075 | DRM_MODE_CONNECTOR_DisplayPort && | ||
4076 | connector->status == connector_status_connected && | ||
4077 | connector->encoder != NULL) { | 4031 | connector->encoder != NULL) { |
4078 | intel_dp = enc_to_intel_dp(connector->encoder); | 4032 | intel_dp = enc_to_intel_dp(connector->encoder); |
4079 | status = kstrtoint(input_buffer, 10, &val); | 4033 | status = kstrtoint(input_buffer, 10, &val); |
@@ -4105,9 +4059,6 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data) | |||
4105 | struct list_head *connector_list = &dev->mode_config.connector_list; | 4059 | struct list_head *connector_list = &dev->mode_config.connector_list; |
4106 | struct intel_dp *intel_dp; | 4060 | struct intel_dp *intel_dp; |
4107 | 4061 | ||
4108 | if (!dev) | ||
4109 | return -ENODEV; | ||
4110 | |||
4111 | list_for_each_entry(connector, connector_list, head) { | 4062 | list_for_each_entry(connector, connector_list, head) { |
4112 | 4063 | ||
4113 | if (connector->connector_type != | 4064 | if (connector->connector_type != |
@@ -4152,9 +4103,6 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data) | |||
4152 | struct list_head *connector_list = &dev->mode_config.connector_list; | 4103 | struct list_head *connector_list = &dev->mode_config.connector_list; |
4153 | struct intel_dp *intel_dp; | 4104 | struct intel_dp *intel_dp; |
4154 | 4105 | ||
4155 | if (!dev) | ||
4156 | return -ENODEV; | ||
4157 | |||
4158 | list_for_each_entry(connector, connector_list, head) { | 4106 | list_for_each_entry(connector, connector_list, head) { |
4159 | 4107 | ||
4160 | if (connector->connector_type != | 4108 | if (connector->connector_type != |
@@ -4194,9 +4142,6 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data) | |||
4194 | struct list_head *connector_list = &dev->mode_config.connector_list; | 4142 | struct list_head *connector_list = &dev->mode_config.connector_list; |
4195 | struct intel_dp *intel_dp; | 4143 | struct intel_dp *intel_dp; |
4196 | 4144 | ||
4197 | if (!dev) | ||
4198 | return -ENODEV; | ||
4199 | |||
4200 | list_for_each_entry(connector, connector_list, head) { | 4145 | list_for_each_entry(connector, connector_list, head) { |
4201 | 4146 | ||
4202 | if (connector->connector_type != | 4147 | if (connector->connector_type != |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b1f9e5561cf2..ab37d1121be8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1274,13 +1274,3 @@ const struct drm_ioctl_desc i915_ioctls[] = { | |||
1274 | }; | 1274 | }; |
1275 | 1275 | ||
1276 | int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); | 1276 | int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); |
1277 | |||
1278 | /* | ||
1279 | * This is really ugly: Because old userspace abused the linux agp interface to | ||
1280 | * manage the gtt, we need to claim that all intel devices are agp. For | ||
1281 | * otherwise the drm core refuses to initialize the agp support code. | ||
1282 | */ | ||
1283 | int i915_driver_device_is_agp(struct drm_device *dev) | ||
1284 | { | ||
1285 | return 1; | ||
1286 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0d6775a3e88c..1d887459e37f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -935,8 +935,6 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
935 | if (PCI_FUNC(pdev->devfn)) | 935 | if (PCI_FUNC(pdev->devfn)) |
936 | return -ENODEV; | 936 | return -ENODEV; |
937 | 937 | ||
938 | driver.driver_features &= ~(DRIVER_USE_AGP); | ||
939 | |||
940 | return drm_get_pci_dev(pdev, ent, &driver); | 938 | return drm_get_pci_dev(pdev, ent, &driver); |
941 | } | 939 | } |
942 | 940 | ||
@@ -1491,7 +1489,15 @@ static int intel_runtime_suspend(struct device *device) | |||
1491 | * FIXME: We really should find a document that references the arguments | 1489 | * FIXME: We really should find a document that references the arguments |
1492 | * used below! | 1490 | * used below! |
1493 | */ | 1491 | */ |
1494 | if (IS_HASWELL(dev)) { | 1492 | if (IS_BROADWELL(dev)) { |
1493 | /* | ||
1494 | * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop | ||
1495 | * being detected, and the call we do at intel_runtime_resume() | ||
1496 | * won't be able to restore them. Since PCI_D3hot matches the | ||
1497 | * actual specification and appears to be working, use it. | ||
1498 | */ | ||
1499 | intel_opregion_notify_adapter(dev, PCI_D3hot); | ||
1500 | } else { | ||
1495 | /* | 1501 | /* |
1496 | * current versions of firmware which depend on this opregion | 1502 | * current versions of firmware which depend on this opregion |
1497 | * notification have repurposed the D1 definition to mean | 1503 | * notification have repurposed the D1 definition to mean |
@@ -1500,16 +1506,6 @@ static int intel_runtime_suspend(struct device *device) | |||
1500 | * the suspend path. | 1506 | * the suspend path. |
1501 | */ | 1507 | */ |
1502 | intel_opregion_notify_adapter(dev, PCI_D1); | 1508 | intel_opregion_notify_adapter(dev, PCI_D1); |
1503 | } else { | ||
1504 | /* | ||
1505 | * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop | ||
1506 | * being detected, and the call we do at intel_runtime_resume() | ||
1507 | * won't be able to restore them. Since PCI_D3hot matches the | ||
1508 | * actual specification and appears to be working, use it. Let's | ||
1509 | * assume the other non-Haswell platforms will stay the same as | ||
1510 | * Broadwell. | ||
1511 | */ | ||
1512 | intel_opregion_notify_adapter(dev, PCI_D3hot); | ||
1513 | } | 1509 | } |
1514 | 1510 | ||
1515 | assert_forcewakes_inactive(dev_priv); | 1511 | assert_forcewakes_inactive(dev_priv); |
@@ -1649,7 +1645,6 @@ static struct drm_driver driver = { | |||
1649 | * deal with them for Intel hardware. | 1645 | * deal with them for Intel hardware. |
1650 | */ | 1646 | */ |
1651 | .driver_features = | 1647 | .driver_features = |
1652 | DRIVER_USE_AGP | | ||
1653 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | | 1648 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | |
1654 | DRIVER_RENDER, | 1649 | DRIVER_RENDER, |
1655 | .load = i915_driver_load, | 1650 | .load = i915_driver_load, |
@@ -1664,7 +1659,6 @@ static struct drm_driver driver = { | |||
1664 | .suspend = i915_suspend_legacy, | 1659 | .suspend = i915_suspend_legacy, |
1665 | .resume = i915_resume_legacy, | 1660 | .resume = i915_resume_legacy, |
1666 | 1661 | ||
1667 | .device_is_agp = i915_driver_device_is_agp, | ||
1668 | #if defined(CONFIG_DEBUG_FS) | 1662 | #if defined(CONFIG_DEBUG_FS) |
1669 | .debugfs_init = i915_debugfs_init, | 1663 | .debugfs_init = i915_debugfs_init, |
1670 | .debugfs_cleanup = i915_debugfs_cleanup, | 1664 | .debugfs_cleanup = i915_debugfs_cleanup, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 574d0f1c26bf..599441beea17 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | #define DRIVER_NAME "i915" | 57 | #define DRIVER_NAME "i915" |
58 | #define DRIVER_DESC "Intel Graphics" | 58 | #define DRIVER_DESC "Intel Graphics" |
59 | #define DRIVER_DATE "20150717" | 59 | #define DRIVER_DATE "20150731" |
60 | 60 | ||
61 | #undef WARN_ON | 61 | #undef WARN_ON |
62 | /* Many gcc seem to no see through this and fall over :( */ | 62 | /* Many gcc seem to no see through this and fall over :( */ |
@@ -206,11 +206,11 @@ enum intel_display_power_domain { | |||
206 | 206 | ||
207 | enum hpd_pin { | 207 | enum hpd_pin { |
208 | HPD_NONE = 0, | 208 | HPD_NONE = 0, |
209 | HPD_PORT_A = HPD_NONE, /* PORT_A is internal */ | ||
210 | HPD_TV = HPD_NONE, /* TV is known to be unreliable */ | 209 | HPD_TV = HPD_NONE, /* TV is known to be unreliable */ |
211 | HPD_CRT, | 210 | HPD_CRT, |
212 | HPD_SDVO_B, | 211 | HPD_SDVO_B, |
213 | HPD_SDVO_C, | 212 | HPD_SDVO_C, |
213 | HPD_PORT_A, | ||
214 | HPD_PORT_B, | 214 | HPD_PORT_B, |
215 | HPD_PORT_C, | 215 | HPD_PORT_C, |
216 | HPD_PORT_D, | 216 | HPD_PORT_D, |
@@ -484,6 +484,7 @@ struct drm_i915_error_state { | |||
484 | struct timeval time; | 484 | struct timeval time; |
485 | 485 | ||
486 | char error_msg[128]; | 486 | char error_msg[128]; |
487 | int iommu; | ||
487 | u32 reset_count; | 488 | u32 reset_count; |
488 | u32 suspend_count; | 489 | u32 suspend_count; |
489 | 490 | ||
@@ -742,7 +743,7 @@ enum csr_state { | |||
742 | 743 | ||
743 | struct intel_csr { | 744 | struct intel_csr { |
744 | const char *fw_path; | 745 | const char *fw_path; |
745 | __be32 *dmc_payload; | 746 | uint32_t *dmc_payload; |
746 | uint32_t dmc_fw_size; | 747 | uint32_t dmc_fw_size; |
747 | uint32_t mmio_count; | 748 | uint32_t mmio_count; |
748 | uint32_t mmioaddr[8]; | 749 | uint32_t mmioaddr[8]; |
@@ -894,6 +895,7 @@ enum fb_op_origin { | |||
894 | ORIGIN_CPU, | 895 | ORIGIN_CPU, |
895 | ORIGIN_CS, | 896 | ORIGIN_CS, |
896 | ORIGIN_FLIP, | 897 | ORIGIN_FLIP, |
898 | ORIGIN_DIRTYFB, | ||
897 | }; | 899 | }; |
898 | 900 | ||
899 | struct i915_fbc { | 901 | struct i915_fbc { |
@@ -1408,6 +1410,11 @@ enum modeset_restore { | |||
1408 | MODESET_SUSPENDED, | 1410 | MODESET_SUSPENDED, |
1409 | }; | 1411 | }; |
1410 | 1412 | ||
1413 | #define DP_AUX_A 0x40 | ||
1414 | #define DP_AUX_B 0x10 | ||
1415 | #define DP_AUX_C 0x20 | ||
1416 | #define DP_AUX_D 0x30 | ||
1417 | |||
1411 | struct ddi_vbt_port_info { | 1418 | struct ddi_vbt_port_info { |
1412 | /* | 1419 | /* |
1413 | * This is an index in the HDMI/DVI DDI buffer translation table. | 1420 | * This is an index in the HDMI/DVI DDI buffer translation table. |
@@ -1420,6 +1427,11 @@ struct ddi_vbt_port_info { | |||
1420 | uint8_t supports_dvi:1; | 1427 | uint8_t supports_dvi:1; |
1421 | uint8_t supports_hdmi:1; | 1428 | uint8_t supports_hdmi:1; |
1422 | uint8_t supports_dp:1; | 1429 | uint8_t supports_dp:1; |
1430 | |||
1431 | uint8_t alternate_aux_channel; | ||
1432 | |||
1433 | uint8_t dp_boost_level; | ||
1434 | uint8_t hdmi_boost_level; | ||
1423 | }; | 1435 | }; |
1424 | 1436 | ||
1425 | enum psr_lines_to_wait { | 1437 | enum psr_lines_to_wait { |
@@ -2610,6 +2622,8 @@ struct i915_params { | |||
2610 | bool reset; | 2622 | bool reset; |
2611 | bool disable_display; | 2623 | bool disable_display; |
2612 | bool disable_vtd_wa; | 2624 | bool disable_vtd_wa; |
2625 | bool enable_guc_submission; | ||
2626 | int guc_log_level; | ||
2613 | int use_mmio_flip; | 2627 | int use_mmio_flip; |
2614 | int mmio_debug; | 2628 | int mmio_debug; |
2615 | bool verbose_state_checks; | 2629 | bool verbose_state_checks; |
@@ -2626,7 +2640,6 @@ extern void i915_driver_preclose(struct drm_device *dev, | |||
2626 | struct drm_file *file); | 2640 | struct drm_file *file); |
2627 | extern void i915_driver_postclose(struct drm_device *dev, | 2641 | extern void i915_driver_postclose(struct drm_device *dev, |
2628 | struct drm_file *file); | 2642 | struct drm_file *file); |
2629 | extern int i915_driver_device_is_agp(struct drm_device * dev); | ||
2630 | #ifdef CONFIG_COMPAT | 2643 | #ifdef CONFIG_COMPAT |
2631 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 2644 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
2632 | unsigned long arg); | 2645 | unsigned long arg); |
@@ -2646,7 +2659,7 @@ void intel_hpd_irq_handler(struct drm_device *dev, u32 pin_mask, u32 long_mask); | |||
2646 | void intel_hpd_init(struct drm_i915_private *dev_priv); | 2659 | void intel_hpd_init(struct drm_i915_private *dev_priv); |
2647 | void intel_hpd_init_work(struct drm_i915_private *dev_priv); | 2660 | void intel_hpd_init_work(struct drm_i915_private *dev_priv); |
2648 | void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); | 2661 | void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); |
2649 | enum port intel_hpd_pin_to_port(enum hpd_pin pin); | 2662 | bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port); |
2650 | 2663 | ||
2651 | /* i915_irq.c */ | 2664 | /* i915_irq.c */ |
2652 | void i915_queue_hangcheck(struct drm_device *dev); | 2665 | void i915_queue_hangcheck(struct drm_device *dev); |
@@ -2758,6 +2771,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, | |||
2758 | const struct drm_i915_gem_object_ops *ops); | 2771 | const struct drm_i915_gem_object_ops *ops); |
2759 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | 2772 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, |
2760 | size_t size); | 2773 | size_t size); |
2774 | struct drm_i915_gem_object *i915_gem_object_create_from_data( | ||
2775 | struct drm_device *dev, const void *data, size_t size); | ||
2761 | void i915_init_vm(struct drm_i915_private *dev_priv, | 2776 | void i915_init_vm(struct drm_i915_private *dev_priv, |
2762 | struct i915_address_space *vm); | 2777 | struct i915_address_space *vm); |
2763 | void i915_gem_free_object(struct drm_gem_object *obj); | 2778 | void i915_gem_free_object(struct drm_gem_object *obj); |
@@ -2864,11 +2879,6 @@ static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req, | |||
2864 | 2879 | ||
2865 | int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); | 2880 | int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); |
2866 | int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); | 2881 | int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); |
2867 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); | ||
2868 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | ||
2869 | |||
2870 | bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj); | ||
2871 | void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj); | ||
2872 | 2882 | ||
2873 | struct drm_i915_gem_request * | 2883 | struct drm_i915_gem_request * |
2874 | i915_gem_find_active_request(struct intel_engine_cs *ring); | 2884 | i915_gem_find_active_request(struct intel_engine_cs *ring); |
@@ -2966,8 +2976,6 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, | |||
2966 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | 2976 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, |
2967 | struct drm_gem_object *gem_obj, int flags); | 2977 | struct drm_gem_object *gem_obj, int flags); |
2968 | 2978 | ||
2969 | void i915_gem_restore_fences(struct drm_device *dev); | ||
2970 | |||
2971 | unsigned long | 2979 | unsigned long |
2972 | i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, | 2980 | i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, |
2973 | const struct i915_ggtt_view *view); | 2981 | const struct i915_ggtt_view *view); |
@@ -3062,6 +3070,19 @@ i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj) | |||
3062 | i915_gem_object_ggtt_unpin_view(obj, &i915_ggtt_view_normal); | 3070 | i915_gem_object_ggtt_unpin_view(obj, &i915_ggtt_view_normal); |
3063 | } | 3071 | } |
3064 | 3072 | ||
3073 | /* i915_gem_fence.c */ | ||
3074 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); | ||
3075 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | ||
3076 | |||
3077 | bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj); | ||
3078 | void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj); | ||
3079 | |||
3080 | void i915_gem_restore_fences(struct drm_device *dev); | ||
3081 | |||
3082 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | ||
3083 | void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); | ||
3084 | void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); | ||
3085 | |||
3065 | /* i915_gem_context.c */ | 3086 | /* i915_gem_context.c */ |
3066 | int __must_check i915_gem_context_init(struct drm_device *dev); | 3087 | int __must_check i915_gem_context_init(struct drm_device *dev); |
3067 | void i915_gem_context_fini(struct drm_device *dev); | 3088 | void i915_gem_context_fini(struct drm_device *dev); |
@@ -3154,10 +3175,6 @@ static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_objec | |||
3154 | obj->tiling_mode != I915_TILING_NONE; | 3175 | obj->tiling_mode != I915_TILING_NONE; |
3155 | } | 3176 | } |
3156 | 3177 | ||
3157 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | ||
3158 | void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); | ||
3159 | void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); | ||
3160 | |||
3161 | /* i915_gem_debug.c */ | 3178 | /* i915_gem_debug.c */ |
3162 | #if WATCH_LISTS | 3179 | #if WATCH_LISTS |
3163 | int i915_verify_lists(struct drm_device *dev); | 3180 | int i915_verify_lists(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d9f2701b4593..84f91bcc12f7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -46,11 +46,6 @@ static void | |||
46 | i915_gem_object_retire__write(struct drm_i915_gem_object *obj); | 46 | i915_gem_object_retire__write(struct drm_i915_gem_object *obj); |
47 | static void | 47 | static void |
48 | i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring); | 48 | i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring); |
49 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | ||
50 | struct drm_i915_gem_object *obj); | ||
51 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | ||
52 | struct drm_i915_fence_reg *fence, | ||
53 | bool enable); | ||
54 | 49 | ||
55 | static bool cpu_cache_is_coherent(struct drm_device *dev, | 50 | static bool cpu_cache_is_coherent(struct drm_device *dev, |
56 | enum i915_cache_level level) | 51 | enum i915_cache_level level) |
@@ -66,18 +61,6 @@ static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) | |||
66 | return obj->pin_display; | 61 | return obj->pin_display; |
67 | } | 62 | } |
68 | 63 | ||
69 | static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) | ||
70 | { | ||
71 | if (obj->tiling_mode) | ||
72 | i915_gem_release_mmap(obj); | ||
73 | |||
74 | /* As we do not have an associated fence register, we will force | ||
75 | * a tiling change if we ever need to acquire one. | ||
76 | */ | ||
77 | obj->fence_dirty = false; | ||
78 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
79 | } | ||
80 | |||
81 | /* some bookkeeping */ | 64 | /* some bookkeeping */ |
82 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | 65 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, |
83 | size_t size) | 66 | size_t size) |
@@ -2402,6 +2385,13 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring) | |||
2402 | if (obj->active) | 2385 | if (obj->active) |
2403 | return; | 2386 | return; |
2404 | 2387 | ||
2388 | /* Bump our place on the bound list to keep it roughly in LRU order | ||
2389 | * so that we don't steal from recently used but inactive objects | ||
2390 | * (unless we are forced to ofc!) | ||
2391 | */ | ||
2392 | list_move_tail(&obj->global_list, | ||
2393 | &to_i915(obj->base.dev)->mm.bound_list); | ||
2394 | |||
2405 | list_for_each_entry(vma, &obj->vma_list, vma_link) { | 2395 | list_for_each_entry(vma, &obj->vma_list, vma_link) { |
2406 | if (!list_empty(&vma->mm_list)) | 2396 | if (!list_empty(&vma->mm_list)) |
2407 | list_move_tail(&vma->mm_list, &vma->vm->inactive_list); | 2397 | list_move_tail(&vma->mm_list, &vma->vm->inactive_list); |
@@ -2793,27 +2783,6 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | |||
2793 | } | 2783 | } |
2794 | } | 2784 | } |
2795 | 2785 | ||
2796 | void i915_gem_restore_fences(struct drm_device *dev) | ||
2797 | { | ||
2798 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2799 | int i; | ||
2800 | |||
2801 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | ||
2802 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | ||
2803 | |||
2804 | /* | ||
2805 | * Commit delayed tiling changes if we have an object still | ||
2806 | * attached to the fence, otherwise just clear the fence. | ||
2807 | */ | ||
2808 | if (reg->obj) { | ||
2809 | i915_gem_object_update_fence(reg->obj, reg, | ||
2810 | reg->obj->tiling_mode); | ||
2811 | } else { | ||
2812 | i915_gem_write_fence(dev, i, NULL); | ||
2813 | } | ||
2814 | } | ||
2815 | } | ||
2816 | |||
2817 | void i915_gem_reset(struct drm_device *dev) | 2786 | void i915_gem_reset(struct drm_device *dev) |
2818 | { | 2787 | { |
2819 | struct drm_i915_private *dev_priv = dev->dev_private; | 2788 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3340,343 +3309,6 @@ int i915_gpu_idle(struct drm_device *dev) | |||
3340 | return 0; | 3309 | return 0; |
3341 | } | 3310 | } |
3342 | 3311 | ||
3343 | static void i965_write_fence_reg(struct drm_device *dev, int reg, | ||
3344 | struct drm_i915_gem_object *obj) | ||
3345 | { | ||
3346 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3347 | int fence_reg; | ||
3348 | int fence_pitch_shift; | ||
3349 | |||
3350 | if (INTEL_INFO(dev)->gen >= 6) { | ||
3351 | fence_reg = FENCE_REG_SANDYBRIDGE_0; | ||
3352 | fence_pitch_shift = SANDYBRIDGE_FENCE_PITCH_SHIFT; | ||
3353 | } else { | ||
3354 | fence_reg = FENCE_REG_965_0; | ||
3355 | fence_pitch_shift = I965_FENCE_PITCH_SHIFT; | ||
3356 | } | ||
3357 | |||
3358 | fence_reg += reg * 8; | ||
3359 | |||
3360 | /* To w/a incoherency with non-atomic 64-bit register updates, | ||
3361 | * we split the 64-bit update into two 32-bit writes. In order | ||
3362 | * for a partial fence not to be evaluated between writes, we | ||
3363 | * precede the update with write to turn off the fence register, | ||
3364 | * and only enable the fence as the last step. | ||
3365 | * | ||
3366 | * For extra levels of paranoia, we make sure each step lands | ||
3367 | * before applying the next step. | ||
3368 | */ | ||
3369 | I915_WRITE(fence_reg, 0); | ||
3370 | POSTING_READ(fence_reg); | ||
3371 | |||
3372 | if (obj) { | ||
3373 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
3374 | uint64_t val; | ||
3375 | |||
3376 | /* Adjust fence size to match tiled area */ | ||
3377 | if (obj->tiling_mode != I915_TILING_NONE) { | ||
3378 | uint32_t row_size = obj->stride * | ||
3379 | (obj->tiling_mode == I915_TILING_Y ? 32 : 8); | ||
3380 | size = (size / row_size) * row_size; | ||
3381 | } | ||
3382 | |||
3383 | val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & | ||
3384 | 0xfffff000) << 32; | ||
3385 | val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; | ||
3386 | val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift; | ||
3387 | if (obj->tiling_mode == I915_TILING_Y) | ||
3388 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | ||
3389 | val |= I965_FENCE_REG_VALID; | ||
3390 | |||
3391 | I915_WRITE(fence_reg + 4, val >> 32); | ||
3392 | POSTING_READ(fence_reg + 4); | ||
3393 | |||
3394 | I915_WRITE(fence_reg + 0, val); | ||
3395 | POSTING_READ(fence_reg); | ||
3396 | } else { | ||
3397 | I915_WRITE(fence_reg + 4, 0); | ||
3398 | POSTING_READ(fence_reg + 4); | ||
3399 | } | ||
3400 | } | ||
3401 | |||
3402 | static void i915_write_fence_reg(struct drm_device *dev, int reg, | ||
3403 | struct drm_i915_gem_object *obj) | ||
3404 | { | ||
3405 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3406 | u32 val; | ||
3407 | |||
3408 | if (obj) { | ||
3409 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
3410 | int pitch_val; | ||
3411 | int tile_width; | ||
3412 | |||
3413 | WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) || | ||
3414 | (size & -size) != size || | ||
3415 | (i915_gem_obj_ggtt_offset(obj) & (size - 1)), | ||
3416 | "object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", | ||
3417 | i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size); | ||
3418 | |||
3419 | if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | ||
3420 | tile_width = 128; | ||
3421 | else | ||
3422 | tile_width = 512; | ||
3423 | |||
3424 | /* Note: pitch better be a power of two tile widths */ | ||
3425 | pitch_val = obj->stride / tile_width; | ||
3426 | pitch_val = ffs(pitch_val) - 1; | ||
3427 | |||
3428 | val = i915_gem_obj_ggtt_offset(obj); | ||
3429 | if (obj->tiling_mode == I915_TILING_Y) | ||
3430 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
3431 | val |= I915_FENCE_SIZE_BITS(size); | ||
3432 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
3433 | val |= I830_FENCE_REG_VALID; | ||
3434 | } else | ||
3435 | val = 0; | ||
3436 | |||
3437 | if (reg < 8) | ||
3438 | reg = FENCE_REG_830_0 + reg * 4; | ||
3439 | else | ||
3440 | reg = FENCE_REG_945_8 + (reg - 8) * 4; | ||
3441 | |||
3442 | I915_WRITE(reg, val); | ||
3443 | POSTING_READ(reg); | ||
3444 | } | ||
3445 | |||
3446 | static void i830_write_fence_reg(struct drm_device *dev, int reg, | ||
3447 | struct drm_i915_gem_object *obj) | ||
3448 | { | ||
3449 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3450 | uint32_t val; | ||
3451 | |||
3452 | if (obj) { | ||
3453 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
3454 | uint32_t pitch_val; | ||
3455 | |||
3456 | WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) || | ||
3457 | (size & -size) != size || | ||
3458 | (i915_gem_obj_ggtt_offset(obj) & (size - 1)), | ||
3459 | "object 0x%08lx not 512K or pot-size 0x%08x aligned\n", | ||
3460 | i915_gem_obj_ggtt_offset(obj), size); | ||
3461 | |||
3462 | pitch_val = obj->stride / 128; | ||
3463 | pitch_val = ffs(pitch_val) - 1; | ||
3464 | |||
3465 | val = i915_gem_obj_ggtt_offset(obj); | ||
3466 | if (obj->tiling_mode == I915_TILING_Y) | ||
3467 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
3468 | val |= I830_FENCE_SIZE_BITS(size); | ||
3469 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
3470 | val |= I830_FENCE_REG_VALID; | ||
3471 | } else | ||
3472 | val = 0; | ||
3473 | |||
3474 | I915_WRITE(FENCE_REG_830_0 + reg * 4, val); | ||
3475 | POSTING_READ(FENCE_REG_830_0 + reg * 4); | ||
3476 | } | ||
3477 | |||
3478 | inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj) | ||
3479 | { | ||
3480 | return obj && obj->base.read_domains & I915_GEM_DOMAIN_GTT; | ||
3481 | } | ||
3482 | |||
3483 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | ||
3484 | struct drm_i915_gem_object *obj) | ||
3485 | { | ||
3486 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3487 | |||
3488 | /* Ensure that all CPU reads are completed before installing a fence | ||
3489 | * and all writes before removing the fence. | ||
3490 | */ | ||
3491 | if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj)) | ||
3492 | mb(); | ||
3493 | |||
3494 | WARN(obj && (!obj->stride || !obj->tiling_mode), | ||
3495 | "bogus fence setup with stride: 0x%x, tiling mode: %i\n", | ||
3496 | obj->stride, obj->tiling_mode); | ||
3497 | |||
3498 | if (IS_GEN2(dev)) | ||
3499 | i830_write_fence_reg(dev, reg, obj); | ||
3500 | else if (IS_GEN3(dev)) | ||
3501 | i915_write_fence_reg(dev, reg, obj); | ||
3502 | else if (INTEL_INFO(dev)->gen >= 4) | ||
3503 | i965_write_fence_reg(dev, reg, obj); | ||
3504 | |||
3505 | /* And similarly be paranoid that no direct access to this region | ||
3506 | * is reordered to before the fence is installed. | ||
3507 | */ | ||
3508 | if (i915_gem_object_needs_mb(obj)) | ||
3509 | mb(); | ||
3510 | } | ||
3511 | |||
3512 | static inline int fence_number(struct drm_i915_private *dev_priv, | ||
3513 | struct drm_i915_fence_reg *fence) | ||
3514 | { | ||
3515 | return fence - dev_priv->fence_regs; | ||
3516 | } | ||
3517 | |||
3518 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | ||
3519 | struct drm_i915_fence_reg *fence, | ||
3520 | bool enable) | ||
3521 | { | ||
3522 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
3523 | int reg = fence_number(dev_priv, fence); | ||
3524 | |||
3525 | i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); | ||
3526 | |||
3527 | if (enable) { | ||
3528 | obj->fence_reg = reg; | ||
3529 | fence->obj = obj; | ||
3530 | list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); | ||
3531 | } else { | ||
3532 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
3533 | fence->obj = NULL; | ||
3534 | list_del_init(&fence->lru_list); | ||
3535 | } | ||
3536 | obj->fence_dirty = false; | ||
3537 | } | ||
3538 | |||
3539 | static int | ||
3540 | i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) | ||
3541 | { | ||
3542 | if (obj->last_fenced_req) { | ||
3543 | int ret = i915_wait_request(obj->last_fenced_req); | ||
3544 | if (ret) | ||
3545 | return ret; | ||
3546 | |||
3547 | i915_gem_request_assign(&obj->last_fenced_req, NULL); | ||
3548 | } | ||
3549 | |||
3550 | return 0; | ||
3551 | } | ||
3552 | |||
3553 | int | ||
3554 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | ||
3555 | { | ||
3556 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
3557 | struct drm_i915_fence_reg *fence; | ||
3558 | int ret; | ||
3559 | |||
3560 | ret = i915_gem_object_wait_fence(obj); | ||
3561 | if (ret) | ||
3562 | return ret; | ||
3563 | |||
3564 | if (obj->fence_reg == I915_FENCE_REG_NONE) | ||
3565 | return 0; | ||
3566 | |||
3567 | fence = &dev_priv->fence_regs[obj->fence_reg]; | ||
3568 | |||
3569 | if (WARN_ON(fence->pin_count)) | ||
3570 | return -EBUSY; | ||
3571 | |||
3572 | i915_gem_object_fence_lost(obj); | ||
3573 | i915_gem_object_update_fence(obj, fence, false); | ||
3574 | |||
3575 | return 0; | ||
3576 | } | ||
3577 | |||
3578 | static struct drm_i915_fence_reg * | ||
3579 | i915_find_fence_reg(struct drm_device *dev) | ||
3580 | { | ||
3581 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3582 | struct drm_i915_fence_reg *reg, *avail; | ||
3583 | int i; | ||
3584 | |||
3585 | /* First try to find a free reg */ | ||
3586 | avail = NULL; | ||
3587 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | ||
3588 | reg = &dev_priv->fence_regs[i]; | ||
3589 | if (!reg->obj) | ||
3590 | return reg; | ||
3591 | |||
3592 | if (!reg->pin_count) | ||
3593 | avail = reg; | ||
3594 | } | ||
3595 | |||
3596 | if (avail == NULL) | ||
3597 | goto deadlock; | ||
3598 | |||
3599 | /* None available, try to steal one or wait for a user to finish */ | ||
3600 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { | ||
3601 | if (reg->pin_count) | ||
3602 | continue; | ||
3603 | |||
3604 | return reg; | ||
3605 | } | ||
3606 | |||
3607 | deadlock: | ||
3608 | /* Wait for completion of pending flips which consume fences */ | ||
3609 | if (intel_has_pending_fb_unpin(dev)) | ||
3610 | return ERR_PTR(-EAGAIN); | ||
3611 | |||
3612 | return ERR_PTR(-EDEADLK); | ||
3613 | } | ||
3614 | |||
3615 | /** | ||
3616 | * i915_gem_object_get_fence - set up fencing for an object | ||
3617 | * @obj: object to map through a fence reg | ||
3618 | * | ||
3619 | * When mapping objects through the GTT, userspace wants to be able to write | ||
3620 | * to them without having to worry about swizzling if the object is tiled. | ||
3621 | * This function walks the fence regs looking for a free one for @obj, | ||
3622 | * stealing one if it can't find any. | ||
3623 | * | ||
3624 | * It then sets up the reg based on the object's properties: address, pitch | ||
3625 | * and tiling format. | ||
3626 | * | ||
3627 | * For an untiled surface, this removes any existing fence. | ||
3628 | */ | ||
3629 | int | ||
3630 | i915_gem_object_get_fence(struct drm_i915_gem_object *obj) | ||
3631 | { | ||
3632 | struct drm_device *dev = obj->base.dev; | ||
3633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3634 | bool enable = obj->tiling_mode != I915_TILING_NONE; | ||
3635 | struct drm_i915_fence_reg *reg; | ||
3636 | int ret; | ||
3637 | |||
3638 | /* Have we updated the tiling parameters upon the object and so | ||
3639 | * will need to serialise the write to the associated fence register? | ||
3640 | */ | ||
3641 | if (obj->fence_dirty) { | ||
3642 | ret = i915_gem_object_wait_fence(obj); | ||
3643 | if (ret) | ||
3644 | return ret; | ||
3645 | } | ||
3646 | |||
3647 | /* Just update our place in the LRU if our fence is getting reused. */ | ||
3648 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
3649 | reg = &dev_priv->fence_regs[obj->fence_reg]; | ||
3650 | if (!obj->fence_dirty) { | ||
3651 | list_move_tail(®->lru_list, | ||
3652 | &dev_priv->mm.fence_list); | ||
3653 | return 0; | ||
3654 | } | ||
3655 | } else if (enable) { | ||
3656 | if (WARN_ON(!obj->map_and_fenceable)) | ||
3657 | return -EINVAL; | ||
3658 | |||
3659 | reg = i915_find_fence_reg(dev); | ||
3660 | if (IS_ERR(reg)) | ||
3661 | return PTR_ERR(reg); | ||
3662 | |||
3663 | if (reg->obj) { | ||
3664 | struct drm_i915_gem_object *old = reg->obj; | ||
3665 | |||
3666 | ret = i915_gem_object_wait_fence(old); | ||
3667 | if (ret) | ||
3668 | return ret; | ||
3669 | |||
3670 | i915_gem_object_fence_lost(old); | ||
3671 | } | ||
3672 | } else | ||
3673 | return 0; | ||
3674 | |||
3675 | i915_gem_object_update_fence(obj, reg, enable); | ||
3676 | |||
3677 | return 0; | ||
3678 | } | ||
3679 | |||
3680 | static bool i915_gem_valid_gtt_space(struct i915_vma *vma, | 3312 | static bool i915_gem_valid_gtt_space(struct i915_vma *vma, |
3681 | unsigned long cache_level) | 3313 | unsigned long cache_level) |
3682 | { | 3314 | { |
@@ -4476,32 +4108,6 @@ i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj, | |||
4476 | --vma->pin_count; | 4108 | --vma->pin_count; |
4477 | } | 4109 | } |
4478 | 4110 | ||
4479 | bool | ||
4480 | i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) | ||
4481 | { | ||
4482 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
4483 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
4484 | struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj); | ||
4485 | |||
4486 | WARN_ON(!ggtt_vma || | ||
4487 | dev_priv->fence_regs[obj->fence_reg].pin_count > | ||
4488 | ggtt_vma->pin_count); | ||
4489 | dev_priv->fence_regs[obj->fence_reg].pin_count++; | ||
4490 | return true; | ||
4491 | } else | ||
4492 | return false; | ||
4493 | } | ||
4494 | |||
4495 | void | ||
4496 | i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | ||
4497 | { | ||
4498 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
4499 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
4500 | WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0); | ||
4501 | dev_priv->fence_regs[obj->fence_reg].pin_count--; | ||
4502 | } | ||
4503 | } | ||
4504 | |||
4505 | int | 4111 | int |
4506 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, | 4112 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, |
4507 | struct drm_file *file) | 4113 | struct drm_file *file) |
@@ -5477,3 +5083,43 @@ bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) | |||
5477 | 5083 | ||
5478 | return false; | 5084 | return false; |
5479 | } | 5085 | } |
5086 | |||
5087 | /* Allocate a new GEM object and fill it with the supplied data */ | ||
5088 | struct drm_i915_gem_object * | ||
5089 | i915_gem_object_create_from_data(struct drm_device *dev, | ||
5090 | const void *data, size_t size) | ||
5091 | { | ||
5092 | struct drm_i915_gem_object *obj; | ||
5093 | struct sg_table *sg; | ||
5094 | size_t bytes; | ||
5095 | int ret; | ||
5096 | |||
5097 | obj = i915_gem_alloc_object(dev, round_up(size, PAGE_SIZE)); | ||
5098 | if (IS_ERR_OR_NULL(obj)) | ||
5099 | return obj; | ||
5100 | |||
5101 | ret = i915_gem_object_set_to_cpu_domain(obj, true); | ||
5102 | if (ret) | ||
5103 | goto fail; | ||
5104 | |||
5105 | ret = i915_gem_object_get_pages(obj); | ||
5106 | if (ret) | ||
5107 | goto fail; | ||
5108 | |||
5109 | i915_gem_object_pin_pages(obj); | ||
5110 | sg = obj->pages; | ||
5111 | bytes = sg_copy_from_buffer(sg->sgl, sg->nents, (void *)data, size); | ||
5112 | i915_gem_object_unpin_pages(obj); | ||
5113 | |||
5114 | if (WARN_ON(bytes != size)) { | ||
5115 | DRM_ERROR("Incomplete copy, wrote %zu of %zu", bytes, size); | ||
5116 | ret = -EFAULT; | ||
5117 | goto fail; | ||
5118 | } | ||
5119 | |||
5120 | return obj; | ||
5121 | |||
5122 | fail: | ||
5123 | drm_gem_object_unreference(&obj->base); | ||
5124 | return ERR_PTR(ret); | ||
5125 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index b77a8f78c35a..8e893b354bcc 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -287,6 +287,7 @@ err_unpin: | |||
287 | if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) | 287 | if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) |
288 | i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); | 288 | i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); |
289 | err_destroy: | 289 | err_destroy: |
290 | idr_remove(&file_priv->context_idr, ctx->user_handle); | ||
290 | i915_gem_context_unreference(ctx); | 291 | i915_gem_context_unreference(ctx); |
291 | return ERR_PTR(ret); | 292 | return ERR_PTR(ret); |
292 | } | 293 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c new file mode 100644 index 000000000000..af1f8c461060 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_fence.c | |||
@@ -0,0 +1,787 @@ | |||
1 | /* | ||
2 | * Copyright © 2008-2015 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | */ | ||
23 | |||
24 | #include <drm/drmP.h> | ||
25 | #include <drm/i915_drm.h> | ||
26 | #include "i915_drv.h" | ||
27 | |||
28 | /** | ||
29 | * DOC: fence register handling | ||
30 | * | ||
31 | * Important to avoid confusions: "fences" in the i915 driver are not execution | ||
32 | * fences used to track command completion but hardware detiler objects which | ||
33 | * wrap a given range of the global GTT. Each platform has only a fairly limited | ||
34 | * set of these objects. | ||
35 | * | ||
36 | * Fences are used to detile GTT memory mappings. They're also connected to the | ||
37 | * hardware frontbuffer render tracking and hence interract with frontbuffer | ||
38 | * conmpression. Furthermore on older platforms fences are required for tiled | ||
39 | * objects used by the display engine. They can also be used by the render | ||
40 | * engine - they're required for blitter commands and are optional for render | ||
41 | * commands. But on gen4+ both display (with the exception of fbc) and rendering | ||
42 | * have their own tiling state bits and don't need fences. | ||
43 | * | ||
44 | * Also note that fences only support X and Y tiling and hence can't be used for | ||
45 | * the fancier new tiling formats like W, Ys and Yf. | ||
46 | * | ||
47 | * Finally note that because fences are such a restricted resource they're | ||
48 | * dynamically associated with objects. Furthermore fence state is committed to | ||
49 | * the hardware lazily to avoid unecessary stalls on gen2/3. Therefore code must | ||
50 | * explictly call i915_gem_object_get_fence() to synchronize fencing status | ||
51 | * for cpu access. Also note that some code wants an unfenced view, for those | ||
52 | * cases the fence can be removed forcefully with i915_gem_object_put_fence(). | ||
53 | * | ||
54 | * Internally these functions will synchronize with userspace access by removing | ||
55 | * CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed. | ||
56 | */ | ||
57 | |||
58 | static void i965_write_fence_reg(struct drm_device *dev, int reg, | ||
59 | struct drm_i915_gem_object *obj) | ||
60 | { | ||
61 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
62 | int fence_reg; | ||
63 | int fence_pitch_shift; | ||
64 | |||
65 | if (INTEL_INFO(dev)->gen >= 6) { | ||
66 | fence_reg = FENCE_REG_SANDYBRIDGE_0; | ||
67 | fence_pitch_shift = SANDYBRIDGE_FENCE_PITCH_SHIFT; | ||
68 | } else { | ||
69 | fence_reg = FENCE_REG_965_0; | ||
70 | fence_pitch_shift = I965_FENCE_PITCH_SHIFT; | ||
71 | } | ||
72 | |||
73 | fence_reg += reg * 8; | ||
74 | |||
75 | /* To w/a incoherency with non-atomic 64-bit register updates, | ||
76 | * we split the 64-bit update into two 32-bit writes. In order | ||
77 | * for a partial fence not to be evaluated between writes, we | ||
78 | * precede the update with write to turn off the fence register, | ||
79 | * and only enable the fence as the last step. | ||
80 | * | ||
81 | * For extra levels of paranoia, we make sure each step lands | ||
82 | * before applying the next step. | ||
83 | */ | ||
84 | I915_WRITE(fence_reg, 0); | ||
85 | POSTING_READ(fence_reg); | ||
86 | |||
87 | if (obj) { | ||
88 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
89 | uint64_t val; | ||
90 | |||
91 | /* Adjust fence size to match tiled area */ | ||
92 | if (obj->tiling_mode != I915_TILING_NONE) { | ||
93 | uint32_t row_size = obj->stride * | ||
94 | (obj->tiling_mode == I915_TILING_Y ? 32 : 8); | ||
95 | size = (size / row_size) * row_size; | ||
96 | } | ||
97 | |||
98 | val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & | ||
99 | 0xfffff000) << 32; | ||
100 | val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; | ||
101 | val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift; | ||
102 | if (obj->tiling_mode == I915_TILING_Y) | ||
103 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | ||
104 | val |= I965_FENCE_REG_VALID; | ||
105 | |||
106 | I915_WRITE(fence_reg + 4, val >> 32); | ||
107 | POSTING_READ(fence_reg + 4); | ||
108 | |||
109 | I915_WRITE(fence_reg + 0, val); | ||
110 | POSTING_READ(fence_reg); | ||
111 | } else { | ||
112 | I915_WRITE(fence_reg + 4, 0); | ||
113 | POSTING_READ(fence_reg + 4); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | static void i915_write_fence_reg(struct drm_device *dev, int reg, | ||
118 | struct drm_i915_gem_object *obj) | ||
119 | { | ||
120 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
121 | u32 val; | ||
122 | |||
123 | if (obj) { | ||
124 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
125 | int pitch_val; | ||
126 | int tile_width; | ||
127 | |||
128 | WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) || | ||
129 | (size & -size) != size || | ||
130 | (i915_gem_obj_ggtt_offset(obj) & (size - 1)), | ||
131 | "object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", | ||
132 | i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size); | ||
133 | |||
134 | if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | ||
135 | tile_width = 128; | ||
136 | else | ||
137 | tile_width = 512; | ||
138 | |||
139 | /* Note: pitch better be a power of two tile widths */ | ||
140 | pitch_val = obj->stride / tile_width; | ||
141 | pitch_val = ffs(pitch_val) - 1; | ||
142 | |||
143 | val = i915_gem_obj_ggtt_offset(obj); | ||
144 | if (obj->tiling_mode == I915_TILING_Y) | ||
145 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
146 | val |= I915_FENCE_SIZE_BITS(size); | ||
147 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
148 | val |= I830_FENCE_REG_VALID; | ||
149 | } else | ||
150 | val = 0; | ||
151 | |||
152 | if (reg < 8) | ||
153 | reg = FENCE_REG_830_0 + reg * 4; | ||
154 | else | ||
155 | reg = FENCE_REG_945_8 + (reg - 8) * 4; | ||
156 | |||
157 | I915_WRITE(reg, val); | ||
158 | POSTING_READ(reg); | ||
159 | } | ||
160 | |||
161 | static void i830_write_fence_reg(struct drm_device *dev, int reg, | ||
162 | struct drm_i915_gem_object *obj) | ||
163 | { | ||
164 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
165 | uint32_t val; | ||
166 | |||
167 | if (obj) { | ||
168 | u32 size = i915_gem_obj_ggtt_size(obj); | ||
169 | uint32_t pitch_val; | ||
170 | |||
171 | WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) || | ||
172 | (size & -size) != size || | ||
173 | (i915_gem_obj_ggtt_offset(obj) & (size - 1)), | ||
174 | "object 0x%08lx not 512K or pot-size 0x%08x aligned\n", | ||
175 | i915_gem_obj_ggtt_offset(obj), size); | ||
176 | |||
177 | pitch_val = obj->stride / 128; | ||
178 | pitch_val = ffs(pitch_val) - 1; | ||
179 | |||
180 | val = i915_gem_obj_ggtt_offset(obj); | ||
181 | if (obj->tiling_mode == I915_TILING_Y) | ||
182 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
183 | val |= I830_FENCE_SIZE_BITS(size); | ||
184 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
185 | val |= I830_FENCE_REG_VALID; | ||
186 | } else | ||
187 | val = 0; | ||
188 | |||
189 | I915_WRITE(FENCE_REG_830_0 + reg * 4, val); | ||
190 | POSTING_READ(FENCE_REG_830_0 + reg * 4); | ||
191 | } | ||
192 | |||
193 | inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj) | ||
194 | { | ||
195 | return obj && obj->base.read_domains & I915_GEM_DOMAIN_GTT; | ||
196 | } | ||
197 | |||
198 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | ||
199 | struct drm_i915_gem_object *obj) | ||
200 | { | ||
201 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
202 | |||
203 | /* Ensure that all CPU reads are completed before installing a fence | ||
204 | * and all writes before removing the fence. | ||
205 | */ | ||
206 | if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj)) | ||
207 | mb(); | ||
208 | |||
209 | WARN(obj && (!obj->stride || !obj->tiling_mode), | ||
210 | "bogus fence setup with stride: 0x%x, tiling mode: %i\n", | ||
211 | obj->stride, obj->tiling_mode); | ||
212 | |||
213 | if (IS_GEN2(dev)) | ||
214 | i830_write_fence_reg(dev, reg, obj); | ||
215 | else if (IS_GEN3(dev)) | ||
216 | i915_write_fence_reg(dev, reg, obj); | ||
217 | else if (INTEL_INFO(dev)->gen >= 4) | ||
218 | i965_write_fence_reg(dev, reg, obj); | ||
219 | |||
220 | /* And similarly be paranoid that no direct access to this region | ||
221 | * is reordered to before the fence is installed. | ||
222 | */ | ||
223 | if (i915_gem_object_needs_mb(obj)) | ||
224 | mb(); | ||
225 | } | ||
226 | |||
227 | static inline int fence_number(struct drm_i915_private *dev_priv, | ||
228 | struct drm_i915_fence_reg *fence) | ||
229 | { | ||
230 | return fence - dev_priv->fence_regs; | ||
231 | } | ||
232 | |||
233 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | ||
234 | struct drm_i915_fence_reg *fence, | ||
235 | bool enable) | ||
236 | { | ||
237 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
238 | int reg = fence_number(dev_priv, fence); | ||
239 | |||
240 | i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); | ||
241 | |||
242 | if (enable) { | ||
243 | obj->fence_reg = reg; | ||
244 | fence->obj = obj; | ||
245 | list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); | ||
246 | } else { | ||
247 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
248 | fence->obj = NULL; | ||
249 | list_del_init(&fence->lru_list); | ||
250 | } | ||
251 | obj->fence_dirty = false; | ||
252 | } | ||
253 | |||
254 | static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) | ||
255 | { | ||
256 | if (obj->tiling_mode) | ||
257 | i915_gem_release_mmap(obj); | ||
258 | |||
259 | /* As we do not have an associated fence register, we will force | ||
260 | * a tiling change if we ever need to acquire one. | ||
261 | */ | ||
262 | obj->fence_dirty = false; | ||
263 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
264 | } | ||
265 | |||
266 | static int | ||
267 | i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) | ||
268 | { | ||
269 | if (obj->last_fenced_req) { | ||
270 | int ret = i915_wait_request(obj->last_fenced_req); | ||
271 | if (ret) | ||
272 | return ret; | ||
273 | |||
274 | i915_gem_request_assign(&obj->last_fenced_req, NULL); | ||
275 | } | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * i915_gem_object_put_fence - force-remove fence for an object | ||
282 | * @obj: object to map through a fence reg | ||
283 | * | ||
284 | * This function force-removes any fence from the given object, which is useful | ||
285 | * if the kernel wants to do untiled GTT access. | ||
286 | * | ||
287 | * Returns: | ||
288 | * | ||
289 | * 0 on success, negative error code on failure. | ||
290 | */ | ||
291 | int | ||
292 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | ||
293 | { | ||
294 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
295 | struct drm_i915_fence_reg *fence; | ||
296 | int ret; | ||
297 | |||
298 | ret = i915_gem_object_wait_fence(obj); | ||
299 | if (ret) | ||
300 | return ret; | ||
301 | |||
302 | if (obj->fence_reg == I915_FENCE_REG_NONE) | ||
303 | return 0; | ||
304 | |||
305 | fence = &dev_priv->fence_regs[obj->fence_reg]; | ||
306 | |||
307 | if (WARN_ON(fence->pin_count)) | ||
308 | return -EBUSY; | ||
309 | |||
310 | i915_gem_object_fence_lost(obj); | ||
311 | i915_gem_object_update_fence(obj, fence, false); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static struct drm_i915_fence_reg * | ||
317 | i915_find_fence_reg(struct drm_device *dev) | ||
318 | { | ||
319 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
320 | struct drm_i915_fence_reg *reg, *avail; | ||
321 | int i; | ||
322 | |||
323 | /* First try to find a free reg */ | ||
324 | avail = NULL; | ||
325 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | ||
326 | reg = &dev_priv->fence_regs[i]; | ||
327 | if (!reg->obj) | ||
328 | return reg; | ||
329 | |||
330 | if (!reg->pin_count) | ||
331 | avail = reg; | ||
332 | } | ||
333 | |||
334 | if (avail == NULL) | ||
335 | goto deadlock; | ||
336 | |||
337 | /* None available, try to steal one or wait for a user to finish */ | ||
338 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { | ||
339 | if (reg->pin_count) | ||
340 | continue; | ||
341 | |||
342 | return reg; | ||
343 | } | ||
344 | |||
345 | deadlock: | ||
346 | /* Wait for completion of pending flips which consume fences */ | ||
347 | if (intel_has_pending_fb_unpin(dev)) | ||
348 | return ERR_PTR(-EAGAIN); | ||
349 | |||
350 | return ERR_PTR(-EDEADLK); | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * i915_gem_object_get_fence - set up fencing for an object | ||
355 | * @obj: object to map through a fence reg | ||
356 | * | ||
357 | * When mapping objects through the GTT, userspace wants to be able to write | ||
358 | * to them without having to worry about swizzling if the object is tiled. | ||
359 | * This function walks the fence regs looking for a free one for @obj, | ||
360 | * stealing one if it can't find any. | ||
361 | * | ||
362 | * It then sets up the reg based on the object's properties: address, pitch | ||
363 | * and tiling format. | ||
364 | * | ||
365 | * For an untiled surface, this removes any existing fence. | ||
366 | * | ||
367 | * Returns: | ||
368 | * | ||
369 | * 0 on success, negative error code on failure. | ||
370 | */ | ||
371 | int | ||
372 | i915_gem_object_get_fence(struct drm_i915_gem_object *obj) | ||
373 | { | ||
374 | struct drm_device *dev = obj->base.dev; | ||
375 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
376 | bool enable = obj->tiling_mode != I915_TILING_NONE; | ||
377 | struct drm_i915_fence_reg *reg; | ||
378 | int ret; | ||
379 | |||
380 | /* Have we updated the tiling parameters upon the object and so | ||
381 | * will need to serialise the write to the associated fence register? | ||
382 | */ | ||
383 | if (obj->fence_dirty) { | ||
384 | ret = i915_gem_object_wait_fence(obj); | ||
385 | if (ret) | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | /* Just update our place in the LRU if our fence is getting reused. */ | ||
390 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
391 | reg = &dev_priv->fence_regs[obj->fence_reg]; | ||
392 | if (!obj->fence_dirty) { | ||
393 | list_move_tail(®->lru_list, | ||
394 | &dev_priv->mm.fence_list); | ||
395 | return 0; | ||
396 | } | ||
397 | } else if (enable) { | ||
398 | if (WARN_ON(!obj->map_and_fenceable)) | ||
399 | return -EINVAL; | ||
400 | |||
401 | reg = i915_find_fence_reg(dev); | ||
402 | if (IS_ERR(reg)) | ||
403 | return PTR_ERR(reg); | ||
404 | |||
405 | if (reg->obj) { | ||
406 | struct drm_i915_gem_object *old = reg->obj; | ||
407 | |||
408 | ret = i915_gem_object_wait_fence(old); | ||
409 | if (ret) | ||
410 | return ret; | ||
411 | |||
412 | i915_gem_object_fence_lost(old); | ||
413 | } | ||
414 | } else | ||
415 | return 0; | ||
416 | |||
417 | i915_gem_object_update_fence(obj, reg, enable); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * i915_gem_object_pin_fence - pin fencing state | ||
424 | * @obj: object to pin fencing for | ||
425 | * | ||
426 | * This pins the fencing state (whether tiled or untiled) to make sure the | ||
427 | * object is ready to be used as a scanout target. Fencing status must be | ||
428 | * synchronize first by calling i915_gem_object_get_fence(): | ||
429 | * | ||
430 | * The resulting fence pin reference must be released again with | ||
431 | * i915_gem_object_unpin_fence(). | ||
432 | * | ||
433 | * Returns: | ||
434 | * | ||
435 | * True if the object has a fence, false otherwise. | ||
436 | */ | ||
437 | bool | ||
438 | i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) | ||
439 | { | ||
440 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
441 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
442 | struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj); | ||
443 | |||
444 | WARN_ON(!ggtt_vma || | ||
445 | dev_priv->fence_regs[obj->fence_reg].pin_count > | ||
446 | ggtt_vma->pin_count); | ||
447 | dev_priv->fence_regs[obj->fence_reg].pin_count++; | ||
448 | return true; | ||
449 | } else | ||
450 | return false; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * i915_gem_object_unpin_fence - unpin fencing state | ||
455 | * @obj: object to unpin fencing for | ||
456 | * | ||
457 | * This releases the fence pin reference acquired through | ||
458 | * i915_gem_object_pin_fence. It will handle both objects with and without an | ||
459 | * attached fence correctly, callers do not need to distinguish this. | ||
460 | */ | ||
461 | void | ||
462 | i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | ||
463 | { | ||
464 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
465 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
466 | WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0); | ||
467 | dev_priv->fence_regs[obj->fence_reg].pin_count--; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * i915_gem_restore_fences - restore fence state | ||
473 | * @dev: DRM device | ||
474 | * | ||
475 | * Restore the hw fence state to match the software tracking again, to be called | ||
476 | * after a gpu reset and on resume. | ||
477 | */ | ||
478 | void i915_gem_restore_fences(struct drm_device *dev) | ||
479 | { | ||
480 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
481 | int i; | ||
482 | |||
483 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | ||
484 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | ||
485 | |||
486 | /* | ||
487 | * Commit delayed tiling changes if we have an object still | ||
488 | * attached to the fence, otherwise just clear the fence. | ||
489 | */ | ||
490 | if (reg->obj) { | ||
491 | i915_gem_object_update_fence(reg->obj, reg, | ||
492 | reg->obj->tiling_mode); | ||
493 | } else { | ||
494 | i915_gem_write_fence(dev, i, NULL); | ||
495 | } | ||
496 | } | ||
497 | } | ||
498 | |||
499 | /** | ||
500 | * DOC: tiling swizzling details | ||
501 | * | ||
502 | * The idea behind tiling is to increase cache hit rates by rearranging | ||
503 | * pixel data so that a group of pixel accesses are in the same cacheline. | ||
504 | * Performance improvement from doing this on the back/depth buffer are on | ||
505 | * the order of 30%. | ||
506 | * | ||
507 | * Intel architectures make this somewhat more complicated, though, by | ||
508 | * adjustments made to addressing of data when the memory is in interleaved | ||
509 | * mode (matched pairs of DIMMS) to improve memory bandwidth. | ||
510 | * For interleaved memory, the CPU sends every sequential 64 bytes | ||
511 | * to an alternate memory channel so it can get the bandwidth from both. | ||
512 | * | ||
513 | * The GPU also rearranges its accesses for increased bandwidth to interleaved | ||
514 | * memory, and it matches what the CPU does for non-tiled. However, when tiled | ||
515 | * it does it a little differently, since one walks addresses not just in the | ||
516 | * X direction but also Y. So, along with alternating channels when bit | ||
517 | * 6 of the address flips, it also alternates when other bits flip -- Bits 9 | ||
518 | * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines) | ||
519 | * are common to both the 915 and 965-class hardware. | ||
520 | * | ||
521 | * The CPU also sometimes XORs in higher bits as well, to improve | ||
522 | * bandwidth doing strided access like we do so frequently in graphics. This | ||
523 | * is called "Channel XOR Randomization" in the MCH documentation. The result | ||
524 | * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address | ||
525 | * decode. | ||
526 | * | ||
527 | * All of this bit 6 XORing has an effect on our memory management, | ||
528 | * as we need to make sure that the 3d driver can correctly address object | ||
529 | * contents. | ||
530 | * | ||
531 | * If we don't have interleaved memory, all tiling is safe and no swizzling is | ||
532 | * required. | ||
533 | * | ||
534 | * When bit 17 is XORed in, we simply refuse to tile at all. Bit | ||
535 | * 17 is not just a page offset, so as we page an objet out and back in, | ||
536 | * individual pages in it will have different bit 17 addresses, resulting in | ||
537 | * each 64 bytes being swapped with its neighbor! | ||
538 | * | ||
539 | * Otherwise, if interleaved, we have to tell the 3d driver what the address | ||
540 | * swizzling it needs to do is, since it's writing with the CPU to the pages | ||
541 | * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the | ||
542 | * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling | ||
543 | * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order | ||
544 | * to match what the GPU expects. | ||
545 | */ | ||
546 | |||
547 | /** | ||
548 | * i915_gem_detect_bit_6_swizzle - detect bit 6 swizzling pattern | ||
549 | * @dev: DRM device | ||
550 | * | ||
551 | * Detects bit 6 swizzling of address lookup between IGD access and CPU | ||
552 | * access through main memory. | ||
553 | */ | ||
554 | void | ||
555 | i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | ||
556 | { | ||
557 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
558 | uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
559 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
560 | |||
561 | if (INTEL_INFO(dev)->gen >= 8 || IS_VALLEYVIEW(dev)) { | ||
562 | /* | ||
563 | * On BDW+, swizzling is not used. We leave the CPU memory | ||
564 | * controller in charge of optimizing memory accesses without | ||
565 | * the extra address manipulation GPU side. | ||
566 | * | ||
567 | * VLV and CHV don't have GPU swizzling. | ||
568 | */ | ||
569 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
570 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
571 | } else if (INTEL_INFO(dev)->gen >= 6) { | ||
572 | if (dev_priv->preserve_bios_swizzle) { | ||
573 | if (I915_READ(DISP_ARB_CTL) & | ||
574 | DISP_TILE_SURFACE_SWIZZLING) { | ||
575 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
576 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
577 | } else { | ||
578 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
579 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
580 | } | ||
581 | } else { | ||
582 | uint32_t dimm_c0, dimm_c1; | ||
583 | dimm_c0 = I915_READ(MAD_DIMM_C0); | ||
584 | dimm_c1 = I915_READ(MAD_DIMM_C1); | ||
585 | dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
586 | dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
587 | /* Enable swizzling when the channels are populated | ||
588 | * with identically sized dimms. We don't need to check | ||
589 | * the 3rd channel because no cpu with gpu attached | ||
590 | * ships in that configuration. Also, swizzling only | ||
591 | * makes sense for 2 channels anyway. */ | ||
592 | if (dimm_c0 == dimm_c1) { | ||
593 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
594 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
595 | } else { | ||
596 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
597 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
598 | } | ||
599 | } | ||
600 | } else if (IS_GEN5(dev)) { | ||
601 | /* On Ironlake whatever DRAM config, GPU always do | ||
602 | * same swizzling setup. | ||
603 | */ | ||
604 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
605 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
606 | } else if (IS_GEN2(dev)) { | ||
607 | /* As far as we know, the 865 doesn't have these bit 6 | ||
608 | * swizzling issues. | ||
609 | */ | ||
610 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
611 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
612 | } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { | ||
613 | uint32_t dcc; | ||
614 | |||
615 | /* On 9xx chipsets, channel interleave by the CPU is | ||
616 | * determined by DCC. For single-channel, neither the CPU | ||
617 | * nor the GPU do swizzling. For dual channel interleaved, | ||
618 | * the GPU's interleave is bit 9 and 10 for X tiled, and bit | ||
619 | * 9 for Y tiled. The CPU's interleave is independent, and | ||
620 | * can be based on either bit 11 (haven't seen this yet) or | ||
621 | * bit 17 (common). | ||
622 | */ | ||
623 | dcc = I915_READ(DCC); | ||
624 | switch (dcc & DCC_ADDRESSING_MODE_MASK) { | ||
625 | case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: | ||
626 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: | ||
627 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
628 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
629 | break; | ||
630 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: | ||
631 | if (dcc & DCC_CHANNEL_XOR_DISABLE) { | ||
632 | /* This is the base swizzling by the GPU for | ||
633 | * tiled buffers. | ||
634 | */ | ||
635 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
636 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
637 | } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { | ||
638 | /* Bit 11 swizzling by the CPU in addition. */ | ||
639 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; | ||
640 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; | ||
641 | } else { | ||
642 | /* Bit 17 swizzling by the CPU in addition. */ | ||
643 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; | ||
644 | swizzle_y = I915_BIT_6_SWIZZLE_9_17; | ||
645 | } | ||
646 | break; | ||
647 | } | ||
648 | |||
649 | /* check for L-shaped memory aka modified enhanced addressing */ | ||
650 | if (IS_GEN4(dev)) { | ||
651 | uint32_t ddc2 = I915_READ(DCC2); | ||
652 | |||
653 | if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE)) | ||
654 | dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES; | ||
655 | } | ||
656 | |||
657 | if (dcc == 0xffffffff) { | ||
658 | DRM_ERROR("Couldn't read from MCHBAR. " | ||
659 | "Disabling tiling.\n"); | ||
660 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
661 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
662 | } | ||
663 | } else { | ||
664 | /* The 965, G33, and newer, have a very flexible memory | ||
665 | * configuration. It will enable dual-channel mode | ||
666 | * (interleaving) on as much memory as it can, and the GPU | ||
667 | * will additionally sometimes enable different bit 6 | ||
668 | * swizzling for tiled objects from the CPU. | ||
669 | * | ||
670 | * Here's what I found on the G965: | ||
671 | * slot fill memory size swizzling | ||
672 | * 0A 0B 1A 1B 1-ch 2-ch | ||
673 | * 512 0 0 0 512 0 O | ||
674 | * 512 0 512 0 16 1008 X | ||
675 | * 512 0 0 512 16 1008 X | ||
676 | * 0 512 0 512 16 1008 X | ||
677 | * 1024 1024 1024 0 2048 1024 O | ||
678 | * | ||
679 | * We could probably detect this based on either the DRB | ||
680 | * matching, which was the case for the swizzling required in | ||
681 | * the table above, or from the 1-ch value being less than | ||
682 | * the minimum size of a rank. | ||
683 | */ | ||
684 | if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { | ||
685 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
686 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
687 | } else { | ||
688 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
689 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
690 | } | ||
691 | } | ||
692 | |||
693 | dev_priv->mm.bit_6_swizzle_x = swizzle_x; | ||
694 | dev_priv->mm.bit_6_swizzle_y = swizzle_y; | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * Swap every 64 bytes of this page around, to account for it having a new | ||
699 | * bit 17 of its physical address and therefore being interpreted differently | ||
700 | * by the GPU. | ||
701 | */ | ||
702 | static void | ||
703 | i915_gem_swizzle_page(struct page *page) | ||
704 | { | ||
705 | char temp[64]; | ||
706 | char *vaddr; | ||
707 | int i; | ||
708 | |||
709 | vaddr = kmap(page); | ||
710 | |||
711 | for (i = 0; i < PAGE_SIZE; i += 128) { | ||
712 | memcpy(temp, &vaddr[i], 64); | ||
713 | memcpy(&vaddr[i], &vaddr[i + 64], 64); | ||
714 | memcpy(&vaddr[i + 64], temp, 64); | ||
715 | } | ||
716 | |||
717 | kunmap(page); | ||
718 | } | ||
719 | |||
720 | /** | ||
721 | * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling | ||
722 | * @obj: i915 GEM buffer object | ||
723 | * | ||
724 | * This function fixes up the swizzling in case any page frame number for this | ||
725 | * object has changed in bit 17 since that state has been saved with | ||
726 | * i915_gem_object_save_bit_17_swizzle(). | ||
727 | * | ||
728 | * This is called when pinning backing storage again, since the kernel is free | ||
729 | * to move unpinned backing storage around (either by directly moving pages or | ||
730 | * by swapping them out and back in again). | ||
731 | */ | ||
732 | void | ||
733 | i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) | ||
734 | { | ||
735 | struct sg_page_iter sg_iter; | ||
736 | int i; | ||
737 | |||
738 | if (obj->bit_17 == NULL) | ||
739 | return; | ||
740 | |||
741 | i = 0; | ||
742 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | ||
743 | struct page *page = sg_page_iter_page(&sg_iter); | ||
744 | char new_bit_17 = page_to_phys(page) >> 17; | ||
745 | if ((new_bit_17 & 0x1) != | ||
746 | (test_bit(i, obj->bit_17) != 0)) { | ||
747 | i915_gem_swizzle_page(page); | ||
748 | set_page_dirty(page); | ||
749 | } | ||
750 | i++; | ||
751 | } | ||
752 | } | ||
753 | |||
754 | /** | ||
755 | * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling | ||
756 | * @obj: i915 GEM buffer object | ||
757 | * | ||
758 | * This function saves the bit 17 of each page frame number so that swizzling | ||
759 | * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must | ||
760 | * be called before the backing storage can be unpinned. | ||
761 | */ | ||
762 | void | ||
763 | i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) | ||
764 | { | ||
765 | struct sg_page_iter sg_iter; | ||
766 | int page_count = obj->base.size >> PAGE_SHIFT; | ||
767 | int i; | ||
768 | |||
769 | if (obj->bit_17 == NULL) { | ||
770 | obj->bit_17 = kcalloc(BITS_TO_LONGS(page_count), | ||
771 | sizeof(long), GFP_KERNEL); | ||
772 | if (obj->bit_17 == NULL) { | ||
773 | DRM_ERROR("Failed to allocate memory for bit 17 " | ||
774 | "record\n"); | ||
775 | return; | ||
776 | } | ||
777 | } | ||
778 | |||
779 | i = 0; | ||
780 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | ||
781 | if (page_to_phys(sg_page_iter_page(&sg_iter)) & (1 << 17)) | ||
782 | __set_bit(i, obj->bit_17); | ||
783 | else | ||
784 | __clear_bit(i, obj->bit_17); | ||
785 | i++; | ||
786 | } | ||
787 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index a0201fc94d25..5026a6267a88 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c | |||
@@ -73,6 +73,24 @@ free_gem: | |||
73 | return ret; | 73 | return ret; |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | ||
77 | * Macro to add commands to auxiliary batch. | ||
78 | * This macro only checks for page overflow before inserting the commands, | ||
79 | * this is sufficient as the null state generator makes the final batch | ||
80 | * with two passes to build command and state separately. At this point | ||
81 | * the size of both are known and it compacts them by relocating the state | ||
82 | * right after the commands taking care of aligment so we should sufficient | ||
83 | * space below them for adding new commands. | ||
84 | */ | ||
85 | #define OUT_BATCH(batch, i, val) \ | ||
86 | do { \ | ||
87 | if (WARN_ON((i) >= PAGE_SIZE / sizeof(u32))) { \ | ||
88 | ret = -ENOSPC; \ | ||
89 | goto err_out; \ | ||
90 | } \ | ||
91 | (batch)[(i)++] = (val); \ | ||
92 | } while(0) | ||
93 | |||
76 | static int render_state_setup(struct render_state *so) | 94 | static int render_state_setup(struct render_state *so) |
77 | { | 95 | { |
78 | const struct intel_renderstate_rodata *rodata = so->rodata; | 96 | const struct intel_renderstate_rodata *rodata = so->rodata; |
@@ -96,8 +114,10 @@ static int render_state_setup(struct render_state *so) | |||
96 | s = lower_32_bits(r); | 114 | s = lower_32_bits(r); |
97 | if (so->gen >= 8) { | 115 | if (so->gen >= 8) { |
98 | if (i + 1 >= rodata->batch_items || | 116 | if (i + 1 >= rodata->batch_items || |
99 | rodata->batch[i + 1] != 0) | 117 | rodata->batch[i + 1] != 0) { |
100 | return -EINVAL; | 118 | ret = -EINVAL; |
119 | goto err_out; | ||
120 | } | ||
101 | 121 | ||
102 | d[i++] = s; | 122 | d[i++] = s; |
103 | s = upper_32_bits(r); | 123 | s = upper_32_bits(r); |
@@ -108,6 +128,21 @@ static int render_state_setup(struct render_state *so) | |||
108 | 128 | ||
109 | d[i++] = s; | 129 | d[i++] = s; |
110 | } | 130 | } |
131 | |||
132 | while (i % CACHELINE_DWORDS) | ||
133 | OUT_BATCH(d, i, MI_NOOP); | ||
134 | |||
135 | so->aux_batch_offset = i * sizeof(u32); | ||
136 | |||
137 | OUT_BATCH(d, i, MI_BATCH_BUFFER_END); | ||
138 | so->aux_batch_size = (i * sizeof(u32)) - so->aux_batch_offset; | ||
139 | |||
140 | /* | ||
141 | * Since we are sending length, we need to strictly conform to | ||
142 | * all requirements. For Gen2 this must be a multiple of 8. | ||
143 | */ | ||
144 | so->aux_batch_size = ALIGN(so->aux_batch_size, 8); | ||
145 | |||
111 | kunmap(page); | 146 | kunmap(page); |
112 | 147 | ||
113 | ret = i915_gem_object_set_to_gtt_domain(so->obj, false); | 148 | ret = i915_gem_object_set_to_gtt_domain(so->obj, false); |
@@ -120,8 +155,14 @@ static int render_state_setup(struct render_state *so) | |||
120 | } | 155 | } |
121 | 156 | ||
122 | return 0; | 157 | return 0; |
158 | |||
159 | err_out: | ||
160 | kunmap(page); | ||
161 | return ret; | ||
123 | } | 162 | } |
124 | 163 | ||
164 | #undef OUT_BATCH | ||
165 | |||
125 | void i915_gem_render_state_fini(struct render_state *so) | 166 | void i915_gem_render_state_fini(struct render_state *so) |
126 | { | 167 | { |
127 | i915_gem_object_ggtt_unpin(so->obj); | 168 | i915_gem_object_ggtt_unpin(so->obj); |
@@ -170,6 +211,16 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req) | |||
170 | if (ret) | 211 | if (ret) |
171 | goto out; | 212 | goto out; |
172 | 213 | ||
214 | if (so.aux_batch_size > 8) { | ||
215 | ret = req->ring->dispatch_execbuffer(req, | ||
216 | (so.ggtt_offset + | ||
217 | so.aux_batch_offset), | ||
218 | so.aux_batch_size, | ||
219 | I915_DISPATCH_SECURE); | ||
220 | if (ret) | ||
221 | goto out; | ||
222 | } | ||
223 | |||
173 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); | 224 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); |
174 | 225 | ||
175 | out: | 226 | out: |
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h index 7aa73728178a..e641bb093a90 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h | |||
@@ -37,6 +37,8 @@ struct render_state { | |||
37 | struct drm_i915_gem_object *obj; | 37 | struct drm_i915_gem_object *obj; |
38 | u64 ggtt_offset; | 38 | u64 ggtt_offset; |
39 | int gen; | 39 | int gen; |
40 | u32 aux_batch_size; | ||
41 | u32 aux_batch_offset; | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | int i915_gem_render_state_init(struct drm_i915_gem_request *req); | 44 | int i915_gem_render_state_init(struct drm_i915_gem_request *req); |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index ed682a9a9cbb..a36cb95ec798 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -186,11 +186,103 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) | |||
186 | drm_mm_takedown(&dev_priv->mm.stolen); | 186 | drm_mm_takedown(&dev_priv->mm.stolen); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv, | ||
190 | unsigned long *base, unsigned long *size) | ||
191 | { | ||
192 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | ||
193 | |||
194 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | ||
195 | |||
196 | switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) { | ||
197 | case GEN6_STOLEN_RESERVED_1M: | ||
198 | *size = 1024 * 1024; | ||
199 | break; | ||
200 | case GEN6_STOLEN_RESERVED_512K: | ||
201 | *size = 512 * 1024; | ||
202 | break; | ||
203 | case GEN6_STOLEN_RESERVED_256K: | ||
204 | *size = 256 * 1024; | ||
205 | break; | ||
206 | case GEN6_STOLEN_RESERVED_128K: | ||
207 | *size = 128 * 1024; | ||
208 | break; | ||
209 | default: | ||
210 | *size = 1024 * 1024; | ||
211 | MISSING_CASE(reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv, | ||
216 | unsigned long *base, unsigned long *size) | ||
217 | { | ||
218 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | ||
219 | |||
220 | *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK; | ||
221 | |||
222 | switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) { | ||
223 | case GEN7_STOLEN_RESERVED_1M: | ||
224 | *size = 1024 * 1024; | ||
225 | break; | ||
226 | case GEN7_STOLEN_RESERVED_256K: | ||
227 | *size = 256 * 1024; | ||
228 | break; | ||
229 | default: | ||
230 | *size = 1024 * 1024; | ||
231 | MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static void gen8_get_stolen_reserved(struct drm_i915_private *dev_priv, | ||
236 | unsigned long *base, unsigned long *size) | ||
237 | { | ||
238 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | ||
239 | |||
240 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | ||
241 | |||
242 | switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) { | ||
243 | case GEN8_STOLEN_RESERVED_1M: | ||
244 | *size = 1024 * 1024; | ||
245 | break; | ||
246 | case GEN8_STOLEN_RESERVED_2M: | ||
247 | *size = 2 * 1024 * 1024; | ||
248 | break; | ||
249 | case GEN8_STOLEN_RESERVED_4M: | ||
250 | *size = 4 * 1024 * 1024; | ||
251 | break; | ||
252 | case GEN8_STOLEN_RESERVED_8M: | ||
253 | *size = 8 * 1024 * 1024; | ||
254 | break; | ||
255 | default: | ||
256 | *size = 8 * 1024 * 1024; | ||
257 | MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, | ||
262 | unsigned long *base, unsigned long *size) | ||
263 | { | ||
264 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | ||
265 | unsigned long stolen_top; | ||
266 | |||
267 | stolen_top = dev_priv->mm.stolen_base + dev_priv->gtt.stolen_size; | ||
268 | |||
269 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | ||
270 | |||
271 | /* On these platforms, the register doesn't have a size field, so the | ||
272 | * size is the distance between the base and the top of the stolen | ||
273 | * memory. We also have the genuine case where base is zero and there's | ||
274 | * nothing reserved. */ | ||
275 | if (*base == 0) | ||
276 | *size = 0; | ||
277 | else | ||
278 | *size = stolen_top - *base; | ||
279 | } | ||
280 | |||
189 | int i915_gem_init_stolen(struct drm_device *dev) | 281 | int i915_gem_init_stolen(struct drm_device *dev) |
190 | { | 282 | { |
191 | struct drm_i915_private *dev_priv = dev->dev_private; | 283 | struct drm_i915_private *dev_priv = dev->dev_private; |
192 | u32 tmp; | 284 | unsigned long reserved_total, reserved_base, reserved_size; |
193 | int bios_reserved = 0; | 285 | unsigned long stolen_top; |
194 | 286 | ||
195 | mutex_init(&dev_priv->mm.stolen_lock); | 287 | mutex_init(&dev_priv->mm.stolen_lock); |
196 | 288 | ||
@@ -208,26 +300,61 @@ int i915_gem_init_stolen(struct drm_device *dev) | |||
208 | if (dev_priv->mm.stolen_base == 0) | 300 | if (dev_priv->mm.stolen_base == 0) |
209 | return 0; | 301 | return 0; |
210 | 302 | ||
211 | DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n", | 303 | stolen_top = dev_priv->mm.stolen_base + dev_priv->gtt.stolen_size; |
212 | dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base); | 304 | |
213 | 305 | switch (INTEL_INFO(dev_priv)->gen) { | |
214 | if (INTEL_INFO(dev)->gen >= 8) { | 306 | case 2: |
215 | tmp = I915_READ(GEN7_BIOS_RESERVED); | 307 | case 3: |
216 | tmp >>= GEN8_BIOS_RESERVED_SHIFT; | 308 | case 4: |
217 | tmp &= GEN8_BIOS_RESERVED_MASK; | 309 | case 5: |
218 | bios_reserved = (1024*1024) << tmp; | 310 | /* Assume the gen6 maximum for the older platforms. */ |
219 | } else if (IS_GEN7(dev)) { | 311 | reserved_size = 1024 * 1024; |
220 | tmp = I915_READ(GEN7_BIOS_RESERVED); | 312 | reserved_base = stolen_top - reserved_size; |
221 | bios_reserved = tmp & GEN7_BIOS_RESERVED_256K ? | 313 | break; |
222 | 256*1024 : 1024*1024; | 314 | case 6: |
315 | gen6_get_stolen_reserved(dev_priv, &reserved_base, | ||
316 | &reserved_size); | ||
317 | break; | ||
318 | case 7: | ||
319 | gen7_get_stolen_reserved(dev_priv, &reserved_base, | ||
320 | &reserved_size); | ||
321 | break; | ||
322 | default: | ||
323 | if (IS_BROADWELL(dev_priv) || IS_SKYLAKE(dev_priv)) | ||
324 | bdw_get_stolen_reserved(dev_priv, &reserved_base, | ||
325 | &reserved_size); | ||
326 | else | ||
327 | gen8_get_stolen_reserved(dev_priv, &reserved_base, | ||
328 | &reserved_size); | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | /* It is possible for the reserved base to be zero, but the register | ||
333 | * field for size doesn't have a zero option. */ | ||
334 | if (reserved_base == 0) { | ||
335 | reserved_size = 0; | ||
336 | reserved_base = stolen_top; | ||
223 | } | 337 | } |
224 | 338 | ||
225 | if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size)) | 339 | if (reserved_base < dev_priv->mm.stolen_base || |
340 | reserved_base + reserved_size > stolen_top) { | ||
341 | DRM_DEBUG_KMS("Stolen reserved area [0x%08lx - 0x%08lx] outside stolen memory [0x%08lx - 0x%08lx]\n", | ||
342 | reserved_base, reserved_base + reserved_size, | ||
343 | dev_priv->mm.stolen_base, stolen_top); | ||
226 | return 0; | 344 | return 0; |
345 | } | ||
346 | |||
347 | /* It is possible for the reserved area to end before the end of stolen | ||
348 | * memory, so just consider the start. */ | ||
349 | reserved_total = stolen_top - reserved_base; | ||
350 | |||
351 | DRM_DEBUG_KMS("Memory reserved for graphics device: %luK, usable: %luK\n", | ||
352 | dev_priv->gtt.stolen_size >> 10, | ||
353 | (dev_priv->gtt.stolen_size - reserved_total) >> 10); | ||
227 | 354 | ||
228 | /* Basic memrange allocator for stolen space */ | 355 | /* Basic memrange allocator for stolen space */ |
229 | drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size - | 356 | drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size - |
230 | bios_reserved); | 357 | reserved_total); |
231 | 358 | ||
232 | return 0; | 359 | return 0; |
233 | } | 360 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index d19c9db5e18c..8a6717cc265c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -31,201 +31,32 @@ | |||
31 | #include <drm/i915_drm.h> | 31 | #include <drm/i915_drm.h> |
32 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
33 | 33 | ||
34 | /** @file i915_gem_tiling.c | 34 | /** |
35 | * | 35 | * DOC: buffer object tiling |
36 | * Support for managing tiling state of buffer objects. | ||
37 | * | ||
38 | * The idea behind tiling is to increase cache hit rates by rearranging | ||
39 | * pixel data so that a group of pixel accesses are in the same cacheline. | ||
40 | * Performance improvement from doing this on the back/depth buffer are on | ||
41 | * the order of 30%. | ||
42 | * | ||
43 | * Intel architectures make this somewhat more complicated, though, by | ||
44 | * adjustments made to addressing of data when the memory is in interleaved | ||
45 | * mode (matched pairs of DIMMS) to improve memory bandwidth. | ||
46 | * For interleaved memory, the CPU sends every sequential 64 bytes | ||
47 | * to an alternate memory channel so it can get the bandwidth from both. | ||
48 | * | ||
49 | * The GPU also rearranges its accesses for increased bandwidth to interleaved | ||
50 | * memory, and it matches what the CPU does for non-tiled. However, when tiled | ||
51 | * it does it a little differently, since one walks addresses not just in the | ||
52 | * X direction but also Y. So, along with alternating channels when bit | ||
53 | * 6 of the address flips, it also alternates when other bits flip -- Bits 9 | ||
54 | * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines) | ||
55 | * are common to both the 915 and 965-class hardware. | ||
56 | * | ||
57 | * The CPU also sometimes XORs in higher bits as well, to improve | ||
58 | * bandwidth doing strided access like we do so frequently in graphics. This | ||
59 | * is called "Channel XOR Randomization" in the MCH documentation. The result | ||
60 | * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address | ||
61 | * decode. | ||
62 | * | 36 | * |
63 | * All of this bit 6 XORing has an effect on our memory management, | 37 | * i915_gem_set_tiling() and i915_gem_get_tiling() is the userspace interface to |
64 | * as we need to make sure that the 3d driver can correctly address object | 38 | * declare fence register requirements. |
65 | * contents. | ||
66 | * | 39 | * |
67 | * If we don't have interleaved memory, all tiling is safe and no swizzling is | 40 | * In principle GEM doesn't care at all about the internal data layout of an |
68 | * required. | 41 | * object, and hence it also doesn't care about tiling or swizzling. There's two |
42 | * exceptions: | ||
69 | * | 43 | * |
70 | * When bit 17 is XORed in, we simply refuse to tile at all. Bit | 44 | * - For X and Y tiling the hardware provides detilers for CPU access, so called |
71 | * 17 is not just a page offset, so as we page an objet out and back in, | 45 | * fences. Since there's only a limited amount of them the kernel must manage |
72 | * individual pages in it will have different bit 17 addresses, resulting in | 46 | * these, and therefore userspace must tell the kernel the object tiling if it |
73 | * each 64 bytes being swapped with its neighbor! | 47 | * wants to use fences for detiling. |
48 | * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which | ||
49 | * depends upon the physical page frame number. When swapping such objects the | ||
50 | * page frame number might change and the kernel must be able to fix this up | ||
51 | * and hence now the tiling. Note that on a subset of platforms with | ||
52 | * asymmetric memory channel population the swizzling pattern changes in an | ||
53 | * unknown way, and for those the kernel simply forbids swapping completely. | ||
74 | * | 54 | * |
75 | * Otherwise, if interleaved, we have to tell the 3d driver what the address | 55 | * Since neither of this applies for new tiling layouts on modern platforms like |
76 | * swizzling it needs to do is, since it's writing with the CPU to the pages | 56 | * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled. |
77 | * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the | 57 | * Anything else can be handled in userspace entirely without the kernel's |
78 | * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling | 58 | * invovlement. |
79 | * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order | ||
80 | * to match what the GPU expects. | ||
81 | */ | ||
82 | |||
83 | /** | ||
84 | * Detects bit 6 swizzling of address lookup between IGD access and CPU | ||
85 | * access through main memory. | ||
86 | */ | 59 | */ |
87 | void | ||
88 | i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | ||
89 | { | ||
90 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
91 | uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
92 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
93 | |||
94 | if (INTEL_INFO(dev)->gen >= 8 || IS_VALLEYVIEW(dev)) { | ||
95 | /* | ||
96 | * On BDW+, swizzling is not used. We leave the CPU memory | ||
97 | * controller in charge of optimizing memory accesses without | ||
98 | * the extra address manipulation GPU side. | ||
99 | * | ||
100 | * VLV and CHV don't have GPU swizzling. | ||
101 | */ | ||
102 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
103 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
104 | } else if (INTEL_INFO(dev)->gen >= 6) { | ||
105 | if (dev_priv->preserve_bios_swizzle) { | ||
106 | if (I915_READ(DISP_ARB_CTL) & | ||
107 | DISP_TILE_SURFACE_SWIZZLING) { | ||
108 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
109 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
110 | } else { | ||
111 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
112 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
113 | } | ||
114 | } else { | ||
115 | uint32_t dimm_c0, dimm_c1; | ||
116 | dimm_c0 = I915_READ(MAD_DIMM_C0); | ||
117 | dimm_c1 = I915_READ(MAD_DIMM_C1); | ||
118 | dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
119 | dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
120 | /* Enable swizzling when the channels are populated | ||
121 | * with identically sized dimms. We don't need to check | ||
122 | * the 3rd channel because no cpu with gpu attached | ||
123 | * ships in that configuration. Also, swizzling only | ||
124 | * makes sense for 2 channels anyway. */ | ||
125 | if (dimm_c0 == dimm_c1) { | ||
126 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
127 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
128 | } else { | ||
129 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
130 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
131 | } | ||
132 | } | ||
133 | } else if (IS_GEN5(dev)) { | ||
134 | /* On Ironlake whatever DRAM config, GPU always do | ||
135 | * same swizzling setup. | ||
136 | */ | ||
137 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
138 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
139 | } else if (IS_GEN2(dev)) { | ||
140 | /* As far as we know, the 865 doesn't have these bit 6 | ||
141 | * swizzling issues. | ||
142 | */ | ||
143 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
144 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
145 | } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { | ||
146 | uint32_t dcc; | ||
147 | |||
148 | /* On 9xx chipsets, channel interleave by the CPU is | ||
149 | * determined by DCC. For single-channel, neither the CPU | ||
150 | * nor the GPU do swizzling. For dual channel interleaved, | ||
151 | * the GPU's interleave is bit 9 and 10 for X tiled, and bit | ||
152 | * 9 for Y tiled. The CPU's interleave is independent, and | ||
153 | * can be based on either bit 11 (haven't seen this yet) or | ||
154 | * bit 17 (common). | ||
155 | */ | ||
156 | dcc = I915_READ(DCC); | ||
157 | switch (dcc & DCC_ADDRESSING_MODE_MASK) { | ||
158 | case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: | ||
159 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: | ||
160 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
161 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
162 | break; | ||
163 | case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: | ||
164 | if (dcc & DCC_CHANNEL_XOR_DISABLE) { | ||
165 | /* This is the base swizzling by the GPU for | ||
166 | * tiled buffers. | ||
167 | */ | ||
168 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
169 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
170 | } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { | ||
171 | /* Bit 11 swizzling by the CPU in addition. */ | ||
172 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; | ||
173 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; | ||
174 | } else { | ||
175 | /* Bit 17 swizzling by the CPU in addition. */ | ||
176 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; | ||
177 | swizzle_y = I915_BIT_6_SWIZZLE_9_17; | ||
178 | } | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | /* check for L-shaped memory aka modified enhanced addressing */ | ||
183 | if (IS_GEN4(dev)) { | ||
184 | uint32_t ddc2 = I915_READ(DCC2); | ||
185 | |||
186 | if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE)) | ||
187 | dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES; | ||
188 | } | ||
189 | |||
190 | if (dcc == 0xffffffff) { | ||
191 | DRM_ERROR("Couldn't read from MCHBAR. " | ||
192 | "Disabling tiling.\n"); | ||
193 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
194 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
195 | } | ||
196 | } else { | ||
197 | /* The 965, G33, and newer, have a very flexible memory | ||
198 | * configuration. It will enable dual-channel mode | ||
199 | * (interleaving) on as much memory as it can, and the GPU | ||
200 | * will additionally sometimes enable different bit 6 | ||
201 | * swizzling for tiled objects from the CPU. | ||
202 | * | ||
203 | * Here's what I found on the G965: | ||
204 | * slot fill memory size swizzling | ||
205 | * 0A 0B 1A 1B 1-ch 2-ch | ||
206 | * 512 0 0 0 512 0 O | ||
207 | * 512 0 512 0 16 1008 X | ||
208 | * 512 0 0 512 16 1008 X | ||
209 | * 0 512 0 512 16 1008 X | ||
210 | * 1024 1024 1024 0 2048 1024 O | ||
211 | * | ||
212 | * We could probably detect this based on either the DRB | ||
213 | * matching, which was the case for the swizzling required in | ||
214 | * the table above, or from the 1-ch value being less than | ||
215 | * the minimum size of a rank. | ||
216 | */ | ||
217 | if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { | ||
218 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
219 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
220 | } else { | ||
221 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
222 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | dev_priv->mm.bit_6_swizzle_x = swizzle_x; | ||
227 | dev_priv->mm.bit_6_swizzle_y = swizzle_y; | ||
228 | } | ||
229 | 60 | ||
230 | /* Check pitch constriants for all chips & tiling formats */ | 61 | /* Check pitch constriants for all chips & tiling formats */ |
231 | static bool | 62 | static bool |
@@ -313,8 +144,18 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) | |||
313 | } | 144 | } |
314 | 145 | ||
315 | /** | 146 | /** |
147 | * i915_gem_set_tiling - IOCTL handler to set tiling mode | ||
148 | * @dev: DRM device | ||
149 | * @data: data pointer for the ioctl | ||
150 | * @file: DRM file for the ioctl call | ||
151 | * | ||
316 | * Sets the tiling mode of an object, returning the required swizzling of | 152 | * Sets the tiling mode of an object, returning the required swizzling of |
317 | * bit 6 of addresses in the object. | 153 | * bit 6 of addresses in the object. |
154 | * | ||
155 | * Called by the user via ioctl. | ||
156 | * | ||
157 | * Returns: | ||
158 | * Zero on success, negative errno on failure. | ||
318 | */ | 159 | */ |
319 | int | 160 | int |
320 | i915_gem_set_tiling(struct drm_device *dev, void *data, | 161 | i915_gem_set_tiling(struct drm_device *dev, void *data, |
@@ -432,7 +273,17 @@ err: | |||
432 | } | 273 | } |
433 | 274 | ||
434 | /** | 275 | /** |
276 | * i915_gem_get_tiling - IOCTL handler to get tiling mode | ||
277 | * @dev: DRM device | ||
278 | * @data: data pointer for the ioctl | ||
279 | * @file: DRM file for the ioctl call | ||
280 | * | ||
435 | * Returns the current tiling mode and required bit 6 swizzling for the object. | 281 | * Returns the current tiling mode and required bit 6 swizzling for the object. |
282 | * | ||
283 | * Called by the user via ioctl. | ||
284 | * | ||
285 | * Returns: | ||
286 | * Zero on success, negative errno on failure. | ||
436 | */ | 287 | */ |
437 | int | 288 | int |
438 | i915_gem_get_tiling(struct drm_device *dev, void *data, | 289 | i915_gem_get_tiling(struct drm_device *dev, void *data, |
@@ -478,75 +329,3 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
478 | 329 | ||
479 | return 0; | 330 | return 0; |
480 | } | 331 | } |
481 | |||
482 | /** | ||
483 | * Swap every 64 bytes of this page around, to account for it having a new | ||
484 | * bit 17 of its physical address and therefore being interpreted differently | ||
485 | * by the GPU. | ||
486 | */ | ||
487 | static void | ||
488 | i915_gem_swizzle_page(struct page *page) | ||
489 | { | ||
490 | char temp[64]; | ||
491 | char *vaddr; | ||
492 | int i; | ||
493 | |||
494 | vaddr = kmap(page); | ||
495 | |||
496 | for (i = 0; i < PAGE_SIZE; i += 128) { | ||
497 | memcpy(temp, &vaddr[i], 64); | ||
498 | memcpy(&vaddr[i], &vaddr[i + 64], 64); | ||
499 | memcpy(&vaddr[i + 64], temp, 64); | ||
500 | } | ||
501 | |||
502 | kunmap(page); | ||
503 | } | ||
504 | |||
505 | void | ||
506 | i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) | ||
507 | { | ||
508 | struct sg_page_iter sg_iter; | ||
509 | int i; | ||
510 | |||
511 | if (obj->bit_17 == NULL) | ||
512 | return; | ||
513 | |||
514 | i = 0; | ||
515 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | ||
516 | struct page *page = sg_page_iter_page(&sg_iter); | ||
517 | char new_bit_17 = page_to_phys(page) >> 17; | ||
518 | if ((new_bit_17 & 0x1) != | ||
519 | (test_bit(i, obj->bit_17) != 0)) { | ||
520 | i915_gem_swizzle_page(page); | ||
521 | set_page_dirty(page); | ||
522 | } | ||
523 | i++; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | void | ||
528 | i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) | ||
529 | { | ||
530 | struct sg_page_iter sg_iter; | ||
531 | int page_count = obj->base.size >> PAGE_SHIFT; | ||
532 | int i; | ||
533 | |||
534 | if (obj->bit_17 == NULL) { | ||
535 | obj->bit_17 = kcalloc(BITS_TO_LONGS(page_count), | ||
536 | sizeof(long), GFP_KERNEL); | ||
537 | if (obj->bit_17 == NULL) { | ||
538 | DRM_ERROR("Failed to allocate memory for bit 17 " | ||
539 | "record\n"); | ||
540 | return; | ||
541 | } | ||
542 | } | ||
543 | |||
544 | i = 0; | ||
545 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | ||
546 | if (page_to_phys(sg_page_iter_page(&sg_iter)) & (1 << 17)) | ||
547 | __set_bit(i, obj->bit_17); | ||
548 | else | ||
549 | __clear_bit(i, obj->bit_17); | ||
550 | i++; | ||
551 | } | ||
552 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 6f4256918f76..41d0739e6fdf 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -369,6 +369,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
369 | err_printf(m, "Reset count: %u\n", error->reset_count); | 369 | err_printf(m, "Reset count: %u\n", error->reset_count); |
370 | err_printf(m, "Suspend count: %u\n", error->suspend_count); | 370 | err_printf(m, "Suspend count: %u\n", error->suspend_count); |
371 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); | 371 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
372 | err_printf(m, "IOMMU enabled?: %d\n", error->iommu); | ||
372 | err_printf(m, "EIR: 0x%08x\n", error->eir); | 373 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
373 | err_printf(m, "IER: 0x%08x\n", error->ier); | 374 | err_printf(m, "IER: 0x%08x\n", error->ier); |
374 | if (INTEL_INFO(dev)->gen >= 8) { | 375 | if (INTEL_INFO(dev)->gen >= 8) { |
@@ -1266,6 +1267,10 @@ static void i915_error_capture_msg(struct drm_device *dev, | |||
1266 | static void i915_capture_gen_state(struct drm_i915_private *dev_priv, | 1267 | static void i915_capture_gen_state(struct drm_i915_private *dev_priv, |
1267 | struct drm_i915_error_state *error) | 1268 | struct drm_i915_error_state *error) |
1268 | { | 1269 | { |
1270 | error->iommu = -1; | ||
1271 | #ifdef CONFIG_INTEL_IOMMU | ||
1272 | error->iommu = intel_iommu_gfx_mapped; | ||
1273 | #endif | ||
1269 | error->reset_count = i915_reset_count(&dev_priv->gpu_error); | 1274 | error->reset_count = i915_reset_count(&dev_priv->gpu_error); |
1270 | error->suspend_count = dev_priv->suspend_count; | 1275 | error->suspend_count = dev_priv->suspend_count; |
1271 | } | 1276 | } |
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h new file mode 100644 index 000000000000..ccdc6c8ac20b --- /dev/null +++ b/drivers/gpu/drm/i915/i915_guc_reg.h | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Copyright © 2014 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | */ | ||
24 | #ifndef _I915_GUC_REG_H_ | ||
25 | #define _I915_GUC_REG_H_ | ||
26 | |||
27 | /* Definitions of GuC H/W registers, bits, etc */ | ||
28 | |||
29 | #define GUC_STATUS 0xc000 | ||
30 | #define GS_BOOTROM_SHIFT 1 | ||
31 | #define GS_BOOTROM_MASK (0x7F << GS_BOOTROM_SHIFT) | ||
32 | #define GS_BOOTROM_RSA_FAILED (0x50 << GS_BOOTROM_SHIFT) | ||
33 | #define GS_UKERNEL_SHIFT 8 | ||
34 | #define GS_UKERNEL_MASK (0xFF << GS_UKERNEL_SHIFT) | ||
35 | #define GS_UKERNEL_LAPIC_DONE (0x30 << GS_UKERNEL_SHIFT) | ||
36 | #define GS_UKERNEL_DPC_ERROR (0x60 << GS_UKERNEL_SHIFT) | ||
37 | #define GS_UKERNEL_READY (0xF0 << GS_UKERNEL_SHIFT) | ||
38 | #define GS_MIA_SHIFT 16 | ||
39 | #define GS_MIA_MASK (0x07 << GS_MIA_SHIFT) | ||
40 | |||
41 | #define GUC_WOPCM_SIZE 0xc050 | ||
42 | #define GUC_WOPCM_SIZE_VALUE (0x80 << 12) /* 512KB */ | ||
43 | #define GUC_WOPCM_OFFSET 0x80000 /* 512KB */ | ||
44 | |||
45 | #define SOFT_SCRATCH(n) (0xc180 + ((n) * 4)) | ||
46 | |||
47 | #define UOS_RSA_SCRATCH_0 0xc200 | ||
48 | #define DMA_ADDR_0_LOW 0xc300 | ||
49 | #define DMA_ADDR_0_HIGH 0xc304 | ||
50 | #define DMA_ADDR_1_LOW 0xc308 | ||
51 | #define DMA_ADDR_1_HIGH 0xc30c | ||
52 | #define DMA_ADDRESS_SPACE_WOPCM (7 << 16) | ||
53 | #define DMA_ADDRESS_SPACE_GTT (8 << 16) | ||
54 | #define DMA_COPY_SIZE 0xc310 | ||
55 | #define DMA_CTRL 0xc314 | ||
56 | #define UOS_MOVE (1<<4) | ||
57 | #define START_DMA (1<<0) | ||
58 | #define DMA_GUC_WOPCM_OFFSET 0xc340 | ||
59 | |||
60 | #define GEN8_GT_PM_CONFIG 0x138140 | ||
61 | #define GEN9_GT_PM_CONFIG 0x13816c | ||
62 | #define GEN8_GT_DOORBELL_ENABLE (1<<0) | ||
63 | |||
64 | #define GEN8_GTCR 0x4274 | ||
65 | #define GEN8_GTCR_INVALIDATE (1<<0) | ||
66 | |||
67 | #define GUC_ARAT_C6DIS 0xA178 | ||
68 | |||
69 | #define GUC_SHIM_CONTROL 0xc064 | ||
70 | #define GUC_DISABLE_SRAM_INIT_TO_ZEROES (1<<0) | ||
71 | #define GUC_ENABLE_READ_CACHE_LOGIC (1<<1) | ||
72 | #define GUC_ENABLE_MIA_CACHING (1<<2) | ||
73 | #define GUC_GEN10_MSGCH_ENABLE (1<<4) | ||
74 | #define GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA (1<<9) | ||
75 | #define GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA (1<<10) | ||
76 | #define GUC_ENABLE_MIA_CLOCK_GATING (1<<15) | ||
77 | #define GUC_GEN10_SHIM_WC_ENABLE (1<<21) | ||
78 | |||
79 | #define GUC_SHIM_CONTROL_VALUE (GUC_DISABLE_SRAM_INIT_TO_ZEROES | \ | ||
80 | GUC_ENABLE_READ_CACHE_LOGIC | \ | ||
81 | GUC_ENABLE_MIA_CACHING | \ | ||
82 | GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | \ | ||
83 | GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA) | ||
84 | |||
85 | #define HOST2GUC_INTERRUPT 0xc4c8 | ||
86 | #define HOST2GUC_TRIGGER (1<<0) | ||
87 | |||
88 | #define DRBMISC1 0x1984 | ||
89 | #define DOORBELL_ENABLE (1<<0) | ||
90 | |||
91 | #define GEN8_DRBREGL(x) (0x1000 + (x) * 8) | ||
92 | #define GEN8_DRB_VALID (1<<0) | ||
93 | #define GEN8_DRBREGU(x) (GEN8_DRBREGL(x) + 4) | ||
94 | |||
95 | #define DE_GUCRMR 0x44054 | ||
96 | |||
97 | #define GUC_BCS_RCS_IER 0xC550 | ||
98 | #define GUC_VCS2_VCS1_IER 0xC554 | ||
99 | #define GUC_WD_VECS_IER 0xC558 | ||
100 | #define GUC_PM_P24C_IER 0xC55C | ||
101 | |||
102 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d87f173a0179..1118c39281f9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1227,6 +1227,22 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, | |||
1227 | return ret; | 1227 | return ret; |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | static bool bxt_port_hotplug_long_detect(enum port port, u32 val) | ||
1231 | { | ||
1232 | switch (port) { | ||
1233 | case PORT_A: | ||
1234 | return val & BXT_PORTA_HOTPLUG_LONG_DETECT; | ||
1235 | case PORT_B: | ||
1236 | return val & PORTB_HOTPLUG_LONG_DETECT; | ||
1237 | case PORT_C: | ||
1238 | return val & PORTC_HOTPLUG_LONG_DETECT; | ||
1239 | case PORT_D: | ||
1240 | return val & PORTD_HOTPLUG_LONG_DETECT; | ||
1241 | default: | ||
1242 | return false; | ||
1243 | } | ||
1244 | } | ||
1245 | |||
1230 | static bool pch_port_hotplug_long_detect(enum port port, u32 val) | 1246 | static bool pch_port_hotplug_long_detect(enum port port, u32 val) |
1231 | { | 1247 | { |
1232 | switch (port) { | 1248 | switch (port) { |
@@ -1256,9 +1272,10 @@ static bool i9xx_port_hotplug_long_detect(enum port port, u32 val) | |||
1256 | } | 1272 | } |
1257 | 1273 | ||
1258 | /* Get a bit mask of pins that have triggered, and which ones may be long. */ | 1274 | /* Get a bit mask of pins that have triggered, and which ones may be long. */ |
1259 | static void pch_get_hpd_pins(u32 *pin_mask, u32 *long_mask, | 1275 | static void intel_get_hpd_pins(u32 *pin_mask, u32 *long_mask, |
1260 | u32 hotplug_trigger, u32 dig_hotplug_reg, | 1276 | u32 hotplug_trigger, u32 dig_hotplug_reg, |
1261 | const u32 hpd[HPD_NUM_PINS]) | 1277 | const u32 hpd[HPD_NUM_PINS], |
1278 | bool long_pulse_detect(enum port port, u32 val)) | ||
1262 | { | 1279 | { |
1263 | enum port port; | 1280 | enum port port; |
1264 | int i; | 1281 | int i; |
@@ -1272,8 +1289,10 @@ static void pch_get_hpd_pins(u32 *pin_mask, u32 *long_mask, | |||
1272 | 1289 | ||
1273 | *pin_mask |= BIT(i); | 1290 | *pin_mask |= BIT(i); |
1274 | 1291 | ||
1275 | port = intel_hpd_pin_to_port(i); | 1292 | if (!intel_hpd_pin_to_port(i, &port)) |
1276 | if (pch_port_hotplug_long_detect(port, dig_hotplug_reg)) | 1293 | continue; |
1294 | |||
1295 | if (long_pulse_detect(port, dig_hotplug_reg)) | ||
1277 | *long_mask |= BIT(i); | 1296 | *long_mask |= BIT(i); |
1278 | } | 1297 | } |
1279 | 1298 | ||
@@ -1282,34 +1301,6 @@ static void pch_get_hpd_pins(u32 *pin_mask, u32 *long_mask, | |||
1282 | 1301 | ||
1283 | } | 1302 | } |
1284 | 1303 | ||
1285 | /* Get a bit mask of pins that have triggered, and which ones may be long. */ | ||
1286 | static void i9xx_get_hpd_pins(u32 *pin_mask, u32 *long_mask, | ||
1287 | u32 hotplug_trigger, const u32 hpd[HPD_NUM_PINS]) | ||
1288 | { | ||
1289 | enum port port; | ||
1290 | int i; | ||
1291 | |||
1292 | *pin_mask = 0; | ||
1293 | *long_mask = 0; | ||
1294 | |||
1295 | if (!hotplug_trigger) | ||
1296 | return; | ||
1297 | |||
1298 | for_each_hpd_pin(i) { | ||
1299 | if ((hpd[i] & hotplug_trigger) == 0) | ||
1300 | continue; | ||
1301 | |||
1302 | *pin_mask |= BIT(i); | ||
1303 | |||
1304 | port = intel_hpd_pin_to_port(i); | ||
1305 | if (i9xx_port_hotplug_long_detect(port, hotplug_trigger)) | ||
1306 | *long_mask |= BIT(i); | ||
1307 | } | ||
1308 | |||
1309 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x, pins 0x%08x\n", | ||
1310 | hotplug_trigger, *pin_mask); | ||
1311 | } | ||
1312 | |||
1313 | static void gmbus_irq_handler(struct drm_device *dev) | 1304 | static void gmbus_irq_handler(struct drm_device *dev) |
1314 | { | 1305 | { |
1315 | struct drm_i915_private *dev_priv = dev->dev_private; | 1306 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1547,7 +1538,9 @@ static void i9xx_hpd_irq_handler(struct drm_device *dev) | |||
1547 | if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { | 1538 | if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { |
1548 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; | 1539 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; |
1549 | 1540 | ||
1550 | i9xx_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, hpd_status_g4x); | 1541 | intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, |
1542 | hotplug_trigger, hpd_status_g4x, | ||
1543 | i9xx_port_hotplug_long_detect); | ||
1551 | intel_hpd_irq_handler(dev, pin_mask, long_mask); | 1544 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
1552 | 1545 | ||
1553 | if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) | 1546 | if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) |
@@ -1555,7 +1548,9 @@ static void i9xx_hpd_irq_handler(struct drm_device *dev) | |||
1555 | } else { | 1548 | } else { |
1556 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; | 1549 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
1557 | 1550 | ||
1558 | i9xx_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, hpd_status_i915); | 1551 | intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, |
1552 | hotplug_trigger, hpd_status_g4x, | ||
1553 | i9xx_port_hotplug_long_detect); | ||
1559 | intel_hpd_irq_handler(dev, pin_mask, long_mask); | 1554 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
1560 | } | 1555 | } |
1561 | } | 1556 | } |
@@ -1662,8 +1657,9 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) | |||
1662 | dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); | 1657 | dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); |
1663 | I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); | 1658 | I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); |
1664 | 1659 | ||
1665 | pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, | 1660 | intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, |
1666 | dig_hotplug_reg, hpd_ibx); | 1661 | dig_hotplug_reg, hpd_ibx, |
1662 | pch_port_hotplug_long_detect); | ||
1667 | intel_hpd_irq_handler(dev, pin_mask, long_mask); | 1663 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
1668 | } | 1664 | } |
1669 | 1665 | ||
@@ -1763,8 +1759,10 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) | |||
1763 | 1759 | ||
1764 | dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); | 1760 | dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); |
1765 | I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); | 1761 | I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); |
1766 | pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, | 1762 | |
1767 | dig_hotplug_reg, hpd_cpt); | 1763 | intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, |
1764 | dig_hotplug_reg, hpd_cpt, | ||
1765 | pch_port_hotplug_long_detect); | ||
1768 | intel_hpd_irq_handler(dev, pin_mask, long_mask); | 1766 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
1769 | } | 1767 | } |
1770 | 1768 | ||
@@ -1981,7 +1979,8 @@ static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status) | |||
1981 | /* Clear sticky bits in hpd status */ | 1979 | /* Clear sticky bits in hpd status */ |
1982 | I915_WRITE(BXT_HOTPLUG_CTL, hp_control); | 1980 | I915_WRITE(BXT_HOTPLUG_CTL, hp_control); |
1983 | 1981 | ||
1984 | pch_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, hpd_bxt); | 1982 | intel_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, |
1983 | hpd_bxt, bxt_port_hotplug_long_detect); | ||
1985 | intel_hpd_irq_handler(dev, pin_mask, long_mask); | 1984 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
1986 | } | 1985 | } |
1987 | 1986 | ||
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 5f4e7295295f..5ae4b0aba564 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c | |||
@@ -52,6 +52,8 @@ struct i915_params i915 __read_mostly = { | |||
52 | .mmio_debug = 0, | 52 | .mmio_debug = 0, |
53 | .verbose_state_checks = 1, | 53 | .verbose_state_checks = 1, |
54 | .edp_vswing = 0, | 54 | .edp_vswing = 0, |
55 | .enable_guc_submission = false, | ||
56 | .guc_log_level = -1, | ||
55 | }; | 57 | }; |
56 | 58 | ||
57 | module_param_named(modeset, i915.modeset, int, 0400); | 59 | module_param_named(modeset, i915.modeset, int, 0400); |
@@ -181,3 +183,10 @@ MODULE_PARM_DESC(edp_vswing, | |||
181 | "Ignore/Override vswing pre-emph table selection from VBT " | 183 | "Ignore/Override vswing pre-emph table selection from VBT " |
182 | "(0=use value from vbt [default], 1=low power swing(200mV)," | 184 | "(0=use value from vbt [default], 1=low power swing(200mV)," |
183 | "2=default swing(400mV))"); | 185 | "2=default swing(400mV))"); |
186 | |||
187 | module_param_named_unsafe(enable_guc_submission, i915.enable_guc_submission, bool, 0400); | ||
188 | MODULE_PARM_DESC(enable_guc_submission, "Enable GuC submission (default:false)"); | ||
189 | |||
190 | module_param_named(guc_log_level, i915.guc_log_level, int, 0400); | ||
191 | MODULE_PARM_DESC(guc_log_level, | ||
192 | "GuC firmware logging level (-1:disabled (default), 0-3:enabled)"); | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e9a95df639f0..8e46c348366b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -178,13 +178,22 @@ | |||
178 | #define GAB_CTL 0x24000 | 178 | #define GAB_CTL 0x24000 |
179 | #define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) | 179 | #define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) |
180 | 180 | ||
181 | #define GEN7_BIOS_RESERVED 0x1082C0 | 181 | #define GEN6_STOLEN_RESERVED 0x1082C0 |
182 | #define GEN7_BIOS_RESERVED_1M (0 << 5) | 182 | #define GEN6_STOLEN_RESERVED_ADDR_MASK (0xFFF << 20) |
183 | #define GEN7_BIOS_RESERVED_256K (1 << 5) | 183 | #define GEN7_STOLEN_RESERVED_ADDR_MASK (0x3FFF << 18) |
184 | #define GEN8_BIOS_RESERVED_SHIFT 7 | 184 | #define GEN6_STOLEN_RESERVED_SIZE_MASK (3 << 4) |
185 | #define GEN7_BIOS_RESERVED_MASK 0x1 | 185 | #define GEN6_STOLEN_RESERVED_1M (0 << 4) |
186 | #define GEN8_BIOS_RESERVED_MASK 0x3 | 186 | #define GEN6_STOLEN_RESERVED_512K (1 << 4) |
187 | 187 | #define GEN6_STOLEN_RESERVED_256K (2 << 4) | |
188 | #define GEN6_STOLEN_RESERVED_128K (3 << 4) | ||
189 | #define GEN7_STOLEN_RESERVED_SIZE_MASK (1 << 5) | ||
190 | #define GEN7_STOLEN_RESERVED_1M (0 << 5) | ||
191 | #define GEN7_STOLEN_RESERVED_256K (1 << 5) | ||
192 | #define GEN8_STOLEN_RESERVED_SIZE_MASK (3 << 7) | ||
193 | #define GEN8_STOLEN_RESERVED_1M (0 << 7) | ||
194 | #define GEN8_STOLEN_RESERVED_2M (1 << 7) | ||
195 | #define GEN8_STOLEN_RESERVED_4M (2 << 7) | ||
196 | #define GEN8_STOLEN_RESERVED_8M (3 << 7) | ||
188 | 197 | ||
189 | /* VGA stuff */ | 198 | /* VGA stuff */ |
190 | 199 | ||
@@ -5985,6 +5994,11 @@ enum skl_disp_power_wells { | |||
5985 | 5994 | ||
5986 | /* digital port hotplug */ | 5995 | /* digital port hotplug */ |
5987 | #define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ | 5996 | #define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ |
5997 | #define BXT_PORTA_HOTPLUG_ENABLE (1 << 28) | ||
5998 | #define BXT_PORTA_HOTPLUG_STATUS_MASK (0x3 << 24) | ||
5999 | #define BXT_PORTA_HOTPLUG_NO_DETECT (0 << 24) | ||
6000 | #define BXT_PORTA_HOTPLUG_SHORT_DETECT (1 << 24) | ||
6001 | #define BXT_PORTA_HOTPLUG_LONG_DETECT (2 << 24) | ||
5988 | #define PORTD_HOTPLUG_ENABLE (1 << 20) | 6002 | #define PORTD_HOTPLUG_ENABLE (1 << 20) |
5989 | #define PORTD_PULSE_DURATION_2ms (0) | 6003 | #define PORTD_PULSE_DURATION_2ms (0) |
5990 | #define PORTD_PULSE_DURATION_4_5ms (1 << 18) | 6004 | #define PORTD_PULSE_DURATION_4_5ms (1 << 18) |
@@ -6846,6 +6860,9 @@ enum skl_disp_power_wells { | |||
6846 | #define GEN7_MISCCPCTL (0x9424) | 6860 | #define GEN7_MISCCPCTL (0x9424) |
6847 | #define GEN7_DOP_CLOCK_GATE_ENABLE (1<<0) | 6861 | #define GEN7_DOP_CLOCK_GATE_ENABLE (1<<0) |
6848 | 6862 | ||
6863 | #define GEN8_GARBCNTL 0xB004 | ||
6864 | #define GEN9_GAPS_TSV_CREDIT_DISABLE (1<<7) | ||
6865 | |||
6849 | /* IVYBRIDGE DPF */ | 6866 | /* IVYBRIDGE DPF */ |
6850 | #define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */ | 6867 | #define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */ |
6851 | #define HSW_L3CDERRST11 0xB208 /* L3CD Error Status register 1 slice 1 */ | 6868 | #define HSW_L3CDERRST11 0xB208 /* L3CD Error Status register 1 slice 1 */ |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 31b1079cbd1b..8e46149bafdd 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -886,6 +886,17 @@ err: | |||
886 | memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence)); | 886 | memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence)); |
887 | } | 887 | } |
888 | 888 | ||
889 | static u8 translate_iboost(u8 val) | ||
890 | { | ||
891 | static const u8 mapping[] = { 1, 3, 7 }; /* See VBT spec */ | ||
892 | |||
893 | if (val >= ARRAY_SIZE(mapping)) { | ||
894 | DRM_DEBUG_KMS("Unsupported I_boost value found in VBT (%d), display may not work properly\n", val); | ||
895 | return 0; | ||
896 | } | ||
897 | return mapping[val]; | ||
898 | } | ||
899 | |||
889 | static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | 900 | static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, |
890 | const struct bdb_header *bdb) | 901 | const struct bdb_header *bdb) |
891 | { | 902 | { |
@@ -968,13 +979,28 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | |||
968 | } | 979 | } |
969 | 980 | ||
970 | if (is_dp) { | 981 | if (is_dp) { |
971 | if (aux_channel == 0x40 && port != PORT_A) | 982 | if (port == PORT_E) { |
983 | info->alternate_aux_channel = aux_channel; | ||
984 | /* if DDIE share aux channel with other port, then | ||
985 | * DP couldn't exist on the shared port. Otherwise | ||
986 | * they share the same aux channel and system | ||
987 | * couldn't communicate with them seperately. */ | ||
988 | if (aux_channel == DP_AUX_A) | ||
989 | dev_priv->vbt.ddi_port_info[PORT_A].supports_dp = 0; | ||
990 | else if (aux_channel == DP_AUX_B) | ||
991 | dev_priv->vbt.ddi_port_info[PORT_B].supports_dp = 0; | ||
992 | else if (aux_channel == DP_AUX_C) | ||
993 | dev_priv->vbt.ddi_port_info[PORT_C].supports_dp = 0; | ||
994 | else if (aux_channel == DP_AUX_D) | ||
995 | dev_priv->vbt.ddi_port_info[PORT_D].supports_dp = 0; | ||
996 | } | ||
997 | else if (aux_channel == DP_AUX_A && port != PORT_A) | ||
972 | DRM_DEBUG_KMS("Unexpected AUX channel for port A\n"); | 998 | DRM_DEBUG_KMS("Unexpected AUX channel for port A\n"); |
973 | if (aux_channel == 0x10 && port != PORT_B) | 999 | else if (aux_channel == DP_AUX_B && port != PORT_B) |
974 | DRM_DEBUG_KMS("Unexpected AUX channel for port B\n"); | 1000 | DRM_DEBUG_KMS("Unexpected AUX channel for port B\n"); |
975 | if (aux_channel == 0x20 && port != PORT_C) | 1001 | else if (aux_channel == DP_AUX_C && port != PORT_C) |
976 | DRM_DEBUG_KMS("Unexpected AUX channel for port C\n"); | 1002 | DRM_DEBUG_KMS("Unexpected AUX channel for port C\n"); |
977 | if (aux_channel == 0x30 && port != PORT_D) | 1003 | else if (aux_channel == DP_AUX_D && port != PORT_D) |
978 | DRM_DEBUG_KMS("Unexpected AUX channel for port D\n"); | 1004 | DRM_DEBUG_KMS("Unexpected AUX channel for port D\n"); |
979 | } | 1005 | } |
980 | 1006 | ||
@@ -986,6 +1012,16 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | |||
986 | hdmi_level_shift); | 1012 | hdmi_level_shift); |
987 | info->hdmi_level_shift = hdmi_level_shift; | 1013 | info->hdmi_level_shift = hdmi_level_shift; |
988 | } | 1014 | } |
1015 | |||
1016 | /* Parse the I_boost config for SKL and above */ | ||
1017 | if (bdb->version >= 196 && (child->common.flags_1 & IBOOST_ENABLE)) { | ||
1018 | info->dp_boost_level = translate_iboost(child->common.iboost_level & 0xF); | ||
1019 | DRM_DEBUG_KMS("VBT (e)DP boost level for port %c: %d\n", | ||
1020 | port_name(port), info->dp_boost_level); | ||
1021 | info->hdmi_boost_level = translate_iboost(child->common.iboost_level >> 4); | ||
1022 | DRM_DEBUG_KMS("VBT HDMI boost level for port %c: %d\n", | ||
1023 | port_name(port), info->hdmi_boost_level); | ||
1024 | } | ||
989 | } | 1025 | } |
990 | 1026 | ||
991 | static void parse_ddi_ports(struct drm_i915_private *dev_priv, | 1027 | static void parse_ddi_ports(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index f7ad6a585129..6d909efbf43f 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -231,6 +231,10 @@ struct old_child_dev_config { | |||
231 | /* This one contains field offsets that are known to be common for all BDB | 231 | /* This one contains field offsets that are known to be common for all BDB |
232 | * versions. Notice that the meaning of the contents contents may still change, | 232 | * versions. Notice that the meaning of the contents contents may still change, |
233 | * but at least the offsets are consistent. */ | 233 | * but at least the offsets are consistent. */ |
234 | |||
235 | /* Definitions for flags_1 */ | ||
236 | #define IBOOST_ENABLE (1<<3) | ||
237 | |||
234 | struct common_child_dev_config { | 238 | struct common_child_dev_config { |
235 | u16 handle; | 239 | u16 handle; |
236 | u16 device_type; | 240 | u16 device_type; |
@@ -239,8 +243,13 @@ struct common_child_dev_config { | |||
239 | u8 not_common2[2]; | 243 | u8 not_common2[2]; |
240 | u8 ddc_pin; | 244 | u8 ddc_pin; |
241 | u16 edid_ptr; | 245 | u16 edid_ptr; |
246 | u8 obsolete; | ||
247 | u8 flags_1; | ||
248 | u8 not_common3[13]; | ||
249 | u8 iboost_level; | ||
242 | } __packed; | 250 | } __packed; |
243 | 251 | ||
252 | |||
244 | /* This field changes depending on the BDB version, so the most reliable way to | 253 | /* This field changes depending on the BDB version, so the most reliable way to |
245 | * read it is by checking the BDB version and reading the raw pointer. */ | 254 | * read it is by checking the BDB version and reading the raw pointer. */ |
246 | union child_device_config { | 255 | union child_device_config { |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 5d78c1feec81..af5e43bef4a4 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -236,55 +236,6 @@ static void intel_enable_crt(struct intel_encoder *encoder) | |||
236 | intel_crt_set_dpms(encoder, crt->connector->base.dpms); | 236 | intel_crt_set_dpms(encoder, crt->connector->base.dpms); |
237 | } | 237 | } |
238 | 238 | ||
239 | /* Special dpms function to support cloning between dvo/sdvo/crt. */ | ||
240 | static int intel_crt_dpms(struct drm_connector *connector, int mode) | ||
241 | { | ||
242 | struct drm_device *dev = connector->dev; | ||
243 | struct intel_encoder *encoder = intel_attached_encoder(connector); | ||
244 | struct drm_crtc *crtc; | ||
245 | int old_dpms; | ||
246 | |||
247 | /* PCH platforms and VLV only support on/off. */ | ||
248 | if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) | ||
249 | mode = DRM_MODE_DPMS_OFF; | ||
250 | |||
251 | if (mode == connector->dpms) | ||
252 | return 0; | ||
253 | |||
254 | old_dpms = connector->dpms; | ||
255 | connector->dpms = mode; | ||
256 | |||
257 | /* Only need to change hw state when actually enabled */ | ||
258 | crtc = encoder->base.crtc; | ||
259 | if (!crtc) { | ||
260 | encoder->connectors_active = false; | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /* We need the pipe to run for anything but OFF. */ | ||
265 | if (mode == DRM_MODE_DPMS_OFF) | ||
266 | encoder->connectors_active = false; | ||
267 | else | ||
268 | encoder->connectors_active = true; | ||
269 | |||
270 | /* We call connector dpms manually below in case pipe dpms doesn't | ||
271 | * change due to cloning. */ | ||
272 | if (mode < old_dpms) { | ||
273 | /* From off to on, enable the pipe first. */ | ||
274 | intel_crtc_update_dpms(crtc); | ||
275 | |||
276 | intel_crt_set_dpms(encoder, mode); | ||
277 | } else { | ||
278 | intel_crt_set_dpms(encoder, mode); | ||
279 | |||
280 | intel_crtc_update_dpms(crtc); | ||
281 | } | ||
282 | |||
283 | intel_modeset_check_state(connector->dev); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static enum drm_mode_status | 239 | static enum drm_mode_status |
289 | intel_crt_mode_valid(struct drm_connector *connector, | 240 | intel_crt_mode_valid(struct drm_connector *connector, |
290 | struct drm_display_mode *mode) | 241 | struct drm_display_mode *mode) |
@@ -800,7 +751,7 @@ static void intel_crt_reset(struct drm_connector *connector) | |||
800 | 751 | ||
801 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 752 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
802 | .reset = intel_crt_reset, | 753 | .reset = intel_crt_reset, |
803 | .dpms = intel_crt_dpms, | 754 | .dpms = drm_atomic_helper_connector_dpms, |
804 | .detect = intel_crt_detect, | 755 | .detect = intel_crt_detect, |
805 | .fill_modes = drm_helper_probe_single_connector_modes, | 756 | .fill_modes = drm_helper_probe_single_connector_modes, |
806 | .destroy = intel_crt_destroy, | 757 | .destroy = intel_crt_destroy, |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 6d8a7bf06dfc..ba1ae031e6fd 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -244,7 +244,7 @@ void intel_csr_load_status_set(struct drm_i915_private *dev_priv, | |||
244 | void intel_csr_load_program(struct drm_device *dev) | 244 | void intel_csr_load_program(struct drm_device *dev) |
245 | { | 245 | { |
246 | struct drm_i915_private *dev_priv = dev->dev_private; | 246 | struct drm_i915_private *dev_priv = dev->dev_private; |
247 | __be32 *payload = dev_priv->csr.dmc_payload; | 247 | u32 *payload = dev_priv->csr.dmc_payload; |
248 | uint32_t i, fw_size; | 248 | uint32_t i, fw_size; |
249 | 249 | ||
250 | if (!IS_GEN9(dev)) { | 250 | if (!IS_GEN9(dev)) { |
@@ -256,7 +256,7 @@ void intel_csr_load_program(struct drm_device *dev) | |||
256 | fw_size = dev_priv->csr.dmc_fw_size; | 256 | fw_size = dev_priv->csr.dmc_fw_size; |
257 | for (i = 0; i < fw_size; i++) | 257 | for (i = 0; i < fw_size; i++) |
258 | I915_WRITE(CSR_PROGRAM_BASE + i * 4, | 258 | I915_WRITE(CSR_PROGRAM_BASE + i * 4, |
259 | (u32 __force)payload[i]); | 259 | payload[i]); |
260 | 260 | ||
261 | for (i = 0; i < dev_priv->csr.mmio_count; i++) { | 261 | for (i = 0; i < dev_priv->csr.mmio_count; i++) { |
262 | I915_WRITE(dev_priv->csr.mmioaddr[i], | 262 | I915_WRITE(dev_priv->csr.mmioaddr[i], |
@@ -279,7 +279,7 @@ static void finish_csr_load(const struct firmware *fw, void *context) | |||
279 | char substepping = intel_get_substepping(dev); | 279 | char substepping = intel_get_substepping(dev); |
280 | uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; | 280 | uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; |
281 | uint32_t i; | 281 | uint32_t i; |
282 | __be32 *dmc_payload; | 282 | uint32_t *dmc_payload; |
283 | bool fw_loaded = false; | 283 | bool fw_loaded = false; |
284 | 284 | ||
285 | if (!fw) { | 285 | if (!fw) { |
@@ -375,15 +375,7 @@ static void finish_csr_load(const struct firmware *fw, void *context) | |||
375 | } | 375 | } |
376 | 376 | ||
377 | dmc_payload = csr->dmc_payload; | 377 | dmc_payload = csr->dmc_payload; |
378 | for (i = 0; i < dmc_header->fw_size; i++) { | 378 | memcpy(dmc_payload, &fw->data[readcount], nbytes); |
379 | uint32_t *tmp = (u32 *)&fw->data[readcount + i * 4]; | ||
380 | /* | ||
381 | * The firmware payload is an array of 32 bit words stored in | ||
382 | * little-endian format in the firmware image and programmed | ||
383 | * as 32 bit big-endian format to memory. | ||
384 | */ | ||
385 | dmc_payload[i] = cpu_to_be32(*tmp); | ||
386 | } | ||
387 | 379 | ||
388 | /* load csr program during system boot, as needed for DC states */ | 380 | /* load csr program during system boot, as needed for DC states */ |
389 | intel_csr_load_program(dev); | 381 | intel_csr_load_program(dev); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9a40bfb20e0c..6cfe65d6a8cf 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -440,6 +440,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, | |||
440 | { | 440 | { |
441 | struct drm_i915_private *dev_priv = dev->dev_private; | 441 | struct drm_i915_private *dev_priv = dev->dev_private; |
442 | u32 reg; | 442 | u32 reg; |
443 | u32 iboost_bit = 0; | ||
443 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, | 444 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, |
444 | size; | 445 | size; |
445 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | 446 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; |
@@ -466,6 +467,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, | |||
466 | ddi_translations_hdmi = | 467 | ddi_translations_hdmi = |
467 | skl_get_buf_trans_hdmi(dev, &n_hdmi_entries); | 468 | skl_get_buf_trans_hdmi(dev, &n_hdmi_entries); |
468 | hdmi_default_entry = 8; | 469 | hdmi_default_entry = 8; |
470 | /* If we're boosting the current, set bit 31 of trans1 */ | ||
471 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || | ||
472 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) | ||
473 | iboost_bit = 1<<31; | ||
469 | } else if (IS_BROADWELL(dev)) { | 474 | } else if (IS_BROADWELL(dev)) { |
470 | ddi_translations_fdi = bdw_ddi_translations_fdi; | 475 | ddi_translations_fdi = bdw_ddi_translations_fdi; |
471 | ddi_translations_dp = bdw_ddi_translations_dp; | 476 | ddi_translations_dp = bdw_ddi_translations_dp; |
@@ -526,7 +531,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, | |||
526 | } | 531 | } |
527 | 532 | ||
528 | for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) { | 533 | for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) { |
529 | I915_WRITE(reg, ddi_translations[i].trans1); | 534 | I915_WRITE(reg, ddi_translations[i].trans1 | iboost_bit); |
530 | reg += 4; | 535 | reg += 4; |
531 | I915_WRITE(reg, ddi_translations[i].trans2); | 536 | I915_WRITE(reg, ddi_translations[i].trans2); |
532 | reg += 4; | 537 | reg += 4; |
@@ -541,7 +546,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, | |||
541 | hdmi_level = hdmi_default_entry; | 546 | hdmi_level = hdmi_default_entry; |
542 | 547 | ||
543 | /* Entry 9 is for HDMI: */ | 548 | /* Entry 9 is for HDMI: */ |
544 | I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1); | 549 | I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); |
545 | reg += 4; | 550 | reg += 4; |
546 | I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2); | 551 | I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2); |
547 | reg += 4; | 552 | reg += 4; |
@@ -2078,18 +2083,35 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level, | |||
2078 | struct drm_i915_private *dev_priv = dev->dev_private; | 2083 | struct drm_i915_private *dev_priv = dev->dev_private; |
2079 | const struct ddi_buf_trans *ddi_translations; | 2084 | const struct ddi_buf_trans *ddi_translations; |
2080 | uint8_t iboost; | 2085 | uint8_t iboost; |
2086 | uint8_t dp_iboost, hdmi_iboost; | ||
2081 | int n_entries; | 2087 | int n_entries; |
2082 | u32 reg; | 2088 | u32 reg; |
2083 | 2089 | ||
2090 | /* VBT may override standard boost values */ | ||
2091 | dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; | ||
2092 | hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level; | ||
2093 | |||
2084 | if (type == INTEL_OUTPUT_DISPLAYPORT) { | 2094 | if (type == INTEL_OUTPUT_DISPLAYPORT) { |
2085 | ddi_translations = skl_get_buf_trans_dp(dev, &n_entries); | 2095 | if (dp_iboost) { |
2086 | iboost = ddi_translations[port].i_boost; | 2096 | iboost = dp_iboost; |
2097 | } else { | ||
2098 | ddi_translations = skl_get_buf_trans_dp(dev, &n_entries); | ||
2099 | iboost = ddi_translations[port].i_boost; | ||
2100 | } | ||
2087 | } else if (type == INTEL_OUTPUT_EDP) { | 2101 | } else if (type == INTEL_OUTPUT_EDP) { |
2088 | ddi_translations = skl_get_buf_trans_edp(dev, &n_entries); | 2102 | if (dp_iboost) { |
2089 | iboost = ddi_translations[port].i_boost; | 2103 | iboost = dp_iboost; |
2104 | } else { | ||
2105 | ddi_translations = skl_get_buf_trans_edp(dev, &n_entries); | ||
2106 | iboost = ddi_translations[port].i_boost; | ||
2107 | } | ||
2090 | } else if (type == INTEL_OUTPUT_HDMI) { | 2108 | } else if (type == INTEL_OUTPUT_HDMI) { |
2091 | ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries); | 2109 | if (hdmi_iboost) { |
2092 | iboost = ddi_translations[port].i_boost; | 2110 | iboost = hdmi_iboost; |
2111 | } else { | ||
2112 | ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries); | ||
2113 | iboost = ddi_translations[port].i_boost; | ||
2114 | } | ||
2093 | } else { | 2115 | } else { |
2094 | return; | 2116 | return; |
2095 | } | 2117 | } |
@@ -3184,10 +3206,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port) | |||
3184 | dev_priv->vbt.ddi_port_info[port].supports_hdmi); | 3206 | dev_priv->vbt.ddi_port_info[port].supports_hdmi); |
3185 | init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp; | 3207 | init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp; |
3186 | if (!init_dp && !init_hdmi) { | 3208 | if (!init_dp && !init_hdmi) { |
3187 | DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n", | 3209 | DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n", |
3188 | port_name(port)); | 3210 | port_name(port)); |
3189 | init_hdmi = true; | 3211 | return; |
3190 | init_dp = true; | ||
3191 | } | 3212 | } |
3192 | 3213 | ||
3193 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); | 3214 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0a1d4a5d152d..83936403502f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1936,7 +1936,9 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) | |||
1936 | struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); | 1936 | struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); |
1937 | 1937 | ||
1938 | /* PCH only available on ILK+ */ | 1938 | /* PCH only available on ILK+ */ |
1939 | BUG_ON(INTEL_INFO(dev)->gen < 5); | 1939 | if (INTEL_INFO(dev)->gen < 5) |
1940 | return; | ||
1941 | |||
1940 | if (pll == NULL) | 1942 | if (pll == NULL) |
1941 | return; | 1943 | return; |
1942 | 1944 | ||
@@ -2395,7 +2397,18 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, | |||
2395 | * a fence as the cost is not that onerous. | 2397 | * a fence as the cost is not that onerous. |
2396 | */ | 2398 | */ |
2397 | ret = i915_gem_object_get_fence(obj); | 2399 | ret = i915_gem_object_get_fence(obj); |
2398 | if (ret) | 2400 | if (ret == -EDEADLK) { |
2401 | /* | ||
2402 | * -EDEADLK means there are no free fences | ||
2403 | * no pending flips. | ||
2404 | * | ||
2405 | * This is propagated to atomic, but it uses | ||
2406 | * -EDEADLK to force a locking recovery, so | ||
2407 | * change the returned error to -EBUSY. | ||
2408 | */ | ||
2409 | ret = -EBUSY; | ||
2410 | goto err_unpin; | ||
2411 | } else if (ret) | ||
2399 | goto err_unpin; | 2412 | goto err_unpin; |
2400 | 2413 | ||
2401 | i915_gem_object_pin_fence(obj); | 2414 | i915_gem_object_pin_fence(obj); |
@@ -5134,6 +5147,7 @@ static enum intel_display_power_domain port_to_power_domain(enum port port) | |||
5134 | { | 5147 | { |
5135 | switch (port) { | 5148 | switch (port) { |
5136 | case PORT_A: | 5149 | case PORT_A: |
5150 | case PORT_E: | ||
5137 | return POWER_DOMAIN_PORT_DDI_A_4_LANES; | 5151 | return POWER_DOMAIN_PORT_DDI_A_4_LANES; |
5138 | case PORT_B: | 5152 | case PORT_B: |
5139 | return POWER_DOMAIN_PORT_DDI_B_4_LANES; | 5153 | return POWER_DOMAIN_PORT_DDI_B_4_LANES; |
@@ -6271,67 +6285,6 @@ free: | |||
6271 | return ret; | 6285 | return ret; |
6272 | } | 6286 | } |
6273 | 6287 | ||
6274 | /* Master function to enable/disable CRTC and corresponding power wells */ | ||
6275 | int intel_crtc_control(struct drm_crtc *crtc, bool enable) | ||
6276 | { | ||
6277 | struct drm_device *dev = crtc->dev; | ||
6278 | struct drm_mode_config *config = &dev->mode_config; | ||
6279 | struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx; | ||
6280 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6281 | struct intel_crtc_state *pipe_config; | ||
6282 | struct drm_atomic_state *state; | ||
6283 | int ret; | ||
6284 | |||
6285 | if (enable == intel_crtc->active) | ||
6286 | return 0; | ||
6287 | |||
6288 | if (enable && !crtc->state->enable) | ||
6289 | return 0; | ||
6290 | |||
6291 | /* this function should be called with drm_modeset_lock_all for now */ | ||
6292 | if (WARN_ON(!ctx)) | ||
6293 | return -EIO; | ||
6294 | lockdep_assert_held(&ctx->ww_ctx); | ||
6295 | |||
6296 | state = drm_atomic_state_alloc(dev); | ||
6297 | if (WARN_ON(!state)) | ||
6298 | return -ENOMEM; | ||
6299 | |||
6300 | state->acquire_ctx = ctx; | ||
6301 | state->allow_modeset = true; | ||
6302 | |||
6303 | pipe_config = intel_atomic_get_crtc_state(state, intel_crtc); | ||
6304 | if (IS_ERR(pipe_config)) { | ||
6305 | ret = PTR_ERR(pipe_config); | ||
6306 | goto err; | ||
6307 | } | ||
6308 | pipe_config->base.active = enable; | ||
6309 | |||
6310 | ret = drm_atomic_commit(state); | ||
6311 | if (!ret) | ||
6312 | return ret; | ||
6313 | |||
6314 | err: | ||
6315 | DRM_ERROR("Updating crtc active failed with %i\n", ret); | ||
6316 | drm_atomic_state_free(state); | ||
6317 | return ret; | ||
6318 | } | ||
6319 | |||
6320 | /** | ||
6321 | * Sets the power management mode of the pipe and plane. | ||
6322 | */ | ||
6323 | void intel_crtc_update_dpms(struct drm_crtc *crtc) | ||
6324 | { | ||
6325 | struct drm_device *dev = crtc->dev; | ||
6326 | struct intel_encoder *intel_encoder; | ||
6327 | bool enable = false; | ||
6328 | |||
6329 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) | ||
6330 | enable |= intel_encoder->connectors_active; | ||
6331 | |||
6332 | intel_crtc_control(crtc, enable); | ||
6333 | } | ||
6334 | |||
6335 | void intel_encoder_destroy(struct drm_encoder *encoder) | 6288 | void intel_encoder_destroy(struct drm_encoder *encoder) |
6336 | { | 6289 | { |
6337 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | 6290 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
@@ -6340,62 +6293,42 @@ void intel_encoder_destroy(struct drm_encoder *encoder) | |||
6340 | kfree(intel_encoder); | 6293 | kfree(intel_encoder); |
6341 | } | 6294 | } |
6342 | 6295 | ||
6343 | /* Simple dpms helper for encoders with just one connector, no cloning and only | ||
6344 | * one kind of off state. It clamps all !ON modes to fully OFF and changes the | ||
6345 | * state of the entire output pipe. */ | ||
6346 | static void intel_encoder_dpms(struct intel_encoder *encoder, int mode) | ||
6347 | { | ||
6348 | if (mode == DRM_MODE_DPMS_ON) { | ||
6349 | encoder->connectors_active = true; | ||
6350 | |||
6351 | intel_crtc_update_dpms(encoder->base.crtc); | ||
6352 | } else { | ||
6353 | encoder->connectors_active = false; | ||
6354 | |||
6355 | intel_crtc_update_dpms(encoder->base.crtc); | ||
6356 | } | ||
6357 | } | ||
6358 | |||
6359 | /* Cross check the actual hw state with our own modeset state tracking (and it's | 6296 | /* Cross check the actual hw state with our own modeset state tracking (and it's |
6360 | * internal consistency). */ | 6297 | * internal consistency). */ |
6361 | static void intel_connector_check_state(struct intel_connector *connector) | 6298 | static void intel_connector_check_state(struct intel_connector *connector) |
6362 | { | 6299 | { |
6300 | struct drm_crtc *crtc = connector->base.state->crtc; | ||
6301 | |||
6302 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | ||
6303 | connector->base.base.id, | ||
6304 | connector->base.name); | ||
6305 | |||
6363 | if (connector->get_hw_state(connector)) { | 6306 | if (connector->get_hw_state(connector)) { |
6364 | struct intel_encoder *encoder = connector->encoder; | 6307 | struct drm_encoder *encoder = &connector->encoder->base; |
6365 | struct drm_crtc *crtc; | 6308 | struct drm_connector_state *conn_state = connector->base.state; |
6366 | bool encoder_enabled; | ||
6367 | enum pipe pipe; | ||
6368 | 6309 | ||
6369 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | 6310 | I915_STATE_WARN(!crtc, |
6370 | connector->base.base.id, | 6311 | "connector enabled without attached crtc\n"); |
6371 | connector->base.name); | ||
6372 | 6312 | ||
6373 | /* there is no real hw state for MST connectors */ | 6313 | if (!crtc) |
6374 | if (connector->mst_port) | ||
6375 | return; | 6314 | return; |
6376 | 6315 | ||
6377 | I915_STATE_WARN(connector->base.dpms == DRM_MODE_DPMS_OFF, | 6316 | I915_STATE_WARN(!crtc->state->active, |
6378 | "wrong connector dpms state\n"); | 6317 | "connector is active, but attached crtc isn't\n"); |
6379 | I915_STATE_WARN(connector->base.encoder != &encoder->base, | ||
6380 | "active connector not linked to encoder\n"); | ||
6381 | 6318 | ||
6382 | if (encoder) { | 6319 | if (!encoder) |
6383 | I915_STATE_WARN(!encoder->connectors_active, | 6320 | return; |
6384 | "encoder->connectors_active not set\n"); | ||
6385 | |||
6386 | encoder_enabled = encoder->get_hw_state(encoder, &pipe); | ||
6387 | I915_STATE_WARN(!encoder_enabled, "encoder not enabled\n"); | ||
6388 | if (I915_STATE_WARN_ON(!encoder->base.crtc)) | ||
6389 | return; | ||
6390 | 6321 | ||
6391 | crtc = encoder->base.crtc; | 6322 | I915_STATE_WARN(conn_state->best_encoder != encoder, |
6323 | "atomic encoder doesn't match attached encoder\n"); | ||
6392 | 6324 | ||
6393 | I915_STATE_WARN(!crtc->state->enable, | 6325 | I915_STATE_WARN(conn_state->crtc != encoder->crtc, |
6394 | "crtc not enabled\n"); | 6326 | "attached encoder crtc differs from connector crtc\n"); |
6395 | I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n"); | 6327 | } else { |
6396 | I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe, | 6328 | I915_STATE_WARN(crtc && crtc->state->active, |
6397 | "encoder active on the wrong pipe\n"); | 6329 | "attached crtc is active, but connector isn't\n"); |
6398 | } | 6330 | I915_STATE_WARN(!crtc && connector->base.state->best_encoder, |
6331 | "best encoder set without crtc!\n"); | ||
6399 | } | 6332 | } |
6400 | } | 6333 | } |
6401 | 6334 | ||
@@ -6427,28 +6360,6 @@ struct intel_connector *intel_connector_alloc(void) | |||
6427 | return connector; | 6360 | return connector; |
6428 | } | 6361 | } |
6429 | 6362 | ||
6430 | /* Even simpler default implementation, if there's really no special case to | ||
6431 | * consider. */ | ||
6432 | int intel_connector_dpms(struct drm_connector *connector, int mode) | ||
6433 | { | ||
6434 | /* All the simple cases only support two dpms states. */ | ||
6435 | if (mode != DRM_MODE_DPMS_ON) | ||
6436 | mode = DRM_MODE_DPMS_OFF; | ||
6437 | |||
6438 | if (mode == connector->dpms) | ||
6439 | return 0; | ||
6440 | |||
6441 | connector->dpms = mode; | ||
6442 | |||
6443 | /* Only need to change hw state when actually enabled */ | ||
6444 | if (connector->encoder) | ||
6445 | intel_encoder_dpms(to_intel_encoder(connector->encoder), mode); | ||
6446 | |||
6447 | intel_modeset_check_state(connector->dev); | ||
6448 | |||
6449 | return 0; | ||
6450 | } | ||
6451 | |||
6452 | /* Simple connector->get_hw_state implementation for encoders that support only | 6363 | /* Simple connector->get_hw_state implementation for encoders that support only |
6453 | * one connector and no cloning and hence the encoder state determines the state | 6364 | * one connector and no cloning and hence the encoder state determines the state |
6454 | * of the connector. */ | 6365 | * of the connector. */ |
@@ -10764,15 +10675,12 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
10764 | container_of(__work, struct intel_unpin_work, work); | 10675 | container_of(__work, struct intel_unpin_work, work); |
10765 | struct intel_crtc *crtc = to_intel_crtc(work->crtc); | 10676 | struct intel_crtc *crtc = to_intel_crtc(work->crtc); |
10766 | struct drm_device *dev = crtc->base.dev; | 10677 | struct drm_device *dev = crtc->base.dev; |
10767 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
10768 | struct drm_plane *primary = crtc->base.primary; | 10678 | struct drm_plane *primary = crtc->base.primary; |
10769 | 10679 | ||
10770 | mutex_lock(&dev->struct_mutex); | 10680 | mutex_lock(&dev->struct_mutex); |
10771 | intel_unpin_fb_obj(work->old_fb, primary->state); | 10681 | intel_unpin_fb_obj(work->old_fb, primary->state); |
10772 | drm_gem_object_unreference(&work->pending_flip_obj->base); | 10682 | drm_gem_object_unreference(&work->pending_flip_obj->base); |
10773 | 10683 | ||
10774 | intel_fbc_update(dev_priv); | ||
10775 | |||
10776 | if (work->flip_queued_req) | 10684 | if (work->flip_queued_req) |
10777 | i915_gem_request_assign(&work->flip_queued_req, NULL); | 10685 | i915_gem_request_assign(&work->flip_queued_req, NULL); |
10778 | mutex_unlock(&dev->struct_mutex); | 10686 | mutex_unlock(&dev->struct_mutex); |
@@ -11544,7 +11452,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
11544 | to_intel_plane(primary)->frontbuffer_bit); | 11452 | to_intel_plane(primary)->frontbuffer_bit); |
11545 | mutex_unlock(&dev->struct_mutex); | 11453 | mutex_unlock(&dev->struct_mutex); |
11546 | 11454 | ||
11547 | intel_fbc_disable(dev_priv); | 11455 | intel_fbc_disable_crtc(intel_crtc); |
11548 | intel_frontbuffer_flip_prepare(dev, | 11456 | intel_frontbuffer_flip_prepare(dev, |
11549 | to_intel_plane(primary)->frontbuffer_bit); | 11457 | to_intel_plane(primary)->frontbuffer_bit); |
11550 | 11458 | ||
@@ -11840,7 +11748,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, | |||
11840 | struct intel_crtc_state *pipe_config = | 11748 | struct intel_crtc_state *pipe_config = |
11841 | to_intel_crtc_state(crtc_state); | 11749 | to_intel_crtc_state(crtc_state); |
11842 | struct drm_atomic_state *state = crtc_state->state; | 11750 | struct drm_atomic_state *state = crtc_state->state; |
11843 | int ret, idx = crtc->base.id; | 11751 | int ret; |
11844 | bool mode_changed = needs_modeset(crtc_state); | 11752 | bool mode_changed = needs_modeset(crtc_state); |
11845 | 11753 | ||
11846 | if (mode_changed && !check_encoder_cloning(state, intel_crtc)) { | 11754 | if (mode_changed && !check_encoder_cloning(state, intel_crtc)) { |
@@ -11848,10 +11756,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, | |||
11848 | return -EINVAL; | 11756 | return -EINVAL; |
11849 | } | 11757 | } |
11850 | 11758 | ||
11851 | I915_STATE_WARN(crtc->state->active != intel_crtc->active, | ||
11852 | "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n", | ||
11853 | idx, crtc->state->active, intel_crtc->active); | ||
11854 | |||
11855 | if (mode_changed && !crtc_state->active) | 11759 | if (mode_changed && !crtc_state->active) |
11856 | intel_crtc->atomic.update_wm_post = true; | 11760 | intel_crtc->atomic.update_wm_post = true; |
11857 | 11761 | ||
@@ -12160,6 +12064,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) | |||
12160 | struct intel_dpll_hw_state dpll_hw_state; | 12064 | struct intel_dpll_hw_state dpll_hw_state; |
12161 | enum intel_dpll_id shared_dpll; | 12065 | enum intel_dpll_id shared_dpll; |
12162 | uint32_t ddi_pll_sel; | 12066 | uint32_t ddi_pll_sel; |
12067 | bool force_thru; | ||
12163 | 12068 | ||
12164 | /* FIXME: before the switch to atomic started, a new pipe_config was | 12069 | /* FIXME: before the switch to atomic started, a new pipe_config was |
12165 | * kzalloc'd. Code that depends on any field being zero should be | 12070 | * kzalloc'd. Code that depends on any field being zero should be |
@@ -12171,6 +12076,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) | |||
12171 | shared_dpll = crtc_state->shared_dpll; | 12076 | shared_dpll = crtc_state->shared_dpll; |
12172 | dpll_hw_state = crtc_state->dpll_hw_state; | 12077 | dpll_hw_state = crtc_state->dpll_hw_state; |
12173 | ddi_pll_sel = crtc_state->ddi_pll_sel; | 12078 | ddi_pll_sel = crtc_state->ddi_pll_sel; |
12079 | force_thru = crtc_state->pch_pfit.force_thru; | ||
12174 | 12080 | ||
12175 | memset(crtc_state, 0, sizeof *crtc_state); | 12081 | memset(crtc_state, 0, sizeof *crtc_state); |
12176 | 12082 | ||
@@ -12179,6 +12085,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) | |||
12179 | crtc_state->shared_dpll = shared_dpll; | 12085 | crtc_state->shared_dpll = shared_dpll; |
12180 | crtc_state->dpll_hw_state = dpll_hw_state; | 12086 | crtc_state->dpll_hw_state = dpll_hw_state; |
12181 | crtc_state->ddi_pll_sel = ddi_pll_sel; | 12087 | crtc_state->ddi_pll_sel = ddi_pll_sel; |
12088 | crtc_state->pch_pfit.force_thru = force_thru; | ||
12182 | } | 12089 | } |
12183 | 12090 | ||
12184 | static int | 12091 | static int |
@@ -12280,7 +12187,9 @@ encoder_retry: | |||
12280 | goto encoder_retry; | 12187 | goto encoder_retry; |
12281 | } | 12188 | } |
12282 | 12189 | ||
12283 | pipe_config->dither = pipe_config->pipe_bpp != base_bpp; | 12190 | /* Dithering seems to not pass-through bits correctly when it should, so |
12191 | * only enable it on 6bpc panels. */ | ||
12192 | pipe_config->dither = pipe_config->pipe_bpp == 6*3; | ||
12284 | DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", | 12193 | DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", |
12285 | base_bpp, pipe_config->pipe_bpp, pipe_config->dither); | 12194 | base_bpp, pipe_config->pipe_bpp, pipe_config->dither); |
12286 | 12195 | ||
@@ -12288,48 +12197,15 @@ fail: | |||
12288 | return ret; | 12197 | return ret; |
12289 | } | 12198 | } |
12290 | 12199 | ||
12291 | static bool intel_crtc_in_use(struct drm_crtc *crtc) | ||
12292 | { | ||
12293 | struct drm_encoder *encoder; | ||
12294 | struct drm_device *dev = crtc->dev; | ||
12295 | |||
12296 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
12297 | if (encoder->crtc == crtc) | ||
12298 | return true; | ||
12299 | |||
12300 | return false; | ||
12301 | } | ||
12302 | |||
12303 | static void | 12200 | static void |
12304 | intel_modeset_update_state(struct drm_atomic_state *state) | 12201 | intel_modeset_update_crtc_state(struct drm_atomic_state *state) |
12305 | { | 12202 | { |
12306 | struct drm_device *dev = state->dev; | ||
12307 | struct intel_encoder *intel_encoder; | ||
12308 | struct drm_crtc *crtc; | 12203 | struct drm_crtc *crtc; |
12309 | struct drm_crtc_state *crtc_state; | 12204 | struct drm_crtc_state *crtc_state; |
12310 | struct drm_connector *connector; | ||
12311 | int i; | 12205 | int i; |
12312 | 12206 | ||
12313 | intel_shared_dpll_commit(state); | ||
12314 | |||
12315 | for_each_intel_encoder(dev, intel_encoder) { | ||
12316 | if (!intel_encoder->base.crtc) | ||
12317 | continue; | ||
12318 | |||
12319 | crtc = intel_encoder->base.crtc; | ||
12320 | crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); | ||
12321 | if (!crtc_state || !needs_modeset(crtc->state)) | ||
12322 | continue; | ||
12323 | |||
12324 | intel_encoder->connectors_active = false; | ||
12325 | } | ||
12326 | |||
12327 | drm_atomic_helper_update_legacy_modeset_state(state->dev, state); | ||
12328 | |||
12329 | /* Double check state. */ | 12207 | /* Double check state. */ |
12330 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 12208 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
12331 | WARN_ON(crtc->state->enable != intel_crtc_in_use(crtc)); | ||
12332 | |||
12333 | to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state); | 12209 | to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state); |
12334 | 12210 | ||
12335 | /* Update hwmode for vblank functions */ | 12211 | /* Update hwmode for vblank functions */ |
@@ -12338,21 +12214,6 @@ intel_modeset_update_state(struct drm_atomic_state *state) | |||
12338 | else | 12214 | else |
12339 | crtc->hwmode.crtc_clock = 0; | 12215 | crtc->hwmode.crtc_clock = 0; |
12340 | } | 12216 | } |
12341 | |||
12342 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
12343 | if (!connector->encoder || !connector->encoder->crtc) | ||
12344 | continue; | ||
12345 | |||
12346 | crtc = connector->encoder->crtc; | ||
12347 | crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); | ||
12348 | if (!crtc_state || !needs_modeset(crtc->state)) | ||
12349 | continue; | ||
12350 | |||
12351 | if (crtc->state->active) { | ||
12352 | intel_encoder = to_intel_encoder(connector->encoder); | ||
12353 | intel_encoder->connectors_active = true; | ||
12354 | } | ||
12355 | } | ||
12356 | } | 12217 | } |
12357 | 12218 | ||
12358 | static bool intel_fuzzy_clock_check(int clock1, int clock2) | 12219 | static bool intel_fuzzy_clock_check(int clock1, int clock2) |
@@ -12702,20 +12563,23 @@ static void check_wm_state(struct drm_device *dev) | |||
12702 | } | 12563 | } |
12703 | 12564 | ||
12704 | static void | 12565 | static void |
12705 | check_connector_state(struct drm_device *dev) | 12566 | check_connector_state(struct drm_device *dev, |
12567 | struct drm_atomic_state *old_state) | ||
12706 | { | 12568 | { |
12707 | struct intel_connector *connector; | 12569 | struct drm_connector_state *old_conn_state; |
12570 | struct drm_connector *connector; | ||
12571 | int i; | ||
12708 | 12572 | ||
12709 | for_each_intel_connector(dev, connector) { | 12573 | for_each_connector_in_state(old_state, connector, old_conn_state, i) { |
12710 | struct drm_encoder *encoder = connector->base.encoder; | 12574 | struct drm_encoder *encoder = connector->encoder; |
12711 | struct drm_connector_state *state = connector->base.state; | 12575 | struct drm_connector_state *state = connector->state; |
12712 | 12576 | ||
12713 | /* This also checks the encoder/connector hw state with the | 12577 | /* This also checks the encoder/connector hw state with the |
12714 | * ->get_hw_state callbacks. */ | 12578 | * ->get_hw_state callbacks. */ |
12715 | intel_connector_check_state(connector); | 12579 | intel_connector_check_state(to_intel_connector(connector)); |
12716 | 12580 | ||
12717 | I915_STATE_WARN(state->best_encoder != encoder, | 12581 | I915_STATE_WARN(state->best_encoder != encoder, |
12718 | "connector's staged encoder doesn't match current encoder\n"); | 12582 | "connector's atomic encoder doesn't match legacy encoder\n"); |
12719 | } | 12583 | } |
12720 | } | 12584 | } |
12721 | 12585 | ||
@@ -12727,133 +12591,106 @@ check_encoder_state(struct drm_device *dev) | |||
12727 | 12591 | ||
12728 | for_each_intel_encoder(dev, encoder) { | 12592 | for_each_intel_encoder(dev, encoder) { |
12729 | bool enabled = false; | 12593 | bool enabled = false; |
12730 | bool active = false; | 12594 | enum pipe pipe; |
12731 | enum pipe pipe, tracked_pipe; | ||
12732 | 12595 | ||
12733 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", | 12596 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", |
12734 | encoder->base.base.id, | 12597 | encoder->base.base.id, |
12735 | encoder->base.name); | 12598 | encoder->base.name); |
12736 | 12599 | ||
12737 | I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc, | ||
12738 | "encoder's active_connectors set, but no crtc\n"); | ||
12739 | |||
12740 | for_each_intel_connector(dev, connector) { | 12600 | for_each_intel_connector(dev, connector) { |
12741 | if (connector->base.encoder != &encoder->base) | 12601 | if (connector->base.state->best_encoder != &encoder->base) |
12742 | continue; | 12602 | continue; |
12743 | enabled = true; | 12603 | enabled = true; |
12744 | if (connector->base.dpms != DRM_MODE_DPMS_OFF) | ||
12745 | active = true; | ||
12746 | 12604 | ||
12747 | I915_STATE_WARN(connector->base.state->crtc != | 12605 | I915_STATE_WARN(connector->base.state->crtc != |
12748 | encoder->base.crtc, | 12606 | encoder->base.crtc, |
12749 | "connector's crtc doesn't match encoder crtc\n"); | 12607 | "connector's crtc doesn't match encoder crtc\n"); |
12750 | } | 12608 | } |
12751 | /* | ||
12752 | * for MST connectors if we unplug the connector is gone | ||
12753 | * away but the encoder is still connected to a crtc | ||
12754 | * until a modeset happens in response to the hotplug. | ||
12755 | */ | ||
12756 | if (!enabled && encoder->base.encoder_type == DRM_MODE_ENCODER_DPMST) | ||
12757 | continue; | ||
12758 | 12609 | ||
12759 | I915_STATE_WARN(!!encoder->base.crtc != enabled, | 12610 | I915_STATE_WARN(!!encoder->base.crtc != enabled, |
12760 | "encoder's enabled state mismatch " | 12611 | "encoder's enabled state mismatch " |
12761 | "(expected %i, found %i)\n", | 12612 | "(expected %i, found %i)\n", |
12762 | !!encoder->base.crtc, enabled); | 12613 | !!encoder->base.crtc, enabled); |
12763 | I915_STATE_WARN(active && !encoder->base.crtc, | ||
12764 | "active encoder with no crtc\n"); | ||
12765 | 12614 | ||
12766 | I915_STATE_WARN(encoder->connectors_active != active, | 12615 | if (!encoder->base.crtc) { |
12767 | "encoder's computed active state doesn't match tracked active state " | 12616 | bool active; |
12768 | "(expected %i, found %i)\n", active, encoder->connectors_active); | ||
12769 | |||
12770 | active = encoder->get_hw_state(encoder, &pipe); | ||
12771 | I915_STATE_WARN(active != encoder->connectors_active, | ||
12772 | "encoder's hw state doesn't match sw tracking " | ||
12773 | "(expected %i, found %i)\n", | ||
12774 | encoder->connectors_active, active); | ||
12775 | |||
12776 | if (!encoder->base.crtc) | ||
12777 | continue; | ||
12778 | |||
12779 | tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe; | ||
12780 | I915_STATE_WARN(active && pipe != tracked_pipe, | ||
12781 | "active encoder's pipe doesn't match" | ||
12782 | "(expected %i, found %i)\n", | ||
12783 | tracked_pipe, pipe); | ||
12784 | 12617 | ||
12618 | active = encoder->get_hw_state(encoder, &pipe); | ||
12619 | I915_STATE_WARN(active, | ||
12620 | "encoder detached but still enabled on pipe %c.\n", | ||
12621 | pipe_name(pipe)); | ||
12622 | } | ||
12785 | } | 12623 | } |
12786 | } | 12624 | } |
12787 | 12625 | ||
12788 | static void | 12626 | static void |
12789 | check_crtc_state(struct drm_device *dev) | 12627 | check_crtc_state(struct drm_device *dev, struct drm_atomic_state *old_state) |
12790 | { | 12628 | { |
12791 | struct drm_i915_private *dev_priv = dev->dev_private; | 12629 | struct drm_i915_private *dev_priv = dev->dev_private; |
12792 | struct intel_crtc *crtc; | ||
12793 | struct intel_encoder *encoder; | 12630 | struct intel_encoder *encoder; |
12794 | struct intel_crtc_state pipe_config; | 12631 | struct drm_crtc_state *old_crtc_state; |
12632 | struct drm_crtc *crtc; | ||
12633 | int i; | ||
12795 | 12634 | ||
12796 | for_each_intel_crtc(dev, crtc) { | 12635 | for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { |
12797 | bool enabled = false; | 12636 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
12798 | bool active = false; | 12637 | struct intel_crtc_state *pipe_config, *sw_config; |
12638 | bool active; | ||
12799 | 12639 | ||
12800 | memset(&pipe_config, 0, sizeof(pipe_config)); | 12640 | if (!needs_modeset(crtc->state)) |
12641 | continue; | ||
12801 | 12642 | ||
12802 | DRM_DEBUG_KMS("[CRTC:%d]\n", | 12643 | __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state); |
12803 | crtc->base.base.id); | 12644 | pipe_config = to_intel_crtc_state(old_crtc_state); |
12645 | memset(pipe_config, 0, sizeof(*pipe_config)); | ||
12646 | pipe_config->base.crtc = crtc; | ||
12647 | pipe_config->base.state = old_state; | ||
12804 | 12648 | ||
12805 | I915_STATE_WARN(crtc->active && !crtc->base.state->enable, | 12649 | DRM_DEBUG_KMS("[CRTC:%d]\n", |
12806 | "active crtc, but not enabled in sw tracking\n"); | 12650 | crtc->base.id); |
12807 | 12651 | ||
12808 | for_each_intel_encoder(dev, encoder) { | 12652 | active = dev_priv->display.get_pipe_config(intel_crtc, |
12809 | if (encoder->base.crtc != &crtc->base) | 12653 | pipe_config); |
12810 | continue; | ||
12811 | enabled = true; | ||
12812 | if (encoder->connectors_active) | ||
12813 | active = true; | ||
12814 | } | ||
12815 | 12654 | ||
12816 | I915_STATE_WARN(active != crtc->active, | 12655 | /* hw state is inconsistent with the pipe quirk */ |
12817 | "crtc's computed active state doesn't match tracked active state " | 12656 | if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || |
12818 | "(expected %i, found %i)\n", active, crtc->active); | 12657 | (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) |
12819 | I915_STATE_WARN(enabled != crtc->base.state->enable, | 12658 | active = crtc->state->active; |
12820 | "crtc's computed enabled state doesn't match tracked enabled state " | ||
12821 | "(expected %i, found %i)\n", enabled, | ||
12822 | crtc->base.state->enable); | ||
12823 | 12659 | ||
12824 | active = dev_priv->display.get_pipe_config(crtc, | 12660 | I915_STATE_WARN(crtc->state->active != active, |
12825 | &pipe_config); | 12661 | "crtc active state doesn't match with hw state " |
12662 | "(expected %i, found %i)\n", crtc->state->active, active); | ||
12826 | 12663 | ||
12827 | /* hw state is inconsistent with the pipe quirk */ | 12664 | I915_STATE_WARN(intel_crtc->active != crtc->state->active, |
12828 | if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || | 12665 | "transitional active state does not match atomic hw state " |
12829 | (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) | 12666 | "(expected %i, found %i)\n", crtc->state->active, intel_crtc->active); |
12830 | active = crtc->active; | ||
12831 | 12667 | ||
12832 | for_each_intel_encoder(dev, encoder) { | 12668 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
12833 | enum pipe pipe; | 12669 | enum pipe pipe; |
12834 | if (encoder->base.crtc != &crtc->base) | ||
12835 | continue; | ||
12836 | if (encoder->get_hw_state(encoder, &pipe)) | ||
12837 | encoder->get_config(encoder, &pipe_config); | ||
12838 | } | ||
12839 | 12670 | ||
12840 | I915_STATE_WARN(crtc->active != active, | 12671 | active = encoder->get_hw_state(encoder, &pipe); |
12841 | "crtc active state doesn't match with hw state " | 12672 | I915_STATE_WARN(active != crtc->state->active, |
12842 | "(expected %i, found %i)\n", crtc->active, active); | 12673 | "[ENCODER:%i] active %i with crtc active %i\n", |
12674 | encoder->base.base.id, active, crtc->state->active); | ||
12843 | 12675 | ||
12844 | I915_STATE_WARN(crtc->active != crtc->base.state->active, | 12676 | I915_STATE_WARN(active && intel_crtc->pipe != pipe, |
12845 | "transitional active state does not match atomic hw state " | 12677 | "Encoder connected to wrong pipe %c\n", |
12846 | "(expected %i, found %i)\n", crtc->base.state->active, crtc->active); | 12678 | pipe_name(pipe)); |
12847 | 12679 | ||
12848 | if (!active) | 12680 | if (active) |
12681 | encoder->get_config(encoder, pipe_config); | ||
12682 | } | ||
12683 | |||
12684 | if (!crtc->state->active) | ||
12849 | continue; | 12685 | continue; |
12850 | 12686 | ||
12851 | if (!intel_pipe_config_compare(dev, crtc->config, | 12687 | sw_config = to_intel_crtc_state(crtc->state); |
12852 | &pipe_config, false)) { | 12688 | if (!intel_pipe_config_compare(dev, sw_config, |
12689 | pipe_config, false)) { | ||
12853 | I915_STATE_WARN(1, "pipe state doesn't match!\n"); | 12690 | I915_STATE_WARN(1, "pipe state doesn't match!\n"); |
12854 | intel_dump_pipe_config(crtc, &pipe_config, | 12691 | intel_dump_pipe_config(intel_crtc, pipe_config, |
12855 | "[hw state]"); | 12692 | "[hw state]"); |
12856 | intel_dump_pipe_config(crtc, crtc->config, | 12693 | intel_dump_pipe_config(intel_crtc, sw_config, |
12857 | "[sw state]"); | 12694 | "[sw state]"); |
12858 | } | 12695 | } |
12859 | } | 12696 | } |
@@ -12908,13 +12745,14 @@ check_shared_dpll_state(struct drm_device *dev) | |||
12908 | } | 12745 | } |
12909 | } | 12746 | } |
12910 | 12747 | ||
12911 | void | 12748 | static void |
12912 | intel_modeset_check_state(struct drm_device *dev) | 12749 | intel_modeset_check_state(struct drm_device *dev, |
12750 | struct drm_atomic_state *old_state) | ||
12913 | { | 12751 | { |
12914 | check_wm_state(dev); | 12752 | check_wm_state(dev); |
12915 | check_connector_state(dev); | 12753 | check_connector_state(dev, old_state); |
12916 | check_encoder_state(dev); | 12754 | check_encoder_state(dev); |
12917 | check_crtc_state(dev); | 12755 | check_crtc_state(dev, old_state); |
12918 | check_shared_dpll_state(dev); | 12756 | check_shared_dpll_state(dev); |
12919 | } | 12757 | } |
12920 | 12758 | ||
@@ -13270,12 +13108,14 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
13270 | 13108 | ||
13271 | /* Only after disabling all output pipelines that will be changed can we | 13109 | /* Only after disabling all output pipelines that will be changed can we |
13272 | * update the the output configuration. */ | 13110 | * update the the output configuration. */ |
13273 | intel_modeset_update_state(state); | 13111 | intel_modeset_update_crtc_state(state); |
13274 | 13112 | ||
13275 | /* The state has been swaped above, so state actually contains the | 13113 | if (any_ms) { |
13276 | * old state now. */ | 13114 | intel_shared_dpll_commit(state); |
13277 | if (any_ms) | 13115 | |
13116 | drm_atomic_helper_update_legacy_modeset_state(state->dev, state); | ||
13278 | modeset_update_crtc_power_domains(state); | 13117 | modeset_update_crtc_power_domains(state); |
13118 | } | ||
13279 | 13119 | ||
13280 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ | 13120 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ |
13281 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 13121 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
@@ -13298,10 +13138,11 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
13298 | 13138 | ||
13299 | drm_atomic_helper_wait_for_vblanks(dev, state); | 13139 | drm_atomic_helper_wait_for_vblanks(dev, state); |
13300 | drm_atomic_helper_cleanup_planes(dev, state); | 13140 | drm_atomic_helper_cleanup_planes(dev, state); |
13301 | drm_atomic_state_free(state); | ||
13302 | 13141 | ||
13303 | if (any_ms) | 13142 | if (any_ms) |
13304 | intel_modeset_check_state(dev); | 13143 | intel_modeset_check_state(dev, state); |
13144 | |||
13145 | drm_atomic_state_free(state); | ||
13305 | 13146 | ||
13306 | return 0; | 13147 | return 0; |
13307 | } | 13148 | } |
@@ -14106,8 +13947,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
14106 | */ | 13947 | */ |
14107 | found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED; | 13948 | found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED; |
14108 | /* WaIgnoreDDIAStrap: skl */ | 13949 | /* WaIgnoreDDIAStrap: skl */ |
14109 | if (found || | 13950 | if (found || IS_SKYLAKE(dev)) |
14110 | (IS_SKYLAKE(dev) && INTEL_REVID(dev) < SKL_REVID_D0)) | ||
14111 | intel_ddi_init(dev, PORT_A); | 13951 | intel_ddi_init(dev, PORT_A); |
14112 | 13952 | ||
14113 | /* DDI B, C and D detection is indicated by the SFUSE_STRAP | 13953 | /* DDI B, C and D detection is indicated by the SFUSE_STRAP |
@@ -14271,7 +14111,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, | |||
14271 | struct drm_i915_gem_object *obj = intel_fb->obj; | 14111 | struct drm_i915_gem_object *obj = intel_fb->obj; |
14272 | 14112 | ||
14273 | mutex_lock(&dev->struct_mutex); | 14113 | mutex_lock(&dev->struct_mutex); |
14274 | intel_fb_obj_flush(obj, false, ORIGIN_GTT); | 14114 | intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB); |
14275 | mutex_unlock(&dev->struct_mutex); | 14115 | mutex_unlock(&dev->struct_mutex); |
14276 | 14116 | ||
14277 | return 0; | 14117 | return 0; |
@@ -15065,8 +14905,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
15065 | /* Adjust the state of the output pipe according to whether we | 14905 | /* Adjust the state of the output pipe according to whether we |
15066 | * have active connectors/encoders. */ | 14906 | * have active connectors/encoders. */ |
15067 | enable = false; | 14907 | enable = false; |
15068 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) | 14908 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { |
15069 | enable |= encoder->connectors_active; | 14909 | enable = true; |
14910 | break; | ||
14911 | } | ||
15070 | 14912 | ||
15071 | if (!enable) | 14913 | if (!enable) |
15072 | intel_crtc_disable_noatomic(&crtc->base); | 14914 | intel_crtc_disable_noatomic(&crtc->base); |
@@ -15093,10 +14935,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
15093 | * actually up, hence no need to break them. */ | 14935 | * actually up, hence no need to break them. */ |
15094 | WARN_ON(crtc->active); | 14936 | WARN_ON(crtc->active); |
15095 | 14937 | ||
15096 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { | 14938 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) |
15097 | WARN_ON(encoder->connectors_active); | ||
15098 | encoder->base.crtc = NULL; | 14939 | encoder->base.crtc = NULL; |
15099 | } | ||
15100 | } | 14940 | } |
15101 | 14941 | ||
15102 | if (crtc->active || HAS_GMCH_DISPLAY(dev)) { | 14942 | if (crtc->active || HAS_GMCH_DISPLAY(dev)) { |
@@ -15122,6 +14962,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
15122 | { | 14962 | { |
15123 | struct intel_connector *connector; | 14963 | struct intel_connector *connector; |
15124 | struct drm_device *dev = encoder->base.dev; | 14964 | struct drm_device *dev = encoder->base.dev; |
14965 | bool active = false; | ||
15125 | 14966 | ||
15126 | /* We need to check both for a crtc link (meaning that the | 14967 | /* We need to check both for a crtc link (meaning that the |
15127 | * encoder is active and trying to read from a pipe) and the | 14968 | * encoder is active and trying to read from a pipe) and the |
@@ -15129,7 +14970,15 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
15129 | bool has_active_crtc = encoder->base.crtc && | 14970 | bool has_active_crtc = encoder->base.crtc && |
15130 | to_intel_crtc(encoder->base.crtc)->active; | 14971 | to_intel_crtc(encoder->base.crtc)->active; |
15131 | 14972 | ||
15132 | if (encoder->connectors_active && !has_active_crtc) { | 14973 | for_each_intel_connector(dev, connector) { |
14974 | if (connector->base.encoder != &encoder->base) | ||
14975 | continue; | ||
14976 | |||
14977 | active = true; | ||
14978 | break; | ||
14979 | } | ||
14980 | |||
14981 | if (active && !has_active_crtc) { | ||
15133 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", | 14982 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", |
15134 | encoder->base.base.id, | 14983 | encoder->base.base.id, |
15135 | encoder->base.name); | 14984 | encoder->base.name); |
@@ -15146,7 +14995,6 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
15146 | encoder->post_disable(encoder); | 14995 | encoder->post_disable(encoder); |
15147 | } | 14996 | } |
15148 | encoder->base.crtc = NULL; | 14997 | encoder->base.crtc = NULL; |
15149 | encoder->connectors_active = false; | ||
15150 | 14998 | ||
15151 | /* Inconsistent output/port/pipe state happens presumably due to | 14999 | /* Inconsistent output/port/pipe state happens presumably due to |
15152 | * a bug in one of the get_hw_state functions. Or someplace else | 15000 | * a bug in one of the get_hw_state functions. Or someplace else |
@@ -15308,7 +15156,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
15308 | encoder->base.crtc = NULL; | 15156 | encoder->base.crtc = NULL; |
15309 | } | 15157 | } |
15310 | 15158 | ||
15311 | encoder->connectors_active = false; | ||
15312 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", | 15159 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", |
15313 | encoder->base.base.id, | 15160 | encoder->base.base.id, |
15314 | encoder->base.name, | 15161 | encoder->base.name, |
@@ -15319,7 +15166,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
15319 | for_each_intel_connector(dev, connector) { | 15166 | for_each_intel_connector(dev, connector) { |
15320 | if (connector->get_hw_state(connector)) { | 15167 | if (connector->get_hw_state(connector)) { |
15321 | connector->base.dpms = DRM_MODE_DPMS_ON; | 15168 | connector->base.dpms = DRM_MODE_DPMS_ON; |
15322 | connector->encoder->connectors_active = true; | ||
15323 | connector->base.encoder = &connector->encoder->base; | 15169 | connector->base.encoder = &connector->encoder->base; |
15324 | } else { | 15170 | } else { |
15325 | connector->base.dpms = DRM_MODE_DPMS_OFF; | 15171 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f1b9f939b435..016e7bc6af0a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -849,8 +849,15 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
849 | } | 849 | } |
850 | 850 | ||
851 | if (try == 3) { | 851 | if (try == 3) { |
852 | WARN(1, "dp_aux_ch not started status 0x%08x\n", | 852 | static u32 last_status = -1; |
853 | I915_READ(ch_ctl)); | 853 | const u32 status = I915_READ(ch_ctl); |
854 | |||
855 | if (status != last_status) { | ||
856 | WARN(1, "dp_aux_ch not started status 0x%08x\n", | ||
857 | status); | ||
858 | last_status = status; | ||
859 | } | ||
860 | |||
854 | ret = -EBUSY; | 861 | ret = -EBUSY; |
855 | goto out; | 862 | goto out; |
856 | } | 863 | } |
@@ -1026,11 +1033,34 @@ static void | |||
1026 | intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) | 1033 | intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) |
1027 | { | 1034 | { |
1028 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1035 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1036 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1029 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 1037 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
1030 | enum port port = intel_dig_port->port; | 1038 | enum port port = intel_dig_port->port; |
1039 | struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port]; | ||
1031 | const char *name = NULL; | 1040 | const char *name = NULL; |
1041 | uint32_t porte_aux_ctl_reg = DPA_AUX_CH_CTL; | ||
1032 | int ret; | 1042 | int ret; |
1033 | 1043 | ||
1044 | /* On SKL we don't have Aux for port E so we rely on VBT to set | ||
1045 | * a proper alternate aux channel. | ||
1046 | */ | ||
1047 | if (IS_SKYLAKE(dev) && port == PORT_E) { | ||
1048 | switch (info->alternate_aux_channel) { | ||
1049 | case DP_AUX_B: | ||
1050 | porte_aux_ctl_reg = DPB_AUX_CH_CTL; | ||
1051 | break; | ||
1052 | case DP_AUX_C: | ||
1053 | porte_aux_ctl_reg = DPC_AUX_CH_CTL; | ||
1054 | break; | ||
1055 | case DP_AUX_D: | ||
1056 | porte_aux_ctl_reg = DPD_AUX_CH_CTL; | ||
1057 | break; | ||
1058 | case DP_AUX_A: | ||
1059 | default: | ||
1060 | porte_aux_ctl_reg = DPA_AUX_CH_CTL; | ||
1061 | } | ||
1062 | } | ||
1063 | |||
1034 | switch (port) { | 1064 | switch (port) { |
1035 | case PORT_A: | 1065 | case PORT_A: |
1036 | intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL; | 1066 | intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL; |
@@ -1048,6 +1078,10 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) | |||
1048 | intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL; | 1078 | intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL; |
1049 | name = "DPDDC-D"; | 1079 | name = "DPDDC-D"; |
1050 | break; | 1080 | break; |
1081 | case PORT_E: | ||
1082 | intel_dp->aux_ch_ctl_reg = porte_aux_ctl_reg; | ||
1083 | name = "DPDDC-E"; | ||
1084 | break; | ||
1051 | default: | 1085 | default: |
1052 | BUG(); | 1086 | BUG(); |
1053 | } | 1087 | } |
@@ -1061,7 +1095,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) | |||
1061 | * | 1095 | * |
1062 | * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU. | 1096 | * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU. |
1063 | */ | 1097 | */ |
1064 | if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) | 1098 | if (!IS_HASWELL(dev) && !IS_BROADWELL(dev) && port != PORT_E) |
1065 | intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10; | 1099 | intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10; |
1066 | 1100 | ||
1067 | intel_dp->aux.name = name; | 1101 | intel_dp->aux.name = name; |
@@ -1409,7 +1443,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
1409 | * bpc in between. */ | 1443 | * bpc in between. */ |
1410 | bpp = pipe_config->pipe_bpp; | 1444 | bpp = pipe_config->pipe_bpp; |
1411 | if (is_edp(intel_dp)) { | 1445 | if (is_edp(intel_dp)) { |
1412 | if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) { | 1446 | |
1447 | /* Get bpp from vbt only for panels that dont have bpp in edid */ | ||
1448 | if (intel_connector->base.display_info.bpc == 0 && | ||
1449 | (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp)) { | ||
1413 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", | 1450 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", |
1414 | dev_priv->vbt.edp_bpp); | 1451 | dev_priv->vbt.edp_bpp); |
1415 | bpp = dev_priv->vbt.edp_bpp; | 1452 | bpp = dev_priv->vbt.edp_bpp; |
@@ -2624,7 +2661,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, | |||
2624 | DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n", | 2661 | DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n", |
2625 | pipe_name(pipe), port_name(port)); | 2662 | pipe_name(pipe), port_name(port)); |
2626 | 2663 | ||
2627 | WARN(encoder->connectors_active, | 2664 | WARN(encoder->base.crtc, |
2628 | "stealing pipe %c power sequencer from active eDP port %c\n", | 2665 | "stealing pipe %c power sequencer from active eDP port %c\n", |
2629 | pipe_name(pipe), port_name(port)); | 2666 | pipe_name(pipe), port_name(port)); |
2630 | 2667 | ||
@@ -3958,43 +3995,67 @@ intel_dp_probe_mst(struct intel_dp *intel_dp) | |||
3958 | return intel_dp->is_mst; | 3995 | return intel_dp->is_mst; |
3959 | } | 3996 | } |
3960 | 3997 | ||
3961 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | 3998 | static void intel_dp_sink_crc_stop(struct intel_dp *intel_dp) |
3962 | { | 3999 | { |
3963 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 4000 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
3964 | struct drm_device *dev = intel_dig_port->base.base.dev; | 4001 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); |
3965 | struct intel_crtc *intel_crtc = | ||
3966 | to_intel_crtc(intel_dig_port->base.base.crtc); | ||
3967 | u8 buf; | 4002 | u8 buf; |
3968 | int test_crc_count; | ||
3969 | int attempts = 6; | ||
3970 | int ret = 0; | ||
3971 | 4003 | ||
3972 | hsw_disable_ips(intel_crtc); | 4004 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) { |
3973 | 4005 | DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n"); | |
3974 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { | 4006 | return; |
3975 | ret = -EIO; | ||
3976 | goto out; | ||
3977 | } | 4007 | } |
3978 | 4008 | ||
3979 | if (!(buf & DP_TEST_CRC_SUPPORTED)) { | 4009 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, |
3980 | ret = -ENOTTY; | 4010 | buf & ~DP_TEST_SINK_START) < 0) |
3981 | goto out; | 4011 | DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n"); |
3982 | } | ||
3983 | 4012 | ||
3984 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) { | 4013 | hsw_enable_ips(intel_crtc); |
3985 | ret = -EIO; | 4014 | } |
3986 | goto out; | 4015 | |
3987 | } | 4016 | static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) |
4017 | { | ||
4018 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | ||
4019 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | ||
4020 | u8 buf; | ||
4021 | |||
4022 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) | ||
4023 | return -EIO; | ||
4024 | |||
4025 | if (!(buf & DP_TEST_CRC_SUPPORTED)) | ||
4026 | return -ENOTTY; | ||
4027 | |||
4028 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) | ||
4029 | return -EIO; | ||
4030 | |||
4031 | hsw_disable_ips(intel_crtc); | ||
3988 | 4032 | ||
3989 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, | 4033 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, |
3990 | buf | DP_TEST_SINK_START) < 0) { | 4034 | buf | DP_TEST_SINK_START) < 0) { |
3991 | ret = -EIO; | 4035 | hsw_enable_ips(intel_crtc); |
3992 | goto out; | 4036 | return -EIO; |
3993 | } | 4037 | } |
3994 | 4038 | ||
4039 | return 0; | ||
4040 | } | ||
4041 | |||
4042 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | ||
4043 | { | ||
4044 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | ||
4045 | struct drm_device *dev = dig_port->base.base.dev; | ||
4046 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | ||
4047 | u8 buf; | ||
4048 | int test_crc_count; | ||
4049 | int attempts = 6; | ||
4050 | int ret; | ||
4051 | |||
4052 | ret = intel_dp_sink_crc_start(intel_dp); | ||
4053 | if (ret) | ||
4054 | return ret; | ||
4055 | |||
3995 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { | 4056 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { |
3996 | ret = -EIO; | 4057 | ret = -EIO; |
3997 | goto out; | 4058 | goto stop; |
3998 | } | 4059 | } |
3999 | 4060 | ||
4000 | test_crc_count = buf & DP_TEST_COUNT_MASK; | 4061 | test_crc_count = buf & DP_TEST_COUNT_MASK; |
@@ -4003,7 +4064,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | |||
4003 | if (drm_dp_dpcd_readb(&intel_dp->aux, | 4064 | if (drm_dp_dpcd_readb(&intel_dp->aux, |
4004 | DP_TEST_SINK_MISC, &buf) < 0) { | 4065 | DP_TEST_SINK_MISC, &buf) < 0) { |
4005 | ret = -EIO; | 4066 | ret = -EIO; |
4006 | goto out; | 4067 | goto stop; |
4007 | } | 4068 | } |
4008 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 4069 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
4009 | } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); | 4070 | } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); |
@@ -4011,25 +4072,13 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | |||
4011 | if (attempts == 0) { | 4072 | if (attempts == 0) { |
4012 | DRM_DEBUG_KMS("Panel is unable to calculate CRC after 6 vblanks\n"); | 4073 | DRM_DEBUG_KMS("Panel is unable to calculate CRC after 6 vblanks\n"); |
4013 | ret = -ETIMEDOUT; | 4074 | ret = -ETIMEDOUT; |
4014 | goto out; | 4075 | goto stop; |
4015 | } | ||
4016 | |||
4017 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) { | ||
4018 | ret = -EIO; | ||
4019 | goto out; | ||
4020 | } | 4076 | } |
4021 | 4077 | ||
4022 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) { | 4078 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) |
4023 | ret = -EIO; | ||
4024 | goto out; | ||
4025 | } | ||
4026 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, | ||
4027 | buf & ~DP_TEST_SINK_START) < 0) { | ||
4028 | ret = -EIO; | 4079 | ret = -EIO; |
4029 | goto out; | 4080 | stop: |
4030 | } | 4081 | intel_dp_sink_crc_stop(intel_dp); |
4031 | out: | ||
4032 | hsw_enable_ips(intel_crtc); | ||
4033 | return ret; | 4082 | return ret; |
4034 | } | 4083 | } |
4035 | 4084 | ||
@@ -4090,9 +4139,16 @@ static uint8_t intel_dp_autotest_edid(struct intel_dp *intel_dp) | |||
4090 | intel_dp->aux.i2c_defer_count); | 4139 | intel_dp->aux.i2c_defer_count); |
4091 | intel_dp->compliance_test_data = INTEL_DP_RESOLUTION_FAILSAFE; | 4140 | intel_dp->compliance_test_data = INTEL_DP_RESOLUTION_FAILSAFE; |
4092 | } else { | 4141 | } else { |
4142 | struct edid *block = intel_connector->detect_edid; | ||
4143 | |||
4144 | /* We have to write the checksum | ||
4145 | * of the last block read | ||
4146 | */ | ||
4147 | block += intel_connector->detect_edid->extensions; | ||
4148 | |||
4093 | if (!drm_dp_dpcd_write(&intel_dp->aux, | 4149 | if (!drm_dp_dpcd_write(&intel_dp->aux, |
4094 | DP_TEST_EDID_CHECKSUM, | 4150 | DP_TEST_EDID_CHECKSUM, |
4095 | &intel_connector->detect_edid->checksum, | 4151 | &block->checksum, |
4096 | 1)) | 4152 | 1)) |
4097 | DRM_DEBUG_KMS("Failed to write EDID checksum\n"); | 4153 | DRM_DEBUG_KMS("Failed to write EDID checksum\n"); |
4098 | 4154 | ||
@@ -4240,10 +4296,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
4240 | 4296 | ||
4241 | WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); | 4297 | WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); |
4242 | 4298 | ||
4243 | if (!intel_encoder->connectors_active) | 4299 | if (!intel_encoder->base.crtc) |
4244 | return; | ||
4245 | |||
4246 | if (WARN_ON(!intel_encoder->base.crtc)) | ||
4247 | return; | 4300 | return; |
4248 | 4301 | ||
4249 | if (!to_intel_crtc(intel_encoder->base.crtc)->active) | 4302 | if (!to_intel_crtc(intel_encoder->base.crtc)->active) |
@@ -4824,7 +4877,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder) | |||
4824 | } | 4877 | } |
4825 | 4878 | ||
4826 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 4879 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
4827 | .dpms = intel_connector_dpms, | 4880 | .dpms = drm_atomic_helper_connector_dpms, |
4828 | .detect = intel_dp_detect, | 4881 | .detect = intel_dp_detect, |
4829 | .force = intel_dp_force, | 4882 | .force = intel_dp_force, |
4830 | .fill_modes = drm_helper_probe_single_connector_modes, | 4883 | .fill_modes = drm_helper_probe_single_connector_modes, |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index a61df29918ed..369f8b6b804f 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -328,7 +328,7 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { | 330 | static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { |
331 | .dpms = intel_connector_dpms, | 331 | .dpms = drm_atomic_helper_connector_dpms, |
332 | .detect = intel_dp_mst_detect, | 332 | .detect = intel_dp_mst_detect, |
333 | .fill_modes = drm_helper_probe_single_connector_modes, | 333 | .fill_modes = drm_helper_probe_single_connector_modes, |
334 | .set_property = intel_dp_mst_set_property, | 334 | .set_property = intel_dp_mst_set_property, |
@@ -464,9 +464,20 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
464 | { | 464 | { |
465 | struct intel_connector *intel_connector = to_intel_connector(connector); | 465 | struct intel_connector *intel_connector = to_intel_connector(connector); |
466 | struct drm_device *dev = connector->dev; | 466 | struct drm_device *dev = connector->dev; |
467 | |||
467 | /* need to nuke the connector */ | 468 | /* need to nuke the connector */ |
468 | drm_modeset_lock_all(dev); | 469 | drm_modeset_lock_all(dev); |
469 | intel_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 470 | if (connector->state->crtc) { |
471 | struct drm_mode_set set; | ||
472 | int ret; | ||
473 | |||
474 | memset(&set, 0, sizeof(set)); | ||
475 | set.crtc = connector->state->crtc, | ||
476 | |||
477 | ret = drm_atomic_helper_set_config(&set); | ||
478 | |||
479 | WARN(ret, "Disabling mst crtc failed with %i\n", ret); | ||
480 | } | ||
470 | drm_modeset_unlock_all(dev); | 481 | drm_modeset_unlock_all(dev); |
471 | 482 | ||
472 | intel_connector->unregister(intel_connector); | 483 | intel_connector->unregister(intel_connector); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2e743d6abffd..93008fbb815d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -133,7 +133,6 @@ struct intel_encoder { | |||
133 | 133 | ||
134 | enum intel_output_type type; | 134 | enum intel_output_type type; |
135 | unsigned int cloneable; | 135 | unsigned int cloneable; |
136 | bool connectors_active; | ||
137 | void (*hot_plug)(struct intel_encoder *); | 136 | void (*hot_plug)(struct intel_encoder *); |
138 | bool (*compute_config)(struct intel_encoder *, | 137 | bool (*compute_config)(struct intel_encoder *, |
139 | struct intel_crtc_state *); | 138 | struct intel_crtc_state *); |
@@ -992,14 +991,10 @@ void intel_mark_busy(struct drm_device *dev); | |||
992 | void intel_mark_idle(struct drm_device *dev); | 991 | void intel_mark_idle(struct drm_device *dev); |
993 | void intel_crtc_restore_mode(struct drm_crtc *crtc); | 992 | void intel_crtc_restore_mode(struct drm_crtc *crtc); |
994 | int intel_display_suspend(struct drm_device *dev); | 993 | int intel_display_suspend(struct drm_device *dev); |
995 | int intel_crtc_control(struct drm_crtc *crtc, bool enable); | ||
996 | void intel_crtc_update_dpms(struct drm_crtc *crtc); | ||
997 | void intel_encoder_destroy(struct drm_encoder *encoder); | 994 | void intel_encoder_destroy(struct drm_encoder *encoder); |
998 | int intel_connector_init(struct intel_connector *); | 995 | int intel_connector_init(struct intel_connector *); |
999 | struct intel_connector *intel_connector_alloc(void); | 996 | struct intel_connector *intel_connector_alloc(void); |
1000 | int intel_connector_dpms(struct drm_connector *, int mode); | ||
1001 | bool intel_connector_get_hw_state(struct intel_connector *connector); | 997 | bool intel_connector_get_hw_state(struct intel_connector *connector); |
1002 | void intel_modeset_check_state(struct drm_device *dev); | ||
1003 | bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, | 998 | bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, |
1004 | struct intel_digital_port *port); | 999 | struct intel_digital_port *port); |
1005 | void intel_connector_attach_encoder(struct intel_connector *connector, | 1000 | void intel_connector_attach_encoder(struct intel_connector *connector, |
@@ -1243,7 +1238,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, | |||
1243 | unsigned int frontbuffer_bits, | 1238 | unsigned int frontbuffer_bits, |
1244 | enum fb_op_origin origin); | 1239 | enum fb_op_origin origin); |
1245 | void intel_fbc_flush(struct drm_i915_private *dev_priv, | 1240 | void intel_fbc_flush(struct drm_i915_private *dev_priv, |
1246 | unsigned int frontbuffer_bits); | 1241 | unsigned int frontbuffer_bits, enum fb_op_origin origin); |
1247 | const char *intel_no_fbc_reason_str(enum no_fbc_reason reason); | 1242 | const char *intel_no_fbc_reason_str(enum no_fbc_reason reason); |
1248 | void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); | 1243 | void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); |
1249 | 1244 | ||
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 18dd7d7360a0..4a601cf90f16 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -982,7 +982,7 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs | |||
982 | }; | 982 | }; |
983 | 983 | ||
984 | static const struct drm_connector_funcs intel_dsi_connector_funcs = { | 984 | static const struct drm_connector_funcs intel_dsi_connector_funcs = { |
985 | .dpms = intel_connector_dpms, | 985 | .dpms = drm_atomic_helper_connector_dpms, |
986 | .detect = intel_dsi_detect, | 986 | .detect = intel_dsi_detect, |
987 | .destroy = intel_dsi_connector_destroy, | 987 | .destroy = intel_dsi_connector_destroy, |
988 | .fill_modes = drm_helper_probe_single_connector_modes, | 988 | .fill_modes = drm_helper_probe_single_connector_modes, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index fd5e522abebb..dc532bb61d22 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -196,52 +196,6 @@ static void intel_enable_dvo(struct intel_encoder *encoder) | |||
196 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); | 196 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); |
197 | } | 197 | } |
198 | 198 | ||
199 | /* Special dpms function to support cloning between dvo/sdvo/crt. */ | ||
200 | static int intel_dvo_dpms(struct drm_connector *connector, int mode) | ||
201 | { | ||
202 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); | ||
203 | struct drm_crtc *crtc; | ||
204 | struct intel_crtc_state *config; | ||
205 | |||
206 | /* dvo supports only 2 dpms states. */ | ||
207 | if (mode != DRM_MODE_DPMS_ON) | ||
208 | mode = DRM_MODE_DPMS_OFF; | ||
209 | |||
210 | if (mode == connector->dpms) | ||
211 | return 0; | ||
212 | |||
213 | connector->dpms = mode; | ||
214 | |||
215 | /* Only need to change hw state when actually enabled */ | ||
216 | crtc = intel_dvo->base.base.crtc; | ||
217 | if (!crtc) { | ||
218 | intel_dvo->base.connectors_active = false; | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* We call connector dpms manually below in case pipe dpms doesn't | ||
223 | * change due to cloning. */ | ||
224 | if (mode == DRM_MODE_DPMS_ON) { | ||
225 | config = to_intel_crtc(crtc)->config; | ||
226 | |||
227 | intel_dvo->base.connectors_active = true; | ||
228 | |||
229 | intel_crtc_update_dpms(crtc); | ||
230 | |||
231 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); | ||
232 | } else { | ||
233 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); | ||
234 | |||
235 | intel_dvo->base.connectors_active = false; | ||
236 | |||
237 | intel_crtc_update_dpms(crtc); | ||
238 | } | ||
239 | |||
240 | intel_modeset_check_state(connector->dev); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static enum drm_mode_status | 199 | static enum drm_mode_status |
246 | intel_dvo_mode_valid(struct drm_connector *connector, | 200 | intel_dvo_mode_valid(struct drm_connector *connector, |
247 | struct drm_display_mode *mode) | 201 | struct drm_display_mode *mode) |
@@ -389,7 +343,7 @@ static void intel_dvo_destroy(struct drm_connector *connector) | |||
389 | } | 343 | } |
390 | 344 | ||
391 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 345 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
392 | .dpms = intel_dvo_dpms, | 346 | .dpms = drm_atomic_helper_connector_dpms, |
393 | .detect = intel_dvo_detect, | 347 | .detect = intel_dvo_detect, |
394 | .destroy = intel_dvo_destroy, | 348 | .destroy = intel_dvo_destroy, |
395 | .fill_modes = drm_helper_probe_single_connector_modes, | 349 | .fill_modes = drm_helper_probe_single_connector_modes, |
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index c271af767981..1f97fb548c2a 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c | |||
@@ -884,22 +884,23 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, | |||
884 | } | 884 | } |
885 | 885 | ||
886 | void intel_fbc_flush(struct drm_i915_private *dev_priv, | 886 | void intel_fbc_flush(struct drm_i915_private *dev_priv, |
887 | unsigned int frontbuffer_bits) | 887 | unsigned int frontbuffer_bits, enum fb_op_origin origin) |
888 | { | 888 | { |
889 | if (!dev_priv->fbc.enable_fbc) | 889 | if (!dev_priv->fbc.enable_fbc) |
890 | return; | 890 | return; |
891 | 891 | ||
892 | mutex_lock(&dev_priv->fbc.lock); | 892 | if (origin == ORIGIN_GTT) |
893 | return; | ||
893 | 894 | ||
894 | if (!dev_priv->fbc.busy_bits) | 895 | mutex_lock(&dev_priv->fbc.lock); |
895 | goto out; | ||
896 | 896 | ||
897 | dev_priv->fbc.busy_bits &= ~frontbuffer_bits; | 897 | dev_priv->fbc.busy_bits &= ~frontbuffer_bits; |
898 | 898 | ||
899 | if (!dev_priv->fbc.busy_bits) | 899 | if (!dev_priv->fbc.busy_bits) { |
900 | __intel_fbc_disable(dev_priv); | ||
900 | __intel_fbc_update(dev_priv); | 901 | __intel_fbc_update(dev_priv); |
902 | } | ||
901 | 903 | ||
902 | out: | ||
903 | mutex_unlock(&dev_priv->fbc.lock); | 904 | mutex_unlock(&dev_priv->fbc.lock); |
904 | } | 905 | } |
905 | 906 | ||
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index 777b1d3ccd41..ac85357010b4 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c | |||
@@ -129,7 +129,7 @@ static void intel_frontbuffer_flush(struct drm_device *dev, | |||
129 | 129 | ||
130 | intel_edp_drrs_flush(dev, frontbuffer_bits); | 130 | intel_edp_drrs_flush(dev, frontbuffer_bits); |
131 | intel_psr_flush(dev, frontbuffer_bits, origin); | 131 | intel_psr_flush(dev, frontbuffer_bits, origin); |
132 | intel_fbc_flush(dev_priv, frontbuffer_bits); | 132 | intel_fbc_flush(dev_priv, frontbuffer_bits, origin); |
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h new file mode 100644 index 000000000000..18d7f20936c8 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * Copyright © 2014 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | */ | ||
23 | #ifndef _INTEL_GUC_FWIF_H | ||
24 | #define _INTEL_GUC_FWIF_H | ||
25 | |||
26 | /* | ||
27 | * This file is partially autogenerated, although currently with some manual | ||
28 | * fixups afterwards. In future, it should be entirely autogenerated, in order | ||
29 | * to ensure that the definitions herein remain in sync with those used by the | ||
30 | * GuC's own firmware. | ||
31 | * | ||
32 | * EDITING THIS FILE IS THEREFORE NOT RECOMMENDED - YOUR CHANGES MAY BE LOST. | ||
33 | */ | ||
34 | |||
35 | #define GFXCORE_FAMILY_GEN8 11 | ||
36 | #define GFXCORE_FAMILY_GEN9 12 | ||
37 | #define GFXCORE_FAMILY_FORCE_ULONG 0x7fffffff | ||
38 | |||
39 | #define GUC_CTX_PRIORITY_CRITICAL 0 | ||
40 | #define GUC_CTX_PRIORITY_HIGH 1 | ||
41 | #define GUC_CTX_PRIORITY_NORMAL 2 | ||
42 | #define GUC_CTX_PRIORITY_LOW 3 | ||
43 | |||
44 | #define GUC_MAX_GPU_CONTEXTS 1024 | ||
45 | #define GUC_INVALID_CTX_ID (GUC_MAX_GPU_CONTEXTS + 1) | ||
46 | |||
47 | /* Work queue item header definitions */ | ||
48 | #define WQ_STATUS_ACTIVE 1 | ||
49 | #define WQ_STATUS_SUSPENDED 2 | ||
50 | #define WQ_STATUS_CMD_ERROR 3 | ||
51 | #define WQ_STATUS_ENGINE_ID_NOT_USED 4 | ||
52 | #define WQ_STATUS_SUSPENDED_FROM_RESET 5 | ||
53 | #define WQ_TYPE_SHIFT 0 | ||
54 | #define WQ_TYPE_BATCH_BUF (0x1 << WQ_TYPE_SHIFT) | ||
55 | #define WQ_TYPE_PSEUDO (0x2 << WQ_TYPE_SHIFT) | ||
56 | #define WQ_TYPE_INORDER (0x3 << WQ_TYPE_SHIFT) | ||
57 | #define WQ_TARGET_SHIFT 10 | ||
58 | #define WQ_LEN_SHIFT 16 | ||
59 | #define WQ_NO_WCFLUSH_WAIT (1 << 27) | ||
60 | #define WQ_PRESENT_WORKLOAD (1 << 28) | ||
61 | #define WQ_WORKLOAD_SHIFT 29 | ||
62 | #define WQ_WORKLOAD_GENERAL (0 << WQ_WORKLOAD_SHIFT) | ||
63 | #define WQ_WORKLOAD_GPGPU (1 << WQ_WORKLOAD_SHIFT) | ||
64 | #define WQ_WORKLOAD_TOUCH (2 << WQ_WORKLOAD_SHIFT) | ||
65 | |||
66 | #define WQ_RING_TAIL_SHIFT 20 | ||
67 | #define WQ_RING_TAIL_MASK (0x7FF << WQ_RING_TAIL_SHIFT) | ||
68 | |||
69 | #define GUC_DOORBELL_ENABLED 1 | ||
70 | #define GUC_DOORBELL_DISABLED 0 | ||
71 | |||
72 | #define GUC_CTX_DESC_ATTR_ACTIVE (1 << 0) | ||
73 | #define GUC_CTX_DESC_ATTR_PENDING_DB (1 << 1) | ||
74 | #define GUC_CTX_DESC_ATTR_KERNEL (1 << 2) | ||
75 | #define GUC_CTX_DESC_ATTR_PREEMPT (1 << 3) | ||
76 | #define GUC_CTX_DESC_ATTR_RESET (1 << 4) | ||
77 | #define GUC_CTX_DESC_ATTR_WQLOCKED (1 << 5) | ||
78 | #define GUC_CTX_DESC_ATTR_PCH (1 << 6) | ||
79 | |||
80 | /* The guc control data is 10 DWORDs */ | ||
81 | #define GUC_CTL_CTXINFO 0 | ||
82 | #define GUC_CTL_CTXNUM_IN16_SHIFT 0 | ||
83 | #define GUC_CTL_BASE_ADDR_SHIFT 12 | ||
84 | #define GUC_CTL_ARAT_HIGH 1 | ||
85 | #define GUC_CTL_ARAT_LOW 2 | ||
86 | #define GUC_CTL_DEVICE_INFO 3 | ||
87 | #define GUC_CTL_GTTYPE_SHIFT 0 | ||
88 | #define GUC_CTL_COREFAMILY_SHIFT 7 | ||
89 | #define GUC_CTL_LOG_PARAMS 4 | ||
90 | #define GUC_LOG_VALID (1 << 0) | ||
91 | #define GUC_LOG_NOTIFY_ON_HALF_FULL (1 << 1) | ||
92 | #define GUC_LOG_ALLOC_IN_MEGABYTE (1 << 3) | ||
93 | #define GUC_LOG_CRASH_PAGES 1 | ||
94 | #define GUC_LOG_CRASH_SHIFT 4 | ||
95 | #define GUC_LOG_DPC_PAGES 3 | ||
96 | #define GUC_LOG_DPC_SHIFT 6 | ||
97 | #define GUC_LOG_ISR_PAGES 3 | ||
98 | #define GUC_LOG_ISR_SHIFT 9 | ||
99 | #define GUC_LOG_BUF_ADDR_SHIFT 12 | ||
100 | #define GUC_CTL_PAGE_FAULT_CONTROL 5 | ||
101 | #define GUC_CTL_WA 6 | ||
102 | #define GUC_CTL_WA_UK_BY_DRIVER (1 << 3) | ||
103 | #define GUC_CTL_FEATURE 7 | ||
104 | #define GUC_CTL_VCS2_ENABLED (1 << 0) | ||
105 | #define GUC_CTL_KERNEL_SUBMISSIONS (1 << 1) | ||
106 | #define GUC_CTL_FEATURE2 (1 << 2) | ||
107 | #define GUC_CTL_POWER_GATING (1 << 3) | ||
108 | #define GUC_CTL_DISABLE_SCHEDULER (1 << 4) | ||
109 | #define GUC_CTL_PREEMPTION_LOG (1 << 5) | ||
110 | #define GUC_CTL_ENABLE_SLPC (1 << 7) | ||
111 | #define GUC_CTL_DEBUG 8 | ||
112 | #define GUC_LOG_VERBOSITY_SHIFT 0 | ||
113 | #define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT) | ||
114 | #define GUC_LOG_VERBOSITY_MED (1 << GUC_LOG_VERBOSITY_SHIFT) | ||
115 | #define GUC_LOG_VERBOSITY_HIGH (2 << GUC_LOG_VERBOSITY_SHIFT) | ||
116 | #define GUC_LOG_VERBOSITY_ULTRA (3 << GUC_LOG_VERBOSITY_SHIFT) | ||
117 | /* Verbosity range-check limits, without the shift */ | ||
118 | #define GUC_LOG_VERBOSITY_MIN 0 | ||
119 | #define GUC_LOG_VERBOSITY_MAX 3 | ||
120 | |||
121 | #define GUC_CTL_MAX_DWORDS (GUC_CTL_DEBUG + 1) | ||
122 | |||
123 | struct guc_doorbell_info { | ||
124 | u32 db_status; | ||
125 | u32 cookie; | ||
126 | u32 reserved[14]; | ||
127 | } __packed; | ||
128 | |||
129 | union guc_doorbell_qw { | ||
130 | struct { | ||
131 | u32 db_status; | ||
132 | u32 cookie; | ||
133 | }; | ||
134 | u64 value_qw; | ||
135 | } __packed; | ||
136 | |||
137 | #define GUC_MAX_DOORBELLS 256 | ||
138 | #define GUC_INVALID_DOORBELL_ID (GUC_MAX_DOORBELLS) | ||
139 | |||
140 | #define GUC_DB_SIZE (PAGE_SIZE) | ||
141 | #define GUC_WQ_SIZE (PAGE_SIZE * 2) | ||
142 | |||
143 | /* Work item for submitting workloads into work queue of GuC. */ | ||
144 | struct guc_wq_item { | ||
145 | u32 header; | ||
146 | u32 context_desc; | ||
147 | u32 ring_tail; | ||
148 | u32 fence_id; | ||
149 | } __packed; | ||
150 | |||
151 | struct guc_process_desc { | ||
152 | u32 context_id; | ||
153 | u64 db_base_addr; | ||
154 | u32 head; | ||
155 | u32 tail; | ||
156 | u32 error_offset; | ||
157 | u64 wq_base_addr; | ||
158 | u32 wq_size_bytes; | ||
159 | u32 wq_status; | ||
160 | u32 engine_presence; | ||
161 | u32 priority; | ||
162 | u32 reserved[30]; | ||
163 | } __packed; | ||
164 | |||
165 | /* engine id and context id is packed into guc_execlist_context.context_id*/ | ||
166 | #define GUC_ELC_CTXID_OFFSET 0 | ||
167 | #define GUC_ELC_ENGINE_OFFSET 29 | ||
168 | |||
169 | /* The execlist context including software and HW information */ | ||
170 | struct guc_execlist_context { | ||
171 | u32 context_desc; | ||
172 | u32 context_id; | ||
173 | u32 ring_status; | ||
174 | u32 ring_lcra; | ||
175 | u32 ring_begin; | ||
176 | u32 ring_end; | ||
177 | u32 ring_next_free_location; | ||
178 | u32 ring_current_tail_pointer_value; | ||
179 | u8 engine_state_submit_value; | ||
180 | u8 engine_state_wait_value; | ||
181 | u16 pagefault_count; | ||
182 | u16 engine_submit_queue_count; | ||
183 | } __packed; | ||
184 | |||
185 | /*Context descriptor for communicating between uKernel and Driver*/ | ||
186 | struct guc_context_desc { | ||
187 | u32 sched_common_area; | ||
188 | u32 context_id; | ||
189 | u32 pas_id; | ||
190 | u8 engines_used; | ||
191 | u64 db_trigger_cpu; | ||
192 | u32 db_trigger_uk; | ||
193 | u64 db_trigger_phy; | ||
194 | u16 db_id; | ||
195 | |||
196 | struct guc_execlist_context lrc[I915_NUM_RINGS]; | ||
197 | |||
198 | u8 attribute; | ||
199 | |||
200 | u32 priority; | ||
201 | |||
202 | u32 wq_sampled_tail_offset; | ||
203 | u32 wq_total_submit_enqueues; | ||
204 | |||
205 | u32 process_desc; | ||
206 | u32 wq_addr; | ||
207 | u32 wq_size; | ||
208 | |||
209 | u32 engine_presence; | ||
210 | |||
211 | u32 reserved0[1]; | ||
212 | u64 reserved1[1]; | ||
213 | |||
214 | u64 desc_private; | ||
215 | } __packed; | ||
216 | |||
217 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ | ||
218 | enum host2guc_action { | ||
219 | HOST2GUC_ACTION_DEFAULT = 0x0, | ||
220 | HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, | ||
221 | HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, | ||
222 | HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, | ||
223 | HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, | ||
224 | HOST2GUC_ACTION_LIMIT | ||
225 | }; | ||
226 | |||
227 | /* | ||
228 | * The GuC sends its response to a command by overwriting the | ||
229 | * command in SS0. The response is distinguishable from a command | ||
230 | * by the fact that all the MASK bits are set. The remaining bits | ||
231 | * give more detail. | ||
232 | */ | ||
233 | #define GUC2HOST_RESPONSE_MASK ((u32)0xF0000000) | ||
234 | #define GUC2HOST_IS_RESPONSE(x) ((u32)(x) >= GUC2HOST_RESPONSE_MASK) | ||
235 | #define GUC2HOST_STATUS(x) (GUC2HOST_RESPONSE_MASK | (x)) | ||
236 | |||
237 | /* GUC will return status back to SOFT_SCRATCH_O_REG */ | ||
238 | enum guc2host_status { | ||
239 | GUC2HOST_STATUS_SUCCESS = GUC2HOST_STATUS(0x0), | ||
240 | GUC2HOST_STATUS_ALLOCATE_DOORBELL_FAIL = GUC2HOST_STATUS(0x10), | ||
241 | GUC2HOST_STATUS_DEALLOCATE_DOORBELL_FAIL = GUC2HOST_STATUS(0x20), | ||
242 | GUC2HOST_STATUS_GENERIC_FAIL = GUC2HOST_STATUS(0x0000F000) | ||
243 | }; | ||
244 | |||
245 | #endif | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 70bad5bf1d48..51cbea8247fe 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -1909,7 +1909,7 @@ static void intel_hdmi_destroy(struct drm_connector *connector) | |||
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 1911 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
1912 | .dpms = intel_connector_dpms, | 1912 | .dpms = drm_atomic_helper_connector_dpms, |
1913 | .detect = intel_hdmi_detect, | 1913 | .detect = intel_hdmi_detect, |
1914 | .force = intel_hdmi_force, | 1914 | .force = intel_hdmi_force, |
1915 | .fill_modes = drm_helper_probe_single_connector_modes, | 1915 | .fill_modes = drm_helper_probe_single_connector_modes, |
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 3c9171f11531..032a0bf75f3b 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c | |||
@@ -76,17 +76,23 @@ | |||
76 | * it will use i915_hotplug_work_func where this logic is handled. | 76 | * it will use i915_hotplug_work_func where this logic is handled. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | enum port intel_hpd_pin_to_port(enum hpd_pin pin) | 79 | bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port) |
80 | { | 80 | { |
81 | switch (pin) { | 81 | switch (pin) { |
82 | case HPD_PORT_A: | ||
83 | *port = PORT_A; | ||
84 | return true; | ||
82 | case HPD_PORT_B: | 85 | case HPD_PORT_B: |
83 | return PORT_B; | 86 | *port = PORT_B; |
87 | return true; | ||
84 | case HPD_PORT_C: | 88 | case HPD_PORT_C: |
85 | return PORT_C; | 89 | *port = PORT_C; |
90 | return true; | ||
86 | case HPD_PORT_D: | 91 | case HPD_PORT_D: |
87 | return PORT_D; | 92 | *port = PORT_D; |
93 | return true; | ||
88 | default: | 94 | default: |
89 | return PORT_A; /* no hpd */ | 95 | return false; /* no hpd */ |
90 | } | 96 | } |
91 | } | 97 | } |
92 | 98 | ||
@@ -369,8 +375,8 @@ void intel_hpd_irq_handler(struct drm_device *dev, | |||
369 | if (!(BIT(i) & pin_mask)) | 375 | if (!(BIT(i) & pin_mask)) |
370 | continue; | 376 | continue; |
371 | 377 | ||
372 | port = intel_hpd_pin_to_port(i); | 378 | is_dig_port = intel_hpd_pin_to_port(i, &port) && |
373 | is_dig_port = port && dev_priv->hotplug.irq_port[port]; | 379 | dev_priv->hotplug.irq_port[port]; |
374 | 380 | ||
375 | if (is_dig_port) { | 381 | if (is_dig_port) { |
376 | bool long_hpd = long_mask & BIT(i); | 382 | bool long_hpd = long_mask & BIT(i); |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9faad82c42ec..5bc0ce1347ce 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -497,6 +497,9 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) | |||
497 | status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + | 497 | status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + |
498 | (read_pointer % 6) * 8 + 4); | 498 | (read_pointer % 6) * 8 + 4); |
499 | 499 | ||
500 | if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) | ||
501 | continue; | ||
502 | |||
500 | if (status & GEN8_CTX_STATUS_PREEMPTED) { | 503 | if (status & GEN8_CTX_STATUS_PREEMPTED) { |
501 | if (status & GEN8_CTX_STATUS_LITE_RESTORE) { | 504 | if (status & GEN8_CTX_STATUS_LITE_RESTORE) { |
502 | if (execlists_check_remove_request(ring, status_id)) | 505 | if (execlists_check_remove_request(ring, status_id)) |
@@ -521,7 +524,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) | |||
521 | ring->next_context_status_buffer = write_pointer % 6; | 524 | ring->next_context_status_buffer = write_pointer % 6; |
522 | 525 | ||
523 | I915_WRITE(RING_CONTEXT_STATUS_PTR(ring), | 526 | I915_WRITE(RING_CONTEXT_STATUS_PTR(ring), |
524 | ((u32)ring->next_context_status_buffer & 0x07) << 8); | 527 | _MASKED_FIELD(0x07 << 8, ((u32)ring->next_context_status_buffer & 0x07) << 8)); |
525 | } | 528 | } |
526 | 529 | ||
527 | static int execlists_context_queue(struct drm_i915_gem_request *request) | 530 | static int execlists_context_queue(struct drm_i915_gem_request *request) |
@@ -1740,6 +1743,12 @@ static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req) | |||
1740 | if (ret) | 1743 | if (ret) |
1741 | goto out; | 1744 | goto out; |
1742 | 1745 | ||
1746 | ret = req->ring->emit_bb_start(req, | ||
1747 | (so.ggtt_offset + so.aux_batch_offset), | ||
1748 | I915_DISPATCH_SECURE); | ||
1749 | if (ret) | ||
1750 | goto out; | ||
1751 | |||
1743 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); | 1752 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req); |
1744 | 1753 | ||
1745 | out: | 1754 | out: |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index cb634f48e7d9..881b5d13592e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -549,7 +549,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs | |||
549 | }; | 549 | }; |
550 | 550 | ||
551 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 551 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
552 | .dpms = intel_connector_dpms, | 552 | .dpms = drm_atomic_helper_connector_dpms, |
553 | .detect = intel_lvds_detect, | 553 | .detect = intel_lvds_detect, |
554 | .fill_modes = drm_helper_probe_single_connector_modes, | 554 | .fill_modes = drm_helper_probe_single_connector_modes, |
555 | .set_property = intel_lvds_set_property, | 555 | .set_property = intel_lvds_set_property, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5004c4a46a9e..fff0c22682ee 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -102,6 +102,12 @@ static void skl_init_clock_gating(struct drm_device *dev) | |||
102 | /* WaDisableLSQCROPERFforOCL:skl */ | 102 | /* WaDisableLSQCROPERFforOCL:skl */ |
103 | I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | | 103 | I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | |
104 | GEN8_LQSC_RO_PERF_DIS); | 104 | GEN8_LQSC_RO_PERF_DIS); |
105 | |||
106 | /* WaEnableGapsTsvCreditFix:skl */ | ||
107 | if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) { | ||
108 | I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | | ||
109 | GEN9_GAPS_TSV_CREDIT_DISABLE)); | ||
110 | } | ||
105 | } | 111 | } |
106 | 112 | ||
107 | static void bxt_init_clock_gating(struct drm_device *dev) | 113 | static void bxt_init_clock_gating(struct drm_device *dev) |
@@ -4266,7 +4272,7 @@ static void ironlake_enable_drps(struct drm_device *dev) | |||
4266 | 4272 | ||
4267 | if (wait_for_atomic((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) | 4273 | if (wait_for_atomic((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) |
4268 | DRM_ERROR("stuck trying to change perf mode\n"); | 4274 | DRM_ERROR("stuck trying to change perf mode\n"); |
4269 | msleep(1); | 4275 | mdelay(1); |
4270 | 4276 | ||
4271 | ironlake_set_drps(dev, fstart); | 4277 | ironlake_set_drps(dev, fstart); |
4272 | 4278 | ||
@@ -4297,10 +4303,10 @@ static void ironlake_disable_drps(struct drm_device *dev) | |||
4297 | 4303 | ||
4298 | /* Go back to the starting frequency */ | 4304 | /* Go back to the starting frequency */ |
4299 | ironlake_set_drps(dev, dev_priv->ips.fstart); | 4305 | ironlake_set_drps(dev, dev_priv->ips.fstart); |
4300 | msleep(1); | 4306 | mdelay(1); |
4301 | rgvswctl |= MEMCTL_CMD_STS; | 4307 | rgvswctl |= MEMCTL_CMD_STS; |
4302 | I915_WRITE(MEMSWCTL, rgvswctl); | 4308 | I915_WRITE(MEMSWCTL, rgvswctl); |
4303 | msleep(1); | 4309 | mdelay(1); |
4304 | 4310 | ||
4305 | spin_unlock_irq(&mchdev_lock); | 4311 | spin_unlock_irq(&mchdev_lock); |
4306 | } | 4312 | } |
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index acd8ec859f71..a04b4dc5ed9b 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c | |||
@@ -698,6 +698,7 @@ void intel_psr_flush(struct drm_device *dev, | |||
698 | struct drm_i915_private *dev_priv = dev->dev_private; | 698 | struct drm_i915_private *dev_priv = dev->dev_private; |
699 | struct drm_crtc *crtc; | 699 | struct drm_crtc *crtc; |
700 | enum pipe pipe; | 700 | enum pipe pipe; |
701 | int delay_ms = HAS_DDI(dev) ? 100 : 500; | ||
701 | 702 | ||
702 | mutex_lock(&dev_priv->psr.lock); | 703 | mutex_lock(&dev_priv->psr.lock); |
703 | if (!dev_priv->psr.enabled) { | 704 | if (!dev_priv->psr.enabled) { |
@@ -733,7 +734,7 @@ void intel_psr_flush(struct drm_device *dev, | |||
733 | 734 | ||
734 | if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) | 735 | if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) |
735 | schedule_delayed_work(&dev_priv->psr.work, | 736 | schedule_delayed_work(&dev_priv->psr.work, |
736 | msecs_to_jiffies(100)); | 737 | msecs_to_jiffies(delay_ms)); |
737 | mutex_unlock(&dev_priv->psr.lock); | 738 | mutex_unlock(&dev_priv->psr.lock); |
738 | } | 739 | } |
739 | 740 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 177f7ed16cf0..6e6b8db996ef 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -780,11 +780,11 @@ static int wa_add(struct drm_i915_private *dev_priv, | |||
780 | return 0; | 780 | return 0; |
781 | } | 781 | } |
782 | 782 | ||
783 | #define WA_REG(addr, mask, val) { \ | 783 | #define WA_REG(addr, mask, val) do { \ |
784 | const int r = wa_add(dev_priv, (addr), (mask), (val)); \ | 784 | const int r = wa_add(dev_priv, (addr), (mask), (val)); \ |
785 | if (r) \ | 785 | if (r) \ |
786 | return r; \ | 786 | return r; \ |
787 | } | 787 | } while (0) |
788 | 788 | ||
789 | #define WA_SET_BIT_MASKED(addr, mask) \ | 789 | #define WA_SET_BIT_MASKED(addr, mask) \ |
790 | WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask)) | 790 | WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask)) |
@@ -1041,13 +1041,6 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1041 | WA_SET_BIT_MASKED(HIZ_CHICKEN, | 1041 | WA_SET_BIT_MASKED(HIZ_CHICKEN, |
1042 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); | 1042 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); |
1043 | 1043 | ||
1044 | if (INTEL_REVID(dev) == SKL_REVID_C0 || | ||
1045 | INTEL_REVID(dev) == SKL_REVID_D0) | ||
1046 | /* WaBarrierPerformanceFixDisable:skl */ | ||
1047 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
1048 | HDC_FENCE_DEST_SLM_DISABLE | | ||
1049 | HDC_BARRIER_PERFORMANCE_DISABLE); | ||
1050 | |||
1051 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | 1044 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { |
1052 | /* | 1045 | /* |
1053 | *Use Force Non-Coherent whenever executing a 3D context. This | 1046 | *Use Force Non-Coherent whenever executing a 3D context. This |
@@ -1066,6 +1059,13 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1066 | HDC_FENCE_DEST_SLM_DISABLE | | 1059 | HDC_FENCE_DEST_SLM_DISABLE | |
1067 | HDC_BARRIER_PERFORMANCE_DISABLE); | 1060 | HDC_BARRIER_PERFORMANCE_DISABLE); |
1068 | 1061 | ||
1062 | /* WaDisableSbeCacheDispatchPortSharing:skl */ | ||
1063 | if (INTEL_REVID(dev) <= SKL_REVID_F0) { | ||
1064 | WA_SET_BIT_MASKED( | ||
1065 | GEN7_HALF_SLICE_CHICKEN1, | ||
1066 | GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); | ||
1067 | } | ||
1068 | |||
1069 | return skl_tune_iz_hashing(ring); | 1069 | return skl_tune_iz_hashing(ring); |
1070 | } | 1070 | } |
1071 | 1071 | ||
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 6393b76f87ff..821644d1b544 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -68,6 +68,22 @@ | |||
68 | bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, | 68 | bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, |
69 | int power_well_id); | 69 | int power_well_id); |
70 | 70 | ||
71 | static void intel_power_well_enable(struct drm_i915_private *dev_priv, | ||
72 | struct i915_power_well *power_well) | ||
73 | { | ||
74 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | ||
75 | power_well->ops->enable(dev_priv, power_well); | ||
76 | power_well->hw_enabled = true; | ||
77 | } | ||
78 | |||
79 | static void intel_power_well_disable(struct drm_i915_private *dev_priv, | ||
80 | struct i915_power_well *power_well) | ||
81 | { | ||
82 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | ||
83 | power_well->hw_enabled = false; | ||
84 | power_well->ops->disable(dev_priv, power_well); | ||
85 | } | ||
86 | |||
71 | /* | 87 | /* |
72 | * We should only use the power well if we explicitly asked the hardware to | 88 | * We should only use the power well if we explicitly asked the hardware to |
73 | * enable it, so check if it's enabled and also check if we've requested it to | 89 | * enable it, so check if it's enabled and also check if we've requested it to |
@@ -1104,11 +1120,8 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
1104 | mutex_lock(&power_domains->lock); | 1120 | mutex_lock(&power_domains->lock); |
1105 | 1121 | ||
1106 | for_each_power_well(i, power_well, BIT(domain), power_domains) { | 1122 | for_each_power_well(i, power_well, BIT(domain), power_domains) { |
1107 | if (!power_well->count++) { | 1123 | if (!power_well->count++) |
1108 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | 1124 | intel_power_well_enable(dev_priv, power_well); |
1109 | power_well->ops->enable(dev_priv, power_well); | ||
1110 | power_well->hw_enabled = true; | ||
1111 | } | ||
1112 | } | 1125 | } |
1113 | 1126 | ||
1114 | power_domains->domain_use_count[domain]++; | 1127 | power_domains->domain_use_count[domain]++; |
@@ -1142,11 +1155,8 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
1142 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 1155 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
1143 | WARN_ON(!power_well->count); | 1156 | WARN_ON(!power_well->count); |
1144 | 1157 | ||
1145 | if (!--power_well->count && i915.disable_power_well) { | 1158 | if (!--power_well->count && i915.disable_power_well) |
1146 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | 1159 | intel_power_well_disable(dev_priv, power_well); |
1147 | power_well->hw_enabled = false; | ||
1148 | power_well->ops->disable(dev_priv, power_well); | ||
1149 | } | ||
1150 | } | 1160 | } |
1151 | 1161 | ||
1152 | mutex_unlock(&power_domains->lock); | 1162 | mutex_unlock(&power_domains->lock); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 2c435a79d4da..c98098e884cc 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1508,53 +1508,6 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) | |||
1508 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); | 1508 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
1509 | } | 1509 | } |
1510 | 1510 | ||
1511 | /* Special dpms function to support cloning between dvo/sdvo/crt. */ | ||
1512 | static int intel_sdvo_dpms(struct drm_connector *connector, int mode) | ||
1513 | { | ||
1514 | struct drm_crtc *crtc; | ||
1515 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
1516 | |||
1517 | /* dvo supports only 2 dpms states. */ | ||
1518 | if (mode != DRM_MODE_DPMS_ON) | ||
1519 | mode = DRM_MODE_DPMS_OFF; | ||
1520 | |||
1521 | if (mode == connector->dpms) | ||
1522 | return 0; | ||
1523 | |||
1524 | connector->dpms = mode; | ||
1525 | |||
1526 | /* Only need to change hw state when actually enabled */ | ||
1527 | crtc = intel_sdvo->base.base.crtc; | ||
1528 | if (!crtc) { | ||
1529 | intel_sdvo->base.connectors_active = false; | ||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1533 | /* We set active outputs manually below in case pipe dpms doesn't change | ||
1534 | * due to cloning. */ | ||
1535 | if (mode != DRM_MODE_DPMS_ON) { | ||
1536 | intel_sdvo_set_active_outputs(intel_sdvo, 0); | ||
1537 | if (0) | ||
1538 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); | ||
1539 | |||
1540 | intel_sdvo->base.connectors_active = false; | ||
1541 | |||
1542 | intel_crtc_update_dpms(crtc); | ||
1543 | } else { | ||
1544 | intel_sdvo->base.connectors_active = true; | ||
1545 | |||
1546 | intel_crtc_update_dpms(crtc); | ||
1547 | |||
1548 | if (0) | ||
1549 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); | ||
1550 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); | ||
1551 | } | ||
1552 | |||
1553 | intel_modeset_check_state(connector->dev); | ||
1554 | |||
1555 | return 0; | ||
1556 | } | ||
1557 | |||
1558 | static enum drm_mode_status | 1511 | static enum drm_mode_status |
1559 | intel_sdvo_mode_valid(struct drm_connector *connector, | 1512 | intel_sdvo_mode_valid(struct drm_connector *connector, |
1560 | struct drm_display_mode *mode) | 1513 | struct drm_display_mode *mode) |
@@ -2192,7 +2145,7 @@ done: | |||
2192 | } | 2145 | } |
2193 | 2146 | ||
2194 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 2147 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
2195 | .dpms = intel_sdvo_dpms, | 2148 | .dpms = drm_atomic_helper_connector_dpms, |
2196 | .detect = intel_sdvo_detect, | 2149 | .detect = intel_sdvo_detect, |
2197 | .fill_modes = drm_helper_probe_single_connector_modes, | 2150 | .fill_modes = drm_helper_probe_single_connector_modes, |
2198 | .set_property = intel_sdvo_set_property, | 2151 | .set_property = intel_sdvo_set_property, |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 8b9d325bda3c..0568ae6ec9dd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1509,7 +1509,7 @@ out: | |||
1509 | } | 1509 | } |
1510 | 1510 | ||
1511 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1511 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
1512 | .dpms = intel_connector_dpms, | 1512 | .dpms = drm_atomic_helper_connector_dpms, |
1513 | .detect = intel_tv_detect, | 1513 | .detect = intel_tv_detect, |
1514 | .destroy = intel_tv_destroy, | 1514 | .destroy = intel_tv_destroy, |
1515 | .set_property = intel_tv_set_property, | 1515 | .set_property = intel_tv_set_property, |