From: "Timur Kristóf" <timur.kristof@gmail.com>
To: amd-gfx@lists.freedesktop.org, "Marek Olšák" <maraeo@gmail.com>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Christian König" <christian.koenig@amd.com>,
"Tvrtko Ursulin" <tursulin@ursulin.net>,
pierre-eric.pelloux-prayer@amd.com,
"Natalie Vock" <nat@pixelcluster.dev>,
"Lijo Lazar" <lijo.lazar@amd.com>,
"Felix Kuehling" <Felix.Kuehling@amd.com>
Cc: "Timur Kristóf" <timur.kristof@gmail.com>
Subject: [PATCH 03/12] drm/amdgpu/sdma: Refactor CIK SDMA functions to be per instance
Date: Mon, 7 Sep 2026 22:33:07 +0200 [thread overview]
Message-ID: <20260907203316.159103-4-timur.kristof@gmail.com> (raw)
In-Reply-To: <20260907203316.159103-1-timur.kristof@gmail.com>
This prepares the code for implementing recovery for CIK SDMA.
Reorganize the CIK SDMA code so that the functions that are
responsible for managing the SDMA engines take an instance ID
as an argument.
This makes it possible to manage the SDMA instances
independently of each other, which will enable us to
also use these functions to implement resetting and
recovering them independently.
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 272 ++++++++++++++------------
1 file changed, 142 insertions(+), 130 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index f444207fa550..78fea0621ed9 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -300,34 +300,36 @@ static void cik_sdma_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq
* cik_sdma_gfx_stop - stop the gfx async dma engines
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
*
* Stop the gfx async dma ring buffers (CIK).
*/
-static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
+static void cik_sdma_gfx_stop(struct amdgpu_device *adev, const u32 instance_id)
{
+ const u32 reg_offset = sdma_offsets[instance_id];
u32 rb_cntl;
- int i;
- for (i = 0; i < adev->sdma.num_instances; i++) {
- rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
- rb_cntl &= ~SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK;
- WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl);
- WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], 0);
- }
+ rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + reg_offset);
+ rb_cntl &= ~SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK;
+ WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset, rb_cntl);
+ WREG32(mmSDMA0_GFX_IB_CNTL + reg_offset, 0);
}
/**
* cik_ctx_switch_enable - stop the async dma engines context switch
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
* @enable: enable/disable the DMA MEs context switch.
*
* Halt or unhalt the async dma engines context switch (VI).
*/
-static void cik_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
+static void cik_ctx_switch_enable(struct amdgpu_device *adev,
+ const u32 instance_id,
+ const bool enable)
{
+ const u32 reg_offset = sdma_offsets[instance_id];
u32 f32_cntl, phase_quantum = 0;
- int i;
if (amdgpu_sdma_phase_quantum) {
unsigned value = amdgpu_sdma_phase_quantum;
@@ -353,176 +355,172 @@ static void cik_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
}
- for (i = 0; i < adev->sdma.num_instances; i++) {
- f32_cntl = RREG32(mmSDMA0_CNTL + sdma_offsets[i]);
- if (enable) {
- f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
- AUTO_CTXSW_ENABLE, 1);
- if (amdgpu_sdma_phase_quantum) {
- WREG32(mmSDMA0_PHASE0_QUANTUM + sdma_offsets[i],
- phase_quantum);
- WREG32(mmSDMA0_PHASE1_QUANTUM + sdma_offsets[i],
- phase_quantum);
- }
- } else {
- f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
- AUTO_CTXSW_ENABLE, 0);
+ f32_cntl = RREG32(mmSDMA0_CNTL + reg_offset);
+ if (enable) {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 1);
+ if (amdgpu_sdma_phase_quantum) {
+ WREG32(mmSDMA0_PHASE0_QUANTUM + reg_offset,
+ phase_quantum);
+ WREG32(mmSDMA0_PHASE1_QUANTUM + reg_offset,
+ phase_quantum);
}
-
- WREG32(mmSDMA0_CNTL + sdma_offsets[i], f32_cntl);
+ } else {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 0);
}
+
+ WREG32(mmSDMA0_CNTL + reg_offset, f32_cntl);
}
/**
* cik_sdma_enable - stop the async dma engines
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
* @enable: enable/disable the DMA MEs.
*
* Halt or unhalt the async dma engines (CIK).
*/
-static void cik_sdma_enable(struct amdgpu_device *adev, bool enable)
+static void cik_sdma_enable(struct amdgpu_device *adev,
+ const u32 instance_id,
+ const bool enable)
{
+ const u32 reg_offset = sdma_offsets[instance_id];
u32 me_cntl;
- int i;
if (!enable) {
- cik_sdma_gfx_stop(adev);
+ cik_sdma_gfx_stop(adev, instance_id);
}
- for (i = 0; i < adev->sdma.num_instances; i++) {
- me_cntl = RREG32(mmSDMA0_F32_CNTL + sdma_offsets[i]);
- if (enable)
- me_cntl &= ~SDMA0_F32_CNTL__HALT_MASK;
- else
- me_cntl |= SDMA0_F32_CNTL__HALT_MASK;
- WREG32(mmSDMA0_F32_CNTL + sdma_offsets[i], me_cntl);
- }
+ me_cntl = RREG32(mmSDMA0_F32_CNTL + reg_offset);
+ if (enable)
+ me_cntl &= ~SDMA0_F32_CNTL__HALT_MASK;
+ else
+ me_cntl |= SDMA0_F32_CNTL__HALT_MASK;
+ WREG32(mmSDMA0_F32_CNTL + reg_offset, me_cntl);
}
/**
* cik_sdma_gfx_resume - setup and start the async dma engines
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
*
* Set up the gfx DMA ring buffers and enable them (CIK).
* Returns 0 for success, error for failure.
*/
-static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
+static int cik_sdma_gfx_resume(struct amdgpu_device *adev, const u32 instance_id)
{
- struct amdgpu_ring *ring;
+ struct amdgpu_ring *const ring = &adev->sdma.instance[instance_id].ring;
+ const u32 reg_offset = sdma_offsets[instance_id];
u32 rb_cntl, ib_cntl;
u32 rb_bufsz;
- int i, j, r;
-
- for (i = 0; i < adev->sdma.num_instances; i++) {
- ring = &adev->sdma.instance[i].ring;
-
- mutex_lock(&adev->srbm_mutex);
- for (j = 0; j < 16; j++) {
- cik_srbm_select(adev, 0, 0, 0, j);
- /* SDMA GFX */
- WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + sdma_offsets[i], 0);
- WREG32(mmSDMA0_GFX_APE1_CNTL + sdma_offsets[i], 0);
- /* XXX SDMA RLC - todo */
- }
- cik_srbm_select(adev, 0, 0, 0, 0);
- mutex_unlock(&adev->srbm_mutex);
+ int j;
+
+ mutex_lock(&adev->srbm_mutex);
+ for (j = 0; j < 16; j++) {
+ cik_srbm_select(adev, 0, 0, 0, j);
+ /* SDMA GFX */
+ WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + reg_offset, 0);
+ WREG32(mmSDMA0_GFX_APE1_CNTL + reg_offset, 0);
+ /* XXX SDMA RLC - todo */
+ }
+ cik_srbm_select(adev, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
- WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i],
- adev->gfx.config.gb_addr_config & 0x70);
+ WREG32(mmSDMA0_TILING_CONFIG + reg_offset,
+ adev->gfx.config.gb_addr_config & 0x70);
- WREG32(mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0);
- WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0);
+ WREG32(mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
+ WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
- /* Set ring buffer size in dwords */
- rb_bufsz = order_base_2(ring->ring_size / 4);
- rb_cntl = rb_bufsz << 1;
+ /* Set ring buffer size in dwords */
+ rb_bufsz = order_base_2(ring->ring_size / 4);
+ rb_cntl = rb_bufsz << 1;
#ifdef __BIG_ENDIAN
- rb_cntl |= SDMA0_GFX_RB_CNTL__RB_SWAP_ENABLE_MASK |
- SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_SWAP_ENABLE_MASK;
+ rb_cntl |= SDMA0_GFX_RB_CNTL__RB_SWAP_ENABLE_MASK |
+ SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_SWAP_ENABLE_MASK;
#endif
- WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl);
+ WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset, rb_cntl);
- /* Initialize the ring buffer's read and write pointers */
- WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0);
- WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0);
- WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0);
- WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0);
+ /* Initialize the ring buffer's read and write pointers */
+ WREG32(mmSDMA0_GFX_RB_RPTR + reg_offset, 0);
+ WREG32(mmSDMA0_GFX_RB_WPTR + reg_offset, 0);
+ WREG32(mmSDMA0_GFX_IB_RPTR + reg_offset, 0);
+ WREG32(mmSDMA0_GFX_IB_OFFSET + reg_offset, 0);
- /* set the wb address whether it's enabled or not */
- WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i],
- upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF);
- WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + sdma_offsets[i],
- ((ring->rptr_gpu_addr) & 0xFFFFFFFC));
+ /* set the wb address whether it's enabled or not */
+ WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + reg_offset,
+ upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF);
+ WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + reg_offset,
+ ((ring->rptr_gpu_addr) & 0xFFFFFFFC));
- rb_cntl |= SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_ENABLE_MASK;
+ rb_cntl |= SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_ENABLE_MASK;
- WREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8);
- WREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i], ring->gpu_addr >> 40);
+ WREG32(mmSDMA0_GFX_RB_BASE + reg_offset, ring->gpu_addr >> 8);
+ WREG32(mmSDMA0_GFX_RB_BASE_HI + reg_offset, ring->gpu_addr >> 40);
- ring->wptr = 0;
- WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], ring->wptr << 2);
+ ring->wptr = 0;
+ WREG32(mmSDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2);
- /* enable DMA RB */
- WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i],
- rb_cntl | SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK);
+ /* enable DMA RB */
+ WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset,
+ rb_cntl | SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK);
- ib_cntl = SDMA0_GFX_IB_CNTL__IB_ENABLE_MASK;
+ ib_cntl = SDMA0_GFX_IB_CNTL__IB_ENABLE_MASK;
#ifdef __BIG_ENDIAN
- ib_cntl |= SDMA0_GFX_IB_CNTL__IB_SWAP_ENABLE_MASK;
+ ib_cntl |= SDMA0_GFX_IB_CNTL__IB_SWAP_ENABLE_MASK;
#endif
- /* enable DMA IBs */
- WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
- }
+ /* enable DMA IBs */
+ WREG32(mmSDMA0_GFX_IB_CNTL + reg_offset, ib_cntl);
- cik_sdma_enable(adev, true);
-
- for (i = 0; i < adev->sdma.num_instances; i++) {
- ring = &adev->sdma.instance[i].ring;
- r = amdgpu_ring_test_helper(ring);
- if (r)
- return r;
- }
+ cik_sdma_enable(adev, instance_id, true);
- return 0;
+ return amdgpu_ring_test_helper(ring);
}
/**
* cik_sdma_load_microcode - load the sDMA ME ucode
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
*
* Loads the sDMA0/1 ucode.
* Returns 0 for success, -EINVAL if the ucode is not available.
*/
-static int cik_sdma_load_microcode(struct amdgpu_device *adev)
+static int cik_sdma_load_microcode(struct amdgpu_device *adev, const u32 instance_id)
{
+ struct amdgpu_sdma_instance *const instance = &adev->sdma.instance[instance_id];
+ const u32 reg_offset = sdma_offsets[instance_id];
const struct sdma_firmware_header_v1_0 *hdr;
const __le32 *fw_data;
u32 fw_size;
- int i, j;
+ int j;
/* halt the MEs */
- cik_sdma_enable(adev, false);
+ cik_sdma_enable(adev, instance_id, false);
- for (i = 0; i < adev->sdma.num_instances; i++) {
- if (!adev->sdma.instance[i].fw)
- return -EINVAL;
- hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma.instance[i].fw->data;
- amdgpu_ucode_print_sdma_hdr(&hdr->header);
- fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
- adev->sdma.instance[i].fw_version = le32_to_cpu(hdr->header.ucode_version);
- adev->sdma.instance[i].feature_version = le32_to_cpu(hdr->ucode_feature_version);
- if (adev->sdma.instance[i].feature_version >= 20)
- adev->sdma.instance[i].burst_nop = true;
- fw_data = (const __le32 *)
- (adev->sdma.instance[i].fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
- WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], 0);
- for (j = 0; j < fw_size; j++)
- WREG32(mmSDMA0_UCODE_DATA + sdma_offsets[i], le32_to_cpup(fw_data++));
- WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], adev->sdma.instance[i].fw_version);
- }
+ if (!adev->sdma.instance[instance_id].fw)
+ return -EINVAL;
+
+ hdr = (const struct sdma_firmware_header_v1_0 *)instance->fw->data;
+ amdgpu_ucode_print_sdma_hdr(&hdr->header);
+
+ fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ instance->fw_version = le32_to_cpu(hdr->header.ucode_version);
+ instance->feature_version = le32_to_cpu(hdr->ucode_feature_version);
+
+ if (instance->feature_version >= 20)
+ instance->burst_nop = true;
+
+ fw_data = (const __le32 *)
+ (instance->fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+
+ WREG32(mmSDMA0_UCODE_ADDR + reg_offset, 0);
+ for (j = 0; j < fw_size; j++)
+ WREG32(mmSDMA0_UCODE_DATA + reg_offset, le32_to_cpup(fw_data++));
+ WREG32(mmSDMA0_UCODE_ADDR + reg_offset, instance->fw_version);
return 0;
}
@@ -531,29 +529,40 @@ static int cik_sdma_load_microcode(struct amdgpu_device *adev)
* cik_sdma_start - setup and start the async dma engines
*
* @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
*
* Set up the DMA engines and enable them (CIK).
* Returns 0 for success, error for failure.
*/
-static int cik_sdma_start(struct amdgpu_device *adev)
+static int cik_sdma_start(struct amdgpu_device *adev, const u32 instance_id)
{
int r;
- r = cik_sdma_load_microcode(adev);
+ r = cik_sdma_load_microcode(adev, instance_id);
if (r)
return r;
/* halt the engine before programing */
- cik_sdma_enable(adev, false);
+ cik_sdma_enable(adev, instance_id, false);
/* enable sdma ring preemption */
- cik_ctx_switch_enable(adev, true);
+ cik_ctx_switch_enable(adev, instance_id, true);
/* start the gfx rings and rlc compute queues */
- r = cik_sdma_gfx_resume(adev);
- if (r)
- return r;
+ return cik_sdma_gfx_resume(adev, instance_id);
+}
- return 0;
+/**
+ * cik_sdma_stop() - Stop an SDMA engine
+ *
+ * @adev: amdgpu_device pointer
+ * @instance_id: SDMA engine instance ID
+ *
+ * Stop the given SDMA engine instance (CIK).
+ */
+static void cik_sdma_stop(struct amdgpu_device *adev, const u32 instance_id)
+{
+ cik_ctx_switch_enable(adev, instance_id, false);
+ cik_sdma_enable(adev, instance_id, false);
}
/**
@@ -974,11 +983,13 @@ static int cik_sdma_sw_fini(struct amdgpu_ip_block *ip_block)
static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
- int r;
+ int i, r;
- r = cik_sdma_start(adev);
- if (r)
- return r;
+ for (i = 0; i < adev->sdma.num_instances; ++i) {
+ r = cik_sdma_start(adev, i);
+ if (r)
+ return r;
+ }
cik_sdma_set_buffer_funcs(adev);
@@ -988,9 +999,10 @@ static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
static int cik_sdma_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+ int i;
- cik_ctx_switch_enable(adev, false);
- cik_sdma_enable(adev, false);
+ for (i = 0; i < adev->sdma.num_instances; ++i)
+ cik_sdma_stop(adev, i);
return 0;
}
--
2.55.0
next prev parent reply other threads:[~2026-09-07 20:33 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 20:33 [PATCH 00/12] RFC: drm/amdgpu/sdma: Refactor SDMA v4 and older functions to be per-instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 01/12] drm/amdgpu/sdma: Refactor SI DMA functions to be per instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 02/12] drm/amdgpu/sdma: Refactor SI DMA clock gating functions to be per-instance Timur Kristóf
2026-09-07 20:33 ` Timur Kristóf [this message]
2026-09-07 20:33 ` [PATCH 04/12] drm/amdgpu/sdma: Refactor CIK SDMA " Timur Kristóf
2026-09-07 20:33 ` [PATCH 05/12] drm/amdgpu/sdma: Refactor SDMA v2.4 functions to be per instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 06/12] drm/amdgpu/sdma: Refactor SDMA v2.4 golden registers to be per-instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 07/12] drm/amdgpu/sdma: Refactor SDMA v3.0 functions to be per instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 08/12] drm/amdgpu/sdma: Refactor SDMA v3.0 clock gating functions to be per-instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 09/12] drm/amdgpu/sdma: Refactor SDMA v3.0 golden registers " Timur Kristóf
2026-09-07 20:33 ` [PATCH 10/12] drm/amdgpu/sdma: Refactor SDMA v4.0 functions to be per instance Timur Kristóf
2026-09-08 7:41 ` Tvrtko Ursulin
2026-09-08 8:14 ` Timur Kristóf
2026-09-10 14:44 ` Tvrtko Ursulin
2026-09-07 20:33 ` [PATCH 11/12] drm/amdgpu/sdma: Refactor SDMA v4.0 clock gating functions to be per-instance Timur Kristóf
2026-09-07 20:33 ` [PATCH 12/12] drm/amdgpu/sdma: Refactor SDMA v4.0 golden registers " Timur Kristóf
2026-09-11 19:00 ` [PATCH 00/12] RFC: drm/amdgpu/sdma: Refactor SDMA v4 and older functions " Alex Deucher
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=20260907203316.159103-4-timur.kristof@gmail.com \
--to=timur.kristof@gmail.com \
--cc=Felix.Kuehling@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=christian.koenig@amd.com \
--cc=lijo.lazar@amd.com \
--cc=maraeo@gmail.com \
--cc=nat@pixelcluster.dev \
--cc=pierre-eric.pelloux-prayer@amd.com \
--cc=tursulin@ursulin.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox