]> Git Repo - linux.git/commitdiff
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <[email protected]>
Mon, 23 May 2016 18:48:48 +0000 (11:48 -0700)
committerLinus Torvalds <[email protected]>
Mon, 23 May 2016 18:48:48 +0000 (11:48 -0700)
Pull drm updates from Dave Airlie:
 "Here's the main drm pull request for 4.7, it's been a busy one, and
  I've been a bit more distracted in real life this merge window.  Lots
  more ARM drivers, not sure if it'll ever end.  I think I've at least
  one more coming the next merge window.

  But changes are all over the place, support for AMD Polaris GPUs is in
  here, some missing GM108 support for nouveau (found in some Lenovos),
  a bunch of MST and skylake fixes.

  I've also noticed a few fixes from Arnd in my inbox, that I'll try and
  get in asap, but I didn't think they should hold this up.

  New drivers:
   - Hisilicon kirin display driver
   - Mediatek MT8173 display driver
   - ARC PGU - bitstreamer on Synopsys ARC SDP boards
   - Allwinner A13 initial RGB output driver
   - Analogix driver for DisplayPort IP found in exynos and rockchip

  DRM Core:
   - UAPI headers fixes and C++ safety
   - DRM connector reference counting
   - DisplayID mode parsing for Dell 5K monitors
   - Removal of struct_mutex from drivers
   - Connector registration cleanups
   - MST robustness fixes
   - MAINTAINERS updates
   - Lockless GEM object freeing
   - Generic fbdev deferred IO support

  panel:
   - Support for a bunch of new panels

  i915:
   - VBT refactoring
   - PLL computation cleanups
   - DSI support for BXT
   - Color manager support
   - More atomic patches
   - GEM improvements
   - GuC fw loading fixes
   - DP detection fixes
   - SKL GPU hang fixes
   - Lots of BXT fixes

  radeon/amdgpu:
   - Initial Polaris support
   - GPUVM/Scheduler/Clock/Power improvements
   - ASYNC pageflip support
   - New mesa feature support

  nouveau:
   - GM108 support
   - Power sensor support improvements
   - GR init + ucode fixes.
   - Use GPU provided topology information

  vmwgfx:
   - Add host messaging support

  gma500:
   - Some cleanups and fixes

  atmel:
   - Bridge support
   - Async atomic commit support

  fsl-dcu:
   - Timing controller for LCD support
   - Pixel clock polarity support

  rcar-du:
   - Misc fixes

  exynos:
   - Pipeline clock support
   - Exynoss4533 SoC support
   - HW trigger mode support
   - export HDMI_PHY clock
   - DECON5433 fixes
   - Use generic prime functions
   - use DMA mapping APIs

  rockchip:
   - Lots of little fixes

  vc4:
   - Render node support
   - Gamma ramp support
   - DPI output support

  msm:
   - Mostly cleanups and fixes
   - Conversion to generic struct fence

  etnaviv:
   - Fix for prime buffer handling
   - Allow hangcheck to be coalesced with other wakeups

  tegra:
   - Gamme table size fix"

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (1050 commits)
  drm/edid: add displayid detailed 1 timings to the modelist. (v1.1)
  drm/edid: move displayid validation to it's own function.
  drm/displayid: Iterate over all DisplayID blocks
  drm/edid: move displayid tiled block parsing into separate function.
  drm: Nuke ->vblank_disable_allowed
  drm/vmwgfx: Report vmwgfx version to vmware.log
  drm/vmwgfx: Add VMWare host messaging capability
  drm/vmwgfx: Kill some lockdep warnings
  drm/nouveau/gr/gf100-: fix race condition in fecs/gpccs ucode
  drm/nouveau/core: recognise GM108 chipsets
  drm/nouveau/gr/gm107-: fix touching non-existent ppcs in attrib cb setup
  drm/nouveau/gr/gk104-: share implementation of ppc exception init
  drm/nouveau/gr/gk104-: move rop_active_fbps init to nonctx
  drm/nouveau/bios/pll: check BIT table version before trying to parse it
  drm/nouveau/bios/pll: prevent oops when limits table can't be parsed
  drm/nouveau/volt/gk104: round up in gk104_volt_set
  drm/nouveau/fb/gm200: setup mmu debug buffer registers at init()
  drm/nouveau/fb/gk20a,gm20b: setup mmu debug buffer registers at init()
  drm/nouveau/fb/gf100-: allocate mmu debug buffers
  drm/nouveau/fb: allow chipset-specific actions for oneinit()
  ...

33 files changed:
1  2 
Documentation/devicetree/bindings/vendor-prefixes.txt
MAINTAINERS
arch/arc/boot/dts/axc001.dtsi
arch/arc/boot/dts/axc003.dtsi
arch/arc/boot/dts/axc003_idu.dtsi
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250-snow-common.dtsi
arch/arm/boot/dts/exynos5250-spring.dts
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/vc4/vc4_drv.c
include/linux/console.h
include/linux/vmalloc.h
mm/vmalloc.c

index 4454483cc53ffdfe89a1216c2a422ed01f446c32,42b6688c4a981d7c146881960b6a139190d24f9c..a7440bcd67ffc9ac43afe39564cb434ce8e58bc6
@@@ -16,22 -16,20 +16,23 @@@ al Annapurna Lab
  allwinner     Allwinner Technology Co., Ltd.
  alphascale    AlphaScale Integrated Circuits Systems, Inc.
  altr  Altera Corp.
 +amazon        Amazon.com, Inc.
  amcc  Applied Micro Circuits Corporation (APM, formally AMCC)
  amd   Advanced Micro Devices (AMD), Inc.
  amlogic       Amlogic, Inc.
  ampire        Ampire Co., Ltd.
  ams   AMS AG
  amstaos       AMS-Taos Inc.
+ analogix      Analogix Semiconductor, Inc.
  apm   Applied Micro Circuits Corporation (APM)
  aptina        Aptina Imaging
  arasan        Arasan Chip Systems
  arm   ARM Ltd.
  armadeus      ARMadeus Systems SARL
 +arrow Arrow Electronics
  artesyn       Artesyn Embedded Technologies Inc.
  asahi-kasei   Asahi Kasei Corp.
 +aspeed        ASPEED Technology Inc.
  atlas Atlas Scientific LLC
  atmel Atmel Corporation
  auo   AU Optronics Corporation
@@@ -61,7 -59,6 +62,7 @@@ cnxt  Conexant Systems, Inc
  compulab      CompuLab Ltd.
  cortina       Cortina Systems, Inc.
  cosmic        Cosmic Circuits
 +creative      Creative Technology Ltd
  crystalfontz  Crystalfontz America, Inc.
  cubietech     Cubietech, Ltd.
  cypress       Cypress Semiconductor Corporation
@@@ -74,14 -71,11 +75,14 @@@ digilent   Diglent, Inc
  dlg   Dialog Semiconductor
  dlink D-Link Corporation
  dmo   Data Modul AG
 +dptechnics    DPTechnics
 +dragino       Dragino Technology Co., Limited
  ea    Embedded Artists AB
  ebv   EBV Elektronik
  edt   Emerging Display Technologies
  eeti  eGalax_eMPIA Technology Inc
  elan  Elan Microelectronic Corp.
 +embest        Shenzhen Embest Technology Co., Ltd.
  emmicro       EM Microelectronic
  energymicro   Silicon Laboratories (formerly Energy Micro AS)
  epcos EPCOS AG
@@@ -93,13 -87,11 +94,13 @@@ eukrea  EukrĂ©a Electromatiqu
  everest       Everest Semiconductor Co. Ltd.
  everspin      Everspin Technologies, Inc.
  excito        Excito
 +ezchip        EZchip Semiconductor
  fcs   Fairchild Semiconductor
  firefly       Firefly
  focaltech     FocalTech Systems Co.,Ltd
  fsl   Freescale Semiconductor
  ge    General Electric Company
 +geekbuying    GeekBuying
  GEFanuc       GE Fanuc Intelligent Platforms Embedded Systems, Inc.
  gef   GE Fanuc Intelligent Platforms Embedded Systems, Inc.
  geniatech     Geniatech, Inc.
@@@ -127,7 -119,6 +128,7 @@@ idt        Integrated Device Technologies, Inc
  ifi   Ingenieurburo Fur Ic-Technologie (I/F/I)
  iom   Iomega Corporation
  img   Imagination Technologies Ltd.
 +inforce       Inforce Computing
  ingenic       Ingenic Semiconductor
  innolux       Innolux Corporation
  intel Intel Corporation
@@@ -151,7 -142,6 +152,7 @@@ lsi        LSI Corp. (LSI Logic
  lltc  Linear Technology Corporation
  marvell       Marvell Technology Group Ltd.
  maxim Maxim Integrated Products
 +meas  Measurement Specialties
  mediatek      MediaTek Inc.
  melexis       Melexis N.V.
  merrii        Merrii Technology Co., Ltd.
@@@ -163,7 -153,6 +164,7 @@@ mitsubishi Mitsubishi Electric Corporat
  mosaixtech    Mosaix Technologies, Inc.
  moxa  Moxa
  mpl   MPL AG
 +mqmaker       mqmaker Inc.
  msi   Micro-Star International Co. Ltd.
  mti   Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
  mundoreader   Mundo Reader S.L.
@@@ -183,14 -172,13 +184,15 @@@ nvidia  NVIDI
  nxp   NXP Semiconductors
  okaya Okaya Electric America, Inc.
  olimex        OLIMEX Ltd.
 +onion Onion Corporation
  onnn  ON Semiconductor Corp.
+ ontat On Tat Industrial Company
  opencores     OpenCores.org
  option        Option NV
  ortustech     Ortus Technology Co., Ltd.
  ovti  OmniVision Technologies
  ORCL  Oracle Corporation
 +oxsemi        Oxford Semiconductor, Ltd.
  panasonic     Panasonic Corporation
  parade        Parade Technologies Inc.
  pericom       Pericom Technology Inc.
@@@ -261,10 -249,10 +263,11 @@@ toradex Toradex A
  toshiba       Toshiba Corporation
  toumaz        Toumaz
  tplink        TP-LINK Technologies Co., Ltd.
+ tpk   TPK U.S.A. LLC
  tronfy        Tronfy
  tronsmart     Tronsmart
  truly Truly Semiconductors Limited
 +tyan  Tyan Computer Corporation
  upisemi       uPI Semiconductor Corp.
  urt   United Radiant Technology Corporation
  usi   Universal Scientific Industrial Co., Ltd.
@@@ -274,7 -262,6 +277,7 @@@ via        VIA Technologies, Inc
  virtio        Virtual I/O Device Specification, developed by the OASIS consortium
  vivante       Vivante Corporation
  voipac        Voipac Technologies s.r.o.
 +wd    Western Digital Corp.
  wexler        Wexler
  winbond Winbond Electronics corp.
  wlf   Wolfson Microelectronics
diff --combined MAINTAINERS
index 5f83015ff01691c003d85c90b6635f87a69ac3f3,216d4476aab6c2a964670545f353f8cc90424a2a..ee7fb1668c15c979f65168a887f1e4dc7b08babe
@@@ -175,6 -175,7 +175,6 @@@ F: drivers/net/ethernet/realtek/r8169.
  8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
  M:    Greg Kroah-Hartman <[email protected]>
  L:    [email protected]
 -W:    http://serial.sourceforge.net
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
  F:    drivers/tty/serial/8250*
@@@ -626,7 -627,6 +626,7 @@@ F: include/linux/altera_jtaguart.
  
  AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
  M:    Tom Lendacky <[email protected]>
 +M:    Gary Hook <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    drivers/crypto/ccp/
@@@ -776,15 -776,6 +776,15 @@@ S:       Supporte
  F:    drivers/android/
  F:    drivers/staging/android/
  
 +ANDROID ION DRIVER
 +M:    Laura Abbott <[email protected]>
 +M:    Sumit Semwal <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/staging/android/ion
 +F:    drivers/staging/android/uapi/ion.h
 +F:    drivers/staging/android/uapi/ion_test.h
 +
  AOA (Apple Onboard Audio) ALSA DRIVER
  M:    Johannes Berg <[email protected]>
  L:    [email protected]
@@@ -856,6 -847,12 +856,12 @@@ S:       Maintaine
  F:    drivers/net/arcnet/
  F:    include/uapi/linux/if_arcnet.h
  
+ ARC PGU DRM DRIVER
+ M:    Alexey Brodkin <[email protected]>
+ S:    Supported
+ F:    drivers/gpu/drm/arc/
+ F:    Documentation/devicetree/bindings/display/snps,arcpgu.txt
  ARM HDLCD DRM DRIVER
  M:    Liviu Dudau <[email protected]>
  S:    Supported
@@@ -957,15 -954,12 +963,15 @@@ F:      drivers/clk/sunxi
  
  ARM/Amlogic Meson SoC support
  M:    Carlo Caione <[email protected]>
 +M:    Kevin Hilman <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
 -L:    linux-[email protected]
 +L:    linux-[email protected]
  W:    http://linux-meson.com/
  S:    Maintained
  F:    arch/arm/mach-meson/
  F:    arch/arm/boot/dts/meson*
 +F:    arch/arm64/boot/dts/amlogic/
 +F:    drivers/pinctrl/meson/
  N:    meson
  
  ARM/Annapurna Labs ALPINE ARCHITECTURE
@@@ -985,14 -979,7 +991,14 @@@ S:       Maintaine
  L:    [email protected]
  F:    arch/arm/mach-artpec
  F:    arch/arm/boot/dts/artpec6*
 -F:    drivers/clk/clk-artpec6.c
 +F:    drivers/clk/axis
 +
 +ARM/ASPEED MACHINE SUPPORT
 +M:    Joel Stanley <[email protected]>
 +S:    Maintained
 +F:    arch/arm/mach-aspeed/
 +F:    arch/arm/boot/dts/aspeed-*
 +F:    drivers/*/*aspeed*
  
  ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
  M:    Nicolas Ferre <[email protected]>
@@@ -1279,7 -1266,7 +1285,7 @@@ M:      Santosh Shilimkar <[email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-keystone/
 -F:    arch/arm/boot/dts/k2*
 +F:    arch/arm/boot/dts/keystone-*
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
  
  ARM/TEXAS INSTRUMENT KEYSTONE CLOCK FRAMEWORK
  S:    Maintained
  F:    drivers/memory/*emif*
  
 +ARM/LG1K ARCHITECTURE
 +M:    Chanho Min <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm64/boot/dts/lg/
 +
  ARM/LOGICPD PXA270 MACHINE SUPPORT
  M:    Lennert Buytenhek <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -1331,25 -1312,11 +1337,25 @@@ F:   drivers/mtd/spi-nor/nxp-spifi.
  F:    drivers/rtc/rtc-lpc24xx.c
  N:    lpc18xx
  
 +ARM/LPC32XX SOC SUPPORT
 +M:    Vladimir Zapolskiy <[email protected]>
 +M:    Sylvain Lemieux <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +T:    git git://github.com/vzapolskiy/linux-lpc32xx.git
 +S:    Maintained
 +F:    arch/arm/boot/dts/lpc32*
 +F:    arch/arm/mach-lpc32xx/
 +F:    drivers/i2c/busses/i2c-pnx.c
 +F:    drivers/net/ethernet/nxp/lpc_eth.c
 +F:    drivers/usb/host/ohci-nxp.c
 +F:    drivers/watchdog/pnx4008_wdt.c
 +N:    lpc32xx
 +
  ARM/MAGICIAN MACHINE SUPPORT
  M:    Philipp Zabel <[email protected]>
  S:    Maintained
  
 -ARM/Marvell Kirkwood and Armada 370, 375, 38x, XP SOC support
 +ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K SOC support
  M:    Jason Cooper <[email protected]>
  M:    Andrew Lunn <[email protected]>
  M:    Gregory Clement <[email protected]>
@@@ -1361,8 -1328,7 +1367,8 @@@ F:      drivers/rtc/rtc-armada38x.
  F:    arch/arm/boot/dts/armada*
  F:    arch/arm/boot/dts/kirkwood*
  F:    arch/arm64/boot/dts/marvell/armada*
 -
 +F:    drivers/cpufreq/mvebu-cpufreq.c
 +F:    arch/arm/configs/mvebu_*_defconfig
  
  ARM/Marvell Berlin SoC support
  M:    Sebastian Hesselbarth <[email protected]>
@@@ -1395,15 -1361,6 +1401,15 @@@ W:    http://www.digriz.org.uk/ts78xx/kern
  S:    Maintained
  F:    arch/arm/mach-orion5x/ts78xx-*
  
 +ARM/OXNAS platform support
 +M:    Neil Armstrong <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm/mach-oxnas/
 +F:    arch/arm/boot/dts/oxnas*
 +F:    arch/arm/boot/dts/wd-mbwe.dts
 +N:    oxnas
 +
  ARM/Mediatek RTC DRIVER
  M:    Eddie Huang <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -1519,10 -1476,7 +1525,10 @@@ F:    arch/arm/boot/dts/qcom-*.dt
  F:    arch/arm/boot/dts/qcom-*.dtsi
  F:    arch/arm/mach-qcom/
  F:    arch/arm64/boot/dts/qcom/*
 +F:    drivers/i2c/busses/i2c-qup.c
 +F:    drivers/clk/qcom/
  F:    drivers/soc/qcom/
 +F:    drivers/spi/spi-qup.c
  F:    drivers/tty/serial/msm_serial.h
  F:    drivers/tty/serial/msm_serial.c
  F:    drivers/*/pm8???-*
@@@ -1543,8 -1497,6 +1549,8 @@@ Q:      http://patchwork.kernel.org/project/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
  S:    Supported
  F:    arch/arm64/boot/dts/renesas/
 +F:    drivers/soc/renesas/
 +F:    include/linux/soc/renesas/
  
  ARM/RISCPC ARCHITECTURE
  M:    Russell King <[email protected]>
@@@ -1594,7 -1546,6 +1600,7 @@@ F:      arch/arm/mach-s5p*
  F:    arch/arm/mach-exynos*/
  F:    drivers/*/*s3c2410*
  F:    drivers/*/*/*s3c2410*
 +F:    drivers/memory/samsung/*
  F:    drivers/soc/samsung/*
  F:    drivers/spi/spi-s3c*
  F:    sound/soc/samsung/*
@@@ -1659,8 -1610,6 +1665,8 @@@ F:      arch/arm/configs/shmobile_defconfi
  F:    arch/arm/include/debug/renesas-scif.S
  F:    arch/arm/mach-shmobile/
  F:    drivers/sh/
 +F:    drivers/soc/renesas/
 +F:    include/linux/soc/renesas/
  
  ARM/SOCFPGA ARCHITECTURE
  M:    Dinh Nguyen <[email protected]>
@@@ -1695,7 -1644,6 +1701,7 @@@ F:      arch/arm/boot/dts/sti
  F:    drivers/char/hw_random/st-rng.c
  F:    drivers/clocksource/arm_global_timer.c
  F:    drivers/clocksource/clksrc_st_lpc.c
 +F:    drivers/cpufreq/sti-cpufreq.c
  F:    drivers/i2c/busses/i2c-st.c
  F:    drivers/media/rc/st_rc.c
  F:    drivers/media/platform/sti/c8sectpfe/
@@@ -1705,7 -1653,6 +1711,7 @@@ F:      drivers/phy/phy-miphy365x.
  F:    drivers/phy/phy-stih407-usb.c
  F:    drivers/phy/phy-stih41x-usb.c
  F:    drivers/pinctrl/pinctrl-st.c
 +F:    drivers/remoteproc/st_remoteproc.c
  F:    drivers/reset/sti/
  F:    drivers/rtc/rtc-st-lpc.c
  F:    drivers/tty/serial/st-asc.c
@@@ -1830,7 -1777,6 +1836,7 @@@ F:      */*/vexpress
  F:    */*/*/vexpress*
  F:    drivers/clk/versatile/clk-vexpress-osc.c
  F:    drivers/clocksource/versatile.c
 +N:    mps2
  
  ARM/VFP SUPPORT
  M:    Russell King <[email protected]>
@@@ -2056,11 -2002,6 +2062,11 @@@ M:    Nicolas Ferre <[email protected]
  S:    Supported
  F:    drivers/tty/serial/atmel_serial.c
  
 +ATMEL AT91 SAMA5D2-Compatible Shutdown Controller
 +M:    Nicolas Ferre <[email protected]>
 +S:    Supported
 +F:    drivers/power/reset/at91-sama5d2_shdwc.c
 +
  ATMEL SAMA5D2 ADC DRIVER
  M:    Ludovic Desroches <[email protected]>
  L:    [email protected]
@@@ -2268,13 -2209,10 +2274,13 @@@ BATMAN ADVANCE
  M:    Marek Lindner <[email protected]>
  M:    Simon Wunderlich <[email protected]>
  M:    Antonio Quartulli <[email protected]>
 -L:    [email protected]
 +L:    [email protected] (moderated for non-subscribers)
  W:    https://www.open-mesh.org/
  Q:    https://patchwork.open-mesh.org/project/batman/list/
  S:    Maintained
 +F:    Documentation/ABI/testing/sysfs-class-net-batman-adv
 +F:    Documentation/ABI/testing/sysfs-class-net-mesh
 +F:    Documentation/networking/batman-adv.txt
  F:    net/batman-adv/
  
  BAYCOM/HDLCDRV DRIVERS FOR AX.25
@@@ -3416,7 -3354,6 +3422,7 @@@ F:      Documentation/powerpc/cxlflash.tx
  
  STMMAC ETHERNET DRIVER
  M:    Giuseppe Cavallaro <[email protected]>
 +M:    Alexandre Torgue <[email protected]>
  L:    [email protected]
  W:    http://www.stlinux.com
  S:    Supported
@@@ -3608,15 -3545,6 +3614,15 @@@ F:    drivers/devfreq/devfreq-event.
  F:    include/linux/devfreq-event.h
  F:    Documentation/devicetree/bindings/devfreq/event/
  
 +BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS
 +M:    Chanwoo Choi <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
 +S:    Maintained
 +F:    drivers/devfreq/exynos-bus.c
 +F:    Documentation/devicetree/bindings/devfreq/exynos-bus.txt
 +
  DEVICE NUMBER REGISTRY
  M:    Torben Mathiasen <[email protected]>
  W:    http://lanana.org/docs/device-list/index.html
@@@ -3837,9 -3765,25 +3843,25 @@@ T:    git git://people.freedesktop.org/~ai
  S:    Maintained
  F:    drivers/gpu/drm/
  F:    drivers/gpu/vga/
+ F:    Documentation/DocBook/gpu.*
  F:    include/drm/
  F:    include/uapi/drm/
  
+ DRM DRIVER FOR AST SERVER GRAPHICS CHIPS
+ M:    Dave Airlie <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/ast/
+ DRM DRIVER FOR BOCHS VIRTUAL GPU
+ M:    Gerd Hoffmann <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/bochs/
+ DRM DRIVER FOR QEMU'S CIRRUS DEVICE
+ M:    Dave Airlie <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/cirrus/
  RADEON and AMDGPU DRM DRIVERS
  M:    Alex Deucher <[email protected]>
  M:    Christian König <[email protected]>
@@@ -3847,9 -3791,9 +3869,9 @@@ L:      [email protected]
  T:    git git://people.freedesktop.org/~agd5f/linux
  S:    Supported
  F:    drivers/gpu/drm/radeon/
- F:    include/uapi/drm/radeon*
+ F:    include/uapi/drm/radeon_drm.h
  F:    drivers/gpu/drm/amd/
- F:    include/uapi/drm/amdgpu*
+ F:    include/uapi/drm/amdgpu_drm.h
  
  DRM PANEL DRIVERS
  M:    Thierry Reding <[email protected]>
@@@ -3872,7 -3816,7 +3894,7 @@@ T:      git git://anongit.freedesktop.org/dr
  S:    Supported
  F:    drivers/gpu/drm/i915/
  F:    include/drm/i915*
- F:    include/uapi/drm/i915*
+ F:    include/uapi/drm/i915_drm.h
  
  DRM DRIVERS FOR ATMEL HLCDC
  M:    Boris Brezillon <[email protected]>
@@@ -3881,6 -3825,13 +3903,13 @@@ S:    Supporte
  F:    drivers/gpu/drm/atmel-hlcdc/
  F:    Documentation/devicetree/bindings/drm/atmel/
  
+ DRM DRIVERS FOR ALLWINNER A10
+ M:    Maxime Ripard  <[email protected]>
+ L:    [email protected]
+ S:    Supported
+ F:    drivers/gpu/drm/sun4i/
+ F:    Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <[email protected]>
  M:    Joonyoung Shim <[email protected]>
@@@ -3890,8 -3841,8 +3919,8 @@@ L:      [email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
  S:    Supported
  F:    drivers/gpu/drm/exynos/
- F:    include/drm/exynos*
- F:    include/uapi/drm/exynos*
+ F:    include/uapi/drm/exynos_drm.h
+ F:    Documentation/devicetree/bindings/display/exynos/
  
  DRM DRIVERS FOR FREESCALE DCU
  M:    Stefan Agner <[email protected]>
@@@ -3900,6 -3851,7 +3929,7 @@@ L:      [email protected]
  S:    Supported
  F:    drivers/gpu/drm/fsl-dcu/
  F:    Documentation/devicetree/bindings/display/fsl,dcu.txt
+ F:    Documentation/devicetree/bindings/display/fsl,tcon.txt
  F:    Documentation/devicetree/bindings/display/panel/nec,nl4827hc19_05b.txt
  
  DRM DRIVERS FOR FREESCALE IMX
@@@ -3915,12 -3867,45 +3945,45 @@@ M:   Patrik Jakobsson <patrik.r.jakobsson
  L:    [email protected]
  T:    git git://github.com/patjak/drm-gma500
  S:    Maintained
- F:    drivers/gpu/drm/gma500
- F:    include/drm/gma500*
+ F:    drivers/gpu/drm/gma500/
+ DRM DRIVERS FOR HISILICON
+ M:    Xinliang Liu <[email protected]>
+ R:    Xinwei Kong <[email protected]>
+ R:    Chen Feng <[email protected]>
+ L:    [email protected]
+ T:    git git://github.com/xin3liang/linux.git
+ S:    Maintained
+ F:    drivers/gpu/drm/hisilicon/
+ F:    Documentation/devicetree/bindings/display/hisilicon/
+ DRM DRIVER FOR INTEL I810 VIDEO CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/i810/
+ F:    include/uapi/drm/i810_drm.h
+ DRM DRIVER FOR MSM ADRENO GPU
+ M:    Rob Clark <[email protected]>
+ L:    [email protected]
+ L:    [email protected]
+ L:    [email protected]
+ T:    git git://people.freedesktop.org/~robclark/linux
+ S:    Maintained
+ F:    drivers/gpu/drm/msm/
+ F:    include/uapi/drm/msm_drm.h
+ F:    Documentation/devicetree/bindings/display/msm/
+ DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
+ M:    Ben Skeggs <[email protected]>
+ L:    [email protected]
+ L:    [email protected]
+ T:    git git://github.com/skeggsb/linux
+ S:    Supported
+ F:    drivers/gpu/drm/nouveau/
+ F:    include/uapi/drm/nouveau_drm.h
  
  DRM DRIVERS FOR NVIDIA TEGRA
  M:    Thierry Reding <[email protected]>
- M:    Terje Bergström <[email protected]>
  L:    [email protected]
  L:    [email protected]
  T:    git git://anongit.freedesktop.org/tegra/linux.git
@@@ -3931,22 -3916,54 +3994,54 @@@ F:   include/linux/host1x.
  F:    include/uapi/drm/tegra_drm.h
  F:    Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
  
+ DRM DRIVER FOR MATROX G200/G400 GRAPHICS CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/mga/
+ F:    include/uapi/drm/mga_drm.h
+ DRM DRIVER FOR MGA G200 SERVER GRAPHICS CHIPS
+ M:    Dave Airlie <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/mgag200/
+ DRM DRIVER FOR RAGE 128 VIDEO CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/r128/
+ F:    include/uapi/drm/r128_drm.h
  DRM DRIVERS FOR RENESAS
  M:    Laurent Pinchart <[email protected]>
  L:    [email protected]
  L:    [email protected]
- T:    git git://people.freedesktop.org/~airlied/linux
+ T:    git git://linuxtv.org/pinchartl/fbdev
  S:    Supported
  F:    drivers/gpu/drm/rcar-du/
  F:    drivers/gpu/drm/shmobile/
  F:    include/linux/platform_data/shmob_drm.h
+ F:    Documentation/devicetree/bindings/display/renesas,du.txt
+ DRM DRIVER FOR QXL VIRTUAL GPU
+ M:    Dave Airlie <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/qxl/
+ F:    include/uapi/drm/qxl_drm.h
  
  DRM DRIVERS FOR ROCKCHIP
  M:    Mark Yao <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/gpu/drm/rockchip/
- F:    Documentation/devicetree/bindings/display/rockchip*
+ F:    Documentation/devicetree/bindings/display/rockchip/
+ DRM DRIVER FOR SAVAGE VIDEO CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/savage/
+ F:    include/uapi/drm/savage_drm.h
+ DRM DRIVER FOR SIS VIDEO CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/sis/
+ F:    include/uapi/drm/sis_drm.h
  
  DRM DRIVERS FOR STI
  M:    Benjamin Gaignard <[email protected]>
@@@ -3957,14 -3974,43 +4052,43 @@@ S:   Maintaine
  F:    drivers/gpu/drm/sti
  F:    Documentation/devicetree/bindings/display/st,stih4xx.txt
  
+ DRM DRIVER FOR TDFX VIDEO CARDS
+ S:    Orphan / Obsolete
+ F:    drivers/gpu/drm/tdfx/
+ DRM DRIVER FOR USB DISPLAYLINK VIDEO ADAPTERS
+ M:    Dave Airlie <[email protected]>
+ S:    Odd Fixes
+ F:    drivers/gpu/drm/udl/
  DRM DRIVERS FOR VIVANTE GPU IP
  M:    Lucas Stach <[email protected]>
  R:    Russell King <[email protected]>
  R:    Christian Gmeiner <[email protected]>
  L:    [email protected]
  S:    Maintained
- F:    drivers/gpu/drm/etnaviv
- F:    Documentation/devicetree/bindings/display/etnaviv
+ F:    drivers/gpu/drm/etnaviv/
+ F:    include/uapi/drm/etnaviv_drm.h
+ F:    Documentation/devicetree/bindings/display/etnaviv/
+ DRM DRIVER FOR VMWARE VIRTUAL GPU
+ M:    "VMware Graphics" <[email protected]>
+ M:    Sinclair Yeh <[email protected]>
+ M:    Thomas Hellstrom <[email protected]>
+ L:    [email protected]
+ T:    git git://people.freedesktop.org/~syeh/repos_linux
+ T:    git git://people.freedesktop.org/~thomash/linux
+ S:    Supported
+ F:    drivers/gpu/drm/vmwgfx/
+ F:    include/uapi/drm/vmwgfx_drm.h
+ DRM DRIVERS FOR VC4
+ M:    Eric Anholt <[email protected]>
+ T:    git git://github.com/anholt/linux
+ S:    Supported
+ F:    drivers/gpu/drm/vc4/
+ F:    include/uapi/drm/vc4_drm.h
+ F:    Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
  
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <[email protected]>
@@@ -4457,12 -4503,6 +4581,12 @@@ S:    Maintaine
  F:    drivers/video/fbdev/exynos/exynos_mipi*
  F:    include/video/exynos_mipi*
  
 +EZchip NPS platform support
 +M:    Noam Camus <[email protected]>
 +S:    Supported
 +F:    arch/arc/plat-eznps
 +F:    arch/arc/boot/dts/eznps.dts
 +
  F71805F HARDWARE MONITORING DRIVER
  M:    Jean Delvare <[email protected]>
  L:    [email protected]
@@@ -4745,7 -4785,6 +4869,7 @@@ FREESCALE SOC SOUND DRIVER
  M:    Timur Tabi <[email protected]>
  M:    Nicolin Chen <[email protected]>
  M:    Xiubo Li <[email protected]>
 +R:    Fabio Estevam <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
  S:    Maintained
@@@ -4755,7 -4794,6 +4879,7 @@@ F:      sound/soc/fsl/mpc8610_hpcd.
  
  FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER
  M:    "J. German Rivera" <[email protected]>
 +M:    Stuart Yoder <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/staging/fsl-mc/
@@@ -4793,7 -4831,7 +4917,7 @@@ F:      include/linux/fscache*.
  F2FS FILE SYSTEM
  M:    Jaegeuk Kim <[email protected]>
  M:    Changman Lee <[email protected]>
 -R:    Chao Yu <chao2.yu@samsung.com>
 +R:    Chao Yu <yuchao0@huawei.com>
  L:    [email protected]
  W:    http://en.wikipedia.org/wiki/F2FS
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
@@@ -4970,7 -5008,6 +5094,7 @@@ M:      Alexandre Courbot <[email protected]
  L:    [email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
  S:    Maintained
 +F:    Documentation/devicetree/bindings/gpio/
  F:    Documentation/gpio/
  F:    Documentation/ABI/testing/gpio-cdev
  F:    Documentation/ABI/obsolete/sysfs-gpio
@@@ -5362,7 -5399,6 +5486,7 @@@ I2C MUXE
  M:    Peter Rosin <[email protected]>
  L:    [email protected]
  S:    Maintained
 +F:    Documentation/i2c/i2c-topology
  F:    Documentation/i2c/muxes/
  F:    Documentation/devicetree/bindings/i2c/i2c-mux*
  F:    drivers/i2c/i2c-mux.c
@@@ -5627,7 -5663,7 +5751,7 @@@ IIO SUBSYSTEM AND DRIVER
  M:    Jonathan Cameron <[email protected]>
  R:    Hartmut Knaack <[email protected]>
  R:    Lars-Peter Clausen <[email protected]>
 -R:    Peter Meerwald <[email protected]>
 +R:    Peter Meerwald-Stadler <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/iio/
@@@ -5832,6 -5868,13 +5956,6 @@@ F:     drivers/char/hw_random/ixp4xx-rng.
  
  INTEL ETHERNET DRIVERS
  M:    Jeff Kirsher <[email protected]>
 -R:    Jesse Brandeburg <[email protected]>
 -R:    Shannon Nelson <[email protected]>
 -R:    Carolyn Wyborny <[email protected]>
 -R:    Don Skidmore <[email protected]>
 -R:    Bruce Allan <[email protected]>
 -R:    John Ronciak <[email protected]>
 -R:    Mitch Williams <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  W:    http://www.intel.com/support/feedback.htm
  W:    http://e1000.sourceforge.net/
@@@ -5911,7 -5954,6 +6035,7 @@@ F:      drivers/net/wireless/intel/iwlegacy
  INTEL WIRELESS WIFI LINK (iwlwifi)
  M:    Johannes Berg <[email protected]>
  M:    Emmanuel Grumbach <[email protected]>
 +M:    Luca Coelho <[email protected]>
  M:    Intel Linux Wireless <[email protected]>
  L:    [email protected]
  W:    http://intellinuxwireless.org
@@@ -6077,13 -6119,6 +6201,13 @@@ F:    include/linux/irqdomain.
  F:    kernel/irq/irqdomain.c
  F:    kernel/irq/msi.c
  
 +ISA
 +M:    William Breathitt Gray <[email protected]>
 +S:    Maintained
 +F:    Documentation/isa.txt
 +F:    drivers/base/isa.c
 +F:    include/linux/isa.h
 +
  ISAPNP
  M:    Jaroslav Kysela <[email protected]>
  S:    Maintained
@@@ -6264,7 -6299,7 +6388,7 @@@ S:      Maintaine
  F:    arch/*/include/asm/kasan.h
  F:    arch/*/mm/kasan_init*
  F:    Documentation/kasan.txt
 -F:    include/linux/kasan.h
 +F:    include/linux/kasan*.h
  F:    lib/test_kasan.c
  F:    mm/kasan/
  F:    scripts/Makefile.kasan
@@@ -6515,7 -6550,7 +6639,7 @@@ F:      net/l3mde
  F:    include/net/l3mdev.h
  
  LANTIQ MIPS ARCHITECTURE
 -M:    John Crispin <blogic@openwrt.org>
 +M:    John Crispin <john@phrozen.org>
  L:    [email protected]
  S:    Maintained
  F:    arch/mips/lantiq
@@@ -6697,19 -6732,6 +6821,19 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    Documentation/powerpc/
  F:    arch/powerpc/
 +F:    drivers/char/tpm/tpm_ibmvtpm*
 +F:    drivers/crypto/nx/
 +F:    drivers/crypto/vmx/
 +F:    drivers/net/ethernet/ibm/ibmveth.*
 +F:    drivers/net/ethernet/ibm/ibmvnic.*
 +F:    drivers/pci/hotplug/rpa*
 +F:    drivers/scsi/ibmvscsi/
 +N:    opal
 +N:    /pmac
 +N:    powermac
 +N:    powernv
 +N:    [^a-z0-9]ps3
 +N:    pseries
  
  LINUX FOR POWER MACINTOSH
  M:    Benjamin Herrenschmidt <[email protected]>
@@@ -6790,7 -6812,6 +6914,7 @@@ F:      kernel/livepatch
  F:    include/linux/livepatch.h
  F:    arch/x86/include/asm/livepatch.h
  F:    arch/x86/kernel/livepatch.c
 +F:    Documentation/livepatch/
  F:    Documentation/ABI/testing/sysfs-kernel-livepatch
  F:    samples/livepatch/
  L:    [email protected]
@@@ -6879,6 -6900,12 +7003,6 @@@ W:     logfs.or
  S:    Maintained
  F:    fs/logfs/
  
 -LPC32XX MACHINE SUPPORT
 -M:    Roland Stigge <[email protected]>
 -L:    [email protected] (moderated for non-subscribers)
 -S:    Maintained
 -F:    arch/arm/mach-lpc32xx/
 -
  LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
  M:    Sathya Prakash <[email protected]>
  M:    Chaitra P B <[email protected]>
@@@ -7005,6 -7032,8 +7129,8 @@@ MARVELL ARMADA DRM SUPPOR
  M:    Russell King <[email protected]>
  S:    Maintained
  F:    drivers/gpu/drm/armada/
+ F:    include/uapi/drm/armada_drm.h
+ F:    Documentation/devicetree/bindings/display/armada/
  
  MARVELL 88E6352 DSA support
  M:    Guenter Roeck <[email protected]>
@@@ -7117,9 -7146,9 +7243,9 @@@ M:      Chanwoo Choi <[email protected]
  M:    Krzysztof Kozlowski <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    drivers/*/max14577.c
 +F:    drivers/*/max14577*.c
  F:    drivers/*/max77686*.c
 -F:    drivers/*/max77693.c
 +F:    drivers/*/max77693*.c
  F:    drivers/extcon/extcon-max14577.c
  F:    drivers/extcon/extcon-max77693.c
  F:    drivers/rtc/rtc-max77686.c
@@@ -7369,15 -7398,6 +7495,15 @@@ S:    Supporte
  F:    Documentation/mips/
  F:    arch/mips/
  
 +MIPS/LOONGSON1 ARCHITECTURE
 +M:    Keguang Zhang <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    arch/mips/loongson32/
 +F:    arch/mips/include/asm/mach-loongson32/
 +F:    drivers/*/*loongson1*
 +F:    drivers/*/*/*loongson1*
 +
  MIROSOUND PCM20 FM RADIO RECEIVER DRIVER
  M:    Hans Verkuil <[email protected]>
  L:    [email protected]
@@@ -7645,10 -7665,10 +7771,10 @@@ M:   Michael Schmitz <[email protected]
  L:    [email protected]
  S:    Maintained
  F:    Documentation/scsi/g_NCR5380.txt
 +F:    Documentation/scsi/dtc3x80.txt
  F:    drivers/scsi/NCR5380.*
  F:    drivers/scsi/arm/cumana_1.c
  F:    drivers/scsi/arm/oak.c
 -F:    drivers/scsi/atari_NCR5380.c
  F:    drivers/scsi/atari_scsi.*
  F:    drivers/scsi/dmx3191d.c
  F:    drivers/scsi/dtc.*
@@@ -8280,6 -8300,7 +8406,6 @@@ F:      drivers/of/resolver.
  OPENRISC ARCHITECTURE
  M:    Jonas Bonn <[email protected]>
  W:    http://openrisc.net
 -L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  T:    git git://openrisc.net/~jonas/linux
  F:    arch/openrisc/
@@@ -8400,6 -8421,7 +8526,6 @@@ F:      drivers/platform/x86/panasonic-lapto
  
  PANASONIC MN10300/AM33/AM34 PORT
  M:    David Howells <[email protected]>
 -M:    Koichi Yasutake <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  W:    ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/
  S:    Maintained
@@@ -8833,6 -8855,7 +8959,6 @@@ F:      drivers/pinctrl/pinctrl-single.
  
  PIN CONTROLLER - ST SPEAR
  M:    Viresh Kumar <[email protected]>
 -L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  W:    http://www.st.com/spear
  S:    Maintained
@@@ -9294,7 -9317,7 +9420,7 @@@ S:      Maintaine
  F:    drivers/video/fbdev/aty/aty128fb.c
  
  RALINK MIPS ARCHITECTURE
 -M:    John Crispin <blogic@openwrt.org>
 +M:    John Crispin <john@phrozen.org>
  L:    [email protected]
  S:    Maintained
  F:    arch/mips/ralink
@@@ -9592,7 -9615,7 +9718,7 @@@ F:      drivers/net/wireless/realtek/rtlwifi
  RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
  M:    Jes Sorensen <[email protected]>
  L:    [email protected]
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8723au-mac80211
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
  S:    Maintained
  F:    drivers/net/wireless/realtek/rtl8xxxu/
  
@@@ -9857,7 -9880,6 +9983,7 @@@ F:      drivers/mmc/host/dw_mmc
  SYSTEM TRACE MODULE CLASS
  M:    Alexander Shishkin <[email protected]>
  S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git
  F:    Documentation/trace/stm.txt
  F:    drivers/hwtracing/stm/
  F:    include/linux/stm.h
@@@ -10037,6 -10059,7 +10163,6 @@@ F:   drivers/mmc/host/sdhci-s3c
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER
  M:    Viresh Kumar <[email protected]>
 -L:    [email protected]
  L:    [email protected]
  S:    Maintained
  F:    drivers/mmc/host/sdhci-spear.c
@@@ -10074,12 -10097,6 +10200,12 @@@ T: git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    security/apparmor/
  
 +LOADPIN SECURITY MODULE
 +M:    Kees Cook <[email protected]>
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin
 +S:    Supported
 +F:    security/loadpin/
 +
  YAMA SECURITY MODULE
  M:    Kees Cook <[email protected]>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
@@@ -10270,8 -10287,8 +10396,8 @@@ F:   arch/arm/mach-s3c24xx/bast-irq.
  TI DAVINCI MACHINE SUPPORT
  M:    Sekhar Nori <[email protected]>
  M:    Kevin Hilman <[email protected]>
 -T:    git git://gitorious.org/linux-davinci/linux-davinci.git
 -Q:    http://patchwork.kernel.org/project/linux-davinci/list/
 +L:    [email protected] (moderated for non-subscribers)
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git
  S:    Supported
  F:    arch/arm/mach-davinci/
  F:    drivers/i2c/busses/i2c-davinci.c
@@@ -10599,6 -10616,7 +10725,6 @@@ F:   include/linux/compiler.
  SPEAR PLATFORM SUPPORT
  M:    Viresh Kumar <[email protected]>
  M:    Shiraz Hashim <[email protected]>
 -L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  W:    http://www.st.com/spear
  S:    Maintained
@@@ -10607,6 -10625,7 +10733,6 @@@ F:   arch/arm/mach-spear
  
  SPEAR CLOCK FRAMEWORK SUPPORT
  M:    Viresh Kumar <[email protected]>
 -L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  W:    http://www.st.com/spear
  S:    Maintained
@@@ -11049,11 -11068,10 +11175,11 @@@ M:        Prashant Gaikwad <[email protected]
  S:    Supported
  F:    drivers/clk/tegra/
  
 -TEGRA DMA DRIVER
 +TEGRA DMA DRIVERS
  M:    Laxman Dewangan <[email protected]>
 +M:    Jon Hunter <[email protected]>
  S:    Supported
 -F:    drivers/dma/tegra20-apb-dma.c
 +F:    drivers/dma/tegra*
  
  TEGRA I2C DRIVER
  M:    Laxman Dewangan <[email protected]>
@@@ -11354,13 -11372,14 +11480,13 @@@ S:        Maintaine
  F:    drivers/media/i2c/tc358743*
  F:    include/media/i2c/tc358743.h
  
 -TMIO MMC DRIVER
 -M:    Ian Molton <[email protected]>
 +TMIO/SDHI MMC DRIVER
 +M:    Wolfram Sang <[email protected]>
  L:    [email protected]
 -S:    Maintained
 +S:    Supported
  F:    drivers/mmc/host/tmio_mmc*
  F:    drivers/mmc/host/sh_mobile_sdhi.c
 -F:    include/linux/mmc/tmio.h
 -F:    include/linux/mmc/sh_mobile_sdhi.h
 +F:    include/linux/mfd/tmio.h
  
  TMP401 HARDWARE MONITOR DRIVER
  M:    Guenter Roeck <[email protected]>
@@@ -11392,14 -11411,6 +11518,14 @@@ W: https://linuxtv.or
  S:    Odd Fixes
  F:    drivers/media/pci/tw68/
  
 +TW686X VIDEO4LINUX DRIVER
 +M:    Ezequiel Garcia <[email protected]>
 +L:    [email protected]
 +T:    git git://linuxtv.org/media_tree.git
 +W:    http://linuxtv.org
 +S:    Maintained
 +F:    drivers/media/pci/tw686x/
 +
  TPM DEVICE DRIVER
  M:    Peter Huewe <[email protected]>
  M:    Marcel Selhorst <[email protected]>
@@@ -11433,20 -11444,6 +11559,20 @@@ F: include/trace
  F:    kernel/trace/
  F:    tools/testing/selftests/ftrace/
  
 +TRACING MMIO ACCESSES (MMIOTRACE)
 +M:    Steven Rostedt <[email protected]>
 +M:    Ingo Molnar <[email protected]>
 +R:    Karol Herbst <[email protected]>
 +R:    Pekka Paalanen <[email protected]>
 +S:    Maintained
 +L:    [email protected]
 +L:    [email protected]
 +F:    kernel/trace/trace_mmiotrace.c
 +F:    include/linux/mmiotrace.h
 +F:    arch/x86/mm/kmmio.c
 +F:    arch/x86/mm/mmio-mod.c
 +F:    arch/x86/mm/testmmiotrace.c
 +
  TRIVIAL PATCHES
  M:    Jiri Kosina <[email protected]>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
@@@ -11518,8 -11515,7 +11644,8 @@@ F:   Documentation/filesystems/ubifs.tx
  F:    fs/ubifs/
  
  UCLINUX (M68KNOMMU AND COLDFIRE)
 -M:    Greg Ungerer <[email protected]>
 +M:    Greg Ungerer <[email protected]>
 +W:    http://www.linux-m68k.org/
  W:    http://www.uclinux.org/
  L:    [email protected]
  L:    [email protected]  (subscribers-only)
  W:    http://www.slimlogic.co.uk/?p=48
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
  S:    Supported
 +F:    Documentation/devicetree/bindings/regulator/
  F:    drivers/regulator/
 +F:    include/dt-bindings/regulator/
  F:    include/linux/regulator/
  
  VRF
@@@ -12309,12 -12303,6 +12435,12 @@@ F: include/linux/workqueue.
  F:    kernel/workqueue.c
  F:    Documentation/workqueue.txt
  
 +X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS
 +M:    Chen-Yu Tsai <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +N:    axp[128]
 +
  X.25 NETWORK LAYER
  M:    Andrew Hendry <[email protected]>
  L:    [email protected]
index 40bcecfc368706dfb600f7f82636ed4d0fd43d92,262496ac2628e1b1721ac11220a9993868065bc5..3e02f152edcb5eac50870720be8ffe626cb1b1b6
@@@ -11,8 -11,6 +11,8 @@@
   * Note that this file only supports the 770D CPU
   */
  
 +/include/ "skeleton.dtsi"
 +
  / {
        compatible = "snps,arc";
        clock-frequency = <750000000>;  /* 750 MHZ */
  
                ranges = <0x00000000 0xf0000000 0x10000000>;
  
 -              cpu_intc: arc700-intc@cpu {
 +              core_clk: core_clk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <750000000>;
 +              };
 +
 +              core_intc: arc700-intc@cpu {
                        compatible = "snps,arc700-intc";
                        interrupt-controller;
                        #interrupt-cells = <1>;
@@@ -56,7 -48,7 +56,7 @@@
                                reg = <0>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
 -                              interrupt-parent = <&cpu_intc>;
 +                              interrupt-parent = <&core_intc>;
                                interrupts = <15>;
                        };
                };
                compatible = "snps,dw-apb-ictl";
                reg = < 0xe0012000 0x200 >;
                interrupt-controller;
 -              interrupt-parent = <&cpu_intc>;
 +              interrupt-parent = <&core_intc>;
                interrupts = < 7 >;
        };
  
        memory {
                #address-cells = <1>;
                #size-cells = <1>;
-               ranges = <0x00000000 0x80000000 0x40000000>;
+               ranges = <0x00000000 0x80000000 0x20000000>;
                device_type = "memory";
-               reg = <0x80000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x1b000000>;  /* (512 - 32) MiB */
+       };
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               /*
+                * We just move frame buffer area to the very end of
+                * available DDR. And even though in case of ARC770 there's
+                * no strict requirement for a frame-buffer to be in any
+                * particular location it allows us to use the same
+                * base board's DT node for ARC PGU as for ARc HS38.
+                */
+               frame_buffer: frame_buffer@9e000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x9e000000 0x2000000>;
+                       no-map;
+               };
        };
  };
index cabe0deeb2d880d3fab56d419d95f9592b3536a2,35ece04d8353d13a9151642989d1e8fb2cab57b6..378e455a94c4a86aa2af9a44a4d83c2cbbf771c2
@@@ -10,8 -10,6 +10,8 @@@
   * Device tree for AXC003 CPU card: HS38x UP configuration
   */
  
 +/include/ "skeleton_hs.dtsi"
 +
  / {
        compatible = "snps,arc";
        clock-frequency = <90000000>;
  
                ranges = <0x00000000 0xf0000000 0x10000000>;
  
 -              cpu_intc: archs-intc@cpu {
 +              core_clk: core_clk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <90000000>;
 +              };
 +
 +              core_intc: archs-intc@cpu {
                        compatible = "snps,archs-intc";
                        interrupt-controller;
                        #interrupt-cells = <1>;
@@@ -55,7 -47,7 +55,7 @@@
                                reg = <0>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
 -                              interrupt-parent = <&cpu_intc>;
 +                              interrupt-parent = <&core_intc>;
                                interrupts = <25>;
                        };
                };
@@@ -74,7 -66,7 +74,7 @@@
                arcpct0: pct {
                        compatible = "snps,archs-pct";
                        #interrupt-cells = <1>;
 -                      interrupt-parent = <&cpu_intc>;
 +                      interrupt-parent = <&core_intc>;
                        interrupts = <20>;
                };
        };
@@@ -97,7 -89,7 +97,7 @@@
                compatible = "snps,dw-apb-ictl";
                reg = < 0xe0012000 0x200 >;
                interrupt-controller;
 -              interrupt-parent = <&cpu_intc>;
 +              interrupt-parent = <&core_intc>;
                interrupts = < 24 >;
        };
  
                device_type = "memory";
                reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               /*
+                * Move frame buffer out of IOC aperture (0x8z-0xAz).
+                */
+               frame_buffer: frame_buffer@be000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0xbe000000 0x2000000>;
+                       no-map;
+               };
+       };
  };
index ed1674b16e827285e2b0849a8531fafeb959197b,df9ddb623bfe574fc98b7149111ed4a9d73c64f5..64c94b2860ab569d03d4672db417ad1e3307f86a
@@@ -10,8 -10,6 +10,8 @@@
   * Device tree for AXC003 CPU card: HS38x2 (Dual Core) with IDU intc
   */
  
 +/include/ "skeleton_hs_idu.dtsi"
 +
  / {
        compatible = "snps,arc";
        clock-frequency = <90000000>;
  
                ranges = <0x00000000 0xf0000000 0x10000000>;
  
 -              cpu_intc: archs-intc@cpu {
 +              core_clk: core_clk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <100000000>;
 +              };
 +
 +              core_intc: archs-intc@cpu {
                        compatible = "snps,archs-intc";
                        interrupt-controller;
                        #interrupt-cells = <1>;
@@@ -40,7 -32,7 +40,7 @@@
                idu_intc: idu-interrupt-controller {
                        compatible = "snps,archs-idu-intc";
                        interrupt-controller;
 -                      interrupt-parent = <&cpu_intc>;
 +                      interrupt-parent = <&core_intc>;
  
                        /*
                         * <hwirq  distribution>
@@@ -97,7 -89,7 +97,7 @@@
                arcpct0: pct {
                        compatible = "snps,archs-pct";
                        #interrupt-cells = <1>;
 -                      interrupt-parent = <&cpu_intc>;
 +                      interrupt-parent = <&core_intc>;
                        interrupts = <20>;
                };
        };
                device_type = "memory";
                reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               /*
+                * Move frame buffer out of IOC aperture (0x8z-0xAz).
+                */
+               frame_buffer: frame_buffer@be000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0xbe000000 0x2000000>;
+                       no-map;
+               };
+       };
  };
index 68c84a2fc1e4ffcda9501e2749bbd1f59ea91e46,c3ecb5e6b72d17533be3d7fc91086059475dc07b..d6c1bbc98ac3b40caa94e60420996081bdafe44c
                ranges = <0x00000000 0xe0000000 0x10000000>;
                interrupt-parent = <&mb_intc>;
  
 +              i2sclk: i2sclk@100a0 {
 +                      compatible = "snps,axs10x-i2s-pll-clock";
 +                      reg = <0x100a0 0x10>;
 +                      clocks = <&i2spll_clk>;
 +                      #clock-cells = <0>;
 +              };
 +
                clocks {
 +                      i2spll_clk: i2spll_clk {
 +                              compatible = "fixed-clock";
 +                              clock-frequency = <27000000>;
 +                              #clock-cells = <0>;
 +                      };
 +
                        i2cclk: i2cclk {
                                compatible = "fixed-clock";
                                clock-frequency = <50000000>;
                                clock-frequency = <50000000>;
                                #clock-cells = <0>;
                        };
+                       pguclk: pguclk {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <74440000>;
+                       };
                };
  
                ethernet@0x18000 {
                        clocks = <&i2cclk>;
                        interrupts = <16>;
  
+                       adv7511:adv7511@39{
+                               compatible="adi,adv7511";
+                               reg = <0x39>;
+                               interrupts = <23>;
+                               adi,input-depth = <8>;
+                               adi,input-colorspace = "rgb";
+                               adi,input-clock = "1x";
+                               adi,clock-delay = <0x03>;
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       /* RGB/YUV input */
+                                       port@0 {
+                                               reg = <0>;
+                                               adv7511_input:endpoint {
+                                               remote-endpoint = <&pgu_output>;
+                                               };
+                                       };
+                                       /* HDMI output */
+                                       port@1 {
+                                               reg = <1>;
+                                               adv7511_output: endpoint {
+                                                       remote-endpoint = <&hdmi_connector_in>;
+                                               };
+                                       };
+                               };
+                       };
                        eeprom@0x54{
                                compatible = "24c01";
                                reg = <0x54>;
                        };
                };
  
+               hdmi0: connector {
+                       compatible = "hdmi-connector";
+                       type = "a";
+                       port {
+                               hdmi_connector_in: endpoint {
+                                       remote-endpoint = <&adv7511_output>;
+                               };
+                       };
+               };
                gpio0:gpio@13000 {
                        compatible = "snps,dw-apb-gpio";
                        reg = <0x13000 0x1000>;
                                reg = <2>;
                        };
                };
+               pgu@17000 {
+                       compatible = "snps,arcpgu";
+                       reg = <0x17000 0x400>;
+                       encoder-slave = <&adv7511>;
+                       clocks = <&pguclk>;
+                       clock-names = "pxlclk";
+                       memory-region = <&frame_buffer>;
+                       port {
+                               pgu_output: endpoint {
+                                       remote-endpoint = <&adv7511_input>;
+                               };
+                       };
+               };
        };
  };
index 1e25152dc0f6ccc5adb0ff18e21fccf86c854351,85d819217d17cd0426d91686f7c6978831171f73..85dad29c08dc745028739efd45d2e6bfdf84b780
  &dp {
        status = "okay";
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <4>;
        display-timings {
                native-mode = <&timing0>;
  
 -              timing0: timing@0 {
 +              timing0: timing {
                        /* 2560x1600 DP panel */
                        clock-frequency = <50000>;
                        hactive = <2560>;
index 0e2eb3f6b590b38dbcd561ce6006110af5110357,f30c2dbba4f5ddc2b945388d8ca35f0c9a893894..b7992b13c9de96d63720ec22eafd8319c79127e0
@@@ -29,7 -29,7 +29,7 @@@
                bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
        };
  
 -      vdd: fixed-regulator@0 {
 +      vdd: fixed-regulator-vdd {
                compatible = "regulator-fixed";
                regulator-name = "vdd-supply";
                regulator-min-microvolt = <1800000>;
@@@ -37,7 -37,7 +37,7 @@@
                regulator-always-on;
        };
  
 -      dbvdd: fixed-regulator@1 {
 +      dbvdd: fixed-regulator-dbvdd {
                compatible = "regulator-fixed";
                regulator-name = "dbvdd-supply";
                regulator-min-microvolt = <3300000>;
@@@ -45,7 -45,7 +45,7 @@@
                regulator-always-on;
        };
  
 -      spkvdd: fixed-regulator@2 {
 +      spkvdd: fixed-regulator-spkvdd {
                compatible = "regulator-fixed";
                regulator-name = "spkvdd-supply";
                regulator-min-microvolt = <5000000>;
@@@ -80,8 -80,6 +80,6 @@@
  
  &dp {
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <4>;
@@@ -93,7 -91,7 +91,7 @@@
        display-timings {
                native-mode = <&timing0>;
  
 -              timing0: timing@0 {
 +              timing0: timing {
                        /* 1280x800 */
                        clock-frequency = <50000>;
                        hactive = <1280>;
index c9889b1f530af6782c52fd023f2a7f337ae3e7c5,746808f401e5de551cc4bfc69679b5b279a83944..ddfe1f558c105a1b962cce3ca69e0966021a01da
@@@ -84,7 -84,7 +84,7 @@@
                                sbs,poll-retry-count = <1>;
                        };
  
 -                      cros_ec: embedded-controller {
 +                      cros_ec: embedded-controller@1e {
                                compatible = "google,cros-ec-i2c";
                                reg = <0x1e>;
                                interrupts = <6 IRQ_TYPE_NONE>;
@@@ -94,7 -94,7 +94,7 @@@
                                wakeup-source;
                        };
  
 -                      power-regulator {
 +                      power-regulator@48 {
                                compatible = "ti,tps65090";
                                reg = <0x48>;
  
        pinctrl-names = "default";
        pinctrl-0 = <&dp_hpd>;
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <2>;
-       samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+       hpd-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
  
        ports {
 -              port@0 {
 +              port0 {
                        dp_out: endpoint {
                                remote-endpoint = <&bridge_in>;
                        };
        samsung,i2c-sda-delay = <100>;
        samsung,i2c-max-bus-freq = <378000>;
  
 -      trackpad {
 +      trackpad@67 {
                reg = <0x67>;
                compatible = "cypress,cyapa";
                interrupts = <2 IRQ_TYPE_NONE>;
                edid-emulation = <5>;
  
                ports {
 -                      port@0 {
 +                      port0 {
                                bridge_out: endpoint {
                                        remote-endpoint = <&panel_in>;
                                };
                        };
  
 -                      port@1 {
 +                      port1 {
                                bridge_in: endpoint {
                                        remote-endpoint = <&dp_out>;
                                };
index 273d66282ebcaf0ac2f5e8e0aa47e6792dc54807,c607bed575d95c772bf42fb4ed4bdf69a1dc5be0..ac291f540812e813eebd67fc26e6a0e9b1e39ec0
        pinctrl-names = "default";
        pinctrl-0 = <&dp_hpd_gpio>;
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <1>;
-       samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+       hpd-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>;
  };
  
  &ehci {
        samsung,i2c-sda-delay = <100>;
        samsung,i2c-max-bus-freq = <66000>;
  
 -      cros_ec: embedded-controller {
 +      cros_ec: embedded-controller@1e {
                compatible = "google,cros-ec-i2c";
                reg = <0x1e>;
                interrupts = <6 IRQ_TYPE_NONE>;
index 8811e170c2afb7c970a855bee8368ae450b5292c,7ddb6a066b28ec2aa5a792ccae234d9cc7171d7e..f9d2e4f1a0e09598de0ad852bec24996b7373c56
        pinctrl-names = "default";
        pinctrl-0 = <&dp_hpd_gpio>;
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x06>;
        samsung,lane-count = <2>;
-       samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+       hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
  
        ports {
 -              port@0 {
 +              port0 {
                        dp_out: endpoint {
                                remote-endpoint = <&bridge_in>;
                        };
                use-external-pwm;
  
                ports {
 -                      port@0 {
 +                      port0 {
                                bridge_out: endpoint {
                                        remote-endpoint = <&panel_in>;
                                };
                        };
  
 -                      port@1 {
 +                      port1 {
                                bridge_in: endpoint {
                                        remote-endpoint = <&dp_out>;
                                };
        status = "okay";
  };
  
 +&mfc {
 +      samsung,mfc-r = <0x43000000 0x800000>;
 +      samsung,mfc-l = <0x51000000 0x800000>;
 +};
 +
  &mmc_0 {
        status = "okay";
        num-slots = <1>;
index 9b77940c920125dacf2e99f7aba62b19d54b5aaf,288817daa16c28c64a552036faf31854312b9882..2e748d19322f29bdd91fbcc270c97a382234cbf1
        pinctrl-names = "default";
        pinctrl-0 = <&dp_hpd>;
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <4>;
  
        display-timings {
                native-mode = <&timing0>;
 -              timing0: timing@0 {
 +              timing0: timing {
                        clock-frequency = <50000>;
                        hactive = <2560>;
                        vactive = <1600>;
        s2mps11_pmic@66 {
                compatible = "samsung,s2mps11-pmic";
                reg = <0x66>;
 -              s2mps11,buck2-ramp-delay = <12>;
 -              s2mps11,buck34-ramp-delay = <12>;
 -              s2mps11,buck16-ramp-delay = <12>;
 -              s2mps11,buck6-ramp-enable = <1>;
 -              s2mps11,buck2-ramp-enable = <1>;
 -              s2mps11,buck3-ramp-enable = <1>;
 -              s2mps11,buck4-ramp-enable = <1>;
  
                s2mps11_osc: clocks {
                        #clock-cells = <1>;
index f95992520a7749f6b562a8657de4d97ed83b5062,6ba9aec15485560e051666df826ac30a430cb7b0..62ceb89e073f291ff93a133209066b7accb417b9
        pinctrl-names = "default";
        pinctrl-0 = <&dp_hpd_gpio>;
        samsung,color-space = <0>;
-       samsung,dynamic-range = <0>;
-       samsung,ycbcr-coeff = <0>;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <2>;
        status = "okay";
  };
  
 +&mfc {
 +      samsung,mfc-r = <0x43000000 0x800000>;
 +      samsung,mfc-l = <0x51000000 0x800000>;
 +};
 +
  &mmc_0 {
        status = "okay";
        num-slots = <1>;
index d8a9a9c68e98e8b861c821d85ae5c50db107a566,049d00d8ded50a374d8aff20e03e133a1fb89b96..ff6aa5dfb2d7574556f9f8d97310c4c127f1c212
@@@ -796,9 -796,9 +796,9 @@@ int etnaviv_gpu_debugfs(struct etnaviv_
            debug.state[0] == debug.state[1]) {
                seq_puts(m, "seems to be stuck\n");
        } else if (debug.address[0] == debug.address[1]) {
 -              seq_puts(m, "adress is constant\n");
 +              seq_puts(m, "address is constant\n");
        } else {
 -              seq_puts(m, "is runing\n");
 +              seq_puts(m, "is running\n");
        }
  
        seq_printf(m, "\t address 0: 0x%08x\n", debug.address[0]);
@@@ -1528,8 -1528,8 +1528,8 @@@ static int etnaviv_gpu_bind(struct devi
        INIT_WORK(&gpu->recover_work, recover_worker);
        init_waitqueue_head(&gpu->fence_event);
  
-       setup_timer(&gpu->hangcheck_timer, hangcheck_handler,
-                       (unsigned long)gpu);
+       setup_deferrable_timer(&gpu->hangcheck_timer, hangcheck_handler,
+                              (unsigned long)gpu);
  
        priv->gpu[priv->num_gpus++] = gpu;
  
index e3f4c725a1c6910f3431431d9a2dbc538153f025,8b8d6f07d7aad8e7971dd1deeaa628fb0659dde9..32690332d441dc16b7ba51bd641add5e984cc52e
@@@ -89,27 -89,34 +89,34 @@@ static int i915_capabilities(struct seq
        return 0;
  }
  
- static const char *get_pin_flag(struct drm_i915_gem_object *obj)
+ static const char get_active_flag(struct drm_i915_gem_object *obj)
  {
-       if (obj->pin_display)
-               return "p";
-       else
-               return " ";
+       return obj->active ? '*' : ' ';
+ }
+ static const char get_pin_flag(struct drm_i915_gem_object *obj)
+ {
+       return obj->pin_display ? 'p' : ' ';
  }
  
- static const char *get_tiling_flag(struct drm_i915_gem_object *obj)
+ static const char get_tiling_flag(struct drm_i915_gem_object *obj)
  {
        switch (obj->tiling_mode) {
        default:
-       case I915_TILING_NONE: return " ";
-       case I915_TILING_X: return "X";
-       case I915_TILING_Y: return "Y";
+       case I915_TILING_NONE: return ' ';
+       case I915_TILING_X: return 'X';
+       case I915_TILING_Y: return 'Y';
        }
  }
  
- static inline const char *get_global_flag(struct drm_i915_gem_object *obj)
+ static inline const char get_global_flag(struct drm_i915_gem_object *obj)
+ {
+       return i915_gem_obj_to_ggtt(obj) ? 'g' : ' ';
+ }
+ static inline const char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
  {
-       return i915_gem_obj_to_ggtt(obj) ? "g" : " ";
+       return obj->mapping ? 'M' : ' ';
  }
  
  static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
@@@ -129,23 -136,26 +136,26 @@@ static voi
  describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
  {
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct i915_vma *vma;
        int pin_count = 0;
-       int i;
+       enum intel_engine_id id;
  
-       seq_printf(m, "%pK: %s%s%s%s %8zdKiB %02x %02x [ ",
+       lockdep_assert_held(&obj->base.dev->struct_mutex);
+       seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x [ ",
                   &obj->base,
-                  obj->active ? "*" : " ",
+                  get_active_flag(obj),
                   get_pin_flag(obj),
                   get_tiling_flag(obj),
                   get_global_flag(obj),
+                  get_pin_mapped_flag(obj),
                   obj->base.size / 1024,
                   obj->base.read_domains,
                   obj->base.write_domain);
-       for_each_ring(ring, dev_priv, i)
+       for_each_engine_id(engine, dev_priv, id)
                seq_printf(m, "%x ",
-                               i915_gem_request_get_seqno(obj->last_read_req[i]));
+                               i915_gem_request_get_seqno(obj->last_read_req[id]));
        seq_printf(m, "] %x %x%s%s%s",
                   i915_gem_request_get_seqno(obj->last_write_req),
                   i915_gem_request_get_seqno(obj->last_fenced_req),
        }
        if (obj->last_write_req != NULL)
                seq_printf(m, " (%s)",
-                          i915_gem_request_get_ring(obj->last_write_req)->name);
+                          i915_gem_request_get_engine(obj->last_write_req)->name);
        if (obj->frontbuffer_bits)
                seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
  }
@@@ -202,8 -212,8 +212,8 @@@ static int i915_gem_object_list_info(st
        uintptr_t list = (uintptr_t) node->info_ent->data;
        struct list_head *head;
        struct drm_device *dev = node->minor->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct i915_address_space *vm = &dev_priv->gtt.base;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct i915_vma *vma;
        u64 total_obj_size, total_gtt_size;
        int count, ret;
        switch (list) {
        case ACTIVE_LIST:
                seq_puts(m, "Active:\n");
-               head = &vm->active_list;
+               head = &ggtt->base.active_list;
                break;
        case INACTIVE_LIST:
                seq_puts(m, "Inactive:\n");
-               head = &vm->inactive_list;
+               head = &ggtt->base.inactive_list;
                break;
        default:
                mutex_unlock(&dev->struct_mutex);
@@@ -397,15 -407,15 +407,15 @@@ static void print_batch_pool_stats(stru
  {
        struct drm_i915_gem_object *obj;
        struct file_stats stats;
-       struct intel_engine_cs *ring;
-       int i, j;
+       struct intel_engine_cs *engine;
+       int j;
  
        memset(&stats, 0, sizeof(stats));
  
-       for_each_ring(ring, dev_priv, i) {
-               for (j = 0; j < ARRAY_SIZE(ring->batch_pool.cache_list); j++) {
+       for_each_engine(engine, dev_priv) {
+               for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
                        list_for_each_entry(obj,
-                                           &ring->batch_pool.cache_list[j],
+                                           &engine->batch_pool.cache_list[j],
                                            batch_pool_link)
                                per_file_stats(0, obj, &stats);
                }
@@@ -429,11 -439,13 +439,13 @@@ static int i915_gem_object_info(struct 
  {
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        u32 count, mappable_count, purgeable_count;
        u64 size, mappable_size, purgeable_size;
+       unsigned long pin_mapped_count = 0, pin_mapped_purgeable_count = 0;
+       u64 pin_mapped_size = 0, pin_mapped_purgeable_size = 0;
        struct drm_i915_gem_object *obj;
-       struct i915_address_space *vm = &dev_priv->gtt.base;
        struct drm_file *file;
        struct i915_vma *vma;
        int ret;
                   count, mappable_count, size, mappable_size);
  
        size = count = mappable_size = mappable_count = 0;
-       count_vmas(&vm->active_list, vm_link);
+       count_vmas(&ggtt->base.active_list, vm_link);
        seq_printf(m, "  %u [%u] active objects, %llu [%llu] bytes\n",
                   count, mappable_count, size, mappable_size);
  
        size = count = mappable_size = mappable_count = 0;
-       count_vmas(&vm->inactive_list, vm_link);
+       count_vmas(&ggtt->base.inactive_list, vm_link);
        seq_printf(m, "  %u [%u] inactive objects, %llu [%llu] bytes\n",
                   count, mappable_count, size, mappable_size);
  
                size += obj->base.size, ++count;
                if (obj->madv == I915_MADV_DONTNEED)
                        purgeable_size += obj->base.size, ++purgeable_count;
+               if (obj->mapping) {
+                       pin_mapped_count++;
+                       pin_mapped_size += obj->base.size;
+                       if (obj->pages_pin_count == 0) {
+                               pin_mapped_purgeable_count++;
+                               pin_mapped_purgeable_size += obj->base.size;
+                       }
+               }
        }
        seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);
  
                        purgeable_size += obj->base.size;
                        ++purgeable_count;
                }
+               if (obj->mapping) {
+                       pin_mapped_count++;
+                       pin_mapped_size += obj->base.size;
+                       if (obj->pages_pin_count == 0) {
+                               pin_mapped_purgeable_count++;
+                               pin_mapped_purgeable_size += obj->base.size;
+                       }
+               }
        }
        seq_printf(m, "%u purgeable objects, %llu bytes\n",
                   purgeable_count, purgeable_size);
                   mappable_count, mappable_size);
        seq_printf(m, "%u fault mappable objects, %llu bytes\n",
                   count, size);
+       seq_printf(m,
+                  "%lu [%lu] pin mapped objects, %llu [%llu] bytes [purgeable]\n",
+                  pin_mapped_count, pin_mapped_purgeable_count,
+                  pin_mapped_size, pin_mapped_purgeable_size);
  
        seq_printf(m, "%llu [%llu] gtt total\n",
-                  dev_priv->gtt.base.total,
-                  (u64)dev_priv->gtt.mappable_end - dev_priv->gtt.base.start);
+                  ggtt->base.total, ggtt->mappable_end - ggtt->base.start);
  
        seq_putc(m, '\n');
        print_batch_pool_stats(m, dev_priv);
+       mutex_unlock(&dev->struct_mutex);
+       mutex_lock(&dev->filelist_mutex);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct file_stats stats;
                struct task_struct *task;
                print_file_stats(m, task ? task->comm : "<unknown>", stats);
                rcu_read_unlock();
        }
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->filelist_mutex);
  
        return 0;
  }
@@@ -591,14 -625,13 +625,13 @@@ static int i915_gem_pageflip_info(struc
                                           pipe, plane);
                        }
                        if (work->flip_queued_req) {
-                               struct intel_engine_cs *ring =
-                                       i915_gem_request_get_ring(work->flip_queued_req);
+                               struct intel_engine_cs *engine = i915_gem_request_get_engine(work->flip_queued_req);
  
                                seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n",
-                                          ring->name,
+                                          engine->name,
                                           i915_gem_request_get_seqno(work->flip_queued_req),
                                           dev_priv->next_seqno,
-                                          ring->get_seqno(ring, true),
+                                          engine->get_seqno(engine),
                                           i915_gem_request_completed(work->flip_queued_req, true));
                        } else
                                seq_printf(m, "Flip not associated with any ring\n");
@@@ -637,28 -670,28 +670,28 @@@ static int i915_gem_batch_pool_info(str
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        int total = 0;
-       int ret, i, j;
+       int ret, j;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
                return ret;
  
-       for_each_ring(ring, dev_priv, i) {
-               for (j = 0; j < ARRAY_SIZE(ring->batch_pool.cache_list); j++) {
+       for_each_engine(engine, dev_priv) {
+               for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
                        int count;
  
                        count = 0;
                        list_for_each_entry(obj,
-                                           &ring->batch_pool.cache_list[j],
+                                           &engine->batch_pool.cache_list[j],
                                            batch_pool_link)
                                count++;
                        seq_printf(m, "%s cache[%d]: %d objects\n",
-                                  ring->name, j, count);
+                                  engine->name, j, count);
  
                        list_for_each_entry(obj,
-                                           &ring->batch_pool.cache_list[j],
+                                           &engine->batch_pool.cache_list[j],
                                            batch_pool_link) {
                                seq_puts(m, "   ");
                                describe_obj(m, obj);
@@@ -681,26 -714,26 +714,26 @@@ static int i915_gem_request_info(struc
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct drm_i915_gem_request *req;
-       int ret, any, i;
+       int ret, any;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
                return ret;
  
        any = 0;
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                int count;
  
                count = 0;
-               list_for_each_entry(req, &ring->request_list, list)
+               list_for_each_entry(req, &engine->request_list, list)
                        count++;
                if (count == 0)
                        continue;
  
-               seq_printf(m, "%s requests: %d\n", ring->name, count);
-               list_for_each_entry(req, &ring->request_list, list) {
+               seq_printf(m, "%s requests: %d\n", engine->name, count);
+               list_for_each_entry(req, &engine->request_list, list) {
                        struct task_struct *task;
  
                        rcu_read_lock();
  }
  
  static void i915_ring_seqno_info(struct seq_file *m,
-                                struct intel_engine_cs *ring)
+                                struct intel_engine_cs *engine)
  {
-       if (ring->get_seqno) {
-               seq_printf(m, "Current sequence (%s): %x\n",
-                          ring->name, ring->get_seqno(ring, false));
-       }
+       seq_printf(m, "Current sequence (%s): %x\n",
+                  engine->name, engine->get_seqno(engine));
+       seq_printf(m, "Current user interrupts (%s): %x\n",
+                  engine->name, READ_ONCE(engine->user_interrupts));
  }
  
  static int i915_gem_seqno_info(struct seq_file *m, void *data)
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int ret, i;
+       struct intel_engine_cs *engine;
+       int ret;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
                return ret;
        intel_runtime_pm_get(dev_priv);
  
-       for_each_ring(ring, dev_priv, i)
-               i915_ring_seqno_info(m, ring);
+       for_each_engine(engine, dev_priv)
+               i915_ring_seqno_info(m, engine);
  
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
@@@ -762,7 -795,7 +795,7 @@@ static int i915_interrupt_info(struct s
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        int ret, i, pipe;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
                seq_printf(m, "Graphics Interrupt mask:         %08x\n",
                           I915_READ(GTIMR));
        }
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                if (INTEL_INFO(dev)->gen >= 6) {
                        seq_printf(m,
                                   "Graphics Interrupt mask (%s):       %08x\n",
-                                  ring->name, I915_READ_IMR(ring));
+                                  engine->name, I915_READ_IMR(engine));
                }
-               i915_ring_seqno_info(m, ring);
+               i915_ring_seqno_info(m, engine);
        }
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
@@@ -981,12 -1014,12 +1014,12 @@@ static int i915_hws_info(struct seq_fil
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        const u32 *hws;
        int i;
  
-       ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];
-       hws = ring->status_page.page_addr;
+       engine = &dev_priv->engine[(uintptr_t)node->info_ent->data];
+       hws = engine->status_page.page_addr;
        if (hws == NULL)
                return 0;
  
@@@ -1216,12 -1249,12 +1249,12 @@@ static int i915_frequency_info(struct s
                rpdeclimit = I915_READ(GEN6_RP_DOWN_THRESHOLD);
  
                rpstat = I915_READ(GEN6_RPSTAT1);
-               rpupei = I915_READ(GEN6_RP_CUR_UP_EI);
-               rpcurup = I915_READ(GEN6_RP_CUR_UP);
-               rpprevup = I915_READ(GEN6_RP_PREV_UP);
-               rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI);
-               rpcurdown = I915_READ(GEN6_RP_CUR_DOWN);
-               rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
+               rpupei = I915_READ(GEN6_RP_CUR_UP_EI) & GEN6_CURICONT_MASK;
+               rpcurup = I915_READ(GEN6_RP_CUR_UP) & GEN6_CURBSYTAVG_MASK;
+               rpprevup = I915_READ(GEN6_RP_PREV_UP) & GEN6_CURBSYTAVG_MASK;
+               rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
+               rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
+               rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
                if (IS_GEN9(dev))
                        cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
                else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
                seq_printf(m, "RPDECLIMIT: 0x%08x\n", rpdeclimit);
                seq_printf(m, "RPNSWREQ: %dMHz\n", reqf);
                seq_printf(m, "CAGF: %dMHz\n", cagf);
-               seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
-                          GEN6_CURICONT_MASK);
-               seq_printf(m, "RP CUR UP: %dus\n", rpcurup &
-                          GEN6_CURBSYTAVG_MASK);
-               seq_printf(m, "RP PREV UP: %dus\n", rpprevup &
-                          GEN6_CURBSYTAVG_MASK);
+               seq_printf(m, "RP CUR UP EI: %d (%dus)\n",
+                          rpupei, GT_PM_INTERVAL_TO_US(dev_priv, rpupei));
+               seq_printf(m, "RP CUR UP: %d (%dus)\n",
+                          rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
+               seq_printf(m, "RP PREV UP: %d (%dus)\n",
+                          rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
                seq_printf(m, "Up threshold: %d%%\n",
                           dev_priv->rps.up_threshold);
  
-               seq_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei &
-                          GEN6_CURIAVG_MASK);
-               seq_printf(m, "RP CUR DOWN: %dus\n", rpcurdown &
-                          GEN6_CURBSYTAVG_MASK);
-               seq_printf(m, "RP PREV DOWN: %dus\n", rpprevdown &
-                          GEN6_CURBSYTAVG_MASK);
+               seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
+                          rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
+               seq_printf(m, "RP CUR DOWN: %d (%dus)\n",
+                          rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
+               seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
+                          rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
                seq_printf(m, "Down threshold: %d%%\n",
                           dev_priv->rps.down_threshold);
  
@@@ -1331,11 -1364,12 +1364,12 @@@ static int i915_hangcheck_info(struct s
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       u64 acthd[I915_NUM_RINGS];
-       u32 seqno[I915_NUM_RINGS];
+       struct intel_engine_cs *engine;
+       u64 acthd[I915_NUM_ENGINES];
+       u32 seqno[I915_NUM_ENGINES];
        u32 instdone[I915_NUM_INSTDONE_REG];
-       int i, j;
+       enum intel_engine_id id;
+       int j;
  
        if (!i915.enable_hangcheck) {
                seq_printf(m, "Hangcheck disabled\n");
  
        intel_runtime_pm_get(dev_priv);
  
-       for_each_ring(ring, dev_priv, i) {
-               seqno[i] = ring->get_seqno(ring, false);
-               acthd[i] = intel_ring_get_active_head(ring);
+       for_each_engine_id(engine, dev_priv, id) {
+               acthd[id] = intel_ring_get_active_head(engine);
+               seqno[id] = engine->get_seqno(engine);
        }
  
        i915_get_extra_instdone(dev, instdone);
        } else
                seq_printf(m, "Hangcheck inactive\n");
  
-       for_each_ring(ring, dev_priv, i) {
-               seq_printf(m, "%s:\n", ring->name);
-               seq_printf(m, "\tseqno = %x [current %x]\n",
-                          ring->hangcheck.seqno, seqno[i]);
+       for_each_engine_id(engine, dev_priv, id) {
+               seq_printf(m, "%s:\n", engine->name);
+               seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
+                          engine->hangcheck.seqno,
+                          seqno[id],
+                          engine->last_submitted_seqno);
+               seq_printf(m, "\tuser interrupts = %x [current %x]\n",
+                          engine->hangcheck.user_interrupts,
+                          READ_ONCE(engine->user_interrupts));
                seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n",
-                          (long long)ring->hangcheck.acthd,
-                          (long long)acthd[i]);
-               seq_printf(m, "\tmax ACTHD = 0x%08llx\n",
-                          (long long)ring->hangcheck.max_acthd);
-               seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
-               seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
-               if (ring->id == RCS) {
+                          (long long)engine->hangcheck.acthd,
+                          (long long)acthd[id]);
+               seq_printf(m, "\tscore = %d\n", engine->hangcheck.score);
+               seq_printf(m, "\taction = %d\n", engine->hangcheck.action);
+               if (engine->id == RCS) {
                        seq_puts(m, "\tinstdone read =");
  
                        for (j = 0; j < I915_NUM_INSTDONE_REG; j++)
  
                        for (j = 0; j < I915_NUM_INSTDONE_REG; j++)
                                seq_printf(m, " 0x%08x",
-                                          ring->hangcheck.instdone[j]);
+                                          engine->hangcheck.instdone[j]);
  
                        seq_puts(m, "\n");
                }
@@@ -1465,12 -1502,11 +1502,11 @@@ static int i915_forcewake_domains(struc
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_uncore_forcewake_domain *fw_domain;
-       int i;
  
        spin_lock_irq(&dev_priv->uncore.lock);
-       for_each_fw_domain(fw_domain, dev_priv, i) {
+       for_each_fw_domain(fw_domain, dev_priv) {
                seq_printf(m, "%s.wake_count = %u\n",
-                          intel_uncore_forcewake_domain_to_str(i),
+                          intel_uncore_forcewake_domain_to_str(fw_domain->id),
                           fw_domain->wake_count);
        }
        spin_unlock_irq(&dev_priv->uncore.lock);
@@@ -1897,6 -1933,11 +1933,11 @@@ static int i915_gem_framebuffer_info(st
        struct drm_device *dev = node->minor->dev;
        struct intel_framebuffer *fbdev_fb = NULL;
        struct drm_framebuffer *drm_fb;
+       int ret;
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
  
  #ifdef CONFIG_DRM_FBDEV_EMULATION
         if (to_i915(dev)->fbdev) {
                           fbdev_fb->base.depth,
                           fbdev_fb->base.bits_per_pixel,
                           fbdev_fb->base.modifier[0],
-                          atomic_read(&fbdev_fb->base.refcount.refcount));
+                          drm_framebuffer_read_refcount(&fbdev_fb->base));
                 describe_obj(m, fbdev_fb->obj);
                 seq_putc(m, '\n');
         }
                           fb->base.depth,
                           fb->base.bits_per_pixel,
                           fb->base.modifier[0],
-                          atomic_read(&fb->base.refcount.refcount));
+                          drm_framebuffer_read_refcount(&fb->base));
                describe_obj(m, fb->obj);
                seq_putc(m, '\n');
        }
        mutex_unlock(&dev->mode_config.fb_lock);
+       mutex_unlock(&dev->struct_mutex);
  
        return 0;
  }
@@@ -1948,9 -1990,10 +1990,10 @@@ static int i915_context_status(struct s
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct intel_context *ctx;
-       int ret, i;
+       enum intel_engine_id id;
+       int ret;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
  
                if (i915.enable_execlists) {
                        seq_putc(m, '\n');
-                       for_each_ring(ring, dev_priv, i) {
+                       for_each_engine_id(engine, dev_priv, id) {
                                struct drm_i915_gem_object *ctx_obj =
-                                       ctx->engine[i].state;
+                                       ctx->engine[id].state;
                                struct intel_ringbuffer *ringbuf =
-                                       ctx->engine[i].ringbuf;
+                                       ctx->engine[id].ringbuf;
  
-                               seq_printf(m, "%s: ", ring->name);
+                               seq_printf(m, "%s: ", engine->name);
                                if (ctx_obj)
                                        describe_obj(m, ctx_obj);
                                if (ringbuf)
  
  static void i915_dump_lrc_obj(struct seq_file *m,
                              struct intel_context *ctx,
-                             struct intel_engine_cs *ring)
+                             struct intel_engine_cs *engine)
  {
        struct page *page;
        uint32_t *reg_state;
        int j;
-       struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state;
+       struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
        unsigned long ggtt_offset = 0;
  
        if (ctx_obj == NULL) {
                seq_printf(m, "Context on %s with no gem object\n",
-                          ring->name);
+                          engine->name);
                return;
        }
  
-       seq_printf(m, "CONTEXT: %s %u\n", ring->name,
-                  intel_execlists_ctx_id(ctx, ring));
+       seq_printf(m, "CONTEXT: %s %u\n", engine->name,
+                  intel_execlists_ctx_id(ctx, engine));
  
        if (!i915_gem_obj_ggtt_bound(ctx_obj))
                seq_puts(m, "\tNot bound in GGTT\n");
@@@ -2043,9 -2086,9 +2086,9 @@@ static int i915_dump_lrc(struct seq_fil
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct intel_context *ctx;
-       int ret, i;
+       int ret;
  
        if (!i915.enable_execlists) {
                seq_printf(m, "Logical Ring Contexts are disabled\n");
  
        list_for_each_entry(ctx, &dev_priv->context_list, link)
                if (ctx != dev_priv->kernel_context)
-                       for_each_ring(ring, dev_priv, i)
-                               i915_dump_lrc_obj(m, ctx, ring);
+                       for_each_engine(engine, dev_priv)
+                               i915_dump_lrc_obj(m, ctx, engine);
  
        mutex_unlock(&dev->struct_mutex);
  
@@@ -2071,15 -2114,14 +2114,14 @@@ static int i915_execlists(struct seq_fi
        struct drm_info_node *node = (struct drm_info_node *)m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        u32 status_pointer;
        u8 read_pointer;
        u8 write_pointer;
        u32 status;
        u32 ctx_id;
        struct list_head *cursor;
-       int ring_id, i;
-       int ret;
+       int i, ret;
  
        if (!i915.enable_execlists) {
                seq_puts(m, "Logical Ring Contexts are disabled\n");
  
        intel_runtime_pm_get(dev_priv);
  
-       for_each_ring(ring, dev_priv, ring_id) {
+       for_each_engine(engine, dev_priv) {
                struct drm_i915_gem_request *head_req = NULL;
                int count = 0;
-               unsigned long flags;
  
-               seq_printf(m, "%s\n", ring->name);
+               seq_printf(m, "%s\n", engine->name);
  
-               status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
-               ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
+               status = I915_READ(RING_EXECLIST_STATUS_LO(engine));
+               ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(engine));
                seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n",
                           status, ctx_id);
  
-               status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
+               status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
                seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer);
  
-               read_pointer = ring->next_context_status_buffer;
+               read_pointer = engine->next_context_status_buffer;
                write_pointer = GEN8_CSB_WRITE_PTR(status_pointer);
                if (read_pointer > write_pointer)
                        write_pointer += GEN8_CSB_ENTRIES;
                           read_pointer, write_pointer);
  
                for (i = 0; i < GEN8_CSB_ENTRIES; i++) {
-                       status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i));
-                       ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i));
+                       status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, i));
+                       ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, i));
  
                        seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n",
                                   i, status, ctx_id);
                }
  
-               spin_lock_irqsave(&ring->execlist_lock, flags);
-               list_for_each(cursor, &ring->execlist_queue)
+               spin_lock_bh(&engine->execlist_lock);
+               list_for_each(cursor, &engine->execlist_queue)
                        count++;
-               head_req = list_first_entry_or_null(&ring->execlist_queue,
-                               struct drm_i915_gem_request, execlist_link);
-               spin_unlock_irqrestore(&ring->execlist_lock, flags);
+               head_req = list_first_entry_or_null(&engine->execlist_queue,
+                                                   struct drm_i915_gem_request,
+                                                   execlist_link);
+               spin_unlock_bh(&engine->execlist_lock);
  
                seq_printf(m, "\t%d requests in queue\n", count);
                if (head_req) {
                        seq_printf(m, "\tHead request id: %u\n",
-                                  intel_execlists_ctx_id(head_req->ctx, ring));
+                                  intel_execlists_ctx_id(head_req->ctx, engine));
                        seq_printf(m, "\tHead request tail: %u\n",
                                   head_req->tail);
                }
@@@ -2248,19 -2290,19 +2290,19 @@@ static int per_file_ctx(int id, void *p
  static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
-       int unused, i;
+       int i;
  
        if (!ppgtt)
                return;
  
-       for_each_ring(ring, dev_priv, unused) {
-               seq_printf(m, "%s\n", ring->name);
+       for_each_engine(engine, dev_priv) {
+               seq_printf(m, "%s\n", engine->name);
                for (i = 0; i < 4; i++) {
-                       u64 pdp = I915_READ(GEN8_RING_PDP_UDW(ring, i));
+                       u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i));
                        pdp <<= 32;
-                       pdp |= I915_READ(GEN8_RING_PDP_LDW(ring, i));
+                       pdp |= I915_READ(GEN8_RING_PDP_LDW(engine, i));
                        seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp);
                }
        }
  static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int i;
+       struct intel_engine_cs *engine;
  
        if (INTEL_INFO(dev)->gen == 6)
                seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
  
-       for_each_ring(ring, dev_priv, i) {
-               seq_printf(m, "%s\n", ring->name);
+       for_each_engine(engine, dev_priv) {
+               seq_printf(m, "%s\n", engine->name);
                if (INTEL_INFO(dev)->gen == 7)
-                       seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
-               seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring)));
-               seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring)));
-               seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring)));
+                       seq_printf(m, "GFX_MODE: 0x%08x\n",
+                                  I915_READ(RING_MODE_GEN7(engine)));
+               seq_printf(m, "PP_DIR_BASE: 0x%08x\n",
+                          I915_READ(RING_PP_DIR_BASE(engine)));
+               seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n",
+                          I915_READ(RING_PP_DIR_BASE_READ(engine)));
+               seq_printf(m, "PP_DIR_DCLV: 0x%08x\n",
+                          I915_READ(RING_PP_DIR_DCLV(engine)));
        }
        if (dev_priv->mm.aliasing_ppgtt) {
                struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
@@@ -2312,6 -2357,7 +2357,7 @@@ static int i915_ppgtt_info(struct seq_f
        else if (INTEL_INFO(dev)->gen >= 6)
                gen6_ppgtt_info(m, dev);
  
+       mutex_lock(&dev->filelist_mutex);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct drm_i915_file_private *file_priv = file->driver_priv;
                struct task_struct *task;
                idr_for_each(&file_priv->context_idr, per_file_ctx,
                             (void *)(unsigned long)m);
        }
+       mutex_unlock(&dev->filelist_mutex);
  
  out_put:
        intel_runtime_pm_put(dev_priv);
  
  static int count_irq_waiters(struct drm_i915_private *i915)
  {
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        int count = 0;
-       int i;
  
-       for_each_ring(ring, i915, i)
-               count += ring->irq_refcount;
+       for_each_engine(engine, i915)
+               count += engine->irq_refcount;
  
        return count;
  }
@@@ -2362,6 -2408,8 +2408,8 @@@ static int i915_rps_boost_info(struct s
                   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit),
                   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit),
                   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+       mutex_lock(&dev->filelist_mutex);
        spin_lock(&dev_priv->rps.client_lock);
        list_for_each_entry_reverse(file, &dev->filelist, lhead) {
                struct drm_i915_file_private *file_priv = file->driver_priv;
                   list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active");
        seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts);
        spin_unlock(&dev_priv->rps.client_lock);
+       mutex_unlock(&dev->filelist_mutex);
  
        return 0;
  }
@@@ -2393,10 -2442,11 +2442,11 @@@ static int i915_llc(struct seq_file *m
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       const bool edram = INTEL_GEN(dev_priv) > 8;
  
-       /* Size calculation for LLC is a bit of a pain. Ignore for now. */
        seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev)));
-       seq_printf(m, "eLLC: %zuMB\n", dev_priv->ellc_size);
+       seq_printf(m, "%s: %lluMB\n", edram ? "eDRAM" : "eLLC",
+                  intel_uncore_edram_size(dev_priv)/1024/1024);
  
        return 0;
  }
@@@ -2408,7 -2458,7 +2458,7 @@@ static int i915_guc_load_status_info(st
        struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
        u32 tmp, i;
  
-       if (!HAS_GUC_UCODE(dev_priv->dev))
+       if (!HAS_GUC_UCODE(dev_priv))
                return 0;
  
        seq_printf(m, "GuC firmware status:\n");
@@@ -2449,9 -2499,8 +2499,8 @@@ static void i915_guc_client_info(struc
                                 struct drm_i915_private *dev_priv,
                                 struct i915_guc_client *client)
  {
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        uint64_t tot = 0;
-       uint32_t i;
  
        seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n",
                client->priority, client->ctx_index, client->proc_desc_offset);
        seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
        seq_printf(m, "\tLast submission result: %d\n", client->retcode);
  
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                seq_printf(m, "\tSubmissions: %llu %s\n",
-                               client->submissions[ring->guc_id],
-                               ring->name);
-               tot += client->submissions[ring->guc_id];
+                               client->submissions[engine->guc_id],
+                               engine->name);
+               tot += client->submissions[engine->guc_id];
        }
        seq_printf(m, "\tTotal: %llu\n", tot);
  }
@@@ -2480,11 -2529,10 +2529,10 @@@ static int i915_guc_info(struct seq_fil
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_guc guc;
        struct i915_guc_client client = {};
-       struct intel_engine_cs *ring;
-       enum intel_ring_id i;
+       struct intel_engine_cs *engine;
        u64 total = 0;
  
-       if (!HAS_GUC_SCHED(dev_priv->dev))
+       if (!HAS_GUC_SCHED(dev_priv))
                return 0;
  
        if (mutex_lock_interruptible(&dev->struct_mutex))
        seq_printf(m, "GuC last action error code: %d\n", guc.action_err);
  
        seq_printf(m, "\nGuC submissions:\n");
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
-                       ring->name, guc.submissions[ring->guc_id],
-                       guc.last_seqno[ring->guc_id]);
-               total += guc.submissions[ring->guc_id];
+                       engine->name, guc.submissions[engine->guc_id],
+                       guc.last_seqno[engine->guc_id]);
+               total += guc.submissions[engine->guc_id];
        }
        seq_printf(m, "\t%s: %llu\n", "Total", total);
  
@@@ -2688,10 -2736,8 +2736,8 @@@ static int i915_runtime_pm_status(struc
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       if (!HAS_RUNTIME_PM(dev)) {
-               seq_puts(m, "not supported\n");
-               return 0;
-       }
+       if (!HAS_RUNTIME_PM(dev_priv))
+               seq_puts(m, "Runtime power management not supported\n");
  
        seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy));
        seq_printf(m, "IRQs disabled: %s\n",
  #else
        seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n");
  #endif
+       seq_printf(m, "PCI device power state: %s [%d]\n",
+                  pci_power_name(dev_priv->dev->pdev->current_state),
+                  dev_priv->dev->pdev->current_state);
  
        return 0;
  }
@@@ -2872,6 -2921,20 +2921,6 @@@ static void intel_dp_info(struct seq_fi
                intel_panel_info(m, &intel_connector->panel);
  }
  
 -static void intel_dp_mst_info(struct seq_file *m,
 -                        struct intel_connector *intel_connector)
 -{
 -      struct intel_encoder *intel_encoder = intel_connector->encoder;
 -      struct intel_dp_mst_encoder *intel_mst =
 -              enc_to_mst(&intel_encoder->base);
 -      struct intel_digital_port *intel_dig_port = intel_mst->primary;
 -      struct intel_dp *intel_dp = &intel_dig_port->dp;
 -      bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr,
 -                                      intel_connector->port);
 -
 -      seq_printf(m, "\taudio support: %s\n", yesno(has_audio));
 -}
 -
  static void intel_hdmi_info(struct seq_file *m,
                            struct intel_connector *intel_connector)
  {
@@@ -2915,6 -2978,8 +2964,6 @@@ static void intel_connector_info(struc
                        intel_hdmi_info(m, intel_connector);
                else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
                        intel_lvds_info(m, intel_connector);
 -              else if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
 -                      intel_dp_mst_info(m, intel_connector);
        }
  
        seq_printf(m, "\tmodes:\n");
@@@ -3114,9 -3179,10 +3163,10 @@@ static int i915_semaphore_status(struc
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        int num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
-       int i, j, ret;
+       enum intel_engine_id id;
+       int j, ret;
  
        if (!i915_semaphore_is_enabled(dev)) {
                seq_puts(m, "Semaphores are disabled\n");
                page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
  
                seqno = (uint64_t *)kmap_atomic(page);
-               for_each_ring(ring, dev_priv, i) {
+               for_each_engine_id(engine, dev_priv, id) {
                        uint64_t offset;
  
-                       seq_printf(m, "%s\n", ring->name);
+                       seq_printf(m, "%s\n", engine->name);
  
                        seq_puts(m, "  Last signal:");
                        for (j = 0; j < num_rings; j++) {
-                               offset = i * I915_NUM_RINGS + j;
+                               offset = id * I915_NUM_ENGINES + j;
                                seq_printf(m, "0x%08llx (0x%02llx) ",
                                           seqno[offset], offset * 8);
                        }
  
                        seq_puts(m, "  Last wait:  ");
                        for (j = 0; j < num_rings; j++) {
-                               offset = i + (j * I915_NUM_RINGS);
+                               offset = id + (j * I915_NUM_ENGINES);
                                seq_printf(m, "0x%08llx (0x%02llx) ",
                                           seqno[offset], offset * 8);
                        }
                kunmap_atomic(seqno);
        } else {
                seq_puts(m, "  Last signal:");
-               for_each_ring(ring, dev_priv, i)
+               for_each_engine(engine, dev_priv)
                        for (j = 0; j < num_rings; j++)
                                seq_printf(m, "0x%08x\n",
-                                          I915_READ(ring->semaphore.mbox.signal[j]));
+                                          I915_READ(engine->semaphore.mbox.signal[j]));
                seq_putc(m, '\n');
        }
  
        seq_puts(m, "\nSync seqno:\n");
-       for_each_ring(ring, dev_priv, i) {
-               for (j = 0; j < num_rings; j++) {
-                       seq_printf(m, "  0x%08x ", ring->semaphore.sync_seqno[j]);
-               }
+       for_each_engine(engine, dev_priv) {
+               for (j = 0; j < num_rings; j++)
+                       seq_printf(m, "  0x%08x ",
+                                  engine->semaphore.sync_seqno[j]);
                seq_putc(m, '\n');
        }
        seq_putc(m, '\n');
@@@ -3193,8 -3259,8 +3243,8 @@@ static int i915_shared_dplls_info(struc
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
  
                seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id);
-               seq_printf(m, " crtc_mask: 0x%08x, active: %d, on: %s\n",
-                          pll->config.crtc_mask, pll->active, yesno(pll->on));
+               seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n",
+                          pll->config.crtc_mask, pll->active_mask, yesno(pll->on));
                seq_printf(m, " tracked hardware state:\n");
                seq_printf(m, " dpll:    0x%08x\n", pll->config.hw_state.dpll);
                seq_printf(m, " dpll_md: 0x%08x\n",
@@@ -3212,11 -3278,12 +3262,12 @@@ static int i915_wa_registers(struct seq
  {
        int i;
        int ret;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_workarounds *workarounds = &dev_priv->workarounds;
+       enum intel_engine_id id;
  
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
        intel_runtime_pm_get(dev_priv);
  
        seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
-       for_each_ring(ring, dev_priv, i)
+       for_each_engine_id(engine, dev_priv, id)
                seq_printf(m, "HW whitelist count for %s: %d\n",
-                          ring->name, workarounds->hw_whitelist_count[i]);
+                          engine->name, workarounds->hw_whitelist_count[id]);
        for (i = 0; i < workarounds->count; ++i) {
                i915_reg_t addr;
                u32 mask, value, read;
@@@ -3417,7 -3484,8 +3468,8 @@@ static int i915_dp_mst_info(struct seq_
                intel_dig_port = enc_to_dig_port(encoder);
                if (!intel_dig_port->dp.can_mst)
                        continue;
+               seq_printf(m, "MST Source Port %c\n",
+                          port_name(intel_dig_port->port));
                drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
        }
        drm_modeset_unlock_all(dev);
@@@ -4693,7 -4761,7 +4745,7 @@@ i915_wedged_get(void *data, u64 *val
        struct drm_device *dev = data;
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       *val = atomic_read(&dev_priv->gpu_error.reset_counter);
+       *val = i915_terminally_wedged(&dev_priv->gpu_error);
  
        return 0;
  }
index 5d7a7c4f51362575fe94abeccf0f4808bae5b511,9d7b54ea14f955f8bba4cf30f10011cfb45b9d6f..b87ca4fae20a47d30ef20ff97008ef8222c4f28d
  #include <uapi/drm/i915_drm.h>
  #include <uapi/drm/drm_fourcc.h>
  
- #include <drm/drmP.h>
- #include "i915_params.h"
- #include "i915_reg.h"
- #include "intel_bios.h"
- #include "intel_ringbuffer.h"
- #include "intel_lrc.h"
- #include "i915_gem_gtt.h"
- #include "i915_gem_render_state.h"
  #include <linux/io-mapping.h>
  #include <linux/i2c.h>
  #include <linux/i2c-algo-bit.h>
- #include <drm/intel-gtt.h>
- #include <drm/drm_legacy.h> /* for struct drm_dma_handle */
- #include <drm/drm_gem.h>
  #include <linux/backlight.h>
  #include <linux/hashtable.h>
  #include <linux/intel-iommu.h>
  #include <linux/kref.h>
  #include <linux/pm_qos.h>
+ #include <linux/shmem_fs.h>
+ #include <drm/drmP.h>
+ #include <drm/intel-gtt.h>
+ #include <drm/drm_legacy.h> /* for struct drm_dma_handle */
+ #include <drm/drm_gem.h>
+ #include "i915_params.h"
+ #include "i915_reg.h"
+ #include "intel_bios.h"
+ #include "intel_dpll_mgr.h"
  #include "intel_guc.h"
+ #include "intel_lrc.h"
+ #include "intel_ringbuffer.h"
+ #include "i915_gem.h"
+ #include "i915_gem_gtt.h"
+ #include "i915_gem_render_state.h"
  
  /* General customization:
   */
  
  #define DRIVER_NAME           "i915"
  #define DRIVER_DESC           "Intel Graphics"
- #define DRIVER_DATE           "20160229"
+ #define DRIVER_DATE           "20160425"
  
  #undef WARN_ON
  /* Many gcc seem to no see through this and fall over :( */
  #define I915_STATE_WARN_ON(x)                                         \
        I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
  
+ bool __i915_inject_load_failure(const char *func, int line);
+ #define i915_inject_load_failure() \
+       __i915_inject_load_failure(__func__, __LINE__)
  static inline const char *yesno(bool v)
  {
        return v ? "yes" : "no";
@@@ -122,9 -133,35 +133,35 @@@ enum transcoder 
        TRANSCODER_B,
        TRANSCODER_C,
        TRANSCODER_EDP,
+       TRANSCODER_DSI_A,
+       TRANSCODER_DSI_C,
        I915_MAX_TRANSCODERS
  };
- #define transcoder_name(t) ((t) + 'A')
+ static inline const char *transcoder_name(enum transcoder transcoder)
+ {
+       switch (transcoder) {
+       case TRANSCODER_A:
+               return "A";
+       case TRANSCODER_B:
+               return "B";
+       case TRANSCODER_C:
+               return "C";
+       case TRANSCODER_EDP:
+               return "EDP";
+       case TRANSCODER_DSI_A:
+               return "DSI A";
+       case TRANSCODER_DSI_C:
+               return "DSI C";
+       default:
+               return "<invalid>";
+       }
+ }
+ static inline bool transcoder_is_dsi(enum transcoder transcoder)
+ {
+       return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C;
+ }
  
  /*
   * I915_MAX_PLANES in the enum below is the maximum (across all platforms)
@@@ -176,6 -213,8 +213,8 @@@ enum intel_display_power_domain 
        POWER_DOMAIN_TRANSCODER_B,
        POWER_DOMAIN_TRANSCODER_C,
        POWER_DOMAIN_TRANSCODER_EDP,
+       POWER_DOMAIN_TRANSCODER_DSI_A,
+       POWER_DOMAIN_TRANSCODER_DSI_C,
        POWER_DOMAIN_PORT_DDI_A_LANES,
        POWER_DOMAIN_PORT_DDI_B_LANES,
        POWER_DOMAIN_PORT_DDI_C_LANES,
@@@ -273,6 -312,10 +312,10 @@@ struct i915_hotplug 
             (__s) < INTEL_INFO(__dev_priv)->num_sprites[(__p)];        \
             (__s)++)
  
+ #define for_each_port_masked(__port, __ports_mask) \
+       for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++)  \
+               for_each_if ((__ports_mask) & (1 << (__port)))
  #define for_each_crtc(dev, crtc) \
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
  
@@@ -340,81 -383,6 +383,6 @@@ struct drm_i915_file_private 
        unsigned int bsd_ring;
  };
  
- enum intel_dpll_id {
-       DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
-       /* real shared dpll ids must be >= 0 */
-       DPLL_ID_PCH_PLL_A = 0,
-       DPLL_ID_PCH_PLL_B = 1,
-       /* hsw/bdw */
-       DPLL_ID_WRPLL1 = 0,
-       DPLL_ID_WRPLL2 = 1,
-       DPLL_ID_SPLL = 2,
-       /* skl */
-       DPLL_ID_SKL_DPLL1 = 0,
-       DPLL_ID_SKL_DPLL2 = 1,
-       DPLL_ID_SKL_DPLL3 = 2,
- };
- #define I915_NUM_PLLS 3
- struct intel_dpll_hw_state {
-       /* i9xx, pch plls */
-       uint32_t dpll;
-       uint32_t dpll_md;
-       uint32_t fp0;
-       uint32_t fp1;
-       /* hsw, bdw */
-       uint32_t wrpll;
-       uint32_t spll;
-       /* skl */
-       /*
-        * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
-        * lower part of ctrl1 and they get shifted into position when writing
-        * the register.  This allows us to easily compare the state to share
-        * the DPLL.
-        */
-       uint32_t ctrl1;
-       /* HDMI only, 0 when used for DP */
-       uint32_t cfgcr1, cfgcr2;
-       /* bxt */
-       uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
-                pcsdw12;
- };
- struct intel_shared_dpll_config {
-       unsigned crtc_mask; /* mask of CRTCs sharing this PLL */
-       struct intel_dpll_hw_state hw_state;
- };
- struct intel_shared_dpll {
-       struct intel_shared_dpll_config config;
-       int active; /* count of number of active CRTCs (i.e. DPMS on) */
-       bool on; /* is the PLL actually active? Disabled during modeset */
-       const char *name;
-       /* should match the index in the dev_priv->shared_dplls array */
-       enum intel_dpll_id id;
-       /* The mode_set hook is optional and should be used together with the
-        * intel_prepare_shared_dpll function. */
-       void (*mode_set)(struct drm_i915_private *dev_priv,
-                        struct intel_shared_dpll *pll);
-       void (*enable)(struct drm_i915_private *dev_priv,
-                      struct intel_shared_dpll *pll);
-       void (*disable)(struct drm_i915_private *dev_priv,
-                       struct intel_shared_dpll *pll);
-       bool (*get_hw_state)(struct drm_i915_private *dev_priv,
-                            struct intel_shared_dpll *pll,
-                            struct intel_dpll_hw_state *hw_state);
- };
- #define SKL_DPLL0 0
- #define SKL_DPLL1 1
- #define SKL_DPLL2 2
- #define SKL_DPLL3 3
  /* Used by dp and fdi links */
  struct intel_link_m_n {
        uint32_t        tu;
@@@ -533,7 -501,8 +501,8 @@@ struct drm_i915_error_state 
                u32 cpu_ring_head;
                u32 cpu_ring_tail;
  
-               u32 semaphore_seqno[I915_NUM_RINGS - 1];
+               u32 last_seqno;
+               u32 semaphore_seqno[I915_NUM_ENGINES - 1];
  
                /* Register state */
                u32 start;
                u32 fault_reg;
                u64 faddr;
                u32 rc_psmi; /* sleep state */
-               u32 semaphore_mboxes[I915_NUM_RINGS - 1];
+               u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
  
                struct drm_i915_error_object {
                        int page_count;
                        u32 *pages[0];
                } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
  
+               struct drm_i915_error_object *wa_ctx;
                struct drm_i915_error_request {
                        long jiffies;
                        u32 seqno;
  
                pid_t pid;
                char comm[TASK_COMM_LEN];
-       } ring[I915_NUM_RINGS];
+       } ring[I915_NUM_ENGINES];
  
        struct drm_i915_error_buffer {
                u32 size;
                u32 name;
-               u32 rseqno[I915_NUM_RINGS], wseqno;
+               u32 rseqno[I915_NUM_ENGINES], wseqno;
                u64 gtt_offset;
                u32 read_domains;
                u32 write_domain;
@@@ -611,27 -582,12 +582,12 @@@ struct dpll
  struct drm_i915_display_funcs {
        int (*get_display_clock_speed)(struct drm_device *dev);
        int (*get_fifo_size)(struct drm_device *dev, int plane);
-       /**
-        * find_dpll() - Find the best values for the PLL
-        * @limit: limits for the PLL
-        * @crtc: current CRTC
-        * @target: target frequency in kHz
-        * @refclk: reference clock frequency in kHz
-        * @match_clock: if provided, @best_clock P divider must
-        *               match the P divider from @match_clock
-        *               used for LVDS downclocking
-        * @best_clock: best PLL values found
-        *
-        * Returns true on success, false on failure.
-        */
-       bool (*find_dpll)(const struct intel_limit *limit,
-                         struct intel_crtc_state *crtc_state,
-                         int target, int refclk,
-                         struct dpll *match_clock,
-                         struct dpll *best_clock);
-       int (*compute_pipe_wm)(struct intel_crtc *crtc,
-                              struct drm_atomic_state *state);
-       void (*program_watermarks)(struct intel_crtc_state *cstate);
+       int (*compute_pipe_wm)(struct intel_crtc_state *cstate);
+       int (*compute_intermediate_wm)(struct drm_device *dev,
+                                      struct intel_crtc *intel_crtc,
+                                      struct intel_crtc_state *newstate);
+       void (*initial_watermarks)(struct intel_crtc_state *cstate);
+       void (*optimize_watermarks)(struct intel_crtc_state *cstate);
        void (*update_wm)(struct drm_crtc *crtc);
        int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
        void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
        /* render clock increase/decrease */
        /* display clock increase/decrease */
        /* pll clock increase/decrease */
+       void (*load_csc_matrix)(struct drm_crtc_state *crtc_state);
+       void (*load_luts)(struct drm_crtc_state *crtc_state);
  };
  
  enum forcewake_domain_id {
@@@ -681,6 -640,13 +640,13 @@@ enum forcewake_domains 
                         FORCEWAKE_MEDIA)
  };
  
+ #define FW_REG_READ  (1)
+ #define FW_REG_WRITE (2)
+ enum forcewake_domains
+ intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
+                              i915_reg_t reg, unsigned int op);
  struct intel_uncore_funcs {
        void (*force_wake_get)(struct drm_i915_private *dev_priv,
                                                        enum forcewake_domains domains);
@@@ -713,8 -679,9 +679,9 @@@ struct intel_uncore 
        struct intel_uncore_forcewake_domain {
                struct drm_i915_private *i915;
                enum forcewake_domain_id id;
+               enum forcewake_domains mask;
                unsigned wake_count;
-               struct timer_list timer;
+               struct hrtimer timer;
                i915_reg_t reg_set;
                u32 val_set;
                u32 val_clear;
  };
  
  /* Iterate over initialised fw domains */
- #define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
-       for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
-            (i__) < FW_DOMAIN_ID_COUNT; \
-            (i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
-               for_each_if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
+ #define for_each_fw_domain_masked(domain__, mask__, dev_priv__) \
+       for ((domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
+            (domain__) < &(dev_priv__)->uncore.fw_domain[FW_DOMAIN_ID_COUNT]; \
+            (domain__)++) \
+               for_each_if ((mask__) & (domain__)->mask)
  
- #define for_each_fw_domain(domain__, dev_priv__, i__) \
-       for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
+ #define for_each_fw_domain(domain__, dev_priv__) \
+       for_each_fw_domain_masked(domain__, FORCEWAKE_ALL, dev_priv__)
  
  #define CSR_VERSION(major, minor)     ((major) << 16 | (minor))
  #define CSR_VERSION_MAJOR(version)    ((version) >> 16)
@@@ -750,6 -717,7 +717,7 @@@ struct intel_csr 
        i915_reg_t mmioaddr[8];
        uint32_t mmiodata[8];
        uint32_t dc_state;
+       uint32_t allowed_dc_mask;
  };
  
  #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
        func(overlay_needs_physical) sep \
        func(supports_tv) sep \
        func(has_llc) sep \
+       func(has_snoop) sep \
        func(has_ddi) sep \
        func(has_fpga_dbg)
  
@@@ -810,6 -779,11 +779,11 @@@ struct intel_device_info 
        u8 has_slice_pg:1;
        u8 has_subslice_pg:1;
        u8 has_eu_pg:1;
+       struct color_luts {
+               u16 degamma_lut_size;
+               u16 gamma_lut_size;
+       } color;
  };
  
  #undef DEFINE_FLAG
@@@ -891,7 -865,7 +865,7 @@@ struct intel_context 
                struct i915_vma *lrc_vma;
                u64 lrc_desc;
                uint32_t *lrc_reg_state;
-       } engine[I915_NUM_RINGS];
+       } engine[I915_NUM_ENGINES];
  
        struct list_head link;
  };
@@@ -1036,6 -1010,7 +1010,7 @@@ struct intel_fbc_work
  
  struct intel_gmbus {
        struct i2c_adapter adapter;
+ #define GMBUS_FORCE_BIT_RETRY (1U << 31)
        u32 force_bit;
        u32 reg0;
        i915_reg_t gpio_reg;
@@@ -1159,6 -1134,7 +1134,7 @@@ struct intel_gen6_power_mgmt 
        u8 efficient_freq;      /* AKA RPe. Pre-determined balanced frequency */
        u8 rp1_freq;            /* "less than" RP0 power/freqency */
        u8 rp0_freq;            /* Non-overclocked max frequency. */
+       u16 gpll_ref_freq;      /* vlv/chv GPLL reference frequency */
  
        u8 up_threshold; /* Current %busy required to uplock */
        u8 down_threshold; /* Current %busy required to downclock */
@@@ -1298,6 -1274,7 +1274,7 @@@ struct i915_gem_mm 
        struct i915_hw_ppgtt *aliasing_ppgtt;
  
        struct notifier_block oom_notifier;
+       struct notifier_block vmap_notifier;
        struct shrinker shrinker;
        bool shrinker_no_lock_stealing;
  
@@@ -1423,9 -1400,6 +1400,6 @@@ struct i915_gpu_error 
  
        /* For missed irq/seqno simulation. */
        unsigned int test_irq_rings;
-       /* Used to prevent gem_check_wedged returning -EAGAIN during gpu reset   */
-       bool reload_in_reset;
  };
  
  enum modeset_restore {
@@@ -1482,21 -1456,23 +1456,23 @@@ struct intel_vbt_data 
        unsigned int lvds_use_ssc:1;
        unsigned int display_clock_mode:1;
        unsigned int fdi_rx_polarity_inverted:1;
-       unsigned int has_mipi:1;
+       unsigned int panel_type:4;
        int lvds_ssc_freq;
        unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
  
        enum drrs_support_type drrs_type;
  
-       /* eDP */
-       int edp_rate;
-       int edp_lanes;
-       int edp_preemphasis;
-       int edp_vswing;
-       bool edp_initialized;
-       bool edp_support;
-       int edp_bpp;
-       struct edp_power_seq edp_pps;
+       struct {
+               int rate;
+               int lanes;
+               int preemphasis;
+               int vswing;
+               bool low_vswing;
+               bool initialized;
+               bool support;
+               int bpp;
+               struct edp_power_seq pps;
+       } edp;
  
        struct {
                bool full_link;
  
        /* MIPI DSI */
        struct {
-               u16 port;
                u16 panel_id;
                struct mipi_config *config;
                struct mipi_pps_data *pps;
        union child_device_config *child_dev;
  
        struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS];
+       struct sdvo_device_mapping sdvo_mappings[2];
  };
  
  enum intel_ddb_partitioning {
@@@ -1706,7 -1682,7 +1682,7 @@@ struct i915_wa_reg 
  struct i915_workarounds {
        struct i915_wa_reg reg[I915_MAX_WA_REGS];
        u32 count;
-       u32 hw_whitelist_count[I915_NUM_RINGS];
+       u32 hw_whitelist_count[I915_NUM_ENGINES];
  };
  
  struct i915_virtual_gpu {
@@@ -1719,7 -1695,7 +1695,7 @@@ struct i915_execbuffer_params 
        uint32_t                        dispatch_flags;
        uint32_t                        args_batch_start_offset;
        uint64_t                        batch_obj_vm_offset;
-       struct intel_engine_cs          *ring;
+       struct intel_engine_cs *engine;
        struct drm_i915_gem_object      *batch_obj;
        struct intel_context            *ctx;
        struct drm_i915_gem_request     *request;
@@@ -1771,7 -1747,7 +1747,7 @@@ struct drm_i915_private 
        wait_queue_head_t gmbus_wait_queue;
  
        struct pci_dev *bridge_dev;
-       struct intel_engine_cs ring[I915_NUM_RINGS];
+       struct intel_engine_cs engine[I915_NUM_ENGINES];
        struct drm_i915_gem_object *semaphore_obj;
        uint32_t last_seqno, next_seqno;
  
        unsigned int skl_boot_cdclk;
        unsigned int cdclk_freq, max_cdclk_freq, atomic_cdclk_freq;
        unsigned int max_dotclk_freq;
+       unsigned int rawclk_freq;
        unsigned int hpll_freq;
        unsigned int czclk_freq;
  
        struct drm_atomic_state *modeset_restore_state;
  
        struct list_head vm_list; /* Global list of all address spaces */
-       struct i915_gtt gtt; /* VM representing the global address space */
+       struct i915_ggtt ggtt; /* VM representing the global address space */
  
        struct i915_gem_mm mm;
        DECLARE_HASHTABLE(mm_structs, 7);
  
        /* Kernel Modesetting */
  
-       struct sdvo_device_mapping sdvo_mappings[2];
        struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
        struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
        wait_queue_head_t pending_flip_queue;
        /* dpll and cdclk state is protected by connection_mutex */
        int num_shared_dpll;
        struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
+       const struct intel_dpll_mgr *dpll_mgr;
+       /*
+        * dpll_lock serializes intel_{prepare,enable,disable}_shared_dpll.
+        * Must be global rather than per dpll, because on some platforms
+        * plls share registers.
+        */
+       struct mutex dpll_lock;
  
        unsigned int active_crtcs;
        unsigned int min_pixclk[I915_MAX_PIPES];
  
        struct i915_workarounds workarounds;
  
-       /* Reclocking support */
-       bool render_reclock_avail;
        struct i915_frontbuffer_tracking fb_tracking;
  
        u16 orig_clock;
        struct intel_l3_parity l3_parity;
  
        /* Cannot be determined by PCIID. You must always read a register. */
-       size_t ellc_size;
+       u32 edram_cap;
  
        /* gen6+ rps state */
        struct intel_gen6_power_mgmt rps;
  
        u32 fdi_rx_config;
  
+       /* Shadow for DISPLAY_PHY_CONTROL which can't be safely read */
        u32 chv_phy_control;
+       /*
+        * Shadows for CHV DPLL_MD regs to keep the state
+        * checker somewhat working in the presence hardware
+        * crappiness (can't read out DPLL_MD for pipes B & C).
+        */
+       u32 chv_dpll_md[I915_MAX_PIPES];
+       u32 bxt_phy_grc;
  
        u32 suspend_count;
        bool suspended_to_idle;
                };
  
                uint8_t max_level;
+               /*
+                * Should be held around atomic WM register writing; also
+                * protects * intel_crtc->wm.active and
+                * cstate->wm.need_postvbl_update.
+                */
+               struct mutex wm_mutex;
        } wm;
  
        struct i915_runtime_pm pm;
                int (*execbuf_submit)(struct i915_execbuffer_params *params,
                                      struct drm_i915_gem_execbuffer2 *args,
                                      struct list_head *vmas);
-               int (*init_rings)(struct drm_device *dev);
-               void (*cleanup_ring)(struct intel_engine_cs *ring);
-               void (*stop_ring)(struct intel_engine_cs *ring);
+               int (*init_engines)(struct drm_device *dev);
+               void (*cleanup_engine)(struct intel_engine_cs *engine);
+               void (*stop_engine)(struct intel_engine_cs *engine);
        } gt;
  
        struct intel_context *kernel_context;
  
-       bool edp_low_vswing;
        /* perform PHY state sanity checks? */
        bool chv_phy_assert[2];
  
@@@ -2024,10 -2017,28 +2017,28 @@@ static inline struct drm_i915_private *
        return container_of(guc, struct drm_i915_private, guc);
  }
  
- /* Iterate over initialised rings */
- #define for_each_ring(ring__, dev_priv__, i__) \
-       for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
-               for_each_if ((((ring__) = &(dev_priv__)->ring[(i__)]), intel_ring_initialized((ring__))))
+ /* Simple iterator over all initialised engines */
+ #define for_each_engine(engine__, dev_priv__) \
+       for ((engine__) = &(dev_priv__)->engine[0]; \
+            (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+            (engine__)++) \
+               for_each_if (intel_engine_initialized(engine__))
+ /* Iterator with engine_id */
+ #define for_each_engine_id(engine__, dev_priv__, id__) \
+       for ((engine__) = &(dev_priv__)->engine[0], (id__) = 0; \
+            (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+            (engine__)++) \
+               for_each_if (((id__) = (engine__)->id, \
+                             intel_engine_initialized(engine__)))
+ /* Iterator over subset of engines selected by mask */
+ #define for_each_engine_masked(engine__, dev_priv__, mask__) \
+       for ((engine__) = &(dev_priv__)->engine[0]; \
+            (engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
+            (engine__)++) \
+               for_each_if (((mask__) & intel_engine_flag(engine__)) && \
+                            intel_engine_initialized(engine__))
  
  enum hdmi_force_audio {
        HDMI_AUDIO_OFF_DVI = -2,        /* no aux data for HDMI-DVI converter */
@@@ -2097,7 -2108,7 +2108,7 @@@ struct drm_i915_gem_object 
        struct drm_mm_node *stolen;
        struct list_head global_list;
  
-       struct list_head ring_list[I915_NUM_RINGS];
+       struct list_head engine_list[I915_NUM_ENGINES];
        /** Used in execbuf to temporarily hold a ref */
        struct list_head obj_exec_link;
  
         * rendering and so a non-zero seqno), and is not set if it i s on
         * inactive (ready to be unbound) list.
         */
-       unsigned int active:I915_NUM_RINGS;
+       unsigned int active:I915_NUM_ENGINES;
  
        /**
         * This is set if the object has been written to since last bound
                struct scatterlist *sg;
                int last;
        } get_page;
-       /* prime dma-buf support */
-       void *dma_buf_vmapping;
-       int vmapping_count;
+       void *mapping;
  
        /** Breadcrumb of last rendering to the buffer.
         * There can only be one writer, but we allow for multiple readers.
         * read request. This allows for the CPU to read from an active
         * buffer by only waiting for the write to complete.
         * */
-       struct drm_i915_gem_request *last_read_req[I915_NUM_RINGS];
+       struct drm_i915_gem_request *last_read_req[I915_NUM_ENGINES];
        struct drm_i915_gem_request *last_write_req;
        /** Breadcrumb of last fenced GPU access to the buffer. */
        struct drm_i915_gem_request *last_fenced_req;
@@@ -2242,7 -2250,8 +2250,8 @@@ struct drm_i915_gem_request 
  
        /** On Which ring this request was generated */
        struct drm_i915_private *i915;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
+       unsigned reset_counter;
  
         /** GEM sequence number associated with the previous request,
          * when the HWS breadcrumb is equal to this the GPU is processing
  struct drm_i915_gem_request * __must_check
  i915_gem_request_alloc(struct intel_engine_cs *engine,
                       struct intel_context *ctx);
- void i915_gem_request_cancel(struct drm_i915_gem_request *req);
  void i915_gem_request_free(struct kref *req_ref);
  int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
                                   struct drm_file *file);
@@@ -2335,9 -2343,9 +2343,9 @@@ i915_gem_request_get_seqno(struct drm_i
  }
  
  static inline struct intel_engine_cs *
- i915_gem_request_get_ring(struct drm_i915_gem_request *req)
+ i915_gem_request_get_engine(struct drm_i915_gem_request *req)
  {
-       return req ? req->ring : NULL;
+       return req ? req->engine : NULL;
  }
  
  static inline struct drm_i915_gem_request *
@@@ -2351,7 -2359,7 +2359,7 @@@ i915_gem_request_reference(struct drm_i
  static inline void
  i915_gem_request_unreference(struct drm_i915_gem_request *req)
  {
-       WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
+       WARN_ON(!mutex_is_locked(&req->engine->dev->struct_mutex));
        kref_put(&req->ref, i915_gem_request_free);
  }
  
@@@ -2363,7 -2371,7 +2371,7 @@@ i915_gem_request_unreference__unlocked(
        if (!req)
                return;
  
-       dev = req->ring->dev;
+       dev = req->engine->dev;
        if (kref_put_mutex(&req->ref, i915_gem_request_free, &dev->struct_mutex))
                mutex_unlock(&dev->struct_mutex);
  }
@@@ -2493,6 -2501,7 +2501,7 @@@ struct drm_i915_cmd_table 
        __p; \
  })
  #define INTEL_INFO(p)         (&__I915__(p)->info)
+ #define INTEL_GEN(p)  (INTEL_INFO(p)->gen)
  #define INTEL_DEVID(p)        (INTEL_INFO(p)->device_id)
  #define INTEL_REVID(p)        (__I915__(p)->dev->pdev->revision)
  
  #define BLT_RING              (1<<BCS)
  #define VEBOX_RING            (1<<VECS)
  #define BSD2_RING             (1<<VCS2)
+ #define ALL_ENGINES           (~0)
  #define HAS_BSD(dev)          (INTEL_INFO(dev)->ring_mask & BSD_RING)
  #define HAS_BSD2(dev)         (INTEL_INFO(dev)->ring_mask & BSD2_RING)
  #define HAS_BLT(dev)          (INTEL_INFO(dev)->ring_mask & BLT_RING)
  #define HAS_VEBOX(dev)                (INTEL_INFO(dev)->ring_mask & VEBOX_RING)
  #define HAS_LLC(dev)          (INTEL_INFO(dev)->has_llc)
+ #define HAS_SNOOP(dev)                (INTEL_INFO(dev)->has_snoop)
+ #define HAS_EDRAM(dev)                (__I915__(dev)->edram_cap & EDRAM_ENABLED)
  #define HAS_WT(dev)           ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && \
-                                __I915__(dev)->ellc_size)
+                                HAS_EDRAM(dev))
  #define I915_NEED_GFX_HWS(dev)        (INTEL_INFO(dev)->need_gfx_hws)
  
  #define HAS_HW_CONTEXTS(dev)  (INTEL_INFO(dev)->gen >= 6)
  #define HAS_RUNTIME_PM(dev)   (IS_GEN6(dev) || IS_HASWELL(dev) || \
                                 IS_BROADWELL(dev) || IS_VALLEYVIEW(dev) || \
                                 IS_CHERRYVIEW(dev) || IS_SKYLAKE(dev) || \
-                                IS_KABYLAKE(dev))
+                                IS_KABYLAKE(dev) || IS_BROXTON(dev))
  #define HAS_RC6(dev)          (INTEL_INFO(dev)->gen >= 6)
  #define HAS_RC6p(dev)         (INTEL_INFO(dev)->gen == 6 || IS_IVYBRIDGE(dev))
  
  #define INTEL_PCH_SPT_DEVICE_ID_TYPE          0xA100
  #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE               0x9D00
  #define INTEL_PCH_P2X_DEVICE_ID_TYPE          0x7100
+ #define INTEL_PCH_P3X_DEVICE_ID_TYPE          0x7000
  #define INTEL_PCH_QEMU_DEVICE_ID_TYPE         0x2900 /* qemu q35 has 2918 */
  
  #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
@@@ -2727,6 -2741,13 +2741,13 @@@ extern int i915_suspend_switcheroo(stru
  extern int i915_resume_switcheroo(struct drm_device *dev);
  
  /* i915_dma.c */
+ void __printf(3, 4)
+ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
+             const char *fmt, ...);
+ #define i915_report_error(dev_priv, fmt, ...)                            \
+       __i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__)
  extern int i915_driver_load(struct drm_device *, unsigned long flags);
  extern int i915_driver_unload(struct drm_device *);
  extern int i915_driver_open(struct drm_device *dev, struct drm_file *file);
@@@ -2739,9 -2760,11 +2760,11 @@@ extern void i915_driver_postclose(struc
  extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
  #endif
- extern int intel_gpu_reset(struct drm_device *dev);
+ extern int intel_gpu_reset(struct drm_device *dev, u32 engine_mask);
  extern bool intel_has_gpu_reset(struct drm_device *dev);
  extern int i915_reset(struct drm_device *dev);
+ extern int intel_guc_reset(struct drm_i915_private *dev_priv);
+ extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
  extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
  extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
  extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
@@@ -2758,7 -2781,7 +2781,7 @@@ bool intel_hpd_pin_to_port(enum hpd_pi
  /* i915_irq.c */
  void i915_queue_hangcheck(struct drm_device *dev);
  __printf(3, 4)
- void i915_handle_error(struct drm_device *dev, bool wedged,
+ void i915_handle_error(struct drm_device *dev, u32 engine_mask,
                       const char *fmt, ...);
  
  extern void intel_irq_init(struct drm_i915_private *dev_priv);
@@@ -2785,6 -2808,8 +2808,8 @@@ void intel_uncore_forcewake_get__locked
                                        enum forcewake_domains domains);
  void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
                                        enum forcewake_domains domains);
+ u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv);
  void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
  static inline bool intel_vgpu_active(struct drm_device *dev)
  {
@@@ -2863,7 -2888,6 +2888,6 @@@ int i915_gem_sw_finish_ioctl(struct drm
                             struct drm_file *file_priv);
  void i915_gem_execbuffer_move_to_active(struct list_head *vmas,
                                        struct drm_i915_gem_request *req);
- void i915_gem_execbuffer_retire_commands(struct i915_execbuffer_params *params);
  int i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
                                   struct drm_i915_gem_execbuffer2 *args,
                                   struct list_head *vmas);
@@@ -2894,6 -2918,7 +2918,7 @@@ int i915_gem_wait_ioctl(struct drm_devi
                        struct drm_file *file_priv);
  void i915_gem_load_init(struct drm_device *dev);
  void i915_gem_load_cleanup(struct drm_device *dev);
+ void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
  void *i915_gem_object_alloc(struct drm_device *dev);
  void i915_gem_object_free(struct drm_i915_gem_object *obj);
  void i915_gem_object_init(struct drm_i915_gem_object *obj,
@@@ -2978,12 -3003,46 +3003,46 @@@ static inline void i915_gem_object_pin_
        BUG_ON(obj->pages == NULL);
        obj->pages_pin_count++;
  }
  static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
  {
        BUG_ON(obj->pages_pin_count == 0);
        obj->pages_pin_count--;
  }
  
+ /**
+  * i915_gem_object_pin_map - return a contiguous mapping of the entire object
+  * @obj - the object to map into kernel address space
+  *
+  * Calls i915_gem_object_pin_pages() to prevent reaping of the object's
+  * pages and then returns a contiguous mapping of the backing storage into
+  * the kernel address space.
+  *
+  * The caller must hold the struct_mutex, and is responsible for calling
+  * i915_gem_object_unpin_map() when the mapping is no longer required.
+  *
+  * Returns the pointer through which to access the mapped object, or an
+  * ERR_PTR() on error.
+  */
+ void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj);
+ /**
+  * i915_gem_object_unpin_map - releases an earlier mapping
+  * @obj - the object to unmap
+  *
+  * After pinning the object and mapping its pages, once you are finished
+  * with your access, call i915_gem_object_unpin_map() to release the pin
+  * upon the mapping. Once the pin count reaches zero, that mapping may be
+  * removed.
+  *
+  * The caller must hold the struct_mutex.
+  */
+ static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj)
+ {
+       lockdep_assert_held(&obj->base.dev->struct_mutex);
+       i915_gem_object_unpin_pages(obj);
+ }
  int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
  int i915_gem_object_sync(struct drm_i915_gem_object *obj,
                         struct intel_engine_cs *to,
@@@ -3007,42 -3066,68 +3066,68 @@@ i915_seqno_passed(uint32_t seq1, uint32
  static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
                                           bool lazy_coherency)
  {
-       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-       return i915_seqno_passed(seqno, req->previous_seqno);
+       if (!lazy_coherency && req->engine->irq_seqno_barrier)
+               req->engine->irq_seqno_barrier(req->engine);
+       return i915_seqno_passed(req->engine->get_seqno(req->engine),
+                                req->previous_seqno);
  }
  
  static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
                                              bool lazy_coherency)
  {
-       u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-       return i915_seqno_passed(seqno, req->seqno);
+       if (!lazy_coherency && req->engine->irq_seqno_barrier)
+               req->engine->irq_seqno_barrier(req->engine);
+       return i915_seqno_passed(req->engine->get_seqno(req->engine),
+                                req->seqno);
  }
  
  int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
  int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno);
  
  struct drm_i915_gem_request *
- i915_gem_find_active_request(struct intel_engine_cs *ring);
+ i915_gem_find_active_request(struct intel_engine_cs *engine);
  
  bool i915_gem_retire_requests(struct drm_device *dev);
- void i915_gem_retire_requests_ring(struct intel_engine_cs *ring);
- int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
-                                     bool interruptible);
+ void i915_gem_retire_requests_ring(struct intel_engine_cs *engine);
+ static inline u32 i915_reset_counter(struct i915_gpu_error *error)
+ {
+       return atomic_read(&error->reset_counter);
+ }
+ static inline bool __i915_reset_in_progress(u32 reset)
+ {
+       return unlikely(reset & I915_RESET_IN_PROGRESS_FLAG);
+ }
+ static inline bool __i915_reset_in_progress_or_wedged(u32 reset)
+ {
+       return unlikely(reset & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
+ }
+ static inline bool __i915_terminally_wedged(u32 reset)
+ {
+       return unlikely(reset & I915_WEDGED);
+ }
  
  static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
  {
-       return unlikely(atomic_read(&error->reset_counter)
-                       & (I915_RESET_IN_PROGRESS_FLAG | I915_WEDGED));
+       return __i915_reset_in_progress(i915_reset_counter(error));
+ }
+ static inline bool i915_reset_in_progress_or_wedged(struct i915_gpu_error *error)
+ {
+       return __i915_reset_in_progress_or_wedged(i915_reset_counter(error));
  }
  
  static inline bool i915_terminally_wedged(struct i915_gpu_error *error)
  {
-       return atomic_read(&error->reset_counter) & I915_WEDGED;
+       return __i915_terminally_wedged(i915_reset_counter(error));
  }
  
  static inline u32 i915_reset_count(struct i915_gpu_error *error)
  {
-       return ((atomic_read(&error->reset_counter) & ~I915_WEDGED) + 1) / 2;
+       return ((i915_reset_counter(error) & ~I915_WEDGED) + 1) / 2;
  }
  
  static inline bool i915_stop_ring_allow_ban(struct drm_i915_private *dev_priv)
@@@ -3060,11 -3145,11 +3145,11 @@@ static inline bool i915_stop_ring_allow
  void i915_gem_reset(struct drm_device *dev);
  bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
  int __must_check i915_gem_init(struct drm_device *dev);
- int i915_gem_init_rings(struct drm_device *dev);
+ int i915_gem_init_engines(struct drm_device *dev);
  int __must_check i915_gem_init_hw(struct drm_device *dev);
  int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice);
  void i915_gem_init_swizzling(struct drm_device *dev);
- void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
+ void i915_gem_cleanup_engines(struct drm_device *dev);
  int __must_check i915_gpu_idle(struct drm_device *dev);
  int __must_check i915_gem_suspend(struct drm_device *dev);
  void __i915_add_request(struct drm_i915_gem_request *req,
  #define i915_add_request_no_flush(req) \
        __i915_add_request(req, NULL, false)
  int __i915_wait_request(struct drm_i915_gem_request *req,
-                       unsigned reset_counter,
                        bool interruptible,
                        s64 *timeout,
                        struct intel_rps_client *rps);
@@@ -3155,13 -3239,9 +3239,9 @@@ i915_gem_obj_to_ggtt(struct drm_i915_ge
  bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
  
  /* Some GGTT VM helpers */
- #define i915_obj_to_ggtt(obj) \
-       (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base)
  static inline struct i915_hw_ppgtt *
  i915_vm_to_ppgtt(struct i915_address_space *vm)
  {
-       WARN_ON(i915_is_ggtt(vm));
        return container_of(vm, struct i915_hw_ppgtt, base);
  }
  
@@@ -3174,7 -3254,10 +3254,10 @@@ static inline bool i915_gem_obj_ggtt_bo
  static inline unsigned long
  i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj)
  {
-       return i915_gem_obj_size(obj, i915_obj_to_ggtt(obj));
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
+       return i915_gem_obj_size(obj, &ggtt->base);
  }
  
  static inline int __must_check
@@@ -3182,7 -3265,10 +3265,10 @@@ i915_gem_obj_ggtt_pin(struct drm_i915_g
                      uint32_t alignment,
                      unsigned flags)
  {
-       return i915_gem_object_pin(obj, i915_obj_to_ggtt(obj),
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
+       return i915_gem_object_pin(obj, &ggtt->base,
                                   alignment, flags | PIN_GLOBAL);
  }
  
@@@ -3297,6 -3383,7 +3383,7 @@@ unsigned long i915_gem_shrink(struct dr
  #define I915_SHRINK_UNBOUND 0x2
  #define I915_SHRINK_BOUND 0x4
  #define I915_SHRINK_ACTIVE 0x8
+ #define I915_SHRINK_VMAPS 0x10
  unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
  void i915_gem_shrinker_init(struct drm_i915_private *dev_priv);
  void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv);
@@@ -3343,7 -3430,7 +3430,7 @@@ static inline void i915_error_state_buf
  {
        kfree(eb->buf);
  }
- void i915_capture_error_state(struct drm_device *dev, bool wedge,
+ void i915_capture_error_state(struct drm_device *dev, u32 engine_mask,
                              const char *error_msg);
  void i915_error_state_get(struct drm_device *dev,
                          struct i915_error_state_file_priv *error_priv);
@@@ -3355,10 -3442,10 +3442,10 @@@ const char *i915_cache_level_str(struc
  
  /* i915_cmd_parser.c */
  int i915_cmd_parser_get_version(void);
- int i915_cmd_parser_init_ring(struct intel_engine_cs *ring);
- void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring);
- bool i915_needs_cmd_parser(struct intel_engine_cs *ring);
- int i915_parse_cmds(struct intel_engine_cs *ring,
+ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine);
+ void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine);
+ bool i915_needs_cmd_parser(struct intel_engine_cs *engine);
+ int i915_parse_cmds(struct intel_engine_cs *engine,
                    struct drm_i915_gem_object *batch_obj,
                    struct drm_i915_gem_object *shadow_batch_obj,
                    u32 batch_start_offset,
@@@ -3392,6 -3479,12 +3479,12 @@@ extern void intel_i2c_reset(struct drm_
  /* intel_bios.c */
  int intel_bios_init(struct drm_i915_private *dev_priv);
  bool intel_bios_is_valid_vbt(const void *buf, size_t size);
+ bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
+ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);
+ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
+ bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port);
+ bool intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv,
+                                    enum port port);
  
  /* intel_opregion.c */
  #ifdef CONFIG_ACPI
@@@ -3403,6 -3496,7 +3496,7 @@@ extern int intel_opregion_notify_encode
                                         bool enable);
  extern int intel_opregion_notify_adapter(struct drm_device *dev,
                                         pci_power_t state);
+ extern int intel_opregion_get_panel_type(struct drm_device *dev);
  #else
  static inline int intel_opregion_setup(struct drm_device *dev) { return 0; }
  static inline void intel_opregion_init(struct drm_device *dev) { return; }
@@@ -3418,6 -3512,10 +3512,10 @@@ intel_opregion_notify_adapter(struct dr
  {
        return 0;
  }
+ static inline int intel_opregion_get_panel_type(struct drm_device *dev)
+ {
+       return -ENODEV;
+ }
  #endif
  
  /* intel_acpi.c */
@@@ -3577,6 -3675,11 +3675,6 @@@ static inline i915_reg_t i915_vgacntrl_
                return VGACNTRL;
  }
  
 -static inline void __user *to_user_ptr(u64 address)
 -{
 -      return (void __user *)(uintptr_t)address;
 -}
 -
  static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
  {
        unsigned long j = msecs_to_jiffies(m);
@@@ -3624,11 -3727,11 +3722,11 @@@ wait_remaining_ms_from_jiffies(unsigne
        }
  }
  
- static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
+ static inline void i915_trace_irq_get(struct intel_engine_cs *engine,
                                      struct drm_i915_gem_request *req)
  {
-       if (ring->trace_irq_req == NULL && ring->irq_get(ring))
-               i915_gem_request_assign(&ring->trace_irq_req, req);
+       if (engine->trace_irq_req == NULL && engine->irq_get(engine))
+               i915_gem_request_assign(&engine->trace_irq_req, req);
  }
  
  #endif
index 233adc31ef0c9ed32b0cc63cefb78b23cc0d82c6,cdd2f438d4b40a985bcf77a40b4259bf6d28261d..94bbc4314ac5a3a8190fda2f23da1143eb8f5c13
  #include "i915_vgpu.h"
  #include "i915_trace.h"
  #include "intel_drv.h"
+ #include "intel_mocs.h"
  #include <linux/shmem_fs.h>
  #include <linux/slab.h>
  #include <linux/swap.h>
  #include <linux/pci.h>
  #include <linux/dma-buf.h>
  
- #define RQ_BUG_ON(expr)
  static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
  static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
  static void
@@@ -85,9 -84,7 +84,7 @@@ i915_gem_wait_for_error(struct i915_gpu
  {
        int ret;
  
- #define EXIT_COND (!i915_reset_in_progress(error) || \
-                  i915_terminally_wedged(error))
-       if (EXIT_COND)
+       if (!i915_reset_in_progress(error))
                return 0;
  
        /*
         * we should simply try to bail out and fail as gracefully as possible.
         */
        ret = wait_event_interruptible_timeout(error->reset_queue,
-                                              EXIT_COND,
+                                              !i915_reset_in_progress(error),
                                               10*HZ);
        if (ret == 0) {
                DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
                return -EIO;
        } else if (ret < 0) {
                return ret;
+       } else {
+               return 0;
        }
- #undef EXIT_COND
-       return 0;
  }
  
  int i915_mutex_lock_interruptible(struct drm_device *dev)
@@@ -130,9 -126,9 +126,9 @@@ in
  i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
                            struct drm_file *file)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct drm_i915_gem_get_aperture *args = data;
-       struct i915_gtt *ggtt = &dev_priv->gtt;
        struct i915_vma *vma;
        size_t pinned;
  
                        pinned += vma->node.size;
        mutex_unlock(&dev->struct_mutex);
  
-       args->aper_size = dev_priv->gtt.base.total;
+       args->aper_size = ggtt->base.total;
        args->aper_available_size = args->aper_size - pinned;
  
        return 0;
@@@ -211,11 -207,10 +207,10 @@@ i915_gem_object_put_pages_phys(struct d
        BUG_ON(obj->madv == __I915_MADV_PURGED);
  
        ret = i915_gem_object_set_to_cpu_domain(obj, true);
-       if (ret) {
+       if (WARN_ON(ret)) {
                /* In the event of a disaster, abandon all caches and
                 * hope for the best.
                 */
-               WARN_ON(ret != -EIO);
                obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
        }
  
@@@ -324,7 -319,7 +319,7 @@@ i915_gem_phys_pwrite(struct drm_i915_ge
  {
        struct drm_device *dev = obj->base.dev;
        void *vaddr = obj->phys_handle->vaddr + args->offset;
 -      char __user *user_data = to_user_ptr(args->data_ptr);
 +      char __user *user_data = u64_to_user_ptr(args->data_ptr);
        int ret = 0;
  
        /* We manually control the domain here and pretend that it
@@@ -605,7 -600,7 +600,7 @@@ i915_gem_shmem_pread(struct drm_device 
        int needs_clflush = 0;
        struct sg_page_iter sg_iter;
  
 -      user_data = to_user_ptr(args->data_ptr);
 +      user_data = u64_to_user_ptr(args->data_ptr);
        remain = args->size;
  
        obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
@@@ -692,7 -687,7 +687,7 @@@ i915_gem_pread_ioctl(struct drm_device 
                return 0;
  
        if (!access_ok(VERIFY_WRITE,
 -                     to_user_ptr(args->data_ptr),
 +                     u64_to_user_ptr(args->data_ptr),
                       args->size))
                return -EFAULT;
  
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -765,7 -760,8 +760,8 @@@ i915_gem_gtt_pwrite_fast(struct drm_dev
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
        if (ret)
                goto out_unpin;
  
 -      user_data = to_user_ptr(args->data_ptr);
 +      user_data = u64_to_user_ptr(args->data_ptr);
        remain = args->size;
  
        offset = i915_gem_obj_ggtt_offset(obj) + args->offset;
                 * source page isn't available.  Return the error and we'll
                 * retry in the slow path.
                 */
-               if (fast_user_write(dev_priv->gtt.mappable, page_base,
+               if (fast_user_write(ggtt->mappable, page_base,
                                    page_offset, user_data, page_length)) {
                        ret = -EFAULT;
                        goto out_flush;
@@@ -907,7 -903,7 +903,7 @@@ i915_gem_shmem_pwrite(struct drm_devic
        int needs_clflush_before = 0;
        struct sg_page_iter sg_iter;
  
 -      user_data = to_user_ptr(args->data_ptr);
 +      user_data = u64_to_user_ptr(args->data_ptr);
        remain = args->size;
  
        obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
@@@ -1036,12 -1032,12 +1032,12 @@@ i915_gem_pwrite_ioctl(struct drm_devic
                return 0;
  
        if (!access_ok(VERIFY_READ,
 -                     to_user_ptr(args->data_ptr),
 +                     u64_to_user_ptr(args->data_ptr),
                       args->size))
                return -EFAULT;
  
        if (likely(!i915.prefault_disable)) {
 -              ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr),
 +              ret = fault_in_multipages_readable(u64_to_user_ptr(args->data_ptr),
                                                   args->size);
                if (ret)
                        return -EFAULT;
        if (ret)
                goto put_rpm;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -1109,27 -1105,19 +1105,19 @@@ put_rpm
        return ret;
  }
  
- int
- i915_gem_check_wedge(struct i915_gpu_error *error,
-                    bool interruptible)
+ static int
+ i915_gem_check_wedge(unsigned reset_counter, bool interruptible)
  {
-       if (i915_reset_in_progress(error)) {
+       if (__i915_terminally_wedged(reset_counter))
+               return -EIO;
+       if (__i915_reset_in_progress(reset_counter)) {
                /* Non-interruptible callers can't handle -EAGAIN, hence return
                 * -EIO unconditionally for these. */
                if (!interruptible)
                        return -EIO;
  
-               /* Recovery complete, but the reset failed ... */
-               if (i915_terminally_wedged(error))
-                       return -EIO;
-               /*
-                * Check if GPU Reset is in progress - we need intel_ring_begin
-                * to work properly to reinit the hw state while the gpu is
-                * still marked as reset-in-progress. Handle this with a flag.
-                */
-               if (!error->reload_in_reset)
-                       return -EAGAIN;
+               return -EAGAIN;
        }
  
        return 0;
@@@ -1141,9 -1129,9 +1129,9 @@@ static void fake_irq(unsigned long data
  }
  
  static bool missed_irq(struct drm_i915_private *dev_priv,
-                      struct intel_engine_cs *ring)
+                      struct intel_engine_cs *engine)
  {
-       return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
+       return test_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings);
  }
  
  static unsigned long local_clock_us(unsigned *cpu)
@@@ -1193,7 -1181,7 +1181,7 @@@ static int __i915_spin_request(struct d
         * takes to sleep on a request, on the order of a microsecond.
         */
  
-       if (req->ring->irq_refcount)
+       if (req->engine->irq_refcount)
                return -EBUSY;
  
        /* Only spin if we know the GPU is processing this request */
  /**
   * __i915_wait_request - wait until execution of request has finished
   * @req: duh!
-  * @reset_counter: reset sequence associated with the given request
   * @interruptible: do an interruptible wait (normally yes)
   * @timeout: in - how long to wait (NULL forever); out - how much time remaining
   *
   * errno with remaining time filled in timeout argument.
   */
  int __i915_wait_request(struct drm_i915_gem_request *req,
-                       unsigned reset_counter,
                        bool interruptible,
                        s64 *timeout,
                        struct intel_rps_client *rps)
  {
-       struct intel_engine_cs *ring = i915_gem_request_get_ring(req);
-       struct drm_device *dev = ring->dev;
+       struct intel_engine_cs *engine = i915_gem_request_get_engine(req);
+       struct drm_device *dev = engine->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        const bool irq_test_in_progress =
-               ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
+               ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_engine_flag(engine);
        int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
        DEFINE_WAIT(wait);
        unsigned long timeout_expire;
        if (ret == 0)
                goto out;
  
-       if (!irq_test_in_progress && WARN_ON(!ring->irq_get(ring))) {
+       if (!irq_test_in_progress && WARN_ON(!engine->irq_get(engine))) {
                ret = -ENODEV;
                goto out;
        }
        for (;;) {
                struct timer_list timer;
  
-               prepare_to_wait(&ring->irq_queue, &wait, state);
+               prepare_to_wait(&engine->irq_queue, &wait, state);
  
                /* We need to check whether any gpu reset happened in between
-                * the caller grabbing the seqno and now ... */
-               if (reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) {
-                       /* ... but upgrade the -EAGAIN to an -EIO if the gpu
-                        * is truely gone. */
-                       ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
-                       if (ret == 0)
-                               ret = -EAGAIN;
+                * the request being submitted and now. If a reset has occurred,
+                * the request is effectively complete (we either are in the
+                * process of or have discarded the rendering and completely
+                * reset the GPU. The results of the request are lost and we
+                * are free to continue on with the original operation.
+                */
+               if (req->reset_counter != i915_reset_counter(&dev_priv->gpu_error)) {
+                       ret = 0;
                        break;
                }
  
                }
  
                timer.function = NULL;
-               if (timeout || missed_irq(dev_priv, ring)) {
+               if (timeout || missed_irq(dev_priv, engine)) {
                        unsigned long expire;
  
                        setup_timer_on_stack(&timer, fake_irq, (unsigned long)current);
-                       expire = missed_irq(dev_priv, ring) ? jiffies + 1 : timeout_expire;
+                       expire = missed_irq(dev_priv, engine) ? jiffies + 1 : timeout_expire;
                        mod_timer(&timer, expire);
                }
  
                }
        }
        if (!irq_test_in_progress)
-               ring->irq_put(ring);
+               engine->irq_put(engine);
  
-       finish_wait(&ring->irq_queue, &wait);
+       finish_wait(&engine->irq_queue, &wait);
  
  out:
        trace_i915_gem_request_wait_end(req);
  int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
                                   struct drm_file *file)
  {
-       struct drm_i915_private *dev_private;
        struct drm_i915_file_private *file_priv;
  
        WARN_ON(!req || !file || req->file_priv);
        if (req->file_priv)
                return -EINVAL;
  
-       dev_private = req->ring->dev->dev_private;
        file_priv = file->driver_priv;
  
        spin_lock(&file_priv->mm.lock);
@@@ -1434,7 -1419,7 +1419,7 @@@ static void i915_gem_request_retire(str
  static void
  __i915_gem_request_retire__upto(struct drm_i915_gem_request *req)
  {
-       struct intel_engine_cs *engine = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct drm_i915_gem_request *tmp;
  
        lockdep_assert_held(&engine->dev->struct_mutex);
  int
  i915_wait_request(struct drm_i915_gem_request *req)
  {
-       struct drm_device *dev;
-       struct drm_i915_private *dev_priv;
+       struct drm_i915_private *dev_priv = req->i915;
        bool interruptible;
        int ret;
  
-       BUG_ON(req == NULL);
-       dev = req->ring->dev;
-       dev_priv = dev->dev_private;
        interruptible = dev_priv->mm.interruptible;
  
-       BUG_ON(!mutex_is_locked(&dev->struct_mutex));
-       ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
-       if (ret)
-               return ret;
+       BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
  
-       ret = __i915_wait_request(req,
-                                 atomic_read(&dev_priv->gpu_error.reset_counter),
-                                 interruptible, NULL, NULL);
+       ret = __i915_wait_request(req, interruptible, NULL, NULL);
        if (ret)
                return ret;
  
@@@ -1505,14 -1479,14 +1479,14 @@@ i915_gem_object_wait_rendering(struct d
                        if (ret)
                                return ret;
  
-                       i = obj->last_write_req->ring->id;
+                       i = obj->last_write_req->engine->id;
                        if (obj->last_read_req[i] == obj->last_write_req)
                                i915_gem_object_retire__read(obj, i);
                        else
                                i915_gem_object_retire__write(obj);
                }
        } else {
-               for (i = 0; i < I915_NUM_RINGS; i++) {
+               for (i = 0; i < I915_NUM_ENGINES; i++) {
                        if (obj->last_read_req[i] == NULL)
                                continue;
  
  
                        i915_gem_object_retire__read(obj, i);
                }
-               RQ_BUG_ON(obj->active);
+               GEM_BUG_ON(obj->active);
        }
  
        return 0;
@@@ -1532,7 -1506,7 +1506,7 @@@ static voi
  i915_gem_object_retire_request(struct drm_i915_gem_object *obj,
                               struct drm_i915_gem_request *req)
  {
-       int ring = req->ring->id;
+       int ring = req->engine->id;
  
        if (obj->last_read_req[ring] == req)
                i915_gem_object_retire__read(obj, ring);
@@@ -1552,8 -1526,7 +1526,7 @@@ i915_gem_object_wait_rendering__nonbloc
  {
        struct drm_device *dev = obj->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_request *requests[I915_NUM_RINGS];
-       unsigned reset_counter;
+       struct drm_i915_gem_request *requests[I915_NUM_ENGINES];
        int ret, i, n = 0;
  
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
        if (!obj->active)
                return 0;
  
-       ret = i915_gem_check_wedge(&dev_priv->gpu_error, true);
-       if (ret)
-               return ret;
-       reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
        if (readonly) {
                struct drm_i915_gem_request *req;
  
  
                requests[n++] = i915_gem_request_reference(req);
        } else {
-               for (i = 0; i < I915_NUM_RINGS; i++) {
+               for (i = 0; i < I915_NUM_ENGINES; i++) {
                        struct drm_i915_gem_request *req;
  
                        req = obj->last_read_req[i];
        }
  
        mutex_unlock(&dev->struct_mutex);
+       ret = 0;
        for (i = 0; ret == 0 && i < n; i++)
-               ret = __i915_wait_request(requests[i], reset_counter, true,
-                                         NULL, rps);
+               ret = __i915_wait_request(requests[i], true, NULL, rps);
        mutex_lock(&dev->struct_mutex);
  
        for (i = 0; i < n; i++) {
@@@ -1640,7 -1607,7 +1607,7 @@@ i915_gem_set_domain_ioctl(struct drm_de
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -1688,7 -1655,7 +1655,7 @@@ i915_gem_sw_finish_ioctl(struct drm_dev
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -1732,10 -1699,10 +1699,10 @@@ i915_gem_mmap_ioctl(struct drm_device *
        if (args->flags & ~(I915_MMAP_WC))
                return -EINVAL;
  
 -      if (args->flags & I915_MMAP_WC && !cpu_has_pat)
 +      if (args->flags & I915_MMAP_WC && !boot_cpu_has(X86_FEATURE_PAT))
                return -ENODEV;
  
-       obj = drm_gem_object_lookup(dev, file, args->handle);
+       obj = drm_gem_object_lookup(file, args->handle);
        if (obj == NULL)
                return -ENOENT;
  
@@@ -1792,7 -1759,8 +1759,8 @@@ int i915_gem_fault(struct vm_area_struc
  {
        struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data);
        struct drm_device *dev = obj->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct i915_ggtt_view view = i915_ggtt_view_normal;
        pgoff_t page_offset;
        unsigned long pfn;
        }
  
        /* Use a partial view if the object is bigger than the aperture. */
-       if (obj->base.size >= dev_priv->gtt.mappable_end &&
+       if (obj->base.size >= ggtt->mappable_end &&
            obj->tiling_mode == I915_TILING_NONE) {
                static const unsigned int chunk_size = 256; // 1 MiB
  
                goto unpin;
  
        /* Finally, remap it using the new GTT offset */
-       pfn = dev_priv->gtt.mappable_base +
+       pfn = ggtt->mappable_base +
                i915_gem_obj_ggtt_offset_view(obj, &view);
        pfn >>= PAGE_SHIFT;
  
  void
  i915_gem_release_mmap(struct drm_i915_gem_object *obj)
  {
+       /* Serialisation between user GTT access and our code depends upon
+        * revoking the CPU's PTE whilst the mutex is held. The next user
+        * pagefault then has to wait until we release the mutex.
+        */
+       lockdep_assert_held(&obj->base.dev->struct_mutex);
        if (!obj->fault_mappable)
                return;
  
        drm_vma_node_unmap(&obj->base.vma_node,
                           obj->base.dev->anon_inode->i_mapping);
+       /* Ensure that the CPU's PTE are revoked and there are not outstanding
+        * memory transactions from userspace before we return. The TLB
+        * flushing implied above by changing the PTE above *should* be
+        * sufficient, an extra barrier here just provides us with a bit
+        * of paranoid documentation about our requirement to serialise
+        * memory writes before touching registers / GSM.
+        */
+       wmb();
        obj->fault_mappable = false;
  }
  
@@@ -2033,9 -2017,6 +2017,6 @@@ static int i915_gem_object_create_mmap_
        struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
        int ret;
  
-       if (drm_vma_node_has_offset(&obj->base.vma_node))
-               return 0;
        dev_priv->mm.shrinker_no_lock_stealing = true;
  
        ret = drm_gem_create_mmap_offset(&obj->base);
@@@ -2084,7 -2065,7 +2065,7 @@@ i915_gem_mmap_gtt(struct drm_file *file
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -2180,11 -2161,10 +2161,10 @@@ i915_gem_object_put_pages_gtt(struct dr
        BUG_ON(obj->madv == __I915_MADV_PURGED);
  
        ret = i915_gem_object_set_to_cpu_domain(obj, true);
-       if (ret) {
+       if (WARN_ON(ret)) {
                /* In the event of a disaster, abandon all caches and
                 * hope for the best.
                 */
-               WARN_ON(ret != -EIO);
                i915_gem_clflush_object(obj, true);
                obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
        }
@@@ -2232,6 -2212,14 +2212,14 @@@ i915_gem_object_put_pages(struct drm_i9
         * lists early. */
        list_del(&obj->global_list);
  
+       if (obj->mapping) {
+               if (is_vmalloc_addr(obj->mapping))
+                       vunmap(obj->mapping);
+               else
+                       kunmap(kmap_to_page(obj->mapping));
+               obj->mapping = NULL;
+       }
        ops->put_pages(obj);
        obj->pages = NULL;
  
@@@ -2400,21 -2388,64 +2388,64 @@@ i915_gem_object_get_pages(struct drm_i9
        return 0;
  }
  
+ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj)
+ {
+       int ret;
+       lockdep_assert_held(&obj->base.dev->struct_mutex);
+       ret = i915_gem_object_get_pages(obj);
+       if (ret)
+               return ERR_PTR(ret);
+       i915_gem_object_pin_pages(obj);
+       if (obj->mapping == NULL) {
+               struct page **pages;
+               pages = NULL;
+               if (obj->base.size == PAGE_SIZE)
+                       obj->mapping = kmap(sg_page(obj->pages->sgl));
+               else
+                       pages = drm_malloc_gfp(obj->base.size >> PAGE_SHIFT,
+                                              sizeof(*pages),
+                                              GFP_TEMPORARY);
+               if (pages != NULL) {
+                       struct sg_page_iter sg_iter;
+                       int n;
+                       n = 0;
+                       for_each_sg_page(obj->pages->sgl, &sg_iter,
+                                        obj->pages->nents, 0)
+                               pages[n++] = sg_page_iter_page(&sg_iter);
+                       obj->mapping = vmap(pages, n, 0, PAGE_KERNEL);
+                       drm_free_large(pages);
+               }
+               if (obj->mapping == NULL) {
+                       i915_gem_object_unpin_pages(obj);
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
+       return obj->mapping;
+ }
  void i915_vma_move_to_active(struct i915_vma *vma,
                             struct drm_i915_gem_request *req)
  {
        struct drm_i915_gem_object *obj = vma->obj;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
  
-       ring = i915_gem_request_get_ring(req);
+       engine = i915_gem_request_get_engine(req);
  
        /* Add a reference if we're newly entering the active list. */
        if (obj->active == 0)
                drm_gem_object_reference(&obj->base);
-       obj->active |= intel_ring_flag(ring);
+       obj->active |= intel_engine_flag(engine);
  
-       list_move_tail(&obj->ring_list[ring->id], &ring->active_list);
-       i915_gem_request_assign(&obj->last_read_req[ring->id], req);
+       list_move_tail(&obj->engine_list[engine->id], &engine->active_list);
+       i915_gem_request_assign(&obj->last_read_req[engine->id], req);
  
        list_move_tail(&vma->vm_link, &vma->vm->active_list);
  }
  static void
  i915_gem_object_retire__write(struct drm_i915_gem_object *obj)
  {
-       RQ_BUG_ON(obj->last_write_req == NULL);
-       RQ_BUG_ON(!(obj->active & intel_ring_flag(obj->last_write_req->ring)));
+       GEM_BUG_ON(obj->last_write_req == NULL);
+       GEM_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write_req->engine)));
  
        i915_gem_request_assign(&obj->last_write_req, NULL);
        intel_fb_obj_flush(obj, true, ORIGIN_CS);
@@@ -2434,13 -2465,13 +2465,13 @@@ i915_gem_object_retire__read(struct drm
  {
        struct i915_vma *vma;
  
-       RQ_BUG_ON(obj->last_read_req[ring] == NULL);
-       RQ_BUG_ON(!(obj->active & (1 << ring)));
+       GEM_BUG_ON(obj->last_read_req[ring] == NULL);
+       GEM_BUG_ON(!(obj->active & (1 << ring)));
  
-       list_del_init(&obj->ring_list[ring]);
+       list_del_init(&obj->engine_list[ring]);
        i915_gem_request_assign(&obj->last_read_req[ring], NULL);
  
-       if (obj->last_write_req && obj->last_write_req->ring->id == ring)
+       if (obj->last_write_req && obj->last_write_req->engine->id == ring)
                i915_gem_object_retire__write(obj);
  
        obj->active &= ~(1 << ring);
@@@ -2467,24 -2498,20 +2498,20 @@@ static in
  i915_gem_init_seqno(struct drm_device *dev, u32 seqno)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int ret, i, j;
+       struct intel_engine_cs *engine;
+       int ret;
  
        /* Carefully retire all requests without writing to the rings */
-       for_each_ring(ring, dev_priv, i) {
-               ret = intel_ring_idle(ring);
+       for_each_engine(engine, dev_priv) {
+               ret = intel_engine_idle(engine);
                if (ret)
                        return ret;
        }
        i915_gem_retire_requests(dev);
  
        /* Finally reset hw state */
-       for_each_ring(ring, dev_priv, i) {
-               intel_ring_init_seqno(ring, seqno);
-               for (j = 0; j < ARRAY_SIZE(ring->semaphore.sync_seqno); j++)
-                       ring->semaphore.sync_seqno[j] = 0;
-       }
+       for_each_engine(engine, dev_priv)
+               intel_ring_init_seqno(engine, seqno);
  
        return 0;
  }
@@@ -2542,7 -2569,7 +2569,7 @@@ void __i915_add_request(struct drm_i915
                        struct drm_i915_gem_object *obj,
                        bool flush_caches)
  {
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct drm_i915_private *dev_priv;
        struct intel_ringbuffer *ringbuf;
        u32 request_start;
        if (WARN_ON(request == NULL))
                return;
  
-       ring = request->ring;
-       dev_priv = ring->dev->dev_private;
+       engine = request->engine;
+       dev_priv = request->i915;
        ringbuf = request->ringbuf;
  
        /*
                WARN(ret, "*_ring_flush_all_caches failed: %d!\n", ret);
        }
  
+       trace_i915_gem_request_add(request);
+       request->head = request_start;
+       /* Whilst this request exists, batch_obj will be on the
+        * active_list, and so will hold the active reference. Only when this
+        * request is retired will the the batch_obj be moved onto the
+        * inactive_list and lose its active reference. Hence we do not need
+        * to explicitly hold another reference here.
+        */
+       request->batch_obj = obj;
+       /* Seal the request and mark it as pending execution. Note that
+        * we may inspect this state, without holding any locks, during
+        * hangcheck. Hence we apply the barrier to ensure that we do not
+        * see a more recent value in the hws than we are tracking.
+        */
+       request->emitted_jiffies = jiffies;
+       request->previous_seqno = engine->last_submitted_seqno;
+       smp_store_mb(engine->last_submitted_seqno, request->seqno);
+       list_add_tail(&request->list, &engine->request_list);
        /* Record the position of the start of the request so that
         * should we detect the updated seqno part-way through the
         * GPU processing the request, we never over-estimate the
        request->postfix = intel_ring_get_tail(ringbuf);
  
        if (i915.enable_execlists)
-               ret = ring->emit_request(request);
+               ret = engine->emit_request(request);
        else {
-               ret = ring->add_request(request);
+               ret = engine->add_request(request);
  
                request->tail = intel_ring_get_tail(ringbuf);
        }
        /* Not allowed to fail! */
        WARN(ret, "emit|add_request failed: %d!\n", ret);
  
-       request->head = request_start;
-       /* Whilst this request exists, batch_obj will be on the
-        * active_list, and so will hold the active reference. Only when this
-        * request is retired will the the batch_obj be moved onto the
-        * inactive_list and lose its active reference. Hence we do not need
-        * to explicitly hold another reference here.
-        */
-       request->batch_obj = obj;
-       request->emitted_jiffies = jiffies;
-       request->previous_seqno = ring->last_submitted_seqno;
-       ring->last_submitted_seqno = request->seqno;
-       list_add_tail(&request->list, &ring->request_list);
-       trace_i915_gem_request_add(request);
-       i915_queue_hangcheck(ring->dev);
+       i915_queue_hangcheck(engine->dev);
  
        queue_delayed_work(dev_priv->wq,
                           &dev_priv->mm.retire_work,
@@@ -2680,7 -2712,7 +2712,7 @@@ void i915_gem_request_free(struct kref 
  
        if (ctx) {
                if (i915.enable_execlists && ctx != req->i915->kernel_context)
-                       intel_lr_context_unpin(ctx, req->ring);
+                       intel_lr_context_unpin(ctx, req->engine);
  
                i915_gem_context_unreference(ctx);
        }
  }
  
  static inline int
- __i915_gem_request_alloc(struct intel_engine_cs *ring,
+ __i915_gem_request_alloc(struct intel_engine_cs *engine,
                         struct intel_context *ctx,
                         struct drm_i915_gem_request **req_out)
  {
-       struct drm_i915_private *dev_priv = to_i915(ring->dev);
+       struct drm_i915_private *dev_priv = to_i915(engine->dev);
+       unsigned reset_counter = i915_reset_counter(&dev_priv->gpu_error);
        struct drm_i915_gem_request *req;
        int ret;
  
  
        *req_out = NULL;
  
+       /* 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.
+        */
+       ret = i915_gem_check_wedge(reset_counter, dev_priv->mm.interruptible);
+       if (ret)
+               return ret;
        req = kmem_cache_zalloc(dev_priv->requests, GFP_KERNEL);
        if (req == NULL)
                return -ENOMEM;
  
-       ret = i915_gem_get_seqno(ring->dev, &req->seqno);
+       ret = i915_gem_get_seqno(engine->dev, &req->seqno);
        if (ret)
                goto err;
  
        kref_init(&req->ref);
        req->i915 = dev_priv;
-       req->ring = ring;
+       req->engine = engine;
+       req->reset_counter = reset_counter;
        req->ctx  = ctx;
        i915_gem_context_reference(req->ctx);
  
                 * fully prepared. Thus it can be cleaned up using the proper
                 * free code.
                 */
-               i915_gem_request_cancel(req);
+               intel_ring_reserved_space_cancel(req->ringbuf);
+               i915_gem_request_unreference(req);
                return ret;
        }
  
@@@ -2779,19 -2822,12 +2822,12 @@@ i915_gem_request_alloc(struct intel_eng
        return err ? ERR_PTR(err) : req;
  }
  
- void i915_gem_request_cancel(struct drm_i915_gem_request *req)
- {
-       intel_ring_reserved_space_cancel(req->ringbuf);
-       i915_gem_request_unreference(req);
- }
  struct drm_i915_gem_request *
- i915_gem_find_active_request(struct intel_engine_cs *ring)
+ i915_gem_find_active_request(struct intel_engine_cs *engine)
  {
        struct drm_i915_gem_request *request;
  
-       list_for_each_entry(request, &ring->request_list, list) {
+       list_for_each_entry(request, &engine->request_list, list) {
                if (i915_gem_request_completed(request, false))
                        continue;
  
        return NULL;
  }
  
- static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv,
-                                      struct intel_engine_cs *ring)
+ static void i915_gem_reset_engine_status(struct drm_i915_private *dev_priv,
+                                      struct intel_engine_cs *engine)
  {
        struct drm_i915_gem_request *request;
        bool ring_hung;
  
-       request = i915_gem_find_active_request(ring);
+       request = i915_gem_find_active_request(engine);
  
        if (request == NULL)
                return;
  
-       ring_hung = ring->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG;
+       ring_hung = engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG;
  
        i915_set_reset_status(dev_priv, request->ctx, ring_hung);
  
-       list_for_each_entry_continue(request, &ring->request_list, list)
+       list_for_each_entry_continue(request, &engine->request_list, list)
                i915_set_reset_status(dev_priv, request->ctx, false);
  }
  
- static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
-                                       struct intel_engine_cs *ring)
+ static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv,
+                                       struct intel_engine_cs *engine)
  {
        struct intel_ringbuffer *buffer;
  
-       while (!list_empty(&ring->active_list)) {
+       while (!list_empty(&engine->active_list)) {
                struct drm_i915_gem_object *obj;
  
-               obj = list_first_entry(&ring->active_list,
+               obj = list_first_entry(&engine->active_list,
                                       struct drm_i915_gem_object,
-                                      ring_list[ring->id]);
+                                      engine_list[engine->id]);
  
-               i915_gem_object_retire__read(obj, ring->id);
+               i915_gem_object_retire__read(obj, engine->id);
        }
  
        /*
         */
  
        if (i915.enable_execlists) {
-               spin_lock_irq(&ring->execlist_lock);
+               /* Ensure irq handler finishes or is cancelled. */
+               tasklet_kill(&engine->irq_tasklet);
  
+               spin_lock_bh(&engine->execlist_lock);
                /* list_splice_tail_init checks for empty lists */
-               list_splice_tail_init(&ring->execlist_queue,
-                                     &ring->execlist_retired_req_list);
+               list_splice_tail_init(&engine->execlist_queue,
+                                     &engine->execlist_retired_req_list);
+               spin_unlock_bh(&engine->execlist_lock);
  
-               spin_unlock_irq(&ring->execlist_lock);
-               intel_execlists_retire_requests(ring);
+               intel_execlists_retire_requests(engine);
        }
  
        /*
         * implicit references on things like e.g. ppgtt address spaces through
         * the request.
         */
-       while (!list_empty(&ring->request_list)) {
+       while (!list_empty(&engine->request_list)) {
                struct drm_i915_gem_request *request;
  
-               request = list_first_entry(&ring->request_list,
+               request = list_first_entry(&engine->request_list,
                                           struct drm_i915_gem_request,
                                           list);
  
         * upon reset is less than when we start. Do one more pass over
         * all the ringbuffers to reset last_retired_head.
         */
-       list_for_each_entry(buffer, &ring->buffers, link) {
+       list_for_each_entry(buffer, &engine->buffers, link) {
                buffer->last_retired_head = buffer->tail;
                intel_ring_update_space(buffer);
        }
+       intel_ring_init_seqno(engine, engine->last_submitted_seqno);
  }
  
  void i915_gem_reset(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int i;
+       struct intel_engine_cs *engine;
  
        /*
         * Before we free the objects from the requests, we need to inspect
         * them for finding the guilty party. As the requests only borrow
         * their reference to the objects, the inspection must be done first.
         */
-       for_each_ring(ring, dev_priv, i)
-               i915_gem_reset_ring_status(dev_priv, ring);
+       for_each_engine(engine, dev_priv)
+               i915_gem_reset_engine_status(dev_priv, engine);
  
-       for_each_ring(ring, dev_priv, i)
-               i915_gem_reset_ring_cleanup(dev_priv, ring);
+       for_each_engine(engine, dev_priv)
+               i915_gem_reset_engine_cleanup(dev_priv, engine);
  
        i915_gem_context_reset(dev);
  
   * This function clears the request list as sequence numbers are passed.
   */
  void
- i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
+ i915_gem_retire_requests_ring(struct intel_engine_cs *engine)
  {
-       WARN_ON(i915_verify_lists(ring->dev));
+       WARN_ON(i915_verify_lists(engine->dev));
  
        /* Retire requests first as we use it above for the early return.
         * If we retire requests last, we may use a later seqno and so clear
         * the requests lists without clearing the active list, leading to
         * confusion.
         */
-       while (!list_empty(&ring->request_list)) {
+       while (!list_empty(&engine->request_list)) {
                struct drm_i915_gem_request *request;
  
-               request = list_first_entry(&ring->request_list,
+               request = list_first_entry(&engine->request_list,
                                           struct drm_i915_gem_request,
                                           list);
  
         * by the ringbuffer to the flushing/inactive lists as appropriate,
         * before we free the context associated with the requests.
         */
-       while (!list_empty(&ring->active_list)) {
+       while (!list_empty(&engine->active_list)) {
                struct drm_i915_gem_object *obj;
  
-               obj = list_first_entry(&ring->active_list,
-                                     struct drm_i915_gem_object,
-                                     ring_list[ring->id]);
+               obj = list_first_entry(&engine->active_list,
+                                      struct drm_i915_gem_object,
+                                      engine_list[engine->id]);
  
-               if (!list_empty(&obj->last_read_req[ring->id]->list))
+               if (!list_empty(&obj->last_read_req[engine->id]->list))
                        break;
  
-               i915_gem_object_retire__read(obj, ring->id);
+               i915_gem_object_retire__read(obj, engine->id);
        }
  
-       if (unlikely(ring->trace_irq_req &&
-                    i915_gem_request_completed(ring->trace_irq_req, true))) {
-               ring->irq_put(ring);
-               i915_gem_request_assign(&ring->trace_irq_req, NULL);
+       if (unlikely(engine->trace_irq_req &&
+                    i915_gem_request_completed(engine->trace_irq_req, true))) {
+               engine->irq_put(engine);
+               i915_gem_request_assign(&engine->trace_irq_req, NULL);
        }
  
-       WARN_ON(i915_verify_lists(ring->dev));
+       WARN_ON(i915_verify_lists(engine->dev));
  }
  
  bool
  i915_gem_retire_requests(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        bool idle = true;
-       int i;
  
-       for_each_ring(ring, dev_priv, i) {
-               i915_gem_retire_requests_ring(ring);
-               idle &= list_empty(&ring->request_list);
+       for_each_engine(engine, dev_priv) {
+               i915_gem_retire_requests_ring(engine);
+               idle &= list_empty(&engine->request_list);
                if (i915.enable_execlists) {
-                       spin_lock_irq(&ring->execlist_lock);
-                       idle &= list_empty(&ring->execlist_queue);
-                       spin_unlock_irq(&ring->execlist_lock);
+                       spin_lock_bh(&engine->execlist_lock);
+                       idle &= list_empty(&engine->execlist_queue);
+                       spin_unlock_bh(&engine->execlist_lock);
  
-                       intel_execlists_retire_requests(ring);
+                       intel_execlists_retire_requests(engine);
                }
        }
  
@@@ -3011,25 -3049,21 +3049,21 @@@ i915_gem_idle_work_handler(struct work_
        struct drm_i915_private *dev_priv =
                container_of(work, typeof(*dev_priv), mm.idle_work.work);
        struct drm_device *dev = dev_priv->dev;
-       struct intel_engine_cs *ring;
-       int i;
+       struct intel_engine_cs *engine;
  
-       for_each_ring(ring, dev_priv, i)
-               if (!list_empty(&ring->request_list))
+       for_each_engine(engine, dev_priv)
+               if (!list_empty(&engine->request_list))
                        return;
  
        /* we probably should sync with hangcheck here, using cancel_work_sync.
-        * Also locking seems to be fubar here, ring->request_list is protected
+        * Also locking seems to be fubar here, engine->request_list is protected
         * by dev->struct_mutex. */
  
        intel_mark_idle(dev);
  
        if (mutex_trylock(&dev->struct_mutex)) {
-               struct intel_engine_cs *ring;
-               int i;
-               for_each_ring(ring, dev_priv, i)
-                       i915_gem_batch_pool_fini(&ring->batch_pool);
+               for_each_engine(engine, dev_priv)
+                       i915_gem_batch_pool_fini(&engine->batch_pool);
  
                mutex_unlock(&dev->struct_mutex);
        }
@@@ -3048,7 -3082,7 +3082,7 @@@ i915_gem_object_flush_active(struct drm
        if (!obj->active)
                return 0;
  
-       for (i = 0; i < I915_NUM_RINGS; i++) {
+       for (i = 0; i < I915_NUM_ENGINES; i++) {
                struct drm_i915_gem_request *req;
  
                req = obj->last_read_req[i];
@@@ -3093,11 -3127,9 +3127,9 @@@ retire
  int
  i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_wait *args = data;
        struct drm_i915_gem_object *obj;
-       struct drm_i915_gem_request *req[I915_NUM_RINGS];
-       unsigned reset_counter;
+       struct drm_i915_gem_request *req[I915_NUM_ENGINES];
        int i, n = 0;
        int ret;
  
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->bo_handle));
        if (&obj->base == NULL) {
                mutex_unlock(&dev->struct_mutex);
                return -ENOENT;
        }
  
        drm_gem_object_unreference(&obj->base);
-       reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
  
-       for (i = 0; i < I915_NUM_RINGS; i++) {
+       for (i = 0; i < I915_NUM_ENGINES; i++) {
                if (obj->last_read_req[i] == NULL)
                        continue;
  
  
        for (i = 0; i < n; i++) {
                if (ret == 0)
-                       ret = __i915_wait_request(req[i], reset_counter, true,
+                       ret = __i915_wait_request(req[i], true,
                                                  args->timeout_ns > 0 ? &args->timeout_ns : NULL,
                                                  to_rps_client(file));
                i915_gem_request_unreference__unlocked(req[i]);
@@@ -3166,7 -3197,7 +3197,7 @@@ __i915_gem_object_sync(struct drm_i915_
        struct intel_engine_cs *from;
        int ret;
  
-       from = i915_gem_request_get_ring(from_req);
+       from = i915_gem_request_get_engine(from_req);
        if (to == from)
                return 0;
  
        if (!i915_semaphore_is_enabled(obj->base.dev)) {
                struct drm_i915_private *i915 = to_i915(obj->base.dev);
                ret = __i915_wait_request(from_req,
-                                         atomic_read(&i915->gpu_error.reset_counter),
                                          i915->mm.interruptible,
                                          NULL,
                                          &i915->rps.semaphores);
@@@ -3260,7 -3290,7 +3290,7 @@@ i915_gem_object_sync(struct drm_i915_ge
                     struct drm_i915_gem_request **to_req)
  {
        const bool readonly = obj->base.pending_write_domain == 0;
-       struct drm_i915_gem_request *req[I915_NUM_RINGS];
+       struct drm_i915_gem_request *req[I915_NUM_ENGINES];
        int ret, i, n;
  
        if (!obj->active)
                if (obj->last_write_req)
                        req[n++] = obj->last_write_req;
        } else {
-               for (i = 0; i < I915_NUM_RINGS; i++)
+               for (i = 0; i < I915_NUM_ENGINES; i++)
                        if (obj->last_read_req[i])
                                req[n++] = obj->last_read_req[i];
        }
@@@ -3297,9 -3327,6 +3327,6 @@@ static void i915_gem_object_finish_gtt(
        if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
                return;
  
-       /* Wait for any direct GTT access to complete */
-       mb();
        old_read_domains = obj->base.read_domains;
        old_write_domain = obj->base.write_domain;
  
@@@ -3391,28 -3418,25 +3418,25 @@@ int __i915_vma_unbind_no_wait(struct i9
  int i915_gpu_idle(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int ret, i;
+       struct intel_engine_cs *engine;
+       int ret;
  
        /* Flush everything onto the inactive list. */
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                if (!i915.enable_execlists) {
                        struct drm_i915_gem_request *req;
  
-                       req = i915_gem_request_alloc(ring, NULL);
+                       req = i915_gem_request_alloc(engine, NULL);
                        if (IS_ERR(req))
                                return PTR_ERR(req);
  
                        ret = i915_switch_context(req);
-                       if (ret) {
-                               i915_gem_request_cancel(req);
-                               return ret;
-                       }
                        i915_add_request_no_flush(req);
+                       if (ret)
+                               return ret;
                }
  
-               ret = intel_ring_idle(ring);
+               ret = intel_engine_idle(engine);
                if (ret)
                        return ret;
        }
@@@ -3466,7 -3490,8 +3490,8 @@@ i915_gem_object_bind_to_vm(struct drm_i
                           uint64_t flags)
  {
        struct drm_device *dev = obj->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        u32 fence_alignment, unfenced_alignment;
        u32 search_flag, alloc_flag;
        u64 start, end;
        start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
        end = vm->total;
        if (flags & PIN_MAPPABLE)
-               end = min_t(u64, end, dev_priv->gtt.mappable_end);
+               end = min_t(u64, end, ggtt->mappable_end);
        if (flags & PIN_ZONE_4G)
                end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE);
  
@@@ -3720,6 -3745,9 +3745,9 @@@ i915_gem_object_flush_cpu_write_domain(
  int
  i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
  {
+       struct drm_device *dev = obj->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        uint32_t old_write_domain, old_read_domains;
        struct i915_vma *vma;
        int ret;
        vma = i915_gem_obj_to_ggtt(obj);
        if (vma && drm_mm_node_allocated(&vma->node) && !obj->active)
                list_move_tail(&vma->vm_link,
-                              &to_i915(obj->base.dev)->gtt.base.inactive_list);
+                              &ggtt->base.inactive_list);
  
        return 0;
  }
@@@ -3906,7 -3934,7 +3934,7 @@@ int i915_gem_get_caching_ioctl(struct d
        struct drm_i915_gem_caching *args = data;
        struct drm_i915_gem_object *obj;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL)
                return -ENOENT;
  
@@@ -3949,7 -3977,7 +3977,7 @@@ int i915_gem_set_caching_ioctl(struct d
                 * cacheline, whereas normally such cachelines would get
                 * invalidated.
                 */
-               if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+               if (!HAS_LLC(dev) && !HAS_SNOOP(dev))
                        return -ENODEV;
  
                level = I915_CACHE_LLC;
        if (ret)
                goto rpm_put;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -4128,16 -4156,15 +4156,15 @@@ i915_gem_ring_throttle(struct drm_devic
        struct drm_i915_file_private *file_priv = file->driver_priv;
        unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES;
        struct drm_i915_gem_request *request, *target = NULL;
-       unsigned reset_counter;
        int ret;
  
        ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
        if (ret)
                return ret;
  
-       ret = i915_gem_check_wedge(&dev_priv->gpu_error, false);
-       if (ret)
-               return ret;
+       /* ABI: return -EIO if already wedged */
+       if (i915_terminally_wedged(&dev_priv->gpu_error))
+               return -EIO;
  
        spin_lock(&file_priv->mm.lock);
        list_for_each_entry(request, &file_priv->mm.request_list, client_list) {
  
                target = request;
        }
-       reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
        if (target)
                i915_gem_request_reference(target);
        spin_unlock(&file_priv->mm.lock);
        if (target == NULL)
                return 0;
  
-       ret = __i915_wait_request(target, reset_counter, true, NULL, NULL);
+       ret = __i915_wait_request(target, true, NULL, NULL);
        if (ret == 0)
                queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
  
@@@ -4211,7 -4237,7 +4237,7 @@@ void __i915_vma_set_map_and_fenceable(s
                     (vma->node.start & (fence_alignment - 1)) == 0);
  
        mappable = (vma->node.start + fence_size <=
-                   to_i915(obj->base.dev)->gtt.mappable_end);
+                   to_i915(obj->base.dev)->ggtt.mappable_end);
  
        obj->map_and_fenceable = mappable && fenceable;
  }
@@@ -4243,9 -4269,6 +4269,6 @@@ i915_gem_object_do_pin(struct drm_i915_
        vma = ggtt_view ? i915_gem_obj_to_ggtt_view(obj, ggtt_view) :
                          i915_gem_obj_to_vma(obj, vm);
  
-       if (IS_ERR(vma))
-               return PTR_ERR(vma);
        if (vma) {
                if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
                        return -EBUSY;
@@@ -4308,10 -4331,13 +4331,13 @@@ i915_gem_object_ggtt_pin(struct drm_i91
                         uint32_t alignment,
                         uint64_t flags)
  {
-       if (WARN_ONCE(!view, "no view specified"))
-               return -EINVAL;
+       struct drm_device *dev = obj->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
+       BUG_ON(!view);
  
-       return i915_gem_object_do_pin(obj, i915_obj_to_ggtt(obj), view,
+       return i915_gem_object_do_pin(obj, &ggtt->base, view,
                                      alignment, flags | PIN_GLOBAL);
  }
  
@@@ -4321,7 -4347,6 +4347,6 @@@ i915_gem_object_ggtt_unpin_view(struct 
  {
        struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view);
  
-       BUG_ON(!vma);
        WARN_ON(vma->pin_count == 0);
        WARN_ON(!i915_gem_obj_ggtt_bound_view(obj, view));
  
@@@ -4340,7 -4365,7 +4365,7 @@@ i915_gem_busy_ioctl(struct drm_device *
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
        if (obj->active) {
                int i;
  
-               for (i = 0; i < I915_NUM_RINGS; i++) {
+               for (i = 0; i < I915_NUM_ENGINES; i++) {
                        struct drm_i915_gem_request *req;
  
                        req = obj->last_read_req[i];
                        if (req)
-                               args->busy |= 1 << (16 + req->ring->exec_id);
+                               args->busy |= 1 << (16 + req->engine->exec_id);
                }
                if (obj->last_write_req)
-                       args->busy |= obj->last_write_req->ring->exec_id;
+                       args->busy |= obj->last_write_req->engine->exec_id;
        }
  
  unref:
@@@ -4405,7 -4430,7 +4430,7 @@@ i915_gem_madvise_ioctl(struct drm_devic
        if (ret)
                return ret;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle));
+       obj = to_intel_bo(drm_gem_object_lookup(file_priv, args->handle));
        if (&obj->base == NULL) {
                ret = -ENOENT;
                goto unlock;
@@@ -4447,8 -4472,8 +4472,8 @@@ void i915_gem_object_init(struct drm_i9
        int i;
  
        INIT_LIST_HEAD(&obj->global_list);
-       for (i = 0; i < I915_NUM_RINGS; i++)
-               INIT_LIST_HEAD(&obj->ring_list[i]);
+       for (i = 0; i < I915_NUM_ENGINES; i++)
+               INIT_LIST_HEAD(&obj->engine_list[i]);
        INIT_LIST_HEAD(&obj->obj_exec_link);
        INIT_LIST_HEAD(&obj->vma_list);
        INIT_LIST_HEAD(&obj->batch_pool_link);
@@@ -4623,14 -4648,15 +4648,15 @@@ struct i915_vma *i915_gem_obj_to_vma(st
  struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
                                           const struct i915_ggtt_view *view)
  {
-       struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
+       struct drm_device *dev = obj->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct i915_vma *vma;
  
-       if (WARN_ONCE(!view, "no view specified"))
-               return ERR_PTR(-EINVAL);
+       BUG_ON(!view);
  
        list_for_each_entry(vma, &obj->vma_list, obj_link)
-               if (vma->vm == ggtt &&
+               if (vma->vm == &ggtt->base &&
                    i915_ggtt_view_equal(&vma->ggtt_view, view))
                        return vma;
        return NULL;
@@@ -4653,14 -4679,13 +4679,13 @@@ void i915_gem_vma_destroy(struct i915_v
  }
  
  static void
- i915_gem_stop_ringbuffers(struct drm_device *dev)
+ i915_gem_stop_engines(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int i;
+       struct intel_engine_cs *engine;
  
-       for_each_ring(ring, dev_priv, i)
-               dev_priv->gt.stop_ring(ring);
+       for_each_engine(engine, dev_priv)
+               dev_priv->gt.stop_engine(engine);
  }
  
  int
@@@ -4676,7 -4701,7 +4701,7 @@@ i915_gem_suspend(struct drm_device *dev
  
        i915_gem_retire_requests(dev);
  
-       i915_gem_stop_ringbuffers(dev);
+       i915_gem_stop_engines(dev);
        mutex_unlock(&dev->struct_mutex);
  
        cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
@@@ -4697,8 -4722,8 +4722,8 @@@ err
  
  int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice)
  {
-       struct intel_engine_cs *ring = req->ring;
-       struct drm_device *dev = ring->dev;
+       struct intel_engine_cs *engine = req->engine;
+       struct drm_device *dev = engine->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 *remap_info = dev_priv->l3_parity.remap_info[slice];
        int i, ret;
         * at initialization time.
         */
        for (i = 0; i < GEN7_L3LOG_SIZE / 4; i++) {
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, GEN7_L3LOG(slice, i));
-               intel_ring_emit(ring, remap_info[i]);
+               intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+               intel_ring_emit_reg(engine, GEN7_L3LOG(slice, i));
+               intel_ring_emit(engine, remap_info[i]);
        }
  
-       intel_ring_advance(ring);
+       intel_ring_advance(engine);
  
        return ret;
  }
@@@ -4778,7 -4803,7 +4803,7 @@@ static void init_unused_rings(struct dr
        }
  }
  
- int i915_gem_init_rings(struct drm_device *dev)
+ int i915_gem_init_engines(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
        return 0;
  
  cleanup_vebox_ring:
-       intel_cleanup_ring_buffer(&dev_priv->ring[VECS]);
+       intel_cleanup_engine(&dev_priv->engine[VECS]);
  cleanup_blt_ring:
-       intel_cleanup_ring_buffer(&dev_priv->ring[BCS]);
+       intel_cleanup_engine(&dev_priv->engine[BCS]);
  cleanup_bsd_ring:
-       intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
+       intel_cleanup_engine(&dev_priv->engine[VCS]);
  cleanup_render_ring:
-       intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
+       intel_cleanup_engine(&dev_priv->engine[RCS]);
  
        return ret;
  }
@@@ -4829,8 -4854,8 +4854,8 @@@ in
  i915_gem_init_hw(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int ret, i, j;
+       struct intel_engine_cs *engine;
+       int ret, j;
  
        if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
                return -EIO;
        /* Double layer security blanket, see i915_gem_init() */
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
  
-       if (dev_priv->ellc_size)
+       if (HAS_EDRAM(dev) && INTEL_GEN(dev_priv) < 9)
                I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
  
        if (IS_HASWELL(dev))
        }
  
        /* Need to do basic initialisation of all rings first: */
-       for_each_ring(ring, dev_priv, i) {
-               ret = ring->init_hw(ring);
+       for_each_engine(engine, dev_priv) {
+               ret = engine->init_hw(engine);
                if (ret)
                        goto out;
        }
  
+       intel_mocs_init_l3cc_table(dev);
        /* We can't enable contexts until all firmware is loaded */
        if (HAS_GUC_UCODE(dev)) {
                ret = intel_guc_ucode_load(dev);
                goto out;
  
        /* Now it is safe to go back round and do everything else: */
-       for_each_ring(ring, dev_priv, i) {
+       for_each_engine(engine, dev_priv) {
                struct drm_i915_gem_request *req;
  
-               req = i915_gem_request_alloc(ring, NULL);
+               req = i915_gem_request_alloc(engine, NULL);
                if (IS_ERR(req)) {
                        ret = PTR_ERR(req);
-                       i915_gem_cleanup_ringbuffer(dev);
-                       goto out;
+                       break;
                }
  
-               if (ring->id == RCS) {
-                       for (j = 0; j < NUM_L3_SLICES(dev); j++)
-                               i915_gem_l3_remap(req, j);
+               if (engine->id == RCS) {
+                       for (j = 0; j < NUM_L3_SLICES(dev); j++) {
+                               ret = i915_gem_l3_remap(req, j);
+                               if (ret)
+                                       goto err_request;
+                       }
                }
  
                ret = i915_ppgtt_init_ring(req);
-               if (ret && ret != -EIO) {
-                       DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret);
-                       i915_gem_request_cancel(req);
-                       i915_gem_cleanup_ringbuffer(dev);
-                       goto out;
-               }
+               if (ret)
+                       goto err_request;
  
                ret = i915_gem_context_enable(req);
-               if (ret && ret != -EIO) {
-                       DRM_ERROR("Context enable ring #%d failed %d\n", i, ret);
-                       i915_gem_request_cancel(req);
-                       i915_gem_cleanup_ringbuffer(dev);
-                       goto out;
-               }
+               if (ret)
+                       goto err_request;
  
+ err_request:
                i915_add_request_no_flush(req);
+               if (ret) {
+                       DRM_ERROR("Failed to enable %s, error=%d\n",
+                                 engine->name, ret);
+                       i915_gem_cleanup_engines(dev);
+                       break;
+               }
        }
  
  out:
@@@ -4952,14 -4980,14 +4980,14 @@@ int i915_gem_init(struct drm_device *de
  
        if (!i915.enable_execlists) {
                dev_priv->gt.execbuf_submit = i915_gem_ringbuffer_submission;
-               dev_priv->gt.init_rings = i915_gem_init_rings;
-               dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer;
-               dev_priv->gt.stop_ring = intel_stop_ring_buffer;
+               dev_priv->gt.init_engines = i915_gem_init_engines;
+               dev_priv->gt.cleanup_engine = intel_cleanup_engine;
+               dev_priv->gt.stop_engine = intel_stop_engine;
        } else {
                dev_priv->gt.execbuf_submit = intel_execlists_submission;
-               dev_priv->gt.init_rings = intel_logical_rings_init;
-               dev_priv->gt.cleanup_ring = intel_logical_ring_cleanup;
-               dev_priv->gt.stop_ring = intel_logical_ring_stop;
+               dev_priv->gt.init_engines = intel_logical_rings_init;
+               dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup;
+               dev_priv->gt.stop_engine = intel_logical_ring_stop;
        }
  
        /* This is just a security blanket to placate dragons.
        if (ret)
                goto out_unlock;
  
-       i915_gem_init_global_gtt(dev);
+       i915_gem_init_ggtt(dev);
  
        ret = i915_gem_context_init(dev);
        if (ret)
                goto out_unlock;
  
-       ret = dev_priv->gt.init_rings(dev);
+       ret = dev_priv->gt.init_engines(dev);
        if (ret)
                goto out_unlock;
  
@@@ -5003,29 -5031,52 +5031,52 @@@ out_unlock
  }
  
  void
- i915_gem_cleanup_ringbuffer(struct drm_device *dev)
+ i915_gem_cleanup_engines(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
-       int i;
+       struct intel_engine_cs *engine;
  
-       for_each_ring(ring, dev_priv, i)
-               dev_priv->gt.cleanup_ring(ring);
+       for_each_engine(engine, dev_priv)
+               dev_priv->gt.cleanup_engine(engine);
  
-     if (i915.enable_execlists)
-             /*
-              * Neither the BIOS, ourselves or any other kernel
-              * expects the system to be in execlists mode on startup,
-              * so we need to reset the GPU back to legacy mode.
-              */
-             intel_gpu_reset(dev);
+       if (i915.enable_execlists)
+               /*
+                * Neither the BIOS, ourselves or any other kernel
+                * expects the system to be in execlists mode on startup,
+                * so we need to reset the GPU back to legacy mode.
+                */
+               intel_gpu_reset(dev, ALL_ENGINES);
  }
  
  static void
- init_ring_lists(struct intel_engine_cs *ring)
+ init_engine_lists(struct intel_engine_cs *engine)
  {
-       INIT_LIST_HEAD(&ring->active_list);
-       INIT_LIST_HEAD(&ring->request_list);
+       INIT_LIST_HEAD(&engine->active_list);
+       INIT_LIST_HEAD(&engine->request_list);
+ }
+ void
+ i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
+ {
+       struct drm_device *dev = dev_priv->dev;
+       if (INTEL_INFO(dev_priv)->gen >= 7 && !IS_VALLEYVIEW(dev_priv) &&
+           !IS_CHERRYVIEW(dev_priv))
+               dev_priv->num_fence_regs = 32;
+       else if (INTEL_INFO(dev_priv)->gen >= 4 || IS_I945G(dev_priv) ||
+                IS_I945GM(dev_priv) || IS_G33(dev_priv))
+               dev_priv->num_fence_regs = 16;
+       else
+               dev_priv->num_fence_regs = 8;
+       if (intel_vgpu_active(dev))
+               dev_priv->num_fence_regs =
+                               I915_READ(vgtif_reg(avail_rs.fence_num));
+       /* Initialize fence registers to zero */
+       i915_gem_restore_fences(dev);
+       i915_gem_detect_bit_6_swizzle(dev);
  }
  
  void
@@@ -5055,8 -5106,8 +5106,8 @@@ i915_gem_load_init(struct drm_device *d
        INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
        INIT_LIST_HEAD(&dev_priv->mm.bound_list);
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
-       for (i = 0; i < I915_NUM_RINGS; i++)
-               init_ring_lists(&dev_priv->ring[i]);
+       for (i = 0; i < I915_NUM_ENGINES; i++)
+               init_engine_lists(&dev_priv->engine[i]);
        for (i = 0; i < I915_MAX_NUM_FENCES; i++)
                INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
  
        dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
  
-       if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev))
-               dev_priv->num_fence_regs = 32;
-       else if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
-               dev_priv->num_fence_regs = 16;
-       else
-               dev_priv->num_fence_regs = 8;
-       if (intel_vgpu_active(dev))
-               dev_priv->num_fence_regs =
-                               I915_READ(vgtif_reg(avail_rs.fence_num));
        /*
         * Set initial sequence number for requests.
         * Using this number allows the wraparound to happen early,
        dev_priv->next_seqno = ((u32)~0 - 0x1100);
        dev_priv->last_seqno = ((u32)~0 - 0x1101);
  
-       /* Initialize fence registers to zero */
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
-       i915_gem_restore_fences(dev);
  
-       i915_gem_detect_bit_6_swizzle(dev);
        init_waitqueue_head(&dev_priv->pending_flip_queue);
  
        dev_priv->mm.interruptible = true;
@@@ -5213,11 -5250,12 +5250,12 @@@ u64 i915_gem_obj_offset(struct drm_i915
  u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
                                  const struct i915_ggtt_view *view)
  {
-       struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
+       struct drm_i915_private *dev_priv = to_i915(o->base.dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct i915_vma *vma;
  
        list_for_each_entry(vma, &o->vma_list, obj_link)
-               if (vma->vm == ggtt &&
+               if (vma->vm == &ggtt->base &&
                    i915_ggtt_view_equal(&vma->ggtt_view, view))
                        return vma->node.start;
  
@@@ -5244,11 -5282,12 +5282,12 @@@ bool i915_gem_obj_bound(struct drm_i915
  bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
                                  const struct i915_ggtt_view *view)
  {
-       struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
+       struct drm_i915_private *dev_priv = to_i915(o->base.dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct i915_vma *vma;
  
        list_for_each_entry(vma, &o->vma_list, obj_link)
-               if (vma->vm == ggtt &&
+               if (vma->vm == &ggtt->base &&
                    i915_ggtt_view_equal(&vma->ggtt_view, view) &&
                    drm_mm_node_allocated(&vma->node))
                        return true;
index d4d7c88ab595436cce00b48bbd7b5d5c6cf83d31,6f4f2a6cdf93640e8bdf05d487f354aa0174c676..33df74d98269c83bf6fa6d45f852839a959ff724
@@@ -313,7 -313,8 +313,8 @@@ relocate_entry_gtt(struct drm_i915_gem_
                   uint64_t target_offset)
  {
        struct drm_device *dev = obj->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        uint64_t delta = relocation_target(reloc, target_offset);
        uint64_t offset;
        void __iomem *reloc_page;
        /* Map the page containing the relocation we're going to perform.  */
        offset = i915_gem_obj_ggtt_offset(obj);
        offset += reloc->offset;
-       reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
+       reloc_page = io_mapping_map_atomic_wc(ggtt->mappable,
                                              offset & PAGE_MASK);
        iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset));
  
                if (offset_in_page(offset) == 0) {
                        io_mapping_unmap_atomic(reloc_page);
                        reloc_page =
-                               io_mapping_map_atomic_wc(dev_priv->gtt.mappable,
+                               io_mapping_map_atomic_wc(ggtt->mappable,
                                                         offset);
                }
  
@@@ -488,7 -489,7 +489,7 @@@ i915_gem_execbuffer_relocate_entry(stru
                ret = relocate_entry_cpu(obj, reloc, target_offset);
        else if (obj->map_and_fenceable)
                ret = relocate_entry_gtt(obj, reloc, target_offset);
 -      else if (cpu_has_clflush)
 +      else if (static_cpu_has(X86_FEATURE_CLFLUSH))
                ret = relocate_entry_clflush(obj, reloc, target_offset);
        else {
                WARN_ONCE(1, "Impossible case in relocation handling\n");
@@@ -514,7 -515,7 +515,7 @@@ i915_gem_execbuffer_relocate_vma(struc
        struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
        int remain, ret;
  
 -      user_relocs = to_user_ptr(entry->relocs_ptr);
 +      user_relocs = u64_to_user_ptr(entry->relocs_ptr);
  
        remain = entry->relocation_count;
        while (remain) {
                                return ret;
  
                        if (r->presumed_offset != offset &&
 -                          __copy_to_user_inatomic(&user_relocs->presumed_offset,
 -                                                  &r->presumed_offset,
 -                                                  sizeof(r->presumed_offset))) {
 +                          __put_user(r->presumed_offset, &user_relocs->presumed_offset)) {
                                return -EFAULT;
                        }
  
@@@ -597,7 -600,7 +598,7 @@@ static bool only_mappable_for_reloc(uns
  
  static int
  i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
-                               struct intel_engine_cs *ring,
+                               struct intel_engine_cs *engine,
                                bool *need_reloc)
  {
        struct drm_i915_gem_object *obj = vma->obj;
@@@ -711,7 -714,7 +712,7 @@@ eb_vma_misplaced(struct i915_vma *vma
  }
  
  static int
- i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,
+ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
                            struct list_head *vmas,
                            struct intel_context *ctx,
                            bool *need_relocs)
        struct i915_address_space *vm;
        struct list_head ordered_vmas;
        struct list_head pinned_vmas;
-       bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
+       bool has_fenced_gpu_access = INTEL_INFO(engine->dev)->gen < 4;
        int retry;
  
-       i915_gem_retire_requests_ring(ring);
+       i915_gem_retire_requests_ring(engine);
  
        vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
  
                        if (eb_vma_misplaced(vma))
                                ret = i915_vma_unbind(vma);
                        else
-                               ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
+                               ret = i915_gem_execbuffer_reserve_vma(vma,
+                                                                     engine,
+                                                                     need_relocs);
                        if (ret)
                                goto err;
                }
                        if (drm_mm_node_allocated(&vma->node))
                                continue;
  
-                       ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs);
+                       ret = i915_gem_execbuffer_reserve_vma(vma, engine,
+                                                             need_relocs);
                        if (ret)
                                goto err;
                }
@@@ -819,7 -825,7 +823,7 @@@ static in
  i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
                                  struct drm_i915_gem_execbuffer2 *args,
                                  struct drm_file *file,
-                                 struct intel_engine_cs *ring,
+                                 struct intel_engine_cs *engine,
                                  struct eb_vmas *eb,
                                  struct drm_i915_gem_exec_object2 *exec,
                                  struct intel_context *ctx)
                u64 invalid_offset = (u64)-1;
                int j;
  
 -              user_relocs = to_user_ptr(exec[i].relocs_ptr);
 +              user_relocs = u64_to_user_ptr(exec[i].relocs_ptr);
  
                if (copy_from_user(reloc+total, user_relocs,
                                   exec[i].relocation_count * sizeof(*reloc))) {
                goto err;
  
        need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
-       ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, ctx, &need_relocs);
+       ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx,
+                                         &need_relocs);
        if (ret)
                goto err;
  
@@@ -936,7 -943,7 +941,7 @@@ static in
  i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req,
                                struct list_head *vmas)
  {
-       const unsigned other_rings = ~intel_ring_flag(req->ring);
+       const unsigned other_rings = ~intel_engine_flag(req->engine);
        struct i915_vma *vma;
        uint32_t flush_domains = 0;
        bool flush_chipset = false;
                struct drm_i915_gem_object *obj = vma->obj;
  
                if (obj->active & other_rings) {
-                       ret = i915_gem_object_sync(obj, req->ring, &req);
+                       ret = i915_gem_object_sync(obj, req->engine, &req);
                        if (ret)
                                return ret;
                }
        }
  
        if (flush_chipset)
-               i915_gem_chipset_flush(req->ring->dev);
+               i915_gem_chipset_flush(req->engine->dev);
  
        if (flush_domains & I915_GEM_DOMAIN_GTT)
                wmb();
@@@ -1007,7 -1014,7 +1012,7 @@@ validate_exec_list(struct drm_device *d
                invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
  
        for (i = 0; i < count; i++) {
 -              char __user *ptr = to_user_ptr(exec[i].relocs_ptr);
 +              char __user *ptr = u64_to_user_ptr(exec[i].relocs_ptr);
                int length; /* limited by fault_in_pages_readable() */
  
                if (exec[i].flags & invalid_flags)
  
  static struct intel_context *
  i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
-                         struct intel_engine_cs *ring, const u32 ctx_id)
+                         struct intel_engine_cs *engine, const u32 ctx_id)
  {
        struct intel_context *ctx = NULL;
        struct i915_ctx_hang_stats *hs;
  
-       if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE)
+       if (engine->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE)
                return ERR_PTR(-EINVAL);
  
        ctx = i915_gem_context_get(file->driver_priv, ctx_id);
                return ERR_PTR(-EIO);
        }
  
-       if (i915.enable_execlists && !ctx->engine[ring->id].state) {
-               int ret = intel_lr_context_deferred_alloc(ctx, ring);
+       if (i915.enable_execlists && !ctx->engine[engine->id].state) {
+               int ret = intel_lr_context_deferred_alloc(ctx, engine);
                if (ret) {
                        DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret);
                        return ERR_PTR(ret);
@@@ -1093,7 -1100,7 +1098,7 @@@ voi
  i915_gem_execbuffer_move_to_active(struct list_head *vmas,
                                   struct drm_i915_gem_request *req)
  {
-       struct intel_engine_cs *ring = i915_gem_request_get_ring(req);
+       struct intel_engine_cs *engine = i915_gem_request_get_engine(req);
        struct i915_vma *vma;
  
        list_for_each_entry(vma, vmas, exec_list) {
                if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
                        i915_gem_request_assign(&obj->last_fenced_req, req);
                        if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
-                               struct drm_i915_private *dev_priv = to_i915(ring->dev);
+                               struct drm_i915_private *dev_priv = to_i915(engine->dev);
                                list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
                                               &dev_priv->mm.fence_list);
                        }
        }
  }
  
- void
static void
  i915_gem_execbuffer_retire_commands(struct i915_execbuffer_params *params)
  {
        /* Unconditionally force add_request to emit a full flush. */
-       params->ring->gpu_caches_dirty = true;
+       params->engine->gpu_caches_dirty = true;
  
        /* Add a breadcrumb for the completion of the batch buffer */
        __i915_add_request(params->request, params->batch_obj, true);
@@@ -1144,11 -1151,11 +1149,11 @@@ static in
  i915_reset_gen7_sol_offsets(struct drm_device *dev,
                            struct drm_i915_gem_request *req)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret, i;
  
-       if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS]) {
+       if (!IS_GEN7(dev) || engine != &dev_priv->engine[RCS]) {
                DRM_DEBUG("sol reset is gen7/rcs only\n");
                return -EINVAL;
        }
                return ret;
  
        for (i = 0; i < 4; i++) {
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, GEN7_SO_WRITE_OFFSET(i));
-               intel_ring_emit(ring, 0);
+               intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+               intel_ring_emit_reg(engine, GEN7_SO_WRITE_OFFSET(i));
+               intel_ring_emit(engine, 0);
        }
  
-       intel_ring_advance(ring);
+       intel_ring_advance(engine);
  
        return 0;
  }
  
  static struct drm_i915_gem_object*
- i915_gem_execbuffer_parse(struct intel_engine_cs *ring,
+ i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
                          struct drm_i915_gem_exec_object2 *shadow_exec_entry,
                          struct eb_vmas *eb,
                          struct drm_i915_gem_object *batch_obj,
        struct i915_vma *vma;
        int ret;
  
-       shadow_batch_obj = i915_gem_batch_pool_get(&ring->batch_pool,
+       shadow_batch_obj = i915_gem_batch_pool_get(&engine->batch_pool,
                                                   PAGE_ALIGN(batch_len));
        if (IS_ERR(shadow_batch_obj))
                return shadow_batch_obj;
  
-       ret = i915_parse_cmds(ring,
+       ret = i915_parse_cmds(engine,
                              batch_obj,
                              shadow_batch_obj,
                              batch_start_offset,
@@@ -1227,7 -1234,7 +1232,7 @@@ i915_gem_ringbuffer_submission(struct i
                               struct list_head *vmas)
  {
        struct drm_device *dev = params->dev;
-       struct intel_engine_cs *ring = params->ring;
+       struct intel_engine_cs *engine = params->engine;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u64 exec_start, exec_len;
        int instp_mode;
        if (ret)
                return ret;
  
-       WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<<ring->id),
-            "%s didn't clear reload\n", ring->name);
+       WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<<engine->id),
+            "%s didn't clear reload\n", engine->name);
  
        instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
        instp_mask = I915_EXEC_CONSTANTS_MASK;
        case I915_EXEC_CONSTANTS_REL_GENERAL:
        case I915_EXEC_CONSTANTS_ABSOLUTE:
        case I915_EXEC_CONSTANTS_REL_SURFACE:
-               if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
+               if (instp_mode != 0 && engine != &dev_priv->engine[RCS]) {
                        DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
                        return -EINVAL;
                }
                return -EINVAL;
        }
  
-       if (ring == &dev_priv->ring[RCS] &&
+       if (engine == &dev_priv->engine[RCS] &&
            instp_mode != dev_priv->relative_constants_mode) {
                ret = intel_ring_begin(params->request, 4);
                if (ret)
                        return ret;
  
-               intel_ring_emit(ring, MI_NOOP);
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, INSTPM);
-               intel_ring_emit(ring, instp_mask << 16 | instp_mode);
-               intel_ring_advance(ring);
+               intel_ring_emit(engine, MI_NOOP);
+               intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+               intel_ring_emit_reg(engine, INSTPM);
+               intel_ring_emit(engine, instp_mask << 16 | instp_mode);
+               intel_ring_advance(engine);
  
                dev_priv->relative_constants_mode = instp_mode;
        }
        if (exec_len == 0)
                exec_len = params->batch_obj->base.size;
  
-       ret = ring->dispatch_execbuffer(params->request,
+       ret = engine->dispatch_execbuffer(params->request,
                                        exec_start, exec_len,
                                        params->dispatch_flags);
        if (ret)
        trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags);
  
        i915_gem_execbuffer_move_to_active(vmas, params->request);
-       i915_gem_execbuffer_retire_commands(params);
  
        return 0;
  }
@@@ -1363,7 -1369,7 +1367,7 @@@ eb_get_batch(struct eb_vmas *eb
  
  #define I915_USER_RINGS (4)
  
- static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = {
+ static const enum intel_engine_id user_ring_map[I915_USER_RINGS + 1] = {
        [I915_EXEC_DEFAULT]     = RCS,
        [I915_EXEC_RENDER]      = RCS,
        [I915_EXEC_BLT]         = BCS,
@@@ -1406,12 -1412,12 +1410,12 @@@ eb_select_ring(struct drm_i915_private 
                        return -EINVAL;
                }
  
-               *ring = &dev_priv->ring[_VCS(bsd_idx)];
+               *ring = &dev_priv->engine[_VCS(bsd_idx)];
        } else {
-               *ring = &dev_priv->ring[user_ring_map[user_ring_id]];
+               *ring = &dev_priv->engine[user_ring_map[user_ring_id]];
        }
  
-       if (!intel_ring_initialized(*ring)) {
+       if (!intel_engine_initialized(*ring)) {
                DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
                return -EINVAL;
        }
@@@ -1425,12 -1431,13 +1429,13 @@@ i915_gem_do_execbuffer(struct drm_devic
                       struct drm_i915_gem_execbuffer2 *args,
                       struct drm_i915_gem_exec_object2 *exec)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct drm_i915_gem_request *req = NULL;
        struct eb_vmas *eb;
        struct drm_i915_gem_object *batch_obj;
        struct drm_i915_gem_exec_object2 shadow_exec_entry;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        struct intel_context *ctx;
        struct i915_address_space *vm;
        struct i915_execbuffer_params params_master; /* XXX: will be removed later */
        if (args->flags & I915_EXEC_IS_PINNED)
                dispatch_flags |= I915_DISPATCH_PINNED;
  
-       ret = eb_select_ring(dev_priv, file, args, &ring);
+       ret = eb_select_ring(dev_priv, file, args, &engine);
        if (ret)
                return ret;
  
                        DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n");
                        return -EINVAL;
                }
-               if (ring->id != RCS) {
+               if (engine->id != RCS) {
                        DRM_DEBUG("RS is not available on %s\n",
-                                ring->name);
+                                engine->name);
                        return -EINVAL;
                }
  
        if (ret)
                goto pre_mutex_err;
  
-       ctx = i915_gem_validate_context(dev, file, ring, ctx_id);
+       ctx = i915_gem_validate_context(dev, file, engine, ctx_id);
        if (IS_ERR(ctx)) {
                mutex_unlock(&dev->struct_mutex);
                ret = PTR_ERR(ctx);
        if (ctx->ppgtt)
                vm = &ctx->ppgtt->base;
        else
-               vm = &dev_priv->gtt.base;
+               vm = &ggtt->base;
  
        memset(&params_master, 0x00, sizeof(params_master));
  
  
        /* Move the objects en-masse into the GTT, evicting if necessary. */
        need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0;
-       ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, ctx, &need_relocs);
+       ret = i915_gem_execbuffer_reserve(engine, &eb->vmas, ctx,
+                                         &need_relocs);
        if (ret)
                goto err;
  
                ret = i915_gem_execbuffer_relocate(eb);
        if (ret) {
                if (ret == -EFAULT) {
-                       ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring,
+                       ret = i915_gem_execbuffer_relocate_slow(dev, args, file,
+                                                               engine,
                                                                eb, exec, ctx);
                        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
                }
        }
  
        params->args_batch_start_offset = args->batch_start_offset;
-       if (i915_needs_cmd_parser(ring) && args->batch_len) {
+       if (i915_needs_cmd_parser(engine) && args->batch_len) {
                struct drm_i915_gem_object *parsed_batch_obj;
  
-               parsed_batch_obj = i915_gem_execbuffer_parse(ring,
-                                                     &shadow_exec_entry,
-                                                     eb,
-                                                     batch_obj,
-                                                     args->batch_start_offset,
-                                                     args->batch_len,
-                                                     file->is_master);
+               parsed_batch_obj = i915_gem_execbuffer_parse(engine,
+                                                            &shadow_exec_entry,
+                                                            eb,
+                                                            batch_obj,
+                                                            args->batch_start_offset,
+                                                            args->batch_len,
+                                                            file->is_master);
                if (IS_ERR(parsed_batch_obj)) {
                        ret = PTR_ERR(parsed_batch_obj);
                        goto err;
                params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
  
        /* Allocate a request for this batch buffer nice and early. */
-       req = i915_gem_request_alloc(ring, ctx);
+       req = i915_gem_request_alloc(engine, ctx);
        if (IS_ERR(req)) {
                ret = PTR_ERR(req);
                goto err_batch_unpin;
  
        ret = i915_gem_request_add_to_client(req, file);
        if (ret)
-               goto err_batch_unpin;
+               goto err_request;
  
        /*
         * Save assorted stuff away to pass through to *_submission().
         */
        params->dev                     = dev;
        params->file                    = file;
-       params->ring                    = ring;
+       params->engine                    = engine;
        params->dispatch_flags          = dispatch_flags;
        params->batch_obj               = batch_obj;
        params->ctx                     = ctx;
        params->request                 = req;
  
        ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas);
+ err_request:
+       i915_gem_execbuffer_retire_commands(params);
  
  err_batch_unpin:
        /*
@@@ -1647,14 -1658,6 +1656,6 @@@ err
        i915_gem_context_unreference(ctx);
        eb_destroy(eb);
  
-       /*
-        * If the request was created but not successfully submitted then it
-        * must be freed again. If it was submitted then it is being tracked
-        * on the active request list and no clean up is required here.
-        */
-       if (ret && !IS_ERR_OR_NULL(req))
-               i915_gem_request_cancel(req);
        mutex_unlock(&dev->struct_mutex);
  
  pre_mutex_err:
@@@ -1694,7 -1697,7 +1695,7 @@@ i915_gem_execbuffer(struct drm_device *
                return -ENOMEM;
        }
        ret = copy_from_user(exec_list,
 -                           to_user_ptr(args->buffers_ptr),
 +                           u64_to_user_ptr(args->buffers_ptr),
                             sizeof(*exec_list) * args->buffer_count);
        if (ret != 0) {
                DRM_DEBUG("copy %d exec entries failed %d\n",
        ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
        if (!ret) {
                struct drm_i915_gem_exec_object __user *user_exec_list =
 -                      to_user_ptr(args->buffers_ptr);
 +                      u64_to_user_ptr(args->buffers_ptr);
  
                /* Copy the new buffer offsets back to the user's exec list. */
                for (i = 0; i < args->buffer_count; i++) {
@@@ -1773,18 -1776,16 +1774,16 @@@ i915_gem_execbuffer2(struct drm_device 
                return -EINVAL;
        }
  
-       exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count,
-                            GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
-       if (exec2_list == NULL)
-               exec2_list = drm_malloc_ab(sizeof(*exec2_list),
-                                          args->buffer_count);
+       exec2_list = drm_malloc_gfp(args->buffer_count,
+                                   sizeof(*exec2_list),
+                                   GFP_TEMPORARY);
        if (exec2_list == NULL) {
                DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
                          args->buffer_count);
                return -ENOMEM;
        }
        ret = copy_from_user(exec2_list,
 -                           to_user_ptr(args->buffers_ptr),
 +                           u64_to_user_ptr(args->buffers_ptr),
                             sizeof(*exec2_list) * args->buffer_count);
        if (ret != 0) {
                DRM_DEBUG("copy %d exec entries failed %d\n",
        if (!ret) {
                /* Copy the new buffer offsets back to the user's exec list. */
                struct drm_i915_gem_exec_object2 __user *user_exec_list =
 -                                 to_user_ptr(args->buffers_ptr);
 +                                 u64_to_user_ptr(args->buffers_ptr);
                int i;
  
                for (i = 0; i < args->buffer_count; i++) {
index 363bd79dea2ef476bdf0f14886248175310720f6,58ac6c7c690b0736bc025966cab6a1e57f48af5c..b407411e31ba8e649ccbec2255888a976fffde2c
@@@ -79,6 -79,16 +79,16 @@@ static inline bool i915_mmio_reg_valid(
  
  /* PCI config space */
  
+ #define MCHBAR_I915 0x44
+ #define MCHBAR_I965 0x48
+ #define MCHBAR_SIZE (4 * 4096)
+ #define DEVEN 0x54
+ #define   DEVEN_MCHBAR_EN (1 << 28)
+ #define BSM 0x5c
+ #define   BSM_MASK (0xFFFF << 20)
  #define HPLLCC        0xc0 /* 85x only */
  #define   GC_CLOCK_CONTROL_MASK               (0x7 << 0)
  #define   GC_CLOCK_133_200            (0 << 0)
  #define   GC_CLOCK_166_266            (6 << 0)
  #define   GC_CLOCK_166_250            (7 << 0)
  
+ #define I915_GDRST 0xc0 /* PCI config register */
+ #define   GRDOM_FULL          (0 << 2)
+ #define   GRDOM_RENDER                (1 << 2)
+ #define   GRDOM_MEDIA         (3 << 2)
+ #define   GRDOM_MASK          (3 << 2)
+ #define   GRDOM_RESET_STATUS  (1 << 1)
+ #define   GRDOM_RESET_ENABLE  (1 << 0)
+ #define GCDGMBUS 0xcc
  #define GCFGC2        0xda
  #define GCFGC 0xf0 /* 915+ only */
  #define   GC_LOW_FREQUENCY_ENABLE     (1 << 7)
  #define   I915_GC_RENDER_CLOCK_166_MHZ        (0 << 0)
  #define   I915_GC_RENDER_CLOCK_200_MHZ        (1 << 0)
  #define   I915_GC_RENDER_CLOCK_333_MHZ        (4 << 0)
- #define GCDGMBUS 0xcc
- #define PCI_LBPC 0xf4 /* legacy/combination backlight modes, also called LBB */
  
+ #define ASLE  0xe4
+ #define ASLS  0xfc
+ #define SWSCI 0xe8
+ #define   SWSCI_SCISEL        (1 << 15)
+ #define   SWSCI_GSSCIE        (1 << 0)
+ #define LBPC 0xf4 /* legacy/combination backlight modes, also called LBB */
  
- /* Graphics reset regs */
- #define I915_GDRST 0xc0 /* PCI config register */
- #define  GRDOM_FULL   (0<<2)
- #define  GRDOM_RENDER (1<<2)
- #define  GRDOM_MEDIA  (3<<2)
- #define  GRDOM_MASK   (3<<2)
- #define  GRDOM_RESET_STATUS (1<<1)
- #define  GRDOM_RESET_ENABLE (1<<0)
  
  #define ILK_GDSR _MMIO(MCHBAR_MIRROR_BASE + 0x2ca4)
  #define  ILK_GRDOM_FULL               (0<<1)
  #define  GEN6_GRDOM_RENDER            (1 << 1)
  #define  GEN6_GRDOM_MEDIA             (1 << 2)
  #define  GEN6_GRDOM_BLT                       (1 << 3)
+ #define  GEN6_GRDOM_VECS              (1 << 4)
+ #define  GEN9_GRDOM_GUC                       (1 << 5)
+ #define  GEN8_GRDOM_MEDIA2            (1 << 7)
  
  #define RING_PP_DIR_BASE(ring)                _MMIO((ring)->mmio_base+0x228)
  #define RING_PP_DIR_BASE_READ(ring)   _MMIO((ring)->mmio_base+0x518)
  #define GEN7_GPGPU_DISPATCHDIMY         _MMIO(0x2504)
  #define GEN7_GPGPU_DISPATCHDIMZ         _MMIO(0x2508)
  
+ /* There are the 16 64-bit CS General Purpose Registers */
+ #define HSW_CS_GPR(n)                   _MMIO(0x2600 + (n) * 8)
+ #define HSW_CS_GPR_UDW(n)               _MMIO(0x2600 + (n) * 8 + 4)
  #define OACONTROL _MMIO(0x2360)
  
  #define _GEN7_PIPEA_DE_LOAD_SL        0x70068
  #define   IOSF_PORT_GPIO_SC                   0x48
  #define   IOSF_PORT_GPIO_SUS                  0xa8
  #define   IOSF_PORT_CCU                               0xa9
+ #define   CHV_IOSF_PORT_GPIO_N                        0x13
+ #define   CHV_IOSF_PORT_GPIO_SE                       0x48
+ #define   CHV_IOSF_PORT_GPIO_E                        0xa8
+ #define   CHV_IOSF_PORT_GPIO_SW                       0xb2
  #define VLV_IOSF_DATA                         _MMIO(VLV_DISPLAY_BASE + 0x2104)
  #define VLV_IOSF_ADDR                         _MMIO(VLV_DISPLAY_BASE + 0x2108)
  
@@@ -785,7 -814,9 +814,9 @@@ enum skl_disp_power_wells 
  #define  DSI_PLL_M1_DIV_SHIFT                 0
  #define  DSI_PLL_M1_DIV_MASK                  (0x1ff << 0)
  #define CCK_CZ_CLOCK_CONTROL                  0x62
+ #define CCK_GPLL_CLOCK_CONTROL                        0x67
  #define CCK_DISPLAY_CLOCK_CONTROL             0x6b
+ #define CCK_DISPLAY_REF_CLOCK_CONTROL         0x6c
  #define  CCK_TRUNK_FORCE_ON                   (1 << 17)
  #define  CCK_TRUNK_FORCE_OFF                  (1 << 16)
  #define  CCK_FREQUENCY_STATUS                 (0x1f << 8)
  #define _PORT_CL1CM_DW0_A             0x162000
  #define _PORT_CL1CM_DW0_BC            0x6C000
  #define   PHY_POWER_GOOD              (1 << 16)
+ #define   PHY_RESERVED                        (1 << 7)
  #define BXT_PORT_CL1CM_DW0(phy)               _BXT_PHY((phy), _PORT_CL1CM_DW0_BC, \
                                                        _PORT_CL1CM_DW0_A)
  
  
  #define _PORT_REF_DW6_A                       0x162198
  #define _PORT_REF_DW6_BC              0x6C198
- /*
-  * FIXME: BSpec/CHV ConfigDB disagrees on the following two fields, fix them
-  * after testing.
-  */
- #define   GRC_CODE_SHIFT              23
- #define   GRC_CODE_MASK                       (0x1FF << GRC_CODE_SHIFT)
+ #define   GRC_CODE_SHIFT              24
+ #define   GRC_CODE_MASK                       (0xFF << GRC_CODE_SHIFT)
  #define   GRC_CODE_FAST_SHIFT         16
- #define   GRC_CODE_FAST_MASK          (0x7F << GRC_CODE_FAST_SHIFT)
+ #define   GRC_CODE_FAST_MASK          (0xFF << GRC_CODE_FAST_SHIFT)
  #define   GRC_CODE_SLOW_SHIFT         8
  #define   GRC_CODE_SLOW_MASK          (0xFF << GRC_CODE_SLOW_SHIFT)
  #define   GRC_CODE_NOM_MASK           0xFF
  #define   GEN9_IZ_HASHING_MASK(slice)                 (0x3 << ((slice) * 2))
  #define   GEN9_IZ_HASHING(slice, val)                 ((val) << ((slice) * 2))
  
+ /* WaClearTdlStateAckDirtyBits */
+ #define GEN8_STATE_ACK                _MMIO(0x20F0)
+ #define GEN9_STATE_ACK_SLICE1 _MMIO(0x20F8)
+ #define GEN9_STATE_ACK_SLICE2 _MMIO(0x2100)
+ #define   GEN9_STATE_ACK_TDL0 (1 << 12)
+ #define   GEN9_STATE_ACK_TDL1 (1 << 13)
+ #define   GEN9_STATE_ACK_TDL2 (1 << 14)
+ #define   GEN9_STATE_ACK_TDL3 (1 << 15)
+ #define   GEN9_SUBSLICE_TDL_ACK_BITS \
+       (GEN9_STATE_ACK_TDL3 | GEN9_STATE_ACK_TDL2 | \
+        GEN9_STATE_ACK_TDL1 | GEN9_STATE_ACK_TDL0)
  #define GFX_MODE      _MMIO(0x2520)
  #define GFX_MODE_GEN7 _MMIO(0x229c)
  #define RING_MODE_GEN7(ring)  _MMIO((ring)->mmio_base+0x29c)
  
  #define VLV_DISPLAY_BASE 0x180000
  #define VLV_MIPI_BASE VLV_DISPLAY_BASE
+ #define BXT_MIPI_BASE 0x60000
  
  #define VLV_GU_CTL0   _MMIO(VLV_DISPLAY_BASE + 0x2030)
  #define VLV_GU_CTL1   _MMIO(VLV_DISPLAY_BASE + 0x2034)
                                INTERVAL_1_33_US(us)) : \
                                INTERVAL_1_28_US(us))
  
+ #define INTERVAL_1_28_TO_US(interval)  (((interval) << 7) / 100)
+ #define INTERVAL_1_33_TO_US(interval)  (((interval) << 2) / 3)
+ #define INTERVAL_0_833_TO_US(interval) (((interval) * 5)  / 6)
+ #define GT_PM_INTERVAL_TO_US(dev_priv, interval) (IS_GEN9(dev_priv) ? \
+                            (IS_BROXTON(dev_priv) ? \
+                            INTERVAL_0_833_TO_US(interval) : \
+                            INTERVAL_1_33_TO_US(interval)) : \
+                            INTERVAL_1_28_TO_US(interval))
  /*
   * Logical Context regs
   */
  #define  CBR_PND_DEADLINE_DISABLE     (1<<31)
  #define  CBR_PWM_CLOCK_MUX_SELECT     (1<<30)
  
+ #define CBR4_VLV                      _MMIO(VLV_DISPLAY_BASE + 0x70450)
+ #define  CBR_DPLLBMD_PIPE_C           (1<<29)
+ #define  CBR_DPLLBMD_PIPE_B           (1<<18)
  /* FIFO watermark sizes etc */
  #define G4X_FIFO_LINE_SIZE    64
  #define I915_FIFO_LINE_SIZE   64
  /* digital port hotplug */
  #define PCH_PORT_HOTPLUG              _MMIO(0xc4030)  /* SHOTPLUG_CTL */
  #define  PORTA_HOTPLUG_ENABLE         (1 << 28) /* LPT:LP+ & BXT */
+ #define  BXT_DDIA_HPD_INVERT            (1 << 27)
  #define  PORTA_HOTPLUG_STATUS_MASK    (3 << 24) /* SPT+ & BXT */
  #define  PORTA_HOTPLUG_NO_DETECT      (0 << 24) /* SPT+ & BXT */
  #define  PORTA_HOTPLUG_SHORT_DETECT   (1 << 24) /* SPT+ & BXT */
  #define  PORTD_HOTPLUG_SHORT_DETECT   (1 << 16)
  #define  PORTD_HOTPLUG_LONG_DETECT    (2 << 16)
  #define  PORTC_HOTPLUG_ENABLE         (1 << 12)
+ #define  BXT_DDIC_HPD_INVERT            (1 << 11)
  #define  PORTC_PULSE_DURATION_2ms     (0 << 10) /* pre-LPT */
  #define  PORTC_PULSE_DURATION_4_5ms   (1 << 10) /* pre-LPT */
  #define  PORTC_PULSE_DURATION_6ms     (2 << 10) /* pre-LPT */
  #define  PORTC_HOTPLUG_SHORT_DETECT   (1 << 8)
  #define  PORTC_HOTPLUG_LONG_DETECT    (2 << 8)
  #define  PORTB_HOTPLUG_ENABLE         (1 << 4)
+ #define  BXT_DDIB_HPD_INVERT            (1 << 3)
  #define  PORTB_PULSE_DURATION_2ms     (0 << 2) /* pre-LPT */
  #define  PORTB_PULSE_DURATION_4_5ms   (1 << 2) /* pre-LPT */
  #define  PORTB_PULSE_DURATION_6ms     (2 << 2) /* pre-LPT */
  #define  PORTB_HOTPLUG_NO_DETECT      (0 << 0)
  #define  PORTB_HOTPLUG_SHORT_DETECT   (1 << 0)
  #define  PORTB_HOTPLUG_LONG_DETECT    (2 << 0)
+ #define  BXT_DDI_HPD_INVERT_MASK      (BXT_DDIA_HPD_INVERT | \
+                                       BXT_DDIB_HPD_INVERT | \
+                                       BXT_DDIC_HPD_INVERT)
  
  #define PCH_PORT_HOTPLUG2             _MMIO(0xc403C)  /* SHOTPLUG_CTL2 SPT+ */
  #define  PORTE_HOTPLUG_ENABLE         (1 << 4)
  #define  VLV_SPAREG2H                         _MMIO(0xA194)
  
  #define  GTFIFODBG                            _MMIO(0x120000)
+ #define    GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV  (0x1f << 20)
+ #define    GT_FIFO_FREE_ENTRIES_CHV           (0x7f << 13)
  #define    GT_FIFO_SBDROPERR                  (1<<6)
  #define    GT_FIFO_BLOBDROPERR                        (1<<5)
  #define    GT_FIFO_SB_READ_ABORTERR           (1<<4)
  
  #define  HSW_IDICR                            _MMIO(0x9008)
  #define    IDIHASHMSK(x)                      (((x) & 0x3f) << 16)
- #define  HSW_EDRAM_PRESENT                    _MMIO(0x120010)
+ #define  HSW_EDRAM_CAP                                _MMIO(0x120010)
  #define    EDRAM_ENABLED                      0x1
+ #define    EDRAM_NUM_BANKS(cap)                       (((cap) >> 1) & 0xf)
+ #define    EDRAM_WAYS_IDX(cap)                        (((cap) >> 5) & 0x7)
+ #define    EDRAM_SETS_IDX(cap)                        (((cap) >> 8) & 0x3)
  
  #define GEN6_UCGCTL1                          _MMIO(0x9400)
  # define GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE            (1 << 16)
  #define   GEN9_CCS_TLB_PREFETCH_ENABLE        (1<<3)
  
  #define GEN8_ROW_CHICKEN              _MMIO(0xe4f0)
+ #define   FLOW_CONTROL_ENABLE         (1<<15)
  #define   PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE       (1<<8)
  #define   STALL_DOP_GATING_DISABLE            (1<<5)
  
  
  #define GEN9_HALF_SLICE_CHICKEN7      _MMIO(0xe194)
  #define   GEN9_ENABLE_YV12_BUGFIX     (1<<4)
+ #define   GEN9_ENABLE_GPGPU_PREEMPTION        (1<<2)
  
  /* Audio */
  #define G4X_AUD_VID_DID                       _MMIO(dev_priv->info.display_mmio_offset + 0x62020)
  /* SBI offsets */
  #define  SBI_SSCDIVINTPHASE                   0x0200
  #define  SBI_SSCDIVINTPHASE6                  0x0600
- #define   SBI_SSCDIVINTPHASE_DIVSEL_MASK      ((0x7f)<<1)
+ #define   SBI_SSCDIVINTPHASE_DIVSEL_SHIFT     1
+ #define   SBI_SSCDIVINTPHASE_DIVSEL_MASK      (0x7f<<1)
  #define   SBI_SSCDIVINTPHASE_DIVSEL(x)                ((x)<<1)
- #define   SBI_SSCDIVINTPHASE_INCVAL_MASK      ((0x7f)<<8)
+ #define   SBI_SSCDIVINTPHASE_INCVAL_SHIFT     8
+ #define   SBI_SSCDIVINTPHASE_INCVAL_MASK      (0x7f<<8)
  #define   SBI_SSCDIVINTPHASE_INCVAL(x)                ((x)<<8)
  #define   SBI_SSCDIVINTPHASE_DIR(x)           ((x)<<15)
  #define   SBI_SSCDIVINTPHASE_PROPAGATE                (1<<0)
  #define   SBI_SSCCTL_PATHALT                  (1<<3)
  #define   SBI_SSCCTL_DISABLE                  (1<<0)
  #define  SBI_SSCAUXDIV6                               0x0610
+ #define   SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT    4
+ #define   SBI_SSCAUXDIV_FINALDIV2SEL_MASK     (1<<4)
  #define   SBI_SSCAUXDIV_FINALDIV2SEL(x)               ((x)<<4)
  #define  SBI_DBUFF0                           0x2a00
  #define  SBI_GEN0                             0x1f00
  #define  TRANS_CLK_SEL_DISABLED               (0x0<<29)
  #define  TRANS_CLK_SEL_PORT(x)                (((x)+1)<<29)
  
 +#define CDCLK_FREQ                    _MMIO(0x46200)
 +
  #define _TRANSA_MSA_MISC              0x60410
  #define _TRANSB_MSA_MISC              0x61410
  #define _TRANSC_MSA_MISC              0x62410
  #define PIPE_CSC_POSTOFF_ME(pipe)     _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
  #define PIPE_CSC_POSTOFF_LO(pipe)     _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
  
+ /* pipe degamma/gamma LUTs on IVB+ */
+ #define _PAL_PREC_INDEX_A     0x4A400
+ #define _PAL_PREC_INDEX_B     0x4AC00
+ #define _PAL_PREC_INDEX_C     0x4B400
+ #define   PAL_PREC_10_12_BIT          (0 << 31)
+ #define   PAL_PREC_SPLIT_MODE         (1 << 31)
+ #define   PAL_PREC_AUTO_INCREMENT     (1 << 15)
+ #define _PAL_PREC_DATA_A      0x4A404
+ #define _PAL_PREC_DATA_B      0x4AC04
+ #define _PAL_PREC_DATA_C      0x4B404
+ #define _PAL_PREC_GC_MAX_A    0x4A410
+ #define _PAL_PREC_GC_MAX_B    0x4AC10
+ #define _PAL_PREC_GC_MAX_C    0x4B410
+ #define _PAL_PREC_EXT_GC_MAX_A        0x4A420
+ #define _PAL_PREC_EXT_GC_MAX_B        0x4AC20
+ #define _PAL_PREC_EXT_GC_MAX_C        0x4B420
+ #define PREC_PAL_INDEX(pipe)          _MMIO_PIPE(pipe, _PAL_PREC_INDEX_A, _PAL_PREC_INDEX_B)
+ #define PREC_PAL_DATA(pipe)           _MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B)
+ #define PREC_PAL_GC_MAX(pipe, i)      _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4)
+ #define PREC_PAL_EXT_GC_MAX(pipe, i)  _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4)
+ /* pipe CSC & degamma/gamma LUTs on CHV */
+ #define _CGM_PIPE_A_CSC_COEFF01       (VLV_DISPLAY_BASE + 0x67900)
+ #define _CGM_PIPE_A_CSC_COEFF23       (VLV_DISPLAY_BASE + 0x67904)
+ #define _CGM_PIPE_A_CSC_COEFF45       (VLV_DISPLAY_BASE + 0x67908)
+ #define _CGM_PIPE_A_CSC_COEFF67       (VLV_DISPLAY_BASE + 0x6790C)
+ #define _CGM_PIPE_A_CSC_COEFF8        (VLV_DISPLAY_BASE + 0x67910)
+ #define _CGM_PIPE_A_DEGAMMA   (VLV_DISPLAY_BASE + 0x66000)
+ #define _CGM_PIPE_A_GAMMA     (VLV_DISPLAY_BASE + 0x67000)
+ #define _CGM_PIPE_A_MODE      (VLV_DISPLAY_BASE + 0x67A00)
+ #define   CGM_PIPE_MODE_GAMMA (1 << 2)
+ #define   CGM_PIPE_MODE_CSC   (1 << 1)
+ #define   CGM_PIPE_MODE_DEGAMMA       (1 << 0)
+ #define _CGM_PIPE_B_CSC_COEFF01       (VLV_DISPLAY_BASE + 0x69900)
+ #define _CGM_PIPE_B_CSC_COEFF23       (VLV_DISPLAY_BASE + 0x69904)
+ #define _CGM_PIPE_B_CSC_COEFF45       (VLV_DISPLAY_BASE + 0x69908)
+ #define _CGM_PIPE_B_CSC_COEFF67       (VLV_DISPLAY_BASE + 0x6990C)
+ #define _CGM_PIPE_B_CSC_COEFF8        (VLV_DISPLAY_BASE + 0x69910)
+ #define _CGM_PIPE_B_DEGAMMA   (VLV_DISPLAY_BASE + 0x68000)
+ #define _CGM_PIPE_B_GAMMA     (VLV_DISPLAY_BASE + 0x69000)
+ #define _CGM_PIPE_B_MODE      (VLV_DISPLAY_BASE + 0x69A00)
+ #define CGM_PIPE_CSC_COEFF01(pipe)    _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01)
+ #define CGM_PIPE_CSC_COEFF23(pipe)    _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23)
+ #define CGM_PIPE_CSC_COEFF45(pipe)    _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45)
+ #define CGM_PIPE_CSC_COEFF67(pipe)    _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67)
+ #define CGM_PIPE_CSC_COEFF8(pipe)     _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8)
+ #define CGM_PIPE_DEGAMMA(pipe, i, w)  _MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4)
+ #define CGM_PIPE_GAMMA(pipe, i, w)    _MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4)
+ #define CGM_PIPE_MODE(pipe)           _MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE)
  /* MIPI DSI registers */
  
  #define _MIPI_PORT(port, a, c)        _PORT3(port, a, 0, c)   /* ports A and C only */
  #define  BXT_MIPI_DIV_SHIFT(port)             \
                        _MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \
                                        BXT_MIPI2_DIV_SHIFT)
- /* Var clock divider to generate TX source. Result must be < 39.5 M */
- #define  BXT_MIPI1_ESCLK_VAR_DIV_MASK         (0x3F << 26)
- #define  BXT_MIPI2_ESCLK_VAR_DIV_MASK         (0x3F << 10)
- #define  BXT_MIPI_ESCLK_VAR_DIV_MASK(port)    \
-                       _MIPI_PORT(port, BXT_MIPI1_ESCLK_VAR_DIV_MASK, \
-                                               BXT_MIPI2_ESCLK_VAR_DIV_MASK)
- #define  BXT_MIPI_ESCLK_VAR_DIV(port, val)    \
-                       (val << BXT_MIPI_DIV_SHIFT(port))
  /* TX control divider to select actual TX clock output from (8x/var) */
- #define  BXT_MIPI1_TX_ESCLK_SHIFT             21
- #define  BXT_MIPI2_TX_ESCLK_SHIFT             5
+ #define  BXT_MIPI1_TX_ESCLK_SHIFT             26
+ #define  BXT_MIPI2_TX_ESCLK_SHIFT             10
  #define  BXT_MIPI_TX_ESCLK_SHIFT(port)                \
                        _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \
                                        BXT_MIPI2_TX_ESCLK_SHIFT)
- #define  BXT_MIPI1_TX_ESCLK_FIXDIV_MASK               (3 << 21)
- #define  BXT_MIPI2_TX_ESCLK_FIXDIV_MASK               (3 << 5)
+ #define  BXT_MIPI1_TX_ESCLK_FIXDIV_MASK               (0x3F << 26)
+ #define  BXT_MIPI2_TX_ESCLK_FIXDIV_MASK               (0x3F << 10)
  #define  BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)  \
                        _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \
-                                               BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
- #define  BXT_MIPI_TX_ESCLK_8XDIV_BY2(port)    \
-               (0x0 << BXT_MIPI_TX_ESCLK_SHIFT(port))
- #define  BXT_MIPI_TX_ESCLK_8XDIV_BY4(port)    \
-               (0x1 << BXT_MIPI_TX_ESCLK_SHIFT(port))
- #define  BXT_MIPI_TX_ESCLK_8XDIV_BY8(port)    \
-               (0x2 << BXT_MIPI_TX_ESCLK_SHIFT(port))
- /* RX control divider to select actual RX clock output from 8x*/
- #define  BXT_MIPI1_RX_ESCLK_SHIFT             19
- #define  BXT_MIPI2_RX_ESCLK_SHIFT             3
- #define  BXT_MIPI_RX_ESCLK_SHIFT(port)                \
-                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_SHIFT, \
-                                       BXT_MIPI2_RX_ESCLK_SHIFT)
- #define  BXT_MIPI1_RX_ESCLK_FIXDIV_MASK               (3 << 19)
- #define  BXT_MIPI2_RX_ESCLK_FIXDIV_MASK               (3 << 3)
- #define  BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)  \
-               (3 << BXT_MIPI_RX_ESCLK_SHIFT(port))
- #define  BXT_MIPI_RX_ESCLK_8X_BY2(port)       \
-               (1 << BXT_MIPI_RX_ESCLK_SHIFT(port))
- #define  BXT_MIPI_RX_ESCLK_8X_BY3(port)       \
-               (2 << BXT_MIPI_RX_ESCLK_SHIFT(port))
- #define  BXT_MIPI_RX_ESCLK_8X_BY4(port)       \
-               (3 << BXT_MIPI_RX_ESCLK_SHIFT(port))
- /* BXT-A WA: Always prog DPHY dividers to 00 */
- #define  BXT_MIPI1_DPHY_DIV_SHIFT             16
- #define  BXT_MIPI2_DPHY_DIV_SHIFT             0
- #define  BXT_MIPI_DPHY_DIV_SHIFT(port)                \
-                       _MIPI_PORT(port, BXT_MIPI1_DPHY_DIV_SHIFT, \
-                                       BXT_MIPI2_DPHY_DIV_SHIFT)
- #define  BXT_MIPI_1_DPHY_DIVIDER_MASK         (3 << 16)
- #define  BXT_MIPI_2_DPHY_DIVIDER_MASK         (3 << 0)
- #define  BXT_MIPI_DPHY_DIVIDER_MASK(port)     \
-               (3 << BXT_MIPI_DPHY_DIV_SHIFT(port))
+                                       BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
+ #define  BXT_MIPI_TX_ESCLK_DIVIDER(port, val) \
+               ((val & 0x3F) << BXT_MIPI_TX_ESCLK_SHIFT(port))
+ /* RX upper control divider to select actual RX clock output from 8x */
+ #define  BXT_MIPI1_RX_ESCLK_UPPER_SHIFT               21
+ #define  BXT_MIPI2_RX_ESCLK_UPPER_SHIFT               5
+ #define  BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port)          \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_SHIFT, \
+                                       BXT_MIPI2_RX_ESCLK_UPPER_SHIFT)
+ #define  BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK         (3 << 21)
+ #define  BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK         (3 << 5)
+ #define  BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)    \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK, \
+                                       BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK)
+ #define  BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, val)   \
+               ((val & 3) << BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port))
+ /* 8/3X divider to select the actual 8/3X clock output from 8x */
+ #define  BXT_MIPI1_8X_BY3_SHIFT                19
+ #define  BXT_MIPI2_8X_BY3_SHIFT                3
+ #define  BXT_MIPI_8X_BY3_SHIFT(port)          \
+                       _MIPI_PORT(port, BXT_MIPI1_8X_BY3_SHIFT, \
+                                       BXT_MIPI2_8X_BY3_SHIFT)
+ #define  BXT_MIPI1_8X_BY3_DIVIDER_MASK         (3 << 19)
+ #define  BXT_MIPI2_8X_BY3_DIVIDER_MASK         (3 << 3)
+ #define  BXT_MIPI_8X_BY3_DIVIDER_MASK(port)    \
+                       _MIPI_PORT(port, BXT_MIPI1_8X_BY3_DIVIDER_MASK, \
+                                               BXT_MIPI2_8X_BY3_DIVIDER_MASK)
+ #define  BXT_MIPI_8X_BY3_DIVIDER(port, val)    \
+                       ((val & 3) << BXT_MIPI_8X_BY3_SHIFT(port))
+ /* RX lower control divider to select actual RX clock output from 8x */
+ #define  BXT_MIPI1_RX_ESCLK_LOWER_SHIFT               16
+ #define  BXT_MIPI2_RX_ESCLK_LOWER_SHIFT               0
+ #define  BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port)          \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_SHIFT, \
+                                       BXT_MIPI2_RX_ESCLK_LOWER_SHIFT)
+ #define  BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK         (3 << 16)
+ #define  BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK         (3 << 0)
+ #define  BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port)    \
+                       _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK, \
+                                       BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK)
+ #define  BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, val)   \
+               ((val & 3) << BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port))
+ #define RX_DIVIDER_BIT_1_2                     0x3
+ #define RX_DIVIDER_BIT_3_4                     0xC
  
  /* BXT MIPI mode configure */
  #define  _BXT_MIPIA_TRANS_HACTIVE                     0x6B0F8
  #define  BXT_DSIC_16X_BY2             (1 << 10)
  #define  BXT_DSIC_16X_BY3             (2 << 10)
  #define  BXT_DSIC_16X_BY4             (3 << 10)
+ #define  BXT_DSIC_16X_MASK            (3 << 10)
  #define  BXT_DSIA_16X_BY2             (1 << 8)
  #define  BXT_DSIA_16X_BY3             (2 << 8)
  #define  BXT_DSIA_16X_BY4             (3 << 8)
+ #define  BXT_DSIA_16X_MASK            (3 << 8)
  #define  BXT_DSI_FREQ_SEL_SHIFT               8
  #define  BXT_DSI_FREQ_SEL_MASK                (0xF << BXT_DSI_FREQ_SEL_SHIFT)
  
  #define  VID_MODE_FORMAT_MASK                         (0xf << 7)
  #define  VID_MODE_NOT_SUPPORTED                               (0 << 7)
  #define  VID_MODE_FORMAT_RGB565                               (1 << 7)
- #define  VID_MODE_FORMAT_RGB666                               (2 << 7)
- #define  VID_MODE_FORMAT_RGB666_LOOSE                 (3 << 7)
+ #define  VID_MODE_FORMAT_RGB666_PACKED                        (2 << 7)
+ #define  VID_MODE_FORMAT_RGB666                               (3 << 7)
  #define  VID_MODE_FORMAT_RGB888                               (4 << 7)
  #define  CMD_MODE_CHANNEL_NUMBER_SHIFT                        5
  #define  CMD_MODE_CHANNEL_NUMBER_MASK                 (3 << 5)
  #define  READ_REQUEST_PRIORITY_HIGH                   (3 << 3)
  #define  RGB_FLIP_TO_BGR                              (1 << 2)
  
+ #define  BXT_PIPE_SELECT_SHIFT                                7
  #define  BXT_PIPE_SELECT_MASK                         (7 << 7)
  #define  BXT_PIPE_SELECT(pipe)                                ((pipe) << 7)
  
index 7d281b40064a47f7e46071ef897c4720da38f9d8,56ba8765816ef0ff3fccd265bffd8803cbf1b4a9..02a7527ce7bb4e20d37699d7365b42e6d02b2d31
@@@ -262,7 -262,8 +262,7 @@@ static void hsw_audio_codec_disable(str
        tmp |= AUD_CONFIG_N_PROG_ENABLE;
        tmp &= ~AUD_CONFIG_UPPER_N_MASK;
        tmp &= ~AUD_CONFIG_LOWER_N_MASK;
 -      if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT) ||
 -          intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DP_MST))
 +      if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
                tmp |= AUD_CONFIG_N_VALUE_INDEX;
        I915_WRITE(HSW_AUD_CFG(pipe), tmp);
  
@@@ -372,7 -373,7 +372,7 @@@ static void ilk_audio_codec_disable(str
        if (WARN_ON(port == PORT_A))
                return;
  
-       if (HAS_PCH_IBX(dev_priv->dev)) {
+       if (HAS_PCH_IBX(dev_priv)) {
                aud_config = IBX_AUD_CFG(pipe);
                aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
@@@ -475,7 -476,8 +475,7 @@@ static void ilk_audio_codec_enable(stru
        tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
        tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
        tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
 -      if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT) ||
 -          intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DP_MST))
 +      if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
                tmp |= AUD_CONFIG_N_VALUE_INDEX;
        else
                tmp |= audio_config_hdmi_pixel_clock(adjusted_mode);
@@@ -513,7 -515,8 +513,7 @@@ void intel_audio_codec_enable(struct in
  
        /* ELD Conn_Type */
        connector->eld[5] &= ~(3 << 2);
 -      if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
 -          intel_pipe_has_type(crtc, INTEL_OUTPUT_DP_MST))
 +      if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
                connector->eld[5] |= (1 << 2);
  
        connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
@@@ -561,23 -564,21 +561,21 @@@ void intel_audio_codec_disable(struct i
  }
  
  /**
-  * intel_init_audio - Set up chip specific audio functions
-  * @dev: drm device
+  * intel_init_audio_hooks - Set up chip specific audio hooks
+  * @dev_priv: device private
   */
- void intel_init_audio(struct drm_device *dev)
+ void intel_init_audio_hooks(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       if (IS_G4X(dev)) {
+       if (IS_G4X(dev_priv)) {
                dev_priv->display.audio_codec_enable = g4x_audio_codec_enable;
                dev_priv->display.audio_codec_disable = g4x_audio_codec_disable;
-       } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                dev_priv->display.audio_codec_enable = ilk_audio_codec_enable;
                dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
-       } else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) {
+       } else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) {
                dev_priv->display.audio_codec_enable = hsw_audio_codec_enable;
                dev_priv->display.audio_codec_disable = hsw_audio_codec_disable;
-       } else if (HAS_PCH_SPLIT(dev)) {
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->display.audio_codec_enable = ilk_audio_codec_enable;
                dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
        }
index 0364292367b1425a297cd35e6ae81da2cf18dbc3,a2a31fd01d1dca88653f3f0a846ebae4a44fdbe0..3fbb6fc664516cdced5ab80ad1d0a8fe4cc70219
@@@ -120,22 -120,16 +120,16 @@@ static unsigned int intel_crt_get_flags
  static void intel_crt_get_config(struct intel_encoder *encoder,
                                 struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = encoder->base.dev;
-       int dotclock;
        pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
  
-       dotclock = pipe_config->port_clock;
-       if (HAS_PCH_SPLIT(dev))
-               ironlake_check_encoder_dotclock(pipe_config, dotclock);
-       pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+       pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
  }
  
  static void hsw_crt_get_config(struct intel_encoder *encoder,
                               struct intel_crtc_state *pipe_config)
  {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        intel_ddi_get_config(encoder, pipe_config);
  
        pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
                                              DRM_MODE_FLAG_PVSYNC |
                                              DRM_MODE_FLAG_NVSYNC);
        pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
+       pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
  }
  
  /* Note: The caller is required to filter out dpms modes not supported by the
@@@ -222,18 -218,26 +218,26 @@@ intel_crt_mode_valid(struct drm_connect
  {
        struct drm_device *dev = connector->dev;
        int max_dotclk = to_i915(dev)->max_dotclk_freq;
+       int max_clock;
  
-       int max_clock = 0;
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
  
        if (mode->clock < 25000)
                return MODE_CLOCK_LOW;
  
-       if (IS_GEN2(dev))
-               max_clock = 350000;
-       else
+       if (HAS_PCH_LPT(dev))
+               max_clock = 180000;
+       else if (IS_VALLEYVIEW(dev))
+               /*
+                * 270 MHz due to current DPLL limits,
+                * DAC limit supposedly 355 MHz.
+                */
+               max_clock = 270000;
+       else if (IS_GEN3(dev) || IS_GEN4(dev))
                max_clock = 400000;
+       else
+               max_clock = 350000;
        if (mode->clock > max_clock)
                return MODE_CLOCK_HIGH;
  
@@@ -257,25 -261,13 +261,19 @@@ static bool intel_crt_compute_config(st
                pipe_config->has_pch_encoder = true;
  
        /* LPT FDI RX only supports 8bpc. */
 -      if (HAS_PCH_LPT(dev))
 +      if (HAS_PCH_LPT(dev)) {
 +              if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
 +                      DRM_DEBUG_KMS("LPT only supports 24bpp\n");
 +                      return false;
 +              }
 +
                pipe_config->pipe_bpp = 24;
 +      }
  
        /* FDI must always be 2.7 GHz */
-       if (HAS_DDI(dev)) {
-               pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL;
+       if (HAS_DDI(dev))
                pipe_config->port_clock = 135000 * 2;
  
-               pipe_config->dpll_hw_state.wrpll = 0;
-               pipe_config->dpll_hw_state.spll =
-                       SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
-       }
        return true;
  }
  
@@@ -658,6 -650,8 +656,8 @@@ intel_crt_detect(struct drm_connector *
                else if (INTEL_INFO(dev)->gen < 4)
                        status = intel_crt_load_detect(crt,
                                to_intel_crtc(connector->state->crtc)->pipe);
+               else if (i915.load_detect_test)
+                       status = connector_status_disconnected;
                else
                        status = connector_status_unknown;
                intel_release_load_detect_pipe(connector, &tmp, &ctx);
index 96ffcc541e17697b69bad69fb24fe5bec3866aab,e30e1781fd713bc0b315503fdda9c0257ffa6b18..3fac04602a257b40906ef252543ec29af885e098
@@@ -315,6 -315,9 +315,9 @@@ static void ddi_get_encoder_port(struc
                *dig_port = enc_to_mst(encoder)->primary;
                *port = (*dig_port)->port;
                break;
+       default:
+               WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
+               /* fallthrough and treat as unknown */
        case INTEL_OUTPUT_DISPLAYPORT:
        case INTEL_OUTPUT_EDP:
        case INTEL_OUTPUT_HDMI:
                *dig_port = NULL;
                *port = PORT_E;
                break;
-       default:
-               WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
-               break;
        }
  }
  
@@@ -360,7 -360,7 +360,7 @@@ skl_get_buf_trans_dp(struct drm_i915_pr
  static const struct ddi_buf_trans *
  skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
  {
-       if (dev_priv->edp_low_vswing) {
+       if (dev_priv->vbt.edp.low_vswing) {
                if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
                        *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
                        return skl_y_ddi_translations_edp;
@@@ -444,7 -444,7 +444,7 @@@ void intel_prepare_ddi_buffer(struct in
                ddi_translations_fdi = bdw_ddi_translations_fdi;
                ddi_translations_dp = bdw_ddi_translations_dp;
  
-               if (dev_priv->edp_low_vswing) {
+               if (dev_priv->vbt.edp.low_vswing) {
                        ddi_translations_edp = bdw_ddi_translations_edp;
                        n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
                } else {
@@@ -637,6 -637,10 +637,10 @@@ void hsw_fdi_link_train(struct drm_crt
                        break;
                }
  
+               rx_ctl_val &= ~FDI_RX_ENABLE;
+               I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
+               POSTING_READ(FDI_RX_CTL(PIPE_A));
                temp = I915_READ(DDI_BUF_CTL(PORT_E));
                temp &= ~DDI_BUF_CTL_ENABLE;
                I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
  
                intel_wait_ddi_buf_idle(dev_priv, PORT_E);
  
-               rx_ctl_val &= ~FDI_RX_ENABLE;
-               I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
-               POSTING_READ(FDI_RX_CTL(PIPE_A));
                /* Reset FDI_RX_MISC pwrdn lanes */
                temp = I915_READ(FDI_RX_MISC(PIPE_A));
                temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
@@@ -732,160 -732,6 +732,6 @@@ intel_ddi_get_crtc_new_encoder(struct i
  }
  
  #define LC_FREQ 2700
- #define LC_FREQ_2K U64_C(LC_FREQ * 2000)
- #define P_MIN 2
- #define P_MAX 64
- #define P_INC 2
- /* Constraints for PLL good behavior */
- #define REF_MIN 48
- #define REF_MAX 400
- #define VCO_MIN 2400
- #define VCO_MAX 4800
- #define abs_diff(a, b) ({                     \
-       typeof(a) __a = (a);                    \
-       typeof(b) __b = (b);                    \
-       (void) (&__a == &__b);                  \
-       __a > __b ? (__a - __b) : (__b - __a); })
- struct hsw_wrpll_rnp {
-       unsigned p, n2, r2;
- };
- static unsigned hsw_wrpll_get_budget_for_freq(int clock)
- {
-       unsigned budget;
-       switch (clock) {
-       case 25175000:
-       case 25200000:
-       case 27000000:
-       case 27027000:
-       case 37762500:
-       case 37800000:
-       case 40500000:
-       case 40541000:
-       case 54000000:
-       case 54054000:
-       case 59341000:
-       case 59400000:
-       case 72000000:
-       case 74176000:
-       case 74250000:
-       case 81000000:
-       case 81081000:
-       case 89012000:
-       case 89100000:
-       case 108000000:
-       case 108108000:
-       case 111264000:
-       case 111375000:
-       case 148352000:
-       case 148500000:
-       case 162000000:
-       case 162162000:
-       case 222525000:
-       case 222750000:
-       case 296703000:
-       case 297000000:
-               budget = 0;
-               break;
-       case 233500000:
-       case 245250000:
-       case 247750000:
-       case 253250000:
-       case 298000000:
-               budget = 1500;
-               break;
-       case 169128000:
-       case 169500000:
-       case 179500000:
-       case 202000000:
-               budget = 2000;
-               break;
-       case 256250000:
-       case 262500000:
-       case 270000000:
-       case 272500000:
-       case 273750000:
-       case 280750000:
-       case 281250000:
-       case 286000000:
-       case 291750000:
-               budget = 4000;
-               break;
-       case 267250000:
-       case 268500000:
-               budget = 5000;
-               break;
-       default:
-               budget = 1000;
-               break;
-       }
-       return budget;
- }
- static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
-                                unsigned r2, unsigned n2, unsigned p,
-                                struct hsw_wrpll_rnp *best)
- {
-       uint64_t a, b, c, d, diff, diff_best;
-       /* No best (r,n,p) yet */
-       if (best->p == 0) {
-               best->p = p;
-               best->n2 = n2;
-               best->r2 = r2;
-               return;
-       }
-       /*
-        * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
-        * freq2k.
-        *
-        * delta = 1e6 *
-        *         abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
-        *         freq2k;
-        *
-        * and we would like delta <= budget.
-        *
-        * If the discrepancy is above the PPM-based budget, always prefer to
-        * improve upon the previous solution.  However, if you're within the
-        * budget, try to maximize Ref * VCO, that is N / (P * R^2).
-        */
-       a = freq2k * budget * p * r2;
-       b = freq2k * budget * best->p * best->r2;
-       diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
-       diff_best = abs_diff(freq2k * best->p * best->r2,
-                            LC_FREQ_2K * best->n2);
-       c = 1000000 * diff;
-       d = 1000000 * diff_best;
-       if (a < c && b < d) {
-               /* If both are above the budget, pick the closer */
-               if (best->p * best->r2 * diff < p * r2 * diff_best) {
-                       best->p = p;
-                       best->n2 = n2;
-                       best->r2 = r2;
-               }
-       } else if (a >= c && b < d) {
-               /* If A is below the threshold but B is above it?  Update. */
-               best->p = p;
-               best->n2 = n2;
-               best->r2 = r2;
-       } else if (a >= c && b >= d) {
-               /* Both are below the limit, so pick the higher n2/(r2*r2) */
-               if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
-                       best->p = p;
-                       best->n2 = n2;
-                       best->r2 = r2;
-               }
-       }
-       /* Otherwise a < c && b >= d, do nothing */
- }
  
  static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
                                   i915_reg_t reg)
@@@ -1147,363 -993,20 +993,20 @@@ void intel_ddi_clock_get(struct intel_e
                bxt_ddi_clock_get(encoder, pipe_config);
  }
  
- static void
- hsw_ddi_calculate_wrpll(int clock /* in Hz */,
-                       unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
- {
-       uint64_t freq2k;
-       unsigned p, n2, r2;
-       struct hsw_wrpll_rnp best = { 0, 0, 0 };
-       unsigned budget;
-       freq2k = clock / 100;
-       budget = hsw_wrpll_get_budget_for_freq(clock);
-       /* Special case handling for 540 pixel clock: bypass WR PLL entirely
-        * and directly pass the LC PLL to it. */
-       if (freq2k == 5400000) {
-               *n2_out = 2;
-               *p_out = 1;
-               *r2_out = 2;
-               return;
-       }
-       /*
-        * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
-        * the WR PLL.
-        *
-        * We want R so that REF_MIN <= Ref <= REF_MAX.
-        * Injecting R2 = 2 * R gives:
-        *   REF_MAX * r2 > LC_FREQ * 2 and
-        *   REF_MIN * r2 < LC_FREQ * 2
-        *
-        * Which means the desired boundaries for r2 are:
-        *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
-        *
-        */
-       for (r2 = LC_FREQ * 2 / REF_MAX + 1;
-            r2 <= LC_FREQ * 2 / REF_MIN;
-            r2++) {
-               /*
-                * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
-                *
-                * Once again we want VCO_MIN <= VCO <= VCO_MAX.
-                * Injecting R2 = 2 * R and N2 = 2 * N, we get:
-                *   VCO_MAX * r2 > n2 * LC_FREQ and
-                *   VCO_MIN * r2 < n2 * LC_FREQ)
-                *
-                * Which means the desired boundaries for n2 are:
-                * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
-                */
-               for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
-                    n2 <= VCO_MAX * r2 / LC_FREQ;
-                    n2++) {
-                       for (p = P_MIN; p <= P_MAX; p += P_INC)
-                               hsw_wrpll_update_rnp(freq2k, budget,
-                                                    r2, n2, p, &best);
-               }
-       }
-       *n2_out = best.n2;
-       *p_out = best.p;
-       *r2_out = best.r2;
- }
  static bool
  hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
                   struct intel_crtc_state *crtc_state,
                   struct intel_encoder *intel_encoder)
  {
-       int clock = crtc_state->port_clock;
-       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-               struct intel_shared_dpll *pll;
-               uint32_t val;
-               unsigned p, n2, r2;
-               hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-               val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
-                     WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
-                     WRPLL_DIVIDER_POST(p);
-               memset(&crtc_state->dpll_hw_state, 0,
-                      sizeof(crtc_state->dpll_hw_state));
-               crtc_state->dpll_hw_state.wrpll = val;
-               pll = intel_get_shared_dpll(intel_crtc, crtc_state);
-               if (pll == NULL) {
-                       DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
-                                        pipe_name(intel_crtc->pipe));
-                       return false;
-               }
-               crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
-       } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
-               struct drm_atomic_state *state = crtc_state->base.state;
-               struct intel_shared_dpll_config *spll =
-                       &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
-               if (spll->crtc_mask &&
-                   WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
-                       return false;
-               crtc_state->shared_dpll = DPLL_ID_SPLL;
-               spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
-               spll->crtc_mask |= 1 << intel_crtc->pipe;
-       }
-       return true;
- }
- struct skl_wrpll_context {
-       uint64_t min_deviation;         /* current minimal deviation */
-       uint64_t central_freq;          /* chosen central freq */
-       uint64_t dco_freq;              /* chosen dco freq */
-       unsigned int p;                 /* chosen divider */
- };
- static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
- {
-       memset(ctx, 0, sizeof(*ctx));
-       ctx->min_deviation = U64_MAX;
- }
- /* DCO freq must be within +1%/-6%  of the DCO central freq */
- #define SKL_DCO_MAX_PDEVIATION        100
- #define SKL_DCO_MAX_NDEVIATION        600
- static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
-                                 uint64_t central_freq,
-                                 uint64_t dco_freq,
-                                 unsigned int divider)
- {
-       uint64_t deviation;
-       deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
-                             central_freq);
-       /* positive deviation */
-       if (dco_freq >= central_freq) {
-               if (deviation < SKL_DCO_MAX_PDEVIATION &&
-                   deviation < ctx->min_deviation) {
-                       ctx->min_deviation = deviation;
-                       ctx->central_freq = central_freq;
-                       ctx->dco_freq = dco_freq;
-                       ctx->p = divider;
-               }
-       /* negative deviation */
-       } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
-                  deviation < ctx->min_deviation) {
-               ctx->min_deviation = deviation;
-               ctx->central_freq = central_freq;
-               ctx->dco_freq = dco_freq;
-               ctx->p = divider;
-       }
- }
- static void skl_wrpll_get_multipliers(unsigned int p,
-                                     unsigned int *p0 /* out */,
-                                     unsigned int *p1 /* out */,
-                                     unsigned int *p2 /* out */)
- {
-       /* even dividers */
-       if (p % 2 == 0) {
-               unsigned int half = p / 2;
-               if (half == 1 || half == 2 || half == 3 || half == 5) {
-                       *p0 = 2;
-                       *p1 = 1;
-                       *p2 = half;
-               } else if (half % 2 == 0) {
-                       *p0 = 2;
-                       *p1 = half / 2;
-                       *p2 = 2;
-               } else if (half % 3 == 0) {
-                       *p0 = 3;
-                       *p1 = half / 3;
-                       *p2 = 2;
-               } else if (half % 7 == 0) {
-                       *p0 = 7;
-                       *p1 = half / 7;
-                       *p2 = 2;
-               }
-       } else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
-               *p0 = 3;
-               *p1 = 1;
-               *p2 = p / 3;
-       } else if (p == 5 || p == 7) {
-               *p0 = p;
-               *p1 = 1;
-               *p2 = 1;
-       } else if (p == 15) {
-               *p0 = 3;
-               *p1 = 1;
-               *p2 = 5;
-       } else if (p == 21) {
-               *p0 = 7;
-               *p1 = 1;
-               *p2 = 3;
-       } else if (p == 35) {
-               *p0 = 7;
-               *p1 = 1;
-               *p2 = 5;
-       }
- }
- struct skl_wrpll_params {
-       uint32_t        dco_fraction;
-       uint32_t        dco_integer;
-       uint32_t        qdiv_ratio;
-       uint32_t        qdiv_mode;
-       uint32_t        kdiv;
-       uint32_t        pdiv;
-       uint32_t        central_freq;
- };
- static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
-                                     uint64_t afe_clock,
-                                     uint64_t central_freq,
-                                     uint32_t p0, uint32_t p1, uint32_t p2)
- {
-       uint64_t dco_freq;
-       switch (central_freq) {
-       case 9600000000ULL:
-               params->central_freq = 0;
-               break;
-       case 9000000000ULL:
-               params->central_freq = 1;
-               break;
-       case 8400000000ULL:
-               params->central_freq = 3;
-       }
-       switch (p0) {
-       case 1:
-               params->pdiv = 0;
-               break;
-       case 2:
-               params->pdiv = 1;
-               break;
-       case 3:
-               params->pdiv = 2;
-               break;
-       case 7:
-               params->pdiv = 4;
-               break;
-       default:
-               WARN(1, "Incorrect PDiv\n");
-       }
-       switch (p2) {
-       case 5:
-               params->kdiv = 0;
-               break;
-       case 2:
-               params->kdiv = 1;
-               break;
-       case 3:
-               params->kdiv = 2;
-               break;
-       case 1:
-               params->kdiv = 3;
-               break;
-       default:
-               WARN(1, "Incorrect KDiv\n");
-       }
-       params->qdiv_ratio = p1;
-       params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
-       dco_freq = p0 * p1 * p2 * afe_clock;
-       /*
-        * Intermediate values are in Hz.
-        * Divide by MHz to match bsepc
-        */
-       params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
-       params->dco_fraction =
-               div_u64((div_u64(dco_freq, 24) -
-                        params->dco_integer * MHz(1)) * 0x8000, MHz(1));
- }
- static bool
- skl_ddi_calculate_wrpll(int clock /* in Hz */,
-                       struct skl_wrpll_params *wrpll_params)
- {
-       uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
-       uint64_t dco_central_freq[3] = {8400000000ULL,
-                                       9000000000ULL,
-                                       9600000000ULL};
-       static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
-                                            24, 28, 30, 32, 36, 40, 42, 44,
-                                            48, 52, 54, 56, 60, 64, 66, 68,
-                                            70, 72, 76, 78, 80, 84, 88, 90,
-                                            92, 96, 98 };
-       static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
-       static const struct {
-               const int *list;
-               int n_dividers;
-       } dividers[] = {
-               { even_dividers, ARRAY_SIZE(even_dividers) },
-               { odd_dividers, ARRAY_SIZE(odd_dividers) },
-       };
-       struct skl_wrpll_context ctx;
-       unsigned int dco, d, i;
-       unsigned int p0, p1, p2;
-       skl_wrpll_context_init(&ctx);
-       for (d = 0; d < ARRAY_SIZE(dividers); d++) {
-               for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
-                       for (i = 0; i < dividers[d].n_dividers; i++) {
-                               unsigned int p = dividers[d].list[i];
-                               uint64_t dco_freq = p * afe_clock;
-                               skl_wrpll_try_divider(&ctx,
-                                                     dco_central_freq[dco],
-                                                     dco_freq,
-                                                     p);
-                               /*
-                                * Skip the remaining dividers if we're sure to
-                                * have found the definitive divider, we can't
-                                * improve a 0 deviation.
-                                */
-                               if (ctx.min_deviation == 0)
-                                       goto skip_remaining_dividers;
-                       }
-               }
- skip_remaining_dividers:
-               /*
-                * If a solution is found with an even divider, prefer
-                * this one.
-                */
-               if (d == 0 && ctx.p)
-                       break;
-       }
-       if (!ctx.p) {
-               DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
-               return false;
-       }
+       struct intel_shared_dpll *pll;
  
-       /*
-        * gcc incorrectly analyses that these can be used without being
-        * initialized. To be fair, it's hard to guess.
-        */
-       p0 = p1 = p2 = 0;
-       skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
-       skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
-                                 p0, p1, p2);
+       pll = intel_get_shared_dpll(intel_crtc, crtc_state,
+                                   intel_encoder);
+       if (!pll)
+               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+                                pipe_name(intel_crtc->pipe));
  
-       return true;
+       return pll;
  }
  
  static bool
@@@ -1512,218 -1015,23 +1015,23 @@@ skl_ddi_pll_select(struct intel_crtc *i
                   struct intel_encoder *intel_encoder)
  {
        struct intel_shared_dpll *pll;
-       uint32_t ctrl1, cfgcr1, cfgcr2;
-       int clock = crtc_state->port_clock;
-       /*
-        * See comment in intel_dpll_hw_state to understand why we always use 0
-        * as the DPLL id in this function.
-        */
-       ctrl1 = DPLL_CTRL1_OVERRIDE(0);
-       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-               struct skl_wrpll_params wrpll_params = { 0, };
-               ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
-               if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
-                       return false;
-               cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
-                        DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
-                        wrpll_params.dco_integer;
-               cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
-                        DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
-                        DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
-                        DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
-                        wrpll_params.central_freq;
-       } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-                  intel_encoder->type == INTEL_OUTPUT_DP_MST) {
-               switch (crtc_state->port_clock / 2) {
-               case 81000:
-                       ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
-                       break;
-               case 135000:
-                       ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
-                       break;
-               case 270000:
-                       ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
-                       break;
-               }
-               cfgcr1 = cfgcr2 = 0;
-       } else if (intel_encoder->type == INTEL_OUTPUT_EDP) {
-               return true;
-       } else
-               return false;
  
-       memset(&crtc_state->dpll_hw_state, 0,
-              sizeof(crtc_state->dpll_hw_state));
-       crtc_state->dpll_hw_state.ctrl1 = ctrl1;
-       crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
-       crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
-       pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+       pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
        if (pll == NULL) {
                DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
                                 pipe_name(intel_crtc->pipe));
                return false;
        }
  
-       /* shared DPLL id 0 is DPLL 1 */
-       crtc_state->ddi_pll_sel = pll->id + 1;
        return true;
  }
  
- /* bxt clock parameters */
- struct bxt_clk_div {
-       int clock;
-       uint32_t p1;
-       uint32_t p2;
-       uint32_t m2_int;
-       uint32_t m2_frac;
-       bool m2_frac_en;
-       uint32_t n;
- };
- /* pre-calculated values for DP linkrates */
- static const struct bxt_clk_div bxt_dp_clk_val[] = {
-       {162000, 4, 2, 32, 1677722, 1, 1},
-       {270000, 4, 1, 27,       0, 0, 1},
-       {540000, 2, 1, 27,       0, 0, 1},
-       {216000, 3, 2, 32, 1677722, 1, 1},
-       {243000, 4, 1, 24, 1258291, 1, 1},
-       {324000, 4, 1, 32, 1677722, 1, 1},
-       {432000, 3, 1, 32, 1677722, 1, 1}
- };
  static bool
  bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
                   struct intel_crtc_state *crtc_state,
                   struct intel_encoder *intel_encoder)
  {
-       struct intel_shared_dpll *pll;
-       struct bxt_clk_div clk_div = {0};
-       int vco = 0;
-       uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
-       uint32_t lanestagger;
-       int clock = crtc_state->port_clock;
-       if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-               intel_clock_t best_clock;
-               /* Calculate HDMI div */
-               /*
-                * FIXME: tie the following calculation into
-                * i9xx_crtc_compute_clock
-                */
-               if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
-                       DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
-                                        clock, pipe_name(intel_crtc->pipe));
-                       return false;
-               }
-               clk_div.p1 = best_clock.p1;
-               clk_div.p2 = best_clock.p2;
-               WARN_ON(best_clock.m1 != 2);
-               clk_div.n = best_clock.n;
-               clk_div.m2_int = best_clock.m2 >> 22;
-               clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
-               clk_div.m2_frac_en = clk_div.m2_frac != 0;
-               vco = best_clock.vco;
-       } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-                       intel_encoder->type == INTEL_OUTPUT_EDP) {
-               int i;
-               clk_div = bxt_dp_clk_val[0];
-               for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
-                       if (bxt_dp_clk_val[i].clock == clock) {
-                               clk_div = bxt_dp_clk_val[i];
-                               break;
-                       }
-               }
-               vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
-       }
-       if (vco >= 6200000 && vco <= 6700000) {
-               prop_coef = 4;
-               int_coef = 9;
-               gain_ctl = 3;
-               targ_cnt = 8;
-       } else if ((vco > 5400000 && vco < 6200000) ||
-                       (vco >= 4800000 && vco < 5400000)) {
-               prop_coef = 5;
-               int_coef = 11;
-               gain_ctl = 3;
-               targ_cnt = 9;
-       } else if (vco == 5400000) {
-               prop_coef = 3;
-               int_coef = 8;
-               gain_ctl = 1;
-               targ_cnt = 9;
-       } else {
-               DRM_ERROR("Invalid VCO\n");
-               return false;
-       }
-       memset(&crtc_state->dpll_hw_state, 0,
-              sizeof(crtc_state->dpll_hw_state));
-       if (clock > 270000)
-               lanestagger = 0x18;
-       else if (clock > 135000)
-               lanestagger = 0x0d;
-       else if (clock > 67000)
-               lanestagger = 0x07;
-       else if (clock > 33000)
-               lanestagger = 0x04;
-       else
-               lanestagger = 0x02;
-       crtc_state->dpll_hw_state.ebb0 =
-               PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
-       crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
-       crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
-       crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
-       if (clk_div.m2_frac_en)
-               crtc_state->dpll_hw_state.pll3 =
-                       PORT_PLL_M2_FRAC_ENABLE;
-       crtc_state->dpll_hw_state.pll6 =
-               prop_coef | PORT_PLL_INT_COEFF(int_coef);
-       crtc_state->dpll_hw_state.pll6 |=
-               PORT_PLL_GAIN_CTL(gain_ctl);
-       crtc_state->dpll_hw_state.pll8 = targ_cnt;
-       crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
-       crtc_state->dpll_hw_state.pll10 =
-               PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
-               | PORT_PLL_DCO_AMP_OVR_EN_H;
-       crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
-       crtc_state->dpll_hw_state.pcsdw12 =
-               LANESTAGGER_STRAP_OVRD | lanestagger;
-       pll = intel_get_shared_dpll(intel_crtc, crtc_state);
-       if (pll == NULL) {
-               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
-                       pipe_name(intel_crtc->pipe));
-               return false;
-       }
-       /* shared DPLL id 0 is DPLL A */
-       crtc_state->ddi_pll_sel = pll->id;
-       return true;
+       return !!intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
  }
  
  /*
@@@ -1761,6 -1069,8 +1069,8 @@@ void intel_ddi_set_pipe_settings(struc
        uint32_t temp;
  
        if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
+               WARN_ON(transcoder_is_dsi(cpu_transcoder));
                temp = TRANS_MSA_SYNC_CLK;
                switch (intel_crtc->config->pipe_bpp) {
                case 18:
@@@ -2129,7 -1439,7 +1439,7 @@@ static void bxt_ddi_vswing_sequence(str
        u32 n_entries, i;
        uint32_t val;
  
-       if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
+       if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
                n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
                ddi_translations = bxt_ddi_translations_edp;
        } else if (type == INTEL_OUTPUT_DISPLAYPORT
@@@ -2267,24 -1577,6 +1577,6 @@@ void intel_ddi_clk_select(struct intel_
                uint32_t dpll = pipe_config->ddi_pll_sel;
                uint32_t val;
  
-               /*
-                * DPLL0 is used for eDP and is the only "private" DPLL (as
-                * opposed to shared) on SKL
-                */
-               if (encoder->type == INTEL_OUTPUT_EDP) {
-                       WARN_ON(dpll != SKL_DPLL0);
-                       val = I915_READ(DPLL_CTRL1);
-                       val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
-                                DPLL_CTRL1_SSC(dpll) |
-                                DPLL_CTRL1_LINK_RATE_MASK(dpll));
-                       val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
-                       I915_WRITE(DPLL_CTRL1, val);
-                       POSTING_READ(DPLL_CTRL1);
-               }
                /* DDI -> PLL mapping  */
                val = I915_READ(DPLL_CTRL2);
  
@@@ -2438,251 -1730,101 +1730,101 @@@ static void intel_disable_ddi(struct in
        }
  }
  
- static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
-                              struct intel_shared_dpll *pll)
- {
-       I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
-       POSTING_READ(WRPLL_CTL(pll->id));
-       udelay(20);
- }
- static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
-                               struct intel_shared_dpll *pll)
- {
-       I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
-       POSTING_READ(SPLL_CTL);
-       udelay(20);
- }
- static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
-                                 struct intel_shared_dpll *pll)
+ static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv,
+                                  enum dpio_phy phy)
  {
-       uint32_t val;
-       val = I915_READ(WRPLL_CTL(pll->id));
-       I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
-       POSTING_READ(WRPLL_CTL(pll->id));
- }
- static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
-                                struct intel_shared_dpll *pll)
- {
-       uint32_t val;
-       val = I915_READ(SPLL_CTL);
-       I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
-       POSTING_READ(SPLL_CTL);
- }
- static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
-                                      struct intel_shared_dpll *pll,
-                                      struct intel_dpll_hw_state *hw_state)
- {
-       uint32_t val;
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+       if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy)))
                return false;
  
-       val = I915_READ(WRPLL_CTL(pll->id));
-       hw_state->wrpll = val;
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-       return val & WRPLL_PLL_ENABLE;
- }
- static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
-                                     struct intel_shared_dpll *pll,
-                                     struct intel_dpll_hw_state *hw_state)
- {
-       uint32_t val;
+       if ((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
+            (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) {
+               DRM_DEBUG_DRIVER("DDI PHY %d powered, but power hasn't settled\n",
+                                phy);
  
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
                return false;
+       }
  
-       val = I915_READ(SPLL_CTL);
-       hw_state->spll = val;
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-       return val & SPLL_PLL_ENABLE;
- }
- static const char * const hsw_ddi_pll_names[] = {
-       "WRPLL 1",
-       "WRPLL 2",
-       "SPLL"
- };
+       if (phy == DPIO_PHY1 &&
+           !(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE)) {
+               DRM_DEBUG_DRIVER("DDI PHY 1 powered, but GRC isn't done\n");
  
- static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
- {
-       int i;
+               return false;
+       }
  
-       dev_priv->num_shared_dpll = 3;
+       if (!(I915_READ(BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
+               DRM_DEBUG_DRIVER("DDI PHY %d powered, but still in reset\n",
+                                phy);
  
-       for (i = 0; i < 2; i++) {
-               dev_priv->shared_dplls[i].id = i;
-               dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-               dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
-               dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
-               dev_priv->shared_dplls[i].get_hw_state =
-                       hsw_ddi_wrpll_get_hw_state;
+               return false;
        }
  
-       /* SPLL is special, but needs to be initialized anyway.. */
-       dev_priv->shared_dplls[i].id = i;
-       dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-       dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
-       dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
-       dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
+       return true;
  }
  
- static const char * const skl_ddi_pll_names[] = {
-       "DPLL 1",
-       "DPLL 2",
-       "DPLL 3",
- };
- struct skl_dpll_regs {
-       i915_reg_t ctl, cfgcr1, cfgcr2;
- };
- /* this array is indexed by the *shared* pll id */
- static const struct skl_dpll_regs skl_dpll_regs[3] = {
-       {
-               /* DPLL 1 */
-               .ctl = LCPLL2_CTL,
-               .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
-               .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
-       },
-       {
-               /* DPLL 2 */
-               .ctl = WRPLL_CTL(0),
-               .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
-               .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
-       },
-       {
-               /* DPLL 3 */
-               .ctl = WRPLL_CTL(1),
-               .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
-               .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
-       },
- };
- static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
-                              struct intel_shared_dpll *pll)
+ static u32 broxton_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
  {
-       uint32_t val;
-       unsigned int dpll;
-       const struct skl_dpll_regs *regs = skl_dpll_regs;
-       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-       dpll = pll->id + 1;
-       val = I915_READ(DPLL_CTRL1);
-       val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
-                DPLL_CTRL1_LINK_RATE_MASK(dpll));
-       val |= pll->config.hw_state.ctrl1 << (dpll * 6);
-       I915_WRITE(DPLL_CTRL1, val);
-       POSTING_READ(DPLL_CTRL1);
-       I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
-       I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
-       POSTING_READ(regs[pll->id].cfgcr1);
-       POSTING_READ(regs[pll->id].cfgcr2);
+       u32 val = I915_READ(BXT_PORT_REF_DW6(phy));
  
-       /* the enable bit is always bit 31 */
-       I915_WRITE(regs[pll->id].ctl,
-                  I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
-       if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
-               DRM_ERROR("DPLL %d not locked\n", dpll);
+       return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
  }
  
- static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
-                               struct intel_shared_dpll *pll)
+ static void broxton_phy_wait_grc_done(struct drm_i915_private *dev_priv,
+                                     enum dpio_phy phy)
  {
-       const struct skl_dpll_regs *regs = skl_dpll_regs;
-       /* the enable bit is always bit 31 */
-       I915_WRITE(regs[pll->id].ctl,
-                  I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
-       POSTING_READ(regs[pll->id].ctl);
+       if (wait_for(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE, 10))
+               DRM_ERROR("timeout waiting for PHY%d GRC\n", phy);
  }
  
- static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
-                                    struct intel_shared_dpll *pll,
-                                    struct intel_dpll_hw_state *hw_state)
- {
-       uint32_t val;
-       unsigned int dpll;
-       const struct skl_dpll_regs *regs = skl_dpll_regs;
-       bool ret;
+ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
+                                    enum dpio_phy phy);
  
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-               return false;
-       ret = false;
-       /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-       dpll = pll->id + 1;
-       val = I915_READ(regs[pll->id].ctl);
-       if (!(val & LCPLL_PLL_ENABLE))
-               goto out;
-       val = I915_READ(DPLL_CTRL1);
-       hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
-       /* avoid reading back stale values if HDMI mode is not enabled */
-       if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
-               hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
-               hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
-       }
-       ret = true;
- out:
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+ static void broxton_phy_init(struct drm_i915_private *dev_priv,
+                            enum dpio_phy phy)
+ {
+       enum port port;
+       u32 ports, val;
  
-       return ret;
- }
+       if (broxton_phy_is_enabled(dev_priv, phy)) {
+               /* Still read out the GRC value for state verification */
+               if (phy == DPIO_PHY0)
+                       dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy);
  
- static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
- {
-       int i;
+               if (broxton_phy_verify_state(dev_priv, phy)) {
+                       DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
+                                        "won't reprogram it\n", phy);
  
-       dev_priv->num_shared_dpll = 3;
+                       return;
+               }
  
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               dev_priv->shared_dplls[i].id = i;
-               dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
-               dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
-               dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
-               dev_priv->shared_dplls[i].get_hw_state =
-                       skl_ddi_pll_get_hw_state;
+               DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, "
+                                "force reprogramming it\n", phy);
+       } else {
+               DRM_DEBUG_DRIVER("DDI PHY %d not enabled, enabling it\n", phy);
        }
- }
- static void broxton_phy_init(struct drm_i915_private *dev_priv,
-                            enum dpio_phy phy)
- {
-       enum port port;
-       uint32_t val;
  
        val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
        val |= GT_DISPLAY_POWER_ON(phy);
        I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
  
-       /* Considering 10ms timeout until BSpec is updated */
-       if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
+       /*
+        * The PHY registers start out inaccessible and respond to reads with
+        * all 1s.  Eventually they become accessible as they power up, then
+        * the reserved bit will give the default 0.  Poll on the reserved bit
+        * becoming 0 to find when the PHY is accessible.
+        * HW team confirmed that the time to reach phypowergood status is
+        * anywhere between 50 us and 100us.
+        */
+       if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
+               (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) {
                DRM_ERROR("timeout during PHY%d power on\n", phy);
+       }
  
-       for (port =  (phy == DPIO_PHY0 ? PORT_B : PORT_A);
-            port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
+       if (phy == DPIO_PHY0)
+               ports = BIT(PORT_B) | BIT(PORT_C);
+       else
+               ports = BIT(PORT_A);
+       for_each_port_masked(port, ports) {
                int lane;
  
                for (lane = 0; lane < 4; lane++) {
         * enabled.
         * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
         * power down the second channel on PHY0 as well.
+        *
+        * FIXME: Clarify programming of the following, the register is
+        * read-only with bit 6 fixed at 0 at least in stepping A.
         */
        if (phy == DPIO_PHY1)
                val |= OCL2_LDOFUSE_PWR_DIS;
                 * the corresponding calibrated value from PHY1, and disable
                 * the automatic calibration on PHY0.
                 */
-               if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
-                            10))
-                       DRM_ERROR("timeout waiting for PHY1 GRC\n");
+               broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
  
-               val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
-               val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
+               val = dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv,
+                                                             DPIO_PHY1);
                grc_code = val << GRC_CODE_FAST_SHIFT |
                           val << GRC_CODE_SLOW_SHIFT |
                           val;
                val |= GRC_DIS | GRC_RDY_OVRD;
                I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
        }
+       /*
+        * During PHY1 init delay waiting for GRC calibration to finish, since
+        * it can happen in parallel with the subsequent PHY0 init.
+        */
  
        val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
        val |= COMMON_RESET_DIS;
        I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
  }
  
- void broxton_ddi_phy_init(struct drm_device *dev)
+ void broxton_ddi_phy_init(struct drm_i915_private *dev_priv)
  {
        /* Enable PHY1 first since it provides Rcomp for PHY0 */
-       broxton_phy_init(dev->dev_private, DPIO_PHY1);
-       broxton_phy_init(dev->dev_private, DPIO_PHY0);
+       broxton_phy_init(dev_priv, DPIO_PHY1);
+       broxton_phy_init(dev_priv, DPIO_PHY0);
+       /*
+        * If BIOS enabled only PHY0 and not PHY1, we skipped waiting for the
+        * PHY1 GRC calibration to finish, so wait for it here.
+        */
+       broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
  }
  
  static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
        val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
        val &= ~COMMON_RESET_DIS;
        I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
+       val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
+       val &= ~GT_DISPLAY_POWER_ON(phy);
+       I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
  }
  
- void broxton_ddi_phy_uninit(struct drm_device *dev)
+ void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        broxton_phy_uninit(dev_priv, DPIO_PHY1);
        broxton_phy_uninit(dev_priv, DPIO_PHY0);
-       /* FIXME: do this in broxton_phy_uninit per phy */
-       I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
  }
  
- static const char * const bxt_ddi_pll_names[] = {
-       "PORT PLL A",
-       "PORT PLL B",
-       "PORT PLL C",
- };
- static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
-                               struct intel_shared_dpll *pll)
+ static bool __printf(6, 7)
+ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+                      i915_reg_t reg, u32 mask, u32 expected,
+                      const char *reg_fmt, ...)
  {
-       uint32_t temp;
-       enum port port = (enum port)pll->id;    /* 1:1 port->PLL mapping */
-       temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-       temp &= ~PORT_PLL_REF_SEL;
-       /* Non-SSC reference */
-       I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-       /* Disable 10 bit clock */
-       temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
-       temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
-       I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-       /* Write P1 & P2 */
-       temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
-       temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
-       temp |= pll->config.hw_state.ebb0;
-       I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
-       /* Write M2 integer */
-       temp = I915_READ(BXT_PORT_PLL(port, 0));
-       temp &= ~PORT_PLL_M2_MASK;
-       temp |= pll->config.hw_state.pll0;
-       I915_WRITE(BXT_PORT_PLL(port, 0), temp);
-       /* Write N */
-       temp = I915_READ(BXT_PORT_PLL(port, 1));
-       temp &= ~PORT_PLL_N_MASK;
-       temp |= pll->config.hw_state.pll1;
-       I915_WRITE(BXT_PORT_PLL(port, 1), temp);
-       /* Write M2 fraction */
-       temp = I915_READ(BXT_PORT_PLL(port, 2));
-       temp &= ~PORT_PLL_M2_FRAC_MASK;
-       temp |= pll->config.hw_state.pll2;
-       I915_WRITE(BXT_PORT_PLL(port, 2), temp);
-       /* Write M2 fraction enable */
-       temp = I915_READ(BXT_PORT_PLL(port, 3));
-       temp &= ~PORT_PLL_M2_FRAC_ENABLE;
-       temp |= pll->config.hw_state.pll3;
-       I915_WRITE(BXT_PORT_PLL(port, 3), temp);
-       /* Write coeff */
-       temp = I915_READ(BXT_PORT_PLL(port, 6));
-       temp &= ~PORT_PLL_PROP_COEFF_MASK;
-       temp &= ~PORT_PLL_INT_COEFF_MASK;
-       temp &= ~PORT_PLL_GAIN_CTL_MASK;
-       temp |= pll->config.hw_state.pll6;
-       I915_WRITE(BXT_PORT_PLL(port, 6), temp);
-       /* Write calibration val */
-       temp = I915_READ(BXT_PORT_PLL(port, 8));
-       temp &= ~PORT_PLL_TARGET_CNT_MASK;
-       temp |= pll->config.hw_state.pll8;
-       I915_WRITE(BXT_PORT_PLL(port, 8), temp);
-       temp = I915_READ(BXT_PORT_PLL(port, 9));
-       temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
-       temp |= pll->config.hw_state.pll9;
-       I915_WRITE(BXT_PORT_PLL(port, 9), temp);
-       temp = I915_READ(BXT_PORT_PLL(port, 10));
-       temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
-       temp &= ~PORT_PLL_DCO_AMP_MASK;
-       temp |= pll->config.hw_state.pll10;
-       I915_WRITE(BXT_PORT_PLL(port, 10), temp);
-       /* Recalibrate with new settings */
-       temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
-       temp |= PORT_PLL_RECALIBRATE;
-       I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-       temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
-       temp |= pll->config.hw_state.ebb4;
-       I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-       /* Enable PLL */
-       temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-       temp |= PORT_PLL_ENABLE;
-       I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-       POSTING_READ(BXT_PORT_PLL_ENABLE(port));
-       if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
-                       PORT_PLL_LOCK), 200))
-               DRM_ERROR("PLL %d not locked\n", port);
-       /*
-        * While we write to the group register to program all lanes at once we
-        * can read only lane registers and we pick lanes 0/1 for that.
-        */
-       temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
-       temp &= ~LANE_STAGGER_MASK;
-       temp &= ~LANESTAGGER_STRAP_OVRD;
-       temp |= pll->config.hw_state.pcsdw12;
-       I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
- }
- static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
-                                       struct intel_shared_dpll *pll)
- {
-       enum port port = (enum port)pll->id;    /* 1:1 port->PLL mapping */
-       uint32_t temp;
+       struct va_format vaf;
+       va_list args;
+       u32 val;
  
-       temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-       temp &= ~PORT_PLL_ENABLE;
-       I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-       POSTING_READ(BXT_PORT_PLL_ENABLE(port));
- }
+       val = I915_READ(reg);
+       if ((val & mask) == expected)
+               return true;
  
- static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
-                                       struct intel_shared_dpll *pll,
-                                       struct intel_dpll_hw_state *hw_state)
- {
-       enum port port = (enum port)pll->id;    /* 1:1 port->PLL mapping */
-       uint32_t val;
-       bool ret;
+       va_start(args, reg_fmt);
+       vaf.fmt = reg_fmt;
+       vaf.va = &args;
  
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-               return false;
+       DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: "
+                        "current %08x, expected %08x (mask %08x)\n",
+                        phy, &vaf, reg.reg, val, (val & ~mask) | expected,
+                        mask);
  
-       ret = false;
+       va_end(args);
  
-       val = I915_READ(BXT_PORT_PLL_ENABLE(port));
-       if (!(val & PORT_PLL_ENABLE))
-               goto out;
+       return false;
+ }
  
-       hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
-       hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
+ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
+                                    enum dpio_phy phy)
+ {
+       enum port port;
+       u32 ports;
+       uint32_t mask;
+       bool ok;
  
-       hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
-       hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
+ #define _CHK(reg, mask, exp, fmt, ...)                                        \
+       __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt,      \
+                              ## __VA_ARGS__)
  
-       hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
-       hw_state->pll0 &= PORT_PLL_M2_MASK;
+       /* We expect the PHY to be always enabled */
+       if (!broxton_phy_is_enabled(dev_priv, phy))
+               return false;
  
-       hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
-       hw_state->pll1 &= PORT_PLL_N_MASK;
+       ok = true;
  
-       hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
-       hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
+       if (phy == DPIO_PHY0)
+               ports = BIT(PORT_B) | BIT(PORT_C);
+       else
+               ports = BIT(PORT_A);
  
-       hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
-       hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
+       for_each_port_masked(port, ports) {
+               int lane;
  
-       hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
-       hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
-                         PORT_PLL_INT_COEFF_MASK |
-                         PORT_PLL_GAIN_CTL_MASK;
+               for (lane = 0; lane < 4; lane++)
+                       ok &= _CHK(BXT_PORT_TX_DW14_LN(port, lane),
+                                   LATENCY_OPTIM,
+                                   lane != 1 ? LATENCY_OPTIM : 0,
+                                   "BXT_PORT_TX_DW14_LN(%d, %d)", port, lane);
+       }
  
-       hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
-       hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
+       /* PLL Rcomp code offset */
+       ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
+                   IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
+                   "BXT_PORT_CL1CM_DW9(%d)", phy);
+       ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
+                   IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
+                   "BXT_PORT_CL1CM_DW10(%d)", phy);
  
-       hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
-       hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
+       /* Power gating */
+       mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
+       ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
+                   "BXT_PORT_CL1CM_DW28(%d)", phy);
  
-       hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
-       hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
-                          PORT_PLL_DCO_AMP_MASK;
+       if (phy == DPIO_PHY0)
+               ok &= _CHK(BXT_PORT_CL2CM_DW6_BC,
+                          DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN,
+                          "BXT_PORT_CL2CM_DW6_BC");
  
        /*
-        * While we write to the group register to program all lanes at once we
-        * can read only lane registers. We configure all lanes the same way, so
-        * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
+        * TODO: Verify BXT_PORT_CL1CM_DW30 bit OCL2_LDOFUSE_PWR_DIS,
+        * at least on stepping A this bit is read-only and fixed at 0.
         */
-       hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
-       if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
-               DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
-                                hw_state->pcsdw12,
-                                I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
-       hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
-       ret = true;
  
- out:
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-       return ret;
- }
- static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
- {
-       int i;
+       if (phy == DPIO_PHY0) {
+               u32 grc_code = dev_priv->bxt_phy_grc;
  
-       dev_priv->num_shared_dpll = 3;
+               grc_code = grc_code << GRC_CODE_FAST_SHIFT |
+                          grc_code << GRC_CODE_SLOW_SHIFT |
+                          grc_code;
+               mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK |
+                      GRC_CODE_NOM_MASK;
+               ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code,
+                           "BXT_PORT_REF_DW6(%d)", DPIO_PHY0);
  
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               dev_priv->shared_dplls[i].id = i;
-               dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
-               dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
-               dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
-               dev_priv->shared_dplls[i].get_hw_state =
-                       bxt_ddi_pll_get_hw_state;
+               mask = GRC_DIS | GRC_RDY_OVRD;
+               ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask,
+                           "BXT_PORT_REF_DW8(%d)", DPIO_PHY0);
        }
+       return ok;
+ #undef _CHK
  }
  
- void intel_ddi_pll_init(struct drm_device *dev)
+ void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t val = I915_READ(LCPLL_CTL);
-       if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
-               skl_shared_dplls_init(dev_priv);
-       else if (IS_BROXTON(dev))
-               bxt_shared_dplls_init(dev_priv);
-       else
-               hsw_shared_dplls_init(dev_priv);
-       if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-               int cdclk_freq;
-               cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
-               dev_priv->skl_boot_cdclk = cdclk_freq;
-               if (skl_sanitize_cdclk(dev_priv))
-                       DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
-               if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-                       DRM_ERROR("LCPLL1 is disabled\n");
-       } else if (IS_BROXTON(dev)) {
-               broxton_init_cdclk(dev);
-               broxton_ddi_phy_init(dev);
-       } else {
-               /*
-                * The LCPLL register should be turned on by the BIOS. For now
-                * let's just check its state and print errors in case
-                * something is wrong.  Don't even try to turn it on.
-                */
-               if (val & LCPLL_CD_SOURCE_FCLK)
-                       DRM_ERROR("CDCLK source is not LCPLL\n");
-               if (val & LCPLL_PLL_DISABLE)
-                       DRM_ERROR("LCPLL is disabled\n");
-       }
+       if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) ||
+           !broxton_phy_verify_state(dev_priv, DPIO_PHY1))
+               i915_report_error(dev_priv, "DDI PHY state mismatch\n");
  }
  
  void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
@@@ -3086,12 -2105,18 +2105,18 @@@ void intel_ddi_fdi_disable(struct drm_c
        struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
        uint32_t val;
  
-       intel_ddi_post_disable(intel_encoder);
+       /*
+        * Bspec lists this as both step 13 (before DDI_BUF_CTL disable)
+        * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN,
+        * step 13 is the correct place for it. Step 18 is where it was
+        * originally before the BUN.
+        */
        val = I915_READ(FDI_RX_CTL(PIPE_A));
        val &= ~FDI_RX_ENABLE;
        I915_WRITE(FDI_RX_CTL(PIPE_A), val);
  
+       intel_ddi_post_disable(intel_encoder);
        val = I915_READ(FDI_RX_MISC(PIPE_A));
        val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
        val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
        I915_WRITE(FDI_RX_CTL(PIPE_A), val);
  }
  
 -bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
 -                               struct intel_crtc *intel_crtc)
 -{
 -      u32 temp;
 -
 -      if (intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
 -              temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
 -
 -              intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
 -
 -              if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
 -                      return true;
 -      }
 -
 -      return false;
 -}
 -
  void intel_ddi_get_config(struct intel_encoder *encoder,
                          struct intel_crtc_state *pipe_config)
  {
        struct intel_hdmi *intel_hdmi;
        u32 temp, flags = 0;
  
+       /* XXX: DSI transcoder paranoia */
+       if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+               return;
        temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
        if (temp & TRANS_DDI_PHSYNC)
                flags |= DRM_MODE_FLAG_PHSYNC;
                break;
        }
  
 -      pipe_config->has_audio =
 -              intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
 +      if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
 +              temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
 +              if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
 +                      pipe_config->has_audio = true;
 +      }
  
-       if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
-           pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
+       if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
+           pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
                /*
                 * This is a big fat ugly hack.
                 *
                 * load.
                 */
                DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-                             pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
-               dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
+                             pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
+               dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
        }
  
        intel_ddi_clock_get(encoder, pipe_config);
index 0104a06d01fd6617f54bedf68353935668eee45b,9cfbf2fe941ea044a68df1d18faa98e53dedbfbb..46f9be3ad5a20df846658558a430cdf80d6f56de
@@@ -36,6 -36,7 +36,7 @@@
  #include "intel_drv.h"
  #include <drm/i915_drm.h>
  #include "i915_drv.h"
+ #include "intel_dsi.h"
  #include "i915_trace.h"
  #include <drm/drm_atomic.h>
  #include <drm/drm_atomic_helper.h>
@@@ -96,12 -97,13 +97,13 @@@ static int intel_framebuffer_init(struc
                                  struct drm_i915_gem_object *obj);
  static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
  static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
+ static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc);
  static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
                                         struct intel_link_m_n *m_n,
                                         struct intel_link_m_n *m2_n2);
  static void ironlake_set_pipeconf(struct drm_crtc *crtc);
  static void haswell_set_pipeconf(struct drm_crtc *crtc);
- static void intel_set_pipe_csc(struct drm_crtc *crtc);
+ static void haswell_set_pipemisc(struct drm_crtc *crtc);
  static void vlv_prepare_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *pipe_config);
  static void chv_prepare_pll(struct intel_crtc *crtc,
@@@ -110,13 -112,11 +112,11 @@@ static void intel_begin_crtc_commit(str
  static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
        struct intel_crtc_state *crtc_state);
- static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
-                          int num_connectors);
  static void skylake_pfit_enable(struct intel_crtc *crtc);
  static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
  static void ironlake_pfit_enable(struct intel_crtc *crtc);
  static void intel_modeset_setup_hw_state(struct drm_device *dev);
- static void intel_pre_disable_primary(struct drm_crtc *crtc);
+ static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc);
  
  typedef struct {
        int     min, max;
@@@ -147,15 -147,12 +147,12 @@@ static int valleyview_get_vco(struct dr
        return vco_freq[hpll_freq] * 1000;
  }
  
static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
-                                 const char *name, u32 reg)
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
+                     const char *name, u32 reg, int ref_freq)
  {
        u32 val;
        int divider;
  
-       if (dev_priv->hpll_freq == 0)
-               dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
        mutex_lock(&dev_priv->sb_lock);
        val = vlv_cck_read(dev_priv, reg);
        mutex_unlock(&dev_priv->sb_lock);
             (divider << CCK_FREQUENCY_STATUS_SHIFT),
             "%s change in progress\n", name);
  
-       return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
+       return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
  }
  
- int
intel_pch_rawclk(struct drm_device *dev)
+ static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
                                const char *name, u32 reg)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       if (dev_priv->hpll_freq == 0)
+               dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
  
-       WARN_ON(!HAS_PCH_SPLIT(dev));
+       return vlv_get_cck_clock(dev_priv, name, reg,
+                                dev_priv->hpll_freq);
+ }
  
-       return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK;
+ static int
+ intel_pch_rawclk(struct drm_i915_private *dev_priv)
+ {
+       return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
  }
  
- /* hrawclock is 1/4 the FSB frequency */
- int intel_hrawclk(struct drm_device *dev)
+ static int
+ intel_vlv_hrawclk(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t clkcfg;
+       return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
+                                     CCK_DISPLAY_REF_CLOCK_CONTROL);
+ }
  
-       /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
-               return 200;
+ static int
+ intel_g4x_hrawclk(struct drm_i915_private *dev_priv)
+ {
+       uint32_t clkcfg;
  
+       /* hrawclock is 1/4 the FSB frequency */
        clkcfg = I915_READ(CLKCFG);
        switch (clkcfg & CLKCFG_FSB_MASK) {
        case CLKCFG_FSB_400:
-               return 100;
+               return 100000;
        case CLKCFG_FSB_533:
-               return 133;
+               return 133333;
        case CLKCFG_FSB_667:
-               return 166;
+               return 166667;
        case CLKCFG_FSB_800:
-               return 200;
+               return 200000;
        case CLKCFG_FSB_1067:
-               return 266;
+               return 266667;
        case CLKCFG_FSB_1333:
-               return 333;
+               return 333333;
        /* these two are just a guess; one of them might be right */
        case CLKCFG_FSB_1600:
        case CLKCFG_FSB_1600_ALT:
-               return 400;
+               return 400000;
        default:
-               return 133;
+               return 133333;
        }
  }
  
+ static void intel_update_rawclk(struct drm_i915_private *dev_priv)
+ {
+       if (HAS_PCH_SPLIT(dev_priv))
+               dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv);
+       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               dev_priv->rawclk_freq = intel_vlv_hrawclk(dev_priv);
+       else if (IS_G4X(dev_priv) || IS_PINEVIEW(dev_priv))
+               dev_priv->rawclk_freq = intel_g4x_hrawclk(dev_priv);
+       else
+               return; /* no rawclk on other platforms, or no need to know it */
+       DRM_DEBUG_DRIVER("rawclk rate: %d kHz\n", dev_priv->rawclk_freq);
+ }
  static void intel_update_czclk(struct drm_i915_private *dev_priv)
  {
        if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
  }
  
  static inline u32 /* units of 100MHz */
- intel_fdi_link_freq(struct drm_device *dev)
+ intel_fdi_link_freq(struct drm_i915_private *dev_priv,
+                   const struct intel_crtc_state *pipe_config)
  {
-       if (IS_GEN5(dev)) {
-               struct drm_i915_private *dev_priv = dev->dev_private;
-               return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2;
-       } else
-               return 27;
+       if (HAS_DDI(dev_priv))
+               return pipe_config->port_clock; /* SPLL */
+       else if (IS_GEN5(dev_priv))
+               return ((I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2) * 10000;
+       else
+               return 270000;
  }
  
  static const intel_limit_t intel_limits_i8xx_dac = {
@@@ -550,89 -572,6 +572,6 @@@ static bool intel_pipe_will_have_type(c
        return false;
  }
  
- static const intel_limit_t *
- intel_ironlake_limit(struct intel_crtc_state *crtc_state, int refclk)
- {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
-       const intel_limit_t *limit;
-       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
-               if (intel_is_dual_link_lvds(dev)) {
-                       if (refclk == 100000)
-                               limit = &intel_limits_ironlake_dual_lvds_100m;
-                       else
-                               limit = &intel_limits_ironlake_dual_lvds;
-               } else {
-                       if (refclk == 100000)
-                               limit = &intel_limits_ironlake_single_lvds_100m;
-                       else
-                               limit = &intel_limits_ironlake_single_lvds;
-               }
-       } else
-               limit = &intel_limits_ironlake_dac;
-       return limit;
- }
- static const intel_limit_t *
- intel_g4x_limit(struct intel_crtc_state *crtc_state)
- {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
-       const intel_limit_t *limit;
-       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
-               if (intel_is_dual_link_lvds(dev))
-                       limit = &intel_limits_g4x_dual_channel_lvds;
-               else
-                       limit = &intel_limits_g4x_single_channel_lvds;
-       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) ||
-                  intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
-               limit = &intel_limits_g4x_hdmi;
-       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
-               limit = &intel_limits_g4x_sdvo;
-       } else /* The option is for other outputs */
-               limit = &intel_limits_i9xx_sdvo;
-       return limit;
- }
- static const intel_limit_t *
- intel_limit(struct intel_crtc_state *crtc_state, int refclk)
- {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
-       const intel_limit_t *limit;
-       if (IS_BROXTON(dev))
-               limit = &intel_limits_bxt;
-       else if (HAS_PCH_SPLIT(dev))
-               limit = intel_ironlake_limit(crtc_state, refclk);
-       else if (IS_G4X(dev)) {
-               limit = intel_g4x_limit(crtc_state);
-       } else if (IS_PINEVIEW(dev)) {
-               if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
-                       limit = &intel_limits_pineview_lvds;
-               else
-                       limit = &intel_limits_pineview_sdvo;
-       } else if (IS_CHERRYVIEW(dev)) {
-               limit = &intel_limits_chv;
-       } else if (IS_VALLEYVIEW(dev)) {
-               limit = &intel_limits_vlv;
-       } else if (!IS_GEN2(dev)) {
-               if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
-                       limit = &intel_limits_i9xx_lvds;
-               else
-                       limit = &intel_limits_i9xx_sdvo;
-       } else {
-               if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
-                       limit = &intel_limits_i8xx_lvds;
-               else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO))
-                       limit = &intel_limits_i8xx_dvo;
-               else
-                       limit = &intel_limits_i8xx_dac;
-       }
-       return limit;
- }
  /*
   * Platform specific helpers to calculate the port PLL loopback- (clock.m),
   * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast
@@@ -763,6 -702,16 +702,16 @@@ i9xx_select_p2_div(const intel_limit_t 
        }
  }
  
+ /*
+  * Returns a set of divisors for the desired target clock with the given
+  * refclk, or FALSE.  The returned values represent the clock equation:
+  * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+  *
+  * Target and reference clocks are specified in kHz.
+  *
+  * If match_clock is provided, then best_clock P divider must match the P
+  * divider from @match_clock used for LVDS downclocking.
+  */
  static bool
  i9xx_find_best_dpll(const intel_limit_t *limit,
                    struct intel_crtc_state *crtc_state,
        return (err != target);
  }
  
+ /*
+  * Returns a set of divisors for the desired target clock with the given
+  * refclk, or FALSE.  The returned values represent the clock equation:
+  * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+  *
+  * Target and reference clocks are specified in kHz.
+  *
+  * If match_clock is provided, then best_clock P divider must match the P
+  * divider from @match_clock used for LVDS downclocking.
+  */
  static bool
  pnv_find_best_dpll(const intel_limit_t *limit,
                   struct intel_crtc_state *crtc_state,
        return (err != target);
  }
  
+ /*
+  * Returns a set of divisors for the desired target clock with the given
+  * refclk, or FALSE.  The returned values represent the clock equation:
+  * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+  *
+  * Target and reference clocks are specified in kHz.
+  *
+  * If match_clock is provided, then best_clock P divider must match the P
+  * divider from @match_clock used for LVDS downclocking.
+  */
  static bool
  g4x_find_best_dpll(const intel_limit_t *limit,
                   struct intel_crtc_state *crtc_state,
@@@ -943,6 -912,11 +912,11 @@@ static bool vlv_PLL_is_optimal(struct d
        return *error_ppm + 10 < best_error_ppm;
  }
  
+ /*
+  * Returns a set of divisors for the desired target clock with the given
+  * refclk, or FALSE.  The returned values represent the clock equation:
+  * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+  */
  static bool
  vlv_find_best_dpll(const intel_limit_t *limit,
                   struct intel_crtc_state *crtc_state,
        return found;
  }
  
+ /*
+  * Returns a set of divisors for the desired target clock with the given
+  * refclk, or FALSE.  The returned values represent the clock equation:
+  * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+  */
  static bool
  chv_find_best_dpll(const intel_limit_t *limit,
                   struct intel_crtc_state *crtc_state,
  bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
                        intel_clock_t *best_clock)
  {
-       int refclk = i9xx_get_refclk(crtc_state, 0);
+       int refclk = 100000;
+       const intel_limit_t *limit = &intel_limits_bxt;
  
-       return chv_find_best_dpll(intel_limit(crtc_state, refclk), crtc_state,
+       return chv_find_best_dpll(limit, crtc_state,
                                  target_clock, refclk, NULL, best_clock);
  }
  
@@@ -1165,7 -1145,7 +1145,7 @@@ void assert_pll(struct drm_i915_privat
  }
  
  /* XXX: the dsi pll is shared between MIPI DSI ports */
static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
+ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
  {
        u32 val;
        bool cur_state;
             "DSI PLL state assertion failure (expected %s, current %s)\n",
                        onoff(state), onoff(cur_state));
  }
- #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
- #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
- struct intel_shared_dpll *
- intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
- {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-       if (crtc->config->shared_dpll < 0)
-               return NULL;
-       return &dev_priv->shared_dplls[crtc->config->shared_dpll];
- }
- /* For ILK+ */
- void assert_shared_dpll(struct drm_i915_private *dev_priv,
-                       struct intel_shared_dpll *pll,
-                       bool state)
- {
-       bool cur_state;
-       struct intel_dpll_hw_state hw_state;
-       if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
-               return;
-       cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
-       I915_STATE_WARN(cur_state != state,
-            "%s assertion failure (expected %s, current %s)\n",
-                       pll->name, onoff(state), onoff(cur_state));
- }
  
  static void assert_fdi_tx(struct drm_i915_private *dev_priv,
                          enum pipe pipe, bool state)
        enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
                                                                      pipe);
  
-       if (HAS_DDI(dev_priv->dev)) {
+       if (HAS_DDI(dev_priv)) {
                /* DDI does not have a specific FDI_TX register */
                u32 val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
                cur_state = !!(val & TRANS_DDI_FUNC_ENABLE);
@@@ -1253,11 -1203,11 +1203,11 @@@ static void assert_fdi_tx_pll_enabled(s
        u32 val;
  
        /* ILK FDI PLL is always enabled */
-       if (INTEL_INFO(dev_priv->dev)->gen == 5)
+       if (INTEL_INFO(dev_priv)->gen == 5)
                return;
  
        /* On Haswell, DDI ports are responsible for the FDI PLL setup */
-       if (HAS_DDI(dev_priv->dev))
+       if (HAS_DDI(dev_priv))
                return;
  
        val = I915_READ(FDI_TX_CTL(pipe));
@@@ -1446,21 -1396,8 +1396,8 @@@ static void assert_vblank_disabled(stru
                drm_crtc_vblank_put(crtc);
  }
  
- static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
- {
-       u32 val;
-       bool enabled;
-       I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
-       val = I915_READ(PCH_DREF_CONTROL);
-       enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
-                           DREF_SUPERSPREAD_SOURCE_MASK));
-       I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
- }
- static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
-                                          enum pipe pipe)
+ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+                                   enum pipe pipe)
  {
        u32 val;
        bool enabled;
@@@ -1478,11 -1415,11 +1415,11 @@@ static bool dp_pipe_enabled(struct drm_
        if ((val & DP_PORT_EN) == 0)
                return false;
  
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       if (HAS_PCH_CPT(dev_priv)) {
                u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
                if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
                        return false;
-       } else if (IS_CHERRYVIEW(dev_priv->dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                if ((val & DP_PIPE_MASK_CHV) != DP_PIPE_SELECT_CHV(pipe))
                        return false;
        } else {
@@@ -1498,10 -1435,10 +1435,10 @@@ static bool hdmi_pipe_enabled(struct dr
        if ((val & SDVO_ENABLE) == 0)
                return false;
  
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       if (HAS_PCH_CPT(dev_priv)) {
                if ((val & SDVO_PIPE_SEL_MASK_CPT) != SDVO_PIPE_SEL_CPT(pipe))
                        return false;
-       } else if (IS_CHERRYVIEW(dev_priv->dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                if ((val & SDVO_PIPE_SEL_MASK_CHV) != SDVO_PIPE_SEL_CHV(pipe))
                        return false;
        } else {
@@@ -1517,7 -1454,7 +1454,7 @@@ static bool lvds_pipe_enabled(struct dr
        if ((val & LVDS_PORT_EN) == 0)
                return false;
  
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       if (HAS_PCH_CPT(dev_priv)) {
                if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
                        return false;
        } else {
@@@ -1532,7 -1469,7 +1469,7 @@@ static bool adpa_pipe_enabled(struct dr
  {
        if ((val & ADPA_DAC_ENABLE) == 0)
                return false;
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       if (HAS_PCH_CPT(dev_priv)) {
                if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
                        return false;
        } else {
@@@ -1551,7 -1488,7 +1488,7 @@@ static void assert_pch_dp_disabled(stru
             "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
             i915_mmio_reg_offset(reg), pipe_name(pipe));
  
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & DP_PORT_EN) == 0
             && (val & DP_PIPEB_SELECT),
             "IBX PCH dp port still using transcoder B\n");
  }
@@@ -1564,7 -1501,7 +1501,7 @@@ static void assert_pch_hdmi_disabled(st
             "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
             i915_mmio_reg_offset(reg), pipe_name(pipe));
  
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_ENABLE) == 0
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & SDVO_ENABLE) == 0
             && (val & SDVO_PIPE_B_SELECT),
             "IBX PCH hdmi port still using transcoder B\n");
  }
@@@ -1593,53 -1530,47 +1530,47 @@@ static void assert_pch_ports_disabled(s
        assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
  }
  
+ static void _vlv_enable_pll(struct intel_crtc *crtc,
+                           const struct intel_crtc_state *pipe_config)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+       I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll);
+       POSTING_READ(DPLL(pipe));
+       udelay(150);
+       if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
+               DRM_ERROR("DPLL %d failed to lock\n", pipe);
+ }
  static void vlv_enable_pll(struct intel_crtc *crtc,
                           const struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       i915_reg_t reg = DPLL(crtc->pipe);
-       u32 dpll = pipe_config->dpll_hw_state.dpll;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
  
-       assert_pipe_disabled(dev_priv, crtc->pipe);
+       assert_pipe_disabled(dev_priv, pipe);
  
        /* PLL is protected by panel, make sure we can write it */
-       if (IS_MOBILE(dev_priv->dev))
-               assert_panel_unlocked(dev_priv, crtc->pipe);
-       I915_WRITE(reg, dpll);
-       POSTING_READ(reg);
-       udelay(150);
-       if (wait_for(((I915_READ(reg) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
-               DRM_ERROR("DPLL %d failed to lock\n", crtc->pipe);
+       assert_panel_unlocked(dev_priv, pipe);
  
-       I915_WRITE(DPLL_MD(crtc->pipe), pipe_config->dpll_hw_state.dpll_md);
-       POSTING_READ(DPLL_MD(crtc->pipe));
+       if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+               _vlv_enable_pll(crtc, pipe_config);
  
-       /* We do this three times for luck */
-       I915_WRITE(reg, dpll);
-       POSTING_READ(reg);
-       udelay(150); /* wait for warmup */
-       I915_WRITE(reg, dpll);
-       POSTING_READ(reg);
-       udelay(150); /* wait for warmup */
-       I915_WRITE(reg, dpll);
-       POSTING_READ(reg);
-       udelay(150); /* wait for warmup */
+       I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
+       POSTING_READ(DPLL_MD(pipe));
  }
  
- static void chv_enable_pll(struct intel_crtc *crtc,
-                          const struct intel_crtc_state *pipe_config)
+ static void _chv_enable_pll(struct intel_crtc *crtc,
+                           const struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipe = crtc->pipe;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
        enum dpio_channel port = vlv_pipe_to_channel(pipe);
        u32 tmp;
  
-       assert_pipe_disabled(dev_priv, crtc->pipe);
        mutex_lock(&dev_priv->sb_lock);
  
        /* Enable back the 10bit clock to display controller */
        /* Check PLL is locked */
        if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
                DRM_ERROR("PLL %d failed to lock\n", pipe);
+ }
  
-       /* not sure when this should be written */
-       I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
-       POSTING_READ(DPLL_MD(pipe));
+ static void chv_enable_pll(struct intel_crtc *crtc,
+                          const struct intel_crtc_state *pipe_config)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+       assert_pipe_disabled(dev_priv, pipe);
+       /* PLL is protected by panel, make sure we can write it */
+       assert_panel_unlocked(dev_priv, pipe);
+       if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+               _chv_enable_pll(crtc, pipe_config);
+       if (pipe != PIPE_A) {
+               /*
+                * WaPixelRepeatModeFixForC0:chv
+                *
+                * DPLLCMD is AWOL. Use chicken bits to propagate
+                * the value from DPLLBMD to either pipe B or C.
+                */
+               I915_WRITE(CBR4_VLV, pipe == PIPE_B ? CBR_DPLLBMD_PIPE_B : CBR_DPLLBMD_PIPE_C);
+               I915_WRITE(DPLL_MD(PIPE_B), pipe_config->dpll_hw_state.dpll_md);
+               I915_WRITE(CBR4_VLV, 0);
+               dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
+               /*
+                * DPLLB VGA mode also seems to cause problems.
+                * We should always have it disabled.
+                */
+               WARN_ON((I915_READ(DPLL(PIPE_B)) & DPLL_VGA_MODE_DIS) == 0);
+       } else {
+               I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
+               POSTING_READ(DPLL_MD(pipe));
+       }
  }
  
  static int intel_num_dvo_pipes(struct drm_device *dev)
@@@ -1687,9 -1651,6 +1651,6 @@@ static void i9xx_enable_pll(struct inte
  
        assert_pipe_disabled(dev_priv, crtc->pipe);
  
-       /* No really, not for ILK+ */
-       BUG_ON(INTEL_INFO(dev)->gen >= 5);
        /* PLL is protected by panel, make sure we can write it */
        if (IS_MOBILE(dev) && !IS_I830(dev))
                assert_panel_unlocked(dev_priv, crtc->pipe);
@@@ -1788,16 -1749,13 +1749,13 @@@ static void vlv_disable_pll(struct drm_
        /* Make sure the pipe isn't still relying on us */
        assert_pipe_disabled(dev_priv, pipe);
  
-       /*
-        * Leave integrated clock source and reference clock enabled for pipe B.
-        * The latter is needed for VGA hotplug / manual detection.
-        */
-       val = DPLL_VGA_MODE_DIS;
-       if (pipe == PIPE_B)
-               val = DPLL_INTEGRATED_CRI_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV;
+       val = DPLL_INTEGRATED_REF_CLK_VLV |
+               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+       if (pipe != PIPE_A)
+               val |= DPLL_INTEGRATED_CRI_CLK_VLV;
        I915_WRITE(DPLL(pipe), val);
        POSTING_READ(DPLL(pipe));
  }
  
  static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
        /* Make sure the pipe isn't still relying on us */
        assert_pipe_disabled(dev_priv, pipe);
  
-       /* Set PLL en = 0 */
        val = DPLL_SSC_REF_CLK_CHV |
                DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
        if (pipe != PIPE_A)
                val |= DPLL_INTEGRATED_CRI_CLK_VLV;
        I915_WRITE(DPLL(pipe), val);
        POSTING_READ(DPLL(pipe));
  
@@@ -1856,149 -1814,51 +1814,51 @@@ void vlv_wait_port_ready(struct drm_i91
                     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
  }
  
- static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
+ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
+                                          enum pipe pipe)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+       struct drm_device *dev = dev_priv->dev;
+       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       i915_reg_t reg;
+       uint32_t val, pipeconf_val;
  
-       if (WARN_ON(pll == NULL))
-               return;
+       /* Make sure PCH DPLL is enabled */
+       assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll);
  
-       WARN_ON(!pll->config.crtc_mask);
-       if (pll->active == 0) {
-               DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
-               WARN_ON(pll->on);
-               assert_shared_dpll_disabled(dev_priv, pll);
+       /* FDI must be feeding us bits for PCH ports */
+       assert_fdi_tx_enabled(dev_priv, pipe);
+       assert_fdi_rx_enabled(dev_priv, pipe);
  
-               pll->mode_set(dev_priv, pll);
+       if (HAS_PCH_CPT(dev)) {
+               /* Workaround: Set the timing override bit before enabling the
+                * pch transcoder. */
+               reg = TRANS_CHICKEN2(pipe);
+               val = I915_READ(reg);
+               val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
+               I915_WRITE(reg, val);
        }
- }
  
- /**
-  * intel_enable_shared_dpll - enable PCH PLL
-  * @dev_priv: i915 private structure
-  * @pipe: pipe PLL to enable
-  *
-  * The PCH PLL needs to be enabled before the PCH transcoder, since it
-  * drives the transcoder clock.
-  */
- static void intel_enable_shared_dpll(struct intel_crtc *crtc)
- {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+       reg = PCH_TRANSCONF(pipe);
+       val = I915_READ(reg);
+       pipeconf_val = I915_READ(PIPECONF(pipe));
  
-       if (WARN_ON(pll == NULL))
-               return;
-       if (WARN_ON(pll->config.crtc_mask == 0))
-               return;
-       DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
-                     pll->name, pll->active, pll->on,
-                     crtc->base.base.id);
-       if (pll->active++) {
-               WARN_ON(!pll->on);
-               assert_shared_dpll_enabled(dev_priv, pll);
-               return;
-       }
-       WARN_ON(pll->on);
-       intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
-       DRM_DEBUG_KMS("enabling %s\n", pll->name);
-       pll->enable(dev_priv, pll);
-       pll->on = true;
- }
- static void intel_disable_shared_dpll(struct intel_crtc *crtc)
- {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-       /* PCH only available on ILK+ */
-       if (INTEL_INFO(dev)->gen < 5)
-               return;
-       if (pll == NULL)
-               return;
-       if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base)))))
-               return;
-       DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
-                     pll->name, pll->active, pll->on,
-                     crtc->base.base.id);
-       if (WARN_ON(pll->active == 0)) {
-               assert_shared_dpll_disabled(dev_priv, pll);
-               return;
-       }
-       assert_shared_dpll_enabled(dev_priv, pll);
-       WARN_ON(!pll->on);
-       if (--pll->active)
-               return;
-       DRM_DEBUG_KMS("disabling %s\n", pll->name);
-       pll->disable(dev_priv, pll);
-       pll->on = false;
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
- }
- static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
-                                          enum pipe pipe)
- {
-       struct drm_device *dev = dev_priv->dev;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       i915_reg_t reg;
-       uint32_t val, pipeconf_val;
-       /* PCH only available on ILK+ */
-       BUG_ON(!HAS_PCH_SPLIT(dev));
-       /* Make sure PCH DPLL is enabled */
-       assert_shared_dpll_enabled(dev_priv,
-                                  intel_crtc_to_shared_dpll(intel_crtc));
-       /* FDI must be feeding us bits for PCH ports */
-       assert_fdi_tx_enabled(dev_priv, pipe);
-       assert_fdi_rx_enabled(dev_priv, pipe);
-       if (HAS_PCH_CPT(dev)) {
-               /* Workaround: Set the timing override bit before enabling the
-                * pch transcoder. */
-               reg = TRANS_CHICKEN2(pipe);
-               val = I915_READ(reg);
-               val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
-               I915_WRITE(reg, val);
-       }
-       reg = PCH_TRANSCONF(pipe);
-       val = I915_READ(reg);
-       pipeconf_val = I915_READ(PIPECONF(pipe));
-       if (HAS_PCH_IBX(dev_priv->dev)) {
-               /*
-                * Make the BPC in transcoder be consistent with
-                * that in pipeconf reg. For HDMI we must use 8bpc
-                * here for both 8bpc and 12bpc.
-                */
-               val &= ~PIPECONF_BPC_MASK;
-               if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_HDMI))
-                       val |= PIPECONF_8BPC;
-               else
-                       val |= pipeconf_val & PIPECONF_BPC_MASK;
-       }
+       if (HAS_PCH_IBX(dev_priv)) {
+               /*
+                * Make the BPC in transcoder be consistent with
+                * that in pipeconf reg. For HDMI we must use 8bpc
+                * here for both 8bpc and 12bpc.
+                */
+               val &= ~PIPECONF_BPC_MASK;
+               if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_HDMI))
+                       val |= PIPECONF_8BPC;
+               else
+                       val |= pipeconf_val & PIPECONF_BPC_MASK;
+       }
  
        val &= ~TRANS_INTERLACE_MASK;
        if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK)
-               if (HAS_PCH_IBX(dev_priv->dev) &&
+               if (HAS_PCH_IBX(dev_priv) &&
                    intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
                        val |= TRANS_LEGACY_INTERLACED_ILK;
                else
@@@ -2016,9 -1876,6 +1876,6 @@@ static void lpt_enable_pch_transcoder(s
  {
        u32 val, pipeconf_val;
  
-       /* PCH only available on ILK+ */
-       BUG_ON(!HAS_PCH_SPLIT(dev_priv->dev));
        /* FDI must be feeding us bits for PCH ports */
        assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
        assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
@@@ -2113,7 -1970,7 +1970,7 @@@ static void intel_enable_pipe(struct in
        assert_cursor_disabled(dev_priv, pipe);
        assert_sprites_disabled(dev_priv, pipe);
  
-       if (HAS_PCH_LPT(dev_priv->dev))
+       if (HAS_PCH_LPT(dev_priv))
                pch_transcoder = TRANSCODER_A;
        else
                pch_transcoder = pipe;
         * a plane.  On ILK+ the pipe PLLs are integrated, so we don't
         * need the check.
         */
-       if (HAS_GMCH_DISPLAY(dev_priv->dev))
+       if (HAS_GMCH_DISPLAY(dev_priv))
                if (crtc->config->has_dsi_encoder)
                        assert_dsi_pll_enabled(dev_priv);
                else
@@@ -2225,8 -2082,8 +2082,8 @@@ static unsigned int intel_tile_size(con
        return IS_GEN2(dev_priv) ? 2048 : 4096;
  }
  
- static unsigned int intel_tile_width(const struct drm_i915_private *dev_priv,
-                                    uint64_t fb_modifier, unsigned int cpp)
+ static unsigned int intel_tile_width_bytes(const struct drm_i915_private *dev_priv,
+                                          uint64_t fb_modifier, unsigned int cpp)
  {
        switch (fb_modifier) {
        case DRM_FORMAT_MOD_NONE:
@@@ -2269,7 -2126,21 +2126,21 @@@ unsigned int intel_tile_height(const st
                return 1;
        else
                return intel_tile_size(dev_priv) /
-                       intel_tile_width(dev_priv, fb_modifier, cpp);
+                       intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
+ }
+ /* Return the tile dimensions in pixel units */
+ static void intel_tile_dims(const struct drm_i915_private *dev_priv,
+                           unsigned int *tile_width,
+                           unsigned int *tile_height,
+                           uint64_t fb_modifier,
+                           unsigned int cpp)
+ {
+       unsigned int tile_width_bytes =
+               intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
+       *tile_width = tile_width_bytes / cpp;
+       *tile_height = intel_tile_size(dev_priv) / tile_width_bytes;
  }
  
  unsigned int
@@@ -2282,48 -2153,54 +2153,54 @@@ intel_fb_align_height(struct drm_devic
        return ALIGN(height, tile_height);
  }
  
- static void
- intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb,
-                       const struct drm_plane_state *plane_state)
+ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)
  {
-       struct drm_i915_private *dev_priv = to_i915(fb->dev);
-       struct intel_rotation_info *info = &view->params.rotated;
-       unsigned int tile_size, tile_width, tile_height, cpp;
-       *view = i915_ggtt_view_normal;
+       unsigned int size = 0;
+       int i;
  
-       if (!plane_state)
-               return;
+       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
+               size += rot_info->plane[i].width * rot_info->plane[i].height;
  
-       if (!intel_rotation_90_or_270(plane_state->rotation))
-               return;
+       return size;
+ }
  
-       *view = i915_ggtt_view_rotated;
+ static void
+ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
+                       const struct drm_framebuffer *fb,
+                       unsigned int rotation)
+ {
+       if (intel_rotation_90_or_270(rotation)) {
+               *view = i915_ggtt_view_rotated;
+               view->params.rotated = to_intel_framebuffer(fb)->rot_info;
+       } else {
+               *view = i915_ggtt_view_normal;
+       }
+ }
  
-       info->height = fb->height;
-       info->pixel_format = fb->pixel_format;
-       info->pitch = fb->pitches[0];
-       info->uv_offset = fb->offsets[1];
-       info->fb_modifier = fb->modifier[0];
+ static void
+ intel_fill_fb_info(struct drm_i915_private *dev_priv,
+                  struct drm_framebuffer *fb)
+ {
+       struct intel_rotation_info *info = &to_intel_framebuffer(fb)->rot_info;
+       unsigned int tile_size, tile_width, tile_height, cpp;
  
        tile_size = intel_tile_size(dev_priv);
  
        cpp = drm_format_plane_cpp(fb->pixel_format, 0);
-       tile_width = intel_tile_width(dev_priv, fb->modifier[0], cpp);
-       tile_height = tile_size / tile_width;
+       intel_tile_dims(dev_priv, &tile_width, &tile_height,
+                       fb->modifier[0], cpp);
  
-       info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width);
-       info->height_pages = DIV_ROUND_UP(fb->height, tile_height);
-       info->size = info->width_pages * info->height_pages * tile_size;
+       info->plane[0].width = DIV_ROUND_UP(fb->pitches[0], tile_width * cpp);
+       info->plane[0].height = DIV_ROUND_UP(fb->height, tile_height);
  
        if (info->pixel_format == DRM_FORMAT_NV12) {
                cpp = drm_format_plane_cpp(fb->pixel_format, 1);
-               tile_width = intel_tile_width(dev_priv, fb->modifier[1], cpp);
-               tile_height = tile_size / tile_width;
+               intel_tile_dims(dev_priv, &tile_width, &tile_height,
+                               fb->modifier[1], cpp);
  
-               info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width);
-               info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height);
-               info->size_uv = info->width_pages_uv * info->height_pages_uv * tile_size;
+               info->uv_offset = fb->offsets[1];
+               info->plane[1].width = DIV_ROUND_UP(fb->pitches[1], tile_width * cpp);
+               info->plane[1].height = DIV_ROUND_UP(fb->height / 2, tile_height);
        }
  }
  
@@@ -2360,9 -2237,8 +2237,8 @@@ static unsigned int intel_surf_alignmen
  }
  
  int
- intel_pin_and_fence_fb_obj(struct drm_plane *plane,
-                          struct drm_framebuffer *fb,
-                          const struct drm_plane_state *plane_state)
+ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+                          unsigned int rotation)
  {
        struct drm_device *dev = fb->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
  
-       intel_fill_fb_ggtt_view(&view, fb, plane_state);
+       intel_fill_fb_ggtt_view(&view, fb, rotation);
  
        /* Note that the w/a also requires 64 PTE of padding following the
         * bo. We currently fill all unused PTE with the shadow page and so
@@@ -2433,15 -2309,14 +2309,14 @@@ err_pm
        return ret;
  }
  
- static void intel_unpin_fb_obj(struct drm_framebuffer *fb,
-                              const struct drm_plane_state *plane_state)
+ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
  {
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        struct i915_ggtt_view view;
  
        WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
  
-       intel_fill_fb_ggtt_view(&view, fb, plane_state);
+       intel_fill_fb_ggtt_view(&view, fb, rotation);
  
        if (view.type == I915_GGTT_VIEW_NORMAL)
                i915_gem_object_unpin_fence(obj);
        i915_gem_object_unpin_from_display_plane(obj, &view);
  }
  
- /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
-  * is assumed to be a power-of-two. */
- u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv,
-                             int *x, int *y,
-                             uint64_t fb_modifier,
-                             unsigned int cpp,
-                             unsigned int pitch)
+ /*
+  * Adjust the tile offset by moving the difference into
+  * the x/y offsets.
+  *
+  * Input tile dimensions and pitch must already be
+  * rotated to match x and y, and in pixel units.
+  */
+ static u32 intel_adjust_tile_offset(int *x, int *y,
+                                   unsigned int tile_width,
+                                   unsigned int tile_height,
+                                   unsigned int tile_size,
+                                   unsigned int pitch_tiles,
+                                   u32 old_offset,
+                                   u32 new_offset)
+ {
+       unsigned int tiles;
+       WARN_ON(old_offset & (tile_size - 1));
+       WARN_ON(new_offset & (tile_size - 1));
+       WARN_ON(new_offset > old_offset);
+       tiles = (old_offset - new_offset) / tile_size;
+       *y += tiles / pitch_tiles * tile_height;
+       *x += tiles % pitch_tiles * tile_width;
+       return new_offset;
+ }
+ /*
+  * Computes the linear offset to the base tile and adjusts
+  * x, y. bytes per pixel is assumed to be a power-of-two.
+  *
+  * In the 90/270 rotated case, x and y are assumed
+  * to be already rotated to match the rotated GTT view, and
+  * pitch is the tile_height aligned framebuffer height.
+  */
+ u32 intel_compute_tile_offset(int *x, int *y,
+                             const struct drm_framebuffer *fb, int plane,
+                             unsigned int pitch,
+                             unsigned int rotation)
  {
+       const struct drm_i915_private *dev_priv = to_i915(fb->dev);
+       uint64_t fb_modifier = fb->modifier[plane];
+       unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       u32 offset, offset_aligned, alignment;
+       alignment = intel_surf_alignment(dev_priv, fb_modifier);
+       if (alignment)
+               alignment--;
        if (fb_modifier != DRM_FORMAT_MOD_NONE) {
                unsigned int tile_size, tile_width, tile_height;
-               unsigned int tile_rows, tiles;
+               unsigned int tile_rows, tiles, pitch_tiles;
  
                tile_size = intel_tile_size(dev_priv);
-               tile_width = intel_tile_width(dev_priv, fb_modifier, cpp);
-               tile_height = tile_size / tile_width;
+               intel_tile_dims(dev_priv, &tile_width, &tile_height,
+                               fb_modifier, cpp);
+               if (intel_rotation_90_or_270(rotation)) {
+                       pitch_tiles = pitch / tile_height;
+                       swap(tile_width, tile_height);
+               } else {
+                       pitch_tiles = pitch / (tile_width * cpp);
+               }
  
                tile_rows = *y / tile_height;
                *y %= tile_height;
  
-               tiles = *x / (tile_width/cpp);
-               *x %= tile_width/cpp;
+               tiles = *x / tile_width;
+               *x %= tile_width;
  
-               return tile_rows * pitch * tile_height + tiles * tile_size;
-       } else {
-               unsigned int alignment = intel_linear_alignment(dev_priv) - 1;
-               unsigned int offset;
+               offset = (tile_rows * pitch_tiles + tiles) * tile_size;
+               offset_aligned = offset & ~alignment;
  
+               intel_adjust_tile_offset(x, y, tile_width, tile_height,
+                                        tile_size, pitch_tiles,
+                                        offset, offset_aligned);
+       } else {
                offset = *y * pitch + *x * cpp;
+               offset_aligned = offset & ~alignment;
                *y = (offset & alignment) / pitch;
                *x = ((offset & alignment) - *y * pitch) / cpp;
-               return offset & ~alignment;
        }
+       return offset_aligned;
  }
  
  static int i9xx_format_to_fourcc(int format)
@@@ -2536,6 -2466,7 +2466,7 @@@ intel_alloc_initial_plane_obj(struct in
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        struct drm_i915_gem_object *obj = NULL;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
        struct drm_framebuffer *fb = &plane_config->fb->base;
        /* If the FB is too big, just don't use it since fbdev is not very
         * important and we should probably use that space with FBC or other
         * features. */
-       if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size)
+       if (size_aligned * 2 > ggtt->stolen_usable_size)
                return false;
  
        mutex_lock(&dev->struct_mutex);
@@@ -2667,7 -2598,7 +2598,7 @@@ intel_find_initial_plane_obj(struct int
         */
        to_intel_plane_state(plane_state)->visible = false;
        crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
-       intel_pre_disable_primary(&intel_crtc->base);
+       intel_pre_disable_primary_noatomic(&intel_crtc->base);
        intel_plane->disable_plane(primary, &intel_crtc->base);
  
        return;
@@@ -2716,6 -2647,7 +2647,7 @@@ static void i9xx_update_primary_plane(s
        u32 linear_offset;
        u32 dspcntr;
        i915_reg_t reg = DSPCNTR(plane);
+       unsigned int rotation = plane_state->base.rotation;
        int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        int x = plane_state->src.x1 >> 16;
        int y = plane_state->src.y1 >> 16;
  
        if (INTEL_INFO(dev)->gen >= 4) {
                intel_crtc->dspaddr_offset =
-                       intel_compute_tile_offset(dev_priv, &x, &y,
-                                                 fb->modifier[0], cpp,
-                                                 fb->pitches[0]);
+                       intel_compute_tile_offset(&x, &y, fb, 0,
+                                                 fb->pitches[0], rotation);
                linear_offset -= intel_crtc->dspaddr_offset;
        } else {
                intel_crtc->dspaddr_offset = linear_offset;
        }
  
-       if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == BIT(DRM_ROTATE_180)) {
                dspcntr |= DISPPLANE_ROTATE_180;
  
                x += (crtc_state->pipe_src_w - 1);
@@@ -2846,6 -2777,7 +2777,7 @@@ static void ironlake_update_primary_pla
        u32 linear_offset;
        u32 dspcntr;
        i915_reg_t reg = DSPCNTR(plane);
+       unsigned int rotation = plane_state->base.rotation;
        int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
        int x = plane_state->src.x1 >> 16;
        int y = plane_state->src.y1 >> 16;
  
        linear_offset = y * fb->pitches[0] + x * cpp;
        intel_crtc->dspaddr_offset =
-               intel_compute_tile_offset(dev_priv, &x, &y,
-                                         fb->modifier[0], cpp,
-                                         fb->pitches[0]);
+               intel_compute_tile_offset(&x, &y, fb, 0,
+                                         fb->pitches[0], rotation);
        linear_offset -= intel_crtc->dspaddr_offset;
-       if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) {
+       if (rotation == BIT(DRM_ROTATE_180)) {
                dspcntr |= DISPPLANE_ROTATE_180;
  
                if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
@@@ -2931,7 -2862,7 +2862,7 @@@ u32 intel_fb_stride_alignment(const str
        } else {
                int cpp = drm_format_plane_cpp(pixel_format, 0);
  
-               return intel_tile_width(dev_priv, fb_modifier, cpp);
+               return intel_tile_width_bytes(dev_priv, fb_modifier, cpp);
        }
  }
  
@@@ -2944,7 -2875,7 +2875,7 @@@ u32 intel_plane_obj_offset(struct intel
        u64 offset;
  
        intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb,
-                               intel_plane->base.state);
+                               intel_plane->base.state->rotation);
  
        vma = i915_gem_obj_to_ggtt_view(obj, &view);
        if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
@@@ -3284,12 -3215,12 +3215,12 @@@ void intel_finish_reset(struct drm_devi
  static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
  {
        struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       unsigned reset_counter;
        bool pending;
  
-       if (i915_reset_in_progress(&dev_priv->gpu_error) ||
-           intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
+       reset_counter = i915_reset_counter(&to_i915(dev)->gpu_error);
+       if (intel_crtc->reset_counter != reset_counter)
                return false;
  
        spin_lock_irq(&dev->event_lock);
@@@ -3314,9 -3245,6 +3245,6 @@@ static void intel_update_pipe_config(st
                      old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
                      pipe_config->pipe_src_w, pipe_config->pipe_src_h);
  
-       if (HAS_DDI(dev))
-               intel_set_pipe_csc(&crtc->base);
        /*
         * Update pipe size and adjust fitter if needed: the reason for this is
         * that in compute_mode_changes we check the native mode (not the pfit
@@@ -3894,9 -3822,7 +3822,7 @@@ static void page_flip_completed(struct 
        intel_crtc->unpin_work = NULL;
  
        if (work->event)
-               drm_send_vblank_event(intel_crtc->base.dev,
-                                     intel_crtc->pipe,
-                                     work->event);
+               drm_crtc_send_vblank_event(&intel_crtc->base, work->event);
  
        drm_crtc_vblank_put(&intel_crtc->base);
  
@@@ -3955,37 -3881,35 +3881,35 @@@ static void lpt_disable_iclkip(struct d
  /* Program iCLKIP clock to the desired frequency */
  static void lpt_program_iclkip(struct drm_crtc *crtc)
  {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
        u32 divsel, phaseinc, auxdiv, phasedir = 0;
        u32 temp;
  
        lpt_disable_iclkip(dev_priv);
  
-       /* 20MHz is a corner case which is out of range for the 7-bit divisor */
-       if (clock == 20000) {
-               auxdiv = 1;
-               divsel = 0x41;
-               phaseinc = 0x20;
-       } else {
-               /* The iCLK virtual clock root frequency is in MHz,
-                * but the adjusted_mode->crtc_clock in in KHz. To get the
-                * divisors, it is necessary to divide one by another, so we
-                * convert the virtual clock precision to KHz here for higher
-                * precision.
-                */
+       /* The iCLK virtual clock root frequency is in MHz,
+        * but the adjusted_mode->crtc_clock in in KHz. To get the
+        * divisors, it is necessary to divide one by another, so we
+        * convert the virtual clock precision to KHz here for higher
+        * precision.
+        */
+       for (auxdiv = 0; auxdiv < 2; auxdiv++) {
                u32 iclk_virtual_root_freq = 172800 * 1000;
                u32 iclk_pi_range = 64;
-               u32 desired_divisor, msb_divisor_value, pi_value;
+               u32 desired_divisor;
  
-               desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq, clock);
-               msb_divisor_value = desired_divisor / iclk_pi_range;
-               pi_value = desired_divisor % iclk_pi_range;
+               desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
+                                                   clock << auxdiv);
+               divsel = (desired_divisor / iclk_pi_range) - 2;
+               phaseinc = desired_divisor % iclk_pi_range;
  
-               auxdiv = 0;
-               divsel = msb_divisor_value - 2;
-               phaseinc = pi_value;
+               /*
+                * Near 20MHz is a corner case which is
+                * out of range for the 7-bit divisor
+                */
+               if (divsel <= 0x7f)
+                       break;
        }
  
        /* This should not happen with any sane values */
        I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE);
  }
  
+ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
+ {
+       u32 divsel, phaseinc, auxdiv;
+       u32 iclk_virtual_root_freq = 172800 * 1000;
+       u32 iclk_pi_range = 64;
+       u32 desired_divisor;
+       u32 temp;
+       if ((I915_READ(PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0)
+               return 0;
+       mutex_lock(&dev_priv->sb_lock);
+       temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
+       if (temp & SBI_SSCCTL_DISABLE) {
+               mutex_unlock(&dev_priv->sb_lock);
+               return 0;
+       }
+       temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
+       divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >>
+               SBI_SSCDIVINTPHASE_DIVSEL_SHIFT;
+       phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >>
+               SBI_SSCDIVINTPHASE_INCVAL_SHIFT;
+       temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
+       auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >>
+               SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT;
+       mutex_unlock(&dev_priv->sb_lock);
+       desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc;
+       return DIV_ROUND_CLOSEST(iclk_virtual_root_freq,
+                                desired_divisor << auxdiv);
+ }
  static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
                                                enum pipe pch_transcoder)
  {
@@@ -4142,12 -4103,6 +4103,6 @@@ static void ironlake_pch_enable(struct 
        I915_WRITE(FDI_RX_TUSIZE1(pipe),
                   I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
  
-       /*
-        * Sometimes spurious CPU pipe underruns happen during FDI
-        * training, at least with VGA+HDMI cloning. Suppress them.
-        */
-       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
        /* For PCH output, training FDI link */
        dev_priv->display.fdi_link_train(crtc);
  
                temp = I915_READ(PCH_DPLL_SEL);
                temp |= TRANS_DPLL_ENABLE(pipe);
                sel = TRANS_DPLLB_SEL(pipe);
-               if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
+               if (intel_crtc->config->shared_dpll ==
+                   intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
                        temp |= sel;
                else
                        temp &= ~sel;
  
        intel_fdi_normal_train(crtc);
  
-       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
                const struct drm_display_mode *adjusted_mode =
@@@ -4238,113 -4192,6 +4192,6 @@@ static void lpt_pch_enable(struct drm_c
        lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
  }
  
- struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-                                               struct intel_crtc_state *crtc_state)
- {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-       struct intel_shared_dpll *pll;
-       struct intel_shared_dpll_config *shared_dpll;
-       enum intel_dpll_id i;
-       int max = dev_priv->num_shared_dpll;
-       shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
-       if (HAS_PCH_IBX(dev_priv->dev)) {
-               /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
-               i = (enum intel_dpll_id) crtc->pipe;
-               pll = &dev_priv->shared_dplls[i];
-               DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-                             crtc->base.base.id, pll->name);
-               WARN_ON(shared_dpll[i].crtc_mask);
-               goto found;
-       }
-       if (IS_BROXTON(dev_priv->dev)) {
-               /* PLL is attached to port in bxt */
-               struct intel_encoder *encoder;
-               struct intel_digital_port *intel_dig_port;
-               encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
-               if (WARN_ON(!encoder))
-                       return NULL;
-               intel_dig_port = enc_to_dig_port(&encoder->base);
-               /* 1:1 mapping between ports and PLLs */
-               i = (enum intel_dpll_id)intel_dig_port->port;
-               pll = &dev_priv->shared_dplls[i];
-               DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-                       crtc->base.base.id, pll->name);
-               WARN_ON(shared_dpll[i].crtc_mask);
-               goto found;
-       } else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
-               /* Do not consider SPLL */
-               max = 2;
-       for (i = 0; i < max; i++) {
-               pll = &dev_priv->shared_dplls[i];
-               /* Only want to check enabled timings first */
-               if (shared_dpll[i].crtc_mask == 0)
-                       continue;
-               if (memcmp(&crtc_state->dpll_hw_state,
-                          &shared_dpll[i].hw_state,
-                          sizeof(crtc_state->dpll_hw_state)) == 0) {
-                       DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
-                                     crtc->base.base.id, pll->name,
-                                     shared_dpll[i].crtc_mask,
-                                     pll->active);
-                       goto found;
-               }
-       }
-       /* Ok no matching timings, maybe there's a free one? */
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               pll = &dev_priv->shared_dplls[i];
-               if (shared_dpll[i].crtc_mask == 0) {
-                       DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
-                                     crtc->base.base.id, pll->name);
-                       goto found;
-               }
-       }
-       return NULL;
- found:
-       if (shared_dpll[i].crtc_mask == 0)
-               shared_dpll[i].hw_state =
-                       crtc_state->dpll_hw_state;
-       crtc_state->shared_dpll = i;
-       DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
-                        pipe_name(crtc->pipe));
-       shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
-       return pll;
- }
- static void intel_shared_dpll_commit(struct drm_atomic_state *state)
- {
-       struct drm_i915_private *dev_priv = to_i915(state->dev);
-       struct intel_shared_dpll_config *shared_dpll;
-       struct intel_shared_dpll *pll;
-       enum intel_dpll_id i;
-       if (!to_intel_atomic_state(state)->dpll_set)
-               return;
-       shared_dpll = to_intel_atomic_state(state)->shared_dpll;
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               pll = &dev_priv->shared_dplls[i];
-               pll->config = shared_dpll[i];
-       }
- }
  static void cpt_verify_modeset(struct drm_device *dev, int pipe)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@@ -4576,8 -4423,11 +4423,11 @@@ void hsw_enable_ips(struct intel_crtc *
        if (!crtc->config->ips_enabled)
                return;
  
-       /* We can only enable IPS after we enable a plane and wait for a vblank */
-       intel_wait_for_vblank(dev, crtc->pipe);
+       /*
+        * We can only enable IPS after we enable a plane and wait for a vblank
+        * This function is called from post_plane_update, which is run after
+        * a vblank wait.
+        */
  
        assert_plane_enabled(dev_priv, crtc->plane);
        if (IS_BROADWELL(dev)) {
@@@ -4626,55 -4476,6 +4476,6 @@@ void hsw_disable_ips(struct intel_crtc 
        intel_wait_for_vblank(dev, crtc->pipe);
  }
  
- /** Loads the palette/gamma unit for the CRTC with the prepared values */
- static void intel_crtc_load_lut(struct drm_crtc *crtc)
- {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum pipe pipe = intel_crtc->pipe;
-       int i;
-       bool reenable_ips = false;
-       /* The clocks have to be on to load the palette. */
-       if (!crtc->state->active)
-               return;
-       if (HAS_GMCH_DISPLAY(dev_priv->dev)) {
-               if (intel_crtc->config->has_dsi_encoder)
-                       assert_dsi_pll_enabled(dev_priv);
-               else
-                       assert_pll_enabled(dev_priv, pipe);
-       }
-       /* Workaround : Do not read or write the pipe palette/gamma data while
-        * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
-        */
-       if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
-           ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
-            GAMMA_MODE_MODE_SPLIT)) {
-               hsw_disable_ips(intel_crtc);
-               reenable_ips = true;
-       }
-       for (i = 0; i < 256; i++) {
-               i915_reg_t palreg;
-               if (HAS_GMCH_DISPLAY(dev))
-                       palreg = PALETTE(pipe, i);
-               else
-                       palreg = LGC_PALETTE(pipe, i);
-               I915_WRITE(palreg,
-                          (intel_crtc->lut_r[i] << 16) |
-                          (intel_crtc->lut_g[i] << 8) |
-                          intel_crtc->lut_b[i]);
-       }
-       if (reenable_ips)
-               hsw_enable_ips(intel_crtc);
- }
  static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
  {
        if (intel_crtc->overlay) {
@@@ -4734,16 -4535,7 +4535,7 @@@ intel_post_enable_primary(struct drm_cr
        intel_check_pch_fifo_underruns(dev_priv);
  }
  
- /**
-  * intel_pre_disable_primary - Perform operations before disabling primary plane
-  * @crtc: the CRTC whose primary plane is to be disabled
-  *
-  * Performs potentially sleeping operations that must be done before the
-  * primary plane is disabled, such as updating FBC and IPS.  Note that this may
-  * be called due to an explicit primary plane update, or due to an implicit
-  * disable that is caused when a sprite plane completely hides the primary
-  * plane.
-  */
+ /* FIXME move all this to pre_plane_update() with proper state tracking */
  static void
  intel_pre_disable_primary(struct drm_crtc *crtc)
  {
        if (IS_GEN2(dev))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
  
+       /*
+        * FIXME IPS should be fine as long as one plane is
+        * enabled, but in practice it seems to have problems
+        * when going from primary only to sprite only and vice
+        * versa.
+        */
+       hsw_disable_ips(intel_crtc);
+ }
+ /* FIXME get rid of this and use pre_plane_update */
+ static void
+ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
+ {
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       intel_pre_disable_primary(crtc);
        /*
         * Vblank time updates from the shadow to live plane control register
         * are blocked if the memory self-refresh mode is active at that
                dev_priv->wm.vlv.cxsr = false;
                intel_wait_for_vblank(dev, pipe);
        }
-       /*
-        * FIXME IPS should be fine as long as one plane is
-        * enabled, but in practice it seems to have problems
-        * when going from primary only to sprite only and vice
-        * versa.
-        */
-       hsw_disable_ips(intel_crtc);
  }
  
- static void intel_post_plane_update(struct intel_crtc *crtc)
+ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
  {
-       struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
+       struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+       struct drm_atomic_state *old_state = old_crtc_state->base.state;
        struct intel_crtc_state *pipe_config =
                to_intel_crtc_state(crtc->base.state);
        struct drm_device *dev = crtc->base.dev;
-       intel_frontbuffer_flip(dev, atomic->fb_bits);
+       struct drm_plane *primary = crtc->base.primary;
+       struct drm_plane_state *old_pri_state =
+               drm_atomic_get_existing_plane_state(old_state, primary);
+       intel_frontbuffer_flip(dev, pipe_config->fb_bits);
  
        crtc->wm.cxsr_allowed = true;
  
-       if (pipe_config->wm_changed && pipe_config->base.active)
+       if (pipe_config->update_wm_post && pipe_config->base.active)
                intel_update_watermarks(&crtc->base);
  
-       if (atomic->update_fbc)
-               intel_fbc_post_update(crtc);
+       if (old_pri_state) {
+               struct intel_plane_state *primary_state =
+                       to_intel_plane_state(primary->state);
+               struct intel_plane_state *old_primary_state =
+                       to_intel_plane_state(old_pri_state);
  
-       if (atomic->post_enable_primary)
-               intel_post_enable_primary(&crtc->base);
+               intel_fbc_post_update(crtc);
  
-       memset(atomic, 0, sizeof(*atomic));
+               if (primary_state->visible &&
+                   (needs_modeset(&pipe_config->base) ||
+                    !old_primary_state->visible))
+                       intel_post_enable_primary(&crtc->base);
+       }
  }
  
  static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
        struct intel_crtc_state *pipe_config =
                to_intel_crtc_state(crtc->base.state);
        struct drm_atomic_state *old_state = old_crtc_state->base.state;
                drm_atomic_get_existing_plane_state(old_state, primary);
        bool modeset = needs_modeset(&pipe_config->base);
  
-       if (atomic->update_fbc)
-               intel_fbc_pre_update(crtc);
        if (old_pri_state) {
                struct intel_plane_state *primary_state =
                        to_intel_plane_state(primary->state);
                struct intel_plane_state *old_primary_state =
                        to_intel_plane_state(old_pri_state);
  
+               intel_fbc_pre_update(crtc);
                if (old_primary_state->visible &&
                    (modeset || !primary_state->visible))
                        intel_pre_disable_primary(&crtc->base);
        if (pipe_config->disable_cxsr) {
                crtc->wm.cxsr_allowed = false;
  
-               if (old_crtc_state->base.active)
+               /*
+                * Vblank time updates from the shadow to live plane control register
+                * are blocked if the memory self-refresh mode is active at that
+                * moment. So to make sure the plane gets truly disabled, disable
+                * first the self-refresh mode. The self-refresh enable bit in turn
+                * will be checked/applied by the HW only at the next frame start
+                * event which is after the vblank start event, so we need to have a
+                * wait-for-vblank between disabling the plane and the pipe.
+                */
+               if (old_crtc_state->base.active) {
                        intel_set_memory_cxsr(dev_priv, false);
+                       dev_priv->wm.vlv.cxsr = false;
+                       intel_wait_for_vblank(dev, crtc->pipe);
+               }
        }
  
-       if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed)
+       /*
+        * IVB workaround: must disable low power watermarks for at least
+        * one frame before enabling scaling.  LP watermarks can be re-enabled
+        * when scaling is disabled.
+        *
+        * WaCxSRDisabledForSpriteScaling:ivb
+        */
+       if (pipe_config->disable_lp_wm) {
+               ilk_disable_lp_wm(dev);
+               intel_wait_for_vblank(dev, crtc->pipe);
+       }
+       /*
+        * If we're doing a modeset, we're done.  No need to do any pre-vblank
+        * watermark programming here.
+        */
+       if (needs_modeset(&pipe_config->base))
+               return;
+       /*
+        * For platforms that support atomic watermarks, program the
+        * 'intermediate' watermarks immediately.  On pre-gen9 platforms, these
+        * will be the intermediate values that are safe for both pre- and
+        * post- vblank; when vblank happens, the 'active' values will be set
+        * to the final 'target' values and we'll do this again to get the
+        * optimal watermarks.  For gen9+ platforms, the values we program here
+        * will be the final target values which will get automatically latched
+        * at vblank time; no further programming will be necessary.
+        *
+        * If a platform hasn't been transitioned to atomic watermarks yet,
+        * we'll continue to update watermarks the old way, if flags tell
+        * us to.
+        */
+       if (dev_priv->display.initial_watermarks != NULL)
+               dev_priv->display.initial_watermarks(pipe_config);
+       else if (pipe_config->update_wm_pre)
                intel_update_watermarks(&crtc->base);
  }
  
@@@ -4874,10 -4733,24 +4733,24 @@@ static void ironlake_crtc_enable(struc
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
+       struct intel_crtc_state *pipe_config =
+               to_intel_crtc_state(crtc->state);
  
        if (WARN_ON(intel_crtc->active))
                return;
  
+       /*
+        * Sometimes spurious CPU pipe underruns happen during FDI
+        * training, at least with VGA+HDMI cloning. Suppress them.
+        *
+        * On ILK we get an occasional spurious CPU pipe underruns
+        * between eDP port A enable and vdd enable. Also PCH port
+        * enable seems to result in the occasional CPU pipe underrun.
+        *
+        * Spurious PCH underruns also occur during PCH enabling.
+        */
+       if (intel_crtc->config->has_pch_encoder || IS_GEN5(dev_priv))
+               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
        if (intel_crtc->config->has_pch_encoder)
                intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
  
                intel_dp_set_m_n(intel_crtc, M1_N1);
  
        intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
  
        if (intel_crtc->config->has_pch_encoder) {
                intel_cpu_transcoder_set_m_n(intel_crtc,
  
        intel_crtc->active = true;
  
-       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_enable)
                        encoder->pre_enable(encoder);
         * On ILK+ LUT must be loaded before the pipe is running but with
         * clocks enabled
         */
-       intel_crtc_load_lut(crtc);
+       intel_color_load_luts(&pipe_config->base);
  
-       intel_update_watermarks(crtc);
+       if (dev_priv->display.initial_watermarks != NULL)
+               dev_priv->display.initial_watermarks(intel_crtc->config);
        intel_enable_pipe(intel_crtc);
  
        if (intel_crtc->config->has_pch_encoder)
        /* Must wait for vblank to avoid spurious PCH FIFO underruns */
        if (intel_crtc->config->has_pch_encoder)
                intel_wait_for_vblank(dev, pipe);
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
  }
  
@@@ -4956,6 -4830,7 +4830,7 @@@ static void haswell_crtc_enable(struct 
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe, hsw_workaround_pipe;
+       enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
        struct intel_crtc_state *pipe_config =
                to_intel_crtc_state(crtc->state);
  
                intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
                                                      false);
  
-       if (intel_crtc_to_shared_dpll(intel_crtc))
+       if (intel_crtc->config->shared_dpll)
                intel_enable_shared_dpll(intel_crtc);
  
        if (intel_crtc->config->has_dp_encoder)
                intel_dp_set_m_n(intel_crtc, M1_N1);
  
-       intel_set_pipe_timings(intel_crtc);
+       if (!intel_crtc->config->has_dsi_encoder)
+               intel_set_pipe_timings(intel_crtc);
  
-       if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
-               I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
+       intel_set_pipe_src_size(intel_crtc);
+       if (cpu_transcoder != TRANSCODER_EDP &&
+           !transcoder_is_dsi(cpu_transcoder)) {
+               I915_WRITE(PIPE_MULT(cpu_transcoder),
                           intel_crtc->config->pixel_multiplier - 1);
        }
  
                                     &intel_crtc->config->fdi_m_n, NULL);
        }
  
-       haswell_set_pipeconf(crtc);
+       if (!intel_crtc->config->has_dsi_encoder)
+               haswell_set_pipeconf(crtc);
+       haswell_set_pipemisc(crtc);
  
-       intel_set_pipe_csc(crtc);
+       intel_color_set_csc(&pipe_config->base);
  
        intel_crtc->active = true;
  
         * On ILK+ LUT must be loaded before the pipe is running but with
         * clocks enabled
         */
-       intel_crtc_load_lut(crtc);
+       intel_color_load_luts(&pipe_config->base);
  
        intel_ddi_set_pipe_settings(crtc);
        if (!intel_crtc->config->has_dsi_encoder)
                intel_ddi_enable_transcoder_func(crtc);
  
-       intel_update_watermarks(crtc);
-       intel_enable_pipe(intel_crtc);
+       if (dev_priv->display.initial_watermarks != NULL)
+               dev_priv->display.initial_watermarks(pipe_config);
+       else
+               intel_update_watermarks(crtc);
+       /* XXX: Do the pipe assertions at the right place for BXT DSI. */
+       if (!intel_crtc->config->has_dsi_encoder)
+               intel_enable_pipe(intel_crtc);
  
        if (intel_crtc->config->has_pch_encoder)
                lpt_pch_enable(crtc);
@@@ -5078,8 -4966,15 +4966,15 @@@ static void ironlake_crtc_disable(struc
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
  
-       if (intel_crtc->config->has_pch_encoder)
+       /*
+        * Sometimes spurious CPU pipe underruns happen when the
+        * pipe is already disabled, but FDI RX/TX is still enabled.
+        * Happens at least with VGA+HDMI cloning. Suppress them.
+        */
+       if (intel_crtc->config->has_pch_encoder) {
+               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
                intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
+       }
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                encoder->disable(encoder);
        drm_crtc_vblank_off(crtc);
        assert_vblank_disabled(crtc);
  
-       /*
-        * Sometimes spurious CPU pipe underruns happen when the
-        * pipe is already disabled, but FDI RX/TX is still enabled.
-        * Happens at least with VGA+HDMI cloning. Suppress them.
-        */
-       if (intel_crtc->config->has_pch_encoder)
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
        intel_disable_pipe(intel_crtc);
  
        ironlake_pfit_disable(intel_crtc, false);
  
-       if (intel_crtc->config->has_pch_encoder) {
+       if (intel_crtc->config->has_pch_encoder)
                ironlake_fdi_disable(crtc);
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
-       }
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->post_disable)
                ironlake_fdi_pll_disable(intel_crtc);
        }
  
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
  }
  
@@@ -5155,7 -5041,9 +5041,9 @@@ static void haswell_crtc_disable(struc
        drm_crtc_vblank_off(crtc);
        assert_vblank_disabled(crtc);
  
-       intel_disable_pipe(intel_crtc);
+       /* XXX: Do the pipe assertions at the right place for BXT DSI. */
+       if (!intel_crtc->config->has_dsi_encoder)
+               intel_disable_pipe(intel_crtc);
  
        if (intel_crtc->config->dp_encoder_is_mst)
                intel_ddi_set_vc_payload_alloc(crtc, false);
@@@ -5330,6 -5218,9 +5218,9 @@@ static unsigned long get_crtc_power_dom
                mask |= BIT(intel_display_port_power_domain(intel_encoder));
        }
  
+       if (crtc_state->shared_dpll)
+               mask |= BIT(POWER_DOMAIN_PLLS);
        return mask;
  }
  
@@@ -5393,6 -5284,8 +5284,8 @@@ static void intel_update_max_cdclk(stru
                        dev_priv->max_cdclk_freq = 450000;
                else
                        dev_priv->max_cdclk_freq = 337500;
+       } else if (IS_BROXTON(dev)) {
+               dev_priv->max_cdclk_freq = 624000;
        } else if (IS_BROADWELL(dev))  {
                /*
                 * FIXME with extra cooling we can allow
@@@ -5452,9 -5345,8 +5345,8 @@@ static void intel_update_cdclk(struct d
                intel_update_max_cdclk(dev);
  }
  
- static void broxton_set_cdclk(struct drm_device *dev, int frequency)
+ static void broxton_set_cdclk(struct drm_i915_private *dev_priv, int frequency)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t divider;
        uint32_t ratio;
        uint32_t current_freq;
                return;
        }
  
-       intel_update_cdclk(dev);
+       intel_update_cdclk(dev_priv->dev);
  }
  
void broxton_init_cdclk(struct drm_device *dev)
static bool broxton_cdclk_is_enabled(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t val;
+       if (!(I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_PLL_ENABLE))
+               return false;
  
-       /*
-        * NDE_RSTWRN_OPT RST PCH Handshake En must always be 0b on BXT
-        * or else the reset will hang because there is no PCH to respond.
-        * Move the handshake programming to initialization sequence.
-        * Previously was left up to BIOS.
-        */
-       val = I915_READ(HSW_NDE_RSTWRN_OPT);
-       val &= ~RESET_PCH_HANDSHAKE_ENABLE;
-       I915_WRITE(HSW_NDE_RSTWRN_OPT, val);
+       /* TODO: Check for a valid CDCLK rate */
  
-       /* Enable PG1 for cdclk */
-       intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+       if (!(I915_READ(DBUF_CTL) & DBUF_POWER_REQUEST)) {
+               DRM_DEBUG_DRIVER("CDCLK enabled, but DBUF power not requested\n");
+               return false;
+       }
+       if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE)) {
+               DRM_DEBUG_DRIVER("CDCLK enabled, but DBUF power hasn't settled\n");
+               return false;
+       }
+       return true;
+ }
+ bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv)
+ {
+       return broxton_cdclk_is_enabled(dev_priv);
+ }
  
+ void broxton_init_cdclk(struct drm_i915_private *dev_priv)
+ {
        /* check if cd clock is enabled */
-       if (I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_PLL_ENABLE) {
-               DRM_DEBUG_KMS("Display already initialized\n");
+       if (broxton_cdclk_is_enabled(dev_priv)) {
+               DRM_DEBUG_KMS("CDCLK already enabled, won't reprogram it\n");
                return;
        }
  
+       DRM_DEBUG_KMS("CDCLK not enabled, enabling it\n");
        /*
         * FIXME:
         * - The initial CDCLK needs to be read from VBT.
         * - check if setting the max (or any) cdclk freq is really necessary
         *   here, it belongs to modeset time
         */
-       broxton_set_cdclk(dev, 624000);
+       broxton_set_cdclk(dev_priv, 624000);
  
        I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST);
        POSTING_READ(DBUF_CTL);
                DRM_ERROR("DBuf power enable timeout!\n");
  }
  
- void broxton_uninit_cdclk(struct drm_device *dev)
+ void broxton_uninit_cdclk(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST);
        POSTING_READ(DBUF_CTL);
  
                DRM_ERROR("DBuf power disable timeout!\n");
  
        /* Set minimum (bypass) frequency, in effect turning off the DE PLL */
-       broxton_set_cdclk(dev, 19200);
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+       broxton_set_cdclk(dev_priv, 19200);
  }
  
  static const struct skl_cdclk_entry {
@@@ -6165,6 -6066,8 +6066,8 @@@ static void valleyview_crtc_enable(stru
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
+       struct intel_crtc_state *pipe_config =
+               to_intel_crtc_state(crtc->state);
        int pipe = intel_crtc->pipe;
  
        if (WARN_ON(intel_crtc->active))
                intel_dp_set_m_n(intel_crtc, M1_N1);
  
        intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
  
        if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
                struct drm_i915_private *dev_priv = dev->dev_private;
                if (encoder->pre_pll_enable)
                        encoder->pre_pll_enable(encoder);
  
-       if (!intel_crtc->config->has_dsi_encoder) {
-               if (IS_CHERRYVIEW(dev)) {
-                       chv_prepare_pll(intel_crtc, intel_crtc->config);
-                       chv_enable_pll(intel_crtc, intel_crtc->config);
-               } else {
-                       vlv_prepare_pll(intel_crtc, intel_crtc->config);
-                       vlv_enable_pll(intel_crtc, intel_crtc->config);
-               }
+       if (IS_CHERRYVIEW(dev)) {
+               chv_prepare_pll(intel_crtc, intel_crtc->config);
+               chv_enable_pll(intel_crtc, intel_crtc->config);
+       } else {
+               vlv_prepare_pll(intel_crtc, intel_crtc->config);
+               vlv_enable_pll(intel_crtc, intel_crtc->config);
        }
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
  
        i9xx_pfit_enable(intel_crtc);
  
-       intel_crtc_load_lut(crtc);
+       intel_color_load_luts(&pipe_config->base);
  
+       intel_update_watermarks(crtc);
        intel_enable_pipe(intel_crtc);
  
        assert_vblank_disabled(crtc);
@@@ -6234,7 -6137,9 +6137,9 @@@ static void i9xx_crtc_enable(struct drm
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
-       int pipe = intel_crtc->pipe;
+       struct intel_crtc_state *pipe_config =
+               to_intel_crtc_state(crtc->state);
+       enum pipe pipe = intel_crtc->pipe;
  
        if (WARN_ON(intel_crtc->active))
                return;
                intel_dp_set_m_n(intel_crtc, M1_N1);
  
        intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
  
        i9xx_set_pipeconf(intel_crtc);
  
  
        i9xx_pfit_enable(intel_crtc);
  
-       intel_crtc_load_lut(crtc);
+       intel_color_load_luts(&pipe_config->base);
  
        intel_update_watermarks(crtc);
        intel_enable_pipe(intel_crtc);
@@@ -6299,10 -6205,9 +6205,9 @@@ static void i9xx_crtc_disable(struct dr
        /*
         * On gen2 planes are double buffered but the pipe isn't, so we must
         * wait for planes to fully turn off before disabling the pipe.
-        * We also need to wait on all gmch platforms because of the
-        * self-refresh mode constraint explained above.
         */
-       intel_wait_for_vblank(dev, pipe);
+       if (IS_GEN2(dev))
+               intel_wait_for_vblank(dev, pipe);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                encoder->disable(encoder);
  
  static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
  {
+       struct intel_encoder *encoder;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        enum intel_display_power_domain domain;
        if (to_intel_plane_state(crtc->primary->state)->visible) {
                WARN_ON(intel_crtc->unpin_work);
  
-               intel_pre_disable_primary(crtc);
+               intel_pre_disable_primary_noatomic(crtc);
  
                intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
                to_intel_plane_state(crtc->primary->state)->visible = false;
        }
  
        dev_priv->display.crtc_disable(crtc);
+       DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was enabled, now disabled\n",
+                     crtc->base.id);
+       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->state, NULL) < 0);
+       crtc->state->active = false;
        intel_crtc->active = false;
+       crtc->enabled = false;
+       crtc->state->connector_mask = 0;
+       crtc->state->encoder_mask = 0;
+       for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
+               encoder->base.crtc = NULL;
        intel_fbc_disable(intel_crtc);
        intel_update_watermarks(crtc);
        intel_disable_shared_dpll(intel_crtc);
@@@ -6398,7 -6317,7 +6317,7 @@@ void intel_encoder_destroy(struct drm_e
  
  /* Cross check the actual hw state with our own modeset state tracking (and it's
   * internal consistency). */
- static void intel_connector_check_state(struct intel_connector *connector)
+ static void intel_connector_verify_state(struct intel_connector *connector)
  {
        struct drm_crtc *crtc = connector->base.state->crtc;
  
@@@ -6568,7 -6487,7 +6487,7 @@@ retry
         * Hence the bw of each lane in terms of the mode signal
         * is:
         */
-       link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
+       link_bw = intel_fdi_link_freq(to_i915(dev), pipe_config);
  
        fdi_dotclock = adjusted_mode->crtc_clock;
  
        intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
                               link_bw, &pipe_config->fdi_m_n);
  
-       ret = ironlake_check_fdi_lanes(intel_crtc->base.dev,
-                                      intel_crtc->pipe, pipe_config);
+       ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
        if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
                pipe_config->pipe_bpp -= 2*3;
                DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n",
@@@ -6605,7 -6523,7 +6523,7 @@@ static bool pipe_config_supports_ips(st
                return false;
  
        /* HSW can handle pixel rate up to cdclk? */
-       if (IS_HASWELL(dev_priv->dev))
+       if (IS_HASWELL(dev_priv))
                return true;
  
        /*
@@@ -7133,30 -7051,6 +7051,6 @@@ static inline bool intel_panel_use_ssc(
                && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
  }
  
- static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
-                          int num_connectors)
- {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int refclk;
-       WARN_ON(!crtc_state->base.state);
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) {
-               refclk = 100000;
-       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
-           intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
-               refclk = dev_priv->vbt.lvds_ssc_freq;
-               DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
-       } else if (!IS_GEN2(dev)) {
-               refclk = 96000;
-       } else {
-               refclk = 48000;
-       }
-       return refclk;
- }
  static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
  {
        return (1 << dpll->n) << 16 | dpll->m2;
@@@ -7300,24 -7194,34 +7194,34 @@@ void intel_dp_set_m_n(struct intel_crt
  static void vlv_compute_dpll(struct intel_crtc *crtc,
                             struct intel_crtc_state *pipe_config)
  {
-       u32 dpll, dpll_md;
+       pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV |
+               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+       if (crtc->pipe != PIPE_A)
+               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
  
-       /*
-        * Enable DPIO clock input. We should never disable the reference
-        * clock for pipe B, since VGA hotplug / manual detection depends
-        * on it.
-        */
-       dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REF_CLK_ENABLE_VLV |
-               DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_REF_CLK_VLV;
-       /* We should never disable this, set it here for state tracking */
-       if (crtc->pipe == PIPE_B)
-               dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
-       dpll |= DPLL_VCO_ENABLE;
-       pipe_config->dpll_hw_state.dpll = dpll;
+       /* DPLL not used with DSI, but still need the rest set up */
+       if (!pipe_config->has_dsi_encoder)
+               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
+                       DPLL_EXT_BUFFER_ENABLE_VLV;
+       pipe_config->dpll_hw_state.dpll_md =
+               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
+ }
+ static void chv_compute_dpll(struct intel_crtc *crtc,
+                            struct intel_crtc_state *pipe_config)
+ {
+       pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
+               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+       if (crtc->pipe != PIPE_A)
+               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
+       /* DPLL not used with DSI, but still need the rest set up */
+       if (!pipe_config->has_dsi_encoder)
+               pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
  
-       dpll_md = (pipe_config->pixel_multiplier - 1)
-               << DPLL_MD_UDI_MULTIPLIER_SHIFT;
-       pipe_config->dpll_hw_state.dpll_md = dpll_md;
+       pipe_config->dpll_hw_state.dpll_md =
+               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
  }
  
  static void vlv_prepare_pll(struct intel_crtc *crtc,
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipe = crtc->pipe;
+       enum pipe pipe = crtc->pipe;
        u32 mdiv;
        u32 bestn, bestm1, bestm2, bestp1, bestp2;
        u32 coreclk, reg_val;
  
+       /* Enable Refclk */
+       I915_WRITE(DPLL(pipe),
+                  pipe_config->dpll_hw_state.dpll &
+                  ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
+       /* No need to actually set up the DPLL with DSI */
+       if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+               return;
        mutex_lock(&dev_priv->sb_lock);
  
        bestn = pipe_config->dpll.n;
        mutex_unlock(&dev_priv->sb_lock);
  }
  
- static void chv_compute_dpll(struct intel_crtc *crtc,
-                            struct intel_crtc_state *pipe_config)
- {
-       pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV |
-               DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS |
-               DPLL_VCO_ENABLE;
-       if (crtc->pipe != PIPE_A)
-               pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
-       pipe_config->dpll_hw_state.dpll_md =
-               (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
- }
  static void chv_prepare_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *pipe_config)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipe = crtc->pipe;
-       i915_reg_t dpll_reg = DPLL(crtc->pipe);
+       enum pipe pipe = crtc->pipe;
        enum dpio_channel port = vlv_pipe_to_channel(pipe);
        u32 loopfilter, tribuf_calcntr;
        u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
        u32 dpio_val;
        int vco;
  
+       /* Enable Refclk and SSC */
+       I915_WRITE(DPLL(pipe),
+                  pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
+       /* No need to actually set up the DPLL with DSI */
+       if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+               return;
        bestn = pipe_config->dpll.n;
        bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
        bestm1 = pipe_config->dpll.m1;
        dpio_val = 0;
        loopfilter = 0;
  
-       /*
-        * Enable Refclk and SSC
-        */
-       I915_WRITE(dpll_reg,
-                  pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
        mutex_lock(&dev_priv->sb_lock);
  
        /* p1 and p2 divider */
@@@ -7586,8 -7487,7 +7487,7 @@@ void vlv_force_pll_off(struct drm_devic
  
  static void i9xx_compute_dpll(struct intel_crtc *crtc,
                              struct intel_crtc_state *crtc_state,
-                             intel_clock_t *reduced_clock,
-                             int num_connectors)
+                             intel_clock_t *reduced_clock)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        if (crtc_state->sdvo_tv_clock)
                dpll |= PLL_REF_INPUT_TVCLKINBC;
        else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
-                intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+                intel_panel_use_ssc(dev_priv))
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
  
  static void i8xx_compute_dpll(struct intel_crtc *crtc,
                              struct intel_crtc_state *crtc_state,
-                             intel_clock_t *reduced_clock,
-                             int num_connectors)
+                             intel_clock_t *reduced_clock)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
                dpll |= DPLL_DVO_2X_MODE;
  
        if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
-                intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+           intel_panel_use_ssc(dev_priv))
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
@@@ -7759,6 -7658,14 +7658,14 @@@ static void intel_set_pipe_timings(stru
            (pipe == PIPE_B || pipe == PIPE_C))
                I915_WRITE(VTOTAL(pipe), I915_READ(VTOTAL(cpu_transcoder)));
  
+ }
+ static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc)
+ {
+       struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum pipe pipe = intel_crtc->pipe;
        /* pipesrc controls the size that is scaled from, which should
         * always be the user's requested size.
         */
@@@ -7800,6 -7707,14 +7707,14 @@@ static void intel_get_pipe_timings(stru
                pipe_config->base.adjusted_mode.crtc_vtotal += 1;
                pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
        }
+ }
+ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
+                                   struct intel_crtc_state *pipe_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 tmp;
  
        tmp = I915_READ(PIPESRC(crtc->pipe));
        pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
@@@ -7897,69 -7812,192 +7812,192 @@@ static void i9xx_set_pipeconf(struct in
        POSTING_READ(PIPECONF(intel_crtc->pipe));
  }
  
- static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+ static int i8xx_crtc_compute_clock(struct intel_crtc *crtc,
                                   struct intel_crtc_state *crtc_state)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int refclk, num_connectors = 0;
-       intel_clock_t clock;
-       bool ok;
        const intel_limit_t *limit;
-       struct drm_atomic_state *state = crtc_state->base.state;
-       struct drm_connector *connector;
-       struct drm_connector_state *connector_state;
-       int i;
+       int refclk = 48000;
  
        memset(&crtc_state->dpll_hw_state, 0,
               sizeof(crtc_state->dpll_hw_state));
  
-       if (crtc_state->has_dsi_encoder)
-               return 0;
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv)) {
+                       refclk = dev_priv->vbt.lvds_ssc_freq;
+                       DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+               }
  
-       for_each_connector_in_state(state, connector, connector_state, i) {
-               if (connector_state->crtc == &crtc->base)
-                       num_connectors++;
+               limit = &intel_limits_i8xx_lvds;
+       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) {
+               limit = &intel_limits_i8xx_dvo;
+       } else {
+               limit = &intel_limits_i8xx_dac;
        }
  
-       if (!crtc_state->clock_set) {
-               refclk = i9xx_get_refclk(crtc_state, num_connectors);
+       if (!crtc_state->clock_set &&
+           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                                refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
+       }
  
-               /*
-                * Returns a set of divisors for the desired target clock with
-                * the given refclk, or FALSE.  The returned values represent
-                * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
-                * 2) / p1 / p2.
-                */
-               limit = intel_limit(crtc_state, refclk);
-               ok = dev_priv->display.find_dpll(limit, crtc_state,
-                                                crtc_state->port_clock,
-                                                refclk, NULL, &clock);
-               if (!ok) {
-                       DRM_ERROR("Couldn't find PLL settings for mode!\n");
-                       return -EINVAL;
+       i8xx_compute_dpll(crtc, crtc_state, NULL);
+       return 0;
+ }
+ static int g4x_crtc_compute_clock(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       const intel_limit_t *limit;
+       int refclk = 96000;
+       memset(&crtc_state->dpll_hw_state, 0,
+              sizeof(crtc_state->dpll_hw_state));
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv)) {
+                       refclk = dev_priv->vbt.lvds_ssc_freq;
+                       DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
                }
  
-               /* Compat-code for transition, will disappear. */
-               crtc_state->dpll.n = clock.n;
-               crtc_state->dpll.m1 = clock.m1;
-               crtc_state->dpll.m2 = clock.m2;
-               crtc_state->dpll.p1 = clock.p1;
-               crtc_state->dpll.p2 = clock.p2;
+               if (intel_is_dual_link_lvds(dev))
+                       limit = &intel_limits_g4x_dual_channel_lvds;
+               else
+                       limit = &intel_limits_g4x_single_channel_lvds;
+       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) ||
+                  intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
+               limit = &intel_limits_g4x_hdmi;
+       } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
+               limit = &intel_limits_g4x_sdvo;
+       } else {
+               /* The option is for other outputs */
+               limit = &intel_limits_i9xx_sdvo;
        }
  
-       if (IS_GEN2(dev)) {
-               i8xx_compute_dpll(crtc, crtc_state, NULL,
-                                 num_connectors);
-       } else if (IS_CHERRYVIEW(dev)) {
-               chv_compute_dpll(crtc, crtc_state);
-       } else if (IS_VALLEYVIEW(dev)) {
-               vlv_compute_dpll(crtc, crtc_state);
+       if (!crtc_state->clock_set &&
+           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                               refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
+       }
+       i9xx_compute_dpll(crtc, crtc_state, NULL);
+       return 0;
+ }
+ static int pnv_crtc_compute_clock(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       const intel_limit_t *limit;
+       int refclk = 96000;
+       memset(&crtc_state->dpll_hw_state, 0,
+              sizeof(crtc_state->dpll_hw_state));
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv)) {
+                       refclk = dev_priv->vbt.lvds_ssc_freq;
+                       DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+               }
+               limit = &intel_limits_pineview_lvds;
        } else {
-               i9xx_compute_dpll(crtc, crtc_state, NULL,
-                                 num_connectors);
+               limit = &intel_limits_pineview_sdvo;
+       }
+       if (!crtc_state->clock_set &&
+           !pnv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                               refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
+       }
+       i9xx_compute_dpll(crtc, crtc_state, NULL);
+       return 0;
+ }
+ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+                                  struct intel_crtc_state *crtc_state)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       const intel_limit_t *limit;
+       int refclk = 96000;
+       memset(&crtc_state->dpll_hw_state, 0,
+              sizeof(crtc_state->dpll_hw_state));
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv)) {
+                       refclk = dev_priv->vbt.lvds_ssc_freq;
+                       DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
+               }
+               limit = &intel_limits_i9xx_lvds;
+       } else {
+               limit = &intel_limits_i9xx_sdvo;
+       }
+       if (!crtc_state->clock_set &&
+           !i9xx_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                                refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
+       }
+       i9xx_compute_dpll(crtc, crtc_state, NULL);
+       return 0;
+ }
+ static int chv_crtc_compute_clock(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
+ {
+       int refclk = 100000;
+       const intel_limit_t *limit = &intel_limits_chv;
+       memset(&crtc_state->dpll_hw_state, 0,
+              sizeof(crtc_state->dpll_hw_state));
+       if (!crtc_state->clock_set &&
+           !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                               refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
+       }
+       chv_compute_dpll(crtc, crtc_state);
+       return 0;
+ }
+ static int vlv_crtc_compute_clock(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
+ {
+       int refclk = 100000;
+       const intel_limit_t *limit = &intel_limits_vlv;
+       memset(&crtc_state->dpll_hw_state, 0,
+              sizeof(crtc_state->dpll_hw_state));
+       if (!crtc_state->clock_set &&
+           !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                               refclk, NULL, &crtc_state->dpll)) {
+               DRM_ERROR("Couldn't find PLL settings for mode!\n");
+               return -EINVAL;
        }
  
+       vlv_compute_dpll(crtc, crtc_state);
        return 0;
  }
  
@@@ -7988,6 -8026,9 +8026,6 @@@ static void i9xx_get_pfit_config(struc
  
        pipe_config->gmch_pfit.control = tmp;
        pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
 -      if (INTEL_INFO(dev)->gen < 5)
 -              pipe_config->gmch_pfit.lvds_border_bits =
 -                      I915_READ(LVDS) & LVDS_BORDER_ENABLE;
  }
  
  static void vlv_crtc_clock_get(struct intel_crtc *crtc,
        u32 mdiv;
        int refclk = 100000;
  
-       /* In case of MIPI DPLL will not even be used */
-       if (!(pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE))
+       /* In case of DSI, DPLL will not be used */
+       if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
                return;
  
        mutex_lock(&dev_priv->sb_lock);
@@@ -8097,6 -8138,10 +8135,10 @@@ static void chv_crtc_clock_get(struct i
        u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3;
        int refclk = 100000;
  
+       /* In case of DSI, DPLL will not be used */
+       if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+               return;
        mutex_lock(&dev_priv->sb_lock);
        cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
        pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
@@@ -8130,7 -8175,7 +8172,7 @@@ static bool i9xx_get_pipe_config(struc
                return false;
  
        pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-       pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+       pipe_config->shared_dpll = NULL;
  
        ret = false;
  
                pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
  
        intel_get_pipe_timings(crtc, pipe_config);
+       intel_get_pipe_src_size(crtc, pipe_config);
  
        i9xx_get_pfit_config(crtc, pipe_config);
  
        if (INTEL_INFO(dev)->gen >= 4) {
-               tmp = I915_READ(DPLL_MD(crtc->pipe));
+               /* No way to read it out on pipes B and C */
+               if (IS_CHERRYVIEW(dev) && crtc->pipe != PIPE_A)
+                       tmp = dev_priv->chv_dpll_md[crtc->pipe];
+               else
+                       tmp = I915_READ(DPLL_MD(crtc->pipe));
                pipe_config->pixel_multiplier =
                        ((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
                         >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
@@@ -8635,42 -8685,6 +8682,6 @@@ void intel_init_pch_refclk(struct drm_d
                lpt_init_pch_refclk(dev);
  }
  
- static int ironlake_get_refclk(struct intel_crtc_state *crtc_state)
- {
-       struct drm_device *dev = crtc_state->base.crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_atomic_state *state = crtc_state->base.state;
-       struct drm_connector *connector;
-       struct drm_connector_state *connector_state;
-       struct intel_encoder *encoder;
-       int num_connectors = 0, i;
-       bool is_lvds = false;
-       for_each_connector_in_state(state, connector, connector_state, i) {
-               if (connector_state->crtc != crtc_state->base.crtc)
-                       continue;
-               encoder = to_intel_encoder(connector_state->best_encoder);
-               switch (encoder->type) {
-               case INTEL_OUTPUT_LVDS:
-                       is_lvds = true;
-                       break;
-               default:
-                       break;
-               }
-               num_connectors++;
-       }
-       if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
-               DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
-                             dev_priv->vbt.lvds_ssc_freq);
-               return dev_priv->vbt.lvds_ssc_freq;
-       }
-       return 120000;
- }
  static void ironlake_set_pipeconf(struct drm_crtc *crtc)
  {
        struct drm_i915_private *dev_priv = crtc->dev->dev_private;
        POSTING_READ(PIPECONF(pipe));
  }
  
- /*
-  * Set up the pipe CSC unit.
-  *
-  * Currently only full range RGB to limited range RGB conversion
-  * is supported, but eventually this should handle various
-  * RGB<->YCbCr scenarios as well.
-  */
- static void intel_set_pipe_csc(struct drm_crtc *crtc)
- {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
-       uint16_t coeff = 0x7800; /* 1.0 */
-       /*
-        * TODO: Check what kind of values actually come out of the pipe
-        * with these coeff/postoff values and adjust to get the best
-        * accuracy. Perhaps we even need to take the bpc value into
-        * consideration.
-        */
-       if (intel_crtc->config->limited_color_range)
-               coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
-       /*
-        * GY/GU and RY/RU should be the other way around according
-        * to BSpec, but reality doesn't agree. Just set them up in
-        * a way that results in the correct picture.
-        */
-       I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16);
-       I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0);
-       I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff);
-       I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0);
-       I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0);
-       I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16);
-       I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0);
-       I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0);
-       I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0);
-       if (INTEL_INFO(dev)->gen > 6) {
-               uint16_t postoff = 0;
-               if (intel_crtc->config->limited_color_range)
-                       postoff = (16 * (1 << 12) / 255) & 0x1fff;
-               I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
-               I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff);
-               I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff);
-               I915_WRITE(PIPE_CSC_MODE(pipe), 0);
-       } else {
-               uint32_t mode = CSC_MODE_YUV_TO_RGB;
-               if (intel_crtc->config->limited_color_range)
-                       mode |= CSC_BLACK_SCREEN_OFFSET;
-               I915_WRITE(PIPE_CSC_MODE(pipe), mode);
-       }
- }
  static void haswell_set_pipeconf(struct drm_crtc *crtc)
  {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = crtc->dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum pipe pipe = intel_crtc->pipe;
        enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
-       uint32_t val;
-       val = 0;
+       u32 val = 0;
  
-       if (IS_HASWELL(dev) && intel_crtc->config->dither)
+       if (IS_HASWELL(dev_priv) && intel_crtc->config->dither)
                val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
  
        if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
  
        I915_WRITE(PIPECONF(cpu_transcoder), val);
        POSTING_READ(PIPECONF(cpu_transcoder));
+ }
  
-       I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
-       POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
+ static void haswell_set_pipemisc(struct drm_crtc *crtc)
+ {
+       struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  
-       if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
-               val = 0;
+       if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
+               u32 val = 0;
  
                switch (intel_crtc->config->pipe_bpp) {
                case 18:
                default:
                        /* Case prevented by pipe_config_set_bpp. */
                        BUG();
-               }
-               if (intel_crtc->config->dither)
-                       val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
-               I915_WRITE(PIPEMISC(pipe), val);
-       }
- }
- static bool ironlake_compute_clocks(struct drm_crtc *crtc,
-                                   struct intel_crtc_state *crtc_state,
-                                   intel_clock_t *clock,
-                                   bool *has_reduced_clock,
-                                   intel_clock_t *reduced_clock)
- {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int refclk;
-       const intel_limit_t *limit;
-       bool ret;
-       refclk = ironlake_get_refclk(crtc_state);
+               }
  
-       /*
-        * Returns a set of divisors for the desired target clock with the given
-        * refclk, or FALSE.  The returned values represent the clock equation:
-        * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
-        */
-       limit = intel_limit(crtc_state, refclk);
-       ret = dev_priv->display.find_dpll(limit, crtc_state,
-                                         crtc_state->port_clock,
-                                         refclk, NULL, clock);
-       if (!ret)
-               return false;
+               if (intel_crtc->config->dither)
+                       val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
  
-       return true;
+               I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
+       }
  }
  
  int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
@@@ -8875,10 -8795,9 +8792,9 @@@ static bool ironlake_needs_fb_cb_tune(s
        return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
  }
  
- static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
-                                     struct intel_crtc_state *crtc_state,
-                                     u32 *fp,
-                                     intel_clock_t *reduced_clock, u32 *fp2)
+ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
+                                 struct intel_crtc_state *crtc_state,
+                                 intel_clock_t *reduced_clock)
  {
        struct drm_crtc *crtc = &intel_crtc->base;
        struct drm_device *dev = crtc->dev;
        struct drm_connector *connector;
        struct drm_connector_state *connector_state;
        struct intel_encoder *encoder;
-       uint32_t dpll;
-       int factor, num_connectors = 0, i;
+       u32 dpll, fp, fp2;
+       int factor, i;
        bool is_lvds = false, is_sdvo = false;
  
        for_each_connector_in_state(state, connector, connector_state, i) {
                default:
                        break;
                }
-               num_connectors++;
        }
  
        /* Enable autotuning of the PLL clock (if permissible) */
        } else if (crtc_state->sdvo_tv_clock)
                factor = 20;
  
+       fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
        if (ironlake_needs_fb_cb_tune(&crtc_state->dpll, factor))
-               *fp |= FP_CB_TUNE;
+               fp |= FP_CB_TUNE;
  
-       if (fp2 && (reduced_clock->m < factor * reduced_clock->n))
-               *fp2 |= FP_CB_TUNE;
+       if (reduced_clock) {
+               fp2 = i9xx_dpll_compute_fp(reduced_clock);
+               if (reduced_clock->m < factor * reduced_clock->n)
+                       fp2 |= FP_CB_TUNE;
+       } else {
+               fp2 = fp;
+       }
  
        dpll = 0;
  
                break;
        }
  
-       if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+       if (is_lvds && intel_panel_use_ssc(dev_priv))
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
  
-       return dpll | DPLL_VCO_ENABLE;
+       dpll |= DPLL_VCO_ENABLE;
+       crtc_state->dpll_hw_state.dpll = dpll;
+       crtc_state->dpll_hw_state.fp0 = fp;
+       crtc_state->dpll_hw_state.fp1 = fp2;
  }
  
  static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
                                       struct intel_crtc_state *crtc_state)
  {
        struct drm_device *dev = crtc->base.dev;
-       intel_clock_t clock, reduced_clock;
-       u32 dpll = 0, fp = 0, fp2 = 0;
-       bool ok, has_reduced_clock = false;
-       bool is_lvds = false;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       intel_clock_t reduced_clock;
+       bool has_reduced_clock = false;
        struct intel_shared_dpll *pll;
+       const intel_limit_t *limit;
+       int refclk = 120000;
  
        memset(&crtc_state->dpll_hw_state, 0,
               sizeof(crtc_state->dpll_hw_state));
  
-       is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
+       crtc->lowfreq_avail = false;
+       /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
+       if (!crtc_state->has_pch_encoder)
+               return 0;
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
+               if (intel_panel_use_ssc(dev_priv)) {
+                       DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
+                                     dev_priv->vbt.lvds_ssc_freq);
+                       refclk = dev_priv->vbt.lvds_ssc_freq;
+               }
  
-       WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
-            "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
+               if (intel_is_dual_link_lvds(dev)) {
+                       if (refclk == 100000)
+                               limit = &intel_limits_ironlake_dual_lvds_100m;
+                       else
+                               limit = &intel_limits_ironlake_dual_lvds;
+               } else {
+                       if (refclk == 100000)
+                               limit = &intel_limits_ironlake_single_lvds_100m;
+                       else
+                               limit = &intel_limits_ironlake_single_lvds;
+               }
+       } else {
+               limit = &intel_limits_ironlake_dac;
+       }
  
-       ok = ironlake_compute_clocks(&crtc->base, crtc_state, &clock,
-                                    &has_reduced_clock, &reduced_clock);
-       if (!ok && !crtc_state->clock_set) {
+       if (!crtc_state->clock_set &&
+           !g4x_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
+                               refclk, NULL, &crtc_state->dpll)) {
                DRM_ERROR("Couldn't find PLL settings for mode!\n");
                return -EINVAL;
        }
-       /* Compat-code for transition, will disappear. */
-       if (!crtc_state->clock_set) {
-               crtc_state->dpll.n = clock.n;
-               crtc_state->dpll.m1 = clock.m1;
-               crtc_state->dpll.m2 = clock.m2;
-               crtc_state->dpll.p1 = clock.p1;
-               crtc_state->dpll.p2 = clock.p2;
-       }
-       /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
-       if (crtc_state->has_pch_encoder) {
-               fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
-               if (has_reduced_clock)
-                       fp2 = i9xx_dpll_compute_fp(&reduced_clock);
  
-               dpll = ironlake_compute_dpll(crtc, crtc_state,
-                                            &fp, &reduced_clock,
-                                            has_reduced_clock ? &fp2 : NULL);
-               crtc_state->dpll_hw_state.dpll = dpll;
-               crtc_state->dpll_hw_state.fp0 = fp;
-               if (has_reduced_clock)
-                       crtc_state->dpll_hw_state.fp1 = fp2;
-               else
-                       crtc_state->dpll_hw_state.fp1 = fp;
+       ironlake_compute_dpll(crtc, crtc_state,
+                             has_reduced_clock ? &reduced_clock : NULL);
  
-               pll = intel_get_shared_dpll(crtc, crtc_state);
-               if (pll == NULL) {
-                       DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
-                                        pipe_name(crtc->pipe));
-                       return -EINVAL;
-               }
+       pll = intel_get_shared_dpll(crtc, crtc_state, NULL);
+       if (pll == NULL) {
+               DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+                                pipe_name(crtc->pipe));
+               return -EINVAL;
        }
  
-       if (is_lvds && has_reduced_clock)
+       if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+           has_reduced_clock)
                crtc->lowfreq_avail = true;
-       else
-               crtc->lowfreq_avail = false;
  
        return 0;
  }
@@@ -9334,7 -9263,7 +9260,7 @@@ static bool ironlake_get_pipe_config(st
                return false;
  
        pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-       pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+       pipe_config->shared_dpll = NULL;
  
        ret = false;
        tmp = I915_READ(PIPECONF(crtc->pipe));
  
        if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
                struct intel_shared_dpll *pll;
+               enum intel_dpll_id pll_id;
  
                pipe_config->has_pch_encoder = true;
  
  
                ironlake_get_fdi_m_n_config(crtc, pipe_config);
  
-               if (HAS_PCH_IBX(dev_priv->dev)) {
-                       pipe_config->shared_dpll =
-                               (enum intel_dpll_id) crtc->pipe;
+               if (HAS_PCH_IBX(dev_priv)) {
+                       pll_id = (enum intel_dpll_id) crtc->pipe;
                } else {
                        tmp = I915_READ(PCH_DPLL_SEL);
                        if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
-                               pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B;
+                               pll_id = DPLL_ID_PCH_PLL_B;
                        else
-                               pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
+                               pll_id= DPLL_ID_PCH_PLL_A;
                }
  
-               pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
+               pipe_config->shared_dpll =
+                       intel_get_shared_dpll_by_id(dev_priv, pll_id);
+               pll = pipe_config->shared_dpll;
  
-               WARN_ON(!pll->get_hw_state(dev_priv, pll,
-                                          &pipe_config->dpll_hw_state));
+               WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+                                                &pipe_config->dpll_hw_state));
  
                tmp = pipe_config->dpll_hw_state.dpll;
                pipe_config->pixel_multiplier =
        }
  
        intel_get_pipe_timings(crtc, pipe_config);
+       intel_get_pipe_src_size(crtc, pipe_config);
  
        ironlake_get_pfit_config(crtc, pipe_config);
  
@@@ -9638,7 -9570,7 +9567,7 @@@ static void broxton_modeset_commit_cdcl
                to_intel_atomic_state(old_state);
        unsigned int req_cdclk = old_intel_state->dev_cdclk;
  
-       broxton_set_cdclk(dev, req_cdclk);
+       broxton_set_cdclk(to_i915(dev), req_cdclk);
  }
  
  /* compute the max rate for new configuration */
@@@ -9706,8 -9638,8 +9635,8 @@@ static void broadwell_set_cdclk(struct 
        val |= LCPLL_CD_SOURCE_FCLK;
        I915_WRITE(LCPLL_CTL, val);
  
-       if (wait_for_atomic_us(I915_READ(LCPLL_CTL) &
-                              LCPLL_CD_SOURCE_FCLK_DONE, 1))
+       if (wait_for_us(I915_READ(LCPLL_CTL) &
+                       LCPLL_CD_SOURCE_FCLK_DONE, 1))
                DRM_ERROR("Switching to FCLK failed\n");
  
        val = I915_READ(LCPLL_CTL);
        val &= ~LCPLL_CD_SOURCE_FCLK;
        I915_WRITE(LCPLL_CTL, val);
  
-       if (wait_for_atomic_us((I915_READ(LCPLL_CTL) &
-                               LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
+       if (wait_for_us((I915_READ(LCPLL_CTL) &
+                       LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
                DRM_ERROR("Switching back to LCPLL failed\n");
  
        mutex_lock(&dev_priv->rps.hw_lock);
        sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
        mutex_unlock(&dev_priv->rps.hw_lock);
  
 +      I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
 +
        intel_update_cdclk(dev);
  
        WARN(cdclk != dev_priv->cdclk_freq,
@@@ -9821,72 -9751,193 +9750,193 @@@ static void bxt_get_ddi_pll(struct drm_
                                enum port port,
                                struct intel_crtc_state *pipe_config)
  {
+       enum intel_dpll_id id;
        switch (port) {
        case PORT_A:
                pipe_config->ddi_pll_sel = SKL_DPLL0;
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+               id = DPLL_ID_SKL_DPLL0;
                break;
        case PORT_B:
                pipe_config->ddi_pll_sel = SKL_DPLL1;
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+               id = DPLL_ID_SKL_DPLL1;
                break;
        case PORT_C:
                pipe_config->ddi_pll_sel = SKL_DPLL2;
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+               id = DPLL_ID_SKL_DPLL2;
                break;
        default:
                DRM_ERROR("Incorrect port type\n");
+               return;
        }
+       pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
  }
  
  static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
                                enum port port,
                                struct intel_crtc_state *pipe_config)
  {
-       u32 temp, dpll_ctl1;
+       enum intel_dpll_id id;
+       u32 temp;
  
        temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
        pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
  
        switch (pipe_config->ddi_pll_sel) {
        case SKL_DPLL0:
-               /*
-                * On SKL the eDP DPLL (DPLL0 as we don't use SSC) is not part
-                * of the shared DPLL framework and thus needs to be read out
-                * separately
-                */
-               dpll_ctl1 = I915_READ(DPLL_CTRL1);
-               pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f;
+               id = DPLL_ID_SKL_DPLL0;
                break;
        case SKL_DPLL1:
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+               id = DPLL_ID_SKL_DPLL1;
                break;
        case SKL_DPLL2:
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+               id = DPLL_ID_SKL_DPLL2;
                break;
        case SKL_DPLL3:
-               pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+               id = DPLL_ID_SKL_DPLL3;
                break;
+       default:
+               MISSING_CASE(pipe_config->ddi_pll_sel);
+               return;
        }
+       pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
  }
  
  static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
                                enum port port,
                                struct intel_crtc_state *pipe_config)
  {
+       enum intel_dpll_id id;
        pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
  
        switch (pipe_config->ddi_pll_sel) {
        case PORT_CLK_SEL_WRPLL1:
-               pipe_config->shared_dpll = DPLL_ID_WRPLL1;
+               id = DPLL_ID_WRPLL1;
                break;
        case PORT_CLK_SEL_WRPLL2:
-               pipe_config->shared_dpll = DPLL_ID_WRPLL2;
+               id = DPLL_ID_WRPLL2;
                break;
        case PORT_CLK_SEL_SPLL:
-               pipe_config->shared_dpll = DPLL_ID_SPLL;
+               id = DPLL_ID_SPLL;
+               break;
+       case PORT_CLK_SEL_LCPLL_810:
+               id = DPLL_ID_LCPLL_810;
+               break;
+       case PORT_CLK_SEL_LCPLL_1350:
+               id = DPLL_ID_LCPLL_1350;
+               break;
+       case PORT_CLK_SEL_LCPLL_2700:
+               id = DPLL_ID_LCPLL_2700;
+               break;
+       default:
+               MISSING_CASE(pipe_config->ddi_pll_sel);
+               /* fall through */
+       case PORT_CLK_SEL_NONE:
+               return;
+       }
+       pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
+ }
+ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
+                                    struct intel_crtc_state *pipe_config,
+                                    unsigned long *power_domain_mask)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum intel_display_power_domain power_domain;
+       u32 tmp;
+       pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
+       /*
+        * XXX: Do intel_display_power_get_if_enabled before reading this (for
+        * consistency and less surprising code; it's in always on power).
+        */
+       tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+       if (tmp & TRANS_DDI_FUNC_ENABLE) {
+               enum pipe trans_edp_pipe;
+               switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+               default:
+                       WARN(1, "unknown pipe linked to edp transcoder\n");
+               case TRANS_DDI_EDP_INPUT_A_ONOFF:
+               case TRANS_DDI_EDP_INPUT_A_ON:
+                       trans_edp_pipe = PIPE_A;
+                       break;
+               case TRANS_DDI_EDP_INPUT_B_ONOFF:
+                       trans_edp_pipe = PIPE_B;
+                       break;
+               case TRANS_DDI_EDP_INPUT_C_ONOFF:
+                       trans_edp_pipe = PIPE_C;
+                       break;
+               }
+               if (trans_edp_pipe == crtc->pipe)
+                       pipe_config->cpu_transcoder = TRANSCODER_EDP;
+       }
+       power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
+       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+               return false;
+       *power_domain_mask |= BIT(power_domain);
+       tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
+       return tmp & PIPECONF_ENABLE;
+ }
+ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
+                                        struct intel_crtc_state *pipe_config,
+                                        unsigned long *power_domain_mask)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum intel_display_power_domain power_domain;
+       enum port port;
+       enum transcoder cpu_transcoder;
+       u32 tmp;
+       pipe_config->has_dsi_encoder = false;
+       for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) {
+               if (port == PORT_A)
+                       cpu_transcoder = TRANSCODER_DSI_A;
+               else
+                       cpu_transcoder = TRANSCODER_DSI_C;
+               power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+               if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+                       continue;
+               *power_domain_mask |= BIT(power_domain);
+               /*
+                * The PLL needs to be enabled with a valid divider
+                * configuration, otherwise accessing DSI registers will hang
+                * the machine. See BSpec North Display Engine
+                * registers/MIPI[BXT]. We can break out here early, since we
+                * need the same DSI PLL to be enabled for both DSI ports.
+                */
+               if (!intel_dsi_pll_is_enabled(dev_priv))
+                       break;
+               /* XXX: this works for video mode only */
+               tmp = I915_READ(BXT_MIPI_PORT_CTRL(port));
+               if (!(tmp & DPI_ENABLE))
+                       continue;
+               tmp = I915_READ(MIPI_CTRL(port));
+               if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe))
+                       continue;
+               pipe_config->cpu_transcoder = cpu_transcoder;
+               pipe_config->has_dsi_encoder = true;
                break;
        }
+       return pipe_config->has_dsi_encoder;
  }
  
  static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
        else
                haswell_get_ddi_pll(dev_priv, port, pipe_config);
  
-       if (pipe_config->shared_dpll >= 0) {
-               pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
-               WARN_ON(!pll->get_hw_state(dev_priv, pll,
-                                          &pipe_config->dpll_hw_state));
+       pll = pipe_config->shared_dpll;
+       if (pll) {
+               WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+                                                &pipe_config->dpll_hw_state));
        }
  
        /*
@@@ -9940,53 -9990,37 +9989,37 @@@ static bool haswell_get_pipe_config(str
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum intel_display_power_domain power_domain;
        unsigned long power_domain_mask;
-       uint32_t tmp;
-       bool ret;
+       bool active;
  
        power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
        power_domain_mask = BIT(power_domain);
  
-       ret = false;
-       pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-       pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+       pipe_config->shared_dpll = NULL;
  
-       tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
-       if (tmp & TRANS_DDI_FUNC_ENABLE) {
-               enum pipe trans_edp_pipe;
-               switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
-               default:
-                       WARN(1, "unknown pipe linked to edp transcoder\n");
-               case TRANS_DDI_EDP_INPUT_A_ONOFF:
-               case TRANS_DDI_EDP_INPUT_A_ON:
-                       trans_edp_pipe = PIPE_A;
-                       break;
-               case TRANS_DDI_EDP_INPUT_B_ONOFF:
-                       trans_edp_pipe = PIPE_B;
-                       break;
-               case TRANS_DDI_EDP_INPUT_C_ONOFF:
-                       trans_edp_pipe = PIPE_C;
-                       break;
-               }
+       active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask);
  
-               if (trans_edp_pipe == crtc->pipe)
-                       pipe_config->cpu_transcoder = TRANSCODER_EDP;
+       if (IS_BROXTON(dev_priv)) {
+               bxt_get_dsi_transcoder_state(crtc, pipe_config,
+                                            &power_domain_mask);
+               WARN_ON(active && pipe_config->has_dsi_encoder);
+               if (pipe_config->has_dsi_encoder)
+                       active = true;
        }
  
-       power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
-       if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
+       if (!active)
                goto out;
-       power_domain_mask |= BIT(power_domain);
  
-       tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
-       if (!(tmp & PIPECONF_ENABLE))
-               goto out;
+       if (!pipe_config->has_dsi_encoder) {
+               haswell_get_ddi_port_state(crtc, pipe_config);
+               intel_get_pipe_timings(crtc, pipe_config);
+       }
  
-       haswell_get_ddi_port_state(crtc, pipe_config);
+       intel_get_pipe_src_size(crtc, pipe_config);
  
-       intel_get_pipe_timings(crtc, pipe_config);
+       pipe_config->gamma_mode =
+               I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
  
        if (INTEL_INFO(dev)->gen >= 9) {
                skl_init_scalers(dev, crtc, pipe_config);
                pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
                        (I915_READ(IPS_CTL) & IPS_ENABLE);
  
-       if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
+       if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
+           !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
                pipe_config->pixel_multiplier =
                        I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
        } else {
                pipe_config->pixel_multiplier = 1;
        }
  
-       ret = true;
  out:
        for_each_power_domain(power_domain, power_domain_mask)
                intel_display_power_put(dev_priv, power_domain);
  
-       return ret;
+       return active;
  }
  
  static void i845_update_cursor(struct drm_crtc *crtc, u32 base,
@@@ -10216,21 -10249,6 +10248,6 @@@ static bool cursor_size_ok(struct drm_d
        return true;
  }
  
- static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
-                                u16 *blue, uint32_t start, uint32_t size)
- {
-       int end = (start + size > 256) ? 256 : start + size, i;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       for (i = start; i < end; i++) {
-               intel_crtc->lut_r[i] = red[i] >> 8;
-               intel_crtc->lut_g[i] = green[i] >> 8;
-               intel_crtc->lut_b[i] = blue[i] >> 8;
-       }
-       intel_crtc_load_lut(crtc);
- }
  /* VESA 640x480x72Hz mode to set on the pipe */
  static struct drm_display_mode load_detect_mode = {
        DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
@@@ -10718,19 -10736,18 +10735,18 @@@ int intel_dotclock_calculate(int link_f
  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
                                   struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  
        /* read out port_clock from the DPLL */
        i9xx_crtc_clock_get(crtc, pipe_config);
  
        /*
-        * This value does not include pixel_multiplier.
-        * We will check that port_clock and adjusted_mode.crtc_clock
-        * agree once we know their relationship in the encoder's
-        * get_config() function.
+        * In case there is an active pipe without active ports,
+        * we may need some idea for the dotclock anyway.
+        * Calculate one based on the FDI configuration.
         */
        pipe_config->base.adjusted_mode.crtc_clock =
-               intel_dotclock_calculate(intel_fdi_link_freq(dev) * 10000,
+               intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
                                         &pipe_config->fdi_m_n);
  }
  
@@@ -10849,7 -10866,7 +10865,7 @@@ static void intel_unpin_work_fn(struct 
        struct drm_plane *primary = crtc->base.primary;
  
        mutex_lock(&dev->struct_mutex);
-       intel_unpin_fb_obj(work->old_fb, primary->state);
+       intel_unpin_fb_obj(work->old_fb, primary->state->rotation);
        drm_gem_object_unreference(&work->pending_flip_obj->base);
  
        if (work->flip_queued_req)
@@@ -10923,9 -10940,10 +10939,10 @@@ static bool page_flip_finished(struct i
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned reset_counter;
  
-       if (i915_reset_in_progress(&dev_priv->gpu_error) ||
-           crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
+       reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+       if (crtc->reset_counter != reset_counter)
                return true;
  
        /*
@@@ -11003,7 -11021,7 +11020,7 @@@ static int intel_gen2_queue_flip(struc
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        u32 flip_mask;
        int ret;
                flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
        else
                flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-       intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
-       intel_ring_emit(ring, MI_NOOP);
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
+       intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
+       intel_ring_emit(engine, MI_NOOP);
+       intel_ring_emit(engine, MI_DISPLAY_FLIP |
                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
-       intel_ring_emit(ring, 0); /* aux display base address, unused */
+       intel_ring_emit(engine, fb->pitches[0]);
+       intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+       intel_ring_emit(engine, 0); /* aux display base address, unused */
  
        intel_mark_page_flip_active(intel_crtc->unpin_work);
        return 0;
@@@ -11038,7 -11056,7 +11055,7 @@@ static int intel_gen3_queue_flip(struc
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        u32 flip_mask;
        int ret;
                flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
        else
                flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-       intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
-       intel_ring_emit(ring, MI_NOOP);
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 |
+       intel_ring_emit(engine, MI_WAIT_FOR_EVENT | flip_mask);
+       intel_ring_emit(engine, MI_NOOP);
+       intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 |
                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
-       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_emit(engine, fb->pitches[0]);
+       intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+       intel_ring_emit(engine, MI_NOOP);
  
        intel_mark_page_flip_active(intel_crtc->unpin_work);
        return 0;
@@@ -11070,7 -11088,7 +11087,7 @@@ static int intel_gen4_queue_flip(struc
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t pf, pipesrc;
         * Display Registers (which do not change across a page-flip)
         * so we need only reprogram the base address.
         */
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
+       intel_ring_emit(engine, MI_DISPLAY_FLIP |
                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset |
+       intel_ring_emit(engine, fb->pitches[0]);
+       intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset |
                        obj->tiling_mode);
  
        /* XXX Enabling the panel-fitter across page-flip is so far
         */
        pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
-       intel_ring_emit(ring, pf | pipesrc);
+       intel_ring_emit(engine, pf | pipesrc);
  
        intel_mark_page_flip_active(intel_crtc->unpin_work);
        return 0;
@@@ -11109,7 -11127,7 +11126,7 @@@ static int intel_gen6_queue_flip(struc
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t pf, pipesrc;
        if (ret)
                return ret;
  
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
+       intel_ring_emit(engine, MI_DISPLAY_FLIP |
                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
+       intel_ring_emit(engine, fb->pitches[0] | obj->tiling_mode);
+       intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
  
        /* Contrary to the suggestions in the documentation,
         * "Enable Panel Fitter" does not seem to be required when page
         */
        pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
-       intel_ring_emit(ring, pf | pipesrc);
+       intel_ring_emit(engine, pf | pipesrc);
  
        intel_mark_page_flip_active(intel_crtc->unpin_work);
        return 0;
@@@ -11145,7 -11163,7 +11162,7 @@@ static int intel_gen7_queue_flip(struc
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
  {
-       struct intel_engine_cs *ring = req->ring;
+       struct intel_engine_cs *engine = req->engine;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t plane_bit = 0;
        int len, ret;
        }
  
        len = 4;
-       if (ring->id == RCS) {
+       if (engine->id == RCS) {
                len += 6;
                /*
                 * On Gen 8, SRM is now taking an extra dword to accommodate
         * for the RCS also doesn't appear to drop events. Setting the DERRMR
         * to zero does lead to lockups within MI_DISPLAY_FLIP.
         */
-       if (ring->id == RCS) {
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, DERRMR);
-               intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
-                                       DERRMR_PIPEB_PRI_FLIP_DONE |
-                                       DERRMR_PIPEC_PRI_FLIP_DONE));
+       if (engine->id == RCS) {
+               intel_ring_emit(engine, MI_LOAD_REGISTER_IMM(1));
+               intel_ring_emit_reg(engine, DERRMR);
+               intel_ring_emit(engine, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
+                                         DERRMR_PIPEB_PRI_FLIP_DONE |
+                                         DERRMR_PIPEC_PRI_FLIP_DONE));
                if (IS_GEN8(dev))
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8 |
+                       intel_ring_emit(engine, MI_STORE_REGISTER_MEM_GEN8 |
                                              MI_SRM_LRM_GLOBAL_GTT);
                else
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
+                       intel_ring_emit(engine, MI_STORE_REGISTER_MEM |
                                              MI_SRM_LRM_GLOBAL_GTT);
-               intel_ring_emit_reg(ring, DERRMR);
-               intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
+               intel_ring_emit_reg(engine, DERRMR);
+               intel_ring_emit(engine, engine->scratch.gtt_offset + 256);
                if (IS_GEN8(dev)) {
-                       intel_ring_emit(ring, 0);
-                       intel_ring_emit(ring, MI_NOOP);
+                       intel_ring_emit(engine, 0);
+                       intel_ring_emit(engine, MI_NOOP);
                }
        }
  
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
-       intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
-       intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
-       intel_ring_emit(ring, (MI_NOOP));
+       intel_ring_emit(engine, MI_DISPLAY_FLIP_I915 | plane_bit);
+       intel_ring_emit(engine, (fb->pitches[0] | obj->tiling_mode));
+       intel_ring_emit(engine, intel_crtc->unpin_work->gtt_offset);
+       intel_ring_emit(engine, (MI_NOOP));
  
        intel_mark_page_flip_active(intel_crtc->unpin_work);
        return 0;
  }
  
- static bool use_mmio_flip(struct intel_engine_cs *ring,
+ static bool use_mmio_flip(struct intel_engine_cs *engine,
                          struct drm_i915_gem_object *obj)
  {
        /*
         * So using MMIO flips there would disrupt this mechanism.
         */
  
-       if (ring == NULL)
+       if (engine == NULL)
                return true;
  
-       if (INTEL_INFO(ring->dev)->gen < 5)
+       if (INTEL_INFO(engine->dev)->gen < 5)
                return false;
  
        if (i915.use_mmio_flip < 0)
                                                       false))
                return true;
        else
-               return ring != i915_gem_request_get_ring(obj->last_write_req);
+               return engine != i915_gem_request_get_engine(obj->last_write_req);
  }
  
  static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
@@@ -11379,7 -11397,6 +11396,6 @@@ static void intel_mmio_flip_work_func(s
  
        if (mmio_flip->req) {
                WARN_ON(__i915_wait_request(mmio_flip->req,
-                                           mmio_flip->crtc->reset_counter,
                                            false, NULL,
                                            &mmio_flip->i915->rps.mmioflips));
                i915_gem_request_unreference__unlocked(mmio_flip->req);
@@@ -11507,7 -11524,7 +11523,7 @@@ static int intel_crtc_page_flip(struct 
        struct drm_plane *primary = crtc->primary;
        enum pipe pipe = intel_crtc->pipe;
        struct intel_unpin_work *work;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        bool mmio_flip;
        struct drm_i915_gem_request *request = NULL;
        int ret;
        if (ret)
                goto cleanup;
  
+       intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+       if (__i915_reset_in_progress_or_wedged(intel_crtc->reset_counter)) {
+               ret = -EIO;
+               goto cleanup;
+       }
        atomic_inc(&intel_crtc->unpin_work_count);
-       intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
  
        if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
                work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
  
        if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
-               ring = &dev_priv->ring[BCS];
+               engine = &dev_priv->engine[BCS];
                if (obj->tiling_mode != intel_fb_obj(work->old_fb)->tiling_mode)
                        /* vlv: DISPLAY_FLIP fails to change tiling */
-                       ring = NULL;
+                       engine = NULL;
        } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
-               ring = &dev_priv->ring[BCS];
+               engine = &dev_priv->engine[BCS];
        } else if (INTEL_INFO(dev)->gen >= 7) {
-               ring = i915_gem_request_get_ring(obj->last_write_req);
-               if (ring == NULL || ring->id != RCS)
-                       ring = &dev_priv->ring[BCS];
+               engine = i915_gem_request_get_engine(obj->last_write_req);
+               if (engine == NULL || engine->id != RCS)
+                       engine = &dev_priv->engine[BCS];
        } else {
-               ring = &dev_priv->ring[RCS];
+               engine = &dev_priv->engine[RCS];
        }
  
-       mmio_flip = use_mmio_flip(ring, obj);
+       mmio_flip = use_mmio_flip(engine, obj);
  
        /* When using CS flips, we want to emit semaphores between rings.
         * However, when using mmio flips we will create a task to do the
         * into the display plane and skip any waits.
         */
        if (!mmio_flip) {
-               ret = i915_gem_object_sync(obj, ring, &request);
+               ret = i915_gem_object_sync(obj, engine, &request);
                if (ret)
                        goto cleanup_pending;
        }
  
-       ret = intel_pin_and_fence_fb_obj(crtc->primary, fb,
-                                        crtc->primary->state);
+       ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
        if (ret)
                goto cleanup_pending;
  
                                        obj->last_write_req);
        } else {
                if (!request) {
-                       request = i915_gem_request_alloc(ring, NULL);
+                       request = i915_gem_request_alloc(engine, NULL);
                        if (IS_ERR(request)) {
                                ret = PTR_ERR(request);
                                goto cleanup_unpin;
        return 0;
  
  cleanup_unpin:
-       intel_unpin_fb_obj(fb, crtc->primary->state);
+       intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
  cleanup_pending:
        if (!IS_ERR_OR_NULL(request))
-               i915_gem_request_cancel(request);
+               i915_add_request_no_flush(request);
        atomic_dec(&intel_crtc->unpin_work_count);
        mutex_unlock(&dev->struct_mutex);
  cleanup:
@@@ -11725,7 -11746,7 +11745,7 @@@ retry
  
                if (ret == 0 && event) {
                        spin_lock_irq(&dev->event_lock);
-                       drm_send_vblank_event(dev, pipe, event);
+                       drm_crtc_send_vblank_event(crtc, event);
                        spin_unlock_irq(&dev->event_lock);
                }
        }
@@@ -11785,6 -11806,7 +11805,7 @@@ int intel_plane_atomic_calc_changes(str
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_plane *plane = plane_state->plane;
        struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane_state *old_plane_state =
                to_intel_plane_state(plane->state);
        int idx = intel_crtc->base.base.id, ret;
                         plane->base.id, was_visible, visible,
                         turn_off, turn_on, mode_changed);
  
-       if (turn_on || turn_off) {
-               pipe_config->wm_changed = true;
+       if (turn_on) {
+               pipe_config->update_wm_pre = true;
+               /* must disable cxsr around plane enable/disable */
+               if (plane->type != DRM_PLANE_TYPE_CURSOR)
+                       pipe_config->disable_cxsr = true;
+       } else if (turn_off) {
+               pipe_config->update_wm_post = true;
  
                /* must disable cxsr around plane enable/disable */
                if (plane->type != DRM_PLANE_TYPE_CURSOR)
                        pipe_config->disable_cxsr = true;
        } else if (intel_wm_need_update(plane, plane_state)) {
-               pipe_config->wm_changed = true;
+               /* FIXME bollocks */
+               pipe_config->update_wm_pre = true;
+               pipe_config->update_wm_post = true;
        }
  
-       if (visible || was_visible)
-               intel_crtc->atomic.fb_bits |=
-                       to_intel_plane(plane)->frontbuffer_bit;
+       /* Pre-gen9 platforms need two-step watermark updates */
+       if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) &&
+           INTEL_INFO(dev)->gen < 9 && dev_priv->display.optimize_watermarks)
+               to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true;
  
-       switch (plane->type) {
-       case DRM_PLANE_TYPE_PRIMARY:
-               intel_crtc->atomic.post_enable_primary = turn_on;
-               intel_crtc->atomic.update_fbc = true;
+       if (visible || was_visible)
+               pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit;
  
-               break;
-       case DRM_PLANE_TYPE_CURSOR:
-               break;
-       case DRM_PLANE_TYPE_OVERLAY:
-               /*
-                * WaCxSRDisabledForSpriteScaling:ivb
-                *
-                * cstate->update_wm was already set above, so this flag will
-                * take effect when we commit and program watermarks.
-                */
-               if (IS_IVYBRIDGE(dev) &&
-                   needs_scaling(to_intel_plane_state(plane_state)) &&
-                   !needs_scaling(old_plane_state))
-                       pipe_config->disable_lp_wm = true;
+       /*
+        * WaCxSRDisabledForSpriteScaling:ivb
+        *
+        * cstate->update_wm was already set above, so this flag will
+        * take effect when we commit and program watermarks.
+        */
+       if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev) &&
+           needs_scaling(to_intel_plane_state(plane_state)) &&
+           !needs_scaling(old_plane_state))
+               pipe_config->disable_lp_wm = true;
  
-               break;
-       }
        return 0;
  }
  
@@@ -11940,22 -11963,49 +11962,49 @@@ static int intel_crtc_atomic_check(stru
        }
  
        if (mode_changed && !crtc_state->active)
-               pipe_config->wm_changed = true;
+               pipe_config->update_wm_post = true;
  
        if (mode_changed && crtc_state->enable &&
            dev_priv->display.crtc_compute_clock &&
-           !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) {
+           !WARN_ON(pipe_config->shared_dpll)) {
                ret = dev_priv->display.crtc_compute_clock(intel_crtc,
                                                           pipe_config);
                if (ret)
                        return ret;
        }
  
+       if (crtc_state->color_mgmt_changed) {
+               ret = intel_color_check(crtc, crtc_state);
+               if (ret)
+                       return ret;
+       }
        ret = 0;
        if (dev_priv->display.compute_pipe_wm) {
-               ret = dev_priv->display.compute_pipe_wm(intel_crtc, state);
-               if (ret)
+               ret = dev_priv->display.compute_pipe_wm(pipe_config);
+               if (ret) {
+                       DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
+                       return ret;
+               }
+       }
+       if (dev_priv->display.compute_intermediate_wm &&
+           !to_intel_atomic_state(state)->skip_intermediate_wm) {
+               if (WARN_ON(!dev_priv->display.compute_pipe_wm))
+                       return 0;
+               /*
+                * Calculate 'intermediate' watermarks that satisfy both the
+                * old state and the new state.  We can program these
+                * immediately.
+                */
+               ret = dev_priv->display.compute_intermediate_wm(crtc->dev,
+                                                               intel_crtc,
+                                                               pipe_config);
+               if (ret) {
+                       DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n");
                        return ret;
+               }
        }
  
        if (INTEL_INFO(dev)->gen >= 9) {
  
  static const struct drm_crtc_helper_funcs intel_helper_funcs = {
        .mode_set_base_atomic = intel_pipe_set_base_atomic,
-       .load_lut = intel_crtc_load_lut,
        .atomic_begin = intel_begin_crtc_commit,
        .atomic_flush = intel_finish_crtc_commit,
        .atomic_check = intel_crtc_atomic_check,
@@@ -11983,11 -12032,16 +12031,16 @@@ static void intel_modeset_update_connec
        struct intel_connector *connector;
  
        for_each_intel_connector(dev, connector) {
+               if (connector->base.state->crtc)
+                       drm_connector_unreference(&connector->base);
                if (connector->base.encoder) {
                        connector->base.state->best_encoder =
                                connector->base.encoder;
                        connector->base.state->crtc =
                                connector->base.encoder->crtc;
+                       drm_connector_reference(&connector->base);
                } else {
                        connector->base.state->best_encoder = NULL;
                        connector->base.state->crtc = NULL;
@@@ -12089,7 -12143,7 +12142,7 @@@ static void intel_dump_pipe_config(stru
        DRM_DEBUG_KMS("[CRTC:%d]%s config %p for pipe %c\n", crtc->base.base.id,
                      context, pipe_config, pipe_name(crtc->pipe));
  
-       DRM_DEBUG_KMS("cpu_transcoder: %c\n", transcoder_name(pipe_config->cpu_transcoder));
+       DRM_DEBUG_KMS("cpu_transcoder: %s\n", transcoder_name(pipe_config->cpu_transcoder));
        DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n",
                      pipe_config->pipe_bpp, pipe_config->dither);
        DRM_DEBUG_KMS("fdi/pch: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
                              pipe_config->dpll_hw_state.cfgcr1,
                              pipe_config->dpll_hw_state.cfgcr2);
        } else if (HAS_DDI(dev)) {
-               DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
+               DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
                              pipe_config->ddi_pll_sel,
                              pipe_config->dpll_hw_state.wrpll,
                              pipe_config->dpll_hw_state.spll);
@@@ -12268,7 -12322,7 +12321,7 @@@ clear_intel_crtc_state(struct intel_crt
        struct drm_crtc_state tmp_state;
        struct intel_crtc_scaler_state scaler_state;
        struct intel_dpll_hw_state dpll_hw_state;
-       enum intel_dpll_id shared_dpll;
+       struct intel_shared_dpll *shared_dpll;
        uint32_t ddi_pll_sel;
        bool force_thru;
  
@@@ -12538,6 -12592,15 +12591,15 @@@ intel_pipe_config_compare(struct drm_de
                ret = false; \
        }
  
+ #define PIPE_CONF_CHECK_P(name)       \
+       if (current_config->name != pipe_config->name) { \
+               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+                         "(expected %p, found %p)\n", \
+                         current_config->name, \
+                         pipe_config->name); \
+               ret = false; \
+       }
  #define PIPE_CONF_CHECK_M_N(name) \
        if (!intel_compare_link_m_n(&current_config->name, \
                                    &pipe_config->name,\
                ret = false; \
        }
  
+ /* This is required for BDW+ where there is only one set of registers for
+  * switching between high and low RR.
+  * This macro can be used whenever a comparison has to be made between one
+  * hw state and multiple sw state variables.
+  */
  #define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
        if (!intel_compare_link_m_n(&current_config->name, \
                                    &pipe_config->name, adjust) && \
                ret = false; \
        }
  
- /* This is required for BDW+ where there is only one set of registers for
-  * switching between high and low RR.
-  * This macro can be used whenever a comparison has to be made between one
-  * hw state and multiple sw state variables.
-  */
- #define PIPE_CONF_CHECK_I_ALT(name, alt_name) \
-       if ((current_config->name != pipe_config->name) && \
-               (current_config->alt_name != pipe_config->name)) { \
-                       INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
-                                 "(expected %i or %i, found %i)\n", \
-                                 current_config->name, \
-                                 current_config->alt_name, \
-                                 pipe_config->name); \
-                       ret = false; \
-       }
  #define PIPE_CONF_CHECK_FLAGS(name, mask)     \
        if ((current_config->name ^ pipe_config->name) & (mask)) { \
                INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
        PIPE_CONF_CHECK_X(gmch_pfit.control);
        /* pfit ratios are autocomputed by the hw on gen4+ */
        if (INTEL_INFO(dev)->gen < 4)
-               PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+               PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
        PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
  
        if (!adjust) {
  
        PIPE_CONF_CHECK_X(ddi_pll_sel);
  
-       PIPE_CONF_CHECK_I(shared_dpll);
+       PIPE_CONF_CHECK_P(shared_dpll);
        PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
        PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
        PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
        PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
        PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
  
+       PIPE_CONF_CHECK_X(dsi_pll.ctrl);
+       PIPE_CONF_CHECK_X(dsi_pll.div);
        if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
                PIPE_CONF_CHECK_I(pipe_bpp);
  
  
  #undef PIPE_CONF_CHECK_X
  #undef PIPE_CONF_CHECK_I
- #undef PIPE_CONF_CHECK_I_ALT
+ #undef PIPE_CONF_CHECK_P
  #undef PIPE_CONF_CHECK_FLAGS
  #undef PIPE_CONF_CHECK_CLOCK_FUZZY
  #undef PIPE_CONF_QUIRK
        return ret;
  }
  
- static void check_wm_state(struct drm_device *dev)
+ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
+                                          const struct intel_crtc_state *pipe_config)
+ {
+       if (pipe_config->has_pch_encoder) {
+               int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
+                                                           &pipe_config->fdi_m_n);
+               int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
+               /*
+                * FDI already provided one idea for the dotclock.
+                * Yell if the encoder disagrees.
+                */
+               WARN(!intel_fuzzy_clock_check(fdi_dotclock, dotclock),
+                    "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
+                    fdi_dotclock, dotclock);
+       }
+ }
+ static void verify_wm_state(struct drm_crtc *crtc,
+                           struct drm_crtc_state *new_state)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct skl_ddb_allocation hw_ddb, *sw_ddb;
-       struct intel_crtc *intel_crtc;
+       struct skl_ddb_entry *hw_entry, *sw_entry;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       const enum pipe pipe = intel_crtc->pipe;
        int plane;
  
-       if (INTEL_INFO(dev)->gen < 9)
+       if (INTEL_INFO(dev)->gen < 9 || !new_state->active)
                return;
  
        skl_ddb_get_hw_state(dev_priv, &hw_ddb);
        sw_ddb = &dev_priv->wm.skl_hw.ddb;
  
-       for_each_intel_crtc(dev, intel_crtc) {
-               struct skl_ddb_entry *hw_entry, *sw_entry;
-               const enum pipe pipe = intel_crtc->pipe;
+       /* planes */
+       for_each_plane(dev_priv, pipe, plane) {
+               hw_entry = &hw_ddb.plane[pipe][plane];
+               sw_entry = &sw_ddb->plane[pipe][plane];
  
-               if (!intel_crtc->active)
+               if (skl_ddb_entry_equal(hw_entry, sw_entry))
                        continue;
  
-               /* planes */
-               for_each_plane(dev_priv, pipe, plane) {
-                       hw_entry = &hw_ddb.plane[pipe][plane];
-                       sw_entry = &sw_ddb->plane[pipe][plane];
-                       if (skl_ddb_entry_equal(hw_entry, sw_entry))
-                               continue;
-                       DRM_ERROR("mismatch in DDB state pipe %c plane %d "
-                                 "(expected (%u,%u), found (%u,%u))\n",
-                                 pipe_name(pipe), plane + 1,
-                                 sw_entry->start, sw_entry->end,
-                                 hw_entry->start, hw_entry->end);
-               }
-               /* cursor */
-               hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
-               sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+               DRM_ERROR("mismatch in DDB state pipe %c plane %d "
+                         "(expected (%u,%u), found (%u,%u))\n",
+                         pipe_name(pipe), plane + 1,
+                         sw_entry->start, sw_entry->end,
+                         hw_entry->start, hw_entry->end);
+       }
  
-               if (skl_ddb_entry_equal(hw_entry, sw_entry))
-                       continue;
+       /* cursor */
+       hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
+       sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
  
+       if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
                DRM_ERROR("mismatch in DDB state pipe %c cursor "
                          "(expected (%u,%u), found (%u,%u))\n",
                          pipe_name(pipe),
  }
  
  static void
- check_connector_state(struct drm_device *dev,
-                     struct drm_atomic_state *old_state)
+ verify_connector_state(struct drm_device *dev, struct drm_crtc *crtc)
  {
-       struct drm_connector_state *old_conn_state;
        struct drm_connector *connector;
-       int i;
  
-       for_each_connector_in_state(old_state, connector, old_conn_state, i) {
+       drm_for_each_connector(connector, dev) {
                struct drm_encoder *encoder = connector->encoder;
                struct drm_connector_state *state = connector->state;
  
-               /* This also checks the encoder/connector hw state with the
-                * ->get_hw_state callbacks. */
-               intel_connector_check_state(to_intel_connector(connector));
+               if (state->crtc != crtc)
+                       continue;
+               intel_connector_verify_state(to_intel_connector(connector));
  
                I915_STATE_WARN(state->best_encoder != encoder,
                     "connector's atomic encoder doesn't match legacy encoder\n");
  }
  
  static void
check_encoder_state(struct drm_device *dev)
verify_encoder_state(struct drm_device *dev)
  {
        struct intel_encoder *encoder;
        struct intel_connector *connector;
  }
  
  static void
- check_crtc_state(struct drm_device *dev, struct drm_atomic_state *old_state)
+ verify_crtc_state(struct drm_crtc *crtc,
+                 struct drm_crtc_state *old_crtc_state,
+                 struct drm_crtc_state *new_crtc_state)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
-       struct drm_crtc_state *old_crtc_state;
-       struct drm_crtc *crtc;
-       int i;
-       for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
-               struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-               struct intel_crtc_state *pipe_config, *sw_config;
-               bool active;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc_state *pipe_config, *sw_config;
+       struct drm_atomic_state *old_state;
+       bool active;
  
-               if (!needs_modeset(crtc->state) &&
-                   !to_intel_crtc_state(crtc->state)->update_pipe)
-                       continue;
+       old_state = old_crtc_state->state;
+       __drm_atomic_helper_crtc_destroy_state(old_crtc_state);
+       pipe_config = to_intel_crtc_state(old_crtc_state);
+       memset(pipe_config, 0, sizeof(*pipe_config));
+       pipe_config->base.crtc = crtc;
+       pipe_config->base.state = old_state;
  
-               __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state);
-               pipe_config = to_intel_crtc_state(old_crtc_state);
-               memset(pipe_config, 0, sizeof(*pipe_config));
-               pipe_config->base.crtc = crtc;
-               pipe_config->base.state = old_state;
+       DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
  
-               DRM_DEBUG_KMS("[CRTC:%d]\n",
-                             crtc->base.id);
+       active = dev_priv->display.get_pipe_config(intel_crtc, pipe_config);
  
-               active = dev_priv->display.get_pipe_config(intel_crtc,
-                                                          pipe_config);
+       /* hw state is inconsistent with the pipe quirk */
+       if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+           (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+               active = new_crtc_state->active;
  
-               /* hw state is inconsistent with the pipe quirk */
-               if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
-                   (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
-                       active = crtc->state->active;
+       I915_STATE_WARN(new_crtc_state->active != active,
+            "crtc active state doesn't match with hw state "
+            "(expected %i, found %i)\n", new_crtc_state->active, active);
  
-               I915_STATE_WARN(crtc->state->active != active,
-                    "crtc active state doesn't match with hw state "
-                    "(expected %i, found %i)\n", crtc->state->active, active);
+       I915_STATE_WARN(intel_crtc->active != new_crtc_state->active,
+            "transitional active state does not match atomic hw state "
+            "(expected %i, found %i)\n", new_crtc_state->active, intel_crtc->active);
  
-               I915_STATE_WARN(intel_crtc->active != crtc->state->active,
-                    "transitional active state does not match atomic hw state "
-                    "(expected %i, found %i)\n", crtc->state->active, intel_crtc->active);
+       for_each_encoder_on_crtc(dev, crtc, encoder) {
+               enum pipe pipe;
  
-               for_each_encoder_on_crtc(dev, crtc, encoder) {
-                       enum pipe pipe;
+               active = encoder->get_hw_state(encoder, &pipe);
+               I915_STATE_WARN(active != new_crtc_state->active,
+                       "[ENCODER:%i] active %i with crtc active %i\n",
+                       encoder->base.base.id, active, new_crtc_state->active);
  
-                       active = encoder->get_hw_state(encoder, &pipe);
-                       I915_STATE_WARN(active != crtc->state->active,
-                               "[ENCODER:%i] active %i with crtc active %i\n",
-                               encoder->base.base.id, active, crtc->state->active);
+               I915_STATE_WARN(active && intel_crtc->pipe != pipe,
+                               "Encoder connected to wrong pipe %c\n",
+                               pipe_name(pipe));
  
-                       I915_STATE_WARN(active && intel_crtc->pipe != pipe,
-                                       "Encoder connected to wrong pipe %c\n",
-                                       pipe_name(pipe));
+               if (active)
+                       encoder->get_config(encoder, pipe_config);
+       }
  
-                       if (active)
-                               encoder->get_config(encoder, pipe_config);
-               }
+       if (!new_crtc_state->active)
+               return;
  
-               if (!crtc->state->active)
-                       continue;
+       intel_pipe_config_sanity_check(dev_priv, pipe_config);
  
-               sw_config = to_intel_crtc_state(crtc->state);
-               if (!intel_pipe_config_compare(dev, sw_config,
-                                              pipe_config, false)) {
-                       I915_STATE_WARN(1, "pipe state doesn't match!\n");
-                       intel_dump_pipe_config(intel_crtc, pipe_config,
-                                              "[hw state]");
-                       intel_dump_pipe_config(intel_crtc, sw_config,
-                                              "[sw state]");
-               }
+       sw_config = to_intel_crtc_state(crtc->state);
+       if (!intel_pipe_config_compare(dev, sw_config,
+                                      pipe_config, false)) {
+               I915_STATE_WARN(1, "pipe state doesn't match!\n");
+               intel_dump_pipe_config(intel_crtc, pipe_config,
+                                      "[hw state]");
+               intel_dump_pipe_config(intel_crtc, sw_config,
+                                      "[sw state]");
        }
  }
  
  static void
- check_shared_dpll_state(struct drm_device *dev)
+ verify_single_dpll_state(struct drm_i915_private *dev_priv,
+                        struct intel_shared_dpll *pll,
+                        struct drm_crtc *crtc,
+                        struct drm_crtc_state *new_state)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *crtc;
        struct intel_dpll_hw_state dpll_hw_state;
-       int i;
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
-               int enabled_crtcs = 0, active_crtcs = 0;
-               bool active;
+       unsigned crtc_mask;
+       bool active;
  
-               memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
+       memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
  
-               DRM_DEBUG_KMS("%s\n", pll->name);
+       DRM_DEBUG_KMS("%s\n", pll->name);
  
-               active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
+       active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
  
-               I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask),
-                    "more active pll users than references: %i vs %i\n",
-                    pll->active, hweight32(pll->config.crtc_mask));
-               I915_STATE_WARN(pll->active && !pll->on,
+       if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) {
+               I915_STATE_WARN(!pll->on && pll->active_mask,
                     "pll in active use but not on in sw tracking\n");
-               I915_STATE_WARN(pll->on && !pll->active,
-                    "pll in on but not on in use in sw tracking\n");
+               I915_STATE_WARN(pll->on && !pll->active_mask,
+                    "pll is on but not used by any active crtc\n");
                I915_STATE_WARN(pll->on != active,
                     "pll on state mismatch (expected %i, found %i)\n",
                     pll->on, active);
+       }
  
-               for_each_intel_crtc(dev, crtc) {
-                       if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
-                               enabled_crtcs++;
-                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
-                               active_crtcs++;
-               }
-               I915_STATE_WARN(pll->active != active_crtcs,
-                    "pll active crtcs mismatch (expected %i, found %i)\n",
-                    pll->active, active_crtcs);
-               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
-                    "pll enabled crtcs mismatch (expected %i, found %i)\n",
-                    hweight32(pll->config.crtc_mask), enabled_crtcs);
+       if (!crtc) {
+               I915_STATE_WARN(pll->active_mask & ~pll->config.crtc_mask,
+                               "more active pll users than references: %x vs %x\n",
+                               pll->active_mask, pll->config.crtc_mask);
+               return;
+       }
+       crtc_mask = 1 << drm_crtc_index(crtc);
+       if (new_state->active)
+               I915_STATE_WARN(!(pll->active_mask & crtc_mask),
+                               "pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
+                               pipe_name(drm_crtc_index(crtc)), pll->active_mask);
+       else
+               I915_STATE_WARN(pll->active_mask & crtc_mask,
+                               "pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n",
+                               pipe_name(drm_crtc_index(crtc)), pll->active_mask);
+       I915_STATE_WARN(!(pll->config.crtc_mask & crtc_mask),
+                       "pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n",
+                       crtc_mask, pll->config.crtc_mask);
+       I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state,
+                                         &dpll_hw_state,
+                                         sizeof(dpll_hw_state)),
+                       "pll hw state mismatch\n");
+ }
+ static void
+ verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc,
+                        struct drm_crtc_state *old_crtc_state,
+                        struct drm_crtc_state *new_crtc_state)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc_state *old_state = to_intel_crtc_state(old_crtc_state);
+       struct intel_crtc_state *new_state = to_intel_crtc_state(new_crtc_state);
+       if (new_state->shared_dpll)
+               verify_single_dpll_state(dev_priv, new_state->shared_dpll, crtc, new_crtc_state);
+       if (old_state->shared_dpll &&
+           old_state->shared_dpll != new_state->shared_dpll) {
+               unsigned crtc_mask = 1 << drm_crtc_index(crtc);
+               struct intel_shared_dpll *pll = old_state->shared_dpll;
  
-               I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state,
-                                      sizeof(dpll_hw_state)),
-                    "pll hw state mismatch\n");
+               I915_STATE_WARN(pll->active_mask & crtc_mask,
+                               "pll active mismatch (didn't expect pipe %c in active mask)\n",
+                               pipe_name(drm_crtc_index(crtc)));
+               I915_STATE_WARN(pll->config.crtc_mask & crtc_mask,
+                               "pll enabled crtcs mismatch (found %x in enabled mask)\n",
+                               pipe_name(drm_crtc_index(crtc)));
        }
  }
  
  static void
- intel_modeset_check_state(struct drm_device *dev,
-                         struct drm_atomic_state *old_state)
+ intel_modeset_verify_crtc(struct drm_crtc *crtc,
+                        struct drm_crtc_state *old_state,
+                        struct drm_crtc_state *new_state)
  {
-       check_wm_state(dev);
-       check_connector_state(dev, old_state);
-       check_encoder_state(dev);
-       check_crtc_state(dev, old_state);
-       check_shared_dpll_state(dev);
+       if (!needs_modeset(new_state) &&
+           !to_intel_crtc_state(new_state)->update_pipe)
+               return;
+       verify_wm_state(crtc, new_state);
+       verify_connector_state(crtc->dev, crtc);
+       verify_crtc_state(crtc, old_state, new_state);
+       verify_shared_dpll_state(crtc->dev, crtc, old_state, new_state);
  }
  
- void ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
                                   int dotclock)
+ static void
verify_disabled_dpll_state(struct drm_device *dev)
  {
-       /*
-        * FDI already provided one idea for the dotclock.
-        * Yell if the encoder disagrees.
-        */
-       WARN(!intel_fuzzy_clock_check(pipe_config->base.adjusted_mode.crtc_clock, dotclock),
-            "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
-            pipe_config->base.adjusted_mode.crtc_clock, dotclock);
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int i;
+       for (i = 0; i < dev_priv->num_shared_dpll; i++)
+               verify_single_dpll_state(dev_priv, &dev_priv->shared_dplls[i], NULL, NULL);
+ }
+ static void
+ intel_modeset_verify_disabled(struct drm_device *dev)
+ {
+       verify_encoder_state(dev);
+       verify_connector_state(dev, NULL);
+       verify_disabled_dpll_state(dev);
  }
  
  static void update_scanline_offset(struct intel_crtc *crtc)
@@@ -13042,20 -13145,21 +13144,21 @@@ static void intel_modeset_clear_plls(st
  
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-               int old_dpll = to_intel_crtc_state(crtc->state)->shared_dpll;
+               struct intel_shared_dpll *old_dpll =
+                       to_intel_crtc_state(crtc->state)->shared_dpll;
  
                if (!needs_modeset(crtc_state))
                        continue;
  
-               to_intel_crtc_state(crtc_state)->shared_dpll = DPLL_ID_PRIVATE;
+               to_intel_crtc_state(crtc_state)->shared_dpll = NULL;
  
-               if (old_dpll == DPLL_ID_PRIVATE)
+               if (!old_dpll)
                        continue;
  
                if (!shared_dpll)
                        shared_dpll = intel_atomic_get_shared_dpll_state(state);
  
-               shared_dpll[old_dpll].crtc_mask &= ~(1 << intel_crtc->pipe);
+               intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
        }
  }
  
@@@ -13267,9 -13371,6 +13370,6 @@@ static int intel_atomic_check(struct dr
                struct intel_crtc_state *pipe_config =
                        to_intel_crtc_state(crtc_state);
  
-               memset(&to_intel_crtc(crtc)->atomic, 0,
-                      sizeof(struct intel_crtc_atomic_commit));
                /* Catch I915_MODE_FLAG_INHERITED */
                if (crtc_state->mode.private_flags != crtc->state->mode.private_flags)
                        crtc_state->mode_changed = true;
  
  static int intel_atomic_prepare_commit(struct drm_device *dev,
                                       struct drm_atomic_state *state,
-                                      bool async)
+                                      bool nonblock)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_plane_state *plane_state;
        struct drm_crtc *crtc;
        int i, ret;
  
-       if (async) {
-               DRM_DEBUG_KMS("i915 does not yet support async commit\n");
+       if (nonblock) {
+               DRM_DEBUG_KMS("i915 does not yet support nonblocking commit\n");
                return -EINVAL;
        }
  
                return ret;
  
        ret = drm_atomic_helper_prepare_planes(dev, state);
-       if (!ret && !async && !i915_reset_in_progress(&dev_priv->gpu_error)) {
-               u32 reset_counter;
-               reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
-               mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->struct_mutex);
  
+       if (!ret && !nonblock) {
                for_each_plane_in_state(state, plane, plane_state, i) {
                        struct intel_plane_state *intel_plane_state =
                                to_intel_plane_state(plane_state);
                                continue;
  
                        ret = __i915_wait_request(intel_plane_state->wait_req,
-                                                 reset_counter, true,
-                                                 NULL, NULL);
-                       /* Swallow -EIO errors to allow updates during hw lockup. */
-                       if (ret == -EIO)
-                               ret = 0;
-                       if (ret)
+                                                 true, NULL, NULL);
+                       if (ret) {
+                               /* Any hang should be swallowed by the wait */
+                               WARN_ON(ret == -EIO);
+                               mutex_lock(&dev->struct_mutex);
+                               drm_atomic_helper_cleanup_planes(dev, state);
+                               mutex_unlock(&dev->struct_mutex);
                                break;
+                       }
                }
-               if (!ret)
-                       return 0;
-               mutex_lock(&dev->struct_mutex);
-               drm_atomic_helper_cleanup_planes(dev, state);
        }
  
-       mutex_unlock(&dev->struct_mutex);
        return ret;
  }
  
@@@ -13440,7 -13531,7 +13530,7 @@@ static void intel_atomic_wait_for_vblan
                                        drm_crtc_vblank_count(crtc),
                                msecs_to_jiffies(50));
  
-               WARN_ON(!lret);
+               WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe));
  
                drm_crtc_vblank_put(crtc);
        }
@@@ -13453,12 -13544,12 +13543,12 @@@ static bool needs_vblank_wait(struct in
                return true;
  
        /* wm changes, need vblank before final wm's */
-       if (crtc_state->wm_changed)
+       if (crtc_state->update_wm_post)
                return true;
  
        /*
         * cxsr is re-enabled after vblank.
-        * This is already handled by crtc_state->wm_changed,
+        * This is already handled by crtc_state->update_wm_post,
         * but added for clarity.
         */
        if (crtc_state->disable_cxsr)
   * intel_atomic_commit - commit validated state object
   * @dev: DRM device
   * @state: the top-level driver state object
-  * @async: asynchronous commit
+  * @nonblock: nonblocking commit
   *
   * This function commits a top-level state object that has been validated
   * with drm_atomic_helper_check().
   *
   * FIXME:  Atomic modeset support for i915 is not yet complete.  At the moment
   * we can only handle plane-related operations and do not yet support
-  * asynchronous commit.
+  * nonblocking commit.
   *
   * RETURNS
   * Zero for success or -errno.
   */
  static int intel_atomic_commit(struct drm_device *dev,
                               struct drm_atomic_state *state,
-                              bool async)
+                              bool nonblock)
  {
        struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_crtc_state *crtc_state;
+       struct drm_crtc_state *old_crtc_state;
        struct drm_crtc *crtc;
+       struct intel_crtc_state *intel_cstate;
        int ret = 0, i;
        bool hw_check = intel_state->modeset;
        unsigned long put_domains[I915_MAX_PIPES] = {};
        unsigned crtc_vblank_mask = 0;
  
-       ret = intel_atomic_prepare_commit(dev, state, async);
+       ret = intel_atomic_prepare_commit(dev, state, nonblock);
        if (ret) {
                DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
                return ret;
        }
  
        drm_atomic_helper_swap_state(dev, state);
-       dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
+       dev_priv->wm.config = intel_state->wm_config;
+       intel_shared_dpll_commit(state);
  
        if (intel_state->modeset) {
                memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
                intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
        }
  
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+       for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  
                if (needs_modeset(crtc->state) ||
                if (!needs_modeset(crtc->state))
                        continue;
  
-               intel_pre_plane_update(to_intel_crtc_state(crtc_state));
+               intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
  
-               if (crtc_state->active) {
-                       intel_crtc_disable_planes(crtc, crtc_state->plane_mask);
+               if (old_crtc_state->active) {
+                       intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask);
                        dev_priv->display.crtc_disable(crtc);
                        intel_crtc->active = false;
                        intel_fbc_disable(intel_crtc);
        intel_modeset_update_crtc_state(state);
  
        if (intel_state->modeset) {
-               intel_shared_dpll_commit(state);
                drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
  
                if (dev_priv->display.modeset_commit_cdclk &&
                    intel_state->dev_cdclk != dev_priv->cdclk_freq)
                        dev_priv->display.modeset_commit_cdclk(state);
+               intel_modeset_verify_disabled(dev);
        }
  
        /* Now enable the clocks, plane, pipe, and connectors that we set up. */
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+       for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
                bool modeset = needs_modeset(crtc->state);
                struct intel_crtc_state *pipe_config =
                }
  
                if (!modeset)
-                       intel_pre_plane_update(to_intel_crtc_state(crtc_state));
+                       intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
  
-               if (crtc->state->active && intel_crtc->atomic.update_fbc)
+               if (crtc->state->active &&
+                   drm_atomic_get_existing_plane_state(state, crtc->primary))
                        intel_fbc_enable(intel_crtc);
  
                if (crtc->state->active &&
                    (crtc->state->planes_changed || update_pipe))
-                       drm_atomic_helper_commit_planes_on_crtc(crtc_state);
+                       drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
  
                if (pipe_config->base.active && needs_vblank_wait(pipe_config))
                        crtc_vblank_mask |= 1 << i;
        if (!state->legacy_cursor_update)
                intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
  
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               intel_post_plane_update(to_intel_crtc(crtc));
+       /*
+        * Now that the vblank has passed, we can go ahead and program the
+        * optimal watermarks on platforms that need two-step watermark
+        * programming.
+        *
+        * TODO: Move this (and other cleanup) to an async worker eventually.
+        */
+       for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+               intel_cstate = to_intel_crtc_state(crtc->state);
+               if (dev_priv->display.optimize_watermarks)
+                       dev_priv->display.optimize_watermarks(intel_cstate);
+       }
+       for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+               intel_post_plane_update(to_intel_crtc_state(old_crtc_state));
  
                if (put_domains[i])
                        modeset_put_power_domains(dev_priv, put_domains[i]);
+               intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
        }
  
        if (intel_state->modeset)
        drm_atomic_helper_cleanup_planes(dev, state);
        mutex_unlock(&dev->struct_mutex);
  
-       if (hw_check)
-               intel_modeset_check_state(dev, state);
        drm_atomic_state_free(state);
  
        /* As one of the primary mmio accessors, KMS has a high likelihood
  #undef for_each_intel_crtc_masked
  
  static const struct drm_crtc_funcs intel_crtc_funcs = {
-       .gamma_set = intel_crtc_gamma_set,
+       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .set_config = drm_atomic_helper_set_config,
+       .set_property = drm_atomic_helper_crtc_set_property,
        .destroy = intel_crtc_destroy,
        .page_flip = intel_crtc_page_flip,
        .atomic_duplicate_state = intel_crtc_duplicate_state,
        .atomic_destroy_state = intel_crtc_destroy_state,
  };
  
- static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
-                                     struct intel_shared_dpll *pll,
-                                     struct intel_dpll_hw_state *hw_state)
- {
-       uint32_t val;
-       if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-               return false;
-       val = I915_READ(PCH_DPLL(pll->id));
-       hw_state->dpll = val;
-       hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
-       hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-       return val & DPLL_VCO_ENABLE;
- }
- static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
-                                 struct intel_shared_dpll *pll)
- {
-       I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
-       I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
- }
- static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
-                               struct intel_shared_dpll *pll)
- {
-       /* PCH refclock must be enabled first */
-       ibx_assert_pch_refclk_enabled(dev_priv);
-       I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
-       /* Wait for the clocks to stabilize. */
-       POSTING_READ(PCH_DPLL(pll->id));
-       udelay(150);
-       /* The pixel multiplier can only be updated once the
-        * DPLL is enabled and the clocks are stable.
-        *
-        * So write it again.
-        */
-       I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
-       POSTING_READ(PCH_DPLL(pll->id));
-       udelay(200);
- }
- static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
-                                struct intel_shared_dpll *pll)
- {
-       struct drm_device *dev = dev_priv->dev;
-       struct intel_crtc *crtc;
-       /* Make sure no transcoder isn't still depending on us. */
-       for_each_intel_crtc(dev, crtc) {
-               if (intel_crtc_to_shared_dpll(crtc) == pll)
-                       assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
-       }
-       I915_WRITE(PCH_DPLL(pll->id), 0);
-       POSTING_READ(PCH_DPLL(pll->id));
-       udelay(200);
- }
- static char *ibx_pch_dpll_names[] = {
-       "PCH DPLL A",
-       "PCH DPLL B",
- };
- static void ibx_pch_dpll_init(struct drm_device *dev)
- {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int i;
-       dev_priv->num_shared_dpll = 2;
-       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-               dev_priv->shared_dplls[i].id = i;
-               dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
-               dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
-               dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
-               dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
-               dev_priv->shared_dplls[i].get_hw_state =
-                       ibx_pch_dpll_get_hw_state;
-       }
- }
- static void intel_shared_dpll_init(struct drm_device *dev)
- {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       if (HAS_DDI(dev))
-               intel_ddi_pll_init(dev);
-       else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
-               ibx_pch_dpll_init(dev);
-       else
-               dev_priv->num_shared_dpll = 0;
-       BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
- }
  /**
   * intel_prepare_plane_fb - Prepare fb for usage on plane
   * @plane: drm plane to prepare for
@@@ -13827,10 -13833,11 +13832,11 @@@ intel_prepare_plane_fb(struct drm_plan
                 */
                if (needs_modeset(crtc_state))
                        ret = i915_gem_object_wait_rendering(old_obj, true);
-               /* Swallow -EIO errors to allow updates during hw lockup. */
-               if (ret && ret != -EIO)
+               if (ret) {
+                       /* GPU hangs should have been swallowed by the wait */
+                       WARN_ON(ret == -EIO);
                        return ret;
+               }
        }
  
        /* For framebuffer backed by dmabuf, wait for fence */
                if (ret)
                        DRM_DEBUG_KMS("failed to attach phys object\n");
        } else {
-               ret = intel_pin_and_fence_fb_obj(plane, fb, new_state);
+               ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
        }
  
        if (ret == 0) {
@@@ -13899,7 -13906,7 +13905,7 @@@ intel_cleanup_plane_fb(struct drm_plan
  
        if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
            !INTEL_INFO(dev)->cursor_needs_physical))
-               intel_unpin_fb_obj(old_state->fb, old_state);
+               intel_unpin_fb_obj(old_state->fb, old_state->rotation);
  
        /* prepare_fb aborted? */
        if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
                i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
  
        i915_gem_request_assign(&old_intel_state->wait_req, NULL);
  }
  
  int
@@@ -13982,6 -13988,11 +13987,11 @@@ static void intel_begin_crtc_commit(str
        if (modeset)
                return;
  
+       if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) {
+               intel_color_set_csc(crtc->state);
+               intel_color_load_luts(crtc->state);
+       }
        if (to_intel_crtc_state(crtc->state)->update_pipe)
                intel_update_pipe_config(intel_crtc, old_intel_state);
        else if (INTEL_INFO(dev)->gen >= 9)
@@@ -14025,20 -14036,19 +14035,19 @@@ const struct drm_plane_funcs intel_plan
  static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
                                                    int pipe)
  {
-       struct intel_plane *primary;
-       struct intel_plane_state *state;
+       struct intel_plane *primary = NULL;
+       struct intel_plane_state *state = NULL;
        const uint32_t *intel_primary_formats;
        unsigned int num_formats;
+       int ret;
  
        primary = kzalloc(sizeof(*primary), GFP_KERNEL);
-       if (primary == NULL)
-               return NULL;
+       if (!primary)
+               goto fail;
  
        state = intel_create_plane_state(&primary->base);
-       if (!state) {
-               kfree(primary);
-               return NULL;
-       }
+       if (!state)
+               goto fail;
        primary->base.state = &state->base;
  
        primary->can_scale = false;
                primary->disable_plane = i9xx_disable_primary_plane;
        }
  
-       drm_universal_plane_init(dev, &primary->base, 0,
-                                &intel_plane_funcs,
-                                intel_primary_formats, num_formats,
-                                DRM_PLANE_TYPE_PRIMARY, NULL);
+       ret = drm_universal_plane_init(dev, &primary->base, 0,
+                                      &intel_plane_funcs,
+                                      intel_primary_formats, num_formats,
+                                      DRM_PLANE_TYPE_PRIMARY, NULL);
+       if (ret)
+               goto fail;
  
        if (INTEL_INFO(dev)->gen >= 4)
                intel_create_rotation_property(dev, primary);
        drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
  
        return &primary->base;
+ fail:
+       kfree(state);
+       kfree(primary);
+       return NULL;
  }
  
  void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane)
@@@ -14207,18 -14225,17 +14224,17 @@@ intel_update_cursor_plane(struct drm_pl
  static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
                                                   int pipe)
  {
-       struct intel_plane *cursor;
-       struct intel_plane_state *state;
+       struct intel_plane *cursor = NULL;
+       struct intel_plane_state *state = NULL;
+       int ret;
  
        cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
-       if (cursor == NULL)
-               return NULL;
+       if (!cursor)
+               goto fail;
  
        state = intel_create_plane_state(&cursor->base);
-       if (!state) {
-               kfree(cursor);
-               return NULL;
-       }
+       if (!state)
+               goto fail;
        cursor->base.state = &state->base;
  
        cursor->can_scale = false;
        cursor->update_plane = intel_update_cursor_plane;
        cursor->disable_plane = intel_disable_cursor_plane;
  
-       drm_universal_plane_init(dev, &cursor->base, 0,
-                                &intel_plane_funcs,
-                                intel_cursor_formats,
-                                ARRAY_SIZE(intel_cursor_formats),
-                                DRM_PLANE_TYPE_CURSOR, NULL);
+       ret = drm_universal_plane_init(dev, &cursor->base, 0,
+                                      &intel_plane_funcs,
+                                      intel_cursor_formats,
+                                      ARRAY_SIZE(intel_cursor_formats),
+                                      DRM_PLANE_TYPE_CURSOR, NULL);
+       if (ret)
+               goto fail;
  
        if (INTEL_INFO(dev)->gen >= 4) {
                if (!dev->mode_config.rotation_property)
        drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
  
        return &cursor->base;
+ fail:
+       kfree(state);
+       kfree(cursor);
+       return NULL;
  }
  
  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
@@@ -14279,7 -14304,7 +14303,7 @@@ static void intel_crtc_init(struct drm_
        struct intel_crtc_state *crtc_state = NULL;
        struct drm_plane *primary = NULL;
        struct drm_plane *cursor = NULL;
-       int i, ret;
+       int ret;
  
        intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
        if (intel_crtc == NULL)
        if (ret)
                goto fail;
  
-       drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
-       for (i = 0; i < 256; i++) {
-               intel_crtc->lut_r[i] = i;
-               intel_crtc->lut_g[i] = i;
-               intel_crtc->lut_b[i] = i;
-       }
        /*
         * On gen2/3 only plane A can do fbc, but the panel fitter and lvds port
         * is hooked to pipe B. Hence we want plane A feeding pipe B.
  
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
  
+       intel_color_init(&intel_crtc->base);
        WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
        return;
  
@@@ -14470,6 -14490,8 +14489,8 @@@ static void intel_setup_outputs(struct 
                intel_ddi_init(dev, PORT_A);
                intel_ddi_init(dev, PORT_B);
                intel_ddi_init(dev, PORT_C);
+               intel_dsi_init(dev);
        } else if (HAS_DDI(dev)) {
                int found;
  
@@@ -14839,6 -14861,8 +14860,8 @@@ static int intel_framebuffer_init(struc
        drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
        intel_fb->obj = obj;
  
+       intel_fill_fb_info(dev_priv, &intel_fb->base);
        ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
        if (ret) {
                DRM_ERROR("framebuffer init failed %d\n", ret);
@@@ -14859,8 -14883,7 +14882,7 @@@ intel_user_framebuffer_create(struct dr
        struct drm_i915_gem_object *obj;
        struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
  
-       obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
-                                               mode_cmd.handles[0]));
+       obj = to_intel_bo(drm_gem_object_lookup(filp, mode_cmd.handles[0]));
        if (&obj->base == NULL)
                return ERR_PTR(-ENOENT);
  
@@@ -14886,23 -14909,13 +14908,13 @@@ static const struct drm_mode_config_fun
        .atomic_state_clear = intel_atomic_state_clear,
  };
  
- /* Set up chip specific display functions */
- static void intel_init_display(struct drm_device *dev)
+ /**
+  * intel_init_display_hooks - initialize the display modesetting hooks
+  * @dev_priv: device private
+  */
+ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       if (HAS_PCH_SPLIT(dev) || IS_G4X(dev))
-               dev_priv->display.find_dpll = g4x_find_best_dpll;
-       else if (IS_CHERRYVIEW(dev))
-               dev_priv->display.find_dpll = chv_find_best_dpll;
-       else if (IS_VALLEYVIEW(dev))
-               dev_priv->display.find_dpll = vlv_find_best_dpll;
-       else if (IS_PINEVIEW(dev))
-               dev_priv->display.find_dpll = pnv_find_best_dpll;
-       else
-               dev_priv->display.find_dpll = i9xx_find_best_dpll;
-       if (INTEL_INFO(dev)->gen >= 9) {
+       if (INTEL_INFO(dev_priv)->gen >= 9) {
                dev_priv->display.get_pipe_config = haswell_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        skylake_get_initial_plane_config;
                        haswell_crtc_compute_clock;
                dev_priv->display.crtc_enable = haswell_crtc_enable;
                dev_priv->display.crtc_disable = haswell_crtc_disable;
-       } else if (HAS_DDI(dev)) {
+       } else if (HAS_DDI(dev_priv)) {
                dev_priv->display.get_pipe_config = haswell_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        ironlake_get_initial_plane_config;
                        haswell_crtc_compute_clock;
                dev_priv->display.crtc_enable = haswell_crtc_enable;
                dev_priv->display.crtc_disable = haswell_crtc_disable;
-       } else if (HAS_PCH_SPLIT(dev)) {
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
                dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        ironlake_get_initial_plane_config;
                        ironlake_crtc_compute_clock;
                dev_priv->display.crtc_enable = ironlake_crtc_enable;
                dev_priv->display.crtc_disable = ironlake_crtc_disable;
-       } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        i9xx_get_initial_plane_config;
-               dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
+               dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock;
                dev_priv->display.crtc_enable = valleyview_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
-       } else {
+       } else if (IS_VALLEYVIEW(dev_priv)) {
+               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+               dev_priv->display.get_initial_plane_config =
+                       i9xx_get_initial_plane_config;
+               dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock;
+               dev_priv->display.crtc_enable = valleyview_crtc_enable;
+               dev_priv->display.crtc_disable = i9xx_crtc_disable;
+       } else if (IS_G4X(dev_priv)) {
+               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+               dev_priv->display.get_initial_plane_config =
+                       i9xx_get_initial_plane_config;
+               dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
+               dev_priv->display.crtc_enable = i9xx_crtc_enable;
+               dev_priv->display.crtc_disable = i9xx_crtc_disable;
+       } else if (IS_PINEVIEW(dev_priv)) {
+               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+               dev_priv->display.get_initial_plane_config =
+                       i9xx_get_initial_plane_config;
+               dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
+               dev_priv->display.crtc_enable = i9xx_crtc_enable;
+               dev_priv->display.crtc_disable = i9xx_crtc_disable;
+       } else if (!IS_GEN2(dev_priv)) {
                dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        i9xx_get_initial_plane_config;
                dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
                dev_priv->display.crtc_enable = i9xx_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
+       } else {
+               dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+               dev_priv->display.get_initial_plane_config =
+                       i9xx_get_initial_plane_config;
+               dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
+               dev_priv->display.crtc_enable = i9xx_crtc_enable;
+               dev_priv->display.crtc_disable = i9xx_crtc_disable;
        }
  
        /* Returns the core display clock speed */
-       if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        skylake_get_display_clock_speed;
-       else if (IS_BROXTON(dev))
+       else if (IS_BROXTON(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        broxton_get_display_clock_speed;
-       else if (IS_BROADWELL(dev))
+       else if (IS_BROADWELL(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        broadwell_get_display_clock_speed;
-       else if (IS_HASWELL(dev))
+       else if (IS_HASWELL(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        haswell_get_display_clock_speed;
-       else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        valleyview_get_display_clock_speed;
-       else if (IS_GEN5(dev))
+       else if (IS_GEN5(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        ilk_get_display_clock_speed;
-       else if (IS_I945G(dev) || IS_BROADWATER(dev) ||
-                IS_GEN6(dev) || IS_IVYBRIDGE(dev))
+       else if (IS_I945G(dev_priv) || IS_BROADWATER(dev_priv) ||
+                IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i945_get_display_clock_speed;
-       else if (IS_GM45(dev))
+       else if (IS_GM45(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        gm45_get_display_clock_speed;
-       else if (IS_CRESTLINE(dev))
+       else if (IS_CRESTLINE(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i965gm_get_display_clock_speed;
-       else if (IS_PINEVIEW(dev))
+       else if (IS_PINEVIEW(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        pnv_get_display_clock_speed;
-       else if (IS_G33(dev) || IS_G4X(dev))
+       else if (IS_G33(dev_priv) || IS_G4X(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        g33_get_display_clock_speed;
-       else if (IS_I915G(dev))
+       else if (IS_I915G(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i915_get_display_clock_speed;
-       else if (IS_I945GM(dev) || IS_845G(dev))
+       else if (IS_I945GM(dev_priv) || IS_845G(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i9xx_misc_get_display_clock_speed;
-       else if (IS_I915GM(dev))
+       else if (IS_I915GM(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i915gm_get_display_clock_speed;
-       else if (IS_I865G(dev))
+       else if (IS_I865G(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i865_get_display_clock_speed;
-       else if (IS_I85X(dev))
+       else if (IS_I85X(dev_priv))
                dev_priv->display.get_display_clock_speed =
                        i85x_get_display_clock_speed;
        else { /* 830 */
-               WARN(!IS_I830(dev), "Unknown platform. Assuming 133 MHz CDCLK\n");
+               WARN(!IS_I830(dev_priv), "Unknown platform. Assuming 133 MHz CDCLK\n");
                dev_priv->display.get_display_clock_speed =
                        i830_get_display_clock_speed;
        }
  
-       if (IS_GEN5(dev)) {
+       if (IS_GEN5(dev_priv)) {
                dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
-       } else if (IS_GEN6(dev)) {
+       } else if (IS_GEN6(dev_priv)) {
                dev_priv->display.fdi_link_train = gen6_fdi_link_train;
-       } else if (IS_IVYBRIDGE(dev)) {
+       } else if (IS_IVYBRIDGE(dev_priv)) {
                /* FIXME: detect B0+ stepping and use auto training */
                dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
-       } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+       } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
                dev_priv->display.fdi_link_train = hsw_fdi_link_train;
-               if (IS_BROADWELL(dev)) {
+               if (IS_BROADWELL(dev_priv)) {
                        dev_priv->display.modeset_commit_cdclk =
                                broadwell_modeset_commit_cdclk;
                        dev_priv->display.modeset_calc_cdclk =
                                broadwell_modeset_calc_cdclk;
                }
-       } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                dev_priv->display.modeset_commit_cdclk =
                        valleyview_modeset_commit_cdclk;
                dev_priv->display.modeset_calc_cdclk =
                        valleyview_modeset_calc_cdclk;
-       } else if (IS_BROXTON(dev)) {
+       } else if (IS_BROXTON(dev_priv)) {
                dev_priv->display.modeset_commit_cdclk =
                        broxton_modeset_commit_cdclk;
                dev_priv->display.modeset_calc_cdclk =
                        broxton_modeset_calc_cdclk;
        }
  
-       switch (INTEL_INFO(dev)->gen) {
+       switch (INTEL_INFO(dev_priv)->gen) {
        case 2:
                dev_priv->display.queue_flip = intel_gen2_queue_flip;
                break;
                /* Default just returns -ENODEV to indicate unsupported */
                dev_priv->display.queue_flip = intel_default_queue_flip;
        }
-       mutex_init(&dev_priv->pps_mutex);
  }
  
  /*
@@@ -15276,7 -15315,7 +15314,7 @@@ static void sanitize_watermarks(struct 
        int i;
  
        /* Only supported on platforms that use atomic watermark design */
-       if (!dev_priv->display.program_watermarks)
+       if (!dev_priv->display.optimize_watermarks)
                return;
  
        /*
        if (WARN_ON(IS_ERR(state)))
                goto fail;
  
+       /*
+        * Hardware readout is the only time we don't want to calculate
+        * intermediate watermarks (since we don't trust the current
+        * watermarks).
+        */
+       to_intel_atomic_state(state)->skip_intermediate_wm = true;
        ret = intel_atomic_check(dev, state);
        if (ret) {
                /*
        for_each_crtc_in_state(state, crtc, cstate, i) {
                struct intel_crtc_state *cs = to_intel_crtc_state(cstate);
  
-               dev_priv->display.program_watermarks(cs);
+               cs->wm.need_postvbl_update = true;
+               dev_priv->display.optimize_watermarks(cs);
        }
  
        drm_atomic_state_free(state);
@@@ -15330,7 -15377,8 +15376,8 @@@ fail
  
  void intel_modeset_init(struct drm_device *dev)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        int sprite, ret;
        enum pipe pipe;
        struct intel_crtc *crtc;
                }
        }
  
-       intel_init_display(dev);
-       intel_init_audio(dev);
        if (IS_GEN2(dev)) {
                dev->mode_config.max_width = 2048;
                dev->mode_config.max_height = 2048;
                dev->mode_config.cursor_height = MAX_CURSOR_HEIGHT;
        }
  
-       dev->mode_config.fb_base = dev_priv->gtt.mappable_base;
+       dev->mode_config.fb_base = ggtt->mappable_base;
  
        DRM_DEBUG_KMS("%d display pipe%s available.\n",
                      INTEL_INFO(dev)->num_pipes,
        }
  
        intel_update_czclk(dev_priv);
+       intel_update_rawclk(dev_priv);
        intel_update_cdclk(dev);
  
        intel_shared_dpll_init(dev);
@@@ -15526,10 -15572,15 +15571,15 @@@ static void intel_sanitize_crtc(struct 
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       i915_reg_t reg = PIPECONF(crtc->config->cpu_transcoder);
+       enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
  
        /* Clear any frame start delays used for debugging left by the BIOS */
-       I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+       if (!transcoder_is_dsi(cpu_transcoder)) {
+               i915_reg_t reg = PIPECONF(cpu_transcoder);
+               I915_WRITE(reg,
+                          I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+       }
  
        /* restore vblank interrupts to correct state */
        drm_crtc_vblank_reset(&crtc->base);
  
        /* Adjust the state of the output pipe according to whether we
         * have active connectors/encoders. */
-       if (!intel_crtc_has_encoders(crtc))
+       if (crtc->active && !intel_crtc_has_encoders(crtc))
                intel_crtc_disable_noatomic(&crtc->base);
  
-       if (crtc->active != crtc->base.state->active) {
-               struct intel_encoder *encoder;
-               /* This can happen either due to bugs in the get_hw_state
-                * functions or because of calls to intel_crtc_disable_noatomic,
-                * or because the pipe is force-enabled due to the
-                * pipe A quirk. */
-               DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
-                             crtc->base.base.id,
-                             crtc->base.state->enable ? "enabled" : "disabled",
-                             crtc->active ? "enabled" : "disabled");
-               WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, NULL) < 0);
-               crtc->base.state->active = crtc->active;
-               crtc->base.enabled = crtc->active;
-               crtc->base.state->connector_mask = 0;
-               crtc->base.state->encoder_mask = 0;
-               /* Because we only establish the connector -> encoder ->
-                * crtc links if something is active, this means the
-                * crtc is now deactivated. Break the links. connector
-                * -> encoder links are only establish when things are
-                *  actually up, hence no need to break them. */
-               WARN_ON(crtc->active);
-               for_each_encoder_on_crtc(dev, &crtc->base, encoder)
-                       encoder->base.crtc = NULL;
-       }
        if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
                /*
                 * We start out with underrun reporting disabled to avoid races.
@@@ -15738,7 -15760,7 +15759,7 @@@ static void intel_modeset_readout_hw_st
                struct intel_crtc_state *crtc_state = crtc->config;
                int pixclk = 0;
  
-               __drm_atomic_helper_crtc_destroy_state(&crtc->base, &crtc_state->base);
+               __drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
                memset(crtc_state, 0, sizeof(*crtc_state));
                crtc_state->base.crtc = &crtc->base;
  
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
  
-               pll->on = pll->get_hw_state(dev_priv, pll,
-                                           &pll->config.hw_state);
-               pll->active = 0;
+               pll->on = pll->funcs.get_hw_state(dev_priv, pll,
+                                                 &pll->config.hw_state);
                pll->config.crtc_mask = 0;
                for_each_intel_crtc(dev, crtc) {
-                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) {
-                               pll->active++;
+                       if (crtc->active && crtc->config->shared_dpll == pll)
                                pll->config.crtc_mask |= 1 << crtc->pipe;
-                       }
                }
+               pll->active_mask = pll->config.crtc_mask;
  
                DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
                              pll->name, pll->config.crtc_mask, pll->on);
-               if (pll->config.crtc_mask)
-                       intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
        }
  
        for_each_intel_encoder(dev, encoder) {
                        drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
                        update_scanline_offset(crtc);
                }
+               intel_pipe_config_sanity_check(dev_priv, crtc->config);
        }
  }
  
@@@ -15908,12 -15927,12 +15926,12 @@@ intel_modeset_setup_hw_state(struct drm
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
  
-               if (!pll->on || pll->active)
+               if (!pll->on || pll->active_mask)
                        continue;
  
                DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
  
-               pll->disable(dev_priv, pll);
+               pll->funcs.disable(dev_priv, pll);
                pll->on = false;
        }
  
@@@ -16022,9 -16041,8 +16040,8 @@@ void intel_modeset_gem_init(struct drm_
                        continue;
  
                mutex_lock(&dev->struct_mutex);
-               ret = intel_pin_and_fence_fb_obj(c->primary,
-                                                c->primary->fb,
-                                                c->primary->state);
+               ret = intel_pin_and_fence_fb_obj(c->primary->fb,
+                                                c->primary->state->rotation);
                mutex_unlock(&dev->struct_mutex);
                if (ret) {
                        DRM_ERROR("failed to pin boot fb on pipe %d\n",
@@@ -16233,8 -16251,9 +16250,9 @@@ intel_display_capture_error_state(struc
                        error->pipe[i].stat = I915_READ(PIPESTAT(i));
        }
  
+       /* Note: this does not include DSI transcoders. */
        error->num_transcoders = INTEL_INFO(dev)->num_pipes;
-       if (HAS_DDI(dev_priv->dev))
+       if (HAS_DDI(dev_priv))
                error->num_transcoders++; /* Account for eDP. */
  
        for (i = 0; i < error->num_transcoders; i++) {
@@@ -16305,7 -16324,7 +16323,7 @@@ intel_display_print_error_state(struct 
        }
  
        for (i = 0; i < error->num_transcoders; i++) {
-               err_printf(m, "CPU transcoder: %c\n",
+               err_printf(m, "CPU transcoder: %s\n",
                           transcoder_name(error->transcoder[i].cpu_transcoder));
                err_printf(m, "  Power: %s\n",
                           onoff(error->transcoder[i].power_domain_on));
index 2c999725b3d4b3ac10d9599227e00a1b392ae4f2,b6bf7fd0b806362e0c903fcbf7219458b88b977f..7a34090cef34e6a14276ab2cdfcbc4c498926be8
@@@ -33,7 -33,6 +33,6 @@@
  static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
                                        struct intel_crtc_state *pipe_config)
  {
-       struct drm_device *dev = encoder->base.dev;
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        struct intel_digital_port *intel_dig_port = intel_mst->primary;
        struct intel_dp *intel_dp = &intel_dig_port->dp;
@@@ -78,6 -77,8 +77,6 @@@
                return false;
        }
  
 -      if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, found->port))
 -              pipe_config->has_audio = true;
        mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
  
        pipe_config->pbn = mst_pbn;
@@@ -90,9 -91,6 +89,6 @@@
  
        pipe_config->dp_m_n.tu = slots;
  
-       if (IS_HASWELL(dev) || IS_BROADWELL(dev))
-               hsw_dp_set_ddi_pll_sel(pipe_config);
        return true;
  
  }
@@@ -102,16 -100,25 +98,16 @@@ static void intel_mst_disable_dp(struc
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        struct intel_digital_port *intel_dig_port = intel_mst->primary;
        struct intel_dp *intel_dp = &intel_dig_port->dp;
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct drm_crtc *crtc = encoder->base.crtc;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 -
        int ret;
  
        DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
  
-       drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, intel_mst->port);
+       drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, intel_mst->connector->port);
  
        ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
        if (ret) {
                DRM_ERROR("failed to update payload %d\n", ret);
        }
 -      if (intel_crtc->config->has_audio) {
 -              intel_audio_codec_disable(encoder);
 -              intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
 -      }
  }
  
  static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
        /* and this can also fail */
        drm_dp_update_payload_part2(&intel_dp->mst_mgr);
  
-       drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->port);
+       drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->connector->port);
  
        intel_dp->active_mst_links--;
-       intel_mst->port = NULL;
+       intel_mst->connector = NULL;
        if (intel_dp->active_mst_links == 0) {
                intel_dig_port->base.post_disable(&intel_dig_port->base);
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
@@@ -170,7 -178,8 +167,8 @@@ static void intel_mst_pre_enable_dp(str
        found->encoder = encoder;
  
        DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
-       intel_mst->port = found->port;
+       intel_mst->connector = found;
  
        if (intel_dp->active_mst_links == 0) {
                intel_prepare_ddi_buffer(&intel_dig_port->base);
        }
  
        ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
-                                      intel_mst->port,
+                                      intel_mst->connector->port,
                                       intel_crtc->config->pbn, &slots);
        if (ret == false) {
                DRM_ERROR("failed to allocate vcpi\n");
@@@ -210,6 -219,7 +208,6 @@@ static void intel_mst_enable_dp(struct 
        struct intel_dp *intel_dp = &intel_dig_port->dp;
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
        enum port port = intel_dig_port->port;
        int ret;
  
        ret = drm_dp_check_act_status(&intel_dp->mst_mgr);
  
        ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr);
 -
 -      if (crtc->config->has_audio) {
 -              DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
 -                               pipe_name(crtc->pipe));
 -              intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
 -              intel_audio_codec_enable(encoder);
 -      }
  }
  
  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
  {
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        *pipe = intel_mst->pipe;
-       if (intel_mst->port)
+       if (intel_mst->connector)
                return true;
        return false;
  }
@@@ -247,6 -264,9 +245,6 @@@ static void intel_dp_mst_enc_get_config
  
        pipe_config->has_dp_encoder = true;
  
 -      pipe_config->has_audio =
 -              intel_ddi_is_audio_enabled(dev_priv, crtc);
 -
        temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
        if (temp & TRANS_DDI_PHSYNC)
                flags |= DRM_MODE_FLAG_PHSYNC;
@@@ -290,10 -310,11 +288,11 @@@ static int intel_dp_mst_get_ddc_modes(s
        struct edid *edid;
        int ret;
  
-       edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
-       if (!edid)
-               return 0;
+       if (!intel_dp) {
+               return intel_connector_update_modes(connector, NULL);
+       }
  
+       edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
        ret = intel_connector_update_modes(connector, edid);
        kfree(edid);
  
@@@ -306,6 -327,8 +305,8 @@@ intel_dp_mst_detect(struct drm_connecto
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct intel_dp *intel_dp = intel_connector->mst_port;
  
+       if (!intel_dp)
+               return connector_status_disconnected;
        return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, intel_connector->port);
  }
  
@@@ -371,6 -394,8 +372,8 @@@ static struct drm_encoder *intel_mst_at
        struct intel_dp *intel_dp = intel_connector->mst_port;
        struct intel_crtc *crtc = to_intel_crtc(state->crtc);
  
+       if (!intel_dp)
+               return NULL;
        return &intel_dp->mst_encoders[crtc->pipe]->base.base;
  }
  
@@@ -378,6 -403,8 +381,8 @@@ static struct drm_encoder *intel_mst_be
  {
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct intel_dp *intel_dp = intel_connector->mst_port;
+       if (!intel_dp)
+               return NULL;
        return &intel_dp->mst_encoders[0]->base.base;
  }
  
@@@ -488,23 -515,11 +493,11 @@@ static void intel_dp_destroy_mst_connec
  
        /* need to nuke the connector */
        drm_modeset_lock_all(dev);
-       if (connector->state->crtc) {
-               struct drm_mode_set set;
-               int ret;
-               memset(&set, 0, sizeof(set));
-               set.crtc = connector->state->crtc,
-               ret = drm_atomic_helper_set_config(&set);
-               WARN(ret, "Disabling mst crtc failed with %i\n", ret);
-       }
        intel_connector_remove_from_fbdev(intel_connector);
-       drm_connector_cleanup(connector);
+       intel_connector->mst_port = NULL;
        drm_modeset_unlock_all(dev);
  
-       kfree(intel_connector);
+       drm_connector_unreference(&intel_connector->base);
        DRM_DEBUG_KMS("\n");
  }
  
index 9d0770c23fdece738575cc70a372353b7ea6284e,315c971b5b31000518bf8c7deb7247e17cd25e60..5da29a02b9e34360f1e8cffcb8d219f49c5a5947
   * contexts. Note that it's important that we check the condition again after
   * having timed out, since the timeout could be due to preemption or similar and
   * we've never had a chance to check the condition before the timeout.
+  *
+  * TODO: When modesetting has fully transitioned to atomic, the below
+  * drm_can_sleep() can be removed and in_atomic()/!in_atomic() asserts
+  * added.
   */
- #define _wait_for(COND, MS, W) ({ \
-       unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1;   \
+ #define _wait_for(COND, US, W) ({ \
+       unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;   \
        int ret__ = 0;                                                  \
        while (!(COND)) {                                               \
                if (time_after(jiffies, timeout__)) {                   \
@@@ -55,7 -59,7 +59,7 @@@
                        break;                                          \
                }                                                       \
                if ((W) && drm_can_sleep()) {                           \
-                       usleep_range((W)*1000, (W)*2000);               \
+                       usleep_range((W), (W)*2);                       \
                } else {                                                \
                        cpu_relax();                                    \
                }                                                       \
        ret__;                                                          \
  })
  
- #define wait_for(COND, MS) _wait_for(COND, MS, 1)
- #define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0)
- #define wait_for_atomic_us(COND, US) _wait_for((COND), \
-                                              DIV_ROUND_UP((US), 1000), 0)
+ #define wait_for(COND, MS)            _wait_for((COND), (MS) * 1000, 1000)
+ #define wait_for_us(COND, US)         _wait_for((COND), (US), 1)
+ /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
+ #if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
+ # define _WAIT_FOR_ATOMIC_CHECK WARN_ON_ONCE(!in_atomic())
+ #else
+ # define _WAIT_FOR_ATOMIC_CHECK do { } while (0)
+ #endif
+ #define _wait_for_atomic(COND, US) ({ \
+       unsigned long end__; \
+       int ret__ = 0; \
+       _WAIT_FOR_ATOMIC_CHECK; \
+       BUILD_BUG_ON((US) > 50000); \
+       end__ = (local_clock() >> 10) + (US) + 1; \
+       while (!(COND)) { \
+               if (time_after((unsigned long)(local_clock() >> 10), end__)) { \
+                       /* Unlike the regular wait_for(), this atomic variant \
+                        * cannot be preempted (and we'll just ignore the issue\
+                        * of irq interruptions) and so we know that no time \
+                        * has passed since the last check of COND and can \
+                        * immediately report the timeout. \
+                        */ \
+                       ret__ = -ETIMEDOUT; \
+                       break; \
+               } \
+               cpu_relax(); \
+       } \
+       ret__; \
+ })
+ #define wait_for_atomic(COND, MS)     _wait_for_atomic((COND), (MS) * 1000)
+ #define wait_for_atomic_us(COND, US)  _wait_for_atomic((COND), (US))
  
  #define KHz(x) (1000 * (x))
  #define MHz(x) KHz(1000 * (x))
@@@ -118,6 -152,7 +152,7 @@@ enum intel_output_type 
  struct intel_framebuffer {
        struct drm_framebuffer base;
        struct drm_i915_gem_object *obj;
+       struct intel_rotation_info rot_info;
  };
  
  struct intel_fbdev {
@@@ -260,6 -295,12 +295,12 @@@ struct intel_atomic_state 
  
        struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
        struct intel_wm_config wm_config;
+       /*
+        * Current watermarks can't be trusted during hardware readout, so
+        * don't bother calculating intermediate watermarks.
+        */
+       bool skip_intermediate_wm;
  };
  
  struct intel_plane_state {
@@@ -349,6 -390,7 +390,7 @@@ struct intel_crtc_scaler_state 
  
  struct intel_pipe_wm {
        struct intel_wm_level wm[5];
+       struct intel_wm_level raw_wm[5];
        uint32_t linetime;
        bool fbc_wm_enabled;
        bool pipe_enabled;
@@@ -376,9 -418,10 +418,10 @@@ struct intel_crtc_state 
  #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS     (1<<0) /* unreliable sync mode.flags */
        unsigned long quirks;
  
+       unsigned fb_bits; /* framebuffers to flip */
        bool update_pipe; /* can a fast modeset be performed? */
        bool disable_cxsr;
-       bool wm_changed; /* watermarks are updated */
+       bool update_wm_pre, update_wm_post; /* watermarks are updated */
        bool fb_changed; /* fb on any of the planes is changed */
  
        /* Pipe source size (ie. panel fitter input size)
        bool has_infoframe;
  
        /* CPU Transcoder for the pipe. Currently this can only differ from the
-        * pipe on Haswell (where we have a special eDP transcoder). */
+        * pipe on Haswell and later (where we have a special eDP transcoder)
+        * and Broxton (where we have special DSI transcoders). */
        enum transcoder cpu_transcoder;
  
        /*
         * haswell. */
        struct dpll dpll;
  
-       /* Selected dpll when shared or DPLL_ID_PRIVATE. */
-       enum intel_dpll_id shared_dpll;
+       /* Selected dpll when shared or NULL. */
+       struct intel_shared_dpll *shared_dpll;
  
        /*
         * - PORT_CLK_SEL for DDI ports on HSW/BDW.
        /* Actual register state of the dpll, for shared dpll cross-checking. */
        struct intel_dpll_hw_state dpll_hw_state;
  
+       /* DSI PLL registers */
+       struct {
+               u32 ctrl, div;
+       } dsi_pll;
        int pipe_bpp;
        struct intel_link_m_n dp_m_n;
  
  
        struct {
                /*
-                * optimal watermarks, programmed post-vblank when this state
-                * is committed
+                * Optimal watermarks, programmed post-vblank when this state
+                * is committed.
                 */
                union {
                        struct intel_pipe_wm ilk;
                        struct skl_pipe_wm skl;
                } optimal;
+               /*
+                * Intermediate watermarks; these can be programmed immediately
+                * since they satisfy both the current configuration we're
+                * switching away from and the new configuration we're switching
+                * to.
+                */
+               struct intel_pipe_wm intermediate;
+               /*
+                * Platforms with two-step watermark programming will need to
+                * update watermark programming post-vblank to switch from the
+                * safe intermediate watermarks to the optimal final
+                * watermarks.
+                */
+               bool need_postvbl_update;
        } wm;
+       /* Gamma mode programmed on the pipe */
+       uint32_t gamma_mode;
  };
  
  struct vlv_wm_state {
@@@ -537,23 -605,6 +605,6 @@@ struct intel_mmio_flip 
        unsigned int rotation;
  };
  
- /*
-  * Tracking of operations that need to be performed at the beginning/end of an
-  * atomic commit, outside the atomic section where interrupts are disabled.
-  * These are generally operations that grab mutexes or might otherwise sleep
-  * and thus can't be run with interrupts disabled.
-  */
- struct intel_crtc_atomic_commit {
-       /* Sleepable operations to perform before commit */
-       /* Sleepable operations to perform after commit */
-       unsigned fb_bits;
-       bool post_enable_primary;
-       /* Sleepable operations to perform before and after commit */
-       bool update_fbc;
- };
  struct intel_crtc {
        struct drm_crtc base;
        enum pipe pipe;
                        struct intel_pipe_wm ilk;
                        struct skl_pipe_wm skl;
                } active;
                /* allow CxSR on this pipe */
                bool cxsr_allowed;
        } wm;
                int scanline_start;
        } debug;
  
-       struct intel_crtc_atomic_commit atomic;
        /* scalers available on this crtc */
        int num_scalers;
  
@@@ -751,7 -801,9 +801,9 @@@ struct intel_dp 
        uint32_t DP;
        int link_rate;
        uint8_t lane_count;
+       uint8_t sink_count;
        bool has_audio;
+       bool detect_done;
        enum hdmi_force_audio force_audio;
        bool limited_color_range;
        bool color_range_auto;
@@@ -831,7 -883,7 +883,7 @@@ struct intel_dp_mst_encoder 
        struct intel_encoder base;
        enum pipe pipe;
        struct intel_digital_port *primary;
-       void *port; /* store this opaque as its illegal to dereference it */
+       struct intel_connector *connector;
  };
  
  static inline enum dpio_channel
@@@ -1007,7 -1059,6 +1059,6 @@@ void hsw_fdi_link_train(struct drm_crt
  void intel_ddi_init(struct drm_device *dev, enum port port);
  enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
  bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
- void intel_ddi_pll_init(struct drm_device *dev);
  void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
  void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
                                       enum transcoder cpu_transcoder);
@@@ -1019,6 -1070,8 +1070,6 @@@ void intel_ddi_set_pipe_settings(struc
  void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp);
  bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
  void intel_ddi_fdi_disable(struct drm_crtc *crtc);
 -bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
 -                               struct intel_crtc *intel_crtc);
  void intel_ddi_get_config(struct intel_encoder *encoder,
                          struct intel_crtc_state *pipe_config);
  struct intel_encoder *
@@@ -1049,17 -1102,19 +1100,19 @@@ u32 intel_fb_stride_alignment(const str
                              uint64_t fb_modifier, uint32_t pixel_format);
  
  /* intel_audio.c */
- void intel_init_audio(struct drm_device *dev);
+ void intel_init_audio_hooks(struct drm_i915_private *dev_priv);
  void intel_audio_codec_enable(struct intel_encoder *encoder);
  void intel_audio_codec_disable(struct intel_encoder *encoder);
  void i915_audio_component_init(struct drm_i915_private *dev_priv);
  void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
  
  /* intel_display.c */
+ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
+                     const char *name, u32 reg, int ref_freq);
  extern const struct drm_plane_funcs intel_plane_funcs;
+ void intel_init_display_hooks(struct drm_i915_private *dev_priv);
+ unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
  bool intel_has_pending_fb_unpin(struct drm_device *dev);
- int intel_pch_rawclk(struct drm_device *dev);
- int intel_hrawclk(struct drm_device *dev);
  void intel_mark_busy(struct drm_device *dev);
  void intel_mark_idle(struct drm_device *dev);
  void intel_crtc_restore_mode(struct drm_crtc *crtc);
@@@ -1104,9 -1159,8 +1157,8 @@@ bool intel_get_load_detect_pipe(struct 
  void intel_release_load_detect_pipe(struct drm_connector *connector,
                                    struct intel_load_detect_pipe *old,
                                    struct drm_modeset_acquire_ctx *ctx);
- int intel_pin_and_fence_fb_obj(struct drm_plane *plane,
-                              struct drm_framebuffer *fb,
-                              const struct drm_plane_state *plane_state);
+ int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+                              unsigned int rotation);
  struct drm_framebuffer *
  __intel_framebuffer_create(struct drm_device *dev,
                           struct drm_mode_fb_cmd2 *mode_cmd,
@@@ -1142,19 -1196,13 +1194,13 @@@ intel_rotation_90_or_270(unsigned int r
  void intel_create_rotation_property(struct drm_device *dev,
                                        struct intel_plane *plane);
  
- /* shared dpll functions */
- struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
- void assert_shared_dpll(struct drm_i915_private *dev_priv,
-                       struct intel_shared_dpll *pll,
-                       bool state);
- #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
- #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
- struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-                                               struct intel_crtc_state *state);
+ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+                                   enum pipe pipe);
  
  int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
                     const struct dpll *dpll);
  void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe);
+ int lpt_get_iclkip(struct drm_i915_private *dev_priv);
  
  /* modesetting asserts */
  void assert_panel_unlocked(struct drm_i915_private *dev_priv,
@@@ -1163,6 -1211,9 +1209,9 @@@ void assert_pll(struct drm_i915_privat
                enum pipe pipe, bool state);
  #define assert_pll_enabled(d, p) assert_pll(d, p, true)
  #define assert_pll_disabled(d, p) assert_pll(d, p, false)
+ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state);
+ #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
+ #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
  void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
                       enum pipe pipe, bool state);
  #define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true)
  void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
  #define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
  #define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
- u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv,
-                             int *x, int *y,
-                             uint64_t fb_modifier,
-                             unsigned int cpp,
-                             unsigned int pitch);
+ u32 intel_compute_tile_offset(int *x, int *y,
+                             const struct drm_framebuffer *fb, int plane,
+                             unsigned int pitch,
+                             unsigned int rotation);
  void intel_prepare_reset(struct drm_device *dev);
  void intel_finish_reset(struct drm_device *dev);
  void hsw_enable_pc8(struct drm_i915_private *dev_priv);
  void hsw_disable_pc8(struct drm_i915_private *dev_priv);
- void broxton_init_cdclk(struct drm_device *dev);
- void broxton_uninit_cdclk(struct drm_device *dev);
- void broxton_ddi_phy_init(struct drm_device *dev);
- void broxton_ddi_phy_uninit(struct drm_device *dev);
+ void broxton_init_cdclk(struct drm_i915_private *dev_priv);
+ void broxton_uninit_cdclk(struct drm_i915_private *dev_priv);
+ bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv);
+ void broxton_ddi_phy_init(struct drm_i915_private *dev_priv);
+ void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv);
+ void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv);
+ void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
  void bxt_enable_dc9(struct drm_i915_private *dev_priv);
  void bxt_disable_dc9(struct drm_i915_private *dev_priv);
+ void gen9_enable_dc5(struct drm_i915_private *dev_priv);
  void skl_init_cdclk(struct drm_i915_private *dev_priv);
  int skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
  void skl_uninit_cdclk(struct drm_i915_private *dev_priv);
@@@ -1194,9 -1248,6 +1246,6 @@@ void intel_dp_get_m_n(struct intel_crt
                      struct intel_crtc_state *pipe_config);
  void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n);
  int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
- void
- ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
-                               int dotclock);
  bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
                        intel_clock_t *best_clock);
  int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock);
@@@ -1224,8 -1275,10 +1273,10 @@@ u32 skl_plane_ctl_rotation(unsigned in
  
  /* intel_csr.c */
  void intel_csr_ucode_init(struct drm_i915_private *);
bool intel_csr_load_program(struct drm_i915_private *);
void intel_csr_load_program(struct drm_i915_private *);
  void intel_csr_ucode_fini(struct drm_i915_private *);
+ void intel_csr_ucode_suspend(struct drm_i915_private *);
+ void intel_csr_ucode_resume(struct drm_i915_private *);
  
  /* intel_dp.c */
  void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
@@@ -1266,7 -1319,6 +1317,6 @@@ void intel_edp_drrs_invalidate(struct d
  void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
  bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
                                         struct intel_digital_port *port);
- void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
  
  void
  intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
@@@ -1423,8 -1475,8 +1473,8 @@@ int intel_power_domains_init(struct drm
  void intel_power_domains_fini(struct drm_i915_private *);
  void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
  void intel_power_domains_suspend(struct drm_i915_private *dev_priv);
- void skl_pw1_misc_io_init(struct drm_i915_private *dev_priv);
- void skl_pw1_misc_io_fini(struct drm_i915_private *dev_priv);
+ void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
+ void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
  void intel_runtime_pm_enable(struct drm_i915_private *dev_priv);
  const char *
  intel_display_power_domain_str(enum intel_display_power_domain domain);
@@@ -1541,6 -1593,7 +1591,7 @@@ void intel_suspend_hw(struct drm_devic
  int ilk_wm_max_level(const struct drm_device *dev);
  void intel_update_watermarks(struct drm_crtc *crtc);
  void intel_init_pm(struct drm_device *dev);
+ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv);
  void intel_pm_setup(struct drm_device *dev);
  void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
  void intel_gpu_ips_teardown(void);
@@@ -1565,6 -1618,7 +1616,7 @@@ void skl_wm_get_hw_state(struct drm_dev
  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
                          struct skl_ddb_allocation *ddb /* out */);
  uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
+ bool ilk_disable_lp_wm(struct drm_device *dev);
  int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6);
  
  /* intel_sdvo.c */
@@@ -1606,6 -1660,18 +1658,18 @@@ intel_atomic_get_crtc_state(struct drm_
  
        return to_intel_crtc_state(crtc_state);
  }
+ static inline struct intel_plane_state *
+ intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
+                                     struct intel_plane *plane)
+ {
+       struct drm_plane_state *plane_state;
+       plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
+       return to_intel_plane_state(plane_state);
+ }
  int intel_atomic_setup_scalers(struct drm_device *dev,
        struct intel_crtc *intel_crtc,
        struct intel_crtc_state *crtc_state);
@@@ -1617,4 -1683,10 +1681,10 @@@ void intel_plane_destroy_state(struct d
                               struct drm_plane_state *state);
  extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
  
+ /* intel_color.c */
+ void intel_color_init(struct drm_crtc *crtc);
+ int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
+ void intel_color_set_csc(struct drm_crtc_state *crtc_state);
+ void intel_color_load_luts(struct drm_crtc_state *crtc_state);
  #endif /* __INTEL_DRV_H__ */
index 10dc3517b63b32921437bcff3d2352829061c4ed,66e832beeb37e570f505b4549bc9e9b01234dd35..bc53c0dd34d082cc53ad2ca4b398b9d5ba85a1f5
@@@ -109,7 -109,6 +109,6 @@@ static void intel_lvds_get_config(struc
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
        u32 tmp, flags = 0;
-       int dotclock;
  
        tmp = I915_READ(lvds_encoder->reg);
        if (tmp & LVDS_HSYNC_POLARITY)
  
        pipe_config->base.adjusted_mode.flags |= flags;
  
 +      if (INTEL_INFO(dev)->gen < 5)
 +              pipe_config->gmch_pfit.lvds_border_bits =
 +                      tmp & LVDS_BORDER_ENABLE;
 +
        /* gen2/3 store dither state in pfit control, needs to match */
        if (INTEL_INFO(dev)->gen < 4) {
                tmp = I915_READ(PFIT_CONTROL);
                pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
        }
  
-       dotclock = pipe_config->port_clock;
-       if (HAS_PCH_SPLIT(dev_priv->dev))
-               ironlake_check_encoder_dotclock(pipe_config, dotclock);
-       pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+       pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
  }
  
  static void intel_pre_enable_lvds(struct intel_encoder *encoder)
        if (HAS_PCH_SPLIT(dev)) {
                assert_fdi_rx_pll_disabled(dev_priv, pipe);
                assert_shared_dpll_disabled(dev_priv,
-                                           intel_crtc_to_shared_dpll(crtc));
+                                           crtc->config->shared_dpll);
        } else {
                assert_pll_disabled(dev_priv, pipe);
        }
@@@ -782,57 -772,6 +776,6 @@@ static const struct dmi_system_id intel
        { }     /* terminating entry */
  };
  
- /*
-  * Enumerate the child dev array parsed from VBT to check whether
-  * the LVDS is present.
-  * If it is present, return 1.
-  * If it is not present, return false.
-  * If no child dev is parsed from VBT, it assumes that the LVDS is present.
-  */
- static bool lvds_is_present_in_vbt(struct drm_device *dev,
-                                  u8 *i2c_pin)
- {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int i;
-       if (!dev_priv->vbt.child_dev_num)
-               return true;
-       for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
-               union child_device_config *uchild = dev_priv->vbt.child_dev + i;
-               struct old_child_dev_config *child = &uchild->old;
-               /* If the device type is not LFP, continue.
-                * We have to check both the new identifiers as well as the
-                * old for compatibility with some BIOSes.
-                */
-               if (child->device_type != DEVICE_TYPE_INT_LFP &&
-                   child->device_type != DEVICE_TYPE_LFP)
-                       continue;
-               if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
-                       *i2c_pin = child->i2c_pin;
-               /* However, we cannot trust the BIOS writers to populate
-                * the VBT correctly.  Since LVDS requires additional
-                * information from AIM blocks, a non-zero addin offset is
-                * a good indicator that the LVDS is actually present.
-                */
-               if (child->addin_offset)
-                       return true;
-               /* But even then some BIOS writers perform some black magic
-                * and instantiate the device without reference to any
-                * additional data.  Trust that if the VBT was written into
-                * the OpRegion then they have validated the LVDS's existence.
-                */
-               if (dev_priv->opregion.vbt)
-                       return true;
-       }
-       return false;
- }
  static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
  {
        DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
@@@ -982,14 -921,14 +925,14 @@@ void intel_lvds_init(struct drm_device 
        if (HAS_PCH_SPLIT(dev)) {
                if ((lvds & LVDS_DETECTED) == 0)
                        return;
-               if (dev_priv->vbt.edp_support) {
+               if (dev_priv->vbt.edp.support) {
                        DRM_DEBUG_KMS("disable LVDS for eDP support\n");
                        return;
                }
        }
  
        pin = GMBUS_PIN_PANEL;
-       if (!lvds_is_present_in_vbt(dev, &pin)) {
+       if (!intel_bios_is_lvds_present(dev_priv, &pin)) {
                if ((lvds & LVDS_PORT_EN) == 0) {
                        DRM_DEBUG_KMS("LVDS is not present in VBT\n");
                        return;
index 3425d8e737b344ec8d43bdeab38957e2667d00bf,695a464a5e64fd5cc42c4c12e1e88844ae8a375e..4b60005cda378f27293d2721baf09970818eea2e
@@@ -487,20 -487,6 +487,6 @@@ static const struct intel_watermark_par
        .guard_size = 2,
        .cacheline_size = G4X_FIFO_LINE_SIZE,
  };
- static const struct intel_watermark_params valleyview_wm_info = {
-       .fifo_size = VALLEYVIEW_FIFO_SIZE,
-       .max_wm = VALLEYVIEW_MAX_WM,
-       .default_wm = VALLEYVIEW_MAX_WM,
-       .guard_size = 2,
-       .cacheline_size = G4X_FIFO_LINE_SIZE,
- };
- static const struct intel_watermark_params valleyview_cursor_wm_info = {
-       .fifo_size = I965_CURSOR_FIFO,
-       .max_wm = VALLEYVIEW_CURSOR_MAX_WM,
-       .default_wm = I965_CURSOR_DFT_WM,
-       .guard_size = 2,
-       .cacheline_size = G4X_FIFO_LINE_SIZE,
- };
  static const struct intel_watermark_params i965_cursor_wm_info = {
        .fifo_size = I965_CURSOR_FIFO,
        .max_wm = I965_CURSOR_MAX_WM,
@@@ -2010,11 -1996,18 +1996,18 @@@ static void ilk_compute_wm_level(const 
                cur_latency *= 5;
        }
  
-       result->pri_val = ilk_compute_pri_wm(cstate, pristate,
-                                            pri_latency, level);
-       result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
-       result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
-       result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
+       if (pristate) {
+               result->pri_val = ilk_compute_pri_wm(cstate, pristate,
+                                                    pri_latency, level);
+               result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
+       }
+       if (sprstate)
+               result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
+       if (curstate)
+               result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
        result->enable = true;
  }
  
@@@ -2278,99 -2271,170 +2271,170 @@@ static void skl_setup_wm_latency(struc
        intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
  }
  
+ static bool ilk_validate_pipe_wm(struct drm_device *dev,
+                                struct intel_pipe_wm *pipe_wm)
+ {
+       /* LP0 watermark maximums depend on this pipe alone */
+       const struct intel_wm_config config = {
+               .num_pipes_active = 1,
+               .sprites_enabled = pipe_wm->sprites_enabled,
+               .sprites_scaled = pipe_wm->sprites_scaled,
+       };
+       struct ilk_wm_maximums max;
+       /* LP0 watermarks always use 1/2 DDB partitioning */
+       ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
+       /* At least LP0 must be valid */
+       if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) {
+               DRM_DEBUG_KMS("LP0 watermark invalid\n");
+               return false;
+       }
+       return true;
+ }
  /* Compute new watermarks for the pipe */
- static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc,
-                              struct drm_atomic_state *state)
+ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
  {
+       struct drm_atomic_state *state = cstate->base.state;
+       struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
        struct intel_pipe_wm *pipe_wm;
-       struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_device *dev = state->dev;
        const struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc_state *cstate = NULL;
        struct intel_plane *intel_plane;
-       struct drm_plane_state *ps;
        struct intel_plane_state *pristate = NULL;
        struct intel_plane_state *sprstate = NULL;
        struct intel_plane_state *curstate = NULL;
-       int level, max_level = ilk_wm_max_level(dev);
-       /* LP0 watermark maximums depend on this pipe alone */
-       struct intel_wm_config config = {
-               .num_pipes_active = 1,
-       };
+       int level, max_level = ilk_wm_max_level(dev), usable_level;
        struct ilk_wm_maximums max;
  
-       cstate = intel_atomic_get_crtc_state(state, intel_crtc);
-       if (IS_ERR(cstate))
-               return PTR_ERR(cstate);
        pipe_wm = &cstate->wm.optimal.ilk;
-       memset(pipe_wm, 0, sizeof(*pipe_wm));
  
        for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-               ps = drm_atomic_get_plane_state(state,
-                                               &intel_plane->base);
-               if (IS_ERR(ps))
-                       return PTR_ERR(ps);
+               struct intel_plane_state *ps;
+               ps = intel_atomic_get_existing_plane_state(state,
+                                                          intel_plane);
+               if (!ps)
+                       continue;
  
                if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
-                       pristate = to_intel_plane_state(ps);
+                       pristate = ps;
                else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
-                       sprstate = to_intel_plane_state(ps);
+                       sprstate = ps;
                else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
-                       curstate = to_intel_plane_state(ps);
+                       curstate = ps;
        }
  
-       config.sprites_enabled = sprstate->visible;
-       config.sprites_scaled = sprstate->visible &&
-               (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
-               drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
        pipe_wm->pipe_enabled = cstate->base.active;
-       pipe_wm->sprites_enabled = config.sprites_enabled;
-       pipe_wm->sprites_scaled = config.sprites_scaled;
+       if (sprstate) {
+               pipe_wm->sprites_enabled = sprstate->visible;
+               pipe_wm->sprites_scaled = sprstate->visible &&
+                       (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
+                        drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
+       }
+       usable_level = max_level;
  
        /* ILK/SNB: LP2+ watermarks only w/o sprites */
-       if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
-               max_level = 1;
+       if (INTEL_INFO(dev)->gen <= 6 && pipe_wm->sprites_enabled)
+               usable_level = 1;
  
        /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
-       if (config.sprites_scaled)
-               max_level = 0;
+       if (pipe_wm->sprites_scaled)
+               usable_level = 0;
  
        ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
-                            pristate, sprstate, curstate, &pipe_wm->wm[0]);
+                            pristate, sprstate, curstate, &pipe_wm->raw_wm[0]);
+       memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm));
+       pipe_wm->wm[0] = pipe_wm->raw_wm[0];
  
        if (IS_HASWELL(dev) || IS_BROADWELL(dev))
                pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate);
  
-       /* LP0 watermarks always use 1/2 DDB partitioning */
-       ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
-       /* At least LP0 must be valid */
-       if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
+       if (!ilk_validate_pipe_wm(dev, pipe_wm))
                return -EINVAL;
  
        ilk_compute_wm_reg_maximums(dev, 1, &max);
  
        for (level = 1; level <= max_level; level++) {
-               struct intel_wm_level wm = {};
+               struct intel_wm_level *wm = &pipe_wm->raw_wm[level];
  
                ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
-                                    pristate, sprstate, curstate, &wm);
+                                    pristate, sprstate, curstate, wm);
  
                /*
                 * Disable any watermark level that exceeds the
                 * register maximums since such watermarks are
                 * always invalid.
                 */
-               if (!ilk_validate_wm_level(level, &max, &wm))
-                       break;
+               if (level > usable_level)
+                       continue;
  
-               pipe_wm->wm[level] = wm;
+               if (ilk_validate_wm_level(level, &max, wm))
+                       pipe_wm->wm[level] = *wm;
+               else
+                       usable_level = level;
        }
  
        return 0;
  }
  
+ /*
+  * Build a set of 'intermediate' watermark values that satisfy both the old
+  * state and the new state.  These can be programmed to the hardware
+  * immediately.
+  */
+ static int ilk_compute_intermediate_wm(struct drm_device *dev,
+                                      struct intel_crtc *intel_crtc,
+                                      struct intel_crtc_state *newstate)
+ {
+       struct intel_pipe_wm *a = &newstate->wm.intermediate;
+       struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk;
+       int level, max_level = ilk_wm_max_level(dev);
+       /*
+        * Start with the final, target watermarks, then combine with the
+        * currently active watermarks to get values that are safe both before
+        * and after the vblank.
+        */
+       *a = newstate->wm.optimal.ilk;
+       a->pipe_enabled |= b->pipe_enabled;
+       a->sprites_enabled |= b->sprites_enabled;
+       a->sprites_scaled |= b->sprites_scaled;
+       for (level = 0; level <= max_level; level++) {
+               struct intel_wm_level *a_wm = &a->wm[level];
+               const struct intel_wm_level *b_wm = &b->wm[level];
+               a_wm->enable &= b_wm->enable;
+               a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val);
+               a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val);
+               a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val);
+               a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val);
+       }
+       /*
+        * We need to make sure that these merged watermark values are
+        * actually a valid configuration themselves.  If they're not,
+        * there's no safe way to transition from the old state to
+        * the new state, so we need to fail the atomic transaction.
+        */
+       if (!ilk_validate_pipe_wm(dev, a))
+               return -EINVAL;
+       /*
+        * If our intermediate WM are identical to the final WM, then we can
+        * omit the post-vblank programming; only update if it's different.
+        */
+       if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) == 0)
+               newstate->wm.need_postvbl_update = false;
+       return 0;
+ }
  /*
   * Merge the watermarks from all active pipes for a specific level.
   */
@@@ -2383,9 -2447,7 +2447,7 @@@ static void ilk_merge_wm_level(struct d
        ret_wm->enable = true;
  
        for_each_intel_crtc(dev, intel_crtc) {
-               const struct intel_crtc_state *cstate =
-                       to_intel_crtc_state(intel_crtc->base.state);
-               const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
+               const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk;
                const struct intel_wm_level *wm = &active->wm[level];
  
                if (!active->pipe_enabled)
@@@ -2421,7 -2483,7 +2483,7 @@@ static void ilk_wm_merge(struct drm_dev
        /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */
        if ((INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev)) &&
            config->num_pipes_active > 1)
-               return;
+               last_enabled_level = 0;
  
        /* ILK: FBC WM must be disabled always */
        merged->fbc_wm_enabled = INTEL_INFO(dev)->gen >= 6;
@@@ -2533,15 -2595,14 +2595,14 @@@ static void ilk_compute_wm_results(stru
  
        /* LP0 register values */
        for_each_intel_crtc(dev, intel_crtc) {
-               const struct intel_crtc_state *cstate =
-                       to_intel_crtc_state(intel_crtc->base.state);
                enum pipe pipe = intel_crtc->pipe;
-               const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0];
+               const struct intel_wm_level *r =
+                       &intel_crtc->wm.active.ilk.wm[0];
  
                if (WARN_ON(!r->enable))
                        continue;
  
-               results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime;
+               results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime;
  
                results->wm_pipe[pipe] =
                        (r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@@ -2748,7 -2809,7 +2809,7 @@@ static void ilk_write_wm_values(struct 
        dev_priv->wm.hw = *results;
  }
  
static bool ilk_disable_lp_wm(struct drm_device *dev)
+ bool ilk_disable_lp_wm(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
@@@ -3657,11 -3718,9 +3718,9 @@@ static void ilk_compute_wm_config(struc
        }
  }
  
- static void ilk_program_watermarks(struct intel_crtc_state *cstate)
+ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
  {
-       struct drm_crtc *crtc = cstate->base.crtc;
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_device *dev = dev_priv->dev;
        struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
        struct ilk_wm_maximums max;
        struct intel_wm_config config = {};
        ilk_write_wm_values(dev_priv, &results);
  }
  
- static void ilk_update_wm(struct drm_crtc *crtc)
+ static void ilk_initial_watermarks(struct intel_crtc_state *cstate)
  {
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
-       WARN_ON(cstate->base.active != intel_crtc->active);
+       struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
+       struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
  
-       /*
-        * IVB workaround: must disable low power watermarks for at least
-        * one frame before enabling scaling.  LP watermarks can be re-enabled
-        * when scaling is disabled.
-        *
-        * WaCxSRDisabledForSpriteScaling:ivb
-        */
-       if (cstate->disable_lp_wm) {
-               ilk_disable_lp_wm(crtc->dev);
-               intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
-       }
+       mutex_lock(&dev_priv->wm.wm_mutex);
+       intel_crtc->wm.active.ilk = cstate->wm.intermediate;
+       ilk_program_watermarks(dev_priv);
+       mutex_unlock(&dev_priv->wm.wm_mutex);
+ }
  
-       intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
+ static void ilk_optimize_watermarks(struct intel_crtc_state *cstate)
+ {
+       struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
+       struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
  
-       ilk_program_watermarks(cstate);
+       mutex_lock(&dev_priv->wm.wm_mutex);
+       if (cstate->wm.need_postvbl_update) {
+               intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
+               ilk_program_watermarks(dev_priv);
+       }
+       mutex_unlock(&dev_priv->wm.wm_mutex);
  }
  
  static void skl_pipe_wm_active_state(uint32_t val,
@@@ -4243,7 -4302,7 +4302,7 @@@ static u32 intel_rps_limits(struct drm_
         * the hw runs at the minimal clock before selecting the desired
         * frequency, if the down threshold expires in that window we will not
         * receive a down interrupt. */
-       if (IS_GEN9(dev_priv->dev)) {
+       if (IS_GEN9(dev_priv)) {
                limits = (dev_priv->rps.max_freq_softlimit) << 23;
                if (val <= dev_priv->rps.min_freq_softlimit)
                        limits |= (dev_priv->rps.min_freq_softlimit) << 14;
@@@ -4528,7 -4587,7 +4587,7 @@@ void intel_set_rps(struct drm_device *d
                gen6_set_rps(dev, val);
  }
  
- static void gen9_disable_rps(struct drm_device *dev)
+ static void gen9_disable_rc6(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        I915_WRITE(GEN9_PG_ENABLE, 0);
  }
  
+ static void gen9_disable_rps(struct drm_device *dev)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       I915_WRITE(GEN6_RP_CONTROL, 0);
+ }
  static void gen6_disable_rps(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        I915_WRITE(GEN6_RC_CONTROL, 0);
        I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
+       I915_WRITE(GEN6_RP_CONTROL, 0);
  }
  
  static void cherryview_disable_rps(struct drm_device *dev)
@@@ -4585,7 -4652,8 +4652,8 @@@ static void intel_print_rc6_info(struc
  
  static bool bxt_check_bios_rc6_setup(const struct drm_device *dev)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        bool enable_rc6 = true;
        unsigned long rc6_ctx_base;
  
         * for this check.
         */
        rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK;
-       if (!((rc6_ctx_base >= dev_priv->gtt.stolen_reserved_base) &&
-             (rc6_ctx_base + PAGE_SIZE <= dev_priv->gtt.stolen_reserved_base +
-                                       dev_priv->gtt.stolen_reserved_size))) {
+       if (!((rc6_ctx_base >= ggtt->stolen_reserved_base) &&
+             (rc6_ctx_base + PAGE_SIZE <= ggtt->stolen_reserved_base +
+                                       ggtt->stolen_reserved_size))) {
                DRM_DEBUG_KMS("RC6 Base address not as expected.\n");
                enable_rc6 = false;
        }
@@@ -4744,6 -4812,16 +4812,16 @@@ static void gen9_enable_rps(struct drm_
  
        /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */
        if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) {
+               /*
+                * BIOS could leave the Hw Turbo enabled, so need to explicitly
+                * clear out the Control register just to avoid inconsitency
+                * with debugfs interface, which will show  Turbo as enabled
+                * only and that is not expected by the User after adding the
+                * WaGsvDisableTurbo. Apart from this there is no problem even
+                * if the Turbo is left enabled in the Control register, as the
+                * Up/Down interrupts would remain masked.
+                */
+               gen9_disable_rps(dev);
                intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
                return;
        }
         * Up/Down EI & threshold registers, as well as the RP_CONTROL,
         * RP_INTERRUPT_LIMITS & RPNSWREQ registers */
        dev_priv->rps.power = HIGH_POWER; /* force a reset */
-       gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
+       gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
  
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
  }
  static void gen9_enable_rc6(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        uint32_t rc6_mask = 0;
-       int unused;
  
        /* 1a: Software RC state - RC0 */
        I915_WRITE(GEN6_RC_STATE, 0);
                I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
-       for_each_ring(ring, dev_priv, unused)
-               I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+       for_each_engine(engine, dev_priv)
+               I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
  
        if (HAS_GUC_UCODE(dev))
                I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
  static void gen8_enable_rps(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        uint32_t rc6_mask = 0;
-       int unused;
  
        /* 1a: Software RC state - RC0 */
        I915_WRITE(GEN6_RC_STATE, 0);
        I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
-       for_each_ring(ring, dev_priv, unused)
-               I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+       for_each_engine(engine, dev_priv)
+               I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
        I915_WRITE(GEN6_RC_SLEEP, 0);
        if (IS_BROADWELL(dev))
                I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
  static void gen6_enable_rps(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        u32 rc6vids, pcu_mbox = 0, rc6_mask = 0;
        u32 gtfifodbg;
        int rc6_mode;
-       int i, ret;
+       int ret;
  
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  
        I915_WRITE(GEN6_RC_STATE, 0);
  
        /* Clear the DBG now so we don't confuse earlier errors */
-       if ((gtfifodbg = I915_READ(GTFIFODBG))) {
+       gtfifodbg = I915_READ(GTFIFODBG);
+       if (gtfifodbg) {
                DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
                I915_WRITE(GTFIFODBG, gtfifodbg);
        }
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
  
-       for_each_ring(ring, dev_priv, i)
-               I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+       for_each_engine(engine, dev_priv)
+               I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
  
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
@@@ -5244,9 -5321,9 +5321,9 @@@ static void cherryview_check_pctx(struc
  
  static void cherryview_setup_pctx(struct drm_device *dev)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct i915_ggtt *ggtt = &dev_priv->ggtt;
        unsigned long pctx_paddr, paddr;
-       struct i915_gtt *gtt = &dev_priv->gtt;
        u32 pcbr;
        int pctx_size = 32*1024;
  
        if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
                DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
                paddr = (dev_priv->mm.stolen_base +
-                        (gtt->stolen_size - pctx_size));
+                        (ggtt->stolen_size - pctx_size));
  
                pctx_paddr = (paddr & (~4095));
                I915_WRITE(VLV_PCBR, pctx_paddr);
@@@ -5322,6 -5399,17 +5399,17 @@@ static void valleyview_cleanup_pctx(str
        dev_priv->vlv_pctx = NULL;
  }
  
+ static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
+ {
+       dev_priv->rps.gpll_ref_freq =
+               vlv_get_cck_clock(dev_priv, "GPLL ref",
+                                 CCK_GPLL_CLOCK_CONTROL,
+                                 dev_priv->czclk_freq);
+       DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
+                        dev_priv->rps.gpll_ref_freq);
+ }
  static void valleyview_init_gt_powersave(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        valleyview_setup_pctx(dev);
  
+       vlv_init_gpll_ref_freq(dev_priv);
        mutex_lock(&dev_priv->rps.hw_lock);
  
        val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
@@@ -5386,6 -5476,8 +5476,8 @@@ static void cherryview_init_gt_powersav
  
        cherryview_setup_pctx(dev);
  
+       vlv_init_gpll_ref_freq(dev_priv);
        mutex_lock(&dev_priv->rps.hw_lock);
  
        mutex_lock(&dev_priv->sb_lock);
@@@ -5450,13 -5542,13 +5542,13 @@@ static void valleyview_cleanup_gt_power
  static void cherryview_enable_rps(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        u32 gtfifodbg, val, rc6_mode = 0, pcbr;
-       int i;
  
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  
-       gtfifodbg = I915_READ(GTFIFODBG);
+       gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
+                                            GT_FIFO_FREE_ENTRIES_CHV);
        if (gtfifodbg) {
                DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
                                 gtfifodbg);
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
  
-       for_each_ring(ring, dev_priv, i)
-               I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+       for_each_engine(engine, dev_priv)
+               I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
        I915_WRITE(GEN6_RC_SLEEP, 0);
  
        /* TO threshold set to 500 us ( 0x186 * 1.28 us) */
                         dev_priv->rps.cur_freq);
  
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
-                        intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-                        dev_priv->rps.efficient_freq);
+                        intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+                        dev_priv->rps.idle_freq);
  
-       valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
+       valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
  
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
  }
  static void valleyview_enable_rps(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        u32 gtfifodbg, val, rc6_mode = 0;
-       int i;
  
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  
        valleyview_check_pctx(dev_priv);
  
-       if ((gtfifodbg = I915_READ(GTFIFODBG))) {
+       gtfifodbg = I915_READ(GTFIFODBG);
+       if (gtfifodbg) {
                DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
                                 gtfifodbg);
                I915_WRITE(GTFIFODBG, gtfifodbg);
        I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
        I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
  
-       for_each_ring(ring, dev_priv, i)
-               I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+       for_each_engine(engine, dev_priv)
+               I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
  
        I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
  
                         dev_priv->rps.cur_freq);
  
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
-                        intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-                        dev_priv->rps.efficient_freq);
+                        intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
+                        dev_priv->rps.idle_freq);
  
-       valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
+       valleyview_set_rps(dev_priv->dev, dev_priv->rps.idle_freq);
  
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
  }
@@@ -5965,17 -6057,16 +6057,16 @@@ EXPORT_SYMBOL_GPL(i915_gpu_lower)
  bool i915_gpu_busy(void)
  {
        struct drm_i915_private *dev_priv;
-       struct intel_engine_cs *ring;
+       struct intel_engine_cs *engine;
        bool ret = false;
-       int i;
  
        spin_lock_irq(&mchdev_lock);
        if (!i915_mch_dev)
                goto out_unlock;
        dev_priv = i915_mch_dev;
  
-       for_each_ring(ring, dev_priv, i)
-               ret |= !list_empty(&ring->request_list);
+       for_each_engine(engine, dev_priv)
+               ret |= !list_empty(&engine->request_list);
  
  out_unlock:
        spin_unlock_irq(&mchdev_lock);
@@@ -6195,9 -6286,10 +6286,10 @@@ void intel_disable_gt_powersave(struct 
                intel_suspend_gt_powersave(dev);
  
                mutex_lock(&dev_priv->rps.hw_lock);
-               if (INTEL_INFO(dev)->gen >= 9)
+               if (INTEL_INFO(dev)->gen >= 9) {
+                       gen9_disable_rc6(dev);
                        gen9_disable_rps(dev);
-               else if (IS_CHERRYVIEW(dev))
+               else if (IS_CHERRYVIEW(dev))
                        cherryview_disable_rps(dev);
                else if (IS_VALLEYVIEW(dev))
                        valleyview_disable_rps(dev);
@@@ -6646,12 -6738,6 +6738,12 @@@ static void broadwell_init_clock_gating
        misccpctl = I915_READ(GEN7_MISCCPCTL);
        I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
        I915_WRITE(GEN8_L3SQCREG1, BDW_WA_L3SQCREG1_DEFAULT);
 +      /*
 +       * Wait at least 100 clocks before re-enabling clock gating. See
 +       * the definition of L3SQCREG1 in BSpec.
 +       */
 +      POSTING_READ(GEN8_L3SQCREG1);
 +      udelay(1);
        I915_WRITE(GEN7_MISCCPCTL, misccpctl);
  
        /*
@@@ -6818,23 -6904,10 +6910,10 @@@ static void ivybridge_init_clock_gating
        gen6_check_mch_setup(dev);
  }
  
- static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
- {
-       I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
-       /*
-        * Disable trickle feed and enable pnd deadline calculation
-        */
-       I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
-       I915_WRITE(CBR1_VLV, 0);
- }
  static void valleyview_init_clock_gating(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       vlv_init_display_clock_gating(dev_priv);
        /* WaDisableEarlyCull:vlv */
        I915_WRITE(_3D_CHICKEN3,
                   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
@@@ -6917,8 -6990,6 +6996,6 @@@ static void cherryview_init_clock_gatin
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       vlv_init_display_clock_gating(dev_priv);
        /* WaVSRefCountFullforceMissDisable:chv */
        /* WaDSRefCountFullforceMissDisable:chv */
        I915_WRITE(GEN7_FF_THREAD_MODE,
@@@ -7058,8 -7129,7 +7135,7 @@@ void intel_init_clock_gating(struct drm
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       if (dev_priv->display.init_clock_gating)
-               dev_priv->display.init_clock_gating(dev);
+       dev_priv->display.init_clock_gating(dev);
  }
  
  void intel_suspend_hw(struct drm_device *dev)
                lpt_suspend_hw(dev);
  }
  
+ static void nop_init_clock_gating(struct drm_device *dev)
+ {
+       DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n");
+ }
+ /**
+  * intel_init_clock_gating_hooks - setup the clock gating hooks
+  * @dev_priv: device private
+  *
+  * Setup the hooks that configure which clocks of a given platform can be
+  * gated and also apply various GT and display specific workarounds for these
+  * platforms. Note that some GT specific workarounds are applied separately
+  * when GPU contexts or batchbuffers start their execution.
+  */
+ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
+ {
+       if (IS_SKYLAKE(dev_priv))
+               dev_priv->display.init_clock_gating = nop_init_clock_gating;
+       else if (IS_KABYLAKE(dev_priv))
+               dev_priv->display.init_clock_gating = nop_init_clock_gating;
+       else if (IS_BROXTON(dev_priv))
+               dev_priv->display.init_clock_gating = bxt_init_clock_gating;
+       else if (IS_BROADWELL(dev_priv))
+               dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
+       else if (IS_CHERRYVIEW(dev_priv))
+               dev_priv->display.init_clock_gating = cherryview_init_clock_gating;
+       else if (IS_HASWELL(dev_priv))
+               dev_priv->display.init_clock_gating = haswell_init_clock_gating;
+       else if (IS_IVYBRIDGE(dev_priv))
+               dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
+       else if (IS_VALLEYVIEW(dev_priv))
+               dev_priv->display.init_clock_gating = valleyview_init_clock_gating;
+       else if (IS_GEN6(dev_priv))
+               dev_priv->display.init_clock_gating = gen6_init_clock_gating;
+       else if (IS_GEN5(dev_priv))
+               dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
+       else if (IS_G4X(dev_priv))
+               dev_priv->display.init_clock_gating = g4x_init_clock_gating;
+       else if (IS_CRESTLINE(dev_priv))
+               dev_priv->display.init_clock_gating = crestline_init_clock_gating;
+       else if (IS_BROADWATER(dev_priv))
+               dev_priv->display.init_clock_gating = broadwater_init_clock_gating;
+       else if (IS_GEN3(dev_priv))
+               dev_priv->display.init_clock_gating = gen3_init_clock_gating;
+       else if (IS_I85X(dev_priv) || IS_I865G(dev_priv))
+               dev_priv->display.init_clock_gating = i85x_init_clock_gating;
+       else if (IS_GEN2(dev_priv))
+               dev_priv->display.init_clock_gating = i830_init_clock_gating;
+       else {
+               MISSING_CASE(INTEL_DEVID(dev_priv));
+               dev_priv->display.init_clock_gating = nop_init_clock_gating;
+       }
+ }
  /* Set up chip specific power management-related functions */
  void intel_init_pm(struct drm_device *dev)
  {
        /* For FIFO watermark updates */
        if (INTEL_INFO(dev)->gen >= 9) {
                skl_setup_wm_latency(dev);
-               if (IS_BROXTON(dev))
-                       dev_priv->display.init_clock_gating =
-                               bxt_init_clock_gating;
                dev_priv->display.update_wm = skl_update_wm;
        } else if (HAS_PCH_SPLIT(dev)) {
                ilk_setup_wm_latency(dev);
                     dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) ||
                    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
                     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
-                       dev_priv->display.update_wm = ilk_update_wm;
                        dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm;
-                       dev_priv->display.program_watermarks = ilk_program_watermarks;
+                       dev_priv->display.compute_intermediate_wm =
+                               ilk_compute_intermediate_wm;
+                       dev_priv->display.initial_watermarks =
+                               ilk_initial_watermarks;
+                       dev_priv->display.optimize_watermarks =
+                               ilk_optimize_watermarks;
                } else {
                        DRM_DEBUG_KMS("Failed to read display plane latency. "
                                      "Disable CxSR\n");
                }
-               if (IS_GEN5(dev))
-                       dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
-               else if (IS_GEN6(dev))
-                       dev_priv->display.init_clock_gating = gen6_init_clock_gating;
-               else if (IS_IVYBRIDGE(dev))
-                       dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
-               else if (IS_HASWELL(dev))
-                       dev_priv->display.init_clock_gating = haswell_init_clock_gating;
-               else if (INTEL_INFO(dev)->gen == 8)
-                       dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
        } else if (IS_CHERRYVIEW(dev)) {
                vlv_setup_wm_latency(dev);
                dev_priv->display.update_wm = vlv_update_wm;
-               dev_priv->display.init_clock_gating =
-                       cherryview_init_clock_gating;
        } else if (IS_VALLEYVIEW(dev)) {
                vlv_setup_wm_latency(dev);
                dev_priv->display.update_wm = vlv_update_wm;
-               dev_priv->display.init_clock_gating =
-                       valleyview_init_clock_gating;
        } else if (IS_PINEVIEW(dev)) {
                if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
                                            dev_priv->is_ddr3,
                        dev_priv->display.update_wm = NULL;
                } else
                        dev_priv->display.update_wm = pineview_update_wm;
-               dev_priv->display.init_clock_gating = gen3_init_clock_gating;
        } else if (IS_G4X(dev)) {
                dev_priv->display.update_wm = g4x_update_wm;
-               dev_priv->display.init_clock_gating = g4x_init_clock_gating;
        } else if (IS_GEN4(dev)) {
                dev_priv->display.update_wm = i965_update_wm;
-               if (IS_CRESTLINE(dev))
-                       dev_priv->display.init_clock_gating = crestline_init_clock_gating;
-               else if (IS_BROADWATER(dev))
-                       dev_priv->display.init_clock_gating = broadwater_init_clock_gating;
        } else if (IS_GEN3(dev)) {
                dev_priv->display.update_wm = i9xx_update_wm;
                dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
-               dev_priv->display.init_clock_gating = gen3_init_clock_gating;
        } else if (IS_GEN2(dev)) {
                if (INTEL_INFO(dev)->num_pipes == 1) {
                        dev_priv->display.update_wm = i845_update_wm;
                        dev_priv->display.update_wm = i9xx_update_wm;
                        dev_priv->display.get_fifo_size = i830_get_fifo_size;
                }
-               if (IS_I85X(dev) || IS_I865G(dev))
-                       dev_priv->display.init_clock_gating = i85x_init_clock_gating;
-               else
-                       dev_priv->display.init_clock_gating = i830_init_clock_gating;
        } else {
                DRM_ERROR("unexpected fall-through in intel_init_pm\n");
        }
@@@ -7221,78 -7316,43 +7322,43 @@@ int sandybridge_pcode_write(struct drm_
        return 0;
  }
  
- static int vlv_gpu_freq_div(unsigned int czclk_freq)
- {
-       switch (czclk_freq) {
-       case 200:
-               return 10;
-       case 267:
-               return 12;
-       case 320:
-       case 333:
-               return 16;
-       case 400:
-               return 20;
-       default:
-               return -1;
-       }
- }
  static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
  {
-       int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-       div = vlv_gpu_freq_div(czclk_freq);
-       if (div < 0)
-               return div;
-       return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div);
+       /*
+        * N = val - 0xb7
+        * Slow = Fast = GPLL ref * N
+        */
+       return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000);
  }
  
  static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
  {
-       int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-       mul = vlv_gpu_freq_div(czclk_freq);
-       if (mul < 0)
-               return mul;
-       return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6;
+       return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7;
  }
  
  static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
  {
-       int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-       div = vlv_gpu_freq_div(czclk_freq);
-       if (div < 0)
-               return div;
-       div /= 2;
-       return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2;
+       /*
+        * N = val / 2
+        * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
+        */
+       return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000);
  }
  
  static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
  {
-       int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
-       mul = vlv_gpu_freq_div(czclk_freq);
-       if (mul < 0)
-               return mul;
-       mul /= 2;
        /* CHV needs even values */
-       return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2;
+       return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2;
  }
  
  int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
  {
-       if (IS_GEN9(dev_priv->dev))
+       if (IS_GEN9(dev_priv))
                return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
                                         GEN9_FREQ_SCALER);
-       else if (IS_CHERRYVIEW(dev_priv->dev))
+       else if (IS_CHERRYVIEW(dev_priv))
                return chv_gpu_freq(dev_priv, val);
-       else if (IS_VALLEYVIEW(dev_priv->dev))
+       else if (IS_VALLEYVIEW(dev_priv))
                return byt_gpu_freq(dev_priv, val);
        else
                return val * GT_FREQUENCY_MULTIPLIER;
  
  int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
  {
-       if (IS_GEN9(dev_priv->dev))
+       if (IS_GEN9(dev_priv))
                return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
                                         GT_FREQUENCY_MULTIPLIER);
-       else if (IS_CHERRYVIEW(dev_priv->dev))
+       else if (IS_CHERRYVIEW(dev_priv))
                return chv_freq_opcode(dev_priv, val);
-       else if (IS_VALLEYVIEW(dev_priv->dev))
+       else if (IS_VALLEYVIEW(dev_priv))
                return byt_freq_opcode(dev_priv, val);
        else
                return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
@@@ -7322,7 -7382,7 +7388,7 @@@ static void __intel_rps_boost_work(stru
        struct drm_i915_gem_request *req = boost->req;
  
        if (!i915_gem_request_completed(req, true))
-               gen6_rps_boost(to_i915(req->ring->dev), NULL,
+               gen6_rps_boost(to_i915(req->engine->dev), NULL,
                               req->emitted_jiffies);
  
        i915_gem_request_unreference__unlocked(req);
index 23d25283616cb3dbd62e3e072fa2ffab2a4a9933,a9a001150b9edae73b4a588873003997fdc447f0..b89ca5174863e7ab73c48117605ded1d56626e19
   */
  
  /* make sure these don't conflict w/ MSM_SUBMIT_BO_x */
- #define BO_VALID    0x8000
+ #define BO_VALID    0x8000   /* is current addr in cmdstream correct/valid? */
  #define BO_LOCKED   0x4000
  #define BO_PINNED   0x2000
  
 -static inline void __user *to_user_ptr(u64 address)
 -{
 -      return (void __user *)(uintptr_t)address;
 -}
 -
  static struct msm_gem_submit *submit_create(struct drm_device *dev,
                struct msm_gpu *gpu, int nr)
  {
        int sz = sizeof(*submit) + (nr * sizeof(submit->bos[0]));
  
        submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
-       if (submit) {
-               submit->dev = dev;
-               submit->gpu = gpu;
+       if (!submit)
+               return NULL;
  
-               /* initially, until copy_from_user() and bo lookup succeeds: */
-               submit->nr_bos = 0;
-               submit->nr_cmds = 0;
+       submit->dev = dev;
+       submit->gpu = gpu;
+       submit->pid = get_pid(task_pid(current));
  
-               INIT_LIST_HEAD(&submit->bo_list);
-               ww_acquire_init(&submit->ticket, &reservation_ww_class);
-       }
+       /* initially, until copy_from_user() and bo lookup succeeds: */
+       submit->nr_bos = 0;
+       submit->nr_cmds = 0;
+       INIT_LIST_HEAD(&submit->bo_list);
+       ww_acquire_init(&submit->ticket, &reservation_ww_class);
  
        return submit;
  }
  
+ void msm_gem_submit_free(struct msm_gem_submit *submit)
+ {
+       fence_put(submit->fence);
+       list_del(&submit->node);
+       put_pid(submit->pid);
+       kfree(submit);
+ }
  static int submit_lookup_objects(struct msm_gem_submit *submit,
                struct drm_msm_gem_submit *args, struct drm_file *file)
  {
@@@ -63,7 -78,7 +73,7 @@@
                struct drm_gem_object *obj;
                struct msm_gem_object *msm_obj;
                void __user *userptr =
 -                      to_user_ptr(args->bos + (i * sizeof(submit_bo)));
 +                      u64_to_user_ptr(args->bos + (i * sizeof(submit_bo)));
  
                ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
                if (ret) {
@@@ -131,16 -146,13 +141,13 @@@ static void submit_unlock_unpin_bo(stru
  }
  
  /* This is where we make sure all the bo's are reserved and pin'd: */
- static int submit_validate_objects(struct msm_gem_submit *submit)
+ static int submit_lock_objects(struct msm_gem_submit *submit)
  {
        int contended, slow_locked = -1, i, ret = 0;
  
  retry:
-       submit->valid = true;
        for (i = 0; i < submit->nr_bos; i++) {
                struct msm_gem_object *msm_obj = submit->bos[i].obj;
-               uint32_t iova;
  
                if (slow_locked == i)
                        slow_locked = -1;
                                goto fail;
                        submit->bos[i].flags |= BO_LOCKED;
                }
-               /* if locking succeeded, pin bo: */
-               ret = msm_gem_get_iova_locked(&msm_obj->base,
-                               submit->gpu->id, &iova);
-               /* this would break the logic in the fail path.. there is no
-                * reason for this to happen, but just to be on the safe side
-                * let's notice if this starts happening in the future:
-                */
-               WARN_ON(ret == -EDEADLK);
-               if (ret)
-                       goto fail;
-               submit->bos[i].flags |= BO_PINNED;
-               if (iova == submit->bos[i].iova) {
-                       submit->bos[i].flags |= BO_VALID;
-               } else {
-                       submit->bos[i].iova = iova;
-                       submit->bos[i].flags &= ~BO_VALID;
-                       submit->valid = false;
-               }
        }
  
        ww_acquire_done(&submit->ticket);
@@@ -206,6 -194,54 +189,54 @@@ fail
        return ret;
  }
  
+ static int submit_fence_sync(struct msm_gem_submit *submit)
+ {
+       int i, ret = 0;
+       for (i = 0; i < submit->nr_bos; i++) {
+               struct msm_gem_object *msm_obj = submit->bos[i].obj;
+               bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE;
+               ret = msm_gem_sync_object(&msm_obj->base, submit->gpu->fctx, write);
+               if (ret)
+                       break;
+       }
+       return ret;
+ }
+ static int submit_pin_objects(struct msm_gem_submit *submit)
+ {
+       int i, ret = 0;
+       submit->valid = true;
+       for (i = 0; i < submit->nr_bos; i++) {
+               struct msm_gem_object *msm_obj = submit->bos[i].obj;
+               uint32_t iova;
+               /* if locking succeeded, pin bo: */
+               ret = msm_gem_get_iova_locked(&msm_obj->base,
+                               submit->gpu->id, &iova);
+               if (ret)
+                       break;
+               submit->bos[i].flags |= BO_PINNED;
+               if (iova == submit->bos[i].iova) {
+                       submit->bos[i].flags |= BO_VALID;
+               } else {
+                       submit->bos[i].iova = iova;
+                       /* iova changed, so address in cmdstream is not valid: */
+                       submit->bos[i].flags &= ~BO_VALID;
+                       submit->valid = false;
+               }
+       }
+       return ret;
+ }
  static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
                struct msm_gem_object **obj, uint32_t *iova, bool *valid)
  {
@@@ -252,7 -288,7 +283,7 @@@ static int submit_reloc(struct msm_gem_
        for (i = 0; i < nr_relocs; i++) {
                struct drm_msm_gem_submit_reloc submit_reloc;
                void __user *userptr =
 -                      to_user_ptr(relocs + (i * sizeof(submit_reloc)));
 +                      u64_to_user_ptr(relocs + (i * sizeof(submit_reloc)));
                uint32_t iova, off;
                bool valid;
  
        return 0;
  }
  
- static void submit_cleanup(struct msm_gem_submit *submit, bool fail)
+ static void submit_cleanup(struct msm_gem_submit *submit)
  {
        unsigned i;
  
@@@ -344,14 -380,22 +375,22 @@@ int msm_ioctl_gem_submit(struct drm_dev
        if (ret)
                goto out;
  
-       ret = submit_validate_objects(submit);
+       ret = submit_lock_objects(submit);
+       if (ret)
+               goto out;
+       ret = submit_fence_sync(submit);
+       if (ret)
+               goto out;
+       ret = submit_pin_objects(submit);
        if (ret)
                goto out;
  
        for (i = 0; i < args->nr_cmds; i++) {
                struct drm_msm_gem_submit_cmd submit_cmd;
                void __user *userptr =
 -                      to_user_ptr(args->cmds + (i * sizeof(submit_cmd)));
 +                      u64_to_user_ptr(args->cmds + (i * sizeof(submit_cmd)));
                struct msm_gem_object *msm_obj;
                uint32_t iova;
  
  
        ret = msm_gpu_submit(gpu, submit, ctx);
  
-       args->fence = submit->fence;
+       args->fence = submit->fence->seqno;
  
  out:
-       submit_cleanup(submit, !!ret);
+       submit_cleanup(submit);
+       if (ret)
+               msm_gem_submit_free(submit);
        mutex_unlock(&dev->struct_mutex);
        return ret;
  }
index 532127c55de64197698336c92d602b0ff3043071,bdc7b9ee193022672a53b930a71464ce34af68fd..2e216e2ea78c3535a07b761327c04c345a6667ff
@@@ -1375,6 -1375,11 +1375,11 @@@ static int dce4_crtc_do_set_base(struc
                break;
        }
  
+       /* Make sure surface address is updated at vertical blank rather than
+        * horizontal blank
+        */
+       WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
               upper_32_bits(fb_location));
        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (viewport_w << 16) | viewport_h);
  
-       /* pageflip setup */
-       /* make sure flip is at vb rather than hb */
-       tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
-       tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
-       WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
        /* set pageflip to happen only at start of vblank interval (front porch) */
        WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
  
@@@ -1466,7 -1465,7 +1465,7 @@@ static int avivo_crtc_do_set_base(struc
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
-       u32 tmp, viewport_w, viewport_h;
+       u32 viewport_w, viewport_h;
        int r;
        bool bypass_lut = false;
  
        else
                WREG32(AVIVO_D2VGA_CONTROL, 0);
  
+       /* Make sure surface address is update at vertical blank rather than
+        * horizontal blank
+        */
+       WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
        if (rdev->family >= CHIP_RV770) {
                if (radeon_crtc->crtc_id) {
                        WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
               (viewport_w << 16) | viewport_h);
  
-       /* pageflip setup */
-       /* make sure flip is at vb rather than hb */
-       tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
-       tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
-       WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
        /* set pageflip to happen only at start of vblank interval (front porch) */
        WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
  
@@@ -1742,7 -1740,6 +1740,7 @@@ static u32 radeon_get_pll_use_mask(stru
  static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
  {
        struct drm_device *dev = crtc->dev;
 +      struct radeon_device *rdev = dev->dev_private;
        struct drm_crtc *test_crtc;
        struct radeon_crtc *test_radeon_crtc;
  
                test_radeon_crtc = to_radeon_crtc(test_crtc);
                if (test_radeon_crtc->encoder &&
                    ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
 +                      /* PPLL2 is exclusive to UNIPHYA on DCE61 */
 +                      if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
 +                          test_radeon_crtc->pll_id == ATOM_PPLL2)
 +                              continue;
                        /* for DP use the same PLL for all */
                        if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
                                return test_radeon_crtc->pll_id;
@@@ -1777,7 -1770,6 +1775,7 @@@ static int radeon_get_shared_nondp_ppll
  {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
 +      struct radeon_device *rdev = dev->dev_private;
        struct drm_crtc *test_crtc;
        struct radeon_crtc *test_radeon_crtc;
        u32 adjusted_clock, test_adjusted_clock;
                test_radeon_crtc = to_radeon_crtc(test_crtc);
                if (test_radeon_crtc->encoder &&
                    !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
 +                      /* PPLL2 is exclusive to UNIPHYA on DCE61 */
 +                      if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
 +                          test_radeon_crtc->pll_id == ATOM_PPLL2)
 +                              continue;
                        /* check if we are already driving this connector with another crtc */
                        if (test_radeon_crtc->connector == radeon_crtc->connector) {
                                /* if we are, return that pll */
index 109b10651959dd3206c2b928acada78e157840bc,143dd98aa0793208753de64056ec9bc5666dae7e..3446ece21b4ab4e2d38280ad0b2c5733207ffd20
@@@ -81,6 -81,7 +81,7 @@@ static struct drm_driver vc4_drm_drive
                            DRIVER_ATOMIC |
                            DRIVER_GEM |
                            DRIVER_HAVE_IRQ |
+                           DRIVER_RENDER |
                            DRIVER_PRIME),
        .lastclose = vc4_lastclose,
        .irq_handler = vc4_irq,
@@@ -153,24 -154,6 +154,24 @@@ static void vc4_match_add_drivers(struc
        }
  }
  
 +static void vc4_kick_out_firmware_fb(void)
 +{
 +      struct apertures_struct *ap;
 +
 +      ap = alloc_apertures(1);
 +      if (!ap)
 +              return;
 +
 +      /* Since VC4 is a UMA device, the simplefb node may have been
 +       * located anywhere in memory.
 +       */
 +      ap->ranges[0].base = 0;
 +      ap->ranges[0].size = ~0;
 +
 +      remove_conflicting_framebuffers(ap, "vc4drmfb", false);
 +      kfree(ap);
 +}
 +
  static int vc4_drm_bind(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
        if (ret)
                goto gem_destroy;
  
 +      vc4_kick_out_firmware_fb();
 +
        ret = drm_dev_register(drm, 0);
        if (ret < 0)
                goto unbind_all;
@@@ -257,6 -238,7 +258,7 @@@ static const struct component_master_op
  
  static struct platform_driver *const component_drivers[] = {
        &vc4_hdmi_driver,
+       &vc4_dpi_driver,
        &vc4_crtc_driver,
        &vc4_hvs_driver,
        &vc4_v3d_driver,
diff --combined include/linux/console.h
index 137ac1a1c16fc93fcf5c5feeffc5fb8f31631185,e49cc1ef19be14fbfe4db94614461f9875b64610..98c8615dc300cb843766a157deadca248364d686
@@@ -47,7 -47,7 +47,7 @@@ struct consw 
        int     (*con_font_copy)(struct vc_data *, int);
        int     (*con_resize)(struct vc_data *, unsigned int, unsigned int,
                               unsigned int);
 -      int     (*con_set_palette)(struct vc_data *, unsigned char *);
 +      int     (*con_set_palette)(struct vc_data *, const unsigned char *);
        int     (*con_scrolldelta)(struct vc_data *, int);
        int     (*con_set_origin)(struct vc_data *);
        void    (*con_save_screen)(struct vc_data *);
@@@ -191,6 -191,8 +191,8 @@@ void vcs_remove_sysfs(int index)
  
  #ifdef CONFIG_VGA_CONSOLE
  extern bool vgacon_text_force(void);
+ #else
+ static inline bool vgacon_text_force(void) { return false; }
  #endif
  
  #endif /* _LINUX_CONSOLE_H */
diff --combined include/linux/vmalloc.h
index 957adb741b6f7d97742079e266ca3c72d22d4542,8b51df3ab3347001a535f7444345b5887859691a..3d9d786a943cacd7321b208f59ff4a4467c561df
@@@ -4,11 -4,11 +4,12 @@@
  #include <linux/spinlock.h>
  #include <linux/init.h>
  #include <linux/list.h>
 +#include <linux/llist.h>
  #include <asm/page.h>         /* pgprot_t */
  #include <linux/rbtree.h>
  
  struct vm_area_struct;                /* vma defining user mapping in mm_types.h */
+ struct notifier_block;                /* in notifier.h */
  
  /* bits in flags of vmalloc's vm_struct below */
  #define VM_IOREMAP            0x00000001      /* ioremap() and friends */
@@@ -45,7 -45,7 +46,7 @@@ struct vmap_area 
        unsigned long flags;
        struct rb_node rb_node;         /* address sorted rbtree */
        struct list_head list;          /* address sorted list */
 -      struct list_head purge_list;    /* "lazy purge" list */
 +      struct llist_node purge_list;    /* "lazy purge" list */
        struct vm_struct *vm;
        struct rcu_head rcu_head;
  };
@@@ -188,4 -188,7 +189,7 @@@ pcpu_free_vm_areas(struct vm_struct **v
  #define VMALLOC_TOTAL 0UL
  #endif
  
+ int register_vmap_purge_notifier(struct notifier_block *nb);
+ int unregister_vmap_purge_notifier(struct notifier_block *nb);
  #endif /* _LINUX_VMALLOC_H */
diff --combined mm/vmalloc.c
index 6e3291882739b664c2bbb2805c136a41ca0dd870,293889d7f482995daf8d39de6174698fbeea20be..cf7ad1a53be03b866ecee6325c47abef278d70fc
@@@ -21,6 -21,7 +21,7 @@@
  #include <linux/debugobjects.h>
  #include <linux/kallsyms.h>
  #include <linux/list.h>
+ #include <linux/notifier.h>
  #include <linux/rbtree.h>
  #include <linux/radix-tree.h>
  #include <linux/rcupdate.h>
@@@ -274,12 -275,13 +275,12 @@@ EXPORT_SYMBOL(vmalloc_to_pfn)
  
  /*** Global kva allocator ***/
  
 -#define VM_LAZY_FREE  0x01
 -#define VM_LAZY_FREEING       0x02
  #define VM_VM_AREA    0x04
  
  static DEFINE_SPINLOCK(vmap_area_lock);
  /* Export for kexec only */
  LIST_HEAD(vmap_area_list);
 +static LLIST_HEAD(vmap_purge_list);
  static struct rb_root vmap_area_root = RB_ROOT;
  
  /* The vmap cache globals are protected by vmap_area_lock */
@@@ -343,6 -345,8 +344,8 @@@ static void __insert_vmap_area(struct v
  
  static void purge_vmap_area_lazy(void);
  
+ static BLOCKING_NOTIFIER_HEAD(vmap_notify_list);
  /*
   * Allocate a region of KVA of the specified size and alignment, within the
   * vstart and vend.
@@@ -362,6 -366,8 +365,8 @@@ static struct vmap_area *alloc_vmap_are
        BUG_ON(offset_in_page(size));
        BUG_ON(!is_power_of_2(align));
  
+       might_sleep_if(gfpflags_allow_blocking(gfp_mask));
        va = kmalloc_node(sizeof(struct vmap_area),
                        gfp_mask & GFP_RECLAIM_MASK, node);
        if (unlikely(!va))
@@@ -467,6 -473,16 +472,16 @@@ overflow
                purged = 1;
                goto retry;
        }
+       if (gfpflags_allow_blocking(gfp_mask)) {
+               unsigned long freed = 0;
+               blocking_notifier_call_chain(&vmap_notify_list, 0, &freed);
+               if (freed > 0) {
+                       purged = 0;
+                       goto retry;
+               }
+       }
        if (printk_ratelimit())
                pr_warn("vmap allocation for size %lu failed: use vmalloc=<size> to increase size\n",
                        size);
        return ERR_PTR(-EBUSY);
  }
  
+ int register_vmap_purge_notifier(struct notifier_block *nb)
+ {
+       return blocking_notifier_chain_register(&vmap_notify_list, nb);
+ }
+ EXPORT_SYMBOL_GPL(register_vmap_purge_notifier);
+ int unregister_vmap_purge_notifier(struct notifier_block *nb)
+ {
+       return blocking_notifier_chain_unregister(&vmap_notify_list, nb);
+ }
+ EXPORT_SYMBOL_GPL(unregister_vmap_purge_notifier);
  static void __free_vmap_area(struct vmap_area *va)
  {
        BUG_ON(RB_EMPTY_NODE(&va->rb_node));
@@@ -600,7 -628,7 +627,7 @@@ static void __purge_vmap_area_lazy(unsi
                                        int sync, int force_flush)
  {
        static DEFINE_SPINLOCK(purge_lock);
 -      LIST_HEAD(valist);
 +      struct llist_node *valist;
        struct vmap_area *va;
        struct vmap_area *n_va;
        int nr = 0;
        if (sync)
                purge_fragmented_blocks_allcpus();
  
 -      rcu_read_lock();
 -      list_for_each_entry_rcu(va, &vmap_area_list, list) {
 -              if (va->flags & VM_LAZY_FREE) {
 -                      if (va->va_start < *start)
 -                              *start = va->va_start;
 -                      if (va->va_end > *end)
 -                              *end = va->va_end;
 -                      nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
 -                      list_add_tail(&va->purge_list, &valist);
 -                      va->flags |= VM_LAZY_FREEING;
 -                      va->flags &= ~VM_LAZY_FREE;
 -              }
 +      valist = llist_del_all(&vmap_purge_list);
 +      llist_for_each_entry(va, valist, purge_list) {
 +              if (va->va_start < *start)
 +                      *start = va->va_start;
 +              if (va->va_end > *end)
 +                      *end = va->va_end;
 +              nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
        }
 -      rcu_read_unlock();
  
        if (nr)
                atomic_sub(nr, &vmap_lazy_nr);
  
        if (nr) {
                spin_lock(&vmap_area_lock);
 -              list_for_each_entry_safe(va, n_va, &valist, purge_list)
 +              llist_for_each_entry_safe(va, n_va, valist, purge_list)
                        __free_vmap_area(va);
                spin_unlock(&vmap_area_lock);
        }
@@@ -671,15 -705,9 +698,15 @@@ static void purge_vmap_area_lazy(void
   */
  static void free_vmap_area_noflush(struct vmap_area *va)
  {
 -      va->flags |= VM_LAZY_FREE;
 -      atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
 -      if (unlikely(atomic_read(&vmap_lazy_nr) > lazy_max_pages()))
 +      int nr_lazy;
 +
 +      nr_lazy = atomic_add_return((va->va_end - va->va_start) >> PAGE_SHIFT,
 +                                  &vmap_lazy_nr);
 +
 +      /* After this point, we may free va at any time */
 +      llist_add(&va->purge_list, &vmap_purge_list);
 +
 +      if (unlikely(nr_lazy > lazy_max_pages()))
                try_purge_vmap_area_lazy();
  }
  
This page took 0.836407 seconds and 4 git commands to generate.