linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces
@ 2025-12-05  6:50 Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 1/5] drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask Yo-Jung Leo Lin (AMD)
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

The integrated info v2.3 table in the Atom ROM exposes available
options for the VRAM carveout sizes. The carveout size can be changed
using the ATCS function code 0xA for BIOS that supports this.

Make these features available as sysfs files, so that users can set
the carveout size in a way similar to what a Windows user can do in
the "Tuning" tab in the AMD Adrenalin. The newly added sysfs files
are:

- uma/carveout_options: this a read-only file listing all available
  carveout options. They are fetched from the Atom ROM on driver
  initialization.

- uma/carveout: this shows the index of the currently selected option,
  as shown in the uma_carveout_options. Writing a valid option index
  to this file will change the carveout option on next boot.

Note that above files are created only if BIOS indicates support for
it, i.e. where the table shows non-zero UMACarveoutIndexMax.

Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
Changes in v5:
- Move uma_info from struct amdgpu_atcs to struct amdgpu_device.
- Move implementation of sysfs entry initialization functions from amdgpu_acpi.c
  to amdgpu_device.c
- Adjust function prototypes and how they access uma_info and amdgpu_atcs in accordance
  with the changes above
- Do clean up for uma_info in amdgpu_acpi_uma_option_fini() only if allocation size
  setting is supported, for uma_info is initialized only when this is supported
- Link to v4: https://lore.kernel.org/r/20251201-vram-carveout-tuning-for-upstream-v4-0-9e151363b5ab@amd.com

Changes in v4:
- Correct format string and error message in carveout_show()
- Sanitize input array index in carveout_show() to fix smatch spectre warning
- Fix typos in comments for amdgpu_uma_carveout_option and amdgpu_uma_carveout_info
- Link to v3: https://lore.kernel.org/r/20251126-vram-carveout-tuning-for-upstream-v3-0-cf1729c4cb3c@amd.com

Changes in v3:
- Change the unit of memory carved in UMA option entry from GB to MB and use
  uint32_t instead, so that options below 1 GB can be properly recorded.
- Rename the sysfs interfaces from "uma_carveout_options" and "uma_carveout" to
  just "carveout_options" and "carveout", and put them under a new uma/ directory.
- Update docs to reflect the naming/location changes to the said sysfs files.
- Rebase to latest asdn
- Fix LKP build error
- Link to v2: https://lore.kernel.org/r/20251114-vram-carveout-tuning-for-upstream-v2-0-4f6bdd48030d@amd.com

Changes in v2:
- Move VBIOS table parsing and sysfs interface creation from atomfirmware
  initialization code to amdgpu_acpi_init()
- Create structs that abstract the uma options
- Move the parsed carveout options from atom_context to the amdgpu_atcs
- Minor kdoc fixes, as well as adding example output for uma_carveout_options
- Link to v1: https://lore.kernel.org/r/20251103-vram-carveout-tuning-for-upstream-v1-0-17e2a72639c5@amd.com

---
Yo-Jung Leo Lin (AMD) (5):
      drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask
      drm/amdgpu: add helper to read UMA carveout info
      drm/amdgpu: add UMA allocation setting helpers
      drm/amdgpu: add UMA allocation interfaces to sysfs
      Documentation/amdgpu: Add UMA carveout details

 Documentation/gpu/amdgpu/driver-misc.rst         |  26 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu.h              |  45 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c         |  54 ++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c |  77 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c       | 167 +++++++++++++++++++++++
 drivers/gpu/drm/amd/include/amd_acpi.h           |  34 ++++-
 7 files changed, 404 insertions(+), 1 deletion(-)
---
base-commit: 5de8ce0f3709ad93ca5a579aa45cf1b52d72bc90
change-id: 20251103-vram-carveout-tuning-for-upstream-1d5189688d73

Best regards,
-- 
Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>


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

* [PATCH v5 1/5] drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask
  2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
@ 2025-12-05  6:50 ` Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 2/5] drm/amdgpu: add helper to read UMA carveout info Yo-Jung Leo Lin (AMD)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

The capabilities of getting and setting VRAM carveout size are exposed
in the ATCS mask. Parse and store these capabilities for future use.

Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 ++++
 drivers/gpu/drm/amd/include/amd_acpi.h   | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index d31460a9e958..610449d73a6c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -116,7 +116,9 @@ struct amdgpu_atcs_functions {
 	bool pcie_perf_req;
 	bool pcie_dev_rdy;
 	bool pcie_bus_width;
+	bool get_uma_size;
 	bool power_shift_control;
+	bool set_uma_allocation_size;
 };
 
 struct amdgpu_atcs {
@@ -587,7 +589,9 @@ static void amdgpu_atcs_parse_functions(struct amdgpu_atcs_functions *f, u32 mas
 	f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
 	f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
 	f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
+	f->get_uma_size = mask & ACPI_ATCS_GET_UMA_SIZE_SUPPORTED;
 	f->power_shift_control = mask & ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED;
+	f->set_uma_allocation_size = mask & ACPI_ATCS_SET_UMA_ALLOCATION_SIZE_SUPPORTED;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/include/amd_acpi.h b/drivers/gpu/drm/amd/include/amd_acpi.h
index 06badbf0c5b9..e582339e8e8e 100644
--- a/drivers/gpu/drm/amd/include/amd_acpi.h
+++ b/drivers/gpu/drm/amd/include/amd_acpi.h
@@ -427,7 +427,9 @@ struct atcs_pwr_shift_input {
 #       define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED             (1 << 1)
 #       define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED       (1 << 2)
 #       define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED                   (1 << 3)
-#       define ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED		   (1 << 7)
+#       define ACPI_ATCS_GET_UMA_SIZE_SUPPORTED                    (1 << 5)
+#       define ATCS_SET_POWER_SHIFT_CONTROL_SUPPORTED              (1 << 7)
+#       define ACPI_ATCS_SET_UMA_ALLOCATION_SIZE_SUPPORTED         (1 << 9)
 #define ATCS_FUNCTION_GET_EXTERNAL_STATE                           0x1
 /* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
  * ARG1: none

-- 
2.43.0


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

* [PATCH v5 2/5] drm/amdgpu: add helper to read UMA carveout info
  2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 1/5] drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask Yo-Jung Leo Lin (AMD)
@ 2025-12-05  6:50 ` Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 3/5] drm/amdgpu: add UMA allocation setting helpers Yo-Jung Leo Lin (AMD)
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

Currently, the available UMA allocation configs in the integrated system
information table have not been parsed. Add a helper function to retrieve
and store these configs.

Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h              | 34 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 77 ++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h |  2 +
 3 files changed, 113 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 9f9774f58ce1..aca2ddddc64c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -836,6 +836,38 @@ struct amdgpu_uid {
 	struct amdgpu_device *adev;
 };
 
+#define MAX_UMA_OPTION_NAME	28
+#define MAX_UMA_OPTION_ENTRIES	19
+
+#define AMDGPU_UMA_FLAG_AUTO	BIT(1)
+#define AMDGPU_UMA_FLAG_CUSTOM	BIT(0)
+
+/**
+ * struct amdgpu_uma_carveout_option - single UMA carveout option
+ * @name: Name of the carveout option
+ * @memory_carved_mb: Amount of memory carved in MB
+ * @flags: ATCS flags supported by this option
+ */
+struct amdgpu_uma_carveout_option {
+	char name[MAX_UMA_OPTION_NAME];
+	uint32_t memory_carved_mb;
+	uint8_t flags;
+};
+
+/**
+ * struct amdgpu_uma_carveout_info - table of available UMA carveout options
+ * @num_entries: Number of available options
+ * @uma_option_index: The index of the option currently applied
+ * @update_lock: Lock to serialize changes to the option
+ * @entries: The array of carveout options
+ */
+struct amdgpu_uma_carveout_info {
+	uint8_t num_entries;
+	uint8_t uma_option_index;
+	struct mutex update_lock;
+	struct amdgpu_uma_carveout_option entries[MAX_UMA_OPTION_ENTRIES];
+};
+
 struct amd_powerplay {
 	void *pp_handle;
 	const struct amd_pm_funcs *pp_funcs;
@@ -1319,6 +1351,8 @@ struct amdgpu_device {
 	struct work_struct              userq_reset_work;
 	struct amdgpu_uid *uid_info;
 
+	struct amdgpu_uma_carveout_info uma_info;
+
 	/* KFD
 	 * Must be last --ends in a flexible-array member.
 	 */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index 636385c80f64..7f4751e5caaf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -296,6 +296,83 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
 	return vram_type;
 }
 
+static int amdgpu_atomfirmware_get_uma_carveout_info_v2_3(struct amdgpu_device *adev,
+							  union igp_info *igp_info,
+							  struct amdgpu_uma_carveout_info *uma_info)
+{
+	struct uma_carveout_option *opts;
+	uint8_t nr_uma_options;
+	int i;
+
+	nr_uma_options = igp_info->v23.UMACarveoutIndexMax;
+
+	if (!nr_uma_options)
+		return -ENODEV;
+
+	if (nr_uma_options > MAX_UMA_OPTION_ENTRIES) {
+		drm_dbg(adev_to_drm(adev),
+			"Number of UMA options exceeds max table size. Options will not be parsed");
+		return -EINVAL;
+	}
+
+	uma_info->num_entries = nr_uma_options;
+	uma_info->uma_option_index = igp_info->v23.UMACarveoutIndex;
+
+	opts = igp_info->v23.UMASizeControlOption;
+
+	for (i = 0; i < nr_uma_options; i++) {
+		if (!opts[i].memoryCarvedGb)
+			uma_info->entries[i].memory_carved_mb = 512;
+		else
+			uma_info->entries[i].memory_carved_mb = (uint32_t)opts[i].memoryCarvedGb << 10;
+
+		uma_info->entries[i].flags = opts[i].uma_carveout_option_flags.all8;
+		strscpy(uma_info->entries[i].name, opts[i].optionName, MAX_UMA_OPTION_NAME);
+	}
+
+	return 0;
+}
+
+int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
+					      struct amdgpu_uma_carveout_info *uma_info)
+{
+	struct amdgpu_mode_info *mode_info = &adev->mode_info;
+	union igp_info *igp_info;
+	u16 data_offset, size;
+	u8 frev, crev;
+	int index;
+
+	if (!(adev->flags & AMD_IS_APU))
+		return -ENODEV;
+
+	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+					    integratedsysteminfo);
+
+	if (!amdgpu_atom_parse_data_header(mode_info->atom_context,
+					  index, &size,
+					  &frev, &crev, &data_offset)) {
+		return -EINVAL;
+	}
+
+	igp_info = (union igp_info *)
+			(mode_info->atom_context->bios + data_offset);
+
+	switch (frev) {
+	case 2:
+		switch (crev) {
+		case 3:
+			return amdgpu_atomfirmware_get_uma_carveout_info_v2_3(adev, igp_info, uma_info);
+		break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+	return -ENODEV;
+}
+
 int
 amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
 				  int *vram_width, int *vram_type,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
index 649b5530d8ae..67c8d105729b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
@@ -32,6 +32,8 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
 int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
 int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
 	int *vram_width, int *vram_type, int *vram_vendor);
+int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev,
+					      struct amdgpu_uma_carveout_info *uma_info);
 int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
 int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
 bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev);

-- 
2.43.0


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

* [PATCH v5 3/5] drm/amdgpu: add UMA allocation setting helpers
  2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 1/5] drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 2/5] drm/amdgpu: add helper to read UMA carveout info Yo-Jung Leo Lin (AMD)
@ 2025-12-05  6:50 ` Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs Yo-Jung Leo Lin (AMD)
  2025-12-05  6:50 ` [PATCH v5 5/5] Documentation/amdgpu: Add UMA carveout details Yo-Jung Leo Lin (AMD)
  4 siblings, 0 replies; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

On some platforms, UMA allocation size can be set using the ATCS
methods. Add helper functions to interact with this functionality.

Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h      |  7 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 43 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/include/amd_acpi.h   | 30 ++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index aca2ddddc64c..6bf626a51dfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1720,12 +1720,14 @@ int amdgpu_acpi_init(struct amdgpu_device *adev);
 void amdgpu_acpi_fini(struct amdgpu_device *adev);
 bool amdgpu_acpi_is_pcie_performance_request_supported(struct amdgpu_device *adev);
 bool amdgpu_acpi_is_power_shift_control_supported(void);
+bool amdgpu_acpi_is_set_uma_allocation_size_supported(void);
 int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
 						u8 perf_req, bool advertise);
 int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
 				    u8 dev_state, bool drv_state);
 int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
 				   enum amdgpu_ss ss_state);
+int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type);
 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
 int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
 			     u64 *tmr_size);
@@ -1754,6 +1756,7 @@ static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { re
 static inline void amdgpu_acpi_detect(void) { }
 static inline void amdgpu_acpi_release(void) { }
 static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
+static inline bool amdgpu_acpi_is_set_uma_allocation_size_supported(void) { return false; }
 static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
 						  u8 dev_state, bool drv_state) { return 0; }
 static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
@@ -1761,6 +1764,10 @@ static inline int amdgpu_acpi_smart_shift_update(struct amdgpu_device *adev,
 {
 	return 0;
 }
+static inline int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type)
+{
+	return -EINVAL;
+}
 static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps) { }
 #endif
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index 610449d73a6c..bdafcde51107 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -668,6 +668,11 @@ bool amdgpu_acpi_is_power_shift_control_supported(void)
 	return amdgpu_acpi_priv.atcs.functions.power_shift_control;
 }
 
+bool amdgpu_acpi_is_set_uma_allocation_size_supported(void)
+{
+	return amdgpu_acpi_priv.atcs.functions.set_uma_allocation_size;
+}
+
 /**
  * amdgpu_acpi_pcie_notify_device_ready
  *
@@ -908,6 +913,44 @@ static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm)
 }
 #endif
 
+/**
+ * amdgpu_acpi_set_uma_allocation_size - Set Unified Memory Architecture allocation size via ACPI
+ * @adev: Pointer to the amdgpu_device structure
+ * @index: Index specifying the UMA allocation
+ * @type: Type of UMA allocation
+ *
+ * This function configures the UMA allocation size for the specified device
+ * using ACPI methods. The allocation is determined by the provided index and type.
+ * Returns 0 on success or a negative error code on failure.
+ */
+int amdgpu_acpi_set_uma_allocation_size(struct amdgpu_device *adev, u8 index, u8 type)
+{
+	struct atcs_set_uma_allocation_size_input atcs_input;
+	struct amdgpu_atcs *atcs = &amdgpu_acpi_priv.atcs;
+	struct acpi_buffer params;
+	union acpi_object *info;
+
+	if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
+		return -EINVAL;
+
+	atcs_input.size = sizeof(struct atcs_set_uma_allocation_size_input);
+	atcs_input.uma_size_index = index;
+	atcs_input.uma_size_type = type;
+
+	params.length = sizeof(struct atcs_set_uma_allocation_size_input);
+	params.pointer = &atcs_input;
+
+	info = amdgpu_atcs_call(atcs, ATCS_FUNCTION_SET_UMA_ALLOCATION_SIZE, &params);
+	if (!info) {
+		drm_err(adev_to_drm(adev), "ATCS UMA allocation size update failed\n");
+		return -EIO;
+	}
+
+	kfree(info);
+
+	return 0;
+}
+
 /**
  * amdgpu_acpi_get_node_id - obtain the NUMA node id for corresponding amdgpu
  * acpi device handle
diff --git a/drivers/gpu/drm/amd/include/amd_acpi.h b/drivers/gpu/drm/amd/include/amd_acpi.h
index e582339e8e8e..84933c07f720 100644
--- a/drivers/gpu/drm/amd/include/amd_acpi.h
+++ b/drivers/gpu/drm/amd/include/amd_acpi.h
@@ -24,6 +24,8 @@
 #ifndef AMD_ACPI_H
 #define AMD_ACPI_H
 
+#include <linux/types.h>
+
 #define ACPI_AC_CLASS           "ac_adapter"
 
 struct atif_verify_interface {
@@ -112,6 +114,17 @@ struct atcs_pwr_shift_input {
 	u8 drv_state;	/* 0 = operational, 1 = not operational */
 } __packed;
 
+struct atcs_get_uma_size_output {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u32 uma_size_mb;	/* allocated UMA size in MB */
+} __packed;
+
+struct atcs_set_uma_allocation_size_input {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u8 uma_size_index;	/* UMA size index */
+	u8 uma_size_type;	/* UMA size type */
+} __packed;
+
 /* AMD hw uses four ACPI control methods:
  * 1. ATIF
  * ARG0: (ACPI_INTEGER) function code
@@ -494,4 +507,21 @@ struct atcs_pwr_shift_input {
  * OUTPUT: none
  */
 
+#define ATCS_FUNCTION_GET_UMA_SIZE                                 0x6
+/* ARG0: ATCS_FUNCTION_GET_UMA_SIZE
+ * ARG1: none
+ * OUTPUT:
+ * WORD  - structure size in bytes (includes size field)
+ * DWORD - allocated UMA size in MB
+ */
+
+#define ATCS_FUNCTION_SET_UMA_ALLOCATION_SIZE                     0xA
+/* ARG0: ATCS_FUNCTION_SET_UMA_ALLOCATION_SIZE
+ * ARG1:
+ * WORD  - structure size in bytes (includes size field)
+ * BYTE  - UMA size index
+ * BYTE  - UMA size type
+ * OUTPUT: none
+ */
+
 #endif

-- 
2.43.0


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

* [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs
  2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
                   ` (2 preceding siblings ...)
  2025-12-05  6:50 ` [PATCH v5 3/5] drm/amdgpu: add UMA allocation setting helpers Yo-Jung Leo Lin (AMD)
@ 2025-12-05  6:50 ` Yo-Jung Leo Lin (AMD)
  2025-12-05 10:34   ` Lazar, Lijo
  2025-12-05  6:50 ` [PATCH v5 5/5] Documentation/amdgpu: Add UMA carveout details Yo-Jung Leo Lin (AMD)
  4 siblings, 1 reply; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

Add a uma/ directory containing two sysfs files as interfaces to
inspect or change UMA carveout size. These files are:

- uma/carveout_options: a read-only file listing all the available
  UMA allocation options and their index.

- uma/carveout: a file that is both readable and writable. On read,
  it shows the index of the current setting. Writing a valid index
  into this file allows users to change the UMA carveout size to that
  option on the next boot.

Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |   4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   |   7 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 138 +++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 6bf626a51dfc..177376ff5811 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1846,4 +1846,8 @@ void amdgpu_device_set_uid(struct amdgpu_uid *uid_info,
 			   uint64_t uid);
 uint64_t amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
 			       enum amdgpu_uid_type type, uint8_t inst);
+
+int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev);
+void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev);
+
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index bdafcde51107..b2779fc2f712 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -1288,6 +1288,12 @@ static int amdgpu_acpi_event(struct notifier_block *nb,
 int amdgpu_acpi_init(struct amdgpu_device *adev)
 {
 	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
+	int rc;
+
+	rc = amdgpu_acpi_uma_option_init(adev);
+
+	if (rc)
+		drm_dbg(adev_to_drm(adev), "Not creating uma carveout interfaces: %d", rc);
 
 	if (atif->notifications.brightness_change) {
 		if (adev->dc_enabled) {
@@ -1340,6 +1346,7 @@ void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps)
 void amdgpu_acpi_fini(struct amdgpu_device *adev)
 {
 	unregister_acpi_notifier(&adev->acpi_nb);
+	amdgpu_acpi_uma_option_fini(adev);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index a7594ae44b20..979298d9c213 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/pci-p2pdma.h>
 #include <linux/apple-gmux.h>
+#include <linux/nospec.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_client_event.h>
@@ -7835,3 +7836,140 @@ u64 amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
 
 	return uid_info->uid[type][inst];
 }
+
+static ssize_t carveout_options_show(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = drm_to_adev(ddev);
+	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
+	uint32_t memory_carved;
+	ssize_t size = 0;
+
+	if (!uma_info || !uma_info->num_entries)
+		return -ENODEV;
+
+	for (int i = 0; i < uma_info->num_entries; i++) {
+		memory_carved = uma_info->entries[i].memory_carved_mb;
+		if (memory_carved >= SZ_1G/SZ_1M) {
+			size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n",
+					      i,
+					      uma_info->entries[i].name,
+					      memory_carved >> 10);
+		} else {
+			size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n",
+					      i,
+					      uma_info->entries[i].name,
+					      memory_carved);
+		}
+	}
+
+	return size;
+}
+static DEVICE_ATTR_RO(carveout_options);
+
+static ssize_t carveout_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = drm_to_adev(ddev);
+
+	return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index);
+}
+
+static ssize_t carveout_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+	struct amdgpu_device *adev = drm_to_adev(ddev);
+	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
+	struct amdgpu_uma_carveout_option *opt;
+	unsigned long val;
+	uint8_t flags;
+	int r;
+
+	r = kstrtoul(buf, 10, &val);
+	if (r)
+		return r;
+
+	if (val >= uma_info->num_entries)
+		return -EINVAL;
+
+	val = array_index_nospec(val, uma_info->num_entries);
+	opt = &uma_info->entries[val];
+
+	if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) &&
+	    !(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) {
+		drm_err_once(ddev, "Option %lu not supported due to lack of Custom/Auto flag", val);
+		return -EINVAL;
+	}
+
+	flags = opt->flags;
+	flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1);
+
+	guard(mutex)(&uma_info->update_lock);
+
+	r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags);
+	if (r)
+		return r;
+
+	uma_info->uma_option_index = val;
+
+	return count;
+}
+static DEVICE_ATTR_RW(carveout);
+
+static struct attribute *amdgpu_uma_attrs[] = {
+	&dev_attr_carveout.attr,
+	&dev_attr_carveout_options.attr,
+	NULL
+};
+
+const struct attribute_group amdgpu_uma_attr_group = {
+	.name = "uma",
+	.attrs = amdgpu_uma_attrs
+};
+
+int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev)
+{
+	int rc;
+
+	if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
+		return -ENODEV;
+
+	rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev->uma_info);
+	if (rc) {
+		drm_dbg(adev_to_drm(adev),
+			"Failed to parse UMA carveout info from VBIOS: %d\n", rc);
+		goto out_info;
+	}
+
+	mutex_init(&adev->uma_info.update_lock);
+
+	rc = devm_device_add_group(adev->dev, &amdgpu_uma_attr_group);
+	if (rc) {
+		drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout sysfs interfaces %d\n", rc);
+		goto out_attr;
+	}
+
+	return 0;
+
+out_attr:
+	mutex_destroy(&adev->uma_info.update_lock);
+out_info:
+	return rc;
+}
+
+void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev)
+{
+	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
+
+	if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
+		return;
+
+	mutex_destroy(&uma_info->update_lock);
+	uma_info->num_entries = 0;
+}

-- 
2.43.0


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

* [PATCH v5 5/5] Documentation/amdgpu: Add UMA carveout details
  2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
                   ` (3 preceding siblings ...)
  2025-12-05  6:50 ` [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs Yo-Jung Leo Lin (AMD)
@ 2025-12-05  6:50 ` Yo-Jung Leo Lin (AMD)
  4 siblings, 0 replies; 9+ messages in thread
From: Yo-Jung Leo Lin (AMD) @ 2025-12-05  6:50 UTC (permalink / raw)
  To: Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org), Yo-Jung Leo Lin (AMD)

Add documentation for the uma/carveout_options and uma/carveout
attributes in sysfs

Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
---
 Documentation/gpu/amdgpu/driver-misc.rst   | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/Documentation/gpu/amdgpu/driver-misc.rst b/Documentation/gpu/amdgpu/driver-misc.rst
index 25b0c857816e..e1a964c3add2 100644
--- a/Documentation/gpu/amdgpu/driver-misc.rst
+++ b/Documentation/gpu/amdgpu/driver-misc.rst
@@ -128,3 +128,29 @@ smartshift_bias
 
 .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
    :doc: smartshift_bias
+
+UMA Carveout
+============
+
+Some versions of Atom ROM expose available options for the VRAM carveout sizes,
+and allow changes to the carveout size via the ATCS function code 0xA on supported
+BIOS implementations.
+
+For those platforms, users can use the following files under uma/ to set the
+carveout size, in a way similar to what Windows users can do in the "Tuning"
+tab in AMD Adrenalin.
+
+Note that for BIOS implementations that don't support this, these files will not
+be created at all.
+
+uma/carveout_options
+--------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: uma/carveout_options
+
+uma/carveout
+--------------------
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+   :doc: uma/carveout
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 979298d9c213..540f0781ca36 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -7837,6 +7837,24 @@ u64 amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
 	return uid_info->uid[type][inst];
 }
 
+/**
+ * DOC: uma/carveout_options
+ *
+ * This is a read-only file that lists all available UMA allocation
+ * options and their corresponding indices. Example output::
+ *
+ *     $ cat uma/carveout_options
+ *     0: Minimum (512 MB)
+ *     1:  (1 GB)
+ *     2:  (2 GB)
+ *     3:  (4 GB)
+ *     4:  (6 GB)
+ *     5:  (8 GB)
+ *     6:  (12 GB)
+ *     7: Medium (16 GB)
+ *     8:  (24 GB)
+ *     9: High (32 GB)
+ */
 static ssize_t carveout_options_show(struct device *dev,
 				     struct device_attribute *attr,
 				     char *buf)
@@ -7869,6 +7887,17 @@ static ssize_t carveout_options_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(carveout_options);
 
+/**
+ * DOC: uma/carveout
+ *
+ * This file is both readable and writable. When read, it shows the
+ * index of the current setting. Writing a valid index to this file
+ * allows users to change the UMA carveout size to the selected option
+ * on the next boot.
+ *
+ * The available options and their corresponding indices can be read
+ * from the uma/carveout_options file.
+ */
 static ssize_t carveout_show(struct device *dev,
 			     struct device_attribute *attr,
 			     char *buf)

-- 
2.43.0


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

* Re: [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs
  2025-12-05  6:50 ` [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs Yo-Jung Leo Lin (AMD)
@ 2025-12-05 10:34   ` Lazar, Lijo
  2025-12-05 10:45     ` Lazar, Lijo
  2025-12-05 14:05     ` Lin, Leo
  0 siblings, 2 replies; 9+ messages in thread
From: Lazar, Lijo @ 2025-12-05 10:34 UTC (permalink / raw)
  To: Yo-Jung Leo Lin (AMD), Alex Deucher, Christian König,
	David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org)



On 12/5/2025 12:20 PM, Yo-Jung Leo Lin (AMD) wrote:
> Add a uma/ directory containing two sysfs files as interfaces to
> inspect or change UMA carveout size. These files are:
> 
> - uma/carveout_options: a read-only file listing all the available
>    UMA allocation options and their index.
> 
> - uma/carveout: a file that is both readable and writable. On read,
>    it shows the index of the current setting. Writing a valid index
>    into this file allows users to change the UMA carveout size to that
>    option on the next boot.
> 
> Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |   4 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   |   7 ++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 138 +++++++++++++++++++++++++++++
>   3 files changed, 149 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 6bf626a51dfc..177376ff5811 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1846,4 +1846,8 @@ void amdgpu_device_set_uid(struct amdgpu_uid *uid_info,
>   			   uint64_t uid);
>   uint64_t amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
>   			       enum amdgpu_uid_type type, uint8_t inst);
> +
> +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev);
> +void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev);
> +
>   #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> index bdafcde51107..b2779fc2f712 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> @@ -1288,6 +1288,12 @@ static int amdgpu_acpi_event(struct notifier_block *nb,
>   int amdgpu_acpi_init(struct amdgpu_device *adev)
>   {
>   	struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
> +	int rc;
> +
> +	rc = amdgpu_acpi_uma_option_init(adev);
> +
> +	if (rc)
> +		drm_dbg(adev_to_drm(adev), "Not creating uma carveout interfaces: %d", rc);
>   
>   	if (atif->notifications.brightness_change) {
>   		if (adev->dc_enabled) {
> @@ -1340,6 +1346,7 @@ void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps)
>   void amdgpu_acpi_fini(struct amdgpu_device *adev)
>   {
>   	unregister_acpi_notifier(&adev->acpi_nb);
> +	amdgpu_acpi_uma_option_fini(adev);
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index a7594ae44b20..979298d9c213 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -36,6 +36,7 @@
>   #include <linux/pci.h>
>   #include <linux/pci-p2pdma.h>
>   #include <linux/apple-gmux.h>
> +#include <linux/nospec.h>
>   
>   #include <drm/drm_atomic_helper.h>
>   #include <drm/drm_client_event.h>
> @@ -7835,3 +7836,140 @@ u64 amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
>   
>   	return uid_info->uid[type][inst];
>   }
> +
> +static ssize_t carveout_options_show(struct device *dev,
> +				     struct device_attribute *attr,
> +				     char *buf)
> +{
> +	struct drm_device *ddev = dev_get_drvdata(dev);
> +	struct amdgpu_device *adev = drm_to_adev(ddev);
> +	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> +	uint32_t memory_carved;
> +	ssize_t size = 0;
> +
> +	if (!uma_info || !uma_info->num_entries)
> +		return -ENODEV;
> +
> +	for (int i = 0; i < uma_info->num_entries; i++) {
> +		memory_carved = uma_info->entries[i].memory_carved_mb;
> +		if (memory_carved >= SZ_1G/SZ_1M) {
> +			size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n",
> +					      i,
> +					      uma_info->entries[i].name,
> +					      memory_carved >> 10);
> +		} else {
> +			size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n",
> +					      i,
> +					      uma_info->entries[i].name,
> +					      memory_carved);
> +		}
> +	}
> +
> +	return size;
> +}
> +static DEVICE_ATTR_RO(carveout_options);
> +
> +static ssize_t carveout_show(struct device *dev,
> +			     struct device_attribute *attr,
> +			     char *buf)
> +{
> +	struct drm_device *ddev = dev_get_drvdata(dev);
> +	struct amdgpu_device *adev = drm_to_adev(ddev);
> +
> +	return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index);
> +}
> +
> +static ssize_t carveout_store(struct device *dev,
> +			      struct device_attribute *attr,
> +			      const char *buf, size_t count)
> +{
> +	struct drm_device *ddev = dev_get_drvdata(dev);
> +	struct amdgpu_device *adev = drm_to_adev(ddev);
> +	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> +	struct amdgpu_uma_carveout_option *opt;
> +	unsigned long val;
> +	uint8_t flags;
> +	int r;
> +
> +	r = kstrtoul(buf, 10, &val);
> +	if (r)
> +		return r;
> +
> +	if (val >= uma_info->num_entries)
> +		return -EINVAL;
> +
> +	val = array_index_nospec(val, uma_info->num_entries);
> +	opt = &uma_info->entries[val];
> +
> +	if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) &&
> +	    !(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) {
> +		drm_err_once(ddev, "Option %lu not supported due to lack of Custom/Auto flag", val);
> +		return -EINVAL;
> +	}
> +
> +	flags = opt->flags;
> +	flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1);
> +
> +	guard(mutex)(&uma_info->update_lock);
> +
> +	r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags);
> +	if (r)
> +		return r;
> +
> +	uma_info->uma_option_index = val;
> +
> +	return count;
> +}
> +static DEVICE_ATTR_RW(carveout);
> +
> +static struct attribute *amdgpu_uma_attrs[] = {
> +	&dev_attr_carveout.attr,
> +	&dev_attr_carveout_options.attr,
> +	NULL
> +};
> +
> +const struct attribute_group amdgpu_uma_attr_group = {
> +	.name = "uma",
> +	.attrs = amdgpu_uma_attrs
> +};
> +
> +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev)
> +{

To clarify on the comment about moving this to amdgpu_device -

UMA option is a device specific option which could be set through acpi. 
Options are retrieved through atom tables.

So the function names remain amdgpu_device_uma_option_init/fini() and 
init/fini are called within amdgpu_device.c

Thanks,
Lijo

> +	int rc;
> +
> +	if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
> +		return -ENODEV;
> +
> +	rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev->uma_info);
> +	if (rc) {
> +		drm_dbg(adev_to_drm(adev),
> +			"Failed to parse UMA carveout info from VBIOS: %d\n", rc);
> +		goto out_info;
> +	}
> +
> +	mutex_init(&adev->uma_info.update_lock);
> +
> +	rc = devm_device_add_group(adev->dev, &amdgpu_uma_attr_group);
> +	if (rc) {
> +		drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout sysfs interfaces %d\n", rc);
> +		goto out_attr;
> +	}
> +
> +	return 0;
> +
> +out_attr:
> +	mutex_destroy(&adev->uma_info.update_lock);
> +out_info:
> +	return rc;
> +}
> +
> +void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev)
> +{
> +	struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> +
> +	if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
> +		return;
> +
> +	mutex_destroy(&uma_info->update_lock);
> +	uma_info->num_entries = 0;
> +}
> 


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

* Re: [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs
  2025-12-05 10:34   ` Lazar, Lijo
@ 2025-12-05 10:45     ` Lazar, Lijo
  2025-12-05 14:05     ` Lin, Leo
  1 sibling, 0 replies; 9+ messages in thread
From: Lazar, Lijo @ 2025-12-05 10:45 UTC (permalink / raw)
  To: Yo-Jung Leo Lin (AMD), Alex Deucher, Christian König,
	David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet
  Cc: amd-gfx, dri-devel, linux-kernel, linux-doc, Tsao, Anson,
	Mario Limonciello (AMD) (kernel.org)



On 12/5/2025 4:04 PM, Lazar, Lijo wrote:
> 
> 
> On 12/5/2025 12:20 PM, Yo-Jung Leo Lin (AMD) wrote:
>> Add a uma/ directory containing two sysfs files as interfaces to
>> inspect or change UMA carveout size. These files are:
>>
>> - uma/carveout_options: a read-only file listing all the available
>>    UMA allocation options and their index.
>>
>> - uma/carveout: a file that is both readable and writable. On read,
>>    it shows the index of the current setting. Writing a valid index
>>    into this file allows users to change the UMA carveout size to that
>>    option on the next boot.
>>
>> Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
>> Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
>> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
>> Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |   4 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   |   7 ++
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 138 +++++++++++++++++++ 
>> ++++++++++
>>   3 files changed, 149 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/ 
>> amd/amdgpu/amdgpu.h
>> index 6bf626a51dfc..177376ff5811 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -1846,4 +1846,8 @@ void amdgpu_device_set_uid(struct amdgpu_uid 
>> *uid_info,
>>                  uint64_t uid);
>>   uint64_t amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
>>                      enum amdgpu_uid_type type, uint8_t inst);
>> +
>> +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev);
>> +void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev);
>> +
>>   #endif
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/ 
>> drm/amd/amdgpu/amdgpu_acpi.c
>> index bdafcde51107..b2779fc2f712 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
>> @@ -1288,6 +1288,12 @@ static int amdgpu_acpi_event(struct 
>> notifier_block *nb,
>>   int amdgpu_acpi_init(struct amdgpu_device *adev)
>>   {
>>       struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
>> +    int rc;
>> +
>> +    rc = amdgpu_acpi_uma_option_init(adev);
>> +
>> +    if (rc)
>> +        drm_dbg(adev_to_drm(adev), "Not creating uma carveout 
>> interfaces: %d", rc);
>>       if (atif->notifications.brightness_change) {
>>           if (adev->dc_enabled) {
>> @@ -1340,6 +1346,7 @@ void amdgpu_acpi_get_backlight_caps(struct 
>> amdgpu_dm_backlight_caps *caps)
>>   void amdgpu_acpi_fini(struct amdgpu_device *adev)
>>   {
>>       unregister_acpi_notifier(&adev->acpi_nb);
>> +    amdgpu_acpi_uma_option_fini(adev);
>>   }
>>   /**
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/ 
>> drm/amd/amdgpu/amdgpu_device.c
>> index a7594ae44b20..979298d9c213 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/pci.h>
>>   #include <linux/pci-p2pdma.h>
>>   #include <linux/apple-gmux.h>
>> +#include <linux/nospec.h>
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_client_event.h>
>> @@ -7835,3 +7836,140 @@ u64 amdgpu_device_get_uid(struct amdgpu_uid 
>> *uid_info,
>>       return uid_info->uid[type][inst];
>>   }
>> +
>> +static ssize_t carveout_options_show(struct device *dev,
>> +                     struct device_attribute *attr,
>> +                     char *buf)
>> +{
>> +    struct drm_device *ddev = dev_get_drvdata(dev);
>> +    struct amdgpu_device *adev = drm_to_adev(ddev);
>> +    struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
>> +    uint32_t memory_carved;
>> +    ssize_t size = 0;
>> +
>> +    if (!uma_info || !uma_info->num_entries)
>> +        return -ENODEV;
>> +
>> +    for (int i = 0; i < uma_info->num_entries; i++) {
>> +        memory_carved = uma_info->entries[i].memory_carved_mb;
>> +        if (memory_carved >= SZ_1G/SZ_1M) {
>> +            size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n",
>> +                          i,
>> +                          uma_info->entries[i].name,
>> +                          memory_carved >> 10);
>> +        } else {
>> +            size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n",
>> +                          i,
>> +                          uma_info->entries[i].name,
>> +                          memory_carved);
>> +        }
>> +    }
>> +
>> +    return size;
>> +}
>> +static DEVICE_ATTR_RO(carveout_options);
>> +
>> +static ssize_t carveout_show(struct device *dev,
>> +                 struct device_attribute *attr,
>> +                 char *buf)
>> +{
>> +    struct drm_device *ddev = dev_get_drvdata(dev);
>> +    struct amdgpu_device *adev = drm_to_adev(ddev);
>> +
>> +    return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index);
>> +}
>> +
>> +static ssize_t carveout_store(struct device *dev,
>> +                  struct device_attribute *attr,
>> +                  const char *buf, size_t count)
>> +{
>> +    struct drm_device *ddev = dev_get_drvdata(dev);
>> +    struct amdgpu_device *adev = drm_to_adev(ddev);
>> +    struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
>> +    struct amdgpu_uma_carveout_option *opt;
>> +    unsigned long val;
>> +    uint8_t flags;
>> +    int r;
>> +
>> +    r = kstrtoul(buf, 10, &val);
>> +    if (r)
>> +        return r;
>> +
>> +    if (val >= uma_info->num_entries)
>> +        return -EINVAL;
>> +
>> +    val = array_index_nospec(val, uma_info->num_entries);
>> +    opt = &uma_info->entries[val];
>> +
>> +    if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) &&
>> +        !(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) {
>> +        drm_err_once(ddev, "Option %lu not supported due to lack of 
>> Custom/Auto flag", val);
>> +        return -EINVAL;
>> +    }
>> +
>> +    flags = opt->flags;
>> +    flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1);
>> +
>> +    guard(mutex)(&uma_info->update_lock);
>> +
>> +    r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags);
>> +    if (r)
>> +        return r;
>> +
>> +    uma_info->uma_option_index = val;
>> +
>> +    return count;
>> +}
>> +static DEVICE_ATTR_RW(carveout);
>> +
>> +static struct attribute *amdgpu_uma_attrs[] = {
>> +    &dev_attr_carveout.attr,
>> +    &dev_attr_carveout_options.attr,
>> +    NULL
>> +};
>> +
>> +const struct attribute_group amdgpu_uma_attr_group = {
>> +    .name = "uma",
>> +    .attrs = amdgpu_uma_attrs
>> +};
>> +
>> +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev)
>> +{
> 
> To clarify on the comment about moving this to amdgpu_device -
> 
> UMA option is a device specific option which could be set through acpi. 
> Options are retrieved through atom tables.
> 
> So the function names remain amdgpu_device_uma_option_init/fini() and 
> init/fini are called within amdgpu_device.c
> 

Couple of additional comments below -

> Thanks,
> Lijo
> 
>> +    int rc;
>> +

It's better to have an early exit from here itself if it's not APU. 
Otherwise, the dbg prints will show up even on dGPUs.

There also needs to be a check for availability of BIOS (adev->bios) and 
(adev->is_atom_fw). For example in Instinct APUs, driver doesn't read 
bios image (adev->bios is NULL).

Thanks,
Lijo

>> +    if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
>> +        return -ENODEV;
>> +
>> +    rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev- 
>> >uma_info);
>> +    if (rc) {
>> +        drm_dbg(adev_to_drm(adev),
>> +            "Failed to parse UMA carveout info from VBIOS: %d\n", rc);
>> +        goto out_info;
>> +    }
>> +
>> +    mutex_init(&adev->uma_info.update_lock);
>> +
>> +    rc = devm_device_add_group(adev->dev, &amdgpu_uma_attr_group);
>> +    if (rc) {
>> +        drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout sysfs 
>> interfaces %d\n", rc);
>> +        goto out_attr;
>> +    }
>> +
>> +    return 0;
>> +
>> +out_attr:
>> +    mutex_destroy(&adev->uma_info.update_lock);
>> +out_info:
>> +    return rc;
>> +}
>> +
>> +void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev)
>> +{
>> +    struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
>> +
>> +    if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
>> +        return;
>> +
>> +    mutex_destroy(&uma_info->update_lock);
>> +    uma_info->num_entries = 0;
>> +}
>>
> 


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

* RE: [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs
  2025-12-05 10:34   ` Lazar, Lijo
  2025-12-05 10:45     ` Lazar, Lijo
@ 2025-12-05 14:05     ` Lin, Leo
  1 sibling, 0 replies; 9+ messages in thread
From: Lin, Leo @ 2025-12-05 14:05 UTC (permalink / raw)
  To: Lazar, Lijo, Deucher, Alexander, Koenig, Christian, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet
  Cc: amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	Tsao, Anson, Mario Limonciello (AMD) (kernel.org)

[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Lazar, Lijo <Lijo.Lazar@amd.com>
> Sent: Friday, December 5, 2025 6:34 PM
> To: Lin, Leo <Leo.Lin@amd.com>; Deucher, Alexander
> <Alexander.Deucher@amd.com>; Koenig, Christian
> <Christian.Koenig@amd.com>; David Airlie <airlied@gmail.com>; Simona
> Vetter <simona@ffwll.ch>; Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com>; Maxime Ripard
> <mripard@kernel.org>; Thomas Zimmermann <tzimmermann@suse.de>;
> Jonathan Corbet <corbet@lwn.net>
> Cc: amd-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux-
> kernel@vger.kernel.org; linux-doc@vger.kernel.org; Tsao, Anson
> <anson.tsao@amd.com>; Mario Limonciello (AMD) (kernel.org)
> <superm1@kernel.org>
> Subject: Re: [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to
> sysfs
>
>
>
> On 12/5/2025 12:20 PM, Yo-Jung Leo Lin (AMD) wrote:
> > Add a uma/ directory containing two sysfs files as interfaces to
> > inspect or change UMA carveout size. These files are:
> >
> > - uma/carveout_options: a read-only file listing all the available
> >    UMA allocation options and their index.
> >
> > - uma/carveout: a file that is both readable and writable. On read,
> >    it shows the index of the current setting. Writing a valid index
> >    into this file allows users to change the UMA carveout size to that
> >    option on the next boot.
> >
> > Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> > Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
> > Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> > Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |   4 +
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   |   7 ++
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 138
> +++++++++++++++++++++++++++++
> >   3 files changed, 149 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > index 6bf626a51dfc..177376ff5811 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> > @@ -1846,4 +1846,8 @@ void amdgpu_device_set_uid(struct amdgpu_uid
> *uid_info,
> >                        uint64_t uid);
> >   uint64_t amdgpu_device_get_uid(struct amdgpu_uid *uid_info,
> >                            enum amdgpu_uid_type type, uint8_t inst);
> > +
> > +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev); void
> > +amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev);
> > +
> >   #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> > index bdafcde51107..b2779fc2f712 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
> > @@ -1288,6 +1288,12 @@ static int amdgpu_acpi_event(struct
> notifier_block *nb,
> >   int amdgpu_acpi_init(struct amdgpu_device *adev)
> >   {
> >     struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
> > +   int rc;
> > +
> > +   rc = amdgpu_acpi_uma_option_init(adev);
> > +
> > +   if (rc)
> > +           drm_dbg(adev_to_drm(adev), "Not creating uma carveout
> interfaces:
> > +%d", rc);
> >
> >     if (atif->notifications.brightness_change) {
> >             if (adev->dc_enabled) {
> > @@ -1340,6 +1346,7 @@ void amdgpu_acpi_get_backlight_caps(struct
> amdgpu_dm_backlight_caps *caps)
> >   void amdgpu_acpi_fini(struct amdgpu_device *adev)
> >   {
> >     unregister_acpi_notifier(&adev->acpi_nb);
> > +   amdgpu_acpi_uma_option_fini(adev);
> >   }
> >
> >   /**
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > index a7594ae44b20..979298d9c213 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > @@ -36,6 +36,7 @@
> >   #include <linux/pci.h>
> >   #include <linux/pci-p2pdma.h>
> >   #include <linux/apple-gmux.h>
> > +#include <linux/nospec.h>
> >
> >   #include <drm/drm_atomic_helper.h>
> >   #include <drm/drm_client_event.h>
> > @@ -7835,3 +7836,140 @@ u64 amdgpu_device_get_uid(struct
> amdgpu_uid
> > *uid_info,
> >
> >     return uid_info->uid[type][inst];
> >   }
> > +
> > +static ssize_t carveout_options_show(struct device *dev,
> > +                                struct device_attribute *attr,
> > +                                char *buf)
> > +{
> > +   struct drm_device *ddev = dev_get_drvdata(dev);
> > +   struct amdgpu_device *adev = drm_to_adev(ddev);
> > +   struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> > +   uint32_t memory_carved;
> > +   ssize_t size = 0;
> > +
> > +   if (!uma_info || !uma_info->num_entries)
> > +           return -ENODEV;
> > +
> > +   for (int i = 0; i < uma_info->num_entries; i++) {
> > +           memory_carved = uma_info->entries[i].memory_carved_mb;
> > +           if (memory_carved >= SZ_1G/SZ_1M) {
> > +                   size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n",
> > +                                         i,
> > +                                         uma_info->entries[i].name,
> > +                                         memory_carved >> 10);
> > +           } else {
> > +                   size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n",
> > +                                         i,
> > +                                         uma_info->entries[i].name,
> > +                                         memory_carved);
> > +           }
> > +   }
> > +
> > +   return size;
> > +}
> > +static DEVICE_ATTR_RO(carveout_options);
> > +
> > +static ssize_t carveout_show(struct device *dev,
> > +                        struct device_attribute *attr,
> > +                        char *buf)
> > +{
> > +   struct drm_device *ddev = dev_get_drvdata(dev);
> > +   struct amdgpu_device *adev = drm_to_adev(ddev);
> > +
> > +   return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index); }
> > +
> > +static ssize_t carveout_store(struct device *dev,
> > +                         struct device_attribute *attr,
> > +                         const char *buf, size_t count) {
> > +   struct drm_device *ddev = dev_get_drvdata(dev);
> > +   struct amdgpu_device *adev = drm_to_adev(ddev);
> > +   struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> > +   struct amdgpu_uma_carveout_option *opt;
> > +   unsigned long val;
> > +   uint8_t flags;
> > +   int r;
> > +
> > +   r = kstrtoul(buf, 10, &val);
> > +   if (r)
> > +           return r;
> > +
> > +   if (val >= uma_info->num_entries)
> > +           return -EINVAL;
> > +
> > +   val = array_index_nospec(val, uma_info->num_entries);
> > +   opt = &uma_info->entries[val];
> > +
> > +   if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) &&
> > +       !(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) {
> > +           drm_err_once(ddev, "Option %lu not supported due to lack
> of Custom/Auto flag", val);
> > +           return -EINVAL;
> > +   }
> > +
> > +   flags = opt->flags;
> > +   flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1);
> > +
> > +   guard(mutex)(&uma_info->update_lock);
> > +
> > +   r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags);
> > +   if (r)
> > +           return r;
> > +
> > +   uma_info->uma_option_index = val;
> > +
> > +   return count;
> > +}
> > +static DEVICE_ATTR_RW(carveout);
> > +
> > +static struct attribute *amdgpu_uma_attrs[] = {
> > +   &dev_attr_carveout.attr,
> > +   &dev_attr_carveout_options.attr,
> > +   NULL
> > +};
> > +
> > +const struct attribute_group amdgpu_uma_attr_group = {
> > +   .name = "uma",
> > +   .attrs = amdgpu_uma_attrs
> > +};
> > +
> > +int amdgpu_acpi_uma_option_init(struct amdgpu_device *adev) {
>
> To clarify on the comment about moving this to amdgpu_device -
>
> UMA option is a device specific option which could be set through acpi.
> Options are retrieved through atom tables.
>
> So the function names remain amdgpu_device_uma_option_init/fini() and
> init/fini are called within amdgpu_device.c

Hi Lijo,

Originally, I got the idea of putting init/fini in amdgpu_acpi_init/fini() from previous discussion[1], but now I see your point that amdgpu_device.c is a more suitable place for handling things that need both ACPI and atom at the same time.

If both you and Alex agree with moving this into amdgpu_device.c I'm glad to make that change in the next version.

[1] https://lore.kernel.org/all/CADnq5_PS7pfseo84hVPfBevJqrfBxHEAct0w35xVjNg0cjREqg@mail.gmail.com/

Best,
Leo

>
> Thanks,
> Lijo
>
> > +   int rc;
> > +
> > +   if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
> > +           return -ENODEV;
> > +
> > +   rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev-
> >uma_info);
> > +   if (rc) {
> > +           drm_dbg(adev_to_drm(adev),
> > +                   "Failed to parse UMA carveout info from VBIOS:
> %d\n", rc);
> > +           goto out_info;
> > +   }
> > +
> > +   mutex_init(&adev->uma_info.update_lock);
> > +
> > +   rc = devm_device_add_group(adev->dev,
> &amdgpu_uma_attr_group);
> > +   if (rc) {
> > +           drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout
> sysfs interfaces %d\n", rc);
> > +           goto out_attr;
> > +   }
> > +
> > +   return 0;
> > +
> > +out_attr:
> > +   mutex_destroy(&adev->uma_info.update_lock);
> > +out_info:
> > +   return rc;
> > +}
> > +
> > +void amdgpu_acpi_uma_option_fini(struct amdgpu_device *adev) {
> > +   struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info;
> > +
> > +   if (!amdgpu_acpi_is_set_uma_allocation_size_supported())
> > +           return;
> > +
> > +   mutex_destroy(&uma_info->update_lock);
> > +   uma_info->num_entries = 0;
> > +}
> >


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

end of thread, other threads:[~2025-12-05 14:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-05  6:50 [PATCH v5 0/5] drm/amdgpu: add UMA carveout tuning interfaces Yo-Jung Leo Lin (AMD)
2025-12-05  6:50 ` [PATCH v5 1/5] drm/amdgpu: parse UMA size-getting/setting bits in ATCS mask Yo-Jung Leo Lin (AMD)
2025-12-05  6:50 ` [PATCH v5 2/5] drm/amdgpu: add helper to read UMA carveout info Yo-Jung Leo Lin (AMD)
2025-12-05  6:50 ` [PATCH v5 3/5] drm/amdgpu: add UMA allocation setting helpers Yo-Jung Leo Lin (AMD)
2025-12-05  6:50 ` [PATCH v5 4/5] drm/amdgpu: add UMA allocation interfaces to sysfs Yo-Jung Leo Lin (AMD)
2025-12-05 10:34   ` Lazar, Lijo
2025-12-05 10:45     ` Lazar, Lijo
2025-12-05 14:05     ` Lin, Leo
2025-12-05  6:50 ` [PATCH v5 5/5] Documentation/amdgpu: Add UMA carveout details Yo-Jung Leo Lin (AMD)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).