aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-12-15 09:29:43 -0500
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-02-01 16:05:07 -0500
commit37255d8d3f4d0c88fc9f60f50bb4c3c30e6688cc (patch)
tree88c223b2ca5467e2c2caffcd0809bf64c7e0f825
parenta667fb402c1e856209bf9e77ba41fc1cf356b867 (diff)
drm/i915: Fix POWER_DOMAIN_AUDIO refcounting.
If the crtc was brought up with audio before the driver loads, then crtc_disable will remove a refcount to audio that doesn't exist before. Fortunately we already set power domains on readout, so we can just add the power domain handling to get_crtc_power_domains, which will update the power domains correctly in all cases. This was found when testing module reload on CI with the crtc enabled, which resulted in the following warn after module reload + modeset: [ 24.197041] ------------[ cut here ]------------ [ 24.197075] WARNING: CPU: 0 PID: 99 at drivers/gpu/drm/i915/intel_runtime_pm.c:1790 intel_display_power_put+0x134/0x140 [i915] [ 24.197076] Use count on domain AUDIO is already zero [ 24.197098] CPU: 0 PID: 99 Comm: kworker/u8:2 Not tainted 4.9.0-CI-Trybot_393+ #1 [ 24.197099] Hardware name: /NUC6i5SYB, BIOS SYSKLi35.86A.0042.2016.0409.1246 04/09/2016 [ 24.197102] Workqueue: events_unbound async_run_entry_fn [ 24.197105] ffffc900003c7688 ffffffff81435b35 ffffc900003c76d8 0000000000000000 [ 24.197107] ffffc900003c76c8 ffffffff8107e4d6 000006fe5dc36f28 ffff88025dc30054 [ 24.197109] ffff88025dc36f28 ffff88025dc30000 ffff88025dc30000 0000000000000015 [ 24.197110] Call Trace: [ 24.197113] [<ffffffff81435b35>] dump_stack+0x67/0x92 [ 24.197116] [<ffffffff8107e4d6>] __warn+0xc6/0xe0 [ 24.197118] [<ffffffff8107e53a>] warn_slowpath_fmt+0x4a/0x50 [ 24.197149] [<ffffffffa039b4b4>] intel_display_power_put+0x134/0x140 [i915] [ 24.197187] [<ffffffffa04217dd>] intel_disable_ddi+0x4d/0x80 [i915] [ 24.197223] [<ffffffffa03f388f>] intel_encoders_disable.isra.74+0x7f/0x90 [i915] [ 24.197257] [<ffffffffa03f6c05>] haswell_crtc_disable+0x55/0x170 [i915] [ 24.197292] [<ffffffffa03fec88>] intel_atomic_commit_tail+0x108/0xfd0 [i915] [ 24.197295] [<ffffffff810d47c6>] ? __lock_is_held+0x66/0x90 [ 24.197330] [<ffffffffa03fff79>] intel_atomic_commit+0x429/0x560 [i915] [ 24.197332] [<ffffffff81570186>] ?drm_atomic_add_affected_connectors+0x56/0xf0 [ 24.197334] [<ffffffff8156f726>] drm_atomic_commit+0x46/0x50 [ 24.197336] [<ffffffff81553f87>] restore_fbdev_mode+0x147/0x270 [ 24.197337] [<ffffffff81555bee>] drm_fb_helper_restore_fbdev_mode_unlocked+0x2e/0x70 [ 24.197339] [<ffffffff81555aa8>] drm_fb_helper_set_par+0x28/0x50 [ 24.197374] [<ffffffffa041c7d3>] intel_fbdev_set_par+0x13/0x70 [i915] [ 24.197376] [<ffffffff8149e07a>] fbcon_init+0x57a/0x600 [ 24.197379] [<ffffffff81514b71>] visual_init+0xd1/0x130 [ 24.197381] [<ffffffff8151603c>] do_bind_con_driver+0x1bc/0x3a0 [ 24.197384] [<ffffffff81516521>] do_take_over_console+0x111/0x180 [ 24.197386] [<ffffffff8149e152>] do_fbcon_takeover+0x52/0xb0 [ 24.197387] [<ffffffff814a12c3>] fbcon_event_notify+0x723/0x850 [ 24.197390] [<ffffffff810a4830>] ?__blocking_notifier_call_chain+0x30/0x70 [ 24.197392] [<ffffffff810a44a4>] notifier_call_chain+0x34/0xa0 [ 24.197394] [<ffffffff810a4848>] __blocking_notifier_call_chain+0x48/0x70 [ 24.197397] [<ffffffff810a4881>] blocking_notifier_call_chain+0x11/0x20 [ 24.197398] [<ffffffff814a4556>] fb_notifier_call_chain+0x16/0x20 [ 24.197400] [<ffffffff814a678c>] register_framebuffer+0x24c/0x330 [ 24.197402] [<ffffffff815558d9>] drm_fb_helper_initial_config+0x219/0x3c0 [ 24.197436] [<ffffffffa041d373>] intel_fbdev_initial_config+0x13/0x30 [i915] [ 24.197438] [<ffffffff810a5d44>] async_run_entry_fn+0x34/0x140 [ 24.197440] [<ffffffff8109c26c>] process_one_work+0x1ec/0x6b0 [ 24.197442] [<ffffffff8109c1e6>] ? process_one_work+0x166/0x6b0 [ 24.197445] [<ffffffff8109c779>] worker_thread+0x49/0x490 [ 24.197447] [<ffffffff8109c730>] ? process_one_work+0x6b0/0x6b0 [ 24.197448] [<ffffffff810a2a9b>] kthread+0xeb/0x110 [ 24.197451] [<ffffffff810a29b0>] ? kthread_park+0x60/0x60 [ 24.197453] [<ffffffff818241a7>] ret_from_fork+0x27/0x40 [ 24.197476] ---[ end trace bda64b683b8e8162 ]--- Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1481812185-19098-3-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c14
-rw-r--r--drivers/gpu/drm/i915/intel_display.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c9
3 files changed, 8 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9a9a670f8549..d957211c76ad 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1835,8 +1835,6 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder,
1835 struct drm_connector_state *conn_state) 1835 struct drm_connector_state *conn_state)
1836{ 1836{
1837 struct drm_encoder *encoder = &intel_encoder->base; 1837 struct drm_encoder *encoder = &intel_encoder->base;
1838 struct drm_crtc *crtc = encoder->crtc;
1839 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1840 struct drm_i915_private *dev_priv = to_i915(encoder->dev); 1838 struct drm_i915_private *dev_priv = to_i915(encoder->dev);
1841 enum port port = intel_ddi_get_encoder_port(intel_encoder); 1839 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1842 int type = intel_encoder->type; 1840 int type = intel_encoder->type;
@@ -1863,10 +1861,8 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder,
1863 intel_edp_drrs_enable(intel_dp, pipe_config); 1861 intel_edp_drrs_enable(intel_dp, pipe_config);
1864 } 1862 }
1865 1863
1866 if (intel_crtc->config->has_audio) { 1864 if (pipe_config->has_audio)
1867 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
1868 intel_audio_codec_enable(intel_encoder, pipe_config, conn_state); 1865 intel_audio_codec_enable(intel_encoder, pipe_config, conn_state);
1869 }
1870} 1866}
1871 1867
1872static void intel_disable_ddi(struct intel_encoder *intel_encoder, 1868static void intel_disable_ddi(struct intel_encoder *intel_encoder,
@@ -1874,16 +1870,10 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder,
1874 struct drm_connector_state *old_conn_state) 1870 struct drm_connector_state *old_conn_state)
1875{ 1871{
1876 struct drm_encoder *encoder = &intel_encoder->base; 1872 struct drm_encoder *encoder = &intel_encoder->base;
1877 struct drm_crtc *crtc = encoder->crtc;
1878 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1879 int type = intel_encoder->type; 1873 int type = intel_encoder->type;
1880 struct drm_device *dev = encoder->dev;
1881 struct drm_i915_private *dev_priv = to_i915(dev);
1882 1874
1883 if (intel_crtc->config->has_audio) { 1875 if (old_crtc_state->has_audio)
1884 intel_audio_codec_disable(intel_encoder); 1876 intel_audio_codec_disable(intel_encoder);
1885 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
1886 }
1887 1877
1888 if (type == INTEL_OUTPUT_EDP) { 1878 if (type == INTEL_OUTPUT_EDP) {
1889 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1879 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b44e9466d394..88689a0b4183 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5730,6 +5730,7 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
5730 struct intel_crtc_state *crtc_state) 5730 struct intel_crtc_state *crtc_state)
5731{ 5731{
5732 struct drm_device *dev = crtc->dev; 5732 struct drm_device *dev = crtc->dev;
5733 struct drm_i915_private *dev_priv = to_i915(dev);
5733 struct drm_encoder *encoder; 5734 struct drm_encoder *encoder;
5734 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5735 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
5735 enum pipe pipe = intel_crtc->pipe; 5736 enum pipe pipe = intel_crtc->pipe;
@@ -5751,6 +5752,9 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
5751 mask |= BIT(intel_display_port_power_domain(intel_encoder)); 5752 mask |= BIT(intel_display_port_power_domain(intel_encoder));
5752 } 5753 }
5753 5754
5755 if (HAS_DDI(dev_priv) && crtc_state->has_audio)
5756 mask |= BIT(POWER_DOMAIN_AUDIO);
5757
5754 if (crtc_state->shared_dpll) 5758 if (crtc_state->shared_dpll)
5755 mask |= BIT(POWER_DOMAIN_PLLS); 5759 mask |= BIT(POWER_DOMAIN_PLLS);
5756 5760
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 95267fcef71b..6a85d388f936 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -92,7 +92,6 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
92 struct intel_dp *intel_dp = &intel_dig_port->dp; 92 struct intel_dp *intel_dp = &intel_dig_port->dp;
93 struct intel_connector *connector = 93 struct intel_connector *connector =
94 to_intel_connector(old_conn_state->connector); 94 to_intel_connector(old_conn_state->connector);
95 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
96 int ret; 95 int ret;
97 96
98 DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); 97 DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
@@ -103,10 +102,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
103 if (ret) { 102 if (ret) {
104 DRM_ERROR("failed to update payload %d\n", ret); 103 DRM_ERROR("failed to update payload %d\n", ret);
105 } 104 }
106 if (old_crtc_state->has_audio) { 105 if (old_crtc_state->has_audio)
107 intel_audio_codec_disable(encoder); 106 intel_audio_codec_disable(encoder);
108 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
109 }
110} 107}
111 108
112static void intel_mst_post_disable_dp(struct intel_encoder *encoder, 109static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
@@ -219,10 +216,8 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder,
219 ret = drm_dp_check_act_status(&intel_dp->mst_mgr); 216 ret = drm_dp_check_act_status(&intel_dp->mst_mgr);
220 217
221 ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr); 218 ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr);
222 if (pipe_config->has_audio) { 219 if (pipe_config->has_audio)
223 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
224 intel_audio_codec_enable(encoder, pipe_config, conn_state); 220 intel_audio_codec_enable(encoder, pipe_config, conn_state);
225 }
226} 221}
227 222
228static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder, 223static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,