]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'drm-for-v4.10' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 17:35:09 +0000 (09:35 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 17:35:09 +0000 (09:35 -0800)
Pull drm updates from Dave Airlie:
 "This is the main pull request for drm for 4.10 kernel.

  New drivers:
   - ZTE VOU display driver (zxdrm)
   - Amlogic Meson Graphic Controller GXBB/GXL/GXM SoCs (meson)
   - MXSFB support (mxsfb)

  Core:
   - Format handling has been reworked
   - Better atomic state debugging
   - drm_mm leak debugging
   - Atomic explicit fencing support
   - fbdev helper ops
   - Documentation updates
   - MST fbcon fixes

  Bridge:
   - Silicon Image SiI8620 driver

  Panel:
   - Add support for new simple panels

  i915:
   - GVT Device model
   - Better HDMI2.0 support on skylake
   - More watermark fixes
   - GPU idling rework for suspend/resume
   - DP Audio workarounds
   - Scheduler prep-work
   - Opregion CADL handling
   - GPU scheduler and priority boosting

  amdgfx/radeon:
   - Support for virtual devices
   - New VM manager for non-contig VRAM buffers
   - UVD powergating
   - SI register header cleanup
   - Cursor fixes
   - Powermanagement fixes

  nouveau:
   - Powermangement reworks for better voltage/clock changes
   - Atomic modesetting support
   - Displayport Multistream (MST) support.
   - GP102/104 hang and cursor fixes
   - GP106 support

  hisilicon:
   - hibmc support (BMC chip for aarch64 servers)

  armada:
   - add tracing support for overlay change
   - refactor plane support
   - de-midlayer the driver

  omapdrm:
   - Timing code cleanups

  rcar-du:
   - R8A7792/R8A7796 support
   - Misc fixes.

  sunxi:
   - A31 SoC display engine support

  imx-drm:
   - YUV format support
   - Cleanup plane atomic update

  mali-dp:
   - Misc fixes

  dw-hdmi:
   - Add support for HDMI i2c master controller

  tegra:
   - IOMMU support fixes
   - Error handling fixes

  tda998x:
   - Fix connector registration
   - Improved robustness
   - Fix infoframe/audio compliance

  virtio:
   - fix busid issues
   - allocate more vbufs

  qxl:
   - misc fixes and cleanups.

  vc4:
   - Fragment shader threading
   - ETC1 support
   - VEC (tv-out) support

  msm:
   - A5XX GPU support
   - Lots of atomic changes

  tilcdc:
   - Misc fixes and cleanups.

  etnaviv:
   - Fix dma-buf export path
   - DRAW_INSTANCED support
   - fix driver on i.MX6SX

  exynos:
   - HDMI refactoring

  fsl-dcu:
   - fbdev changes"

* tag 'drm-for-v4.10' of git://people.freedesktop.org/~airlied/linux: (1343 commits)
  drm/nouveau/kms/nv50: fix atomic regression on original G80
  drm/nouveau/bl: Do not register interface if Apple GMUX detected
  drm/nouveau/bl: Assign different names to interfaces
  drm/nouveau/bios/dp: fix handling of LevelEntryTableIndex on DP table 4.2
  drm/nouveau/ltc: protect clearing of comptags with mutex
  drm/nouveau/gr/gf100-: handle GPC/TPC/MPC trap
  drm/nouveau/core: recognise GP106 chipset
  drm/nouveau/ttm: wait for bo fence to signal before unmapping vmas
  drm/nouveau/gr/gf100-: FECS intr handling is not relevant on proprietary ucode
  drm/nouveau/gr/gf100-: properly ack all FECS error interrupts
  drm/nouveau/fifo/gf100-: recover from host mmu faults
  drm: Add fake controlD* symlinks for backwards compat
  drm/vc4: Don't use drm_put_dev
  drm/vc4: Document VEC DT binding
  drm/vc4: Add support for the VEC (Video Encoder) IP
  drm: Add TV connector states to drm_connector_state
  drm: Turn DRM_MODE_SUBCONNECTOR_xx definitions into an enum
  drm/vc4: Fix ->clock_select setting for the VEC encoder
  drm/amdgpu/dce6: Set MASTER_UPDATE_MODE to 0 in resume_mc_access as well
  drm/amdgpu: use pin rather than pin_restricted in a few cases
  ...

1  2 
Documentation/gpu/drm-kms.rst
MAINTAINERS
arch/x86/kvm/x86.c
drivers/base/Kconfig
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/include/cgs_common.h
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_gem_shrinker.c

index 38af5d1cc59f53f6ab915e263ff30a653310b010,0ef21076012b7f24a1496dd89e8c2489b0da6c08..0c9abdc0ee315b69c39685ae9e0b6bf61312f0c6
@@@ -15,25 -15,24 +15,24 @@@ be setup by initializing the following 
  -  struct drm_mode_config_funcs \*funcs;
     Mode setting functions.
  
- Modeset Base Object Abstraction
- ===============================
+ Mode Configuration
  
- .. kernel-doc:: include/drm/drm_mode_object.h
-    :internal:
+ KMS Core Structures and Functions
+ =================================
  
- .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c
+ .. kernel-doc:: drivers/gpu/drm/drm_mode_config.c
     :export:
  
- KMS Data Structures
- ===================
- .. kernel-doc:: include/drm/drm_crtc.h
+ .. kernel-doc:: include/drm/drm_mode_config.h
     :internal:
  
- KMS API Functions
- =================
+ Modeset Base Object Abstraction
+ ===============================
  
- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c
+ .. kernel-doc:: include/drm/drm_mode_object.h
+    :internal:
+ .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c
     :export:
  
  Atomic Mode Setting Function Reference
  .. kernel-doc:: include/drm/drm_atomic.h
     :internal:
  
+ CRTC Abstraction
+ ================
+ .. kernel-doc:: drivers/gpu/drm/drm_crtc.c
+    :export:
+ .. kernel-doc:: include/drm/drm_crtc.h
+    :internal:
  Frame Buffer Abstraction
  ========================
  
@@@ -63,52 -71,17 +71,17 @@@ Frame Buffer Functions Referenc
  DRM Format Handling
  ===================
  
+ .. kernel-doc:: include/drm/drm_fourcc.h
+    :internal:
  .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c
     :export:
  
  Dumb Buffer Objects
  ===================
  
- The KMS API doesn't standardize backing storage object creation and
- leaves it to driver-specific ioctls. Furthermore actually creating a
- buffer object even for GEM-based drivers is done through a
- driver-specific ioctl - GEM only has a common userspace interface for
- sharing and destroying objects. While not an issue for full-fledged
- graphics stacks that include device-specific userspace components (in
- libdrm for instance), this limit makes DRM-based early boot graphics
- unnecessarily complex.
- Dumb objects partly alleviate the problem by providing a standard API to
- create dumb buffers suitable for scanout, which can then be used to
- create KMS frame buffers.
- To support dumb objects drivers must implement the dumb_create,
- dumb_destroy and dumb_map_offset operations.
- -  int (\*dumb_create)(struct drm_file \*file_priv, struct
-    drm_device \*dev, struct drm_mode_create_dumb \*args);
-    The dumb_create operation creates a driver object (GEM or TTM
-    handle) suitable for scanout based on the width, height and depth
-    from the struct :c:type:`struct drm_mode_create_dumb
-    <drm_mode_create_dumb>` argument. It fills the argument's
-    handle, pitch and size fields with a handle for the newly created
-    object and its line pitch and size in bytes.
- -  int (\*dumb_destroy)(struct drm_file \*file_priv, struct
-    drm_device \*dev, uint32_t handle);
-    The dumb_destroy operation destroys a dumb object created by
-    dumb_create.
- -  int (\*dumb_map_offset)(struct drm_file \*file_priv, struct
-    drm_device \*dev, uint32_t handle, uint64_t \*offset);
-    The dumb_map_offset operation associates an mmap fake offset with
-    the object given by the handle and returns it. Drivers must use the
-    :c:func:`drm_gem_create_mmap_offset()` function to associate
-    the fake offset as described in ?.
- Note that dumb objects may not be used for gpu acceleration, as has been
- attempted on some ARM embedded platforms. Such drivers really must have
- a hardware-specific ioctl to allocate suitable buffer objects.
+ .. kernel-doc:: drivers/gpu/drm/drm_dumb_buffers.c
+    :doc: overview
  
  Plane Abstraction
  =================
@@@ -215,7 -188,7 +188,7 @@@ Connectors state change detection must 
  Output discovery and initialization example
  -------------------------------------------
  
 -::
 +.. code-block:: c
  
      void intel_crt_init(struct drm_device *dev)
      {
@@@ -287,6 -260,12 +260,12 @@@ Property Types and Blob Property Suppor
  .. kernel-doc:: drivers/gpu/drm/drm_property.c
     :export:
  
+ Standard Connector Properties
+ -----------------------------
+ .. kernel-doc:: drivers/gpu/drm/drm_connector.c
+    :doc: standard connector properties
  Plane Composition Properties
  ----------------------------
  
@@@ -308,6 -287,18 +287,18 @@@ Color Management Propertie
  .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
     :export:
  
+ Tile Group Property
+ -------------------
+ .. kernel-doc:: drivers/gpu/drm/drm_connector.c
+    :doc: Tile group
+ Explicit Fencing Properties
+ ---------------------------
+ .. kernel-doc:: drivers/gpu/drm/drm_atomic.c
+    :doc: explicit fencing properties
  Existing KMS Properties
  -----------------------
  
diff --combined MAINTAINERS
index 21a7e7e0aef0658158fdf4fb6b021a5f9bd88abf,1a7a773114aa26b274adab6a3106921c63fd5ab2..81d597ca73c66c12e6f290344f1e4ca10d7c495a
@@@ -35,13 -35,13 +35,13 @@@ trivial patch so apply some common sens
  
        PLEASE check your patch with the automated style checker
        (scripts/checkpatch.pl) to catch trivial style violations.
 -      See Documentation/CodingStyle for guidance here.
 +      See Documentation/process/coding-style.rst for guidance here.
  
        PLEASE CC: the maintainers and mailing lists that are generated
        by scripts/get_maintainer.pl.  The results returned by the
        script will be best if you have git installed and are making
        your changes in a branch derived from Linus' latest git tree.
 -      See Documentation/SubmittingPatches for details.
 +      See Documentation/process/submitting-patches.rst for details.
  
        PLEASE try to include any credit lines you want added with the
        patch. It avoids people being missed off by mistake and makes
@@@ -54,7 -54,7 +54,7 @@@
        of the Linux Foundation certificate of contribution and should
        include a Signed-off-by: line.  The current version of this
        "Developer's Certificate of Origin" (DCO) is listed in the file
 -      Documentation/SubmittingPatches.
 +      Documentation/process/submitting-patches.rst.
  
  6.    Make sure you have the right to send any changes you make. If you
        do changes at work you may find your employer owns the patch
@@@ -74,10 -74,6 +74,10 @@@ Descriptions of section entries
           These reviewers should be CCed on patches.
        L: Mailing list that is relevant to this area
        W: Web-page with status/info
 +      B: URI for where to file bugs. A web-page with detailed bug
 +         filing info, a direct bug tracker link, or a mailto: URI.
 +      C: URI for chat protocol, server and channel where developers
 +         usually hang out, for example irc://server/channel.
        Q: Patchwork web based patch tracking system site
        T: SCM tree type and location.
           Type is one of: git, hg, quilt, stgit, topgit
@@@ -581,11 -577,6 +581,11 @@@ T:       git git://linuxtv.org/anttip/media_t
  S:    Maintained
  F:    drivers/media/usb/airspy/
  
 +ALACRITECH GIGABIT ETHERNET DRIVER
 +M:    Lino Sanfilippo <LinoSanfilippo@gmx.de>
 +S:    Maintained
 +F:    drivers/net/ethernet/alacritech/*
 +
  ALCATEL SPEEDTOUCH USB DRIVER
  M:    Duncan Sands <duncan.sands@free.fr>
  L:    linux-usb@vger.kernel.org
@@@ -1052,7 -1043,6 +1052,7 @@@ F:      arch/arm/mach-meson
  F:    arch/arm/boot/dts/meson*
  F:    arch/arm64/boot/dts/amlogic/
  F:    drivers/pinctrl/meson/
 +F:    drivers/mmc/host/meson*
  N:    meson
  
  ARM/Annapurna Labs ALPINE ARCHITECTURE
@@@ -1792,7 -1782,6 +1792,7 @@@ F:      drivers/char/hw_random/st-rng.
  F:    drivers/clocksource/arm_global_timer.c
  F:    drivers/clocksource/clksrc_st_lpc.c
  F:    drivers/cpufreq/sti-cpufreq.c
 +F:    drivers/dma/st_fdma*
  F:    drivers/i2c/busses/i2c-st.c
  F:    drivers/media/rc/st_rc.c
  F:    drivers/media/platform/sti/c8sectpfe/
@@@ -1803,7 -1792,6 +1803,7 @@@ F:      drivers/phy/phy-stih407-usb.
  F:    drivers/phy/phy-stih41x-usb.c
  F:    drivers/pinctrl/pinctrl-st.c
  F:    drivers/remoteproc/st_remoteproc.c
 +F:    drivers/remoteproc/st_slim_rproc.c
  F:    drivers/reset/sti/
  F:    drivers/rtc/rtc-st-lpc.c
  F:    drivers/tty/serial/st-asc.c
@@@ -1812,7 -1800,6 +1812,7 @@@ F:      drivers/usb/host/ehci-st.
  F:    drivers/usb/host/ohci-st.c
  F:    drivers/watchdog/st_lpc_wdt.c
  F:    drivers/ata/ahci_st.c
 +F:    include/linux/remoteproc/st_slim_rproc.h
  
  ARM/STM32 ARCHITECTURE
  M:    Maxime Coquelin <mcoquelin.stm32@gmail.com>
@@@ -2550,8 -2537,6 +2550,8 @@@ L:      netdev@vger.kernel.or
  L:    linux-kernel@vger.kernel.org
  S:    Supported
  F:    kernel/bpf/
 +F:    tools/testing/selftests/bpf/
 +F:    lib/test_bpf.c
  
  BROADCOM B44 10/100 ETHERNET DRIVER
  M:    Michael Chan <michael.chan@broadcom.com>
@@@ -2952,7 -2937,7 +2952,7 @@@ CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVE
  M:    Kevin Tsai <ktsai@capellamicro.com>
  S:    Maintained
  F:    drivers/iio/light/cm*
 -F:    Documentation/devicetree/bindings/i2c/trivial-devices.txt
 +F:    Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst
  
  CAVIUM I2C DRIVER
  M:    Jan Glauber <jglauber@cavium.com>
@@@ -3100,7 -3085,7 +3100,7 @@@ M:      Harry Wei <harryxiyou@gmail.com
  L:    xiyoulinuxkernelgroup@googlegroups.com (subscribers-only)
  L:    linux-kernel@zh-kernel.org (moderated for non-subscribers)
  S:    Maintained
 -F:    Documentation/zh_CN/
 +F:    Documentation/translations/zh_CN/
  
  CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
  M:    Peter Chen <Peter.Chen@nxp.com>
@@@ -3933,7 -3918,7 +3933,7 @@@ F:      include/linux/dma-buf
  F:    include/linux/reservation.h
  F:    include/linux/*fence.h
  F:    Documentation/dma-buf-sharing.txt
- T:    git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
+ T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  SYNC FILE FRAMEWORK
  M:    Sumit Semwal <sumit.semwal@linaro.org>
@@@ -3941,10 -3926,12 +3941,12 @@@ R:   Gustavo Padovan <gustavo@padovan.org
  S:    Maintained
  L:    linux-media@vger.kernel.org
  L:    dri-devel@lists.freedesktop.org
- F:    drivers/dma-buf/sync_file.c
+ F:    drivers/dma-buf/sync_*
+ F:    drivers/dma-buf/sw_sync.c
  F:    include/linux/sync_file.h
+ F:    include/uapi/linux/sync_file.h
  F:    Documentation/sync_file.txt
- T:    git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
+ T:    git git://anongit.freedesktop.org/drm/drm-misc
  
  DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
  M:    Vinod Koul <vinod.koul@intel.com>
@@@ -4032,8 -4019,6 +4034,8 @@@ DRM DRIVER
  M:    David Airlie <airlied@linux.ie>
  L:    dri-devel@lists.freedesktop.org
  T:    git git://people.freedesktop.org/~airlied/linux
 +B:    https://bugs.freedesktop.org/
 +C:    irc://chat.freenode.net/dri-devel
  S:    Maintained
  F:    drivers/gpu/drm/
  F:    drivers/gpu/vga/
@@@ -4044,11 -4029,30 +4046,30 @@@ F:   Documentation/gpu
  F:    include/drm/
  F:    include/uapi/drm/
  
+ DRM DRIVERS AND MISC GPU PATCHES
+ M:    Daniel Vetter <daniel.vetter@intel.com>
+ M:    Jani Nikula <jani.nikula@linux.intel.com>
+ M:    Sean Paul <seanpaul@chromium.org>
+ W:    https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
+ S:    Maintained
+ T:    git git://anongit.freedesktop.org/drm/drm-misc
+ F:    Documentation/gpu/
+ F:    drivers/gpu/vga/
+ F:    drivers/gpu/drm/*
+ F:    include/drm/drm*
+ F:    include/uapi/drm/drm*
  DRM DRIVER FOR AST SERVER GRAPHICS CHIPS
  M:    Dave Airlie <airlied@redhat.com>
  S:    Odd Fixes
  F:    drivers/gpu/drm/ast/
  
+ DRM DRIVERS FOR BRIDGE CHIPS
+ M:    Archit Taneja <architt@codeaurora.org>
+ S:    Maintained
+ T:    git git://anongit.freedesktop.org/drm/drm-misc
+ F:    drivers/gpu/drm/bridge/
  DRM DRIVER FOR BOCHS VIRTUAL GPU
  M:    Gerd Hoffmann <kraxel@redhat.com>
  S:    Odd Fixes
@@@ -4084,10 -4088,7 +4105,9 @@@ INTEL DRM DRIVERS (excluding Poulsbo, M
  M:    Daniel Vetter <daniel.vetter@intel.com>
  M:    Jani Nikula <jani.nikula@linux.intel.com>
  L:    intel-gfx@lists.freedesktop.org
- L:    dri-devel@lists.freedesktop.org
  W:    https://01.org/linuxgraphics/
 +B:    https://01.org/linuxgraphics/documentation/how-report-bugs
 +C:    irc://chat.freenode.net/intel-gfx
  Q:    http://patchwork.freedesktop.org/project/intel-gfx/
  T:    git git://anongit.freedesktop.org/drm-intel
  S:    Supported
@@@ -4096,6 -4097,16 +4116,16 @@@ F:    include/drm/i915
  F:    include/uapi/drm/i915_drm.h
  F:    Documentation/gpu/i915.rst
  
+ INTEL GVT-g DRIVERS (Intel GPU Virtualization)
+ M:      Zhenyu Wang <zhenyuw@linux.intel.com>
+ M:      Zhi Wang <zhi.a.wang@intel.com>
+ L:      igvt-g-dev@lists.01.org
+ L:      intel-gfx@lists.freedesktop.org
+ W:      https://01.org/igvt-g
+ T:      git https://github.com/01org/gvt-linux.git
+ S:      Supported
+ F:      drivers/gpu/drm/i915/gvt/
  DRM DRIVERS FOR ATMEL HLCDC
  M:    Boris Brezillon <boris.brezillon@free-electrons.com>
  L:    dri-devel@lists.freedesktop.org
@@@ -4110,6 -4121,15 +4140,15 @@@ S:    Supporte
  F:    drivers/gpu/drm/sun4i/
  F:    Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
  
+ DRM DRIVERS FOR AMLOGIC SOCS
+ M:    Neil Armstrong <narmstrong@baylibre.com>
+ L:    dri-devel@lists.freedesktop.org
+ L:    linux-amlogic@lists.infradead.org
+ W:    http://linux-meson.com/
+ S:    Supported
+ F:    drivers/gpu/drm/meson/
+ F:    Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <inki.dae@samsung.com>
  M:    Joonyoung Shim <jy0922.shim@samsung.com>
@@@ -4149,6 -4169,7 +4188,7 @@@ F:      drivers/gpu/drm/gma500
  
  DRM DRIVERS FOR HISILICON
  M:    Xinliang Liu <z.liuxinliang@hisilicon.com>
+ M:    Rongrong Zou <zourongrong@gmail.com>
  R:    Xinwei Kong <kong.kongxinwei@hisilicon.com>
  R:    Chen Feng <puck.chen@hisilicon.com>
  L:    dri-devel@lists.freedesktop.org
@@@ -4273,6 -4294,7 +4313,7 @@@ DRM DRIVERS FOR VIVANTE GPU I
  M:    Lucas Stach <l.stach@pengutronix.de>
  R:    Russell King <linux+etnaviv@armlinux.org.uk>
  R:    Christian Gmeiner <christian.gmeiner@gmail.com>
+ L:    etnaviv@lists.freedesktop.org
  L:    dri-devel@lists.freedesktop.org
  S:    Maintained
  F:    drivers/gpu/drm/etnaviv/
@@@ -4313,6 -4335,13 +4354,13 @@@ S:    Maintaine
  F:    drivers/gpu/drm/tilcdc/
  F:    Documentation/devicetree/bindings/display/tilcdc/
  
+ DRM DRIVERS FOR ZTE ZX
+ M:    Shawn Guo <shawnguo@kernel.org>
+ L:    dri-devel@lists.freedesktop.org
+ S:    Maintained
+ F:    drivers/gpu/drm/zte/
+ F:    Documentation/devicetree/bindings/display/zte,vou.txt
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <klimov.linux@gmail.com>
  L:    linux-media@vger.kernel.org
@@@ -4657,14 -4686,12 +4705,14 @@@ L:   linux-efi@vger.kernel.or
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
  S:    Maintained
  F:    Documentation/efi-stub.txt
 -F:    arch/ia64/kernel/efi.c
 +F:    arch/*/kernel/efi.c
  F:    arch/x86/boot/compressed/eboot.[ch]
 -F:    arch/x86/include/asm/efi.h
 +F:    arch/*/include/asm/efi.h
  F:    arch/x86/platform/efi/
  F:    drivers/firmware/efi/
  F:    include/linux/efi*.h
 +F:    arch/arm/boot/compressed/efi-header.S
 +F:    arch/arm64/kernel/efi-entry.S
  
  EFI VARIABLE FILESYSTEM
  M:    Matthew Garrett <matthew.garrett@nebula.com>
@@@ -4996,9 -5023,10 +5044,9 @@@ F:     drivers/net/wan/dlci.
  F:    drivers/net/wan/sdla.c
  
  FRAMEBUFFER LAYER
 -M:    Tomi Valkeinen <tomi.valkeinen@ti.com>
  L:    linux-fbdev@vger.kernel.org
  Q:    http://patchwork.kernel.org/project/linux-fbdev/list/
 -S:    Maintained
 +S:    Orphan
  F:    Documentation/fb/
  F:    drivers/video/
  F:    include/video/
@@@ -5071,18 -5099,9 +5119,18 @@@ S:    Maintaine
  F:    drivers/net/ethernet/freescale/fman
  F:    Documentation/devicetree/bindings/powerpc/fsl/fman.txt
  
 +FREESCALE SOC DRIVERS
 +M:    Scott Wood <oss@buserror.net>
 +L:    linuxppc-dev@lists.ozlabs.org
 +L:    linux-arm-kernel@lists.infradead.org
 +S:    Maintained
 +F:    drivers/soc/fsl/
 +F:    include/linux/fsl/
 +
  FREESCALE QUICC ENGINE LIBRARY
 +M:    Qiang Zhao <qiang.zhao@nxp.com>
  L:    linuxppc-dev@lists.ozlabs.org
 -S:    Orphan
 +S:    Maintained
  F:    drivers/soc/fsl/qe/
  F:    include/soc/fsl/*qe*.h
  F:    include/soc/fsl/*ucc*.h
@@@ -5238,7 -5257,6 +5286,7 @@@ L:      kernel-hardening@lists.openwall.co
  S:    Maintained
  F:    scripts/gcc-plugins/
  F:    scripts/gcc-plugin.sh
 +F:    scripts/Makefile.gcc-plugins
  F:    Documentation/gcc-plugins.txt
  
  GCOV BASED KERNEL PROFILING
@@@ -6125,9 -6143,14 +6173,9 @@@ S:     Maintaine
  F:    Documentation/cdrom/ide-cd
  F:    drivers/ide/ide-cd*
  
 -IDLE-I7300
 -M:    Andy Henroid <andrew.d.henroid@intel.com>
 -L:    linux-pm@vger.kernel.org
 -S:    Supported
 -F:    drivers/idle/i7300_idle.c
 -
  IEEE 802.15.4 SUBSYSTEM
  M:    Alexander Aring <aar@pengutronix.de>
 +M:    Stefan Schmidt <stefan@osg.samsung.com>
  L:    linux-wpan@vger.kernel.org
  W:    http://wpan.cakelab.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git
@@@ -7590,10 -7613,8 +7638,10 @@@ S:    Maintaine
  MARVELL 88E6XXX ETHERNET SWITCH FABRIC DRIVER
  M:    Andrew Lunn <andrew@lunn.ch>
  M:    Vivien Didelot <vivien.didelot@savoirfairelinux.com>
 +L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/dsa/mv88e6xxx/
 +F:    Documentation/devicetree/bindings/net/dsa/marvell.txt
  
  MARVELL ARMADA DRM SUPPORT
  M:    Russell King <rmk+kernel@armlinux.org.uk>
@@@ -8307,6 -8328,12 +8355,12 @@@ T:    git git://linuxtv.org/mkrufky/tuners
  S:    Maintained
  F:    drivers/media/tuners/mxl5007t.*
  
+ MXSFB DRM DRIVER
+ M:    Marek Vasut <marex@denx.de>
+ S:    Supported
+ F:    drivers/gpu/drm/mxsfb/
+ F:    Documentation/devicetree/bindings/display/mxsfb-drm.txt
  MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
  M:    Hyong-Youb Kim <hykim@myri.com>
  L:    netdev@vger.kernel.org
@@@ -8484,6 -8511,7 +8538,6 @@@ F:      include/uapi/linux/net_namespace.
  F:    tools/net/
  F:    tools/testing/selftests/net/
  F:    lib/random32.c
 -F:    lib/test_bpf.c
  
  NETWORKING [IPv4/IPv6]
  M:    "David S. Miller" <davem@davemloft.net>
@@@ -8774,7 -8802,6 +8828,7 @@@ F:      drivers/regulator/tps65217-regulator
  F:    drivers/regulator/tps65218-regulator.c
  F:    drivers/regulator/tps65910-regulator.c
  F:    drivers/regulator/twl-regulator.c
 +F:    drivers/regulator/twl6030-regulator.c
  F:    include/linux/i2c-omap.h
  
  OMAP DEVICE TREE SUPPORT
@@@ -8995,11 -9022,9 +9049,11 @@@ F:    drivers/of/resolver.
  
  OPENRISC ARCHITECTURE
  M:    Jonas Bonn <jonas@southpole.se>
 -W:    http://openrisc.net
 +M:    Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
 +M:    Stafford Horne <shorne@gmail.com>
 +L:    openrisc@lists.librecores.org
 +W:    http://openrisc.io
  S:    Maintained
 -T:    git git://openrisc.net/~jonas/linux
  F:    arch/openrisc/
  
  OPENVSWITCH
@@@ -9838,7 -9863,7 +9892,7 @@@ F:      drivers/media/usb/pwc/
  
  PWM FAN DRIVER
  M:    Kamil Debski <kamil@wypas.org>
 -M:    Lukasz Majewski <l.majewski@samsung.com>
 +M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  L:    linux-hwmon@vger.kernel.org
  S:    Supported
  F:    Documentation/devicetree/bindings/hwmon/pwm-fan.txt
@@@ -10609,7 -10634,7 +10663,7 @@@ L:   netdev@vger.kernel.or
  F:    drivers/net/ethernet/samsung/sxgbe/
  
  SAMSUNG THERMAL DRIVER
 -M:    Lukasz Majewski <l.majewski@samsung.com>
 +M:    Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  L:    linux-pm@vger.kernel.org
  L:    linux-samsung-soc@vger.kernel.org
  S:    Supported
@@@ -11500,7 -11525,7 +11554,7 @@@ STABLE BRANC
  M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  L:    stable@vger.kernel.org
  S:    Supported
 -F:    Documentation/stable_kernel_rules.txt
 +F:    Documentation/process/stable-kernel-rules.rst
  
  STAGING SUBSYSTEM
  M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@@@ -12790,15 -12815,6 +12844,15 @@@ F: drivers/vfio
  F:    include/linux/vfio.h
  F:    include/uapi/linux/vfio.h
  
 +VFIO MEDIATED DEVICE DRIVERS
 +M:    Kirti Wankhede <kwankhede@nvidia.com>
 +L:    kvm@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/vfio-mediated-device.txt
 +F:    drivers/vfio/mdev/
 +F:    include/linux/mdev.h
 +F:    samples/vfio-mdev/
 +
  VFIO PLATFORM DRIVER
  M:    Baptiste Reynal <b.reynal@virtualopensystems.com>
  L:    kvm@vger.kernel.org
@@@ -12951,7 -12967,7 +13005,7 @@@ M:   Greg Kroah-Hartman <gregkh@linuxfoun
  L:    devel@driverdev.osuosl.org
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
 -F:    Documentation/vme_api.txt
 +F:    Documentation/driver-api/vme.rst
  F:    drivers/staging/vme/
  F:    drivers/vme/
  F:    include/linux/vme*
@@@ -13175,7 -13191,7 +13229,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    include/linux/workqueue.h
  F:    kernel/workqueue.c
 -F:    Documentation/workqueue.txt
 +F:    Documentation/core-api/workqueue.rst
  
  X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS
  M:    Chen-Yu Tsai <wens@csie.org>
diff --combined arch/x86/kvm/x86.c
index 6f5f465fdb6bdc2b80a7220e5247a04213d44a74,073eaeabc2a7e12a34b04aee8eb288d9d1ed8a72..2912684ff902ebcbe315f68e166deb73a67b1127
@@@ -2071,8 -2071,6 +2071,8 @@@ static void record_steal_time(struct kv
                &vcpu->arch.st.steal, sizeof(struct kvm_steal_time))))
                return;
  
 +      vcpu->arch.st.steal.preempted = 0;
 +
        if (vcpu->arch.st.steal.version & 1)
                vcpu->arch.st.steal.version += 1;  /* first time write, random junk */
  
@@@ -2828,22 -2826,8 +2828,22 @@@ void kvm_arch_vcpu_load(struct kvm_vcp
        kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
  }
  
 +static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
 +{
 +      if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
 +              return;
 +
 +      vcpu->arch.st.steal.preempted = 1;
 +
 +      kvm_write_guest_offset_cached(vcpu->kvm, &vcpu->arch.st.stime,
 +                      &vcpu->arch.st.steal.preempted,
 +                      offsetof(struct kvm_steal_time, preempted),
 +                      sizeof(vcpu->arch.st.steal.preempted));
 +}
 +
  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
  {
 +      kvm_steal_time_set_preempted(vcpu);
        kvm_x86_ops->vcpu_put(vcpu);
        kvm_put_guest_fpu(vcpu);
        vcpu->arch.last_host_tsc = rdtsc();
@@@ -5097,6 -5081,11 +5097,6 @@@ static void emulator_get_fpu(struct x86
  {
        preempt_disable();
        kvm_load_guest_fpu(emul_to_vcpu(ctxt));
 -      /*
 -       * CR0.TS may reference the host fpu state, not the guest fpu state,
 -       * so it may be clear at this point.
 -       */
 -      clts();
  }
  
  static void emulator_put_fpu(struct x86_emulate_ctxt *ctxt)
@@@ -7418,13 -7407,25 +7418,13 @@@ void kvm_load_guest_fpu(struct kvm_vcp
  
  void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
  {
 -      if (!vcpu->guest_fpu_loaded) {
 -              vcpu->fpu_counter = 0;
 +      if (!vcpu->guest_fpu_loaded)
                return;
 -      }
  
        vcpu->guest_fpu_loaded = 0;
        copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu);
        __kernel_fpu_end();
        ++vcpu->stat.fpu_reload;
 -      /*
 -       * If using eager FPU mode, or if the guest is a frequent user
 -       * of the FPU, just leave the FPU active for next time.
 -       * Every 255 times fpu_counter rolls over to 0; a guest that uses
 -       * the FPU in bursts will revert to loading it on demand.
 -       */
 -      if (!use_eager_fpu()) {
 -              if (++vcpu->fpu_counter < 5)
 -                      kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
 -      }
        trace_kvm_fpu(0);
  }
  
@@@ -8175,7 -8176,7 +8175,7 @@@ void kvm_arch_flush_shadow_all(struct k
  void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
                                   struct kvm_memory_slot *slot)
  {
-       kvm_mmu_invalidate_zap_all_pages(kvm);
+       kvm_page_track_flush_slot(kvm, slot);
  }
  
  static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
diff --combined drivers/base/Kconfig
index 2abea876c0a0c2c2ed7b86e88e953462b6fdd096,0e40967a5d6e311b8a8e268ea69256a53fa94709..afa67f9ed726981bd297f887897d1899e8efcf1f
@@@ -237,7 -237,6 +237,7 @@@ config GENERIC_CPU_AUTOPROB
  
  config SOC_BUS
        bool
 +      select GLOB
  
  source "drivers/base/regmap/Kconfig"
  
@@@ -251,11 -250,11 +251,11 @@@ config DMA_SHARED_BUFFE
          APIs extension; the file's descriptor can then be passed on to other
          driver.
  
- config FENCE_TRACE
-       bool "Enable verbose FENCE_TRACE messages"
+ config DMA_FENCE_TRACE
+       bool "Enable verbose DMA_FENCE_TRACE messages"
        depends on DMA_SHARED_BUFFER
        help
-         Enable the FENCE_TRACE printks. This will add extra
+         Enable the DMA_FENCE_TRACE printks. This will add extra
          spam to the console log, but will make it easier to diagnose
          lockup related problems for dma-buffers shared across multiple
          devices.
index 05c2850c04b00f01bfcda21182fdaa15f3c0edb1,54ac8a845e9f4852bb13fac308770de5e695a288..63208e5c158832f36dd9898a9a0e272a144b2ca4
@@@ -34,7 -34,7 +34,7 @@@
  #include <linux/kref.h>
  #include <linux/interval_tree.h>
  #include <linux/hashtable.h>
- #include <linux/fence.h>
+ #include <linux/dma-fence.h>
  
  #include <ttm/ttm_bo_api.h>
  #include <ttm/ttm_bo_driver.h>
  #include "amdgpu_ucode.h"
  #include "amdgpu_ttm.h"
  #include "amdgpu_gds.h"
+ #include "amdgpu_sync.h"
+ #include "amdgpu_ring.h"
+ #include "amdgpu_vm.h"
  #include "amd_powerplay.h"
+ #include "amdgpu_dpm.h"
  #include "amdgpu_acp.h"
  
  #include "gpu_scheduler.h"
@@@ -88,15 -92,16 +92,16 @@@ extern int amdgpu_vm_debug
  extern int amdgpu_sched_jobs;
  extern int amdgpu_sched_hw_submission;
  extern int amdgpu_powerplay;
- extern int amdgpu_powercontainment;
+ extern int amdgpu_no_evict;
+ extern int amdgpu_direct_gma_size;
  extern unsigned amdgpu_pcie_gen_cap;
  extern unsigned amdgpu_pcie_lane_cap;
  extern unsigned amdgpu_cg_mask;
  extern unsigned amdgpu_pg_mask;
  extern char *amdgpu_disable_cu;
- extern int amdgpu_sclk_deep_sleep_en;
  extern char *amdgpu_virtual_display;
  extern unsigned amdgpu_pp_feature_mask;
+ extern int amdgpu_vram_page_split;
  
  #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS                3000
  #define AMDGPU_MAX_USEC_TIMEOUT                       100000  /* 100 ms */
  #define AMDGPUFB_CONN_LIMIT                   4
  #define AMDGPU_BIOS_NUM_SCRATCH                       8
  
- /* max number of rings */
- #define AMDGPU_MAX_RINGS                      16
- #define AMDGPU_MAX_GFX_RINGS                  1
- #define AMDGPU_MAX_COMPUTE_RINGS              8
- #define AMDGPU_MAX_VCE_RINGS                  3
  /* max number of IP instances */
  #define AMDGPU_MAX_SDMA_INSTANCES             2
  
  
  struct amdgpu_device;
  struct amdgpu_ib;
- struct amdgpu_vm;
- struct amdgpu_ring;
  struct amdgpu_cs_parser;
  struct amdgpu_job;
  struct amdgpu_irq_src;
@@@ -198,21 -195,38 +195,38 @@@ int amdgpu_wait_for_idle(struct amdgpu_
  bool amdgpu_is_idle(struct amdgpu_device *adev,
                    enum amd_ip_block_type block_type);
  
+ #define AMDGPU_MAX_IP_NUM 16
+ struct amdgpu_ip_block_status {
+       bool valid;
+       bool sw;
+       bool hw;
+       bool late_initialized;
+       bool hang;
+ };
  struct amdgpu_ip_block_version {
-       enum amd_ip_block_type type;
-       u32 major;
-       u32 minor;
-       u32 rev;
+       const enum amd_ip_block_type type;
+       const u32 major;
+       const u32 minor;
+       const u32 rev;
        const struct amd_ip_funcs *funcs;
  };
  
+ struct amdgpu_ip_block {
+       struct amdgpu_ip_block_status status;
+       const struct amdgpu_ip_block_version *version;
+ };
  int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
                                enum amd_ip_block_type type,
                                u32 major, u32 minor);
  
- const struct amdgpu_ip_block_version * amdgpu_get_ip_block(
-                                       struct amdgpu_device *adev,
-                                       enum amd_ip_block_type type);
+ struct amdgpu_ip_block * amdgpu_get_ip_block(struct amdgpu_device *adev,
+                                            enum amd_ip_block_type type);
+ int amdgpu_ip_block_add(struct amdgpu_device *adev,
+                       const struct amdgpu_ip_block_version *ip_block_version);
  
  /* provided by hw blocks that can move/clear data.  e.g., gfx or sdma */
  struct amdgpu_buffer_funcs {
@@@ -286,47 -300,6 +300,6 @@@ struct amdgpu_ih_funcs 
        void (*set_rptr)(struct amdgpu_device *adev);
  };
  
- /* provided by hw blocks that expose a ring buffer for commands */
- struct amdgpu_ring_funcs {
-       /* ring read/write ptr handling */
-       u32 (*get_rptr)(struct amdgpu_ring *ring);
-       u32 (*get_wptr)(struct amdgpu_ring *ring);
-       void (*set_wptr)(struct amdgpu_ring *ring);
-       /* validating and patching of IBs */
-       int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
-       /* command emit functions */
-       void (*emit_ib)(struct amdgpu_ring *ring,
-                       struct amdgpu_ib *ib,
-                       unsigned vm_id, bool ctx_switch);
-       void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr,
-                          uint64_t seq, unsigned flags);
-       void (*emit_pipeline_sync)(struct amdgpu_ring *ring);
-       void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id,
-                             uint64_t pd_addr);
-       void (*emit_hdp_flush)(struct amdgpu_ring *ring);
-       void (*emit_hdp_invalidate)(struct amdgpu_ring *ring);
-       void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid,
-                               uint32_t gds_base, uint32_t gds_size,
-                               uint32_t gws_base, uint32_t gws_size,
-                               uint32_t oa_base, uint32_t oa_size);
-       /* testing functions */
-       int (*test_ring)(struct amdgpu_ring *ring);
-       int (*test_ib)(struct amdgpu_ring *ring, long timeout);
-       /* insert NOP packets */
-       void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count);
-       /* pad the indirect buffer to the necessary number of dw */
-       void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
-       unsigned (*init_cond_exec)(struct amdgpu_ring *ring);
-       void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset);
-       /* note usage for clock and power gating */
-       void (*begin_use)(struct amdgpu_ring *ring);
-       void (*end_use)(struct amdgpu_ring *ring);
-       void (*emit_switch_buffer) (struct amdgpu_ring *ring);
-       void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags);
-       unsigned (*get_emit_ib_size) (struct amdgpu_ring *ring);
-       unsigned (*get_dma_frame_size) (struct amdgpu_ring *ring);
- };
  /*
   * BIOS.
   */
@@@ -363,47 -336,6 +336,6 @@@ struct amdgpu_clock 
        uint32_t max_pixel_clock;
  };
  
- /*
-  * Fences.
-  */
- struct amdgpu_fence_driver {
-       uint64_t                        gpu_addr;
-       volatile uint32_t               *cpu_addr;
-       /* sync_seq is protected by ring emission lock */
-       uint32_t                        sync_seq;
-       atomic_t                        last_seq;
-       bool                            initialized;
-       struct amdgpu_irq_src           *irq_src;
-       unsigned                        irq_type;
-       struct timer_list               fallback_timer;
-       unsigned                        num_fences_mask;
-       spinlock_t                      lock;
-       struct fence                    **fences;
- };
- /* some special values for the owner field */
- #define AMDGPU_FENCE_OWNER_UNDEFINED  ((void*)0ul)
- #define AMDGPU_FENCE_OWNER_VM         ((void*)1ul)
- #define AMDGPU_FENCE_FLAG_64BIT         (1 << 0)
- #define AMDGPU_FENCE_FLAG_INT           (1 << 1)
- int amdgpu_fence_driver_init(struct amdgpu_device *adev);
- void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
- void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
- int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
-                                 unsigned num_hw_submission);
- int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
-                                  struct amdgpu_irq_src *irq_src,
-                                  unsigned irq_type);
- void amdgpu_fence_driver_suspend(struct amdgpu_device *adev);
- void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
- int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **fence);
- void amdgpu_fence_process(struct amdgpu_ring *ring);
- int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
- unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
  /*
   * BO.
   */
@@@ -427,7 -359,7 +359,7 @@@ struct amdgpu_bo_va_mapping 
  struct amdgpu_bo_va {
        /* protected by bo being reserved */
        struct list_head                bo_list;
-       struct fence                    *last_pt_update;
+       struct dma_fence                *last_pt_update;
        unsigned                        ref_count;
  
        /* protected by vm mutex and spinlock */
@@@ -465,7 -397,6 +397,6 @@@ struct amdgpu_bo 
         */
        struct list_head                va;
        /* Constant after initialization */
-       struct amdgpu_device            *adev;
        struct drm_gem_object           gem_base;
        struct amdgpu_bo                *parent;
        struct amdgpu_bo                *shadow;
@@@ -544,7 -475,7 +475,7 @@@ struct amdgpu_sa_bo 
        struct amdgpu_sa_manager        *manager;
        unsigned                        soffset;
        unsigned                        eoffset;
-       struct fence                    *fence;
+       struct dma_fence                *fence;
  };
  
  /*
@@@ -562,27 -493,6 +493,6 @@@ int amdgpu_mode_dumb_create(struct drm_
  int amdgpu_mode_dumb_mmap(struct drm_file *filp,
                          struct drm_device *dev,
                          uint32_t handle, uint64_t *offset_p);
- /*
-  * Synchronization
-  */
- struct amdgpu_sync {
-       DECLARE_HASHTABLE(fences, 4);
-       struct fence            *last_vm_update;
- };
- void amdgpu_sync_create(struct amdgpu_sync *sync);
- int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
-                     struct fence *f);
- int amdgpu_sync_resv(struct amdgpu_device *adev,
-                    struct amdgpu_sync *sync,
-                    struct reservation_object *resv,
-                    void *owner);
- struct fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
-                                    struct amdgpu_ring *ring);
- struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
- void amdgpu_sync_free(struct amdgpu_sync *sync);
- int amdgpu_sync_init(void);
- void amdgpu_sync_fini(void);
  int amdgpu_fence_slab_init(void);
  void amdgpu_fence_slab_fini(void);
  
@@@ -704,10 -614,10 +614,10 @@@ struct amdgpu_flip_work 
        uint64_t                        base;
        struct drm_pending_vblank_event *event;
        struct amdgpu_bo                *old_abo;
-       struct fence                    *excl;
+       struct dma_fence                *excl;
        unsigned                        shared_count;
-       struct fence                    **shared;
-       struct fence_cb                 cb;
+       struct dma_fence                **shared;
+       struct dma_fence_cb             cb;
        bool                            async;
  };
  
@@@ -724,14 -634,6 +634,6 @@@ struct amdgpu_ib 
        uint32_t                        flags;
  };
  
- enum amdgpu_ring_type {
-       AMDGPU_RING_TYPE_GFX,
-       AMDGPU_RING_TYPE_COMPUTE,
-       AMDGPU_RING_TYPE_SDMA,
-       AMDGPU_RING_TYPE_UVD,
-       AMDGPU_RING_TYPE_VCE
- };
  extern const struct amd_sched_backend_ops amdgpu_sched_ops;
  
  int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
@@@ -743,214 -645,7 +645,7 @@@ void amdgpu_job_free_resources(struct a
  void amdgpu_job_free(struct amdgpu_job *job);
  int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
                      struct amd_sched_entity *entity, void *owner,
-                     struct fence **f);
- struct amdgpu_ring {
-       struct amdgpu_device            *adev;
-       const struct amdgpu_ring_funcs  *funcs;
-       struct amdgpu_fence_driver      fence_drv;
-       struct amd_gpu_scheduler        sched;
-       struct amdgpu_bo        *ring_obj;
-       volatile uint32_t       *ring;
-       unsigned                rptr_offs;
-       unsigned                wptr;
-       unsigned                wptr_old;
-       unsigned                ring_size;
-       unsigned                max_dw;
-       int                     count_dw;
-       uint64_t                gpu_addr;
-       uint32_t                align_mask;
-       uint32_t                ptr_mask;
-       bool                    ready;
-       u32                     nop;
-       u32                     idx;
-       u32                     me;
-       u32                     pipe;
-       u32                     queue;
-       struct amdgpu_bo        *mqd_obj;
-       u32                     doorbell_index;
-       bool                    use_doorbell;
-       unsigned                wptr_offs;
-       unsigned                fence_offs;
-       uint64_t                current_ctx;
-       enum amdgpu_ring_type   type;
-       char                    name[16];
-       unsigned                cond_exe_offs;
-       u64                     cond_exe_gpu_addr;
-       volatile u32            *cond_exe_cpu_addr;
- #if defined(CONFIG_DEBUG_FS)
-       struct dentry *ent;
- #endif
- };
- /*
-  * VM
-  */
- /* maximum number of VMIDs */
- #define AMDGPU_NUM_VM 16
- /* Maximum number of PTEs the hardware can write with one command */
- #define AMDGPU_VM_MAX_UPDATE_SIZE     0x3FFFF
- /* number of entries in page table */
- #define AMDGPU_VM_PTE_COUNT (1 << amdgpu_vm_block_size)
- /* PTBs (Page Table Blocks) need to be aligned to 32K */
- #define AMDGPU_VM_PTB_ALIGN_SIZE   32768
- /* LOG2 number of continuous pages for the fragment field */
- #define AMDGPU_LOG2_PAGES_PER_FRAG 4
- #define AMDGPU_PTE_VALID      (1 << 0)
- #define AMDGPU_PTE_SYSTEM     (1 << 1)
- #define AMDGPU_PTE_SNOOPED    (1 << 2)
- /* VI only */
- #define AMDGPU_PTE_EXECUTABLE (1 << 4)
- #define AMDGPU_PTE_READABLE   (1 << 5)
- #define AMDGPU_PTE_WRITEABLE  (1 << 6)
- #define AMDGPU_PTE_FRAG(x)    ((x & 0x1f) << 7)
- /* How to programm VM fault handling */
- #define AMDGPU_VM_FAULT_STOP_NEVER    0
- #define AMDGPU_VM_FAULT_STOP_FIRST    1
- #define AMDGPU_VM_FAULT_STOP_ALWAYS   2
- struct amdgpu_vm_pt {
-       struct amdgpu_bo_list_entry     entry;
-       uint64_t                        addr;
-       uint64_t                        shadow_addr;
- };
- struct amdgpu_vm {
-       /* tree of virtual addresses mapped */
-       struct rb_root          va;
-       /* protecting invalidated */
-       spinlock_t              status_lock;
-       /* BOs moved, but not yet updated in the PT */
-       struct list_head        invalidated;
-       /* BOs cleared in the PT because of a move */
-       struct list_head        cleared;
-       /* BO mappings freed, but not yet updated in the PT */
-       struct list_head        freed;
-       /* contains the page directory */
-       struct amdgpu_bo        *page_directory;
-       unsigned                max_pde_used;
-       struct fence            *page_directory_fence;
-       uint64_t                last_eviction_counter;
-       /* array of page tables, one for each page directory entry */
-       struct amdgpu_vm_pt     *page_tables;
-       /* for id and flush management per ring */
-       struct amdgpu_vm_id     *ids[AMDGPU_MAX_RINGS];
-       /* protecting freed */
-       spinlock_t              freed_lock;
-       /* Scheduler entity for page table updates */
-       struct amd_sched_entity entity;
-       /* client id */
-       u64                     client_id;
- };
- struct amdgpu_vm_id {
-       struct list_head        list;
-       struct fence            *first;
-       struct amdgpu_sync      active;
-       struct fence            *last_flush;
-       atomic64_t              owner;
-       uint64_t                pd_gpu_addr;
-       /* last flushed PD/PT update */
-       struct fence            *flushed_updates;
-       uint32_t                current_gpu_reset_count;
-       uint32_t                gds_base;
-       uint32_t                gds_size;
-       uint32_t                gws_base;
-       uint32_t                gws_size;
-       uint32_t                oa_base;
-       uint32_t                oa_size;
- };
- struct amdgpu_vm_manager {
-       /* Handling of VMIDs */
-       struct mutex                            lock;
-       unsigned                                num_ids;
-       struct list_head                        ids_lru;
-       struct amdgpu_vm_id                     ids[AMDGPU_NUM_VM];
-       /* Handling of VM fences */
-       u64                                     fence_context;
-       unsigned                                seqno[AMDGPU_MAX_RINGS];
-       uint32_t                                max_pfn;
-       /* vram base address for page table entry  */
-       u64                                     vram_base_offset;
-       /* is vm enabled? */
-       bool                                    enabled;
-       /* vm pte handling */
-       const struct amdgpu_vm_pte_funcs        *vm_pte_funcs;
-       struct amdgpu_ring                      *vm_pte_rings[AMDGPU_MAX_RINGS];
-       unsigned                                vm_pte_num_rings;
-       atomic_t                                vm_pte_next_ring;
-       /* client id counter */
-       atomic64_t                              client_counter;
- };
- void amdgpu_vm_manager_init(struct amdgpu_device *adev);
- void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
- int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
- void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
- void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
-                        struct list_head *validated,
-                        struct amdgpu_bo_list_entry *entry);
- void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-                         struct list_head *duplicates);
- void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
-                                 struct amdgpu_vm *vm);
- int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
-                     struct amdgpu_sync *sync, struct fence *fence,
-                     struct amdgpu_job *job);
- int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job);
- void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id);
- int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
-                                   struct amdgpu_vm *vm);
- int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
-                         struct amdgpu_vm *vm);
- int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-                            struct amdgpu_sync *sync);
- int amdgpu_vm_bo_update(struct amdgpu_device *adev,
-                       struct amdgpu_bo_va *bo_va,
-                       bool clear);
- void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
-                            struct amdgpu_bo *bo);
- struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
-                                      struct amdgpu_bo *bo);
- struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
-                                     struct amdgpu_vm *vm,
-                                     struct amdgpu_bo *bo);
- int amdgpu_vm_bo_map(struct amdgpu_device *adev,
-                    struct amdgpu_bo_va *bo_va,
-                    uint64_t addr, uint64_t offset,
-                    uint64_t size, uint32_t flags);
- int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
-                      struct amdgpu_bo_va *bo_va,
-                      uint64_t addr);
- void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
-                     struct amdgpu_bo_va *bo_va);
+                     struct dma_fence **f);
  
  /*
   * context related structures
  
  struct amdgpu_ctx_ring {
        uint64_t                sequence;
-       struct fence            **fences;
+       struct dma_fence        **fences;
        struct amd_sched_entity entity;
  };
  
@@@ -967,7 -662,7 +662,7 @@@ struct amdgpu_ctx 
        struct amdgpu_device    *adev;
        unsigned                reset_counter;
        spinlock_t              ring_lock;
-       struct fence            **fences;
+       struct dma_fence        **fences;
        struct amdgpu_ctx_ring  rings[AMDGPU_MAX_RINGS];
        bool preamble_presented;
  };
@@@ -983,8 -678,8 +678,8 @@@ struct amdgpu_ctx *amdgpu_ctx_get(struc
  int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
  
  uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring,
-                             struct fence *fence);
- struct fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
+                             struct dma_fence *fence);
+ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
                                   struct amdgpu_ring *ring, uint64_t seq);
  
  int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
@@@ -1094,6 -789,16 +789,16 @@@ struct amdgpu_scratch 
  /*
   * GFX configurations
   */
+ #define AMDGPU_GFX_MAX_SE 4
+ #define AMDGPU_GFX_MAX_SH_PER_SE 2
+ struct amdgpu_rb_config {
+       uint32_t rb_backend_disable;
+       uint32_t user_rb_backend_disable;
+       uint32_t raster_config;
+       uint32_t raster_config_1;
+ };
  struct amdgpu_gca_config {
        unsigned max_shader_engines;
        unsigned max_tile_pipes;
  
        uint32_t tile_mode_array[32];
        uint32_t macrotile_mode_array[16];
+       struct amdgpu_rb_config rb_config[AMDGPU_GFX_MAX_SE][AMDGPU_GFX_MAX_SH_PER_SE];
  };
  
  struct amdgpu_cu_info {
@@@ -1134,6 -841,9 +841,9 @@@ struct amdgpu_gfx_funcs 
        /* get the gpu clock counter */
        uint64_t (*get_gpu_clock_counter)(struct amdgpu_device *adev);
        void (*select_se_sh)(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 instance);
+       void (*read_wave_data)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t *dst, int *no_fields);
+       void (*read_wave_vgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t thread, uint32_t start, uint32_t size, uint32_t *dst);
+       void (*read_wave_sgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t start, uint32_t size, uint32_t *dst);
  };
  
  struct amdgpu_gfx {
  int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                  unsigned size, struct amdgpu_ib *ib);
  void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
-                   struct fence *f);
+                   struct dma_fence *f);
  int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
-                      struct amdgpu_ib *ib, struct fence *last_vm_update,
-                      struct amdgpu_job *job, struct fence **f);
+                      struct amdgpu_ib *ib, struct dma_fence *last_vm_update,
+                      struct amdgpu_job *job, struct dma_fence **f);
  int amdgpu_ib_pool_init(struct amdgpu_device *adev);
  void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
  int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
- int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
- void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
- void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
- void amdgpu_ring_commit(struct amdgpu_ring *ring);
- void amdgpu_ring_undo(struct amdgpu_ring *ring);
- int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
-                    unsigned ring_size, u32 nop, u32 align_mask,
-                    struct amdgpu_irq_src *irq_src, unsigned irq_type,
-                    enum amdgpu_ring_type ring_type);
- void amdgpu_ring_fini(struct amdgpu_ring *ring);
  
  /*
   * CS.
@@@ -1226,7 -926,7 +926,7 @@@ struct amdgpu_cs_parser 
        struct amdgpu_bo_list           *bo_list;
        struct amdgpu_bo_list_entry     vm_pd;
        struct list_head                validated;
-       struct fence                    *fence;
+       struct dma_fence                *fence;
        uint64_t                        bytes_moved_threshold;
        uint64_t                        bytes_moved;
        struct amdgpu_bo_list_entry     *evictable;
@@@ -1246,7 -946,7 +946,7 @@@ struct amdgpu_job 
        struct amdgpu_ring      *ring;
        struct amdgpu_sync      sync;
        struct amdgpu_ib        *ibs;
-       struct fence            *fence; /* the hw fence */
+       struct dma_fence        *fence; /* the hw fence */
        uint32_t                preamble_status;
        uint32_t                num_ibs;
        void                    *owner;
@@@ -1295,354 -995,6 +995,6 @@@ struct amdgpu_wb 
  int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
  void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
  
- enum amdgpu_int_thermal_type {
-       THERMAL_TYPE_NONE,
-       THERMAL_TYPE_EXTERNAL,
-       THERMAL_TYPE_EXTERNAL_GPIO,
-       THERMAL_TYPE_RV6XX,
-       THERMAL_TYPE_RV770,
-       THERMAL_TYPE_ADT7473_WITH_INTERNAL,
-       THERMAL_TYPE_EVERGREEN,
-       THERMAL_TYPE_SUMO,
-       THERMAL_TYPE_NI,
-       THERMAL_TYPE_SI,
-       THERMAL_TYPE_EMC2103_WITH_INTERNAL,
-       THERMAL_TYPE_CI,
-       THERMAL_TYPE_KV,
- };
- enum amdgpu_dpm_auto_throttle_src {
-       AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL,
-       AMDGPU_DPM_AUTO_THROTTLE_SRC_EXTERNAL
- };
- enum amdgpu_dpm_event_src {
-       AMDGPU_DPM_EVENT_SRC_ANALOG = 0,
-       AMDGPU_DPM_EVENT_SRC_EXTERNAL = 1,
-       AMDGPU_DPM_EVENT_SRC_DIGITAL = 2,
-       AMDGPU_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
-       AMDGPU_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
- };
- #define AMDGPU_MAX_VCE_LEVELS 6
- enum amdgpu_vce_level {
-       AMDGPU_VCE_LEVEL_AC_ALL = 0,     /* AC, All cases */
-       AMDGPU_VCE_LEVEL_DC_EE = 1,      /* DC, entropy encoding */
-       AMDGPU_VCE_LEVEL_DC_LL_LOW = 2,  /* DC, low latency queue, res <= 720 */
-       AMDGPU_VCE_LEVEL_DC_LL_HIGH = 3, /* DC, low latency queue, 1080 >= res > 720 */
-       AMDGPU_VCE_LEVEL_DC_GP_LOW = 4,  /* DC, general purpose queue, res <= 720 */
-       AMDGPU_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */
- };
- struct amdgpu_ps {
-       u32 caps; /* vbios flags */
-       u32 class; /* vbios flags */
-       u32 class2; /* vbios flags */
-       /* UVD clocks */
-       u32 vclk;
-       u32 dclk;
-       /* VCE clocks */
-       u32 evclk;
-       u32 ecclk;
-       bool vce_active;
-       enum amdgpu_vce_level vce_level;
-       /* asic priv */
-       void *ps_priv;
- };
- struct amdgpu_dpm_thermal {
-       /* thermal interrupt work */
-       struct work_struct work;
-       /* low temperature threshold */
-       int                min_temp;
-       /* high temperature threshold */
-       int                max_temp;
-       /* was last interrupt low to high or high to low */
-       bool               high_to_low;
-       /* interrupt source */
-       struct amdgpu_irq_src   irq;
- };
- enum amdgpu_clk_action
- {
-       AMDGPU_SCLK_UP = 1,
-       AMDGPU_SCLK_DOWN
- };
- struct amdgpu_blacklist_clocks
- {
-       u32 sclk;
-       u32 mclk;
-       enum amdgpu_clk_action action;
- };
- struct amdgpu_clock_and_voltage_limits {
-       u32 sclk;
-       u32 mclk;
-       u16 vddc;
-       u16 vddci;
- };
- struct amdgpu_clock_array {
-       u32 count;
-       u32 *values;
- };
- struct amdgpu_clock_voltage_dependency_entry {
-       u32 clk;
-       u16 v;
- };
- struct amdgpu_clock_voltage_dependency_table {
-       u32 count;
-       struct amdgpu_clock_voltage_dependency_entry *entries;
- };
- union amdgpu_cac_leakage_entry {
-       struct {
-               u16 vddc;
-               u32 leakage;
-       };
-       struct {
-               u16 vddc1;
-               u16 vddc2;
-               u16 vddc3;
-       };
- };
- struct amdgpu_cac_leakage_table {
-       u32 count;
-       union amdgpu_cac_leakage_entry *entries;
- };
- struct amdgpu_phase_shedding_limits_entry {
-       u16 voltage;
-       u32 sclk;
-       u32 mclk;
- };
- struct amdgpu_phase_shedding_limits_table {
-       u32 count;
-       struct amdgpu_phase_shedding_limits_entry *entries;
- };
- struct amdgpu_uvd_clock_voltage_dependency_entry {
-       u32 vclk;
-       u32 dclk;
-       u16 v;
- };
- struct amdgpu_uvd_clock_voltage_dependency_table {
-       u8 count;
-       struct amdgpu_uvd_clock_voltage_dependency_entry *entries;
- };
- struct amdgpu_vce_clock_voltage_dependency_entry {
-       u32 ecclk;
-       u32 evclk;
-       u16 v;
- };
- struct amdgpu_vce_clock_voltage_dependency_table {
-       u8 count;
-       struct amdgpu_vce_clock_voltage_dependency_entry *entries;
- };
- struct amdgpu_ppm_table {
-       u8 ppm_design;
-       u16 cpu_core_number;
-       u32 platform_tdp;
-       u32 small_ac_platform_tdp;
-       u32 platform_tdc;
-       u32 small_ac_platform_tdc;
-       u32 apu_tdp;
-       u32 dgpu_tdp;
-       u32 dgpu_ulv_power;
-       u32 tj_max;
- };
- struct amdgpu_cac_tdp_table {
-       u16 tdp;
-       u16 configurable_tdp;
-       u16 tdc;
-       u16 battery_power_limit;
-       u16 small_power_limit;
-       u16 low_cac_leakage;
-       u16 high_cac_leakage;
-       u16 maximum_power_delivery_limit;
- };
- struct amdgpu_dpm_dynamic_state {
-       struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_sclk;
-       struct amdgpu_clock_voltage_dependency_table vddci_dependency_on_mclk;
-       struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_mclk;
-       struct amdgpu_clock_voltage_dependency_table mvdd_dependency_on_mclk;
-       struct amdgpu_clock_voltage_dependency_table vddc_dependency_on_dispclk;
-       struct amdgpu_uvd_clock_voltage_dependency_table uvd_clock_voltage_dependency_table;
-       struct amdgpu_vce_clock_voltage_dependency_table vce_clock_voltage_dependency_table;
-       struct amdgpu_clock_voltage_dependency_table samu_clock_voltage_dependency_table;
-       struct amdgpu_clock_voltage_dependency_table acp_clock_voltage_dependency_table;
-       struct amdgpu_clock_voltage_dependency_table vddgfx_dependency_on_sclk;
-       struct amdgpu_clock_array valid_sclk_values;
-       struct amdgpu_clock_array valid_mclk_values;
-       struct amdgpu_clock_and_voltage_limits max_clock_voltage_on_dc;
-       struct amdgpu_clock_and_voltage_limits max_clock_voltage_on_ac;
-       u32 mclk_sclk_ratio;
-       u32 sclk_mclk_delta;
-       u16 vddc_vddci_delta;
-       u16 min_vddc_for_pcie_gen2;
-       struct amdgpu_cac_leakage_table cac_leakage_table;
-       struct amdgpu_phase_shedding_limits_table phase_shedding_limits_table;
-       struct amdgpu_ppm_table *ppm_table;
-       struct amdgpu_cac_tdp_table *cac_tdp_table;
- };
- struct amdgpu_dpm_fan {
-       u16 t_min;
-       u16 t_med;
-       u16 t_high;
-       u16 pwm_min;
-       u16 pwm_med;
-       u16 pwm_high;
-       u8 t_hyst;
-       u32 cycle_delay;
-       u16 t_max;
-       u8 control_mode;
-       u16 default_max_fan_pwm;
-       u16 default_fan_output_sensitivity;
-       u16 fan_output_sensitivity;
-       bool ucode_fan_control;
- };
- enum amdgpu_pcie_gen {
-       AMDGPU_PCIE_GEN1 = 0,
-       AMDGPU_PCIE_GEN2 = 1,
-       AMDGPU_PCIE_GEN3 = 2,
-       AMDGPU_PCIE_GEN_INVALID = 0xffff
- };
- enum amdgpu_dpm_forced_level {
-       AMDGPU_DPM_FORCED_LEVEL_AUTO = 0,
-       AMDGPU_DPM_FORCED_LEVEL_LOW = 1,
-       AMDGPU_DPM_FORCED_LEVEL_HIGH = 2,
-       AMDGPU_DPM_FORCED_LEVEL_MANUAL = 3,
- };
- struct amdgpu_vce_state {
-       /* vce clocks */
-       u32 evclk;
-       u32 ecclk;
-       /* gpu clocks */
-       u32 sclk;
-       u32 mclk;
-       u8 clk_idx;
-       u8 pstate;
- };
- struct amdgpu_dpm_funcs {
-       int (*get_temperature)(struct amdgpu_device *adev);
-       int (*pre_set_power_state)(struct amdgpu_device *adev);
-       int (*set_power_state)(struct amdgpu_device *adev);
-       void (*post_set_power_state)(struct amdgpu_device *adev);
-       void (*display_configuration_changed)(struct amdgpu_device *adev);
-       u32 (*get_sclk)(struct amdgpu_device *adev, bool low);
-       u32 (*get_mclk)(struct amdgpu_device *adev, bool low);
-       void (*print_power_state)(struct amdgpu_device *adev, struct amdgpu_ps *ps);
-       void (*debugfs_print_current_performance_level)(struct amdgpu_device *adev, struct seq_file *m);
-       int (*force_performance_level)(struct amdgpu_device *adev, enum amdgpu_dpm_forced_level level);
-       bool (*vblank_too_short)(struct amdgpu_device *adev);
-       void (*powergate_uvd)(struct amdgpu_device *adev, bool gate);
-       void (*powergate_vce)(struct amdgpu_device *adev, bool gate);
-       void (*enable_bapm)(struct amdgpu_device *adev, bool enable);
-       void (*set_fan_control_mode)(struct amdgpu_device *adev, u32 mode);
-       u32 (*get_fan_control_mode)(struct amdgpu_device *adev);
-       int (*set_fan_speed_percent)(struct amdgpu_device *adev, u32 speed);
-       int (*get_fan_speed_percent)(struct amdgpu_device *adev, u32 *speed);
-       int (*force_clock_level)(struct amdgpu_device *adev, enum pp_clock_type type, uint32_t mask);
-       int (*print_clock_levels)(struct amdgpu_device *adev, enum pp_clock_type type, char *buf);
-       int (*get_sclk_od)(struct amdgpu_device *adev);
-       int (*set_sclk_od)(struct amdgpu_device *adev, uint32_t value);
-       int (*get_mclk_od)(struct amdgpu_device *adev);
-       int (*set_mclk_od)(struct amdgpu_device *adev, uint32_t value);
- };
- struct amdgpu_dpm {
-       struct amdgpu_ps        *ps;
-       /* number of valid power states */
-       int                     num_ps;
-       /* current power state that is active */
-       struct amdgpu_ps        *current_ps;
-       /* requested power state */
-       struct amdgpu_ps        *requested_ps;
-       /* boot up power state */
-       struct amdgpu_ps        *boot_ps;
-       /* default uvd power state */
-       struct amdgpu_ps        *uvd_ps;
-       /* vce requirements */
-       struct amdgpu_vce_state vce_states[AMDGPU_MAX_VCE_LEVELS];
-       enum amdgpu_vce_level vce_level;
-       enum amd_pm_state_type state;
-       enum amd_pm_state_type user_state;
-       u32                     platform_caps;
-       u32                     voltage_response_time;
-       u32                     backbias_response_time;
-       void                    *priv;
-       u32                     new_active_crtcs;
-       int                     new_active_crtc_count;
-       u32                     current_active_crtcs;
-       int                     current_active_crtc_count;
-       struct amdgpu_dpm_dynamic_state dyn_state;
-       struct amdgpu_dpm_fan fan;
-       u32 tdp_limit;
-       u32 near_tdp_limit;
-       u32 near_tdp_limit_adjusted;
-       u32 sq_ramping_threshold;
-       u32 cac_leakage;
-       u16 tdp_od_limit;
-       u32 tdp_adjustment;
-       u16 load_line_slope;
-       bool power_control;
-       bool ac_power;
-       /* special states active */
-       bool                    thermal_active;
-       bool                    uvd_active;
-       bool                    vce_active;
-       /* thermal handling */
-       struct amdgpu_dpm_thermal thermal;
-       /* forced levels */
-       enum amdgpu_dpm_forced_level forced_level;
- };
- struct amdgpu_pm {
-       struct mutex            mutex;
-       u32                     current_sclk;
-       u32                     current_mclk;
-       u32                     default_sclk;
-       u32                     default_mclk;
-       struct amdgpu_i2c_chan *i2c_bus;
-       /* internal thermal controller on rv6xx+ */
-       enum amdgpu_int_thermal_type int_thermal_type;
-       struct device           *int_hwmon_dev;
-       /* fan control parameters */
-       bool                    no_fan;
-       u8                      fan_pulses_per_revolution;
-       u8                      fan_min_rpm;
-       u8                      fan_max_rpm;
-       /* dpm */
-       bool                    dpm_enabled;
-       bool                    sysfs_initialized;
-       struct amdgpu_dpm       dpm;
-       const struct firmware   *fw;    /* SMC firmware */
-       uint32_t                fw_version;
-       const struct amdgpu_dpm_funcs *funcs;
-       uint32_t                pcie_gen_mask;
-       uint32_t                pcie_mlw_mask;
-       struct amd_pp_display_configuration pm_display_cfg;/* set by DAL */
- };
  void amdgpu_get_pcie_info(struct amdgpu_device *adev);
  
  /*
@@@ -1863,6 -1215,8 +1215,8 @@@ int amdgpu_gem_op_ioctl(struct drm_devi
                        struct drm_file *filp);
  int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
  int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
+ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *filp);
  
  int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *filp);
@@@ -1940,14 -1294,6 +1294,6 @@@ typedef void (*amdgpu_wreg_t)(struct am
  typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
  typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
  
- struct amdgpu_ip_block_status {
-       bool valid;
-       bool sw;
-       bool hw;
-       bool late_initialized;
-       bool hang;
- };
  struct amdgpu_device {
        struct device                   *dev;
        struct drm_device               *ddev;
  
        /* BIOS */
        uint8_t                         *bios;
+       uint32_t                        bios_size;
        bool                            is_atom_bios;
        struct amdgpu_bo                *stollen_vga_memory;
        uint32_t                        bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
        /* GDS */
        struct amdgpu_gds               gds;
  
-       const struct amdgpu_ip_block_version *ip_blocks;
+       struct amdgpu_ip_block          ip_blocks[AMDGPU_MAX_IP_NUM];
        int                             num_ip_blocks;
-       struct amdgpu_ip_block_status   *ip_block_status;
        struct mutex    mn_lock;
        DECLARE_HASHTABLE(mn_hash, 7);
  
  
  };
  
+ static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
+ {
+       return container_of(bdev, struct amdgpu_device, mman.bdev);
+ }
  bool amdgpu_device_is_px(struct drm_device *dev);
  int amdgpu_device_init(struct amdgpu_device *adev,
                       struct drm_device *ddev,
@@@ -2279,15 -1630,12 +1630,12 @@@ amdgpu_get_sdma_instance(struct amdgpu_
  #define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
  #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
  #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
- #define amdgpu_ring_get_emit_ib_size(r) (r)->funcs->get_emit_ib_size((r))
- #define amdgpu_ring_get_dma_frame_size(r) (r)->funcs->get_dma_frame_size((r))
  #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
  #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
  #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
  #define amdgpu_display_set_vga_render_state(adev, r) (adev)->mode_info.funcs->set_vga_render_state((adev), (r))
  #define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
  #define amdgpu_display_vblank_wait(adev, crtc) (adev)->mode_info.funcs->vblank_wait((adev), (crtc))
- #define amdgpu_display_is_display_hung(adev) (adev)->mode_info.funcs->is_display_hung((adev))
  #define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
  #define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e))
  #define amdgpu_display_hpd_sense(adev, h) (adev)->mode_info.funcs->hpd_sense((adev), (h))
  #define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
  #define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b))
  #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
- #define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev))
- #define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev))
- #define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev))
- #define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev))
- #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps))
- #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev))
- #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e))
  #define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
  #define amdgpu_gfx_select_se_sh(adev, se, sh, instance) (adev)->gfx.funcs->select_se_sh((adev), (se), (sh), (instance))
- #define amdgpu_dpm_read_sensor(adev, idx, value) \
-       ((adev)->pp_enabled ? \
-               (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value)) : \
-               -EINVAL)
- #define amdgpu_dpm_get_temperature(adev) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle) : \
-             (adev)->pm.funcs->get_temperature((adev)))
- #define amdgpu_dpm_set_fan_control_mode(adev, m) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)) : \
-             (adev)->pm.funcs->set_fan_control_mode((adev), (m)))
- #define amdgpu_dpm_get_fan_control_mode(adev) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle) : \
-             (adev)->pm.funcs->get_fan_control_mode((adev)))
- #define amdgpu_dpm_set_fan_speed_percent(adev, s) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \
-             (adev)->pm.funcs->set_fan_speed_percent((adev), (s)))
- #define amdgpu_dpm_get_fan_speed_percent(adev, s) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \
-             (adev)->pm.funcs->get_fan_speed_percent((adev), (s)))
- #define amdgpu_dpm_get_sclk(adev, l) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \
-               (adev)->pm.funcs->get_sclk((adev), (l)))
- #define amdgpu_dpm_get_mclk(adev, l)  \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \
-             (adev)->pm.funcs->get_mclk((adev), (l)))
- #define amdgpu_dpm_force_performance_level(adev, l) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \
-             (adev)->pm.funcs->force_performance_level((adev), (l)))
- #define amdgpu_dpm_powergate_uvd(adev, g) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \
-             (adev)->pm.funcs->powergate_uvd((adev), (g)))
- #define amdgpu_dpm_powergate_vce(adev, g) \
-       ((adev)->pp_enabled ?                                           \
-             (adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \
-             (adev)->pm.funcs->powergate_vce((adev), (g)))
- #define amdgpu_dpm_get_current_power_state(adev) \
-       (adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)
- #define amdgpu_dpm_get_performance_level(adev) \
-       (adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle)
- #define amdgpu_dpm_get_pp_num_states(adev, data) \
-       (adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data)
- #define amdgpu_dpm_get_pp_table(adev, table) \
-       (adev)->powerplay.pp_funcs->get_pp_table((adev)->powerplay.pp_handle, table)
- #define amdgpu_dpm_set_pp_table(adev, buf, size) \
-       (adev)->powerplay.pp_funcs->set_pp_table((adev)->powerplay.pp_handle, buf, size)
- #define amdgpu_dpm_print_clock_levels(adev, type, buf) \
-       (adev)->powerplay.pp_funcs->print_clock_levels((adev)->powerplay.pp_handle, type, buf)
- #define amdgpu_dpm_force_clock_level(adev, type, level) \
-               (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level)
- #define amdgpu_dpm_get_sclk_od(adev) \
-       (adev)->powerplay.pp_funcs->get_sclk_od((adev)->powerplay.pp_handle)
- #define amdgpu_dpm_set_sclk_od(adev, value) \
-       (adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value)
- #define amdgpu_dpm_get_mclk_od(adev) \
-       ((adev)->powerplay.pp_funcs->get_mclk_od((adev)->powerplay.pp_handle))
- #define amdgpu_dpm_set_mclk_od(adev, value) \
-       ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value))
- #define amdgpu_dpm_dispatch_task(adev, event_id, input, output)               \
-       (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output))
  #define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
  
  /* Common functions */
@@@ -2434,8 -1682,6 +1682,6 @@@ uint32_t amdgpu_ttm_tt_pte_flags(struc
  void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
  void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
  void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
- u64 amdgpu_ttm_get_gtt_mem_size(struct amdgpu_device *adev);
- int amdgpu_ttm_global_init(struct amdgpu_device *adev);
  int amdgpu_ttm_init(struct amdgpu_device *adev);
  void amdgpu_ttm_fini(struct amdgpu_device *adev);
  void amdgpu_program_register_sequence(struct amdgpu_device *adev,
@@@ -2472,7 -1718,6 +1718,7 @@@ void amdgpu_driver_postclose_kms(struc
                                 struct drm_file *file_priv);
  void amdgpu_driver_preclose_kms(struct drm_device *dev,
                                struct drm_file *file_priv);
 +int amdgpu_suspend(struct amdgpu_device *adev);
  int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon);
  int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon);
  u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
index e41d4baebf86ea39b7e604071d72b0ca29ded612,f6394b5793c2e214856bb3b0d105dcaa73408501..cc8aafd9cb0d4160cd8578001ac45236ec778c65
@@@ -264,7 -264,8 +264,8 @@@ static int amdgpu_vram_scratch_init(str
        if (adev->vram_scratch.robj == NULL) {
                r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
                                     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
-                                    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+                                    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+                                    AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
                                     NULL, NULL, &adev->vram_scratch.robj);
                if (r) {
                        return r;
@@@ -442,13 -443,9 +443,9 @@@ void amdgpu_doorbell_get_kfd_info(struc
  static void amdgpu_wb_fini(struct amdgpu_device *adev)
  {
        if (adev->wb.wb_obj) {
-               if (!amdgpu_bo_reserve(adev->wb.wb_obj, false)) {
-                       amdgpu_bo_kunmap(adev->wb.wb_obj);
-                       amdgpu_bo_unpin(adev->wb.wb_obj);
-                       amdgpu_bo_unreserve(adev->wb.wb_obj);
-               }
-               amdgpu_bo_unref(&adev->wb.wb_obj);
-               adev->wb.wb = NULL;
+               amdgpu_bo_free_kernel(&adev->wb.wb_obj,
+                                     &adev->wb.gpu_addr,
+                                     (void **)&adev->wb.wb);
                adev->wb.wb_obj = NULL;
        }
  }
@@@ -467,33 -464,14 +464,14 @@@ static int amdgpu_wb_init(struct amdgpu
        int r;
  
        if (adev->wb.wb_obj == NULL) {
-               r = amdgpu_bo_create(adev, AMDGPU_MAX_WB * 4, PAGE_SIZE, true,
-                                    AMDGPU_GEM_DOMAIN_GTT, 0,  NULL, NULL,
-                                    &adev->wb.wb_obj);
+               r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * 4,
+                                           PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+                                           &adev->wb.wb_obj, &adev->wb.gpu_addr,
+                                           (void **)&adev->wb.wb);
                if (r) {
                        dev_warn(adev->dev, "(%d) create WB bo failed\n", r);
                        return r;
                }
-               r = amdgpu_bo_reserve(adev->wb.wb_obj, false);
-               if (unlikely(r != 0)) {
-                       amdgpu_wb_fini(adev);
-                       return r;
-               }
-               r = amdgpu_bo_pin(adev->wb.wb_obj, AMDGPU_GEM_DOMAIN_GTT,
-                               &adev->wb.gpu_addr);
-               if (r) {
-                       amdgpu_bo_unreserve(adev->wb.wb_obj);
-                       dev_warn(adev->dev, "(%d) pin WB bo failed\n", r);
-                       amdgpu_wb_fini(adev);
-                       return r;
-               }
-               r = amdgpu_bo_kmap(adev->wb.wb_obj, (void **)&adev->wb.wb);
-               amdgpu_bo_unreserve(adev->wb.wb_obj);
-               if (r) {
-                       dev_warn(adev->dev, "(%d) map WB bo failed\n", r);
-                       amdgpu_wb_fini(adev);
-                       return r;
-               }
  
                adev->wb.num_wb = AMDGPU_MAX_WB;
                memset(&adev->wb.used, 0, sizeof(adev->wb.used));
@@@ -1038,6 -1016,13 +1016,13 @@@ static void amdgpu_check_arguments(stru
                         amdgpu_vm_block_size);
                amdgpu_vm_block_size = 9;
        }
+       if (amdgpu_vram_page_split != -1 && (amdgpu_vram_page_split < 16 ||
+           !amdgpu_check_pot_argument(amdgpu_vram_page_split))) {
+               dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
+                        amdgpu_vram_page_split);
+               amdgpu_vram_page_split = 1024;
+       }
  }
  
  /**
@@@ -1112,11 -1097,11 +1097,11 @@@ int amdgpu_set_clockgating_state(struc
        int i, r = 0;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].type == block_type) {
-                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                           state);
+               if (adev->ip_blocks[i].version->type == block_type) {
+                       r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                                    state);
                        if (r)
                                return r;
                        break;
@@@ -1132,11 -1117,11 +1117,11 @@@ int amdgpu_set_powergating_state(struc
        int i, r = 0;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].type == block_type) {
-                       r = adev->ip_blocks[i].funcs->set_powergating_state((void *)adev,
-                                                                           state);
+               if (adev->ip_blocks[i].version->type == block_type) {
+                       r = adev->ip_blocks[i].version->funcs->set_powergating_state((void *)adev,
+                                                                                    state);
                        if (r)
                                return r;
                        break;
@@@ -1151,10 -1136,10 +1136,10 @@@ int amdgpu_wait_for_idle(struct amdgpu_
        int i, r;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].type == block_type) {
-                       r = adev->ip_blocks[i].funcs->wait_for_idle((void *)adev);
+               if (adev->ip_blocks[i].version->type == block_type) {
+                       r = adev->ip_blocks[i].version->funcs->wait_for_idle((void *)adev);
                        if (r)
                                return r;
                        break;
@@@ -1170,23 -1155,22 +1155,22 @@@ bool amdgpu_is_idle(struct amdgpu_devic
        int i;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].type == block_type)
-                       return adev->ip_blocks[i].funcs->is_idle((void *)adev);
+               if (adev->ip_blocks[i].version->type == block_type)
+                       return adev->ip_blocks[i].version->funcs->is_idle((void *)adev);
        }
        return true;
  
  }
  
- const struct amdgpu_ip_block_version * amdgpu_get_ip_block(
-                                       struct amdgpu_device *adev,
-                                       enum amd_ip_block_type type)
+ struct amdgpu_ip_block * amdgpu_get_ip_block(struct amdgpu_device *adev,
+                                            enum amd_ip_block_type type)
  {
        int i;
  
        for (i = 0; i < adev->num_ip_blocks; i++)
-               if (adev->ip_blocks[i].type == type)
+               if (adev->ip_blocks[i].version->type == type)
                        return &adev->ip_blocks[i];
  
        return NULL;
@@@ -1207,38 -1191,75 +1191,75 @@@ int amdgpu_ip_block_version_cmp(struct 
                                enum amd_ip_block_type type,
                                u32 major, u32 minor)
  {
-       const struct amdgpu_ip_block_version *ip_block;
-       ip_block = amdgpu_get_ip_block(adev, type);
+       struct amdgpu_ip_block *ip_block = amdgpu_get_ip_block(adev, type);
  
-       if (ip_block && ((ip_block->major > major) ||
-                       ((ip_block->major == major) &&
-                       (ip_block->minor >= minor))))
+       if (ip_block && ((ip_block->version->major > major) ||
+                       ((ip_block->version->major == major) &&
+                       (ip_block->version->minor >= minor))))
                return 0;
  
        return 1;
  }
  
- static void amdgpu_whether_enable_virtual_display(struct amdgpu_device *adev)
+ /**
+  * amdgpu_ip_block_add
+  *
+  * @adev: amdgpu_device pointer
+  * @ip_block_version: pointer to the IP to add
+  *
+  * Adds the IP block driver information to the collection of IPs
+  * on the asic.
+  */
+ int amdgpu_ip_block_add(struct amdgpu_device *adev,
+                       const struct amdgpu_ip_block_version *ip_block_version)
+ {
+       if (!ip_block_version)
+               return -EINVAL;
+       adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version;
+       return 0;
+ }
+ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
  {
        adev->enable_virtual_display = false;
  
        if (amdgpu_virtual_display) {
                struct drm_device *ddev = adev->ddev;
                const char *pci_address_name = pci_name(ddev->pdev);
-               char *pciaddstr, *pciaddstr_tmp, *pciaddname;
+               char *pciaddstr, *pciaddstr_tmp, *pciaddname_tmp, *pciaddname;
  
                pciaddstr = kstrdup(amdgpu_virtual_display, GFP_KERNEL);
                pciaddstr_tmp = pciaddstr;
-               while ((pciaddname = strsep(&pciaddstr_tmp, ";"))) {
+               while ((pciaddname_tmp = strsep(&pciaddstr_tmp, ";"))) {
+                       pciaddname = strsep(&pciaddname_tmp, ",");
                        if (!strcmp(pci_address_name, pciaddname)) {
+                               long num_crtc;
+                               int res = -1;
                                adev->enable_virtual_display = true;
+                               if (pciaddname_tmp)
+                                       res = kstrtol(pciaddname_tmp, 10,
+                                                     &num_crtc);
+                               if (!res) {
+                                       if (num_crtc < 1)
+                                               num_crtc = 1;
+                                       if (num_crtc > 6)
+                                               num_crtc = 6;
+                                       adev->mode_info.num_crtc = num_crtc;
+                               } else {
+                                       adev->mode_info.num_crtc = 1;
+                               }
                                break;
                        }
                }
  
-               DRM_INFO("virtual display string:%s, %s:virtual_display:%d\n",
-                                amdgpu_virtual_display, pci_address_name,
-                                adev->enable_virtual_display);
+               DRM_INFO("virtual display string:%s, %s:virtual_display:%d, num_crtc:%d\n",
+                        amdgpu_virtual_display, pci_address_name,
+                        adev->enable_virtual_display, adev->mode_info.num_crtc);
  
                kfree(pciaddstr);
        }
@@@ -1248,7 -1269,7 +1269,7 @@@ static int amdgpu_early_init(struct amd
  {
        int i, r;
  
-       amdgpu_whether_enable_virtual_display(adev);
+       amdgpu_device_enable_virtual_display(adev);
  
        switch (adev->asic_type) {
        case CHIP_TOPAZ:
                return -EINVAL;
        }
  
-       adev->ip_block_status = kcalloc(adev->num_ip_blocks,
-                                       sizeof(struct amdgpu_ip_block_status), GFP_KERNEL);
-       if (adev->ip_block_status == NULL)
-               return -ENOMEM;
-       if (adev->ip_blocks == NULL) {
-               DRM_ERROR("No IP blocks found!\n");
-               return r;
-       }
        for (i = 0; i < adev->num_ip_blocks; i++) {
                if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
                        DRM_ERROR("disabled ip block: %d\n", i);
-                       adev->ip_block_status[i].valid = false;
+                       adev->ip_blocks[i].status.valid = false;
                } else {
-                       if (adev->ip_blocks[i].funcs->early_init) {
-                               r = adev->ip_blocks[i].funcs->early_init((void *)adev);
+                       if (adev->ip_blocks[i].version->funcs->early_init) {
+                               r = adev->ip_blocks[i].version->funcs->early_init((void *)adev);
                                if (r == -ENOENT) {
-                                       adev->ip_block_status[i].valid = false;
+                                       adev->ip_blocks[i].status.valid = false;
                                } else if (r) {
-                                       DRM_ERROR("early_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                                       DRM_ERROR("early_init of IP block <%s> failed %d\n",
+                                                 adev->ip_blocks[i].version->funcs->name, r);
                                        return r;
                                } else {
-                                       adev->ip_block_status[i].valid = true;
+                                       adev->ip_blocks[i].status.valid = true;
                                }
                        } else {
-                               adev->ip_block_status[i].valid = true;
+                               adev->ip_blocks[i].status.valid = true;
                        }
                }
        }
@@@ -1342,22 -1354,23 +1354,23 @@@ static int amdgpu_init(struct amdgpu_de
        int i, r;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               r = adev->ip_blocks[i].funcs->sw_init((void *)adev);
+               r = adev->ip_blocks[i].version->funcs->sw_init((void *)adev);
                if (r) {
-                       DRM_ERROR("sw_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_ERROR("sw_init of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                        return r;
                }
-               adev->ip_block_status[i].sw = true;
+               adev->ip_blocks[i].status.sw = true;
                /* need to do gmc hw init early so we can allocate gpu mem */
-               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
+               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
                        r = amdgpu_vram_scratch_init(adev);
                        if (r) {
                                DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r);
                                return r;
                        }
-                       r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
+                       r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
                        if (r) {
                                DRM_ERROR("hw_init %d failed %d\n", i, r);
                                return r;
                                DRM_ERROR("amdgpu_wb_init failed %d\n", r);
                                return r;
                        }
-                       adev->ip_block_status[i].hw = true;
+                       adev->ip_blocks[i].status.hw = true;
                }
        }
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].sw)
+               if (!adev->ip_blocks[i].status.sw)
                        continue;
                /* gmc hw init is done early */
-               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC)
+               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC)
                        continue;
-               r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
+               r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
                if (r) {
-                       DRM_ERROR("hw_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_ERROR("hw_init of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                        return r;
                }
-               adev->ip_block_status[i].hw = true;
+               adev->ip_blocks[i].status.hw = true;
        }
  
        return 0;
@@@ -1393,25 -1407,26 +1407,26 @@@ static int amdgpu_late_init(struct amdg
        int i = 0, r;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].funcs->late_init) {
-                       r = adev->ip_blocks[i].funcs->late_init((void *)adev);
+               if (adev->ip_blocks[i].version->funcs->late_init) {
+                       r = adev->ip_blocks[i].version->funcs->late_init((void *)adev);
                        if (r) {
-                               DRM_ERROR("late_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                               DRM_ERROR("late_init of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].version->funcs->name, r);
                                return r;
                        }
-                       adev->ip_block_status[i].late_initialized = true;
+                       adev->ip_blocks[i].status.late_initialized = true;
                }
                /* skip CG for VCE/UVD, it's handled specially */
-               if (adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_UVD &&
-                   adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_VCE) {
+               if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
+                   adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
                        /* enable clockgating to save power */
-                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                           AMD_CG_STATE_GATE);
+                       r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                                    AMD_CG_STATE_GATE);
                        if (r) {
                                DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n",
-                                         adev->ip_blocks[i].funcs->name, r);
+                                         adev->ip_blocks[i].version->funcs->name, r);
                                return r;
                        }
                }
@@@ -1426,74 -1441,83 +1441,83 @@@ static int amdgpu_fini(struct amdgpu_de
  
        /* need to disable SMC first */
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].hw)
+               if (!adev->ip_blocks[i].status.hw)
                        continue;
-               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) {
+               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
                        /* ungate blocks before hw fini so that we can shutdown the blocks safely */
-                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                           AMD_CG_STATE_UNGATE);
+                       r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                                    AMD_CG_STATE_UNGATE);
                        if (r) {
                                DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
-                                         adev->ip_blocks[i].funcs->name, r);
+                                         adev->ip_blocks[i].version->funcs->name, r);
                                return r;
                        }
-                       r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
+                       r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev);
                        /* XXX handle errors */
                        if (r) {
                                DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
-                                         adev->ip_blocks[i].funcs->name, r);
+                                         adev->ip_blocks[i].version->funcs->name, r);
                        }
-                       adev->ip_block_status[i].hw = false;
+                       adev->ip_blocks[i].status.hw = false;
                        break;
                }
        }
  
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
-               if (!adev->ip_block_status[i].hw)
+               if (!adev->ip_blocks[i].status.hw)
                        continue;
-               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
+               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
                        amdgpu_wb_fini(adev);
                        amdgpu_vram_scratch_fini(adev);
                }
-               /* ungate blocks before hw fini so that we can shutdown the blocks safely */
-               r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                   AMD_CG_STATE_UNGATE);
-               if (r) {
-                       DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
-                       return r;
+               if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
+                       adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
+                       /* ungate blocks before hw fini so that we can shutdown the blocks safely */
+                       r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                                    AMD_CG_STATE_UNGATE);
+                       if (r) {
+                               DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].version->funcs->name, r);
+                               return r;
+                       }
                }
-               r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
+               r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev);
                /* XXX handle errors */
                if (r) {
-                       DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                }
-               adev->ip_block_status[i].hw = false;
+               adev->ip_blocks[i].status.hw = false;
        }
  
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
-               if (!adev->ip_block_status[i].sw)
+               if (!adev->ip_blocks[i].status.sw)
                        continue;
-               r = adev->ip_blocks[i].funcs->sw_fini((void *)adev);
+               r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev);
                /* XXX handle errors */
                if (r) {
-                       DRM_DEBUG("sw_fini of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_DEBUG("sw_fini of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                }
-               adev->ip_block_status[i].sw = false;
-               adev->ip_block_status[i].valid = false;
+               adev->ip_blocks[i].status.sw = false;
+               adev->ip_blocks[i].status.valid = false;
        }
  
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
-               if (!adev->ip_block_status[i].late_initialized)
+               if (!adev->ip_blocks[i].status.late_initialized)
                        continue;
-               if (adev->ip_blocks[i].funcs->late_fini)
-                       adev->ip_blocks[i].funcs->late_fini((void *)adev);
-               adev->ip_block_status[i].late_initialized = false;
+               if (adev->ip_blocks[i].version->funcs->late_fini)
+                       adev->ip_blocks[i].version->funcs->late_fini((void *)adev);
+               adev->ip_blocks[i].status.late_initialized = false;
        }
  
        return 0;
  }
  
 -static int amdgpu_suspend(struct amdgpu_device *adev)
 +int amdgpu_suspend(struct amdgpu_device *adev)
  {
        int i, r;
  
        }
  
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
                /* ungate blocks so that suspend can properly shut them down */
                if (i != AMD_IP_BLOCK_TYPE_SMC) {
-                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                           AMD_CG_STATE_UNGATE);
+                       r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
+                                                                                    AMD_CG_STATE_UNGATE);
                        if (r) {
-                               DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                               DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].version->funcs->name, r);
                        }
                }
                /* XXX handle errors */
-               r = adev->ip_blocks[i].funcs->suspend(adev);
+               r = adev->ip_blocks[i].version->funcs->suspend(adev);
                /* XXX handle errors */
                if (r) {
-                       DRM_ERROR("suspend of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_ERROR("suspend of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                }
        }
  
@@@ -1531,11 -1557,12 +1557,12 @@@ static int amdgpu_resume(struct amdgpu_
        int i, r;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               r = adev->ip_blocks[i].funcs->resume(adev);
+               r = adev->ip_blocks[i].version->funcs->resume(adev);
                if (r) {
-                       DRM_ERROR("resume of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
+                       DRM_ERROR("resume of IP block <%s> failed %d\n",
+                                 adev->ip_blocks[i].version->funcs->name, r);
                        return r;
                }
        }
@@@ -1586,7 -1613,7 +1613,7 @@@ int amdgpu_device_init(struct amdgpu_de
        adev->vm_manager.vm_pte_funcs = NULL;
        adev->vm_manager.vm_pte_num_rings = 0;
        adev->gart.gart_funcs = NULL;
-       adev->fence_context = fence_context_alloc(AMDGPU_MAX_RINGS);
+       adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);
  
        adev->smc_rreg = &amdgpu_invalid_rreg;
        adev->smc_wreg = &amdgpu_invalid_wreg;
@@@ -1846,8 -1873,6 +1873,6 @@@ void amdgpu_device_fini(struct amdgpu_d
        amdgpu_fence_driver_fini(adev);
        amdgpu_fbdev_fini(adev);
        r = amdgpu_fini(adev);
-       kfree(adev->ip_block_status);
-       adev->ip_block_status = NULL;
        adev->accel_working = false;
        /* free i2c buses */
        amdgpu_i2c_fini(adev);
@@@ -1943,7 -1968,10 +1968,10 @@@ int amdgpu_device_suspend(struct drm_de
  
        r = amdgpu_suspend(adev);
  
-       /* evict remaining vram memory */
+       /* evict remaining vram memory
+        * This second call to evict vram is to evict the gart page table
+        * using the CPU.
+        */
        amdgpu_bo_evict_vram(adev);
  
        amdgpu_atombios_scratch_regs_save(adev);
@@@ -2085,13 -2113,13 +2113,13 @@@ static bool amdgpu_check_soft_reset(str
        bool asic_hang = false;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_blocks[i].funcs->check_soft_reset)
-                       adev->ip_block_status[i].hang =
-                               adev->ip_blocks[i].funcs->check_soft_reset(adev);
-               if (adev->ip_block_status[i].hang) {
-                       DRM_INFO("IP block:%d is hang!\n", i);
+               if (adev->ip_blocks[i].version->funcs->check_soft_reset)
+                       adev->ip_blocks[i].status.hang =
+                               adev->ip_blocks[i].version->funcs->check_soft_reset(adev);
+               if (adev->ip_blocks[i].status.hang) {
+                       DRM_INFO("IP block:%s is hung!\n", adev->ip_blocks[i].version->funcs->name);
                        asic_hang = true;
                }
        }
@@@ -2103,11 -2131,11 +2131,11 @@@ static int amdgpu_pre_soft_reset(struc
        int i, r = 0;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_block_status[i].hang &&
-                   adev->ip_blocks[i].funcs->pre_soft_reset) {
-                       r = adev->ip_blocks[i].funcs->pre_soft_reset(adev);
+               if (adev->ip_blocks[i].status.hang &&
+                   adev->ip_blocks[i].version->funcs->pre_soft_reset) {
+                       r = adev->ip_blocks[i].version->funcs->pre_soft_reset(adev);
                        if (r)
                                return r;
                }
@@@ -2121,13 -2149,13 +2149,13 @@@ static bool amdgpu_need_full_reset(stru
        int i;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) ||
-                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) ||
-                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) ||
-                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) {
-                       if (adev->ip_block_status[i].hang) {
+               if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) ||
+                   (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) ||
+                   (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_ACP) ||
+                   (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)) {
+                       if (adev->ip_blocks[i].status.hang) {
                                DRM_INFO("Some block need full reset!\n");
                                return true;
                        }
@@@ -2141,11 -2169,11 +2169,11 @@@ static int amdgpu_soft_reset(struct amd
        int i, r = 0;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_block_status[i].hang &&
-                   adev->ip_blocks[i].funcs->soft_reset) {
-                       r = adev->ip_blocks[i].funcs->soft_reset(adev);
+               if (adev->ip_blocks[i].status.hang &&
+                   adev->ip_blocks[i].version->funcs->soft_reset) {
+                       r = adev->ip_blocks[i].version->funcs->soft_reset(adev);
                        if (r)
                                return r;
                }
@@@ -2159,11 -2187,11 +2187,11 @@@ static int amdgpu_post_soft_reset(struc
        int i, r = 0;
  
        for (i = 0; i < adev->num_ip_blocks; i++) {
-               if (!adev->ip_block_status[i].valid)
+               if (!adev->ip_blocks[i].status.valid)
                        continue;
-               if (adev->ip_block_status[i].hang &&
-                   adev->ip_blocks[i].funcs->post_soft_reset)
-                       r = adev->ip_blocks[i].funcs->post_soft_reset(adev);
+               if (adev->ip_blocks[i].status.hang &&
+                   adev->ip_blocks[i].version->funcs->post_soft_reset)
+                       r = adev->ip_blocks[i].version->funcs->post_soft_reset(adev);
                if (r)
                        return r;
        }
@@@ -2182,7 -2210,7 +2210,7 @@@ bool amdgpu_need_backup(struct amdgpu_d
  static int amdgpu_recover_vram_from_shadow(struct amdgpu_device *adev,
                                           struct amdgpu_ring *ring,
                                           struct amdgpu_bo *bo,
-                                          struct fence **fence)
+                                          struct dma_fence **fence)
  {
        uint32_t domain;
        int r;
@@@ -2298,30 -2326,30 +2326,30 @@@ retry
                if (need_full_reset && amdgpu_need_backup(adev)) {
                        struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
                        struct amdgpu_bo *bo, *tmp;
-                       struct fence *fence = NULL, *next = NULL;
+                       struct dma_fence *fence = NULL, *next = NULL;
  
                        DRM_INFO("recover vram bo from shadow\n");
                        mutex_lock(&adev->shadow_list_lock);
                        list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
                                amdgpu_recover_vram_from_shadow(adev, ring, bo, &next);
                                if (fence) {
-                                       r = fence_wait(fence, false);
+                                       r = dma_fence_wait(fence, false);
                                        if (r) {
                                                WARN(r, "recovery from shadow isn't comleted\n");
                                                break;
                                        }
                                }
  
-                               fence_put(fence);
+                               dma_fence_put(fence);
                                fence = next;
                        }
                        mutex_unlock(&adev->shadow_list_lock);
                        if (fence) {
-                               r = fence_wait(fence, false);
+                               r = dma_fence_wait(fence, false);
                                if (r)
                                        WARN(r, "recovery from shadow isn't comleted\n");
                        }
-                       fence_put(fence);
+                       dma_fence_put(fence);
                }
                for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
                        struct amdgpu_ring *ring = adev->rings[i];
@@@ -2470,9 -2498,6 +2498,6 @@@ int amdgpu_debugfs_add_files(struct amd
        adev->debugfs[adev->debugfs_count].num_files = nfiles;
        adev->debugfs_count = i;
  #if defined(CONFIG_DEBUG_FS)
-       drm_debugfs_create_files(files, nfiles,
-                                adev->ddev->control->debugfs_root,
-                                adev->ddev->control);
        drm_debugfs_create_files(files, nfiles,
                                 adev->ddev->primary->debugfs_root,
                                 adev->ddev->primary);
@@@ -2486,9 -2511,6 +2511,6 @@@ static void amdgpu_debugfs_remove_files
        unsigned i;
  
        for (i = 0; i < adev->debugfs_count; i++) {
-               drm_debugfs_remove_files(adev->debugfs[i].files,
-                                        adev->debugfs[i].num_files,
-                                        adev->ddev->control);
                drm_debugfs_remove_files(adev->debugfs[i].files,
                                         adev->debugfs[i].num_files,
                                         adev->ddev->primary);
@@@ -2517,6 -2539,13 +2539,13 @@@ static ssize_t amdgpu_debugfs_regs_read
                se_bank = (*pos >> 24) & 0x3FF;
                sh_bank = (*pos >> 34) & 0x3FF;
                instance_bank = (*pos >> 44) & 0x3FF;
+               if (se_bank == 0x3FF)
+                       se_bank = 0xFFFFFFFF;
+               if (sh_bank == 0x3FF)
+                       sh_bank = 0xFFFFFFFF;
+               if (instance_bank == 0x3FF)
+                       instance_bank = 0xFFFFFFFF;
                use_bank = 1;
        } else {
                use_bank = 0;
        *pos &= 0x3FFFF;
  
        if (use_bank) {
-               if (sh_bank >= adev->gfx.config.max_sh_per_se ||
-                   se_bank >= adev->gfx.config.max_shader_engines)
+               if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
+                   (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
                        return -EINVAL;
                mutex_lock(&adev->grbm_idx_mutex);
                amdgpu_gfx_select_se_sh(adev, se_bank,
@@@ -2573,10 -2602,45 +2602,45 @@@ static ssize_t amdgpu_debugfs_regs_writ
        struct amdgpu_device *adev = f->f_inode->i_private;
        ssize_t result = 0;
        int r;
+       bool pm_pg_lock, use_bank;
+       unsigned instance_bank, sh_bank, se_bank;
  
        if (size & 0x3 || *pos & 0x3)
                return -EINVAL;
  
+       /* are we reading registers for which a PG lock is necessary? */
+       pm_pg_lock = (*pos >> 23) & 1;
+       if (*pos & (1ULL << 62)) {
+               se_bank = (*pos >> 24) & 0x3FF;
+               sh_bank = (*pos >> 34) & 0x3FF;
+               instance_bank = (*pos >> 44) & 0x3FF;
+               if (se_bank == 0x3FF)
+                       se_bank = 0xFFFFFFFF;
+               if (sh_bank == 0x3FF)
+                       sh_bank = 0xFFFFFFFF;
+               if (instance_bank == 0x3FF)
+                       instance_bank = 0xFFFFFFFF;
+               use_bank = 1;
+       } else {
+               use_bank = 0;
+       }
+       *pos &= 0x3FFFF;
+       if (use_bank) {
+               if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
+                   (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
+                       return -EINVAL;
+               mutex_lock(&adev->grbm_idx_mutex);
+               amdgpu_gfx_select_se_sh(adev, se_bank,
+                                       sh_bank, instance_bank);
+       }
+       if (pm_pg_lock)
+               mutex_lock(&adev->pm.mutex);
        while (size) {
                uint32_t value;
  
                size -= 4;
        }
  
+       if (use_bank) {
+               amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
+               mutex_unlock(&adev->grbm_idx_mutex);
+       }
+       if (pm_pg_lock)
+               mutex_unlock(&adev->pm.mutex);
        return result;
  }
  
@@@ -2857,6 -2929,116 +2929,116 @@@ static ssize_t amdgpu_debugfs_sensor_re
        return !r ? 4 : r;
  }
  
+ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
+                                       size_t size, loff_t *pos)
+ {
+       struct amdgpu_device *adev = f->f_inode->i_private;
+       int r, x;
+       ssize_t result=0;
+       uint32_t offset, se, sh, cu, wave, simd, data[32];
+       if (size & 3 || *pos & 3)
+               return -EINVAL;
+       /* decode offset */
+       offset = (*pos & 0x7F);
+       se = ((*pos >> 7) & 0xFF);
+       sh = ((*pos >> 15) & 0xFF);
+       cu = ((*pos >> 23) & 0xFF);
+       wave = ((*pos >> 31) & 0xFF);
+       simd = ((*pos >> 37) & 0xFF);
+       /* switch to the specific se/sh/cu */
+       mutex_lock(&adev->grbm_idx_mutex);
+       amdgpu_gfx_select_se_sh(adev, se, sh, cu);
+       x = 0;
+       if (adev->gfx.funcs->read_wave_data)
+               adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x);
+       amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+       mutex_unlock(&adev->grbm_idx_mutex);
+       if (!x)
+               return -EINVAL;
+       while (size && (offset < x * 4)) {
+               uint32_t value;
+               value = data[offset >> 2];
+               r = put_user(value, (uint32_t *)buf);
+               if (r)
+                       return r;
+               result += 4;
+               buf += 4;
+               offset += 4;
+               size -= 4;
+       }
+       return result;
+ }
+ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
+                                       size_t size, loff_t *pos)
+ {
+       struct amdgpu_device *adev = f->f_inode->i_private;
+       int r;
+       ssize_t result = 0;
+       uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;
+       if (size & 3 || *pos & 3)
+               return -EINVAL;
+       /* decode offset */
+       offset = (*pos & 0xFFF);       /* in dwords */
+       se = ((*pos >> 12) & 0xFF);
+       sh = ((*pos >> 20) & 0xFF);
+       cu = ((*pos >> 28) & 0xFF);
+       wave = ((*pos >> 36) & 0xFF);
+       simd = ((*pos >> 44) & 0xFF);
+       thread = ((*pos >> 52) & 0xFF);
+       bank = ((*pos >> 60) & 1);
+       data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       /* switch to the specific se/sh/cu */
+       mutex_lock(&adev->grbm_idx_mutex);
+       amdgpu_gfx_select_se_sh(adev, se, sh, cu);
+       if (bank == 0) {
+               if (adev->gfx.funcs->read_wave_vgprs)
+                       adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);
+       } else {
+               if (adev->gfx.funcs->read_wave_sgprs)
+                       adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);
+       }
+       amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+       mutex_unlock(&adev->grbm_idx_mutex);
+       while (size) {
+               uint32_t value;
+               value = data[offset++];
+               r = put_user(value, (uint32_t *)buf);
+               if (r) {
+                       result = r;
+                       goto err;
+               }
+               result += 4;
+               buf += 4;
+               size -= 4;
+       }
+ err:
+       kfree(data);
+       return result;
+ }
  static const struct file_operations amdgpu_debugfs_regs_fops = {
        .owner = THIS_MODULE,
        .read = amdgpu_debugfs_regs_read,
@@@ -2894,6 -3076,17 +3076,17 @@@ static const struct file_operations amd
        .llseek = default_llseek
  };
  
+ static const struct file_operations amdgpu_debugfs_wave_fops = {
+       .owner = THIS_MODULE,
+       .read = amdgpu_debugfs_wave_read,
+       .llseek = default_llseek
+ };
+ static const struct file_operations amdgpu_debugfs_gpr_fops = {
+       .owner = THIS_MODULE,
+       .read = amdgpu_debugfs_gpr_read,
+       .llseek = default_llseek
+ };
  static const struct file_operations *debugfs_regs[] = {
        &amdgpu_debugfs_regs_fops,
        &amdgpu_debugfs_regs_didt_fops,
        &amdgpu_debugfs_regs_smc_fops,
        &amdgpu_debugfs_gca_config_fops,
        &amdgpu_debugfs_sensors_fops,
+       &amdgpu_debugfs_wave_fops,
+       &amdgpu_debugfs_gpr_fops,
  };
  
  static const char *debugfs_regs_names[] = {
        "amdgpu_regs_smc",
        "amdgpu_gca_config",
        "amdgpu_sensors",
+       "amdgpu_wave",
+       "amdgpu_gpr",
  };
  
  static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
index e0890deccb2fe31d4deb78deac640d53d8f34a45,7914f999b1bc2082e9419bcec63e1627ca150e50..8cb937b2bfcc7fac0e3308aaa5cdc70cd53021c2
   * - 3.6.0 - kmd involves use CONTEXT_CONTROL in ring buffer.
   * - 3.7.0 - Add support for VCE clock list packet
   * - 3.8.0 - Add support raster config init in the kernel
+  * - 3.9.0 - Add support for memory query info about VRAM and GTT.
   */
  #define KMS_DRIVER_MAJOR      3
- #define KMS_DRIVER_MINOR      8
+ #define KMS_DRIVER_MINOR      9
  #define KMS_DRIVER_PATCHLEVEL 0
  
  int amdgpu_vram_limit = 0;
@@@ -85,12 -86,13 +86,13 @@@ int amdgpu_vm_size = 64
  int amdgpu_vm_block_size = -1;
  int amdgpu_vm_fault_stop = 0;
  int amdgpu_vm_debug = 0;
+ int amdgpu_vram_page_split = 1024;
  int amdgpu_exp_hw_support = 0;
  int amdgpu_sched_jobs = 32;
  int amdgpu_sched_hw_submission = 2;
  int amdgpu_powerplay = -1;
- int amdgpu_powercontainment = 1;
- int amdgpu_sclk_deep_sleep_en = 1;
+ int amdgpu_no_evict = 0;
+ int amdgpu_direct_gma_size = 0;
  unsigned amdgpu_pcie_gen_cap = 0;
  unsigned amdgpu_pcie_lane_cap = 0;
  unsigned amdgpu_cg_mask = 0xffffffff;
@@@ -165,6 -167,9 +167,9 @@@ module_param_named(vm_fault_stop, amdgp
  MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)");
  module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
  
+ MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024, -1 = disable)");
+ module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
  MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
  module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
  
@@@ -177,14 -182,14 +182,14 @@@ module_param_named(sched_hw_submission
  MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))");
  module_param_named(powerplay, amdgpu_powerplay, int, 0444);
  
- MODULE_PARM_DESC(powercontainment, "Power Containment (1 = enable (default), 0 = disable)");
- module_param_named(powercontainment, amdgpu_powercontainment, int, 0444);
  MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
  module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, int, 0444);
  
- MODULE_PARM_DESC(sclkdeepsleep, "SCLK Deep Sleep (1 = enable (default), 0 = disable)");
- module_param_named(sclkdeepsleep, amdgpu_sclk_deep_sleep_en, int, 0444);
+ MODULE_PARM_DESC(no_evict, "Support pinning request from user space (1 = enable, 0 = disable (default))");
+ module_param_named(no_evict, amdgpu_no_evict, int, 0444);
+ MODULE_PARM_DESC(direct_gma_size, "Direct GMA size in megabytes (max 96MB)");
+ module_param_named(direct_gma_size, amdgpu_direct_gma_size, int, 0444);
  
  MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))");
  module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444);
@@@ -201,7 -206,8 +206,8 @@@ module_param_named(pg_mask, amdgpu_pg_m
  MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)");
  module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444);
  
- MODULE_PARM_DESC(virtual_display, "Enable virtual display feature (the virtual_display will be set like xxxx:xx:xx.x;xxxx:xx:xx.x)");
+ MODULE_PARM_DESC(virtual_display,
+                "Enable virtual display feature (the virtual_display will be set like xxxx:xx:xx.x,x;xxxx:xx:xx.x,x)");
  module_param_named(virtual_display, amdgpu_virtual_display, charp, 0444);
  
  static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x6939, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
        /* fiji */
        {0x1002, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_FIJI},
+       {0x1002, 0x730F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_FIJI},
        /* carrizo */
        {0x1002, 0x9870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMD_IS_APU},
        {0x1002, 0x9874, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CARRIZO|AMD_IS_APU},
@@@ -479,15 -486,12 +486,15 @@@ amdgpu_pci_remove(struct pci_dev *pdev
  static void
  amdgpu_pci_shutdown(struct pci_dev *pdev)
  {
 +      struct drm_device *dev = pci_get_drvdata(pdev);
 +      struct amdgpu_device *adev = dev->dev_private;
 +
        /* if we are running in a VM, make sure the device
         * torn down properly on reboot/shutdown.
         * unfortunately we can't detect certain
         * hypervisors so just do this all the time.
         */
 -      amdgpu_pci_remove(pdev);
 +      amdgpu_suspend(adev);
  }
  
  static int amdgpu_pmops_suspend(struct device *dev)
index df7c18b6a02a199bc9eda3fdec4f2406f5aabdf8,e4a1697ec1d31f4d04e5995c2975c4f2ef9fb745..e4a1697ec1d31f4d04e5995c2975c4f2ef9fb745
mode 100644,100755..100644
@@@ -106,6 -106,7 +106,7 @@@ enum cgs_ucode_id 
        CGS_UCODE_ID_CP_MEC_JT2,
        CGS_UCODE_ID_GMCON_RENG,
        CGS_UCODE_ID_RLC_G,
+       CGS_UCODE_ID_STORAGE,
        CGS_UCODE_ID_MAXIMUM,
  };
  
@@@ -619,6 -620,8 +620,8 @@@ typedef int (*cgs_call_acpi_method)(str
  typedef int (*cgs_query_system_info)(struct cgs_device *cgs_device,
                                struct cgs_system_info *sys_info);
  
+ typedef int (*cgs_is_virtualization_enabled_t)(void *cgs_device);
  struct cgs_ops {
        /* memory management calls (similar to KFD interface) */
        cgs_gpu_mem_info_t gpu_mem_info;
        cgs_call_acpi_method call_acpi_method;
        /* get system info */
        cgs_query_system_info query_system_info;
+       cgs_is_virtualization_enabled_t is_virtualization_enabled;
  };
  
  struct cgs_os_ops; /* To be define in OS-specific CGS header */
@@@ -773,4 -777,6 +777,6 @@@ struct cgs_devic
        CGS_CALL(get_pci_resource, cgs_device, resource_type, size, offset, \
        resource_base)
  
+ #define cgs_is_virtualization_enabled(cgs_device) \
+               CGS_CALL(is_virtualization_enabled, cgs_device)
  #endif /* _CGS_COMMON_H */
index 02fe1df855a92b588df4faa3ac8543f64f26d357,26eff56b4a99dd0ffba3f4d35a44cce8001d296b..26eff56b4a99dd0ffba3f4d35a44cce8001d296b
mode 100644,100755..100644
@@@ -159,7 -159,7 +159,7 @@@ static int fiji_start_smu_in_non_protec
        return result;
  }
  
- int fiji_setup_pwr_virus(struct pp_smumgr *smumgr)
static int fiji_setup_pwr_virus(struct pp_smumgr *smumgr)
  {
        int i, result = -1;
        uint32_t reg, data;
@@@ -224,7 -224,7 +224,7 @@@ static int fiji_start_avfs_btc(struct p
        return result;
  }
  
- int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
static int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
  {
        int result = 0;
        uint32_t table_start;
        return result;
  }
  
- int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
static int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
  {
        int32_t vr_config;
        uint32_t table_start;
  }
  
  /* Work in Progress */
- int fiji_restore_vft_table(struct pp_smumgr *smumgr)
static int fiji_restore_vft_table(struct pp_smumgr *smumgr)
  {
        struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
  
  }
  
  /* Work in Progress */
- int fiji_save_vft_table(struct pp_smumgr *smumgr)
static int fiji_save_vft_table(struct pp_smumgr *smumgr)
  {
        struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
  
                return -EINVAL;
  }
  
- int fiji_avfs_event_mgr(struct pp_smumgr *smumgr, bool smu_started)
static int fiji_avfs_event_mgr(struct pp_smumgr *smumgr, bool smu_started)
  {
        struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
  
@@@ -396,7 -396,8 +396,8 @@@ static int fiji_start_smu(struct pp_smu
        struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
  
        /* Only start SMC if SMC RAM is not running */
-       if (!smu7_is_smc_ram_running(smumgr)) {
+       if (!(smu7_is_smc_ram_running(smumgr)
+               || cgs_is_virtualization_enabled(smumgr->device))) {
                fiji_avfs_event_mgr(smumgr, false);
  
                /* Check if SMU is running in protected mode */
@@@ -443,6 -444,9 +444,9 @@@ static bool fiji_is_hw_avfs_present(str
        uint32_t efuse = 0;
        uint32_t mask = (1 << ((AVFS_EN_MSB - AVFS_EN_LSB) + 1)) - 1;
  
+       if (cgs_is_virtualization_enabled(smumgr->device))
+               return 0;
        if (!atomctrl_read_efuse(smumgr->device, AVFS_EN_LSB, AVFS_EN_MSB,
                        mask, &efuse)) {
                if (efuse)
index 383d134164424ceb5f7ffde73dc620d1af0fc69b,57194471f8cd8f9daca75685b54ce30c60b236d2..b8f403faadbb867af596e1f3d967e1d411ed443e
   */
  
  #include <linux/prefetch.h>
+ #include <linux/dma-fence-array.h>
  
  #include "i915_drv.h"
  
- static const char *i915_fence_get_driver_name(struct fence *fence)
+ static const char *i915_fence_get_driver_name(struct dma_fence *fence)
  {
        return "i915";
  }
  
- static const char *i915_fence_get_timeline_name(struct fence *fence)
+ static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
  {
-       /* Timelines are bound by eviction to a VM. However, since
-        * we only have a global seqno at the moment, we only have
-        * a single timeline. Note that each timeline will have
-        * multiple execution contexts (fence contexts) as we allow
-        * engines within a single timeline to execute in parallel.
-        */
-       return "global";
+       return to_request(fence)->timeline->common->name;
  }
  
- static bool i915_fence_signaled(struct fence *fence)
+ static bool i915_fence_signaled(struct dma_fence *fence)
  {
        return i915_gem_request_completed(to_request(fence));
  }
  
- static bool i915_fence_enable_signaling(struct fence *fence)
+ static bool i915_fence_enable_signaling(struct dma_fence *fence)
  {
        if (i915_fence_signaled(fence))
                return false;
        return true;
  }
  
- static signed long i915_fence_wait(struct fence *fence,
+ static signed long i915_fence_wait(struct dma_fence *fence,
                                   bool interruptible,
-                                  signed long timeout_jiffies)
+                                  signed long timeout)
  {
-       s64 timeout_ns, *timeout;
-       int ret;
-       if (timeout_jiffies != MAX_SCHEDULE_TIMEOUT) {
-               timeout_ns = jiffies_to_nsecs(timeout_jiffies);
-               timeout = &timeout_ns;
-       } else {
-               timeout = NULL;
-       }
-       ret = i915_wait_request(to_request(fence),
-                               interruptible, timeout,
-                               NO_WAITBOOST);
-       if (ret == -ETIME)
-               return 0;
-       if (ret < 0)
-               return ret;
-       if (timeout_jiffies != MAX_SCHEDULE_TIMEOUT)
-               timeout_jiffies = nsecs_to_jiffies(timeout_ns);
-       return timeout_jiffies;
+       return i915_wait_request(to_request(fence), interruptible, timeout);
  }
  
- static void i915_fence_value_str(struct fence *fence, char *str, int size)
- {
-       snprintf(str, size, "%u", fence->seqno);
- }
- static void i915_fence_timeline_value_str(struct fence *fence, char *str,
-                                         int size)
- {
-       snprintf(str, size, "%u",
-                intel_engine_get_seqno(to_request(fence)->engine));
- }
- static void i915_fence_release(struct fence *fence)
+ static void i915_fence_release(struct dma_fence *fence)
  {
        struct drm_i915_gem_request *req = to_request(fence);
  
        kmem_cache_free(req->i915->requests, req);
  }
  
- const struct fence_ops i915_fence_ops = {
+ const struct dma_fence_ops i915_fence_ops = {
        .get_driver_name = i915_fence_get_driver_name,
        .get_timeline_name = i915_fence_get_timeline_name,
        .enable_signaling = i915_fence_enable_signaling,
        .signaled = i915_fence_signaled,
        .wait = i915_fence_wait,
        .release = i915_fence_release,
-       .fence_value_str = i915_fence_value_str,
-       .timeline_value_str = i915_fence_timeline_value_str,
  };
  
  int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
@@@ -154,6 -113,82 +113,82 @@@ i915_gem_request_remove_from_client(str
        spin_unlock(&file_priv->mm.lock);
  }
  
+ static struct i915_dependency *
+ i915_dependency_alloc(struct drm_i915_private *i915)
+ {
+       return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
+ }
+ static void
+ i915_dependency_free(struct drm_i915_private *i915,
+                    struct i915_dependency *dep)
+ {
+       kmem_cache_free(i915->dependencies, dep);
+ }
+ static void
+ __i915_priotree_add_dependency(struct i915_priotree *pt,
+                              struct i915_priotree *signal,
+                              struct i915_dependency *dep,
+                              unsigned long flags)
+ {
+       INIT_LIST_HEAD(&dep->dfs_link);
+       list_add(&dep->wait_link, &signal->waiters_list);
+       list_add(&dep->signal_link, &pt->signalers_list);
+       dep->signaler = signal;
+       dep->flags = flags;
+ }
+ static int
+ i915_priotree_add_dependency(struct drm_i915_private *i915,
+                            struct i915_priotree *pt,
+                            struct i915_priotree *signal)
+ {
+       struct i915_dependency *dep;
+       dep = i915_dependency_alloc(i915);
+       if (!dep)
+               return -ENOMEM;
+       __i915_priotree_add_dependency(pt, signal, dep, I915_DEPENDENCY_ALLOC);
+       return 0;
+ }
+ static void
+ i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
+ {
+       struct i915_dependency *dep, *next;
+       GEM_BUG_ON(!RB_EMPTY_NODE(&pt->node));
+       /* Everyone we depended upon (the fences we wait to be signaled)
+        * should retire before us and remove themselves from our list.
+        * However, retirement is run independently on each timeline and
+        * so we may be called out-of-order.
+        */
+       list_for_each_entry_safe(dep, next, &pt->signalers_list, signal_link) {
+               list_del(&dep->wait_link);
+               if (dep->flags & I915_DEPENDENCY_ALLOC)
+                       i915_dependency_free(i915, dep);
+       }
+       /* Remove ourselves from everyone who depends upon us */
+       list_for_each_entry_safe(dep, next, &pt->waiters_list, wait_link) {
+               list_del(&dep->signal_link);
+               if (dep->flags & I915_DEPENDENCY_ALLOC)
+                       i915_dependency_free(i915, dep);
+       }
+ }
+ static void
+ i915_priotree_init(struct i915_priotree *pt)
+ {
+       INIT_LIST_HEAD(&pt->signalers_list);
+       INIT_LIST_HEAD(&pt->waiters_list);
+       RB_CLEAR_NODE(&pt->node);
+       pt->priority = INT_MIN;
+ }
  void i915_gem_retire_noop(struct i915_gem_active *active,
                          struct drm_i915_gem_request *request)
  {
@@@ -164,8 -199,17 +199,17 @@@ static void i915_gem_request_retire(str
  {
        struct i915_gem_active *active, *next;
  
+       lockdep_assert_held(&request->i915->drm.struct_mutex);
+       GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit));
+       GEM_BUG_ON(!i915_sw_fence_signaled(&request->execute));
+       GEM_BUG_ON(!i915_gem_request_completed(request));
+       GEM_BUG_ON(!request->i915->gt.active_requests);
        trace_i915_gem_request_retire(request);
-       list_del(&request->link);
+       spin_lock_irq(&request->engine->timeline->lock);
+       list_del_init(&request->link);
+       spin_unlock_irq(&request->engine->timeline->lock);
  
        /* We know the GPU must have read the request to have
         * sent us the seqno + interrupt, so use the position
         */
        list_del(&request->ring_link);
        request->ring->last_retired_head = request->postfix;
+       if (!--request->i915->gt.active_requests) {
+               GEM_BUG_ON(!request->i915->gt.awake);
+               mod_delayed_work(request->i915->wq,
+                                &request->i915->gt.idle_work,
+                                msecs_to_jiffies(100));
+       }
  
        /* Walk through the active list, calling retire on each. This allows
         * objects to track their GPU activity and mark themselves as idle
        }
  
        i915_gem_context_put(request->ctx);
+       dma_fence_signal(&request->fence);
+       i915_priotree_fini(request->i915, &request->priotree);
        i915_gem_request_put(request);
  }
  
@@@ -223,10 -277,11 +277,11 @@@ void i915_gem_request_retire_upto(struc
        struct drm_i915_gem_request *tmp;
  
        lockdep_assert_held(&req->i915->drm.struct_mutex);
-       GEM_BUG_ON(list_empty(&req->link));
+       if (list_empty(&req->link))
+               return;
  
        do {
-               tmp = list_first_entry(&engine->request_list,
+               tmp = list_first_entry(&engine->timeline->requests,
                                       typeof(*tmp), link);
  
                i915_gem_request_retire(tmp);
@@@ -253,39 -308,50 +308,50 @@@ static int i915_gem_check_wedge(struct 
        return 0;
  }
  
- static int i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno)
+ static int i915_gem_init_global_seqno(struct drm_i915_private *i915, u32 seqno)
  {
+       struct i915_gem_timeline *timeline = &i915->gt.global_timeline;
        struct intel_engine_cs *engine;
+       enum intel_engine_id id;
        int ret;
  
        /* Carefully retire all requests without writing to the rings */
-       for_each_engine(engine, dev_priv) {
-               ret = intel_engine_idle(engine,
-                                       I915_WAIT_INTERRUPTIBLE |
-                                       I915_WAIT_LOCKED);
-               if (ret)
-                       return ret;
-       }
-       i915_gem_retire_requests(dev_priv);
+       ret = i915_gem_wait_for_idle(i915,
+                                    I915_WAIT_INTERRUPTIBLE |
+                                    I915_WAIT_LOCKED);
+       if (ret)
+               return ret;
+       i915_gem_retire_requests(i915);
+       GEM_BUG_ON(i915->gt.active_requests > 1);
  
        /* If the seqno wraps around, we need to clear the breadcrumb rbtree */
-       if (!i915_seqno_passed(seqno, dev_priv->next_seqno)) {
-               while (intel_kick_waiters(dev_priv) ||
-                      intel_kick_signalers(dev_priv))
-                       yield();
+       if (!i915_seqno_passed(seqno, atomic_read(&timeline->next_seqno))) {
+               while (intel_breadcrumbs_busy(i915))
+                       cond_resched(); /* spin until threads are complete */
        }
+       atomic_set(&timeline->next_seqno, seqno);
  
        /* Finally reset hw state */
-       for_each_engine(engine, dev_priv)
-               intel_engine_init_seqno(engine, seqno);
+       for_each_engine(engine, i915, id)
+               intel_engine_init_global_seqno(engine, seqno);
+       list_for_each_entry(timeline, &i915->gt.timelines, link) {
+               for_each_engine(engine, i915, id) {
+                       struct intel_timeline *tl = &timeline->engine[id];
+                       memset(tl->sync_seqno, 0, sizeof(tl->sync_seqno));
+               }
+       }
  
        return 0;
  }
  
- int i915_gem_set_seqno(struct drm_device *dev, u32 seqno)
+ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
  {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       int ret;
+       lockdep_assert_held(&dev_priv->drm.struct_mutex);
  
        if (seqno == 0)
                return -EINVAL;
        /* HWS page needs to be set less than what we
         * will inject to ring
         */
-       ret = i915_gem_init_seqno(dev_priv, seqno - 1);
-       if (ret)
+       return i915_gem_init_global_seqno(dev_priv, seqno - 1);
+ }
+ static int reserve_global_seqno(struct drm_i915_private *i915)
+ {
+       u32 active_requests = ++i915->gt.active_requests;
+       u32 next_seqno = atomic_read(&i915->gt.global_timeline.next_seqno);
+       int ret;
+       /* Reservation is fine until we need to wrap around */
+       if (likely(next_seqno + active_requests > next_seqno))
+               return 0;
+       ret = i915_gem_init_global_seqno(i915, 0);
+       if (ret) {
+               i915->gt.active_requests--;
                return ret;
+       }
  
-       dev_priv->next_seqno = seqno;
        return 0;
  }
  
- static int i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno)
+ static u32 __timeline_get_seqno(struct i915_gem_timeline *tl)
  {
-       /* reserve 0 for non-seqno */
-       if (unlikely(dev_priv->next_seqno == 0)) {
-               int ret;
+       /* next_seqno only incremented under a mutex */
+       return ++tl->next_seqno.counter;
+ }
  
-               ret = i915_gem_init_seqno(dev_priv, 0);
-               if (ret)
-                       return ret;
+ static u32 timeline_get_seqno(struct i915_gem_timeline *tl)
+ {
+       return atomic_inc_return(&tl->next_seqno);
+ }
  
-               dev_priv->next_seqno = 1;
-       }
+ void __i915_gem_request_submit(struct drm_i915_gem_request *request)
+ {
+       struct intel_engine_cs *engine = request->engine;
+       struct intel_timeline *timeline;
+       u32 seqno;
  
-       *seqno = dev_priv->next_seqno++;
-       return 0;
+       /* Transfer from per-context onto the global per-engine timeline */
+       timeline = engine->timeline;
+       GEM_BUG_ON(timeline == request->timeline);
+       assert_spin_locked(&timeline->lock);
+       seqno = timeline_get_seqno(timeline->common);
+       GEM_BUG_ON(!seqno);
+       GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
+       GEM_BUG_ON(i915_seqno_passed(timeline->last_submitted_seqno, seqno));
+       request->previous_seqno = timeline->last_submitted_seqno;
+       timeline->last_submitted_seqno = seqno;
+       /* We may be recursing from the signal callback of another i915 fence */
+       spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
+       request->global_seqno = seqno;
+       if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
+               intel_engine_enable_signaling(request);
+       spin_unlock(&request->lock);
+       GEM_BUG_ON(!request->global_seqno);
+       engine->emit_breadcrumb(request,
+                               request->ring->vaddr + request->postfix);
+       spin_lock(&request->timeline->lock);
+       list_move_tail(&request->link, &timeline->requests);
+       spin_unlock(&request->timeline->lock);
+       i915_sw_fence_commit(&request->execute);
+ }
+ void i915_gem_request_submit(struct drm_i915_gem_request *request)
+ {
+       struct intel_engine_cs *engine = request->engine;
+       unsigned long flags;
+       /* Will be called from irq-context when using foreign fences. */
+       spin_lock_irqsave(&engine->timeline->lock, flags);
+       __i915_gem_request_submit(request);
+       spin_unlock_irqrestore(&engine->timeline->lock, flags);
  }
  
  static int __i915_sw_fence_call
@@@ -324,15 -448,31 +448,31 @@@ submit_notify(struct i915_sw_fence *fen
        struct drm_i915_gem_request *request =
                container_of(fence, typeof(*request), submit);
  
-       /* Will be called from irq-context when using foreign DMA fences */
        switch (state) {
        case FENCE_COMPLETE:
-               request->engine->last_submitted_seqno = request->fence.seqno;
                request->engine->submit_request(request);
                break;
  
        case FENCE_FREE:
+               i915_gem_request_put(request);
+               break;
+       }
+       return NOTIFY_DONE;
+ }
+ static int __i915_sw_fence_call
+ execute_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
+ {
+       struct drm_i915_gem_request *request =
+               container_of(fence, typeof(*request), execute);
+       switch (state) {
+       case FENCE_COMPLETE:
+               break;
+       case FENCE_FREE:
+               i915_gem_request_put(request);
                break;
        }
  
@@@ -357,9 -497,10 +497,10 @@@ i915_gem_request_alloc(struct intel_eng
  {
        struct drm_i915_private *dev_priv = engine->i915;
        struct drm_i915_gem_request *req;
-       u32 seqno;
        int ret;
  
+       lockdep_assert_held(&dev_priv->drm.struct_mutex);
        /* ABI: Before userspace accesses the GPU (e.g. execbuffer), report
         * EIO if the GPU is already wedged, or EAGAIN to drop the struct_mutex
         * and restart.
        if (ret)
                return ERR_PTR(ret);
  
+       ret = reserve_global_seqno(dev_priv);
+       if (ret)
+               return ERR_PTR(ret);
        /* Move the oldest request to the slab-cache (if not in use!) */
-       req = list_first_entry_or_null(&engine->request_list,
+       req = list_first_entry_or_null(&engine->timeline->requests,
                                       typeof(*req), link);
-       if (req && i915_gem_request_completed(req))
+       if (req && __i915_gem_request_completed(req))
                i915_gem_request_retire(req);
  
        /* Beware: Dragons be flying overhead.
         * of being read by __i915_gem_active_get_rcu(). As such,
         * we have to be very careful when overwriting the contents. During
         * the RCU lookup, we change chase the request->engine pointer,
-        * read the request->fence.seqno and increment the reference count.
+        * read the request->global_seqno and increment the reference count.
         *
         * The reference count is incremented atomically. If it is zero,
         * the lookup knows the request is unallocated and complete. Otherwise,
         * it is either still in use, or has been reallocated and reset
-        * with fence_init(). This increment is safe for release as we check
-        * that the request we have a reference to and matches the active
+        * with dma_fence_init(). This increment is safe for release as we
+        * check that the request we have a reference to and matches the active
         * request.
         *
         * Before we increment the refcount, we chase the request->engine
         * Do not use kmem_cache_zalloc() here!
         */
        req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL);
-       if (!req)
-               return ERR_PTR(-ENOMEM);
+       if (!req) {
+               ret = -ENOMEM;
+               goto err_unreserve;
+       }
  
-       ret = i915_gem_get_seqno(dev_priv, &seqno);
-       if (ret)
-               goto err;
+       req->timeline = i915_gem_context_lookup_timeline(ctx, engine);
+       GEM_BUG_ON(req->timeline == engine->timeline);
  
        spin_lock_init(&req->lock);
-       fence_init(&req->fence,
-                  &i915_fence_ops,
-                  &req->lock,
-                  engine->fence_context,
-                  seqno);
+       dma_fence_init(&req->fence,
+                      &i915_fence_ops,
+                      &req->lock,
+                      req->timeline->fence_context,
+                      __timeline_get_seqno(req->timeline->common));
+       /* We bump the ref for the fence chain */
+       i915_sw_fence_init(&i915_gem_request_get(req)->submit, submit_notify);
+       i915_sw_fence_init(&i915_gem_request_get(req)->execute, execute_notify);
+       /* Ensure that the execute fence completes after the submit fence -
+        * as we complete the execute fence from within the submit fence
+        * callback, its completion would otherwise be visible first.
+        */
+       i915_sw_fence_await_sw_fence(&req->execute, &req->submit, &req->execq);
  
-       i915_sw_fence_init(&req->submit, submit_notify);
+       i915_priotree_init(&req->priotree);
  
        INIT_LIST_HEAD(&req->active_list);
        req->i915 = dev_priv;
        req->ctx = i915_gem_context_get(ctx);
  
        /* No zalloc, must clear what we need by hand */
+       req->global_seqno = 0;
        req->previous_context = NULL;
        req->file_priv = NULL;
        req->batch = NULL;
         * away, e.g. because a GPU scheduler has deferred it.
         */
        req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
+       GEM_BUG_ON(req->reserved_space < engine->emit_breadcrumb_sz);
  
        if (i915.enable_execlists)
                ret = intel_logical_ring_alloc_request_extras(req);
  
  err_ctx:
        i915_gem_context_put(ctx);
- err:
        kmem_cache_free(dev_priv->requests, req);
+ err_unreserve:
+       dev_priv->gt.active_requests--;
        return ERR_PTR(ret);
  }
  
@@@ -465,15 -624,36 +624,36 @@@ static in
  i915_gem_request_await_request(struct drm_i915_gem_request *to,
                               struct drm_i915_gem_request *from)
  {
-       int idx, ret;
+       int ret;
  
        GEM_BUG_ON(to == from);
  
-       if (to->engine == from->engine)
+       if (to->engine->schedule) {
+               ret = i915_priotree_add_dependency(to->i915,
+                                                  &to->priotree,
+                                                  &from->priotree);
+               if (ret < 0)
+                       return ret;
+       }
+       if (to->timeline == from->timeline)
                return 0;
  
-       idx = intel_engine_sync_index(from->engine, to->engine);
-       if (from->fence.seqno <= from->engine->semaphore.sync_seqno[idx])
+       if (to->engine == from->engine) {
+               ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
+                                                      &from->submit,
+                                                      GFP_KERNEL);
+               return ret < 0 ? ret : 0;
+       }
+       if (!from->global_seqno) {
+               ret = i915_sw_fence_await_dma_fence(&to->submit,
+                                                   &from->fence, 0,
+                                                   GFP_KERNEL);
+               return ret < 0 ? ret : 0;
+       }
+       if (from->global_seqno <= to->timeline->sync_seqno[from->engine->id])
                return 0;
  
        trace_i915_gem_ring_sync_to(to, from);
                        return ret;
        }
  
-       from->engine->semaphore.sync_seqno[idx] = from->fence.seqno;
+       to->timeline->sync_seqno[from->engine->id] = from->global_seqno;
+       return 0;
+ }
+ int
+ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
+                                struct dma_fence *fence)
+ {
+       struct dma_fence_array *array;
+       int ret;
+       int i;
+       if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+               return 0;
+       if (dma_fence_is_i915(fence))
+               return i915_gem_request_await_request(req, to_request(fence));
+       if (!dma_fence_is_array(fence)) {
+               ret = i915_sw_fence_await_dma_fence(&req->submit,
+                                                   fence, I915_FENCE_TIMEOUT,
+                                                   GFP_KERNEL);
+               return ret < 0 ? ret : 0;
+       }
+       /* Note that if the fence-array was created in signal-on-any mode,
+        * we should *not* decompose it into its individual fences. However,
+        * we don't currently store which mode the fence-array is operating
+        * in. Fortunately, the only user of signal-on-any is private to
+        * amdgpu and we should not see any incoming fence-array from
+        * sync-file being in signal-on-any mode.
+        */
+       array = to_dma_fence_array(fence);
+       for (i = 0; i < array->num_fences; i++) {
+               struct dma_fence *child = array->fences[i];
+               if (dma_fence_is_i915(child))
+                       ret = i915_gem_request_await_request(req,
+                                                            to_request(child));
+               else
+                       ret = i915_sw_fence_await_dma_fence(&req->submit,
+                                                           child, I915_FENCE_TIMEOUT,
+                                                           GFP_KERNEL);
+               if (ret < 0)
+                       return ret;
+       }
        return 0;
  }
  
@@@ -520,43 -747,52 +747,52 @@@ i915_gem_request_await_object(struct dr
                              struct drm_i915_gem_object *obj,
                              bool write)
  {
-       struct i915_gem_active *active;
-       unsigned long active_mask;
-       int idx;
+       struct dma_fence *excl;
+       int ret = 0;
  
        if (write) {
-               active_mask = i915_gem_object_get_active(obj);
-               active = obj->last_read;
+               struct dma_fence **shared;
+               unsigned int count, i;
+               ret = reservation_object_get_fences_rcu(obj->resv,
+                                                       &excl, &count, &shared);
+               if (ret)
+                       return ret;
+               for (i = 0; i < count; i++) {
+                       ret = i915_gem_request_await_dma_fence(to, shared[i]);
+                       if (ret)
+                               break;
+                       dma_fence_put(shared[i]);
+               }
+               for (; i < count; i++)
+                       dma_fence_put(shared[i]);
+               kfree(shared);
        } else {
-               active_mask = 1;
-               active = &obj->last_write;
+               excl = reservation_object_get_excl_rcu(obj->resv);
        }
  
-       for_each_active(active_mask, idx) {
-               struct drm_i915_gem_request *request;
-               int ret;
-               request = i915_gem_active_peek(&active[idx],
-                                              &obj->base.dev->struct_mutex);
-               if (!request)
-                       continue;
+       if (excl) {
+               if (ret == 0)
+                       ret = i915_gem_request_await_dma_fence(to, excl);
  
-               ret = i915_gem_request_await_request(to, request);
-               if (ret)
-                       return ret;
+               dma_fence_put(excl);
        }
  
-       return 0;
+       return ret;
  }
  
  static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
  {
        struct drm_i915_private *dev_priv = engine->i915;
  
-       dev_priv->gt.active_engines |= intel_engine_flag(engine);
        if (dev_priv->gt.awake)
                return;
  
+       GEM_BUG_ON(!dev_priv->gt.active_requests);
        intel_runtime_pm_get_noresume(dev_priv);
        dev_priv->gt.awake = true;
  
@@@ -579,11 -815,11 +815,11 @@@ void __i915_add_request(struct drm_i915
  {
        struct intel_engine_cs *engine = request->engine;
        struct intel_ring *ring = request->ring;
+       struct intel_timeline *timeline = request->timeline;
        struct drm_i915_gem_request *prev;
-       u32 request_start;
-       u32 reserved_tail;
-       int ret;
+       int err;
  
+       lockdep_assert_held(&request->i915->drm.struct_mutex);
        trace_i915_gem_request_add(request);
  
        /*
         * should already have been reserved in the ring buffer. Let the ring
         * know that it is time to use that space up.
         */
-       request_start = ring->tail;
-       reserved_tail = request->reserved_space;
        request->reserved_space = 0;
  
        /*
         * what.
         */
        if (flush_caches) {
-               ret = engine->emit_flush(request, EMIT_FLUSH);
+               err = engine->emit_flush(request, EMIT_FLUSH);
  
                /* Not allowed to fail! */
-               WARN(ret, "engine->emit_flush() failed: %d!\n", ret);
+               WARN(err, "engine->emit_flush() failed: %d!\n", err);
        }
  
        /* Record the position of the start of the breadcrumb so that
         * GPU processing the request, we never over-estimate the
         * position of the ring's HEAD.
         */
+       err = intel_ring_begin(request, engine->emit_breadcrumb_sz);
+       GEM_BUG_ON(err);
        request->postfix = ring->tail;
-       /* Not allowed to fail! */
-       ret = engine->emit_request(request);
-       WARN(ret, "(%s)->emit_request failed: %d!\n", engine->name, ret);
-       /* Sanity check that the reserved size was large enough. */
-       ret = ring->tail - request_start;
-       if (ret < 0)
-               ret += ring->size;
-       WARN_ONCE(ret > reserved_tail,
-                 "Not enough space reserved (%d bytes) "
-                 "for adding the request (%d bytes)\n",
-                 reserved_tail, ret);
+       ring->tail += engine->emit_breadcrumb_sz * sizeof(u32);
  
        /* Seal the request and mark it as pending execution. Note that
         * we may inspect this state, without holding any locks, during
         * see a more recent value in the hws than we are tracking.
         */
  
-       prev = i915_gem_active_raw(&engine->last_request,
+       prev = i915_gem_active_raw(&timeline->last_request,
                                   &request->i915->drm.struct_mutex);
-       if (prev)
+       if (prev) {
                i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
                                             &request->submitq);
+               if (engine->schedule)
+                       __i915_priotree_add_dependency(&request->priotree,
+                                                      &prev->priotree,
+                                                      &request->dep,
+                                                      0);
+       }
+       spin_lock_irq(&timeline->lock);
+       list_add_tail(&request->link, &timeline->requests);
+       spin_unlock_irq(&timeline->lock);
+       GEM_BUG_ON(i915_seqno_passed(timeline->last_submitted_seqno,
+                                    request->fence.seqno));
+       timeline->last_submitted_seqno = request->fence.seqno;
+       i915_gem_active_set(&timeline->last_request, request);
  
-       request->emitted_jiffies = jiffies;
-       request->previous_seqno = engine->last_pending_seqno;
-       engine->last_pending_seqno = request->fence.seqno;
-       i915_gem_active_set(&engine->last_request, request);
-       list_add_tail(&request->link, &engine->request_list);
        list_add_tail(&request->ring_link, &ring->request_list);
+       request->emitted_jiffies = jiffies;
  
        i915_gem_mark_busy(engine);
  
+       /* Let the backend know a new request has arrived that may need
+        * to adjust the existing execution schedule due to a high priority
+        * request - i.e. we may want to preempt the current request in order
+        * to run a high priority dependency chain *before* we can execute this
+        * request.
+        *
+        * This is called before the request is ready to run so that we can
+        * decide whether to preempt the entire chain so that it is ready to
+        * run at the earliest possible convenience.
+        */
+       if (engine->schedule)
+               engine->schedule(request, request->ctx->priority);
        local_bh_disable();
        i915_sw_fence_commit(&request->submit);
        local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
@@@ -714,7 -963,7 +963,7 @@@ bool __i915_spin_request(const struct d
  
        timeout_us += local_clock_us(&cpu);
        do {
-               if (i915_gem_request_completed(req))
+               if (__i915_gem_request_completed(req))
                        return true;
  
                if (signal_pending_state(state, current))
                if (busywait_stop(timeout_us, cpu))
                        break;
  
 -              cpu_relax_lowlatency();
 +              cpu_relax();
        } while (!need_resched());
  
        return false;
  }
  
+ static long
+ __i915_request_wait_for_execute(struct drm_i915_gem_request *request,
+                               unsigned int flags,
+                               long timeout)
+ {
+       const int state = flags & I915_WAIT_INTERRUPTIBLE ?
+               TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+       wait_queue_head_t *q = &request->i915->gpu_error.wait_queue;
+       DEFINE_WAIT(reset);
+       DEFINE_WAIT(wait);
+       if (flags & I915_WAIT_LOCKED)
+               add_wait_queue(q, &reset);
+       do {
+               prepare_to_wait(&request->execute.wait, &wait, state);
+               if (i915_sw_fence_done(&request->execute))
+                       break;
+               if (flags & I915_WAIT_LOCKED &&
+                   i915_reset_in_progress(&request->i915->gpu_error)) {
+                       __set_current_state(TASK_RUNNING);
+                       i915_reset(request->i915);
+                       reset_wait_queue(q, &reset);
+                       continue;
+               }
+               if (signal_pending_state(state, current)) {
+                       timeout = -ERESTARTSYS;
+                       break;
+               }
+               timeout = io_schedule_timeout(timeout);
+       } while (timeout);
+       finish_wait(&request->execute.wait, &wait);
+       if (flags & I915_WAIT_LOCKED)
+               remove_wait_queue(q, &reset);
+       return timeout;
+ }
  /**
   * i915_wait_request - wait until execution of request has finished
-  * @req: duh!
+  * @req: the request to wait upon
   * @flags: how to wait
-  * @timeout: in - how long to wait (NULL forever); out - how much time remaining
-  * @rps: client to charge for RPS boosting
+  * @timeout: how long to wait in jiffies
+  *
+  * i915_wait_request() waits for the request to be completed, for a
+  * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
+  * unbounded wait).
   *
-  * Note: It is of utmost importance that the passed in seqno and reset_counter
-  * values have been read by the caller in an smp safe manner. Where read-side
-  * locks are involved, it is sufficient to read the reset_counter before
-  * unlocking the lock that protects the seqno. For lockless tricks, the
-  * reset_counter _must_ be read before, and an appropriate smp_rmb must be
-  * inserted.
+  * If the caller holds the struct_mutex, the caller must pass I915_WAIT_LOCKED
+  * in via the flags, and vice versa if the struct_mutex is not held, the caller
+  * must not specify that the wait is locked.
   *
-  * Returns 0 if the request was found within the alloted time. Else returns the
-  * errno with remaining time filled in timeout argument.
+  * Returns the remaining time (in jiffies) if the request completed, which may
+  * be zero or -ETIME if the request is unfinished after the timeout expires.
+  * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
+  * pending before the request completes.
   */
- int i915_wait_request(struct drm_i915_gem_request *req,
-                     unsigned int flags,
-                     s64 *timeout,
-                     struct intel_rps_client *rps)
+ long i915_wait_request(struct drm_i915_gem_request *req,
+                      unsigned int flags,
+                      long timeout)
  {
        const int state = flags & I915_WAIT_INTERRUPTIBLE ?
                TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
        DEFINE_WAIT(reset);
        struct intel_wait wait;
-       unsigned long timeout_remain;
-       int ret = 0;
  
        might_sleep();
  #if IS_ENABLED(CONFIG_LOCKDEP)
-       GEM_BUG_ON(!!lockdep_is_held(&req->i915->drm.struct_mutex) !=
+       GEM_BUG_ON(debug_locks &&
+                  !!lockdep_is_held(&req->i915->drm.struct_mutex) !=
                   !!(flags & I915_WAIT_LOCKED));
  #endif
+       GEM_BUG_ON(timeout < 0);
  
        if (i915_gem_request_completed(req))
-               return 0;
-       timeout_remain = MAX_SCHEDULE_TIMEOUT;
-       if (timeout) {
-               if (WARN_ON(*timeout < 0))
-                       return -EINVAL;
+               return timeout;
  
-               if (*timeout == 0)
-                       return -ETIME;
-               /* Record current time in case interrupted, or wedged */
-               timeout_remain = nsecs_to_jiffies_timeout(*timeout);
-               *timeout += ktime_get_raw_ns();
-       }
+       if (!timeout)
+               return -ETIME;
  
        trace_i915_gem_request_wait_begin(req);
  
-       /* This client is about to stall waiting for the GPU. In many cases
-        * this is undesirable and limits the throughput of the system, as
-        * many clients cannot continue processing user input/output whilst
-        * blocked. RPS autotuning may take tens of milliseconds to respond
-        * to the GPU load and thus incurs additional latency for the client.
-        * We can circumvent that by promoting the GPU frequency to maximum
-        * before we wait. This makes the GPU throttle up much more quickly
-        * (good for benchmarks and user experience, e.g. window animations),
-        * but at a cost of spending more power processing the workload
-        * (bad for battery). Not all clients even want their results
-        * immediately and for them we should just let the GPU select its own
-        * frequency to maximise efficiency. To prevent a single client from
-        * forcing the clocks too high for the whole system, we only allow
-        * each client to waitboost once in a busy period.
-        */
-       if (IS_RPS_CLIENT(rps) && INTEL_GEN(req->i915) >= 6)
-               gen6_rps_boost(req->i915, rps, req->emitted_jiffies);
+       if (!i915_sw_fence_done(&req->execute)) {
+               timeout = __i915_request_wait_for_execute(req, flags, timeout);
+               if (timeout < 0)
+                       goto complete;
+               GEM_BUG_ON(!i915_sw_fence_done(&req->execute));
+       }
+       GEM_BUG_ON(!i915_sw_fence_done(&req->submit));
+       GEM_BUG_ON(!req->global_seqno);
  
        /* Optimistic short spin before touching IRQs */
        if (i915_spin_request(req, state, 5))
        if (flags & I915_WAIT_LOCKED)
                add_wait_queue(&req->i915->gpu_error.wait_queue, &reset);
  
-       intel_wait_init(&wait, req->fence.seqno);
+       intel_wait_init(&wait, req->global_seqno);
        if (intel_engine_add_wait(req->engine, &wait))
                /* In order to check that we haven't missed the interrupt
                 * as we enabled it, we need to kick ourselves to do a
  
        for (;;) {
                if (signal_pending_state(state, current)) {
-                       ret = -ERESTARTSYS;
+                       timeout = -ERESTARTSYS;
                        break;
                }
  
-               timeout_remain = io_schedule_timeout(timeout_remain);
-               if (timeout_remain == 0) {
-                       ret = -ETIME;
+               if (!timeout) {
+                       timeout = -ETIME;
                        break;
                }
  
+               timeout = io_schedule_timeout(timeout);
                if (intel_wait_complete(&wait))
                        break;
  
@@@ -874,74 -1150,32 +1150,32 @@@ wakeup
  complete:
        trace_i915_gem_request_wait_end(req);
  
-       if (timeout) {
-               *timeout -= ktime_get_raw_ns();
-               if (*timeout < 0)
-                       *timeout = 0;
-               /*
-                * Apparently ktime isn't accurate enough and occasionally has a
-                * bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch
-                * things up to make the test happy. We allow up to 1 jiffy.
-                *
-                * This is a regrssion from the timespec->ktime conversion.
-                */
-               if (ret == -ETIME && *timeout < jiffies_to_usecs(1)*1000)
-                       *timeout = 0;
-       }
-       if (IS_RPS_USER(rps) &&
-           req->fence.seqno == req->engine->last_submitted_seqno) {
-               /* The GPU is now idle and this client has stalled.
-                * Since no other client has submitted a request in the
-                * meantime, assume that this client is the only one
-                * supplying work to the GPU but is unable to keep that
-                * work supplied because it is waiting. Since the GPU is
-                * then never kept fully busy, RPS autoclocking will
-                * keep the clocks relatively low, causing further delays.
-                * Compensate by giving the synchronous client credit for
-                * a waitboost next time.
-                */
-               spin_lock(&req->i915->rps.client_lock);
-               list_del_init(&rps->link);
-               spin_unlock(&req->i915->rps.client_lock);
-       }
-       return ret;
+       return timeout;
  }
  
- static bool engine_retire_requests(struct intel_engine_cs *engine)
+ static void engine_retire_requests(struct intel_engine_cs *engine)
  {
        struct drm_i915_gem_request *request, *next;
  
-       list_for_each_entry_safe(request, next, &engine->request_list, link) {
-               if (!i915_gem_request_completed(request))
-                       return false;
+       list_for_each_entry_safe(request, next,
+                                &engine->timeline->requests, link) {
+               if (!__i915_gem_request_completed(request))
+                       return;
  
                i915_gem_request_retire(request);
        }
-       return true;
  }
  
  void i915_gem_retire_requests(struct drm_i915_private *dev_priv)
  {
        struct intel_engine_cs *engine;
-       unsigned int tmp;
+       enum intel_engine_id id;
  
        lockdep_assert_held(&dev_priv->drm.struct_mutex);
  
-       if (dev_priv->gt.active_engines == 0)
+       if (!dev_priv->gt.active_requests)
                return;
  
-       GEM_BUG_ON(!dev_priv->gt.awake);
-       for_each_engine_masked(engine, dev_priv, dev_priv->gt.active_engines, tmp)
-               if (engine_retire_requests(engine))
-                       dev_priv->gt.active_engines &= ~intel_engine_flag(engine);
-       if (dev_priv->gt.active_engines == 0)
-               queue_delayed_work(dev_priv->wq,
-                                  &dev_priv->gt.idle_work,
-                                  msecs_to_jiffies(100));
+       for_each_engine(engine, dev_priv, id)
+               engine_retire_requests(engine);
  }
index c450076d2f9bc39c640702ff7a39405d752a7e40,a6fc1bdc48af9a332ed2f5d6d7c95544c17000c2..401006b4c6a36bf2a8058c2b47eb38105ab5baf4
  #include "i915_drv.h"
  #include "i915_trace.h"
  
 -static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
++static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock)
+ {
 -      if (!mutex_is_locked(mutex))
++      switch (mutex_trylock_recursive(&dev->struct_mutex)) {
++      case MUTEX_TRYLOCK_FAILED:
+               return false;
 -#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
 -      return mutex->owner == task;
 -#else
 -      /* Since UP may be pre-empted, we cannot assume that we own the lock */
 -      return false;
 -#endif
 -}
 -
 -static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock)
 -{
 -      if (!mutex_trylock(&dev->struct_mutex)) {
 -              if (!mutex_is_locked_by(&dev->struct_mutex, current))
 -                      return false;
++      case MUTEX_TRYLOCK_SUCCESS:
++              *unlock = true;
++              return true;
++      case MUTEX_TRYLOCK_RECURSIVE:
+               *unlock = false;
 -      } else {
 -              *unlock = true;
++              return true;
+       }
 -      return true;
++      BUG();
+ }
  static bool any_vma_pinned(struct drm_i915_gem_object *obj)
  {
        struct i915_vma *vma;
@@@ -53,8 -80,11 +71,11 @@@ static bool swap_available(void
  
  static bool can_release_pages(struct drm_i915_gem_object *obj)
  {
-       /* Only shmemfs objects are backed by swap */
-       if (!obj->base.filp)
+       if (!obj->mm.pages)
+               return false;
+       /* Consider only shrinkable ojects. */
+       if (!i915_gem_object_is_shrinkable(obj))
                return false;
  
        /* Only report true if by unbinding the object and putting its pages
@@@ -65,7 -95,7 +86,7 @@@
         * to the GPU, simply unbinding from the GPU is not going to succeed
         * in releasing our pin count on the pages themselves.
         */
-       if (obj->pages_pin_count > obj->bind_count)
+       if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
                return false;
  
        if (any_vma_pinned(obj))
         * discard the contents (because the user has marked them as being
         * purgeable) or if we can move their contents out to swap.
         */
-       return swap_available() || obj->madv == I915_MADV_DONTNEED;
+       return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
+ }
+ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj)
+ {
+       if (i915_gem_object_unbind(obj) == 0)
+               __i915_gem_object_put_pages(obj, I915_MM_SHRINKER);
+       return !READ_ONCE(obj->mm.pages);
  }
  
  /**
@@@ -115,6 -152,10 +143,10 @@@ i915_gem_shrink(struct drm_i915_privat
                { NULL, 0 },
        }, *phase;
        unsigned long count = 0;
+       bool unlock;
+       if (!i915_gem_shrinker_lock(&dev_priv->drm, &unlock))
+               return 0;
  
        trace_i915_gem_shrink(dev_priv, target, flags);
        i915_gem_retire_requests(dev_priv);
                while (count < target &&
                       (obj = list_first_entry_or_null(phase->list,
                                                       typeof(*obj),
-                                                      global_list))) {
-                       list_move_tail(&obj->global_list, &still_in_list);
+                                                      global_link))) {
+                       list_move_tail(&obj->global_link, &still_in_list);
+                       if (!obj->mm.pages) {
+                               list_del_init(&obj->global_link);
+                               continue;
+                       }
  
                        if (flags & I915_SHRINK_PURGEABLE &&
-                           obj->madv != I915_MADV_DONTNEED)
+                           obj->mm.madv != I915_MADV_DONTNEED)
                                continue;
  
                        if (flags & I915_SHRINK_VMAPS &&
-                           !is_vmalloc_addr(obj->mapping))
+                           !is_vmalloc_addr(obj->mm.mapping))
                                continue;
  
-                       if ((flags & I915_SHRINK_ACTIVE) == 0 &&
-                           i915_gem_object_is_active(obj))
+                       if (!(flags & I915_SHRINK_ACTIVE) &&
+                           (i915_gem_object_is_active(obj) ||
+                            obj->framebuffer_references))
                                continue;
  
                        if (!can_release_pages(obj))
                                continue;
  
-                       i915_gem_object_get(obj);
-                       /* For the unbound phase, this should be a no-op! */
-                       i915_gem_object_unbind(obj);
-                       if (i915_gem_object_put_pages(obj) == 0)
-                               count += obj->base.size >> PAGE_SHIFT;
-                       i915_gem_object_put(obj);
+                       if (unsafe_drop_pages(obj)) {
+                               /* May arrive from get_pages on another bo */
+                               mutex_lock_nested(&obj->mm.lock,
+                                                 I915_MM_SHRINKER);
+                               if (!obj->mm.pages) {
+                                       __i915_gem_object_invalidate(obj);
+                                       list_del_init(&obj->global_link);
+                                       count += obj->base.size >> PAGE_SHIFT;
+                               }
+                               mutex_unlock(&obj->mm.lock);
+                       }
                }
-               list_splice(&still_in_list, phase->list);
+               list_splice_tail(&still_in_list, phase->list);
        }
  
        if (flags & I915_SHRINK_BOUND)
                intel_runtime_pm_put(dev_priv);
  
        i915_gem_retire_requests(dev_priv);
+       if (unlock)
+               mutex_unlock(&dev_priv->drm.struct_mutex);
        /* expedite the RCU grace period to free some request slabs */
        synchronize_rcu_expedited();
  
@@@ -225,24 -277,6 +268,6 @@@ unsigned long i915_gem_shrink_all(struc
        return freed;
  }
  
- static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock)
- {
-       switch (mutex_trylock_recursive(&dev->struct_mutex)) {
-       case MUTEX_TRYLOCK_FAILED:
-               return false;
-       case MUTEX_TRYLOCK_SUCCESS:
-               *unlock = true;
-               return true;
-       case MUTEX_TRYLOCK_RECURSIVE:
-               *unlock = false;
-               return true;
-       }
-       BUG();
- }
  static unsigned long
  i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
  {
        i915_gem_retire_requests(dev_priv);
  
        count = 0;
-       list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
+       list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link)
                if (can_release_pages(obj))
                        count += obj->base.size >> PAGE_SHIFT;
  
-       list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+       list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) {
                if (!i915_gem_object_is_active(obj) && can_release_pages(obj))
                        count += obj->base.size >> PAGE_SHIFT;
        }
@@@ -364,13 -398,19 +389,19 @@@ i915_gem_shrinker_oom(struct notifier_b
         * being pointed to by hardware.
         */
        unbound = bound = unevictable = 0;
-       list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
+       list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) {
+               if (!obj->mm.pages)
+                       continue;
                if (!can_release_pages(obj))
                        unevictable += obj->base.size >> PAGE_SHIFT;
                else
                        unbound += obj->base.size >> PAGE_SHIFT;
        }
-       list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+       list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) {
+               if (!obj->mm.pages)
+                       continue;
                if (!can_release_pages(obj))
                        unevictable += obj->base.size >> PAGE_SHIFT;
                else