Back-merge tag 'v4.7-rc5' into drm-next
authorDave Airlie <airlied@redhat.com>
Sat, 2 Jul 2016 05:56:01 +0000 (15:56 +1000)
committerDave Airlie <airlied@redhat.com>
Sat, 2 Jul 2016 05:56:01 +0000 (15:56 +1000)
Linux 4.7-rc5

The fsl-dcu pull needs -rc3 so go to -rc5 for now.

23 files changed:
1  2 
MAINTAINERS
Makefile
arch/arc/boot/dts/nsimosci.dts
arch/arc/boot/dts/nsimosci_hs.dts
arch/arc/boot/dts/nsimosci_hs_idu.dts
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbc.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/sun4i/sun4i_drv.c
drivers/gpu/drm/sun4i/sun4i_rgb.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/gpu/drm/vc4/vc4_drv.c
drivers/gpu/drm/vc4/vc4_kms.c

diff --combined MAINTAINERS
@@@ -865,17 -865,9 +865,17 @@@ F:       Documentation/devicetree/bindings/di
  ARM HDLCD DRM DRIVER
  M:    Liviu Dudau <liviu.dudau@arm.com>
  S:    Supported
 -F:    drivers/gpu/drm/arm/
 +F:    drivers/gpu/drm/arm/hdlcd_*
  F:    Documentation/devicetree/bindings/display/arm,hdlcd.txt
  
 +ARM MALI-DP DRM DRIVER
 +M:    Liviu Dudau <liviu.dudau@arm.com>
 +M:    Brian Starkey <brian.starkey@arm.com>
 +M:    Mali DP Maintainers <malidp@foss.arm.com>
 +S:    Supported
 +F:    drivers/gpu/drm/arm/
 +F:    Documentation/devicetree/bindings/display/arm,malidp.txt
 +
  ARM MFM AND FLOPPY DRIVERS
  M:    Ian Molton <spyro@f2s.com>
  S:    Maintained
@@@ -1167,6 -1159,7 +1167,7 @@@ F:      arch/arm/mach-footbridge
  ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
  M:    Shawn Guo <shawnguo@kernel.org>
  M:    Sascha Hauer <kernel@pengutronix.de>
+ R:    Fabio Estevam <fabio.estevam@nxp.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
@@@ -2250,7 -2243,8 +2251,8 @@@ F:      include/net/ax25.
  F:    net/ax25/
  
  AZ6007 DVB DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -2717,7 -2711,8 +2719,8 @@@ F:      Documentation/filesystems/btrfs.tx
  F:    fs/btrfs/
  
  BTTV VIDEO4LINUX DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -2781,9 -2776,9 +2784,9 @@@ F:      include/net/caif
  F:    net/caif/
  
  CALGARY x86-64 IOMMU
- M:    Muli Ben-Yehuda <muli@il.ibm.com>
- M:    "Jon D. Mason" <jdmason@kudzu.us>
- L:    discuss@x86-64.org
+ M:    Muli Ben-Yehuda <mulix@mulix.org>
+ M:    Jon Mason <jdmason@kudzu.us>
+ L:    iommu@lists.linux-foundation.org
  S:    Maintained
  F:    arch/x86/kernel/pci-calgary_64.c
  F:    arch/x86/kernel/tce_64.c
@@@ -3094,6 -3089,7 +3097,7 @@@ M:      Stephen Boyd <sboyd@codeaurora.org
  L:    linux-clk@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
  S:    Maintained
+ F:    Documentation/devicetree/bindings/clock/
  F:    drivers/clk/
  X:    drivers/clk/clkdev.c
  F:    include/linux/clk-pr*
@@@ -3351,7 -3347,8 +3355,8 @@@ S:      Maintaine
  F:    drivers/media/dvb-frontends/cx24120*
  
  CX88 VIDEO4LINUX DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -3781,6 -3778,7 +3786,7 @@@ Q:      https://patchwork.kernel.org/project
  S:    Maintained
  F:    drivers/dma/
  F:    include/linux/dmaengine.h
+ F:    Documentation/devicetree/bindings/dma/
  F:    Documentation/dmaengine/
  T:    git git://git.infradead.org/users/vkoul/slave-dma.git
  
@@@ -3862,10 -3860,7 +3868,10 @@@ T:    git git://people.freedesktop.org/~ai
  S:    Maintained
  F:    drivers/gpu/drm/
  F:    drivers/gpu/vga/
 -F:    Documentation/DocBook/gpu.*
 +F:    Documentation/devicetree/bindings/display/
 +F:    Documentation/devicetree/bindings/gpu/
 +F:    Documentation/devicetree/bindings/video/
 +F:    Documentation/gpu/
  F:    include/drm/
  F:    include/uapi/drm/
  
@@@ -3917,7 -3912,6 +3923,7 @@@ S:      Supporte
  F:    drivers/gpu/drm/i915/
  F:    include/drm/i915*
  F:    include/uapi/drm/i915_drm.h
 +F:    Documentation/gpu/i915.rst
  
  DRM DRIVERS FOR ATMEL HLCDC
  M:    Boris Brezillon <boris.brezillon@free-electrons.com>
@@@ -4113,21 -4107,6 +4119,21 @@@ F:    drivers/gpu/drm/vc4
  F:    include/uapi/drm/vc4_drm.h
  F:    Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
  
 +DRM DRIVERS FOR TI OMAP
 +M:    Tomi Valkeinen <tomi.valkeinen@ti.com>
 +L:    dri-devel@lists.freedesktop.org
 +S:    Maintained
 +F:    drivers/gpu/drm/omapdrm/
 +F:    Documentation/devicetree/bindings/display/ti/
 +
 +DRM DRIVERS FOR TI LCDC
 +M:    Jyri Sarha <jsarha@ti.com>
 +R:    Tomi Valkeinen <tomi.valkeinen@ti.com>
 +L:    dri-devel@lists.freedesktop.org
 +S:    Maintained
 +F:    drivers/gpu/drm/tilcdc/
 +F:    Documentation/devicetree/bindings/display/tilcdc/
 +
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <klimov.linux@gmail.com>
  L:    linux-media@vger.kernel.org
@@@ -4317,7 -4296,8 +4323,8 @@@ F:      fs/ecryptfs
  EDAC-CORE
  M:    Doug Thompson <dougthompson@xmission.com>
  M:    Borislav Petkov <bp@alien8.de>
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
@@@ -4362,7 -4342,8 +4369,8 @@@ S:      Maintaine
  F:    drivers/edac/e7xxx_edac.c
  
  EDAC-GHES
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  S:    Maintained
  F:    drivers/edac/ghes_edac.c
@@@ -4386,19 -4367,22 +4394,22 @@@ S:   Maintaine
  F:    drivers/edac/i5000_edac.c
  
  EDAC-I5400
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  S:    Maintained
  F:    drivers/edac/i5400_edac.c
  
  EDAC-I7300
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  S:    Maintained
  F:    drivers/edac/i7300_edac.c
  
  EDAC-I7CORE
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  S:    Maintained
  F:    drivers/edac/i7core_edac.c
@@@ -4435,7 -4419,8 +4446,8 @@@ S:      Maintaine
  F:    drivers/edac/r82600_edac.c
  
  EDAC-SBRIDGE
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-edac@vger.kernel.org
  S:    Maintained
  F:    drivers/edac/sb_edac.c
@@@ -4494,7 -4479,8 +4506,8 @@@ S:      Maintaine
  F:    drivers/net/ethernet/ibm/ehea/
  
  EM28XX VIDEO4LINUX DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -6513,6 -6499,7 +6526,7 @@@ F:      include/uapi/linux/sunrpc
  
  KERNEL SELFTEST FRAMEWORK
  M:    Shuah Khan <shuahkh@osg.samsung.com>
+ M:    Shuah Khan <shuah@kernel.org>
  L:    linux-kselftest@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/shuah/linux-kselftest
  S:    Maintained
@@@ -7384,7 -7371,8 +7398,8 @@@ S:      Supporte
  F:    drivers/media/pci/netup_unidvb/*
  
  MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  P:    LinuxTV.org Project
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
@@@ -8035,6 -8023,7 +8050,7 @@@ Q:      http://patchwork.kernel.org/project/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
  S:    Maintained
+ F:    Documentation/devicetree/bindings/net/wireless/
  F:    drivers/net/wireless/
  
  NETXEN (1/10) GbE SUPPORT
@@@ -8432,10 -8421,9 +8448,9 @@@ F:     drivers/i2c/busses/i2c-ocores.
  OPEN FIRMWARE AND FLATTENED DEVICE TREE
  M:    Rob Herring <robh+dt@kernel.org>
  M:    Frank Rowand <frowand.list@gmail.com>
- M:    Grant Likely <grant.likely@linaro.org>
  L:    devicetree@vger.kernel.org
  W:    http://www.devicetree.org/
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
  S:    Maintained
  F:    drivers/of/
  F:    include/linux/of*.h
@@@ -8443,12 -8431,10 +8458,10 @@@ F:   scripts/dtc
  
  OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
  M:    Rob Herring <robh+dt@kernel.org>
- M:    Pawel Moll <pawel.moll@arm.com>
  M:    Mark Rutland <mark.rutland@arm.com>
- M:    Ian Campbell <ijc+devicetree@hellion.org.uk>
- M:    Kumar Gala <galak@codeaurora.org>
  L:    devicetree@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
+ Q:    http://patchwork.ozlabs.org/project/devicetree-bindings/list/
  S:    Maintained
  F:    Documentation/devicetree/
  F:    arch/*/boot/dts/
@@@ -9880,7 -9866,8 +9893,8 @@@ S:      Odd Fixe
  F:    drivers/media/i2c/saa6588*
  
  SAA7134 VIDEO4LINUX DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -10399,7 -10386,8 +10413,8 @@@ S:   Maintaine
  F:    drivers/media/radio/si4713/radio-usb-si4713.c
  
  SIANO DVB DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -11165,7 -11153,8 +11180,8 @@@ S:   Maintaine
  F:    drivers/media/i2c/tda9840*
  
  TEA5761 TUNER DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -11173,7 -11162,8 +11189,8 @@@ S:   Odd fixe
  F:    drivers/media/tuners/tea5761.*
  
  TEA5767 TUNER DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -11560,7 -11550,8 +11577,8 @@@ F:   include/linux/shmem_fs.
  F:    mm/shmem.c
  
  TM6000 VIDEO4LINUX DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
@@@ -11914,7 -11905,8 +11932,8 @@@ F:   drivers/usb/common/usb-otg-fsm.
  
  USB OVER IP DRIVER
  M:    Valentina Manea <valentina.manea.m@gmail.com>
- M:    Shuah Khan <shuah.kh@samsung.com>
+ M:    Shuah Khan <shuahkh@osg.samsung.com>
+ M:    Shuah Khan <shuah@kernel.org>
  L:    linux-usb@vger.kernel.org
  S:    Maintained
  F:    Documentation/usb/usbip_protocol.txt
@@@ -11985,6 -11977,7 +12004,7 @@@ L:   linux-usb@vger.kernel.or
  W:    http://www.linux-usb.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
  S:    Supported
+ F:    Documentation/devicetree/bindings/usb/
  F:    Documentation/usb/
  F:    drivers/usb/
  F:    include/linux/usb.h
@@@ -12158,6 -12151,7 +12178,7 @@@ VIRTIO CORE, NET AND BLOCK DRIVER
  M:    "Michael S. Tsirkin" <mst@redhat.com>
  L:    virtualization@lists.linux-foundation.org
  S:    Maintained
+ F:    Documentation/devicetree/bindings/virtio/
  F:    drivers/virtio/
  F:    tools/virtio/
  F:    drivers/net/virtio_net.c
@@@ -12546,7 -12540,8 +12567,8 @@@ S:   Maintaine
  F:    arch/x86/entry/vdso/
  
  XC2028/3028 TUNER DRIVER
- M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ M:    Mauro Carvalho Chehab <mchehab@s-opensource.com>
+ M:    Mauro Carvalho Chehab <mchehab@kernel.org>
  L:    linux-media@vger.kernel.org
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
diff --combined Makefile
+++ b/Makefile
@@@ -1,7 -1,7 +1,7 @@@
  VERSION = 4
  PATCHLEVEL = 7
  SUBLEVEL = 0
- EXTRAVERSION = -rc2
+ EXTRAVERSION = -rc5
  NAME = Psychotic Stoned Sheep
  
  # *DOCUMENTATION*
@@@ -1412,11 -1412,8 +1412,11 @@@ $(help-board-dirs): help-%
  
  # Documentation targets
  # ---------------------------------------------------------------------------
 -%docs: scripts_basic FORCE
 +DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs
 +PHONY += $(DOC_TARGETS)
 +$(DOC_TARGETS): scripts_basic FORCE
        $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype
 +      $(Q)$(MAKE) $(build)=Documentation -f $(srctree)/Documentation/Makefile.sphinx $@
        $(Q)$(MAKE) $(build)=Documentation/DocBook $@
  
  else # KBUILD_EXTMOD
@@@ -11,7 -11,6 +11,6 @@@
  
  / {
        compatible = "snps,nsimosci";
-       clock-frequency = <20000000>;   /* 20 MHZ */
        #address-cells = <1>;
        #size-cells = <1>;
        interrupt-parent = <&core_intc>;
@@@ -20,7 -19,7 +19,7 @@@
                /* this is for console on PGU */
                /* bootargs = "console=tty0 consoleblank=0"; */
                /* this is for console on serial */
 -              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
 +              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24";
        };
  
        aliases {
                        no-loopback-test = <1>;
                };
  
 -              pgu0: pgu@f9000000 {
 -                      compatible = "snps,arcpgufb";
 +              pguclk: pguclk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <25175000>;
 +              };
 +
 +              pgu@f9000000 {
 +                      compatible = "snps,arcpgu";
                        reg = <0xf9000000 0x400>;
 +                      clocks = <&pguclk>;
 +                      clock-names = "pxlclk";
                };
  
                ps2: ps2@f9001000 {
@@@ -11,7 -11,6 +11,6 @@@
  
  / {
        compatible = "snps,nsimosci_hs";
-       clock-frequency = <20000000>;   /* 20 MHZ */
        #address-cells = <1>;
        #size-cells = <1>;
        interrupt-parent = <&core_intc>;
@@@ -20,7 -19,7 +19,7 @@@
                /* this is for console on PGU */
                /* bootargs = "console=tty0 consoleblank=0"; */
                /* this is for console on serial */
 -              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
 +              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24";
        };
  
        aliases {
                        no-loopback-test = <1>;
                };
  
 -              pgu0: pgu@f9000000 {
 -                      compatible = "snps,arcpgufb";
 +              pguclk: pguclk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <25175000>;
 +              };
 +
 +              pgu@f9000000 {
 +                      compatible = "snps,arcpgu";
                        reg = <0xf9000000 0x400>;
 +                      clocks = <&pguclk>;
 +                      clock-names = "pxlclk";
                };
  
                ps2: ps2@f9001000 {
  
  / {
        compatible = "snps,nsimosci_hs";
-       clock-frequency = <5000000>;    /* 5 MHZ */
        #address-cells = <1>;
        #size-cells = <1>;
        interrupt-parent = <&core_intc>;
  
        chosen {
                /* this is for console on serial */
 -              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblan=0 debug";
 +              bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblan=0 debug video=640x480-24";
        };
  
        aliases {
                        no-loopback-test = <1>;
                };
  
 -              pgu0: pgu@f9000000 {
 -                      compatible = "snps,arcpgufb";
 +              pguclk: pguclk {
 +                      #clock-cells = <0>;
 +                      compatible = "fixed-clock";
 +                      clock-frequency = <25175000>;
 +              };
 +
 +              pgu@f9000000 {
 +                      compatible = "snps,arcpgu";
                        reg = <0xf9000000 0x400>;
 +                      clocks = <&pguclk>;
 +                      clock-names = "pxlclk";
                };
  
                ps2: ps2@f9001000 {
@@@ -1820,6 -1820,8 +1820,8 @@@ struct amdgpu_asic_funcs 
        /* MM block clocks */
        int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
        int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
+       /* query virtual capabilities */
+       u32 (*get_virtual_caps)(struct amdgpu_device *adev);
  };
  
  /*
@@@ -1914,8 -1916,12 +1916,12 @@@ void amdgpu_cgs_destroy_device(struct c
  
  
  /* GPU virtualization */
+ #define AMDGPU_VIRT_CAPS_SRIOV_EN       (1 << 0)
+ #define AMDGPU_VIRT_CAPS_IS_VF          (1 << 1)
  struct amdgpu_virtualization {
        bool supports_sr_iov;
+       bool is_virtual;
+       u32 caps;
  };
  
  /*
@@@ -2032,7 -2038,7 +2038,7 @@@ struct amdgpu_device 
        struct amdgpu_irq_src           hpd_irq;
  
        /* rings */
 -      unsigned                        fence_context;
 +      u64                             fence_context;
        unsigned                        num_rings;
        struct amdgpu_ring              *rings[AMDGPU_MAX_RINGS];
        bool                            ib_pool_ready;
@@@ -2204,6 -2210,7 +2210,7 @@@ amdgpu_get_sdma_instance(struct amdgpu_
  #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
  #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))
  #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
+ #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev)))
  #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
  #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
  #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
@@@ -115,6 -115,7 +115,7 @@@ int amdgpu_sa_bo_manager_start(struct a
                return r;
        }
        r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr);
+       memset(sa_manager->cpu_ptr, 0, sa_manager->size);
        amdgpu_bo_unreserve(sa_manager->bo);
        return r;
  }
@@@ -427,7 -428,7 +428,7 @@@ void amdgpu_sa_bo_dump_debug_info(struc
                           soffset, eoffset, eoffset - soffset);
  
                if (i->fence)
 -                      seq_printf(m, " protected by 0x%08x on context %d",
 +                      seq_printf(m, " protected by 0x%08x on context %llu",
                                   i->fence->seqno, i->fence->context);
  
                seq_printf(m, "\n");
@@@ -113,9 -113,21 +113,9 @@@ static int atmel_hlcdc_rgb_mode_valid(s
        return atmel_hlcdc_dc_mode_valid(rgb->dc, mode);
  }
  
 -
 -
 -static struct drm_encoder *
 -atmel_hlcdc_rgb_best_encoder(struct drm_connector *connector)
 -{
 -      struct atmel_hlcdc_rgb_output *rgb =
 -                      drm_connector_to_atmel_hlcdc_rgb_output(connector);
 -
 -      return &rgb->encoder;
 -}
 -
  static const struct drm_connector_helper_funcs atmel_hlcdc_panel_connector_helper_funcs = {
        .get_modes = atmel_hlcdc_panel_get_modes,
        .mode_valid = atmel_hlcdc_rgb_mode_valid,
 -      .best_encoder = atmel_hlcdc_rgb_best_encoder,
  };
  
  static enum drm_connector_status
@@@ -254,9 -266,10 +254,10 @@@ int atmel_hlcdc_create_outputs(struct d
                if (!ret)
                        ret = atmel_hlcdc_check_endpoint(dev, &ep);
  
-               of_node_put(ep_np);
-               if (ret)
+               if (ret) {
+                       of_node_put(ep_np);
                        return ret;
+               }
        }
  
        for_each_endpoint_of_node(dev->dev->of_node, ep_np) {
                if (!ret)
                        ret = atmel_hlcdc_attach_endpoint(dev, &ep);
  
-               of_node_put(ep_np);
-               if (ret)
+               if (ret) {
+                       of_node_put(ep_np);
                        return ret;
+               }
        }
  
        return 0;
  
  #include "drm_crtc_internal.h"
  
 +static void crtc_commit_free(struct kref *kref)
 +{
 +      struct drm_crtc_commit *commit =
 +              container_of(kref, struct drm_crtc_commit, ref);
 +
 +      kfree(commit);
 +}
 +
 +void drm_crtc_commit_put(struct drm_crtc_commit *commit)
 +{
 +      kref_put(&commit->ref, crtc_commit_free);
 +}
 +EXPORT_SYMBOL(drm_crtc_commit_put);
 +
  /**
   * drm_atomic_state_default_release -
   * release memory initialized by drm_atomic_state_init
  void drm_atomic_state_default_release(struct drm_atomic_state *state)
  {
        kfree(state->connectors);
 -      kfree(state->connector_states);
        kfree(state->crtcs);
 -      kfree(state->crtc_states);
        kfree(state->planes);
 -      kfree(state->plane_states);
  }
  EXPORT_SYMBOL(drm_atomic_state_default_release);
  
@@@ -83,10 -72,18 +83,10 @@@ drm_atomic_state_init(struct drm_devic
                               sizeof(*state->crtcs), GFP_KERNEL);
        if (!state->crtcs)
                goto fail;
 -      state->crtc_states = kcalloc(dev->mode_config.num_crtc,
 -                                   sizeof(*state->crtc_states), GFP_KERNEL);
 -      if (!state->crtc_states)
 -              goto fail;
        state->planes = kcalloc(dev->mode_config.num_total_plane,
                                sizeof(*state->planes), GFP_KERNEL);
        if (!state->planes)
                goto fail;
 -      state->plane_states = kcalloc(dev->mode_config.num_total_plane,
 -                                    sizeof(*state->plane_states), GFP_KERNEL);
 -      if (!state->plane_states)
 -              goto fail;
  
        state->dev = dev;
  
@@@ -142,48 -139,40 +142,48 @@@ void drm_atomic_state_default_clear(str
        DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
  
        for (i = 0; i < state->num_connector; i++) {
 -              struct drm_connector *connector = state->connectors[i];
 +              struct drm_connector *connector = state->connectors[i].ptr;
  
                if (!connector)
                        continue;
  
                connector->funcs->atomic_destroy_state(connector,
 -                                                     state->connector_states[i]);
 -              state->connectors[i] = NULL;
 -              state->connector_states[i] = NULL;
 +                                                     state->connectors[i].state);
 +              state->connectors[i].ptr = NULL;
 +              state->connectors[i].state = NULL;
                drm_connector_unreference(connector);
        }
  
        for (i = 0; i < config->num_crtc; i++) {
 -              struct drm_crtc *crtc = state->crtcs[i];
 +              struct drm_crtc *crtc = state->crtcs[i].ptr;
  
                if (!crtc)
                        continue;
  
                crtc->funcs->atomic_destroy_state(crtc,
 -                                                state->crtc_states[i]);
 -              state->crtcs[i] = NULL;
 -              state->crtc_states[i] = NULL;
 +                                                state->crtcs[i].state);
 +
 +              if (state->crtcs[i].commit) {
 +                      kfree(state->crtcs[i].commit->event);
 +                      state->crtcs[i].commit->event = NULL;
 +                      drm_crtc_commit_put(state->crtcs[i].commit);
 +              }
 +
 +              state->crtcs[i].commit = NULL;
 +              state->crtcs[i].ptr = NULL;
 +              state->crtcs[i].state = NULL;
        }
  
        for (i = 0; i < config->num_total_plane; i++) {
 -              struct drm_plane *plane = state->planes[i];
 +              struct drm_plane *plane = state->planes[i].ptr;
  
                if (!plane)
                        continue;
  
                plane->funcs->atomic_destroy_state(plane,
 -                                                 state->plane_states[i]);
 -              state->planes[i] = NULL;
 -              state->plane_states[i] = NULL;
 +                                                 state->planes[i].state);
 +              state->planes[i].ptr = NULL;
 +              state->planes[i].state = NULL;
        }
  }
  EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@@ -281,8 -270,8 +281,8 @@@ drm_atomic_get_crtc_state(struct drm_at
        if (!crtc_state)
                return ERR_PTR(-ENOMEM);
  
 -      state->crtc_states[index] = crtc_state;
 -      state->crtcs[index] = crtc;
 +      state->crtcs[index].state = crtc_state;
 +      state->crtcs[index].ptr = crtc;
        crtc_state->state = state;
  
        DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
@@@ -643,8 -632,8 +643,8 @@@ drm_atomic_get_plane_state(struct drm_a
        if (!plane_state)
                return ERR_PTR(-ENOMEM);
  
 -      state->plane_states[index] = plane_state;
 -      state->planes[index] = plane;
 +      state->planes[index].state = plane_state;
 +      state->planes[index].ptr = plane;
        plane_state->state = state;
  
        DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
@@@ -908,7 -897,8 +908,7 @@@ drm_atomic_get_connector_state(struct d
        index = drm_connector_index(connector);
  
        if (index >= state->num_connector) {
 -              struct drm_connector **c;
 -              struct drm_connector_state **cs;
 +              struct __drm_connnectors_state *c;
                int alloc = max(index + 1, config->num_connector);
  
                c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
                memset(&state->connectors[state->num_connector], 0,
                       sizeof(*state->connectors) * (alloc - state->num_connector));
  
 -              cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
 -              if (!cs)
 -                      return ERR_PTR(-ENOMEM);
 -
 -              state->connector_states = cs;
 -              memset(&state->connector_states[state->num_connector], 0,
 -                     sizeof(*state->connector_states) * (alloc - state->num_connector));
                state->num_connector = alloc;
        }
  
 -      if (state->connector_states[index])
 -              return state->connector_states[index];
 +      if (state->connectors[index].state)
 +              return state->connectors[index].state;
  
        connector_state = connector->funcs->atomic_duplicate_state(connector);
        if (!connector_state)
                return ERR_PTR(-ENOMEM);
  
        drm_connector_reference(connector);
 -      state->connector_states[index] = connector_state;
 -      state->connectors[index] = connector;
 +      state->connectors[index].state = connector_state;
 +      state->connectors[index].ptr = connector;
        connector_state->state = state;
  
        DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
@@@ -1299,14 -1296,39 +1299,39 @@@ EXPORT_SYMBOL(drm_atomic_add_affected_p
   */
  void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
  {
+       struct drm_device *dev = state->dev;
+       unsigned crtc_mask = 0;
+       struct drm_crtc *crtc;
        int ret;
+       bool global = false;
+       drm_for_each_crtc(crtc, dev) {
+               if (crtc->acquire_ctx != state->acquire_ctx)
+                       continue;
+               crtc_mask |= drm_crtc_mask(crtc);
+               crtc->acquire_ctx = NULL;
+       }
+       if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
+               global = true;
+               dev->mode_config.acquire_ctx = NULL;
+       }
  
  retry:
        drm_modeset_backoff(state->acquire_ctx);
  
-       ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
+       ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
        if (ret)
                goto retry;
+       drm_for_each_crtc(crtc, dev)
+               if (drm_crtc_mask(crtc) & crtc_mask)
+                       crtc->acquire_ctx = state->acquire_ctx;
+       if (global)
+               dev->mode_config.acquire_ctx = state->acquire_ctx;
  }
  EXPORT_SYMBOL(drm_atomic_legacy_backoff);
  
@@@ -1435,8 -1457,7 +1460,8 @@@ EXPORT_SYMBOL(drm_atomic_nonblocking_co
   */
  
  static struct drm_pending_vblank_event *create_vblank_event(
 -              struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
 +              struct drm_device *dev, struct drm_file *file_priv,
 +              struct fence *fence, uint64_t user_data)
  {
        struct drm_pending_vblank_event *e = NULL;
        int ret;
        e->event.base.length = sizeof(e->event);
        e->event.user_data = user_data;
  
 -      ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
 -      if (ret) {
 -              kfree(e);
 -              return NULL;
 +      if (file_priv) {
 +              ret = drm_event_reserve_init(dev, file_priv, &e->base,
 +                                           &e->event.base);
 +              if (ret) {
 +                      kfree(e);
 +                      return NULL;
 +              }
        }
  
 +      e->base.fence = fence;
 +
        return e;
  }
  
@@@ -1699,8 -1715,7 +1724,8 @@@ retry
                for_each_crtc_in_state(state, crtc, crtc_state, i) {
                        struct drm_pending_vblank_event *e;
  
 -                      e = create_vblank_event(dev, file_priv, arg->user_data);
 +                      e = create_vblank_event(dev, file_priv, NULL,
 +                                              arg->user_data);
                        if (!e) {
                                ret = -ENOMEM;
                                goto out;
@@@ -232,9 -232,6 +232,9 @@@ static void __drm_helper_disable_unused
   */
  void drm_helper_disable_unused_functions(struct drm_device *dev)
  {
 +      if (drm_core_check_feature(dev, DRIVER_ATOMIC))
 +              DRM_ERROR("Called for atomic driver, this is not what you want.\n");
 +
        drm_modeset_lock_all(dev);
        __drm_helper_disable_unused_functions(dev);
        drm_modeset_unlock_all(dev);
@@@ -531,11 -528,11 +531,11 @@@ drm_crtc_helper_disable(struct drm_crt
  int drm_crtc_helper_set_config(struct drm_mode_set *set)
  {
        struct drm_device *dev;
-       struct drm_crtc *new_crtc;
-       struct drm_encoder *save_encoders, *new_encoder, *encoder;
+       struct drm_crtc **save_encoder_crtcs, *new_crtc;
+       struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
        bool mode_changed = false; /* if true do a full mode set */
        bool fb_changed = false; /* if true and !mode_changed just do a flip */
-       struct drm_connector *save_connectors, *connector;
+       struct drm_connector *connector;
        int count = 0, ro, fail = 0;
        const struct drm_crtc_helper_funcs *crtc_funcs;
        struct drm_mode_set save_set;
         * Allocate space for the backup of all (non-pointer) encoder and
         * connector data.
         */
-       save_encoders = kzalloc(dev->mode_config.num_encoder *
-                               sizeof(struct drm_encoder), GFP_KERNEL);
-       if (!save_encoders)
+       save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder *
+                               sizeof(struct drm_crtc *), GFP_KERNEL);
+       if (!save_encoder_crtcs)
                return -ENOMEM;
  
-       save_connectors = kzalloc(dev->mode_config.num_connector *
-                               sizeof(struct drm_connector), GFP_KERNEL);
-       if (!save_connectors) {
-               kfree(save_encoders);
+       save_connector_encoders = kzalloc(dev->mode_config.num_connector *
+                               sizeof(struct drm_encoder *), GFP_KERNEL);
+       if (!save_connector_encoders) {
+               kfree(save_encoder_crtcs);
                return -ENOMEM;
        }
  
         */
        count = 0;
        drm_for_each_encoder(encoder, dev) {
-               save_encoders[count++] = *encoder;
+               save_encoder_crtcs[count++] = encoder->crtc;
        }
  
        count = 0;
        drm_for_each_connector(connector, dev) {
-               save_connectors[count++] = *connector;
+               save_connector_encoders[count++] = connector->encoder;
        }
  
        save_set.crtc = set->crtc;
                mode_changed = true;
        }
  
-       /* take a reference on all connectors in set */
+       /* take a reference on all unbound connectors in set, reuse the
+        * already taken reference for bound connectors
+        */
        for (ro = 0; ro < set->num_connectors; ro++) {
+               if (set->connectors[ro]->encoder)
+                       continue;
                drm_connector_reference(set->connectors[ro]);
        }
  
                }
        }
  
-       /* after fail drop reference on all connectors in save set */
-       count = 0;
-       drm_for_each_connector(connector, dev) {
-               drm_connector_unreference(&save_connectors[count++]);
-       }
-       kfree(save_connectors);
-       kfree(save_encoders);
+       kfree(save_connector_encoders);
+       kfree(save_encoder_crtcs);
        return 0;
  
  fail:
        /* Restore all previous data. */
        count = 0;
        drm_for_each_encoder(encoder, dev) {
-               *encoder = save_encoders[count++];
+               encoder->crtc = save_encoder_crtcs[count++];
        }
  
        count = 0;
        drm_for_each_connector(connector, dev) {
-               *connector = save_connectors[count++];
+               connector->encoder = save_connector_encoders[count++];
        }
  
-       /* after fail drop reference on all connectors in set */
+       /* after fail drop reference on all unbound connectors in set, let
+        * bound connectors keep their reference
+        */
        for (ro = 0; ro < set->num_connectors; ro++) {
+               if (set->connectors[ro]->encoder)
+                       continue;
                drm_connector_unreference(set->connectors[ro]);
        }
  
                                      save_set.y, save_set.fb))
                DRM_ERROR("failed to restore config after modeset failure\n");
  
-       kfree(save_connectors);
-       kfree(save_encoders);
+       kfree(save_connector_encoders);
+       kfree(save_encoder_crtcs);
        return ret;
  }
  EXPORT_SYMBOL(drm_crtc_helper_set_config);
@@@ -1124,3 -1123,36 +1126,3 @@@ int drm_helper_crtc_mode_set_base(struc
        return drm_plane_helper_commit(plane, plane_state, old_fb);
  }
  EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
 -
 -/**
 - * drm_helper_crtc_enable_color_mgmt - enable color management properties
 - * @crtc: DRM CRTC
 - * @degamma_lut_size: the size of the degamma lut (before CSC)
 - * @gamma_lut_size: the size of the gamma lut (after CSC)
 - *
 - * This function lets the driver enable the color correction properties on a
 - * CRTC. This includes 3 degamma, csc and gamma properties that userspace can
 - * set and 2 size properties to inform the userspace of the lut sizes.
 - */
 -void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc,
 -                                     int degamma_lut_size,
 -                                     int gamma_lut_size)
 -{
 -      struct drm_device *dev = crtc->dev;
 -      struct drm_mode_config *config = &dev->mode_config;
 -
 -      drm_object_attach_property(&crtc->base,
 -                                 config->degamma_lut_property, 0);
 -      drm_object_attach_property(&crtc->base,
 -                                 config->ctm_property, 0);
 -      drm_object_attach_property(&crtc->base,
 -                                 config->gamma_lut_property, 0);
 -
 -      drm_object_attach_property(&crtc->base,
 -                                 config->degamma_lut_size_property,
 -                                 degamma_lut_size);
 -      drm_object_attach_property(&crtc->base,
 -                                 config->gamma_lut_size_property,
 -                                 gamma_lut_size);
 -}
 -EXPORT_SYMBOL(drm_helper_crtc_enable_color_mgmt);
@@@ -42,9 -42,10 +42,10 @@@ static const struct regmap_config fsl_d
        .reg_bits = 32,
        .reg_stride = 4,
        .val_bits = 32,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
  
        .volatile_reg = fsl_dcu_drm_is_volatile_reg,
+       .max_register = 0x11fc,
  };
  
  static int fsl_dcu_drm_irq_init(struct drm_device *dev)
@@@ -198,7 -199,7 +199,7 @@@ static struct drm_driver fsl_dcu_drm_dr
        .get_vblank_counter     = drm_vblank_no_hw_counter,
        .enable_vblank          = fsl_dcu_drm_enable_vblank,
        .disable_vblank         = fsl_dcu_drm_disable_vblank,
 -      .gem_free_object        = drm_gem_cma_free_object,
 +      .gem_free_object_unlocked = drm_gem_cma_free_object,
        .gem_vm_ops             = &drm_gem_cma_vm_ops,
        .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
@@@ -131,6 -131,11 +131,6 @@@ static void vlv_steal_power_sequencer(s
                                      enum pipe pipe);
  static void intel_dp_unset_edid(struct intel_dp *intel_dp);
  
 -static unsigned int intel_dp_unused_lane_mask(int lane_count)
 -{
 -      return ~((1 << lane_count) - 1) & 0xf;
 -}
 -
  static int
  intel_dp_max_link_bw(struct intel_dp  *intel_dp)
  {
@@@ -770,7 -775,6 +770,7 @@@ static uint32_t skl_get_aux_send_ctl(st
               DP_AUX_CH_CTL_TIME_OUT_1600us |
               DP_AUX_CH_CTL_RECEIVE_ERROR |
               (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
 +             DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
               DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
  }
  
@@@ -1177,6 -1181,7 +1177,6 @@@ static void intel_aux_reg_init(struct i
  static void
  intel_dp_aux_fini(struct intel_dp *intel_dp)
  {
 -      drm_dp_aux_unregister(&intel_dp->aux);
        kfree(intel_dp->aux.name);
  }
  
@@@ -1211,6 -1216,15 +1211,6 @@@ intel_dp_aux_init(struct intel_dp *inte
        return 0;
  }
  
 -static void
 -intel_dp_connector_unregister(struct intel_connector *intel_connector)
 -{
 -      struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
 -
 -      intel_dp_aux_fini(intel_dp);
 -      intel_connector_unregister(intel_connector);
 -}
 -
  static int
  intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
  {
@@@ -1568,27 -1582,6 +1568,27 @@@ found
                                &pipe_config->dp_m2_n2);
        }
  
 +      /*
 +       * DPLL0 VCO may need to be adjusted to get the correct
 +       * clock for eDP. This will affect cdclk as well.
 +       */
 +      if (is_edp(intel_dp) &&
 +          (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))) {
 +              int vco;
 +
 +              switch (pipe_config->port_clock / 2) {
 +              case 108000:
 +              case 216000:
 +                      vco = 8640000;
 +                      break;
 +              default:
 +                      vco = 8100000;
 +                      break;
 +              }
 +
 +              to_intel_atomic_state(pipe_config->base.state)->cdclk_pll_vco = vco;
 +      }
 +
        if (!HAS_DDI(dev))
                intel_dp_set_clock(encoder, pipe_config);
  
@@@ -2467,6 -2460,50 +2467,6 @@@ static void vlv_post_disable_dp(struct 
        intel_dp_link_down(intel_dp);
  }
  
 -static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
 -                                   bool reset)
 -{
 -      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 -      enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
 -      struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 -      enum pipe pipe = crtc->pipe;
 -      uint32_t val;
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
 -      if (reset)
 -              val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -      else
 -              val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
 -
 -      if (crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
 -              if (reset)
 -                      val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
 -              else
 -                      val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
 -      }
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
 -      val |= CHV_PCS_REQ_SOFTRESET_EN;
 -      if (reset)
 -              val &= ~DPIO_PCS_CLK_SOFT_RESET;
 -      else
 -              val |= DPIO_PCS_CLK_SOFT_RESET;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
 -
 -      if (crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
 -              val |= CHV_PCS_REQ_SOFTRESET_EN;
 -              if (reset)
 -                      val &= ~DPIO_PCS_CLK_SOFT_RESET;
 -              else
 -                      val |= DPIO_PCS_CLK_SOFT_RESET;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
 -      }
 -}
 -
  static void chv_post_disable_dp(struct intel_encoder *encoder)
  {
        struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@@ -2774,38 -2811,266 +2774,38 @@@ static void vlv_init_panel_power_sequen
  
  static void vlv_pre_enable_dp(struct intel_encoder *encoder)
  {
 -      struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 -      struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
 -      enum dpio_channel port = vlv_dport_to_channel(dport);
 -      int pipe = intel_crtc->pipe;
 -      u32 val;
 -
 -      mutex_lock(&dev_priv->sb_lock);
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
 -      val = 0;
 -      if (pipe)
 -              val |= (1<<21);
 -      else
 -              val &= ~(1<<21);
 -      val |= 0x001000c4;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
 -
 -      mutex_unlock(&dev_priv->sb_lock);
 +      vlv_phy_pre_encoder_enable(encoder);
  
        intel_enable_dp(encoder);
  }
  
  static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
  {
 -      struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc =
 -              to_intel_crtc(encoder->base.crtc);
 -      enum dpio_channel port = vlv_dport_to_channel(dport);
 -      int pipe = intel_crtc->pipe;
 -
        intel_dp_prepare(encoder);
  
 -      /* Program Tx lane resets to default */
 -      mutex_lock(&dev_priv->sb_lock);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
 -                       DPIO_PCS_TX_LANE2_RESET |
 -                       DPIO_PCS_TX_LANE1_RESET);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
 -                       DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
 -                       DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
 -                       (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
 -                               DPIO_PCS_CLK_SOFT_RESET);
 -
 -      /* Fix up inter-pair skew failure */
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
 -      mutex_unlock(&dev_priv->sb_lock);
 +      vlv_phy_pre_pll_enable(encoder);
  }
  
  static void chv_pre_enable_dp(struct intel_encoder *encoder)
  {
 -      struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 -      struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc =
 -              to_intel_crtc(encoder->base.crtc);
 -      enum dpio_channel ch = vlv_dport_to_channel(dport);
 -      int pipe = intel_crtc->pipe;
 -      int data, i, stagger;
 -      u32 val;
 -
 -      mutex_lock(&dev_priv->sb_lock);
 -
 -      /* allow hardware to manage TX FIFO reset source */
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
 -      val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 -              val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 -      }
 -
 -      /* Program Tx lane latency optimal setting*/
 -      for (i = 0; i < intel_crtc->config->lane_count; i++) {
 -              /* Set the upar bit */
 -              if (intel_crtc->config->lane_count == 1)
 -                      data = 0x0;
 -              else
 -                      data = (i == 1) ? 0x0 : 0x1;
 -              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
 -                              data << DPIO_UPAR_SHIFT);
 -      }
 -
 -      /* Data lane stagger programming */
 -      if (intel_crtc->config->port_clock > 270000)
 -              stagger = 0x18;
 -      else if (intel_crtc->config->port_clock > 135000)
 -              stagger = 0xd;
 -      else if (intel_crtc->config->port_clock > 67500)
 -              stagger = 0x7;
 -      else if (intel_crtc->config->port_clock > 33750)
 -              stagger = 0x4;
 -      else
 -              stagger = 0x2;
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
 -      val |= DPIO_TX2_STAGGER_MASK(0x1f);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
 -              val |= DPIO_TX2_STAGGER_MASK(0x1f);
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 -      }
 -
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch),
 -                     DPIO_LANESTAGGER_STRAP(stagger) |
 -                     DPIO_LANESTAGGER_STRAP_OVRD |
 -                     DPIO_TX1_STAGGER_MASK(0x1f) |
 -                     DPIO_TX1_STAGGER_MULT(6) |
 -                     DPIO_TX2_STAGGER_MULT(0));
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
 -                             DPIO_LANESTAGGER_STRAP(stagger) |
 -                             DPIO_LANESTAGGER_STRAP_OVRD |
 -                             DPIO_TX1_STAGGER_MASK(0x1f) |
 -                             DPIO_TX1_STAGGER_MULT(7) |
 -                             DPIO_TX2_STAGGER_MULT(5));
 -      }
 -
 -      /* Deassert data lane reset */
 -      chv_data_lane_soft_reset(encoder, false);
 -
 -      mutex_unlock(&dev_priv->sb_lock);
 +      chv_phy_pre_encoder_enable(encoder);
  
        intel_enable_dp(encoder);
  
        /* Second common lane will stay alive on its own now */
 -      if (dport->release_cl2_override) {
 -              chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
 -              dport->release_cl2_override = false;
 -      }
 +      chv_phy_release_cl2_override(encoder);
  }
  
  static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
  {
 -      struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 -      struct drm_device *dev = encoder->base.dev;
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_crtc *intel_crtc =
 -              to_intel_crtc(encoder->base.crtc);
 -      enum dpio_channel ch = vlv_dport_to_channel(dport);
 -      enum pipe pipe = intel_crtc->pipe;
 -      unsigned int lane_mask =
 -              intel_dp_unused_lane_mask(intel_crtc->config->lane_count);
 -      u32 val;
 -
        intel_dp_prepare(encoder);
  
 -      /*
 -       * Must trick the second common lane into life.
 -       * Otherwise we can't even access the PLL.
 -       */
 -      if (ch == DPIO_CH0 && pipe == PIPE_B)
 -              dport->release_cl2_override =
 -                      !chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
 -
 -      chv_phy_powergate_lanes(encoder, true, lane_mask);
 -
 -      mutex_lock(&dev_priv->sb_lock);
 -
 -      /* Assert data lane reset */
 -      chv_data_lane_soft_reset(encoder, true);
 -
 -      /* program left/right clock distribution */
 -      if (pipe != PIPE_B) {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
 -              val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
 -              if (ch == DPIO_CH0)
 -                      val |= CHV_BUFLEFTENA1_FORCE;
 -              if (ch == DPIO_CH1)
 -                      val |= CHV_BUFRIGHTENA1_FORCE;
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
 -      } else {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
 -              val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
 -              if (ch == DPIO_CH0)
 -                      val |= CHV_BUFLEFTENA2_FORCE;
 -              if (ch == DPIO_CH1)
 -                      val |= CHV_BUFRIGHTENA2_FORCE;
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
 -      }
 -
 -      /* program clock channel usage */
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
 -      val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
 -      if (pipe != PIPE_B)
 -              val &= ~CHV_PCS_USEDCLKCHANNEL;
 -      else
 -              val |= CHV_PCS_USEDCLKCHANNEL;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
 -              val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
 -              if (pipe != PIPE_B)
 -                      val &= ~CHV_PCS_USEDCLKCHANNEL;
 -              else
 -                      val |= CHV_PCS_USEDCLKCHANNEL;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
 -      }
 -
 -      /*
 -       * This a a bit weird since generally CL
 -       * matches the pipe, but here we need to
 -       * pick the CL based on the port.
 -       */
 -      val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
 -      if (pipe != PIPE_B)
 -              val &= ~CHV_CMN_USEDCLKCHANNEL;
 -      else
 -              val |= CHV_CMN_USEDCLKCHANNEL;
 -      vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
 -
 -      mutex_unlock(&dev_priv->sb_lock);
 +      chv_phy_pre_pll_enable(encoder);
  }
  
  static void chv_dp_post_pll_disable(struct intel_encoder *encoder)
  {
 -      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 -      enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe;
 -      u32 val;
 -
 -      mutex_lock(&dev_priv->sb_lock);
 -
 -      /* disable left/right clock distribution */
 -      if (pipe != PIPE_B) {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
 -              val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
 -      } else {
 -              val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
 -              val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
 -              vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
 -      }
 -
 -      mutex_unlock(&dev_priv->sb_lock);
 -
 -      /*
 -       * Leave the power down bit cleared for at least one
 -       * lane so that chv_powergate_phy_ch() will power
 -       * on something when the channel is otherwise unused.
 -       * When the port is off and the override is removed
 -       * the lanes power down anyway, so otherwise it doesn't
 -       * really matter what the state of power down bits is
 -       * after this.
 -       */
 -      chv_phy_powergate_lanes(encoder, false, 0x0);
 +      chv_phy_post_pll_disable(encoder);
  }
  
  /*
@@@ -2913,10 -3178,16 +2913,10 @@@ intel_dp_pre_emphasis_max(struct intel_
  
  static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
  {
 -      struct drm_device *dev = intel_dp_to_dev(intel_dp);
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 -      struct intel_crtc *intel_crtc =
 -              to_intel_crtc(dport->base.base.crtc);
 +      struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        unsigned long demph_reg_value, preemph_reg_value,
                uniqtranscale_reg_value;
        uint8_t train_set = intel_dp->train_set[0];
 -      enum dpio_channel port = vlv_dport_to_channel(dport);
 -      int pipe = intel_crtc->pipe;
  
        switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
        case DP_TRAIN_PRE_EMPH_LEVEL_0:
                return 0;
        }
  
 -      mutex_lock(&dev_priv->sb_lock);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
 -                       uniqtranscale_reg_value);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
 -      vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
 -      mutex_unlock(&dev_priv->sb_lock);
 +      vlv_set_phy_signal_level(encoder, demph_reg_value, preemph_reg_value,
 +                               uniqtranscale_reg_value, 0);
  
        return 0;
  }
  
 -static bool chv_need_uniq_trans_scale(uint8_t train_set)
 -{
 -      return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
 -              (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 -}
 -
  static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
  {
 -      struct drm_device *dev = intel_dp_to_dev(intel_dp);
 -      struct drm_i915_private *dev_priv = dev->dev_private;
 -      struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 -      struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
 -      u32 deemph_reg_value, margin_reg_value, val;
 +      struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 +      u32 deemph_reg_value, margin_reg_value;
 +      bool uniq_trans_scale = false;
        uint8_t train_set = intel_dp->train_set[0];
 -      enum dpio_channel ch = vlv_dport_to_channel(dport);
 -      enum pipe pipe = intel_crtc->pipe;
 -      int i;
  
        switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
        case DP_TRAIN_PRE_EMPH_LEVEL_0:
                case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
                        deemph_reg_value = 128;
                        margin_reg_value = 154;
 -                      /* FIXME extra to set for 1200 */
 +                      uniq_trans_scale = true;
                        break;
                default:
                        return 0;
                return 0;
        }
  
 -      mutex_lock(&dev_priv->sb_lock);
 -
 -      /* Clear calc init */
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
 -      val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 -      val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
 -      val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 -              val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 -              val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
 -              val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 -      }
 -
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
 -      val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 -      val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
 -              val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 -              val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
 -      }
 -
 -      /* Program swing deemph */
 -      for (i = 0; i < intel_crtc->config->lane_count; i++) {
 -              val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
 -              val &= ~DPIO_SWING_DEEMPH9P5_MASK;
 -              val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
 -              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
 -      }
 -
 -      /* Program swing margin */
 -      for (i = 0; i < intel_crtc->config->lane_count; i++) {
 -              val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
 -
 -              val &= ~DPIO_SWING_MARGIN000_MASK;
 -              val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
 -
 -              /*
 -               * Supposedly this value shouldn't matter when unique transition
 -               * scale is disabled, but in fact it does matter. Let's just
 -               * always program the same value and hope it's OK.
 -               */
 -              val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
 -              val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
 -
 -              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
 -      }
 -
 -      /*
 -       * The document said it needs to set bit 27 for ch0 and bit 26
 -       * for ch1. Might be a typo in the doc.
 -       * For now, for this unique transition scale selection, set bit
 -       * 27 for ch0 and ch1.
 -       */
 -      for (i = 0; i < intel_crtc->config->lane_count; i++) {
 -              val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
 -              if (chv_need_uniq_trans_scale(train_set))
 -                      val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
 -              else
 -                      val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
 -              vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
 -      }
 -
 -      /* Start swing calculation */
 -      val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
 -      val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 -      vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 -
 -      if (intel_crtc->config->lane_count > 2) {
 -              val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 -              val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 -              vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 -      }
 -
 -      mutex_unlock(&dev_priv->sb_lock);
 +      chv_set_phy_signal_level(encoder, deemph_reg_value,
 +                               margin_reg_value, uniq_trans_scale);
  
        return 0;
  }
@@@ -3344,6 -3714,7 +3344,6 @@@ intel_dp_get_dpcd(struct intel_dp *inte
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      uint8_t rev;
  
        if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
                             sizeof(intel_dp->dpcd)) < 0)
                        DRM_DEBUG_KMS("PSR2 %s on sink",
                                dev_priv->psr.psr2_support ? "supported" : "not supported");
                }
 +
 +              /* Read the eDP Display control capabilities registers */
 +              memset(intel_dp->edp_dpcd, 0, sizeof(intel_dp->edp_dpcd));
 +              if ((intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
 +                              (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV,
 +                                              intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) ==
 +                                                              sizeof(intel_dp->edp_dpcd)))
 +                      DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd),
 +                                      intel_dp->edp_dpcd);
        }
  
        DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
                      yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
  
        /* Intermediate frequency support */
 -      if (is_edp(intel_dp) &&
 -          (intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
 -          (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) == 1) &&
 -          (rev >= 0x03)) { /* eDp v1.4 or higher */
 +      if (is_edp(intel_dp) && (intel_dp->edp_dpcd[0] >= 0x03)) { /* eDp v1.4 or higher */
                __le16 sink_rates[DP_MAX_SUPPORTED_RATES];
                int i;
  
@@@ -4446,13 -4811,6 +4446,13 @@@ done
        return 0;
  }
  
 +static void
 +intel_dp_connector_unregister(struct drm_connector *connector)
 +{
 +      drm_dp_aux_unregister(&intel_attached_dp(connector)->aux);
 +      intel_connector_unregister(connector);
 +}
 +
  static void
  intel_dp_connector_destroy(struct drm_connector *connector)
  {
@@@ -4493,9 -4851,6 +4493,9 @@@ void intel_dp_encoder_destroy(struct dr
                        intel_dp->edp_notifier.notifier_call = NULL;
                }
        }
 +
 +      intel_dp_aux_fini(intel_dp);
 +
        drm_encoder_cleanup(encoder);
        kfree(intel_dig_port);
  }
@@@ -4572,7 -4927,6 +4572,7 @@@ static const struct drm_connector_func
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_dp_set_property,
        .atomic_get_property = intel_connector_atomic_get_property,
 +      .early_unregister = intel_dp_connector_unregister,
        .destroy = intel_dp_connector_destroy,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
        .get_modes = intel_dp_get_modes,
        .mode_valid = intel_dp_mode_valid,
 -      .best_encoder = intel_best_encoder,
  };
  
  static const struct drm_encoder_funcs intel_dp_enc_funcs = {
@@@ -4622,9 -4977,6 +4622,6 @@@ intel_dp_hpd_pulse(struct intel_digital
        intel_display_power_get(dev_priv, power_domain);
  
        if (long_hpd) {
-               /* indicate that we need to restart link training */
-               intel_dp->train_set_valid = false;
                intel_dp_long_pulse(intel_dp->attached_connector);
                if (intel_dp->is_mst)
                        ret = IRQ_HANDLED;
@@@ -5235,14 -5587,14 +5232,14 @@@ void intel_edp_drrs_flush(struct drm_de
   *
   * DRRS saves power by switching to low RR based on usage scenarios.
   *
 - * eDP DRRS:-
 - *        The implementation is based on frontbuffer tracking implementation.
 - * When there is a disturbance on the screen triggered by user activity or a
 - * periodic system activity, DRRS is disabled (RR is changed to high RR).
 - * When there is no movement on screen, after a timeout of 1 second, a switch
 - * to low RR is made.
 - *        For integration with frontbuffer tracking code,
 - * intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called.
 + * The implementation is based on frontbuffer tracking implementation.  When
 + * there is a disturbance on the screen triggered by user activity or a periodic
 + * system activity, DRRS is disabled (RR is changed to high RR).  When there is
 + * no movement on screen, after a timeout of 1 second, a switch to low RR is
 + * made.
 + *
 + * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
 + * and intel_edp_drrs_flush() are called.
   *
   * DRRS can be further extended to support other internal panels and also
   * the scenario of video playback wherein RR is set based on the rate
@@@ -5488,6 -5840,7 +5485,6 @@@ intel_dp_init_connector(struct intel_di
                intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
        else
                intel_connector->get_hw_state = intel_connector_get_hw_state;
 -      intel_connector->unregister = intel_dp_connector_unregister;
  
        /* Set up the hotplug pin. */
        switch (port) {
@@@ -5592,7 -5945,7 +5589,7 @@@ bool intel_dp_init(struct drm_device *d
        encoder = &intel_encoder->base;
  
        if (drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
 -                           DRM_MODE_ENCODER_TMDS, NULL))
 +                           DRM_MODE_ENCODER_TMDS, "DP %c", port_name(port)))
                goto err_encoder_init;
  
        intel_encoder->compute_config = intel_dp_compute_config;
@@@ -242,6 -242,14 +242,6 @@@ struct intel_connector 
         * and active (i.e. dpms ON state). */
        bool (*get_hw_state)(struct intel_connector *);
  
 -      /*
 -       * Removes all interfaces through which the connector is accessible
 -       * - like sysfs, debugfs entries -, so that no new operations can be
 -       * started on the connector. Also makes sure all currently pending
 -       * operations finish before returing.
 -       */
 -      void (*unregister)(struct intel_connector *);
 -
        /* Panel info for eDP and LVDS */
        struct intel_panel panel;
  
        struct intel_dp *mst_port;
  };
  
 -typedef struct dpll {
 +struct dpll {
        /* given values */
        int n;
        int m1, m2;
        int     vco;
        int     m;
        int     p;
 -} intel_clock_t;
 +};
  
  struct intel_atomic_state {
        struct drm_atomic_state base;
  
        bool dpll_set, modeset;
  
 +      /*
 +       * Does this transaction change the pipes that are active?  This mask
 +       * tracks which CRTC's have changed their active state at the end of
 +       * the transaction (not counting the temporary disable during modesets).
 +       * This mask should only be non-zero when intel_state->modeset is true,
 +       * but the converse is not necessarily true; simply changing a mode may
 +       * not flip the final active status of any CRTC's
 +       */
 +      unsigned int active_pipe_changes;
 +
        unsigned int active_crtcs;
        unsigned int min_pixclk[I915_MAX_PIPES];
  
 +      /* SKL/KBL Only */
 +      unsigned int cdclk_pll_vco;
 +
        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;
 +
 +      /* Gen9+ only */
 +      struct skl_wm_values wm_results;
  };
  
  struct intel_plane_state {
@@@ -412,48 -405,6 +412,48 @@@ struct skl_pipe_wm 
        uint32_t linetime;
  };
  
 +struct intel_crtc_wm_state {
 +      union {
 +              struct {
 +                      /*
 +                       * 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;
 +
 +                      /*
 +                       * Optimal watermarks, programmed post-vblank
 +                       * when this state is committed.
 +                       */
 +                      struct intel_pipe_wm optimal;
 +              } ilk;
 +
 +              struct {
 +                      /* gen9+ only needs 1-step wm programming */
 +                      struct skl_pipe_wm optimal;
 +
 +                      /* cached plane data rate */
 +                      unsigned plane_data_rate[I915_MAX_PLANES];
 +                      unsigned plane_y_data_rate[I915_MAX_PLANES];
 +
 +                      /* minimum block allocation */
 +                      uint16_t minimum_blocks[I915_MAX_PLANES];
 +                      uint16_t minimum_y_blocks[I915_MAX_PLANES];
 +              } skl;
 +      };
 +
 +      /*
 +       * 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;
 +};
 +
  struct intel_crtc_state {
        struct drm_crtc_state base;
  
  
        uint8_t lane_count;
  
 +      /*
 +       * Used by platforms having DP/HDMI PHY with programmable lane
 +       * latency optimization.
 +       */
 +      uint8_t lane_lat_optim_mask;
 +
        /* Panel fitter controls for gen2-gen4 + VLV */
        struct {
                u32 control;
        /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
        bool disable_lp_wm;
  
 -      struct {
 -              /*
 -               * 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;
 +      struct intel_crtc_wm_state wm;
  
        /* Gamma mode programmed on the pipe */
        uint32_t gamma_mode;
@@@ -628,6 -598,14 +628,6 @@@ struct vlv_wm_state 
        bool cxsr;
  };
  
 -struct intel_mmio_flip {
 -      struct work_struct work;
 -      struct drm_i915_private *i915;
 -      struct drm_i915_gem_request *req;
 -      struct intel_crtc *crtc;
 -      unsigned int rotation;
 -};
 -
  struct intel_crtc {
        struct drm_crtc base;
        enum pipe pipe;
        unsigned long enabled_power_domains;
        bool lowfreq_avail;
        struct intel_overlay *overlay;
 -      struct intel_unpin_work *unpin_work;
 +      struct intel_flip_work *flip_work;
  
        atomic_t unpin_work_count;
  
@@@ -837,7 -815,6 +837,7 @@@ struct intel_dp 
        uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
        uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
        uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
 +      uint8_t edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
        /* sink rates as reported by DP_SUPPORTED_LINK_RATES */
        uint8_t num_sink_rates;
        int sink_rates[DP_MAX_SUPPORTED_RATES];
        /* This is called before a link training is starterd */
        void (*prepare_link_retrain)(struct intel_dp *intel_dp);
  
-       bool train_set_valid;
        /* Displayport compliance testing */
        unsigned long compliance_test_type;
        unsigned long compliance_test_data;
@@@ -970,21 -945,22 +968,21 @@@ intel_get_crtc_for_plane(struct drm_dev
        return dev_priv->plane_to_crtc_mapping[plane];
  }
  
 -struct intel_unpin_work {
 -      struct work_struct work;
 +struct intel_flip_work {
 +      struct work_struct unpin_work;
 +      struct work_struct mmio_work;
 +
        struct drm_crtc *crtc;
        struct drm_framebuffer *old_fb;
        struct drm_i915_gem_object *pending_flip_obj;
        struct drm_pending_vblank_event *event;
        atomic_t pending;
 -#define INTEL_FLIP_INACTIVE   0
 -#define INTEL_FLIP_PENDING    1
 -#define INTEL_FLIP_COMPLETE   2
        u32 flip_count;
        u32 gtt_offset;
        struct drm_i915_gem_request *flip_queued_req;
        u32 flip_queued_vblank;
        u32 flip_ready_vblank;
 -      bool enable_stall_check;
 +      unsigned int rotation;
  };
  
  struct intel_load_detect_pipe {
@@@ -1053,9 -1029,9 +1051,9 @@@ void gen5_enable_gt_irq(struct drm_i915
  void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
  void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
  void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
 -void gen6_reset_rps_interrupts(struct drm_device *dev);
 -void gen6_enable_rps_interrupts(struct drm_device *dev);
 -void gen6_disable_rps_interrupts(struct drm_device *dev);
 +void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv);
 +void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv);
 +void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv);
  u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask);
  void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
  void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
@@@ -1134,16 -1110,14 +1132,16 @@@ void i915_audio_component_init(struct d
  void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
  
  /* intel_display.c */
 +void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, int vco);
 +void intel_update_rawclk(struct drm_i915_private *dev_priv);
  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);
 -void intel_mark_busy(struct drm_device *dev);
 -void intel_mark_idle(struct drm_device *dev);
 +void intel_mark_busy(struct drm_i915_private *dev_priv);
 +void intel_mark_idle(struct drm_i915_private *dev_priv);
  void intel_crtc_restore_mode(struct drm_crtc *crtc);
  int intel_display_suspend(struct drm_device *dev);
  void intel_encoder_destroy(struct drm_encoder *encoder);
@@@ -1152,6 -1126,7 +1150,6 @@@ struct intel_connector *intel_connector
  bool intel_connector_get_hw_state(struct intel_connector *connector);
  void intel_connector_attach_encoder(struct intel_connector *connector,
                                    struct intel_encoder *encoder);
 -struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
  struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
                                             struct drm_crtc *crtc);
  enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
@@@ -1174,9 -1149,6 +1172,9 @@@ intel_wait_for_vblank_if_active(struct 
        if (crtc->active)
                intel_wait_for_vblank(dev, pipe);
  }
 +
 +u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
 +
  int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
  void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
                         struct intel_digital_port *dport,
@@@ -1190,14 -1162,14 +1188,14 @@@ void intel_release_load_detect_pipe(str
                                    struct drm_modeset_acquire_ctx *ctx);
  int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
                               unsigned int rotation);
 +void intel_unpin_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,
                           struct drm_i915_gem_object *obj);
 -void intel_prepare_page_flip(struct drm_device *dev, int plane);
 -void intel_finish_page_flip(struct drm_device *dev, int pipe);
 -void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
 -void intel_check_page_flip(struct drm_device *dev, int pipe);
 +void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
 +void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
 +void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
  int intel_prepare_plane_fb(struct drm_plane *plane,
                           const struct drm_plane_state *new_state);
  void intel_cleanup_plane_fb(struct drm_plane *plane,
@@@ -1254,25 -1226,23 +1252,25 @@@ u32 intel_compute_tile_offset(int *x, i
                              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 intel_prepare_reset(struct drm_i915_private *dev_priv);
 +void intel_finish_reset(struct drm_i915_private *dev_priv);
  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_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 bxt_init_cdclk(struct drm_i915_private *dev_priv);
 +void bxt_uninit_cdclk(struct drm_i915_private *dev_priv);
 +void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy);
 +void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy);
 +bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
 +                          enum dpio_phy phy);
 +bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
 +                            enum dpio_phy phy);
  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);
 +unsigned int skl_cdclk_get_vco(unsigned int freq);
  void skl_enable_dc6(struct drm_i915_private *dev_priv);
  void skl_disable_dc6(struct drm_i915_private *dev_priv);
  void intel_dp_get_m_n(struct intel_crtc *crtc,
  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);
  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);
 +                      struct dpll *best_clock);
 +int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
  
  bool intel_crtc_active(struct drm_crtc *crtc);
  void hsw_enable_ips(struct intel_crtc *crtc);
@@@ -1367,22 -1337,12 +1365,22 @@@ bool intel_dp_source_supports_hbr2(stru
  bool
  intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
  
 +static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 +{
 +      return ~((1 << lane_count) - 1) & 0xf;
 +}
 +
 +/* intel_dp_aux_backlight.c */
 +int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
 +
  /* intel_dp_mst.c */
  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
  void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
  /* intel_dsi.c */
  void intel_dsi_init(struct drm_device *dev);
  
 +/* intel_dsi_dcs_backlight.c */
 +int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector);
  
  /* intel_dvo.c */
  void intel_dvo_init(struct drm_device *dev);
@@@ -1423,15 -1383,11 +1421,15 @@@ static inline void intel_fbdev_restore_
  void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
                           struct drm_atomic_state *state);
  bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
 -void intel_fbc_pre_update(struct intel_crtc *crtc);
 +void intel_fbc_pre_update(struct intel_crtc *crtc,
 +                        struct intel_crtc_state *crtc_state,
 +                        struct intel_plane_state *plane_state);
  void intel_fbc_post_update(struct intel_crtc *crtc);
  void intel_fbc_init(struct drm_i915_private *dev_priv);
  void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv);
 -void intel_fbc_enable(struct intel_crtc *crtc);
 +void intel_fbc_enable(struct intel_crtc *crtc,
 +                    struct intel_crtc_state *crtc_state,
 +                    struct intel_plane_state *plane_state);
  void intel_fbc_disable(struct intel_crtc *crtc);
  void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
  void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
@@@ -1466,13 -1422,13 +1464,13 @@@ void intel_attach_aspect_ratio_property
  
  
  /* intel_overlay.c */
 -void intel_setup_overlay(struct drm_device *dev);
 -void intel_cleanup_overlay(struct drm_device *dev);
 +void intel_setup_overlay(struct drm_i915_private *dev_priv);
 +void intel_cleanup_overlay(struct drm_i915_private *dev_priv);
  int intel_overlay_switch_off(struct intel_overlay *overlay);
 -int intel_overlay_put_image(struct drm_device *dev, void *data,
 -                          struct drm_file *file_priv);
 -int intel_overlay_attrs(struct drm_device *dev, void *data,
 -                      struct drm_file *file_priv);
 +int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
 +                                struct drm_file *file_priv);
 +int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
 +                            struct drm_file *file_priv);
  void intel_overlay_reset(struct drm_i915_private *dev_priv);
  
  
@@@ -1501,14 -1457,7 +1499,14 @@@ extern struct drm_display_mode *intel_f
                                struct drm_display_mode *fixed_mode,
                                struct drm_connector *connector);
  void intel_backlight_register(struct drm_device *dev);
 -void intel_backlight_unregister(struct drm_device *dev);
 +
 +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
 +void intel_backlight_device_unregister(struct intel_connector *connector);
 +#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
 +static inline void intel_backlight_device_unregister(struct intel_connector *connector)
 +{
 +}
 +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
  
  
  /* intel_psr.c */
@@@ -1650,20 -1599,21 +1648,20 @@@ void intel_init_clock_gating_hooks(stru
  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);
 -void intel_init_gt_powersave(struct drm_device *dev);
 -void intel_cleanup_gt_powersave(struct drm_device *dev);
 -void intel_enable_gt_powersave(struct drm_device *dev);
 -void intel_disable_gt_powersave(struct drm_device *dev);
 -void intel_suspend_gt_powersave(struct drm_device *dev);
 -void intel_reset_gt_powersave(struct drm_device *dev);
 -void gen6_update_ring_freq(struct drm_device *dev);
 +void intel_init_gt_powersave(struct drm_i915_private *dev_priv);
 +void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv);
 +void intel_enable_gt_powersave(struct drm_i915_private *dev_priv);
 +void intel_disable_gt_powersave(struct drm_i915_private *dev_priv);
 +void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
 +void intel_reset_gt_powersave(struct drm_i915_private *dev_priv);
 +void gen6_update_ring_freq(struct drm_i915_private *dev_priv);
  void gen6_rps_busy(struct drm_i915_private *dev_priv);
  void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
  void gen6_rps_idle(struct drm_i915_private *dev_priv);
  void gen6_rps_boost(struct drm_i915_private *dev_priv,
                    struct intel_rps_client *rps,
                    unsigned long submitted);
 -void intel_queue_rps_boost_for_request(struct drm_device *dev,
 -                                     struct drm_i915_gem_request *req);
 +void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req);
  void vlv_wm_get_hw_state(struct drm_device *dev);
  void ilk_wm_get_hw_state(struct drm_device *dev);
  void skl_wm_get_hw_state(struct drm_device *dev);
@@@ -1671,11 -1621,7 +1669,11 @@@ void skl_ddb_get_hw_state(struct drm_i9
                          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);
 +int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
 +static inline int intel_enable_rc6(void)
 +{
 +      return i915.enable_rc6;
 +}
  
  /* intel_sdvo.c */
  bool intel_sdvo_init(struct drm_device *dev,
@@@ -1687,7 -1633,7 +1685,7 @@@ int intel_plane_init(struct drm_device 
  int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
  void intel_pipe_update_start(struct intel_crtc *crtc);
 -void intel_pipe_update_end(struct intel_crtc *crtc);
 +void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
  
  /* intel_tv.c */
  void intel_tv_init(struct drm_device *dev);
@@@ -374,9 -374,8 +374,9 @@@ static void intel_fbc_hw_deactivate(str
   * @dev_priv: i915 device instance
   *
   * This function is used to verify the current state of FBC.
 + *
   * FIXME: This should be tracked in the plane config eventually
 - *        instead of queried at runtime for most callers.
 + * instead of queried at runtime for most callers.
   */
  bool intel_fbc_is_active(struct drm_i915_private *dev_priv)
  {
@@@ -481,10 -480,10 +481,10 @@@ static void intel_fbc_deactivate(struc
                intel_fbc_hw_deactivate(dev_priv);
  }
  
 -static bool multiple_pipes_ok(struct intel_crtc *crtc)
 +static bool multiple_pipes_ok(struct intel_crtc *crtc,
 +                            struct intel_plane_state *plane_state)
  {
 -      struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 -      struct drm_plane *primary = crtc->base.primary;
 +      struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_fbc *fbc = &dev_priv->fbc;
        enum pipe pipe = crtc->pipe;
  
        if (!no_fbc_on_multiple_pipes(dev_priv))
                return true;
  
 -      WARN_ON(!drm_modeset_is_locked(&primary->mutex));
 -
 -      if (to_intel_plane_state(primary->state)->visible)
 +      if (plane_state->visible)
                fbc->visible_pipes_mask |= (1 << pipe);
        else
                fbc->visible_pipes_mask &= ~(1 << pipe);
@@@ -707,16 -708,21 +707,16 @@@ static bool intel_fbc_hw_tracking_cover
        return effective_w <= max_w && effective_h <= max_h;
  }
  
 -static void intel_fbc_update_state_cache(struct intel_crtc *crtc)
 +static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
 +                                       struct intel_crtc_state *crtc_state,
 +                                       struct intel_plane_state *plane_state)
  {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
        struct intel_fbc_state_cache *cache = &fbc->state_cache;
 -      struct intel_crtc_state *crtc_state =
 -              to_intel_crtc_state(crtc->base.state);
 -      struct intel_plane_state *plane_state =
 -              to_intel_plane_state(crtc->base.primary->state);
        struct drm_framebuffer *fb = plane_state->base.fb;
        struct drm_i915_gem_object *obj;
  
 -      WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
 -      WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex));
 -
        cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                cache->crtc.hsw_bdw_pixel_rate =
  
        /* FIXME: We lack the proper locking here, so only run this on the
         * platforms that need. */
 -      if (INTEL_INFO(dev_priv)->gen >= 5 && INTEL_INFO(dev_priv)->gen < 7)
 +      if (IS_GEN(dev_priv, 5, 6))
                cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj);
        cache->fb.pixel_format = fb->pixel_format;
        cache->fb.stride = fb->pitches[0];
@@@ -818,10 -824,9 +818,9 @@@ static bool intel_fbc_can_choose(struc
  {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
-       bool enable_by_default = IS_HASWELL(dev_priv) ||
-                                IS_BROADWELL(dev_priv);
+       bool enable_by_default = IS_BROADWELL(dev_priv);
  
 -      if (intel_vgpu_active(dev_priv->dev)) {
 +      if (intel_vgpu_active(dev_priv)) {
                fbc->no_fbc_reason = "VGPU is active";
                return false;
        }
@@@ -881,9 -886,7 +880,9 @@@ static bool intel_fbc_reg_params_equal(
        return memcmp(params1, params2, sizeof(*params1)) == 0;
  }
  
 -void intel_fbc_pre_update(struct intel_crtc *crtc)
 +void intel_fbc_pre_update(struct intel_crtc *crtc,
 +                        struct intel_crtc_state *crtc_state,
 +                        struct intel_plane_state *plane_state)
  {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
  
        mutex_lock(&fbc->lock);
  
 -      if (!multiple_pipes_ok(crtc)) {
 +      if (!multiple_pipes_ok(crtc, plane_state)) {
                fbc->no_fbc_reason = "more than one pipe active";
                goto deactivate;
        }
        if (!fbc->enabled || fbc->crtc != crtc)
                goto unlock;
  
 -      intel_fbc_update_state_cache(crtc);
 +      intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
  
  deactivate:
        intel_fbc_deactivate(dev_priv);
@@@ -1085,9 -1088,7 +1084,9 @@@ out
   * intel_fbc_enable multiple times for the same pipe without an
   * intel_fbc_disable in the middle, as long as it is deactivated.
   */
 -void intel_fbc_enable(struct intel_crtc *crtc)
 +void intel_fbc_enable(struct intel_crtc *crtc,
 +                    struct intel_crtc_state *crtc_state,
 +                    struct intel_plane_state *plane_state)
  {
        struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
        struct intel_fbc *fbc = &dev_priv->fbc;
        if (fbc->enabled) {
                WARN_ON(fbc->crtc == NULL);
                if (fbc->crtc == crtc) {
 -                      WARN_ON(!crtc->config->enable_fbc);
 +                      WARN_ON(!crtc_state->enable_fbc);
                        WARN_ON(fbc->active);
                }
                goto out;
        }
  
 -      if (!crtc->config->enable_fbc)
 +      if (!crtc_state->enable_fbc)
                goto out;
  
        WARN_ON(fbc->active);
        WARN_ON(fbc->crtc != NULL);
  
 -      intel_fbc_update_state_cache(crtc);
 +      intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
        if (intel_fbc_alloc_cfb(crtc)) {
                fbc->no_fbc_reason = "not enough stolen memory";
                goto out;
@@@ -159,6 -159,10 +159,10 @@@ static int msm_fbdev_create(struct drm_
        dev->mode_config.fb_base = paddr;
  
        fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo);
+       if (IS_ERR(fbi->screen_base)) {
+               ret = PTR_ERR(fbi->screen_base);
+               goto fail_unlock;
+       }
        fbi->screen_size = fbdev->bo->size;
        fbi->fix.smem_start = paddr;
        fbi->fix.smem_len = fbdev->bo->size;
@@@ -184,7 -188,21 +188,7 @@@ fail
        return ret;
  }
  
 -static void msm_crtc_fb_gamma_set(struct drm_crtc *crtc,
 -              u16 red, u16 green, u16 blue, int regno)
 -{
 -      DBG("fbdev: set gamma");
 -}
 -
 -static void msm_crtc_fb_gamma_get(struct drm_crtc *crtc,
 -              u16 *red, u16 *green, u16 *blue, int regno)
 -{
 -      DBG("fbdev: get gamma");
 -}
 -
  static const struct drm_fb_helper_funcs msm_fb_helper_funcs = {
 -      .gamma_set = msm_crtc_fb_gamma_set,
 -      .gamma_get = msm_crtc_fb_gamma_get,
        .fb_probe = msm_fbdev_create,
  };
  
@@@ -42,9 -42,9 +42,9 @@@
  #include <linux/of_platform.h>
  #include <linux/component.h>
  
 -#include <video/omapdss.h>
  #include <video/mipi_display.h>
  
 +#include "omapdss.h"
  #include "dss.h"
  #include "dss_features.h"
  
@@@ -1167,7 -1167,6 +1167,6 @@@ static int dsi_regulator_init(struct pl
  {
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct regulator *vdds_dsi;
-       int r;
  
        if (dsi->vdds_dsi_reg != NULL)
                return 0;
@@@ -1262,7 -1261,7 +1261,7 @@@ static unsigned long dsi_fclk_rate(stru
        unsigned long r;
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
  
 -      if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) {
 +      if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
                /* DSI FCLK source is DSS_CLK_FCK */
                r = clk_get_rate(dsi->dss_clk);
        } else {
@@@ -1475,7 -1474,7 +1474,7 @@@ static void dsi_dump_dsidev_clocks(stru
  {
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
 -      enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
 +      enum dss_clk_source dispc_clk_src, dsi_clk_src;
        int dsi_module = dsi->module_id;
        struct dss_pll *pll = &dsi->pll;
  
                        cinfo->clkdco, cinfo->m);
  
        seq_printf(s,   "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
 -                      dss_feat_get_clk_source_name(dsi_module == 0 ?
 -                              OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
 -                              OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
 +                      dss_get_clk_source_name(dsi_module == 0 ?
 +                              DSS_CLK_SRC_PLL1_1 :
 +                              DSS_CLK_SRC_PLL2_1),
                        cinfo->clkout[HSDIV_DISPC],
                        cinfo->mX[HSDIV_DISPC],
 -                      dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
 +                      dispc_clk_src == DSS_CLK_SRC_FCK ?
                        "off" : "on");
  
        seq_printf(s,   "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
 -                      dss_feat_get_clk_source_name(dsi_module == 0 ?
 -                              OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
 -                              OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
 +                      dss_get_clk_source_name(dsi_module == 0 ?
 +                              DSS_CLK_SRC_PLL1_2 :
 +                              DSS_CLK_SRC_PLL2_2),
                        cinfo->clkout[HSDIV_DSI],
                        cinfo->mX[HSDIV_DSI],
 -                      dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
 +                      dsi_clk_src == DSS_CLK_SRC_FCK ?
                        "off" : "on");
  
        seq_printf(s,   "- DSI%d -\n", dsi_module + 1);
  
 -      seq_printf(s,   "dsi fclk source = %s (%s)\n",
 -                      dss_get_generic_clk_source_name(dsi_clk_src),
 -                      dss_feat_get_clk_source_name(dsi_clk_src));
 +      seq_printf(s,   "dsi fclk source = %s\n",
 +                      dss_get_clk_source_name(dsi_clk_src));
  
        seq_printf(s,   "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
  
@@@ -4101,8 -4101,8 +4100,8 @@@ static int dsi_display_init_dispc(struc
        int r;
  
        dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
 -                      OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
 -                      OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC);
 +                      DSS_CLK_SRC_PLL1_1 :
 +                      DSS_CLK_SRC_PLL2_1);
  
        if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
                r = dss_mgr_register_framedone_handler(channel,
@@@ -4149,7 -4149,7 +4148,7 @@@ err1
                dss_mgr_unregister_framedone_handler(channel,
                                dsi_framedone_irq_callback, dsidev);
  err:
 -      dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
 +      dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
        return r;
  }
  
@@@ -4162,7 -4162,7 +4161,7 @@@ static void dsi_display_uninit_dispc(st
                dss_mgr_unregister_framedone_handler(channel,
                                dsi_framedone_irq_callback, dsidev);
  
 -      dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK);
 +      dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
  }
  
  static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
@@@ -4196,8 -4196,8 +4195,8 @@@ static int dsi_display_init_dsi(struct 
                goto err1;
  
        dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
 -                      OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
 -                      OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI);
 +                      DSS_CLK_SRC_PLL1_2 :
 +                      DSS_CLK_SRC_PLL2_2);
  
        DSSDBG("PLL OK\n");
  
  err3:
        dsi_cio_uninit(dsidev);
  err2:
 -      dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
 +      dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
  err1:
        dss_pll_disable(&dsi->pll);
  err0:
@@@ -4251,7 -4251,7 +4250,7 @@@ static void dsi_display_uninit_dsi(stru
        dsi_vc_enable(dsidev, 2, 0);
        dsi_vc_enable(dsidev, 3, 0);
  
 -      dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
 +      dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
        dsi_cio_uninit(dsidev);
        dsi_pll_uninit(dsidev, disconnect_lanes);
  }
@@@ -4452,7 -4452,7 +4451,7 @@@ static bool dsi_cm_calc_pll_cb(int n, i
        ctx->dsi_cinfo.fint = fint;
        ctx->dsi_cinfo.clkdco = clkdco;
  
 -      return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
 +      return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
                        dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
                        dsi_cm_calc_hsdiv_cb, ctx);
  }
@@@ -4491,7 -4491,7 +4490,7 @@@ static bool dsi_cm_calc(struct dsi_dat
        pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
        pll_max = cfg->hs_clk_max * 4;
  
 -      return dss_pll_calc(ctx->pll, clkin,
 +      return dss_pll_calc_a(ctx->pll, clkin,
                        pll_min, pll_max,
                        dsi_cm_calc_pll_cb, ctx);
  }
@@@ -4750,7 -4750,7 +4749,7 @@@ static bool dsi_vm_calc_pll_cb(int n, i
        ctx->dsi_cinfo.fint = fint;
        ctx->dsi_cinfo.clkdco = clkdco;
  
 -      return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
 +      return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
                        dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
                        dsi_vm_calc_hsdiv_cb, ctx);
  }
@@@ -4792,7 -4792,7 +4791,7 @@@ static bool dsi_vm_calc(struct dsi_dat
                pll_max = byteclk_max * 4 * 4;
        }
  
 -      return dss_pll_calc(ctx->pll, clkin,
 +      return dss_pll_calc_a(ctx->pll, clkin,
                        pll_min, pll_max,
                        dsi_vm_calc_pll_cb, ctx);
  }
@@@ -5138,8 -5138,6 +5137,8 @@@ static const struct dss_pll_ops dsi_pll
  };
  
  static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
 +      .type = DSS_PLL_TYPE_A,
 +
        .n_max = (1 << 7) - 1,
        .m_max = (1 << 11) - 1,
        .mX_max = (1 << 4) - 1,
  };
  
  static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
 +      .type = DSS_PLL_TYPE_A,
 +
        .n_max = (1 << 8) - 1,
        .m_max = (1 << 12) - 1,
        .mX_max = (1 << 5) - 1,
  };
  
  static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
 +      .type = DSS_PLL_TYPE_A,
 +
        .n_max = (1 << 8) - 1,
        .m_max = (1 << 12) - 1,
        .mX_max = (1 << 5) - 1,
@@@ -39,9 -39,9 +39,9 @@@
  #include <linux/regulator/consumer.h>
  #include <linux/component.h>
  #include <linux/of.h>
 -#include <video/omapdss.h>
  #include <sound/omap-hdmi-audio.h>
  
 +#include "omapdss.h"
  #include "hdmi5_core.h"
  #include "dss.h"
  #include "dss_features.h"
@@@ -120,7 -120,6 +120,6 @@@ static irqreturn_t hdmi_irq_handler(in
  
  static int hdmi_init_regulator(void)
  {
-       int r;
        struct regulator *reg;
  
        if (hdmi.vdda_reg != NULL)
@@@ -190,11 -189,7 +189,11 @@@ static int hdmi_power_on_full(struct om
        if (p->double_pixel)
                pc *= 2;
  
 -      hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo);
 +      /* DSS_HDMI_TCLK is bitclk / 10 */
 +      pc *= 10;
 +
 +      dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
 +              pc, &hdmi_cinfo);
  
        /* disable and clear irqs */
        hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
  
        hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
  
 -      /* bypass TV gamma table */
 -      dispc_enable_gamma_table(0);
 -
        /* tv size */
        dss_mgr_set_timings(channel, p);
  
@@@ -276,14 -276,14 +276,14 @@@ void atombios_crtc_dpms(struct drm_crt
                        atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
                atombios_blank_crtc(crtc, ATOM_DISABLE);
                if (dev->num_crtcs > radeon_crtc->crtc_id)
 -                      drm_vblank_on(dev, radeon_crtc->crtc_id);
 +                      drm_crtc_vblank_on(crtc);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
                if (dev->num_crtcs > radeon_crtc->crtc_id)
 -                      drm_vblank_off(dev, radeon_crtc->crtc_id);
 +                      drm_crtc_vblank_off(crtc);
                if (radeon_crtc->enabled)
                        atombios_blank_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
@@@ -589,7 -589,8 +589,8 @@@ static u32 atombios_adjust_pll(struct d
                if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                /* use frac fb div on RS780/RS880 */
-               if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
+               if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
+                   && !radeon_crtc->ss_enabled)
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                        if (radeon_crtc->ss.refdiv) {
                                radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
                                radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
-                               if (ASIC_IS_AVIVO(rdev))
+                               if (rdev->family >= CHIP_RV770)
                                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                        }
                }
@@@ -75,7 -75,7 +75,7 @@@ static struct drm_driver sun4i_drv_driv
        .dumb_create            = drm_gem_cma_dumb_create,
        .dumb_destroy           = drm_gem_dumb_destroy,
        .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
 -      .gem_free_object        = drm_gem_cma_free_object,
 +      .gem_free_object_unlocked = drm_gem_cma_free_object,
        .gem_vm_ops             = &drm_gem_cma_vm_ops,
  
        /* PRIME Operations */
        .disable_vblank         = sun4i_drv_disable_vblank,
  };
  
+ static void sun4i_remove_framebuffers(void)
+ {
+       struct apertures_struct *ap;
+       ap = alloc_apertures(1);
+       if (!ap)
+               return;
+       /* The framebuffer can be located anywhere in RAM */
+       ap->ranges[0].base = 0;
+       ap->ranges[0].size = ~0;
+       remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false);
+       kfree(ap);
+ }
  static int sun4i_drv_bind(struct device *dev)
  {
        struct drm_device *drm;
        if (!drm)
                return -ENOMEM;
  
 -      ret = drm_dev_set_unique(drm, dev_name(drm->dev));
 -      if (ret)
 -              goto free_drm;
 -
        drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
        if (!drv) {
                ret = -ENOMEM;
        }
        drm->irq_enabled = true;
  
+       /* Remove early framebuffers (ie. simplefb) */
+       sun4i_remove_framebuffers();
        /* Create our framebuffer */
        drv->fbdev = sun4i_framebuffer_init(drm);
        if (IS_ERR(drv->fbdev)) {
        if (ret)
                goto free_drm;
  
 -      ret = drm_connector_register_all(drm);
 -      if (ret)
 -              goto unregister_drm;
 -
        return 0;
  
 -unregister_drm:
 -      drm_dev_unregister(drm);
  free_drm:
        drm_dev_unref(drm);
        return ret;
@@@ -166,6 -195,7 +185,7 @@@ static void sun4i_drv_unbind(struct dev
  {
        struct drm_device *drm = dev_get_drvdata(dev);
  
+       drm_connector_unregister_all(drm);
        drm_dev_unregister(drm);
        drm_kms_helper_poll_fini(drm);
        sun4i_framebuffer_free(drm);
@@@ -54,8 -54,13 +54,13 @@@ static int sun4i_rgb_get_modes(struct d
  static int sun4i_rgb_mode_valid(struct drm_connector *connector,
                                struct drm_display_mode *mode)
  {
+       struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector);
+       struct sun4i_drv *drv = rgb->drv;
+       struct sun4i_tcon *tcon = drv->tcon;
        u32 hsync = mode->hsync_end - mode->hsync_start;
        u32 vsync = mode->vsync_end - mode->vsync_start;
+       unsigned long rate = mode->clock * 1000;
+       long rounded_rate;
  
        DRM_DEBUG_DRIVER("Validating modes...\n");
  
  
        DRM_DEBUG_DRIVER("Vertical parameters OK\n");
  
+       rounded_rate = clk_round_rate(tcon->dclk, rate);
+       if (rounded_rate < rate)
+               return MODE_CLOCK_LOW;
+       if (rounded_rate > rate)
+               return MODE_CLOCK_HIGH;
+       DRM_DEBUG_DRIVER("Clock rate OK\n");
        return MODE_OK;
  }
  
 -static struct drm_encoder *
 -sun4i_rgb_best_encoder(struct drm_connector *connector)
 -{
 -      struct sun4i_rgb *rgb =
 -              drm_connector_to_sun4i_rgb(connector);
 -
 -      return &rgb->encoder;
 -}
 -
  static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {
        .get_modes      = sun4i_rgb_get_modes,
        .mode_valid     = sun4i_rgb_mode_valid,
 -      .best_encoder   = sun4i_rgb_best_encoder,
  };
  
  static enum drm_connector_status
@@@ -193,7 -217,7 +207,7 @@@ int sun4i_rgb_init(struct drm_device *d
        int ret;
  
        /* If we don't have a panel, there's no point in going on */
-       if (!tcon->panel)
+       if (IS_ERR(tcon->panel))
                return -ENODEV;
  
        rgb = devm_kzalloc(drm->dev, sizeof(*rgb), GFP_KERNEL);
@@@ -175,22 -175,20 +175,22 @@@ vc4_crtc_lut_load(struct drm_crtc *crtc
                HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
  }
  
 -static void
 +static int
  vc4_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
 -                 uint32_t start, uint32_t size)
 +                 uint32_t size)
  {
        struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
        u32 i;
  
 -      for (i = start; i < start + size; i++) {
 +      for (i = 0; i < size; i++) {
                vc4_crtc->lut_r[i] = r[i] >> 8;
                vc4_crtc->lut_g[i] = g[i] >> 8;
                vc4_crtc->lut_b[i] = b[i] >> 8;
        }
  
        vc4_crtc_lut_load(crtc);
 +
 +      return 0;
  }
  
  static u32 vc4_get_fifo_full_level(u32 format)
@@@ -397,7 -395,6 +397,7 @@@ static int vc4_crtc_atomic_check(struc
        struct vc4_dev *vc4 = to_vc4_dev(dev);
        struct drm_plane *plane;
        unsigned long flags;
 +      const struct drm_plane_state *plane_state;
        u32 dlist_count = 0;
        int ret;
  
        if (hweight32(state->connector_mask) > 1)
                return -EINVAL;
  
 -      drm_atomic_crtc_state_for_each_plane(plane, state) {
 -              struct drm_plane_state *plane_state =
 -                      state->state->plane_states[drm_plane_index(plane)];
 -
 -              /* plane might not have changed, in which case take
 -               * current state:
 -               */
 -              if (!plane_state)
 -                      plane_state = plane->state;
 -
 +      drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state)
                dlist_count += vc4_plane_dlist_size(plane_state);
 -      }
  
        dlist_count++; /* Account for SCALER_CTL0_END. */
  
@@@ -449,14 -456,6 +449,6 @@@ static void vc4_crtc_atomic_flush(struc
  
        WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
  
-       HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
-                 vc4_state->mm.start);
-       if (debug_dump_regs) {
-               DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
-               vc4_hvs_dump_state(dev);
-       }
        if (crtc->state->event) {
                unsigned long flags;
  
  
                spin_lock_irqsave(&dev->event_lock, flags);
                vc4_crtc->event = crtc->state->event;
-               spin_unlock_irqrestore(&dev->event_lock, flags);
                crtc->state->event = NULL;
+               HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+                         vc4_state->mm.start);
+               spin_unlock_irqrestore(&dev->event_lock, flags);
+       } else {
+               HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+                         vc4_state->mm.start);
+       }
+       if (debug_dump_regs) {
+               DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
+               vc4_hvs_dump_state(dev);
        }
  }
  
@@@ -493,12 -504,17 +497,17 @@@ static void vc4_crtc_handle_page_flip(s
  {
        struct drm_crtc *crtc = &vc4_crtc->base;
        struct drm_device *dev = crtc->dev;
+       struct vc4_dev *vc4 = to_vc4_dev(dev);
+       struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+       u32 chan = vc4_crtc->channel;
        unsigned long flags;
  
        spin_lock_irqsave(&dev->event_lock, flags);
-       if (vc4_crtc->event) {
+       if (vc4_crtc->event &&
+           (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)))) {
                drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
                vc4_crtc->event = NULL;
+               drm_crtc_vblank_put(crtc);
        }
        spin_unlock_irqrestore(&dev->event_lock, flags);
  }
@@@ -549,6 -565,7 +558,7 @@@ vc4_async_page_flip_complete(struct vc4
                spin_unlock_irqrestore(&dev->event_lock, flags);
        }
  
+       drm_crtc_vblank_put(crtc);
        drm_framebuffer_unreference(flip_state->fb);
        kfree(flip_state);
  
@@@ -591,6 -608,8 +601,8 @@@ static int vc4_async_page_flip(struct d
                return ret;
        }
  
+       WARN_ON(drm_crtc_vblank_get(crtc) != 0);
        /* Immediately update the plane's legacy fb pointer, so that later
         * modeset prep sees the state that will be present when the semaphore
         * is released.
@@@ -66,12 -66,12 +66,12 @@@ static const struct file_operations vc4
  };
  
  static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
-       DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0),
-       DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0),
-       DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0),
-       DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
-       DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
-       DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
+       DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
                          DRM_ROOT_ONLY),
  };
@@@ -91,7 -91,7 +91,7 @@@ static struct drm_driver vc4_drm_drive
  
        .enable_vblank = vc4_enable_vblank,
        .disable_vblank = vc4_disable_vblank,
-       .get_vblank_counter = drm_vblank_count,
+       .get_vblank_counter = drm_vblank_no_hw_counter,
  
  #if defined(CONFIG_DEBUG_FS)
        .debugfs_init = vc4_debugfs_init,
@@@ -99,7 -99,7 +99,7 @@@
  #endif
  
        .gem_create_object = vc4_create_object,
 -      .gem_free_object = vc4_free_object,
 +      .gem_free_object_unlocked = vc4_free_object,
        .gem_vm_ops = &drm_gem_cma_vm_ops,
  
        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@@ -176,6 -176,7 +176,6 @@@ static int vc4_drm_bind(struct device *
  {
        struct platform_device *pdev = to_platform_device(dev);
        struct drm_device *drm;
 -      struct drm_connector *connector;
        struct vc4_dev *vc4;
        int ret = 0;
  
        if (ret < 0)
                goto unbind_all;
  
 -      /* Connector registration has to occur after DRM device
 -       * registration, because it creates sysfs entries based on the
 -       * DRM device.
 -       */
 -      list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
 -              ret = drm_connector_register(connector);
 -              if (ret)
 -                      goto unregister;
 -      }
 -
        vc4_kms_load(drm);
  
        return 0;
  
 -unregister:
 -      drm_dev_unregister(drm);
  unbind_all:
        component_unbind_all(dev, drm);
  gem_destroy:
@@@ -111,18 -111,24 +111,26 @@@ static int vc4_atomic_commit(struct drm
        int i;
        uint64_t wait_seqno = 0;
        struct vc4_commit *c;
 +      struct drm_plane *plane;
 +      struct drm_plane_state *new_state;
  
        c = commit_init(state);
        if (!c)
                return -ENOMEM;
  
        /* Make sure that any outstanding modesets have finished. */
-       ret = down_interruptible(&vc4->async_modeset);
-       if (ret) {
-               kfree(c);
-               return ret;
+       if (nonblock) {
+               ret = down_trylock(&vc4->async_modeset);
+               if (ret) {
+                       kfree(c);
+                       return -EBUSY;
+               }
+       } else {
+               ret = down_interruptible(&vc4->async_modeset);
+               if (ret) {
+                       kfree(c);
+                       return ret;
+               }
        }
  
        ret = drm_atomic_helper_prepare_planes(dev, state);
                return ret;
        }
  
 -      for (i = 0; i < dev->mode_config.num_total_plane; i++) {
 -              struct drm_plane *plane = state->planes[i];
 -              struct drm_plane_state *new_state = state->plane_states[i];
 -
 -              if (!plane)
 -                      continue;
 -
 +      for_each_plane_in_state(state, plane, new_state, i) {
                if ((plane->state->fb != new_state->fb) && new_state->fb) {
                        struct drm_gem_cma_object *cma_bo =
                                drm_fb_cma_get_gem_obj(new_state->fb, 0);
         * the software side now.
         */
  
 -      drm_atomic_helper_swap_state(dev, state);
 +      drm_atomic_helper_swap_state(state, true);
  
        /*
         * Everything below can be run asynchronously without the need to grab