All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads
@ 2026-09-28 10:31 Victor Zhao
  2026-09-28 10:31 ` [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF Victor Zhao
  2026-09-28 12:53 ` [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Lazar, Lijo
  0 siblings, 2 replies; 4+ messages in thread
From: Victor Zhao @ 2026-09-28 10:31 UTC (permalink / raw)
  To: amd-gfx, Lijo.Lazar, Alexander.Deucher, Shaoyun.Liu
  Cc: Davis.Ming, Gavin.Wan, Victor Zhao

[why]
Some register values span two consecutive dwords and must be sampled
with one MES operation.

[how]
Add amdgpu_mes_rreg64(), set READ_REG read64Bits for MES 11 and
MES 12, and combine the two returned dwords into a 64-bit value.
Reject 64-bit reads on MES 11 scheduler firmware older than 0x42,
which predates read64Bits support.

v2: add MES 11 support with the same read64Bits option
v3: return read status separately and require MES 11 firmware 0x42 or newer

Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 43 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  3 ++
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  6 +++
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c        |  2 +
 drivers/gpu/drm/amd/amdgpu/mes_v12_1.c        |  2 +
 drivers/gpu/drm/amd/include/mes_v11_api_def.h |  7 +++
 6 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 5bebe74de01ad..3be6e577a8aa7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -582,6 +582,7 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
 	op_input.op = MES_MISC_OP_READ_REG;
 	op_input.read_reg.reg_offset = reg;
 	op_input.read_reg.buffer_addr = read_val_gpu_addr;
+	op_input.read_reg.read64_bits = false;
 
 	if (!adev->mes.funcs->misc_op) {
 		dev_err(adev->dev, "mes rreg is not supported!\n");
@@ -602,6 +603,48 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
 	return val;
 }
 
+int amdgpu_mes_rreg64(struct amdgpu_device *adev, uint32_t reg,
+		      uint32_t xcc_id, uint64_t *val)
+{
+	struct mes_misc_op_input op_input = { 0 };
+	uint32_t addr_offset;
+	uint32_t *read_val_ptr;
+	int r;
+
+	r = amdgpu_wb_get(adev, &addr_offset);
+	if (r) {
+		dev_err(adev->dev, "critical bug! too many mes readers\n");
+		return r;
+	}
+
+	read_val_ptr = (uint32_t *)&adev->wb.wb[addr_offset];
+	op_input.xcc_id = xcc_id;
+	op_input.op = MES_MISC_OP_READ_REG;
+	op_input.read_reg.reg_offset = reg;
+	op_input.read_reg.buffer_addr = adev->wb.gpu_addr + addr_offset * 4;
+	op_input.read_reg.read64_bits = true;
+
+	if (!adev->mes.funcs->misc_op) {
+		dev_err(adev->dev, "mes rreg is not supported!\n");
+		r = -EINVAL;
+		goto error;
+	}
+
+	amdgpu_mes_lock(&adev->mes);
+	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
+	amdgpu_mes_unlock(&adev->mes);
+	if (r) {
+		dev_err(adev->dev, "failed to read reg (0x%x)\n", reg);
+	} else {
+		*val = READ_ONCE(read_val_ptr[0]);
+		*val |= (uint64_t)READ_ONCE(read_val_ptr[1]) << 32;
+	}
+
+error:
+	amdgpu_wb_free(adev, addr_offset);
+	return r;
+}
+
 int amdgpu_mes_wreg(struct amdgpu_device *adev, uint32_t reg,
 		    uint32_t val, uint32_t xcc_id)
 {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index 33a426f58e723..1e801f427ddb2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -373,6 +373,7 @@ struct mes_misc_op_input {
 		struct {
 			uint32_t                  reg_offset;
 			uint64_t                  buffer_addr;
+			bool                      read64_bits;
 		} read_reg;
 
 		struct {
@@ -545,6 +546,8 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
 
 uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
 			 uint32_t xcc_id);
+int amdgpu_mes_rreg64(struct amdgpu_device *adev, uint32_t reg,
+		      uint32_t xcc_id, uint64_t *val);
 int amdgpu_mes_wreg(struct amdgpu_device *adev,
 		    uint32_t reg, uint32_t val, uint32_t xcc_id);
 int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index d8b4d3deff605..ef82f7536e449 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -902,9 +902,15 @@ static int mes_v11_0_misc_op(struct amdgpu_mes *mes,
 
 	switch (input->op) {
 	case MES_MISC_OP_READ_REG:
+		if (input->read_reg.read64_bits &&
+		    (mes->sched_version & AMDGPU_MES_VERSION_MASK) < 0x42)
+			return -EOPNOTSUPP;
+
 		misc_pkt.opcode = MESAPI_MISC__READ_REG;
 		misc_pkt.read_reg.reg_offset = input->read_reg.reg_offset;
 		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
+		misc_pkt.read_reg.option.bits.read64Bits =
+			input->read_reg.read64_bits;
 		break;
 	case MES_MISC_OP_WRITE_REG:
 		misc_pkt.opcode = MESAPI_MISC__WRITE_REG;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 04465804c2544..0d2a60528802e 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -858,6 +858,8 @@ static int mes_v12_0_misc_op(struct amdgpu_mes *mes,
 		misc_pkt.opcode = MESAPI_MISC__READ_REG;
 		misc_pkt.read_reg.reg_offset = input->read_reg.reg_offset;
 		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
+		misc_pkt.read_reg.option.bits.read64Bits =
+			input->read_reg.read64_bits;
 		break;
 	case MES_MISC_OP_WRITE_REG:
 		misc_pkt.opcode = MESAPI_MISC__WRITE_REG;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
index d17ced46d5f73..e0a488e516c09 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
@@ -581,6 +581,8 @@ static int mes_v12_1_misc_op(struct amdgpu_mes *mes,
 	case MES_MISC_OP_READ_REG:
 		misc_pkt.opcode = MESAPI_MISC__READ_REG;
 		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
+		misc_pkt.read_reg.option.bits.read64Bits =
+			input->read_reg.read64_bits;
 		mes_v12_1_get_rrmt(input->read_reg.reg_offset,
 				   GET_INST(GC, input->xcc_id),
 				   &misc_pkt.read_reg.rrmt_opt,
diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
index 1fe824b41f2a5..b27ec78da3b08 100644
--- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
+++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
@@ -635,6 +635,13 @@ struct WRITE_REG {
 struct READ_REG {
 	uint32_t                  reg_offset;
 	uint64_t                  buffer_addr;
+	union {
+		struct {
+			uint32_t read64Bits : 1;
+			uint32_t reserved : 31;
+		} bits;
+		uint32_t all;
+	} option;
 };
 
 enum WRM_OPERATION {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF
  2026-09-28 10:31 [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Victor Zhao
@ 2026-09-28 10:31 ` Victor Zhao
  2026-09-28 12:54   ` Lazar, Lijo
  2026-09-28 12:53 ` [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Lazar, Lijo
  1 sibling, 1 reply; 4+ messages in thread
From: Victor Zhao @ 2026-09-28 10:31 UTC (permalink / raw)
  To: amd-gfx, Lijo.Lazar, Alexander.Deucher, Shaoyun.Liu
  Cc: Davis.Ming, Gavin.Wan, Victor Zhao

[why]
VF timestamp queries need a TSC sample independent of CP/MES.
The SMUIO path is not safe on VF.

[how]
Capture via RLC_CAPTURE_GPU_CLOCK_COUNT and read the consecutive
count registers with amdgpu_mes_rreg64().

v3: check errors returned by amdgpu_mes_rreg64()

Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c | 27 ++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
index d6f70d33201a0..83be620d7204b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
@@ -3168,10 +3168,37 @@ static int gfx_v12_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
 	return -ETIMEDOUT;
 }
 
+static uint64_t gfx_v12_1_get_rlc_gpu_clock_counter(struct amdgpu_device *adev)
+{
+	uint64_t clock = 0;
+	uint32_t reg;
+
+	if (!down_read_trylock(&adev->reset_domain->sem))
+		return 0;
+	if (amdgpu_device_skip_hw_access(adev) ||
+	    !adev->mes.ring[0].sched.ready)
+		goto unlock_reset;
+
+	mutex_lock(&adev->gfx.gpu_clock_mutex);
+	WREG32_SOC15(GC, GET_INST(GC, 0), regRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+	reg = SOC15_REG_OFFSET(GC, GET_INST(GC, 0),
+			       regRLC_GPU_CLOCK_COUNT_LSB);
+	if (amdgpu_mes_rreg64(adev, reg, 0, &clock))
+		clock = 0;
+	mutex_unlock(&adev->gfx.gpu_clock_mutex);
+
+unlock_reset:
+	up_read(&adev->reset_domain->sem);
+	return clock;
+}
+
 static uint64_t gfx_v12_1_get_gpu_clock_counter(struct amdgpu_device *adev)
 {
 	uint64_t clock = 0;
 
+	if (amdgpu_sriov_vf(adev))
+		return gfx_v12_1_get_rlc_gpu_clock_counter(adev);
+
 	if (adev->smuio.funcs &&
 	    adev->smuio.funcs->get_gpu_clock_counter)
 		clock = adev->smuio.funcs->get_gpu_clock_counter(adev);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads
  2026-09-28 10:31 [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Victor Zhao
  2026-09-28 10:31 ` [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF Victor Zhao
@ 2026-09-28 12:53 ` Lazar, Lijo
  1 sibling, 0 replies; 4+ messages in thread
From: Lazar, Lijo @ 2026-09-28 12:53 UTC (permalink / raw)
  To: Victor Zhao, amd-gfx, Alexander.Deucher, Shaoyun.Liu
  Cc: Davis.Ming, Gavin.Wan



On 28-Sep-26 4:01 PM, Victor Zhao wrote:
> [why]
> Some register values span two consecutive dwords and must be sampled
> with one MES operation.
> 
> [how]
> Add amdgpu_mes_rreg64(), set READ_REG read64Bits for MES 11 and
> MES 12, and combine the two returned dwords into a 64-bit value.
> Reject 64-bit reads on MES 11 scheduler firmware older than 0x42,
> which predates read64Bits support.
> 
> v2: add MES 11 support with the same read64Bits option
> v3: return read status separately and require MES 11 firmware 0x42 or newer
> 
> Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 43 +++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  3 ++
>   drivers/gpu/drm/amd/amdgpu/mes_v11_0.c        |  6 +++
>   drivers/gpu/drm/amd/amdgpu/mes_v12_0.c        |  2 +
>   drivers/gpu/drm/amd/amdgpu/mes_v12_1.c        |  2 +
>   drivers/gpu/drm/amd/include/mes_v11_api_def.h |  7 +++
>   6 files changed, 63 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> index 5bebe74de01ad..3be6e577a8aa7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> @@ -582,6 +582,7 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
>   	op_input.op = MES_MISC_OP_READ_REG;
>   	op_input.read_reg.reg_offset = reg;
>   	op_input.read_reg.buffer_addr = read_val_gpu_addr;
> +	op_input.read_reg.read64_bits = false;
>   
>   	if (!adev->mes.funcs->misc_op) {
>   		dev_err(adev->dev, "mes rreg is not supported!\n");
> @@ -602,6 +603,48 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
>   	return val;
>   }
>   
> +int amdgpu_mes_rreg64(struct amdgpu_device *adev, uint32_t reg,
> +		      uint32_t xcc_id, uint64_t *val)
> +{
> +	struct mes_misc_op_input op_input = { 0 };
> +	uint32_t addr_offset;
> +	uint32_t *read_val_ptr;
> +	int r;
> +
> +	r = amdgpu_wb_get(adev, &addr_offset);
> +	if (r) {
> +		dev_err(adev->dev, "critical bug! too many mes readers\n");
> +		return r;
> +	}
> +
> +	read_val_ptr = (uint32_t *)&adev->wb.wb[addr_offset];

read_val_ptr may be declared/assigned as u64* and used during read back.

That aside, this looks good.

Thanks,
Lijo

> +	op_input.xcc_id = xcc_id;
> +	op_input.op = MES_MISC_OP_READ_REG;
> +	op_input.read_reg.reg_offset = reg;
> +	op_input.read_reg.buffer_addr = adev->wb.gpu_addr + addr_offset * 4;
> +	op_input.read_reg.read64_bits = true;
> +
> +	if (!adev->mes.funcs->misc_op) {
> +		dev_err(adev->dev, "mes rreg is not supported!\n");
> +		r = -EINVAL;
> +		goto error;
> +	}
> +
> +	amdgpu_mes_lock(&adev->mes);
> +	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
> +	amdgpu_mes_unlock(&adev->mes);
> +	if (r) {
> +		dev_err(adev->dev, "failed to read reg (0x%x)\n", reg);
> +	} else {
> +		*val = READ_ONCE(read_val_ptr[0]);
> +		*val |= (uint64_t)READ_ONCE(read_val_ptr[1]) << 32;
> +	}
> +
> +error:
> +	amdgpu_wb_free(adev, addr_offset);
> +	return r;
> +}
> +
>   int amdgpu_mes_wreg(struct amdgpu_device *adev, uint32_t reg,
>   		    uint32_t val, uint32_t xcc_id)
>   {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> index 33a426f58e723..1e801f427ddb2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> @@ -373,6 +373,7 @@ struct mes_misc_op_input {
>   		struct {
>   			uint32_t                  reg_offset;
>   			uint64_t                  buffer_addr;
> +			bool                      read64_bits;
>   		} read_reg;
>   
>   		struct {
> @@ -545,6 +546,8 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
>   
>   uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg,
>   			 uint32_t xcc_id);
> +int amdgpu_mes_rreg64(struct amdgpu_device *adev, uint32_t reg,
> +		      uint32_t xcc_id, uint64_t *val);
>   int amdgpu_mes_wreg(struct amdgpu_device *adev,
>   		    uint32_t reg, uint32_t val, uint32_t xcc_id);
>   int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> index d8b4d3deff605..ef82f7536e449 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> @@ -902,9 +902,15 @@ static int mes_v11_0_misc_op(struct amdgpu_mes *mes,
>   
>   	switch (input->op) {
>   	case MES_MISC_OP_READ_REG:
> +		if (input->read_reg.read64_bits &&
> +		    (mes->sched_version & AMDGPU_MES_VERSION_MASK) < 0x42)
> +			return -EOPNOTSUPP;
> +
>   		misc_pkt.opcode = MESAPI_MISC__READ_REG;
>   		misc_pkt.read_reg.reg_offset = input->read_reg.reg_offset;
>   		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
> +		misc_pkt.read_reg.option.bits.read64Bits =
> +			input->read_reg.read64_bits;
>   		break;
>   	case MES_MISC_OP_WRITE_REG:
>   		misc_pkt.opcode = MESAPI_MISC__WRITE_REG;
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> index 04465804c2544..0d2a60528802e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> @@ -858,6 +858,8 @@ static int mes_v12_0_misc_op(struct amdgpu_mes *mes,
>   		misc_pkt.opcode = MESAPI_MISC__READ_REG;
>   		misc_pkt.read_reg.reg_offset = input->read_reg.reg_offset;
>   		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
> +		misc_pkt.read_reg.option.bits.read64Bits =
> +			input->read_reg.read64_bits;
>   		break;
>   	case MES_MISC_OP_WRITE_REG:
>   		misc_pkt.opcode = MESAPI_MISC__WRITE_REG;
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
> index d17ced46d5f73..e0a488e516c09 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
> @@ -581,6 +581,8 @@ static int mes_v12_1_misc_op(struct amdgpu_mes *mes,
>   	case MES_MISC_OP_READ_REG:
>   		misc_pkt.opcode = MESAPI_MISC__READ_REG;
>   		misc_pkt.read_reg.buffer_addr = input->read_reg.buffer_addr;
> +		misc_pkt.read_reg.option.bits.read64Bits =
> +			input->read_reg.read64_bits;
>   		mes_v12_1_get_rrmt(input->read_reg.reg_offset,
>   				   GET_INST(GC, input->xcc_id),
>   				   &misc_pkt.read_reg.rrmt_opt,
> diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> index 1fe824b41f2a5..b27ec78da3b08 100644
> --- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> +++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> @@ -635,6 +635,13 @@ struct WRITE_REG {
>   struct READ_REG {
>   	uint32_t                  reg_offset;
>   	uint64_t                  buffer_addr;
> +	union {
> +		struct {
> +			uint32_t read64Bits : 1;
> +			uint32_t reserved : 31;
> +		} bits;
> +		uint32_t all;
> +	} option;
>   };
>   
>   enum WRM_OPERATION {


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF
  2026-09-28 10:31 ` [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF Victor Zhao
@ 2026-09-28 12:54   ` Lazar, Lijo
  0 siblings, 0 replies; 4+ messages in thread
From: Lazar, Lijo @ 2026-09-28 12:54 UTC (permalink / raw)
  To: Victor Zhao, amd-gfx, Alexander.Deucher, Shaoyun.Liu
  Cc: Davis.Ming, Gavin.Wan



On 28-Sep-26 4:01 PM, Victor Zhao wrote:
> [why]
> VF timestamp queries need a TSC sample independent of CP/MES.
> The SMUIO path is not safe on VF.
> 
> [how]
> Capture via RLC_CAPTURE_GPU_CLOCK_COUNT and read the consecutive
> count registers with amdgpu_mes_rreg64().
> 
> v3: check errors returned by amdgpu_mes_rreg64()
> 
> Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>

Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>

Thanks,
Lijo

> ---
>   drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c | 27 ++++++++++++++++++++++++++
>   1 file changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
> index d6f70d33201a0..83be620d7204b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
> @@ -3168,10 +3168,37 @@ static int gfx_v12_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
>   	return -ETIMEDOUT;
>   }
>   
> +static uint64_t gfx_v12_1_get_rlc_gpu_clock_counter(struct amdgpu_device *adev)
> +{
> +	uint64_t clock = 0;
> +	uint32_t reg;
> +
> +	if (!down_read_trylock(&adev->reset_domain->sem))
> +		return 0;
> +	if (amdgpu_device_skip_hw_access(adev) ||
> +	    !adev->mes.ring[0].sched.ready)
> +		goto unlock_reset;
> +
> +	mutex_lock(&adev->gfx.gpu_clock_mutex);
> +	WREG32_SOC15(GC, GET_INST(GC, 0), regRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
> +	reg = SOC15_REG_OFFSET(GC, GET_INST(GC, 0),
> +			       regRLC_GPU_CLOCK_COUNT_LSB);
> +	if (amdgpu_mes_rreg64(adev, reg, 0, &clock))
> +		clock = 0;
> +	mutex_unlock(&adev->gfx.gpu_clock_mutex);
> +
> +unlock_reset:
> +	up_read(&adev->reset_domain->sem);
> +	return clock;
> +}
> +
>   static uint64_t gfx_v12_1_get_gpu_clock_counter(struct amdgpu_device *adev)
>   {
>   	uint64_t clock = 0;
>   
> +	if (amdgpu_sriov_vf(adev))
> +		return gfx_v12_1_get_rlc_gpu_clock_counter(adev);
> +
>   	if (adev->smuio.funcs &&
>   	    adev->smuio.funcs->get_gpu_clock_counter)
>   		clock = adev->smuio.funcs->get_gpu_clock_counter(adev);


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-28 12:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-28 10:31 [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Victor Zhao
2026-09-28 10:31 ` [PATCH v3 2/2] drm/amdgpu: Read RLC GPU clock on GFX12.1 VF Victor Zhao
2026-09-28 12:54   ` Lazar, Lijo
2026-09-28 12:53 ` [PATCH v3 1/2] drm/amdgpu/mes: Support 64-bit register reads Lazar, Lijo

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.