Skip to content

Commit

Permalink
Merge tag 'amd-drm-next-5.8-2020-05-12' of git://people.freedesktop.o…
Browse files Browse the repository at this point in the history
…rg/~agd5f/linux into drm-next

amd-drm-next-5.8-2020-05-12:

amdgpu:
- Misc cleanups
- RAS fixes
- Expose FP16 for modesetting
- DP 1.4 compliance test fixes
- Clockgating fixes
- MAINTAINERS update
- Soft recovery for gfx10
- Runtime PM cleanups
- PSP code cleanups

amdkfd:
- Track GPU memory utilization per process
- Report PCI domain in topology

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200512213703.4039-1-alexander.deucher@amd.com
  • Loading branch information
Dave Airlie committed May 14, 2020
2 parents a1fb548 + 37e4f05 commit 49eea1c
Show file tree
Hide file tree
Showing 98 changed files with 1,549 additions and 1,981 deletions.
1 change: 0 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -14063,7 +14063,6 @@ F: drivers/net/wireless/quantenna
RADEON and AMDGPU DRM DRIVERS
M: Alex Deucher <alexander.deucher@amd.com>
M: Christian König <christian.koenig@amd.com>
M: David (ChunMing) Zhou <David1.Zhou@amd.com>
L: amd-gfx@lists.freedesktop.org
S: Supported
T: git git://people.freedesktop.org/~agd5f/linux
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,6 @@ struct amdgpu_device {
uint8_t *bios;
uint32_t bios_size;
struct amdgpu_bo *stolen_vga_memory;
struct amdgpu_bo *discovery_memory;
uint32_t bios_scratch_reg_offset;
uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];

Expand Down Expand Up @@ -918,7 +917,9 @@ struct amdgpu_device {
struct amdgpu_display_manager dm;

/* discovery */
uint8_t *discovery;
uint8_t *discovery_bin;
uint32_t discovery_tmr_size;
struct amdgpu_bo *discovery_memory;

/* mes */
bool enable_mes;
Expand Down Expand Up @@ -957,6 +958,7 @@ struct amdgpu_device {

/* s3/s4 mask */
bool in_suspend;
bool in_hibernate;

bool in_gpu_reset;
enum pp_mp1_state mp1_state;
Expand Down
22 changes: 21 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,

DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);

/* todo: add DC handling */
if ((req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) &&
!amdgpu_device_has_dc_support(adev)) {
struct amdgpu_encoder *enc = atif->encoder_for_bl;
Expand All @@ -463,6 +462,27 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
#endif
}
}
#if defined(CONFIG_DRM_AMD_DC)
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
if ((req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) &&
amdgpu_device_has_dc_support(adev)) {
struct amdgpu_display_manager *dm = &adev->dm;
struct backlight_device *bd = dm->backlight_dev;

if (bd) {
DRM_DEBUG_DRIVER("Changing brightness to %d\n",
req.backlight_level);

/*
* XXX backlight_device_set_brightness() is
* hardwired to post BACKLIGHT_UPDATE_SYSFS.
* It probably should accept 'reason' parameter.
*/
backlight_device_set_brightness(bd, req.backlight_level);
}
}
#endif
#endif
if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
if (adev->flags & AMD_IS_PX) {
pm_runtime_get_sync(adev->ddev->dev);
Expand Down
6 changes: 5 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct kgd_mem {
struct amdgpu_sync sync;

bool aql_queue;
bool is_imported;
};

/* KFD Memory Eviction */
Expand Down Expand Up @@ -148,6 +149,9 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev);

void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd);

int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
int queue_bit);

/* Shared API */
int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
void **mem_obj, uint64_t *gpu_addr,
Expand Down Expand Up @@ -219,7 +223,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
void *vm, struct kgd_mem **mem,
uint64_t *offset, uint32_t flags);
int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem);
struct kgd_dev *kgd, struct kgd_mem *mem, uint64_t *size);
int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem, void *vm);
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
Expand Down
21 changes: 18 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
}

int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem)
struct kgd_dev *kgd, struct kgd_mem *mem, uint64_t *size)
{
struct amdkfd_process_info *process_info = mem->process_info;
unsigned long bo_size = mem->bo->tbo.mem.size;
Expand All @@ -1286,9 +1286,11 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct ttm_validate_buffer *bo_list_entry;
unsigned int mapped_to_gpu_memory;
int ret;
bool is_imported = 0;

mutex_lock(&mem->lock);
mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
is_imported = mem->is_imported;
mutex_unlock(&mem->lock);
/* lock is not needed after this, since mem is unused and will
* be freed anyway
Expand Down Expand Up @@ -1340,8 +1342,19 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
kfree(mem->bo->tbo.sg);
}

/* Update the size of the BO being freed if it was allocated from
* VRAM and is not imported.
*/
if (size) {
if ((mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_VRAM) &&
(!is_imported))
*size = bo_size;
else
*size = 0;
}

/* Free the BO*/
amdgpu_bo_unref(&mem->bo);
drm_gem_object_put_unlocked(&mem->bo->tbo.base);
mutex_destroy(&mem->lock);
kfree(mem);

Expand Down Expand Up @@ -1686,14 +1699,16 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
| KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE
| KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE;

(*mem)->bo = amdgpu_bo_ref(bo);
drm_gem_object_get(&bo->tbo.base);
(*mem)->bo = bo;
(*mem)->va = va;
(*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
(*mem)->mapped_to_gpu_memory = 0;
(*mem)->process_info = avm->process_info;
add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, false);
amdgpu_sync_create(&(*mem)->sync);
(*mem)->is_imported = true;

return 0;
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct drm_sched_entity *entity = p->entity;
enum drm_sched_priority priority;
struct amdgpu_bo_list_entry *e;
struct amdgpu_job *job;
uint64_t seq;
Expand Down Expand Up @@ -1258,7 +1257,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,

trace_amdgpu_cs_ioctl(job);
amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
priority = job->base.s_priority;
drm_sched_entity_push_job(&job->base, entity);

amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
Expand Down
137 changes: 113 additions & 24 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@

#include <linux/suspend.h>
#include <drm/task_barrier.h>
#include <linux/pm_runtime.h>

MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin");
Expand Down Expand Up @@ -254,6 +255,32 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
uint32_t hi = ~0;
uint64_t last;


#ifdef CONFIG_64BIT
last = min(pos + size, adev->gmc.visible_vram_size);
if (last > pos) {
void __iomem *addr = adev->mman.aper_base_kaddr + pos;
size_t count = last - pos;

if (write) {
memcpy_toio(addr, buf, count);
mb();
amdgpu_asic_flush_hdp(adev, NULL);
} else {
amdgpu_asic_invalidate_hdp(adev, NULL);
mb();
memcpy_fromio(buf, addr, count);
}

if (count == size)
return;

pos += count;
buf += count / 4;
size -= count;
}
#endif

spin_lock_irqsave(&adev->mmio_idx_lock, flags);
for (last = pos + size; pos < last; pos += 4) {
uint32_t tmp = pos >> 31;
Expand Down Expand Up @@ -2891,6 +2918,14 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
return ret;
}

static const struct attribute *amdgpu_dev_attributes[] = {
&dev_attr_product_name.attr,
&dev_attr_product_number.attr,
&dev_attr_serial_number.attr,
&dev_attr_pcie_replay_count.attr,
NULL
};

/**
* amdgpu_device_init - initialize the driver
*
Expand Down Expand Up @@ -3240,27 +3275,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
queue_delayed_work(system_wq, &adev->delayed_init_work,
msecs_to_jiffies(AMDGPU_RESUME_MS));

r = device_create_file(adev->dev, &dev_attr_pcie_replay_count);
r = sysfs_create_files(&adev->dev->kobj, amdgpu_dev_attributes);
if (r) {
dev_err(adev->dev, "Could not create pcie_replay_count");
return r;
}

r = device_create_file(adev->dev, &dev_attr_product_name);
if (r) {
dev_err(adev->dev, "Could not create product_name");
return r;
}

r = device_create_file(adev->dev, &dev_attr_product_number);
if (r) {
dev_err(adev->dev, "Could not create product_number");
return r;
}

r = device_create_file(adev->dev, &dev_attr_serial_number);
if (r) {
dev_err(adev->dev, "Could not create serial_number");
dev_err(adev->dev, "Could not create amdgpu device attr\n");
return r;
}

Expand Down Expand Up @@ -3343,12 +3360,10 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
adev->rmmio = NULL;
amdgpu_device_doorbell_fini(adev);

device_remove_file(adev->dev, &dev_attr_pcie_replay_count);
if (adev->ucode_sysfs_en)
amdgpu_ucode_sysfs_fini(adev);
device_remove_file(adev->dev, &dev_attr_product_name);
device_remove_file(adev->dev, &dev_attr_product_number);
device_remove_file(adev->dev, &dev_attr_serial_number);

sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes);
if (IS_ENABLED(CONFIG_PERF_EVENTS))
amdgpu_pmu_fini(adev);
if (amdgpu_discovery && adev->asic_type >= CHIP_NAVI10)
Expand Down Expand Up @@ -4116,6 +4131,64 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
mutex_unlock(&adev->lock_reset);
}

static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
{
struct pci_dev *p = NULL;

p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
adev->pdev->bus->number, 1);
if (p) {
pm_runtime_enable(&(p->dev));
pm_runtime_resume(&(p->dev));
}
}

static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
{
enum amd_reset_method reset_method;
struct pci_dev *p = NULL;
u64 expires;

/*
* For now, only BACO and mode1 reset are confirmed
* to suffer the audio issue without proper suspended.
*/
reset_method = amdgpu_asic_reset_method(adev);
if ((reset_method != AMD_RESET_METHOD_BACO) &&
(reset_method != AMD_RESET_METHOD_MODE1))
return -EINVAL;

p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
adev->pdev->bus->number, 1);
if (!p)
return -ENODEV;

expires = pm_runtime_autosuspend_expiration(&(p->dev));
if (!expires)
/*
* If we cannot get the audio device autosuspend delay,
* a fixed 4S interval will be used. Considering 3S is
* the audio controller default autosuspend delay setting.
* 4S used here is guaranteed to cover that.
*/
expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4ULL;

while (!pm_runtime_status_suspended(&(p->dev))) {
if (!pm_runtime_suspend(&(p->dev)))
break;

if (expires < ktime_get_mono_fast_ns()) {
dev_warn(adev->dev, "failed to suspend display audio\n");
/* TODO: abort the succeeding gpu reset? */
return -ETIMEDOUT;
}
}

pm_runtime_disable(&(p->dev));

return 0;
}

/**
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
*
Expand All @@ -4140,6 +4213,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
bool use_baco =
(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) ?
true : false;
bool audio_suspended = false;

/*
* Flush RAM to disk so that after reboot
Expand Down Expand Up @@ -4197,6 +4271,19 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
return 0;
}

/*
* Try to put the audio codec into suspend state
* before gpu reset started.
*
* Due to the power domain of the graphics device
* is shared with AZ power domain. Without this,
* we may change the audio hardware from behind
* the audio driver's back. That will trigger
* some audio codec errors.
*/
if (!amdgpu_device_suspend_display_audio(tmp_adev))
audio_suspended = true;

amdgpu_ras_set_error_query_ready(tmp_adev, false);

cancel_delayed_work_sync(&tmp_adev->delayed_init_work);
Expand Down Expand Up @@ -4309,6 +4396,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
/*unlock kfd: SRIOV would do it separately */
if (!(in_ras_intr && !use_baco) && !amdgpu_sriov_vf(tmp_adev))
amdgpu_amdkfd_post_reset(tmp_adev);
if (audio_suspended)
amdgpu_device_resume_display_audio(tmp_adev);
amdgpu_device_unlock_adev(tmp_adev);
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_df.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ struct amdgpu_df_funcs {
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
uint32_t ficadl_val, uint32_t ficadh_val);
uint64_t (*get_dram_base_addr)(struct amdgpu_device *adev,
uint32_t df_inst);
uint32_t (*get_df_inst_id)(struct amdgpu_device *adev);
};

struct amdgpu_df {
Expand Down
Loading

0 comments on commit 49eea1c

Please sign in to comment.