mirror of
https://github.com/torvalds/linux.git
synced 2026-04-28 03:22:27 -04:00
Merge tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"Lots of stuff all over, some new AMD IP support and gang submit
support. i915 has further DG2 and Meteorlake pieces, and a bunch of
i915 display refactoring. msm has a shrinker rework. There are also a
bunch of conversions to use kunit.
This has two external pieces, some MEI changes needed for future Intel
discrete GPUs. These should be acked by Greg. There is also a cross
maintainer shared tree with some backlight rework from Hans in here.
Core:
- convert selftests to kunit
- managed init for more objects
- move to idr_init_base
- rename fb and gem cma helpers to dma
- hide unregistered connectors from getconnector ioctl
- DSC passthrough aux support
- backlight handling improvements
- add dma_resv_assert_held to vmap/vunmap
edid:
- move luminance calculation to core
fbdev:
- fix aperture helper usage
fourcc:
- add more format helpers
- add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx, DRM_FORMAT_Dxx
- add packed AYUV8888, XYUV8888
- add some kunit tests
ttm:
- allow bos without backing store
- rewrite placement to use intersect/compatible functions
dma-buf:
- docs update
- improve signalling when debugging
udmabuf:
- fix failure path GPF
dp:
- drop dp/mst legacy code
- atomic mst state support
- audio infoframe packing
panel:
- Samsung LTL101AL01
- B120XAN01.0
- R140NWF5 RH
- DMT028VGHMCMI-1A T
- AUO B133UAN02.1
- IVO M133NW4J-R3
- Innolux N120ACA-EA1
amdgpu:
- Gang submit support
- Mode2 reset for RDNA2
- New IP support:
DCN 3.1.4, 3.2
SMU 13.x
NBIO 7.7
GC 11.x
PSP 13.x
SDMA 6.x
GMC 11.x
- DSC passthrough support
- PSP fixes for TA support
- vangogh GFXOFF stats
- clang fixes
- gang submit CS cleanup prep work
- fix VRAM eviction issues
amdkfd:
- GC 10.3 IP ISA fixes
- fix CRIU regression
- CPU fault on COW mapping fixes
i915:
- align fw versioning with kernel practices
- add display substruct to i915 private
- add initial runtime info to driver info
- split out HDCP and backlight registers
- MEI XeHP SDV GSC support
- add per-gt sysfs defaults
- TLB invalidation improvements
- Disable PCI BAR resize on 32-bit
- GuC firmware updates and compat changes
- GuC log timestamp translation
- DG2 preemption workaround changes
- DG2 improved HDMI pixel clocks support
- PCI BAR sanity checks
- Enable DC5 on DG2
- DG2 DMC fw bumped
- ADL-S PCI ID added
- Meteorlake enablement
- Rename ggtt_view to gtt_view
- host RPS fixes
- release mmaps on rpm suspend on discrete
- clocking and dpll refactoring
- VBT definitions and parsing updates
- SKL watermark code extracted to separate file
- allow seamless M/N changes on eDP panels
- BUG_ON removal and cleanups
msm:
- DPU:
simplified VBIF configuration
cleanup CTL interfaces
- DSI:
removed unused msm_display_dsc_config struct
switch regulator calls to new API
switched to PANEL_BRIDGE for direct attached panels
- DSI_PHY: convert drivers to parent_hws
- DP: cleanup pixel_rate handling
- HDMI: turned hdmi-phy-8996 into OF clk provider
- misc dt-bindings fixes
- choose eDP as primary display if it's available
- support getting interconnects from either the mdss or the mdp5/dpu
device nodes
- gem: Shrinker + LRU re-work:
- adds a shared GEM LRU+shrinker helper and moves msm over to that
- reduce lock contention between retire and submit by avoiding the
need to acquire obj lock in retire path (and instead using resv
seeing obj's busyness in the shrinker
- fix reclaim vs submit issues
- GEM fault injection for triggering userspace error paths
- Map/unmap optimization
- Improved robustness for a6xx GPU recovery
virtio:
- improve error and edge conditions handling
- convert to use managed helpers
- stop exposing LINEAR modifier
mgag200:
- split modeset handling per model
udl:
- suspend/disconnect handling improvements
vc4:
- rework HDMI power up
- depend on PM
- better unplugging support
ast:
- resolution handling improvements
ingenic:
- add JZ4760(B) support
- avoid a modeset when sharpness property is unchanged
- use the new PM ops
it6505:
- power seq and clock updates
ssd130x:
- regmap bulk write
- use atomic helpers instead of simple helpers
via:
- rename via_drv to via_dri1, consolidate all code.
radeon:
- drop DP MST experimental support
- delayed work flush fix
- use time_after
ti-sn65dsi86:
- DP support
mediatek:
- MT8195 DP support
- drop of_gpio header
- remove unneeded result
- small DP code improvements
vkms:
- RGB565, XRGB64 and ARGB64 support
sun4i:
- tv: convert to atomic
rcar-du:
- Synopsys DW HDMI bridge DT bindings update
exynos:
- use drm_display_info.is_hdmi
- correct return of mixer_mode_valid and hdmi_mode_valid
omap:
- refcounting fix
rockchip:
- RK3568 support
- RK3399 gamma support"
* tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm: (1374 commits)
drm/amdkfd: Fix UBSAN shift-out-of-bounds warning
drm/amdkfd: Track unified memory when switching xnack mode
drm/amdgpu: Enable sram on vcn_4_0_2
drm/amdgpu: Enable VCN DPG for GC11_0_1
drm/msm: Fix build break with recent mm tree
drm/panel: simple: Use dev_err_probe() to simplify code
drm/panel: panel-edp: Use dev_err_probe() to simplify code
drm/panel: simple: Add Multi-Inno Technology MI0800FT-9
dt-bindings: display: simple: Add Multi-Inno Technology MI0800FT-9 panel
drm/amdgpu: correct the memcpy size for ip discovery firmware
drm/amdgpu: Skip put_reset_domain if it doesn't exist
drm/amdgpu: remove switch from amdgpu_gmc_noretry_set
drm/amdgpu: Fix mc_umc_status used uninitialized warning
drm/amd/display: Prevent OTG shutdown during PSR SU
drm/amdgpu: add page retirement handling for CPU RAS
drm/amdgpu: use RAS error address convert api in mca notifier
drm/amdgpu: support to convert dedicated umc mca address
drm/amdgpu: export umc error address convert interface
drm/amdgpu: fix sdma v4 init microcode error
drm/amd/display: fix array-bounds error in dc_stream_remove_writeback()
...
This commit is contained in:
@@ -75,7 +75,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 arct_reg_init.o mxgpu_nv.o \
|
||||
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
|
||||
nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
|
||||
sienna_cichlid.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
@@ -89,7 +89,7 @@ amdgpu-y += \
|
||||
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_v3_0_1.o
|
||||
mmhub_v3_0_1.o gfxhub_v3_0_3.o
|
||||
|
||||
# add UMC block
|
||||
amdgpu-y += \
|
||||
@@ -134,7 +134,8 @@ amdgpu-y += \
|
||||
gfx_v9_4_2.o \
|
||||
gfx_v10_0.o \
|
||||
imu_v11_0.o \
|
||||
gfx_v11_0.o
|
||||
gfx_v11_0.o \
|
||||
imu_v11_0_3.o
|
||||
|
||||
# add async DMA block
|
||||
amdgpu-y += \
|
||||
|
||||
@@ -274,6 +274,9 @@ extern int amdgpu_vcnfw_log;
|
||||
#define AMDGPU_RESET_VCE (1 << 13)
|
||||
#define AMDGPU_RESET_VCE1 (1 << 14)
|
||||
|
||||
#define AMDGPU_RESET_LEVEL_SOFT_RECOVERY (1 << 0)
|
||||
#define AMDGPU_RESET_LEVEL_MODE2 (1 << 1)
|
||||
|
||||
/* max cursor sizes (in pixels) */
|
||||
#define CIK_CURSOR_WIDTH 128
|
||||
#define CIK_CURSOR_HEIGHT 128
|
||||
@@ -882,6 +885,7 @@ struct amdgpu_device {
|
||||
u64 fence_context;
|
||||
unsigned num_rings;
|
||||
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
|
||||
struct dma_fence __rcu *gang_submit;
|
||||
bool ib_pool_ready;
|
||||
struct amdgpu_sa_manager ib_pools[AMDGPU_IB_POOL_MAX];
|
||||
struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
|
||||
@@ -1060,6 +1064,9 @@ struct amdgpu_device {
|
||||
uint32_t scpm_status;
|
||||
|
||||
struct work_struct reset_work;
|
||||
|
||||
uint32_t amdgpu_reset_level_mask;
|
||||
bool job_hang;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||
@@ -1288,6 +1295,8 @@ u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
|
||||
u32 reg);
|
||||
void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
|
||||
u32 reg, u32 v);
|
||||
struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
|
||||
struct dma_fence *gang);
|
||||
|
||||
/* atpx handler */
|
||||
#if defined(CONFIG_VGA_SWITCHEROO)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2012 Advanced Micro Devices, Inc.
|
||||
*
|
||||
@@ -849,6 +850,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
|
||||
if (dm->backlight_dev[0])
|
||||
atif->bd = dm->backlight_dev[0];
|
||||
#endif
|
||||
@@ -863,6 +865,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
|
||||
enc->enc_priv) {
|
||||
struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
|
||||
|
||||
if (dig->bl_dev) {
|
||||
atif->bd = dig->bl_dev;
|
||||
break;
|
||||
@@ -919,9 +922,9 @@ static bool amdgpu_atif_pci_probe_handle(struct pci_dev *pdev)
|
||||
return false;
|
||||
|
||||
status = acpi_get_handle(dhandle, "ATIF", &atif_handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
}
|
||||
|
||||
amdgpu_acpi_priv.atif.handle = atif_handle;
|
||||
acpi_get_name(amdgpu_acpi_priv.atif.handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
|
||||
@@ -954,9 +957,9 @@ static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
|
||||
return false;
|
||||
|
||||
status = acpi_get_handle(dhandle, "ATCS", &atcs_handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
}
|
||||
|
||||
amdgpu_acpi_priv.atcs.handle = atcs_handle;
|
||||
acpi_get_name(amdgpu_acpi_priv.atcs.handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name);
|
||||
@@ -1070,6 +1073,12 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
|
||||
(pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
|
||||
* risky to do any special firmware-related preparations for entering
|
||||
* S0ix even though the system is suspending to idle, so return false
|
||||
* in that case.
|
||||
*/
|
||||
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
|
||||
dev_warn_once(adev->dev,
|
||||
"Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2014 Advanced Micro Devices, Inc.
|
||||
*
|
||||
@@ -130,11 +131,13 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
|
||||
kfd.reset_work);
|
||||
|
||||
struct amdgpu_reset_context reset_context;
|
||||
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
@@ -683,6 +686,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
||||
ib->length_dw = ib_len;
|
||||
/* This works for NO_HWS. TODO: need to handle without knowing VMID */
|
||||
job->vmid = vmid;
|
||||
job->num_ibs = 1;
|
||||
|
||||
ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
|
||||
|
||||
@@ -752,11 +756,7 @@ void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bo
|
||||
{
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
|
||||
/* CPU MCA will handle page retirement if connected_to_cpu is 1 */
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
amdgpu_umc_poison_handler(adev, &err_data, reset);
|
||||
else if (reset)
|
||||
amdgpu_amdkfd_gpu_reset(adev);
|
||||
amdgpu_umc_poison_handler(adev, &err_data, reset);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2014-2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
@@ -297,7 +298,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
|
||||
*/
|
||||
replacement = dma_fence_get_stub();
|
||||
dma_resv_replace_fences(bo->tbo.base.resv, ef->base.context,
|
||||
replacement, DMA_RESV_USAGE_READ);
|
||||
replacement, DMA_RESV_USAGE_BOOKKEEP);
|
||||
dma_fence_put(replacement);
|
||||
return 0;
|
||||
}
|
||||
@@ -1390,8 +1391,9 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
|
||||
ret = dma_resv_reserve_fences(vm->root.bo->tbo.base.resv, 1);
|
||||
if (ret)
|
||||
goto reserve_shared_fail;
|
||||
amdgpu_bo_fence(vm->root.bo,
|
||||
&vm->process_info->eviction_fence->base, true);
|
||||
dma_resv_add_fence(vm->root.bo->tbo.base.resv,
|
||||
&vm->process_info->eviction_fence->base,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
/* Update process info */
|
||||
@@ -1612,6 +1614,7 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
|
||||
uint64_t reserved_for_pt =
|
||||
ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
|
||||
size_t available;
|
||||
|
||||
spin_lock(&kfd_mem_limit.mem_limit_lock);
|
||||
available = adev->gmc.real_vram_size
|
||||
- adev->kfd.vram_used_aligned
|
||||
@@ -1987,9 +1990,9 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
||||
}
|
||||
|
||||
if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count)
|
||||
amdgpu_bo_fence(bo,
|
||||
&avm->process_info->eviction_fence->base,
|
||||
true);
|
||||
dma_resv_add_fence(bo->tbo.base.resv,
|
||||
&avm->process_info->eviction_fence->base,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
ret = unreserve_bo_and_vms(&ctx, false, false);
|
||||
|
||||
goto out;
|
||||
@@ -2216,7 +2219,7 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
|
||||
{
|
||||
if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) {
|
||||
*mem = *adev->gmc.vm_fault_info;
|
||||
mb();
|
||||
mb(); /* make sure read happened */
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 0);
|
||||
}
|
||||
return 0;
|
||||
@@ -2758,15 +2761,18 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
|
||||
if (mem->bo->tbo.pin_count)
|
||||
continue;
|
||||
|
||||
amdgpu_bo_fence(mem->bo,
|
||||
&process_info->eviction_fence->base, true);
|
||||
dma_resv_add_fence(mem->bo->tbo.base.resv,
|
||||
&process_info->eviction_fence->base,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
}
|
||||
/* Attach eviction fence to PD / PT BOs */
|
||||
list_for_each_entry(peer_vm, &process_info->vm_list_head,
|
||||
vm_list_node) {
|
||||
struct amdgpu_bo *bo = peer_vm->root.bo;
|
||||
|
||||
amdgpu_bo_fence(bo, &process_info->eviction_fence->base, true);
|
||||
dma_resv_add_fence(bo->tbo.base.resv,
|
||||
&process_info->eviction_fence->base,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
}
|
||||
|
||||
validate_map_fail:
|
||||
@@ -2820,7 +2826,9 @@ int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem
|
||||
ret = dma_resv_reserve_fences(gws_bo->tbo.base.resv, 1);
|
||||
if (ret)
|
||||
goto reserve_shared_fail;
|
||||
amdgpu_bo_fence(gws_bo, &process_info->eviction_fence->base, true);
|
||||
dma_resv_add_fence(gws_bo->tbo.base.resv,
|
||||
&process_info->eviction_fence->base,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
amdgpu_bo_unreserve(gws_bo);
|
||||
mutex_unlock(&(*mem)->process_info->lock);
|
||||
|
||||
|
||||
@@ -1674,10 +1674,12 @@ amdgpu_connector_add(struct amdgpu_device *adev,
|
||||
adev->mode_info.dither_property,
|
||||
AMDGPU_FMT_DITHER_DISABLE);
|
||||
|
||||
if (amdgpu_audio != 0)
|
||||
if (amdgpu_audio != 0) {
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.audio_property,
|
||||
AMDGPU_AUDIO_AUTO);
|
||||
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
|
||||
}
|
||||
|
||||
subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = true;
|
||||
@@ -1799,6 +1801,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.audio_property,
|
||||
AMDGPU_AUDIO_AUTO);
|
||||
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
|
||||
}
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.dither_property,
|
||||
@@ -1852,6 +1855,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.audio_property,
|
||||
AMDGPU_AUDIO_AUTO);
|
||||
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
|
||||
}
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.dither_property,
|
||||
@@ -1902,6 +1906,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.audio_property,
|
||||
AMDGPU_AUDIO_AUTO);
|
||||
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
|
||||
}
|
||||
drm_object_attach_property(&amdgpu_connector->base.base,
|
||||
adev->mode_info.dither_property,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,8 @@
|
||||
#include "amdgpu_bo_list.h"
|
||||
#include "amdgpu_ring.h"
|
||||
|
||||
#define AMDGPU_CS_GANG_SIZE 4
|
||||
|
||||
struct amdgpu_bo_va_mapping;
|
||||
|
||||
struct amdgpu_cs_chunk {
|
||||
@@ -50,9 +52,11 @@ struct amdgpu_cs_parser {
|
||||
unsigned nchunks;
|
||||
struct amdgpu_cs_chunk *chunks;
|
||||
|
||||
/* scheduler job object */
|
||||
struct amdgpu_job *job;
|
||||
struct drm_sched_entity *entity;
|
||||
/* scheduler job objects */
|
||||
unsigned int gang_size;
|
||||
struct drm_sched_entity *entities[AMDGPU_CS_GANG_SIZE];
|
||||
struct amdgpu_job *jobs[AMDGPU_CS_GANG_SIZE];
|
||||
struct amdgpu_job *gang_leader;
|
||||
|
||||
/* buffer objects */
|
||||
struct ww_acquire_ctx ticket;
|
||||
|
||||
@@ -315,7 +315,6 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
|
||||
kref_init(&ctx->refcount);
|
||||
ctx->mgr = mgr;
|
||||
spin_lock_init(&ctx->ring_lock);
|
||||
mutex_init(&ctx->lock);
|
||||
|
||||
ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
|
||||
ctx->reset_counter_query = ctx->reset_counter;
|
||||
@@ -402,12 +401,11 @@ static void amdgpu_ctx_fini(struct kref *ref)
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
||||
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||
amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
mutex_destroy(&ctx->lock);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
@@ -848,7 +846,7 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr,
|
||||
|
||||
mgr->adev = adev;
|
||||
mutex_init(&mgr->lock);
|
||||
idr_init(&mgr->ctx_handles);
|
||||
idr_init_base(&mgr->ctx_handles, 1);
|
||||
|
||||
for (i = 0; i < AMDGPU_HW_IP_NUM; ++i)
|
||||
atomic64_set(&mgr->time_spend[i], 0);
|
||||
|
||||
@@ -53,7 +53,6 @@ struct amdgpu_ctx {
|
||||
bool preamble_presented;
|
||||
int32_t init_priority;
|
||||
int32_t override_priority;
|
||||
struct mutex lock;
|
||||
atomic_t guilty;
|
||||
unsigned long ras_counter_ce;
|
||||
unsigned long ras_counter_ue;
|
||||
|
||||
@@ -1042,6 +1042,157 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency
|
||||
*
|
||||
* @f: open file handle
|
||||
* @buf: User buffer to store read data in
|
||||
* @size: Number of bytes to read
|
||||
* @pos: Offset to seek to
|
||||
*
|
||||
* Read the last residency value logged. It doesn't auto update, one needs to
|
||||
* stop logging before getting the current value.
|
||||
*/
|
||||
static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
r = amdgpu_get_gfx_off_residency(adev, &value);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
*pos += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency
|
||||
*
|
||||
* @f: open file handle
|
||||
* @buf: User buffer to write data from
|
||||
* @size: Number of bytes to write
|
||||
* @pos: Offset to seek to
|
||||
*
|
||||
* Write a 32-bit non-zero to start logging; write a 32-bit zero to stop
|
||||
*/
|
||||
static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
u32 value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
amdgpu_set_gfx_off_residency(adev, value ? true : false);
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
*pos += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count
|
||||
*
|
||||
* @f: open file handle
|
||||
* @buf: User buffer to store read data in
|
||||
* @size: Number of bytes to read
|
||||
* @pos: Offset to seek to
|
||||
*/
|
||||
static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
u64 value = 0;
|
||||
|
||||
r = amdgpu_get_gfx_off_entrycount(adev, &value);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = put_user(value, (u64 *)buf);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
*pos += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
|
||||
*
|
||||
@@ -1249,6 +1400,19 @@ static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = amdgpu_debugfs_gfxoff_count_read,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = amdgpu_debugfs_gfxoff_residency_read,
|
||||
.write = amdgpu_debugfs_gfxoff_residency_write,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations *debugfs_regs[] = {
|
||||
&amdgpu_debugfs_regs_fops,
|
||||
&amdgpu_debugfs_regs2_fops,
|
||||
@@ -1261,6 +1425,8 @@ static const struct file_operations *debugfs_regs[] = {
|
||||
&amdgpu_debugfs_gpr_fops,
|
||||
&amdgpu_debugfs_gfxoff_fops,
|
||||
&amdgpu_debugfs_gfxoff_status_fops,
|
||||
&amdgpu_debugfs_gfxoff_count_fops,
|
||||
&amdgpu_debugfs_gfxoff_residency_fops,
|
||||
};
|
||||
|
||||
static const char *debugfs_regs_names[] = {
|
||||
@@ -1275,6 +1441,8 @@ static const char *debugfs_regs_names[] = {
|
||||
"amdgpu_gpr",
|
||||
"amdgpu_gfxoff",
|
||||
"amdgpu_gfxoff_status",
|
||||
"amdgpu_gfxoff_count",
|
||||
"amdgpu_gfxoff_residency",
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1786,6 +1954,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
||||
return PTR_ERR(ent);
|
||||
}
|
||||
|
||||
debugfs_create_u32("amdgpu_reset_level", 0600, root, &adev->amdgpu_reset_level_mask);
|
||||
|
||||
/* Register debugfs entries for amdgpu_ttm */
|
||||
amdgpu_ttm_debugfs_init(adev);
|
||||
amdgpu_debugfs_pm_init(adev);
|
||||
|
||||
@@ -2459,19 +2459,21 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
*/
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
if (amdgpu_xgmi_add_device(adev) == 0) {
|
||||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
|
||||
|
||||
if (!hive->reset_domain ||
|
||||
!amdgpu_reset_get_reset_domain(hive->reset_domain)) {
|
||||
r = -ENOENT;
|
||||
if (!hive->reset_domain ||
|
||||
!amdgpu_reset_get_reset_domain(hive->reset_domain)) {
|
||||
r = -ENOENT;
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
/* Drop the early temporary reset domain we created for device */
|
||||
amdgpu_reset_put_reset_domain(adev->reset_domain);
|
||||
adev->reset_domain = hive->reset_domain;
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
/* Drop the early temporary reset domain we created for device */
|
||||
amdgpu_reset_put_reset_domain(adev->reset_domain);
|
||||
adev->reset_domain = hive->reset_domain;
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3510,6 +3512,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
adev->gmc.gart_size = 512 * 1024 * 1024;
|
||||
adev->accel_working = false;
|
||||
adev->num_rings = 0;
|
||||
RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
|
||||
adev->mman.buffer_funcs = NULL;
|
||||
adev->mman.buffer_funcs_ring = NULL;
|
||||
adev->vm_manager.vm_pte_funcs = NULL;
|
||||
@@ -3588,6 +3591,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
|
||||
|
||||
adev->gfx.gfx_off_req_count = 1;
|
||||
adev->gfx.gfx_off_residency = 0;
|
||||
adev->gfx.gfx_off_entrycount = 0;
|
||||
adev->pm.ac_power = power_supply_is_system_supplied() > 0;
|
||||
|
||||
atomic_set(&adev->throttling_logging_enabled, 1);
|
||||
@@ -3976,8 +3981,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
|
||||
amdgpu_gart_dummy_page_fini(adev);
|
||||
|
||||
if (drm_dev_is_unplugged(adev_to_drm(adev)))
|
||||
amdgpu_device_unmap_mmio(adev);
|
||||
amdgpu_device_unmap_mmio(adev);
|
||||
|
||||
}
|
||||
|
||||
@@ -3990,6 +3994,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
||||
release_firmware(adev->firmware.gpu_info_fw);
|
||||
adev->firmware.gpu_info_fw = NULL;
|
||||
adev->accel_working = false;
|
||||
dma_fence_put(rcu_dereference_protected(adev->gang_submit, true));
|
||||
|
||||
amdgpu_reset_fini(adev);
|
||||
|
||||
@@ -4542,14 +4547,15 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
|
||||
*/
|
||||
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_device_ip_check_soft_reset(adev)) {
|
||||
dev_info(adev->dev, "Timeout, but no hardware hang detected.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (amdgpu_gpu_recovery == 0)
|
||||
goto disabled;
|
||||
|
||||
if (!amdgpu_device_ip_check_soft_reset(adev)) {
|
||||
dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return true;
|
||||
|
||||
@@ -4674,7 +4680,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
if (!need_full_reset)
|
||||
need_full_reset = amdgpu_device_ip_need_full_reset(adev);
|
||||
|
||||
if (!need_full_reset) {
|
||||
if (!need_full_reset && amdgpu_gpu_recovery) {
|
||||
amdgpu_device_ip_pre_soft_reset(adev);
|
||||
r = amdgpu_device_ip_soft_reset(adev);
|
||||
amdgpu_device_ip_post_soft_reset(adev);
|
||||
@@ -4770,6 +4776,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
bool need_full_reset, skip_hw_reset, vram_lost = false;
|
||||
int r = 0;
|
||||
bool gpu_reset_for_dev_remove = 0;
|
||||
|
||||
/* Try reset handler method first */
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
@@ -4789,6 +4796,10 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
|
||||
|
||||
gpu_reset_for_dev_remove =
|
||||
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
|
||||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
|
||||
/*
|
||||
* ASIC reset has to be done on all XGMI hive nodes ASAP
|
||||
* to allow proper links negotiation in FW (within 1 sec)
|
||||
@@ -4833,6 +4844,18 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
amdgpu_ras_intr_cleared();
|
||||
}
|
||||
|
||||
/* Since the mode1 reset affects base ip blocks, the
|
||||
* phase1 ip blocks need to be resumed. Otherwise there
|
||||
* will be a BIOS signature error and the psp bootloader
|
||||
* can't load kdb on the next amdgpu install.
|
||||
*/
|
||||
if (gpu_reset_for_dev_remove) {
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list)
|
||||
amdgpu_device_ip_resume_phase1(tmp_adev);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
if (need_full_reset) {
|
||||
/* post card */
|
||||
@@ -5072,6 +5095,7 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
|
||||
/* set guilty */
|
||||
drm_sched_increase_karma(s_job);
|
||||
amdgpu_reset_prepare_hwcontext(adev, reset_context);
|
||||
retry:
|
||||
/* do hw reset */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
@@ -5154,6 +5178,11 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
int tmp_vram_lost_counter;
|
||||
bool gpu_reset_for_dev_remove = false;
|
||||
|
||||
gpu_reset_for_dev_remove =
|
||||
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
|
||||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
@@ -5181,6 +5210,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
|
||||
reset_context->job = job;
|
||||
reset_context->hive = hive;
|
||||
|
||||
/*
|
||||
* Build list of devices to reset.
|
||||
* In case we are in XGMI hive mode, resort the device list
|
||||
@@ -5188,8 +5218,11 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
*/
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
if (gpu_reset_for_dev_remove && adev->shutdown)
|
||||
tmp_adev->shutdown = true;
|
||||
}
|
||||
if (!list_is_first(&adev->reset_list, &device_list))
|
||||
list_rotate_to_front(&adev->reset_list, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
@@ -5272,6 +5305,10 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
|
||||
retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
if (gpu_reset_for_dev_remove) {
|
||||
/* Workaroud for ASICs need to disable SMC first */
|
||||
amdgpu_device_smu_fini_early(tmp_adev);
|
||||
}
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
|
||||
/*TODO Should we stop ?*/
|
||||
if (r) {
|
||||
@@ -5300,8 +5337,14 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
amdgpu_ras_resume(adev);
|
||||
} else {
|
||||
r = amdgpu_do_asic_reset(device_list_handle, reset_context);
|
||||
if (r && r == -EAGAIN)
|
||||
if (r && r == -EAGAIN) {
|
||||
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags);
|
||||
adev->asic_reset_res = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!r && gpu_reset_for_dev_remove)
|
||||
goto recover_end;
|
||||
}
|
||||
|
||||
skip_hw_reset:
|
||||
@@ -5375,6 +5418,7 @@ skip_sched_resume:
|
||||
amdgpu_device_unset_mp1_state(tmp_adev);
|
||||
}
|
||||
|
||||
recover_end:
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
reset_list);
|
||||
amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
|
||||
@@ -5557,9 +5601,9 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
|
||||
~*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 = !adev->gmc.xgmi.connected_to_cpu &&
|
||||
!(pci_p2pdma_distance_many(adev->pdev,
|
||||
&peer_adev->dev, 1, true) < 0);
|
||||
bool p2p_access =
|
||||
!adev->gmc.xgmi.connected_to_cpu &&
|
||||
!(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0);
|
||||
|
||||
return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
|
||||
adev->gmc.real_vram_size == adev->gmc.visible_vram_size &&
|
||||
@@ -5733,6 +5777,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
||||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
adev->no_hw_access = true;
|
||||
r = amdgpu_device_pre_asic_reset(adev, &reset_context);
|
||||
@@ -5942,3 +5987,36 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
|
||||
(void)RREG32(data);
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_switch_gang - switch to a new gang
|
||||
* @adev: amdgpu_device pointer
|
||||
* @gang: the gang to switch to
|
||||
*
|
||||
* Try to switch to a new gang.
|
||||
* Returns: NULL if we switched to the new gang or a reference to the current
|
||||
* gang leader.
|
||||
*/
|
||||
struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
|
||||
struct dma_fence *gang)
|
||||
{
|
||||
struct dma_fence *old = NULL;
|
||||
|
||||
do {
|
||||
dma_fence_put(old);
|
||||
rcu_read_lock();
|
||||
old = dma_fence_get_rcu_safe(&adev->gang_submit);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (old == gang)
|
||||
break;
|
||||
|
||||
if (!dma_fence_is_signaled(old))
|
||||
return old;
|
||||
|
||||
} while (cmpxchg((struct dma_fence __force **)&adev->gang_submit,
|
||||
old, gang) != old);
|
||||
|
||||
dma_fence_put(old);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, ui
|
||||
return r;
|
||||
}
|
||||
|
||||
memcpy((u8 *)binary, (u8 *)fw->data, adev->mman.discovery_tmr_size);
|
||||
memcpy((u8 *)binary, (u8 *)fw->data, fw->size);
|
||||
release_firmware(fw);
|
||||
|
||||
return 0;
|
||||
@@ -1506,6 +1506,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1549,6 +1550,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1633,6 +1635,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 4):
|
||||
@@ -1682,6 +1685,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1780,6 +1784,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1823,6 +1828,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(6, 0, 0):
|
||||
case IP_VERSION(6, 0, 1):
|
||||
case IP_VERSION(6, 0, 2):
|
||||
case IP_VERSION(6, 0, 3):
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1903,7 +1909,8 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||
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);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
@@ -1940,6 +1947,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
|
||||
adev->enable_mes = true;
|
||||
adev->enable_mes_kiq = true;
|
||||
@@ -2165,6 +2173,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
break;
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->family = AMDGPU_FAMILY_GC_11_0_0;
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
@@ -2234,7 +2243,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
break;
|
||||
case IP_VERSION(4, 3, 0):
|
||||
case IP_VERSION(4, 3, 1):
|
||||
adev->nbio.funcs = &nbio_v4_3_funcs;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->nbio.funcs = &nbio_v4_3_sriov_funcs;
|
||||
else
|
||||
adev->nbio.funcs = &nbio_v4_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 7, 0):
|
||||
@@ -2332,6 +2344,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(6, 0, 0):
|
||||
case IP_VERSION(6, 0, 1):
|
||||
case IP_VERSION(6, 0, 2):
|
||||
case IP_VERSION(6, 0, 3):
|
||||
adev->lsdma.funcs = &lsdma_v6_0_funcs;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -58,7 +58,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
int r;
|
||||
|
||||
if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, true) < 0)
|
||||
if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
attach->peer2peer = false;
|
||||
|
||||
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
|
||||
|
||||
@@ -102,9 +102,10 @@
|
||||
* - 3.46.0 - To enable hot plug amdgpu tests in libdrm
|
||||
* - 3.47.0 - Add AMDGPU_GEM_CREATE_DISCARDABLE and AMDGPU_VM_NOALLOC flags
|
||||
* - 3.48.0 - Add IP discovery version info to HW INFO
|
||||
* 3.49.0 - Add gang submit into CS IOCTL
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 48
|
||||
#define KMS_DRIVER_MINOR 49
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit;
|
||||
@@ -2181,15 +2182,46 @@ amdgpu_pci_remove(struct pci_dev *pdev)
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
||||
drm_dev_unplug(dev);
|
||||
|
||||
if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
|
||||
pm_runtime_get_sync(dev->dev);
|
||||
pm_runtime_forbid(dev->dev);
|
||||
}
|
||||
|
||||
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) {
|
||||
bool need_to_reset_gpu = false;
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
struct amdgpu_hive_info *hive;
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive->device_remove_count == 0)
|
||||
need_to_reset_gpu = true;
|
||||
hive->device_remove_count++;
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
} else {
|
||||
need_to_reset_gpu = true;
|
||||
}
|
||||
|
||||
/* Workaround for ASICs need to reset SMU.
|
||||
* Called only when the first device is removed.
|
||||
*/
|
||||
if (need_to_reset_gpu) {
|
||||
struct amdgpu_reset_context reset_context;
|
||||
|
||||
adev->shutdown = true;
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags);
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_driver_unload_kms(dev);
|
||||
|
||||
drm_dev_unplug(dev);
|
||||
|
||||
/*
|
||||
* Flush any in flight DMA operations from device.
|
||||
* Clear the Bus Master Enable bit and then wait on the PCIe Device
|
||||
@@ -2563,8 +2595,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
|
||||
amdgpu_device_baco_exit(drm_dev);
|
||||
}
|
||||
ret = amdgpu_device_resume(drm_dev, false);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
if (amdgpu_device_supports_px(drm_dev))
|
||||
pci_disable_device(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (amdgpu_device_supports_px(drm_dev))
|
||||
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_gfx.h"
|
||||
#include "amdgpu_rlc.h"
|
||||
@@ -477,7 +478,7 @@ int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev)
|
||||
kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i],
|
||||
RESET_QUEUES, 0, 0);
|
||||
|
||||
if (adev->gfx.kiq.ring.sched.ready)
|
||||
if (adev->gfx.kiq.ring.sched.ready && !adev->job_hang)
|
||||
r = amdgpu_ring_test_helper(kiq_ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
|
||||
@@ -610,6 +611,45 @@ unlock:
|
||||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||
}
|
||||
|
||||
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
r = amdgpu_dpm_set_residency_gfxoff(adev, value);
|
||||
|
||||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *value)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
r = amdgpu_dpm_get_residency_gfxoff(adev, value);
|
||||
|
||||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
r = amdgpu_dpm_get_entrycount_gfxoff(adev, value);
|
||||
|
||||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
|
||||
{
|
||||
|
||||
@@ -826,3 +866,142 @@ int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
|
||||
}
|
||||
return amdgpu_num_kcq;
|
||||
}
|
||||
|
||||
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev,
|
||||
uint32_t ucode_id)
|
||||
{
|
||||
const struct gfx_firmware_header_v1_0 *cp_hdr;
|
||||
const struct gfx_firmware_header_v2_0 *cp_hdr_v2_0;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct firmware *ucode_fw;
|
||||
unsigned int fw_size;
|
||||
|
||||
switch (ucode_id) {
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.pfp_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_PFP:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.pfp_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK:
|
||||
case AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.pfp_fw->data;
|
||||
ucode_fw = adev->gfx.pfp_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.me_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.me_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_ME:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.me_feature_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.me_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK:
|
||||
case AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.me_fw->data;
|
||||
ucode_fw = adev->gfx.me_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.ce_fw->data;
|
||||
adev->gfx.ce_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.ce_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.ce_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.mec_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
|
||||
le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_MEC1_JT:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec_fw->data;
|
||||
ucode_fw = adev->gfx.mec_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec2_fw->data;
|
||||
adev->gfx.mec2_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec2_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.mec2_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
|
||||
le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_MEC2_JT:
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec2_fw->data;
|
||||
ucode_fw = adev->gfx.mec2_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_MEC:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.mec_feature_version =
|
||||
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
ucode_fw = adev->gfx.mec_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK:
|
||||
case AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK:
|
||||
case AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK:
|
||||
case AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK:
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
|
||||
adev->gfx.mec_fw->data;
|
||||
ucode_fw = adev->gfx.mec_fw;
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[ucode_id];
|
||||
info->ucode_id = ucode_id;
|
||||
info->fw = ucode_fw;
|
||||
adev->firmware.fw_size += ALIGN(fw_size, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,10 +336,12 @@ struct amdgpu_gfx {
|
||||
uint32_t srbm_soft_reset;
|
||||
|
||||
/* gfx off */
|
||||
bool gfx_off_state; /* true: enabled, false: disabled */
|
||||
struct mutex gfx_off_mutex;
|
||||
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
|
||||
struct delayed_work gfx_off_delay_work;
|
||||
bool gfx_off_state; /* true: enabled, false: disabled */
|
||||
struct mutex gfx_off_mutex; /* mutex to change gfxoff state */
|
||||
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
|
||||
struct delayed_work gfx_off_delay_work; /* async work to set gfx block off */
|
||||
uint32_t gfx_off_residency; /* last logged residency */
|
||||
uint64_t gfx_off_entrycount; /* count of times GPU has get into GFXOFF state */
|
||||
|
||||
/* pipe reservation */
|
||||
struct mutex pipe_reserve_mutex;
|
||||
@@ -411,6 +413,10 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
|
||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
|
||||
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
|
||||
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value);
|
||||
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *residency);
|
||||
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value);
|
||||
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
void *err_data,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
@@ -420,4 +426,6 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
|
||||
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
|
||||
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,9 @@ struct amdgpu_gfxhub_funcs {
|
||||
void (*init)(struct amdgpu_device *adev);
|
||||
int (*get_xgmi_info)(struct amdgpu_device *adev);
|
||||
void (*utcl2_harvest)(struct amdgpu_device *adev);
|
||||
void (*mode2_save_regs)(struct amdgpu_device *adev);
|
||||
void (*mode2_restore_regs)(struct amdgpu_device *adev);
|
||||
void (*halt)(struct amdgpu_device *adev);
|
||||
};
|
||||
|
||||
struct amdgpu_gfxhub {
|
||||
|
||||
@@ -572,45 +572,15 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
||||
void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_gmc *gmc = &adev->gmc;
|
||||
uint32_t gc_ver = adev->ip_versions[GC_HWIP][0];
|
||||
bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) ||
|
||||
gc_ver == IP_VERSION(9, 3, 0) ||
|
||||
gc_ver == IP_VERSION(9, 4, 0) ||
|
||||
gc_ver == IP_VERSION(9, 4, 1) ||
|
||||
gc_ver == IP_VERSION(9, 4, 2) ||
|
||||
gc_ver >= IP_VERSION(10, 3, 0));
|
||||
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(9, 0, 1):
|
||||
case IP_VERSION(9, 3, 0):
|
||||
case IP_VERSION(9, 4, 0):
|
||||
case IP_VERSION(9, 4, 1):
|
||||
case IP_VERSION(9, 4, 2):
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(10, 3, 4):
|
||||
case IP_VERSION(10, 3, 5):
|
||||
case IP_VERSION(10, 3, 6):
|
||||
case IP_VERSION(10, 3, 7):
|
||||
/*
|
||||
* noretry = 0 will cause kfd page fault tests fail
|
||||
* for some ASICs, so set default to 1 for these ASICs.
|
||||
*/
|
||||
if (amdgpu_noretry == -1)
|
||||
gmc->noretry = 1;
|
||||
else
|
||||
gmc->noretry = amdgpu_noretry;
|
||||
break;
|
||||
default:
|
||||
/* Raven currently has issues with noretry
|
||||
* regardless of what we decide for other
|
||||
* asics, we should leave raven with
|
||||
* noretry = 0 until we root cause the
|
||||
* issues.
|
||||
*
|
||||
* default this to 0 for now, but we may want
|
||||
* to change this in the future for certain
|
||||
* GPUs as it can increase performance in
|
||||
* certain cases.
|
||||
*/
|
||||
if (amdgpu_noretry == -1)
|
||||
gmc->noretry = 0;
|
||||
else
|
||||
gmc->noretry = amdgpu_noretry;
|
||||
break;
|
||||
}
|
||||
gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
|
||||
}
|
||||
|
||||
void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
|
||||
|
||||
@@ -264,6 +264,32 @@ struct amdgpu_gmc {
|
||||
u64 mall_size;
|
||||
/* number of UMC instances */
|
||||
int num_umc;
|
||||
/* mode2 save restore */
|
||||
u64 VM_L2_CNTL;
|
||||
u64 VM_L2_CNTL2;
|
||||
u64 VM_DUMMY_PAGE_FAULT_CNTL;
|
||||
u64 VM_DUMMY_PAGE_FAULT_ADDR_LO32;
|
||||
u64 VM_DUMMY_PAGE_FAULT_ADDR_HI32;
|
||||
u64 VM_L2_PROTECTION_FAULT_CNTL;
|
||||
u64 VM_L2_PROTECTION_FAULT_CNTL2;
|
||||
u64 VM_L2_PROTECTION_FAULT_MM_CNTL3;
|
||||
u64 VM_L2_PROTECTION_FAULT_MM_CNTL4;
|
||||
u64 VM_L2_PROTECTION_FAULT_ADDR_LO32;
|
||||
u64 VM_L2_PROTECTION_FAULT_ADDR_HI32;
|
||||
u64 VM_DEBUG;
|
||||
u64 VM_L2_MM_GROUP_RT_CLASSES;
|
||||
u64 VM_L2_BANK_SELECT_RESERVED_CID;
|
||||
u64 VM_L2_BANK_SELECT_RESERVED_CID2;
|
||||
u64 VM_L2_CACHE_PARITY_CNTL;
|
||||
u64 VM_L2_IH_LOG_CNTL;
|
||||
u64 VM_CONTEXT_CNTL[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[16];
|
||||
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[16];
|
||||
u64 MC_VM_MX_L1_TLB_CNTL;
|
||||
};
|
||||
|
||||
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
|
||||
|
||||
@@ -204,6 +204,42 @@ void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
|
||||
amdgpu_gart_invalidate_tlb(adev);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_intersects - test for intersection
|
||||
*
|
||||
* @man: Our manager object
|
||||
* @res: The resource to test
|
||||
* @place: The place for the new allocation
|
||||
* @size: The size of the new allocation
|
||||
*
|
||||
* Simplified intersection test, only interesting if we need GART or not.
|
||||
*/
|
||||
static bool amdgpu_gtt_mgr_intersects(struct ttm_resource_manager *man,
|
||||
struct ttm_resource *res,
|
||||
const struct ttm_place *place,
|
||||
size_t size)
|
||||
{
|
||||
return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_compatible - test for compatibility
|
||||
*
|
||||
* @man: Our manager object
|
||||
* @res: The resource to test
|
||||
* @place: The place for the new allocation
|
||||
* @size: The size of the new allocation
|
||||
*
|
||||
* Simplified compatibility test.
|
||||
*/
|
||||
static bool amdgpu_gtt_mgr_compatible(struct ttm_resource_manager *man,
|
||||
struct ttm_resource *res,
|
||||
const struct ttm_place *place,
|
||||
size_t size)
|
||||
{
|
||||
return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_debug - dump VRAM table
|
||||
*
|
||||
@@ -225,6 +261,8 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
|
||||
static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
|
||||
.alloc = amdgpu_gtt_mgr_new,
|
||||
.free = amdgpu_gtt_mgr_del,
|
||||
.intersects = amdgpu_gtt_mgr_intersects,
|
||||
.compatible = amdgpu_gtt_mgr_compatible,
|
||||
.debug = amdgpu_gtt_mgr_debug
|
||||
};
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
}
|
||||
|
||||
memset(&ti, 0, sizeof(struct amdgpu_task_info));
|
||||
adev->job_hang = true;
|
||||
|
||||
if (amdgpu_gpu_recovery &&
|
||||
amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
|
||||
@@ -71,6 +72,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
|
||||
if (r)
|
||||
@@ -82,6 +84,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
||||
}
|
||||
|
||||
exit:
|
||||
adev->job_hang = false;
|
||||
drm_dev_exit(idx);
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
@@ -102,7 +105,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
*/
|
||||
(*job)->base.sched = &adev->rings[0]->sched;
|
||||
(*job)->vm = vm;
|
||||
(*job)->num_ibs = num_ibs;
|
||||
|
||||
amdgpu_sync_create(&(*job)->sync);
|
||||
amdgpu_sync_create(&(*job)->sched_sync);
|
||||
@@ -122,6 +124,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
(*job)->num_ibs = 1;
|
||||
r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);
|
||||
if (r)
|
||||
kfree(*job);
|
||||
@@ -129,6 +132,23 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
return r;
|
||||
}
|
||||
|
||||
void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
|
||||
struct amdgpu_bo *gws, struct amdgpu_bo *oa)
|
||||
{
|
||||
if (gds) {
|
||||
job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
|
||||
job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
|
||||
}
|
||||
if (gws) {
|
||||
job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
|
||||
job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
|
||||
}
|
||||
if (oa) {
|
||||
job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
|
||||
job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_job_free_resources(struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
|
||||
@@ -153,11 +173,29 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||
dma_fence_put(&job->hw_fence);
|
||||
}
|
||||
|
||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
struct amdgpu_job *leader)
|
||||
{
|
||||
struct dma_fence *fence = &leader->base.s_fence->scheduled;
|
||||
|
||||
WARN_ON(job->gang_submit);
|
||||
|
||||
/*
|
||||
* Don't add a reference when we are the gang leader to avoid circle
|
||||
* dependency.
|
||||
*/
|
||||
if (job != leader)
|
||||
dma_fence_get(fence);
|
||||
job->gang_submit = fence;
|
||||
}
|
||||
|
||||
void amdgpu_job_free(struct amdgpu_job *job)
|
||||
{
|
||||
amdgpu_job_free_resources(job);
|
||||
amdgpu_sync_free(&job->sync);
|
||||
amdgpu_sync_free(&job->sched_sync);
|
||||
if (job->gang_submit != &job->base.s_fence->scheduled)
|
||||
dma_fence_put(job->gang_submit);
|
||||
|
||||
if (!job->hw_fence.ops)
|
||||
kfree(job);
|
||||
@@ -227,12 +265,16 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
|
||||
fence = amdgpu_sync_get_fence(&job->sync);
|
||||
}
|
||||
|
||||
if (!fence && job->gang_submit)
|
||||
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
|
||||
|
||||
return fence;
|
||||
}
|
||||
|
||||
static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched);
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct dma_fence *fence = NULL, *finished;
|
||||
struct amdgpu_job *job;
|
||||
int r = 0;
|
||||
@@ -244,8 +286,10 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
||||
|
||||
trace_amdgpu_sched_run_job(job);
|
||||
|
||||
if (job->vram_lost_counter != atomic_read(&ring->adev->vram_lost_counter))
|
||||
dma_fence_set_error(finished, -ECANCELED);/* skip IB as well if VRAM lost */
|
||||
/* Skip job if VRAM is lost and never resubmit gangs */
|
||||
if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter) ||
|
||||
(job->job_run_counter && job->gang_submit))
|
||||
dma_fence_set_error(finished, -ECANCELED);
|
||||
|
||||
if (finished->error < 0) {
|
||||
DRM_INFO("Skip scheduling IBs!\n");
|
||||
|
||||
@@ -50,6 +50,7 @@ struct amdgpu_job {
|
||||
struct amdgpu_sync sync;
|
||||
struct amdgpu_sync sched_sync;
|
||||
struct dma_fence hw_fence;
|
||||
struct dma_fence *gang_submit;
|
||||
uint32_t preamble_status;
|
||||
uint32_t preemption_status;
|
||||
bool vm_needs_flush;
|
||||
@@ -72,11 +73,20 @@ struct amdgpu_job {
|
||||
struct amdgpu_ib ibs[];
|
||||
};
|
||||
|
||||
static inline struct amdgpu_ring *amdgpu_job_ring(struct amdgpu_job *job)
|
||||
{
|
||||
return to_amdgpu_ring(job->base.entity->rq->sched);
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
struct amdgpu_job **job, struct amdgpu_vm *vm);
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
|
||||
void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
|
||||
struct amdgpu_bo *gws, struct amdgpu_bo *oa);
|
||||
void amdgpu_job_free_resources(struct amdgpu_job *job);
|
||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
struct amdgpu_job *leader);
|
||||
void amdgpu_job_free(struct amdgpu_job *job);
|
||||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
void *owner, struct dma_fence **f);
|
||||
|
||||
@@ -247,6 +247,14 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
||||
fw_info->ver = adev->gfx.rlc_srls_fw_version;
|
||||
fw_info->feature = adev->gfx.rlc_srls_feature_version;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_GFX_RLCP:
|
||||
fw_info->ver = adev->gfx.rlcp_ucode_version;
|
||||
fw_info->feature = adev->gfx.rlcp_ucode_feature_version;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_GFX_RLCV:
|
||||
fw_info->ver = adev->gfx.rlcv_ucode_version;
|
||||
fw_info->feature = adev->gfx.rlcv_ucode_feature_version;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_GFX_MEC:
|
||||
if (query_fw->index == 0) {
|
||||
fw_info->ver = adev->gfx.mec_fw_version;
|
||||
@@ -328,6 +336,14 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
||||
fw_info->ver = adev->psp.cap_fw_version;
|
||||
fw_info->feature = adev->psp.cap_feature_version;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_MES_KIQ:
|
||||
fw_info->ver = adev->mes.ucode_fw_version[0];
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_MES:
|
||||
fw_info->ver = adev->mes.ucode_fw_version[1];
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1160,7 +1176,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
}
|
||||
|
||||
mutex_init(&fpriv->bo_list_lock);
|
||||
idr_init(&fpriv->bo_list_handles);
|
||||
idr_init_base(&fpriv->bo_list_handles, 1);
|
||||
|
||||
amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
|
||||
|
||||
@@ -1469,6 +1485,22 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
||||
seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* RLCP */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCP;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "RLCP feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* RLCV */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCV;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "RLCV feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* MEC */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC;
|
||||
query_fw.index = 0;
|
||||
@@ -1581,6 +1613,22 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
||||
fw_info.feature, fw_info.ver);
|
||||
}
|
||||
|
||||
/* MES_KIQ */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_MES_KIQ;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "MES_KIQ feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* MES */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_MES;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "MES feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
@@ -591,7 +591,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
|
||||
if (!bp->destroy)
|
||||
bp->destroy = &amdgpu_bo_destroy;
|
||||
|
||||
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type,
|
||||
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, bp->type,
|
||||
&bo->placement, page_align, &ctx, NULL,
|
||||
bp->resv, bp->destroy);
|
||||
if (unlikely(r != 0))
|
||||
@@ -1309,7 +1309,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
|
||||
if (bo->base.resv == &bo->base._resv)
|
||||
amdgpu_amdkfd_remove_fence_on_pt_pd_bos(abo);
|
||||
|
||||
if (bo->resource->mem_type != TTM_PL_VRAM ||
|
||||
if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
|
||||
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
|
||||
adev->in_suspend || adev->shutdown)
|
||||
return;
|
||||
|
||||
@@ -138,6 +138,7 @@ static int psp_early_init(void *handle)
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
psp_v13_0_set_psp_funcs(psp);
|
||||
psp->autoload_supported = true;
|
||||
break;
|
||||
@@ -327,23 +328,32 @@ static int psp_init_sriov_microcode(struct psp_context *psp)
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(9, 0, 0):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "vega10");
|
||||
break;
|
||||
case IP_VERSION(11, 0, 9):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "navi12");
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "sienna_cichlid");
|
||||
break;
|
||||
case IP_VERSION(13, 0, 2):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "aldebaran");
|
||||
ret &= psp_init_ta_microcode(psp, "aldebaran");
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
adev->virt.autoload_ucode_id = 0;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -501,6 +511,11 @@ static int psp_sw_fini(void *handle)
|
||||
kfree(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
if (psp->km_ring.ring_mem)
|
||||
amdgpu_bo_free_kernel(&adev->firmware.rbuf,
|
||||
&psp->km_ring.ring_mem_mc_addr,
|
||||
(void **)&psp->km_ring.ring_mem);
|
||||
|
||||
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
|
||||
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
|
||||
@@ -769,6 +784,7 @@ static bool psp_skip_tmr(struct psp_context *psp)
|
||||
case IP_VERSION(11, 0, 9):
|
||||
case IP_VERSION(11, 0, 7):
|
||||
case IP_VERSION(13, 0, 2):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -815,7 +831,7 @@ static int psp_tmr_unload(struct psp_context *psp)
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_tmr_unload_cmd_buf(psp, cmd);
|
||||
DRM_INFO("free PSP TMR buffer\n");
|
||||
dev_info(psp->adev->dev, "free PSP TMR buffer\n");
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
@@ -2044,6 +2060,15 @@ static int psp_hw_start(struct psp_context *psp)
|
||||
}
|
||||
}
|
||||
|
||||
if ((is_psp_fw_valid(psp->ras_drv)) &&
|
||||
(psp->funcs->bootloader_load_ras_drv != NULL)) {
|
||||
ret = psp_bootloader_load_ras_drv(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("PSP load ras_drv failed!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((is_psp_fw_valid(psp->sos)) &&
|
||||
(psp->funcs->bootloader_load_sos != NULL)) {
|
||||
ret = psp_bootloader_load_sos(psp);
|
||||
@@ -2414,20 +2439,7 @@ static bool fw_load_skip_check(struct psp_context *psp,
|
||||
return true;
|
||||
|
||||
if (amdgpu_sriov_vf(psp->adev) &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
|
||||
/*skip ucode loading in SRIOV VF */
|
||||
amdgpu_virt_fw_load_skip_check(psp->adev, ucode->ucode_id))
|
||||
return true;
|
||||
|
||||
if (psp->autoload_supported &&
|
||||
@@ -2501,7 +2513,7 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
|
||||
|
||||
/* Start rlc autoload after psp recieved all the gfx firmware */
|
||||
if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
|
||||
AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) {
|
||||
adev->virt.autoload_ucode_id : AMDGPU_UCODE_ID_RLC_G)) {
|
||||
ret = psp_rlc_autoload_start(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to start rlc autoload\n");
|
||||
@@ -3042,6 +3054,12 @@ static int parse_sos_bin_descriptor(struct psp_context *psp,
|
||||
psp->dbg_drv.size_bytes = le32_to_cpu(desc->size_bytes);
|
||||
psp->dbg_drv.start_addr = ucode_start_addr;
|
||||
break;
|
||||
case PSP_FW_TYPE_PSP_RAS_DRV:
|
||||
psp->ras_drv.fw_version = le32_to_cpu(desc->fw_version);
|
||||
psp->ras_drv.feature_version = le32_to_cpu(desc->fw_version);
|
||||
psp->ras_drv.size_bytes = le32_to_cpu(desc->size_bytes);
|
||||
psp->ras_drv.start_addr = ucode_start_addr;
|
||||
break;
|
||||
default:
|
||||
dev_warn(psp->adev->dev, "Unsupported PSP FW type: %d\n", desc->fw_type);
|
||||
break;
|
||||
|
||||
@@ -72,6 +72,7 @@ enum psp_bootloader_cmd {
|
||||
PSP_BL__LOAD_SOCDRV = 0xB0000,
|
||||
PSP_BL__LOAD_DBGDRV = 0xC0000,
|
||||
PSP_BL__LOAD_INTFDRV = 0xD0000,
|
||||
PSP_BL__LOAD_RASDRV = 0xE0000,
|
||||
PSP_BL__DRAM_LONG_TRAIN = 0x100000,
|
||||
PSP_BL__DRAM_SHORT_TRAIN = 0x200000,
|
||||
PSP_BL__LOAD_TOS_SPL_TABLE = 0x10000000,
|
||||
@@ -115,6 +116,7 @@ struct psp_funcs
|
||||
int (*bootloader_load_soc_drv)(struct psp_context *psp);
|
||||
int (*bootloader_load_intf_drv)(struct psp_context *psp);
|
||||
int (*bootloader_load_dbg_drv)(struct psp_context *psp);
|
||||
int (*bootloader_load_ras_drv)(struct psp_context *psp);
|
||||
int (*bootloader_load_sos)(struct psp_context *psp);
|
||||
int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type);
|
||||
int (*ring_create)(struct psp_context *psp,
|
||||
@@ -324,6 +326,7 @@ struct psp_context
|
||||
struct psp_bin_desc soc_drv;
|
||||
struct psp_bin_desc intf_drv;
|
||||
struct psp_bin_desc dbg_drv;
|
||||
struct psp_bin_desc ras_drv;
|
||||
|
||||
/* tmr buffer */
|
||||
struct amdgpu_bo *tmr_bo;
|
||||
@@ -404,6 +407,9 @@ struct amdgpu_psp_funcs {
|
||||
((psp)->funcs->bootloader_load_intf_drv ? (psp)->funcs->bootloader_load_intf_drv((psp)) : 0)
|
||||
#define psp_bootloader_load_dbg_drv(psp) \
|
||||
((psp)->funcs->bootloader_load_dbg_drv ? (psp)->funcs->bootloader_load_dbg_drv((psp)) : 0)
|
||||
#define psp_bootloader_load_ras_drv(psp) \
|
||||
((psp)->funcs->bootloader_load_ras_drv ? \
|
||||
(psp)->funcs->bootloader_load_ras_drv((psp)) : 0)
|
||||
#define psp_bootloader_load_sos(psp) \
|
||||
((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0)
|
||||
#define psp_smu_reload_quirk(psp) \
|
||||
|
||||
@@ -1950,6 +1950,7 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
|
||||
}
|
||||
@@ -2719,7 +2720,8 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
|
||||
|
||||
|
||||
/* Need disable ras on all IPs here before ip [hw/sw]fini */
|
||||
amdgpu_ras_disable_all_features(adev, 0);
|
||||
if (con->features)
|
||||
amdgpu_ras_disable_all_features(adev, 0);
|
||||
amdgpu_ras_recovery_fini(adev);
|
||||
return 0;
|
||||
}
|
||||
@@ -2832,11 +2834,8 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
||||
struct mce *m = (struct mce *)data;
|
||||
struct amdgpu_device *adev = NULL;
|
||||
uint32_t gpu_id = 0;
|
||||
uint32_t umc_inst = 0;
|
||||
uint32_t ch_inst, channel_index = 0;
|
||||
uint32_t umc_inst = 0, ch_inst = 0;
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
struct eeprom_table_record err_rec;
|
||||
uint64_t retired_page;
|
||||
|
||||
/*
|
||||
* If the error was generated in UMC_V2, which belongs to GPU UMCs,
|
||||
@@ -2875,21 +2874,22 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
||||
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
|
||||
umc_inst, ch_inst);
|
||||
|
||||
err_data.err_addr =
|
||||
kcalloc(adev->umc.max_ras_err_cnt_per_query,
|
||||
sizeof(struct eeprom_table_record), GFP_KERNEL);
|
||||
if(!err_data.err_addr) {
|
||||
dev_warn(adev->dev, "Failed to alloc memory for "
|
||||
"umc error address record in mca notifier!\n");
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate UMC channel address to Physical address
|
||||
*/
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num
|
||||
+ ch_inst];
|
||||
|
||||
retired_page = ADDR_OF_8KB_BLOCK(m->addr) |
|
||||
ADDR_OF_256B_BLOCK(channel_index) |
|
||||
OFFSET_IN_256B_BLOCK(m->addr);
|
||||
|
||||
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
|
||||
err_data.err_addr = &err_rec;
|
||||
amdgpu_umc_fill_error_record(&err_data, m->addr,
|
||||
retired_page, channel_index, umc_inst);
|
||||
if (adev->umc.ras &&
|
||||
adev->umc.ras->convert_ras_error_address)
|
||||
adev->umc.ras->convert_ras_error_address(adev,
|
||||
&err_data, 0, ch_inst, umc_inst, m->addr);
|
||||
|
||||
if (amdgpu_bad_page_threshold != 0) {
|
||||
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
|
||||
@@ -2897,6 +2897,7 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
||||
amdgpu_ras_save_bad_pages(adev);
|
||||
}
|
||||
|
||||
kfree(err_data.err_addr);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0
|
||||
#define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0
|
||||
#define EEPROM_I2C_MADDR_ALDEBARAN 0x0
|
||||
#define EEPROM_I2C_MADDR_SMU_13_0_0 (0x54UL << 16)
|
||||
|
||||
/*
|
||||
* The 2 macros bellow represent the actual size in bytes that
|
||||
@@ -156,6 +157,15 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
control->i2c_address = EEPROM_I2C_MADDR_SMU_13_0_0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "amdgpu_reset.h"
|
||||
#include "aldebaran.h"
|
||||
#include "sienna_cichlid.h"
|
||||
|
||||
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_handler *handler)
|
||||
@@ -36,10 +37,15 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
adev->amdgpu_reset_level_mask = 0x1;
|
||||
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 2):
|
||||
ret = aldebaran_reset_init(adev);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
ret = sienna_cichlid_reset_init(adev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -55,6 +61,9 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 2):
|
||||
ret = aldebaran_reset_fini(adev);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
ret = sienna_cichlid_reset_fini(adev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -67,6 +76,12 @@ int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev,
|
||||
{
|
||||
struct amdgpu_reset_handler *reset_handler = NULL;
|
||||
|
||||
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
|
||||
return -ENOSYS;
|
||||
|
||||
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
|
||||
return -ENOSYS;
|
||||
|
||||
if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
|
||||
reset_handler = adev->reset_cntl->get_reset_handler(
|
||||
adev->reset_cntl, reset_context);
|
||||
@@ -83,6 +98,12 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
|
||||
int ret;
|
||||
struct amdgpu_reset_handler *reset_handler = NULL;
|
||||
|
||||
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
|
||||
return -ENOSYS;
|
||||
|
||||
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
|
||||
return -ENOSYS;
|
||||
|
||||
if (adev->reset_cntl)
|
||||
reset_handler = adev->reset_cntl->get_reset_handler(
|
||||
adev->reset_cntl, reset_context);
|
||||
|
||||
@@ -30,6 +30,8 @@ enum AMDGPU_RESET_FLAGS {
|
||||
|
||||
AMDGPU_NEED_FULL_RESET = 0,
|
||||
AMDGPU_SKIP_HW_RESET = 1,
|
||||
AMDGPU_SKIP_MODE2_RESET = 2,
|
||||
AMDGPU_RESET_FOR_DEVICE_REMOVE = 3,
|
||||
};
|
||||
|
||||
struct amdgpu_reset_context {
|
||||
@@ -111,7 +113,8 @@ static inline bool amdgpu_reset_get_reset_domain(struct amdgpu_reset_domain *dom
|
||||
|
||||
static inline void amdgpu_reset_put_reset_domain(struct amdgpu_reset_domain *domain)
|
||||
{
|
||||
kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain);
|
||||
if (domain)
|
||||
kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain);
|
||||
}
|
||||
|
||||
static inline bool amdgpu_reset_domain_schedule(struct amdgpu_reset_domain *domain,
|
||||
|
||||
@@ -405,6 +405,9 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
|
||||
{
|
||||
ktime_t deadline = ktime_add_us(ktime_get(), 10000);
|
||||
|
||||
if (!(ring->adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_SOFT_RECOVERY))
|
||||
return false;
|
||||
|
||||
if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -359,6 +359,14 @@ static void amdgpu_gfx_rlc_init_microcode_v2_1(struct amdgpu_device *adev)
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
if (adev->gfx.rlc.save_restore_list_cntl_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.save_restore_list_gpm_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_sdma.h"
|
||||
#include "amdgpu_ras.h"
|
||||
@@ -150,3 +151,135 @@ int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
|
||||
amdgpu_ras_interrupt_dispatch(adev, &ih_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_sdma_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst)
|
||||
{
|
||||
int err = 0;
|
||||
uint16_t version_major;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
const struct sdma_firmware_header_v2_0 *hdr_v2;
|
||||
|
||||
err = amdgpu_ucode_validate(sdma_inst->fw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
header = (const struct common_firmware_header *)
|
||||
sdma_inst->fw->data;
|
||||
version_major = le16_to_cpu(header->header_version_major);
|
||||
|
||||
switch (version_major) {
|
||||
case 1:
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)sdma_inst->fw->data;
|
||||
sdma_inst->fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
sdma_inst->feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
break;
|
||||
case 2:
|
||||
hdr_v2 = (const struct sdma_firmware_header_v2_0 *)sdma_inst->fw->data;
|
||||
sdma_inst->fw_version = le32_to_cpu(hdr_v2->header.ucode_version);
|
||||
sdma_inst->feature_version = le32_to_cpu(hdr_v2->ucode_feature_version);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sdma_inst->feature_version >= 20)
|
||||
sdma_inst->burst_nop = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
|
||||
bool duplicate)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
release_firmware(adev->sdma.instance[i].fw);
|
||||
if (duplicate)
|
||||
break;
|
||||
}
|
||||
|
||||
memset((void *)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
|
||||
char *fw_name, u32 instance,
|
||||
bool duplicate)
|
||||
{
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
int err = 0, i;
|
||||
const struct sdma_firmware_header_v2_0 *sdma_hdr;
|
||||
uint16_t version_major;
|
||||
|
||||
err = request_firmware(&adev->sdma.instance[instance].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
header = (const struct common_firmware_header *)
|
||||
adev->sdma.instance[instance].fw->data;
|
||||
version_major = le16_to_cpu(header->header_version_major);
|
||||
|
||||
if ((duplicate && instance) || (!duplicate && version_major > 1))
|
||||
return -EINVAL;
|
||||
|
||||
err = amdgpu_sdma_init_inst_ctx(&adev->sdma.instance[instance]);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (duplicate) {
|
||||
for (i = 1; i < adev->sdma.num_instances; i++)
|
||||
memcpy((void *)&adev->sdma.instance[i],
|
||||
(void *)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG("psp_load == '%s'\n",
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
switch (version_major) {
|
||||
case 1:
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (!duplicate && (instance != i))
|
||||
continue;
|
||||
else {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
sdma_hdr = (const struct sdma_firmware_header_v2_0 *)
|
||||
adev->sdma.instance[0].fw->data;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH0];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH0;
|
||||
info->fw = adev->sdma.instance[0].fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH1;
|
||||
info->fw = adev->sdma.instance[0].fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes), PAGE_SIZE);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
DRM_ERROR("SDMA: Failed to init firmware \"%s\"\n", fw_name);
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, duplicate);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -124,4 +124,8 @@ int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
|
||||
char *fw_name, u32 instance, bool duplicate);
|
||||
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
|
||||
bool duplicate);
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2014 Advanced Micro Devices, Inc.
|
||||
* All Rights Reserved.
|
||||
@@ -315,6 +316,7 @@ struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync)
|
||||
struct hlist_node *tmp;
|
||||
struct dma_fence *f;
|
||||
int i;
|
||||
|
||||
hash_for_each_safe(sync->fences, i, tmp, e, node) {
|
||||
|
||||
f = e->fence;
|
||||
@@ -392,7 +394,7 @@ void amdgpu_sync_free(struct amdgpu_sync *sync)
|
||||
{
|
||||
struct amdgpu_sync_entry *e;
|
||||
struct hlist_node *tmp;
|
||||
unsigned i;
|
||||
unsigned int i;
|
||||
|
||||
hash_for_each_safe(sync->fences, i, tmp, e, node) {
|
||||
hash_del(&e->node);
|
||||
|
||||
@@ -140,8 +140,10 @@ TRACE_EVENT(amdgpu_bo_create,
|
||||
);
|
||||
|
||||
TRACE_EVENT(amdgpu_cs,
|
||||
TP_PROTO(struct amdgpu_cs_parser *p, int i),
|
||||
TP_ARGS(p, i),
|
||||
TP_PROTO(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib),
|
||||
TP_ARGS(p, job, ib),
|
||||
TP_STRUCT__entry(
|
||||
__field(struct amdgpu_bo_list *, bo_list)
|
||||
__field(u32, ring)
|
||||
@@ -151,10 +153,10 @@ TRACE_EVENT(amdgpu_cs,
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->bo_list = p->bo_list;
|
||||
__entry->ring = to_amdgpu_ring(p->entity->rq->sched)->idx;
|
||||
__entry->dw = p->job->ibs[i].length_dw;
|
||||
__entry->ring = to_amdgpu_ring(job->base.sched)->idx;
|
||||
__entry->dw = ib->length_dw;
|
||||
__entry->fences = amdgpu_fence_count_emitted(
|
||||
to_amdgpu_ring(p->entity->rq->sched));
|
||||
to_amdgpu_ring(job->base.sched));
|
||||
),
|
||||
TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u",
|
||||
__entry->bo_list, __entry->ring, __entry->dw,
|
||||
|
||||
@@ -471,7 +471,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
|
||||
adev = amdgpu_ttm_adev(bo->bdev);
|
||||
|
||||
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
|
||||
if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
bo->ttm == NULL)) {
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
}
|
||||
@@ -1329,11 +1330,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
|
||||
static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
|
||||
const struct ttm_place *place)
|
||||
{
|
||||
unsigned long num_pages = bo->resource->num_pages;
|
||||
struct dma_resv_iter resv_cursor;
|
||||
struct amdgpu_res_cursor cursor;
|
||||
struct dma_fence *f;
|
||||
|
||||
if (!amdgpu_bo_is_amdgpu_bo(bo))
|
||||
return ttm_bo_eviction_valuable(bo, place);
|
||||
|
||||
/* Swapout? */
|
||||
if (bo->resource->mem_type == TTM_PL_SYSTEM)
|
||||
return true;
|
||||
@@ -1352,39 +1354,19 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (bo->resource->mem_type) {
|
||||
case AMDGPU_PL_PREEMPT:
|
||||
/* Preemptible BOs don't own system resources managed by the
|
||||
* driver (pages, VRAM, GART space). They point to resources
|
||||
* owned by someone else (e.g. pageable memory in user mode
|
||||
* or a DMABuf). They are used in a preemptible context so we
|
||||
* can guarantee no deadlocks and good QoS in case of MMU
|
||||
* notifiers or DMABuf move notifiers from the resource owner.
|
||||
*/
|
||||
return false;
|
||||
case TTM_PL_TT:
|
||||
if (amdgpu_bo_is_amdgpu_bo(bo) &&
|
||||
amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
case TTM_PL_VRAM:
|
||||
/* Check each drm MM node individually */
|
||||
amdgpu_res_first(bo->resource, 0, (u64)num_pages << PAGE_SHIFT,
|
||||
&cursor);
|
||||
while (cursor.remaining) {
|
||||
if (place->fpfn < PFN_DOWN(cursor.start + cursor.size)
|
||||
&& !(place->lpfn &&
|
||||
place->lpfn <= PFN_DOWN(cursor.start)))
|
||||
return true;
|
||||
|
||||
amdgpu_res_next(&cursor, cursor.size);
|
||||
}
|
||||
/* Preemptible BOs don't own system resources managed by the
|
||||
* driver (pages, VRAM, GART space). They point to resources
|
||||
* owned by someone else (e.g. pageable memory in user mode
|
||||
* or a DMABuf). They are used in a preemptible context so we
|
||||
* can guarantee no deadlocks and good QoS in case of MMU
|
||||
* notifiers or DMABuf move notifiers from the resource owner.
|
||||
*/
|
||||
if (bo->resource->mem_type == AMDGPU_PL_PREEMPT)
|
||||
return false;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (bo->resource->mem_type == TTM_PL_TT &&
|
||||
amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
|
||||
return false;
|
||||
|
||||
return ttm_bo_eviction_valuable(bo, place);
|
||||
}
|
||||
|
||||
@@ -164,70 +164,138 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
|
||||
} else if (version_major == 2) {
|
||||
const struct rlc_firmware_header_v2_0 *rlc_hdr =
|
||||
container_of(hdr, struct rlc_firmware_header_v2_0, header);
|
||||
const struct rlc_firmware_header_v2_1 *rlc_hdr_v2_1 =
|
||||
container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0);
|
||||
const struct rlc_firmware_header_v2_2 *rlc_hdr_v2_2 =
|
||||
container_of(rlc_hdr_v2_1, struct rlc_firmware_header_v2_2, v2_1);
|
||||
const struct rlc_firmware_header_v2_3 *rlc_hdr_v2_3 =
|
||||
container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_3, v2_2);
|
||||
const struct rlc_firmware_header_v2_4 *rlc_hdr_v2_4 =
|
||||
container_of(rlc_hdr_v2_3, struct rlc_firmware_header_v2_4, v2_3);
|
||||
|
||||
DRM_DEBUG("ucode_feature_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr->ucode_feature_version));
|
||||
DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(rlc_hdr->jt_offset));
|
||||
DRM_DEBUG("jt_size: %u\n", le32_to_cpu(rlc_hdr->jt_size));
|
||||
DRM_DEBUG("save_and_restore_offset: %u\n",
|
||||
le32_to_cpu(rlc_hdr->save_and_restore_offset));
|
||||
DRM_DEBUG("clear_state_descriptor_offset: %u\n",
|
||||
le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
|
||||
DRM_DEBUG("avail_scratch_ram_locations: %u\n",
|
||||
le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
|
||||
DRM_DEBUG("reg_restore_list_size: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_restore_list_size));
|
||||
DRM_DEBUG("reg_list_format_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_start));
|
||||
DRM_DEBUG("reg_list_format_separate_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_start));
|
||||
DRM_DEBUG("starting_offsets_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->starting_offsets_start));
|
||||
DRM_DEBUG("reg_list_format_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_size_bytes));
|
||||
DRM_DEBUG("reg_list_format_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_size_bytes));
|
||||
DRM_DEBUG("reg_list_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_format_separate_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_size_bytes));
|
||||
DRM_DEBUG("reg_list_format_separate_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_separate_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes));
|
||||
DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes));
|
||||
if (version_minor == 1) {
|
||||
const struct rlc_firmware_header_v2_1 *v2_1 =
|
||||
container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0);
|
||||
switch (version_minor) {
|
||||
case 0:
|
||||
/* rlc_hdr v2_0 */
|
||||
DRM_DEBUG("ucode_feature_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr->ucode_feature_version));
|
||||
DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(rlc_hdr->jt_offset));
|
||||
DRM_DEBUG("jt_size: %u\n", le32_to_cpu(rlc_hdr->jt_size));
|
||||
DRM_DEBUG("save_and_restore_offset: %u\n",
|
||||
le32_to_cpu(rlc_hdr->save_and_restore_offset));
|
||||
DRM_DEBUG("clear_state_descriptor_offset: %u\n",
|
||||
le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
|
||||
DRM_DEBUG("avail_scratch_ram_locations: %u\n",
|
||||
le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
|
||||
DRM_DEBUG("reg_restore_list_size: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_restore_list_size));
|
||||
DRM_DEBUG("reg_list_format_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_start));
|
||||
DRM_DEBUG("reg_list_format_separate_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_start));
|
||||
DRM_DEBUG("starting_offsets_start: %u\n",
|
||||
le32_to_cpu(rlc_hdr->starting_offsets_start));
|
||||
DRM_DEBUG("reg_list_format_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_size_bytes));
|
||||
DRM_DEBUG("reg_list_format_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_size_bytes));
|
||||
DRM_DEBUG("reg_list_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_format_separate_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_size_bytes));
|
||||
DRM_DEBUG("reg_list_format_separate_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes));
|
||||
DRM_DEBUG("reg_list_separate_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes));
|
||||
DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes));
|
||||
break;
|
||||
case 1:
|
||||
/* rlc_hdr v2_1 */
|
||||
DRM_DEBUG("reg_list_format_direct_reg_list_length: %u\n",
|
||||
le32_to_cpu(v2_1->reg_list_format_direct_reg_list_length));
|
||||
le32_to_cpu(rlc_hdr_v2_1->reg_list_format_direct_reg_list_length));
|
||||
DRM_DEBUG("save_restore_list_cntl_ucode_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_cntl_ucode_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_ucode_ver));
|
||||
DRM_DEBUG("save_restore_list_cntl_feature_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_cntl_feature_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_feature_ver));
|
||||
DRM_DEBUG("save_restore_list_cntl_size_bytes %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_cntl_size_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_size_bytes));
|
||||
DRM_DEBUG("save_restore_list_cntl_offset_bytes: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_cntl_offset_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_offset_bytes));
|
||||
DRM_DEBUG("save_restore_list_gpm_ucode_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_gpm_ucode_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_ucode_ver));
|
||||
DRM_DEBUG("save_restore_list_gpm_feature_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_gpm_feature_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_feature_ver));
|
||||
DRM_DEBUG("save_restore_list_gpm_size_bytes %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_gpm_size_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_size_bytes));
|
||||
DRM_DEBUG("save_restore_list_gpm_offset_bytes: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_gpm_offset_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_offset_bytes));
|
||||
DRM_DEBUG("save_restore_list_srm_ucode_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_srm_ucode_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_ucode_ver));
|
||||
DRM_DEBUG("save_restore_list_srm_feature_ver: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_srm_feature_ver));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_feature_ver));
|
||||
DRM_DEBUG("save_restore_list_srm_size_bytes %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_srm_size_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_size_bytes));
|
||||
DRM_DEBUG("save_restore_list_srm_offset_bytes: %u\n",
|
||||
le32_to_cpu(v2_1->save_restore_list_srm_offset_bytes));
|
||||
le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_offset_bytes));
|
||||
break;
|
||||
case 2:
|
||||
/* rlc_hdr v2_2 */
|
||||
DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_size_bytes));
|
||||
DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_offset_bytes));
|
||||
DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_size_bytes));
|
||||
DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_offset_bytes));
|
||||
break;
|
||||
case 3:
|
||||
/* rlc_hdr v2_3 */
|
||||
DRM_DEBUG("rlcp_ucode_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_version));
|
||||
DRM_DEBUG("rlcp_ucode_feature_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_feature_version));
|
||||
DRM_DEBUG("rlcp_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_size_bytes));
|
||||
DRM_DEBUG("rlcp_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_offset_bytes));
|
||||
DRM_DEBUG("rlcv_ucode_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_version));
|
||||
DRM_DEBUG("rlcv_ucode_feature_version: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_feature_version));
|
||||
DRM_DEBUG("rlcv_ucode_size_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_size_bytes));
|
||||
DRM_DEBUG("rlcv_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_offset_bytes));
|
||||
break;
|
||||
case 4:
|
||||
/* rlc_hdr v2_4 */
|
||||
DRM_DEBUG("global_tap_delays_ucode_size_bytes :%u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_size_bytes));
|
||||
DRM_DEBUG("global_tap_delays_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_offset_bytes));
|
||||
DRM_DEBUG("se0_tap_delays_ucode_size_bytes :%u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_size_bytes));
|
||||
DRM_DEBUG("se0_tap_delays_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_offset_bytes));
|
||||
DRM_DEBUG("se1_tap_delays_ucode_size_bytes :%u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_size_bytes));
|
||||
DRM_DEBUG("se1_tap_delays_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_offset_bytes));
|
||||
DRM_DEBUG("se2_tap_delays_ucode_size_bytes :%u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_size_bytes));
|
||||
DRM_DEBUG("se2_tap_delays_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_offset_bytes));
|
||||
DRM_DEBUG("se3_tap_delays_ucode_size_bytes :%u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_size_bytes));
|
||||
DRM_DEBUG("se3_tap_delays_ucode_offset_bytes: %u\n",
|
||||
le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_offset_bytes));
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown RLC v2 ucode: v2.%u\n", version_minor);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);
|
||||
|
||||
@@ -124,6 +124,7 @@ enum psp_fw_type {
|
||||
PSP_FW_TYPE_PSP_SOC_DRV,
|
||||
PSP_FW_TYPE_PSP_INTF_DRV,
|
||||
PSP_FW_TYPE_PSP_DBG_DRV,
|
||||
PSP_FW_TYPE_PSP_RAS_DRV,
|
||||
};
|
||||
|
||||
/* version_major=2, version_minor=0 */
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#define __AMDGPU_UMC_H__
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
#define UMC_INVALID_ADDR 0x1ULL
|
||||
|
||||
/*
|
||||
* (addr / 256) * 4096, the higher 26 bits in ErrorAddr
|
||||
* is the index of 4KB block
|
||||
@@ -51,6 +53,10 @@ struct amdgpu_umc_ras {
|
||||
struct amdgpu_ras_block_object ras_block;
|
||||
void (*err_cnt_init)(struct amdgpu_device *adev);
|
||||
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
|
||||
void (*convert_ras_error_address)(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t umc_reg_offset, uint32_t ch_inst,
|
||||
uint32_t umc_inst, uint64_t mca_addr);
|
||||
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev,
|
||||
|
||||
@@ -161,6 +161,8 @@
|
||||
#define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
|
||||
#define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10)
|
||||
#define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
|
||||
#define AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG (1 << 11)
|
||||
#define AMDGPU_VCN_VF_RB_SETUP_FLAG (1 << 14)
|
||||
|
||||
#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001
|
||||
#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001
|
||||
@@ -170,6 +172,9 @@
|
||||
#define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2)
|
||||
#define VCN_CODEC_DISABLE_MASK_H264 (1 << 3)
|
||||
|
||||
#define AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU (0)
|
||||
#define AMDGPU_VCN_SMU_DPM_INTERFACE_APU (1)
|
||||
|
||||
enum fw_queue_mode {
|
||||
FW_QUEUE_RING_RESET = 1,
|
||||
FW_QUEUE_DPG_HOLD_OFF = 2,
|
||||
@@ -317,12 +322,26 @@ struct amdgpu_fw_shared {
|
||||
struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
|
||||
};
|
||||
|
||||
struct amdgpu_fw_shared_rb_setup {
|
||||
uint32_t is_rb_enabled_flags;
|
||||
uint32_t rb_addr_lo;
|
||||
uint32_t rb_addr_hi;
|
||||
uint32_t rb_size;
|
||||
uint32_t rb4_addr_lo;
|
||||
uint32_t rb4_addr_hi;
|
||||
uint32_t rb4_size;
|
||||
uint32_t reserved[6];
|
||||
};
|
||||
|
||||
struct amdgpu_vcn4_fw_shared {
|
||||
uint32_t present_flag_0;
|
||||
uint8_t pad[12];
|
||||
struct amdgpu_fw_shared_unified_queue_struct sq;
|
||||
uint8_t pad1[8];
|
||||
struct amdgpu_fw_shared_fw_logging fw_log;
|
||||
uint8_t pad2[20];
|
||||
struct amdgpu_fw_shared_rb_setup rb_setup;
|
||||
struct amdgpu_fw_shared_smu_interface_info smu_dpm_interface;
|
||||
};
|
||||
|
||||
struct amdgpu_vcn_fwlog {
|
||||
|
||||
@@ -690,7 +690,6 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void amdgpu_detect_virtualization(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
@@ -707,6 +706,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_ALDEBARAN:
|
||||
case CHIP_IP_DISCOVERY:
|
||||
reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
|
||||
break;
|
||||
default: /* other chip doesn't support SRIOV */
|
||||
@@ -750,6 +750,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_IP_DISCOVERY:
|
||||
nv_set_virt_ops(adev);
|
||||
/* try send GPU_INIT_DATA request to host */
|
||||
amdgpu_virt_request_init_data(adev);
|
||||
@@ -807,6 +808,60 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev, uint32_t ucode_id)
|
||||
{
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
/* no vf autoload, white list */
|
||||
if (ucode_id == AMDGPU_UCODE_ID_VCN1 ||
|
||||
ucode_id == AMDGPU_UCODE_ID_VCN)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
/* white list */
|
||||
if (ucode_id == AMDGPU_UCODE_ID_CAP
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_MES
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1
|
||||
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1_DATA
|
||||
|| ucode_id == AMDGPU_UCODE_ID_VCN1
|
||||
|| ucode_id == AMDGPU_UCODE_ID_VCN)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
default:
|
||||
/* lagacy black list */
|
||||
if (ucode_id == AMDGPU_UCODE_ID_SDMA0
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA1
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA2
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA3
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA4
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA5
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA6
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SDMA7
|
||||
|| ucode_id == AMDGPU_UCODE_ID_RLC_G
|
||||
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|
||||
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|
||||
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|
||||
|| ucode_id == AMDGPU_UCODE_ID_SMC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
|
||||
struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
|
||||
struct amdgpu_video_codec_info *decode, uint32_t decode_array_size)
|
||||
|
||||
@@ -253,6 +253,9 @@ struct amdgpu_virt {
|
||||
uint32_t decode_max_frame_pixels;
|
||||
uint32_t encode_max_dimension_pixels;
|
||||
uint32_t encode_max_frame_pixels;
|
||||
|
||||
/* the ucode id to signal the autoload */
|
||||
uint32_t autoload_ucode_id;
|
||||
};
|
||||
|
||||
struct amdgpu_video_codec_info;
|
||||
@@ -343,4 +346,6 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
|
||||
u32 acc_flags, u32 hwip);
|
||||
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
u32 offset, u32 acc_flags, u32 hwip);
|
||||
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
|
||||
uint32_t ucode_id);
|
||||
#endif
|
||||
|
||||
@@ -282,8 +282,8 @@ static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
|
||||
return PTR_ERR(crtc_state);
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
false, true);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -183,10 +183,12 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
|
||||
struct amdgpu_bo *bo = vm_bo->bo;
|
||||
|
||||
vm_bo->moved = true;
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
if (bo->tbo.type == ttm_bo_type_kernel)
|
||||
list_move(&vm_bo->vm_status, &vm->evicted);
|
||||
else
|
||||
list_move_tail(&vm_bo->vm_status, &vm->evicted);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
/**
|
||||
* amdgpu_vm_bo_moved - vm_bo is moved
|
||||
@@ -198,7 +200,9 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,7 +215,9 @@ static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->idle);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
vm_bo->moved = false;
|
||||
}
|
||||
|
||||
@@ -225,9 +231,9 @@ static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->invalidated_lock);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated);
|
||||
spin_unlock(&vm_bo->vm->invalidated_lock);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,10 +246,13 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
if (vm_bo->bo->parent)
|
||||
if (vm_bo->bo->parent) {
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
|
||||
else
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
} else {
|
||||
amdgpu_vm_bo_idle(vm_bo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,9 +265,9 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
|
||||
*/
|
||||
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->invalidated_lock);
|
||||
spin_lock(&vm_bo->vm->status_lock);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->done);
|
||||
spin_unlock(&vm_bo->vm->invalidated_lock);
|
||||
spin_unlock(&vm_bo->vm->status_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,12 +372,20 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int (*validate)(void *p, struct amdgpu_bo *bo),
|
||||
void *param)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *bo_base, *tmp;
|
||||
struct amdgpu_vm_bo_base *bo_base;
|
||||
struct amdgpu_bo *shadow;
|
||||
struct amdgpu_bo *bo;
|
||||
int r;
|
||||
|
||||
list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {
|
||||
struct amdgpu_bo *bo = bo_base->bo;
|
||||
struct amdgpu_bo *shadow = amdgpu_bo_shadowed(bo);
|
||||
spin_lock(&vm->status_lock);
|
||||
while (!list_empty(&vm->evicted)) {
|
||||
bo_base = list_first_entry(&vm->evicted,
|
||||
struct amdgpu_vm_bo_base,
|
||||
vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
bo = bo_base->bo;
|
||||
shadow = amdgpu_bo_shadowed(bo);
|
||||
|
||||
r = validate(param, bo);
|
||||
if (r)
|
||||
@@ -385,7 +402,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
|
||||
amdgpu_vm_bo_relocated(bo_base);
|
||||
}
|
||||
spin_lock(&vm->status_lock);
|
||||
}
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
vm->evicting = false;
|
||||
@@ -406,13 +425,18 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
*/
|
||||
bool amdgpu_vm_ready(struct amdgpu_vm *vm)
|
||||
{
|
||||
bool empty;
|
||||
bool ret;
|
||||
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
ret = !vm->evicting;
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
|
||||
return ret && list_empty(&vm->evicted);
|
||||
spin_lock(&vm->status_lock);
|
||||
empty = list_empty(&vm->evicted);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
return ret && empty;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,9 +704,14 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm_update_params params;
|
||||
struct amdgpu_vm_bo_base *entry;
|
||||
bool flush_tlb_needed = false;
|
||||
LIST_HEAD(relocated);
|
||||
int r, idx;
|
||||
|
||||
if (list_empty(&vm->relocated))
|
||||
spin_lock(&vm->status_lock);
|
||||
list_splice_init(&vm->relocated, &relocated);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
if (list_empty(&relocated))
|
||||
return 0;
|
||||
|
||||
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||
@@ -697,7 +726,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
list_for_each_entry(entry, &vm->relocated, vm_status) {
|
||||
list_for_each_entry(entry, &relocated, vm_status) {
|
||||
/* vm_flush_needed after updating moved PDEs */
|
||||
flush_tlb_needed |= entry->moved;
|
||||
|
||||
@@ -713,9 +742,8 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
if (flush_tlb_needed)
|
||||
atomic64_inc(&vm->tlb_seq);
|
||||
|
||||
while (!list_empty(&vm->relocated)) {
|
||||
entry = list_first_entry(&vm->relocated,
|
||||
struct amdgpu_vm_bo_base,
|
||||
while (!list_empty(&relocated)) {
|
||||
entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base,
|
||||
vm_status);
|
||||
amdgpu_vm_bo_idle(entry);
|
||||
}
|
||||
@@ -912,6 +940,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va, *tmp;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
@@ -936,7 +965,6 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
}
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
@@ -949,7 +977,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
||||
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
|
||||
gtt_mem, cpu_mem);
|
||||
}
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
spin_unlock(&vm->status_lock);
|
||||
}
|
||||
/**
|
||||
* amdgpu_vm_bo_update - update all BO mappings in the vm page table
|
||||
@@ -1278,24 +1306,29 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
||||
int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm)
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va, *tmp;
|
||||
struct amdgpu_bo_va *bo_va;
|
||||
struct dma_resv *resv;
|
||||
bool clear;
|
||||
int r;
|
||||
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
|
||||
spin_lock(&vm->status_lock);
|
||||
while (!list_empty(&vm->moved)) {
|
||||
bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
/* Per VM BOs never need to bo cleared in the page tables */
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
if (r)
|
||||
return r;
|
||||
spin_lock(&vm->status_lock);
|
||||
}
|
||||
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
while (!list_empty(&vm->invalidated)) {
|
||||
bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
resv = bo_va->base.bo->tbo.base.resv;
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
/* Try to reserve the BO to avoid clearing its ptes */
|
||||
if (!amdgpu_vm_debug && dma_resv_trylock(resv))
|
||||
@@ -1310,9 +1343,9 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
||||
|
||||
if (!clear)
|
||||
dma_resv_unlock(resv);
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
spin_lock(&vm->status_lock);
|
||||
}
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1387,7 +1420,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
|
||||
|
||||
if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv &&
|
||||
!bo_va->base.moved) {
|
||||
list_move(&bo_va->base.vm_status, &vm->moved);
|
||||
amdgpu_vm_bo_moved(&bo_va->base);
|
||||
}
|
||||
trace_amdgpu_vm_bo_map(bo_va, mapping);
|
||||
}
|
||||
@@ -1763,9 +1796,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
spin_lock(&vm->status_lock);
|
||||
list_del(&bo_va->base.vm_status);
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
|
||||
list_del(&mapping->list);
|
||||
@@ -2019,9 +2052,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||
INIT_LIST_HEAD(&vm->moved);
|
||||
INIT_LIST_HEAD(&vm->idle);
|
||||
INIT_LIST_HEAD(&vm->invalidated);
|
||||
spin_lock_init(&vm->invalidated_lock);
|
||||
spin_lock_init(&vm->status_lock);
|
||||
INIT_LIST_HEAD(&vm->freed);
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
INIT_LIST_HEAD(&vm->pt_freed);
|
||||
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
|
||||
|
||||
/* create scheduler entities for page table updates */
|
||||
r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
|
||||
@@ -2223,6 +2258,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||
|
||||
amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
|
||||
|
||||
flush_work(&vm->pt_free_work);
|
||||
|
||||
root = amdgpu_bo_ref(vm->root.bo);
|
||||
amdgpu_bo_reserve(root, true);
|
||||
amdgpu_vm_set_pasid(adev, vm, 0);
|
||||
@@ -2547,6 +2584,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
unsigned int total_done_objs = 0;
|
||||
unsigned int id = 0;
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
seq_puts(m, "\tIdle BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
@@ -2584,7 +2622,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tInvalidated BOs:\n");
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
@@ -2599,7 +2636,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
continue;
|
||||
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
spin_unlock(&vm->status_lock);
|
||||
total_done_objs = id;
|
||||
|
||||
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,
|
||||
|
||||
@@ -254,6 +254,9 @@ struct amdgpu_vm {
|
||||
bool evicting;
|
||||
unsigned int saved_flags;
|
||||
|
||||
/* Lock to protect vm_bo add/del/move on all lists of vm */
|
||||
spinlock_t status_lock;
|
||||
|
||||
/* BOs who needs a validation */
|
||||
struct list_head evicted;
|
||||
|
||||
@@ -268,7 +271,6 @@ struct amdgpu_vm {
|
||||
|
||||
/* regular invalidated BOs, but not yet updated in the PT */
|
||||
struct list_head invalidated;
|
||||
spinlock_t invalidated_lock;
|
||||
|
||||
/* BO mappings freed, but not yet updated in the PT */
|
||||
struct list_head freed;
|
||||
@@ -276,6 +278,10 @@ struct amdgpu_vm {
|
||||
/* BOs which are invalidated, has been updated in the PTs */
|
||||
struct list_head done;
|
||||
|
||||
/* PT BOs scheduled to free and fill with zero if vm_resv is not hold */
|
||||
struct list_head pt_freed;
|
||||
struct work_struct pt_free_work;
|
||||
|
||||
/* contains the page directory */
|
||||
struct amdgpu_vm_bo_base root;
|
||||
struct dma_fence *last_update;
|
||||
@@ -471,6 +477,7 @@ int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params,
|
||||
int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
|
||||
uint64_t start, uint64_t end,
|
||||
uint64_t dst, uint64_t flags);
|
||||
void amdgpu_vm_pt_free_work(struct work_struct *work);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
|
||||
|
||||
@@ -637,10 +637,34 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
|
||||
}
|
||||
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
|
||||
entry->bo->vm_bo = NULL;
|
||||
|
||||
spin_lock(&entry->vm->status_lock);
|
||||
list_del(&entry->vm_status);
|
||||
spin_unlock(&entry->vm->status_lock);
|
||||
amdgpu_bo_unref(&entry->bo);
|
||||
}
|
||||
|
||||
void amdgpu_vm_pt_free_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *entry, *next;
|
||||
struct amdgpu_vm *vm;
|
||||
LIST_HEAD(pt_freed);
|
||||
|
||||
vm = container_of(work, struct amdgpu_vm, pt_free_work);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
list_splice_init(&vm->pt_freed, &pt_freed);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
/* flush_work in amdgpu_vm_fini ensure vm->root.bo is valid. */
|
||||
amdgpu_bo_reserve(vm->root.bo, true);
|
||||
|
||||
list_for_each_entry_safe(entry, next, &pt_freed, vm_status)
|
||||
amdgpu_vm_pt_free(entry);
|
||||
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_pt_free_dfs - free PD/PT levels
|
||||
*
|
||||
@@ -652,11 +676,24 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
|
||||
*/
|
||||
static void amdgpu_vm_pt_free_dfs(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
struct amdgpu_vm_pt_cursor *start)
|
||||
struct amdgpu_vm_pt_cursor *start,
|
||||
bool unlocked)
|
||||
{
|
||||
struct amdgpu_vm_pt_cursor cursor;
|
||||
struct amdgpu_vm_bo_base *entry;
|
||||
|
||||
if (unlocked) {
|
||||
spin_lock(&vm->status_lock);
|
||||
for_each_amdgpu_vm_pt_dfs_safe(adev, vm, start, cursor, entry)
|
||||
list_move(&entry->vm_status, &vm->pt_freed);
|
||||
|
||||
if (start)
|
||||
list_move(&start->entry->vm_status, &vm->pt_freed);
|
||||
spin_unlock(&vm->status_lock);
|
||||
schedule_work(&vm->pt_free_work);
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_amdgpu_vm_pt_dfs_safe(adev, vm, start, cursor, entry)
|
||||
amdgpu_vm_pt_free(entry);
|
||||
|
||||
@@ -673,7 +710,7 @@ static void amdgpu_vm_pt_free_dfs(struct amdgpu_device *adev,
|
||||
*/
|
||||
void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||
{
|
||||
amdgpu_vm_pt_free_dfs(adev, vm, NULL);
|
||||
amdgpu_vm_pt_free_dfs(adev, vm, NULL, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -966,7 +1003,8 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
|
||||
if (cursor.entry->bo) {
|
||||
params->table_freed = true;
|
||||
amdgpu_vm_pt_free_dfs(adev, params->vm,
|
||||
&cursor);
|
||||
&cursor,
|
||||
params->unlocked);
|
||||
}
|
||||
amdgpu_vm_pt_next(adev, &cursor);
|
||||
}
|
||||
|
||||
@@ -112,7 +112,8 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
|
||||
swap(p->vm->last_unlocked, tmp);
|
||||
dma_fence_put(tmp);
|
||||
} else {
|
||||
amdgpu_bo_fence(p->vm->root.bo, f, true);
|
||||
dma_resv_add_fence(p->vm->root.bo->tbo.base.resv, f,
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
}
|
||||
|
||||
if (fence && !p->immediate)
|
||||
@@ -211,12 +212,15 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
|
||||
int r;
|
||||
|
||||
/* Wait for PD/PT moves to be completed */
|
||||
dma_resv_for_each_fence(&cursor, bo->tbo.base.resv,
|
||||
DMA_RESV_USAGE_KERNEL, fence) {
|
||||
dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL);
|
||||
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||
r = amdgpu_sync_fence(&p->job->sync, fence);
|
||||
if (r)
|
||||
if (r) {
|
||||
dma_resv_iter_end(&cursor);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
dma_resv_iter_end(&cursor);
|
||||
|
||||
do {
|
||||
ndw = p->num_dw_left;
|
||||
|
||||
@@ -720,6 +720,72 @@ uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr)
|
||||
return atomic64_read(&mgr->vis_usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_intersects - test each drm buddy block for intersection
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @res: The resource to test
|
||||
* @place: The place to test against
|
||||
* @size: Size of the new allocation
|
||||
*
|
||||
* Test each drm buddy block for intersection for eviction decision.
|
||||
*/
|
||||
static bool amdgpu_vram_mgr_intersects(struct ttm_resource_manager *man,
|
||||
struct ttm_resource *res,
|
||||
const struct ttm_place *place,
|
||||
size_t size)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
|
||||
struct drm_buddy_block *block;
|
||||
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &mgr->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(amdgpu_vram_mgr_block_size(block) >> PAGE_SHIFT);
|
||||
|
||||
if (place->fpfn < lpfn &&
|
||||
(!place->lpfn || place->lpfn > fpfn))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_compatible - test each drm buddy block for compatibility
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @res: The resource to test
|
||||
* @place: The place to test against
|
||||
* @size: Size of the new allocation
|
||||
*
|
||||
* Test each drm buddy block for placement compatibility.
|
||||
*/
|
||||
static bool amdgpu_vram_mgr_compatible(struct ttm_resource_manager *man,
|
||||
struct ttm_resource *res,
|
||||
const struct ttm_place *place,
|
||||
size_t size)
|
||||
{
|
||||
struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res);
|
||||
struct drm_buddy_block *block;
|
||||
|
||||
/* Check each drm buddy block individually */
|
||||
list_for_each_entry(block, &mgr->blocks, link) {
|
||||
unsigned long fpfn =
|
||||
amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT;
|
||||
unsigned long lpfn = fpfn +
|
||||
(amdgpu_vram_mgr_block_size(block) >> PAGE_SHIFT);
|
||||
|
||||
if (fpfn < place->fpfn ||
|
||||
(place->lpfn && lpfn > place->lpfn))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_debug - dump VRAM table
|
||||
*
|
||||
@@ -753,6 +819,8 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
|
||||
static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = {
|
||||
.alloc = amdgpu_vram_mgr_new,
|
||||
.free = amdgpu_vram_mgr_del,
|
||||
.intersects = amdgpu_vram_mgr_intersects,
|
||||
.compatible = amdgpu_vram_mgr_compatible,
|
||||
.debug = amdgpu_vram_mgr_debug
|
||||
};
|
||||
|
||||
|
||||
@@ -391,13 +391,21 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
|
||||
goto pro_end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only init hive->reset_domain for none SRIOV configuration. For SRIOV,
|
||||
* Host driver decide how to reset the GPU either through FLR or chain reset.
|
||||
* Guest side will get individual notifications from the host for the FLR
|
||||
* if necessary.
|
||||
*/
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/**
|
||||
* Avoid recreating reset domain when hive is reconstructed for the case
|
||||
* of reset the devices in the XGMI hive during probe for SRIOV
|
||||
* of reset the devices in the XGMI hive during probe for passthrough GPU
|
||||
* See https://www.spinics.net/lists/amd-gfx/msg58836.html
|
||||
*/
|
||||
if (adev->reset_domain->type != XGMI_HIVE) {
|
||||
hive->reset_domain = amdgpu_reset_create_reset_domain(XGMI_HIVE, "amdgpu-reset-hive");
|
||||
if (adev->reset_domain->type != XGMI_HIVE) {
|
||||
hive->reset_domain =
|
||||
amdgpu_reset_create_reset_domain(XGMI_HIVE, "amdgpu-reset-hive");
|
||||
if (!hive->reset_domain) {
|
||||
dev_err(adev->dev, "XGMI: failed initializing reset domain for xgmi hive\n");
|
||||
ret = -ENOMEM;
|
||||
@@ -406,9 +414,10 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
|
||||
hive = NULL;
|
||||
goto pro_end;
|
||||
}
|
||||
} else {
|
||||
amdgpu_reset_get_reset_domain(adev->reset_domain);
|
||||
hive->reset_domain = adev->reset_domain;
|
||||
} else {
|
||||
amdgpu_reset_get_reset_domain(adev->reset_domain);
|
||||
hive->reset_domain = adev->reset_domain;
|
||||
}
|
||||
}
|
||||
|
||||
hive->hive_id = adev->gmc.xgmi.hive_id;
|
||||
@@ -504,6 +513,9 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
/* Each psp need to set the latest topology */
|
||||
ret = psp_xgmi_set_topology_info(&adev->psp,
|
||||
atomic_read(&hive->number_devices),
|
||||
|
||||
@@ -43,6 +43,7 @@ struct amdgpu_hive_info {
|
||||
} pstate;
|
||||
|
||||
struct amdgpu_reset_domain *reset_domain;
|
||||
uint32_t device_remove_count;
|
||||
};
|
||||
|
||||
struct amdgpu_pcs_ras_field {
|
||||
|
||||
@@ -3943,56 +3943,6 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
|
||||
DRM_WARN_ONCE("CP firmware version too old, please update!");
|
||||
}
|
||||
|
||||
|
||||
static void gfx_v10_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_1 *rlc_hdr;
|
||||
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data;
|
||||
adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver);
|
||||
adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes);
|
||||
adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver);
|
||||
adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes);
|
||||
adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver);
|
||||
adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes);
|
||||
adev->gfx.rlc.reg_list_format_direct_reg_list_length =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_init_rlc_iram_dram_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_2 *rlc_hdr;
|
||||
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_2 *)adev->gfx.rlc_fw->data;
|
||||
adev->gfx.rlc.rlc_iram_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlc_iram_ucode_size_bytes);
|
||||
adev->gfx.rlc.rlc_iram_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlc_iram_ucode_offset_bytes);
|
||||
adev->gfx.rlc.rlc_dram_ucode_size_bytes = le32_to_cpu(rlc_hdr->rlc_dram_ucode_size_bytes);
|
||||
adev->gfx.rlc.rlc_dram_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->rlc_dram_ucode_offset_bytes);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_init_tap_delays_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_4 *rlc_hdr;
|
||||
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_4 *)adev->gfx.rlc_fw->data;
|
||||
adev->gfx.rlc.global_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->global_tap_delays_ucode_size_bytes);
|
||||
adev->gfx.rlc.global_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->global_tap_delays_ucode_offset_bytes);
|
||||
adev->gfx.rlc.se0_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se0_tap_delays_ucode_size_bytes);
|
||||
adev->gfx.rlc.se0_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se0_tap_delays_ucode_offset_bytes);
|
||||
adev->gfx.rlc.se1_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se1_tap_delays_ucode_size_bytes);
|
||||
adev->gfx.rlc.se1_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se1_tap_delays_ucode_offset_bytes);
|
||||
adev->gfx.rlc.se2_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se2_tap_delays_ucode_size_bytes);
|
||||
adev->gfx.rlc.se2_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se2_tap_delays_ucode_offset_bytes);
|
||||
adev->gfx.rlc.se3_tap_delays_ucode_size_bytes = le32_to_cpu(rlc_hdr->se3_tap_delays_ucode_size_bytes);
|
||||
adev->gfx.rlc.se3_tap_delays_ucode = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->se3_tap_delays_ucode_offset_bytes);
|
||||
}
|
||||
|
||||
static bool gfx_v10_0_navi10_gfxoff_should_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
bool ret = false;
|
||||
@@ -4028,12 +3978,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
char fw_name[40];
|
||||
char *wks = "";
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct gfx_firmware_header_v1_0 *cp_hdr;
|
||||
const struct rlc_firmware_header_v2_0 *rlc_hdr;
|
||||
unsigned int *tmp = NULL;
|
||||
unsigned int i = 0;
|
||||
uint16_t version_major;
|
||||
uint16_t version_minor;
|
||||
|
||||
@@ -4091,9 +4036,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = amdgpu_ucode_validate(adev->gfx.pfp_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
|
||||
@@ -4102,9 +4045,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = amdgpu_ucode_validate(adev->gfx.me_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
|
||||
@@ -4113,69 +4054,27 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = amdgpu_ucode_validate(adev->gfx.ce_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data;
|
||||
adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name);
|
||||
err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
/* don't check this. There are apparently firmwares in the wild with
|
||||
* incorrect size in the header
|
||||
*/
|
||||
err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
|
||||
if (err)
|
||||
dev_dbg(adev->dev,
|
||||
"gfx10: amdgpu_ucode_validate() failed \"%s\"\n",
|
||||
fw_name);
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
|
||||
version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
|
||||
version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
|
||||
|
||||
adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
|
||||
adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
|
||||
adev->gfx.rlc.save_and_restore_offset =
|
||||
le32_to_cpu(rlc_hdr->save_and_restore_offset);
|
||||
adev->gfx.rlc.clear_state_descriptor_offset =
|
||||
le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
|
||||
adev->gfx.rlc.avail_scratch_ram_locations =
|
||||
le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
|
||||
adev->gfx.rlc.reg_restore_list_size =
|
||||
le32_to_cpu(rlc_hdr->reg_restore_list_size);
|
||||
adev->gfx.rlc.reg_list_format_start =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_start);
|
||||
adev->gfx.rlc.reg_list_format_separate_start =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
|
||||
adev->gfx.rlc.starting_offsets_start =
|
||||
le32_to_cpu(rlc_hdr->starting_offsets_start);
|
||||
adev->gfx.rlc.reg_list_format_size_bytes =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
|
||||
adev->gfx.rlc.reg_list_size_bytes =
|
||||
le32_to_cpu(rlc_hdr->reg_list_size_bytes);
|
||||
adev->gfx.rlc.register_list_format =
|
||||
kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
|
||||
adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
|
||||
if (!adev->gfx.rlc.register_list_format) {
|
||||
err = -ENOMEM;
|
||||
err = amdgpu_gfx_rlc_init_microcode(adev, version_major, version_minor);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = (unsigned int *)((uintptr_t)rlc_hdr +
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
|
||||
for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
|
||||
adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
|
||||
|
||||
adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
|
||||
|
||||
tmp = (unsigned int *)((uintptr_t)rlc_hdr +
|
||||
le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
|
||||
for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
|
||||
adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
|
||||
|
||||
if (version_major == 2) {
|
||||
if (version_minor >= 1)
|
||||
gfx_v10_0_init_rlc_ext_microcode(adev);
|
||||
if (version_minor >= 2)
|
||||
gfx_v10_0_init_rlc_iram_dram_microcode(adev);
|
||||
if (version_minor == 4) {
|
||||
gfx_v10_0_init_tap_delays_microcode(adev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks);
|
||||
@@ -4185,9 +4084,8 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = amdgpu_ucode_validate(adev->gfx.mec_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
|
||||
@@ -4195,164 +4093,18 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec2_fw->data;
|
||||
adev->gfx.mec2_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec2_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
|
||||
} else {
|
||||
err = 0;
|
||||
adev->gfx.mec2_fw = NULL;
|
||||
}
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_CE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_CE;
|
||||
info->fw = adev->gfx.ce_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
if (info->fw) {
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
if (adev->gfx.rlc.save_restore_list_cntl_size_bytes &&
|
||||
adev->gfx.rlc.save_restore_list_gpm_size_bytes &&
|
||||
adev->gfx.rlc.save_restore_list_srm_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE);
|
||||
|
||||
if (adev->gfx.rlc.rlc_iram_ucode_size_bytes &&
|
||||
adev->gfx.rlc.rlc_dram_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_IRAM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_IRAM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.rlc_iram_ucode_size_bytes, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_DRAM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_DRAM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.rlc_dram_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.global_tap_delays_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.se0_tap_delays_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.se1_tap_delays_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.se2_tap_delays_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (adev->gfx.rlc.se3_tap_delays_ucode_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes) -
|
||||
le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1_JT];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1_JT;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
if (adev->gfx.mec2_fw) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes) -
|
||||
le32_to_cpu(cp_hdr->jt_size) * 4,
|
||||
PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2_JT];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2_JT;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) * 4,
|
||||
PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v10_0_check_fw_write_wait(adev);
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"gfx10: Failed to load firmware \"%s\"\n",
|
||||
"gfx10: Failed to init firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->gfx.pfp_fw);
|
||||
adev->gfx.pfp_fw = NULL;
|
||||
@@ -5981,6 +5733,9 @@ static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
||||
WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp);
|
||||
}
|
||||
|
||||
if (adev->job_hang && !enable)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0)
|
||||
break;
|
||||
@@ -7579,8 +7334,10 @@ static int gfx_v10_0_kiq_disable_kgq(struct amdgpu_device *adev)
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
||||
kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.gfx_ring[i],
|
||||
PREEMPT_QUEUES, 0, 0);
|
||||
|
||||
return amdgpu_ring_test_helper(kiq_ring);
|
||||
if (!adev->job_hang)
|
||||
return amdgpu_ring_test_helper(kiq_ring);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -73,21 +73,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_11_0[] =
|
||||
{
|
||||
/* Pending on emulation bring up */
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_11_0_0[] =
|
||||
{
|
||||
/* Pending on emulation bring up */
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_rlc_spm_11_0[] =
|
||||
{
|
||||
/* Pending on emulation bring up */
|
||||
};
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
|
||||
{
|
||||
@@ -269,34 +258,10 @@ static void gfx_v11_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
|
||||
adev->gfx.kiq.pmf = &gfx_v11_0_kiq_pm4_funcs;
|
||||
}
|
||||
|
||||
static void gfx_v11_0_init_spm_golden_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_rlc_spm_11_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_11_0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_11_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_11_0_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_0_0));
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_11_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_11_0_1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
|
||||
@@ -304,7 +269,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gfx_v11_0_init_spm_golden_registers(adev);
|
||||
}
|
||||
|
||||
static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel,
|
||||
@@ -479,10 +443,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
char fw_name[40];
|
||||
char ucode_prefix[30];
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct gfx_firmware_header_v1_0 *cp_hdr;
|
||||
const struct gfx_firmware_header_v2_0 *cp_hdr_v2_0;
|
||||
const struct rlc_firmware_header_v2_0 *rlc_hdr;
|
||||
uint16_t version_major;
|
||||
uint16_t version_minor;
|
||||
@@ -504,14 +464,11 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
adev->gfx.pfp_fw->data, 2, 0);
|
||||
if (adev->gfx.rs64_enable) {
|
||||
dev_info(adev->dev, "CP RS64 enable\n");
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK);
|
||||
} else {
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix);
|
||||
@@ -522,14 +479,11 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
if (err)
|
||||
goto out;
|
||||
if (adev->gfx.rs64_enable) {
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version = le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.me_feature_version = le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK);
|
||||
} else {
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
@@ -556,136 +510,23 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
if (err)
|
||||
goto out;
|
||||
if (adev->gfx.rs64_enable) {
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
|
||||
adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
|
||||
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK);
|
||||
} else {
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
|
||||
}
|
||||
|
||||
/* only one MEC for gfx 11.0.0. */
|
||||
adev->gfx.mec2_fw = NULL;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
if (adev->gfx.rs64_enable) {
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.pfp_fw->data;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.me_fw->data;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)adev->gfx.mec_fw->data;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_MEC];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_MEC;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr_v2_0->data_size_bytes), PAGE_SIZE);
|
||||
} else {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes) -
|
||||
le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1_JT];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1_JT;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"gfx11: Failed to load firmware \"%s\"\n",
|
||||
"gfx11: Failed to init firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->gfx.pfp_fw);
|
||||
adev->gfx.pfp_fw = NULL;
|
||||
@@ -997,7 +838,6 @@ static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
|
||||
.read_wave_sgprs = &gfx_v11_0_read_wave_sgprs,
|
||||
.read_wave_vgprs = &gfx_v11_0_read_wave_vgprs,
|
||||
.select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
|
||||
.init_spm_golden = &gfx_v11_0_init_spm_golden_registers,
|
||||
.update_perfmon_mgcg = &gfx_v11_0_update_perf_clk,
|
||||
};
|
||||
|
||||
@@ -1008,6 +848,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
@@ -1443,6 +1284,7 @@ static int gfx_v11_0_sw_init(void *handle)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->gfx.me.num_me = 1;
|
||||
adev->gfx.me.num_pipe_per_me = 1;
|
||||
adev->gfx.me.num_queue_per_pipe = 1;
|
||||
@@ -2617,6 +2459,21 @@ static void gfx_v11_0_config_gfx_rs64(struct amdgpu_device *adev)
|
||||
mec_hdr->ucode_start_addr_hi >> 2);
|
||||
}
|
||||
soc21_grbm_select(adev, 0, 0, 0, 0);
|
||||
|
||||
/* reset mec pipe */
|
||||
tmp = RREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 1);
|
||||
WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
|
||||
|
||||
/* clear mec pipe reset */
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 0);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 0);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 0);
|
||||
tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 0);
|
||||
WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
|
||||
}
|
||||
|
||||
static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
|
||||
|
||||
@@ -126,6 +126,8 @@ MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
|
||||
|
||||
#define mmTCP_CHAN_STEER_0_ARCT 0x0b03
|
||||
#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0
|
||||
@@ -1089,27 +1091,6 @@ static void gfx_v9_0_free_microcode(struct amdgpu_device *adev)
|
||||
kfree(adev->gfx.rlc.register_list_format);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_1 *rlc_hdr;
|
||||
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_1 *)adev->gfx.rlc_fw->data;
|
||||
adev->gfx.rlc_srlc_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_ucode_ver);
|
||||
adev->gfx.rlc_srlc_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_cntl_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_cntl_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_cntl_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_cntl = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_cntl_offset_bytes);
|
||||
adev->gfx.rlc_srlg_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_ucode_ver);
|
||||
adev->gfx.rlc_srlg_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_gpm_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_gpm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_gpm_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_gpm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_gpm_offset_bytes);
|
||||
adev->gfx.rlc_srls_fw_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_ucode_ver);
|
||||
adev->gfx.rlc_srls_feature_version = le32_to_cpu(rlc_hdr->save_restore_list_srm_feature_ver);
|
||||
adev->gfx.rlc.save_restore_list_srm_size_bytes = le32_to_cpu(rlc_hdr->save_restore_list_srm_size_bytes);
|
||||
adev->gfx.rlc.save_restore_list_srm = (u8 *)rlc_hdr + le32_to_cpu(rlc_hdr->save_restore_list_srm_offset_bytes);
|
||||
adev->gfx.rlc.reg_list_format_direct_reg_list_length =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfx.me_fw_write_wait = false;
|
||||
@@ -1271,9 +1252,6 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
|
||||
{
|
||||
char fw_name[30];
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct gfx_firmware_header_v1_0 *cp_hdr;
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name);
|
||||
err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
|
||||
@@ -1282,9 +1260,7 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
|
||||
err = amdgpu_ucode_validate(adev->gfx.pfp_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data;
|
||||
adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name);
|
||||
err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
|
||||
@@ -1293,9 +1269,7 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
|
||||
err = amdgpu_ucode_validate(adev->gfx.me_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data;
|
||||
adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name);
|
||||
err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
|
||||
@@ -1304,37 +1278,12 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev,
|
||||
err = amdgpu_ucode_validate(adev->gfx.ce_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data;
|
||||
adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_PFP];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_PFP;
|
||||
info->fw = adev->gfx.pfp_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_ME];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_ME;
|
||||
info->fw = adev->gfx.me_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_CE];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_CE;
|
||||
info->fw = adev->gfx.ce_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE);
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"gfx9: Failed to load firmware \"%s\"\n",
|
||||
"gfx9: Failed to init firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->gfx.pfp_fw);
|
||||
adev->gfx.pfp_fw = NULL;
|
||||
@@ -1351,11 +1300,7 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev,
|
||||
{
|
||||
char fw_name[30];
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct rlc_firmware_header_v2_0 *rlc_hdr;
|
||||
unsigned int *tmp = NULL;
|
||||
unsigned int i = 0;
|
||||
uint16_t version_major;
|
||||
uint16_t version_minor;
|
||||
uint32_t smu_version;
|
||||
@@ -1384,92 +1329,17 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev,
|
||||
if (err)
|
||||
goto out;
|
||||
err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
|
||||
|
||||
version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
|
||||
version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
|
||||
if (version_major == 2 && version_minor == 1)
|
||||
adev->gfx.rlc.is_rlc_v2_1 = true;
|
||||
|
||||
adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
|
||||
adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
|
||||
adev->gfx.rlc.save_and_restore_offset =
|
||||
le32_to_cpu(rlc_hdr->save_and_restore_offset);
|
||||
adev->gfx.rlc.clear_state_descriptor_offset =
|
||||
le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
|
||||
adev->gfx.rlc.avail_scratch_ram_locations =
|
||||
le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
|
||||
adev->gfx.rlc.reg_restore_list_size =
|
||||
le32_to_cpu(rlc_hdr->reg_restore_list_size);
|
||||
adev->gfx.rlc.reg_list_format_start =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_start);
|
||||
adev->gfx.rlc.reg_list_format_separate_start =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
|
||||
adev->gfx.rlc.starting_offsets_start =
|
||||
le32_to_cpu(rlc_hdr->starting_offsets_start);
|
||||
adev->gfx.rlc.reg_list_format_size_bytes =
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
|
||||
adev->gfx.rlc.reg_list_size_bytes =
|
||||
le32_to_cpu(rlc_hdr->reg_list_size_bytes);
|
||||
adev->gfx.rlc.register_list_format =
|
||||
kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
|
||||
adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
|
||||
if (!adev->gfx.rlc.register_list_format) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = (unsigned int *)((uintptr_t)rlc_hdr +
|
||||
le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
|
||||
for (i = 0 ; i < (adev->gfx.rlc.reg_list_format_size_bytes >> 2); i++)
|
||||
adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
|
||||
|
||||
adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
|
||||
|
||||
tmp = (unsigned int *)((uintptr_t)rlc_hdr +
|
||||
le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
|
||||
for (i = 0 ; i < (adev->gfx.rlc.reg_list_size_bytes >> 2); i++)
|
||||
adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
|
||||
|
||||
if (adev->gfx.rlc.is_rlc_v2_1)
|
||||
gfx_v9_0_init_rlc_ext_microcode(adev);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
if (adev->gfx.rlc.is_rlc_v2_1 &&
|
||||
adev->gfx.rlc.save_restore_list_cntl_size_bytes &&
|
||||
adev->gfx.rlc.save_restore_list_gpm_size_bytes &&
|
||||
adev->gfx.rlc.save_restore_list_srm_size_bytes) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_gpm_size_bytes, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(adev->gfx.rlc.save_restore_list_srm_size_bytes, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
err = amdgpu_gfx_rlc_init_microcode(adev, version_major, version_minor);
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"gfx9: Failed to load firmware \"%s\"\n",
|
||||
"gfx9: Failed to init firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->gfx.rlc_fw);
|
||||
adev->gfx.rlc_fw = NULL;
|
||||
@@ -1492,35 +1362,34 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
|
||||
{
|
||||
char fw_name[30];
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct gfx_firmware_header_v1_0 *cp_hdr;
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
|
||||
if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", chip_name);
|
||||
else
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
|
||||
|
||||
err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
err = amdgpu_ucode_validate(adev->gfx.mec_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
|
||||
|
||||
if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
|
||||
if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec2.bin", chip_name);
|
||||
else
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
|
||||
|
||||
err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
|
||||
if (!err) {
|
||||
err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
|
||||
adev->gfx.mec2_fw->data;
|
||||
adev->gfx.mec2_fw_version =
|
||||
le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec2_feature_version =
|
||||
le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2);
|
||||
amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT);
|
||||
} else {
|
||||
err = 0;
|
||||
adev->gfx.mec2_fw = NULL;
|
||||
@@ -1530,49 +1399,12 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
|
||||
adev->gfx.mec2_feature_version = adev->gfx.mec_feature_version;
|
||||
}
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes) - le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1_JT];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1_JT;
|
||||
info->fw = adev->gfx.mec_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
if (adev->gfx.mec2_fw) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
cp_hdr = (const struct gfx_firmware_header_v1_0 *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes) - le32_to_cpu(cp_hdr->jt_size) * 4, PAGE_SIZE);
|
||||
|
||||
/* TODO: Determine if MEC2 JT FW loading can be removed
|
||||
for all GFX V9 asic and above */
|
||||
if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC2_JT];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_CP_MEC2_JT;
|
||||
info->fw = adev->gfx.mec2_fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(cp_hdr->jt_size) * 4,
|
||||
PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
gfx_v9_0_check_if_need_gfxoff(adev);
|
||||
gfx_v9_0_check_fw_write_wait(adev);
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"gfx9: Failed to load firmware \"%s\"\n",
|
||||
"gfx9: Failed to init firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->gfx.mec_fw);
|
||||
adev->gfx.mec_fw = NULL;
|
||||
|
||||
@@ -576,6 +576,111 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static void gfxhub_v2_1_save_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
adev->gmc.VM_L2_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL);
|
||||
adev->gmc.VM_L2_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2);
|
||||
adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL);
|
||||
adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32);
|
||||
adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32);
|
||||
adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32);
|
||||
adev->gmc.VM_DEBUG = RREG32_SOC15(GC, 0, mmGCVM_DEBUG);
|
||||
adev->gmc.VM_L2_MM_GROUP_RT_CLASSES = RREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES);
|
||||
adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID);
|
||||
adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2 = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2);
|
||||
adev->gmc.VM_L2_CACHE_PARITY_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL);
|
||||
adev->gmc.VM_L2_IH_LOG_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL);
|
||||
|
||||
for (i = 0; i <= 15; i++) {
|
||||
adev->gmc.VM_CONTEXT_CNTL[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2);
|
||||
adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2);
|
||||
}
|
||||
|
||||
adev->gmc.MC_VM_MX_L1_TLB_CNTL = RREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL);
|
||||
}
|
||||
|
||||
static void gfxhub_v2_1_restore_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL, adev->gmc.VM_L2_CNTL);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, adev->gmc.VM_L2_CNTL2);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL, adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_DEBUG, adev->gmc.VM_DEBUG);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES, adev->gmc.VM_L2_MM_GROUP_RT_CLASSES);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL, adev->gmc.VM_L2_CACHE_PARITY_CNTL);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL, adev->gmc.VM_L2_IH_LOG_CNTL);
|
||||
|
||||
for (i = 0; i <= 15; i++) {
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i, adev->gmc.VM_CONTEXT_CNTL[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i]);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i]);
|
||||
}
|
||||
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_BASE, adev->gmc.vram_start >> 24);
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_TOP, adev->gmc.vram_end >> 24);
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, adev->gmc.MC_VM_MX_L1_TLB_CNTL);
|
||||
}
|
||||
|
||||
static void gfxhub_v2_1_halt(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
int i;
|
||||
uint32_t tmp;
|
||||
int time = 1000;
|
||||
|
||||
gfxhub_v2_1_set_fault_enable_default(adev, false);
|
||||
|
||||
for (i = 0; i <= 14; i++) {
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance, ~0);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance, ~0);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance,
|
||||
0);
|
||||
WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance,
|
||||
0);
|
||||
}
|
||||
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
|
||||
while ((tmp & (GRBM_STATUS2__EA_BUSY_MASK |
|
||||
GRBM_STATUS2__EA_LINK_BUSY_MASK)) != 0 &&
|
||||
time) {
|
||||
udelay(100);
|
||||
time--;
|
||||
tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
|
||||
}
|
||||
|
||||
if (!time) {
|
||||
DRM_WARN("failed to wait for GRBM(EA) idle\n");
|
||||
}
|
||||
}
|
||||
|
||||
const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
|
||||
.get_fb_location = gfxhub_v2_1_get_fb_location,
|
||||
.get_mc_fb_offset = gfxhub_v2_1_get_mc_fb_offset,
|
||||
@@ -586,4 +691,7 @@ const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
|
||||
.init = gfxhub_v2_1_init,
|
||||
.get_xgmi_info = gfxhub_v2_1_get_xgmi_info,
|
||||
.utcl2_harvest = gfxhub_v2_1_utcl2_harvest,
|
||||
.mode2_save_regs = gfxhub_v2_1_save_regs,
|
||||
.mode2_restore_regs = gfxhub_v2_1_restore_regs,
|
||||
.halt = gfxhub_v2_1_halt,
|
||||
};
|
||||
|
||||
511
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.c
Normal file
511
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.c
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* Copyright 2022 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 "gfxhub_v3_0_3.h"
|
||||
|
||||
#include "gc/gc_11_0_3_offset.h"
|
||||
#include "gc/gc_11_0_3_sh_mask.h"
|
||||
#include "navi10_enum.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#define regGCVM_L2_CNTL3_DEFAULT 0x80100007
|
||||
#define regGCVM_L2_CNTL4_DEFAULT 0x000000c1
|
||||
#define regGCVM_L2_CNTL5_DEFAULT 0x00003fe0
|
||||
|
||||
static const char *gfxhub_client_ids[] = {
|
||||
"CB/DB",
|
||||
"Reserved",
|
||||
"GE1",
|
||||
"GE2",
|
||||
"CPF",
|
||||
"CPC",
|
||||
"CPG",
|
||||
"RLC",
|
||||
"TCP",
|
||||
"SQC (inst)",
|
||||
"SQC (data)",
|
||||
"SQG",
|
||||
"Reserved",
|
||||
"SDMA0",
|
||||
"SDMA1",
|
||||
"GCR",
|
||||
"SDMA2",
|
||||
"SDMA3",
|
||||
};
|
||||
|
||||
static uint32_t gfxhub_v3_0_3_get_invalidate_req(unsigned int vmid,
|
||||
uint32_t flush_type)
|
||||
{
|
||||
u32 req = 0;
|
||||
|
||||
/* invalidate using legacy mode on vmid*/
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
|
||||
PER_VMID_INVALIDATE_REQ, 1 << vmid);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
|
||||
req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
|
||||
CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void
|
||||
gfxhub_v3_0_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
|
||||
uint32_t status)
|
||||
{
|
||||
u32 cid = REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, CID);
|
||||
|
||||
dev_err(adev->dev,
|
||||
"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid],
|
||||
cid);
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
|
||||
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, RW));
|
||||
}
|
||||
|
||||
static u64 gfxhub_v3_0_3_get_fb_location(struct amdgpu_device *adev)
|
||||
{
|
||||
u64 base = RREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE);
|
||||
|
||||
base &= GCMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
|
||||
base <<= 24;
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static u64 gfxhub_v3_0_3_get_mc_fb_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return (u64)RREG32_SOC15(GC, 0, regGCMC_VM_FB_OFFSET) << 24;
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint64_t page_table_base)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
|
||||
hub->ctx_addr_distance * vmid,
|
||||
lower_32_bits(page_table_base));
|
||||
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
|
||||
hub->ctx_addr_distance * vmid,
|
||||
upper_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_init_gart_aperture_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
|
||||
|
||||
gfxhub_v3_0_3_setup_vm_pt_regs(adev, 0, pt_base);
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
|
||||
(u32)(adev->gmc.gart_start >> 12));
|
||||
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
|
||||
(u32)(adev->gmc.gart_start >> 44));
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
|
||||
(u32)(adev->gmc.gart_end >> 12));
|
||||
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
|
||||
(u32)(adev->gmc.gart_end >> 44));
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t value;
|
||||
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, 0x00FFFFFF);
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
|
||||
+ adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
(u32)(value >> 44));
|
||||
|
||||
/* Program "protection fault". */
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
|
||||
(u32)(adev->dummy_page_addr >> 12));
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
|
||||
(u32)((u64)adev->dummy_page_addr >> 44));
|
||||
|
||||
WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_PROTECTION_FAULT_CNTL2,
|
||||
ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
|
||||
}
|
||||
|
||||
|
||||
static void gfxhub_v3_0_3_init_tlb_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Setup TLB control */
|
||||
tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
|
||||
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
|
||||
ENABLE_ADVANCED_DRIVER_MODEL, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
|
||||
SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
|
||||
MTYPE, MTYPE_UC); /* UC, uncached */
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_init_cache_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* These registers are not accessible to VF-SRIOV.
|
||||
* The PF will program them instead.
|
||||
*/
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
/* Setup L2 cache */
|
||||
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_CACHE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
|
||||
ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
|
||||
/* XXX for emulation, Refer to closed source code.*/
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
|
||||
L2_PDE0_CACHE_TAG_GENERATION_MODE, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL, tmp);
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL2);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL2, tmp);
|
||||
|
||||
tmp = regGCVM_L2_CNTL3_DEFAULT;
|
||||
if (adev->gmc.translate_further) {
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||
} else {
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||
}
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, tmp);
|
||||
|
||||
tmp = regGCVM_L2_CNTL4_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL4, tmp);
|
||||
|
||||
tmp = regGCVM_L2_CNTL5_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL5, tmp);
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_enable_system_domain(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL,
|
||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL, tmp);
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_disable_identity_aperture(struct amdgpu_device *adev)
|
||||
{
|
||||
/* These registers are not accessible to VF-SRIOV.
|
||||
* The PF will program them instead.
|
||||
*/
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
|
||||
0xFFFFFFFF);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
|
||||
0x0000000F);
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32,
|
||||
0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32,
|
||||
0);
|
||||
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, 0);
|
||||
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_setup_vmid_config(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
int i;
|
||||
uint32_t tmp;
|
||||
|
||||
for (i = 0; i <= 14; i++) {
|
||||
tmp = RREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL, i);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
|
||||
adev->vm_manager.num_level);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
PAGE_TABLE_BLOCK_SIZE,
|
||||
adev->vm_manager.block_size - 9);
|
||||
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
|
||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
|
||||
!amdgpu_noretry);
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL,
|
||||
i * hub->ctx_distance, tmp);
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance, 0);
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance, 0);
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance,
|
||||
lower_32_bits(adev->vm_manager.max_pfn - 1));
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance,
|
||||
upper_32_bits(adev->vm_manager.max_pfn - 1));
|
||||
}
|
||||
|
||||
hub->vm_cntx_cntl = tmp;
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_program_invalidation(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
unsigned i;
|
||||
|
||||
for (i = 0 ; i < 18; ++i) {
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
|
||||
i * hub->eng_addr_distance, 0xffffffff);
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
|
||||
i * hub->eng_addr_distance, 0x1f);
|
||||
}
|
||||
}
|
||||
|
||||
static int gfxhub_v3_0_3_gart_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* GCMC_VM_FB_LOCATION_BASE/TOP is NULL for VF, becuase they are
|
||||
* VF copy registers so vbios post doesn't program them, for
|
||||
* SRIOV driver need to program them
|
||||
*/
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE,
|
||||
adev->gmc.vram_start >> 24);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_TOP,
|
||||
adev->gmc.vram_end >> 24);
|
||||
}
|
||||
|
||||
/* GART Enable. */
|
||||
gfxhub_v3_0_3_init_gart_aperture_regs(adev);
|
||||
gfxhub_v3_0_3_init_system_aperture_regs(adev);
|
||||
gfxhub_v3_0_3_init_tlb_regs(adev);
|
||||
gfxhub_v3_0_3_init_cache_regs(adev);
|
||||
|
||||
gfxhub_v3_0_3_enable_system_domain(adev);
|
||||
gfxhub_v3_0_3_disable_identity_aperture(adev);
|
||||
gfxhub_v3_0_3_setup_vmid_config(adev);
|
||||
gfxhub_v3_0_3_program_invalidation(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfxhub_v3_0_3_gart_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
u32 tmp;
|
||||
u32 i;
|
||||
|
||||
/* Disable all tables */
|
||||
for (i = 0; i < 16; i++)
|
||||
WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL,
|
||||
i * hub->ctx_distance, 0);
|
||||
|
||||
/* Setup TLB control */
|
||||
tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
|
||||
ENABLE_ADVANCED_DRIVER_MODEL, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
|
||||
/* Setup L2 cache */
|
||||
WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_CNTL, ENABLE_L2_CACHE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfxhub_v3_0_3_set_fault_enable_default - update GART/VM fault handling
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @value: true redirects VM faults to the default page
|
||||
*/
|
||||
static void gfxhub_v3_0_3_set_fault_enable_default(struct amdgpu_device *adev,
|
||||
bool value)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
/* These registers are not accessible to VF-SRIOV.
|
||||
* The PF will program them instead.
|
||||
*/
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
|
||||
value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
if (!value) {
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
CRASH_ON_NO_RETRY_FAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
|
||||
CRASH_ON_RETRY_FAULT, 1);
|
||||
}
|
||||
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
|
||||
}
|
||||
|
||||
static const struct amdgpu_vmhub_funcs gfxhub_v3_0_3_vmhub_funcs = {
|
||||
.print_l2_protection_fault_status = gfxhub_v3_0_3_print_l2_protection_fault_status,
|
||||
.get_invalidate_req = gfxhub_v3_0_3_get_invalidate_req,
|
||||
};
|
||||
|
||||
static void gfxhub_v3_0_3_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
|
||||
hub->ctx0_ptb_addr_lo32 =
|
||||
SOC15_REG_OFFSET(GC, 0,
|
||||
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
|
||||
hub->ctx0_ptb_addr_hi32 =
|
||||
SOC15_REG_OFFSET(GC, 0,
|
||||
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
|
||||
hub->vm_inv_eng0_sem =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_SEM);
|
||||
hub->vm_inv_eng0_req =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_REQ);
|
||||
hub->vm_inv_eng0_ack =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ACK);
|
||||
hub->vm_context0_cntl =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL);
|
||||
hub->vm_l2_pro_fault_status =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_STATUS);
|
||||
hub->vm_l2_pro_fault_cntl =
|
||||
SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
|
||||
|
||||
hub->ctx_distance = regGCVM_CONTEXT1_CNTL - regGCVM_CONTEXT0_CNTL;
|
||||
hub->ctx_addr_distance = regGCVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
|
||||
regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
|
||||
hub->eng_distance = regGCVM_INVALIDATE_ENG1_REQ -
|
||||
regGCVM_INVALIDATE_ENG0_REQ;
|
||||
hub->eng_addr_distance = regGCVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
|
||||
regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
|
||||
|
||||
hub->vm_cntx_cntl_vm_fault = GCVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
|
||||
|
||||
hub->vmhub_funcs = &gfxhub_v3_0_3_vmhub_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs = {
|
||||
.get_fb_location = gfxhub_v3_0_3_get_fb_location,
|
||||
.get_mc_fb_offset = gfxhub_v3_0_3_get_mc_fb_offset,
|
||||
.setup_vm_pt_regs = gfxhub_v3_0_3_setup_vm_pt_regs,
|
||||
.gart_enable = gfxhub_v3_0_3_gart_enable,
|
||||
.gart_disable = gfxhub_v3_0_3_gart_disable,
|
||||
.set_fault_enable_default = gfxhub_v3_0_3_set_fault_enable_default,
|
||||
.init = gfxhub_v3_0_3_init,
|
||||
};
|
||||
29
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.h
Normal file
29
drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GFXHUB_V3_0_3_H__
|
||||
#define __GFXHUB_V3_0_3_H__
|
||||
|
||||
extern const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs;
|
||||
|
||||
#endif
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "soc15_common.h"
|
||||
#include "nbio_v4_3.h"
|
||||
#include "gfxhub_v3_0.h"
|
||||
#include "gfxhub_v3_0_3.h"
|
||||
#include "mmhub_v3_0.h"
|
||||
#include "mmhub_v3_0_1.h"
|
||||
#include "mmhub_v3_0_2.h"
|
||||
@@ -233,7 +234,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
|
||||
|
||||
/* Issue additional private vm invalidation to MMHUB */
|
||||
if ((vmhub != AMDGPU_GFXHUB_0) &&
|
||||
(hub->vm_l2_bank_select_reserved_cid2)) {
|
||||
(hub->vm_l2_bank_select_reserved_cid2) &&
|
||||
!amdgpu_sriov_vf(adev)) {
|
||||
inv_req = RREG32_NO_KIQ(hub->vm_l2_bank_select_reserved_cid2);
|
||||
/* bit 25: RSERVED_CACHE_PRIVATE_INVALIDATION */
|
||||
inv_req |= (1 << 25);
|
||||
@@ -590,7 +592,14 @@ static void gmc_v11_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
||||
|
||||
static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->gfxhub.funcs = &gfxhub_v3_0_3_funcs;
|
||||
break;
|
||||
default:
|
||||
adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int gmc_v11_0_early_init(void *handle)
|
||||
@@ -640,7 +649,10 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
amdgpu_gmc_gart_location(adev, mc);
|
||||
|
||||
/* base offset of vram pages */
|
||||
adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->vm_manager.vram_base_offset = 0;
|
||||
else
|
||||
adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -732,6 +744,7 @@ static int gmc_v11_0_sw_init(void *handle)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->num_vmhubs = 2;
|
||||
/*
|
||||
* To fulfill 4-level page support,
|
||||
|
||||
@@ -105,7 +105,13 @@ force_update_wptr_for_self_int(struct amdgpu_device *adev,
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
|
||||
RB_USED_INT_THRESHOLD, threshold);
|
||||
|
||||
WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, ih_rb_cntl))
|
||||
return;
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||
}
|
||||
|
||||
WREG32_SOC15(OSSSYS, 0, regIH_CNTL2, ih_cntl);
|
||||
}
|
||||
|
||||
@@ -132,7 +138,13 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
|
||||
/* enable_intr field is only valid in ring0 */
|
||||
if (ih == &adev->irq.ih)
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
|
||||
WREG32(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
|
||||
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
WREG32(ih_regs->ih_rb_cntl, tmp);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ih->enabled = true;
|
||||
@@ -242,7 +254,15 @@ static int ih_v6_0_enable_ring(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
|
||||
}
|
||||
WREG32(ih_regs->ih_rb_cntl, tmp);
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
|
||||
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
|
||||
DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} else {
|
||||
WREG32(ih_regs->ih_rb_cntl, tmp);
|
||||
}
|
||||
|
||||
if (ih == &adev->irq.ih) {
|
||||
/* set the ih ring 0 writeback address whether it's enabled or not */
|
||||
|
||||
@@ -26,12 +26,15 @@
|
||||
#include "amdgpu_imu.h"
|
||||
#include "amdgpu_dpm.h"
|
||||
|
||||
#include "imu_v11_0_3.h"
|
||||
|
||||
#include "gc/gc_11_0_0_offset.h"
|
||||
#include "gc/gc_11_0_0_sh_mask.h"
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_imu.bin");
|
||||
|
||||
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
@@ -360,6 +363,9 @@ static void imu_v11_0_program_rlc_ram(struct amdgpu_device *adev)
|
||||
program_imu_rlc_ram(adev, imu_rlc_ram_golden_11_0_2,
|
||||
(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_2));
|
||||
break;
|
||||
case IP_VERSION(11, 0, 3):
|
||||
imu_v11_0_3_program_rlc_ram(adev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
|
||||
145
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.c
Normal file
145
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2022 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_imu.h"
|
||||
#include "imu_v11_0_3.h"
|
||||
|
||||
#include "gc/gc_11_0_3_offset.h"
|
||||
#include "gc/gc_11_0_3_sh_mask.h"
|
||||
|
||||
static const struct imu_rlc_ram_golden imu_rlc_ram_golden_11_0_3[] = {
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_RD_COMBINE_FLUSH, 0x00055555, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_WR_COMBINE_FLUSH, 0x00055555, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_DRAM_COMBINE_FLUSH, 0x00555555, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC2, 0x00001ffe, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_CREDITS, 0x003f3fff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_TAG_RESERVE1, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE0, 0x00041000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE1, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE0, 0x00040000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE1, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC, 0x00000017, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_ENABLE, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_CREDITS, 0x003f3fbf, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE0, 0x10200800, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE1, 0x00000088, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE0, 0x1d041040, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE1, 0x80000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_IO_PRIORITY, 0x88888888, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MAM_CTRL, 0x0000d800, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ARB_FINAL, 0x000007ff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_DRAM_PAGE_BURST, 0x20080200, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ENABLE, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_CACHEABLE_DRAM_ADDRESS_END, 0x000fffff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MISC, 0x0c48bff0, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SA_UNIT_DISABLE, 0x00fffc01, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_PRIM_CONFIG, 0x000fffe1, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_RB_BACKEND_DISABLE, 0xffffff01, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x40000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x42000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x44000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x46000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x48000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x4A000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCGTS_TCC_DISABLE, 0x00000001, 0x00000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_RATE_CONFIG, 0x00000001, 0x00000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_EDC_CONFIG, 0x00000001, 0x00000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000500, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_START, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_END, 0x000005ff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_BASE, 0x00006000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_TOP, 0x000065ff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_TOP_OF_DRAM_SLOT1, 0xff800000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_LOWER_TOP_OF_DRAM2, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_UPPER_TOP_OF_DRAM2, 0x00000fff, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, 0x00001ffc, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000551, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL, 0x00080603, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL2, 0x00000003, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL3, 0x00100003, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL5, 0x00003fe0, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT0_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000001, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT1_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000444, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_0, 0x54105410, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_2, 0x76323276, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000244, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCUTCL2_HARVEST_BYPASS_GROUPS, 0x00000006, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BASE, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BOT, 0x00000002, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_TOP, 0x00000000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA0_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA1_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPC_PSP_DEBUG, CPC_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
|
||||
IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPG_PSP_DEBUG, CPG_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
|
||||
};
|
||||
|
||||
static void program_rlc_ram_register_setting(struct amdgpu_device *adev,
|
||||
const struct imu_rlc_ram_golden *regs,
|
||||
const u32 array_size)
|
||||
{
|
||||
const struct imu_rlc_ram_golden *entry;
|
||||
u32 reg, data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < array_size; ++i) {
|
||||
entry = ®s[i];
|
||||
reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
|
||||
reg |= entry->addr_mask;
|
||||
|
||||
data = entry->data;
|
||||
if (entry->reg == regGCMC_VM_AGP_BASE)
|
||||
data = 0x00ffffff;
|
||||
else if (entry->reg == regGCMC_VM_AGP_TOP)
|
||||
data = 0x0;
|
||||
else if (entry->reg == regGCMC_VM_FB_LOCATION_BASE)
|
||||
data = adev->gmc.vram_start >> 24;
|
||||
else if (entry->reg == regGCMC_VM_FB_LOCATION_TOP)
|
||||
data = adev->gmc.vram_end >> 24;
|
||||
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, reg);
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, data);
|
||||
}
|
||||
//Indicate the latest entry
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, 0);
|
||||
WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, 0);
|
||||
}
|
||||
|
||||
void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev)
|
||||
{
|
||||
program_rlc_ram_register_setting(adev,
|
||||
imu_rlc_ram_golden_11_0_3,
|
||||
(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_3));
|
||||
}
|
||||
29
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.h
Normal file
29
drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __IMU_V11_0_3_H__
|
||||
#define __IMU_V11_0_3_H__
|
||||
|
||||
void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
@@ -38,6 +38,8 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
|
||||
|
||||
static int mes_v11_0_hw_fini(void *handle);
|
||||
static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
|
||||
@@ -189,6 +191,15 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
|
||||
mes_add_queue_pkt.is_aql_queue = input->is_aql_queue;
|
||||
mes_add_queue_pkt.gds_size = input->queue_size;
|
||||
|
||||
if (!(((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 4) &&
|
||||
(adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) &&
|
||||
(adev->ip_versions[GC_HWIP][0] <= IP_VERSION(11, 0, 3))))
|
||||
mes_add_queue_pkt.trap_en = 1;
|
||||
|
||||
/* For KFD, gds_size is re-used for queue size (needed in MES for AQL queues) */
|
||||
mes_add_queue_pkt.is_aql_queue = input->is_aql_queue;
|
||||
mes_add_queue_pkt.gds_size = input->queue_size;
|
||||
|
||||
return mes_v11_0_submit_pkt_and_poll_completion(mes,
|
||||
&mes_add_queue_pkt, sizeof(mes_add_queue_pkt),
|
||||
offsetof(union MESAPI__ADD_QUEUE, api_status));
|
||||
|
||||
@@ -169,17 +169,17 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
uint64_t value;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* the new L1 policy will block SRIOV guest from writing
|
||||
* these regs, and they will be programed at host.
|
||||
* so skip programing these regs.
|
||||
*/
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
|
||||
140
drivers/gpu/drm/amd/amdgpu/mmsch_v4_0.h
Normal file
140
drivers/gpu/drm/amd/amdgpu/mmsch_v4_0.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MMSCH_V4_0_H__
|
||||
#define __MMSCH_V4_0_H__
|
||||
|
||||
#include "amdgpu_vcn.h"
|
||||
|
||||
#define MMSCH_VERSION_MAJOR 4
|
||||
#define MMSCH_VERSION_MINOR 0
|
||||
#define MMSCH_VERSION (MMSCH_VERSION_MAJOR << 16 | MMSCH_VERSION_MINOR)
|
||||
|
||||
#define RB_ENABLED (1 << 0)
|
||||
#define RB4_ENABLED (1 << 1)
|
||||
#define MMSCH_DOORBELL_OFFSET 0x8
|
||||
|
||||
#define MMSCH_VF_ENGINE_STATUS__PASS 0x1
|
||||
|
||||
#define MMSCH_VF_MAILBOX_RESP__OK 0x1
|
||||
#define MMSCH_VF_MAILBOX_RESP__INCOMPLETE 0x2
|
||||
|
||||
enum mmsch_v4_0_command_type {
|
||||
MMSCH_COMMAND__DIRECT_REG_WRITE = 0,
|
||||
MMSCH_COMMAND__DIRECT_REG_POLLING = 2,
|
||||
MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE = 3,
|
||||
MMSCH_COMMAND__INDIRECT_REG_WRITE = 8,
|
||||
MMSCH_COMMAND__END = 0xf
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_table_info {
|
||||
uint32_t init_status;
|
||||
uint32_t table_offset;
|
||||
uint32_t table_size;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_init_header {
|
||||
uint32_t version;
|
||||
uint32_t total_size;
|
||||
struct mmsch_v4_0_table_info inst[AMDGPU_MAX_VCN_INSTANCES];
|
||||
struct mmsch_v4_0_table_info jpegdec;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_direct_reg_header {
|
||||
uint32_t reg_offset : 28;
|
||||
uint32_t command_type : 4;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_indirect_reg_header {
|
||||
uint32_t reg_offset : 20;
|
||||
uint32_t reg_idx_space : 8;
|
||||
uint32_t command_type : 4;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_direct_write {
|
||||
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
|
||||
uint32_t reg_value;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_direct_read_modify_write {
|
||||
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
|
||||
uint32_t write_data;
|
||||
uint32_t mask_value;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_direct_polling {
|
||||
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
|
||||
uint32_t mask_value;
|
||||
uint32_t wait_value;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_end {
|
||||
struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
|
||||
};
|
||||
|
||||
struct mmsch_v4_0_cmd_indirect_write {
|
||||
struct mmsch_v4_0_cmd_indirect_reg_header cmd_header;
|
||||
uint32_t reg_value;
|
||||
};
|
||||
|
||||
#define MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(reg, mask, data) { \
|
||||
size = sizeof(struct mmsch_v4_0_cmd_direct_read_modify_write); \
|
||||
size_dw = size / 4; \
|
||||
direct_rd_mod_wt.cmd_header.reg_offset = reg; \
|
||||
direct_rd_mod_wt.mask_value = mask; \
|
||||
direct_rd_mod_wt.write_data = data; \
|
||||
memcpy((void *)table_loc, &direct_rd_mod_wt, size); \
|
||||
table_loc += size_dw; \
|
||||
table_size += size_dw; \
|
||||
}
|
||||
|
||||
#define MMSCH_V4_0_INSERT_DIRECT_WT(reg, value) { \
|
||||
size = sizeof(struct mmsch_v4_0_cmd_direct_write); \
|
||||
size_dw = size / 4; \
|
||||
direct_wt.cmd_header.reg_offset = reg; \
|
||||
direct_wt.reg_value = value; \
|
||||
memcpy((void *)table_loc, &direct_wt, size); \
|
||||
table_loc += size_dw; \
|
||||
table_size += size_dw; \
|
||||
}
|
||||
|
||||
#define MMSCH_V4_0_INSERT_DIRECT_POLL(reg, mask, wait) { \
|
||||
size = sizeof(struct mmsch_v4_0_cmd_direct_polling); \
|
||||
size_dw = size / 4; \
|
||||
direct_poll.cmd_header.reg_offset = reg; \
|
||||
direct_poll.mask_value = mask; \
|
||||
direct_poll.wait_value = wait; \
|
||||
memcpy((void *)table_loc, &direct_poll, size); \
|
||||
table_loc += size_dw; \
|
||||
table_size += size_dw; \
|
||||
}
|
||||
|
||||
#define MMSCH_V4_0_INSERT_END() { \
|
||||
size = sizeof(struct mmsch_v4_0_cmd_end); \
|
||||
size_dw = size / 4; \
|
||||
memcpy((void *)table_loc, &end, size); \
|
||||
table_loc += size_dw; \
|
||||
table_size += size_dw; \
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -290,6 +290,7 @@ flr_done:
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
|
||||
@@ -317,6 +317,7 @@ flr_done:
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
|
||||
@@ -529,6 +529,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work)
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
|
||||
@@ -488,3 +488,47 @@ const struct amdgpu_nbio_funcs nbio_v4_3_funcs = {
|
||||
.get_rom_offset = nbio_v4_3_get_rom_offset,
|
||||
.program_aspm = nbio_v4_3_program_aspm,
|
||||
};
|
||||
|
||||
|
||||
static void nbio_v4_3_sriov_ih_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index)
|
||||
{
|
||||
}
|
||||
|
||||
static void nbio_v4_3_sriov_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
|
||||
bool use_doorbell, int doorbell_index,
|
||||
int doorbell_size)
|
||||
{
|
||||
}
|
||||
|
||||
static void nbio_v4_3_sriov_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
|
||||
int doorbell_index, int instance)
|
||||
{
|
||||
}
|
||||
|
||||
static void nbio_v4_3_sriov_gc_doorbell_init(struct amdgpu_device *adev)
|
||||
{
|
||||
}
|
||||
|
||||
const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs = {
|
||||
.get_hdp_flush_req_offset = nbio_v4_3_get_hdp_flush_req_offset,
|
||||
.get_hdp_flush_done_offset = nbio_v4_3_get_hdp_flush_done_offset,
|
||||
.get_pcie_index_offset = nbio_v4_3_get_pcie_index_offset,
|
||||
.get_pcie_data_offset = nbio_v4_3_get_pcie_data_offset,
|
||||
.get_rev_id = nbio_v4_3_get_rev_id,
|
||||
.mc_access_enable = nbio_v4_3_mc_access_enable,
|
||||
.get_memsize = nbio_v4_3_get_memsize,
|
||||
.sdma_doorbell_range = nbio_v4_3_sriov_sdma_doorbell_range,
|
||||
.vcn_doorbell_range = nbio_v4_3_sriov_vcn_doorbell_range,
|
||||
.gc_doorbell_init = nbio_v4_3_sriov_gc_doorbell_init,
|
||||
.enable_doorbell_aperture = nbio_v4_3_enable_doorbell_aperture,
|
||||
.enable_doorbell_selfring_aperture = nbio_v4_3_enable_doorbell_selfring_aperture,
|
||||
.ih_doorbell_range = nbio_v4_3_sriov_ih_doorbell_range,
|
||||
.update_medium_grain_clock_gating = nbio_v4_3_update_medium_grain_clock_gating,
|
||||
.update_medium_grain_light_sleep = nbio_v4_3_update_medium_grain_light_sleep,
|
||||
.get_clockgating_state = nbio_v4_3_get_clockgating_state,
|
||||
.ih_control = nbio_v4_3_ih_control,
|
||||
.init_registers = nbio_v4_3_init_registers,
|
||||
.remap_hdp_registers = nbio_v4_3_remap_hdp_registers,
|
||||
.get_rom_offset = nbio_v4_3_get_rom_offset,
|
||||
};
|
||||
|
||||
@@ -28,5 +28,6 @@
|
||||
|
||||
extern const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg;
|
||||
extern const struct amdgpu_nbio_funcs nbio_v4_3_funcs;
|
||||
extern const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
|
||||
|
||||
/* For large FW files the time to complete can be very long */
|
||||
#define USBC_PD_POLLING_LIMIT_S 240
|
||||
@@ -109,6 +110,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -222,6 +224,12 @@ static int psp_v13_0_bootloader_load_dbg_drv(struct psp_context *psp)
|
||||
return psp_v13_0_bootloader_load_component(psp, &psp->dbg_drv, PSP_BL__LOAD_DBGDRV);
|
||||
}
|
||||
|
||||
static int psp_v13_0_bootloader_load_ras_drv(struct psp_context *psp)
|
||||
{
|
||||
return psp_v13_0_bootloader_load_component(psp, &psp->ras_drv, PSP_BL__LOAD_RASDRV);
|
||||
}
|
||||
|
||||
|
||||
static int psp_v13_0_bootloader_load_sos(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
@@ -718,6 +726,7 @@ static const struct psp_funcs psp_v13_0_funcs = {
|
||||
.bootloader_load_soc_drv = psp_v13_0_bootloader_load_soc_drv,
|
||||
.bootloader_load_intf_drv = psp_v13_0_bootloader_load_intf_drv,
|
||||
.bootloader_load_dbg_drv = psp_v13_0_bootloader_load_dbg_drv,
|
||||
.bootloader_load_ras_drv = psp_v13_0_bootloader_load_ras_drv,
|
||||
.bootloader_load_sos = psp_v13_0_bootloader_load_sos,
|
||||
.ring_init = psp_v13_0_ring_init,
|
||||
.ring_create = psp_v13_0_ring_create,
|
||||
|
||||
@@ -561,44 +561,6 @@ static void sdma_v4_0_setup_ulv(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static int sdma_v4_0_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst)
|
||||
{
|
||||
int err = 0;
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
|
||||
err = amdgpu_ucode_validate(sdma_inst->fw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)sdma_inst->fw->data;
|
||||
sdma_inst->fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
sdma_inst->feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
|
||||
if (sdma_inst->feature_version >= 20)
|
||||
sdma_inst->burst_nop = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdma_v4_0_destroy_inst_ctx(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
release_firmware(adev->sdma.instance[i].fw);
|
||||
adev->sdma.instance[i].fw = NULL;
|
||||
|
||||
/* arcturus shares the same FW memory across
|
||||
all SDMA isntances */
|
||||
if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) ||
|
||||
adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
memset((void *)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v4_0_init_microcode - load ucode images from disk
|
||||
*
|
||||
@@ -615,9 +577,7 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0, i;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
int ret, i;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
@@ -656,58 +616,25 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
|
||||
BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
|
||||
|
||||
err = request_firmware(&adev->sdma.instance[0].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = sdma_v4_0_init_inst_ctx(&adev->sdma.instance[0]);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
for (i = 1; i < adev->sdma.num_instances; i++) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (i == 0)
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
|
||||
else
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i);
|
||||
if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) ||
|
||||
adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) {
|
||||
/* Acturus & Aldebaran will leverage the same FW memory
|
||||
for every SDMA instance */
|
||||
memcpy((void *)&adev->sdma.instance[i],
|
||||
(void *)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
}
|
||||
else {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i);
|
||||
|
||||
err = request_firmware(&adev->sdma.instance[i].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = sdma_v4_0_init_inst_ctx(&adev->sdma.instance[i]);
|
||||
if (err)
|
||||
goto out;
|
||||
ret = amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
|
||||
break;
|
||||
} else {
|
||||
ret = amdgpu_sdma_init_microcode(adev, fw_name, i, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("psp_load == '%s'\n",
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
DRM_ERROR("sdma_v4_0: Failed to load firmware \"%s\"\n", fw_name);
|
||||
sdma_v4_0_destroy_inst_ctx(adev);
|
||||
}
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2000,14 +1927,17 @@ static int sdma_v4_0_sw_fini(void *handle)
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].page);
|
||||
}
|
||||
|
||||
sdma_v4_0_destroy_inst_ctx(adev);
|
||||
if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 0) ||
|
||||
adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0))
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, true);
|
||||
else
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdma_v4_0_hw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
@@ -2016,9 +1946,7 @@ static int sdma_v4_0_hw_init(void *handle)
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
sdma_v4_0_init_golden_registers(adev);
|
||||
|
||||
r = sdma_v4_0_start(adev);
|
||||
|
||||
return r;
|
||||
return sdma_v4_0_start(adev);
|
||||
}
|
||||
|
||||
static int sdma_v4_0_hw_fini(void *handle)
|
||||
|
||||
@@ -240,10 +240,7 @@ static int sdma_v5_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
char fw_name[40];
|
||||
int err = 0, i;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
int ret, i;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 0, 5)))
|
||||
return 0;
|
||||
@@ -272,38 +269,12 @@ static int sdma_v5_0_init_microcode(struct amdgpu_device *adev)
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
|
||||
else
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma1.bin", chip_name);
|
||||
err = request_firmware(&adev->sdma.instance[i].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
err = amdgpu_ucode_validate(adev->sdma.instance[i].fw);
|
||||
if (err)
|
||||
goto out;
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma.instance[i].fw->data;
|
||||
adev->sdma.instance[i].fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
adev->sdma.instance[i].feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
if (adev->sdma.instance[i].feature_version >= 20)
|
||||
adev->sdma.instance[i].burst_nop = true;
|
||||
DRM_DEBUG("psp_load == '%s'\n",
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
ret = amdgpu_sdma_init_microcode(adev, fw_name, i, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
out:
|
||||
if (err) {
|
||||
DRM_ERROR("sdma_v5_0: Failed to load firmware \"%s\"\n", fw_name);
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
release_firmware(adev->sdma.instance[i].fw);
|
||||
adev->sdma.instance[i].fw = NULL;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned sdma_v5_0_ring_init_cond_exec(struct amdgpu_ring *ring)
|
||||
@@ -1465,12 +1436,10 @@ static int sdma_v5_0_sw_fini(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
release_firmware(adev->sdma.instance[i].fw);
|
||||
adev->sdma.instance[i].fw = NULL;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++)
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
|
||||
}
|
||||
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -89,33 +89,6 @@ static u32 sdma_v5_2_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
|
||||
return base + internal_offset;
|
||||
}
|
||||
|
||||
static int sdma_v5_2_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst)
|
||||
{
|
||||
int err = 0;
|
||||
const struct sdma_firmware_header_v1_0 *hdr;
|
||||
|
||||
err = amdgpu_ucode_validate(sdma_inst->fw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hdr = (const struct sdma_firmware_header_v1_0 *)sdma_inst->fw->data;
|
||||
sdma_inst->fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
sdma_inst->feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
|
||||
if (sdma_inst->feature_version >= 20)
|
||||
sdma_inst->burst_nop = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdma_v5_2_destroy_inst_ctx(struct amdgpu_device *adev)
|
||||
{
|
||||
release_firmware(adev->sdma.instance[0].fw);
|
||||
|
||||
memset((void *)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v5_2_init_microcode - load ucode images from disk
|
||||
*
|
||||
@@ -132,9 +105,6 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
char fw_name[40];
|
||||
int err = 0, i;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
@@ -169,42 +139,7 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
|
||||
|
||||
err = request_firmware(&adev->sdma.instance[0].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = sdma_v5_2_init_inst_ctx(&adev->sdma.instance[0]);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
for (i = 1; i < adev->sdma.num_instances; i++)
|
||||
memcpy((void *)&adev->sdma.instance[i],
|
||||
(void *)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 2, 0)))
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG("psp_load == '%s'\n",
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
|
||||
info->fw = adev->sdma.instance[i].fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
DRM_ERROR("sdma_v5_2: Failed to load firmware \"%s\"\n", fw_name);
|
||||
sdma_v5_2_destroy_inst_ctx(adev);
|
||||
}
|
||||
return err;
|
||||
return amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
|
||||
}
|
||||
|
||||
static unsigned sdma_v5_2_ring_init_cond_exec(struct amdgpu_ring *ring)
|
||||
@@ -1406,19 +1341,16 @@ static int sdma_v5_2_sw_fini(void *handle)
|
||||
for (i = 0; i < adev->sdma.num_instances; i++)
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
|
||||
|
||||
sdma_v5_2_destroy_inst_ctx(adev);
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdma_v5_2_hw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = sdma_v5_2_start(adev);
|
||||
|
||||
return r;
|
||||
return sdma_v5_2_start(adev);
|
||||
}
|
||||
|
||||
static int sdma_v5_2_hw_fini(void *handle)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
|
||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
|
||||
|
||||
#define SDMA1_REG_OFFSET 0x600
|
||||
#define SDMA0_HYP_DEC_REG_START 0x5880
|
||||
@@ -77,33 +78,6 @@ static u32 sdma_v6_0_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
|
||||
return base + internal_offset;
|
||||
}
|
||||
|
||||
static int sdma_v6_0_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst)
|
||||
{
|
||||
int err = 0;
|
||||
const struct sdma_firmware_header_v2_0 *hdr;
|
||||
|
||||
err = amdgpu_ucode_validate(sdma_inst->fw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hdr = (const struct sdma_firmware_header_v2_0 *)sdma_inst->fw->data;
|
||||
sdma_inst->fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
sdma_inst->feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
|
||||
if (sdma_inst->feature_version >= 20)
|
||||
sdma_inst->burst_nop = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdma_v6_0_destroy_inst_ctx(struct amdgpu_device *adev)
|
||||
{
|
||||
release_firmware(adev->sdma.instance[0].fw);
|
||||
|
||||
memset((void*)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdma_v6_0_init_microcode - load ucode images from disk
|
||||
*
|
||||
@@ -113,16 +87,10 @@ static void sdma_v6_0_destroy_inst_ctx(struct amdgpu_device *adev)
|
||||
* the driver (not loaded into hw).
|
||||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
|
||||
// emulation only, won't work on real chip
|
||||
// sdma 6.0.0 real chip need to use PSP to load firmware
|
||||
static int sdma_v6_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
char fw_name[30];
|
||||
char ucode_prefix[30];
|
||||
int err = 0, i;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct sdma_firmware_header_v2_0 *sdma_hdr;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
@@ -130,43 +98,7 @@ static int sdma_v6_0_init_microcode(struct amdgpu_device *adev)
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
|
||||
|
||||
err = request_firmware(&adev->sdma.instance[0].fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = sdma_v6_0_init_inst_ctx(&adev->sdma.instance[0]);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
for (i = 1; i < adev->sdma.num_instances; i++) {
|
||||
memcpy((void*)&adev->sdma.instance[i],
|
||||
(void*)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
}
|
||||
|
||||
DRM_DEBUG("psp_load == '%s'\n",
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
sdma_hdr = (const struct sdma_firmware_header_v2_0 *)adev->sdma.instance[0].fw->data;
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH0];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH0;
|
||||
info->fw = adev->sdma.instance[0].fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes), PAGE_SIZE);
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH1];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH1;
|
||||
info->fw = adev->sdma.instance[0].fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
DRM_ERROR("sdma_v6_0: Failed to load firmware \"%s\"\n", fw_name);
|
||||
sdma_v6_0_destroy_inst_ctx(adev);
|
||||
}
|
||||
return err;
|
||||
return amdgpu_sdma_init_microcode(adev, fw_name, 0, true);
|
||||
}
|
||||
|
||||
static unsigned sdma_v6_0_ring_init_cond_exec(struct amdgpu_ring *ring)
|
||||
@@ -559,7 +491,8 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
ring = &adev->sdma.instance[i].ring;
|
||||
|
||||
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
|
||||
|
||||
/* Set ring buffer size in dwords */
|
||||
rb_bufsz = order_base_2(ring->ring_size / 4);
|
||||
@@ -593,7 +526,10 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
|
||||
lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
|
||||
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 1);
|
||||
else
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
|
||||
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, F32_WPTR_POLL_ENABLE, 1);
|
||||
|
||||
WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
|
||||
@@ -1365,19 +1301,16 @@ static int sdma_v6_0_sw_fini(void *handle)
|
||||
for (i = 0; i < adev->sdma.num_instances; i++)
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
|
||||
|
||||
sdma_v6_0_destroy_inst_ctx(adev);
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdma_v6_0_hw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = sdma_v6_0_start(adev);
|
||||
|
||||
return r;
|
||||
return sdma_v6_0_start(adev);
|
||||
}
|
||||
|
||||
static int sdma_v6_0_hw_fini(void *handle)
|
||||
|
||||
303
drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
Normal file
303
drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2021 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 "sienna_cichlid.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_dpm.h"
|
||||
#include "amdgpu_job.h"
|
||||
#include "amdgpu_ring.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
static struct amdgpu_reset_handler *
|
||||
sienna_cichlid_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct amdgpu_reset_handler *handler;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
if (reset_context->method != AMD_RESET_METHOD_NONE) {
|
||||
list_for_each_entry(handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == reset_context->method)
|
||||
return handler;
|
||||
}
|
||||
} else {
|
||||
list_for_each_entry(handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == AMD_RESET_METHOD_MODE2 &&
|
||||
adev->pm.fw_version >= 0x3a5500 &&
|
||||
!amdgpu_sriov_vf(adev)) {
|
||||
reset_context->method = AMD_RESET_METHOD_MODE2;
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int sienna_cichlid_mode2_suspend_ip(struct amdgpu_device *adev)
|
||||
{
|
||||
int r, i;
|
||||
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
|
||||
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
||||
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"suspend of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
sienna_cichlid_mode2_prepare_hwcontext(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
int r = 0;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (adev->gfxhub.funcs->mode2_save_regs)
|
||||
adev->gfxhub.funcs->mode2_save_regs(adev);
|
||||
if (adev->gfxhub.funcs->halt)
|
||||
adev->gfxhub.funcs->halt(adev);
|
||||
r = sienna_cichlid_mode2_suspend_ip(adev);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void sienna_cichlid_async_reset(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_reset_handler *handler;
|
||||
struct amdgpu_reset_control *reset_ctl =
|
||||
container_of(work, struct amdgpu_reset_control, reset_work);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
list_for_each_entry(handler, &reset_ctl->reset_handlers,
|
||||
handler_list) {
|
||||
if (handler->reset_method == reset_ctl->active_reset) {
|
||||
dev_dbg(adev->dev, "Resetting device\n");
|
||||
handler->do_reset(adev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int sienna_cichlid_mode2_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
/* disable BM */
|
||||
pci_clear_master(adev->pdev);
|
||||
return amdgpu_dpm_mode2_reset(adev);
|
||||
}
|
||||
|
||||
static int
|
||||
sienna_cichlid_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
int r;
|
||||
|
||||
r = sienna_cichlid_mode2_reset(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"ASIC reset failed with error, %d ", r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sienna_cichlid_mode2_restore_ip(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, r;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
|
||||
r = psp_rlc_autoload_start(psp);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "Failed to start rlc autoload\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Reinit GFXHUB */
|
||||
if (adev->gfxhub.funcs->mode2_restore_regs)
|
||||
adev->gfxhub.funcs->mode2_restore_regs(adev);
|
||||
adev->gfxhub.funcs->init(adev);
|
||||
r = adev->gfxhub.funcs->gart_enable(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "GFXHUB gart reenable failed after reset\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
|
||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"resume of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"resume of IP block <%s> failed %d\n",
|
||||
adev->ip_blocks[i].version->funcs->name, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!(adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type ==
|
||||
AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
|
||||
if (adev->ip_blocks[i].version->funcs->late_init) {
|
||||
r = adev->ip_blocks[i].version->funcs->late_init(
|
||||
(void *)adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev,
|
||||
"late_init of IP block <%s> failed %d after reset\n",
|
||||
adev->ip_blocks[i].version->funcs->name,
|
||||
r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
sienna_cichlid_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle;
|
||||
|
||||
dev_info(tmp_adev->dev,
|
||||
"GPU reset succeeded, trying to resume\n");
|
||||
r = sienna_cichlid_mode2_restore_ip(tmp_adev);
|
||||
if (r)
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Add this ASIC as tracked as reset was already
|
||||
* complete successfully.
|
||||
*/
|
||||
amdgpu_register_gpu_instance(tmp_adev);
|
||||
|
||||
/* Resume RAS */
|
||||
amdgpu_ras_resume(tmp_adev);
|
||||
|
||||
amdgpu_irq_gpu_reset_resume_helper(tmp_adev);
|
||||
|
||||
r = amdgpu_ib_ring_tests(tmp_adev);
|
||||
if (r) {
|
||||
dev_err(tmp_adev->dev,
|
||||
"ib ring test failed (%d).\n", r);
|
||||
r = -EAGAIN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
if (r)
|
||||
return -EAGAIN;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct amdgpu_reset_handler sienna_cichlid_mode2_handler = {
|
||||
.reset_method = AMD_RESET_METHOD_MODE2,
|
||||
.prepare_env = NULL,
|
||||
.prepare_hwcontext = sienna_cichlid_mode2_prepare_hwcontext,
|
||||
.perform_reset = sienna_cichlid_mode2_perform_reset,
|
||||
.restore_hwcontext = sienna_cichlid_mode2_restore_hwcontext,
|
||||
.restore_env = NULL,
|
||||
.do_reset = sienna_cichlid_mode2_reset,
|
||||
};
|
||||
|
||||
int sienna_cichlid_reset_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_reset_control *reset_ctl;
|
||||
|
||||
reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL);
|
||||
if (!reset_ctl)
|
||||
return -ENOMEM;
|
||||
|
||||
reset_ctl->handle = adev;
|
||||
reset_ctl->async_reset = sienna_cichlid_async_reset;
|
||||
reset_ctl->active_reset = AMD_RESET_METHOD_NONE;
|
||||
reset_ctl->get_reset_handler = sienna_cichlid_get_reset_handler;
|
||||
|
||||
INIT_LIST_HEAD(&reset_ctl->reset_handlers);
|
||||
INIT_WORK(&reset_ctl->reset_work, reset_ctl->async_reset);
|
||||
/* Only mode2 is handled through reset control now */
|
||||
amdgpu_reset_add_handler(reset_ctl, &sienna_cichlid_mode2_handler);
|
||||
|
||||
adev->reset_cntl = reset_ctl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sienna_cichlid_reset_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
kfree(adev->reset_cntl);
|
||||
adev->reset_cntl = NULL;
|
||||
return 0;
|
||||
}
|
||||
32
drivers/gpu/drm/amd/amdgpu/sienna_cichlid.h
Normal file
32
drivers/gpu/drm/amd/amdgpu/sienna_cichlid.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SIENNA_CICHLID_H__
|
||||
#define __SIENNA_CICHLID_H__
|
||||
|
||||
#include "amdgpu.h"
|
||||
|
||||
int sienna_cichlid_reset_init(struct amdgpu_device *adev);
|
||||
int sienna_cichlid_reset_fini(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
@@ -179,7 +179,7 @@ void soc21_grbm_select(struct amdgpu_device *adev,
|
||||
grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
|
||||
grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL), grbm_gfx_cntl);
|
||||
WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, grbm_gfx_cntl);
|
||||
}
|
||||
|
||||
static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
|
||||
@@ -583,6 +583,10 @@ static int soc21_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_JPEG |
|
||||
AMD_PG_SUPPORT_ATHUB |
|
||||
AMD_PG_SUPPORT_MMHUB;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
}
|
||||
adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
|
||||
break;
|
||||
case IP_VERSION(11, 0, 2):
|
||||
@@ -629,6 +633,19 @@ static int soc21_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
break;
|
||||
case IP_VERSION(11, 0, 3):
|
||||
adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG |
|
||||
AMD_CG_SUPPORT_JPEG_MGCG;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* hypervisor control CG and PG enablement */
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
}
|
||||
adev->external_rev_id = adev->rev_id + 0x20;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
|
||||
@@ -452,41 +452,47 @@ static void umc_v6_7_query_ras_error_count(struct amdgpu_device *adev,
|
||||
|
||||
static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data,
|
||||
uint32_t umc_reg_offset,
|
||||
uint32_t ch_inst,
|
||||
uint32_t umc_inst)
|
||||
uint32_t umc_reg_offset, uint32_t ch_inst,
|
||||
uint32_t umc_inst, uint64_t mca_addr)
|
||||
{
|
||||
uint32_t mc_umc_status_addr;
|
||||
uint32_t channel_index;
|
||||
uint64_t mc_umc_status, mc_umc_addrt0;
|
||||
uint64_t mc_umc_status = 0, mc_umc_addrt0;
|
||||
uint64_t err_addr, soc_pa, retired_page, column;
|
||||
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
if (mca_addr == UMC_INVALID_ADDR) {
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
|
||||
if (mc_umc_status == 0)
|
||||
return;
|
||||
if (mc_umc_status == 0)
|
||||
return;
|
||||
|
||||
if (!err_data->err_addr) {
|
||||
/* clear umc status */
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
return;
|
||||
if (!err_data->err_addr) {
|
||||
/* clear umc status */
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
channel_index =
|
||||
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
|
||||
/* calculate error address if ue/ce error is detected */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) ||
|
||||
mca_addr != UMC_INVALID_ADDR) {
|
||||
if (mca_addr == UMC_INVALID_ADDR) {
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
err_addr =
|
||||
REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
} else {
|
||||
err_addr = mca_addr;
|
||||
}
|
||||
|
||||
/* translate umc channel address to soc pa, 3 parts are included */
|
||||
soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
|
||||
@@ -501,7 +507,8 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
|
||||
|
||||
/* we only save ue error information currently, ce is skipped */
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
|
||||
== 1) {
|
||||
== 1 ||
|
||||
mca_addr != UMC_INVALID_ADDR) {
|
||||
/* loop for all possibilities of [C4 C3 C2] */
|
||||
for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
|
||||
retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
|
||||
@@ -519,7 +526,8 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
/* clear umc status */
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
if (mca_addr == UMC_INVALID_ADDR)
|
||||
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
|
||||
}
|
||||
|
||||
static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev,
|
||||
@@ -540,9 +548,8 @@ static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev,
|
||||
ch_inst);
|
||||
umc_v6_7_query_error_address(adev,
|
||||
err_data,
|
||||
umc_reg_offset,
|
||||
ch_inst,
|
||||
umc_inst);
|
||||
umc_reg_offset, ch_inst,
|
||||
umc_inst, UMC_INVALID_ADDR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,4 +590,5 @@ struct amdgpu_umc_ras umc_v6_7_ras = {
|
||||
.query_ras_poison_mode = umc_v6_7_query_ras_poison_mode,
|
||||
.ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count,
|
||||
.ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address,
|
||||
.convert_ras_error_address = umc_v6_7_query_error_address,
|
||||
};
|
||||
|
||||
@@ -101,22 +101,16 @@ static void umc_v8_10_query_correctable_error_count(struct amdgpu_device *adev,
|
||||
uint32_t umc_reg_offset,
|
||||
unsigned long *error_count)
|
||||
{
|
||||
uint32_t ecc_err_cnt, ecc_err_cnt_addr;
|
||||
uint64_t mc_umc_status;
|
||||
uint32_t mc_umc_status_addr;
|
||||
|
||||
/* UMC 8_10 registers */
|
||||
ecc_err_cnt_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regUMCCH0_0_GeccErrCnt);
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
|
||||
ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
|
||||
*error_count +=
|
||||
(REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_GeccErrCnt, GeccErrCnt) -
|
||||
UMC_V8_10_CE_CNT_INIT);
|
||||
|
||||
/* Check for SRAM correctable error, MCUMC_STATUS is a 64 bit register */
|
||||
/* Rely on MCUMC_STATUS for correctable error counter
|
||||
* MCUMC_STATUS is a 64 bit register
|
||||
*/
|
||||
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
|
||||
|
||||
@@ -1761,21 +1761,23 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = {
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
};
|
||||
|
||||
static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p)
|
||||
static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct drm_gpu_scheduler **scheds;
|
||||
|
||||
/* The create msg must be in the first IB submitted */
|
||||
if (atomic_read(&p->entity->fence_seq))
|
||||
if (atomic_read(&job->base.entity->fence_seq))
|
||||
return -EINVAL;
|
||||
|
||||
scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC]
|
||||
[AMDGPU_RING_PRIO_DEFAULT].sched;
|
||||
drm_sched_entity_modify_sched(p->entity, scheds, 1);
|
||||
drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
|
||||
static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||
uint64_t addr)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_bo_va_mapping *map;
|
||||
@@ -1846,7 +1848,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
|
||||
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
|
||||
continue;
|
||||
|
||||
r = vcn_v3_0_limit_sched(p);
|
||||
r = vcn_v3_0_limit_sched(p, job);
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
@@ -1860,7 +1862,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
|
||||
struct amdgpu_ring *ring = amdgpu_job_ring(job);
|
||||
uint32_t msg_lo = 0, msg_hi = 0;
|
||||
unsigned i;
|
||||
int r;
|
||||
@@ -1879,7 +1881,8 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
|
||||
msg_hi = val;
|
||||
} else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0) &&
|
||||
val == 0) {
|
||||
r = vcn_v3_0_dec_msg(p, ((u64)msg_hi) << 32 | msg_lo);
|
||||
r = vcn_v3_0_dec_msg(p, job,
|
||||
((u64)msg_hi) << 32 | msg_lo);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "soc15d.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "vcn_v2_0.h"
|
||||
#include "mmsch_v4_0.h"
|
||||
|
||||
#include "vcn/vcn_4_0_0_offset.h"
|
||||
#include "vcn/vcn_4_0_0_sh_mask.h"
|
||||
@@ -45,6 +46,8 @@
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48300
|
||||
|
||||
#define VCN_HARVEST_MMSCH 0
|
||||
|
||||
#define RDECODE_MSG_CREATE 0x00000000
|
||||
#define RDECODE_MESSAGE_CREATE 0x00000001
|
||||
|
||||
@@ -53,12 +56,14 @@ static int amdgpu_ih_clientid_vcns[] = {
|
||||
SOC15_IH_CLIENTID_VCN1
|
||||
};
|
||||
|
||||
static int vcn_v4_0_start_sriov(struct amdgpu_device *adev);
|
||||
static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int vcn_v4_0_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state);
|
||||
static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring);
|
||||
|
||||
/**
|
||||
* vcn_v4_0_early_init - set function pointers
|
||||
@@ -71,6 +76,9 @@ static int vcn_v4_0_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->vcn.harvest_config = VCN_HARVEST_MMSCH;
|
||||
|
||||
/* re-use enc ring as unified ring */
|
||||
adev->vcn.num_enc_rings = 1;
|
||||
|
||||
@@ -92,6 +100,7 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
struct amdgpu_ring *ring;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i, r;
|
||||
int vcn_doorbell_index = 0;
|
||||
|
||||
r = amdgpu_vcn_sw_init(adev);
|
||||
if (r)
|
||||
@@ -103,6 +112,12 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
|
||||
/* get DWORD offset */
|
||||
vcn_doorbell_index = vcn_doorbell_index << 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
|
||||
@@ -119,7 +134,10 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_enc[0];
|
||||
ring->use_doorbell = true;
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1;
|
||||
else
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
|
||||
|
||||
sprintf(ring->name, "vcn_unified_%d", i);
|
||||
|
||||
@@ -132,10 +150,23 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
|
||||
fw_shared->sq.is_enabled = 1;
|
||||
|
||||
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
|
||||
fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
|
||||
AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
|
||||
|
||||
if (amdgpu_vcnfw_log)
|
||||
amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
r = amdgpu_virt_alloc_mm_table(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
|
||||
|
||||
@@ -169,6 +200,9 @@ static int vcn_v4_0_sw_fini(void *handle)
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_free_mm_table(adev);
|
||||
|
||||
r = amdgpu_vcn_suspend(adev);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -191,18 +225,42 @@ static int vcn_v4_0_hw_init(void *handle)
|
||||
struct amdgpu_ring *ring;
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_enc[0];
|
||||
|
||||
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
|
||||
((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
|
||||
|
||||
r = amdgpu_ring_test_helper(ring);
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
r = vcn_v4_0_start_sriov(adev);
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_enc[0];
|
||||
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
|
||||
ring->sched.ready = false;
|
||||
ring->no_scheduler = true;
|
||||
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
|
||||
} else {
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v4_0_unified_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_enc[0];
|
||||
|
||||
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
|
||||
((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
|
||||
|
||||
r = amdgpu_ring_test_helper(ring);
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -230,12 +288,14 @@ static int vcn_v4_0_hw_fini(void *handle)
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
|
||||
(adev->vcn.cur_state != AMD_PG_STATE_GATE &&
|
||||
RREG32_SOC15(VCN, i, regUVD_STATUS))) {
|
||||
vcn_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1107,6 +1167,214 @@ static int vcn_v4_0_start(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
struct amdgpu_ring *ring_enc;
|
||||
uint64_t cache_addr;
|
||||
uint64_t rb_enc_addr;
|
||||
uint64_t ctx_addr;
|
||||
uint32_t param, resp, expected;
|
||||
uint32_t offset, cache_size;
|
||||
uint32_t tmp, timeout;
|
||||
|
||||
struct amdgpu_mm_table *table = &adev->virt.mm_table;
|
||||
uint32_t *table_loc;
|
||||
uint32_t table_size;
|
||||
uint32_t size, size_dw;
|
||||
uint32_t init_status;
|
||||
uint32_t enabled_vcn;
|
||||
|
||||
struct mmsch_v4_0_cmd_direct_write
|
||||
direct_wt = { {0} };
|
||||
struct mmsch_v4_0_cmd_direct_read_modify_write
|
||||
direct_rd_mod_wt = { {0} };
|
||||
struct mmsch_v4_0_cmd_end end = { {0} };
|
||||
struct mmsch_v4_0_init_header header;
|
||||
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
volatile struct amdgpu_fw_shared_rb_setup *rb_setup;
|
||||
|
||||
direct_wt.cmd_header.command_type =
|
||||
MMSCH_COMMAND__DIRECT_REG_WRITE;
|
||||
direct_rd_mod_wt.cmd_header.command_type =
|
||||
MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
|
||||
end.cmd_header.command_type =
|
||||
MMSCH_COMMAND__END;
|
||||
|
||||
header.version = MMSCH_VERSION;
|
||||
header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2;
|
||||
for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
|
||||
header.inst[i].init_status = 0;
|
||||
header.inst[i].table_offset = 0;
|
||||
header.inst[i].table_size = 0;
|
||||
}
|
||||
|
||||
table_loc = (uint32_t *)table->cpu_addr;
|
||||
table_loc += header.total_size;
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
table_size = 0;
|
||||
|
||||
MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_STATUS),
|
||||
~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
|
||||
|
||||
cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
|
||||
offset = 0;
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_OFFSET0),
|
||||
0);
|
||||
} else {
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst[i].gpu_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst[i].gpu_addr));
|
||||
offset = cache_size;
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_OFFSET0),
|
||||
AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
|
||||
}
|
||||
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_SIZE0),
|
||||
cache_size);
|
||||
|
||||
cache_addr = adev->vcn.inst[i].gpu_addr + offset;
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
|
||||
lower_32_bits(cache_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
|
||||
upper_32_bits(cache_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_OFFSET1),
|
||||
0);
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_SIZE1),
|
||||
AMDGPU_VCN_STACK_SIZE);
|
||||
|
||||
cache_addr = adev->vcn.inst[i].gpu_addr + offset +
|
||||
AMDGPU_VCN_STACK_SIZE;
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
|
||||
lower_32_bits(cache_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
|
||||
upper_32_bits(cache_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_OFFSET2),
|
||||
0);
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_CACHE_SIZE2),
|
||||
AMDGPU_VCN_CONTEXT_SIZE);
|
||||
|
||||
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
|
||||
rb_setup = &fw_shared->rb_setup;
|
||||
|
||||
ring_enc = &adev->vcn.inst[i].ring_enc[0];
|
||||
ring_enc->wptr = 0;
|
||||
rb_enc_addr = ring_enc->gpu_addr;
|
||||
|
||||
rb_setup->is_rb_enabled_flags |= RB_ENABLED;
|
||||
rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
|
||||
rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
|
||||
rb_setup->rb_size = ring_enc->ring_size / 4;
|
||||
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
|
||||
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
|
||||
MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
regUVD_VCPU_NONCACHE_SIZE0),
|
||||
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
|
||||
|
||||
/* add end packet */
|
||||
MMSCH_V4_0_INSERT_END();
|
||||
|
||||
/* refine header */
|
||||
header.inst[i].init_status = 0;
|
||||
header.inst[i].table_offset = header.total_size;
|
||||
header.inst[i].table_size = table_size;
|
||||
header.total_size += table_size;
|
||||
}
|
||||
|
||||
/* Update init table header in memory */
|
||||
size = sizeof(struct mmsch_v4_0_init_header);
|
||||
table_loc = (uint32_t *)table->cpu_addr;
|
||||
memcpy((void *)table_loc, &header, size);
|
||||
|
||||
/* message MMSCH (in VCN[0]) to initialize this client
|
||||
* 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
|
||||
* of memory descriptor location
|
||||
*/
|
||||
ctx_addr = table->gpu_addr;
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
|
||||
|
||||
/* 2, update vmid of descriptor */
|
||||
tmp = RREG32_SOC15(VCN, 0, regMMSCH_VF_VMID);
|
||||
tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
|
||||
/* use domain0 for MM scheduler */
|
||||
tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_VMID, tmp);
|
||||
|
||||
/* 3, notify mmsch about the size of this descriptor */
|
||||
size = header.total_size;
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE, size);
|
||||
|
||||
/* 4, set resp to zero */
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP, 0);
|
||||
|
||||
/* 5, kick off the initialization and wait until
|
||||
* MMSCH_VF_MAILBOX_RESP becomes non-zero
|
||||
*/
|
||||
param = 0x00000001;
|
||||
WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_HOST, param);
|
||||
tmp = 0;
|
||||
timeout = 1000;
|
||||
resp = 0;
|
||||
expected = MMSCH_VF_MAILBOX_RESP__OK;
|
||||
while (resp != expected) {
|
||||
resp = RREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP);
|
||||
if (resp != 0)
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
tmp = tmp + 10;
|
||||
if (tmp >= timeout) {
|
||||
DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
|
||||
" waiting for regMMSCH_VF_MAILBOX_RESP "\
|
||||
"(expected=0x%08x, readback=0x%08x)\n",
|
||||
tmp, expected, resp);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0;
|
||||
init_status = ((struct mmsch_v4_0_init_header *)(table_loc))->inst[enabled_vcn].init_status;
|
||||
if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE
|
||||
&& init_status != MMSCH_VF_ENGINE_STATUS__PASS)
|
||||
DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\
|
||||
"status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode
|
||||
*
|
||||
@@ -1327,21 +1595,23 @@ static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
}
|
||||
}
|
||||
|
||||
static int vcn_v4_0_limit_sched(struct amdgpu_cs_parser *p)
|
||||
static int vcn_v4_0_limit_sched(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct drm_gpu_scheduler **scheds;
|
||||
|
||||
/* The create msg must be in the first IB submitted */
|
||||
if (atomic_read(&p->entity->fence_seq))
|
||||
if (atomic_read(&job->base.entity->fence_seq))
|
||||
return -EINVAL;
|
||||
|
||||
scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC]
|
||||
[AMDGPU_RING_PRIO_0].sched;
|
||||
drm_sched_entity_modify_sched(p->entity, scheds, 1);
|
||||
drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
|
||||
static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
|
||||
uint64_t addr)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_bo_va_mapping *map;
|
||||
@@ -1412,7 +1682,7 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
|
||||
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
|
||||
continue;
|
||||
|
||||
r = vcn_v4_0_limit_sched(p);
|
||||
r = vcn_v4_0_limit_sched(p, job);
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
@@ -1425,32 +1695,34 @@ out:
|
||||
#define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003)
|
||||
|
||||
static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib)
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_ib *ib)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
|
||||
struct amdgpu_vcn_decode_buffer *decode_buffer = NULL;
|
||||
struct amdgpu_ring *ring = amdgpu_job_ring(job);
|
||||
struct amdgpu_vcn_decode_buffer *decode_buffer;
|
||||
uint64_t addr;
|
||||
uint32_t val;
|
||||
int r = 0;
|
||||
|
||||
/* The first instance can decode anything */
|
||||
if (!ring->me)
|
||||
return r;
|
||||
return 0;
|
||||
|
||||
/* unified queue ib header has 8 double words. */
|
||||
if (ib->length_dw < 8)
|
||||
return r;
|
||||
return 0;
|
||||
|
||||
val = amdgpu_ib_get_value(ib, 6); //RADEON_VCN_ENGINE_TYPE
|
||||
if (val != RADEON_VCN_ENGINE_TYPE_DECODE)
|
||||
return 0;
|
||||
|
||||
if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
|
||||
decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[10];
|
||||
decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[10];
|
||||
|
||||
if (decode_buffer->valid_buf_flag & 0x1)
|
||||
r = vcn_v4_0_dec_msg(p, ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
|
||||
decode_buffer->msg_buffer_address_lo);
|
||||
}
|
||||
return r;
|
||||
if (!(decode_buffer->valid_buf_flag & 0x1))
|
||||
return 0;
|
||||
|
||||
addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
|
||||
decode_buffer->msg_buffer_address_lo;
|
||||
return vcn_v4_0_dec_msg(p, job, addr);
|
||||
}
|
||||
|
||||
static const struct amdgpu_ring_funcs vcn_v4_0_unified_ring_vm_funcs = {
|
||||
@@ -1596,6 +1868,15 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
/* for SRIOV, guest should not control VCN Power-gating
|
||||
* MMSCH FW should control Power-gating and clock-gating
|
||||
* guest should avoid touching CGC and PG
|
||||
*/
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(state == adev->vcn.cur_state)
|
||||
return 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user