362 lines
14 KiB
Diff
362 lines
14 KiB
Diff
From 9d8a694efd245aee5d63ad415859a96011bec889 Mon Sep 17 00:00:00 2001
|
|
From: Vivek Kasireddy <vivek.kasireddy@intel.com>
|
|
Date: Thu, 8 Mar 2018 15:10:34 -0800
|
|
Subject: [PATCH 519/550] INTERNAL [IOTG] drm/i915: Decouple pipe and crtc
|
|
index dependencies
|
|
|
|
i915 driver had assumptions that pipe and the crtc index always
|
|
matched, but with plane restrictions feature, this assuumption is no
|
|
longer true.
|
|
In virualized environment guest Oses may have pipes with no planes
|
|
attached and no crtc should be created for that pipe (but for
|
|
service OS, CRTC still needs to be created to do the initial modeset).
|
|
In cases were no CRTC was created for some pipes, the index and pipe
|
|
won't
|
|
match and was causing issues. These changes are to decouple the pipe and
|
|
index dependencies in the driver.
|
|
|
|
v2(ssingh) : Ported this patch to 4.19 kernel.
|
|
|
|
Signed-off-by: Satyeshwar Singh <satyeshwar.singh@intel.com>
|
|
Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus@intel.com>
|
|
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
|
|
Change-Id: Iccf6b54c254e2b3d7053620c1b64ad8dda7632b8
|
|
---
|
|
drivers/gpu/drm/i915/i915_drv.h | 10 +++---
|
|
drivers/gpu/drm/i915/i915_irq.c | 32 ++++++++++++-----
|
|
drivers/gpu/drm/i915/i915_trace.h | 2 +-
|
|
drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++----
|
|
drivers/gpu/drm/i915/intel_dpll_mgr.c | 5 +--
|
|
drivers/gpu/drm/i915/intel_drv.h | 10 +++++-
|
|
drivers/gpu/drm/i915/intel_fifo_underrun.c | 11 ++++--
|
|
drivers/gpu/drm/i915/intel_pm.c | 7 ++--
|
|
8 files changed, 87 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
|
|
index 18650bc9c8e4..e477f8a0764f 100644
|
|
--- a/drivers/gpu/drm/i915/i915_drv.h
|
|
+++ b/drivers/gpu/drm/i915/i915_drv.h
|
|
@@ -2822,18 +2822,18 @@ ilk_disable_display_irq(struct drm_i915_private *dev_priv, uint32_t bits)
|
|
ilk_update_display_irq(dev_priv, bits, 0);
|
|
}
|
|
void bdw_update_pipe_irq(struct drm_i915_private *dev_priv,
|
|
- enum pipe pipe,
|
|
+ unsigned int crtc_index,
|
|
uint32_t interrupt_mask,
|
|
uint32_t enabled_irq_mask);
|
|
static inline void bdw_enable_pipe_irq(struct drm_i915_private *dev_priv,
|
|
- enum pipe pipe, uint32_t bits)
|
|
+ unsigned int crtc_index, uint32_t bits)
|
|
{
|
|
- bdw_update_pipe_irq(dev_priv, pipe, bits, bits);
|
|
+ bdw_update_pipe_irq(dev_priv, crtc_index, bits, bits);
|
|
}
|
|
static inline void bdw_disable_pipe_irq(struct drm_i915_private *dev_priv,
|
|
- enum pipe pipe, uint32_t bits)
|
|
+ unsigned int crtc_index, uint32_t bits)
|
|
{
|
|
- bdw_update_pipe_irq(dev_priv, pipe, bits, 0);
|
|
+ bdw_update_pipe_irq(dev_priv, crtc_index, bits, 0);
|
|
}
|
|
void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
|
|
uint32_t interrupt_mask,
|
|
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
|
|
index 71977fb8725c..5e0e9f189418 100644
|
|
--- a/drivers/gpu/drm/i915/i915_irq.c
|
|
+++ b/drivers/gpu/drm/i915/i915_irq.c
|
|
@@ -626,11 +626,12 @@ static void bdw_update_port_irq(struct drm_i915_private *dev_priv,
|
|
* @enabled_irq_mask: mask of interrupt bits to enable
|
|
*/
|
|
void bdw_update_pipe_irq(struct drm_i915_private *dev_priv,
|
|
- enum pipe pipe,
|
|
+ unsigned int crtc_index,
|
|
uint32_t interrupt_mask,
|
|
uint32_t enabled_irq_mask)
|
|
{
|
|
uint32_t new_val;
|
|
+ enum pipe pipe;
|
|
|
|
lockdep_assert_held(&dev_priv->irq_lock);
|
|
|
|
@@ -639,6 +640,9 @@ void bdw_update_pipe_irq(struct drm_i915_private *dev_priv,
|
|
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
|
|
return;
|
|
|
|
+ if(get_pipe_from_crtc_index(&dev_priv->drm, crtc_index, &pipe))
|
|
+ return;
|
|
+
|
|
new_val = dev_priv->de_irq_mask[pipe];
|
|
new_val &= ~interrupt_mask;
|
|
new_val |= (~enabled_irq_mask & interrupt_mask);
|
|
@@ -884,9 +888,14 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
|
|
return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff;
|
|
}
|
|
|
|
-static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
|
|
+static u32 g4x_get_vblank_counter(struct drm_device *dev,
|
|
+ unsigned int crtc_index)
|
|
{
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
+ enum pipe pipe;
|
|
+
|
|
+ if(get_pipe_from_crtc_index(dev, crtc_index, &pipe))
|
|
+ return 0;
|
|
|
|
return I915_READ(PIPE_FRMCOUNT_G4X(pipe));
|
|
}
|
|
@@ -1002,18 +1011,21 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
|
|
return (position + crtc->scanline_offset) % vtotal;
|
|
}
|
|
|
|
-static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
|
|
- bool in_vblank_irq, int *vpos, int *hpos,
|
|
- ktime_t *stime, ktime_t *etime,
|
|
- const struct drm_display_mode *mode)
|
|
+static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc_index,
|
|
+ bool in_vblank_irq, int *vpos, int *hpos,
|
|
+ ktime_t *stime, ktime_t *etime,
|
|
+ const struct drm_display_mode *mode)
|
|
{
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
- struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv,
|
|
- pipe);
|
|
+ struct intel_crtc *intel_crtc;
|
|
+ enum pipe pipe;
|
|
int position;
|
|
int vbl_start, vbl_end, hsync_start, htotal, vtotal;
|
|
unsigned long irqflags;
|
|
|
|
+ intel_crtc = get_intel_crtc_from_index(dev, crtc_index);
|
|
+ pipe = intel_crtc->pipe;
|
|
+
|
|
if (WARN_ON(!mode->crtc_clock)) {
|
|
DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
|
|
"pipe %c\n", pipe_name(pipe));
|
|
@@ -2748,6 +2760,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
|
|
irqreturn_t ret = IRQ_NONE;
|
|
u32 iir;
|
|
enum pipe pipe;
|
|
+ struct intel_crtc *crtc;
|
|
|
|
if (master_ctl & GEN8_DE_MISC_IRQ) {
|
|
iir = I915_READ(GEN8_DE_MISC_IIR);
|
|
@@ -2858,8 +2871,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
|
|
ret = IRQ_HANDLED;
|
|
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
|
|
|
|
+ crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
if (iir & GEN8_PIPE_VBLANK) {
|
|
- drm_handle_vblank(&dev_priv->drm, pipe);
|
|
+ drm_handle_vblank(&dev_priv->drm, drm_crtc_index(&crtc->base));
|
|
#if IS_ENABLED(CONFIG_DRM_I915_GVT)
|
|
gvt_notify_vblank(dev_priv, pipe);
|
|
#endif
|
|
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
|
|
index af592e3d09a9..6f25961ad9ad 100644
|
|
--- a/drivers/gpu/drm/i915/i915_trace.h
|
|
+++ b/drivers/gpu/drm/i915/i915_trace.h
|
|
@@ -281,7 +281,7 @@ TRACE_EVENT(i915_pipe_update_start,
|
|
TP_fast_assign(
|
|
__entry->pipe = crtc->pipe;
|
|
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
|
- crtc->pipe);
|
|
+ drm_crtc_index(&crtc->base));
|
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
|
__entry->min = crtc->debug.min_vbl;
|
|
__entry->max = crtc->debug.max_vbl;
|
|
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
|
|
index bc4d36c1a672..fe8952f6cdad 100644
|
|
--- a/drivers/gpu/drm/i915/intel_display.c
|
|
+++ b/drivers/gpu/drm/i915/intel_display.c
|
|
@@ -11949,11 +11949,13 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
|
|
if (new_state->active)
|
|
I915_STATE_WARN(!(pll->active_mask & crtc_mask),
|
|
"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
|
|
- pipe_name(drm_crtc_index(crtc)), pll->active_mask);
|
|
+ pipe_name(to_intel_crtc(crtc)->pipe),
|
|
+ pll->active_mask);
|
|
else
|
|
I915_STATE_WARN(pll->active_mask & crtc_mask,
|
|
"pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n",
|
|
- pipe_name(drm_crtc_index(crtc)), pll->active_mask);
|
|
+ pipe_name(to_intel_crtc(crtc)->pipe),
|
|
+ pll->active_mask);
|
|
|
|
I915_STATE_WARN(!(pll->state.crtc_mask & crtc_mask),
|
|
"pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n",
|
|
@@ -11984,10 +11986,10 @@ verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc,
|
|
|
|
I915_STATE_WARN(pll->active_mask & crtc_mask,
|
|
"pll active mismatch (didn't expect pipe %c in active mask)\n",
|
|
- pipe_name(drm_crtc_index(crtc)));
|
|
+ pipe_name(to_intel_crtc(crtc)->pipe));
|
|
I915_STATE_WARN(pll->state.crtc_mask & crtc_mask,
|
|
"pll enabled crtcs mismatch (found %x in enabled mask)\n",
|
|
- pipe_name(drm_crtc_index(crtc)));
|
|
+ pipe_name(to_intel_crtc(crtc)->pipe));
|
|
}
|
|
}
|
|
|
|
@@ -12402,7 +12404,8 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
|
|
if (!dev->max_vblank_count)
|
|
return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
|
|
|
|
- return dev->driver->get_vblank_counter(dev, crtc->pipe);
|
|
+ return dev->driver->get_vblank_counter(dev,
|
|
+ drm_crtc_index(&crtc->base));
|
|
}
|
|
|
|
static void intel_update_crtc(struct drm_crtc *crtc,
|
|
@@ -14058,6 +14061,27 @@ int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
|
|
return 0;
|
|
}
|
|
|
|
+int get_pipe_from_crtc_index(struct drm_device *dev, unsigned int index, enum pipe *pipe)
|
|
+{
|
|
+ struct drm_crtc *c = drm_crtc_from_index(dev, index);
|
|
+
|
|
+ if (WARN_ON(!c))
|
|
+ return -ENOENT;
|
|
+
|
|
+ *pipe = (to_intel_crtc(c)->pipe);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct intel_crtc *get_intel_crtc_from_index(struct drm_device *dev,
|
|
+ unsigned int index)
|
|
+{
|
|
+ struct drm_crtc *c = drm_crtc_from_index(dev, index);
|
|
+
|
|
+ WARN_ON(!c);
|
|
+ return to_intel_crtc(c);
|
|
+}
|
|
+
|
|
+
|
|
static int intel_encoder_clones(struct intel_encoder *encoder)
|
|
{
|
|
struct drm_device *dev = encoder->base.dev;
|
|
@@ -15644,7 +15668,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
|
crtc->active = crtc_state->base.active;
|
|
|
|
if (crtc_state->base.active)
|
|
- dev_priv->active_crtcs |= 1 << crtc->pipe;
|
|
+ dev_priv->active_crtcs |=
|
|
+ 1 << drm_crtc_index(&crtc->base);
|
|
|
|
readout_plane_state(crtc);
|
|
|
|
@@ -15665,7 +15690,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
|
|
|
if (crtc_state->base.active &&
|
|
crtc_state->shared_dpll == pll)
|
|
- pll->state.crtc_mask |= 1 << crtc->pipe;
|
|
+ pll->state.crtc_mask |=
|
|
+ 1 << drm_crtc_index(&crtc->base);
|
|
}
|
|
pll->active_mask = pll->state.crtc_mask;
|
|
|
|
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
|
|
index b51ad2917dbe..47b1dfe06152 100644
|
|
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
|
|
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
|
|
@@ -303,7 +303,7 @@ intel_reference_shared_dpll(struct intel_shared_dpll *pll,
|
|
DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->info->name,
|
|
pipe_name(crtc->pipe));
|
|
|
|
- shared_dpll[id].crtc_mask |= 1 << crtc->pipe;
|
|
+ shared_dpll[id].crtc_mask |= 1 << (drm_crtc_index(&crtc->base));
|
|
}
|
|
|
|
/**
|
|
@@ -3285,7 +3285,8 @@ void intel_release_shared_dpll(struct intel_shared_dpll *dpll,
|
|
struct intel_shared_dpll_state *shared_dpll_state;
|
|
|
|
shared_dpll_state = intel_atomic_get_shared_dpll_state(state);
|
|
- shared_dpll_state[dpll->info->id].crtc_mask &= ~(1 << crtc->pipe);
|
|
+ shared_dpll_state[dpll->info->id].crtc_mask &=
|
|
+ ~(1 << drm_crtc_index(&crtc->base));
|
|
}
|
|
|
|
/**
|
|
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
|
|
index 098c2886cf7e..49d4282b234b 100644
|
|
--- a/drivers/gpu/drm/i915/intel_drv.h
|
|
+++ b/drivers/gpu/drm/i915/intel_drv.h
|
|
@@ -1520,6 +1520,9 @@ enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
|
|
enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
|
|
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
|
|
struct drm_file *file_priv);
|
|
+int get_pipe_from_crtc_index(struct drm_device *dev, unsigned int index, enum pipe *pipe);
|
|
+struct intel_crtc *get_intel_crtc_from_index(struct drm_device *dev,
|
|
+ unsigned int index);
|
|
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
|
|
enum pipe pipe);
|
|
static inline bool
|
|
@@ -1539,7 +1542,12 @@ intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state)
|
|
static inline void
|
|
intel_wait_for_vblank(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
{
|
|
- drm_wait_one_vblank(&dev_priv->drm, pipe);
|
|
+ struct intel_crtc *crtc;
|
|
+
|
|
+ crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
+ if (crtc)
|
|
+ drm_wait_one_vblank(&dev_priv->drm,
|
|
+ drm_crtc_index(&crtc->base));
|
|
}
|
|
static inline void
|
|
intel_wait_for_vblank_if_active(struct drm_i915_private *dev_priv, int pipe)
|
|
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
|
|
index 77c123cc8817..83ed6f56ed56 100644
|
|
--- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
|
|
+++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
|
|
@@ -181,11 +181,18 @@ static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev,
|
|
enum pipe pipe, bool enable)
|
|
{
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
+ struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
|
|
+ if (!crtc) {
|
|
+ DRM_DEBUG("No crtc for pipe=%d\n", pipe);
|
|
+ return;
|
|
+ }
|
|
if (enable)
|
|
- bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
|
|
+ bdw_enable_pipe_irq(dev_priv, drm_crtc_index(&crtc->base),
|
|
+ GEN8_PIPE_FIFO_UNDERRUN);
|
|
else
|
|
- bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
|
|
+ bdw_disable_pipe_irq(dev_priv, drm_crtc_index(&crtc->base),
|
|
+ GEN8_PIPE_FIFO_UNDERRUN);
|
|
}
|
|
|
|
static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
|
|
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
|
index c7c7b5e78330..1884b8140131 100644
|
|
--- a/drivers/gpu/drm/i915/intel_pm.c
|
|
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
|
@@ -3710,7 +3710,6 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
|
|
struct intel_crtc *crtc;
|
|
struct intel_plane *plane;
|
|
struct intel_crtc_state *cstate;
|
|
- enum pipe pipe;
|
|
int level, latency;
|
|
int sagv_block_time_us;
|
|
|
|
@@ -3736,8 +3735,10 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
|
|
return false;
|
|
|
|
/* Since we're now guaranteed to only have one active CRTC... */
|
|
- pipe = ffs(intel_state->active_crtcs) - 1;
|
|
- crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
|
+ crtc = get_intel_crtc_from_index(dev,
|
|
+ ffs(intel_state->active_crtcs) - 1);
|
|
+ if (!crtc)
|
|
+ return false;
|
|
cstate = to_intel_crtc_state(crtc->base.state);
|
|
|
|
if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
|
--
|
|
2.19.1
|
|
|