mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'amd-drm-next-5.13-2021-03-23' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.13-2021-03-23:
amdgpu:
- Debugfs cleanup
- Various cleanups and spelling fixes
- Flexible array cleanups
- Initial AMD Freesync HDMI
- Display fixes
- 10bpc dithering improvements
- Display ASSR support
- Clean up and unify powerplay and swsmu interfaces
- Vangogh fixes
- Add SMU gfx busy queues for RV/PCO
- PCIE DPM fixes
- S0ix fixes
- GPU metrics data fixes
- DCN secure display support
- Backlight type override
- Add initial support for Aldebaran
- RAS fixes
- Prime fixes for A+A systems
- Reset fixes
- Initial resource cursor support
- Drop legacy IO BAR requirements
- Various power fixes
amdkfd:
- MMU notifier fixes
- APU fixes
radeon:
- Debugfs cleanups
- Flexible array cleanups
UAPI:
- amdgpu: Add a new INFO ioctl interface to query video capabilities
rather than hardcoding them in userspace. This allows us to provide
fine grained asic capabilities (e.g., if a particular part is
bandwidth limited, we can limit the capabilities). Proposed userspace:
https://gitlab.freedesktop.org/leoliu/drm/-/commits/info_video_caps
https://gitlab.freedesktop.org/leoliu/mesa/-/commits/info_video_caps
- amdkfd: bump the driver version. There was a problem with reporting
some RAS features on older versions of the driver. Proposed userspace:
7cdd63475c
Danvet: A bunch of conflicts all over, but it seems to compile ... I
did put the call to dc_allow_idle_optimizations() on a single line
since it looked a bit too jarring to be left alone.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210324040147.1990338-1-alexander.deucher@amd.com
This commit is contained in:
@@ -34,15 +34,6 @@ config DRM_AMDGPU_USERPTR
|
||||
This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
|
||||
isn't already selected to enabled full userptr support.
|
||||
|
||||
config DRM_AMDGPU_GART_DEBUGFS
|
||||
bool "Allow GART access through debugfs"
|
||||
depends on DRM_AMDGPU
|
||||
depends on DEBUG_FS
|
||||
default n
|
||||
help
|
||||
Selecting this option creates a debugfs file to inspect the mapped
|
||||
pages. Uses more memory for housekeeping, enable only for debugging.
|
||||
|
||||
source "drivers/gpu/drm/amd/acp/Kconfig"
|
||||
source "drivers/gpu/drm/amd/display/Kconfig"
|
||||
source "drivers/gpu/drm/amd/amdkfd/Kconfig"
|
||||
|
||||
@@ -71,7 +71,7 @@ amdgpu-y += \
|
||||
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \
|
||||
arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \
|
||||
nbio_v7_2.o dimgrey_cavefish_reg_init.o hdp_v4_0.o hdp_v5_0.o
|
||||
nbio_v7_2.o dimgrey_cavefish_reg_init.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
@@ -83,7 +83,8 @@ amdgpu-y += \
|
||||
gmc_v7_0.o \
|
||||
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
|
||||
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
|
||||
mmhub_v1_7.o
|
||||
|
||||
# add UMC block
|
||||
amdgpu-y += \
|
||||
@@ -106,7 +107,8 @@ amdgpu-y += \
|
||||
psp_v3_1.o \
|
||||
psp_v10_0.o \
|
||||
psp_v11_0.o \
|
||||
psp_v12_0.o
|
||||
psp_v12_0.o \
|
||||
psp_v13_0.o
|
||||
|
||||
# add DCE block
|
||||
amdgpu-y += \
|
||||
@@ -121,6 +123,7 @@ amdgpu-y += \
|
||||
gfx_v8_0.o \
|
||||
gfx_v9_0.o \
|
||||
gfx_v9_4.o \
|
||||
gfx_v9_4_2.o \
|
||||
gfx_v10_0.o
|
||||
|
||||
# add async DMA block
|
||||
@@ -129,6 +132,7 @@ amdgpu-y += \
|
||||
sdma_v2_4.o \
|
||||
sdma_v3_0.o \
|
||||
sdma_v4_0.o \
|
||||
sdma_v4_4.o \
|
||||
sdma_v5_0.o \
|
||||
sdma_v5_2.o
|
||||
|
||||
@@ -172,7 +176,8 @@ amdgpu-y += \
|
||||
amdgpu-y += \
|
||||
smuio_v9_0.o \
|
||||
smuio_v11_0.o \
|
||||
smuio_v11_0_6.o
|
||||
smuio_v11_0_6.o \
|
||||
smuio_v13_0.o
|
||||
|
||||
# add amdkfd interfaces
|
||||
amdgpu-y += amdgpu_amdkfd.o
|
||||
@@ -187,6 +192,7 @@ amdgpu-y += \
|
||||
amdgpu_amdkfd_gfx_v8.o \
|
||||
amdgpu_amdkfd_gfx_v9.o \
|
||||
amdgpu_amdkfd_arcturus.o \
|
||||
amdgpu_amdkfd_aldebaran.o \
|
||||
amdgpu_amdkfd_gfx_v10.o \
|
||||
amdgpu_amdkfd_gfx_v10_3.o
|
||||
|
||||
|
||||
54
drivers/gpu/drm/amd/amdgpu/aldebaran_reg_init.c
Normal file
54
drivers/gpu/drm/amd/amdgpu/aldebaran_reg_init.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "soc15.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "aldebaran_ip_offset.h"
|
||||
|
||||
int aldebaran_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the block needed by our driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(SDMA0_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(SDMA1_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(SDMA2_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(SDMA3_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA4_HWIP][i] = (uint32_t *)(&(SDMA4_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
adev->reg_offset[UMC_HWIP][i] = (uint32_t *)(&(UMC_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -124,6 +124,16 @@ struct amdgpu_mgpu_info
|
||||
uint32_t num_gpu;
|
||||
uint32_t num_dgpu;
|
||||
uint32_t num_apu;
|
||||
|
||||
/* delayed reset_func for XGMI configuration if necessary */
|
||||
struct delayed_work delayed_reset_work;
|
||||
bool pending_reset;
|
||||
};
|
||||
|
||||
struct amdgpu_watchdog_timer
|
||||
{
|
||||
bool timeout_fatal_disable;
|
||||
uint32_t period; /* maxCycles = (1 << period), the number of cycles before a timeout */
|
||||
};
|
||||
|
||||
#define AMDGPU_MAX_TIMEOUT_PARAM_LENGTH 256
|
||||
@@ -177,7 +187,9 @@ extern int amdgpu_compute_multipipe;
|
||||
extern int amdgpu_gpu_recovery;
|
||||
extern int amdgpu_emu_mode;
|
||||
extern uint amdgpu_smu_memory_pool_size;
|
||||
extern int amdgpu_smu_pptable_id;
|
||||
extern uint amdgpu_dc_feature_mask;
|
||||
extern uint amdgpu_freesync_vid_mode;
|
||||
extern uint amdgpu_dc_debug_mask;
|
||||
extern uint amdgpu_dm_abm_level;
|
||||
extern int amdgpu_backlight;
|
||||
@@ -185,6 +197,7 @@ extern struct amdgpu_mgpu_info mgpu_info;
|
||||
extern int amdgpu_ras_enable;
|
||||
extern uint amdgpu_ras_mask;
|
||||
extern int amdgpu_bad_page_threshold;
|
||||
extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer;
|
||||
extern int amdgpu_async_gfx_ring;
|
||||
extern int amdgpu_mcbp;
|
||||
extern int amdgpu_discovery;
|
||||
@@ -584,6 +597,19 @@ enum amd_reset_method {
|
||||
AMD_RESET_METHOD_PCI,
|
||||
};
|
||||
|
||||
struct amdgpu_video_codec_info {
|
||||
u32 codec_type;
|
||||
u32 max_width;
|
||||
u32 max_height;
|
||||
u32 max_pixels_per_frame;
|
||||
u32 max_level;
|
||||
};
|
||||
|
||||
struct amdgpu_video_codecs {
|
||||
const u32 codec_count;
|
||||
const struct amdgpu_video_codec_info *codec_array;
|
||||
};
|
||||
|
||||
/*
|
||||
* ASIC specific functions.
|
||||
*/
|
||||
@@ -628,6 +654,9 @@ struct amdgpu_asic_funcs {
|
||||
void (*pre_asic_init)(struct amdgpu_device *adev);
|
||||
/* enter/exit umd stable pstate */
|
||||
int (*update_umd_stable_pstate)(struct amdgpu_device *adev, bool enter);
|
||||
/* query video codecs */
|
||||
int (*query_video_codecs)(struct amdgpu_device *adev, bool encode,
|
||||
const struct amdgpu_video_codecs **codecs);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -792,12 +821,7 @@ struct amdgpu_device {
|
||||
bool accel_working;
|
||||
struct notifier_block acpi_nb;
|
||||
struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS];
|
||||
struct amdgpu_debugfs debugfs[AMDGPU_DEBUGFS_MAX_COMPONENTS];
|
||||
unsigned debugfs_count;
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
struct dentry *debugfs_preempt;
|
||||
struct dentry *debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS];
|
||||
#endif
|
||||
struct debugfs_blob_wrapper debugfs_vbios_blob;
|
||||
struct amdgpu_atif *atif;
|
||||
struct amdgpu_atcs atcs;
|
||||
struct mutex srbm_mutex;
|
||||
@@ -853,8 +877,6 @@ struct amdgpu_device {
|
||||
spinlock_t audio_endpt_idx_lock;
|
||||
amdgpu_block_rreg_t audio_endpt_rreg;
|
||||
amdgpu_block_wreg_t audio_endpt_wreg;
|
||||
void __iomem *rio_mem;
|
||||
resource_size_t rio_mem_size;
|
||||
struct amdgpu_doorbell doorbell;
|
||||
|
||||
/* clock/pll info */
|
||||
@@ -897,6 +919,7 @@ struct amdgpu_device {
|
||||
struct amdgpu_irq_src vupdate_irq;
|
||||
struct amdgpu_irq_src pageflip_irq;
|
||||
struct amdgpu_irq_src hpd_irq;
|
||||
struct amdgpu_irq_src dmub_trace_irq;
|
||||
|
||||
/* rings */
|
||||
u64 fence_context;
|
||||
@@ -1024,6 +1047,7 @@ struct amdgpu_device {
|
||||
|
||||
int asic_reset_res;
|
||||
struct work_struct xgmi_reset_work;
|
||||
struct list_head reset_list;
|
||||
|
||||
long gfx_timeout;
|
||||
long sdma_timeout;
|
||||
@@ -1088,9 +1112,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
|
||||
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
|
||||
|
||||
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg);
|
||||
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
|
||||
|
||||
u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr);
|
||||
@@ -1107,6 +1128,15 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job,
|
||||
bool *need_full_reset_arg);
|
||||
|
||||
int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive,
|
||||
struct list_head *device_list_handle,
|
||||
bool *need_full_reset_arg,
|
||||
bool skip_hw_reset);
|
||||
|
||||
int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
|
||||
/*
|
||||
@@ -1172,8 +1202,6 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
} while (0)
|
||||
|
||||
#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_device_rreg((adev), (reg), false))
|
||||
#define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
|
||||
#define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))
|
||||
|
||||
#define REG_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
|
||||
#define REG_FIELD_MASK(reg, field) reg##__##field##_MASK
|
||||
@@ -1227,6 +1255,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev))
|
||||
#define amdgpu_asic_update_umd_stable_pstate(adev, enter) \
|
||||
((adev)->asic_funcs->update_umd_stable_pstate ? (adev)->asic_funcs->update_umd_stable_pstate((adev), (enter)) : 0)
|
||||
#define amdgpu_asic_query_video_codecs(adev, e, c) (adev)->asic_funcs->query_video_codecs((adev), (e), (c))
|
||||
|
||||
#define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter));
|
||||
|
||||
@@ -1247,6 +1276,7 @@ void amdgpu_device_program_register_sequence(struct amdgpu_device *adev,
|
||||
const u32 array_size);
|
||||
|
||||
bool amdgpu_device_supports_atpx(struct drm_device *dev);
|
||||
int amdgpu_device_mode1_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_supports_boco(struct drm_device *dev);
|
||||
bool amdgpu_device_supports_baco(struct drm_device *dev);
|
||||
bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
|
||||
|
||||
@@ -44,7 +44,7 @@ int amdgpu_amdkfd_init(void)
|
||||
int ret;
|
||||
|
||||
si_meminfo(&si);
|
||||
amdgpu_amdkfd_total_mem_size = si.totalram - si.totalhigh;
|
||||
amdgpu_amdkfd_total_mem_size = si.freeram - si.freehigh;
|
||||
amdgpu_amdkfd_total_mem_size *= si.mem_unit;
|
||||
|
||||
ret = kgd2kfd_init();
|
||||
@@ -165,7 +165,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
adev->doorbell_index.last_non_cp;
|
||||
}
|
||||
|
||||
kgd2kfd_device_init(adev->kfd.dev, adev_to_drm(adev), &gpu_resources);
|
||||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
adev_to_drm(adev), &gpu_resources);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -638,13 +639,6 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
||||
/* Temp workaround to fix the soft hang observed in certain compute
|
||||
* applications if GFXOFF is enabled.
|
||||
*/
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID) {
|
||||
pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
|
||||
amdgpu_gfx_off_ctrl(adev, idle);
|
||||
}
|
||||
amdgpu_dpm_switch_power_profile(adev,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
|
||||
@@ -80,6 +80,7 @@ struct amdgpu_amdkfd_fence {
|
||||
struct amdgpu_kfd_dev {
|
||||
struct kfd_dev *dev;
|
||||
uint64_t vram_used;
|
||||
bool init_complete;
|
||||
};
|
||||
|
||||
enum kgd_engine_type {
|
||||
|
||||
47
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
Normal file
47
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_amdkfd_arcturus.h"
|
||||
#include "amdgpu_amdkfd_gfx_v9.h"
|
||||
|
||||
const struct kfd2kgd_calls aldebaran_kfd2kgd = {
|
||||
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
|
||||
.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
|
||||
.init_interrupts = kgd_gfx_v9_init_interrupts,
|
||||
.hqd_load = kgd_gfx_v9_hqd_load,
|
||||
.hiq_mqd_load = kgd_gfx_v9_hiq_mqd_load,
|
||||
.hqd_sdma_load = kgd_arcturus_hqd_sdma_load,
|
||||
.hqd_dump = kgd_gfx_v9_hqd_dump,
|
||||
.hqd_sdma_dump = kgd_arcturus_hqd_sdma_dump,
|
||||
.hqd_is_occupied = kgd_gfx_v9_hqd_is_occupied,
|
||||
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
|
||||
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
|
||||
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
|
||||
.address_watch_disable = kgd_gfx_v9_address_watch_disable,
|
||||
.address_watch_execute = kgd_gfx_v9_address_watch_execute,
|
||||
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
|
||||
.address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
|
||||
.get_atc_vmid_pasid_mapping_info =
|
||||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
|
||||
};
|
||||
@@ -122,7 +122,7 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
|
||||
return sdma_rlc_reg_offset;
|
||||
}
|
||||
|
||||
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
|
||||
int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
|
||||
uint32_t __user *wptr, struct mm_struct *mm)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
@@ -192,7 +192,7 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
|
||||
int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd,
|
||||
uint32_t engine_id, uint32_t queue_id,
|
||||
uint32_t (**dump)[2], uint32_t *n_regs)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
|
||||
bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct v9_sdma_mqd *m;
|
||||
@@ -243,7 +243,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int utimeout)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
@@ -289,13 +289,13 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
||||
.init_interrupts = kgd_gfx_v9_init_interrupts,
|
||||
.hqd_load = kgd_gfx_v9_hqd_load,
|
||||
.hiq_mqd_load = kgd_gfx_v9_hiq_mqd_load,
|
||||
.hqd_sdma_load = kgd_hqd_sdma_load,
|
||||
.hqd_sdma_load = kgd_arcturus_hqd_sdma_load,
|
||||
.hqd_dump = kgd_gfx_v9_hqd_dump,
|
||||
.hqd_sdma_dump = kgd_hqd_sdma_dump,
|
||||
.hqd_sdma_dump = kgd_arcturus_hqd_sdma_dump,
|
||||
.hqd_is_occupied = kgd_gfx_v9_hqd_is_occupied,
|
||||
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
|
||||
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
|
||||
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
|
||||
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
|
||||
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
|
||||
.address_watch_disable = kgd_gfx_v9_address_watch_disable,
|
||||
.address_watch_execute = kgd_gfx_v9_address_watch_execute,
|
||||
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
|
||||
|
||||
30
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h
Normal file
30
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
|
||||
uint32_t __user *wptr, struct mm_struct *mm);
|
||||
int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd,
|
||||
uint32_t engine_id, uint32_t queue_id,
|
||||
uint32_t (**dump)[2], uint32_t *n_regs);
|
||||
bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
|
||||
int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int utimeout);
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_dma_buf.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
/* BO flag to indicate a KFD userptr BO */
|
||||
#define AMDGPU_AMDKFD_USERPTR_BO (1ULL << 63)
|
||||
@@ -96,7 +97,7 @@ void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
|
||||
uint64_t mem;
|
||||
|
||||
si_meminfo(&si);
|
||||
mem = si.totalram - si.totalhigh;
|
||||
mem = si.freeram - si.freehigh;
|
||||
mem *= si.mem_unit;
|
||||
|
||||
spin_lock_init(&kfd_mem_limit.mem_limit_lock);
|
||||
@@ -412,7 +413,10 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
||||
{
|
||||
struct amdgpu_device *bo_adev = amdgpu_ttm_adev(mem->bo->tbo.bdev);
|
||||
bool coherent = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_COHERENT;
|
||||
bool uncached = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED;
|
||||
uint32_t mapping_flags;
|
||||
uint64_t pte_flags;
|
||||
bool snoop = false;
|
||||
|
||||
mapping_flags = AMDGPU_VM_PAGE_READABLE;
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE)
|
||||
@@ -433,12 +437,41 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
}
|
||||
break;
|
||||
case CHIP_ALDEBARAN:
|
||||
if (coherent && uncached) {
|
||||
if (adev->gmc.xgmi.connected_to_cpu ||
|
||||
!(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM))
|
||||
snoop = true;
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
} else if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (bo_adev == adev) {
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_RW;
|
||||
if (adev->gmc.xgmi.connected_to_cpu)
|
||||
snoop = true;
|
||||
} else {
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_NC;
|
||||
if (amdgpu_xgmi_same_hive(adev, bo_adev))
|
||||
snoop = true;
|
||||
}
|
||||
} else {
|
||||
snoop = true;
|
||||
if (adev->gmc.xgmi.connected_to_cpu)
|
||||
/* system memory uses NC on A+A */
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_NC;
|
||||
else
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
}
|
||||
|
||||
return amdgpu_gem_va_map_flags(adev, mapping_flags);
|
||||
pte_flags = amdgpu_gem_va_map_flags(adev, mapping_flags);
|
||||
pte_flags |= snoop ? AMDGPU_PTE_SNOOPED : 0;
|
||||
|
||||
return pte_flags;
|
||||
}
|
||||
|
||||
/* add_bo_to_vm - Add a BO to a VM
|
||||
|
||||
@@ -1905,40 +1905,6 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* cail_ioreg_write - write IO register
|
||||
*
|
||||
* @info: atom card_info pointer
|
||||
* @reg: IO register offset
|
||||
* @val: value to write to the pll register
|
||||
*
|
||||
* Provides a IO register accessor for the atom interpreter (r4xx+).
|
||||
*/
|
||||
static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(info->dev);
|
||||
|
||||
WREG32_IO(reg, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cail_ioreg_read - read IO register
|
||||
*
|
||||
* @info: atom card_info pointer
|
||||
* @reg: IO register offset
|
||||
*
|
||||
* Provides an IO register accessor for the atom interpreter (r4xx+).
|
||||
* Returns the value of the IO register.
|
||||
*/
|
||||
static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(info->dev);
|
||||
uint32_t r;
|
||||
|
||||
r = RREG32_IO(reg);
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@@ -1998,15 +1964,6 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
|
||||
atom_card_info->dev = adev_to_drm(adev);
|
||||
atom_card_info->reg_read = cail_reg_read;
|
||||
atom_card_info->reg_write = cail_reg_write;
|
||||
/* needed for iio ops */
|
||||
if (adev->rio_mem) {
|
||||
atom_card_info->ioreg_read = cail_ioreg_read;
|
||||
atom_card_info->ioreg_write = cail_ioreg_write;
|
||||
} else {
|
||||
DRM_DEBUG("PCI I/O BAR is not found. Using MMIO to access ATOM BIOS\n");
|
||||
atom_card_info->ioreg_read = cail_reg_read;
|
||||
atom_card_info->ioreg_write = cail_reg_write;
|
||||
}
|
||||
atom_card_info->mc_read = cail_mc_read;
|
||||
atom_card_info->mc_write = cail_mc_write;
|
||||
atom_card_info->pll_read = cail_pll_read;
|
||||
|
||||
@@ -117,12 +117,15 @@ union igp_info {
|
||||
|
||||
union umc_info {
|
||||
struct atom_umc_info_v3_1 v31;
|
||||
struct atom_umc_info_v3_2 v32;
|
||||
struct atom_umc_info_v3_3 v33;
|
||||
};
|
||||
|
||||
union vram_info {
|
||||
struct atom_vram_info_header_v2_3 v23;
|
||||
struct atom_vram_info_header_v2_4 v24;
|
||||
struct atom_vram_info_header_v2_5 v25;
|
||||
struct atom_vram_info_header_v2_6 v26;
|
||||
};
|
||||
|
||||
union vram_module {
|
||||
@@ -164,6 +167,7 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
|
||||
vram_type = AMDGPU_VRAM_TYPE_GDDR5;
|
||||
break;
|
||||
case ATOM_DGPU_VRAM_TYPE_HBM2:
|
||||
case ATOM_DGPU_VRAM_TYPE_HBM2E:
|
||||
vram_type = AMDGPU_VRAM_TYPE_HBM;
|
||||
break;
|
||||
case ATOM_DGPU_VRAM_TYPE_GDDR6:
|
||||
@@ -315,6 +319,26 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev,
|
||||
if (vram_vendor)
|
||||
*vram_vendor = mem_vendor;
|
||||
break;
|
||||
case 6:
|
||||
if (module_id > vram_info->v26.vram_module_num)
|
||||
module_id = 0;
|
||||
vram_module = (union vram_module *)vram_info->v26.vram_module;
|
||||
while (i < module_id) {
|
||||
vram_module = (union vram_module *)
|
||||
((u8 *)vram_module + vram_module->v9.vram_module_size);
|
||||
i++;
|
||||
}
|
||||
mem_type = vram_module->v9.memory_type;
|
||||
if (vram_type)
|
||||
*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
|
||||
mem_channel_number = vram_module->v9.channel_num;
|
||||
mem_channel_width = vram_module->v9.channel_width;
|
||||
if (vram_width)
|
||||
*vram_width = mem_channel_number * (1 << mem_channel_width);
|
||||
mem_vendor = (vram_module->v9.vender_rev_id) & 0xF;
|
||||
if (vram_vendor)
|
||||
*vram_vendor = mem_vendor;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -337,19 +361,39 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
|
||||
union umc_info *umc_info;
|
||||
u8 frev, crev;
|
||||
bool ecc_default_enabled = false;
|
||||
u8 umc_config;
|
||||
u32 umc_config1;
|
||||
|
||||
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
umc_info);
|
||||
|
||||
if (amdgpu_atom_parse_data_header(mode_info->atom_context,
|
||||
index, &size, &frev, &crev, &data_offset)) {
|
||||
/* support umc_info 3.1+ */
|
||||
if ((frev == 3 && crev >= 1) || (frev > 3)) {
|
||||
if (frev == 3) {
|
||||
umc_info = (union umc_info *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
ecc_default_enabled =
|
||||
(le32_to_cpu(umc_info->v31.umc_config) &
|
||||
UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
switch (crev) {
|
||||
case 1:
|
||||
umc_config = le32_to_cpu(umc_info->v31.umc_config);
|
||||
ecc_default_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
case 2:
|
||||
umc_config = le32_to_cpu(umc_info->v32.umc_config);
|
||||
ecc_default_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
case 3:
|
||||
umc_config = le32_to_cpu(umc_info->v33.umc_config);
|
||||
umc_config1 = le32_to_cpu(umc_info->v33.umc_config1);
|
||||
ecc_default_enabled =
|
||||
((umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ||
|
||||
(umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE)) ? true : false;
|
||||
break;
|
||||
default:
|
||||
/* unsupported crev */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +523,8 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
union gfx_info {
|
||||
struct atom_gfx_info_v2_4 v24;
|
||||
struct atom_gfx_info_v2_4 v24;
|
||||
struct atom_gfx_info_v2_7 v27;
|
||||
};
|
||||
|
||||
int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
|
||||
@@ -514,6 +559,22 @@ int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev)
|
||||
adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu;
|
||||
adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size);
|
||||
return 0;
|
||||
case 7:
|
||||
adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines;
|
||||
adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh;
|
||||
adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se;
|
||||
adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se;
|
||||
adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches;
|
||||
adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs);
|
||||
adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds;
|
||||
adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth;
|
||||
adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth);
|
||||
adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer;
|
||||
adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size);
|
||||
adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd);
|
||||
adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu;
|
||||
adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size);
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
|
||||
if (amdgpu_device_need_post(adev))
|
||||
return false;
|
||||
|
||||
/* FB BAR not enabled */
|
||||
if (pci_resource_len(adev->pdev, 0) == 0)
|
||||
return false;
|
||||
|
||||
adev->bios = NULL;
|
||||
vram_base = pci_resource_start(adev->pdev, 0);
|
||||
bios = ioremap_wc(vram_base, size);
|
||||
@@ -316,7 +320,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
|
||||
|
||||
adev->bios = kmalloc(size, GFP_KERNEL);
|
||||
if (!adev->bios) {
|
||||
DRM_ERROR("Unable to allocate bios\n");
|
||||
dev_err(adev->dev, "Unable to allocate bios\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -364,7 +368,7 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
||||
return false;
|
||||
tbl_size = hdr->length;
|
||||
if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
|
||||
DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
|
||||
dev_info(adev->dev, "ACPI VFCT table present but broken (too short #1),skipping\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -377,13 +381,13 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
||||
|
||||
offset += sizeof(VFCT_IMAGE_HEADER);
|
||||
if (offset > tbl_size) {
|
||||
DRM_ERROR("ACPI VFCT image header truncated\n");
|
||||
dev_info(adev->dev, "ACPI VFCT image header truncated,skipping\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
offset += vhdr->ImageLength;
|
||||
if (offset > tbl_size) {
|
||||
DRM_ERROR("ACPI VFCT image truncated\n");
|
||||
dev_info(adev->dev, "ACPI VFCT image truncated,skipping\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -406,7 +410,7 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
|
||||
dev_info(adev->dev, "ACPI VFCT table present but broken (too short #2),skipping\n");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
@@ -453,7 +457,7 @@ bool amdgpu_get_bios(struct amdgpu_device *adev)
|
||||
goto success;
|
||||
}
|
||||
|
||||
DRM_ERROR("Unable to locate a BIOS ROM\n");
|
||||
dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
|
||||
return false;
|
||||
|
||||
success:
|
||||
|
||||
@@ -117,7 +117,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
|
||||
if (cs->in.num_chunks == 0)
|
||||
return 0;
|
||||
|
||||
chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
|
||||
chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
|
||||
if (!chunk_array)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -144,7 +144,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
|
||||
}
|
||||
|
||||
p->nchunks = cs->in.num_chunks;
|
||||
p->chunks = kmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),
|
||||
p->chunks = kvmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),
|
||||
GFP_KERNEL);
|
||||
if (!p->chunks) {
|
||||
ret = -ENOMEM;
|
||||
@@ -238,7 +238,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
|
||||
|
||||
if (p->uf_entry.tv.bo)
|
||||
p->job->uf_addr = uf_offset;
|
||||
kfree(chunk_array);
|
||||
kvfree(chunk_array);
|
||||
|
||||
/* Use this opportunity to fill in task info for the vm */
|
||||
amdgpu_vm_set_task_info(vm);
|
||||
@@ -250,11 +250,11 @@ free_all_kdata:
|
||||
free_partial_kdata:
|
||||
for (; i >= 0; i--)
|
||||
kvfree(p->chunks[i].kdata);
|
||||
kfree(p->chunks);
|
||||
kvfree(p->chunks);
|
||||
p->chunks = NULL;
|
||||
p->nchunks = 0;
|
||||
free_chunk:
|
||||
kfree(chunk_array);
|
||||
kvfree(chunk_array);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -559,7 +559,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
|
||||
sizeof(struct page *),
|
||||
GFP_KERNEL | __GFP_ZERO);
|
||||
if (!e->user_pages) {
|
||||
DRM_ERROR("calloc failure\n");
|
||||
DRM_ERROR("kvmalloc_array failure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
|
||||
|
||||
for (i = 0; i < parser->nchunks; i++)
|
||||
kvfree(parser->chunks[i].kdata);
|
||||
kfree(parser->chunks);
|
||||
kvfree(parser->chunks);
|
||||
if (parser->job)
|
||||
amdgpu_job_free(parser->job);
|
||||
if (parser->uf_entry.tv.bo) {
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/poll.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_pm.h"
|
||||
@@ -38,45 +37,6 @@
|
||||
#include "amdgpu_securedisplay.h"
|
||||
#include "amdgpu_fw_attestation.h"
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_add_files - Add simple debugfs entries
|
||||
*
|
||||
* @adev: Device to attach debugfs entries to
|
||||
* @files: Array of function callbacks that respond to reads
|
||||
* @nfiles: Number of callbacks to register
|
||||
*
|
||||
*/
|
||||
int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
|
||||
const struct drm_info_list *files,
|
||||
unsigned nfiles)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < adev->debugfs_count; i++) {
|
||||
if (adev->debugfs[i].files == files) {
|
||||
/* Already registered */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i = adev->debugfs_count + 1;
|
||||
if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) {
|
||||
DRM_ERROR("Reached maximum number of debugfs components.\n");
|
||||
DRM_ERROR("Report so we increase "
|
||||
"AMDGPU_DEBUGFS_MAX_COMPONENTS.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
adev->debugfs[adev->debugfs_count].files = files;
|
||||
adev->debugfs[adev->debugfs_count].num_files = nfiles;
|
||||
adev->debugfs_count = i;
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
drm_debugfs_create_files(files, nfiles,
|
||||
adev_to_drm(adev)->primary->debugfs_root,
|
||||
adev_to_drm(adev)->primary);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
@@ -1228,22 +1188,20 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
|
||||
adev, debugfs_regs[i]);
|
||||
if (!i && !IS_ERR_OR_NULL(ent))
|
||||
i_size_write(ent->d_inode, adev->rmmio_size);
|
||||
adev->debugfs_regs[i] = ent;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
|
||||
static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
int r = 0, i;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1285,30 +1243,19 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data)
|
||||
static int amdgpu_debugfs_evict_vram(void *data, u64 *val)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
||||
seq_write(m, adev->bios, adev->bios_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)data;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));
|
||||
*val = amdgpu_bo_evict_vram(adev);
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
@@ -1316,11 +1263,11 @@ static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
|
||||
|
||||
static int amdgpu_debugfs_evict_gtt(void *data, u64 *val)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)data;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct ttm_resource_manager *man;
|
||||
int r;
|
||||
|
||||
@@ -1331,8 +1278,7 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
|
||||
}
|
||||
|
||||
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
|
||||
r = ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
||||
seq_printf(m, "(%d)\n", r);
|
||||
*val = ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
@@ -1340,10 +1286,11 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_vm_info(struct seq_file *m, void *data)
|
||||
|
||||
static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_file *file;
|
||||
int r;
|
||||
|
||||
@@ -1369,13 +1316,12 @@ static int amdgpu_debugfs_vm_info(struct seq_file *m, void *data)
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct drm_info_list amdgpu_debugfs_list[] = {
|
||||
{"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},
|
||||
{"amdgpu_test_ib", &amdgpu_debugfs_test_ib},
|
||||
{"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram},
|
||||
{"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt},
|
||||
{"amdgpu_vm_info", &amdgpu_debugfs_vm_info},
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_test_ib);
|
||||
DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_vm_info);
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_vram_fops, amdgpu_debugfs_evict_vram,
|
||||
NULL, "%lld\n");
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_gtt_fops, amdgpu_debugfs_evict_gtt,
|
||||
NULL, "%lld\n");
|
||||
|
||||
static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
|
||||
struct dma_fence **fences)
|
||||
@@ -1586,71 +1532,50 @@ static int amdgpu_debugfs_sclk_set(void *data, u64 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_ib_preempt, NULL,
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,
|
||||
amdgpu_debugfs_ib_preempt, "%llu\n");
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(fops_sclk_set, NULL,
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL,
|
||||
amdgpu_debugfs_sclk_set, "%llu\n");
|
||||
|
||||
int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct dentry *root = adev_to_drm(adev)->primary->debugfs_root;
|
||||
struct dentry *ent;
|
||||
int r, i;
|
||||
|
||||
adev->debugfs_preempt =
|
||||
debugfs_create_file("amdgpu_preempt_ib", 0600,
|
||||
adev_to_drm(adev)->primary->debugfs_root, adev,
|
||||
&fops_ib_preempt);
|
||||
if (!(adev->debugfs_preempt)) {
|
||||
|
||||
|
||||
ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
|
||||
&fops_ib_preempt);
|
||||
if (!ent) {
|
||||
DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
adev->smu.debugfs_sclk =
|
||||
debugfs_create_file("amdgpu_force_sclk", 0200,
|
||||
adev_to_drm(adev)->primary->debugfs_root, adev,
|
||||
&fops_sclk_set);
|
||||
if (!(adev->smu.debugfs_sclk)) {
|
||||
ent = debugfs_create_file("amdgpu_force_sclk", 0200, root, adev,
|
||||
&fops_sclk_set);
|
||||
if (!ent) {
|
||||
DRM_ERROR("unable to create amdgpu_set_sclk debugsfs file\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Register debugfs entries for amdgpu_ttm */
|
||||
r = amdgpu_ttm_debugfs_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to init debugfs\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_debugfs_pm_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to register debugfs file for dpm!\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
if (amdgpu_debugfs_sa_init(adev)) {
|
||||
dev_err(adev->dev, "failed to register debugfs file for SA\n");
|
||||
}
|
||||
|
||||
if (amdgpu_debugfs_fence_init(adev))
|
||||
dev_err(adev->dev, "fence debugfs file creation failed\n");
|
||||
|
||||
r = amdgpu_debugfs_gem_init(adev);
|
||||
if (r)
|
||||
DRM_ERROR("registering gem debugfs failed (%d).\n", r);
|
||||
amdgpu_ttm_debugfs_init(adev);
|
||||
amdgpu_debugfs_pm_init(adev);
|
||||
amdgpu_debugfs_sa_init(adev);
|
||||
amdgpu_debugfs_fence_init(adev);
|
||||
amdgpu_debugfs_gem_init(adev);
|
||||
|
||||
r = amdgpu_debugfs_regs_init(adev);
|
||||
if (r)
|
||||
DRM_ERROR("registering register debugfs failed (%d).\n", r);
|
||||
|
||||
r = amdgpu_debugfs_firmware_init(adev);
|
||||
if (r)
|
||||
DRM_ERROR("registering firmware debugfs failed (%d).\n", r);
|
||||
amdgpu_debugfs_firmware_init(adev);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
if (dtn_debugfs_init(adev))
|
||||
DRM_ERROR("amdgpu: failed initialize dtn debugfs support.\n");
|
||||
}
|
||||
if (amdgpu_device_has_dc_support(adev))
|
||||
dtn_debugfs_init(adev);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
@@ -1665,17 +1590,26 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
amdgpu_ras_debugfs_create_all(adev);
|
||||
|
||||
amdgpu_debugfs_autodump_init(adev);
|
||||
|
||||
amdgpu_rap_debugfs_init(adev);
|
||||
|
||||
amdgpu_securedisplay_debugfs_init(adev);
|
||||
|
||||
amdgpu_fw_attestation_debugfs_init(adev);
|
||||
|
||||
return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,
|
||||
ARRAY_SIZE(amdgpu_debugfs_list));
|
||||
debugfs_create_file("amdgpu_evict_vram", 0444, root, adev,
|
||||
&amdgpu_evict_vram_fops);
|
||||
debugfs_create_file("amdgpu_evict_gtt", 0444, root, adev,
|
||||
&amdgpu_evict_gtt_fops);
|
||||
debugfs_create_file("amdgpu_test_ib", 0444, root, adev,
|
||||
&amdgpu_debugfs_test_ib_fops);
|
||||
debugfs_create_file("amdgpu_vm_info", 0444, root, adev,
|
||||
&amdgpu_debugfs_vm_info_fops);
|
||||
|
||||
adev->debugfs_vbios_blob.data = adev->bios;
|
||||
adev->debugfs_vbios_blob.size = adev->bios_size;
|
||||
debugfs_create_blob("amdgpu_vbios", 0444, root,
|
||||
&adev->debugfs_vbios_blob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -26,11 +26,6 @@
|
||||
/*
|
||||
* Debugfs
|
||||
*/
|
||||
struct amdgpu_debugfs {
|
||||
const struct drm_info_list *files;
|
||||
unsigned num_files;
|
||||
};
|
||||
|
||||
struct amdgpu_autodump {
|
||||
struct completion dumping;
|
||||
struct wait_queue_head gpu_hang;
|
||||
@@ -39,10 +34,7 @@ struct amdgpu_autodump {
|
||||
int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
|
||||
const struct drm_info_list *files,
|
||||
unsigned nfiles);
|
||||
int amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
|
||||
int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -870,17 +870,62 @@ static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_display_gem_fb_init(struct drm_device *dev,
|
||||
struct amdgpu_framebuffer *rfb,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
struct drm_gem_object *obj)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rfb->base.obj[0] = obj;
|
||||
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
drm_err(dev, "Failed to init gem fb: %d\n", ret);
|
||||
rfb->base.obj[0] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_display_gem_fb_verify_and_init(
|
||||
struct drm_device *dev, struct amdgpu_framebuffer *rfb,
|
||||
struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
struct drm_gem_object *obj)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rfb->base.obj[0] = obj;
|
||||
|
||||
/* Verify that bo size can fit the fb size. */
|
||||
ret = drm_gem_fb_init_with_funcs(dev, &rfb->base, file_priv, mode_cmd,
|
||||
&amdgpu_fb_funcs);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
drm_err(dev, "Failed to verify and init gem fb: %d\n", ret);
|
||||
rfb->base.obj[0] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
||||
struct amdgpu_framebuffer *rfb,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
struct drm_gem_object *obj)
|
||||
{
|
||||
int ret, i;
|
||||
rfb->base.obj[0] = obj;
|
||||
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* This needs to happen before modifier conversion as that might change
|
||||
@@ -891,13 +936,13 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
||||
drm_dbg_kms(dev, "Plane 0 and %d have different BOs: %u vs. %u\n",
|
||||
i, mode_cmd->handles[0], mode_cmd->handles[i]);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface);
|
||||
if (ret)
|
||||
goto fail;
|
||||
return ret;
|
||||
|
||||
if (dev->mode_config.allow_fb_modifiers &&
|
||||
!(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
|
||||
@@ -905,20 +950,17 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
||||
if (ret) {
|
||||
drm_dbg_kms(dev, "Failed to convert tiling flags 0x%llX to a modifier",
|
||||
rfb->tiling_flags);
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < rfb->base.format->num_planes; ++i) {
|
||||
drm_gem_object_get(rfb->base.obj[0]);
|
||||
drm_gem_object_put(rfb->base.obj[i]);
|
||||
rfb->base.obj[i] = rfb->base.obj[0];
|
||||
drm_gem_object_get(rfb->base.obj[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
rfb->base.obj[0] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct drm_framebuffer *
|
||||
@@ -953,13 +995,15 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
ret = amdgpu_display_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
|
||||
ret = amdgpu_display_gem_fb_verify_and_init(dev, amdgpu_fb, file_priv,
|
||||
mode_cmd, obj);
|
||||
if (ret) {
|
||||
kfree(amdgpu_fb);
|
||||
drm_gem_object_put(obj);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
drm_gem_object_put(obj);
|
||||
return &amdgpu_fb->base;
|
||||
}
|
||||
|
||||
|
||||
@@ -321,17 +321,12 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
|
||||
struct sg_table *sgt,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
struct dma_buf *dma_buf = attach->dmabuf;
|
||||
struct drm_gem_object *obj = dma_buf->priv;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
|
||||
if (sgt->sgl->page_link) {
|
||||
dma_unmap_sgtable(attach->dev, sgt, dir, 0);
|
||||
sg_free_table(sgt);
|
||||
kfree(sgt);
|
||||
} else {
|
||||
amdgpu_vram_mgr_free_sgt(adev, attach->dev, dir, sgt);
|
||||
amdgpu_vram_mgr_free_sgt(attach->dev, dir, sgt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,22 +429,22 @@ amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
|
||||
{
|
||||
struct dma_resv *resv = dma_buf->resv;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_bo *bo;
|
||||
struct amdgpu_bo_param bp;
|
||||
struct drm_gem_object *gobj;
|
||||
struct amdgpu_bo *bo;
|
||||
uint64_t flags = 0;
|
||||
int ret;
|
||||
|
||||
memset(&bp, 0, sizeof(bp));
|
||||
bp.size = dma_buf->size;
|
||||
bp.byte_align = PAGE_SIZE;
|
||||
bp.domain = AMDGPU_GEM_DOMAIN_CPU;
|
||||
bp.flags = 0;
|
||||
bp.type = ttm_bo_type_sg;
|
||||
bp.resv = resv;
|
||||
dma_resv_lock(resv, NULL);
|
||||
|
||||
if (dma_buf->ops == &amdgpu_dmabuf_ops) {
|
||||
struct amdgpu_bo *other = gem_to_amdgpu_bo(dma_buf->priv);
|
||||
|
||||
flags |= other->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC;
|
||||
}
|
||||
|
||||
ret = amdgpu_gem_object_create(adev, dma_buf->size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_CPU,
|
||||
0, ttm_bo_type_sg, resv, &gobj);
|
||||
AMDGPU_GEM_DOMAIN_CPU, flags,
|
||||
ttm_bo_type_sg, resv, &gobj);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "amdgpu_amdkfd.h"
|
||||
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
/*
|
||||
* KMS wrapper.
|
||||
@@ -90,9 +91,10 @@
|
||||
* - 3.38.0 - Add AMDGPU_IB_FLAG_EMIT_MEM_SYNC
|
||||
* - 3.39.0 - DMABUF implicit sync does a full pipeline sync
|
||||
* - 3.40.0 - Add AMDGPU_IDS_FLAGS_TMZ
|
||||
* - 3.41.0 - Add video codec query
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 40
|
||||
#define KMS_DRIVER_MINOR 41
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit;
|
||||
@@ -145,6 +147,7 @@ int amdgpu_compute_multipipe = -1;
|
||||
int amdgpu_gpu_recovery = -1; /* auto */
|
||||
int amdgpu_emu_mode;
|
||||
uint amdgpu_smu_memory_pool_size;
|
||||
int amdgpu_smu_pptable_id = -1;
|
||||
/*
|
||||
* FBC (bit 0) disabled by default
|
||||
* MULTI_MON_PP_MCLK_SWITCH (bit 1) enabled by default
|
||||
@@ -162,16 +165,26 @@ int amdgpu_discovery = -1;
|
||||
int amdgpu_mes;
|
||||
int amdgpu_noretry = -1;
|
||||
int amdgpu_force_asic_type = -1;
|
||||
int amdgpu_tmz;
|
||||
int amdgpu_tmz = -1; /* auto */
|
||||
uint amdgpu_freesync_vid_mode;
|
||||
int amdgpu_reset_method = -1; /* auto */
|
||||
int amdgpu_num_kcq = -1;
|
||||
|
||||
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
|
||||
|
||||
struct amdgpu_mgpu_info mgpu_info = {
|
||||
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
|
||||
.delayed_reset_work = __DELAYED_WORK_INITIALIZER(
|
||||
mgpu_info.delayed_reset_work,
|
||||
amdgpu_drv_delayed_reset_work_handler, 0),
|
||||
};
|
||||
int amdgpu_ras_enable = -1;
|
||||
uint amdgpu_ras_mask = 0xffffffff;
|
||||
int amdgpu_bad_page_threshold = -1;
|
||||
struct amdgpu_watchdog_timer amdgpu_watchdog_timer = {
|
||||
.timeout_fatal_disable = false,
|
||||
.period = 0x23, /* default to max. timeout = 1 << 0x23 cycles */
|
||||
};
|
||||
|
||||
/**
|
||||
* DOC: vramlimit (int)
|
||||
@@ -527,6 +540,20 @@ module_param_named(ras_enable, amdgpu_ras_enable, int, 0444);
|
||||
MODULE_PARM_DESC(ras_mask, "Mask of RAS features to enable (default 0xffffffff), only valid when ras_enable == 1");
|
||||
module_param_named(ras_mask, amdgpu_ras_mask, uint, 0444);
|
||||
|
||||
/**
|
||||
* DOC: timeout_fatal_disable (bool)
|
||||
* Disable Watchdog timeout fatal error event
|
||||
*/
|
||||
MODULE_PARM_DESC(timeout_fatal_disable, "disable watchdog timeout fatal error (false = default)");
|
||||
module_param_named(timeout_fatal_disable, amdgpu_watchdog_timer.timeout_fatal_disable, bool, 0644);
|
||||
|
||||
/**
|
||||
* DOC: timeout_period (uint)
|
||||
* Modify the watchdog timeout max_cycles as (1 << period)
|
||||
*/
|
||||
MODULE_PARM_DESC(timeout_period, "watchdog timeout period (1 to 0x23(default), timeout maxCycles = (1 << period)");
|
||||
module_param_named(timeout_period, amdgpu_watchdog_timer.period, uint, 0644);
|
||||
|
||||
/**
|
||||
* DOC: si_support (int)
|
||||
* Set SI support driver. This parameter works after set config CONFIG_DRM_AMDGPU_SI. For SI asic, when radeon driver is enabled,
|
||||
@@ -748,6 +775,13 @@ bool no_system_mem_limit;
|
||||
module_param(no_system_mem_limit, bool, 0644);
|
||||
MODULE_PARM_DESC(no_system_mem_limit, "disable system memory limit (false = default)");
|
||||
|
||||
/**
|
||||
* DOC: no_queue_eviction_on_vm_fault (int)
|
||||
* If set, process queues will not be evicted on gpuvm fault. This is to keep the wavefront context for debugging (0 = queue eviction, 1 = no queue eviction). The default is 0 (queue eviction).
|
||||
*/
|
||||
int amdgpu_no_queue_eviction_on_vm_fault = 0;
|
||||
MODULE_PARM_DESC(no_queue_eviction_on_vm_fault, "No queue eviction on VM fault (0 = queue eviction, 1 = no queue eviction)");
|
||||
module_param_named(no_queue_eviction_on_vm_fault, amdgpu_no_queue_eviction_on_vm_fault, int, 0444);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -792,9 +826,20 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444);
|
||||
*
|
||||
* The default value: 0 (off). TODO: change to auto till it is completed.
|
||||
*/
|
||||
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto, 0 = off (default), 1 = on)");
|
||||
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
|
||||
module_param_named(tmz, amdgpu_tmz, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: freesync_video (uint)
|
||||
* Enabled the optimization to adjust front porch timing to achieve seamless mode change experience
|
||||
* when setting a freesync supported mode for which full modeset is not needed.
|
||||
* The default value: 0 (off).
|
||||
*/
|
||||
MODULE_PARM_DESC(
|
||||
freesync_video,
|
||||
"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
|
||||
module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
|
||||
|
||||
/**
|
||||
* DOC: reset_method (int)
|
||||
* GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco, 5 = pci)
|
||||
@@ -815,6 +860,15 @@ module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444);
|
||||
MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
|
||||
module_param_named(num_kcq, amdgpu_num_kcq, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: smu_pptable_id (int)
|
||||
* Used to override pptable id. id = 0 use VBIOS pptable.
|
||||
* id > 0 use the soft pptable with specicfied id.
|
||||
*/
|
||||
MODULE_PARM_DESC(smu_pptable_id,
|
||||
"specify pptable id to be used (-1 = auto(default) value, 0 = use pptable from vbios, > 0 = soft pptable id)");
|
||||
module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444);
|
||||
|
||||
static const struct pci_device_id pciidlist[] = {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
|
||||
@@ -1124,6 +1178,11 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x73E2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
|
||||
{0x1002, 0x73FF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
|
||||
|
||||
/* Aldebaran */
|
||||
{0x1002, 0x7408, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x740F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1280,6 +1339,69 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
|
||||
adev->mp1_state = PP_MP1_STATE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_drv_delayed_reset_work_handler - work handler for reset
|
||||
*
|
||||
* @work: work_struct.
|
||||
*/
|
||||
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct list_head device_list;
|
||||
struct amdgpu_device *adev;
|
||||
int i, r;
|
||||
bool need_full_reset = true;
|
||||
|
||||
mutex_lock(&mgpu_info.mutex);
|
||||
if (mgpu_info.pending_reset == true) {
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
return;
|
||||
}
|
||||
mgpu_info.pending_reset = true;
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++) {
|
||||
adev = mgpu_info.gpu_ins[i].adev;
|
||||
r = amdgpu_device_pre_asic_reset(adev, NULL, &need_full_reset);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ",
|
||||
r, adev_to_drm(adev)->unique);
|
||||
}
|
||||
if (!queue_work(system_unbound_wq, &adev->xgmi_reset_work))
|
||||
r = -EALREADY;
|
||||
}
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++) {
|
||||
adev = mgpu_info.gpu_ins[i].adev;
|
||||
flush_work(&adev->xgmi_reset_work);
|
||||
adev->gmc.xgmi.pending_reset = false;
|
||||
}
|
||||
|
||||
/* reset function will rebuild the xgmi hive info , clear it now */
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++)
|
||||
amdgpu_xgmi_remove_device(mgpu_info.gpu_ins[i].adev);
|
||||
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++)
|
||||
list_add_tail(&mgpu_info.gpu_ins[i].adev->reset_list, &device_list);
|
||||
|
||||
/* unregister the GPU first, reset function will add them back */
|
||||
list_for_each_entry(adev, &device_list, reset_list)
|
||||
amdgpu_unregister_gpu_instance(adev);
|
||||
|
||||
r = amdgpu_do_asic_reset(NULL, &device_list, &need_full_reset, true);
|
||||
if (r) {
|
||||
DRM_ERROR("reinit gpus failure");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < mgpu_info.num_dgpu; i++) {
|
||||
adev = mgpu_info.gpu_ins[i].adev;
|
||||
if (!adev->kfd.init_complete)
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user