From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
This series refactors some of the atomic krealloc() stuff into a small helper
that avoids everyone having to do the krealloc() dance and memset() themselves.
Another thing we do is rework the private objects state handling to resemble
the normal crtc/plane/connector state handling more closely. Should make it
less cumbersome and error prone to deal with private objects.
Entire series available here:
git://github.com/vsyrjala/linux.…
[View More]git drm_dynarray
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan(a)intel.com>
Ville Syrjälä (5):
drm: Add drm_dynarray
drm/atomic: Convert state->connectors to drm_dynarray
drm/atomic: Remove pointless private object NULL state check
drm/atomic: Convert private_objs to drm_dynarray
drm/atomic: Make private objs proper objects
Documentation/gpu/drm-utils.rst | 15 +++
Documentation/gpu/index.rst | 1 +
drivers/gpu/drm/Makefile | 2 +-
drivers/gpu/drm/drm_atomic.c | 164 ++++++++++++++++++++------------
drivers/gpu/drm/drm_atomic_helper.c | 34 +++++--
drivers/gpu/drm/drm_dp_mst_topology.c | 63 ++++++------
drivers/gpu/drm/drm_dynarray.c | 97 +++++++++++++++++++
include/drm/drm_atomic.h | 174 +++++++++++++++++++++-------------
include/drm/drm_atomic_helper.h | 4 +
include/drm/drm_dp_mst_helper.h | 10 ++
include/drm/drm_dynarray.h | 54 +++++++++++
11 files changed, 454 insertions(+), 164 deletions(-)
create mode 100644 Documentation/gpu/drm-utils.rst
create mode 100644 drivers/gpu/drm/drm_dynarray.c
create mode 100644 include/drm/drm_dynarray.h
--
2.13.0
[View Less]
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
I set out to fix the pre-g4x GPU reset by protecting display commits with
an rw_semaphore. I originally went all out and added infrastructure to track
the committed state (as opposed the latest swapped state), but Daniel suggested
that we want to backport the thing so I simplified it to just use obj->state
instead. I will be posting the committed state handling as a followup as it
will also DTRT if/when we will start allowing …
[View More]queueing multiple commits per-crtc.
Not sure if we want to put the "committed" state stuf into the atomic helper or
I should just pull it all into i915. Suggestions welcome.
Series available here:
git://github.com/vsyrjala/linux.git reset_commit_rwsem_norefactor_2,
Ville Syrjälä (5):
drm/atomic: Refactor drm_atomic_state_realloc_connectors()
drm/atomic: Introduce drm_atomic_helper_duplicate_committed_state()
drm/i915% Store vma gtt offset in plane state
drm/i915: Refactor __intel_atomic_commit_tail()
drm/i915: Solve the GPU reset vs. modeset deadlocks with an
rw_semaphore
drivers/gpu/drm/drm_atomic.c | 43 ++++--
drivers/gpu/drm/drm_atomic_helper.c | 123 +++++++++++++++++
drivers/gpu/drm/i915/i915_drv.h | 2 +
drivers/gpu/drm/i915/i915_irq.c | 44 +-----
drivers/gpu/drm/i915/intel_display.c | 251 +++++++++++++++++++++++------------
drivers/gpu/drm/i915/intel_drv.h | 6 +-
drivers/gpu/drm/i915/intel_sprite.c | 8 +-
include/drm/drm_atomic.h | 5 +
include/drm/drm_atomic_helper.h | 4 +
9 files changed, 338 insertions(+), 148 deletions(-)
--
2.13.0
[View Less]
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Add drm_crtc_vblank_get_accurate() which is the same as
drm_crtc_vblank_get() except that it will forcefully update the
the current vblank counter/timestamp value even if the interrupt
is already enabled.
And we'll switch drm_wait_one_vblank() over to using it to make sure it
will really wait at least one vblank even if it races with the irq
handler.
Cc: Daniel Vetter <daniel(a)ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.…
[View More]syrjala(a)linux.intel.com>
---
drivers/gpu/drm/drm_vblank.c | 37 ++++++++++++++++++++++++++++++++-----
include/drm/drm_vblank.h | 1 +
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 823c853de052..c57383b8753b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -955,7 +955,8 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
return ret;
}
-static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
+static int drm_vblank_get(struct drm_device *dev, unsigned int pipe,
+ bool force_update)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
unsigned long irqflags;
@@ -975,6 +976,10 @@ static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
if (!vblank->enabled) {
atomic_dec(&vblank->refcount);
ret = -EINVAL;
+ } else if (force_update) {
+ spin_lock(&dev->vblank_time_lock);
+ drm_update_vblank_count(dev, pipe, false);
+ spin_unlock(&dev->vblank_time_lock);
}
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -994,10 +999,32 @@ static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
*/
int drm_crtc_vblank_get(struct drm_crtc *crtc)
{
- return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
+ return drm_vblank_get(crtc->dev, drm_crtc_index(crtc), false);
}
EXPORT_SYMBOL(drm_crtc_vblank_get);
+/**
+ * drm_crtc_vblank_get_accurate - get a reference count on vblank events and
+ * make sure the counter is uptodate
+ * @crtc: which CRTC to own
+ *
+ * Acquire a reference count on vblank events to avoid having them disabled
+ * while in use.
+ *
+ * Also make sure the current vblank counter is value is fully up to date
+ * even if we're already past the start of vblank but the irq hasn't fired
+ * yet, which may be the case with some hardware that raises the interrupt
+ * only some time after the start of vblank.
+ *
+ * Returns:
+ * Zero on success or a negative error code on failure.
+ */
+int drm_crtc_vblank_get_accurate(struct drm_crtc *crtc)
+{
+ return drm_vblank_get(crtc->dev, drm_crtc_index(crtc), true);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_get_accurate);
+
static void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -1053,7 +1080,7 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
if (WARN_ON(pipe >= dev->num_crtcs))
return;
- ret = drm_vblank_get(dev, pipe);
+ ret = drm_vblank_get(dev, pipe, true);
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret))
return;
@@ -1248,7 +1275,7 @@ static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
*/
if (!vblank->inmodeset) {
vblank->inmodeset = 0x1;
- if (drm_vblank_get(dev, pipe) == 0)
+ if (drm_vblank_get(dev, pipe, false) == 0)
vblank->inmodeset |= 0x2;
}
}
@@ -1448,7 +1475,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
return 0;
}
- ret = drm_vblank_get(dev, pipe);
+ ret = drm_vblank_get(dev, pipe, false);
if (ret) {
DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret);
return ret;
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 7fba9efe4951..5629e7841318 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -162,6 +162,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
int drm_crtc_vblank_get(struct drm_crtc *crtc);
+int drm_crtc_vblank_get_accurate(struct drm_crtc *crtc);
void drm_crtc_vblank_put(struct drm_crtc *crtc);
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
--
2.13.0
[View Less]