drm/i915: Clear fb_tracking.busy_bits also for synchronous flips
Subsystems (2)
PATCH 1/9 drm/i915: Clear fb_tracking.busy_bits also for synchronous flips
The current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the flip_prepare and flip_complete functions) already does this, but somehow I've forgotten to do this for synchronous flips.
Note that we don't track outstanding rendering of the new framebuffer with busy_bits since all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.
---
Paulo promised to also extend kms_frontbuffer_tracking with flip vs. busy buffer tests.
--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)
drivers/gpu/drm/i915/intel_drv.h +2 -16
@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device -* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will -* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inline void intel_frontbuffer_flip (struct drm_device *dev, -unsigned frontbuffer_bits) -{ -intel_frontbuffer_flush (dev, frontbuffer_bits); -} +unsigned frontbuffer_bits); unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height,
drivers/gpu/drm/i915/intel_frontbuffer.c +26 -0
@@ -270,3 +270,29 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev,intel_frontbuffer_flush (dev, frontbuffer_bits); } + +/** +* intel_frontbuffer_flip - synchronous frontbuffer flip +* @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits +* +* This function gets called after scheduling a flip on @obj. This is for +* synchronous plane updates which will happen on the next vblank and which will +* not get delayed by pending gpu rendering. +* +* Can be called without any locks held. +*/ +inline +void intel_frontbuffer_flip (struct drm_device *dev, +unsigned frontbuffer_bits) +{ +struct drm_i915_private *dev_priv = dev->dev_private; + +mutex_lock (&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; +/* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; +mutex_unlock (&dev_priv->fb_tracking.lock); + +intel_frontbuffer_flush (dev, frontbuffer_bits); +}
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 2/9 drm/i915: Filter out no-op frontbuffer tracking flushes
Paulo noticed that the fbc frontbuffer tracking flush callback occasionally gets a call without any bit set. This can happen when we have to filter flush calls due to e.g. gpu rendering. Filter these out.
--- drivers/gpu/drm/i915/intel_frontbuffer.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/i915/intel_frontbuffer.c +3 -0
@@ -179,6 +179,9 @@ void intel_frontbuffer_flush(struct drm_device *dev, frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;mutex_unlock (&dev_priv->fb_tracking.lock); +if (!frontbuffer_bits) +return ; +intel_mark_fb_busy (dev, frontbuffer_bits,NULL );intel_edp_drrs_flush (dev, frontbuffer_bits);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 2/9] drm/i915: Filter out no-op frontbuffer tracking flushes
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 8 lines
Paulo noticed that the fbc frontbuffer tracking flush callback occasionally gets a call without any bit set. This can happen when we have to filter flush calls due to e.g. gpu rendering. Filter these out.
Reported-by Paulo Zanoni <[email protected]>Cc Paulo Zanoni <[email protected]>Signed-off-by Daniel Vetter <[email protected]>
Quoted 21 lines
--- drivers/gpu/drm/i915/intel_frontbuffer.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/i915/intel_frontbuffer.c +3
-1@@ -179,6 +179,9 @@ void intel_frontbuffer_flush(struct drm_device *dev, frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;mutex_unlock (&dev_priv->fb_tracking.lock); +if (!frontbuffer_bits) +return ; +intel_mark_fb_busy (dev, frontbuffer_bits,NULL );intel_edp_drrs_flush (dev, frontbuffer_bits); --2.1.0
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 3/9 drm/i915: debugfs for frontbuffer tracking
In reply to Daniel VetterUseful to figure out whether stuck bits are due to the frontbuffer tracking code as opposed to individual consumers (who have their own bitmask tracking).
--- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/gpu/drm/i915/i915_debugfs.c +16 -0
@@ -1581,6 +1581,21 @@ static int i915_drpc_info(struct seq_file *m, void *unused)return ironlake_drpc_info (m); } +static int i915_frontbuffer_tracking (struct seq_file *m,void *unused) +{ +struct drm_info_node *node = m->private; +struct drm_device *dev = node->minor->dev; +struct drm_i915_private *dev_priv = dev->dev_private; + +seq_printf (m,"FB tracking busy bits: 0x%08x\n" , + dev_priv->fb_tracking.busy_bits); + +seq_printf (m,"FB tracking flip bits: 0x%08x\n" , + dev_priv->fb_tracking.flip_bits); + +return 0 ; +} +static int i915_fbc_status (struct seq_file *m,void *unused) {struct drm_info_node *node = m->private;
@@ -5024,6 +5039,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_drpc_info", i915_drpc_info, 0}, {"i915_emon_status", i915_emon_status, 0}, {"i915_ring_freq_table", i915_ring_freq_table, 0}, + {"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0}, {"i915_fbc_status", i915_fbc_status, 0}, {"i915_ips_status", i915_ips_status, 0}, {"i915_sr_status", i915_sr_status, 0},
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/9] drm/i915: debugfs for frontbuffer tracking
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 3 lines
Useful to figure out whether stuck bits are due to the frontbuffer tracking code as opposed to individual consumers (who have their own bitmask tracking).
Quoted 47 lines
Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)drivers/gpu/drm/i915/i915_debugfs.c +16
-1@@ -1581,6 +1581,21 @@ static int i915_drpc_info(struct seq_file *m, void *unused)return ironlake_drpc_info (m); } +static int i915_frontbuffer_tracking (struct seq_file *m,void *unused) +{ +struct drm_info_node *node = m->private; +struct drm_device *dev = node->minor->dev; +struct drm_i915_private *dev_priv = dev->dev_private; + +seq_printf (m,"FB tracking busy bits: 0x%08x\n" , + dev_priv->fb_tracking.busy_bits); + +seq_printf (m,"FB tracking flip bits: 0x%08x\n" , + dev_priv->fb_tracking.flip_bits); + +return 0 ; +} +static int i915_fbc_status (struct seq_file *m,void *unused) {struct drm_info_node *node = m->private;@@ -5024,6 +5039,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_drpc_info", i915_drpc_info, 0}, {"i915_emon_status", i915_emon_status, 0}, {"i915_ring_freq_table", i915_ring_freq_table, 0}, + {"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0}, {"i915_fbc_status", i915_fbc_status, 0}, {"i915_ips_status", i915_ips_status, 0}, {"i915_sr_status", i915_sr_status, 0}, --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 4/9 drm/i915: Nuke lvds downclock support
In reply to Daniel VetterWith the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
--- drivers/gpu/drm/i915/i915_drv.h | 4 -- drivers/gpu/drm/i915/i915_params.c | 6 --- drivers/gpu/drm/i915/intel_bios.c | 62 +--------------------- drivers/gpu/drm/i915/intel_display.c | 90 +++----------------------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 57 -------------------- drivers/gpu/drm/i915/intel_lvds.c | 18 +------ 6 files changed, 8 insertions(+), 229 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +0 -4
@@ -1793,9 +1793,6 @@ struct drm_i915_private {/* Reclocking support */ bool render_reclock_avail; -bool lvds_downclock_avail; -/* indicates the reduced downclock for LVDS*/ -int lvds_downclock;struct i915_frontbuffer_tracking fb_tracking;
@@ -2548,7 +2545,6 @@ struct i915_params {int modeset;int panel_ignore_lid;int semaphores; -unsigned int lvds_downclock;int lvds_channel_mode;int panel_use_ssc;int vbt_sdvo_panel_type;
drivers/gpu/drm/i915/i915_params.c +0 -6
@@ -28,7 +28,6 @@ struct i915_params i915 __read_mostly = { .modeset = -1, .panel_ignore_lid = 1, .semaphores = -1, - .lvds_downclock = 0, .lvds_channel_mode = 0, .panel_use_ssc = -1, .vbt_sdvo_panel_type = -1,
@@ -84,11 +83,6 @@ MODULE_PARM_DESC(enable_fbc,"Enable frame buffer compression for power savings " "(default: -1 (use per-chip default))"); -module_param_named (lvds_downclock, i915.lvds_downclock, int,0400 ); -MODULE_PARM_DESC (lvds_downclock, -"Use panel (LVDS/eDP) downclocking for power savings " -"(default: false)" ); -module_param_named (lvds_channel_mode, i915.lvds_channel_mode, int,0600 );MODULE_PARM_DESC (lvds_channel_mode, "Specify LVDS channel mode "
drivers/gpu/drm/i915/intel_bios.c +1 -61
80 lines not on this page · raw message
drivers/gpu/drm/i915/intel_display.c +6 -84
150 lines not on this page · raw message
drivers/gpu/drm/i915/intel_frontbuffer.c +0 -57
75 lines not on this page · raw message
drivers/gpu/drm/i915/intel_lvds.c +1 -17
@@ -1068,24 +1068,8 @@ void intel_lvds_init(struct drm_device *dev)drm_mode_debug_printmodeline (scan); fixed_mode =drm_mode_duplicate (dev, scan); -if (fixed_mode) { - downclock_mode = -intel_find_panel_downclock (dev, - fixed_mode, connector); -if (downclock_mode !=NULL && - i915.lvds_downclock) { -/* We found the downclock for LVDS. */ - dev_priv->lvds_downclock_avail = true; - dev_priv->lvds_downclock = - downclock_mode->clock; -DRM_DEBUG_KMS ("LVDS downclock is found" -" in EDID. Normal clock %dKhz, " -"downclock %dKhz\n" , - fixed_mode->clock, - dev_priv->lvds_downclock); - } +if (fixed_mode) goto out; - } } }
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 4/9] drm/i915: Nuke lvds downclock support
Quoted 7 lines · Daniel Vetter
With the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
Can you nuke just the intel_mark_busy side? Keeping the mode finder intact would be useful as the intrepid reader need only then implement the intel_frontbuffer callbacks and have the harder part of matching appropriate modes and switching routines ready to plug in. (Those latter ones I expect to be tweaked over time, and so the reader's first step of reverting this commit would conflict in such a way as to dissuade them.) -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 4/9] drm/i915: Nuke lvds downclock support
Quoted 9 lines · Chris Wilson
Quoted 7 lines · Daniel Vetter
With the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
Quoted 6 lines
Can you nuke just the
intel_mark_busyside? Keeping the mode finder intact would be useful as the intrepid reader need only then implement theintel_frontbuffercallbacks and have the harder part of matching appropriate modes and switching routines ready to plug in. (Those latter ones I expect to be tweaked over time, and so the reader's first step of reverting this commit would conflict in such a way as to dissuade them.)
Well I was also somewhat annoyed by the dev_priv->lvds_* stuff and figured getting rid of that is good - it really should be stored somewhere in intel_lvds or in the pipe_config. Also given that no one ever really bothered to fix this up since gen5 (where the bit to change frequency moved around iirc) I don't think anyone will ever resurrect this. Hence the much more eager delete.
-Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 4/9] drm/i915: Nuke lvds downclock support
Quoted 17 lines · Daniel Vetter
Quoted 9 lines · Chris Wilson
Quoted 7 lines · Daniel Vetter
With the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
Quoted 6 lines
Can you nuke just the
intel_mark_busyside? Keeping the mode finder intact would be useful as the intrepid reader need only then implement theintel_frontbuffercallbacks and have the harder part of matching appropriate modes and switching routines ready to plug in. (Those latter ones I expect to be tweaked over time, and so the reader's first step of reverting this commit would conflict in such a way as to dissuade them.)
Quoted 6 lines
Well I was also somewhat annoyed by the dev_priv->lvds_* stuff and figured getting rid of that is good - it really should be stored somewhere in
intel_lvdsor in thepipe_config. Also given that no one ever really bothered to fix this up since gen5 (where the bit to change frequency moved around iirc) I don't think anyone will ever resurrect this. Hence the much more eager delete.
*shrug* we know that people do try to use it, I was just thinking of a way that we could make it easier for them to refresh the code. (Ideally, I would prefer that they wouldn't have to and the new framework provided the impetus needed to solidify LVDS reclocking. All that was lacking was the vblank task to do the reclocking on the refresh to hide any flicker on transition. That and so few manufacturers supplied dual-mode panels.) -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 4/9] drm/i915: Nuke lvds downclock support
Quoted 25 lines · Chris Wilson
Quoted 17 lines · Daniel Vetter
Quoted 9 lines · Chris Wilson
Quoted 7 lines · Daniel Vetter
With the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
Quoted 6 lines
Can you nuke just the
intel_mark_busyside? Keeping the mode finder intact would be useful as the intrepid reader need only then implement theintel_frontbuffercallbacks and have the harder part of matching appropriate modes and switching routines ready to plug in. (Those latter ones I expect to be tweaked over time, and so the reader's first step of reverting this commit would conflict in such a way as to dissuade them.)Quoted 6 lines
Well I was also somewhat annoyed by the dev_priv->lvds_* stuff and figured getting rid of that is good - it really should be stored somewhere in
intel_lvdsor in thepipe_config. Also given that no one ever really bothered to fix this up since gen5 (where the bit to change frequency moved around iirc) I don't think anyone will ever resurrect this. Hence the much more eager delete.
Quoted 6 lines
*shrug* we know that people do try to use it, I was just thinking of a way that we could make it easier for them to refresh the code. (Ideally, I would prefer that they wouldn't have to and the new framework provided the impetus needed to solidify LVDS reclocking. All that was lacking was the vblank task to do the reclocking on the refresh to hide any flicker on transition. That and so few manufacturers supplied dual-mode panels.)
Not sure users trying to use it is a good argument - they enthusiastically try it on gen5+ too (where we don't frob the right pipe bits to make the frequency switch) and on machines without lvds panels. I expect a dummy i915.save_me_some_power option would get enabled too ;-)
Btw for the vblank work I think the crucial bit is that we want seamless DRRS (which edp drrs checks in the vbt) and lvds drrs never did check that. At least that might explain why it flickered often badly.
Given that ack or nack?
-Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 4/9] drm/i915: Nuke lvds downclock support
Quoted 38 lines · Daniel Vetter
Quoted 25 lines · Chris Wilson
Quoted 17 lines · Daniel Vetter
Quoted 9 lines · Chris Wilson
Quoted 7 lines · Daniel Vetter
With the new DRRS code it kinda sticks out, and we never managed to get this to work well enough without causing issues. Time to wave goodbye.
I've decided to keep the logic for programming the reduced clocks intact, but everything else is gone. If anyone ever wants to resurrect this we need to redo it all anyway on top of the frontbuffer tracking.
Quoted 6 lines
Can you nuke just the
intel_mark_busyside? Keeping the mode finder intact would be useful as the intrepid reader need only then implement theintel_frontbuffercallbacks and have the harder part of matching appropriate modes and switching routines ready to plug in. (Those latter ones I expect to be tweaked over time, and so the reader's first step of reverting this commit would conflict in such a way as to dissuade them.)Quoted 6 lines
Well I was also somewhat annoyed by the dev_priv->lvds_* stuff and figured getting rid of that is good - it really should be stored somewhere in
intel_lvdsor in thepipe_config. Also given that no one ever really bothered to fix this up since gen5 (where the bit to change frequency moved around iirc) I don't think anyone will ever resurrect this. Hence the much more eager delete.Quoted 6 lines
*shrug* we know that people do try to use it, I was just thinking of a way that we could make it easier for them to refresh the code. (Ideally, I would prefer that they wouldn't have to and the new framework provided the impetus needed to solidify LVDS reclocking. All that was lacking was the vblank task to do the reclocking on the refresh to hide any flicker on transition. That and so few manufacturers supplied dual-mode panels.)
Not sure users trying to use it is a good argument - they enthusiastically try it on gen5+ too (where we don't frob the right pipe bits to make the frequency switch) and on machines without lvds panels. I expect a dummy i915.save_me_some_power option would get enabled too ;-)
Quoted 5 lines
Btw for the vblank work I think the crucial bit is that we want seamless DRRS (which edp drrs checks in the vbt) and lvds drrs never did check that. At least that might explain why it flickered often badly.
Given that ack or nack?
Given that it has been buggy forever, and removes some interloping code, ack.
I'm just disappointed.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 5/9 drm/i915: s/update/compute/ for gmch dpll register functions
In reply to Daniel VetterI was momentarily confused until I've double-checked that these functions really only compute state and don't update the hardware state. They once did that, but since Ander's rework of the dpll computation flow that's no longer the case.
Rename them to avoid further confusion.
Note that the ilk code already follows the compute_dpll naming scheme for computing the actual register value. DDI code goes with _calc_, but that is close enough.
--- drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-)
drivers/gpu/drm/i915/intel_display.c +20 -20
@@ -7233,8 +7233,8 @@ void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)intel_cpu_transcoder_set_m_n (crtc, dp_m_n, dp_m2_n2); } -static void vlv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void vlv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) {u32 dpll, dpll_md;
@@ -7347,8 +7347,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,mutex_unlock (&dev_priv->sb_lock); } -static void chv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void chv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) { pipe_config->dpll_hw_state.dpll =DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS |
@@ -7487,11 +7487,11 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, };if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, &pipe_config); +chv_compute_dpll (crtc, &pipe_config);chv_prepare_pll (crtc, &pipe_config);chv_enable_pll (crtc, &pipe_config); }else { -vlv_update_pll (crtc, &pipe_config); +vlv_compute_dpll (crtc, &pipe_config);vlv_prepare_pll (crtc, &pipe_config);vlv_enable_pll (crtc, &pipe_config); }
@@ -7513,10 +7513,10 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)vlv_disable_pll (to_i915 (dev), pipe); } -static void i9xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i9xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7590,10 +7590,10 @@ static void i9xx_update_pll(struct intel_crtc *crtc, } } -static void i8xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i8xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7887,15 +7887,15 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, }if (IS_GEN2 (dev)) { -i8xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i8xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }else if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, crtc_state); +chv_compute_dpll (crtc, crtc_state); }else if (IS_VALLEYVIEW (dev)) { -vlv_update_pll (crtc, crtc_state); +vlv_compute_dpll (crtc, crtc_state); }else { -i9xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i9xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }return 0 ;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 5/9] drm/i915: s/update/compute/ for gmch dpll register functions
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 10 lines
I was momentarily confused until I've double-checked that these functions really only compute state and don't update the hardware state. They once did that, but since Ander's rework of the dpll computation flow that's no longer the case.
Rename them to avoid further confusion.
Note that the ilk code already follows the
compute_dpllnaming scheme for computing the actual register value. DDI code goes with _calc_, but that is close enough.
My only bikeshed would be to point that we now have x_prepare_pll(), x_enable_pll() and x_compute_dpll(), with the "d" to break the standard. OTOH the ILK function also has the "d" letter, so meh...
Quoted 106 lines
Cc Ander Conselvan de Oliveira <[email protected]>Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-)drivers/gpu/drm/i915/intel_display.c +20
-21@@ -7233,8 +7233,8 @@ void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)intel_cpu_transcoder_set_m_n (crtc, dp_m_n, dp_m2_n2); } -static void vlv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void vlv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) {u32 dpll, dpll_md;@@ -7347,8 +7347,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,mutex_unlock (&dev_priv->sb_lock); } -static void chv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void chv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) { pipe_config->dpll_hw_state.dpll =DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS |@@ -7487,11 +7487,11 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, };if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, &pipe_config); +chv_compute_dpll (crtc, &pipe_config);chv_prepare_pll (crtc, &pipe_config);chv_enable_pll (crtc, &pipe_config); }else { -vlv_update_pll (crtc, &pipe_config); +vlv_compute_dpll (crtc, &pipe_config);vlv_prepare_pll (crtc, &pipe_config);vlv_enable_pll (crtc, &pipe_config); }@@ -7513,10 +7513,10 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)vlv_disable_pll (to_i915 (dev), pipe); } -static void i9xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i9xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;@@ -7590,10 +7590,10 @@ static void i9xx_update_pll(struct intel_crtc *crtc, } } -static void i8xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i8xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;@@ -7887,15 +7887,15 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, }if (IS_GEN2 (dev)) { -i8xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i8xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }else if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, crtc_state); +chv_compute_dpll (crtc, crtc_state); }else if (IS_VALLEYVIEW (dev)) { -vlv_update_pll (crtc, crtc_state); +vlv_compute_dpll (crtc, crtc_state); }else { -i9xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i9xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }return 0 ; --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 5/9] drm/i915: s/update/compute/ for gmch dpll register functions
Quoted 8 lines · Paulo Zanoni
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 7 lines
I was momentarily confused until I've double-checked that these functions really only compute state and don't update the hardware state. They once did that, but since Ander's rework of the dpll computation flow that's no longer the case.
Rename them to avoid further confusion.
Quoted 7 lines
Quoted 3 lines
Note that the ilk code already follows the
compute_dpllnaming scheme for computing the actual register value. DDI code goes with _calc_, but that is close enough.My only bikeshed would be to point that we now have
x_prepare_pll(),x_enable_pll()andx_compute_dpll(), with the "d" to break the standard. OTOH the ILK function also has the "d" letter, so meh...
Thanks for your review. I fixed up patch 1, pinged Chris again on the lvds drrs removal and merged all the others.
-Daniel
Quoted 114 lines
Reviewed-by Paulo Zanoni <[email protected]>Quoted 106 lines
Cc Ander Conselvan de Oliveira <[email protected]>Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-)drivers/gpu/drm/i915/intel_display.c +20
-21@@ -7233,8 +7233,8 @@ void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)intel_cpu_transcoder_set_m_n (crtc, dp_m_n, dp_m2_n2); } -static void vlv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void vlv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) {u32 dpll, dpll_md;@@ -7347,8 +7347,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,mutex_unlock (&dev_priv->sb_lock); } -static void chv_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *pipe_config) +static void chv_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *pipe_config) { pipe_config->dpll_hw_state.dpll =DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS |@@ -7487,11 +7487,11 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, };if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, &pipe_config); +chv_compute_dpll (crtc, &pipe_config);chv_prepare_pll (crtc, &pipe_config);chv_enable_pll (crtc, &pipe_config); }else { -vlv_update_pll (crtc, &pipe_config); +vlv_compute_dpll (crtc, &pipe_config);vlv_prepare_pll (crtc, &pipe_config);vlv_enable_pll (crtc, &pipe_config); }@@ -7513,10 +7513,10 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)vlv_disable_pll (to_i915 (dev), pipe); } -static void i9xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i9xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;@@ -7590,10 +7590,10 @@ static void i9xx_update_pll(struct intel_crtc *crtc, } } -static void i8xx_update_pll (struct intel_crtc *crtc, -struct intel_crtc_state *crtc_state, -intel_clock_t *reduced_clock, -int num_connectors) +static void i8xx_compute_dpll (struct intel_crtc *crtc, +struct intel_crtc_state *crtc_state, +intel_clock_t *reduced_clock, +int num_connectors) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private;@@ -7887,15 +7887,15 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, }if (IS_GEN2 (dev)) { -i8xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i8xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }else if (IS_CHERRYVIEW (dev)) { -chv_update_pll (crtc, crtc_state); +chv_compute_dpll (crtc, crtc_state); }else if (IS_VALLEYVIEW (dev)) { -vlv_update_pll (crtc, crtc_state); +vlv_compute_dpll (crtc, crtc_state); }else { -i9xx_update_pll (crtc, crtc_state,NULL , - num_connectors); +i9xx_compute_dpll (crtc, crtc_state,NULL , + num_connectors); }return 0 ; --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfxSignature · 1 line
Paulo Zanoni
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 6/9 drm/i915/drrs: Restrict buffer tracking to the DRRS pipe
In reply to Daniel VetterThe current code tracks business across all pipes, but we're only really interested in the one pipe DRRS is enabled on. Fairly tiny optimization, but something I noticed while reading the code. But it might matter a bit when e.g. showing a video or something only on the external screen, while the panel is kept static.
Also regroup the code slightly: First compute new bitmasks, then take appropriate actions.
--- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/intel_dp.c +7 -6
@@ -5485,16 +5485,15 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->drrs.dp)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); + dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; +/* invalidate means busy screen hence upclock */ -if (dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR ) { +if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR )intel_dp_set_drrs_state (dev_priv->dev, dev_priv->drrs.dp->attached_connector->panel. fixed_mode->vrefresh); - } - - frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); - dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;mutex_unlock (&dev_priv->drrs.mutex); }
@@ -5530,10 +5529,12 @@ void intel_edp_drrs_flush(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->drrs.dp)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;/* flush means busy screen hence upclock */ -if (dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR ) +if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR )intel_dp_set_drrs_state (dev_priv->dev, dev_priv->drrs.dp->attached_connector->panel. fixed_mode->vrefresh);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 6/9] drm/i915/drrs: Restrict buffer tracking to the DRRS pipe
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 6 lines
The current code tracks business across all pipes, but we're only really interested in the one pipe DRRS is enabled on. Fairly tiny optimization, but something I noticed while reading the code. But it might matter a bit when e.g. showing a video or something only on the external screen, while the panel is kept static.
Quoted 6 lines
Also regroup the code slightly: First compute new bitmasks, then take appropriate actions.
Cc Ramalingam C <[email protected]>Cc Sivakumar Thulasimani <[email protected]>Signed-off-by Daniel Vetter <[email protected]>
PS: with this, everything except P4 has a R-B tag (but P1 has a change request). I'll let you and Chris decide what to do on P4.
Quoted 50 lines
--- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)drivers/gpu/drm/i915/intel_dp.c +7
-7@@ -5485,16 +5485,15 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->drrs.dp)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); + dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; +/* invalidate means busy screen hence upclock */ -if (dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR ) { +if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR )intel_dp_set_drrs_state (dev_priv->dev, dev_priv->drrs.dp->attached_connector->panel. fixed_mode->vrefresh); - } - - frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); - dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;mutex_unlock (&dev_priv->drrs.mutex); }@@ -5530,10 +5529,12 @@ void intel_edp_drrs_flush(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->drrs.dp)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;/* flush means busy screen hence upclock */ -if (dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR ) +if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type ==DRRS_LOW_RR )intel_dp_set_drrs_state (dev_priv->dev, dev_priv->drrs.dp->attached_connector->panel. fixed_mode->vrefresh); --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 7/9 drm/i915/psr: Restrict buffer tracking to the PSR pipe
In reply to Daniel VetterThe current code tracks business across all pipes, but we're only really interested in the one pipe DRRS is enabled on. Fairly tiny optimization, but something I noticed while reading the code. But it might matter a bit when e.g. showing a video or something only on the external screen, while the panel is kept static.
Also regroup the code slightly: First compute new bitmasks, then take appropriate actions.
--- drivers/gpu/drm/i915/intel_psr.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/intel_psr.c +7 -4
@@ -663,11 +663,12 @@ void intel_psr_invalidate(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; -intel_psr_exit (dev); - frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); - dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; + +if (frontbuffer_bits) +intel_psr_exit (dev); +mutex_unlock (&dev_priv->psr.lock); }
@@ -698,6 +699,8 @@ void intel_psr_flush(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;/*
@@ -716,7 +719,7 @@ void intel_psr_flush(struct drm_device *dev,* invalidating. Which means we need to manually fake this in * software for all flushes, not just when we've seen a preceding * invalidation through frontbuffer rendering. */ -if (!HAS_DDI (dev)) +if (frontbuffer_bits && !HAS_DDI (dev))intel_psr_exit (dev);if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 7/9] drm/i915/psr: Restrict buffer tracking to the PSR pipe
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 2 lines
The current code tracks business across all pipes, but we're only really interested in the one pipe DRRS is enabled on. Fairly tiny
s/DRRS/PSR/
Quoted 6 lines
optimization, but something I noticed while reading the code. But it might matter a bit when e.g. showing a video or something only on the external screen, while the panel is kept static.
Also regroup the code slightly: First compute new bitmasks, then take appropriate actions.
One of the ideas I had last year was to implement a way to tell user space (possibly through debugs) when FBC/PSR gets enabled/disabled. My initial idea was to do this through timestamps. Our IGT suite would then verify those timestamps: if we have 2 pipes enabled, then we write on the non-FBC buffer, the FBC timestamps can't change. This type of test would catch exactly the bug you're solving here.
I even implemented this, and added support for it on kms_frontbuffer_tracking, but I ended never sending the Kernel patch to the list due to the possible slowness created by the constant timestamp generation. Maybe I should resurrect this and hide it under some debug kconfig option. I also considered maybe moving the implementation from timestamps debugfs file events, or maybe tracing code, or something else. Ideas and bikesheds are welcome here.
So I added some debug messages to the PSR code, then I ran:
sudo ./kms_frontbuffer_tracking --run-subtest psr-2p-scndscrn-pri-sfb-draw-mmap-cpu --step --step
And I kept watching dmesg as I stepped. Without the patch, I could see psr being disabled/enabled as we were writing on the secondary screen frontbuffer. With the patch, we stop calling intel_psr_exit()! So:
Quoted 53 lines
Cc Rodrigo Vivi <[email protected]>Cc Durgadoss R <[email protected]>Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/intel_psr.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)drivers/gpu/drm/i915/intel_psr.c +7
-5@@ -663,11 +663,12 @@ void intel_psr_invalidate(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; -intel_psr_exit (dev); - frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); - dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; + +if (frontbuffer_bits) +intel_psr_exit (dev); +mutex_unlock (&dev_priv->psr.lock); }@@ -698,6 +699,8 @@ void intel_psr_flush(struct drm_device *dev, crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; + + frontbuffer_bits &=INTEL_FRONTBUFFER_ALL_MASK (pipe); dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;/* @@ -716,7 +719,7 @@ void intel_psr_flush(struct drm_device *dev,* invalidating. Which means we need to manually fake this in * software for all flushes, not just when we've seen a preceding * invalidation through frontbuffer rendering. */ -if (!HAS_DDI (dev)) +if (frontbuffer_bits && !HAS_DDI (dev))intel_psr_exit (dev);if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 7/9] drm/i915/psr: Restrict buffer tracking to the PSR pipe
Quoted 28 lines · Paulo Zanoni
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 2 lines
The current code tracks business across all pipes, but we're only really interested in the one pipe DRRS is enabled on. Fairly tiny
s/DRRS/PSR/
Quoted 6 lines
optimization, but something I noticed while reading the code. But it might matter a bit when e.g. showing a video or something only on the external screen, while the panel is kept static.
Also regroup the code slightly: First compute new bitmasks, then take appropriate actions.
One of the ideas I had last year was to implement a way to tell user space (possibly through debugs) when FBC/PSR gets enabled/disabled. My initial idea was to do this through timestamps. Our IGT suite would then verify those timestamps: if we have 2 pipes enabled, then we write on the non-FBC buffer, the FBC timestamps can't change. This type of test would catch exactly the bug you're solving here.
I even implemented this, and added support for it on
kms_frontbuffer_tracking, but I ended never sending the Kernel patch to the list due to the possible slowness created by the constant timestamp generation. Maybe I should resurrect this and hide it under some debug kconfig option. I also considered maybe moving the implementation from timestamps debugfs file events, or maybe tracing code, or something else. Ideas and bikesheds are welcome here.
Quoted 7 lines
So I added some debug messages to the PSR code, then I ran:
sudo ./kms_frontbuffer_tracking --run-subtest psr-2p-scndscrn-pri-sfb-draw-mmap-cpu --step --stepAnd I kept watching dmesg as I stepped. Without the patch, I could see psr being disabled/enabled as we were writing on the secondary screen frontbuffer. With the patch, we stop calling
intel_psr_exit()! So:
I think there's two cases really: Adding tracepoints to watch the psr or frontbuffer code could certainly be useful.
For testcases otoh I'm not in favour of coupling them tightly with the current kernel implementation. If we only check behavior (like residency or captured CRCs) we can change the kernel implementation (like e.g. switch away from hw tracking or the other way round) without any changes to testcases. If we couple tests tightly with such tracepoints/timestamps then we might accidentally break the testcase while changing it.
And since upstream is really big about never breaking ABI (which means observable behaviour, not never changing how it's implemented) I think doing blackbox testcase is a big plus.
But if it's really not possibel to validate a feature without introspection then I'm ok with adding tracepoints/ts or similar things. -Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 8/9 drm/i915/psr: Restrict single-shot updates to the PSR pipe
In reply to Daniel VetterThe frontbuffer code gives us accurate information about activity, let's use it. Again this should avoid unecessary updates when multiple screens are on.
Also realing function paramaters, I couldn't resist that bit of OCD.
--- drivers/gpu/drm/i915/intel_drv.h | 7 ++++--- drivers/gpu/drm/i915/intel_frontbuffer.c | 2 +- drivers/gpu/drm/i915/intel_psr.c | 22 +++++++++++++--------- 3 files changed, 18 insertions(+), 13 deletions(-)
drivers/gpu/drm/i915/intel_drv.h +4 -3
@@ -1310,11 +1310,12 @@ void intel_backlight_unregister(struct drm_device *dev);void intel_psr_enable (struct intel_dp *intel_dp);void intel_psr_disable (struct intel_dp *intel_dp);void intel_psr_invalidate (struct drm_device *dev, -unsigned frontbuffer_bits); +unsigned frontbuffer_bits);void intel_psr_flush (struct drm_device *dev, -unsigned frontbuffer_bits); +unsigned frontbuffer_bits);void intel_psr_init (struct drm_device *dev); -void intel_psr_single_frame_update (struct drm_device *dev); +void intel_psr_single_frame_update (struct drm_device *dev, +unsigned frontbuffer_bits);/* intel_runtime_pm.c */ int intel_power_domains_init (struct drm_i915_private *);
drivers/gpu/drm/i915/intel_frontbuffer.c +1 -1
@@ -190,7 +190,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev, dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;mutex_unlock (&dev_priv->fb_tracking.lock); -intel_psr_single_frame_update (dev); +intel_psr_single_frame_update (dev, frontbuffer_bits); }/**
drivers/gpu/drm/i915/intel_psr.c +13 -9
@@ -596,13 +596,15 @@ static void intel_psr_exit(struct drm_device *dev)/** * intel_psr_single_frame_update - Single Frame Update * @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits * * Some platforms support a single frame update feature that is used to * send and update only one frame on Remote Frame Buffer. * So far it is only implemented for Valleyview and Cherryview because * hardware requires this to be done before a page flip. */ -void intel_psr_single_frame_update (struct drm_device *dev) +void intel_psr_single_frame_update (struct drm_device *dev, +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc;
@@ -624,14 +626,16 @@ void intel_psr_single_frame_update(struct drm_device *dev) crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; - val =I915_READ (VLV_PSRCTL (pipe)); -/* -* We need to set this bit before writing registers for a flip. -* This bit will be self-clear when it gets to the PSR active state. -*/ -I915_WRITE (VLV_PSRCTL (pipe), val |VLV_EDP_PSR_SINGLE_FRAME_UPDATE ); +if (frontbuffer_bits &INTEL_FRONTBUFFER_ALL_MASK (pipe)) { + val =I915_READ (VLV_PSRCTL (pipe)); +/* +* We need to set this bit before writing registers for a flip. +* This bit will be self-clear when it gets to the PSR active state. +*/ +I915_WRITE (VLV_PSRCTL (pipe), val |VLV_EDP_PSR_SINGLE_FRAME_UPDATE ); + }mutex_unlock (&dev_priv->psr.lock); }
@@ -648,7 +652,7 @@ void intel_psr_single_frame_update(struct drm_device *dev)* Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits." */ void intel_psr_invalidate (struct drm_device *dev, -unsigned frontbuffer_bits) +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc;
@@ -685,7 +689,7 @@ void intel_psr_invalidate(struct drm_device *dev,* Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits. */ void intel_psr_flush (struct drm_device *dev, -unsigned frontbuffer_bits) +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 8/9] drm/i915/psr: Restrict single-shot updates to the PSR pipe
Quoted 5 lines · Daniel Vetter
The frontbuffer code gives us accurate information about activity, let's use it. Again this should avoid unecessary updates when multiple screens are on.
Also realing function paramaters, I couldn't resist that bit of OCD.
realign. I ocd'ed your ocd.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 8/9] drm/i915/psr: Restrict single-shot updates to the PSR pipe
In reply to Daniel Vetter2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 5 lines
The frontbuffer code gives us accurate information about activity, let's use it. Again this should avoid unecessary updates when multiple screens are on.
Also realing function paramaters, I couldn't resist that bit of OCD.
Can't test this since -ENOHW. But it appears correct, so with and only with the fix mentioned by Chris:
This bug could also be verified by the idea I mentioned in my comment to patch 7, if it was implemented.
Or we can also verify it by adding some debugfs messages at the correct places of intel_psr_single_frame_update(), then run "sudo ./kms_frontbuffer_tracking --run-subtest psr-2p-scndscrn-sfb-flip-blt --step --step" and watch the PSR single frame updates messages appear on dmesg as we do flips on the non-PSR screen.
Quoted 112 lines
Cc Rodrigo Vivi <[email protected]>Cc Durgadoss R <[email protected]>Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/intel_drv.h | 7 ++++--- drivers/gpu/drm/i915/intel_frontbuffer.c | 2 +- drivers/gpu/drm/i915/intel_psr.c | 22 +++++++++++++--------- 3 files changed, 18 insertions(+), 13 deletions(-)drivers/gpu/drm/i915/intel_drv.h +4
-3@@ -1310,11 +1310,12 @@ void intel_backlight_unregister(struct drm_device *dev);void intel_psr_enable (struct intel_dp *intel_dp);void intel_psr_disable (struct intel_dp *intel_dp);void intel_psr_invalidate (struct drm_device *dev, -unsigned frontbuffer_bits); +unsigned frontbuffer_bits);void intel_psr_flush (struct drm_device *dev, -unsigned frontbuffer_bits); +unsigned frontbuffer_bits);void intel_psr_init (struct drm_device *dev); -void intel_psr_single_frame_update (struct drm_device *dev); +void intel_psr_single_frame_update (struct drm_device *dev, +unsigned frontbuffer_bits);/* intel_runtime_pm.c */ int intel_power_domains_init (struct drm_i915_private *);drivers/gpu/drm/i915/intel_frontbuffer.c +1
-1@@ -190,7 +190,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev, dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;mutex_unlock (&dev_priv->fb_tracking.lock); -intel_psr_single_frame_update (dev); +intel_psr_single_frame_update (dev, frontbuffer_bits); }/** drivers/gpu/drm/i915/intel_psr.c +13
-10@@ -596,13 +596,15 @@ static void intel_psr_exit(struct drm_device *dev)/** * intel_psr_single_frame_update - Single Frame Update * @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits * * Some platforms support a single frame update feature that is used to * send and update only one frame on Remote Frame Buffer. * So far it is only implemented for Valleyview and Cherryview because * hardware requires this to be done before a page flip. */ -void intel_psr_single_frame_update (struct drm_device *dev) +void intel_psr_single_frame_update (struct drm_device *dev, +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc;@@ -624,14 +626,16 @@ void intel_psr_single_frame_update(struct drm_device *dev) crtc =dp_to_dig_port (dev_priv->psr.enabled)->base.base.crtc; pipe =to_intel_crtc (crtc)->pipe; - val =I915_READ (VLV_PSRCTL (pipe)); -/* -* We need to set this bit before writing registers for a flip. -* This bit will be self-clear when it gets to the PSR active state. -*/ -I915_WRITE (VLV_PSRCTL (pipe), val |VLV_EDP_PSR_SINGLE_FRAME_UPDATE ); +if (frontbuffer_bits &INTEL_FRONTBUFFER_ALL_MASK (pipe)) { + val =I915_READ (VLV_PSRCTL (pipe)); +/* +* We need to set this bit before writing registers for a flip. +* This bit will be self-clear when it gets to the PSR active state. +*/ +I915_WRITE (VLV_PSRCTL (pipe), val |VLV_EDP_PSR_SINGLE_FRAME_UPDATE ); + }mutex_unlock (&dev_priv->psr.lock); }@@ -648,7 +652,7 @@ void intel_psr_single_frame_update(struct drm_device *dev)* Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits." */ void intel_psr_invalidate (struct drm_device *dev, -unsigned frontbuffer_bits) +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc;@@ -685,7 +689,7 @@ void intel_psr_invalidate(struct drm_device *dev,* Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits. */ void intel_psr_flush (struct drm_device *dev, -unsigned frontbuffer_bits) +unsigned frontbuffer_bits) {struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc; --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 9/9 drm/i915: Use to_i915 in intel_frontbuffer.c
In reply to Daniel VetterMust have missed the transition.
--- drivers/gpu/drm/i915/intel_frontbuffer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/intel_frontbuffer.c +6 -6
@@ -82,7 +82,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, enum fb_op_origin origin) {struct drm_device *dev = obj->base.dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);WARN_ON (!mutex_is_locked (&dev->struct_mutex));
@@ -117,7 +117,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);/* Delay flushing when rings are still busy.*/ mutex_lock (&dev_priv->fb_tracking.lock);
@@ -145,7 +145,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire) {struct drm_device *dev = obj->base.dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);unsigned frontbuffer_bits;WARN_ON (!mutex_is_locked (&dev->struct_mutex));
@@ -182,7 +182,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj,void intel_frontbuffer_flip_prepare (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock); dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
@@ -206,7 +206,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,void intel_frontbuffer_flip_complete (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock);/* Mask any cancelled flips. */
@@ -232,7 +232,7 @@ inlinevoid intel_frontbuffer_flip (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock); dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 9/9] drm/i915: Use to_i915 in intel_frontbuffer.c
2015-06-18 5:30 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 1 line
Must have missed the transition.
Quoted 71 lines
Signed-off-by Daniel Vetter <[email protected]>--- drivers/gpu/drm/i915/intel_frontbuffer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)drivers/gpu/drm/i915/intel_frontbuffer.c +6
-7@@ -82,7 +82,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, enum fb_op_origin origin) {struct drm_device *dev = obj->base.dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);WARN_ON (!mutex_is_locked (&dev->struct_mutex));@@ -117,7 +117,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);/* Delay flushing when rings are still busy.*/ mutex_lock (&dev_priv->fb_tracking.lock);@@ -145,7 +145,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire) {struct drm_device *dev = obj->base.dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);unsigned frontbuffer_bits;WARN_ON (!mutex_is_locked (&dev->struct_mutex));@@ -182,7 +182,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj,void intel_frontbuffer_flip_prepare (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock); dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;@@ -206,7 +206,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,void intel_frontbuffer_flip_complete (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock);/* Mask any cancelled flips. */ @@ -232,7 +232,7 @@ inlinevoid intel_frontbuffer_flip (struct drm_device *dev,unsigned frontbuffer_bits) { -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_i915_private *dev_priv =to_i915 (dev);mutex_lock (&dev_priv->fb_tracking.lock); dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; --2.1.0
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 34 lines · Daniel Vetter
The current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the
flip_prepareandflip_completefunctions) already does this, but somehow I've forgotten to do this for synchronous flips.Note that we don't track outstanding rendering of the new framebuffer with
busy_bitssince all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.Reported-by Paulo Zanoni <[email protected]>Cc Paulo Zanoni <[email protected]>Signed-off-by Daniel Vetter <[email protected]>---
Paulo promised to also extendkms_frontbuffer_trackingwith flip vs. busy buffer tests.--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/intel_drv.h +0
-3@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device
drivers/gpu/drm/i915/intel_drv.h void intel_frontbuffer_flip_complete(struct drm_device *dev, · line 966
Quoted 10 lines
drivers/gpu/drm/i915/intel_drv.h +1
-9-* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will -* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inline
inline?
Quoted 50 lines
drivers/gpu/drm/i915/intel_drv.h +1
-4void intel_frontbuffer_flip (struct drm_device *dev, -unsigned frontbuffer_bits) -{ -intel_frontbuffer_flush (dev, frontbuffer_bits); -} +unsigned frontbuffer_bits); unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height,drivers/gpu/drm/i915/intel_frontbuffer.c +26
-0@@ -270,3 +270,29 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev,intel_frontbuffer_flush (dev, frontbuffer_bits); } + +/** +* intel_frontbuffer_flip - synchronous frontbuffer flip +* @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits +* +* This function gets called after scheduling a flip on @obj. This is for +* synchronous plane updates which will happen on the next vblank and which will +* not get delayed by pending gpu rendering. +* +* Can be called without any locks held. +*/ +inline +void intel_frontbuffer_flip (struct drm_device *dev, +unsigned frontbuffer_bits) +{ +struct drm_i915_private *dev_priv = dev->dev_private; + +mutex_lock (&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; +/* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; +mutex_unlock (&dev_priv->fb_tracking.lock); + +intel_frontbuffer_flush (dev, frontbuffer_bits); +}Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 39 lines · Ville Syrjälä
Quoted 38 lines · Daniel Vetter
The current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the
flip_prepareandflip_completefunctions) already does this, but somehow I've forgotten to do this for synchronous flips.Note that we don't track outstanding rendering of the new framebuffer with
busy_bitssince all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.Reported-by Paulo Zanoni <[email protected]>Cc Paulo Zanoni <[email protected]>Signed-off-by Daniel Vetter <[email protected]>---
Paulo promised to also extendkms_frontbuffer_trackingwith flip vs. busy buffer tests.--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/intel_drv.h +0
-7@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device -* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will
Quoted 8 lines
drivers/gpu/drm/i915/intel_drv.h void intel_frontbuffer_flip_complete(struct drm_device *dev, · line 966
Quoted 6 lines
drivers/gpu/drm/i915/intel_drv.h +1
-5-* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inlineinline?
Daniel's probably looked at a perf profile and felt guilty. :)
Hijacking the thread purely to promote
http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=nightly&id=fe05042a9dda46f4bdd9e40612bf48befaee1ad3
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 1/1 drm/i915: Clear fb_tracking.busy_bits also for synchronous flips
In reply to Ville SyrjäläThe current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the flip_prepare and flip_complete functions) already does this, but somehow I've forgotten to do this for synchronous flips.
Note that we don't track outstanding rendering of the new framebuffer with busy_bits since all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.
v2: Drop the spurious inline Ville spotted.
---
Paulo promised to also extend kms_frontbuffer_tracking with flip vs. busy buffer tests.
--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)
drivers/gpu/drm/i915/intel_drv.h +2 -16
@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device -* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will -* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inline void intel_frontbuffer_flip (struct drm_device *dev, -unsigned frontbuffer_bits) -{ -intel_frontbuffer_flush (dev, frontbuffer_bits); -} +unsigned frontbuffer_bits); unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height,
drivers/gpu/drm/i915/intel_frontbuffer.c +26 -0
@@ -270,3 +270,29 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev,intel_frontbuffer_flush (dev, frontbuffer_bits); } + +/** +* intel_frontbuffer_flip - synchronous frontbuffer flip +* @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits +* +* This function gets called after scheduling a flip on @obj. This is for +* synchronous plane updates which will happen on the next vblank and which will +* not get delayed by pending gpu rendering. +* +* Can be called without any locks held. +*/ + +void intel_frontbuffer_flip (struct drm_device *dev, +unsigned frontbuffer_bits) +{ +struct drm_i915_private *dev_priv = dev->dev_private; + +mutex_lock (&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; +/* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; +mutex_unlock (&dev_priv->fb_tracking.lock); + +intel_frontbuffer_flush (dev, frontbuffer_bits); +}
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
2015-06-18 6:23 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 11 lines
The current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the
flip_prepareandflip_completefunctions) already does this, but somehow I've forgotten to do this for synchronous flips.Note that we don't track outstanding rendering of the new framebuffer with
busy_bitssince all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.
Steps to reproduce:
- Boot your machine to the display manager
- Kill it, returning to fbcon
- Try to run any subtest from igt/tests/kms_frontbuffer_tracking: they all fail because FBC never gets enabled
- Do any blt/render operation to the frontbuffer
- Now the tests will succeed
I also submitted a new test for this, that doesn't require the steps above, so we can also add:
Testcase: igt/kms_frontbuffer_tracking/fbc-modesetfrombusy
More below:
Quoted 63 lines
v2: Drop the spurious inline Ville spotted.
Reported-by Paulo Zanoni <[email protected]>Cc Paulo Zanoni <[email protected]>Cc Ville Syrjälä <[email protected]>Signed-off-by Daniel Vetter <[email protected]>---
Paulo promised to also extendkms_frontbuffer_trackingwith flip vs. busy buffer tests.--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/intel_drv.h +2
-16@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device -* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will -* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inline void intel_frontbuffer_flip (struct drm_device *dev, -unsigned frontbuffer_bits) -{ -intel_frontbuffer_flush (dev, frontbuffer_bits); -} +unsigned frontbuffer_bits); unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height,drivers/gpu/drm/i915/intel_frontbuffer.c +10
-0@@ -270,3 +270,29 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev,intel_frontbuffer_flush (dev, frontbuffer_bits); } + +/** +* intel_frontbuffer_flip - synchronous frontbuffer flip +* @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits +* +* This function gets called after scheduling a flip on @obj. This is for +* synchronous plane updates which will happen on the next vblank and which will +* not get delayed by pending gpu rendering. +*
drivers/gpu/drm/i915/intel_frontbuffer.c void intel_frontbuffer_flip_complete(struct drm_device *dev, · line 292
Quoted 10 lines
drivers/gpu/drm/i915/intel_frontbuffer.c +10
-0+* Can be called without any locks held. +*/ + +void intel_frontbuffer_flip (struct drm_device *dev, +unsigned frontbuffer_bits) +{ +struct drm_i915_private *dev_priv = dev->dev_private; + +mutex_lock (&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;
I don't understand the purpose of the line above. Is this really necessary? It seems that flip_bits is only necessary for the asynchronous flip case, where someone schedules a flip then draws on the buffer, so we don't flush the buffer at flip_complete. We do unconditional flush at intel_frontbuffer_flip(), so it seems like we shouldn't be touching flip_bits here.
I tested both this version and the version without the flip_bits change, and both appear to solve the problem I can reproduce, so for both:
And, with the flip_bits problem explained or fixed:
Quoted 9 lines
drivers/gpu/drm/i915/intel_frontbuffer.c +6
-1+/* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; +mutex_unlock (&dev_priv->fb_tracking.lock); + +intel_frontbuffer_flush (dev, frontbuffer_bits); +} --2.1.0
Signature · 5 lines
Paulo Zanoni _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 99 lines · Paulo Zanoni
2015-06-18 6:23 GMT-03:00 Daniel Vetter <[email protected]>:
Quoted 11 lines
The current/old frontbuffer might still have gpu frontbuffer rendering pending. But once flipped it won't have the corresponding frontbuffer bits any more and hence the request retire function won't ever clear the corresponding busy bits. The async flip tracking (with the
flip_prepareandflip_completefunctions) already does this, but somehow I've forgotten to do this for synchronous flips.Note that we don't track outstanding rendering of the new framebuffer with
busy_bitssince all our plane update code waits for previous rendering to complete before displaying a new buffer. Hence a new buffer will never be busy.Steps to reproduce:
- Boot your machine to the display manager
- Kill it, returning to fbcon
- Try to run any subtest from igt/tests/kms_frontbuffer_tracking: they all fail because FBC never gets enabled
- Do any blt/render operation to the frontbuffer
- Now the tests will succeedI also submitted a new test for this, that doesn't require the steps above, so we can also add:
Testcase: igt/kms_frontbuffer_tracking/fbc-modesetfrombusyMore below:
Quoted 72 lines
v2: Drop the spurious inline Ville spotted.
Reported-by Paulo Zanoni <[email protected]>Cc Paulo Zanoni <[email protected]>Cc Ville Syrjälä <[email protected]>Signed-off-by Daniel Vetter <[email protected]>---
Paulo promised to also extendkms_frontbuffer_trackingwith flip vs. busy buffer tests.--- drivers/gpu/drm/i915/intel_drv.h | 18 ++---------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/intel_drv.h +2
-16@@ -963,23 +963,9 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, unsigned frontbuffer_bits);void intel_frontbuffer_flush (struct drm_device *dev,unsigned frontbuffer_bits); -/** -* intel_frontbuffer_flip - synchronous frontbuffer flip -* @dev: DRM device -* @frontbuffer_bits: frontbuffer plane tracking bits -* -* This function gets called after scheduling a flip on @obj. This is for -* synchronous plane updates which will happen on the next vblank and which will -* not get delayed by pending gpu rendering. -* -* Can be called without any locks held. -*/ -static inline +inline void intel_frontbuffer_flip (struct drm_device *dev, -unsigned frontbuffer_bits) -{ -intel_frontbuffer_flush (dev, frontbuffer_bits); -} +unsigned frontbuffer_bits); unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height,drivers/gpu/drm/i915/intel_frontbuffer.c +19
-0@@ -270,3 +270,29 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev,intel_frontbuffer_flush (dev, frontbuffer_bits); } + +/** +* intel_frontbuffer_flip - synchronous frontbuffer flip +* @dev: DRM device +* @frontbuffer_bits: frontbuffer plane tracking bits +* +* This function gets called after scheduling a flip on @obj. This is for +* synchronous plane updates which will happen on the next vblank and which will +* not get delayed by pending gpu rendering. +* +* Can be called without any locks held. +*/ + +void intel_frontbuffer_flip (struct drm_device *dev, +unsigned frontbuffer_bits) +{ +struct drm_i915_private *dev_priv = dev->dev_private; + +mutex_lock (&dev_priv->fb_tracking.lock);
Quoted 8 lines
drivers/gpu/drm/i915/intel_frontbuffer.c void intel_frontbuffer_flip_complete(struct drm_device *dev, · line 292
Quoted 1 line
drivers/gpu/drm/i915/intel_frontbuffer.c +1
-0+ dev_priv->fb_tracking.flip_bits |= frontbuffer_bits;I don't understand the purpose of the line above. Is this really necessary? It seems that
flip_bitsis only necessary for the asynchronous flip case, where someone schedules a flip then draws on the buffer, so we don't flush the buffer atflip_complete. We do unconditional flush atintel_frontbuffer_flip(), so it seems like we shouldn't be touchingflip_bitshere.
Indeed this was bogus, but luckily it was harmless (keeping track of an async flip that will never happen isn't a problem) so either version worked. But I removed it when merging the patch, thanks for spotting this. -Daniel
Quoted 23 lines
I tested both this version and the version without the
flip_bitschange, and both appear to solve the problem I can reproduce, so for both:Tested-by Paulo Zanoni <[email protected]>And, with the
flip_bitsproblem explained or fixed:Reviewed-by Paulo Zanoni <[email protected]>Quoted 9 lines
drivers/gpu/drm/i915/intel_frontbuffer.c +6
-1+/* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; +mutex_unlock (&dev_priv->fb_tracking.lock); + +intel_frontbuffer_flush (dev, frontbuffer_bits); +} --2.1.0
Signature · 1 line
Paulo Zanoni
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 1/1 tests/kms_frontbuffer_tracking: add modesetfrombusy test
In reply to Daniel VetterFrom: Paulo Zanoni <[email protected]>
This test exercies the dev_priv->fb_tracking.busy_bits bug I recently found and Daniel fixed.
--- tests/kms_frontbuffer_tracking.c | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+)
tests/kms_frontbuffer_tracking.c +113 -0
@@ -27,6 +27,7 @@#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <pthread.h> #include "drmtest.h" #include "igt_aux.h"
@@ -259,6 +260,19 @@ struct {struct igt_fb big; } fbs; +struct { +pthread_t thread; +bool stop; + +uint32_t handle; +uint32_t size; +uint32_t stride; +int width; +int height; +} busy_thread = { + .stop = true, +}; +static drmModeModeInfoPtr get_connector_smallest_mode (drmModeConnectorPtr c) {int i;
@@ -876,6 +890,41 @@ static void disable_features(void)psr_disable (); } +static void *busy_thread_func (void *data) +{ +while (!busy_thread.stop) +igt_draw_rect (drm.fd, drm.bufmgr,NULL , busy_thread.handle, + busy_thread.size, busy_thread.stride, +IGT_DRAW_BLT ,0 ,0 , busy_thread.width, + busy_thread.height,0xFF ); + +pthread_exit (0 ); +} + +static void start_busy_thread (struct igt_fb *fb) +{ +int rc; + +igt_assert (busy_thread.stop == true); + busy_thread.stop = false; + busy_thread.handle = fb->gem_handle; + busy_thread.size = fb->size; + busy_thread.stride = fb->stride; + busy_thread.width = fb->width; + busy_thread.height = fb->height; + + rc =pthread_create (&busy_thread.thread,NULL , busy_thread_func,NULL ); +igt_assert (rc ==0 ); +} + +static void stop_busy_thread (void ) +{ +if (!busy_thread.stop) { + busy_thread.stop = true; +igt_assert (pthread_join (busy_thread.thread,NULL ) ==0 ); + } +} +static void print_crc (const char *str,struct both_crcs *crc) {int i;
@@ -1199,6 +1248,8 @@ static void setup_environment(void)static void teardown_environment (void ) { +stop_busy_thread (); +teardown_crcs ();teardown_psr ();teardown_fbc ();
@@ -1481,6 +1532,8 @@ static void prepare_subtest(const struct test_mode *t, {check_test_requirements (t); +stop_busy_thread (); +disable_features ();set_crtc_fbs (t);
@@ -1964,6 +2017,50 @@ static void fullscreen_plane_subtest(const struct test_mode *t)igt_remove_fb (drm.fd, &fullscreen_fb); } +/** +* modesetfrombusy - modeset from a busy buffer to a non-busy buffer +* +* METHOD +* Set a mode, make the frontbuffer busy using BLT writes, do a modeset to a +* non-busy buffer, then check if the features are enabled. The goal of this +* test is to exercise a bug we had on the frontbuffer tracking infrastructure +* code. +* +* EXPECTED RESULTS +* No assertions fail. +* +* FAILURES +* If you're failing this test, then you probably need "drm/i915: Clear +* fb_tracking.busy_bits also for synchronous flips" or any other patch that +* properly updates dev_priv->fb_tracking.busy_bits when we're alternating +* between buffers with different busyness. +*/ +static void modesetfrombusy_subtest (const struct test_mode *t) +{ +struct draw_pattern_info *pattern = &pattern1; +struct modeset_params *params =pick_params (t); +struct igt_fb fb2; + +prepare_subtest (t, pattern); + +igt_create_fb (drm.fd, params->fb.fb->width, params->fb.fb->height, +DRM_FORMAT_XRGB8888 ,LOCAL_I915_FORMAT_MOD_X_TILED , &fb2); +igt_draw_fill_fb (drm.fd, &fb2,0xFF ); + +start_busy_thread (params->fb.fb); +usleep (10000 ); + +unset_all_crtcs (); + params->fb.fb = &fb2; +set_mode_for_params (params); + +do_assertions (0 ); + +stop_busy_thread (); + +igt_remove_fb (drm.fd, &fb2); +} +static int opt_handler (int option,int option_index,void *data) {switch (option) {
@@ -2248,6 +2345,22 @@ int main(int argc, char *argv[])multidraw_subtest (&t); TEST_MODE_ITER_END + TEST_MODE_ITER_BEGIN(t) + if (t.pipes != PIPE_SINGLE) + continue; + if (t.screen != SCREEN_PRIM) + continue; + if (t.plane != PLANE_PRI) + continue; + if (t.fbs != FBS_SINGLE) + continue; + if (t.method != IGT_DRAW_MMAP_CPU) + continue; + + igt_subtest_f("%s-modesetfrombusy", feature_str(t.feature)) +modesetfrombusy_subtest (&t); +TEST_MODE_ITER_END +/* * TODO: ideas for subtests: * - Add a new enum to struct test_mode that allows us to specify the
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx