From 1a8406795052e3ec49e400465f3211d04fd9dd86 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 30 Apr 2008 16:03:15 -0700 Subject: Hacking towards hooking up execbuffer. --- shared-core/i915_drv.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 412a2594..0c6ec588 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -241,6 +241,10 @@ typedef struct drm_i915_private { u8 saveDACMASK; u8 saveDACDATA[256*3]; /* 256 3-byte colors */ u8 saveCR[36]; + + struct { + struct drm_memrange gtt_space; + } mm; } drm_i915_private_t; enum intel_chip_family { @@ -329,6 +333,11 @@ void i915_flush_ttm(struct drm_ttm *ttm); /* i915_execbuf.c */ int i915_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); +/* i915_mm.c */ +int intel_mm_init_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int intel_mm_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv); #endif -- cgit v1.2.3 From 2140e102f942edf7982cee2a3f00caf234551687 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 1 May 2008 11:39:06 -0700 Subject: checkpoint: rename to GEM and a few more i915 bits. --- shared-core/i915_drv.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 0c6ec588..7913f48b 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -254,6 +254,18 @@ enum intel_chip_family { CHIP_I965 = 0x08, }; +/** driver private structure attached to each drm_gem_object */ +struct drm_i915_gem_object { + /** Current offset of the object in GTT space, if any. */ + uint32_t gtt_offset; + + /** Boolean whether this object has a valid gtt offset. */ + int gtt_bound; + + /** How many users have pinned this object in GTT space */ + int pin_count; +}; + extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; @@ -333,11 +345,13 @@ void i915_flush_ttm(struct drm_ttm *ttm); /* i915_execbuf.c */ int i915_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); -/* i915_mm.c */ -int intel_mm_init_ioctl(struct drm_device *dev, void *data, +/* i915_gem.c */ +int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -int intel_mm_execbuffer(struct drm_device *dev, void *data, +int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_init_object(struct drm_device *dev, struct drm_gem_object *obj); +void i915_gem_free_object(struct drm_device *dev, struct drm_gem_object *obj); #endif -- cgit v1.2.3 From 5af87acbc2025b9f72d51b30f176e9c3909695ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 1 May 2008 14:20:44 -0700 Subject: checkpoint: gtt binding written. --- shared-core/i915_drv.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 7913f48b..431fc433 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -256,7 +256,19 @@ enum intel_chip_family { /** driver private structure attached to each drm_gem_object */ struct drm_i915_gem_object { - /** Current offset of the object in GTT space, if any. */ + /** Current space allocated to this object in the GTT, if any. */ + struct drm_memrange_node *gtt_space; + + /** AGP memory structure for our GTT binding. */ + DRM_AGP_MEM *agp_mem; + + struct page **page_list; + + /** + * Current offset of the object in GTT space. + * + * This is the same as gtt_space->start + */ uint32_t gtt_offset; /** Boolean whether this object has a valid gtt offset. */ -- cgit v1.2.3 From 793549116ee6e9202fc7e474bd382eb19ffeb87f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 1 May 2008 15:40:02 -0700 Subject: Add pin/unpin object ioctls for gem. --- shared-core/i915_drv.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 431fc433..801ac99e 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -362,6 +362,10 @@ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_init_object(struct drm_device *dev, struct drm_gem_object *obj); void i915_gem_free_object(struct drm_device *dev, struct drm_gem_object *obj); -- cgit v1.2.3 From 49e8e3372afcf5fab9ffef5691d87ad8bc19599a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 2 May 2008 10:36:00 -0700 Subject: Remove drm_driver argument to functions taking drm_gem_object. Now that drm_gem_object has a drm_driver * in it, functions don't need both parameters. --- shared-core/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 801ac99e..0ebfedca 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -366,8 +366,8 @@ int i915_gem_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -int i915_gem_init_object(struct drm_device *dev, struct drm_gem_object *obj); -void i915_gem_free_object(struct drm_device *dev, struct drm_gem_object *obj); +int i915_gem_init_object(struct drm_gem_object *obj); +void i915_gem_free_object(struct drm_gem_object *obj); #endif -- cgit v1.2.3 From b6f173c4300e90be9bdd3b24003b800afd8819c5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 May 2008 10:51:49 -0700 Subject: Add i915_dispatch_gem_execbuffer (broken). This function submits a gem-based execbuffer to the ring. It doesn't work yet. --- shared-core/i915_drv.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 0ebfedca..c6d86584 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -299,6 +299,10 @@ extern int i915_dispatch_batchbuffer(struct drm_device * dev, drm_i915_batchbuffer_t * batch); extern int i915_quiescent(struct drm_device *dev); +int i915_emit_box(struct drm_device * dev, + struct drm_clip_rect __user * boxes, + int i, int DR1, int DR4); + /* i915_irq.c */ extern int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); -- cgit v1.2.3 From 91cba3ae17eb34d1836164f86c13a2a8e08c2a29 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 May 2008 22:10:02 -0700 Subject: Dump last batch buffer when hardware lockup is detected. --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c6d86584..6c06ff5c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -544,6 +544,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 #define I915REG_INSTPM 0x020c0 +#define I965REG_ACTHD 0x02074 +#define I915REG_ACTHD 0x020C8 #define PIPEADSL 0x70000 #define PIPEBDSL 0x71000 -- cgit v1.2.3 From d2373b2a341868882208bb4297ab4f2f51302031 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 May 2008 13:28:26 -0700 Subject: GEM: Use irq-based fencing rather than syncing and evicting every exec. --- shared-core/i915_drv.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 6c06ff5c..bd6fa188 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -244,6 +244,8 @@ typedef struct drm_i915_private { struct { struct drm_memrange gtt_space; + /** LRU List of unpinned objects in the GTT. */ + struct list_head gtt_lru; } mm; } drm_i915_private_t; @@ -256,8 +258,12 @@ enum intel_chip_family { /** driver private structure attached to each drm_gem_object */ struct drm_i915_gem_object { + struct drm_gem_object *obj; + /** Current space allocated to this object in the GTT, if any. */ struct drm_memrange_node *gtt_space; + /** This object's place on the GTT LRU list */ + struct list_head gtt_lru_entry; /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; @@ -276,6 +282,9 @@ struct drm_i915_gem_object { /** How many users have pinned this object in GTT space */ int pin_count; + + /** Breadcrumb of last rendering to the buffer. */ + uint32_t last_rendering_cookie; }; extern struct drm_ioctl_desc i915_ioctls[]; @@ -318,6 +327,7 @@ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_emit_irq(struct drm_device * dev); +extern int i915_wait_irq(struct drm_device * dev, int irq_nr); extern int i915_enable_vblank(struct drm_device *dev, int crtc); extern void i915_disable_vblank(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); -- cgit v1.2.3 From 6a6c37af9ecaabfe1399a1300cadaff730767013 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 6 May 2008 21:59:06 -0700 Subject: [intel-GEM] ref count objects in gtt-lru. If objects on the lru aren't ref counted, they'll get pulled from the gtt as soon as they are freed. This change does cause objects to get stuck in the gtt until they're forced out by new requests. The lru should get cleaned when the irq occurs. --- shared-core/i915_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index bd6fa188..daa77f72 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -262,6 +262,7 @@ struct drm_i915_gem_object { /** Current space allocated to this object in the GTT, if any. */ struct drm_memrange_node *gtt_space; + /** This object's place on the GTT LRU list */ struct list_head gtt_lru_entry; -- cgit v1.2.3 From 9af4c497433398fa4576a7c1c31036448cf4f24c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 8 May 2008 10:44:02 -0700 Subject: [intel-gem] Move domains to relocation records. add set_domain ioctl. Domain information is about buffer relationships, not buffer contents. That means a relocation contains the domain information as it knows how the source buffer references the target buffer. This also adds the set_domain ioctl so that user space can move buffers to the cpu domain. --- shared-core/i915_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index daa77f72..96257ab6 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -383,6 +383,9 @@ int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); +int i915_gem_set_domain_ioctl (struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); #endif -- cgit v1.2.3 From c5c59eab809604e4d0d4d1dc71fc11186d0220f8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 9 May 2008 14:34:20 -0700 Subject: GEM: Separate the LRU into execution list and LRU list. Now, the LRU list has objects that are completely done rendering and ready to kick out, while the execution list has things with active rendering, which have associated cookies and reference counts on them. --- shared-core/i915_drv.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 96257ab6..413fca89 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -244,7 +244,12 @@ typedef struct drm_i915_private { struct { struct drm_memrange gtt_space; - /** LRU List of unpinned objects in the GTT. */ + /** + * List of objects currently involved in rendering from the + * ringbuffer. + */ + struct list_head execution_list; + /** LRU List of non-executing objects still in the GTT. */ struct list_head gtt_lru; } mm; } drm_i915_private_t; @@ -386,7 +391,7 @@ void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_set_domain_ioctl (struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain); - +void i915_gem_lastclose(struct drm_device *dev); #endif #ifdef __linux__ -- cgit v1.2.3 From ff39db099b9ca6c8feee68101a2269345b7bd798 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 11 May 2008 00:10:16 -0700 Subject: [GEM] Make pread/pwrite manage memory domains. No luck with movnti though. pread and pwrite must update the memory domains to ensure consistency with the GPU. At some point, it should be possible to avoid clflush through this path, but that isn't working for me. --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 413fca89..78c5d3df 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -391,6 +391,8 @@ void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_set_domain_ioctl (struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain); +int i915_gem_flush_pwrite(struct drm_gem_object *obj, + uint64_t offset, uint64_t size); void i915_gem_lastclose(struct drm_device *dev); #endif -- cgit v1.2.3 From 3ab152da66f6c7bcc68a13efcf4a62800354f13b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 May 2008 09:37:49 -0700 Subject: [gem] Rename the GTT LRU lists to active (executing) and inactive (idle). --- shared-core/i915_drv.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 78c5d3df..51c6bb59 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -248,9 +248,9 @@ typedef struct drm_i915_private { * List of objects currently involved in rendering from the * ringbuffer. */ - struct list_head execution_list; + struct list_head active_list; /** LRU List of non-executing objects still in the GTT. */ - struct list_head gtt_lru; + struct list_head inactive_list; } mm; } drm_i915_private_t; @@ -267,9 +267,9 @@ struct drm_i915_gem_object { /** Current space allocated to this object in the GTT, if any. */ struct drm_memrange_node *gtt_space; - - /** This object's place on the GTT LRU list */ - struct list_head gtt_lru_entry; + + /** This object's place on the active or inactive lists */ + struct list_head list; /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; -- cgit v1.2.3 From 7dced2f33a952ad12aafb7a3e34747156020a3ae Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 May 2008 11:21:11 -0700 Subject: [gem] Hold dev->struct_mutex to protect structure data. --- shared-core/i915_drv.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 51c6bb59..296e1823 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -388,9 +388,9 @@ int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); -int i915_gem_set_domain_ioctl (struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); +int i915_gem_set_domain(struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); int i915_gem_flush_pwrite(struct drm_gem_object *obj, uint64_t offset, uint64_t size); void i915_gem_lastclose(struct drm_device *dev); -- cgit v1.2.3 From 6c3ac484b049681f9f3e692f9a6238ed122a8191 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 20 May 2008 10:48:36 -0700 Subject: [gem] Clean up active/inactive list handling using helper functions. Additionally, a boolean active field is added to indicate which list an object is on, rather than smashing last_rendering_cookie to 0 to show inactive. This will help with flush-reduction later on, and makes the code clearer. --- shared-core/i915_drv.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 296e1823..870726c5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -247,9 +247,18 @@ typedef struct drm_i915_private { /** * List of objects currently involved in rendering from the * ringbuffer. + * + * A reference is held on the buffer while on this list. */ struct list_head active_list; - /** LRU List of non-executing objects still in the GTT. */ + /** + * LRU List of non-executing objects still in the GTT. + * There may still be dirty cachelines that need to be flushed + * before unbind. + * A reference is not held on the buffer while on this list, + * as merely being GTT-bound shouldn't prevent its being + * freed, and we'll pull it off the list in the free path. + */ struct list_head inactive_list; } mm; } drm_i915_private_t; @@ -271,6 +280,13 @@ struct drm_i915_gem_object { /** This object's place on the active or inactive lists */ struct list_head list; + /** + * This is set if the object is on the active list + * (has pending rendering), and is not set if it's on inactive (ready + * to be unbound). + */ + int active; + /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; -- cgit v1.2.3 From ab36a6f983107971890e81473452b3f0313fb692 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 20 May 2008 10:52:24 -0700 Subject: [gem] Rename sequence numbers from "cookie" to "seqno" --- shared-core/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 870726c5..79c607bc 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -306,7 +306,7 @@ struct drm_i915_gem_object { int pin_count; /** Breadcrumb of last rendering to the buffer. */ - uint32_t last_rendering_cookie; + uint32_t last_rendering_seqno; }; extern struct drm_ioctl_desc i915_ioctls[]; -- cgit v1.2.3 From af8e087157ef5034fa12d93202037f87da61355d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 20 May 2008 14:03:27 -0700 Subject: [gem] Use a separate sequence number field from classic/ttm This lets us get some qualities we desire, such as using the full 32-bit range (except zero), avoiding DRM_WAIT_ON, and a 1:1 mapping of active sequence numbers to request structs, which will be used soon for throttling and interrupt-driven list cleanup. --- shared-core/i915_drv.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 79c607bc..ef41b433 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -260,6 +260,14 @@ typedef struct drm_i915_private { * freed, and we'll pull it off the list in the free path. */ struct list_head inactive_list; + + /** + * List of breadcrumbs associated with GPU requests currently + * outstanding. + */ + struct list_head request_list; + + uint32_t next_gem_seqno; } mm; } drm_i915_private_t; @@ -309,6 +317,23 @@ struct drm_i915_gem_object { uint32_t last_rendering_seqno; }; +/** + * Request queue structure. + * + * The request queue allows us to note sequence numbers that have been emitted + * and may be associated with active buffers to be retired. + * + * By keeping this list, we can avoid having to do questionable + * sequence-number comparisons on buffer last_rendering_seqnos, and associate + * an emission time with seqnos for tracking how far ahead of the GPU we are. + */ +struct drm_i915_gem_request { + /** GEM sequence number associated with this request. */ + uint32_t seqno; + + struct list_head list; +}; + extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; @@ -506,7 +531,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IMM ((0x20<<23) | (0x1 << 22) | 0x1) +/** + * Stores a 32-bit integer to the status page at the dword index given. + */ #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +# define STORE_DWORD_INDEX_SHIFT 2 + #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) #define CMD_MI_FLUSH (0x04 << 23) @@ -855,7 +885,22 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) #define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) + +/** + * Reads a dword out of the status page, which is written to from the command + * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or + * MI_STORE_DATA_IMM. + * + * The following dwords have a reserved meaning: + * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes. + * 4: ring 0 head pointer + * 5: ring 1 head pointer (915-class) + * 6: ring 2 head pointer (915-class) + * + * The area from dword 0x10 to 0x3ff is available for driver usage. + */ #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) +#define I915_GEM_HWS_INDEX 0x10 #define BLC_PWM_CTL 0x61254 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -- cgit v1.2.3 From d6f796857780fc54641047e2aa4e7091376928eb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 20 May 2008 16:27:05 -0700 Subject: [gem] Replace ring throttling hack with actual time measurement. --- shared-core/i915_drv.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index ef41b433..e3f280d5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -331,6 +331,9 @@ struct drm_i915_gem_request { /** GEM sequence number associated with this request. */ uint32_t seqno; + /** Time at which this request was emitted, in jiffies. */ + unsigned long emitted_jiffies; + struct list_head list; }; -- cgit v1.2.3 From 5e662f90d1143de53db866e2b8a94f1bfbe5fc51 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 May 2008 15:13:14 -0700 Subject: [gem] Release GEM buffers from work task scheduled from IRQ. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are now 3 lists. Active is buffers currently in the ringbuffer. Flushing is not in the ringbuffer, but needs a flush before unbinding. Inactive is as before. This prevents object_free → unbind → wait_rendering → object_reference and a kernel oops about weird refcounting. This also avoids an synchronous extra flush and wait when freeing a buffer which had a write_domain set (such as a temporary rendered to and then from using the 2d engine). It will sit around on the flushing list until the appropriate flush gets emitted, or we need the GTT space for another operation. --- shared-core/i915_drv.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index e3f280d5..029c39a0 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -101,6 +101,8 @@ typedef struct _drm_i915_vbl_swap { } drm_i915_vbl_swap_t; typedef struct drm_i915_private { + struct drm_device *dev; + drm_local_map_t *sarea; drm_local_map_t *mmio_map; @@ -244,6 +246,7 @@ typedef struct drm_i915_private { struct { struct drm_memrange gtt_space; + /** * List of objects currently involved in rendering from the * ringbuffer. @@ -251,10 +254,20 @@ typedef struct drm_i915_private { * A reference is held on the buffer while on this list. */ struct list_head active_list; + /** - * LRU List of non-executing objects still in the GTT. - * There may still be dirty cachelines that need to be flushed - * before unbind. + * List of objects which are not in the ringbuffer but which + * still have a write_domain which needs to be flushed before + * unbinding. + * + * A reference is held on the buffer while on this list. + */ + struct list_head flushing_list; + + /** + * LRU list of objects which are not in the ringbuffer and + * are ready to unbind, but are still in the GTT. + * * A reference is not held on the buffer while on this list, * as merely being GTT-bound shouldn't prevent its being * freed, and we'll pull it off the list in the free path. @@ -269,6 +282,8 @@ typedef struct drm_i915_private { uint32_t next_gem_seqno; } mm; + + struct work_struct user_interrupt_task; } drm_i915_private_t; enum intel_chip_family { @@ -285,11 +300,11 @@ struct drm_i915_gem_object { /** Current space allocated to this object in the GTT, if any. */ struct drm_memrange_node *gtt_space; - /** This object's place on the active or inactive lists */ + /** This object's place on the active/flushing/inactive lists */ struct list_head list; /** - * This is set if the object is on the active list + * This is set if the object is on the active or flushing lists * (has pending rendering), and is not set if it's on inactive (ready * to be unbound). */ @@ -334,6 +349,9 @@ struct drm_i915_gem_request { /** Time at which this request was emitted, in jiffies. */ unsigned long emitted_jiffies; + /** Cache domains that were flushed at the start of the request. */ + uint32_t flush_domains; + struct list_head list; }; @@ -385,6 +403,7 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_user_irq_on(drm_i915_private_t *dev_priv); extern void i915_user_irq_off(drm_i915_private_t *dev_priv); +extern void i915_user_interrupt_handler(struct work_struct *work); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, @@ -438,6 +457,7 @@ int i915_gem_set_domain(struct drm_gem_object *obj, int i915_gem_flush_pwrite(struct drm_gem_object *obj, uint64_t offset, uint64_t size); void i915_gem_lastclose(struct drm_device *dev); +void i915_gem_retire_requests(struct drm_device *dev); #endif #ifdef __linux__ -- cgit v1.2.3 From a51c3a76ff415104426493a97ac686ccfe3f3926 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 22 May 2008 10:48:32 -0700 Subject: [intel] Add debug code to verify the cached ring tail pointer. Recording the tail pointer in a local variable improves performance, but if someone messes up and fails to reload at the right time, the driver will write commands to the wrong part of the ring and scramble execution badly. This change (available by setting I915_RING_VALIDATE to 1) checks to make sure the cached tail pointer matches the hardware tail pointer at each ring buffer addition, calling BUG_ON when that's not true. --- shared-core/i915_drv.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 029c39a0..e217b789 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -473,14 +473,23 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev); #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) #define I915_VERBOSE 0 +#define I915_RING_VALIDATE 0 #define RING_LOCALS unsigned int outring, ringmask, outcount; \ volatile char *virt; +#if I915_RING_VALIDATE +void i915_ring_validate(struct drm_device *dev, const char *func, int line); +#define I915_RING_DO_VALIDATE(dev) i915_ring_validate(dev, __FUNCTION__, __LINE__) +#else +#define I915_RING_DO_VALIDATE(dev) +#endif + #define BEGIN_LP_RING(n) do { \ if (I915_VERBOSE) \ DRM_DEBUG("BEGIN_LP_RING(%d)\n", \ (n)); \ + I915_RING_DO_VALIDATE(dev); \ if (dev_priv->ring.space < (n)*4) \ i915_wait_ring(dev, (n)*4, __FUNCTION__); \ outcount = 0; \ @@ -499,6 +508,7 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev); #define ADVANCE_LP_RING() do { \ if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ + I915_RING_DO_VALIDATE(dev); \ dev_priv->ring.tail = outring; \ dev_priv->ring.space -= outcount * 4; \ I915_WRITE(LP_RING + RING_TAIL, outring); \ -- cgit v1.2.3 From 7cf3fd29fe058a0bfc2ba7e889d1b360398be161 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 25 May 2008 20:45:20 -0700 Subject: [intel-gem] Add DRM_I915_GEM_BUSY ioctl to check for idle buffers. This new ioctl returns whether re-using the buffer would force a wait. --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index e217b789..04e149a9 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -449,6 +449,8 @@ int i915_gem_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_busy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_set_domain(struct drm_gem_object *obj, -- cgit v1.2.3 From d434b64f6a760d85295e32298a9a1f3624ee1b69 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 May 2008 03:25:16 -0700 Subject: [i915] leave interrupts masked off when not in use. The interrupt enable register cannot be used to temporarily disable interrupts, instead use the interrupt mask register. Note that this change means that a pile of buffers will be left stuck on the chip as the final interrupts will not be recognized to come and drain things. --- shared-core/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 04e149a9..fee6d436 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -131,7 +131,7 @@ typedef struct drm_i915_private { DRM_SPINTYPE user_irq_lock; int user_irq_refcount; int fence_irq_on; - uint32_t irq_enable_reg; + uint32_t irq_mask_reg; int irq_enabled; #ifdef I915_HAVE_FENCE -- cgit v1.2.3 From e10502002f0ebb2b56b19384b2f2eae7a7a84512 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 27 May 2008 17:50:39 -0700 Subject: [intel-gem] Replace idlelock usage with real lock acquisition. --- shared-core/i915_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index fee6d436..76bc6bee 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -454,6 +454,7 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_set_domain(struct drm_gem_object *obj, + struct drm_file *file_priv, uint32_t read_domains, uint32_t write_domain); int i915_gem_flush_pwrite(struct drm_gem_object *obj, -- cgit v1.2.3 From 56a96841d01d112d7d4adfebb572016398551ba8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Jun 2008 12:57:01 -0700 Subject: [intel-gem] Add explicit throttle ioctl Instead of throttling and execbuffer time, have the application ask to throttle explicitly. This allows the throttle to happen less often, and without holding the DRM lock. --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index d646177b..33fb7ca9 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -451,6 +451,8 @@ int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_set_domain(struct drm_gem_object *obj, -- cgit v1.2.3 From 9f46c6935d154743162c6239903a4a9e443907bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Jun 2008 12:59:52 -0700 Subject: [intel-gem] Use timers to retire requests periodically. Without the user IRQ running constantly, there's no wakeup when the ring empties to go retire requests and free buffers. Use a 1 second timer to make that happen more often. --- shared-core/i915_drv.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 33fb7ca9..55af6552 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -280,6 +280,16 @@ typedef struct drm_i915_private { */ struct list_head request_list; + /** + * We leave the user IRQ off as much as possible, + * but this means that requests will finish and never + * be retired once the system goes idle. Set a timer to + * fire periodically while the ring is running. When it + * fires, go retire requests. + */ + struct timer_list retire_timer; + struct work_struct retire_task; + uint32_t next_gem_seqno; } mm; @@ -463,6 +473,8 @@ int i915_gem_flush_pwrite(struct drm_gem_object *obj, uint64_t offset, uint64_t size); void i915_gem_lastclose(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); +void i915_gem_retire_timeout(unsigned long data); +void i915_gem_retire_handler(struct work_struct *work); #endif #ifdef __linux__ -- cgit v1.2.3 From 6cd0ef06a6c2bdcede166d9a2d0434e58e4a01f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Jun 2008 13:26:03 -0700 Subject: [intel] remove settable use_mi_batchbuffer_start The driver can know what hardware requires MI_BATCH_BUFFER vs MI_BATCH_BUFFER_START; there's no reason to let user mode configure this. --- shared-core/i915_drv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 55af6552..8acef0ca 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -117,7 +117,6 @@ typedef struct drm_i915_private { drm_local_map_t hws_map; unsigned int cpp; - int use_mi_batchbuffer_start; wait_queue_head_t irq_queue; atomic_t irq_received; -- cgit v1.2.3 From 2150da5d1a57d25d0f4bc39bb6c883d410f586d1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 10 Jun 2008 15:30:23 -0700 Subject: [gem] Manage the ringbuffer from the kernel in the GEM case. This requires that the X Server use the execbuf interface for buffer submission, as it no longer has direct access to the ring. This is therefore a flag day for the gem interface. This also adds enter/leavevt ioctls for use by the X Server. These would get stubbed out in a modesetting implementation, but are required while in an environment where the device's state is only managed by the DRM while X has the VT. --- shared-core/i915_drv.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 8acef0ca..3a22ae3c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -74,14 +74,13 @@ struct drm_i915_validate_buffer; typedef struct _drm_i915_ring_buffer { int tail_mask; - unsigned long Start; - unsigned long End; unsigned long Size; u8 *virtual_start; int head; int tail; int space; drm_local_map_t map; + struct drm_gem_object *ring_obj; } drm_i915_ring_buffer_t; struct mem_block { @@ -290,6 +289,16 @@ typedef struct drm_i915_private { struct work_struct retire_task; uint32_t next_gem_seqno; + + /** + * Flag if the X Server, and thus DRM, is not currently in + * control of the device. + * + * This is set between LeaveVT and EnterVT. It needs to be + * replaced with a semaphore. It also needs to be + * transitioned away from for kernel modesetting. + */ + int suspended; } mm; struct work_struct user_interrupt_task; @@ -462,8 +471,14 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); +int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); +void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_set_domain(struct drm_gem_object *obj, struct drm_file *file_priv, uint32_t read_domains, -- cgit v1.2.3 From 2655005762b8915d5f44d1d1ee7e6c2eb34841d7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 11 Jun 2008 14:42:40 -0700 Subject: [gem] Move potentially device-specific ioctls to the intel driver. This is the create (may want location flags), pread/pwrite/mmap (performance tuning hints), and set_domain (will 32 bits be enough for everyone?) ioctls. Left in the generic set are just flink/open/close. The 2D driver must be updated for this change, and API but not ABI is broken for 3D. The driver version is bumped to mark this. --- shared-core/i915_drv.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 3a22ae3c..9c9925b5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -37,7 +37,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20080312" +#define DRIVER_DATE "20080611" #if defined(__linux__) #define I915_HAVE_FENCE @@ -61,7 +61,7 @@ */ #define DRIVER_MAJOR 1 #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) -#define DRIVER_MINOR 13 +#define DRIVER_MINOR 14 #else #define DRIVER_MINOR 6 #endif @@ -461,6 +461,16 @@ int i915_execbuffer(struct drm_device *dev, void *data, /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_pread_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_pin_ioctl(struct drm_device *dev, void *data, @@ -479,12 +489,6 @@ int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); void i915_gem_object_unpin(struct drm_gem_object *obj); -int i915_gem_set_domain(struct drm_gem_object *obj, - struct drm_file *file_priv, - uint32_t read_domains, - uint32_t write_domain); -int i915_gem_flush_pwrite(struct drm_gem_object *obj, - uint64_t offset, uint64_t size); void i915_gem_lastclose(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_timeout(unsigned long data); -- cgit v1.2.3 From 0558d99c01c38e24e97b57ef55f66bb94a92e157 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 13 Jun 2008 09:53:36 -0700 Subject: [gem] Remove the interrupt handler for retiring requests. This was insufficient once we started masking interrupts to only when someone was waiting for them (and would thus retire requests themselves). It was replaced by the retire_timer. --- shared-core/i915_drv.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 9c9925b5..5af9a964 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -300,8 +300,6 @@ typedef struct drm_i915_private { */ int suspended; } mm; - - struct work_struct user_interrupt_task; } drm_i915_private_t; enum intel_chip_family { @@ -421,7 +419,6 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_user_irq_on(drm_i915_private_t *dev_priv); extern void i915_user_irq_off(drm_i915_private_t *dev_priv); -extern void i915_user_interrupt_handler(struct work_struct *work); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, -- cgit v1.2.3 From 462af73149b9286a74b95b9cda5e4224ebe0dd87 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Jun 2008 09:19:30 -0700 Subject: [intel-gem] Use a delayed_work instead of a timer + work_struct We want request retirement to occur about once a second when the request queue is non-empty. This was done with a timer that queued a work_struct, using a delayed_work instead makes a lot more sense. --- shared-core/i915_drv.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 5af9a964..5cc6e680 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -285,8 +285,7 @@ typedef struct drm_i915_private { * fire periodically while the ring is running. When it * fires, go retire requests. */ - struct timer_list retire_timer; - struct work_struct retire_task; + struct delayed_work retire_work; uint32_t next_gem_seqno; @@ -488,8 +487,7 @@ int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); void i915_gem_object_unpin(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); -void i915_gem_retire_timeout(unsigned long data); -void i915_gem_retire_handler(struct work_struct *work); +void i915_gem_retire_work_handler(struct work_struct *work); #endif #ifdef __linux__ @@ -915,6 +913,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) #define XY_SRC_COPY_BLT_DST_TILED (1<<11) +#define MI_NOOP (0) +#define MI_NOOP_ENABLE_NOPID (1 << 22) +#define MI_NOOP_ID_MASK ((1 << 22) - 1) #define MI_BATCH_BUFFER ((0x30<<23)|1) #define MI_BATCH_BUFFER_START (0x31<<23) -- cgit v1.2.3 From ced9ebf64543b4d64a38feee3293040af953acc0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Jun 2008 12:06:13 -0700 Subject: [intel-gem] throttle based on frames rather than time. Reduces jitter. Record the last execbuffer sequence for each client. Record that sequence in the throttle ioctl as the 'throttle sequence'. Wait for the last throttle sequence in the throttle ioctl. --- shared-core/i915_drv.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 5cc6e680..334bc43f 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -301,6 +301,13 @@ typedef struct drm_i915_private { } mm; } drm_i915_private_t; +struct drm_i915_file_private { + struct { + uint32_t last_gem_seqno; + uint32_t last_gem_throttle_seqno; + } mm; +}; + enum intel_chip_family { CHIP_I8XX = 0x01, CHIP_I9XX = 0x02, @@ -378,8 +385,11 @@ extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); extern void i915_driver_lastclose(struct drm_device * dev); +extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv); extern void i915_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); +extern void i915_driver_postclose(struct drm_device *dev, + struct drm_file *file_priv); extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -- cgit v1.2.3 From 52e5d24fae4af6f2f4a5304a516c8c5ab347a11b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jun 2008 00:19:42 -0700 Subject: [intel-gem] Add DRM_IOCTL_I915_GEM_SW_FINISH to flag CPU writes When a software fallback has completed, usermode must notify the kernel so that any scanout buffers can be synchronized. This ioctl should be called whenever a fallback completes to flush CPU and chipset caches. --- shared-core/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 334bc43f..4d8a40d4 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -477,6 +477,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_pin_ioctl(struct drm_device *dev, void *data, -- cgit v1.2.3 From 918420deefb978d4e572121b4273d717bdbfde8e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jun 2008 00:21:37 -0700 Subject: [intel-gem] Use shmem_getpage instead of find_or_create_page find_or_create_page doesn't quite set up pages correctly; any newly created pages aren't hooked into the shmem object quite right; user space mmaps of those pages end up mapping pages full of zeros which then get written to the real pages inappropriately. This patch requires that the kernel export shmem_getpage. --- shared-core/i915_drv.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 4d8a40d4..94e80cda 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -332,6 +332,12 @@ struct drm_i915_gem_object { */ int active; + /** + * This is set if the object has been written to since last bound + * to the GTT + */ + int dirty; + /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; -- cgit v1.2.3 From 71b1623e22c54d42837840a1d0479127a5049caf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jun 2008 21:07:46 -0700 Subject: [intel-gem] Add intel-specific /proc entries to help monitor gem operation This adds gem_active, gem_flushing, gem_inactive, gem_request and gem_seqno entries to monitor gem operation and help debug issues. --- shared-core/i915_drv.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 94e80cda..87776504 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -289,6 +289,16 @@ typedef struct drm_i915_private { uint32_t next_gem_seqno; + /** + * Waiting sequence number, if any + */ + uint32_t waiting_gem_seqno; + + /** + * Last seq seen at irq time + */ + uint32_t irq_gem_seqno; + /** * Flag if the X Server, and thus DRM, is not currently in * control of the device. @@ -499,11 +509,14 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_proc_init(struct drm_minor *minor); +void i915_gem_proc_cleanup(struct drm_minor *minor); int i915_gem_init_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); void i915_gem_object_unpin(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); +uint32_t i915_get_gem_seqno(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); #endif -- cgit v1.2.3 From 33114e4a1167ac79cb53043e77c16cc7fe40a640 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 21 Jun 2008 00:12:21 -0700 Subject: [intel] Count received interrupts Another patch adds this to a /proc/dri file for debugging and monitoring. --- shared-core/i915_drv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 87776504..9f500330 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -119,7 +119,6 @@ typedef struct drm_i915_private { wait_queue_head_t irq_queue; atomic_t irq_received; - atomic_t irq_emitted; int tex_lru_log_granularity; int allow_batchbuffer; -- cgit v1.2.3 From ed73651d47a5f95c3436207144b70811366e4edd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 23 Jun 2008 10:16:35 -0700 Subject: [intel-gem] Recover resources from wedged hardware. Clean up queues, free objects. On the next entervt, unmark the hardware to let the user try again (presumably after resetting the chip). Someday we'll automatically recover... --- shared-core/i915_drv.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 9f500330..0df5af9c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -307,6 +307,15 @@ typedef struct drm_i915_private { * transitioned away from for kernel modesetting. */ int suspended; + + /** + * Flag if the hardware appears to be wedged. + * + * This is set when attempts to idle the device timeout. + * It prevents command submission from occuring and makes + * every pending request fail + */ + int wedged; } mm; } drm_i915_private_t; -- cgit v1.2.3 From a0474be4e78d678eb615b37aad355effb955ee19 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 11 Jul 2008 14:47:33 -0700 Subject: intel-gem: Add two new ioctls for managing tiling on objects. Various chips have exciting interactions between the CPU and the GPU's different ways of accessing interleaved memory, so we need some kernel assistance in determining how it works. Only fully tested on GM965 so far. --- shared-core/i915_drv.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 0df5af9c..a9a431c4 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -316,6 +316,11 @@ typedef struct drm_i915_private { * every pending request fail */ int wedged; + + /** Bit 6 swizzling required for X tiling */ + uint32_t bit_6_swizzle_x; + /** Bit 6 swizzling required for Y tiling */ + uint32_t bit_6_swizzle_y; } mm; } drm_i915_private_t; @@ -376,6 +381,9 @@ struct drm_i915_gem_object { /** Breadcrumb of last rendering to the buffer. */ uint32_t last_rendering_seqno; + + /** Current tiling mode for the object. */ + uint32_t tiling_mode; }; /** @@ -517,6 +525,11 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_set_tiling(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int i915_gem_get_tiling(struct drm_device *dev, void *data, + struct drm_file *file_priv); +void i915_gem_load(struct drm_device *dev); int i915_gem_proc_init(struct drm_minor *minor); void i915_gem_proc_cleanup(struct drm_minor *minor); int i915_gem_init_object(struct drm_gem_object *obj); @@ -529,6 +542,9 @@ void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); #endif +/* i915_gem_tiling.c */ +void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); + #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) extern void intel_init_chipset_flush_compat(struct drm_device *dev); @@ -585,6 +601,19 @@ void i915_ring_validate(struct drm_device *dev, const char *func, int line); extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); +/* MCH MMIO space */ +/** 915-945 and GM965 MCH register controlling DRAM channel access */ +#define DCC 0x200 +#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) +#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0) +#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) +#define DCC_ADDRESSING_MODE_MASK (3 << 0) +#define DCC_CHANNEL_XOR_DISABLE (1 << 10) + +/** 965 MCH register controlling DRAM channel configuration */ +#define CHDECMISC 0x111 +#define CHDECMISC_FLEXMEMORY (1 << 1) + /* Extended config space */ #define LBB 0xf4 -- cgit v1.2.3 From 67d15215660407b07265c37d60ea5cac8930cef9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 1 Jul 2008 12:31:37 -0700 Subject: intel-gem: Set up HWS when it needs a vaddr during GEM init. This requires an updated 2D driver to not try to set it up as well. --- shared-core/i915_drv.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a9a431c4..c57c292f 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -114,6 +114,7 @@ typedef struct drm_i915_private { uint32_t counter; unsigned int status_gfx_addr; drm_local_map_t hws_map; + struct drm_gem_object *hws_obj; unsigned int cpp; @@ -854,6 +855,11 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define RING_VALID 0x00000001 #define RING_INVALID 0x00000000 +/* Hardware status page address */ +#define HWS_PGA 0x2080 +#define HWS_ADDRESS_MASK 0xfffff000 +#define HWS_START_ADDRES_SHIFT 4 + /* Instruction parser error reg: */ #define IPEIR 0x2088 -- cgit v1.2.3 From 04ae66db1c517264cddc786be962fdd393c9c8ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 26 Jul 2008 19:51:58 -0700 Subject: intel-gem: Move debug-only functions to a separate file. --- shared-core/i915_drv.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c57c292f..99416e8d 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -72,6 +72,14 @@ struct drm_i915_validate_buffer; #endif +#define WATCH_COHERENCY 0 +#define WATCH_BUF 0 +#define WATCH_EXEC 0 +#define WATCH_LRU 0 +#define WATCH_RELOC 0 +#define WATCH_INACTIVE 0 +#define WATCH_PWRITE 0 + typedef struct _drm_i915_ring_buffer { int tail_mask; unsigned long Size; @@ -541,11 +549,25 @@ void i915_gem_lastclose(struct drm_device *dev); uint32_t i915_get_gem_seqno(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); +void i915_gem_clflush_object(struct drm_gem_object *obj); #endif /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); +/* i915_gem_debug.c */ +void i915_gem_dump_object(struct drm_gem_object *obj, int len, + const char *where, uint32_t mark); +#if WATCH_INACTIVE +void i915_verify_inactive(struct drm_device *dev, char *file, int line); +#else +#define i915_verify_inactive(dev,file,line) +#endif +void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle); +void i915_gem_dump_object(struct drm_gem_object *obj, int len, + const char *where, uint32_t mark); +void i915_dump_lru(struct drm_device *dev, const char *where); + #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) extern void intel_init_chipset_flush_compat(struct drm_device *dev); -- cgit v1.2.3 From f85fd1b42dc2d77266007c02144d4f4f524e4157 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 26 Jul 2008 19:28:14 -0700 Subject: intel-gem: Speed up tiled readpixels by tracking which pages have been flushed. This is around 3x or so speedup, since we would read wide rows at a time, and clflush each tile 8 times as a result. We'll want code related to this anyway when we do fault-based per-page clflushing for sw fallbacks. --- shared-core/i915_drv.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 99416e8d..7bb9e5bb 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -393,6 +393,12 @@ struct drm_i915_gem_object { /** Current tiling mode for the object. */ uint32_t tiling_mode; + + /** + * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when + * GEM_DOMAIN_CPU is not in the object's read domain. + */ + uint8_t *page_cpu_valid; }; /** -- cgit v1.2.3 From 487c42bd42d93304278abce03b36c935bdc83284 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 28 Jul 2008 11:45:22 -0700 Subject: intel-gem: Another checkpatch.pl pass. --- shared-core/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 7bb9e5bb..50319373 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -294,14 +294,14 @@ typedef struct drm_i915_private { * fires, go retire requests. */ struct delayed_work retire_work; - + uint32_t next_gem_seqno; /** * Waiting sequence number, if any */ uint32_t waiting_gem_seqno; - + /** * Last seq seen at irq time */ -- cgit v1.2.3 From 0e49e49c9f8fdbe77740c1bdcc0cb4102d26bf7a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 28 Jul 2008 23:14:11 -0700 Subject: intel: Fix typo in unused register definition name. --- shared-core/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 9d3a37df..3cd57c21 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -887,7 +887,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define ACTHD_I965 0x02074 #define HWS_PGA 0x02080 #define HWS_ADDRESS_MASK 0xfffff000 -#define HWS_START_ADDRES_SHIFT 4 +#define HWS_START_ADDRESS_SHIFT 4 #define IPEIR 0x02088 #define NOPID 0x02094 #define HWSTAM 0x02098 -- cgit v1.2.3 From 33c8e03787308c2b86a4f724ba7ce4dc43918b6a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 30 Jul 2008 11:22:48 -0700 Subject: Revert "Rename drm_mm.c and its fuctions to drm_memrange." This reverts commit 3ad8db2071d30c198403e605f2726fc5c3e46bfd. We ended up not needing that namespace, and I'd rather not have the churn for producing diffs. --- shared-core/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 3cd57c21..0ebdab0c 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -277,7 +277,7 @@ typedef struct drm_i915_private { u8 saveCR[37]; struct { - struct drm_memrange gtt_space; + struct drm_mm gtt_space; /** * List of objects currently involved in rendering from the @@ -378,7 +378,7 @@ struct drm_i915_gem_object { struct drm_gem_object *obj; /** Current space allocated to this object in the GTT, if any. */ - struct drm_memrange_node *gtt_space; + struct drm_mm_node *gtt_space; /** This object's place on the active/flushing/inactive lists */ struct list_head list; -- cgit v1.2.3 From ccbaad52f79162a77d98d0dde00681b1dbf14165 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 30 Jul 2008 14:10:36 -0700 Subject: intel-gem: Replace version bump signalling GEM with I915_PARAM_HAS_GEM. --- shared-core/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_drv.h') diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 0ebdab0c..fe52845e 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -37,7 +37,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20080611" +#define DRIVER_DATE "20080730" #if defined(__linux__) #define I915_HAVE_FENCE @@ -61,7 +61,7 @@ */ #define DRIVER_MAJOR 1 #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) -#define DRIVER_MINOR 14 +#define DRIVER_MINOR 13 #else #define DRIVER_MINOR 6 #endif -- cgit v1.2.3