diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
commit | 68a32ba14177d4a21c4a9a941cf1d7aea86d436f (patch) | |
tree | 945c20860766c22b19d1806d5b5db5b37bc65b65 /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |
parent | 3aa139aa9fdc138a84243dc49dc18d9b40e1c6e4 (diff) | |
parent | a1a1ca70deb3ec600eeabb21de7f3f48aaae5695 (diff) |
Merge tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"The usual lots of work all over the place.
i915 has gotten some Alderlake work and prelim DG1 code, along with a
major locking rework over the GEM code, and brings back the property
of timing out long running jobs using a watchdog. amdgpu has some
Alderbran support (new GPU), freesync HDMI support along with a lot
other fixes.
Outside of the drm, there is a new printf specifier added which should
have all the correct acks/sobs:
- printk fourcc modifier support added %p4cc
Summary:
core:
- drm_crtc_commit_wait
- atomic plane state helpers reworked for full state
- dma-buf heaps API rework
- edid: rework and improvements for displayid
dp-mst:
- better topology logging
bridge:
- Chipone ICN6211
- Lontium LT8912B
- anx7625 regulator support
panel:
- fix lt9611 4k panels handling
simple-kms:
- add plane state helpers
ttm:
- debugfs support
- removal of unused sysfs
- ignore signaled moved fences
- ioremap buffer according to mem caching
i915:
- Alderlake S enablement
- Conversion to dma_resv_locking
- Bring back watchdog timeout support
- legacy ioctl cleanups
- add GEM TDDO and RFC process
- DG1 LMEM preparation work
- intel_display.c refactoring
- Gen9/TGL PCH combination support
- eDP MSO Support
- multiple PSR instance support
- Link training debug updates
- Disable PSR2 support on JSL/EHL
- DDR5/LPDDR5 support for bw calcs
- LSPCON limited to gen9/10 platforms
- HSW/BDW async flip/VTd corruption workaround
- SAGV watermark fixes
- SNB hard hang on ring resume fix
- Limit imported dma-buf size
- move to use new tasklet API
- refactor KBL/TGL/ADL-S display/gt steppings
- refactoring legacy DP/HDMI, FB plane code out
amdgpu:
- uapi: add ioctl to query video capabilities
- Iniital AMD Freesync HDMI support
- Initial Adebaran support
- 10bpc dithering improvements
- DCN secure display support
- Drop legacy IO BAR requirements
- PCIE/S0ix/RAS/Prime/Reset fixes
- Display ASSR support
- SMU gfx busy queues for RV/PCO
- Initial LTTPR display work
amdkfd:
- MMU notifier fixes
- APU fixes
radeon:
- debugfs cleanps
- fw error handling ifix
- Flexible array cleanups
msm:
- big DSI phy/pll cleanup
- sc7280 initial support
- commong bandwidth scaling path
- shrinker locking contention fixes
- unpin/swap support for GEM objcets
ast:
- cursor plane handling reworked
tegra:
- don't register DP AUX channels before connectors
zynqmp:
- fix OOB struct padding memset
gma500:
- drop ttm and medfield support
exynos:
- request_irq cleanup function
mediatek:
- fine tune line time for EOTp
- MT8192 dpi support
- atomic crtc config updates
- don't support HDMI connector creation
mxsdb:
- imx8mm support
panfrost:
- MMU IRQ handling rework
qxl:
- locking fixes
- resource deallocation changes
sun4i:
- add alpha properties to UI/VI layers
vc4:
- RPi4 CEC support
vmwgfx:
- doc cleanups
arc:
- moved to drm/tiny"
* tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm: (1390 commits)
drm/ttm: Don't count pages in SG BOs against pages_limit
drm/ttm: fix return value check
drm/bridge: lt8912b: fix incorrect handling of of_* return values
drm: bridge: fix LONTIUM use of mipi_dsi_() functions
drm: bridge: fix ANX7625 use of mipi_dsi_() functions
drm/amdgpu: page retire over debugfs mechanism
drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
drm/amd/display: Fix the Wunused-function warning
drm/radeon/r600: Fix variables that are not used after assignment
drm/amdgpu/smu7: fix CAC setting on TOPAZ
drm/amd/display: Update DCN302 SR Exit Latency
drm/amdgpu: enable ras eeprom on aldebaran
drm/amdgpu: RAS harvest on driver load
drm/amdgpu: add ras aldebaran ras eeprom driver
drm/amd/pm: increase time out value when sending msg to SMU
drm/amdgpu: add DMUB outbox event IRQ source define/complete/debug flag
drm/amd/pm: add the callback to get vbios bootup values for vangogh
drm/radeon: Fix size overflow
drm/amdgpu: Fix size overflow
drm/amdgpu: move mmhub ras_func init to ip specific file
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 146 |
1 files changed, 124 insertions, 22 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 839917eb7bc3c..9e769cf6095be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -34,6 +34,7 @@ #include "psp_v10_0.h" #include "psp_v11_0.h" #include "psp_v12_0.h" +#include "psp_v13_0.h" #include "amdgpu_ras.h" #include "amdgpu_securedisplay.h" @@ -56,7 +57,7 @@ static int psp_load_smu_fw(struct psp_context *psp); * - Load XGMI/RAS/HDCP/DTM TA if any * * This new sequence is required for - * - Arcturus + * - Arcturus and onwards * - Navi12 and onwards */ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp) @@ -71,7 +72,7 @@ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp if (adev->flags & AMD_IS_APU) return; - if ((adev->asic_type == CHIP_ARCTURUS) || + if ((adev->asic_type >= CHIP_ARCTURUS) || (adev->asic_type >= CHIP_NAVI12)) psp->pmfw_centralized_cstate_management = true; } @@ -109,6 +110,9 @@ static int psp_early_init(void *handle) case CHIP_RENOIR: psp_v12_0_set_psp_funcs(psp); break; + case CHIP_ALDEBARAN: + psp_v13_0_set_psp_funcs(psp); + break; default: return -EINVAL; } @@ -383,7 +387,7 @@ static int psp_tmr_init(struct psp_context *psp) * Note: this memory need be reserved till the driver * uninitializes. */ - tmr_size = PSP_TMR_SIZE; + tmr_size = PSP_TMR_SIZE(psp->adev); /* For ASICs support RLC autoload, psp will parse the toc * and calculate the total size of TMR needed */ @@ -399,10 +403,20 @@ static int psp_tmr_init(struct psp_context *psp) } pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; - ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE, + ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE(psp->adev), AMDGPU_GEM_DOMAIN_VRAM, &psp->tmr_bo, &psp->tmr_mc_addr, pptr); + /* workaround the tmr_mc_addr: + * PSP requires an address in FB aperture. Right now driver produce + * tmr_mc_addr in the GART aperture. Convert it back to FB aperture + * for PSP. Will revert it after we get a fix from PSP FW. + */ + if (psp->adev->asic_type == CHIP_ALDEBARAN) { + psp->tmr_mc_addr -= psp->adev->gmc.fb_start; + psp->tmr_mc_addr += psp->adev->gmc.fb_start_original; + } + return ret; } @@ -542,6 +556,46 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp, return ret; } +static int psp_boot_config_set(struct amdgpu_device *adev) +{ + struct psp_context *psp = &adev->psp; + struct psp_gfx_cmd_resp *cmd = psp->cmd; + + if (adev->asic_type != CHIP_SIENNA_CICHLID) + return 0; + + memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); + + cmd->cmd_id = GFX_CMD_ID_BOOT_CFG; + cmd->cmd.boot_cfg.sub_cmd = BOOTCFG_CMD_SET; + cmd->cmd.boot_cfg.boot_config = BOOT_CONFIG_GECC; + cmd->cmd.boot_cfg.boot_config_valid = BOOT_CONFIG_GECC; + + return psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); +} + +static int psp_rl_load(struct amdgpu_device *adev) +{ + struct psp_context *psp = &adev->psp; + struct psp_gfx_cmd_resp *cmd = psp->cmd; + + if (psp->rl_bin_size == 0) + return 0; + + memset(psp->fw_pri_buf, 0, PSP_1_MEG); + memcpy(psp->fw_pri_buf, psp->rl_start_addr, psp->rl_bin_size); + + memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); + + cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW; + cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(psp->fw_pri_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(psp->fw_pri_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_size = psp->rl_bin_size; + cmd->cmd.cmd_load_ip_fw.fw_type = GFX_FW_TYPE_REG_LIST; + + return psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); +} + static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, uint64_t asd_mc, uint32_t size) { @@ -755,8 +809,9 @@ static int psp_xgmi_unload(struct psp_context *psp) struct psp_gfx_cmd_resp *cmd; struct amdgpu_device *adev = psp->adev; - /* XGMI TA unload currently is not supported on Arcturus */ - if (adev->asic_type == CHIP_ARCTURUS) + /* XGMI TA unload currently is not supported on Arcturus/Aldebaran A+A */ + if (adev->asic_type == CHIP_ARCTURUS || + (adev->asic_type == CHIP_ALDEBARAN && adev->gmc.xgmi.connected_to_cpu)) return 0; /* @@ -1561,6 +1616,7 @@ static int psp_rap_unload(struct psp_context *psp) static int psp_rap_initialize(struct psp_context *psp) { int ret; + enum ta_rap_status status = TA_RAP_STATUS__SUCCESS; /* * TODO: bypass the initialize in sriov for now @@ -1584,8 +1640,8 @@ static int psp_rap_initialize(struct psp_context *psp) if (ret) return ret; - ret = psp_rap_invoke(psp, TA_CMD_RAP__INITIALIZE); - if (ret != TA_RAP_STATUS__SUCCESS) { + ret = psp_rap_invoke(psp, TA_CMD_RAP__INITIALIZE, &status); + if (ret || status != TA_RAP_STATUS__SUCCESS) { psp_rap_unload(psp); amdgpu_bo_free_kernel(&psp->rap_context.rap_shared_bo, @@ -1594,8 +1650,10 @@ static int psp_rap_initialize(struct psp_context *psp) psp->rap_context.rap_initialized = false; - dev_warn(psp->adev->dev, "RAP TA initialize fail.\n"); - return -EINVAL; + dev_warn(psp->adev->dev, "RAP TA initialize fail (%d) status %d.\n", + ret, status); + + return ret; } return 0; @@ -1620,13 +1678,13 @@ static int psp_rap_terminate(struct psp_context *psp) return ret; } -int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id) +int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_status *status) { struct ta_rap_shared_memory *rap_cmd; - int ret; + int ret = 0; if (!psp->rap_context.rap_initialized) - return -EINVAL; + return 0; if (ta_cmd_id != TA_CMD_RAP__INITIALIZE && ta_cmd_id != TA_CMD_RAP__VALIDATE_L0) @@ -1642,14 +1700,16 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id) rap_cmd->validation_method_id = METHOD_A; ret = psp_ta_invoke(psp, rap_cmd->cmd_id, psp->rap_context.session_id); - if (ret) { - mutex_unlock(&psp->rap_context.mutex); - return ret; - } + if (ret) + goto out_unlock; + + if (status) + *status = rap_cmd->rap_status; +out_unlock: mutex_unlock(&psp->rap_context.mutex); - return rap_cmd->rap_status; + return ret; } // RAP end @@ -1870,6 +1930,11 @@ static int psp_hw_start(struct psp_context *psp) return ret; } + ret = psp_boot_config_set(adev); + if (ret) { + DRM_WARN("PSP set boot config@\n"); + } + ret = psp_tmr_init(psp); if (ret) { DRM_ERROR("PSP tmr init failed!\n"); @@ -2104,9 +2169,13 @@ static int psp_load_smu_fw(struct psp_context *psp) if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; - - if (amdgpu_in_reset(adev) && ras && ras->supported && - adev->asic_type == CHIP_ARCTURUS) { + if ((amdgpu_in_reset(adev) && + ras && ras->supported && + (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_VEGA20)) || + (adev->in_runpm && + adev->asic_type >= CHIP_NAVI10 && + adev->asic_type <= CHIP_NAVI12)) { ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD); if (ret) { DRM_WARN("Failed to set MP1 state prepare for reload\n"); @@ -2159,6 +2228,22 @@ static bool fw_load_skip_check(struct psp_context *psp, return false; } +int psp_load_fw_list(struct psp_context *psp, + struct amdgpu_firmware_info **ucode_list, int ucode_count) +{ + int ret = 0, i; + struct amdgpu_firmware_info *ucode; + + for (i = 0; i < ucode_count; ++i) { + ucode = ucode_list[i]; + psp_print_fw_hdr(psp, ucode); + ret = psp_execute_np_fw_load(psp, ucode); + if (ret) + return ret; + } + return ret; +} + static int psp_np_fw_load(struct psp_context *psp) { int i, ret; @@ -2276,6 +2361,12 @@ skip_memalloc: return ret; } + ret = psp_rl_load(adev); + if (ret) { + DRM_ERROR("PSP load RL failed!\n"); + return ret; + } + if (psp->adev->psp.ta_fw) { ret = psp_ras_initialize(psp); if (ret) @@ -2751,6 +2842,9 @@ int psp_init_sos_microcode(struct psp_context *psp, adev->psp.spl_bin_size = le32_to_cpu(sos_hdr_v1_3->spl_size_bytes); adev->psp.spl_start_addr = (uint8_t *)adev->psp.sys_start_addr + le32_to_cpu(sos_hdr_v1_3->spl_offset_bytes); + adev->psp.rl_bin_size = le32_to_cpu(sos_hdr_v1_3->rl_size_bytes); + adev->psp.rl_start_addr = (uint8_t *)adev->psp.sys_start_addr + + le32_to_cpu(sos_hdr_v1_3->rl_offset_bytes); } break; default: @@ -2916,7 +3010,7 @@ static ssize_t psp_usbc_pd_fw_sysfs_read(struct device *dev, return ret; } - return snprintf(buf, PAGE_SIZE, "%x\n", fw_ver); + return sysfs_emit(buf, "%x\n", fw_ver); } static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev, @@ -3052,3 +3146,11 @@ const struct amdgpu_ip_block_version psp_v12_0_ip_block = .rev = 0, .funcs = &psp_ip_funcs, }; + +const struct amdgpu_ip_block_version psp_v13_0_ip_block = { + .type = AMD_IP_BLOCK_TYPE_PSP, + .major = 13, + .minor = 0, + .rev = 0, + .funcs = &psp_ip_funcs, +}; |