diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-25 16:18:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-25 16:18:27 -0700 |
commit | 2518f226c60d8e04d18ba4295500a5b0b8ac7659 (patch) | |
tree | e74de5ca0db01398cbb0c34376f74a81d7583c75 /drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | |
parent | 86c87bea6b42100c67418af690919c44de6ede6e (diff) | |
parent | c4955d9cd2fc56c43e78c908dad4e2cac7cc9073 (diff) |
Merge tag 'drm-next-2022-05-25' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"Intel have enabled DG2 on certain SKUs for laptops, AMD has started
some new GPU support, msm has user allocated VA controls
dma-buf:
- add dma_resv_replace_fences
- add dma_resv_get_singleton
- make dma_excl_fence private
core:
- EDID parser refactorings
- switch drivers to drm_mode_copy/duplicate
- DRM managed mutex initialization
display-helper:
- put HDMI, SCDC, HDCP, DSC and DP into new module
gem:
- rework fence handling
ttm:
- rework bulk move handling
- add common debugfs for resource managers
- convert to kvcalloc
format helpers:
- support monochrome formats
- RGB888, RGB565 to XRGB8888 conversions
fbdev:
- cfb/sys_imageblit fixes
- pagelist corruption fix
- create offb platform device
- deferred io improvements
sysfb:
- Kconfig rework
- support for VESA mode selection
bridge:
- conversions to devm_drm_of_get_bridge
- conversions to panel_bridge
- analogix_dp - autosuspend support
- it66121 - audio support
- tc358767 - DSI to DPI support
- icn6211 - PLL/I2C fixes, DT property
- adv7611 - enable DRM_BRIDGE_OP_HPD
- anx7625 - fill ELD if no monitor
- dw_hdmi - add audio support
- lontium LT9211 support, i.MXMP LDB
- it6505: Kconfig fix, DPCD set power fix
- adv7511 - CEC support for ADV7535
panel:
- ltk035c5444t, B133UAN01, NV3052C panel support
- DataImage FG040346DSSWBG04 support
- st7735r - DT bindings fix
- ssd130x - fixes
i915:
- DG2 laptop PCI-IDs ("motherboard down")
- Initial RPL-P PCI IDs
- compute engine ABI
- DG2 Tile4 support
- DG2 CCS clear color compression support
- DG2 render/media compression formats support
- ATS-M platform info
- RPL-S PCI IDs added
- Bump ADL-P DMC version to v2.16
- Support static DRRS
- Support multiple eDP/LVDS native mode refresh rates
- DP HDR support for HSW+
- Lots of display refactoring + fixes
- GuC hwconfig support and query
- sysfs support for multi-tile
- fdinfo per-client gpu utilisation
- add geometry subslices query
- fix prime mmap with LMEM
- fix vm open count and remove vma refcounts
- contiguous allocation fixes
- steered register write support
- small PCI BAR enablement
- GuC error capture support
- sunset igpu legacy mmap support for newer devices
- GuC version 70.1.1 support
amdgpu:
- Initial SoC21 support
- SMU 13.x enablement
- SMU 13.0.4 support
- ttm_eu cleanups
- USB-C, GPUVM updates
- TMZ fixes for RV
- RAS support for VCN
- PM sysfs code cleanup
- DC FP rework
- extend CG/PG flags to 64-bit
- SI dpm lockdep fix
- runtime PM fixes
amdkfd:
- RAS/SVM fixes
- TLB flush fixes
- CRIU GWS support
- ignore bogus MEC signals more efficiently
msm:
- Fourcc modifier for tiled but not compressed layouts
- Support for userspace allocated IOVA (GPU virtual address)
- DPU: DSC (Display Stream Compression) support
- DP: eDP support
- DP: conversion to use drm_bridge and drm_bridge_connector
- Merge DPU1 and MDP5 MDSS driver
- DPU: writeback support
nouveau:
- make some structures static
- make some variables static
- switch to drm_gem_plane_helper_prepare_fb
radeon:
- misc fixes/cleanups
mxsfb:
- rework crtc mode setting
- LCDIF CRC support
etnaviv:
- fencing improvements
- fix address space collisions
- cleanup MMU reference handling
gma500:
- GEM/GTT improvements
- connector handling fixes
komeda:
- switch to plane reset helper
mediatek:
- MIPI DSI improvements
omapdrm:
- GEM improvements
qxl:
- aarch64 support
vc4:
- add a CL submission tracepoint
- HDMI YUV support
- HDMI/clock improvements
- drop is_hdmi caching
virtio:
- remove restriction of non-zero blob types
vmwgfx:
- support for cursormob and cursorbypass 4
- fence improvements
tidss:
- reset DISPC on startup
solomon:
- SPI support
- DT improvements
sun4i:
- allwinner D1 support
- drop is_hdmi caching
imx:
- use swap() instead of open-coding
- use devm_platform_ioremap_resource
- remove redunant initializations
ast:
- Displayport support
rockchip:
- Refactor IOMMU initialisation
- make some structures static
- replace drm_detect_hdmi_monitor with drm_display_info.is_hdmi
- support swapped YUV formats,
- clock improvements
- rk3568 support
- VOP2 support
mediatek:
- MT8186 support
tegra:
- debugabillity improvements"
* tag 'drm-next-2022-05-25' of git://anongit.freedesktop.org/drm/drm: (1740 commits)
drm/i915/dsi: fix VBT send packet port selection for ICL+
drm/i915/uc: Fix undefined behavior due to shift overflowing the constant
drm/i915/reg: fix undefined behavior due to shift overflowing the constant
drm/i915/gt: Fix use of static in macro mismatch
drm/i915/audio: fix audio code enable/disable pipe logging
drm/i915: Fix CFI violation with show_dynamic_id()
drm/i915: Fix 'mixing different enum types' warnings in intel_display_power.c
drm/i915/gt: Fix build error without CONFIG_PM
drm/msm/dpu: handle pm_runtime_get_sync() errors in bind path
drm/msm/dpu: add DRM_MODE_ROTATE_180 back to supported rotations
drm/msm: don't free the IRQ if it was not requested
drm/msm/dpu: limit writeback modes according to max_linewidth
drm/amd: Don't reset dGPUs if the system is going to s2idle
drm/amdgpu: Unmap legacy queue when MES is enabled
drm: msm: fix possible memory leak in mdp5_crtc_cursor_set()
drm/msm: Fix fb plane offset calculation
drm/msm/a6xx: Fix refcount leak in a6xx_gpu_init
drm/msm/dsi: don't powerup at modeset time for parade-ps8640
drm/rockchip: Change register space names in vop2
dt-bindings: display: rockchip: make reg-names mandatory for VOP2
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 377 |
1 files changed, 251 insertions, 126 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 4d4ddf026faf6..63e0293edc5fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -162,12 +162,14 @@ union vram_info { struct atom_vram_info_header_v2_4 v24; struct atom_vram_info_header_v2_5 v25; struct atom_vram_info_header_v2_6 v26; + struct atom_vram_info_header_v3_0 v30; }; union vram_module { struct atom_vram_module_v9 v9; struct atom_vram_module_v10 v10; struct atom_vram_module_v11 v11; + struct atom_vram_module_v3_0 v30; }; static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev, @@ -294,88 +296,116 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, vram_info = (union vram_info *) (mode_info->atom_context->bios + data_offset); module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16; - switch (crev) { - case 3: - if (module_id > vram_info->v23.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v23.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v9.vram_module_size); - i++; - } - mem_type = vram_module->v9.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v9.channel_num; - mem_channel_width = vram_module->v9.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - case 4: - if (module_id > vram_info->v24.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v24.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v10.vram_module_size); - i++; - } - mem_type = vram_module->v10.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v10.channel_num; - mem_channel_width = vram_module->v10.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v10.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - case 5: - if (module_id > vram_info->v25.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v25.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v11.vram_module_size); - i++; + if (frev == 3) { + switch (crev) { + /* v30 */ + case 0: + vram_module = (union vram_module *)vram_info->v30.vram_module; + mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + mem_type = vram_info->v30.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_info->v30.channel_num; + mem_channel_width = vram_info->v30.channel_width; + if (vram_width) + *vram_width = mem_channel_number * mem_channel_width; + break; + default: + return -EINVAL; } - mem_type = vram_module->v11.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v11.channel_num; - mem_channel_width = vram_module->v11.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v11.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - case 6: - if (module_id > vram_info->v26.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v26.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v9.vram_module_size); - i++; + } else if (frev == 2) { + switch (crev) { + /* v23 */ + case 3: + if (module_id > vram_info->v23.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v23.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v9.vram_module_size); + i++; + } + mem_type = vram_module->v9.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v9.channel_num; + mem_channel_width = vram_module->v9.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v24 */ + case 4: + if (module_id > vram_info->v24.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v24.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v10.vram_module_size); + i++; + } + mem_type = vram_module->v10.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v10.channel_num; + mem_channel_width = vram_module->v10.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v10.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v25 */ + case 5: + if (module_id > vram_info->v25.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v25.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v11.vram_module_size); + i++; + } + mem_type = vram_module->v11.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v11.channel_num; + mem_channel_width = vram_module->v11.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v11.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v26 */ + case 6: + if (module_id > vram_info->v26.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v26.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v9.vram_module_size); + i++; + } + mem_type = vram_module->v9.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v9.channel_num; + mem_channel_width = vram_module->v9.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + default: + return -EINVAL; } - mem_type = vram_module->v9.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v9.channel_num; - mem_channel_width = vram_module->v9.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - default: + } else { + /* invalid frev */ return -EINVAL; } } @@ -526,6 +556,14 @@ bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev, union smu_info { struct atom_smu_info_v3_1 v31; + struct atom_smu_info_v4_0 v40; +}; + +union gfx_info { + struct atom_gfx_info_v2_2 v22; + struct atom_gfx_info_v2_4 v24; + struct atom_gfx_info_v2_7 v27; + struct atom_gfx_info_v3_0 v30; }; int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) @@ -565,7 +603,10 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) data_offset); /* system clock */ - spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz); + if (frev == 3) + spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz); + else if (frev == 4) + spll->reference_freq = le32_to_cpu(smu_info->v40.core_refclk_10khz); spll->reference_div = 0; spll->min_post_div = 1; @@ -609,22 +650,26 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) gfx_info); if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) { - struct atom_gfx_info_v2_2 *gfx_info = (struct atom_gfx_info_v2_2*) + union gfx_info *gfx_info = (union gfx_info *) (mode_info->atom_context->bios + data_offset); - if ((frev == 2) && (crev >= 2)) - spll->reference_freq = le32_to_cpu(gfx_info->rlc_gpu_timer_refclk); - ret = 0; + if ((frev == 3) || + (frev == 2 && crev == 6)) { + spll->reference_freq = le32_to_cpu(gfx_info->v30.golden_tsc_count_lower_refclk); + ret = 0; + } else if ((frev == 2) && + (crev >= 2) && + (crev != 6)) { + spll->reference_freq = le32_to_cpu(gfx_info->v22.rlc_gpu_timer_refclk); + ret = 0; + } else { + BUG(); + } } } return ret; } -union gfx_info { - struct atom_gfx_info_v2_4 v24; - struct atom_gfx_info_v2_7 v27; -}; - int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) { struct amdgpu_mode_info *mode_info = &adev->mode_info; @@ -638,42 +683,58 @@ int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) &frev, &crev, &data_offset)) { union gfx_info *gfx_info = (union gfx_info *) (mode_info->atom_context->bios + data_offset); - switch (crev) { - case 4: - adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines; - adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh; - adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se; - adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se; - adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches; - adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs); - adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds; - adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth; - adev->gfx.config.gs_prim_buffer_depth = - le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth); - adev->gfx.config.double_offchip_lds_buf = - gfx_info->v24.gc_double_offchip_lds_buffer; - adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size); - adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd); - adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu; - adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size); - return 0; - case 7: - adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines; - adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh; - adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se; - adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se; - adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches; - adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs); - adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds; - adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth; - adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth); - adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer; - adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size); - adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd); - adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu; - adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size); - return 0; - default: + if (frev == 2) { + switch (crev) { + case 4: + adev->gfx.config.max_shader_engines = gfx_info->v24.max_shader_engines; + adev->gfx.config.max_cu_per_sh = gfx_info->v24.max_cu_per_sh; + adev->gfx.config.max_sh_per_se = gfx_info->v24.max_sh_per_se; + adev->gfx.config.max_backends_per_se = gfx_info->v24.max_backends_per_se; + adev->gfx.config.max_texture_channel_caches = gfx_info->v24.max_texture_channel_caches; + adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs); + adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds; + adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth; + adev->gfx.config.gs_prim_buffer_depth = + le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth); + adev->gfx.config.double_offchip_lds_buf = + gfx_info->v24.gc_double_offchip_lds_buffer; + adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size); + adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd); + adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu; + adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size); + return 0; + case 7: + adev->gfx.config.max_shader_engines = gfx_info->v27.max_shader_engines; + adev->gfx.config.max_cu_per_sh = gfx_info->v27.max_cu_per_sh; + adev->gfx.config.max_sh_per_se = gfx_info->v27.max_sh_per_se; + adev->gfx.config.max_backends_per_se = gfx_info->v27.max_backends_per_se; + adev->gfx.config.max_texture_channel_caches = gfx_info->v27.max_texture_channel_caches; + adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v27.gc_num_gprs); + adev->gfx.config.max_gs_threads = gfx_info->v27.gc_num_max_gs_thds; + adev->gfx.config.gs_vgt_table_depth = gfx_info->v27.gc_gs_table_depth; + adev->gfx.config.gs_prim_buffer_depth = le16_to_cpu(gfx_info->v27.gc_gsprim_buff_depth); + adev->gfx.config.double_offchip_lds_buf = gfx_info->v27.gc_double_offchip_lds_buffer; + adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v27.gc_wave_size); + adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v27.gc_max_waves_per_simd); + adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v27.gc_max_scratch_slots_per_cu; + adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v27.gc_lds_size); + return 0; + default: + return -EINVAL; + } + } else if (frev == 3) { + switch (crev) { + case 0: + adev->gfx.config.max_shader_engines = gfx_info->v30.max_shader_engines; + adev->gfx.config.max_cu_per_sh = gfx_info->v30.max_cu_per_sh; + adev->gfx.config.max_sh_per_se = gfx_info->v30.max_sh_per_se; + adev->gfx.config.max_backends_per_se = gfx_info->v30.max_backends_per_se; + adev->gfx.config.max_texture_channel_caches = gfx_info->v30.max_texture_channel_caches; + return 0; + default: + return -EINVAL; + } + } else { return -EINVAL; } @@ -731,3 +792,67 @@ int amdgpu_atomfirmware_get_fw_reserved_fb_size(struct amdgpu_device *adev) return fw_reserved_fb_size; } + +/* + * Helper function to execute asic_init table + * + * @adev: amdgpu_device pointer + * @fb_reset: flag to indicate whether fb is reset or not + * + * Return 0 if succeed, otherwise failed + */ +int amdgpu_atomfirmware_asic_init(struct amdgpu_device *adev, bool fb_reset) +{ + struct amdgpu_mode_info *mode_info = &adev->mode_info; + struct atom_context *ctx; + uint8_t frev, crev; + uint16_t data_offset; + uint32_t bootup_sclk_in10khz, bootup_mclk_in10khz; + struct asic_init_ps_allocation_v2_1 asic_init_ps_v2_1; + int index; + + if (!mode_info) + return -EINVAL; + + ctx = mode_info->atom_context; + if (!ctx) + return -EINVAL; + + /* query bootup sclk/mclk from firmware_info table */ + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + firmwareinfo); + if (amdgpu_atom_parse_data_header(ctx, index, NULL, + &frev, &crev, &data_offset)) { + union firmware_info *firmware_info = + (union firmware_info *)(ctx->bios + + data_offset); + + bootup_sclk_in10khz = + le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz); + bootup_mclk_in10khz = + le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz); + } else { + return -EINVAL; + } + + index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1, + asic_init); + if (amdgpu_atom_parse_cmd_header(mode_info->atom_context, index, &frev, &crev)) { + if (frev == 2 && crev >= 1) { + memset(&asic_init_ps_v2_1, 0, sizeof(asic_init_ps_v2_1)); + asic_init_ps_v2_1.param.engineparam.sclkfreqin10khz = bootup_sclk_in10khz; + asic_init_ps_v2_1.param.memparam.mclkfreqin10khz = bootup_mclk_in10khz; + asic_init_ps_v2_1.param.engineparam.engineflag = b3NORMAL_ENGINE_INIT; + if (!fb_reset) + asic_init_ps_v2_1.param.memparam.memflag = b3DRAM_SELF_REFRESH_EXIT; + else + asic_init_ps_v2_1.param.memparam.memflag = 0; + } else { + return -EINVAL; + } + } else { + return -EINVAL; + } + + return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1); +} |