diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-02 16:59:23 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-02 16:59:23 +0200 |
commit | 320b164abb32db876866a4ff8c2cb710524ac6ea (patch) | |
tree | 1f79119cde6e24c9f1d01fb1e51252bca7c4cdd5 /drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |
parent | Linux 4.16 (diff) | |
parent | Merge branch 'drm-misc-next-fixes' of git://anongit.freedesktop.org/drm/drm-m... (diff) | |
download | linux-320b164abb32db876866a4ff8c2cb710524ac6ea.tar.xz linux-320b164abb32db876866a4ff8c2cb710524ac6ea.zip |
Merge tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Cannonlake and Vega12 support are probably the two major things. This
pull lacks nouveau, Ben had some unforseen leave and a few other
blockers so we'll see how things look or maybe leave it for this merge
window.
core:
- Device links to handle sound/gpu pm dependency
- Color encoding/range properties
- Plane clipping into plane check helper
- Backlight helpers
- DP TP4 + HBR3 helper support
amdgpu:
- Vega12 support
- Enable DC by default on all supported GPUs
- Powerplay restructuring and cleanup
- DC bandwidth calc updates
- DC backlight on pre-DCE11
- TTM backing store dropping support
- SR-IOV fixes
- Adding "wattman" like functionality
- DC crc support
- Improved DC dual-link handling
amdkfd:
- GPUVM support for dGPU
- KFD events for dGPU
- Enable PCIe atomics for dGPUs
- HSA process eviction support
- Live-lock fixes for process eviction
- VM page table allocation fix for large-bar systems
panel:
- Raydium RM68200
- AUO G104SN02 V2
- KEO TX31D200VM0BAA
- ARM Versatile panels
i915:
- Cannonlake support enabled
- AUX-F port support added
- Icelake base enabling until internal milestone of forcewake support
- Query uAPI interface (used for GPU topology information currently)
- Compressed framebuffer support for sprites
- kmem cache shrinking when GPU is idle
- Avoid boosting GPU when waited item is being processed already
- Avoid retraining LSPCON link unnecessarily
- Decrease request signaling latency
- Deprecation of I915_SET_COLORKEY_NONE
- Kerneldoc and compiler warning cleanup for upcoming CI enforcements
- Full range ycbcr toggling
- HDCP support
i915/gvt:
- Big refactor for shadow ppgtt
- KBL context save/restore via LRI cmd (Weinan)
- Properly unmap dma for guest page (Changbin)
vmwgfx:
- Lots of various improvements
etnaviv:
- Use the drm gpu scheduler
- prep work for GC7000L support
vc4:
- fix alpha blending
- Expose perf counters to userspace
pl111:
- Bandwidth checking/limiting
- Versatile panel support
sun4i:
- A83T HDMI support
- A80 support
- YUV plane support
- H3/H5 HDMI support
omapdrm:
- HPD support for DVI connector
- remove lots of static variables
msm:
- DSI updates from 10nm / SDM845
- fix for race condition with a3xx/a4xx fence completion irq
- some refactoring/prep work for eventual a6xx support (ie. when we
have a userspace)
- a5xx debugfs enhancements
- some mdp5 fixes/cleanups to prepare for eventually merging
writeback
- support (ie. when we have a userspace)
tegra:
- mmap() fixes for fbdev devices
- Overlay plane for hw cursor fix
- dma-buf cache maintenance support
mali-dp:
- YUV->RGB conversion support
rockchip:
- rk3399/chromebook fixes and improvements
rcar-du:
- LVDS support move to drm bridge
- DT bindings for R8A77995
- Driver/DT support for R8A77970
tilcdc:
- DRM panel support"
* tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux: (1646 commits)
drm/i915: Fix hibernation with ACPI S0 target state
drm/i915/execlists: Use a locked clear_bit() for synchronisation with interrupt
drm/i915: Specify which engines to reset following semaphore/event lockups
drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.
drm/amdkfd: Use ordered workqueue to restore processes
drm/amdgpu: Fix acquiring VM on large-BAR systems
drm/amd/pp: clean header file hwmgr.h
drm/amd/pp: use mlck_table.count for array loop index limit
drm: Fix uabi regression by allowing garbage mode->type from userspace
drm/amdgpu: Add an ATPX quirk for hybrid laptop
drm/amdgpu: fix spelling mistake: "asssert" -> "assert"
drm/amd/pp: Add new asic support in pp_psm.c
drm/amd/pp: Clean up powerplay code on Vega12
drm/amd/pp: Add smu irq handlers for legacy asics
drm/amd/pp: Fix set wrong temperature range on smu7
drm/amdgpu: Don't change preferred domian when fallback GTT v5
drm/vmwgfx: Bump version patchlevel and date
drm/vmwgfx: use monotonic event timestamps
drm/vmwgfx: Unpin the screen object backup buffer when not used
drm/vmwgfx: Stricter count of legacy surface device resources
...
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fb.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 106 |
1 files changed, 45 insertions, 61 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index d23a18aae476..2582ffd36bb5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -43,8 +43,6 @@ struct vmw_fb_par { struct mutex bo_mutex; struct vmw_dma_buffer *vmw_bo; - struct ttm_bo_kmap_obj map; - void *bo_ptr; unsigned bo_size; struct drm_framebuffer *set_fb; struct drm_display_mode *set_mode; @@ -163,10 +161,17 @@ static int vmw_fb_blank(int blank, struct fb_info *info) return 0; } -/* - * Dirty code +/** + * vmw_fb_dirty_flush - flush dirty regions to the kms framebuffer + * + * @work: The struct work_struct associated with this task. + * + * This function flushes the dirty regions of the vmalloc framebuffer to the + * kms framebuffer, and if the kms framebuffer is visible, also updated the + * corresponding displays. Note that this function runs even if the kms + * framebuffer is not bound to a crtc and thus not visible, but it's turned + * off during hibernation using the par->dirty.active bool. */ - static void vmw_fb_dirty_flush(struct work_struct *work) { struct vmw_fb_par *par = container_of(work, struct vmw_fb_par, @@ -174,13 +179,15 @@ static void vmw_fb_dirty_flush(struct work_struct *work) struct vmw_private *vmw_priv = par->vmw_priv; struct fb_info *info = vmw_priv->fb_info; unsigned long irq_flags; - s32 dst_x1, dst_x2, dst_y1, dst_y2, w, h; + s32 dst_x1, dst_x2, dst_y1, dst_y2, w = 0, h = 0; u32 cpp, max_x, max_y; struct drm_clip_rect clip; struct drm_framebuffer *cur_fb; u8 *src_ptr, *dst_ptr; + struct vmw_dma_buffer *vbo = par->vmw_bo; + void *virtual; - if (vmw_priv->suspended) + if (!READ_ONCE(par->dirty.active)) return; mutex_lock(&par->bo_mutex); @@ -188,10 +195,16 @@ static void vmw_fb_dirty_flush(struct work_struct *work) if (!cur_fb) goto out_unlock; + (void) ttm_read_lock(&vmw_priv->reservation_sem, false); + (void) ttm_bo_reserve(&vbo->base, false, false, NULL); + virtual = vmw_dma_buffer_map_and_cache(vbo); + if (!virtual) + goto out_unreserve; + spin_lock_irqsave(&par->dirty.lock, irq_flags); if (!par->dirty.active) { spin_unlock_irqrestore(&par->dirty.lock, irq_flags); - goto out_unlock; + goto out_unreserve; } /* @@ -221,7 +234,7 @@ static void vmw_fb_dirty_flush(struct work_struct *work) spin_unlock_irqrestore(&par->dirty.lock, irq_flags); if (w && h) { - dst_ptr = (u8 *)par->bo_ptr + + dst_ptr = (u8 *)virtual + (dst_y1 * par->set_fb->pitches[0] + dst_x1 * cpp); src_ptr = (u8 *)par->vmalloc + ((dst_y1 + par->fb_y) * info->fix.line_length + @@ -237,7 +250,12 @@ static void vmw_fb_dirty_flush(struct work_struct *work) clip.x2 = dst_x2; clip.y1 = dst_y1; clip.y2 = dst_y2; + } +out_unreserve: + ttm_bo_unreserve(&vbo->base); + ttm_read_unlock(&vmw_priv->reservation_sem); + if (w && h) { WARN_ON_ONCE(par->set_fb->funcs->dirty(cur_fb, NULL, 0, 0, &clip, 1)); vmw_fifo_flush(vmw_priv, false); @@ -500,22 +518,12 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, } if (cur_fb) { - drm_framebuffer_unreference(cur_fb); + drm_framebuffer_put(cur_fb); par->set_fb = NULL; } - if (par->vmw_bo && detach_bo) { - struct vmw_private *vmw_priv = par->vmw_priv; - - if (par->bo_ptr) { - ttm_bo_kunmap(&par->map); - par->bo_ptr = NULL; - } - if (unref_bo) - vmw_dmabuf_unreference(&par->vmw_bo); - else if (vmw_priv->active_display_unit != vmw_du_legacy) - vmw_dmabuf_unpin(par->vmw_priv, par->vmw_bo, false); - } + if (par->vmw_bo && detach_bo && unref_bo) + vmw_dmabuf_unreference(&par->vmw_bo); return 0; } @@ -636,38 +644,6 @@ static int vmw_fb_set_par(struct fb_info *info) if (ret) goto out_unlock; - if (!par->bo_ptr) { - struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb); - - /* - * Pin before mapping. Since we don't know in what placement - * to pin, call into KMS to do it for us. LDU doesn't require - * additional pinning because set_config() would've pinned - * it already - */ - if (vmw_priv->active_display_unit != vmw_du_legacy) { - ret = vfb->pin(vfb); - if (ret) { - DRM_ERROR("Could not pin the fbdev " - "framebuffer.\n"); - goto out_unlock; - } - } - - ret = ttm_bo_kmap(&par->vmw_bo->base, 0, - par->vmw_bo->base.num_pages, &par->map); - if (ret) { - if (vmw_priv->active_display_unit != vmw_du_legacy) - vfb->unpin(vfb); - - DRM_ERROR("Could not map the fbdev framebuffer.\n"); - goto out_unlock; - } - - par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite); - } - - vmw_fb_dirty_mark(par, par->fb_x, par->fb_y, par->set_fb->width, par->set_fb->height); @@ -883,12 +859,6 @@ int vmw_fb_off(struct vmw_private *vmw_priv) flush_delayed_work(&info->deferred_work); flush_delayed_work(&par->local_work); - mutex_lock(&par->bo_mutex); - drm_modeset_lock_all(vmw_priv->dev); - (void) vmw_fb_kms_detach(par, true, false); - drm_modeset_unlock_all(vmw_priv->dev); - mutex_unlock(&par->bo_mutex); - return 0; } @@ -904,10 +874,24 @@ int vmw_fb_on(struct vmw_private *vmw_priv) info = vmw_priv->fb_info; par = info->par; - vmw_fb_set_par(info); spin_lock_irqsave(&par->dirty.lock, flags); par->dirty.active = true; spin_unlock_irqrestore(&par->dirty.lock, flags); return 0; } + +/** + * vmw_fb_refresh - Refresh fb display + * + * @vmw_priv: Pointer to device private + * + * Call into kms to show the fbdev display(s). + */ +void vmw_fb_refresh(struct vmw_private *vmw_priv) +{ + if (!vmw_priv->fb_info) + return; + + vmw_fb_set_par(vmw_priv->fb_info); +} |