Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
ab95cb3
Documentation
LICENSES
arch
block
certs
crypto
drivers
accessibility
acpi
amba
android
ata
atm
auxdisplay
base
bcma
block
bluetooth
bus
cdrom
char
clk
clocksource
comedi
connector
counter
cpufreq
cpuidle
crypto
cxl
dax
dca
devfreq
dio
dma-buf
dma
edac
eisa
extcon
firewire
firmware
fpga
fsi
gnss
gpio
gpu
drm
amd
acp
amdgpu
Kconfig
Makefile
ObjectID.h
aldebaran.c
aldebaran.h
aldebaran_reg_init.c
amdgpu.h
amdgpu_acp.c
amdgpu_acp.h
amdgpu_acpi.c
amdgpu_afmt.c
amdgpu_amdkfd.c
amdgpu_amdkfd.h
amdgpu_amdkfd_aldebaran.c
amdgpu_amdkfd_arcturus.c
amdgpu_amdkfd_arcturus.h
amdgpu_amdkfd_fence.c
amdgpu_amdkfd_gfx_v10.c
amdgpu_amdkfd_gfx_v10_3.c
amdgpu_amdkfd_gfx_v7.c
amdgpu_amdkfd_gfx_v8.c
amdgpu_amdkfd_gfx_v9.c
amdgpu_amdkfd_gfx_v9.h
amdgpu_amdkfd_gpuvm.c
amdgpu_atombios.c
amdgpu_atombios.h
amdgpu_atomfirmware.c
amdgpu_atomfirmware.h
amdgpu_atpx_handler.c
amdgpu_benchmark.c
amdgpu_bios.c
amdgpu_bo_list.c
amdgpu_bo_list.h
amdgpu_cgs.c
amdgpu_connectors.c
amdgpu_connectors.h
amdgpu_cs.c
amdgpu_csa.c
amdgpu_csa.h
amdgpu_ctx.c
amdgpu_ctx.h
amdgpu_debugfs.c
amdgpu_debugfs.h
amdgpu_device.c
amdgpu_df.h
amdgpu_discovery.c
amdgpu_discovery.h
amdgpu_display.c
amdgpu_display.h
amdgpu_dma_buf.c
amdgpu_dma_buf.h
amdgpu_doorbell.h
amdgpu_drv.c
amdgpu_drv.h
amdgpu_encoders.c
amdgpu_fb.c
amdgpu_fence.c
amdgpu_fru_eeprom.c
amdgpu_fru_eeprom.h
amdgpu_fw_attestation.c
amdgpu_fw_attestation.h
amdgpu_gart.c
amdgpu_gart.h
amdgpu_gds.h
amdgpu_gem.c
amdgpu_gem.h
amdgpu_gfx.c
amdgpu_gfx.h
amdgpu_gfxhub.h
amdgpu_gmc.c
amdgpu_gmc.h
amdgpu_gtt_mgr.c
amdgpu_hdp.h
amdgpu_i2c.c
amdgpu_i2c.h
amdgpu_ib.c
amdgpu_ids.c
amdgpu_ids.h
amdgpu_ih.c
amdgpu_ih.h
amdgpu_ioc32.c
amdgpu_irq.c
amdgpu_irq.h
amdgpu_job.c
amdgpu_job.h
amdgpu_jpeg.c
amdgpu_jpeg.h
amdgpu_kms.c
amdgpu_mes.h
amdgpu_mmhub.c
amdgpu_mmhub.h
amdgpu_mn.c
amdgpu_mn.h
amdgpu_mode.h
amdgpu_nbio.c
amdgpu_nbio.h
amdgpu_object.c
amdgpu_object.h
amdgpu_pll.c
amdgpu_pll.h
amdgpu_pmu.c
amdgpu_pmu.h
amdgpu_psp.c
amdgpu_psp.h
amdgpu_rap.c
amdgpu_rap.h
amdgpu_ras.c
amdgpu_ras.h
amdgpu_ras_eeprom.c
amdgpu_ras_eeprom.h
amdgpu_res_cursor.h
amdgpu_reset.c
amdgpu_reset.h
amdgpu_ring.c
amdgpu_ring.h
amdgpu_rlc.c
amdgpu_rlc.h
amdgpu_sa.c
amdgpu_sched.c
amdgpu_sched.h
amdgpu_sdma.c
amdgpu_sdma.h
amdgpu_securedisplay.c
amdgpu_securedisplay.h
amdgpu_smuio.h
amdgpu_socbb.h
amdgpu_sync.c
amdgpu_sync.h
amdgpu_test.c
amdgpu_trace.h
amdgpu_trace_points.c
amdgpu_ttm.c
amdgpu_ttm.h
amdgpu_ucode.c
amdgpu_ucode.h
amdgpu_umc.c
amdgpu_umc.h
amdgpu_uvd.c
amdgpu_uvd.h
amdgpu_vce.c
amdgpu_vce.h
amdgpu_vcn.c
amdgpu_vcn.h
amdgpu_vf_error.c
amdgpu_vf_error.h
amdgpu_virt.c
amdgpu_virt.h
amdgpu_vm.c
amdgpu_vm.h
amdgpu_vm_cpu.c
amdgpu_vm_sdma.c
amdgpu_vram_mgr.c
amdgpu_xgmi.c
amdgpu_xgmi.h
amdgv_sriovmsg.h
arct_reg_init.c
athub_v1_0.c
athub_v1_0.h
athub_v2_0.c
athub_v2_0.h
athub_v2_1.c
athub_v2_1.h
atom.c
atom.h
atombios_crtc.c
atombios_crtc.h
atombios_dp.c
atombios_dp.h
atombios_encoders.c
atombios_encoders.h
atombios_i2c.c
atombios_i2c.h
cik.c
cik.h
cik_ih.c
cik_ih.h
cik_sdma.c
cik_sdma.h
cikd.h
clearstate_ci.h
clearstate_defs.h
clearstate_gfx10.h
clearstate_gfx9.h
clearstate_si.h
clearstate_vi.h
cz_ih.c
cz_ih.h
dce_v10_0.c
dce_v10_0.h
dce_v11_0.c
dce_v11_0.h
dce_v6_0.c
dce_v6_0.h
dce_v8_0.c
dce_v8_0.h
dce_virtual.c
dce_virtual.h
df_v1_7.c
df_v1_7.h
df_v3_6.c
df_v3_6.h
dimgrey_cavefish_reg_init.c
emu_soc.c
gfx_v10_0.c
gfx_v10_0.h
gfx_v6_0.c
gfx_v6_0.h
gfx_v7_0.c
gfx_v7_0.h
gfx_v8_0.c
gfx_v8_0.h
gfx_v9_0.c
gfx_v9_0.h
gfx_v9_4.c
gfx_v9_4.h
gfx_v9_4_2.c
gfx_v9_4_2.h
gfxhub_v1_0.c
gfxhub_v1_0.h
gfxhub_v1_1.c
gfxhub_v1_1.h
gfxhub_v2_0.c
gfxhub_v2_0.h
gfxhub_v2_1.c
gfxhub_v2_1.h
gmc_v10_0.c
gmc_v10_0.h
gmc_v6_0.c
gmc_v6_0.h
gmc_v7_0.c
gmc_v7_0.h
gmc_v8_0.c
gmc_v8_0.h
gmc_v9_0.c
gmc_v9_0.h
hdp_v4_0.c
hdp_v4_0.h
hdp_v5_0.c
hdp_v5_0.h
iceland_ih.c
iceland_ih.h
iceland_sdma_pkt_open.h
jpeg_v1_0.c
jpeg_v1_0.h
jpeg_v2_0.c
jpeg_v2_0.h
jpeg_v2_5.c
jpeg_v2_5.h
jpeg_v3_0.c
jpeg_v3_0.h
mes_api_def.h
mes_v10_1.c
mes_v10_1.h
mmhub_v1_0.c
mmhub_v1_0.h
mmhub_v1_7.c
mmhub_v1_7.h
mmhub_v2_0.c
mmhub_v2_0.h
mmhub_v2_3.c
mmhub_v2_3.h
mmhub_v9_4.c
mmhub_v9_4.h
mmsch_v1_0.h
mmsch_v2_0.h
mmsch_v3_0.h
mxgpu_ai.c
mxgpu_ai.h
mxgpu_nv.c
mxgpu_nv.h
mxgpu_vi.c
mxgpu_vi.h
navi10_ih.c
navi10_ih.h
navi10_reg_init.c
navi10_sdma_pkt_open.h
navi12_reg_init.c
navi14_reg_init.c
nbio_v2_3.c
nbio_v2_3.h
nbio_v6_1.c
nbio_v6_1.h
nbio_v7_0.c
nbio_v7_0.h
nbio_v7_2.c
nbio_v7_2.h
nbio_v7_4.c
nbio_v7_4.h
nv.c
nv.h
nvd.h
psp_gfx_if.h
psp_v10_0.c
psp_v10_0.h
psp_v11_0.c
psp_v11_0.h
psp_v12_0.c
psp_v12_0.h
psp_v13_0.c
psp_v13_0.h
psp_v3_1.c
psp_v3_1.h
sdma_common.h
sdma_v2_4.c
sdma_v2_4.h
sdma_v3_0.c
sdma_v3_0.h
sdma_v4_0.c
sdma_v4_0.h
sdma_v4_4.c
sdma_v4_4.h
sdma_v5_0.c
sdma_v5_0.h
sdma_v5_2.c
sdma_v5_2.h
si.c
si.h
si_dma.c
si_dma.h
si_enums.h
si_ih.c
si_ih.h
sid.h
sienna_cichlid_reg_init.c
smu_v11_0_i2c.c
smu_v11_0_i2c.h
smuio_v11_0.c
smuio_v11_0.h
smuio_v11_0_6.c
smuio_v11_0_6.h
smuio_v13_0.c
smuio_v13_0.h
smuio_v9_0.c
smuio_v9_0.h
soc15.c
soc15.h
soc15_common.h
soc15d.h
ta_rap_if.h
ta_ras_if.h
ta_secureDisplay_if.h
ta_xgmi_if.h
tonga_ih.c
tonga_ih.h
tonga_sdma_pkt_open.h
umc_v6_0.c
umc_v6_0.h
umc_v6_1.c
umc_v6_1.h
umc_v6_7.c
umc_v6_7.h
umc_v8_7.c
umc_v8_7.h
uvd_v3_1.c
uvd_v3_1.h
uvd_v4_2.c
uvd_v4_2.h
uvd_v5_0.c
uvd_v5_0.h
uvd_v6_0.c
uvd_v6_0.h
uvd_v7_0.c
uvd_v7_0.h
vangogh_reg_init.c
vce_v2_0.c
vce_v2_0.h
vce_v3_0.c
vce_v3_0.h
vce_v4_0.c
vce_v4_0.h
vcn_v1_0.c
vcn_v1_0.h
vcn_v2_0.c
vcn_v2_0.h
vcn_v2_5.c
vcn_v2_5.h
vcn_v3_0.c
vcn_v3_0.h
vega10_ih.c
vega10_ih.h
vega10_reg_init.c
vega10_sdma_pkt_open.h
vega20_ih.c
vega20_ih.h
vega20_reg_init.c
vi.c
vi.h
vid.h
amdkfd
display
include
pm
arm
armada
aspeed
ast
atmel-hlcdc
bochs
bridge
etnaviv
exynos
fsl-dcu
gma500
gud
hisilicon
i2c
i810
i915
imx
ingenic
kmb
lib
lima
mcde
mediatek
meson
mga
mgag200
msm
mxsfb
nouveau
omapdrm
panel
panfrost
pl111
qxl
r128
radeon
rcar-du
rockchip
savage
scheduler
selftests
shmobile
sis
sti
stm
sun4i
tdfx
tegra
tidss
tilcdc
tiny
ttm
tve200
udl
v3d
vboxvideo
vc4
vgem
via
virtio
vkms
vmwgfx
xen
xlnx
zte
Kconfig
Makefile
drm_agpsupport.c
drm_atomic.c
drm_atomic_helper.c
drm_atomic_state_helper.c
drm_atomic_uapi.c
drm_auth.c
drm_blend.c
drm_bridge.c
drm_bridge_connector.c
drm_bufs.c
drm_cache.c
drm_client.c
drm_client_modeset.c
drm_color_mgmt.c
drm_connector.c
drm_context.c
drm_crtc.c
drm_crtc_helper.c
drm_crtc_helper_internal.h
drm_crtc_internal.h
drm_damage_helper.c
drm_debugfs.c
drm_debugfs_crc.c
drm_displayid.c
drm_dma.c
drm_dp_aux_dev.c
drm_dp_cec.c
drm_dp_dual_mode_helper.c
drm_dp_helper.c
drm_dp_mst_topology.c
drm_dp_mst_topology_internal.h
drm_drv.c
drm_dsc.c
drm_dumb_buffers.c
drm_edid.c
drm_edid_load.c
drm_encoder.c
drm_encoder_slave.c
drm_fb_cma_helper.c
drm_fb_helper.c
drm_file.c
drm_flip_work.c
drm_format_helper.c
drm_fourcc.c
drm_framebuffer.c
drm_gem.c
drm_gem_atomic_helper.c
drm_gem_cma_helper.c
drm_gem_framebuffer_helper.c
drm_gem_shmem_helper.c
drm_gem_ttm_helper.c
drm_gem_vram_helper.c
drm_hashtab.c
drm_hdcp.c
drm_internal.h
drm_ioc32.c
drm_ioctl.c
drm_irq.c
drm_kms_helper_common.c
drm_lease.c
drm_legacy.h
drm_legacy_misc.c
drm_lock.c
drm_managed.c
drm_memory.c
drm_mipi_dbi.c
drm_mipi_dsi.c
drm_mm.c
drm_mode_config.c
drm_mode_object.c
drm_modes.c
drm_modeset_helper.c
drm_modeset_lock.c
drm_of.c
drm_panel.c
drm_panel_orientation_quirks.c
drm_pci.c
drm_plane.c
drm_plane_helper.c
drm_prime.c
drm_print.c
drm_probe_helper.c
drm_property.c
drm_rect.c
drm_scatter.c
drm_scdc_helper.c
drm_self_refresh_helper.c
drm_simple_kms_helper.c
drm_syncobj.c
drm_sysfs.c
drm_trace.h
drm_trace_points.c
drm_vblank.c
drm_vblank_work.c
drm_vm.c
drm_vma_manager.c
drm_writeback.c
host1x
ipu-v3
trace
vga
Makefile
greybus
hid
hsi
hv
hwmon
hwspinlock
hwtracing
i2c
i3c
ide
idle
iio
infiniband
input
interconnect
iommu
ipack
irqchip
isdn
leds
lightnvm
macintosh
mailbox
mcb
md
media
memory
memstick
message
mfd
misc
mmc
most
mtd
mux
net
nfc
ntb
nubus
nvdimm
nvme
nvmem
of
opp
parisc
parport
pci
pcmcia
perf
phy
pinctrl
platform
pnp
power
powercap
pps
ps3
ptp
pwm
rapidio
ras
regulator
remoteproc
reset
rpmsg
rtc
s390
sbus
scsi
sh
siox
slimbus
soc
soundwire
spi
spmi
ssb
staging
target
tc
tee
thermal
thunderbolt
tty
uio
usb
vdpa
vfio
vhost
video
virt
virtio
visorbus
vlynq
vme
w1
watchdog
xen
zorro
Kconfig
Makefile
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.clang-format
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
drivers
/
gpu
/
drm
/
amd
/
amdgpu
/
soc15.c
Copy path
Blame
Blame
Latest commit
History
History
1805 lines (1589 loc) · 50.3 KB
Breadcrumbs
linux
/
drivers
/
gpu
/
drm
/
amd
/
amdgpu
/
soc15.c
Top
File metadata and controls
Code
Blame
1805 lines (1589 loc) · 50.3 KB
Raw
/* * Copyright 2016 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 <linux/firmware.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/pci.h> #include <drm/amdgpu_drm.h> #include "amdgpu.h" #include "amdgpu_atombios.h" #include "amdgpu_ih.h" #include "amdgpu_uvd.h" #include "amdgpu_vce.h" #include "amdgpu_ucode.h" #include "amdgpu_psp.h" #include "atom.h" #include "amd_pcie.h" #include "uvd/uvd_7_0_offset.h" #include "gc/gc_9_0_offset.h" #include "gc/gc_9_0_sh_mask.h" #include "sdma0/sdma0_4_0_offset.h" #include "sdma1/sdma1_4_0_offset.h" #include "nbio/nbio_7_0_default.h" #include "nbio/nbio_7_0_offset.h" #include "nbio/nbio_7_0_sh_mask.h" #include "nbio/nbio_7_0_smn.h" #include "mp/mp_9_0_offset.h" #include "soc15.h" #include "soc15_common.h" #include "gfx_v9_0.h" #include "gmc_v9_0.h" #include "gfxhub_v1_0.h" #include "mmhub_v1_0.h" #include "df_v1_7.h" #include "df_v3_6.h" #include "nbio_v6_1.h" #include "nbio_v7_0.h" #include "nbio_v7_4.h" #include "hdp_v4_0.h" #include "vega10_ih.h" #include "vega20_ih.h" #include "navi10_ih.h" #include "sdma_v4_0.h" #include "uvd_v7_0.h" #include "vce_v4_0.h" #include "vcn_v1_0.h" #include "vcn_v2_0.h" #include "jpeg_v2_0.h" #include "vcn_v2_5.h" #include "jpeg_v2_5.h" #include "smuio_v9_0.h" #include "smuio_v11_0.h" #include "smuio_v13_0.h" #include "dce_virtual.h" #include "mxgpu_ai.h" #include "amdgpu_ras.h" #include "amdgpu_xgmi.h" #include <uapi/linux/kfd_ioctl.h> #define mmMP0_MISC_CGTT_CTRL0 0x01b9 #define mmMP0_MISC_CGTT_CTRL0_BASE_IDX 0 #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 /* Vega, Raven, Arcturus */ static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = { { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, .max_width = 4096, .max_height = 2304, .max_pixels_per_frame = 4096 * 2304, .max_level = 0, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, .max_width = 4096, .max_height = 2304, .max_pixels_per_frame = 4096 * 2304, .max_level = 0, }, }; static const struct amdgpu_video_codecs vega_video_codecs_encode = { .codec_count = ARRAY_SIZE(vega_video_codecs_encode_array), .codec_array = vega_video_codecs_encode_array, }; /* Vega */ static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = { { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 3, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 5, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 52, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 4, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 186, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 0, }, }; static const struct amdgpu_video_codecs vega_video_codecs_decode = { .codec_count = ARRAY_SIZE(vega_video_codecs_decode_array), .codec_array = vega_video_codecs_decode_array, }; /* Raven */ static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = { { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 3, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 5, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 52, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 4, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 186, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 0, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 0, }, }; static const struct amdgpu_video_codecs rv_video_codecs_decode = { .codec_count = ARRAY_SIZE(rv_video_codecs_decode_array), .codec_array = rv_video_codecs_decode_array, }; /* Renoir, Arcturus */ static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = { { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 3, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 5, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 52, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 4, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, .max_width = 8192, .max_height = 4352, .max_pixels_per_frame = 4096 * 4096, .max_level = 186, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, .max_width = 4096, .max_height = 4096, .max_pixels_per_frame = 4096 * 4096, .max_level = 0, }, { .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, .max_width = 8192, .max_height = 4352, .max_pixels_per_frame = 4096 * 4096, .max_level = 0, }, }; static const struct amdgpu_video_codecs rn_video_codecs_decode = { .codec_count = ARRAY_SIZE(rn_video_codecs_decode_array), .codec_array = rn_video_codecs_decode_array, }; static int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode, const struct amdgpu_video_codecs **codecs) { switch (adev->asic_type) { case CHIP_VEGA20: case CHIP_VEGA10: case CHIP_VEGA12: if (encode) *codecs = &vega_video_codecs_encode; else *codecs = &vega_video_codecs_decode; return 0; case CHIP_RAVEN: if (encode) *codecs = &vega_video_codecs_encode; else *codecs = &rv_video_codecs_decode; return 0; case CHIP_ARCTURUS: case CHIP_ALDEBARAN: case CHIP_RENOIR: if (encode) *codecs = &vega_video_codecs_encode; else *codecs = &rn_video_codecs_decode; return 0; default: return -EINVAL; } } /* * Indirect registers accessor */ static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long address, data; address = adev->nbio.funcs->get_pcie_index_offset(adev); data = adev->nbio.funcs->get_pcie_data_offset(adev); return amdgpu_device_indirect_rreg(adev, address, data, reg); } static void soc15_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long address, data; address = adev->nbio.funcs->get_pcie_index_offset(adev); data = adev->nbio.funcs->get_pcie_data_offset(adev); amdgpu_device_indirect_wreg(adev, address, data, reg, v); } static u64 soc15_pcie_rreg64(struct amdgpu_device *adev, u32 reg) { unsigned long address, data; address = adev->nbio.funcs->get_pcie_index_offset(adev); data = adev->nbio.funcs->get_pcie_data_offset(adev); return amdgpu_device_indirect_rreg64(adev, address, data, reg); } static void soc15_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) { unsigned long address, data; address = adev->nbio.funcs->get_pcie_index_offset(adev); data = adev->nbio.funcs->get_pcie_data_offset(adev); amdgpu_device_indirect_wreg64(adev, address, data, reg, v); } static u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long flags, address, data; u32 r; address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); WREG32(address, ((reg) & 0x1ff)); r = RREG32(data); spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); return r; } static void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long flags, address, data; address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); WREG32(address, ((reg) & 0x1ff)); WREG32(data, (v)); spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); } static u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long flags, address, data; u32 r; address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); spin_lock_irqsave(&adev->didt_idx_lock, flags); WREG32(address, (reg)); r = RREG32(data); spin_unlock_irqrestore(&adev->didt_idx_lock, flags); return r; } static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long flags, address, data; address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); spin_lock_irqsave(&adev->didt_idx_lock, flags); WREG32(address, (reg)); WREG32(data, (v)); spin_unlock_irqrestore(&adev->didt_idx_lock, flags); } static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long flags; u32 r; spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA); spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); return r; } static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long flags; spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v)); spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); } static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg) { unsigned long flags; u32 r; spin_lock_irqsave(&adev->se_cac_idx_lock, flags); WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA); spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); return r; } static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) { unsigned long flags; spin_lock_irqsave(&adev->se_cac_idx_lock, flags); WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v)); spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); } static u32 soc15_get_config_memsize(struct amdgpu_device *adev) { return adev->nbio.funcs->get_memsize(adev); } static u32 soc15_get_xclk(struct amdgpu_device *adev) { u32 reference_clock = adev->clock.spll.reference_freq; if (adev->asic_type == CHIP_RENOIR) return 10000; if (adev->asic_type == CHIP_RAVEN) return reference_clock / 4; return reference_clock; } void soc15_grbm_select(struct amdgpu_device *adev, u32 me, u32 pipe, u32 queue, u32 vmid) { u32 grbm_gfx_cntl = 0; grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe); grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me); 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_RLC_SHADOW(GC, 0, mmGRBM_GFX_CNTL, grbm_gfx_cntl); } static void soc15_vga_set_state(struct amdgpu_device *adev, bool state) { /* todo */ } static bool soc15_read_disabled_bios(struct amdgpu_device *adev) { /* todo */ return false; } static bool soc15_read_bios_from_rom(struct amdgpu_device *adev, u8 *bios, u32 length_bytes) { u32 *dw_ptr; u32 i, length_dw; uint32_t rom_index_offset; uint32_t rom_data_offset; if (bios == NULL) return false; if (length_bytes == 0) return false; /* APU vbios image is part of sbios image */ if (adev->flags & AMD_IS_APU) return false; dw_ptr = (u32 *)bios; length_dw = ALIGN(length_bytes, 4) / 4; rom_index_offset = adev->smuio.funcs->get_rom_index_offset(adev); rom_data_offset = adev->smuio.funcs->get_rom_data_offset(adev); /* set rom index to 0 */ WREG32(rom_index_offset, 0); /* read out the rom data */ for (i = 0; i < length_dw; i++) dw_ptr[i] = RREG32(rom_data_offset); return true; } static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = { { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)}, { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)}, { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)}, { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)}, { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)}, { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)}, { SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)}, { SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)}, { SOC15_REG_ENTRY(GC, 0, mmCP_STAT)}, { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)}, { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)}, { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)}, { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)}, { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)}, { SOC15_REG_ENTRY(GC, 0, mmDB_DEBUG2)}, }; static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 reg_offset) { uint32_t val; mutex_lock(&adev->grbm_idx_mutex); if (se_num != 0xffffffff || sh_num != 0xffffffff) amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); val = RREG32(reg_offset); if (se_num != 0xffffffff || sh_num != 0xffffffff) amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); mutex_unlock(&adev->grbm_idx_mutex); return val; } static uint32_t soc15_get_register_value(struct amdgpu_device *adev, bool indexed, u32 se_num, u32 sh_num, u32 reg_offset) { if (indexed) { return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset); } else { if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) return adev->gfx.config.gb_addr_config; else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) return adev->gfx.config.db_debug2; return RREG32(reg_offset); } } static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 reg_offset, u32 *value) { uint32_t i; struct soc15_allowed_register_entry *en; *value = 0; for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) { en = &soc15_allowed_read_registers[i]; if (adev->reg_offset[en->hwip][en->inst] && reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) continue; *value = soc15_get_register_value(adev, soc15_allowed_read_registers[i].grbm_indexed, se_num, sh_num, reg_offset); return 0; } return -EINVAL; } /** * soc15_program_register_sequence - program an array of registers. * * @adev: amdgpu_device pointer * @regs: pointer to the register array * @array_size: size of the register array * * Programs an array or registers with and and or masks. * This is a helper for setting golden registers. */ void soc15_program_register_sequence(struct amdgpu_device *adev, const struct soc15_reg_golden *regs, const u32 array_size) { const struct soc15_reg_golden *entry; u32 tmp, reg; int i; for (i = 0; i < array_size; ++i) { entry = ®s[i]; reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg; if (entry->and_mask == 0xffffffff) { tmp = entry->or_mask; } else { tmp = RREG32(reg); tmp &= ~(entry->and_mask); tmp |= (entry->or_mask & entry->and_mask); } if (reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3) || reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE) || reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE_1) || reg == SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG)) WREG32_RLC(reg, tmp); else WREG32(reg, tmp); } } static int soc15_asic_baco_reset(struct amdgpu_device *adev) { struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); int ret = 0; /* avoid NBIF got stuck when do RAS recovery in BACO reset */ if (ras && ras->supported) adev->nbio.funcs->enable_doorbell_interrupt(adev, false); ret = amdgpu_dpm_baco_reset(adev); if (ret) return ret; /* re-enable doorbell interrupt after BACO exit */ if (ras && ras->supported) adev->nbio.funcs->enable_doorbell_interrupt(adev, true); return 0; } static enum amd_reset_method soc15_asic_reset_method(struct amdgpu_device *adev) { bool baco_reset = false; bool connected_to_cpu = false; struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); if (adev->gmc.xgmi.supported && adev->gmc.xgmi.connected_to_cpu) connected_to_cpu = true; if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || amdgpu_reset_method == AMD_RESET_METHOD_BACO || amdgpu_reset_method == AMD_RESET_METHOD_PCI) { /* If connected to cpu, driver only support mode2 */ if (connected_to_cpu) return AMD_RESET_METHOD_MODE2; return amdgpu_reset_method; } if (amdgpu_reset_method != -1) dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", amdgpu_reset_method); switch (adev->asic_type) { case CHIP_RAVEN: case CHIP_RENOIR: return AMD_RESET_METHOD_MODE2; case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_ARCTURUS: baco_reset = amdgpu_dpm_is_baco_supported(adev); break; case CHIP_VEGA20: if (adev->psp.sos_fw_version >= 0x80067) baco_reset = amdgpu_dpm_is_baco_supported(adev); /* * 1. PMFW version > 0x284300: all cases use baco * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco */ if ((ras && ras->supported) && adev->pm.fw_version <= 0x283400) baco_reset = false; break; case CHIP_ALDEBARAN: /* * 1.connected to cpu: driver issue mode2 reset * 2.discret gpu: driver issue mode1 reset */ if (connected_to_cpu) return AMD_RESET_METHOD_MODE2; break; default: break; } if (baco_reset) return AMD_RESET_METHOD_BACO; else return AMD_RESET_METHOD_MODE1; } static int soc15_asic_reset(struct amdgpu_device *adev) { /* original raven doesn't have full asic reset */ if ((adev->apu_flags & AMD_APU_IS_RAVEN) && !(adev->apu_flags & AMD_APU_IS_RAVEN2)) return 0; switch (soc15_asic_reset_method(adev)) { case AMD_RESET_METHOD_PCI: dev_info(adev->dev, "PCI reset\n"); return amdgpu_device_pci_reset(adev); case AMD_RESET_METHOD_BACO: dev_info(adev->dev, "BACO reset\n"); return soc15_asic_baco_reset(adev); case AMD_RESET_METHOD_MODE2: dev_info(adev->dev, "MODE2 reset\n"); return amdgpu_dpm_mode2_reset(adev); default: dev_info(adev->dev, "MODE1 reset\n"); return amdgpu_device_mode1_reset(adev); } } static bool soc15_supports_baco(struct amdgpu_device *adev) { switch (adev->asic_type) { case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_ARCTURUS: return amdgpu_dpm_is_baco_supported(adev); case CHIP_VEGA20: if (adev->psp.sos_fw_version >= 0x80067) return amdgpu_dpm_is_baco_supported(adev); return false; default: return false; } } /*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock, u32 cntl_reg, u32 status_reg) { return 0; }*/ static int soc15_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) { /*int r; r = soc15_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS); if (r) return r; r = soc15_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS); */ return 0; } static int soc15_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) { /* todo */ return 0; } static void soc15_pcie_gen3_enable(struct amdgpu_device *adev) { if (pci_is_root_bus(adev->pdev->bus)) return; if (amdgpu_pcie_gen2 == 0) return; if (adev->flags & AMD_IS_APU) return; if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) return; /* todo */ } static void soc15_program_aspm(struct amdgpu_device *adev) { if (amdgpu_aspm != 1) return; if (!(adev->flags & AMD_IS_APU) && (adev->nbio.funcs->program_aspm)) adev->nbio.funcs->program_aspm(adev); } static void soc15_enable_doorbell_aperture(struct amdgpu_device *adev, bool enable) { adev->nbio.funcs->enable_doorbell_aperture(adev, enable); adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); } static const struct amdgpu_ip_block_version vega10_common_ip_block = { .type = AMD_IP_BLOCK_TYPE_COMMON, .major = 2, .minor = 0, .rev = 0, .funcs = &soc15_common_ip_funcs, }; static uint32_t soc15_get_rev_id(struct amdgpu_device *adev) { return adev->nbio.funcs->get_rev_id(adev); } static void soc15_reg_base_init(struct amdgpu_device *adev) { int r; /* Set IP register base before any HW register access */ switch (adev->asic_type) { case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_RAVEN: vega10_reg_base_init(adev); break; case CHIP_RENOIR: /* It's safe to do ip discovery here for Renior, * it doesn't support SRIOV. */ if (amdgpu_discovery) { r = amdgpu_discovery_reg_base_init(adev); if (r == 0) break; DRM_WARN("failed to init reg base from ip discovery table, " "fallback to legacy init method\n"); } vega10_reg_base_init(adev); break; case CHIP_VEGA20: vega20_reg_base_init(adev); break; case CHIP_ARCTURUS: arct_reg_base_init(adev); break; case CHIP_ALDEBARAN: aldebaran_reg_base_init(adev); break; default: DRM_ERROR("Unsupported asic type: %d!\n", adev->asic_type); break; } } void soc15_set_virt_ops(struct amdgpu_device *adev) { adev->virt.ops = &xgpu_ai_virt_ops; /* init soc15 reg base early enough so we can * request request full access for sriov before * set_ip_blocks. */ soc15_reg_base_init(adev); } int soc15_set_ip_blocks(struct amdgpu_device *adev) { /* for bare metal case */ if (!amdgpu_sriov_vf(adev)) soc15_reg_base_init(adev); if (adev->flags & AMD_IS_APU) { adev->nbio.funcs = &nbio_v7_0_funcs; adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg; } else if (adev->asic_type == CHIP_VEGA20 || adev->asic_type == CHIP_ARCTURUS || adev->asic_type == CHIP_ALDEBARAN) { adev->nbio.funcs = &nbio_v7_4_funcs; adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; } else { adev->nbio.funcs = &nbio_v6_1_funcs; adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg; } adev->hdp.funcs = &hdp_v4_0_funcs; if (adev->asic_type == CHIP_VEGA20 || adev->asic_type == CHIP_ARCTURUS || adev->asic_type == CHIP_ALDEBARAN) adev->df.funcs = &df_v3_6_funcs; else adev->df.funcs = &df_v1_7_funcs; if (adev->asic_type == CHIP_VEGA20 || adev->asic_type == CHIP_ARCTURUS) adev->smuio.funcs = &smuio_v11_0_funcs; else if (adev->asic_type == CHIP_ALDEBARAN) adev->smuio.funcs = &smuio_v13_0_funcs; else adev->smuio.funcs = &smuio_v9_0_funcs; adev->rev_id = soc15_get_rev_id(adev); switch (adev->asic_type) { case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_VEGA20: amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); /* For Vega10 SR-IOV, PSP need to be initialized before IH */ if (amdgpu_sriov_vf(adev)) { if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { if (adev->asic_type == CHIP_VEGA20) amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); else amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); } if (adev->asic_type == CHIP_VEGA20) amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); else amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); } else { if (adev->asic_type == CHIP_VEGA20) amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); else amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { if (adev->asic_type == CHIP_VEGA20) amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); else amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); } } amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); if (is_support_sw_smu(adev)) { if (!amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); } else { amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); } if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); #if defined(CONFIG_DRM_AMD_DC) else if (amdgpu_device_has_dc_support(adev)) amdgpu_device_ip_block_add(adev, &dm_ip_block); #endif if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) { amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block); amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block); } break; case CHIP_RAVEN: amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block); amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); #if defined(CONFIG_DRM_AMD_DC) else if (amdgpu_device_has_dc_support(adev)) amdgpu_device_ip_block_add(adev, &dm_ip_block); #endif amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block); break; case CHIP_ARCTURUS: amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); if (amdgpu_sriov_vf(adev)) { if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); } else { amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); } if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); if (amdgpu_sriov_vf(adev)) { if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); } else { amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); } if (!amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block); break; case CHIP_RENOIR: amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block); amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block); amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); #if defined(CONFIG_DRM_AMD_DC) else if (amdgpu_device_has_dc_support(adev)) amdgpu_device_ip_block_add(adev, &dm_ip_block); #endif amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); break; case CHIP_ALDEBARAN: amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); if (amdgpu_sriov_vf(adev)) { if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); } else { amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); } amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block); amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block); break; default: return -EINVAL; } return 0; } static bool soc15_need_full_reset(struct amdgpu_device *adev) { /* change this when we implement soft reset */ return true; } static void soc15_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, uint64_t *count1) { uint32_t perfctr = 0; uint64_t cnt0_of, cnt1_of; int tmp; /* This reports 0 on APUs, so return to avoid writing/reading registers * that may or may not be different from their GPU counterparts */ if (adev->flags & AMD_IS_APU) return; /* Set the 2 events that we wish to watch, defined above */ /* Reg 40 is # received msgs */ /* Reg 104 is # of posted requests sent */ perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT0_SEL, 40); perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT1_SEL, 104); /* Write to enable desired perf counters */ WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK, perfctr); /* Zero out and enable the perf counters * Write 0x5: * Bit 0 = Start all counters(1) * Bit 2 = Global counter reset enable(1) */ WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); msleep(1000); /* Load the shadow and disable the perf counters * Write 0x2: * Bit 0 = Stop counters(0) * Bit 1 = Load the shadow counters(1) */ WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); /* Read register values to get any >32bit overflow */ tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK); cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER0_UPPER); cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER1_UPPER); /* Get the values and add the overflow */ *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK) | (cnt0_of << 32); *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK) | (cnt1_of << 32); } static void vega20_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, uint64_t *count1) { uint32_t perfctr = 0; uint64_t cnt0_of, cnt1_of; int tmp; /* This reports 0 on APUs, so return to avoid writing/reading registers * that may or may not be different from their GPU counterparts */ if (adev->flags & AMD_IS_APU) return; /* Set the 2 events that we wish to watch, defined above */ /* Reg 40 is # received msgs */ /* Reg 108 is # of posted requests sent on VG20 */ perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, EVENT0_SEL, 40); perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, EVENT1_SEL, 108); /* Write to enable desired perf counters */ WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3, perfctr); /* Zero out and enable the perf counters * Write 0x5: * Bit 0 = Start all counters(1) * Bit 2 = Global counter reset enable(1) */ WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); msleep(1000); /* Load the shadow and disable the perf counters * Write 0x2: * Bit 0 = Stop counters(0) * Bit 1 = Load the shadow counters(1) */ WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); /* Read register values to get any >32bit overflow */ tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3); cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER0_UPPER); cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER1_UPPER); /* Get the values and add the overflow */ *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK3) | (cnt0_of << 32); *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK3) | (cnt1_of << 32); } static bool soc15_need_reset_on_init(struct amdgpu_device *adev) { u32 sol_reg; /* Just return false for soc15 GPUs. Reset does not seem to * be necessary. */ if (!amdgpu_passthrough(adev)) return false; if (adev->flags & AMD_IS_APU) return false; /* Check sOS sign of life register to confirm sys driver and sOS * are already been loaded. */ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); if (sol_reg) return true; return false; } static uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev) { uint64_t nak_r, nak_g; /* Get the number of NAKs received and generated */ nak_r = RREG32_PCIE(smnPCIE_RX_NUM_NAK); nak_g = RREG32_PCIE(smnPCIE_RX_NUM_NAK_GENERATED); /* Add the total number of NAKs, i.e the number of replays */ return (nak_r + nak_g); } static void soc15_pre_asic_init(struct amdgpu_device *adev) { gmc_v9_0_restore_registers(adev); } static const struct amdgpu_asic_funcs soc15_asic_funcs = { .read_disabled_bios = &soc15_read_disabled_bios, .read_bios_from_rom = &soc15_read_bios_from_rom, .read_register = &soc15_read_register, .reset = &soc15_asic_reset, .reset_method = &soc15_asic_reset_method, .set_vga_state = &soc15_vga_set_state, .get_xclk = &soc15_get_xclk, .set_uvd_clocks = &soc15_set_uvd_clocks, .set_vce_clocks = &soc15_set_vce_clocks, .get_config_memsize = &soc15_get_config_memsize, .need_full_reset = &soc15_need_full_reset, .init_doorbell_index = &vega10_doorbell_index_init, .get_pcie_usage = &soc15_get_pcie_usage, .need_reset_on_init = &soc15_need_reset_on_init, .get_pcie_replay_count = &soc15_get_pcie_replay_count, .supports_baco = &soc15_supports_baco, .pre_asic_init = &soc15_pre_asic_init, .query_video_codecs = &soc15_query_video_codecs, }; static const struct amdgpu_asic_funcs vega20_asic_funcs = { .read_disabled_bios = &soc15_read_disabled_bios, .read_bios_from_rom = &soc15_read_bios_from_rom, .read_register = &soc15_read_register, .reset = &soc15_asic_reset, .reset_method = &soc15_asic_reset_method, .set_vga_state = &soc15_vga_set_state, .get_xclk = &soc15_get_xclk, .set_uvd_clocks = &soc15_set_uvd_clocks, .set_vce_clocks = &soc15_set_vce_clocks, .get_config_memsize = &soc15_get_config_memsize, .need_full_reset = &soc15_need_full_reset, .init_doorbell_index = &vega20_doorbell_index_init, .get_pcie_usage = &vega20_get_pcie_usage, .need_reset_on_init = &soc15_need_reset_on_init, .get_pcie_replay_count = &soc15_get_pcie_replay_count, .supports_baco = &soc15_supports_baco, .pre_asic_init = &soc15_pre_asic_init, .query_video_codecs = &soc15_query_video_codecs, }; static int soc15_common_early_init(void *handle) { #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) struct amdgpu_device *adev = (struct amdgpu_device *)handle; adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; adev->smc_rreg = NULL; adev->smc_wreg = NULL; adev->pcie_rreg = &soc15_pcie_rreg; adev->pcie_wreg = &soc15_pcie_wreg; adev->pcie_rreg64 = &soc15_pcie_rreg64; adev->pcie_wreg64 = &soc15_pcie_wreg64; adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg; adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg; adev->didt_rreg = &soc15_didt_rreg; adev->didt_wreg = &soc15_didt_wreg; adev->gc_cac_rreg = &soc15_gc_cac_rreg; adev->gc_cac_wreg = &soc15_gc_cac_wreg; adev->se_cac_rreg = &soc15_se_cac_rreg; adev->se_cac_wreg = &soc15_se_cac_wreg; adev->external_rev_id = 0xFF; switch (adev->asic_type) { case CHIP_VEGA10: adev->asic_funcs = &soc15_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_RLC_LS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_BIF_MGCG | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_DRM_MGCG | AMD_CG_SUPPORT_DRM_LS | AMD_CG_SUPPORT_ROM_MGCG | AMD_CG_SUPPORT_DF_MGCG | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS; adev->pg_flags = 0; adev->external_rev_id = 0x1; break; case CHIP_VEGA12: adev->asic_funcs = &soc15_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_BIF_MGCG | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_MGCG | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_ROM_MGCG | AMD_CG_SUPPORT_VCE_MGCG | AMD_CG_SUPPORT_UVD_MGCG; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x14; break; case CHIP_VEGA20: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_BIF_MGCG | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_MGCG | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_ROM_MGCG | AMD_CG_SUPPORT_VCE_MGCG | AMD_CG_SUPPORT_UVD_MGCG; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x28; break; case CHIP_RAVEN: adev->asic_funcs = &soc15_asic_funcs; if (adev->pdev->device == 0x15dd) adev->apu_flags |= AMD_APU_IS_RAVEN; if (adev->pdev->device == 0x15d8) adev->apu_flags |= AMD_APU_IS_PICASSO; if (adev->rev_id >= 0x8) adev->apu_flags |= AMD_APU_IS_RAVEN2; if (adev->apu_flags & AMD_APU_IS_RAVEN2) adev->external_rev_id = adev->rev_id + 0x79; else if (adev->apu_flags & AMD_APU_IS_PICASSO) adev->external_rev_id = adev->rev_id + 0x41; else if (adev->rev_id == 1) adev->external_rev_id = adev->rev_id + 0x20; else adev->external_rev_id = adev->rev_id + 0x01; if (adev->apu_flags & AMD_APU_IS_RAVEN2) { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_VCN_MGCG; adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; } else if (adev->apu_flags & AMD_APU_IS_PICASSO) { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_VCN_MGCG; adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_MMHUB | AMD_PG_SUPPORT_VCN; } else { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_RLC_LS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_BIF_MGCG | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_MGCG | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_DRM_MGCG | AMD_CG_SUPPORT_DRM_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_VCN_MGCG; adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; } break; case CHIP_ARCTURUS: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_HDP_MGCG | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_IH_CG | AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG; adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG; adev->external_rev_id = adev->rev_id + 0x32; break; case CHIP_RENOIR: adev->asic_funcs = &soc15_asic_funcs; if ((adev->pdev->device == 0x1636) || (adev->pdev->device == 0x164c)) adev->apu_flags |= AMD_APU_IS_RENOIR; else adev->apu_flags |= AMD_APU_IS_GREEN_SARDINE; if (adev->apu_flags & AMD_APU_IS_RENOIR) adev->external_rev_id = adev->rev_id + 0x91; else adev->external_rev_id = adev->rev_id + 0xa1; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_MC_MGCG | AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_BIF_LS | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG | AMD_CG_SUPPORT_IH_CG | AMD_CG_SUPPORT_ATHUB_LS | AMD_CG_SUPPORT_ATHUB_MGCG | AMD_CG_SUPPORT_DF_MGCG; adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_JPEG | AMD_PG_SUPPORT_VCN_DPG; break; case CHIP_ALDEBARAN: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_IH_CG | AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG; adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG; adev->external_rev_id = adev->rev_id + 0x3c; break; default: /* FIXME: not supported yet */ return -EINVAL; } if (amdgpu_sriov_vf(adev)) { amdgpu_virt_init_setting(adev); xgpu_ai_mailbox_set_irq_funcs(adev); } return 0; } static int soc15_common_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; int r = 0; if (amdgpu_sriov_vf(adev)) xgpu_ai_mailbox_get_irq(adev); if (adev->hdp.funcs->reset_ras_error_count) adev->hdp.funcs->reset_ras_error_count(adev); if (adev->nbio.ras_funcs && adev->nbio.ras_funcs->ras_late_init) r = adev->nbio.ras_funcs->ras_late_init(adev); return r; } static int soc15_common_sw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (amdgpu_sriov_vf(adev)) xgpu_ai_mailbox_add_irq_id(adev); adev->df.funcs->sw_init(adev); return 0; } static int soc15_common_sw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->nbio.ras_funcs && adev->nbio.ras_funcs->ras_fini) adev->nbio.ras_funcs->ras_fini(adev); adev->df.funcs->sw_fini(adev); return 0; } static void soc15_doorbell_range_init(struct amdgpu_device *adev) { int i; struct amdgpu_ring *ring; /* sdma/ih doorbell range are programed by hypervisor */ if (!amdgpu_sriov_vf(adev)) { for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; adev->nbio.funcs->sdma_doorbell_range(adev, i, ring->use_doorbell, ring->doorbell_index, adev->doorbell_index.sdma_doorbell_range); } adev->nbio.funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell, adev->irq.ih.doorbell_index); } } static int soc15_common_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* enable pcie gen2/3 link */ soc15_pcie_gen3_enable(adev); /* enable aspm */ soc15_program_aspm(adev); /* setup nbio registers */ adev->nbio.funcs->init_registers(adev); /* remap HDP registers to a hole in mmio space, * for the purpose of expose those registers * to process space */ if (adev->nbio.funcs->remap_hdp_registers) adev->nbio.funcs->remap_hdp_registers(adev); /* enable the doorbell aperture */ soc15_enable_doorbell_aperture(adev, true); /* HW doorbell routing policy: doorbell writing not * in SDMA/IH/MM/ACV range will be routed to CP. So * we need to init SDMA/IH/MM/ACV doorbell range prior * to CP ip block init and ring test. */ soc15_doorbell_range_init(adev); return 0; } static int soc15_common_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* disable the doorbell aperture */ soc15_enable_doorbell_aperture(adev, false); if (amdgpu_sriov_vf(adev)) xgpu_ai_mailbox_put_irq(adev); if (adev->nbio.ras_if && amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) { if (adev->nbio.ras_funcs && adev->nbio.ras_funcs->init_ras_controller_interrupt) amdgpu_irq_put(adev, &adev->nbio.ras_controller_irq, 0); if (adev->nbio.ras_funcs && adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt) amdgpu_irq_put(adev, &adev->nbio.ras_err_event_athub_irq, 0); } return 0; } static int soc15_common_suspend(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; return soc15_common_hw_fini(adev); } static int soc15_common_resume(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; return soc15_common_hw_init(adev); } static bool soc15_common_is_idle(void *handle) { return true; } static int soc15_common_wait_for_idle(void *handle) { return 0; } static int soc15_common_soft_reset(void *handle) { return 0; } static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) { uint32_t def, data; def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_MGCG)) data &= ~(0x01000000 | 0x02000000 | 0x04000000 | 0x08000000 | 0x10000000 | 0x20000000 | 0x40000000 | 0x80000000); else data |= (0x01000000 | 0x02000000 | 0x04000000 | 0x08000000 | 0x10000000 | 0x20000000 | 0x40000000 | 0x80000000); if (def != data) WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0), data); } static void soc15_update_drm_light_sleep(struct amdgpu_device *adev, bool enable) { uint32_t def, data; def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS)) data |= 1; else data &= ~1; if (def != data) WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL), data); } static int soc15_common_set_clockgating_state(void *handle, enum amd_clockgating_state state) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (amdgpu_sriov_vf(adev)) return 0; switch (adev->asic_type) { case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_VEGA20: adev->nbio.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->nbio.funcs->update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE); adev->hdp.funcs->update_clock_gating(adev, state == AMD_CG_STATE_GATE); soc15_update_drm_clock_gating(adev, state == AMD_CG_STATE_GATE); soc15_update_drm_light_sleep(adev, state == AMD_CG_STATE_GATE); adev->smuio.funcs->update_rom_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->df.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); break; case CHIP_RAVEN: case CHIP_RENOIR: adev->nbio.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->nbio.funcs->update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE); adev->hdp.funcs->update_clock_gating(adev, state == AMD_CG_STATE_GATE); soc15_update_drm_clock_gating(adev, state == AMD_CG_STATE_GATE); soc15_update_drm_light_sleep(adev, state == AMD_CG_STATE_GATE); break; case CHIP_ARCTURUS: case CHIP_ALDEBARAN: adev->hdp.funcs->update_clock_gating(adev, state == AMD_CG_STATE_GATE); break; default: break; } return 0; } static void soc15_common_get_clockgating_state(void *handle, u32 *flags) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; int data; if (amdgpu_sriov_vf(adev)) *flags = 0; adev->nbio.funcs->get_clockgating_state(adev, flags); adev->hdp.funcs->get_clock_gating_state(adev, flags); if (adev->asic_type != CHIP_ALDEBARAN) { /* AMD_CG_SUPPORT_DRM_MGCG */ data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); if (!(data & 0x01000000)) *flags |= AMD_CG_SUPPORT_DRM_MGCG; /* AMD_CG_SUPPORT_DRM_LS */ data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); if (data & 0x1) *flags |= AMD_CG_SUPPORT_DRM_LS; } /* AMD_CG_SUPPORT_ROM_MGCG */ adev->smuio.funcs->get_clock_gating_state(adev, flags); adev->df.funcs->get_clockgating_state(adev, flags); } static int soc15_common_set_powergating_state(void *handle, enum amd_powergating_state state) { /* todo */ return 0; } const struct amd_ip_funcs soc15_common_ip_funcs = { .name = "soc15_common", .early_init = soc15_common_early_init, .late_init = soc15_common_late_init, .sw_init = soc15_common_sw_init, .sw_fini = soc15_common_sw_fini, .hw_init = soc15_common_hw_init, .hw_fini = soc15_common_hw_fini, .suspend = soc15_common_suspend, .resume = soc15_common_resume, .is_idle = soc15_common_is_idle, .wait_for_idle = soc15_common_wait_for_idle, .soft_reset = soc15_common_soft_reset, .set_clockgating_state = soc15_common_set_clockgating_state, .set_powergating_state = soc15_common_set_powergating_state, .get_clockgating_state= soc15_common_get_clockgating_state, };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
You can’t perform that action at this time.