diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-03 11:44:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-03 11:44:24 -0700 |
commit | 2f34c1231bfc9f2550f934acb268ac7315fb3837 (patch) | |
tree | ff8114b3b4ec4723a11b041c6b74c389e9f0eeb9 /drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c | |
parent | a3719f34fdb664ffcfaec2160ef20fca7becf2ee (diff) | |
parent | 8b03d1ed2c43a2ba5ef3381322ee4515b97381bf (diff) | |
download | linux-2f34c1231bfc9f2550f934acb268ac7315fb3837.tar.gz linux-2f34c1231bfc9f2550f934acb268ac7315fb3837.tar.bz2 linux-2f34c1231bfc9f2550f934acb268ac7315fb3837.zip |
Merge tag 'drm-for-v4.12' of git://people.freedesktop.org/~airlied/linux
Pull drm u pdates from Dave Airlie:
"This is the main drm pull request for v4.12. Apart from two fixes
pulls, everything should have been in drm-next for at least 2 weeks.
The biggest thing in here is AMD released the public headers for their
upcoming VEGA GPUs. These as always are quite a sizeable chunk of
header files. They've also added initial non-display support for those
GPUs, though they aren't available in production yet.
Otherwise it's pretty much normal.
New bridge drivers:
- megachips-stdpxxxx-ge-b850v3-fw LVDS->DP++
- generic LVDS bridge support.
Core:
- Displayport link train failure reporting to userspace
- debugfs interface cleaned up
- subsystem TODO in kerneldoc now
- Extended fbdev support (flipping and vblank wait)
- drm_platform removed
- EDP CRC support in helper
- HF-VSDB SCDC support in EDID parser
- Lots of code cleanups and header extraction
- Thunderbolt external GPU awareness
- Atomic helper improvements
- Documentation improvements
panel:
- Sitronix and Samsung new panel support
amdgpu:
- Preliminary vega10 support
- Multi-level page table support
- GPU sensor support for userspace
- PRT support for sparse buffers
- SR-IOV improvements
- Non-contig VRAM CPU mapping
i915:
- Atomic modesetting enabled by default on Gen5+
- LSPCON improvements
- Atomic state handling for cdclk
- GPU reset improvements
- In-kernel unit tests
- Geminilake improvements and color manager support
- Designware i2c fixes
- vblank evasion improvements
- Hotplug safe connector iterators
- GVT scheduler QoS support
- GVT Kabylake support
nouveau:
- Acceleration support for Pascal (GP10x).
- Rearchitecture of code handling proprietary signed firmware
- Fix GTX 970 with odd MMU configuration
- GP10B support
- GP107 acceleration support
vmwgfx:
- Atomic modesetting support for vmwgfx
omapdrm:
- Support for render nodes
- Refactor omapdss code
- Fix some probe ordering issues
- Fix too dark RGB565 rendering
sunxi:
- prelim rework for multiple pipes.
mali-dp:
- Color management support
- Plane scaling
- Power management improvements
imx-drm:
- Prefetch Resolve Engine/Gasket on i.MX6QP
- Deferred plane disabling
- Separate alpha support
mediatek:
- Mediatek SoC MT2701 support
rcar-du:
- Gen3 HDMI support
msm:
- 4k support for newer chips
- OPP bindings for gpu
- prep work for per-process pagetables
vc4:
- HDMI audio support
- fixes
qxl:
- minor fixes.
dw-hdmi:
- PHY improvements
- CSC fixes
- Amlogic GX SoC support"
* tag 'drm-for-v4.12' of git://people.freedesktop.org/~airlied/linux: (1778 commits)
drm/nouveau/fb/gf100-: Fix 32 bit wraparound in new ram detection
drm/nouveau/secboot/gm20b: fix the error return code in gm20b_secboot_tegra_read_wpr()
drm/nouveau/kms: Increase max retries in scanout position queries.
drm/nouveau/bios/bitP: check that table is long enough for optional pointers
drm/nouveau/fifo/nv40: no ctxsw for pre-nv44 mpeg engine
drm: mali-dp: use div_u64 for expensive 64-bit divisions
drm/i915: Confirm the request is still active before adding it to the await
drm/i915: Avoid busy-spinning on VLV_GLTC_PW_STATUS mmio
drm/i915/selftests: Allocate inode/file dynamically
drm/i915: Fix system hang with EI UP masked on Haswell
drm/i915: checking for NULL instead of IS_ERR() in mock selftests
drm/i915: Perform link quality check unconditionally during long pulse
drm/i915: Fix use after free in lpe_audio_platdev_destroy()
drm/i915: Use the right mapping_gfp_mask for final shmem allocation
drm/i915: Make legacy cursor updates more unsynced
drm/i915: Apply a cond_resched() to the saturated signaler
drm/i915: Park the signaler before sleeping
drm: mali-dp: Check the mclk rate and allow up/down scaling
drm: mali-dp: Enable image enhancement when scaling
drm: mali-dp: Add plane upscaling support
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c | 102 |
1 files changed, 60 insertions, 42 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c index d2622b6f49fa..70a3dd13cb02 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c @@ -318,31 +318,46 @@ void xgpu_vi_init_golden_registers(struct amdgpu_device *adev) static void xgpu_vi_mailbox_send_ack(struct amdgpu_device *adev) { u32 reg; + int timeout = VI_MAILBOX_TIMEDOUT; + u32 mask = REG_FIELD_MASK(MAILBOX_CONTROL, RCV_MSG_VALID); - reg = RREG32(mmMAILBOX_CONTROL); + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); reg = REG_SET_FIELD(reg, MAILBOX_CONTROL, RCV_MSG_ACK, 1); - WREG32(mmMAILBOX_CONTROL, reg); + WREG32_NO_KIQ(mmMAILBOX_CONTROL, reg); + + /*Wait for RCV_MSG_VALID to be 0*/ + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); + while (reg & mask) { + if (timeout <= 0) { + pr_err("RCV_MSG_VALID is not cleared\n"); + break; + } + mdelay(1); + timeout -=1; + + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); + } } static void xgpu_vi_mailbox_set_valid(struct amdgpu_device *adev, bool val) { u32 reg; - reg = RREG32(mmMAILBOX_CONTROL); + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); reg = REG_SET_FIELD(reg, MAILBOX_CONTROL, TRN_MSG_VALID, val ? 1 : 0); - WREG32(mmMAILBOX_CONTROL, reg); + WREG32_NO_KIQ(mmMAILBOX_CONTROL, reg); } static void xgpu_vi_mailbox_trans_msg(struct amdgpu_device *adev, - enum idh_event event) + enum idh_request req) { u32 reg; - reg = RREG32(mmMAILBOX_MSGBUF_TRN_DW0); + reg = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW0); reg = REG_SET_FIELD(reg, MAILBOX_MSGBUF_TRN_DW0, - MSGBUF_DATA, event); - WREG32(mmMAILBOX_MSGBUF_TRN_DW0, reg); + MSGBUF_DATA, req); + WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW0, reg); xgpu_vi_mailbox_set_valid(adev, true); } @@ -351,8 +366,13 @@ static int xgpu_vi_mailbox_rcv_msg(struct amdgpu_device *adev, enum idh_event event) { u32 reg; + u32 mask = REG_FIELD_MASK(MAILBOX_CONTROL, RCV_MSG_VALID); - reg = RREG32(mmMAILBOX_MSGBUF_RCV_DW0); + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); + if (!(reg & mask)) + return -ENOENT; + + reg = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW0); if (reg != event) return -ENOENT; @@ -368,7 +388,7 @@ static int xgpu_vi_poll_ack(struct amdgpu_device *adev) u32 mask = REG_FIELD_MASK(MAILBOX_CONTROL, TRN_MSG_ACK); u32 reg; - reg = RREG32(mmMAILBOX_CONTROL); + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); while (!(reg & mask)) { if (timeout <= 0) { pr_err("Doesn't get ack from pf.\n"); @@ -378,7 +398,7 @@ static int xgpu_vi_poll_ack(struct amdgpu_device *adev) msleep(1); timeout -= 1; - reg = RREG32(mmMAILBOX_CONTROL); + reg = RREG32_NO_KIQ(mmMAILBOX_CONTROL); } return r; @@ -419,7 +439,9 @@ static int xgpu_vi_send_access_requests(struct amdgpu_device *adev, xgpu_vi_mailbox_set_valid(adev, false); /* start to check msg if request is idh_req_gpu_init_access */ - if (request == IDH_REQ_GPU_INIT_ACCESS) { + if (request == IDH_REQ_GPU_INIT_ACCESS || + request == IDH_REQ_GPU_FINI_ACCESS || + request == IDH_REQ_GPU_RESET_ACCESS) { r = xgpu_vi_poll_msg(adev, IDH_READY_TO_ACCESS_GPU); if (r) return r; @@ -436,20 +458,20 @@ static int xgpu_vi_request_reset(struct amdgpu_device *adev) static int xgpu_vi_request_full_gpu_access(struct amdgpu_device *adev, bool init) { - enum idh_event event; + enum idh_request req; - event = init ? IDH_REQ_GPU_INIT_ACCESS : IDH_REQ_GPU_FINI_ACCESS; - return xgpu_vi_send_access_requests(adev, event); + req = init ? IDH_REQ_GPU_INIT_ACCESS : IDH_REQ_GPU_FINI_ACCESS; + return xgpu_vi_send_access_requests(adev, req); } static int xgpu_vi_release_full_gpu_access(struct amdgpu_device *adev, bool init) { - enum idh_event event; + enum idh_request req; int r = 0; - event = init ? IDH_REL_GPU_INIT_ACCESS : IDH_REL_GPU_FINI_ACCESS; - r = xgpu_vi_send_access_requests(adev, event); + req = init ? IDH_REL_GPU_INIT_ACCESS : IDH_REL_GPU_FINI_ACCESS; + r = xgpu_vi_send_access_requests(adev, req); return r; } @@ -468,28 +490,28 @@ static int xgpu_vi_set_mailbox_ack_irq(struct amdgpu_device *adev, unsigned type, enum amdgpu_interrupt_state state) { - u32 tmp = RREG32(mmMAILBOX_INT_CNTL); + u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL); tmp = REG_SET_FIELD(tmp, MAILBOX_INT_CNTL, ACK_INT_EN, (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0); - WREG32(mmMAILBOX_INT_CNTL, tmp); + WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp); return 0; } static void xgpu_vi_mailbox_flr_work(struct work_struct *work) { - struct amdgpu_virt *virt = container_of(work, - struct amdgpu_virt, flr_work.work); - struct amdgpu_device *adev = container_of(virt, - struct amdgpu_device, virt); - int r = 0; + struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, flr_work); + struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); - r = xgpu_vi_poll_msg(adev, IDH_FLR_NOTIFICATION_CMPL); - if (r) - DRM_ERROR("failed to get flr cmpl msg from hypervior.\n"); + /* wait until RCV_MSG become 3 */ + if (xgpu_vi_poll_msg(adev, IDH_FLR_NOTIFICATION_CMPL)) { + pr_err("failed to recieve FLR_CMPL\n"); + return; + } - /* TODO: need to restore gfx states */ + /* Trigger recovery due to world switch failure */ + amdgpu_sriov_gpu_reset(adev, false); } static int xgpu_vi_set_mailbox_rcv_irq(struct amdgpu_device *adev, @@ -497,11 +519,11 @@ static int xgpu_vi_set_mailbox_rcv_irq(struct amdgpu_device *adev, unsigned type, enum amdgpu_interrupt_state state) { - u32 tmp = RREG32(mmMAILBOX_INT_CNTL); + u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL); tmp = REG_SET_FIELD(tmp, MAILBOX_INT_CNTL, VALID_INT_EN, (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0); - WREG32(mmMAILBOX_INT_CNTL, tmp); + WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp); return 0; } @@ -512,15 +534,12 @@ static int xgpu_vi_mailbox_rcv_irq(struct amdgpu_device *adev, { int r; - adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME; + /* see what event we get */ r = xgpu_vi_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION); - /* do nothing for other msg */ - if (r) - return 0; - /* TODO: need to save gfx states */ - schedule_delayed_work(&adev->virt.flr_work, - msecs_to_jiffies(VI_MAILBOX_RESET_TIME)); + /* only handle FLR_NOTIFY now */ + if (!r) + schedule_work(&adev->virt.flr_work); return 0; } @@ -547,11 +566,11 @@ int xgpu_vi_mailbox_add_irq_id(struct amdgpu_device *adev) { int r; - r = amdgpu_irq_add_id(adev, 135, &adev->virt.rcv_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 135, &adev->virt.rcv_irq); if (r) return r; - r = amdgpu_irq_add_id(adev, 138, &adev->virt.ack_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 138, &adev->virt.ack_irq); if (r) { amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0); return r; @@ -573,14 +592,13 @@ int xgpu_vi_mailbox_get_irq(struct amdgpu_device *adev) return r; } - INIT_DELAYED_WORK(&adev->virt.flr_work, xgpu_vi_mailbox_flr_work); + INIT_WORK(&adev->virt.flr_work, xgpu_vi_mailbox_flr_work); return 0; } void xgpu_vi_mailbox_put_irq(struct amdgpu_device *adev) { - cancel_delayed_work_sync(&adev->virt.flr_work); amdgpu_irq_put(adev, &adev->virt.ack_irq, 0); amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0); } |