diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 08:23:15 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 08:23:15 -0800 |
commit | 851ca779d110f694b5d078bc4af06d3ad37169e8 (patch) | |
tree | 3d03de09e44ef02a6f73924f32fa21646347e64e /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |
parent | b5dd0c658c31b469ccff1b637e5124851e7a4a1c (diff) | |
parent | 4b057e73f28f1df13b77b77a52094238ffdf8abd (diff) |
Merge tag 'drm-next-2019-03-06' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"This is the main drm pull request for the 5.1 merge window.
The big changes I'd highlight are:
- nouveau has HMM support now, there is finally an in-tree user so we
can quieten down the rip it out people.
- i915 now enables fastboot by default on Skylake+
- Displayport Multistream support has been refactored and should
hopefully be more reliable.
Core:
- header cleanups aiming towards removing drmP.h
- dma-buf fence seqnos to 64-bits
- common helper for DP mst hotplug for radeon,i915,amdgpu + new
refcounting scheme
- MST i2c improvements
- drm_syncobj_cb removal
- ARM FB compression fourcc
- P010 + P016 fourcc
- allwinner tiled format modifier
- i2c over aux I2C_M_STOP support
- DRM_AUTH handling fixes
TTM:
- ref/unref renaming
New driver:
- ARM komeda display driver
scheduler:
- refactor mirror list handling
- rework hw fence processing
- 0 run queue entity fix
bridge:
- TI DS90C185 LVDS bridge
- thc631lvdm83d bridge improvements
- cadence + allwinner DSI ported to generic phy
panels:
- Sitronix ST7701 panel
- Kingdisplay KD097D04
- LeMaker BL035-RGB-002
- PDA 91-00156-A0
- Innolux EE101IA-01D
i915:
- Enable fastboot by default on SKL+/VLV/CHV
- Export RPCS configuration for ICL media driver
- Coffelake PCI ID
- CNL clocks setup fixes
- ACPI/PMIC support for MIPI/DSI
- Per-engine WA init for all engines
- Shrinker locking fixes
- Kerneldoc updates
- Lots of ring improvements and reset fixes
- Coffeelake GVT Support
- VFIO GVT EDID Region support
- runtime PM wakeref tracking
- ILK->IVB primary plane enable delays
- userptr mutex locking fixes
- DSI fixes
- LVDS/TV cleanups
- HW readout fixes
- LUT robustness fixes
- ICL display and watermark fixes
- gem mmap race fix
amdgpu:
- add scheduled dependencies interface
- DCC on scanout surfaces
- vega10/20 BACO support
- Multiple IH rings on soc15
- XGMI locking fixes
- DC i2c/aux cleanups
- runtime SMU debug interface
- Kexec improvmeents
- SR-IOV fixes
- DC freesync + ABM fixes
- GDS fixes
- GPUVM fixes
- vega20 PCIE DPM switching fixes
- Context priority handling fixes
radeon:
- fix missing break in evergreen parser
nouveau:
- SVM support via HMM
msm:
- QCOM Compressed modifier support
exynos:
- s5pv210 rotator support
imx:
- zpos property support
- pending update fixes
v3d:
- cache flush improvments
vc4:
- reflection support
- HDMI overscan support
tegra:
- CEC refactoring
- HDMI audio fixes
- Tegra186 prep work
- SOR crossbar device tree fixes
sun4i:
- implicit fencing support
- YUV and scalar support improvements
- A23 support
- tiling fixes
atmel-hlcdc:
- clipping and rotation property fixes
qxl:
- BO and PRIME improvements
- generic fbdev emulation
dw-hdmi:
- HDMI 2.0 2160p
- YUV420 ouput
rockchip:
- implicit fencing support
- reflection proerties
virtio-gpu:
- use generic fbdev emulation
tilcdc:
- cpufreq vs crtc init fix
rcar-du:
- R8A774C0 support
- D3/E3 RGB output routing fixes and DPAD0 support
- RA87744 LVDS support
bochs:
- atomic and generic fbdev emulation
- ID mismatch error on bochs load
meson:
- remove firmware fbs"
* tag 'drm-next-2019-03-06' of git://anongit.freedesktop.org/drm/drm: (1130 commits)
drm/amd/display: Use vrr friendly pageflip throttling in DC.
drm/imx: only send commit done event when all state has been applied
drm/imx: allow building under COMPILE_TEST
drm/imx: imx-tve: depend on COMMON_CLK
drm/imx: ipuv3-plane: add zpos property
drm/imx: ipuv3-plane: add function to query atomic update status
gpu: ipu-v3: prg: add function to get channel configure status
gpu: ipu-v3: pre: add double buffer status readback
drm/amdgpu: Bump amdgpu version for context priority override.
drm/amdgpu/powerplay: fix typo in BACO header guards
drm/amdgpu/powerplay: fix return codes in BACO code
drm/amdgpu: add missing license on baco files
drm/bochs: Fix the ID mismatch error
drm/nouveau/dmem: use dma addresses during migration copies
drm/nouveau/dmem: use physical vram addresses during migration copies
drm/nouveau/dmem: extend copy function to allow direct use of physical addresses
drm/nouveau/svm: new ioctl to migrate process memory to GPU memory
drm/nouveau/dmem: device memory helpers for SVM
drm/nouveau/svm: initial support for shared virtual memory
drm/nouveau: prepare for enabling svm with existing userspace interfaces
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 141 |
1 files changed, 110 insertions, 31 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 3a9b48b227ac..3091488cd8cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -67,9 +67,6 @@ static int psp_sw_init(void *handle) psp->adev = adev; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - ret = psp_init_microcode(psp); if (ret) { DRM_ERROR("Failed to load psp firmware!\n"); @@ -83,9 +80,6 @@ static int psp_sw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - release_firmware(adev->psp.sos_fw); adev->psp.sos_fw = NULL; release_firmware(adev->psp.asd_fw); @@ -142,13 +136,24 @@ psp_cmd_submit_buf(struct psp_context *psp, while (*((unsigned int *)psp->fence_buf) != index) msleep(1); - /* the status field must be 0 after FW is loaded */ - if (ucode && psp->cmd_buf_mem->resp.status) { - DRM_ERROR("failed loading with status (%d) and ucode id (%d)\n", - psp->cmd_buf_mem->resp.status, ucode->ucode_id); - return -EINVAL; + /* In some cases, psp response status is not 0 even there is no + * problem while the command is submitted. Some version of PSP FW + * doesn't write 0 to that field. + * So here we would like to only print a warning instead of an error + * during psp initialization to avoid breaking hw_init and it doesn't + * return -EINVAL. + */ + if (psp->cmd_buf_mem->resp.status) { + if (ucode) + DRM_WARN("failed to load ucode id (%d) ", + ucode->ucode_id); + DRM_WARN("psp command failed and response status is (%d)\n", + psp->cmd_buf_mem->resp.status); } + /* get xGMI session id from response buffer */ + cmd->resp.session_id = psp->cmd_buf_mem->resp.session_id; + if (ucode) { ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi; @@ -500,6 +505,98 @@ static int psp_hw_start(struct psp_context *psp) return 0; } +static int psp_get_fw_type(struct amdgpu_firmware_info *ucode, + enum psp_gfx_fw_type *type) +{ + switch (ucode->ucode_id) { + case AMDGPU_UCODE_ID_SDMA0: + *type = GFX_FW_TYPE_SDMA0; + break; + case AMDGPU_UCODE_ID_SDMA1: + *type = GFX_FW_TYPE_SDMA1; + break; + case AMDGPU_UCODE_ID_CP_CE: + *type = GFX_FW_TYPE_CP_CE; + break; + case AMDGPU_UCODE_ID_CP_PFP: + *type = GFX_FW_TYPE_CP_PFP; + break; + case AMDGPU_UCODE_ID_CP_ME: + *type = GFX_FW_TYPE_CP_ME; + break; + case AMDGPU_UCODE_ID_CP_MEC1: + *type = GFX_FW_TYPE_CP_MEC; + break; + case AMDGPU_UCODE_ID_CP_MEC1_JT: + *type = GFX_FW_TYPE_CP_MEC_ME1; + break; + case AMDGPU_UCODE_ID_CP_MEC2: + *type = GFX_FW_TYPE_CP_MEC; + break; + case AMDGPU_UCODE_ID_CP_MEC2_JT: + *type = GFX_FW_TYPE_CP_MEC_ME2; + break; + case AMDGPU_UCODE_ID_RLC_G: + *type = GFX_FW_TYPE_RLC_G; + break; + case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL: + *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_CNTL; + break; + case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM: + *type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM; + break; + case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM: + *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM; + break; + case AMDGPU_UCODE_ID_SMC: + *type = GFX_FW_TYPE_SMU; + break; + case AMDGPU_UCODE_ID_UVD: + *type = GFX_FW_TYPE_UVD; + break; + case AMDGPU_UCODE_ID_UVD1: + *type = GFX_FW_TYPE_UVD1; + break; + case AMDGPU_UCODE_ID_VCE: + *type = GFX_FW_TYPE_VCE; + break; + case AMDGPU_UCODE_ID_VCN: + *type = GFX_FW_TYPE_VCN; + break; + case AMDGPU_UCODE_ID_DMCU_ERAM: + *type = GFX_FW_TYPE_DMCU_ERAM; + break; + case AMDGPU_UCODE_ID_DMCU_INTV: + *type = GFX_FW_TYPE_DMCU_ISR; + break; + case AMDGPU_UCODE_ID_MAXIMUM: + default: + return -EINVAL; + } + + return 0; +} + +static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode, + struct psp_gfx_cmd_resp *cmd) +{ + int ret; + uint64_t fw_mem_mc_addr = ucode->mc_addr; + + 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(fw_mem_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size; + + ret = psp_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type); + if (ret) + DRM_ERROR("Unknown firmware type\n"); + + return ret; +} + static int psp_np_fw_load(struct psp_context *psp) { int i, ret; @@ -521,7 +618,7 @@ static int psp_np_fw_load(struct psp_context *psp) /*skip ucode loading in SRIOV VF */ continue; - ret = psp_prep_cmd_buf(ucode, psp->cmd); + ret = psp_prep_load_ip_fw_cmd_buf(ucode, psp->cmd); if (ret) return ret; @@ -546,7 +643,7 @@ static int psp_load_fw(struct amdgpu_device *adev) struct psp_context *psp = &adev->psp; if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) { - psp_ring_destroy(psp, PSP_RING_TYPE__KM); + psp_ring_stop(psp, PSP_RING_TYPE__KM); /* should not destroy ring, only stop */ goto skip_memalloc; } @@ -623,10 +720,6 @@ static int psp_hw_init(void *handle) int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - mutex_lock(&adev->firmware.mutex); /* * This sequence is just used on hw_init only once, no need on @@ -656,9 +749,6 @@ static int psp_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - if (adev->gmc.xgmi.num_physical_nodes > 1 && psp->xgmi_context.initialized == 1) psp_xgmi_terminate(psp); @@ -687,9 +777,6 @@ static int psp_suspend(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - if (adev->gmc.xgmi.num_physical_nodes > 1 && psp->xgmi_context.initialized == 1) { ret = psp_xgmi_terminate(psp); @@ -714,9 +801,6 @@ static int psp_resume(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) - return 0; - DRM_INFO("PSP is resuming...\n"); mutex_lock(&adev->firmware.mutex); @@ -752,11 +836,6 @@ static bool psp_check_fw_loading_status(struct amdgpu_device *adev, { struct amdgpu_firmware_info *ucode = NULL; - if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { - DRM_INFO("firmware is not loaded by PSP\n"); - return true; - } - if (!adev->firmware.fw_size) return false; |