mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'amd-drm-next-5.20-2022-07-05' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.20-2022-07-05: amdgpu: - Various spelling and grammer fixes - Various eDP fixes - Various DMCUB fixes - VCN fixes - GMC 11 fixes - RAS fixes - TMZ support for GC 10.3.7 - GPUVM TLB flush fixes - SMU 13.0.x updates - DCN 3.2 Support - DCN 3.2.1 Support - MES updates - GFX11 modifiers support - USB-C fixes - MMHUB 3.0.1 support - SDMA 6.0 doorbell fixes - Initial devcoredump support - Enable high priority gfx queue on asics which support it - Enable GPU reset for SMU 13.0.4 - OLED display fixes - MPO fixes - DC frame size fixes - ASPM support for PCIE 7.4/7.6 - GPU reset support for SMU 13.0.0 - GFX11 updates - VCN JPEG fix - BACO support for SMU 13.0.7 - VCN instance handling fix - GFX8 GPUVM TLB flush fix - GPU reset rework - VCN 4.0.2 support - GTT size fixes - DP link training fixes - LSDMA 6.0.1 support - Various backlight fixes - Color encoding fixes - Backlight config cleanup - VCN 4.x unified queue cleanup amdkfd: - MMU notifier fixes - Updates for GC 10.3.6 and 10.3.7 - P2P DMA support using dma-buf - Add available memory IOCTL - SDMA 6.0.1 fix - MES fixes - HMM profiler support radeon: - License fix - Backlight config cleanup UAPI: - Add available memory IOCTL to amdkfd Proposed userspace: https://www.mail-archive.com/amd-gfx@lists.freedesktop.org/msg75743.html - HMM profiler support for amdkfd Proposed userspace: https://lists.freedesktop.org/archives/amd-gfx/2022-June/080805.html Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220705212633.6037-1-alexander.deucher@amd.com
This commit is contained in:
@@ -88,7 +88,8 @@ amdgpu-y += \
|
||||
gmc_v8_0.o \
|
||||
gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
|
||||
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
|
||||
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o
|
||||
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
|
||||
mmhub_v3_0_1.o
|
||||
|
||||
# add UMC block
|
||||
amdgpu-y += \
|
||||
|
||||
@@ -223,6 +223,9 @@ static const int __maybe_unused sched_policy = KFD_SCHED_POLICY_HWS;
|
||||
static const bool __maybe_unused debug_evictions; /* = false */
|
||||
static const bool __maybe_unused no_system_mem_limit;
|
||||
#endif
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
extern bool pcie_p2p;
|
||||
#endif
|
||||
|
||||
extern int amdgpu_tmz;
|
||||
extern int amdgpu_reset_method;
|
||||
@@ -274,7 +277,7 @@ extern int amdgpu_vcnfw_log;
|
||||
#define CIK_CURSOR_WIDTH 128
|
||||
#define CIK_CURSOR_HEIGHT 128
|
||||
|
||||
/* smasrt shift bias level limits */
|
||||
/* smart shift bias level limits */
|
||||
#define AMDGPU_SMARTSHIFT_MAX_BIAS (100)
|
||||
#define AMDGPU_SMARTSHIFT_MIN_BIAS (-100)
|
||||
|
||||
@@ -667,6 +670,7 @@ enum amd_hw_ip_block_type {
|
||||
RSMU_HWIP,
|
||||
XGMI_HWIP,
|
||||
DCI_HWIP,
|
||||
PCIE_HWIP,
|
||||
MAX_HWIP
|
||||
};
|
||||
|
||||
@@ -1044,10 +1048,18 @@ struct amdgpu_device {
|
||||
|
||||
/* reset dump register */
|
||||
uint32_t *reset_dump_reg_list;
|
||||
uint32_t *reset_dump_reg_value;
|
||||
int num_regs;
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
struct amdgpu_task_info reset_task_info;
|
||||
bool reset_vram_lost;
|
||||
struct timespec64 reset_time;
|
||||
#endif
|
||||
|
||||
bool scpm_enabled;
|
||||
uint32_t scpm_status;
|
||||
|
||||
struct work_struct reset_work;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||
@@ -1242,7 +1254,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job* job);
|
||||
int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job);
|
||||
void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_device_pci_reset(struct amdgpu_device *adev);
|
||||
|
||||
@@ -66,9 +66,7 @@ struct amdgpu_atif {
|
||||
struct amdgpu_atif_notifications notifications;
|
||||
struct amdgpu_atif_functions functions;
|
||||
struct amdgpu_atif_notification_cfg notification_cfg;
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
struct backlight_device *bd;
|
||||
#endif
|
||||
struct amdgpu_dm_backlight_caps backlight_caps;
|
||||
};
|
||||
|
||||
@@ -436,7 +434,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
||||
DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
|
||||
|
||||
if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
if (atif->bd) {
|
||||
DRM_DEBUG_DRIVER("Changing brightness to %d\n",
|
||||
req.backlight_level);
|
||||
@@ -447,7 +444,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
||||
*/
|
||||
backlight_device_set_brightness(atif->bd, req.backlight_level);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
|
||||
@@ -849,7 +845,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
|
||||
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
if (atif->notifications.brightness_change) {
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
@@ -876,7 +871,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
adev->acpi_nb.notifier_call = amdgpu_acpi_event;
|
||||
register_acpi_notifier(&adev->acpi_nb);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_umc.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
/* Total memory size in system memory and all GPU VRAM. Used to
|
||||
* estimate worst case amount of memory to reserve for page tables
|
||||
@@ -122,6 +123,15 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void amdgpu_amdkfd_reset_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
kfd.reset_work);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
@@ -180,6 +190,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
|
||||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
adev_to_drm(adev), &gpu_resources);
|
||||
|
||||
INIT_WORK(&adev->kfd.reset_work, amdgpu_amdkfd_reset_work);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +259,8 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev)
|
||||
void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_device_should_recover_gpu(adev))
|
||||
amdgpu_device_gpu_recover(adev, NULL);
|
||||
amdgpu_reset_domain_schedule(adev->reset_domain,
|
||||
&adev->kfd.reset_work);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
|
||||
@@ -671,6 +684,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
||||
goto err_ib_sched;
|
||||
}
|
||||
|
||||
/* Drop the initial kref_init count (see drm_sched_main as example) */
|
||||
dma_fence_put(f);
|
||||
ret = dma_fence_wait(f, false);
|
||||
|
||||
err_ib_sched:
|
||||
@@ -714,7 +729,8 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
{
|
||||
bool all_hub = false;
|
||||
|
||||
if (adev->family == AMDGPU_FAMILY_AI)
|
||||
if (adev->family == AMDGPU_FAMILY_AI ||
|
||||
adev->family == AMDGPU_FAMILY_RV)
|
||||
all_hub = true;
|
||||
|
||||
return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub);
|
||||
|
||||
@@ -48,6 +48,7 @@ enum kfd_mem_attachment_type {
|
||||
KFD_MEM_ATT_SHARED, /* Share kgd_mem->bo or another attachment's */
|
||||
KFD_MEM_ATT_USERPTR, /* SG bo to DMA map pages from a userptr bo */
|
||||
KFD_MEM_ATT_DMABUF, /* DMAbuf to DMA map TTM BOs */
|
||||
KFD_MEM_ATT_SG /* Tag to DMA map SG BOs */
|
||||
};
|
||||
|
||||
struct kfd_mem_attachment {
|
||||
@@ -96,6 +97,7 @@ struct amdgpu_kfd_dev {
|
||||
struct kfd_dev *dev;
|
||||
uint64_t vram_used;
|
||||
bool init_complete;
|
||||
struct work_struct reset_work;
|
||||
};
|
||||
|
||||
enum kgd_engine_type {
|
||||
@@ -266,6 +268,7 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
|
||||
void *drm_priv);
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
struct amdgpu_device *adev, uint64_t va, uint64_t size,
|
||||
void *drm_priv, struct kgd_mem **mem,
|
||||
@@ -279,10 +282,11 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, void **kptr, uint64_t *size);
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
void **kptr, uint64_t *size);
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);
|
||||
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
||||
struct dma_fence **ef);
|
||||
@@ -332,7 +336,7 @@ void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
|
||||
}
|
||||
#endif
|
||||
/* KGD2KFD callbacks */
|
||||
int kgd2kfd_quiesce_mm(struct mm_struct *mm);
|
||||
int kgd2kfd_quiesce_mm(struct mm_struct *mm, uint32_t trigger);
|
||||
int kgd2kfd_resume_mm(struct mm_struct *mm);
|
||||
int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
|
||||
struct dma_fence *fence);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -110,7 +110,7 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_compute_prio(int32_t prio)
|
||||
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_gfx_pipe_prio(int32_t prio)
|
||||
{
|
||||
switch (prio) {
|
||||
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||
@@ -143,8 +143,9 @@ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
|
||||
ctx->init_priority : ctx->override_priority;
|
||||
|
||||
switch (hw_ip) {
|
||||
case AMDGPU_HW_IP_GFX:
|
||||
case AMDGPU_HW_IP_COMPUTE:
|
||||
hw_prio = amdgpu_ctx_prio_to_compute_prio(ctx_prio);
|
||||
hw_prio = amdgpu_ctx_prio_to_gfx_pipe_prio(ctx_prio);
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCE:
|
||||
case AMDGPU_HW_IP_VCN_ENC:
|
||||
@@ -779,7 +780,7 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
||||
amdgpu_ctx_to_drm_sched_prio(priority));
|
||||
|
||||
/* set hw priority */
|
||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
|
||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE || hw_ip == AMDGPU_HW_IP_GFX) {
|
||||
hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
|
||||
hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
|
||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||
|
||||
@@ -1709,17 +1709,24 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
|
||||
i++;
|
||||
} while (len < size);
|
||||
|
||||
new = kmalloc_array(i, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!new) {
|
||||
ret = -ENOMEM;
|
||||
goto error_free;
|
||||
}
|
||||
ret = down_write_killable(&adev->reset_domain->sem);
|
||||
if (ret)
|
||||
goto error_free;
|
||||
|
||||
swap(adev->reset_dump_reg_list, tmp);
|
||||
swap(adev->reset_dump_reg_value, new);
|
||||
adev->num_regs = i;
|
||||
up_write(&adev->reset_domain->sem);
|
||||
ret = size;
|
||||
|
||||
error_free:
|
||||
kfree(tmp);
|
||||
kfree(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/devcoredump.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
@@ -1942,35 +1945,6 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_VERDE:
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_OLAND:
|
||||
case CHIP_HAINAN:
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
#endif
|
||||
case CHIP_TOPAZ:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_VEGAM:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ALDEBARAN:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_BEIGE_GOBY:
|
||||
default:
|
||||
return 0;
|
||||
case CHIP_VEGA10:
|
||||
@@ -3316,38 +3290,12 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
||||
case CHIP_MULLINS:
|
||||
/*
|
||||
* We have systems in the wild with these ASICs that require
|
||||
* LVDS and VGA support which is not supported with DC.
|
||||
* VGA support which is not supported with DC.
|
||||
*
|
||||
* Fallback to the non-DC driver here by default so as not to
|
||||
* cause regressions.
|
||||
*/
|
||||
return amdgpu_dc > 0;
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_VEGAM:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_CYAN_SKILLFISH:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_BEIGE_GOBY:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_YELLOW_CARP:
|
||||
#endif
|
||||
default:
|
||||
return amdgpu_dc != 0;
|
||||
#else
|
||||
@@ -3369,7 +3317,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
||||
*/
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
adev->enable_virtual_display ||
|
||||
(adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK))
|
||||
return false;
|
||||
@@ -3667,14 +3615,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
if (amdgpu_mcbp)
|
||||
DRM_INFO("MCBP is enabled\n");
|
||||
|
||||
if (adev->asic_type >= CHIP_NAVI10) {
|
||||
if (amdgpu_mes || amdgpu_mes_kiq)
|
||||
adev->enable_mes = true;
|
||||
|
||||
if (amdgpu_mes_kiq)
|
||||
adev->enable_mes_kiq = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset domain needs to be present early, before XGMI hive discovered
|
||||
* (if any) and intitialized to use reset sem and in_gpu reset flag
|
||||
@@ -4666,6 +4606,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
amdgpu_virt_fini_data_exchange(adev);
|
||||
}
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, true);
|
||||
|
||||
/* block all schedulers and reset given job's ring */
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
@@ -4681,6 +4623,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
amdgpu_fence_driver_force_completion(ring);
|
||||
}
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, false);
|
||||
|
||||
if (job && job->vm)
|
||||
drm_sched_increase_karma(&job->base);
|
||||
|
||||
@@ -4721,20 +4665,73 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
|
||||
static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&adev->reset_domain->sem);
|
||||
dump_stack();
|
||||
|
||||
for (i = 0; i < adev->num_regs; i++) {
|
||||
reg_value = RREG32(adev->reset_dump_reg_list[i]);
|
||||
trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i], reg_value);
|
||||
adev->reset_dump_reg_value[i] = RREG32(adev->reset_dump_reg_list[i]);
|
||||
trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i],
|
||||
adev->reset_dump_reg_value[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset,
|
||||
size_t count, void *data, size_t datalen)
|
||||
{
|
||||
struct drm_printer p;
|
||||
struct amdgpu_device *adev = data;
|
||||
struct drm_print_iterator iter;
|
||||
int i;
|
||||
|
||||
iter.data = buffer;
|
||||
iter.offset = 0;
|
||||
iter.start = offset;
|
||||
iter.remain = count;
|
||||
|
||||
p = drm_coredump_printer(&iter);
|
||||
|
||||
drm_printf(&p, "**** AMDGPU Device Coredump ****\n");
|
||||
drm_printf(&p, "kernel: " UTS_RELEASE "\n");
|
||||
drm_printf(&p, "module: " KBUILD_MODNAME "\n");
|
||||
drm_printf(&p, "time: %lld.%09ld\n", adev->reset_time.tv_sec, adev->reset_time.tv_nsec);
|
||||
if (adev->reset_task_info.pid)
|
||||
drm_printf(&p, "process_name: %s PID: %d\n",
|
||||
adev->reset_task_info.process_name,
|
||||
adev->reset_task_info.pid);
|
||||
|
||||
if (adev->reset_vram_lost)
|
||||
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
|
||||
if (adev->num_regs) {
|
||||
drm_printf(&p, "AMDGPU register dumps:\nOffset: Value:\n");
|
||||
|
||||
for (i = 0; i < adev->num_regs; i++)
|
||||
drm_printf(&p, "0x%08x: 0x%08x\n",
|
||||
adev->reset_dump_reg_list[i],
|
||||
adev->reset_dump_reg_value[i]);
|
||||
}
|
||||
|
||||
return count - iter.remain;
|
||||
}
|
||||
|
||||
static void amdgpu_devcoredump_free(void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
|
||||
ktime_get_ts64(&adev->reset_time);
|
||||
dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_KERNEL,
|
||||
amdgpu_devcoredump_read, amdgpu_devcoredump_free);
|
||||
}
|
||||
#endif
|
||||
|
||||
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
@@ -4819,6 +4816,15 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
goto out;
|
||||
|
||||
vram_lost = amdgpu_device_check_vram_lost(tmp_adev);
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
tmp_adev->reset_vram_lost = vram_lost;
|
||||
memset(&tmp_adev->reset_task_info, 0,
|
||||
sizeof(tmp_adev->reset_task_info));
|
||||
if (reset_context->job && reset_context->job->vm)
|
||||
tmp_adev->reset_task_info =
|
||||
reset_context->job->vm->task_info;
|
||||
amdgpu_reset_capture_coredumpm(tmp_adev);
|
||||
#endif
|
||||
if (vram_lost) {
|
||||
DRM_INFO("VRAM is lost due to GPU reset!\n");
|
||||
amdgpu_inc_vram_lost(tmp_adev);
|
||||
@@ -5004,16 +5010,32 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
|
||||
/* clear job's guilty and depend the folowing step to decide the real one */
|
||||
drm_sched_reset_karma(s_job);
|
||||
/* for the real bad job, it will be resubmitted twice, adding a dma_fence_get
|
||||
* to make sure fence is balanced */
|
||||
dma_fence_get(s_job->s_fence->parent);
|
||||
drm_sched_resubmit_jobs_ext(&ring->sched, 1);
|
||||
|
||||
if (!s_job->s_fence->parent) {
|
||||
DRM_WARN("Failed to get a HW fence for job!");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout);
|
||||
if (ret == 0) { /* timeout */
|
||||
DRM_ERROR("Found the real bad job! ring:%s, job_id:%llx\n",
|
||||
ring->sched.name, s_job->id);
|
||||
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, true);
|
||||
|
||||
/* Clear this failed job from fence array */
|
||||
amdgpu_fence_driver_clear_job_fences(ring);
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, false);
|
||||
|
||||
/* Since the job won't signal and we go for
|
||||
* another resubmit drop this parent pointer
|
||||
*/
|
||||
dma_fence_put(s_job->s_fence->parent);
|
||||
s_job->s_fence->parent = NULL;
|
||||
|
||||
/* set guilty */
|
||||
drm_sched_increase_karma(s_job);
|
||||
retry:
|
||||
@@ -5042,7 +5064,6 @@ retry:
|
||||
|
||||
/* got the hw fence, signal finished fence */
|
||||
atomic_dec(ring->sched.score);
|
||||
dma_fence_put(s_job->s_fence->parent);
|
||||
dma_fence_get(&s_job->s_fence->finished);
|
||||
dma_fence_signal(&s_job->s_fence->finished);
|
||||
dma_fence_put(&s_job->s_fence->finished);
|
||||
@@ -5055,8 +5076,29 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
cancel_work(&adev->reset_work);
|
||||
#endif
|
||||
|
||||
if (adev->kfd.dev)
|
||||
cancel_work(&adev->kfd.reset_work);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
cancel_work(&adev->virt.flr_work);
|
||||
|
||||
if (con && adev->ras_enabled)
|
||||
cancel_work(&con->recovery_work);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_gpu_recover_imp - reset the asic and recover scheduler
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @job: which job trigger hang
|
||||
@@ -5066,7 +5108,7 @@ retry:
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
|
||||
int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct list_head device_list, *device_list_handle = NULL;
|
||||
@@ -5164,7 +5206,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
*/
|
||||
amdgpu_unregister_gpu_instance(tmp_adev);
|
||||
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, true);
|
||||
|
||||
/* disable ras on ALL IPs */
|
||||
if (!need_emergency_restart &&
|
||||
@@ -5194,8 +5236,8 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
*
|
||||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && job->base.s_fence->parent &&
|
||||
dma_fence_is_signaled(job->base.s_fence->parent)) {
|
||||
if (job && (job->hw_fence.ops != NULL) &&
|
||||
dma_fence_is_signaled(&job->hw_fence)) {
|
||||
job_signaled = true;
|
||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||
goto skip_hw_reset;
|
||||
@@ -5210,6 +5252,12 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
r, adev_to_drm(tmp_adev)->unique);
|
||||
tmp_adev->asic_reset_res = r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop all pending non scheduler resets. Scheduler resets
|
||||
* were already dropped during drm_sched_stop
|
||||
*/
|
||||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
}
|
||||
|
||||
tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
|
||||
@@ -5308,40 +5356,11 @@ skip_sched_resume:
|
||||
|
||||
if (r)
|
||||
dev_info(adev->dev, "GPU reset end with ret = %d\n", r);
|
||||
|
||||
atomic_set(&adev->reset_domain->reset_res, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct amdgpu_recover_work_struct {
|
||||
struct work_struct base;
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_job *job;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static void amdgpu_device_queue_gpu_recover_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_recover_work_struct *recover_work = container_of(work, struct amdgpu_recover_work_struct, base);
|
||||
|
||||
recover_work->ret = amdgpu_device_gpu_recover_imp(recover_work->adev, recover_work->job);
|
||||
}
|
||||
/*
|
||||
* Serialize gpu recover into reset domain single threaded wq
|
||||
*/
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_recover_work_struct work = {.adev = adev, .job = job};
|
||||
|
||||
INIT_WORK(&work.base, amdgpu_device_queue_gpu_recover_work);
|
||||
|
||||
if (!amdgpu_reset_domain_schedule(adev->reset_domain, &work.base))
|
||||
return -EAGAIN;
|
||||
|
||||
flush_work(&work.base);
|
||||
|
||||
return work.ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
|
||||
*
|
||||
@@ -5490,6 +5509,36 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_is_peer_accessible - Check peer access through PCIe BAR
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @peer_adev: amdgpu_device pointer for peer device trying to access @adev
|
||||
*
|
||||
* Return true if @peer_adev can access (DMA) @adev through the PCIe
|
||||
* BAR, i.e. @adev is "large BAR" and the BAR matches the DMA mask of
|
||||
* @peer_adev.
|
||||
*/
|
||||
bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
|
||||
struct amdgpu_device *peer_adev)
|
||||
{
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
uint64_t address_mask = peer_adev->dev->dma_mask ?
|
||||
~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
|
||||
resource_size_t aper_limit =
|
||||
adev->gmc.aper_base + adev->gmc.aper_size - 1;
|
||||
bool p2p_access = !(pci_p2pdma_distance_many(adev->pdev,
|
||||
&peer_adev->dev, 1, true) < 0);
|
||||
|
||||
return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
|
||||
adev->gmc.real_vram_size == adev->gmc.visible_vram_size &&
|
||||
!(adev->gmc.aper_base & address_mask ||
|
||||
aper_limit & address_mask));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int amdgpu_device_baco_enter(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
||||
@@ -194,6 +194,7 @@ static int hw_id_map[MAX_HWIP] = {
|
||||
[UMC_HWIP] = UMC_HWID,
|
||||
[XGMI_HWIP] = XGMI_HWID,
|
||||
[DCI_HWIP] = DCI_HWID,
|
||||
[PCIE_HWIP] = PCIE_HWID,
|
||||
};
|
||||
|
||||
static int amdgpu_discovery_read_binary_from_vram(struct amdgpu_device *adev, uint8_t *binary)
|
||||
@@ -1435,6 +1436,11 @@ static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
|
||||
* which is smaller than VCN_INFO_TABLE_MAX_NUM_INSTANCES
|
||||
* but that may change in the future with new GPUs so keep this
|
||||
* check for defensive purposes.
|
||||
*/
|
||||
if (adev->vcn.num_vcn_inst > VCN_INFO_TABLE_MAX_NUM_INSTANCES) {
|
||||
dev_err(adev->dev, "invalid vcn instances\n");
|
||||
return -EINVAL;
|
||||
@@ -1450,6 +1456,9 @@ static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev)
|
||||
|
||||
switch (le16_to_cpu(vcn_info->v1.header.version_major)) {
|
||||
case 1:
|
||||
/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
|
||||
* so this won't overflow.
|
||||
*/
|
||||
for (v = 0; v < adev->vcn.num_vcn_inst; v++) {
|
||||
adev->vcn.vcn_codec_disable_mask[v] =
|
||||
le32_to_cpu(vcn_info->v1.instance_info[v].fuse_data.all_bits);
|
||||
@@ -1709,6 +1718,8 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(3, 1, 3):
|
||||
case IP_VERSION(3, 1, 5):
|
||||
case IP_VERSION(3, 1, 6):
|
||||
case IP_VERSION(3, 2, 0):
|
||||
case IP_VERSION(3, 2, 1):
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1886,6 +1897,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(4, 0, 0):
|
||||
case IP_VERSION(4, 0, 2):
|
||||
case IP_VERSION(4, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
|
||||
@@ -2321,6 +2333,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->ip_versions[LSDMA_HWIP][0]) {
|
||||
case IP_VERSION(6, 0, 0):
|
||||
case IP_VERSION(6, 0, 1):
|
||||
case IP_VERSION(6, 0, 2):
|
||||
adev->lsdma.funcs = &lsdma_v6_0_funcs;
|
||||
break;
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include "atom.h"
|
||||
#include "amdgpu_connectors.h"
|
||||
#include "amdgpu_display.h"
|
||||
#include "soc15_common.h"
|
||||
#include "gc/gc_11_0_0_offset.h"
|
||||
#include "gc/gc_11_0_0_sh_mask.h"
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/pci.h>
|
||||
@@ -663,6 +666,11 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
|
||||
uint64_t modifier = 0;
|
||||
int num_pipes = 0;
|
||||
int num_pkrs = 0;
|
||||
|
||||
num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
|
||||
num_pipes = adev->gfx.config.gb_addr_config_fields.num_pipes;
|
||||
|
||||
if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) {
|
||||
modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
@@ -675,7 +683,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
int bank_xor_bits = 0;
|
||||
int packers = 0;
|
||||
int rb = 0;
|
||||
int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
|
||||
int pipes = ilog2(num_pipes);
|
||||
uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B);
|
||||
|
||||
switch (swizzle >> 2) {
|
||||
@@ -691,12 +699,17 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
case 6: /* 64 KiB _X */
|
||||
block_size_bits = 16;
|
||||
break;
|
||||
case 7: /* 256 KiB */
|
||||
block_size_bits = 18;
|
||||
break;
|
||||
default:
|
||||
/* RESERVED or VAR */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX11;
|
||||
else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
|
||||
else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10;
|
||||
@@ -707,19 +720,32 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
case 0: /* Z microtiling */
|
||||
return -EINVAL;
|
||||
case 1: /* S microtiling */
|
||||
if (!has_xor)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) {
|
||||
if (!has_xor)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!has_xor && afb->base.format->cpp[0] != 4)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) {
|
||||
if (!has_xor && afb->base.format->cpp[0] != 4)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_xor) {
|
||||
if (num_pipes == num_pkrs && num_pkrs == 0) {
|
||||
DRM_ERROR("invalid number of pipes and packers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
case AMD_FMT_MOD_TILE_VER_GFX11:
|
||||
pipe_xor_bits = min(block_size_bits - 8, pipes);
|
||||
packers = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
|
||||
break;
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
|
||||
pipe_xor_bits = min(block_size_bits - 8, pipes);
|
||||
packers = min(block_size_bits - 8 - pipe_xor_bits,
|
||||
@@ -753,9 +779,10 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
u64 render_dcc_offset;
|
||||
|
||||
/* Enable constant encode on RAVEN2 and later. */
|
||||
bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN ||
|
||||
bool dcc_constant_encode = (adev->asic_type > CHIP_RAVEN ||
|
||||
(adev->asic_type == CHIP_RAVEN &&
|
||||
adev->external_rev_id >= 0x81);
|
||||
adev->external_rev_id >= 0x81)) &&
|
||||
adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0);
|
||||
|
||||
int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B :
|
||||
dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B :
|
||||
@@ -870,10 +897,11 @@ static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned,
|
||||
return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, modifier) : 0), 12);
|
||||
}
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10:
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: {
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
|
||||
case AMD_FMT_MOD_TILE_VER_GFX11: {
|
||||
int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
|
||||
|
||||
if (ver == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
|
||||
if (ver >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
|
||||
AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2)
|
||||
++pipes_log2;
|
||||
|
||||
@@ -966,6 +994,9 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
|
||||
case DC_SW_64KB_S_X:
|
||||
block_size_log2 = 16;
|
||||
break;
|
||||
case DC_SW_VAR_S_X:
|
||||
block_size_log2 = 18;
|
||||
break;
|
||||
default:
|
||||
drm_dbg_kms(rfb->base.dev,
|
||||
"Swizzle mode with unknown block size: %d\n", swizzle);
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#define amdgpu_display_add_encoder(adev, e, s, c) (adev)->mode_info.funcs->add_encoder((adev), (e), (s), (c))
|
||||
#define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
|
||||
|
||||
int amdgpu_display_freesync_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp);
|
||||
void amdgpu_display_update_priority(struct amdgpu_device *adev);
|
||||
uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
uint64_t bo_flags);
|
||||
|
||||
@@ -802,6 +802,16 @@ MODULE_PARM_DESC(no_queue_eviction_on_vm_fault, "No queue eviction on VM fault (
|
||||
module_param_named(no_queue_eviction_on_vm_fault, amdgpu_no_queue_eviction_on_vm_fault, int, 0444);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DOC: pcie_p2p (bool)
|
||||
* Enable PCIe P2P (requires large-BAR). Default value: true (on)
|
||||
*/
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
bool pcie_p2p = true;
|
||||
module_param(pcie_p2p, bool, 0444);
|
||||
MODULE_PARM_DESC(pcie_p2p, "Enable PCIe P2P (requires large-BAR). (N = off, Y = on(default))");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DOC: dcfeaturemask (uint)
|
||||
* Override display features enabled. See enum DC_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h.
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <drm/drm_drv.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_trace.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
/*
|
||||
* Fences
|
||||
@@ -163,11 +164,16 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd
|
||||
if (job && job->job_run_counter) {
|
||||
/* reinit seq for resubmitted jobs */
|
||||
fence->seqno = seq;
|
||||
/* TO be inline with external fence creation and other drivers */
|
||||
dma_fence_get(fence);
|
||||
} else {
|
||||
if (job)
|
||||
if (job) {
|
||||
dma_fence_init(fence, &amdgpu_job_fence_ops,
|
||||
&ring->fence_drv.lock,
|
||||
adev->fence_context + ring->idx, seq);
|
||||
/* Against remove in amdgpu_job_{free, free_cb} */
|
||||
dma_fence_get(fence);
|
||||
}
|
||||
else
|
||||
dma_fence_init(fence, &amdgpu_fence_ops,
|
||||
&ring->fence_drv.lock,
|
||||
@@ -531,6 +537,24 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Will either stop and flush handlers for amdgpu interrupt or reanble it */
|
||||
void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !ring->fence_drv.initialized || !ring->fence_drv.irq_src)
|
||||
continue;
|
||||
|
||||
if (stop)
|
||||
disable_irq(adev->irq.irq);
|
||||
else
|
||||
enable_irq(adev->irq.irq);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@@ -594,8 +618,10 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)
|
||||
for (i = 0; i <= ring->fence_drv.num_fences_mask; i++) {
|
||||
ptr = &ring->fence_drv.fences[i];
|
||||
old = rcu_dereference_protected(*ptr, 1);
|
||||
if (old && old->ops == &amdgpu_job_fence_ops)
|
||||
if (old && old->ops == &amdgpu_job_fence_ops) {
|
||||
RCU_INIT_POINTER(*ptr, NULL);
|
||||
dma_fence_put(old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,7 +824,10 @@ static int gpu_recover_get(void *data, u64 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*val = amdgpu_device_gpu_recover(adev, NULL);
|
||||
if (amdgpu_reset_domain_schedule(adev->reset_domain, &adev->reset_work))
|
||||
flush_work(&adev->reset_work);
|
||||
|
||||
*val = atomic_read(&adev->reset_domain->reset_res);
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
@@ -810,6 +839,14 @@ DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_fence_info);
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_debugfs_gpu_recover_fops, gpu_recover_get, NULL,
|
||||
"%lld\n");
|
||||
|
||||
static void amdgpu_debugfs_reset_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
reset_work);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void amdgpu_debugfs_fence_init(struct amdgpu_device *adev)
|
||||
@@ -821,9 +858,12 @@ void amdgpu_debugfs_fence_init(struct amdgpu_device *adev)
|
||||
debugfs_create_file("amdgpu_fence_info", 0444, root, adev,
|
||||
&amdgpu_debugfs_fence_info_fops);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
|
||||
INIT_WORK(&adev->reset_work, amdgpu_debugfs_reset_work);
|
||||
debugfs_create_file("amdgpu_gpu_recover", 0444, root, adev,
|
||||
&amdgpu_debugfs_gpu_recover_fops);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,12 @@ void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_s
|
||||
}
|
||||
}
|
||||
|
||||
static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev)
|
||||
static bool amdgpu_gfx_is_graphics_multipipe_capable(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_async_gfx_ring && adev->gfx.me.num_pipe_per_me > 1;
|
||||
}
|
||||
|
||||
static bool amdgpu_gfx_is_compute_multipipe_capable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_compute_multipipe != -1) {
|
||||
DRM_INFO("amdgpu: forcing compute pipe policy %d\n",
|
||||
@@ -158,6 +163,28 @@ static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev)
|
||||
return adev->gfx.mec.num_mec > 1;
|
||||
}
|
||||
|
||||
bool amdgpu_gfx_is_high_priority_graphics_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
int queue = ring->queue;
|
||||
int pipe = ring->pipe;
|
||||
|
||||
/* Policy: use pipe1 queue0 as high priority graphics queue if we
|
||||
* have more than one gfx pipe.
|
||||
*/
|
||||
if (amdgpu_gfx_is_graphics_multipipe_capable(adev) &&
|
||||
adev->gfx.num_gfx_rings > 1 && pipe == 1 && queue == 0) {
|
||||
int me = ring->me;
|
||||
int bit;
|
||||
|
||||
bit = amdgpu_gfx_me_queue_to_bit(adev, me, pipe, queue);
|
||||
if (ring == &adev->gfx.gfx_ring[bit])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
@@ -174,7 +201,7 @@ bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
|
||||
void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, queue, pipe;
|
||||
bool multipipe_policy = amdgpu_gfx_is_multipipe_capable(adev);
|
||||
bool multipipe_policy = amdgpu_gfx_is_compute_multipipe_capable(adev);
|
||||
int max_queues_per_mec = min(adev->gfx.mec.num_pipe_per_mec *
|
||||
adev->gfx.mec.num_queue_per_pipe,
|
||||
adev->gfx.num_compute_rings);
|
||||
@@ -200,18 +227,24 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
|
||||
|
||||
void amdgpu_gfx_graphics_queue_acquire(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, queue, me;
|
||||
int i, queue, pipe;
|
||||
bool multipipe_policy = amdgpu_gfx_is_graphics_multipipe_capable(adev);
|
||||
int max_queues_per_me = adev->gfx.me.num_pipe_per_me *
|
||||
adev->gfx.me.num_queue_per_pipe;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_GFX_QUEUES; ++i) {
|
||||
queue = i % adev->gfx.me.num_queue_per_pipe;
|
||||
me = (i / adev->gfx.me.num_queue_per_pipe)
|
||||
/ adev->gfx.me.num_pipe_per_me;
|
||||
|
||||
if (me >= adev->gfx.me.num_me)
|
||||
break;
|
||||
if (multipipe_policy) {
|
||||
/* policy: amdgpu owns the first queue per pipe at this stage
|
||||
* will extend to mulitple queues per pipe later */
|
||||
if (me == 0 && queue < 1)
|
||||
for (i = 0; i < max_queues_per_me; i++) {
|
||||
pipe = i % adev->gfx.me.num_pipe_per_me;
|
||||
queue = (i / adev->gfx.me.num_pipe_per_me) %
|
||||
adev->gfx.me.num_queue_per_pipe;
|
||||
|
||||
set_bit(pipe * adev->gfx.me.num_queue_per_pipe + queue,
|
||||
adev->gfx.me.queue_bitmap);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < max_queues_per_me; ++i)
|
||||
set_bit(i, adev->gfx.me.queue_bitmap);
|
||||
}
|
||||
|
||||
@@ -666,6 +699,9 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return 0;
|
||||
|
||||
if (adev->mes.ring.sched.ready)
|
||||
return amdgpu_mes_rreg(adev, reg);
|
||||
|
||||
BUG_ON(!ring->funcs->emit_rreg);
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
@@ -733,6 +769,11 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return;
|
||||
|
||||
if (adev->mes.ring.sched.ready) {
|
||||
amdgpu_mes_wreg(adev, reg, v);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_emit_wreg(ring, reg, v);
|
||||
|
||||
@@ -396,6 +396,8 @@ bool amdgpu_gfx_is_mec_queue_enabled(struct amdgpu_device *adev, int mec,
|
||||
int pipe, int queue);
|
||||
bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring);
|
||||
bool amdgpu_gfx_is_high_priority_graphics_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring);
|
||||
int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me,
|
||||
int pipe, int queue);
|
||||
void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit,
|
||||
|
||||
@@ -242,7 +242,7 @@ restart_ih:
|
||||
* @entry: IV entry
|
||||
*
|
||||
* Decodes the interrupt vector at the current rptr
|
||||
* position and also advance the position for for Vega10
|
||||
* position and also advance the position for Vega10
|
||||
* and later GPUs.
|
||||
*/
|
||||
void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev,
|
||||
|
||||
@@ -24,12 +24,18 @@
|
||||
#ifndef __AMDGPU_IMU_H__
|
||||
#define __AMDGPU_IMU_H__
|
||||
|
||||
enum imu_work_mode {
|
||||
DEBUG_MODE,
|
||||
MISSION_MODE
|
||||
};
|
||||
|
||||
struct amdgpu_imu_funcs {
|
||||
int (*init_microcode)(struct amdgpu_device *adev);
|
||||
int (*load_microcode)(struct amdgpu_device *adev);
|
||||
void (*setup_imu)(struct amdgpu_device *adev);
|
||||
int (*start_imu)(struct amdgpu_device *adev);
|
||||
void (*program_rlc_ram)(struct amdgpu_device *adev);
|
||||
int (*wait_for_reset_status)(struct amdgpu_device *adev);
|
||||
};
|
||||
|
||||
struct imu_rlc_ram_golden {
|
||||
@@ -46,6 +52,7 @@ struct imu_rlc_ram_golden {
|
||||
|
||||
struct amdgpu_imu {
|
||||
const struct amdgpu_imu_funcs *funcs;
|
||||
enum imu_work_mode mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -320,6 +320,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
if (!adev->enable_virtual_display)
|
||||
/* Disable vblank IRQs aggressively for power-saving */
|
||||
/* XXX: can this be enabled for DC? */
|
||||
adev_to_drm(adev)->vblank_disable_immediate = true;
|
||||
|
||||
r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc);
|
||||
|
||||
@@ -64,7 +64,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
ti.process_name, ti.tgid, ti.task_name, ti.pid);
|
||||
|
||||
if (amdgpu_device_should_recover_gpu(ring->adev)) {
|
||||
r = amdgpu_device_gpu_recover_imp(ring->adev, job);
|
||||
r = amdgpu_device_gpu_recover(ring->adev, job);
|
||||
if (r)
|
||||
DRM_ERROR("GPU Recovery Failed: %d\n", r);
|
||||
} else {
|
||||
@@ -262,10 +262,6 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
||||
DRM_ERROR("Error scheduling IBs (%d)\n", r);
|
||||
}
|
||||
|
||||
if (!job->job_run_counter)
|
||||
dma_fence_get(fence);
|
||||
else if (finished->error < 0)
|
||||
dma_fence_put(&job->hw_fence);
|
||||
job->job_run_counter++;
|
||||
amdgpu_job_free_resources(job);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user