diff options
author | Mika Kuoppala <mika.kuoppala@linux.intel.com> | 2012-12-19 04:13:08 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-12-19 05:25:10 -0500 |
commit | fca26bb45375266d9d9b8b4b57fee905ac38fe3c (patch) | |
tree | 910b86c16c7d5d49180c6a85d4d548f753143d89 /drivers/gpu/drm/i915/i915_gem.c | |
parent | ba1a7067c00f4cbdd99b00a570ff072639ae59f2 (diff) |
drm/i915: Introduce i915_gem_set_seqno()
This function can be used to set the driver's next_seqno
to arbitrary value.
i915_gem_set_seqno() will idle the gpu, retire outstanding
requests, clear the semaphore mailboxes and set the hardware
status page's seqno index.
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bb38bca02559..23b883a135db 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1926,7 +1926,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | |||
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | static int | 1928 | static int |
1929 | i915_gem_handle_seqno_wrap(struct drm_device *dev) | 1929 | i915_gem_init_seqno(struct drm_device *dev, u32 seqno) |
1930 | { | 1930 | { |
1931 | struct drm_i915_private *dev_priv = dev->dev_private; | 1931 | struct drm_i915_private *dev_priv = dev->dev_private; |
1932 | struct intel_ring_buffer *ring; | 1932 | struct intel_ring_buffer *ring; |
@@ -1942,7 +1942,7 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev) | |||
1942 | 1942 | ||
1943 | /* Finally reset hw state */ | 1943 | /* Finally reset hw state */ |
1944 | for_each_ring(ring, dev_priv, i) { | 1944 | for_each_ring(ring, dev_priv, i) { |
1945 | intel_ring_init_seqno(ring, 0); | 1945 | intel_ring_init_seqno(ring, seqno); |
1946 | 1946 | ||
1947 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) | 1947 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) |
1948 | ring->sync_seqno[j] = 0; | 1948 | ring->sync_seqno[j] = 0; |
@@ -1951,6 +1951,32 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev) | |||
1951 | return 0; | 1951 | return 0; |
1952 | } | 1952 | } |
1953 | 1953 | ||
1954 | int i915_gem_set_seqno(struct drm_device *dev, u32 seqno) | ||
1955 | { | ||
1956 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1957 | int ret; | ||
1958 | |||
1959 | if (seqno == 0) | ||
1960 | return -EINVAL; | ||
1961 | |||
1962 | /* HWS page needs to be set less than what we | ||
1963 | * will inject to ring | ||
1964 | */ | ||
1965 | ret = i915_gem_init_seqno(dev, seqno - 1); | ||
1966 | if (ret) | ||
1967 | return ret; | ||
1968 | |||
1969 | /* Carefully set the last_seqno value so that wrap | ||
1970 | * detection still works | ||
1971 | */ | ||
1972 | dev_priv->next_seqno = seqno; | ||
1973 | dev_priv->last_seqno = seqno - 1; | ||
1974 | if (dev_priv->last_seqno == 0) | ||
1975 | dev_priv->last_seqno--; | ||
1976 | |||
1977 | return 0; | ||
1978 | } | ||
1979 | |||
1954 | int | 1980 | int |
1955 | i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) | 1981 | i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) |
1956 | { | 1982 | { |
@@ -1958,7 +1984,7 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) | |||
1958 | 1984 | ||
1959 | /* reserve 0 for non-seqno */ | 1985 | /* reserve 0 for non-seqno */ |
1960 | if (dev_priv->next_seqno == 0) { | 1986 | if (dev_priv->next_seqno == 0) { |
1961 | int ret = i915_gem_handle_seqno_wrap(dev); | 1987 | int ret = i915_gem_init_seqno(dev, 0); |
1962 | if (ret) | 1988 | if (ret) |
1963 | return ret; | 1989 | return ret; |
1964 | 1990 | ||