Commit 51cbaf01 authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/i915: Unify unpin_work and mmio_work into flip_work, v2.

Rename intel_unpin_work to intel_flip_work and use it for mmio flips
and unpinning. Use flip_queued_req to hold the wait request in the
mmio case, and the vblank counter from intel_crtc_get_vblank_counter.

MMIO flips get their own path through intel_finish_page_flip_mmio,
handled on vblank. CS page flips go through *_cs.

Changes since v1:
- Clean up destinction between MMIO and CS flips.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463490484-19540-7-git-send-email-maarten.lankhorst@linux.intel.comReviewed-by: default avatarPatrik Jakobsson <patrik.jakobsson@linux.intel.com>
parent a2991414
......@@ -607,10 +607,10 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
for_each_intel_crtc(dev, crtc) {
const char pipe = pipe_name(crtc->pipe);
const char plane = plane_name(crtc->plane);
struct intel_unpin_work *work;
struct intel_flip_work *work;
spin_lock_irq(&dev->event_lock);
work = crtc->unpin_work;
work = crtc->flip_work;
if (work == NULL) {
seq_printf(m, "No flip due on pipe %c (plane %c)\n",
pipe, plane);
......@@ -640,7 +640,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
work->flip_queued_vblank,
work->flip_ready_vblank,
drm_crtc_vblank_count(&crtc->base));
intel_crtc_get_vblank_counter(crtc));
seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
if (INTEL_INFO(dev)->gen >= 4)
......
......@@ -1634,7 +1634,13 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
return drm_handle_vblank(dev_priv->dev, pipe);
bool ret;
ret = drm_handle_vblank(dev_priv->dev, pipe);
if (ret)
intel_finish_page_flip_mmio(dev_priv, pipe);
return ret;
}
static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
......@@ -1706,7 +1712,7 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
intel_check_page_flip(dev_priv, pipe);
if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
......@@ -2161,7 +2167,7 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
/* plane/pipes map 1:1 on ilk+ */
if (de_iir & DE_PLANE_FLIP_DONE(pipe))
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
}
/* check event from PCH */
......@@ -2206,7 +2212,7 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
/* plane/pipes map 1:1 on ilk+ */
if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
}
/* check event from PCH */
......@@ -2412,7 +2418,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
if (flip_done)
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
hsw_pipe_crc_irq_handler(dev_priv, pipe);
......@@ -3990,7 +3996,7 @@ static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
if (I915_READ16(ISR) & flip_pending)
goto check_page_flip;
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
return true;
check_page_flip:
......@@ -4179,7 +4185,7 @@ static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
if (I915_READ(ISR) & flip_pending)
goto check_page_flip;
intel_finish_page_flip(dev_priv, pipe);
intel_finish_page_flip_cs(dev_priv, pipe);
return true;
check_page_flip:
......
This diff is collapsed.
......@@ -627,14 +627,6 @@ struct vlv_wm_state {
bool cxsr;
};
struct intel_mmio_flip {
struct work_struct work;
struct drm_i915_private *i915;
struct drm_i915_gem_request *req;
struct intel_crtc *crtc;
unsigned int rotation;
};
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
......@@ -649,7 +641,7 @@ struct intel_crtc {
unsigned long enabled_power_domains;
bool lowfreq_avail;
struct intel_overlay *overlay;
struct intel_unpin_work *unpin_work;
struct intel_flip_work *flip_work;
atomic_t unpin_work_count;
......@@ -977,8 +969,10 @@ intel_get_crtc_for_plane(struct drm_device *dev, int plane)
return dev_priv->plane_to_crtc_mapping[plane];
}
struct intel_unpin_work {
struct work_struct work;
struct intel_flip_work {
struct work_struct unpin_work;
struct work_struct mmio_work;
struct drm_crtc *crtc;
struct drm_framebuffer *old_fb;
struct drm_i915_gem_object *pending_flip_obj;
......@@ -989,6 +983,7 @@ struct intel_unpin_work {
struct drm_i915_gem_request *flip_queued_req;
u32 flip_queued_vblank;
u32 flip_ready_vblank;
unsigned int rotation;
};
struct intel_load_detect_pipe {
......@@ -1199,7 +1194,8 @@ struct drm_framebuffer *
__intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj);
void intel_finish_page_flip(struct drm_i915_private *dev_priv, int pipe);
void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
int intel_prepare_plane_fb(struct drm_plane *plane,
const struct drm_plane_state *new_state);
......@@ -1677,7 +1673,7 @@ int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc);
void intel_pipe_update_end(struct intel_crtc *crtc);
void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
/* intel_tv.c */
void intel_tv_init(struct drm_device *dev);
......
......@@ -151,13 +151,19 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
* re-enables interrupts and verifies the update was actually completed
* before a vblank using the value of @start_vbl_count.
*/
void intel_pipe_update_end(struct intel_crtc *crtc)
void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
{
enum pipe pipe = crtc->pipe;
int scanline_end = intel_get_crtc_scanline(crtc);
u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
ktime_t end_vbl_time = ktime_get();
if (work) {
work->flip_queued_vblank = end_vbl_count;
smp_mb__before_atomic();
atomic_set(&work->pending, 1);
}
trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
local_irq_enable();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment