[PATCH 5/5] drm/amdgpu: add more inject control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



TA accept some options like address is in sram or vram. Most default
options are enough to use. But allow user to setup them.

reuse inject.value to place these options.

At the same time, we need translate the address to a physical/gpu
address which the pages are mapped at.

Signed-off-by: xinhui pan <xinhui.pan@xxxxxxx>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 83 ++++++++++++++++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 20 +++++-
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 469cb6477b8e..ca823675a1c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -121,6 +121,21 @@ const char *ras_block_string[] = {
 #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS 1
 #define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
 
+static int amdgpu_ras_reserve_vram(struct amdgpu_device *adev,
+		uint64_t offset, uint64_t size,
+		struct amdgpu_bo **bo_ptr);
+
+static int amdgpu_ras_release_vram(struct amdgpu_device *adev,
+		struct amdgpu_bo **bo_ptr);
+
+static int amdgpu_ras_translate_addr(struct amdgpu_device *adev,
+		u64 *gpu_addr, int addr_type)
+{
+	/* TODO */
+
+	return -EINVAL;
+}
+
 static void amdgpu_ras_self_test(struct amdgpu_device *adev)
 {
 	/* TODO */
@@ -176,6 +191,28 @@ static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id)
 	return -EINVAL;
 }
 
+static bool amdgpu_ras_extract_inject_data(const struct ras_inject_if *inject,
+		u64 *address, u64 *value, int *addr_type, int *inject_type)
+{
+	const struct inject_data *data = &inject->data;
+
+	if (data->magic != AMDGPU_RAS_INJECT_MAGIC ||
+			data->u8_reserved ||
+			data->u32_reserved) {
+		*address = inject->address;
+		*value = inject->value;
+
+		return false;
+	}
+
+	*address = inject->address;
+	*value = data->value;
+	*addr_type = data->addr_type;
+	*inject_type = data->inject_type;
+
+	return true;
+}
+
 static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
 		const char __user *buf, size_t size,
 		loff_t *pos, struct ras_debug_if *data)
@@ -300,7 +337,14 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
 	struct ras_debug_if data;
+	struct amdgpu_bo *bo = NULL;
 	int ret = 0;
+	u64 address;
+	u64 value;
+	int addr_type = 0;
+	int inject_type;
+
+	BUILD_BUG_ON(sizeof(struct inject_data) > sizeof(uint64_t));
 
 	ret = amdgpu_ras_debugfs_ctrl_parse_data(f, buf, size, pos, &data);
 	if (ret)
@@ -317,7 +361,44 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
 		ret = amdgpu_ras_feature_enable(adev, &data.head, 1);
 		break;
 	case 2:
-		ret = amdgpu_ras_error_inject(adev, &data.inject);
+		do {
+			if (amdgpu_ras_extract_inject_data(&data.inject,
+						&address,
+						&value,
+						&addr_type,
+						&inject_type))
+				/* not documented yet. */
+				data.inject.value = inject_type;
+			else
+				data.inject.value = value;
+
+			/* 0 is vram, 1 is sram. */
+			data.inject.head.sub_block_index = addr_type;
+
+			/*
+			 * Need translate address to phy address accodring to
+			 * addr_type.
+			 */
+			ret = amdgpu_ras_translate_addr(adev,
+					&address, addr_type);
+			/* address is not mapped with physical pages */
+			if (ret) {
+				if (addr_type)
+					break;
+
+				/* try to reserve vram at address for inject.*/
+				if (amdgpu_ras_reserve_vram(adev,
+							address >> PAGE_SHIFT,
+							PAGE_SIZE, &bo))
+					break;
+			}
+
+			data.inject.address = address;
+
+			ret = amdgpu_ras_error_inject(adev, &data.inject);
+			if (bo)
+				amdgpu_ras_release_vram(adev, &bo);
+		} while (0);
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 682f2be0d68c..adcf7d88d59d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -121,10 +121,28 @@ struct ras_query_if {
 	unsigned long ce_count;
 };
 
+#define AMDGPU_RAS_INJECT_MAGIC 0xaa55
 struct ras_inject_if {
 	struct ras_common_if head;
 	uint64_t address;
-	uint64_t value;
+	union {
+		uint64_t value;
+		struct inject_data {
+			u8 value;
+			/* 0 is vram, 1 is sram */
+			u8 addr_type:1;
+			/* TA has several inject types,
+			 * but looks like 0 is the most case.
+			 */
+			u8 inject_type:3;
+			/* must be 0 */
+			u8 u8_reserved;
+			/* identify value or inject_data. */
+			u8 magic;
+			/* must be 0 */
+			u32 u32_reserved;
+		} data;
+	};
 };
 
 struct ras_cure_if {
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux