Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318582
b: refs/heads/master
c: 254f965
h: refs/heads/master
v: v3
  • Loading branch information
Ben Widawsky authored and Daniel Vetter committed Jun 14, 2012
1 parent 72f5c40 commit 0aafb5e
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fe1cc68fcb11ca14f420068d1806eb5e719ac772
refs/heads/master: 254f965c39e3918544395f4ebac8c589d890bae6
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/i915/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
i915_debugfs.o \
i915_suspend.o \
i915_gem.o \
i915_gem_context.o \
i915_gem_debug.o \
i915_gem_evict.o \
i915_gem_execbuffer.o \
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,7 @@ int i915_driver_unload(struct drm_device *dev)
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
i915_gem_retire_requests(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);

/* Cancel the retire work handler, which should be idle now. */
Expand Down Expand Up @@ -1758,6 +1759,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file)
spin_lock_init(&file_priv->mm.lock);
INIT_LIST_HEAD(&file_priv->mm.request_list);

i915_gem_context_open(dev, file);

return 0;
}

Expand Down Expand Up @@ -1790,6 +1793,7 @@ void i915_driver_lastclose(struct drm_device * dev)

void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
{
i915_gem_context_close(dev, file_priv);
i915_gem_release(dev, file_priv);
}

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ int i915_reset(struct drm_device *dev)
for_each_ring(ring, dev_priv, i)
ring->init(ring);

i915_gem_context_init(dev);
i915_gem_init_ppgtt(dev);

mutex_unlock(&dev->struct_mutex);
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,8 @@ typedef struct drm_i915_private {
struct drm_property *force_audio_property;

struct work_struct parity_error_work;
bool hw_contexts_disabled;
uint32_t hw_context_size;
} drm_i915_private_t;

/* Iterate over initialised rings */
Expand Down Expand Up @@ -1075,6 +1077,7 @@ struct drm_i915_file_private {
#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc)
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)

#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6)
#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6)

#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay)
Expand Down Expand Up @@ -1363,6 +1366,11 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags);

/* i915_gem_context.c */
void i915_gem_context_init(struct drm_device *dev);
void i915_gem_context_fini(struct drm_device *dev);
void i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);

/* i915_gem_gtt.c */
int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev);
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3714,6 +3714,11 @@ i915_gem_init_hw(struct drm_device *dev)

dev_priv->next_seqno = 1;

/*
* XXX: There was some w/a described somewhere suggesting loading
* contexts before PPGTT.
*/
i915_gem_context_init(dev);
i915_gem_init_ppgtt(dev);

return 0;
Expand Down
175 changes: 175 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_gem_context.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* Copyright © 2011-2012 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Ben Widawsky <ben@bwidawsk.net>
*
*/

/*
* This file implements HW context support. On gen5+ a HW context consists of an
* opaque GPU object which is referenced at times of context saves and restores.
* With RC6 enabled, the context is also referenced as the GPU enters and exists
* from RC6 (GPU has it's own internal power context, except on gen5). Though
* something like a context does exist for the media ring, the code only
* supports contexts for the render ring.
*
* In software, there is a distinction between contexts created by the user,
* and the default HW context. The default HW context is used by GPU clients
* that do not request setup of their own hardware context. The default
* context's state is never restored to help prevent programming errors. This
* would happen if a client ran and piggy-backed off another clients GPU state.
* The default context only exists to give the GPU some offset to load as the
* current to invoke a save of the context we actually care about. In fact, the
* code could likely be constructed, albeit in a more complicated fashion, to
* never use the default context, though that limits the driver's ability to
* swap out, and/or destroy other contexts.
*
* All other contexts are created as a request by the GPU client. These contexts
* store GPU state, and thus allow GPU clients to not re-emit state (and
* potentially query certain state) at any time. The kernel driver makes
* certain that the appropriate commands are inserted.
*
* The context life cycle is semi-complicated in that context BOs may live
* longer than the context itself because of the way the hardware, and object
* tracking works. Below is a very crude representation of the state machine
* describing the context life.
* refcount pincount active
* S0: initial state 0 0 0
* S1: context created 1 0 0
* S2: context is currently running 2 1 X
* S3: GPU referenced, but not current 2 0 1
* S4: context is current, but destroyed 1 1 0
* S5: like S3, but destroyed 1 0 1
*
* The most common (but not all) transitions:
* S0->S1: client creates a context
* S1->S2: client submits execbuf with context
* S2->S3: other clients submits execbuf with context
* S3->S1: context object was retired
* S3->S2: clients submits another execbuf
* S2->S4: context destroy called with current context
* S3->S5->S0: destroy path
* S4->S5->S0: destroy path on current context
*
* There are two confusing terms used above:
* The "current context" means the context which is currently running on the
* GPU. The GPU has loaded it's state already and has stored away the gtt
* offset of the BO. The GPU is not actively referencing the data at this
* offset, but it will on the next context switch. The only way to avoid this
* is to do a GPU reset.
*
* An "active context' is one which was previously the "current context" and is
* on the active list waiting for the next context switch to occur. Until this
* happens, the object must remain at the same gtt offset. It is therefore
* possible to destroy a context, but it is still active.
*
*/

#include "drmP.h"
#include "i915_drm.h"
#include "i915_drv.h"

static int get_context_size(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
u32 reg;

switch (INTEL_INFO(dev)->gen) {
case 6:
reg = I915_READ(CXT_SIZE);
ret = GEN6_CXT_TOTAL_SIZE(reg) * 64;
break;
case 7:
reg = I915_READ(GEN7_CTX_SIZE);
ret = GEN7_CTX_TOTAL_SIZE(reg) * 64;
break;
default:
BUG();
}

return ret;
}

/**
* The default context needs to exist per ring that uses contexts. It stores the
* context state of the GPU for applications that don't utilize HW contexts, as
* well as an idle case.
*/
static int create_default_context(struct drm_i915_private *dev_priv)
{
return 0;
}

void i915_gem_context_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t ctx_size;

if (!HAS_HW_CONTEXTS(dev))
return;

/* If called from reset, or thaw... we've been here already */
if (dev_priv->hw_contexts_disabled)
return;

ctx_size = get_context_size(dev);
dev_priv->hw_context_size = get_context_size(dev);
dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096);

if (ctx_size <= 0 || ctx_size > (1<<20)) {
dev_priv->hw_contexts_disabled = true;
return;
}

if (create_default_context(dev_priv)) {
dev_priv->hw_contexts_disabled = true;
return;
}

DRM_DEBUG_DRIVER("HW context support initialized\n");
}

void i915_gem_context_fini(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;

if (dev_priv->hw_contexts_disabled)
return;
}

void i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_private *dev_priv = dev->dev_private;

if (dev_priv->hw_contexts_disabled)
return;
}

void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_private *dev_priv = dev->dev_private;

if (dev_priv->hw_contexts_disabled)
return;
}

0 comments on commit 0aafb5e

Please sign in to comment.