* [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, ¶ms);
+ 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* 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
* [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