mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'amd-drm-next-7.1-2026-03-12' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-7.1-2026-03-12: amdgpu: - SMU13 fix - SMU14 fix - Fixes for bring up hw testing - Kerneldoc fix - GC12 idle power fix for compute workloads - DCCG fixes - UserQ fixes - Move test for fbdev object to a generic helper - GC 12.1 updates - Use struct drm_edid in non-DC code - Include IP discovery data in devcoredump - SMU 13.x updates - Misc cleanups - DML 2.1 fixes - Enable NV12/P010 support on primary planes - Enable color encoding and color range on overlay planes - DC underflow fixes - HWSS fast path fixes - Replay fixes - DCN 4.2 updates - Support newer IP discovery tables - LSDMA 7.1 support - IH 7.1 fixes - SoC v1 updates - GC12.1 updates - PSP 15 updates - XGMI fixes - GPUVM locking fix amdkfd: - Fix missing BO unreserve in an error path radeon: - Move test for fbdev object to a generic helper From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260312184425.3875669-1-alexander.deucher@amd.com Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -86,7 +86,7 @@ amdgpu-y += \
|
||||
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o soc24.o \
|
||||
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \
|
||||
nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o nbif_v6_3_1.o \
|
||||
cyan_skillfish_reg_init.o soc_v1_0.o
|
||||
cyan_skillfish_reg_init.o soc_v1_0.o lsdma_v7_1.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
|
||||
@@ -246,10 +246,10 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct edid *
|
||||
static const struct drm_edid *
|
||||
amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev)
|
||||
{
|
||||
return drm_edid_duplicate(drm_edid_raw(adev->mode_info.bios_hardcoded_edid));
|
||||
return drm_edid_dup(adev->mode_info.bios_hardcoded_edid);
|
||||
}
|
||||
|
||||
static void amdgpu_connector_get_edid(struct drm_connector *connector)
|
||||
@@ -268,8 +268,8 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
|
||||
if ((amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
|
||||
ENCODER_OBJECT_ID_NONE) &&
|
||||
amdgpu_connector->ddc_bus->has_aux) {
|
||||
amdgpu_connector->edid = drm_get_edid(connector,
|
||||
&amdgpu_connector->ddc_bus->aux.ddc);
|
||||
amdgpu_connector->edid = drm_edid_read_ddc(connector,
|
||||
&amdgpu_connector->ddc_bus->aux.ddc);
|
||||
} else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
||||
struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv;
|
||||
@@ -277,14 +277,14 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
|
||||
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
|
||||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
|
||||
amdgpu_connector->ddc_bus->has_aux)
|
||||
amdgpu_connector->edid = drm_get_edid(connector,
|
||||
&amdgpu_connector->ddc_bus->aux.ddc);
|
||||
amdgpu_connector->edid = drm_edid_read_ddc(connector,
|
||||
&amdgpu_connector->ddc_bus->aux.ddc);
|
||||
else if (amdgpu_connector->ddc_bus)
|
||||
amdgpu_connector->edid = drm_get_edid(connector,
|
||||
&amdgpu_connector->ddc_bus->adapter);
|
||||
amdgpu_connector->edid = drm_edid_read_ddc(connector,
|
||||
&amdgpu_connector->ddc_bus->adapter);
|
||||
} else if (amdgpu_connector->ddc_bus) {
|
||||
amdgpu_connector->edid = drm_get_edid(connector,
|
||||
&amdgpu_connector->ddc_bus->adapter);
|
||||
amdgpu_connector->edid = drm_edid_read_ddc(connector,
|
||||
&amdgpu_connector->ddc_bus->adapter);
|
||||
}
|
||||
|
||||
if (!amdgpu_connector->edid) {
|
||||
@@ -292,30 +292,22 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
|
||||
if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP))) {
|
||||
amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev);
|
||||
drm_connector_update_edid_property(connector, amdgpu_connector->edid);
|
||||
drm_edid_connector_update(connector, amdgpu_connector->edid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void amdgpu_connector_free_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
|
||||
|
||||
kfree(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
}
|
||||
|
||||
static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
|
||||
int ret;
|
||||
|
||||
if (amdgpu_connector->edid) {
|
||||
drm_connector_update_edid_property(connector, amdgpu_connector->edid);
|
||||
ret = drm_add_edid_modes(connector, amdgpu_connector->edid);
|
||||
drm_edid_connector_update(connector, amdgpu_connector->edid);
|
||||
ret = drm_edid_connector_add_modes(connector);
|
||||
return ret;
|
||||
}
|
||||
drm_connector_update_edid_property(connector, NULL);
|
||||
drm_edid_connector_update(connector, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -754,7 +746,7 @@ static void amdgpu_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
|
||||
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
kfree(amdgpu_connector->con_priv);
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
@@ -873,7 +865,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
||||
dret = amdgpu_display_ddc_probe(amdgpu_connector, false);
|
||||
if (dret) {
|
||||
amdgpu_connector->detected_by_load = false;
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector_get_edid(connector);
|
||||
|
||||
if (!amdgpu_connector->edid) {
|
||||
@@ -883,13 +875,13 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
||||
ret = connector_status_connected;
|
||||
} else {
|
||||
amdgpu_connector->use_digital =
|
||||
!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
drm_edid_is_digital(amdgpu_connector->edid);
|
||||
|
||||
/* some oems have boards with separate digital and analog connectors
|
||||
* with a shared ddc line (often vga + hdmi)
|
||||
*/
|
||||
if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
ret = connector_status_disconnected;
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
@@ -984,7 +976,7 @@ static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,
|
||||
/* hpd is our only option in this case */
|
||||
if (!amdgpu_display_hpd_sense(adev,
|
||||
amdgpu_connector->hpd.hpd)) {
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
*status = connector_status_disconnected;
|
||||
}
|
||||
}
|
||||
@@ -1053,7 +1045,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
if (dret) {
|
||||
amdgpu_connector->detected_by_load = false;
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
amdgpu_connector_get_edid(connector);
|
||||
|
||||
if (!amdgpu_connector->edid) {
|
||||
@@ -1063,13 +1055,13 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
||||
broken_edid = true; /* defer use_digital to later */
|
||||
} else {
|
||||
amdgpu_connector->use_digital =
|
||||
!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
drm_edid_is_digital(amdgpu_connector->edid);
|
||||
|
||||
/* some oems have boards with separate digital and analog connectors
|
||||
* with a shared ddc line (often vga + hdmi)
|
||||
*/
|
||||
if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
ret = connector_status_disconnected;
|
||||
} else {
|
||||
ret = connector_status_connected;
|
||||
@@ -1417,7 +1409,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
|
||||
goto out;
|
||||
}
|
||||
|
||||
amdgpu_connector_free_edid(connector);
|
||||
drm_edid_free(amdgpu_connector->edid);
|
||||
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_psp_ta.h"
|
||||
#include "amdgpu_userq.h"
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
@@ -2156,6 +2157,53 @@ static const struct file_operations amdgpu_pt_info_fops = {
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int amdgpu_mqd_info_read(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct amdgpu_usermode_queue *queue = m->private;
|
||||
struct amdgpu_bo *bo;
|
||||
int r;
|
||||
|
||||
if (!queue || !queue->mqd.obj)
|
||||
return -EINVAL;
|
||||
|
||||
bo = amdgpu_bo_ref(queue->mqd.obj);
|
||||
r = amdgpu_bo_reserve(bo, true);
|
||||
if (r) {
|
||||
amdgpu_bo_unref(&bo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
seq_printf(m, "queue_type: %d\n", queue->queue_type);
|
||||
seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj));
|
||||
|
||||
amdgpu_bo_unreserve(bo);
|
||||
amdgpu_bo_unref(&bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_mqd_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, amdgpu_mqd_info_read, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations amdgpu_mqd_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = amdgpu_mqd_info_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
void amdgpu_debugfs_userq_init(struct drm_file *file, struct amdgpu_usermode_queue *queue, int qid)
|
||||
{
|
||||
char queue_name[32];
|
||||
|
||||
scnprintf(queue_name, sizeof(queue_name), "queue_%d", qid);
|
||||
queue->debugfs_queue = debugfs_create_dir(queue_name, file->debugfs_client);
|
||||
debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops);
|
||||
}
|
||||
|
||||
void amdgpu_debugfs_vm_init(struct drm_file *file)
|
||||
{
|
||||
debugfs_create_file("vm_pagetable_info", 0444, file->debugfs_client, file,
|
||||
@@ -2174,4 +2222,9 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
|
||||
void amdgpu_debugfs_vm_init(struct drm_file *file)
|
||||
{
|
||||
}
|
||||
void amdgpu_debugfs_userq_init(struct drm_file *file,
|
||||
struct amdgpu_usermode_queue *queue,
|
||||
int qid)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
/*
|
||||
* Debugfs
|
||||
*/
|
||||
struct amdgpu_usermode_queue;
|
||||
|
||||
int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_init(struct amdgpu_device *adev);
|
||||
@@ -34,4 +35,7 @@ void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_vm_init(struct drm_file *file);
|
||||
void amdgpu_debugfs_userq_init(struct drm_file *file,
|
||||
struct amdgpu_usermode_queue *queue,
|
||||
int qid);
|
||||
|
||||
|
||||
@@ -261,6 +261,8 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_discovery_dump(coredump->adev, &p);
|
||||
|
||||
/* IP firmware information */
|
||||
drm_printf(&p, "\nIP Firmwares\n");
|
||||
amdgpu_devcoredump_fw_info(coredump->adev, &p);
|
||||
|
||||
@@ -1995,8 +1995,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
||||
break;
|
||||
default:
|
||||
r = amdgpu_discovery_set_ip_blocks(adev);
|
||||
if (r)
|
||||
if (r) {
|
||||
adev->num_ip_blocks = 0;
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2550,6 +2552,8 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
|
||||
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
if (!adev->ip_blocks[i].version)
|
||||
continue;
|
||||
/* skip CG for GFX, SDMA on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
|
||||
@@ -2589,6 +2593,8 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
|
||||
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
if (!adev->ip_blocks[i].version)
|
||||
continue;
|
||||
/* skip PG for GFX, SDMA on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
|
||||
@@ -2796,6 +2802,8 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].version)
|
||||
continue;
|
||||
if (!adev->ip_blocks[i].version->funcs->early_fini)
|
||||
continue;
|
||||
|
||||
@@ -2873,6 +2881,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
||||
if (!adev->ip_blocks[i].status.sw)
|
||||
continue;
|
||||
|
||||
if (!adev->ip_blocks[i].version)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
|
||||
amdgpu_ucode_free_bo(adev);
|
||||
amdgpu_free_static_csa(&adev->virt.csa_obj);
|
||||
@@ -2899,6 +2909,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
if (!adev->ip_blocks[i].version)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->funcs->late_fini)
|
||||
adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]);
|
||||
adev->ip_blocks[i].status.late_initialized = false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,10 +30,12 @@
|
||||
#define DISCOVERY_TMR_OFFSET (64 << 10)
|
||||
|
||||
struct ip_discovery_top;
|
||||
struct drm_printer;
|
||||
|
||||
struct amdgpu_discovery_info {
|
||||
struct debugfs_blob_wrapper debugfs_blob;
|
||||
struct ip_discovery_top *ip_top;
|
||||
uint64_t offset;
|
||||
uint32_t size;
|
||||
uint8_t *bin;
|
||||
bool reserve_tmr;
|
||||
@@ -47,4 +49,6 @@ int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
|
||||
struct amdgpu_gmc_memrange **ranges,
|
||||
int *range_cnt, bool refresh);
|
||||
|
||||
void amdgpu_discovery_dump(struct amdgpu_device *adev, struct drm_printer *p);
|
||||
|
||||
#endif /* __AMDGPU_DISCOVERY__ */
|
||||
|
||||
@@ -1738,21 +1738,6 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
|
||||
stime, etime, mode);
|
||||
}
|
||||
|
||||
static bool
|
||||
amdgpu_display_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_fb_helper *fb_helper = dev->fb_helper;
|
||||
|
||||
if (!fb_helper || !fb_helper->buffer)
|
||||
return false;
|
||||
|
||||
if (gem_to_amdgpu_bo(fb_helper->buffer->gem) != robj)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
@@ -1775,7 +1760,6 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_framebuffer *fb = crtc->primary->fb;
|
||||
struct amdgpu_bo *robj;
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
@@ -1790,8 +1774,9 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
||||
if (!fb || !fb->obj[0])
|
||||
continue;
|
||||
|
||||
robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
if (!amdgpu_display_robj_is_fb(adev, robj)) {
|
||||
if (!drm_fb_helper_gem_is_fb(dev->fb_helper, fb->obj[0])) {
|
||||
struct amdgpu_bo *robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
|
||||
r = amdgpu_bo_reserve(robj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(robj);
|
||||
|
||||
@@ -94,6 +94,10 @@ enum amdgpu_memory_partition {
|
||||
#define AMDGPU_GMC9_FAULT_SOURCE_DATA_WRITE 0x20
|
||||
#define AMDGPU_GMC9_FAULT_SOURCE_DATA_EXE 0x10
|
||||
|
||||
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_READ 0x400000
|
||||
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_WRITE 0x200000
|
||||
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_EXE 0x100000
|
||||
|
||||
/*
|
||||
* GMC page fault information
|
||||
*/
|
||||
|
||||
@@ -83,7 +83,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
||||
if (adev == NULL)
|
||||
if (adev == NULL || !adev->num_ip_blocks)
|
||||
return;
|
||||
|
||||
amdgpu_unregister_gpu_instance(adev);
|
||||
|
||||
@@ -159,9 +159,9 @@ struct amdgpu_mes {
|
||||
|
||||
int hung_queue_db_array_size;
|
||||
int hung_queue_hqd_info_offset;
|
||||
struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_PIPES];
|
||||
uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_PIPES];
|
||||
void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_PIPES];
|
||||
struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_INST_PIPES];
|
||||
uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
|
||||
void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_INST_PIPES];
|
||||
|
||||
/* cooperative dispatch */
|
||||
bool enable_coop_mode;
|
||||
|
||||
@@ -368,15 +368,15 @@ struct amdgpu_mode_info {
|
||||
|
||||
struct drm_property *plane_ctm_property;
|
||||
/**
|
||||
* @shaper_lut_property: Plane property to set pre-blending shaper LUT
|
||||
* that converts color content before 3D LUT. If
|
||||
* plane_shaper_tf_property != Identity TF, AMD color module will
|
||||
* @plane_shaper_lut_property: Plane property to set pre-blending
|
||||
* shaper LUT that converts color content before 3D LUT.
|
||||
* If plane_shaper_tf_property != Identity TF, AMD color module will
|
||||
* combine the user LUT values with pre-defined TF into the LUT
|
||||
* parameters to be programmed.
|
||||
*/
|
||||
struct drm_property *plane_shaper_lut_property;
|
||||
/**
|
||||
* @shaper_lut_size_property: Plane property for the size of
|
||||
* @plane_shaper_lut_size_property: Plane property for the size of
|
||||
* pre-blending shaper LUT as supported by the driver (read-only).
|
||||
*/
|
||||
struct drm_property *plane_shaper_lut_size_property;
|
||||
@@ -400,10 +400,10 @@ struct amdgpu_mode_info {
|
||||
*/
|
||||
struct drm_property *plane_lut3d_property;
|
||||
/**
|
||||
* @plane_degamma_lut_size_property: Plane property to define the max
|
||||
* size of 3D LUT as supported by the driver (read-only). The max size
|
||||
* is the max size of one dimension and, therefore, the max number of
|
||||
* entries for 3D LUT array is the 3D LUT size cubed;
|
||||
* @plane_lut3d_size_property: Plane property to define the max size
|
||||
* of 3D LUT as supported by the driver (read-only). The max size is
|
||||
* the max size of one dimension and, therefore, the max number of
|
||||
* entries for 3D LUT array is the 3D LUT size cubed.
|
||||
*/
|
||||
struct drm_property *plane_lut3d_size_property;
|
||||
/**
|
||||
@@ -624,7 +624,7 @@ struct amdgpu_connector {
|
||||
bool use_digital;
|
||||
/* we need to mind the EDID between detect
|
||||
and get modes due to analog/digital/tvencoder */
|
||||
struct edid *edid;
|
||||
const struct drm_edid *edid;
|
||||
void *con_priv;
|
||||
bool dac_load_detect;
|
||||
bool detected_by_load; /* if the connection status was determined by load */
|
||||
|
||||
@@ -3096,6 +3096,13 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
|
||||
*/
|
||||
continue;
|
||||
|
||||
/* IMU ucode is part of IFWI and MP0 15.0.8 would load it */
|
||||
if (amdgpu_ip_version(adev, MP0_HWIP, 0) ==
|
||||
IP_VERSION(15, 0, 8) &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_IMU_I ||
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_IMU_D))
|
||||
continue;
|
||||
|
||||
psp_print_fw_hdr(psp, ucode);
|
||||
|
||||
ret = psp_execute_ip_fw_load(psp, ucode);
|
||||
|
||||
@@ -291,22 +291,22 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
|
||||
break;
|
||||
case 5:
|
||||
/* rlc_hdr v2_5 */
|
||||
DRM_INFO("rlc_iram_ucode_size_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_size_bytes));
|
||||
DRM_INFO("rlc_iram_ucode_offset_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_offset_bytes));
|
||||
DRM_INFO("rlc_dram_ucode_size_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_size_bytes));
|
||||
DRM_INFO("rlc_dram_ucode_offset_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_offset_bytes));
|
||||
/* rlc_hdr v2_5 */
|
||||
DRM_INFO("rlc_1_iram_ucode_size_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_1_iram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_size_bytes));
|
||||
DRM_INFO("rlc_1_iram_ucode_offset_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_1_iram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_offset_bytes));
|
||||
DRM_INFO("rlc_1_dram_ucode_size_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_1_dram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_size_bytes));
|
||||
DRM_INFO("rlc_1_dram_ucode_offset_bytes: %u\n",
|
||||
DRM_DEBUG("rlc_1_dram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_offset_bytes));
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -709,46 +709,6 @@ static int amdgpu_userq_priority_permit(struct drm_file *filp,
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static int amdgpu_mqd_info_read(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct amdgpu_usermode_queue *queue = m->private;
|
||||
struct amdgpu_bo *bo;
|
||||
int r;
|
||||
|
||||
if (!queue || !queue->mqd.obj)
|
||||
return -EINVAL;
|
||||
|
||||
bo = amdgpu_bo_ref(queue->mqd.obj);
|
||||
r = amdgpu_bo_reserve(bo, true);
|
||||
if (r) {
|
||||
amdgpu_bo_unref(&bo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
seq_printf(m, "queue_type: %d\n", queue->queue_type);
|
||||
seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj));
|
||||
|
||||
amdgpu_bo_unreserve(bo);
|
||||
amdgpu_bo_unref(&bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_mqd_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, amdgpu_mqd_info_read, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations amdgpu_mqd_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = amdgpu_mqd_info_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int
|
||||
amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
|
||||
{
|
||||
@@ -758,7 +718,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
|
||||
const struct amdgpu_userq_funcs *uq_funcs;
|
||||
struct amdgpu_usermode_queue *queue;
|
||||
struct amdgpu_db_info db_info;
|
||||
char *queue_name;
|
||||
bool skip_map_queue;
|
||||
u32 qid;
|
||||
uint64_t index;
|
||||
@@ -819,17 +778,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
|
||||
amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) ||
|
||||
amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) {
|
||||
r = -EINVAL;
|
||||
kfree(queue);
|
||||
goto unlock;
|
||||
goto free_queue;
|
||||
}
|
||||
|
||||
/* Convert relative doorbell offset into absolute doorbell index */
|
||||
index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp);
|
||||
if (index == (uint64_t)-EINVAL) {
|
||||
drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n");
|
||||
kfree(queue);
|
||||
r = -EINVAL;
|
||||
goto unlock;
|
||||
goto free_queue;
|
||||
}
|
||||
|
||||
queue->doorbell_index = index;
|
||||
@@ -837,42 +794,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
|
||||
r = amdgpu_userq_fence_driver_alloc(adev, queue);
|
||||
if (r) {
|
||||
drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n");
|
||||
goto unlock;
|
||||
goto free_queue;
|
||||
}
|
||||
|
||||
r = uq_funcs->mqd_create(queue, &args->in);
|
||||
if (r) {
|
||||
drm_file_err(uq_mgr->file, "Failed to create Queue\n");
|
||||
amdgpu_userq_fence_driver_free(queue);
|
||||
kfree(queue);
|
||||
goto unlock;
|
||||
goto clean_fence_driver;
|
||||
}
|
||||
|
||||
/* drop this refcount during queue destroy */
|
||||
kref_init(&queue->refcount);
|
||||
|
||||
/* Wait for mode-1 reset to complete */
|
||||
down_read(&adev->reset_domain->sem);
|
||||
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
|
||||
if (r) {
|
||||
kfree(queue);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
r = xa_alloc(&uq_mgr->userq_xa, &qid, queue,
|
||||
XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
|
||||
if (r) {
|
||||
drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n");
|
||||
amdgpu_userq_fence_driver_free(queue);
|
||||
uq_funcs->mqd_destroy(queue);
|
||||
kfree(queue);
|
||||
r = -ENOMEM;
|
||||
up_read(&adev->reset_domain->sem);
|
||||
goto unlock;
|
||||
}
|
||||
up_read(&adev->reset_domain->sem);
|
||||
|
||||
/* don't map the queue if scheduling is halted */
|
||||
if (adev->userq_halt_for_enforce_isolation &&
|
||||
((queue->queue_type == AMDGPU_HW_IP_GFX) ||
|
||||
@@ -884,31 +814,52 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
|
||||
r = amdgpu_userq_map_helper(queue);
|
||||
if (r) {
|
||||
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
|
||||
xa_erase(&uq_mgr->userq_xa, qid);
|
||||
amdgpu_userq_fence_driver_free(queue);
|
||||
uq_funcs->mqd_destroy(queue);
|
||||
kfree(queue);
|
||||
goto unlock;
|
||||
down_read(&adev->reset_domain->sem);
|
||||
goto clean_mqd;
|
||||
}
|
||||
}
|
||||
|
||||
queue_name = kasprintf(GFP_KERNEL, "queue-%d", qid);
|
||||
if (!queue_name) {
|
||||
/* drop this refcount during queue destroy */
|
||||
kref_init(&queue->refcount);
|
||||
|
||||
/* Wait for mode-1 reset to complete */
|
||||
down_read(&adev->reset_domain->sem);
|
||||
|
||||
r = xa_alloc(&uq_mgr->userq_xa, &qid, queue,
|
||||
XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
|
||||
if (r) {
|
||||
if (!skip_map_queue)
|
||||
amdgpu_userq_unmap_helper(queue);
|
||||
|
||||
r = -ENOMEM;
|
||||
goto unlock;
|
||||
goto clean_mqd;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
/* Queue dentry per client to hold MQD information */
|
||||
queue->debugfs_queue = debugfs_create_dir(queue_name, filp->debugfs_client);
|
||||
debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops);
|
||||
#endif
|
||||
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
|
||||
if (r) {
|
||||
xa_erase(&uq_mgr->userq_xa, qid);
|
||||
if (!skip_map_queue)
|
||||
amdgpu_userq_unmap_helper(queue);
|
||||
|
||||
goto clean_mqd;
|
||||
}
|
||||
up_read(&adev->reset_domain->sem);
|
||||
|
||||
amdgpu_debugfs_userq_init(filp, queue, qid);
|
||||
amdgpu_userq_init_hang_detect_work(queue);
|
||||
kfree(queue_name);
|
||||
|
||||
args->out.queue_id = qid;
|
||||
atomic_inc(&uq_mgr->userq_count[queue->queue_type]);
|
||||
mutex_unlock(&uq_mgr->userq_mutex);
|
||||
return 0;
|
||||
|
||||
clean_mqd:
|
||||
uq_funcs->mqd_destroy(queue);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
clean_fence_driver:
|
||||
amdgpu_userq_fence_driver_free(queue);
|
||||
free_queue:
|
||||
kfree(queue);
|
||||
unlock:
|
||||
mutex_unlock(&uq_mgr->userq_mutex);
|
||||
|
||||
@@ -1089,12 +1040,12 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
|
||||
struct amdgpu_bo *bo;
|
||||
int ret;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
while (!list_empty(&vm->invalidated)) {
|
||||
bo_va = list_first_entry(&vm->invalidated,
|
||||
struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
bo = bo_va->base.bo;
|
||||
ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 2);
|
||||
@@ -1111,9 +1062,9 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,6 +162,7 @@ enum AMDGIM_FEATURE_FLAG {
|
||||
AMDGIM_FEATURE_RAS_TELEMETRY = (1 << 10),
|
||||
AMDGIM_FEATURE_RAS_CPER = (1 << 11),
|
||||
AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK = (1 << 12),
|
||||
AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU = (1 << 13),
|
||||
};
|
||||
|
||||
enum AMDGIM_REG_ACCESS_FLAG {
|
||||
@@ -412,6 +413,9 @@ struct amdgpu_video_codec_info;
|
||||
#define amdgpu_sriov_xgmi_ta_ext_peer_link_en(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK)
|
||||
|
||||
#define amdgpu_sriov_xgmi_connected_to_cpu(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU)
|
||||
|
||||
static inline bool is_virtual_machine(void)
|
||||
{
|
||||
#if defined(CONFIG_X86)
|
||||
|
||||
@@ -153,12 +153,10 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
|
||||
|
||||
vm_bo->moved = true;
|
||||
amdgpu_vm_assert_locked(vm);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
if (bo->tbo.type == ttm_bo_type_kernel)
|
||||
list_move(&vm_bo->vm_status, &vm->evicted);
|
||||
else
|
||||
list_move_tail(&vm_bo->vm_status, &vm->evicted);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
/**
|
||||
* amdgpu_vm_bo_moved - vm_bo is moved
|
||||
@@ -171,9 +169,7 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
|
||||
static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
amdgpu_vm_assert_locked(vm_bo->vm);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,9 +183,7 @@ static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
|
||||
static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
amdgpu_vm_assert_locked(vm_bo->vm);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->idle);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
vm_bo->moved = false;
|
||||
}
|
||||
|
||||
@@ -203,9 +197,9 @@ static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
spin_lock(&vm_bo->vm->invalidated_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
spin_unlock(&vm_bo->vm->invalidated_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,10 +212,9 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
amdgpu_vm_assert_locked(vm_bo->vm);
|
||||
vm_bo->moved = true;
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->evicted_user);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,13 +228,10 @@ static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
|
||||
static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
amdgpu_vm_assert_locked(vm_bo->vm);
|
||||
if (vm_bo->bo->parent) {
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
if (vm_bo->bo->parent)
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
} else {
|
||||
else
|
||||
amdgpu_vm_bo_idle(vm_bo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,9 +245,7 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
amdgpu_vm_assert_locked(vm_bo->vm);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->done);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,13 +259,13 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *vm_bo, *tmp;
|
||||
|
||||
amdgpu_vm_assert_locked(vm);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_splice_init(&vm->done, &vm->invalidated);
|
||||
list_for_each_entry(vm_bo, &vm->invalidated, vm_status)
|
||||
vm_bo->moved = true;
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
amdgpu_vm_assert_locked(vm);
|
||||
list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) {
|
||||
struct amdgpu_bo *bo = vm_bo->bo;
|
||||
|
||||
@@ -287,14 +275,13 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
|
||||
else if (bo->parent)
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_update_shared - helper to update shared memory stat
|
||||
* @base: base structure for tracking BO usage in a VM
|
||||
*
|
||||
* Takes the vm status_lock and updates the shared memory stat. If the basic
|
||||
* Takes the vm stats_lock and updates the shared memory stat. If the basic
|
||||
* stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called
|
||||
* as well.
|
||||
*/
|
||||
@@ -307,7 +294,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
|
||||
bool shared;
|
||||
|
||||
dma_resv_assert_held(bo->tbo.base.resv);
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->stats_lock);
|
||||
shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
|
||||
if (base->shared != shared) {
|
||||
base->shared = shared;
|
||||
@@ -319,7 +306,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
|
||||
vm->stats[bo_memtype].drm.private += size;
|
||||
}
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->stats_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,11 +331,11 @@ void amdgpu_vm_bo_update_shared(struct amdgpu_bo *bo)
|
||||
* be bo->tbo.resource
|
||||
* @sign: if we should add (+1) or subtract (-1) from the stat
|
||||
*
|
||||
* Caller need to have the vm status_lock held. Useful for when multiple update
|
||||
* Caller need to have the vm stats_lock held. Useful for when multiple update
|
||||
* need to happen at the same time.
|
||||
*/
|
||||
static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
|
||||
struct ttm_resource *res, int sign)
|
||||
struct ttm_resource *res, int sign)
|
||||
{
|
||||
struct amdgpu_vm *vm = base->vm;
|
||||
struct amdgpu_bo *bo = base->bo;
|
||||
@@ -372,7 +359,8 @@ static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
|
||||
*/
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE)
|
||||
vm->stats[res_memtype].drm.purgeable += size;
|
||||
if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(res_memtype)))
|
||||
if (!(bo->preferred_domains &
|
||||
amdgpu_mem_type_to_domain(res_memtype)))
|
||||
vm->stats[bo_memtype].evicted += size;
|
||||
}
|
||||
}
|
||||
@@ -391,9 +379,9 @@ void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base,
|
||||
{
|
||||
struct amdgpu_vm *vm = base->vm;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->stats_lock);
|
||||
amdgpu_vm_update_stats_locked(base, res, sign);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->stats_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,10 +407,10 @@ void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
|
||||
base->next = bo->vm_bo;
|
||||
bo->vm_bo = base;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->stats_lock);
|
||||
base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
|
||||
amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->stats_lock);
|
||||
|
||||
if (!amdgpu_vm_is_bo_always_valid(vm, bo))
|
||||
return;
|
||||
@@ -481,25 +469,25 @@ int amdgpu_vm_lock_done_list(struct amdgpu_vm *vm, struct drm_exec *exec,
|
||||
int ret;
|
||||
|
||||
/* We can only trust prev->next while holding the lock */
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
while (!list_is_head(prev->next, &vm->done)) {
|
||||
bo_va = list_entry(prev->next, typeof(*bo_va), base.vm_status);
|
||||
|
||||
bo = bo_va->base.bo;
|
||||
if (bo) {
|
||||
amdgpu_bo_ref(bo);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 1);
|
||||
amdgpu_bo_unref(&bo);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
}
|
||||
prev = prev->next;
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -595,7 +583,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
void *param)
|
||||
{
|
||||
uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm);
|
||||
struct amdgpu_vm_bo_base *bo_base;
|
||||
struct amdgpu_vm_bo_base *bo_base, *tmp;
|
||||
struct amdgpu_bo *bo;
|
||||
int r;
|
||||
|
||||
@@ -608,13 +596,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
return r;
|
||||
}
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
while (!list_empty(&vm->evicted)) {
|
||||
bo_base = list_first_entry(&vm->evicted,
|
||||
struct amdgpu_vm_bo_base,
|
||||
vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {
|
||||
bo = bo_base->bo;
|
||||
|
||||
r = validate(param, bo);
|
||||
@@ -627,26 +609,21 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
|
||||
amdgpu_vm_bo_relocated(bo_base);
|
||||
}
|
||||
spin_lock(&vm->status_lock);
|
||||
}
|
||||
while (ticket && !list_empty(&vm->evicted_user)) {
|
||||
bo_base = list_first_entry(&vm->evicted_user,
|
||||
struct amdgpu_vm_bo_base,
|
||||
vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
bo = bo_base->bo;
|
||||
dma_resv_assert_held(bo->tbo.base.resv);
|
||||
if (ticket) {
|
||||
list_for_each_entry_safe(bo_base, tmp, &vm->evicted_user,
|
||||
vm_status) {
|
||||
bo = bo_base->bo;
|
||||
dma_resv_assert_held(bo->tbo.base.resv);
|
||||
|
||||
r = validate(param, bo);
|
||||
if (r)
|
||||
return r;
|
||||
r = validate(param, bo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_bo_invalidated(bo_base);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
amdgpu_vm_bo_invalidated(bo_base);
|
||||
}
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
vm->evicting = false;
|
||||
@@ -675,9 +652,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
|
||||
ret = !vm->evicting;
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
ret &= list_empty(&vm->evicted);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
spin_lock(&vm->immediate.lock);
|
||||
ret &= !vm->immediate.stopped;
|
||||
@@ -971,18 +946,13 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm, bool immediate)
|
||||
{
|
||||
struct amdgpu_vm_update_params params;
|
||||
struct amdgpu_vm_bo_base *entry;
|
||||
struct amdgpu_vm_bo_base *entry, *tmp;
|
||||
bool flush_tlb_needed = false;
|
||||
LIST_HEAD(relocated);
|
||||
int r, idx;
|
||||
|
||||
amdgpu_vm_assert_locked(vm);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
list_splice_init(&vm->relocated, &relocated);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
if (list_empty(&relocated))
|
||||
if (list_empty(&vm->relocated))
|
||||
return 0;
|
||||
|
||||
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||
@@ -998,7 +968,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
list_for_each_entry(entry, &relocated, vm_status) {
|
||||
list_for_each_entry(entry, &vm->relocated, vm_status) {
|
||||
/* vm_flush_needed after updating moved PDEs */
|
||||
flush_tlb_needed |= entry->moved;
|
||||
|
||||
@@ -1014,9 +984,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
if (flush_tlb_needed)
|
||||
atomic64_inc(&vm->tlb_seq);
|
||||
|
||||
while (!list_empty(&relocated)) {
|
||||
entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base,
|
||||
vm_status);
|
||||
list_for_each_entry_safe(entry, tmp, &vm->relocated, vm_status) {
|
||||
amdgpu_vm_bo_idle(entry);
|
||||
}
|
||||
|
||||
@@ -1243,9 +1211,9 @@ error_free:
|
||||
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
|
||||
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM])
|
||||
{
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->stats_lock);
|
||||
memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->stats_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1612,29 +1580,24 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
struct ww_acquire_ctx *ticket)
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va;
|
||||
struct amdgpu_bo_va *bo_va, *tmp;
|
||||
struct dma_resv *resv;
|
||||
bool clear, unlock;
|
||||
int r;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
while (!list_empty(&vm->moved)) {
|
||||
bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
|
||||
/* Per VM BOs never need to bo cleared in the page tables */
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
if (r)
|
||||
return r;
|
||||
spin_lock(&vm->status_lock);
|
||||
}
|
||||
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
while (!list_empty(&vm->invalidated)) {
|
||||
bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
resv = bo_va->base.bo->tbo.base.resv;
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
/* Try to reserve the BO to avoid clearing its ptes */
|
||||
if (!adev->debug_vm && dma_resv_trylock(resv)) {
|
||||
@@ -1666,9 +1629,9 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
||||
bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM))
|
||||
amdgpu_vm_bo_evicted_user(&bo_va->base);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2211,9 +2174,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_del(&bo_va->base.vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
|
||||
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
|
||||
list_del(&mapping->list);
|
||||
@@ -2321,10 +2284,10 @@ void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem,
|
||||
for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
|
||||
struct amdgpu_vm *vm = bo_base->vm;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
spin_lock(&vm->stats_lock);
|
||||
amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1);
|
||||
amdgpu_vm_update_stats_locked(bo_base, new_mem, +1);
|
||||
spin_unlock(&vm->status_lock);
|
||||
spin_unlock(&vm->stats_lock);
|
||||
}
|
||||
|
||||
amdgpu_vm_bo_invalidate(bo, evicted);
|
||||
@@ -2593,11 +2556,12 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
INIT_LIST_HEAD(&vm->relocated);
|
||||
INIT_LIST_HEAD(&vm->moved);
|
||||
INIT_LIST_HEAD(&vm->idle);
|
||||
spin_lock_init(&vm->invalidated_lock);
|
||||
INIT_LIST_HEAD(&vm->invalidated);
|
||||
spin_lock_init(&vm->status_lock);
|
||||
INIT_LIST_HEAD(&vm->freed);
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
INIT_KFIFO(vm->faults);
|
||||
spin_lock_init(&vm->stats_lock);
|
||||
|
||||
r = amdgpu_vm_init_entities(adev, vm);
|
||||
if (r)
|
||||
@@ -3065,7 +3029,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
|
||||
amdgpu_vm_assert_locked(vm);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
seq_puts(m, "\tIdle BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
@@ -3103,11 +3066,13 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tInvalidated BOs:\n");
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
total_invalidated_objs = id;
|
||||
id = 0;
|
||||
|
||||
@@ -3117,7 +3082,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
continue;
|
||||
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
total_done_objs = id;
|
||||
|
||||
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,
|
||||
|
||||
@@ -205,11 +205,11 @@ struct amdgpu_vm_bo_base {
|
||||
/* protected by bo being reserved */
|
||||
struct amdgpu_vm_bo_base *next;
|
||||
|
||||
/* protected by vm status_lock */
|
||||
/* protected by vm reservation and invalidated_lock */
|
||||
struct list_head vm_status;
|
||||
|
||||
/* if the bo is counted as shared in mem stats
|
||||
* protected by vm status_lock */
|
||||
* protected by vm BO being reserved */
|
||||
bool shared;
|
||||
|
||||
/* protected by the BO being reserved */
|
||||
@@ -345,10 +345,8 @@ struct amdgpu_vm {
|
||||
bool evicting;
|
||||
unsigned int saved_flags;
|
||||
|
||||
/* Lock to protect vm_bo add/del/move on all lists of vm */
|
||||
spinlock_t status_lock;
|
||||
|
||||
/* Memory statistics for this vm, protected by status_lock */
|
||||
/* Memory statistics for this vm, protected by stats_lock */
|
||||
spinlock_t stats_lock;
|
||||
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM];
|
||||
|
||||
/*
|
||||
@@ -356,6 +354,8 @@ struct amdgpu_vm {
|
||||
* PDs, PTs or per VM BOs. The state transits are:
|
||||
*
|
||||
* evicted -> relocated (PDs, PTs) or moved (per VM BOs) -> idle
|
||||
*
|
||||
* Lists are protected by the root PD dma_resv lock.
|
||||
*/
|
||||
|
||||
/* Per-VM and PT BOs who needs a validation */
|
||||
@@ -376,7 +376,10 @@ struct amdgpu_vm {
|
||||
* state transits are:
|
||||
*
|
||||
* evicted_user or invalidated -> done
|
||||
*
|
||||
* Lists are protected by the invalidated_lock.
|
||||
*/
|
||||
spinlock_t invalidated_lock;
|
||||
|
||||
/* BOs for user mode queues that need a validation */
|
||||
struct list_head evicted_user;
|
||||
|
||||
@@ -544,9 +544,7 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
|
||||
entry->bo->vm_bo = NULL;
|
||||
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
|
||||
|
||||
spin_lock(&entry->vm->status_lock);
|
||||
list_del(&entry->vm_status);
|
||||
spin_unlock(&entry->vm->status_lock);
|
||||
amdgpu_bo_unref(&entry->bo);
|
||||
}
|
||||
|
||||
@@ -590,7 +588,6 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
|
||||
struct amdgpu_vm_pt_cursor seek;
|
||||
struct amdgpu_vm_bo_base *entry;
|
||||
|
||||
spin_lock(¶ms->vm->status_lock);
|
||||
for_each_amdgpu_vm_pt_dfs_safe(params->adev, params->vm, cursor, seek, entry) {
|
||||
if (entry && entry->bo)
|
||||
list_move(&entry->vm_status, ¶ms->tlb_flush_waitlist);
|
||||
@@ -598,7 +595,6 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
|
||||
|
||||
/* enter start node now */
|
||||
list_move(&cursor->entry->vm_status, ¶ms->tlb_flush_waitlist);
|
||||
spin_unlock(¶ms->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user