All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zou Nan hai <nanhai.zou@intel.com>
To: Anholt Eric <eric.anholt@intel.com>,
	Intel GFX <intel-gfx@lists.freedesktop.org>
Subject: [PATCH 3/4] add BSD ring buffer support
Date: Thu,  6 May 2010 09:20:04 +0800	[thread overview]
Message-ID: <1273108805-1354-3-git-send-email-nanhai.zou@intel.com> (raw)
In-Reply-To: <1273108805-1354-1-git-send-email-nanhai.zou@intel.com>

add BSD ring buffer support on GM45+ systems.
BSD (bit-stream-decoder) engine is a GPU engine for H.264/VC1
VLD decoding.

Signed-off-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Zou Nanhai <nanhai.zou@intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c         |    2 +
 drivers/gpu/drm/i915/i915_drv.h         |    2 +
 drivers/gpu/drm/i915/i915_gem.c         |   76 ++--------
 drivers/gpu/drm/i915/i915_reg.h         |   16 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c |  232 ++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_ringbuffer.h |    6 +
 6 files changed, 252 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 88ec88c..063f355 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -128,6 +128,8 @@ static int i915_dma_cleanup(struct drm_device * dev)
 		drm_irq_uninstall(dev);
 
 	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+	if (HAS_BSD(dev))
+		intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
 
 	/* Clear the HWS virtual address at teardown */
 	if (I915_NEED_GFX_HWS(dev))
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 83d6e9b..ee0a15e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -238,6 +238,7 @@ typedef struct drm_i915_private {
 
 	struct pci_dev *bridge_dev;
 	struct intel_ring_buffer render_ring;
+	struct intel_ring_buffer bsd_ring;
 
 
 	drm_dma_handle_t *status_page_dmah;
@@ -1120,6 +1121,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 			 (dev)->pci_device == 0x2A42 ||		\
 			 (dev)->pci_device == 0x2E42)
 
+#define HAS_BSD(dev)           (IS_IRONLAKE(dev) || IS_G4X(dev))
 #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7b8fa88..450c67e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1887,70 +1887,17 @@ i915_gem_flush(struct drm_device *dev,
 	       uint32_t flush_domains)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t cmd;
-
-#if WATCH_EXEC
-	DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
-		  invalidate_domains, flush_domains);
-#endif
-	trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno,
-				     invalidate_domains, flush_domains);
-
 	if (flush_domains & I915_GEM_DOMAIN_CPU)
 		drm_agp_chipset_flush(dev);
 
-	if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
-		/*
-		 * read/write caches:
-		 *
-		 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
-		 * only flushed if MI_NO_WRITE_FLUSH is unset.  On 965, it is
-		 * also flushed at 2d versus 3d pipeline switches.
-		 *
-		 * read-only caches:
-		 *
-		 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
-		 * MI_READ_FLUSH is set, and is always flushed on 965.
-		 *
-		 * I915_GEM_DOMAIN_COMMAND may not exist?
-		 *
-		 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
-		 * invalidated when MI_EXE_FLUSH is set.
-		 *
-		 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
-		 * invalidated with every MI_FLUSH.
-		 *
-		 * TLBs:
-		 *
-		 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
-		 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
-		 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
-		 * are flushed at any MI_FLUSH.
-		 */
-
-		cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
-		if ((invalidate_domains|flush_domains) &
-		    I915_GEM_DOMAIN_RENDER)
-			cmd &= ~MI_NO_WRITE_FLUSH;
-		if (!IS_I965G(dev)) {
-			/*
-			 * On the 965, the sampler cache always gets flushed
-			 * and this bit is reserved.
-			 */
-			if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
-				cmd |= MI_READ_FLUSH;
-		}
-		if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
-			cmd |= MI_EXE_FLUSH;
+	dev_priv->render_ring.flush(dev, &dev_priv->render_ring,
+			invalidate_domains,
+			flush_domains);
 
-#if WATCH_EXEC
-		DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
-#endif
-		BEGIN_LP_RING(2);
-		OUT_RING(cmd);
-		OUT_RING(MI_NOOP);
-		ADVANCE_LP_RING();
-	}
+	if (HAS_BSD(dev))
+		dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring,
+				invalidate_domains,
+				flush_domains);
 }
 
 /**
@@ -4552,10 +4499,14 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
 	if (!I915_NEED_GFX_HWS(dev)) {
 		dev_priv->render_ring.status_page.page_addr
 			= dev_priv->status_page_dmah->vaddr;
-		memset(dev_priv->render_ring.status_page.page_addr
+		memset(dev_priv->render_ring.status_page.page_addr,
 			0, PAGE_SIZE);
 	}
 	ret = intel_init_ring_buffer(dev, &dev_priv->render_ring);
+	if (!ret && HAS_BSD(dev)) {
+		dev_priv->bsd_ring = bsd_ring;
+		ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring);
+	}
 	return ret;
 }
 
@@ -4564,6 +4515,9 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+	if (HAS_BSD(dev))
+		intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
+
 }
 
 int
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 527d30a..64f6bba 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -324,6 +324,7 @@
 #define   I915_DEBUG_INTERRUPT				(1<<2)
 #define   I915_USER_INTERRUPT				(1<<1)
 #define   I915_ASLE_INTERRUPT				(1<<0)
+#define   I915_BSD_USER_INTERRUPT                      (1<<25)
 #define EIR		0x020b0
 #define EMR		0x020b4
 #define ESR		0x020b8
@@ -358,6 +359,18 @@
 #define BB_ADDR		0x02140 /* 8 bytes */
 #define GFX_FLSH_CNTL	0x02170 /* 915+ only */
 
+/*
+ * BSD (bit stream decoder instruction and interrupt control register defines
+ * (G4X and Ironlake only)
+ */
+
+#define BSD_RING_TAIL          0x04030
+#define BSD_RING_HEAD          0x04034
+#define BSD_RING_START         0x04038
+#define BSD_RING_CTL           0x0403c
+#define BSD_RING_ACTHD         0x04074
+#define BSD_HWS_PGA            0x04080
+
 
 /*
  * Framebuffer compression (915+ only)
@@ -2342,6 +2355,9 @@
 #define GT_SYNC_STATUS          (1 << 2)
 #define GT_USER_INTERRUPT       (1 << 0)
 
+#define GT_BSD_USER_INTERRUPT          (1 << 5)
+
+
 #define GTISR   0x44010
 #define GTIMR   0x44014
 #define GTIIR   0x44018
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 33e4fde..4df70fe 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -130,8 +130,7 @@ static void render_ring_advance_ring(struct drm_device *dev,
 	I915_WRITE(PRB0_TAIL, ring->tail);
 }
 
-
-static int init_render_ring(struct drm_device *dev,
+static int init_ring_common(struct drm_device *dev,
 		struct intel_ring_buffer *ring)
 {
 	u32 head;
@@ -140,12 +139,12 @@ static int init_render_ring(struct drm_device *dev,
 	obj_priv = ring->gem_object->driver_private;
 
 	/* Stop the ring if it's running. */
-	I915_WRITE(PRB0_CTL, 0);
-	I915_WRITE(PRB0_HEAD, 0);
-	I915_WRITE(PRB0_TAIL, 0);
+	I915_WRITE(ring->regs.ctl, 0);
+	I915_WRITE(ring->regs.head, 0);
+	I915_WRITE(ring->regs.tail, 0);
 
 	/* Initialize the ring. */
-	I915_WRITE(PRB0_START, obj_priv->gtt_offset);
+	I915_WRITE(ring->regs.start, obj_priv->gtt_offset);
 	head = ring->get_head(dev, ring);
 
 	/* G45 ring initialization fails to reset head to zero */
@@ -153,35 +152,36 @@ static int init_render_ring(struct drm_device *dev,
 		DRM_ERROR("%s head not reset to zero "
 				"ctl %08x head %08x tail %08x start %08x\n",
 				ring->name,
-				I915_READ(PRB0_CTL),
-				I915_READ(PRB0_HEAD),
-				I915_READ(PRB0_TAIL),
-				I915_READ(PRB0_START));
-		I915_WRITE(PRB0_HEAD, 0);
+				I915_READ(ring->regs.ctl),
+				I915_READ(ring->regs.head),
+				I915_READ(ring->regs.tail),
+				I915_READ(ring->regs.start));
+
+		I915_WRITE(ring->regs.head, 0);
 
 		DRM_ERROR("%s head forced to zero "
 				"ctl %08x head %08x tail %08x start %08x\n",
 				ring->name,
-				I915_READ(PRB0_CTL),
-				I915_READ(PRB0_HEAD),
-				I915_READ(PRB0_TAIL),
-				I915_READ(PRB0_START));
+				I915_READ(ring->regs.ctl),
+				I915_READ(ring->regs.head),
+				I915_READ(ring->regs.tail),
+				I915_READ(ring->regs.start));
 	}
 
-	I915_WRITE(PRB0_CTL,
+	I915_WRITE(ring->regs.ctl,
 			((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
 			| RING_NO_REPORT | RING_VALID);
 
-	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+	head = I915_READ(ring->regs.head) & HEAD_ADDR;
 	/* If the head is still not zero, the ring is dead */
 	if (head != 0) {
 		DRM_ERROR("%s initialization failed "
 				"ctl %08x head %08x tail %08x start %08x\n",
 				ring->name,
-				I915_READ(PRB0_CTL),
-				I915_READ(PRB0_HEAD),
-				I915_READ(PRB0_TAIL),
-				I915_READ(PRB0_START));
+				I915_READ(ring->regs.ctl),
+				I915_READ(ring->regs.head),
+				I915_READ(ring->regs.tail),
+				I915_READ(ring->regs.start));
 		return -EIO;
 	}
 
@@ -197,6 +197,12 @@ static int init_render_ring(struct drm_device *dev,
 	return 0;
 }
 
+static int init_render_ring(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	return init_ring_common(dev, ring);
+}
+
 
 static u32
 render_ring_add_request(struct drm_device *dev,
@@ -273,6 +279,143 @@ static void render_setup_status_page(struct drm_device *dev,
 	(void)I915_READ(HWS_PGA);
 }
 
+void
+bsd_ring_flush(struct drm_device *dev,
+		struct intel_ring_buffer *ring,
+		u32     invalidate_domains,
+		u32     flush_domains)
+{
+	intel_ring_begin(dev, ring, 8);
+	intel_ring_emit(dev, ring, MI_FLUSH);
+	intel_ring_emit(dev, ring, MI_NOOP);
+	intel_ring_advance(dev, ring);
+}
+
+static inline unsigned int bsd_ring_get_head(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	return I915_READ(BSD_RING_HEAD) & HEAD_ADDR;
+}
+
+static inline unsigned int bsd_ring_get_tail(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	return I915_READ(BSD_RING_TAIL) & TAIL_ADDR;
+}
+
+static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	return I915_READ(BSD_RING_ACTHD);
+}
+
+static inline void bsd_ring_advance_ring(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	I915_WRITE(BSD_RING_TAIL, ring->tail);
+}
+
+static int init_bsd_ring(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	return init_ring_common(dev, ring);
+}
+
+static u32
+bsd_ring_add_request(struct drm_device *dev,
+		struct intel_ring_buffer *ring,
+		struct drm_file *file_priv,
+		u32 flush_domains)
+{
+	u32 seqno;
+	seqno = intel_ring_get_seqno(dev, ring);
+	intel_ring_begin(dev, ring, 4);
+	intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
+	intel_ring_emit(dev, ring,
+			I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+	intel_ring_emit(dev, ring, seqno);
+	intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
+	intel_ring_advance(dev, ring);
+
+	DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
+
+	return seqno;
+}
+
+static void bsd_setup_status_page(struct drm_device *dev,
+		struct  intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr);
+	I915_READ(BSD_HWS_PGA);
+}
+
+static void
+bsd_ring_get_user_irq(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+	if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) {
+		if (IS_IRONLAKE(dev))
+			ironlake_enable_graphics_irq(dev_priv,
+					GT_BSD_USER_INTERRUPT);
+		else
+			i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
+	}
+	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
+
+}
+
+static void
+bsd_ring_put_user_irq(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+	BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0);
+	if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) {
+		if (IS_IRONLAKE(dev))
+			ironlake_disable_graphics_irq(dev_priv,
+					GT_BSD_USER_INTERRUPT);
+		else
+			i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
+	}
+	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
+}
+
+static u32
+bsd_ring_get_gem_seqno(struct drm_device *dev,
+		struct intel_ring_buffer *ring)
+{
+	return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
+}
+
+static int
+bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev,
+		struct intel_ring_buffer *ring,
+		struct drm_i915_gem_execbuffer2 *exec,
+		struct drm_clip_rect *cliprects,
+		uint64_t exec_offset)
+{
+	uint32_t exec_start;
+	exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
+	intel_ring_begin(dev, ring, 2);
+	intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START |
+			(2 << 6) | MI_BATCH_NON_SECURE_I965);
+	intel_ring_emit(dev, ring, exec_start);
+	intel_ring_advance(dev, ring);
+	return 0;
+}
+
 
 static int
 render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
@@ -340,6 +483,7 @@ static void cleanup_status_page(struct drm_device *dev, struct intel_ring_buffer
 
 	memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
 }
+
 static int init_status_page(struct drm_device *dev, struct intel_ring_buffer *ring)
 {
 	struct drm_i915_gem_object *obj_priv;
@@ -560,6 +704,12 @@ u32 intel_ring_get_seqno(struct drm_device *dev,
 
 struct intel_ring_buffer render_ring = {
 	.name 			= "render ring",
+	.regs                   = {
+		.ctl = PRB0_CTL,
+		.head = PRB0_HEAD,
+		.tail = PRB0_TAIL,
+		.start = PRB0_START
+	},
 	.ring_flag		= I915_EXEC_RENDER,
 	.size 			= 32 * PAGE_SIZE,
 	.alignment 		= PAGE_SIZE,
@@ -588,3 +738,43 @@ struct intel_ring_buffer render_ring = {
 	.status_page		= {NULL, 0, NULL},
 	.map 			= {0,}
 };
+
+/* ring buffer for bit-stream decoder */
+
+struct intel_ring_buffer bsd_ring = {
+	.name                   = "bsd ring",
+	.regs			= {
+		.ctl = BSD_RING_CTL,
+		.head = BSD_RING_HEAD,
+		.tail = BSD_RING_TAIL,
+		.start = BSD_RING_START
+	},
+	.ring_flag              = I915_EXEC_BSD,
+	.size                   = 32 * PAGE_SIZE,
+	.alignment              = PAGE_SIZE,
+	.virtual_start          = NULL,
+	.dev                    = NULL,
+	.gem_object             = NULL,
+	.head                   = 0,
+	.tail                   = 0,
+	.space                  = 0,
+	.next_seqno             = 1,
+	.user_irq_refcount      = 0,
+	.irq_gem_seqno          = 0,
+	.waiting_gem_seqno      = 0,
+	.setup_status_page      = bsd_setup_status_page,
+	.init                   = init_bsd_ring,
+	.get_head               = bsd_ring_get_head,
+	.get_tail               = bsd_ring_get_tail,
+	.get_active_head        = bsd_ring_get_active_head,
+	.advance_ring           = bsd_ring_advance_ring,
+	.flush                  = bsd_ring_flush,
+	.add_request            = bsd_ring_add_request,
+	.get_gem_seqno          = bsd_ring_get_gem_seqno,
+	.user_irq_get           = bsd_ring_get_user_irq,
+	.user_irq_put           = bsd_ring_put_user_irq,
+	.dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer,
+	.status_page            = {NULL, 0, NULL},
+	.map                    = {0,}
+};
+
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index e3b40d1..b1748b6 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -10,6 +10,12 @@ struct  intel_hw_status_page {
 struct drm_i915_gem_execbuffer2;
 struct  intel_ring_buffer {
 	const char	*name;
+	struct		ring_regs {
+			u32 ctl;
+			u32 head;
+			u32 tail;
+			u32 start;
+	} regs;
 	unsigned int	ring_flag;	
 	unsigned long	size;
 	unsigned int  	alignment;
-- 
1.7.1

  parent reply	other threads:[~2010-05-06  1:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-06  1:20 [PATCH 1/4] introduce intel_ring_buffer structure Zou Nan hai
2010-05-06  1:20 ` [PATCH 2/4] convert render engine to use intel_ring_buffer Zou Nan hai
2010-05-06  1:20 ` Zou Nan hai [this message]
2010-05-06  1:20 ` [PATCH 4/4] adapt intel_ring_buffer into gem Zou Nan hai
2010-05-07 21:34 ` [PATCH 1/4] introduce intel_ring_buffer structure Eric Anholt
2010-05-08 18:15   ` Thomas Bächler
2010-05-11 22:24 ` Daniel Vetter
2010-05-14  1:39   ` Zou, Nanhai
2010-05-14  9:51     ` Daniel Vetter
2010-05-14 15:03       ` Daniel Vetter
2010-05-17  1:59         ` Zou, Nanhai
2010-05-17 17:52           ` Daniel Vetter
2010-05-14 17:43     ` Owain Ainsworth
2010-05-17  1:43       ` Zou, Nanhai
2010-05-17 17:42         ` Daniel Vetter
2010-05-18  2:20           ` Zou, Nanhai
2010-05-18 16:19             ` Simon Farnsworth
2010-05-19  1:09               ` Zou, Nanhai
2010-05-19  9:00                 ` Simon Farnsworth
2010-05-19 16:54                   ` Eric Anholt
2010-05-19 17:33                     ` Simon Farnsworth
  -- strict thread matches above, loose matches on Subject: below --
2010-05-05  3:17 Zou Nan hai
2010-05-05  3:17 ` [PATCH 3/4] add BSD ring buffer support Zou Nan hai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1273108805-1354-3-git-send-email-nanhai.zou@intel.com \
    --to=nanhai.zou@intel.com \
    --cc=eric.anholt@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.